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 // 0x5f00, /* horizontal total */
\r
81 // 0x3f01, /* horizontal display enable end */
\r
82 0x0d06, /* vertical total */
\r
83 0x3e07, /* overflow (bit 8 of vertical counts) */
\r
84 0x4109, /* cell height (2 to double-scan */
\r
85 0xea10, /* v sync start */
\r
86 0xac11, /* v sync end and protect cr0-cr7 */
\r
87 0xdf12, /* vertical displayed */
\r
88 // 0x2013, /* offset/logical width */
\r
89 0x0014, /* turn off dword mode */
\r
90 0xe715, /* v blank start */
\r
91 0x0616, /* v blank end */
\r
92 0xe317 /* turn on byte mode */
\r
95 int CRTParmCount = sizeof(CRTParms) / sizeof(CRTParms[0]);
\r
96 /* width and height */
\r
99 /* TODO save current video mode and palette */
\r
100 vgaSetMode(VGA_256_COLOR_MODE);
\r
102 /* disable chain4 mode */
\r
103 outpw(SC_INDEX, 0x0604);
\r
105 /* synchronous reset while setting Misc Output */
\r
106 outpw(SC_INDEX, 0x0100);
\r
108 /* select 25 MHz dot clock & 60 Hz scanning rate */
\r
109 outp(MISC_OUTPUT, 0xe3);
\r
111 /* undo reset (restart sequencer) */
\r
112 outpw(SC_INDEX, 0x0300);
\r
114 /* reprogram the CRT controller */
\r
115 outp(CRTC_INDEX, 0x11); /* VSync End reg contains register write prot */
\r
116 outp(CRTC_DATA, 0x7f); /* get current write protect on varios regs */
\r
118 /* send the CRTParms */
\r
119 for(i=0; i<CRTParmCount; i++) {
\r
120 outpw(CRTC_INDEX, CRTParms[i]);
\r
123 /* clear video memory */
\r
124 outpw(SC_INDEX, 0x0f02);
\r
125 for(i=0; i<0x8000; i++) {
\r
133 /* TODO restore original mode and palette */
\r
134 vgaSetMode(TEXT_MODE);
\r
139 modexDefaultPage() {
\r
142 /* default page values */
\r
146 page.width = SCREEN_WIDTH;
\r
147 page.height = SCREEN_HEIGHT;
\r
148 page.tw = page.width/TILEWH;
\r
149 page.th = page.height/TILEWH;
\r
155 /* returns the next page in contiguous memory
\r
156 * the next page will be the same size as p, by default
\r
159 modexNextPage(page_t *p) {
\r
162 result.data = p->data + (p->width/4)*p->height;
\r
165 result.width = p->width;
\r
166 result.height = p->height;
\r
167 result.tw = p->width/TILEWH;
\r
168 result.th = p->height/TILEWH;
\r
169 result.id = p->id+1;
\r
172 // return modexNextPageFlexibleSize(&p, p->width, p->height);
\r
175 //next page with defined dimentions~
\r
177 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
181 result.data = p->data + (p->width/4)*p->height; /* compute the offset */
\r
186 result.tw = p->width/TILEWH;
\r
187 result.th = p->height/TILEWH;
\r
188 result.id = p->id+1;
\r
195 modexShowPage(page_t *page) {
\r
201 /* calculate offset */
\r
202 offset = (word) page->data;
\r
203 offset += page->dy * (page->width >> 2 );
\r
204 offset += page->dx >> 2;
\r
206 /* calculate crtcOffset according to virtual width */
\r
207 crtcOffset = page->width >> 3;
\r
209 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
210 low_address = LOW_ADDRESS | (offset << 8);
\r
212 /* wait for appropriate timing and then program CRTC */
\r
213 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
214 outpw(CRTC_INDEX, high_address);
\r
215 outpw(CRTC_INDEX, low_address);
\r
216 outp(CRTC_INDEX, 0x13);
\r
217 outp(CRTC_DATA, crtcOffset);
\r
219 /* wait for one retrace */
\r
220 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
222 /* do PEL panning here */
\r
223 outp(AC_INDEX, 0x33);
\r
224 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
229 modexPanPage(page_t *page, int dx, int dy) {
\r
236 modexSelectPlane(byte plane) {
\r
237 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
238 outp(SC_DATA, plane);
\r
243 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
244 word pageOff = (word) page->data;
\r
245 word xoff=x/4; /* xoffset that begins each row */
\r
246 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
247 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
248 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
249 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
250 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
251 byte left = lclip[x&0x03];
\r
252 byte right = rclip[(x+w)&0x03];
\r
254 /* handle the case which requires an extra group */
\r
255 if((x & 0x03) && !((x+w) & 0x03)) {
\r
260 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
262 MOV DI, poffset ; go to the first pixel
\r
263 MOV DX, SC_INDEX ; point to the map mask
\r
267 MOV AL, color ; get ready to write colors
\r
269 MOV CX, scanCount ; count the line
\r
270 MOV BL, AL ; remember color
\r
271 MOV AL, left ; do the left clip
\r
272 OUT DX, AL ; set the left clip
\r
273 MOV AL, BL ; restore color
\r
274 STOSB ; write the color
\r
276 JZ SCAN_DONE ; handle 1 group stuff
\r
278 ;-- write the main body of the scanline
\r
279 MOV BL, AL ; remember color
\r
280 MOV AL, 0x0f ; write to all pixels
\r
282 MOV AL, BL ; restore color
\r
283 REP STOSB ; write the color
\r
285 MOV BL, AL ; remeber color
\r
287 OUT DX, AL ; do the right clip
\r
288 MOV AL, BL ; restore color
\r
289 STOSB ; write pixel
\r
290 ADD DI, nextRow ; go to the next row
\r
298 oldDrawBmp(byte far* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
304 /* TODO Make this fast. It's SLOOOOOOW */
\r
305 for(plane=0; plane < 4; plane++) {
\r
306 modexSelectPlane(PLANE(plane+x));
\r
307 for(px = plane; px < bmp->width; px+=4) {
\r
309 for(py=0; py<bmp->height; py++) {
\r
310 if(!sprite || bmp->data[offset])
\r
311 page[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
312 offset+=bmp->width;
\r
319 CDrawBmp(byte far* vgamem, page_t* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
326 /* TODO Make this fast. It's SLOOOOOOW */
\r
327 for(plane=0; plane < 4; plane++) {
\r
328 modexSelectPlane(PLANE(plane+x));
\r
329 for(px = plane; px < bmp->width; px+=4) {
\r
331 for(py=0; py<bmp->height; py++) {
\r
332 if(!sprite || bmp->data[offset])
\r
333 //modexputPixel(page, x+px, y+py, bmp->data[offset]);
\r
334 vgamem[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
335 offset+=bmp->width;
\r
342 modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) {
\r
343 /* draw the region (the entire freakin bitmap) */
\r
344 modexDrawBmpRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
349 modexDrawBmpRegion(page_t *page, int x, int y,
\r
350 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
351 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
352 byte far *data = bmp->data;//+bmp->offset;
\r
353 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
356 byte plane = 1 << ((byte) x & 0x03);
\r
357 word scanCount = width/4 + (width%4 ? 1 :0);
\r
358 word nextPageRow = page->width/4 - scanCount;
\r
359 word nextBmpRow = (word) bmp->width - width;
\r
361 byte planeCounter = 4;
\r
363 /* printf("bmp->data=%Fp\n",bmp->data);
\r
364 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
365 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
367 //code is a bit slow here
\r
369 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
372 MOV DX, SC_INDEX ; point at the map mask register
\r
377 MOV DX, SC_DATA ; select the current plane
\r
381 ;-- begin plane painting
\r
382 MOV AX, height ; start the row counter
\r
383 MOV rowCounter, AX ;
\r
384 MOV DI, poffset ; go to the first pixel
\r
385 MOV SI, bmpOffset ; go to the bmp pixel
\r
387 MOV CX, width ; count the columns
\r
389 MOVSB ; copy the pixel
\r
390 SUB CX, 3 ; we skip the next 3
\r
391 ADD SI, 3 ; skip the bmp pixels
\r
392 LOOP SCAN_LOOP ; finish the scan
\r
394 MOV AX, nextPageRow
\r
395 ADD DI, AX ; go to the next row on screen
\r
397 ADD SI, AX ; go to the next row on bmp
\r
400 JNZ ROW_LOOP ; do all the rows
\r
401 ;-- end plane painting
\r
403 MOV AL, plane ; advance to the next plane
\r
405 AND AL, 0x0f ; mask the plane properly
\r
406 MOV plane, AL ; store the plane
\r
408 INC bmpOffset ; start bmp at the right spot
\r
411 JNZ PLANE_LOOP ; do all 4 planes
\r
416 modex_sparky4_DrawBmpRegion(page_t *page, int x, int y,
\r
417 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
418 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
419 byte far *data = bmp->data;//+bmp->offset;
\r
420 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
423 byte plane = 1 << ((byte) x & 0x03);
\r
424 word scanCount = width/4 + (width%4 ? 1 :0);
\r
425 word nextPageRow = page->width/4 - scanCount;
\r
426 word nextBmpRow = (word) bmp->width - width;
\r
428 byte planeCounter = 4;
\r
430 /* printf("bmp->data=%Fp\n",bmp->data);
\r
431 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
432 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
434 //code is a bit slow here
\r
436 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
439 MOV DX, SC_INDEX ; point at the map mask register
\r
444 MOV DX, SC_DATA ; select the current plane
\r
448 ;-- begin plane painting
\r
449 MOV AX, height ; start the row counter
\r
450 MOV rowCounter, AX ;
\r
451 MOV DI, poffset ; go to the first pixel
\r
452 MOV SI, bmpOffset ; go to the bmp pixel
\r
454 MOV CX, width ; count the columns
\r
456 MOVSB ; copy the pixel
\r
457 SUB CX, 3 ; we skip the next 3
\r
458 ADD SI, 3 ; skip the bmp pixels
\r
459 LOOP SCAN_LOOP ; finish the scan
\r
461 MOV AX, nextPageRow
\r
462 ADD DI, AX ; go to the next row on screen
\r
464 ADD SI, AX ; go to the next row on bmp
\r
467 JNZ ROW_LOOP ; do all the rows
\r
468 ;-- end plane painting
\r
470 MOV AL, plane ; advance to the next plane
\r
472 AND AL, 0x0f ; mask the plane properly
\r
473 MOV plane, AL ; store the plane
\r
475 INC bmpOffset ; start bmp at the right spot
\r
478 JNZ PLANE_LOOP ; do all 4 planes
\r
483 modexDrawPlanarBuf(page_t *page, int x, int y, planar_buf_t *bmp) {
\r
484 /* TODO - adapt from test code */
\r
486 for(plane=0; plane < 4; plane++)
\r
494 modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp) {
\r
495 /* draw the whole sprite */
\r
496 modexDrawSpriteRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
500 modexDrawSpriteRegion(page_t *page, int x, int y,
\r
501 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
502 word poffset = (word)page->data + y*(page->width/4) + x/4;
\r
503 byte *data = bmp->data;//+bmp->offset;
\r
504 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
507 byte plane = 1 << ((byte) x & 0x03);
\r
508 word scanCount = width/4 + (width%4 ? 1 :0);
\r
509 word nextPageRow = page->width/4 - scanCount;
\r
510 word nextBmpRow = (word) bmp->width - width;
\r
512 byte planeCounter = 4;
\r
515 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
518 MOV DX, SC_INDEX ; point at the map mask register
\r
523 MOV DX, SC_DATA ; select the current plane
\r
527 ;-- begin plane painting
\r
528 MOV AX, height ; start the row counter
\r
529 MOV rowCounter, AX ;
\r
530 MOV DI, poffset ; go to the first pixel
\r
531 MOV SI, bmpOffset ; go to the bmp pixel
\r
533 MOV CX, width ; count the columns
\r
538 JNE DRAW_PIXEL ; draw non-zero pixels
\r
540 INC DI ; skip the transparent pixel
\r
544 MOVSB ; copy the pixel
\r
546 SUB CX, 3 ; we skip the next 3
\r
547 ADD SI, 3 ; skip the bmp pixels
\r
548 LOOP SCAN_LOOP ; finish the scan
\r
550 MOV AX, nextPageRow
\r
551 ADD DI, AX ; go to the next row on screen
\r
553 ADD SI, AX ; go to the next row on bmp
\r
556 JNZ ROW_LOOP ; do all the rows
\r
557 ;-- end plane painting
\r
559 MOV AL, plane ; advance to the next plane
\r
561 AND AL, 0x0f ; mask the plane properly
\r
562 MOV plane, AL ; store the plane
\r
564 INC bmpOffset ; start bmp at the right spot
\r
567 JNZ PLANE_LOOP ; do all 4 planes
\r
572 /* copy a region of video memory from one page to another.
\r
573 * It assumes that the left edge of the tile is the same on both
\r
574 * regions and the memory areas do not overlap.
\r
577 modexCopyPageRegion(page_t *dest, page_t *src,
\r
580 word width, word height)
\r
582 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
583 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
584 word scans = width/4;
\r
585 word nextSrcRow = src->width/4 - scans - 1;
\r
586 word nextDestRow = dest->width/4 - scans - 1;
\r
587 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
588 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
589 byte left = lclip[sx&0x03];
\r
590 byte right = rclip[(sx+width)&0x03];
\r
593 MOV AX, SCREEN_SEG ; work in the vga space
\r
598 MOV DX, GC_INDEX ; turn off cpu bits
\r
602 MOV AX, SC_INDEX ; point to the mask register
\r
612 MOV CX, scans ; the number of latches
\r
614 MOV AL, left ; do the left column
\r
619 MOV AL, 0fh ; do the inner columns
\r
621 REP MOVSB ; copy the pixels
\r
623 MOV AL, right ; do the right column
\r
628 MOV AX, SI ; go the start of the next row
\r
629 ADD AX, nextSrcRow ;
\r
632 ADD AX, nextDestRow ;
\r
635 DEC height ; do the rest of the actions
\r
638 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
639 MOV AL, 0ffh ; none from latches
\r
645 /* fade and flash */
\r
647 modexFadeOn(word fade, byte *palette) {
\r
648 fadePalette(-fade, 64, 64/fade+1, palette);
\r
653 modexFadeOff(word fade, byte *palette) {
\r
654 fadePalette(fade, 0, 64/fade+1, palette);
\r
659 modexFlashOn(word fade, byte *palette) {
\r
660 fadePalette(fade, -64, 64/fade+1, palette);
\r
665 modexFlashOff(word fade, byte *palette) {
\r
666 fadePalette(-fade, 0, 64/fade+1, palette);
\r
671 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
675 /* handle the case where we just update */
\r
677 modexPalUpdate1(palette);
\r
681 while(iter > 0) { /* FadeLoop */
\r
682 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
683 tmppal[i] = palette[i] - dim;
\r
684 if(tmppal[i] > 127) {
\r
686 } else if(tmppal[i] > 63) {
\r
690 modexPalUpdate1(tmppal);
\r
697 /* save and load */
\r
699 modexPalSave(byte *palette) {
\r
702 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
703 for(i=0; i<PAL_SIZE; i++) {
\r
704 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
712 ptr = malloc(PAL_SIZE);
\r
714 /* handle errors */
\r
716 printf("Could not allocate palette.\n");
\r
725 modexLoadPalFile(byte *filename, byte **palette) {
\r
729 /* free the palette if it exists */
\r
734 /* allocate the new palette */
\r
735 *palette = modexNewPal();
\r
737 /* open the file */
\r
738 file = fopen(filename, "rb");
\r
740 printf("Could not open palette file: %s\n", filename);
\r
744 /* read the file */
\r
746 while(!feof(file)) {
\r
747 *ptr++ = fgetc(file);
\r
755 modexSavePalFile(char *filename, byte *pal) {
\r
759 /* open the file for writing */
\r
760 file = fopen(filename, "wb");
\r
762 printf("Could not open %s for writing\n", filename);
\r
766 /* write the data to the file */
\r
767 fwrite(pal, 1, PAL_SIZE, file);
\r
775 fadePalette(-1, 64, 1, tmppal);
\r
781 fadePalette(-1, -64, 1, tmppal);
\r
787 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
789 byte *p = bmp->palette;
\r
793 static word a[PAL_SIZE]; //palette array of change values!
\r
794 word z=0, aq=0, aa=0, pp=0;
\r
799 memset(a, -1, sizeof(a));
\r
800 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
810 // printf("q: %02d\n", (q));
\r
811 // printf("qq: %02d\n", (qq));
\r
812 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
813 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
815 if((*i)<PAL_SIZE/2 && w==0)
\r
817 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
819 //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
820 //____ 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
821 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
826 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
828 //printf("qp=%d\n", qp);
\r
829 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
830 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
831 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
832 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
836 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
838 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
839 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
840 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
843 //if(qp>0) printf("qp=%d\n", qp);
\r
844 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
846 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
847 if((*i)>=PAL_SIZE/2 && w==0)
\r
849 for(; (*i)<PAL_SIZE; (*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(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
868 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
869 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
872 //printf(" (*i)=%d\n", (*i)/3);
\r
875 printf("\nqqqqqqqq\n\n");
\r
881 long bufSize = (bmp->width * bmp->height);
\r
883 //printf("1(*i)=%02d\n", (*i)/3);
\r
884 //printf("1z=%02d\n", z/3);
\r
885 chkcolor(bmp, &q, &a, &aa, &z, i);
\r
886 //printf("2(*i)=%02d\n", (*i)/3);
\r
887 //printf("2z=%02d\n", z/3);
\r
892 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
893 if(a[aq]==-1) aq++;
\r
894 else { aqoffset++; break; }
\r
896 //update the image data here!
\r
897 for(lq=0; lq<bufSize; lq++)
\r
901 use a[qp] instead of bmp->offset for this spot!
\r
906 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
909 //(offset/bmp->offset)*bmp->offset
\r
912 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
913 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
914 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
915 /*if(bmp->data[lq]+bmp->offset==aq)
\r
917 //printf("%02d", bmp->data[lq]);
\r
918 //printf("\n%02d\n", bmp->offset);
\r
919 printf("aq=%02d ", aq);
\r
920 printf("a[aq]=%02d ", a[aq]);
\r
921 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
922 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
923 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
924 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
925 // printf("_%d ", bmp->data[lq]);
\r
926 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
928 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
930 if(bmp->data[lq]+bmp->offset >= aq)
\r
932 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
933 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
935 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
938 //printf("%02d`", bmp->data[lq]);
\r
939 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
942 //printf(" aq=%02d\n", aq);
\r
943 //printf(" aa=%02d\n", aa);
\r
945 //update the palette~
\r
946 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
949 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
954 modexPalUpdate1(byte *p)
\r
958 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
959 for(i=0; i<PAL_SIZE/2; i++)
\r
961 outp(PAL_DATA_REG, p[i]);
\r
963 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
964 for(; i<PAL_SIZE; i++)
\r
966 outp(PAL_DATA_REG, p[(i)]);
\r
971 modexPalUpdate0(byte *p)
\r
975 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
976 for(i=0; i<PAL_SIZE/2; i++)
\r
978 outp(PAL_DATA_REG, rand());
\r
980 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
981 for(; i<PAL_SIZE; i++)
\r
983 outp(PAL_DATA_REG, rand());
\r
988 //i want to make another vesion that checks the palette when the palette is being appened~
\r
989 void chkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
993 pal = modexNewPal();
\r
995 //printf("q: %02d\n", (*q));
\r
996 printf("chkcolor start~\n");
\r
997 printf("1 (*z): %d\n", (*z)/3);
\r
998 printf("1 (*i): %d\n", (*i)/3);
\r
999 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
1000 printf("wwwwwwwwwwwwwwww\n");
\r
1001 //check palette for dups
\r
1002 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
1004 //printf("\n z: %d\n", (*z));
\r
1005 //printf(" q: %d\n", (*q));
\r
1006 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
1009 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
1012 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1013 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
1017 else for(zz=0; zz<(*q); zz+=3)
\r
1019 //printf("zz: %02d\n", zz/3);
\r
1022 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
1026 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
1027 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
1030 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
1032 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
1033 // 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
1034 // 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
1035 // //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
1036 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1039 //expand dong here
\r
1041 planned features that i plan to implement~
\r
1042 image that has values on the pallete list!
\r
1044 no... wait.... no wwww
\r
1046 //for(zzii=0; zzii<3; zzii++)
\r
1048 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
1049 a[(((*z)+(*q)))]=zz;
\r
1051 (*aa)=(((*z)+(*q)));
\r
1052 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
1053 // printf("\n aa: %d\n\n", (*aa));
\r
1054 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
1055 // printf("wwwwwwwwwwwwwwww\n\n");
\r
1059 printf("================\n");
\r
1060 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
1061 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
1062 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1063 printf("================\n");
\r
1065 //printf("[%d]", (zz+q));
\r
1069 printf("wwwwwwwwwwwwwwww\n");
\r
1070 printf("2 (*z): %d\n", (*z)/3);
\r
1071 printf("2 (*i): %d\n", (*i)/3);
\r
1072 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
1073 printf("chkcolor end~\n");
\r
1077 void modexputPixel(page_t *page, int x, int y, byte color)
\r
1079 word pageOff = (word) page->data;
\r
1080 /* Each address accesses four neighboring pixels, so set
\r
1081 Write Plane Enable according to which pixel we want
\r
1082 to modify. The plane is determined by the two least
\r
1083 significant bits of the x-coordinate: */
\r
1084 modexSelectPlane(PLANE(x));
\r
1085 //outp(SC_INDEX, 0x02);
\r
1086 //outp(SC_DATA, 0x01 << (x & 3));
\r
1088 /* The offset of the pixel into the video segment is
\r
1089 offset = (width * y + x) / 4, and write the given
\r
1090 color to the plane we selected above. Heed the active
\r
1091 page start selection. */
\r
1092 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
1096 byte modexgetPixel(page_t *page, int x, int y)
\r
1098 word pageOff = (word) page->data;
\r
1099 /* Select the plane from which we must read the pixel color: */
\r
1100 outpw(GC_INDEX, 0x04);
\r
1101 outpw(GC_INDEX+1, x & 3);
\r
1103 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
1107 void modexhlin(page_t *page, word xl, word xh, word y, word color)
\r
1112 for(x=0;x<xh*4;x+=4)
\r
1114 if(x+4>=SCREEN_WIDTH-1){ x=0; yy+=4; }
\r
1115 modexClearRegion(page, x+xl, y+yy, 4, 4, color);
\r
1117 //modexputPixel(page, x+xl, y, color);
\r
1120 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1122 word i, s, o, w, j, xp;
\r
1124 word addr = (word) l;
\r
1148 s=romFonts[t].seg;
\r
1149 o=romFonts[t].off;
\r
1151 for(; *str != '\0'; str++)
\r
1154 if((c=='\n'/* || c=="\
\r
1162 //load the letter 'A'
\r
1168 MOV AL, c ; the letter
\r
1171 ADD SI, AX ;the address of charcter
\r
1180 for(i=0; i<w; i++)
\r
1186 modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1195 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1197 word i, s, o, w, j, xp;
\r
1199 word addr = (word) l;
\r
1223 s=romFonts[t].seg;
\r
1224 o=romFonts[t].off;
\r
1226 for(; *str != '\0'; str++)
\r
1229 if((c=='\n'/* || c=="\
\r
1230 "*/)/* || chw>=page->width*/)
\r
1236 //load the letter 'A'
\r
1242 MOV AL, c ; the letter
\r
1245 ADD SI, AX ;the address of charcter
\r
1254 for(i=0; i<w; i++)
\r
1260 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1261 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1270 /////////////////////////////////////////////////////////////////////////////
\r
1272 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1273 // the Virtual screen. //
\r
1275 /////////////////////////////////////////////////////////////////////////////
\r
1276 void cls(page_t *page, byte color, byte *Where)
\r
1278 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1279 /* set map mask to all 4 planes */
\r
1280 outpw(SC_INDEX, 0xff02);
\r
1281 //_fmemset(VGA, color, 16000);
\r
1282 _fmemset(Where, color, page->width*(page->height));
\r
1286 modexWaitBorder() {
\r
1287 while(inp(INPUT_STATUS_1) & 8) {
\r
1291 while(!(inp(INPUT_STATUS_1) & 8)) {
\r