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 += (TILEWH*2); video->page[0].height += (TILEWH*2);
\r
242 (video->page[1]) = modexNextPage(&(video->page[0])); video->num_of_pages++;
\r
243 (video->page[2]) = modexNextPage(&(video->page[1])); video->num_of_pages++;
\r
244 //(352*176)+1024 is the remaining amount of memory left wwww
\r
245 modexCalcVmemRemain(video);
\r
246 (video->page[3]) = modexNextPageFlexibleSize(&(video->page[2]), video->page[0].sw, 92); video->num_of_pages++;
\r
247 modexCalcVmemRemain(video);
\r
248 //gvar.video.page[2] = modexNextPage0(mv2.page, 320, 192); //(352*176)+1024 is the remaining amount of memory left wwww
\r
251 modexShowPage(page_t *page) {
\r
257 /* calculate offset */
\r
258 offset = (word) page->data;
\r
259 offset += page->dy * (page->width >> 2 );
\r
260 offset += page->dx >> 2;
\r
262 /* calculate crtcOffset according to virtual width */
\r
263 crtcOffset = page->width >> 3;
\r
265 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
266 low_address = LOW_ADDRESS | (offset << 8);
\r
268 /* wait for appropriate timing and then program CRTC */
\r
269 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
270 outpw(CRTC_INDEX, high_address);
\r
271 outpw(CRTC_INDEX, low_address);
\r
272 outp(CRTC_INDEX, 0x13);
\r
273 outp(CRTC_DATA, crtcOffset);
\r
275 /* wait for one retrace */
\r
276 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
278 /* do PEL panning here */
\r
279 outp(AC_INDEX, 0x33);
\r
280 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
285 modexPanPage(page_t *page, int dx, int dy) {
\r
292 modexSelectPlane(byte plane) {
\r
293 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
294 outp(SC_DATA, plane);
\r
299 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
300 word pageOff = (word) page->data;
\r
301 word xoff=x/4; /* xoffset that begins each row */
\r
302 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
303 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
304 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
305 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
306 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
307 byte left = lclip[x&0x03];
\r
308 byte right = rclip[(x+w)&0x03];
\r
310 /* handle the case which requires an extra group */
\r
311 if((x & 0x03) && !((x+w) & 0x03)) {
\r
316 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
318 MOV DI, poffset ; go to the first pixel
\r
319 MOV DX, SC_INDEX ; point to the map mask
\r
323 MOV AL, color ; get ready to write colors
\r
325 MOV CX, scanCount ; count the line
\r
326 MOV BL, AL ; remember color
\r
327 MOV AL, left ; do the left clip
\r
328 OUT DX, AL ; set the left clip
\r
329 MOV AL, BL ; restore color
\r
330 STOSB ; write the color
\r
332 JZ SCAN_DONE ; handle 1 group stuff
\r
334 ;-- write the main body of the scanline
\r
335 MOV BL, AL ; remember color
\r
336 MOV AL, 0x0f ; write to all pixels
\r
338 MOV AL, BL ; restore color
\r
339 REP STOSB ; write the color
\r
341 MOV BL, AL ; remeber color
\r
343 OUT DX, AL ; do the right clip
\r
344 MOV AL, BL ; restore color
\r
345 STOSB ; write pixel
\r
346 ADD DI, nextRow ; go to the next row
\r
352 /* moved to src/lib/modex16/16render.c */
\r
354 /* copy a region of video memory from one page to another.
\r
355 * It assumes that the left edge of the tile is the same on both
\r
356 * regions and the memory areas do not overlap.
\r
359 modexCopyPageRegion(page_t *dest, page_t *src,
\r
362 word width, word height)
\r
364 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
365 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
366 word scans = width/4;
\r
367 word nextSrcRow = src->width/4 - scans - 1;
\r
368 word nextDestRow = dest->width/4 - scans - 1;
\r
369 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
370 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
371 byte left = lclip[sx&0x03];
\r
372 byte right = rclip[(sx+width)&0x03];
\r
375 MOV AX, SCREEN_SEG ; work in the vga space
\r
380 MOV DX, GC_INDEX ; turn off cpu bits
\r
384 MOV AX, SC_INDEX ; point to the mask register
\r
394 MOV CX, scans ; the number of latches
\r
396 MOV AL, left ; do the left column
\r
401 MOV AL, 0fh ; do the inner columns
\r
403 REP MOVSB ; copy the pixels
\r
405 MOV AL, right ; do the right column
\r
410 MOV AX, SI ; go the start of the next row
\r
411 ADD AX, nextSrcRow ;
\r
414 ADD AX, nextDestRow ;
\r
417 DEC height ; do the rest of the actions
\r
420 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
421 MOV AL, 0ffh ; none from latches
\r
427 /* fade and flash */
\r
429 modexFadeOn(word fade, byte *palette) {
\r
430 fadePalette(-fade, 64, 64/fade+1, palette);
\r
435 modexFadeOff(word fade, byte *palette) {
\r
436 fadePalette(fade, 0, 64/fade+1, palette);
\r
441 modexFlashOn(word fade, byte *palette) {
\r
442 fadePalette(fade, -64, 64/fade+1, palette);
\r
447 modexFlashOff(word fade, byte *palette) {
\r
448 fadePalette(-fade, 0, 64/fade+1, palette);
\r
453 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
457 /* handle the case where we just update */
\r
459 modexPalUpdate1(palette);
\r
463 while(iter > 0) { /* FadeLoop */
\r
464 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
465 tmppal[i] = palette[i] - dim;
\r
466 if(tmppal[i] > 127) {
\r
468 } else if(tmppal[i] > 63) {
\r
472 modexPalUpdate1(tmppal);
\r
479 /* save and load */
\r
481 modexPalSave(byte *palette) {
\r
484 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
485 for(i=0; i<PAL_SIZE; i++) {
\r
486 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
494 ptr = malloc(PAL_SIZE);
\r
496 /* handle errors */
\r
498 printf("Could not allocate palette.\n");
\r
507 modexLoadPalFile(byte *filename, byte **palette) {
\r
511 /* free the palette if it exists */
\r
516 /* allocate the new palette */
\r
517 *palette = modexNewPal();
\r
519 /* open the file */
\r
520 file = fopen(filename, "rb");
\r
522 printf("Could not open palette file: %s\n", filename);
\r
526 /* read the file */
\r
528 while(!feof(file)) {
\r
529 *ptr++ = fgetc(file);
\r
537 modexSavePalFile(char *filename, byte *pal) {
\r
541 /* open the file for writing */
\r
542 file = fopen(filename, "wb");
\r
544 printf("Could not open %s for writing\n", filename);
\r
548 /* write the data to the file */
\r
549 fwrite(pal, 1, PAL_SIZE, file);
\r
557 fadePalette(-1, 64, 1, tmppal);
\r
563 fadePalette(-1, -64, 1, tmppal);
\r
569 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
571 byte *p = bmp->palette;
\r
575 static word a[PAL_SIZE]; //palette array of change values!
\r
576 word z=0, aq=0, aa=0, pp=0;
\r
578 //modexWaitBorder();
\r
579 vga_wait_for_vsync();
\r
582 memset(a, -1, sizeof(a));
\r
583 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
593 // printf("q: %02d\n", (q));
\r
594 // printf("qq: %02d\n", (qq));
\r
595 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
596 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
598 if((*i)<PAL_SIZE/2 && w==0)
\r
600 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
602 //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
603 //____ 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
604 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
609 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
611 //printf("qp=%d\n", qp);
\r
612 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
613 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
614 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
615 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
619 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
621 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
622 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
623 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
626 //if(qp>0) printf("qp=%d\n", qp);
\r
627 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
629 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
630 vga_wait_for_vsync();
\r
631 if((*i)>=PAL_SIZE/2 && w==0)
\r
633 for(; (*i)<PAL_SIZE; (*i)++)
\r
635 //____ 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
636 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
641 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
643 //printf("qp=%d\n", qp);
\r
644 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
645 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
646 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
647 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
651 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
652 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
653 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
656 //printf(" (*i)=%d\n", (*i)/3);
\r
659 printf("\nqqqqqqqq\n\n");
\r
665 long bufSize = (bmp->width * bmp->height);
\r
667 //printf("1(*i)=%02d\n", (*i)/3);
\r
668 //printf("1z=%02d\n", z/3);
\r
669 modexchkcolor(bmp, &q, &a, &aa, &z, i);
\r
670 //printf("2(*i)=%02d\n", (*i)/3);
\r
671 //printf("2z=%02d\n", z/3);
\r
676 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
677 if(a[aq]==-1) aq++;
\r
678 else { aqoffset++; break; }
\r
680 //update the image data here!
\r
681 for(lq=0; lq<bufSize; lq++)
\r
685 use a[qp] instead of bmp->offset for this spot!
\r
690 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
693 //(offset/bmp->offset)*bmp->offset
\r
696 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
697 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
698 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
699 /*if(bmp->data[lq]+bmp->offset==aq)
\r
701 //printf("%02d", bmp->data[lq]);
\r
702 //printf("\n%02d\n", bmp->offset);
\r
703 printf("aq=%02d ", aq);
\r
704 printf("a[aq]=%02d ", a[aq]);
\r
705 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
706 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
707 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
708 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
709 // printf("_%d ", bmp->data[lq]);
\r
710 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
712 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
714 if(bmp->data[lq]+bmp->offset >= aq)
\r
716 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
717 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
719 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
722 //printf("%02d`", bmp->data[lq]);
\r
723 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
726 //printf(" aq=%02d\n", aq);
\r
727 //printf(" aa=%02d\n", aa);
\r
729 //update the palette~
\r
730 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
733 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
738 modexPalUpdate1(byte *p)
\r
741 //modexWaitBorder();
\r
742 vga_wait_for_vsync();
\r
743 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
744 for(i=0; i<PAL_SIZE/2; i++)
\r
746 outp(PAL_DATA_REG, p[i]);
\r
748 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
749 vga_wait_for_vsync();
\r
750 for(; i<PAL_SIZE; i++)
\r
752 outp(PAL_DATA_REG, p[(i)]);
\r
757 modexPalUpdate0(byte *p)
\r
760 //modexWaitBorder();
\r
761 vga_wait_for_vsync();
\r
762 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
763 for(i=0; i<PAL_SIZE/2; i++)
\r
765 outp(PAL_DATA_REG, rand());
\r
767 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
768 vga_wait_for_vsync();
\r
769 for(; i<PAL_SIZE; i++)
\r
771 outp(PAL_DATA_REG, rand());
\r
776 modexPalOverscan(byte *p, word col)
\r
778 //modexWaitBorder();
\r
779 vga_wait_for_vsync();
\r
780 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
781 outp(PAL_DATA_REG, col);
\r
785 //i want to make another vesion that checks the palette when the palette is being appened~
\r
786 void modexchkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
790 pal = modexNewPal();
\r
792 //printf("q: %02d\n", (*q));
\r
793 printf("chkcolor start~\n");
\r
794 printf("1 (*z): %d\n", (*z)/3);
\r
795 printf("1 (*i): %d\n", (*i)/3);
\r
796 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
797 printf("wwwwwwwwwwwwwwww\n");
\r
798 //check palette for dups
\r
799 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
801 //printf("\n z: %d\n", (*z));
\r
802 //printf(" q: %d\n", (*q));
\r
803 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
806 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
809 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
810 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
814 else for(zz=0; zz<(*q); zz+=3)
\r
816 //printf("zz: %02d\n", zz/3);
\r
819 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
823 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
824 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
827 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
829 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
830 // 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
831 // 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
832 // //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
833 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
838 planned features that i plan to implement~
\r
839 image that has values on the pallete list!
\r
841 no... wait.... no wwww
\r
843 //for(zzii=0; zzii<3; zzii++)
\r
845 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
846 a[(((*z)+(*q)))]=zz;
\r
848 (*aa)=(((*z)+(*q)));
\r
849 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
850 // printf("\n aa: %d\n\n", (*aa));
\r
851 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
852 // printf("wwwwwwwwwwwwwwww\n\n");
\r
856 printf("================\n");
\r
857 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
858 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
859 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
860 printf("================\n");
\r
862 //printf("[%d]", (zz+q));
\r
866 printf("wwwwwwwwwwwwwwww\n");
\r
867 printf("2 (*z): %d\n", (*z)/3);
\r
868 printf("2 (*i): %d\n", (*i)/3);
\r
869 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
870 printf("chkcolor end~\n");
\r
874 void modexputPixel(page_t *page, int x, int y, byte color)
\r
876 word pageOff = (word) page->data;
\r
877 /* Each address accesses four neighboring pixels, so set
\r
878 Write Plane Enable according to which pixel we want
\r
879 to modify. The plane is determined by the two least
\r
880 significant bits of the x-coordinate: */
\r
881 modexSelectPlane(PLANE(x));
\r
882 //outp(SC_INDEX, 0x02);
\r
883 //outp(SC_DATA, 0x01 << (x & 3));
\r
885 /* The offset of the pixel into the video segment is
\r
886 offset = (width * y + x) / 4, and write the given
\r
887 color to the plane we selected above. Heed the active
\r
888 page start selection. */
\r
889 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
893 byte modexgetPixel(page_t *page, int x, int y)
\r
895 word pageOff = (word) page->data;
\r
896 /* Select the plane from which we must read the pixel color: */
\r
897 outpw(GC_INDEX, 0x04);
\r
898 outpw(GC_INDEX+1, x & 3);
\r
900 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
904 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
908 word addr = (word) romFontsData.l;
\r
909 word addrq = (page->width/4) * y + (x / 4) + ((word)page->data);
\r
910 word addrr = addrq;
\r
915 w=romFonts[t].charSize;
\r
916 romFontsData.chw=0;
\r
918 for(; *str != '\0'; str++)
\r
924 romFontsData.chw = 0;
\r
925 addrq += (page->width / 4) * 8;
\r
931 // load the character into romFontsData.l
\r
932 // no need for inline assembly!
\r
933 // NTS: It might even be faster to just let the modexDrawChar point directly at ROM font than to copy per char! --J.C.
\r
934 _fmemcpy(romFontsData.l,MK_FP(s,o+(w*c))/*ROM font location*/,w/*char size*/);
\r
935 modexDrawChar(page, x_draw/*for mode X planar use*/, t, col, bgcol, addrr);
\r
936 x_draw += 8; /* track X for edge of screen */
\r
937 addrr += 2; /* move 8 pixels over (2 x 4 planar pixels per byte) */
\r
941 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
943 word i, s, o, w, j, xp;
\r
945 word addr = (word) l;
\r
972 for(; *str != '\0'; str++)
\r
975 if((c=='\n'/* || c=="\
\r
976 "*/)/* || chw>=page->width*/)
\r
982 //load the letter 'A'
\r
988 MOV AL, c ; the letter
\r
991 ADD SI, AX ;the address of charcter
\r
1000 for(i=0; i<w; i++)
\r
1006 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1007 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1016 /* palette dump on display! */
\r
1017 void modexpdump(page_t *pee)
\r
1019 int mult=(QUADWH);
\r
1020 int palq=(mult)*TILEWH;
\r
1023 for(paly=0; paly<palq; paly+=mult){
\r
1024 for(palx=0; palx<palq; palx+=mult){
\r
1025 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
\r
1031 /////////////////////////////////////////////////////////////////////////////
\r
1033 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1034 // the Virtual screen. //
\r
1036 /////////////////////////////////////////////////////////////////////////////
\r
1037 void modexcls(page_t *page, byte color, byte *Where)
\r
1039 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1040 /* set map mask to all 4 planes */
\r
1041 outpw(SC_INDEX, 0xff02);
\r
1042 //_fmemset(VGA, color, 16000);
\r
1043 _fmemset(Where, color, page->width*(page->height)/4);
\r
1047 modexWaitBorder() {
\r
1048 while(inp(INPUT_STATUS_1) & 8) {
\r
1052 while(!(inp(INPUT_STATUS_1) & 8)) {
\r
1062 m = int10_getmode();
\r
1063 if ((rp=vga_state.vga_graphics_ram) != NULL && !(m <= 3 || m == 7)) {
\r
1064 unsigned int i,im;
\r
1066 im = (FP_SEG(vga_state.vga_graphics_ram_fence) - FP_SEG(vga_state.vga_graphics_ram));
\r
1067 if (im > 0xFFE) im = 0xFFE;
\r
1069 for (i=0;i < im;i++) vga_state.vga_graphics_ram[i] = 0;
\r
1071 else if ((ap=vga_state.vga_alpha_ram) != NULL) {
\r
1072 unsigned int i,im;
\r
1074 im = (FP_SEG(vga_state.vga_alpha_ram_fence) - FP_SEG(vga_state.vga_alpha_ram));
\r
1075 if (im > 0x7FE) im = 0x7FE;
\r
1076 im <<= 4 - 1; /* because ptr is type uint16_t */
\r
1077 for (i=0;i < im;i++) vga_state.vga_alpha_ram[i] = 0x0720;
\r
1080 printf("WARNING: bios cls no ptr\n");
\r