]> 4ch.mooo.com Git - 16.git/blob - 16/WOLFSRC/id_vh.c
got 8086 port of wolf3d to work and sod to work
[16.git] / 16 / WOLFSRC / id_vh.c
1 // ID_VH.C\r
2 \r
3 #include "ID_HEADS.H"\r
4 \r
5 #define SCREENWIDTH             80\r
6 #define CHARWIDTH               2\r
7 #define TILEWIDTH               4\r
8 #define GRPLANES                4\r
9 #define BYTEPIXELS              4\r
10 \r
11 #define SCREENXMASK             (~3)\r
12 #define SCREENXPLUS             (3)\r
13 #define SCREENXDIV              (4)\r
14 \r
15 #define VIEWWIDTH               80\r
16 \r
17 #define PIXTOBLOCK              4               // 16 pixels to an update block\r
18 \r
19 #define UNCACHEGRCHUNK(chunk)   {MM_FreePtr(&grsegs[chunk]);grneeded[chunk]&=~ca_levelbit;}\r
20 \r
21 byte    update[UPDATEHIGH][UPDATEWIDE];\r
22 \r
23 //==========================================================================\r
24 \r
25 pictabletype    _seg *pictable;\r
26 \r
27 \r
28 int     px,py;\r
29 byte    fontcolor,backcolor;\r
30 int     fontnumber;\r
31 int bufferwidth,bufferheight;\r
32 \r
33 \r
34 //==========================================================================\r
35 \r
36 void    VWL_UpdateScreenBlocks (void);\r
37 \r
38 //==========================================================================\r
39 \r
40 void VW_DrawPropString (char far *string)\r
41 {\r
42         fontstruct      far     *font;\r
43         int             width,step,height,i;\r
44         byte    far *source, far *dest, far *origdest;\r
45         byte    ch,mask;\r
46 \r
47         font = (fontstruct far *)grsegs[STARTFONT+fontnumber];\r
48         height = bufferheight = font->height;\r
49         dest = origdest = MK_FP(SCREENSEG,bufferofs+ylookup[py]+(px>>2));\r
50         mask = 1<<(px&3);\r
51 \r
52 \r
53         while ((ch = *string++)!=0)\r
54         {\r
55                 width = step = font->width[ch];\r
56                 source = ((byte far *)font)+font->location[ch];\r
57                 while (width--)\r
58                 {\r
59                         VGAMAPMASK(mask);\r
60 \r
61 asm     mov     ah,[BYTE PTR fontcolor]\r
62 asm     mov     bx,[step]\r
63 asm     mov     cx,[height]\r
64 asm     mov     dx,[linewidth]\r
65 asm     lds     si,[source]\r
66 asm     les     di,[dest]\r
67 \r
68 vertloop:\r
69 asm     mov     al,[si]\r
70 asm     or      al,al\r
71 asm     je      next\r
72 asm     mov     [es:di],ah                      // draw color\r
73 \r
74 next:\r
75 asm     add     si,bx\r
76 asm     add     di,dx\r
77 asm     loop    vertloop\r
78 asm     mov     ax,ss\r
79 asm     mov     ds,ax\r
80 \r
81                         source++;\r
82                         px++;\r
83                         mask <<= 1;\r
84                         if (mask == 16)\r
85                         {\r
86                                 mask = 1;\r
87                                 dest++;\r
88                         }\r
89                 }\r
90         }\r
91 bufferheight = height;\r
92 bufferwidth = ((dest+1)-origdest)*4;\r
93 }\r
94 \r
95 \r
96 void VW_DrawColorPropString (char far *string)\r
97 {\r
98         fontstruct      far     *font;\r
99         int             width,step,height,i;\r
100         byte    far *source, far *dest, far *origdest;\r
101         byte    ch,mask;\r
102 \r
103         font = (fontstruct far *)grsegs[STARTFONT+fontnumber];\r
104         height = bufferheight = font->height;\r
105         dest = origdest = MK_FP(SCREENSEG,bufferofs+ylookup[py]+(px>>2));\r
106         mask = 1<<(px&3);\r
107 \r
108 \r
109         while ((ch = *string++)!=0)\r
110         {\r
111                 width = step = font->width[ch];\r
112                 source = ((byte far *)font)+font->location[ch];\r
113                 while (width--)\r
114                 {\r
115                         VGAMAPMASK(mask);\r
116 \r
117 asm     mov     ah,[BYTE PTR fontcolor]\r
118 asm     mov     bx,[step]\r
119 asm     mov     cx,[height]\r
120 asm     mov     dx,[linewidth]\r
121 asm     lds     si,[source]\r
122 asm     les     di,[dest]\r
123 \r
124 vertloop:\r
125 asm     mov     al,[si]\r
126 asm     or      al,al\r
127 asm     je      next\r
128 asm     mov     [es:di],ah                      // draw color\r
129 \r
130 next:\r
131 asm     add     si,bx\r
132 asm     add     di,dx\r
133 \r
134 asm rcr cx,1                            // inc font color\r
135 asm jc  cont\r
136 asm     inc ah\r
137 \r
138 cont:\r
139 asm rcl cx,1\r
140 asm     loop    vertloop\r
141 asm     mov     ax,ss\r
142 asm     mov     ds,ax\r
143 \r
144                         source++;\r
145                         px++;\r
146                         mask <<= 1;\r
147                         if (mask == 16)\r
148                         {\r
149                                 mask = 1;\r
150                                 dest++;\r
151                         }\r
152                 }\r
153         }\r
154 bufferheight = height;\r
155 bufferwidth = ((dest+1)-origdest)*4;\r
156 }\r
157 \r
158 \r
159 //==========================================================================\r
160 \r
161 \r
162 /*\r
163 =================\r
164 =\r
165 = VL_MungePic\r
166 =\r
167 =================\r
168 */\r
169 \r
170 void VL_MungePic (byte far *source, unsigned width, unsigned height)\r
171 {\r
172         unsigned        x,y,plane,size,pwidth;\r
173         byte            _seg *temp, far *dest, far *srcline;\r
174 \r
175         size = width*height;\r
176 \r
177         if (width&3)\r
178                 MS_Quit ("VL_MungePic: Not divisable by 4!");\r
179 \r
180 //\r
181 // copy the pic to a temp buffer\r
182 //\r
183         MM_GetPtr (&(memptr)temp,size);\r
184         _fmemcpy (temp,source,size);\r
185 \r
186 //\r
187 // munge it back into the original buffer\r
188 //\r
189         dest = source;\r
190         pwidth = width/4;\r
191 \r
192         for (plane=0;plane<4;plane++)\r
193         {\r
194                 srcline = temp;\r
195                 for (y=0;y<height;y++)\r
196                 {\r
197                         for (x=0;x<pwidth;x++)\r
198                                 *dest++ = *(srcline+x*4+plane);\r
199                         srcline+=width;\r
200                 }\r
201         }\r
202 \r
203         MM_FreePtr (&(memptr)temp);\r
204 }\r
205 \r
206 void VWL_MeasureString (char far *string, word *width, word *height\r
207         , fontstruct _seg *font)\r
208 {\r
209         *height = font->height;\r
210         for (*width = 0;*string;string++)\r
211                 *width += font->width[*((byte far *)string)];   // proportional width\r
212 }\r
213 \r
214 void    VW_MeasurePropString (char far *string, word *width, word *height)\r
215 {\r
216         VWL_MeasureString(string,width,height,(fontstruct _seg *)grsegs[STARTFONT+fontnumber]);\r
217 }\r
218 \r
219 void    VW_MeasureMPropString  (char far *string, word *width, word *height)\r
220 {\r
221         VWL_MeasureString(string,width,height,(fontstruct _seg *)grsegs[STARTFONTM+fontnumber]);\r
222 }\r
223 \r
224 \r
225 \r
226 /*\r
227 =============================================================================\r
228 \r
229                                 Double buffer management routines\r
230 \r
231 =============================================================================\r
232 */\r
233 \r
234 \r
235 /*\r
236 =======================\r
237 =\r
238 = VW_MarkUpdateBlock\r
239 =\r
240 = Takes a pixel bounded block and marks the tiles in bufferblocks\r
241 = Returns 0 if the entire block is off the buffer screen\r
242 =\r
243 =======================\r
244 */\r
245 \r
246 int VW_MarkUpdateBlock (int x1, int y1, int x2, int y2)\r
247 {\r
248         int     x,y,xt1,yt1,xt2,yt2,nextline;\r
249         byte *mark;\r
250 \r
251         xt1 = x1>>PIXTOBLOCK;\r
252         yt1 = y1>>PIXTOBLOCK;\r
253 \r
254         xt2 = x2>>PIXTOBLOCK;\r
255         yt2 = y2>>PIXTOBLOCK;\r
256 \r
257         if (xt1<0)\r
258                 xt1=0;\r
259         else if (xt1>=UPDATEWIDE)\r
260                 return 0;\r
261 \r
262         if (yt1<0)\r
263                 yt1=0;\r
264         else if (yt1>UPDATEHIGH)\r
265                 return 0;\r
266 \r
267         if (xt2<0)\r
268                 return 0;\r
269         else if (xt2>=UPDATEWIDE)\r
270                 xt2 = UPDATEWIDE-1;\r
271 \r
272         if (yt2<0)\r
273                 return 0;\r
274         else if (yt2>=UPDATEHIGH)\r
275                 yt2 = UPDATEHIGH-1;\r
276 \r
277         mark = updateptr + uwidthtable[yt1] + xt1;\r
278         nextline = UPDATEWIDE - (xt2-xt1) - 1;\r
279 \r
280         for (y=yt1;y<=yt2;y++)\r
281         {\r
282                 for (x=xt1;x<=xt2;x++)\r
283                         *mark++ = 1;                    // this tile will need to be updated\r
284 \r
285                 mark += nextline;\r
286         }\r
287 \r
288         return 1;\r
289 }\r
290 \r
291 void VWB_DrawTile8 (int x, int y, int tile)\r
292 {\r
293         if (VW_MarkUpdateBlock (x,y,x+7,y+7))\r
294                 LatchDrawChar(x,y,tile);\r
295 }\r
296 \r
297 void VWB_DrawTile8M (int x, int y, int tile)\r
298 {\r
299         if (VW_MarkUpdateBlock (x,y,x+7,y+7))\r
300                 VL_MemToScreen (((byte far *)grsegs[STARTTILE8M])+tile*64,8,8,x,y);\r
301 }\r
302 \r
303 \r
304 void VWB_DrawPic (int x, int y, int chunknum)\r
305 {\r
306         int     picnum = chunknum - STARTPICS;\r
307         unsigned width,height;\r
308 \r
309         x &= ~7;\r
310 \r
311         width = pictable[picnum].width;\r
312         height = pictable[picnum].height;\r
313 \r
314         if (VW_MarkUpdateBlock (x,y,x+width-1,y+height-1))\r
315                 VL_MemToScreen (grsegs[chunknum],width,height,x,y);\r
316 }\r
317 \r
318 \r
319 \r
320 void VWB_DrawPropString  (char far *string)\r
321 {\r
322         int x;\r
323         x=px;\r
324         VW_DrawPropString (string);\r
325         VW_MarkUpdateBlock(x,py,px-1,py+bufferheight-1);\r
326 }\r
327 \r
328 \r
329 void VWB_Bar (int x, int y, int width, int height, int color)\r
330 {\r
331         if (VW_MarkUpdateBlock (x,y,x+width,y+height-1) )\r
332                 VW_Bar (x,y,width,height,color);\r
333 }\r
334 \r
335 void VWB_Plot (int x, int y, int color)\r
336 {\r
337         if (VW_MarkUpdateBlock (x,y,x,y))\r
338                 VW_Plot(x,y,color);\r
339 }\r
340 \r
341 void VWB_Hlin (int x1, int x2, int y, int color)\r
342 {\r
343         if (VW_MarkUpdateBlock (x1,y,x2,y))\r
344                 VW_Hlin(x1,x2,y,color);\r
345 }\r
346 \r
347 void VWB_Vlin (int y1, int y2, int x, int color)\r
348 {\r
349         if (VW_MarkUpdateBlock (x,y1,x,y2))\r
350                 VW_Vlin(y1,y2,x,color);\r
351 }\r
352 \r
353 void VW_UpdateScreen (void)\r
354 {\r
355         VH_UpdateScreen ();\r
356 }\r
357 \r
358 \r
359 /*\r
360 =============================================================================\r
361 \r
362                                                 WOLFENSTEIN STUFF\r
363 \r
364 =============================================================================\r
365 */\r
366 \r
367 /*\r
368 =====================\r
369 =\r
370 = LatchDrawPic\r
371 =\r
372 =====================\r
373 */\r
374 \r
375 void LatchDrawPic (unsigned x, unsigned y, unsigned picnum)\r
376 {\r
377         unsigned wide, height, source;\r
378 \r
379         wide = pictable[picnum-STARTPICS].width;\r
380         height = pictable[picnum-STARTPICS].height;\r
381         source = latchpics[2+picnum-LATCHPICS_LUMP_START];\r
382 \r
383         VL_LatchToScreen (source,wide/4,height,x*8,y);\r
384 }\r
385 \r
386 \r
387 //==========================================================================\r
388 \r
389 /*\r
390 ===================\r
391 =\r
392 = LoadLatchMem\r
393 =\r
394 ===================\r
395 */\r
396 \r
397 void LoadLatchMem (void)\r
398 {\r
399         int     i,j,p,m,width,height,start,end;\r
400         byte    far *src;\r
401         unsigned        destoff;\r
402 \r
403 //\r
404 // tile 8s\r
405 //\r
406         latchpics[0] = freelatch;\r
407         CA_CacheGrChunk (STARTTILE8);\r
408         src = (byte _seg *)grsegs[STARTTILE8];\r
409         destoff = freelatch;\r
410 \r
411         for (i=0;i<NUMTILE8;i++)\r
412         {\r
413                 VL_MemToLatch (src,8,8,destoff);\r
414                 src += 64;\r
415                 destoff +=16;\r
416         }\r
417         UNCACHEGRCHUNK (STARTTILE8);\r
418 \r
419 #if 0   // ran out of latch space!\r
420 //\r
421 // tile 16s\r
422 //\r
423         src = (byte _seg *)grsegs[STARTTILE16];\r
424         latchpics[1] = destoff;\r
425 \r
426         for (i=0;i<NUMTILE16;i++)\r
427         {\r
428                 CA_CacheGrChunk (STARTTILE16+i);\r
429                 src = (byte _seg *)grsegs[STARTTILE16+i];\r
430                 VL_MemToLatch (src,16,16,destoff);\r
431                 destoff+=64;\r
432                 if (src)\r
433                         UNCACHEGRCHUNK (STARTTILE16+i);\r
434         }\r
435 #endif\r
436 \r
437 //\r
438 // pics\r
439 //\r
440         start = LATCHPICS_LUMP_START;\r
441         end = LATCHPICS_LUMP_END;\r
442 \r
443         for (i=start;i<=end;i++)\r
444         {\r
445                 latchpics[2+i-start] = destoff;\r
446                 CA_CacheGrChunk (i);\r
447                 width = pictable[i-STARTPICS].width;\r
448                 height = pictable[i-STARTPICS].height;\r
449                 VL_MemToLatch (grsegs[i],width,height,destoff);\r
450                 destoff += width/4 *height;\r
451                 UNCACHEGRCHUNK(i);\r
452         }\r
453 \r
454         EGAMAPMASK(15);\r
455 }\r
456 \r
457 //==========================================================================\r
458 \r
459 /*\r
460 ===================\r
461 =\r
462 = FizzleFade\r
463 =\r
464 = returns true if aborted\r
465 =\r
466 ===================\r
467 */\r
468 \r
469 extern  ControlInfo     c;\r
470 \r
471 boolean FizzleFade (unsigned source, unsigned dest,\r
472         unsigned width,unsigned height, unsigned frames, boolean abortable)\r
473 {\r
474         int                     pixperframe;\r
475         unsigned        drawofs,pagedelta;\r
476         byte            mask,maskb[8] = {1,2,4,8};\r
477         unsigned        x,y,p,frame;\r
478         long            rndval;\r
479 \r
480         pagedelta = dest-source;\r
481         rndval = 1;\r
482         y = 0;\r
483         pixperframe = 64000/frames;\r
484 \r
485         IN_StartAck ();\r
486 \r
487         TimeCount=frame=0;\r
488         do      // while (1)\r
489         {\r
490                 if (abortable && IN_CheckAck () )\r
491                         return true;\r
492 \r
493                 asm     mov     es,[screenseg]\r
494 \r
495                 for (p=0;p<pixperframe;p++)\r
496                 {\r
497                         //\r
498                         // seperate random value into x/y pair\r
499                         //\r
500                         asm     mov     ax,[WORD PTR rndval]\r
501                         asm     mov     dx,[WORD PTR rndval+2]\r
502                         asm     mov     bx,ax\r
503                         asm     dec     bl\r
504                         asm     mov     [BYTE PTR y],bl                 // low 8 bits - 1 = y xoordinate\r
505                         asm     mov     bx,ax\r
506                         asm     mov     cx,dx\r
507                         asm     mov     [BYTE PTR x],ah                 // next 9 bits = x xoordinate\r
508                         asm     mov     [BYTE PTR x+1],dl\r
509                         //\r
510                         // advance to next random element\r
511                         //\r
512                         asm     shr     dx,1\r
513                         asm     rcr     ax,1\r
514                         asm     jnc     noxor\r
515                         asm     xor     dx,0x0001\r
516                         asm     xor     ax,0x2000\r
517 noxor:\r
518                         asm     mov     [WORD PTR rndval],ax\r
519                         asm     mov     [WORD PTR rndval+2],dx\r
520 \r
521                         if (x>width || y>height)\r
522                                 continue;\r
523                         drawofs = source+ylookup[y] + (x>>2);\r
524 \r
525                         //\r
526                         // copy one pixel\r
527                         //\r
528                         mask = x&3;\r
529                         VGAREADMAP(mask);\r
530                         mask = maskb[mask];\r
531                         VGAMAPMASK(mask);\r
532 \r
533                         asm     mov     di,[drawofs]\r
534                         asm     mov     al,[es:di]\r
535                         asm add di,[pagedelta]\r
536                         asm     mov     [es:di],al\r
537 \r
538                         if (rndval == 1)                // entire sequence has been completed\r
539                                 return false;\r
540                 }\r
541                 frame++;\r
542                 while (TimeCount<frame)         // don't go too fast\r
543                 ;\r
544         } while (1);\r
545 \r
546 \r
547 }\r