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
59 modex__320x240_256__Enter(gv);
\r
64 vgaSetMode(byte mode)
\r
68 regs.h.ah = SET_MODE;
\r
70 int86(VIDEO_INT, ®s, ®s);
\r
74 /* -========================= Entry Points ==========================- */
\r
76 modex__320x240_256__Enter(global_game_variables_t *gv)
\r
79 dword far*ptr=(dword far*)VGA; /* used for faster screen clearing */
\r
81 // 0x5f00, /* horizontal total */
\r
82 // 0x3f01, /* horizontal display enable end */
\r
83 0x0d06, /* vertical total */
\r
84 0x3e07, /* overflow (bit 8 of vertical counts) */
\r
85 0x4109, /* cell height (2 to double-scan */
\r
86 0xea10, /* v sync start */
\r
87 0xac11, /* v sync end and protect cr0-cr7 */
\r
88 0xdf12, /* vertical displayed */
\r
89 // 0x2013, /* offset/logical width */
\r
90 0x0014, /* turn off dword mode */
\r
91 0xe715, /* v blank start */
\r
92 0x0616, /* v blank end */
\r
93 0xe317 /* turn on byte mode */
\r
96 int CRTParmCount = sizeof(CRTParms) / sizeof(CRTParms[0]);
\r
97 /* width and height */
\r
100 /* TODO save current video mode and palette */
\r
101 vgaSetMode(VGA_256_COLOR_MODE);
\r
103 /* disable chain4 mode */
\r
104 outpw(SC_INDEX, 0x0604);
\r
106 /* synchronous reset while setting Misc Output */
\r
107 outpw(SC_INDEX, 0x0100);
\r
109 /* select 25 MHz dot clock & 60 Hz scanning rate */
\r
110 outp(MISC_OUTPUT, 0xe3);
\r
112 /* undo reset (restart sequencer) */
\r
113 outpw(SC_INDEX, 0x0300);
\r
115 /* reprogram the CRT controller */
\r
116 outp(CRTC_INDEX, 0x11); /* VSync End reg contains register write prot */
\r
117 outp(CRTC_DATA, 0x7f); /* get current write protect on varios regs */
\r
119 /* send the CRTParms */
\r
120 for(i=0; i<CRTParmCount; i++) {
\r
121 outpw(CRTC_INDEX, CRTParms[i]);
\r
124 /* clear video memory */
\r
125 outpw(SC_INDEX, 0x0f02);
\r
126 for(i=0; i<0x8000; i++) {
\r
134 /* TODO restore original mode and palette */
\r
135 vgaSetMode(TEXT_MODE);
\r
140 modexDefaultPage() {
\r
143 /* default page values */
\r
147 page.width = SCREEN_WIDTH;
\r
148 page.height = SCREEN_HEIGHT;
\r
149 page.tw = page.width/TILEWH;
\r
150 page.th = page.height/TILEWH;
\r
156 /* returns the next page in contiguous memory
\r
157 * the next page will be the same size as p, by default
\r
160 modexNextPage(page_t *p) {
\r
163 result.data = p->data + (p->width/4)*p->height;
\r
166 result.width = p->width;
\r
167 result.height = p->height;
\r
168 result.tw = p->width/TILEWH;
\r
169 result.th = p->height/TILEWH;
\r
170 result.id = p->id+1;
\r
173 // return modexNextPageFlexibleSize(&p, p->width, p->height);
\r
176 //next page with defined dimentions~
\r
178 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
182 result.data = p->data + (p->width/4)*p->height; /* compute the offset */
\r
187 result.tw = p->width/TILEWH;
\r
188 result.th = p->height/TILEWH;
\r
189 result.id = p->id+1;
\r
196 modexShowPage(page_t *page) {
\r
202 /* calculate offset */
\r
203 offset = (word) page->data;
\r
204 offset += page->dy * (page->width >> 2 );
\r
205 offset += page->dx >> 2;
\r
207 /* calculate crtcOffset according to virtual width */
\r
208 crtcOffset = page->width >> 3;
\r
210 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
211 low_address = LOW_ADDRESS | (offset << 8);
\r
213 /* wait for appropriate timing and then program CRTC */
\r
214 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
215 outpw(CRTC_INDEX, high_address);
\r
216 outpw(CRTC_INDEX, low_address);
\r
217 outp(CRTC_INDEX, 0x13);
\r
218 outp(CRTC_DATA, crtcOffset);
\r
220 /* wait for one retrace */
\r
221 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
223 /* do PEL panning here */
\r
224 outp(AC_INDEX, 0x33);
\r
225 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
230 modexPanPage(page_t *page, int dx, int dy) {
\r
237 modexSelectPlane(byte plane) {
\r
238 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
239 outp(SC_DATA, plane);
\r
244 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
245 word pageOff = (word) page->data;
\r
246 word xoff=x/4; /* xoffset that begins each row */
\r
247 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
248 word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */
\r
249 word nextRow = page->width/4-scanCount-1; /* loc of next row */
\r
250 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
251 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
252 byte left = lclip[x&0x03];
\r
253 byte right = rclip[(x+w)&0x03];
\r
255 /* handle the case which requires an extra group */
\r
256 if((x & 0x03) && !((x+w) & 0x03)) {
\r
261 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
263 MOV DI, poffset ; go to the first pixel
\r
264 MOV DX, SC_INDEX ; point to the map mask
\r
268 MOV AL, color ; get ready to write colors
\r
270 MOV CX, scanCount ; count the line
\r
271 MOV BL, AL ; remember color
\r
272 MOV AL, left ; do the left clip
\r
273 OUT DX, AL ; set the left clip
\r
274 MOV AL, BL ; restore color
\r
275 STOSB ; write the color
\r
277 JZ SCAN_DONE ; handle 1 group stuff
\r
279 ;-- write the main body of the scanline
\r
280 MOV BL, AL ; remember color
\r
281 MOV AL, 0x0f ; write to all pixels
\r
283 MOV AL, BL ; restore color
\r
284 REP STOSB ; write the color
\r
286 MOV BL, AL ; remeber color
\r
288 OUT DX, AL ; do the right clip
\r
289 MOV AL, BL ; restore color
\r
290 STOSB ; write pixel
\r
291 ADD DI, nextRow ; go to the next row
\r
299 oldDrawBmp(byte far* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
305 /* TODO Make this fast. It's SLOOOOOOW */
\r
306 for(plane=0; plane < 4; plane++) {
\r
307 modexSelectPlane(PLANE(plane+x));
\r
308 for(px = plane; px < bmp->width; px+=4) {
\r
310 for(py=0; py<bmp->height; py++) {
\r
311 if(!sprite || bmp->data[offset])
\r
312 page[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
313 offset+=bmp->width;
\r
320 CDrawBmp(byte far* vgamem, page_t* page, int x, int y, bitmap_t *bmp, byte sprite)
\r
327 /* TODO Make this fast. It's SLOOOOOOW */
\r
328 for(plane=0; plane < 4; plane++) {
\r
329 modexSelectPlane(PLANE(plane+x));
\r
330 for(px = plane; px < bmp->width; px+=4) {
\r
332 for(py=0; py<bmp->height; py++) {
\r
333 if(!sprite || bmp->data[offset])
\r
334 //modexputPixel(page, x+px, y+py, bmp->data[offset]);
\r
335 vgamem[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];
\r
336 offset+=bmp->width;
\r
343 modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) {
\r
344 /* draw the region (the entire freakin bitmap) */
\r
345 modexDrawBmpRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
350 modexDrawBmpRegion(page_t *page, int x, int y,
\r
351 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
352 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
353 byte far *data = bmp->data;//+bmp->offset;
\r
354 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
357 byte plane = 1 << ((byte) x & 0x03);
\r
358 word scanCount = width/4 + (width%4 ? 1 :0);
\r
359 word nextPageRow = page->width/4 - scanCount;
\r
360 word nextBmpRow = (word) bmp->width - width;
\r
362 byte planeCounter = 4;
\r
364 /* printf("bmp->data=%Fp\n",bmp->data);
\r
365 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
366 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
368 //code is a bit slow here
\r
370 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
373 MOV DX, SC_INDEX ; point at the map mask register
\r
378 MOV DX, SC_DATA ; select the current plane
\r
382 ;-- begin plane painting
\r
383 MOV AX, height ; start the row counter
\r
384 MOV rowCounter, AX ;
\r
385 MOV DI, poffset ; go to the first pixel
\r
386 MOV SI, bmpOffset ; go to the bmp pixel
\r
388 MOV CX, width ; count the columns
\r
390 MOVSB ; copy the pixel
\r
391 SUB CX, 3 ; we skip the next 3
\r
392 ADD SI, 3 ; skip the bmp pixels
\r
393 LOOP SCAN_LOOP ; finish the scan
\r
395 MOV AX, nextPageRow
\r
396 ADD DI, AX ; go to the next row on screen
\r
398 ADD SI, AX ; go to the next row on bmp
\r
401 JNZ ROW_LOOP ; do all the rows
\r
402 ;-- end plane painting
\r
404 MOV AL, plane ; advance to the next plane
\r
406 AND AL, 0x0f ; mask the plane properly
\r
407 MOV plane, AL ; store the plane
\r
409 INC bmpOffset ; start bmp at the right spot
\r
412 JNZ PLANE_LOOP ; do all 4 planes
\r
417 modex_sparky4_DrawBmpRegion(page_t *page, int x, int y,
\r
418 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
419 word poffset = (word) page->data + y*(page->width/4) + x/4;
\r
420 byte far *data = bmp->data;//+bmp->offset;
\r
421 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
424 byte plane = 1 << ((byte) x & 0x03);
\r
425 word scanCount = width/4 + (width%4 ? 1 :0);
\r
426 word nextPageRow = page->width/4 - scanCount;
\r
427 word nextBmpRow = (word) bmp->width - width;
\r
429 byte planeCounter = 4;
\r
431 /* printf("bmp->data=%Fp\n",bmp->data);
\r
432 printf("*bmp->data=%Fp\n",*(bmp->data));
\r
433 printf("&bmp->data=%Fp\n",&(bmp->data));*/
\r
435 //code is a bit slow here
\r
437 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
440 MOV DX, SC_INDEX ; point at the map mask register
\r
445 MOV DX, SC_DATA ; select the current plane
\r
449 ;-- begin plane painting
\r
450 MOV AX, height ; start the row counter
\r
451 MOV rowCounter, AX ;
\r
452 MOV DI, poffset ; go to the first pixel
\r
453 MOV SI, bmpOffset ; go to the bmp pixel
\r
455 MOV CX, width ; count the columns
\r
457 MOVSB ; copy the pixel
\r
458 SUB CX, 3 ; we skip the next 3
\r
459 ADD SI, 3 ; skip the bmp pixels
\r
460 LOOP SCAN_LOOP ; finish the scan
\r
462 MOV AX, nextPageRow
\r
463 ADD DI, AX ; go to the next row on screen
\r
465 ADD SI, AX ; go to the next row on bmp
\r
468 JNZ ROW_LOOP ; do all the rows
\r
469 ;-- end plane painting
\r
471 MOV AL, plane ; advance to the next plane
\r
473 AND AL, 0x0f ; mask the plane properly
\r
474 MOV plane, AL ; store the plane
\r
476 INC bmpOffset ; start bmp at the right spot
\r
479 JNZ PLANE_LOOP ; do all 4 planes
\r
484 modexDrawPlanarBuf(page_t *page, int x, int y, planar_buf_t *bmp) {
\r
485 /* TODO - adapt from test code */
\r
487 for(plane=0; plane < 4; plane++)
\r
495 modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp) {
\r
496 /* draw the whole sprite */
\r
497 modexDrawSpriteRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);
\r
501 modexDrawSpriteRegion(page_t *page, int x, int y,
\r
502 int rx, int ry, int rw, int rh, bitmap_t *bmp) {
\r
503 word poffset = (word)page->data + y*(page->width/4) + x/4;
\r
504 byte *data = bmp->data;//+bmp->offset;
\r
505 word bmpOffset = (word) data + ry * bmp->width + rx;
\r
508 byte plane = 1 << ((byte) x & 0x03);
\r
509 word scanCount = width/4 + (width%4 ? 1 :0);
\r
510 word nextPageRow = page->width/4 - scanCount;
\r
511 word nextBmpRow = (word) bmp->width - width;
\r
513 byte planeCounter = 4;
\r
516 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
519 MOV DX, SC_INDEX ; point at the map mask register
\r
524 MOV DX, SC_DATA ; select the current plane
\r
528 ;-- begin plane painting
\r
529 MOV AX, height ; start the row counter
\r
530 MOV rowCounter, AX ;
\r
531 MOV DI, poffset ; go to the first pixel
\r
532 MOV SI, bmpOffset ; go to the bmp pixel
\r
534 MOV CX, width ; count the columns
\r
539 JNE DRAW_PIXEL ; draw non-zero pixels
\r
541 INC DI ; skip the transparent pixel
\r
545 MOVSB ; copy the pixel
\r
547 SUB CX, 3 ; we skip the next 3
\r
548 ADD SI, 3 ; skip the bmp pixels
\r
549 LOOP SCAN_LOOP ; finish the scan
\r
551 MOV AX, nextPageRow
\r
552 ADD DI, AX ; go to the next row on screen
\r
554 ADD SI, AX ; go to the next row on bmp
\r
557 JNZ ROW_LOOP ; do all the rows
\r
558 ;-- end plane painting
\r
560 MOV AL, plane ; advance to the next plane
\r
562 AND AL, 0x0f ; mask the plane properly
\r
563 MOV plane, AL ; store the plane
\r
565 INC bmpOffset ; start bmp at the right spot
\r
568 JNZ PLANE_LOOP ; do all 4 planes
\r
573 /* copy a region of video memory from one page to another.
\r
574 * It assumes that the left edge of the tile is the same on both
\r
575 * regions and the memory areas do not overlap.
\r
578 modexCopyPageRegion(page_t *dest, page_t *src,
\r
581 word width, word height)
\r
583 word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;
\r
584 word soffset = (word)src->data + sy*(src->width/4) + sx/4;
\r
585 word scans = width/4;
\r
586 word nextSrcRow = src->width/4 - scans - 1;
\r
587 word nextDestRow = dest->width/4 - scans - 1;
\r
588 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
589 byte rclip[] = {0x0f, 0x01, 0x03, 0x07};
\r
590 byte left = lclip[sx&0x03];
\r
591 byte right = rclip[(sx+width)&0x03];
\r
594 MOV AX, SCREEN_SEG ; work in the vga space
\r
599 MOV DX, GC_INDEX ; turn off cpu bits
\r
603 MOV AX, SC_INDEX ; point to the mask register
\r
613 MOV CX, scans ; the number of latches
\r
615 MOV AL, left ; do the left column
\r
620 MOV AL, 0fh ; do the inner columns
\r
622 REP MOVSB ; copy the pixels
\r
624 MOV AL, right ; do the right column
\r
629 MOV AX, SI ; go the start of the next row
\r
630 ADD AX, nextSrcRow ;
\r
633 ADD AX, nextDestRow ;
\r
636 DEC height ; do the rest of the actions
\r
639 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
640 MOV AL, 0ffh ; none from latches
\r
646 /* fade and flash */
\r
648 modexFadeOn(word fade, byte *palette) {
\r
649 fadePalette(-fade, 64, 64/fade+1, palette);
\r
654 modexFadeOff(word fade, byte *palette) {
\r
655 fadePalette(fade, 0, 64/fade+1, palette);
\r
660 modexFlashOn(word fade, byte *palette) {
\r
661 fadePalette(fade, -64, 64/fade+1, palette);
\r
666 modexFlashOff(word fade, byte *palette) {
\r
667 fadePalette(-fade, 0, 64/fade+1, palette);
\r
672 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
676 /* handle the case where we just update */
\r
678 modexPalUpdate1(palette);
\r
682 while(iter > 0) { /* FadeLoop */
\r
683 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
684 tmppal[i] = palette[i] - dim;
\r
685 if(tmppal[i] > 127) {
\r
687 } else if(tmppal[i] > 63) {
\r
691 modexPalUpdate1(tmppal);
\r
698 /* save and load */
\r
700 modexPalSave(byte *palette) {
\r
703 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
704 for(i=0; i<PAL_SIZE; i++) {
\r
705 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
713 ptr = malloc(PAL_SIZE);
\r
715 /* handle errors */
\r
717 printf("Could not allocate palette.\n");
\r
726 modexLoadPalFile(byte *filename, byte **palette) {
\r
730 /* free the palette if it exists */
\r
735 /* allocate the new palette */
\r
736 *palette = modexNewPal();
\r
738 /* open the file */
\r
739 file = fopen(filename, "rb");
\r
741 printf("Could not open palette file: %s\n", filename);
\r
745 /* read the file */
\r
747 while(!feof(file)) {
\r
748 *ptr++ = fgetc(file);
\r
756 modexSavePalFile(char *filename, byte *pal) {
\r
760 /* open the file for writing */
\r
761 file = fopen(filename, "wb");
\r
763 printf("Could not open %s for writing\n", filename);
\r
767 /* write the data to the file */
\r
768 fwrite(pal, 1, PAL_SIZE, file);
\r
776 fadePalette(-1, 64, 1, tmppal);
\r
782 fadePalette(-1, -64, 1, tmppal);
\r
788 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
790 byte *p = bmp->palette;
\r
794 static word a[PAL_SIZE]; //palette array of change values!
\r
795 word z=0, aq=0, aa=0, pp=0;
\r
800 memset(a, -1, sizeof(a));
\r
801 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
811 // printf("q: %02d\n", (q));
\r
812 // printf("qq: %02d\n", (qq));
\r
813 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
814 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
816 if((*i)<PAL_SIZE/2 && w==0)
\r
818 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
820 //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
821 //____ 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
822 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
827 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
829 //printf("qp=%d\n", qp);
\r
830 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
831 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
832 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
833 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
837 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
839 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
840 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
841 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
844 //if(qp>0) printf("qp=%d\n", qp);
\r
845 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
847 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
848 if((*i)>=PAL_SIZE/2 && w==0)
\r
850 for(; (*i)<PAL_SIZE; (*i)++)
\r
852 //____ 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
853 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
858 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
860 //printf("qp=%d\n", qp);
\r
861 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
862 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
863 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
864 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
868 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
869 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
870 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
873 //printf(" (*i)=%d\n", (*i)/3);
\r
876 printf("\nqqqqqqqq\n\n");
\r
882 long bufSize = (bmp->width * bmp->height);
\r
884 //printf("1(*i)=%02d\n", (*i)/3);
\r
885 //printf("1z=%02d\n", z/3);
\r
886 chkcolor(bmp, &q, &a, &aa, &z, i);
\r
887 //printf("2(*i)=%02d\n", (*i)/3);
\r
888 //printf("2z=%02d\n", z/3);
\r
893 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
894 if(a[aq]==-1) aq++;
\r
895 else { aqoffset++; break; }
\r
897 //update the image data here!
\r
898 for(lq=0; lq<bufSize; lq++)
\r
902 use a[qp] instead of bmp->offset for this spot!
\r
907 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
910 //(offset/bmp->offset)*bmp->offset
\r
913 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
914 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
915 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
916 /*if(bmp->data[lq]+bmp->offset==aq)
\r
918 //printf("%02d", bmp->data[lq]);
\r
919 //printf("\n%02d\n", bmp->offset);
\r
920 printf("aq=%02d ", aq);
\r
921 printf("a[aq]=%02d ", a[aq]);
\r
922 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
923 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
924 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
925 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
926 // printf("_%d ", bmp->data[lq]);
\r
927 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
929 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
931 if(bmp->data[lq]+bmp->offset >= aq)
\r
933 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
934 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
936 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
939 //printf("%02d`", bmp->data[lq]);
\r
940 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
943 //printf(" aq=%02d\n", aq);
\r
944 //printf(" aa=%02d\n", aa);
\r
946 //update the palette~
\r
947 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
950 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
955 modexPalUpdate1(byte *p)
\r
959 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
960 for(i=0; i<PAL_SIZE/2; i++)
\r
962 outp(PAL_DATA_REG, p[i]);
\r
964 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
965 for(; i<PAL_SIZE; i++)
\r
967 outp(PAL_DATA_REG, p[(i)]);
\r
972 modexPalUpdate0(byte *p)
\r
976 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
977 for(i=0; i<PAL_SIZE/2; i++)
\r
979 outp(PAL_DATA_REG, rand());
\r
981 modexWaitBorder(); /* waits one retrace -- less flicker */
\r
982 for(; i<PAL_SIZE; i++)
\r
984 outp(PAL_DATA_REG, rand());
\r
989 //i want to make another vesion that checks the palette when the palette is being appened~
\r
990 void chkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
994 pal = modexNewPal();
\r
996 //printf("q: %02d\n", (*q));
\r
997 printf("chkcolor start~\n");
\r
998 printf("1 (*z): %d\n", (*z)/3);
\r
999 printf("1 (*i): %d\n", (*i)/3);
\r
1000 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
1001 printf("wwwwwwwwwwwwwwww\n");
\r
1002 //check palette for dups
\r
1003 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
1005 //printf("\n z: %d\n", (*z));
\r
1006 //printf(" q: %d\n", (*q));
\r
1007 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
1010 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
1013 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1014 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
1018 else for(zz=0; zz<(*q); zz+=3)
\r
1020 //printf("zz: %02d\n", zz/3);
\r
1023 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
1027 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
1028 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
1031 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
1033 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
1034 // 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
1035 // 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
1036 // //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
1037 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1040 //expand dong here
\r
1042 planned features that i plan to implement~
\r
1043 image that has values on the pallete list!
\r
1045 no... wait.... no wwww
\r
1047 //for(zzii=0; zzii<3; zzii++)
\r
1049 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
1050 a[(((*z)+(*q)))]=zz;
\r
1052 (*aa)=(((*z)+(*q)));
\r
1053 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
1054 // printf("\n aa: %d\n\n", (*aa));
\r
1055 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
1056 // printf("wwwwwwwwwwwwwwww\n\n");
\r
1060 printf("================\n");
\r
1061 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
1062 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
1063 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
1064 printf("================\n");
\r
1066 //printf("[%d]", (zz+q));
\r
1070 printf("wwwwwwwwwwwwwwww\n");
\r
1071 printf("2 (*z): %d\n", (*z)/3);
\r
1072 printf("2 (*i): %d\n", (*i)/3);
\r
1073 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
1074 printf("chkcolor end~\n");
\r
1078 void modexputPixel(page_t *page, int x, int y, byte color)
\r
1080 word pageOff = (word) page->data;
\r
1081 /* Each address accesses four neighboring pixels, so set
\r
1082 Write Plane Enable according to which pixel we want
\r
1083 to modify. The plane is determined by the two least
\r
1084 significant bits of the x-coordinate: */
\r
1085 modexSelectPlane(PLANE(x));
\r
1086 //outp(SC_INDEX, 0x02);
\r
1087 //outp(SC_DATA, 0x01 << (x & 3));
\r
1089 /* The offset of the pixel into the video segment is
\r
1090 offset = (width * y + x) / 4, and write the given
\r
1091 color to the plane we selected above. Heed the active
\r
1092 page start selection. */
\r
1093 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
1097 byte modexgetPixel(page_t *page, int x, int y)
\r
1099 word pageOff = (word) page->data;
\r
1100 /* Select the plane from which we must read the pixel color: */
\r
1101 outpw(GC_INDEX, 0x04);
\r
1102 outpw(GC_INDEX+1, x & 3);
\r
1104 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
1108 void modexhlin(page_t *page, word xl, word xh, word y, word color)
\r
1113 for(x=0;x<xh*4;x+=4)
\r
1115 if(x+4>=SCREEN_WIDTH-1){ x=0; yy+=4; }
\r
1116 modexClearRegion(page, x+xl, y+yy, 4, 4, color);
\r
1118 //modexputPixel(page, x+xl, y, color);
\r
1121 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1123 word i, s, o, w, j, xp;
\r
1125 word addr = (word) l;
\r
1149 s=romFonts[t].seg;
\r
1150 o=romFonts[t].off;
\r
1152 for(; *str != '\0'; str++)
\r
1155 if((c=='\n'/* || c=="\
\r
1163 //load the letter 'A'
\r
1169 MOV AL, c ; the letter
\r
1172 ADD SI, AX ;the address of charcter
\r
1181 for(i=0; i<w; i++)
\r
1187 modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1196 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1198 word i, s, o, w, j, xp;
\r
1200 word addr = (word) l;
\r
1224 s=romFonts[t].seg;
\r
1225 o=romFonts[t].off;
\r
1227 for(; *str != '\0'; str++)
\r
1230 if((c=='\n'/* || c=="\
\r
1231 "*/)/* || chw>=page->width*/)
\r
1237 //load the letter 'A'
\r
1243 MOV AL, c ; the letter
\r
1246 ADD SI, AX ;the address of charcter
\r
1255 for(i=0; i<w; i++)
\r
1261 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1262 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1271 /////////////////////////////////////////////////////////////////////////////
\r
1273 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1274 // the Virtual screen. //
\r
1276 /////////////////////////////////////////////////////////////////////////////
\r
1277 void cls(page_t *page, byte color, byte *Where)
\r
1279 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1280 /* set map mask to all 4 planes */
\r
1281 outpw(SC_INDEX, 0xff02);
\r
1282 //_fmemset(VGA, color, 16000);
\r
1283 _fmemset(Where, color, page->width*(page->height));
\r
1287 modexWaitBorder() {
\r
1288 while(inp(INPUT_STATUS_1) & 8) {
\r
1292 while(!(inp(INPUT_STATUS_1) & 8)) {
\r