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
274 modexShowPage(page_t *page) {
\r
280 /* calculate offset */
\r
281 offset = (word) page->data;
\r
282 offset += page->dy * (page->width >> 2 );
\r
283 offset += page->dx >> 2;
\r
285 /* calculate crtcOffset according to virtual width */
\r
286 crtcOffset = page->width >> 3;
\r
288 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
289 low_address = LOW_ADDRESS | (offset << 8);
\r
291 /* wait for appropriate timing and then program CRTC */
\r
292 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
293 outpw(CRTC_INDEX, high_address);
\r
294 outpw(CRTC_INDEX, low_address);
\r
295 outp(CRTC_INDEX, 0x13);
\r
296 outp(CRTC_DATA, crtcOffset);
\r
298 /* wait for one retrace */
\r
299 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
301 /* do PEL panning here */
\r
302 outp(AC_INDEX, 0x33);
\r
303 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
307 modexPanPage(page_t *page, int dx, int dy) {
\r
313 modexSelectPlane(byte plane) {
\r
314 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
315 outp(SC_DATA, plane);
\r
319 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
320 word pageOff = (word) page->data;
\r
321 word xoff=x/4; /* xoffset that begins each row */
\r
322 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
323 word poffset = pageOff + y*(page->stridew) + xoff; /* starting offset */
\r
324 word nextRow = page->stridew-scanCount-1; /* loc of next row */
\r
325 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
326 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
327 byte left = lclip[x&0x03];
\r
328 byte right = rclip[(x+w)&0x03];
\r
330 /* handle the case which requires an extra group */
\r
331 if((x & 0x03) && !((x+w) & 0x03)) {
\r
344 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
346 MOV DI, poffset ; go to the first pixel
\r
347 MOV DX, SC_INDEX ; point to the map mask
\r
351 MOV AL, color ; get ready to write colors
\r
353 MOV CX, scanCount ; count the line
\r
354 MOV BL, AL ; remember color
\r
355 MOV AL, left ; do the left clip
\r
356 OUT DX, AL ; set the left clip
\r
357 MOV AL, BL ; restore color
\r
358 STOSB ; write the color
\r
360 JZ SCAN_DONE ; handle 1 group stuff
\r
362 ;-- write the main body of the scanline
\r
363 MOV BL, AL ; remember color
\r
364 MOV AL, 0x0f ; write to all pixels
\r
366 MOV AL, BL ; restore color
\r
367 REP STOSB ; write the color
\r
369 MOV BL, AL ; remeber color
\r
371 OUT DX, AL ; do the right clip
\r
372 MOV AL, BL ; restore color
\r
373 STOSB ; write pixel
\r
374 ADD DI, nextRow ; go to the next row
\r
388 /* moved to src/lib/modex16/16render.c */
\r
390 /* copy a region of video memory from one page to another.
\r
391 * It assumes that the left edge of the tile is the same on both
\r
392 * regions and the memory areas do not overlap.
\r
395 modexCopyPageRegion(page_t *dest, page_t *src,
\r
398 word width, word height)
\r
400 word doffset = (word)dest->data + dy*(dest->stridew) + dx/4;
\r
401 word soffset = (word)src->data + sy*(src->stridew) + sx/4;
\r
402 word scans = vga_state.vga_stride;
\r
403 word nextSrcRow = src->stridew - scans - 1;
\r
404 word nextDestRow = dest->stridew - scans - 1;
\r
405 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
406 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
407 byte left = lclip[sx&0x03];
\r
408 byte right = rclip[(sx+width)&0x03];
\r
420 MOV AX, SCREEN_SEG ; work in the vga space
\r
425 MOV DX, GC_INDEX ; turn off cpu bits
\r
429 MOV AX, SC_INDEX ; point to the mask register
\r
439 MOV CX, scans ; the number of latches
\r
441 MOV AL, left ; do the left column
\r
446 MOV AL, 0fh ; do the inner columns
\r
448 REP MOVSB ; copy the pixels
\r
450 MOV AL, right ; do the right column
\r
455 MOV AX, SI ; go the start of the next row
\r
456 ADD AX, nextSrcRow ;
\r
459 ADD AX, nextDestRow ;
\r
462 DEC height ; do the rest of the actions
\r
465 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
466 MOV AL, 0ffh ; none from latches
\r
481 /* fade and flash */
\r
483 modexFadeOn(word fade, byte *palette) {
\r
484 fadePalette(-fade, 64, 64/fade+1, palette);
\r
489 modexFadeOff(word fade, byte *palette) {
\r
490 fadePalette(fade, 0, 64/fade+1, palette);
\r
495 modexFlashOn(word fade, byte *palette) {
\r
496 fadePalette(fade, -64, 64/fade+1, palette);
\r
501 modexFlashOff(word fade, byte *palette) {
\r
502 fadePalette(-fade, 0, 64/fade+1, palette);
\r
507 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
511 /* handle the case where we just update */
\r
513 modexPalUpdate1(palette);
\r
517 while(iter > 0) { /* FadeLoop */
\r
518 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
519 tmppal[i] = palette[i] - dim;
\r
520 if(tmppal[i] > 127) {
\r
522 } else if(tmppal[i] > 63) {
\r
526 modexPalUpdate1(tmppal);
\r
533 /* save and load */
\r
535 modexPalSave(byte *palette) {
\r
538 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
539 for(i=0; i<PAL_SIZE; i++) {
\r
540 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
548 ptr = malloc(PAL_SIZE);
\r
550 /* handle errors */
\r
552 printf("Could not allocate palette.\n");
\r
561 modexLoadPalFile(byte *filename, byte **palette) {
\r
565 /* free the palette if it exists */
\r
570 /* allocate the new palette */
\r
571 *palette = modexNewPal();
\r
573 /* open the file */
\r
574 file = fopen(filename, "rb");
\r
576 printf("Could not open palette file: %s\n", filename);
\r
580 /* read the file */
\r
582 while(!feof(file)) {
\r
583 *ptr++ = fgetc(file);
\r
591 modexSavePalFile(char *filename, byte *pal) {
\r
595 /* open the file for writing */
\r
596 file = fopen(filename, "wb");
\r
598 printf("Could not open %s for writing\n", filename);
\r
602 /* write the data to the file */
\r
603 fwrite(pal, 1, PAL_SIZE, file);
\r
611 fadePalette(-1, 64, 1, tmppal);
\r
617 fadePalette(-1, -64, 1, tmppal);
\r
623 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
625 byte *p = bmp->palette;
\r
629 static word a[PAL_SIZE]; //palette array of change values!
\r
630 word z=0, aq=0, aa=0, pp=0;
\r
632 //modexWaitBorder();
\r
633 vga_wait_for_vsync();
\r
636 memset(a, -1, sizeof(a));
\r
637 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
647 // printf("q: %02d\n", (q));
\r
648 // printf("qq: %02d\n", (qq));
\r
649 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
650 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
652 if((*i)<PAL_SIZE/2 && w==0)
\r
654 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
656 //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
657 //____ 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
658 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
663 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
665 //printf("qp=%d\n", qp);
\r
666 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
667 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
668 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
669 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
673 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
675 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
676 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
677 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
680 //if(qp>0) printf("qp=%d\n", qp);
\r
681 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
683 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
684 vga_wait_for_vsync();
\r
685 if((*i)>=PAL_SIZE/2 && w==0)
\r
687 for(; (*i)<PAL_SIZE; (*i)++)
\r
689 //____ 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
690 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
695 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
697 //printf("qp=%d\n", qp);
\r
698 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
699 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
700 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
701 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
705 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
706 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
707 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
710 //printf(" (*i)=%d\n", (*i)/3);
\r
713 printf("\nqqqqqqqq\n\n");
\r
719 long bufSize = (bmp->width * bmp->height);
\r
721 //printf("1(*i)=%02d\n", (*i)/3);
\r
722 //printf("1z=%02d\n", z/3);
\r
723 modexchkcolor(bmp, &q, &a, &aa, &z, i);
\r
724 //printf("2(*i)=%02d\n", (*i)/3);
\r
725 //printf("2z=%02d\n", z/3);
\r
730 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
731 if(a[aq]==-1) aq++;
\r
732 else { aqoffset++; break; }
\r
734 //update the image data here!
\r
735 for(lq=0; lq<bufSize; lq++)
\r
739 use a[qp] instead of bmp->offset for this spot!
\r
744 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
747 //(offset/bmp->offset)*bmp->offset
\r
750 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
751 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
752 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
753 /*if(bmp->data[lq]+bmp->offset==aq)
\r
755 //printf("%02d", bmp->data[lq]);
\r
756 //printf("\n%02d\n", bmp->offset);
\r
757 printf("aq=%02d ", aq);
\r
758 printf("a[aq]=%02d ", a[aq]);
\r
759 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
760 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
761 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
762 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
763 // printf("_%d ", bmp->data[lq]);
\r
764 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
766 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
768 if(bmp->data[lq]+bmp->offset >= aq)
\r
770 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
771 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
773 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
776 //printf("%02d`", bmp->data[lq]);
\r
777 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
780 //printf(" aq=%02d\n", aq);
\r
781 //printf(" aa=%02d\n", aa);
\r
783 //update the palette~
\r
784 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
787 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
792 modexPalUpdate1(byte *p)
\r
795 //modexWaitBorder();
\r
796 vga_wait_for_vsync();
\r
797 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
798 for(i=0; i<PAL_SIZE/2; i++)
\r
800 outp(PAL_DATA_REG, p[i]);
\r
802 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
803 vga_wait_for_vsync();
\r
804 for(; i<PAL_SIZE; i++)
\r
806 outp(PAL_DATA_REG, p[(i)]);
\r
811 modexPalUpdate0(byte *p)
\r
814 //modexWaitBorder();
\r
815 vga_wait_for_vsync();
\r
816 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
817 for(i=0; i<PAL_SIZE/2; i++)
\r
819 outp(PAL_DATA_REG, rand());
\r
821 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
822 vga_wait_for_vsync();
\r
823 for(; i<PAL_SIZE; i++)
\r
825 outp(PAL_DATA_REG, rand());
\r
830 modexPalOverscan(byte *p, word col)
\r
832 //modexWaitBorder();
\r
833 vga_wait_for_vsync();
\r
834 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
835 outp(PAL_DATA_REG, col);
\r
839 //i want to make another vesion that checks the palette when the palette is being appened~
\r
840 void modexchkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
844 pal = modexNewPal();
\r
846 //printf("q: %02d\n", (*q));
\r
847 printf("chkcolor start~\n");
\r
848 printf("1 (*z): %d\n", (*z)/3);
\r
849 printf("1 (*i): %d\n", (*i)/3);
\r
850 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
851 printf("wwwwwwwwwwwwwwww\n");
\r
852 //check palette for dups
\r
853 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
855 //printf("\n z: %d\n", (*z));
\r
856 //printf(" q: %d\n", (*q));
\r
857 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
860 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
863 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
864 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
868 else for(zz=0; zz<(*q); zz+=3)
\r
870 //printf("zz: %02d\n", zz/3);
\r
873 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
877 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
878 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
881 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
883 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
884 // 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
885 // 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
886 // //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
887 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
892 planned features that i plan to implement~
\r
893 image that has values on the pallete list!
\r
895 no... wait.... no wwww
\r
897 //for(zzii=0; zzii<3; zzii++)
\r
899 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
900 a[(((*z)+(*q)))]=zz;
\r
902 (*aa)=(((*z)+(*q)));
\r
903 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
904 // printf("\n aa: %d\n\n", (*aa));
\r
905 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
906 // printf("wwwwwwwwwwwwwwww\n\n");
\r
910 printf("================\n");
\r
911 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
912 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
913 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
914 printf("================\n");
\r
916 //printf("[%d]", (zz+q));
\r
920 printf("wwwwwwwwwwwwwwww\n");
\r
921 printf("2 (*z): %d\n", (*z)/3);
\r
922 printf("2 (*i): %d\n", (*i)/3);
\r
923 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
924 printf("chkcolor end~\n");
\r
928 void modexputPixel(page_t *page, int x, int y, byte color)
\r
930 word pageOff = (word) page->data;
\r
931 /* Each address accesses four neighboring pixels, so set
\r
932 Write Plane Enable according to which pixel we want
\r
933 to modify. The plane is determined by the two least
\r
934 significant bits of the x-coordinate: */
\r
935 modexSelectPlane(PLANE(x));
\r
936 //outp(SC_INDEX, 0x02);
\r
937 //outp(SC_DATA, 0x01 << (x & 3));
\r
939 /* The offset of the pixel into the video segment is
\r
940 offset = (width * y + x) / 4, and write the given
\r
941 color to the plane we selected above. Heed the active
\r
942 page start selection. */
\r
943 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
947 byte modexgetPixel(page_t *page, int x, int y)
\r
949 word pageOff = (word) page->data;
\r
950 /* Select the plane from which we must read the pixel color: */
\r
951 outpw(GC_INDEX, 0x04);
\r
952 outpw(GC_INDEX+1, x & 3);
\r
954 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
958 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
962 word addr = (word) romFontsData.l;
\r
963 word addrq = (page->width/4) * y + (x / 4) + ((word)page->data);
\r
964 word addrr = addrq;
\r
969 w=romFonts[t].charSize;
\r
970 romFontsData.chw=0;
\r
972 for(; *str != '\0'; str++)
\r
978 romFontsData.chw = 0;
\r
979 addrq += (page->width / 4) * 8;
\r
985 // load the character into romFontsData.l
\r
986 // no need for inline assembly!
\r
987 // NTS: It might even be faster to just let the modexDrawChar point directly at ROM font than to copy per char! --J.C.
\r
988 _fmemcpy(romFontsData.l,MK_FP(s,o+(w*c))/*ROM font location*/,w/*char size*/);
\r
989 modexDrawChar(page, x_draw/*for mode X planar use*/, t, col, bgcol, addrr);
\r
990 x_draw += 8; /* track X for edge of screen */
\r
991 addrr += 2; /* move 8 pixels over (2 x 4 planar pixels per byte) */
\r
995 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
997 word i, s, o, w, j, xp;
\r
999 word addr = (word) l;
\r
1023 s=romFonts[t].seg;
\r
1024 o=romFonts[t].off;
\r
1026 for(; *str != '\0'; str++)
\r
1029 if((c=='\n'/* || c=="\
\r
1030 "*/)/* || chw>=page->width*/)
\r
1036 //load the letter 'A'
\r
1051 MOV AL, c ; the letter
\r
1054 ADD SI, AX ;the address of charcter
\r
1072 for(i=0; i<w; i++)
\r
1078 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1079 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1088 /* palette dump on display! */
\r
1089 void modexpdump(page_t *pee)
\r
1091 int mult=(QUADWH);
\r
1092 int palq=(mult)*TILEWH;
\r
1095 for(paly=0; paly<palq; paly+=mult){
\r
1096 for(palx=0; palx<palq; palx+=mult){
\r
1097 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
\r
1103 /////////////////////////////////////////////////////////////////////////////
\r
1105 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1106 // the Virtual screen. //
\r
1108 /////////////////////////////////////////////////////////////////////////////
\r
1109 void modexcls(page_t *page, byte color, byte *Where)
\r
1111 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1112 /* set map mask to all 4 planes */
\r
1113 outpw(SC_INDEX, 0xff02);
\r
1114 //_fmemset(VGA, color, 16000);
\r
1115 _fmemset(Where, color, page->width*(page->height)/4);
\r
1119 modexWaitBorder() {
\r
1120 while(inp(INPUT_STATUS_1) & 8) {
\r
1124 while(!(inp(INPUT_STATUS_1) & 8)) {
\r
1134 m = int10_getmode();
\r
1135 if ((rp=vga_state.vga_graphics_ram) != NULL && !(m <= 3 || m == 7)) {
\r
1136 unsigned int i,im;
\r
1138 im = (FP_SEG(vga_state.vga_graphics_ram_fence) - FP_SEG(vga_state.vga_graphics_ram));
\r
1139 if (im > 0xFFE) im = 0xFFE;
\r
1141 for (i=0;i < im;i++) vga_state.vga_graphics_ram[i] = 0;
\r
1143 else if ((ap=vga_state.vga_alpha_ram) != NULL) {
\r
1144 unsigned int i,im;
\r
1146 im = (FP_SEG(vga_state.vga_alpha_ram_fence) - FP_SEG(vga_state.vga_alpha_ram));
\r
1147 if (im > 0x7FE) im = 0x7FE;
\r
1148 im <<= 4 - 1; /* because ptr is type uint16_t */
\r
1149 for (i=0;i < im;i++) vga_state.vga_alpha_ram[i] = 0x0720;
\r
1152 printf("WARNING: bios cls no ptr\n");
\r
1156 void modexprintmeminfo(video_t *v)
\r
1159 printf("video memory remaining: %u\n", v->vmem_remain);
\r
1161 for(i=0; i<v->num_of_pages;i++)
\r
1163 printf(" [%u]=", i);
\r
1164 printf("(%Fp)", (v->page[i].data));
\r
1165 printf(" size=%u", v->page[i].pagesize);
\r
1166 printf(" sw=%lu sh=%lu ", (unsigned long)v->page[i].sw, (unsigned long)v->page[i].sh);
\r
1167 printf(" width=%lu height=%lu", (unsigned long)v->page[i].width, (unsigned long)v->page[i].height);
\r