1 /* Project 16 Source Code~
\r
2 * Copyright (C) 2012-2015 sparky4 & pngwen & andrius4669
\r
4 * This file is part of Project 16.
\r
6 * Project 16 is free software; you can redistribute it and/or modify
\r
7 * it under the terms of the GNU General Public License as published by
\r
8 * the Free Software Foundation; either version 3 of the License, or
\r
9 * (at your option) any later version.
\r
11 * Project 16 is distributed in the hope that it will be useful,
\r
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
14 * GNU General Public License for more details.
\r
16 * You should have received a copy of the GNU General Public License
\r
17 * along with this program. If not, see <http://www.gnu.org/licenses/>, or
\r
18 * write to the Free Software Foundation, Inc., 51 Franklin Street,
\r
19 * Fifth Floor, Boston, MA 02110-1301 USA.
\r
26 #include "src/lib/modex16.h"
\r
28 byte far* VGA=(byte far*) 0xA0000000; /* this points to video memory. */
\r
30 static void fadePalette(sbyte fade, sbyte start, word iter, byte *palette);
\r
31 static byte tmppal[PAL_SIZE];
\r
34 /////////////////////////////////////////////////////////////////////////////
\r
36 // setvideo() - This function Manages the video modes //
\r
38 /////////////////////////////////////////////////////////////////////////////
\r
39 void VGAmodeX(sword vq, global_game_variables_t *gv)
\r
44 { // deinit the video
\r
45 // change to the video mode we were in before we switched to mode 13h
\r
48 in.h.al = gv->old_mode;
\r
49 int86(0x10, &in, &out);
\r
54 // get old video mode
\r
56 int86(0x10, &in, &out);
\r
57 gv->old_mode = out.h.al;
\r
64 vgaSetMode(byte mode)
\r
68 regs.h.ah = SET_MODE;
\r
70 int86(VIDEO_INT, ®s, ®s);
\r
74 /* -========================= Entry Points ==========================- */
\r
78 dword far*ptr=(dword far*)VGA; /* used for faster screen clearing */
\r
80 0x0d06, /* vertical total */
\r
81 0x3e07, /* overflow (bit 8 of vertical counts) */
\r
82 0x4109, /* cell height (2 to double-scan */
\r
83 0xea10, /* v sync start */
\r
84 0xac11, /* v sync end and protect cr0-cr7 */
\r
85 0xdf12, /* vertical displayed */
\r
86 0x0014, /* turn off dword mode */
\r
87 0xe715, /* v blank start */
\r
88 0x0616, /* v blank end */
\r
89 0xe317 /* turn on byte mode */
\r
91 int CRTParmCount = sizeof(CRTParms) / sizeof(CRTParms[0]);
\r
93 /* TODO save current video mode and palette */
\r
94 vgaSetMode(VGA_256_COLOR_MODE);
\r
96 /* disable chain4 mode */
\r
97 outpw(SC_INDEX, 0x0604);
\r
99 /* synchronous reset while setting Misc Output */
\r
100 outpw(SC_INDEX, 0x0100);
\r
102 /* select 25 MHz dot clock & 60 Hz scanning rate */
\r
103 outp(MISC_OUTPUT, 0xe3);
\r
105 /* undo reset (restart sequencer) */
\r
106 outpw(SC_INDEX, 0x0300);
\r
108 /* reprogram the CRT controller */
\r
109 outp(CRTC_INDEX, 0x11); /* VSync End reg contains register write prot */
\r
110 outp(CRTC_DATA, 0x7f); /* get current write protect on varios regs */
\r
112 /* send the CRTParms */
\r
113 for(i=0; i<CRTParmCount; i++) {
\r
114 outpw(CRTC_INDEX, CRTParms[i]);
\r
117 /* clear video memory */
\r
118 outpw(SC_INDEX, 0x0f02);
\r
119 for(i=0; i<0x8000; i++) {
\r
127 /* TODO restore original mode and palette */
\r
128 vgaSetMode(TEXT_MODE);
\r
133 modexDefaultPage() {
\r
136 /* default page values */
\r
140 page.width = SCREEN_WIDTH;
\r
141 page.height = SCREEN_HEIGHT;
\r
142 page.tw = page.width/TILEWH;
\r
143 page.th = page.height/TILEWH;
\r
149 /* returns the next page in contiguous memory
\r
150 * the next page will be the same size as p, by default
\r
153 modexNextPage(page_t *p) {
\r
156 result.data = p->data + (p->width/4)*p->height;
\r
159 result.width = p->width;
\r
160 result.height = p->height;
\r
161 result.tw = p->width/TILEWH;
\r
162 result.th = p->height/TILEWH;
\r
163 result.id = p->id+1;
\r
166 // return modexNextPageFlexibleSize(&p, p->width, p->height);
\r
169 //next page with defined dimentions~
\r
171 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
175 result.data = p->data + (p->width/4)*p->height; /* compute the offset */
\r
180 result.tw = p->width/TILEWH;
\r
181 result.th = p->height/TILEWH;
\r
182 result.id = p->id+1;
\r
189 modexShowPage(page_t *page) {
\r
195 /* calculate offset */
\r
196 offset = (word) page->data;
\r
197 offset += page->dy * (page->width >> 2 );
\r
198 offset += page->dx >> 2;
\r
200 /* calculate crtcOffset according to virtual width */
\r
201 crtcOffset = page->width >> 3;
\r
203 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
204 low_address = LOW_ADDRESS | (offset << 8);
\r
206 /* wait for appropriate timing and then program CRTC */
\r
207 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
208 outpw(CRTC_INDEX, high_address);
\r
209 outpw(CRTC_INDEX, low_address);
\r
210 outp(CRTC_INDEX, 0x13);
\r
211 outp(CRTC_DATA, crtcOffset);
\r
213 /* wait for one retrace */
\r
214 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
216 /* do PEL panning here */
\r
217 outp(AC_INDEX, 0x33);
\r
218 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
223 modexPanPage(page_t *page, int dx, int dy) {
\r
230 modexSelectPlane(byte plane) {
\r
231 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
232 outp(SC_DATA, plane);
\r
237 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
238 word pageOff = (word) page->data;
\r
239 word xoff=x/4; /* xoffset that begins each row */
\r
240 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
241 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
242 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
243 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
244 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
245 byte left = lclip[x&0x03];
\r
246 byte right = rclip[(x+w)&0x03];
\r
248 /* handle the case which requires an extra group */
\r
249 if((x & 0x03) && !((x+w) & 0x03)) {
\r
254 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
256 MOV DI, poffset ; go to the first pixel
\r
257 MOV DX, SC_INDEX ; point to the map mask
\r
261 MOV AL, color ; get ready to write colors
\r
263 MOV CX, scanCount ; count the line
\r
264 MOV BL, AL ; remember color
\r
265 MOV AL, left ; do the left clip
\r
266 OUT DX, AL ; set the left clip
\r
267 MOV AL, BL ; restore color
\r
268 STOSB ; write the color
\r
270 JZ SCAN_DONE ; handle 1 group stuff
\r
272 ;-- write the main body of the scanline
\r
273 MOV BL, AL ; remember color
\r
274 MOV AL, 0x0f ; write to all pixels
\r
276 MOV AL, BL ; restore color
\r
277 REP STOSB ; write the color
\r
279 MOV BL, AL ; remeber color
\r
281 OUT DX, AL ; do the right clip
\r
282 MOV AL, BL ; restore color
\r
283 STOSB ; write pixel
\r
284 ADD DI, nextRow ; go to the next row
\r
292 oldDrawBmp(byte far* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
298 /* TODO Make this fast. It's SLOOOOOOW */
\r
299 for(plane=0; plane < 4; plane++) {
\r
300 modexSelectPlane(PLANE(plane+x));
\r
301 for(px = plane; px < bmp->width; px+=4) {
\r
303 for(py=0; py<bmp->height; py++) {
\r
304 if(!sprite || bmp->data[offset])
\r
305 page[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
306 offset+=bmp->width;
\r
313 CDrawBmp(byte far* vgamem, page_t* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
320 /* TODO Make this fast. It's SLOOOOOOW */
\r
321 for(plane=0; plane < 4; plane++) {
\r
322 modexSelectPlane(PLANE(plane+x));
\r
323 for(px = plane; px < bmp->width; px+=4) {
\r
325 for(py=0; py<bmp->height; py++) {
\r
326 if(!sprite || bmp->data[offset])
\r
327 //modexputPixel(page, x+px, y+py, bmp->data[offset]);
\r
328 vgamem[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
329 offset+=bmp->width;
\r
336 modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) {
\r
337 /* draw the region (the entire freakin bitmap) */
\r
338 modexDrawBmpRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
343 modexDrawBmpRegion(page_t *page, int x, int y,
\r
344 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
345 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
346 byte far *data = bmp->data;//+bmp->offset;
\r
347 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
350 byte plane = 1 << ((byte) x & 0x03);
\r
351 word scanCount = width/4 + (width%4 ? 1 :0);
\r
352 word nextPageRow = page->width/4 - scanCount;
\r
353 word nextBmpRow = (word) bmp->width - width;
\r
355 byte planeCounter = 4;
\r
357 /* printf("bmp->data=%Fp\n",bmp->data);
\r
358 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
359 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
361 //code is a bit slow here
\r
363 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
366 MOV DX, SC_INDEX ; point at the map mask register
\r
371 MOV DX, SC_DATA ; select the current plane
\r
375 ;-- begin plane painting
\r
376 MOV AX, height ; start the row counter
\r
377 MOV rowCounter, AX ;
\r
378 MOV DI, poffset ; go to the first pixel
\r
379 MOV SI, bmpOffset ; go to the bmp pixel
\r
381 MOV CX, width ; count the columns
\r
383 MOVSB ; copy the pixel
\r
384 SUB CX, 3 ; we skip the next 3
\r
385 ADD SI, 3 ; skip the bmp pixels
\r
386 LOOP SCAN_LOOP ; finish the scan
\r
388 MOV AX, nextPageRow
\r
389 ADD DI, AX ; go to the next row on screen
\r
391 ADD SI, AX ; go to the next row on bmp
\r
394 JNZ ROW_LOOP ; do all the rows
\r
395 ;-- end plane painting
\r
397 MOV AL, plane ; advance to the next plane
\r
399 AND AL, 0x0f ; mask the plane properly
\r
400 MOV plane, AL ; store the plane
\r
402 INC bmpOffset ; start bmp at the right spot
\r
405 JNZ PLANE_LOOP ; do all 4 planes
\r
410 modex_sparky4_DrawBmpRegion(page_t *page, int x, int y,
\r
411 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
412 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
413 byte far *data = bmp->data;//+bmp->offset;
\r
414 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
417 byte plane = 1 << ((byte) x & 0x03);
\r
418 word scanCount = width/4 + (width%4 ? 1 :0);
\r
419 word nextPageRow = page->width/4 - scanCount;
\r
420 word nextBmpRow = (word) bmp->width - width;
\r
422 byte planeCounter = 4;
\r
424 /* printf("bmp->data=%Fp\n",bmp->data);
\r
425 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
426 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
428 //code is a bit slow here
\r
430 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
433 MOV DX, SC_INDEX ; point at the map mask register
\r
438 MOV DX, SC_DATA ; select the current plane
\r
442 ;-- begin plane painting
\r
443 MOV AX, height ; start the row counter
\r
444 MOV rowCounter, AX ;
\r
445 MOV DI, poffset ; go to the first pixel
\r
446 MOV SI, bmpOffset ; go to the bmp pixel
\r
448 MOV CX, width ; count the columns
\r
450 MOVSB ; copy the pixel
\r
451 SUB CX, 3 ; we skip the next 3
\r
452 ADD SI, 3 ; skip the bmp pixels
\r
453 LOOP SCAN_LOOP ; finish the scan
\r
455 MOV AX, nextPageRow
\r
456 ADD DI, AX ; go to the next row on screen
\r
458 ADD SI, AX ; go to the next row on bmp
\r
461 JNZ ROW_LOOP ; do all the rows
\r
462 ;-- end plane painting
\r
464 MOV AL, plane ; advance to the next plane
\r
466 AND AL, 0x0f ; mask the plane properly
\r
467 MOV plane, AL ; store the plane
\r
469 INC bmpOffset ; start bmp at the right spot
\r
472 JNZ PLANE_LOOP ; do all 4 planes
\r
477 modexDrawPlanarBuf(page_t *page, int x, int y, planar_buf_t *bmp) {
\r
478 /* TODO - adapt from test code */
\r
480 for(plane=0; plane < 4; plane++)
\r
488 modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp) {
\r
489 /* draw the whole sprite */
\r
490 modexDrawSpriteRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
494 modexDrawSpriteRegion(page_t *page, int x, int y,
\r
495 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
496 word poffset = (word)page->data + y*(page->width/4) + x/4;
\r
497 byte *data = bmp->data;//+bmp->offset;
\r
498 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
501 byte plane = 1 << ((byte) x & 0x03);
\r
502 word scanCount = width/4 + (width%4 ? 1 :0);
\r
503 word nextPageRow = page->width/4 - scanCount;
\r
504 word nextBmpRow = (word) bmp->width - width;
\r
506 byte planeCounter = 4;
\r
509 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
512 MOV DX, SC_INDEX ; point at the map mask register
\r
517 MOV DX, SC_DATA ; select the current plane
\r
521 ;-- begin plane painting
\r
522 MOV AX, height ; start the row counter
\r
523 MOV rowCounter, AX ;
\r
524 MOV DI, poffset ; go to the first pixel
\r
525 MOV SI, bmpOffset ; go to the bmp pixel
\r
527 MOV CX, width ; count the columns
\r
532 JNE DRAW_PIXEL ; draw non-zero pixels
\r
534 INC DI ; skip the transparent pixel
\r
538 MOVSB ; copy the pixel
\r
540 SUB CX, 3 ; we skip the next 3
\r
541 ADD SI, 3 ; skip the bmp pixels
\r
542 LOOP SCAN_LOOP ; finish the scan
\r
544 MOV AX, nextPageRow
\r
545 ADD DI, AX ; go to the next row on screen
\r
547 ADD SI, AX ; go to the next row on bmp
\r
550 JNZ ROW_LOOP ; do all the rows
\r
551 ;-- end plane painting
\r
553 MOV AL, plane ; advance to the next plane
\r
555 AND AL, 0x0f ; mask the plane properly
\r
556 MOV plane, AL ; store the plane
\r
558 INC bmpOffset ; start bmp at the right spot
\r
561 JNZ PLANE_LOOP ; do all 4 planes
\r
566 /* copy a region of video memory from one page to another.
\r
567 * It assumes that the left edge of the tile is the same on both
\r
568 * regions and the memory areas do not overlap.
\r
571 modexCopyPageRegion(page_t *dest, page_t *src,
\r
574 word width, word height)
\r
576 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
577 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
578 word scans = width/4;
\r
579 word nextSrcRow = src->width/4 - scans - 1;
\r
580 word nextDestRow = dest->width/4 - scans - 1;
\r
581 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
582 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
583 byte left = lclip[sx&0x03];
\r
584 byte right = rclip[(sx+width)&0x03];
\r
587 MOV AX, SCREEN_SEG ; work in the vga space
\r
592 MOV DX, GC_INDEX ; turn off cpu bits
\r
596 MOV AX, SC_INDEX ; point to the mask register
\r
606 MOV CX, scans ; the number of latches
\r
608 MOV AL, left ; do the left column
\r
613 MOV AL, 0fh ; do the inner columns
\r
615 REP MOVSB ; copy the pixels
\r
617 MOV AL, right ; do the right column
\r
622 MOV AX, SI ; go the start of the next row
\r
623 ADD AX, nextSrcRow ;
\r
626 ADD AX, nextDestRow ;
\r
629 DEC height ; do the rest of the actions
\r
632 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
633 MOV AL, 0ffh ; none from latches
\r
639 /* fade and flash */
\r
641 modexFadeOn(word fade, byte *palette) {
\r
642 fadePalette(-fade, 64, 64/fade+1, palette);
\r
647 modexFadeOff(word fade, byte *palette) {
\r
648 fadePalette(fade, 0, 64/fade+1, palette);
\r
653 modexFlashOn(word fade, byte *palette) {
\r
654 fadePalette(fade, -64, 64/fade+1, palette);
\r
659 modexFlashOff(word fade, byte *palette) {
\r
660 fadePalette(-fade, 0, 64/fade+1, palette);
\r
665 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
669 /* handle the case where we just update */
\r
671 modexPalUpdate1(palette);
\r
675 while(iter > 0) { /* FadeLoop */
\r
676 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
677 tmppal[i] = palette[i] - dim;
\r
678 if(tmppal[i] > 127) {
\r
680 } else if(tmppal[i] > 63) {
\r
684 modexPalUpdate1(tmppal);
\r
691 /* save and load */
\r
693 modexPalSave(byte *palette) {
\r
696 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
697 for(i=0; i<PAL_SIZE; i++) {
\r
698 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
706 ptr = malloc(PAL_SIZE);
\r
708 /* handle errors */
\r
710 printf("Could not allocate palette.\n");
\r
719 modexLoadPalFile(byte *filename, byte **palette) {
\r
723 /* free the palette if it exists */
\r
728 /* allocate the new palette */
\r
729 *palette = modexNewPal();
\r
731 /* open the file */
\r
732 file = fopen(filename, "rb");
\r
734 printf("Could not open palette file: %s\n", filename);
\r
738 /* read the file */
\r
740 while(!feof(file)) {
\r
741 *ptr++ = fgetc(file);
\r
749 modexSavePalFile(char *filename, byte *pal) {
\r
753 /* open the file for writing */
\r
754 file = fopen(filename, "wb");
\r
756 printf("Could not open %s for writing\n", filename);
\r
760 /* write the data to the file */
\r
761 fwrite(pal, 1, PAL_SIZE, file);
\r
769 fadePalette(-1, 64, 1, tmppal);
\r
775 fadePalette(-1, -64, 1, tmppal);
\r
781 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
783 byte *p = bmp->palette;
\r
787 static word a[PAL_SIZE]; //palette array of change values!
\r
788 word z=0, aq=0, aa=0, pp=0;
\r
793 memset(a, -1, sizeof(a));
\r
794 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
804 // printf("q: %02d\n", (q));
\r
805 // printf("qq: %02d\n", (qq));
\r
806 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
807 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
809 if((*i)<PAL_SIZE/2 && w==0)
\r
811 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
813 //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
814 //____ 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
815 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
820 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
822 //printf("qp=%d\n", qp);
\r
823 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
824 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
825 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
826 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
830 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
832 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
833 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
834 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
837 //if(qp>0) printf("qp=%d\n", qp);
\r
838 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
840 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
841 if((*i)>=PAL_SIZE/2 && w==0)
\r
843 for(; (*i)<PAL_SIZE; (*i)++)
\r
845 //____ 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
846 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
851 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
853 //printf("qp=%d\n", qp);
\r
854 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
855 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
856 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
857 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
861 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
862 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
863 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
866 //printf(" (*i)=%d\n", (*i)/3);
\r
869 printf("\nqqqqqqqq\n\n");
\r
875 long bufSize = (bmp->width * bmp->height);
\r
877 //printf("1(*i)=%02d\n", (*i)/3);
\r
878 //printf("1z=%02d\n", z/3);
\r
879 chkcolor(bmp, &q, &a, &aa, &z, i);
\r
880 //printf("2(*i)=%02d\n", (*i)/3);
\r
881 //printf("2z=%02d\n", z/3);
\r
886 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
887 if(a[aq]==-1) aq++;
\r
888 else { aqoffset++; break; }
\r
890 //update the image data here!
\r
891 for(lq=0; lq<bufSize; lq++)
\r
895 use a[qp] instead of bmp->offset for this spot!
\r
900 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
903 //(offset/bmp->offset)*bmp->offset
\r
906 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
907 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
908 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
909 /*if(bmp->data[lq]+bmp->offset==aq)
\r
911 //printf("%02d", bmp->data[lq]);
\r
912 //printf("\n%02d\n", bmp->offset);
\r
913 printf("aq=%02d ", aq);
\r
914 printf("a[aq]=%02d ", a[aq]);
\r
915 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
916 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
917 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
918 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
919 // printf("_%d ", bmp->data[lq]);
\r
920 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
922 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
924 if(bmp->data[lq]+bmp->offset >= aq)
\r
926 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
927 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
929 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
932 //printf("%02d`", bmp->data[lq]);
\r
933 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
936 //printf(" aq=%02d\n", aq);
\r
937 //printf(" aa=%02d\n", aa);
\r
939 //update the palette~
\r
940 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
943 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
948 modexPalUpdate1(byte *p)
\r
952 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
953 for(i=0; i<PAL_SIZE/2; i++)
\r
955 outp(PAL_DATA_REG, p[i]);
\r
957 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
958 for(; i<PAL_SIZE; i++)
\r
960 outp(PAL_DATA_REG, p[(i)]);
\r
965 modexPalUpdate0(byte *p)
\r
969 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
970 for(i=0; i<PAL_SIZE/2; i++)
\r
972 outp(PAL_DATA_REG, rand());
\r
974 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
975 for(; i<PAL_SIZE; i++)
\r
977 outp(PAL_DATA_REG, rand());
\r
982 //i want to make another vesion that checks the palette when the palette is being appened~
\r
983 void chkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
987 pal = modexNewPal();
\r
989 //printf("q: %02d\n", (*q));
\r
990 printf("chkcolor start~\n");
\r
991 printf("1 (*z): %d\n", (*z)/3);
\r
992 printf("1 (*i): %d\n", (*i)/3);
\r
993 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
994 printf("wwwwwwwwwwwwwwww\n");
\r
995 //check palette for dups
\r
996 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
998 //printf("\n z: %d\n", (*z));
\r
999 //printf(" q: %d\n", (*q));
\r
1000 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
1003 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
1006 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1007 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
1011 else for(zz=0; zz<(*q); zz+=3)
\r
1013 //printf("zz: %02d\n", zz/3);
\r
1016 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
1020 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
1021 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
1024 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
1026 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
1027 // 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
1028 // 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
1029 // //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
1030 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1033 //expand dong here
\r
1035 planned features that i plan to implement~
\r
1036 image that has values on the pallete list!
\r
1038 no... wait.... no wwww
\r
1040 //for(zzii=0; zzii<3; zzii++)
\r
1042 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
1043 a[(((*z)+(*q)))]=zz;
\r
1045 (*aa)=(((*z)+(*q)));
\r
1046 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
1047 // printf("\n aa: %d\n\n", (*aa));
\r
1048 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
1049 // printf("wwwwwwwwwwwwwwww\n\n");
\r
1053 printf("================\n");
\r
1054 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
1055 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
1056 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1057 printf("================\n");
\r
1059 //printf("[%d]", (zz+q));
\r
1063 printf("wwwwwwwwwwwwwwww\n");
\r
1064 printf("2 (*z): %d\n", (*z)/3);
\r
1065 printf("2 (*i): %d\n", (*i)/3);
\r
1066 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
1067 printf("chkcolor end~\n");
\r
1071 void modexputPixel(page_t *page, int x, int y, byte color)
\r
1073 word pageOff = (word) page->data;
\r
1074 /* Each address accesses four neighboring pixels, so set
\r
1075 Write Plane Enable according to which pixel we want
\r
1076 to modify. The plane is determined by the two least
\r
1077 significant bits of the x-coordinate: */
\r
1078 modexSelectPlane(PLANE(x));
\r
1079 //outp(SC_INDEX, 0x02);
\r
1080 //outp(SC_DATA, 0x01 << (x & 3));
\r
1082 /* The offset of the pixel into the video segment is
\r
1083 offset = (width * y + x) / 4, and write the given
\r
1084 color to the plane we selected above. Heed the active
\r
1085 page start selection. */
\r
1086 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
1090 byte modexgetPixel(page_t *page, int x, int y)
\r
1092 word pageOff = (word) page->data;
\r
1093 /* Select the plane from which we must read the pixel color: */
\r
1094 outpw(GC_INDEX, 0x04);
\r
1095 outpw(GC_INDEX+1, x & 3);
\r
1097 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
1101 void modexhlin(page_t *page, word xl, word xh, word y, word color)
\r
1106 for(x=0;x<xh*4;x+=4)
\r
1108 if(x+4>=SCREEN_WIDTH-1){ x=0; yy+=4; }
\r
1109 modexClearRegion(page, x+xl, y+yy, 4, 4, color);
\r
1111 //modexputPixel(page, x+xl, y, color);
\r
1114 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1116 word i, s, o, w, j, xp;
\r
1118 word addr = (word) l;
\r
1142 s=romFonts[t].seg;
\r
1143 o=romFonts[t].off;
\r
1145 for(; *str != '\0'; str++)
\r
1148 if((c=='\n'/* || c=="\
\r
1156 //load the letter 'A'
\r
1162 MOV AL, c ; the letter
\r
1165 ADD SI, AX ;the address of charcter
\r
1174 for(i=0; i<w; i++)
\r
1180 modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1189 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1191 word i, s, o, w, j, xp;
\r
1193 word addr = (word) l;
\r
1217 s=romFonts[t].seg;
\r
1218 o=romFonts[t].off;
\r
1220 for(; *str != '\0'; str++)
\r
1223 if((c=='\n'/* || c=="\
\r
1224 "*/)/* || chw>=page->width*/)
\r
1230 //load the letter 'A'
\r
1236 MOV AL, c ; the letter
\r
1239 ADD SI, AX ;the address of charcter
\r
1248 for(i=0; i<w; i++)
\r
1254 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1255 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1264 /////////////////////////////////////////////////////////////////////////////
\r
1266 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1267 // the Virtual screen. //
\r
1269 /////////////////////////////////////////////////////////////////////////////
\r
1270 void cls(page_t *page, byte color, byte *Where)
\r
1272 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1273 /* set map mask to all 4 planes */
\r
1274 outpw(SC_INDEX, 0xff02);
\r
1275 //_fmemset(VGA, color, 16000);
\r
1276 _fmemset(Where, color, page->width*(page->height));
\r
1280 modexWaitBorder() {
\r
1281 while(inp(INPUT_STATUS_1) & 8) {
\r
1285 while(!(inp(INPUT_STATUS_1) & 8)) {
\r