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
119 case 2: // TODO: 160x120 according to ModeX_160x120regs
\r
121 case 3: // TODO: 160x120 according to ModeX_320x200regs
\r
123 case 4: // TODO: 160x120 according to ModeX_192x144regs
\r
125 case 5: // TODO: 160x120 according to ModeX_256x192regs
\r
131 vga_write_crtc_mode(&cm,0);
\r
133 /* clear video memory */
\r
137 /* clear video memory */
\r
138 vga_write_sequencer(2/*map mask register*/,0xf/*all 4 planes*/);
\r
139 for(i=0; i<0x8000; i++) ptr[i] = 0x0000;
\r
142 gv->video.page[0].tilesw = gv->video.page[0].sw/TILEWH;
\r
143 gv->video.page[0].tilesh = gv->video.page[0].sh/TILEWH;
\r
144 //TODO MAKE FLEXIBLE~
\r
145 gv->video.page[0].tilemidposscreenx = gv->video.page[0].tilesw;
\r
146 gv->video.page[0].tilemidposscreeny = (gv->video.page[0].tilesh/2)+1;
\r
147 #define PAGE_SIZE (word)(gv->video.page[0].sw/4 * gv->video.page[0].sh)
\r
152 /* TODO restore original mode and palette */
\r
153 vgaSetMode(TEXT_MODE);
\r
157 modexDefaultPage(page_t *p)
\r
161 /* default page values */
\r
162 page.data = vga_state.vga_graphics_ram;//VGA;
\r
167 page.width = p->sw;
\r
168 page.height = p->sh;
\r
169 page.tw = page.sw/TILEWH;
\r
170 page.th = page.sh/TILEWH;
\r
171 page.tilemidposscreenx = page.tw/2;
\r
172 page.tilemidposscreeny = (page.th/2)+1;
\r
173 page.tilesw=p->tilesw;
\r
174 page.tilesh=p->tilesh;
\r
175 //pageSize = p->sw*p->sh;
\r
181 /* returns the next page in contiguous memory
\r
182 * the next page will be the same size as p, by default
\r
185 modexNextPage(page_t *p) {
\r
188 result.data = p->data + (p->width/4)*p->height;
\r
191 result.width = p->width;
\r
192 result.height = p->height;
\r
193 result.tw = p->width/TILEWH;
\r
194 result.th = p->height/TILEWH;
\r
195 result.id = p->id+1;
\r
198 // return modexNextPageFlexibleSize(&p, p->width, p->height);
\r
201 //next page with defined dimentions~
\r
203 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
207 result.data = p->data + (p->width/4)*p->height; /* compute the offset */
\r
212 result.tw = p->width/TILEWH;
\r
213 result.th = p->height/TILEWH;
\r
214 result.id = p->id+1;
\r
221 modexShowPage(page_t *page) {
\r
227 /* calculate offset */
\r
228 offset = (word) page->data;
\r
229 offset += page->dy * (page->width >> 2 );
\r
230 offset += page->dx >> 2;
\r
232 /* calculate crtcOffset according to virtual width */
\r
233 crtcOffset = page->width >> 3;
\r
235 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
236 low_address = LOW_ADDRESS | (offset << 8);
\r
238 /* wait for appropriate timing and then program CRTC */
\r
239 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
240 outpw(CRTC_INDEX, high_address);
\r
241 outpw(CRTC_INDEX, low_address);
\r
242 outp(CRTC_INDEX, 0x13);
\r
243 outp(CRTC_DATA, crtcOffset);
\r
245 /* wait for one retrace */
\r
246 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
248 /* do PEL panning here */
\r
249 outp(AC_INDEX, 0x33);
\r
250 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
255 modexPanPage(page_t *page, int dx, int dy) {
\r
262 modexSelectPlane(byte plane) {
\r
263 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
264 outp(SC_DATA, plane);
\r
269 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
270 word pageOff = (word) page->data;
\r
271 word xoff=x/4; /* xoffset that begins each row */
\r
272 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
273 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
274 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
275 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
276 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
277 byte left = lclip[x&0x03];
\r
278 byte right = rclip[(x+w)&0x03];
\r
280 /* handle the case which requires an extra group */
\r
281 if((x & 0x03) && !((x+w) & 0x03)) {
\r
286 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
288 MOV DI, poffset ; go to the first pixel
\r
289 MOV DX, SC_INDEX ; point to the map mask
\r
293 MOV AL, color ; get ready to write colors
\r
295 MOV CX, scanCount ; count the line
\r
296 MOV BL, AL ; remember color
\r
297 MOV AL, left ; do the left clip
\r
298 OUT DX, AL ; set the left clip
\r
299 MOV AL, BL ; restore color
\r
300 STOSB ; write the color
\r
302 JZ SCAN_DONE ; handle 1 group stuff
\r
304 ;-- write the main body of the scanline
\r
305 MOV BL, AL ; remember color
\r
306 MOV AL, 0x0f ; write to all pixels
\r
308 MOV AL, BL ; restore color
\r
309 REP STOSB ; write the color
\r
311 MOV BL, AL ; remeber color
\r
313 OUT DX, AL ; do the right clip
\r
314 MOV AL, BL ; restore color
\r
315 STOSB ; write pixel
\r
316 ADD DI, nextRow ; go to the next row
\r
322 /* moved to src/lib/modex16/16render.c */
\r
324 /* copy a region of video memory from one page to another.
\r
325 * It assumes that the left edge of the tile is the same on both
\r
326 * regions and the memory areas do not overlap.
\r
329 modexCopyPageRegion(page_t *dest, page_t *src,
\r
332 word width, word height)
\r
334 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
335 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
336 word scans = width/4;
\r
337 word nextSrcRow = src->width/4 - scans - 1;
\r
338 word nextDestRow = dest->width/4 - scans - 1;
\r
339 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
340 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
341 byte left = lclip[sx&0x03];
\r
342 byte right = rclip[(sx+width)&0x03];
\r
345 MOV AX, SCREEN_SEG ; work in the vga space
\r
350 MOV DX, GC_INDEX ; turn off cpu bits
\r
354 MOV AX, SC_INDEX ; point to the mask register
\r
364 MOV CX, scans ; the number of latches
\r
366 MOV AL, left ; do the left column
\r
371 MOV AL, 0fh ; do the inner columns
\r
373 REP MOVSB ; copy the pixels
\r
375 MOV AL, right ; do the right column
\r
380 MOV AX, SI ; go the start of the next row
\r
381 ADD AX, nextSrcRow ;
\r
384 ADD AX, nextDestRow ;
\r
387 DEC height ; do the rest of the actions
\r
390 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
391 MOV AL, 0ffh ; none from latches
\r
397 /* fade and flash */
\r
399 modexFadeOn(word fade, byte *palette) {
\r
400 fadePalette(-fade, 64, 64/fade+1, palette);
\r
405 modexFadeOff(word fade, byte *palette) {
\r
406 fadePalette(fade, 0, 64/fade+1, palette);
\r
411 modexFlashOn(word fade, byte *palette) {
\r
412 fadePalette(fade, -64, 64/fade+1, palette);
\r
417 modexFlashOff(word fade, byte *palette) {
\r
418 fadePalette(-fade, 0, 64/fade+1, palette);
\r
423 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
427 /* handle the case where we just update */
\r
429 modexPalUpdate1(palette);
\r
433 while(iter > 0) { /* FadeLoop */
\r
434 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
435 tmppal[i] = palette[i] - dim;
\r
436 if(tmppal[i] > 127) {
\r
438 } else if(tmppal[i] > 63) {
\r
442 modexPalUpdate1(tmppal);
\r
449 /* save and load */
\r
451 modexPalSave(byte *palette) {
\r
454 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
455 for(i=0; i<PAL_SIZE; i++) {
\r
456 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
464 ptr = malloc(PAL_SIZE);
\r
466 /* handle errors */
\r
468 printf("Could not allocate palette.\n");
\r
477 modexLoadPalFile(byte *filename, byte **palette) {
\r
481 /* free the palette if it exists */
\r
486 /* allocate the new palette */
\r
487 *palette = modexNewPal();
\r
489 /* open the file */
\r
490 file = fopen(filename, "rb");
\r
492 printf("Could not open palette file: %s\n", filename);
\r
496 /* read the file */
\r
498 while(!feof(file)) {
\r
499 *ptr++ = fgetc(file);
\r
507 modexSavePalFile(char *filename, byte *pal) {
\r
511 /* open the file for writing */
\r
512 file = fopen(filename, "wb");
\r
514 printf("Could not open %s for writing\n", filename);
\r
518 /* write the data to the file */
\r
519 fwrite(pal, 1, PAL_SIZE, file);
\r
527 fadePalette(-1, 64, 1, tmppal);
\r
533 fadePalette(-1, -64, 1, tmppal);
\r
539 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
541 byte *p = bmp->palette;
\r
545 static word a[PAL_SIZE]; //palette array of change values!
\r
546 word z=0, aq=0, aa=0, pp=0;
\r
548 //modexWaitBorder();
\r
549 vga_wait_for_vsync();
\r
552 memset(a, -1, sizeof(a));
\r
553 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
563 // printf("q: %02d\n", (q));
\r
564 // printf("qq: %02d\n", (qq));
\r
565 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
566 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
568 if((*i)<PAL_SIZE/2 && w==0)
\r
570 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
572 //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
573 //____ 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
574 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
579 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
581 //printf("qp=%d\n", qp);
\r
582 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
583 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
584 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
585 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
589 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
591 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
592 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
593 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
596 //if(qp>0) printf("qp=%d\n", qp);
\r
597 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
599 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
600 vga_wait_for_vsync();
\r
601 if((*i)>=PAL_SIZE/2 && w==0)
\r
603 for(; (*i)<PAL_SIZE; (*i)++)
\r
605 //____ 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
606 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
611 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
613 //printf("qp=%d\n", qp);
\r
614 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
615 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
616 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
617 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
621 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
622 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
623 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
626 //printf(" (*i)=%d\n", (*i)/3);
\r
629 printf("\nqqqqqqqq\n\n");
\r
635 long bufSize = (bmp->width * bmp->height);
\r
637 //printf("1(*i)=%02d\n", (*i)/3);
\r
638 //printf("1z=%02d\n", z/3);
\r
639 modexchkcolor(bmp, &q, &a, &aa, &z, i);
\r
640 //printf("2(*i)=%02d\n", (*i)/3);
\r
641 //printf("2z=%02d\n", z/3);
\r
646 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
647 if(a[aq]==-1) aq++;
\r
648 else { aqoffset++; break; }
\r
650 //update the image data here!
\r
651 for(lq=0; lq<bufSize; lq++)
\r
655 use a[qp] instead of bmp->offset for this spot!
\r
660 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
663 //(offset/bmp->offset)*bmp->offset
\r
666 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
667 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
668 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
669 /*if(bmp->data[lq]+bmp->offset==aq)
\r
671 //printf("%02d", bmp->data[lq]);
\r
672 //printf("\n%02d\n", bmp->offset);
\r
673 printf("aq=%02d ", aq);
\r
674 printf("a[aq]=%02d ", a[aq]);
\r
675 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
676 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
677 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
678 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
679 // printf("_%d ", bmp->data[lq]);
\r
680 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
682 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
684 if(bmp->data[lq]+bmp->offset >= aq)
\r
686 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
687 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
689 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
692 //printf("%02d`", bmp->data[lq]);
\r
693 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
696 //printf(" aq=%02d\n", aq);
\r
697 //printf(" aa=%02d\n", aa);
\r
699 //update the palette~
\r
700 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
703 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
708 modexPalUpdate1(byte *p)
\r
711 //modexWaitBorder();
\r
712 vga_wait_for_vsync();
\r
713 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
714 for(i=0; i<PAL_SIZE/2; i++)
\r
716 outp(PAL_DATA_REG, p[i]);
\r
718 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
719 vga_wait_for_vsync();
\r
720 for(; i<PAL_SIZE; i++)
\r
722 outp(PAL_DATA_REG, p[(i)]);
\r
727 modexPalUpdate0(byte *p)
\r
730 //modexWaitBorder();
\r
731 vga_wait_for_vsync();
\r
732 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
733 for(i=0; i<PAL_SIZE/2; i++)
\r
735 outp(PAL_DATA_REG, rand());
\r
737 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
738 vga_wait_for_vsync();
\r
739 for(; i<PAL_SIZE; i++)
\r
741 outp(PAL_DATA_REG, rand());
\r
746 modexPalOverscan(byte *p, word col)
\r
748 //modexWaitBorder();
\r
749 vga_wait_for_vsync();
\r
750 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
751 outp(PAL_DATA_REG, col);
\r
755 //i want to make another vesion that checks the palette when the palette is being appened~
\r
756 void modexchkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
760 pal = modexNewPal();
\r
762 //printf("q: %02d\n", (*q));
\r
763 printf("chkcolor start~\n");
\r
764 printf("1 (*z): %d\n", (*z)/3);
\r
765 printf("1 (*i): %d\n", (*i)/3);
\r
766 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
767 printf("wwwwwwwwwwwwwwww\n");
\r
768 //check palette for dups
\r
769 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
771 //printf("\n z: %d\n", (*z));
\r
772 //printf(" q: %d\n", (*q));
\r
773 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
776 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
779 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
780 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
784 else for(zz=0; zz<(*q); zz+=3)
\r
786 //printf("zz: %02d\n", zz/3);
\r
789 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
793 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
794 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
797 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
799 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
800 // 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
801 // 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
802 // //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
803 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
808 planned features that i plan to implement~
\r
809 image that has values on the pallete list!
\r
811 no... wait.... no wwww
\r
813 //for(zzii=0; zzii<3; zzii++)
\r
815 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
816 a[(((*z)+(*q)))]=zz;
\r
818 (*aa)=(((*z)+(*q)));
\r
819 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
820 // printf("\n aa: %d\n\n", (*aa));
\r
821 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
822 // printf("wwwwwwwwwwwwwwww\n\n");
\r
826 printf("================\n");
\r
827 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
828 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
829 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
830 printf("================\n");
\r
832 //printf("[%d]", (zz+q));
\r
836 printf("wwwwwwwwwwwwwwww\n");
\r
837 printf("2 (*z): %d\n", (*z)/3);
\r
838 printf("2 (*i): %d\n", (*i)/3);
\r
839 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
840 printf("chkcolor end~\n");
\r
844 void modexputPixel(page_t *page, int x, int y, byte color)
\r
846 word pageOff = (word) page->data;
\r
847 /* Each address accesses four neighboring pixels, so set
\r
848 Write Plane Enable according to which pixel we want
\r
849 to modify. The plane is determined by the two least
\r
850 significant bits of the x-coordinate: */
\r
851 modexSelectPlane(PLANE(x));
\r
852 //outp(SC_INDEX, 0x02);
\r
853 //outp(SC_DATA, 0x01 << (x & 3));
\r
855 /* The offset of the pixel into the video segment is
\r
856 offset = (width * y + x) / 4, and write the given
\r
857 color to the plane we selected above. Heed the active
\r
858 page start selection. */
\r
859 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
863 byte modexgetPixel(page_t *page, int x, int y)
\r
865 word pageOff = (word) page->data;
\r
866 /* Select the plane from which we must read the pixel color: */
\r
867 outpw(GC_INDEX, 0x04);
\r
868 outpw(GC_INDEX+1, x & 3);
\r
870 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
874 void modexhlin(page_t *page, word xl, word xh, word y, word color)
\r
879 for(x=0;x<xh*4;x+=4)
\r
881 if(x+4>=page[0].sw-1){ x=0; yy+=4; }
\r
882 modexClearRegion(page, x+xl, y+yy, 4, 4, color);
\r
884 //modexputPixel(page, x+xl, y, color);
\r
887 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str, boolean q)
\r
890 word addr = (word) romFontsData.l;
\r
895 w=romFonts[t].charSize;
\r
896 romFontsData.chw=0;
\r
898 for(; *str != '\0'; str++)
\r
901 if((c=='\n'/* || c=="\
\r
902 "*/) || romFontsData.chw
\r
905 romFontsData.chw=0;
\r
906 y+=romFonts[t].charSize;
\r
909 //load the letter 'A'
\r
915 MOV AL, c ; the letter
\r
918 ADD SI, AX ;the address of charcter
\r
926 //TODO: OPTIMIZE THIS!!!!
\r
927 modexDrawCharPBuf(page, x, y, t, col, bgcol, q);
\r
933 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
935 word i, s, o, w, j, xp;
\r
937 word addr = (word) l;
\r
964 for(; *str != '\0'; str++)
\r
967 if((c=='\n'/* || c=="\
\r
968 "*/)/* || chw>=page->width*/)
\r
974 //load the letter 'A'
\r
980 MOV AL, c ; the letter
\r
983 ADD SI, AX ;the address of charcter
\r
998 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
999 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1008 /* palette dump on display! */
\r
1009 void modexpdump(page_t *pee)
\r
1011 int mult=(QUADWH);
\r
1012 int palq=(mult)*TILEWH;
\r
1015 for(paly=0; paly<palq; paly+=mult){
\r
1016 for(palx=0; palx<palq; palx+=mult){
\r
1017 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
\r
1023 /////////////////////////////////////////////////////////////////////////////
\r
1025 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1026 // the Virtual screen. //
\r
1028 /////////////////////////////////////////////////////////////////////////////
\r
1029 void modexcls(page_t *page, byte color, byte *Where)
\r
1031 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1032 /* set map mask to all 4 planes */
\r
1033 outpw(SC_INDEX, 0xff02);
\r
1034 //_fmemset(VGA, color, 16000);
\r
1035 _fmemset(Where, color, page->width*(page->height)/4);
\r
1039 modexWaitBorder() {
\r
1040 while(inp(INPUT_STATUS_1) & 8) {
\r
1044 while(!(inp(INPUT_STATUS_1) & 8)) {
\r