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
33 /////////////////////////////////////////////////////////////////////////////
\r
35 // setvideo() - This function Manages the video modes //
\r
37 /////////////////////////////////////////////////////////////////////////////
\r
38 void VGAmodeX(sword vq, global_game_variables_t *gv)
\r
44 case 0: // 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->video.old_mode;
\r
49 int86(0x10, &in, &out);
\r
51 default: // init the video
\r
52 // get old video mode
\r
54 //int86(0x10, &in, &out);
\r
55 gv->video.old_mode = vgaGetMode();//out.h.al;
\r
63 vgaSetMode(byte mode)
\r
67 regs.h.ah = SET_MODE;
\r
69 int86(VIDEO_INT, ®s, ®s);
\r
72 //---------------------------------------------------
\r
74 // Use the bios to get the current video mode
\r
83 int86(VIDEO_INT, &rg, &rg);
\r
88 /* -========================= Entry Points ==========================- */
\r
90 modexEnter(sword vq, global_game_variables_t *gv)
\r
93 dword far*ptr=(dword far*)VGA; /* used for faster screen clearing */
\r
95 /* common mode X initiation stuff~ */
\r
96 modexsetBaseXMode(gv->video.page);
\r
102 CRTParmCount = sizeof(ModeX_320x240regs) / sizeof(ModeX_320x240regs[0]);
\r
103 /* width and height */
\r
104 gv->video.page[0].sw=320;
\r
105 gv->video.page[0].sh=240;
\r
106 //printf("%dx%d\n", gv->video.page[0].sw, gv->video.page[0].sh);
\r
107 gv->video.page[0].tilesw = gv->video.page[0].sw/TILEWH;
\r
108 gv->video.page[0].tilesh = gv->video.page[0].sh/TILEWH;
\r
109 //printf("%dx%d\n", gv->video.page[0].tilesw, gv->video.page[0].tilesh);
\r
110 //TODO MAKE FLEXIBLE~
\r
111 gv->video.page[0].tilemidposscreenx = 10;
\r
112 gv->video.page[0].tilemidposscreeny = 8;
\r
114 /* send the CRTParms */
\r
115 for(i=0; i<CRTParmCount; i++) {
\r
116 outpw(CRTC_INDEX, ModeX_320x240regs[i]);
\r
119 /* clear video memory */
\r
120 outpw(SC_INDEX, 0x0f02);
\r
121 for(i=0; i<0x8000; i++) {
\r
126 CRTParmCount = sizeof(ModeX_192x144regs) / sizeof(ModeX_192x144regs[0]);
\r
127 /* width and height */
\r
128 //TODO add width and height of screen
\r
130 /* send the CRTParms */
\r
131 for(i=0; i<CRTParmCount; i++) {
\r
132 outpw(CRTC_INDEX, ModeX_192x144regs[i]);
\r
135 /* clear video memory */
\r
136 outpw(SC_INDEX, 0x0f02);
\r
137 for(i=0; i<0x8000; i++) {
\r
142 #define PAGE_SIZE (word)(gv->video.page[0].sw/4 * gv->video.page[0].sh)
\r
147 /* TODO restore original mode and palette */
\r
148 vgaSetMode(TEXT_MODE);
\r
151 // setBaseXMode() does the initialization to make the VGA ready to
\r
152 // accept any combination of configuration register settings. This
\r
153 // involves enabling writes to index 0 to 7 of the CRT controller (port
\r
154 // 0x3D4), by clearing the most significant bit (bit 7) of index 0x11.
\r
156 modexsetBaseXMode(page_t *page)
\r
159 /* TODO save current video mode and palette */
\r
160 vgaSetMode(VGA_256_COLOR_MODE);
\r
162 /* disable chain4 mode */
\r
163 outpw(SC_INDEX, 0x0604);
\r
165 /* synchronous reset while setting Misc Output */
\r
166 outpw(SC_INDEX, 0x0100);
\r
168 /* select 25 MHz dot clock & 60 Hz scanning rate */
\r
169 outp(MISC_OUTPUT, 0xe3);
\r
171 /* undo reset (restart sequencer) */
\r
172 outpw(SC_INDEX, 0x0300);
\r
174 /* reprogram the CRT controller */
\r
175 outp(CRTC_INDEX, 0x11); /* VSync End reg contains register write prot */
\r
176 temp = inp(CRTC_DATA) & 0x7F;
\r
177 outp(CRTC_INDEX, 0x11);
\r
178 // outp(CRTC_DATA, 0x7f); /* get current write protect on varios regs */
\r
179 outp(CRTC_DATA, temp); /* get current write protect on varios regs */
\r
183 modexDefaultPage(page_t *p)
\r
187 /* default page values */
\r
191 page.width = p->sw;
\r
192 page.height = p->sh;
\r
193 page.tw = page.sw/TILEWH;
\r
194 page.th = page.sh/TILEWH;
\r
200 /* returns the next page in contiguous memory
\r
201 * the next page will be the same size as p, by default
\r
204 modexNextPage(page_t *p) {
\r
207 result.data = p->data + (p->width/4)*p->height;
\r
210 result.width = p->width;
\r
211 result.height = p->height;
\r
212 result.tw = p->width/TILEWH;
\r
213 result.th = p->height/TILEWH;
\r
214 result.id = p->id+1;
\r
217 // return modexNextPageFlexibleSize(&p, p->width, p->height);
\r
220 //next page with defined dimentions~
\r
222 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
226 result.data = p->data + (p->width/4)*p->height; /* compute the offset */
\r
231 result.tw = p->width/TILEWH;
\r
232 result.th = p->height/TILEWH;
\r
233 result.id = p->id+1;
\r
240 modexShowPage(page_t *page) {
\r
246 /* calculate offset */
\r
247 offset = (word) page->data;
\r
248 offset += page->dy * (page->width >> 2 );
\r
249 offset += page->dx >> 2;
\r
251 /* calculate crtcOffset according to virtual width */
\r
252 crtcOffset = page->width >> 3;
\r
254 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
255 low_address = LOW_ADDRESS | (offset << 8);
\r
257 /* wait for appropriate timing and then program CRTC */
\r
258 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
259 outpw(CRTC_INDEX, high_address);
\r
260 outpw(CRTC_INDEX, low_address);
\r
261 outp(CRTC_INDEX, 0x13);
\r
262 outp(CRTC_DATA, crtcOffset);
\r
264 /* wait for one retrace */
\r
265 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
267 /* do PEL panning here */
\r
268 outp(AC_INDEX, 0x33);
\r
269 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
274 modexPanPage(page_t *page, int dx, int dy) {
\r
281 modexSelectPlane(byte plane) {
\r
282 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
283 outp(SC_DATA, plane);
\r
288 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
289 word pageOff = (word) page->data;
\r
290 word xoff=x/4; /* xoffset that begins each row */
\r
291 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
292 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
293 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
294 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
295 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
296 byte left = lclip[x&0x03];
\r
297 byte right = rclip[(x+w)&0x03];
\r
299 /* handle the case which requires an extra group */
\r
300 if((x & 0x03) && !((x+w) & 0x03)) {
\r
305 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
307 MOV DI, poffset ; go to the first pixel
\r
308 MOV DX, SC_INDEX ; point to the map mask
\r
312 MOV AL, color ; get ready to write colors
\r
314 MOV CX, scanCount ; count the line
\r
315 MOV BL, AL ; remember color
\r
316 MOV AL, left ; do the left clip
\r
317 OUT DX, AL ; set the left clip
\r
318 MOV AL, BL ; restore color
\r
319 STOSB ; write the color
\r
321 JZ SCAN_DONE ; handle 1 group stuff
\r
323 ;-- write the main body of the scanline
\r
324 MOV BL, AL ; remember color
\r
325 MOV AL, 0x0f ; write to all pixels
\r
327 MOV AL, BL ; restore color
\r
328 REP STOSB ; write the color
\r
330 MOV BL, AL ; remeber color
\r
332 OUT DX, AL ; do the right clip
\r
333 MOV AL, BL ; restore color
\r
334 STOSB ; write pixel
\r
335 ADD DI, nextRow ; go to the next row
\r
343 oldDrawBmp(byte far* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
349 /* TODO Make this fast. It's SLOOOOOOW */
\r
350 for(plane=0; plane < 4; plane++) {
\r
351 modexSelectPlane(PLANE(plane+x));
\r
352 for(px = plane; px < bmp->width; px+=4) {
\r
354 for(py=0; py<bmp->height; py++) {
\r
355 if(!sprite || bmp->data[offset])
\r
356 page[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
357 offset+=bmp->width;
\r
364 CDrawBmp(byte far* vgamem, page_t* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
371 /* TODO Make this fast. It's SLOOOOOOW */
\r
372 for(plane=0; plane < 4; plane++) {
\r
373 modexSelectPlane(PLANE(plane+x));
\r
374 for(px = plane; px < bmp->width; px+=4) {
\r
376 for(py=0; py<bmp->height; py++) {
\r
377 if(!sprite || bmp->data[offset])
\r
378 //modexputPixel(page, x+px, y+py, bmp->data[offset]);
\r
379 vgamem[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
380 offset+=bmp->width;
\r
387 modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) {
\r
388 /* draw the region (the entire freakin bitmap) */
\r
389 modexDrawBmpRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
394 modexDrawBmpRegion(page_t *page, int x, int y,
\r
395 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
396 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
397 byte far *data = bmp->data;//+bmp->offset;
\r
398 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
401 byte plane = 1 << ((byte) x & 0x03);
\r
402 word scanCount = width/4 + (width%4 ? 1 :0);
\r
403 word nextPageRow = page->width/4 - scanCount;
\r
404 word nextBmpRow = (word) bmp->width - width;
\r
406 byte planeCounter = 4;
\r
408 /* printf("bmp->data=%Fp\n",bmp->data);
\r
409 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
410 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
412 //code is a bit slow here
\r
414 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
417 MOV DX, SC_INDEX ; point at the map mask register
\r
422 MOV DX, SC_DATA ; select the current plane
\r
426 ;-- begin plane painting
\r
427 MOV AX, height ; start the row counter
\r
428 MOV rowCounter, AX ;
\r
429 MOV DI, poffset ; go to the first pixel
\r
430 MOV SI, bmpOffset ; go to the bmp pixel
\r
432 MOV CX, width ; count the columns
\r
434 MOVSB ; copy the pixel
\r
435 SUB CX, 3 ; we skip the next 3
\r
436 ADD SI, 3 ; skip the bmp pixels
\r
437 LOOP SCAN_LOOP ; finish the scan
\r
439 MOV AX, nextPageRow
\r
440 ADD DI, AX ; go to the next row on screen
\r
442 ADD SI, AX ; go to the next row on bmp
\r
445 JNZ ROW_LOOP ; do all the rows
\r
446 ;-- end plane painting
\r
448 MOV AL, plane ; advance to the next plane
\r
450 AND AL, 0x0f ; mask the plane properly
\r
451 MOV plane, AL ; store the plane
\r
453 INC bmpOffset ; start bmp at the right spot
\r
456 JNZ PLANE_LOOP ; do all 4 planes
\r
461 modex_sparky4_DrawBmpRegion(page_t *page, int x, int y,
\r
462 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
463 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
464 byte far *data = bmp->data;//+bmp->offset;
\r
465 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
468 byte plane = 1 << ((byte) x & 0x03);
\r
469 word scanCount = width/4 + (width%4 ? 1 :0);
\r
470 word nextPageRow = page->width/4 - scanCount;
\r
471 word nextBmpRow = (word) bmp->width - width;
\r
473 byte planeCounter = 4;
\r
475 /* printf("bmp->data=%Fp\n",bmp->data);
\r
476 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
477 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
479 //code is a bit slow here
\r
481 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
484 MOV DX, SC_INDEX ; point at the map mask register
\r
489 MOV DX, SC_DATA ; select the current plane
\r
493 ;-- begin plane painting
\r
494 MOV AX, height ; start the row counter
\r
495 MOV rowCounter, AX ;
\r
496 MOV DI, poffset ; go to the first pixel
\r
497 MOV SI, bmpOffset ; go to the bmp pixel
\r
499 MOV CX, width ; count the columns
\r
501 MOVSB ; copy the pixel
\r
502 SUB CX, 3 ; we skip the next 3
\r
503 ADD SI, 3 ; skip the bmp pixels
\r
504 LOOP SCAN_LOOP ; finish the scan
\r
506 MOV AX, nextPageRow
\r
507 ADD DI, AX ; go to the next row on screen
\r
509 ADD SI, AX ; go to the next row on bmp
\r
512 JNZ ROW_LOOP ; do all the rows
\r
513 ;-- end plane painting
\r
515 MOV AL, plane ; advance to the next plane
\r
517 AND AL, 0x0f ; mask the plane properly
\r
518 MOV plane, AL ; store the plane
\r
520 INC bmpOffset ; start bmp at the right spot
\r
523 JNZ PLANE_LOOP ; do all 4 planes
\r
528 modexDrawPlanarBuf(page_t *page, int x, int y, planar_buf_t *bmp) {
\r
529 /* TODO - adapt from test code */
\r
531 for(plane=0; plane < 4; plane++)
\r
539 modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp) {
\r
540 /* draw the whole sprite */
\r
541 modexDrawSpriteRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
545 modexDrawSpriteRegion(page_t *page, int x, int y,
\r
546 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
547 word poffset = (word)page->data + y*(page->width/4) + x/4;
\r
548 byte *data = bmp->data;//+bmp->offset;
\r
549 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
552 byte plane = 1 << ((byte) x & 0x03);
\r
553 word scanCount = width/4 + (width%4 ? 1 :0);
\r
554 word nextPageRow = page->width/4 - scanCount;
\r
555 word nextBmpRow = (word) bmp->width - width;
\r
557 byte planeCounter = 4;
\r
560 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
563 MOV DX, SC_INDEX ; point at the map mask register
\r
568 MOV DX, SC_DATA ; select the current plane
\r
572 ;-- begin plane painting
\r
573 MOV AX, height ; start the row counter
\r
574 MOV rowCounter, AX ;
\r
575 MOV DI, poffset ; go to the first pixel
\r
576 MOV SI, bmpOffset ; go to the bmp pixel
\r
578 MOV CX, width ; count the columns
\r
583 JNE DRAW_PIXEL ; draw non-zero pixels
\r
585 INC DI ; skip the transparent pixel
\r
589 MOVSB ; copy the pixel
\r
591 SUB CX, 3 ; we skip the next 3
\r
592 ADD SI, 3 ; skip the bmp pixels
\r
593 LOOP SCAN_LOOP ; finish the scan
\r
595 MOV AX, nextPageRow
\r
596 ADD DI, AX ; go to the next row on screen
\r
598 ADD SI, AX ; go to the next row on bmp
\r
601 JNZ ROW_LOOP ; do all the rows
\r
602 ;-- end plane painting
\r
604 MOV AL, plane ; advance to the next plane
\r
606 AND AL, 0x0f ; mask the plane properly
\r
607 MOV plane, AL ; store the plane
\r
609 INC bmpOffset ; start bmp at the right spot
\r
612 JNZ PLANE_LOOP ; do all 4 planes
\r
617 /* copy a region of video memory from one page to another.
\r
618 * It assumes that the left edge of the tile is the same on both
\r
619 * regions and the memory areas do not overlap.
\r
622 modexCopyPageRegion(page_t *dest, page_t *src,
\r
625 word width, word height)
\r
627 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
628 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
629 word scans = width/4;
\r
630 word nextSrcRow = src->width/4 - scans - 1;
\r
631 word nextDestRow = dest->width/4 - scans - 1;
\r
632 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
633 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
634 byte left = lclip[sx&0x03];
\r
635 byte right = rclip[(sx+width)&0x03];
\r
638 MOV AX, SCREEN_SEG ; work in the vga space
\r
643 MOV DX, GC_INDEX ; turn off cpu bits
\r
647 MOV AX, SC_INDEX ; point to the mask register
\r
657 MOV CX, scans ; the number of latches
\r
659 MOV AL, left ; do the left column
\r
664 MOV AL, 0fh ; do the inner columns
\r
666 REP MOVSB ; copy the pixels
\r
668 MOV AL, right ; do the right column
\r
673 MOV AX, SI ; go the start of the next row
\r
674 ADD AX, nextSrcRow ;
\r
677 ADD AX, nextDestRow ;
\r
680 DEC height ; do the rest of the actions
\r
683 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
684 MOV AL, 0ffh ; none from latches
\r
690 /* fade and flash */
\r
692 modexFadeOn(word fade, byte *palette) {
\r
693 fadePalette(-fade, 64, 64/fade+1, palette);
\r
698 modexFadeOff(word fade, byte *palette) {
\r
699 fadePalette(fade, 0, 64/fade+1, palette);
\r
704 modexFlashOn(word fade, byte *palette) {
\r
705 fadePalette(fade, -64, 64/fade+1, palette);
\r
710 modexFlashOff(word fade, byte *palette) {
\r
711 fadePalette(-fade, 0, 64/fade+1, palette);
\r
716 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
720 /* handle the case where we just update */
\r
722 modexPalUpdate1(palette);
\r
726 while(iter > 0) { /* FadeLoop */
\r
727 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
728 tmppal[i] = palette[i] - dim;
\r
729 if(tmppal[i] > 127) {
\r
731 } else if(tmppal[i] > 63) {
\r
735 modexPalUpdate1(tmppal);
\r
742 /* save and load */
\r
744 modexPalSave(byte *palette) {
\r
747 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
748 for(i=0; i<PAL_SIZE; i++) {
\r
749 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
757 ptr = malloc(PAL_SIZE);
\r
759 /* handle errors */
\r
761 printf("Could not allocate palette.\n");
\r
770 modexLoadPalFile(byte *filename, byte **palette) {
\r
774 /* free the palette if it exists */
\r
779 /* allocate the new palette */
\r
780 *palette = modexNewPal();
\r
782 /* open the file */
\r
783 file = fopen(filename, "rb");
\r
785 printf("Could not open palette file: %s\n", filename);
\r
789 /* read the file */
\r
791 while(!feof(file)) {
\r
792 *ptr++ = fgetc(file);
\r
800 modexSavePalFile(char *filename, byte *pal) {
\r
804 /* open the file for writing */
\r
805 file = fopen(filename, "wb");
\r
807 printf("Could not open %s for writing\n", filename);
\r
811 /* write the data to the file */
\r
812 fwrite(pal, 1, PAL_SIZE, file);
\r
820 fadePalette(-1, 64, 1, tmppal);
\r
826 fadePalette(-1, -64, 1, tmppal);
\r
832 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
834 byte *p = bmp->palette;
\r
838 static word a[PAL_SIZE]; //palette array of change values!
\r
839 word z=0, aq=0, aa=0, pp=0;
\r
844 memset(a, -1, sizeof(a));
\r
845 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
855 // printf("q: %02d\n", (q));
\r
856 // printf("qq: %02d\n", (qq));
\r
857 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
858 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
860 if((*i)<PAL_SIZE/2 && w==0)
\r
862 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
864 //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
865 //____ 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
866 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
871 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
873 //printf("qp=%d\n", qp);
\r
874 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
875 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
876 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
877 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
881 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
883 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
884 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
885 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
888 //if(qp>0) printf("qp=%d\n", qp);
\r
889 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
891 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
892 if((*i)>=PAL_SIZE/2 && w==0)
\r
894 for(; (*i)<PAL_SIZE; (*i)++)
\r
896 //____ 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
897 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
902 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
904 //printf("qp=%d\n", qp);
\r
905 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
906 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
907 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
908 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
912 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
913 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
914 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
917 //printf(" (*i)=%d\n", (*i)/3);
\r
920 printf("\nqqqqqqqq\n\n");
\r
926 long bufSize = (bmp->width * bmp->height);
\r
928 //printf("1(*i)=%02d\n", (*i)/3);
\r
929 //printf("1z=%02d\n", z/3);
\r
930 chkcolor(bmp, &q, &a, &aa, &z, i);
\r
931 //printf("2(*i)=%02d\n", (*i)/3);
\r
932 //printf("2z=%02d\n", z/3);
\r
937 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
938 if(a[aq]==-1) aq++;
\r
939 else { aqoffset++; break; }
\r
941 //update the image data here!
\r
942 for(lq=0; lq<bufSize; lq++)
\r
946 use a[qp] instead of bmp->offset for this spot!
\r
951 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
954 //(offset/bmp->offset)*bmp->offset
\r
957 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
958 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
959 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
960 /*if(bmp->data[lq]+bmp->offset==aq)
\r
962 //printf("%02d", bmp->data[lq]);
\r
963 //printf("\n%02d\n", bmp->offset);
\r
964 printf("aq=%02d ", aq);
\r
965 printf("a[aq]=%02d ", a[aq]);
\r
966 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
967 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
968 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
969 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
970 // printf("_%d ", bmp->data[lq]);
\r
971 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
973 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
975 if(bmp->data[lq]+bmp->offset >= aq)
\r
977 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
978 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
980 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
983 //printf("%02d`", bmp->data[lq]);
\r
984 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
987 //printf(" aq=%02d\n", aq);
\r
988 //printf(" aa=%02d\n", aa);
\r
990 //update the palette~
\r
991 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
994 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
999 modexPalUpdate1(byte *p)
\r
1002 modexWaitBorder();
\r
1003 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
1004 for(i=0; i<PAL_SIZE/2; i++)
\r
1006 outp(PAL_DATA_REG, p[i]);
\r
1008 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
1009 for(; i<PAL_SIZE; i++)
\r
1011 outp(PAL_DATA_REG, p[(i)]);
\r
1016 modexPalUpdate0(byte *p)
\r
1019 modexWaitBorder();
\r
1020 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
1021 for(i=0; i<PAL_SIZE/2; i++)
\r
1023 outp(PAL_DATA_REG, rand());
\r
1025 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
1026 for(; i<PAL_SIZE; i++)
\r
1028 outp(PAL_DATA_REG, rand());
\r
1033 //i want to make another vesion that checks the palette when the palette is being appened~
\r
1034 void chkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
1038 pal = modexNewPal();
\r
1039 modexPalSave(pal);
\r
1040 //printf("q: %02d\n", (*q));
\r
1041 printf("chkcolor start~\n");
\r
1042 printf("1 (*z): %d\n", (*z)/3);
\r
1043 printf("1 (*i): %d\n", (*i)/3);
\r
1044 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
1045 printf("wwwwwwwwwwwwwwww\n");
\r
1046 //check palette for dups
\r
1047 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
1049 //printf("\n z: %d\n", (*z));
\r
1050 //printf(" q: %d\n", (*q));
\r
1051 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
1054 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
1057 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1058 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
1062 else for(zz=0; zz<(*q); zz+=3)
\r
1064 //printf("zz: %02d\n", zz/3);
\r
1067 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
1071 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
1072 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
1075 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
1077 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
1078 // 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
1079 // 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
1080 // //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
1081 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1084 //expand dong here
\r
1086 planned features that i plan to implement~
\r
1087 image that has values on the pallete list!
\r
1089 no... wait.... no wwww
\r
1091 //for(zzii=0; zzii<3; zzii++)
\r
1093 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
1094 a[(((*z)+(*q)))]=zz;
\r
1096 (*aa)=(((*z)+(*q)));
\r
1097 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
1098 // printf("\n aa: %d\n\n", (*aa));
\r
1099 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
1100 // printf("wwwwwwwwwwwwwwww\n\n");
\r
1104 printf("================\n");
\r
1105 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
1106 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
1107 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1108 printf("================\n");
\r
1110 //printf("[%d]", (zz+q));
\r
1114 printf("wwwwwwwwwwwwwwww\n");
\r
1115 printf("2 (*z): %d\n", (*z)/3);
\r
1116 printf("2 (*i): %d\n", (*i)/3);
\r
1117 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
1118 printf("chkcolor end~\n");
\r
1122 void modexputPixel(page_t *page, int x, int y, byte color)
\r
1124 word pageOff = (word) page->data;
\r
1125 /* Each address accesses four neighboring pixels, so set
\r
1126 Write Plane Enable according to which pixel we want
\r
1127 to modify. The plane is determined by the two least
\r
1128 significant bits of the x-coordinate: */
\r
1129 modexSelectPlane(PLANE(x));
\r
1130 //outp(SC_INDEX, 0x02);
\r
1131 //outp(SC_DATA, 0x01 << (x & 3));
\r
1133 /* The offset of the pixel into the video segment is
\r
1134 offset = (width * y + x) / 4, and write the given
\r
1135 color to the plane we selected above. Heed the active
\r
1136 page start selection. */
\r
1137 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
1141 byte modexgetPixel(page_t *page, int x, int y)
\r
1143 word pageOff = (word) page->data;
\r
1144 /* Select the plane from which we must read the pixel color: */
\r
1145 outpw(GC_INDEX, 0x04);
\r
1146 outpw(GC_INDEX+1, x & 3);
\r
1148 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
1152 void modexhlin(page_t *page, word xl, word xh, word y, word color)
\r
1157 for(x=0;x<xh*4;x+=4)
\r
1159 if(x+4>=page[0].sw-1){ x=0; yy+=4; }
\r
1160 modexClearRegion(page, x+xl, y+yy, 4, 4, color);
\r
1162 //modexputPixel(page, x+xl, y, color);
\r
1165 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1167 word i, s, o, w, j, xp;
\r
1169 word addr = (word) l;
\r
1193 s=romFonts[t].seg;
\r
1194 o=romFonts[t].off;
\r
1196 for(; *str != '\0'; str++)
\r
1199 if((c=='\n'/* || c=="\
\r
1207 //load the letter 'A'
\r
1213 MOV AL, c ; the letter
\r
1216 ADD SI, AX ;the address of charcter
\r
1225 for(i=0; i<w; i++)
\r
1231 modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1240 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1242 word i, s, o, w, j, xp;
\r
1244 word addr = (word) l;
\r
1268 s=romFonts[t].seg;
\r
1269 o=romFonts[t].off;
\r
1271 for(; *str != '\0'; str++)
\r
1274 if((c=='\n'/* || c=="\
\r
1275 "*/)/* || chw>=page->width*/)
\r
1281 //load the letter 'A'
\r
1287 MOV AL, c ; the letter
\r
1290 ADD SI, AX ;the address of charcter
\r
1299 for(i=0; i<w; i++)
\r
1305 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1306 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1315 /* palette dump on display! */
\r
1316 void pdump(page_t *pee)
\r
1318 int mult=(QUADWH);
\r
1319 int palq=(mult)*TILEWH;
\r
1322 for(paly=0; paly<palq; paly+=mult){
\r
1323 for(palx=0; palx<palq; palx+=mult){
\r
1324 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
\r
1330 /////////////////////////////////////////////////////////////////////////////
\r
1332 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1333 // the Virtual screen. //
\r
1335 /////////////////////////////////////////////////////////////////////////////
\r
1336 void cls(page_t *page, byte color, byte *Where)
\r
1338 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1339 /* set map mask to all 4 planes */
\r
1340 outpw(SC_INDEX, 0xff02);
\r
1341 //_fmemset(VGA, color, 16000);
\r
1342 _fmemset(Where, color, page->width*(page->height));
\r
1346 modexWaitBorder() {
\r
1347 while(inp(INPUT_STATUS_1) & 8) {
\r
1351 while(!(inp(INPUT_STATUS_1) & 8)) {
\r