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]) = modexNextPage(&(video->page[1])); video->num_of_pages++;
\r
265 // (video->page[3]) = modexNextPageFlexibleSize(&(video->page[2]), video->page[0].width/8, video->page[0].height/8); video->num_of_pages++;
\r
266 //(video->page[3]) = modexNextPageFlexibleSize(&(video->page[2]), TILEWH, TILEWH); video->num_of_pages++;
\r
267 modexCalcVmemRemain(video);
\r
272 modexShowPage(page_t *page) {
\r
278 /* calculate offset */
\r
279 offset = (word) page->data;
\r
280 offset += page->dy * (page->width >> 2 );
\r
281 offset += page->dx >> 2;
\r
283 /* calculate crtcOffset according to virtual width */
\r
284 crtcOffset = page->width >> 3;
\r
286 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
287 low_address = LOW_ADDRESS | (offset << 8);
\r
289 /* wait for appropriate timing and then program CRTC */
\r
290 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
291 outpw(CRTC_INDEX, high_address);
\r
292 outpw(CRTC_INDEX, low_address);
\r
293 outp(CRTC_INDEX, 0x13);
\r
294 outp(CRTC_DATA, crtcOffset);
\r
296 /* wait for one retrace */
\r
297 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
299 /* do PEL panning here */
\r
300 outp(AC_INDEX, 0x33);
\r
301 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
305 modexPanPage(page_t *page, int dx, int dy) {
\r
311 modexSelectPlane(byte plane) {
\r
312 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
313 outp(SC_DATA, plane);
\r
317 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
318 word pageOff = (word) page->data;
\r
319 word xoff=x/4; /* xoffset that begins each row */
\r
320 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
321 word poffset = pageOff + y*(page->stridew) + xoff; /* starting offset */
\r
322 word nextRow = page->stridew-scanCount-1; /* loc of next row */
\r
323 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
324 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
325 byte left = lclip[x&0x03];
\r
326 byte right = rclip[(x+w)&0x03];
\r
328 /* handle the case which requires an extra group */
\r
329 if((x & 0x03) && !((x+w) & 0x03)) {
\r
342 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
344 MOV DI, poffset ; go to the first pixel
\r
345 MOV DX, SC_INDEX ; point to the map mask
\r
349 MOV AL, color ; get ready to write colors
\r
351 MOV CX, scanCount ; count the line
\r
352 MOV BL, AL ; remember color
\r
353 MOV AL, left ; do the left clip
\r
354 OUT DX, AL ; set the left clip
\r
355 MOV AL, BL ; restore color
\r
356 STOSB ; write the color
\r
358 JZ SCAN_DONE ; handle 1 group stuff
\r
360 ;-- write the main body of the scanline
\r
361 MOV BL, AL ; remember color
\r
362 MOV AL, 0x0f ; write to all pixels
\r
364 MOV AL, BL ; restore color
\r
365 REP STOSB ; write the color
\r
367 MOV BL, AL ; remeber color
\r
369 OUT DX, AL ; do the right clip
\r
370 MOV AL, BL ; restore color
\r
371 STOSB ; write pixel
\r
372 ADD DI, nextRow ; go to the next row
\r
386 /* moved to src/lib/modex16/16render.c */
\r
388 /* copy a region of video memory from one page to another.
\r
389 * It assumes that the left edge of the tile is the same on both
\r
390 * regions and the memory areas do not overlap.
\r
393 modexCopyPageRegion(page_t *dest, page_t *src,
\r
396 word width, word height)
\r
398 word doffset = (word)dest->data + dy*(dest->stridew) + dx/4;
\r
399 word soffset = (word)src->data + sy*(src->stridew) + sx/4;
\r
400 word scans = vga_state.vga_stride;
\r
401 word nextSrcRow = src->stridew - scans - 1;
\r
402 word nextDestRow = dest->stridew - scans - 1;
\r
403 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
404 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
405 byte left = lclip[sx&0x03];
\r
406 byte right = rclip[(sx+width)&0x03];
\r
418 MOV AX, SCREEN_SEG ; work in the vga space
\r
423 MOV DX, GC_INDEX ; turn off cpu bits
\r
427 MOV AX, SC_INDEX ; point to the mask register
\r
437 MOV CX, scans ; the number of latches
\r
439 MOV AL, left ; do the left column
\r
444 MOV AL, 0fh ; do the inner columns
\r
446 REP MOVSB ; copy the pixels
\r
448 MOV AL, right ; do the right column
\r
453 MOV AX, SI ; go the start of the next row
\r
454 ADD AX, nextSrcRow ;
\r
457 ADD AX, nextDestRow ;
\r
460 DEC height ; do the rest of the actions
\r
463 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
464 MOV AL, 0ffh ; none from latches
\r
479 /* fade and flash */
\r
481 modexFadeOn(word fade, byte *palette) {
\r
482 fadePalette(-fade, 64, 64/fade+1, palette);
\r
487 modexFadeOff(word fade, byte *palette) {
\r
488 fadePalette(fade, 0, 64/fade+1, palette);
\r
493 modexFlashOn(word fade, byte *palette) {
\r
494 fadePalette(fade, -64, 64/fade+1, palette);
\r
499 modexFlashOff(word fade, byte *palette) {
\r
500 fadePalette(-fade, 0, 64/fade+1, palette);
\r
505 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
509 /* handle the case where we just update */
\r
511 modexPalUpdate1(palette);
\r
515 while(iter > 0) { /* FadeLoop */
\r
516 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
517 tmppal[i] = palette[i] - dim;
\r
518 if(tmppal[i] > 127) {
\r
520 } else if(tmppal[i] > 63) {
\r
524 modexPalUpdate1(tmppal);
\r
531 /* save and load */
\r
533 modexPalSave(byte *palette) {
\r
536 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
537 for(i=0; i<PAL_SIZE; i++) {
\r
538 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
546 ptr = malloc(PAL_SIZE);
\r
548 /* handle errors */
\r
550 printf("Could not allocate palette.\n");
\r
559 modexLoadPalFile(byte *filename, byte **palette) {
\r
563 /* free the palette if it exists */
\r
568 /* allocate the new palette */
\r
569 *palette = modexNewPal();
\r
571 /* open the file */
\r
572 file = fopen(filename, "rb");
\r
574 printf("Could not open palette file: %s\n", filename);
\r
578 /* read the file */
\r
580 while(!feof(file)) {
\r
581 *ptr++ = fgetc(file);
\r
589 modexSavePalFile(char *filename, byte *pal) {
\r
593 /* open the file for writing */
\r
594 file = fopen(filename, "wb");
\r
596 printf("Could not open %s for writing\n", filename);
\r
600 /* write the data to the file */
\r
601 fwrite(pal, 1, PAL_SIZE, file);
\r
609 fadePalette(-1, 64, 1, tmppal);
\r
615 fadePalette(-1, -64, 1, tmppal);
\r
621 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
623 byte *p = bmp->palette;
\r
627 static word a[PAL_SIZE]; //palette array of change values!
\r
628 word z=0, aq=0, aa=0, pp=0;
\r
630 //modexWaitBorder();
\r
631 vga_wait_for_vsync();
\r
634 memset(a, -1, sizeof(a));
\r
635 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
645 // printf("q: %02d\n", (q));
\r
646 // printf("qq: %02d\n", (qq));
\r
647 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
648 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
650 if((*i)<PAL_SIZE/2 && w==0)
\r
652 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
654 //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
655 //____ 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
656 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
661 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
663 //printf("qp=%d\n", qp);
\r
664 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
665 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
666 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
667 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
671 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
673 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
674 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
675 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
678 //if(qp>0) printf("qp=%d\n", qp);
\r
679 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
681 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
682 vga_wait_for_vsync();
\r
683 if((*i)>=PAL_SIZE/2 && w==0)
\r
685 for(; (*i)<PAL_SIZE; (*i)++)
\r
687 //____ 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
688 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
693 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
695 //printf("qp=%d\n", qp);
\r
696 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
697 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
698 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
699 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
703 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
704 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
705 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
708 //printf(" (*i)=%d\n", (*i)/3);
\r
711 printf("\nqqqqqqqq\n\n");
\r
717 long bufSize = (bmp->width * bmp->height);
\r
719 //printf("1(*i)=%02d\n", (*i)/3);
\r
720 //printf("1z=%02d\n", z/3);
\r
721 modexchkcolor(bmp, &q, &a, &aa, &z, i);
\r
722 //printf("2(*i)=%02d\n", (*i)/3);
\r
723 //printf("2z=%02d\n", z/3);
\r
728 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
729 if(a[aq]==-1) aq++;
\r
730 else { aqoffset++; break; }
\r
732 //update the image data here!
\r
733 for(lq=0; lq<bufSize; lq++)
\r
737 use a[qp] instead of bmp->offset for this spot!
\r
742 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
745 //(offset/bmp->offset)*bmp->offset
\r
748 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
749 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
750 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
751 /*if(bmp->data[lq]+bmp->offset==aq)
\r
753 //printf("%02d", bmp->data[lq]);
\r
754 //printf("\n%02d\n", bmp->offset);
\r
755 printf("aq=%02d ", aq);
\r
756 printf("a[aq]=%02d ", a[aq]);
\r
757 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
758 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
759 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
760 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
761 // printf("_%d ", bmp->data[lq]);
\r
762 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
764 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
766 if(bmp->data[lq]+bmp->offset >= aq)
\r
768 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
769 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
771 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
774 //printf("%02d`", bmp->data[lq]);
\r
775 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
778 //printf(" aq=%02d\n", aq);
\r
779 //printf(" aa=%02d\n", aa);
\r
781 //update the palette~
\r
782 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
785 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
790 modexPalUpdate1(byte *p)
\r
793 //modexWaitBorder();
\r
794 vga_wait_for_vsync();
\r
795 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
796 for(i=0; i<PAL_SIZE/2; i++)
\r
798 outp(PAL_DATA_REG, p[i]);
\r
800 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
801 vga_wait_for_vsync();
\r
802 for(; i<PAL_SIZE; i++)
\r
804 outp(PAL_DATA_REG, p[(i)]);
\r
809 modexPalUpdate0(byte *p)
\r
812 //modexWaitBorder();
\r
813 vga_wait_for_vsync();
\r
814 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
815 for(i=0; i<PAL_SIZE/2; i++)
\r
817 outp(PAL_DATA_REG, rand());
\r
819 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
820 vga_wait_for_vsync();
\r
821 for(; i<PAL_SIZE; i++)
\r
823 outp(PAL_DATA_REG, rand());
\r
828 modexPalOverscan(byte *p, word col)
\r
830 //modexWaitBorder();
\r
831 vga_wait_for_vsync();
\r
832 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
833 outp(PAL_DATA_REG, col);
\r
837 //i want to make another vesion that checks the palette when the palette is being appened~
\r
838 void modexchkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
842 pal = modexNewPal();
\r
844 //printf("q: %02d\n", (*q));
\r
845 printf("chkcolor start~\n");
\r
846 printf("1 (*z): %d\n", (*z)/3);
\r
847 printf("1 (*i): %d\n", (*i)/3);
\r
848 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
849 printf("wwwwwwwwwwwwwwww\n");
\r
850 //check palette for dups
\r
851 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
853 //printf("\n z: %d\n", (*z));
\r
854 //printf(" q: %d\n", (*q));
\r
855 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
858 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
861 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
862 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
866 else for(zz=0; zz<(*q); zz+=3)
\r
868 //printf("zz: %02d\n", zz/3);
\r
871 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
875 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
876 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
879 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
881 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
882 // 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
883 // 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
884 // //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
885 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
890 planned features that i plan to implement~
\r
891 image that has values on the pallete list!
\r
893 no... wait.... no wwww
\r
895 //for(zzii=0; zzii<3; zzii++)
\r
897 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
898 a[(((*z)+(*q)))]=zz;
\r
900 (*aa)=(((*z)+(*q)));
\r
901 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
902 // printf("\n aa: %d\n\n", (*aa));
\r
903 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
904 // printf("wwwwwwwwwwwwwwww\n\n");
\r
908 printf("================\n");
\r
909 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
910 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
911 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
912 printf("================\n");
\r
914 //printf("[%d]", (zz+q));
\r
918 printf("wwwwwwwwwwwwwwww\n");
\r
919 printf("2 (*z): %d\n", (*z)/3);
\r
920 printf("2 (*i): %d\n", (*i)/3);
\r
921 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
922 printf("chkcolor end~\n");
\r
926 void modexputPixel(page_t *page, int x, int y, byte color)
\r
928 word pageOff = (word) page->data;
\r
929 /* Each address accesses four neighboring pixels, so set
\r
930 Write Plane Enable according to which pixel we want
\r
931 to modify. The plane is determined by the two least
\r
932 significant bits of the x-coordinate: */
\r
933 modexSelectPlane(PLANE(x));
\r
934 //outp(SC_INDEX, 0x02);
\r
935 //outp(SC_DATA, 0x01 << (x & 3));
\r
937 /* The offset of the pixel into the video segment is
\r
938 offset = (width * y + x) / 4, and write the given
\r
939 color to the plane we selected above. Heed the active
\r
940 page start selection. */
\r
941 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
945 byte modexgetPixel(page_t *page, int x, int y)
\r
947 word pageOff = (word) page->data;
\r
948 /* Select the plane from which we must read the pixel color: */
\r
949 outpw(GC_INDEX, 0x04);
\r
950 outpw(GC_INDEX+1, x & 3);
\r
952 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
956 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
960 word addr = (word) romFontsData.l;
\r
961 word addrq = (page->width/4) * y + (x / 4) + ((word)page->data);
\r
962 word addrr = addrq;
\r
967 w=romFonts[t].charSize;
\r
968 romFontsData.chw=0;
\r
970 for(; *str != '\0'; str++)
\r
976 romFontsData.chw = 0;
\r
977 addrq += (page->width / 4) * 8;
\r
983 // load the character into romFontsData.l
\r
984 // no need for inline assembly!
\r
985 // NTS: It might even be faster to just let the modexDrawChar point directly at ROM font than to copy per char! --J.C.
\r
986 _fmemcpy(romFontsData.l,MK_FP(s,o+(w*c))/*ROM font location*/,w/*char size*/);
\r
987 modexDrawChar(page, x_draw/*for mode X planar use*/, t, col, bgcol, addrr);
\r
988 x_draw += 8; /* track X for edge of screen */
\r
989 addrr += 2; /* move 8 pixels over (2 x 4 planar pixels per byte) */
\r
993 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
995 word i, s, o, w, j, xp;
\r
997 word addr = (word) l;
\r
1021 s=romFonts[t].seg;
\r
1022 o=romFonts[t].off;
\r
1024 for(; *str != '\0'; str++)
\r
1027 if((c=='\n'/* || c=="\
\r
1028 "*/)/* || chw>=page->width*/)
\r
1034 //load the letter 'A'
\r
1049 MOV AL, c ; the letter
\r
1052 ADD SI, AX ;the address of charcter
\r
1070 for(i=0; i<w; i++)
\r
1076 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1077 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1086 /* palette dump on display! */
\r
1087 void modexpdump(page_t *pee)
\r
1089 int mult=(QUADWH);
\r
1090 int palq=(mult)*TILEWH;
\r
1093 for(paly=0; paly<palq; paly+=mult){
\r
1094 for(palx=0; palx<palq; palx+=mult){
\r
1095 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
\r
1101 /////////////////////////////////////////////////////////////////////////////
\r
1103 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1104 // the Virtual screen. //
\r
1106 /////////////////////////////////////////////////////////////////////////////
\r
1107 void modexcls(page_t *page, byte color, byte *Where)
\r
1109 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1110 /* set map mask to all 4 planes */
\r
1111 outpw(SC_INDEX, 0xff02);
\r
1112 //_fmemset(VGA, color, 16000);
\r
1113 _fmemset(Where, color, page->width*(page->height)/4);
\r
1117 modexWaitBorder() {
\r
1118 while(inp(INPUT_STATUS_1) & 8) {
\r
1122 // while(!(inp(INPUT_STATUS_1) & 8)) {
\r
1132 m = int10_getmode();
\r
1133 if ((rp=vga_state.vga_graphics_ram) != NULL && !(m <= 3 || m == 7)) {
\r
1134 unsigned int i,im;
\r
1136 im = (FP_SEG(vga_state.vga_graphics_ram_fence) - FP_SEG(vga_state.vga_graphics_ram));
\r
1137 if (im > 0xFFE) im = 0xFFE;
\r
1139 for (i=0;i < im;i++) vga_state.vga_graphics_ram[i] = 0;
\r
1141 else if ((ap=vga_state.vga_alpha_ram) != NULL) {
\r
1142 unsigned int i,im;
\r
1144 im = (FP_SEG(vga_state.vga_alpha_ram_fence) - FP_SEG(vga_state.vga_alpha_ram));
\r
1145 if (im > 0x7FE) im = 0x7FE;
\r
1146 im <<= 4 - 1; /* because ptr is type uint16_t */
\r
1147 for (i=0;i < im;i++) vga_state.vga_alpha_ram[i] = 0x0720;
\r
1150 printf("WARNING: bios cls no ptr\n");
\r
1154 void modexprintmeminfo(video_t *v)
\r
1157 printf("video memory remaining: %u\n", v->vmem_remain);
\r
1159 for(i=0; i<v->num_of_pages;i++)
\r
1161 printf(" [%u]=", i);
\r
1162 printf("(%Fp)", (v->page[i].data));
\r
1163 printf(" size=%u", v->page[i].pagesize);
\r
1164 printf(" sw=%lu sh=%lu ", (unsigned long)v->page[i].sw, (unsigned long)v->page[i].sh);
\r
1165 printf(" width=%lu height=%lu", (unsigned long)v->page[i].width, (unsigned long)v->page[i].height);
\r