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
255 result.pi=p->width*p->pi;
\r
256 else if(result.id==3) result.pi=p->pi;
\r
261 void modexCalcVmemRemain(video_t *video)
\r
264 //printf("\n\n 1st vmem_remain=%u\n", video->vmem_remain);
\r
265 for(i=0; i<video->num_of_pages; i++)
\r
267 video->vmem_remain-=video->page[i].pagesize;
\r
268 //printf(" [%u], video->page[%u].pagesize=%u\n", i, i, video->page[i].pagesize);
\r
269 //printf(" [%u], vmem_remain=%u\n", i, video->vmem_remain);
\r
273 void modexHiganbanaPageSetup(video_t *video)
\r
275 video->vmem_remain=65535U;
\r
276 video->num_of_pages=0;
\r
277 (video->page[0]) = modexDefaultPage(&(video->page[0])); video->num_of_pages++; //video->page[0].width += (TILEWHD); video->page[0].height += (TILEWHD);
\r
278 (video->page[1]) = modexNextPage(&(video->page[0])); video->num_of_pages++;
\r
279 //0000 (video->page[2]) = modexNextPageFlexibleSize(&(video->page[1]), (video->page[0]).width, TILEWH*4); video->num_of_pages++;
\r
280 //0000 (video->page[3]) = (video->page[2]); video->num_of_pages++;
\r
281 (video->page[2]) = modexNextPageFlexibleSize(&(video->page[1]), TILEWH*4, TILEWH*4); video->num_of_pages++;
\r
282 // (video->page[3]) = modexNextPageFlexibleSize(&(video->page[2]), video->page[0].width, 176); video->num_of_pages++;
\r
283 (video->page[3]) = modexNextPageFlexibleSize(&(video->page[2]), video->page[0].sw, 208); video->num_of_pages++;
\r
284 // (video->page[2]) = modexNextPageFlexibleSize(&(video->page[1]), video->page[0].width, 172); video->num_of_pages++;
\r
285 // (video->page[3]) = modexNextPageFlexibleSize(&(video->page[2]), 72, 128); video->num_of_pages++;
\r
286 modexCalcVmemRemain(video);
\r
292 modexShowPage(page_t *page) {
\r
298 /* calculate offset */
\r
299 offset = (word) page->data;
\r
300 offset += page->dy * (page->width >> 2 );
\r
301 offset += page->dx >> 2;
\r
303 /* calculate crtcOffset according to virtual width */
\r
304 crtcOffset = page->width >> 3;
\r
306 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
307 low_address = LOW_ADDRESS | (offset << 8);
\r
309 /* wait for appropriate timing and then program CRTC */
\r
310 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
311 outpw(CRTC_INDEX, high_address);
\r
312 outpw(CRTC_INDEX, low_address);
\r
313 outp(CRTC_INDEX, 0x13);
\r
314 outp(CRTC_DATA, crtcOffset);
\r
316 /* wait for one retrace */
\r
317 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
319 /* do PEL panning here */
\r
320 outp(AC_INDEX, 0x33);
\r
321 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
325 modexPanPage(page_t *page, int dx, int dy) {
\r
331 modexSelectPlane(byte plane) {
\r
332 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
333 outp(SC_DATA, plane);
\r
337 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
338 word pageOff = (word) page->data;
\r
339 word xoff=x/4; /* xoffset that begins each row */
\r
340 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
341 word poffset = pageOff + y*(page->stridew) + xoff; /* starting offset */
\r
342 word nextRow = page->stridew-scanCount-1; /* loc of next row */
\r
343 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
344 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
345 byte left = lclip[x&0x03];
\r
346 byte right = rclip[(x+w)&0x03];
\r
348 /* handle the case which requires an extra group */
\r
349 if((x & 0x03) && !((x+w) & 0x03)) {
\r
353 //printf("modexClearRegion(x=%u, y=%u, w=%u, h=%u, left=%u, right=%u)\n", x, y, w, h, left, right);
\r
364 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
366 MOV DI, poffset ; go to the first pixel
\r
367 MOV DX, SC_INDEX ; point to the map mask
\r
371 MOV AL, color ; get ready to write colors
\r
373 MOV CX, scanCount ; count the line
\r
374 MOV BL, AL ; remember color
\r
375 MOV AL, left ; do the left clip
\r
376 OUT DX, AL ; set the left clip
\r
377 MOV AL, BL ; restore color
\r
378 STOSB ; write the color
\r
380 JZ SCAN_DONE ; handle 1 group stuff
\r
382 ;-- write the main body of the scanline
\r
383 MOV BL, AL ; remember color
\r
384 MOV AL, 0x0f ; write to all pixels
\r
386 MOV AL, BL ; restore color
\r
387 REP STOSB ; write the color
\r
389 MOV BL, AL ; remeber color
\r
391 OUT DX, AL ; do the right clip
\r
392 MOV AL, BL ; restore color
\r
393 STOSB ; write pixel
\r
394 ADD DI, nextRow ; go to the next row
\r
408 /* moved to src/lib/modex16/16render.c */
\r
410 /* copy a region of video memory from one page to another.
\r
411 * It assumes that the left edge of the tile is the same on both
\r
412 * regions and the memory areas do not overlap.
\r
415 modexCopyPageRegion(page_t *dest, page_t *src,
\r
418 word width, word height)
\r
420 word doffset = (word)dest->data + dy*(dest->stridew) + dx/4;
\r
421 word soffset = (word)src->data + sy*(src->stridew) + sx/4;
\r
422 word scans = vga_state.vga_stride+8; //++++0000 the quick and dirty fix of the major issue with p16 video display wwww
\r
423 word nextSrcRow = src->stridew - scans - 1;
\r
424 word nextDestRow = dest->stridew - scans - 1;
\r
425 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
426 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
427 byte left = lclip[sx&0x03];
\r
428 byte right = rclip[(sx+width)&0x03];
\r
430 /* handle the case which requires an extra group */
\r
431 if((sx & 0x03) && !((sx+width) & 0x03)) {
\r
435 // 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
447 MOV AX, SCREEN_SEG ; work in the vga space
\r
452 MOV DX, GC_INDEX ; turn off cpu bits
\r
456 MOV AX, SC_INDEX ; point to the mask register
\r
466 MOV CX, scans ; the number of latches
\r
468 MOV AL, left ; do the left column
\r
473 MOV AL, 0fh ; do the inner columns
\r
475 REP MOVSB ; copy the pixels
\r
477 MOV AL, right ; do the right column
\r
482 MOV AX, SI ; go the start of the next row
\r
483 ADD AX, nextSrcRow ;
\r
486 ADD AX, nextDestRow ;
\r
489 DEC height ; do the rest of the actions
\r
492 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
493 MOV AL, 0ffh ; none from latches
\r
508 /* fade and flash */
\r
510 modexFadeOn(word fade, byte *palette) {
\r
511 fadePalette(-fade, 64, 64/fade+1, palette);
\r
516 modexFadeOff(word fade, byte *palette) {
\r
517 fadePalette(fade, 0, 64/fade+1, palette);
\r
522 modexFlashOn(word fade, byte *palette) {
\r
523 fadePalette(fade, -64, 64/fade+1, palette);
\r
528 modexFlashOff(word fade, byte *palette) {
\r
529 fadePalette(-fade, 0, 64/fade+1, palette);
\r
534 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
538 /* handle the case where we just update */
\r
540 modexPalUpdate1(palette);
\r
544 while(iter > 0) { /* FadeLoop */
\r
545 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
546 tmppal[i] = palette[i] - dim;
\r
547 if(tmppal[i] > 127) {
\r
549 } else if(tmppal[i] > 63) {
\r
553 modexPalUpdate1(tmppal);
\r
560 /* save and load */
\r
562 modexPalSave(byte *palette) {
\r
565 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
566 for(i=0; i<PAL_SIZE; i++) {
\r
567 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
575 ptr = malloc(PAL_SIZE);
\r
577 /* handle errors */
\r
579 printf("Could not allocate palette.\n");
\r
588 modexLoadPalFile(byte *filename, byte **palette) {
\r
592 /* free the palette if it exists */
\r
597 /* allocate the new palette */
\r
598 *palette = modexNewPal();
\r
600 /* open the file */
\r
601 file = fopen(filename, "rb");
\r
603 printf("Could not open palette file: %s\n", filename);
\r
607 /* read the file */
\r
609 while(!feof(file)) {
\r
610 *ptr++ = fgetc(file);
\r
618 modexSavePalFile(char *filename, byte *pal) {
\r
622 /* open the file for writing */
\r
623 file = fopen(filename, "wb");
\r
625 printf("Could not open %s for writing\n", filename);
\r
629 /* write the data to the file */
\r
630 fwrite(pal, 1, PAL_SIZE, file);
\r
638 fadePalette(-1, 64, 1, tmppal);
\r
644 fadePalette(-1, -64, 1, tmppal);
\r
650 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
652 byte *p = bmp->palette;
\r
656 static word a[PAL_SIZE]; //palette array of change values!
\r
657 word z=0, aq=0, aa=0, pp=0;
\r
659 //modexWaitBorder();
\r
660 vga_wait_for_vsync();
\r
663 memset(a, -1, sizeof(a));
\r
664 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
674 // printf("q: %02d\n", (q));
\r
675 // printf("qq: %02d\n", (qq));
\r
676 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
677 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
679 if((*i)<PAL_SIZE/2 && w==0)
\r
681 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
683 //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
684 //____ 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
685 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
690 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
692 //printf("qp=%d\n", qp);
\r
693 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
694 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
695 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
696 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
700 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
702 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
703 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
704 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
707 //if(qp>0) printf("qp=%d\n", qp);
\r
708 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
710 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
711 vga_wait_for_vsync();
\r
712 if((*i)>=PAL_SIZE/2 && w==0)
\r
714 for(; (*i)<PAL_SIZE; (*i)++)
\r
716 //____ 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
717 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
722 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
724 //printf("qp=%d\n", qp);
\r
725 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
726 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
727 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
728 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
732 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
733 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
734 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
737 //printf(" (*i)=%d\n", (*i)/3);
\r
740 printf("\nqqqqqqqq\n\n");
\r
746 long bufSize = (bmp->width * bmp->height);
\r
748 //printf("1(*i)=%02d\n", (*i)/3);
\r
749 //printf("1z=%02d\n", z/3);
\r
750 modexchkcolor(bmp, &q, &a, &aa, &z, i);
\r
751 //printf("2(*i)=%02d\n", (*i)/3);
\r
752 //printf("2z=%02d\n", z/3);
\r
757 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
758 if(a[aq]==-1) aq++;
\r
759 else { aqoffset++; break; }
\r
761 //update the image data here!
\r
762 for(lq=0; lq<bufSize; lq++)
\r
766 use a[qp] instead of bmp->offset for this spot!
\r
771 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
774 //(offset/bmp->offset)*bmp->offset
\r
777 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
778 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
779 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
780 /*if(bmp->data[lq]+bmp->offset==aq)
\r
782 //printf("%02d", bmp->data[lq]);
\r
783 //printf("\n%02d\n", bmp->offset);
\r
784 printf("aq=%02d ", aq);
\r
785 printf("a[aq]=%02d ", a[aq]);
\r
786 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
787 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
788 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
789 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
790 // printf("_%d ", bmp->data[lq]);
\r
791 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
793 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
795 if(bmp->data[lq]+bmp->offset >= aq)
\r
797 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
798 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
800 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
803 //printf("%02d`", bmp->data[lq]);
\r
804 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
807 //printf(" aq=%02d\n", aq);
\r
808 //printf(" aa=%02d\n", aa);
\r
810 //update the palette~
\r
811 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
814 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
819 modexPalUpdate1(byte *p)
\r
822 //modexWaitBorder();
\r
823 vga_wait_for_vsync();
\r
824 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
825 for(i=0; i<PAL_SIZE/2; i++)
\r
827 outp(PAL_DATA_REG, p[i]);
\r
829 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
830 vga_wait_for_vsync();
\r
831 for(; i<PAL_SIZE; i++)
\r
833 outp(PAL_DATA_REG, p[(i)]);
\r
838 modexPalUpdate0(byte *p)
\r
841 //modexWaitBorder();
\r
842 vga_wait_for_vsync();
\r
843 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
844 for(i=0; i<PAL_SIZE/2; i++)
\r
846 outp(PAL_DATA_REG, rand());
\r
848 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
849 vga_wait_for_vsync();
\r
850 for(; i<PAL_SIZE; i++)
\r
852 outp(PAL_DATA_REG, rand());
\r
857 modexPalOverscan(word col)
\r
859 //modexWaitBorder();
\r
860 vga_wait_for_vsync();
\r
861 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
862 outp(PAL_DATA_REG, col);
\r
866 //i want to make another vesion that checks the palette when the palette is being appened~
\r
867 void modexchkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
871 pal = modexNewPal();
\r
873 //printf("q: %02d\n", (*q));
\r
874 printf("chkcolor start~\n");
\r
875 printf("1 (*z): %d\n", (*z)/3);
\r
876 printf("1 (*i): %d\n", (*i)/3);
\r
877 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
878 printf("wwwwwwwwwwwwwwww\n");
\r
879 //check palette for dups
\r
880 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
882 //printf("\n z: %d\n", (*z));
\r
883 //printf(" q: %d\n", (*q));
\r
884 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
887 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
890 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
891 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
895 else for(zz=0; zz<(*q); zz+=3)
\r
897 //printf("zz: %02d\n", zz/3);
\r
900 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
904 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
905 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
908 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
910 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
911 // 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
912 // 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
913 // //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
914 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
919 planned features that i plan to implement~
\r
920 image that has values on the pallete list!
\r
922 no... wait.... no wwww
\r
924 //for(zzii=0; zzii<3; zzii++)
\r
926 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
927 a[(((*z)+(*q)))]=zz;
\r
929 (*aa)=(((*z)+(*q)));
\r
930 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
931 // printf("\n aa: %d\n\n", (*aa));
\r
932 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
933 // printf("wwwwwwwwwwwwwwww\n\n");
\r
937 printf("================\n");
\r
938 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
939 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
940 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
941 printf("================\n");
\r
943 //printf("[%d]", (zz+q));
\r
947 printf("wwwwwwwwwwwwwwww\n");
\r
948 printf("2 (*z): %d\n", (*z)/3);
\r
949 printf("2 (*i): %d\n", (*i)/3);
\r
950 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
951 printf("chkcolor end~\n");
\r
955 void modexputPixel(page_t *page, int x, int y, byte color)
\r
957 word pageOff = (word) page->data;
\r
958 /* Each address accesses four neighboring pixels, so set
\r
959 Write Plane Enable according to which pixel we want
\r
960 to modify. The plane is determined by the two least
\r
961 significant bits of the x-coordinate: */
\r
962 modexSelectPlane(PLANE(x));
\r
963 //outp(SC_INDEX, 0x02);
\r
964 //outp(SC_DATA, 0x01 << (x & 3));
\r
966 /* The offset of the pixel into the video segment is
\r
967 offset = (width * y + x) / 4, and write the given
\r
968 color to the plane we selected above. Heed the active
\r
969 page start selection. */
\r
970 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
974 byte modexgetPixel(page_t *page, int x, int y)
\r
976 word pageOff = (word) page->data;
\r
977 /* Select the plane from which we must read the pixel color: */
\r
978 outpw(GC_INDEX, 0x04);
\r
979 outpw(GC_INDEX+1, x & 3);
\r
981 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
985 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
989 word addr = (word) romFontsData.l;
\r
990 word addrq = (page->width/4) * y + (x / 4) + ((word)page->data);
\r
991 word addrr = addrq;
\r
996 w=romFonts[t].charSize;
\r
997 romFontsData.chw=0;
\r
999 for(; *str != '\0'; str++)
\r
1005 romFontsData.chw = 0;
\r
1006 addrq += (page->width / 4) * 8;
\r
1012 // load the character into romFontsData.l
\r
1013 // no need for inline assembly!
\r
1014 // NTS: It might even be faster to just let the modexDrawChar point directly at ROM font than to copy per char! --J.C.
\r
1015 _fmemcpy(romFontsData.l,MK_FP(s,o+(w*c))/*ROM font location*/,w/*char size*/);
\r
1016 modexDrawChar(page, x_draw/*for mode X planar use*/, t, col, bgcol, addrr);
\r
1017 x_draw += 8; /* track X for edge of screen */
\r
1018 addrr += 2; /* move 8 pixels over (2 x 4 planar pixels per byte) */
\r
1022 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1024 word i, s, o, w, j, xp;
\r
1026 word addr = (word) l;
\r
1050 s=romFonts[t].seg;
\r
1051 o=romFonts[t].off;
\r
1053 for(; *str != '\0'; str++)
\r
1056 if((c=='\n'/* || c=="\
\r
1057 "*/)/* || chw>=page->width*/)
\r
1063 //load the letter 'A'
\r
1078 MOV AL, c ; the letter
\r
1081 ADD SI, AX ;the address of charcter
\r
1099 for(i=0; i<w; i++)
\r
1105 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1106 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1115 /* palette dump on display! */
\r
1116 void modexpdump(page_t *pee)
\r
1118 int mult=(QUADWH);
\r
1119 int palq=(mult)*TILEWH;
\r
1122 for(paly=0; paly<palq; paly+=mult){
\r
1123 for(palx=0; palx<palq; palx+=mult){
\r
1124 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
\r
1130 /////////////////////////////////////////////////////////////////////////////
\r
1132 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1133 // the Virtual screen. //
\r
1135 /////////////////////////////////////////////////////////////////////////////
\r
1136 void modexcls(page_t *page, byte color, byte *Where)
\r
1138 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1139 /* set map mask to all 4 planes */
\r
1140 outpw(SC_INDEX, 0xff02);
\r
1141 //_fmemset(VGA, color, 16000);
\r
1142 _fmemset(Where, color, page->width*(page->height)/4);
\r
1146 modexWaitBorder() {
\r
1147 while(inp(INPUT_STATUS_1) & 8) {
\r
1151 while(!(inp(INPUT_STATUS_1) & 8)) {
\r
1156 void modexprintmeminfo(video_t *v)
\r
1159 printf("video memory remaining: %u\n", v->vmem_remain);
\r
1161 for(i=0; i<v->num_of_pages;i++)
\r
1163 printf(" [%u]=", i);
\r
1164 printf("(%Fp)", (v->page[i].data));
\r
1165 printf(" size=%u ", v->page[i].pagesize);
\r
1166 printf("w=%lu h=%lu ", (unsigned long)v->page[i].width, (unsigned long)v->page[i].height);
\r
1167 printf("sw=%lu sh=%lu ", (unsigned long)v->page[i].sw, (unsigned long)v->page[i].sh);
\r
1168 printf("pi=%u", v->page[i].pi);
\r