]> 4ch.mooo.com Git - 16.git/blob - src/lib/modex16.c
failed fontgfxtest.exe
[16.git] / src / lib / modex16.c
1 /* Project 16 Source Code~\r
2  * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669\r
3  *\r
4  * This file is part of Project 16.\r
5  *\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
10  *\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
15  *\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
20  *\r
21  */\r
22 \r
23 #include <conio.h>\r
24 #include <stdio.h>\r
25 #include <stdlib.h>\r
26 #include "src/lib/modex16.h"\r
27 \r
28 byte far* VGA=(byte far*) 0xA0000000;   /* this points to video memory. */\r
29 \r
30 static void fadePalette(sbyte fade, sbyte start, word iter, byte *palette);\r
31 static byte tmppal[PAL_SIZE];\r
32 \r
33 /////////////////////////////////////////////////////////////////////////////\r
34 //                                                                                                                                                                                                                                              //\r
35 // setvideo() - This function Manages the video modes                                                                                           //\r
36 //                                                                                                                                                                                                                                              //\r
37 /////////////////////////////////////////////////////////////////////////////\r
38 void VGAmodeX(sword vq, boolean cmem, global_game_variables_t *gv)\r
39 {\r
40         union REGS in, out;\r
41 \r
42         switch (vq)\r
43         {\r
44                 case 0: // deinit the video\r
45                         // change to the video mode we were in before we switched to mode 13h\r
46                         modexLeave();\r
47                         in.h.ah = 0x00;\r
48                         in.h.al = gv->video.old_mode;\r
49                         int86(0x10, &in, &out);\r
50                 break;\r
51                 default: // init the video\r
52                         // get old video mode\r
53                         //in.h.ah = 0xf;\r
54                         //int86(0x10, &in, &out);\r
55                         gv->video.old_mode = vgaGetMode();//out.h.al;\r
56                         // enter mode\r
57                         modexEnter(vq, cmem, gv);\r
58                 break;\r
59         }\r
60 }\r
61 \r
62 static void\r
63 vgaSetMode(byte mode)\r
64 {\r
65   int10_setmode(mode);\r
66 }\r
67 \r
68 //---------------------------------------------------\r
69 //\r
70 // Use the bios to get the current video mode\r
71 //\r
72 \r
73 byte/*FIXME: why long? "long" is 32-bit datatype, VGA modes are 8-bit numbers. */\r
74 vgaGetMode()\r
75 {\r
76     return int10_getmode();\r
77 }\r
78 \r
79 /* -========================= Entry  Points ==========================- */\r
80 void modexEnter(sword vq, boolean cmem, global_game_variables_t *gv)\r
81 {\r
82         word i;\r
83         dword far*ptr=(dword far*)vga_state.vga_graphics_ram;//VGA;      /* used for faster screen clearing */\r
84         struct vga_mode_params cm;\r
85         int CRTParmCount;\r
86 \r
87         vgaSetMode(VGA_256_COLOR_MODE);\r
88         vga_enable_256color_modex();\r
89         update_state_from_vga();\r
90         vga_read_crtc_mode(&cm);\r
91 \r
92         switch(vq)\r
93         {\r
94                 case 1:\r
95                         //CRTParmCount = sizeof(ModeX_320x240regs) / sizeof(ModeX_320x240regs[0]);\r
96                         /* width and height */\r
97                         gv->video.page[0].sw=vga_state.vga_width = 320; // VGA lib currently does not update this\r
98                         gv->video.page[0].sh=vga_state.vga_height = 240; // VGA lib currently does not update this\r
99 \r
100                         // 320x240 mode 60Hz\r
101                         cm.horizontal_total=0x5f + 5; /* CRTC[0]             -5 */\r
102                         cm.horizontal_display_end=0x4f + 1; /* CRTC[1]       -1 */\r
103                         cm.horizontal_blank_start=0x50 + 1; /* CRTC[2] */\r
104                         cm.horizontal_blank_end=0x82 + 1;   /* CRTC[3] bit 0-4 & CRTC[5] bit 7 */\r
105                         cm.horizontal_start_retrace=0x54;/* CRTC[4] */\r
106                         cm.horizontal_end_retrace=0x80; /* CRTC[5] bit 0-4 */\r
107                         //cm.horizontal_start_delay_after_total=0x3e; /* CRTC[3] bit 5-6 */\r
108                         //cm.horizontal_start_delay_after_retrace=0x41; /* CRTC[5] bit 5-6 */\r
109                         cm.vertical_total = 0x20D + 2;\r
110                         cm.vertical_start_retrace = 0x1EA;\r
111                         cm.vertical_end_retrace = 0x1EC;\r
112                         cm.vertical_display_end = 480;\r
113                         cm.vertical_blank_start = 0x1E7 + 1;\r
114                         cm.vertical_blank_end = 0x206 + 1;\r
115                         cm.clock_select = 0; /* misc register = 0xE3  25MHz */\r
116                         cm.vsync_neg = 1;\r
117                         cm.hsync_neg = 1;\r
118 \r
119                         cm.scan_double=1;               /* CRTC[0x09] bit 7 */\r
120                         cm.max_scanline=0;              /* CRTC[0x09] bit 4-0 */\r
121                         break;\r
122                 case 2: // TODO: 160x120 according to ModeX_160x120regs\r
123                         return;\r
124                 case 3: // TODO: 160x120 according to ModeX_320x200regs\r
125                         return;\r
126                 case 4: // TODO: 160x120 according to ModeX_192x144regs\r
127                         return;\r
128                 case 5: // TODO: 160x120 according to ModeX_256x192regs\r
129                         return;\r
130                 default:\r
131                         return;\r
132         }\r
133 \r
134         vga_write_crtc_mode(&cm,0);\r
135 \r
136         /* clear video memory */\r
137         switch (cmem)\r
138         {\r
139                 case 1:\r
140                 /* clear video memory */\r
141                 vga_write_sequencer(2/*map mask register*/,0xf/*all 4 planes*/);\r
142                 for(i=0; i<0x8000; i++) ptr[i] = 0x0000;\r
143                 break;\r
144         }\r
145         gv->video.page[0].tilesw = gv->video.page[0].sw/TILEWH;\r
146         gv->video.page[0].tilesh = gv->video.page[0].sh/TILEWH;\r
147         //TODO MAKE FLEXIBLE~\r
148         gv->video.page[0].tilemidposscreenx = gv->video.page[0].tilesw;\r
149         gv->video.page[0].tilemidposscreeny = (gv->video.page[0].tilesh/2)+1;\r
150         #define PAGE_SIZE               (word)(gv->video.page[0].sw/4 * gv->video.page[0].sh)\r
151 }\r
152 \r
153 void\r
154 modexLeave() {\r
155         /* TODO restore original mode and palette */\r
156         vgaSetMode(TEXT_MODE);\r
157 }\r
158 \r
159 page_t\r
160 modexDefaultPage(page_t *p)\r
161 {\r
162     page_t page;\r
163 \r
164     /* default page values */\r
165     page.data = vga_state.vga_graphics_ram;//VGA;\r
166     page.dx = 0;\r
167     page.dy = 0;\r
168         page.sw = p->sw;\r
169         page.sh = p->sh;\r
170         page.width = p->sw;\r
171         page.height = p->sh;\r
172         page.tw = page.sw/TILEWH;\r
173         page.th = page.sh/TILEWH;\r
174         page.tilemidposscreenx = page.tw/2;\r
175         page.tilemidposscreeny = (page.th/2)+1;\r
176         page.tilesw=p->tilesw;\r
177         page.tilesh=p->tilesh;\r
178         //pageSize = p->sw*p->sh;\r
179         page.id = 0;\r
180 \r
181     return page;\r
182 }\r
183 \r
184 /* returns the next page in contiguous memory\r
185  * the next page will be the same size as p, by default\r
186  */\r
187 page_t\r
188 modexNextPage(page_t *p) {\r
189     page_t result;\r
190 \r
191     result.data = p->data + (p->width/4)*p->height;\r
192     result.dx = 0;\r
193     result.dy = 0;\r
194     result.width = p->width;\r
195     result.height = p->height;\r
196         result.tw = p->width/TILEWH;\r
197         result.th = p->height/TILEWH;\r
198         result.id = p->id+1;\r
199 \r
200         return result;\r
201 //      return modexNextPageFlexibleSize(&p, p->width, p->height);\r
202 }\r
203 \r
204 //next page with defined dimentions~\r
205 page_t\r
206 modexNextPageFlexibleSize(page_t *p, word x, word y)\r
207 {\r
208         page_t result;\r
209 \r
210         result.data = p->data + (p->width/4)*p->height;  /* compute the offset */\r
211         result.dx = 0;\r
212         result.dy = 0;\r
213         result.width = x;\r
214         result.height = y;\r
215         result.tw = p->width/TILEWH;\r
216         result.th = p->height/TILEWH;\r
217         result.id = p->id+1;\r
218 \r
219         return result;\r
220 }\r
221 \r
222 \r
223 void\r
224 modexShowPage(page_t *page) {\r
225     word high_address;\r
226     word low_address;\r
227     word offset;\r
228     byte crtcOffset;\r
229 \r
230     /* calculate offset */\r
231     offset = (word) page->data;\r
232     offset += page->dy * (page->width >> 2 );\r
233     offset += page->dx >> 2;\r
234 \r
235     /* calculate crtcOffset according to virtual width */\r
236     crtcOffset = page->width >> 3;\r
237 \r
238     high_address = HIGH_ADDRESS | (offset & 0xff00);\r
239     low_address  = LOW_ADDRESS  | (offset << 8);\r
240 \r
241     /* wait for appropriate timing and then program CRTC */\r
242     while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));\r
243     outpw(CRTC_INDEX, high_address);\r
244     outpw(CRTC_INDEX, low_address);\r
245     outp(CRTC_INDEX, 0x13);\r
246     outp(CRTC_DATA, crtcOffset);\r
247 \r
248     /*  wait for one retrace */\r
249     while (!(inp(INPUT_STATUS_1) & VRETRACE));\r
250 \r
251     /* do PEL panning here */\r
252     outp(AC_INDEX, 0x33);\r
253     outp(AC_INDEX, (page->dx & 0x03) << 1);\r
254 }\r
255 \r
256 \r
257 void\r
258 modexPanPage(page_t *page, int dx, int dy) {\r
259     page->dx = dx;\r
260     page->dy = dy;\r
261 }\r
262 \r
263 \r
264 void\r
265 modexSelectPlane(byte plane) {\r
266     outp(SC_INDEX, MAP_MASK);     /* select plane */\r
267     outp(SC_DATA,  plane);\r
268 }\r
269 \r
270 \r
271 void\r
272 modexClearRegion(page_t *page, int x, int y, int w, int h, byte  color) {\r
273     word pageOff = (word) page->data;\r
274     word xoff=x/4;       /* xoffset that begins each row */\r
275     word scanCount=w/4;  /* number of iterations per row (excluding right clip)*/\r
276     word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */\r
277     word nextRow = page->width/4-scanCount-1;  /* loc of next row */\r
278     byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08};  /* clips for rectangles not on 4s */\r
279     byte rclip[] = {0x00, 0x01, 0x03, 0x07};\r
280     byte left = lclip[x&0x03];\r
281     byte right = rclip[(x+w)&0x03];\r
282 \r
283     /* handle the case which requires an extra group */\r
284     if((x & 0x03) && !((x+w) & 0x03)) {\r
285       right=0x0f;\r
286     }\r
287 \r
288     __asm {\r
289                 MOV AX, SCREEN_SEG      ; go to the VGA memory\r
290                 MOV ES, AX\r
291                 MOV DI, poffset  ; go to the first pixel\r
292                 MOV DX, SC_INDEX        ; point to the map mask\r
293                 MOV AL, MAP_MASK\r
294                 OUT DX, AL\r
295                 INC DX\r
296                 MOV AL, color      ; get ready to write colors\r
297         SCAN_START:\r
298                 MOV CX, scanCount       ; count the line\r
299                 MOV BL, AL            ; remember color\r
300                 MOV AL, left        ; do the left clip\r
301                 OUT DX, AL            ; set the left clip\r
302                 MOV AL, BL            ; restore color\r
303                 STOSB              ; write the color\r
304                 DEC CX\r
305                 JZ SCAN_DONE        ; handle 1 group stuff\r
306 \r
307                 ;-- write the main body of the scanline\r
308                 MOV BL, AL            ; remember color\r
309                 MOV AL, 0x0f        ; write to all pixels\r
310                 OUT DX, AL\r
311                 MOV AL, BL            ; restore color\r
312                 REP STOSB              ; write the color\r
313         SCAN_DONE:\r
314                 MOV BL, AL            ; remeber color\r
315                 MOV AL, right\r
316                 OUT DX, AL            ; do the right clip\r
317                 MOV AL, BL            ; restore color\r
318                 STOSB              ; write pixel\r
319                 ADD DI, nextRow  ; go to the next row\r
320                 DEC h\r
321                 JNZ SCAN_START\r
322     }\r
323 }\r
324 \r
325 /* moved to src/lib/modex16/16render.c */\r
326 \r
327 /* copy a region of video memory from one page to another.\r
328  * It assumes that the left edge of the tile is the same on both\r
329  * regions and the memory areas do not overlap.\r
330  */\r
331 void\r
332 modexCopyPageRegion(page_t *dest, page_t *src,\r
333                     word sx, word sy,\r
334                     word dx, word dy,\r
335                     word width, word height)\r
336 {\r
337     word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;\r
338     word soffset = (word)src->data + sy*(src->width/4) + sx/4;\r
339     word scans   = width/4;\r
340     word nextSrcRow = src->width/4 - scans - 1;\r
341     word nextDestRow = dest->width/4 - scans - 1;\r
342     byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08};  /* clips for rectangles not on 4s */\r
343     byte rclip[] = {0x0f, 0x01, 0x03, 0x07};\r
344     byte left = lclip[sx&0x03];\r
345     byte right = rclip[(sx+width)&0x03];\r
346 \r
347     __asm {\r
348                 MOV AX, SCREEN_SEG      ; work in the vga space\r
349                 MOV ES, AX            ;\r
350                 MOV DI, doffset  ;\r
351                 MOV SI, soffset  ;\r
352 \r
353                 MOV DX, GC_INDEX        ; turn off cpu bits\r
354                 MOV AX, 0008h      ;\r
355                 OUT DX, AX\r
356 \r
357                 MOV AX, SC_INDEX        ; point to the mask register\r
358                 MOV DX, AX            ;\r
359                 MOV AL, MAP_MASK        ;\r
360                 OUT DX, AL            ;\r
361                 INC DX            ;\r
362 \r
363         ROW_START:\r
364                 PUSH DS\r
365                 MOV AX, ES\r
366                 MOV DS, AX\r
367                 MOV CX, scans      ; the number of latches\r
368 \r
369                 MOV AL, left        ; do the left column\r
370                 OUT DX, AL            ;\r
371                 MOVSB              ;\r
372                 DEC CX            ;\r
373 \r
374                 MOV AL, 0fh          ; do the inner columns\r
375                 OUT DX, AL\r
376                 REP MOVSB              ; copy the pixels\r
377 \r
378                 MOV AL, right      ; do the right column\r
379                 OUT DX, AL\r
380                 MOVSB\r
381                 POP DS\r
382 \r
383                 MOV AX, SI            ; go the start of the next row\r
384                 ADD AX, nextSrcRow      ;\r
385                 MOV SI, AX            ;\r
386                 MOV AX, DI            ;\r
387                 ADD AX, nextDestRow     ;\r
388                 MOV DI, AX            ;\r
389 \r
390                 DEC height            ; do the rest of the actions\r
391                 JNZ ROW_START      ;\r
392 \r
393                 MOV DX, GC_INDEX+1      ; go back to CPU data\r
394                 MOV AL, 0ffh        ; none from latches\r
395                 OUT DX, AL            ;\r
396     }\r
397 }\r
398 \r
399 \r
400 /* fade and flash */\r
401 void\r
402 modexFadeOn(word fade, byte *palette) {\r
403     fadePalette(-fade, 64, 64/fade+1, palette);\r
404 }\r
405 \r
406 \r
407 void\r
408 modexFadeOff(word fade, byte *palette) {\r
409     fadePalette(fade, 0, 64/fade+1, palette);\r
410 }\r
411 \r
412 \r
413 void\r
414 modexFlashOn(word fade, byte *palette) {\r
415     fadePalette(fade, -64, 64/fade+1, palette);\r
416 }\r
417 \r
418 \r
419 void\r
420 modexFlashOff(word fade, byte *palette) {\r
421     fadePalette(-fade, 0, 64/fade+1, palette);\r
422 }\r
423 \r
424 \r
425 static void\r
426 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {\r
427     word i;\r
428     byte dim = start;\r
429 \r
430     /* handle the case where we just update */\r
431     if(iter == 0) {\r
432         modexPalUpdate1(palette);\r
433         return;\r
434     }\r
435 \r
436     while(iter > 0) {  /* FadeLoop */\r
437         for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */\r
438             tmppal[i] = palette[i] - dim;\r
439             if(tmppal[i] > 127) {\r
440                 tmppal[i] = 0;\r
441             } else if(tmppal[i] > 63) {\r
442                 tmppal[i] = 63;\r
443             }\r
444         }\r
445         modexPalUpdate1(tmppal);\r
446         iter--;\r
447         dim += fade;\r
448     }\r
449 }\r
450 \r
451 \r
452 /* save and load */\r
453 void\r
454 modexPalSave(byte *palette) {\r
455     int  i;\r
456 \r
457     outp(PAL_READ_REG, 0);      /* start at palette entry 0 */\r
458     for(i=0; i<PAL_SIZE; i++) {\r
459         palette[i] = inp(PAL_DATA_REG); /* read the palette data */\r
460     }\r
461 }\r
462 \r
463 \r
464 byte *\r
465 modexNewPal() {\r
466     byte *ptr;\r
467     ptr = malloc(PAL_SIZE);\r
468 \r
469     /* handle errors */\r
470     if(!ptr) {\r
471         printf("Could not allocate palette.\n");\r
472         exit(-1);\r
473     }\r
474 \r
475     return ptr;\r
476 }\r
477 \r
478 \r
479 void\r
480 modexLoadPalFile(byte *filename, byte **palette) {\r
481     FILE *file;\r
482     byte *ptr;\r
483 \r
484     /* free the palette if it exists */\r
485     if(*palette) {\r
486         free(*palette);\r
487     }\r
488 \r
489     /* allocate the new palette */\r
490     *palette = modexNewPal();\r
491 \r
492     /* open the file */\r
493     file = fopen(filename, "rb");\r
494     if(!file) {\r
495         printf("Could not open palette file: %s\n", filename);\r
496         exit(-2);\r
497     }\r
498 \r
499     /* read the file */\r
500     ptr = *palette;\r
501     while(!feof(file)) {\r
502         *ptr++ = fgetc(file);\r
503     }\r
504 \r
505     fclose(file);\r
506 }\r
507 \r
508 \r
509 void\r
510 modexSavePalFile(char *filename, byte *pal) {\r
511     unsigned int i;\r
512     FILE *file;\r
513 \r
514     /* open the file for writing */\r
515     file = fopen(filename, "wb");\r
516     if(!file) {\r
517         printf("Could not open %s for writing\n", filename);\r
518         exit(-2);\r
519     }\r
520 \r
521     /* write the data to the file */\r
522     fwrite(pal, 1, PAL_SIZE, file);\r
523     fclose(file);\r
524 }\r
525 \r
526 \r
527 /* blanking */\r
528 void\r
529 modexPalBlack() {\r
530     fadePalette(-1, 64, 1, tmppal);\r
531 }\r
532 \r
533 \r
534 void\r
535 modexPalWhite() {\r
536     fadePalette(-1, -64, 1, tmppal);\r
537 }\r
538 \r
539 \r
540 /* utility */\r
541 void\r
542 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)\r
543 {\r
544         byte *p = bmp->palette;\r
545         word w=0;\r
546         word q=0;\r
547         word qq=0;\r
548         static word a[PAL_SIZE];        //palette array of change values!\r
549         word z=0, aq=0, aa=0, pp=0;\r
550 \r
551         //modexWaitBorder();\r
552         vga_wait_for_vsync();\r
553         if((*i)==0)\r
554         {\r
555                 memset(a, -1, sizeof(a));\r
556                 outp(PAL_WRITE_REG, 0);  /* start at the beginning of palette */\r
557         }\r
558         else if(qp==0)\r
559         {\r
560                 q=(*i);\r
561         }\r
562         else\r
563         {\r
564                 q=(*i);\r
565                 qq=(*i)/3;\r
566 //            printf("q: %02d\n", (q));\r
567 //            printf("qq: %02d\n", (qq));\r
568                 //printf("      (*i)-q=%02d\n", (*i)-q);\r
569                 outp(PAL_WRITE_REG, qq);  /* start at the beginning of palette */\r
570         }\r
571         if((*i)<PAL_SIZE/2 && w==0)\r
572         {\r
573                 for(; (*i)<PAL_SIZE/2; (*i)++)\r
574                 {\r
575                         //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
576 //____            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
577                         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
578                         {\r
579                                 w++;\r
580                                 break;\r
581                         }\r
582                         else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))\r
583                         {\r
584                                 //printf("qp=%d\n", qp);\r
585                                 //printf("            (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);\r
586                                 printf("                %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);\r
587                                 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!\r
588                                 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }\r
589                         }\r
590                         else\r
591                         {\r
592                                 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);\r
593                                 else\r
594                                 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);\r
595                                 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);\r
596                                 printf("p[]=%d  qp=%d   p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }\r
597                         }\r
598                 }\r
599                 //if(qp>0) printf("qp=%d\n", qp);\r
600                 //if(qp>0) printf("                                          (*i)=%d\n", (*i)/3);\r
601         }\r
602         //modexWaitBorder();      /* waits one retrace -- less flicker */\r
603         vga_wait_for_vsync();\r
604         if((*i)>=PAL_SIZE/2 && w==0)\r
605         {\r
606                 for(; (*i)<PAL_SIZE; (*i)++)\r
607                 {\r
608 //____            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
609                         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
610                         {\r
611                                 w++;\r
612                                 break;\r
613                         }\r
614                         else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))\r
615                         {\r
616                                 //printf("qp=%d\n", qp);\r
617                                 //printf("            (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);\r
618                                 printf("                %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));\r
619                                 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!\r
620                                 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }\r
621                         }\r
622                         else\r
623                         {\r
624                                 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);\r
625                                 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);\r
626                                 printf("p[]=%d  qp=%d   p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }\r
627                         }\r
628                 }\r
629                 //printf("                                            (*i)=%d\n", (*i)/3);\r
630         }\r
631 \r
632 printf("\nqqqqqqqq\n\n");\r
633 \r
634         //palette checker~\r
635         if(q>0 && qp==0)\r
636         {\r
637                 long lq;\r
638                 long bufSize = (bmp->width * bmp->height);\r
639                 pp = q;\r
640                 //printf("1(*i)=%02d\n", (*i)/3);\r
641                 //printf("1z=%02d\n", z/3);\r
642                 modexchkcolor(bmp, &q, &a, &aa, &z, i);\r
643                 //printf("2(*i)=%02d\n", (*i)/3);\r
644                 //printf("2z=%02d\n", z/3);\r
645                 aq=0;\r
646 aqpee:\r
647                 while(aq<=aa)\r
648                 {\r
649 //                    printf("a[%02d]=(%d)\n", aq, a[aq]);\r
650                         if(a[aq]==-1) aq++;\r
651                         else { aqoffset++; break; }\r
652                 }\r
653 //update the image data here!\r
654         for(lq=0; lq<bufSize; lq++)\r
655         {\r
656                                 /*\r
657                                                                         note to self\r
658                                                                         use a[qp] instead of bmp->offset for this spot!\r
659                                                                         NO! wwww\r
660                                 */\r
661 \r
662                                 /*\r
663                                 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww\r
664                                 */\r
665 \r
666                 //(offset/bmp->offset)*bmp->offset\r
667 \r
668 \r
669                 //printf("%02d ",bmp->data[lq]+bmp->offset);\r
670                 //if(lq > 0 && lq%bmp->width==0) printf("\n");\r
671                 //printf("%02d_", bmp->data[lq]+bmp->offset);\r
672                 /*if(bmp->data[lq]+bmp->offset==aq)\r
673                 {\r
674                         //printf("%02d", bmp->data[lq]);\r
675                         //printf("\n%02d\n", bmp->offset);\r
676                         printf("aq=%02d ", aq);\r
677                         printf("a[aq]=%02d      ", a[aq]);\r
678                         printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);\r
679                         printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);\r
680                         //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);\r
681 //++++            bmp->data[lq]=a[aq]-aqpp;\r
682 //                    printf("_%d ", bmp->data[lq]);\r
683                         //if(lq > 0 && lq%bmp->width==0) printf("\n");\r
684                 }\r
685                 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)\r
686                 {\r
687                         if(bmp->data[lq]+bmp->offset >= aq)\r
688                         {\r
689                                 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);\r
690                                 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);\r
691                         }\r
692                         else bmp->data[lq]+=(bmp->offset-aqpp);\r
693                 }*/\r
694 \r
695                 //printf("%02d`", bmp->data[lq]);\r
696                 //if(lq > 0 && lq%bmp->width==0) printf("\n");\r
697         }\r
698 \r
699 //printf("            aq=%02d\n", aq);\r
700 //printf("            aa=%02d\n", aa);\r
701 \r
702         //update the palette~\r
703         modexPalUpdate(bmp, &pp, aq, aqoffset);\r
704         (*i)=pp;\r
705 \r
706         if(aq<aa){ pp=q; aq++; goto aqpee; }\r
707         }\r
708 }\r
709 \r
710 void\r
711 modexPalUpdate1(byte *p)\r
712 {\r
713         int i;\r
714         //modexWaitBorder();\r
715         vga_wait_for_vsync();\r
716         outp(PAL_WRITE_REG, 0);  /* start at the beginning of palette */\r
717         for(i=0; i<PAL_SIZE/2; i++)\r
718         {\r
719                 outp(PAL_DATA_REG, p[i]);\r
720         }\r
721         //modexWaitBorder();      /* waits one retrace -- less flicker */\r
722         vga_wait_for_vsync();\r
723         for(; i<PAL_SIZE; i++)\r
724         {\r
725                 outp(PAL_DATA_REG, p[(i)]);\r
726         }\r
727 }\r
728 \r
729 void\r
730 modexPalUpdate0(byte *p)\r
731 {\r
732         int i;\r
733         //modexWaitBorder();\r
734         vga_wait_for_vsync();\r
735         outp(PAL_WRITE_REG, 0);  /* start at the beginning of palette */\r
736         for(i=0; i<PAL_SIZE/2; i++)\r
737         {\r
738                 outp(PAL_DATA_REG, rand());\r
739         }\r
740         //modexWaitBorder();      /* waits one retrace -- less flicker */\r
741         vga_wait_for_vsync();\r
742         for(; i<PAL_SIZE; i++)\r
743         {\r
744                 outp(PAL_DATA_REG, rand());\r
745         }\r
746 }\r
747 \r
748 void\r
749 modexPalOverscan(byte *p, word col)\r
750 {\r
751         //modexWaitBorder();\r
752         vga_wait_for_vsync();\r
753         outp(PAL_WRITE_REG, 0);  /* start at the beginning of palette */\r
754         outp(PAL_DATA_REG, col);\r
755 }\r
756 \r
757 //color checker~\r
758 //i want to make another vesion that checks the palette when the palette is being appened~\r
759 void modexchkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)\r
760 {\r
761                 byte *pal;\r
762                 word zz=0;\r
763                 pal = modexNewPal();\r
764                 modexPalSave(pal);\r
765                 //printf("q: %02d\n", (*q));\r
766                 printf("chkcolor start~\n");\r
767                 printf("1                              (*z): %d\n", (*z)/3);\r
768                 printf("1                              (*i): %d\n", (*i)/3);\r
769 //            printf("1 offset of color in palette    (*q): %d\n", (*q)/3);\r
770                 printf("wwwwwwwwwwwwwwww\n");\r
771                 //check palette for dups\r
772                 for(; (*z)<PAL_SIZE; (*z)+=3)\r
773                 {\r
774                         //printf("\n        z: %d\n", (*z));\r
775                         //printf("            q: %d\n", (*q));\r
776                         //printf("            z+q: %d\n\n", ((*z)+(*q)));\r
777                         //if((*z)%3==0)\r
778                         //{\r
779 //----                    if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])\r
780                                 if((*z)==(*i))\r
781                                 {\r
782 //                                    printf("\n%d    [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);\r
783 //                                    printf("%d      [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);\r
784 //0000                            (*z)-=3;\r
785                                         break;\r
786                                 }\r
787                                 else for(zz=0; zz<(*q); zz+=3)\r
788                                 {\r
789                                         //printf("zz: %02d\n", zz/3);\r
790                                         if(zz%3==0)\r
791                                         {\r
792                                                 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
793                                                 {\r
794 //                                                    (*z)-=3;\r
795 //                                                    (*i)-=3;\r
796 //                                                    printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);\r
797 //                                                    printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);\r
798                                                         break;\r
799                                                 }\r
800                                                 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])\r
801                                                 {\r
802 //                                                    printf("\n\nwwwwwwwwwwwwwwww\n");\r
803 //                                                    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
804 //                                                    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
805 //                                                    //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
806 //                                                    printf("  z : %d  [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);\r
807 //++++                                            (*i)--;\r
808 //                                                    (*z)--;\r
809                                                         //expand dong here\r
810 /*\r
811 planned features that i plan to implement~\r
812 image that has values on the pallete list!\r
813 wwww\r
814 no... wait.... no wwww\r
815 */\r
816                                                         //for(zzii=0; zzii<3; zzii++)\r
817                                                         //{\r
818                                                                 //printf("z+q: %d\n\n", ((*z)+(*q)));\r
819                                                                 a[(((*z)+(*q)))]=zz;\r
820                                                         //}\r
821                                                         (*aa)=(((*z)+(*q)));\r
822                                                         printf("!!                                    a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);\r
823 //                                                    printf("\n              aa: %d\n\n", (*aa));\r
824 //                                                    printf("  a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);\r
825 //                                                    printf("wwwwwwwwwwwwwwww\n\n");\r
826                                                 }\r
827                                                 /*else\r
828                                                 {\r
829                                                         printf("================\n");\r
830                                                         printf("zq: %d  [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);\r
831                                                         printf("zz: %d  [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);\r
832                                                         printf("z : %d  [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);\r
833                                                         printf("================\n");\r
834                                                 }*/\r
835                                                 //printf("[%d]", (zz+q));\r
836                                         }\r
837                                 }\r
838                 }\r
839                 printf("wwwwwwwwwwwwwwww\n");\r
840                 printf("2                              (*z): %d\n", (*z)/3);\r
841                 printf("2                              (*i): %d\n", (*i)/3);\r
842 //            printf("2 offset of color in palette    (*q): %d\n", (*q)/3);\r
843                 printf("chkcolor end~\n");\r
844                 free(pal);\r
845 }\r
846 \r
847 void modexputPixel(page_t *page, int x, int y, byte color)\r
848 {\r
849         word pageOff = (word) page->data;\r
850         /* Each address accesses four neighboring pixels, so set\r
851            Write Plane Enable according to which pixel we want\r
852            to modify.  The plane is determined by the two least\r
853            significant bits of the x-coordinate: */\r
854         modexSelectPlane(PLANE(x));\r
855         //outp(SC_INDEX, 0x02);\r
856         //outp(SC_DATA, 0x01 << (x & 3));\r
857 \r
858         /* The offset of the pixel into the video segment is\r
859            offset = (width * y + x) / 4, and write the given\r
860            color to the plane we selected above.  Heed the active\r
861            page start selection. */\r
862         VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;\r
863 \r
864 }\r
865 \r
866 byte modexgetPixel(page_t *page, int x, int y)\r
867 {\r
868         word pageOff = (word) page->data;\r
869         /* Select the plane from which we must read the pixel color: */\r
870         outpw(GC_INDEX, 0x04);\r
871         outpw(GC_INDEX+1, x & 3);\r
872 \r
873         return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];\r
874 \r
875 }\r
876 \r
877 void modexhlin(page_t *page, word xl, word xh, word y, word color)\r
878 {\r
879         word x;\r
880         word yy=0;\r
881 \r
882         for(x=0;x<xh*4;x+=4)\r
883         {\r
884                 if(x+4>=page[0].sw-1){ x=0; yy+=4; }\r
885                 modexClearRegion(page, x+xl, y+yy, 4, 4, color);\r
886         }\r
887         //modexputPixel(page, x+xl, y, color);\r
888 }\r
889 \r
890 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str, boolean q)\r
891 {\r
892         word s, o, w;\r
893         word addr = (word) romFontsData.l;\r
894         byte c;\r
895 \r
896         s=romFonts[t].seg;\r
897         o=romFonts[t].off;\r
898         w=romFonts[t].charSize;\r
899         romFontsData.chw=0;\r
900 \r
901         for(; *str != '\0'; str++)\r
902         {\r
903         c = (*str);\r
904         if((c=='\n'/* || c=="\\r
905 "*/) || romFontsData.chw\r
906 >=page->width)\r
907         {\r
908                 romFontsData.chw=0;\r
909                 y+=romFonts[t].charSize;\r
910                 continue;\r
911         }\r
912         //load the letter 'A'\r
913         __asm {\r
914                 MOV DI, addr\r
915                 MOV SI, o\r
916                 MOV ES, s\r
917                 SUB AH, AH\r
918                 MOV AL, c       ; the letter\r
919                 MOV CX, w\r
920                 MUL CX\r
921                 ADD SI, AX      ;the address of charcter\r
922         L1:     MOV AX, ES:SI\r
923                 MOV DS:DI, AX\r
924                 INC SI\r
925                 INC DI\r
926                 DEC CX\r
927                 JNZ L1\r
928         }\r
929 //TODO: OPTIMIZE THIS!!!!\r
930                 modexDrawCharPBuf(page, x, y, t, col, bgcol, q);\r
931 \r
932                 //if(!q) getch();\r
933         }\r
934 }\r
935 \r
936 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)\r
937 {\r
938         word i, s, o, w, j, xp;\r
939         byte l[1024];\r
940         word addr = (word) l;\r
941         word chw=0;\r
942         byte c;\r
943 \r
944         switch(t)\r
945         {\r
946                 case 0:\r
947                         w=14;\r
948                 break;\r
949                 case 1:\r
950                         w=8;\r
951                 break;\r
952                 case 2:\r
953                         w=8;\r
954                 break;\r
955                 case 3:\r
956                         w=16;\r
957                 break;\r
958                 default:\r
959                         t=3;\r
960                         w=16;\r
961                 break;\r
962         }\r
963 \r
964         s=romFonts[t].seg;\r
965         o=romFonts[t].off;\r
966 \r
967         for(; *str != '\0'; str++)\r
968         {\r
969         c = (*str);\r
970         if((c=='\n'/* || c=="\\r
971 "*/)/* || chw>=page->width*/)\r
972         {\r
973                 chw=0;\r
974                 y+=w;\r
975                 continue;\r
976         }\r
977         //load the letter 'A'\r
978         __asm {\r
979                 MOV DI, addr\r
980                 MOV SI, o\r
981                 MOV ES, s\r
982                 SUB AH, AH\r
983                 MOV AL, c       ; the letter\r
984                 MOV CX, w\r
985                 MUL CX\r
986                 ADD SI, AX      ;the address of charcter\r
987         L1:     MOV AX, ES:SI\r
988                 MOV DS:DI, AX\r
989                 INC SI\r
990                 INC DI\r
991                 DEC CX\r
992                 JNZ L1\r
993         }\r
994 \r
995                 for(i=0; i<w; i++)\r
996                 {\r
997                         j=1<<8;\r
998                         xp=0;\r
999                         while(j)\r
1000                         {\r
1001                                 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);\r
1002                                 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);\r
1003                                 xp++;\r
1004                                 j>>=1;\r
1005                         }\r
1006                 }\r
1007                 chw += xp;\r
1008         }\r
1009 }\r
1010 \r
1011 /* palette dump on display! */\r
1012 void modexpdump(page_t *pee)\r
1013 {\r
1014         int mult=(QUADWH);\r
1015         int palq=(mult)*TILEWH;\r
1016         int palcol=0;\r
1017         int palx, paly;\r
1018         for(paly=0; paly<palq; paly+=mult){\r
1019                 for(palx=0; palx<palq; palx+=mult){\r
1020                                 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);\r
1021                         palcol++;\r
1022                 }\r
1023         }\r
1024 }\r
1025 \r
1026 /////////////////////////////////////////////////////////////////////////////\r
1027 //                                                                                                                                               //\r
1028 // cls() - This clears the screen to the specified color, on the VGA or on //\r
1029 //               the Virtual screen.                                                                                     //\r
1030 //                                                                                                                                               //\r
1031 /////////////////////////////////////////////////////////////////////////////\r
1032 void modexcls(page_t *page, byte color, byte *Where)\r
1033 {\r
1034         //modexClearRegion(page, 0, 0, page->width, page->height, color);\r
1035         /* set map mask to all 4 planes */\r
1036         outpw(SC_INDEX, 0xff02);\r
1037         //_fmemset(VGA, color, 16000);\r
1038         _fmemset(Where, color, page->width*(page->height)/4);\r
1039 }\r
1040 \r
1041 /*void\r
1042 modexWaitBorder() {\r
1043     while(inp(INPUT_STATUS_1)  & 8)  {\r
1044         // spin\r
1045     }\r
1046 \r
1047     while(!(inp(INPUT_STATUS_1)  & 8))  {\r
1048         // spin\r
1049     }\r
1050 }*/\r
1051 \r
1052 void bios_cls() {\r
1053         VGA_ALPHA_PTR ap;\r
1054         VGA_RAM_PTR rp;\r
1055         unsigned char m;\r
1056 \r
1057         m = int10_getmode();\r
1058         if ((rp=vga_state.vga_graphics_ram) != NULL && !(m <= 3 || m == 7)) {\r
1059                 unsigned int i,im;\r
1060 \r
1061                 im = (FP_SEG(vga_state.vga_graphics_ram_fence) - FP_SEG(vga_state.vga_graphics_ram));\r
1062                 if (im > 0xFFE) im = 0xFFE;\r
1063                 im <<= 4;\r
1064                 for (i=0;i < im;i++) vga_state.vga_graphics_ram[i] = 0;\r
1065         }\r
1066         else if ((ap=vga_state.vga_alpha_ram) != NULL) {\r
1067                 unsigned int i,im;\r
1068 \r
1069                 im = (FP_SEG(vga_state.vga_alpha_ram_fence) - FP_SEG(vga_state.vga_alpha_ram));\r
1070                 if (im > 0x7FE) im = 0x7FE;\r
1071                 im <<= 4 - 1; /* because ptr is type uint16_t */\r
1072                 for (i=0;i < im;i++) vga_state.vga_alpha_ram[i] = 0x0720;\r
1073         }\r
1074         else {\r
1075                 printf("WARNING: bios cls no ptr\n");\r
1076         }\r
1077 }\r