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
158 gv->video.num_of_pages=0;
\r
163 /* VGAmodeX restores original mode and palette */
\r
164 vgaSetMode(TEXT_MODE);
\r
168 modexDefaultPage(page_t *p)
\r
172 /* default page values */
\r
174 //page.data = (byte far *)(vga_state.vga_graphics_ram);
\r
175 page.data = (vga_state.vga_graphics_ram);
\r
180 page.width = p->sw+TILEWHD;
\r
181 page.height = p->sh+TILEWHD;
\r
182 page.tw = page.sw/TILEWH;
\r
183 page.th = page.sh/TILEWH;
\r
184 page.tilesw=page.width/TILEWH;
\r
185 page.tilesh=page.height/TILEWH;
\r
186 page.tilemidposscreenx = page.tw/2;
\r
187 page.tilemidposscreeny = (page.th/2)+1;
\r
188 page.pagesize = (sdiword)page.width*page.height;
\r
194 /* returns the next page in contiguous memory
\r
195 * the next page will be the same size as p, by default
\r
198 modexNextPage(page_t *p) {
\r
201 result.data = p->data + (byte)(p->width/4)*p->height;
\r
204 result.width = p->width;
\r
205 result.height = p->height;
\r
208 result.tilesw = p->tilesw;
\r
209 result.tilesh = p->tilesh;
\r
210 result.id = p->id+1;
\r
211 result.pagesize = p->pagesize;
\r
216 //next page with defined dimentions~
\r
218 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
222 result.data = p->data + (byte)(p->width/4)*p->height; /* compute the offset */
\r
227 result.tw = result.sw/TILEWH;
\r
228 result.th = result.sh/TILEWH;
\r
229 result.tilesw=result.width/TILEWH;
\r
230 result.tilesh=result.height/TILEWH;
\r
231 result.id = p->id+1;
\r
232 result.pagesize = (sdiword)result.width*result.height;
\r
237 void modexCalcVmemRemain(video_t *video)
\r
240 //printf("\n\n 1st vmem_remain=%ld\n", video->vmem_remain);
\r
241 for(i=0; i<=video->num_of_pages-1; i++)
\r
243 video->vmem_remain-=video->page[i].pagesize;
\r
244 //printf(" [%u], video->page[i].pagesize=%ld\n", i, video->page[i].pagesize);
\r
245 //printf(" [%u], vmem_remain=%ld\n", i, video->vmem_remain);
\r
249 void modexHiganbanaPageSetup(video_t *video)
\r
251 video->vmem_remain=262144L;
\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
303 modexSelectPlane(byte plane) {
\r
304 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
305 outp(SC_DATA, plane);
\r
310 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
311 word pageOff = (word) page->data;
\r
312 word xoff=x/4; /* xoffset that begins each row */
\r
313 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
314 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
315 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
316 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
317 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
318 byte left = lclip[x&0x03];
\r
319 byte right = rclip[(x+w)&0x03];
\r
321 /* handle the case which requires an extra group */
\r
322 if((x & 0x03) && !((x+w) & 0x03)) {
\r
327 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
329 MOV DI, poffset ; go to the first pixel
\r
330 MOV DX, SC_INDEX ; point to the map mask
\r
334 MOV AL, color ; get ready to write colors
\r
336 MOV CX, scanCount ; count the line
\r
337 MOV BL, AL ; remember color
\r
338 MOV AL, left ; do the left clip
\r
339 OUT DX, AL ; set the left clip
\r
340 MOV AL, BL ; restore color
\r
341 STOSB ; write the color
\r
343 JZ SCAN_DONE ; handle 1 group stuff
\r
345 ;-- write the main body of the scanline
\r
346 MOV BL, AL ; remember color
\r
347 MOV AL, 0x0f ; write to all pixels
\r
349 MOV AL, BL ; restore color
\r
350 REP STOSB ; write the color
\r
352 MOV BL, AL ; remeber color
\r
354 OUT DX, AL ; do the right clip
\r
355 MOV AL, BL ; restore color
\r
356 STOSB ; write pixel
\r
357 ADD DI, nextRow ; go to the next row
\r
363 /* moved to src/lib/modex16/16render.c */
\r
365 /* copy a region of video memory from one page to another.
\r
366 * It assumes that the left edge of the tile is the same on both
\r
367 * regions and the memory areas do not overlap.
\r
370 modexCopyPageRegion(page_t *dest, page_t *src,
\r
373 word width, word height)
\r
375 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
376 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
377 word scans = vga_state.vga_stride;
\r
378 word nextSrcRow = src->width/4 - scans - 1;
\r
379 word nextDestRow = dest->width/4 - scans - 1;
\r
380 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
381 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
382 byte left = lclip[sx&0x03];
\r
383 byte right = rclip[(sx+width)&0x03];
\r
386 MOV AX, SCREEN_SEG ; work in the vga space
\r
391 MOV DX, GC_INDEX ; turn off cpu bits
\r
395 MOV AX, SC_INDEX ; point to the mask register
\r
405 MOV CX, scans ; the number of latches
\r
407 MOV AL, left ; do the left column
\r
412 MOV AL, 0fh ; do the inner columns
\r
414 REP MOVSB ; copy the pixels
\r
416 MOV AL, right ; do the right column
\r
421 MOV AX, SI ; go the start of the next row
\r
422 ADD AX, nextSrcRow ;
\r
425 ADD AX, nextDestRow ;
\r
428 DEC height ; do the rest of the actions
\r
431 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
432 MOV AL, 0ffh ; none from latches
\r
438 /* fade and flash */
\r
440 modexFadeOn(word fade, byte *palette) {
\r
441 fadePalette(-fade, 64, 64/fade+1, palette);
\r
446 modexFadeOff(word fade, byte *palette) {
\r
447 fadePalette(fade, 0, 64/fade+1, palette);
\r
452 modexFlashOn(word fade, byte *palette) {
\r
453 fadePalette(fade, -64, 64/fade+1, palette);
\r
458 modexFlashOff(word fade, byte *palette) {
\r
459 fadePalette(-fade, 0, 64/fade+1, palette);
\r
464 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
468 /* handle the case where we just update */
\r
470 modexPalUpdate1(palette);
\r
474 while(iter > 0) { /* FadeLoop */
\r
475 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
476 tmppal[i] = palette[i] - dim;
\r
477 if(tmppal[i] > 127) {
\r
479 } else if(tmppal[i] > 63) {
\r
483 modexPalUpdate1(tmppal);
\r
490 /* save and load */
\r
492 modexPalSave(byte *palette) {
\r
495 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
496 for(i=0; i<PAL_SIZE; i++) {
\r
497 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
505 ptr = malloc(PAL_SIZE);
\r
507 /* handle errors */
\r
509 printf("Could not allocate palette.\n");
\r
518 modexLoadPalFile(byte *filename, byte **palette) {
\r
522 /* free the palette if it exists */
\r
527 /* allocate the new palette */
\r
528 *palette = modexNewPal();
\r
530 /* open the file */
\r
531 file = fopen(filename, "rb");
\r
533 printf("Could not open palette file: %s\n", filename);
\r
537 /* read the file */
\r
539 while(!feof(file)) {
\r
540 *ptr++ = fgetc(file);
\r
548 modexSavePalFile(char *filename, byte *pal) {
\r
552 /* open the file for writing */
\r
553 file = fopen(filename, "wb");
\r
555 printf("Could not open %s for writing\n", filename);
\r
559 /* write the data to the file */
\r
560 fwrite(pal, 1, PAL_SIZE, file);
\r
568 fadePalette(-1, 64, 1, tmppal);
\r
574 fadePalette(-1, -64, 1, tmppal);
\r
580 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
582 byte *p = bmp->palette;
\r
586 static word a[PAL_SIZE]; //palette array of change values!
\r
587 word z=0, aq=0, aa=0, pp=0;
\r
589 //modexWaitBorder();
\r
590 vga_wait_for_vsync();
\r
593 memset(a, -1, sizeof(a));
\r
594 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
604 // printf("q: %02d\n", (q));
\r
605 // printf("qq: %02d\n", (qq));
\r
606 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
607 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
609 if((*i)<PAL_SIZE/2 && w==0)
\r
611 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
613 //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
614 //____ 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
615 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
620 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
622 //printf("qp=%d\n", qp);
\r
623 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
624 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
625 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
626 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
630 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
632 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
633 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
634 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
637 //if(qp>0) printf("qp=%d\n", qp);
\r
638 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
640 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
641 vga_wait_for_vsync();
\r
642 if((*i)>=PAL_SIZE/2 && w==0)
\r
644 for(; (*i)<PAL_SIZE; (*i)++)
\r
646 //____ 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
647 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
652 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
654 //printf("qp=%d\n", qp);
\r
655 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
656 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
657 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
658 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
662 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
663 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
664 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
667 //printf(" (*i)=%d\n", (*i)/3);
\r
670 printf("\nqqqqqqqq\n\n");
\r
676 long bufSize = (bmp->width * bmp->height);
\r
678 //printf("1(*i)=%02d\n", (*i)/3);
\r
679 //printf("1z=%02d\n", z/3);
\r
680 modexchkcolor(bmp, &q, &a, &aa, &z, i);
\r
681 //printf("2(*i)=%02d\n", (*i)/3);
\r
682 //printf("2z=%02d\n", z/3);
\r
687 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
688 if(a[aq]==-1) aq++;
\r
689 else { aqoffset++; break; }
\r
691 //update the image data here!
\r
692 for(lq=0; lq<bufSize; lq++)
\r
696 use a[qp] instead of bmp->offset for this spot!
\r
701 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
704 //(offset/bmp->offset)*bmp->offset
\r
707 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
708 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
709 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
710 /*if(bmp->data[lq]+bmp->offset==aq)
\r
712 //printf("%02d", bmp->data[lq]);
\r
713 //printf("\n%02d\n", bmp->offset);
\r
714 printf("aq=%02d ", aq);
\r
715 printf("a[aq]=%02d ", a[aq]);
\r
716 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
717 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
718 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
719 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
720 // printf("_%d ", bmp->data[lq]);
\r
721 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
723 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
725 if(bmp->data[lq]+bmp->offset >= aq)
\r
727 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
728 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
730 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
733 //printf("%02d`", bmp->data[lq]);
\r
734 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
737 //printf(" aq=%02d\n", aq);
\r
738 //printf(" aa=%02d\n", aa);
\r
740 //update the palette~
\r
741 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
744 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
749 modexPalUpdate1(byte *p)
\r
752 //modexWaitBorder();
\r
753 vga_wait_for_vsync();
\r
754 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
755 for(i=0; i<PAL_SIZE/2; i++)
\r
757 outp(PAL_DATA_REG, p[i]);
\r
759 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
760 vga_wait_for_vsync();
\r
761 for(; i<PAL_SIZE; i++)
\r
763 outp(PAL_DATA_REG, p[(i)]);
\r
768 modexPalUpdate0(byte *p)
\r
771 //modexWaitBorder();
\r
772 vga_wait_for_vsync();
\r
773 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
774 for(i=0; i<PAL_SIZE/2; i++)
\r
776 outp(PAL_DATA_REG, rand());
\r
778 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
779 vga_wait_for_vsync();
\r
780 for(; i<PAL_SIZE; i++)
\r
782 outp(PAL_DATA_REG, rand());
\r
787 modexPalOverscan(byte *p, word col)
\r
789 //modexWaitBorder();
\r
790 vga_wait_for_vsync();
\r
791 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
792 outp(PAL_DATA_REG, col);
\r
796 //i want to make another vesion that checks the palette when the palette is being appened~
\r
797 void modexchkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
801 pal = modexNewPal();
\r
803 //printf("q: %02d\n", (*q));
\r
804 printf("chkcolor start~\n");
\r
805 printf("1 (*z): %d\n", (*z)/3);
\r
806 printf("1 (*i): %d\n", (*i)/3);
\r
807 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
808 printf("wwwwwwwwwwwwwwww\n");
\r
809 //check palette for dups
\r
810 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
812 //printf("\n z: %d\n", (*z));
\r
813 //printf(" q: %d\n", (*q));
\r
814 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
817 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
820 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
821 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
825 else for(zz=0; zz<(*q); zz+=3)
\r
827 //printf("zz: %02d\n", zz/3);
\r
830 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
834 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
835 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
838 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
840 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
841 // 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
842 // 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
843 // //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
844 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
849 planned features that i plan to implement~
\r
850 image that has values on the pallete list!
\r
852 no... wait.... no wwww
\r
854 //for(zzii=0; zzii<3; zzii++)
\r
856 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
857 a[(((*z)+(*q)))]=zz;
\r
859 (*aa)=(((*z)+(*q)));
\r
860 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
861 // printf("\n aa: %d\n\n", (*aa));
\r
862 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
863 // printf("wwwwwwwwwwwwwwww\n\n");
\r
867 printf("================\n");
\r
868 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
869 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
870 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
871 printf("================\n");
\r
873 //printf("[%d]", (zz+q));
\r
877 printf("wwwwwwwwwwwwwwww\n");
\r
878 printf("2 (*z): %d\n", (*z)/3);
\r
879 printf("2 (*i): %d\n", (*i)/3);
\r
880 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
881 printf("chkcolor end~\n");
\r
885 void modexputPixel(page_t *page, int x, int y, byte color)
\r
887 word pageOff = (word) page->data;
\r
888 /* Each address accesses four neighboring pixels, so set
\r
889 Write Plane Enable according to which pixel we want
\r
890 to modify. The plane is determined by the two least
\r
891 significant bits of the x-coordinate: */
\r
892 modexSelectPlane(PLANE(x));
\r
893 //outp(SC_INDEX, 0x02);
\r
894 //outp(SC_DATA, 0x01 << (x & 3));
\r
896 /* The offset of the pixel into the video segment is
\r
897 offset = (width * y + x) / 4, and write the given
\r
898 color to the plane we selected above. Heed the active
\r
899 page start selection. */
\r
900 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
904 byte modexgetPixel(page_t *page, int x, int y)
\r
906 word pageOff = (word) page->data;
\r
907 /* Select the plane from which we must read the pixel color: */
\r
908 outpw(GC_INDEX, 0x04);
\r
909 outpw(GC_INDEX+1, x & 3);
\r
911 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
915 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
919 word addr = (word) romFontsData.l;
\r
920 word addrq = (page->width/4) * y + (x / 4) + ((word)page->data);
\r
921 word addrr = addrq;
\r
926 w=romFonts[t].charSize;
\r
927 romFontsData.chw=0;
\r
929 for(; *str != '\0'; str++)
\r
935 romFontsData.chw = 0;
\r
936 addrq += (page->width / 4) * 8;
\r
942 // load the character into romFontsData.l
\r
943 // no need for inline assembly!
\r
944 // NTS: It might even be faster to just let the modexDrawChar point directly at ROM font than to copy per char! --J.C.
\r
945 _fmemcpy(romFontsData.l,MK_FP(s,o+(w*c))/*ROM font location*/,w/*char size*/);
\r
946 modexDrawChar(page, x_draw/*for mode X planar use*/, t, col, bgcol, addrr);
\r
947 x_draw += 8; /* track X for edge of screen */
\r
948 addrr += 2; /* move 8 pixels over (2 x 4 planar pixels per byte) */
\r
952 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
954 word i, s, o, w, j, xp;
\r
956 word addr = (word) l;
\r
983 for(; *str != '\0'; str++)
\r
986 if((c=='\n'/* || c=="\
\r
987 "*/)/* || chw>=page->width*/)
\r
993 //load the letter 'A'
\r
999 MOV AL, c ; the letter
\r
1002 ADD SI, AX ;the address of charcter
\r
1011 for(i=0; i<w; i++)
\r
1017 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1018 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1027 /* palette dump on display! */
\r
1028 void modexpdump(page_t *pee)
\r
1030 int mult=(QUADWH);
\r
1031 int palq=(mult)*TILEWH;
\r
1034 for(paly=0; paly<palq; paly+=mult){
\r
1035 for(palx=0; palx<palq; palx+=mult){
\r
1036 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
\r
1042 /////////////////////////////////////////////////////////////////////////////
\r
1044 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1045 // the Virtual screen. //
\r
1047 /////////////////////////////////////////////////////////////////////////////
\r
1048 void modexcls(page_t *page, byte color, byte *Where)
\r
1050 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1051 /* set map mask to all 4 planes */
\r
1052 outpw(SC_INDEX, 0xff02);
\r
1053 //_fmemset(VGA, color, 16000);
\r
1054 _fmemset(Where, color, page->width*(page->height)/4);
\r
1058 modexWaitBorder() {
\r
1059 while(inp(INPUT_STATUS_1) & 8) {
\r
1063 while(!(inp(INPUT_STATUS_1) & 8)) {
\r
1073 m = int10_getmode();
\r
1074 if ((rp=vga_state.vga_graphics_ram) != NULL && !(m <= 3 || m == 7)) {
\r
1075 unsigned int i,im;
\r
1077 im = (FP_SEG(vga_state.vga_graphics_ram_fence) - FP_SEG(vga_state.vga_graphics_ram));
\r
1078 if (im > 0xFFE) im = 0xFFE;
\r
1080 for (i=0;i < im;i++) vga_state.vga_graphics_ram[i] = 0;
\r
1082 else if ((ap=vga_state.vga_alpha_ram) != NULL) {
\r
1083 unsigned int i,im;
\r
1085 im = (FP_SEG(vga_state.vga_alpha_ram_fence) - FP_SEG(vga_state.vga_alpha_ram));
\r
1086 if (im > 0x7FE) im = 0x7FE;
\r
1087 im <<= 4 - 1; /* because ptr is type uint16_t */
\r
1088 for (i=0;i < im;i++) vga_state.vga_alpha_ram[i] = 0x0720;
\r
1091 printf("WARNING: bios cls no ptr\n");
\r