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 vgaSetMode(byte mode)
\r
38 regs.h.ah = SET_MODE;
\r
40 int86(VIDEO_INT, ®s, ®s);
\r
44 /* -========================= Entry Points ==========================- */
\r
48 dword far*ptr=(dword far*)VGA; /* used for faster screen clearing */
\r
50 0x0d06, /* vertical total */
\r
51 0x3e07, /* overflow (bit 8 of vertical counts) */
\r
52 0x4109, /* cell height (2 to double-scan */
\r
53 0xea10, /* v sync start */
\r
54 0xac11, /* v sync end and protect cr0-cr7 */
\r
55 0xdf12, /* vertical displayed */
\r
56 0x0014, /* turn off dword mode */
\r
57 0xe715, /* v blank start */
\r
58 0x0616, /* v blank end */
\r
59 0xe317 /* turn on byte mode */
\r
61 int CRTParmCount = sizeof(CRTParms) / sizeof(CRTParms[0]);
\r
63 /* TODO save current video mode and palette */
\r
64 vgaSetMode(VGA_256_COLOR_MODE);
\r
66 /* disable chain4 mode */
\r
67 outpw(SC_INDEX, 0x0604);
\r
69 /* synchronous reset while setting Misc Output */
\r
70 outpw(SC_INDEX, 0x0100);
\r
72 /* select 25 MHz dot clock & 60 Hz scanning rate */
\r
73 outp(MISC_OUTPUT, 0xe3);
\r
75 /* undo reset (restart sequencer) */
\r
76 outpw(SC_INDEX, 0x0300);
\r
78 /* reprogram the CRT controller */
\r
79 outp(CRTC_INDEX, 0x11); /* VSync End reg contains register write prot */
\r
80 outp(CRTC_DATA, 0x7f); /* get current write protect on varios regs */
\r
82 /* send the CRTParms */
\r
83 for(i=0; i<CRTParmCount; i++) {
\r
84 outpw(CRTC_INDEX, CRTParms[i]);
\r
87 /* clear video memory */
\r
88 outpw(SC_INDEX, 0x0f02);
\r
89 for(i=0; i<0x8000; i++) {
\r
97 /* TODO restore original mode and palette */
\r
98 vgaSetMode(TEXT_MODE);
\r
103 modexDefaultPage() {
\r
106 /* default page values */
\r
110 page.width = SCREEN_WIDTH;
\r
111 page.height = SCREEN_HEIGHT;
\r
117 /* returns the next page in contiguous memory
\r
118 * the next page will be the same size as p, by default
\r
121 modexNextPage(page_t *p) {
\r
124 result.data = p->data + (p->width/4)*p->height; /* compute the offset */
\r
127 result.width = p->width;
\r
128 result.height = p->height;
\r
129 result.id = p->id+1;
\r
134 //next page with defined dimentions~
\r
136 modexNextPage0(page_t *p, word x, word y)
\r
140 result.data = p->data + (p->width/4)*p->height; /* compute the offset */
\r
145 result.id = p->id+1;
\r
152 modexShowPage(page_t *page) {
\r
158 /* calculate offset */
\r
159 offset = (word) page->data;
\r
160 offset += page->dy * (page->width >> 2 );
\r
161 offset += page->dx >> 2;
\r
163 /* calculate crtcOffset according to virtual width */
\r
164 crtcOffset = page->width >> 3;
\r
166 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
167 low_address = LOW_ADDRESS | (offset << 8);
\r
169 /* wait for appropriate timing and then program CRTC */
\r
170 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
171 outpw(CRTC_INDEX, high_address);
\r
172 outpw(CRTC_INDEX, low_address);
\r
173 outp(CRTC_INDEX, 0x13);
\r
174 outp(CRTC_DATA, crtcOffset);
\r
176 /* wait for one retrace */
\r
177 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
179 /* do PEL panning here */
\r
180 outp(AC_INDEX, 0x33);
\r
181 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
186 modexPanPage(page_t *page, int dx, int dy) {
\r
193 modexSelectPlane(byte plane) {
\r
194 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
195 outp(SC_DATA, plane);
\r
200 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
201 word pageOff = (word) page->data;
\r
202 word xoff=x/4; /* xoffset that begins each row */
\r
203 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
204 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
205 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
206 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
207 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
208 byte left = lclip[x&0x03];
\r
209 byte right = rclip[(x+w)&0x03];
\r
211 /* handle the case which requires an extra group */
\r
212 if((x & 0x03) && !((x+w) & 0x03)) {
\r
217 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
219 MOV DI, poffset ; go to the first pixel
\r
220 MOV DX, SC_INDEX ; point to the map mask
\r
224 MOV AL, color ; get ready to write colors
\r
226 MOV CX, scanCount ; count the line
\r
227 MOV BL, AL ; remember color
\r
228 MOV AL, left ; do the left clip
\r
229 OUT DX, AL ; set the left clip
\r
230 MOV AL, BL ; restore color
\r
231 STOSB ; write the color
\r
233 JZ SCAN_DONE ; handle 1 group stuff
\r
235 ;-- write the main body of the scanline
\r
236 MOV BL, AL ; remember color
\r
237 MOV AL, 0x0f ; write to all pixels
\r
239 MOV AL, BL ; restore color
\r
240 REP STOSB ; write the color
\r
242 MOV BL, AL ; remeber color
\r
244 OUT DX, AL ; do the right clip
\r
245 MOV AL, BL ; restore color
\r
246 STOSB ; write pixel
\r
247 ADD DI, nextRow ; go to the next row
\r
255 oldDrawBmp(byte far* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
261 /* TODO Make this fast. It's SLOOOOOOW */
\r
262 for(plane=0; plane < 4; plane++) {
\r
263 modexSelectPlane(PLANE(plane+x));
\r
264 for(px = plane; px < bmp->width; px+=4) {
\r
266 for(py=0; py<bmp->height; py++) {
\r
267 if(!sprite || bmp->data[offset])
\r
268 page[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
269 offset+=bmp->width;
\r
277 modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) {
\r
278 /* draw the region (the entire freakin bitmap) */
\r
279 modexDrawBmpRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
284 modexDrawBmpRegion(page_t *page, int x, int y,
\r
285 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
286 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
287 byte *data = bmp->data;//+bmp->offset;
\r
288 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
291 byte plane = 1 << ((byte) x & 0x03);
\r
292 word scanCount = width/4 + (width%4 ? 1 :0);
\r
293 word nextPageRow = page->width/4 - scanCount;
\r
294 word nextBmpRow = (word) bmp->width - width;
\r
296 byte planeCounter = 4;
\r
298 //code is a bit slow here
\r
300 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
303 MOV DX, SC_INDEX ; point at the map mask register
\r
308 MOV DX, SC_DATA ; select the current plane
\r
312 ;-- begin plane painting
\r
313 MOV AX, height ; start the row counter
\r
314 MOV rowCounter, AX ;
\r
315 MOV DI, poffset ; go to the first pixel
\r
316 MOV SI, bmpOffset ; go to the bmp pixel
\r
318 MOV CX, width ; count the columns
\r
320 MOVSB ; copy the pixel
\r
321 SUB CX, 3 ; we skip the next 3
\r
322 ADD SI, 3 ; skip the bmp pixels
\r
323 LOOP SCAN_LOOP ; finish the scan
\r
325 MOV AX, nextPageRow
\r
326 ADD DI, AX ; go to the next row on screen
\r
328 ADD SI, AX ; go to the next row on bmp
\r
331 JNZ ROW_LOOP ; do all the rows
\r
332 ;-- end plane painting
\r
334 MOV AL, plane ; advance to the next plane
\r
336 AND AL, 0x0f ; mask the plane properly
\r
337 MOV plane, AL ; store the plane
\r
339 INC bmpOffset ; start bmp at the right spot
\r
342 JNZ PLANE_LOOP ; do all 4 planes
\r
348 modexDrawPlanarBuf(page_t *page, int x, int y, planar_buf_t *bmp) {
\r
349 /* TODO - adapt from test code */
\r
351 for(plane=0; plane < 4; plane++)
\r
359 modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp) {
\r
360 /* draw the whole sprite */
\r
361 modexDrawSpriteRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
365 modexDrawSpriteRegion(page_t *page, int x, int y,
\r
366 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
367 word poffset = (word)page->data + y*(page->width/4) + x/4;
\r
368 byte *data = bmp->data;//+bmp->offset;
\r
369 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
372 byte plane = 1 << ((byte) x & 0x03);
\r
373 word scanCount = width/4 + (width%4 ? 1 :0);
\r
374 word nextPageRow = page->width/4 - scanCount;
\r
375 word nextBmpRow = (word) bmp->width - width;
\r
377 byte planeCounter = 4;
\r
380 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
383 MOV DX, SC_INDEX ; point at the map mask register
\r
388 MOV DX, SC_DATA ; select the current plane
\r
392 ;-- begin plane painting
\r
393 MOV AX, height ; start the row counter
\r
394 MOV rowCounter, AX ;
\r
395 MOV DI, poffset ; go to the first pixel
\r
396 MOV SI, bmpOffset ; go to the bmp pixel
\r
398 MOV CX, width ; count the columns
\r
403 JNE DRAW_PIXEL ; draw non-zero pixels
\r
405 INC DI ; skip the transparent pixel
\r
409 MOVSB ; copy the pixel
\r
411 SUB CX, 3 ; we skip the next 3
\r
412 ADD SI, 3 ; skip the bmp pixels
\r
413 LOOP SCAN_LOOP ; finish the scan
\r
415 MOV AX, nextPageRow
\r
416 ADD DI, AX ; go to the next row on screen
\r
418 ADD SI, AX ; go to the next row on bmp
\r
421 JNZ ROW_LOOP ; do all the rows
\r
422 ;-- end plane painting
\r
424 MOV AL, plane ; advance to the next plane
\r
426 AND AL, 0x0f ; mask the plane properly
\r
427 MOV plane, AL ; store the plane
\r
429 INC bmpOffset ; start bmp at the right spot
\r
432 JNZ PLANE_LOOP ; do all 4 planes
\r
437 /* copy a region of video memory from one page to another.
\r
438 * It assumes that the left edge of the tile is the same on both
\r
439 * regions and the memory areas do not overlap.
\r
442 modexCopyPageRegion(page_t *dest, page_t *src,
\r
445 word width, word height)
\r
447 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
448 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
449 word scans = width/4;
\r
450 word nextSrcRow = src->width/4 - scans - 1;
\r
451 word nextDestRow = dest->width/4 - scans - 1;
\r
452 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
453 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
454 byte left = lclip[sx&0x03];
\r
455 byte right = rclip[(sx+width)&0x03];
\r
458 MOV AX, SCREEN_SEG ; work in the vga space
\r
463 MOV DX, GC_INDEX ; turn off cpu bits
\r
467 MOV AX, SC_INDEX ; point to the mask register
\r
477 MOV CX, scans ; the number of latches
\r
479 MOV AL, left ; do the left column
\r
484 MOV AL, 0fh ; do the inner columns
\r
486 REP MOVSB ; copy the pixels
\r
488 MOV AL, right ; do the right column
\r
493 MOV AX, SI ; go the start of the next row
\r
494 ADD AX, nextSrcRow ;
\r
497 ADD AX, nextDestRow ;
\r
500 DEC height ; do the rest of the actions
\r
503 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
504 MOV AL, 0ffh ; none from latches
\r
510 /* fade and flash */
\r
512 modexFadeOn(word fade, byte *palette) {
\r
513 fadePalette(-fade, 64, 64/fade+1, palette);
\r
518 modexFadeOff(word fade, byte *palette) {
\r
519 fadePalette(fade, 0, 64/fade+1, palette);
\r
524 modexFlashOn(word fade, byte *palette) {
\r
525 fadePalette(fade, -64, 64/fade+1, palette);
\r
530 modexFlashOff(word fade, byte *palette) {
\r
531 fadePalette(-fade, 0, 64/fade+1, palette);
\r
536 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
540 /* handle the case where we just update */
\r
542 modexPalUpdate1(palette);
\r
546 while(iter > 0) { /* FadeLoop */
\r
547 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
548 tmppal[i] = palette[i] - dim;
\r
549 if(tmppal[i] > 127) {
\r
551 } else if(tmppal[i] > 63) {
\r
555 modexPalUpdate1(tmppal);
\r
562 /* save and load */
\r
564 modexPalSave(byte *palette) {
\r
567 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
568 for(i=0; i<PAL_SIZE; i++) {
\r
569 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
577 ptr = malloc(PAL_SIZE);
\r
579 /* handle errors */
\r
581 printf("Could not allocate palette.\n");
\r
590 modexLoadPalFile(byte *filename, byte **palette) {
\r
594 /* free the palette if it exists */
\r
599 /* allocate the new palette */
\r
600 *palette = modexNewPal();
\r
602 /* open the file */
\r
603 file = fopen(filename, "rb");
\r
605 printf("Could not open palette file: %s\n", filename);
\r
609 /* read the file */
\r
611 while(!feof(file)) {
\r
612 *ptr++ = fgetc(file);
\r
620 modexSavePalFile(char *filename, byte *pal) {
\r
624 /* open the file for writing */
\r
625 file = fopen(filename, "wb");
\r
627 printf("Could not open %s for writing\n", filename);
\r
631 /* write the data to the file */
\r
632 fwrite(pal, 1, PAL_SIZE, file);
\r
640 fadePalette(-1, 64, 1, tmppal);
\r
646 fadePalette(-1, -64, 1, tmppal);
\r
652 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
654 byte *p = bmp->palette;
\r
658 static word a[PAL_SIZE]; //palette array of change values!
\r
659 word z=0, aq=0, aa=0, pp=0;
\r
664 memset(a, -1, sizeof(a));
\r
665 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
675 // printf("q: %02d\n", (q));
\r
676 // printf("qq: %02d\n", (qq));
\r
677 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
678 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
680 if((*i)<PAL_SIZE/2 && w==0)
\r
682 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
684 //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
685 //____ 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
686 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
691 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
693 //printf("qp=%d\n", qp);
\r
694 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
695 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
696 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
697 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
701 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
703 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
704 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
705 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
708 //if(qp>0) printf("qp=%d\n", qp);
\r
709 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
711 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
712 if((*i)>=PAL_SIZE/2 && w==0)
\r
714 for(; (*i)<PAL_SIZE; (*i)++)
\r
716 //____ 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
717 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
722 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
724 //printf("qp=%d\n", qp);
\r
725 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
726 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
727 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
728 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
732 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
733 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
734 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
737 //printf(" (*i)=%d\n", (*i)/3);
\r
740 printf("\nqqqqqqqq\n\n");
\r
746 long bufSize = (bmp->width * bmp->height);
\r
748 //printf("1(*i)=%02d\n", (*i)/3);
\r
749 //printf("1z=%02d\n", z/3);
\r
750 chkcolor(bmp, &q, &a, &aa, &z, i);
\r
751 //printf("2(*i)=%02d\n", (*i)/3);
\r
752 //printf("2z=%02d\n", z/3);
\r
757 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
758 if(a[aq]==-1) aq++;
\r
759 else { aqoffset++; break; }
\r
761 //update the image data here!
\r
762 for(lq=0; lq<bufSize; lq++)
\r
766 use a[qp] instead of bmp->offset for this spot!
\r
771 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
774 //(offset/bmp->offset)*bmp->offset
\r
777 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
778 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
779 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
780 /*if(bmp->data[lq]+bmp->offset==aq)
\r
782 //printf("%02d", bmp->data[lq]);
\r
783 //printf("\n%02d\n", bmp->offset);
\r
784 printf("aq=%02d ", aq);
\r
785 printf("a[aq]=%02d ", a[aq]);
\r
786 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
787 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
788 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
789 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
790 // printf("_%d ", bmp->data[lq]);
\r
791 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
793 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
795 if(bmp->data[lq]+bmp->offset >= aq)
\r
797 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
798 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
800 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
803 //printf("%02d`", bmp->data[lq]);
\r
804 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
807 //printf(" aq=%02d\n", aq);
\r
808 //printf(" aa=%02d\n", aa);
\r
810 //update the palette~
\r
811 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
814 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
819 modexPalUpdate1(byte *p)
\r
823 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
824 for(i=0; i<PAL_SIZE/2; i++)
\r
826 outp(PAL_DATA_REG, p[i]);
\r
828 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
829 for(; i<PAL_SIZE; i++)
\r
831 outp(PAL_DATA_REG, p[(i)]);
\r
836 modexPalUpdate0(byte *p)
\r
840 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
841 for(i=0; i<PAL_SIZE/2; i++)
\r
843 outp(PAL_DATA_REG, rand());
\r
845 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
846 for(; i<PAL_SIZE; i++)
\r
848 outp(PAL_DATA_REG, rand());
\r
853 //i want to make another vesion that checks the palette when the palette is being appened~
\r
854 void chkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
858 pal = modexNewPal();
\r
860 //printf("q: %02d\n", (*q));
\r
861 printf("chkcolor start~\n");
\r
862 printf("1 (*z): %d\n", (*z)/3);
\r
863 printf("1 (*i): %d\n", (*i)/3);
\r
864 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
865 printf("wwwwwwwwwwwwwwww\n");
\r
866 //check palette for dups
\r
867 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
869 //printf("\n z: %d\n", (*z));
\r
870 //printf(" q: %d\n", (*q));
\r
871 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
874 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
877 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
878 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
882 else for(zz=0; zz<(*q); zz+=3)
\r
884 //printf("zz: %02d\n", zz/3);
\r
887 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
891 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
892 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
895 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
897 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
898 // 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
899 // 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
900 // //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
901 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
906 planned features that i plan to implement~
\r
907 image that has values on the pallete list!
\r
909 no... wait.... no wwww
\r
911 //for(zzii=0; zzii<3; zzii++)
\r
913 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
914 a[(((*z)+(*q)))]=zz;
\r
916 (*aa)=(((*z)+(*q)));
\r
917 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
918 // printf("\n aa: %d\n\n", (*aa));
\r
919 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
920 // printf("wwwwwwwwwwwwwwww\n\n");
\r
924 printf("================\n");
\r
925 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
926 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
927 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
928 printf("================\n");
\r
930 //printf("[%d]", (zz+q));
\r
934 printf("wwwwwwwwwwwwwwww\n");
\r
935 printf("2 (*z): %d\n", (*z)/3);
\r
936 printf("2 (*i): %d\n", (*i)/3);
\r
937 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
938 printf("chkcolor end~\n");
\r
942 void modexputPixel(page_t *page, int x, int y, byte color)
\r
944 word pageOff = (word) page->data;
\r
945 /* Each address accesses four neighboring pixels, so set
\r
946 Write Plane Enable according to which pixel we want
\r
947 to modify. The plane is determined by the two least
\r
948 significant bits of the x-coordinate: */
949 //modexSelectPlane(PLANE(x));
\r
950 outp(SC_INDEX, 0x02);
\r
951 outp(SC_DATA, 0x01 << (x & 3));
\r
953 /* The offset of the pixel into the video segment is
\r
954 offset = (width * y + x) / 4, and write the given
\r
955 color to the plane we selected above. Heed the active
\r
956 page start selection. */
\r
957 VGA[(unsigned)((SCREEN_WIDTH/4) * y) + (x / 4) + pageOff] = color;
\r
961 byte modexgetPixel(page_t *page, int x, int y)
\r
963 word pageOff = (word) page->data;
\r
964 /* Select the plane from which we must read the pixel color: */
\r
965 outpw(GC_INDEX, 0x04);
\r
966 outpw(GC_INDEX+1, x & 3);
\r
968 return VGA[(unsigned)((SCREEN_WIDTH/4) * y) + (x / 4) + pageOff];
\r
972 void modexhlin(page_t *page, word xl, word xh, word y, word color)
979 if(x+4>=SCREEN_WIDTH-1){ x=0; yy+=4; }
980 modexClearRegion(page, x+xl, y+yy, 4, 4, color);
982 //modexputPixel(page, x+xl, y, color);
985 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
987 word i, s, o, w, j, xp;
989 word addr = (word) l;
1013 s=romFonts[t].seg;
\r
1016 for(; *str != '\0'; str++)
\r
1019 if((c=='\n'/* || c=="\
1027 //load the letter 'A'
\r
1033 MOV AL, c ; the letter
\r
1036 ADD SI, AX ;the address of charcter
\r
1051 modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
1060 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1062 word i, s, o, w, j, xp;
1064 word addr = (word) l;
1088 s=romFonts[t].seg;
\r
1091 for(; *str != '\0'; str++)
\r
1094 if((c=='\n'/* || c=="\
1095 "*/)/* || chw>=page->width*/)
1101 //load the letter 'A'
\r
1107 MOV AL, c ; the letter
\r
1110 ADD SI, AX ;the address of charcter
\r
1125 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
1126 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
1136 modexWaitBorder() {
\r
1137 while(inp(INPUT_STATUS_1) & 8) {
\r
1141 while(!(inp(INPUT_STATUS_1) & 8)) {
\r