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
101 CRTParmCount = sizeof(ModeX_320x240regs) / sizeof(ModeX_320x240regs[0]);
\r
102 /* width and height */
\r
103 gv->video.page[0].sw=320;
\r
104 gv->video.page[0].sh=240;
\r
106 /* send the CRTParms */
\r
107 for(i=0; i<CRTParmCount; i++) {
\r
108 outpw(CRTC_INDEX, ModeX_320x240regs[i]);
\r
111 /* clear video memory */
\r
112 outpw(SC_INDEX, 0x0f02);
\r
113 for(i=0; i<0x8000; i++) {
\r
118 CRTParmCount = sizeof(ModeX_192x144regs) / sizeof(ModeX_192x144regs[0]);
\r
119 /* width and height */
\r
120 gv->video.page[0].sw=192;
\r
121 gv->video.page[0].sh=144;
\r
123 /* send the CRTParms */
\r
124 for(i=0; i<CRTParmCount; i++) {
\r
125 outpw(CRTC_INDEX, ModeX_192x144regs[i]);
\r
128 /* clear video memory */
\r
129 outpw(SC_INDEX, 0x0f02);
\r
130 for(i=0; i<0x8000; i++) {
\r
135 gv->video.page[0].tilesw = gv->video.page[0].sw/TILEWH;
\r
136 gv->video.page[0].tilesh = gv->video.page[0].sh/TILEWH;
\r
137 //TODO MAKE FLEXIBLE~
\r
138 gv->video.page[0].tilemidposscreenx = gv->video.page[0].tilesw;
\r
139 gv->video.page[0].tilemidposscreeny = (gv->video.page[0].tilesh/2)+1;
\r
140 #define PAGE_SIZE (word)(gv->video.page[0].sw/4 * gv->video.page[0].sh)
\r
145 /* TODO restore original mode and palette */
\r
146 vgaSetMode(TEXT_MODE);
\r
149 // setBaseXMode() does the initialization to make the VGA ready to
\r
150 // accept any combination of configuration register settings. This
\r
151 // involves enabling writes to index 0 to 7 of the CRT controller (port
\r
152 // 0x3D4), by clearing the most significant bit (bit 7) of index 0x11.
\r
154 modexsetBaseXMode(page_t *page)
\r
157 /* TODO save current video mode and palette */
\r
158 vgaSetMode(VGA_256_COLOR_MODE);
\r
160 /* disable chain4 mode */
\r
161 outpw(SC_INDEX, 0x0604);
\r
163 /* synchronous reset while setting Misc Output */
\r
164 outpw(SC_INDEX, 0x0100);
\r
166 /* select 25 MHz dot clock & 60 Hz scanning rate */
\r
167 outp(MISC_OUTPUT, 0xe3);
\r
169 /* undo reset (restart sequencer) */
\r
170 outpw(SC_INDEX, 0x0300);
\r
172 /* reprogram the CRT controller */
\r
173 outp(CRTC_INDEX, 0x11); /* VSync End reg contains register write prot */
\r
174 // temp = inp(CRTC_DATA) & 0x7F;
\r
175 // outp(CRTC_INDEX, 0x11);
\r
176 outp(CRTC_DATA, 0x7f); /* get current write protect on varios regs */
\r
177 // outp(CRTC_DATA, temp); /* get current write protect on varios regs */
\r
181 modexDefaultPage(page_t *p)
\r
185 /* 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
195 page.tilemidposscreenx = page.tw/2;
\r
196 page.tilemidposscreeny = (page.th/2)+1;
\r
197 //pageSize = p->sw*p->sh;
\r
203 /* returns the next page in contiguous memory
\r
204 * the next page will be the same size as p, by default
\r
207 modexNextPage(page_t *p) {
\r
210 result.data = p->data + (p->width/4)*p->height;
\r
213 result.width = p->width;
\r
214 result.height = p->height;
\r
215 result.tw = p->width/TILEWH;
\r
216 result.th = p->height/TILEWH;
\r
217 result.id = p->id+1;
\r
220 // return modexNextPageFlexibleSize(&p, p->width, p->height);
\r
223 //next page with defined dimentions~
\r
225 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
229 result.data = p->data + (p->width/4)*p->height; /* compute the offset */
\r
234 result.tw = p->width/TILEWH;
\r
235 result.th = p->height/TILEWH;
\r
236 result.id = p->id+1;
\r
243 modexShowPage(page_t *page) {
\r
249 /* calculate offset */
\r
250 offset = (word) page->data;
\r
251 offset += page->dy * (page->width >> 2 );
\r
252 offset += page->dx >> 2;
\r
254 /* calculate crtcOffset according to virtual width */
\r
255 crtcOffset = page->width >> 3;
\r
257 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
258 low_address = LOW_ADDRESS | (offset << 8);
\r
260 /* wait for appropriate timing and then program CRTC */
\r
261 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
262 outpw(CRTC_INDEX, high_address);
\r
263 outpw(CRTC_INDEX, low_address);
\r
264 outp(CRTC_INDEX, 0x13);
\r
265 outp(CRTC_DATA, crtcOffset);
\r
267 /* wait for one retrace */
\r
268 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
270 /* do PEL panning here */
\r
271 outp(AC_INDEX, 0x33);
\r
272 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
277 modexPanPage(page_t *page, int dx, int dy) {
\r
284 modexSelectPlane(byte plane) {
\r
285 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
286 outp(SC_DATA, plane);
\r
291 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
292 word pageOff = (word) page->data;
\r
293 word xoff=x/4; /* xoffset that begins each row */
\r
294 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
295 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
296 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
297 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
298 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
299 byte left = lclip[x&0x03];
\r
300 byte right = rclip[(x+w)&0x03];
\r
302 /* handle the case which requires an extra group */
\r
303 if((x & 0x03) && !((x+w) & 0x03)) {
\r
308 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
310 MOV DI, poffset ; go to the first pixel
\r
311 MOV DX, SC_INDEX ; point to the map mask
\r
315 MOV AL, color ; get ready to write colors
\r
317 MOV CX, scanCount ; count the line
\r
318 MOV BL, AL ; remember color
\r
319 MOV AL, left ; do the left clip
\r
320 OUT DX, AL ; set the left clip
\r
321 MOV AL, BL ; restore color
\r
322 STOSB ; write the color
\r
324 JZ SCAN_DONE ; handle 1 group stuff
\r
326 ;-- write the main body of the scanline
\r
327 MOV BL, AL ; remember color
\r
328 MOV AL, 0x0f ; write to all pixels
\r
330 MOV AL, BL ; restore color
\r
331 REP STOSB ; write the color
\r
333 MOV BL, AL ; remeber color
\r
335 OUT DX, AL ; do the right clip
\r
336 MOV AL, BL ; restore color
\r
337 STOSB ; write pixel
\r
338 ADD DI, nextRow ; go to the next row
\r
346 oldDrawBmp(byte far* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
352 /* TODO Make this fast. It's SLOOOOOOW */
\r
353 for(plane=0; plane < 4; plane++) {
\r
354 modexSelectPlane(PLANE(plane+x));
\r
355 for(px = plane; px < bmp->width; px+=4) {
\r
357 for(py=0; py<bmp->height; py++) {
\r
358 if(!sprite || bmp->data[offset])
\r
359 page[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
360 offset+=bmp->width;
\r
367 CDrawBmp(byte far* vgamem, page_t* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
374 /* TODO Make this fast. It's SLOOOOOOW */
\r
375 for(plane=0; plane < 4; plane++) {
\r
376 modexSelectPlane(PLANE(plane+x));
\r
377 for(px = plane; px < bmp->width; px+=4) {
\r
379 for(py=0; py<bmp->height; py++) {
\r
380 if(!sprite || bmp->data[offset])
\r
381 //modexputPixel(page, x+px, y+py, bmp->data[offset]);
\r
382 vgamem[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
383 offset+=bmp->width;
\r
390 modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) {
\r
391 /* draw the region (the entire freakin bitmap) */
\r
392 modexDrawBmpRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
397 modexDrawBmpRegion(page_t *page, int x, int y,
\r
398 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
399 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
400 byte far *data = bmp->data;//+bmp->offset;
\r
401 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
404 byte plane = 1 << ((byte) x & 0x03);
\r
405 word scanCount = width/4 + (width%4 ? 1 :0);
\r
406 word nextPageRow = page->width/4 - scanCount;
\r
407 word nextBmpRow = (word) bmp->width - width;
\r
409 byte planeCounter = 4;
\r
411 /* printf("bmp->data=%Fp\n",bmp->data);
\r
412 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
413 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
415 //code is a bit slow here
\r
417 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
420 MOV DX, SC_INDEX ; point at the map mask register
\r
425 MOV DX, SC_DATA ; select the current plane
\r
429 ;-- begin plane painting
\r
430 MOV AX, height ; start the row counter
\r
431 MOV rowCounter, AX ;
\r
432 MOV DI, poffset ; go to the first pixel
\r
433 MOV SI, bmpOffset ; go to the bmp pixel
\r
435 MOV CX, width ; count the columns
\r
437 MOVSB ; copy the pixel
\r
438 SUB CX, 3 ; we skip the next 3
\r
439 ADD SI, 3 ; skip the bmp pixels
\r
440 LOOP SCAN_LOOP ; finish the scan
\r
442 MOV AX, nextPageRow
\r
443 ADD DI, AX ; go to the next row on screen
\r
445 ADD SI, AX ; go to the next row on bmp
\r
448 JNZ ROW_LOOP ; do all the rows
\r
449 ;-- end plane painting
\r
451 MOV AL, plane ; advance to the next plane
\r
453 AND AL, 0x0f ; mask the plane properly
\r
454 MOV plane, AL ; store the plane
\r
456 INC bmpOffset ; start bmp at the right spot
\r
459 JNZ PLANE_LOOP ; do all 4 planes
\r
464 modex_sparky4_DrawBmpRegion(page_t *page, int x, int y,
\r
465 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
466 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
467 byte far *data = bmp->data;//+bmp->offset;
\r
468 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
471 byte plane = 1 << ((byte) x & 0x03);
\r
472 word scanCount = width/4 + (width%4 ? 1 :0);
\r
473 word nextPageRow = page->width/4 - scanCount;
\r
474 word nextBmpRow = (word) bmp->width - width;
\r
476 byte planeCounter = 4;
\r
478 /* printf("bmp->data=%Fp\n",bmp->data);
\r
479 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
480 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
482 //code is a bit slow here
\r
484 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
487 MOV DX, SC_INDEX ; point at the map mask register
\r
492 MOV DX, SC_DATA ; select the current plane
\r
496 ;-- begin plane painting
\r
497 MOV AX, height ; start the row counter
\r
498 MOV rowCounter, AX ;
\r
499 MOV DI, poffset ; go to the first pixel
\r
500 MOV SI, bmpOffset ; go to the bmp pixel
\r
502 MOV CX, width ; count the columns
\r
504 MOVSB ; copy the pixel
\r
505 SUB CX, 3 ; we skip the next 3
\r
506 ADD SI, 3 ; skip the bmp pixels
\r
507 LOOP SCAN_LOOP ; finish the scan
\r
509 MOV AX, nextPageRow
\r
510 ADD DI, AX ; go to the next row on screen
\r
512 ADD SI, AX ; go to the next row on bmp
\r
515 JNZ ROW_LOOP ; do all the rows
\r
516 ;-- end plane painting
\r
518 MOV AL, plane ; advance to the next plane
\r
520 AND AL, 0x0f ; mask the plane properly
\r
521 MOV plane, AL ; store the plane
\r
523 INC bmpOffset ; start bmp at the right spot
\r
526 JNZ PLANE_LOOP ; do all 4 planes
\r
531 modexDrawPlanarBuf(page_t *page, int x, int y, planar_buf_t *bmp) {
\r
532 /* TODO - adapt from test code */
\r
534 for(plane=0; plane < 4; plane++)
\r
542 modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp) {
\r
543 /* draw the whole sprite */
\r
544 modexDrawSpriteRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
548 modexDrawSpriteRegion(page_t *page, int x, int y,
\r
549 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
550 word poffset = (word)page->data + y*(page->width/4) + x/4;
\r
551 byte *data = bmp->data;//+bmp->offset;
\r
552 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
555 byte plane = 1 << ((byte) x & 0x03);
\r
556 word scanCount = width/4 + (width%4 ? 1 :0);
\r
557 word nextPageRow = page->width/4 - scanCount;
\r
558 word nextBmpRow = (word) bmp->width - width;
\r
560 byte planeCounter = 4;
\r
563 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
566 MOV DX, SC_INDEX ; point at the map mask register
\r
571 MOV DX, SC_DATA ; select the current plane
\r
575 ;-- begin plane painting
\r
576 MOV AX, height ; start the row counter
\r
577 MOV rowCounter, AX ;
\r
578 MOV DI, poffset ; go to the first pixel
\r
579 MOV SI, bmpOffset ; go to the bmp pixel
\r
581 MOV CX, width ; count the columns
\r
586 JNE DRAW_PIXEL ; draw non-zero pixels
\r
588 INC DI ; skip the transparent pixel
\r
592 MOVSB ; copy the pixel
\r
594 SUB CX, 3 ; we skip the next 3
\r
595 ADD SI, 3 ; skip the bmp pixels
\r
596 LOOP SCAN_LOOP ; finish the scan
\r
598 MOV AX, nextPageRow
\r
599 ADD DI, AX ; go to the next row on screen
\r
601 ADD SI, AX ; go to the next row on bmp
\r
604 JNZ ROW_LOOP ; do all the rows
\r
605 ;-- end plane painting
\r
607 MOV AL, plane ; advance to the next plane
\r
609 AND AL, 0x0f ; mask the plane properly
\r
610 MOV plane, AL ; store the plane
\r
612 INC bmpOffset ; start bmp at the right spot
\r
615 JNZ PLANE_LOOP ; do all 4 planes
\r
620 /* copy a region of video memory from one page to another.
\r
621 * It assumes that the left edge of the tile is the same on both
\r
622 * regions and the memory areas do not overlap.
\r
625 modexCopyPageRegion(page_t *dest, page_t *src,
\r
628 word width, word height)
\r
630 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
631 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
632 word scans = width/4;
\r
633 word nextSrcRow = src->width/4 - scans - 1;
\r
634 word nextDestRow = dest->width/4 - scans - 1;
\r
635 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
636 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
637 byte left = lclip[sx&0x03];
\r
638 byte right = rclip[(sx+width)&0x03];
\r
641 MOV AX, SCREEN_SEG ; work in the vga space
\r
646 MOV DX, GC_INDEX ; turn off cpu bits
\r
650 MOV AX, SC_INDEX ; point to the mask register
\r
660 MOV CX, scans ; the number of latches
\r
662 MOV AL, left ; do the left column
\r
667 MOV AL, 0fh ; do the inner columns
\r
669 REP MOVSB ; copy the pixels
\r
671 MOV AL, right ; do the right column
\r
676 MOV AX, SI ; go the start of the next row
\r
677 ADD AX, nextSrcRow ;
\r
680 ADD AX, nextDestRow ;
\r
683 DEC height ; do the rest of the actions
\r
686 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
687 MOV AL, 0ffh ; none from latches
\r
693 /* fade and flash */
\r
695 modexFadeOn(word fade, byte *palette) {
\r
696 fadePalette(-fade, 64, 64/fade+1, palette);
\r
701 modexFadeOff(word fade, byte *palette) {
\r
702 fadePalette(fade, 0, 64/fade+1, palette);
\r
707 modexFlashOn(word fade, byte *palette) {
\r
708 fadePalette(fade, -64, 64/fade+1, palette);
\r
713 modexFlashOff(word fade, byte *palette) {
\r
714 fadePalette(-fade, 0, 64/fade+1, palette);
\r
719 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
723 /* handle the case where we just update */
\r
725 modexPalUpdate1(palette);
\r
729 while(iter > 0) { /* FadeLoop */
\r
730 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
731 tmppal[i] = palette[i] - dim;
\r
732 if(tmppal[i] > 127) {
\r
734 } else if(tmppal[i] > 63) {
\r
738 modexPalUpdate1(tmppal);
\r
745 /* save and load */
\r
747 modexPalSave(byte *palette) {
\r
750 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
751 for(i=0; i<PAL_SIZE; i++) {
\r
752 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
760 ptr = malloc(PAL_SIZE);
\r
762 /* handle errors */
\r
764 printf("Could not allocate palette.\n");
\r
773 modexLoadPalFile(byte *filename, byte **palette) {
\r
777 /* free the palette if it exists */
\r
782 /* allocate the new palette */
\r
783 *palette = modexNewPal();
\r
785 /* open the file */
\r
786 file = fopen(filename, "rb");
\r
788 printf("Could not open palette file: %s\n", filename);
\r
792 /* read the file */
\r
794 while(!feof(file)) {
\r
795 *ptr++ = fgetc(file);
\r
803 modexSavePalFile(char *filename, byte *pal) {
\r
807 /* open the file for writing */
\r
808 file = fopen(filename, "wb");
\r
810 printf("Could not open %s for writing\n", filename);
\r
814 /* write the data to the file */
\r
815 fwrite(pal, 1, PAL_SIZE, file);
\r
823 fadePalette(-1, 64, 1, tmppal);
\r
829 fadePalette(-1, -64, 1, tmppal);
\r
835 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
837 byte *p = bmp->palette;
\r
841 static word a[PAL_SIZE]; //palette array of change values!
\r
842 word z=0, aq=0, aa=0, pp=0;
\r
847 memset(a, -1, sizeof(a));
\r
848 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
858 // printf("q: %02d\n", (q));
\r
859 // printf("qq: %02d\n", (qq));
\r
860 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
861 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
863 if((*i)<PAL_SIZE/2 && w==0)
\r
865 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
867 //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
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(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
886 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
887 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
888 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
891 //if(qp>0) printf("qp=%d\n", qp);
\r
892 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
894 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
895 if((*i)>=PAL_SIZE/2 && w==0)
\r
897 for(; (*i)<PAL_SIZE; (*i)++)
\r
899 //____ 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
900 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
905 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
907 //printf("qp=%d\n", qp);
\r
908 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
909 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
910 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
911 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
915 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
916 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
917 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
920 //printf(" (*i)=%d\n", (*i)/3);
\r
923 printf("\nqqqqqqqq\n\n");
\r
929 long bufSize = (bmp->width * bmp->height);
\r
931 //printf("1(*i)=%02d\n", (*i)/3);
\r
932 //printf("1z=%02d\n", z/3);
\r
933 chkcolor(bmp, &q, &a, &aa, &z, i);
\r
934 //printf("2(*i)=%02d\n", (*i)/3);
\r
935 //printf("2z=%02d\n", z/3);
\r
940 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
941 if(a[aq]==-1) aq++;
\r
942 else { aqoffset++; break; }
\r
944 //update the image data here!
\r
945 for(lq=0; lq<bufSize; lq++)
\r
949 use a[qp] instead of bmp->offset for this spot!
\r
954 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
957 //(offset/bmp->offset)*bmp->offset
\r
960 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
961 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
962 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
963 /*if(bmp->data[lq]+bmp->offset==aq)
\r
965 //printf("%02d", bmp->data[lq]);
\r
966 //printf("\n%02d\n", bmp->offset);
\r
967 printf("aq=%02d ", aq);
\r
968 printf("a[aq]=%02d ", a[aq]);
\r
969 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
970 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
971 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
972 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
973 // printf("_%d ", bmp->data[lq]);
\r
974 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
976 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
978 if(bmp->data[lq]+bmp->offset >= aq)
\r
980 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
981 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
983 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
986 //printf("%02d`", bmp->data[lq]);
\r
987 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
990 //printf(" aq=%02d\n", aq);
\r
991 //printf(" aa=%02d\n", aa);
\r
993 //update the palette~
\r
994 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
997 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
1002 modexPalUpdate1(byte *p)
\r
1005 modexWaitBorder();
\r
1006 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
1007 for(i=0; i<PAL_SIZE/2; i++)
\r
1009 outp(PAL_DATA_REG, p[i]);
\r
1011 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
1012 for(; i<PAL_SIZE; i++)
\r
1014 outp(PAL_DATA_REG, p[(i)]);
\r
1019 modexPalUpdate0(byte *p)
\r
1022 modexWaitBorder();
\r
1023 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
1024 for(i=0; i<PAL_SIZE/2; i++)
\r
1026 outp(PAL_DATA_REG, rand());
\r
1028 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
1029 for(; i<PAL_SIZE; i++)
\r
1031 outp(PAL_DATA_REG, rand());
\r
1036 //i want to make another vesion that checks the palette when the palette is being appened~
\r
1037 void chkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
1041 pal = modexNewPal();
\r
1042 modexPalSave(pal);
\r
1043 //printf("q: %02d\n", (*q));
\r
1044 printf("chkcolor start~\n");
\r
1045 printf("1 (*z): %d\n", (*z)/3);
\r
1046 printf("1 (*i): %d\n", (*i)/3);
\r
1047 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
1048 printf("wwwwwwwwwwwwwwww\n");
\r
1049 //check palette for dups
\r
1050 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
1052 //printf("\n z: %d\n", (*z));
\r
1053 //printf(" q: %d\n", (*q));
\r
1054 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
1057 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
1060 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1061 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
1065 else for(zz=0; zz<(*q); zz+=3)
\r
1067 //printf("zz: %02d\n", zz/3);
\r
1070 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
1074 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
1075 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
1078 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
1080 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
1081 // 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
1082 // 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
1083 // //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
1084 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1087 //expand dong here
\r
1089 planned features that i plan to implement~
\r
1090 image that has values on the pallete list!
\r
1092 no... wait.... no wwww
\r
1094 //for(zzii=0; zzii<3; zzii++)
\r
1096 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
1097 a[(((*z)+(*q)))]=zz;
\r
1099 (*aa)=(((*z)+(*q)));
\r
1100 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
1101 // printf("\n aa: %d\n\n", (*aa));
\r
1102 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
1103 // printf("wwwwwwwwwwwwwwww\n\n");
\r
1107 printf("================\n");
\r
1108 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
1109 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
1110 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1111 printf("================\n");
\r
1113 //printf("[%d]", (zz+q));
\r
1117 printf("wwwwwwwwwwwwwwww\n");
\r
1118 printf("2 (*z): %d\n", (*z)/3);
\r
1119 printf("2 (*i): %d\n", (*i)/3);
\r
1120 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
1121 printf("chkcolor end~\n");
\r
1125 void modexputPixel(page_t *page, int x, int y, byte color)
\r
1127 word pageOff = (word) page->data;
\r
1128 /* Each address accesses four neighboring pixels, so set
\r
1129 Write Plane Enable according to which pixel we want
\r
1130 to modify. The plane is determined by the two least
\r
1131 significant bits of the x-coordinate: */
\r
1132 modexSelectPlane(PLANE(x));
\r
1133 //outp(SC_INDEX, 0x02);
\r
1134 //outp(SC_DATA, 0x01 << (x & 3));
\r
1136 /* The offset of the pixel into the video segment is
\r
1137 offset = (width * y + x) / 4, and write the given
\r
1138 color to the plane we selected above. Heed the active
\r
1139 page start selection. */
\r
1140 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
1144 byte modexgetPixel(page_t *page, int x, int y)
\r
1146 word pageOff = (word) page->data;
\r
1147 /* Select the plane from which we must read the pixel color: */
\r
1148 outpw(GC_INDEX, 0x04);
\r
1149 outpw(GC_INDEX+1, x & 3);
\r
1151 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
1155 void modexhlin(page_t *page, word xl, word xh, word y, word color)
\r
1160 for(x=0;x<xh*4;x+=4)
\r
1162 if(x+4>=page[0].sw-1){ x=0; yy+=4; }
\r
1163 modexClearRegion(page, x+xl, y+yy, 4, 4, color);
\r
1165 //modexputPixel(page, x+xl, y, color);
\r
1168 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1170 word i, s, o, w, j, xp;
\r
1172 word addr = (word) l;
\r
1196 s=romFonts[t].seg;
\r
1197 o=romFonts[t].off;
\r
1199 for(; *str != '\0'; str++)
\r
1202 if((c=='\n'/* || c=="\
\r
1210 //load the letter 'A'
\r
1216 MOV AL, c ; the letter
\r
1219 ADD SI, AX ;the address of charcter
\r
1228 for(i=0; i<w; i++)
\r
1234 modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1243 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1245 word i, s, o, w, j, xp;
\r
1247 word addr = (word) l;
\r
1271 s=romFonts[t].seg;
\r
1272 o=romFonts[t].off;
\r
1274 for(; *str != '\0'; str++)
\r
1277 if((c=='\n'/* || c=="\
\r
1278 "*/)/* || chw>=page->width*/)
\r
1284 //load the letter 'A'
\r
1290 MOV AL, c ; the letter
\r
1293 ADD SI, AX ;the address of charcter
\r
1302 for(i=0; i<w; i++)
\r
1308 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1309 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1318 /* palette dump on display! */
\r
1319 void pdump(page_t *pee)
\r
1321 int mult=(QUADWH);
\r
1322 int palq=(mult)*TILEWH;
\r
1325 for(paly=0; paly<palq; paly+=mult){
\r
1326 for(palx=0; palx<palq; palx+=mult){
\r
1327 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
\r
1333 /////////////////////////////////////////////////////////////////////////////
\r
1335 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1336 // the Virtual screen. //
\r
1338 /////////////////////////////////////////////////////////////////////////////
\r
1339 void cls(page_t *page, byte color, byte *Where)
\r
1341 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1342 /* set map mask to all 4 planes */
\r
1343 outpw(SC_INDEX, 0xff02);
\r
1344 //_fmemset(VGA, color, 16000);
\r
1345 _fmemset(Where, color, page->width*(page->height));
\r
1349 modexWaitBorder() {
\r
1350 while(inp(INPUT_STATUS_1) & 8) {
\r
1354 while(!(inp(INPUT_STATUS_1) & 8)) {
\r