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