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 0x4f01, /* horizontal display enable end */
\r
84 0x0d06, /* vertical total */
\r
85 0x3e07, /* overflow (bit 8 of vertical counts) */
\r
86 0x4109, /* cell height (2 to double-scan */
\r
87 0xea10, /* v sync start */
\r
88 0xac11, /* v sync end and protect cr0-cr7 */
\r
89 0xdf12, /* vertical displayed */
\r
90 0x2813, /* offset/logical width */
\r
91 0x0014, /* turn off dword mode */
\r
92 0xe715, /* v blank start */
\r
93 0x0616, /* v blank end */
\r
94 0xe317 /* turn on byte mode */
\r
97 int CRTParmCount = sizeof(CRTParms) / sizeof(CRTParms[0]);
\r
98 /* width and height */
\r
101 /* common mode X initiation stuff~ */
\r
102 modexsetBaseXMode();
\r
104 /* send the CRTParms */
\r
105 for(i=0; i<CRTParmCount; i++) {
\r
106 outpw(CRTC_INDEX, CRTParms[i]);
\r
109 /* clear video memory */
\r
110 outpw(SC_INDEX, 0x0f02);
\r
111 for(i=0; i<0x8000; i++) {
\r
118 /* TODO restore original mode and palette */
\r
119 vgaSetMode(TEXT_MODE);
\r
122 // setBaseXMode() does the initialization to make the VGA ready to
\r
123 // accept any combination of configuration register settings. This
\r
124 // involves enabling writes to index 0 to 7 of the CRT controller (port
\r
125 // 0x3D4), by clearing the most significant bit (bit 7) of index 0x11.
\r
127 modexsetBaseXMode(void)
\r
130 /* TODO save current video mode and palette */
\r
131 vgaSetMode(VGA_256_COLOR_MODE);
\r
133 /* disable chain4 mode */
\r
134 outpw(SC_INDEX, 0x0604);
\r
136 /* synchronous reset while setting Misc Output */
\r
137 outpw(SC_INDEX, 0x0100);
\r
139 /* select 25 MHz dot clock & 60 Hz scanning rate */
\r
140 outp(MISC_OUTPUT, 0xe3);
\r
142 /* undo reset (restart sequencer) */
\r
143 outpw(SC_INDEX, 0x0300);
\r
145 /* reprogram the CRT controller */
\r
146 outp(CRTC_INDEX, 0x11); /* VSync End reg contains register write prot */
\r
147 temp = inp(CRTC_DATA) & 0x7F;
\r
148 outp(CRTC_INDEX, 0x11);
\r
149 //outp(CRTC_DATA, 0x7f); /* get current write protect on varios regs */
\r
150 outp(CRTC_DATA, temp); /* get current write protect on varios regs */
\r
154 modexDefaultPage() {
\r
157 /* default page values */
\r
161 page.width = SCREEN_WIDTH;
\r
162 page.height = SCREEN_HEIGHT;
\r
163 page.tw = page.width/TILEWH;
\r
164 page.th = page.height/TILEWH;
\r
170 /* returns the next page in contiguous memory
\r
171 * the next page will be the same size as p, by default
\r
174 modexNextPage(page_t *p) {
\r
177 result.data = p->data + (p->width/4)*p->height;
\r
180 result.width = p->width;
\r
181 result.height = p->height;
\r
182 result.tw = p->width/TILEWH;
\r
183 result.th = p->height/TILEWH;
\r
184 result.id = p->id+1;
\r
187 // return modexNextPageFlexibleSize(&p, p->width, p->height);
\r
190 //next page with defined dimentions~
\r
192 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
196 result.data = p->data + (p->width/4)*p->height; /* compute the offset */
\r
201 result.tw = p->width/TILEWH;
\r
202 result.th = p->height/TILEWH;
\r
203 result.id = p->id+1;
\r
210 modexShowPage(page_t *page) {
\r
216 /* calculate offset */
\r
217 offset = (word) page->data;
\r
218 offset += page->dy * (page->width >> 2 );
\r
219 offset += page->dx >> 2;
\r
221 /* calculate crtcOffset according to virtual width */
\r
222 crtcOffset = page->width >> 3;
\r
224 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
225 low_address = LOW_ADDRESS | (offset << 8);
\r
227 /* wait for appropriate timing and then program CRTC */
\r
228 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
229 outpw(CRTC_INDEX, high_address);
\r
230 outpw(CRTC_INDEX, low_address);
\r
231 outp(CRTC_INDEX, 0x13);
\r
232 outp(CRTC_DATA, crtcOffset);
\r
234 /* wait for one retrace */
\r
235 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
237 /* do PEL panning here */
\r
238 outp(AC_INDEX, 0x33);
\r
239 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
244 modexPanPage(page_t *page, int dx, int dy) {
\r
251 modexSelectPlane(byte plane) {
\r
252 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
253 outp(SC_DATA, plane);
\r
258 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
259 word pageOff = (word) page->data;
\r
260 word xoff=x/4; /* xoffset that begins each row */
\r
261 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
262 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
263 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
264 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
265 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
266 byte left = lclip[x&0x03];
\r
267 byte right = rclip[(x+w)&0x03];
\r
269 /* handle the case which requires an extra group */
\r
270 if((x & 0x03) && !((x+w) & 0x03)) {
\r
275 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
277 MOV DI, poffset ; go to the first pixel
\r
278 MOV DX, SC_INDEX ; point to the map mask
\r
282 MOV AL, color ; get ready to write colors
\r
284 MOV CX, scanCount ; count the line
\r
285 MOV BL, AL ; remember color
\r
286 MOV AL, left ; do the left clip
\r
287 OUT DX, AL ; set the left clip
\r
288 MOV AL, BL ; restore color
\r
289 STOSB ; write the color
\r
291 JZ SCAN_DONE ; handle 1 group stuff
\r
293 ;-- write the main body of the scanline
\r
294 MOV BL, AL ; remember color
\r
295 MOV AL, 0x0f ; write to all pixels
\r
297 MOV AL, BL ; restore color
\r
298 REP STOSB ; write the color
\r
300 MOV BL, AL ; remeber color
\r
302 OUT DX, AL ; do the right clip
\r
303 MOV AL, BL ; restore color
\r
304 STOSB ; write pixel
\r
305 ADD DI, nextRow ; go to the next row
\r
313 oldDrawBmp(byte far* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
319 /* TODO Make this fast. It's SLOOOOOOW */
\r
320 for(plane=0; plane < 4; plane++) {
\r
321 modexSelectPlane(PLANE(plane+x));
\r
322 for(px = plane; px < bmp->width; px+=4) {
\r
324 for(py=0; py<bmp->height; py++) {
\r
325 if(!sprite || bmp->data[offset])
\r
326 page[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
327 offset+=bmp->width;
\r
334 CDrawBmp(byte far* vgamem, page_t* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
341 /* TODO Make this fast. It's SLOOOOOOW */
\r
342 for(plane=0; plane < 4; plane++) {
\r
343 modexSelectPlane(PLANE(plane+x));
\r
344 for(px = plane; px < bmp->width; px+=4) {
\r
346 for(py=0; py<bmp->height; py++) {
\r
347 if(!sprite || bmp->data[offset])
\r
348 //modexputPixel(page, x+px, y+py, bmp->data[offset]);
\r
349 vgamem[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
350 offset+=bmp->width;
\r
357 modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) {
\r
358 /* draw the region (the entire freakin bitmap) */
\r
359 modexDrawBmpRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
364 modexDrawBmpRegion(page_t *page, int x, int y,
\r
365 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
366 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
367 byte far *data = bmp->data;//+bmp->offset;
\r
368 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
371 byte plane = 1 << ((byte) x & 0x03);
\r
372 word scanCount = width/4 + (width%4 ? 1 :0);
\r
373 word nextPageRow = page->width/4 - scanCount;
\r
374 word nextBmpRow = (word) bmp->width - width;
\r
376 byte planeCounter = 4;
\r
378 /* printf("bmp->data=%Fp\n",bmp->data);
\r
379 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
380 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
382 //code is a bit slow here
\r
384 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
387 MOV DX, SC_INDEX ; point at the map mask register
\r
392 MOV DX, SC_DATA ; select the current plane
\r
396 ;-- begin plane painting
\r
397 MOV AX, height ; start the row counter
\r
398 MOV rowCounter, AX ;
\r
399 MOV DI, poffset ; go to the first pixel
\r
400 MOV SI, bmpOffset ; go to the bmp pixel
\r
402 MOV CX, width ; count the columns
\r
404 MOVSB ; copy the pixel
\r
405 SUB CX, 3 ; we skip the next 3
\r
406 ADD SI, 3 ; skip the bmp pixels
\r
407 LOOP SCAN_LOOP ; finish the scan
\r
409 MOV AX, nextPageRow
\r
410 ADD DI, AX ; go to the next row on screen
\r
412 ADD SI, AX ; go to the next row on bmp
\r
415 JNZ ROW_LOOP ; do all the rows
\r
416 ;-- end plane painting
\r
418 MOV AL, plane ; advance to the next plane
\r
420 AND AL, 0x0f ; mask the plane properly
\r
421 MOV plane, AL ; store the plane
\r
423 INC bmpOffset ; start bmp at the right spot
\r
426 JNZ PLANE_LOOP ; do all 4 planes
\r
431 modex_sparky4_DrawBmpRegion(page_t *page, int x, int y,
\r
432 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
433 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
434 byte far *data = bmp->data;//+bmp->offset;
\r
435 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
438 byte plane = 1 << ((byte) x & 0x03);
\r
439 word scanCount = width/4 + (width%4 ? 1 :0);
\r
440 word nextPageRow = page->width/4 - scanCount;
\r
441 word nextBmpRow = (word) bmp->width - width;
\r
443 byte planeCounter = 4;
\r
445 /* printf("bmp->data=%Fp\n",bmp->data);
\r
446 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
447 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
449 //code is a bit slow here
\r
451 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
454 MOV DX, SC_INDEX ; point at the map mask register
\r
459 MOV DX, SC_DATA ; select the current plane
\r
463 ;-- begin plane painting
\r
464 MOV AX, height ; start the row counter
\r
465 MOV rowCounter, AX ;
\r
466 MOV DI, poffset ; go to the first pixel
\r
467 MOV SI, bmpOffset ; go to the bmp pixel
\r
469 MOV CX, width ; count the columns
\r
471 MOVSB ; copy the pixel
\r
472 SUB CX, 3 ; we skip the next 3
\r
473 ADD SI, 3 ; skip the bmp pixels
\r
474 LOOP SCAN_LOOP ; finish the scan
\r
476 MOV AX, nextPageRow
\r
477 ADD DI, AX ; go to the next row on screen
\r
479 ADD SI, AX ; go to the next row on bmp
\r
482 JNZ ROW_LOOP ; do all the rows
\r
483 ;-- end plane painting
\r
485 MOV AL, plane ; advance to the next plane
\r
487 AND AL, 0x0f ; mask the plane properly
\r
488 MOV plane, AL ; store the plane
\r
490 INC bmpOffset ; start bmp at the right spot
\r
493 JNZ PLANE_LOOP ; do all 4 planes
\r
498 modexDrawPlanarBuf(page_t *page, int x, int y, planar_buf_t *bmp) {
\r
499 /* TODO - adapt from test code */
\r
501 for(plane=0; plane < 4; plane++)
\r
509 modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp) {
\r
510 /* draw the whole sprite */
\r
511 modexDrawSpriteRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
515 modexDrawSpriteRegion(page_t *page, int x, int y,
\r
516 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
517 word poffset = (word)page->data + y*(page->width/4) + x/4;
\r
518 byte *data = bmp->data;//+bmp->offset;
\r
519 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
522 byte plane = 1 << ((byte) x & 0x03);
\r
523 word scanCount = width/4 + (width%4 ? 1 :0);
\r
524 word nextPageRow = page->width/4 - scanCount;
\r
525 word nextBmpRow = (word) bmp->width - width;
\r
527 byte planeCounter = 4;
\r
530 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
533 MOV DX, SC_INDEX ; point at the map mask register
\r
538 MOV DX, SC_DATA ; select the current plane
\r
542 ;-- begin plane painting
\r
543 MOV AX, height ; start the row counter
\r
544 MOV rowCounter, AX ;
\r
545 MOV DI, poffset ; go to the first pixel
\r
546 MOV SI, bmpOffset ; go to the bmp pixel
\r
548 MOV CX, width ; count the columns
\r
553 JNE DRAW_PIXEL ; draw non-zero pixels
\r
555 INC DI ; skip the transparent pixel
\r
559 MOVSB ; copy the pixel
\r
561 SUB CX, 3 ; we skip the next 3
\r
562 ADD SI, 3 ; skip the bmp pixels
\r
563 LOOP SCAN_LOOP ; finish the scan
\r
565 MOV AX, nextPageRow
\r
566 ADD DI, AX ; go to the next row on screen
\r
568 ADD SI, AX ; go to the next row on bmp
\r
571 JNZ ROW_LOOP ; do all the rows
\r
572 ;-- end plane painting
\r
574 MOV AL, plane ; advance to the next plane
\r
576 AND AL, 0x0f ; mask the plane properly
\r
577 MOV plane, AL ; store the plane
\r
579 INC bmpOffset ; start bmp at the right spot
\r
582 JNZ PLANE_LOOP ; do all 4 planes
\r
587 /* copy a region of video memory from one page to another.
\r
588 * It assumes that the left edge of the tile is the same on both
\r
589 * regions and the memory areas do not overlap.
\r
592 modexCopyPageRegion(page_t *dest, page_t *src,
\r
595 word width, word height)
\r
597 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
598 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
599 word scans = width/4;
\r
600 word nextSrcRow = src->width/4 - scans - 1;
\r
601 word nextDestRow = dest->width/4 - scans - 1;
\r
602 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
603 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
604 byte left = lclip[sx&0x03];
\r
605 byte right = rclip[(sx+width)&0x03];
\r
608 MOV AX, SCREEN_SEG ; work in the vga space
\r
613 MOV DX, GC_INDEX ; turn off cpu bits
\r
617 MOV AX, SC_INDEX ; point to the mask register
\r
627 MOV CX, scans ; the number of latches
\r
629 MOV AL, left ; do the left column
\r
634 MOV AL, 0fh ; do the inner columns
\r
636 REP MOVSB ; copy the pixels
\r
638 MOV AL, right ; do the right column
\r
643 MOV AX, SI ; go the start of the next row
\r
644 ADD AX, nextSrcRow ;
\r
647 ADD AX, nextDestRow ;
\r
650 DEC height ; do the rest of the actions
\r
653 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
654 MOV AL, 0ffh ; none from latches
\r
660 /* fade and flash */
\r
662 modexFadeOn(word fade, byte *palette) {
\r
663 fadePalette(-fade, 64, 64/fade+1, palette);
\r
668 modexFadeOff(word fade, byte *palette) {
\r
669 fadePalette(fade, 0, 64/fade+1, palette);
\r
674 modexFlashOn(word fade, byte *palette) {
\r
675 fadePalette(fade, -64, 64/fade+1, palette);
\r
680 modexFlashOff(word fade, byte *palette) {
\r
681 fadePalette(-fade, 0, 64/fade+1, palette);
\r
686 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
690 /* handle the case where we just update */
\r
692 modexPalUpdate1(palette);
\r
696 while(iter > 0) { /* FadeLoop */
\r
697 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
698 tmppal[i] = palette[i] - dim;
\r
699 if(tmppal[i] > 127) {
\r
701 } else if(tmppal[i] > 63) {
\r
705 modexPalUpdate1(tmppal);
\r
712 /* save and load */
\r
714 modexPalSave(byte *palette) {
\r
717 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
718 for(i=0; i<PAL_SIZE; i++) {
\r
719 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
727 ptr = malloc(PAL_SIZE);
\r
729 /* handle errors */
\r
731 printf("Could not allocate palette.\n");
\r
740 modexLoadPalFile(byte *filename, byte **palette) {
\r
744 /* free the palette if it exists */
\r
749 /* allocate the new palette */
\r
750 *palette = modexNewPal();
\r
752 /* open the file */
\r
753 file = fopen(filename, "rb");
\r
755 printf("Could not open palette file: %s\n", filename);
\r
759 /* read the file */
\r
761 while(!feof(file)) {
\r
762 *ptr++ = fgetc(file);
\r
770 modexSavePalFile(char *filename, byte *pal) {
\r
774 /* open the file for writing */
\r
775 file = fopen(filename, "wb");
\r
777 printf("Could not open %s for writing\n", filename);
\r
781 /* write the data to the file */
\r
782 fwrite(pal, 1, PAL_SIZE, file);
\r
790 fadePalette(-1, 64, 1, tmppal);
\r
796 fadePalette(-1, -64, 1, tmppal);
\r
802 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
804 byte *p = bmp->palette;
\r
808 static word a[PAL_SIZE]; //palette array of change values!
\r
809 word z=0, aq=0, aa=0, pp=0;
\r
814 memset(a, -1, sizeof(a));
\r
815 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
825 // printf("q: %02d\n", (q));
\r
826 // printf("qq: %02d\n", (qq));
\r
827 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
828 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
830 if((*i)<PAL_SIZE/2 && w==0)
\r
832 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
834 //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
835 //____ 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
836 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
841 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
843 //printf("qp=%d\n", qp);
\r
844 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
845 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
846 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
847 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
851 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
853 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
854 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
855 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
858 //if(qp>0) printf("qp=%d\n", qp);
\r
859 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
861 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
862 if((*i)>=PAL_SIZE/2 && w==0)
\r
864 for(; (*i)<PAL_SIZE; (*i)++)
\r
866 //____ 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
867 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
872 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
874 //printf("qp=%d\n", qp);
\r
875 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
876 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
877 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
878 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
882 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
883 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
884 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
887 //printf(" (*i)=%d\n", (*i)/3);
\r
890 printf("\nqqqqqqqq\n\n");
\r
896 long bufSize = (bmp->width * bmp->height);
\r
898 //printf("1(*i)=%02d\n", (*i)/3);
\r
899 //printf("1z=%02d\n", z/3);
\r
900 chkcolor(bmp, &q, &a, &aa, &z, i);
\r
901 //printf("2(*i)=%02d\n", (*i)/3);
\r
902 //printf("2z=%02d\n", z/3);
\r
907 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
908 if(a[aq]==-1) aq++;
\r
909 else { aqoffset++; break; }
\r
911 //update the image data here!
\r
912 for(lq=0; lq<bufSize; lq++)
\r
916 use a[qp] instead of bmp->offset for this spot!
\r
921 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
924 //(offset/bmp->offset)*bmp->offset
\r
927 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
928 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
929 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
930 /*if(bmp->data[lq]+bmp->offset==aq)
\r
932 //printf("%02d", bmp->data[lq]);
\r
933 //printf("\n%02d\n", bmp->offset);
\r
934 printf("aq=%02d ", aq);
\r
935 printf("a[aq]=%02d ", a[aq]);
\r
936 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
937 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
938 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
939 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
940 // printf("_%d ", bmp->data[lq]);
\r
941 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
943 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
945 if(bmp->data[lq]+bmp->offset >= aq)
\r
947 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
948 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
950 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
953 //printf("%02d`", bmp->data[lq]);
\r
954 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
957 //printf(" aq=%02d\n", aq);
\r
958 //printf(" aa=%02d\n", aa);
\r
960 //update the palette~
\r
961 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
964 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
969 modexPalUpdate1(byte *p)
\r
973 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
974 for(i=0; i<PAL_SIZE/2; i++)
\r
976 outp(PAL_DATA_REG, p[i]);
\r
978 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
979 for(; i<PAL_SIZE; i++)
\r
981 outp(PAL_DATA_REG, p[(i)]);
\r
986 modexPalUpdate0(byte *p)
\r
990 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
991 for(i=0; i<PAL_SIZE/2; i++)
\r
993 outp(PAL_DATA_REG, rand());
\r
995 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
996 for(; i<PAL_SIZE; i++)
\r
998 outp(PAL_DATA_REG, rand());
\r
1003 //i want to make another vesion that checks the palette when the palette is being appened~
\r
1004 void chkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
1008 pal = modexNewPal();
\r
1009 modexPalSave(pal);
\r
1010 //printf("q: %02d\n", (*q));
\r
1011 printf("chkcolor start~\n");
\r
1012 printf("1 (*z): %d\n", (*z)/3);
\r
1013 printf("1 (*i): %d\n", (*i)/3);
\r
1014 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
1015 printf("wwwwwwwwwwwwwwww\n");
\r
1016 //check palette for dups
\r
1017 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
1019 //printf("\n z: %d\n", (*z));
\r
1020 //printf(" q: %d\n", (*q));
\r
1021 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
1024 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
1027 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1028 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
1032 else for(zz=0; zz<(*q); zz+=3)
\r
1034 //printf("zz: %02d\n", zz/3);
\r
1037 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
1041 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
1042 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
1045 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
1047 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
1048 // 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
1049 // 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
1050 // //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
1051 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1054 //expand dong here
\r
1056 planned features that i plan to implement~
\r
1057 image that has values on the pallete list!
\r
1059 no... wait.... no wwww
\r
1061 //for(zzii=0; zzii<3; zzii++)
\r
1063 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
1064 a[(((*z)+(*q)))]=zz;
\r
1066 (*aa)=(((*z)+(*q)));
\r
1067 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
1068 // printf("\n aa: %d\n\n", (*aa));
\r
1069 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
1070 // printf("wwwwwwwwwwwwwwww\n\n");
\r
1074 printf("================\n");
\r
1075 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
1076 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
1077 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1078 printf("================\n");
\r
1080 //printf("[%d]", (zz+q));
\r
1084 printf("wwwwwwwwwwwwwwww\n");
\r
1085 printf("2 (*z): %d\n", (*z)/3);
\r
1086 printf("2 (*i): %d\n", (*i)/3);
\r
1087 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
1088 printf("chkcolor end~\n");
\r
1092 void modexputPixel(page_t *page, int x, int y, byte color)
\r
1094 word pageOff = (word) page->data;
\r
1095 /* Each address accesses four neighboring pixels, so set
\r
1096 Write Plane Enable according to which pixel we want
\r
1097 to modify. The plane is determined by the two least
\r
1098 significant bits of the x-coordinate: */
\r
1099 modexSelectPlane(PLANE(x));
\r
1100 //outp(SC_INDEX, 0x02);
\r
1101 //outp(SC_DATA, 0x01 << (x & 3));
\r
1103 /* The offset of the pixel into the video segment is
\r
1104 offset = (width * y + x) / 4, and write the given
\r
1105 color to the plane we selected above. Heed the active
\r
1106 page start selection. */
\r
1107 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
1111 byte modexgetPixel(page_t *page, int x, int y)
\r
1113 word pageOff = (word) page->data;
\r
1114 /* Select the plane from which we must read the pixel color: */
\r
1115 outpw(GC_INDEX, 0x04);
\r
1116 outpw(GC_INDEX+1, x & 3);
\r
1118 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
1122 void modexhlin(page_t *page, word xl, word xh, word y, word color)
\r
1127 for(x=0;x<xh*4;x+=4)
\r
1129 if(x+4>=SCREEN_WIDTH-1){ x=0; yy+=4; }
\r
1130 modexClearRegion(page, x+xl, y+yy, 4, 4, color);
\r
1132 //modexputPixel(page, x+xl, y, color);
\r
1135 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1137 word i, s, o, w, j, xp;
\r
1139 word addr = (word) l;
\r
1163 s=romFonts[t].seg;
\r
1164 o=romFonts[t].off;
\r
1166 for(; *str != '\0'; str++)
\r
1169 if((c=='\n'/* || c=="\
\r
1177 //load the letter 'A'
\r
1183 MOV AL, c ; the letter
\r
1186 ADD SI, AX ;the address of charcter
\r
1195 for(i=0; i<w; i++)
\r
1201 modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1210 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1212 word i, s, o, w, j, xp;
\r
1214 word addr = (word) l;
\r
1238 s=romFonts[t].seg;
\r
1239 o=romFonts[t].off;
\r
1241 for(; *str != '\0'; str++)
\r
1244 if((c=='\n'/* || c=="\
\r
1245 "*/)/* || chw>=page->width*/)
\r
1251 //load the letter 'A'
\r
1257 MOV AL, c ; the letter
\r
1260 ADD SI, AX ;the address of charcter
\r
1269 for(i=0; i<w; i++)
\r
1275 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1276 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1285 /////////////////////////////////////////////////////////////////////////////
\r
1287 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1288 // the Virtual screen. //
\r
1290 /////////////////////////////////////////////////////////////////////////////
\r
1291 void cls(page_t *page, byte color, byte *Where)
\r
1293 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1294 /* set map mask to all 4 planes */
\r
1295 outpw(SC_INDEX, 0xff02);
\r
1296 //_fmemset(VGA, color, 16000);
\r
1297 _fmemset(Where, color, page->width*(page->height));
\r
1301 modexWaitBorder() {
\r
1302 while(inp(INPUT_STATUS_1) & 8) {
\r
1306 while(!(inp(INPUT_STATUS_1) & 8)) {
\r