]> 4ch.mooo.com Git - 16.git/blob - src/lib/modex16.c
going to work on this soon
[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 //TODO! ADD CLIPPING!!\r
398 //void\r
399 //modexDrawBmpRegion    (page_t *page, int x, int y, int rx, int ry, int rw, int rh, bitmap_t *bmp)\r
400 void modexDrawPBufRegion        (page_t *page, int x, int y, int rx, int ry, int rw, int rh, planar_buf_t *p, boolean sprite)\r
401 {\r
402         int plane;\r
403         int px, py, i;\r
404 //      byte near *buff;\r
405         px=x;\r
406         py=y;\r
407 //      buff = _nmalloc(p->pwidth+1);\r
408         // TODO Make this fast.  It's SLOOOOOOW\r
409 //      for(plane=0; plane < 4; plane++) {\r
410 //              i=0;\r
411 //              modexSelectPlane(PLANE(plane+x));\r
412 //              for(px = plane; px < p->width; px+=4) {\r
413 //                      offset=px;\r
414 //                      for(py=0; py<p->height/2; py++) {\r
415 //                              //SELECT_ALL_PLANES();\r
416 //                              if(!sprite || p->plane[offset])\r
417 //                                      page->data = &(p->plane[offset][i++]);\r
418 //                              offset+=p->width;\r
419 //                              offset++;\r
420 //                      }\r
421 //              }\r
422 //      }\r
423         for(plane=0; plane < 4; plane++) {\r
424                 i=(rx/4)+((rx/4)*ry);\r
425                 modexSelectPlane(PLANE(plane+x));\r
426                 for(; y < py+p->height; y++) {\r
427                         //for(px=0; px < p->width; px++) {\r
428                                 //printf("%02X ", (int) p->plane[plane][i++]);\r
429 //                              _fmemcpy(buff, &(p->plane[plane][i+=p->pwidth]), p->pwidth);\r
430 //                              printf("buff %u==%s\n", y, *buff);\r
431 //                              _fmemcpy(page->data + (((page->width/4) * (y+page->dy)) + ((x+page->dx) / 4)), buff, p->pwidth);\r
432                                 _fmemcpy(page->data + (((page->width/4) * (y+page->dy)) + ((x+page->dx) / 4)), &(p->plane[plane][i+=p->pwidth]), p->pwidth);\r
433                         //}\r
434                 }\r
435                 x=px;\r
436                 y=py;\r
437         }\r
438 //      _nfree(buff);\r
439 }\r
440 \r
441 /*void\r
442 DrawPBuf(page_t *page, int x, int y, planar_buf_t *p, boolean sprite)\r
443 {\r
444         int plane;\r
445         int px, py, i;\r
446 //      byte near *buff;\r
447         px=x;\r
448         py=y;\r
449 //      buff = _nmalloc(p->pwidth+1);\r
450         // TODO Make this fast.  It's SLOOOOOOW\r
451 //      for(plane=0; plane < 4; plane++) {\r
452 //              i=0;\r
453 //              modexSelectPlane(PLANE(plane+x));\r
454 //              for(px = plane; px < p->width; px+=4) {\r
455 //                      offset=px;\r
456 //                      for(py=0; py<p->height/2; py++) {\r
457 //                              //SELECT_ALL_PLANES();\r
458 //                              if(!sprite || p->plane[offset])\r
459 //                                      page->data = &(p->plane[offset][i++]);\r
460 //                              offset+=p->width;\r
461 //                              offset++;\r
462 //                      }\r
463 //              }\r
464 //      }\r
465         for(plane=0; plane < 4; plane++) {\r
466                 i=0;\r
467                 modexSelectPlane(PLANE(plane+x));\r
468                 for(; y < py+p->height; y++) {\r
469                         //for(px=0; px < p->width; px++) {\r
470                                 //printf("%02X ", (int) p->plane[plane][i++]);\r
471 //                              _fmemcpy(buff, &(p->plane[plane][i+=p->pwidth]), p->pwidth);\r
472 //                              printf("buff %u==%s\n", y, *buff);\r
473 //                              _fmemcpy(page->data + (((page->width/4) * (y+page->dy)) + ((x+page->dx) / 4)), buff, p->pwidth);\r
474                                 _fmemcpy(page->data + (((page->width/4) * (y+page->dy)) + ((x+page->dx) / 4)), &(p->plane[plane][i+=p->pwidth]), p->pwidth);\r
475                         //}\r
476                 }\r
477                 x=px;\r
478                 y=py;\r
479         }\r
480 //      _nfree(buff);\r
481 }*/\r
482 \r
483 void\r
484 oldDrawBmp(byte far* page, int x, int y, bitmap_t *bmp, byte sprite)\r
485 {\r
486         byte plane;\r
487         word px, py;\r
488         word offset;\r
489 \r
490         /* TODO Make this fast.  It's SLOOOOOOW */\r
491         for(plane=0; plane < 4; plane++) {\r
492                 modexSelectPlane(PLANE(plane+x));\r
493                 for(px = plane; px < bmp->width; px+=4) {\r
494                         offset=px;\r
495                         for(py=0; py<bmp->height; py++) {\r
496                         if(!sprite || bmp->data[offset])\r
497                                 page[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];\r
498                         offset+=bmp->width;\r
499                         }\r
500                 }\r
501         }\r
502 }\r
503 \r
504 void\r
505 modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) {\r
506     /* draw the region (the entire freakin bitmap) */\r
507     modexDrawBmpRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);\r
508 }\r
509 \r
510 void\r
511 modexDrawBmpRegion(page_t *page, int x, int y,\r
512                    int rx, int ry, int rw, int rh, bitmap_t *bmp) {\r
513     word poffset = (word) page->data  + y*(page->width/4) + x/4;\r
514     byte far *data = bmp->data;//+bmp->offset;\r
515     word bmpOffset = (word) data + ry * bmp->width + rx;\r
516     word width = rw;\r
517     word height = rh;\r
518     byte plane = 1 << ((byte) x & 0x03);\r
519     word scanCount = width/4 + (width%4 ? 1 :0);\r
520     word nextPageRow = page->width/4 - scanCount;\r
521     word nextBmpRow = (word) bmp->width - width;\r
522     word rowCounter;\r
523     byte planeCounter = 4;\r
524 \r
525 /*      printf("bmp->data=%Fp\n",bmp->data);\r
526         printf("*bmp->data=%Fp\n",*(bmp->data));\r
527         printf("&bmp->data=%Fp\n",&(bmp->data));*/\r
528 \r
529         //code is a bit slow here\r
530     __asm {\r
531                 MOV AX, SCREEN_SEG      ; go to the VGA memory\r
532                 MOV ES, AX\r
533 \r
534                 MOV DX, SC_INDEX        ; point at the map mask register\r
535                 MOV AL, MAP_MASK        ;\r
536                 OUT DX, AL              ;\r
537 \r
538         PLANE_LOOP:\r
539                 MOV DX, SC_DATA         ; select the current plane\r
540                 MOV AL, plane           ;\r
541                 OUT DX, AL              ;\r
542 \r
543                 ;-- begin plane painting\r
544                 MOV AX, height          ; start the row counter\r
545                 MOV rowCounter, AX      ;\r
546                 MOV DI, poffset         ; go to the first pixel\r
547                 MOV SI, bmpOffset       ; go to the bmp pixel\r
548         ROW_LOOP:\r
549                 MOV CX, width           ; count the columns\r
550         SCAN_LOOP:\r
551                 MOVSB                   ; copy the pixel\r
552                 SUB CX, 3               ; we skip the next 3\r
553                 ADD SI, 3               ; skip the bmp pixels\r
554                 LOOP SCAN_LOOP          ; finish the scan\r
555 \r
556                 MOV AX, nextPageRow\r
557                 ADD DI, AX              ; go to the next row on screen\r
558                 MOV AX, nextBmpRow\r
559                 ADD SI, AX              ; go to the next row on bmp\r
560 \r
561                 DEC rowCounter\r
562                 JNZ ROW_LOOP            ; do all the rows\r
563                 ;-- end plane painting\r
564 \r
565                 MOV AL, plane           ; advance to the next plane\r
566                 SHL AL, 1               ;\r
567                 AND AL, 0x0f            ; mask the plane properly\r
568                 MOV plane, AL           ; store the plane\r
569 \r
570                 INC bmpOffset           ; start bmp at the right spot\r
571 \r
572                 DEC planeCounter\r
573                 JNZ PLANE_LOOP          ; do all 4 planes\r
574     }\r
575 }\r
576 \r
577 void\r
578 modexDrawPlanarBuf(page_t *page, int x, int y, planar_buf_t *bmp) {\r
579     /* TODO - adapt from test code */\r
580         int plane;\r
581         for(plane=0; plane < 4; plane++)\r
582         {\r
583                 //fack\r
584         }\r
585 }\r
586 \r
587 \r
588 void\r
589 modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp) {\r
590     /* draw the whole sprite */\r
591     modexDrawSpriteRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);\r
592 }\r
593 \r
594 /*void\r
595 modexDrawSpriteRegion(page_t *page, int x, int y,\r
596                       int rx, int ry, int rw, int rh, bitmap_t *bmp) {\r
597     word poffset = (word)page->data + y*(page->width/4) + x/4;\r
598     byte *data = bmp->data;//+bmp->offset;\r
599     word bmpOffset = (word) data + ry * bmp->width + rx;\r
600     word width = rw;\r
601     word height = rh;\r
602     byte plane = 1 << ((byte) x & 0x03);\r
603     word scanCount = width/4 + (width%4 ? 1 :0);\r
604     word nextPageRow = page->width/4 - scanCount;\r
605     word nextBmpRow = (word) bmp->width - width;\r
606     word rowCounter;\r
607     byte planeCounter = 4;\r
608 \r
609     __asm {\r
610                 MOV AX, SCREEN_SEG      ; go to the VGA memory\r
611                 MOV ES, AX\r
612 \r
613                 MOV DX, SC_INDEX        ; point at the map mask register\r
614                 MOV AL, MAP_MASK        ;\r
615                 OUT DX, AL              ;\r
616 \r
617         PLANE_LOOP:\r
618                 MOV DX, SC_DATA         ; select the current plane\r
619                 MOV AL, plane           ;\r
620                 OUT DX, AL              ;\r
621 \r
622                 ;-- begin plane painting\r
623                 MOV AX, height          ; start the row counter\r
624                 MOV rowCounter, AX      ;\r
625                 MOV DI, poffset         ; go to the first pixel\r
626                 MOV SI, bmpOffset       ; go to the bmp pixel\r
627         ROW_LOOP:\r
628                 MOV CX, width           ; count the columns\r
629         SCAN_LOOP:\r
630                 LODSB\r
631                 DEC SI\r
632                 CMP AL, 0\r
633                 JNE DRAW_PIXEL          ; draw non-zero pixels\r
634 \r
635                 INC DI                  ; skip the transparent pixel\r
636                 ADD SI, 1\r
637                 JMP NEXT_PIXEL\r
638         DRAW_PIXEL:\r
639                 MOVSB                   ; copy the pixel\r
640         NEXT_PIXEL:\r
641                 SUB CX, 3               ; we skip the next 3\r
642                 ADD SI, 3               ; skip the bmp pixels\r
643                 LOOP SCAN_LOOP          ; finish the scan\r
644 \r
645                 MOV AX, nextPageRow\r
646                 ADD DI, AX              ; go to the next row on screen\r
647                 MOV AX, nextBmpRow\r
648                 ADD SI, AX              ; go to the next row on bmp\r
649 \r
650                 DEC rowCounter\r
651                 JNZ ROW_LOOP            ; do all the rows\r
652                 ;-- end plane painting\r
653 \r
654                 MOV AL, plane           ; advance to the next plane\r
655                 SHL AL, 1               ;\r
656                 AND AL, 0x0f            ; mask the plane properly\r
657                 MOV plane, AL           ; store the plane\r
658 \r
659                 INC bmpOffset           ; start bmp at the right spot\r
660 \r
661                 DEC planeCounter\r
662                 JNZ PLANE_LOOP          ; do all 4 planes\r
663     }\r
664 }//backup!*/\r
665 \r
666 void\r
667 modexDrawSpriteRegion(page_t *page, int x, int y,\r
668                       int rx, int ry, int rw, int rh, bitmap_t *bmp) {\r
669     word poffset = (word)page->data + y*(page->width/4) + x/4;\r
670     byte huge *data = bmp->data;//+bmp->offset;\r
671     word bmpOffset = (word) data + ry * bmp->width + rx;\r
672     word width = rw;\r
673     word height = rh;\r
674     byte plane = 1 << ((byte) x & 0x03);\r
675     word scanCount = width/4 + (width%4 ? 1 :0);\r
676     word nextPageRow = page->width/4 - scanCount;\r
677     word nextBmpRow = (word) bmp->width - width;\r
678     word rowCounter;\r
679     byte planeCounter = 4;\r
680 \r
681     __asm {\r
682                 MOV AX, SCREEN_SEG      ; go to the VGA memory\r
683                 MOV ES, AX\r
684 \r
685                 MOV DX, SC_INDEX        ; point at the map mask register\r
686                 MOV AL, MAP_MASK        ;\r
687                 OUT DX, AL              ;\r
688 \r
689         PLANE_LOOP:\r
690                 MOV DX, SC_DATA         ; select the current plane\r
691                 MOV AL, plane           ;\r
692                 OUT DX, AL              ;\r
693 \r
694                 ;-- begin plane painting\r
695                 MOV AX, height          ; start the row counter\r
696                 MOV rowCounter, AX      ;\r
697                 MOV DI, poffset         ; go to the first pixel\r
698                 MOV SI, bmpOffset       ; go to the bmp pixel\r
699         ROW_LOOP:\r
700                 MOV CX, width           ; count the columns\r
701         SCAN_LOOP:\r
702                 LODSB\r
703                 DEC SI\r
704                 CMP AL, 0\r
705                 JNE DRAW_PIXEL          ; draw non-zero pixels\r
706 \r
707                 INC DI                  ; skip the transparent pixel\r
708                 ADD SI, 1\r
709                 JMP NEXT_PIXEL\r
710         DRAW_PIXEL:\r
711                 MOVSB                   ; copy the pixel\r
712         NEXT_PIXEL:\r
713                 SUB CX, 3               ; we skip the next 3\r
714                 ADD SI, 3               ; skip the bmp pixels\r
715                 LOOP SCAN_LOOP          ; finish the scan\r
716 \r
717                 MOV AX, nextPageRow\r
718                 ADD DI, AX              ; go to the next row on screen\r
719                 MOV AX, nextBmpRow\r
720                 ADD SI, AX              ; go to the next row on bmp\r
721 \r
722                 DEC rowCounter\r
723                 JNZ ROW_LOOP            ; do all the rows\r
724                 ;-- end plane painting\r
725 \r
726                 MOV AL, plane           ; advance to the next plane\r
727                 SHL AL, 1               ;\r
728                 AND AL, 0x0f            ; mask the plane properly\r
729                 MOV plane, AL           ; store the plane\r
730 \r
731                 INC bmpOffset           ; start bmp at the right spot\r
732 \r
733                 DEC planeCounter\r
734                 JNZ PLANE_LOOP          ; do all 4 planes\r
735     }\r
736 }\r
737 \r
738 /* copy a region of video memory from one page to another.\r
739  * It assumes that the left edge of the tile is the same on both\r
740  * regions and the memory areas do not overlap.\r
741  */\r
742 void\r
743 modexCopyPageRegion(page_t *dest, page_t *src,\r
744                     word sx, word sy,\r
745                     word dx, word dy,\r
746                     word width, word height)\r
747 {\r
748     word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;\r
749     word soffset = (word)src->data + sy*(src->width/4) + sx/4;\r
750     word scans   = width/4;\r
751     word nextSrcRow = src->width/4 - scans - 1;\r
752     word nextDestRow = dest->width/4 - scans - 1;\r
753     byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08};  /* clips for rectangles not on 4s */\r
754     byte rclip[] = {0x0f, 0x01, 0x03, 0x07};\r
755     byte left = lclip[sx&0x03];\r
756     byte right = rclip[(sx+width)&0x03];\r
757 \r
758     __asm {\r
759                 MOV AX, SCREEN_SEG      ; work in the vga space\r
760                 MOV ES, AX              ;\r
761                 MOV DI, doffset         ;\r
762                 MOV SI, soffset         ;\r
763 \r
764                 MOV DX, GC_INDEX        ; turn off cpu bits\r
765                 MOV AX, 0008h           ;\r
766                 OUT DX, AX\r
767 \r
768                 MOV AX, SC_INDEX        ; point to the mask register\r
769                 MOV DX, AX              ;\r
770                 MOV AL, MAP_MASK        ;\r
771                 OUT DX, AL              ;\r
772                 INC DX                  ;\r
773 \r
774         ROW_START:\r
775                 PUSH DS\r
776                 MOV AX, ES\r
777                 MOV DS, AX\r
778                 MOV CX, scans           ; the number of latches\r
779 \r
780                 MOV AL, left            ; do the left column\r
781                 OUT DX, AL              ;\r
782                 MOVSB                   ;\r
783                 DEC CX                  ;\r
784 \r
785                 MOV AL, 0fh             ; do the inner columns\r
786                 OUT DX, AL\r
787                 REP MOVSB               ; copy the pixels\r
788 \r
789                 MOV AL, right           ; do the right column\r
790                 OUT DX, AL\r
791                 MOVSB\r
792                 POP DS\r
793 \r
794                 MOV AX, SI              ; go the start of the next row\r
795                 ADD AX, nextSrcRow      ;\r
796                 MOV SI, AX              ;\r
797                 MOV AX, DI              ;\r
798                 ADD AX, nextDestRow     ;\r
799                 MOV DI, AX              ;\r
800 \r
801                 DEC height              ; do the rest of the actions\r
802                 JNZ ROW_START           ;\r
803 \r
804                 MOV DX, GC_INDEX+1      ; go back to CPU data\r
805                 MOV AL, 0ffh            ; none from latches\r
806                 OUT DX, AL              ;\r
807     }\r
808 }\r
809 \r
810 \r
811 /* fade and flash */\r
812 void\r
813 modexFadeOn(word fade, byte *palette) {\r
814     fadePalette(-fade, 64, 64/fade+1, palette);\r
815 }\r
816 \r
817 \r
818 void\r
819 modexFadeOff(word fade, byte *palette) {\r
820     fadePalette(fade, 0, 64/fade+1, palette);\r
821 }\r
822 \r
823 \r
824 void\r
825 modexFlashOn(word fade, byte *palette) {\r
826     fadePalette(fade, -64, 64/fade+1, palette);\r
827 }\r
828 \r
829 \r
830 void\r
831 modexFlashOff(word fade, byte *palette) {\r
832     fadePalette(-fade, 0, 64/fade+1, palette);\r
833 }\r
834 \r
835 \r
836 static void\r
837 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {\r
838     word i;\r
839     byte dim = start;\r
840 \r
841     /* handle the case where we just update */\r
842     if(iter == 0) {\r
843         modexPalUpdate1(palette);\r
844         return;\r
845     }\r
846 \r
847     while(iter > 0) {  /* FadeLoop */\r
848         for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */\r
849             tmppal[i] = palette[i] - dim;\r
850             if(tmppal[i] > 127) {\r
851                 tmppal[i] = 0;\r
852             } else if(tmppal[i] > 63) {\r
853                 tmppal[i] = 63;\r
854             }\r
855         }\r
856         modexPalUpdate1(tmppal);\r
857         iter--;\r
858         dim += fade;\r
859     }\r
860 }\r
861 \r
862 \r
863 /* save and load */\r
864 void\r
865 modexPalSave(byte *palette) {\r
866     int  i;\r
867 \r
868     outp(PAL_READ_REG, 0);      /* start at palette entry 0 */\r
869     for(i=0; i<PAL_SIZE; i++) {\r
870         palette[i] = inp(PAL_DATA_REG); /* read the palette data */\r
871     }\r
872 }\r
873 \r
874 \r
875 byte *\r
876 modexNewPal() {\r
877     byte *ptr;\r
878     ptr = malloc(PAL_SIZE);\r
879 \r
880     /* handle errors */\r
881     if(!ptr) {\r
882         printf("Could not allocate palette.\n");\r
883         exit(-1);\r
884     }\r
885 \r
886     return ptr;\r
887 }\r
888 \r
889 \r
890 void\r
891 modexLoadPalFile(byte *filename, byte **palette) {\r
892     FILE *file;\r
893     byte *ptr;\r
894 \r
895     /* free the palette if it exists */\r
896     if(*palette) {\r
897         free(*palette);\r
898     }\r
899 \r
900     /* allocate the new palette */\r
901     *palette = modexNewPal();\r
902 \r
903     /* open the file */\r
904     file = fopen(filename, "rb");\r
905     if(!file) {\r
906         printf("Could not open palette file: %s\n", filename);\r
907         exit(-2);\r
908     }\r
909 \r
910     /* read the file */\r
911     ptr = *palette;\r
912     while(!feof(file)) {\r
913         *ptr++ = fgetc(file);\r
914     }\r
915 \r
916     fclose(file);\r
917 }\r
918 \r
919 \r
920 void\r
921 modexSavePalFile(char *filename, byte *pal) {\r
922     unsigned int i;\r
923     FILE *file;\r
924 \r
925     /* open the file for writing */\r
926     file = fopen(filename, "wb");\r
927     if(!file) {\r
928         printf("Could not open %s for writing\n", filename);\r
929         exit(-2);\r
930     }\r
931 \r
932     /* write the data to the file */\r
933     fwrite(pal, 1, PAL_SIZE, file);\r
934     fclose(file);\r
935 }\r
936 \r
937 \r
938 /* blanking */\r
939 void\r
940 modexPalBlack() {\r
941     fadePalette(-1, 64, 1, tmppal);\r
942 }\r
943 \r
944 \r
945 void\r
946 modexPalWhite() {\r
947     fadePalette(-1, -64, 1, tmppal);\r
948 }\r
949 \r
950 \r
951 /* utility */\r
952 void\r
953 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)\r
954 {\r
955         byte *p = bmp->palette;\r
956         word w=0;\r
957         word q=0;\r
958         word qq=0;\r
959         static word a[PAL_SIZE];        //palette array of change values!\r
960         word z=0, aq=0, aa=0, pp=0;\r
961 \r
962         modexWaitBorder();\r
963         if((*i)==0)\r
964         {\r
965                 memset(a, -1, sizeof(a));\r
966                 outp(PAL_WRITE_REG, 0);  /* start at the beginning of palette */\r
967         }\r
968         else if(qp==0)\r
969         {\r
970                 q=(*i);\r
971         }\r
972         else\r
973         {\r
974                 q=(*i);\r
975                 qq=(*i)/3;\r
976 //              printf("q: %02d\n", (q));\r
977 //              printf("qq: %02d\n", (qq));\r
978                 //printf("      (*i)-q=%02d\n", (*i)-q);\r
979                 outp(PAL_WRITE_REG, qq);  /* start at the beginning of palette */\r
980         }\r
981         if((*i)<PAL_SIZE/2 && w==0)\r
982         {\r
983                 for(; (*i)<PAL_SIZE/2; (*i)++)\r
984                 {\r
985                         //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
986 //____                  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
987                         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
988                         {\r
989                                 w++;\r
990                                 break;\r
991                         }\r
992                         else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))\r
993                         {\r
994                                 //printf("qp=%d\n", qp);\r
995                                 //printf("              (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);\r
996                                 printf("                %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);\r
997                                 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!\r
998                                 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }\r
999                         }\r
1000                         else\r
1001                         {\r
1002                                 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);\r
1003                                 else\r
1004                                 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);\r
1005                                 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);\r
1006                                 printf("p[]=%d  qp=%d   p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }\r
1007                         }\r
1008                 }\r
1009                 //if(qp>0) printf("qp=%d\n", qp);\r
1010                 //if(qp>0) printf("                                             (*i)=%d\n", (*i)/3);\r
1011         }\r
1012         modexWaitBorder();          /* waits one retrace -- less flicker */\r
1013         if((*i)>=PAL_SIZE/2 && w==0)\r
1014         {\r
1015                 for(; (*i)<PAL_SIZE; (*i)++)\r
1016                 {\r
1017 //____                  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
1018                         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
1019                         {\r
1020                                 w++;\r
1021                                 break;\r
1022                         }\r
1023                         else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))\r
1024                         {\r
1025                                 //printf("qp=%d\n", qp);\r
1026                                 //printf("              (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);\r
1027                                 printf("                %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));\r
1028                                 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!\r
1029                                 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }\r
1030                         }\r
1031                         else\r
1032                         {\r
1033                                 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);\r
1034                                 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);\r
1035                                 printf("p[]=%d  qp=%d   p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }\r
1036                         }\r
1037                 }\r
1038                 //printf("                                              (*i)=%d\n", (*i)/3);\r
1039         }\r
1040 \r
1041 printf("\nqqqqqqqq\n\n");\r
1042 \r
1043         //palette checker~\r
1044         if(q>0 && qp==0)\r
1045         {\r
1046                 long lq;\r
1047                 long bufSize = (bmp->width * bmp->height);\r
1048                 pp = q;\r
1049                 //printf("1(*i)=%02d\n", (*i)/3);\r
1050                 //printf("1z=%02d\n", z/3);\r
1051                 chkcolor(bmp, &q, &a, &aa, &z, i);\r
1052                 //printf("2(*i)=%02d\n", (*i)/3);\r
1053                 //printf("2z=%02d\n", z/3);\r
1054                 aq=0;\r
1055 aqpee:\r
1056                 while(aq<=aa)\r
1057                 {\r
1058 //                      printf("a[%02d]=(%d)\n", aq, a[aq]);\r
1059                         if(a[aq]==-1) aq++;\r
1060                         else { aqoffset++; break; }\r
1061                 }\r
1062 //update the image data here!\r
1063         for(lq=0; lq<bufSize; lq++)\r
1064         {\r
1065                                 /*\r
1066                                                                         note to self\r
1067                                                                         use a[qp] instead of bmp->offset for this spot!\r
1068                                                                         NO! wwww\r
1069                                 */\r
1070 \r
1071                                 /*\r
1072                                 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww\r
1073                                 */\r
1074 \r
1075                 //(offset/bmp->offset)*bmp->offset\r
1076 \r
1077 \r
1078                 //printf("%02d ",bmp->data[lq]+bmp->offset);\r
1079                 //if(lq > 0 && lq%bmp->width==0) printf("\n");\r
1080                 //printf("%02d_", bmp->data[lq]+bmp->offset);\r
1081                 /*if(bmp->data[lq]+bmp->offset==aq)\r
1082                 {\r
1083                         //printf("%02d", bmp->data[lq]);\r
1084                         //printf("\n%02d\n", bmp->offset);\r
1085                         printf("aq=%02d ", aq);\r
1086                         printf("a[aq]=%02d      ", a[aq]);\r
1087                         printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);\r
1088                         printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);\r
1089                         //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);\r
1090 //++++                  bmp->data[lq]=a[aq]-aqpp;\r
1091 //                      printf("_%d ", bmp->data[lq]);\r
1092                         //if(lq > 0 && lq%bmp->width==0) printf("\n");\r
1093                 }\r
1094                 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)\r
1095                 {\r
1096                         if(bmp->data[lq]+bmp->offset >= aq)\r
1097                         {\r
1098                                 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);\r
1099                                 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);\r
1100                         }\r
1101                         else bmp->data[lq]+=(bmp->offset-aqpp);\r
1102                 }*/\r
1103 \r
1104                 //printf("%02d`", bmp->data[lq]);\r
1105                 //if(lq > 0 && lq%bmp->width==0) printf("\n");\r
1106         }\r
1107 \r
1108 //printf("              aq=%02d\n", aq);\r
1109 //printf("              aa=%02d\n", aa);\r
1110 \r
1111         //update the palette~\r
1112         modexPalUpdate(bmp, &pp, aq, aqoffset);\r
1113         (*i)=pp;\r
1114 \r
1115         if(aq<aa){ pp=q; aq++; goto aqpee; }\r
1116         }\r
1117 }\r
1118 \r
1119 void\r
1120 modexPalUpdate1(byte *p)\r
1121 {\r
1122         int i;\r
1123         modexWaitBorder();\r
1124         outp(PAL_WRITE_REG, 0);  /* start at the beginning of palette */\r
1125         for(i=0; i<PAL_SIZE/2; i++)\r
1126         {\r
1127                 outp(PAL_DATA_REG, p[i]);\r
1128         }\r
1129         modexWaitBorder();          /* waits one retrace -- less flicker */\r
1130         for(; i<PAL_SIZE; i++)\r
1131         {\r
1132                 outp(PAL_DATA_REG, p[(i)]);\r
1133         }\r
1134 }\r
1135 \r
1136 void\r
1137 modexPalUpdate0(byte *p)\r
1138 {\r
1139         int i;\r
1140         modexWaitBorder();\r
1141         outp(PAL_WRITE_REG, 0);  /* start at the beginning of palette */\r
1142         for(i=0; i<PAL_SIZE/2; i++)\r
1143         {\r
1144                 outp(PAL_DATA_REG, rand());\r
1145         }\r
1146         modexWaitBorder();          /* waits one retrace -- less flicker */\r
1147         for(; i<PAL_SIZE; i++)\r
1148         {\r
1149                 outp(PAL_DATA_REG, rand());\r
1150         }\r
1151 }\r
1152 \r
1153 void\r
1154 modexPalOverscan(byte *p, word col)\r
1155 {\r
1156         modexWaitBorder();\r
1157         outp(PAL_WRITE_REG, 0);  /* start at the beginning of palette */\r
1158         outp(PAL_DATA_REG, col);\r
1159 }\r
1160 \r
1161 //color checker~\r
1162 //i want to make another vesion that checks the palette when the palette is being appened~\r
1163 void chkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)\r
1164 {\r
1165                 byte *pal;\r
1166                 word zz=0;\r
1167                 pal = modexNewPal();\r
1168                 modexPalSave(pal);\r
1169                 //printf("q: %02d\n", (*q));\r
1170                 printf("chkcolor start~\n");\r
1171                 printf("1                               (*z): %d\n", (*z)/3);\r
1172                 printf("1                               (*i): %d\n", (*i)/3);\r
1173 //              printf("1 offset of color in palette    (*q): %d\n", (*q)/3);\r
1174                 printf("wwwwwwwwwwwwwwww\n");\r
1175                 //check palette for dups\r
1176                 for(; (*z)<PAL_SIZE; (*z)+=3)\r
1177                 {\r
1178                         //printf("\n            z: %d\n", (*z));\r
1179                         //printf("              q: %d\n", (*q));\r
1180                         //printf("              z+q: %d\n\n", ((*z)+(*q)));\r
1181                         //if((*z)%3==0)\r
1182                         //{\r
1183 //----                          if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])\r
1184                                 if((*z)==(*i))\r
1185                                 {\r
1186 //                                      printf("\n%d    [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);\r
1187 //                                      printf("%d      [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);\r
1188 //0000                                  (*z)-=3;\r
1189                                         break;\r
1190                                 }\r
1191                                 else for(zz=0; zz<(*q); zz+=3)\r
1192                                 {\r
1193                                         //printf("zz: %02d\n", zz/3);\r
1194                                         if(zz%3==0)\r
1195                                         {\r
1196                                                 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
1197                                                 {\r
1198 //                                                      (*z)-=3;\r
1199 //                                                      (*i)-=3;\r
1200 //                                                      printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);\r
1201 //                                                      printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);\r
1202                                                         break;\r
1203                                                 }\r
1204                                                 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])\r
1205                                                 {\r
1206 //                                                      printf("\n\nwwwwwwwwwwwwwwww\n");\r
1207 //                                                      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
1208 //                                                      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
1209 //                                                      //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
1210 //                                                      printf("        z : %d  [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);\r
1211 //++++                                                  (*i)--;\r
1212 //                                                      (*z)--;\r
1213                                                         //expand dong here\r
1214 /*\r
1215 planned features that i plan to implement~\r
1216 image that has values on the pallete list!\r
1217 wwww\r
1218 no... wait.... no wwww\r
1219 */\r
1220                                                         //for(zzii=0; zzii<3; zzii++)\r
1221                                                         //{\r
1222                                                                 //printf("z+q: %d\n\n", ((*z)+(*q)));\r
1223                                                                 a[(((*z)+(*q)))]=zz;\r
1224                                                         //}\r
1225                                                         (*aa)=(((*z)+(*q)));\r
1226                                                         printf("!!                                      a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);\r
1227 //                                                      printf("\n              aa: %d\n\n", (*aa));\r
1228 //                                                      printf("        a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);\r
1229 //                                                      printf("wwwwwwwwwwwwwwww\n\n");\r
1230                                                 }\r
1231                                                 /*else\r
1232                                                 {\r
1233                                                         printf("================\n");\r
1234                                                         printf("zq: %d  [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);\r
1235                                                         printf("zz: %d  [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);\r
1236                                                         printf("z : %d  [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);\r
1237                                                         printf("================\n");\r
1238                                                 }*/\r
1239                                                 //printf("[%d]", (zz+q));\r
1240                                         }\r
1241                                 }\r
1242                 }\r
1243                 printf("wwwwwwwwwwwwwwww\n");\r
1244                 printf("2                               (*z): %d\n", (*z)/3);\r
1245                 printf("2                               (*i): %d\n", (*i)/3);\r
1246 //              printf("2 offset of color in palette    (*q): %d\n", (*q)/3);\r
1247                 printf("chkcolor end~\n");\r
1248                 free(pal);\r
1249 }\r
1250 \r
1251 void modexputPixel(page_t *page, int x, int y, byte color)\r
1252 {\r
1253         word pageOff = (word) page->data;\r
1254         /* Each address accesses four neighboring pixels, so set\r
1255            Write Plane Enable according to which pixel we want\r
1256            to modify.  The plane is determined by the two least\r
1257            significant bits of the x-coordinate: */\r
1258         modexSelectPlane(PLANE(x));\r
1259         //outp(SC_INDEX, 0x02);\r
1260         //outp(SC_DATA, 0x01 << (x & 3));\r
1261 \r
1262         /* The offset of the pixel into the video segment is\r
1263            offset = (width * y + x) / 4, and write the given\r
1264            color to the plane we selected above.  Heed the active\r
1265            page start selection. */\r
1266         VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;\r
1267 \r
1268 }\r
1269 \r
1270 byte modexgetPixel(page_t *page, int x, int y)\r
1271 {\r
1272         word pageOff = (word) page->data;\r
1273         /* Select the plane from which we must read the pixel color: */\r
1274         outpw(GC_INDEX, 0x04);\r
1275         outpw(GC_INDEX+1, x & 3);\r
1276 \r
1277         return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];\r
1278 \r
1279 }\r
1280 \r
1281 void modexhlin(page_t *page, word xl, word xh, word y, word color)\r
1282 {\r
1283         word x;\r
1284         word yy=0;\r
1285 \r
1286         for(x=0;x<xh*4;x+=4)\r
1287         {\r
1288                 if(x+4>=page[0].sw-1){ x=0; yy+=4; }\r
1289                 modexClearRegion(page, x+xl, y+yy, 4, 4, color);\r
1290         }\r
1291         //modexputPixel(page, x+xl, y, color);\r
1292 }\r
1293 \r
1294 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)\r
1295 {\r
1296         word i, s, o, w, j, xp;\r
1297         byte l[1024];\r
1298         word addr = (word) l;\r
1299         word chw=0;\r
1300         byte c;\r
1301         //byte near *bakapee;\r
1302 \r
1303         switch(t)\r
1304         {\r
1305                 case 0:\r
1306                         w=14;\r
1307                 break;\r
1308                 case 1:\r
1309                         w=8;\r
1310                 break;\r
1311                 case 2:\r
1312                         w=8;\r
1313                 break;\r
1314                 case 3:\r
1315                         w=16;\r
1316                 break;\r
1317                 default:\r
1318                         t=3;\r
1319                         w=16;\r
1320                 break;\r
1321         }\r
1322 \r
1323         s=romFonts[t].seg;\r
1324         o=romFonts[t].off;\r
1325 \r
1326         for(; *str != '\0'; str++)\r
1327         {\r
1328         c = (*str);\r
1329         if((c=='\n'/* || c=="\\r
1330 "*/) || chw\r
1331 >=page->width)\r
1332         {\r
1333                 chw=0;\r
1334                 y+=w;\r
1335                 continue;\r
1336         }\r
1337         //load the letter 'A'\r
1338         __asm {\r
1339                 MOV DI, addr\r
1340                 MOV SI, o\r
1341                 MOV ES, s\r
1342                 SUB AH, AH\r
1343                 MOV AL, c       ; the letter\r
1344                 MOV CX, w\r
1345                 MUL CX\r
1346                 ADD SI, AX      ;the address of charcter\r
1347         L1:     MOV AX, ES:SI\r
1348                 MOV DS:DI, AX\r
1349                 INC SI\r
1350                 INC DI\r
1351                 DEC CX\r
1352                 JNZ L1\r
1353         }\r
1354         //bakapee = _nmalloc(sizeof(byte)*8);\r
1355 //TODO: OPTIMIZE THIS!!!!\r
1356                 for(i=0; i<w; i++)\r
1357                 {\r
1358                         /*modexSelectPlane(PLANE(x));\r
1359                         j=1<<8;\r
1360                         *bakapee=(l[i] & j ? col:bgcol);\r
1361                         _fmemcpy(page->data + (((page->width/4) * (y+page->dy+i)) + ((x+page->dx+chw) / 4)), bakapee, 8);*/\r
1362                         j=1<<8;\r
1363                         xp=0;\r
1364                         while(j)\r
1365                         {\r
1366                                 modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);\r
1367                                 xp++;\r
1368                                 j>>=1;\r
1369                         }\r
1370                 }\r
1371                 chw += xp;\r
1372         }\r
1373         //_nfree(bakapee);\r
1374 }\r
1375 \r
1376 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)\r
1377 {\r
1378         word i, s, o, w, j, xp;\r
1379         byte l[1024];\r
1380         word addr = (word) l;\r
1381         word chw=0;\r
1382         byte c;\r
1383 \r
1384         switch(t)\r
1385         {\r
1386                 case 0:\r
1387                         w=14;\r
1388                 break;\r
1389                 case 1:\r
1390                         w=8;\r
1391                 break;\r
1392                 case 2:\r
1393                         w=8;\r
1394                 break;\r
1395                 case 3:\r
1396                         w=16;\r
1397                 break;\r
1398                 default:\r
1399                         t=3;\r
1400                         w=16;\r
1401                 break;\r
1402         }\r
1403 \r
1404         s=romFonts[t].seg;\r
1405         o=romFonts[t].off;\r
1406 \r
1407         for(; *str != '\0'; str++)\r
1408         {\r
1409         c = (*str);\r
1410         if((c=='\n'/* || c=="\\r
1411 "*/)/* || chw>=page->width*/)\r
1412         {\r
1413                 chw=0;\r
1414                 y+=w;\r
1415                 continue;\r
1416         }\r
1417         //load the letter 'A'\r
1418         __asm {\r
1419                 MOV DI, addr\r
1420                 MOV SI, o\r
1421                 MOV ES, s\r
1422                 SUB AH, AH\r
1423                 MOV AL, c       ; the letter\r
1424                 MOV CX, w\r
1425                 MUL CX\r
1426                 ADD SI, AX      ;the address of charcter\r
1427         L1:     MOV AX, ES:SI\r
1428                 MOV DS:DI, AX\r
1429                 INC SI\r
1430                 INC DI\r
1431                 DEC CX\r
1432                 JNZ L1\r
1433         }\r
1434 \r
1435                 for(i=0; i<w; i++)\r
1436                 {\r
1437                         j=1<<8;\r
1438                         xp=0;\r
1439                         while(j)\r
1440                         {\r
1441                                 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);\r
1442                                 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);\r
1443                                 xp++;\r
1444                                 j>>=1;\r
1445                         }\r
1446                 }\r
1447                 chw += xp;\r
1448         }\r
1449 }\r
1450 \r
1451 /* palette dump on display! */\r
1452 void pdump(page_t *pee)\r
1453 {\r
1454         int mult=(QUADWH);\r
1455         int palq=(mult)*TILEWH;\r
1456         int palcol=0;\r
1457         int palx, paly;\r
1458         for(paly=0; paly<palq; paly+=mult){\r
1459                 for(palx=0; palx<palq; palx+=mult){\r
1460                                 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);\r
1461                         palcol++;\r
1462                 }\r
1463         }\r
1464 }\r
1465 \r
1466 /////////////////////////////////////////////////////////////////////////////\r
1467 //                                                                                                                                               //\r
1468 // cls() - This clears the screen to the specified color, on the VGA or on //\r
1469 //               the Virtual screen.                                                                                     //\r
1470 //                                                                                                                                               //\r
1471 /////////////////////////////////////////////////////////////////////////////\r
1472 void cls(page_t *page, byte color, byte *Where)\r
1473 {\r
1474         //modexClearRegion(page, 0, 0, page->width, page->height, color);\r
1475         /* set map mask to all 4 planes */\r
1476         outpw(SC_INDEX, 0xff02);\r
1477         //_fmemset(VGA, color, 16000);\r
1478         _fmemset(Where, color, page->width*(page->height));\r
1479 }\r
1480 \r
1481 void\r
1482 modexWaitBorder() {\r
1483     while(inp(INPUT_STATUS_1)  & 8)  {\r
1484         /* spin */\r
1485     }\r
1486 \r
1487     while(!(inp(INPUT_STATUS_1)  & 8))  {\r
1488         /* spin */\r
1489     }\r
1490 }\r