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 // 0x5f00, /* horizontal total */
\r
81 // 0x3f01, /* horizontal display enable end */
\r
82 0x0d06, /* vertical total */
\r
83 0x3e07, /* overflow (bit 8 of vertical counts) */
\r
84 0x4109, /* cell height (2 to double-scan */
\r
85 0xea10, /* v sync start */
\r
86 0xac11, /* v sync end and protect cr0-cr7 */
\r
87 0xdf12, /* vertical displayed */
\r
88 // 0x2013, /* offset/logical width */
\r
89 0x0014, /* turn off dword mode */
\r
90 0xe715, /* v blank start */
\r
91 0x0616, /* v blank end */
\r
92 0xe317 /* turn on byte mode */
\r
94 int CRTParmCount = sizeof(CRTParms) / sizeof(CRTParms[0]);
\r
96 /* TODO save current video mode and palette */
\r
97 vgaSetMode(VGA_256_COLOR_MODE);
\r
99 /* disable chain4 mode */
\r
100 outpw(SC_INDEX, 0x0604);
\r
102 /* synchronous reset while setting Misc Output */
\r
103 outpw(SC_INDEX, 0x0100);
\r
105 /* select 25 MHz dot clock & 60 Hz scanning rate */
\r
106 outp(MISC_OUTPUT, 0xe3);
\r
108 /* undo reset (restart sequencer) */
\r
109 outpw(SC_INDEX, 0x0300);
\r
111 /* reprogram the CRT controller */
\r
112 outp(CRTC_INDEX, 0x11); /* VSync End reg contains register write prot */
\r
113 outp(CRTC_DATA, 0x7f); /* get current write protect on varios regs */
\r
115 /* send the CRTParms */
\r
116 for(i=0; i<CRTParmCount; i++) {
\r
117 outpw(CRTC_INDEX, CRTParms[i]);
\r
120 /* clear video memory */
\r
121 outpw(SC_INDEX, 0x0f02);
\r
122 for(i=0; i<0x8000; i++) {
\r
130 /* TODO restore original mode and palette */
\r
131 vgaSetMode(TEXT_MODE);
\r
136 modexDefaultPage() {
\r
139 /* default page values */
\r
143 page.width = SCREEN_WIDTH;
\r
144 page.height = SCREEN_HEIGHT;
\r
145 page.tw = page.width/TILEWH;
\r
146 page.th = page.height/TILEWH;
\r
152 /* returns the next page in contiguous memory
\r
153 * the next page will be the same size as p, by default
\r
156 modexNextPage(page_t *p) {
\r
159 result.data = p->data + (p->width/4)*p->height;
\r
162 result.width = p->width;
\r
163 result.height = p->height;
\r
164 result.tw = p->width/TILEWH;
\r
165 result.th = p->height/TILEWH;
\r
166 result.id = p->id+1;
\r
169 // return modexNextPageFlexibleSize(&p, p->width, p->height);
\r
172 //next page with defined dimentions~
\r
174 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
178 result.data = p->data + (p->width/4)*p->height; /* compute the offset */
\r
183 result.tw = p->width/TILEWH;
\r
184 result.th = p->height/TILEWH;
\r
185 result.id = p->id+1;
\r
192 modexShowPage(page_t *page) {
\r
198 /* calculate offset */
\r
199 offset = (word) page->data;
\r
200 offset += page->dy * (page->width >> 2 );
\r
201 offset += page->dx >> 2;
\r
203 /* calculate crtcOffset according to virtual width */
\r
204 crtcOffset = page->width >> 3;
\r
206 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
207 low_address = LOW_ADDRESS | (offset << 8);
\r
209 /* wait for appropriate timing and then program CRTC */
\r
210 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
211 outpw(CRTC_INDEX, high_address);
\r
212 outpw(CRTC_INDEX, low_address);
\r
213 outp(CRTC_INDEX, 0x13);
\r
214 outp(CRTC_DATA, crtcOffset);
\r
216 /* wait for one retrace */
\r
217 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
219 /* do PEL panning here */
\r
220 outp(AC_INDEX, 0x33);
\r
221 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
226 modexPanPage(page_t *page, int dx, int dy) {
\r
233 modexSelectPlane(byte plane) {
\r
234 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
235 outp(SC_DATA, plane);
\r
240 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
241 word pageOff = (word) page->data;
\r
242 word xoff=x/4; /* xoffset that begins each row */
\r
243 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
244 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
245 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
246 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
247 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
248 byte left = lclip[x&0x03];
\r
249 byte right = rclip[(x+w)&0x03];
\r
251 /* handle the case which requires an extra group */
\r
252 if((x & 0x03) && !((x+w) & 0x03)) {
\r
257 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
259 MOV DI, poffset ; go to the first pixel
\r
260 MOV DX, SC_INDEX ; point to the map mask
\r
264 MOV AL, color ; get ready to write colors
\r
266 MOV CX, scanCount ; count the line
\r
267 MOV BL, AL ; remember color
\r
268 MOV AL, left ; do the left clip
\r
269 OUT DX, AL ; set the left clip
\r
270 MOV AL, BL ; restore color
\r
271 STOSB ; write the color
\r
273 JZ SCAN_DONE ; handle 1 group stuff
\r
275 ;-- write the main body of the scanline
\r
276 MOV BL, AL ; remember color
\r
277 MOV AL, 0x0f ; write to all pixels
\r
279 MOV AL, BL ; restore color
\r
280 REP STOSB ; write the color
\r
282 MOV BL, AL ; remeber color
\r
284 OUT DX, AL ; do the right clip
\r
285 MOV AL, BL ; restore color
\r
286 STOSB ; write pixel
\r
287 ADD DI, nextRow ; go to the next row
\r
295 oldDrawBmp(byte far* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
301 /* TODO Make this fast. It's SLOOOOOOW */
\r
302 for(plane=0; plane < 4; plane++) {
\r
303 modexSelectPlane(PLANE(plane+x));
\r
304 for(px = plane; px < bmp->width; px+=4) {
\r
306 for(py=0; py<bmp->height; py++) {
\r
307 if(!sprite || bmp->data[offset])
\r
308 page[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
309 offset+=bmp->width;
\r
316 CDrawBmp(byte far* vgamem, page_t* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
323 /* TODO Make this fast. It's SLOOOOOOW */
\r
324 for(plane=0; plane < 4; plane++) {
\r
325 modexSelectPlane(PLANE(plane+x));
\r
326 for(px = plane; px < bmp->width; px+=4) {
\r
328 for(py=0; py<bmp->height; py++) {
\r
329 if(!sprite || bmp->data[offset])
\r
330 //modexputPixel(page, x+px, y+py, bmp->data[offset]);
\r
331 vgamem[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
332 offset+=bmp->width;
\r
339 modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) {
\r
340 /* draw the region (the entire freakin bitmap) */
\r
341 modexDrawBmpRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
346 modexDrawBmpRegion(page_t *page, int x, int y,
\r
347 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
348 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
349 byte far *data = bmp->data;//+bmp->offset;
\r
350 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
353 byte plane = 1 << ((byte) x & 0x03);
\r
354 word scanCount = width/4 + (width%4 ? 1 :0);
\r
355 word nextPageRow = page->width/4 - scanCount;
\r
356 word nextBmpRow = (word) bmp->width - width;
\r
358 byte planeCounter = 4;
\r
360 /* printf("bmp->data=%Fp\n",bmp->data);
\r
361 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
362 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
364 //code is a bit slow here
\r
366 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
369 MOV DX, SC_INDEX ; point at the map mask register
\r
374 MOV DX, SC_DATA ; select the current plane
\r
378 ;-- begin plane painting
\r
379 MOV AX, height ; start the row counter
\r
380 MOV rowCounter, AX ;
\r
381 MOV DI, poffset ; go to the first pixel
\r
382 MOV SI, bmpOffset ; go to the bmp pixel
\r
384 MOV CX, width ; count the columns
\r
386 MOVSB ; copy the pixel
\r
387 SUB CX, 3 ; we skip the next 3
\r
388 ADD SI, 3 ; skip the bmp pixels
\r
389 LOOP SCAN_LOOP ; finish the scan
\r
391 MOV AX, nextPageRow
\r
392 ADD DI, AX ; go to the next row on screen
\r
394 ADD SI, AX ; go to the next row on bmp
\r
397 JNZ ROW_LOOP ; do all the rows
\r
398 ;-- end plane painting
\r
400 MOV AL, plane ; advance to the next plane
\r
402 AND AL, 0x0f ; mask the plane properly
\r
403 MOV plane, AL ; store the plane
\r
405 INC bmpOffset ; start bmp at the right spot
\r
408 JNZ PLANE_LOOP ; do all 4 planes
\r
413 modex_sparky4_DrawBmpRegion(page_t *page, int x, int y,
\r
414 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
415 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
416 byte far *data = bmp->data;//+bmp->offset;
\r
417 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
420 byte plane = 1 << ((byte) x & 0x03);
\r
421 word scanCount = width/4 + (width%4 ? 1 :0);
\r
422 word nextPageRow = page->width/4 - scanCount;
\r
423 word nextBmpRow = (word) bmp->width - width;
\r
425 byte planeCounter = 4;
\r
427 /* printf("bmp->data=%Fp\n",bmp->data);
\r
428 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
429 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
431 //code is a bit slow here
\r
433 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
436 MOV DX, SC_INDEX ; point at the map mask register
\r
441 MOV DX, SC_DATA ; select the current plane
\r
445 ;-- begin plane painting
\r
446 MOV AX, height ; start the row counter
\r
447 MOV rowCounter, AX ;
\r
448 MOV DI, poffset ; go to the first pixel
\r
449 MOV SI, bmpOffset ; go to the bmp pixel
\r
451 MOV CX, width ; count the columns
\r
453 MOVSB ; copy the pixel
\r
454 SUB CX, 3 ; we skip the next 3
\r
455 ADD SI, 3 ; skip the bmp pixels
\r
456 LOOP SCAN_LOOP ; finish the scan
\r
458 MOV AX, nextPageRow
\r
459 ADD DI, AX ; go to the next row on screen
\r
461 ADD SI, AX ; go to the next row on bmp
\r
464 JNZ ROW_LOOP ; do all the rows
\r
465 ;-- end plane painting
\r
467 MOV AL, plane ; advance to the next plane
\r
469 AND AL, 0x0f ; mask the plane properly
\r
470 MOV plane, AL ; store the plane
\r
472 INC bmpOffset ; start bmp at the right spot
\r
475 JNZ PLANE_LOOP ; do all 4 planes
\r
480 modexDrawPlanarBuf(page_t *page, int x, int y, planar_buf_t *bmp) {
\r
481 /* TODO - adapt from test code */
\r
483 for(plane=0; plane < 4; plane++)
\r
491 modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp) {
\r
492 /* draw the whole sprite */
\r
493 modexDrawSpriteRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
497 modexDrawSpriteRegion(page_t *page, int x, int y,
\r
498 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
499 word poffset = (word)page->data + y*(page->width/4) + x/4;
\r
500 byte *data = bmp->data;//+bmp->offset;
\r
501 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
504 byte plane = 1 << ((byte) x & 0x03);
\r
505 word scanCount = width/4 + (width%4 ? 1 :0);
\r
506 word nextPageRow = page->width/4 - scanCount;
\r
507 word nextBmpRow = (word) bmp->width - width;
\r
509 byte planeCounter = 4;
\r
512 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
515 MOV DX, SC_INDEX ; point at the map mask register
\r
520 MOV DX, SC_DATA ; select the current plane
\r
524 ;-- begin plane painting
\r
525 MOV AX, height ; start the row counter
\r
526 MOV rowCounter, AX ;
\r
527 MOV DI, poffset ; go to the first pixel
\r
528 MOV SI, bmpOffset ; go to the bmp pixel
\r
530 MOV CX, width ; count the columns
\r
535 JNE DRAW_PIXEL ; draw non-zero pixels
\r
537 INC DI ; skip the transparent pixel
\r
541 MOVSB ; copy the pixel
\r
543 SUB CX, 3 ; we skip the next 3
\r
544 ADD SI, 3 ; skip the bmp pixels
\r
545 LOOP SCAN_LOOP ; finish the scan
\r
547 MOV AX, nextPageRow
\r
548 ADD DI, AX ; go to the next row on screen
\r
550 ADD SI, AX ; go to the next row on bmp
\r
553 JNZ ROW_LOOP ; do all the rows
\r
554 ;-- end plane painting
\r
556 MOV AL, plane ; advance to the next plane
\r
558 AND AL, 0x0f ; mask the plane properly
\r
559 MOV plane, AL ; store the plane
\r
561 INC bmpOffset ; start bmp at the right spot
\r
564 JNZ PLANE_LOOP ; do all 4 planes
\r
569 /* copy a region of video memory from one page to another.
\r
570 * It assumes that the left edge of the tile is the same on both
\r
571 * regions and the memory areas do not overlap.
\r
574 modexCopyPageRegion(page_t *dest, page_t *src,
\r
577 word width, word height)
\r
579 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
580 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
581 word scans = width/4;
\r
582 word nextSrcRow = src->width/4 - scans - 1;
\r
583 word nextDestRow = dest->width/4 - scans - 1;
\r
584 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
585 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
586 byte left = lclip[sx&0x03];
\r
587 byte right = rclip[(sx+width)&0x03];
\r
590 MOV AX, SCREEN_SEG ; work in the vga space
\r
595 MOV DX, GC_INDEX ; turn off cpu bits
\r
599 MOV AX, SC_INDEX ; point to the mask register
\r
609 MOV CX, scans ; the number of latches
\r
611 MOV AL, left ; do the left column
\r
616 MOV AL, 0fh ; do the inner columns
\r
618 REP MOVSB ; copy the pixels
\r
620 MOV AL, right ; do the right column
\r
625 MOV AX, SI ; go the start of the next row
\r
626 ADD AX, nextSrcRow ;
\r
629 ADD AX, nextDestRow ;
\r
632 DEC height ; do the rest of the actions
\r
635 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
636 MOV AL, 0ffh ; none from latches
\r
642 /* fade and flash */
\r
644 modexFadeOn(word fade, byte *palette) {
\r
645 fadePalette(-fade, 64, 64/fade+1, palette);
\r
650 modexFadeOff(word fade, byte *palette) {
\r
651 fadePalette(fade, 0, 64/fade+1, palette);
\r
656 modexFlashOn(word fade, byte *palette) {
\r
657 fadePalette(fade, -64, 64/fade+1, palette);
\r
662 modexFlashOff(word fade, byte *palette) {
\r
663 fadePalette(-fade, 0, 64/fade+1, palette);
\r
668 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
672 /* handle the case where we just update */
\r
674 modexPalUpdate1(palette);
\r
678 while(iter > 0) { /* FadeLoop */
\r
679 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
680 tmppal[i] = palette[i] - dim;
\r
681 if(tmppal[i] > 127) {
\r
683 } else if(tmppal[i] > 63) {
\r
687 modexPalUpdate1(tmppal);
\r
694 /* save and load */
\r
696 modexPalSave(byte *palette) {
\r
699 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
700 for(i=0; i<PAL_SIZE; i++) {
\r
701 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
709 ptr = malloc(PAL_SIZE);
\r
711 /* handle errors */
\r
713 printf("Could not allocate palette.\n");
\r
722 modexLoadPalFile(byte *filename, byte **palette) {
\r
726 /* free the palette if it exists */
\r
731 /* allocate the new palette */
\r
732 *palette = modexNewPal();
\r
734 /* open the file */
\r
735 file = fopen(filename, "rb");
\r
737 printf("Could not open palette file: %s\n", filename);
\r
741 /* read the file */
\r
743 while(!feof(file)) {
\r
744 *ptr++ = fgetc(file);
\r
752 modexSavePalFile(char *filename, byte *pal) {
\r
756 /* open the file for writing */
\r
757 file = fopen(filename, "wb");
\r
759 printf("Could not open %s for writing\n", filename);
\r
763 /* write the data to the file */
\r
764 fwrite(pal, 1, PAL_SIZE, file);
\r
772 fadePalette(-1, 64, 1, tmppal);
\r
778 fadePalette(-1, -64, 1, tmppal);
\r
784 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
786 byte *p = bmp->palette;
\r
790 static word a[PAL_SIZE]; //palette array of change values!
\r
791 word z=0, aq=0, aa=0, pp=0;
\r
796 memset(a, -1, sizeof(a));
\r
797 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
807 // printf("q: %02d\n", (q));
\r
808 // printf("qq: %02d\n", (qq));
\r
809 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
810 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
812 if((*i)<PAL_SIZE/2 && w==0)
\r
814 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
816 //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
817 //____ 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
818 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
823 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
825 //printf("qp=%d\n", qp);
\r
826 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
827 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
828 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
829 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
833 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
835 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
836 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
837 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
840 //if(qp>0) printf("qp=%d\n", qp);
\r
841 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
843 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
844 if((*i)>=PAL_SIZE/2 && w==0)
\r
846 for(; (*i)<PAL_SIZE; (*i)++)
\r
848 //____ 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
849 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
854 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
856 //printf("qp=%d\n", qp);
\r
857 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
858 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
859 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
860 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
864 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
865 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
866 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
869 //printf(" (*i)=%d\n", (*i)/3);
\r
872 printf("\nqqqqqqqq\n\n");
\r
878 long bufSize = (bmp->width * bmp->height);
\r
880 //printf("1(*i)=%02d\n", (*i)/3);
\r
881 //printf("1z=%02d\n", z/3);
\r
882 chkcolor(bmp, &q, &a, &aa, &z, i);
\r
883 //printf("2(*i)=%02d\n", (*i)/3);
\r
884 //printf("2z=%02d\n", z/3);
\r
889 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
890 if(a[aq]==-1) aq++;
\r
891 else { aqoffset++; break; }
\r
893 //update the image data here!
\r
894 for(lq=0; lq<bufSize; lq++)
\r
898 use a[qp] instead of bmp->offset for this spot!
\r
903 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
906 //(offset/bmp->offset)*bmp->offset
\r
909 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
910 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
911 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
912 /*if(bmp->data[lq]+bmp->offset==aq)
\r
914 //printf("%02d", bmp->data[lq]);
\r
915 //printf("\n%02d\n", bmp->offset);
\r
916 printf("aq=%02d ", aq);
\r
917 printf("a[aq]=%02d ", a[aq]);
\r
918 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
919 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
920 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
921 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
922 // printf("_%d ", bmp->data[lq]);
\r
923 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
925 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
927 if(bmp->data[lq]+bmp->offset >= aq)
\r
929 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
930 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
932 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
935 //printf("%02d`", bmp->data[lq]);
\r
936 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
939 //printf(" aq=%02d\n", aq);
\r
940 //printf(" aa=%02d\n", aa);
\r
942 //update the palette~
\r
943 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
946 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
951 modexPalUpdate1(byte *p)
\r
955 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
956 for(i=0; i<PAL_SIZE/2; i++)
\r
958 outp(PAL_DATA_REG, p[i]);
\r
960 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
961 for(; i<PAL_SIZE; i++)
\r
963 outp(PAL_DATA_REG, p[(i)]);
\r
968 modexPalUpdate0(byte *p)
\r
972 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
973 for(i=0; i<PAL_SIZE/2; i++)
\r
975 outp(PAL_DATA_REG, rand());
\r
977 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
978 for(; i<PAL_SIZE; i++)
\r
980 outp(PAL_DATA_REG, rand());
\r
985 //i want to make another vesion that checks the palette when the palette is being appened~
\r
986 void chkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
990 pal = modexNewPal();
\r
992 //printf("q: %02d\n", (*q));
\r
993 printf("chkcolor start~\n");
\r
994 printf("1 (*z): %d\n", (*z)/3);
\r
995 printf("1 (*i): %d\n", (*i)/3);
\r
996 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
997 printf("wwwwwwwwwwwwwwww\n");
\r
998 //check palette for dups
\r
999 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
1001 //printf("\n z: %d\n", (*z));
\r
1002 //printf(" q: %d\n", (*q));
\r
1003 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
1006 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
1009 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1010 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
1014 else for(zz=0; zz<(*q); zz+=3)
\r
1016 //printf("zz: %02d\n", zz/3);
\r
1019 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
1023 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
1024 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
1027 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
1029 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
1030 // 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
1031 // 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
1032 // //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
1033 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1036 //expand dong here
\r
1038 planned features that i plan to implement~
\r
1039 image that has values on the pallete list!
\r
1041 no... wait.... no wwww
\r
1043 //for(zzii=0; zzii<3; zzii++)
\r
1045 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
1046 a[(((*z)+(*q)))]=zz;
\r
1048 (*aa)=(((*z)+(*q)));
\r
1049 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
1050 // printf("\n aa: %d\n\n", (*aa));
\r
1051 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
1052 // printf("wwwwwwwwwwwwwwww\n\n");
\r
1056 printf("================\n");
\r
1057 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
1058 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
1059 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1060 printf("================\n");
\r
1062 //printf("[%d]", (zz+q));
\r
1066 printf("wwwwwwwwwwwwwwww\n");
\r
1067 printf("2 (*z): %d\n", (*z)/3);
\r
1068 printf("2 (*i): %d\n", (*i)/3);
\r
1069 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
1070 printf("chkcolor end~\n");
\r
1074 void modexputPixel(page_t *page, int x, int y, byte color)
\r
1076 word pageOff = (word) page->data;
\r
1077 /* Each address accesses four neighboring pixels, so set
\r
1078 Write Plane Enable according to which pixel we want
\r
1079 to modify. The plane is determined by the two least
\r
1080 significant bits of the x-coordinate: */
\r
1081 modexSelectPlane(PLANE(x));
\r
1082 //outp(SC_INDEX, 0x02);
\r
1083 //outp(SC_DATA, 0x01 << (x & 3));
\r
1085 /* The offset of the pixel into the video segment is
\r
1086 offset = (width * y + x) / 4, and write the given
\r
1087 color to the plane we selected above. Heed the active
\r
1088 page start selection. */
\r
1089 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
1093 byte modexgetPixel(page_t *page, int x, int y)
\r
1095 word pageOff = (word) page->data;
\r
1096 /* Select the plane from which we must read the pixel color: */
\r
1097 outpw(GC_INDEX, 0x04);
\r
1098 outpw(GC_INDEX+1, x & 3);
\r
1100 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
1104 void modexhlin(page_t *page, word xl, word xh, word y, word color)
\r
1109 for(x=0;x<xh*4;x+=4)
\r
1111 if(x+4>=SCREEN_WIDTH-1){ x=0; yy+=4; }
\r
1112 modexClearRegion(page, x+xl, y+yy, 4, 4, color);
\r
1114 //modexputPixel(page, x+xl, y, color);
\r
1117 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1119 word i, s, o, w, j, xp;
\r
1121 word addr = (word) l;
\r
1145 s=romFonts[t].seg;
\r
1146 o=romFonts[t].off;
\r
1148 for(; *str != '\0'; str++)
\r
1151 if((c=='\n'/* || c=="\
\r
1159 //load the letter 'A'
\r
1165 MOV AL, c ; the letter
\r
1168 ADD SI, AX ;the address of charcter
\r
1177 for(i=0; i<w; i++)
\r
1183 modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1192 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1194 word i, s, o, w, j, xp;
\r
1196 word addr = (word) l;
\r
1220 s=romFonts[t].seg;
\r
1221 o=romFonts[t].off;
\r
1223 for(; *str != '\0'; str++)
\r
1226 if((c=='\n'/* || c=="\
\r
1227 "*/)/* || chw>=page->width*/)
\r
1233 //load the letter 'A'
\r
1239 MOV AL, c ; the letter
\r
1242 ADD SI, AX ;the address of charcter
\r
1251 for(i=0; i<w; i++)
\r
1257 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1258 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1267 /////////////////////////////////////////////////////////////////////////////
\r
1269 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1270 // the Virtual screen. //
\r
1272 /////////////////////////////////////////////////////////////////////////////
\r
1273 void cls(page_t *page, byte color, byte *Where)
\r
1275 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1276 /* set map mask to all 4 planes */
\r
1277 outpw(SC_INDEX, 0xff02);
\r
1278 //_fmemset(VGA, color, 16000);
\r
1279 _fmemset(Where, color, page->width*(page->height));
\r
1283 modexWaitBorder() {
\r
1284 while(inp(INPUT_STATUS_1) & 8) {
\r
1288 while(!(inp(INPUT_STATUS_1) & 8)) {
\r