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
208 /* returns the next page in contiguous memory
\r
209 * the next page will be the same size as p, by default
\r
212 modexNextPage(page_t *p) {
\r
215 result.data = p->data + (p->pagesize);
\r
220 result.width = p->width;
\r
221 result.height = p->height;
\r
224 result.tilesw = p->tilesw;
\r
225 result.tilesh = p->tilesh;
\r
226 result.stridew=p->stridew;
\r
227 result.pagesize = p->pagesize;
\r
229 result.id = p->id+1;
\r
234 //next page with defined dimentions~
\r
236 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
240 result.data = p->data + (p->pagesize); /* compute the offset */
\r
247 result.tw = result.sw/TILEWH;
\r
248 result.th = result.sh/TILEWH;
\r
249 result.tilesw=result.width/TILEWH;
\r
250 result.tilesh=result.height/TILEWH;
\r
251 result.id = p->id+1;
\r
252 result.stridew=result.width/4;
\r
253 result.pagesize = (word)(result.width/4)*result.height;
\r
254 if(result.id==2) result.pi=p->width*p->pi;
\r
255 else if(result.id==3) result.pi=p->pi;
\r
260 void modexCalcVmemRemain(video_t *video)
\r
263 //printf("\n\n 1st vmem_remain=%u\n", video->vmem_remain);
\r
264 for(i=0; i<video->num_of_pages; i++)
\r
266 video->vmem_remain-=video->page[i].pagesize;
\r
267 //printf(" [%u], video->page[%u].pagesize=%u\n", i, i, video->page[i].pagesize);
\r
268 //printf(" [%u], vmem_remain=%u\n", i, video->vmem_remain);
\r
272 void modexHiganbanaPageSetup(video_t *video)
\r
274 video->vmem_remain=65535U;
\r
275 video->num_of_pages=0;
\r
276 (video->page[0]) = modexDefaultPage(&(video->page[0])); video->num_of_pages++; //video->page[0].width += (TILEWHD); video->page[0].height += (TILEWHD);
\r
277 (video->page[1]) = modexNextPage(&(video->page[0])); video->num_of_pages++;
\r
278 //0000 (video->page[2]) = modexNextPageFlexibleSize(&(video->page[1]), (video->page[0]).width, TILEWH*4); video->num_of_pages++;
\r
279 //0000 (video->page[3]) = (video->page[2]); video->num_of_pages++;
\r
280 (video->page[2]) = modexNextPageFlexibleSize(&(video->page[1]), TILEWH*4, TILEWH*4); video->num_of_pages++;
\r
281 // (video->page[3]) = modexNextPageFlexibleSize(&(video->page[2]), video->page[0].width, 176); video->num_of_pages++;
\r
282 (video->page[3]) = modexNextPageFlexibleSize(&(video->page[2]), video->page[0].sw, 208); video->num_of_pages++;
\r
283 // (video->page[2]) = modexNextPageFlexibleSize(&(video->page[1]), video->page[0].width, 172); video->num_of_pages++;
\r
284 // (video->page[3]) = modexNextPageFlexibleSize(&(video->page[2]), 72, 128); video->num_of_pages++;
\r
285 modexCalcVmemRemain(video);
\r
291 modexShowPage(page_t *page) {
\r
297 /* calculate offset */
\r
298 offset = (word) page->data;
\r
299 offset += page->dy * (page->width >> 2 );
\r
300 offset += page->dx >> 2;
\r
302 /* calculate crtcOffset according to virtual width */
\r
303 crtcOffset = page->width >> 3;
\r
305 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
306 low_address = LOW_ADDRESS | (offset << 8);
\r
308 /* wait for appropriate timing and then program CRTC */
\r
309 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
310 outpw(CRTC_INDEX, high_address);
\r
311 outpw(CRTC_INDEX, low_address);
\r
312 outp(CRTC_INDEX, 0x13);
\r
313 outp(CRTC_DATA, crtcOffset);
\r
315 /* wait for one retrace */
\r
316 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
318 /* do PEL panning here */
\r
319 outp(AC_INDEX, 0x33);
\r
320 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
324 modexPanPage(page_t *page, int dx, int dy) {
\r
330 modexSelectPlane(byte plane) {
\r
331 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
332 outp(SC_DATA, plane);
\r
336 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
337 word pageOff = (word) page->data;
\r
338 word xoff=x/4; /* xoffset that begins each row */
\r
339 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
340 word poffset = pageOff + y*(page->stridew) + xoff; /* starting offset */
\r
341 word nextRow = page->stridew-scanCount-1; /* loc of next row */
\r
342 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
343 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
344 byte left = lclip[x&0x03];
\r
345 byte right = rclip[(x+w)&0x03];
\r
347 /* handle the case which requires an extra group */
\r
348 if((x & 0x03) && !((x+w) & 0x03)) {
\r
352 //printf("modexClearRegion(x=%u, y=%u, w=%u, h=%u, left=%u, right=%u)\n", x, y, w, h, left, right);
\r
363 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
365 MOV DI, poffset ; go to the first pixel
\r
366 MOV DX, SC_INDEX ; point to the map mask
\r
370 MOV AL, color ; get ready to write colors
\r
372 MOV CX, scanCount ; count the line
\r
373 MOV BL, AL ; remember color
\r
374 MOV AL, left ; do the left clip
\r
375 OUT DX, AL ; set the left clip
\r
376 MOV AL, BL ; restore color
\r
377 STOSB ; write the color
\r
379 JZ SCAN_DONE ; handle 1 group stuff
\r
381 ;-- write the main body of the scanline
\r
382 MOV BL, AL ; remember color
\r
383 MOV AL, 0x0f ; write to all pixels
\r
385 MOV AL, BL ; restore color
\r
386 REP STOSB ; write the color
\r
388 MOV BL, AL ; remeber color
\r
390 OUT DX, AL ; do the right clip
\r
391 MOV AL, BL ; restore color
\r
392 STOSB ; write pixel
\r
393 ADD DI, nextRow ; go to the next row
\r
407 /* moved to src/lib/modex16/16render.c */
\r
409 /* copy a region of video memory from one page to another.
\r
410 * It assumes that the left edge of the tile is the same on both
\r
411 * regions and the memory areas do not overlap.
\r
414 modexCopyPageRegion(page_t *dest, page_t *src,
\r
417 word width, word height)
\r
419 word doffset = (word)dest->data + dy*(dest->stridew) + dx/4;
\r
420 word soffset = (word)src->data + sy*(src->stridew) + sx/4;
\r
421 word scans = vga_state.vga_stride+8; //++++0000 the quick and dirty fix of the major issue with p16 video display wwww
\r
422 word nextSrcRow = src->stridew - scans - 1;
\r
423 word nextDestRow = dest->stridew - scans - 1;
\r
424 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
425 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
426 byte left = lclip[sx&0x03];
\r
427 byte right = rclip[(sx+width)&0x03];
\r
429 /* handle the case which requires an extra group */
\r
430 if((sx & 0x03) && !((sx+width) & 0x03)) {
\r
434 // 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
446 MOV AX, SCREEN_SEG ; work in the vga space
\r
451 MOV DX, GC_INDEX ; turn off cpu bits
\r
455 MOV AX, SC_INDEX ; point to the mask register
\r
465 MOV CX, scans ; the number of latches
\r
467 MOV AL, left ; do the left column
\r
472 MOV AL, 0fh ; do the inner columns
\r
474 REP MOVSB ; copy the pixels
\r
476 MOV AL, right ; do the right column
\r
481 MOV AX, SI ; go the start of the next row
\r
482 ADD AX, nextSrcRow ;
\r
485 ADD AX, nextDestRow ;
\r
488 DEC height ; do the rest of the actions
\r
491 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
492 MOV AL, 0ffh ; none from latches
\r
507 /* fade and flash */
\r
509 modexFadeOn(word fade, byte *palette) {
\r
510 fadePalette(-fade, 64, 64/fade+1, palette);
\r
515 modexFadeOff(word fade, byte *palette) {
\r
516 fadePalette(fade, 0, 64/fade+1, palette);
\r
521 modexFlashOn(word fade, byte *palette) {
\r
522 fadePalette(fade, -64, 64/fade+1, palette);
\r
527 modexFlashOff(word fade, byte *palette) {
\r
528 fadePalette(-fade, 0, 64/fade+1, palette);
\r
533 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
537 /* handle the case where we just update */
\r
539 modexPalUpdate1(palette);
\r
543 while(iter > 0) { /* FadeLoop */
\r
544 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
545 tmppal[i] = palette[i] - dim;
\r
546 if(tmppal[i] > 127) {
\r
548 } else if(tmppal[i] > 63) {
\r
552 modexPalUpdate1(tmppal);
\r
559 /* save and load */
\r
561 modexPalSave(byte *palette) {
\r
564 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
565 for(i=0; i<PAL_SIZE; i++) {
\r
566 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
574 ptr = malloc(PAL_SIZE);
\r
576 /* handle errors */
\r
578 printf("Could not allocate palette.\n");
\r
587 modexLoadPalFile(byte *filename, byte **palette) {
\r
591 /* free the palette if it exists */
\r
596 /* allocate the new palette */
\r
597 *palette = modexNewPal();
\r
599 /* open the file */
\r
600 file = fopen(filename, "rb");
\r
602 printf("Could not open palette file: %s\n", filename);
\r
606 /* read the file */
\r
608 while(!feof(file)) {
\r
609 *ptr++ = fgetc(file);
\r
617 modexSavePalFile(char *filename, byte *pal) {
\r
621 /* open the file for writing */
\r
622 file = fopen(filename, "wb");
\r
624 printf("Could not open %s for writing\n", filename);
\r
628 /* write the data to the file */
\r
629 fwrite(pal, 1, PAL_SIZE, file);
\r
637 fadePalette(-1, 64, 1, tmppal);
\r
643 fadePalette(-1, -64, 1, tmppal);
\r
649 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
651 byte *p = bmp->palette;
\r
655 static word a[PAL_SIZE]; //palette array of change values!
\r
656 word z=0, aq=0, aa=0, pp=0;
\r
658 //modexWaitBorder();
\r
659 vga_wait_for_vsync();
\r
662 memset(a, -1, sizeof(a));
\r
663 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
673 // printf("q: %02d\n", (q));
\r
674 // printf("qq: %02d\n", (qq));
\r
675 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
676 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
678 if((*i)<PAL_SIZE/2 && w==0)
\r
680 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
682 //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
683 //____ 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
684 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
689 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
691 //printf("qp=%d\n", qp);
\r
692 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
693 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
694 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
695 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
699 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
701 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
702 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
703 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
706 //if(qp>0) printf("qp=%d\n", qp);
\r
707 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
709 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
710 vga_wait_for_vsync();
\r
711 if((*i)>=PAL_SIZE/2 && w==0)
\r
713 for(; (*i)<PAL_SIZE; (*i)++)
\r
715 //____ 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
716 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
721 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
723 //printf("qp=%d\n", qp);
\r
724 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
725 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
726 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
727 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
731 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
732 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
733 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
736 //printf(" (*i)=%d\n", (*i)/3);
\r
739 printf("\nqqqqqqqq\n\n");
\r
745 long bufSize = (bmp->width * bmp->height);
\r
747 //printf("1(*i)=%02d\n", (*i)/3);
\r
748 //printf("1z=%02d\n", z/3);
\r
749 modexchkcolor(bmp, &q, &a, &aa, &z, i);
\r
750 //printf("2(*i)=%02d\n", (*i)/3);
\r
751 //printf("2z=%02d\n", z/3);
\r
756 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
757 if(a[aq]==-1) aq++;
\r
758 else { aqoffset++; break; }
\r
760 //update the image data here!
\r
761 for(lq=0; lq<bufSize; lq++)
\r
765 use a[qp] instead of bmp->offset for this spot!
\r
770 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
773 //(offset/bmp->offset)*bmp->offset
\r
776 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
777 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
778 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
779 /*if(bmp->data[lq]+bmp->offset==aq)
\r
781 //printf("%02d", bmp->data[lq]);
\r
782 //printf("\n%02d\n", bmp->offset);
\r
783 printf("aq=%02d ", aq);
\r
784 printf("a[aq]=%02d ", a[aq]);
\r
785 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
786 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
787 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
788 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
789 // printf("_%d ", bmp->data[lq]);
\r
790 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
792 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
794 if(bmp->data[lq]+bmp->offset >= aq)
\r
796 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
797 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
799 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
802 //printf("%02d`", bmp->data[lq]);
\r
803 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
806 //printf(" aq=%02d\n", aq);
\r
807 //printf(" aa=%02d\n", aa);
\r
809 //update the palette~
\r
810 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
813 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
818 modexPalUpdate1(byte *p)
\r
821 //modexWaitBorder();
\r
822 vga_wait_for_vsync();
\r
823 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
824 for(i=0; i<PAL_SIZE/2; i++)
\r
826 outp(PAL_DATA_REG, p[i]);
\r
828 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
829 vga_wait_for_vsync();
\r
830 for(; i<PAL_SIZE; i++)
\r
832 outp(PAL_DATA_REG, p[(i)]);
\r
837 modexPalUpdate0(byte *p)
\r
840 //modexWaitBorder();
\r
841 vga_wait_for_vsync();
\r
842 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
843 for(i=0; i<PAL_SIZE/2; i++)
\r
845 outp(PAL_DATA_REG, rand());
\r
847 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
848 vga_wait_for_vsync();
\r
849 for(; i<PAL_SIZE; i++)
\r
851 outp(PAL_DATA_REG, rand());
\r
856 modexPalOverscan(word col)
\r
858 //modexWaitBorder();
\r
859 vga_wait_for_vsync();
\r
860 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
861 outp(PAL_DATA_REG, col);
\r
865 //i want to make another vesion that checks the palette when the palette is being appened~
\r
866 void modexchkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
870 pal = modexNewPal();
\r
872 //printf("q: %02d\n", (*q));
\r
873 printf("chkcolor start~\n");
\r
874 printf("1 (*z): %d\n", (*z)/3);
\r
875 printf("1 (*i): %d\n", (*i)/3);
\r
876 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
877 printf("wwwwwwwwwwwwwwww\n");
\r
878 //check palette for dups
\r
879 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
881 //printf("\n z: %d\n", (*z));
\r
882 //printf(" q: %d\n", (*q));
\r
883 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
886 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
889 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
890 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
894 else for(zz=0; zz<(*q); zz+=3)
\r
896 //printf("zz: %02d\n", zz/3);
\r
899 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
903 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
904 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
907 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
909 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
910 // 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
911 // 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
912 // //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
913 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
918 planned features that i plan to implement~
\r
919 image that has values on the pallete list!
\r
921 no... wait.... no wwww
\r
923 //for(zzii=0; zzii<3; zzii++)
\r
925 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
926 a[(((*z)+(*q)))]=zz;
\r
928 (*aa)=(((*z)+(*q)));
\r
929 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
930 // printf("\n aa: %d\n\n", (*aa));
\r
931 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
932 // printf("wwwwwwwwwwwwwwww\n\n");
\r
936 printf("================\n");
\r
937 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
938 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
939 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
940 printf("================\n");
\r
942 //printf("[%d]", (zz+q));
\r
946 printf("wwwwwwwwwwwwwwww\n");
\r
947 printf("2 (*z): %d\n", (*z)/3);
\r
948 printf("2 (*i): %d\n", (*i)/3);
\r
949 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
950 printf("chkcolor end~\n");
\r
954 void modexputPixel(page_t *page, int x, int y, byte color)
\r
956 word pageOff = (word) page->data;
\r
957 /* Each address accesses four neighboring pixels, so set
\r
958 Write Plane Enable according to which pixel we want
\r
959 to modify. The plane is determined by the two least
\r
960 significant bits of the x-coordinate: */
\r
961 modexSelectPlane(PLANE(x));
\r
962 //outp(SC_INDEX, 0x02);
\r
963 //outp(SC_DATA, 0x01 << (x & 3));
\r
965 /* The offset of the pixel into the video segment is
\r
966 offset = (width * y + x) / 4, and write the given
\r
967 color to the plane we selected above. Heed the active
\r
968 page start selection. */
\r
969 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
973 byte modexgetPixel(page_t *page, int x, int y)
\r
975 word pageOff = (word) page->data;
\r
976 /* Select the plane from which we must read the pixel color: */
\r
977 outpw(GC_INDEX, 0x04);
\r
978 outpw(GC_INDEX+1, x & 3);
\r
980 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
984 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
988 word addr = (word) romFontsData.l;
\r
989 word addrq = (page->width/4) * y + (x / 4) + ((word)page->data);
\r
990 word addrr = addrq;
\r
995 w=romFonts[t].charSize;
\r
996 romFontsData.chw=0;
\r
998 for(; *str != '\0'; str++)
\r
1004 romFontsData.chw = 0;
\r
1005 addrq += (page->width / 4) * 8;
\r
1011 // load the character into romFontsData.l
\r
1012 // no need for inline assembly!
\r
1013 // NTS: It might even be faster to just let the modexDrawChar point directly at ROM font than to copy per char! --J.C.
\r
1014 _fmemcpy(romFontsData.l,MK_FP(s,o+(w*c))/*ROM font location*/,w/*char size*/);
\r
1015 modexDrawChar(page, x_draw/*for mode X planar use*/, t, col, bgcol, addrr);
\r
1016 x_draw += 8; /* track X for edge of screen */
\r
1017 addrr += 2; /* move 8 pixels over (2 x 4 planar pixels per byte) */
\r
1021 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1023 word i, s, o, w, j, xp;
\r
1025 word addr = (word) l;
\r
1049 s=romFonts[t].seg;
\r
1050 o=romFonts[t].off;
\r
1052 for(; *str != '\0'; str++)
\r
1055 if((c=='\n'/* || c=="\
\r
1056 "*/)/* || chw>=page->width*/)
\r
1062 //load the letter 'A'
\r
1077 MOV AL, c ; the letter
\r
1080 ADD SI, AX ;the address of charcter
\r
1098 for(i=0; i<w; i++)
\r
1104 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1105 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1114 /* palette dump on display! */
\r
1115 void modexpdump(page_t *pee)
\r
1117 int mult=(QUADWH);
\r
1118 int palq=(mult)*TILEWH;
\r
1121 for(paly=0; paly<palq; paly+=mult){
\r
1122 for(palx=0; palx<palq; palx+=mult){
\r
1123 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
\r
1129 /////////////////////////////////////////////////////////////////////////////
\r
1131 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1132 // the Virtual screen. //
\r
1134 /////////////////////////////////////////////////////////////////////////////
\r
1135 void modexcls(page_t *page, byte color, byte *Where)
\r
1137 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1138 /* set map mask to all 4 planes */
\r
1139 outpw(SC_INDEX, 0xff02);
\r
1140 //_fmemset(VGA, color, 16000);
\r
1141 _fmemset(Where, color, page->width*(page->height)/4);
\r
1145 modexWaitBorder() {
\r
1146 while(inp(INPUT_STATUS_1) & 8) {
\r
1150 // while(!(inp(INPUT_STATUS_1) & 8)) {
\r
1155 void modexprintmeminfo(video_t *v)
\r
1158 printf("video memory remaining: %u\n", v->vmem_remain);
\r
1160 for(i=0; i<v->num_of_pages;i++)
\r
1162 printf(" [%u]=", i);
\r
1163 printf("(%Fp)", (v->page[i].data));
\r
1164 printf(" size=%u ", v->page[i].pagesize);
\r
1165 printf("sw=%lu sh=%lu ", (unsigned long)v->page[i].sw, (unsigned long)v->page[i].sh);
\r
1166 printf(" width=%lu height=%lu", (unsigned long)v->page[i].width, (unsigned long)v->page[i].height);
\r
1167 printf(" pi=%u" v->page[i].pi);
\r