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
34 /////////////////////////////////////////////////////////////////////////////
\r
36 // setvideo() - This function Manages the video modes //
\r
38 /////////////////////////////////////////////////////////////////////////////
\r
39 void VGAmodeX(sword vq, global_game_variables_t *gv)
\r
45 case 0: // deinit the video
\r
46 // change to the video mode we were in before we switched to mode 13h
\r
49 in.h.al = gv->old_mode;
\r
50 int86(0x10, &in, &out);
\r
52 case 1: // init the video
\r
53 // get old video mode
\r
55 //int86(0x10, &in, &out);
\r
56 gv->old_mode = vgaGetMode();//out.h.al;
\r
58 modex__320x240_256__Enter(gv);
\r
60 case 2: // init the video
\r
61 // get old video mode
\r
63 int86(0x10, &in, &out);
\r
64 gv->old_mode = out.h.al;
\r
66 modex__192x144_256__Enter(gv);
\r
72 vgaSetMode(byte mode)
\r
76 regs.h.ah = SET_MODE;
\r
78 int86(VIDEO_INT, ®s, ®s);
\r
81 //---------------------------------------------------
\r
83 // Use the bios to get the current video mode
\r
92 int86(VIDEO_INT, &rg, &rg);
\r
97 /* -========================= Entry Points ==========================- */
\r
99 modex__320x240_256__Enter(global_game_variables_t *gv)
\r
102 dword far*ptr=(dword far*)VGA; /* used for faster screen clearing */
\r
104 int CRTParmCount = sizeof(ModeX_320x240regs) / sizeof(ModeX_320x240regs[0]);
\r
105 /* width and height */
\r
108 /* common mode X initiation stuff~ */
\r
109 modexsetBaseXMode();
\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
124 modex__192x144_256__Enter(global_game_variables_t *gv)
\r
127 dword far*ptr=(dword far*)VGA; /* used for faster screen clearing */
\r
129 int CRTParmCount = sizeof(ModeX_192x144regs) / sizeof(ModeX_192x144regs[0]);
\r
130 /* width and height */
\r
133 /* common mode X initiation stuff~ */
\r
134 modexsetBaseXMode();
\r
136 /* send the CRTParms */
\r
137 for(i=0; i<CRTParmCount; i++) {
\r
138 outpw(CRTC_INDEX, ModeX_192x144regs[i]);
\r
141 /* clear video memory */
\r
142 outpw(SC_INDEX, 0x0f02);
\r
143 for(i=0; i<0x8000; i++) {
\r
150 /* TODO restore original mode and palette */
\r
151 vgaSetMode(TEXT_MODE);
\r
154 // setBaseXMode() does the initialization to make the VGA ready to
\r
155 // accept any combination of configuration register settings. This
\r
156 // involves enabling writes to index 0 to 7 of the CRT controller (port
\r
157 // 0x3D4), by clearing the most significant bit (bit 7) of index 0x11.
\r
159 modexsetBaseXMode(void)
\r
162 /* TODO save current video mode and palette */
\r
163 vgaSetMode(VGA_256_COLOR_MODE);
\r
165 /* disable chain4 mode */
\r
166 outpw(SC_INDEX, 0x0604);
\r
168 /* synchronous reset while setting Misc Output */
\r
169 outpw(SC_INDEX, 0x0100);
\r
171 /* select 25 MHz dot clock & 60 Hz scanning rate */
\r
172 outp(MISC_OUTPUT, 0xe3);
\r
174 /* undo reset (restart sequencer) */
\r
175 outpw(SC_INDEX, 0x0300);
\r
177 /* reprogram the CRT controller */
\r
178 outp(CRTC_INDEX, 0x11); /* VSync End reg contains register write prot */
\r
179 // temp = inp(CRTC_DATA) & 0x7F;
\r
180 // outp(CRTC_INDEX, 0x11);
\r
181 outp(CRTC_DATA, 0x7f); /* get current write protect on varios regs */
\r
182 // outp(CRTC_DATA, temp); /* get current write protect on varios regs */
\r
186 modexDefaultPage() {
\r
189 /* default page values */
\r
193 page.width = SCREEN_WIDTH;
\r
194 page.height = SCREEN_HEIGHT;
\r
195 page.tw = page.width/TILEWH;
\r
196 page.th = page.height/TILEWH;
\r
202 /* returns the next page in contiguous memory
\r
203 * the next page will be the same size as p, by default
\r
206 modexNextPage(page_t *p) {
\r
209 result.data = p->data + (p->width/4)*p->height;
\r
212 result.width = p->width;
\r
213 result.height = p->height;
\r
214 result.tw = p->width/TILEWH;
\r
215 result.th = p->height/TILEWH;
\r
216 result.id = p->id+1;
\r
219 // return modexNextPageFlexibleSize(&p, p->width, p->height);
\r
222 //next page with defined dimentions~
\r
224 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
228 result.data = p->data + (p->width/4)*p->height; /* compute the offset */
\r
233 result.tw = p->width/TILEWH;
\r
234 result.th = p->height/TILEWH;
\r
235 result.id = p->id+1;
\r
242 modexShowPage(page_t *page) {
\r
248 /* calculate offset */
\r
249 offset = (word) page->data;
\r
250 offset += page->dy * (page->width >> 2 );
\r
251 offset += page->dx >> 2;
\r
253 /* calculate crtcOffset according to virtual width */
\r
254 crtcOffset = page->width >> 3;
\r
256 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
257 low_address = LOW_ADDRESS | (offset << 8);
\r
259 /* wait for appropriate timing and then program CRTC */
\r
260 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
261 outpw(CRTC_INDEX, high_address);
\r
262 outpw(CRTC_INDEX, low_address);
\r
263 outp(CRTC_INDEX, 0x13);
\r
264 outp(CRTC_DATA, crtcOffset);
\r
266 /* wait for one retrace */
\r
267 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
269 /* do PEL panning here */
\r
270 outp(AC_INDEX, 0x33);
\r
271 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
276 modexPanPage(page_t *page, int dx, int dy) {
\r
283 modexSelectPlane(byte plane) {
\r
284 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
285 outp(SC_DATA, plane);
\r
290 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
291 word pageOff = (word) page->data;
\r
292 word xoff=x/4; /* xoffset that begins each row */
\r
293 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
294 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
295 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
296 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
297 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
298 byte left = lclip[x&0x03];
\r
299 byte right = rclip[(x+w)&0x03];
\r
301 /* handle the case which requires an extra group */
\r
302 if((x & 0x03) && !((x+w) & 0x03)) {
\r
307 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
309 MOV DI, poffset ; go to the first pixel
\r
310 MOV DX, SC_INDEX ; point to the map mask
\r
314 MOV AL, color ; get ready to write colors
\r
316 MOV CX, scanCount ; count the line
\r
317 MOV BL, AL ; remember color
\r
318 MOV AL, left ; do the left clip
\r
319 OUT DX, AL ; set the left clip
\r
320 MOV AL, BL ; restore color
\r
321 STOSB ; write the color
\r
323 JZ SCAN_DONE ; handle 1 group stuff
\r
325 ;-- write the main body of the scanline
\r
326 MOV BL, AL ; remember color
\r
327 MOV AL, 0x0f ; write to all pixels
\r
329 MOV AL, BL ; restore color
\r
330 REP STOSB ; write the color
\r
332 MOV BL, AL ; remeber color
\r
334 OUT DX, AL ; do the right clip
\r
335 MOV AL, BL ; restore color
\r
336 STOSB ; write pixel
\r
337 ADD DI, nextRow ; go to the next row
\r
345 oldDrawBmp(byte far* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
351 /* TODO Make this fast. It's SLOOOOOOW */
\r
352 for(plane=0; plane < 4; plane++) {
\r
353 modexSelectPlane(PLANE(plane+x));
\r
354 for(px = plane; px < bmp->width; px+=4) {
\r
356 for(py=0; py<bmp->height; py++) {
\r
357 if(!sprite || bmp->data[offset])
\r
358 page[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
359 offset+=bmp->width;
\r
366 CDrawBmp(byte far* vgamem, page_t* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
373 /* TODO Make this fast. It's SLOOOOOOW */
\r
374 for(plane=0; plane < 4; plane++) {
\r
375 modexSelectPlane(PLANE(plane+x));
\r
376 for(px = plane; px < bmp->width; px+=4) {
\r
378 for(py=0; py<bmp->height; py++) {
\r
379 if(!sprite || bmp->data[offset])
\r
380 //modexputPixel(page, x+px, y+py, bmp->data[offset]);
\r
381 vgamem[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
382 offset+=bmp->width;
\r
389 modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) {
\r
390 /* draw the region (the entire freakin bitmap) */
\r
391 modexDrawBmpRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
396 modexDrawBmpRegion(page_t *page, int x, int y,
\r
397 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
398 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
399 byte far *data = bmp->data;//+bmp->offset;
\r
400 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
403 byte plane = 1 << ((byte) x & 0x03);
\r
404 word scanCount = width/4 + (width%4 ? 1 :0);
\r
405 word nextPageRow = page->width/4 - scanCount;
\r
406 word nextBmpRow = (word) bmp->width - width;
\r
408 byte planeCounter = 4;
\r
410 /* printf("bmp->data=%Fp\n",bmp->data);
\r
411 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
412 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
414 //code is a bit slow here
\r
416 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
419 MOV DX, SC_INDEX ; point at the map mask register
\r
424 MOV DX, SC_DATA ; select the current plane
\r
428 ;-- begin plane painting
\r
429 MOV AX, height ; start the row counter
\r
430 MOV rowCounter, AX ;
\r
431 MOV DI, poffset ; go to the first pixel
\r
432 MOV SI, bmpOffset ; go to the bmp pixel
\r
434 MOV CX, width ; count the columns
\r
436 MOVSB ; copy the pixel
\r
437 SUB CX, 3 ; we skip the next 3
\r
438 ADD SI, 3 ; skip the bmp pixels
\r
439 LOOP SCAN_LOOP ; finish the scan
\r
441 MOV AX, nextPageRow
\r
442 ADD DI, AX ; go to the next row on screen
\r
444 ADD SI, AX ; go to the next row on bmp
\r
447 JNZ ROW_LOOP ; do all the rows
\r
448 ;-- end plane painting
\r
450 MOV AL, plane ; advance to the next plane
\r
452 AND AL, 0x0f ; mask the plane properly
\r
453 MOV plane, AL ; store the plane
\r
455 INC bmpOffset ; start bmp at the right spot
\r
458 JNZ PLANE_LOOP ; do all 4 planes
\r
463 modex_sparky4_DrawBmpRegion(page_t *page, int x, int y,
\r
464 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
465 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
466 byte far *data = bmp->data;//+bmp->offset;
\r
467 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
470 byte plane = 1 << ((byte) x & 0x03);
\r
471 word scanCount = width/4 + (width%4 ? 1 :0);
\r
472 word nextPageRow = page->width/4 - scanCount;
\r
473 word nextBmpRow = (word) bmp->width - width;
\r
475 byte planeCounter = 4;
\r
477 /* printf("bmp->data=%Fp\n",bmp->data);
\r
478 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
479 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
481 //code is a bit slow here
\r
483 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
486 MOV DX, SC_INDEX ; point at the map mask register
\r
491 MOV DX, SC_DATA ; select the current plane
\r
495 ;-- begin plane painting
\r
496 MOV AX, height ; start the row counter
\r
497 MOV rowCounter, AX ;
\r
498 MOV DI, poffset ; go to the first pixel
\r
499 MOV SI, bmpOffset ; go to the bmp pixel
\r
501 MOV CX, width ; count the columns
\r
503 MOVSB ; copy the pixel
\r
504 SUB CX, 3 ; we skip the next 3
\r
505 ADD SI, 3 ; skip the bmp pixels
\r
506 LOOP SCAN_LOOP ; finish the scan
\r
508 MOV AX, nextPageRow
\r
509 ADD DI, AX ; go to the next row on screen
\r
511 ADD SI, AX ; go to the next row on bmp
\r
514 JNZ ROW_LOOP ; do all the rows
\r
515 ;-- end plane painting
\r
517 MOV AL, plane ; advance to the next plane
\r
519 AND AL, 0x0f ; mask the plane properly
\r
520 MOV plane, AL ; store the plane
\r
522 INC bmpOffset ; start bmp at the right spot
\r
525 JNZ PLANE_LOOP ; do all 4 planes
\r
530 modexDrawPlanarBuf(page_t *page, int x, int y, planar_buf_t *bmp) {
\r
531 /* TODO - adapt from test code */
\r
533 for(plane=0; plane < 4; plane++)
\r
541 modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp) {
\r
542 /* draw the whole sprite */
\r
543 modexDrawSpriteRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
547 modexDrawSpriteRegion(page_t *page, int x, int y,
\r
548 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
549 word poffset = (word)page->data + y*(page->width/4) + x/4;
\r
550 byte *data = bmp->data;//+bmp->offset;
\r
551 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
554 byte plane = 1 << ((byte) x & 0x03);
\r
555 word scanCount = width/4 + (width%4 ? 1 :0);
\r
556 word nextPageRow = page->width/4 - scanCount;
\r
557 word nextBmpRow = (word) bmp->width - width;
\r
559 byte planeCounter = 4;
\r
562 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
565 MOV DX, SC_INDEX ; point at the map mask register
\r
570 MOV DX, SC_DATA ; select the current plane
\r
574 ;-- begin plane painting
\r
575 MOV AX, height ; start the row counter
\r
576 MOV rowCounter, AX ;
\r
577 MOV DI, poffset ; go to the first pixel
\r
578 MOV SI, bmpOffset ; go to the bmp pixel
\r
580 MOV CX, width ; count the columns
\r
585 JNE DRAW_PIXEL ; draw non-zero pixels
\r
587 INC DI ; skip the transparent pixel
\r
591 MOVSB ; copy the pixel
\r
593 SUB CX, 3 ; we skip the next 3
\r
594 ADD SI, 3 ; skip the bmp pixels
\r
595 LOOP SCAN_LOOP ; finish the scan
\r
597 MOV AX, nextPageRow
\r
598 ADD DI, AX ; go to the next row on screen
\r
600 ADD SI, AX ; go to the next row on bmp
\r
603 JNZ ROW_LOOP ; do all the rows
\r
604 ;-- end plane painting
\r
606 MOV AL, plane ; advance to the next plane
\r
608 AND AL, 0x0f ; mask the plane properly
\r
609 MOV plane, AL ; store the plane
\r
611 INC bmpOffset ; start bmp at the right spot
\r
614 JNZ PLANE_LOOP ; do all 4 planes
\r
619 /* copy a region of video memory from one page to another.
\r
620 * It assumes that the left edge of the tile is the same on both
\r
621 * regions and the memory areas do not overlap.
\r
624 modexCopyPageRegion(page_t *dest, page_t *src,
\r
627 word width, word height)
\r
629 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
630 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
631 word scans = width/4;
\r
632 word nextSrcRow = src->width/4 - scans - 1;
\r
633 word nextDestRow = dest->width/4 - scans - 1;
\r
634 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
635 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
636 byte left = lclip[sx&0x03];
\r
637 byte right = rclip[(sx+width)&0x03];
\r
640 MOV AX, SCREEN_SEG ; work in the vga space
\r
645 MOV DX, GC_INDEX ; turn off cpu bits
\r
649 MOV AX, SC_INDEX ; point to the mask register
\r
659 MOV CX, scans ; the number of latches
\r
661 MOV AL, left ; do the left column
\r
666 MOV AL, 0fh ; do the inner columns
\r
668 REP MOVSB ; copy the pixels
\r
670 MOV AL, right ; do the right column
\r
675 MOV AX, SI ; go the start of the next row
\r
676 ADD AX, nextSrcRow ;
\r
679 ADD AX, nextDestRow ;
\r
682 DEC height ; do the rest of the actions
\r
685 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
686 MOV AL, 0ffh ; none from latches
\r
692 /* fade and flash */
\r
694 modexFadeOn(word fade, byte *palette) {
\r
695 fadePalette(-fade, 64, 64/fade+1, palette);
\r
700 modexFadeOff(word fade, byte *palette) {
\r
701 fadePalette(fade, 0, 64/fade+1, palette);
\r
706 modexFlashOn(word fade, byte *palette) {
\r
707 fadePalette(fade, -64, 64/fade+1, palette);
\r
712 modexFlashOff(word fade, byte *palette) {
\r
713 fadePalette(-fade, 0, 64/fade+1, palette);
\r
718 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
722 /* handle the case where we just update */
\r
724 modexPalUpdate1(palette);
\r
728 while(iter > 0) { /* FadeLoop */
\r
729 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
730 tmppal[i] = palette[i] - dim;
\r
731 if(tmppal[i] > 127) {
\r
733 } else if(tmppal[i] > 63) {
\r
737 modexPalUpdate1(tmppal);
\r
744 /* save and load */
\r
746 modexPalSave(byte *palette) {
\r
749 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
750 for(i=0; i<PAL_SIZE; i++) {
\r
751 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
759 ptr = malloc(PAL_SIZE);
\r
761 /* handle errors */
\r
763 printf("Could not allocate palette.\n");
\r
772 modexLoadPalFile(byte *filename, byte **palette) {
\r
776 /* free the palette if it exists */
\r
781 /* allocate the new palette */
\r
782 *palette = modexNewPal();
\r
784 /* open the file */
\r
785 file = fopen(filename, "rb");
\r
787 printf("Could not open palette file: %s\n", filename);
\r
791 /* read the file */
\r
793 while(!feof(file)) {
\r
794 *ptr++ = fgetc(file);
\r
802 modexSavePalFile(char *filename, byte *pal) {
\r
806 /* open the file for writing */
\r
807 file = fopen(filename, "wb");
\r
809 printf("Could not open %s for writing\n", filename);
\r
813 /* write the data to the file */
\r
814 fwrite(pal, 1, PAL_SIZE, file);
\r
822 fadePalette(-1, 64, 1, tmppal);
\r
828 fadePalette(-1, -64, 1, tmppal);
\r
834 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
836 byte *p = bmp->palette;
\r
840 static word a[PAL_SIZE]; //palette array of change values!
\r
841 word z=0, aq=0, aa=0, pp=0;
\r
846 memset(a, -1, sizeof(a));
\r
847 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
857 // printf("q: %02d\n", (q));
\r
858 // printf("qq: %02d\n", (qq));
\r
859 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
860 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
862 if((*i)<PAL_SIZE/2 && w==0)
\r
864 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
866 //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
867 //____ 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
868 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
873 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
875 //printf("qp=%d\n", qp);
\r
876 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
877 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
878 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
879 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
883 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
885 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
886 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
887 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
890 //if(qp>0) printf("qp=%d\n", qp);
\r
891 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
893 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
894 if((*i)>=PAL_SIZE/2 && w==0)
\r
896 for(; (*i)<PAL_SIZE; (*i)++)
\r
898 //____ 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
899 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
904 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
906 //printf("qp=%d\n", qp);
\r
907 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
908 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
909 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
910 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
914 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
915 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
916 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
919 //printf(" (*i)=%d\n", (*i)/3);
\r
922 printf("\nqqqqqqqq\n\n");
\r
928 long bufSize = (bmp->width * bmp->height);
\r
930 //printf("1(*i)=%02d\n", (*i)/3);
\r
931 //printf("1z=%02d\n", z/3);
\r
932 chkcolor(bmp, &q, &a, &aa, &z, i);
\r
933 //printf("2(*i)=%02d\n", (*i)/3);
\r
934 //printf("2z=%02d\n", z/3);
\r
939 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
940 if(a[aq]==-1) aq++;
\r
941 else { aqoffset++; break; }
\r
943 //update the image data here!
\r
944 for(lq=0; lq<bufSize; lq++)
\r
948 use a[qp] instead of bmp->offset for this spot!
\r
953 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
956 //(offset/bmp->offset)*bmp->offset
\r
959 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
960 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
961 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
962 /*if(bmp->data[lq]+bmp->offset==aq)
\r
964 //printf("%02d", bmp->data[lq]);
\r
965 //printf("\n%02d\n", bmp->offset);
\r
966 printf("aq=%02d ", aq);
\r
967 printf("a[aq]=%02d ", a[aq]);
\r
968 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
969 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
970 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
971 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
972 // printf("_%d ", bmp->data[lq]);
\r
973 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
975 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
977 if(bmp->data[lq]+bmp->offset >= aq)
\r
979 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
980 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
982 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
985 //printf("%02d`", bmp->data[lq]);
\r
986 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
989 //printf(" aq=%02d\n", aq);
\r
990 //printf(" aa=%02d\n", aa);
\r
992 //update the palette~
\r
993 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
996 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
1001 modexPalUpdate1(byte *p)
\r
1004 modexWaitBorder();
\r
1005 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
1006 for(i=0; i<PAL_SIZE/2; i++)
\r
1008 outp(PAL_DATA_REG, p[i]);
\r
1010 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
1011 for(; i<PAL_SIZE; i++)
\r
1013 outp(PAL_DATA_REG, p[(i)]);
\r
1018 modexPalUpdate0(byte *p)
\r
1021 modexWaitBorder();
\r
1022 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
1023 for(i=0; i<PAL_SIZE/2; i++)
\r
1025 outp(PAL_DATA_REG, rand());
\r
1027 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
1028 for(; i<PAL_SIZE; i++)
\r
1030 outp(PAL_DATA_REG, rand());
\r
1035 //i want to make another vesion that checks the palette when the palette is being appened~
\r
1036 void chkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
1040 pal = modexNewPal();
\r
1041 modexPalSave(pal);
\r
1042 //printf("q: %02d\n", (*q));
\r
1043 printf("chkcolor start~\n");
\r
1044 printf("1 (*z): %d\n", (*z)/3);
\r
1045 printf("1 (*i): %d\n", (*i)/3);
\r
1046 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
1047 printf("wwwwwwwwwwwwwwww\n");
\r
1048 //check palette for dups
\r
1049 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
1051 //printf("\n z: %d\n", (*z));
\r
1052 //printf(" q: %d\n", (*q));
\r
1053 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
1056 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
1059 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1060 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
1064 else for(zz=0; zz<(*q); zz+=3)
\r
1066 //printf("zz: %02d\n", zz/3);
\r
1069 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
1073 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
1074 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
1077 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
1079 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
1080 // 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
1081 // 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
1082 // //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
1083 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1086 //expand dong here
\r
1088 planned features that i plan to implement~
\r
1089 image that has values on the pallete list!
\r
1091 no... wait.... no wwww
\r
1093 //for(zzii=0; zzii<3; zzii++)
\r
1095 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
1096 a[(((*z)+(*q)))]=zz;
\r
1098 (*aa)=(((*z)+(*q)));
\r
1099 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
1100 // printf("\n aa: %d\n\n", (*aa));
\r
1101 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
1102 // printf("wwwwwwwwwwwwwwww\n\n");
\r
1106 printf("================\n");
\r
1107 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
1108 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
1109 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1110 printf("================\n");
\r
1112 //printf("[%d]", (zz+q));
\r
1116 printf("wwwwwwwwwwwwwwww\n");
\r
1117 printf("2 (*z): %d\n", (*z)/3);
\r
1118 printf("2 (*i): %d\n", (*i)/3);
\r
1119 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
1120 printf("chkcolor end~\n");
\r
1124 void modexputPixel(page_t *page, int x, int y, byte color)
\r
1126 word pageOff = (word) page->data;
\r
1127 /* Each address accesses four neighboring pixels, so set
\r
1128 Write Plane Enable according to which pixel we want
\r
1129 to modify. The plane is determined by the two least
\r
1130 significant bits of the x-coordinate: */
\r
1131 modexSelectPlane(PLANE(x));
\r
1132 //outp(SC_INDEX, 0x02);
\r
1133 //outp(SC_DATA, 0x01 << (x & 3));
\r
1135 /* The offset of the pixel into the video segment is
\r
1136 offset = (width * y + x) / 4, and write the given
\r
1137 color to the plane we selected above. Heed the active
\r
1138 page start selection. */
\r
1139 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
1143 byte modexgetPixel(page_t *page, int x, int y)
\r
1145 word pageOff = (word) page->data;
\r
1146 /* Select the plane from which we must read the pixel color: */
\r
1147 outpw(GC_INDEX, 0x04);
\r
1148 outpw(GC_INDEX+1, x & 3);
\r
1150 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
1154 void modexhlin(page_t *page, word xl, word xh, word y, word color)
\r
1159 for(x=0;x<xh*4;x+=4)
\r
1161 if(x+4>=SCREEN_WIDTH-1){ x=0; yy+=4; }
\r
1162 modexClearRegion(page, x+xl, y+yy, 4, 4, color);
\r
1164 //modexputPixel(page, x+xl, y, color);
\r
1167 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1169 word i, s, o, w, j, xp;
\r
1171 word addr = (word) l;
\r
1195 s=romFonts[t].seg;
\r
1196 o=romFonts[t].off;
\r
1198 for(; *str != '\0'; str++)
\r
1201 if((c=='\n'/* || c=="\
\r
1209 //load the letter 'A'
\r
1215 MOV AL, c ; the letter
\r
1218 ADD SI, AX ;the address of charcter
\r
1227 for(i=0; i<w; i++)
\r
1233 modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1242 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1244 word i, s, o, w, j, xp;
\r
1246 word addr = (word) l;
\r
1270 s=romFonts[t].seg;
\r
1271 o=romFonts[t].off;
\r
1273 for(; *str != '\0'; str++)
\r
1276 if((c=='\n'/* || c=="\
\r
1277 "*/)/* || chw>=page->width*/)
\r
1283 //load the letter 'A'
\r
1289 MOV AL, c ; the letter
\r
1292 ADD SI, AX ;the address of charcter
\r
1301 for(i=0; i<w; i++)
\r
1307 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1308 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1317 /////////////////////////////////////////////////////////////////////////////
\r
1319 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1320 // the Virtual screen. //
\r
1322 /////////////////////////////////////////////////////////////////////////////
\r
1323 void cls(page_t *page, byte color, byte *Where)
\r
1325 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1326 /* set map mask to all 4 planes */
\r
1327 outpw(SC_INDEX, 0xff02);
\r
1328 //_fmemset(VGA, color, 16000);
\r
1329 _fmemset(Where, color, page->width*(page->height));
\r
1333 modexWaitBorder() {
\r
1334 while(inp(INPUT_STATUS_1) & 8) {
\r
1338 while(!(inp(INPUT_STATUS_1) & 8)) {
\r