1 /* Project 16 Source Code~
\r
2 * Copyright (C) 2012-2015 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 version 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
34 /////////////////////////////////////////////////////////////////////////////
\r
36 // setvideo() - This function Manages the video modes //
\r
38 /////////////////////////////////////////////////////////////////////////////
\r
39 void VGAmodeX(sword vq, global_game_variables_t *gv)
\r
44 { // 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->old_mode;
\r
49 int86(0x10, &in, &out);
\r
54 // get old video mode
\r
56 int86(0x10, &in, &out);
\r
57 gv->old_mode = out.h.al;
\r
64 vgaSetMode(byte mode)
\r
68 regs.h.ah = SET_MODE;
\r
70 int86(VIDEO_INT, ®s, ®s);
\r
74 /* -========================= Entry Points ==========================- */
\r
78 dword far*ptr=(dword far*)VGA; /* used for faster screen clearing */
\r
80 0x0d06, /* vertical total */
\r
81 0x3e07, /* overflow (bit 8 of vertical counts) */
\r
82 0x4109, /* cell height (2 to double-scan */
\r
83 0xea10, /* v sync start */
\r
84 0xac11, /* v sync end and protect cr0-cr7 */
\r
85 0xdf12, /* vertical displayed */
\r
86 0x0014, /* turn off dword mode */
\r
87 0xe715, /* v blank start */
\r
88 0x0616, /* v blank end */
\r
89 0xe317 /* turn on byte mode */
\r
91 int CRTParmCount = sizeof(CRTParms) / sizeof(CRTParms[0]);
\r
93 /* TODO save current video mode and palette */
\r
94 vgaSetMode(VGA_256_COLOR_MODE);
\r
96 /* disable chain4 mode */
\r
97 outpw(SC_INDEX, 0x0604);
\r
99 /* synchronous reset while setting Misc Output */
\r
100 outpw(SC_INDEX, 0x0100);
\r
102 /* select 25 MHz dot clock & 60 Hz scanning rate */
\r
103 outp(MISC_OUTPUT, 0xe3);
\r
105 /* undo reset (restart sequencer) */
\r
106 outpw(SC_INDEX, 0x0300);
\r
108 /* reprogram the CRT controller */
\r
109 outp(CRTC_INDEX, 0x11); /* VSync End reg contains register write prot */
\r
110 outp(CRTC_DATA, 0x7f); /* get current write protect on varios regs */
\r
112 /* send the CRTParms */
\r
113 for(i=0; i<CRTParmCount; i++) {
\r
114 outpw(CRTC_INDEX, CRTParms[i]);
\r
117 /* clear video memory */
\r
118 outpw(SC_INDEX, 0x0f02);
\r
119 for(i=0; i<0x8000; i++) {
\r
127 /* TODO restore original mode and palette */
\r
128 vgaSetMode(TEXT_MODE);
\r
133 modexDefaultPage() {
\r
136 /* default page values */
\r
140 page.width = SCREEN_WIDTH;
\r
141 page.height = SCREEN_HEIGHT;
\r
142 page.tw = page.width/TILEWH;
\r
143 page.th = page.height/TILEWH;
\r
149 /* returns the next page in contiguous memory
\r
150 * the next page will be the same size as p, by default
\r
153 modexNextPage(page_t *p) {
\r
156 result.data = p->data + (p->width/4)*p->height;
\r
159 result.width = p->width;
\r
160 result.height = p->height;
\r
161 result.tw = p->width/TILEWH;
\r
162 result.th = p->height/TILEWH;
\r
163 result.id = p->id+1;
\r
166 // return modexNextPageFlexibleSize(&p, p->width, p->height);
\r
169 //next page with defined dimentions~
\r
171 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
175 result.data = p->data + (p->width/4)*p->height; /* compute the offset */
\r
180 result.tw = p->width/TILEWH;
\r
181 result.th = p->height/TILEWH;
\r
182 result.id = p->id+1;
\r
189 modexShowPage(page_t *page) {
\r
195 /* calculate offset */
\r
196 offset = (word) page->data;
\r
197 offset += page->dy * (page->width >> 2 );
\r
198 offset += page->dx >> 2;
\r
200 /* calculate crtcOffset according to virtual width */
\r
201 crtcOffset = page->width >> 3;
\r
203 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
204 low_address = LOW_ADDRESS | (offset << 8);
\r
206 /* wait for appropriate timing and then program CRTC */
\r
207 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
208 outpw(CRTC_INDEX, high_address);
\r
209 outpw(CRTC_INDEX, low_address);
\r
210 outp(CRTC_INDEX, 0x13);
\r
211 outp(CRTC_DATA, crtcOffset);
\r
213 /* wait for one retrace */
\r
214 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
216 /* do PEL panning here */
\r
217 outp(AC_INDEX, 0x33);
\r
218 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
223 modexPanPage(page_t *page, int dx, int dy) {
\r
230 modexSelectPlane(byte plane) {
\r
231 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
232 outp(SC_DATA, plane);
\r
237 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
238 word pageOff = (word) page->data;
\r
239 word xoff=x/4; /* xoffset that begins each row */
\r
240 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
241 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
242 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
243 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
244 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
245 byte left = lclip[x&0x03];
\r
246 byte right = rclip[(x+w)&0x03];
\r
248 /* handle the case which requires an extra group */
\r
249 if((x & 0x03) && !((x+w) & 0x03)) {
\r
254 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
256 MOV DI, poffset ; go to the first pixel
\r
257 MOV DX, SC_INDEX ; point to the map mask
\r
261 MOV AL, color ; get ready to write colors
\r
263 MOV CX, scanCount ; count the line
\r
264 MOV BL, AL ; remember color
\r
265 MOV AL, left ; do the left clip
\r
266 OUT DX, AL ; set the left clip
\r
267 MOV AL, BL ; restore color
\r
268 STOSB ; write the color
\r
270 JZ SCAN_DONE ; handle 1 group stuff
\r
272 ;-- write the main body of the scanline
\r
273 MOV BL, AL ; remember color
\r
274 MOV AL, 0x0f ; write to all pixels
\r
276 MOV AL, BL ; restore color
\r
277 REP STOSB ; write the color
\r
279 MOV BL, AL ; remeber color
\r
281 OUT DX, AL ; do the right clip
\r
282 MOV AL, BL ; restore color
\r
283 STOSB ; write pixel
\r
284 ADD DI, nextRow ; go to the next row
\r
292 oldDrawBmp(byte far* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
298 /* TODO Make this fast. It's SLOOOOOOW */
\r
299 for(plane=0; plane < 4; plane++) {
\r
300 modexSelectPlane(PLANE(plane+x));
\r
301 for(px = plane; px < bmp->width; px+=4) {
\r
303 for(py=0; py<bmp->height; py++) {
\r
304 if(!sprite || bmp->data[offset])
\r
305 page[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
306 offset+=bmp->width;
\r
313 CDrawBmp(byte far* vgamem, page_t* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
320 /* TODO Make this fast. It's SLOOOOOOW */
\r
321 for(plane=0; plane < 4; plane++) {
\r
322 modexSelectPlane(PLANE(plane+x));
\r
323 for(px = plane; px < bmp->width; px+=4) {
\r
325 for(py=0; py<bmp->height; py++) {
\r
326 if(!sprite || bmp->data[offset])
\r
327 //modexputPixel(page, x+px, y+py, bmp->data[offset]);
\r
328 vgamem[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
329 offset+=bmp->width;
\r
336 modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) {
\r
337 /* draw the region (the entire freakin bitmap) */
\r
338 modexDrawBmpRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
343 modexDrawBmpRegion(page_t *page, int x, int y,
\r
344 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
345 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
346 byte far *data = bmp->data;//+bmp->offset;
\r
347 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
350 byte plane = 1 << ((byte) x & 0x03);
\r
351 word scanCount = width/4 + (width%4 ? 1 :0);
\r
352 word nextPageRow = page->width/4 - scanCount;
\r
353 word nextBmpRow = (word) bmp->width - width;
\r
355 byte planeCounter = 4;
\r
357 /* printf("bmp->data=%Fp\n",bmp->data);
\r
358 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
359 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
361 //code is a bit slow here
\r
363 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
366 MOV DX, SC_INDEX ; point at the map mask register
\r
371 MOV DX, SC_DATA ; select the current plane
\r
375 ;-- begin plane painting
\r
376 MOV AX, height ; start the row counter
\r
377 MOV rowCounter, AX ;
\r
378 MOV DI, poffset ; go to the first pixel
\r
379 MOV SI, bmpOffset ; go to the bmp pixel
\r
381 MOV CX, width ; count the columns
\r
383 MOVSB ; copy the pixel
\r
384 SUB CX, 3 ; we skip the next 3
\r
385 ADD SI, 3 ; skip the bmp pixels
\r
386 LOOP SCAN_LOOP ; finish the scan
\r
388 MOV AX, nextPageRow
\r
389 ADD DI, AX ; go to the next row on screen
\r
391 ADD SI, AX ; go to the next row on bmp
\r
394 JNZ ROW_LOOP ; do all the rows
\r
395 ;-- end plane painting
\r
397 MOV AL, plane ; advance to the next plane
\r
399 AND AL, 0x0f ; mask the plane properly
\r
400 MOV plane, AL ; store the plane
\r
402 INC bmpOffset ; start bmp at the right spot
\r
405 JNZ PLANE_LOOP ; do all 4 planes
\r
411 modexDrawPlanarBuf(page_t *page, int x, int y, planar_buf_t *bmp) {
\r
412 /* TODO - adapt from test code */
\r
414 for(plane=0; plane < 4; plane++)
\r
422 modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp) {
\r
423 /* draw the whole sprite */
\r
424 modexDrawSpriteRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
428 modexDrawSpriteRegion(page_t *page, int x, int y,
\r
429 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
430 word poffset = (word)page->data + y*(page->width/4) + x/4;
\r
431 byte *data = bmp->data;//+bmp->offset;
\r
432 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
435 byte plane = 1 << ((byte) x & 0x03);
\r
436 word scanCount = width/4 + (width%4 ? 1 :0);
\r
437 word nextPageRow = page->width/4 - scanCount;
\r
438 word nextBmpRow = (word) bmp->width - width;
\r
440 byte planeCounter = 4;
\r
443 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
446 MOV DX, SC_INDEX ; point at the map mask register
\r
451 MOV DX, SC_DATA ; select the current plane
\r
455 ;-- begin plane painting
\r
456 MOV AX, height ; start the row counter
\r
457 MOV rowCounter, AX ;
\r
458 MOV DI, poffset ; go to the first pixel
\r
459 MOV SI, bmpOffset ; go to the bmp pixel
\r
461 MOV CX, width ; count the columns
\r
466 JNE DRAW_PIXEL ; draw non-zero pixels
\r
468 INC DI ; skip the transparent pixel
\r
472 MOVSB ; copy the pixel
\r
474 SUB CX, 3 ; we skip the next 3
\r
475 ADD SI, 3 ; skip the bmp pixels
\r
476 LOOP SCAN_LOOP ; finish the scan
\r
478 MOV AX, nextPageRow
\r
479 ADD DI, AX ; go to the next row on screen
\r
481 ADD SI, AX ; go to the next row on bmp
\r
484 JNZ ROW_LOOP ; do all the rows
\r
485 ;-- end plane painting
\r
487 MOV AL, plane ; advance to the next plane
\r
489 AND AL, 0x0f ; mask the plane properly
\r
490 MOV plane, AL ; store the plane
\r
492 INC bmpOffset ; start bmp at the right spot
\r
495 JNZ PLANE_LOOP ; do all 4 planes
\r
500 /* copy a region of video memory from one page to another.
\r
501 * It assumes that the left edge of the tile is the same on both
\r
502 * regions and the memory areas do not overlap.
\r
505 modexCopyPageRegion(page_t *dest, page_t *src,
\r
508 word width, word height)
\r
510 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
511 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
512 word scans = width/4;
\r
513 word nextSrcRow = src->width/4 - scans - 1;
\r
514 word nextDestRow = dest->width/4 - scans - 1;
\r
515 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
516 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
517 byte left = lclip[sx&0x03];
\r
518 byte right = rclip[(sx+width)&0x03];
\r
521 MOV AX, SCREEN_SEG ; work in the vga space
\r
526 MOV DX, GC_INDEX ; turn off cpu bits
\r
530 MOV AX, SC_INDEX ; point to the mask register
\r
540 MOV CX, scans ; the number of latches
\r
542 MOV AL, left ; do the left column
\r
547 MOV AL, 0fh ; do the inner columns
\r
549 REP MOVSB ; copy the pixels
\r
551 MOV AL, right ; do the right column
\r
556 MOV AX, SI ; go the start of the next row
\r
557 ADD AX, nextSrcRow ;
\r
560 ADD AX, nextDestRow ;
\r
563 DEC height ; do the rest of the actions
\r
566 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
567 MOV AL, 0ffh ; none from latches
\r
573 /* fade and flash */
\r
575 modexFadeOn(word fade, byte *palette) {
\r
576 fadePalette(-fade, 64, 64/fade+1, palette);
\r
581 modexFadeOff(word fade, byte *palette) {
\r
582 fadePalette(fade, 0, 64/fade+1, palette);
\r
587 modexFlashOn(word fade, byte *palette) {
\r
588 fadePalette(fade, -64, 64/fade+1, palette);
\r
593 modexFlashOff(word fade, byte *palette) {
\r
594 fadePalette(-fade, 0, 64/fade+1, palette);
\r
599 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
603 /* handle the case where we just update */
\r
605 modexPalUpdate1(palette);
\r
609 while(iter > 0) { /* FadeLoop */
\r
610 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
611 tmppal[i] = palette[i] - dim;
\r
612 if(tmppal[i] > 127) {
\r
614 } else if(tmppal[i] > 63) {
\r
618 modexPalUpdate1(tmppal);
\r
625 /* save and load */
\r
627 modexPalSave(byte *palette) {
\r
630 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
631 for(i=0; i<PAL_SIZE; i++) {
\r
632 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
640 ptr = malloc(PAL_SIZE);
\r
642 /* handle errors */
\r
644 printf("Could not allocate palette.\n");
\r
653 modexLoadPalFile(byte *filename, byte **palette) {
\r
657 /* free the palette if it exists */
\r
662 /* allocate the new palette */
\r
663 *palette = modexNewPal();
\r
665 /* open the file */
\r
666 file = fopen(filename, "rb");
\r
668 printf("Could not open palette file: %s\n", filename);
\r
672 /* read the file */
\r
674 while(!feof(file)) {
\r
675 *ptr++ = fgetc(file);
\r
683 modexSavePalFile(char *filename, byte *pal) {
\r
687 /* open the file for writing */
\r
688 file = fopen(filename, "wb");
\r
690 printf("Could not open %s for writing\n", filename);
\r
694 /* write the data to the file */
\r
695 fwrite(pal, 1, PAL_SIZE, file);
\r
703 fadePalette(-1, 64, 1, tmppal);
\r
709 fadePalette(-1, -64, 1, tmppal);
\r
715 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
717 byte *p = bmp->palette;
\r
721 static word a[PAL_SIZE]; //palette array of change values!
\r
722 word z=0, aq=0, aa=0, pp=0;
\r
727 memset(a, -1, sizeof(a));
\r
728 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
738 // printf("q: %02d\n", (q));
\r
739 // printf("qq: %02d\n", (qq));
\r
740 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
741 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
743 if((*i)<PAL_SIZE/2 && w==0)
\r
745 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
747 //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
748 //____ 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
749 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
754 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
756 //printf("qp=%d\n", qp);
\r
757 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
758 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
759 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
760 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
764 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
766 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
767 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
768 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
771 //if(qp>0) printf("qp=%d\n", qp);
\r
772 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
774 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
775 if((*i)>=PAL_SIZE/2 && w==0)
\r
777 for(; (*i)<PAL_SIZE; (*i)++)
\r
779 //____ 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
780 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
785 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
787 //printf("qp=%d\n", qp);
\r
788 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
789 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
790 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
791 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
795 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
796 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
797 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
800 //printf(" (*i)=%d\n", (*i)/3);
\r
803 printf("\nqqqqqqqq\n\n");
\r
809 long bufSize = (bmp->width * bmp->height);
\r
811 //printf("1(*i)=%02d\n", (*i)/3);
\r
812 //printf("1z=%02d\n", z/3);
\r
813 chkcolor(bmp, &q, &a, &aa, &z, i);
\r
814 //printf("2(*i)=%02d\n", (*i)/3);
\r
815 //printf("2z=%02d\n", z/3);
\r
820 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
821 if(a[aq]==-1) aq++;
\r
822 else { aqoffset++; break; }
\r
824 //update the image data here!
\r
825 for(lq=0; lq<bufSize; lq++)
\r
829 use a[qp] instead of bmp->offset for this spot!
\r
834 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
837 //(offset/bmp->offset)*bmp->offset
\r
840 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
841 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
842 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
843 /*if(bmp->data[lq]+bmp->offset==aq)
\r
845 //printf("%02d", bmp->data[lq]);
\r
846 //printf("\n%02d\n", bmp->offset);
\r
847 printf("aq=%02d ", aq);
\r
848 printf("a[aq]=%02d ", a[aq]);
\r
849 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
850 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
851 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
852 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
853 // printf("_%d ", bmp->data[lq]);
\r
854 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
856 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
858 if(bmp->data[lq]+bmp->offset >= aq)
\r
860 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
861 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
863 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
866 //printf("%02d`", bmp->data[lq]);
\r
867 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
870 //printf(" aq=%02d\n", aq);
\r
871 //printf(" aa=%02d\n", aa);
\r
873 //update the palette~
\r
874 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
877 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
882 modexPalUpdate1(byte *p)
\r
886 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
887 for(i=0; i<PAL_SIZE/2; i++)
\r
889 outp(PAL_DATA_REG, p[i]);
\r
891 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
892 for(; i<PAL_SIZE; i++)
\r
894 outp(PAL_DATA_REG, p[(i)]);
\r
899 modexPalUpdate0(byte *p)
\r
903 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
904 for(i=0; i<PAL_SIZE/2; i++)
\r
906 outp(PAL_DATA_REG, rand());
\r
908 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
909 for(; i<PAL_SIZE; i++)
\r
911 outp(PAL_DATA_REG, rand());
\r
916 //i want to make another vesion that checks the palette when the palette is being appened~
\r
917 void chkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
921 pal = modexNewPal();
\r
923 //printf("q: %02d\n", (*q));
\r
924 printf("chkcolor start~\n");
\r
925 printf("1 (*z): %d\n", (*z)/3);
\r
926 printf("1 (*i): %d\n", (*i)/3);
\r
927 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
928 printf("wwwwwwwwwwwwwwww\n");
\r
929 //check palette for dups
\r
930 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
932 //printf("\n z: %d\n", (*z));
\r
933 //printf(" q: %d\n", (*q));
\r
934 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
937 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
940 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
941 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
945 else for(zz=0; zz<(*q); zz+=3)
\r
947 //printf("zz: %02d\n", zz/3);
\r
950 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
954 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
955 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
958 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
960 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
961 // 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
962 // 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
963 // //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
964 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
969 planned features that i plan to implement~
\r
970 image that has values on the pallete list!
\r
972 no... wait.... no wwww
\r
974 //for(zzii=0; zzii<3; zzii++)
\r
976 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
977 a[(((*z)+(*q)))]=zz;
\r
979 (*aa)=(((*z)+(*q)));
\r
980 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
981 // printf("\n aa: %d\n\n", (*aa));
\r
982 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
983 // printf("wwwwwwwwwwwwwwww\n\n");
\r
987 printf("================\n");
\r
988 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
989 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
990 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
991 printf("================\n");
\r
993 //printf("[%d]", (zz+q));
\r
997 printf("wwwwwwwwwwwwwwww\n");
\r
998 printf("2 (*z): %d\n", (*z)/3);
\r
999 printf("2 (*i): %d\n", (*i)/3);
\r
1000 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
1001 printf("chkcolor end~\n");
\r
1005 void modexputPixel(page_t *page, int x, int y, byte color)
\r
1007 word pageOff = (word) page->data;
\r
1008 /* Each address accesses four neighboring pixels, so set
\r
1009 Write Plane Enable according to which pixel we want
\r
1010 to modify. The plane is determined by the two least
\r
1011 significant bits of the x-coordinate: */
\r
1012 modexSelectPlane(PLANE(x));
\r
1013 //outp(SC_INDEX, 0x02);
\r
1014 //outp(SC_DATA, 0x01 << (x & 3));
\r
1016 /* The offset of the pixel into the video segment is
\r
1017 offset = (width * y + x) / 4, and write the given
\r
1018 color to the plane we selected above. Heed the active
\r
1019 page start selection. */
\r
1020 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
1024 byte modexgetPixel(page_t *page, int x, int y)
\r
1026 word pageOff = (word) page->data;
\r
1027 /* Select the plane from which we must read the pixel color: */
\r
1028 outpw(GC_INDEX, 0x04);
\r
1029 outpw(GC_INDEX+1, x & 3);
\r
1031 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
1035 void modexhlin(page_t *page, word xl, word xh, word y, word color)
\r
1040 for(x=0;x<xh*4;x+=4)
\r
1042 if(x+4>=SCREEN_WIDTH-1){ x=0; yy+=4; }
\r
1043 modexClearRegion(page, x+xl, y+yy, 4, 4, color);
\r
1045 //modexputPixel(page, x+xl, y, color);
\r
1048 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1050 word i, s, o, w, j, xp;
\r
1052 word addr = (word) l;
\r
1076 s=romFonts[t].seg;
\r
1077 o=romFonts[t].off;
\r
1079 for(; *str != '\0'; str++)
\r
1082 if((c=='\n'/* || c=="\
\r
1090 //load the letter 'A'
\r
1096 MOV AL, c ; the letter
\r
1099 ADD SI, AX ;the address of charcter
\r
1108 for(i=0; i<w; i++)
\r
1114 modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1123 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1125 word i, s, o, w, j, xp;
\r
1127 word addr = (word) l;
\r
1151 s=romFonts[t].seg;
\r
1152 o=romFonts[t].off;
\r
1154 for(; *str != '\0'; str++)
\r
1157 if((c=='\n'/* || c=="\
\r
1158 "*/)/* || chw>=page->width*/)
\r
1164 //load the letter 'A'
\r
1170 MOV AL, c ; the letter
\r
1173 ADD SI, AX ;the address of charcter
\r
1182 for(i=0; i<w; i++)
\r
1188 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1189 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1198 /////////////////////////////////////////////////////////////////////////////
\r
1200 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1201 // the Virtual screen. //
\r
1203 /////////////////////////////////////////////////////////////////////////////
\r
1204 void cls(page_t *page, byte color, byte *Where)
\r
1206 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1207 /* set map mask to all 4 planes */
\r
1208 outpw(SC_INDEX, 0xff02);
\r
1209 //_fmemset(VGA, color, 16000);
\r
1210 _fmemset(Where, color, page->width*(page->height));
\r
1214 modexWaitBorder() {
\r
1215 while(inp(INPUT_STATUS_1) & 8) {
\r
1219 while(!(inp(INPUT_STATUS_1) & 8)) {
\r