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+TILEWHD;
\r
176 page.height = p->sh+TILEWHD;
\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 = (sdiword)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 = (sdiword)result.width*result.height;
\r
228 void modexCalcVmemRemain(video_t *video)
\r
231 printf("\n\n 1st vmem_remain=%ld\n", video->vmem_remain);
\r
232 for(i=0; i<=video->num_of_pages-1; i++)
\r
234 video->vmem_remain-=video->page[i].pagesize;
\r
235 printf(" [%u], video->page[i].pagesize=%ld\n", i, video->page[i].pagesize);
\r
236 printf(" [%u], vmem_remain=%ld\n", i, video->vmem_remain);
\r
240 void modexHiganbanaPageSetup(video_t *video)
\r
242 video->vmem_remain=262144L;
\r
243 (video->page[0]) = modexDefaultPage(&(video->page[0])); video->num_of_pages++;
\r
244 //video->page[0].width += (TILEWHD); video->page[0].height += (TILEWHD);
\r
245 (video->page[1]) = modexNextPage(&(video->page[0])); video->num_of_pages++;
\r
246 (video->page[2]) = modexNextPageFlexibleSize(&(video->page[1]), video->page[0].width, video->page[0].sh-40); video->num_of_pages++;
\r
247 (video->page[3]) = modexNextPageFlexibleSize(&(video->page[2]), TILEWH, TILEWH); video->num_of_pages++;
\r
248 modexCalcVmemRemain(video);
\r
253 modexShowPage(page_t *page) {
\r
259 /* calculate offset */
\r
260 offset = (word) page->data;
\r
261 offset += page->dy * (page->width >> 2 );
\r
262 offset += page->dx >> 2;
\r
264 /* calculate crtcOffset according to virtual width */
\r
265 crtcOffset = page->width >> 3;
\r
267 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
268 low_address = LOW_ADDRESS | (offset << 8);
\r
270 /* wait for appropriate timing and then program CRTC */
\r
271 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
272 outpw(CRTC_INDEX, high_address);
\r
273 outpw(CRTC_INDEX, low_address);
\r
274 outp(CRTC_INDEX, 0x13);
\r
275 outp(CRTC_DATA, crtcOffset);
\r
277 /* wait for one retrace */
\r
278 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
280 /* do PEL panning here */
\r
281 outp(AC_INDEX, 0x33);
\r
282 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
287 modexPanPage(page_t *page, int dx, int dy) {
\r
294 modexSelectPlane(byte plane) {
\r
295 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
296 outp(SC_DATA, plane);
\r
301 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
302 word pageOff = (word) page->data;
\r
303 word xoff=x/4; /* xoffset that begins each row */
\r
304 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
305 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
306 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
307 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
308 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
309 byte left = lclip[x&0x03];
\r
310 byte right = rclip[(x+w)&0x03];
\r
312 /* handle the case which requires an extra group */
\r
313 if((x & 0x03) && !((x+w) & 0x03)) {
\r
318 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
320 MOV DI, poffset ; go to the first pixel
\r
321 MOV DX, SC_INDEX ; point to the map mask
\r
325 MOV AL, color ; get ready to write colors
\r
327 MOV CX, scanCount ; count the line
\r
328 MOV BL, AL ; remember color
\r
329 MOV AL, left ; do the left clip
\r
330 OUT DX, AL ; set the left clip
\r
331 MOV AL, BL ; restore color
\r
332 STOSB ; write the color
\r
334 JZ SCAN_DONE ; handle 1 group stuff
\r
336 ;-- write the main body of the scanline
\r
337 MOV BL, AL ; remember color
\r
338 MOV AL, 0x0f ; write to all pixels
\r
340 MOV AL, BL ; restore color
\r
341 REP STOSB ; write the color
\r
343 MOV BL, AL ; remeber color
\r
345 OUT DX, AL ; do the right clip
\r
346 MOV AL, BL ; restore color
\r
347 STOSB ; write pixel
\r
348 ADD DI, nextRow ; go to the next row
\r
354 /* moved to src/lib/modex16/16render.c */
\r
356 /* copy a region of video memory from one page to another.
\r
357 * It assumes that the left edge of the tile is the same on both
\r
358 * regions and the memory areas do not overlap.
\r
361 modexCopyPageRegion(page_t *dest, page_t *src,
\r
364 word width, word height)
\r
366 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
367 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
368 word scans = vga_state.vga_stride;
\r
369 word nextSrcRow = src->width/4 - scans - 1;
\r
370 word nextDestRow = dest->width/4 - scans - 1;
\r
371 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
372 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
373 byte left = lclip[sx&0x03];
\r
374 byte right = rclip[(sx+width)&0x03];
\r
377 MOV AX, SCREEN_SEG ; work in the vga space
\r
382 MOV DX, GC_INDEX ; turn off cpu bits
\r
386 MOV AX, SC_INDEX ; point to the mask register
\r
396 MOV CX, scans ; the number of latches
\r
398 MOV AL, left ; do the left column
\r
403 MOV AL, 0fh ; do the inner columns
\r
405 REP MOVSB ; copy the pixels
\r
407 MOV AL, right ; do the right column
\r
412 MOV AX, SI ; go the start of the next row
\r
413 ADD AX, nextSrcRow ;
\r
416 ADD AX, nextDestRow ;
\r
419 DEC height ; do the rest of the actions
\r
422 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
423 MOV AL, 0ffh ; none from latches
\r
429 /* fade and flash */
\r
431 modexFadeOn(word fade, byte *palette) {
\r
432 fadePalette(-fade, 64, 64/fade+1, palette);
\r
437 modexFadeOff(word fade, byte *palette) {
\r
438 fadePalette(fade, 0, 64/fade+1, palette);
\r
443 modexFlashOn(word fade, byte *palette) {
\r
444 fadePalette(fade, -64, 64/fade+1, palette);
\r
449 modexFlashOff(word fade, byte *palette) {
\r
450 fadePalette(-fade, 0, 64/fade+1, palette);
\r
455 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
459 /* handle the case where we just update */
\r
461 modexPalUpdate1(palette);
\r
465 while(iter > 0) { /* FadeLoop */
\r
466 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
467 tmppal[i] = palette[i] - dim;
\r
468 if(tmppal[i] > 127) {
\r
470 } else if(tmppal[i] > 63) {
\r
474 modexPalUpdate1(tmppal);
\r
481 /* save and load */
\r
483 modexPalSave(byte *palette) {
\r
486 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
487 for(i=0; i<PAL_SIZE; i++) {
\r
488 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
496 ptr = malloc(PAL_SIZE);
\r
498 /* handle errors */
\r
500 printf("Could not allocate palette.\n");
\r
509 modexLoadPalFile(byte *filename, byte **palette) {
\r
513 /* free the palette if it exists */
\r
518 /* allocate the new palette */
\r
519 *palette = modexNewPal();
\r
521 /* open the file */
\r
522 file = fopen(filename, "rb");
\r
524 printf("Could not open palette file: %s\n", filename);
\r
528 /* read the file */
\r
530 while(!feof(file)) {
\r
531 *ptr++ = fgetc(file);
\r
539 modexSavePalFile(char *filename, byte *pal) {
\r
543 /* open the file for writing */
\r
544 file = fopen(filename, "wb");
\r
546 printf("Could not open %s for writing\n", filename);
\r
550 /* write the data to the file */
\r
551 fwrite(pal, 1, PAL_SIZE, file);
\r
559 fadePalette(-1, 64, 1, tmppal);
\r
565 fadePalette(-1, -64, 1, tmppal);
\r
571 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
573 byte *p = bmp->palette;
\r
577 static word a[PAL_SIZE]; //palette array of change values!
\r
578 word z=0, aq=0, aa=0, pp=0;
\r
580 //modexWaitBorder();
\r
581 vga_wait_for_vsync();
\r
584 memset(a, -1, sizeof(a));
\r
585 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
595 // printf("q: %02d\n", (q));
\r
596 // printf("qq: %02d\n", (qq));
\r
597 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
598 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
600 if((*i)<PAL_SIZE/2 && w==0)
\r
602 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
604 //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
605 //____ 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
606 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
611 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
613 //printf("qp=%d\n", qp);
\r
614 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
615 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
616 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
617 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
621 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
623 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
624 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
625 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
628 //if(qp>0) printf("qp=%d\n", qp);
\r
629 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
631 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
632 vga_wait_for_vsync();
\r
633 if((*i)>=PAL_SIZE/2 && w==0)
\r
635 for(; (*i)<PAL_SIZE; (*i)++)
\r
637 //____ 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
638 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
643 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
645 //printf("qp=%d\n", qp);
\r
646 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
647 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
648 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
649 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
653 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
654 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
655 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
658 //printf(" (*i)=%d\n", (*i)/3);
\r
661 printf("\nqqqqqqqq\n\n");
\r
667 long bufSize = (bmp->width * bmp->height);
\r
669 //printf("1(*i)=%02d\n", (*i)/3);
\r
670 //printf("1z=%02d\n", z/3);
\r
671 modexchkcolor(bmp, &q, &a, &aa, &z, i);
\r
672 //printf("2(*i)=%02d\n", (*i)/3);
\r
673 //printf("2z=%02d\n", z/3);
\r
678 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
679 if(a[aq]==-1) aq++;
\r
680 else { aqoffset++; break; }
\r
682 //update the image data here!
\r
683 for(lq=0; lq<bufSize; lq++)
\r
687 use a[qp] instead of bmp->offset for this spot!
\r
692 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
695 //(offset/bmp->offset)*bmp->offset
\r
698 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
699 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
700 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
701 /*if(bmp->data[lq]+bmp->offset==aq)
\r
703 //printf("%02d", bmp->data[lq]);
\r
704 //printf("\n%02d\n", bmp->offset);
\r
705 printf("aq=%02d ", aq);
\r
706 printf("a[aq]=%02d ", a[aq]);
\r
707 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
708 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
709 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
710 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
711 // printf("_%d ", bmp->data[lq]);
\r
712 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
714 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
716 if(bmp->data[lq]+bmp->offset >= aq)
\r
718 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
719 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
721 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
724 //printf("%02d`", bmp->data[lq]);
\r
725 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
728 //printf(" aq=%02d\n", aq);
\r
729 //printf(" aa=%02d\n", aa);
\r
731 //update the palette~
\r
732 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
735 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
740 modexPalUpdate1(byte *p)
\r
743 //modexWaitBorder();
\r
744 vga_wait_for_vsync();
\r
745 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
746 for(i=0; i<PAL_SIZE/2; i++)
\r
748 outp(PAL_DATA_REG, p[i]);
\r
750 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
751 vga_wait_for_vsync();
\r
752 for(; i<PAL_SIZE; i++)
\r
754 outp(PAL_DATA_REG, p[(i)]);
\r
759 modexPalUpdate0(byte *p)
\r
762 //modexWaitBorder();
\r
763 vga_wait_for_vsync();
\r
764 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
765 for(i=0; i<PAL_SIZE/2; i++)
\r
767 outp(PAL_DATA_REG, rand());
\r
769 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
770 vga_wait_for_vsync();
\r
771 for(; i<PAL_SIZE; i++)
\r
773 outp(PAL_DATA_REG, rand());
\r
778 modexPalOverscan(byte *p, word col)
\r
780 //modexWaitBorder();
\r
781 vga_wait_for_vsync();
\r
782 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
783 outp(PAL_DATA_REG, col);
\r
787 //i want to make another vesion that checks the palette when the palette is being appened~
\r
788 void modexchkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
792 pal = modexNewPal();
\r
794 //printf("q: %02d\n", (*q));
\r
795 printf("chkcolor start~\n");
\r
796 printf("1 (*z): %d\n", (*z)/3);
\r
797 printf("1 (*i): %d\n", (*i)/3);
\r
798 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
799 printf("wwwwwwwwwwwwwwww\n");
\r
800 //check palette for dups
\r
801 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
803 //printf("\n z: %d\n", (*z));
\r
804 //printf(" q: %d\n", (*q));
\r
805 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
808 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
811 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
812 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
816 else for(zz=0; zz<(*q); zz+=3)
\r
818 //printf("zz: %02d\n", zz/3);
\r
821 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
825 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
826 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
829 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
831 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
832 // 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
833 // 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
834 // //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
835 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
840 planned features that i plan to implement~
\r
841 image that has values on the pallete list!
\r
843 no... wait.... no wwww
\r
845 //for(zzii=0; zzii<3; zzii++)
\r
847 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
848 a[(((*z)+(*q)))]=zz;
\r
850 (*aa)=(((*z)+(*q)));
\r
851 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
852 // printf("\n aa: %d\n\n", (*aa));
\r
853 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
854 // printf("wwwwwwwwwwwwwwww\n\n");
\r
858 printf("================\n");
\r
859 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
860 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
861 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
862 printf("================\n");
\r
864 //printf("[%d]", (zz+q));
\r
868 printf("wwwwwwwwwwwwwwww\n");
\r
869 printf("2 (*z): %d\n", (*z)/3);
\r
870 printf("2 (*i): %d\n", (*i)/3);
\r
871 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
872 printf("chkcolor end~\n");
\r
876 void modexputPixel(page_t *page, int x, int y, byte color)
\r
878 word pageOff = (word) page->data;
\r
879 /* Each address accesses four neighboring pixels, so set
\r
880 Write Plane Enable according to which pixel we want
\r
881 to modify. The plane is determined by the two least
\r
882 significant bits of the x-coordinate: */
\r
883 modexSelectPlane(PLANE(x));
\r
884 //outp(SC_INDEX, 0x02);
\r
885 //outp(SC_DATA, 0x01 << (x & 3));
\r
887 /* The offset of the pixel into the video segment is
\r
888 offset = (width * y + x) / 4, and write the given
\r
889 color to the plane we selected above. Heed the active
\r
890 page start selection. */
\r
891 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
895 byte modexgetPixel(page_t *page, int x, int y)
\r
897 word pageOff = (word) page->data;
\r
898 /* Select the plane from which we must read the pixel color: */
\r
899 outpw(GC_INDEX, 0x04);
\r
900 outpw(GC_INDEX+1, x & 3);
\r
902 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
906 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
910 word addr = (word) romFontsData.l;
\r
911 word addrq = (page->width/4) * y + (x / 4) + ((word)page->data);
\r
912 word addrr = addrq;
\r
917 w=romFonts[t].charSize;
\r
918 romFontsData.chw=0;
\r
920 for(; *str != '\0'; str++)
\r
926 romFontsData.chw = 0;
\r
927 addrq += (page->width / 4) * 8;
\r
933 // load the character into romFontsData.l
\r
934 // no need for inline assembly!
\r
935 // NTS: It might even be faster to just let the modexDrawChar point directly at ROM font than to copy per char! --J.C.
\r
936 _fmemcpy(romFontsData.l,MK_FP(s,o+(w*c))/*ROM font location*/,w/*char size*/);
\r
937 modexDrawChar(page, x_draw/*for mode X planar use*/, t, col, bgcol, addrr);
\r
938 x_draw += 8; /* track X for edge of screen */
\r
939 addrr += 2; /* move 8 pixels over (2 x 4 planar pixels per byte) */
\r
943 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
945 word i, s, o, w, j, xp;
\r
947 word addr = (word) l;
\r
974 for(; *str != '\0'; str++)
\r
977 if((c=='\n'/* || c=="\
\r
978 "*/)/* || chw>=page->width*/)
\r
984 //load the letter 'A'
\r
990 MOV AL, c ; the letter
\r
993 ADD SI, AX ;the address of charcter
\r
1002 for(i=0; i<w; i++)
\r
1008 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1009 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1018 /* palette dump on display! */
\r
1019 void modexpdump(page_t *pee)
\r
1021 int mult=(QUADWH);
\r
1022 int palq=(mult)*TILEWH;
\r
1025 for(paly=0; paly<palq; paly+=mult){
\r
1026 for(palx=0; palx<palq; palx+=mult){
\r
1027 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
\r
1033 /////////////////////////////////////////////////////////////////////////////
\r
1035 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1036 // the Virtual screen. //
\r
1038 /////////////////////////////////////////////////////////////////////////////
\r
1039 void modexcls(page_t *page, byte color, byte *Where)
\r
1041 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1042 /* set map mask to all 4 planes */
\r
1043 outpw(SC_INDEX, 0xff02);
\r
1044 //_fmemset(VGA, color, 16000);
\r
1045 _fmemset(Where, color, page->width*(page->height)/4);
\r
1049 modexWaitBorder() {
\r
1050 while(inp(INPUT_STATUS_1) & 8) {
\r
1054 while(!(inp(INPUT_STATUS_1) & 8)) {
\r
1064 m = int10_getmode();
\r
1065 if ((rp=vga_state.vga_graphics_ram) != NULL && !(m <= 3 || m == 7)) {
\r
1066 unsigned int i,im;
\r
1068 im = (FP_SEG(vga_state.vga_graphics_ram_fence) - FP_SEG(vga_state.vga_graphics_ram));
\r
1069 if (im > 0xFFE) im = 0xFFE;
\r
1071 for (i=0;i < im;i++) vga_state.vga_graphics_ram[i] = 0;
\r
1073 else if ((ap=vga_state.vga_alpha_ram) != NULL) {
\r
1074 unsigned int i,im;
\r
1076 im = (FP_SEG(vga_state.vga_alpha_ram_fence) - FP_SEG(vga_state.vga_alpha_ram));
\r
1077 if (im > 0x7FE) im = 0x7FE;
\r
1078 im <<= 4 - 1; /* because ptr is type uint16_t */
\r
1079 for (i=0;i < im;i++) vga_state.vga_alpha_ram[i] = 0x0720;
\r
1082 printf("WARNING: bios cls no ptr\n");
\r