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
307 modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) {
\r
308 /* draw the region (the entire freakin bitmap) */
\r
309 modexDrawBmpRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
314 modexDrawBmpRegion(page_t *page, int x, int y,
\r
315 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
316 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
317 byte far *data = bmp->data;//+bmp->offset;
\r
318 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
321 byte plane = 1 << ((byte) x & 0x03);
\r
322 word scanCount = width/4 + (width%4 ? 1 :0);
\r
323 word nextPageRow = page->width/4 - scanCount;
\r
324 word nextBmpRow = (word) bmp->width - width;
\r
326 byte planeCounter = 4;
\r
328 /* printf("bmp->data=%Fp\n",bmp->data);
\r
329 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
330 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
332 //code is a bit slow here
\r
334 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
337 MOV DX, SC_INDEX ; point at the map mask register
\r
342 MOV DX, SC_DATA ; select the current plane
\r
346 ;-- begin plane painting
\r
347 MOV AX, height ; start the row counter
\r
348 MOV rowCounter, AX ;
\r
349 MOV DI, poffset ; go to the first pixel
\r
350 MOV SI, bmpOffset ; go to the bmp pixel
\r
352 MOV CX, width ; count the columns
\r
354 MOVSB ; copy the pixel
\r
355 SUB CX, 3 ; we skip the next 3
\r
356 ADD SI, 3 ; skip the bmp pixels
\r
357 LOOP SCAN_LOOP ; finish the scan
\r
359 MOV AX, nextPageRow
\r
360 ADD DI, AX ; go to the next row on screen
\r
362 ADD SI, AX ; go to the next row on bmp
\r
365 JNZ ROW_LOOP ; do all the rows
\r
366 ;-- end plane painting
\r
368 MOV AL, plane ; advance to the next plane
\r
370 AND AL, 0x0f ; mask the plane properly
\r
371 MOV plane, AL ; store the plane
\r
373 INC bmpOffset ; start bmp at the right spot
\r
376 JNZ PLANE_LOOP ; do all 4 planes
\r
382 modexDrawPlanarBuf(page_t *page, int x, int y, planar_buf_t *bmp) {
\r
383 /* TODO - adapt from test code */
\r
385 for(plane=0; plane < 4; plane++)
\r
393 modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp) {
\r
394 /* draw the whole sprite */
\r
395 modexDrawSpriteRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
399 modexDrawSpriteRegion(page_t *page, int x, int y,
\r
400 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
401 word poffset = (word)page->data + y*(page->width/4) + x/4;
\r
402 byte *data = bmp->data;//+bmp->offset;
\r
403 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
406 byte plane = 1 << ((byte) x & 0x03);
\r
407 word scanCount = width/4 + (width%4 ? 1 :0);
\r
408 word nextPageRow = page->width/4 - scanCount;
\r
409 word nextBmpRow = (word) bmp->width - width;
\r
411 byte planeCounter = 4;
\r
414 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
417 MOV DX, SC_INDEX ; point at the map mask register
\r
422 MOV DX, SC_DATA ; select the current plane
\r
426 ;-- begin plane painting
\r
427 MOV AX, height ; start the row counter
\r
428 MOV rowCounter, AX ;
\r
429 MOV DI, poffset ; go to the first pixel
\r
430 MOV SI, bmpOffset ; go to the bmp pixel
\r
432 MOV CX, width ; count the columns
\r
437 JNE DRAW_PIXEL ; draw non-zero pixels
\r
439 INC DI ; skip the transparent pixel
\r
443 MOVSB ; copy the pixel
\r
445 SUB CX, 3 ; we skip the next 3
\r
446 ADD SI, 3 ; skip the bmp pixels
\r
447 LOOP SCAN_LOOP ; finish the scan
\r
449 MOV AX, nextPageRow
\r
450 ADD DI, AX ; go to the next row on screen
\r
452 ADD SI, AX ; go to the next row on bmp
\r
455 JNZ ROW_LOOP ; do all the rows
\r
456 ;-- end plane painting
\r
458 MOV AL, plane ; advance to the next plane
\r
460 AND AL, 0x0f ; mask the plane properly
\r
461 MOV plane, AL ; store the plane
\r
463 INC bmpOffset ; start bmp at the right spot
\r
466 JNZ PLANE_LOOP ; do all 4 planes
\r
471 /* copy a region of video memory from one page to another.
\r
472 * It assumes that the left edge of the tile is the same on both
\r
473 * regions and the memory areas do not overlap.
\r
476 modexCopyPageRegion(page_t *dest, page_t *src,
\r
479 word width, word height)
\r
481 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
482 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
483 word scans = width/4;
\r
484 word nextSrcRow = src->width/4 - scans - 1;
\r
485 word nextDestRow = dest->width/4 - scans - 1;
\r
486 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
487 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
488 byte left = lclip[sx&0x03];
\r
489 byte right = rclip[(sx+width)&0x03];
\r
492 MOV AX, SCREEN_SEG ; work in the vga space
\r
497 MOV DX, GC_INDEX ; turn off cpu bits
\r
501 MOV AX, SC_INDEX ; point to the mask register
\r
511 MOV CX, scans ; the number of latches
\r
513 MOV AL, left ; do the left column
\r
518 MOV AL, 0fh ; do the inner columns
\r
520 REP MOVSB ; copy the pixels
\r
522 MOV AL, right ; do the right column
\r
527 MOV AX, SI ; go the start of the next row
\r
528 ADD AX, nextSrcRow ;
\r
531 ADD AX, nextDestRow ;
\r
534 DEC height ; do the rest of the actions
\r
537 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
538 MOV AL, 0ffh ; none from latches
\r
544 /* fade and flash */
\r
546 modexFadeOn(word fade, byte *palette) {
\r
547 fadePalette(-fade, 64, 64/fade+1, palette);
\r
552 modexFadeOff(word fade, byte *palette) {
\r
553 fadePalette(fade, 0, 64/fade+1, palette);
\r
558 modexFlashOn(word fade, byte *palette) {
\r
559 fadePalette(fade, -64, 64/fade+1, palette);
\r
564 modexFlashOff(word fade, byte *palette) {
\r
565 fadePalette(-fade, 0, 64/fade+1, palette);
\r
570 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
574 /* handle the case where we just update */
\r
576 modexPalUpdate1(palette);
\r
580 while(iter > 0) { /* FadeLoop */
\r
581 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
582 tmppal[i] = palette[i] - dim;
\r
583 if(tmppal[i] > 127) {
\r
585 } else if(tmppal[i] > 63) {
\r
589 modexPalUpdate1(tmppal);
\r
596 /* save and load */
\r
598 modexPalSave(byte *palette) {
\r
601 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
602 for(i=0; i<PAL_SIZE; i++) {
\r
603 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
611 ptr = malloc(PAL_SIZE);
\r
613 /* handle errors */
\r
615 printf("Could not allocate palette.\n");
\r
624 modexLoadPalFile(byte *filename, byte **palette) {
\r
628 /* free the palette if it exists */
\r
633 /* allocate the new palette */
\r
634 *palette = modexNewPal();
\r
636 /* open the file */
\r
637 file = fopen(filename, "rb");
\r
639 printf("Could not open palette file: %s\n", filename);
\r
643 /* read the file */
\r
645 while(!feof(file)) {
\r
646 *ptr++ = fgetc(file);
\r
654 modexSavePalFile(char *filename, byte *pal) {
\r
658 /* open the file for writing */
\r
659 file = fopen(filename, "wb");
\r
661 printf("Could not open %s for writing\n", filename);
\r
665 /* write the data to the file */
\r
666 fwrite(pal, 1, PAL_SIZE, file);
\r
674 fadePalette(-1, 64, 1, tmppal);
\r
680 fadePalette(-1, -64, 1, tmppal);
\r
686 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
688 byte *p = bmp->palette;
\r
692 static word a[PAL_SIZE]; //palette array of change values!
\r
693 word z=0, aq=0, aa=0, pp=0;
\r
698 memset(a, -1, sizeof(a));
\r
699 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
709 // printf("q: %02d\n", (q));
\r
710 // printf("qq: %02d\n", (qq));
\r
711 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
712 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
714 if((*i)<PAL_SIZE/2 && w==0)
\r
716 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
718 //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
719 //____ 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
720 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
725 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
727 //printf("qp=%d\n", qp);
\r
728 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
729 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
730 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
731 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
735 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
737 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
738 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
739 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
742 //if(qp>0) printf("qp=%d\n", qp);
\r
743 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
745 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
746 if((*i)>=PAL_SIZE/2 && w==0)
\r
748 for(; (*i)<PAL_SIZE; (*i)++)
\r
750 //____ 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
751 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
756 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
758 //printf("qp=%d\n", qp);
\r
759 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
760 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
761 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
762 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\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 //printf(" (*i)=%d\n", (*i)/3);
\r
774 printf("\nqqqqqqqq\n\n");
\r
780 long bufSize = (bmp->width * bmp->height);
\r
782 //printf("1(*i)=%02d\n", (*i)/3);
\r
783 //printf("1z=%02d\n", z/3);
\r
784 chkcolor(bmp, &q, &a, &aa, &z, i);
\r
785 //printf("2(*i)=%02d\n", (*i)/3);
\r
786 //printf("2z=%02d\n", z/3);
\r
791 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
792 if(a[aq]==-1) aq++;
\r
793 else { aqoffset++; break; }
\r
795 //update the image data here!
\r
796 for(lq=0; lq<bufSize; lq++)
\r
800 use a[qp] instead of bmp->offset for this spot!
\r
805 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
808 //(offset/bmp->offset)*bmp->offset
\r
811 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
812 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
813 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
814 /*if(bmp->data[lq]+bmp->offset==aq)
\r
816 //printf("%02d", bmp->data[lq]);
\r
817 //printf("\n%02d\n", bmp->offset);
\r
818 printf("aq=%02d ", aq);
\r
819 printf("a[aq]=%02d ", a[aq]);
\r
820 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
821 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
822 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
823 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
824 // printf("_%d ", bmp->data[lq]);
\r
825 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
827 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
829 if(bmp->data[lq]+bmp->offset >= aq)
\r
831 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
832 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
834 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
837 //printf("%02d`", bmp->data[lq]);
\r
838 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
841 //printf(" aq=%02d\n", aq);
\r
842 //printf(" aa=%02d\n", aa);
\r
844 //update the palette~
\r
845 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
848 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
853 modexPalUpdate1(byte *p)
\r
857 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
858 for(i=0; i<PAL_SIZE/2; i++)
\r
860 outp(PAL_DATA_REG, p[i]);
\r
862 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
863 for(; i<PAL_SIZE; i++)
\r
865 outp(PAL_DATA_REG, p[(i)]);
\r
870 modexPalUpdate0(byte *p)
\r
874 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
875 for(i=0; i<PAL_SIZE/2; i++)
\r
877 outp(PAL_DATA_REG, rand());
\r
879 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
880 for(; i<PAL_SIZE; i++)
\r
882 outp(PAL_DATA_REG, rand());
\r
887 //i want to make another vesion that checks the palette when the palette is being appened~
\r
888 void chkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
892 pal = modexNewPal();
\r
894 //printf("q: %02d\n", (*q));
\r
895 printf("chkcolor start~\n");
\r
896 printf("1 (*z): %d\n", (*z)/3);
\r
897 printf("1 (*i): %d\n", (*i)/3);
\r
898 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
899 printf("wwwwwwwwwwwwwwww\n");
\r
900 //check palette for dups
\r
901 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
903 //printf("\n z: %d\n", (*z));
\r
904 //printf(" q: %d\n", (*q));
\r
905 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
908 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
911 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
912 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
916 else for(zz=0; zz<(*q); zz+=3)
\r
918 //printf("zz: %02d\n", zz/3);
\r
921 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
925 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
926 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
929 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
931 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
932 // 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
933 // 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
934 // //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
935 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
940 planned features that i plan to implement~
\r
941 image that has values on the pallete list!
\r
943 no... wait.... no wwww
\r
945 //for(zzii=0; zzii<3; zzii++)
\r
947 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
948 a[(((*z)+(*q)))]=zz;
\r
950 (*aa)=(((*z)+(*q)));
\r
951 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
952 // printf("\n aa: %d\n\n", (*aa));
\r
953 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
954 // printf("wwwwwwwwwwwwwwww\n\n");
\r
958 printf("================\n");
\r
959 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
960 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
961 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
962 printf("================\n");
\r
964 //printf("[%d]", (zz+q));
\r
968 printf("wwwwwwwwwwwwwwww\n");
\r
969 printf("2 (*z): %d\n", (*z)/3);
\r
970 printf("2 (*i): %d\n", (*i)/3);
\r
971 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
972 printf("chkcolor end~\n");
\r
976 void modexputPixel(page_t *page, int x, int y, byte color)
\r
978 word pageOff = (word) page->data;
\r
979 /* Each address accesses four neighboring pixels, so set
\r
980 Write Plane Enable according to which pixel we want
\r
981 to modify. The plane is determined by the two least
\r
982 significant bits of the x-coordinate: */
\r
983 modexSelectPlane(PLANE(x));
\r
984 //outp(SC_INDEX, 0x02);
\r
985 //outp(SC_DATA, 0x01 << (x & 3));
\r
987 /* The offset of the pixel into the video segment is
\r
988 offset = (width * y + x) / 4, and write the given
\r
989 color to the plane we selected above. Heed the active
\r
990 page start selection. */
\r
991 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
995 byte modexgetPixel(page_t *page, int x, int y)
\r
997 word pageOff = (word) page->data;
\r
998 /* Select the plane from which we must read the pixel color: */
\r
999 outpw(GC_INDEX, 0x04);
\r
1000 outpw(GC_INDEX+1, x & 3);
\r
1002 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
1006 void modexhlin(page_t *page, word xl, word xh, word y, word color)
\r
1011 for(x=0;x<xh*4;x+=4)
\r
1013 if(x+4>=SCREEN_WIDTH-1){ x=0; yy+=4; }
\r
1014 modexClearRegion(page, x+xl, y+yy, 4, 4, color);
\r
1016 //modexputPixel(page, x+xl, y, color);
\r
1019 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1021 word i, s, o, w, j, xp;
\r
1023 word addr = (word) l;
\r
1047 s=romFonts[t].seg;
\r
1048 o=romFonts[t].off;
\r
1050 for(; *str != '\0'; str++)
\r
1053 if((c=='\n'/* || c=="\
\r
1061 //load the letter 'A'
\r
1067 MOV AL, c ; the letter
\r
1070 ADD SI, AX ;the address of charcter
\r
1079 for(i=0; i<w; i++)
\r
1085 modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1094 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1096 word i, s, o, w, j, xp;
\r
1098 word addr = (word) l;
\r
1122 s=romFonts[t].seg;
\r
1123 o=romFonts[t].off;
\r
1125 for(; *str != '\0'; str++)
\r
1128 if((c=='\n'/* || c=="\
\r
1129 "*/)/* || chw>=page->width*/)
\r
1135 //load the letter 'A'
\r
1141 MOV AL, c ; the letter
\r
1144 ADD SI, AX ;the address of charcter
\r
1153 for(i=0; i<w; i++)
\r
1159 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1160 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1170 modexWaitBorder() {
\r
1171 while(inp(INPUT_STATUS_1) & 8) {
\r
1175 while(!(inp(INPUT_STATUS_1) & 8)) {
\r