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
29 #include "src/lib/modex16.h"
\r
31 byte far* VGA=(byte far*) 0xA0000000; /* this points to video memory. */
\r
33 static void fadePalette(sbyte fade, sbyte start, word iter, byte *palette);
\r
34 static byte tmppal[PAL_SIZE];
\r
37 vgaSetMode(byte mode)
\r
41 regs.h.ah = SET_MODE;
\r
43 int86(VIDEO_INT, ®s, ®s);
\r
47 /* -========================= Entry Points ==========================- */
\r
51 dword far*ptr=(dword far*)VGA; /* used for faster screen clearing */
\r
53 0x0d06, /* vertical total */
\r
54 0x3e07, /* overflow (bit 8 of vertical counts) */
\r
55 0x4109, /* cell height (2 to double-scan */
\r
56 0xea10, /* v sync start */
\r
57 0xac11, /* v sync end and protect cr0-cr7 */
\r
58 0xdf12, /* vertical displayed */
\r
59 0x0014, /* turn off dword mode */
\r
60 0xe715, /* v blank start */
\r
61 0x0616, /* v blank end */
\r
62 0xe317 /* turn on byte mode */
\r
64 int CRTParmCount = sizeof(CRTParms) / sizeof(CRTParms[0]);
\r
66 /* TODO save current video mode and palette */
\r
67 vgaSetMode(VGA_256_COLOR_MODE);
\r
69 /* disable chain4 mode */
\r
70 outpw(SC_INDEX, 0x0604);
\r
72 /* synchronous reset while setting Misc Output */
\r
73 outpw(SC_INDEX, 0x0100);
\r
75 /* select 25 MHz dot clock & 60 Hz scanning rate */
\r
76 outp(MISC_OUTPUT, 0xe3);
\r
78 /* undo reset (restart sequencer) */
\r
79 outpw(SC_INDEX, 0x0300);
\r
81 /* reprogram the CRT controller */
\r
82 outp(CRTC_INDEX, 0x11); /* VSync End reg contains register write prot */
\r
83 outp(CRTC_DATA, 0x7f); /* get current write protect on varios regs */
\r
85 /* send the CRTParms */
\r
86 for(i=0; i<CRTParmCount; i++) {
\r
87 outpw(CRTC_INDEX, CRTParms[i]);
\r
90 /* clear video memory */
\r
91 outpw(SC_INDEX, 0x0f02);
\r
92 for(i=0; i<0x8000; i++) {
\r
100 /* TODO restore original mode and palette */
\r
101 vgaSetMode(TEXT_MODE);
\r
106 modexDefaultPage() {
\r
109 /* default page values */
\r
113 page.width = SCREEN_WIDTH;
\r
114 page.height = SCREEN_HEIGHT;
\r
120 /* returns the next page in contiguous memory
\r
121 * the next page will be the same size as p, by default
\r
124 modexNextPage(page_t *p) {
\r
127 result.data = p->data + (p->width/4)*p->height; /* compute the offset */
\r
130 result.width = p->width;
\r
131 result.height = p->height;
\r
132 result.id = p->id+1;
\r
137 //next page with defined dimentions~
\r
139 modexNextPage0(page_t *p, word x, word y)
\r
143 result.data = p->data + (p->width/4)*p->height; /* compute the offset */
\r
148 result.id = p->id+1;
\r
155 modexShowPage(page_t *page) {
\r
161 /* calculate offset */
\r
162 offset = (word) page->data;
\r
163 offset += page->dy * (page->width >> 2 );
\r
164 offset += page->dx >> 2;
\r
166 /* calculate crtcOffset according to virtual width */
\r
167 crtcOffset = page->width >> 3;
\r
169 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
170 low_address = LOW_ADDRESS | (offset << 8);
\r
172 /* wait for appropriate timing and then program CRTC */
\r
173 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
174 outpw(CRTC_INDEX, high_address);
\r
175 outpw(CRTC_INDEX, low_address);
\r
176 outp(CRTC_INDEX, 0x13);
\r
177 outp(CRTC_DATA, crtcOffset);
\r
179 /* wait for one retrace */
\r
180 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
182 /* do PEL panning here */
\r
183 outp(AC_INDEX, 0x33);
\r
184 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
189 modexPanPage(page_t *page, int dx, int dy) {
\r
196 modexSelectPlane(byte plane) {
\r
197 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
198 outp(SC_DATA, plane);
\r
203 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
204 word pageOff = (word) page->data;
\r
205 word xoff=x/4; /* xoffset that begins each row */
\r
206 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
207 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
208 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
209 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
210 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
211 byte left = lclip[x&0x03];
\r
212 byte right = rclip[(x+w)&0x03];
\r
214 /* handle the case which requires an extra group */
\r
215 if((x & 0x03) && !((x+w) & 0x03)) {
\r
220 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
222 MOV DI, poffset ; go to the first pixel
\r
223 MOV DX, SC_INDEX ; point to the map mask
\r
227 MOV AL, color ; get ready to write colors
\r
229 MOV CX, scanCount ; count the line
\r
230 MOV BL, AL ; remember color
\r
231 MOV AL, left ; do the left clip
\r
232 OUT DX, AL ; set the left clip
\r
233 MOV AL, BL ; restore color
\r
234 STOSB ; write the color
\r
236 JZ SCAN_DONE ; handle 1 group stuff
\r
238 ;-- write the main body of the scanline
\r
239 MOV BL, AL ; remember color
\r
240 MOV AL, 0x0f ; write to all pixels
\r
242 MOV AL, BL ; restore color
\r
243 REP STOSB ; write the color
\r
245 MOV BL, AL ; remeber color
\r
247 OUT DX, AL ; do the right clip
\r
248 MOV AL, BL ; restore color
\r
249 STOSB ; write pixel
\r
250 ADD DI, nextRow ; go to the next row
\r
258 oldDrawBmp(byte far* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
264 /* TODO Make this fast. It's SLOOOOOOW */
\r
265 for(plane=0; plane < 4; plane++) {
\r
266 modexSelectPlane(PLANE(plane+x));
\r
267 for(px = plane; px < bmp->width; px+=4) {
\r
269 for(py=0; py<bmp->height; py++) {
\r
270 if(!sprite || bmp->data[offset])
\r
271 page[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
272 offset+=bmp->width;
\r
280 modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) {
\r
281 /* draw the region (the entire freakin bitmap) */
\r
282 modexDrawBmpRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
287 modexDrawBmpRegion(page_t *page, int x, int y,
\r
288 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
289 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
290 byte *data = bmp->data;//+bmp->offset;
\r
291 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
294 byte plane = 1 << ((byte) x & 0x03);
\r
295 word scanCount = width/4 + (width%4 ? 1 :0);
\r
296 word nextPageRow = page->width/4 - scanCount;
\r
297 word nextBmpRow = (word) bmp->width - width;
\r
299 byte planeCounter = 4;
\r
301 //code is a bit slow here
\r
303 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
306 MOV DX, SC_INDEX ; point at the map mask register
\r
311 MOV DX, SC_DATA ; select the current plane
\r
315 ;-- begin plane painting
\r
316 MOV AX, height ; start the row counter
\r
317 MOV rowCounter, AX ;
\r
318 MOV DI, poffset ; go to the first pixel
\r
319 MOV SI, bmpOffset ; go to the bmp pixel
\r
321 MOV CX, width ; count the columns
\r
323 MOVSB ; copy the pixel
\r
324 SUB CX, 3 ; we skip the next 3
\r
325 ADD SI, 3 ; skip the bmp pixels
\r
326 LOOP SCAN_LOOP ; finish the scan
\r
328 MOV AX, nextPageRow
\r
329 ADD DI, AX ; go to the next row on screen
\r
331 ADD SI, AX ; go to the next row on bmp
\r
334 JNZ ROW_LOOP ; do all the rows
\r
335 ;-- end plane painting
\r
337 MOV AL, plane ; advance to the next plane
\r
339 AND AL, 0x0f ; mask the plane properly
\r
340 MOV plane, AL ; store the plane
\r
342 INC bmpOffset ; start bmp at the right spot
\r
345 JNZ PLANE_LOOP ; do all 4 planes
\r
351 modexDrawPlanarBuf(page_t *page, int x, int y, planar_buf_t *bmp) {
\r
352 /* TODO - adapt from test code */
\r
354 for(plane=0; plane < 4; plane++)
\r
362 modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp) {
\r
363 /* draw the whole sprite */
\r
364 modexDrawSpriteRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
368 modexDrawSpriteRegion(page_t *page, int x, int y,
\r
369 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
370 word poffset = (word)page->data + y*(page->width/4) + x/4;
\r
371 byte *data = bmp->data;//+bmp->offset;
\r
372 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
375 byte plane = 1 << ((byte) x & 0x03);
\r
376 word scanCount = width/4 + (width%4 ? 1 :0);
\r
377 word nextPageRow = page->width/4 - scanCount;
\r
378 word nextBmpRow = (word) bmp->width - width;
\r
380 byte planeCounter = 4;
\r
383 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
386 MOV DX, SC_INDEX ; point at the map mask register
\r
391 MOV DX, SC_DATA ; select the current plane
\r
395 ;-- begin plane painting
\r
396 MOV AX, height ; start the row counter
\r
397 MOV rowCounter, AX ;
\r
398 MOV DI, poffset ; go to the first pixel
\r
399 MOV SI, bmpOffset ; go to the bmp pixel
\r
401 MOV CX, width ; count the columns
\r
406 JNE DRAW_PIXEL ; draw non-zero pixels
\r
408 INC DI ; skip the transparent pixel
\r
412 MOVSB ; copy the pixel
\r
414 SUB CX, 3 ; we skip the next 3
\r
415 ADD SI, 3 ; skip the bmp pixels
\r
416 LOOP SCAN_LOOP ; finish the scan
\r
418 MOV AX, nextPageRow
\r
419 ADD DI, AX ; go to the next row on screen
\r
421 ADD SI, AX ; go to the next row on bmp
\r
424 JNZ ROW_LOOP ; do all the rows
\r
425 ;-- end plane painting
\r
427 MOV AL, plane ; advance to the next plane
\r
429 AND AL, 0x0f ; mask the plane properly
\r
430 MOV plane, AL ; store the plane
\r
432 INC bmpOffset ; start bmp at the right spot
\r
435 JNZ PLANE_LOOP ; do all 4 planes
\r
440 /* copy a region of video memory from one page to another.
\r
441 * It assumes that the left edge of the tile is the same on both
\r
442 * regions and the memory areas do not overlap.
\r
445 modexCopyPageRegion(page_t *dest, page_t *src,
\r
448 word width, word height)
\r
450 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
451 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
452 word scans = width/4;
\r
453 word nextSrcRow = src->width/4 - scans - 1;
\r
454 word nextDestRow = dest->width/4 - scans - 1;
\r
455 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
456 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
457 byte left = lclip[sx&0x03];
\r
458 byte right = rclip[(sx+width)&0x03];
\r
461 MOV AX, SCREEN_SEG ; work in the vga space
\r
466 MOV DX, GC_INDEX ; turn off cpu bits
\r
470 MOV AX, SC_INDEX ; point to the mask register
\r
480 MOV CX, scans ; the number of latches
\r
482 MOV AL, left ; do the left column
\r
487 MOV AL, 0fh ; do the inner columns
\r
489 REP MOVSB ; copy the pixels
\r
491 MOV AL, right ; do the right column
\r
496 MOV AX, SI ; go the start of the next row
\r
497 ADD AX, nextSrcRow ;
\r
500 ADD AX, nextDestRow ;
\r
503 DEC height ; do the rest of the actions
\r
506 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
507 MOV AL, 0ffh ; none from latches
\r
513 /* fade and flash */
\r
515 modexFadeOn(word fade, byte *palette) {
\r
516 fadePalette(-fade, 64, 64/fade+1, palette);
\r
521 modexFadeOff(word fade, byte *palette) {
\r
522 fadePalette(fade, 0, 64/fade+1, palette);
\r
527 modexFlashOn(word fade, byte *palette) {
\r
528 fadePalette(fade, -64, 64/fade+1, palette);
\r
533 modexFlashOff(word fade, byte *palette) {
\r
534 fadePalette(-fade, 0, 64/fade+1, palette);
\r
539 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
543 /* handle the case where we just update */
\r
545 modexPalUpdate1(palette);
\r
549 while(iter > 0) { /* FadeLoop */
\r
550 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
551 tmppal[i] = palette[i] - dim;
\r
552 if(tmppal[i] > 127) {
\r
554 } else if(tmppal[i] > 63) {
\r
558 modexPalUpdate1(tmppal);
\r
565 /* save and load */
\r
567 modexPalSave(byte *palette) {
\r
570 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
571 for(i=0; i<PAL_SIZE; i++) {
\r
572 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
580 ptr = malloc(PAL_SIZE);
\r
582 /* handle errors */
\r
584 printf("Could not allocate palette.\n");
\r
593 modexLoadPalFile(byte *filename, byte **palette) {
\r
597 /* free the palette if it exists */
\r
602 /* allocate the new palette */
\r
603 *palette = modexNewPal();
\r
605 /* open the file */
\r
606 file = fopen(filename, "rb");
\r
608 printf("Could not open palette file: %s\n", filename);
\r
612 /* read the file */
\r
614 while(!feof(file)) {
\r
615 *ptr++ = fgetc(file);
\r
623 modexSavePalFile(char *filename, byte *pal) {
\r
627 /* open the file for writing */
\r
628 file = fopen(filename, "wb");
\r
630 printf("Could not open %s for writing\n", filename);
\r
634 /* write the data to the file */
\r
635 fwrite(pal, 1, PAL_SIZE, file);
\r
643 fadePalette(-1, 64, 1, tmppal);
\r
649 fadePalette(-1, -64, 1, tmppal);
\r
655 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
657 byte *p = bmp->palette;
\r
661 static word a[PAL_SIZE]; //palette array of change values!
\r
662 word z=0, aq=0, aa=0, pp=0;
\r
667 memset(a, -1, sizeof(a));
\r
668 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
678 // printf("q: %02d\n", (q));
\r
679 // printf("qq: %02d\n", (qq));
\r
680 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
681 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
683 if((*i)<PAL_SIZE/2 && w==0)
\r
685 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
687 //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
688 //____ 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
689 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
694 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
696 //printf("qp=%d\n", qp);
\r
697 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
698 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
699 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
700 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
704 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
706 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
707 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
708 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
711 //if(qp>0) printf("qp=%d\n", qp);
\r
712 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
714 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
715 if((*i)>=PAL_SIZE/2 && w==0)
\r
717 for(; (*i)<PAL_SIZE; (*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(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
736 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
737 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
740 //printf(" (*i)=%d\n", (*i)/3);
\r
743 printf("\nqqqqqqqq\n\n");
\r
749 long bufSize = (bmp->width * bmp->height);
\r
751 //printf("1(*i)=%02d\n", (*i)/3);
\r
752 //printf("1z=%02d\n", z/3);
\r
753 chkcolor(bmp, &q, &a, &aa, &z, i);
\r
754 //printf("2(*i)=%02d\n", (*i)/3);
\r
755 //printf("2z=%02d\n", z/3);
\r
760 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
761 if(a[aq]==-1) aq++;
\r
762 else { aqoffset++; break; }
\r
764 //update the image data here!
\r
765 for(lq=0; lq<bufSize; lq++)
\r
769 use a[qp] instead of bmp->offset for this spot!
\r
774 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
777 //(offset/bmp->offset)*bmp->offset
\r
780 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
781 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
782 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
783 /*if(bmp->data[lq]+bmp->offset==aq)
\r
785 //printf("%02d", bmp->data[lq]);
\r
786 //printf("\n%02d\n", bmp->offset);
\r
787 printf("aq=%02d ", aq);
\r
788 printf("a[aq]=%02d ", a[aq]);
\r
789 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
790 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
791 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
792 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
793 // printf("_%d ", bmp->data[lq]);
\r
794 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
796 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
798 if(bmp->data[lq]+bmp->offset >= aq)
\r
800 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
801 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
803 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
806 //printf("%02d`", bmp->data[lq]);
\r
807 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
810 //printf(" aq=%02d\n", aq);
\r
811 //printf(" aa=%02d\n", aa);
\r
813 //update the palette~
\r
814 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
817 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
822 modexPalUpdate1(byte *p)
\r
826 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
827 for(i=0; i<PAL_SIZE/2; i++)
\r
829 outp(PAL_DATA_REG, p[i]);
\r
831 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
832 for(; i<PAL_SIZE; i++)
\r
834 outp(PAL_DATA_REG, p[(i)]);
\r
839 modexPalUpdate0(byte *p)
\r
843 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
844 for(i=0; i<PAL_SIZE/2; i++)
\r
846 outp(PAL_DATA_REG, rand());
\r
848 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
849 for(; i<PAL_SIZE; i++)
\r
851 outp(PAL_DATA_REG, rand());
\r
856 //i want to make another vesion that checks the palette when the palette is being appened~
\r
857 void chkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
861 pal = modexNewPal();
\r
863 //printf("q: %02d\n", (*q));
\r
864 printf("chkcolor start~\n");
\r
865 printf("1 (*z): %d\n", (*z)/3);
\r
866 printf("1 (*i): %d\n", (*i)/3);
\r
867 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
868 printf("wwwwwwwwwwwwwwww\n");
\r
869 //check palette for dups
\r
870 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
872 //printf("\n z: %d\n", (*z));
\r
873 //printf(" q: %d\n", (*q));
\r
874 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
877 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
880 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
881 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
885 else for(zz=0; zz<(*q); zz+=3)
\r
887 //printf("zz: %02d\n", zz/3);
\r
890 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
894 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
895 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
898 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
900 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
901 // 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
902 // 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
903 // //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
904 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
909 planned features that i plan to implement~
\r
910 image that has values on the pallete list!
\r
912 no... wait.... no wwww
\r
914 //for(zzii=0; zzii<3; zzii++)
\r
916 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
917 a[(((*z)+(*q)))]=zz;
\r
919 (*aa)=(((*z)+(*q)));
\r
920 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
921 // printf("\n aa: %d\n\n", (*aa));
\r
922 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
923 // printf("wwwwwwwwwwwwwwww\n\n");
\r
927 printf("================\n");
\r
928 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
929 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
930 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
931 printf("================\n");
\r
933 //printf("[%d]", (zz+q));
\r
937 printf("wwwwwwwwwwwwwwww\n");
\r
938 printf("2 (*z): %d\n", (*z)/3);
\r
939 printf("2 (*i): %d\n", (*i)/3);
\r
940 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
941 printf("chkcolor end~\n");
\r
945 void modexputPixel(int x, int y, byte color)
\r
947 /* Each address accesses four neighboring pixels, so set
\r
948 Write Plane Enable according to which pixel we want
\r
949 to modify. The plane is determined by the two least
\r
950 significant bits of the x-coordinate: */
\r
951 outp(SC_INDEX, 0x02);
\r
952 outp(SC_DATA, 0x01 << (x & 3));
\r
954 /* The offset of the pixel into the video segment is
\r
955 offset = (width * y + x) / 4, and write the given
\r
956 color to the plane we selected above. Heed the active
\r
957 page start selection. */
\r
958 VGA[(unsigned)((SCREEN_WIDTH/4) * y) + (x / 4) + 0] = color;
\r
962 byte modexgetPixel(int x, int y)
\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) + 0];
\r
972 void modexprint(word x, word y, word t, word col, word bgcol, const byte *str)
\r
974 word i, s, o, w, j, xp;
976 word addr = (word) l;
1000 s=romFonts[t].seg;
\r
1003 for(; *str != '\0'; str++)
\r
1005 if(chw>=SCREEN_WIDTH-1) y+=w;
1007 //load the letter 'A'
\r
1013 MOV AL, c ; the letter
\r
1016 ADD SI, AX ;the address of charcter
\r
1031 modexputPixel(x+xp+chw, y+i, l[i] & j ? col:bgcol);
1041 modexWaitBorder() {
\r
1042 while(inp(INPUT_STATUS_1) & 8) {
\r
1046 while(!(inp(INPUT_STATUS_1) & 8)) {
\r