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; /* CRTC[0] -5 */
\r
133 cm.horizontal_display_end=0x4f; /* CRTC[1] -1 */
\r
134 cm.horizontal_blank_start=0x50; /* CRTC[2] */
\r
135 cm.horizontal_blank_end=0x82; /* 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 = 525;
\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 = 489;
\r
145 cm.vertical_blank_end = 517;
\r
147 vga_write_crtc_mode(&cm,0);
\r
151 CRTParmCount = sizeof(ModeX_160x120regs) / sizeof(ModeX_160x120regs[0]);
\r
152 /* width and height */
\r
153 gv->video.page[0].sw=120;
\r
154 gv->video.page[0].sh=160;
\r
156 /* send the CRTParms */
\r
157 for(i=0; i<CRTParmCount; i++) {
\r
158 outpw(CRTC_INDEX, ModeX_160x120regs[i]);
\r
162 CRTParmCount = sizeof(ModeX_320x200regs) / sizeof(ModeX_320x200regs[0]);
\r
163 /* width and height */
\r
164 gv->video.page[0].sw=320;
\r
165 gv->video.page[0].sh=200;
\r
167 /* send the CRTParms */
\r
168 for(i=0; i<CRTParmCount; i++) {
\r
169 outpw(CRTC_INDEX, ModeX_320x200regs[i]);
\r
173 CRTParmCount = sizeof(ModeX_192x144regs) / sizeof(ModeX_192x144regs[0]);
\r
174 /* width and height */
\r
175 gv->video.page[0].sw=192;
\r
176 gv->video.page[0].sh=144;
\r
178 /* send the CRTParms */
\r
179 for(i=0; i<CRTParmCount; i++) {
\r
180 outpw(CRTC_INDEX, ModeX_192x144regs[i]);
\r
184 CRTParmCount = sizeof(ModeX_256x192regs) / sizeof(ModeX_256x192regs[0]);
\r
185 /* width and height */
\r
186 gv->video.page[0].sw=256;
\r
187 gv->video.page[0].sh=192;
\r
189 /* send the CRTParms */
\r
190 for(i=0; i<CRTParmCount; i++) {
\r
191 outpw(CRTC_INDEX, ModeX_256x192regs[i]);
\r
196 /* clear video memory */
\r
200 /* clear video memory */
\r
201 outpw(SC_INDEX, 0x0f02);
\r
202 for(i=0; i<0x8000; i++) {
\r
207 gv->video.page[0].tilesw = gv->video.page[0].sw/TILEWH;
\r
208 gv->video.page[0].tilesh = gv->video.page[0].sh/TILEWH;
\r
209 //TODO MAKE FLEXIBLE~
\r
210 gv->video.page[0].tilemidposscreenx = gv->video.page[0].tilesw;
\r
211 gv->video.page[0].tilemidposscreeny = (gv->video.page[0].tilesh/2)+1;
\r
212 #define PAGE_SIZE (word)(gv->video.page[0].sw/4 * gv->video.page[0].sh)
\r
217 /* TODO restore original mode and palette */
\r
218 vgaSetMode(TEXT_MODE);
\r
221 // setBaseXMode() does the initialization to make the VGA ready to
\r
222 // accept any combination of configuration register settings. This
\r
223 // involves enabling writes to index 0 to 7 of the CRT controller (port
\r
224 // 0x3D4), by clearing the most significant bit (bit 7) of index 0x11.
\r
226 modexsetBaseXMode()
\r
228 /* TODO save current video mode and palette */
\r
229 vgaSetMode(VGA_256_COLOR_MODE);
\r
231 vga_enable_256color_modex();
\r
233 /* disable chain4 mode */
\r
234 //outpw(SC_INDEX, 0x0604);
\r
236 /* synchronous reset while setting Misc Output */
\r
237 //outpw(SC_INDEX, 0x0100);
\r
239 /* select 25 MHz dot clock & 60 Hz scanning rate */
\r
240 outp(MISC_OUTPUT, 0xe3);
\r
242 /* undo reset (restart sequencer) */
\r
243 //outpw(SC_INDEX, 0x0300);
\r
245 /* reprogram the CRT controller */
\r
246 outp(CRTC_INDEX, 0x11); /* VSync End reg contains register write prot */
\r
247 // temp = inp(CRTC_DATA) & 0x7F;
\r
248 // outp(CRTC_INDEX, 0x11);
\r
249 outp(CRTC_DATA, 0x7f); /* get current write protect on varios regs */
\r
250 // outp(CRTC_DATA, temp); /* get current write protect on varios regs */
\r
251 update_state_from_vga();
\r
255 modexDefaultPage(page_t *p)
\r
259 /* default page values */
\r
265 page.width = p->sw;
\r
266 page.height = p->sh;
\r
267 page.tw = page.sw/TILEWH;
\r
268 page.th = page.sh/TILEWH;
\r
269 page.tilemidposscreenx = page.tw/2;
\r
270 page.tilemidposscreeny = (page.th/2)+1;
\r
271 page.tilesw=p->tilesw;
\r
272 page.tilesh=p->tilesh;
\r
273 //pageSize = p->sw*p->sh;
\r
279 /* returns the next page in contiguous memory
\r
280 * the next page will be the same size as p, by default
\r
283 modexNextPage(page_t *p) {
\r
286 result.data = p->data + (p->width/4)*p->height;
\r
289 result.width = p->width;
\r
290 result.height = p->height;
\r
291 result.tw = p->width/TILEWH;
\r
292 result.th = p->height/TILEWH;
\r
293 result.id = p->id+1;
\r
296 // return modexNextPageFlexibleSize(&p, p->width, p->height);
\r
299 //next page with defined dimentions~
\r
301 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
305 result.data = p->data + (p->width/4)*p->height; /* compute the offset */
\r
310 result.tw = p->width/TILEWH;
\r
311 result.th = p->height/TILEWH;
\r
312 result.id = p->id+1;
\r
319 modexShowPage(page_t *page) {
\r
325 /* calculate offset */
\r
326 offset = (word) page->data;
\r
327 offset += page->dy * (page->width >> 2 );
\r
328 offset += page->dx >> 2;
\r
330 /* calculate crtcOffset according to virtual width */
\r
331 crtcOffset = page->width >> 3;
\r
333 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
334 low_address = LOW_ADDRESS | (offset << 8);
\r
336 /* wait for appropriate timing and then program CRTC */
\r
337 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
338 outpw(CRTC_INDEX, high_address);
\r
339 outpw(CRTC_INDEX, low_address);
\r
340 outp(CRTC_INDEX, 0x13);
\r
341 outp(CRTC_DATA, crtcOffset);
\r
343 /* wait for one retrace */
\r
344 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
346 /* do PEL panning here */
\r
347 outp(AC_INDEX, 0x33);
\r
348 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
353 modexPanPage(page_t *page, int dx, int dy) {
\r
360 modexSelectPlane(byte plane) {
\r
361 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
362 outp(SC_DATA, plane);
\r
367 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
368 word pageOff = (word) page->data;
\r
369 word xoff=x/4; /* xoffset that begins each row */
\r
370 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
371 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
372 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
373 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
374 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
375 byte left = lclip[x&0x03];
\r
376 byte right = rclip[(x+w)&0x03];
\r
378 /* handle the case which requires an extra group */
\r
379 if((x & 0x03) && !((x+w) & 0x03)) {
\r
384 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
386 MOV DI, poffset ; go to the first pixel
\r
387 MOV DX, SC_INDEX ; point to the map mask
\r
391 MOV AL, color ; get ready to write colors
\r
393 MOV CX, scanCount ; count the line
\r
394 MOV BL, AL ; remember color
\r
395 MOV AL, left ; do the left clip
\r
396 OUT DX, AL ; set the left clip
\r
397 MOV AL, BL ; restore color
\r
398 STOSB ; write the color
\r
400 JZ SCAN_DONE ; handle 1 group stuff
\r
402 ;-- write the main body of the scanline
\r
403 MOV BL, AL ; remember color
\r
404 MOV AL, 0x0f ; write to all pixels
\r
406 MOV AL, BL ; restore color
\r
407 REP STOSB ; write the color
\r
409 MOV BL, AL ; remeber color
\r
411 OUT DX, AL ; do the right clip
\r
412 MOV AL, BL ; restore color
\r
413 STOSB ; write pixel
\r
414 ADD DI, nextRow ; go to the next row
\r
420 /* moved to src/lib/modex16/16render.c */
\r
422 /* copy a region of video memory from one page to another.
\r
423 * It assumes that the left edge of the tile is the same on both
\r
424 * regions and the memory areas do not overlap.
\r
427 modexCopyPageRegion(page_t *dest, page_t *src,
\r
430 word width, word height)
\r
432 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
433 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
434 word scans = width/4;
\r
435 word nextSrcRow = src->width/4 - scans - 1;
\r
436 word nextDestRow = dest->width/4 - scans - 1;
\r
437 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
438 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
439 byte left = lclip[sx&0x03];
\r
440 byte right = rclip[(sx+width)&0x03];
\r
443 MOV AX, SCREEN_SEG ; work in the vga space
\r
448 MOV DX, GC_INDEX ; turn off cpu bits
\r
452 MOV AX, SC_INDEX ; point to the mask register
\r
462 MOV CX, scans ; the number of latches
\r
464 MOV AL, left ; do the left column
\r
469 MOV AL, 0fh ; do the inner columns
\r
471 REP MOVSB ; copy the pixels
\r
473 MOV AL, right ; do the right column
\r
478 MOV AX, SI ; go the start of the next row
\r
479 ADD AX, nextSrcRow ;
\r
482 ADD AX, nextDestRow ;
\r
485 DEC height ; do the rest of the actions
\r
488 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
489 MOV AL, 0ffh ; none from latches
\r
495 /* fade and flash */
\r
497 modexFadeOn(word fade, byte *palette) {
\r
498 fadePalette(-fade, 64, 64/fade+1, palette);
\r
503 modexFadeOff(word fade, byte *palette) {
\r
504 fadePalette(fade, 0, 64/fade+1, palette);
\r
509 modexFlashOn(word fade, byte *palette) {
\r
510 fadePalette(fade, -64, 64/fade+1, palette);
\r
515 modexFlashOff(word fade, byte *palette) {
\r
516 fadePalette(-fade, 0, 64/fade+1, palette);
\r
521 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
525 /* handle the case where we just update */
\r
527 modexPalUpdate1(palette);
\r
531 while(iter > 0) { /* FadeLoop */
\r
532 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
533 tmppal[i] = palette[i] - dim;
\r
534 if(tmppal[i] > 127) {
\r
536 } else if(tmppal[i] > 63) {
\r
540 modexPalUpdate1(tmppal);
\r
547 /* save and load */
\r
549 modexPalSave(byte *palette) {
\r
552 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
553 for(i=0; i<PAL_SIZE; i++) {
\r
554 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
562 ptr = malloc(PAL_SIZE);
\r
564 /* handle errors */
\r
566 printf("Could not allocate palette.\n");
\r
575 modexLoadPalFile(byte *filename, byte **palette) {
\r
579 /* free the palette if it exists */
\r
584 /* allocate the new palette */
\r
585 *palette = modexNewPal();
\r
587 /* open the file */
\r
588 file = fopen(filename, "rb");
\r
590 printf("Could not open palette file: %s\n", filename);
\r
594 /* read the file */
\r
596 while(!feof(file)) {
\r
597 *ptr++ = fgetc(file);
\r
605 modexSavePalFile(char *filename, byte *pal) {
\r
609 /* open the file for writing */
\r
610 file = fopen(filename, "wb");
\r
612 printf("Could not open %s for writing\n", filename);
\r
616 /* write the data to the file */
\r
617 fwrite(pal, 1, PAL_SIZE, file);
\r
625 fadePalette(-1, 64, 1, tmppal);
\r
631 fadePalette(-1, -64, 1, tmppal);
\r
637 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
639 byte *p = bmp->palette;
\r
643 static word a[PAL_SIZE]; //palette array of change values!
\r
644 word z=0, aq=0, aa=0, pp=0;
\r
649 memset(a, -1, sizeof(a));
\r
650 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
660 // printf("q: %02d\n", (q));
\r
661 // printf("qq: %02d\n", (qq));
\r
662 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
663 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
665 if((*i)<PAL_SIZE/2 && w==0)
\r
667 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
669 //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
670 //____ 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
671 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
676 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
678 //printf("qp=%d\n", qp);
\r
679 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
680 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
681 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
682 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
686 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
688 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
689 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
690 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
693 //if(qp>0) printf("qp=%d\n", qp);
\r
694 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
696 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
697 if((*i)>=PAL_SIZE/2 && w==0)
\r
699 for(; (*i)<PAL_SIZE; (*i)++)
\r
701 //____ 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
702 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
707 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
709 //printf("qp=%d\n", qp);
\r
710 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
711 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
712 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
713 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
717 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
718 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
719 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
722 //printf(" (*i)=%d\n", (*i)/3);
\r
725 printf("\nqqqqqqqq\n\n");
\r
731 long bufSize = (bmp->width * bmp->height);
\r
733 //printf("1(*i)=%02d\n", (*i)/3);
\r
734 //printf("1z=%02d\n", z/3);
\r
735 chkcolor(bmp, &q, &a, &aa, &z, i);
\r
736 //printf("2(*i)=%02d\n", (*i)/3);
\r
737 //printf("2z=%02d\n", z/3);
\r
742 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
743 if(a[aq]==-1) aq++;
\r
744 else { aqoffset++; break; }
\r
746 //update the image data here!
\r
747 for(lq=0; lq<bufSize; lq++)
\r
751 use a[qp] instead of bmp->offset for this spot!
\r
756 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
759 //(offset/bmp->offset)*bmp->offset
\r
762 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
763 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
764 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
765 /*if(bmp->data[lq]+bmp->offset==aq)
\r
767 //printf("%02d", bmp->data[lq]);
\r
768 //printf("\n%02d\n", bmp->offset);
\r
769 printf("aq=%02d ", aq);
\r
770 printf("a[aq]=%02d ", a[aq]);
\r
771 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
772 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
773 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
774 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
775 // printf("_%d ", bmp->data[lq]);
\r
776 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
778 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
780 if(bmp->data[lq]+bmp->offset >= aq)
\r
782 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
783 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
785 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
788 //printf("%02d`", bmp->data[lq]);
\r
789 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
792 //printf(" aq=%02d\n", aq);
\r
793 //printf(" aa=%02d\n", aa);
\r
795 //update the palette~
\r
796 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
799 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
804 modexPalUpdate1(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, p[i]);
\r
813 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
814 for(; i<PAL_SIZE; i++)
\r
816 outp(PAL_DATA_REG, p[(i)]);
\r
821 modexPalUpdate0(byte *p)
\r
825 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
826 for(i=0; i<PAL_SIZE/2; i++)
\r
828 outp(PAL_DATA_REG, rand());
\r
830 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
831 for(; i<PAL_SIZE; i++)
\r
833 outp(PAL_DATA_REG, rand());
\r
838 modexPalOverscan(byte *p, word col)
\r
841 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
842 outp(PAL_DATA_REG, col);
\r
846 //i want to make another vesion that checks the palette when the palette is being appened~
\r
847 void chkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
851 pal = modexNewPal();
\r
853 //printf("q: %02d\n", (*q));
\r
854 printf("chkcolor start~\n");
\r
855 printf("1 (*z): %d\n", (*z)/3);
\r
856 printf("1 (*i): %d\n", (*i)/3);
\r
857 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
858 printf("wwwwwwwwwwwwwwww\n");
\r
859 //check palette for dups
\r
860 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
862 //printf("\n z: %d\n", (*z));
\r
863 //printf(" q: %d\n", (*q));
\r
864 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
867 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
870 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
871 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
875 else for(zz=0; zz<(*q); zz+=3)
\r
877 //printf("zz: %02d\n", zz/3);
\r
880 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
884 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
885 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
888 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
890 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
891 // 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
892 // 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
893 // //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
894 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
899 planned features that i plan to implement~
\r
900 image that has values on the pallete list!
\r
902 no... wait.... no wwww
\r
904 //for(zzii=0; zzii<3; zzii++)
\r
906 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
907 a[(((*z)+(*q)))]=zz;
\r
909 (*aa)=(((*z)+(*q)));
\r
910 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
911 // printf("\n aa: %d\n\n", (*aa));
\r
912 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
913 // printf("wwwwwwwwwwwwwwww\n\n");
\r
917 printf("================\n");
\r
918 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
919 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
920 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
921 printf("================\n");
\r
923 //printf("[%d]", (zz+q));
\r
927 printf("wwwwwwwwwwwwwwww\n");
\r
928 printf("2 (*z): %d\n", (*z)/3);
\r
929 printf("2 (*i): %d\n", (*i)/3);
\r
930 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
931 printf("chkcolor end~\n");
\r
935 void modexputPixel(page_t *page, int x, int y, byte color)
\r
937 word pageOff = (word) page->data;
\r
938 /* Each address accesses four neighboring pixels, so set
\r
939 Write Plane Enable according to which pixel we want
\r
940 to modify. The plane is determined by the two least
\r
941 significant bits of the x-coordinate: */
\r
942 modexSelectPlane(PLANE(x));
\r
943 //outp(SC_INDEX, 0x02);
\r
944 //outp(SC_DATA, 0x01 << (x & 3));
\r
946 /* The offset of the pixel into the video segment is
\r
947 offset = (width * y + x) / 4, and write the given
\r
948 color to the plane we selected above. Heed the active
\r
949 page start selection. */
\r
950 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
954 byte modexgetPixel(page_t *page, int x, int y)
\r
956 word pageOff = (word) page->data;
\r
957 /* Select the plane from which we must read the pixel color: */
\r
958 outpw(GC_INDEX, 0x04);
\r
959 outpw(GC_INDEX+1, x & 3);
\r
961 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
965 void modexhlin(page_t *page, word xl, word xh, word y, word color)
\r
970 for(x=0;x<xh*4;x+=4)
\r
972 if(x+4>=page[0].sw-1){ x=0; yy+=4; }
\r
973 modexClearRegion(page, x+xl, y+yy, 4, 4, color);
\r
975 //modexputPixel(page, x+xl, y, color);
\r
978 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str, boolean q)
\r
981 word addr = (word) romFontsData.l;
\r
986 w=romFonts[t].charSize;
\r
987 romFontsData.chw=0;
\r
989 for(; *str != '\0'; str++)
\r
992 if((c=='\n'/* || c=="\
\r
993 "*/) || romFontsData.chw
\r
996 romFontsData.chw=0;
\r
997 y+=romFonts[t].charSize;
\r
1000 //load the letter 'A'
\r
1006 MOV AL, c ; the letter
\r
1009 ADD SI, AX ;the address of charcter
\r
1017 //TODO: OPTIMIZE THIS!!!!
\r
1018 modexDrawCharPBuf(page, x, y, t, col, bgcol, q);
\r
1024 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1026 word i, s, o, w, j, xp;
\r
1028 word addr = (word) l;
\r
1052 s=romFonts[t].seg;
\r
1053 o=romFonts[t].off;
\r
1055 for(; *str != '\0'; str++)
\r
1058 if((c=='\n'/* || c=="\
\r
1059 "*/)/* || chw>=page->width*/)
\r
1065 //load the letter 'A'
\r
1071 MOV AL, c ; the letter
\r
1074 ADD SI, AX ;the address of charcter
\r
1083 for(i=0; i<w; i++)
\r
1089 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1090 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1099 /* palette dump on display! */
\r
1100 void pdump(page_t *pee)
\r
1102 int mult=(QUADWH);
\r
1103 int palq=(mult)*TILEWH;
\r
1106 for(paly=0; paly<palq; paly+=mult){
\r
1107 for(palx=0; palx<palq; palx+=mult){
\r
1108 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
\r
1114 /////////////////////////////////////////////////////////////////////////////
\r
1116 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1117 // the Virtual screen. //
\r
1119 /////////////////////////////////////////////////////////////////////////////
\r
1120 void cls(page_t *page, byte color, byte *Where)
\r
1122 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1123 /* set map mask to all 4 planes */
\r
1124 outpw(SC_INDEX, 0xff02);
\r
1125 //_fmemset(VGA, color, 16000);
\r
1126 _fmemset(Where, color, page->width*(page->height)/4);
\r
1130 modexWaitBorder() {
\r
1131 while(inp(INPUT_STATUS_1) & 8) {
\r
1135 while(!(inp(INPUT_STATUS_1) & 8)) {
\r