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
44 { // 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->old_mode;
\r
49 int86(0x10, &in, &out);
\r
54 // get old video mode
\r
56 int86(0x10, &in, &out);
\r
57 gv->old_mode = out.h.al;
\r
64 vgaSetMode(byte mode)
\r
68 regs.h.ah = SET_MODE;
\r
70 int86(VIDEO_INT, ®s, ®s);
\r
74 /* -========================= Entry Points ==========================- */
\r
78 dword far*ptr=(dword far*)VGA; /* used for faster screen clearing */
\r
80 0x0d06, /* vertical total */
\r
81 0x3e07, /* overflow (bit 8 of vertical counts) */
\r
82 0x4109, /* cell height (2 to double-scan */
\r
83 0xea10, /* v sync start */
\r
84 0xac11, /* v sync end and protect cr0-cr7 */
\r
85 0xdf12, /* vertical displayed */
\r
86 0x2013, /* offset/logical width */
\r
87 0x0014, /* turn off dword mode */
\r
88 0xe715, /* v blank start */
\r
89 0x0616, /* v blank end */
\r
90 0xe317 /* turn on byte mode */
\r
92 int CRTParmCount = sizeof(CRTParms) / sizeof(CRTParms[0]);
\r
94 /* TODO save current video mode and palette */
\r
95 vgaSetMode(VGA_256_COLOR_MODE);
\r
97 /* disable chain4 mode */
\r
98 outpw(SC_INDEX, 0x0604);
\r
100 /* synchronous reset while setting Misc Output */
\r
101 outpw(SC_INDEX, 0x0100);
\r
103 /* select 25 MHz dot clock & 60 Hz scanning rate */
\r
104 outp(MISC_OUTPUT, 0xe3);
\r
106 /* undo reset (restart sequencer) */
\r
107 outpw(SC_INDEX, 0x0300);
\r
109 /* reprogram the CRT controller */
\r
110 outp(CRTC_INDEX, 0x11); /* VSync End reg contains register write prot */
\r
111 outp(CRTC_DATA, 0x7f); /* get current write protect on varios regs */
\r
113 /* send the CRTParms */
\r
114 for(i=0; i<CRTParmCount; i++) {
\r
115 outpw(CRTC_INDEX, CRTParms[i]);
\r
118 /* clear video memory */
\r
119 outpw(SC_INDEX, 0x0f02);
\r
120 for(i=0; i<0x8000; i++) {
\r
128 /* TODO restore original mode and palette */
\r
129 vgaSetMode(TEXT_MODE);
\r
134 modexDefaultPage() {
\r
137 /* default page values */
\r
141 page.width = SCREEN_WIDTH;
\r
142 page.height = SCREEN_HEIGHT;
\r
143 page.tw = page.width/TILEWH;
\r
144 page.th = page.height/TILEWH;
\r
150 /* returns the next page in contiguous memory
\r
151 * the next page will be the same size as p, by default
\r
154 modexNextPage(page_t *p) {
\r
157 result.data = p->data + (p->width/4)*p->height;
\r
160 result.width = p->width;
\r
161 result.height = p->height;
\r
162 result.tw = p->width/TILEWH;
\r
163 result.th = p->height/TILEWH;
\r
164 result.id = p->id+1;
\r
167 // return modexNextPageFlexibleSize(&p, p->width, p->height);
\r
170 //next page with defined dimentions~
\r
172 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
176 result.data = p->data + (p->width/4)*p->height; /* compute the offset */
\r
181 result.tw = p->width/TILEWH;
\r
182 result.th = p->height/TILEWH;
\r
183 result.id = p->id+1;
\r
190 modexShowPage(page_t *page) {
\r
196 /* calculate offset */
\r
197 offset = (word) page->data;
\r
198 offset += page->dy * (page->width >> 2 );
\r
199 offset += page->dx >> 2;
\r
201 /* calculate crtcOffset according to virtual width */
\r
202 crtcOffset = page->width >> 3;
\r
204 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
205 low_address = LOW_ADDRESS | (offset << 8);
\r
207 /* wait for appropriate timing and then program CRTC */
\r
208 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
209 outpw(CRTC_INDEX, high_address);
\r
210 outpw(CRTC_INDEX, low_address);
\r
211 outp(CRTC_INDEX, 0x13);
\r
212 outp(CRTC_DATA, crtcOffset);
\r
214 /* wait for one retrace */
\r
215 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
217 /* do PEL panning here */
\r
218 outp(AC_INDEX, 0x33);
\r
219 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
224 modexPanPage(page_t *page, int dx, int dy) {
\r
231 modexSelectPlane(byte plane) {
\r
232 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
233 outp(SC_DATA, plane);
\r
238 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
239 word pageOff = (word) page->data;
\r
240 word xoff=x/4; /* xoffset that begins each row */
\r
241 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
242 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
243 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
244 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
245 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
246 byte left = lclip[x&0x03];
\r
247 byte right = rclip[(x+w)&0x03];
\r
249 /* handle the case which requires an extra group */
\r
250 if((x & 0x03) && !((x+w) & 0x03)) {
\r
255 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
257 MOV DI, poffset ; go to the first pixel
\r
258 MOV DX, SC_INDEX ; point to the map mask
\r
262 MOV AL, color ; get ready to write colors
\r
264 MOV CX, scanCount ; count the line
\r
265 MOV BL, AL ; remember color
\r
266 MOV AL, left ; do the left clip
\r
267 OUT DX, AL ; set the left clip
\r
268 MOV AL, BL ; restore color
\r
269 STOSB ; write the color
\r
271 JZ SCAN_DONE ; handle 1 group stuff
\r
273 ;-- write the main body of the scanline
\r
274 MOV BL, AL ; remember color
\r
275 MOV AL, 0x0f ; write to all pixels
\r
277 MOV AL, BL ; restore color
\r
278 REP STOSB ; write the color
\r
280 MOV BL, AL ; remeber color
\r
282 OUT DX, AL ; do the right clip
\r
283 MOV AL, BL ; restore color
\r
284 STOSB ; write pixel
\r
285 ADD DI, nextRow ; go to the next row
\r
293 oldDrawBmp(byte far* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
299 /* TODO Make this fast. It's SLOOOOOOW */
\r
300 for(plane=0; plane < 4; plane++) {
\r
301 modexSelectPlane(PLANE(plane+x));
\r
302 for(px = plane; px < bmp->width; px+=4) {
\r
304 for(py=0; py<bmp->height; py++) {
\r
305 if(!sprite || bmp->data[offset])
\r
306 page[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
307 offset+=bmp->width;
\r
314 CDrawBmp(byte far* vgamem, page_t* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
321 /* TODO Make this fast. It's SLOOOOOOW */
\r
322 for(plane=0; plane < 4; plane++) {
\r
323 modexSelectPlane(PLANE(plane+x));
\r
324 for(px = plane; px < bmp->width; px+=4) {
\r
326 for(py=0; py<bmp->height; py++) {
\r
327 if(!sprite || bmp->data[offset])
\r
328 //modexputPixel(page, x+px, y+py, bmp->data[offset]);
\r
329 vgamem[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
330 offset+=bmp->width;
\r
337 modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) {
\r
338 /* draw the region (the entire freakin bitmap) */
\r
339 modexDrawBmpRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
344 modexDrawBmpRegion(page_t *page, int x, int y,
\r
345 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
346 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
347 byte far *data = bmp->data;//+bmp->offset;
\r
348 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
351 byte plane = 1 << ((byte) x & 0x03);
\r
352 word scanCount = width/4 + (width%4 ? 1 :0);
\r
353 word nextPageRow = page->width/4 - scanCount;
\r
354 word nextBmpRow = (word) bmp->width - width;
\r
356 byte planeCounter = 4;
\r
358 /* printf("bmp->data=%Fp\n",bmp->data);
\r
359 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
360 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
362 //code is a bit slow here
\r
364 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
367 MOV DX, SC_INDEX ; point at the map mask register
\r
372 MOV DX, SC_DATA ; select the current plane
\r
376 ;-- begin plane painting
\r
377 MOV AX, height ; start the row counter
\r
378 MOV rowCounter, AX ;
\r
379 MOV DI, poffset ; go to the first pixel
\r
380 MOV SI, bmpOffset ; go to the bmp pixel
\r
382 MOV CX, width ; count the columns
\r
384 MOVSB ; copy the pixel
\r
385 SUB CX, 3 ; we skip the next 3
\r
386 ADD SI, 3 ; skip the bmp pixels
\r
387 LOOP SCAN_LOOP ; finish the scan
\r
389 MOV AX, nextPageRow
\r
390 ADD DI, AX ; go to the next row on screen
\r
392 ADD SI, AX ; go to the next row on bmp
\r
395 JNZ ROW_LOOP ; do all the rows
\r
396 ;-- end plane painting
\r
398 MOV AL, plane ; advance to the next plane
\r
400 AND AL, 0x0f ; mask the plane properly
\r
401 MOV plane, AL ; store the plane
\r
403 INC bmpOffset ; start bmp at the right spot
\r
406 JNZ PLANE_LOOP ; do all 4 planes
\r
411 modex_sparky4_DrawBmpRegion(page_t *page, int x, int y,
\r
412 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
413 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
414 byte far *data = bmp->data;//+bmp->offset;
\r
415 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
418 byte plane = 1 << ((byte) x & 0x03);
\r
419 word scanCount = width/4 + (width%4 ? 1 :0);
\r
420 word nextPageRow = page->width/4 - scanCount;
\r
421 word nextBmpRow = (word) bmp->width - width;
\r
423 byte planeCounter = 4;
\r
425 /* printf("bmp->data=%Fp\n",bmp->data);
\r
426 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
427 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
429 //code is a bit slow here
\r
431 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
434 MOV DX, SC_INDEX ; point at the map mask register
\r
439 MOV DX, SC_DATA ; select the current plane
\r
443 ;-- begin plane painting
\r
444 MOV AX, height ; start the row counter
\r
445 MOV rowCounter, AX ;
\r
446 MOV DI, poffset ; go to the first pixel
\r
447 MOV SI, bmpOffset ; go to the bmp pixel
\r
449 MOV CX, width ; count the columns
\r
451 MOVSB ; copy the pixel
\r
452 SUB CX, 3 ; we skip the next 3
\r
453 ADD SI, 3 ; skip the bmp pixels
\r
454 LOOP SCAN_LOOP ; finish the scan
\r
456 MOV AX, nextPageRow
\r
457 ADD DI, AX ; go to the next row on screen
\r
459 ADD SI, AX ; go to the next row on bmp
\r
462 JNZ ROW_LOOP ; do all the rows
\r
463 ;-- end plane painting
\r
465 MOV AL, plane ; advance to the next plane
\r
467 AND AL, 0x0f ; mask the plane properly
\r
468 MOV plane, AL ; store the plane
\r
470 INC bmpOffset ; start bmp at the right spot
\r
473 JNZ PLANE_LOOP ; do all 4 planes
\r
478 modexDrawPlanarBuf(page_t *page, int x, int y, planar_buf_t *bmp) {
\r
479 /* TODO - adapt from test code */
\r
481 for(plane=0; plane < 4; plane++)
\r
489 modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp) {
\r
490 /* draw the whole sprite */
\r
491 modexDrawSpriteRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
495 modexDrawSpriteRegion(page_t *page, int x, int y,
\r
496 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
497 word poffset = (word)page->data + y*(page->width/4) + x/4;
\r
498 byte *data = bmp->data;//+bmp->offset;
\r
499 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
502 byte plane = 1 << ((byte) x & 0x03);
\r
503 word scanCount = width/4 + (width%4 ? 1 :0);
\r
504 word nextPageRow = page->width/4 - scanCount;
\r
505 word nextBmpRow = (word) bmp->width - width;
\r
507 byte planeCounter = 4;
\r
510 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
513 MOV DX, SC_INDEX ; point at the map mask register
\r
518 MOV DX, SC_DATA ; select the current plane
\r
522 ;-- begin plane painting
\r
523 MOV AX, height ; start the row counter
\r
524 MOV rowCounter, AX ;
\r
525 MOV DI, poffset ; go to the first pixel
\r
526 MOV SI, bmpOffset ; go to the bmp pixel
\r
528 MOV CX, width ; count the columns
\r
533 JNE DRAW_PIXEL ; draw non-zero pixels
\r
535 INC DI ; skip the transparent pixel
\r
539 MOVSB ; copy the pixel
\r
541 SUB CX, 3 ; we skip the next 3
\r
542 ADD SI, 3 ; skip the bmp pixels
\r
543 LOOP SCAN_LOOP ; finish the scan
\r
545 MOV AX, nextPageRow
\r
546 ADD DI, AX ; go to the next row on screen
\r
548 ADD SI, AX ; go to the next row on bmp
\r
551 JNZ ROW_LOOP ; do all the rows
\r
552 ;-- end plane painting
\r
554 MOV AL, plane ; advance to the next plane
\r
556 AND AL, 0x0f ; mask the plane properly
\r
557 MOV plane, AL ; store the plane
\r
559 INC bmpOffset ; start bmp at the right spot
\r
562 JNZ PLANE_LOOP ; do all 4 planes
\r
567 /* copy a region of video memory from one page to another.
\r
568 * It assumes that the left edge of the tile is the same on both
\r
569 * regions and the memory areas do not overlap.
\r
572 modexCopyPageRegion(page_t *dest, page_t *src,
\r
575 word width, word height)
\r
577 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
578 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
579 word scans = width/4;
\r
580 word nextSrcRow = src->width/4 - scans - 1;
\r
581 word nextDestRow = dest->width/4 - scans - 1;
\r
582 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
583 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
584 byte left = lclip[sx&0x03];
\r
585 byte right = rclip[(sx+width)&0x03];
\r
588 MOV AX, SCREEN_SEG ; work in the vga space
\r
593 MOV DX, GC_INDEX ; turn off cpu bits
\r
597 MOV AX, SC_INDEX ; point to the mask register
\r
607 MOV CX, scans ; the number of latches
\r
609 MOV AL, left ; do the left column
\r
614 MOV AL, 0fh ; do the inner columns
\r
616 REP MOVSB ; copy the pixels
\r
618 MOV AL, right ; do the right column
\r
623 MOV AX, SI ; go the start of the next row
\r
624 ADD AX, nextSrcRow ;
\r
627 ADD AX, nextDestRow ;
\r
630 DEC height ; do the rest of the actions
\r
633 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
634 MOV AL, 0ffh ; none from latches
\r
640 /* fade and flash */
\r
642 modexFadeOn(word fade, byte *palette) {
\r
643 fadePalette(-fade, 64, 64/fade+1, palette);
\r
648 modexFadeOff(word fade, byte *palette) {
\r
649 fadePalette(fade, 0, 64/fade+1, palette);
\r
654 modexFlashOn(word fade, byte *palette) {
\r
655 fadePalette(fade, -64, 64/fade+1, palette);
\r
660 modexFlashOff(word fade, byte *palette) {
\r
661 fadePalette(-fade, 0, 64/fade+1, palette);
\r
666 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
670 /* handle the case where we just update */
\r
672 modexPalUpdate1(palette);
\r
676 while(iter > 0) { /* FadeLoop */
\r
677 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
678 tmppal[i] = palette[i] - dim;
\r
679 if(tmppal[i] > 127) {
\r
681 } else if(tmppal[i] > 63) {
\r
685 modexPalUpdate1(tmppal);
\r
692 /* save and load */
\r
694 modexPalSave(byte *palette) {
\r
697 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
698 for(i=0; i<PAL_SIZE; i++) {
\r
699 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
707 ptr = malloc(PAL_SIZE);
\r
709 /* handle errors */
\r
711 printf("Could not allocate palette.\n");
\r
720 modexLoadPalFile(byte *filename, byte **palette) {
\r
724 /* free the palette if it exists */
\r
729 /* allocate the new palette */
\r
730 *palette = modexNewPal();
\r
732 /* open the file */
\r
733 file = fopen(filename, "rb");
\r
735 printf("Could not open palette file: %s\n", filename);
\r
739 /* read the file */
\r
741 while(!feof(file)) {
\r
742 *ptr++ = fgetc(file);
\r
750 modexSavePalFile(char *filename, byte *pal) {
\r
754 /* open the file for writing */
\r
755 file = fopen(filename, "wb");
\r
757 printf("Could not open %s for writing\n", filename);
\r
761 /* write the data to the file */
\r
762 fwrite(pal, 1, PAL_SIZE, file);
\r
770 fadePalette(-1, 64, 1, tmppal);
\r
776 fadePalette(-1, -64, 1, tmppal);
\r
782 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
784 byte *p = bmp->palette;
\r
788 static word a[PAL_SIZE]; //palette array of change values!
\r
789 word z=0, aq=0, aa=0, pp=0;
\r
794 memset(a, -1, sizeof(a));
\r
795 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
805 // printf("q: %02d\n", (q));
\r
806 // printf("qq: %02d\n", (qq));
\r
807 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
808 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
810 if((*i)<PAL_SIZE/2 && w==0)
\r
812 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
814 //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
815 //____ 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
816 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
821 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
823 //printf("qp=%d\n", qp);
\r
824 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
825 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
826 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
827 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
831 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
833 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
834 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
835 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
838 //if(qp>0) printf("qp=%d\n", qp);
\r
839 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
841 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
842 if((*i)>=PAL_SIZE/2 && w==0)
\r
844 for(; (*i)<PAL_SIZE; (*i)++)
\r
846 //____ 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
847 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
852 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
854 //printf("qp=%d\n", qp);
\r
855 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
856 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
857 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
858 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
862 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
863 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
864 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
867 //printf(" (*i)=%d\n", (*i)/3);
\r
870 printf("\nqqqqqqqq\n\n");
\r
876 long bufSize = (bmp->width * bmp->height);
\r
878 //printf("1(*i)=%02d\n", (*i)/3);
\r
879 //printf("1z=%02d\n", z/3);
\r
880 chkcolor(bmp, &q, &a, &aa, &z, i);
\r
881 //printf("2(*i)=%02d\n", (*i)/3);
\r
882 //printf("2z=%02d\n", z/3);
\r
887 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
888 if(a[aq]==-1) aq++;
\r
889 else { aqoffset++; break; }
\r
891 //update the image data here!
\r
892 for(lq=0; lq<bufSize; lq++)
\r
896 use a[qp] instead of bmp->offset for this spot!
\r
901 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
904 //(offset/bmp->offset)*bmp->offset
\r
907 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
908 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
909 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
910 /*if(bmp->data[lq]+bmp->offset==aq)
\r
912 //printf("%02d", bmp->data[lq]);
\r
913 //printf("\n%02d\n", bmp->offset);
\r
914 printf("aq=%02d ", aq);
\r
915 printf("a[aq]=%02d ", a[aq]);
\r
916 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
917 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
918 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
919 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
920 // printf("_%d ", bmp->data[lq]);
\r
921 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
923 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
925 if(bmp->data[lq]+bmp->offset >= aq)
\r
927 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
928 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
930 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
933 //printf("%02d`", bmp->data[lq]);
\r
934 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
937 //printf(" aq=%02d\n", aq);
\r
938 //printf(" aa=%02d\n", aa);
\r
940 //update the palette~
\r
941 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
944 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
949 modexPalUpdate1(byte *p)
\r
953 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
954 for(i=0; i<PAL_SIZE/2; i++)
\r
956 outp(PAL_DATA_REG, p[i]);
\r
958 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
959 for(; i<PAL_SIZE; i++)
\r
961 outp(PAL_DATA_REG, p[(i)]);
\r
966 modexPalUpdate0(byte *p)
\r
970 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
971 for(i=0; i<PAL_SIZE/2; i++)
\r
973 outp(PAL_DATA_REG, rand());
\r
975 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
976 for(; i<PAL_SIZE; i++)
\r
978 outp(PAL_DATA_REG, rand());
\r
983 //i want to make another vesion that checks the palette when the palette is being appened~
\r
984 void chkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
988 pal = modexNewPal();
\r
990 //printf("q: %02d\n", (*q));
\r
991 printf("chkcolor start~\n");
\r
992 printf("1 (*z): %d\n", (*z)/3);
\r
993 printf("1 (*i): %d\n", (*i)/3);
\r
994 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
995 printf("wwwwwwwwwwwwwwww\n");
\r
996 //check palette for dups
\r
997 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
999 //printf("\n z: %d\n", (*z));
\r
1000 //printf(" q: %d\n", (*q));
\r
1001 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
1004 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
1007 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1008 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
1012 else for(zz=0; zz<(*q); zz+=3)
\r
1014 //printf("zz: %02d\n", zz/3);
\r
1017 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
1021 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
1022 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
1025 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
1027 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
1028 // 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
1029 // 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
1030 // //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
1031 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1034 //expand dong here
\r
1036 planned features that i plan to implement~
\r
1037 image that has values on the pallete list!
\r
1039 no... wait.... no wwww
\r
1041 //for(zzii=0; zzii<3; zzii++)
\r
1043 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
1044 a[(((*z)+(*q)))]=zz;
\r
1046 (*aa)=(((*z)+(*q)));
\r
1047 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
1048 // printf("\n aa: %d\n\n", (*aa));
\r
1049 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
1050 // printf("wwwwwwwwwwwwwwww\n\n");
\r
1054 printf("================\n");
\r
1055 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
1056 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
1057 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1058 printf("================\n");
\r
1060 //printf("[%d]", (zz+q));
\r
1064 printf("wwwwwwwwwwwwwwww\n");
\r
1065 printf("2 (*z): %d\n", (*z)/3);
\r
1066 printf("2 (*i): %d\n", (*i)/3);
\r
1067 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
1068 printf("chkcolor end~\n");
\r
1072 void modexputPixel(page_t *page, int x, int y, byte color)
\r
1074 word pageOff = (word) page->data;
\r
1075 /* Each address accesses four neighboring pixels, so set
\r
1076 Write Plane Enable according to which pixel we want
\r
1077 to modify. The plane is determined by the two least
\r
1078 significant bits of the x-coordinate: */
\r
1079 modexSelectPlane(PLANE(x));
\r
1080 //outp(SC_INDEX, 0x02);
\r
1081 //outp(SC_DATA, 0x01 << (x & 3));
\r
1083 /* The offset of the pixel into the video segment is
\r
1084 offset = (width * y + x) / 4, and write the given
\r
1085 color to the plane we selected above. Heed the active
\r
1086 page start selection. */
\r
1087 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
1091 byte modexgetPixel(page_t *page, int x, int y)
\r
1093 word pageOff = (word) page->data;
\r
1094 /* Select the plane from which we must read the pixel color: */
\r
1095 outpw(GC_INDEX, 0x04);
\r
1096 outpw(GC_INDEX+1, x & 3);
\r
1098 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
1102 void modexhlin(page_t *page, word xl, word xh, word y, word color)
\r
1107 for(x=0;x<xh*4;x+=4)
\r
1109 if(x+4>=SCREEN_WIDTH-1){ x=0; yy+=4; }
\r
1110 modexClearRegion(page, x+xl, y+yy, 4, 4, color);
\r
1112 //modexputPixel(page, x+xl, y, color);
\r
1115 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1117 word i, s, o, w, j, xp;
\r
1119 word addr = (word) l;
\r
1143 s=romFonts[t].seg;
\r
1144 o=romFonts[t].off;
\r
1146 for(; *str != '\0'; str++)
\r
1149 if((c=='\n'/* || c=="\
\r
1157 //load the letter 'A'
\r
1163 MOV AL, c ; the letter
\r
1166 ADD SI, AX ;the address of charcter
\r
1175 for(i=0; i<w; i++)
\r
1181 modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1190 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1192 word i, s, o, w, j, xp;
\r
1194 word addr = (word) l;
\r
1218 s=romFonts[t].seg;
\r
1219 o=romFonts[t].off;
\r
1221 for(; *str != '\0'; str++)
\r
1224 if((c=='\n'/* || c=="\
\r
1225 "*/)/* || chw>=page->width*/)
\r
1231 //load the letter 'A'
\r
1237 MOV AL, c ; the letter
\r
1240 ADD SI, AX ;the address of charcter
\r
1249 for(i=0; i<w; i++)
\r
1255 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1256 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1265 /////////////////////////////////////////////////////////////////////////////
\r
1267 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1268 // the Virtual screen. //
\r
1270 /////////////////////////////////////////////////////////////////////////////
\r
1271 void cls(page_t *page, byte color, byte *Where)
\r
1273 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1274 /* set map mask to all 4 planes */
\r
1275 outpw(SC_INDEX, 0xff02);
\r
1276 //_fmemset(VGA, color, 16000);
\r
1277 _fmemset(Where, color, page->width*(page->height));
\r
1281 modexWaitBorder() {
\r
1282 while(inp(INPUT_STATUS_1) & 8) {
\r
1286 while(!(inp(INPUT_STATUS_1) & 8)) {
\r