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
45 case 0: // deinit the video
\r
46 // change to the video mode we were in before we switched to mode 13h
\r
49 in.h.al = gv->old_mode;
\r
50 int86(0x10, &in, &out);
\r
52 case 1: // init the video
\r
53 // get old video mode
\r
55 int86(0x10, &in, &out);
\r
56 gv->old_mode = out.h.al;
\r
58 modex__320x240_256__Enter(gv);
\r
60 case 2: // init the video
\r
61 // get old video mode
\r
63 int86(0x10, &in, &out);
\r
64 gv->old_mode = out.h.al;
\r
66 modex__256x192_256__Enter(gv);
\r
72 vgaSetMode(byte mode)
\r
76 regs.h.ah = SET_MODE;
\r
78 int86(VIDEO_INT, ®s, ®s);
\r
81 /* -========================= Entry Points ==========================- */
\r
83 modex__320x240_256__Enter(global_game_variables_t *gv)
\r
86 dword far*ptr=(dword far*)VGA; /* used for faster screen clearing */
\r
88 int CRTParmCount = sizeof(ModeX_320x240regs) / sizeof(ModeX_320x240regs[0]);
\r
89 /* width and height */
\r
92 /* common mode X initiation stuff~ */
\r
93 modexsetBaseXMode();
\r
95 /* send the CRTParms */
\r
96 for(i=0; i<CRTParmCount; i++) {
\r
97 outpw(CRTC_INDEX, ModeX_320x240regs[i]);
\r
100 /* clear video memory */
\r
101 outpw(SC_INDEX, 0x0f02);
\r
102 for(i=0; i<0x8000; i++) {
\r
108 modex__256x192_256__Enter(global_game_variables_t *gv)
\r
111 dword far*ptr=(dword far*)VGA; /* used for faster screen clearing */
\r
113 int CRTParmCount = sizeof(ModeX_256x192regs) / sizeof(ModeX_256x192regs[0]);
\r
114 /* width and height */
\r
117 /* common mode X initiation stuff~ */
\r
118 modexsetBaseXMode();
\r
120 /* send the CRTParms */
\r
121 for(i=0; i<CRTParmCount; i++) {
\r
122 outpw(CRTC_INDEX, ModeX_256x192regs[i]);
\r
125 /* clear video memory */
\r
126 outpw(SC_INDEX, 0x0f02);
\r
127 for(i=0; i<0x8000; i++) {
\r
134 /* TODO restore original mode and palette */
\r
135 vgaSetMode(TEXT_MODE);
\r
138 // setBaseXMode() does the initialization to make the VGA ready to
\r
139 // accept any combination of configuration register settings. This
\r
140 // involves enabling writes to index 0 to 7 of the CRT controller (port
\r
141 // 0x3D4), by clearing the most significant bit (bit 7) of index 0x11.
\r
143 modexsetBaseXMode(void)
\r
146 /* TODO save current video mode and palette */
\r
147 vgaSetMode(VGA_256_COLOR_MODE);
\r
149 /* disable chain4 mode */
\r
150 outpw(SC_INDEX, 0x0604);
\r
152 /* synchronous reset while setting Misc Output */
\r
153 outpw(SC_INDEX, 0x0100);
\r
155 /* select 25 MHz dot clock & 60 Hz scanning rate */
\r
156 outp(MISC_OUTPUT, 0xe3);
\r
158 /* undo reset (restart sequencer) */
\r
159 outpw(SC_INDEX, 0x0300);
\r
161 /* reprogram the CRT controller */
\r
162 outp(CRTC_INDEX, 0x11); /* VSync End reg contains register write prot */
\r
163 // temp = inp(CRTC_DATA) & 0x7F;
\r
164 // outp(CRTC_INDEX, 0x11);
\r
165 outp(CRTC_DATA, 0x7f); /* get current write protect on varios regs */
\r
166 // outp(CRTC_DATA, temp); /* get current write protect on varios regs */
\r
170 modexDefaultPage() {
\r
173 /* default page values */
\r
177 page.width = SCREEN_WIDTH;
\r
178 page.height = SCREEN_HEIGHT;
\r
179 page.tw = page.width/TILEWH;
\r
180 page.th = page.height/TILEWH;
\r
186 /* returns the next page in contiguous memory
\r
187 * the next page will be the same size as p, by default
\r
190 modexNextPage(page_t *p) {
\r
193 result.data = p->data + (p->width/4)*p->height;
\r
196 result.width = p->width;
\r
197 result.height = p->height;
\r
198 result.tw = p->width/TILEWH;
\r
199 result.th = p->height/TILEWH;
\r
200 result.id = p->id+1;
\r
203 // return modexNextPageFlexibleSize(&p, p->width, p->height);
\r
206 //next page with defined dimentions~
\r
208 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
212 result.data = p->data + (p->width/4)*p->height; /* compute the offset */
\r
217 result.tw = p->width/TILEWH;
\r
218 result.th = p->height/TILEWH;
\r
219 result.id = p->id+1;
\r
226 modexShowPage(page_t *page) {
\r
232 /* calculate offset */
\r
233 offset = (word) page->data;
\r
234 offset += page->dy * (page->width >> 2 );
\r
235 offset += page->dx >> 2;
\r
237 /* calculate crtcOffset according to virtual width */
\r
238 crtcOffset = page->width >> 3;
\r
240 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
241 low_address = LOW_ADDRESS | (offset << 8);
\r
243 /* wait for appropriate timing and then program CRTC */
\r
244 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
245 outpw(CRTC_INDEX, high_address);
\r
246 outpw(CRTC_INDEX, low_address);
\r
247 outp(CRTC_INDEX, 0x13);
\r
248 outp(CRTC_DATA, crtcOffset);
\r
250 /* wait for one retrace */
\r
251 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
253 /* do PEL panning here */
\r
254 outp(AC_INDEX, 0x33);
\r
255 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
260 modexPanPage(page_t *page, int dx, int dy) {
\r
267 modexSelectPlane(byte plane) {
\r
268 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
269 outp(SC_DATA, plane);
\r
274 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
275 word pageOff = (word) page->data;
\r
276 word xoff=x/4; /* xoffset that begins each row */
\r
277 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
278 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
279 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
280 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
281 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
282 byte left = lclip[x&0x03];
\r
283 byte right = rclip[(x+w)&0x03];
\r
285 /* handle the case which requires an extra group */
\r
286 if((x & 0x03) && !((x+w) & 0x03)) {
\r
291 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
293 MOV DI, poffset ; go to the first pixel
\r
294 MOV DX, SC_INDEX ; point to the map mask
\r
298 MOV AL, color ; get ready to write colors
\r
300 MOV CX, scanCount ; count the line
\r
301 MOV BL, AL ; remember color
\r
302 MOV AL, left ; do the left clip
\r
303 OUT DX, AL ; set the left clip
\r
304 MOV AL, BL ; restore color
\r
305 STOSB ; write the color
\r
307 JZ SCAN_DONE ; handle 1 group stuff
\r
309 ;-- write the main body of the scanline
\r
310 MOV BL, AL ; remember color
\r
311 MOV AL, 0x0f ; write to all pixels
\r
313 MOV AL, BL ; restore color
\r
314 REP STOSB ; write the color
\r
316 MOV BL, AL ; remeber color
\r
318 OUT DX, AL ; do the right clip
\r
319 MOV AL, BL ; restore color
\r
320 STOSB ; write pixel
\r
321 ADD DI, nextRow ; go to the next row
\r
329 oldDrawBmp(byte far* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
335 /* TODO Make this fast. It's SLOOOOOOW */
\r
336 for(plane=0; plane < 4; plane++) {
\r
337 modexSelectPlane(PLANE(plane+x));
\r
338 for(px = plane; px < bmp->width; px+=4) {
\r
340 for(py=0; py<bmp->height; py++) {
\r
341 if(!sprite || bmp->data[offset])
\r
342 page[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
343 offset+=bmp->width;
\r
350 CDrawBmp(byte far* vgamem, page_t* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
357 /* TODO Make this fast. It's SLOOOOOOW */
\r
358 for(plane=0; plane < 4; plane++) {
\r
359 modexSelectPlane(PLANE(plane+x));
\r
360 for(px = plane; px < bmp->width; px+=4) {
\r
362 for(py=0; py<bmp->height; py++) {
\r
363 if(!sprite || bmp->data[offset])
\r
364 //modexputPixel(page, x+px, y+py, bmp->data[offset]);
\r
365 vgamem[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
366 offset+=bmp->width;
\r
373 modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) {
\r
374 /* draw the region (the entire freakin bitmap) */
\r
375 modexDrawBmpRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
380 modexDrawBmpRegion(page_t *page, int x, int y,
\r
381 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
382 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
383 byte far *data = bmp->data;//+bmp->offset;
\r
384 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
387 byte plane = 1 << ((byte) x & 0x03);
\r
388 word scanCount = width/4 + (width%4 ? 1 :0);
\r
389 word nextPageRow = page->width/4 - scanCount;
\r
390 word nextBmpRow = (word) bmp->width - width;
\r
392 byte planeCounter = 4;
\r
394 /* printf("bmp->data=%Fp\n",bmp->data);
\r
395 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
396 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
398 //code is a bit slow here
\r
400 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
403 MOV DX, SC_INDEX ; point at the map mask register
\r
408 MOV DX, SC_DATA ; select the current plane
\r
412 ;-- begin plane painting
\r
413 MOV AX, height ; start the row counter
\r
414 MOV rowCounter, AX ;
\r
415 MOV DI, poffset ; go to the first pixel
\r
416 MOV SI, bmpOffset ; go to the bmp pixel
\r
418 MOV CX, width ; count the columns
\r
420 MOVSB ; copy the pixel
\r
421 SUB CX, 3 ; we skip the next 3
\r
422 ADD SI, 3 ; skip the bmp pixels
\r
423 LOOP SCAN_LOOP ; finish the scan
\r
425 MOV AX, nextPageRow
\r
426 ADD DI, AX ; go to the next row on screen
\r
428 ADD SI, AX ; go to the next row on bmp
\r
431 JNZ ROW_LOOP ; do all the rows
\r
432 ;-- end plane painting
\r
434 MOV AL, plane ; advance to the next plane
\r
436 AND AL, 0x0f ; mask the plane properly
\r
437 MOV plane, AL ; store the plane
\r
439 INC bmpOffset ; start bmp at the right spot
\r
442 JNZ PLANE_LOOP ; do all 4 planes
\r
447 modex_sparky4_DrawBmpRegion(page_t *page, int x, int y,
\r
448 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
449 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
450 byte far *data = bmp->data;//+bmp->offset;
\r
451 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
454 byte plane = 1 << ((byte) x & 0x03);
\r
455 word scanCount = width/4 + (width%4 ? 1 :0);
\r
456 word nextPageRow = page->width/4 - scanCount;
\r
457 word nextBmpRow = (word) bmp->width - width;
\r
459 byte planeCounter = 4;
\r
461 /* printf("bmp->data=%Fp\n",bmp->data);
\r
462 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
463 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
465 //code is a bit slow here
\r
467 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
470 MOV DX, SC_INDEX ; point at the map mask register
\r
475 MOV DX, SC_DATA ; select the current plane
\r
479 ;-- begin plane painting
\r
480 MOV AX, height ; start the row counter
\r
481 MOV rowCounter, AX ;
\r
482 MOV DI, poffset ; go to the first pixel
\r
483 MOV SI, bmpOffset ; go to the bmp pixel
\r
485 MOV CX, width ; count the columns
\r
487 MOVSB ; copy the pixel
\r
488 SUB CX, 3 ; we skip the next 3
\r
489 ADD SI, 3 ; skip the bmp pixels
\r
490 LOOP SCAN_LOOP ; finish the scan
\r
492 MOV AX, nextPageRow
\r
493 ADD DI, AX ; go to the next row on screen
\r
495 ADD SI, AX ; go to the next row on bmp
\r
498 JNZ ROW_LOOP ; do all the rows
\r
499 ;-- end plane painting
\r
501 MOV AL, plane ; advance to the next plane
\r
503 AND AL, 0x0f ; mask the plane properly
\r
504 MOV plane, AL ; store the plane
\r
506 INC bmpOffset ; start bmp at the right spot
\r
509 JNZ PLANE_LOOP ; do all 4 planes
\r
514 modexDrawPlanarBuf(page_t *page, int x, int y, planar_buf_t *bmp) {
\r
515 /* TODO - adapt from test code */
\r
517 for(plane=0; plane < 4; plane++)
\r
525 modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp) {
\r
526 /* draw the whole sprite */
\r
527 modexDrawSpriteRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
531 modexDrawSpriteRegion(page_t *page, int x, int y,
\r
532 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
533 word poffset = (word)page->data + y*(page->width/4) + x/4;
\r
534 byte *data = bmp->data;//+bmp->offset;
\r
535 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
538 byte plane = 1 << ((byte) x & 0x03);
\r
539 word scanCount = width/4 + (width%4 ? 1 :0);
\r
540 word nextPageRow = page->width/4 - scanCount;
\r
541 word nextBmpRow = (word) bmp->width - width;
\r
543 byte planeCounter = 4;
\r
546 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
549 MOV DX, SC_INDEX ; point at the map mask register
\r
554 MOV DX, SC_DATA ; select the current plane
\r
558 ;-- begin plane painting
\r
559 MOV AX, height ; start the row counter
\r
560 MOV rowCounter, AX ;
\r
561 MOV DI, poffset ; go to the first pixel
\r
562 MOV SI, bmpOffset ; go to the bmp pixel
\r
564 MOV CX, width ; count the columns
\r
569 JNE DRAW_PIXEL ; draw non-zero pixels
\r
571 INC DI ; skip the transparent pixel
\r
575 MOVSB ; copy the pixel
\r
577 SUB CX, 3 ; we skip the next 3
\r
578 ADD SI, 3 ; skip the bmp pixels
\r
579 LOOP SCAN_LOOP ; finish the scan
\r
581 MOV AX, nextPageRow
\r
582 ADD DI, AX ; go to the next row on screen
\r
584 ADD SI, AX ; go to the next row on bmp
\r
587 JNZ ROW_LOOP ; do all the rows
\r
588 ;-- end plane painting
\r
590 MOV AL, plane ; advance to the next plane
\r
592 AND AL, 0x0f ; mask the plane properly
\r
593 MOV plane, AL ; store the plane
\r
595 INC bmpOffset ; start bmp at the right spot
\r
598 JNZ PLANE_LOOP ; do all 4 planes
\r
603 /* copy a region of video memory from one page to another.
\r
604 * It assumes that the left edge of the tile is the same on both
\r
605 * regions and the memory areas do not overlap.
\r
608 modexCopyPageRegion(page_t *dest, page_t *src,
\r
611 word width, word height)
\r
613 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
614 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
615 word scans = width/4;
\r
616 word nextSrcRow = src->width/4 - scans - 1;
\r
617 word nextDestRow = dest->width/4 - scans - 1;
\r
618 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
619 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
620 byte left = lclip[sx&0x03];
\r
621 byte right = rclip[(sx+width)&0x03];
\r
624 MOV AX, SCREEN_SEG ; work in the vga space
\r
629 MOV DX, GC_INDEX ; turn off cpu bits
\r
633 MOV AX, SC_INDEX ; point to the mask register
\r
643 MOV CX, scans ; the number of latches
\r
645 MOV AL, left ; do the left column
\r
650 MOV AL, 0fh ; do the inner columns
\r
652 REP MOVSB ; copy the pixels
\r
654 MOV AL, right ; do the right column
\r
659 MOV AX, SI ; go the start of the next row
\r
660 ADD AX, nextSrcRow ;
\r
663 ADD AX, nextDestRow ;
\r
666 DEC height ; do the rest of the actions
\r
669 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
670 MOV AL, 0ffh ; none from latches
\r
676 /* fade and flash */
\r
678 modexFadeOn(word fade, byte *palette) {
\r
679 fadePalette(-fade, 64, 64/fade+1, palette);
\r
684 modexFadeOff(word fade, byte *palette) {
\r
685 fadePalette(fade, 0, 64/fade+1, palette);
\r
690 modexFlashOn(word fade, byte *palette) {
\r
691 fadePalette(fade, -64, 64/fade+1, palette);
\r
696 modexFlashOff(word fade, byte *palette) {
\r
697 fadePalette(-fade, 0, 64/fade+1, palette);
\r
702 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
706 /* handle the case where we just update */
\r
708 modexPalUpdate1(palette);
\r
712 while(iter > 0) { /* FadeLoop */
\r
713 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
714 tmppal[i] = palette[i] - dim;
\r
715 if(tmppal[i] > 127) {
\r
717 } else if(tmppal[i] > 63) {
\r
721 modexPalUpdate1(tmppal);
\r
728 /* save and load */
\r
730 modexPalSave(byte *palette) {
\r
733 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
734 for(i=0; i<PAL_SIZE; i++) {
\r
735 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
743 ptr = malloc(PAL_SIZE);
\r
745 /* handle errors */
\r
747 printf("Could not allocate palette.\n");
\r
756 modexLoadPalFile(byte *filename, byte **palette) {
\r
760 /* free the palette if it exists */
\r
765 /* allocate the new palette */
\r
766 *palette = modexNewPal();
\r
768 /* open the file */
\r
769 file = fopen(filename, "rb");
\r
771 printf("Could not open palette file: %s\n", filename);
\r
775 /* read the file */
\r
777 while(!feof(file)) {
\r
778 *ptr++ = fgetc(file);
\r
786 modexSavePalFile(char *filename, byte *pal) {
\r
790 /* open the file for writing */
\r
791 file = fopen(filename, "wb");
\r
793 printf("Could not open %s for writing\n", filename);
\r
797 /* write the data to the file */
\r
798 fwrite(pal, 1, PAL_SIZE, file);
\r
806 fadePalette(-1, 64, 1, tmppal);
\r
812 fadePalette(-1, -64, 1, tmppal);
\r
818 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
820 byte *p = bmp->palette;
\r
824 static word a[PAL_SIZE]; //palette array of change values!
\r
825 word z=0, aq=0, aa=0, pp=0;
\r
830 memset(a, -1, sizeof(a));
\r
831 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
841 // printf("q: %02d\n", (q));
\r
842 // printf("qq: %02d\n", (qq));
\r
843 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
844 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
846 if((*i)<PAL_SIZE/2 && w==0)
\r
848 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
850 //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
851 //____ 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
852 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
857 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
859 //printf("qp=%d\n", qp);
\r
860 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
861 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
862 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
863 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
867 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
869 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
870 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
871 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
874 //if(qp>0) printf("qp=%d\n", qp);
\r
875 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
877 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
878 if((*i)>=PAL_SIZE/2 && w==0)
\r
880 for(; (*i)<PAL_SIZE; (*i)++)
\r
882 //____ 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
883 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
888 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
890 //printf("qp=%d\n", qp);
\r
891 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
892 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
893 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
894 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
898 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
899 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
900 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
903 //printf(" (*i)=%d\n", (*i)/3);
\r
906 printf("\nqqqqqqqq\n\n");
\r
912 long bufSize = (bmp->width * bmp->height);
\r
914 //printf("1(*i)=%02d\n", (*i)/3);
\r
915 //printf("1z=%02d\n", z/3);
\r
916 chkcolor(bmp, &q, &a, &aa, &z, i);
\r
917 //printf("2(*i)=%02d\n", (*i)/3);
\r
918 //printf("2z=%02d\n", z/3);
\r
923 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
924 if(a[aq]==-1) aq++;
\r
925 else { aqoffset++; break; }
\r
927 //update the image data here!
\r
928 for(lq=0; lq<bufSize; lq++)
\r
932 use a[qp] instead of bmp->offset for this spot!
\r
937 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
940 //(offset/bmp->offset)*bmp->offset
\r
943 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
944 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
945 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
946 /*if(bmp->data[lq]+bmp->offset==aq)
\r
948 //printf("%02d", bmp->data[lq]);
\r
949 //printf("\n%02d\n", bmp->offset);
\r
950 printf("aq=%02d ", aq);
\r
951 printf("a[aq]=%02d ", a[aq]);
\r
952 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
953 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
954 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
955 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
956 // printf("_%d ", bmp->data[lq]);
\r
957 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
959 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
961 if(bmp->data[lq]+bmp->offset >= aq)
\r
963 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
964 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
966 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
969 //printf("%02d`", bmp->data[lq]);
\r
970 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
973 //printf(" aq=%02d\n", aq);
\r
974 //printf(" aa=%02d\n", aa);
\r
976 //update the palette~
\r
977 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
980 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
985 modexPalUpdate1(byte *p)
\r
989 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
990 for(i=0; i<PAL_SIZE/2; i++)
\r
992 outp(PAL_DATA_REG, p[i]);
\r
994 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
995 for(; i<PAL_SIZE; i++)
\r
997 outp(PAL_DATA_REG, p[(i)]);
\r
1002 modexPalUpdate0(byte *p)
\r
1005 modexWaitBorder();
\r
1006 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
1007 for(i=0; i<PAL_SIZE/2; i++)
\r
1009 outp(PAL_DATA_REG, rand());
\r
1011 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
1012 for(; i<PAL_SIZE; i++)
\r
1014 outp(PAL_DATA_REG, rand());
\r
1019 //i want to make another vesion that checks the palette when the palette is being appened~
\r
1020 void chkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
1024 pal = modexNewPal();
\r
1025 modexPalSave(pal);
\r
1026 //printf("q: %02d\n", (*q));
\r
1027 printf("chkcolor start~\n");
\r
1028 printf("1 (*z): %d\n", (*z)/3);
\r
1029 printf("1 (*i): %d\n", (*i)/3);
\r
1030 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
1031 printf("wwwwwwwwwwwwwwww\n");
\r
1032 //check palette for dups
\r
1033 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
1035 //printf("\n z: %d\n", (*z));
\r
1036 //printf(" q: %d\n", (*q));
\r
1037 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
1040 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
1043 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1044 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
1048 else for(zz=0; zz<(*q); zz+=3)
\r
1050 //printf("zz: %02d\n", zz/3);
\r
1053 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
1057 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
1058 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
1061 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
1063 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
1064 // 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
1065 // 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
1066 // //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
1067 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1070 //expand dong here
\r
1072 planned features that i plan to implement~
\r
1073 image that has values on the pallete list!
\r
1075 no... wait.... no wwww
\r
1077 //for(zzii=0; zzii<3; zzii++)
\r
1079 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
1080 a[(((*z)+(*q)))]=zz;
\r
1082 (*aa)=(((*z)+(*q)));
\r
1083 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
1084 // printf("\n aa: %d\n\n", (*aa));
\r
1085 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
1086 // printf("wwwwwwwwwwwwwwww\n\n");
\r
1090 printf("================\n");
\r
1091 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
1092 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
1093 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1094 printf("================\n");
\r
1096 //printf("[%d]", (zz+q));
\r
1100 printf("wwwwwwwwwwwwwwww\n");
\r
1101 printf("2 (*z): %d\n", (*z)/3);
\r
1102 printf("2 (*i): %d\n", (*i)/3);
\r
1103 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
1104 printf("chkcolor end~\n");
\r
1108 void modexputPixel(page_t *page, int x, int y, byte color)
\r
1110 word pageOff = (word) page->data;
\r
1111 /* Each address accesses four neighboring pixels, so set
\r
1112 Write Plane Enable according to which pixel we want
\r
1113 to modify. The plane is determined by the two least
\r
1114 significant bits of the x-coordinate: */
\r
1115 modexSelectPlane(PLANE(x));
\r
1116 //outp(SC_INDEX, 0x02);
\r
1117 //outp(SC_DATA, 0x01 << (x & 3));
\r
1119 /* The offset of the pixel into the video segment is
\r
1120 offset = (width * y + x) / 4, and write the given
\r
1121 color to the plane we selected above. Heed the active
\r
1122 page start selection. */
\r
1123 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
1127 byte modexgetPixel(page_t *page, int x, int y)
\r
1129 word pageOff = (word) page->data;
\r
1130 /* Select the plane from which we must read the pixel color: */
\r
1131 outpw(GC_INDEX, 0x04);
\r
1132 outpw(GC_INDEX+1, x & 3);
\r
1134 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
1138 void modexhlin(page_t *page, word xl, word xh, word y, word color)
\r
1143 for(x=0;x<xh*4;x+=4)
\r
1145 if(x+4>=SCREEN_WIDTH-1){ x=0; yy+=4; }
\r
1146 modexClearRegion(page, x+xl, y+yy, 4, 4, color);
\r
1148 //modexputPixel(page, x+xl, y, color);
\r
1151 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1153 word i, s, o, w, j, xp;
\r
1155 word addr = (word) l;
\r
1179 s=romFonts[t].seg;
\r
1180 o=romFonts[t].off;
\r
1182 for(; *str != '\0'; str++)
\r
1185 if((c=='\n'/* || c=="\
\r
1193 //load the letter 'A'
\r
1199 MOV AL, c ; the letter
\r
1202 ADD SI, AX ;the address of charcter
\r
1211 for(i=0; i<w; i++)
\r
1217 modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1226 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1228 word i, s, o, w, j, xp;
\r
1230 word addr = (word) l;
\r
1254 s=romFonts[t].seg;
\r
1255 o=romFonts[t].off;
\r
1257 for(; *str != '\0'; str++)
\r
1260 if((c=='\n'/* || c=="\
\r
1261 "*/)/* || chw>=page->width*/)
\r
1267 //load the letter 'A'
\r
1273 MOV AL, c ; the letter
\r
1276 ADD SI, AX ;the address of charcter
\r
1285 for(i=0; i<w; i++)
\r
1291 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1292 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1301 /////////////////////////////////////////////////////////////////////////////
\r
1303 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1304 // the Virtual screen. //
\r
1306 /////////////////////////////////////////////////////////////////////////////
\r
1307 void cls(page_t *page, byte color, byte *Where)
\r
1309 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1310 /* set map mask to all 4 planes */
\r
1311 outpw(SC_INDEX, 0xff02);
\r
1312 //_fmemset(VGA, color, 16000);
\r
1313 _fmemset(Where, color, page->width*(page->height));
\r
1317 modexWaitBorder() {
\r
1318 while(inp(INPUT_STATUS_1) & 8) {
\r
1322 while(!(inp(INPUT_STATUS_1) & 8)) {
\r