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
147 /* returns the next page in contiguous memory
\r
148 * the next page will be the same size as p, by default
\r
151 modexNextPage(page_t *p) {
\r
154 result.data = p->data + (p->width/4)*p->height;
\r
157 result.width = p->width;
\r
158 result.height = p->height;
\r
159 result.id = p->id+1;
\r
162 // return modexNextPageFlexibleSize(&p, p->width, p->height);
\r
165 //next page with defined dimentions~
\r
167 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
171 result.data = p->data + (p->width/4)*p->height; /* compute the offset */
\r
176 result.id = p->id+1;
\r
183 modexShowPage(page_t *page) {
\r
189 /* calculate offset */
\r
190 offset = (word) page->data;
\r
191 offset += page->dy * (page->width >> 2 );
\r
192 offset += page->dx >> 2;
\r
194 /* calculate crtcOffset according to virtual width */
\r
195 crtcOffset = page->width >> 3;
\r
197 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
198 low_address = LOW_ADDRESS | (offset << 8);
\r
200 /* wait for appropriate timing and then program CRTC */
\r
201 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
202 outpw(CRTC_INDEX, high_address);
\r
203 outpw(CRTC_INDEX, low_address);
\r
204 outp(CRTC_INDEX, 0x13);
\r
205 outp(CRTC_DATA, crtcOffset);
\r
207 /* wait for one retrace */
\r
208 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
210 /* do PEL panning here */
\r
211 outp(AC_INDEX, 0x33);
\r
212 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
217 modexPanPage(page_t *page, int dx, int dy) {
\r
224 modexSelectPlane(byte plane) {
\r
225 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
226 outp(SC_DATA, plane);
\r
231 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
232 word pageOff = (word) page->data;
\r
233 word xoff=x/4; /* xoffset that begins each row */
\r
234 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
235 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
236 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
237 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
238 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
239 byte left = lclip[x&0x03];
\r
240 byte right = rclip[(x+w)&0x03];
\r
242 /* handle the case which requires an extra group */
\r
243 if((x & 0x03) && !((x+w) & 0x03)) {
\r
248 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
250 MOV DI, poffset ; go to the first pixel
\r
251 MOV DX, SC_INDEX ; point to the map mask
\r
255 MOV AL, color ; get ready to write colors
\r
257 MOV CX, scanCount ; count the line
\r
258 MOV BL, AL ; remember color
\r
259 MOV AL, left ; do the left clip
\r
260 OUT DX, AL ; set the left clip
\r
261 MOV AL, BL ; restore color
\r
262 STOSB ; write the color
\r
264 JZ SCAN_DONE ; handle 1 group stuff
\r
266 ;-- write the main body of the scanline
\r
267 MOV BL, AL ; remember color
\r
268 MOV AL, 0x0f ; write to all pixels
\r
270 MOV AL, BL ; restore color
\r
271 REP STOSB ; write the color
\r
273 MOV BL, AL ; remeber color
\r
275 OUT DX, AL ; do the right clip
\r
276 MOV AL, BL ; restore color
\r
277 STOSB ; write pixel
\r
278 ADD DI, nextRow ; go to the next row
\r
286 oldDrawBmp(byte far* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
292 /* TODO Make this fast. It's SLOOOOOOW */
\r
293 for(plane=0; plane < 4; plane++) {
\r
294 modexSelectPlane(PLANE(plane+x));
\r
295 for(px = plane; px < bmp->width; px+=4) {
\r
297 for(py=0; py<bmp->height; py++) {
\r
298 if(!sprite || bmp->data[offset])
\r
299 page[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
300 offset+=bmp->width;
\r
307 CDrawBmp(byte far* vgamem, page_t* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
314 /* TODO Make this fast. It's SLOOOOOOW */
\r
315 for(plane=0; plane < 4; plane++) {
\r
316 modexSelectPlane(PLANE(plane+x));
\r
317 for(px = plane; px < bmp->width; px+=4) {
\r
319 for(py=0; py<bmp->height; py++) {
\r
320 if(!sprite || bmp->data[offset])
\r
321 //modexputPixel(page, x+px, y+py, bmp->data[offset]);
\r
322 vgamem[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
323 offset+=bmp->width;
\r
330 modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) {
\r
331 /* draw the region (the entire freakin bitmap) */
\r
332 modexDrawBmpRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
337 modexDrawBmpRegion(page_t *page, int x, int y,
\r
338 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
339 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
340 byte far *data = bmp->data;//+bmp->offset;
\r
341 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
344 byte plane = 1 << ((byte) x & 0x03);
\r
345 word scanCount = width/4 + (width%4 ? 1 :0);
\r
346 word nextPageRow = page->width/4 - scanCount;
\r
347 word nextBmpRow = (word) bmp->width - width;
\r
349 byte planeCounter = 4;
\r
351 /* printf("bmp->data=%Fp\n",bmp->data);
\r
352 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
353 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
355 //code is a bit slow here
\r
357 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
360 MOV DX, SC_INDEX ; point at the map mask register
\r
365 MOV DX, SC_DATA ; select the current plane
\r
369 ;-- begin plane painting
\r
370 MOV AX, height ; start the row counter
\r
371 MOV rowCounter, AX ;
\r
372 MOV DI, poffset ; go to the first pixel
\r
373 MOV SI, bmpOffset ; go to the bmp pixel
\r
375 MOV CX, width ; count the columns
\r
377 MOVSB ; copy the pixel
\r
378 SUB CX, 3 ; we skip the next 3
\r
379 ADD SI, 3 ; skip the bmp pixels
\r
380 LOOP SCAN_LOOP ; finish the scan
\r
382 MOV AX, nextPageRow
\r
383 ADD DI, AX ; go to the next row on screen
\r
385 ADD SI, AX ; go to the next row on bmp
\r
388 JNZ ROW_LOOP ; do all the rows
\r
389 ;-- end plane painting
\r
391 MOV AL, plane ; advance to the next plane
\r
393 AND AL, 0x0f ; mask the plane properly
\r
394 MOV plane, AL ; store the plane
\r
396 INC bmpOffset ; start bmp at the right spot
\r
399 JNZ PLANE_LOOP ; do all 4 planes
\r
405 modexDrawPlanarBuf(page_t *page, int x, int y, planar_buf_t *bmp) {
\r
406 /* TODO - adapt from test code */
\r
408 for(plane=0; plane < 4; plane++)
\r
416 modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp) {
\r
417 /* draw the whole sprite */
\r
418 modexDrawSpriteRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
422 modexDrawSpriteRegion(page_t *page, int x, int y,
\r
423 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
424 word poffset = (word)page->data + y*(page->width/4) + x/4;
\r
425 byte *data = bmp->data;//+bmp->offset;
\r
426 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
429 byte plane = 1 << ((byte) x & 0x03);
\r
430 word scanCount = width/4 + (width%4 ? 1 :0);
\r
431 word nextPageRow = page->width/4 - scanCount;
\r
432 word nextBmpRow = (word) bmp->width - width;
\r
434 byte planeCounter = 4;
\r
437 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
440 MOV DX, SC_INDEX ; point at the map mask register
\r
445 MOV DX, SC_DATA ; select the current plane
\r
449 ;-- begin plane painting
\r
450 MOV AX, height ; start the row counter
\r
451 MOV rowCounter, AX ;
\r
452 MOV DI, poffset ; go to the first pixel
\r
453 MOV SI, bmpOffset ; go to the bmp pixel
\r
455 MOV CX, width ; count the columns
\r
460 JNE DRAW_PIXEL ; draw non-zero pixels
\r
462 INC DI ; skip the transparent pixel
\r
466 MOVSB ; copy the pixel
\r
468 SUB CX, 3 ; we skip the next 3
\r
469 ADD SI, 3 ; skip the bmp pixels
\r
470 LOOP SCAN_LOOP ; finish the scan
\r
472 MOV AX, nextPageRow
\r
473 ADD DI, AX ; go to the next row on screen
\r
475 ADD SI, AX ; go to the next row on bmp
\r
478 JNZ ROW_LOOP ; do all the rows
\r
479 ;-- end plane painting
\r
481 MOV AL, plane ; advance to the next plane
\r
483 AND AL, 0x0f ; mask the plane properly
\r
484 MOV plane, AL ; store the plane
\r
486 INC bmpOffset ; start bmp at the right spot
\r
489 JNZ PLANE_LOOP ; do all 4 planes
\r
494 /* copy a region of video memory from one page to another.
\r
495 * It assumes that the left edge of the tile is the same on both
\r
496 * regions and the memory areas do not overlap.
\r
499 modexCopyPageRegion(page_t *dest, page_t *src,
\r
502 word width, word height)
\r
504 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
505 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
506 word scans = width/4;
\r
507 word nextSrcRow = src->width/4 - scans - 1;
\r
508 word nextDestRow = dest->width/4 - scans - 1;
\r
509 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
510 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
511 byte left = lclip[sx&0x03];
\r
512 byte right = rclip[(sx+width)&0x03];
\r
515 MOV AX, SCREEN_SEG ; work in the vga space
\r
520 MOV DX, GC_INDEX ; turn off cpu bits
\r
524 MOV AX, SC_INDEX ; point to the mask register
\r
534 MOV CX, scans ; the number of latches
\r
536 MOV AL, left ; do the left column
\r
541 MOV AL, 0fh ; do the inner columns
\r
543 REP MOVSB ; copy the pixels
\r
545 MOV AL, right ; do the right column
\r
550 MOV AX, SI ; go the start of the next row
\r
551 ADD AX, nextSrcRow ;
\r
554 ADD AX, nextDestRow ;
\r
557 DEC height ; do the rest of the actions
\r
560 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
561 MOV AL, 0ffh ; none from latches
\r
567 /* fade and flash */
\r
569 modexFadeOn(word fade, byte *palette) {
\r
570 fadePalette(-fade, 64, 64/fade+1, palette);
\r
575 modexFadeOff(word fade, byte *palette) {
\r
576 fadePalette(fade, 0, 64/fade+1, palette);
\r
581 modexFlashOn(word fade, byte *palette) {
\r
582 fadePalette(fade, -64, 64/fade+1, palette);
\r
587 modexFlashOff(word fade, byte *palette) {
\r
588 fadePalette(-fade, 0, 64/fade+1, palette);
\r
593 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
597 /* handle the case where we just update */
\r
599 modexPalUpdate1(palette);
\r
603 while(iter > 0) { /* FadeLoop */
\r
604 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
605 tmppal[i] = palette[i] - dim;
\r
606 if(tmppal[i] > 127) {
\r
608 } else if(tmppal[i] > 63) {
\r
612 modexPalUpdate1(tmppal);
\r
619 /* save and load */
\r
621 modexPalSave(byte *palette) {
\r
624 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
625 for(i=0; i<PAL_SIZE; i++) {
\r
626 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
634 ptr = malloc(PAL_SIZE);
\r
636 /* handle errors */
\r
638 printf("Could not allocate palette.\n");
\r
647 modexLoadPalFile(byte *filename, byte **palette) {
\r
651 /* free the palette if it exists */
\r
656 /* allocate the new palette */
\r
657 *palette = modexNewPal();
\r
659 /* open the file */
\r
660 file = fopen(filename, "rb");
\r
662 printf("Could not open palette file: %s\n", filename);
\r
666 /* read the file */
\r
668 while(!feof(file)) {
\r
669 *ptr++ = fgetc(file);
\r
677 modexSavePalFile(char *filename, byte *pal) {
\r
681 /* open the file for writing */
\r
682 file = fopen(filename, "wb");
\r
684 printf("Could not open %s for writing\n", filename);
\r
688 /* write the data to the file */
\r
689 fwrite(pal, 1, PAL_SIZE, file);
\r
697 fadePalette(-1, 64, 1, tmppal);
\r
703 fadePalette(-1, -64, 1, tmppal);
\r
709 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
711 byte *p = bmp->palette;
\r
715 static word a[PAL_SIZE]; //palette array of change values!
\r
716 word z=0, aq=0, aa=0, pp=0;
\r
721 memset(a, -1, sizeof(a));
\r
722 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
732 // printf("q: %02d\n", (q));
\r
733 // printf("qq: %02d\n", (qq));
\r
734 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
735 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
737 if((*i)<PAL_SIZE/2 && w==0)
\r
739 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
741 //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
742 //____ 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
743 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
748 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
750 //printf("qp=%d\n", qp);
\r
751 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
752 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
753 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
754 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
758 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
760 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
761 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
762 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
765 //if(qp>0) printf("qp=%d\n", qp);
\r
766 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
768 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
769 if((*i)>=PAL_SIZE/2 && w==0)
\r
771 for(; (*i)<PAL_SIZE; (*i)++)
\r
773 //____ 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
774 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
779 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
781 //printf("qp=%d\n", qp);
\r
782 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
783 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
784 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
785 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
789 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
790 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
791 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
794 //printf(" (*i)=%d\n", (*i)/3);
\r
797 printf("\nqqqqqqqq\n\n");
\r
803 long bufSize = (bmp->width * bmp->height);
\r
805 //printf("1(*i)=%02d\n", (*i)/3);
\r
806 //printf("1z=%02d\n", z/3);
\r
807 chkcolor(bmp, &q, &a, &aa, &z, i);
\r
808 //printf("2(*i)=%02d\n", (*i)/3);
\r
809 //printf("2z=%02d\n", z/3);
\r
814 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
815 if(a[aq]==-1) aq++;
\r
816 else { aqoffset++; break; }
\r
818 //update the image data here!
\r
819 for(lq=0; lq<bufSize; lq++)
\r
823 use a[qp] instead of bmp->offset for this spot!
\r
828 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
831 //(offset/bmp->offset)*bmp->offset
\r
834 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
835 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
836 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
837 /*if(bmp->data[lq]+bmp->offset==aq)
\r
839 //printf("%02d", bmp->data[lq]);
\r
840 //printf("\n%02d\n", bmp->offset);
\r
841 printf("aq=%02d ", aq);
\r
842 printf("a[aq]=%02d ", a[aq]);
\r
843 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
844 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
845 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
846 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
847 // printf("_%d ", bmp->data[lq]);
\r
848 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
850 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
852 if(bmp->data[lq]+bmp->offset >= aq)
\r
854 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
855 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
857 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
860 //printf("%02d`", bmp->data[lq]);
\r
861 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
864 //printf(" aq=%02d\n", aq);
\r
865 //printf(" aa=%02d\n", aa);
\r
867 //update the palette~
\r
868 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
871 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
876 modexPalUpdate1(byte *p)
\r
880 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
881 for(i=0; i<PAL_SIZE/2; i++)
\r
883 outp(PAL_DATA_REG, p[i]);
\r
885 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
886 for(; i<PAL_SIZE; i++)
\r
888 outp(PAL_DATA_REG, p[(i)]);
\r
893 modexPalUpdate0(byte *p)
\r
897 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
898 for(i=0; i<PAL_SIZE/2; i++)
\r
900 outp(PAL_DATA_REG, rand());
\r
902 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
903 for(; i<PAL_SIZE; i++)
\r
905 outp(PAL_DATA_REG, rand());
\r
910 //i want to make another vesion that checks the palette when the palette is being appened~
\r
911 void chkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
915 pal = modexNewPal();
\r
917 //printf("q: %02d\n", (*q));
\r
918 printf("chkcolor start~\n");
\r
919 printf("1 (*z): %d\n", (*z)/3);
\r
920 printf("1 (*i): %d\n", (*i)/3);
\r
921 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
922 printf("wwwwwwwwwwwwwwww\n");
\r
923 //check palette for dups
\r
924 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
926 //printf("\n z: %d\n", (*z));
\r
927 //printf(" q: %d\n", (*q));
\r
928 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
931 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
934 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
935 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
939 else for(zz=0; zz<(*q); zz+=3)
\r
941 //printf("zz: %02d\n", zz/3);
\r
944 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
948 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
949 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
952 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
954 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
955 // 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
956 // 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
957 // //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
958 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
963 planned features that i plan to implement~
\r
964 image that has values on the pallete list!
\r
966 no... wait.... no wwww
\r
968 //for(zzii=0; zzii<3; zzii++)
\r
970 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
971 a[(((*z)+(*q)))]=zz;
\r
973 (*aa)=(((*z)+(*q)));
\r
974 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
975 // printf("\n aa: %d\n\n", (*aa));
\r
976 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
977 // printf("wwwwwwwwwwwwwwww\n\n");
\r
981 printf("================\n");
\r
982 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
983 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
984 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
985 printf("================\n");
\r
987 //printf("[%d]", (zz+q));
\r
991 printf("wwwwwwwwwwwwwwww\n");
\r
992 printf("2 (*z): %d\n", (*z)/3);
\r
993 printf("2 (*i): %d\n", (*i)/3);
\r
994 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
995 printf("chkcolor end~\n");
\r
999 void modexputPixel(page_t *page, int x, int y, byte color)
\r
1001 word pageOff = (word) page->data;
\r
1002 /* Each address accesses four neighboring pixels, so set
\r
1003 Write Plane Enable according to which pixel we want
\r
1004 to modify. The plane is determined by the two least
\r
1005 significant bits of the x-coordinate: */
\r
1006 modexSelectPlane(PLANE(x));
\r
1007 //outp(SC_INDEX, 0x02);
\r
1008 //outp(SC_DATA, 0x01 << (x & 3));
\r
1010 /* The offset of the pixel into the video segment is
\r
1011 offset = (width * y + x) / 4, and write the given
\r
1012 color to the plane we selected above. Heed the active
\r
1013 page start selection. */
\r
1014 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
1018 byte modexgetPixel(page_t *page, int x, int y)
\r
1020 word pageOff = (word) page->data;
\r
1021 /* Select the plane from which we must read the pixel color: */
\r
1022 outpw(GC_INDEX, 0x04);
\r
1023 outpw(GC_INDEX+1, x & 3);
\r
1025 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
1029 void modexhlin(page_t *page, word xl, word xh, word y, word color)
\r
1034 for(x=0;x<xh*4;x+=4)
\r
1036 if(x+4>=SCREEN_WIDTH-1){ x=0; yy+=4; }
\r
1037 modexClearRegion(page, x+xl, y+yy, 4, 4, color);
\r
1039 //modexputPixel(page, x+xl, y, color);
\r
1042 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1044 word i, s, o, w, j, xp;
\r
1046 word addr = (word) l;
\r
1070 s=romFonts[t].seg;
\r
1071 o=romFonts[t].off;
\r
1073 for(; *str != '\0'; str++)
\r
1076 if((c=='\n'/* || c=="\
\r
1084 //load the letter 'A'
\r
1090 MOV AL, c ; the letter
\r
1093 ADD SI, AX ;the address of charcter
\r
1102 for(i=0; i<w; i++)
\r
1108 modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1117 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1119 word i, s, o, w, j, xp;
\r
1121 word addr = (word) l;
\r
1145 s=romFonts[t].seg;
\r
1146 o=romFonts[t].off;
\r
1148 for(; *str != '\0'; str++)
\r
1151 if((c=='\n'/* || c=="\
\r
1152 "*/)/* || chw>=page->width*/)
\r
1158 //load the letter 'A'
\r
1164 MOV AL, c ; the letter
\r
1167 ADD SI, AX ;the address of charcter
\r
1176 for(i=0; i<w; i++)
\r
1182 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1183 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1192 /////////////////////////////////////////////////////////////////////////////
\r
1194 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1195 // the Virtual screen. //
\r
1197 /////////////////////////////////////////////////////////////////////////////
\r
1198 void cls(page_t *page, byte color, byte *Where)
\r
1200 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1201 /* set map mask to all 4 planes */
\r
1202 outpw(SC_INDEX, 0xff02);
\r
1203 //_fmemset(VGA, color, 16000);
\r
1204 _fmemset(Where, color, page->width*(page->height));
\r
1208 modexWaitBorder() {
\r
1209 while(inp(INPUT_STATUS_1) & 8) {
\r
1213 while(!(inp(INPUT_STATUS_1) & 8)) {
\r