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_320x200regs) / sizeof(ModeX_320x200regs[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_320x200regs[i]);
\r
145 /* clear video memory */
\r
146 outpw(SC_INDEX, 0x0f02);
\r
147 for(i=0; i<0x8000; i++) {
\r
151 CRTParmCount = sizeof(ModeX_256x192regs) / sizeof(ModeX_256x192regs[0]);
\r
152 /* width and height */
\r
153 gv->video.page[0].sw=256;
\r
154 gv->video.page[0].sh=192;
\r
156 /* send the CRTParms */
\r
157 for(i=0; i<CRTParmCount; i++) {
\r
158 outpw(CRTC_INDEX, ModeX_256x192regs[i]);
\r
161 /* clear video memory */
\r
162 outpw(SC_INDEX, 0x0f02);
\r
163 for(i=0; i<0x8000; i++) {
\r
168 gv->video.page[0].tilesw = gv->video.page[0].sw/TILEWH;
\r
169 gv->video.page[0].tilesh = gv->video.page[0].sh/TILEWH;
\r
170 //TODO MAKE FLEXIBLE~
\r
171 gv->video.page[0].tilemidposscreenx = gv->video.page[0].tilesw;
\r
172 gv->video.page[0].tilemidposscreeny = (gv->video.page[0].tilesh/2)+1;
\r
173 #define PAGE_SIZE (word)(gv->video.page[0].sw/4 * gv->video.page[0].sh)
\r
178 /* TODO restore original mode and palette */
\r
179 vgaSetMode(TEXT_MODE);
\r
182 // setBaseXMode() does the initialization to make the VGA ready to
\r
183 // accept any combination of configuration register settings. This
\r
184 // involves enabling writes to index 0 to 7 of the CRT controller (port
\r
185 // 0x3D4), by clearing the most significant bit (bit 7) of index 0x11.
\r
187 modexsetBaseXMode(page_t *page)
\r
190 /* TODO save current video mode and palette */
\r
191 vgaSetMode(VGA_256_COLOR_MODE);
\r
193 /* disable chain4 mode */
\r
194 outpw(SC_INDEX, 0x0604);
\r
196 /* synchronous reset while setting Misc Output */
\r
197 outpw(SC_INDEX, 0x0100);
\r
199 /* select 25 MHz dot clock & 60 Hz scanning rate */
\r
200 outp(MISC_OUTPUT, 0xe3);
\r
202 /* undo reset (restart sequencer) */
\r
203 outpw(SC_INDEX, 0x0300);
\r
205 /* reprogram the CRT controller */
\r
206 outp(CRTC_INDEX, 0x11); /* VSync End reg contains register write prot */
\r
207 // temp = inp(CRTC_DATA) & 0x7F;
\r
208 // outp(CRTC_INDEX, 0x11);
\r
209 outp(CRTC_DATA, 0x7f); /* get current write protect on varios regs */
\r
210 // outp(CRTC_DATA, temp); /* get current write protect on varios regs */
\r
214 modexDefaultPage(page_t *p)
\r
218 /* default page values */
\r
224 page.width = p->sw;
\r
225 page.height = p->sh;
\r
226 page.tw = page.sw/TILEWH;
\r
227 page.th = page.sh/TILEWH;
\r
228 page.tilemidposscreenx = page.tw/2;
\r
229 page.tilemidposscreeny = (page.th/2)+1;
\r
230 //pageSize = p->sw*p->sh;
\r
236 /* returns the next page in contiguous memory
\r
237 * the next page will be the same size as p, by default
\r
240 modexNextPage(page_t *p) {
\r
243 result.data = p->data + (p->width/4)*p->height;
\r
246 result.width = p->width;
\r
247 result.height = p->height;
\r
248 result.tw = p->width/TILEWH;
\r
249 result.th = p->height/TILEWH;
\r
250 result.id = p->id+1;
\r
253 // return modexNextPageFlexibleSize(&p, p->width, p->height);
\r
256 //next page with defined dimentions~
\r
258 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
262 result.data = p->data + (p->width/4)*p->height; /* compute the offset */
\r
267 result.tw = p->width/TILEWH;
\r
268 result.th = p->height/TILEWH;
\r
269 result.id = p->id+1;
\r
276 modexShowPage(page_t *page) {
\r
282 /* calculate offset */
\r
283 offset = (word) page->data;
\r
284 offset += page->dy * (page->width >> 2 );
\r
285 offset += page->dx >> 2;
\r
287 /* calculate crtcOffset according to virtual width */
\r
288 crtcOffset = page->width >> 3;
\r
290 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
291 low_address = LOW_ADDRESS | (offset << 8);
\r
293 /* wait for appropriate timing and then program CRTC */
\r
294 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
295 outpw(CRTC_INDEX, high_address);
\r
296 outpw(CRTC_INDEX, low_address);
\r
297 outp(CRTC_INDEX, 0x13);
\r
298 outp(CRTC_DATA, crtcOffset);
\r
300 /* wait for one retrace */
\r
301 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
303 /* do PEL panning here */
\r
304 outp(AC_INDEX, 0x33);
\r
305 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
310 modexPanPage(page_t *page, int dx, int dy) {
\r
317 modexSelectPlane(byte plane) {
\r
318 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
319 outp(SC_DATA, plane);
\r
324 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
325 word pageOff = (word) page->data;
\r
326 word xoff=x/4; /* xoffset that begins each row */
\r
327 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
328 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
329 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
330 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
331 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
332 byte left = lclip[x&0x03];
\r
333 byte right = rclip[(x+w)&0x03];
\r
335 /* handle the case which requires an extra group */
\r
336 if((x & 0x03) && !((x+w) & 0x03)) {
\r
341 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
343 MOV DI, poffset ; go to the first pixel
\r
344 MOV DX, SC_INDEX ; point to the map mask
\r
348 MOV AL, color ; get ready to write colors
\r
350 MOV CX, scanCount ; count the line
\r
351 MOV BL, AL ; remember color
\r
352 MOV AL, left ; do the left clip
\r
353 OUT DX, AL ; set the left clip
\r
354 MOV AL, BL ; restore color
\r
355 STOSB ; write the color
\r
357 JZ SCAN_DONE ; handle 1 group stuff
\r
359 ;-- write the main body of the scanline
\r
360 MOV BL, AL ; remember color
\r
361 MOV AL, 0x0f ; write to all pixels
\r
363 MOV AL, BL ; restore color
\r
364 REP STOSB ; write the color
\r
366 MOV BL, AL ; remeber color
\r
368 OUT DX, AL ; do the right clip
\r
369 MOV AL, BL ; restore color
\r
370 STOSB ; write pixel
\r
371 ADD DI, nextRow ; go to the next row
\r
379 oldDrawBmp(byte far* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
385 /* TODO Make this fast. It's SLOOOOOOW */
\r
386 for(plane=0; plane < 4; plane++) {
\r
387 modexSelectPlane(PLANE(plane+x));
\r
388 for(px = plane; px < bmp->width; px+=4) {
\r
390 for(py=0; py<bmp->height; py++) {
\r
391 if(!sprite || bmp->data[offset])
\r
392 page[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
393 offset+=bmp->width;
\r
400 CDrawBmp(byte far* vgamem, page_t* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
407 /* TODO Make this fast. It's SLOOOOOOW */
\r
408 for(plane=0; plane < 4; plane++) {
\r
409 modexSelectPlane(PLANE(plane+x));
\r
410 for(px = plane; px < bmp->width; px+=4) {
\r
412 for(py=0; py<bmp->height; py++) {
\r
413 if(!sprite || bmp->data[offset])
\r
414 //modexputPixel(page, x+px, y+py, bmp->data[offset]);
\r
415 vgamem[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
416 offset+=bmp->width;
\r
423 modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) {
\r
424 /* draw the region (the entire freakin bitmap) */
\r
425 modexDrawBmpRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
430 modexDrawBmpRegion(page_t *page, int x, int y,
\r
431 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
432 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
433 byte far *data = bmp->data;//+bmp->offset;
\r
434 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
437 byte plane = 1 << ((byte) x & 0x03);
\r
438 word scanCount = width/4 + (width%4 ? 1 :0);
\r
439 word nextPageRow = page->width/4 - scanCount;
\r
440 word nextBmpRow = (word) bmp->width - width;
\r
442 byte planeCounter = 4;
\r
444 /* printf("bmp->data=%Fp\n",bmp->data);
\r
445 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
446 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
448 //code is a bit slow here
\r
450 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
453 MOV DX, SC_INDEX ; point at the map mask register
\r
458 MOV DX, SC_DATA ; select the current plane
\r
462 ;-- begin plane painting
\r
463 MOV AX, height ; start the row counter
\r
464 MOV rowCounter, AX ;
\r
465 MOV DI, poffset ; go to the first pixel
\r
466 MOV SI, bmpOffset ; go to the bmp pixel
\r
468 MOV CX, width ; count the columns
\r
470 MOVSB ; copy the pixel
\r
471 SUB CX, 3 ; we skip the next 3
\r
472 ADD SI, 3 ; skip the bmp pixels
\r
473 LOOP SCAN_LOOP ; finish the scan
\r
475 MOV AX, nextPageRow
\r
476 ADD DI, AX ; go to the next row on screen
\r
478 ADD SI, AX ; go to the next row on bmp
\r
481 JNZ ROW_LOOP ; do all the rows
\r
482 ;-- end plane painting
\r
484 MOV AL, plane ; advance to the next plane
\r
486 AND AL, 0x0f ; mask the plane properly
\r
487 MOV plane, AL ; store the plane
\r
489 INC bmpOffset ; start bmp at the right spot
\r
492 JNZ PLANE_LOOP ; do all 4 planes
\r
497 modex_sparky4_DrawBmpRegion(page_t *page, int x, int y,
\r
498 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
499 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
500 byte far *data = bmp->data;//+bmp->offset;
\r
501 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
504 byte plane = 1 << ((byte) x & 0x03);
\r
505 word scanCount = width/4 + (width%4 ? 1 :0);
\r
506 word nextPageRow = page->width/4 - scanCount;
\r
507 word nextBmpRow = (word) bmp->width - width;
\r
509 byte planeCounter = 4;
\r
511 /* printf("bmp->data=%Fp\n",bmp->data);
\r
512 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
513 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
515 //code is a bit slow here
\r
517 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
520 MOV DX, SC_INDEX ; point at the map mask register
\r
525 MOV DX, SC_DATA ; select the current plane
\r
529 ;-- begin plane painting
\r
530 MOV AX, height ; start the row counter
\r
531 MOV rowCounter, AX ;
\r
532 MOV DI, poffset ; go to the first pixel
\r
533 MOV SI, bmpOffset ; go to the bmp pixel
\r
535 MOV CX, width ; count the columns
\r
537 MOVSB ; copy the pixel
\r
538 SUB CX, 3 ; we skip the next 3
\r
539 ADD SI, 3 ; skip the bmp pixels
\r
540 LOOP SCAN_LOOP ; finish the scan
\r
542 MOV AX, nextPageRow
\r
543 ADD DI, AX ; go to the next row on screen
\r
545 ADD SI, AX ; go to the next row on bmp
\r
548 JNZ ROW_LOOP ; do all the rows
\r
549 ;-- end plane painting
\r
551 MOV AL, plane ; advance to the next plane
\r
553 AND AL, 0x0f ; mask the plane properly
\r
554 MOV plane, AL ; store the plane
\r
556 INC bmpOffset ; start bmp at the right spot
\r
559 JNZ PLANE_LOOP ; do all 4 planes
\r
564 modexDrawPlanarBuf(page_t *page, int x, int y, planar_buf_t *bmp) {
\r
565 /* TODO - adapt from test code */
\r
567 for(plane=0; plane < 4; plane++)
\r
575 modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp) {
\r
576 /* draw the whole sprite */
\r
577 modexDrawSpriteRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
581 modexDrawSpriteRegion(page_t *page, int x, int y,
\r
582 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
583 word poffset = (word)page->data + y*(page->width/4) + x/4;
\r
584 byte *data = bmp->data;//+bmp->offset;
\r
585 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
588 byte plane = 1 << ((byte) x & 0x03);
\r
589 word scanCount = width/4 + (width%4 ? 1 :0);
\r
590 word nextPageRow = page->width/4 - scanCount;
\r
591 word nextBmpRow = (word) bmp->width - width;
\r
593 byte planeCounter = 4;
\r
596 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
599 MOV DX, SC_INDEX ; point at the map mask register
\r
604 MOV DX, SC_DATA ; select the current plane
\r
608 ;-- begin plane painting
\r
609 MOV AX, height ; start the row counter
\r
610 MOV rowCounter, AX ;
\r
611 MOV DI, poffset ; go to the first pixel
\r
612 MOV SI, bmpOffset ; go to the bmp pixel
\r
614 MOV CX, width ; count the columns
\r
619 JNE DRAW_PIXEL ; draw non-zero pixels
\r
621 INC DI ; skip the transparent pixel
\r
625 MOVSB ; copy the pixel
\r
627 SUB CX, 3 ; we skip the next 3
\r
628 ADD SI, 3 ; skip the bmp pixels
\r
629 LOOP SCAN_LOOP ; finish the scan
\r
631 MOV AX, nextPageRow
\r
632 ADD DI, AX ; go to the next row on screen
\r
634 ADD SI, AX ; go to the next row on bmp
\r
637 JNZ ROW_LOOP ; do all the rows
\r
638 ;-- end plane painting
\r
640 MOV AL, plane ; advance to the next plane
\r
642 AND AL, 0x0f ; mask the plane properly
\r
643 MOV plane, AL ; store the plane
\r
645 INC bmpOffset ; start bmp at the right spot
\r
648 JNZ PLANE_LOOP ; do all 4 planes
\r
653 /* copy a region of video memory from one page to another.
\r
654 * It assumes that the left edge of the tile is the same on both
\r
655 * regions and the memory areas do not overlap.
\r
658 modexCopyPageRegion(page_t *dest, page_t *src,
\r
661 word width, word height)
\r
663 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
664 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
665 word scans = width/4;
\r
666 word nextSrcRow = src->width/4 - scans - 1;
\r
667 word nextDestRow = dest->width/4 - scans - 1;
\r
668 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
669 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
670 byte left = lclip[sx&0x03];
\r
671 byte right = rclip[(sx+width)&0x03];
\r
674 MOV AX, SCREEN_SEG ; work in the vga space
\r
679 MOV DX, GC_INDEX ; turn off cpu bits
\r
683 MOV AX, SC_INDEX ; point to the mask register
\r
693 MOV CX, scans ; the number of latches
\r
695 MOV AL, left ; do the left column
\r
700 MOV AL, 0fh ; do the inner columns
\r
702 REP MOVSB ; copy the pixels
\r
704 MOV AL, right ; do the right column
\r
709 MOV AX, SI ; go the start of the next row
\r
710 ADD AX, nextSrcRow ;
\r
713 ADD AX, nextDestRow ;
\r
716 DEC height ; do the rest of the actions
\r
719 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
720 MOV AL, 0ffh ; none from latches
\r
726 /* fade and flash */
\r
728 modexFadeOn(word fade, byte *palette) {
\r
729 fadePalette(-fade, 64, 64/fade+1, palette);
\r
734 modexFadeOff(word fade, byte *palette) {
\r
735 fadePalette(fade, 0, 64/fade+1, palette);
\r
740 modexFlashOn(word fade, byte *palette) {
\r
741 fadePalette(fade, -64, 64/fade+1, palette);
\r
746 modexFlashOff(word fade, byte *palette) {
\r
747 fadePalette(-fade, 0, 64/fade+1, palette);
\r
752 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
756 /* handle the case where we just update */
\r
758 modexPalUpdate1(palette);
\r
762 while(iter > 0) { /* FadeLoop */
\r
763 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
764 tmppal[i] = palette[i] - dim;
\r
765 if(tmppal[i] > 127) {
\r
767 } else if(tmppal[i] > 63) {
\r
771 modexPalUpdate1(tmppal);
\r
778 /* save and load */
\r
780 modexPalSave(byte *palette) {
\r
783 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
784 for(i=0; i<PAL_SIZE; i++) {
\r
785 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
793 ptr = malloc(PAL_SIZE);
\r
795 /* handle errors */
\r
797 printf("Could not allocate palette.\n");
\r
806 modexLoadPalFile(byte *filename, byte **palette) {
\r
810 /* free the palette if it exists */
\r
815 /* allocate the new palette */
\r
816 *palette = modexNewPal();
\r
818 /* open the file */
\r
819 file = fopen(filename, "rb");
\r
821 printf("Could not open palette file: %s\n", filename);
\r
825 /* read the file */
\r
827 while(!feof(file)) {
\r
828 *ptr++ = fgetc(file);
\r
836 modexSavePalFile(char *filename, byte *pal) {
\r
840 /* open the file for writing */
\r
841 file = fopen(filename, "wb");
\r
843 printf("Could not open %s for writing\n", filename);
\r
847 /* write the data to the file */
\r
848 fwrite(pal, 1, PAL_SIZE, file);
\r
856 fadePalette(-1, 64, 1, tmppal);
\r
862 fadePalette(-1, -64, 1, tmppal);
\r
868 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
870 byte *p = bmp->palette;
\r
874 static word a[PAL_SIZE]; //palette array of change values!
\r
875 word z=0, aq=0, aa=0, pp=0;
\r
880 memset(a, -1, sizeof(a));
\r
881 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
891 // printf("q: %02d\n", (q));
\r
892 // printf("qq: %02d\n", (qq));
\r
893 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
894 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
896 if((*i)<PAL_SIZE/2 && w==0)
\r
898 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
900 //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
901 //____ 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
902 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
907 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
909 //printf("qp=%d\n", qp);
\r
910 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
911 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
912 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
913 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
917 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
919 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
920 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
921 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
924 //if(qp>0) printf("qp=%d\n", qp);
\r
925 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
927 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
928 if((*i)>=PAL_SIZE/2 && w==0)
\r
930 for(; (*i)<PAL_SIZE; (*i)++)
\r
932 //____ 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
933 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
938 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
940 //printf("qp=%d\n", qp);
\r
941 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
942 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
943 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
944 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
948 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
949 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
950 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
953 //printf(" (*i)=%d\n", (*i)/3);
\r
956 printf("\nqqqqqqqq\n\n");
\r
962 long bufSize = (bmp->width * bmp->height);
\r
964 //printf("1(*i)=%02d\n", (*i)/3);
\r
965 //printf("1z=%02d\n", z/3);
\r
966 chkcolor(bmp, &q, &a, &aa, &z, i);
\r
967 //printf("2(*i)=%02d\n", (*i)/3);
\r
968 //printf("2z=%02d\n", z/3);
\r
973 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
974 if(a[aq]==-1) aq++;
\r
975 else { aqoffset++; break; }
\r
977 //update the image data here!
\r
978 for(lq=0; lq<bufSize; lq++)
\r
982 use a[qp] instead of bmp->offset for this spot!
\r
987 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
990 //(offset/bmp->offset)*bmp->offset
\r
993 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
994 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
995 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
996 /*if(bmp->data[lq]+bmp->offset==aq)
\r
998 //printf("%02d", bmp->data[lq]);
\r
999 //printf("\n%02d\n", bmp->offset);
\r
1000 printf("aq=%02d ", aq);
\r
1001 printf("a[aq]=%02d ", a[aq]);
\r
1002 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
1003 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
1004 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
1005 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
1006 // printf("_%d ", bmp->data[lq]);
\r
1007 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
1009 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
1011 if(bmp->data[lq]+bmp->offset >= aq)
\r
1013 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
1014 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
1016 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
1019 //printf("%02d`", bmp->data[lq]);
\r
1020 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
1023 //printf(" aq=%02d\n", aq);
\r
1024 //printf(" aa=%02d\n", aa);
\r
1026 //update the palette~
\r
1027 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
1030 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
1035 modexPalUpdate1(byte *p)
\r
1038 modexWaitBorder();
\r
1039 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
1040 for(i=0; i<PAL_SIZE/2; i++)
\r
1042 outp(PAL_DATA_REG, p[i]);
\r
1044 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
1045 for(; i<PAL_SIZE; i++)
\r
1047 outp(PAL_DATA_REG, p[(i)]);
\r
1052 modexPalUpdate0(byte *p)
\r
1055 modexWaitBorder();
\r
1056 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
1057 for(i=0; i<PAL_SIZE/2; i++)
\r
1059 outp(PAL_DATA_REG, rand());
\r
1061 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
1062 for(; i<PAL_SIZE; i++)
\r
1064 outp(PAL_DATA_REG, rand());
\r
1069 //i want to make another vesion that checks the palette when the palette is being appened~
\r
1070 void chkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
1074 pal = modexNewPal();
\r
1075 modexPalSave(pal);
\r
1076 //printf("q: %02d\n", (*q));
\r
1077 printf("chkcolor start~\n");
\r
1078 printf("1 (*z): %d\n", (*z)/3);
\r
1079 printf("1 (*i): %d\n", (*i)/3);
\r
1080 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
1081 printf("wwwwwwwwwwwwwwww\n");
\r
1082 //check palette for dups
\r
1083 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
1085 //printf("\n z: %d\n", (*z));
\r
1086 //printf(" q: %d\n", (*q));
\r
1087 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
1090 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
1093 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1094 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
1098 else for(zz=0; zz<(*q); zz+=3)
\r
1100 //printf("zz: %02d\n", zz/3);
\r
1103 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
1107 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
1108 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
1111 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
1113 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
1114 // 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
1115 // 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
1116 // //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
1117 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1120 //expand dong here
\r
1122 planned features that i plan to implement~
\r
1123 image that has values on the pallete list!
\r
1125 no... wait.... no wwww
\r
1127 //for(zzii=0; zzii<3; zzii++)
\r
1129 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
1130 a[(((*z)+(*q)))]=zz;
\r
1132 (*aa)=(((*z)+(*q)));
\r
1133 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
1134 // printf("\n aa: %d\n\n", (*aa));
\r
1135 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
1136 // printf("wwwwwwwwwwwwwwww\n\n");
\r
1140 printf("================\n");
\r
1141 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
1142 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
1143 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1144 printf("================\n");
\r
1146 //printf("[%d]", (zz+q));
\r
1150 printf("wwwwwwwwwwwwwwww\n");
\r
1151 printf("2 (*z): %d\n", (*z)/3);
\r
1152 printf("2 (*i): %d\n", (*i)/3);
\r
1153 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
1154 printf("chkcolor end~\n");
\r
1158 void modexputPixel(page_t *page, int x, int y, byte color)
\r
1160 word pageOff = (word) page->data;
\r
1161 /* Each address accesses four neighboring pixels, so set
\r
1162 Write Plane Enable according to which pixel we want
\r
1163 to modify. The plane is determined by the two least
\r
1164 significant bits of the x-coordinate: */
\r
1165 modexSelectPlane(PLANE(x));
\r
1166 //outp(SC_INDEX, 0x02);
\r
1167 //outp(SC_DATA, 0x01 << (x & 3));
\r
1169 /* The offset of the pixel into the video segment is
\r
1170 offset = (width * y + x) / 4, and write the given
\r
1171 color to the plane we selected above. Heed the active
\r
1172 page start selection. */
\r
1173 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
1177 byte modexgetPixel(page_t *page, int x, int y)
\r
1179 word pageOff = (word) page->data;
\r
1180 /* Select the plane from which we must read the pixel color: */
\r
1181 outpw(GC_INDEX, 0x04);
\r
1182 outpw(GC_INDEX+1, x & 3);
\r
1184 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
1188 void modexhlin(page_t *page, word xl, word xh, word y, word color)
\r
1193 for(x=0;x<xh*4;x+=4)
\r
1195 if(x+4>=page[0].sw-1){ x=0; yy+=4; }
\r
1196 modexClearRegion(page, x+xl, y+yy, 4, 4, color);
\r
1198 //modexputPixel(page, x+xl, y, color);
\r
1201 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1203 word i, s, o, w, j, xp;
\r
1205 word addr = (word) l;
\r
1229 s=romFonts[t].seg;
\r
1230 o=romFonts[t].off;
\r
1232 for(; *str != '\0'; str++)
\r
1235 if((c=='\n'/* || c=="\
\r
1243 //load the letter 'A'
\r
1249 MOV AL, c ; the letter
\r
1252 ADD SI, AX ;the address of charcter
\r
1261 for(i=0; i<w; i++)
\r
1267 modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1276 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1278 word i, s, o, w, j, xp;
\r
1280 word addr = (word) l;
\r
1304 s=romFonts[t].seg;
\r
1305 o=romFonts[t].off;
\r
1307 for(; *str != '\0'; str++)
\r
1310 if((c=='\n'/* || c=="\
\r
1311 "*/)/* || chw>=page->width*/)
\r
1317 //load the letter 'A'
\r
1323 MOV AL, c ; the letter
\r
1326 ADD SI, AX ;the address of charcter
\r
1335 for(i=0; i<w; i++)
\r
1341 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1342 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1351 /* palette dump on display! */
\r
1352 void pdump(page_t *pee)
\r
1354 int mult=(QUADWH);
\r
1355 int palq=(mult)*TILEWH;
\r
1358 for(paly=0; paly<palq; paly+=mult){
\r
1359 for(palx=0; palx<palq; palx+=mult){
\r
1360 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
\r
1366 /////////////////////////////////////////////////////////////////////////////
\r
1368 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1369 // the Virtual screen. //
\r
1371 /////////////////////////////////////////////////////////////////////////////
\r
1372 void cls(page_t *page, byte color, byte *Where)
\r
1374 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1375 /* set map mask to all 4 planes */
\r
1376 outpw(SC_INDEX, 0xff02);
\r
1377 //_fmemset(VGA, color, 16000);
\r
1378 _fmemset(Where, color, page->width*(page->height));
\r
1382 modexWaitBorder() {
\r
1383 while(inp(INPUT_STATUS_1) & 8) {
\r
1387 while(!(inp(INPUT_STATUS_1) & 8)) {
\r