/***************************************************************************/ /* */ /* */ /* Raven 3D Engine */ /* Copyright (C) 1996 by Softdisk Publishing */ /* */ /* Original Design: */ /* John Carmack of id Software */ /* */ /* Enhancements by: */ /* Robert Morgan of Channel 7............................Main Engine Code */ /* Todd Lewis of Softdisk Publishing......Tools,Utilities,Special Effects */ /* John Bianca of Softdisk Publishing..............Low-level Optimization */ /* Carlos Hasan..........................................Music/Sound Code */ /* */ /* */ /***************************************************************************/ #include #include #include #include "d_global.h" #include "d_disk.h" #include "r_refdef.h" #include "protos.h" #include "d_ints.h" #include "audio.h" /**** VARIABLES ****/ int windowHeight = INIT_VIEW_HEIGHT; int windowWidth = INIT_VIEW_WIDTH; int windowLeft = 0; int windowTop = 0; int windowSize = INIT_VIEW_HEIGHT*INIT_VIEW_WIDTH; int viewLocation=0xA0000; fixed_t CENTERX=INIT_VIEW_WIDTH/2; fixed_t CENTERY=INIT_VIEW_HEIGHT/2; fixed_t SCALE; fixed_t ISCALE; int backtangents[TANANGLES*2]; int autoangle2[MAXAUTO][MAXAUTO]; int scrollmin, scrollmax, bloodcount, metalcount; extern SoundCard SC; /**** FUNCTIONS ****/ void r_publicstub2(void); void RF_PreloadGraphics(void) { int i; int doorlump; // 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; doorlump=CA_GetNamedNum("door_1"); printf("."); // load the lumps for (i=1; i>FRACBITS; y1=y>>FRACBITS; if (x1>=MAXAUTO || y1>=MAXAUTO || autoangle2[x1][y1]!=-1) continue; autoangle2[x1][y1]=angle; } i++; } while (angle0;i--) for(j=0;j0;i--) for(j=0;j>FRACBITS; } void InitReverseCam(void) { int i, intval; for (i=0;i<65; i++) { intval=rint(atan(((double)32-((double)i+1.0))/(double)32)/(double)PI*(double)TANANGLES*(double)2); pixelangle[i]=intval; pixelcosine[i]=cosines[intval&(TANANGLES * 4 - 1)]; } memcpy(campixelangle,pixelangle,sizeof(pixelangle)); memcpy(campixelcosine,pixelcosine,sizeof(pixelcosine)); } void RF_Startup(void) { int i; double angle; int lightlump; lock_region((void near *)RF_GetFloorZ,(char *)r_publicstub2 - (char near *)RF_GetFloorZ); lock_region(&actionhook,sizeof(actionhook)); lock_region(&actionflag,sizeof(actionflag)); memset(framevalid, 0, sizeof(framevalid)); printf("."); frameon=0; // trig tables for (i=0; i<=ANGLES; i++) { angle=(double)(i * PI * 2)/(double)(ANGLES + 1); sintable[i]=rint(sin(angle)*FRACUNIT); costable[i]=rint(cos(angle)*FRACUNIT); } printf("."); SetViewSize(windowWidth,windowHeight); // set up lights // Allocates a page aligned buffer and load in the light tables lightlump=CA_GetNamedNum("lights"); numcolormaps=infotable[lightlump].size/256; colormaps=malloc((size_t)256*(numcolormaps+1)); colormaps=(byte *)(((int)colormaps+255)&~0xff); CA_ReadLump(lightlump, colormaps); RF_SetLights((fixed_t)MAXZ); RF_ClearWorld(); printf("."); // initialize the translation to no animation flattranslation=malloc((size_t)(numflats+1)*4); walltranslation=malloc((size_t)(numwalls+1)*4); if (!debugmode) { for(i=0;i<=numflats;i++) flattranslation[i]=i; for(i=0;i<=numwalls;i++) walltranslation[i]=i; } else { for(i=1;i<=numflats;i++) flattranslation[i]=1; for(i=1;i<=numwalls;i++) walltranslation[i]=1; flattranslation[0]=0; walltranslation[0]=0; } actionhook=NULL; actionflag=0; RF_InitTargets(); InitTables(); printf("."); InitReverseCam(); InitWalls(); printf("."); } void RF_ClearWorld(void) { int i; firstscaleobj.prev=NULL; firstscaleobj.next=&lastscaleobj; lastscaleobj.prev=&firstscaleobj; lastscaleobj.next=NULL; freescaleobj_p=scaleobjlist; memset(scaleobjlist,0,sizeof(scaleobjlist)); for(i=0;itilex=tilex; door->tiley=tiley; mapflags[tiley*MAPROWS+tilex] |= FL_DOOR; return door; } scaleobj_t *RF_GetSprite(void) /* returns a new sprite */ { scaleobj_t *new; if (!freescaleobj_p) MS_Error("RF_GetSprite: Out of spots in scaleobjlist!"); new=freescaleobj_p; freescaleobj_p=freescaleobj_p->next; memset(new,0,sizeof(scaleobj_t)); new->next=(scaleobj_t *)&lastscaleobj; new->prev=lastscaleobj.prev; lastscaleobj.prev=new; new->prev->next=new; return new; } elevobj_t *RF_GetElevator(void) /* returns a elevator structure */ { elevobj_t *new; if (!freeelevobj_p) MS_Error("RF_GetElevator: Too many elevators placed!"); new=freeelevobj_p; freeelevobj_p=freeelevobj_p->next; memset(new,0,sizeof(elevobj_t)); new->next=(elevobj_t *)&lastelevobj; new->prev=lastelevobj.prev; lastelevobj.prev=new; new->prev->next=new; return new; } spawnarea_t *RF_GetSpawnArea(void) { if (numspawnareas==MAXSPAWNAREAS) MS_Error("RF_GetSpawnArea: Too many Spawn Areas placed! (%i,%i)",numspawnareas,MAXSPAWNAREAS); ++numspawnareas; return &spawnareas[numspawnareas-1]; } void Event(int e,boolean send); void RF_RemoveSprite(scaleobj_t *spr) /* removes sprite from doublely linked list of sprites */ { spr->next->prev=spr->prev; spr->prev->next=spr->next; spr->next=freescaleobj_p; freescaleobj_p=spr; } void RF_RemoveElevator(elevobj_t *e) { e->next->prev=e->prev; e->prev->next=e->next; e->next=freeelevobj_p; freeelevobj_p=e; } 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, water; tilex=x>>(FRACBITS+TILESHIFT); tiley=y>>(FRACBITS+TILESHIFT); mapspot=tiley *MAPSIZE+tilex; polytype=(mapflags[mapspot]&FL_FLOOR)>>FLS_FLOOR; if (floorpic[mapspot]>=57 && floorpic[mapspot]<=59) water=-(20<>6; // range from 0 to fracunit-1 fy=(y&(TILEUNIT-1))>>6; if (polytype==POLY_SLOPE) { if (h1==h2) return h1+FIXEDMUL(h3-h1, fy) + water; else return h1+FIXEDMUL(h2-h1, fx) + water; } // 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; return h1+FIXEDMUL(h3-h1, fy); // north/south slope } else { fx=(x&(TILEUNIT-1))>>6; return h1+FIXEDMUL(h2-h1, fx); // east/west slope } } // triangulated slopes // set the outside corner of the triangle that the point is NOT in s // plane with the other three h1=ceilingheight[mapspot]<>6; // range from 0 to fracunit-1 fy=(y&(TILEUNIT-1))>>6; if (polytype==POLY_ULTOLR) { if (fx>fy) h3=h1-(h2-h1); else h2=h1+(h1-h3); } else { if (fx>=FRACBITS; for (i=0;i<=MAXZ>>FRACBITS;i++) { table=numcolormaps * i/blackz; if (table>=numcolormaps) table=numcolormaps-1; zcolormap[i]=colormaps+table*256; } } void RF_CheckActionFlag(void) { if (SC.vrhelmet==0) TimeUpdate(); if (!actionflag) return; actionhook(); actionflag=0; } void RF_RenderView(fixed_t x, fixed_t y, fixed_t z, int angle) { //#ifdef VALIDATE // if (x<=0 || x>=((MAPSIZE-1)<<(FRACBITS+TILESHIFT)) || y<=0 || // y>=((MAPSIZE-1)<<(FRACBITS+TILESHIFT))) // MS_Error("Invalid RF_RenderView (%p, %p, %p, %i)\n", x, y, z, angle); //#endif // viewx=(x&~0xfff) + 0x800; // viewy=(y&~0xfff) + 0x800; // viewz=(z&~0xfff) + 0x800; viewx=x; viewy=y; viewz=z; viewangle=angle&ANGLES; RF_CheckActionFlag(); SetupFrame(); RF_CheckActionFlag(); FlowView(); RF_CheckActionFlag(); RenderSprites(); 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; scrollmax=windowHeight+scrollmin; CENTERX=width/2; CENTERY=height/2; SCALE=(width/2)<>FRACBITS; hfrac=FIXEDDIV(BACKDROPHEIGHT<