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->sw=320;
\r
104 gv->video.page->sh=240;
\r
105 gv->video.page->tilesw = gv->video.page->sw/TILEWH;
\r
106 gv->video.page->tilesh = gv->video.page->sh/TILEWH;
\r
107 //TODO MAKE FLEXIBLE~
\r
108 gv->video.page->tilemidposscreenx = 10;
\r
109 gv->video.page->tilemidposscreeny = 8;
\r
111 /* send the CRTParms */
\r
112 for(i=0; i<CRTParmCount; i++) {
\r
113 outpw(CRTC_INDEX, ModeX_320x240regs[i]);
\r
116 /* clear video memory */
\r
117 outpw(SC_INDEX, 0x0f02);
\r
118 for(i=0; i<0x8000; i++) {
\r
123 CRTParmCount = sizeof(ModeX_192x144regs) / sizeof(ModeX_192x144regs[0]);
\r
124 /* width and height */
\r
125 //TODO add width and height of screen
\r
127 /* send the CRTParms */
\r
128 for(i=0; i<CRTParmCount; i++) {
\r
129 outpw(CRTC_INDEX, ModeX_192x144regs[i]);
\r
132 /* clear video memory */
\r
133 outpw(SC_INDEX, 0x0f02);
\r
134 for(i=0; i<0x8000; i++) {
\r
143 /* TODO restore original mode and palette */
\r
144 vgaSetMode(TEXT_MODE);
\r
147 // setBaseXMode() does the initialization to make the VGA ready to
\r
148 // accept any combination of configuration register settings. This
\r
149 // involves enabling writes to index 0 to 7 of the CRT controller (port
\r
150 // 0x3D4), by clearing the most significant bit (bit 7) of index 0x11.
\r
152 modexsetBaseXMode(page_t *page)
\r
155 /* TODO save current video mode and palette */
\r
156 vgaSetMode(VGA_256_COLOR_MODE);
\r
158 /* disable chain4 mode */
\r
159 outpw(SC_INDEX, 0x0604);
\r
161 /* synchronous reset while setting Misc Output */
\r
162 outpw(SC_INDEX, 0x0100);
\r
164 /* select 25 MHz dot clock & 60 Hz scanning rate */
\r
165 outp(MISC_OUTPUT, 0xe3);
\r
167 /* undo reset (restart sequencer) */
\r
168 outpw(SC_INDEX, 0x0300);
\r
170 /* reprogram the CRT controller */
\r
171 outp(CRTC_INDEX, 0x11); /* VSync End reg contains register write prot */
\r
172 temp = inp(CRTC_DATA) & 0x7F;
\r
173 outp(CRTC_INDEX, 0x11);
\r
174 // outp(CRTC_DATA, 0x7f); /* get current write protect on varios regs */
\r
175 outp(CRTC_DATA, temp); /* get current write protect on varios regs */
\r
179 modexDefaultPage() {
\r
182 /* default page values */
\r
186 page.width = SCREEN_WIDTH;
\r
187 page.height = SCREEN_HEIGHT;
\r
188 page.tw = page.width/TILEWH;
\r
189 page.th = page.height/TILEWH;
\r
195 /* returns the next page in contiguous memory
\r
196 * the next page will be the same size as p, by default
\r
199 modexNextPage(page_t *p) {
\r
202 result.data = p->data + (p->width/4)*p->height;
\r
205 result.width = p->width;
\r
206 result.height = p->height;
\r
207 result.tw = p->width/TILEWH;
\r
208 result.th = p->height/TILEWH;
\r
209 result.id = p->id+1;
\r
212 // return modexNextPageFlexibleSize(&p, p->width, p->height);
\r
215 //next page with defined dimentions~
\r
217 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
221 result.data = p->data + (p->width/4)*p->height; /* compute the offset */
\r
226 result.tw = p->width/TILEWH;
\r
227 result.th = p->height/TILEWH;
\r
228 result.id = p->id+1;
\r
235 modexShowPage(page_t *page) {
\r
241 /* calculate offset */
\r
242 offset = (word) page->data;
\r
243 offset += page->dy * (page->width >> 2 );
\r
244 offset += page->dx >> 2;
\r
246 /* calculate crtcOffset according to virtual width */
\r
247 crtcOffset = page->width >> 3;
\r
249 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
250 low_address = LOW_ADDRESS | (offset << 8);
\r
252 /* wait for appropriate timing and then program CRTC */
\r
253 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
254 outpw(CRTC_INDEX, high_address);
\r
255 outpw(CRTC_INDEX, low_address);
\r
256 outp(CRTC_INDEX, 0x13);
\r
257 outp(CRTC_DATA, crtcOffset);
\r
259 /* wait for one retrace */
\r
260 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
262 /* do PEL panning here */
\r
263 outp(AC_INDEX, 0x33);
\r
264 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
269 modexPanPage(page_t *page, int dx, int dy) {
\r
276 modexSelectPlane(byte plane) {
\r
277 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
278 outp(SC_DATA, plane);
\r
283 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
284 word pageOff = (word) page->data;
\r
285 word xoff=x/4; /* xoffset that begins each row */
\r
286 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
287 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
288 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
289 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
290 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
291 byte left = lclip[x&0x03];
\r
292 byte right = rclip[(x+w)&0x03];
\r
294 /* handle the case which requires an extra group */
\r
295 if((x & 0x03) && !((x+w) & 0x03)) {
\r
300 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
302 MOV DI, poffset ; go to the first pixel
\r
303 MOV DX, SC_INDEX ; point to the map mask
\r
307 MOV AL, color ; get ready to write colors
\r
309 MOV CX, scanCount ; count the line
\r
310 MOV BL, AL ; remember color
\r
311 MOV AL, left ; do the left clip
\r
312 OUT DX, AL ; set the left clip
\r
313 MOV AL, BL ; restore color
\r
314 STOSB ; write the color
\r
316 JZ SCAN_DONE ; handle 1 group stuff
\r
318 ;-- write the main body of the scanline
\r
319 MOV BL, AL ; remember color
\r
320 MOV AL, 0x0f ; write to all pixels
\r
322 MOV AL, BL ; restore color
\r
323 REP STOSB ; write the color
\r
325 MOV BL, AL ; remeber color
\r
327 OUT DX, AL ; do the right clip
\r
328 MOV AL, BL ; restore color
\r
329 STOSB ; write pixel
\r
330 ADD DI, nextRow ; go to the next row
\r
338 oldDrawBmp(byte far* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
344 /* TODO Make this fast. It's SLOOOOOOW */
\r
345 for(plane=0; plane < 4; plane++) {
\r
346 modexSelectPlane(PLANE(plane+x));
\r
347 for(px = plane; px < bmp->width; px+=4) {
\r
349 for(py=0; py<bmp->height; py++) {
\r
350 if(!sprite || bmp->data[offset])
\r
351 page[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
352 offset+=bmp->width;
\r
359 CDrawBmp(byte far* vgamem, page_t* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
366 /* TODO Make this fast. It's SLOOOOOOW */
\r
367 for(plane=0; plane < 4; plane++) {
\r
368 modexSelectPlane(PLANE(plane+x));
\r
369 for(px = plane; px < bmp->width; px+=4) {
\r
371 for(py=0; py<bmp->height; py++) {
\r
372 if(!sprite || bmp->data[offset])
\r
373 //modexputPixel(page, x+px, y+py, bmp->data[offset]);
\r
374 vgamem[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
375 offset+=bmp->width;
\r
382 modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) {
\r
383 /* draw the region (the entire freakin bitmap) */
\r
384 modexDrawBmpRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
389 modexDrawBmpRegion(page_t *page, int x, int y,
\r
390 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
391 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
392 byte far *data = bmp->data;//+bmp->offset;
\r
393 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
396 byte plane = 1 << ((byte) x & 0x03);
\r
397 word scanCount = width/4 + (width%4 ? 1 :0);
\r
398 word nextPageRow = page->width/4 - scanCount;
\r
399 word nextBmpRow = (word) bmp->width - width;
\r
401 byte planeCounter = 4;
\r
403 /* printf("bmp->data=%Fp\n",bmp->data);
\r
404 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
405 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
407 //code is a bit slow here
\r
409 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
412 MOV DX, SC_INDEX ; point at the map mask register
\r
417 MOV DX, SC_DATA ; select the current plane
\r
421 ;-- begin plane painting
\r
422 MOV AX, height ; start the row counter
\r
423 MOV rowCounter, AX ;
\r
424 MOV DI, poffset ; go to the first pixel
\r
425 MOV SI, bmpOffset ; go to the bmp pixel
\r
427 MOV CX, width ; count the columns
\r
429 MOVSB ; copy the pixel
\r
430 SUB CX, 3 ; we skip the next 3
\r
431 ADD SI, 3 ; skip the bmp pixels
\r
432 LOOP SCAN_LOOP ; finish the scan
\r
434 MOV AX, nextPageRow
\r
435 ADD DI, AX ; go to the next row on screen
\r
437 ADD SI, AX ; go to the next row on bmp
\r
440 JNZ ROW_LOOP ; do all the rows
\r
441 ;-- end plane painting
\r
443 MOV AL, plane ; advance to the next plane
\r
445 AND AL, 0x0f ; mask the plane properly
\r
446 MOV plane, AL ; store the plane
\r
448 INC bmpOffset ; start bmp at the right spot
\r
451 JNZ PLANE_LOOP ; do all 4 planes
\r
456 modex_sparky4_DrawBmpRegion(page_t *page, int x, int y,
\r
457 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
458 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
459 byte far *data = bmp->data;//+bmp->offset;
\r
460 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
463 byte plane = 1 << ((byte) x & 0x03);
\r
464 word scanCount = width/4 + (width%4 ? 1 :0);
\r
465 word nextPageRow = page->width/4 - scanCount;
\r
466 word nextBmpRow = (word) bmp->width - width;
\r
468 byte planeCounter = 4;
\r
470 /* printf("bmp->data=%Fp\n",bmp->data);
\r
471 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
472 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
474 //code is a bit slow here
\r
476 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
479 MOV DX, SC_INDEX ; point at the map mask register
\r
484 MOV DX, SC_DATA ; select the current plane
\r
488 ;-- begin plane painting
\r
489 MOV AX, height ; start the row counter
\r
490 MOV rowCounter, AX ;
\r
491 MOV DI, poffset ; go to the first pixel
\r
492 MOV SI, bmpOffset ; go to the bmp pixel
\r
494 MOV CX, width ; count the columns
\r
496 MOVSB ; copy the pixel
\r
497 SUB CX, 3 ; we skip the next 3
\r
498 ADD SI, 3 ; skip the bmp pixels
\r
499 LOOP SCAN_LOOP ; finish the scan
\r
501 MOV AX, nextPageRow
\r
502 ADD DI, AX ; go to the next row on screen
\r
504 ADD SI, AX ; go to the next row on bmp
\r
507 JNZ ROW_LOOP ; do all the rows
\r
508 ;-- end plane painting
\r
510 MOV AL, plane ; advance to the next plane
\r
512 AND AL, 0x0f ; mask the plane properly
\r
513 MOV plane, AL ; store the plane
\r
515 INC bmpOffset ; start bmp at the right spot
\r
518 JNZ PLANE_LOOP ; do all 4 planes
\r
523 modexDrawPlanarBuf(page_t *page, int x, int y, planar_buf_t *bmp) {
\r
524 /* TODO - adapt from test code */
\r
526 for(plane=0; plane < 4; plane++)
\r
534 modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp) {
\r
535 /* draw the whole sprite */
\r
536 modexDrawSpriteRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
540 modexDrawSpriteRegion(page_t *page, int x, int y,
\r
541 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
542 word poffset = (word)page->data + y*(page->width/4) + x/4;
\r
543 byte *data = bmp->data;//+bmp->offset;
\r
544 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
547 byte plane = 1 << ((byte) x & 0x03);
\r
548 word scanCount = width/4 + (width%4 ? 1 :0);
\r
549 word nextPageRow = page->width/4 - scanCount;
\r
550 word nextBmpRow = (word) bmp->width - width;
\r
552 byte planeCounter = 4;
\r
555 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
558 MOV DX, SC_INDEX ; point at the map mask register
\r
563 MOV DX, SC_DATA ; select the current plane
\r
567 ;-- begin plane painting
\r
568 MOV AX, height ; start the row counter
\r
569 MOV rowCounter, AX ;
\r
570 MOV DI, poffset ; go to the first pixel
\r
571 MOV SI, bmpOffset ; go to the bmp pixel
\r
573 MOV CX, width ; count the columns
\r
578 JNE DRAW_PIXEL ; draw non-zero pixels
\r
580 INC DI ; skip the transparent pixel
\r
584 MOVSB ; copy the pixel
\r
586 SUB CX, 3 ; we skip the next 3
\r
587 ADD SI, 3 ; skip the bmp pixels
\r
588 LOOP SCAN_LOOP ; finish the scan
\r
590 MOV AX, nextPageRow
\r
591 ADD DI, AX ; go to the next row on screen
\r
593 ADD SI, AX ; go to the next row on bmp
\r
596 JNZ ROW_LOOP ; do all the rows
\r
597 ;-- end plane painting
\r
599 MOV AL, plane ; advance to the next plane
\r
601 AND AL, 0x0f ; mask the plane properly
\r
602 MOV plane, AL ; store the plane
\r
604 INC bmpOffset ; start bmp at the right spot
\r
607 JNZ PLANE_LOOP ; do all 4 planes
\r
612 /* copy a region of video memory from one page to another.
\r
613 * It assumes that the left edge of the tile is the same on both
\r
614 * regions and the memory areas do not overlap.
\r
617 modexCopyPageRegion(page_t *dest, page_t *src,
\r
620 word width, word height)
\r
622 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
623 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
624 word scans = width/4;
\r
625 word nextSrcRow = src->width/4 - scans - 1;
\r
626 word nextDestRow = dest->width/4 - scans - 1;
\r
627 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
628 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
629 byte left = lclip[sx&0x03];
\r
630 byte right = rclip[(sx+width)&0x03];
\r
633 MOV AX, SCREEN_SEG ; work in the vga space
\r
638 MOV DX, GC_INDEX ; turn off cpu bits
\r
642 MOV AX, SC_INDEX ; point to the mask register
\r
652 MOV CX, scans ; the number of latches
\r
654 MOV AL, left ; do the left column
\r
659 MOV AL, 0fh ; do the inner columns
\r
661 REP MOVSB ; copy the pixels
\r
663 MOV AL, right ; do the right column
\r
668 MOV AX, SI ; go the start of the next row
\r
669 ADD AX, nextSrcRow ;
\r
672 ADD AX, nextDestRow ;
\r
675 DEC height ; do the rest of the actions
\r
678 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
679 MOV AL, 0ffh ; none from latches
\r
685 /* fade and flash */
\r
687 modexFadeOn(word fade, byte *palette) {
\r
688 fadePalette(-fade, 64, 64/fade+1, palette);
\r
693 modexFadeOff(word fade, byte *palette) {
\r
694 fadePalette(fade, 0, 64/fade+1, palette);
\r
699 modexFlashOn(word fade, byte *palette) {
\r
700 fadePalette(fade, -64, 64/fade+1, palette);
\r
705 modexFlashOff(word fade, byte *palette) {
\r
706 fadePalette(-fade, 0, 64/fade+1, palette);
\r
711 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
715 /* handle the case where we just update */
\r
717 modexPalUpdate1(palette);
\r
721 while(iter > 0) { /* FadeLoop */
\r
722 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
723 tmppal[i] = palette[i] - dim;
\r
724 if(tmppal[i] > 127) {
\r
726 } else if(tmppal[i] > 63) {
\r
730 modexPalUpdate1(tmppal);
\r
737 /* save and load */
\r
739 modexPalSave(byte *palette) {
\r
742 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
743 for(i=0; i<PAL_SIZE; i++) {
\r
744 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
752 ptr = malloc(PAL_SIZE);
\r
754 /* handle errors */
\r
756 printf("Could not allocate palette.\n");
\r
765 modexLoadPalFile(byte *filename, byte **palette) {
\r
769 /* free the palette if it exists */
\r
774 /* allocate the new palette */
\r
775 *palette = modexNewPal();
\r
777 /* open the file */
\r
778 file = fopen(filename, "rb");
\r
780 printf("Could not open palette file: %s\n", filename);
\r
784 /* read the file */
\r
786 while(!feof(file)) {
\r
787 *ptr++ = fgetc(file);
\r
795 modexSavePalFile(char *filename, byte *pal) {
\r
799 /* open the file for writing */
\r
800 file = fopen(filename, "wb");
\r
802 printf("Could not open %s for writing\n", filename);
\r
806 /* write the data to the file */
\r
807 fwrite(pal, 1, PAL_SIZE, file);
\r
815 fadePalette(-1, 64, 1, tmppal);
\r
821 fadePalette(-1, -64, 1, tmppal);
\r
827 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
829 byte *p = bmp->palette;
\r
833 static word a[PAL_SIZE]; //palette array of change values!
\r
834 word z=0, aq=0, aa=0, pp=0;
\r
839 memset(a, -1, sizeof(a));
\r
840 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
850 // printf("q: %02d\n", (q));
\r
851 // printf("qq: %02d\n", (qq));
\r
852 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
853 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
855 if((*i)<PAL_SIZE/2 && w==0)
\r
857 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
859 //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
860 //____ 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
861 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
866 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
868 //printf("qp=%d\n", qp);
\r
869 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
870 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
871 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
872 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
876 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
878 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
879 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
880 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
883 //if(qp>0) printf("qp=%d\n", qp);
\r
884 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
886 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
887 if((*i)>=PAL_SIZE/2 && w==0)
\r
889 for(; (*i)<PAL_SIZE; (*i)++)
\r
891 //____ 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
892 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
897 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
899 //printf("qp=%d\n", qp);
\r
900 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
901 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
902 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
903 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
907 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
908 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
909 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
912 //printf(" (*i)=%d\n", (*i)/3);
\r
915 printf("\nqqqqqqqq\n\n");
\r
921 long bufSize = (bmp->width * bmp->height);
\r
923 //printf("1(*i)=%02d\n", (*i)/3);
\r
924 //printf("1z=%02d\n", z/3);
\r
925 chkcolor(bmp, &q, &a, &aa, &z, i);
\r
926 //printf("2(*i)=%02d\n", (*i)/3);
\r
927 //printf("2z=%02d\n", z/3);
\r
932 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
933 if(a[aq]==-1) aq++;
\r
934 else { aqoffset++; break; }
\r
936 //update the image data here!
\r
937 for(lq=0; lq<bufSize; lq++)
\r
941 use a[qp] instead of bmp->offset for this spot!
\r
946 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
949 //(offset/bmp->offset)*bmp->offset
\r
952 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
953 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
954 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
955 /*if(bmp->data[lq]+bmp->offset==aq)
\r
957 //printf("%02d", bmp->data[lq]);
\r
958 //printf("\n%02d\n", bmp->offset);
\r
959 printf("aq=%02d ", aq);
\r
960 printf("a[aq]=%02d ", a[aq]);
\r
961 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
962 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
963 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
964 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
965 // printf("_%d ", bmp->data[lq]);
\r
966 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
968 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
970 if(bmp->data[lq]+bmp->offset >= aq)
\r
972 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
973 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
975 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
978 //printf("%02d`", bmp->data[lq]);
\r
979 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
982 //printf(" aq=%02d\n", aq);
\r
983 //printf(" aa=%02d\n", aa);
\r
985 //update the palette~
\r
986 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
989 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
994 modexPalUpdate1(byte *p)
\r
998 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
999 for(i=0; i<PAL_SIZE/2; i++)
\r
1001 outp(PAL_DATA_REG, p[i]);
\r
1003 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
1004 for(; i<PAL_SIZE; i++)
\r
1006 outp(PAL_DATA_REG, p[(i)]);
\r
1011 modexPalUpdate0(byte *p)
\r
1014 modexWaitBorder();
\r
1015 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
1016 for(i=0; i<PAL_SIZE/2; i++)
\r
1018 outp(PAL_DATA_REG, rand());
\r
1020 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
1021 for(; i<PAL_SIZE; i++)
\r
1023 outp(PAL_DATA_REG, rand());
\r
1028 //i want to make another vesion that checks the palette when the palette is being appened~
\r
1029 void chkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
1033 pal = modexNewPal();
\r
1034 modexPalSave(pal);
\r
1035 //printf("q: %02d\n", (*q));
\r
1036 printf("chkcolor start~\n");
\r
1037 printf("1 (*z): %d\n", (*z)/3);
\r
1038 printf("1 (*i): %d\n", (*i)/3);
\r
1039 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
1040 printf("wwwwwwwwwwwwwwww\n");
\r
1041 //check palette for dups
\r
1042 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
1044 //printf("\n z: %d\n", (*z));
\r
1045 //printf(" q: %d\n", (*q));
\r
1046 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
1049 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
1052 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1053 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
1057 else for(zz=0; zz<(*q); zz+=3)
\r
1059 //printf("zz: %02d\n", zz/3);
\r
1062 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
1066 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
1067 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
1070 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
1072 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
1073 // 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
1074 // 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
1075 // //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
1076 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1079 //expand dong here
\r
1081 planned features that i plan to implement~
\r
1082 image that has values on the pallete list!
\r
1084 no... wait.... no wwww
\r
1086 //for(zzii=0; zzii<3; zzii++)
\r
1088 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
1089 a[(((*z)+(*q)))]=zz;
\r
1091 (*aa)=(((*z)+(*q)));
\r
1092 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
1093 // printf("\n aa: %d\n\n", (*aa));
\r
1094 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
1095 // printf("wwwwwwwwwwwwwwww\n\n");
\r
1099 printf("================\n");
\r
1100 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
1101 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
1102 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1103 printf("================\n");
\r
1105 //printf("[%d]", (zz+q));
\r
1109 printf("wwwwwwwwwwwwwwww\n");
\r
1110 printf("2 (*z): %d\n", (*z)/3);
\r
1111 printf("2 (*i): %d\n", (*i)/3);
\r
1112 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
1113 printf("chkcolor end~\n");
\r
1117 void modexputPixel(page_t *page, int x, int y, byte color)
\r
1119 word pageOff = (word) page->data;
\r
1120 /* Each address accesses four neighboring pixels, so set
\r
1121 Write Plane Enable according to which pixel we want
\r
1122 to modify. The plane is determined by the two least
\r
1123 significant bits of the x-coordinate: */
\r
1124 modexSelectPlane(PLANE(x));
\r
1125 //outp(SC_INDEX, 0x02);
\r
1126 //outp(SC_DATA, 0x01 << (x & 3));
\r
1128 /* The offset of the pixel into the video segment is
\r
1129 offset = (width * y + x) / 4, and write the given
\r
1130 color to the plane we selected above. Heed the active
\r
1131 page start selection. */
\r
1132 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
1136 byte modexgetPixel(page_t *page, int x, int y)
\r
1138 word pageOff = (word) page->data;
\r
1139 /* Select the plane from which we must read the pixel color: */
\r
1140 outpw(GC_INDEX, 0x04);
\r
1141 outpw(GC_INDEX+1, x & 3);
\r
1143 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
1147 void modexhlin(page_t *page, word xl, word xh, word y, word color)
\r
1152 for(x=0;x<xh*4;x+=4)
\r
1154 if(x+4>=SCREEN_WIDTH-1){ x=0; yy+=4; }
\r
1155 modexClearRegion(page, x+xl, y+yy, 4, 4, color);
\r
1157 //modexputPixel(page, x+xl, y, color);
\r
1160 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1162 word i, s, o, w, j, xp;
\r
1164 word addr = (word) l;
\r
1188 s=romFonts[t].seg;
\r
1189 o=romFonts[t].off;
\r
1191 for(; *str != '\0'; str++)
\r
1194 if((c=='\n'/* || c=="\
\r
1202 //load the letter 'A'
\r
1208 MOV AL, c ; the letter
\r
1211 ADD SI, AX ;the address of charcter
\r
1220 for(i=0; i<w; i++)
\r
1226 modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1235 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1237 word i, s, o, w, j, xp;
\r
1239 word addr = (word) l;
\r
1263 s=romFonts[t].seg;
\r
1264 o=romFonts[t].off;
\r
1266 for(; *str != '\0'; str++)
\r
1269 if((c=='\n'/* || c=="\
\r
1270 "*/)/* || chw>=page->width*/)
\r
1276 //load the letter 'A'
\r
1282 MOV AL, c ; the letter
\r
1285 ADD SI, AX ;the address of charcter
\r
1294 for(i=0; i<w; i++)
\r
1300 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1301 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1310 /* palette dump on display! */
\r
1311 void pdump(page_t *pee)
\r
1313 int mult=(QUADWH);
\r
1314 int palq=(mult)*TILEWH;
\r
1317 for(paly=0; paly<palq; paly+=mult){
\r
1318 for(palx=0; palx<palq; palx+=mult){
\r
1319 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
\r
1325 /////////////////////////////////////////////////////////////////////////////
\r
1327 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1328 // the Virtual screen. //
\r
1330 /////////////////////////////////////////////////////////////////////////////
\r
1331 void cls(page_t *page, byte color, byte *Where)
\r
1333 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1334 /* set map mask to all 4 planes */
\r
1335 outpw(SC_INDEX, 0xff02);
\r
1336 //_fmemset(VGA, color, 16000);
\r
1337 _fmemset(Where, color, page->width*(page->height));
\r
1341 modexWaitBorder() {
\r
1342 while(inp(INPUT_STATUS_1) & 8) {
\r
1346 while(!(inp(INPUT_STATUS_1) & 8)) {
\r