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
151 gv->video.page[0].tilesw = gv->video.page[0].sw/TILEWH;
\r
152 gv->video.page[0].tilesh = gv->video.page[0].sh/TILEWH;
\r
153 //TODO MAKE FLEXIBLE~
\r
154 gv->video.page[0].tilemidposscreenx = gv->video.page[0].tilesw;
\r
155 gv->video.page[0].tilemidposscreeny = (gv->video.page[0].tilesh/2)+1;
\r
160 /* VGAmodeX restores original mode and palette */
\r
161 vgaSetMode(TEXT_MODE);
\r
165 modexDefaultPage(page_t *p)
\r
169 /* default page values */
\r
170 page.data = vga_state.vga_graphics_ram;//VGA;
\r
175 page.width = p->sw;
\r
176 page.height = p->sh;
\r
177 page.tw = page.sw/TILEWH;
\r
178 page.th = page.sh/TILEWH;
\r
179 page.tilemidposscreenx = page.tw/2;
\r
180 page.tilemidposscreeny = (page.th/2)+1;
\r
181 page.tilesw=p->tilesw;
\r
182 page.tilesh=p->tilesh;
\r
183 page.pagesize = page.width*page.height;
\r
189 /* returns the next page in contiguous memory
\r
190 * the next page will be the same size as p, by default
\r
193 modexNextPage(page_t *p) {
\r
196 result.data = p->data + (p->width/4)*p->height;
\r
199 result.width = p->width;
\r
200 result.height = p->height;
\r
201 result.tw = p->width/TILEWH;
\r
202 result.th = p->height/TILEWH;
\r
203 result.id = p->id+1;
\r
204 result.pagesize = p->pagesize;
\r
209 //next page with defined dimentions~
\r
211 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
215 result.data = p->data + (p->width/4)*p->height; /* compute the offset */
\r
220 result.tw = p->width/TILEWH;
\r
221 result.th = p->height/TILEWH;
\r
222 result.id = p->id+1;
\r
223 result.pagesize = result.width*result.height;
\r
228 void modexCalcVmemRemain(video_t *video)
\r
231 video->vmem_remain=262144;
\r
232 for(i=0; i<=video->num_of_pages; i++)
\r
234 video->vmem_remain-=video->page[i].pagesize;
\r
238 void modexHiganbanaPageSetup(video_t *video)
\r
240 (video->page[0]) = modexDefaultPage(&(video->page[0])); video->num_of_pages++;
\r
241 video->page[0].width += (TILEWHD); video->page[0].height += (TILEWHD);
\r
242 (video->page[1]) = modexNextPage(&(video->page[0])); video->num_of_pages++;
\r
243 // (video->page[2]) = modexNextPageFlexibleSize(&(video->page[1]), video->page[0].width, 16); video->num_of_pages++;
\r
244 // (video->page[2]) = modexNextPage(&(video->page[1])); video->num_of_pages++;
\r
245 //(352*176)+1024 is the remaining amount of memory left wwww
\r
246 // modexCalcVmemRemain(video);
\r
247 // (video->page[3]) = modexNextPageFlexibleSize(&(video->page[2]), video->page[0].sw, 92); video->num_of_pages++;
\r
248 modexCalcVmemRemain(video);
\r
252 modexShowPage(page_t *page) {
\r
258 /* calculate offset */
\r
259 offset = (word) page->data;
\r
260 offset += page->dy * (page->width >> 2 );
\r
261 offset += page->dx >> 2;
\r
263 /* calculate crtcOffset according to virtual width */
\r
264 crtcOffset = page->width >> 3;
\r
266 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
267 low_address = LOW_ADDRESS | (offset << 8);
\r
269 /* wait for appropriate timing and then program CRTC */
\r
270 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
271 outpw(CRTC_INDEX, high_address);
\r
272 outpw(CRTC_INDEX, low_address);
\r
273 outp(CRTC_INDEX, 0x13);
\r
274 outp(CRTC_DATA, crtcOffset);
\r
276 /* wait for one retrace */
\r
277 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
279 /* do PEL panning here */
\r
280 outp(AC_INDEX, 0x33);
\r
281 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
286 modexPanPage(page_t *page, int dx, int dy) {
\r
293 modexSelectPlane(byte plane) {
\r
294 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
295 outp(SC_DATA, plane);
\r
300 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
301 word pageOff = (word) page->data;
\r
302 word xoff=x/4; /* xoffset that begins each row */
\r
303 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
304 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
305 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
306 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
307 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
308 byte left = lclip[x&0x03];
\r
309 byte right = rclip[(x+w)&0x03];
\r
311 /* handle the case which requires an extra group */
\r
312 if((x & 0x03) && !((x+w) & 0x03)) {
\r
317 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
319 MOV DI, poffset ; go to the first pixel
\r
320 MOV DX, SC_INDEX ; point to the map mask
\r
324 MOV AL, color ; get ready to write colors
\r
326 MOV CX, scanCount ; count the line
\r
327 MOV BL, AL ; remember color
\r
328 MOV AL, left ; do the left clip
\r
329 OUT DX, AL ; set the left clip
\r
330 MOV AL, BL ; restore color
\r
331 STOSB ; write the color
\r
333 JZ SCAN_DONE ; handle 1 group stuff
\r
335 ;-- write the main body of the scanline
\r
336 MOV BL, AL ; remember color
\r
337 MOV AL, 0x0f ; write to all pixels
\r
339 MOV AL, BL ; restore color
\r
340 REP STOSB ; write the color
\r
342 MOV BL, AL ; remeber color
\r
344 OUT DX, AL ; do the right clip
\r
345 MOV AL, BL ; restore color
\r
346 STOSB ; write pixel
\r
347 ADD DI, nextRow ; go to the next row
\r
353 /* moved to src/lib/modex16/16render.c */
\r
355 /* copy a region of video memory from one page to another.
\r
356 * It assumes that the left edge of the tile is the same on both
\r
357 * regions and the memory areas do not overlap.
\r
360 modexCopyPageRegion(page_t *dest, page_t *src,
\r
363 word width, word height)
\r
365 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
366 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
367 word scans = vga_state.vga_stride;
\r
368 word nextSrcRow = src->width/4 - scans - 1;
\r
369 word nextDestRow = dest->width/4 - scans - 1;
\r
370 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
371 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
372 byte left = lclip[sx&0x03];
\r
373 byte right = rclip[(sx+width)&0x03];
\r
376 MOV AX, SCREEN_SEG ; work in the vga space
\r
381 MOV DX, GC_INDEX ; turn off cpu bits
\r
385 MOV AX, SC_INDEX ; point to the mask register
\r
395 MOV CX, scans ; the number of latches
\r
397 MOV AL, left ; do the left column
\r
402 MOV AL, 0fh ; do the inner columns
\r
404 REP MOVSB ; copy the pixels
\r
406 MOV AL, right ; do the right column
\r
411 MOV AX, SI ; go the start of the next row
\r
412 ADD AX, nextSrcRow ;
\r
415 ADD AX, nextDestRow ;
\r
418 DEC height ; do the rest of the actions
\r
421 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
422 MOV AL, 0ffh ; none from latches
\r
428 /* fade and flash */
\r
430 modexFadeOn(word fade, byte *palette) {
\r
431 fadePalette(-fade, 64, 64/fade+1, palette);
\r
436 modexFadeOff(word fade, byte *palette) {
\r
437 fadePalette(fade, 0, 64/fade+1, palette);
\r
442 modexFlashOn(word fade, byte *palette) {
\r
443 fadePalette(fade, -64, 64/fade+1, palette);
\r
448 modexFlashOff(word fade, byte *palette) {
\r
449 fadePalette(-fade, 0, 64/fade+1, palette);
\r
454 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
458 /* handle the case where we just update */
\r
460 modexPalUpdate1(palette);
\r
464 while(iter > 0) { /* FadeLoop */
\r
465 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
466 tmppal[i] = palette[i] - dim;
\r
467 if(tmppal[i] > 127) {
\r
469 } else if(tmppal[i] > 63) {
\r
473 modexPalUpdate1(tmppal);
\r
480 /* save and load */
\r
482 modexPalSave(byte *palette) {
\r
485 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
486 for(i=0; i<PAL_SIZE; i++) {
\r
487 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
495 ptr = malloc(PAL_SIZE);
\r
497 /* handle errors */
\r
499 printf("Could not allocate palette.\n");
\r
508 modexLoadPalFile(byte *filename, byte **palette) {
\r
512 /* free the palette if it exists */
\r
517 /* allocate the new palette */
\r
518 *palette = modexNewPal();
\r
520 /* open the file */
\r
521 file = fopen(filename, "rb");
\r
523 printf("Could not open palette file: %s\n", filename);
\r
527 /* read the file */
\r
529 while(!feof(file)) {
\r
530 *ptr++ = fgetc(file);
\r
538 modexSavePalFile(char *filename, byte *pal) {
\r
542 /* open the file for writing */
\r
543 file = fopen(filename, "wb");
\r
545 printf("Could not open %s for writing\n", filename);
\r
549 /* write the data to the file */
\r
550 fwrite(pal, 1, PAL_SIZE, file);
\r
558 fadePalette(-1, 64, 1, tmppal);
\r
564 fadePalette(-1, -64, 1, tmppal);
\r
570 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
572 byte *p = bmp->palette;
\r
576 static word a[PAL_SIZE]; //palette array of change values!
\r
577 word z=0, aq=0, aa=0, pp=0;
\r
579 //modexWaitBorder();
\r
580 vga_wait_for_vsync();
\r
583 memset(a, -1, sizeof(a));
\r
584 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
594 // printf("q: %02d\n", (q));
\r
595 // printf("qq: %02d\n", (qq));
\r
596 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
597 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
599 if((*i)<PAL_SIZE/2 && w==0)
\r
601 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
603 //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
604 //____ 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
605 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
610 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
612 //printf("qp=%d\n", qp);
\r
613 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
614 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
615 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
616 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
620 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
622 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
623 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
624 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
627 //if(qp>0) printf("qp=%d\n", qp);
\r
628 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
630 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
631 vga_wait_for_vsync();
\r
632 if((*i)>=PAL_SIZE/2 && w==0)
\r
634 for(; (*i)<PAL_SIZE; (*i)++)
\r
636 //____ 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
637 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
642 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
644 //printf("qp=%d\n", qp);
\r
645 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
646 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
647 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
648 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
652 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
653 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
654 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
657 //printf(" (*i)=%d\n", (*i)/3);
\r
660 printf("\nqqqqqqqq\n\n");
\r
666 long bufSize = (bmp->width * bmp->height);
\r
668 //printf("1(*i)=%02d\n", (*i)/3);
\r
669 //printf("1z=%02d\n", z/3);
\r
670 modexchkcolor(bmp, &q, &a, &aa, &z, i);
\r
671 //printf("2(*i)=%02d\n", (*i)/3);
\r
672 //printf("2z=%02d\n", z/3);
\r
677 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
678 if(a[aq]==-1) aq++;
\r
679 else { aqoffset++; break; }
\r
681 //update the image data here!
\r
682 for(lq=0; lq<bufSize; lq++)
\r
686 use a[qp] instead of bmp->offset for this spot!
\r
691 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
694 //(offset/bmp->offset)*bmp->offset
\r
697 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
698 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
699 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
700 /*if(bmp->data[lq]+bmp->offset==aq)
\r
702 //printf("%02d", bmp->data[lq]);
\r
703 //printf("\n%02d\n", bmp->offset);
\r
704 printf("aq=%02d ", aq);
\r
705 printf("a[aq]=%02d ", a[aq]);
\r
706 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
707 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
708 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
709 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
710 // printf("_%d ", bmp->data[lq]);
\r
711 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
713 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
715 if(bmp->data[lq]+bmp->offset >= aq)
\r
717 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
718 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
720 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
723 //printf("%02d`", bmp->data[lq]);
\r
724 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
727 //printf(" aq=%02d\n", aq);
\r
728 //printf(" aa=%02d\n", aa);
\r
730 //update the palette~
\r
731 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
734 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
739 modexPalUpdate1(byte *p)
\r
742 //modexWaitBorder();
\r
743 vga_wait_for_vsync();
\r
744 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
745 for(i=0; i<PAL_SIZE/2; i++)
\r
747 outp(PAL_DATA_REG, p[i]);
\r
749 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
750 vga_wait_for_vsync();
\r
751 for(; i<PAL_SIZE; i++)
\r
753 outp(PAL_DATA_REG, p[(i)]);
\r
758 modexPalUpdate0(byte *p)
\r
761 //modexWaitBorder();
\r
762 vga_wait_for_vsync();
\r
763 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
764 for(i=0; i<PAL_SIZE/2; i++)
\r
766 outp(PAL_DATA_REG, rand());
\r
768 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
769 vga_wait_for_vsync();
\r
770 for(; i<PAL_SIZE; i++)
\r
772 outp(PAL_DATA_REG, rand());
\r
777 modexPalOverscan(byte *p, word col)
\r
779 //modexWaitBorder();
\r
780 vga_wait_for_vsync();
\r
781 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
782 outp(PAL_DATA_REG, col);
\r
786 //i want to make another vesion that checks the palette when the palette is being appened~
\r
787 void modexchkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
791 pal = modexNewPal();
\r
793 //printf("q: %02d\n", (*q));
\r
794 printf("chkcolor start~\n");
\r
795 printf("1 (*z): %d\n", (*z)/3);
\r
796 printf("1 (*i): %d\n", (*i)/3);
\r
797 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
798 printf("wwwwwwwwwwwwwwww\n");
\r
799 //check palette for dups
\r
800 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
802 //printf("\n z: %d\n", (*z));
\r
803 //printf(" q: %d\n", (*q));
\r
804 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
807 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
810 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
811 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
815 else for(zz=0; zz<(*q); zz+=3)
\r
817 //printf("zz: %02d\n", zz/3);
\r
820 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
824 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
825 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
828 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
830 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
831 // 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
832 // 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
833 // //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
834 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
839 planned features that i plan to implement~
\r
840 image that has values on the pallete list!
\r
842 no... wait.... no wwww
\r
844 //for(zzii=0; zzii<3; zzii++)
\r
846 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
847 a[(((*z)+(*q)))]=zz;
\r
849 (*aa)=(((*z)+(*q)));
\r
850 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
851 // printf("\n aa: %d\n\n", (*aa));
\r
852 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
853 // printf("wwwwwwwwwwwwwwww\n\n");
\r
857 printf("================\n");
\r
858 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
859 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
860 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
861 printf("================\n");
\r
863 //printf("[%d]", (zz+q));
\r
867 printf("wwwwwwwwwwwwwwww\n");
\r
868 printf("2 (*z): %d\n", (*z)/3);
\r
869 printf("2 (*i): %d\n", (*i)/3);
\r
870 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
871 printf("chkcolor end~\n");
\r
875 void modexputPixel(page_t *page, int x, int y, byte color)
\r
877 word pageOff = (word) page->data;
\r
878 /* Each address accesses four neighboring pixels, so set
\r
879 Write Plane Enable according to which pixel we want
\r
880 to modify. The plane is determined by the two least
\r
881 significant bits of the x-coordinate: */
\r
882 modexSelectPlane(PLANE(x));
\r
883 //outp(SC_INDEX, 0x02);
\r
884 //outp(SC_DATA, 0x01 << (x & 3));
\r
886 /* The offset of the pixel into the video segment is
\r
887 offset = (width * y + x) / 4, and write the given
\r
888 color to the plane we selected above. Heed the active
\r
889 page start selection. */
\r
890 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
894 byte modexgetPixel(page_t *page, int x, int y)
\r
896 word pageOff = (word) page->data;
\r
897 /* Select the plane from which we must read the pixel color: */
\r
898 outpw(GC_INDEX, 0x04);
\r
899 outpw(GC_INDEX+1, x & 3);
\r
901 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
905 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
909 word addr = (word) romFontsData.l;
\r
910 word addrq = (page->width/4) * y + (x / 4) + ((word)page->data);
\r
911 word addrr = addrq;
\r
916 w=romFonts[t].charSize;
\r
917 romFontsData.chw=0;
\r
919 for(; *str != '\0'; str++)
\r
925 romFontsData.chw = 0;
\r
926 addrq += (page->width / 4) * 8;
\r
932 // load the character into romFontsData.l
\r
933 // no need for inline assembly!
\r
934 // NTS: It might even be faster to just let the modexDrawChar point directly at ROM font than to copy per char! --J.C.
\r
935 _fmemcpy(romFontsData.l,MK_FP(s,o+(w*c))/*ROM font location*/,w/*char size*/);
\r
936 modexDrawChar(page, x_draw/*for mode X planar use*/, t, col, bgcol, addrr);
\r
937 x_draw += 8; /* track X for edge of screen */
\r
938 addrr += 2; /* move 8 pixels over (2 x 4 planar pixels per byte) */
\r
942 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
944 word i, s, o, w, j, xp;
\r
946 word addr = (word) l;
\r
973 for(; *str != '\0'; str++)
\r
976 if((c=='\n'/* || c=="\
\r
977 "*/)/* || chw>=page->width*/)
\r
983 //load the letter 'A'
\r
989 MOV AL, c ; the letter
\r
992 ADD SI, AX ;the address of charcter
\r
1001 for(i=0; i<w; i++)
\r
1007 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1008 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1017 /* palette dump on display! */
\r
1018 void modexpdump(page_t *pee)
\r
1020 int mult=(QUADWH);
\r
1021 int palq=(mult)*TILEWH;
\r
1024 for(paly=0; paly<palq; paly+=mult){
\r
1025 for(palx=0; palx<palq; palx+=mult){
\r
1026 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
\r
1032 /////////////////////////////////////////////////////////////////////////////
\r
1034 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1035 // the Virtual screen. //
\r
1037 /////////////////////////////////////////////////////////////////////////////
\r
1038 void modexcls(page_t *page, byte color, byte *Where)
\r
1040 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1041 /* set map mask to all 4 planes */
\r
1042 outpw(SC_INDEX, 0xff02);
\r
1043 //_fmemset(VGA, color, 16000);
\r
1044 _fmemset(Where, color, page->width*(page->height)/4);
\r
1048 modexWaitBorder() {
\r
1049 while(inp(INPUT_STATUS_1) & 8) {
\r
1053 while(!(inp(INPUT_STATUS_1) & 8)) {
\r
1063 m = int10_getmode();
\r
1064 if ((rp=vga_state.vga_graphics_ram) != NULL && !(m <= 3 || m == 7)) {
\r
1065 unsigned int i,im;
\r
1067 im = (FP_SEG(vga_state.vga_graphics_ram_fence) - FP_SEG(vga_state.vga_graphics_ram));
\r
1068 if (im > 0xFFE) im = 0xFFE;
\r
1070 for (i=0;i < im;i++) vga_state.vga_graphics_ram[i] = 0;
\r
1072 else if ((ap=vga_state.vga_alpha_ram) != NULL) {
\r
1073 unsigned int i,im;
\r
1075 im = (FP_SEG(vga_state.vga_alpha_ram_fence) - FP_SEG(vga_state.vga_alpha_ram));
\r
1076 if (im > 0x7FE) im = 0x7FE;
\r
1077 im <<= 4 - 1; /* because ptr is type uint16_t */
\r
1078 for (i=0;i < im;i++) vga_state.vga_alpha_ram[i] = 0x0720;
\r
1081 printf("WARNING: bios cls no ptr\n");
\r