1 /* Project 16 Source Code~
\r
2 * Copyright (C) 2012-2016 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 verson 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, boolean cmem, 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
57 modexEnter(vq, cmem, gv);
\r
63 vgaSetMode(byte mode)
\r
67 regs.h.ah = SET_MODE;
\r
69 int86(VIDEO_INT, ®s, ®s);
\r
70 //int10_setmode(mode);
\r
73 //---------------------------------------------------
\r
75 // Use the bios to get the current video mode
\r
78 byte/*FIXME: why long? "long" is 32-bit datatype, VGA modes are 8-bit numbers. */
\r
81 return int10_getmode();
\r
84 /* -========================= Entry Points ==========================- */
\r
85 void modexEnter(sword vq, boolean cmem, global_game_variables_t *gv)
\r
88 struct vga_mode_params cm;
\r
91 vgaSetMode(VGA_256_COLOR_MODE);
\r
92 vga_enable_256color_modex();
\r
94 update_state_from_vga();
\r
95 vga_read_crtc_mode(&cm);
\r
97 /* reprogram the CRT controller */
\r
98 //outp(CRTC_INDEX, 0x11); /* VSync End reg contains register write prot */
\r
99 //outp(CRTC_DATA, 0x7f); /* get current write protect on varios regs */
\r
104 //CRTParmCount = sizeof(ModeX_320x240regs) / sizeof(ModeX_320x240regs[0]);
\r
105 /*for(i=0; i<CRTParmCount; i++) {
\r
106 outpw(CRTC_INDEX, ModeX_320x240regs[i]);
\r
108 /* width and height */
\r
109 gv->video.page[0].sw = vga_state.vga_width = 320; // VGA lib currently does not update this
\r
110 gv->video.page[0].sh = vga_state.vga_height = 240; // VGA lib currently does not update this
\r
111 /* virtual width and height. match screen, at first */
\r
112 gv->video.page[0].height = gv->video.page[0].sh;
\r
113 gv->video.page[0].width = gv->video.page[0].sw;
\r
115 // mode X BYTE mode
\r
118 // 320x240 mode 60Hz
\r
119 cm.horizontal_total=0x5f + 5; /* CRTC[0] -5 */
\r
120 cm.horizontal_display_end=0x4f + 1; /* CRTC[1] -1 */
\r
121 cm.horizontal_blank_start=0x50 + 1; /* CRTC[2] */
\r
122 // cm.horizontal_blank_end=0x82 + 1; /* CRTC[3] bit 0-4 & CRTC[5] bit 7 *///skewing ^^;
\r
123 cm.horizontal_start_retrace=0x54;/* CRTC[4] */
\r
124 cm.horizontal_end_retrace=0x80; /* CRTC[5] bit 0-4 */
\r
125 //cm.horizontal_start_delay_after_total=0x3e; /* CRTC[3] bit 5-6 */
\r
126 //cm.horizontal_start_delay_after_retrace=0x41; /* CRTC[5] bit 5-6 */
\r
127 cm.vertical_total = 0x20D + 2;
\r
128 cm.vertical_start_retrace = 0x1EA;
\r
129 cm.vertical_end_retrace = 0x1EC;
\r
130 cm.vertical_display_end = 480;
\r
131 cm.vertical_blank_start = 0x1E7 + 1;
\r
132 cm.vertical_blank_end = 0x206 + 1;
\r
133 cm.clock_select = 0; /* misc register = 0xE3 25MHz */
\r
136 cm.offset = (vga_state.vga_width / (4 * 2)); // 320 wide (40 x 4 pixel groups x 2)
\r
138 case 2: // TODO: 160x120 according to ModeX_160x120regs
\r
140 case 3: // TODO: 160x120 according to ModeX_320x200regs
\r
142 case 4: // TODO: 160x120 according to ModeX_192x144regs
\r
144 case 5: // TODO: 160x120 according to ModeX_256x192regs
\r
150 vga_state.vga_stride = cm.offset * 2;
\r
151 vga_write_crtc_mode(&cm,0);
\r
153 /* clear video memory */
\r
157 /* clear video memory */
\r
158 dword far*ptr=(dword far*)vga_state.vga_graphics_ram;//VGA; /* used for faster screen clearing */
\r
159 vga_write_sequencer(2/*map mask register*/,0xf/*all 4 planes*/);
\r
160 for(i = 0;i < 0x4000; i++) ptr[i] = 0x0000; // 0x4000 x dword = 64KB
\r
165 // gv->video.page[0].tw = gv->video.page[0].sw/TILEWH;
\r
166 // gv->video.page[0].th = gv->video.page[0].sh/TILEWH;
\r
168 //TODO MAKE FLEXIBLE~
\r
169 // gv->video.page[0].tilemidposscreenx = gv->video.page[0].tilesw;
\r
170 // gv->video.page[0].tilemidposscreeny = (gv->video.page[0].tilesh/2)+1;
\r
175 /* VGAmodeX restores original mode and palette */
\r
176 vgaSetMode(TEXT_MODE);
\r
180 modexDefaultPage(page_t *p)
\r
184 /* default page values */
\r
186 //page.data = (byte far *)(vga_state.vga_graphics_ram);
\r
187 page.data = (vga_state.vga_graphics_ram);
\r
192 page.width = p->sw+TILEWHD;
\r
193 page.height = p->sh+TILEWHD;
\r
194 page.tw = page.sw/TILEWH;
\r
195 page.th = page.sh/TILEWH;
\r
196 page.tilesw=page.width/TILEWH;
\r
197 page.tilesh=page.height/TILEWH;
\r
198 page.tilemidposscreenx = page.tw/2;
\r
199 page.tilemidposscreeny = (page.th/2)+1;
\r
200 page.stridew=page.width/4;
\r
201 page.pagesize = (word)(page.width/4)*page.height;
\r
207 /* returns the next page in contiguous memory
\r
208 * the next page will be the same size as p, by default
\r
211 modexNextPage(page_t *p) {
\r
214 result.data = p->data + (p->pagesize);
\r
219 result.width = p->width;
\r
220 result.height = p->height;
\r
223 result.tilesw = p->tilesw;
\r
224 result.tilesh = p->tilesh;
\r
225 result.id = p->id+1;
\r
226 result.stridew=p->stridew;
\r
227 result.pagesize = p->pagesize;
\r
232 //next page with defined dimentions~
\r
234 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
238 result.data = p->data + (p->pagesize); /* compute the offset */
\r
245 result.tw = result.sw/TILEWH;
\r
246 result.th = result.sh/TILEWH;
\r
247 result.tilesw=result.width/TILEWH;
\r
248 result.tilesh=result.height/TILEWH;
\r
249 result.id = p->id+1;
\r
250 result.stridew=result.width/4;
\r
251 result.pagesize = (word)(result.width/4)*result.height;
\r
256 void modexCalcVmemRemain(video_t *video)
\r
259 //printf("\n\n 1st vmem_remain=%u\n", video->vmem_remain);
\r
260 for(i=0; i<video->num_of_pages; i++)
\r
262 video->vmem_remain-=video->page[i].pagesize;
\r
263 //printf(" [%u], video->page[%u].pagesize=%u\n", i, i, video->page[i].pagesize);
\r
264 //printf(" [%u], vmem_remain=%u\n", i, video->vmem_remain);
\r
268 void modexHiganbanaPageSetup(video_t *video)
\r
270 video->vmem_remain=65535U;
\r
271 video->num_of_pages=0;
\r
272 (video->page[0]) = modexDefaultPage(&(video->page[0])); video->num_of_pages++; //video->page[0].width += (TILEWHD); video->page[0].height += (TILEWHD);
\r
273 (video->page[1]) = modexNextPage(&(video->page[0])); video->num_of_pages++;
\r
274 //0000 (video->page[2]) = modexNextPageFlexibleSize(&(video->page[1]), (video->page[0]).width, TILEWH*4); video->num_of_pages++;
\r
275 //0000 (video->page[3]) = (video->page[2]); video->num_of_pages++;
\r
276 (video->page[2]) = modexNextPageFlexibleSize(&(video->page[1]), TILEWH*4, TILEWH*4); video->num_of_pages++;
\r
277 // (video->page[3]) = modexNextPageFlexibleSize(&(video->page[2]), video->page[0].width, 176); video->num_of_pages++;
\r
278 (video->page[3]) = modexNextPageFlexibleSize(&(video->page[2]), video->page[0].sw, 208); video->num_of_pages++;
\r
279 // (video->page[2]) = modexNextPageFlexibleSize(&(video->page[1]), video->page[0].width, 172); video->num_of_pages++;
\r
280 // (video->page[3]) = modexNextPageFlexibleSize(&(video->page[2]), 72, 128); video->num_of_pages++;
\r
281 modexCalcVmemRemain(video);
\r
287 modexShowPage(page_t *page) {
\r
293 /* calculate offset */
\r
294 offset = (word) page->data;
\r
295 offset += page->dy * (page->width >> 2 );
\r
296 offset += page->dx >> 2;
\r
298 /* calculate crtcOffset according to virtual width */
\r
299 crtcOffset = page->width >> 3;
\r
301 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
302 low_address = LOW_ADDRESS | (offset << 8);
\r
304 /* wait for appropriate timing and then program CRTC */
\r
305 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
306 outpw(CRTC_INDEX, high_address);
\r
307 outpw(CRTC_INDEX, low_address);
\r
308 outp(CRTC_INDEX, 0x13);
\r
309 outp(CRTC_DATA, crtcOffset);
\r
311 /* wait for one retrace */
\r
312 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
314 /* do PEL panning here */
\r
315 outp(AC_INDEX, 0x33);
\r
316 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
320 modexPanPage(page_t *page, int dx, int dy) {
\r
326 modexSelectPlane(byte plane) {
\r
327 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
328 outp(SC_DATA, plane);
\r
332 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
333 word pageOff = (word) page->data;
\r
334 word xoff=x/4; /* xoffset that begins each row */
\r
335 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
336 word poffset = pageOff + y*(page->stridew) + xoff; /* starting offset */
\r
337 word nextRow = page->stridew-scanCount-1; /* loc of next row */
\r
338 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
339 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
340 byte left = lclip[x&0x03];
\r
341 byte right = rclip[(x+w)&0x03];
\r
343 /* handle the case which requires an extra group */
\r
344 if((x & 0x03) && !((x+w) & 0x03)) {
\r
348 //printf("modexClearRegion(x=%u, y=%u, w=%u, h=%u, left=%u, right=%u)\n", x, y, w, h, left, right);
\r
359 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
361 MOV DI, poffset ; go to the first pixel
\r
362 MOV DX, SC_INDEX ; point to the map mask
\r
366 MOV AL, color ; get ready to write colors
\r
368 MOV CX, scanCount ; count the line
\r
369 MOV BL, AL ; remember color
\r
370 MOV AL, left ; do the left clip
\r
371 OUT DX, AL ; set the left clip
\r
372 MOV AL, BL ; restore color
\r
373 STOSB ; write the color
\r
375 JZ SCAN_DONE ; handle 1 group stuff
\r
377 ;-- write the main body of the scanline
\r
378 MOV BL, AL ; remember color
\r
379 MOV AL, 0x0f ; write to all pixels
\r
381 MOV AL, BL ; restore color
\r
382 REP STOSB ; write the color
\r
384 MOV BL, AL ; remeber color
\r
386 OUT DX, AL ; do the right clip
\r
387 MOV AL, BL ; restore color
\r
388 STOSB ; write pixel
\r
389 ADD DI, nextRow ; go to the next row
\r
403 /* moved to src/lib/modex16/16render.c */
\r
405 /* copy a region of video memory from one page to another.
\r
406 * It assumes that the left edge of the tile is the same on both
\r
407 * regions and the memory areas do not overlap.
\r
410 modexCopyPageRegion(page_t *dest, page_t *src,
\r
413 word width, word height)
\r
415 word doffset = (word)dest->data + dy*(dest->stridew) + dx/4;
\r
416 word soffset = (word)src->data + sy*(src->stridew) + sx/4;
\r
417 word scans = vga_state.vga_stride+8; //++++0000 the quick and dirty fix of the major issue with p16 video display wwww
\r
418 word nextSrcRow = src->stridew - scans - 1;
\r
419 word nextDestRow = dest->stridew - scans - 1;
\r
420 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
421 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
422 byte left = lclip[sx&0x03];
\r
423 byte right = rclip[(sx+width)&0x03];
\r
425 /* handle the case which requires an extra group */
\r
426 if((sx & 0x03) && !((sx+width) & 0x03)) {
\r
430 // printf("modexCopyPageRegion(src->stridew=%u, dest->stridew=%u, sx=%u, sy=%u, dx=%u, dy=%u, width=%u, height=%u, left=%u, right=%u)\n", src->stridew, dest->stridew, sx, sy, dx, dy, width, height, left, right);
\r
442 MOV AX, SCREEN_SEG ; work in the vga space
\r
447 MOV DX, GC_INDEX ; turn off cpu bits
\r
451 MOV AX, SC_INDEX ; point to the mask register
\r
461 MOV CX, scans ; the number of latches
\r
463 MOV AL, left ; do the left column
\r
468 MOV AL, 0fh ; do the inner columns
\r
470 REP MOVSB ; copy the pixels
\r
472 MOV AL, right ; do the right column
\r
477 MOV AX, SI ; go the start of the next row
\r
478 ADD AX, nextSrcRow ;
\r
481 ADD AX, nextDestRow ;
\r
484 DEC height ; do the rest of the actions
\r
487 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
488 MOV AL, 0ffh ; none from latches
\r
503 /* fade and flash */
\r
505 modexFadeOn(word fade, byte *palette) {
\r
506 fadePalette(-fade, 64, 64/fade+1, palette);
\r
511 modexFadeOff(word fade, byte *palette) {
\r
512 fadePalette(fade, 0, 64/fade+1, palette);
\r
517 modexFlashOn(word fade, byte *palette) {
\r
518 fadePalette(fade, -64, 64/fade+1, palette);
\r
523 modexFlashOff(word fade, byte *palette) {
\r
524 fadePalette(-fade, 0, 64/fade+1, palette);
\r
529 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
533 /* handle the case where we just update */
\r
535 modexPalUpdate1(palette);
\r
539 while(iter > 0) { /* FadeLoop */
\r
540 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
541 tmppal[i] = palette[i] - dim;
\r
542 if(tmppal[i] > 127) {
\r
544 } else if(tmppal[i] > 63) {
\r
548 modexPalUpdate1(tmppal);
\r
555 /* save and load */
\r
557 modexPalSave(byte *palette) {
\r
560 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
561 for(i=0; i<PAL_SIZE; i++) {
\r
562 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
570 ptr = malloc(PAL_SIZE);
\r
572 /* handle errors */
\r
574 printf("Could not allocate palette.\n");
\r
583 modexLoadPalFile(byte *filename, byte **palette) {
\r
587 /* free the palette if it exists */
\r
592 /* allocate the new palette */
\r
593 *palette = modexNewPal();
\r
595 /* open the file */
\r
596 file = fopen(filename, "rb");
\r
598 printf("Could not open palette file: %s\n", filename);
\r
602 /* read the file */
\r
604 while(!feof(file)) {
\r
605 *ptr++ = fgetc(file);
\r
613 modexSavePalFile(char *filename, byte *pal) {
\r
617 /* open the file for writing */
\r
618 file = fopen(filename, "wb");
\r
620 printf("Could not open %s for writing\n", filename);
\r
624 /* write the data to the file */
\r
625 fwrite(pal, 1, PAL_SIZE, file);
\r
633 fadePalette(-1, 64, 1, tmppal);
\r
639 fadePalette(-1, -64, 1, tmppal);
\r
645 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
647 byte *p = bmp->palette;
\r
651 static word a[PAL_SIZE]; //palette array of change values!
\r
652 word z=0, aq=0, aa=0, pp=0;
\r
654 //modexWaitBorder();
\r
655 vga_wait_for_vsync();
\r
658 memset(a, -1, sizeof(a));
\r
659 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
669 // printf("q: %02d\n", (q));
\r
670 // printf("qq: %02d\n", (qq));
\r
671 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
672 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
674 if((*i)<PAL_SIZE/2 && w==0)
\r
676 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
678 //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
679 //____ 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
680 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
685 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
687 //printf("qp=%d\n", qp);
\r
688 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
689 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
690 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
691 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
695 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
697 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
698 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
699 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
702 //if(qp>0) printf("qp=%d\n", qp);
\r
703 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
705 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
706 vga_wait_for_vsync();
\r
707 if((*i)>=PAL_SIZE/2 && w==0)
\r
709 for(; (*i)<PAL_SIZE; (*i)++)
\r
711 //____ 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
712 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
717 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
719 //printf("qp=%d\n", qp);
\r
720 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
721 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
722 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
723 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
727 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
728 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
729 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
732 //printf(" (*i)=%d\n", (*i)/3);
\r
735 printf("\nqqqqqqqq\n\n");
\r
741 long bufSize = (bmp->width * bmp->height);
\r
743 //printf("1(*i)=%02d\n", (*i)/3);
\r
744 //printf("1z=%02d\n", z/3);
\r
745 modexchkcolor(bmp, &q, &a, &aa, &z, i);
\r
746 //printf("2(*i)=%02d\n", (*i)/3);
\r
747 //printf("2z=%02d\n", z/3);
\r
752 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
753 if(a[aq]==-1) aq++;
\r
754 else { aqoffset++; break; }
\r
756 //update the image data here!
\r
757 for(lq=0; lq<bufSize; lq++)
\r
761 use a[qp] instead of bmp->offset for this spot!
\r
766 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
769 //(offset/bmp->offset)*bmp->offset
\r
772 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
773 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
774 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
775 /*if(bmp->data[lq]+bmp->offset==aq)
\r
777 //printf("%02d", bmp->data[lq]);
\r
778 //printf("\n%02d\n", bmp->offset);
\r
779 printf("aq=%02d ", aq);
\r
780 printf("a[aq]=%02d ", a[aq]);
\r
781 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
782 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
783 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
784 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
785 // printf("_%d ", bmp->data[lq]);
\r
786 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
788 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
790 if(bmp->data[lq]+bmp->offset >= aq)
\r
792 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
793 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
795 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
798 //printf("%02d`", bmp->data[lq]);
\r
799 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
802 //printf(" aq=%02d\n", aq);
\r
803 //printf(" aa=%02d\n", aa);
\r
805 //update the palette~
\r
806 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
809 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
814 modexPalUpdate1(byte *p)
\r
817 //modexWaitBorder();
\r
818 vga_wait_for_vsync();
\r
819 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
820 for(i=0; i<PAL_SIZE/2; i++)
\r
822 outp(PAL_DATA_REG, p[i]);
\r
824 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
825 vga_wait_for_vsync();
\r
826 for(; i<PAL_SIZE; i++)
\r
828 outp(PAL_DATA_REG, p[(i)]);
\r
833 modexPalUpdate0(byte *p)
\r
836 //modexWaitBorder();
\r
837 vga_wait_for_vsync();
\r
838 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
839 for(i=0; i<PAL_SIZE/2; i++)
\r
841 outp(PAL_DATA_REG, rand());
\r
843 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
844 vga_wait_for_vsync();
\r
845 for(; i<PAL_SIZE; i++)
\r
847 outp(PAL_DATA_REG, rand());
\r
852 modexPalOverscan(word col)
\r
854 //modexWaitBorder();
\r
855 vga_wait_for_vsync();
\r
856 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
857 outp(PAL_DATA_REG, col);
\r
861 //i want to make another vesion that checks the palette when the palette is being appened~
\r
862 void modexchkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
866 pal = modexNewPal();
\r
868 //printf("q: %02d\n", (*q));
\r
869 printf("chkcolor start~\n");
\r
870 printf("1 (*z): %d\n", (*z)/3);
\r
871 printf("1 (*i): %d\n", (*i)/3);
\r
872 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
873 printf("wwwwwwwwwwwwwwww\n");
\r
874 //check palette for dups
\r
875 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
877 //printf("\n z: %d\n", (*z));
\r
878 //printf(" q: %d\n", (*q));
\r
879 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
882 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
885 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
886 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
890 else for(zz=0; zz<(*q); zz+=3)
\r
892 //printf("zz: %02d\n", zz/3);
\r
895 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
899 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
900 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
903 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
905 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
906 // 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
907 // 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
908 // //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
909 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
914 planned features that i plan to implement~
\r
915 image that has values on the pallete list!
\r
917 no... wait.... no wwww
\r
919 //for(zzii=0; zzii<3; zzii++)
\r
921 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
922 a[(((*z)+(*q)))]=zz;
\r
924 (*aa)=(((*z)+(*q)));
\r
925 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
926 // printf("\n aa: %d\n\n", (*aa));
\r
927 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
928 // printf("wwwwwwwwwwwwwwww\n\n");
\r
932 printf("================\n");
\r
933 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
934 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
935 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
936 printf("================\n");
\r
938 //printf("[%d]", (zz+q));
\r
942 printf("wwwwwwwwwwwwwwww\n");
\r
943 printf("2 (*z): %d\n", (*z)/3);
\r
944 printf("2 (*i): %d\n", (*i)/3);
\r
945 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
946 printf("chkcolor end~\n");
\r
950 void modexputPixel(page_t *page, int x, int y, byte color)
\r
952 word pageOff = (word) page->data;
\r
953 /* Each address accesses four neighboring pixels, so set
\r
954 Write Plane Enable according to which pixel we want
\r
955 to modify. The plane is determined by the two least
\r
956 significant bits of the x-coordinate: */
\r
957 modexSelectPlane(PLANE(x));
\r
958 //outp(SC_INDEX, 0x02);
\r
959 //outp(SC_DATA, 0x01 << (x & 3));
\r
961 /* The offset of the pixel into the video segment is
\r
962 offset = (width * y + x) / 4, and write the given
\r
963 color to the plane we selected above. Heed the active
\r
964 page start selection. */
\r
965 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
969 byte modexgetPixel(page_t *page, int x, int y)
\r
971 word pageOff = (word) page->data;
\r
972 /* Select the plane from which we must read the pixel color: */
\r
973 outpw(GC_INDEX, 0x04);
\r
974 outpw(GC_INDEX+1, x & 3);
\r
976 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
980 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
984 word addr = (word) romFontsData.l;
\r
985 word addrq = (page->width/4) * y + (x / 4) + ((word)page->data);
\r
986 word addrr = addrq;
\r
991 w=romFonts[t].charSize;
\r
992 romFontsData.chw=0;
\r
994 for(; *str != '\0'; str++)
\r
1000 romFontsData.chw = 0;
\r
1001 addrq += (page->width / 4) * 8;
\r
1007 // load the character into romFontsData.l
\r
1008 // no need for inline assembly!
\r
1009 // NTS: It might even be faster to just let the modexDrawChar point directly at ROM font than to copy per char! --J.C.
\r
1010 _fmemcpy(romFontsData.l,MK_FP(s,o+(w*c))/*ROM font location*/,w/*char size*/);
\r
1011 modexDrawChar(page, x_draw/*for mode X planar use*/, t, col, bgcol, addrr);
\r
1012 x_draw += 8; /* track X for edge of screen */
\r
1013 addrr += 2; /* move 8 pixels over (2 x 4 planar pixels per byte) */
\r
1017 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1019 word i, s, o, w, j, xp;
\r
1021 word addr = (word) l;
\r
1045 s=romFonts[t].seg;
\r
1046 o=romFonts[t].off;
\r
1048 for(; *str != '\0'; str++)
\r
1051 if((c=='\n'/* || c=="\
\r
1052 "*/)/* || chw>=page->width*/)
\r
1058 //load the letter 'A'
\r
1073 MOV AL, c ; the letter
\r
1076 ADD SI, AX ;the address of charcter
\r
1094 for(i=0; i<w; i++)
\r
1100 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1101 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1110 /* palette dump on display! */
\r
1111 void modexpdump(page_t *pee)
\r
1113 int mult=(QUADWH);
\r
1114 int palq=(mult)*TILEWH;
\r
1117 for(paly=0; paly<palq; paly+=mult){
\r
1118 for(palx=0; palx<palq; palx+=mult){
\r
1119 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
\r
1125 /////////////////////////////////////////////////////////////////////////////
\r
1127 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1128 // the Virtual screen. //
\r
1130 /////////////////////////////////////////////////////////////////////////////
\r
1131 void modexcls(page_t *page, byte color, byte *Where)
\r
1133 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1134 /* set map mask to all 4 planes */
\r
1135 outpw(SC_INDEX, 0xff02);
\r
1136 //_fmemset(VGA, color, 16000);
\r
1137 _fmemset(Where, color, page->width*(page->height)/4);
\r
1141 modexWaitBorder() {
\r
1142 while(inp(INPUT_STATUS_1) & 8) {
\r
1146 // while(!(inp(INPUT_STATUS_1) & 8)) {
\r
1151 void modexprintmeminfo(video_t *v)
\r
1154 printf("video memory remaining: %u\n", v->vmem_remain);
\r
1156 for(i=0; i<v->num_of_pages;i++)
\r
1158 printf(" [%u]=", i);
\r
1159 printf("(%Fp)", (v->page[i].data));
\r
1160 printf(" size=%u ", v->page[i].pagesize);
\r
1161 printf("sw=%lu sh=%lu ", (unsigned long)v->page[i].sw, (unsigned long)v->page[i].sh);
\r
1162 printf(" width=%lu height=%lu", (unsigned long)v->page[i].width, (unsigned long)v->page[i].height);
\r