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 CRTParmCount = sizeof(ModeX_256x192regs) / sizeof(ModeX_256x192regs[0]);
\r
136 /* width and height */
\r
137 gv->video.page[0].sw=256;
\r
138 gv->video.page[0].sh=192;
\r
140 /* send the CRTParms */
\r
141 for(i=0; i<CRTParmCount; i++) {
\r
142 outpw(CRTC_INDEX, ModeX_256x192regs[i]);
\r
145 /* clear video memory */
\r
146 outpw(SC_INDEX, 0x0f02);
\r
147 for(i=0; i<0x8000; i++) {
\r
152 gv->video.page[0].tilesw = gv->video.page[0].sw/TILEWH;
\r
153 gv->video.page[0].tilesh = gv->video.page[0].sh/TILEWH;
\r
154 //TODO MAKE FLEXIBLE~
\r
155 gv->video.page[0].tilemidposscreenx = gv->video.page[0].tilesw;
\r
156 gv->video.page[0].tilemidposscreeny = (gv->video.page[0].tilesh/2)+1;
\r
157 #define PAGE_SIZE (word)(gv->video.page[0].sw/4 * gv->video.page[0].sh)
\r
162 /* TODO restore original mode and palette */
\r
163 vgaSetMode(TEXT_MODE);
\r
166 // setBaseXMode() does the initialization to make the VGA ready to
\r
167 // accept any combination of configuration register settings. This
\r
168 // involves enabling writes to index 0 to 7 of the CRT controller (port
\r
169 // 0x3D4), by clearing the most significant bit (bit 7) of index 0x11.
\r
171 modexsetBaseXMode(page_t *page)
\r
174 /* TODO save current video mode and palette */
\r
175 vgaSetMode(VGA_256_COLOR_MODE);
\r
177 /* disable chain4 mode */
\r
178 outpw(SC_INDEX, 0x0604);
\r
180 /* synchronous reset while setting Misc Output */
\r
181 outpw(SC_INDEX, 0x0100);
\r
183 /* select 25 MHz dot clock & 60 Hz scanning rate */
\r
184 outp(MISC_OUTPUT, 0xe3);
\r
186 /* undo reset (restart sequencer) */
\r
187 outpw(SC_INDEX, 0x0300);
\r
189 /* reprogram the CRT controller */
\r
190 outp(CRTC_INDEX, 0x11); /* VSync End reg contains register write prot */
\r
191 // temp = inp(CRTC_DATA) & 0x7F;
\r
192 // outp(CRTC_INDEX, 0x11);
\r
193 outp(CRTC_DATA, 0x7f); /* get current write protect on varios regs */
\r
194 // outp(CRTC_DATA, temp); /* get current write protect on varios regs */
\r
198 modexDefaultPage(page_t *p)
\r
202 /* default page values */
\r
208 page.width = p->sw;
\r
209 page.height = p->sh;
\r
210 page.tw = page.sw/TILEWH;
\r
211 page.th = page.sh/TILEWH;
\r
212 page.tilemidposscreenx = page.tw/2;
\r
213 page.tilemidposscreeny = (page.th/2)+1;
\r
214 //pageSize = p->sw*p->sh;
\r
220 /* returns the next page in contiguous memory
\r
221 * the next page will be the same size as p, by default
\r
224 modexNextPage(page_t *p) {
\r
227 result.data = p->data + (p->width/4)*p->height;
\r
230 result.width = p->width;
\r
231 result.height = p->height;
\r
232 result.tw = p->width/TILEWH;
\r
233 result.th = p->height/TILEWH;
\r
234 result.id = p->id+1;
\r
237 // return modexNextPageFlexibleSize(&p, p->width, p->height);
\r
240 //next page with defined dimentions~
\r
242 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
246 result.data = p->data + (p->width/4)*p->height; /* compute the offset */
\r
251 result.tw = p->width/TILEWH;
\r
252 result.th = p->height/TILEWH;
\r
253 result.id = p->id+1;
\r
260 modexShowPage(page_t *page) {
\r
266 /* calculate offset */
\r
267 offset = (word) page->data;
\r
268 offset += page->dy * (page->width >> 2 );
\r
269 offset += page->dx >> 2;
\r
271 /* calculate crtcOffset according to virtual width */
\r
272 crtcOffset = page->width >> 3;
\r
274 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
275 low_address = LOW_ADDRESS | (offset << 8);
\r
277 /* wait for appropriate timing and then program CRTC */
\r
278 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
279 outpw(CRTC_INDEX, high_address);
\r
280 outpw(CRTC_INDEX, low_address);
\r
281 outp(CRTC_INDEX, 0x13);
\r
282 outp(CRTC_DATA, crtcOffset);
\r
284 /* wait for one retrace */
\r
285 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
287 /* do PEL panning here */
\r
288 outp(AC_INDEX, 0x33);
\r
289 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
294 modexPanPage(page_t *page, int dx, int dy) {
\r
301 modexSelectPlane(byte plane) {
\r
302 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
303 outp(SC_DATA, plane);
\r
308 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
309 word pageOff = (word) page->data;
\r
310 word xoff=x/4; /* xoffset that begins each row */
\r
311 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
312 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
313 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
314 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
315 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
316 byte left = lclip[x&0x03];
\r
317 byte right = rclip[(x+w)&0x03];
\r
319 /* handle the case which requires an extra group */
\r
320 if((x & 0x03) && !((x+w) & 0x03)) {
\r
325 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
327 MOV DI, poffset ; go to the first pixel
\r
328 MOV DX, SC_INDEX ; point to the map mask
\r
332 MOV AL, color ; get ready to write colors
\r
334 MOV CX, scanCount ; count the line
\r
335 MOV BL, AL ; remember color
\r
336 MOV AL, left ; do the left clip
\r
337 OUT DX, AL ; set the left clip
\r
338 MOV AL, BL ; restore color
\r
339 STOSB ; write the color
\r
341 JZ SCAN_DONE ; handle 1 group stuff
\r
343 ;-- write the main body of the scanline
\r
344 MOV BL, AL ; remember color
\r
345 MOV AL, 0x0f ; write to all pixels
\r
347 MOV AL, BL ; restore color
\r
348 REP STOSB ; write the color
\r
350 MOV BL, AL ; remeber color
\r
352 OUT DX, AL ; do the right clip
\r
353 MOV AL, BL ; restore color
\r
354 STOSB ; write pixel
\r
355 ADD DI, nextRow ; go to the next row
\r
363 oldDrawBmp(byte far* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
369 /* TODO Make this fast. It's SLOOOOOOW */
\r
370 for(plane=0; plane < 4; plane++) {
\r
371 modexSelectPlane(PLANE(plane+x));
\r
372 for(px = plane; px < bmp->width; px+=4) {
\r
374 for(py=0; py<bmp->height; py++) {
\r
375 if(!sprite || bmp->data[offset])
\r
376 page[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
377 offset+=bmp->width;
\r
384 CDrawBmp(byte far* vgamem, page_t* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
391 /* TODO Make this fast. It's SLOOOOOOW */
\r
392 for(plane=0; plane < 4; plane++) {
\r
393 modexSelectPlane(PLANE(plane+x));
\r
394 for(px = plane; px < bmp->width; px+=4) {
\r
396 for(py=0; py<bmp->height; py++) {
\r
397 if(!sprite || bmp->data[offset])
\r
398 //modexputPixel(page, x+px, y+py, bmp->data[offset]);
\r
399 vgamem[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
400 offset+=bmp->width;
\r
407 modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) {
\r
408 /* draw the region (the entire freakin bitmap) */
\r
409 modexDrawBmpRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
414 modexDrawBmpRegion(page_t *page, int x, int y,
\r
415 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
416 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
417 byte far *data = bmp->data;//+bmp->offset;
\r
418 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
421 byte plane = 1 << ((byte) x & 0x03);
\r
422 word scanCount = width/4 + (width%4 ? 1 :0);
\r
423 word nextPageRow = page->width/4 - scanCount;
\r
424 word nextBmpRow = (word) bmp->width - width;
\r
426 byte planeCounter = 4;
\r
428 /* printf("bmp->data=%Fp\n",bmp->data);
\r
429 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
430 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
432 //code is a bit slow here
\r
434 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
437 MOV DX, SC_INDEX ; point at the map mask register
\r
442 MOV DX, SC_DATA ; select the current plane
\r
446 ;-- begin plane painting
\r
447 MOV AX, height ; start the row counter
\r
448 MOV rowCounter, AX ;
\r
449 MOV DI, poffset ; go to the first pixel
\r
450 MOV SI, bmpOffset ; go to the bmp pixel
\r
452 MOV CX, width ; count the columns
\r
454 MOVSB ; copy the pixel
\r
455 SUB CX, 3 ; we skip the next 3
\r
456 ADD SI, 3 ; skip the bmp pixels
\r
457 LOOP SCAN_LOOP ; finish the scan
\r
459 MOV AX, nextPageRow
\r
460 ADD DI, AX ; go to the next row on screen
\r
462 ADD SI, AX ; go to the next row on bmp
\r
465 JNZ ROW_LOOP ; do all the rows
\r
466 ;-- end plane painting
\r
468 MOV AL, plane ; advance to the next plane
\r
470 AND AL, 0x0f ; mask the plane properly
\r
471 MOV plane, AL ; store the plane
\r
473 INC bmpOffset ; start bmp at the right spot
\r
476 JNZ PLANE_LOOP ; do all 4 planes
\r
481 modex_sparky4_DrawBmpRegion(page_t *page, int x, int y,
\r
482 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
483 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
484 byte far *data = bmp->data;//+bmp->offset;
\r
485 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
488 byte plane = 1 << ((byte) x & 0x03);
\r
489 word scanCount = width/4 + (width%4 ? 1 :0);
\r
490 word nextPageRow = page->width/4 - scanCount;
\r
491 word nextBmpRow = (word) bmp->width - width;
\r
493 byte planeCounter = 4;
\r
495 /* printf("bmp->data=%Fp\n",bmp->data);
\r
496 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
497 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
499 //code is a bit slow here
\r
501 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
504 MOV DX, SC_INDEX ; point at the map mask register
\r
509 MOV DX, SC_DATA ; select the current plane
\r
513 ;-- begin plane painting
\r
514 MOV AX, height ; start the row counter
\r
515 MOV rowCounter, AX ;
\r
516 MOV DI, poffset ; go to the first pixel
\r
517 MOV SI, bmpOffset ; go to the bmp pixel
\r
519 MOV CX, width ; count the columns
\r
521 MOVSB ; copy the pixel
\r
522 SUB CX, 3 ; we skip the next 3
\r
523 ADD SI, 3 ; skip the bmp pixels
\r
524 LOOP SCAN_LOOP ; finish the scan
\r
526 MOV AX, nextPageRow
\r
527 ADD DI, AX ; go to the next row on screen
\r
529 ADD SI, AX ; go to the next row on bmp
\r
532 JNZ ROW_LOOP ; do all the rows
\r
533 ;-- end plane painting
\r
535 MOV AL, plane ; advance to the next plane
\r
537 AND AL, 0x0f ; mask the plane properly
\r
538 MOV plane, AL ; store the plane
\r
540 INC bmpOffset ; start bmp at the right spot
\r
543 JNZ PLANE_LOOP ; do all 4 planes
\r
548 modexDrawPlanarBuf(page_t *page, int x, int y, planar_buf_t *bmp) {
\r
549 /* TODO - adapt from test code */
\r
551 for(plane=0; plane < 4; plane++)
\r
559 modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp) {
\r
560 /* draw the whole sprite */
\r
561 modexDrawSpriteRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
565 modexDrawSpriteRegion(page_t *page, int x, int y,
\r
566 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
567 word poffset = (word)page->data + y*(page->width/4) + x/4;
\r
568 byte *data = bmp->data;//+bmp->offset;
\r
569 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
572 byte plane = 1 << ((byte) x & 0x03);
\r
573 word scanCount = width/4 + (width%4 ? 1 :0);
\r
574 word nextPageRow = page->width/4 - scanCount;
\r
575 word nextBmpRow = (word) bmp->width - width;
\r
577 byte planeCounter = 4;
\r
580 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
583 MOV DX, SC_INDEX ; point at the map mask register
\r
588 MOV DX, SC_DATA ; select the current plane
\r
592 ;-- begin plane painting
\r
593 MOV AX, height ; start the row counter
\r
594 MOV rowCounter, AX ;
\r
595 MOV DI, poffset ; go to the first pixel
\r
596 MOV SI, bmpOffset ; go to the bmp pixel
\r
598 MOV CX, width ; count the columns
\r
603 JNE DRAW_PIXEL ; draw non-zero pixels
\r
605 INC DI ; skip the transparent pixel
\r
609 MOVSB ; copy the pixel
\r
611 SUB CX, 3 ; we skip the next 3
\r
612 ADD SI, 3 ; skip the bmp pixels
\r
613 LOOP SCAN_LOOP ; finish the scan
\r
615 MOV AX, nextPageRow
\r
616 ADD DI, AX ; go to the next row on screen
\r
618 ADD SI, AX ; go to the next row on bmp
\r
621 JNZ ROW_LOOP ; do all the rows
\r
622 ;-- end plane painting
\r
624 MOV AL, plane ; advance to the next plane
\r
626 AND AL, 0x0f ; mask the plane properly
\r
627 MOV plane, AL ; store the plane
\r
629 INC bmpOffset ; start bmp at the right spot
\r
632 JNZ PLANE_LOOP ; do all 4 planes
\r
637 /* copy a region of video memory from one page to another.
\r
638 * It assumes that the left edge of the tile is the same on both
\r
639 * regions and the memory areas do not overlap.
\r
642 modexCopyPageRegion(page_t *dest, page_t *src,
\r
645 word width, word height)
\r
647 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
648 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
649 word scans = width/4;
\r
650 word nextSrcRow = src->width/4 - scans - 1;
\r
651 word nextDestRow = dest->width/4 - scans - 1;
\r
652 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
653 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
654 byte left = lclip[sx&0x03];
\r
655 byte right = rclip[(sx+width)&0x03];
\r
658 MOV AX, SCREEN_SEG ; work in the vga space
\r
663 MOV DX, GC_INDEX ; turn off cpu bits
\r
667 MOV AX, SC_INDEX ; point to the mask register
\r
677 MOV CX, scans ; the number of latches
\r
679 MOV AL, left ; do the left column
\r
684 MOV AL, 0fh ; do the inner columns
\r
686 REP MOVSB ; copy the pixels
\r
688 MOV AL, right ; do the right column
\r
693 MOV AX, SI ; go the start of the next row
\r
694 ADD AX, nextSrcRow ;
\r
697 ADD AX, nextDestRow ;
\r
700 DEC height ; do the rest of the actions
\r
703 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
704 MOV AL, 0ffh ; none from latches
\r
710 /* fade and flash */
\r
712 modexFadeOn(word fade, byte *palette) {
\r
713 fadePalette(-fade, 64, 64/fade+1, palette);
\r
718 modexFadeOff(word fade, byte *palette) {
\r
719 fadePalette(fade, 0, 64/fade+1, palette);
\r
724 modexFlashOn(word fade, byte *palette) {
\r
725 fadePalette(fade, -64, 64/fade+1, palette);
\r
730 modexFlashOff(word fade, byte *palette) {
\r
731 fadePalette(-fade, 0, 64/fade+1, palette);
\r
736 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
740 /* handle the case where we just update */
\r
742 modexPalUpdate1(palette);
\r
746 while(iter > 0) { /* FadeLoop */
\r
747 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
748 tmppal[i] = palette[i] - dim;
\r
749 if(tmppal[i] > 127) {
\r
751 } else if(tmppal[i] > 63) {
\r
755 modexPalUpdate1(tmppal);
\r
762 /* save and load */
\r
764 modexPalSave(byte *palette) {
\r
767 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
768 for(i=0; i<PAL_SIZE; i++) {
\r
769 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
777 ptr = malloc(PAL_SIZE);
\r
779 /* handle errors */
\r
781 printf("Could not allocate palette.\n");
\r
790 modexLoadPalFile(byte *filename, byte **palette) {
\r
794 /* free the palette if it exists */
\r
799 /* allocate the new palette */
\r
800 *palette = modexNewPal();
\r
802 /* open the file */
\r
803 file = fopen(filename, "rb");
\r
805 printf("Could not open palette file: %s\n", filename);
\r
809 /* read the file */
\r
811 while(!feof(file)) {
\r
812 *ptr++ = fgetc(file);
\r
820 modexSavePalFile(char *filename, byte *pal) {
\r
824 /* open the file for writing */
\r
825 file = fopen(filename, "wb");
\r
827 printf("Could not open %s for writing\n", filename);
\r
831 /* write the data to the file */
\r
832 fwrite(pal, 1, PAL_SIZE, file);
\r
840 fadePalette(-1, 64, 1, tmppal);
\r
846 fadePalette(-1, -64, 1, tmppal);
\r
852 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
854 byte *p = bmp->palette;
\r
858 static word a[PAL_SIZE]; //palette array of change values!
\r
859 word z=0, aq=0, aa=0, pp=0;
\r
864 memset(a, -1, sizeof(a));
\r
865 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
875 // printf("q: %02d\n", (q));
\r
876 // printf("qq: %02d\n", (qq));
\r
877 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
878 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
880 if((*i)<PAL_SIZE/2 && w==0)
\r
882 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
884 //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
885 //____ 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
886 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
891 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
893 //printf("qp=%d\n", qp);
\r
894 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
895 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
896 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
897 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
901 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
903 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
904 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
905 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
908 //if(qp>0) printf("qp=%d\n", qp);
\r
909 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
911 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
912 if((*i)>=PAL_SIZE/2 && w==0)
\r
914 for(; (*i)<PAL_SIZE; (*i)++)
\r
916 //____ 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
917 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
922 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
924 //printf("qp=%d\n", qp);
\r
925 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
926 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
927 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
928 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
932 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
933 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
934 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
937 //printf(" (*i)=%d\n", (*i)/3);
\r
940 printf("\nqqqqqqqq\n\n");
\r
946 long bufSize = (bmp->width * bmp->height);
\r
948 //printf("1(*i)=%02d\n", (*i)/3);
\r
949 //printf("1z=%02d\n", z/3);
\r
950 chkcolor(bmp, &q, &a, &aa, &z, i);
\r
951 //printf("2(*i)=%02d\n", (*i)/3);
\r
952 //printf("2z=%02d\n", z/3);
\r
957 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
958 if(a[aq]==-1) aq++;
\r
959 else { aqoffset++; break; }
\r
961 //update the image data here!
\r
962 for(lq=0; lq<bufSize; lq++)
\r
966 use a[qp] instead of bmp->offset for this spot!
\r
971 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
974 //(offset/bmp->offset)*bmp->offset
\r
977 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
978 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
979 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
980 /*if(bmp->data[lq]+bmp->offset==aq)
\r
982 //printf("%02d", bmp->data[lq]);
\r
983 //printf("\n%02d\n", bmp->offset);
\r
984 printf("aq=%02d ", aq);
\r
985 printf("a[aq]=%02d ", a[aq]);
\r
986 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
987 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
988 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
989 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
990 // printf("_%d ", bmp->data[lq]);
\r
991 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
993 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
995 if(bmp->data[lq]+bmp->offset >= aq)
\r
997 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
998 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
1000 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
1003 //printf("%02d`", bmp->data[lq]);
\r
1004 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
1007 //printf(" aq=%02d\n", aq);
\r
1008 //printf(" aa=%02d\n", aa);
\r
1010 //update the palette~
\r
1011 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
1014 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
1019 modexPalUpdate1(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, p[i]);
\r
1028 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
1029 for(; i<PAL_SIZE; i++)
\r
1031 outp(PAL_DATA_REG, p[(i)]);
\r
1036 modexPalUpdate0(byte *p)
\r
1039 modexWaitBorder();
\r
1040 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
1041 for(i=0; i<PAL_SIZE/2; i++)
\r
1043 outp(PAL_DATA_REG, rand());
\r
1045 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
1046 for(; i<PAL_SIZE; i++)
\r
1048 outp(PAL_DATA_REG, rand());
\r
1053 //i want to make another vesion that checks the palette when the palette is being appened~
\r
1054 void chkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
1058 pal = modexNewPal();
\r
1059 modexPalSave(pal);
\r
1060 //printf("q: %02d\n", (*q));
\r
1061 printf("chkcolor start~\n");
\r
1062 printf("1 (*z): %d\n", (*z)/3);
\r
1063 printf("1 (*i): %d\n", (*i)/3);
\r
1064 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
1065 printf("wwwwwwwwwwwwwwww\n");
\r
1066 //check palette for dups
\r
1067 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
1069 //printf("\n z: %d\n", (*z));
\r
1070 //printf(" q: %d\n", (*q));
\r
1071 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
1074 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
1077 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1078 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
1082 else for(zz=0; zz<(*q); zz+=3)
\r
1084 //printf("zz: %02d\n", zz/3);
\r
1087 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
1091 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
1092 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
1095 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
1097 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
1098 // 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
1099 // 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
1100 // //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
1101 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1104 //expand dong here
\r
1106 planned features that i plan to implement~
\r
1107 image that has values on the pallete list!
\r
1109 no... wait.... no wwww
\r
1111 //for(zzii=0; zzii<3; zzii++)
\r
1113 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
1114 a[(((*z)+(*q)))]=zz;
\r
1116 (*aa)=(((*z)+(*q)));
\r
1117 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
1118 // printf("\n aa: %d\n\n", (*aa));
\r
1119 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
1120 // printf("wwwwwwwwwwwwwwww\n\n");
\r
1124 printf("================\n");
\r
1125 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
1126 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
1127 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1128 printf("================\n");
\r
1130 //printf("[%d]", (zz+q));
\r
1134 printf("wwwwwwwwwwwwwwww\n");
\r
1135 printf("2 (*z): %d\n", (*z)/3);
\r
1136 printf("2 (*i): %d\n", (*i)/3);
\r
1137 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
1138 printf("chkcolor end~\n");
\r
1142 void modexputPixel(page_t *page, int x, int y, byte color)
\r
1144 word pageOff = (word) page->data;
\r
1145 /* Each address accesses four neighboring pixels, so set
\r
1146 Write Plane Enable according to which pixel we want
\r
1147 to modify. The plane is determined by the two least
\r
1148 significant bits of the x-coordinate: */
\r
1149 modexSelectPlane(PLANE(x));
\r
1150 //outp(SC_INDEX, 0x02);
\r
1151 //outp(SC_DATA, 0x01 << (x & 3));
\r
1153 /* The offset of the pixel into the video segment is
\r
1154 offset = (width * y + x) / 4, and write the given
\r
1155 color to the plane we selected above. Heed the active
\r
1156 page start selection. */
\r
1157 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
1161 byte modexgetPixel(page_t *page, int x, int y)
\r
1163 word pageOff = (word) page->data;
\r
1164 /* Select the plane from which we must read the pixel color: */
\r
1165 outpw(GC_INDEX, 0x04);
\r
1166 outpw(GC_INDEX+1, x & 3);
\r
1168 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
1172 void modexhlin(page_t *page, word xl, word xh, word y, word color)
\r
1177 for(x=0;x<xh*4;x+=4)
\r
1179 if(x+4>=page[0].sw-1){ x=0; yy+=4; }
\r
1180 modexClearRegion(page, x+xl, y+yy, 4, 4, color);
\r
1182 //modexputPixel(page, x+xl, y, color);
\r
1185 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1187 word i, s, o, w, j, xp;
\r
1189 word addr = (word) l;
\r
1213 s=romFonts[t].seg;
\r
1214 o=romFonts[t].off;
\r
1216 for(; *str != '\0'; str++)
\r
1219 if((c=='\n'/* || c=="\
\r
1227 //load the letter 'A'
\r
1233 MOV AL, c ; the letter
\r
1236 ADD SI, AX ;the address of charcter
\r
1245 for(i=0; i<w; i++)
\r
1251 modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1260 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1262 word i, s, o, w, j, xp;
\r
1264 word addr = (word) l;
\r
1288 s=romFonts[t].seg;
\r
1289 o=romFonts[t].off;
\r
1291 for(; *str != '\0'; str++)
\r
1294 if((c=='\n'/* || c=="\
\r
1295 "*/)/* || chw>=page->width*/)
\r
1301 //load the letter 'A'
\r
1307 MOV AL, c ; the letter
\r
1310 ADD SI, AX ;the address of charcter
\r
1319 for(i=0; i<w; i++)
\r
1325 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1326 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1335 /* palette dump on display! */
\r
1336 void pdump(page_t *pee)
\r
1338 int mult=(QUADWH);
\r
1339 int palq=(mult)*TILEWH;
\r
1342 for(paly=0; paly<palq; paly+=mult){
\r
1343 for(palx=0; palx<palq; palx+=mult){
\r
1344 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
\r
1350 /////////////////////////////////////////////////////////////////////////////
\r
1352 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1353 // the Virtual screen. //
\r
1355 /////////////////////////////////////////////////////////////////////////////
\r
1356 void cls(page_t *page, byte color, byte *Where)
\r
1358 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1359 /* set map mask to all 4 planes */
\r
1360 outpw(SC_INDEX, 0xff02);
\r
1361 //_fmemset(VGA, color, 16000);
\r
1362 _fmemset(Where, color, page->width*(page->height));
\r
1366 modexWaitBorder() {
\r
1367 while(inp(INPUT_STATUS_1) & 8) {
\r
1371 while(!(inp(INPUT_STATUS_1) & 8)) {
\r