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 /*for(i=0; i<CRTParmCount; i++) {
\r
96 outpw(CRTC_INDEX, ModeX_320x240regs[i]);
\r
98 /* width and height */
\r
99 gv->video.page[0].sw = vga_state.vga_width = 320; // VGA lib currently does not update this
\r
100 gv->video.page[0].sh = vga_state.vga_height = 240; // VGA lib currently does not update this
\r
101 /* virtual width and height. match screen, at first */
\r
102 gv->video.page[0].height = gv->video.page[0].sh;
\r
103 gv->video.page[0].width = gv->video.page[0].sw;
\r
105 // mode X BYTE mode
\r
108 // 320x240 mode 60Hz
\r
109 cm.horizontal_total=0x5f + 5; /* CRTC[0] -5 */
\r
110 cm.horizontal_display_end=0x4f + 1; /* CRTC[1] -1 */
\r
111 cm.horizontal_blank_start=0x50 + 1; /* CRTC[2] */
\r
112 cm.horizontal_blank_end=0x82 + 1; /* CRTC[3] bit 0-4 & CRTC[5] bit 7 */
\r
113 cm.horizontal_start_retrace=0x54;/* CRTC[4] */
\r
114 cm.horizontal_end_retrace=0x80; /* CRTC[5] bit 0-4 */
\r
115 //cm.horizontal_start_delay_after_total=0x3e; /* CRTC[3] bit 5-6 */
\r
116 //cm.horizontal_start_delay_after_retrace=0x41; /* CRTC[5] bit 5-6 */
\r
117 cm.vertical_total = 0x20D + 2;
\r
118 cm.vertical_start_retrace = 0x1EA;
\r
119 cm.vertical_end_retrace = 0x1EC;
\r
120 cm.vertical_display_end = 480;
\r
121 cm.vertical_blank_start = 0x1E7 + 1;
\r
122 cm.vertical_blank_end = 0x206 + 1;
\r
123 cm.clock_select = 0; /* misc register = 0xE3 25MHz */
\r
126 cm.offset = (vga_state.vga_width / (4 * 2)); // 320 wide (40 x 4 pixel groups x 2)
\r
128 case 2: // TODO: 160x120 according to ModeX_160x120regs
\r
130 case 3: // TODO: 160x120 according to ModeX_320x200regs
\r
132 case 4: // TODO: 160x120 according to ModeX_192x144regs
\r
134 case 5: // TODO: 160x120 according to ModeX_256x192regs
\r
140 vga_state.vga_stride = cm.offset * 2;
\r
141 vga_write_crtc_mode(&cm,0);
\r
143 /* clear video memory */
\r
147 /* clear video memory */
\r
148 dword far*ptr=(dword far*)vga_state.vga_graphics_ram;//VGA; /* used for faster screen clearing */
\r
149 vga_write_sequencer(2/*map mask register*/,0xf/*all 4 planes*/);
\r
150 for(i = 0;i < 0x4000; i++) ptr[i] = 0x0000; // 0x4000 x dword = 64KB
\r
155 // gv->video.page[0].tw = gv->video.page[0].sw/TILEWH;
\r
156 // gv->video.page[0].th = gv->video.page[0].sh/TILEWH;
\r
158 //TODO MAKE FLEXIBLE~
\r
159 // gv->video.page[0].tilemidposscreenx = gv->video.page[0].tilesw;
\r
160 // gv->video.page[0].tilemidposscreeny = (gv->video.page[0].tilesh/2)+1;
\r
165 /* VGAmodeX restores original mode and palette */
\r
166 vgaSetMode(TEXT_MODE);
\r
170 modexDefaultPage(page_t *p)
\r
174 /* default page values */
\r
176 //page.data = (byte far *)(vga_state.vga_graphics_ram);
\r
177 page.data = (vga_state.vga_graphics_ram);
\r
182 page.width = p->sw+TILEWHD;
\r
183 page.height = p->sh+TILEWHD;
\r
184 page.tw = page.sw/TILEWH;
\r
185 page.th = page.sh/TILEWH;
\r
186 page.tilesw=page.width/TILEWH;
\r
187 page.tilesh=page.height/TILEWH;
\r
188 page.tilemidposscreenx = page.tw/2;
\r
189 page.tilemidposscreeny = (page.th/2)+1;
\r
190 page.pagesize = (sdiword)(page.width/4)*page.height;
\r
196 /* returns the next page in contiguous memory
\r
197 * the next page will be the same size as p, by default
\r
200 modexNextPage(page_t *p) {
\r
203 result.data = p->data + (p->pagesize);
\r
206 result.width = p->width;
\r
207 result.height = p->height;
\r
210 result.tilesw = p->tilesw;
\r
211 result.tilesh = p->tilesh;
\r
212 result.id = p->id+1;
\r
213 result.pagesize = p->pagesize;
\r
218 //next page with defined dimentions~
\r
220 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
224 result.data = p->data + (p->pagesize); /* compute the offset */
\r
229 result.tw = result.sw/TILEWH;
\r
230 result.th = result.sh/TILEWH;
\r
231 result.tilesw=result.width/TILEWH;
\r
232 result.tilesh=result.height/TILEWH;
\r
233 result.id = p->id+1;
\r
234 result.pagesize = (sdiword)(result.width/4)*result.height;
\r
239 void modexCalcVmemRemain(video_t *video)
\r
242 //printf("\n\n 1st vmem_remain=%ld\n", video->vmem_remain);
\r
243 for(i=0; i<=video->num_of_pages-1; i++)
\r
245 video->vmem_remain-=video->page[i].pagesize;
\r
246 //printf(" [%u], video->page[i].pagesize=%ld\n", i, video->page[i].pagesize);
\r
247 //printf(" [%u], vmem_remain=%ld\n", i, video->vmem_remain);
\r
251 void modexHiganbanaPageSetup(video_t *video)
\r
253 video->vmem_remain=262144L;
\r
254 video->num_of_pages=0;
\r
255 (video->page[0]) = modexDefaultPage(&(video->page[0])); video->num_of_pages++;
\r
256 //video->page[0].width += (TILEWHD); video->page[0].height += (TILEWHD);
\r
257 (video->page[1]) = modexNextPage(&(video->page[0])); video->num_of_pages++;
\r
258 //(video->page[2]) = modexNextPageFlexibleSize(&(video->page[1]), video->page[0].width, video->page[0].sh-40); video->num_of_pages++;
\r
259 //(video->page[3]) = modexNextPageFlexibleSize(&(video->page[2]), TILEWH, TILEWH); video->num_of_pages++;
\r
260 modexCalcVmemRemain(video);
\r
265 modexShowPage(page_t *page) {
\r
271 /* calculate offset */
\r
272 offset = (word) page->data;
\r
273 offset += page->dy * (page->width >> 2 );
\r
274 offset += page->dx >> 2;
\r
276 /* calculate crtcOffset according to virtual width */
\r
277 crtcOffset = page->width >> 3;
\r
279 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
280 low_address = LOW_ADDRESS | (offset << 8);
\r
282 /* wait for appropriate timing and then program CRTC */
\r
283 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
284 outpw(CRTC_INDEX, high_address);
\r
285 outpw(CRTC_INDEX, low_address);
\r
286 outp(CRTC_INDEX, 0x13);
\r
287 outp(CRTC_DATA, crtcOffset);
\r
289 /* wait for one retrace */
\r
290 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
292 /* do PEL panning here */
\r
293 outp(AC_INDEX, 0x33);
\r
294 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
298 modexPanPage(page_t *page, int dx, int dy) {
\r
304 modexSelectPlane(byte plane) {
\r
305 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
306 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
335 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
337 MOV DI, poffset ; go to the first pixel
\r
338 MOV DX, SC_INDEX ; point to the map mask
\r
342 MOV AL, color ; get ready to write colors
\r
344 MOV CX, scanCount ; count the line
\r
345 MOV BL, AL ; remember color
\r
346 MOV AL, left ; do the left clip
\r
347 OUT DX, AL ; set the left clip
\r
348 MOV AL, BL ; restore color
\r
349 STOSB ; write the color
\r
351 JZ SCAN_DONE ; handle 1 group stuff
\r
353 ;-- write the main body of the scanline
\r
354 MOV BL, AL ; remember color
\r
355 MOV AL, 0x0f ; write to all pixels
\r
357 MOV AL, BL ; restore color
\r
358 REP STOSB ; write the color
\r
360 MOV BL, AL ; remeber color
\r
362 OUT DX, AL ; do the right clip
\r
363 MOV AL, BL ; restore color
\r
364 STOSB ; write pixel
\r
365 ADD DI, nextRow ; go to the next row
\r
379 /* moved to src/lib/modex16/16render.c */
\r
381 /* copy a region of video memory from one page to another.
\r
382 * It assumes that the left edge of the tile is the same on both
\r
383 * regions and the memory areas do not overlap.
\r
386 modexCopyPageRegion(page_t *dest, page_t *src,
\r
389 word width, word height)
\r
391 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
392 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
393 word scans = vga_state.vga_stride;
\r
394 word nextSrcRow = src->width/4 - scans - 1;
\r
395 word nextDestRow = dest->width/4 - scans - 1;
\r
396 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
397 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
398 byte left = lclip[sx&0x03];
\r
399 byte right = rclip[(sx+width)&0x03];
\r
411 MOV AX, SCREEN_SEG ; work in the vga space
\r
416 MOV DX, GC_INDEX ; turn off cpu bits
\r
420 MOV AX, SC_INDEX ; point to the mask register
\r
430 MOV CX, scans ; the number of latches
\r
432 MOV AL, left ; do the left column
\r
437 MOV AL, 0fh ; do the inner columns
\r
439 REP MOVSB ; copy the pixels
\r
441 MOV AL, right ; do the right column
\r
446 MOV AX, SI ; go the start of the next row
\r
447 ADD AX, nextSrcRow ;
\r
450 ADD AX, nextDestRow ;
\r
453 DEC height ; do the rest of the actions
\r
456 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
457 MOV AL, 0ffh ; none from latches
\r
472 /* fade and flash */
\r
474 modexFadeOn(word fade, byte *palette) {
\r
475 fadePalette(-fade, 64, 64/fade+1, palette);
\r
480 modexFadeOff(word fade, byte *palette) {
\r
481 fadePalette(fade, 0, 64/fade+1, palette);
\r
486 modexFlashOn(word fade, byte *palette) {
\r
487 fadePalette(fade, -64, 64/fade+1, palette);
\r
492 modexFlashOff(word fade, byte *palette) {
\r
493 fadePalette(-fade, 0, 64/fade+1, palette);
\r
498 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
502 /* handle the case where we just update */
\r
504 modexPalUpdate1(palette);
\r
508 while(iter > 0) { /* FadeLoop */
\r
509 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
510 tmppal[i] = palette[i] - dim;
\r
511 if(tmppal[i] > 127) {
\r
513 } else if(tmppal[i] > 63) {
\r
517 modexPalUpdate1(tmppal);
\r
524 /* save and load */
\r
526 modexPalSave(byte *palette) {
\r
529 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
530 for(i=0; i<PAL_SIZE; i++) {
\r
531 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
539 ptr = malloc(PAL_SIZE);
\r
541 /* handle errors */
\r
543 printf("Could not allocate palette.\n");
\r
552 modexLoadPalFile(byte *filename, byte **palette) {
\r
556 /* free the palette if it exists */
\r
561 /* allocate the new palette */
\r
562 *palette = modexNewPal();
\r
564 /* open the file */
\r
565 file = fopen(filename, "rb");
\r
567 printf("Could not open palette file: %s\n", filename);
\r
571 /* read the file */
\r
573 while(!feof(file)) {
\r
574 *ptr++ = fgetc(file);
\r
582 modexSavePalFile(char *filename, byte *pal) {
\r
586 /* open the file for writing */
\r
587 file = fopen(filename, "wb");
\r
589 printf("Could not open %s for writing\n", filename);
\r
593 /* write the data to the file */
\r
594 fwrite(pal, 1, PAL_SIZE, file);
\r
602 fadePalette(-1, 64, 1, tmppal);
\r
608 fadePalette(-1, -64, 1, tmppal);
\r
614 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
616 byte *p = bmp->palette;
\r
620 static word a[PAL_SIZE]; //palette array of change values!
\r
621 word z=0, aq=0, aa=0, pp=0;
\r
623 //modexWaitBorder();
\r
624 vga_wait_for_vsync();
\r
627 memset(a, -1, sizeof(a));
\r
628 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
638 // printf("q: %02d\n", (q));
\r
639 // printf("qq: %02d\n", (qq));
\r
640 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
641 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
643 if((*i)<PAL_SIZE/2 && w==0)
\r
645 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
647 //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
648 //____ 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
649 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
654 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
656 //printf("qp=%d\n", qp);
\r
657 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
658 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
659 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
660 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
664 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
666 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
667 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
668 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
671 //if(qp>0) printf("qp=%d\n", qp);
\r
672 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
674 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
675 vga_wait_for_vsync();
\r
676 if((*i)>=PAL_SIZE/2 && w==0)
\r
678 for(; (*i)<PAL_SIZE; (*i)++)
\r
680 //____ 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
681 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
686 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
688 //printf("qp=%d\n", qp);
\r
689 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
690 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
691 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
692 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
696 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
697 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
698 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
701 //printf(" (*i)=%d\n", (*i)/3);
\r
704 printf("\nqqqqqqqq\n\n");
\r
710 long bufSize = (bmp->width * bmp->height);
\r
712 //printf("1(*i)=%02d\n", (*i)/3);
\r
713 //printf("1z=%02d\n", z/3);
\r
714 modexchkcolor(bmp, &q, &a, &aa, &z, i);
\r
715 //printf("2(*i)=%02d\n", (*i)/3);
\r
716 //printf("2z=%02d\n", z/3);
\r
721 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
722 if(a[aq]==-1) aq++;
\r
723 else { aqoffset++; break; }
\r
725 //update the image data here!
\r
726 for(lq=0; lq<bufSize; lq++)
\r
730 use a[qp] instead of bmp->offset for this spot!
\r
735 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
738 //(offset/bmp->offset)*bmp->offset
\r
741 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
742 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
743 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
744 /*if(bmp->data[lq]+bmp->offset==aq)
\r
746 //printf("%02d", bmp->data[lq]);
\r
747 //printf("\n%02d\n", bmp->offset);
\r
748 printf("aq=%02d ", aq);
\r
749 printf("a[aq]=%02d ", a[aq]);
\r
750 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
751 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
752 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
753 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
754 // printf("_%d ", bmp->data[lq]);
\r
755 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
757 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
759 if(bmp->data[lq]+bmp->offset >= aq)
\r
761 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
762 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
764 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
767 //printf("%02d`", bmp->data[lq]);
\r
768 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
771 //printf(" aq=%02d\n", aq);
\r
772 //printf(" aa=%02d\n", aa);
\r
774 //update the palette~
\r
775 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
778 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
783 modexPalUpdate1(byte *p)
\r
786 //modexWaitBorder();
\r
787 vga_wait_for_vsync();
\r
788 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
789 for(i=0; i<PAL_SIZE/2; i++)
\r
791 outp(PAL_DATA_REG, p[i]);
\r
793 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
794 vga_wait_for_vsync();
\r
795 for(; i<PAL_SIZE; i++)
\r
797 outp(PAL_DATA_REG, p[(i)]);
\r
802 modexPalUpdate0(byte *p)
\r
805 //modexWaitBorder();
\r
806 vga_wait_for_vsync();
\r
807 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
808 for(i=0; i<PAL_SIZE/2; i++)
\r
810 outp(PAL_DATA_REG, rand());
\r
812 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
813 vga_wait_for_vsync();
\r
814 for(; i<PAL_SIZE; i++)
\r
816 outp(PAL_DATA_REG, rand());
\r
821 modexPalOverscan(byte *p, word col)
\r
823 //modexWaitBorder();
\r
824 vga_wait_for_vsync();
\r
825 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
826 outp(PAL_DATA_REG, col);
\r
830 //i want to make another vesion that checks the palette when the palette is being appened~
\r
831 void modexchkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
835 pal = modexNewPal();
\r
837 //printf("q: %02d\n", (*q));
\r
838 printf("chkcolor start~\n");
\r
839 printf("1 (*z): %d\n", (*z)/3);
\r
840 printf("1 (*i): %d\n", (*i)/3);
\r
841 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
842 printf("wwwwwwwwwwwwwwww\n");
\r
843 //check palette for dups
\r
844 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
846 //printf("\n z: %d\n", (*z));
\r
847 //printf(" q: %d\n", (*q));
\r
848 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
851 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
854 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
855 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
859 else for(zz=0; zz<(*q); zz+=3)
\r
861 //printf("zz: %02d\n", zz/3);
\r
864 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
868 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
869 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
872 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
874 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
875 // 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
876 // 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
877 // //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
878 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
883 planned features that i plan to implement~
\r
884 image that has values on the pallete list!
\r
886 no... wait.... no wwww
\r
888 //for(zzii=0; zzii<3; zzii++)
\r
890 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
891 a[(((*z)+(*q)))]=zz;
\r
893 (*aa)=(((*z)+(*q)));
\r
894 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
895 // printf("\n aa: %d\n\n", (*aa));
\r
896 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
897 // printf("wwwwwwwwwwwwwwww\n\n");
\r
901 printf("================\n");
\r
902 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
903 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
904 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
905 printf("================\n");
\r
907 //printf("[%d]", (zz+q));
\r
911 printf("wwwwwwwwwwwwwwww\n");
\r
912 printf("2 (*z): %d\n", (*z)/3);
\r
913 printf("2 (*i): %d\n", (*i)/3);
\r
914 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
915 printf("chkcolor end~\n");
\r
919 void modexputPixel(page_t *page, int x, int y, byte color)
\r
921 word pageOff = (word) page->data;
\r
922 /* Each address accesses four neighboring pixels, so set
\r
923 Write Plane Enable according to which pixel we want
\r
924 to modify. The plane is determined by the two least
\r
925 significant bits of the x-coordinate: */
\r
926 modexSelectPlane(PLANE(x));
\r
927 //outp(SC_INDEX, 0x02);
\r
928 //outp(SC_DATA, 0x01 << (x & 3));
\r
930 /* The offset of the pixel into the video segment is
\r
931 offset = (width * y + x) / 4, and write the given
\r
932 color to the plane we selected above. Heed the active
\r
933 page start selection. */
\r
934 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
938 byte modexgetPixel(page_t *page, int x, int y)
\r
940 word pageOff = (word) page->data;
\r
941 /* Select the plane from which we must read the pixel color: */
\r
942 outpw(GC_INDEX, 0x04);
\r
943 outpw(GC_INDEX+1, x & 3);
\r
945 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
949 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
953 word addr = (word) romFontsData.l;
\r
954 word addrq = (page->width/4) * y + (x / 4) + ((word)page->data);
\r
955 word addrr = addrq;
\r
960 w=romFonts[t].charSize;
\r
961 romFontsData.chw=0;
\r
963 for(; *str != '\0'; str++)
\r
969 romFontsData.chw = 0;
\r
970 addrq += (page->width / 4) * 8;
\r
976 // load the character into romFontsData.l
\r
977 // no need for inline assembly!
\r
978 // NTS: It might even be faster to just let the modexDrawChar point directly at ROM font than to copy per char! --J.C.
\r
979 _fmemcpy(romFontsData.l,MK_FP(s,o+(w*c))/*ROM font location*/,w/*char size*/);
\r
980 modexDrawChar(page, x_draw/*for mode X planar use*/, t, col, bgcol, addrr);
\r
981 x_draw += 8; /* track X for edge of screen */
\r
982 addrr += 2; /* move 8 pixels over (2 x 4 planar pixels per byte) */
\r
986 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
988 word i, s, o, w, j, xp;
\r
990 word addr = (word) l;
\r
1014 s=romFonts[t].seg;
\r
1015 o=romFonts[t].off;
\r
1017 for(; *str != '\0'; str++)
\r
1020 if((c=='\n'/* || c=="\
\r
1021 "*/)/* || chw>=page->width*/)
\r
1027 //load the letter 'A'
\r
1042 MOV AL, c ; the letter
\r
1045 ADD SI, AX ;the address of charcter
\r
1063 for(i=0; i<w; i++)
\r
1069 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1070 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1079 /* palette dump on display! */
\r
1080 void modexpdump(page_t *pee)
\r
1082 int mult=(QUADWH);
\r
1083 int palq=(mult)*TILEWH;
\r
1086 for(paly=0; paly<palq; paly+=mult){
\r
1087 for(palx=0; palx<palq; palx+=mult){
\r
1088 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
\r
1094 /////////////////////////////////////////////////////////////////////////////
\r
1096 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1097 // the Virtual screen. //
\r
1099 /////////////////////////////////////////////////////////////////////////////
\r
1100 void modexcls(page_t *page, byte color, byte *Where)
\r
1102 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1103 /* set map mask to all 4 planes */
\r
1104 outpw(SC_INDEX, 0xff02);
\r
1105 //_fmemset(VGA, color, 16000);
\r
1106 _fmemset(Where, color, page->width*(page->height)/4);
\r
1110 modexWaitBorder() {
\r
1111 while(inp(INPUT_STATUS_1) & 8) {
\r
1115 while(!(inp(INPUT_STATUS_1) & 8)) {
\r
1125 m = int10_getmode();
\r
1126 if ((rp=vga_state.vga_graphics_ram) != NULL && !(m <= 3 || m == 7)) {
\r
1127 unsigned int i,im;
\r
1129 im = (FP_SEG(vga_state.vga_graphics_ram_fence) - FP_SEG(vga_state.vga_graphics_ram));
\r
1130 if (im > 0xFFE) im = 0xFFE;
\r
1132 for (i=0;i < im;i++) vga_state.vga_graphics_ram[i] = 0;
\r
1134 else if ((ap=vga_state.vga_alpha_ram) != NULL) {
\r
1135 unsigned int i,im;
\r
1137 im = (FP_SEG(vga_state.vga_alpha_ram_fence) - FP_SEG(vga_state.vga_alpha_ram));
\r
1138 if (im > 0x7FE) im = 0x7FE;
\r
1139 im <<= 4 - 1; /* because ptr is type uint16_t */
\r
1140 for (i=0;i < im;i++) vga_state.vga_alpha_ram[i] = 0x0720;
\r
1143 printf("WARNING: bios cls no ptr\n");
\r