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.stridew=page.width/4;
\r
191 page.pagesize = (word)(page.width/4)*page.height;
\r
197 /* returns the next page in contiguous memory
\r
198 * the next page will be the same size as p, by default
\r
201 modexNextPage(page_t *p) {
\r
204 result.data = p->data + (p->pagesize);
\r
209 result.width = p->width;
\r
210 result.height = p->height;
\r
213 result.tilesw = p->tilesw;
\r
214 result.tilesh = p->tilesh;
\r
215 result.id = p->id+1;
\r
216 result.stridew=p->stridew;
\r
217 result.pagesize = p->pagesize;
\r
222 //next page with defined dimentions~
\r
224 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
228 result.data = p->data + (p->pagesize); /* compute the offset */
\r
235 result.tw = result.sw/TILEWH;
\r
236 result.th = result.sh/TILEWH;
\r
237 result.tilesw=result.width/TILEWH;
\r
238 result.tilesh=result.height/TILEWH;
\r
239 result.id = p->id+1;
\r
240 result.stridew=result.width/4;
\r
241 result.pagesize = (word)(result.width/4)*result.height;
\r
246 void modexCalcVmemRemain(video_t *video)
\r
249 //printf("\n\n 1st vmem_remain=%u\n", video->vmem_remain);
\r
250 for(i=0; i<video->num_of_pages; i++)
\r
252 video->vmem_remain-=video->page[i].pagesize;
\r
253 //printf(" [%u], video->page[%u].pagesize=%u\n", i, i, video->page[i].pagesize);
\r
254 //printf(" [%u], vmem_remain=%u\n", i, video->vmem_remain);
\r
258 void modexHiganbanaPageSetup(video_t *video)
\r
260 video->vmem_remain=65535U;
\r
261 video->num_of_pages=0;
\r
262 (video->page[0]) = modexDefaultPage(&(video->page[0])); video->num_of_pages++; //video->page[0].width += (TILEWHD); video->page[0].height += (TILEWHD);
\r
263 (video->page[1]) = modexNextPage(&(video->page[0])); video->num_of_pages++;
\r
264 (video->page[2]) = modexNextPageFlexibleSize(&(video->page[1]), TILEWH*4, TILEWH*4); video->num_of_pages++;
\r
265 (video->page[3]) = modexNextPageFlexibleSize(&(video->page[2]), video->page[0].sw, 208); video->num_of_pages++;
\r
266 // (video->page[2]) = modexNextPageFlexibleSize(&(video->page[1]), video->page[0].width, 172); video->num_of_pages++;
\r
267 // (video->page[3]) = modexNextPageFlexibleSize(&(video->page[2]), 72, 128); video->num_of_pages++;
\r
268 modexCalcVmemRemain(video);
\r
273 modexShowPage(page_t *page) {
\r
279 /* calculate offset */
\r
280 offset = (word) page->data;
\r
281 offset += page->dy * (page->width >> 2 );
\r
282 offset += page->dx >> 2;
\r
284 /* calculate crtcOffset according to virtual width */
\r
285 crtcOffset = page->width >> 3;
\r
287 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
288 low_address = LOW_ADDRESS | (offset << 8);
\r
290 /* wait for appropriate timing and then program CRTC */
\r
291 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
292 outpw(CRTC_INDEX, high_address);
\r
293 outpw(CRTC_INDEX, low_address);
\r
294 outp(CRTC_INDEX, 0x13);
\r
295 outp(CRTC_DATA, crtcOffset);
\r
297 /* wait for one retrace */
\r
298 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
300 /* do PEL panning here */
\r
301 outp(AC_INDEX, 0x33);
\r
302 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
306 modexPanPage(page_t *page, int dx, int dy) {
\r
312 modexSelectPlane(byte plane) {
\r
313 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
314 outp(SC_DATA, plane);
\r
318 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
319 word pageOff = (word) page->data;
\r
320 word xoff=x/4; /* xoffset that begins each row */
\r
321 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
322 word poffset = pageOff + y*(page->stridew) + xoff; /* starting offset */
\r
323 word nextRow = page->stridew-scanCount-1; /* loc of next row */
\r
324 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
325 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
326 byte left = lclip[x&0x03];
\r
327 byte right = rclip[(x+w)&0x03];
\r
329 /* handle the case which requires an extra group */
\r
330 if((x & 0x03) && !((x+w) & 0x03)) {
\r
343 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
345 MOV DI, poffset ; go to the first pixel
\r
346 MOV DX, SC_INDEX ; point to the map mask
\r
350 MOV AL, color ; get ready to write colors
\r
352 MOV CX, scanCount ; count the line
\r
353 MOV BL, AL ; remember color
\r
354 MOV AL, left ; do the left clip
\r
355 OUT DX, AL ; set the left clip
\r
356 MOV AL, BL ; restore color
\r
357 STOSB ; write the color
\r
359 JZ SCAN_DONE ; handle 1 group stuff
\r
361 ;-- write the main body of the scanline
\r
362 MOV BL, AL ; remember color
\r
363 MOV AL, 0x0f ; write to all pixels
\r
365 MOV AL, BL ; restore color
\r
366 REP STOSB ; write the color
\r
368 MOV BL, AL ; remeber color
\r
370 OUT DX, AL ; do the right clip
\r
371 MOV AL, BL ; restore color
\r
372 STOSB ; write pixel
\r
373 ADD DI, nextRow ; go to the next row
\r
387 /* moved to src/lib/modex16/16render.c */
\r
389 /* copy a region of video memory from one page to another.
\r
390 * It assumes that the left edge of the tile is the same on both
\r
391 * regions and the memory areas do not overlap.
\r
394 modexCopyPageRegion(page_t *dest, page_t *src,
\r
397 word width, word height)
\r
399 word doffset = (word)dest->data + dy*(dest->stridew) + dx/4;
\r
400 word soffset = (word)src->data + sy*(src->stridew) + sx/4;
\r
401 word scans = vga_state.vga_stride;
\r
402 word nextSrcRow = src->stridew - scans - 1;
\r
403 word nextDestRow = dest->stridew - scans - 1;
\r
404 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
405 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
406 byte left = lclip[sx&0x03];
\r
407 byte right = rclip[(sx+width)&0x03];
\r
419 MOV AX, SCREEN_SEG ; work in the vga space
\r
424 MOV DX, GC_INDEX ; turn off cpu bits
\r
428 MOV AX, SC_INDEX ; point to the mask register
\r
438 MOV CX, scans ; the number of latches
\r
440 MOV AL, left ; do the left column
\r
445 MOV AL, 0fh ; do the inner columns
\r
447 REP MOVSB ; copy the pixels
\r
449 MOV AL, right ; do the right column
\r
454 MOV AX, SI ; go the start of the next row
\r
455 ADD AX, nextSrcRow ;
\r
458 ADD AX, nextDestRow ;
\r
461 DEC height ; do the rest of the actions
\r
464 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
465 MOV AL, 0ffh ; none from latches
\r
480 /* fade and flash */
\r
482 modexFadeOn(word fade, byte *palette) {
\r
483 fadePalette(-fade, 64, 64/fade+1, palette);
\r
488 modexFadeOff(word fade, byte *palette) {
\r
489 fadePalette(fade, 0, 64/fade+1, palette);
\r
494 modexFlashOn(word fade, byte *palette) {
\r
495 fadePalette(fade, -64, 64/fade+1, palette);
\r
500 modexFlashOff(word fade, byte *palette) {
\r
501 fadePalette(-fade, 0, 64/fade+1, palette);
\r
506 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
510 /* handle the case where we just update */
\r
512 modexPalUpdate1(palette);
\r
516 while(iter > 0) { /* FadeLoop */
\r
517 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
518 tmppal[i] = palette[i] - dim;
\r
519 if(tmppal[i] > 127) {
\r
521 } else if(tmppal[i] > 63) {
\r
525 modexPalUpdate1(tmppal);
\r
532 /* save and load */
\r
534 modexPalSave(byte *palette) {
\r
537 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
538 for(i=0; i<PAL_SIZE; i++) {
\r
539 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
547 ptr = malloc(PAL_SIZE);
\r
549 /* handle errors */
\r
551 printf("Could not allocate palette.\n");
\r
560 modexLoadPalFile(byte *filename, byte **palette) {
\r
564 /* free the palette if it exists */
\r
569 /* allocate the new palette */
\r
570 *palette = modexNewPal();
\r
572 /* open the file */
\r
573 file = fopen(filename, "rb");
\r
575 printf("Could not open palette file: %s\n", filename);
\r
579 /* read the file */
\r
581 while(!feof(file)) {
\r
582 *ptr++ = fgetc(file);
\r
590 modexSavePalFile(char *filename, byte *pal) {
\r
594 /* open the file for writing */
\r
595 file = fopen(filename, "wb");
\r
597 printf("Could not open %s for writing\n", filename);
\r
601 /* write the data to the file */
\r
602 fwrite(pal, 1, PAL_SIZE, file);
\r
610 fadePalette(-1, 64, 1, tmppal);
\r
616 fadePalette(-1, -64, 1, tmppal);
\r
622 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
624 byte *p = bmp->palette;
\r
628 static word a[PAL_SIZE]; //palette array of change values!
\r
629 word z=0, aq=0, aa=0, pp=0;
\r
631 //modexWaitBorder();
\r
632 vga_wait_for_vsync();
\r
635 memset(a, -1, sizeof(a));
\r
636 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
646 // printf("q: %02d\n", (q));
\r
647 // printf("qq: %02d\n", (qq));
\r
648 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
649 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
651 if((*i)<PAL_SIZE/2 && w==0)
\r
653 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
655 //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
656 //____ 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
657 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
662 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
664 //printf("qp=%d\n", qp);
\r
665 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
666 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
667 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
668 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
672 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
674 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
675 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
676 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
679 //if(qp>0) printf("qp=%d\n", qp);
\r
680 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
682 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
683 vga_wait_for_vsync();
\r
684 if((*i)>=PAL_SIZE/2 && w==0)
\r
686 for(; (*i)<PAL_SIZE; (*i)++)
\r
688 //____ 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
689 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
694 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
696 //printf("qp=%d\n", qp);
\r
697 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
698 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
699 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
700 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
704 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
705 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
706 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
709 //printf(" (*i)=%d\n", (*i)/3);
\r
712 printf("\nqqqqqqqq\n\n");
\r
718 long bufSize = (bmp->width * bmp->height);
\r
720 //printf("1(*i)=%02d\n", (*i)/3);
\r
721 //printf("1z=%02d\n", z/3);
\r
722 modexchkcolor(bmp, &q, &a, &aa, &z, i);
\r
723 //printf("2(*i)=%02d\n", (*i)/3);
\r
724 //printf("2z=%02d\n", z/3);
\r
729 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
730 if(a[aq]==-1) aq++;
\r
731 else { aqoffset++; break; }
\r
733 //update the image data here!
\r
734 for(lq=0; lq<bufSize; lq++)
\r
738 use a[qp] instead of bmp->offset for this spot!
\r
743 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
746 //(offset/bmp->offset)*bmp->offset
\r
749 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
750 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
751 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
752 /*if(bmp->data[lq]+bmp->offset==aq)
\r
754 //printf("%02d", bmp->data[lq]);
\r
755 //printf("\n%02d\n", bmp->offset);
\r
756 printf("aq=%02d ", aq);
\r
757 printf("a[aq]=%02d ", a[aq]);
\r
758 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
759 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
760 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
761 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
762 // printf("_%d ", bmp->data[lq]);
\r
763 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
765 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
767 if(bmp->data[lq]+bmp->offset >= aq)
\r
769 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
770 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
772 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
775 //printf("%02d`", bmp->data[lq]);
\r
776 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
779 //printf(" aq=%02d\n", aq);
\r
780 //printf(" aa=%02d\n", aa);
\r
782 //update the palette~
\r
783 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
786 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
791 modexPalUpdate1(byte *p)
\r
794 //modexWaitBorder();
\r
795 vga_wait_for_vsync();
\r
796 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
797 for(i=0; i<PAL_SIZE/2; i++)
\r
799 outp(PAL_DATA_REG, p[i]);
\r
801 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
802 vga_wait_for_vsync();
\r
803 for(; i<PAL_SIZE; i++)
\r
805 outp(PAL_DATA_REG, p[(i)]);
\r
810 modexPalUpdate0(byte *p)
\r
813 //modexWaitBorder();
\r
814 vga_wait_for_vsync();
\r
815 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
816 for(i=0; i<PAL_SIZE/2; i++)
\r
818 outp(PAL_DATA_REG, rand());
\r
820 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
821 vga_wait_for_vsync();
\r
822 for(; i<PAL_SIZE; i++)
\r
824 outp(PAL_DATA_REG, rand());
\r
829 modexPalOverscan(byte *p, word col)
\r
831 //modexWaitBorder();
\r
832 vga_wait_for_vsync();
\r
833 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
834 outp(PAL_DATA_REG, col);
\r
838 //i want to make another vesion that checks the palette when the palette is being appened~
\r
839 void modexchkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
843 pal = modexNewPal();
\r
845 //printf("q: %02d\n", (*q));
\r
846 printf("chkcolor start~\n");
\r
847 printf("1 (*z): %d\n", (*z)/3);
\r
848 printf("1 (*i): %d\n", (*i)/3);
\r
849 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
850 printf("wwwwwwwwwwwwwwww\n");
\r
851 //check palette for dups
\r
852 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
854 //printf("\n z: %d\n", (*z));
\r
855 //printf(" q: %d\n", (*q));
\r
856 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
859 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
862 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
863 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
867 else for(zz=0; zz<(*q); zz+=3)
\r
869 //printf("zz: %02d\n", zz/3);
\r
872 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
876 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
877 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
880 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
882 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
883 // 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
884 // 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
885 // //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
886 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
891 planned features that i plan to implement~
\r
892 image that has values on the pallete list!
\r
894 no... wait.... no wwww
\r
896 //for(zzii=0; zzii<3; zzii++)
\r
898 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
899 a[(((*z)+(*q)))]=zz;
\r
901 (*aa)=(((*z)+(*q)));
\r
902 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
903 // printf("\n aa: %d\n\n", (*aa));
\r
904 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
905 // printf("wwwwwwwwwwwwwwww\n\n");
\r
909 printf("================\n");
\r
910 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
911 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
912 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
913 printf("================\n");
\r
915 //printf("[%d]", (zz+q));
\r
919 printf("wwwwwwwwwwwwwwww\n");
\r
920 printf("2 (*z): %d\n", (*z)/3);
\r
921 printf("2 (*i): %d\n", (*i)/3);
\r
922 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
923 printf("chkcolor end~\n");
\r
927 void modexputPixel(page_t *page, int x, int y, byte color)
\r
929 word pageOff = (word) page->data;
\r
930 /* Each address accesses four neighboring pixels, so set
\r
931 Write Plane Enable according to which pixel we want
\r
932 to modify. The plane is determined by the two least
\r
933 significant bits of the x-coordinate: */
\r
934 modexSelectPlane(PLANE(x));
\r
935 //outp(SC_INDEX, 0x02);
\r
936 //outp(SC_DATA, 0x01 << (x & 3));
\r
938 /* The offset of the pixel into the video segment is
\r
939 offset = (width * y + x) / 4, and write the given
\r
940 color to the plane we selected above. Heed the active
\r
941 page start selection. */
\r
942 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
946 byte modexgetPixel(page_t *page, int x, int y)
\r
948 word pageOff = (word) page->data;
\r
949 /* Select the plane from which we must read the pixel color: */
\r
950 outpw(GC_INDEX, 0x04);
\r
951 outpw(GC_INDEX+1, x & 3);
\r
953 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
957 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
961 word addr = (word) romFontsData.l;
\r
962 word addrq = (page->width/4) * y + (x / 4) + ((word)page->data);
\r
963 word addrr = addrq;
\r
968 w=romFonts[t].charSize;
\r
969 romFontsData.chw=0;
\r
971 for(; *str != '\0'; str++)
\r
977 romFontsData.chw = 0;
\r
978 addrq += (page->width / 4) * 8;
\r
984 // load the character into romFontsData.l
\r
985 // no need for inline assembly!
\r
986 // NTS: It might even be faster to just let the modexDrawChar point directly at ROM font than to copy per char! --J.C.
\r
987 _fmemcpy(romFontsData.l,MK_FP(s,o+(w*c))/*ROM font location*/,w/*char size*/);
\r
988 modexDrawChar(page, x_draw/*for mode X planar use*/, t, col, bgcol, addrr);
\r
989 x_draw += 8; /* track X for edge of screen */
\r
990 addrr += 2; /* move 8 pixels over (2 x 4 planar pixels per byte) */
\r
994 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
996 word i, s, o, w, j, xp;
\r
998 word addr = (word) l;
\r
1022 s=romFonts[t].seg;
\r
1023 o=romFonts[t].off;
\r
1025 for(; *str != '\0'; str++)
\r
1028 if((c=='\n'/* || c=="\
\r
1029 "*/)/* || chw>=page->width*/)
\r
1035 //load the letter 'A'
\r
1050 MOV AL, c ; the letter
\r
1053 ADD SI, AX ;the address of charcter
\r
1071 for(i=0; i<w; i++)
\r
1077 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1078 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1087 /* palette dump on display! */
\r
1088 void modexpdump(page_t *pee)
\r
1090 int mult=(QUADWH);
\r
1091 int palq=(mult)*TILEWH;
\r
1094 for(paly=0; paly<palq; paly+=mult){
\r
1095 for(palx=0; palx<palq; palx+=mult){
\r
1096 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
\r
1102 /////////////////////////////////////////////////////////////////////////////
\r
1104 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1105 // the Virtual screen. //
\r
1107 /////////////////////////////////////////////////////////////////////////////
\r
1108 void modexcls(page_t *page, byte color, byte *Where)
\r
1110 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1111 /* set map mask to all 4 planes */
\r
1112 outpw(SC_INDEX, 0xff02);
\r
1113 //_fmemset(VGA, color, 16000);
\r
1114 _fmemset(Where, color, page->width*(page->height)/4);
\r
1118 modexWaitBorder() {
\r
1119 while(inp(INPUT_STATUS_1) & 8) {
\r
1123 // while(!(inp(INPUT_STATUS_1) & 8)) {
\r
1133 m = int10_getmode();
\r
1134 if ((rp=vga_state.vga_graphics_ram) != NULL && !(m <= 3 || m == 7)) {
\r
1135 unsigned int i,im;
\r
1137 im = (FP_SEG(vga_state.vga_graphics_ram_fence) - FP_SEG(vga_state.vga_graphics_ram));
\r
1138 if (im > 0xFFE) im = 0xFFE;
\r
1140 for (i=0;i < im;i++) vga_state.vga_graphics_ram[i] = 0;
\r
1142 else if ((ap=vga_state.vga_alpha_ram) != NULL) {
\r
1143 unsigned int i,im;
\r
1145 im = (FP_SEG(vga_state.vga_alpha_ram_fence) - FP_SEG(vga_state.vga_alpha_ram));
\r
1146 if (im > 0x7FE) im = 0x7FE;
\r
1147 im <<= 4 - 1; /* because ptr is type uint16_t */
\r
1148 for (i=0;i < im;i++) vga_state.vga_alpha_ram[i] = 0x0720;
\r
1151 printf("WARNING: bios cls no ptr\n");
\r
1155 void modexprintmeminfo(video_t *v)
\r
1158 printf("video memory remaining: %u\n", v->vmem_remain);
\r
1160 for(i=0; i<v->num_of_pages;i++)
\r
1162 printf(" [%u]=", i);
\r
1163 printf("(%Fp)", (v->page[i].data));
\r
1164 printf(" size=%u", v->page[i].pagesize);
\r
1165 printf(" sw=%lu sh=%lu ", (unsigned long)v->page[i].sw, (unsigned long)v->page[i].sh);
\r
1166 printf(" width=%lu height=%lu", (unsigned long)v->page[i].width, (unsigned long)v->page[i].height);
\r