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();
\r
100 //CRTParmCount = sizeof(ModeX_320x240regs) / sizeof(ModeX_320x240regs[0]);
\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
105 /* send the CRTParms */
\r
106 /*for(i=0; i<CRTParmCount; i++) {
\r
107 outpw(CRTC_INDEX, ModeX_320x240regs[i]);
\r
110 struct vga_mode_params cm;
\r
111 vga_read_crtc_mode(&cm);
\r
113 // 0x5f00, /* Horizontal total */
\r
114 // 0x4f01, /* horizontal display enable end */
\r
115 // 0x5002, /* Start horizontal blanking */
\r
116 // 0x8203, /* End horizontal blanking */
\r
117 // 0x5404, /* Start horizontal retrace */
\r
118 // 0x8005, /* End horizontal retrace */
\r
119 // 0x0d06, /* vertical total */
\r
120 // 0x3e07, /* overflow (bit 8 of vertical counts) */
\r
121 // 0x4109, /* cell height (2 to double-scan */
\r
122 // 0xea10, /* v sync start */
\r
123 // 0xac11, /* v sync end and protect cr0-cr7 */
\r
124 // 0xdf12, /* vertical displayed */
\r
125 // 0x2813, /* offset/logical width */
\r
126 // 0x0014, /* turn off dword mode */
\r
127 // 0xe715, /* v blank start */
\r
128 // 0x0616, /* v blank end */
\r
129 // 0xe317 /* turn on byte mode */
\r
131 // 320x240 mode 60Hz
\r
132 cm.horizontal_total=0x5f + 5; /* CRTC[0] -5 */
\r
133 cm.horizontal_display_end=0x4f + 1; /* CRTC[1] -1 */
\r
134 cm.horizontal_blank_start=0x50 + 1; /* CRTC[2] */
\r
135 cm.horizontal_blank_end=0x82 + 1; /* CRTC[3] bit 0-4 & CRTC[5] bit 7 */
\r
136 cm.horizontal_start_retrace=0x54;/* CRTC[4] */
\r
137 cm.horizontal_end_retrace=0x80; /* CRTC[5] bit 0-4 */
\r
138 //cm.horizontal_start_delay_after_total=0x3e; /* CRTC[3] bit 5-6 */
\r
139 //cm.horizontal_start_delay_after_retrace=0x41; /* CRTC[5] bit 5-6 */
\r
140 cm.vertical_total = 0x20D + 2;
\r
141 cm.vertical_start_retrace = 0x1EA;
\r
142 cm.vertical_end_retrace = 0x1EC;
\r
143 cm.vertical_display_end = 480;
\r
144 cm.vertical_blank_start = 0x1E7 + 1;
\r
145 cm.vertical_blank_end = 0x206 + 1;
\r
146 cm.clock_select = 0; /* misc register = 0xE3 25MHz */
\r
150 vga_write_crtc_mode(&cm,0);
\r
154 CRTParmCount = sizeof(ModeX_160x120regs) / sizeof(ModeX_160x120regs[0]);
\r
155 /* width and height */
\r
156 gv->video.page[0].sw=120;
\r
157 gv->video.page[0].sh=160;
\r
159 /* send the CRTParms */
\r
160 for(i=0; i<CRTParmCount; i++) {
\r
161 outpw(CRTC_INDEX, ModeX_160x120regs[i]);
\r
165 CRTParmCount = sizeof(ModeX_320x200regs) / sizeof(ModeX_320x200regs[0]);
\r
166 /* width and height */
\r
167 gv->video.page[0].sw=320;
\r
168 gv->video.page[0].sh=200;
\r
170 /* send the CRTParms */
\r
171 for(i=0; i<CRTParmCount; i++) {
\r
172 outpw(CRTC_INDEX, ModeX_320x200regs[i]);
\r
176 CRTParmCount = sizeof(ModeX_192x144regs) / sizeof(ModeX_192x144regs[0]);
\r
177 /* width and height */
\r
178 gv->video.page[0].sw=192;
\r
179 gv->video.page[0].sh=144;
\r
181 /* send the CRTParms */
\r
182 for(i=0; i<CRTParmCount; i++) {
\r
183 outpw(CRTC_INDEX, ModeX_192x144regs[i]);
\r
187 CRTParmCount = sizeof(ModeX_256x192regs) / sizeof(ModeX_256x192regs[0]);
\r
188 /* width and height */
\r
189 gv->video.page[0].sw=256;
\r
190 gv->video.page[0].sh=192;
\r
192 /* send the CRTParms */
\r
193 for(i=0; i<CRTParmCount; i++) {
\r
194 outpw(CRTC_INDEX, ModeX_256x192regs[i]);
\r
199 /* clear video memory */
\r
203 /* clear video memory */
\r
204 vga_write_sequencer(2/*map mask register*/,0xf/*all 4 planes*/);
\r
205 for(i=0; i<0x8000; i++) ptr[i] = 0x0000;
\r
208 gv->video.page[0].tilesw = gv->video.page[0].sw/TILEWH;
\r
209 gv->video.page[0].tilesh = gv->video.page[0].sh/TILEWH;
\r
210 //TODO MAKE FLEXIBLE~
\r
211 gv->video.page[0].tilemidposscreenx = gv->video.page[0].tilesw;
\r
212 gv->video.page[0].tilemidposscreeny = (gv->video.page[0].tilesh/2)+1;
\r
213 #define PAGE_SIZE (word)(gv->video.page[0].sw/4 * gv->video.page[0].sh)
\r
218 /* TODO restore original mode and palette */
\r
219 vgaSetMode(TEXT_MODE);
\r
222 // setBaseXMode() does the initialization to make the VGA ready to
\r
223 // accept any combination of configuration register settings. This
\r
224 // involves enabling writes to index 0 to 7 of the CRT controller (port
\r
225 // 0x3D4), by clearing the most significant bit (bit 7) of index 0x11.
\r
227 modexsetBaseXMode()
\r
229 /* TODO save current video mode and palette */
\r
230 vgaSetMode(VGA_256_COLOR_MODE);
\r
231 vga_enable_256color_modex();
\r
232 update_state_from_vga();
\r
236 modexDefaultPage(page_t *p)
\r
240 /* default page values */
\r
246 page.width = p->sw;
\r
247 page.height = p->sh;
\r
248 page.tw = page.sw/TILEWH;
\r
249 page.th = page.sh/TILEWH;
\r
250 page.tilemidposscreenx = page.tw/2;
\r
251 page.tilemidposscreeny = (page.th/2)+1;
\r
252 page.tilesw=p->tilesw;
\r
253 page.tilesh=p->tilesh;
\r
254 //pageSize = p->sw*p->sh;
\r
260 /* returns the next page in contiguous memory
\r
261 * the next page will be the same size as p, by default
\r
264 modexNextPage(page_t *p) {
\r
267 result.data = p->data + (p->width/4)*p->height;
\r
270 result.width = p->width;
\r
271 result.height = p->height;
\r
272 result.tw = p->width/TILEWH;
\r
273 result.th = p->height/TILEWH;
\r
274 result.id = p->id+1;
\r
277 // return modexNextPageFlexibleSize(&p, p->width, p->height);
\r
280 //next page with defined dimentions~
\r
282 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
286 result.data = p->data + (p->width/4)*p->height; /* compute the offset */
\r
291 result.tw = p->width/TILEWH;
\r
292 result.th = p->height/TILEWH;
\r
293 result.id = p->id+1;
\r
300 modexShowPage(page_t *page) {
\r
306 /* calculate offset */
\r
307 offset = (word) page->data;
\r
308 offset += page->dy * (page->width >> 2 );
\r
309 offset += page->dx >> 2;
\r
311 /* calculate crtcOffset according to virtual width */
\r
312 crtcOffset = page->width >> 3;
\r
314 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
315 low_address = LOW_ADDRESS | (offset << 8);
\r
317 /* wait for appropriate timing and then program CRTC */
\r
318 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
319 outpw(CRTC_INDEX, high_address);
\r
320 outpw(CRTC_INDEX, low_address);
\r
321 outp(CRTC_INDEX, 0x13);
\r
322 outp(CRTC_DATA, crtcOffset);
\r
324 /* wait for one retrace */
\r
325 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
327 /* do PEL panning here */
\r
328 outp(AC_INDEX, 0x33);
\r
329 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
334 modexPanPage(page_t *page, int dx, int dy) {
\r
341 modexSelectPlane(byte plane) {
\r
342 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
343 outp(SC_DATA, plane);
\r
348 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
349 word pageOff = (word) page->data;
\r
350 word xoff=x/4; /* xoffset that begins each row */
\r
351 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
352 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
353 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
354 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
355 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
356 byte left = lclip[x&0x03];
\r
357 byte right = rclip[(x+w)&0x03];
\r
359 /* handle the case which requires an extra group */
\r
360 if((x & 0x03) && !((x+w) & 0x03)) {
\r
365 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
367 MOV DI, poffset ; go to the first pixel
\r
368 MOV DX, SC_INDEX ; point to the map mask
\r
372 MOV AL, color ; get ready to write colors
\r
374 MOV CX, scanCount ; count the line
\r
375 MOV BL, AL ; remember color
\r
376 MOV AL, left ; do the left clip
\r
377 OUT DX, AL ; set the left clip
\r
378 MOV AL, BL ; restore color
\r
379 STOSB ; write the color
\r
381 JZ SCAN_DONE ; handle 1 group stuff
\r
383 ;-- write the main body of the scanline
\r
384 MOV BL, AL ; remember color
\r
385 MOV AL, 0x0f ; write to all pixels
\r
387 MOV AL, BL ; restore color
\r
388 REP STOSB ; write the color
\r
390 MOV BL, AL ; remeber color
\r
392 OUT DX, AL ; do the right clip
\r
393 MOV AL, BL ; restore color
\r
394 STOSB ; write pixel
\r
395 ADD DI, nextRow ; go to the next row
\r
401 /* moved to src/lib/modex16/16render.c */
\r
403 /* copy a region of video memory from one page to another.
\r
404 * It assumes that the left edge of the tile is the same on both
\r
405 * regions and the memory areas do not overlap.
\r
408 modexCopyPageRegion(page_t *dest, page_t *src,
\r
411 word width, word height)
\r
413 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
414 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
415 word scans = width/4;
\r
416 word nextSrcRow = src->width/4 - scans - 1;
\r
417 word nextDestRow = dest->width/4 - scans - 1;
\r
418 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
419 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
420 byte left = lclip[sx&0x03];
\r
421 byte right = rclip[(sx+width)&0x03];
\r
424 MOV AX, SCREEN_SEG ; work in the vga space
\r
429 MOV DX, GC_INDEX ; turn off cpu bits
\r
433 MOV AX, SC_INDEX ; point to the mask register
\r
443 MOV CX, scans ; the number of latches
\r
445 MOV AL, left ; do the left column
\r
450 MOV AL, 0fh ; do the inner columns
\r
452 REP MOVSB ; copy the pixels
\r
454 MOV AL, right ; do the right column
\r
459 MOV AX, SI ; go the start of the next row
\r
460 ADD AX, nextSrcRow ;
\r
463 ADD AX, nextDestRow ;
\r
466 DEC height ; do the rest of the actions
\r
469 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
470 MOV AL, 0ffh ; none from latches
\r
476 /* fade and flash */
\r
478 modexFadeOn(word fade, byte *palette) {
\r
479 fadePalette(-fade, 64, 64/fade+1, palette);
\r
484 modexFadeOff(word fade, byte *palette) {
\r
485 fadePalette(fade, 0, 64/fade+1, palette);
\r
490 modexFlashOn(word fade, byte *palette) {
\r
491 fadePalette(fade, -64, 64/fade+1, palette);
\r
496 modexFlashOff(word fade, byte *palette) {
\r
497 fadePalette(-fade, 0, 64/fade+1, palette);
\r
502 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
506 /* handle the case where we just update */
\r
508 modexPalUpdate1(palette);
\r
512 while(iter > 0) { /* FadeLoop */
\r
513 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
514 tmppal[i] = palette[i] - dim;
\r
515 if(tmppal[i] > 127) {
\r
517 } else if(tmppal[i] > 63) {
\r
521 modexPalUpdate1(tmppal);
\r
528 /* save and load */
\r
530 modexPalSave(byte *palette) {
\r
533 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
534 for(i=0; i<PAL_SIZE; i++) {
\r
535 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
543 ptr = malloc(PAL_SIZE);
\r
545 /* handle errors */
\r
547 printf("Could not allocate palette.\n");
\r
556 modexLoadPalFile(byte *filename, byte **palette) {
\r
560 /* free the palette if it exists */
\r
565 /* allocate the new palette */
\r
566 *palette = modexNewPal();
\r
568 /* open the file */
\r
569 file = fopen(filename, "rb");
\r
571 printf("Could not open palette file: %s\n", filename);
\r
575 /* read the file */
\r
577 while(!feof(file)) {
\r
578 *ptr++ = fgetc(file);
\r
586 modexSavePalFile(char *filename, byte *pal) {
\r
590 /* open the file for writing */
\r
591 file = fopen(filename, "wb");
\r
593 printf("Could not open %s for writing\n", filename);
\r
597 /* write the data to the file */
\r
598 fwrite(pal, 1, PAL_SIZE, file);
\r
606 fadePalette(-1, 64, 1, tmppal);
\r
612 fadePalette(-1, -64, 1, tmppal);
\r
618 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
620 byte *p = bmp->palette;
\r
624 static word a[PAL_SIZE]; //palette array of change values!
\r
625 word z=0, aq=0, aa=0, pp=0;
\r
630 memset(a, -1, sizeof(a));
\r
631 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
641 // printf("q: %02d\n", (q));
\r
642 // printf("qq: %02d\n", (qq));
\r
643 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
644 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
646 if((*i)<PAL_SIZE/2 && w==0)
\r
648 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
650 //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
651 //____ 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
652 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
657 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
659 //printf("qp=%d\n", qp);
\r
660 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
661 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
662 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
663 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
667 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
669 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
670 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
671 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
674 //if(qp>0) printf("qp=%d\n", qp);
\r
675 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
677 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
678 if((*i)>=PAL_SIZE/2 && w==0)
\r
680 for(; (*i)<PAL_SIZE; (*i)++)
\r
682 //____ 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
683 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
688 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
690 //printf("qp=%d\n", qp);
\r
691 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
692 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
693 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
694 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
698 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
699 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
700 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
703 //printf(" (*i)=%d\n", (*i)/3);
\r
706 printf("\nqqqqqqqq\n\n");
\r
712 long bufSize = (bmp->width * bmp->height);
\r
714 //printf("1(*i)=%02d\n", (*i)/3);
\r
715 //printf("1z=%02d\n", z/3);
\r
716 chkcolor(bmp, &q, &a, &aa, &z, i);
\r
717 //printf("2(*i)=%02d\n", (*i)/3);
\r
718 //printf("2z=%02d\n", z/3);
\r
723 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
724 if(a[aq]==-1) aq++;
\r
725 else { aqoffset++; break; }
\r
727 //update the image data here!
\r
728 for(lq=0; lq<bufSize; lq++)
\r
732 use a[qp] instead of bmp->offset for this spot!
\r
737 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
740 //(offset/bmp->offset)*bmp->offset
\r
743 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
744 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
745 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
746 /*if(bmp->data[lq]+bmp->offset==aq)
\r
748 //printf("%02d", bmp->data[lq]);
\r
749 //printf("\n%02d\n", bmp->offset);
\r
750 printf("aq=%02d ", aq);
\r
751 printf("a[aq]=%02d ", a[aq]);
\r
752 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
753 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
754 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
755 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
756 // printf("_%d ", bmp->data[lq]);
\r
757 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
759 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
761 if(bmp->data[lq]+bmp->offset >= aq)
\r
763 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
764 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
766 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
769 //printf("%02d`", bmp->data[lq]);
\r
770 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
773 //printf(" aq=%02d\n", aq);
\r
774 //printf(" aa=%02d\n", aa);
\r
776 //update the palette~
\r
777 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
780 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
785 modexPalUpdate1(byte *p)
\r
789 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
790 for(i=0; i<PAL_SIZE/2; i++)
\r
792 outp(PAL_DATA_REG, p[i]);
\r
794 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
795 for(; i<PAL_SIZE; i++)
\r
797 outp(PAL_DATA_REG, p[(i)]);
\r
802 modexPalUpdate0(byte *p)
\r
806 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
807 for(i=0; i<PAL_SIZE/2; i++)
\r
809 outp(PAL_DATA_REG, rand());
\r
811 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
812 for(; i<PAL_SIZE; i++)
\r
814 outp(PAL_DATA_REG, rand());
\r
819 modexPalOverscan(byte *p, word col)
\r
822 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
823 outp(PAL_DATA_REG, col);
\r
827 //i want to make another vesion that checks the palette when the palette is being appened~
\r
828 void chkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
832 pal = modexNewPal();
\r
834 //printf("q: %02d\n", (*q));
\r
835 printf("chkcolor start~\n");
\r
836 printf("1 (*z): %d\n", (*z)/3);
\r
837 printf("1 (*i): %d\n", (*i)/3);
\r
838 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
839 printf("wwwwwwwwwwwwwwww\n");
\r
840 //check palette for dups
\r
841 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
843 //printf("\n z: %d\n", (*z));
\r
844 //printf(" q: %d\n", (*q));
\r
845 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
848 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
851 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
852 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
856 else for(zz=0; zz<(*q); zz+=3)
\r
858 //printf("zz: %02d\n", zz/3);
\r
861 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
865 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
866 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
869 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
871 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
872 // 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
873 // 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
874 // //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
875 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
880 planned features that i plan to implement~
\r
881 image that has values on the pallete list!
\r
883 no... wait.... no wwww
\r
885 //for(zzii=0; zzii<3; zzii++)
\r
887 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
888 a[(((*z)+(*q)))]=zz;
\r
890 (*aa)=(((*z)+(*q)));
\r
891 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
892 // printf("\n aa: %d\n\n", (*aa));
\r
893 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
894 // printf("wwwwwwwwwwwwwwww\n\n");
\r
898 printf("================\n");
\r
899 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
900 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
901 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
902 printf("================\n");
\r
904 //printf("[%d]", (zz+q));
\r
908 printf("wwwwwwwwwwwwwwww\n");
\r
909 printf("2 (*z): %d\n", (*z)/3);
\r
910 printf("2 (*i): %d\n", (*i)/3);
\r
911 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
912 printf("chkcolor end~\n");
\r
916 void modexputPixel(page_t *page, int x, int y, byte color)
\r
918 word pageOff = (word) page->data;
\r
919 /* Each address accesses four neighboring pixels, so set
\r
920 Write Plane Enable according to which pixel we want
\r
921 to modify. The plane is determined by the two least
\r
922 significant bits of the x-coordinate: */
\r
923 modexSelectPlane(PLANE(x));
\r
924 //outp(SC_INDEX, 0x02);
\r
925 //outp(SC_DATA, 0x01 << (x & 3));
\r
927 /* The offset of the pixel into the video segment is
\r
928 offset = (width * y + x) / 4, and write the given
\r
929 color to the plane we selected above. Heed the active
\r
930 page start selection. */
\r
931 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
935 byte modexgetPixel(page_t *page, int x, int y)
\r
937 word pageOff = (word) page->data;
\r
938 /* Select the plane from which we must read the pixel color: */
\r
939 outpw(GC_INDEX, 0x04);
\r
940 outpw(GC_INDEX+1, x & 3);
\r
942 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
946 void modexhlin(page_t *page, word xl, word xh, word y, word color)
\r
951 for(x=0;x<xh*4;x+=4)
\r
953 if(x+4>=page[0].sw-1){ x=0; yy+=4; }
\r
954 modexClearRegion(page, x+xl, y+yy, 4, 4, color);
\r
956 //modexputPixel(page, x+xl, y, color);
\r
959 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str, boolean q)
\r
962 word addr = (word) romFontsData.l;
\r
967 w=romFonts[t].charSize;
\r
968 romFontsData.chw=0;
\r
970 for(; *str != '\0'; str++)
\r
973 if((c=='\n'/* || c=="\
\r
974 "*/) || romFontsData.chw
\r
977 romFontsData.chw=0;
\r
978 y+=romFonts[t].charSize;
\r
981 //load the letter 'A'
\r
987 MOV AL, c ; the letter
\r
990 ADD SI, AX ;the address of charcter
\r
998 //TODO: OPTIMIZE THIS!!!!
\r
999 modexDrawCharPBuf(page, x, y, t, col, bgcol, q);
\r
1005 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1007 word i, s, o, w, j, xp;
\r
1009 word addr = (word) l;
\r
1033 s=romFonts[t].seg;
\r
1034 o=romFonts[t].off;
\r
1036 for(; *str != '\0'; str++)
\r
1039 if((c=='\n'/* || c=="\
\r
1040 "*/)/* || chw>=page->width*/)
\r
1046 //load the letter 'A'
\r
1052 MOV AL, c ; the letter
\r
1055 ADD SI, AX ;the address of charcter
\r
1064 for(i=0; i<w; i++)
\r
1070 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1071 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1080 /* palette dump on display! */
\r
1081 void pdump(page_t *pee)
\r
1083 int mult=(QUADWH);
\r
1084 int palq=(mult)*TILEWH;
\r
1087 for(paly=0; paly<palq; paly+=mult){
\r
1088 for(palx=0; palx<palq; palx+=mult){
\r
1089 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
\r
1095 /////////////////////////////////////////////////////////////////////////////
\r
1097 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1098 // the Virtual screen. //
\r
1100 /////////////////////////////////////////////////////////////////////////////
\r
1101 void cls(page_t *page, byte color, byte *Where)
\r
1103 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1104 /* set map mask to all 4 planes */
\r
1105 outpw(SC_INDEX, 0xff02);
\r
1106 //_fmemset(VGA, color, 16000);
\r
1107 _fmemset(Where, color, page->width*(page->height)/4);
\r
1111 modexWaitBorder() {
\r
1112 while(inp(INPUT_STATUS_1) & 8) {
\r
1116 while(!(inp(INPUT_STATUS_1) & 8)) {
\r