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
67 regs.h.ah = SET_MODE;
\r
69 int86(VIDEO_INT, ®s, ®s);
\r
72 //---------------------------------------------------
\r
74 // Use the bios to get the current video mode
\r
83 int86(VIDEO_INT, &rg, &rg);
\r
88 /* -========================= Entry Points ==========================- */
\r
89 void modexEnter(sword vq, boolean cmem, global_game_variables_t *gv)
\r
92 dword far*ptr=(dword far*)VGA; /* used for faster screen clearing */
\r
94 /* common mode X initiation stuff~ */
\r
95 modexsetBaseXMode(gv->video.page);
\r
96 vga_enable_256color_modex(); // VGA mode X
\r
97 update_state_from_vga();
\r
102 //CRTParmCount = sizeof(ModeX_320x240regs) / sizeof(ModeX_320x240regs[0]);
\r
103 /* width and height */
\r
104 gv->video.page[0].sw=vga_state.vga_width = 320; // VGA lib currently does not update this
\r
105 gv->video.page[0].sh=vga_state.vga_height = 240; // VGA lib currently does not update this
\r
107 /* send the CRTParms */
\r
108 /*for(i=0; i<CRTParmCount; i++) {
\r
109 outpw(CRTC_INDEX, ModeX_320x240regs[i]);
\r
112 struct vga_mode_params cm;
\r
113 vga_read_crtc_mode(&cm);
\r
115 // 320x240 mode 60Hz
\r
116 cm.vertical_total = 525;
\r
117 cm.vertical_start_retrace = 0x1EA;
\r
118 cm.vertical_end_retrace = 0x1EC;
\r
119 cm.vertical_display_end = 480;
\r
120 cm.vertical_blank_start = 489;
\r
121 cm.vertical_blank_end = 517;
\r
123 vga_write_crtc_mode(&cm,0);
\r
127 CRTParmCount = sizeof(ModeX_160x120regs) / sizeof(ModeX_160x120regs[0]);
\r
128 /* width and height */
\r
129 gv->video.page[0].sw=120;
\r
130 gv->video.page[0].sh=160;
\r
132 /* send the CRTParms */
\r
133 for(i=0; i<CRTParmCount; i++) {
\r
134 outpw(CRTC_INDEX, ModeX_160x120regs[i]);
\r
138 CRTParmCount = sizeof(ModeX_320x200regs) / sizeof(ModeX_320x200regs[0]);
\r
139 /* width and height */
\r
140 gv->video.page[0].sw=320;
\r
141 gv->video.page[0].sh=200;
\r
143 /* send the CRTParms */
\r
144 for(i=0; i<CRTParmCount; i++) {
\r
145 outpw(CRTC_INDEX, ModeX_320x200regs[i]);
\r
149 CRTParmCount = sizeof(ModeX_192x144regs) / sizeof(ModeX_192x144regs[0]);
\r
150 /* width and height */
\r
151 gv->video.page[0].sw=192;
\r
152 gv->video.page[0].sh=144;
\r
154 /* send the CRTParms */
\r
155 for(i=0; i<CRTParmCount; i++) {
\r
156 outpw(CRTC_INDEX, ModeX_192x144regs[i]);
\r
160 CRTParmCount = sizeof(ModeX_256x192regs) / sizeof(ModeX_256x192regs[0]);
\r
161 /* width and height */
\r
162 gv->video.page[0].sw=256;
\r
163 gv->video.page[0].sh=192;
\r
165 /* send the CRTParms */
\r
166 for(i=0; i<CRTParmCount; i++) {
\r
167 outpw(CRTC_INDEX, ModeX_256x192regs[i]);
\r
172 /* clear video memory */
\r
176 /* clear video memory */
\r
177 outpw(SC_INDEX, 0x0f02);
\r
178 for(i=0; i<0x8000; i++) {
\r
183 gv->video.page[0].tilesw = gv->video.page[0].sw/TILEWH;
\r
184 gv->video.page[0].tilesh = gv->video.page[0].sh/TILEWH;
\r
185 //TODO MAKE FLEXIBLE~
\r
186 gv->video.page[0].tilemidposscreenx = gv->video.page[0].tilesw;
\r
187 gv->video.page[0].tilemidposscreeny = (gv->video.page[0].tilesh/2)+1;
\r
188 #define PAGE_SIZE (word)(gv->video.page[0].sw/4 * gv->video.page[0].sh)
\r
193 /* TODO restore original mode and palette */
\r
194 vgaSetMode(TEXT_MODE);
\r
197 // setBaseXMode() does the initialization to make the VGA ready to
\r
198 // accept any combination of configuration register settings. This
\r
199 // involves enabling writes to index 0 to 7 of the CRT controller (port
\r
200 // 0x3D4), by clearing the most significant bit (bit 7) of index 0x11.
\r
202 modexsetBaseXMode(page_t *page)
\r
205 /* TODO save current video mode and palette */
\r
206 vgaSetMode(VGA_256_COLOR_MODE);
\r
208 /* disable chain4 mode */
\r
209 outpw(SC_INDEX, 0x0604);
\r
211 /* synchronous reset while setting Misc Output */
\r
212 outpw(SC_INDEX, 0x0100);
\r
214 /* select 25 MHz dot clock & 60 Hz scanning rate */
\r
215 outp(MISC_OUTPUT, 0xe3);
\r
217 /* undo reset (restart sequencer) */
\r
218 outpw(SC_INDEX, 0x0300);
\r
220 /* reprogram the CRT controller */
\r
221 outp(CRTC_INDEX, 0x11); /* VSync End reg contains register write prot */
\r
222 // temp = inp(CRTC_DATA) & 0x7F;
\r
223 // outp(CRTC_INDEX, 0x11);
\r
224 outp(CRTC_DATA, 0x7f); /* get current write protect on varios regs */
\r
225 // outp(CRTC_DATA, temp); /* get current write protect on varios regs */
\r
229 modexDefaultPage(page_t *p)
\r
233 /* default page values */
\r
239 page.width = p->sw;
\r
240 page.height = p->sh;
\r
241 page.tw = page.sw/TILEWH;
\r
242 page.th = page.sh/TILEWH;
\r
243 page.tilemidposscreenx = page.tw/2;
\r
244 page.tilemidposscreeny = (page.th/2)+1;
\r
245 page.tilesw=p->tilesw;
\r
246 page.tilesh=p->tilesh;
\r
247 //pageSize = p->sw*p->sh;
\r
253 /* returns the next page in contiguous memory
\r
254 * the next page will be the same size as p, by default
\r
257 modexNextPage(page_t *p) {
\r
260 result.data = p->data + (p->width/4)*p->height;
\r
263 result.width = p->width;
\r
264 result.height = p->height;
\r
265 result.tw = p->width/TILEWH;
\r
266 result.th = p->height/TILEWH;
\r
267 result.id = p->id+1;
\r
270 // return modexNextPageFlexibleSize(&p, p->width, p->height);
\r
273 //next page with defined dimentions~
\r
275 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
279 result.data = p->data + (p->width/4)*p->height; /* compute the offset */
\r
284 result.tw = p->width/TILEWH;
\r
285 result.th = p->height/TILEWH;
\r
286 result.id = p->id+1;
\r
293 modexShowPage(page_t *page) {
\r
299 /* calculate offset */
\r
300 offset = (word) page->data;
\r
301 offset += page->dy * (page->width >> 2 );
\r
302 offset += page->dx >> 2;
\r
304 /* calculate crtcOffset according to virtual width */
\r
305 crtcOffset = page->width >> 3;
\r
307 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
308 low_address = LOW_ADDRESS | (offset << 8);
\r
310 /* wait for appropriate timing and then program CRTC */
\r
311 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
312 outpw(CRTC_INDEX, high_address);
\r
313 outpw(CRTC_INDEX, low_address);
\r
314 outp(CRTC_INDEX, 0x13);
\r
315 outp(CRTC_DATA, crtcOffset);
\r
317 /* wait for one retrace */
\r
318 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
320 /* do PEL panning here */
\r
321 outp(AC_INDEX, 0x33);
\r
322 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
327 modexPanPage(page_t *page, int dx, int dy) {
\r
334 modexSelectPlane(byte plane) {
\r
335 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
336 outp(SC_DATA, plane);
\r
341 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
342 word pageOff = (word) page->data;
\r
343 word xoff=x/4; /* xoffset that begins each row */
\r
344 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
345 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
346 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
347 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
348 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
349 byte left = lclip[x&0x03];
\r
350 byte right = rclip[(x+w)&0x03];
\r
352 /* handle the case which requires an extra group */
\r
353 if((x & 0x03) && !((x+w) & 0x03)) {
\r
358 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
360 MOV DI, poffset ; go to the first pixel
\r
361 MOV DX, SC_INDEX ; point to the map mask
\r
365 MOV AL, color ; get ready to write colors
\r
367 MOV CX, scanCount ; count the line
\r
368 MOV BL, AL ; remember color
\r
369 MOV AL, left ; do the left clip
\r
370 OUT DX, AL ; set the left clip
\r
371 MOV AL, BL ; restore color
\r
372 STOSB ; write the color
\r
374 JZ SCAN_DONE ; handle 1 group stuff
\r
376 ;-- write the main body of the scanline
\r
377 MOV BL, AL ; remember color
\r
378 MOV AL, 0x0f ; write to all pixels
\r
380 MOV AL, BL ; restore color
\r
381 REP STOSB ; write the color
\r
383 MOV BL, AL ; remeber color
\r
385 OUT DX, AL ; do the right clip
\r
386 MOV AL, BL ; restore color
\r
387 STOSB ; write pixel
\r
388 ADD DI, nextRow ; go to the next row
\r
394 /* moved to src/lib/modex16/16render.c */
\r
396 /* copy a region of video memory from one page to another.
\r
397 * It assumes that the left edge of the tile is the same on both
\r
398 * regions and the memory areas do not overlap.
\r
401 modexCopyPageRegion(page_t *dest, page_t *src,
\r
404 word width, word height)
\r
406 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
407 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
408 word scans = width/4;
\r
409 word nextSrcRow = src->width/4 - scans - 1;
\r
410 word nextDestRow = dest->width/4 - scans - 1;
\r
411 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
412 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
413 byte left = lclip[sx&0x03];
\r
414 byte right = rclip[(sx+width)&0x03];
\r
417 MOV AX, SCREEN_SEG ; work in the vga space
\r
422 MOV DX, GC_INDEX ; turn off cpu bits
\r
426 MOV AX, SC_INDEX ; point to the mask register
\r
436 MOV CX, scans ; the number of latches
\r
438 MOV AL, left ; do the left column
\r
443 MOV AL, 0fh ; do the inner columns
\r
445 REP MOVSB ; copy the pixels
\r
447 MOV AL, right ; do the right column
\r
452 MOV AX, SI ; go the start of the next row
\r
453 ADD AX, nextSrcRow ;
\r
456 ADD AX, nextDestRow ;
\r
459 DEC height ; do the rest of the actions
\r
462 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
463 MOV AL, 0ffh ; none from latches
\r
469 /* fade and flash */
\r
471 modexFadeOn(word fade, byte *palette) {
\r
472 fadePalette(-fade, 64, 64/fade+1, palette);
\r
477 modexFadeOff(word fade, byte *palette) {
\r
478 fadePalette(fade, 0, 64/fade+1, palette);
\r
483 modexFlashOn(word fade, byte *palette) {
\r
484 fadePalette(fade, -64, 64/fade+1, palette);
\r
489 modexFlashOff(word fade, byte *palette) {
\r
490 fadePalette(-fade, 0, 64/fade+1, palette);
\r
495 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
499 /* handle the case where we just update */
\r
501 modexPalUpdate1(palette);
\r
505 while(iter > 0) { /* FadeLoop */
\r
506 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
507 tmppal[i] = palette[i] - dim;
\r
508 if(tmppal[i] > 127) {
\r
510 } else if(tmppal[i] > 63) {
\r
514 modexPalUpdate1(tmppal);
\r
521 /* save and load */
\r
523 modexPalSave(byte *palette) {
\r
526 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
527 for(i=0; i<PAL_SIZE; i++) {
\r
528 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
536 ptr = malloc(PAL_SIZE);
\r
538 /* handle errors */
\r
540 printf("Could not allocate palette.\n");
\r
549 modexLoadPalFile(byte *filename, byte **palette) {
\r
553 /* free the palette if it exists */
\r
558 /* allocate the new palette */
\r
559 *palette = modexNewPal();
\r
561 /* open the file */
\r
562 file = fopen(filename, "rb");
\r
564 printf("Could not open palette file: %s\n", filename);
\r
568 /* read the file */
\r
570 while(!feof(file)) {
\r
571 *ptr++ = fgetc(file);
\r
579 modexSavePalFile(char *filename, byte *pal) {
\r
583 /* open the file for writing */
\r
584 file = fopen(filename, "wb");
\r
586 printf("Could not open %s for writing\n", filename);
\r
590 /* write the data to the file */
\r
591 fwrite(pal, 1, PAL_SIZE, file);
\r
599 fadePalette(-1, 64, 1, tmppal);
\r
605 fadePalette(-1, -64, 1, tmppal);
\r
611 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
613 byte *p = bmp->palette;
\r
617 static word a[PAL_SIZE]; //palette array of change values!
\r
618 word z=0, aq=0, aa=0, pp=0;
\r
623 memset(a, -1, sizeof(a));
\r
624 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
634 // printf("q: %02d\n", (q));
\r
635 // printf("qq: %02d\n", (qq));
\r
636 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
637 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
639 if((*i)<PAL_SIZE/2 && w==0)
\r
641 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
643 //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
644 //____ 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
645 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
650 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
652 //printf("qp=%d\n", qp);
\r
653 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
654 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
655 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
656 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
660 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
662 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
663 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
664 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
667 //if(qp>0) printf("qp=%d\n", qp);
\r
668 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
670 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
671 if((*i)>=PAL_SIZE/2 && w==0)
\r
673 for(; (*i)<PAL_SIZE; (*i)++)
\r
675 //____ 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
676 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
681 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
683 //printf("qp=%d\n", qp);
\r
684 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
685 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
686 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
687 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
691 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
692 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
693 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
696 //printf(" (*i)=%d\n", (*i)/3);
\r
699 printf("\nqqqqqqqq\n\n");
\r
705 long bufSize = (bmp->width * bmp->height);
\r
707 //printf("1(*i)=%02d\n", (*i)/3);
\r
708 //printf("1z=%02d\n", z/3);
\r
709 chkcolor(bmp, &q, &a, &aa, &z, i);
\r
710 //printf("2(*i)=%02d\n", (*i)/3);
\r
711 //printf("2z=%02d\n", z/3);
\r
716 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
717 if(a[aq]==-1) aq++;
\r
718 else { aqoffset++; break; }
\r
720 //update the image data here!
\r
721 for(lq=0; lq<bufSize; lq++)
\r
725 use a[qp] instead of bmp->offset for this spot!
\r
730 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
733 //(offset/bmp->offset)*bmp->offset
\r
736 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
737 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
738 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
739 /*if(bmp->data[lq]+bmp->offset==aq)
\r
741 //printf("%02d", bmp->data[lq]);
\r
742 //printf("\n%02d\n", bmp->offset);
\r
743 printf("aq=%02d ", aq);
\r
744 printf("a[aq]=%02d ", a[aq]);
\r
745 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
746 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
747 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
748 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
749 // printf("_%d ", bmp->data[lq]);
\r
750 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
752 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
754 if(bmp->data[lq]+bmp->offset >= aq)
\r
756 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
757 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
759 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
762 //printf("%02d`", bmp->data[lq]);
\r
763 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
766 //printf(" aq=%02d\n", aq);
\r
767 //printf(" aa=%02d\n", aa);
\r
769 //update the palette~
\r
770 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
773 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
778 modexPalUpdate1(byte *p)
\r
782 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
783 for(i=0; i<PAL_SIZE/2; i++)
\r
785 outp(PAL_DATA_REG, p[i]);
\r
787 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
788 for(; i<PAL_SIZE; i++)
\r
790 outp(PAL_DATA_REG, p[(i)]);
\r
795 modexPalUpdate0(byte *p)
\r
799 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
800 for(i=0; i<PAL_SIZE/2; i++)
\r
802 outp(PAL_DATA_REG, rand());
\r
804 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
805 for(; i<PAL_SIZE; i++)
\r
807 outp(PAL_DATA_REG, rand());
\r
812 modexPalOverscan(byte *p, word col)
\r
815 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
816 outp(PAL_DATA_REG, col);
\r
820 //i want to make another vesion that checks the palette when the palette is being appened~
\r
821 void chkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
825 pal = modexNewPal();
\r
827 //printf("q: %02d\n", (*q));
\r
828 printf("chkcolor start~\n");
\r
829 printf("1 (*z): %d\n", (*z)/3);
\r
830 printf("1 (*i): %d\n", (*i)/3);
\r
831 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
832 printf("wwwwwwwwwwwwwwww\n");
\r
833 //check palette for dups
\r
834 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
836 //printf("\n z: %d\n", (*z));
\r
837 //printf(" q: %d\n", (*q));
\r
838 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
841 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
844 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
845 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
849 else for(zz=0; zz<(*q); zz+=3)
\r
851 //printf("zz: %02d\n", zz/3);
\r
854 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
858 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
859 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
862 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
864 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
865 // 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
866 // 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
867 // //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
868 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
873 planned features that i plan to implement~
\r
874 image that has values on the pallete list!
\r
876 no... wait.... no wwww
\r
878 //for(zzii=0; zzii<3; zzii++)
\r
880 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
881 a[(((*z)+(*q)))]=zz;
\r
883 (*aa)=(((*z)+(*q)));
\r
884 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
885 // printf("\n aa: %d\n\n", (*aa));
\r
886 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
887 // printf("wwwwwwwwwwwwwwww\n\n");
\r
891 printf("================\n");
\r
892 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
893 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
894 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
895 printf("================\n");
\r
897 //printf("[%d]", (zz+q));
\r
901 printf("wwwwwwwwwwwwwwww\n");
\r
902 printf("2 (*z): %d\n", (*z)/3);
\r
903 printf("2 (*i): %d\n", (*i)/3);
\r
904 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
905 printf("chkcolor end~\n");
\r
909 void modexputPixel(page_t *page, int x, int y, byte color)
\r
911 word pageOff = (word) page->data;
\r
912 /* Each address accesses four neighboring pixels, so set
\r
913 Write Plane Enable according to which pixel we want
\r
914 to modify. The plane is determined by the two least
\r
915 significant bits of the x-coordinate: */
\r
916 modexSelectPlane(PLANE(x));
\r
917 //outp(SC_INDEX, 0x02);
\r
918 //outp(SC_DATA, 0x01 << (x & 3));
\r
920 /* The offset of the pixel into the video segment is
\r
921 offset = (width * y + x) / 4, and write the given
\r
922 color to the plane we selected above. Heed the active
\r
923 page start selection. */
\r
924 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
928 byte modexgetPixel(page_t *page, int x, int y)
\r
930 word pageOff = (word) page->data;
\r
931 /* Select the plane from which we must read the pixel color: */
\r
932 outpw(GC_INDEX, 0x04);
\r
933 outpw(GC_INDEX+1, x & 3);
\r
935 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
939 void modexhlin(page_t *page, word xl, word xh, word y, word color)
\r
944 for(x=0;x<xh*4;x+=4)
\r
946 if(x+4>=page[0].sw-1){ x=0; yy+=4; }
\r
947 modexClearRegion(page, x+xl, y+yy, 4, 4, color);
\r
949 //modexputPixel(page, x+xl, y, color);
\r
952 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str, boolean q)
\r
955 word addr = (word) romFontsData.l;
\r
960 w=romFonts[t].charSize;
\r
961 romFontsData.chw=0;
\r
963 for(; *str != '\0'; str++)
\r
966 if((c=='\n'/* || c=="\
\r
967 "*/) || romFontsData.chw
\r
970 romFontsData.chw=0;
\r
971 y+=romFonts[t].charSize;
\r
974 //load the letter 'A'
\r
980 MOV AL, c ; the letter
\r
983 ADD SI, AX ;the address of charcter
\r
991 //TODO: OPTIMIZE THIS!!!!
\r
992 modexDrawCharPBuf(page, x, y, t, col, bgcol, q);
\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
1045 MOV AL, c ; the letter
\r
1048 ADD SI, AX ;the address of charcter
\r
1057 for(i=0; i<w; i++)
\r
1063 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1064 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1073 /* palette dump on display! */
\r
1074 void pdump(page_t *pee)
\r
1076 int mult=(QUADWH);
\r
1077 int palq=(mult)*TILEWH;
\r
1080 for(paly=0; paly<palq; paly+=mult){
\r
1081 for(palx=0; palx<palq; palx+=mult){
\r
1082 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
\r
1088 /////////////////////////////////////////////////////////////////////////////
\r
1090 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1091 // the Virtual screen. //
\r
1093 /////////////////////////////////////////////////////////////////////////////
\r
1094 void cls(page_t *page, byte color, byte *Where)
\r
1096 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1097 /* set map mask to all 4 planes */
\r
1098 outpw(SC_INDEX, 0xff02);
\r
1099 //_fmemset(VGA, color, 16000);
\r
1100 _fmemset(Where, color, page->width*(page->height)/4);
\r
1104 modexWaitBorder() {
\r
1105 while(inp(INPUT_STATUS_1) & 8) {
\r
1109 while(!(inp(INPUT_STATUS_1) & 8)) {
\r