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
59 modex__320x240_256__Enter(gv);
\r
64 vgaSetMode(byte mode)
\r
68 regs.h.ah = SET_MODE;
\r
70 int86(VIDEO_INT, ®s, ®s);
\r
73 /* -========================= Entry Points ==========================- */
\r
75 modex__320x240_256__Enter(global_game_variables_t *gv)
\r
78 dword far*ptr=(dword far*)VGA; /* used for faster screen clearing */
\r
80 // 0xe300, /* horizontal total */
\r
81 // 0x4f01, /* horizontal display enable end */
\r
85 0x0d06, /* vertical total */
\r
86 0x3e07, /* overflow (bit 8 of vertical counts) */
\r
87 0x4109, /* cell height (2 to double-scan */
\r
88 0xea10, /* v sync start */
\r
89 0xac11, /* v sync end and protect cr0-cr7 */
\r
90 0xdf12, /* vertical displayed */
\r
91 0x2813, /* offset/logical width */
\r
92 0x0014, /* turn off dword mode */
\r
93 0xe715, /* v blank start */
\r
94 0x0616, /* v blank end */
\r
95 0xe317 /* turn on byte mode */
\r
98 int CRTParmCount = sizeof(CRTParms) / sizeof(CRTParms[0]);
\r
99 /* width and height */
\r
102 /* TODO save current video mode and palette */
\r
103 vgaSetMode(VGA_256_COLOR_MODE);
\r
105 /* disable chain4 mode */
\r
106 outpw(SC_INDEX, 0x0604);
\r
108 /* synchronous reset while setting Misc Output */
\r
109 outpw(SC_INDEX, 0x0100);
\r
111 /* select 25 MHz dot clock & 60 Hz scanning rate */
\r
112 outp(MISC_OUTPUT, 0xe3);
\r
114 /* undo reset (restart sequencer) */
\r
115 outpw(SC_INDEX, 0x0300);
\r
117 /* reprogram the CRT controller */
\r
118 outp(CRTC_INDEX, 0x11); /* VSync End reg contains register write prot */
\r
119 outp(CRTC_DATA, 0x7f); /* get current write protect on varios regs */
\r
121 /* send the CRTParms */
\r
122 for(i=0; i<CRTParmCount; i++) {
\r
123 outpw(CRTC_INDEX, CRTParms[i]);
\r
126 /* clear video memory */
\r
127 outpw(SC_INDEX, 0x0f02);
\r
128 for(i=0; i<0x8000; i++) {
\r
133 // setBaseXMode() does the initialization to make the VGA ready to
\r
134 // accept any combination of configuration register settings. This
\r
135 // involves enabling writes to index 0 to 7 of the CRT controller (port
\r
136 // 0x3D4), by clearing the most significant bit (bit 7) of index 0x11.
\r
138 modexsetBaseXMode(void)
\r
142 /* TODO save current video mode and palette */
\r
143 vgaSetMode(VGA_256_COLOR_MODE);
\r
145 outp(CRTC_INDEX, 0x11);
\r
146 temp = inp(CRTC_DATA) & 0x7F;
\r
147 outp(CRTC_INDEX, 0x11);
\r
148 outp(CRTC_DATA, temp);
\r
153 /* TODO restore original mode and palette */
\r
154 vgaSetMode(TEXT_MODE);
\r
159 modexDefaultPage() {
\r
162 /* default page values */
\r
166 page.width = SCREEN_WIDTH;
\r
167 page.height = SCREEN_HEIGHT;
\r
168 page.tw = page.width/TILEWH;
\r
169 page.th = page.height/TILEWH;
\r
175 /* returns the next page in contiguous memory
\r
176 * the next page will be the same size as p, by default
\r
179 modexNextPage(page_t *p) {
\r
182 result.data = p->data + (p->width/4)*p->height;
\r
185 result.width = p->width;
\r
186 result.height = p->height;
\r
187 result.tw = p->width/TILEWH;
\r
188 result.th = p->height/TILEWH;
\r
189 result.id = p->id+1;
\r
192 // return modexNextPageFlexibleSize(&p, p->width, p->height);
\r
195 //next page with defined dimentions~
\r
197 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
201 result.data = p->data + (p->width/4)*p->height; /* compute the offset */
\r
206 result.tw = p->width/TILEWH;
\r
207 result.th = p->height/TILEWH;
\r
208 result.id = p->id+1;
\r
215 modexShowPage(page_t *page) {
\r
221 /* calculate offset */
\r
222 offset = (word) page->data;
\r
223 offset += page->dy * (page->width >> 2 );
\r
224 offset += page->dx >> 2;
\r
226 /* calculate crtcOffset according to virtual width */
\r
227 crtcOffset = page->width >> 3;
\r
229 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
230 low_address = LOW_ADDRESS | (offset << 8);
\r
232 /* wait for appropriate timing and then program CRTC */
\r
233 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
234 outpw(CRTC_INDEX, high_address);
\r
235 outpw(CRTC_INDEX, low_address);
\r
236 outp(CRTC_INDEX, 0x13);
\r
237 outp(CRTC_DATA, crtcOffset);
\r
239 /* wait for one retrace */
\r
240 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
242 /* do PEL panning here */
\r
243 outp(AC_INDEX, 0x33);
\r
244 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
249 modexPanPage(page_t *page, int dx, int dy) {
\r
256 modexSelectPlane(byte plane) {
\r
257 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
258 outp(SC_DATA, plane);
\r
263 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
264 word pageOff = (word) page->data;
\r
265 word xoff=x/4; /* xoffset that begins each row */
\r
266 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
267 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
268 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
269 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
270 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
271 byte left = lclip[x&0x03];
\r
272 byte right = rclip[(x+w)&0x03];
\r
274 /* handle the case which requires an extra group */
\r
275 if((x & 0x03) && !((x+w) & 0x03)) {
\r
280 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
282 MOV DI, poffset ; go to the first pixel
\r
283 MOV DX, SC_INDEX ; point to the map mask
\r
287 MOV AL, color ; get ready to write colors
\r
289 MOV CX, scanCount ; count the line
\r
290 MOV BL, AL ; remember color
\r
291 MOV AL, left ; do the left clip
\r
292 OUT DX, AL ; set the left clip
\r
293 MOV AL, BL ; restore color
\r
294 STOSB ; write the color
\r
296 JZ SCAN_DONE ; handle 1 group stuff
\r
298 ;-- write the main body of the scanline
\r
299 MOV BL, AL ; remember color
\r
300 MOV AL, 0x0f ; write to all pixels
\r
302 MOV AL, BL ; restore color
\r
303 REP STOSB ; write the color
\r
305 MOV BL, AL ; remeber color
\r
307 OUT DX, AL ; do the right clip
\r
308 MOV AL, BL ; restore color
\r
309 STOSB ; write pixel
\r
310 ADD DI, nextRow ; go to the next row
\r
318 oldDrawBmp(byte far* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
324 /* TODO Make this fast. It's SLOOOOOOW */
\r
325 for(plane=0; plane < 4; plane++) {
\r
326 modexSelectPlane(PLANE(plane+x));
\r
327 for(px = plane; px < bmp->width; px+=4) {
\r
329 for(py=0; py<bmp->height; py++) {
\r
330 if(!sprite || bmp->data[offset])
\r
331 page[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
332 offset+=bmp->width;
\r
339 CDrawBmp(byte far* vgamem, page_t* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
346 /* TODO Make this fast. It's SLOOOOOOW */
\r
347 for(plane=0; plane < 4; plane++) {
\r
348 modexSelectPlane(PLANE(plane+x));
\r
349 for(px = plane; px < bmp->width; px+=4) {
\r
351 for(py=0; py<bmp->height; py++) {
\r
352 if(!sprite || bmp->data[offset])
\r
353 //modexputPixel(page, x+px, y+py, bmp->data[offset]);
\r
354 vgamem[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
355 offset+=bmp->width;
\r
362 modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) {
\r
363 /* draw the region (the entire freakin bitmap) */
\r
364 modexDrawBmpRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
369 modexDrawBmpRegion(page_t *page, int x, int y,
\r
370 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
371 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
372 byte far *data = bmp->data;//+bmp->offset;
\r
373 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
376 byte plane = 1 << ((byte) x & 0x03);
\r
377 word scanCount = width/4 + (width%4 ? 1 :0);
\r
378 word nextPageRow = page->width/4 - scanCount;
\r
379 word nextBmpRow = (word) bmp->width - width;
\r
381 byte planeCounter = 4;
\r
383 /* printf("bmp->data=%Fp\n",bmp->data);
\r
384 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
385 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
387 //code is a bit slow here
\r
389 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
392 MOV DX, SC_INDEX ; point at the map mask register
\r
397 MOV DX, SC_DATA ; select the current plane
\r
401 ;-- begin plane painting
\r
402 MOV AX, height ; start the row counter
\r
403 MOV rowCounter, AX ;
\r
404 MOV DI, poffset ; go to the first pixel
\r
405 MOV SI, bmpOffset ; go to the bmp pixel
\r
407 MOV CX, width ; count the columns
\r
409 MOVSB ; copy the pixel
\r
410 SUB CX, 3 ; we skip the next 3
\r
411 ADD SI, 3 ; skip the bmp pixels
\r
412 LOOP SCAN_LOOP ; finish the scan
\r
414 MOV AX, nextPageRow
\r
415 ADD DI, AX ; go to the next row on screen
\r
417 ADD SI, AX ; go to the next row on bmp
\r
420 JNZ ROW_LOOP ; do all the rows
\r
421 ;-- end plane painting
\r
423 MOV AL, plane ; advance to the next plane
\r
425 AND AL, 0x0f ; mask the plane properly
\r
426 MOV plane, AL ; store the plane
\r
428 INC bmpOffset ; start bmp at the right spot
\r
431 JNZ PLANE_LOOP ; do all 4 planes
\r
436 modex_sparky4_DrawBmpRegion(page_t *page, int x, int y,
\r
437 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
438 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
439 byte far *data = bmp->data;//+bmp->offset;
\r
440 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
443 byte plane = 1 << ((byte) x & 0x03);
\r
444 word scanCount = width/4 + (width%4 ? 1 :0);
\r
445 word nextPageRow = page->width/4 - scanCount;
\r
446 word nextBmpRow = (word) bmp->width - width;
\r
448 byte planeCounter = 4;
\r
450 /* printf("bmp->data=%Fp\n",bmp->data);
\r
451 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
452 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
454 //code is a bit slow here
\r
456 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
459 MOV DX, SC_INDEX ; point at the map mask register
\r
464 MOV DX, SC_DATA ; select the current plane
\r
468 ;-- begin plane painting
\r
469 MOV AX, height ; start the row counter
\r
470 MOV rowCounter, AX ;
\r
471 MOV DI, poffset ; go to the first pixel
\r
472 MOV SI, bmpOffset ; go to the bmp pixel
\r
474 MOV CX, width ; count the columns
\r
476 MOVSB ; copy the pixel
\r
477 SUB CX, 3 ; we skip the next 3
\r
478 ADD SI, 3 ; skip the bmp pixels
\r
479 LOOP SCAN_LOOP ; finish the scan
\r
481 MOV AX, nextPageRow
\r
482 ADD DI, AX ; go to the next row on screen
\r
484 ADD SI, AX ; go to the next row on bmp
\r
487 JNZ ROW_LOOP ; do all the rows
\r
488 ;-- end plane painting
\r
490 MOV AL, plane ; advance to the next plane
\r
492 AND AL, 0x0f ; mask the plane properly
\r
493 MOV plane, AL ; store the plane
\r
495 INC bmpOffset ; start bmp at the right spot
\r
498 JNZ PLANE_LOOP ; do all 4 planes
\r
503 modexDrawPlanarBuf(page_t *page, int x, int y, planar_buf_t *bmp) {
\r
504 /* TODO - adapt from test code */
\r
506 for(plane=0; plane < 4; plane++)
\r
514 modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp) {
\r
515 /* draw the whole sprite */
\r
516 modexDrawSpriteRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
520 modexDrawSpriteRegion(page_t *page, int x, int y,
\r
521 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
522 word poffset = (word)page->data + y*(page->width/4) + x/4;
\r
523 byte *data = bmp->data;//+bmp->offset;
\r
524 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
527 byte plane = 1 << ((byte) x & 0x03);
\r
528 word scanCount = width/4 + (width%4 ? 1 :0);
\r
529 word nextPageRow = page->width/4 - scanCount;
\r
530 word nextBmpRow = (word) bmp->width - width;
\r
532 byte planeCounter = 4;
\r
535 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
538 MOV DX, SC_INDEX ; point at the map mask register
\r
543 MOV DX, SC_DATA ; select the current plane
\r
547 ;-- begin plane painting
\r
548 MOV AX, height ; start the row counter
\r
549 MOV rowCounter, AX ;
\r
550 MOV DI, poffset ; go to the first pixel
\r
551 MOV SI, bmpOffset ; go to the bmp pixel
\r
553 MOV CX, width ; count the columns
\r
558 JNE DRAW_PIXEL ; draw non-zero pixels
\r
560 INC DI ; skip the transparent pixel
\r
564 MOVSB ; copy the pixel
\r
566 SUB CX, 3 ; we skip the next 3
\r
567 ADD SI, 3 ; skip the bmp pixels
\r
568 LOOP SCAN_LOOP ; finish the scan
\r
570 MOV AX, nextPageRow
\r
571 ADD DI, AX ; go to the next row on screen
\r
573 ADD SI, AX ; go to the next row on bmp
\r
576 JNZ ROW_LOOP ; do all the rows
\r
577 ;-- end plane painting
\r
579 MOV AL, plane ; advance to the next plane
\r
581 AND AL, 0x0f ; mask the plane properly
\r
582 MOV plane, AL ; store the plane
\r
584 INC bmpOffset ; start bmp at the right spot
\r
587 JNZ PLANE_LOOP ; do all 4 planes
\r
592 /* copy a region of video memory from one page to another.
\r
593 * It assumes that the left edge of the tile is the same on both
\r
594 * regions and the memory areas do not overlap.
\r
597 modexCopyPageRegion(page_t *dest, page_t *src,
\r
600 word width, word height)
\r
602 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
603 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
604 word scans = width/4;
\r
605 word nextSrcRow = src->width/4 - scans - 1;
\r
606 word nextDestRow = dest->width/4 - scans - 1;
\r
607 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
608 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
609 byte left = lclip[sx&0x03];
\r
610 byte right = rclip[(sx+width)&0x03];
\r
613 MOV AX, SCREEN_SEG ; work in the vga space
\r
618 MOV DX, GC_INDEX ; turn off cpu bits
\r
622 MOV AX, SC_INDEX ; point to the mask register
\r
632 MOV CX, scans ; the number of latches
\r
634 MOV AL, left ; do the left column
\r
639 MOV AL, 0fh ; do the inner columns
\r
641 REP MOVSB ; copy the pixels
\r
643 MOV AL, right ; do the right column
\r
648 MOV AX, SI ; go the start of the next row
\r
649 ADD AX, nextSrcRow ;
\r
652 ADD AX, nextDestRow ;
\r
655 DEC height ; do the rest of the actions
\r
658 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
659 MOV AL, 0ffh ; none from latches
\r
665 /* fade and flash */
\r
667 modexFadeOn(word fade, byte *palette) {
\r
668 fadePalette(-fade, 64, 64/fade+1, palette);
\r
673 modexFadeOff(word fade, byte *palette) {
\r
674 fadePalette(fade, 0, 64/fade+1, palette);
\r
679 modexFlashOn(word fade, byte *palette) {
\r
680 fadePalette(fade, -64, 64/fade+1, palette);
\r
685 modexFlashOff(word fade, byte *palette) {
\r
686 fadePalette(-fade, 0, 64/fade+1, palette);
\r
691 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
695 /* handle the case where we just update */
\r
697 modexPalUpdate1(palette);
\r
701 while(iter > 0) { /* FadeLoop */
\r
702 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
703 tmppal[i] = palette[i] - dim;
\r
704 if(tmppal[i] > 127) {
\r
706 } else if(tmppal[i] > 63) {
\r
710 modexPalUpdate1(tmppal);
\r
717 /* save and load */
\r
719 modexPalSave(byte *palette) {
\r
722 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
723 for(i=0; i<PAL_SIZE; i++) {
\r
724 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
732 ptr = malloc(PAL_SIZE);
\r
734 /* handle errors */
\r
736 printf("Could not allocate palette.\n");
\r
745 modexLoadPalFile(byte *filename, byte **palette) {
\r
749 /* free the palette if it exists */
\r
754 /* allocate the new palette */
\r
755 *palette = modexNewPal();
\r
757 /* open the file */
\r
758 file = fopen(filename, "rb");
\r
760 printf("Could not open palette file: %s\n", filename);
\r
764 /* read the file */
\r
766 while(!feof(file)) {
\r
767 *ptr++ = fgetc(file);
\r
775 modexSavePalFile(char *filename, byte *pal) {
\r
779 /* open the file for writing */
\r
780 file = fopen(filename, "wb");
\r
782 printf("Could not open %s for writing\n", filename);
\r
786 /* write the data to the file */
\r
787 fwrite(pal, 1, PAL_SIZE, file);
\r
795 fadePalette(-1, 64, 1, tmppal);
\r
801 fadePalette(-1, -64, 1, tmppal);
\r
807 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
809 byte *p = bmp->palette;
\r
813 static word a[PAL_SIZE]; //palette array of change values!
\r
814 word z=0, aq=0, aa=0, pp=0;
\r
819 memset(a, -1, sizeof(a));
\r
820 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
830 // printf("q: %02d\n", (q));
\r
831 // printf("qq: %02d\n", (qq));
\r
832 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
833 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
835 if((*i)<PAL_SIZE/2 && w==0)
\r
837 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
839 //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
840 //____ 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
841 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
846 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
848 //printf("qp=%d\n", qp);
\r
849 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
850 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
851 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
852 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
856 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
858 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
859 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
860 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
863 //if(qp>0) printf("qp=%d\n", qp);
\r
864 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
866 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
867 if((*i)>=PAL_SIZE/2 && w==0)
\r
869 for(; (*i)<PAL_SIZE; (*i)++)
\r
871 //____ 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
872 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
877 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
879 //printf("qp=%d\n", qp);
\r
880 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
881 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
882 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
883 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
887 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
888 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
889 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
892 //printf(" (*i)=%d\n", (*i)/3);
\r
895 printf("\nqqqqqqqq\n\n");
\r
901 long bufSize = (bmp->width * bmp->height);
\r
903 //printf("1(*i)=%02d\n", (*i)/3);
\r
904 //printf("1z=%02d\n", z/3);
\r
905 chkcolor(bmp, &q, &a, &aa, &z, i);
\r
906 //printf("2(*i)=%02d\n", (*i)/3);
\r
907 //printf("2z=%02d\n", z/3);
\r
912 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
913 if(a[aq]==-1) aq++;
\r
914 else { aqoffset++; break; }
\r
916 //update the image data here!
\r
917 for(lq=0; lq<bufSize; lq++)
\r
921 use a[qp] instead of bmp->offset for this spot!
\r
926 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
929 //(offset/bmp->offset)*bmp->offset
\r
932 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
933 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
934 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
935 /*if(bmp->data[lq]+bmp->offset==aq)
\r
937 //printf("%02d", bmp->data[lq]);
\r
938 //printf("\n%02d\n", bmp->offset);
\r
939 printf("aq=%02d ", aq);
\r
940 printf("a[aq]=%02d ", a[aq]);
\r
941 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
942 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
943 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
944 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
945 // printf("_%d ", bmp->data[lq]);
\r
946 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
948 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
950 if(bmp->data[lq]+bmp->offset >= aq)
\r
952 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
953 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
955 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
958 //printf("%02d`", bmp->data[lq]);
\r
959 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
962 //printf(" aq=%02d\n", aq);
\r
963 //printf(" aa=%02d\n", aa);
\r
965 //update the palette~
\r
966 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
969 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
974 modexPalUpdate1(byte *p)
\r
978 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
979 for(i=0; i<PAL_SIZE/2; i++)
\r
981 outp(PAL_DATA_REG, p[i]);
\r
983 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
984 for(; i<PAL_SIZE; i++)
\r
986 outp(PAL_DATA_REG, p[(i)]);
\r
991 modexPalUpdate0(byte *p)
\r
995 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
996 for(i=0; i<PAL_SIZE/2; i++)
\r
998 outp(PAL_DATA_REG, rand());
\r
1000 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
1001 for(; i<PAL_SIZE; i++)
\r
1003 outp(PAL_DATA_REG, rand());
\r
1008 //i want to make another vesion that checks the palette when the palette is being appened~
\r
1009 void chkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
1013 pal = modexNewPal();
\r
1014 modexPalSave(pal);
\r
1015 //printf("q: %02d\n", (*q));
\r
1016 printf("chkcolor start~\n");
\r
1017 printf("1 (*z): %d\n", (*z)/3);
\r
1018 printf("1 (*i): %d\n", (*i)/3);
\r
1019 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
1020 printf("wwwwwwwwwwwwwwww\n");
\r
1021 //check palette for dups
\r
1022 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
1024 //printf("\n z: %d\n", (*z));
\r
1025 //printf(" q: %d\n", (*q));
\r
1026 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
1029 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
1032 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1033 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
1037 else for(zz=0; zz<(*q); zz+=3)
\r
1039 //printf("zz: %02d\n", zz/3);
\r
1042 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
1046 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
1047 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
1050 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
1052 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
1053 // 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
1054 // 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
1055 // //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
1056 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1059 //expand dong here
\r
1061 planned features that i plan to implement~
\r
1062 image that has values on the pallete list!
\r
1064 no... wait.... no wwww
\r
1066 //for(zzii=0; zzii<3; zzii++)
\r
1068 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
1069 a[(((*z)+(*q)))]=zz;
\r
1071 (*aa)=(((*z)+(*q)));
\r
1072 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
1073 // printf("\n aa: %d\n\n", (*aa));
\r
1074 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
1075 // printf("wwwwwwwwwwwwwwww\n\n");
\r
1079 printf("================\n");
\r
1080 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
1081 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
1082 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1083 printf("================\n");
\r
1085 //printf("[%d]", (zz+q));
\r
1089 printf("wwwwwwwwwwwwwwww\n");
\r
1090 printf("2 (*z): %d\n", (*z)/3);
\r
1091 printf("2 (*i): %d\n", (*i)/3);
\r
1092 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
1093 printf("chkcolor end~\n");
\r
1097 void modexputPixel(page_t *page, int x, int y, byte color)
\r
1099 word pageOff = (word) page->data;
\r
1100 /* Each address accesses four neighboring pixels, so set
\r
1101 Write Plane Enable according to which pixel we want
\r
1102 to modify. The plane is determined by the two least
\r
1103 significant bits of the x-coordinate: */
\r
1104 modexSelectPlane(PLANE(x));
\r
1105 //outp(SC_INDEX, 0x02);
\r
1106 //outp(SC_DATA, 0x01 << (x & 3));
\r
1108 /* The offset of the pixel into the video segment is
\r
1109 offset = (width * y + x) / 4, and write the given
\r
1110 color to the plane we selected above. Heed the active
\r
1111 page start selection. */
\r
1112 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
1116 byte modexgetPixel(page_t *page, int x, int y)
\r
1118 word pageOff = (word) page->data;
\r
1119 /* Select the plane from which we must read the pixel color: */
\r
1120 outpw(GC_INDEX, 0x04);
\r
1121 outpw(GC_INDEX+1, x & 3);
\r
1123 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
1127 void modexhlin(page_t *page, word xl, word xh, word y, word color)
\r
1132 for(x=0;x<xh*4;x+=4)
\r
1134 if(x+4>=SCREEN_WIDTH-1){ x=0; yy+=4; }
\r
1135 modexClearRegion(page, x+xl, y+yy, 4, 4, color);
\r
1137 //modexputPixel(page, x+xl, y, color);
\r
1140 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1142 word i, s, o, w, j, xp;
\r
1144 word addr = (word) l;
\r
1168 s=romFonts[t].seg;
\r
1169 o=romFonts[t].off;
\r
1171 for(; *str != '\0'; str++)
\r
1174 if((c=='\n'/* || c=="\
\r
1182 //load the letter 'A'
\r
1188 MOV AL, c ; the letter
\r
1191 ADD SI, AX ;the address of charcter
\r
1200 for(i=0; i<w; i++)
\r
1206 modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1215 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1217 word i, s, o, w, j, xp;
\r
1219 word addr = (word) l;
\r
1243 s=romFonts[t].seg;
\r
1244 o=romFonts[t].off;
\r
1246 for(; *str != '\0'; str++)
\r
1249 if((c=='\n'/* || c=="\
\r
1250 "*/)/* || chw>=page->width*/)
\r
1256 //load the letter 'A'
\r
1262 MOV AL, c ; the letter
\r
1265 ADD SI, AX ;the address of charcter
\r
1274 for(i=0; i<w; i++)
\r
1280 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1281 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1290 /////////////////////////////////////////////////////////////////////////////
\r
1292 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1293 // the Virtual screen. //
\r
1295 /////////////////////////////////////////////////////////////////////////////
\r
1296 void cls(page_t *page, byte color, byte *Where)
\r
1298 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1299 /* set map mask to all 4 planes */
\r
1300 outpw(SC_INDEX, 0xff02);
\r
1301 //_fmemset(VGA, color, 16000);
\r
1302 _fmemset(Where, color, page->width*(page->height));
\r
1306 modexWaitBorder() {
\r
1307 while(inp(INPUT_STATUS_1) & 8) {
\r
1311 while(!(inp(INPUT_STATUS_1) & 8)) {
\r