]> 4ch.mooo.com Git - 16.git/blob - src/lib/modex16.c
pcxtest0 for planar dump test
[16.git] / src / lib / modex16.c
1 /* Project 16 Source Code~\r
2  * Copyright (C) 2012-2015 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 version 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, 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, gv);\r
58                 break;\r
59         }\r
60 }\r
61 \r
62 static void\r
63 vgaSetMode(byte mode)\r
64 {\r
65   union REGS regs;\r
66 \r
67   regs.h.ah = SET_MODE;\r
68   regs.h.al = mode;\r
69   int86(VIDEO_INT, &regs, &regs);\r
70 }\r
71 \r
72 //---------------------------------------------------\r
73 //\r
74 // Use the bios to get the current video mode\r
75 //\r
76 \r
77 long\r
78 vgaGetMode()\r
79 {\r
80     union REGS rg;\r
81 \r
82     rg.h.ah = 0x0f;\r
83     int86(VIDEO_INT, &rg, &rg);\r
84 \r
85     return rg.h.al;\r
86 }\r
87 \r
88 /* -========================= Entry  Points ==========================- */\r
89 void\r
90 modexEnter(sword vq, global_game_variables_t *gv)\r
91 {\r
92         word i;\r
93         dword far*ptr=(dword far*)VGA;      /* used for faster screen clearing */\r
94         int CRTParmCount;\r
95         /* common mode X initiation stuff~ */\r
96         modexsetBaseXMode(gv->video.page);\r
97 \r
98         switch(vq)\r
99         {\r
100                 case 1:\r
101                         CRTParmCount = sizeof(ModeX_320x240regs) / sizeof(ModeX_320x240regs[0]);\r
102                         /* width and height */\r
103                         gv->video.page[0].sw=320;\r
104                         gv->video.page[0].sh=240;\r
105 \r
106                         /* send the CRTParms */\r
107                         for(i=0; i<CRTParmCount; i++) {\r
108                                 outpw(CRTC_INDEX, ModeX_320x240regs[i]);\r
109                         }\r
110 \r
111                         /* clear video memory */\r
112                         outpw(SC_INDEX, 0x0f02);\r
113                         for(i=0; i<0x8000; i++) {\r
114                                 ptr[i] = 0x0000;\r
115                         }\r
116                 break;\r
117                 case 2:\r
118                         CRTParmCount = sizeof(ModeX_160x120regs) / sizeof(ModeX_160x120regs[0]);\r
119                         /* width and height */\r
120                         gv->video.page[0].sw=120;\r
121                         gv->video.page[0].sh=160;\r
122 \r
123                         /* send the CRTParms */\r
124                         for(i=0; i<CRTParmCount; i++) {\r
125                                 outpw(CRTC_INDEX, ModeX_160x120regs[i]);\r
126                         }\r
127 \r
128                         /* clear video memory */\r
129                         outpw(SC_INDEX, 0x0f02);\r
130                         for(i=0; i<0x8000; i++) {\r
131                                 ptr[i] = 0x0000;\r
132                         }\r
133                 break;\r
134                 case 3:\r
135                         CRTParmCount = sizeof(ModeX_320x200regs) / sizeof(ModeX_320x200regs[0]);\r
136                         /* width and height */\r
137                         gv->video.page[0].sw=320;\r
138                         gv->video.page[0].sh=200;\r
139 \r
140                         /* send the CRTParms */\r
141                         for(i=0; i<CRTParmCount; i++) {\r
142                                 outpw(CRTC_INDEX, ModeX_320x200regs[i]);\r
143                         }\r
144 \r
145                         /* clear video memory */\r
146                         outpw(SC_INDEX, 0x0f02);\r
147                         for(i=0; i<0x8000; i++) {\r
148                                 ptr[i] = 0x0000;\r
149                         }\r
150                 break;\r
151                 case 4:\r
152                         CRTParmCount = sizeof(ModeX_192x144regs) / sizeof(ModeX_192x144regs[0]);\r
153                         /* width and height */\r
154                         gv->video.page[0].sw=192;\r
155                         gv->video.page[0].sh=144;\r
156 \r
157                         /* send the CRTParms */\r
158                         for(i=0; i<CRTParmCount; i++) {\r
159                                 outpw(CRTC_INDEX, ModeX_192x144regs[i]);\r
160                         }\r
161 \r
162                         /* clear video memory */\r
163                         outpw(SC_INDEX, 0x0f02);\r
164                         for(i=0; i<0x8000; i++) {\r
165                                 ptr[i] = 0x0000;\r
166                         }\r
167                 break;\r
168                 case 5:\r
169                         CRTParmCount = sizeof(ModeX_256x192regs) / sizeof(ModeX_256x192regs[0]);\r
170                         /* width and height */\r
171                         gv->video.page[0].sw=256;\r
172                         gv->video.page[0].sh=192;\r
173 \r
174                         /* send the CRTParms */\r
175                         for(i=0; i<CRTParmCount; i++) {\r
176                                 outpw(CRTC_INDEX, ModeX_256x192regs[i]);\r
177                         }\r
178 \r
179                         /* clear video memory */\r
180                         outpw(SC_INDEX, 0x0f02);\r
181                         for(i=0; i<0x8000; i++) {\r
182                                 ptr[i] = 0x0000;\r
183                         }\r
184                 break;\r
185         }\r
186         gv->video.page[0].tilesw = gv->video.page[0].sw/TILEWH;\r
187         gv->video.page[0].tilesh = gv->video.page[0].sh/TILEWH;\r
188         //TODO MAKE FLEXIBLE~\r
189         gv->video.page[0].tilemidposscreenx = gv->video.page[0].tilesw;\r
190         gv->video.page[0].tilemidposscreeny = (gv->video.page[0].tilesh/2)+1;\r
191         #define PAGE_SIZE               (word)(gv->video.page[0].sw/4 * gv->video.page[0].sh)\r
192 }\r
193 \r
194 void\r
195 modexLeave() {\r
196     /* TODO restore original mode and palette */\r
197     vgaSetMode(TEXT_MODE);\r
198 }\r
199 \r
200 //    setBaseXMode() does the initialization to make the VGA ready to\r
201 //    accept any combination of configuration register settings.  This\r
202 //    involves enabling writes to index 0 to 7 of the CRT controller (port\r
203 //    0x3D4), by clearing the most significant bit (bit 7) of index 0x11.\r
204 void\r
205 modexsetBaseXMode(page_t *page)\r
206 {\r
207         word temp;\r
208         /* TODO save current video mode and palette */\r
209         vgaSetMode(VGA_256_COLOR_MODE);\r
210 \r
211         /* disable chain4 mode */\r
212         outpw(SC_INDEX, 0x0604);\r
213 \r
214         /* synchronous reset while setting Misc Output */\r
215         outpw(SC_INDEX, 0x0100);\r
216 \r
217         /* select 25 MHz dot clock & 60 Hz scanning rate */\r
218         outp(MISC_OUTPUT, 0xe3);\r
219 \r
220         /* undo reset (restart sequencer) */\r
221         outpw(SC_INDEX, 0x0300);\r
222 \r
223         /* reprogram the CRT controller */\r
224         outp(CRTC_INDEX, 0x11); /* VSync End reg contains register write prot */\r
225 //      temp = inp(CRTC_DATA) & 0x7F;\r
226 //      outp(CRTC_INDEX, 0x11);\r
227         outp(CRTC_DATA, 0x7f);  /* get current write protect on varios regs */\r
228 //      outp(CRTC_DATA, temp);  /* get current write protect on varios regs */\r
229 }\r
230 \r
231 page_t\r
232 modexDefaultPage(page_t *p)\r
233 {\r
234     page_t page;\r
235 \r
236     /* default page values */\r
237     page.data = VGA;\r
238     page.dx = 0;\r
239     page.dy = 0;\r
240         page.sw = p->sw;\r
241         page.sh = p->sh;\r
242         page.width = p->sw;\r
243         page.height = p->sh;\r
244         page.tw = page.sw/TILEWH;\r
245         page.th = page.sh/TILEWH;\r
246         page.tilemidposscreenx = page.tw/2;\r
247         page.tilemidposscreeny = (page.th/2)+1;\r
248         page.tilesw=p->tilesw;\r
249         page.tilesh=p->tilesh;\r
250         //pageSize = p->sw*p->sh;\r
251         page.id = 0;\r
252 \r
253     return page;\r
254 }\r
255 \r
256 /* returns the next page in contiguous memory\r
257  * the next page will be the same size as p, by default\r
258  */\r
259 page_t\r
260 modexNextPage(page_t *p) {\r
261     page_t result;\r
262 \r
263     result.data = p->data + (p->width/4)*p->height;\r
264     result.dx = 0;\r
265     result.dy = 0;\r
266     result.width = p->width;\r
267     result.height = p->height;\r
268         result.tw = p->width/TILEWH;\r
269         result.th = p->height/TILEWH;\r
270         result.id = p->id+1;\r
271 \r
272         return result;\r
273 //      return modexNextPageFlexibleSize(&p, p->width, p->height);\r
274 }\r
275 \r
276 //next page with defined dimentions~\r
277 page_t\r
278 modexNextPageFlexibleSize(page_t *p, word x, word y)\r
279 {\r
280         page_t result;\r
281 \r
282         result.data = p->data + (p->width/4)*p->height;  /* compute the offset */\r
283         result.dx = 0;\r
284         result.dy = 0;\r
285         result.width = x;\r
286         result.height = y;\r
287         result.tw = p->width/TILEWH;\r
288         result.th = p->height/TILEWH;\r
289         result.id = p->id+1;\r
290 \r
291         return result;\r
292 }\r
293 \r
294 \r
295 void\r
296 modexShowPage(page_t *page) {\r
297     word high_address;\r
298     word low_address;\r
299     word offset;\r
300     byte crtcOffset;\r
301 \r
302     /* calculate offset */\r
303     offset = (word) page->data;\r
304     offset += page->dy * (page->width >> 2 );\r
305     offset += page->dx >> 2;\r
306 \r
307     /* calculate crtcOffset according to virtual width */\r
308     crtcOffset = page->width >> 3;\r
309 \r
310     high_address = HIGH_ADDRESS | (offset & 0xff00);\r
311     low_address  = LOW_ADDRESS  | (offset << 8);\r
312 \r
313     /* wait for appropriate timing and then program CRTC */\r
314     while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));\r
315     outpw(CRTC_INDEX, high_address);\r
316     outpw(CRTC_INDEX, low_address);\r
317     outp(CRTC_INDEX, 0x13);\r
318     outp(CRTC_DATA, crtcOffset);\r
319 \r
320     /*  wait for one retrace */\r
321     while (!(inp(INPUT_STATUS_1) & VRETRACE));\r
322 \r
323     /* do PEL panning here */\r
324     outp(AC_INDEX, 0x33);\r
325     outp(AC_INDEX, (page->dx & 0x03) << 1);\r
326 }\r
327 \r
328 \r
329 void\r
330 modexPanPage(page_t *page, int dx, int dy) {\r
331     page->dx = dx;\r
332     page->dy = dy;\r
333 }\r
334 \r
335 \r
336 void\r
337 modexSelectPlane(byte plane) {\r
338     outp(SC_INDEX, MAP_MASK);          /* select plane */\r
339     outp(SC_DATA,  plane);\r
340 }\r
341 \r
342 \r
343 void\r
344 modexClearRegion(page_t *page, int x, int y, int w, int h, byte  color) {\r
345     word pageOff = (word) page->data;\r
346     word xoff=x/4;       /* xoffset that begins each row */\r
347     word scanCount=w/4;  /* number of iterations per row (excluding right clip)*/\r
348     word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */\r
349     word nextRow = page->width/4-scanCount-1;  /* loc of next row */\r
350     byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08};  /* clips for rectangles not on 4s */\r
351     byte rclip[] = {0x00, 0x01, 0x03, 0x07};\r
352     byte left = lclip[x&0x03];\r
353     byte right = rclip[(x+w)&0x03];\r
354 \r
355     /* handle the case which requires an extra group */\r
356     if((x & 0x03) && !((x+w) & 0x03)) {\r
357       right=0x0f;\r
358     }\r
359 \r
360     __asm {\r
361                 MOV AX, SCREEN_SEG      ; go to the VGA memory\r
362                 MOV ES, AX\r
363                 MOV DI, poffset         ; go to the first pixel\r
364                 MOV DX, SC_INDEX        ; point to the map mask\r
365                 MOV AL, MAP_MASK\r
366                 OUT DX, AL\r
367                 INC DX\r
368                 MOV AL, color           ; get ready to write colors\r
369         SCAN_START:\r
370                 MOV CX, scanCount       ; count the line\r
371                 MOV BL, AL              ; remember color\r
372                 MOV AL, left            ; do the left clip\r
373                 OUT DX, AL              ; set the left clip\r
374                 MOV AL, BL              ; restore color\r
375                 STOSB                   ; write the color\r
376                 DEC CX\r
377                 JZ SCAN_DONE            ; handle 1 group stuff\r
378 \r
379                 ;-- write the main body of the scanline\r
380                 MOV BL, AL              ; remember color\r
381                 MOV AL, 0x0f            ; write to all pixels\r
382                 OUT DX, AL\r
383                 MOV AL, BL              ; restore color\r
384                 REP STOSB               ; write the color\r
385         SCAN_DONE:\r
386                 MOV BL, AL              ; remeber color\r
387                 MOV AL, right\r
388                 OUT DX, AL              ; do the right clip\r
389                 MOV AL, BL              ; restore color\r
390                 STOSB                   ; write pixel\r
391                 ADD DI, nextRow         ; go to the next row\r
392                 DEC h\r
393                 JNZ SCAN_START\r
394     }\r
395 }\r
396 \r
397 \r
398 void\r
399 oldDrawBmp(byte far* page, int x, int y, bitmap_t *bmp, byte sprite)\r
400 {\r
401         byte plane;\r
402         word px, py;\r
403         word offset;\r
404 \r
405         /* TODO Make this fast.  It's SLOOOOOOW */\r
406         for(plane=0; plane < 4; plane++) {\r
407                 modexSelectPlane(PLANE(plane+x));\r
408                 for(px = plane; px < bmp->width; px+=4) {\r
409                         offset=px;\r
410                         for(py=0; py<bmp->height; py++) {\r
411                         if(!sprite || bmp->data[offset])\r
412                                 page[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];\r
413                         offset+=bmp->width;\r
414                         }\r
415                 }\r
416         }\r
417 }\r
418 \r
419 void\r
420 CDrawBmp(byte far* vgamem, page_t* page, int x, int y, bitmap_t *bmp, byte sprite)\r
421 {\r
422         byte plane;\r
423         word px, py;\r
424         word offset=0;\r
425 \r
426 \r
427         /* TODO Make this fast.  It's SLOOOOOOW */\r
428         for(plane=0; plane < 4; plane++) {\r
429                 modexSelectPlane(PLANE(plane+x));\r
430                 for(px = plane; px < bmp->width; px+=4) {\r
431                         offset=px;\r
432                         for(py=0; py<bmp->height; py++) {\r
433                         if(!sprite || bmp->data[offset])\r
434                                 //modexputPixel(page, x+px, y+py, bmp->data[offset]);\r
435                                 vgamem[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];\r
436                         offset+=bmp->width;\r
437                         }\r
438                 }\r
439         }\r
440 }\r
441 \r
442 void\r
443 modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) {\r
444     /* draw the region (the entire freakin bitmap) */\r
445     modexDrawBmpRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);\r
446 }\r
447 \r
448 void\r
449 modexDrawBmpRegion(page_t *page, int x, int y,\r
450                    int rx, int ry, int rw, int rh, bitmap_t *bmp) {\r
451     word poffset = (word) page->data  + y*(page->width/4) + x/4;\r
452     byte far *data = bmp->data;//+bmp->offset;\r
453     word bmpOffset = (word) data + ry * bmp->width + rx;\r
454     word width = rw;\r
455     word height = rh;\r
456     byte plane = 1 << ((byte) x & 0x03);\r
457     word scanCount = width/4 + (width%4 ? 1 :0);\r
458     word nextPageRow = page->width/4 - scanCount;\r
459     word nextBmpRow = (word) bmp->width - width;\r
460     word rowCounter;\r
461     byte planeCounter = 4;\r
462 \r
463 /*      printf("bmp->data=%Fp\n",bmp->data);\r
464         printf("*bmp->data=%Fp\n",*(bmp->data));\r
465         printf("&bmp->data=%Fp\n",&(bmp->data));*/\r
466 \r
467         //code is a bit slow here\r
468     __asm {\r
469                 MOV AX, SCREEN_SEG      ; go to the VGA memory\r
470                 MOV ES, AX\r
471 \r
472                 MOV DX, SC_INDEX        ; point at the map mask register\r
473                 MOV AL, MAP_MASK        ;\r
474                 OUT DX, AL              ;\r
475 \r
476         PLANE_LOOP:\r
477                 MOV DX, SC_DATA         ; select the current plane\r
478                 MOV AL, plane           ;\r
479                 OUT DX, AL              ;\r
480 \r
481                 ;-- begin plane painting\r
482                 MOV AX, height          ; start the row counter\r
483                 MOV rowCounter, AX      ;\r
484                 MOV DI, poffset         ; go to the first pixel\r
485                 MOV SI, bmpOffset       ; go to the bmp pixel\r
486         ROW_LOOP:\r
487                 MOV CX, width           ; count the columns\r
488         SCAN_LOOP:\r
489                 MOVSB                   ; copy the pixel\r
490                 SUB CX, 3               ; we skip the next 3\r
491                 ADD SI, 3               ; skip the bmp pixels\r
492                 LOOP SCAN_LOOP          ; finish the scan\r
493 \r
494                 MOV AX, nextPageRow\r
495                 ADD DI, AX              ; go to the next row on screen\r
496                 MOV AX, nextBmpRow\r
497                 ADD SI, AX              ; go to the next row on bmp\r
498 \r
499                 DEC rowCounter\r
500                 JNZ ROW_LOOP            ; do all the rows\r
501                 ;-- end plane painting\r
502 \r
503                 MOV AL, plane           ; advance to the next plane\r
504                 SHL AL, 1               ;\r
505                 AND AL, 0x0f            ; mask the plane properly\r
506                 MOV plane, AL           ; store the plane\r
507 \r
508                 INC bmpOffset           ; start bmp at the right spot\r
509 \r
510                 DEC planeCounter\r
511                 JNZ PLANE_LOOP          ; do all 4 planes\r
512     }\r
513 }\r
514 \r
515 void\r
516 modexDrawPlanarBuf(page_t *page, int x, int y, planar_buf_t *bmp) {\r
517     /* TODO - adapt from test code */\r
518         int plane;\r
519         for(plane=0; plane < 4; plane++)\r
520         {\r
521                 //fack\r
522         }\r
523 }\r
524 \r
525 \r
526 void\r
527 modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp) {\r
528     /* draw the whole sprite */\r
529     modexDrawSpriteRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);\r
530 }\r
531 \r
532 /*void\r
533 modexDrawSpriteRegion(page_t *page, int x, int y,\r
534                       int rx, int ry, int rw, int rh, bitmap_t *bmp) {\r
535     word poffset = (word)page->data + y*(page->width/4) + x/4;\r
536     byte *data = bmp->data;//+bmp->offset;\r
537     word bmpOffset = (word) data + ry * bmp->width + rx;\r
538     word width = rw;\r
539     word height = rh;\r
540     byte plane = 1 << ((byte) x & 0x03);\r
541     word scanCount = width/4 + (width%4 ? 1 :0);\r
542     word nextPageRow = page->width/4 - scanCount;\r
543     word nextBmpRow = (word) bmp->width - width;\r
544     word rowCounter;\r
545     byte planeCounter = 4;\r
546 \r
547     __asm {\r
548                 MOV AX, SCREEN_SEG      ; go to the VGA memory\r
549                 MOV ES, AX\r
550 \r
551                 MOV DX, SC_INDEX        ; point at the map mask register\r
552                 MOV AL, MAP_MASK        ;\r
553                 OUT DX, AL              ;\r
554 \r
555         PLANE_LOOP:\r
556                 MOV DX, SC_DATA         ; select the current plane\r
557                 MOV AL, plane           ;\r
558                 OUT DX, AL              ;\r
559 \r
560                 ;-- begin plane painting\r
561                 MOV AX, height          ; start the row counter\r
562                 MOV rowCounter, AX      ;\r
563                 MOV DI, poffset         ; go to the first pixel\r
564                 MOV SI, bmpOffset       ; go to the bmp pixel\r
565         ROW_LOOP:\r
566                 MOV CX, width           ; count the columns\r
567         SCAN_LOOP:\r
568                 LODSB\r
569                 DEC SI\r
570                 CMP AL, 0\r
571                 JNE DRAW_PIXEL          ; draw non-zero pixels\r
572 \r
573                 INC DI                  ; skip the transparent pixel\r
574                 ADD SI, 1\r
575                 JMP NEXT_PIXEL\r
576         DRAW_PIXEL:\r
577                 MOVSB                   ; copy the pixel\r
578         NEXT_PIXEL:\r
579                 SUB CX, 3               ; we skip the next 3\r
580                 ADD SI, 3               ; skip the bmp pixels\r
581                 LOOP SCAN_LOOP          ; finish the scan\r
582 \r
583                 MOV AX, nextPageRow\r
584                 ADD DI, AX              ; go to the next row on screen\r
585                 MOV AX, nextBmpRow\r
586                 ADD SI, AX              ; go to the next row on bmp\r
587 \r
588                 DEC rowCounter\r
589                 JNZ ROW_LOOP            ; do all the rows\r
590                 ;-- end plane painting\r
591 \r
592                 MOV AL, plane           ; advance to the next plane\r
593                 SHL AL, 1               ;\r
594                 AND AL, 0x0f            ; mask the plane properly\r
595                 MOV plane, AL           ; store the plane\r
596 \r
597                 INC bmpOffset           ; start bmp at the right spot\r
598 \r
599                 DEC planeCounter\r
600                 JNZ PLANE_LOOP          ; do all 4 planes\r
601     }\r
602 }//backup!*/\r
603 \r
604 void\r
605 modexDrawSpriteRegion(page_t *page, int x, int y,\r
606                       int rx, int ry, int rw, int rh, bitmap_t *bmp) {\r
607     word poffset = (word)page->data + y*(page->width/4) + x/4;\r
608     byte huge *data = bmp->data;//+bmp->offset;\r
609     word bmpOffset = (word) data + ry * bmp->width + rx;\r
610     word width = rw;\r
611     word height = rh;\r
612     byte plane = 1 << ((byte) x & 0x03);\r
613     word scanCount = width/4 + (width%4 ? 1 :0);\r
614     word nextPageRow = page->width/4 - scanCount;\r
615     word nextBmpRow = (word) bmp->width - width;\r
616     word rowCounter;\r
617     byte planeCounter = 4;\r
618 \r
619     __asm {\r
620                 MOV AX, SCREEN_SEG      ; go to the VGA memory\r
621                 MOV ES, AX\r
622 \r
623                 MOV DX, SC_INDEX        ; point at the map mask register\r
624                 MOV AL, MAP_MASK        ;\r
625                 OUT DX, AL              ;\r
626 \r
627         PLANE_LOOP:\r
628                 MOV DX, SC_DATA         ; select the current plane\r
629                 MOV AL, plane           ;\r
630                 OUT DX, AL              ;\r
631 \r
632                 ;-- begin plane painting\r
633                 MOV AX, height          ; start the row counter\r
634                 MOV rowCounter, AX      ;\r
635                 MOV DI, poffset         ; go to the first pixel\r
636                 MOV SI, bmpOffset       ; go to the bmp pixel\r
637         ROW_LOOP:\r
638                 MOV CX, width           ; count the columns\r
639         SCAN_LOOP:\r
640                 LODSB\r
641                 DEC SI\r
642                 CMP AL, 0\r
643                 JNE DRAW_PIXEL          ; draw non-zero pixels\r
644 \r
645                 INC DI                  ; skip the transparent pixel\r
646                 ADD SI, 1\r
647                 JMP NEXT_PIXEL\r
648         DRAW_PIXEL:\r
649                 MOVSB                   ; copy the pixel\r
650         NEXT_PIXEL:\r
651                 SUB CX, 3               ; we skip the next 3\r
652                 ADD SI, 3               ; skip the bmp pixels\r
653                 LOOP SCAN_LOOP          ; finish the scan\r
654 \r
655                 MOV AX, nextPageRow\r
656                 ADD DI, AX              ; go to the next row on screen\r
657                 MOV AX, nextBmpRow\r
658                 ADD SI, AX              ; go to the next row on bmp\r
659 \r
660                 DEC rowCounter\r
661                 JNZ ROW_LOOP            ; do all the rows\r
662                 ;-- end plane painting\r
663 \r
664                 MOV AL, plane           ; advance to the next plane\r
665                 SHL AL, 1               ;\r
666                 AND AL, 0x0f            ; mask the plane properly\r
667                 MOV plane, AL           ; store the plane\r
668 \r
669                 INC bmpOffset           ; start bmp at the right spot\r
670 \r
671                 DEC planeCounter\r
672                 JNZ PLANE_LOOP          ; do all 4 planes\r
673     }\r
674 }\r
675 \r
676 /* copy a region of video memory from one page to another.\r
677  * It assumes that the left edge of the tile is the same on both\r
678  * regions and the memory areas do not overlap.\r
679  */\r
680 void\r
681 modexCopyPageRegion(page_t *dest, page_t *src,\r
682                     word sx, word sy,\r
683                     word dx, word dy,\r
684                     word width, word height)\r
685 {\r
686     word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;\r
687     word soffset = (word)src->data + sy*(src->width/4) + sx/4;\r
688     word scans   = width/4;\r
689     word nextSrcRow = src->width/4 - scans - 1;\r
690     word nextDestRow = dest->width/4 - scans - 1;\r
691     byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08};  /* clips for rectangles not on 4s */\r
692     byte rclip[] = {0x0f, 0x01, 0x03, 0x07};\r
693     byte left = lclip[sx&0x03];\r
694     byte right = rclip[(sx+width)&0x03];\r
695 \r
696     __asm {\r
697                 MOV AX, SCREEN_SEG      ; work in the vga space\r
698                 MOV ES, AX              ;\r
699                 MOV DI, doffset         ;\r
700                 MOV SI, soffset         ;\r
701 \r
702                 MOV DX, GC_INDEX        ; turn off cpu bits\r
703                 MOV AX, 0008h           ;\r
704                 OUT DX, AX\r
705 \r
706                 MOV AX, SC_INDEX        ; point to the mask register\r
707                 MOV DX, AX              ;\r
708                 MOV AL, MAP_MASK        ;\r
709                 OUT DX, AL              ;\r
710                 INC DX                  ;\r
711 \r
712         ROW_START:\r
713                 PUSH DS\r
714                 MOV AX, ES\r
715                 MOV DS, AX\r
716                 MOV CX, scans           ; the number of latches\r
717 \r
718                 MOV AL, left            ; do the left column\r
719                 OUT DX, AL              ;\r
720                 MOVSB                   ;\r
721                 DEC CX                  ;\r
722 \r
723                 MOV AL, 0fh             ; do the inner columns\r
724                 OUT DX, AL\r
725                 REP MOVSB               ; copy the pixels\r
726 \r
727                 MOV AL, right           ; do the right column\r
728                 OUT DX, AL\r
729                 MOVSB\r
730                 POP DS\r
731 \r
732                 MOV AX, SI              ; go the start of the next row\r
733                 ADD AX, nextSrcRow      ;\r
734                 MOV SI, AX              ;\r
735                 MOV AX, DI              ;\r
736                 ADD AX, nextDestRow     ;\r
737                 MOV DI, AX              ;\r
738 \r
739                 DEC height              ; do the rest of the actions\r
740                 JNZ ROW_START           ;\r
741 \r
742                 MOV DX, GC_INDEX+1      ; go back to CPU data\r
743                 MOV AL, 0ffh            ; none from latches\r
744                 OUT DX, AL              ;\r
745     }\r
746 }\r
747 \r
748 \r
749 /* fade and flash */\r
750 void\r
751 modexFadeOn(word fade, byte *palette) {\r
752     fadePalette(-fade, 64, 64/fade+1, palette);\r
753 }\r
754 \r
755 \r
756 void\r
757 modexFadeOff(word fade, byte *palette) {\r
758     fadePalette(fade, 0, 64/fade+1, palette);\r
759 }\r
760 \r
761 \r
762 void\r
763 modexFlashOn(word fade, byte *palette) {\r
764     fadePalette(fade, -64, 64/fade+1, palette);\r
765 }\r
766 \r
767 \r
768 void\r
769 modexFlashOff(word fade, byte *palette) {\r
770     fadePalette(-fade, 0, 64/fade+1, palette);\r
771 }\r
772 \r
773 \r
774 static void\r
775 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {\r
776     word i;\r
777     byte dim = start;\r
778 \r
779     /* handle the case where we just update */\r
780     if(iter == 0) {\r
781         modexPalUpdate1(palette);\r
782         return;\r
783     }\r
784 \r
785     while(iter > 0) {  /* FadeLoop */\r
786         for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */\r
787             tmppal[i] = palette[i] - dim;\r
788             if(tmppal[i] > 127) {\r
789                 tmppal[i] = 0;\r
790             } else if(tmppal[i] > 63) {\r
791                 tmppal[i] = 63;\r
792             }\r
793         }\r
794         modexPalUpdate1(tmppal);\r
795         iter--;\r
796         dim += fade;\r
797     }\r
798 }\r
799 \r
800 \r
801 /* save and load */\r
802 void\r
803 modexPalSave(byte *palette) {\r
804     int  i;\r
805 \r
806     outp(PAL_READ_REG, 0);      /* start at palette entry 0 */\r
807     for(i=0; i<PAL_SIZE; i++) {\r
808         palette[i] = inp(PAL_DATA_REG); /* read the palette data */\r
809     }\r
810 }\r
811 \r
812 \r
813 byte *\r
814 modexNewPal() {\r
815     byte *ptr;\r
816     ptr = malloc(PAL_SIZE);\r
817 \r
818     /* handle errors */\r
819     if(!ptr) {\r
820         printf("Could not allocate palette.\n");\r
821         exit(-1);\r
822     }\r
823 \r
824     return ptr;\r
825 }\r
826 \r
827 \r
828 void\r
829 modexLoadPalFile(byte *filename, byte **palette) {\r
830     FILE *file;\r
831     byte *ptr;\r
832 \r
833     /* free the palette if it exists */\r
834     if(*palette) {\r
835         free(*palette);\r
836     }\r
837 \r
838     /* allocate the new palette */\r
839     *palette = modexNewPal();\r
840 \r
841     /* open the file */\r
842     file = fopen(filename, "rb");\r
843     if(!file) {\r
844         printf("Could not open palette file: %s\n", filename);\r
845         exit(-2);\r
846     }\r
847 \r
848     /* read the file */\r
849     ptr = *palette;\r
850     while(!feof(file)) {\r
851         *ptr++ = fgetc(file);\r
852     }\r
853 \r
854     fclose(file);\r
855 }\r
856 \r
857 \r
858 void\r
859 modexSavePalFile(char *filename, byte *pal) {\r
860     unsigned int i;\r
861     FILE *file;\r
862 \r
863     /* open the file for writing */\r
864     file = fopen(filename, "wb");\r
865     if(!file) {\r
866         printf("Could not open %s for writing\n", filename);\r
867         exit(-2);\r
868     }\r
869 \r
870     /* write the data to the file */\r
871     fwrite(pal, 1, PAL_SIZE, file);\r
872     fclose(file);\r
873 }\r
874 \r
875 \r
876 /* blanking */\r
877 void\r
878 modexPalBlack() {\r
879     fadePalette(-1, 64, 1, tmppal);\r
880 }\r
881 \r
882 \r
883 void\r
884 modexPalWhite() {\r
885     fadePalette(-1, -64, 1, tmppal);\r
886 }\r
887 \r
888 \r
889 /* utility */\r
890 void\r
891 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)\r
892 {\r
893         byte *p = bmp->palette;\r
894         word w=0;\r
895         word q=0;\r
896         word qq=0;\r
897         static word a[PAL_SIZE];        //palette array of change values!\r
898         word z=0, aq=0, aa=0, pp=0;\r
899 \r
900         modexWaitBorder();\r
901         if((*i)==0)\r
902         {\r
903                 memset(a, -1, sizeof(a));\r
904                 outp(PAL_WRITE_REG, 0);  /* start at the beginning of palette */\r
905         }\r
906         else if(qp==0)\r
907         {\r
908                 q=(*i);\r
909         }\r
910         else\r
911         {\r
912                 q=(*i);\r
913                 qq=(*i)/3;\r
914 //              printf("q: %02d\n", (q));\r
915 //              printf("qq: %02d\n", (qq));\r
916                 //printf("      (*i)-q=%02d\n", (*i)-q);\r
917                 outp(PAL_WRITE_REG, qq);  /* start at the beginning of palette */\r
918         }\r
919         if((*i)<PAL_SIZE/2 && w==0)\r
920         {\r
921                 for(; (*i)<PAL_SIZE/2; (*i)++)\r
922                 {\r
923                         //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
924 //____                  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
925                         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
926                         {\r
927                                 w++;\r
928                                 break;\r
929                         }\r
930                         else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))\r
931                         {\r
932                                 //printf("qp=%d\n", qp);\r
933                                 //printf("              (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);\r
934                                 printf("                %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);\r
935                                 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!\r
936                                 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }\r
937                         }\r
938                         else\r
939                         {\r
940                                 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);\r
941                                 else\r
942                                 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);\r
943                                 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);\r
944                                 printf("p[]=%d  qp=%d   p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }\r
945                         }\r
946                 }\r
947                 //if(qp>0) printf("qp=%d\n", qp);\r
948                 //if(qp>0) printf("                                             (*i)=%d\n", (*i)/3);\r
949         }\r
950         modexWaitBorder();          /* waits one retrace -- less flicker */\r
951         if((*i)>=PAL_SIZE/2 && w==0)\r
952         {\r
953                 for(; (*i)<PAL_SIZE; (*i)++)\r
954                 {\r
955 //____                  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
956                         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
957                         {\r
958                                 w++;\r
959                                 break;\r
960                         }\r
961                         else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))\r
962                         {\r
963                                 //printf("qp=%d\n", qp);\r
964                                 //printf("              (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);\r
965                                 printf("                %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));\r
966                                 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!\r
967                                 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }\r
968                         }\r
969                         else\r
970                         {\r
971                                 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);\r
972                                 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);\r
973                                 printf("p[]=%d  qp=%d   p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }\r
974                         }\r
975                 }\r
976                 //printf("                                              (*i)=%d\n", (*i)/3);\r
977         }\r
978 \r
979 printf("\nqqqqqqqq\n\n");\r
980 \r
981         //palette checker~\r
982         if(q>0 && qp==0)\r
983         {\r
984                 long lq;\r
985                 long bufSize = (bmp->width * bmp->height);\r
986                 pp = q;\r
987                 //printf("1(*i)=%02d\n", (*i)/3);\r
988                 //printf("1z=%02d\n", z/3);\r
989                 chkcolor(bmp, &q, &a, &aa, &z, i);\r
990                 //printf("2(*i)=%02d\n", (*i)/3);\r
991                 //printf("2z=%02d\n", z/3);\r
992                 aq=0;\r
993 aqpee:\r
994                 while(aq<=aa)\r
995                 {\r
996 //                      printf("a[%02d]=(%d)\n", aq, a[aq]);\r
997                         if(a[aq]==-1) aq++;\r
998                         else { aqoffset++; break; }\r
999                 }\r
1000 //update the image data here!\r
1001         for(lq=0; lq<bufSize; lq++)\r
1002         {\r
1003                                 /*\r
1004                                                                         note to self\r
1005                                                                         use a[qp] instead of bmp->offset for this spot!\r
1006                                                                         NO! wwww\r
1007                                 */\r
1008 \r
1009                                 /*\r
1010                                 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww\r
1011                                 */\r
1012 \r
1013                 //(offset/bmp->offset)*bmp->offset\r
1014 \r
1015 \r
1016                 //printf("%02d ",bmp->data[lq]+bmp->offset);\r
1017                 //if(lq > 0 && lq%bmp->width==0) printf("\n");\r
1018                 //printf("%02d_", bmp->data[lq]+bmp->offset);\r
1019                 /*if(bmp->data[lq]+bmp->offset==aq)\r
1020                 {\r
1021                         //printf("%02d", bmp->data[lq]);\r
1022                         //printf("\n%02d\n", bmp->offset);\r
1023                         printf("aq=%02d ", aq);\r
1024                         printf("a[aq]=%02d      ", a[aq]);\r
1025                         printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);\r
1026                         printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);\r
1027                         //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);\r
1028 //++++                  bmp->data[lq]=a[aq]-aqpp;\r
1029 //                      printf("_%d ", bmp->data[lq]);\r
1030                         //if(lq > 0 && lq%bmp->width==0) printf("\n");\r
1031                 }\r
1032                 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)\r
1033                 {\r
1034                         if(bmp->data[lq]+bmp->offset >= aq)\r
1035                         {\r
1036                                 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);\r
1037                                 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);\r
1038                         }\r
1039                         else bmp->data[lq]+=(bmp->offset-aqpp);\r
1040                 }*/\r
1041 \r
1042                 //printf("%02d`", bmp->data[lq]);\r
1043                 //if(lq > 0 && lq%bmp->width==0) printf("\n");\r
1044         }\r
1045 \r
1046 //printf("              aq=%02d\n", aq);\r
1047 //printf("              aa=%02d\n", aa);\r
1048 \r
1049         //update the palette~\r
1050         modexPalUpdate(bmp, &pp, aq, aqoffset);\r
1051         (*i)=pp;\r
1052 \r
1053         if(aq<aa){ pp=q; aq++; goto aqpee; }\r
1054         }\r
1055 }\r
1056 \r
1057 void\r
1058 modexPalUpdate1(byte *p)\r
1059 {\r
1060         int i;\r
1061         modexWaitBorder();\r
1062         outp(PAL_WRITE_REG, 0);  /* start at the beginning of palette */\r
1063         for(i=0; i<PAL_SIZE/2; i++)\r
1064         {\r
1065                 outp(PAL_DATA_REG, p[i]);\r
1066         }\r
1067         modexWaitBorder();          /* waits one retrace -- less flicker */\r
1068         for(; i<PAL_SIZE; i++)\r
1069         {\r
1070                 outp(PAL_DATA_REG, p[(i)]);\r
1071         }\r
1072 }\r
1073 \r
1074 void\r
1075 modexPalUpdate0(byte *p)\r
1076 {\r
1077         int i;\r
1078         modexWaitBorder();\r
1079         outp(PAL_WRITE_REG, 0);  /* start at the beginning of palette */\r
1080         for(i=0; i<PAL_SIZE/2; i++)\r
1081         {\r
1082                 outp(PAL_DATA_REG, rand());\r
1083         }\r
1084         modexWaitBorder();          /* waits one retrace -- less flicker */\r
1085         for(; i<PAL_SIZE; i++)\r
1086         {\r
1087                 outp(PAL_DATA_REG, rand());\r
1088         }\r
1089 }\r
1090 \r
1091 void\r
1092 modexPalOverscan(byte *p, word col)\r
1093 {\r
1094         modexWaitBorder();\r
1095         outp(PAL_WRITE_REG, 0);  /* start at the beginning of palette */\r
1096         outp(PAL_DATA_REG, col);\r
1097 }\r
1098 \r
1099 //color checker~\r
1100 //i want to make another vesion that checks the palette when the palette is being appened~\r
1101 void chkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)\r
1102 {\r
1103                 byte *pal;\r
1104                 word zz=0;\r
1105                 pal = modexNewPal();\r
1106                 modexPalSave(pal);\r
1107                 //printf("q: %02d\n", (*q));\r
1108                 printf("chkcolor start~\n");\r
1109                 printf("1                               (*z): %d\n", (*z)/3);\r
1110                 printf("1                               (*i): %d\n", (*i)/3);\r
1111 //              printf("1 offset of color in palette    (*q): %d\n", (*q)/3);\r
1112                 printf("wwwwwwwwwwwwwwww\n");\r
1113                 //check palette for dups\r
1114                 for(; (*z)<PAL_SIZE; (*z)+=3)\r
1115                 {\r
1116                         //printf("\n            z: %d\n", (*z));\r
1117                         //printf("              q: %d\n", (*q));\r
1118                         //printf("              z+q: %d\n\n", ((*z)+(*q)));\r
1119                         //if((*z)%3==0)\r
1120                         //{\r
1121 //----                          if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])\r
1122                                 if((*z)==(*i))\r
1123                                 {\r
1124 //                                      printf("\n%d    [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);\r
1125 //                                      printf("%d      [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);\r
1126 //0000                                  (*z)-=3;\r
1127                                         break;\r
1128                                 }\r
1129                                 else for(zz=0; zz<(*q); zz+=3)\r
1130                                 {\r
1131                                         //printf("zz: %02d\n", zz/3);\r
1132                                         if(zz%3==0)\r
1133                                         {\r
1134                                                 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
1135                                                 {\r
1136 //                                                      (*z)-=3;\r
1137 //                                                      (*i)-=3;\r
1138 //                                                      printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);\r
1139 //                                                      printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);\r
1140                                                         break;\r
1141                                                 }\r
1142                                                 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])\r
1143                                                 {\r
1144 //                                                      printf("\n\nwwwwwwwwwwwwwwww\n");\r
1145 //                                                      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
1146 //                                                      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
1147 //                                                      //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
1148 //                                                      printf("        z : %d  [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);\r
1149 //++++                                                  (*i)--;\r
1150 //                                                      (*z)--;\r
1151                                                         //expand dong here\r
1152 /*\r
1153 planned features that i plan to implement~\r
1154 image that has values on the pallete list!\r
1155 wwww\r
1156 no... wait.... no wwww\r
1157 */\r
1158                                                         //for(zzii=0; zzii<3; zzii++)\r
1159                                                         //{\r
1160                                                                 //printf("z+q: %d\n\n", ((*z)+(*q)));\r
1161                                                                 a[(((*z)+(*q)))]=zz;\r
1162                                                         //}\r
1163                                                         (*aa)=(((*z)+(*q)));\r
1164                                                         printf("!!                                      a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);\r
1165 //                                                      printf("\n              aa: %d\n\n", (*aa));\r
1166 //                                                      printf("        a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);\r
1167 //                                                      printf("wwwwwwwwwwwwwwww\n\n");\r
1168                                                 }\r
1169                                                 /*else\r
1170                                                 {\r
1171                                                         printf("================\n");\r
1172                                                         printf("zq: %d  [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);\r
1173                                                         printf("zz: %d  [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);\r
1174                                                         printf("z : %d  [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);\r
1175                                                         printf("================\n");\r
1176                                                 }*/\r
1177                                                 //printf("[%d]", (zz+q));\r
1178                                         }\r
1179                                 }\r
1180                 }\r
1181                 printf("wwwwwwwwwwwwwwww\n");\r
1182                 printf("2                               (*z): %d\n", (*z)/3);\r
1183                 printf("2                               (*i): %d\n", (*i)/3);\r
1184 //              printf("2 offset of color in palette    (*q): %d\n", (*q)/3);\r
1185                 printf("chkcolor end~\n");\r
1186                 free(pal);\r
1187 }\r
1188 \r
1189 void modexputPixel(page_t *page, int x, int y, byte color)\r
1190 {\r
1191         word pageOff = (word) page->data;\r
1192         /* Each address accesses four neighboring pixels, so set\r
1193            Write Plane Enable according to which pixel we want\r
1194            to modify.  The plane is determined by the two least\r
1195            significant bits of the x-coordinate: */\r
1196         modexSelectPlane(PLANE(x));\r
1197         //outp(SC_INDEX, 0x02);\r
1198         //outp(SC_DATA, 0x01 << (x & 3));\r
1199 \r
1200         /* The offset of the pixel into the video segment is\r
1201            offset = (width * y + x) / 4, and write the given\r
1202            color to the plane we selected above.  Heed the active\r
1203            page start selection. */\r
1204         VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;\r
1205 \r
1206 }\r
1207 \r
1208 byte modexgetPixel(page_t *page, int x, int y)\r
1209 {\r
1210         word pageOff = (word) page->data;\r
1211         /* Select the plane from which we must read the pixel color: */\r
1212         outpw(GC_INDEX, 0x04);\r
1213         outpw(GC_INDEX+1, x & 3);\r
1214 \r
1215         return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];\r
1216 \r
1217 }\r
1218 \r
1219 void modexhlin(page_t *page, word xl, word xh, word y, word color)\r
1220 {\r
1221         word x;\r
1222         word yy=0;\r
1223 \r
1224         for(x=0;x<xh*4;x+=4)\r
1225         {\r
1226                 if(x+4>=page[0].sw-1){ x=0; yy+=4; }\r
1227                 modexClearRegion(page, x+xl, y+yy, 4, 4, color);\r
1228         }\r
1229         //modexputPixel(page, x+xl, y, color);\r
1230 }\r
1231 \r
1232 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)\r
1233 {\r
1234         word i, s, o, w, j, xp;\r
1235         byte l[1024];\r
1236         word addr = (word) l;\r
1237         word chw=0;\r
1238         byte c;\r
1239 \r
1240         switch(t)\r
1241         {\r
1242                 case 0:\r
1243                         w=14;\r
1244                 break;\r
1245                 case 1:\r
1246                         w=8;\r
1247                 break;\r
1248                 case 2:\r
1249                         w=8;\r
1250                 break;\r
1251                 case 3:\r
1252                         w=16;\r
1253                 break;\r
1254                 default:\r
1255                         t=3;\r
1256                         w=16;\r
1257                 break;\r
1258         }\r
1259 \r
1260         s=romFonts[t].seg;\r
1261         o=romFonts[t].off;\r
1262 \r
1263         for(; *str != '\0'; str++)\r
1264         {\r
1265         c = (*str);\r
1266         if((c=='\n'/* || c=="\\r
1267 "*/) || chw\r
1268 >=page->width)\r
1269         {\r
1270                 chw=0;\r
1271                 y+=w;\r
1272                 continue;\r
1273         }\r
1274         //load the letter 'A'\r
1275         __asm {\r
1276                 MOV DI, addr\r
1277                 MOV SI, o\r
1278                 MOV ES, s\r
1279                 SUB AH, AH\r
1280                 MOV AL, c       ; the letter\r
1281                 MOV CX, w\r
1282                 MUL CX\r
1283                 ADD SI, AX      ;the address of charcter\r
1284         L1:     MOV AX, ES:SI\r
1285                 MOV DS:DI, AX\r
1286                 INC SI\r
1287                 INC DI\r
1288                 DEC CX\r
1289                 JNZ L1\r
1290         }\r
1291 \r
1292                 for(i=0; i<w; i++)\r
1293                 {\r
1294                         j=1<<8;\r
1295                         xp=0;\r
1296                         while(j)\r
1297                         {\r
1298                                 modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);\r
1299                                 xp++;\r
1300                                 j>>=1;\r
1301                         }\r
1302                 }\r
1303                 chw += xp;\r
1304         }\r
1305 }\r
1306 \r
1307 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)\r
1308 {\r
1309         word i, s, o, w, j, xp;\r
1310         byte l[1024];\r
1311         word addr = (word) l;\r
1312         word chw=0;\r
1313         byte c;\r
1314 \r
1315         switch(t)\r
1316         {\r
1317                 case 0:\r
1318                         w=14;\r
1319                 break;\r
1320                 case 1:\r
1321                         w=8;\r
1322                 break;\r
1323                 case 2:\r
1324                         w=8;\r
1325                 break;\r
1326                 case 3:\r
1327                         w=16;\r
1328                 break;\r
1329                 default:\r
1330                         t=3;\r
1331                         w=16;\r
1332                 break;\r
1333         }\r
1334 \r
1335         s=romFonts[t].seg;\r
1336         o=romFonts[t].off;\r
1337 \r
1338         for(; *str != '\0'; str++)\r
1339         {\r
1340         c = (*str);\r
1341         if((c=='\n'/* || c=="\\r
1342 "*/)/* || chw>=page->width*/)\r
1343         {\r
1344                 chw=0;\r
1345                 y+=w;\r
1346                 continue;\r
1347         }\r
1348         //load the letter 'A'\r
1349         __asm {\r
1350                 MOV DI, addr\r
1351                 MOV SI, o\r
1352                 MOV ES, s\r
1353                 SUB AH, AH\r
1354                 MOV AL, c       ; the letter\r
1355                 MOV CX, w\r
1356                 MUL CX\r
1357                 ADD SI, AX      ;the address of charcter\r
1358         L1:     MOV AX, ES:SI\r
1359                 MOV DS:DI, AX\r
1360                 INC SI\r
1361                 INC DI\r
1362                 DEC CX\r
1363                 JNZ L1\r
1364         }\r
1365 \r
1366                 for(i=0; i<w; i++)\r
1367                 {\r
1368                         j=1<<8;\r
1369                         xp=0;\r
1370                         while(j)\r
1371                         {\r
1372                                 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);\r
1373                                 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);\r
1374                                 xp++;\r
1375                                 j>>=1;\r
1376                         }\r
1377                 }\r
1378                 chw += xp;\r
1379         }\r
1380 }\r
1381 \r
1382 /* palette dump on display! */\r
1383 void pdump(page_t *pee)\r
1384 {\r
1385         int mult=(QUADWH);\r
1386         int palq=(mult)*TILEWH;\r
1387         int palcol=0;\r
1388         int palx, paly;\r
1389         for(paly=0; paly<palq; paly+=mult){\r
1390                 for(palx=0; palx<palq; palx+=mult){\r
1391                                 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);\r
1392                         palcol++;\r
1393                 }\r
1394         }\r
1395 }\r
1396 \r
1397 /////////////////////////////////////////////////////////////////////////////\r
1398 //                                                                                                                                               //\r
1399 // cls() - This clears the screen to the specified color, on the VGA or on //\r
1400 //               the Virtual screen.                                                                                     //\r
1401 //                                                                                                                                               //\r
1402 /////////////////////////////////////////////////////////////////////////////\r
1403 void cls(page_t *page, byte color, byte *Where)\r
1404 {\r
1405         //modexClearRegion(page, 0, 0, page->width, page->height, color);\r
1406         /* set map mask to all 4 planes */\r
1407         outpw(SC_INDEX, 0xff02);\r
1408         //_fmemset(VGA, color, 16000);\r
1409         _fmemset(Where, color, page->width*(page->height));\r
1410 }\r
1411 \r
1412 void\r
1413 modexWaitBorder() {\r
1414     while(inp(INPUT_STATUS_1)  & 8)  {\r
1415         /* spin */\r
1416     }\r
1417 \r
1418     while(!(inp(INPUT_STATUS_1)  & 8))  {\r
1419         /* spin */\r
1420     }\r
1421 }\r