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 /*for(i=0; i<CRTParmCount; i++) {
\r
96 outpw(CRTC_INDEX, ModeX_320x240regs[i]);
\r
98 /* width and height */
\r
99 gv->video.page[0].sw = vga_state.vga_width = 320; // VGA lib currently does not update this
\r
100 gv->video.page[0].sh = vga_state.vga_height = 240; // VGA lib currently does not update this
\r
101 /* virtual width and height. match screen, at first */
\r
102 gv->video.page[0].height = gv->video.page[0].sh;
\r
103 gv->video.page[0].width = gv->video.page[0].sw;
\r
105 // mode X BYTE mode
\r
108 // 320x240 mode 60Hz
\r
109 cm.horizontal_total=0x5f + 5; /* CRTC[0] -5 */
\r
110 cm.horizontal_display_end=0x4f + 1; /* CRTC[1] -1 */
\r
111 cm.horizontal_blank_start=0x50 + 1; /* CRTC[2] */
\r
112 cm.horizontal_blank_end=0x82 + 1; /* CRTC[3] bit 0-4 & CRTC[5] bit 7 */
\r
113 cm.horizontal_start_retrace=0x54;/* CRTC[4] */
\r
114 cm.horizontal_end_retrace=0x80; /* CRTC[5] bit 0-4 */
\r
115 //cm.horizontal_start_delay_after_total=0x3e; /* CRTC[3] bit 5-6 */
\r
116 //cm.horizontal_start_delay_after_retrace=0x41; /* CRTC[5] bit 5-6 */
\r
117 cm.vertical_total = 0x20D + 2;
\r
118 cm.vertical_start_retrace = 0x1EA;
\r
119 cm.vertical_end_retrace = 0x1EC;
\r
120 cm.vertical_display_end = 480;
\r
121 cm.vertical_blank_start = 0x1E7 + 1;
\r
122 cm.vertical_blank_end = 0x206 + 1;
\r
123 cm.clock_select = 0; /* misc register = 0xE3 25MHz */
\r
126 cm.offset = (vga_state.vga_width / (4 * 2)); // 320 wide (40 x 4 pixel groups x 2)
\r
128 case 2: // TODO: 160x120 according to ModeX_160x120regs
\r
130 case 3: // TODO: 160x120 according to ModeX_320x200regs
\r
132 case 4: // TODO: 160x120 according to ModeX_192x144regs
\r
134 case 5: // TODO: 160x120 according to ModeX_256x192regs
\r
140 vga_state.vga_stride = cm.offset * 2;
\r
141 vga_write_crtc_mode(&cm,0);
\r
143 /* clear video memory */
\r
147 /* clear video memory */
\r
148 dword far*ptr=(dword far*)vga_state.vga_graphics_ram;//VGA; /* used for faster screen clearing */
\r
149 vga_write_sequencer(2/*map mask register*/,0xf/*all 4 planes*/);
\r
150 for(i = 0;i < 0x4000; i++) ptr[i] = 0x0000; // 0x4000 x dword = 64KB
\r
155 // gv->video.page[0].tw = gv->video.page[0].sw/TILEWH;
\r
156 // gv->video.page[0].th = gv->video.page[0].sh/TILEWH;
\r
158 //TODO MAKE FLEXIBLE~
\r
159 // gv->video.page[0].tilemidposscreenx = gv->video.page[0].tilesw;
\r
160 // gv->video.page[0].tilemidposscreeny = (gv->video.page[0].tilesh/2)+1;
\r
165 /* VGAmodeX restores original mode and palette */
\r
166 vgaSetMode(TEXT_MODE);
\r
170 modexDefaultPage(page_t *p)
\r
174 /* default page values */
\r
176 //page.data = (byte far *)(vga_state.vga_graphics_ram);
\r
177 page.data = (vga_state.vga_graphics_ram);
\r
182 page.width = p->sw+TILEWHD;
\r
183 page.height = p->sh+TILEWHD;
\r
184 page.tw = page.sw/TILEWH;
\r
185 page.th = page.sh/TILEWH;
\r
186 page.tilesw=page.width/TILEWH;
\r
187 page.tilesh=page.height/TILEWH;
\r
188 page.tilemidposscreenx = page.tw/2;
\r
189 page.tilemidposscreeny = (page.th/2)+1;
\r
190 page.pagesize = (sdiword)(page.width/4)*page.height;
\r
196 /* returns the next page in contiguous memory
\r
197 * the next page will be the same size as p, by default
\r
200 modexNextPage(page_t *p) {
\r
203 result.data = p->data + (p->pagesize);
\r
208 result.width = p->width;
\r
209 result.height = p->height;
\r
212 result.tilesw = p->tilesw;
\r
213 result.tilesh = p->tilesh;
\r
214 result.id = p->id+1;
\r
215 result.pagesize = p->pagesize;
\r
220 //next page with defined dimentions~
\r
222 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
226 result.data = p->data + (p->pagesize); /* compute the offset */
\r
233 result.tw = result.sw/TILEWH;
\r
234 result.th = result.sh/TILEWH;
\r
235 result.tilesw=result.width/TILEWH;
\r
236 result.tilesh=result.height/TILEWH;
\r
237 result.id = p->id+1;
\r
238 result.pagesize = (sdiword)(result.width/4)*result.height;
\r
243 void modexCalcVmemRemain(video_t *video)
\r
246 //printf("\n\n 1st vmem_remain=%ld\n", video->vmem_remain);
\r
247 for(i=0; i<=video->num_of_pages-1; i++)
\r
249 video->vmem_remain-=video->page[i].pagesize;
\r
250 //printf(" [%u], video->page[i].pagesize=%ld\n", i, video->page[i].pagesize);
\r
251 //printf(" [%u], vmem_remain=%ld\n", i, video->vmem_remain);
\r
255 void modexHiganbanaPageSetup(video_t *video)
\r
257 video->vmem_remain=262144L;
\r
258 video->num_of_pages=0;
\r
259 (video->page[0]) = modexDefaultPage(&(video->page[0])); video->num_of_pages++;
\r
260 //video->page[0].width += (TILEWHD); video->page[0].height += (TILEWHD);
\r
261 (video->page[1]) = modexNextPage(&(video->page[0])); video->num_of_pages++;
\r
262 //(video->page[2]) = modexNextPageFlexibleSize(&(video->page[1]), video->page[0].width, video->page[0].sh-40); video->num_of_pages++;
\r
263 //(video->page[3]) = modexNextPageFlexibleSize(&(video->page[2]), TILEWH, TILEWH); video->num_of_pages++;
\r
264 modexCalcVmemRemain(video);
\r
269 modexShowPage(page_t *page) {
\r
275 /* calculate offset */
\r
276 offset = (word) page->data;
\r
277 offset += page->dy * (page->width >> 2 );
\r
278 offset += page->dx >> 2;
\r
280 /* calculate crtcOffset according to virtual width */
\r
281 crtcOffset = page->width >> 3;
\r
283 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
284 low_address = LOW_ADDRESS | (offset << 8);
\r
286 /* wait for appropriate timing and then program CRTC */
\r
287 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
288 outpw(CRTC_INDEX, high_address);
\r
289 outpw(CRTC_INDEX, low_address);
\r
290 outp(CRTC_INDEX, 0x13);
\r
291 outp(CRTC_DATA, crtcOffset);
\r
293 /* wait for one retrace */
\r
294 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
296 /* do PEL panning here */
\r
297 outp(AC_INDEX, 0x33);
\r
298 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
302 modexPanPage(page_t *page, int dx, int dy) {
\r
308 modexSelectPlane(byte plane) {
\r
309 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
310 outp(SC_DATA, plane);
\r
314 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
315 word pageOff = (word) page->data;
\r
316 word xoff=x/4; /* xoffset that begins each row */
\r
317 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
318 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
319 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
320 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
321 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
322 byte left = lclip[x&0x03];
\r
323 byte right = rclip[(x+w)&0x03];
\r
325 /* handle the case which requires an extra group */
\r
326 if((x & 0x03) && !((x+w) & 0x03)) {
\r
339 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
341 MOV DI, poffset ; go to the first pixel
\r
342 MOV DX, SC_INDEX ; point to the map mask
\r
346 MOV AL, color ; get ready to write colors
\r
348 MOV CX, scanCount ; count the line
\r
349 MOV BL, AL ; remember color
\r
350 MOV AL, left ; do the left clip
\r
351 OUT DX, AL ; set the left clip
\r
352 MOV AL, BL ; restore color
\r
353 STOSB ; write the color
\r
355 JZ SCAN_DONE ; handle 1 group stuff
\r
357 ;-- write the main body of the scanline
\r
358 MOV BL, AL ; remember color
\r
359 MOV AL, 0x0f ; write to all pixels
\r
361 MOV AL, BL ; restore color
\r
362 REP STOSB ; write the color
\r
364 MOV BL, AL ; remeber color
\r
366 OUT DX, AL ; do the right clip
\r
367 MOV AL, BL ; restore color
\r
368 STOSB ; write pixel
\r
369 ADD DI, nextRow ; go to the next row
\r
383 /* moved to src/lib/modex16/16render.c */
\r
385 /* copy a region of video memory from one page to another.
\r
386 * It assumes that the left edge of the tile is the same on both
\r
387 * regions and the memory areas do not overlap.
\r
390 modexCopyPageRegion(page_t *dest, page_t *src,
\r
393 word width, word height)
\r
395 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
396 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
397 word scans = vga_state.vga_stride;
\r
398 word nextSrcRow = src->width/4 - scans - 1;
\r
399 word nextDestRow = dest->width/4 - scans - 1;
\r
400 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
401 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
402 byte left = lclip[sx&0x03];
\r
403 byte right = rclip[(sx+width)&0x03];
\r
415 MOV AX, SCREEN_SEG ; work in the vga space
\r
420 MOV DX, GC_INDEX ; turn off cpu bits
\r
424 MOV AX, SC_INDEX ; point to the mask register
\r
434 MOV CX, scans ; the number of latches
\r
436 MOV AL, left ; do the left column
\r
441 MOV AL, 0fh ; do the inner columns
\r
443 REP MOVSB ; copy the pixels
\r
445 MOV AL, right ; do the right column
\r
450 MOV AX, SI ; go the start of the next row
\r
451 ADD AX, nextSrcRow ;
\r
454 ADD AX, nextDestRow ;
\r
457 DEC height ; do the rest of the actions
\r
460 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
461 MOV AL, 0ffh ; none from latches
\r
476 /* fade and flash */
\r
478 modexFadeOn(word fade, byte *palette) {
\r
479 fadePalette(-fade, 64, 64/fade+1, palette);
\r
484 modexFadeOff(word fade, byte *palette) {
\r
485 fadePalette(fade, 0, 64/fade+1, palette);
\r
490 modexFlashOn(word fade, byte *palette) {
\r
491 fadePalette(fade, -64, 64/fade+1, palette);
\r
496 modexFlashOff(word fade, byte *palette) {
\r
497 fadePalette(-fade, 0, 64/fade+1, palette);
\r
502 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
506 /* handle the case where we just update */
\r
508 modexPalUpdate1(palette);
\r
512 while(iter > 0) { /* FadeLoop */
\r
513 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
514 tmppal[i] = palette[i] - dim;
\r
515 if(tmppal[i] > 127) {
\r
517 } else if(tmppal[i] > 63) {
\r
521 modexPalUpdate1(tmppal);
\r
528 /* save and load */
\r
530 modexPalSave(byte *palette) {
\r
533 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
534 for(i=0; i<PAL_SIZE; i++) {
\r
535 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
543 ptr = malloc(PAL_SIZE);
\r
545 /* handle errors */
\r
547 printf("Could not allocate palette.\n");
\r
556 modexLoadPalFile(byte *filename, byte **palette) {
\r
560 /* free the palette if it exists */
\r
565 /* allocate the new palette */
\r
566 *palette = modexNewPal();
\r
568 /* open the file */
\r
569 file = fopen(filename, "rb");
\r
571 printf("Could not open palette file: %s\n", filename);
\r
575 /* read the file */
\r
577 while(!feof(file)) {
\r
578 *ptr++ = fgetc(file);
\r
586 modexSavePalFile(char *filename, byte *pal) {
\r
590 /* open the file for writing */
\r
591 file = fopen(filename, "wb");
\r
593 printf("Could not open %s for writing\n", filename);
\r
597 /* write the data to the file */
\r
598 fwrite(pal, 1, PAL_SIZE, file);
\r
606 fadePalette(-1, 64, 1, tmppal);
\r
612 fadePalette(-1, -64, 1, tmppal);
\r
618 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
620 byte *p = bmp->palette;
\r
624 static word a[PAL_SIZE]; //palette array of change values!
\r
625 word z=0, aq=0, aa=0, pp=0;
\r
627 //modexWaitBorder();
\r
628 vga_wait_for_vsync();
\r
631 memset(a, -1, sizeof(a));
\r
632 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
642 // printf("q: %02d\n", (q));
\r
643 // printf("qq: %02d\n", (qq));
\r
644 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
645 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
647 if((*i)<PAL_SIZE/2 && w==0)
\r
649 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
651 //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
652 //____ 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
653 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
658 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
660 //printf("qp=%d\n", qp);
\r
661 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
662 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
663 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
664 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
668 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
670 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
671 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
672 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
675 //if(qp>0) printf("qp=%d\n", qp);
\r
676 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
678 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
679 vga_wait_for_vsync();
\r
680 if((*i)>=PAL_SIZE/2 && w==0)
\r
682 for(; (*i)<PAL_SIZE; (*i)++)
\r
684 //____ 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
685 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
690 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
692 //printf("qp=%d\n", qp);
\r
693 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
694 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
695 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
696 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
700 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
701 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
702 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
705 //printf(" (*i)=%d\n", (*i)/3);
\r
708 printf("\nqqqqqqqq\n\n");
\r
714 long bufSize = (bmp->width * bmp->height);
\r
716 //printf("1(*i)=%02d\n", (*i)/3);
\r
717 //printf("1z=%02d\n", z/3);
\r
718 modexchkcolor(bmp, &q, &a, &aa, &z, i);
\r
719 //printf("2(*i)=%02d\n", (*i)/3);
\r
720 //printf("2z=%02d\n", z/3);
\r
725 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
726 if(a[aq]==-1) aq++;
\r
727 else { aqoffset++; break; }
\r
729 //update the image data here!
\r
730 for(lq=0; lq<bufSize; lq++)
\r
734 use a[qp] instead of bmp->offset for this spot!
\r
739 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
742 //(offset/bmp->offset)*bmp->offset
\r
745 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
746 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
747 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
748 /*if(bmp->data[lq]+bmp->offset==aq)
\r
750 //printf("%02d", bmp->data[lq]);
\r
751 //printf("\n%02d\n", bmp->offset);
\r
752 printf("aq=%02d ", aq);
\r
753 printf("a[aq]=%02d ", a[aq]);
\r
754 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
755 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
756 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
757 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
758 // printf("_%d ", bmp->data[lq]);
\r
759 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
761 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
763 if(bmp->data[lq]+bmp->offset >= aq)
\r
765 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
766 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
768 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
771 //printf("%02d`", bmp->data[lq]);
\r
772 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
775 //printf(" aq=%02d\n", aq);
\r
776 //printf(" aa=%02d\n", aa);
\r
778 //update the palette~
\r
779 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
782 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
787 modexPalUpdate1(byte *p)
\r
790 //modexWaitBorder();
\r
791 vga_wait_for_vsync();
\r
792 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
793 for(i=0; i<PAL_SIZE/2; i++)
\r
795 outp(PAL_DATA_REG, p[i]);
\r
797 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
798 vga_wait_for_vsync();
\r
799 for(; i<PAL_SIZE; i++)
\r
801 outp(PAL_DATA_REG, p[(i)]);
\r
806 modexPalUpdate0(byte *p)
\r
809 //modexWaitBorder();
\r
810 vga_wait_for_vsync();
\r
811 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
812 for(i=0; i<PAL_SIZE/2; i++)
\r
814 outp(PAL_DATA_REG, rand());
\r
816 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
817 vga_wait_for_vsync();
\r
818 for(; i<PAL_SIZE; i++)
\r
820 outp(PAL_DATA_REG, rand());
\r
825 modexPalOverscan(byte *p, word col)
\r
827 //modexWaitBorder();
\r
828 vga_wait_for_vsync();
\r
829 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
830 outp(PAL_DATA_REG, col);
\r
834 //i want to make another vesion that checks the palette when the palette is being appened~
\r
835 void modexchkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
839 pal = modexNewPal();
\r
841 //printf("q: %02d\n", (*q));
\r
842 printf("chkcolor start~\n");
\r
843 printf("1 (*z): %d\n", (*z)/3);
\r
844 printf("1 (*i): %d\n", (*i)/3);
\r
845 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
846 printf("wwwwwwwwwwwwwwww\n");
\r
847 //check palette for dups
\r
848 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
850 //printf("\n z: %d\n", (*z));
\r
851 //printf(" q: %d\n", (*q));
\r
852 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
855 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
858 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
859 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
863 else for(zz=0; zz<(*q); zz+=3)
\r
865 //printf("zz: %02d\n", zz/3);
\r
868 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
872 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
873 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
876 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
878 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
879 // 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
880 // 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
881 // //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
882 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
887 planned features that i plan to implement~
\r
888 image that has values on the pallete list!
\r
890 no... wait.... no wwww
\r
892 //for(zzii=0; zzii<3; zzii++)
\r
894 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
895 a[(((*z)+(*q)))]=zz;
\r
897 (*aa)=(((*z)+(*q)));
\r
898 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
899 // printf("\n aa: %d\n\n", (*aa));
\r
900 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
901 // printf("wwwwwwwwwwwwwwww\n\n");
\r
905 printf("================\n");
\r
906 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
907 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
908 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
909 printf("================\n");
\r
911 //printf("[%d]", (zz+q));
\r
915 printf("wwwwwwwwwwwwwwww\n");
\r
916 printf("2 (*z): %d\n", (*z)/3);
\r
917 printf("2 (*i): %d\n", (*i)/3);
\r
918 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
919 printf("chkcolor end~\n");
\r
923 void modexputPixel(page_t *page, int x, int y, byte color)
\r
925 word pageOff = (word) page->data;
\r
926 /* Each address accesses four neighboring pixels, so set
\r
927 Write Plane Enable according to which pixel we want
\r
928 to modify. The plane is determined by the two least
\r
929 significant bits of the x-coordinate: */
\r
930 modexSelectPlane(PLANE(x));
\r
931 //outp(SC_INDEX, 0x02);
\r
932 //outp(SC_DATA, 0x01 << (x & 3));
\r
934 /* The offset of the pixel into the video segment is
\r
935 offset = (width * y + x) / 4, and write the given
\r
936 color to the plane we selected above. Heed the active
\r
937 page start selection. */
\r
938 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
942 byte modexgetPixel(page_t *page, int x, int y)
\r
944 word pageOff = (word) page->data;
\r
945 /* Select the plane from which we must read the pixel color: */
\r
946 outpw(GC_INDEX, 0x04);
\r
947 outpw(GC_INDEX+1, x & 3);
\r
949 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
953 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
957 word addr = (word) romFontsData.l;
\r
958 word addrq = (page->width/4) * y + (x / 4) + ((word)page->data);
\r
959 word addrr = addrq;
\r
964 w=romFonts[t].charSize;
\r
965 romFontsData.chw=0;
\r
967 for(; *str != '\0'; str++)
\r
973 romFontsData.chw = 0;
\r
974 addrq += (page->width / 4) * 8;
\r
980 // load the character into romFontsData.l
\r
981 // no need for inline assembly!
\r
982 // NTS: It might even be faster to just let the modexDrawChar point directly at ROM font than to copy per char! --J.C.
\r
983 _fmemcpy(romFontsData.l,MK_FP(s,o+(w*c))/*ROM font location*/,w/*char size*/);
\r
984 modexDrawChar(page, x_draw/*for mode X planar use*/, t, col, bgcol, addrr);
\r
985 x_draw += 8; /* track X for edge of screen */
\r
986 addrr += 2; /* move 8 pixels over (2 x 4 planar pixels per byte) */
\r
990 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
992 word i, s, o, w, j, xp;
\r
994 word addr = (word) l;
\r
1018 s=romFonts[t].seg;
\r
1019 o=romFonts[t].off;
\r
1021 for(; *str != '\0'; str++)
\r
1024 if((c=='\n'/* || c=="\
\r
1025 "*/)/* || chw>=page->width*/)
\r
1031 //load the letter 'A'
\r
1046 MOV AL, c ; the letter
\r
1049 ADD SI, AX ;the address of charcter
\r
1067 for(i=0; i<w; i++)
\r
1073 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1074 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1083 /* palette dump on display! */
\r
1084 void modexpdump(page_t *pee)
\r
1086 int mult=(QUADWH);
\r
1087 int palq=(mult)*TILEWH;
\r
1090 for(paly=0; paly<palq; paly+=mult){
\r
1091 for(palx=0; palx<palq; palx+=mult){
\r
1092 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
\r
1098 /////////////////////////////////////////////////////////////////////////////
\r
1100 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1101 // the Virtual screen. //
\r
1103 /////////////////////////////////////////////////////////////////////////////
\r
1104 void modexcls(page_t *page, byte color, byte *Where)
\r
1106 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1107 /* set map mask to all 4 planes */
\r
1108 outpw(SC_INDEX, 0xff02);
\r
1109 //_fmemset(VGA, color, 16000);
\r
1110 _fmemset(Where, color, page->width*(page->height)/4);
\r
1114 modexWaitBorder() {
\r
1115 while(inp(INPUT_STATUS_1) & 8) {
\r
1119 while(!(inp(INPUT_STATUS_1) & 8)) {
\r
1129 m = int10_getmode();
\r
1130 if ((rp=vga_state.vga_graphics_ram) != NULL && !(m <= 3 || m == 7)) {
\r
1131 unsigned int i,im;
\r
1133 im = (FP_SEG(vga_state.vga_graphics_ram_fence) - FP_SEG(vga_state.vga_graphics_ram));
\r
1134 if (im > 0xFFE) im = 0xFFE;
\r
1136 for (i=0;i < im;i++) vga_state.vga_graphics_ram[i] = 0;
\r
1138 else if ((ap=vga_state.vga_alpha_ram) != NULL) {
\r
1139 unsigned int i,im;
\r
1141 im = (FP_SEG(vga_state.vga_alpha_ram_fence) - FP_SEG(vga_state.vga_alpha_ram));
\r
1142 if (im > 0x7FE) im = 0x7FE;
\r
1143 im <<= 4 - 1; /* because ptr is type uint16_t */
\r
1144 for (i=0;i < im;i++) vga_state.vga_alpha_ram[i] = 0x0720;
\r
1147 printf("WARNING: bios cls no ptr\n");
\r