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