#include #include #include //#include "r_public.h" #include "D_global.h" #include "d_disk.h" #include "R_refdef.h" int windowHeight = INIT_VIEW_HEIGHT; int windowWidth = INIT_VIEW_WIDTH; int windowLeft = (320-INIT_VIEW_WIDTH) >> 1; int windowTop = (200-INIT_VIEW_HEIGHT) >> 1; int windowSize = INIT_VIEW_HEIGHT*INIT_VIEW_WIDTH; int viewLocation = 0xA0000+VIEW_TOP*320+VIEW_LEFT; //============================================================= /* */ /*===================== */ /*= */ /*= RF_PreloadGraphics */ /*= */ /*===================== */ /* */ void RF_PreloadGraphics(void) { int i, x; byte *base; byte *wall; int size; // // find the number of lumps of each type // spritelump=CA_GetNamedNum("startsprites"); numsprites=CA_GetNamedNum("endsprites")-spritelump; walllump=CA_GetNamedNum("startwalls"); numwalls=CA_GetNamedNum("endwalls")-walllump; flatlump=CA_GetNamedNum("startflats"); numflats=CA_GetNamedNum("endflats")-flatlump; // // load the lumps // for (i=1; itilex=tilex; door->tiley=tiley; mapflags[tiley*MAPROWS+tilex] |= FL_DOOR; return door; } //========================================================== /* */ /*================ */ /*= */ /*= RF_GetSprite */ /*= */ /*= Return a free sprite structure that has been added to the end of */ /*= the active list */ /*= */ /*================ */ /* */ scaleobj_t *RF_GetSprite(void) { scaleobj_t *new; if (!freescaleobj_p) MS_Error("GetSprite: Out of spots in scaleobjlist!"); new=freescaleobj_p; freescaleobj_p=freescaleobj_p->next; memset(new, 0, sizeof(*new)); new->next=(scaleobj_t *)&lastscaleobj; new->prev=lastscaleobj.prev; lastscaleobj.prev=new; new->prev->next=new; return new; } //========================================================== /* */ /*====================*/ /*= */ /*= RF_RemoveSprite */ /*= */ /*= Unlink the sprite */ /*= from the active */ /*= list */ /*= */ /*====================*/ /* */ void RF_RemoveSprite(scaleobj_t *spr) { spr->next->prev=spr->prev; spr->prev->next=spr->next; memset(spr, 0, sizeof(spr)); spr->next=freescaleobj_p; freescaleobj_p=spr; } //========================================================== /* */ /*=====================*/ /*= */ /*= RF_GetFloorZ */ /*= */ /*=====================*/ /* */ fixed_t RF_GetFloorZ(fixed_t x, fixed_t y) { fixed_t h1, h2, h3, h4; int tilex, tiley, mapspot; int polytype; fixed_t fx, fy; fixed_t top, bottom; tilex=x>>(FRACBITS+TILESHIFT); tiley=y>>(FRACBITS+TILESHIFT); mapspot=tiley *MAPSIZE+tilex; polytype=(mapflags[mapspot]&FL_FLOOR)>>FLS_FLOOR; // // flat // if (polytype==POLY_FLAT) return floorheight[mapspot]<>6; // range from 0 to fracunit-1 fy=(y&(TILEUNIT-1))>>6; if (polytype==POLY_SLOPE) { if (h1==h2) // north/south slope return h1+FIXEDMUL(h3-h1, fy); else // east/west slope return h1+FIXEDMUL(h2-h1, fx); } // // triangulated slopes // // set the outside corner of the triangle that the point is NOT in s // plane with the other three if (polytype==POLY_ULTOLR) { if (fx>fy) h3=h1-(h2-h1); else h2=h1+(h1-h3); } else { if (fx>(FRACBITS+TILESHIFT); tiley=y>>(FRACBITS+TILESHIFT); mapspot=tiley *MAPSIZE+tilex; polytype=(mapflags[mapspot]&FL_CEILING)>>FLS_CEILING; // // flat // if (polytype==POLY_FLAT) return ceilingheight[mapspot]<>6; // range from 0 to fracunit-1 fy=(y&(TILEUNIT-1))>>6; if (polytype==POLY_SLOPE) { if (h1==h2) // north/south slope return h1+FIXEDMUL(h3-h1, fy); else // east/west slope return h1+FIXEDMUL(h2-h1, fx); } // // triangulated slopes // // set the outside corner of the triangle that the point is NOT in s // plane with the other three if (polytype==POLY_ULTOLR) { if (fx>fy) h3=h1-(h2-h1); else h2=h1+(h1-h3); } else { if (fxpicture; shapebottom=span_p->y; scale=FIXEDDIV(SCALE, pointz); fracstep=FIXEDMUL(pointz, ISCALE); sp_fracstep=fracstep; leftx=span_p->x2; leftx-=pic->leftoffset<>FRACBITS); if (x>sx) return false; // the sprite is to the right of the point deltascreen=sx-x; post=(fracstep *deltascreen)>>FRACBITS; if (post>=pic->width) return false; // the sprite is to the left of the point if (pointz>wallz[sx]) return false; // this post is obscured by a closer wall collumn=(byte *)pic+pic->collumnofs[post]; topheight=shapebottom+(*collumn<>FRACBITS); if (topy>sy) return false; // shape is below point bottomy=CENTERY-(FIXEDMUL(bottomheight, scale)>>FRACBITS); if (bottomy>FRACBITS; if (!collumn[posty]) return false; // point is in a transparent area id_type=id_sprite; id_structure=span_p->structure; return true; } /* */ /*========================*/ /*= =*/ /*= RF_PixelIdentity =*/ /*= =*/ /*= You can only call =*/ /*= this between frames, =*/ /*= not during an action =*/ /*= hook routine call =*/ /*= =*/ /*========================*/ /* */ void RF_PixelIdentity(int sx, int sy) { unsigned tag, *spantag_p; int spannum; span_t *span_p; int spanx; fixed_t pointz, length, fracstep; int deltay; int angle; // // scan the sorted span lists from closest to farthest // spantag_p=endtaglist_p-1; while (spantag_p>=starttaglist_p) { tag=*spantag_p--; spannum=tag&SPANMASK; span_p=&spans[spannum]; spanx=tag&XMASK; pointz=(tag&ZMASK)>>ZTOFRAC; if (span_p->spantype==sp_shape) { // check for intersection with the sprite's pixels if (CheckSpriteContact(span_p, pointz, sx, sy)) return; continue; } spanx=(spanx>>XSHIFT)^0x1ff; // invert back to regular x if ((span_p->spantype==sp_door)||(span_p->spantype==sp_maskeddoor)) { // if it got here, it didn't hit a floor or ceiling in front if (spanx!=sx) continue; id_type=id_door; id_structure=span_p->structure; return; } /// its just a floor/ ceiling span // check the extent of the span if (span_p->y!=sy||spanx>sx||span_p->x2<=sx) continue; if (tag&CEILINGBIT) id_type=id_ceiling; else id_type=id_floor; angle=viewfineangle+pixelangle[sx]; angle&=TANANGLES *4-1; length=FIXEDDIV(pointz, pixelcosine[sx]); id_px=viewx+FIXEDMUL(length, cosines[angle]); id_py=viewy-FIXEDMUL(length, sines[angle]); return; } // // if there is a wall post at sx, the click was somewhere in it // if (wallz[sx]==MAXZ+1) { // didn't click on anything id_type=id_empty; return; } id_type=id_wall; id_tilex=wallnumber[sx]>>17; id_tiley=(wallnumber[sx]>>2)&63; id_side=wallnumber[sx]&3; id_px=walltexture[sx]; deltay=sy-walltopy[sx]; fracstep=FIXEDMUL(wallz[sx], ISCALEFUDGE); id_py=(deltay *fracstep)>>FRACBITS; if (id_py<0) id_py=0; } /* */ /*=====================*/ /*= */ /*= RF_SetLights */ /*= */ /*= Spreads the light */ /*= translation tables */ /*= from 0 - MAXZ, with*/ /*= the black point at */ /*= blackz. It is OK to*/ /*= have blackz>MAXZ, */ /*= things will be */ /*= brighter when they */ /*= appear */ /*=====================*/ /* */ void RF_SetLights(fixed_t blackz) { // linear diminishing int i; int table; blackz>>=FRACBITS; for (i=0; i<=MAXZ>>FRACBITS; i++) { table=numcolormaps *i/blackz; if (table>=numcolormaps) table=numcolormaps-1; zcolormap[i]=colormaps+table *256; } } //========================================================== /* */ /*===================== */ /*= */ /*= RF_CheckActionFlag */ /*= */ /*===================== */ /* */ void RF_CheckActionFlag(void) { if (!actionflag) return; if (!actionhook) MS_Error("RF_CheckActionFlag: Actionhook not set"); actionhook(); actionflag=0; } /* */ /*===================== */ /*= */ /*= RF_SetActionHook */ /*= */ /*===================== */ /* */ void RF_SetActionHook(void (*hook)(void)) { actionhook=hook; } //========================================================== /* */ /*=============== */ /*= */ /*= RF_RenderView */ /*= */ /*=============== */ /* */ void RF_RenderView(fixed_t x, fixed_t y, fixed_t z, int angle, byte showBlast) { if ((x<=0)||(x>=((MAPSIZE-1)<<(FRACBITS+TILESHIFT)))||(y<=0)|| (y>=((MAPSIZE-1)<<(FRACBITS+TILESHIFT))||angle<0||angle>=ANGLES)) MS_Error("Invalid RF_RenderView (%p, %p, %p, %i)\n", x, y, z, angle); viewx=(x&~0xfff) + 0x800; viewy=(y&~0xfff) + 0x800; viewz=(z&~0xfff) + 0x800; viewangle=angle; SetupFrame(); RF_CheckActionFlag(); FlowView(x,y); RF_CheckActionFlag(); RenderSprites(x, y, z, angle, showBlast); RF_CheckActionFlag(); DrawSpans(); RF_CheckActionFlag(); } void SetViewSize(int width, int height) { int i; if (width>MAX_VIEW_WIDTH) width = MAX_VIEW_WIDTH; if (height>MAX_VIEW_HEIGHT) height = MAX_VIEW_HEIGHT; windowHeight = height; windowWidth = width; windowSize = width*height; for (i=0;i