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
60 modex__256x192_256__Enter(gv);
\r
65 vgaSetMode(byte mode)
\r
69 regs.h.ah = SET_MODE;
\r
71 int86(VIDEO_INT, ®s, ®s);
\r
74 /* -========================= Entry Points ==========================- */
\r
76 modex__320x240_256__Enter(global_game_variables_t *gv)
\r
79 dword far*ptr=(dword far*)VGA; /* used for faster screen clearing */
\r
81 int CRTParmCount = sizeof(ModeX_320x240regs) / sizeof(ModeX_320x240regs[0]);
\r
82 /* width and height */
\r
85 /* common mode X initiation stuff~ */
\r
86 modexsetBaseXMode();
\r
88 /* send the CRTParms */
\r
89 for(i=0; i<CRTParmCount; i++) {
\r
90 outpw(CRTC_INDEX, ModeX_320x240regs[i]);
\r
93 /* clear video memory */
\r
94 outpw(SC_INDEX, 0x0f02);
\r
95 for(i=0; i<0x8000; i++) {
\r
101 modex__256x192_256__Enter(global_game_variables_t *gv)
\r
104 dword far*ptr=(dword far*)VGA; /* used for faster screen clearing */
\r
106 int CRTParmCount = sizeof(ModeX_256x192regs) / sizeof(ModeX_256x192regs[0]);
\r
107 /* width and height */
\r
110 /* common mode X initiation stuff~ */
\r
111 modexsetBaseXMode();
\r
113 /* send the CRTParms */
\r
114 for(i=0; i<CRTParmCount; i++) {
\r
115 outpw(CRTC_INDEX, ModeX_256x192regs[i]);
\r
118 /* clear video memory */
\r
119 outpw(SC_INDEX, 0x0f02);
\r
120 for(i=0; i<0x8000; i++) {
\r
127 /* TODO restore original mode and palette */
\r
128 vgaSetMode(TEXT_MODE);
\r
131 // setBaseXMode() does the initialization to make the VGA ready to
\r
132 // accept any combination of configuration register settings. This
\r
133 // involves enabling writes to index 0 to 7 of the CRT controller (port
\r
134 // 0x3D4), by clearing the most significant bit (bit 7) of index 0x11.
\r
136 modexsetBaseXMode(void)
\r
139 /* TODO save current video mode and palette */
\r
140 vgaSetMode(VGA_256_COLOR_MODE);
\r
142 /* disable chain4 mode */
\r
143 outpw(SC_INDEX, 0x0604);
\r
145 /* synchronous reset while setting Misc Output */
\r
146 outpw(SC_INDEX, 0x0100);
\r
148 /* select 25 MHz dot clock & 60 Hz scanning rate */
\r
149 outp(MISC_OUTPUT, 0xe3);
\r
151 /* undo reset (restart sequencer) */
\r
152 outpw(SC_INDEX, 0x0300);
\r
154 /* reprogram the CRT controller */
\r
155 outp(CRTC_INDEX, 0x11); /* VSync End reg contains register write prot */
\r
156 temp = inp(CRTC_DATA) & 0x7F;
\r
157 outp(CRTC_INDEX, 0x11);
\r
158 //outp(CRTC_DATA, 0x7f); /* get current write protect on varios regs */
\r
159 outp(CRTC_DATA, temp); /* get current write protect on varios regs */
\r
163 modexDefaultPage() {
\r
166 /* default page values */
\r
170 page.width = SCREEN_WIDTH;
\r
171 page.height = SCREEN_HEIGHT;
\r
172 page.tw = page.width/TILEWH;
\r
173 page.th = page.height/TILEWH;
\r
179 /* returns the next page in contiguous memory
\r
180 * the next page will be the same size as p, by default
\r
183 modexNextPage(page_t *p) {
\r
186 result.data = p->data + (p->width/4)*p->height;
\r
189 result.width = p->width;
\r
190 result.height = p->height;
\r
191 result.tw = p->width/TILEWH;
\r
192 result.th = p->height/TILEWH;
\r
193 result.id = p->id+1;
\r
196 // return modexNextPageFlexibleSize(&p, p->width, p->height);
\r
199 //next page with defined dimentions~
\r
201 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
205 result.data = p->data + (p->width/4)*p->height; /* compute the offset */
\r
210 result.tw = p->width/TILEWH;
\r
211 result.th = p->height/TILEWH;
\r
212 result.id = p->id+1;
\r
219 modexShowPage(page_t *page) {
\r
225 /* calculate offset */
\r
226 offset = (word) page->data;
\r
227 offset += page->dy * (page->width >> 2 );
\r
228 offset += page->dx >> 2;
\r
230 /* calculate crtcOffset according to virtual width */
\r
231 crtcOffset = page->width >> 3;
\r
233 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
234 low_address = LOW_ADDRESS | (offset << 8);
\r
236 /* wait for appropriate timing and then program CRTC */
\r
237 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
238 outpw(CRTC_INDEX, high_address);
\r
239 outpw(CRTC_INDEX, low_address);
\r
240 outp(CRTC_INDEX, 0x13);
\r
241 outp(CRTC_DATA, crtcOffset);
\r
243 /* wait for one retrace */
\r
244 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
246 /* do PEL panning here */
\r
247 outp(AC_INDEX, 0x33);
\r
248 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
253 modexPanPage(page_t *page, int dx, int dy) {
\r
260 modexSelectPlane(byte plane) {
\r
261 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
262 outp(SC_DATA, plane);
\r
267 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
268 word pageOff = (word) page->data;
\r
269 word xoff=x/4; /* xoffset that begins each row */
\r
270 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
271 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
272 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
273 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
274 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
275 byte left = lclip[x&0x03];
\r
276 byte right = rclip[(x+w)&0x03];
\r
278 /* handle the case which requires an extra group */
\r
279 if((x & 0x03) && !((x+w) & 0x03)) {
\r
284 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
286 MOV DI, poffset ; go to the first pixel
\r
287 MOV DX, SC_INDEX ; point to the map mask
\r
291 MOV AL, color ; get ready to write colors
\r
293 MOV CX, scanCount ; count the line
\r
294 MOV BL, AL ; remember color
\r
295 MOV AL, left ; do the left clip
\r
296 OUT DX, AL ; set the left clip
\r
297 MOV AL, BL ; restore color
\r
298 STOSB ; write the color
\r
300 JZ SCAN_DONE ; handle 1 group stuff
\r
302 ;-- write the main body of the scanline
\r
303 MOV BL, AL ; remember color
\r
304 MOV AL, 0x0f ; write to all pixels
\r
306 MOV AL, BL ; restore color
\r
307 REP STOSB ; write the color
\r
309 MOV BL, AL ; remeber color
\r
311 OUT DX, AL ; do the right clip
\r
312 MOV AL, BL ; restore color
\r
313 STOSB ; write pixel
\r
314 ADD DI, nextRow ; go to the next row
\r
322 oldDrawBmp(byte far* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
328 /* TODO Make this fast. It's SLOOOOOOW */
\r
329 for(plane=0; plane < 4; plane++) {
\r
330 modexSelectPlane(PLANE(plane+x));
\r
331 for(px = plane; px < bmp->width; px+=4) {
\r
333 for(py=0; py<bmp->height; py++) {
\r
334 if(!sprite || bmp->data[offset])
\r
335 page[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
336 offset+=bmp->width;
\r
343 CDrawBmp(byte far* vgamem, page_t* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
350 /* TODO Make this fast. It's SLOOOOOOW */
\r
351 for(plane=0; plane < 4; plane++) {
\r
352 modexSelectPlane(PLANE(plane+x));
\r
353 for(px = plane; px < bmp->width; px+=4) {
\r
355 for(py=0; py<bmp->height; py++) {
\r
356 if(!sprite || bmp->data[offset])
\r
357 //modexputPixel(page, x+px, y+py, bmp->data[offset]);
\r
358 vgamem[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
359 offset+=bmp->width;
\r
366 modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) {
\r
367 /* draw the region (the entire freakin bitmap) */
\r
368 modexDrawBmpRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
373 modexDrawBmpRegion(page_t *page, int x, int y,
\r
374 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
375 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
376 byte far *data = bmp->data;//+bmp->offset;
\r
377 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
380 byte plane = 1 << ((byte) x & 0x03);
\r
381 word scanCount = width/4 + (width%4 ? 1 :0);
\r
382 word nextPageRow = page->width/4 - scanCount;
\r
383 word nextBmpRow = (word) bmp->width - width;
\r
385 byte planeCounter = 4;
\r
387 /* printf("bmp->data=%Fp\n",bmp->data);
\r
388 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
389 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
391 //code is a bit slow here
\r
393 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
396 MOV DX, SC_INDEX ; point at the map mask register
\r
401 MOV DX, SC_DATA ; select the current plane
\r
405 ;-- begin plane painting
\r
406 MOV AX, height ; start the row counter
\r
407 MOV rowCounter, AX ;
\r
408 MOV DI, poffset ; go to the first pixel
\r
409 MOV SI, bmpOffset ; go to the bmp pixel
\r
411 MOV CX, width ; count the columns
\r
413 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 modex_sparky4_DrawBmpRegion(page_t *page, int x, int y,
\r
441 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
442 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
443 byte far *data = bmp->data;//+bmp->offset;
\r
444 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
447 byte plane = 1 << ((byte) x & 0x03);
\r
448 word scanCount = width/4 + (width%4 ? 1 :0);
\r
449 word nextPageRow = page->width/4 - scanCount;
\r
450 word nextBmpRow = (word) bmp->width - width;
\r
452 byte planeCounter = 4;
\r
454 /* printf("bmp->data=%Fp\n",bmp->data);
\r
455 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
456 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
458 //code is a bit slow here
\r
460 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
463 MOV DX, SC_INDEX ; point at the map mask register
\r
468 MOV DX, SC_DATA ; select the current plane
\r
472 ;-- begin plane painting
\r
473 MOV AX, height ; start the row counter
\r
474 MOV rowCounter, AX ;
\r
475 MOV DI, poffset ; go to the first pixel
\r
476 MOV SI, bmpOffset ; go to the bmp pixel
\r
478 MOV CX, width ; count the columns
\r
480 MOVSB ; copy the pixel
\r
481 SUB CX, 3 ; we skip the next 3
\r
482 ADD SI, 3 ; skip the bmp pixels
\r
483 LOOP SCAN_LOOP ; finish the scan
\r
485 MOV AX, nextPageRow
\r
486 ADD DI, AX ; go to the next row on screen
\r
488 ADD SI, AX ; go to the next row on bmp
\r
491 JNZ ROW_LOOP ; do all the rows
\r
492 ;-- end plane painting
\r
494 MOV AL, plane ; advance to the next plane
\r
496 AND AL, 0x0f ; mask the plane properly
\r
497 MOV plane, AL ; store the plane
\r
499 INC bmpOffset ; start bmp at the right spot
\r
502 JNZ PLANE_LOOP ; do all 4 planes
\r
507 modexDrawPlanarBuf(page_t *page, int x, int y, planar_buf_t *bmp) {
\r
508 /* TODO - adapt from test code */
\r
510 for(plane=0; plane < 4; plane++)
\r
518 modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp) {
\r
519 /* draw the whole sprite */
\r
520 modexDrawSpriteRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
524 modexDrawSpriteRegion(page_t *page, int x, int y,
\r
525 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
526 word poffset = (word)page->data + y*(page->width/4) + x/4;
\r
527 byte *data = bmp->data;//+bmp->offset;
\r
528 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
531 byte plane = 1 << ((byte) x & 0x03);
\r
532 word scanCount = width/4 + (width%4 ? 1 :0);
\r
533 word nextPageRow = page->width/4 - scanCount;
\r
534 word nextBmpRow = (word) bmp->width - width;
\r
536 byte planeCounter = 4;
\r
539 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
542 MOV DX, SC_INDEX ; point at the map mask register
\r
547 MOV DX, SC_DATA ; select the current plane
\r
551 ;-- begin plane painting
\r
552 MOV AX, height ; start the row counter
\r
553 MOV rowCounter, AX ;
\r
554 MOV DI, poffset ; go to the first pixel
\r
555 MOV SI, bmpOffset ; go to the bmp pixel
\r
557 MOV CX, width ; count the columns
\r
562 JNE DRAW_PIXEL ; draw non-zero pixels
\r
564 INC DI ; skip the transparent pixel
\r
568 MOVSB ; copy the pixel
\r
570 SUB CX, 3 ; we skip the next 3
\r
571 ADD SI, 3 ; skip the bmp pixels
\r
572 LOOP SCAN_LOOP ; finish the scan
\r
574 MOV AX, nextPageRow
\r
575 ADD DI, AX ; go to the next row on screen
\r
577 ADD SI, AX ; go to the next row on bmp
\r
580 JNZ ROW_LOOP ; do all the rows
\r
581 ;-- end plane painting
\r
583 MOV AL, plane ; advance to the next plane
\r
585 AND AL, 0x0f ; mask the plane properly
\r
586 MOV plane, AL ; store the plane
\r
588 INC bmpOffset ; start bmp at the right spot
\r
591 JNZ PLANE_LOOP ; do all 4 planes
\r
596 /* copy a region of video memory from one page to another.
\r
597 * It assumes that the left edge of the tile is the same on both
\r
598 * regions and the memory areas do not overlap.
\r
601 modexCopyPageRegion(page_t *dest, page_t *src,
\r
604 word width, word height)
\r
606 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
607 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
608 word scans = width/4;
\r
609 word nextSrcRow = src->width/4 - scans - 1;
\r
610 word nextDestRow = dest->width/4 - scans - 1;
\r
611 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
612 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
613 byte left = lclip[sx&0x03];
\r
614 byte right = rclip[(sx+width)&0x03];
\r
617 MOV AX, SCREEN_SEG ; work in the vga space
\r
622 MOV DX, GC_INDEX ; turn off cpu bits
\r
626 MOV AX, SC_INDEX ; point to the mask register
\r
636 MOV CX, scans ; the number of latches
\r
638 MOV AL, left ; do the left column
\r
643 MOV AL, 0fh ; do the inner columns
\r
645 REP MOVSB ; copy the pixels
\r
647 MOV AL, right ; do the right column
\r
652 MOV AX, SI ; go the start of the next row
\r
653 ADD AX, nextSrcRow ;
\r
656 ADD AX, nextDestRow ;
\r
659 DEC height ; do the rest of the actions
\r
662 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
663 MOV AL, 0ffh ; none from latches
\r
669 /* fade and flash */
\r
671 modexFadeOn(word fade, byte *palette) {
\r
672 fadePalette(-fade, 64, 64/fade+1, palette);
\r
677 modexFadeOff(word fade, byte *palette) {
\r
678 fadePalette(fade, 0, 64/fade+1, palette);
\r
683 modexFlashOn(word fade, byte *palette) {
\r
684 fadePalette(fade, -64, 64/fade+1, palette);
\r
689 modexFlashOff(word fade, byte *palette) {
\r
690 fadePalette(-fade, 0, 64/fade+1, palette);
\r
695 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
699 /* handle the case where we just update */
\r
701 modexPalUpdate1(palette);
\r
705 while(iter > 0) { /* FadeLoop */
\r
706 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
707 tmppal[i] = palette[i] - dim;
\r
708 if(tmppal[i] > 127) {
\r
710 } else if(tmppal[i] > 63) {
\r
714 modexPalUpdate1(tmppal);
\r
721 /* save and load */
\r
723 modexPalSave(byte *palette) {
\r
726 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
727 for(i=0; i<PAL_SIZE; i++) {
\r
728 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
736 ptr = malloc(PAL_SIZE);
\r
738 /* handle errors */
\r
740 printf("Could not allocate palette.\n");
\r
749 modexLoadPalFile(byte *filename, byte **palette) {
\r
753 /* free the palette if it exists */
\r
758 /* allocate the new palette */
\r
759 *palette = modexNewPal();
\r
761 /* open the file */
\r
762 file = fopen(filename, "rb");
\r
764 printf("Could not open palette file: %s\n", filename);
\r
768 /* read the file */
\r
770 while(!feof(file)) {
\r
771 *ptr++ = fgetc(file);
\r
779 modexSavePalFile(char *filename, byte *pal) {
\r
783 /* open the file for writing */
\r
784 file = fopen(filename, "wb");
\r
786 printf("Could not open %s for writing\n", filename);
\r
790 /* write the data to the file */
\r
791 fwrite(pal, 1, PAL_SIZE, file);
\r
799 fadePalette(-1, 64, 1, tmppal);
\r
805 fadePalette(-1, -64, 1, tmppal);
\r
811 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
813 byte *p = bmp->palette;
\r
817 static word a[PAL_SIZE]; //palette array of change values!
\r
818 word z=0, aq=0, aa=0, pp=0;
\r
823 memset(a, -1, sizeof(a));
\r
824 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
834 // printf("q: %02d\n", (q));
\r
835 // printf("qq: %02d\n", (qq));
\r
836 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
837 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
839 if((*i)<PAL_SIZE/2 && w==0)
\r
841 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
843 //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
844 //____ 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
845 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
850 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
852 //printf("qp=%d\n", qp);
\r
853 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
854 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
855 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
856 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
860 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
862 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
863 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
864 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
867 //if(qp>0) printf("qp=%d\n", qp);
\r
868 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
870 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
871 if((*i)>=PAL_SIZE/2 && w==0)
\r
873 for(; (*i)<PAL_SIZE; (*i)++)
\r
875 //____ 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
876 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
881 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
883 //printf("qp=%d\n", qp);
\r
884 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
885 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
886 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
887 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
891 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
892 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
893 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
896 //printf(" (*i)=%d\n", (*i)/3);
\r
899 printf("\nqqqqqqqq\n\n");
\r
905 long bufSize = (bmp->width * bmp->height);
\r
907 //printf("1(*i)=%02d\n", (*i)/3);
\r
908 //printf("1z=%02d\n", z/3);
\r
909 chkcolor(bmp, &q, &a, &aa, &z, i);
\r
910 //printf("2(*i)=%02d\n", (*i)/3);
\r
911 //printf("2z=%02d\n", z/3);
\r
916 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
917 if(a[aq]==-1) aq++;
\r
918 else { aqoffset++; break; }
\r
920 //update the image data here!
\r
921 for(lq=0; lq<bufSize; lq++)
\r
925 use a[qp] instead of bmp->offset for this spot!
\r
930 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
933 //(offset/bmp->offset)*bmp->offset
\r
936 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
937 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
938 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
939 /*if(bmp->data[lq]+bmp->offset==aq)
\r
941 //printf("%02d", bmp->data[lq]);
\r
942 //printf("\n%02d\n", bmp->offset);
\r
943 printf("aq=%02d ", aq);
\r
944 printf("a[aq]=%02d ", a[aq]);
\r
945 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
946 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
947 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
948 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
949 // printf("_%d ", bmp->data[lq]);
\r
950 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
952 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
954 if(bmp->data[lq]+bmp->offset >= aq)
\r
956 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
957 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
959 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
962 //printf("%02d`", bmp->data[lq]);
\r
963 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
966 //printf(" aq=%02d\n", aq);
\r
967 //printf(" aa=%02d\n", aa);
\r
969 //update the palette~
\r
970 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
973 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
978 modexPalUpdate1(byte *p)
\r
982 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
983 for(i=0; i<PAL_SIZE/2; i++)
\r
985 outp(PAL_DATA_REG, p[i]);
\r
987 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
988 for(; i<PAL_SIZE; i++)
\r
990 outp(PAL_DATA_REG, p[(i)]);
\r
995 modexPalUpdate0(byte *p)
\r
999 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
1000 for(i=0; i<PAL_SIZE/2; i++)
\r
1002 outp(PAL_DATA_REG, rand());
\r
1004 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
1005 for(; i<PAL_SIZE; i++)
\r
1007 outp(PAL_DATA_REG, rand());
\r
1012 //i want to make another vesion that checks the palette when the palette is being appened~
\r
1013 void chkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
1017 pal = modexNewPal();
\r
1018 modexPalSave(pal);
\r
1019 //printf("q: %02d\n", (*q));
\r
1020 printf("chkcolor start~\n");
\r
1021 printf("1 (*z): %d\n", (*z)/3);
\r
1022 printf("1 (*i): %d\n", (*i)/3);
\r
1023 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
1024 printf("wwwwwwwwwwwwwwww\n");
\r
1025 //check palette for dups
\r
1026 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
1028 //printf("\n z: %d\n", (*z));
\r
1029 //printf(" q: %d\n", (*q));
\r
1030 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
1033 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
1036 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1037 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
1041 else for(zz=0; zz<(*q); zz+=3)
\r
1043 //printf("zz: %02d\n", zz/3);
\r
1046 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
1050 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
1051 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
1054 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
1056 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
1057 // 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
1058 // 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
1059 // //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
1060 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1063 //expand dong here
\r
1065 planned features that i plan to implement~
\r
1066 image that has values on the pallete list!
\r
1068 no... wait.... no wwww
\r
1070 //for(zzii=0; zzii<3; zzii++)
\r
1072 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
1073 a[(((*z)+(*q)))]=zz;
\r
1075 (*aa)=(((*z)+(*q)));
\r
1076 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
1077 // printf("\n aa: %d\n\n", (*aa));
\r
1078 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
1079 // printf("wwwwwwwwwwwwwwww\n\n");
\r
1083 printf("================\n");
\r
1084 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
1085 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
1086 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1087 printf("================\n");
\r
1089 //printf("[%d]", (zz+q));
\r
1093 printf("wwwwwwwwwwwwwwww\n");
\r
1094 printf("2 (*z): %d\n", (*z)/3);
\r
1095 printf("2 (*i): %d\n", (*i)/3);
\r
1096 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
1097 printf("chkcolor end~\n");
\r
1101 void modexputPixel(page_t *page, int x, int y, byte color)
\r
1103 word pageOff = (word) page->data;
\r
1104 /* Each address accesses four neighboring pixels, so set
\r
1105 Write Plane Enable according to which pixel we want
\r
1106 to modify. The plane is determined by the two least
\r
1107 significant bits of the x-coordinate: */
\r
1108 modexSelectPlane(PLANE(x));
\r
1109 //outp(SC_INDEX, 0x02);
\r
1110 //outp(SC_DATA, 0x01 << (x & 3));
\r
1112 /* The offset of the pixel into the video segment is
\r
1113 offset = (width * y + x) / 4, and write the given
\r
1114 color to the plane we selected above. Heed the active
\r
1115 page start selection. */
\r
1116 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
1120 byte modexgetPixel(page_t *page, int x, int y)
\r
1122 word pageOff = (word) page->data;
\r
1123 /* Select the plane from which we must read the pixel color: */
\r
1124 outpw(GC_INDEX, 0x04);
\r
1125 outpw(GC_INDEX+1, x & 3);
\r
1127 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
1131 void modexhlin(page_t *page, word xl, word xh, word y, word color)
\r
1136 for(x=0;x<xh*4;x+=4)
\r
1138 if(x+4>=SCREEN_WIDTH-1){ x=0; yy+=4; }
\r
1139 modexClearRegion(page, x+xl, y+yy, 4, 4, color);
\r
1141 //modexputPixel(page, x+xl, y, color);
\r
1144 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1146 word i, s, o, w, j, xp;
\r
1148 word addr = (word) l;
\r
1172 s=romFonts[t].seg;
\r
1173 o=romFonts[t].off;
\r
1175 for(; *str != '\0'; str++)
\r
1178 if((c=='\n'/* || c=="\
\r
1186 //load the letter 'A'
\r
1192 MOV AL, c ; the letter
\r
1195 ADD SI, AX ;the address of charcter
\r
1204 for(i=0; i<w; i++)
\r
1210 modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1219 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1221 word i, s, o, w, j, xp;
\r
1223 word addr = (word) l;
\r
1247 s=romFonts[t].seg;
\r
1248 o=romFonts[t].off;
\r
1250 for(; *str != '\0'; str++)
\r
1253 if((c=='\n'/* || c=="\
\r
1254 "*/)/* || chw>=page->width*/)
\r
1260 //load the letter 'A'
\r
1266 MOV AL, c ; the letter
\r
1269 ADD SI, AX ;the address of charcter
\r
1278 for(i=0; i<w; i++)
\r
1284 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1285 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1294 /////////////////////////////////////////////////////////////////////////////
\r
1296 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1297 // the Virtual screen. //
\r
1299 /////////////////////////////////////////////////////////////////////////////
\r
1300 void cls(page_t *page, byte color, byte *Where)
\r
1302 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1303 /* set map mask to all 4 planes */
\r
1304 outpw(SC_INDEX, 0xff02);
\r
1305 //_fmemset(VGA, color, 16000);
\r
1306 _fmemset(Where, color, page->width*(page->height));
\r
1310 modexWaitBorder() {
\r
1311 while(inp(INPUT_STATUS_1) & 8) {
\r
1315 while(!(inp(INPUT_STATUS_1) & 8)) {
\r