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.pattern_ofs=0;
\r
201 page.stridew=page.width/4;
\r
202 page.pagesize = (word)(page.stridew)*page.height;
\r
203 page.pi=page.width*4;
\r
209 /* returns the next page in contiguous memory
\r
210 * the next page will be the same size as p, by default
\r
213 modexNextPage(page_t *p) {
\r
216 result.data = p->data + (p->pagesize);
\r
221 result.width = p->width;
\r
222 result.height = p->height;
\r
225 result.tilesw = p->tilesw;
\r
226 result.tilesh = p->tilesh;
\r
227 result.stridew=p->stridew;
\r
228 result.pattern_ofs = 0x10000UL - p->pagesize;
\r
229 result.pagesize = p->pagesize;
\r
230 result.pi=result.width*4;
\r
231 result.id = p->id+1;
\r
236 //next page with defined dimentions~
\r
238 modexNextPageFlexibleSize(page_t *p, word x, word y)
\r
242 result.data = p->data + (p->pagesize); /* compute the offset */
\r
249 result.tw = result.sw/TILEWH;
\r
250 result.th = result.sh/TILEWH;
\r
251 result.tilesw=result.width/TILEWH;
\r
252 result.tilesh=result.height/TILEWH;
\r
253 result.pattern_ofs=0x10000UL - (p->pattern_ofs+p->pagesize);
\r
254 result.id = p->id+1;
\r
255 result.stridew=p->sw/4;//result.width/4;
\r
256 result.pagesize = (word)(result.stridew)*result.height;
\r
260 result.pi=p->width*4;
\r
270 void modexCalcVmemRemain(video_t *video)
\r
273 //printf("\n\n 1st vmem_remain=%u\n", video->vmem_remain);
\r
274 for(i=0; i<video->num_of_pages; i++)
\r
276 video->vmem_remain-=video->page[i].pagesize;
\r
277 //printf(" [%u], video->page[%u].pagesize=%u\n", i, i, video->page[i].pagesize);
\r
278 //printf(" [%u], vmem_remain=%u\n", i, video->vmem_remain);
\r
282 void modexHiganbanaPageSetup(video_t *video)
\r
284 video->vmem_remain=65535U;
\r
285 video->num_of_pages=0;
\r
286 (video->page[0]) = modexDefaultPage(&(video->page[0])); video->num_of_pages++; //video->page[0].width += (TILEWHD); video->page[0].height += (TILEWHD);
\r
287 (video->page[1]) = modexNextPage(&(video->page[0])); video->num_of_pages++;
\r
288 //0000 (video->page[2]) = modexNextPageFlexibleSize(&(video->page[1]), (video->page[0]).width, TILEWH*4); video->num_of_pages++;
\r
289 //0000 (video->page[3]) = (video->page[2]); video->num_of_pages++;
\r
290 (video->page[2]) = modexNextPageFlexibleSize(&(video->page[1]), TILEWH*4, TILEWH*4); video->num_of_pages++;
\r
291 // (video->page[3]) = modexNextPageFlexibleSize(&(video->page[2]), video->page[0].width, 176); video->num_of_pages++;
\r
292 (video->page[3]) = modexNextPageFlexibleSize(&(video->page[2]), video->page[0].sw, 208); video->num_of_pages++;
\r
293 // (video->page[2]) = modexNextPageFlexibleSize(&(video->page[1]), video->page[0].width, 172); video->num_of_pages++;
\r
294 // (video->page[3]) = modexNextPageFlexibleSize(&(video->page[2]), 72, 128); video->num_of_pages++;
\r
295 modexCalcVmemRemain(video);
\r
301 modexShowPage(page_t *page) {
\r
307 /* calculate offset */
\r
308 offset = (word) page->data;
\r
309 offset += page->dy * (page->width >> 2 );
\r
310 offset += page->dx >> 2;
\r
312 /* calculate crtcOffset according to virtual width */
\r
313 crtcOffset = page->width >> 3;
\r
315 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
316 low_address = LOW_ADDRESS | (offset << 8);
\r
318 /* wait for appropriate timing and then program CRTC */
\r
319 //while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
320 outpw(CRTC_INDEX, high_address);
\r
321 outpw(CRTC_INDEX, low_address);
\r
322 outp(CRTC_INDEX, 0x13);
\r
323 outp(CRTC_DATA, crtcOffset);
\r
325 /* wait for one retrace */
\r
326 //while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
328 /* do PEL panning here */
\r
329 outp(AC_INDEX, 0x33);
\r
330 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
334 modexPanPage(page_t *page, int dx, int dy) {
\r
340 modexSelectPlane(byte plane) {
\r
341 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
342 outp(SC_DATA, plane);
\r
346 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
347 word pageOff = (word) page->data;
\r
348 word xoff=x/4; /* xoffset that begins each row */
\r
349 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
350 word poffset = pageOff + y*(page->stridew) + xoff; /* starting offset */
\r
351 word nextRow = page->stridew-scanCount-1; /* loc of next row */
\r
352 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
353 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
354 byte left = lclip[x&0x03];
\r
355 byte right = rclip[(x+w)&0x03];
\r
357 /* handle the case which requires an extra group */
\r
358 if((x & 0x03) && !((x+w) & 0x03)) {
\r
362 //printf("modexClearRegion(x=%u, y=%u, w=%u, h=%u, left=%u, right=%u)\n", x, y, w, h, left, right);
\r
373 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
375 MOV DI, poffset ; go to the first pixel
\r
376 MOV DX, SC_INDEX ; point to the map mask
\r
380 MOV AL, color ; get ready to write colors
\r
382 MOV CX, scanCount ; count the line
\r
383 MOV BL, AL ; remember color
\r
384 MOV AL, left ; do the left clip
\r
385 OUT DX, AL ; set the left clip
\r
386 MOV AL, BL ; restore color
\r
387 STOSB ; write the color
\r
389 JZ SCAN_DONE ; handle 1 group stuff
\r
391 ;-- write the main body of the scanline
\r
392 MOV BL, AL ; remember color
\r
393 MOV AL, 0x0f ; write to all pixels
\r
395 MOV AL, BL ; restore color
\r
396 REP STOSB ; write the color
\r
398 MOV BL, AL ; remeber color
\r
400 OUT DX, AL ; do the right clip
\r
401 MOV AL, BL ; restore color
\r
402 STOSB ; write pixel
\r
403 ADD DI, nextRow ; go to the next row
\r
417 /* moved to src/lib/modex16/16render.c */
\r
419 /* copy a region of video memory from one page to another.
\r
420 * It assumes that the left edge of the tile is the same on both
\r
421 * regions and the memory areas do not overlap.
\r
424 modexCopyPageRegion(page_t *dest, page_t *src,
\r
427 word width, word height)
\r
429 word doffset = (word)dest->data + dy*(dest->stridew) + dx/4;
\r
430 word soffset = (word)src->data + sy*(src->stridew) + sx/4;
\r
431 word scans = vga_state.vga_stride; //++++0000 the quick and dirty fix of the major issue with p16 video display wwww
\r
432 word nextSrcRow = src->stridew - scans - 1;
\r
433 word nextDestRow = dest->stridew - scans - 1;
\r
434 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
435 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
436 byte left = lclip[sx&0x03];
\r
437 byte right = rclip[(sx+width)&0x03];
\r
439 /* handle the case which requires an extra group */
\r
440 if((sx & 0x03) && !((sx+width) & 0x03)) {
\r
444 // 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
456 MOV AX, SCREEN_SEG ; work in the vga space
\r
461 MOV DX, GC_INDEX ; turn off cpu bits
\r
465 MOV AX, SC_INDEX ; point to the mask register
\r
475 MOV CX, scans ; the number of latches
\r
477 MOV AL, left ; do the left column
\r
482 MOV AL, 0fh ; do the inner columns
\r
484 REP MOVSB ; copy the pixels
\r
486 MOV AL, right ; do the right column
\r
491 MOV AX, SI ; go the start of the next row
\r
492 ADD AX, nextSrcRow ;
\r
495 ADD AX, nextDestRow ;
\r
498 DEC height ; do the rest of the actions
\r
501 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
502 MOV AL, 0ffh ; none from latches
\r
517 /* fade and flash */
\r
519 modexFadeOn(word fade, byte *palette) {
\r
520 fadePalette(-fade, 64, 64/fade+1, palette);
\r
525 modexFadeOff(word fade, byte *palette) {
\r
526 fadePalette(fade, 0, 64/fade+1, palette);
\r
531 modexFlashOn(word fade, byte *palette) {
\r
532 fadePalette(fade, -64, 64/fade+1, palette);
\r
537 modexFlashOff(word fade, byte *palette) {
\r
538 fadePalette(-fade, 0, 64/fade+1, palette);
\r
543 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
547 /* handle the case where we just update */
\r
549 modexPalUpdate1(palette);
\r
553 while(iter > 0) { /* FadeLoop */
\r
554 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
555 tmppal[i] = palette[i] - dim;
\r
556 if(tmppal[i] > 127) {
\r
558 } else if(tmppal[i] > 63) {
\r
562 modexPalUpdate1(tmppal);
\r
569 /* save and load */
\r
571 modexPalSave(byte *palette) {
\r
574 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
575 for(i=0; i<PAL_SIZE; i++) {
\r
576 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
584 ptr = malloc(PAL_SIZE);
\r
586 /* handle errors */
\r
588 printf("Could not allocate palette.\n");
\r
597 modexLoadPalFile(byte *filename, byte **palette) {
\r
601 /* free the palette if it exists */
\r
606 /* allocate the new palette */
\r
607 *palette = modexNewPal();
\r
609 /* open the file */
\r
610 file = fopen(filename, "rb");
\r
612 printf("Could not open palette file: %s\n", filename);
\r
616 /* read the file */
\r
618 while(!feof(file)) {
\r
619 *ptr++ = fgetc(file);
\r
627 modexSavePalFile(char *filename, byte *pal) {
\r
631 /* open the file for writing */
\r
632 file = fopen(filename, "wb");
\r
634 printf("Could not open %s for writing\n", filename);
\r
638 /* write the data to the file */
\r
639 fwrite(pal, 1, PAL_SIZE, file);
\r
647 fadePalette(-1, 64, 1, tmppal);
\r
653 fadePalette(-1, -64, 1, tmppal);
\r
659 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
661 byte *p = bmp->palette;
\r
665 static word a[PAL_SIZE]; //palette array of change values!
\r
666 word z=0, aq=0, aa=0, pp=0;
\r
668 //modexWaitBorder();
\r
669 vga_wait_for_vsync();
\r
672 memset(a, -1, sizeof(a));
\r
673 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
683 // printf("q: %02d\n", (q));
\r
684 // printf("qq: %02d\n", (qq));
\r
685 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
686 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
688 if((*i)<PAL_SIZE/2 && w==0)
\r
690 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
692 //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
693 //____ 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
694 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
699 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
701 //printf("qp=%d\n", qp);
\r
702 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
703 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
704 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
705 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
709 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
711 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
712 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
713 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
716 //if(qp>0) printf("qp=%d\n", qp);
\r
717 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
719 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
720 vga_wait_for_vsync();
\r
721 if((*i)>=PAL_SIZE/2 && w==0)
\r
723 for(; (*i)<PAL_SIZE; (*i)++)
\r
725 //____ 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
726 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
731 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
733 //printf("qp=%d\n", qp);
\r
734 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
735 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
736 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
737 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
741 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
742 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
743 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
746 //printf(" (*i)=%d\n", (*i)/3);
\r
749 printf("\nqqqqqqqq\n\n");
\r
755 long bufSize = (bmp->width * bmp->height);
\r
757 //printf("1(*i)=%02d\n", (*i)/3);
\r
758 //printf("1z=%02d\n", z/3);
\r
759 modexchkcolor(bmp, &q, &a, &aa, &z, i);
\r
760 //printf("2(*i)=%02d\n", (*i)/3);
\r
761 //printf("2z=%02d\n", z/3);
\r
766 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
767 if(a[aq]==-1) aq++;
\r
768 else { aqoffset++; break; }
\r
770 //update the image data here!
\r
771 for(lq=0; lq<bufSize; lq++)
\r
775 use a[qp] instead of bmp->offset for this spot!
\r
780 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
783 //(offset/bmp->offset)*bmp->offset
\r
786 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
787 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
788 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
789 /*if(bmp->data[lq]+bmp->offset==aq)
\r
791 //printf("%02d", bmp->data[lq]);
\r
792 //printf("\n%02d\n", bmp->offset);
\r
793 printf("aq=%02d ", aq);
\r
794 printf("a[aq]=%02d ", a[aq]);
\r
795 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
796 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
797 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
798 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
799 // printf("_%d ", bmp->data[lq]);
\r
800 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
802 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
804 if(bmp->data[lq]+bmp->offset >= aq)
\r
806 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
807 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
809 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
812 //printf("%02d`", bmp->data[lq]);
\r
813 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
816 //printf(" aq=%02d\n", aq);
\r
817 //printf(" aa=%02d\n", aa);
\r
819 //update the palette~
\r
820 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
823 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
828 modexPalUpdate1(byte *p)
\r
831 //modexWaitBorder();
\r
832 vga_wait_for_vsync();
\r
833 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
834 for(i=0; i<PAL_SIZE/2; i++)
\r
836 outp(PAL_DATA_REG, p[i]);
\r
838 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
839 vga_wait_for_vsync();
\r
840 for(; i<PAL_SIZE; i++)
\r
842 outp(PAL_DATA_REG, p[(i)]);
\r
847 modexPalUpdate0(byte *p)
\r
850 //modexWaitBorder();
\r
851 vga_wait_for_vsync();
\r
852 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
853 for(i=0; i<PAL_SIZE/2; i++)
\r
855 outp(PAL_DATA_REG, rand());
\r
857 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
858 vga_wait_for_vsync();
\r
859 for(; i<PAL_SIZE; i++)
\r
861 outp(PAL_DATA_REG, rand());
\r
866 modexPalOverscan(word col)
\r
868 //modexWaitBorder();
\r
869 vga_wait_for_vsync();
\r
870 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
871 outp(PAL_DATA_REG, col);
\r
875 //i want to make another vesion that checks the palette when the palette is being appened~
\r
876 void modexchkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
880 pal = modexNewPal();
\r
882 //printf("q: %02d\n", (*q));
\r
883 printf("chkcolor start~\n");
\r
884 printf("1 (*z): %d\n", (*z)/3);
\r
885 printf("1 (*i): %d\n", (*i)/3);
\r
886 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
887 printf("wwwwwwwwwwwwwwww\n");
\r
888 //check palette for dups
\r
889 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
891 //printf("\n z: %d\n", (*z));
\r
892 //printf(" q: %d\n", (*q));
\r
893 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
896 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
899 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
900 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
904 else for(zz=0; zz<(*q); zz+=3)
\r
906 //printf("zz: %02d\n", zz/3);
\r
909 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
913 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
914 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
917 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
919 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
920 // 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
921 // 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
922 // //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
923 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
928 planned features that i plan to implement~
\r
929 image that has values on the pallete list!
\r
931 no... wait.... no wwww
\r
933 //for(zzii=0; zzii<3; zzii++)
\r
935 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
936 a[(((*z)+(*q)))]=zz;
\r
938 (*aa)=(((*z)+(*q)));
\r
939 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
940 // printf("\n aa: %d\n\n", (*aa));
\r
941 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
942 // printf("wwwwwwwwwwwwwwww\n\n");
\r
946 printf("================\n");
\r
947 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
948 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
949 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
950 printf("================\n");
\r
952 //printf("[%d]", (zz+q));
\r
956 printf("wwwwwwwwwwwwwwww\n");
\r
957 printf("2 (*z): %d\n", (*z)/3);
\r
958 printf("2 (*i): %d\n", (*i)/3);
\r
959 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
960 printf("chkcolor end~\n");
\r
964 void modexputPixel(page_t *page, int x, int y, byte color)
\r
966 word pageOff = (word) page->data;
\r
967 /* Each address accesses four neighboring pixels, so set
\r
968 Write Plane Enable according to which pixel we want
\r
969 to modify. The plane is determined by the two least
\r
970 significant bits of the x-coordinate: */
\r
971 modexSelectPlane(PLANE(x));
\r
972 //outp(SC_INDEX, 0x02);
\r
973 //outp(SC_DATA, 0x01 << (x & 3));
\r
975 /* The offset of the pixel into the video segment is
\r
976 offset = (width * y + x) / 4, and write the given
\r
977 color to the plane we selected above. Heed the active
\r
978 page start selection. */
\r
979 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
983 byte modexgetPixel(page_t *page, int x, int y)
\r
985 word pageOff = (word) page->data;
\r
986 /* Select the plane from which we must read the pixel color: */
\r
987 outpw(GC_INDEX, 0x04);
\r
988 outpw(GC_INDEX+1, x & 3);
\r
990 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
994 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
998 word addr = (word) romFontsData.l;
\r
999 word addrq = (page->width/4) * y + (x / 4) + ((word)page->data);
\r
1000 word addrr = addrq;
\r
1003 s=romFonts[t].seg;
\r
1004 o=romFonts[t].off;
\r
1005 w=romFonts[t].charSize;
\r
1006 romFontsData.chw=0;
\r
1008 for(; *str != '\0'; str++)
\r
1014 romFontsData.chw = 0;
\r
1015 addrq += (page->width / 4) * 8;
\r
1021 // load the character into romFontsData.l
\r
1022 // no need for inline assembly!
\r
1023 // NTS: It might even be faster to just let the modexDrawChar point directly at ROM font than to copy per char! --J.C.
\r
1024 _fmemcpy(romFontsData.l,MK_FP(s,o+(w*c))/*ROM font location*/,w/*char size*/);
\r
1025 modexDrawChar(page, x_draw/*for mode X planar use*/, t, col, bgcol, addrr);
\r
1026 x_draw += 8; /* track X for edge of screen */
\r
1027 addrr += 2; /* move 8 pixels over (2 x 4 planar pixels per byte) */
\r
1031 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1033 word i, s, o, w, j, xp;
\r
1035 word addr = (word) l;
\r
1059 s=romFonts[t].seg;
\r
1060 o=romFonts[t].off;
\r
1062 for(; *str != '\0'; str++)
\r
1065 if((c=='\n'/* || c=="\
\r
1066 "*/)/* || chw>=page->width*/)
\r
1072 //load the letter 'A'
\r
1087 MOV AL, c ; the letter
\r
1090 ADD SI, AX ;the address of charcter
\r
1108 for(i=0; i<w; i++)
\r
1114 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1115 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1124 /* palette dump on display! */
\r
1125 void modexpdump(page_t *pee)
\r
1127 int mult=(QUADWH);
\r
1128 int palq=(mult)*TILEWH;
\r
1131 for(paly=0; paly<palq; paly+=mult){
\r
1132 for(palx=0; palx<palq; palx+=mult){
\r
1133 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
\r
1139 /////////////////////////////////////////////////////////////////////////////
\r
1141 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1142 // the Virtual screen. //
\r
1144 /////////////////////////////////////////////////////////////////////////////
\r
1145 void modexcls(page_t *page, byte color, byte *Where)
\r
1147 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1148 /* set map mask to all 4 planes */
\r
1149 outpw(SC_INDEX, 0xff02);
\r
1150 //_fmemset(VGA, color, 16000);
\r
1151 _fmemset(Where, color, page->width*(page->height)/4);
\r
1155 modexWaitBorder() {
\r
1156 while(inp(INPUT_STATUS_1) & 8) {
\r
1160 while(!(inp(INPUT_STATUS_1) & 8)) {
\r
1165 void modexprintmeminfo(video_t *v)
\r
1168 printf("video memory remaining: %u\n", v->vmem_remain);
\r
1170 for(i=0; i<v->num_of_pages;i++)
\r
1172 printf(" [%u]=", i);
\r
1173 printf("(%Fp)", (v->page[i].data));
\r
1174 printf(" size=%u ", v->page[i].pagesize);
\r
1175 printf("w=%lu h=%lu ", (unsigned long)v->page[i].width, (unsigned long)v->page[i].height);
\r
1176 printf("sw=%lu sh=%lu ", (unsigned long)v->page[i].sw, (unsigned long)v->page[i].sh);
\r
1177 printf("pi=%u", v->page[i].pi);
\r