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
160 /* VGAmodeX restores original mode and palette */
\r
161 vgaSetMode(TEXT_MODE);
\r
165 modexDefaultPage(page_t *p)
\r
169 /* default page values */
\r
170 page.data = vga_state.vga_graphics_ram;//VGA;
\r
175 page.width = p->sw;
\r
176 page.height = p->sh;
\r
177 page.tw = page.sw/TILEWH;
\r
178 page.th = page.sh/TILEWH;
\r
179 page.tilemidposscreenx = page.tw/2;
\r
180 page.tilemidposscreeny = (page.th/2)+1;
\r
181 page.tilesw=p->tilesw;
\r
182 page.tilesh=p->tilesh;
\r
183 page.pagesize = page.width*page.height;
\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
204 result.pagesize = p->pagesize;
\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
223 result.pagesize = result.width*result.height;
\r
228 void modexCalcVmemRemain(video_t *video)
\r
231 video->vmem_remain=262144;
\r
232 for(i=0; i<=video->num_of_pages; i++)
\r
234 video->vmem_remain-=video->page[i].pagesize;
\r
238 void modexHiganbanaPageSetup(video_t *video)
\r
240 (video->page[0]) = modexDefaultPage(&(video->page[0])); video->num_of_pages++;
\r
241 video->page[0].width += (TILEWH*2); video->page[0].height += (TILEWH*2);
\r
242 (video->page[1]) = modexNextPage(&(video->page[0])); video->num_of_pages++;
\r
243 modexCalcVmemRemain(video);
\r
244 (video->page[2]) = modexNextPageFlexibleSize(&(video->page[1]), video->page[0].sw, video->page[0].sh); //(352*176)+1024 is the remaining amount of memory left wwww
\r
245 video->num_of_pages++;
\r
246 modexCalcVmemRemain(video);
\r
247 //gvar.video.page[2] = modexNextPage0(mv2.page, 320, 192); //(352*176)+1024 is the remaining amount of memory left wwww
\r
250 modexShowPage(page_t *page) {
\r
256 /* calculate offset */
\r
257 offset = (word) page->data;
\r
258 offset += page->dy * (page->width >> 2 );
\r
259 offset += page->dx >> 2;
\r
261 /* calculate crtcOffset according to virtual width */
\r
262 crtcOffset = page->width >> 3;
\r
264 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
265 low_address = LOW_ADDRESS | (offset << 8);
\r
267 /* wait for appropriate timing and then program CRTC */
\r
268 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
269 outpw(CRTC_INDEX, high_address);
\r
270 outpw(CRTC_INDEX, low_address);
\r
271 outp(CRTC_INDEX, 0x13);
\r
272 outp(CRTC_DATA, crtcOffset);
\r
274 /* wait for one retrace */
\r
275 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
277 /* do PEL panning here */
\r
278 outp(AC_INDEX, 0x33);
\r
279 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
284 modexPanPage(page_t *page, int dx, int dy) {
\r
291 modexSelectPlane(byte plane) {
\r
292 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
293 outp(SC_DATA, plane);
\r
298 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
299 word pageOff = (word) page->data;
\r
300 word xoff=x/4; /* xoffset that begins each row */
\r
301 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
302 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
303 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
304 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
305 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
306 byte left = lclip[x&0x03];
\r
307 byte right = rclip[(x+w)&0x03];
\r
309 /* handle the case which requires an extra group */
\r
310 if((x & 0x03) && !((x+w) & 0x03)) {
\r
315 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
317 MOV DI, poffset ; go to the first pixel
\r
318 MOV DX, SC_INDEX ; point to the map mask
\r
322 MOV AL, color ; get ready to write colors
\r
324 MOV CX, scanCount ; count the line
\r
325 MOV BL, AL ; remember color
\r
326 MOV AL, left ; do the left clip
\r
327 OUT DX, AL ; set the left clip
\r
328 MOV AL, BL ; restore color
\r
329 STOSB ; write the color
\r
331 JZ SCAN_DONE ; handle 1 group stuff
\r
333 ;-- write the main body of the scanline
\r
334 MOV BL, AL ; remember color
\r
335 MOV AL, 0x0f ; write to all pixels
\r
337 MOV AL, BL ; restore color
\r
338 REP STOSB ; write the color
\r
340 MOV BL, AL ; remeber color
\r
342 OUT DX, AL ; do the right clip
\r
343 MOV AL, BL ; restore color
\r
344 STOSB ; write pixel
\r
345 ADD DI, nextRow ; go to the next row
\r
351 /* moved to src/lib/modex16/16render.c */
\r
353 /* copy a region of video memory from one page to another.
\r
354 * It assumes that the left edge of the tile is the same on both
\r
355 * regions and the memory areas do not overlap.
\r
358 modexCopyPageRegion(page_t *dest, page_t *src,
\r
361 word width, word height)
\r
363 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
364 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
365 word scans = width/4;
\r
366 word nextSrcRow = src->width/4 - scans - 1;
\r
367 word nextDestRow = dest->width/4 - scans - 1;
\r
368 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
369 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
370 byte left = lclip[sx&0x03];
\r
371 byte right = rclip[(sx+width)&0x03];
\r
374 MOV AX, SCREEN_SEG ; work in the vga space
\r
379 MOV DX, GC_INDEX ; turn off cpu bits
\r
383 MOV AX, SC_INDEX ; point to the mask register
\r
393 MOV CX, scans ; the number of latches
\r
395 MOV AL, left ; do the left column
\r
400 MOV AL, 0fh ; do the inner columns
\r
402 REP MOVSB ; copy the pixels
\r
404 MOV AL, right ; do the right column
\r
409 MOV AX, SI ; go the start of the next row
\r
410 ADD AX, nextSrcRow ;
\r
413 ADD AX, nextDestRow ;
\r
416 DEC height ; do the rest of the actions
\r
419 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
420 MOV AL, 0ffh ; none from latches
\r
426 /* fade and flash */
\r
428 modexFadeOn(word fade, byte *palette) {
\r
429 fadePalette(-fade, 64, 64/fade+1, palette);
\r
434 modexFadeOff(word fade, byte *palette) {
\r
435 fadePalette(fade, 0, 64/fade+1, palette);
\r
440 modexFlashOn(word fade, byte *palette) {
\r
441 fadePalette(fade, -64, 64/fade+1, palette);
\r
446 modexFlashOff(word fade, byte *palette) {
\r
447 fadePalette(-fade, 0, 64/fade+1, palette);
\r
452 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
456 /* handle the case where we just update */
\r
458 modexPalUpdate1(palette);
\r
462 while(iter > 0) { /* FadeLoop */
\r
463 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
464 tmppal[i] = palette[i] - dim;
\r
465 if(tmppal[i] > 127) {
\r
467 } else if(tmppal[i] > 63) {
\r
471 modexPalUpdate1(tmppal);
\r
478 /* save and load */
\r
480 modexPalSave(byte *palette) {
\r
483 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
484 for(i=0; i<PAL_SIZE; i++) {
\r
485 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
493 ptr = malloc(PAL_SIZE);
\r
495 /* handle errors */
\r
497 printf("Could not allocate palette.\n");
\r
506 modexLoadPalFile(byte *filename, byte **palette) {
\r
510 /* free the palette if it exists */
\r
515 /* allocate the new palette */
\r
516 *palette = modexNewPal();
\r
518 /* open the file */
\r
519 file = fopen(filename, "rb");
\r
521 printf("Could not open palette file: %s\n", filename);
\r
525 /* read the file */
\r
527 while(!feof(file)) {
\r
528 *ptr++ = fgetc(file);
\r
536 modexSavePalFile(char *filename, byte *pal) {
\r
540 /* open the file for writing */
\r
541 file = fopen(filename, "wb");
\r
543 printf("Could not open %s for writing\n", filename);
\r
547 /* write the data to the file */
\r
548 fwrite(pal, 1, PAL_SIZE, file);
\r
556 fadePalette(-1, 64, 1, tmppal);
\r
562 fadePalette(-1, -64, 1, tmppal);
\r
568 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
570 byte *p = bmp->palette;
\r
574 static word a[PAL_SIZE]; //palette array of change values!
\r
575 word z=0, aq=0, aa=0, pp=0;
\r
577 //modexWaitBorder();
\r
578 vga_wait_for_vsync();
\r
581 memset(a, -1, sizeof(a));
\r
582 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
592 // printf("q: %02d\n", (q));
\r
593 // printf("qq: %02d\n", (qq));
\r
594 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
595 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
597 if((*i)<PAL_SIZE/2 && w==0)
\r
599 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
601 //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
602 //____ 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
603 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
608 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
610 //printf("qp=%d\n", qp);
\r
611 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
612 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
613 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
614 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
618 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
620 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
621 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
622 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
625 //if(qp>0) printf("qp=%d\n", qp);
\r
626 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
628 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
629 vga_wait_for_vsync();
\r
630 if((*i)>=PAL_SIZE/2 && w==0)
\r
632 for(; (*i)<PAL_SIZE; (*i)++)
\r
634 //____ 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
635 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
640 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
642 //printf("qp=%d\n", qp);
\r
643 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
644 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
645 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
646 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
650 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
651 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
652 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
655 //printf(" (*i)=%d\n", (*i)/3);
\r
658 printf("\nqqqqqqqq\n\n");
\r
664 long bufSize = (bmp->width * bmp->height);
\r
666 //printf("1(*i)=%02d\n", (*i)/3);
\r
667 //printf("1z=%02d\n", z/3);
\r
668 modexchkcolor(bmp, &q, &a, &aa, &z, i);
\r
669 //printf("2(*i)=%02d\n", (*i)/3);
\r
670 //printf("2z=%02d\n", z/3);
\r
675 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
676 if(a[aq]==-1) aq++;
\r
677 else { aqoffset++; break; }
\r
679 //update the image data here!
\r
680 for(lq=0; lq<bufSize; lq++)
\r
684 use a[qp] instead of bmp->offset for this spot!
\r
689 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
692 //(offset/bmp->offset)*bmp->offset
\r
695 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
696 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
697 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
698 /*if(bmp->data[lq]+bmp->offset==aq)
\r
700 //printf("%02d", bmp->data[lq]);
\r
701 //printf("\n%02d\n", bmp->offset);
\r
702 printf("aq=%02d ", aq);
\r
703 printf("a[aq]=%02d ", a[aq]);
\r
704 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
705 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
706 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
707 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
708 // printf("_%d ", bmp->data[lq]);
\r
709 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
711 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
713 if(bmp->data[lq]+bmp->offset >= aq)
\r
715 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
716 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
718 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
721 //printf("%02d`", bmp->data[lq]);
\r
722 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
725 //printf(" aq=%02d\n", aq);
\r
726 //printf(" aa=%02d\n", aa);
\r
728 //update the palette~
\r
729 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
732 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
737 modexPalUpdate1(byte *p)
\r
740 //modexWaitBorder();
\r
741 vga_wait_for_vsync();
\r
742 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
743 for(i=0; i<PAL_SIZE/2; i++)
\r
745 outp(PAL_DATA_REG, p[i]);
\r
747 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
748 vga_wait_for_vsync();
\r
749 for(; i<PAL_SIZE; i++)
\r
751 outp(PAL_DATA_REG, p[(i)]);
\r
756 modexPalUpdate0(byte *p)
\r
759 //modexWaitBorder();
\r
760 vga_wait_for_vsync();
\r
761 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
762 for(i=0; i<PAL_SIZE/2; i++)
\r
764 outp(PAL_DATA_REG, rand());
\r
766 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
767 vga_wait_for_vsync();
\r
768 for(; i<PAL_SIZE; i++)
\r
770 outp(PAL_DATA_REG, rand());
\r
775 modexPalOverscan(byte *p, word col)
\r
777 //modexWaitBorder();
\r
778 vga_wait_for_vsync();
\r
779 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
780 outp(PAL_DATA_REG, col);
\r
784 //i want to make another vesion that checks the palette when the palette is being appened~
\r
785 void modexchkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
789 pal = modexNewPal();
\r
791 //printf("q: %02d\n", (*q));
\r
792 printf("chkcolor start~\n");
\r
793 printf("1 (*z): %d\n", (*z)/3);
\r
794 printf("1 (*i): %d\n", (*i)/3);
\r
795 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
796 printf("wwwwwwwwwwwwwwww\n");
\r
797 //check palette for dups
\r
798 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
800 //printf("\n z: %d\n", (*z));
\r
801 //printf(" q: %d\n", (*q));
\r
802 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
805 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
808 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
809 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
813 else for(zz=0; zz<(*q); zz+=3)
\r
815 //printf("zz: %02d\n", zz/3);
\r
818 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
822 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
823 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
826 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
828 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
829 // 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
830 // 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
831 // //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
832 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
837 planned features that i plan to implement~
\r
838 image that has values on the pallete list!
\r
840 no... wait.... no wwww
\r
842 //for(zzii=0; zzii<3; zzii++)
\r
844 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
845 a[(((*z)+(*q)))]=zz;
\r
847 (*aa)=(((*z)+(*q)));
\r
848 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
849 // printf("\n aa: %d\n\n", (*aa));
\r
850 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
851 // printf("wwwwwwwwwwwwwwww\n\n");
\r
855 printf("================\n");
\r
856 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
857 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
858 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
859 printf("================\n");
\r
861 //printf("[%d]", (zz+q));
\r
865 printf("wwwwwwwwwwwwwwww\n");
\r
866 printf("2 (*z): %d\n", (*z)/3);
\r
867 printf("2 (*i): %d\n", (*i)/3);
\r
868 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
869 printf("chkcolor end~\n");
\r
873 void modexputPixel(page_t *page, int x, int y, byte color)
\r
875 word pageOff = (word) page->data;
\r
876 /* Each address accesses four neighboring pixels, so set
\r
877 Write Plane Enable according to which pixel we want
\r
878 to modify. The plane is determined by the two least
\r
879 significant bits of the x-coordinate: */
\r
880 modexSelectPlane(PLANE(x));
\r
881 //outp(SC_INDEX, 0x02);
\r
882 //outp(SC_DATA, 0x01 << (x & 3));
\r
884 /* The offset of the pixel into the video segment is
\r
885 offset = (width * y + x) / 4, and write the given
\r
886 color to the plane we selected above. Heed the active
\r
887 page start selection. */
\r
888 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
892 byte modexgetPixel(page_t *page, int x, int y)
\r
894 word pageOff = (word) page->data;
\r
895 /* Select the plane from which we must read the pixel color: */
\r
896 outpw(GC_INDEX, 0x04);
\r
897 outpw(GC_INDEX+1, x & 3);
\r
899 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
903 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
907 word addr = (word) romFontsData.l;
\r
908 word addrq = (page->width/4) * y + (x / 4) + ((word)page->data);
\r
909 word addrr = addrq;
\r
914 w=romFonts[t].charSize;
\r
915 romFontsData.chw=0;
\r
917 for(; *str != '\0'; str++)
\r
923 romFontsData.chw = 0;
\r
924 addrq += (page->width / 4) * 8;
\r
930 // load the character into romFontsData.l
\r
931 // no need for inline assembly!
\r
932 // NTS: It might even be faster to just let the modexDrawChar point directly at ROM font than to copy per char! --J.C.
\r
933 _fmemcpy(romFontsData.l,MK_FP(s,o+(w*c))/*ROM font location*/,w/*char size*/);
\r
934 modexDrawChar(page, x_draw/*for mode X planar use*/, t, col, bgcol, addrr);
\r
935 x_draw += 8; /* track X for edge of screen */
\r
936 addrr += 2; /* move 8 pixels over (2 x 4 planar pixels per byte) */
\r
940 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
942 word i, s, o, w, j, xp;
\r
944 word addr = (word) l;
\r
971 for(; *str != '\0'; str++)
\r
974 if((c=='\n'/* || c=="\
\r
975 "*/)/* || chw>=page->width*/)
\r
981 //load the letter 'A'
\r
987 MOV AL, c ; the letter
\r
990 ADD SI, AX ;the address of charcter
\r
1005 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1006 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1015 /* palette dump on display! */
\r
1016 void modexpdump(page_t *pee)
\r
1018 int mult=(QUADWH);
\r
1019 int palq=(mult)*TILEWH;
\r
1022 for(paly=0; paly<palq; paly+=mult){
\r
1023 for(palx=0; palx<palq; palx+=mult){
\r
1024 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
\r
1030 /////////////////////////////////////////////////////////////////////////////
\r
1032 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1033 // the Virtual screen. //
\r
1035 /////////////////////////////////////////////////////////////////////////////
\r
1036 void modexcls(page_t *page, byte color, byte *Where)
\r
1038 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1039 /* set map mask to all 4 planes */
\r
1040 outpw(SC_INDEX, 0xff02);
\r
1041 //_fmemset(VGA, color, 16000);
\r
1042 _fmemset(Where, color, page->width*(page->height)/4);
\r
1046 modexWaitBorder() {
\r
1047 while(inp(INPUT_STATUS_1) & 8) {
\r
1051 while(!(inp(INPUT_STATUS_1) & 8)) {
\r
1061 m = int10_getmode();
\r
1062 if ((rp=vga_state.vga_graphics_ram) != NULL && !(m <= 3 || m == 7)) {
\r
1063 unsigned int i,im;
\r
1065 im = (FP_SEG(vga_state.vga_graphics_ram_fence) - FP_SEG(vga_state.vga_graphics_ram));
\r
1066 if (im > 0xFFE) im = 0xFFE;
\r
1068 for (i=0;i < im;i++) vga_state.vga_graphics_ram[i] = 0;
\r
1070 else if ((ap=vga_state.vga_alpha_ram) != NULL) {
\r
1071 unsigned int i,im;
\r
1073 im = (FP_SEG(vga_state.vga_alpha_ram_fence) - FP_SEG(vga_state.vga_alpha_ram));
\r
1074 if (im > 0x7FE) im = 0x7FE;
\r
1075 im <<= 4 - 1; /* because ptr is type uint16_t */
\r
1076 for (i=0;i < im;i++) vga_state.vga_alpha_ram[i] = 0x0720;
\r
1079 printf("WARNING: bios cls no ptr\n");
\r