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 struct vga_mode_params cm;
\r
86 vgaSetMode(VGA_256_COLOR_MODE);
\r
87 vga_enable_256color_modex();
\r
88 update_state_from_vga();
\r
89 vga_read_crtc_mode(&cm);
\r
94 //CRTParmCount = sizeof(ModeX_320x240regs) / sizeof(ModeX_320x240regs[0]);
\r
95 /* width and height */
\r
96 gv->video.page[0].sw = vga_state.vga_width = 320; // VGA lib currently does not update this
\r
97 gv->video.page[0].sh = vga_state.vga_height = 240; // VGA lib currently does not update this
\r
98 /* virtual width and height. match screen, at first */
\r
99 gv->video.page[0].height = gv->video.page[0].sh;
\r
100 gv->video.page[0].width = gv->video.page[0].sw;
\r
102 // mode X BYTE mode
\r
105 // 320x240 mode 60Hz
\r
106 cm.horizontal_total=0x5f + 5; /* CRTC[0] -5 */
\r
107 cm.horizontal_display_end=0x4f + 1; /* CRTC[1] -1 */
\r
108 cm.horizontal_blank_start=0x50 + 1; /* CRTC[2] */
\r
109 cm.horizontal_blank_end=0x82 + 1; /* CRTC[3] bit 0-4 & CRTC[5] bit 7 */
\r
110 cm.horizontal_start_retrace=0x54;/* CRTC[4] */
\r
111 cm.horizontal_end_retrace=0x80; /* CRTC[5] bit 0-4 */
\r
112 //cm.horizontal_start_delay_after_total=0x3e; /* CRTC[3] bit 5-6 */
\r
113 //cm.horizontal_start_delay_after_retrace=0x41; /* CRTC[5] bit 5-6 */
\r
114 cm.vertical_total = 0x20D + 2;
\r
115 cm.vertical_start_retrace = 0x1EA;
\r
116 cm.vertical_end_retrace = 0x1EC;
\r
117 cm.vertical_display_end = 480;
\r
118 cm.vertical_blank_start = 0x1E7 + 1;
\r
119 cm.vertical_blank_end = 0x206 + 1;
\r
120 cm.clock_select = 0; /* misc register = 0xE3 25MHz */
\r
123 cm.offset = (vga_state.vga_width / (4 * 2)); // 320 wide (40 x 4 pixel groups x 2)
\r
125 case 2: // TODO: 160x120 according to ModeX_160x120regs
\r
127 case 3: // TODO: 160x120 according to ModeX_320x200regs
\r
129 case 4: // TODO: 160x120 according to ModeX_192x144regs
\r
131 case 5: // TODO: 160x120 according to ModeX_256x192regs
\r
137 vga_state.vga_stride = cm.offset * 2;
\r
138 vga_write_crtc_mode(&cm,0);
\r
140 /* clear video memory */
\r
144 /* clear video memory */
\r
145 dword far*ptr=(dword far*)vga_state.vga_graphics_ram;//VGA; /* used for faster screen clearing */
\r
146 vga_write_sequencer(2/*map mask register*/,0xf/*all 4 planes*/);
\r
147 for(i = 0;i < 0x4000; i++) ptr[i] = 0x0000; // 0x4000 x dword = 64KB
\r
151 gv->video.page[0].tilesw = gv->video.page[0].sw/TILEWH;
\r
152 gv->video.page[0].tilesh = gv->video.page[0].sh/TILEWH;
\r
153 //TODO MAKE FLEXIBLE~
\r
154 gv->video.page[0].tilemidposscreenx = gv->video.page[0].tilesw;
\r
155 gv->video.page[0].tilemidposscreeny = (gv->video.page[0].tilesh/2)+1;
\r
156 #define PAGE_SIZE (word)(gv->video.page[0].sw/4 * gv->video.page[0].sh)
\r
161 /* TODO restore original mode and palette */
\r
162 vgaSetMode(TEXT_MODE);
\r
166 modexDefaultPage(page_t *p)
\r
170 /* default page values */
\r
171 page.data = vga_state.vga_graphics_ram;//VGA;
\r
176 page.width = p->sw;
\r
177 page.height = p->sh;
\r
178 page.tw = page.sw/TILEWH;
\r
179 page.th = page.sh/TILEWH;
\r
180 page.tilemidposscreenx = page.tw/2;
\r
181 page.tilemidposscreeny = (page.th/2)+1;
\r
182 page.tilesw=p->tilesw;
\r
183 page.tilesh=p->tilesh;
\r
184 //pageSize = p->sw*p->sh;
\r
190 /* returns the next page in contiguous memory
\r
191 * the next page will be the same size as p, by default
\r
194 modexNextPage(page_t *p) {
\r
197 result.data = p->data + (p->width/4)*p->height;
\r
200 result.width = p->width;
\r
201 result.height = p->height;
\r
202 result.tw = p->width/TILEWH;
\r
203 result.th = p->height/TILEWH;
\r
204 result.id = p->id+1;
\r
207 // return modexNextPageFlexibleSize(&p, p->width, p->height);
\r
210 //next page with defined dimentions~
\r
212 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
216 result.data = p->data + (p->width/4)*p->height; /* compute the offset */
\r
221 result.tw = p->width/TILEWH;
\r
222 result.th = p->height/TILEWH;
\r
223 result.id = p->id+1;
\r
230 modexShowPage(page_t *page) {
\r
236 /* calculate offset */
\r
237 offset = (word) page->data;
\r
238 offset += page->dy * (page->width >> 2 );
\r
239 offset += page->dx >> 2;
\r
241 /* calculate crtcOffset according to virtual width */
\r
242 crtcOffset = page->width >> 3;
\r
244 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
245 low_address = LOW_ADDRESS | (offset << 8);
\r
247 /* wait for appropriate timing and then program CRTC */
\r
248 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
249 outpw(CRTC_INDEX, high_address);
\r
250 outpw(CRTC_INDEX, low_address);
\r
251 outp(CRTC_INDEX, 0x13);
\r
252 outp(CRTC_DATA, crtcOffset);
\r
254 /* wait for one retrace */
\r
255 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
257 /* do PEL panning here */
\r
258 outp(AC_INDEX, 0x33);
\r
259 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
264 modexPanPage(page_t *page, int dx, int dy) {
\r
271 modexSelectPlane(byte plane) {
\r
272 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
273 outp(SC_DATA, plane);
\r
278 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
279 word pageOff = (word) page->data;
\r
280 word xoff=x/4; /* xoffset that begins each row */
\r
281 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
282 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
283 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
284 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
285 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
286 byte left = lclip[x&0x03];
\r
287 byte right = rclip[(x+w)&0x03];
\r
289 /* handle the case which requires an extra group */
\r
290 if((x & 0x03) && !((x+w) & 0x03)) {
\r
295 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
297 MOV DI, poffset ; go to the first pixel
\r
298 MOV DX, SC_INDEX ; point to the map mask
\r
302 MOV AL, color ; get ready to write colors
\r
304 MOV CX, scanCount ; count the line
\r
305 MOV BL, AL ; remember color
\r
306 MOV AL, left ; do the left clip
\r
307 OUT DX, AL ; set the left clip
\r
308 MOV AL, BL ; restore color
\r
309 STOSB ; write the color
\r
311 JZ SCAN_DONE ; handle 1 group stuff
\r
313 ;-- write the main body of the scanline
\r
314 MOV BL, AL ; remember color
\r
315 MOV AL, 0x0f ; write to all pixels
\r
317 MOV AL, BL ; restore color
\r
318 REP STOSB ; write the color
\r
320 MOV BL, AL ; remeber color
\r
322 OUT DX, AL ; do the right clip
\r
323 MOV AL, BL ; restore color
\r
324 STOSB ; write pixel
\r
325 ADD DI, nextRow ; go to the next row
\r
331 /* moved to src/lib/modex16/16render.c */
\r
333 /* copy a region of video memory from one page to another.
\r
334 * It assumes that the left edge of the tile is the same on both
\r
335 * regions and the memory areas do not overlap.
\r
338 modexCopyPageRegion(page_t *dest, page_t *src,
\r
341 word width, word height)
\r
343 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
344 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
345 word scans = width/4;
\r
346 word nextSrcRow = src->width/4 - scans - 1;
\r
347 word nextDestRow = dest->width/4 - scans - 1;
\r
348 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
349 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
350 byte left = lclip[sx&0x03];
\r
351 byte right = rclip[(sx+width)&0x03];
\r
354 MOV AX, SCREEN_SEG ; work in the vga space
\r
359 MOV DX, GC_INDEX ; turn off cpu bits
\r
363 MOV AX, SC_INDEX ; point to the mask register
\r
373 MOV CX, scans ; the number of latches
\r
375 MOV AL, left ; do the left column
\r
380 MOV AL, 0fh ; do the inner columns
\r
382 REP MOVSB ; copy the pixels
\r
384 MOV AL, right ; do the right column
\r
389 MOV AX, SI ; go the start of the next row
\r
390 ADD AX, nextSrcRow ;
\r
393 ADD AX, nextDestRow ;
\r
396 DEC height ; do the rest of the actions
\r
399 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
400 MOV AL, 0ffh ; none from latches
\r
406 /* fade and flash */
\r
408 modexFadeOn(word fade, byte *palette) {
\r
409 fadePalette(-fade, 64, 64/fade+1, palette);
\r
414 modexFadeOff(word fade, byte *palette) {
\r
415 fadePalette(fade, 0, 64/fade+1, palette);
\r
420 modexFlashOn(word fade, byte *palette) {
\r
421 fadePalette(fade, -64, 64/fade+1, palette);
\r
426 modexFlashOff(word fade, byte *palette) {
\r
427 fadePalette(-fade, 0, 64/fade+1, palette);
\r
432 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
436 /* handle the case where we just update */
\r
438 modexPalUpdate1(palette);
\r
442 while(iter > 0) { /* FadeLoop */
\r
443 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
444 tmppal[i] = palette[i] - dim;
\r
445 if(tmppal[i] > 127) {
\r
447 } else if(tmppal[i] > 63) {
\r
451 modexPalUpdate1(tmppal);
\r
458 /* save and load */
\r
460 modexPalSave(byte *palette) {
\r
463 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
464 for(i=0; i<PAL_SIZE; i++) {
\r
465 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
473 ptr = malloc(PAL_SIZE);
\r
475 /* handle errors */
\r
477 printf("Could not allocate palette.\n");
\r
486 modexLoadPalFile(byte *filename, byte **palette) {
\r
490 /* free the palette if it exists */
\r
495 /* allocate the new palette */
\r
496 *palette = modexNewPal();
\r
498 /* open the file */
\r
499 file = fopen(filename, "rb");
\r
501 printf("Could not open palette file: %s\n", filename);
\r
505 /* read the file */
\r
507 while(!feof(file)) {
\r
508 *ptr++ = fgetc(file);
\r
516 modexSavePalFile(char *filename, byte *pal) {
\r
520 /* open the file for writing */
\r
521 file = fopen(filename, "wb");
\r
523 printf("Could not open %s for writing\n", filename);
\r
527 /* write the data to the file */
\r
528 fwrite(pal, 1, PAL_SIZE, file);
\r
536 fadePalette(-1, 64, 1, tmppal);
\r
542 fadePalette(-1, -64, 1, tmppal);
\r
548 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
550 byte *p = bmp->palette;
\r
554 static word a[PAL_SIZE]; //palette array of change values!
\r
555 word z=0, aq=0, aa=0, pp=0;
\r
557 //modexWaitBorder();
\r
558 vga_wait_for_vsync();
\r
561 memset(a, -1, sizeof(a));
\r
562 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
572 // printf("q: %02d\n", (q));
\r
573 // printf("qq: %02d\n", (qq));
\r
574 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
575 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
577 if((*i)<PAL_SIZE/2 && w==0)
\r
579 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
581 //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
582 //____ 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
583 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
588 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
590 //printf("qp=%d\n", qp);
\r
591 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
592 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
593 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
594 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
598 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
600 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
601 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
602 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
605 //if(qp>0) printf("qp=%d\n", qp);
\r
606 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
608 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
609 vga_wait_for_vsync();
\r
610 if((*i)>=PAL_SIZE/2 && w==0)
\r
612 for(; (*i)<PAL_SIZE; (*i)++)
\r
614 //____ 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
615 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
620 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
622 //printf("qp=%d\n", qp);
\r
623 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
624 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
625 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
626 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
630 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
631 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
632 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
635 //printf(" (*i)=%d\n", (*i)/3);
\r
638 printf("\nqqqqqqqq\n\n");
\r
644 long bufSize = (bmp->width * bmp->height);
\r
646 //printf("1(*i)=%02d\n", (*i)/3);
\r
647 //printf("1z=%02d\n", z/3);
\r
648 modexchkcolor(bmp, &q, &a, &aa, &z, i);
\r
649 //printf("2(*i)=%02d\n", (*i)/3);
\r
650 //printf("2z=%02d\n", z/3);
\r
655 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
656 if(a[aq]==-1) aq++;
\r
657 else { aqoffset++; break; }
\r
659 //update the image data here!
\r
660 for(lq=0; lq<bufSize; lq++)
\r
664 use a[qp] instead of bmp->offset for this spot!
\r
669 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
672 //(offset/bmp->offset)*bmp->offset
\r
675 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
676 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
677 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
678 /*if(bmp->data[lq]+bmp->offset==aq)
\r
680 //printf("%02d", bmp->data[lq]);
\r
681 //printf("\n%02d\n", bmp->offset);
\r
682 printf("aq=%02d ", aq);
\r
683 printf("a[aq]=%02d ", a[aq]);
\r
684 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
685 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
686 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
687 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
688 // printf("_%d ", bmp->data[lq]);
\r
689 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
691 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
693 if(bmp->data[lq]+bmp->offset >= aq)
\r
695 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
696 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
698 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
701 //printf("%02d`", bmp->data[lq]);
\r
702 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
705 //printf(" aq=%02d\n", aq);
\r
706 //printf(" aa=%02d\n", aa);
\r
708 //update the palette~
\r
709 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
712 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
717 modexPalUpdate1(byte *p)
\r
720 //modexWaitBorder();
\r
721 vga_wait_for_vsync();
\r
722 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
723 for(i=0; i<PAL_SIZE/2; i++)
\r
725 outp(PAL_DATA_REG, p[i]);
\r
727 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
728 vga_wait_for_vsync();
\r
729 for(; i<PAL_SIZE; i++)
\r
731 outp(PAL_DATA_REG, p[(i)]);
\r
736 modexPalUpdate0(byte *p)
\r
739 //modexWaitBorder();
\r
740 vga_wait_for_vsync();
\r
741 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
742 for(i=0; i<PAL_SIZE/2; i++)
\r
744 outp(PAL_DATA_REG, rand());
\r
746 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
747 vga_wait_for_vsync();
\r
748 for(; i<PAL_SIZE; i++)
\r
750 outp(PAL_DATA_REG, rand());
\r
755 modexPalOverscan(byte *p, word col)
\r
757 //modexWaitBorder();
\r
758 vga_wait_for_vsync();
\r
759 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
760 outp(PAL_DATA_REG, col);
\r
764 //i want to make another vesion that checks the palette when the palette is being appened~
\r
765 void modexchkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
769 pal = modexNewPal();
\r
771 //printf("q: %02d\n", (*q));
\r
772 printf("chkcolor start~\n");
\r
773 printf("1 (*z): %d\n", (*z)/3);
\r
774 printf("1 (*i): %d\n", (*i)/3);
\r
775 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
776 printf("wwwwwwwwwwwwwwww\n");
\r
777 //check palette for dups
\r
778 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
780 //printf("\n z: %d\n", (*z));
\r
781 //printf(" q: %d\n", (*q));
\r
782 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
785 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
788 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
789 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
793 else for(zz=0; zz<(*q); zz+=3)
\r
795 //printf("zz: %02d\n", zz/3);
\r
798 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
802 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
803 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
806 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
808 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
809 // 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
810 // 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
811 // //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
812 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
817 planned features that i plan to implement~
\r
818 image that has values on the pallete list!
\r
820 no... wait.... no wwww
\r
822 //for(zzii=0; zzii<3; zzii++)
\r
824 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
825 a[(((*z)+(*q)))]=zz;
\r
827 (*aa)=(((*z)+(*q)));
\r
828 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
829 // printf("\n aa: %d\n\n", (*aa));
\r
830 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
831 // printf("wwwwwwwwwwwwwwww\n\n");
\r
835 printf("================\n");
\r
836 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
837 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
838 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
839 printf("================\n");
\r
841 //printf("[%d]", (zz+q));
\r
845 printf("wwwwwwwwwwwwwwww\n");
\r
846 printf("2 (*z): %d\n", (*z)/3);
\r
847 printf("2 (*i): %d\n", (*i)/3);
\r
848 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
849 printf("chkcolor end~\n");
\r
853 void modexputPixel(page_t *page, int x, int y, byte color)
\r
855 word pageOff = (word) page->data;
\r
856 /* Each address accesses four neighboring pixels, so set
\r
857 Write Plane Enable according to which pixel we want
\r
858 to modify. The plane is determined by the two least
\r
859 significant bits of the x-coordinate: */
\r
860 modexSelectPlane(PLANE(x));
\r
861 //outp(SC_INDEX, 0x02);
\r
862 //outp(SC_DATA, 0x01 << (x & 3));
\r
864 /* The offset of the pixel into the video segment is
\r
865 offset = (width * y + x) / 4, and write the given
\r
866 color to the plane we selected above. Heed the active
\r
867 page start selection. */
\r
868 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
872 byte modexgetPixel(page_t *page, int x, int y)
\r
874 word pageOff = (word) page->data;
\r
875 /* Select the plane from which we must read the pixel color: */
\r
876 outpw(GC_INDEX, 0x04);
\r
877 outpw(GC_INDEX+1, x & 3);
\r
879 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
883 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
887 word addr = (word) romFontsData.l;
\r
888 word addrq = (page->width/4) * y + (x / 4) + ((word)page->data);
\r
889 word addrr = addrq;
\r
894 w=romFonts[t].charSize;
\r
895 romFontsData.chw=0;
\r
897 for(; *str != '\0'; str++)
\r
903 romFontsData.chw = 0;
\r
904 addrq += (page->width / 4) * 8;
\r
910 // load the character into romFontsData.l
\r
911 // no need for inline assembly!
\r
912 // NTS: It might even be faster to just let the modexDrawChar point directly at ROM font than to copy per char! --J.C.
\r
913 _fmemcpy(romFontsData.l,MK_FP(s,o+(w*c))/*ROM font location*/,w/*char size*/);
\r
914 modexDrawChar(page, x_draw/*for mode X planar use*/, t, col, bgcol, addrr);
\r
915 x_draw += 8; /* track X for edge of screen */
\r
916 addrr += 2; /* move 8 pixels over (2 x 4 planar pixels per byte) */
\r
920 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
922 word i, s, o, w, j, xp;
\r
924 word addr = (word) l;
\r
951 for(; *str != '\0'; str++)
\r
954 if((c=='\n'/* || c=="\
\r
955 "*/)/* || chw>=page->width*/)
\r
961 //load the letter 'A'
\r
967 MOV AL, c ; the letter
\r
970 ADD SI, AX ;the address of charcter
\r
985 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
986 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
995 /* palette dump on display! */
\r
996 void modexpdump(page_t *pee)
\r
999 int palq=(mult)*TILEWH;
\r
1002 for(paly=0; paly<palq; paly+=mult){
\r
1003 for(palx=0; palx<palq; palx+=mult){
\r
1004 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
\r
1010 /////////////////////////////////////////////////////////////////////////////
\r
1012 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1013 // the Virtual screen. //
\r
1015 /////////////////////////////////////////////////////////////////////////////
\r
1016 void modexcls(page_t *page, byte color, byte *Where)
\r
1018 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1019 /* set map mask to all 4 planes */
\r
1020 outpw(SC_INDEX, 0xff02);
\r
1021 //_fmemset(VGA, color, 16000);
\r
1022 _fmemset(Where, color, page->width*(page->height)/4);
\r
1026 modexWaitBorder() {
\r
1027 while(inp(INPUT_STATUS_1) & 8) {
\r
1031 while(!(inp(INPUT_STATUS_1) & 8)) {
\r
1041 m = int10_getmode();
\r
1042 if ((rp=vga_state.vga_graphics_ram) != NULL && !(m <= 3 || m == 7)) {
\r
1043 unsigned int i,im;
\r
1045 im = (FP_SEG(vga_state.vga_graphics_ram_fence) - FP_SEG(vga_state.vga_graphics_ram));
\r
1046 if (im > 0xFFE) im = 0xFFE;
\r
1048 for (i=0;i < im;i++) vga_state.vga_graphics_ram[i] = 0;
\r
1050 else if ((ap=vga_state.vga_alpha_ram) != NULL) {
\r
1051 unsigned int i,im;
\r
1053 im = (FP_SEG(vga_state.vga_alpha_ram_fence) - FP_SEG(vga_state.vga_alpha_ram));
\r
1054 if (im > 0x7FE) im = 0x7FE;
\r
1055 im <<= 4 - 1; /* because ptr is type uint16_t */
\r
1056 for (i=0;i < im;i++) vga_state.vga_alpha_ram[i] = 0x0720;
\r
1059 printf("WARNING: bios cls no ptr\n");
\r