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
324 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
326 MOV DI, poffset ; go to the first pixel
\r
327 MOV DX, SC_INDEX ; point to the map mask
\r
331 MOV AL, color ; get ready to write colors
\r
333 MOV CX, scanCount ; count the line
\r
334 MOV BL, AL ; remember color
\r
335 MOV AL, left ; do the left clip
\r
336 OUT DX, AL ; set the left clip
\r
337 MOV AL, BL ; restore color
\r
338 STOSB ; write the color
\r
340 JZ SCAN_DONE ; handle 1 group stuff
\r
342 ;-- write the main body of the scanline
\r
343 MOV BL, AL ; remember color
\r
344 MOV AL, 0x0f ; write to all pixels
\r
346 MOV AL, BL ; restore color
\r
347 REP STOSB ; write the color
\r
349 MOV BL, AL ; remeber color
\r
351 OUT DX, AL ; do the right clip
\r
352 MOV AL, BL ; restore color
\r
353 STOSB ; write pixel
\r
354 ADD DI, nextRow ; go to the next row
\r
360 /* moved to src/lib/modex16/16render.c */
\r
362 /* copy a region of video memory from one page to another.
\r
363 * It assumes that the left edge of the tile is the same on both
\r
364 * regions and the memory areas do not overlap.
\r
367 modexCopyPageRegion(page_t *dest, page_t *src,
\r
370 word width, word height)
\r
372 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
373 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
374 word scans = vga_state.vga_stride;
\r
375 word nextSrcRow = src->width/4 - scans - 1;
\r
376 word nextDestRow = dest->width/4 - scans - 1;
\r
377 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
378 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
379 byte left = lclip[sx&0x03];
\r
380 byte right = rclip[(sx+width)&0x03];
\r
383 MOV AX, SCREEN_SEG ; work in the vga space
\r
388 MOV DX, GC_INDEX ; turn off cpu bits
\r
392 MOV AX, SC_INDEX ; point to the mask register
\r
402 MOV CX, scans ; the number of latches
\r
404 MOV AL, left ; do the left column
\r
409 MOV AL, 0fh ; do the inner columns
\r
411 REP MOVSB ; copy the pixels
\r
413 MOV AL, right ; do the right column
\r
418 MOV AX, SI ; go the start of the next row
\r
419 ADD AX, nextSrcRow ;
\r
422 ADD AX, nextDestRow ;
\r
425 DEC height ; do the rest of the actions
\r
428 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
429 MOV AL, 0ffh ; none from latches
\r
435 /* fade and flash */
\r
437 modexFadeOn(word fade, byte *palette) {
\r
438 fadePalette(-fade, 64, 64/fade+1, palette);
\r
443 modexFadeOff(word fade, byte *palette) {
\r
444 fadePalette(fade, 0, 64/fade+1, palette);
\r
449 modexFlashOn(word fade, byte *palette) {
\r
450 fadePalette(fade, -64, 64/fade+1, palette);
\r
455 modexFlashOff(word fade, byte *palette) {
\r
456 fadePalette(-fade, 0, 64/fade+1, palette);
\r
461 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
465 /* handle the case where we just update */
\r
467 modexPalUpdate1(palette);
\r
471 while(iter > 0) { /* FadeLoop */
\r
472 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
473 tmppal[i] = palette[i] - dim;
\r
474 if(tmppal[i] > 127) {
\r
476 } else if(tmppal[i] > 63) {
\r
480 modexPalUpdate1(tmppal);
\r
487 /* save and load */
\r
489 modexPalSave(byte *palette) {
\r
492 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
493 for(i=0; i<PAL_SIZE; i++) {
\r
494 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
502 ptr = malloc(PAL_SIZE);
\r
504 /* handle errors */
\r
506 printf("Could not allocate palette.\n");
\r
515 modexLoadPalFile(byte *filename, byte **palette) {
\r
519 /* free the palette if it exists */
\r
524 /* allocate the new palette */
\r
525 *palette = modexNewPal();
\r
527 /* open the file */
\r
528 file = fopen(filename, "rb");
\r
530 printf("Could not open palette file: %s\n", filename);
\r
534 /* read the file */
\r
536 while(!feof(file)) {
\r
537 *ptr++ = fgetc(file);
\r
545 modexSavePalFile(char *filename, byte *pal) {
\r
549 /* open the file for writing */
\r
550 file = fopen(filename, "wb");
\r
552 printf("Could not open %s for writing\n", filename);
\r
556 /* write the data to the file */
\r
557 fwrite(pal, 1, PAL_SIZE, file);
\r
565 fadePalette(-1, 64, 1, tmppal);
\r
571 fadePalette(-1, -64, 1, tmppal);
\r
577 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
579 byte *p = bmp->palette;
\r
583 static word a[PAL_SIZE]; //palette array of change values!
\r
584 word z=0, aq=0, aa=0, pp=0;
\r
586 //modexWaitBorder();
\r
587 vga_wait_for_vsync();
\r
590 memset(a, -1, sizeof(a));
\r
591 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
601 // printf("q: %02d\n", (q));
\r
602 // printf("qq: %02d\n", (qq));
\r
603 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
604 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
606 if((*i)<PAL_SIZE/2 && w==0)
\r
608 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
610 //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
611 //____ 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
612 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
617 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
619 //printf("qp=%d\n", qp);
\r
620 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
621 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
622 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
623 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
627 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
629 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
630 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
631 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
634 //if(qp>0) printf("qp=%d\n", qp);
\r
635 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
637 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
638 vga_wait_for_vsync();
\r
639 if((*i)>=PAL_SIZE/2 && w==0)
\r
641 for(; (*i)<PAL_SIZE; (*i)++)
\r
643 //____ 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
644 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
649 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
651 //printf("qp=%d\n", qp);
\r
652 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
653 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
654 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
655 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
659 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
660 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
661 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
664 //printf(" (*i)=%d\n", (*i)/3);
\r
667 printf("\nqqqqqqqq\n\n");
\r
673 long bufSize = (bmp->width * bmp->height);
\r
675 //printf("1(*i)=%02d\n", (*i)/3);
\r
676 //printf("1z=%02d\n", z/3);
\r
677 modexchkcolor(bmp, &q, &a, &aa, &z, i);
\r
678 //printf("2(*i)=%02d\n", (*i)/3);
\r
679 //printf("2z=%02d\n", z/3);
\r
684 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
685 if(a[aq]==-1) aq++;
\r
686 else { aqoffset++; break; }
\r
688 //update the image data here!
\r
689 for(lq=0; lq<bufSize; lq++)
\r
693 use a[qp] instead of bmp->offset for this spot!
\r
698 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
701 //(offset/bmp->offset)*bmp->offset
\r
704 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
705 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
706 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
707 /*if(bmp->data[lq]+bmp->offset==aq)
\r
709 //printf("%02d", bmp->data[lq]);
\r
710 //printf("\n%02d\n", bmp->offset);
\r
711 printf("aq=%02d ", aq);
\r
712 printf("a[aq]=%02d ", a[aq]);
\r
713 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
714 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
715 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
716 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
717 // printf("_%d ", bmp->data[lq]);
\r
718 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
720 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
722 if(bmp->data[lq]+bmp->offset >= aq)
\r
724 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
725 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
727 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
730 //printf("%02d`", bmp->data[lq]);
\r
731 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
734 //printf(" aq=%02d\n", aq);
\r
735 //printf(" aa=%02d\n", aa);
\r
737 //update the palette~
\r
738 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
741 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
746 modexPalUpdate1(byte *p)
\r
749 //modexWaitBorder();
\r
750 vga_wait_for_vsync();
\r
751 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
752 for(i=0; i<PAL_SIZE/2; i++)
\r
754 outp(PAL_DATA_REG, p[i]);
\r
756 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
757 vga_wait_for_vsync();
\r
758 for(; i<PAL_SIZE; i++)
\r
760 outp(PAL_DATA_REG, p[(i)]);
\r
765 modexPalUpdate0(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, rand());
\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, rand());
\r
784 modexPalOverscan(byte *p, word col)
\r
786 //modexWaitBorder();
\r
787 vga_wait_for_vsync();
\r
788 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
789 outp(PAL_DATA_REG, col);
\r
793 //i want to make another vesion that checks the palette when the palette is being appened~
\r
794 void modexchkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
798 pal = modexNewPal();
\r
800 //printf("q: %02d\n", (*q));
\r
801 printf("chkcolor start~\n");
\r
802 printf("1 (*z): %d\n", (*z)/3);
\r
803 printf("1 (*i): %d\n", (*i)/3);
\r
804 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
805 printf("wwwwwwwwwwwwwwww\n");
\r
806 //check palette for dups
\r
807 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
809 //printf("\n z: %d\n", (*z));
\r
810 //printf(" q: %d\n", (*q));
\r
811 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
814 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
817 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
818 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
822 else for(zz=0; zz<(*q); zz+=3)
\r
824 //printf("zz: %02d\n", zz/3);
\r
827 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
831 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
832 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
835 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
837 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
838 // 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
839 // 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
840 // //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
841 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
846 planned features that i plan to implement~
\r
847 image that has values on the pallete list!
\r
849 no... wait.... no wwww
\r
851 //for(zzii=0; zzii<3; zzii++)
\r
853 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
854 a[(((*z)+(*q)))]=zz;
\r
856 (*aa)=(((*z)+(*q)));
\r
857 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
858 // printf("\n aa: %d\n\n", (*aa));
\r
859 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
860 // printf("wwwwwwwwwwwwwwww\n\n");
\r
864 printf("================\n");
\r
865 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
866 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
867 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
868 printf("================\n");
\r
870 //printf("[%d]", (zz+q));
\r
874 printf("wwwwwwwwwwwwwwww\n");
\r
875 printf("2 (*z): %d\n", (*z)/3);
\r
876 printf("2 (*i): %d\n", (*i)/3);
\r
877 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
878 printf("chkcolor end~\n");
\r
882 void modexputPixel(page_t *page, int x, int y, byte color)
\r
884 word pageOff = (word) page->data;
\r
885 /* Each address accesses four neighboring pixels, so set
\r
886 Write Plane Enable according to which pixel we want
\r
887 to modify. The plane is determined by the two least
\r
888 significant bits of the x-coordinate: */
\r
889 modexSelectPlane(PLANE(x));
\r
890 //outp(SC_INDEX, 0x02);
\r
891 //outp(SC_DATA, 0x01 << (x & 3));
\r
893 /* The offset of the pixel into the video segment is
\r
894 offset = (width * y + x) / 4, and write the given
\r
895 color to the plane we selected above. Heed the active
\r
896 page start selection. */
\r
897 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
901 byte modexgetPixel(page_t *page, int x, int y)
\r
903 word pageOff = (word) page->data;
\r
904 /* Select the plane from which we must read the pixel color: */
\r
905 outpw(GC_INDEX, 0x04);
\r
906 outpw(GC_INDEX+1, x & 3);
\r
908 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
912 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
916 word addr = (word) romFontsData.l;
\r
917 word addrq = (page->width/4) * y + (x / 4) + ((word)page->data);
\r
918 word addrr = addrq;
\r
923 w=romFonts[t].charSize;
\r
924 romFontsData.chw=0;
\r
926 for(; *str != '\0'; str++)
\r
932 romFontsData.chw = 0;
\r
933 addrq += (page->width / 4) * 8;
\r
939 // load the character into romFontsData.l
\r
940 // no need for inline assembly!
\r
941 // NTS: It might even be faster to just let the modexDrawChar point directly at ROM font than to copy per char! --J.C.
\r
942 _fmemcpy(romFontsData.l,MK_FP(s,o+(w*c))/*ROM font location*/,w/*char size*/);
\r
943 modexDrawChar(page, x_draw/*for mode X planar use*/, t, col, bgcol, addrr);
\r
944 x_draw += 8; /* track X for edge of screen */
\r
945 addrr += 2; /* move 8 pixels over (2 x 4 planar pixels per byte) */
\r
949 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
951 word i, s, o, w, j, xp;
\r
953 word addr = (word) l;
\r
980 for(; *str != '\0'; str++)
\r
983 if((c=='\n'/* || c=="\
\r
984 "*/)/* || chw>=page->width*/)
\r
990 //load the letter 'A'
\r
996 MOV AL, c ; the letter
\r
999 ADD SI, AX ;the address of charcter
\r
1008 for(i=0; i<w; i++)
\r
1014 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1015 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1024 /* palette dump on display! */
\r
1025 void modexpdump(page_t *pee)
\r
1027 int mult=(QUADWH);
\r
1028 int palq=(mult)*TILEWH;
\r
1031 for(paly=0; paly<palq; paly+=mult){
\r
1032 for(palx=0; palx<palq; palx+=mult){
\r
1033 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
\r
1039 /////////////////////////////////////////////////////////////////////////////
\r
1041 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1042 // the Virtual screen. //
\r
1044 /////////////////////////////////////////////////////////////////////////////
\r
1045 void modexcls(page_t *page, byte color, byte *Where)
\r
1047 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1048 /* set map mask to all 4 planes */
\r
1049 outpw(SC_INDEX, 0xff02);
\r
1050 //_fmemset(VGA, color, 16000);
\r
1051 _fmemset(Where, color, page->width*(page->height)/4);
\r
1055 modexWaitBorder() {
\r
1056 while(inp(INPUT_STATUS_1) & 8) {
\r
1060 while(!(inp(INPUT_STATUS_1) & 8)) {
\r
1070 m = int10_getmode();
\r
1071 if ((rp=vga_state.vga_graphics_ram) != NULL && !(m <= 3 || m == 7)) {
\r
1072 unsigned int i,im;
\r
1074 im = (FP_SEG(vga_state.vga_graphics_ram_fence) - FP_SEG(vga_state.vga_graphics_ram));
\r
1075 if (im > 0xFFE) im = 0xFFE;
\r
1077 for (i=0;i < im;i++) vga_state.vga_graphics_ram[i] = 0;
\r
1079 else if ((ap=vga_state.vga_alpha_ram) != NULL) {
\r
1080 unsigned int i,im;
\r
1082 im = (FP_SEG(vga_state.vga_alpha_ram_fence) - FP_SEG(vga_state.vga_alpha_ram));
\r
1083 if (im > 0x7FE) im = 0x7FE;
\r
1084 im <<= 4 - 1; /* because ptr is type uint16_t */
\r
1085 for (i=0;i < im;i++) vga_state.vga_alpha_ram[i] = 0x0720;
\r
1088 printf("WARNING: bios cls no ptr\n");
\r