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=320;
\r
138 gv->video.page[0].sh=200;
\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
152 CRTParmCount = sizeof(ModeX_256x192regs) / sizeof(ModeX_256x192regs[0]);
\r
153 /* width and height */
\r
154 gv->video.page[0].sw=256;
\r
155 gv->video.page[0].sh=192;
\r
157 /* send the CRTParms */
\r
158 for(i=0; i<CRTParmCount; i++) {
\r
159 outpw(CRTC_INDEX, ModeX_256x192regs[i]);
\r
162 /* clear video memory */
\r
163 outpw(SC_INDEX, 0x0f02);
\r
164 for(i=0; i<0x8000; i++) {
\r
169 gv->video.page[0].tilesw = gv->video.page[0].sw/TILEWH;
\r
170 gv->video.page[0].tilesh = gv->video.page[0].sh/TILEWH;
\r
171 //TODO MAKE FLEXIBLE~
\r
172 gv->video.page[0].tilemidposscreenx = gv->video.page[0].tilesw;
\r
173 gv->video.page[0].tilemidposscreeny = (gv->video.page[0].tilesh/2)+1;
\r
174 #define PAGE_SIZE (word)(gv->video.page[0].sw/4 * gv->video.page[0].sh)
\r
179 /* TODO restore original mode and palette */
\r
180 vgaSetMode(TEXT_MODE);
\r
183 // setBaseXMode() does the initialization to make the VGA ready to
\r
184 // accept any combination of configuration register settings. This
\r
185 // involves enabling writes to index 0 to 7 of the CRT controller (port
\r
186 // 0x3D4), by clearing the most significant bit (bit 7) of index 0x11.
\r
188 modexsetBaseXMode(page_t *page)
\r
191 /* TODO save current video mode and palette */
\r
192 vgaSetMode(VGA_256_COLOR_MODE);
\r
194 /* disable chain4 mode */
\r
195 outpw(SC_INDEX, 0x0604);
\r
197 /* synchronous reset while setting Misc Output */
\r
198 outpw(SC_INDEX, 0x0100);
\r
200 /* select 25 MHz dot clock & 60 Hz scanning rate */
\r
201 outp(MISC_OUTPUT, 0xe3);
\r
203 /* undo reset (restart sequencer) */
\r
204 outpw(SC_INDEX, 0x0300);
\r
206 /* reprogram the CRT controller */
\r
207 outp(CRTC_INDEX, 0x11); /* VSync End reg contains register write prot */
\r
208 // temp = inp(CRTC_DATA) & 0x7F;
\r
209 // outp(CRTC_INDEX, 0x11);
\r
210 outp(CRTC_DATA, 0x7f); /* get current write protect on varios regs */
\r
211 // outp(CRTC_DATA, temp); /* get current write protect on varios regs */
\r
215 modexDefaultPage(page_t *p)
\r
219 /* default page values */
\r
225 page.width = p->sw;
\r
226 page.height = p->sh;
\r
227 page.tw = page.sw/TILEWH;
\r
228 page.th = page.sh/TILEWH;
\r
229 page.tilemidposscreenx = page.tw/2;
\r
230 page.tilemidposscreeny = (page.th/2)+1;
\r
231 page.tilesw=p->tilesw;
\r
232 page.tilesh=p->tilesh;
\r
233 //pageSize = p->sw*p->sh;
\r
239 /* returns the next page in contiguous memory
\r
240 * the next page will be the same size as p, by default
\r
243 modexNextPage(page_t *p) {
\r
246 result.data = p->data + (p->width/4)*p->height;
\r
249 result.width = p->width;
\r
250 result.height = p->height;
\r
251 result.tw = p->width/TILEWH;
\r
252 result.th = p->height/TILEWH;
\r
253 result.id = p->id+1;
\r
256 // return modexNextPageFlexibleSize(&p, p->width, p->height);
\r
259 //next page with defined dimentions~
\r
261 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
265 result.data = p->data + (p->width/4)*p->height; /* compute the offset */
\r
270 result.tw = p->width/TILEWH;
\r
271 result.th = p->height/TILEWH;
\r
272 result.id = p->id+1;
\r
279 modexShowPage(page_t *page) {
\r
285 /* calculate offset */
\r
286 offset = (word) page->data;
\r
287 offset += page->dy * (page->width >> 2 );
\r
288 offset += page->dx >> 2;
\r
290 /* calculate crtcOffset according to virtual width */
\r
291 crtcOffset = page->width >> 3;
\r
293 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
294 low_address = LOW_ADDRESS | (offset << 8);
\r
296 /* wait for appropriate timing and then program CRTC */
\r
297 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
298 outpw(CRTC_INDEX, high_address);
\r
299 outpw(CRTC_INDEX, low_address);
\r
300 outp(CRTC_INDEX, 0x13);
\r
301 outp(CRTC_DATA, crtcOffset);
\r
303 /* wait for one retrace */
\r
304 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
306 /* do PEL panning here */
\r
307 outp(AC_INDEX, 0x33);
\r
308 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
313 modexPanPage(page_t *page, int dx, int dy) {
\r
320 modexSelectPlane(byte plane) {
\r
321 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
322 outp(SC_DATA, plane);
\r
327 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
328 word pageOff = (word) page->data;
\r
329 word xoff=x/4; /* xoffset that begins each row */
\r
330 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
331 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
332 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
333 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
334 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
335 byte left = lclip[x&0x03];
\r
336 byte right = rclip[(x+w)&0x03];
\r
338 /* handle the case which requires an extra group */
\r
339 if((x & 0x03) && !((x+w) & 0x03)) {
\r
344 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
346 MOV DI, poffset ; go to the first pixel
\r
347 MOV DX, SC_INDEX ; point to the map mask
\r
351 MOV AL, color ; get ready to write colors
\r
353 MOV CX, scanCount ; count the line
\r
354 MOV BL, AL ; remember color
\r
355 MOV AL, left ; do the left clip
\r
356 OUT DX, AL ; set the left clip
\r
357 MOV AL, BL ; restore color
\r
358 STOSB ; write the color
\r
360 JZ SCAN_DONE ; handle 1 group stuff
\r
362 ;-- write the main body of the scanline
\r
363 MOV BL, AL ; remember color
\r
364 MOV AL, 0x0f ; write to all pixels
\r
366 MOV AL, BL ; restore color
\r
367 REP STOSB ; write the color
\r
369 MOV BL, AL ; remeber color
\r
371 OUT DX, AL ; do the right clip
\r
372 MOV AL, BL ; restore color
\r
373 STOSB ; write pixel
\r
374 ADD DI, nextRow ; go to the next row
\r
382 oldDrawBmp(byte far* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
388 /* TODO Make this fast. It's SLOOOOOOW */
\r
389 for(plane=0; plane < 4; plane++) {
\r
390 modexSelectPlane(PLANE(plane+x));
\r
391 for(px = plane; px < bmp->width; px+=4) {
\r
393 for(py=0; py<bmp->height; py++) {
\r
394 if(!sprite || bmp->data[offset])
\r
395 page[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
396 offset+=bmp->width;
\r
403 CDrawBmp(byte far* vgamem, page_t* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
410 /* TODO Make this fast. It's SLOOOOOOW */
\r
411 for(plane=0; plane < 4; plane++) {
\r
412 modexSelectPlane(PLANE(plane+x));
\r
413 for(px = plane; px < bmp->width; px+=4) {
\r
415 for(py=0; py<bmp->height; py++) {
\r
416 if(!sprite || bmp->data[offset])
\r
417 //modexputPixel(page, x+px, y+py, bmp->data[offset]);
\r
418 vgamem[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
419 offset+=bmp->width;
\r
426 modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) {
\r
427 /* draw the region (the entire freakin bitmap) */
\r
428 modexDrawBmpRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
432 modexDrawBmpRegion(page_t *page, int x, int y,
\r
433 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
434 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
435 byte far *data = bmp->data;//+bmp->offset;
\r
436 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
439 byte plane = 1 << ((byte) x & 0x03);
\r
440 word scanCount = width/4 + (width%4 ? 1 :0);
\r
441 word nextPageRow = page->width/4 - scanCount;
\r
442 word nextBmpRow = (word) bmp->width - width;
\r
444 byte planeCounter = 4;
\r
446 /* printf("bmp->data=%Fp\n",bmp->data);
\r
447 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
448 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
450 //code is a bit slow here
\r
452 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
455 MOV DX, SC_INDEX ; point at the map mask register
\r
460 MOV DX, SC_DATA ; select the current plane
\r
464 ;-- begin plane painting
\r
465 MOV AX, height ; start the row counter
\r
466 MOV rowCounter, AX ;
\r
467 MOV DI, poffset ; go to the first pixel
\r
468 MOV SI, bmpOffset ; go to the bmp pixel
\r
470 MOV CX, width ; count the columns
\r
472 MOVSB ; copy the pixel
\r
473 SUB CX, 3 ; we skip the next 3
\r
474 ADD SI, 3 ; skip the bmp pixels
\r
475 LOOP SCAN_LOOP ; finish the scan
\r
477 MOV AX, nextPageRow
\r
478 ADD DI, AX ; go to the next row on screen
\r
480 ADD SI, AX ; go to the next row on bmp
\r
483 JNZ ROW_LOOP ; do all the rows
\r
484 ;-- end plane painting
\r
486 MOV AL, plane ; advance to the next plane
\r
488 AND AL, 0x0f ; mask the plane properly
\r
489 MOV plane, AL ; store the plane
\r
491 INC bmpOffset ; start bmp at the right spot
\r
494 JNZ PLANE_LOOP ; do all 4 planes
\r
499 modexDrawPlanarBuf(page_t *page, int x, int y, planar_buf_t *bmp) {
\r
500 /* TODO - adapt from test code */
\r
502 for(plane=0; plane < 4; plane++)
\r
510 modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp) {
\r
511 /* draw the whole sprite */
\r
512 modexDrawSpriteRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
516 modexDrawSpriteRegion(page_t *page, int x, int y,
\r
517 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
518 word poffset = (word)page->data + y*(page->width/4) + x/4;
\r
519 byte *data = bmp->data;//+bmp->offset;
\r
520 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
523 byte plane = 1 << ((byte) x & 0x03);
\r
524 word scanCount = width/4 + (width%4 ? 1 :0);
\r
525 word nextPageRow = page->width/4 - scanCount;
\r
526 word nextBmpRow = (word) bmp->width - width;
\r
528 byte planeCounter = 4;
\r
531 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
534 MOV DX, SC_INDEX ; point at the map mask register
\r
539 MOV DX, SC_DATA ; select the current plane
\r
543 ;-- begin plane painting
\r
544 MOV AX, height ; start the row counter
\r
545 MOV rowCounter, AX ;
\r
546 MOV DI, poffset ; go to the first pixel
\r
547 MOV SI, bmpOffset ; go to the bmp pixel
\r
549 MOV CX, width ; count the columns
\r
554 JNE DRAW_PIXEL ; draw non-zero pixels
\r
556 INC DI ; skip the transparent pixel
\r
560 MOVSB ; copy the pixel
\r
562 SUB CX, 3 ; we skip the next 3
\r
563 ADD SI, 3 ; skip the bmp pixels
\r
564 LOOP SCAN_LOOP ; finish the scan
\r
566 MOV AX, nextPageRow
\r
567 ADD DI, AX ; go to the next row on screen
\r
569 ADD SI, AX ; go to the next row on bmp
\r
572 JNZ ROW_LOOP ; do all the rows
\r
573 ;-- end plane painting
\r
575 MOV AL, plane ; advance to the next plane
\r
577 AND AL, 0x0f ; mask the plane properly
\r
578 MOV plane, AL ; store the plane
\r
580 INC bmpOffset ; start bmp at the right spot
\r
583 JNZ PLANE_LOOP ; do all 4 planes
\r
588 modexDrawSpriteRegion(page_t *page, int x, int y,
\r
589 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
590 word poffset = (word)page->data + y*(page->width/4) + x/4;
\r
591 byte *data = bmp->data;//+bmp->offset;
\r
592 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
595 byte plane = 1 << ((byte) x & 0x03);
\r
596 word scanCount = width/4 + (width%4 ? 1 :0);
\r
597 word nextPageRow = page->width/4 - scanCount;
\r
598 word nextBmpRow = (word) bmp->width - width;
\r
600 byte planeCounter = 4;
\r
603 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
606 MOV DX, SC_INDEX ; point at the map mask register
\r
611 MOV DX, SC_DATA ; select the current plane
\r
615 ;-- begin plane painting
\r
616 MOV AX, height ; start the row counter
\r
617 MOV rowCounter, AX ;
\r
618 MOV DI, poffset ; go to the first pixel
\r
619 // MOV SI, bmpOffset ; go to the bmp pixel
\r
620 MOV DI, bmpOffset ; go to the bmp pixel
\r
622 MOV CX, width ; count the columns
\r
627 JNE DRAW_PIXEL ; draw non-zero pixels
\r
629 INC DI ; skip the transparent pixel
\r
633 MOVSB ; copy the pixel
\r
635 SUB CX, 3 ; we skip the next 3
\r
636 ADD SI, 3 ; skip the bmp pixels
\r
637 LOOP SCAN_LOOP ; finish the scan
\r
639 MOV AX, nextPageRow
\r
640 ADD DI, AX ; go to the next row on screen
\r
642 ADD SI, AX ; go to the next row on bmp
\r
645 JNZ ROW_LOOP ; do all the rows
\r
646 ;-- end plane painting
\r
648 MOV AL, plane ; advance to the next plane
\r
650 AND AL, 0x0f ; mask the plane properly
\r
651 MOV plane, AL ; store the plane
\r
653 INC bmpOffset ; start bmp at the right spot
\r
656 JNZ PLANE_LOOP ; do all 4 planes
\r
660 /* copy a region of video memory from one page to another.
\r
661 * It assumes that the left edge of the tile is the same on both
\r
662 * regions and the memory areas do not overlap.
\r
665 modexCopyPageRegion(page_t *dest, page_t *src,
\r
668 word width, word height)
\r
670 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
671 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
672 word scans = width/4;
\r
673 word nextSrcRow = src->width/4 - scans - 1;
\r
674 word nextDestRow = dest->width/4 - scans - 1;
\r
675 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
676 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
677 byte left = lclip[sx&0x03];
\r
678 byte right = rclip[(sx+width)&0x03];
\r
681 MOV AX, SCREEN_SEG ; work in the vga space
\r
686 MOV DX, GC_INDEX ; turn off cpu bits
\r
690 MOV AX, SC_INDEX ; point to the mask register
\r
700 MOV CX, scans ; the number of latches
\r
702 MOV AL, left ; do the left column
\r
707 MOV AL, 0fh ; do the inner columns
\r
709 REP MOVSB ; copy the pixels
\r
711 MOV AL, right ; do the right column
\r
716 MOV AX, SI ; go the start of the next row
\r
717 ADD AX, nextSrcRow ;
\r
720 ADD AX, nextDestRow ;
\r
723 DEC height ; do the rest of the actions
\r
726 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
727 MOV AL, 0ffh ; none from latches
\r
733 /* fade and flash */
\r
735 modexFadeOn(word fade, byte *palette) {
\r
736 fadePalette(-fade, 64, 64/fade+1, palette);
\r
741 modexFadeOff(word fade, byte *palette) {
\r
742 fadePalette(fade, 0, 64/fade+1, palette);
\r
747 modexFlashOn(word fade, byte *palette) {
\r
748 fadePalette(fade, -64, 64/fade+1, palette);
\r
753 modexFlashOff(word fade, byte *palette) {
\r
754 fadePalette(-fade, 0, 64/fade+1, palette);
\r
759 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
763 /* handle the case where we just update */
\r
765 modexPalUpdate1(palette);
\r
769 while(iter > 0) { /* FadeLoop */
\r
770 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
771 tmppal[i] = palette[i] - dim;
\r
772 if(tmppal[i] > 127) {
\r
774 } else if(tmppal[i] > 63) {
\r
778 modexPalUpdate1(tmppal);
\r
785 /* save and load */
\r
787 modexPalSave(byte *palette) {
\r
790 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
791 for(i=0; i<PAL_SIZE; i++) {
\r
792 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
800 ptr = malloc(PAL_SIZE);
\r
802 /* handle errors */
\r
804 printf("Could not allocate palette.\n");
\r
813 modexLoadPalFile(byte *filename, byte **palette) {
\r
817 /* free the palette if it exists */
\r
822 /* allocate the new palette */
\r
823 *palette = modexNewPal();
\r
825 /* open the file */
\r
826 file = fopen(filename, "rb");
\r
828 printf("Could not open palette file: %s\n", filename);
\r
832 /* read the file */
\r
834 while(!feof(file)) {
\r
835 *ptr++ = fgetc(file);
\r
843 modexSavePalFile(char *filename, byte *pal) {
\r
847 /* open the file for writing */
\r
848 file = fopen(filename, "wb");
\r
850 printf("Could not open %s for writing\n", filename);
\r
854 /* write the data to the file */
\r
855 fwrite(pal, 1, PAL_SIZE, file);
\r
863 fadePalette(-1, 64, 1, tmppal);
\r
869 fadePalette(-1, -64, 1, tmppal);
\r
875 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
877 byte *p = bmp->palette;
\r
881 static word a[PAL_SIZE]; //palette array of change values!
\r
882 word z=0, aq=0, aa=0, pp=0;
\r
887 memset(a, -1, sizeof(a));
\r
888 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
898 // printf("q: %02d\n", (q));
\r
899 // printf("qq: %02d\n", (qq));
\r
900 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
901 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
903 if((*i)<PAL_SIZE/2 && w==0)
\r
905 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
907 //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
908 //____ 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
909 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
914 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
916 //printf("qp=%d\n", qp);
\r
917 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
918 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
919 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
920 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
924 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
926 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
927 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
928 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
931 //if(qp>0) printf("qp=%d\n", qp);
\r
932 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
934 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
935 if((*i)>=PAL_SIZE/2 && w==0)
\r
937 for(; (*i)<PAL_SIZE; (*i)++)
\r
939 //____ 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
940 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
945 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
947 //printf("qp=%d\n", qp);
\r
948 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
949 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
950 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
951 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
955 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
956 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
957 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
960 //printf(" (*i)=%d\n", (*i)/3);
\r
963 printf("\nqqqqqqqq\n\n");
\r
969 long bufSize = (bmp->width * bmp->height);
\r
971 //printf("1(*i)=%02d\n", (*i)/3);
\r
972 //printf("1z=%02d\n", z/3);
\r
973 chkcolor(bmp, &q, &a, &aa, &z, i);
\r
974 //printf("2(*i)=%02d\n", (*i)/3);
\r
975 //printf("2z=%02d\n", z/3);
\r
980 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
981 if(a[aq]==-1) aq++;
\r
982 else { aqoffset++; break; }
\r
984 //update the image data here!
\r
985 for(lq=0; lq<bufSize; lq++)
\r
989 use a[qp] instead of bmp->offset for this spot!
\r
994 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
997 //(offset/bmp->offset)*bmp->offset
\r
1000 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
1001 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
1002 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
1003 /*if(bmp->data[lq]+bmp->offset==aq)
\r
1005 //printf("%02d", bmp->data[lq]);
\r
1006 //printf("\n%02d\n", bmp->offset);
\r
1007 printf("aq=%02d ", aq);
\r
1008 printf("a[aq]=%02d ", a[aq]);
\r
1009 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
1010 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
1011 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
1012 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
1013 // printf("_%d ", bmp->data[lq]);
\r
1014 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
1016 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
1018 if(bmp->data[lq]+bmp->offset >= aq)
\r
1020 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
1021 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
1023 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
1026 //printf("%02d`", bmp->data[lq]);
\r
1027 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
1030 //printf(" aq=%02d\n", aq);
\r
1031 //printf(" aa=%02d\n", aa);
\r
1033 //update the palette~
\r
1034 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
1037 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
1042 modexPalUpdate1(byte *p)
\r
1045 modexWaitBorder();
\r
1046 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
1047 for(i=0; i<PAL_SIZE/2; i++)
\r
1049 outp(PAL_DATA_REG, p[i]);
\r
1051 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
1052 for(; i<PAL_SIZE; i++)
\r
1054 outp(PAL_DATA_REG, p[(i)]);
\r
1059 modexPalUpdate0(byte *p)
\r
1062 modexWaitBorder();
\r
1063 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
1064 for(i=0; i<PAL_SIZE/2; i++)
\r
1066 outp(PAL_DATA_REG, rand());
\r
1068 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
1069 for(; i<PAL_SIZE; i++)
\r
1071 outp(PAL_DATA_REG, rand());
\r
1076 //i want to make another vesion that checks the palette when the palette is being appened~
\r
1077 void chkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
1081 pal = modexNewPal();
\r
1082 modexPalSave(pal);
\r
1083 //printf("q: %02d\n", (*q));
\r
1084 printf("chkcolor start~\n");
\r
1085 printf("1 (*z): %d\n", (*z)/3);
\r
1086 printf("1 (*i): %d\n", (*i)/3);
\r
1087 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
1088 printf("wwwwwwwwwwwwwwww\n");
\r
1089 //check palette for dups
\r
1090 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
1092 //printf("\n z: %d\n", (*z));
\r
1093 //printf(" q: %d\n", (*q));
\r
1094 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
1097 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
1100 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1101 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
1105 else for(zz=0; zz<(*q); zz+=3)
\r
1107 //printf("zz: %02d\n", zz/3);
\r
1110 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
1114 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
1115 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
1118 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
1120 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
1121 // 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
1122 // 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
1123 // //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
1124 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1127 //expand dong here
\r
1129 planned features that i plan to implement~
\r
1130 image that has values on the pallete list!
\r
1132 no... wait.... no wwww
\r
1134 //for(zzii=0; zzii<3; zzii++)
\r
1136 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
1137 a[(((*z)+(*q)))]=zz;
\r
1139 (*aa)=(((*z)+(*q)));
\r
1140 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
1141 // printf("\n aa: %d\n\n", (*aa));
\r
1142 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
1143 // printf("wwwwwwwwwwwwwwww\n\n");
\r
1147 printf("================\n");
\r
1148 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
1149 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
1150 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1151 printf("================\n");
\r
1153 //printf("[%d]", (zz+q));
\r
1157 printf("wwwwwwwwwwwwwwww\n");
\r
1158 printf("2 (*z): %d\n", (*z)/3);
\r
1159 printf("2 (*i): %d\n", (*i)/3);
\r
1160 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
1161 printf("chkcolor end~\n");
\r
1165 void modexputPixel(page_t *page, int x, int y, byte color)
\r
1167 word pageOff = (word) page->data;
\r
1168 /* Each address accesses four neighboring pixels, so set
\r
1169 Write Plane Enable according to which pixel we want
\r
1170 to modify. The plane is determined by the two least
\r
1171 significant bits of the x-coordinate: */
\r
1172 modexSelectPlane(PLANE(x));
\r
1173 //outp(SC_INDEX, 0x02);
\r
1174 //outp(SC_DATA, 0x01 << (x & 3));
\r
1176 /* The offset of the pixel into the video segment is
\r
1177 offset = (width * y + x) / 4, and write the given
\r
1178 color to the plane we selected above. Heed the active
\r
1179 page start selection. */
\r
1180 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
1184 byte modexgetPixel(page_t *page, int x, int y)
\r
1186 word pageOff = (word) page->data;
\r
1187 /* Select the plane from which we must read the pixel color: */
\r
1188 outpw(GC_INDEX, 0x04);
\r
1189 outpw(GC_INDEX+1, x & 3);
\r
1191 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
1195 void modexhlin(page_t *page, word xl, word xh, word y, word color)
\r
1200 for(x=0;x<xh*4;x+=4)
\r
1202 if(x+4>=page[0].sw-1){ x=0; yy+=4; }
\r
1203 modexClearRegion(page, x+xl, y+yy, 4, 4, color);
\r
1205 //modexputPixel(page, x+xl, y, color);
\r
1208 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1210 word i, s, o, w, j, xp;
\r
1212 word addr = (word) l;
\r
1236 s=romFonts[t].seg;
\r
1237 o=romFonts[t].off;
\r
1239 for(; *str != '\0'; str++)
\r
1242 if((c=='\n'/* || c=="\
\r
1250 //load the letter 'A'
\r
1256 MOV AL, c ; the letter
\r
1259 ADD SI, AX ;the address of charcter
\r
1268 for(i=0; i<w; i++)
\r
1274 modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1283 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1285 word i, s, o, w, j, xp;
\r
1287 word addr = (word) l;
\r
1311 s=romFonts[t].seg;
\r
1312 o=romFonts[t].off;
\r
1314 for(; *str != '\0'; str++)
\r
1317 if((c=='\n'/* || c=="\
\r
1318 "*/)/* || chw>=page->width*/)
\r
1324 //load the letter 'A'
\r
1330 MOV AL, c ; the letter
\r
1333 ADD SI, AX ;the address of charcter
\r
1342 for(i=0; i<w; i++)
\r
1348 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1349 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1358 /* palette dump on display! */
\r
1359 void pdump(page_t *pee)
\r
1361 int mult=(QUADWH);
\r
1362 int palq=(mult)*TILEWH;
\r
1365 for(paly=0; paly<palq; paly+=mult){
\r
1366 for(palx=0; palx<palq; palx+=mult){
\r
1367 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
\r
1373 /////////////////////////////////////////////////////////////////////////////
\r
1375 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1376 // the Virtual screen. //
\r
1378 /////////////////////////////////////////////////////////////////////////////
\r
1379 void cls(page_t *page, byte color, byte *Where)
\r
1381 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1382 /* set map mask to all 4 planes */
\r
1383 outpw(SC_INDEX, 0xff02);
\r
1384 //_fmemset(VGA, color, 16000);
\r
1385 _fmemset(Where, color, page->width*(page->height));
\r
1389 modexWaitBorder() {
\r
1390 while(inp(INPUT_STATUS_1) & 8) {
\r
1394 while(!(inp(INPUT_STATUS_1) & 8)) {
\r