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