1 /* Project 16 Source Code~
\r
2 * Copyright (C) 2012-2016 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 verson 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, boolean cmem, 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
57 modexEnter(vq, cmem, gv);
\r
63 vgaSetMode(byte mode)
\r
65 int10_setmode(mode);
\r
68 //---------------------------------------------------
\r
70 // Use the bios to get the current video mode
\r
73 byte/*FIXME: why long? "long" is 32-bit datatype, VGA modes are 8-bit numbers. */
\r
76 return int10_getmode();
\r
79 /* -========================= Entry Points ==========================- */
\r
80 void modexEnter(sword vq, boolean cmem, global_game_variables_t *gv)
\r
83 dword far*ptr=(dword far*)vga_state.vga_graphics_ram;//VGA; /* used for faster screen clearing */
\r
84 struct vga_mode_params cm;
\r
87 vgaSetMode(VGA_256_COLOR_MODE);
\r
88 vga_enable_256color_modex();
\r
89 update_state_from_vga();
\r
90 vga_read_crtc_mode(&cm);
\r
95 //CRTParmCount = sizeof(ModeX_320x240regs) / sizeof(ModeX_320x240regs[0]);
\r
96 /* width and height */
\r
97 gv->video.page[0].sw=vga_state.vga_width = 320; // VGA lib currently does not update this
\r
98 gv->video.page[0].sh=vga_state.vga_height = 240; // VGA lib currently does not update this
\r
100 // 320x240 mode 60Hz
\r
101 cm.horizontal_total=0x5f + 5; /* CRTC[0] -5 */
\r
102 cm.horizontal_display_end=0x4f + 1; /* CRTC[1] -1 */
\r
103 cm.horizontal_blank_start=0x50 + 1; /* CRTC[2] */
\r
104 cm.horizontal_blank_end=0x82 + 1; /* CRTC[3] bit 0-4 & CRTC[5] bit 7 */
\r
105 cm.horizontal_start_retrace=0x54;/* CRTC[4] */
\r
106 cm.horizontal_end_retrace=0x80; /* CRTC[5] bit 0-4 */
\r
107 //cm.horizontal_start_delay_after_total=0x3e; /* CRTC[3] bit 5-6 */
\r
108 //cm.horizontal_start_delay_after_retrace=0x41; /* CRTC[5] bit 5-6 */
\r
109 cm.vertical_total = 0x20D + 2;
\r
110 cm.vertical_start_retrace = 0x1EA;
\r
111 cm.vertical_end_retrace = 0x1EC;
\r
112 cm.vertical_display_end = 480;
\r
113 cm.vertical_blank_start = 0x1E7 + 1;
\r
114 cm.vertical_blank_end = 0x206 + 1;
\r
115 cm.clock_select = 0; /* misc register = 0xE3 25MHz */
\r
118 vga_state.vga_stride=0x58;
\r
121 case 2: // TODO: 160x120 according to ModeX_160x120regs
\r
123 case 3: // TODO: 160x120 according to ModeX_320x200regs
\r
125 case 4: // TODO: 160x120 according to ModeX_192x144regs
\r
127 case 5: // TODO: 160x120 according to ModeX_256x192regs
\r
133 vga_write_crtc_mode(&cm,0);
\r
135 /* clear video memory */
\r
139 /* clear video memory */
\r
140 vga_write_sequencer(2/*map mask register*/,0xf/*all 4 planes*/);
\r
141 for(i=0; i<0x8000; i++) ptr[i] = 0x0000;
\r
144 gv->video.page[0].tilesw = gv->video.page[0].sw/TILEWH;
\r
145 gv->video.page[0].tilesh = gv->video.page[0].sh/TILEWH;
\r
146 //TODO MAKE FLEXIBLE~
\r
147 gv->video.page[0].tilemidposscreenx = gv->video.page[0].tilesw;
\r
148 gv->video.page[0].tilemidposscreeny = (gv->video.page[0].tilesh/2)+1;
\r
149 #define PAGE_SIZE (word)(gv->video.page[0].sw/4 * gv->video.page[0].sh)
\r
154 /* TODO restore original mode and palette */
\r
155 vgaSetMode(TEXT_MODE);
\r
159 modexDefaultPage(page_t *p)
\r
163 /* default page values */
\r
164 page.data = vga_state.vga_graphics_ram;//VGA;
\r
169 page.width = p->sw;
\r
170 page.height = p->sh;
\r
171 page.tw = page.sw/TILEWH;
\r
172 page.th = page.sh/TILEWH;
\r
173 page.tilemidposscreenx = page.tw/2;
\r
174 page.tilemidposscreeny = (page.th/2)+1;
\r
175 page.tilesw=p->tilesw;
\r
176 page.tilesh=p->tilesh;
\r
177 //pageSize = p->sw*p->sh;
\r
183 /* returns the next page in contiguous memory
\r
184 * the next page will be the same size as p, by default
\r
187 modexNextPage(page_t *p) {
\r
190 result.data = p->data + (p->width/4)*p->height;
\r
193 result.width = p->width;
\r
194 result.height = p->height;
\r
195 result.tw = p->width/TILEWH;
\r
196 result.th = p->height/TILEWH;
\r
197 result.id = p->id+1;
\r
200 // return modexNextPageFlexibleSize(&p, p->width, p->height);
\r
203 //next page with defined dimentions~
\r
205 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
209 result.data = p->data + (p->width/4)*p->height; /* compute the offset */
\r
214 result.tw = p->width/TILEWH;
\r
215 result.th = p->height/TILEWH;
\r
216 result.id = p->id+1;
\r
223 modexShowPage(page_t *page) {
\r
229 /* calculate offset */
\r
230 offset = (word) page->data;
\r
231 offset += page->dy * (page->width >> 2 );
\r
232 offset += page->dx >> 2;
\r
234 /* calculate crtcOffset according to virtual width */
\r
235 crtcOffset = page->width >> 3;
\r
237 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
238 low_address = LOW_ADDRESS | (offset << 8);
\r
240 /* wait for appropriate timing and then program CRTC */
\r
241 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
242 outpw(CRTC_INDEX, high_address);
\r
243 outpw(CRTC_INDEX, low_address);
\r
244 outp(CRTC_INDEX, 0x13);
\r
245 outp(CRTC_DATA, crtcOffset);
\r
247 /* wait for one retrace */
\r
248 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
250 /* do PEL panning here */
\r
251 outp(AC_INDEX, 0x33);
\r
252 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
257 modexPanPage(page_t *page, int dx, int dy) {
\r
264 modexSelectPlane(byte plane) {
\r
265 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
266 outp(SC_DATA, plane);
\r
271 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
272 word pageOff = (word) page->data;
\r
273 word xoff=x/4; /* xoffset that begins each row */
\r
274 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
275 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
276 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
277 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
278 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
279 byte left = lclip[x&0x03];
\r
280 byte right = rclip[(x+w)&0x03];
\r
282 /* handle the case which requires an extra group */
\r
283 if((x & 0x03) && !((x+w) & 0x03)) {
\r
288 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
290 MOV DI, poffset ; go to the first pixel
\r
291 MOV DX, SC_INDEX ; point to the map mask
\r
295 MOV AL, color ; get ready to write colors
\r
297 MOV CX, scanCount ; count the line
\r
298 MOV BL, AL ; remember color
\r
299 MOV AL, left ; do the left clip
\r
300 OUT DX, AL ; set the left clip
\r
301 MOV AL, BL ; restore color
\r
302 STOSB ; write the color
\r
304 JZ SCAN_DONE ; handle 1 group stuff
\r
306 ;-- write the main body of the scanline
\r
307 MOV BL, AL ; remember color
\r
308 MOV AL, 0x0f ; write to all pixels
\r
310 MOV AL, BL ; restore color
\r
311 REP STOSB ; write the color
\r
313 MOV BL, AL ; remeber color
\r
315 OUT DX, AL ; do the right clip
\r
316 MOV AL, BL ; restore color
\r
317 STOSB ; write pixel
\r
318 ADD DI, nextRow ; go to the next row
\r
324 /* moved to src/lib/modex16/16render.c */
\r
326 /* copy a region of video memory from one page to another.
\r
327 * It assumes that the left edge of the tile is the same on both
\r
328 * regions and the memory areas do not overlap.
\r
331 modexCopyPageRegion(page_t *dest, page_t *src,
\r
334 word width, word height)
\r
336 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
337 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
338 word scans = width/4;
\r
339 word nextSrcRow = src->width/4 - scans - 1;
\r
340 word nextDestRow = dest->width/4 - scans - 1;
\r
341 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
342 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
343 byte left = lclip[sx&0x03];
\r
344 byte right = rclip[(sx+width)&0x03];
\r
347 MOV AX, SCREEN_SEG ; work in the vga space
\r
352 MOV DX, GC_INDEX ; turn off cpu bits
\r
356 MOV AX, SC_INDEX ; point to the mask register
\r
366 MOV CX, scans ; the number of latches
\r
368 MOV AL, left ; do the left column
\r
373 MOV AL, 0fh ; do the inner columns
\r
375 REP MOVSB ; copy the pixels
\r
377 MOV AL, right ; do the right column
\r
382 MOV AX, SI ; go the start of the next row
\r
383 ADD AX, nextSrcRow ;
\r
386 ADD AX, nextDestRow ;
\r
389 DEC height ; do the rest of the actions
\r
392 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
393 MOV AL, 0ffh ; none from latches
\r
399 /* fade and flash */
\r
401 modexFadeOn(word fade, byte *palette) {
\r
402 fadePalette(-fade, 64, 64/fade+1, palette);
\r
407 modexFadeOff(word fade, byte *palette) {
\r
408 fadePalette(fade, 0, 64/fade+1, palette);
\r
413 modexFlashOn(word fade, byte *palette) {
\r
414 fadePalette(fade, -64, 64/fade+1, palette);
\r
419 modexFlashOff(word fade, byte *palette) {
\r
420 fadePalette(-fade, 0, 64/fade+1, palette);
\r
425 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
429 /* handle the case where we just update */
\r
431 modexPalUpdate1(palette);
\r
435 while(iter > 0) { /* FadeLoop */
\r
436 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
437 tmppal[i] = palette[i] - dim;
\r
438 if(tmppal[i] > 127) {
\r
440 } else if(tmppal[i] > 63) {
\r
444 modexPalUpdate1(tmppal);
\r
451 /* save and load */
\r
453 modexPalSave(byte *palette) {
\r
456 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
457 for(i=0; i<PAL_SIZE; i++) {
\r
458 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
466 ptr = malloc(PAL_SIZE);
\r
468 /* handle errors */
\r
470 printf("Could not allocate palette.\n");
\r
479 modexLoadPalFile(byte *filename, byte **palette) {
\r
483 /* free the palette if it exists */
\r
488 /* allocate the new palette */
\r
489 *palette = modexNewPal();
\r
491 /* open the file */
\r
492 file = fopen(filename, "rb");
\r
494 printf("Could not open palette file: %s\n", filename);
\r
498 /* read the file */
\r
500 while(!feof(file)) {
\r
501 *ptr++ = fgetc(file);
\r
509 modexSavePalFile(char *filename, byte *pal) {
\r
513 /* open the file for writing */
\r
514 file = fopen(filename, "wb");
\r
516 printf("Could not open %s for writing\n", filename);
\r
520 /* write the data to the file */
\r
521 fwrite(pal, 1, PAL_SIZE, file);
\r
529 fadePalette(-1, 64, 1, tmppal);
\r
535 fadePalette(-1, -64, 1, tmppal);
\r
541 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
543 byte *p = bmp->palette;
\r
547 static word a[PAL_SIZE]; //palette array of change values!
\r
548 word z=0, aq=0, aa=0, pp=0;
\r
550 //modexWaitBorder();
\r
551 vga_wait_for_vsync();
\r
554 memset(a, -1, sizeof(a));
\r
555 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
565 // printf("q: %02d\n", (q));
\r
566 // printf("qq: %02d\n", (qq));
\r
567 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
568 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
570 if((*i)<PAL_SIZE/2 && w==0)
\r
572 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
574 //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
575 //____ 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
576 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
581 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
583 //printf("qp=%d\n", qp);
\r
584 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
585 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
586 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
587 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
591 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
593 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
594 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
595 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
598 //if(qp>0) printf("qp=%d\n", qp);
\r
599 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
601 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
602 vga_wait_for_vsync();
\r
603 if((*i)>=PAL_SIZE/2 && w==0)
\r
605 for(; (*i)<PAL_SIZE; (*i)++)
\r
607 //____ 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
608 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
613 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
615 //printf("qp=%d\n", qp);
\r
616 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
617 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
618 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
619 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
623 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
624 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
625 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
628 //printf(" (*i)=%d\n", (*i)/3);
\r
631 printf("\nqqqqqqqq\n\n");
\r
637 long bufSize = (bmp->width * bmp->height);
\r
639 //printf("1(*i)=%02d\n", (*i)/3);
\r
640 //printf("1z=%02d\n", z/3);
\r
641 modexchkcolor(bmp, &q, &a, &aa, &z, i);
\r
642 //printf("2(*i)=%02d\n", (*i)/3);
\r
643 //printf("2z=%02d\n", z/3);
\r
648 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
649 if(a[aq]==-1) aq++;
\r
650 else { aqoffset++; break; }
\r
652 //update the image data here!
\r
653 for(lq=0; lq<bufSize; lq++)
\r
657 use a[qp] instead of bmp->offset for this spot!
\r
662 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
665 //(offset/bmp->offset)*bmp->offset
\r
668 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
669 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
670 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
671 /*if(bmp->data[lq]+bmp->offset==aq)
\r
673 //printf("%02d", bmp->data[lq]);
\r
674 //printf("\n%02d\n", bmp->offset);
\r
675 printf("aq=%02d ", aq);
\r
676 printf("a[aq]=%02d ", a[aq]);
\r
677 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
678 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
679 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
680 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
681 // printf("_%d ", bmp->data[lq]);
\r
682 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
684 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
686 if(bmp->data[lq]+bmp->offset >= aq)
\r
688 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
689 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
691 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
694 //printf("%02d`", bmp->data[lq]);
\r
695 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
698 //printf(" aq=%02d\n", aq);
\r
699 //printf(" aa=%02d\n", aa);
\r
701 //update the palette~
\r
702 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
705 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
710 modexPalUpdate1(byte *p)
\r
713 //modexWaitBorder();
\r
714 vga_wait_for_vsync();
\r
715 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
716 for(i=0; i<PAL_SIZE/2; i++)
\r
718 outp(PAL_DATA_REG, p[i]);
\r
720 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
721 vga_wait_for_vsync();
\r
722 for(; i<PAL_SIZE; i++)
\r
724 outp(PAL_DATA_REG, p[(i)]);
\r
729 modexPalUpdate0(byte *p)
\r
732 //modexWaitBorder();
\r
733 vga_wait_for_vsync();
\r
734 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
735 for(i=0; i<PAL_SIZE/2; i++)
\r
737 outp(PAL_DATA_REG, rand());
\r
739 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
740 vga_wait_for_vsync();
\r
741 for(; i<PAL_SIZE; i++)
\r
743 outp(PAL_DATA_REG, rand());
\r
748 modexPalOverscan(byte *p, word col)
\r
750 //modexWaitBorder();
\r
751 vga_wait_for_vsync();
\r
752 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
753 outp(PAL_DATA_REG, col);
\r
757 //i want to make another vesion that checks the palette when the palette is being appened~
\r
758 void modexchkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
762 pal = modexNewPal();
\r
764 //printf("q: %02d\n", (*q));
\r
765 printf("chkcolor start~\n");
\r
766 printf("1 (*z): %d\n", (*z)/3);
\r
767 printf("1 (*i): %d\n", (*i)/3);
\r
768 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
769 printf("wwwwwwwwwwwwwwww\n");
\r
770 //check palette for dups
\r
771 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
773 //printf("\n z: %d\n", (*z));
\r
774 //printf(" q: %d\n", (*q));
\r
775 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
778 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
781 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
782 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
786 else for(zz=0; zz<(*q); zz+=3)
\r
788 //printf("zz: %02d\n", zz/3);
\r
791 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
795 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
796 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
799 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
801 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
802 // 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
803 // 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
804 // //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
805 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
810 planned features that i plan to implement~
\r
811 image that has values on the pallete list!
\r
813 no... wait.... no wwww
\r
815 //for(zzii=0; zzii<3; zzii++)
\r
817 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
818 a[(((*z)+(*q)))]=zz;
\r
820 (*aa)=(((*z)+(*q)));
\r
821 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
822 // printf("\n aa: %d\n\n", (*aa));
\r
823 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
824 // printf("wwwwwwwwwwwwwwww\n\n");
\r
828 printf("================\n");
\r
829 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
830 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
831 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
832 printf("================\n");
\r
834 //printf("[%d]", (zz+q));
\r
838 printf("wwwwwwwwwwwwwwww\n");
\r
839 printf("2 (*z): %d\n", (*z)/3);
\r
840 printf("2 (*i): %d\n", (*i)/3);
\r
841 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
842 printf("chkcolor end~\n");
\r
846 void modexputPixel(page_t *page, int x, int y, byte color)
\r
848 word pageOff = (word) page->data;
\r
849 /* Each address accesses four neighboring pixels, so set
\r
850 Write Plane Enable according to which pixel we want
\r
851 to modify. The plane is determined by the two least
\r
852 significant bits of the x-coordinate: */
\r
853 modexSelectPlane(PLANE(x));
\r
854 //outp(SC_INDEX, 0x02);
\r
855 //outp(SC_DATA, 0x01 << (x & 3));
\r
857 /* The offset of the pixel into the video segment is
\r
858 offset = (width * y + x) / 4, and write the given
\r
859 color to the plane we selected above. Heed the active
\r
860 page start selection. */
\r
861 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
865 byte modexgetPixel(page_t *page, int x, int y)
\r
867 word pageOff = (word) page->data;
\r
868 /* Select the plane from which we must read the pixel color: */
\r
869 outpw(GC_INDEX, 0x04);
\r
870 outpw(GC_INDEX+1, x & 3);
\r
872 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
876 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
879 word addr = (word) romFontsData.l;
\r
880 word addrq = (page->width/4) * y + (x / 4) + ((word)page->data);
\r
885 w=romFonts[t].charSize;
\r
886 romFontsData.chw=0;
\r
888 for(; *str != '\0'; str++)
\r
891 if((c=='\n'/* || c=="\
\r
892 "*/) || romFontsData.chw
\r
895 romFontsData.chw=0;
\r
896 y+=romFonts[t].charSize;
\r
899 //load the letter 'A'
\r
905 MOV AL, c ; the letter
\r
908 ADD SI, AX ;the address of charcter
\r
916 //TODO: OPTIMIZE THIS!!!!
\r
917 modexDrawCharPBuf(page, x, y, t, col, bgcol, addrq);
\r
923 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
925 word i, s, o, w, j, xp;
\r
927 word addr = (word) l;
\r
954 for(; *str != '\0'; str++)
\r
957 if((c=='\n'/* || c=="\
\r
958 "*/)/* || chw>=page->width*/)
\r
964 //load the letter 'A'
\r
970 MOV AL, c ; the letter
\r
973 ADD SI, AX ;the address of charcter
\r
988 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
989 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
998 /* palette dump on display! */
\r
999 void modexpdump(page_t *pee)
\r
1001 int mult=(QUADWH);
\r
1002 int palq=(mult)*TILEWH;
\r
1005 for(paly=0; paly<palq; paly+=mult){
\r
1006 for(palx=0; palx<palq; palx+=mult){
\r
1007 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
\r
1013 /////////////////////////////////////////////////////////////////////////////
\r
1015 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1016 // the Virtual screen. //
\r
1018 /////////////////////////////////////////////////////////////////////////////
\r
1019 void modexcls(page_t *page, byte color, byte *Where)
\r
1021 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1022 /* set map mask to all 4 planes */
\r
1023 outpw(SC_INDEX, 0xff02);
\r
1024 //_fmemset(VGA, color, 16000);
\r
1025 _fmemset(Where, color, page->width*(page->height)/4);
\r
1029 modexWaitBorder() {
\r
1030 while(inp(INPUT_STATUS_1) & 8) {
\r
1034 while(!(inp(INPUT_STATUS_1) & 8)) {
\r
1044 m = int10_getmode();
\r
1045 if ((rp=vga_state.vga_graphics_ram) != NULL && !(m <= 3 || m == 7)) {
\r
1046 unsigned int i,im;
\r
1048 im = (FP_SEG(vga_state.vga_graphics_ram_fence) - FP_SEG(vga_state.vga_graphics_ram));
\r
1049 if (im > 0xFFE) im = 0xFFE;
\r
1051 for (i=0;i < im;i++) vga_state.vga_graphics_ram[i] = 0;
\r
1053 else if ((ap=vga_state.vga_alpha_ram) != NULL) {
\r
1054 unsigned int i,im;
\r
1056 im = (FP_SEG(vga_state.vga_alpha_ram_fence) - FP_SEG(vga_state.vga_alpha_ram));
\r
1057 if (im > 0x7FE) im = 0x7FE;
\r
1058 im <<= 4 - 1; /* because ptr is type uint16_t */
\r
1059 for (i=0;i < im;i++) vga_state.vga_alpha_ram[i] = 0x0720;
\r
1062 printf("WARNING: bios cls no ptr\n");
\r