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 /* reprogram the CRT controller */
\r
89 outp(CRTC_INDEX, 0x11); /* VSync End reg contains register write prot */
\r
90 outp(CRTC_DATA, 0x7f); /* get current write protect on varios regs */
\r
91 update_state_from_vga();
\r
92 vga_read_crtc_mode(&cm);
\r
97 //CRTParmCount = sizeof(ModeX_320x240regs) / sizeof(ModeX_320x240regs[0]);
\r
98 /*for(i=0; i<CRTParmCount; i++) {
\r
99 outpw(CRTC_INDEX, ModeX_320x240regs[i]);
\r
101 /* width and height */
\r
102 gv->video.page[0].sw = vga_state.vga_width = 320; // VGA lib currently does not update this
\r
103 gv->video.page[0].sh = vga_state.vga_height = 240; // VGA lib currently does not update this
\r
104 /* virtual width and height. match screen, at first */
\r
105 gv->video.page[0].height = gv->video.page[0].sh;
\r
106 gv->video.page[0].width = gv->video.page[0].sw;
\r
108 // mode X BYTE mode
\r
111 // 320x240 mode 60Hz
\r
112 cm.horizontal_total=0x5f + 5; /* CRTC[0] -5 */
\r
113 cm.horizontal_display_end=0x4f + 1; /* CRTC[1] -1 */
\r
114 cm.horizontal_blank_start=0x50 + 1; /* CRTC[2] */
\r
115 cm.horizontal_blank_end=0x82 + 1; /* CRTC[3] bit 0-4 & CRTC[5] bit 7 */
\r
116 cm.horizontal_start_retrace=0x54;/* CRTC[4] */
\r
117 cm.horizontal_end_retrace=0x80; /* CRTC[5] bit 0-4 */
\r
118 //cm.horizontal_start_delay_after_total=0x3e; /* CRTC[3] bit 5-6 */
\r
119 //cm.horizontal_start_delay_after_retrace=0x41; /* CRTC[5] bit 5-6 */
\r
120 cm.vertical_total = 0x20D + 2;
\r
121 cm.vertical_start_retrace = 0x1EA;
\r
122 cm.vertical_end_retrace = 0x1EC;
\r
123 cm.vertical_display_end = 480;
\r
124 cm.vertical_blank_start = 0x1E7 + 1;
\r
125 cm.vertical_blank_end = 0x206 + 1;
\r
126 cm.clock_select = 0; /* misc register = 0xE3 25MHz */
\r
129 cm.offset = (vga_state.vga_width / (4 * 2)); // 320 wide (40 x 4 pixel groups x 2)
\r
131 case 2: // TODO: 160x120 according to ModeX_160x120regs
\r
133 case 3: // TODO: 160x120 according to ModeX_320x200regs
\r
135 case 4: // TODO: 160x120 according to ModeX_192x144regs
\r
137 case 5: // TODO: 160x120 according to ModeX_256x192regs
\r
143 vga_state.vga_stride = cm.offset * 2;
\r
144 vga_write_crtc_mode(&cm,0);
\r
146 /* clear video memory */
\r
150 /* clear video memory */
\r
151 dword far*ptr=(dword far*)vga_state.vga_graphics_ram;//VGA; /* used for faster screen clearing */
\r
152 vga_write_sequencer(2/*map mask register*/,0xf/*all 4 planes*/);
\r
153 for(i = 0;i < 0x4000; i++) ptr[i] = 0x0000; // 0x4000 x dword = 64KB
\r
158 // gv->video.page[0].tw = gv->video.page[0].sw/TILEWH;
\r
159 // gv->video.page[0].th = gv->video.page[0].sh/TILEWH;
\r
161 //TODO MAKE FLEXIBLE~
\r
162 // gv->video.page[0].tilemidposscreenx = gv->video.page[0].tilesw;
\r
163 // gv->video.page[0].tilemidposscreeny = (gv->video.page[0].tilesh/2)+1;
\r
168 /* VGAmodeX restores original mode and palette */
\r
169 vgaSetMode(TEXT_MODE);
\r
173 modexDefaultPage(page_t *p)
\r
177 /* default page values */
\r
179 //page.data = (byte far *)(vga_state.vga_graphics_ram);
\r
180 page.data = (vga_state.vga_graphics_ram);
\r
185 page.width = p->sw+TILEWHD;
\r
186 page.height = p->sh+TILEWHD;
\r
187 page.tw = page.sw/TILEWH;
\r
188 page.th = page.sh/TILEWH;
\r
189 page.tilesw=page.width/TILEWH;
\r
190 page.tilesh=page.height/TILEWH;
\r
191 page.tilemidposscreenx = page.tw/2;
\r
192 page.tilemidposscreeny = (page.th/2)+1;
\r
193 page.stridew=page.width/4;
\r
194 page.pagesize = (word)(page.width/4)*page.height;
\r
200 /* returns the next page in contiguous memory
\r
201 * the next page will be the same size as p, by default
\r
204 modexNextPage(page_t *p) {
\r
207 result.data = p->data + (p->pagesize);
\r
212 result.width = p->width;
\r
213 result.height = p->height;
\r
216 result.tilesw = p->tilesw;
\r
217 result.tilesh = p->tilesh;
\r
218 result.id = p->id+1;
\r
219 result.stridew=p->stridew;
\r
220 result.pagesize = p->pagesize;
\r
225 //next page with defined dimentions~
\r
227 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
231 result.data = p->data + (p->pagesize); /* compute the offset */
\r
238 result.tw = result.sw/TILEWH;
\r
239 result.th = result.sh/TILEWH;
\r
240 result.tilesw=result.width/TILEWH;
\r
241 result.tilesh=result.height/TILEWH;
\r
242 result.id = p->id+1;
\r
243 result.stridew=result.width/4;
\r
244 result.pagesize = (word)(result.width/4)*result.height;
\r
249 void modexCalcVmemRemain(video_t *video)
\r
252 //printf("\n\n 1st vmem_remain=%u\n", video->vmem_remain);
\r
253 for(i=0; i<video->num_of_pages; i++)
\r
255 video->vmem_remain-=video->page[i].pagesize;
\r
256 //printf(" [%u], video->page[%u].pagesize=%u\n", i, i, video->page[i].pagesize);
\r
257 //printf(" [%u], vmem_remain=%u\n", i, video->vmem_remain);
\r
261 void modexHiganbanaPageSetup(video_t *video)
\r
263 video->vmem_remain=65535U;
\r
264 video->num_of_pages=0;
\r
265 (video->page[0]) = modexDefaultPage(&(video->page[0])); video->num_of_pages++; //video->page[0].width += (TILEWHD); video->page[0].height += (TILEWHD);
\r
266 (video->page[1]) = modexNextPage(&(video->page[0])); video->num_of_pages++;
\r
267 (video->page[2]) = modexNextPageFlexibleSize(&(video->page[1]), TILEWH*4, TILEWH*4); video->num_of_pages++;
\r
268 (video->page[3]) = modexNextPageFlexibleSize(&(video->page[2]), video->page[0].sw, 208); video->num_of_pages++;
\r
269 // (video->page[2]) = modexNextPageFlexibleSize(&(video->page[1]), video->page[0].width, 172); video->num_of_pages++;
\r
270 // (video->page[3]) = modexNextPageFlexibleSize(&(video->page[2]), 72, 128); video->num_of_pages++;
\r
271 modexCalcVmemRemain(video);
\r
277 modexShowPage(page_t *page) {
\r
283 /* calculate offset */
\r
284 offset = (word) page->data;
\r
285 offset += page->dy * (page->width >> 2 );
\r
286 offset += page->dx >> 2;
\r
288 /* calculate crtcOffset according to virtual width */
\r
289 crtcOffset = page->width >> 3;
\r
291 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
292 low_address = LOW_ADDRESS | (offset << 8);
\r
294 /* wait for appropriate timing and then program CRTC */
\r
295 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
296 outpw(CRTC_INDEX, high_address);
\r
297 outpw(CRTC_INDEX, low_address);
\r
298 outp(CRTC_INDEX, 0x13);
\r
299 outp(CRTC_DATA, crtcOffset);
\r
301 /* wait for one retrace */
\r
302 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
304 /* do PEL panning here */
\r
305 outp(AC_INDEX, 0x33);
\r
306 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
310 modexPanPage(page_t *page, int dx, int dy) {
\r
316 modexSelectPlane(byte plane) {
\r
317 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
318 outp(SC_DATA, plane);
\r
322 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
323 word pageOff = (word) page->data;
\r
324 word xoff=x/4; /* xoffset that begins each row */
\r
325 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
326 word poffset = pageOff + y*(page->stridew) + xoff; /* starting offset */
\r
327 word nextRow = page->stridew-scanCount-1; /* loc of next row */
\r
328 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
329 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
330 byte left = lclip[x&0x03];
\r
331 byte right = rclip[(x+w)&0x03];
\r
333 /* handle the case which requires an extra group */
\r
334 if((x & 0x03) && !((x+w) & 0x03)) {
\r
347 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
349 MOV DI, poffset ; go to the first pixel
\r
350 MOV DX, SC_INDEX ; point to the map mask
\r
354 MOV AL, color ; get ready to write colors
\r
356 MOV CX, scanCount ; count the line
\r
357 MOV BL, AL ; remember color
\r
358 MOV AL, left ; do the left clip
\r
359 OUT DX, AL ; set the left clip
\r
360 MOV AL, BL ; restore color
\r
361 STOSB ; write the color
\r
363 JZ SCAN_DONE ; handle 1 group stuff
\r
365 ;-- write the main body of the scanline
\r
366 MOV BL, AL ; remember color
\r
367 MOV AL, 0x0f ; write to all pixels
\r
369 MOV AL, BL ; restore color
\r
370 REP STOSB ; write the color
\r
372 MOV BL, AL ; remeber color
\r
374 OUT DX, AL ; do the right clip
\r
375 MOV AL, BL ; restore color
\r
376 STOSB ; write pixel
\r
377 ADD DI, nextRow ; go to the next row
\r
391 /* moved to src/lib/modex16/16render.c */
\r
393 /* copy a region of video memory from one page to another.
\r
394 * It assumes that the left edge of the tile is the same on both
\r
395 * regions and the memory areas do not overlap.
\r
398 modexCopyPageRegion(page_t *dest, page_t *src,
\r
401 word width, word height)
\r
403 word doffset = (word)dest->data + dy*(dest->stridew) + dx/4;
\r
404 word soffset = (word)src->data + sy*(src->stridew) + sx/4;
\r
405 word scans = vga_state.vga_stride;
\r
406 word nextSrcRow = src->stridew - scans - 1;
\r
407 word nextDestRow = dest->stridew - scans - 1;
\r
408 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
409 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
410 byte left = lclip[sx&0x03];
\r
411 byte right = rclip[(sx+width)&0x03];
\r
423 MOV AX, SCREEN_SEG ; work in the vga space
\r
428 MOV DX, GC_INDEX ; turn off cpu bits
\r
432 MOV AX, SC_INDEX ; point to the mask register
\r
442 MOV CX, scans ; the number of latches
\r
444 MOV AL, left ; do the left column
\r
449 MOV AL, 0fh ; do the inner columns
\r
451 REP MOVSB ; copy the pixels
\r
453 MOV AL, right ; do the right column
\r
458 MOV AX, SI ; go the start of the next row
\r
459 ADD AX, nextSrcRow ;
\r
462 ADD AX, nextDestRow ;
\r
465 DEC height ; do the rest of the actions
\r
468 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
469 MOV AL, 0ffh ; none from latches
\r
484 /* fade and flash */
\r
486 modexFadeOn(word fade, byte *palette) {
\r
487 fadePalette(-fade, 64, 64/fade+1, palette);
\r
492 modexFadeOff(word fade, byte *palette) {
\r
493 fadePalette(fade, 0, 64/fade+1, palette);
\r
498 modexFlashOn(word fade, byte *palette) {
\r
499 fadePalette(fade, -64, 64/fade+1, palette);
\r
504 modexFlashOff(word fade, byte *palette) {
\r
505 fadePalette(-fade, 0, 64/fade+1, palette);
\r
510 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
514 /* handle the case where we just update */
\r
516 modexPalUpdate1(palette);
\r
520 while(iter > 0) { /* FadeLoop */
\r
521 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
522 tmppal[i] = palette[i] - dim;
\r
523 if(tmppal[i] > 127) {
\r
525 } else if(tmppal[i] > 63) {
\r
529 modexPalUpdate1(tmppal);
\r
536 /* save and load */
\r
538 modexPalSave(byte *palette) {
\r
541 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
542 for(i=0; i<PAL_SIZE; i++) {
\r
543 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
551 ptr = malloc(PAL_SIZE);
\r
553 /* handle errors */
\r
555 printf("Could not allocate palette.\n");
\r
564 modexLoadPalFile(byte *filename, byte **palette) {
\r
568 /* free the palette if it exists */
\r
573 /* allocate the new palette */
\r
574 *palette = modexNewPal();
\r
576 /* open the file */
\r
577 file = fopen(filename, "rb");
\r
579 printf("Could not open palette file: %s\n", filename);
\r
583 /* read the file */
\r
585 while(!feof(file)) {
\r
586 *ptr++ = fgetc(file);
\r
594 modexSavePalFile(char *filename, byte *pal) {
\r
598 /* open the file for writing */
\r
599 file = fopen(filename, "wb");
\r
601 printf("Could not open %s for writing\n", filename);
\r
605 /* write the data to the file */
\r
606 fwrite(pal, 1, PAL_SIZE, file);
\r
614 fadePalette(-1, 64, 1, tmppal);
\r
620 fadePalette(-1, -64, 1, tmppal);
\r
626 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
628 byte *p = bmp->palette;
\r
632 static word a[PAL_SIZE]; //palette array of change values!
\r
633 word z=0, aq=0, aa=0, pp=0;
\r
635 //modexWaitBorder();
\r
636 vga_wait_for_vsync();
\r
639 memset(a, -1, sizeof(a));
\r
640 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
650 // printf("q: %02d\n", (q));
\r
651 // printf("qq: %02d\n", (qq));
\r
652 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
653 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
655 if((*i)<PAL_SIZE/2 && w==0)
\r
657 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
659 //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
660 //____ 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
661 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
666 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
668 //printf("qp=%d\n", qp);
\r
669 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
670 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
671 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
672 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
676 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
678 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
679 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
680 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
683 //if(qp>0) printf("qp=%d\n", qp);
\r
684 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
686 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
687 vga_wait_for_vsync();
\r
688 if((*i)>=PAL_SIZE/2 && w==0)
\r
690 for(; (*i)<PAL_SIZE; (*i)++)
\r
692 //____ 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
693 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
698 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
700 //printf("qp=%d\n", qp);
\r
701 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
702 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
703 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
704 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
708 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
709 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
710 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
713 //printf(" (*i)=%d\n", (*i)/3);
\r
716 printf("\nqqqqqqqq\n\n");
\r
722 long bufSize = (bmp->width * bmp->height);
\r
724 //printf("1(*i)=%02d\n", (*i)/3);
\r
725 //printf("1z=%02d\n", z/3);
\r
726 modexchkcolor(bmp, &q, &a, &aa, &z, i);
\r
727 //printf("2(*i)=%02d\n", (*i)/3);
\r
728 //printf("2z=%02d\n", z/3);
\r
733 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
734 if(a[aq]==-1) aq++;
\r
735 else { aqoffset++; break; }
\r
737 //update the image data here!
\r
738 for(lq=0; lq<bufSize; lq++)
\r
742 use a[qp] instead of bmp->offset for this spot!
\r
747 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
750 //(offset/bmp->offset)*bmp->offset
\r
753 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
754 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
755 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
756 /*if(bmp->data[lq]+bmp->offset==aq)
\r
758 //printf("%02d", bmp->data[lq]);
\r
759 //printf("\n%02d\n", bmp->offset);
\r
760 printf("aq=%02d ", aq);
\r
761 printf("a[aq]=%02d ", a[aq]);
\r
762 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
763 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
764 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
765 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
766 // printf("_%d ", bmp->data[lq]);
\r
767 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
769 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
771 if(bmp->data[lq]+bmp->offset >= aq)
\r
773 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
774 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
776 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
779 //printf("%02d`", bmp->data[lq]);
\r
780 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
783 //printf(" aq=%02d\n", aq);
\r
784 //printf(" aa=%02d\n", aa);
\r
786 //update the palette~
\r
787 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
790 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
795 modexPalUpdate1(byte *p)
\r
798 //modexWaitBorder();
\r
799 vga_wait_for_vsync();
\r
800 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
801 for(i=0; i<PAL_SIZE/2; i++)
\r
803 outp(PAL_DATA_REG, p[i]);
\r
805 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
806 vga_wait_for_vsync();
\r
807 for(; i<PAL_SIZE; i++)
\r
809 outp(PAL_DATA_REG, p[(i)]);
\r
814 modexPalUpdate0(byte *p)
\r
817 //modexWaitBorder();
\r
818 vga_wait_for_vsync();
\r
819 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
820 for(i=0; i<PAL_SIZE/2; i++)
\r
822 outp(PAL_DATA_REG, rand());
\r
824 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
825 vga_wait_for_vsync();
\r
826 for(; i<PAL_SIZE; i++)
\r
828 outp(PAL_DATA_REG, rand());
\r
833 modexPalOverscan(byte *p, word col)
\r
835 //modexWaitBorder();
\r
836 vga_wait_for_vsync();
\r
837 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
838 outp(PAL_DATA_REG, col);
\r
842 //i want to make another vesion that checks the palette when the palette is being appened~
\r
843 void modexchkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
847 pal = modexNewPal();
\r
849 //printf("q: %02d\n", (*q));
\r
850 printf("chkcolor start~\n");
\r
851 printf("1 (*z): %d\n", (*z)/3);
\r
852 printf("1 (*i): %d\n", (*i)/3);
\r
853 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
854 printf("wwwwwwwwwwwwwwww\n");
\r
855 //check palette for dups
\r
856 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
858 //printf("\n z: %d\n", (*z));
\r
859 //printf(" q: %d\n", (*q));
\r
860 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
863 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
866 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
867 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
871 else for(zz=0; zz<(*q); zz+=3)
\r
873 //printf("zz: %02d\n", zz/3);
\r
876 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
880 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
881 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
884 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
886 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
887 // 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
888 // 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
889 // //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
890 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
895 planned features that i plan to implement~
\r
896 image that has values on the pallete list!
\r
898 no... wait.... no wwww
\r
900 //for(zzii=0; zzii<3; zzii++)
\r
902 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
903 a[(((*z)+(*q)))]=zz;
\r
905 (*aa)=(((*z)+(*q)));
\r
906 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
907 // printf("\n aa: %d\n\n", (*aa));
\r
908 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
909 // printf("wwwwwwwwwwwwwwww\n\n");
\r
913 printf("================\n");
\r
914 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
915 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
916 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
917 printf("================\n");
\r
919 //printf("[%d]", (zz+q));
\r
923 printf("wwwwwwwwwwwwwwww\n");
\r
924 printf("2 (*z): %d\n", (*z)/3);
\r
925 printf("2 (*i): %d\n", (*i)/3);
\r
926 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
927 printf("chkcolor end~\n");
\r
931 void modexputPixel(page_t *page, int x, int y, byte color)
\r
933 word pageOff = (word) page->data;
\r
934 /* Each address accesses four neighboring pixels, so set
\r
935 Write Plane Enable according to which pixel we want
\r
936 to modify. The plane is determined by the two least
\r
937 significant bits of the x-coordinate: */
\r
938 modexSelectPlane(PLANE(x));
\r
939 //outp(SC_INDEX, 0x02);
\r
940 //outp(SC_DATA, 0x01 << (x & 3));
\r
942 /* The offset of the pixel into the video segment is
\r
943 offset = (width * y + x) / 4, and write the given
\r
944 color to the plane we selected above. Heed the active
\r
945 page start selection. */
\r
946 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
950 byte modexgetPixel(page_t *page, int x, int y)
\r
952 word pageOff = (word) page->data;
\r
953 /* Select the plane from which we must read the pixel color: */
\r
954 outpw(GC_INDEX, 0x04);
\r
955 outpw(GC_INDEX+1, x & 3);
\r
957 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
961 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
965 word addr = (word) romFontsData.l;
\r
966 word addrq = (page->width/4) * y + (x / 4) + ((word)page->data);
\r
967 word addrr = addrq;
\r
972 w=romFonts[t].charSize;
\r
973 romFontsData.chw=0;
\r
975 for(; *str != '\0'; str++)
\r
981 romFontsData.chw = 0;
\r
982 addrq += (page->width / 4) * 8;
\r
988 // load the character into romFontsData.l
\r
989 // no need for inline assembly!
\r
990 // NTS: It might even be faster to just let the modexDrawChar point directly at ROM font than to copy per char! --J.C.
\r
991 _fmemcpy(romFontsData.l,MK_FP(s,o+(w*c))/*ROM font location*/,w/*char size*/);
\r
992 modexDrawChar(page, x_draw/*for mode X planar use*/, t, col, bgcol, addrr);
\r
993 x_draw += 8; /* track X for edge of screen */
\r
994 addrr += 2; /* move 8 pixels over (2 x 4 planar pixels per byte) */
\r
998 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1000 word i, s, o, w, j, xp;
\r
1002 word addr = (word) l;
\r
1026 s=romFonts[t].seg;
\r
1027 o=romFonts[t].off;
\r
1029 for(; *str != '\0'; str++)
\r
1032 if((c=='\n'/* || c=="\
\r
1033 "*/)/* || chw>=page->width*/)
\r
1039 //load the letter 'A'
\r
1054 MOV AL, c ; the letter
\r
1057 ADD SI, AX ;the address of charcter
\r
1075 for(i=0; i<w; i++)
\r
1081 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1082 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1091 /* palette dump on display! */
\r
1092 void modexpdump(page_t *pee)
\r
1094 int mult=(QUADWH);
\r
1095 int palq=(mult)*TILEWH;
\r
1098 for(paly=0; paly<palq; paly+=mult){
\r
1099 for(palx=0; palx<palq; palx+=mult){
\r
1100 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
\r
1106 /////////////////////////////////////////////////////////////////////////////
\r
1108 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1109 // the Virtual screen. //
\r
1111 /////////////////////////////////////////////////////////////////////////////
\r
1112 void modexcls(page_t *page, byte color, byte *Where)
\r
1114 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1115 /* set map mask to all 4 planes */
\r
1116 outpw(SC_INDEX, 0xff02);
\r
1117 //_fmemset(VGA, color, 16000);
\r
1118 _fmemset(Where, color, page->width*(page->height)/4);
\r
1122 modexWaitBorder() {
\r
1123 while(inp(INPUT_STATUS_1) & 8) {
\r
1127 while(!(inp(INPUT_STATUS_1) & 8)) {
\r
1137 m = int10_getmode();
\r
1138 if ((rp=vga_state.vga_graphics_ram) != NULL && !(m <= 3 || m == 7)) {
\r
1139 unsigned int i,im;
\r
1141 im = (FP_SEG(vga_state.vga_graphics_ram_fence) - FP_SEG(vga_state.vga_graphics_ram));
\r
1142 if (im > 0xFFE) im = 0xFFE;
\r
1144 for (i=0;i < im;i++) vga_state.vga_graphics_ram[i] = 0;
\r
1146 else if ((ap=vga_state.vga_alpha_ram) != NULL) {
\r
1147 unsigned int i,im;
\r
1149 im = (FP_SEG(vga_state.vga_alpha_ram_fence) - FP_SEG(vga_state.vga_alpha_ram));
\r
1150 if (im > 0x7FE) im = 0x7FE;
\r
1151 im <<= 4 - 1; /* because ptr is type uint16_t */
\r
1152 for (i=0;i < im;i++) vga_state.vga_alpha_ram[i] = 0x0720;
\r
1155 printf("WARNING: bios cls no ptr\n");
\r
1159 void modexprintmeminfo(video_t *v)
\r
1162 printf("video memory remaining: %u\n", v->vmem_remain);
\r
1164 for(i=0; i<v->num_of_pages;i++)
\r
1166 printf(" [%u]=", i);
\r
1167 printf("(%Fp)", (v->page[i].data));
\r
1168 printf(" size=%u", v->page[i].pagesize);
\r
1169 printf(" sw=%lu sh=%lu ", (unsigned long)v->page[i].sw, (unsigned long)v->page[i].sh);
\r
1170 printf(" width=%lu height=%lu", (unsigned long)v->page[i].width, (unsigned long)v->page[i].height);
\r