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 (video->page[2]) = modexNextPageFlexibleSize(&(video->page[1]), TILEWH*4, TILEWH*4); video->num_of_pages++;
\r
275 (video->page[3]) = modexNextPageFlexibleSize(&(video->page[2]), video->page[0].sw, 208); video->num_of_pages++;
\r
276 // (video->page[2]) = modexNextPageFlexibleSize(&(video->page[1]), video->page[0].width, 172); video->num_of_pages++;
\r
277 // (video->page[3]) = modexNextPageFlexibleSize(&(video->page[2]), 72, 128); video->num_of_pages++;
\r
278 modexCalcVmemRemain(video);
\r
284 modexShowPage(page_t *page) {
\r
290 /* calculate offset */
\r
291 offset = (word) page->data;
\r
292 offset += page->dy * (page->width >> 2 );
\r
293 offset += page->dx >> 2;
\r
295 /* calculate crtcOffset according to virtual width */
\r
296 crtcOffset = page->width >> 3;
\r
298 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
299 low_address = LOW_ADDRESS | (offset << 8);
\r
301 /* wait for appropriate timing and then program CRTC */
\r
302 while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
303 outpw(CRTC_INDEX, high_address);
\r
304 outpw(CRTC_INDEX, low_address);
\r
305 outp(CRTC_INDEX, 0x13);
\r
306 outp(CRTC_DATA, crtcOffset);
\r
308 /* wait for one retrace */
\r
309 while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
311 /* do PEL panning here */
\r
312 outp(AC_INDEX, 0x33);
\r
313 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
317 modexPanPage(page_t *page, int dx, int dy) {
\r
323 modexSelectPlane(byte plane) {
\r
324 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
325 outp(SC_DATA, plane);
\r
329 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
330 word pageOff = (word) page->data;
\r
331 word xoff=x/4; /* xoffset that begins each row */
\r
332 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
333 word poffset = pageOff + y*(page->stridew) + xoff; /* starting offset */
\r
334 word nextRow = page->stridew-scanCount-1; /* loc of next row */
\r
335 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
336 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
337 byte left = lclip[x&0x03];
\r
338 byte right = rclip[(x+w)&0x03];
\r
340 /* handle the case which requires an extra group */
\r
341 if((x & 0x03) && !((x+w) & 0x03)) {
\r
345 //printf("modexClearRegion(x=%u, y=%u, w=%u, h=%u, left=%u, right=%u)\n", x, y, w, h, left, right);
\r
356 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
358 MOV DI, poffset ; go to the first pixel
\r
359 MOV DX, SC_INDEX ; point to the map mask
\r
363 MOV AL, color ; get ready to write colors
\r
365 MOV CX, scanCount ; count the line
\r
366 MOV BL, AL ; remember color
\r
367 MOV AL, left ; do the left clip
\r
368 OUT DX, AL ; set the left clip
\r
369 MOV AL, BL ; restore color
\r
370 STOSB ; write the color
\r
372 JZ SCAN_DONE ; handle 1 group stuff
\r
374 ;-- write the main body of the scanline
\r
375 MOV BL, AL ; remember color
\r
376 MOV AL, 0x0f ; write to all pixels
\r
378 MOV AL, BL ; restore color
\r
379 REP STOSB ; write the color
\r
381 MOV BL, AL ; remeber color
\r
383 OUT DX, AL ; do the right clip
\r
384 MOV AL, BL ; restore color
\r
385 STOSB ; write pixel
\r
386 ADD DI, nextRow ; go to the next row
\r
400 /* moved to src/lib/modex16/16render.c */
\r
402 /* copy a region of video memory from one page to another.
\r
403 * It assumes that the left edge of the tile is the same on both
\r
404 * regions and the memory areas do not overlap.
\r
407 modexCopyPageRegion(page_t *dest, page_t *src,
\r
410 word width, word height)
\r
412 word doffset = (word)dest->data + dy*(dest->stridew) + dx/4;
\r
413 word soffset = (word)src->data + sy*(src->stridew) + sx/4;
\r
414 word scans = vga_state.vga_stride+8; //++++0000 the quick and dirty fix of the major issue with p16 video display wwww
\r
415 word nextSrcRow = src->stridew - scans - 1;
\r
416 word nextDestRow = dest->stridew - scans - 1;
\r
417 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
418 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
419 byte left = lclip[sx&0x03];
\r
420 byte right = rclip[(sx+width)&0x03];
\r
422 /* handle the case which requires an extra group */
\r
423 if((sx & 0x03) && !((sx+width) & 0x03)) {
\r
427 // 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
439 MOV AX, SCREEN_SEG ; work in the vga space
\r
444 MOV DX, GC_INDEX ; turn off cpu bits
\r
448 MOV AX, SC_INDEX ; point to the mask register
\r
458 MOV CX, scans ; the number of latches
\r
460 MOV AL, left ; do the left column
\r
465 MOV AL, 0fh ; do the inner columns
\r
467 REP MOVSB ; copy the pixels
\r
469 MOV AL, right ; do the right column
\r
474 MOV AX, SI ; go the start of the next row
\r
475 ADD AX, nextSrcRow ;
\r
478 ADD AX, nextDestRow ;
\r
481 DEC height ; do the rest of the actions
\r
484 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
485 MOV AL, 0ffh ; none from latches
\r
500 /* fade and flash */
\r
502 modexFadeOn(word fade, byte *palette) {
\r
503 fadePalette(-fade, 64, 64/fade+1, palette);
\r
508 modexFadeOff(word fade, byte *palette) {
\r
509 fadePalette(fade, 0, 64/fade+1, palette);
\r
514 modexFlashOn(word fade, byte *palette) {
\r
515 fadePalette(fade, -64, 64/fade+1, palette);
\r
520 modexFlashOff(word fade, byte *palette) {
\r
521 fadePalette(-fade, 0, 64/fade+1, palette);
\r
526 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
530 /* handle the case where we just update */
\r
532 modexPalUpdate1(palette);
\r
536 while(iter > 0) { /* FadeLoop */
\r
537 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
538 tmppal[i] = palette[i] - dim;
\r
539 if(tmppal[i] > 127) {
\r
541 } else if(tmppal[i] > 63) {
\r
545 modexPalUpdate1(tmppal);
\r
552 /* save and load */
\r
554 modexPalSave(byte *palette) {
\r
557 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
558 for(i=0; i<PAL_SIZE; i++) {
\r
559 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
567 ptr = malloc(PAL_SIZE);
\r
569 /* handle errors */
\r
571 printf("Could not allocate palette.\n");
\r
580 modexLoadPalFile(byte *filename, byte **palette) {
\r
584 /* free the palette if it exists */
\r
589 /* allocate the new palette */
\r
590 *palette = modexNewPal();
\r
592 /* open the file */
\r
593 file = fopen(filename, "rb");
\r
595 printf("Could not open palette file: %s\n", filename);
\r
599 /* read the file */
\r
601 while(!feof(file)) {
\r
602 *ptr++ = fgetc(file);
\r
610 modexSavePalFile(char *filename, byte *pal) {
\r
614 /* open the file for writing */
\r
615 file = fopen(filename, "wb");
\r
617 printf("Could not open %s for writing\n", filename);
\r
621 /* write the data to the file */
\r
622 fwrite(pal, 1, PAL_SIZE, file);
\r
630 fadePalette(-1, 64, 1, tmppal);
\r
636 fadePalette(-1, -64, 1, tmppal);
\r
642 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
644 byte *p = bmp->palette;
\r
648 static word a[PAL_SIZE]; //palette array of change values!
\r
649 word z=0, aq=0, aa=0, pp=0;
\r
651 //modexWaitBorder();
\r
652 vga_wait_for_vsync();
\r
655 memset(a, -1, sizeof(a));
\r
656 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
666 // printf("q: %02d\n", (q));
\r
667 // printf("qq: %02d\n", (qq));
\r
668 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
669 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
671 if((*i)<PAL_SIZE/2 && w==0)
\r
673 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
675 //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
676 //____ 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
677 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
682 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
684 //printf("qp=%d\n", qp);
\r
685 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
686 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
687 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
688 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
692 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
694 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
695 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
696 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
699 //if(qp>0) printf("qp=%d\n", qp);
\r
700 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
702 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
703 vga_wait_for_vsync();
\r
704 if((*i)>=PAL_SIZE/2 && w==0)
\r
706 for(; (*i)<PAL_SIZE; (*i)++)
\r
708 //____ 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
709 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
714 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
716 //printf("qp=%d\n", qp);
\r
717 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
718 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
719 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
720 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
724 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
725 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
726 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
729 //printf(" (*i)=%d\n", (*i)/3);
\r
732 printf("\nqqqqqqqq\n\n");
\r
738 long bufSize = (bmp->width * bmp->height);
\r
740 //printf("1(*i)=%02d\n", (*i)/3);
\r
741 //printf("1z=%02d\n", z/3);
\r
742 modexchkcolor(bmp, &q, &a, &aa, &z, i);
\r
743 //printf("2(*i)=%02d\n", (*i)/3);
\r
744 //printf("2z=%02d\n", z/3);
\r
749 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
750 if(a[aq]==-1) aq++;
\r
751 else { aqoffset++; break; }
\r
753 //update the image data here!
\r
754 for(lq=0; lq<bufSize; lq++)
\r
758 use a[qp] instead of bmp->offset for this spot!
\r
763 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
766 //(offset/bmp->offset)*bmp->offset
\r
769 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
770 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
771 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
772 /*if(bmp->data[lq]+bmp->offset==aq)
\r
774 //printf("%02d", bmp->data[lq]);
\r
775 //printf("\n%02d\n", bmp->offset);
\r
776 printf("aq=%02d ", aq);
\r
777 printf("a[aq]=%02d ", a[aq]);
\r
778 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
779 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
780 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
781 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
782 // printf("_%d ", bmp->data[lq]);
\r
783 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
785 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
787 if(bmp->data[lq]+bmp->offset >= aq)
\r
789 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
790 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
792 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
795 //printf("%02d`", bmp->data[lq]);
\r
796 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
799 //printf(" aq=%02d\n", aq);
\r
800 //printf(" aa=%02d\n", aa);
\r
802 //update the palette~
\r
803 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
806 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
811 modexPalUpdate1(byte *p)
\r
814 //modexWaitBorder();
\r
815 vga_wait_for_vsync();
\r
816 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
817 for(i=0; i<PAL_SIZE/2; i++)
\r
819 outp(PAL_DATA_REG, p[i]);
\r
821 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
822 vga_wait_for_vsync();
\r
823 for(; i<PAL_SIZE; i++)
\r
825 outp(PAL_DATA_REG, p[(i)]);
\r
830 modexPalUpdate0(byte *p)
\r
833 //modexWaitBorder();
\r
834 vga_wait_for_vsync();
\r
835 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
836 for(i=0; i<PAL_SIZE/2; i++)
\r
838 outp(PAL_DATA_REG, rand());
\r
840 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
841 vga_wait_for_vsync();
\r
842 for(; i<PAL_SIZE; i++)
\r
844 outp(PAL_DATA_REG, rand());
\r
849 modexPalOverscan(word col)
\r
851 //modexWaitBorder();
\r
852 vga_wait_for_vsync();
\r
853 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
854 outp(PAL_DATA_REG, col);
\r
858 //i want to make another vesion that checks the palette when the palette is being appened~
\r
859 void modexchkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
863 pal = modexNewPal();
\r
865 //printf("q: %02d\n", (*q));
\r
866 printf("chkcolor start~\n");
\r
867 printf("1 (*z): %d\n", (*z)/3);
\r
868 printf("1 (*i): %d\n", (*i)/3);
\r
869 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
870 printf("wwwwwwwwwwwwwwww\n");
\r
871 //check palette for dups
\r
872 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
874 //printf("\n z: %d\n", (*z));
\r
875 //printf(" q: %d\n", (*q));
\r
876 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
879 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
882 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
883 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
887 else for(zz=0; zz<(*q); zz+=3)
\r
889 //printf("zz: %02d\n", zz/3);
\r
892 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
896 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
897 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
900 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
902 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
903 // 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
904 // 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
905 // //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
906 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
911 planned features that i plan to implement~
\r
912 image that has values on the pallete list!
\r
914 no... wait.... no wwww
\r
916 //for(zzii=0; zzii<3; zzii++)
\r
918 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
919 a[(((*z)+(*q)))]=zz;
\r
921 (*aa)=(((*z)+(*q)));
\r
922 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
923 // printf("\n aa: %d\n\n", (*aa));
\r
924 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
925 // printf("wwwwwwwwwwwwwwww\n\n");
\r
929 printf("================\n");
\r
930 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
931 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
932 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
933 printf("================\n");
\r
935 //printf("[%d]", (zz+q));
\r
939 printf("wwwwwwwwwwwwwwww\n");
\r
940 printf("2 (*z): %d\n", (*z)/3);
\r
941 printf("2 (*i): %d\n", (*i)/3);
\r
942 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
943 printf("chkcolor end~\n");
\r
947 void modexputPixel(page_t *page, int x, int y, byte color)
\r
949 word pageOff = (word) page->data;
\r
950 /* Each address accesses four neighboring pixels, so set
\r
951 Write Plane Enable according to which pixel we want
\r
952 to modify. The plane is determined by the two least
\r
953 significant bits of the x-coordinate: */
\r
954 modexSelectPlane(PLANE(x));
\r
955 //outp(SC_INDEX, 0x02);
\r
956 //outp(SC_DATA, 0x01 << (x & 3));
\r
958 /* The offset of the pixel into the video segment is
\r
959 offset = (width * y + x) / 4, and write the given
\r
960 color to the plane we selected above. Heed the active
\r
961 page start selection. */
\r
962 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
966 byte modexgetPixel(page_t *page, int x, int y)
\r
968 word pageOff = (word) page->data;
\r
969 /* Select the plane from which we must read the pixel color: */
\r
970 outpw(GC_INDEX, 0x04);
\r
971 outpw(GC_INDEX+1, x & 3);
\r
973 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
977 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
981 word addr = (word) romFontsData.l;
\r
982 word addrq = (page->width/4) * y + (x / 4) + ((word)page->data);
\r
983 word addrr = addrq;
\r
988 w=romFonts[t].charSize;
\r
989 romFontsData.chw=0;
\r
991 for(; *str != '\0'; str++)
\r
997 romFontsData.chw = 0;
\r
998 addrq += (page->width / 4) * 8;
\r
1004 // load the character into romFontsData.l
\r
1005 // no need for inline assembly!
\r
1006 // NTS: It might even be faster to just let the modexDrawChar point directly at ROM font than to copy per char! --J.C.
\r
1007 _fmemcpy(romFontsData.l,MK_FP(s,o+(w*c))/*ROM font location*/,w/*char size*/);
\r
1008 modexDrawChar(page, x_draw/*for mode X planar use*/, t, col, bgcol, addrr);
\r
1009 x_draw += 8; /* track X for edge of screen */
\r
1010 addrr += 2; /* move 8 pixels over (2 x 4 planar pixels per byte) */
\r
1014 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1016 word i, s, o, w, j, xp;
\r
1018 word addr = (word) l;
\r
1042 s=romFonts[t].seg;
\r
1043 o=romFonts[t].off;
\r
1045 for(; *str != '\0'; str++)
\r
1048 if((c=='\n'/* || c=="\
\r
1049 "*/)/* || chw>=page->width*/)
\r
1055 //load the letter 'A'
\r
1070 MOV AL, c ; the letter
\r
1073 ADD SI, AX ;the address of charcter
\r
1091 for(i=0; i<w; i++)
\r
1097 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1098 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1107 /* palette dump on display! */
\r
1108 void modexpdump(page_t *pee)
\r
1110 int mult=(QUADWH);
\r
1111 int palq=(mult)*TILEWH;
\r
1114 for(paly=0; paly<palq; paly+=mult){
\r
1115 for(palx=0; palx<palq; palx+=mult){
\r
1116 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
\r
1122 /////////////////////////////////////////////////////////////////////////////
\r
1124 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1125 // the Virtual screen. //
\r
1127 /////////////////////////////////////////////////////////////////////////////
\r
1128 void modexcls(page_t *page, byte color, byte *Where)
\r
1130 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1131 /* set map mask to all 4 planes */
\r
1132 outpw(SC_INDEX, 0xff02);
\r
1133 //_fmemset(VGA, color, 16000);
\r
1134 _fmemset(Where, color, page->width*(page->height)/4);
\r
1138 modexWaitBorder() {
\r
1139 while(inp(INPUT_STATUS_1) & 8) {
\r
1143 while(!(inp(INPUT_STATUS_1) & 8)) {
\r
1153 m = int10_getmode();
\r
1154 if ((rp=vga_state.vga_graphics_ram) != NULL && !(m <= 3 || m == 7)) {
\r
1155 unsigned int i,im;
\r
1157 im = (FP_SEG(vga_state.vga_graphics_ram_fence) - FP_SEG(vga_state.vga_graphics_ram));
\r
1158 if (im > 0xFFE) im = 0xFFE;
\r
1160 for (i=0;i < im;i++) vga_state.vga_graphics_ram[i] = 0;
\r
1162 else if ((ap=vga_state.vga_alpha_ram) != NULL) {
\r
1163 unsigned int i,im;
\r
1165 im = (FP_SEG(vga_state.vga_alpha_ram_fence) - FP_SEG(vga_state.vga_alpha_ram));
\r
1166 if (im > 0x7FE) im = 0x7FE;
\r
1167 im <<= 4 - 1; /* because ptr is type uint16_t */
\r
1168 for (i=0;i < im;i++) vga_state.vga_alpha_ram[i] = 0x0720;
\r
1171 printf("WARNING: bios cls no ptr\n");
\r
1175 void modexprintmeminfo(video_t *v)
\r
1178 printf("video memory remaining: %u\n", v->vmem_remain);
\r
1180 for(i=0; i<v->num_of_pages;i++)
\r
1182 printf(" [%u]=", i);
\r
1183 printf("(%Fp)", (v->page[i].data));
\r
1184 printf(" size=%u ", v->page[i].pagesize);
\r
1185 printf("sw=%lu sh=%lu ", (unsigned long)v->page[i].sw, (unsigned long)v->page[i].sh);
\r
1186 printf(" width=%lu height=%lu", (unsigned long)v->page[i].width, (unsigned long)v->page[i].height);
\r