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 // 0xe300, /* horizontal total */
\r
81 0x4f01, /* horizontal display enable end */
\r
85 0x0d06, /* vertical total */
\r
86 0x3e07, /* overflow (bit 8 of vertical counts) */
\r
87 0x4109, /* cell height (2 to double-scan */
\r
88 0xea10, /* v sync start */
\r
89 0xac11, /* v sync end and protect cr0-cr7 */
\r
90 0xdf12, /* vertical displayed */
\r
91 0x2813, /* offset/logical width */
\r
92 0x0014, /* turn off dword mode */
\r
93 0xe715, /* v blank start */
\r
94 0x0616, /* v blank end */
\r
95 0xe317 /* turn on byte mode */
\r
98 int CRTParmCount = sizeof(CRTParms) / sizeof(CRTParms[0]);
\r
99 /* width and height */
\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
130 // setBaseXMode() does the initialization to make the VGA ready to
\r
131 // accept any combination of configuration register settings. This
\r
132 // involves enabling writes to index 0 to 7 of the CRT controller (port
\r
133 // 0x3D4), by clearing the most significant bit (bit 7) of index 0x11.
\r
135 modexsetBaseXMode(void)
\r
139 /* TODO save current video mode and palette */
\r
140 vgaSetMode(VGA_256_COLOR_MODE);
\r
142 outp(CRTC_INDEX, 0x11);
\r
143 temp = inp(CRTC_DATA) & 0x7F;
\r
144 outp(CRTC_INDEX, 0x11);
\r
145 outp(CRTC_DATA, temp);
\r
150 /* TODO restore original mode and palette */
\r
151 vgaSetMode(TEXT_MODE);
\r
156 modexDefaultPage() {
\r
159 /* default page values */
\r
163 page.width = SCREEN_WIDTH;
\r
164 page.height = SCREEN_HEIGHT;
\r
165 page.tw = page.width/TILEWH;
\r
166 page.th = page.height/TILEWH;
\r
172 /* returns the next page in contiguous memory
\r
173 * the next page will be the same size as p, by default
\r
176 modexNextPage(page_t *p) {
\r
179 result.data = p->data + (p->width/4)*p->height;
\r
182 result.width = p->width;
\r
183 result.height = p->height;
\r
184 result.tw = p->width/TILEWH;
\r
185 result.th = p->height/TILEWH;
\r
186 result.id = p->id+1;
\r
189 // return modexNextPageFlexibleSize(&p, p->width, p->height);
\r
192 //next page with defined dimentions~
\r
194 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
198 result.data = p->data + (p->width/4)*p->height; /* compute the offset */
\r
203 result.tw = p->width/TILEWH;
\r
204 result.th = p->height/TILEWH;
\r
205 result.id = p->id+1;
\r
212 modexShowPage(page_t *page) {
\r
218 /* calculate offset */
\r
219 offset = (word) page->data;
\r
220 offset += page->dy * (page->width >> 2 );
\r
221 offset += page->dx >> 2;
\r
223 /* calculate crtcOffset according to virtual width */
\r
224 crtcOffset = page->width >> 3;
\r
226 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
227 low_address = LOW_ADDRESS | (offset << 8);
\r
229 /* wait for appropriate timing and then program CRTC */
\r
230 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
231 outpw(CRTC_INDEX, high_address);
\r
232 outpw(CRTC_INDEX, low_address);
\r
233 outp(CRTC_INDEX, 0x13);
\r
234 outp(CRTC_DATA, crtcOffset);
\r
236 /* wait for one retrace */
\r
237 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
239 /* do PEL panning here */
\r
240 outp(AC_INDEX, 0x33);
\r
241 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
246 modexPanPage(page_t *page, int dx, int dy) {
\r
253 modexSelectPlane(byte plane) {
\r
254 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
255 outp(SC_DATA, plane);
\r
260 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
261 word pageOff = (word) page->data;
\r
262 word xoff=x/4; /* xoffset that begins each row */
\r
263 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
264 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
265 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
266 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
267 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
268 byte left = lclip[x&0x03];
\r
269 byte right = rclip[(x+w)&0x03];
\r
271 /* handle the case which requires an extra group */
\r
272 if((x & 0x03) && !((x+w) & 0x03)) {
\r
277 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
279 MOV DI, poffset ; go to the first pixel
\r
280 MOV DX, SC_INDEX ; point to the map mask
\r
284 MOV AL, color ; get ready to write colors
\r
286 MOV CX, scanCount ; count the line
\r
287 MOV BL, AL ; remember color
\r
288 MOV AL, left ; do the left clip
\r
289 OUT DX, AL ; set the left clip
\r
290 MOV AL, BL ; restore color
\r
291 STOSB ; write the color
\r
293 JZ SCAN_DONE ; handle 1 group stuff
\r
295 ;-- write the main body of the scanline
\r
296 MOV BL, AL ; remember color
\r
297 MOV AL, 0x0f ; write to all pixels
\r
299 MOV AL, BL ; restore color
\r
300 REP STOSB ; write the color
\r
302 MOV BL, AL ; remeber color
\r
304 OUT DX, AL ; do the right clip
\r
305 MOV AL, BL ; restore color
\r
306 STOSB ; write pixel
\r
307 ADD DI, nextRow ; go to the next row
\r
315 oldDrawBmp(byte far* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
321 /* TODO Make this fast. It's SLOOOOOOW */
\r
322 for(plane=0; plane < 4; plane++) {
\r
323 modexSelectPlane(PLANE(plane+x));
\r
324 for(px = plane; px < bmp->width; px+=4) {
\r
326 for(py=0; py<bmp->height; py++) {
\r
327 if(!sprite || bmp->data[offset])
\r
328 page[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
329 offset+=bmp->width;
\r
336 CDrawBmp(byte far* vgamem, page_t* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
343 /* TODO Make this fast. It's SLOOOOOOW */
\r
344 for(plane=0; plane < 4; plane++) {
\r
345 modexSelectPlane(PLANE(plane+x));
\r
346 for(px = plane; px < bmp->width; px+=4) {
\r
348 for(py=0; py<bmp->height; py++) {
\r
349 if(!sprite || bmp->data[offset])
\r
350 //modexputPixel(page, x+px, y+py, bmp->data[offset]);
\r
351 vgamem[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
352 offset+=bmp->width;
\r
359 modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) {
\r
360 /* draw the region (the entire freakin bitmap) */
\r
361 modexDrawBmpRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
366 modexDrawBmpRegion(page_t *page, int x, int y,
\r
367 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
368 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
369 byte far *data = bmp->data;//+bmp->offset;
\r
370 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
373 byte plane = 1 << ((byte) x & 0x03);
\r
374 word scanCount = width/4 + (width%4 ? 1 :0);
\r
375 word nextPageRow = page->width/4 - scanCount;
\r
376 word nextBmpRow = (word) bmp->width - width;
\r
378 byte planeCounter = 4;
\r
380 /* printf("bmp->data=%Fp\n",bmp->data);
\r
381 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
382 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
384 //code is a bit slow here
\r
386 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
389 MOV DX, SC_INDEX ; point at the map mask register
\r
394 MOV DX, SC_DATA ; select the current plane
\r
398 ;-- begin plane painting
\r
399 MOV AX, height ; start the row counter
\r
400 MOV rowCounter, AX ;
\r
401 MOV DI, poffset ; go to the first pixel
\r
402 MOV SI, bmpOffset ; go to the bmp pixel
\r
404 MOV CX, width ; count the columns
\r
406 MOVSB ; copy the pixel
\r
407 SUB CX, 3 ; we skip the next 3
\r
408 ADD SI, 3 ; skip the bmp pixels
\r
409 LOOP SCAN_LOOP ; finish the scan
\r
411 MOV AX, nextPageRow
\r
412 ADD DI, AX ; go to the next row on screen
\r
414 ADD SI, AX ; go to the next row on bmp
\r
417 JNZ ROW_LOOP ; do all the rows
\r
418 ;-- end plane painting
\r
420 MOV AL, plane ; advance to the next plane
\r
422 AND AL, 0x0f ; mask the plane properly
\r
423 MOV plane, AL ; store the plane
\r
425 INC bmpOffset ; start bmp at the right spot
\r
428 JNZ PLANE_LOOP ; do all 4 planes
\r
433 modex_sparky4_DrawBmpRegion(page_t *page, int x, int y,
\r
434 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
435 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
436 byte far *data = bmp->data;//+bmp->offset;
\r
437 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
440 byte plane = 1 << ((byte) x & 0x03);
\r
441 word scanCount = width/4 + (width%4 ? 1 :0);
\r
442 word nextPageRow = page->width/4 - scanCount;
\r
443 word nextBmpRow = (word) bmp->width - width;
\r
445 byte planeCounter = 4;
\r
447 /* printf("bmp->data=%Fp\n",bmp->data);
\r
448 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
449 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
451 //code is a bit slow here
\r
453 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
456 MOV DX, SC_INDEX ; point at the map mask register
\r
461 MOV DX, SC_DATA ; select the current plane
\r
465 ;-- begin plane painting
\r
466 MOV AX, height ; start the row counter
\r
467 MOV rowCounter, AX ;
\r
468 MOV DI, poffset ; go to the first pixel
\r
469 MOV SI, bmpOffset ; go to the bmp pixel
\r
471 MOV CX, width ; count the columns
\r
473 MOVSB ; copy the pixel
\r
474 SUB CX, 3 ; we skip the next 3
\r
475 ADD SI, 3 ; skip the bmp pixels
\r
476 LOOP SCAN_LOOP ; finish the scan
\r
478 MOV AX, nextPageRow
\r
479 ADD DI, AX ; go to the next row on screen
\r
481 ADD SI, AX ; go to the next row on bmp
\r
484 JNZ ROW_LOOP ; do all the rows
\r
485 ;-- end plane painting
\r
487 MOV AL, plane ; advance to the next plane
\r
489 AND AL, 0x0f ; mask the plane properly
\r
490 MOV plane, AL ; store the plane
\r
492 INC bmpOffset ; start bmp at the right spot
\r
495 JNZ PLANE_LOOP ; do all 4 planes
\r
500 modexDrawPlanarBuf(page_t *page, int x, int y, planar_buf_t *bmp) {
\r
501 /* TODO - adapt from test code */
\r
503 for(plane=0; plane < 4; plane++)
\r
511 modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp) {
\r
512 /* draw the whole sprite */
\r
513 modexDrawSpriteRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
517 modexDrawSpriteRegion(page_t *page, int x, int y,
\r
518 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
519 word poffset = (word)page->data + y*(page->width/4) + x/4;
\r
520 byte *data = bmp->data;//+bmp->offset;
\r
521 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
524 byte plane = 1 << ((byte) x & 0x03);
\r
525 word scanCount = width/4 + (width%4 ? 1 :0);
\r
526 word nextPageRow = page->width/4 - scanCount;
\r
527 word nextBmpRow = (word) bmp->width - width;
\r
529 byte planeCounter = 4;
\r
532 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
535 MOV DX, SC_INDEX ; point at the map mask register
\r
540 MOV DX, SC_DATA ; select the current plane
\r
544 ;-- begin plane painting
\r
545 MOV AX, height ; start the row counter
\r
546 MOV rowCounter, AX ;
\r
547 MOV DI, poffset ; go to the first pixel
\r
548 MOV SI, bmpOffset ; go to the bmp pixel
\r
550 MOV CX, width ; count the columns
\r
555 JNE DRAW_PIXEL ; draw non-zero pixels
\r
557 INC DI ; skip the transparent pixel
\r
561 MOVSB ; copy the pixel
\r
563 SUB CX, 3 ; we skip the next 3
\r
564 ADD SI, 3 ; skip the bmp pixels
\r
565 LOOP SCAN_LOOP ; finish the scan
\r
567 MOV AX, nextPageRow
\r
568 ADD DI, AX ; go to the next row on screen
\r
570 ADD SI, AX ; go to the next row on bmp
\r
573 JNZ ROW_LOOP ; do all the rows
\r
574 ;-- end plane painting
\r
576 MOV AL, plane ; advance to the next plane
\r
578 AND AL, 0x0f ; mask the plane properly
\r
579 MOV plane, AL ; store the plane
\r
581 INC bmpOffset ; start bmp at the right spot
\r
584 JNZ PLANE_LOOP ; do all 4 planes
\r
589 /* copy a region of video memory from one page to another.
\r
590 * It assumes that the left edge of the tile is the same on both
\r
591 * regions and the memory areas do not overlap.
\r
594 modexCopyPageRegion(page_t *dest, page_t *src,
\r
597 word width, word height)
\r
599 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
600 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
601 word scans = width/4;
\r
602 word nextSrcRow = src->width/4 - scans - 1;
\r
603 word nextDestRow = dest->width/4 - scans - 1;
\r
604 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
605 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
606 byte left = lclip[sx&0x03];
\r
607 byte right = rclip[(sx+width)&0x03];
\r
610 MOV AX, SCREEN_SEG ; work in the vga space
\r
615 MOV DX, GC_INDEX ; turn off cpu bits
\r
619 MOV AX, SC_INDEX ; point to the mask register
\r
629 MOV CX, scans ; the number of latches
\r
631 MOV AL, left ; do the left column
\r
636 MOV AL, 0fh ; do the inner columns
\r
638 REP MOVSB ; copy the pixels
\r
640 MOV AL, right ; do the right column
\r
645 MOV AX, SI ; go the start of the next row
\r
646 ADD AX, nextSrcRow ;
\r
649 ADD AX, nextDestRow ;
\r
652 DEC height ; do the rest of the actions
\r
655 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
656 MOV AL, 0ffh ; none from latches
\r
662 /* fade and flash */
\r
664 modexFadeOn(word fade, byte *palette) {
\r
665 fadePalette(-fade, 64, 64/fade+1, palette);
\r
670 modexFadeOff(word fade, byte *palette) {
\r
671 fadePalette(fade, 0, 64/fade+1, palette);
\r
676 modexFlashOn(word fade, byte *palette) {
\r
677 fadePalette(fade, -64, 64/fade+1, palette);
\r
682 modexFlashOff(word fade, byte *palette) {
\r
683 fadePalette(-fade, 0, 64/fade+1, palette);
\r
688 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
692 /* handle the case where we just update */
\r
694 modexPalUpdate1(palette);
\r
698 while(iter > 0) { /* FadeLoop */
\r
699 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
700 tmppal[i] = palette[i] - dim;
\r
701 if(tmppal[i] > 127) {
\r
703 } else if(tmppal[i] > 63) {
\r
707 modexPalUpdate1(tmppal);
\r
714 /* save and load */
\r
716 modexPalSave(byte *palette) {
\r
719 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
720 for(i=0; i<PAL_SIZE; i++) {
\r
721 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
729 ptr = malloc(PAL_SIZE);
\r
731 /* handle errors */
\r
733 printf("Could not allocate palette.\n");
\r
742 modexLoadPalFile(byte *filename, byte **palette) {
\r
746 /* free the palette if it exists */
\r
751 /* allocate the new palette */
\r
752 *palette = modexNewPal();
\r
754 /* open the file */
\r
755 file = fopen(filename, "rb");
\r
757 printf("Could not open palette file: %s\n", filename);
\r
761 /* read the file */
\r
763 while(!feof(file)) {
\r
764 *ptr++ = fgetc(file);
\r
772 modexSavePalFile(char *filename, byte *pal) {
\r
776 /* open the file for writing */
\r
777 file = fopen(filename, "wb");
\r
779 printf("Could not open %s for writing\n", filename);
\r
783 /* write the data to the file */
\r
784 fwrite(pal, 1, PAL_SIZE, file);
\r
792 fadePalette(-1, 64, 1, tmppal);
\r
798 fadePalette(-1, -64, 1, tmppal);
\r
804 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
806 byte *p = bmp->palette;
\r
810 static word a[PAL_SIZE]; //palette array of change values!
\r
811 word z=0, aq=0, aa=0, pp=0;
\r
816 memset(a, -1, sizeof(a));
\r
817 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
827 // printf("q: %02d\n", (q));
\r
828 // printf("qq: %02d\n", (qq));
\r
829 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
830 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
832 if((*i)<PAL_SIZE/2 && w==0)
\r
834 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
836 //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
837 //____ 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
838 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
843 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
845 //printf("qp=%d\n", qp);
\r
846 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
847 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
848 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
849 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
853 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
855 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
856 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
857 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
860 //if(qp>0) printf("qp=%d\n", qp);
\r
861 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
863 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
864 if((*i)>=PAL_SIZE/2 && w==0)
\r
866 for(; (*i)<PAL_SIZE; (*i)++)
\r
868 //____ 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
869 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
874 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
876 //printf("qp=%d\n", qp);
\r
877 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
878 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
879 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
880 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
884 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
885 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
886 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
889 //printf(" (*i)=%d\n", (*i)/3);
\r
892 printf("\nqqqqqqqq\n\n");
\r
898 long bufSize = (bmp->width * bmp->height);
\r
900 //printf("1(*i)=%02d\n", (*i)/3);
\r
901 //printf("1z=%02d\n", z/3);
\r
902 chkcolor(bmp, &q, &a, &aa, &z, i);
\r
903 //printf("2(*i)=%02d\n", (*i)/3);
\r
904 //printf("2z=%02d\n", z/3);
\r
909 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
910 if(a[aq]==-1) aq++;
\r
911 else { aqoffset++; break; }
\r
913 //update the image data here!
\r
914 for(lq=0; lq<bufSize; lq++)
\r
918 use a[qp] instead of bmp->offset for this spot!
\r
923 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
926 //(offset/bmp->offset)*bmp->offset
\r
929 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
930 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
931 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
932 /*if(bmp->data[lq]+bmp->offset==aq)
\r
934 //printf("%02d", bmp->data[lq]);
\r
935 //printf("\n%02d\n", bmp->offset);
\r
936 printf("aq=%02d ", aq);
\r
937 printf("a[aq]=%02d ", a[aq]);
\r
938 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
939 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
940 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
941 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
942 // printf("_%d ", bmp->data[lq]);
\r
943 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
945 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
947 if(bmp->data[lq]+bmp->offset >= aq)
\r
949 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
950 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
952 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
955 //printf("%02d`", bmp->data[lq]);
\r
956 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
959 //printf(" aq=%02d\n", aq);
\r
960 //printf(" aa=%02d\n", aa);
\r
962 //update the palette~
\r
963 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
966 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
971 modexPalUpdate1(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, p[i]);
\r
980 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
981 for(; i<PAL_SIZE; i++)
\r
983 outp(PAL_DATA_REG, p[(i)]);
\r
988 modexPalUpdate0(byte *p)
\r
992 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
993 for(i=0; i<PAL_SIZE/2; i++)
\r
995 outp(PAL_DATA_REG, rand());
\r
997 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
998 for(; i<PAL_SIZE; i++)
\r
1000 outp(PAL_DATA_REG, rand());
\r
1005 //i want to make another vesion that checks the palette when the palette is being appened~
\r
1006 void chkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
1010 pal = modexNewPal();
\r
1011 modexPalSave(pal);
\r
1012 //printf("q: %02d\n", (*q));
\r
1013 printf("chkcolor start~\n");
\r
1014 printf("1 (*z): %d\n", (*z)/3);
\r
1015 printf("1 (*i): %d\n", (*i)/3);
\r
1016 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
1017 printf("wwwwwwwwwwwwwwww\n");
\r
1018 //check palette for dups
\r
1019 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
1021 //printf("\n z: %d\n", (*z));
\r
1022 //printf(" q: %d\n", (*q));
\r
1023 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
1026 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
1029 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1030 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
1034 else for(zz=0; zz<(*q); zz+=3)
\r
1036 //printf("zz: %02d\n", zz/3);
\r
1039 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
1043 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
1044 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
1047 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
1049 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
1050 // 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
1051 // 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
1052 // //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
1053 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1056 //expand dong here
\r
1058 planned features that i plan to implement~
\r
1059 image that has values on the pallete list!
\r
1061 no... wait.... no wwww
\r
1063 //for(zzii=0; zzii<3; zzii++)
\r
1065 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
1066 a[(((*z)+(*q)))]=zz;
\r
1068 (*aa)=(((*z)+(*q)));
\r
1069 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
1070 // printf("\n aa: %d\n\n", (*aa));
\r
1071 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
1072 // printf("wwwwwwwwwwwwwwww\n\n");
\r
1076 printf("================\n");
\r
1077 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
1078 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
1079 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1080 printf("================\n");
\r
1082 //printf("[%d]", (zz+q));
\r
1086 printf("wwwwwwwwwwwwwwww\n");
\r
1087 printf("2 (*z): %d\n", (*z)/3);
\r
1088 printf("2 (*i): %d\n", (*i)/3);
\r
1089 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
1090 printf("chkcolor end~\n");
\r
1094 void modexputPixel(page_t *page, int x, int y, byte color)
\r
1096 word pageOff = (word) page->data;
\r
1097 /* Each address accesses four neighboring pixels, so set
\r
1098 Write Plane Enable according to which pixel we want
\r
1099 to modify. The plane is determined by the two least
\r
1100 significant bits of the x-coordinate: */
\r
1101 modexSelectPlane(PLANE(x));
\r
1102 //outp(SC_INDEX, 0x02);
\r
1103 //outp(SC_DATA, 0x01 << (x & 3));
\r
1105 /* The offset of the pixel into the video segment is
\r
1106 offset = (width * y + x) / 4, and write the given
\r
1107 color to the plane we selected above. Heed the active
\r
1108 page start selection. */
\r
1109 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
1113 byte modexgetPixel(page_t *page, int x, int y)
\r
1115 word pageOff = (word) page->data;
\r
1116 /* Select the plane from which we must read the pixel color: */
\r
1117 outpw(GC_INDEX, 0x04);
\r
1118 outpw(GC_INDEX+1, x & 3);
\r
1120 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
1124 void modexhlin(page_t *page, word xl, word xh, word y, word color)
\r
1129 for(x=0;x<xh*4;x+=4)
\r
1131 if(x+4>=SCREEN_WIDTH-1){ x=0; yy+=4; }
\r
1132 modexClearRegion(page, x+xl, y+yy, 4, 4, color);
\r
1134 //modexputPixel(page, x+xl, y, color);
\r
1137 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1139 word i, s, o, w, j, xp;
\r
1141 word addr = (word) l;
\r
1165 s=romFonts[t].seg;
\r
1166 o=romFonts[t].off;
\r
1168 for(; *str != '\0'; str++)
\r
1171 if((c=='\n'/* || c=="\
\r
1179 //load the letter 'A'
\r
1185 MOV AL, c ; the letter
\r
1188 ADD SI, AX ;the address of charcter
\r
1197 for(i=0; i<w; i++)
\r
1203 modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1212 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1214 word i, s, o, w, j, xp;
\r
1216 word addr = (word) l;
\r
1240 s=romFonts[t].seg;
\r
1241 o=romFonts[t].off;
\r
1243 for(; *str != '\0'; str++)
\r
1246 if((c=='\n'/* || c=="\
\r
1247 "*/)/* || chw>=page->width*/)
\r
1253 //load the letter 'A'
\r
1259 MOV AL, c ; the letter
\r
1262 ADD SI, AX ;the address of charcter
\r
1271 for(i=0; i<w; i++)
\r
1277 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1278 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1287 /////////////////////////////////////////////////////////////////////////////
\r
1289 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1290 // the Virtual screen. //
\r
1292 /////////////////////////////////////////////////////////////////////////////
\r
1293 void cls(page_t *page, byte color, byte *Where)
\r
1295 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1296 /* set map mask to all 4 planes */
\r
1297 outpw(SC_INDEX, 0xff02);
\r
1298 //_fmemset(VGA, color, 16000);
\r
1299 _fmemset(Where, color, page->width*(page->height));
\r
1303 modexWaitBorder() {
\r
1304 while(inp(INPUT_STATUS_1) & 8) {
\r
1308 while(!(inp(INPUT_STATUS_1) & 8)) {
\r