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 outpw(SC_INDEX, 0x0f02);
\r
205 for(i=0; i<0x8000; i++) {
\r
210 gv->video.page[0].tilesw = gv->video.page[0].sw/TILEWH;
\r
211 gv->video.page[0].tilesh = gv->video.page[0].sh/TILEWH;
\r
212 //TODO MAKE FLEXIBLE~
\r
213 gv->video.page[0].tilemidposscreenx = gv->video.page[0].tilesw;
\r
214 gv->video.page[0].tilemidposscreeny = (gv->video.page[0].tilesh/2)+1;
\r
215 #define PAGE_SIZE (word)(gv->video.page[0].sw/4 * gv->video.page[0].sh)
\r
220 /* TODO restore original mode and palette */
\r
221 vgaSetMode(TEXT_MODE);
\r
224 // setBaseXMode() does the initialization to make the VGA ready to
\r
225 // accept any combination of configuration register settings. This
\r
226 // involves enabling writes to index 0 to 7 of the CRT controller (port
\r
227 // 0x3D4), by clearing the most significant bit (bit 7) of index 0x11.
\r
229 modexsetBaseXMode()
\r
231 /* TODO save current video mode and palette */
\r
232 vgaSetMode(VGA_256_COLOR_MODE);
\r
233 vga_enable_256color_modex();
\r
234 update_state_from_vga();
\r
238 modexDefaultPage(page_t *p)
\r
242 /* default page values */
\r
248 page.width = p->sw;
\r
249 page.height = p->sh;
\r
250 page.tw = page.sw/TILEWH;
\r
251 page.th = page.sh/TILEWH;
\r
252 page.tilemidposscreenx = page.tw/2;
\r
253 page.tilemidposscreeny = (page.th/2)+1;
\r
254 page.tilesw=p->tilesw;
\r
255 page.tilesh=p->tilesh;
\r
256 //pageSize = p->sw*p->sh;
\r
262 /* returns the next page in contiguous memory
\r
263 * the next page will be the same size as p, by default
\r
266 modexNextPage(page_t *p) {
\r
269 result.data = p->data + (p->width/4)*p->height;
\r
272 result.width = p->width;
\r
273 result.height = p->height;
\r
274 result.tw = p->width/TILEWH;
\r
275 result.th = p->height/TILEWH;
\r
276 result.id = p->id+1;
\r
279 // return modexNextPageFlexibleSize(&p, p->width, p->height);
\r
282 //next page with defined dimentions~
\r
284 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
288 result.data = p->data + (p->width/4)*p->height; /* compute the offset */
\r
293 result.tw = p->width/TILEWH;
\r
294 result.th = p->height/TILEWH;
\r
295 result.id = p->id+1;
\r
302 modexShowPage(page_t *page) {
\r
308 /* calculate offset */
\r
309 offset = (word) page->data;
\r
310 offset += page->dy * (page->width >> 2 );
\r
311 offset += page->dx >> 2;
\r
313 /* calculate crtcOffset according to virtual width */
\r
314 crtcOffset = page->width >> 3;
\r
316 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
317 low_address = LOW_ADDRESS | (offset << 8);
\r
319 /* wait for appropriate timing and then program CRTC */
\r
320 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
321 outpw(CRTC_INDEX, high_address);
\r
322 outpw(CRTC_INDEX, low_address);
\r
323 outp(CRTC_INDEX, 0x13);
\r
324 outp(CRTC_DATA, crtcOffset);
\r
326 /* wait for one retrace */
\r
327 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
329 /* do PEL panning here */
\r
330 outp(AC_INDEX, 0x33);
\r
331 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
336 modexPanPage(page_t *page, int dx, int dy) {
\r
343 modexSelectPlane(byte plane) {
\r
344 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
345 outp(SC_DATA, plane);
\r
350 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
351 word pageOff = (word) page->data;
\r
352 word xoff=x/4; /* xoffset that begins each row */
\r
353 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
354 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
355 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
356 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
357 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
358 byte left = lclip[x&0x03];
\r
359 byte right = rclip[(x+w)&0x03];
\r
361 /* handle the case which requires an extra group */
\r
362 if((x & 0x03) && !((x+w) & 0x03)) {
\r
367 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
369 MOV DI, poffset ; go to the first pixel
\r
370 MOV DX, SC_INDEX ; point to the map mask
\r
374 MOV AL, color ; get ready to write colors
\r
376 MOV CX, scanCount ; count the line
\r
377 MOV BL, AL ; remember color
\r
378 MOV AL, left ; do the left clip
\r
379 OUT DX, AL ; set the left clip
\r
380 MOV AL, BL ; restore color
\r
381 STOSB ; write the color
\r
383 JZ SCAN_DONE ; handle 1 group stuff
\r
385 ;-- write the main body of the scanline
\r
386 MOV BL, AL ; remember color
\r
387 MOV AL, 0x0f ; write to all pixels
\r
389 MOV AL, BL ; restore color
\r
390 REP STOSB ; write the color
\r
392 MOV BL, AL ; remeber color
\r
394 OUT DX, AL ; do the right clip
\r
395 MOV AL, BL ; restore color
\r
396 STOSB ; write pixel
\r
397 ADD DI, nextRow ; go to the next row
\r
403 /* moved to src/lib/modex16/16render.c */
\r
405 /* copy a region of video memory from one page to another.
\r
406 * It assumes that the left edge of the tile is the same on both
\r
407 * regions and the memory areas do not overlap.
\r
410 modexCopyPageRegion(page_t *dest, page_t *src,
\r
413 word width, word height)
\r
415 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
416 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
417 word scans = width/4;
\r
418 word nextSrcRow = src->width/4 - scans - 1;
\r
419 word nextDestRow = dest->width/4 - scans - 1;
\r
420 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
421 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
422 byte left = lclip[sx&0x03];
\r
423 byte right = rclip[(sx+width)&0x03];
\r
426 MOV AX, SCREEN_SEG ; work in the vga space
\r
431 MOV DX, GC_INDEX ; turn off cpu bits
\r
435 MOV AX, SC_INDEX ; point to the mask register
\r
445 MOV CX, scans ; the number of latches
\r
447 MOV AL, left ; do the left column
\r
452 MOV AL, 0fh ; do the inner columns
\r
454 REP MOVSB ; copy the pixels
\r
456 MOV AL, right ; do the right column
\r
461 MOV AX, SI ; go the start of the next row
\r
462 ADD AX, nextSrcRow ;
\r
465 ADD AX, nextDestRow ;
\r
468 DEC height ; do the rest of the actions
\r
471 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
472 MOV AL, 0ffh ; none from latches
\r
478 /* fade and flash */
\r
480 modexFadeOn(word fade, byte *palette) {
\r
481 fadePalette(-fade, 64, 64/fade+1, palette);
\r
486 modexFadeOff(word fade, byte *palette) {
\r
487 fadePalette(fade, 0, 64/fade+1, palette);
\r
492 modexFlashOn(word fade, byte *palette) {
\r
493 fadePalette(fade, -64, 64/fade+1, palette);
\r
498 modexFlashOff(word fade, byte *palette) {
\r
499 fadePalette(-fade, 0, 64/fade+1, palette);
\r
504 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
508 /* handle the case where we just update */
\r
510 modexPalUpdate1(palette);
\r
514 while(iter > 0) { /* FadeLoop */
\r
515 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
516 tmppal[i] = palette[i] - dim;
\r
517 if(tmppal[i] > 127) {
\r
519 } else if(tmppal[i] > 63) {
\r
523 modexPalUpdate1(tmppal);
\r
530 /* save and load */
\r
532 modexPalSave(byte *palette) {
\r
535 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
536 for(i=0; i<PAL_SIZE; i++) {
\r
537 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
545 ptr = malloc(PAL_SIZE);
\r
547 /* handle errors */
\r
549 printf("Could not allocate palette.\n");
\r
558 modexLoadPalFile(byte *filename, byte **palette) {
\r
562 /* free the palette if it exists */
\r
567 /* allocate the new palette */
\r
568 *palette = modexNewPal();
\r
570 /* open the file */
\r
571 file = fopen(filename, "rb");
\r
573 printf("Could not open palette file: %s\n", filename);
\r
577 /* read the file */
\r
579 while(!feof(file)) {
\r
580 *ptr++ = fgetc(file);
\r
588 modexSavePalFile(char *filename, byte *pal) {
\r
592 /* open the file for writing */
\r
593 file = fopen(filename, "wb");
\r
595 printf("Could not open %s for writing\n", filename);
\r
599 /* write the data to the file */
\r
600 fwrite(pal, 1, PAL_SIZE, file);
\r
608 fadePalette(-1, 64, 1, tmppal);
\r
614 fadePalette(-1, -64, 1, tmppal);
\r
620 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
622 byte *p = bmp->palette;
\r
626 static word a[PAL_SIZE]; //palette array of change values!
\r
627 word z=0, aq=0, aa=0, pp=0;
\r
632 memset(a, -1, sizeof(a));
\r
633 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
643 // printf("q: %02d\n", (q));
\r
644 // printf("qq: %02d\n", (qq));
\r
645 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
646 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
648 if((*i)<PAL_SIZE/2 && w==0)
\r
650 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
652 //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
653 //____ 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
654 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
659 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
661 //printf("qp=%d\n", qp);
\r
662 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
663 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
664 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
665 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
669 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
671 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
672 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
673 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
676 //if(qp>0) printf("qp=%d\n", qp);
\r
677 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
679 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
680 if((*i)>=PAL_SIZE/2 && w==0)
\r
682 for(; (*i)<PAL_SIZE; (*i)++)
\r
684 //____ 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
685 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
690 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
692 //printf("qp=%d\n", qp);
\r
693 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
694 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
695 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
696 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
700 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
701 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
702 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
705 //printf(" (*i)=%d\n", (*i)/3);
\r
708 printf("\nqqqqqqqq\n\n");
\r
714 long bufSize = (bmp->width * bmp->height);
\r
716 //printf("1(*i)=%02d\n", (*i)/3);
\r
717 //printf("1z=%02d\n", z/3);
\r
718 chkcolor(bmp, &q, &a, &aa, &z, i);
\r
719 //printf("2(*i)=%02d\n", (*i)/3);
\r
720 //printf("2z=%02d\n", z/3);
\r
725 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
726 if(a[aq]==-1) aq++;
\r
727 else { aqoffset++; break; }
\r
729 //update the image data here!
\r
730 for(lq=0; lq<bufSize; lq++)
\r
734 use a[qp] instead of bmp->offset for this spot!
\r
739 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
742 //(offset/bmp->offset)*bmp->offset
\r
745 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
746 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
747 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
748 /*if(bmp->data[lq]+bmp->offset==aq)
\r
750 //printf("%02d", bmp->data[lq]);
\r
751 //printf("\n%02d\n", bmp->offset);
\r
752 printf("aq=%02d ", aq);
\r
753 printf("a[aq]=%02d ", a[aq]);
\r
754 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
755 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
756 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
757 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
758 // printf("_%d ", bmp->data[lq]);
\r
759 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
761 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
763 if(bmp->data[lq]+bmp->offset >= aq)
\r
765 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
766 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
768 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
771 //printf("%02d`", bmp->data[lq]);
\r
772 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
775 //printf(" aq=%02d\n", aq);
\r
776 //printf(" aa=%02d\n", aa);
\r
778 //update the palette~
\r
779 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
782 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
787 modexPalUpdate1(byte *p)
\r
791 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
792 for(i=0; i<PAL_SIZE/2; i++)
\r
794 outp(PAL_DATA_REG, p[i]);
\r
796 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
797 for(; i<PAL_SIZE; i++)
\r
799 outp(PAL_DATA_REG, p[(i)]);
\r
804 modexPalUpdate0(byte *p)
\r
808 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
809 for(i=0; i<PAL_SIZE/2; i++)
\r
811 outp(PAL_DATA_REG, rand());
\r
813 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
814 for(; i<PAL_SIZE; i++)
\r
816 outp(PAL_DATA_REG, rand());
\r
821 modexPalOverscan(byte *p, word col)
\r
824 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
825 outp(PAL_DATA_REG, col);
\r
829 //i want to make another vesion that checks the palette when the palette is being appened~
\r
830 void chkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
834 pal = modexNewPal();
\r
836 //printf("q: %02d\n", (*q));
\r
837 printf("chkcolor start~\n");
\r
838 printf("1 (*z): %d\n", (*z)/3);
\r
839 printf("1 (*i): %d\n", (*i)/3);
\r
840 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
841 printf("wwwwwwwwwwwwwwww\n");
\r
842 //check palette for dups
\r
843 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
845 //printf("\n z: %d\n", (*z));
\r
846 //printf(" q: %d\n", (*q));
\r
847 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
850 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
853 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
854 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
858 else for(zz=0; zz<(*q); zz+=3)
\r
860 //printf("zz: %02d\n", zz/3);
\r
863 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
867 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
868 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
871 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
873 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
874 // 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
875 // 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
876 // //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
877 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
882 planned features that i plan to implement~
\r
883 image that has values on the pallete list!
\r
885 no... wait.... no wwww
\r
887 //for(zzii=0; zzii<3; zzii++)
\r
889 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
890 a[(((*z)+(*q)))]=zz;
\r
892 (*aa)=(((*z)+(*q)));
\r
893 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
894 // printf("\n aa: %d\n\n", (*aa));
\r
895 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
896 // printf("wwwwwwwwwwwwwwww\n\n");
\r
900 printf("================\n");
\r
901 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
902 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
903 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
904 printf("================\n");
\r
906 //printf("[%d]", (zz+q));
\r
910 printf("wwwwwwwwwwwwwwww\n");
\r
911 printf("2 (*z): %d\n", (*z)/3);
\r
912 printf("2 (*i): %d\n", (*i)/3);
\r
913 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
914 printf("chkcolor end~\n");
\r
918 void modexputPixel(page_t *page, int x, int y, byte color)
\r
920 word pageOff = (word) page->data;
\r
921 /* Each address accesses four neighboring pixels, so set
\r
922 Write Plane Enable according to which pixel we want
\r
923 to modify. The plane is determined by the two least
\r
924 significant bits of the x-coordinate: */
\r
925 modexSelectPlane(PLANE(x));
\r
926 //outp(SC_INDEX, 0x02);
\r
927 //outp(SC_DATA, 0x01 << (x & 3));
\r
929 /* The offset of the pixel into the video segment is
\r
930 offset = (width * y + x) / 4, and write the given
\r
931 color to the plane we selected above. Heed the active
\r
932 page start selection. */
\r
933 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
937 byte modexgetPixel(page_t *page, int x, int y)
\r
939 word pageOff = (word) page->data;
\r
940 /* Select the plane from which we must read the pixel color: */
\r
941 outpw(GC_INDEX, 0x04);
\r
942 outpw(GC_INDEX+1, x & 3);
\r
944 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
948 void modexhlin(page_t *page, word xl, word xh, word y, word color)
\r
953 for(x=0;x<xh*4;x+=4)
\r
955 if(x+4>=page[0].sw-1){ x=0; yy+=4; }
\r
956 modexClearRegion(page, x+xl, y+yy, 4, 4, color);
\r
958 //modexputPixel(page, x+xl, y, color);
\r
961 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str, boolean q)
\r
964 word addr = (word) romFontsData.l;
\r
969 w=romFonts[t].charSize;
\r
970 romFontsData.chw=0;
\r
972 for(; *str != '\0'; str++)
\r
975 if((c=='\n'/* || c=="\
\r
976 "*/) || romFontsData.chw
\r
979 romFontsData.chw=0;
\r
980 y+=romFonts[t].charSize;
\r
983 //load the letter 'A'
\r
989 MOV AL, c ; the letter
\r
992 ADD SI, AX ;the address of charcter
\r
1000 //TODO: OPTIMIZE THIS!!!!
\r
1001 modexDrawCharPBuf(page, x, y, t, col, bgcol, q);
\r
1007 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1009 word i, s, o, w, j, xp;
\r
1011 word addr = (word) l;
\r
1035 s=romFonts[t].seg;
\r
1036 o=romFonts[t].off;
\r
1038 for(; *str != '\0'; str++)
\r
1041 if((c=='\n'/* || c=="\
\r
1042 "*/)/* || chw>=page->width*/)
\r
1048 //load the letter 'A'
\r
1054 MOV AL, c ; the letter
\r
1057 ADD SI, AX ;the address of charcter
\r
1066 for(i=0; i<w; i++)
\r
1072 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1073 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1082 /* palette dump on display! */
\r
1083 void pdump(page_t *pee)
\r
1085 int mult=(QUADWH);
\r
1086 int palq=(mult)*TILEWH;
\r
1089 for(paly=0; paly<palq; paly+=mult){
\r
1090 for(palx=0; palx<palq; palx+=mult){
\r
1091 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
\r
1097 /////////////////////////////////////////////////////////////////////////////
\r
1099 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1100 // the Virtual screen. //
\r
1102 /////////////////////////////////////////////////////////////////////////////
\r
1103 void cls(page_t *page, byte color, byte *Where)
\r
1105 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1106 /* set map mask to all 4 planes */
\r
1107 outpw(SC_INDEX, 0xff02);
\r
1108 //_fmemset(VGA, color, 16000);
\r
1109 _fmemset(Where, color, page->width*(page->height)/4);
\r
1113 modexWaitBorder() {
\r
1114 while(inp(INPUT_STATUS_1) & 8) {
\r
1118 while(!(inp(INPUT_STATUS_1) & 8)) {
\r