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
152 // gv->video.page[0].tw = gv->video.page[0].sw/TILEWH;
\r
153 // gv->video.page[0].th = gv->video.page[0].sh/TILEWH;
\r
155 //TODO MAKE FLEXIBLE~
\r
156 // gv->video.page[0].tilemidposscreenx = gv->video.page[0].tilesw;
\r
157 // gv->video.page[0].tilemidposscreeny = (gv->video.page[0].tilesh/2)+1;
\r
158 gv->video.num_of_pages=0;
\r
163 /* VGAmodeX restores original mode and palette */
\r
164 vgaSetMode(TEXT_MODE);
\r
168 modexDefaultPage(page_t *p)
\r
172 /* default page values */
\r
174 //page.data = (byte far *)(vga_state.vga_graphics_ram);
\r
175 page.data = (vga_state.vga_graphics_ram);
\r
180 page.width = p->sw+TILEWHD;
\r
181 page.height = p->sh+TILEWHD;
\r
182 page.tw = page.sw/TILEWH;
\r
183 page.th = page.sh/TILEWH;
\r
184 page.tilesw=page.width/TILEWH;
\r
185 page.tilesh=page.height/TILEWH;
\r
186 page.tilemidposscreenx = page.tw/2;
\r
187 page.tilemidposscreeny = (page.th/2)+1;
\r
188 page.pagesize = (sdiword)(page.width/4)*page.height;
\r
194 /* returns the next page in contiguous memory
\r
195 * the next page will be the same size as p, by default
\r
198 modexNextPage(page_t *p) {
\r
201 result.data = p->data + (p->pagesize);
\r
204 result.width = p->width;
\r
205 result.height = p->height;
\r
208 result.tilesw = p->tilesw;
\r
209 result.tilesh = p->tilesh;
\r
210 result.id = p->id+1;
\r
211 result.pagesize = p->pagesize;
\r
216 //next page with defined dimentions~
\r
218 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
222 result.data = p->data + (p->pagesize); /* compute the offset */
\r
227 result.tw = result.sw/TILEWH;
\r
228 result.th = result.sh/TILEWH;
\r
229 result.tilesw=result.width/TILEWH;
\r
230 result.tilesh=result.height/TILEWH;
\r
231 result.id = p->id+1;
\r
232 result.pagesize = (sdiword)(result.width/4)*result.height;
\r
237 void modexCalcVmemRemain(video_t *video)
\r
240 //printf("\n\n 1st vmem_remain=%ld\n", video->vmem_remain);
\r
241 for(i=0; i<=video->num_of_pages-1; i++)
\r
243 video->vmem_remain-=video->page[i].pagesize;
\r
244 //printf(" [%u], video->page[i].pagesize=%ld\n", i, video->page[i].pagesize);
\r
245 //printf(" [%u], vmem_remain=%ld\n", i, video->vmem_remain);
\r
249 void modexHiganbanaPageSetup(video_t *video)
\r
251 video->vmem_remain=262144L;
\r
252 (video->page[0]) = modexDefaultPage(&(video->page[0])); video->num_of_pages++;
\r
253 //video->page[0].width += (TILEWHD); video->page[0].height += (TILEWHD);
\r
254 (video->page[1]) = modexNextPage(&(video->page[0])); video->num_of_pages++;
\r
255 //(video->page[2]) = modexNextPageFlexibleSize(&(video->page[1]), video->page[0].width, video->page[0].sh-40); video->num_of_pages++;
\r
256 //(video->page[3]) = modexNextPageFlexibleSize(&(video->page[2]), TILEWH, TILEWH); video->num_of_pages++;
\r
257 modexCalcVmemRemain(video);
\r
262 modexShowPage(page_t *page) {
\r
268 /* calculate offset */
\r
269 offset = (word) page->data;
\r
270 offset += page->dy * (page->width >> 2 );
\r
271 offset += page->dx >> 2;
\r
273 /* calculate crtcOffset according to virtual width */
\r
274 crtcOffset = page->width >> 3;
\r
276 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
277 low_address = LOW_ADDRESS | (offset << 8);
\r
279 /* wait for appropriate timing and then program CRTC */
\r
280 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
281 outpw(CRTC_INDEX, high_address);
\r
282 outpw(CRTC_INDEX, low_address);
\r
283 outp(CRTC_INDEX, 0x13);
\r
284 outp(CRTC_DATA, crtcOffset);
\r
286 /* wait for one retrace */
\r
287 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
289 /* do PEL panning here */
\r
290 outp(AC_INDEX, 0x33);
\r
291 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
296 modexPanPage(page_t *page, int dx, int dy) {
\r
303 modexSelectPlane(byte plane) {
\r
304 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
305 outp(SC_DATA, plane);
\r
310 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
311 word pageOff = (word) page->data;
\r
312 word xoff=x/4; /* xoffset that begins each row */
\r
313 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
314 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
315 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
316 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
317 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
318 byte left = lclip[x&0x03];
\r
319 byte right = rclip[(x+w)&0x03];
\r
321 /* handle the case which requires an extra group */
\r
322 if((x & 0x03) && !((x+w) & 0x03)) {
\r
335 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
337 MOV DI, poffset ; go to the first pixel
\r
338 MOV DX, SC_INDEX ; point to the map mask
\r
342 MOV AL, color ; get ready to write colors
\r
344 MOV CX, scanCount ; count the line
\r
345 MOV BL, AL ; remember color
\r
346 MOV AL, left ; do the left clip
\r
347 OUT DX, AL ; set the left clip
\r
348 MOV AL, BL ; restore color
\r
349 STOSB ; write the color
\r
351 JZ SCAN_DONE ; handle 1 group stuff
\r
353 ;-- write the main body of the scanline
\r
354 MOV BL, AL ; remember color
\r
355 MOV AL, 0x0f ; write to all pixels
\r
357 MOV AL, BL ; restore color
\r
358 REP STOSB ; write the color
\r
360 MOV BL, AL ; remeber color
\r
362 OUT DX, AL ; do the right clip
\r
363 MOV AL, BL ; restore color
\r
364 STOSB ; write pixel
\r
365 ADD DI, nextRow ; go to the next row
\r
379 /* moved to src/lib/modex16/16render.c */
\r
381 /* copy a region of video memory from one page to another.
\r
382 * It assumes that the left edge of the tile is the same on both
\r
383 * regions and the memory areas do not overlap.
\r
386 modexCopyPageRegion(page_t *dest, page_t *src,
\r
389 word width, word height)
\r
391 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
392 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
393 word scans = vga_state.vga_stride;
\r
394 word nextSrcRow = src->width/4 - scans - 1;
\r
395 word nextDestRow = dest->width/4 - scans - 1;
\r
396 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
397 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
398 byte left = lclip[sx&0x03];
\r
399 byte right = rclip[(sx+width)&0x03];
\r
402 MOV AX, SCREEN_SEG ; work in the vga space
\r
407 MOV DX, GC_INDEX ; turn off cpu bits
\r
411 MOV AX, SC_INDEX ; point to the mask register
\r
421 MOV CX, scans ; the number of latches
\r
423 MOV AL, left ; do the left column
\r
428 MOV AL, 0fh ; do the inner columns
\r
430 REP MOVSB ; copy the pixels
\r
432 MOV AL, right ; do the right column
\r
437 MOV AX, SI ; go the start of the next row
\r
438 ADD AX, nextSrcRow ;
\r
441 ADD AX, nextDestRow ;
\r
444 DEC height ; do the rest of the actions
\r
447 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
448 MOV AL, 0ffh ; none from latches
\r
454 /* fade and flash */
\r
456 modexFadeOn(word fade, byte *palette) {
\r
457 fadePalette(-fade, 64, 64/fade+1, palette);
\r
462 modexFadeOff(word fade, byte *palette) {
\r
463 fadePalette(fade, 0, 64/fade+1, palette);
\r
468 modexFlashOn(word fade, byte *palette) {
\r
469 fadePalette(fade, -64, 64/fade+1, palette);
\r
474 modexFlashOff(word fade, byte *palette) {
\r
475 fadePalette(-fade, 0, 64/fade+1, palette);
\r
480 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
484 /* handle the case where we just update */
\r
486 modexPalUpdate1(palette);
\r
490 while(iter > 0) { /* FadeLoop */
\r
491 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
492 tmppal[i] = palette[i] - dim;
\r
493 if(tmppal[i] > 127) {
\r
495 } else if(tmppal[i] > 63) {
\r
499 modexPalUpdate1(tmppal);
\r
506 /* save and load */
\r
508 modexPalSave(byte *palette) {
\r
511 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
512 for(i=0; i<PAL_SIZE; i++) {
\r
513 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
521 ptr = malloc(PAL_SIZE);
\r
523 /* handle errors */
\r
525 printf("Could not allocate palette.\n");
\r
534 modexLoadPalFile(byte *filename, byte **palette) {
\r
538 /* free the palette if it exists */
\r
543 /* allocate the new palette */
\r
544 *palette = modexNewPal();
\r
546 /* open the file */
\r
547 file = fopen(filename, "rb");
\r
549 printf("Could not open palette file: %s\n", filename);
\r
553 /* read the file */
\r
555 while(!feof(file)) {
\r
556 *ptr++ = fgetc(file);
\r
564 modexSavePalFile(char *filename, byte *pal) {
\r
568 /* open the file for writing */
\r
569 file = fopen(filename, "wb");
\r
571 printf("Could not open %s for writing\n", filename);
\r
575 /* write the data to the file */
\r
576 fwrite(pal, 1, PAL_SIZE, file);
\r
584 fadePalette(-1, 64, 1, tmppal);
\r
590 fadePalette(-1, -64, 1, tmppal);
\r
596 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
598 byte *p = bmp->palette;
\r
602 static word a[PAL_SIZE]; //palette array of change values!
\r
603 word z=0, aq=0, aa=0, pp=0;
\r
605 //modexWaitBorder();
\r
606 vga_wait_for_vsync();
\r
609 memset(a, -1, sizeof(a));
\r
610 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
620 // printf("q: %02d\n", (q));
\r
621 // printf("qq: %02d\n", (qq));
\r
622 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
623 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
625 if((*i)<PAL_SIZE/2 && w==0)
\r
627 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
629 //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
630 //____ 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
631 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
636 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
638 //printf("qp=%d\n", qp);
\r
639 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
640 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
641 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
642 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
646 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
648 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
649 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
650 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
653 //if(qp>0) printf("qp=%d\n", qp);
\r
654 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
656 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
657 vga_wait_for_vsync();
\r
658 if((*i)>=PAL_SIZE/2 && w==0)
\r
660 for(; (*i)<PAL_SIZE; (*i)++)
\r
662 //____ 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
663 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
668 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
670 //printf("qp=%d\n", qp);
\r
671 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
672 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
673 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
674 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
678 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
679 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
680 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
683 //printf(" (*i)=%d\n", (*i)/3);
\r
686 printf("\nqqqqqqqq\n\n");
\r
692 long bufSize = (bmp->width * bmp->height);
\r
694 //printf("1(*i)=%02d\n", (*i)/3);
\r
695 //printf("1z=%02d\n", z/3);
\r
696 modexchkcolor(bmp, &q, &a, &aa, &z, i);
\r
697 //printf("2(*i)=%02d\n", (*i)/3);
\r
698 //printf("2z=%02d\n", z/3);
\r
703 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
704 if(a[aq]==-1) aq++;
\r
705 else { aqoffset++; break; }
\r
707 //update the image data here!
\r
708 for(lq=0; lq<bufSize; lq++)
\r
712 use a[qp] instead of bmp->offset for this spot!
\r
717 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
720 //(offset/bmp->offset)*bmp->offset
\r
723 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
724 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
725 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
726 /*if(bmp->data[lq]+bmp->offset==aq)
\r
728 //printf("%02d", bmp->data[lq]);
\r
729 //printf("\n%02d\n", bmp->offset);
\r
730 printf("aq=%02d ", aq);
\r
731 printf("a[aq]=%02d ", a[aq]);
\r
732 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
733 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
734 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
735 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
736 // printf("_%d ", bmp->data[lq]);
\r
737 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
739 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
741 if(bmp->data[lq]+bmp->offset >= aq)
\r
743 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
744 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
746 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
749 //printf("%02d`", bmp->data[lq]);
\r
750 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
753 //printf(" aq=%02d\n", aq);
\r
754 //printf(" aa=%02d\n", aa);
\r
756 //update the palette~
\r
757 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
760 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
765 modexPalUpdate1(byte *p)
\r
768 //modexWaitBorder();
\r
769 vga_wait_for_vsync();
\r
770 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
771 for(i=0; i<PAL_SIZE/2; i++)
\r
773 outp(PAL_DATA_REG, p[i]);
\r
775 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
776 vga_wait_for_vsync();
\r
777 for(; i<PAL_SIZE; i++)
\r
779 outp(PAL_DATA_REG, p[(i)]);
\r
784 modexPalUpdate0(byte *p)
\r
787 //modexWaitBorder();
\r
788 vga_wait_for_vsync();
\r
789 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
790 for(i=0; i<PAL_SIZE/2; i++)
\r
792 outp(PAL_DATA_REG, rand());
\r
794 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
795 vga_wait_for_vsync();
\r
796 for(; i<PAL_SIZE; i++)
\r
798 outp(PAL_DATA_REG, rand());
\r
803 modexPalOverscan(byte *p, word col)
\r
805 //modexWaitBorder();
\r
806 vga_wait_for_vsync();
\r
807 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
808 outp(PAL_DATA_REG, col);
\r
812 //i want to make another vesion that checks the palette when the palette is being appened~
\r
813 void modexchkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
817 pal = modexNewPal();
\r
819 //printf("q: %02d\n", (*q));
\r
820 printf("chkcolor start~\n");
\r
821 printf("1 (*z): %d\n", (*z)/3);
\r
822 printf("1 (*i): %d\n", (*i)/3);
\r
823 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
824 printf("wwwwwwwwwwwwwwww\n");
\r
825 //check palette for dups
\r
826 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
828 //printf("\n z: %d\n", (*z));
\r
829 //printf(" q: %d\n", (*q));
\r
830 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
833 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
836 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
837 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
841 else for(zz=0; zz<(*q); zz+=3)
\r
843 //printf("zz: %02d\n", zz/3);
\r
846 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
850 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
851 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
854 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
856 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
857 // 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
858 // 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
859 // //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
860 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
865 planned features that i plan to implement~
\r
866 image that has values on the pallete list!
\r
868 no... wait.... no wwww
\r
870 //for(zzii=0; zzii<3; zzii++)
\r
872 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
873 a[(((*z)+(*q)))]=zz;
\r
875 (*aa)=(((*z)+(*q)));
\r
876 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
877 // printf("\n aa: %d\n\n", (*aa));
\r
878 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
879 // printf("wwwwwwwwwwwwwwww\n\n");
\r
883 printf("================\n");
\r
884 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
885 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
886 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
887 printf("================\n");
\r
889 //printf("[%d]", (zz+q));
\r
893 printf("wwwwwwwwwwwwwwww\n");
\r
894 printf("2 (*z): %d\n", (*z)/3);
\r
895 printf("2 (*i): %d\n", (*i)/3);
\r
896 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
897 printf("chkcolor end~\n");
\r
901 void modexputPixel(page_t *page, int x, int y, byte color)
\r
903 word pageOff = (word) page->data;
\r
904 /* Each address accesses four neighboring pixels, so set
\r
905 Write Plane Enable according to which pixel we want
\r
906 to modify. The plane is determined by the two least
\r
907 significant bits of the x-coordinate: */
\r
908 modexSelectPlane(PLANE(x));
\r
909 //outp(SC_INDEX, 0x02);
\r
910 //outp(SC_DATA, 0x01 << (x & 3));
\r
912 /* The offset of the pixel into the video segment is
\r
913 offset = (width * y + x) / 4, and write the given
\r
914 color to the plane we selected above. Heed the active
\r
915 page start selection. */
\r
916 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
920 byte modexgetPixel(page_t *page, int x, int y)
\r
922 word pageOff = (word) page->data;
\r
923 /* Select the plane from which we must read the pixel color: */
\r
924 outpw(GC_INDEX, 0x04);
\r
925 outpw(GC_INDEX+1, x & 3);
\r
927 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
931 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
935 word addr = (word) romFontsData.l;
\r
936 word addrq = (page->width/4) * y + (x / 4) + ((word)page->data);
\r
937 word addrr = addrq;
\r
942 w=romFonts[t].charSize;
\r
943 romFontsData.chw=0;
\r
945 for(; *str != '\0'; str++)
\r
951 romFontsData.chw = 0;
\r
952 addrq += (page->width / 4) * 8;
\r
958 // load the character into romFontsData.l
\r
959 // no need for inline assembly!
\r
960 // NTS: It might even be faster to just let the modexDrawChar point directly at ROM font than to copy per char! --J.C.
\r
961 _fmemcpy(romFontsData.l,MK_FP(s,o+(w*c))/*ROM font location*/,w/*char size*/);
\r
962 modexDrawChar(page, x_draw/*for mode X planar use*/, t, col, bgcol, addrr);
\r
963 x_draw += 8; /* track X for edge of screen */
\r
964 addrr += 2; /* move 8 pixels over (2 x 4 planar pixels per byte) */
\r
968 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
970 word i, s, o, w, j, xp;
\r
972 word addr = (word) l;
\r
999 for(; *str != '\0'; str++)
\r
1002 if((c=='\n'/* || c=="\
\r
1003 "*/)/* || chw>=page->width*/)
\r
1009 //load the letter 'A'
\r
1015 MOV AL, c ; the letter
\r
1018 ADD SI, AX ;the address of charcter
\r
1027 for(i=0; i<w; i++)
\r
1033 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1034 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1043 /* palette dump on display! */
\r
1044 void modexpdump(page_t *pee)
\r
1046 int mult=(QUADWH);
\r
1047 int palq=(mult)*TILEWH;
\r
1050 for(paly=0; paly<palq; paly+=mult){
\r
1051 for(palx=0; palx<palq; palx+=mult){
\r
1052 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
\r
1058 /////////////////////////////////////////////////////////////////////////////
\r
1060 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1061 // the Virtual screen. //
\r
1063 /////////////////////////////////////////////////////////////////////////////
\r
1064 void modexcls(page_t *page, byte color, byte *Where)
\r
1066 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1067 /* set map mask to all 4 planes */
\r
1068 outpw(SC_INDEX, 0xff02);
\r
1069 //_fmemset(VGA, color, 16000);
\r
1070 _fmemset(Where, color, page->width*(page->height)/4);
\r
1074 modexWaitBorder() {
\r
1075 while(inp(INPUT_STATUS_1) & 8) {
\r
1079 while(!(inp(INPUT_STATUS_1) & 8)) {
\r
1089 m = int10_getmode();
\r
1090 if ((rp=vga_state.vga_graphics_ram) != NULL && !(m <= 3 || m == 7)) {
\r
1091 unsigned int i,im;
\r
1093 im = (FP_SEG(vga_state.vga_graphics_ram_fence) - FP_SEG(vga_state.vga_graphics_ram));
\r
1094 if (im > 0xFFE) im = 0xFFE;
\r
1096 for (i=0;i < im;i++) vga_state.vga_graphics_ram[i] = 0;
\r
1098 else if ((ap=vga_state.vga_alpha_ram) != NULL) {
\r
1099 unsigned int i,im;
\r
1101 im = (FP_SEG(vga_state.vga_alpha_ram_fence) - FP_SEG(vga_state.vga_alpha_ram));
\r
1102 if (im > 0x7FE) im = 0x7FE;
\r
1103 im <<= 4 - 1; /* because ptr is type uint16_t */
\r
1104 for (i=0;i < im;i++) vga_state.vga_alpha_ram[i] = 0x0720;
\r
1107 printf("WARNING: bios cls no ptr\n");
\r