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
162 /* VGAmodeX restores original mode and palette */
\r
163 vgaSetMode(TEXT_MODE);
\r
167 modexDefaultPage(page_t *p)
\r
171 /* default page values */
\r
173 //page.data = (byte far *)(vga_state.vga_graphics_ram);
\r
174 page.data = (vga_state.vga_graphics_ram);
\r
179 page.width = p->sw+TILEWHD;
\r
180 page.height = p->sh+TILEWHD;
\r
181 page.tw = page.sw/TILEWH;
\r
182 page.th = page.sh/TILEWH;
\r
183 page.tilesw=page.width/TILEWH;
\r
184 page.tilesh=page.height/TILEWH;
\r
185 page.tilemidposscreenx = page.tw/2;
\r
186 page.tilemidposscreeny = (page.th/2)+1;
\r
187 page.pagesize = (sdiword)(page.width/4)*page.height;
\r
193 /* returns the next page in contiguous memory
\r
194 * the next page will be the same size as p, by default
\r
197 modexNextPage(page_t *p) {
\r
200 result.data = p->data + (p->pagesize);
\r
203 result.width = p->width;
\r
204 result.height = p->height;
\r
207 result.tilesw = p->tilesw;
\r
208 result.tilesh = p->tilesh;
\r
209 result.id = p->id+1;
\r
210 result.pagesize = p->pagesize;
\r
215 //next page with defined dimentions~
\r
217 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
221 result.data = p->data + (p->pagesize); /* compute the offset */
\r
226 result.tw = result.sw/TILEWH;
\r
227 result.th = result.sh/TILEWH;
\r
228 result.tilesw=result.width/TILEWH;
\r
229 result.tilesh=result.height/TILEWH;
\r
230 result.id = p->id+1;
\r
231 result.pagesize = (sdiword)(result.width/4)*result.height;
\r
236 void modexCalcVmemRemain(video_t *video)
\r
239 //printf("\n\n 1st vmem_remain=%ld\n", video->vmem_remain);
\r
240 for(i=0; i<=video->num_of_pages-1; i++)
\r
242 video->vmem_remain-=video->page[i].pagesize;
\r
243 //printf(" [%u], video->page[i].pagesize=%ld\n", i, video->page[i].pagesize);
\r
244 //printf(" [%u], vmem_remain=%ld\n", i, video->vmem_remain);
\r
248 void modexHiganbanaPageSetup(video_t *video)
\r
250 video->vmem_remain=262144L;
\r
251 video->num_of_pages=0;
\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
295 modexPanPage(page_t *page, int dx, int dy) {
\r
301 modexSelectPlane(byte plane) {
\r
302 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
303 outp(SC_DATA, plane);
\r
307 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
308 word pageOff = (word) page->data;
\r
309 word xoff=x/4; /* xoffset that begins each row */
\r
310 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
311 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
312 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
313 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
314 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
315 byte left = lclip[x&0x03];
\r
316 byte right = rclip[(x+w)&0x03];
\r
318 /* handle the case which requires an extra group */
\r
319 if((x & 0x03) && !((x+w) & 0x03)) {
\r
332 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
334 MOV DI, poffset ; go to the first pixel
\r
335 MOV DX, SC_INDEX ; point to the map mask
\r
339 MOV AL, color ; get ready to write colors
\r
341 MOV CX, scanCount ; count the line
\r
342 MOV BL, AL ; remember color
\r
343 MOV AL, left ; do the left clip
\r
344 OUT DX, AL ; set the left clip
\r
345 MOV AL, BL ; restore color
\r
346 STOSB ; write the color
\r
348 JZ SCAN_DONE ; handle 1 group stuff
\r
350 ;-- write the main body of the scanline
\r
351 MOV BL, AL ; remember color
\r
352 MOV AL, 0x0f ; write to all pixels
\r
354 MOV AL, BL ; restore color
\r
355 REP STOSB ; write the color
\r
357 MOV BL, AL ; remeber color
\r
359 OUT DX, AL ; do the right clip
\r
360 MOV AL, BL ; restore color
\r
361 STOSB ; write pixel
\r
362 ADD DI, nextRow ; go to the next row
\r
376 /* moved to src/lib/modex16/16render.c */
\r
378 /* copy a region of video memory from one page to another.
\r
379 * It assumes that the left edge of the tile is the same on both
\r
380 * regions and the memory areas do not overlap.
\r
383 modexCopyPageRegion(page_t *dest, page_t *src,
\r
386 word width, word height)
\r
388 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
389 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
390 word scans = vga_state.vga_stride;
\r
391 word nextSrcRow = src->width/4 - scans - 1;
\r
392 word nextDestRow = dest->width/4 - scans - 1;
\r
393 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
394 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
395 byte left = lclip[sx&0x03];
\r
396 byte right = rclip[(sx+width)&0x03];
\r
399 MOV AX, SCREEN_SEG ; work in the vga space
\r
404 MOV DX, GC_INDEX ; turn off cpu bits
\r
408 MOV AX, SC_INDEX ; point to the mask register
\r
418 MOV CX, scans ; the number of latches
\r
420 MOV AL, left ; do the left column
\r
425 MOV AL, 0fh ; do the inner columns
\r
427 REP MOVSB ; copy the pixels
\r
429 MOV AL, right ; do the right column
\r
434 MOV AX, SI ; go the start of the next row
\r
435 ADD AX, nextSrcRow ;
\r
438 ADD AX, nextDestRow ;
\r
441 DEC height ; do the rest of the actions
\r
444 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
445 MOV AL, 0ffh ; none from latches
\r
451 /* fade and flash */
\r
453 modexFadeOn(word fade, byte *palette) {
\r
454 fadePalette(-fade, 64, 64/fade+1, palette);
\r
459 modexFadeOff(word fade, byte *palette) {
\r
460 fadePalette(fade, 0, 64/fade+1, palette);
\r
465 modexFlashOn(word fade, byte *palette) {
\r
466 fadePalette(fade, -64, 64/fade+1, palette);
\r
471 modexFlashOff(word fade, byte *palette) {
\r
472 fadePalette(-fade, 0, 64/fade+1, palette);
\r
477 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
481 /* handle the case where we just update */
\r
483 modexPalUpdate1(palette);
\r
487 while(iter > 0) { /* FadeLoop */
\r
488 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
489 tmppal[i] = palette[i] - dim;
\r
490 if(tmppal[i] > 127) {
\r
492 } else if(tmppal[i] > 63) {
\r
496 modexPalUpdate1(tmppal);
\r
503 /* save and load */
\r
505 modexPalSave(byte *palette) {
\r
508 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
509 for(i=0; i<PAL_SIZE; i++) {
\r
510 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
518 ptr = malloc(PAL_SIZE);
\r
520 /* handle errors */
\r
522 printf("Could not allocate palette.\n");
\r
531 modexLoadPalFile(byte *filename, byte **palette) {
\r
535 /* free the palette if it exists */
\r
540 /* allocate the new palette */
\r
541 *palette = modexNewPal();
\r
543 /* open the file */
\r
544 file = fopen(filename, "rb");
\r
546 printf("Could not open palette file: %s\n", filename);
\r
550 /* read the file */
\r
552 while(!feof(file)) {
\r
553 *ptr++ = fgetc(file);
\r
561 modexSavePalFile(char *filename, byte *pal) {
\r
565 /* open the file for writing */
\r
566 file = fopen(filename, "wb");
\r
568 printf("Could not open %s for writing\n", filename);
\r
572 /* write the data to the file */
\r
573 fwrite(pal, 1, PAL_SIZE, file);
\r
581 fadePalette(-1, 64, 1, tmppal);
\r
587 fadePalette(-1, -64, 1, tmppal);
\r
593 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
595 byte *p = bmp->palette;
\r
599 static word a[PAL_SIZE]; //palette array of change values!
\r
600 word z=0, aq=0, aa=0, pp=0;
\r
602 //modexWaitBorder();
\r
603 vga_wait_for_vsync();
\r
606 memset(a, -1, sizeof(a));
\r
607 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
617 // printf("q: %02d\n", (q));
\r
618 // printf("qq: %02d\n", (qq));
\r
619 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
620 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
622 if((*i)<PAL_SIZE/2 && w==0)
\r
624 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
626 //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
627 //____ 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
628 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
633 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
635 //printf("qp=%d\n", qp);
\r
636 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
637 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
638 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
639 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
643 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
645 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
646 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
647 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
650 //if(qp>0) printf("qp=%d\n", qp);
\r
651 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
653 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
654 vga_wait_for_vsync();
\r
655 if((*i)>=PAL_SIZE/2 && w==0)
\r
657 for(; (*i)<PAL_SIZE; (*i)++)
\r
659 //____ 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
660 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
665 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
667 //printf("qp=%d\n", qp);
\r
668 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
669 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
670 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
671 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
675 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
676 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
677 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
680 //printf(" (*i)=%d\n", (*i)/3);
\r
683 printf("\nqqqqqqqq\n\n");
\r
689 long bufSize = (bmp->width * bmp->height);
\r
691 //printf("1(*i)=%02d\n", (*i)/3);
\r
692 //printf("1z=%02d\n", z/3);
\r
693 modexchkcolor(bmp, &q, &a, &aa, &z, i);
\r
694 //printf("2(*i)=%02d\n", (*i)/3);
\r
695 //printf("2z=%02d\n", z/3);
\r
700 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
701 if(a[aq]==-1) aq++;
\r
702 else { aqoffset++; break; }
\r
704 //update the image data here!
\r
705 for(lq=0; lq<bufSize; lq++)
\r
709 use a[qp] instead of bmp->offset for this spot!
\r
714 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
717 //(offset/bmp->offset)*bmp->offset
\r
720 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
721 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
722 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
723 /*if(bmp->data[lq]+bmp->offset==aq)
\r
725 //printf("%02d", bmp->data[lq]);
\r
726 //printf("\n%02d\n", bmp->offset);
\r
727 printf("aq=%02d ", aq);
\r
728 printf("a[aq]=%02d ", a[aq]);
\r
729 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
730 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
731 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
732 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
733 // printf("_%d ", bmp->data[lq]);
\r
734 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
736 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
738 if(bmp->data[lq]+bmp->offset >= aq)
\r
740 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
741 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
743 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
746 //printf("%02d`", bmp->data[lq]);
\r
747 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
750 //printf(" aq=%02d\n", aq);
\r
751 //printf(" aa=%02d\n", aa);
\r
753 //update the palette~
\r
754 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
757 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
762 modexPalUpdate1(byte *p)
\r
765 //modexWaitBorder();
\r
766 vga_wait_for_vsync();
\r
767 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
768 for(i=0; i<PAL_SIZE/2; i++)
\r
770 outp(PAL_DATA_REG, p[i]);
\r
772 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
773 vga_wait_for_vsync();
\r
774 for(; i<PAL_SIZE; i++)
\r
776 outp(PAL_DATA_REG, p[(i)]);
\r
781 modexPalUpdate0(byte *p)
\r
784 //modexWaitBorder();
\r
785 vga_wait_for_vsync();
\r
786 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
787 for(i=0; i<PAL_SIZE/2; i++)
\r
789 outp(PAL_DATA_REG, rand());
\r
791 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
792 vga_wait_for_vsync();
\r
793 for(; i<PAL_SIZE; i++)
\r
795 outp(PAL_DATA_REG, rand());
\r
800 modexPalOverscan(byte *p, word col)
\r
802 //modexWaitBorder();
\r
803 vga_wait_for_vsync();
\r
804 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
805 outp(PAL_DATA_REG, col);
\r
809 //i want to make another vesion that checks the palette when the palette is being appened~
\r
810 void modexchkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
814 pal = modexNewPal();
\r
816 //printf("q: %02d\n", (*q));
\r
817 printf("chkcolor start~\n");
\r
818 printf("1 (*z): %d\n", (*z)/3);
\r
819 printf("1 (*i): %d\n", (*i)/3);
\r
820 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
821 printf("wwwwwwwwwwwwwwww\n");
\r
822 //check palette for dups
\r
823 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
825 //printf("\n z: %d\n", (*z));
\r
826 //printf(" q: %d\n", (*q));
\r
827 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
830 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
833 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
834 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
838 else for(zz=0; zz<(*q); zz+=3)
\r
840 //printf("zz: %02d\n", zz/3);
\r
843 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
847 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
848 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
851 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
853 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
854 // 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
855 // 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
856 // //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
857 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
862 planned features that i plan to implement~
\r
863 image that has values on the pallete list!
\r
865 no... wait.... no wwww
\r
867 //for(zzii=0; zzii<3; zzii++)
\r
869 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
870 a[(((*z)+(*q)))]=zz;
\r
872 (*aa)=(((*z)+(*q)));
\r
873 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
874 // printf("\n aa: %d\n\n", (*aa));
\r
875 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
876 // printf("wwwwwwwwwwwwwwww\n\n");
\r
880 printf("================\n");
\r
881 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
882 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
883 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
884 printf("================\n");
\r
886 //printf("[%d]", (zz+q));
\r
890 printf("wwwwwwwwwwwwwwww\n");
\r
891 printf("2 (*z): %d\n", (*z)/3);
\r
892 printf("2 (*i): %d\n", (*i)/3);
\r
893 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
894 printf("chkcolor end~\n");
\r
898 void modexputPixel(page_t *page, int x, int y, byte color)
\r
900 word pageOff = (word) page->data;
\r
901 /* Each address accesses four neighboring pixels, so set
\r
902 Write Plane Enable according to which pixel we want
\r
903 to modify. The plane is determined by the two least
\r
904 significant bits of the x-coordinate: */
\r
905 modexSelectPlane(PLANE(x));
\r
906 //outp(SC_INDEX, 0x02);
\r
907 //outp(SC_DATA, 0x01 << (x & 3));
\r
909 /* The offset of the pixel into the video segment is
\r
910 offset = (width * y + x) / 4, and write the given
\r
911 color to the plane we selected above. Heed the active
\r
912 page start selection. */
\r
913 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
917 byte modexgetPixel(page_t *page, int x, int y)
\r
919 word pageOff = (word) page->data;
\r
920 /* Select the plane from which we must read the pixel color: */
\r
921 outpw(GC_INDEX, 0x04);
\r
922 outpw(GC_INDEX+1, x & 3);
\r
924 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
928 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
932 word addr = (word) romFontsData.l;
\r
933 word addrq = (page->width/4) * y + (x / 4) + ((word)page->data);
\r
934 word addrr = addrq;
\r
939 w=romFonts[t].charSize;
\r
940 romFontsData.chw=0;
\r
942 for(; *str != '\0'; str++)
\r
948 romFontsData.chw = 0;
\r
949 addrq += (page->width / 4) * 8;
\r
955 // load the character into romFontsData.l
\r
956 // no need for inline assembly!
\r
957 // NTS: It might even be faster to just let the modexDrawChar point directly at ROM font than to copy per char! --J.C.
\r
958 _fmemcpy(romFontsData.l,MK_FP(s,o+(w*c))/*ROM font location*/,w/*char size*/);
\r
959 modexDrawChar(page, x_draw/*for mode X planar use*/, t, col, bgcol, addrr);
\r
960 x_draw += 8; /* track X for edge of screen */
\r
961 addrr += 2; /* move 8 pixels over (2 x 4 planar pixels per byte) */
\r
965 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
967 word i, s, o, w, j, xp;
\r
969 word addr = (word) l;
\r
996 for(; *str != '\0'; str++)
\r
999 if((c=='\n'/* || c=="\
\r
1000 "*/)/* || chw>=page->width*/)
\r
1006 //load the letter 'A'
\r
1012 MOV AL, c ; the letter
\r
1015 ADD SI, AX ;the address of charcter
\r
1024 for(i=0; i<w; i++)
\r
1030 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1031 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1040 /* palette dump on display! */
\r
1041 void modexpdump(page_t *pee)
\r
1043 int mult=(QUADWH);
\r
1044 int palq=(mult)*TILEWH;
\r
1047 for(paly=0; paly<palq; paly+=mult){
\r
1048 for(palx=0; palx<palq; palx+=mult){
\r
1049 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
\r
1055 /////////////////////////////////////////////////////////////////////////////
\r
1057 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1058 // the Virtual screen. //
\r
1060 /////////////////////////////////////////////////////////////////////////////
\r
1061 void modexcls(page_t *page, byte color, byte *Where)
\r
1063 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1064 /* set map mask to all 4 planes */
\r
1065 outpw(SC_INDEX, 0xff02);
\r
1066 //_fmemset(VGA, color, 16000);
\r
1067 _fmemset(Where, color, page->width*(page->height)/4);
\r
1071 modexWaitBorder() {
\r
1072 while(inp(INPUT_STATUS_1) & 8) {
\r
1076 while(!(inp(INPUT_STATUS_1) & 8)) {
\r
1086 m = int10_getmode();
\r
1087 if ((rp=vga_state.vga_graphics_ram) != NULL && !(m <= 3 || m == 7)) {
\r
1088 unsigned int i,im;
\r
1090 im = (FP_SEG(vga_state.vga_graphics_ram_fence) - FP_SEG(vga_state.vga_graphics_ram));
\r
1091 if (im > 0xFFE) im = 0xFFE;
\r
1093 for (i=0;i < im;i++) vga_state.vga_graphics_ram[i] = 0;
\r
1095 else if ((ap=vga_state.vga_alpha_ram) != NULL) {
\r
1096 unsigned int i,im;
\r
1098 im = (FP_SEG(vga_state.vga_alpha_ram_fence) - FP_SEG(vga_state.vga_alpha_ram));
\r
1099 if (im > 0x7FE) im = 0x7FE;
\r
1100 im <<= 4 - 1; /* because ptr is type uint16_t */
\r
1101 for (i=0;i < im;i++) vga_state.vga_alpha_ram[i] = 0x0720;
\r
1104 printf("WARNING: bios cls no ptr\n");
\r