From d5563fe478ade2cb9384db01eaf5d0292482df8b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 8 May 2008 08:06:26 +0000 Subject: [PATCH] - Changed all thing coordinates that were stored as shorts into fixed_t. - Separated mapthing2_t into mapthinghexen_t and the internal FMapThing so that it is easier to add new features in the UDMF map format. - Added some initial code to read UDMF maps. SVN r956 (trunk) --- docs/rh-log.txt | 6 + src/actor.h | 2 +- src/doomdata.h | 39 +++++- src/doomstat.h | 4 +- src/g_game.cpp | 26 ++-- src/g_hexen/a_teleportother.cpp | 8 +- src/g_raven/a_artitele.cpp | 8 +- src/g_shared/a_pickups.cpp | 8 +- src/g_shared/a_puzzleitems.cpp | 11 +- src/namedef.h | 32 +++++ src/p_buildmap.cpp | 28 ++-- src/p_conversation.cpp | 48 ++++--- src/p_conversation.h | 4 +- src/p_local.h | 2 +- src/p_mobj.cpp | 48 ++++--- src/p_setup.cpp | 212 ++++++++++++++++++++---------- src/p_slopes.cpp | 24 ++-- src/p_writemap.cpp | 2 +- src/thingdef/thingdef_codeptr.cpp | 4 +- 19 files changed, 343 insertions(+), 173 deletions(-) diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 25c1b91af..5f3617dd3 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,9 @@ +May 8, 2008 (Changes by Graf Zahl) +- Changed all thing coordinates that were stored as shorts into fixed_t. +- Separated mapthing2_t into mapthinghexen_t and the internal FMapThing so + that it is easier to add new features in the UDMF map format. +- Added some initial code to read UDMF maps. + May 2, 2008 (Changes by Graf Zahl) - Split off the slope creation code from p_Setup.cpp into its own file. - Separated the linedef activation types into a bit mask that allows combination diff --git a/src/actor.h b/src/actor.h index 606e2be8f..91bd90d45 100644 --- a/src/actor.h +++ b/src/actor.h @@ -665,7 +665,7 @@ public: // no matter what (even if shot) player_s *player; // only valid if type of APlayerPawn TObjPtr LastLookActor; // Actor last looked for (if TIDtoHate != 0) - WORD SpawnPoint[3]; // For nightmare respawn + fixed_t SpawnPoint[3]; // For nightmare respawn WORD SpawnAngle; int skillrespawncount; TObjPtr tracer; // Thing being chased/attacked for tracers diff --git a/src/doomdata.h b/src/doomdata.h index d2b68d322..10a0cb0e6 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -29,6 +29,7 @@ // Some global defines, that configure the game. #include "doomdef.h" +#include "m_swap.h" @@ -55,12 +56,16 @@ enum ML_BLOCKMAP, // LUT, motion clipping, walls/grid element ML_BEHAVIOR, // [RH] Hexen-style scripts. If present, THINGS // and LINEDEFS are also Hexen-style. + ML_CONVERSATION, // Strife dialog (only for TEXTMAP format) ML_MAX, // [RH] These are compressed (and extended) nodes. They combine the data from // vertexes, segs, ssectors, and nodes into a single lump. ML_ZNODES = ML_NODES, - ML_GLZNODES = ML_SSECTORS + ML_GLZNODES = ML_SSECTORS, + + // for text map format + ML_TEXTMAP = ML_THINGS, }; @@ -248,7 +253,7 @@ typedef struct } mapthing_t; // [RH] Hexen-compatible MapThing. -typedef struct MapThing +typedef struct { unsigned short thingid; short x; @@ -259,9 +264,37 @@ typedef struct MapThing short flags; BYTE special; BYTE args[5]; +} mapthinghexen_t; + +// Internal representation of a mapthing +struct FMapThing +{ + unsigned short thingid; + fixed_t x; + fixed_t y; + fixed_t z; + short angle; + short type; + short flags; + short special; + int args[5]; void Serialize (FArchive &); -} mapthing2_t; + + FMapThing &operator =(mapthinghexen_t &mt) + { + thingid = mt.thingid; + x = LittleShort(mt.x)< deathmatchstarts; +extern TArray deathmatchstarts; // Player spawn spots. -extern mapthing2_t playerstarts[MAXPLAYERS]; +extern FMapThing playerstarts[MAXPLAYERS]; // Intermission stats. // Parameters for world map / intermission. diff --git a/src/g_game.cpp b/src/g_game.cpp index b87322148..5db3eb0c3 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1236,20 +1236,20 @@ void G_PlayerReborn (int player) // // G_CheckSpot // Returns false if the player cannot be respawned -// at the given mapthing2_t spot +// at the given mapthing spot // because something is occupying it // -bool G_CheckSpot (int playernum, mapthing2_t *mthing) +bool G_CheckSpot (int playernum, FMapThing *mthing) { fixed_t x; fixed_t y; fixed_t z, oldz; int i; - x = mthing->x << FRACBITS; - y = mthing->y << FRACBITS; - z = mthing->z << FRACBITS; + x = mthing->x; + y = mthing->y; + z = mthing->z; z += P_PointInSector (x, y)->floorplane.ZatPoint (x, y); @@ -1288,8 +1288,8 @@ bool G_CheckSpot (int playernum, mapthing2_t *mthing) // called at level load and each death // -// [RH] Returns the distance of the closest player to the given mapthing2_t. -static fixed_t PlayersRangeFromSpot (mapthing2_t *spot) +// [RH] Returns the distance of the closest player to the given mapthing +static fixed_t PlayersRangeFromSpot (FMapThing *spot) { fixed_t closest = INT_MAX; fixed_t distance; @@ -1300,8 +1300,8 @@ static fixed_t PlayersRangeFromSpot (mapthing2_t *spot) if (!playeringame[i] || !players[i].mo || players[i].health <= 0) continue; - distance = P_AproxDistance (players[i].mo->x - spot->x * FRACUNIT, - players[i].mo->y - spot->y * FRACUNIT); + distance = P_AproxDistance (players[i].mo->x - spot->x, + players[i].mo->y - spot->y); if (distance < closest) closest = distance; @@ -1311,10 +1311,10 @@ static fixed_t PlayersRangeFromSpot (mapthing2_t *spot) } // [RH] Select the deathmatch spawn spot farthest from everyone. -static mapthing2_t *SelectFarthestDeathmatchSpot (size_t selections) +static FMapThing *SelectFarthestDeathmatchSpot (size_t selections) { fixed_t bestdistance = 0; - mapthing2_t *bestspot = NULL; + FMapThing *bestspot = NULL; unsigned int i; for (i = 0; i < selections; i++) @@ -1332,7 +1332,7 @@ static mapthing2_t *SelectFarthestDeathmatchSpot (size_t selections) } // [RH] Select a deathmatch spawn spot at random (original mechanism) -static mapthing2_t *SelectRandomDeathmatchSpot (int playernum, unsigned int selections) +static FMapThing *SelectRandomDeathmatchSpot (int playernum, unsigned int selections) { unsigned int i, j; @@ -1352,7 +1352,7 @@ static mapthing2_t *SelectRandomDeathmatchSpot (int playernum, unsigned int sele void G_DeathMatchSpawnPlayer (int playernum) { unsigned int selections; - mapthing2_t *spot; + FMapThing *spot; selections = deathmatchstarts.Size (); // [RH] We can get by with just 1 deathmatch start diff --git a/src/g_hexen/a_teleportother.cpp b/src/g_hexen/a_teleportother.cpp index 2a0cd8b58..8a9342e37 100644 --- a/src/g_hexen/a_teleportother.cpp +++ b/src/g_hexen/a_teleportother.cpp @@ -279,8 +279,8 @@ void P_TeleportToPlayerStarts (AActor *victim) selections++; } i = pr_telestarts() % selections; - destX = playerstarts[i].x << FRACBITS; - destY = playerstarts[i].y << FRACBITS; + destX = playerstarts[i].x; + destY = playerstarts[i].y; destAngle = ANG45 * (playerstarts[i].angle/45); P_Teleport (victim, destX, destY, ONFLOORZ, destAngle, true, true, false); } @@ -301,8 +301,8 @@ void P_TeleportToDeathmatchStarts (AActor *victim) if (selections > 0) { i = pr_teledm() % selections; - destX = deathmatchstarts[i].x << FRACBITS; - destY = deathmatchstarts[i].y << FRACBITS; + destX = deathmatchstarts[i].x; + destY = deathmatchstarts[i].y; destAngle = ANG45 * (deathmatchstarts[i].angle/45); P_Teleport (victim, destX, destY, ONFLOORZ, destAngle, true, true, false); } diff --git a/src/g_raven/a_artitele.cpp b/src/g_raven/a_artitele.cpp index 6e0411353..679f08e06 100644 --- a/src/g_raven/a_artitele.cpp +++ b/src/g_raven/a_artitele.cpp @@ -48,14 +48,14 @@ bool AArtiTeleport::Use (bool pickup) { unsigned int selections = deathmatchstarts.Size (); unsigned int i = pr_tele() % selections; - destX = deathmatchstarts[i].x << FRACBITS; - destY = deathmatchstarts[i].y << FRACBITS; + destX = deathmatchstarts[i].x; + destY = deathmatchstarts[i].y; destAngle = ANG45 * (deathmatchstarts[i].angle/45); } else { - destX = playerstarts[Owner->player - players].x << FRACBITS; - destY = playerstarts[Owner->player - players].y << FRACBITS; + destX = playerstarts[Owner->player - players].x; + destY = playerstarts[Owner->player - players].y; destAngle = ANG45 * (playerstarts[Owner->player - players].angle/45); } P_Teleport (Owner, destX, destY, ONFLOORZ, destAngle, true, true, false); diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index 5e4ed73d2..48acdb550 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -332,8 +332,8 @@ void A_RestoreSpecialPosition (AActor *self) fixed_t _x, _y; sector_t *sec; - _x = self->SpawnPoint[0] << FRACBITS; - _y = self->SpawnPoint[1] << FRACBITS; + _x = self->SpawnPoint[0]; + _y = self->SpawnPoint[1]; sec = P_PointInSector (_x, _y); self->SetOrigin (_x, _y, sec->floorplane.ZatPoint (_x, _y)); @@ -341,7 +341,7 @@ void A_RestoreSpecialPosition (AActor *self) if (self->flags & MF_SPAWNCEILING) { - self->z = self->ceilingz - self->height - (self->SpawnPoint[2] << FRACBITS); + self->z = self->ceilingz - self->height - self->SpawnPoint[2]; } else if (self->flags2 & MF2_SPAWNFLOAT) { @@ -358,7 +358,7 @@ void A_RestoreSpecialPosition (AActor *self) } else { - self->z = (self->SpawnPoint[2] << FRACBITS) + self->floorz; + self->z = self->SpawnPoint[2] + self->floorz; if (self->flags2 & MF2_FLOATBOB) { self->z += FloatBobOffsets[(self->FloatBobPhase + level.maptime) & 63]; diff --git a/src/g_shared/a_puzzleitems.cpp b/src/g_shared/a_puzzleitems.cpp index 3fbd80b82..69c2cb0e4 100644 --- a/src/g_shared/a_puzzleitems.cpp +++ b/src/g_shared/a_puzzleitems.cpp @@ -39,10 +39,13 @@ bool APuzzleItem::Use (bool pickup) } // [RH] Always play the sound if the use fails. S_Sound (Owner, CHAN_VOICE, "*puzzfail", 1, ATTN_IDLE); - const char *message = GetClass()->Meta.GetMetaString (AIMETA_PuzzFailMessage); - if (message != NULL && *message=='$') message = GStrings[message + 1]; - if (message == NULL) message = GStrings("TXT_USEPUZZLEFAILED"); - C_MidPrintBold (message); + if (Owner != NULL && Owner->CheckLocalView (consoleplayer)) + { + const char *message = GetClass()->Meta.GetMetaString (AIMETA_PuzzFailMessage); + if (message != NULL && *message=='$') message = GStrings[message + 1]; + if (message == NULL) message = GStrings("TXT_USEPUZZLEFAILED"); + C_MidPrintBold (message); + } return false; } diff --git a/src/namedef.h b/src/namedef.h index 24bab95c2..5f58d7c88 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -220,3 +220,35 @@ xx(MapSpot) xx(PatrolPoint) xx(PatrolSpecial) xx(Communicator) + +// Textmap properties +//xx(X) +//xx(Y) +//xx(Z) +//xx(Tid) +//xx(Angle) +xx(Type) +//xx(Special) +xx(Arg0) +xx(Arg1) +xx(Arg2) +xx(Arg3) +xx(Arg4) +xx(Id) +xx(V1) +xx(V2) +xx(Frontside) +xx(Backside) +xx(Offsetx) +xx(Offsety) +xx(Texturetop) +xx(Texturebottom) +xx(Texturemiddle) +xx(Sector) +xx(Floorheight) +xx(Ceilingheight) +xx(Lightlevel) +xx(Tag) +xx(Floorpic) +xx(Ceilingpic) + diff --git a/src/p_buildmap.cpp b/src/p_buildmap.cpp index 96e954677..c2319f7a8 100644 --- a/src/p_buildmap.cpp +++ b/src/p_buildmap.cpp @@ -124,12 +124,12 @@ void P_AdjustLine (line_t *line); // PRIVATE FUNCTION PROTOTYPES --------------------------------------------- -static bool P_LoadBloodMap (BYTE *data, size_t len, mapthing2_t **sprites, int *numsprites); +static bool P_LoadBloodMap (BYTE *data, size_t len, FMapThing **sprites, int *numsprites); static void LoadSectors (sectortype *bsectors); static void LoadWalls (walltype *walls, int numwalls, sectortype *bsectors); -static int LoadSprites (spritetype *sprites, int numsprites, sectortype *bsectors, mapthing2_t *mapthings); +static int LoadSprites (spritetype *sprites, int numsprites, sectortype *bsectors, FMapThing *mapthings); static vertex_t *FindVertex (fixed_t x, fixed_t y); -static void CreateStartSpot (fixed_t *pos, mapthing2_t *start); +static void CreateStartSpot (fixed_t *pos, FMapThing *start); static void CalcPlane (SlopeWork &slope, secplane_t &plane); static void Decrypt (void *to, const void *from, int len, int key); @@ -147,7 +147,7 @@ static void Decrypt (void *to, const void *from, int len, int key); // //========================================================================== -bool P_LoadBuildMap (BYTE *data, size_t len, mapthing2_t **sprites, int *numspr) +bool P_LoadBuildMap (BYTE *data, size_t len, FMapThing **sprites, int *numspr) { if (len < 26) { @@ -178,7 +178,7 @@ bool P_LoadBuildMap (BYTE *data, size_t len, mapthing2_t **sprites, int *numspr) (sectortype *)(data + 22)); numsprites = *(WORD *)(data + 24 + numsectors*sizeof(sectortype) + numwalls*sizeof(walltype)); - *sprites = new mapthing2_t[numsprites + 1]; + *sprites = new FMapThing[numsprites + 1]; CreateStartSpot ((fixed_t *)(data + 4), *sprites); *numspr = 1 + LoadSprites ((spritetype *)(data + 26 + numsectors*sizeof(sectortype) + numwalls*sizeof(walltype)), numsprites, (sectortype *)(data + 22), *sprites + 1); @@ -192,7 +192,7 @@ bool P_LoadBuildMap (BYTE *data, size_t len, mapthing2_t **sprites, int *numspr) // //========================================================================== -static bool P_LoadBloodMap (BYTE *data, size_t len, mapthing2_t **mapthings, int *numspr) +static bool P_LoadBloodMap (BYTE *data, size_t len, FMapThing **mapthings, int *numspr) { BYTE infoBlock[37]; int mapver = data[5]; @@ -303,7 +303,7 @@ static bool P_LoadBloodMap (BYTE *data, size_t len, mapthing2_t **mapthings, int // BUILD info from the map we need. (Sprites are ignored.) LoadSectors (bsec); LoadWalls (bwal, numWalls, bsec); - *mapthings = new mapthing2_t[numsprites + 1]; + *mapthings = new FMapThing[numsprites + 1]; CreateStartSpot ((fixed_t *)infoBlock, *mapthings); *numspr = 1 + LoadSprites (bspr, numsprites, bsec, *mapthings + 1); @@ -606,7 +606,7 @@ static void LoadWalls (walltype *walls, int numwalls, sectortype *bsec) //========================================================================== static int LoadSprites (spritetype *sprites, int numsprites, sectortype *bsectors, - mapthing2_t *mapthings) + FMapThing *mapthings) { char name[9]; int picnum; @@ -621,9 +621,9 @@ static int LoadSprites (spritetype *sprites, int numsprites, sectortype *bsector picnum = TexMan.GetTexture (name, FTexture::TEX_Build); mapthings[count].thingid = 0; - mapthings[count].x = (short)(sprites[i].x >> 4); - mapthings[count].y = -(short)(sprites[i].y >> 4); - mapthings[count].z = (short)((bsectors[sprites[i].sectnum].floorz - sprites[i].z) >> 8); + mapthings[count].x = (sprites[i].x << 12); + mapthings[count].y = -(sprites[i].y << 12); + mapthings[count].z = (bsectors[sprites[i].sectnum].floorz - sprites[i].z) << 8; mapthings[count].angle = (((2048-sprites[i].ang) & 2047) * 360) >> 11; mapthings[count].type = 9988; mapthings[count].flags = MTF_FIGHTER|MTF_CLERIC|MTF_MAGE|MTF_SINGLE|MTF_COOPERATIVE|MTF_DEATHMATCH|MTF_EASY|MTF_NORMAL|MTF_HARD; @@ -671,12 +671,12 @@ vertex_t *FindVertex (fixed_t x, fixed_t y) // //========================================================================== -static void CreateStartSpot (fixed_t *pos, mapthing2_t *start) +static void CreateStartSpot (fixed_t *pos, FMapThing *start) { short angle = LittleShort(*(WORD *)(&pos[3])); - mapthing2_t mt = + FMapThing mt = { - 0, short(LittleLong(pos[0])>>4), short((-LittleLong(pos[1]))>>4), 0,// tid, x, y, z + 0, (LittleLong(pos[0])<<12), ((-LittleLong(pos[1]))<<12), 0,// tid, x, y, z short(Scale ((2048-angle)&2047, 360, 2048)), 1, // angle, type 7|MTF_SINGLE|224, // flags // special and args are 0 diff --git a/src/p_conversation.cpp b/src/p_conversation.cpp index ec4f86e20..7a4e22d72 100644 --- a/src/p_conversation.cpp +++ b/src/p_conversation.cpp @@ -51,6 +51,7 @@ #include "p_enemy.h" #include "gstrings.h" #include "sound/i_music.h" +#include "p_setup.h" // The conversations as they exist inside a SCRIPTxx lump. struct Response @@ -107,8 +108,9 @@ static int ConversationPauseTic; static bool ShowGold; static void LoadScriptFile (const char *name); -static FStrifeDialogueNode *ReadRetailNode (FWadLump *lump, DWORD &prevSpeakerType); -static FStrifeDialogueNode *ReadTeaserNode (FWadLump *lump, DWORD &prevSpeakerType); +static void LoadScriptFile(FileReader *lump, int numnodes); +static FStrifeDialogueNode *ReadRetailNode (FileReader *lump, DWORD &prevSpeakerType); +static FStrifeDialogueNode *ReadTeaserNode (FileReader *lump, DWORD &prevSpeakerType); static void ParseReplies (FStrifeDialogueReply **replyptr, Response *responses); static void DrawConversationMenu (); static void PickConversationReply (); @@ -148,16 +150,25 @@ static const PClass *GetStrifeType (int typenum) // //============================================================================ -void P_LoadStrifeConversations (const char *mapname) +void P_LoadStrifeConversations (MapData *map, const char *mapname) { - if (strnicmp (mapname, "MAP", 3) != 0) + if (map->Size(ML_CONVERSATION) > 0) { - return; + LoadScriptFile ("SCRIPT00"); + map->Seek(ML_CONVERSATION); + LoadScriptFile (map->file, map->Size(ML_CONVERSATION)); } - char scriptname[9] = { 'S','C','R','I','P','T',mapname[3],mapname[4],0 }; + else + { + if (strnicmp (mapname, "MAP", 3) != 0) + { + return; + } + char scriptname[9] = { 'S','C','R','I','P','T',mapname[3],mapname[4],0 }; - LoadScriptFile ("SCRIPT00"); - LoadScriptFile (scriptname); + LoadScriptFile ("SCRIPT00"); + LoadScriptFile (scriptname); + } } //============================================================================ @@ -216,17 +227,23 @@ static char *ncopystring (const char *string) static void LoadScriptFile (const char *name) { int lumpnum = Wads.CheckNumForName (name); - int numnodes, i; - DWORD prevSpeakerType; - FStrifeDialogueNode *node; - FWadLump *lump; + FileReader *lump; if (lumpnum < 0) { return; } + lump = Wads.ReopenLumpNum (lumpnum); + + LoadScriptFile(lump, Wads.LumpLength(lumpnum)); +} + +static void LoadScriptFile(FileReader *lump, int numnodes) +{ + int i; + DWORD prevSpeakerType; + FStrifeDialogueNode *node; - numnodes = Wads.LumpLength (lumpnum); if (!(gameinfo.flags & GI_SHAREWARE)) { // Strife scripts are always a multiple of 1516 bytes because each entry @@ -247,7 +264,6 @@ static void LoadScriptFile (const char *name) numnodes /= 1488; } - lump = Wads.ReopenLumpNum (lumpnum); prevSpeakerType = 0; for (i = 0; i < numnodes; ++i) @@ -273,7 +289,7 @@ static void LoadScriptFile (const char *name) // //============================================================================ -static FStrifeDialogueNode *ReadRetailNode (FWadLump *lump, DWORD &prevSpeakerType) +static FStrifeDialogueNode *ReadRetailNode (FileReader *lump, DWORD &prevSpeakerType) { FStrifeDialogueNode *node; Speech speech; @@ -343,7 +359,7 @@ static FStrifeDialogueNode *ReadRetailNode (FWadLump *lump, DWORD &prevSpeakerTy // //============================================================================ -static FStrifeDialogueNode *ReadTeaserNode (FWadLump *lump, DWORD &prevSpeakerType) +static FStrifeDialogueNode *ReadTeaserNode (FileReader *lump, DWORD &prevSpeakerType) { FStrifeDialogueNode *node; TeaserSpeech speech; diff --git a/src/p_conversation.h b/src/p_conversation.h index bf270efbf..10e2ed90c 100644 --- a/src/p_conversation.h +++ b/src/p_conversation.h @@ -65,7 +65,9 @@ extern TArray StrifeDialogues; // initialized as part of the actor's setup in infodefaults.cpp. extern const PClass *StrifeTypes[1001]; -void P_LoadStrifeConversations (const char *mapname); +struct MapData; + +void P_LoadStrifeConversations (MapData *map, const char *mapname); void P_FreeStrifeConversations (); void P_StartConversation (AActor *npc, AActor *pc, bool facetalker, bool saveangle); diff --git a/src/p_local.h b/src/p_local.h index 2e6dd3a4b..6d668ce55 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -87,7 +87,7 @@ void P_UnPredictPlayer (); extern fixed_t FloatBobOffsets[64]; -APlayerPawn *P_SpawnPlayer (mapthing2_t* mthing, bool tempplayer=false); +APlayerPawn *P_SpawnPlayer (FMapThing *mthing, bool tempplayer=false); void P_ThrustMobj (AActor *mo, angle_t angle, fixed_t move); int P_FaceMobj (AActor *source, AActor *target, angle_t *delta); diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index b0f8aa683..6512686d5 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -414,7 +414,7 @@ void AActor::Serialize (FArchive &arc) } } -void MapThing::Serialize (FArchive &arc) +void FMapThing::Serialize (FArchive &arc) { arc << thingid << x << y << z << angle << type << flags << special << args[0] << args[1] << args[2] << args[3] << args[4]; @@ -2185,19 +2185,19 @@ void P_NightmareRespawn (AActor *mobj) else if (info->flags2 & MF2_SPAWNFLOAT) z = FLOATRANDZ; else if (info->flags2 & MF2_FLOATBOB) - z = mobj->SpawnPoint[2] << FRACBITS; + z = mobj->SpawnPoint[2]; else z = ONFLOORZ; // spawn it - x = mobj->SpawnPoint[0] << FRACBITS; - y = mobj->SpawnPoint[1] << FRACBITS; + x = mobj->SpawnPoint[0]; + y = mobj->SpawnPoint[1]; mo = Spawn (RUNTIME_TYPE(mobj), x, y, z, NO_REPLACE); if (z == ONFLOORZ) - mo->z += mo->SpawnPoint[2] << FRACBITS; + mo->z += mo->SpawnPoint[2]; else if (z == ONCEILINGZ) - mo->z -= mo->SpawnPoint[2] << FRACBITS; + mo->z -= mo->SpawnPoint[2]; // something is occupying its position? if (!P_TestMobjLocation (mo)) @@ -3252,8 +3252,8 @@ AActor *AActor::StaticSpawn (const PClass *type, fixed_t ix, fixed_t iy, fixed_t actor->ceilingsector = actor->Sector; } - actor->SpawnPoint[0] = ix >> FRACBITS; - actor->SpawnPoint[1] = iy >> FRACBITS; + actor->SpawnPoint[0] = ix; + actor->SpawnPoint[1] = iy; if (iz == ONFLOORZ) { @@ -3278,7 +3278,7 @@ AActor *AActor::StaticSpawn (const PClass *type, fixed_t ix, fixed_t iy, fixed_t } else { - actor->SpawnPoint[2] = (actor->z - actor->floorz) >> FRACBITS; + actor->SpawnPoint[2] = (actor->z - actor->floorz); } if (actor->flags2 & MF2_FLOATBOB) @@ -3500,7 +3500,7 @@ EXTERN_CVAR (Bool, chasedemo) extern bool demonew; -APlayerPawn *P_SpawnPlayer (mapthing2_t *mthing, bool tempplayer) +APlayerPawn *P_SpawnPlayer (FMapThing *mthing, bool tempplayer) { int playernum; player_t *p; @@ -3571,8 +3571,8 @@ APlayerPawn *P_SpawnPlayer (mapthing2_t *mthing, bool tempplayer) } else { - spawn_x = mthing->x << FRACBITS; - spawn_y = mthing->y << FRACBITS; + spawn_x = mthing->x; + spawn_y = mthing->y; spawn_angle = ANG45 * (mthing->angle/45); } @@ -3738,7 +3738,7 @@ APlayerPawn *P_SpawnPlayer (mapthing2_t *mthing, bool tempplayer) // already be in host byte order. // // [RH] position is used to weed out unwanted start spots -AActor *P_SpawnMapThing (mapthing2_t *mthing, int position) +AActor *P_SpawnMapThing (FMapThing *mthing, int position) { const PClass *i; int mask; @@ -3786,8 +3786,8 @@ AActor *P_SpawnMapThing (mapthing2_t *mthing, int position) { polyspawns_t *polyspawn = new polyspawns_t; polyspawn->next = polyspawns; - polyspawn->x = mthing->x << FRACBITS; - polyspawn->y = mthing->y << FRACBITS; + polyspawn->x = mthing->x; + polyspawn->y = mthing->y; polyspawn->angle = mthing->angle; polyspawn->type = mthing->type; polyspawns = polyspawn; @@ -3888,8 +3888,7 @@ AActor *P_SpawnMapThing (mapthing2_t *mthing, int position) // [RH] sound sequence overriders if (mthing->type >= 1400 && mthing->type < 1410) { - P_PointInSector (mthing->x<y<seqType = mthing->type - 1400; + P_PointInSector (mthing->x, mthing->y)->seqType = mthing->type - 1400; return NULL; } else if (mthing->type == 1411) @@ -3907,8 +3906,7 @@ AActor *P_SpawnMapThing (mapthing2_t *mthing, int position) } else { - P_PointInSector (mthing->x << FRACBITS, - mthing->y << FRACBITS)->seqType = type; + P_PointInSector (mthing->x, mthing->y)->seqType = type; } return NULL; } @@ -3932,7 +3930,7 @@ AActor *P_SpawnMapThing (mapthing2_t *mthing, int position) // [RH] Don't die if the map tries to spawn an unknown thing Printf ("Unknown type %i at (%i, %i)\n", mthing->type, - mthing->x, mthing->y); + mthing->x>>FRACBITS, mthing->y>>FRACBITS); i = PClass::FindClass("Unknown"); } // [RH] If the thing's corresponding sprite has no frames, also map @@ -3948,7 +3946,7 @@ AActor *P_SpawnMapThing (mapthing2_t *mthing, int position) sprites[defaults->SpawnState->sprite.index].numframes == 0) { Printf ("%s at (%i, %i) has no frames\n", - i->TypeName.GetChars(), mthing->x, mthing->y); + i->TypeName.GetChars(), mthing->x>>FRACBITS, mthing->y>>FRACBITS); i = PClass::FindClass("Unknown"); } } @@ -4002,8 +4000,8 @@ AActor *P_SpawnMapThing (mapthing2_t *mthing, int position) } // spawn it - x = mthing->x << FRACBITS; - y = mthing->y << FRACBITS; + x = mthing->x; + y = mthing->y; if (info->flags & MF_SPAWNCEILING) z = ONCEILINGZ; @@ -4017,9 +4015,9 @@ AActor *P_SpawnMapThing (mapthing2_t *mthing, int position) SpawningMapThing = false; if (z == ONFLOORZ) - mobj->z += mthing->z << FRACBITS; + mobj->z += mthing->z; else if (z == ONCEILINGZ) - mobj->z -= mthing->z << FRACBITS; + mobj->z -= mthing->z; mobj->SpawnPoint[0] = mthing->x; mobj->SpawnPoint[1] = mthing->y; diff --git a/src/p_setup.cpp b/src/p_setup.cpp index cd0d58e14..91a72ca65 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -61,11 +61,11 @@ #include "p_setup.h" #include "r_translate.h" -void P_SpawnSlopeMakers (mapthing2_t *firstmt, mapthing2_t *lastmt); +void P_SpawnSlopeMakers (FMapThing *firstmt, FMapThing *lastmt); void P_SetSlopes (); -extern AActor *P_SpawnMapThing (mapthing2_t *mthing, int position); -extern bool P_LoadBuildMap (BYTE *mapdata, size_t len, mapthing2_t **things, int *numthings); +extern AActor *P_SpawnMapThing (FMapThing *mthing, int position); +extern bool P_LoadBuildMap (BYTE *mapdata, size_t len, FMapThing **things, int *numthings); extern void P_LoadTranslator(const char *lump); extern void P_TranslateLineDef (line_t *ld, maplinedef_t *mld); @@ -116,6 +116,8 @@ zone_t* zones; FExtraLight* ExtraLights; FLightStack* LightStacks; +static TArray MapThingsConverted; + int sidecount; struct sidei_t // [RH] Only keep BOOM sidedef init stuff around for init { @@ -175,8 +177,8 @@ BYTE* rejectmatrix; static bool ForceNodeBuild; // Maintain single and multi player starting spots. -TArray deathmatchstarts (16); -mapthing2_t playerstarts[MAXPLAYERS]; +TArray deathmatchstarts (16); +FMapThing playerstarts[MAXPLAYERS]; static void P_AllocateSideDefs (int count); static void P_SetSideNum (DWORD *sidenum_p, WORD sidenum); @@ -303,20 +305,67 @@ MapData *P_OpenMapData(const char * mapname) } int index = 0; - for(int i = 1;; i++) + + if (stricmp(Wads.GetLumpFullName(lump_name + 1), "TEXTMAP")) { - // Since levels must be stored in WADs they can't really have full - // names and for any valid level lump this always returns the short name. - const char * lumpname = Wads.GetLumpFullName(lump_name + i); - index = GetMapIndex(mapname, index, lumpname, i != 1 || map->MapLumps[0].Size == 0); - if (index == ML_BEHAVIOR) map->HasBehavior = true; + for(int i = 1;; i++) + { + // Since levels must be stored in WADs they can't really have full + // names and for any valid level lump this always returns the short name. + const char * lumpname = Wads.GetLumpFullName(lump_name + i); + index = GetMapIndex(mapname, index, lumpname, i != 1 || map->MapLumps[0].Size == 0); + if (index == ML_BEHAVIOR) map->HasBehavior = true; - // The next lump is not part of this map anymore - if (index < 0) break; + // The next lump is not part of this map anymore + if (index < 0) break; - map->MapLumps[index].FilePos = Wads.GetLumpOffset(lump_name + i); - map->MapLumps[index].Size = Wads.LumpLength(lump_name + i); - strncpy(map->MapLumps[index].Name, lumpname, 8); + map->MapLumps[index].FilePos = Wads.GetLumpOffset(lump_name + i); + map->MapLumps[index].Size = Wads.LumpLength(lump_name + i); + strncpy(map->MapLumps[index].Name, lumpname, 8); + } + } + else + { + map->MapLumps[1].FilePos = Wads.GetLumpOffset(lump_name + 1); + map->MapLumps[1].Size = Wads.LumpLength(lump_name + 1); + for(int i = 2;; i++) + { + const char * lumpname = Wads.GetLumpFullName(lump_name + i); + + if (lumpname == NULL) + { + I_Error("Invalid map definition for %s", mapname); + } + else if (!stricmp(lumpname, "ZNODES")) + { + index = ML_GLZNODES; + } + else if (!stricmp(lumpname, "BLOCKMAP")) + { + // there is no real point in creating a blockmap but let's use it anyway + index = ML_BLOCKMAP; + } + else if (!stricmp(lumpname, "REJECT")) + { + index = ML_REJECT; + } + else if (!stricmp(lumpname, "DIALOGUE")) + { + index = ML_CONVERSATION; + } + else if (!stricmp(lumpname, "BEHAVIOR")) + { + index = ML_BEHAVIOR; + } + else if (!stricmp(lumpname, "ENDMAP")) + { + break; + } + else continue; + map->MapLumps[index].FilePos = Wads.GetLumpOffset(lump_name + i); + map->MapLumps[index].Size = Wads.LumpLength(lump_name + i); + strncpy(map->MapLumps[index].Name, lumpname, 8); + } } return map; } @@ -356,6 +405,50 @@ MapData *P_OpenMapData(const char * mapname) (*map->file) >> offset >> size; map->file->Read(lumpname, 8); + if (i == 1 && !strnicmp(lumpname, "TEXTMAP", 8)) + { + map->MapLumps[1].FilePos = offset; + map->MapLumps[1].Size = size; + for(int i = 2;; i++) + { + (*map->file) >> offset >> size; + long v = map->file->Read(lumpname, 8); + if (v < 8) + { + I_Error("Invalid map definition for %s", mapname); + } + else if (!stricmp(lumpname, "ZNODES")) + { + index = ML_GLZNODES; + } + else if (!stricmp(lumpname, "BLOCKMAP")) + { + // there is no real point in creating a blockmap but let's use it anyway + index = ML_BLOCKMAP; + } + else if (!stricmp(lumpname, "REJECT")) + { + index = ML_REJECT; + } + else if (!stricmp(lumpname, "DIALOGUE")) + { + index = ML_CONVERSATION; + } + else if (!stricmp(lumpname, "BEHAVIOR")) + { + index = ML_BEHAVIOR; + } + else if (!stricmp(lumpname, "ENDMAP")) + { + return map; + } + else continue; + map->MapLumps[index].FilePos = offset; + map->MapLumps[index].Size = size; + strncpy(map->MapLumps[index].Name, lumpname, 8); + } + } + if (i>0) { index = GetMapIndex(maplabel, index, lumpname, true); @@ -1225,13 +1318,13 @@ void P_LoadNodes (MapData * map) //=========================================================================== CVAR(Bool, dumpspawnedthings, false, 0) -static void SpawnMapThing(int index, mapthing2_t *mt, int position) +static void SpawnMapThing(int index, FMapThing *mt, int position) { AActor *spawned = P_SpawnMapThing(mt, position); if (dumpspawnedthings) { Printf("%5d: (%5d, %5d, %5d), doomednum = %5d, flags = %04x, type = %s\n", - index, mt->x, mt->y, mt->z, mt->type, mt->flags, + index, mt->x>>FRACBITS, mt->y>>FRACBITS, mt->z>>FRACBITS, mt->type, mt->flags, spawned? spawned->GetClass()->TypeName.GetChars() : "(none)"); } } @@ -1244,7 +1337,7 @@ static void SpawnMapThing(int index, mapthing2_t *mt, int position) void P_LoadThings (MapData * map, int position) { - mapthing2_t mt2; // [RH] for translation + FMapThing mt2; // [RH] for translation int lumplen = map->Size(ML_THINGS); int numthings = lumplen / sizeof(mapthing_t); @@ -1291,8 +1384,8 @@ void P_LoadThings (MapData * map, int position) } if (flags & BTF_NOTSINGLE) mt2.flags &= ~MTF_SINGLE; - mt2.x = LittleShort(mt->x); - mt2.y = LittleShort(mt->y); + mt2.x = LittleShort(mt->x) << FRACBITS; + mt2.y = LittleShort(mt->y) << FRACBITS; mt2.angle = LittleShort(mt->angle); mt2.type = LittleShort(mt->type); @@ -1316,36 +1409,31 @@ void P_LoadThings (MapData * map, int position) void P_LoadThings2 (MapData * map, int position) { int lumplen = map->MapLumps[ML_THINGS].Size; - int numthings = lumplen / sizeof(mapthing2_t); + int numthings = lumplen / sizeof(mapthinghexen_t); int i; char *mtp; - mapthing2_t *mt; + + MapThingsConverted.Resize(numthings); + FMapThing *mti = &MapThingsConverted[0]; mtp = new char[lumplen]; map->Read(ML_THINGS, mtp); + mapthinghexen_t *mth = (mapthinghexen_t*)mtp; -#ifdef WORDS_BIGENDIAN - for (i=0, mt = (mapthing2_t*)mtp; i < numthings; i++,mt++) + for(int i = 0; i< numthings; i++) { - mt->thingid = LittleShort(mt->thingid); - mt->x = LittleShort(mt->x); - mt->y = LittleShort(mt->y); - mt->z = LittleShort(mt->z); - mt->angle = LittleShort(mt->angle); - mt->type = LittleShort(mt->type); - mt->flags = LittleShort(mt->flags); - } -#endif - - // [RH] Spawn slope creating things first. - P_SpawnSlopeMakers ((mapthing2_t*)mtp, ((mapthing2_t*)mtp)+numthings); - - for (i=0, mt = (mapthing2_t*)mtp; i < numthings; i++,mt++) - { - SpawnMapThing (i, mt, position); + mti[i] = mth[i]; } delete[] mtp; + + // [RH] Spawn slope creating things first. + P_SpawnSlopeMakers (mti, mti + numthings); + + for (i=0; i < numthings; i++) + { + SpawnMapThing (i, &mti[i], position); + } } @@ -2818,38 +2906,30 @@ void P_GetPolySpots (MapData * map, TArray &spots, TAr { int spot1, spot2, spot3, anchor; - int lumplen = map->Size(ML_THINGS); - int num = lumplen / sizeof(mapthing2_t); - - mapthing2_t *mt; - - map->Seek(ML_THINGS); - mt = new mapthing2_t[num]; - map->file->Read(mt, num * sizeof(mapthing2_t)); - if (gameinfo.gametype == GAME_Hexen) { - spot1 = LittleShort(PO_HEX_SPAWN_TYPE); - spot2 = LittleShort(PO_HEX_SPAWNCRUSH_TYPE); - anchor = LittleShort(PO_HEX_ANCHOR_TYPE); + spot1 = PO_HEX_SPAWN_TYPE; + spot2 = PO_HEX_SPAWNCRUSH_TYPE; + anchor = PO_HEX_ANCHOR_TYPE; } else { - spot1 = LittleShort(PO_SPAWN_TYPE); - spot2 = LittleShort(PO_SPAWNCRUSH_TYPE); - anchor = LittleShort(PO_ANCHOR_TYPE); + spot1 = PO_SPAWN_TYPE; + spot2 = PO_SPAWNCRUSH_TYPE; + anchor = PO_ANCHOR_TYPE; } - spot3 = LittleShort(PO_SPAWNHURT_TYPE); + spot3 = PO_SPAWNHURT_TYPE; - for (int i = 0; i < num; ++i) + for (unsigned int i = 0; i < MapThingsConverted.Size(); ++i) { - if (mt[i].type == spot1 || mt[i].type == spot2 || mt[i].type == spot3 || mt[i].type == anchor) + if (MapThingsConverted[i].type == spot1 || MapThingsConverted[i].type == spot2 || + MapThingsConverted[i].type == spot3 || MapThingsConverted[i].type == anchor) { FNodeBuilder::FPolyStart newvert; - newvert.x = LittleShort(mt[i].x) << FRACBITS; - newvert.y = LittleShort(mt[i].y) << FRACBITS; - newvert.polynum = LittleShort(mt[i].angle); - if (mt[i].type == anchor) + newvert.x = MapThingsConverted[i].x; + newvert.y = MapThingsConverted[i].y; + newvert.polynum = MapThingsConverted[i].angle; + if (MapThingsConverted[i].type == anchor) { anchors.Push (newvert); } @@ -2859,7 +2939,6 @@ void P_GetPolySpots (MapData * map, TArray &spots, TAr } } } - delete[] mt; } } @@ -3027,7 +3106,7 @@ void P_FreeExtraLevelData() void P_SetupLevel (char *lumpname, int position) { cycle_t times[20] = { 0 }; - mapthing2_t *buildthings; + FMapThing *buildthings; int numbuildthings; int i; bool buildmap; @@ -3126,7 +3205,7 @@ void P_SetupLevel (char *lumpname, int position) } FBehavior::StaticLoadDefaultModules (); - P_LoadStrifeConversations (lumpname); + P_LoadStrifeConversations (map, lumpname); clock (times[0]); P_LoadVertexes (map); @@ -3386,6 +3465,7 @@ void P_SetupLevel (char *lumpname, int position) Printf ("Time%3d:%10llu cycles (%s)\n", i, times[i], timenames[i]); } } + MapThingsConverted.Clear(); } diff --git a/src/p_slopes.cpp b/src/p_slopes.cpp index 04f37ba88..503d9d846 100644 --- a/src/p_slopes.cpp +++ b/src/p_slopes.cpp @@ -269,10 +269,10 @@ enum // //========================================================================== -static void P_SetSlopesFromVertexHeights(mapthing2_t *firstmt, mapthing2_t *lastmt) +static void P_SetSlopesFromVertexHeights(FMapThing *firstmt, FMapThing *lastmt) { TMap vt_heights[2]; - mapthing2_t *mt; + FMapThing *mt; bool vt_found = false; for (mt = firstmt; mt < lastmt; ++mt) @@ -281,15 +281,15 @@ static void P_SetSlopesFromVertexHeights(mapthing2_t *firstmt, mapthing2_t *last { for(int i=0; ix << FRACBITS && vertexes[i].y == mt->y << FRACBITS) + if (vertexes[i].x == mt->x && vertexes[i].y == mt->y) { if (mt->type == THING_VertexFloorZ) { - vt_heights[0][i] = mt->z << FRACBITS; + vt_heights[0][i] = mt->z; } else { - vt_heights[1][i] = mt->z << FRACBITS; + vt_heights[1][i] = mt->z; } vt_found = true; } @@ -381,9 +381,9 @@ static void P_SetSlopesFromVertexHeights(mapthing2_t *firstmt, mapthing2_t *last // //=========================================================================== -void P_SpawnSlopeMakers (mapthing2_t *firstmt, mapthing2_t *lastmt) +void P_SpawnSlopeMakers (FMapThing *firstmt, FMapThing *lastmt) { - mapthing2_t *mt; + FMapThing *mt; for (mt = firstmt; mt < lastmt; ++mt) { @@ -395,8 +395,8 @@ void P_SpawnSlopeMakers (mapthing2_t *firstmt, mapthing2_t *lastmt) secplane_t *refplane; sector_t *sec; - x = mt->x << FRACBITS; - y = mt->y << FRACBITS; + x = mt->x; + y = mt->y; sec = P_PointInSector (x, y); if (mt->type & 1) { @@ -406,10 +406,10 @@ void P_SpawnSlopeMakers (mapthing2_t *firstmt, mapthing2_t *lastmt) { refplane = &sec->floorplane; } - z = refplane->ZatPoint (x, y) + (mt->z << FRACBITS); + z = refplane->ZatPoint (x, y) + (mt->z); if (mt->type==THING_VavoomFloor || mt->type==THING_VavoomCeiling) { - P_VavoomSlope(sec, mt->thingid, x, y, mt->z<type & 1); + P_VavoomSlope(sec, mt->thingid, x, y, mt->z, mt->type & 1); } else if (mt->type <= THING_SlopeCeilingPointLine) { @@ -428,7 +428,7 @@ void P_SpawnSlopeMakers (mapthing2_t *firstmt, mapthing2_t *lastmt) if (mt->type == THING_CopyFloorPlane || mt->type == THING_CopyCeilingPlane) { - P_CopyPlane (mt->args[0], mt->x << FRACBITS, mt->y << FRACBITS, mt->type & 1); + P_CopyPlane (mt->args[0], mt->x, mt->y, mt->type & 1); mt->type = 0; } } diff --git a/src/p_writemap.cpp b/src/p_writemap.cpp index 637b689a8..ac32fd433 100644 --- a/src/p_writemap.cpp +++ b/src/p_writemap.cpp @@ -94,7 +94,7 @@ CCMD (dumpmap) static int WriteTHINGS (FILE *file) { - mapthing2_t mt = { 0 }; + mapthinghexen_t mt = { 0 }; AActor *mo = players[consoleplayer].mo; mt.x = LittleShort(short(mo->x >> FRACBITS)); diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 32462a470..ba4b9396d 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -2037,8 +2037,8 @@ void A_Stop (AActor *self) //=========================================================================== void A_Respawn (AActor *actor) { - fixed_t x = actor->SpawnPoint[0] << FRACBITS; - fixed_t y = actor->SpawnPoint[1] << FRACBITS; + fixed_t x = actor->SpawnPoint[0]; + fixed_t y = actor->SpawnPoint[1]; sector_t *sec; actor->flags |= MF_SOLID;