1 /* Project 16 Source Code~
\r
2 * Copyright (C) 2012-2015 sparky4 & pngwen & andrius4669
\r
4 * This file is part of Project 16.
\r
6 * Project 16 is free software; you can redistribute it and/or modify
\r
7 * it under the terms of the GNU General Public License as published by
\r
8 * the Free Software Foundation; either version 3 of the License, or
\r
9 * (at your option) any later version.
\r
11 * Project 16 is distributed in the hope that it will be useful,
\r
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
14 * GNU General Public License for more details.
\r
16 * You should have received a copy of the GNU General Public License
\r
17 * along with this program. If not, see <http://www.gnu.org/licenses/>, or
\r
18 * write to the Free Software Foundation, Inc., 51 Franklin Street,
\r
19 * Fifth Floor, Boston, MA 02110-1301 USA.
\r
26 #include "src/lib/modex16.h"
\r
28 byte far* VGA=(byte far*) 0xA0000000; /* this points to video memory. */
\r
30 static void fadePalette(sbyte fade, sbyte start, word iter, byte *palette);
\r
31 static byte tmppal[PAL_SIZE];
\r
33 /////////////////////////////////////////////////////////////////////////////
\r
35 // setvideo() - This function Manages the video modes //
\r
37 /////////////////////////////////////////////////////////////////////////////
\r
38 void VGAmodeX(sword vq, global_game_variables_t *gv)
\r
44 case 0: // deinit the video
\r
45 // change to the video mode we were in before we switched to mode 13h
\r
48 in.h.al = gv->video.old_mode;
\r
49 int86(0x10, &in, &out);
\r
51 default: // init the video
\r
52 // get old video mode
\r
54 //int86(0x10, &in, &out);
\r
55 gv->video.old_mode = vgaGetMode();//out.h.al;
\r
63 vgaSetMode(byte mode)
\r
67 regs.h.ah = SET_MODE;
\r
69 int86(VIDEO_INT, ®s, ®s);
\r
72 //---------------------------------------------------
\r
74 // Use the bios to get the current video mode
\r
83 int86(VIDEO_INT, &rg, &rg);
\r
88 /* -========================= Entry Points ==========================- */
\r
90 modexEnter(sword vq, global_game_variables_t *gv)
\r
93 dword far*ptr=(dword far*)VGA; /* used for faster screen clearing */
\r
95 /* common mode X initiation stuff~ */
\r
96 modexsetBaseXMode();
\r
101 CRTParmCount = sizeof(ModeX_320x240regs) / sizeof(ModeX_320x240regs[0]);
\r
102 /* width and height */
\r
103 //TODO add width and height of screen
\r
105 /* send the CRTParms */
\r
106 for(i=0; i<CRTParmCount; i++) {
\r
107 outpw(CRTC_INDEX, ModeX_320x240regs[i]);
\r
110 /* clear video memory */
\r
111 outpw(SC_INDEX, 0x0f02);
\r
112 for(i=0; i<0x8000; i++) {
\r
117 CRTParmCount = sizeof(ModeX_192x144regs) / sizeof(ModeX_192x144regs[0]);
\r
118 /* width and height */
\r
119 //TODO add width and height of screen
\r
121 /* send the CRTParms */
\r
122 for(i=0; i<CRTParmCount; i++) {
\r
123 outpw(CRTC_INDEX, ModeX_192x144regs[i]);
\r
126 /* clear video memory */
\r
127 outpw(SC_INDEX, 0x0f02);
\r
128 for(i=0; i<0x8000; i++) {
\r
137 /* TODO restore original mode and palette */
\r
138 vgaSetMode(TEXT_MODE);
\r
141 // setBaseXMode() does the initialization to make the VGA ready to
\r
142 // accept any combination of configuration register settings. This
\r
143 // involves enabling writes to index 0 to 7 of the CRT controller (port
\r
144 // 0x3D4), by clearing the most significant bit (bit 7) of index 0x11.
\r
146 modexsetBaseXMode(void)
\r
149 /* TODO save current video mode and palette */
\r
150 vgaSetMode(VGA_256_COLOR_MODE);
\r
152 /* disable chain4 mode */
\r
153 outpw(SC_INDEX, 0x0604);
\r
155 /* synchronous reset while setting Misc Output */
\r
156 outpw(SC_INDEX, 0x0100);
\r
158 /* select 25 MHz dot clock & 60 Hz scanning rate */
\r
159 outp(MISC_OUTPUT, 0xe3);
\r
161 /* undo reset (restart sequencer) */
\r
162 outpw(SC_INDEX, 0x0300);
\r
164 /* reprogram the CRT controller */
\r
165 outp(CRTC_INDEX, 0x11); /* VSync End reg contains register write prot */
\r
166 // temp = inp(CRTC_DATA) & 0x7F;
\r
167 // outp(CRTC_INDEX, 0x11);
\r
168 outp(CRTC_DATA, 0x7f); /* get current write protect on varios regs */
\r
169 // outp(CRTC_DATA, temp); /* get current write protect on varios regs */
\r
173 modexDefaultPage() {
\r
176 /* default page values */
\r
180 page.width = SCREEN_WIDTH;
\r
181 page.height = SCREEN_HEIGHT;
\r
182 page.tw = page.width/TILEWH;
\r
183 page.th = page.height/TILEWH;
\r
189 /* returns the next page in contiguous memory
\r
190 * the next page will be the same size as p, by default
\r
193 modexNextPage(page_t *p) {
\r
196 result.data = p->data + (p->width/4)*p->height;
\r
199 result.width = p->width;
\r
200 result.height = p->height;
\r
201 result.tw = p->width/TILEWH;
\r
202 result.th = p->height/TILEWH;
\r
203 result.id = p->id+1;
\r
206 // return modexNextPageFlexibleSize(&p, p->width, p->height);
\r
209 //next page with defined dimentions~
\r
211 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
215 result.data = p->data + (p->width/4)*p->height; /* compute the offset */
\r
220 result.tw = p->width/TILEWH;
\r
221 result.th = p->height/TILEWH;
\r
222 result.id = p->id+1;
\r
229 modexShowPage(page_t *page) {
\r
235 /* calculate offset */
\r
236 offset = (word) page->data;
\r
237 offset += page->dy * (page->width >> 2 );
\r
238 offset += page->dx >> 2;
\r
240 /* calculate crtcOffset according to virtual width */
\r
241 crtcOffset = page->width >> 3;
\r
243 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
244 low_address = LOW_ADDRESS | (offset << 8);
\r
246 /* wait for appropriate timing and then program CRTC */
\r
247 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
248 outpw(CRTC_INDEX, high_address);
\r
249 outpw(CRTC_INDEX, low_address);
\r
250 outp(CRTC_INDEX, 0x13);
\r
251 outp(CRTC_DATA, crtcOffset);
\r
253 /* wait for one retrace */
\r
254 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
256 /* do PEL panning here */
\r
257 outp(AC_INDEX, 0x33);
\r
258 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
263 modexPanPage(page_t *page, int dx, int dy) {
\r
270 modexSelectPlane(byte plane) {
\r
271 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
272 outp(SC_DATA, plane);
\r
277 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
278 word pageOff = (word) page->data;
\r
279 word xoff=x/4; /* xoffset that begins each row */
\r
280 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
281 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
282 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
283 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
284 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
285 byte left = lclip[x&0x03];
\r
286 byte right = rclip[(x+w)&0x03];
\r
288 /* handle the case which requires an extra group */
\r
289 if((x & 0x03) && !((x+w) & 0x03)) {
\r
294 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
296 MOV DI, poffset ; go to the first pixel
\r
297 MOV DX, SC_INDEX ; point to the map mask
\r
301 MOV AL, color ; get ready to write colors
\r
303 MOV CX, scanCount ; count the line
\r
304 MOV BL, AL ; remember color
\r
305 MOV AL, left ; do the left clip
\r
306 OUT DX, AL ; set the left clip
\r
307 MOV AL, BL ; restore color
\r
308 STOSB ; write the color
\r
310 JZ SCAN_DONE ; handle 1 group stuff
\r
312 ;-- write the main body of the scanline
\r
313 MOV BL, AL ; remember color
\r
314 MOV AL, 0x0f ; write to all pixels
\r
316 MOV AL, BL ; restore color
\r
317 REP STOSB ; write the color
\r
319 MOV BL, AL ; remeber color
\r
321 OUT DX, AL ; do the right clip
\r
322 MOV AL, BL ; restore color
\r
323 STOSB ; write pixel
\r
324 ADD DI, nextRow ; go to the next row
\r
332 oldDrawBmp(byte far* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
338 /* TODO Make this fast. It's SLOOOOOOW */
\r
339 for(plane=0; plane < 4; plane++) {
\r
340 modexSelectPlane(PLANE(plane+x));
\r
341 for(px = plane; px < bmp->width; px+=4) {
\r
343 for(py=0; py<bmp->height; py++) {
\r
344 if(!sprite || bmp->data[offset])
\r
345 page[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
346 offset+=bmp->width;
\r
353 CDrawBmp(byte far* vgamem, page_t* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
360 /* TODO Make this fast. It's SLOOOOOOW */
\r
361 for(plane=0; plane < 4; plane++) {
\r
362 modexSelectPlane(PLANE(plane+x));
\r
363 for(px = plane; px < bmp->width; px+=4) {
\r
365 for(py=0; py<bmp->height; py++) {
\r
366 if(!sprite || bmp->data[offset])
\r
367 //modexputPixel(page, x+px, y+py, bmp->data[offset]);
\r
368 vgamem[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
369 offset+=bmp->width;
\r
376 modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) {
\r
377 /* draw the region (the entire freakin bitmap) */
\r
378 modexDrawBmpRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
383 modexDrawBmpRegion(page_t *page, int x, int y,
\r
384 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
385 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
386 byte far *data = bmp->data;//+bmp->offset;
\r
387 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
390 byte plane = 1 << ((byte) x & 0x03);
\r
391 word scanCount = width/4 + (width%4 ? 1 :0);
\r
392 word nextPageRow = page->width/4 - scanCount;
\r
393 word nextBmpRow = (word) bmp->width - width;
\r
395 byte planeCounter = 4;
\r
397 /* printf("bmp->data=%Fp\n",bmp->data);
\r
398 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
399 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
401 //code is a bit slow here
\r
403 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
406 MOV DX, SC_INDEX ; point at the map mask register
\r
411 MOV DX, SC_DATA ; select the current plane
\r
415 ;-- begin plane painting
\r
416 MOV AX, height ; start the row counter
\r
417 MOV rowCounter, AX ;
\r
418 MOV DI, poffset ; go to the first pixel
\r
419 MOV SI, bmpOffset ; go to the bmp pixel
\r
421 MOV CX, width ; count the columns
\r
423 MOVSB ; copy the pixel
\r
424 SUB CX, 3 ; we skip the next 3
\r
425 ADD SI, 3 ; skip the bmp pixels
\r
426 LOOP SCAN_LOOP ; finish the scan
\r
428 MOV AX, nextPageRow
\r
429 ADD DI, AX ; go to the next row on screen
\r
431 ADD SI, AX ; go to the next row on bmp
\r
434 JNZ ROW_LOOP ; do all the rows
\r
435 ;-- end plane painting
\r
437 MOV AL, plane ; advance to the next plane
\r
439 AND AL, 0x0f ; mask the plane properly
\r
440 MOV plane, AL ; store the plane
\r
442 INC bmpOffset ; start bmp at the right spot
\r
445 JNZ PLANE_LOOP ; do all 4 planes
\r
450 modex_sparky4_DrawBmpRegion(page_t *page, int x, int y,
\r
451 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
452 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
453 byte far *data = bmp->data;//+bmp->offset;
\r
454 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
457 byte plane = 1 << ((byte) x & 0x03);
\r
458 word scanCount = width/4 + (width%4 ? 1 :0);
\r
459 word nextPageRow = page->width/4 - scanCount;
\r
460 word nextBmpRow = (word) bmp->width - width;
\r
462 byte planeCounter = 4;
\r
464 /* printf("bmp->data=%Fp\n",bmp->data);
\r
465 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
466 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
468 //code is a bit slow here
\r
470 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
473 MOV DX, SC_INDEX ; point at the map mask register
\r
478 MOV DX, SC_DATA ; select the current plane
\r
482 ;-- begin plane painting
\r
483 MOV AX, height ; start the row counter
\r
484 MOV rowCounter, AX ;
\r
485 MOV DI, poffset ; go to the first pixel
\r
486 MOV SI, bmpOffset ; go to the bmp pixel
\r
488 MOV CX, width ; count the columns
\r
490 MOVSB ; copy the pixel
\r
491 SUB CX, 3 ; we skip the next 3
\r
492 ADD SI, 3 ; skip the bmp pixels
\r
493 LOOP SCAN_LOOP ; finish the scan
\r
495 MOV AX, nextPageRow
\r
496 ADD DI, AX ; go to the next row on screen
\r
498 ADD SI, AX ; go to the next row on bmp
\r
501 JNZ ROW_LOOP ; do all the rows
\r
502 ;-- end plane painting
\r
504 MOV AL, plane ; advance to the next plane
\r
506 AND AL, 0x0f ; mask the plane properly
\r
507 MOV plane, AL ; store the plane
\r
509 INC bmpOffset ; start bmp at the right spot
\r
512 JNZ PLANE_LOOP ; do all 4 planes
\r
517 modexDrawPlanarBuf(page_t *page, int x, int y, planar_buf_t *bmp) {
\r
518 /* TODO - adapt from test code */
\r
520 for(plane=0; plane < 4; plane++)
\r
528 modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp) {
\r
529 /* draw the whole sprite */
\r
530 modexDrawSpriteRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
534 modexDrawSpriteRegion(page_t *page, int x, int y,
\r
535 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
536 word poffset = (word)page->data + y*(page->width/4) + x/4;
\r
537 byte *data = bmp->data;//+bmp->offset;
\r
538 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
541 byte plane = 1 << ((byte) x & 0x03);
\r
542 word scanCount = width/4 + (width%4 ? 1 :0);
\r
543 word nextPageRow = page->width/4 - scanCount;
\r
544 word nextBmpRow = (word) bmp->width - width;
\r
546 byte planeCounter = 4;
\r
549 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
552 MOV DX, SC_INDEX ; point at the map mask register
\r
557 MOV DX, SC_DATA ; select the current plane
\r
561 ;-- begin plane painting
\r
562 MOV AX, height ; start the row counter
\r
563 MOV rowCounter, AX ;
\r
564 MOV DI, poffset ; go to the first pixel
\r
565 MOV SI, bmpOffset ; go to the bmp pixel
\r
567 MOV CX, width ; count the columns
\r
572 JNE DRAW_PIXEL ; draw non-zero pixels
\r
574 INC DI ; skip the transparent pixel
\r
578 MOVSB ; copy the pixel
\r
580 SUB CX, 3 ; we skip the next 3
\r
581 ADD SI, 3 ; skip the bmp pixels
\r
582 LOOP SCAN_LOOP ; finish the scan
\r
584 MOV AX, nextPageRow
\r
585 ADD DI, AX ; go to the next row on screen
\r
587 ADD SI, AX ; go to the next row on bmp
\r
590 JNZ ROW_LOOP ; do all the rows
\r
591 ;-- end plane painting
\r
593 MOV AL, plane ; advance to the next plane
\r
595 AND AL, 0x0f ; mask the plane properly
\r
596 MOV plane, AL ; store the plane
\r
598 INC bmpOffset ; start bmp at the right spot
\r
601 JNZ PLANE_LOOP ; do all 4 planes
\r
606 /* copy a region of video memory from one page to another.
\r
607 * It assumes that the left edge of the tile is the same on both
\r
608 * regions and the memory areas do not overlap.
\r
611 modexCopyPageRegion(page_t *dest, page_t *src,
\r
614 word width, word height)
\r
616 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
617 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
618 word scans = width/4;
\r
619 word nextSrcRow = src->width/4 - scans - 1;
\r
620 word nextDestRow = dest->width/4 - scans - 1;
\r
621 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
622 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
623 byte left = lclip[sx&0x03];
\r
624 byte right = rclip[(sx+width)&0x03];
\r
627 MOV AX, SCREEN_SEG ; work in the vga space
\r
632 MOV DX, GC_INDEX ; turn off cpu bits
\r
636 MOV AX, SC_INDEX ; point to the mask register
\r
646 MOV CX, scans ; the number of latches
\r
648 MOV AL, left ; do the left column
\r
653 MOV AL, 0fh ; do the inner columns
\r
655 REP MOVSB ; copy the pixels
\r
657 MOV AL, right ; do the right column
\r
662 MOV AX, SI ; go the start of the next row
\r
663 ADD AX, nextSrcRow ;
\r
666 ADD AX, nextDestRow ;
\r
669 DEC height ; do the rest of the actions
\r
672 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
673 MOV AL, 0ffh ; none from latches
\r
679 /* fade and flash */
\r
681 modexFadeOn(word fade, byte *palette) {
\r
682 fadePalette(-fade, 64, 64/fade+1, palette);
\r
687 modexFadeOff(word fade, byte *palette) {
\r
688 fadePalette(fade, 0, 64/fade+1, palette);
\r
693 modexFlashOn(word fade, byte *palette) {
\r
694 fadePalette(fade, -64, 64/fade+1, palette);
\r
699 modexFlashOff(word fade, byte *palette) {
\r
700 fadePalette(-fade, 0, 64/fade+1, palette);
\r
705 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
709 /* handle the case where we just update */
\r
711 modexPalUpdate1(palette);
\r
715 while(iter > 0) { /* FadeLoop */
\r
716 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
717 tmppal[i] = palette[i] - dim;
\r
718 if(tmppal[i] > 127) {
\r
720 } else if(tmppal[i] > 63) {
\r
724 modexPalUpdate1(tmppal);
\r
731 /* save and load */
\r
733 modexPalSave(byte *palette) {
\r
736 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
737 for(i=0; i<PAL_SIZE; i++) {
\r
738 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
746 ptr = malloc(PAL_SIZE);
\r
748 /* handle errors */
\r
750 printf("Could not allocate palette.\n");
\r
759 modexLoadPalFile(byte *filename, byte **palette) {
\r
763 /* free the palette if it exists */
\r
768 /* allocate the new palette */
\r
769 *palette = modexNewPal();
\r
771 /* open the file */
\r
772 file = fopen(filename, "rb");
\r
774 printf("Could not open palette file: %s\n", filename);
\r
778 /* read the file */
\r
780 while(!feof(file)) {
\r
781 *ptr++ = fgetc(file);
\r
789 modexSavePalFile(char *filename, byte *pal) {
\r
793 /* open the file for writing */
\r
794 file = fopen(filename, "wb");
\r
796 printf("Could not open %s for writing\n", filename);
\r
800 /* write the data to the file */
\r
801 fwrite(pal, 1, PAL_SIZE, file);
\r
809 fadePalette(-1, 64, 1, tmppal);
\r
815 fadePalette(-1, -64, 1, tmppal);
\r
821 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
823 byte *p = bmp->palette;
\r
827 static word a[PAL_SIZE]; //palette array of change values!
\r
828 word z=0, aq=0, aa=0, pp=0;
\r
833 memset(a, -1, sizeof(a));
\r
834 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
844 // printf("q: %02d\n", (q));
\r
845 // printf("qq: %02d\n", (qq));
\r
846 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
847 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
849 if((*i)<PAL_SIZE/2 && w==0)
\r
851 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
853 //if(i%3==0 && (p[i+5]==p[i+4] && p[i+4]==p[i+3] && p[i+3]==p[i+2] && p[i+2]==p[i+1] && p[i+1]==p[i] && p[i+5]==p[i]))
\r
854 //____ if((qp>0)&&((*i)-q)%3==0 && (p[((*i)-q)]==p[((*i)-q)+3] && p[((*i)-q)+1]==p[((*i)-q)+4] && p[((*i)-q)+2]==p[((*i)-q)+5])) outp(PAL_DATA_REG, p[(*i)-q]); else
\r
855 if(((((*i)-q)%3==0)) && (p[((*i)-q)]==p[((*i)-q)+3] && p[((*i)-q)+1]==p[((*i)-q)+4] && p[((*i)-q)+2]==p[((*i)-q)+5]))
\r
860 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
862 //printf("qp=%d\n", qp);
\r
863 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
864 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
865 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
866 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
870 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
872 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
873 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
874 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
877 //if(qp>0) printf("qp=%d\n", qp);
\r
878 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
880 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
881 if((*i)>=PAL_SIZE/2 && w==0)
\r
883 for(; (*i)<PAL_SIZE; (*i)++)
\r
885 //____ if((qp>0)&&((*i)-q)%3==0 && (p[((*i)-q)]==p[((*i)-q)+3] && p[((*i)-q)+1]==p[((*i)-q)+4] && p[((*i)-q)+2]==p[((*i)-q)+5])) outp(PAL_DATA_REG, p[(*i)-q]); else
\r
886 if(((((*i)-q)%3==0)) && (p[((*i)-q)]==p[((*i)-q)+3] && p[((*i)-q)+1]==p[((*i)-q)+4] && p[((*i)-q)+2]==p[((*i)-q)+5]))
\r
891 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
893 //printf("qp=%d\n", qp);
\r
894 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
895 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
896 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
897 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
901 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
902 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
903 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
906 //printf(" (*i)=%d\n", (*i)/3);
\r
909 printf("\nqqqqqqqq\n\n");
\r
915 long bufSize = (bmp->width * bmp->height);
\r
917 //printf("1(*i)=%02d\n", (*i)/3);
\r
918 //printf("1z=%02d\n", z/3);
\r
919 chkcolor(bmp, &q, &a, &aa, &z, i);
\r
920 //printf("2(*i)=%02d\n", (*i)/3);
\r
921 //printf("2z=%02d\n", z/3);
\r
926 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
927 if(a[aq]==-1) aq++;
\r
928 else { aqoffset++; break; }
\r
930 //update the image data here!
\r
931 for(lq=0; lq<bufSize; lq++)
\r
935 use a[qp] instead of bmp->offset for this spot!
\r
940 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
943 //(offset/bmp->offset)*bmp->offset
\r
946 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
947 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
948 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
949 /*if(bmp->data[lq]+bmp->offset==aq)
\r
951 //printf("%02d", bmp->data[lq]);
\r
952 //printf("\n%02d\n", bmp->offset);
\r
953 printf("aq=%02d ", aq);
\r
954 printf("a[aq]=%02d ", a[aq]);
\r
955 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
956 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
957 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
958 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
959 // printf("_%d ", bmp->data[lq]);
\r
960 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
962 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
964 if(bmp->data[lq]+bmp->offset >= aq)
\r
966 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
967 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
969 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
972 //printf("%02d`", bmp->data[lq]);
\r
973 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
976 //printf(" aq=%02d\n", aq);
\r
977 //printf(" aa=%02d\n", aa);
\r
979 //update the palette~
\r
980 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
983 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
988 modexPalUpdate1(byte *p)
\r
992 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
993 for(i=0; i<PAL_SIZE/2; i++)
\r
995 outp(PAL_DATA_REG, p[i]);
\r
997 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
998 for(; i<PAL_SIZE; i++)
\r
1000 outp(PAL_DATA_REG, p[(i)]);
\r
1005 modexPalUpdate0(byte *p)
\r
1008 modexWaitBorder();
\r
1009 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
1010 for(i=0; i<PAL_SIZE/2; i++)
\r
1012 outp(PAL_DATA_REG, rand());
\r
1014 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
1015 for(; i<PAL_SIZE; i++)
\r
1017 outp(PAL_DATA_REG, rand());
\r
1022 //i want to make another vesion that checks the palette when the palette is being appened~
\r
1023 void chkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
1027 pal = modexNewPal();
\r
1028 modexPalSave(pal);
\r
1029 //printf("q: %02d\n", (*q));
\r
1030 printf("chkcolor start~\n");
\r
1031 printf("1 (*z): %d\n", (*z)/3);
\r
1032 printf("1 (*i): %d\n", (*i)/3);
\r
1033 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
1034 printf("wwwwwwwwwwwwwwww\n");
\r
1035 //check palette for dups
\r
1036 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
1038 //printf("\n z: %d\n", (*z));
\r
1039 //printf(" q: %d\n", (*q));
\r
1040 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
1043 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
1046 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1047 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
1051 else for(zz=0; zz<(*q); zz+=3)
\r
1053 //printf("zz: %02d\n", zz/3);
\r
1056 if(pal[((*z)+(*q))]==pal[((*z)+(*q))+3] && pal[((*z)+(*q))+1]==pal[((*z)+(*q))+4] && pal[((*z)+(*q))+2]==pal[((*z)+(*q))+5]) //break if duplicate colors found in palette because it have reached the end of the current data of the palette
\r
1060 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
1061 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
1064 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
1066 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
1067 // printf(" zq: %d [%02d][%02d][%02d] value that is needing to be changed~\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
1068 // printf(" zz: %d [%02d][%02d][%02d] value that the previous value is going to change to~\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
1069 // //printf(" zv: %d [%02d][%02d][%02d] wwww\n", (zz-z+q)/3, pal[(zz-z+q)], pal[(zz-z+q)+1], pal[(zz-z+q)+2]);
\r
1070 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1073 //expand dong here
\r
1075 planned features that i plan to implement~
\r
1076 image that has values on the pallete list!
\r
1078 no... wait.... no wwww
\r
1080 //for(zzii=0; zzii<3; zzii++)
\r
1082 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
1083 a[(((*z)+(*q)))]=zz;
\r
1085 (*aa)=(((*z)+(*q)));
\r
1086 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
1087 // printf("\n aa: %d\n\n", (*aa));
\r
1088 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
1089 // printf("wwwwwwwwwwwwwwww\n\n");
\r
1093 printf("================\n");
\r
1094 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
1095 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
1096 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1097 printf("================\n");
\r
1099 //printf("[%d]", (zz+q));
\r
1103 printf("wwwwwwwwwwwwwwww\n");
\r
1104 printf("2 (*z): %d\n", (*z)/3);
\r
1105 printf("2 (*i): %d\n", (*i)/3);
\r
1106 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
1107 printf("chkcolor end~\n");
\r
1111 void modexputPixel(page_t *page, int x, int y, byte color)
\r
1113 word pageOff = (word) page->data;
\r
1114 /* Each address accesses four neighboring pixels, so set
\r
1115 Write Plane Enable according to which pixel we want
\r
1116 to modify. The plane is determined by the two least
\r
1117 significant bits of the x-coordinate: */
\r
1118 modexSelectPlane(PLANE(x));
\r
1119 //outp(SC_INDEX, 0x02);
\r
1120 //outp(SC_DATA, 0x01 << (x & 3));
\r
1122 /* The offset of the pixel into the video segment is
\r
1123 offset = (width * y + x) / 4, and write the given
\r
1124 color to the plane we selected above. Heed the active
\r
1125 page start selection. */
\r
1126 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
1130 byte modexgetPixel(page_t *page, int x, int y)
\r
1132 word pageOff = (word) page->data;
\r
1133 /* Select the plane from which we must read the pixel color: */
\r
1134 outpw(GC_INDEX, 0x04);
\r
1135 outpw(GC_INDEX+1, x & 3);
\r
1137 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
1141 void modexhlin(page_t *page, word xl, word xh, word y, word color)
\r
1146 for(x=0;x<xh*4;x+=4)
\r
1148 if(x+4>=SCREEN_WIDTH-1){ x=0; yy+=4; }
\r
1149 modexClearRegion(page, x+xl, y+yy, 4, 4, color);
\r
1151 //modexputPixel(page, x+xl, y, color);
\r
1154 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1156 word i, s, o, w, j, xp;
\r
1158 word addr = (word) l;
\r
1182 s=romFonts[t].seg;
\r
1183 o=romFonts[t].off;
\r
1185 for(; *str != '\0'; str++)
\r
1188 if((c=='\n'/* || c=="\
\r
1196 //load the letter 'A'
\r
1202 MOV AL, c ; the letter
\r
1205 ADD SI, AX ;the address of charcter
\r
1214 for(i=0; i<w; i++)
\r
1220 modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1229 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1231 word i, s, o, w, j, xp;
\r
1233 word addr = (word) l;
\r
1257 s=romFonts[t].seg;
\r
1258 o=romFonts[t].off;
\r
1260 for(; *str != '\0'; str++)
\r
1263 if((c=='\n'/* || c=="\
\r
1264 "*/)/* || chw>=page->width*/)
\r
1270 //load the letter 'A'
\r
1276 MOV AL, c ; the letter
\r
1279 ADD SI, AX ;the address of charcter
\r
1288 for(i=0; i<w; i++)
\r
1294 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1295 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1304 /* palette dump on display! */
\r
1305 void pdump(page_t *pee)
\r
1307 int mult=(QUADWH);
\r
1308 int palq=(mult)*TILEWH;
\r
1311 for(paly=0; paly<palq; paly+=mult){
\r
1312 for(palx=0; palx<palq; palx+=mult){
\r
1313 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
\r
1319 /////////////////////////////////////////////////////////////////////////////
\r
1321 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1322 // the Virtual screen. //
\r
1324 /////////////////////////////////////////////////////////////////////////////
\r
1325 void cls(page_t *page, byte color, byte *Where)
\r
1327 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1328 /* set map mask to all 4 planes */
\r
1329 outpw(SC_INDEX, 0xff02);
\r
1330 //_fmemset(VGA, color, 16000);
\r
1331 _fmemset(Where, color, page->width*(page->height));
\r
1335 modexWaitBorder() {
\r
1336 while(inp(INPUT_STATUS_1) & 8) {
\r
1340 while(!(inp(INPUT_STATUS_1) & 8)) {
\r