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; /* compute the offset */
\r
157 result.width = p->width;
\r
158 result.height = p->height;
\r
159 result.id = p->id+1;
\r
164 //next page with defined dimentions~
\r
166 modexNextPage0(page_t *p, word x, word y)
\r
170 result.data = p->data + (p->width/4)*p->height; /* compute the offset */
\r
175 result.id = p->id+1;
\r
182 modexShowPage(page_t *page) {
\r
188 /* calculate offset */
\r
189 offset = (word) page->data;
\r
190 offset += page->dy * (page->width >> 2 );
\r
191 offset += page->dx >> 2;
\r
193 /* calculate crtcOffset according to virtual width */
\r
194 crtcOffset = page->width >> 3;
\r
196 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
197 low_address = LOW_ADDRESS | (offset << 8);
\r
199 /* wait for appropriate timing and then program CRTC */
\r
200 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
201 outpw(CRTC_INDEX, high_address);
\r
202 outpw(CRTC_INDEX, low_address);
\r
203 outp(CRTC_INDEX, 0x13);
\r
204 outp(CRTC_DATA, crtcOffset);
\r
206 /* wait for one retrace */
\r
207 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
209 /* do PEL panning here */
\r
210 outp(AC_INDEX, 0x33);
\r
211 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
216 modexPanPage(page_t *page, int dx, int dy) {
\r
223 modexSelectPlane(byte plane) {
\r
224 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
225 outp(SC_DATA, plane);
\r
230 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
231 word pageOff = (word) page->data;
\r
232 word xoff=x/4; /* xoffset that begins each row */
\r
233 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
234 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
235 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
236 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
237 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
238 byte left = lclip[x&0x03];
\r
239 byte right = rclip[(x+w)&0x03];
\r
241 /* handle the case which requires an extra group */
\r
242 if((x & 0x03) && !((x+w) & 0x03)) {
\r
247 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
249 MOV DI, poffset ; go to the first pixel
\r
250 MOV DX, SC_INDEX ; point to the map mask
\r
254 MOV AL, color ; get ready to write colors
\r
256 MOV CX, scanCount ; count the line
\r
257 MOV BL, AL ; remember color
\r
258 MOV AL, left ; do the left clip
\r
259 OUT DX, AL ; set the left clip
\r
260 MOV AL, BL ; restore color
\r
261 STOSB ; write the color
\r
263 JZ SCAN_DONE ; handle 1 group stuff
\r
265 ;-- write the main body of the scanline
\r
266 MOV BL, AL ; remember color
\r
267 MOV AL, 0x0f ; write to all pixels
\r
269 MOV AL, BL ; restore color
\r
270 REP STOSB ; write the color
\r
272 MOV BL, AL ; remeber color
\r
274 OUT DX, AL ; do the right clip
\r
275 MOV AL, BL ; restore color
\r
276 STOSB ; write pixel
\r
277 ADD DI, nextRow ; go to the next row
\r
285 oldDrawBmp(byte far* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
291 /* TODO Make this fast. It's SLOOOOOOW */
\r
292 for(plane=0; plane < 4; plane++) {
\r
293 modexSelectPlane(PLANE(plane+x));
\r
294 for(px = plane; px < bmp->width; px+=4) {
\r
296 for(py=0; py<bmp->height; py++) {
\r
297 if(!sprite || bmp->data[offset])
\r
298 page[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
299 offset+=bmp->width;
\r
306 CDrawBmp(byte far* vgamem, page_t* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
313 /* TODO Make this fast. It's SLOOOOOOW */
\r
314 for(plane=0; plane < 4; plane++) {
\r
315 modexSelectPlane(PLANE(plane+x));
\r
316 for(px = plane; px < bmp->width; px+=4) {
\r
318 for(py=0; py<bmp->height; py++) {
\r
319 if(!sprite || bmp->data[offset])
\r
320 //modexputPixel(page, x+px, y+py, bmp->data[offset]);
\r
321 vgamem[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
322 offset+=bmp->width;
\r
329 modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) {
\r
330 /* draw the region (the entire freakin bitmap) */
\r
331 modexDrawBmpRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
336 modexDrawBmpRegion(page_t *page, int x, int y,
\r
337 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
338 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
339 byte far *data = bmp->data;//+bmp->offset;
\r
340 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
343 byte plane = 1 << ((byte) x & 0x03);
\r
344 word scanCount = width/4 + (width%4 ? 1 :0);
\r
345 word nextPageRow = page->width/4 - scanCount;
\r
346 word nextBmpRow = (word) bmp->width - width;
\r
348 byte planeCounter = 4;
\r
350 /* printf("bmp->data=%Fp\n",bmp->data);
\r
351 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
352 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
354 //code is a bit slow here
\r
356 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
359 MOV DX, SC_INDEX ; point at the map mask register
\r
364 MOV DX, SC_DATA ; select the current plane
\r
368 ;-- begin plane painting
\r
369 MOV AX, height ; start the row counter
\r
370 MOV rowCounter, AX ;
\r
371 MOV DI, poffset ; go to the first pixel
\r
372 MOV SI, bmpOffset ; go to the bmp pixel
\r
374 MOV CX, width ; count the columns
\r
376 MOVSB ; copy the pixel
\r
377 SUB CX, 3 ; we skip the next 3
\r
378 ADD SI, 3 ; skip the bmp pixels
\r
379 LOOP SCAN_LOOP ; finish the scan
\r
381 MOV AX, nextPageRow
\r
382 ADD DI, AX ; go to the next row on screen
\r
384 ADD SI, AX ; go to the next row on bmp
\r
387 JNZ ROW_LOOP ; do all the rows
\r
388 ;-- end plane painting
\r
390 MOV AL, plane ; advance to the next plane
\r
392 AND AL, 0x0f ; mask the plane properly
\r
393 MOV plane, AL ; store the plane
\r
395 INC bmpOffset ; start bmp at the right spot
\r
398 JNZ PLANE_LOOP ; do all 4 planes
\r
404 modexDrawPlanarBuf(page_t *page, int x, int y, planar_buf_t *bmp) {
\r
405 /* TODO - adapt from test code */
\r
407 for(plane=0; plane < 4; plane++)
\r
415 modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp) {
\r
416 /* draw the whole sprite */
\r
417 modexDrawSpriteRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
421 modexDrawSpriteRegion(page_t *page, int x, int y,
\r
422 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
423 word poffset = (word)page->data + y*(page->width/4) + x/4;
\r
424 byte *data = bmp->data;//+bmp->offset;
\r
425 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
428 byte plane = 1 << ((byte) x & 0x03);
\r
429 word scanCount = width/4 + (width%4 ? 1 :0);
\r
430 word nextPageRow = page->width/4 - scanCount;
\r
431 word nextBmpRow = (word) bmp->width - width;
\r
433 byte planeCounter = 4;
\r
436 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
439 MOV DX, SC_INDEX ; point at the map mask register
\r
444 MOV DX, SC_DATA ; select the current plane
\r
448 ;-- begin plane painting
\r
449 MOV AX, height ; start the row counter
\r
450 MOV rowCounter, AX ;
\r
451 MOV DI, poffset ; go to the first pixel
\r
452 MOV SI, bmpOffset ; go to the bmp pixel
\r
454 MOV CX, width ; count the columns
\r
459 JNE DRAW_PIXEL ; draw non-zero pixels
\r
461 INC DI ; skip the transparent pixel
\r
465 MOVSB ; copy the pixel
\r
467 SUB CX, 3 ; we skip the next 3
\r
468 ADD SI, 3 ; skip the bmp pixels
\r
469 LOOP SCAN_LOOP ; finish the scan
\r
471 MOV AX, nextPageRow
\r
472 ADD DI, AX ; go to the next row on screen
\r
474 ADD SI, AX ; go to the next row on bmp
\r
477 JNZ ROW_LOOP ; do all the rows
\r
478 ;-- end plane painting
\r
480 MOV AL, plane ; advance to the next plane
\r
482 AND AL, 0x0f ; mask the plane properly
\r
483 MOV plane, AL ; store the plane
\r
485 INC bmpOffset ; start bmp at the right spot
\r
488 JNZ PLANE_LOOP ; do all 4 planes
\r
493 /* copy a region of video memory from one page to another.
\r
494 * It assumes that the left edge of the tile is the same on both
\r
495 * regions and the memory areas do not overlap.
\r
498 modexCopyPageRegion(page_t *dest, page_t *src,
\r
501 word width, word height)
\r
503 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
504 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
505 word scans = width/4;
\r
506 word nextSrcRow = src->width/4 - scans - 1;
\r
507 word nextDestRow = dest->width/4 - scans - 1;
\r
508 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
509 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
510 byte left = lclip[sx&0x03];
\r
511 byte right = rclip[(sx+width)&0x03];
\r
514 MOV AX, SCREEN_SEG ; work in the vga space
\r
519 MOV DX, GC_INDEX ; turn off cpu bits
\r
523 MOV AX, SC_INDEX ; point to the mask register
\r
533 MOV CX, scans ; the number of latches
\r
535 MOV AL, left ; do the left column
\r
540 MOV AL, 0fh ; do the inner columns
\r
542 REP MOVSB ; copy the pixels
\r
544 MOV AL, right ; do the right column
\r
549 MOV AX, SI ; go the start of the next row
\r
550 ADD AX, nextSrcRow ;
\r
553 ADD AX, nextDestRow ;
\r
556 DEC height ; do the rest of the actions
\r
559 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
560 MOV AL, 0ffh ; none from latches
\r
566 /* fade and flash */
\r
568 modexFadeOn(word fade, byte *palette) {
\r
569 fadePalette(-fade, 64, 64/fade+1, palette);
\r
574 modexFadeOff(word fade, byte *palette) {
\r
575 fadePalette(fade, 0, 64/fade+1, palette);
\r
580 modexFlashOn(word fade, byte *palette) {
\r
581 fadePalette(fade, -64, 64/fade+1, palette);
\r
586 modexFlashOff(word fade, byte *palette) {
\r
587 fadePalette(-fade, 0, 64/fade+1, palette);
\r
592 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
596 /* handle the case where we just update */
\r
598 modexPalUpdate1(palette);
\r
602 while(iter > 0) { /* FadeLoop */
\r
603 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
604 tmppal[i] = palette[i] - dim;
\r
605 if(tmppal[i] > 127) {
\r
607 } else if(tmppal[i] > 63) {
\r
611 modexPalUpdate1(tmppal);
\r
618 /* save and load */
\r
620 modexPalSave(byte *palette) {
\r
623 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
624 for(i=0; i<PAL_SIZE; i++) {
\r
625 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
633 ptr = malloc(PAL_SIZE);
\r
635 /* handle errors */
\r
637 printf("Could not allocate palette.\n");
\r
646 modexLoadPalFile(byte *filename, byte **palette) {
\r
650 /* free the palette if it exists */
\r
655 /* allocate the new palette */
\r
656 *palette = modexNewPal();
\r
658 /* open the file */
\r
659 file = fopen(filename, "rb");
\r
661 printf("Could not open palette file: %s\n", filename);
\r
665 /* read the file */
\r
667 while(!feof(file)) {
\r
668 *ptr++ = fgetc(file);
\r
676 modexSavePalFile(char *filename, byte *pal) {
\r
680 /* open the file for writing */
\r
681 file = fopen(filename, "wb");
\r
683 printf("Could not open %s for writing\n", filename);
\r
687 /* write the data to the file */
\r
688 fwrite(pal, 1, PAL_SIZE, file);
\r
696 fadePalette(-1, 64, 1, tmppal);
\r
702 fadePalette(-1, -64, 1, tmppal);
\r
708 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
710 byte *p = bmp->palette;
\r
714 static word a[PAL_SIZE]; //palette array of change values!
\r
715 word z=0, aq=0, aa=0, pp=0;
\r
720 memset(a, -1, sizeof(a));
\r
721 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
731 // printf("q: %02d\n", (q));
\r
732 // printf("qq: %02d\n", (qq));
\r
733 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
734 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
736 if((*i)<PAL_SIZE/2 && w==0)
\r
738 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
740 //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
741 //____ 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
742 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
747 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
749 //printf("qp=%d\n", qp);
\r
750 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
751 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
752 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
753 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
757 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
759 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
760 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
761 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
764 //if(qp>0) printf("qp=%d\n", qp);
\r
765 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
767 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
768 if((*i)>=PAL_SIZE/2 && w==0)
\r
770 for(; (*i)<PAL_SIZE; (*i)++)
\r
772 //____ 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
773 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
778 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
780 //printf("qp=%d\n", qp);
\r
781 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
782 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
783 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
784 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
788 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
789 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
790 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
793 //printf(" (*i)=%d\n", (*i)/3);
\r
796 printf("\nqqqqqqqq\n\n");
\r
802 long bufSize = (bmp->width * bmp->height);
\r
804 //printf("1(*i)=%02d\n", (*i)/3);
\r
805 //printf("1z=%02d\n", z/3);
\r
806 chkcolor(bmp, &q, &a, &aa, &z, i);
\r
807 //printf("2(*i)=%02d\n", (*i)/3);
\r
808 //printf("2z=%02d\n", z/3);
\r
813 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
814 if(a[aq]==-1) aq++;
\r
815 else { aqoffset++; break; }
\r
817 //update the image data here!
\r
818 for(lq=0; lq<bufSize; lq++)
\r
822 use a[qp] instead of bmp->offset for this spot!
\r
827 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
830 //(offset/bmp->offset)*bmp->offset
\r
833 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
834 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
835 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
836 /*if(bmp->data[lq]+bmp->offset==aq)
\r
838 //printf("%02d", bmp->data[lq]);
\r
839 //printf("\n%02d\n", bmp->offset);
\r
840 printf("aq=%02d ", aq);
\r
841 printf("a[aq]=%02d ", a[aq]);
\r
842 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
843 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
844 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
845 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
846 // printf("_%d ", bmp->data[lq]);
\r
847 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
849 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
851 if(bmp->data[lq]+bmp->offset >= aq)
\r
853 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
854 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
856 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
859 //printf("%02d`", bmp->data[lq]);
\r
860 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
863 //printf(" aq=%02d\n", aq);
\r
864 //printf(" aa=%02d\n", aa);
\r
866 //update the palette~
\r
867 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
870 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
875 modexPalUpdate1(byte *p)
\r
879 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
880 for(i=0; i<PAL_SIZE/2; i++)
\r
882 outp(PAL_DATA_REG, p[i]);
\r
884 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
885 for(; i<PAL_SIZE; i++)
\r
887 outp(PAL_DATA_REG, p[(i)]);
\r
892 modexPalUpdate0(byte *p)
\r
896 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
897 for(i=0; i<PAL_SIZE/2; i++)
\r
899 outp(PAL_DATA_REG, rand());
\r
901 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
902 for(; i<PAL_SIZE; i++)
\r
904 outp(PAL_DATA_REG, rand());
\r
909 //i want to make another vesion that checks the palette when the palette is being appened~
\r
910 void chkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
914 pal = modexNewPal();
\r
916 //printf("q: %02d\n", (*q));
\r
917 printf("chkcolor start~\n");
\r
918 printf("1 (*z): %d\n", (*z)/3);
\r
919 printf("1 (*i): %d\n", (*i)/3);
\r
920 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
921 printf("wwwwwwwwwwwwwwww\n");
\r
922 //check palette for dups
\r
923 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
925 //printf("\n z: %d\n", (*z));
\r
926 //printf(" q: %d\n", (*q));
\r
927 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
930 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
933 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
934 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
938 else for(zz=0; zz<(*q); zz+=3)
\r
940 //printf("zz: %02d\n", zz/3);
\r
943 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
947 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
948 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
951 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
953 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
954 // 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
955 // 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
956 // //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
957 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
962 planned features that i plan to implement~
\r
963 image that has values on the pallete list!
\r
965 no... wait.... no wwww
\r
967 //for(zzii=0; zzii<3; zzii++)
\r
969 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
970 a[(((*z)+(*q)))]=zz;
\r
972 (*aa)=(((*z)+(*q)));
\r
973 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
974 // printf("\n aa: %d\n\n", (*aa));
\r
975 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
976 // printf("wwwwwwwwwwwwwwww\n\n");
\r
980 printf("================\n");
\r
981 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
982 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
983 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
984 printf("================\n");
\r
986 //printf("[%d]", (zz+q));
\r
990 printf("wwwwwwwwwwwwwwww\n");
\r
991 printf("2 (*z): %d\n", (*z)/3);
\r
992 printf("2 (*i): %d\n", (*i)/3);
\r
993 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
994 printf("chkcolor end~\n");
\r
998 void modexputPixel(page_t *page, int x, int y, byte color)
\r
1000 word pageOff = (word) page->data;
\r
1001 /* Each address accesses four neighboring pixels, so set
\r
1002 Write Plane Enable according to which pixel we want
\r
1003 to modify. The plane is determined by the two least
\r
1004 significant bits of the x-coordinate: */
\r
1005 modexSelectPlane(PLANE(x));
\r
1006 //outp(SC_INDEX, 0x02);
\r
1007 //outp(SC_DATA, 0x01 << (x & 3));
\r
1009 /* The offset of the pixel into the video segment is
\r
1010 offset = (width * y + x) / 4, and write the given
\r
1011 color to the plane we selected above. Heed the active
\r
1012 page start selection. */
\r
1013 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
1017 byte modexgetPixel(page_t *page, int x, int y)
\r
1019 word pageOff = (word) page->data;
\r
1020 /* Select the plane from which we must read the pixel color: */
\r
1021 outpw(GC_INDEX, 0x04);
\r
1022 outpw(GC_INDEX+1, x & 3);
\r
1024 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
1028 void modexhlin(page_t *page, word xl, word xh, word y, word color)
\r
1033 for(x=0;x<xh*4;x+=4)
\r
1035 if(x+4>=SCREEN_WIDTH-1){ x=0; yy+=4; }
\r
1036 modexClearRegion(page, x+xl, y+yy, 4, 4, color);
\r
1038 //modexputPixel(page, x+xl, y, color);
\r
1041 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1043 word i, s, o, w, j, xp;
\r
1045 word addr = (word) l;
\r
1069 s=romFonts[t].seg;
\r
1070 o=romFonts[t].off;
\r
1072 for(; *str != '\0'; str++)
\r
1075 if((c=='\n'/* || c=="\
\r
1083 //load the letter 'A'
\r
1089 MOV AL, c ; the letter
\r
1092 ADD SI, AX ;the address of charcter
\r
1101 for(i=0; i<w; i++)
\r
1107 modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1116 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1118 word i, s, o, w, j, xp;
\r
1120 word addr = (word) l;
\r
1144 s=romFonts[t].seg;
\r
1145 o=romFonts[t].off;
\r
1147 for(; *str != '\0'; str++)
\r
1150 if((c=='\n'/* || c=="\
\r
1151 "*/)/* || chw>=page->width*/)
\r
1157 //load the letter 'A'
\r
1163 MOV AL, c ; the letter
\r
1166 ADD SI, AX ;the address of charcter
\r
1175 for(i=0; i<w; i++)
\r
1181 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1182 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1191 /////////////////////////////////////////////////////////////////////////////
\r
1193 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1194 // the Virtual screen. //
\r
1196 /////////////////////////////////////////////////////////////////////////////
\r
1197 void cls(page_t *page, byte color, byte *Where)
\r
1199 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1200 /* set map mask to all 4 planes */
\r
1201 outpw(SC_INDEX, 0xff02);
\r
1202 //_fmemset(VGA, color, 16000);
\r
1203 _fmemset(Where, color, page->width*(page->height));
\r
1207 modexWaitBorder() {
\r
1208 while(inp(INPUT_STATUS_1) & 8) {
\r
1212 while(!(inp(INPUT_STATUS_1) & 8)) {
\r