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.stridew)*page.height;
\r
202 page.pi=page.width*4;
\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
228 result.pi=result.width*4;
\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=p->sw/4;//result.width/4;
\r
253 result.pagesize = (word)(result.stridew)*result.height;
\r
257 result.pi=p->width*4;
\r
267 void modexCalcVmemRemain(video_t *video)
\r
270 //printf("\n\n 1st vmem_remain=%u\n", video->vmem_remain);
\r
271 for(i=0; i<video->num_of_pages; i++)
\r
273 video->vmem_remain-=video->page[i].pagesize;
\r
274 //printf(" [%u], video->page[%u].pagesize=%u\n", i, i, video->page[i].pagesize);
\r
275 //printf(" [%u], vmem_remain=%u\n", i, video->vmem_remain);
\r
279 void modexHiganbanaPageSetup(video_t *video)
\r
281 video->vmem_remain=65535U;
\r
282 video->num_of_pages=0;
\r
283 (video->page[0]) = modexDefaultPage(&(video->page[0])); video->num_of_pages++; //video->page[0].width += (TILEWHD); video->page[0].height += (TILEWHD);
\r
284 (video->page[1]) = modexNextPage(&(video->page[0])); video->num_of_pages++;
\r
285 //0000 (video->page[2]) = modexNextPageFlexibleSize(&(video->page[1]), (video->page[0]).width, TILEWH*4); video->num_of_pages++;
\r
286 //0000 (video->page[3]) = (video->page[2]); video->num_of_pages++;
\r
287 (video->page[2]) = modexNextPageFlexibleSize(&(video->page[1]), TILEWH*4, TILEWH*4); video->num_of_pages++;
\r
288 // (video->page[3]) = modexNextPageFlexibleSize(&(video->page[2]), video->page[0].width, 176); video->num_of_pages++;
\r
289 (video->page[3]) = modexNextPageFlexibleSize(&(video->page[2]), video->page[0].sw, 208); video->num_of_pages++;
\r
290 // (video->page[2]) = modexNextPageFlexibleSize(&(video->page[1]), video->page[0].width, 172); video->num_of_pages++;
\r
291 // (video->page[3]) = modexNextPageFlexibleSize(&(video->page[2]), 72, 128); video->num_of_pages++;
\r
292 modexCalcVmemRemain(video);
\r
298 modexShowPage(page_t *page) {
\r
304 /* calculate offset */
\r
305 offset = (word) page->data;
\r
306 offset += page->dy * (page->width >> 2 );
\r
307 offset += page->dx >> 2;
\r
309 /* calculate crtcOffset according to virtual width */
\r
310 crtcOffset = page->width >> 3;
\r
312 high_address = HIGH_ADDRESS | (offset & 0xff00);
\r
313 low_address = LOW_ADDRESS | (offset << 8);
\r
315 /* wait for appropriate timing and then program CRTC */
\r
316 //while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));
\r
317 outpw(CRTC_INDEX, high_address);
\r
318 outpw(CRTC_INDEX, low_address);
\r
319 outp(CRTC_INDEX, 0x13);
\r
320 outp(CRTC_DATA, crtcOffset);
\r
322 /* wait for one retrace */
\r
323 //while (!(inp(INPUT_STATUS_1) & VRETRACE));
\r
325 /* do PEL panning here */
\r
326 outp(AC_INDEX, 0x33);
\r
327 outp(AC_INDEX, (page->dx & 0x03) << 1);
\r
331 modexPanPage(page_t *page, int dx, int dy) {
\r
337 modexSelectPlane(byte plane) {
\r
338 outp(SC_INDEX, MAP_MASK); /* select plane */
\r
339 outp(SC_DATA, plane);
\r
343 modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {
\r
344 word pageOff = (word) page->data;
\r
345 word xoff=x/4; /* xoffset that begins each row */
\r
346 word scanCount=w/4; /* number of iterations per row (excluding right clip)*/
\r
347 word poffset = pageOff + y*(page->stridew) + xoff; /* starting offset */
\r
348 word nextRow = page->stridew-scanCount-1; /* loc of next row */
\r
349 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
350 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
351 byte left = lclip[x&0x03];
\r
352 byte right = rclip[(x+w)&0x03];
\r
354 /* handle the case which requires an extra group */
\r
355 if((x & 0x03) && !((x+w) & 0x03)) {
\r
359 //printf("modexClearRegion(x=%u, y=%u, w=%u, h=%u, left=%u, right=%u)\n", x, y, w, h, left, right);
\r
370 MOV AX, SCREEN_SEG ; go to the VGA memory
\r
372 MOV DI, poffset ; go to the first pixel
\r
373 MOV DX, SC_INDEX ; point to the map mask
\r
377 MOV AL, color ; get ready to write colors
\r
379 MOV CX, scanCount ; count the line
\r
380 MOV BL, AL ; remember color
\r
381 MOV AL, left ; do the left clip
\r
382 OUT DX, AL ; set the left clip
\r
383 MOV AL, BL ; restore color
\r
384 STOSB ; write the color
\r
386 JZ SCAN_DONE ; handle 1 group stuff
\r
388 ;-- write the main body of the scanline
\r
389 MOV BL, AL ; remember color
\r
390 MOV AL, 0x0f ; write to all pixels
\r
392 MOV AL, BL ; restore color
\r
393 REP STOSB ; write the color
\r
395 MOV BL, AL ; remeber color
\r
397 OUT DX, AL ; do the right clip
\r
398 MOV AL, BL ; restore color
\r
399 STOSB ; write pixel
\r
400 ADD DI, nextRow ; go to the next row
\r
414 /* moved to src/lib/modex16/16render.c */
\r
416 /* copy a region of video memory from one page to another.
\r
417 * It assumes that the left edge of the tile is the same on both
\r
418 * regions and the memory areas do not overlap.
\r
421 modexCopyPageRegion(page_t *dest, page_t *src,
\r
424 word width, word height)
\r
426 word doffset = (word)dest->data + dy*(dest->stridew) + dx/4;
\r
427 word soffset = (word)src->data + sy*(src->stridew) + sx/4;
\r
428 word scans = vga_state.vga_stride; //++++0000 the quick and dirty fix of the major issue with p16 video display wwww
\r
429 word nextSrcRow = src->stridew - scans - 1;
\r
430 word nextDestRow = dest->stridew - scans - 1;
\r
431 byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */
\r
432 byte rclip[] = {0x00, 0x01, 0x03, 0x07};
\r
433 byte left = lclip[sx&0x03];
\r
434 byte right = rclip[(sx+width)&0x03];
\r
436 /* handle the case which requires an extra group */
\r
437 if((sx & 0x03) && !((sx+width) & 0x03)) {
\r
441 // 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
453 MOV AX, SCREEN_SEG ; work in the vga space
\r
458 MOV DX, GC_INDEX ; turn off cpu bits
\r
462 MOV AX, SC_INDEX ; point to the mask register
\r
472 MOV CX, scans ; the number of latches
\r
474 MOV AL, left ; do the left column
\r
479 MOV AL, 0fh ; do the inner columns
\r
481 REP MOVSB ; copy the pixels
\r
483 MOV AL, right ; do the right column
\r
488 MOV AX, SI ; go the start of the next row
\r
489 ADD AX, nextSrcRow ;
\r
492 ADD AX, nextDestRow ;
\r
495 DEC height ; do the rest of the actions
\r
498 MOV DX, GC_INDEX+1 ; go back to CPU data
\r
499 MOV AL, 0ffh ; none from latches
\r
514 /* fade and flash */
\r
516 modexFadeOn(word fade, byte *palette) {
\r
517 fadePalette(-fade, 64, 64/fade+1, palette);
\r
522 modexFadeOff(word fade, byte *palette) {
\r
523 fadePalette(fade, 0, 64/fade+1, palette);
\r
528 modexFlashOn(word fade, byte *palette) {
\r
529 fadePalette(fade, -64, 64/fade+1, palette);
\r
534 modexFlashOff(word fade, byte *palette) {
\r
535 fadePalette(-fade, 0, 64/fade+1, palette);
\r
540 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {
\r
544 /* handle the case where we just update */
\r
546 modexPalUpdate1(palette);
\r
550 while(iter > 0) { /* FadeLoop */
\r
551 for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */
\r
552 tmppal[i] = palette[i] - dim;
\r
553 if(tmppal[i] > 127) {
\r
555 } else if(tmppal[i] > 63) {
\r
559 modexPalUpdate1(tmppal);
\r
566 /* save and load */
\r
568 modexPalSave(byte *palette) {
\r
571 outp(PAL_READ_REG, 0); /* start at palette entry 0 */
\r
572 for(i=0; i<PAL_SIZE; i++) {
\r
573 palette[i] = inp(PAL_DATA_REG); /* read the palette data */
\r
581 ptr = malloc(PAL_SIZE);
\r
583 /* handle errors */
\r
585 printf("Could not allocate palette.\n");
\r
594 modexLoadPalFile(byte *filename, byte **palette) {
\r
598 /* free the palette if it exists */
\r
603 /* allocate the new palette */
\r
604 *palette = modexNewPal();
\r
606 /* open the file */
\r
607 file = fopen(filename, "rb");
\r
609 printf("Could not open palette file: %s\n", filename);
\r
613 /* read the file */
\r
615 while(!feof(file)) {
\r
616 *ptr++ = fgetc(file);
\r
624 modexSavePalFile(char *filename, byte *pal) {
\r
628 /* open the file for writing */
\r
629 file = fopen(filename, "wb");
\r
631 printf("Could not open %s for writing\n", filename);
\r
635 /* write the data to the file */
\r
636 fwrite(pal, 1, PAL_SIZE, file);
\r
644 fadePalette(-1, 64, 1, tmppal);
\r
650 fadePalette(-1, -64, 1, tmppal);
\r
656 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
\r
658 byte *p = bmp->palette;
\r
662 static word a[PAL_SIZE]; //palette array of change values!
\r
663 word z=0, aq=0, aa=0, pp=0;
\r
665 //modexWaitBorder();
\r
666 vga_wait_for_vsync();
\r
669 memset(a, -1, sizeof(a));
\r
670 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
680 // printf("q: %02d\n", (q));
\r
681 // printf("qq: %02d\n", (qq));
\r
682 //printf(" (*i)-q=%02d\n", (*i)-q);
\r
683 outp(PAL_WRITE_REG, qq); /* start at the beginning of palette */
\r
685 if((*i)<PAL_SIZE/2 && w==0)
\r
687 for(; (*i)<PAL_SIZE/2; (*i)++)
\r
689 //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
690 //____ 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
691 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
696 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
698 //printf("qp=%d\n", qp);
\r
699 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
700 printf(" %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);
\r
701 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
702 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
706 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);
\r
708 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
709 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
710 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
713 //if(qp>0) printf("qp=%d\n", qp);
\r
714 //if(qp>0) printf(" (*i)=%d\n", (*i)/3);
\r
716 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
717 vga_wait_for_vsync();
\r
718 if((*i)>=PAL_SIZE/2 && w==0)
\r
720 for(; (*i)<PAL_SIZE; (*i)++)
\r
722 //____ 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
723 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
728 else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))
\r
730 //printf("qp=%d\n", qp);
\r
731 //printf(" (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);
\r
732 printf(" %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));
\r
733 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!
\r
734 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }
\r
738 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);
\r
739 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);
\r
740 printf("p[]=%d qp=%d p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }
\r
743 //printf(" (*i)=%d\n", (*i)/3);
\r
746 printf("\nqqqqqqqq\n\n");
\r
752 long bufSize = (bmp->width * bmp->height);
\r
754 //printf("1(*i)=%02d\n", (*i)/3);
\r
755 //printf("1z=%02d\n", z/3);
\r
756 modexchkcolor(bmp, &q, &a, &aa, &z, i);
\r
757 //printf("2(*i)=%02d\n", (*i)/3);
\r
758 //printf("2z=%02d\n", z/3);
\r
763 // printf("a[%02d]=(%d)\n", aq, a[aq]);
\r
764 if(a[aq]==-1) aq++;
\r
765 else { aqoffset++; break; }
\r
767 //update the image data here!
\r
768 for(lq=0; lq<bufSize; lq++)
\r
772 use a[qp] instead of bmp->offset for this spot!
\r
777 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww
\r
780 //(offset/bmp->offset)*bmp->offset
\r
783 //printf("%02d ",bmp->data[lq]+bmp->offset);
\r
784 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
785 //printf("%02d_", bmp->data[lq]+bmp->offset);
\r
786 /*if(bmp->data[lq]+bmp->offset==aq)
\r
788 //printf("%02d", bmp->data[lq]);
\r
789 //printf("\n%02d\n", bmp->offset);
\r
790 printf("aq=%02d ", aq);
\r
791 printf("a[aq]=%02d ", a[aq]);
\r
792 printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);
\r
793 printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);
\r
794 //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);
\r
795 //++++ bmp->data[lq]=a[aq]-aqpp;
\r
796 // printf("_%d ", bmp->data[lq]);
\r
797 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
799 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)
\r
801 if(bmp->data[lq]+bmp->offset >= aq)
\r
803 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);
\r
804 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);
\r
806 else bmp->data[lq]+=(bmp->offset-aqpp);
\r
809 //printf("%02d`", bmp->data[lq]);
\r
810 //if(lq > 0 && lq%bmp->width==0) printf("\n");
\r
813 //printf(" aq=%02d\n", aq);
\r
814 //printf(" aa=%02d\n", aa);
\r
816 //update the palette~
\r
817 modexPalUpdate(bmp, &pp, aq, aqoffset);
\r
820 if(aq<aa){ pp=q; aq++; goto aqpee; }
\r
825 modexPalUpdate1(byte *p)
\r
828 //modexWaitBorder();
\r
829 vga_wait_for_vsync();
\r
830 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
831 for(i=0; i<PAL_SIZE/2; i++)
\r
833 outp(PAL_DATA_REG, p[i]);
\r
835 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
836 vga_wait_for_vsync();
\r
837 for(; i<PAL_SIZE; i++)
\r
839 outp(PAL_DATA_REG, p[(i)]);
\r
844 modexPalUpdate0(byte *p)
\r
847 //modexWaitBorder();
\r
848 vga_wait_for_vsync();
\r
849 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
850 for(i=0; i<PAL_SIZE/2; i++)
\r
852 outp(PAL_DATA_REG, rand());
\r
854 //modexWaitBorder(); /* waits one retrace -- less flicker */
\r
855 vga_wait_for_vsync();
\r
856 for(; i<PAL_SIZE; i++)
\r
858 outp(PAL_DATA_REG, rand());
\r
863 modexPalOverscan(word col)
\r
865 //modexWaitBorder();
\r
866 vga_wait_for_vsync();
\r
867 outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */
\r
868 outp(PAL_DATA_REG, col);
\r
872 //i want to make another vesion that checks the palette when the palette is being appened~
\r
873 void modexchkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)
\r
877 pal = modexNewPal();
\r
879 //printf("q: %02d\n", (*q));
\r
880 printf("chkcolor start~\n");
\r
881 printf("1 (*z): %d\n", (*z)/3);
\r
882 printf("1 (*i): %d\n", (*i)/3);
\r
883 // printf("1 offset of color in palette (*q): %d\n", (*q)/3);
\r
884 printf("wwwwwwwwwwwwwwww\n");
\r
885 //check palette for dups
\r
886 for(; (*z)<PAL_SIZE; (*z)+=3)
\r
888 //printf("\n z: %d\n", (*z));
\r
889 //printf(" q: %d\n", (*q));
\r
890 //printf(" z+q: %d\n\n", ((*z)+(*q)));
\r
893 //---- if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])
\r
896 // printf("\n%d [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
897 // printf("%d [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);
\r
901 else for(zz=0; zz<(*q); zz+=3)
\r
903 //printf("zz: %02d\n", zz/3);
\r
906 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
910 // printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);
\r
911 // printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);
\r
914 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])
\r
916 // printf("\n\nwwwwwwwwwwwwwwww\n");
\r
917 // 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
918 // 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
919 // //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
920 // printf(" z : %d [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
925 planned features that i plan to implement~
\r
926 image that has values on the pallete list!
\r
928 no... wait.... no wwww
\r
930 //for(zzii=0; zzii<3; zzii++)
\r
932 //printf("z+q: %d\n\n", ((*z)+(*q)));
\r
933 a[(((*z)+(*q)))]=zz;
\r
935 (*aa)=(((*z)+(*q)));
\r
936 printf("!! a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);
\r
937 // printf("\n aa: %d\n\n", (*aa));
\r
938 // printf(" a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);
\r
939 // printf("wwwwwwwwwwwwwwww\n\n");
\r
943 printf("================\n");
\r
944 printf("zq: %d [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);
\r
945 printf("zz: %d [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);
\r
946 printf("z : %d [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);
\r
947 printf("================\n");
\r
949 //printf("[%d]", (zz+q));
\r
953 printf("wwwwwwwwwwwwwwww\n");
\r
954 printf("2 (*z): %d\n", (*z)/3);
\r
955 printf("2 (*i): %d\n", (*i)/3);
\r
956 // printf("2 offset of color in palette (*q): %d\n", (*q)/3);
\r
957 printf("chkcolor end~\n");
\r
961 void modexputPixel(page_t *page, int x, int y, byte color)
\r
963 word pageOff = (word) page->data;
\r
964 /* Each address accesses four neighboring pixels, so set
\r
965 Write Plane Enable according to which pixel we want
\r
966 to modify. The plane is determined by the two least
\r
967 significant bits of the x-coordinate: */
\r
968 modexSelectPlane(PLANE(x));
\r
969 //outp(SC_INDEX, 0x02);
\r
970 //outp(SC_DATA, 0x01 << (x & 3));
\r
972 /* The offset of the pixel into the video segment is
\r
973 offset = (width * y + x) / 4, and write the given
\r
974 color to the plane we selected above. Heed the active
\r
975 page start selection. */
\r
976 VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;
\r
980 byte modexgetPixel(page_t *page, int x, int y)
\r
982 word pageOff = (word) page->data;
\r
983 /* Select the plane from which we must read the pixel color: */
\r
984 outpw(GC_INDEX, 0x04);
\r
985 outpw(GC_INDEX+1, x & 3);
\r
987 return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];
\r
991 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
995 word addr = (word) romFontsData.l;
\r
996 word addrq = (page->width/4) * y + (x / 4) + ((word)page->data);
\r
997 word addrr = addrq;
\r
1000 s=romFonts[t].seg;
\r
1001 o=romFonts[t].off;
\r
1002 w=romFonts[t].charSize;
\r
1003 romFontsData.chw=0;
\r
1005 for(; *str != '\0'; str++)
\r
1011 romFontsData.chw = 0;
\r
1012 addrq += (page->width / 4) * 8;
\r
1018 // load the character into romFontsData.l
\r
1019 // no need for inline assembly!
\r
1020 // NTS: It might even be faster to just let the modexDrawChar point directly at ROM font than to copy per char! --J.C.
\r
1021 _fmemcpy(romFontsData.l,MK_FP(s,o+(w*c))/*ROM font location*/,w/*char size*/);
\r
1022 modexDrawChar(page, x_draw/*for mode X planar use*/, t, col, bgcol, addrr);
\r
1023 x_draw += 8; /* track X for edge of screen */
\r
1024 addrr += 2; /* move 8 pixels over (2 x 4 planar pixels per byte) */
\r
1028 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)
\r
1030 word i, s, o, w, j, xp;
\r
1032 word addr = (word) l;
\r
1056 s=romFonts[t].seg;
\r
1057 o=romFonts[t].off;
\r
1059 for(; *str != '\0'; str++)
\r
1062 if((c=='\n'/* || c=="\
\r
1063 "*/)/* || chw>=page->width*/)
\r
1069 //load the letter 'A'
\r
1084 MOV AL, c ; the letter
\r
1087 ADD SI, AX ;the address of charcter
\r
1105 for(i=0; i<w; i++)
\r
1111 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
\r
1112 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
\r
1121 /* palette dump on display! */
\r
1122 void modexpdump(page_t *pee)
\r
1124 int mult=(QUADWH);
\r
1125 int palq=(mult)*TILEWH;
\r
1128 for(paly=0; paly<palq; paly+=mult){
\r
1129 for(palx=0; palx<palq; palx+=mult){
\r
1130 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
\r
1136 /////////////////////////////////////////////////////////////////////////////
\r
1138 // cls() - This clears the screen to the specified color, on the VGA or on //
\r
1139 // the Virtual screen. //
\r
1141 /////////////////////////////////////////////////////////////////////////////
\r
1142 void modexcls(page_t *page, byte color, byte *Where)
\r
1144 //modexClearRegion(page, 0, 0, page->width, page->height, color);
\r
1145 /* set map mask to all 4 planes */
\r
1146 outpw(SC_INDEX, 0xff02);
\r
1147 //_fmemset(VGA, color, 16000);
\r
1148 _fmemset(Where, color, page->width*(page->height)/4);
\r
1152 modexWaitBorder() {
\r
1153 while(inp(INPUT_STATUS_1) & 8) {
\r
1157 while(!(inp(INPUT_STATUS_1) & 8)) {
\r
1162 void modexprintmeminfo(video_t *v)
\r
1165 printf("video memory remaining: %u\n", v->vmem_remain);
\r
1167 for(i=0; i<v->num_of_pages;i++)
\r
1169 printf(" [%u]=", i);
\r
1170 printf("(%Fp)", (v->page[i].data));
\r
1171 printf(" size=%u ", v->page[i].pagesize);
\r
1172 printf("w=%lu h=%lu ", (unsigned long)v->page[i].width, (unsigned long)v->page[i].height);
\r
1173 printf("sw=%lu sh=%lu ", (unsigned long)v->page[i].sw, (unsigned long)v->page[i].sh);
\r
1174 printf("pi=%u", v->page[i].pi);
\r