]> 4ch.mooo.com Git - 16.git/blob - src/lib/16_vl_1.c
[16_ca needs huge amounts of work and I should remember what needs to be done soon...
[16.git] / src / lib / 16_vl_1.c
1 /* Project 16 Source Code~\r
2  * Copyright (C) 2012-2017 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\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/16_vl.h"\r
27 \r
28 /*\r
29 =============================================================================\r
30 \r
31                                                 PALETTE OPS\r
32 \r
33                 To avoid snow, do a WaitVBL BEFORE calling these\r
34 \r
35 =============================================================================\r
36 */\r
37 \r
38 \r
39 /*\r
40 =================\r
41 =\r
42 = VL_FillPalette\r
43 =\r
44 =================\r
45 */\r
46 \r
47 void VL_FillPalette (int red, int green, int blue)\r
48 {\r
49         int     i;\r
50 \r
51         outportb (PAL_WRITE_REG,0);\r
52         for (i=0;i<256;i++)\r
53         {\r
54                 outportb (PAL_DATA_REG,red);\r
55                 outportb (PAL_DATA_REG,green);\r
56                 outportb (PAL_DATA_REG,blue);\r
57         }\r
58 }\r
59 \r
60 //===========================================================================\r
61 \r
62 /*\r
63 =================\r
64 =\r
65 = VL_SetColor\r
66 =\r
67 =================\r
68 */\r
69 \r
70 void VL_SetColor        (int color, int red, int green, int blue)\r
71 {\r
72         outportb (PAL_WRITE_REG,color);\r
73         outportb (PAL_DATA_REG,red);\r
74         outportb (PAL_DATA_REG,green);\r
75         outportb (PAL_DATA_REG,blue);\r
76 }\r
77 \r
78 //===========================================================================\r
79 \r
80 /*\r
81 =================\r
82 =\r
83 = VL_GetColor\r
84 =\r
85 =================\r
86 */\r
87 \r
88 void VL_GetColor        (int color, int *red, int *green, int *blue)\r
89 {\r
90         outportb (PAL_READ_REG,color);\r
91         *red = inportb (PAL_DATA_REG);\r
92         *green = inportb (PAL_DATA_REG);\r
93         *blue = inportb (PAL_DATA_REG);\r
94 }\r
95 \r
96 //===========================================================================\r
97 \r
98 /*\r
99 =================\r
100 =\r
101 = VL_SetPalette\r
102 =\r
103 = If fast palette setting has been tested for, it is used\r
104 = (some cards don't like outsb palette setting)\r
105 =\r
106 =================\r
107 */\r
108 \r
109 void VL_SetPalette (byte far *palette, video_t *v)\r
110 {\r
111 //      int     i;\r
112         boolean fastpalette;\r
113         fastpalette=v->fastpalette;\r
114 \r
115 //      outportb (PAL_WRITE_REG,0);\r
116 //      for (i=0;i<768;i++)\r
117 //              outportb(PAL_DATA_REG,*palette++);\r
118 \r
119         __asm {\r
120                 mov     dx,PAL_WRITE_REG\r
121                 mov     al,0\r
122                 out     dx,al\r
123                 mov     dx,PAL_DATA_REG\r
124                 lds     si,[palette]\r
125 \r
126                 test    [ss:fastpalette],1\r
127                 jz      slowset\r
128 //\r
129 // set palette fast for cards that can take it\r
130 //\r
131                 //mov   cx,768\r
132                 //rep outsb\r
133                 //jmp   done\r
134 \r
135 //\r
136 // set palette slowly for some video cards\r
137 //\r
138 #ifdef __BORLANDC__\r
139         }\r
140 #endif\r
141 slowset:\r
142 #ifdef __BORLANDC__\r
143         __asm {\r
144 #endif\r
145                 mov     cx,256\r
146 #ifdef __BORLANDC__\r
147         }\r
148 #endif\r
149 setloop:\r
150 #ifdef __BORLANDC__\r
151         __asm {\r
152 #endif\r
153                 lodsb\r
154                 out     dx,al\r
155                 lodsb\r
156                 out     dx,al\r
157                 lodsb\r
158                 out     dx,al\r
159                 loop    setloop\r
160 #ifdef __BORLANDC__\r
161         }\r
162 #endif\r
163 done:\r
164 #ifdef __BORLANDC__\r
165         __asm {\r
166 #endif\r
167                 mov     ax,ss\r
168                         mov     ds,ax\r
169         }\r
170         v->fastpalette=fastpalette;\r
171 }\r
172 \r
173 \r
174 //===========================================================================\r
175 \r
176 /*\r
177 =================\r
178 =\r
179 = VL_GetPalette\r
180 =\r
181 = This does not use the port string instructions,\r
182 = due to some incompatabilities\r
183 =\r
184 =================\r
185 */\r
186 \r
187 void VL_GetPalette (byte far *palette)\r
188 {\r
189         int     i;\r
190 \r
191         outportb (PAL_READ_REG,0);\r
192         for (i=0;i<768;i++)\r
193                 *palette++ = inportb(PAL_DATA_REG);\r
194 }\r
195 \r
196 \r
197 //===========================================================================\r
198 \r
199 /*\r
200 =================\r
201 =\r
202 = VL_FadeOut\r
203 =\r
204 = Fades the current palette to the given color in the given number of steps\r
205 =\r
206 =================\r
207 */\r
208 \r
209 void VL_FadeOut (int start, int end, int red, int green, int blue, int steps, video_t *v)\r
210 {\r
211         int             i,j,orig,delta;\r
212         byte    far *origptr, far *newptr;\r
213 \r
214         VL_WaitVBL(1);\r
215         VL_GetPalette (&v->palette1[0][0]);\r
216         _fmemcpy (v->palette2,v->palette1,PALSIZE);\r
217 \r
218 //\r
219 // fade through intermediate frames\r
220 //\r
221         for (i=0;i<steps;i++)\r
222         {\r
223                 origptr = &v->palette1[start][0];\r
224                 newptr = &v->palette2[start][0];\r
225                 for (j=start;j<=end;j++)\r
226                 {\r
227                         orig = *origptr++;\r
228                         delta = red-orig;\r
229                         *newptr++ = orig + delta * i / steps;\r
230                         orig = *origptr++;\r
231                         delta = green-orig;\r
232                         *newptr++ = orig + delta * i / steps;\r
233                         orig = *origptr++;\r
234                         delta = blue-orig;\r
235                         *newptr++ = orig + delta * i / steps;\r
236                 }\r
237 \r
238                 VL_WaitVBL(1);\r
239                 VL_SetPalette (&v->palette2[0][0], v);\r
240         }\r
241 \r
242 //\r
243 // final color\r
244 //\r
245         VL_FillPalette (red,green,blue);\r
246 \r
247         v->screenfaded = true;\r
248 }\r
249 \r
250 \r
251 /*\r
252 =================\r
253 =\r
254 = VL_FadeIn\r
255 =\r
256 =================\r
257 */\r
258 \r
259 void VL_FadeIn (int start, int end, byte far *palette, int steps, video_t *v)\r
260 {\r
261         int             i,j,delta;\r
262 \r
263         VL_WaitVBL(1);\r
264         VL_GetPalette (&v->palette1[0][0]);\r
265         _fmemcpy (&v->palette2[0][0],&v->palette1[0][0],sizeof(v->palette1));\r
266 \r
267         start *= 3;\r
268         end = end*3+2;\r
269 \r
270 //\r
271 // fade through intermediate frames\r
272 //\r
273         for (i=0;i<steps;i++)\r
274         {\r
275                 for (j=start;j<=end;j++)\r
276                 {\r
277                         delta = palette[j]-v->palette1[0][j];\r
278                         v->palette2[0][j] = v->palette1[0][j] + delta * i / steps;\r
279                 }\r
280 \r
281                 VL_WaitVBL(1);\r
282                 VL_SetPalette (&v->palette2[0][0], v);\r
283         }\r
284 \r
285 //\r
286 // final color\r
287 //\r
288         VL_SetPalette (palette, v);\r
289         v->screenfaded = false;\r
290 }\r
291 \r
292 \r
293 \r
294 /*\r
295 =================\r
296 =\r
297 = VL_TestPaletteSet\r
298 =\r
299 = Sets the palette with outsb, then reads it in and compares\r
300 = If it compares ok, fastpalette is set to true.\r
301 =\r
302 =================\r
303 */\r
304 \r
305 void VL_TestPaletteSet (video_t *v)\r
306 {\r
307         int     i;\r
308 \r
309         for (i=0;i<768;i++)\r
310                 v->palette1[0][i] = i;\r
311 \r
312         v->fastpalette = true;\r
313         VL_SetPalette (&v->palette1[0][0], v);\r
314         VL_GetPalette (&v->palette2[0][0]);\r
315         if (_fmemcmp (&v->palette1[0][0],&v->palette2[0][0],768))\r
316                 v->fastpalette = false;\r
317 }\r
318 \r
319 \r
320 /*\r
321 =============================================================================\r
322 \r
323                                                         PIXEL OPS\r
324 \r
325 =============================================================================\r
326 */\r
327 \r
328 //byte  rightmasks[4] = {1,3,7,15};\r
329 \r
330 /*\r
331 =================\r
332 =\r
333 = VL_Plot\r
334 =\r
335 =================\r
336 */\r
337 \r
338 void VL_Plot (int x, int y, int color, ofs_t *ofs)\r
339 {\r
340         byte mask;\r
341         VCLIPDEF\r
342 \r
343         mask = pclip[x&3];\r
344         VGAMAPMASK(mask);\r
345         *(byte far *)MK_FP(SCREENSEG,ofs->bufferofs+(ofs->ylookup[y]+(x>>2))) = color;\r
346         VGAMAPMASK(15);\r
347 }\r
348 \r
349 \r
350 /*\r
351 =================\r
352 =\r
353 = VL_Hlin\r
354 =\r
355 =================\r
356 */\r
357 \r
358 void VL_Hlin (unsigned x, unsigned y, unsigned width, unsigned color, ofs_t *ofs)\r
359 {\r
360         unsigned                xbyte;\r
361         byte                    far *dest;\r
362         byte                    leftmask,rightmask;\r
363         int                             midbytes;\r
364 \r
365         LRCLIPDEF\r
366 \r
367         xbyte = x>>2;\r
368         leftmask = lclip[x&3];\r
369         rightmask = rclip[(x+width-1)&3];\r
370         midbytes = ((x+width+3)>>2) - xbyte - 2;\r
371 \r
372         dest = MK_FP(SCREENSEG,ofs->bufferofs+ofs->ylookup[y]+xbyte);\r
373 \r
374         if (midbytes<0)\r
375         {\r
376         // all in one byte\r
377                 VGAMAPMASK(leftmask&rightmask);\r
378                 *dest = color;\r
379                 VGAMAPMASK(15);\r
380                 return;\r
381         }\r
382 \r
383         VGAMAPMASK(leftmask);\r
384         *dest++ = color;\r
385 \r
386         VGAMAPMASK(15);\r
387         _fmemset (dest,color,midbytes);\r
388         dest+=midbytes;\r
389 \r
390         VGAMAPMASK(rightmask);\r
391         *dest = color;\r
392 \r
393         VGAMAPMASK(15);\r
394 }\r
395 \r
396 \r
397 /*\r
398 =================\r
399 =\r
400 = VL_Vlin\r
401 =\r
402 =================\r
403 */\r
404 \r
405 void VL_Vlin (int x, int y, int height, int color, ofs_t *ofs)\r
406 {\r
407         byte    far *dest,mask;\r
408         VCLIPDEF\r
409 \r
410         mask = pclip[x&3];\r
411         VGAMAPMASK(mask);\r
412 \r
413         dest = MK_FP(SCREENSEG,ofs->bufferofs+ofs->ylookup[y]+(x>>2));\r
414 \r
415         while (height--)\r
416         {\r
417                 *dest = color;\r
418                 dest += ofs->linewidth;\r
419         }\r
420 \r
421         VGAMAPMASK(15);\r
422 }\r
423 \r
424 \r
425 /*\r
426 =================\r
427 =\r
428 = VL_Bar\r
429 =\r
430 =================\r
431 */\r
432 \r
433 void VL_Bar (int x, int y, int width, int height, int color, ofs_t *ofs)\r
434 {\r
435         byte    far *dest;\r
436         byte    leftmask,rightmask;\r
437         int             midbytes,linedelta;\r
438 \r
439         LRCLIPDEF\r
440 \r
441         leftmask = lclip[x&3];\r
442         rightmask = rclip[(x+width-1)&3];\r
443         midbytes = ((x+width+3)>>2) - (x>>2) - 2;\r
444         linedelta = ofs->linewidth-(midbytes+1);\r
445 \r
446         dest = MK_FP(SCREENSEG,ofs->bufferofs+ofs->ylookup[y]+(x>>2));\r
447 \r
448         if (midbytes<0)\r
449         {\r
450         // all in one byte\r
451                 VGAMAPMASK(leftmask&rightmask);\r
452                 while (height--)\r
453                 {\r
454                         *dest = color;\r
455                         dest += ofs->linewidth;\r
456                 }\r
457                 VGAMAPMASK(15);\r
458                 return;\r
459         }\r
460 \r
461         while (height--)\r
462         {\r
463                 VGAMAPMASK(leftmask);\r
464                 *dest++ = color;\r
465 \r
466                 VGAMAPMASK(15);\r
467                 _fmemset (dest,color,midbytes);\r
468                 dest+=midbytes;\r
469 \r
470                 VGAMAPMASK(rightmask);\r
471                 *dest = color;\r
472 \r
473                 dest+=linedelta;\r
474         }\r
475 \r
476         VGAMAPMASK(15);\r
477 }\r
478 \r
479 \r
480 /*\r
481 ==============\r
482 \r
483  VL_WaitVBL                     ******** NEW *********\r
484 \r
485  Wait for the vertical retrace (returns before the actual vertical sync)\r
486 \r
487 ==============\r
488 */\r
489 \r
490 void VL_WaitVBL(word num)\r
491 {\r
492 //PROC  VL_WaitVBL  num:WORD\r
493 //PUBLIC        VL_WaitVBL\r
494 #ifdef __WATCOMC__\r
495         __asm {\r
496 #endif\r
497         wait:\r
498 #ifdef __BORLANDC__\r
499         __asm {\r
500 #endif\r
501 \r
502                 mov     dx,STATUS_REGISTER_1\r
503 \r
504                 mov     cx,[num]\r
505         //\r
506         // wait for a display signal to make sure the raster isn't in the middle\r
507         // of a sync\r
508         //\r
509 #ifdef __BORLANDC__\r
510         }\r
511 #endif\r
512         waitnosync:\r
513 #ifdef __BORLANDC__\r
514         __asm {\r
515 #endif\r
516                 in      al,dx\r
517                 test    al,8\r
518                 jnz     waitnosync\r
519 \r
520 \r
521 #ifdef __BORLANDC__\r
522         }\r
523 #endif\r
524         waitsync:\r
525 #ifdef __BORLANDC__\r
526         __asm {\r
527 #endif\r
528                 in      al,dx\r
529                 test    al,8\r
530                 jz      waitsync\r
531 \r
532                 loop    waitnosync\r
533 \r
534                 ret\r
535         }\r
536 }\r
537 \r
538 //===========================================================================\r
539 \r
540 void VGAMAPMASK(byte x)\r
541 {\r
542         __asm {\r
543 //              cli\r
544                 mov     dx,SC_INDEX\r
545                 mov     al,SC_MAPMASK\r
546                 mov     ah,x\r
547                 out     dx,ax\r
548 //              sti\r
549         }\r
550 }\r
551 \r
552 void VGAWRITEMODE(byte x)\r
553 {\r
554         __asm {\r
555 //              cli\r
556                 mov     dx,GC_INDEX\r
557                 mov     al,GC_MODE\r
558                 out     dx,al\r
559                 inc     dx\r
560                 in      al,dx\r
561                 and     al,252\r
562                 or      al,x\r
563                 out     dx,al\r
564 //              sti\r
565         }\r
566 }\r
567 \r
568 void VGAREADMAP(byte x)\r
569 {\r
570         __asm {\r
571 //              cli\r
572                 mov     dx,GC_INDEX\r
573                 mov     al,GC_READMAP\r
574                 mov     ah,x\r
575                 out     dx,ax\r
576 //              sti\r
577         }\r
578 }\r
579 \r
580 //===========================================================================\r