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
296 modexPanPage(page_t *page, int dx, int dy) {
\r
302 modexSelectPlane(byte plane) {
\r
303 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
304 outp(SC_DATA, plane);
\r
308 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
309 word pageOff = (word) page->data;
\r
310 word xoff=x/4; /* xoffset that begins each row */
\r
311 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
312 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
313 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
314 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
315 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
316 byte left = lclip[x&0x03];
\r
317 byte right = rclip[(x+w)&0x03];
\r
319 /* handle the case which requires an extra group */
\r
320 if((x & 0x03) && !((x+w) & 0x03)) {
\r
325 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
327 MOV DI, poffset ; go to the first pixel
\r
328 MOV DX, SC_INDEX ; point to the map mask
\r
332 MOV AL, color ; get ready to write colors
\r
334 MOV CX, scanCount ; count the line
\r
335 MOV BL, AL ; remember color
\r
336 MOV AL, left ; do the left clip
\r
337 OUT DX, AL ; set the left clip
\r
338 MOV AL, BL ; restore color
\r
339 STOSB ; write the color
\r
341 JZ SCAN_DONE ; handle 1 group stuff
\r
343 ;-- write the main body of the scanline
\r
344 MOV BL, AL ; remember color
\r
345 MOV AL, 0x0f ; write to all pixels
\r
347 MOV AL, BL ; restore color
\r
348 REP STOSB ; write the color
\r
350 MOV BL, AL ; remeber color
\r
352 OUT DX, AL ; do the right clip
\r
353 MOV AL, BL ; restore color
\r
354 STOSB ; write pixel
\r
355 ADD DI, nextRow ; go to the next row
\r
361 /* moved to src/lib/modex16/16render.c */
\r
363 /* copy a region of video memory from one page to another.
\r
364 * It assumes that the left edge of the tile is the same on both
\r
365 * regions and the memory areas do not overlap.
\r
368 modexCopyPageRegion(page_t *dest, page_t *src,
\r
371 word width, word height)
\r
373 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
374 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
375 word scans = vga_state.vga_stride;
\r
376 word nextSrcRow = src->width/4 - scans - 1;
\r
377 word nextDestRow = dest->width/4 - scans - 1;
\r
378 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
379 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
380 byte left = lclip[sx&0x03];
\r
381 byte right = rclip[(sx+width)&0x03];
\r
384 MOV AX, SCREEN_SEG ; work in the vga space
\r
389 MOV DX, GC_INDEX ; turn off cpu bits
\r
393 MOV AX, SC_INDEX ; point to the mask register
\r
403 MOV CX, scans ; the number of latches
\r
405 MOV AL, left ; do the left column
\r
410 MOV AL, 0fh ; do the inner columns
\r
412 REP MOVSB ; copy the pixels
\r
414 MOV AL, right ; do the right column
\r
419 MOV AX, SI ; go the start of the next row
\r
420 ADD AX, nextSrcRow ;
\r
423 ADD AX, nextDestRow ;
\r
426 DEC height ; do the rest of the actions
\r
429 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
430 MOV AL, 0ffh ; none from latches
\r
436 /* fade and flash */
\r
438 modexFadeOn(word fade, byte *palette) {
\r
439 fadePalette(-fade, 64, 64/fade+1, palette);
\r
444 modexFadeOff(word fade, byte *palette) {
\r
445 fadePalette(fade, 0, 64/fade+1, palette);
\r
450 modexFlashOn(word fade, byte *palette) {
\r
451 fadePalette(fade, -64, 64/fade+1, palette);
\r
456 modexFlashOff(word fade, byte *palette) {
\r
457 fadePalette(-fade, 0, 64/fade+1, palette);
\r
462 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
466 /* handle the case where we just update */
\r
468 modexPalUpdate1(palette);
\r
472 while(iter > 0) { /* FadeLoop */
\r
473 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
474 tmppal[i] = palette[i] - dim;
\r
475 if(tmppal[i] > 127) {
\r
477 } else if(tmppal[i] > 63) {
\r
481 modexPalUpdate1(tmppal);
\r
488 /* save and load */
\r
490 modexPalSave(byte *palette) {
\r
493 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
494 for(i=0; i<PAL_SIZE; i++) {
\r
495 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
503 ptr = malloc(PAL_SIZE);
\r
505 /* handle errors */
\r
507 printf("Could not allocate palette.\n");
\r
516 modexLoadPalFile(byte *filename, byte **palette) {
\r
520 /* free the palette if it exists */
\r
525 /* allocate the new palette */
\r
526 *palette = modexNewPal();
\r
528 /* open the file */
\r
529 file = fopen(filename, "rb");
\r
531 printf("Could not open palette file: %s\n", filename);
\r
535 /* read the file */
\r
537 while(!feof(file)) {
\r
538 *ptr++ = fgetc(file);
\r
546 modexSavePalFile(char *filename, byte *pal) {
\r
550 /* open the file for writing */
\r
551 file = fopen(filename, "wb");
\r
553 printf("Could not open %s for writing\n", filename);
\r
557 /* write the data to the file */
\r
558 fwrite(pal, 1, PAL_SIZE, file);
\r
566 fadePalette(-1, 64, 1, tmppal);
\r
572 fadePalette(-1, -64, 1, tmppal);
\r
578 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
580 byte *p = bmp->palette;
\r
584 static word a[PAL_SIZE]; //palette array of change values!
\r
585 word z=0, aq=0, aa=0, pp=0;
\r
587 //modexWaitBorder();
\r
588 vga_wait_for_vsync();
\r
591 memset(a, -1, sizeof(a));
\r
592 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
602 // printf("q: %02d\n", (q));
\r
603 // printf("qq: %02d\n", (qq));
\r
604 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
605 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
607 if((*i)<PAL_SIZE/2 && w==0)
\r
609 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
611 //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
612 //____ 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
613 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
618 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
620 //printf("qp=%d\n", qp);
\r
621 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
622 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
623 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
624 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
628 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
630 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
631 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
632 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
635 //if(qp>0) printf("qp=%d\n", qp);
\r
636 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
638 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
639 vga_wait_for_vsync();
\r
640 if((*i)>=PAL_SIZE/2 && w==0)
\r
642 for(; (*i)<PAL_SIZE; (*i)++)
\r
644 //____ 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
645 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
650 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
652 //printf("qp=%d\n", qp);
\r
653 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
654 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
655 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
656 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
660 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
661 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
662 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
665 //printf(" (*i)=%d\n", (*i)/3);
\r
668 printf("\nqqqqqqqq\n\n");
\r
674 long bufSize = (bmp->width * bmp->height);
\r
676 //printf("1(*i)=%02d\n", (*i)/3);
\r
677 //printf("1z=%02d\n", z/3);
\r
678 modexchkcolor(bmp, &q, &a, &aa, &z, i);
\r
679 //printf("2(*i)=%02d\n", (*i)/3);
\r
680 //printf("2z=%02d\n", z/3);
\r
685 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
686 if(a[aq]==-1) aq++;
\r
687 else { aqoffset++; break; }
\r
689 //update the image data here!
\r
690 for(lq=0; lq<bufSize; lq++)
\r
694 use a[qp] instead of bmp->offset for this spot!
\r
699 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
702 //(offset/bmp->offset)*bmp->offset
\r
705 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
706 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
707 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
708 /*if(bmp->data[lq]+bmp->offset==aq)
\r
710 //printf("%02d", bmp->data[lq]);
\r
711 //printf("\n%02d\n", bmp->offset);
\r
712 printf("aq=%02d ", aq);
\r
713 printf("a[aq]=%02d ", a[aq]);
\r
714 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
715 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
716 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
717 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
718 // printf("_%d ", bmp->data[lq]);
\r
719 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
721 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
723 if(bmp->data[lq]+bmp->offset >= aq)
\r
725 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
726 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
728 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
731 //printf("%02d`", bmp->data[lq]);
\r
732 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
735 //printf(" aq=%02d\n", aq);
\r
736 //printf(" aa=%02d\n", aa);
\r
738 //update the palette~
\r
739 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
742 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
747 modexPalUpdate1(byte *p)
\r
750 //modexWaitBorder();
\r
751 vga_wait_for_vsync();
\r
752 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
753 for(i=0; i<PAL_SIZE/2; i++)
\r
755 outp(PAL_DATA_REG, p[i]);
\r
757 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
758 vga_wait_for_vsync();
\r
759 for(; i<PAL_SIZE; i++)
\r
761 outp(PAL_DATA_REG, p[(i)]);
\r
766 modexPalUpdate0(byte *p)
\r
769 //modexWaitBorder();
\r
770 vga_wait_for_vsync();
\r
771 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
772 for(i=0; i<PAL_SIZE/2; i++)
\r
774 outp(PAL_DATA_REG, rand());
\r
776 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
777 vga_wait_for_vsync();
\r
778 for(; i<PAL_SIZE; i++)
\r
780 outp(PAL_DATA_REG, rand());
\r
785 modexPalOverscan(byte *p, word col)
\r
787 //modexWaitBorder();
\r
788 vga_wait_for_vsync();
\r
789 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
790 outp(PAL_DATA_REG, col);
\r
794 //i want to make another vesion that checks the palette when the palette is being appened~
\r
795 void modexchkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
799 pal = modexNewPal();
\r
801 //printf("q: %02d\n", (*q));
\r
802 printf("chkcolor start~\n");
\r
803 printf("1 (*z): %d\n", (*z)/3);
\r
804 printf("1 (*i): %d\n", (*i)/3);
\r
805 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
806 printf("wwwwwwwwwwwwwwww\n");
\r
807 //check palette for dups
\r
808 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
810 //printf("\n z: %d\n", (*z));
\r
811 //printf(" q: %d\n", (*q));
\r
812 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
815 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
818 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
819 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
823 else for(zz=0; zz<(*q); zz+=3)
\r
825 //printf("zz: %02d\n", zz/3);
\r
828 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
832 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
833 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
836 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
838 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
839 // 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
840 // 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
841 // //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
842 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
847 planned features that i plan to implement~
\r
848 image that has values on the pallete list!
\r
850 no... wait.... no wwww
\r
852 //for(zzii=0; zzii<3; zzii++)
\r
854 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
855 a[(((*z)+(*q)))]=zz;
\r
857 (*aa)=(((*z)+(*q)));
\r
858 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
859 // printf("\n aa: %d\n\n", (*aa));
\r
860 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
861 // printf("wwwwwwwwwwwwwwww\n\n");
\r
865 printf("================\n");
\r
866 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
867 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
868 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
869 printf("================\n");
\r
871 //printf("[%d]", (zz+q));
\r
875 printf("wwwwwwwwwwwwwwww\n");
\r
876 printf("2 (*z): %d\n", (*z)/3);
\r
877 printf("2 (*i): %d\n", (*i)/3);
\r
878 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
879 printf("chkcolor end~\n");
\r
883 void modexputPixel(page_t *page, int x, int y, byte color)
\r
885 word pageOff = (word) page->data;
\r
886 /* Each address accesses four neighboring pixels, so set
\r
887 Write Plane Enable according to which pixel we want
\r
888 to modify. The plane is determined by the two least
\r
889 significant bits of the x-coordinate: */
\r
890 modexSelectPlane(PLANE(x));
\r
891 //outp(SC_INDEX, 0x02);
\r
892 //outp(SC_DATA, 0x01 << (x & 3));
\r
894 /* The offset of the pixel into the video segment is
\r
895 offset = (width * y + x) / 4, and write the given
\r
896 color to the plane we selected above. Heed the active
\r
897 page start selection. */
\r
898 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
902 byte modexgetPixel(page_t *page, int x, int y)
\r
904 word pageOff = (word) page->data;
\r
905 /* Select the plane from which we must read the pixel color: */
\r
906 outpw(GC_INDEX, 0x04);
\r
907 outpw(GC_INDEX+1, x & 3);
\r
909 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
913 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
917 word addr = (word) romFontsData.l;
\r
918 word addrq = (page->width/4) * y + (x / 4) + ((word)page->data);
\r
919 word addrr = addrq;
\r
924 w=romFonts[t].charSize;
\r
925 romFontsData.chw=0;
\r
927 for(; *str != '\0'; str++)
\r
933 romFontsData.chw = 0;
\r
934 addrq += (page->width / 4) * 8;
\r
940 // load the character into romFontsData.l
\r
941 // no need for inline assembly!
\r
942 // NTS: It might even be faster to just let the modexDrawChar point directly at ROM font than to copy per char! --J.C.
\r
943 _fmemcpy(romFontsData.l,MK_FP(s,o+(w*c))/*ROM font location*/,w/*char size*/);
\r
944 modexDrawChar(page, x_draw/*for mode X planar use*/, t, col, bgcol, addrr);
\r
945 x_draw += 8; /* track X for edge of screen */
\r
946 addrr += 2; /* move 8 pixels over (2 x 4 planar pixels per byte) */
\r
950 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
952 word i, s, o, w, j, xp;
\r
954 word addr = (word) l;
\r
981 for(; *str != '\0'; str++)
\r
984 if((c=='\n'/* || c=="\
\r
985 "*/)/* || chw>=page->width*/)
\r
991 //load the letter 'A'
\r
997 MOV AL, c ; the letter
\r
1000 ADD SI, AX ;the address of charcter
\r
1009 for(i=0; i<w; i++)
\r
1015 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1016 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1025 /* palette dump on display! */
\r
1026 void modexpdump(page_t *pee)
\r
1028 int mult=(QUADWH);
\r
1029 int palq=(mult)*TILEWH;
\r
1032 for(paly=0; paly<palq; paly+=mult){
\r
1033 for(palx=0; palx<palq; palx+=mult){
\r
1034 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
\r
1040 /////////////////////////////////////////////////////////////////////////////
\r
1042 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1043 // the Virtual screen. //
\r
1045 /////////////////////////////////////////////////////////////////////////////
\r
1046 void modexcls(page_t *page, byte color, byte *Where)
\r
1048 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1049 /* set map mask to all 4 planes */
\r
1050 outpw(SC_INDEX, 0xff02);
\r
1051 //_fmemset(VGA, color, 16000);
\r
1052 _fmemset(Where, color, page->width*(page->height)/4);
\r
1056 modexWaitBorder() {
\r
1057 while(inp(INPUT_STATUS_1) & 8) {
\r
1061 while(!(inp(INPUT_STATUS_1) & 8)) {
\r
1071 m = int10_getmode();
\r
1072 if ((rp=vga_state.vga_graphics_ram) != NULL && !(m <= 3 || m == 7)) {
\r
1073 unsigned int i,im;
\r
1075 im = (FP_SEG(vga_state.vga_graphics_ram_fence) - FP_SEG(vga_state.vga_graphics_ram));
\r
1076 if (im > 0xFFE) im = 0xFFE;
\r
1078 for (i=0;i < im;i++) vga_state.vga_graphics_ram[i] = 0;
\r
1080 else if ((ap=vga_state.vga_alpha_ram) != NULL) {
\r
1081 unsigned int i,im;
\r
1083 im = (FP_SEG(vga_state.vga_alpha_ram_fence) - FP_SEG(vga_state.vga_alpha_ram));
\r
1084 if (im > 0x7FE) im = 0x7FE;
\r
1085 im <<= 4 - 1; /* because ptr is type uint16_t */
\r
1086 for (i=0;i < im;i++) vga_state.vga_alpha_ram[i] = 0x0720;
\r
1089 printf("WARNING: bios cls no ptr\n");
\r