uint16_t Reader_ReadPackedUInt16(Reader1 *reader) { ushort pack = Reader_ReadByte(reader); if (pack & 0x80) { pack &= ~0x80; pack |= Reader_ReadByte(reader) << 7; } return pack; }
static void P_v13_UnArchiveThinkers(void) { typedef enum { TC_END, TC_MOBJ } thinkerclass_t; byte tclass; // Remove all the current thinkers. Thinker_Iterate(NULL, removeThinker, NULL); Thinker_Init(); // read in saved thinkers for(;;) { tclass = Reader_ReadByte(svReader); switch(tclass) { case TC_END: return; // End of list. case TC_MOBJ: SV_v13_ReadMobj(); break; default: Con_Error("Unknown tclass %i in savegame", tclass); } } }
void SaveInfo_Read(SaveInfo *info, Reader *reader) { saveheader_t *hdr; DENG_ASSERT(info != 0); hdr = &info->header; hdr->magic = Reader_ReadInt32(reader); hdr->version = Reader_ReadInt32(reader); hdr->gameMode = (gamemode_t)Reader_ReadInt32(reader); if(hdr->version >= 10) { Str_Read(&info->name, reader); } else { // Older formats use a fixed-length name (24 characters). #define OLD_NAME_LENGTH 24 char buf[OLD_NAME_LENGTH]; Reader_Read(reader, buf, OLD_NAME_LENGTH); Str_Set(&info->name, buf); #undef OLD_NAME_LENGTH } hdr->skill = Reader_ReadByte(reader); hdr->episode = Reader_ReadByte(reader); hdr->map = Reader_ReadByte(reader); hdr->deathmatch = Reader_ReadByte(reader); hdr->noMonsters = Reader_ReadByte(reader); #if __JHEXEN__ hdr->randomClasses = Reader_ReadByte(reader); #endif #if !__JHEXEN__ hdr->respawnMonsters = Reader_ReadByte(reader); // Older formats serialize the unpacked saveheader_t struct; skip the junk values (alignment). if(hdr->version < 10) SV_Seek(2); hdr->mapTime = Reader_ReadInt32(reader); { int i; for(i = 0; i < MAXPLAYERS; ++i) { hdr->players[i] = Reader_ReadByte(reader); }} #endif info->gameId = Reader_ReadInt32(reader); #if __JDOOM__ || __JHERETIC__ // Translate gameMode identifiers from older save versions. translateLegacyGameMode(&hdr->gameMode, hdr->version); #endif }
int light_s::read(MapStateReader *msr) { Reader1 *reader = msr->reader(); int mapVersion = msr->mapVersion(); if(mapVersion >= 4) { /*int ver =*/ Reader_ReadByte(reader); // version byte. type = (lighttype_t) Reader_ReadByte(reader); sector = (Sector *)P_ToPtr(DMU_SECTOR, Reader_ReadInt32(reader)); DENG_ASSERT(sector != 0); value1 = (float) Reader_ReadInt32(reader) / 255.0f; value2 = (float) Reader_ReadInt32(reader) / 255.0f; tics1 = Reader_ReadInt32(reader); tics2 = Reader_ReadInt32(reader); count = Reader_ReadInt32(reader); } else { // Its in the old pre V4 format which serialized light_t // Padding at the start (an old thinker_t struct) byte junk[16]; // sizeof thinker_t Reader_Read(reader, junk, 16); // Start of used data members. // A 32bit pointer to sector, serialized. sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); DENG_ASSERT(sector != 0); type = lighttype_t(Reader_ReadInt32(reader)); value1 = (float) Reader_ReadInt32(reader) / 255.0f; value2 = (float) Reader_ReadInt32(reader) / 255.0f; tics1 = Reader_ReadInt32(reader); tics2 = Reader_ReadInt32(reader); count = Reader_ReadInt32(reader); } thinker.function = (thinkfunc_t) T_Light; return true; // Add this thinker. }
int SV_LoadState_Hr_v13(Str const *path, SaveInfo *info) { saveheader_t const *hdr; DENG_ASSERT(path != 0 && info != 0); if(!SV_OpenFile_Hr_v13(Str_Text(path))) return 1; svReader = SV_NewReader_Hr_v13(); // Read the header again. /// @todo Seek past the header straight to the game state. { SaveInfo *tmp = SaveInfo_New(); SaveInfo_Read_Hr_v13(tmp, svReader); SaveInfo_Delete(tmp); } hdr = SaveInfo_Header(info); gameSkill = hdr->skill; gameEpisode = hdr->episode; gameMap = hdr->map; gameMapEntryPoint = 0; // We don't want to see a briefing if we're loading a save game. briefDisabled = true; // Load a base map. G_NewGame(gameSkill, gameEpisode, gameMap, gameMapEntryPoint); /// @todo Necessary? G_SetGameAction(GA_NONE); // Recreate map state. mapTime = hdr->mapTime; P_v13_UnArchivePlayers(); P_v13_UnArchiveWorld(); P_v13_UnArchiveThinkers(); P_v13_UnArchiveSpecials(); if(Reader_ReadByte(svReader) != SAVE_GAME_TERMINATOR) { Reader_Delete(svReader); svReader = NULL; SV_CloseFile_Hr_v13(); Con_Error("Bad savegame"); // Missing savegame termination marker. exit(1); // Unreachable. } Reader_Delete(svReader); svReader = NULL; SV_CloseFile_Hr_v13(); return 0; // Success! }
void SaveInfo_Read_Hx_v9(SaveInfo *info, Reader *reader) { # define HXS_VERSION_TEXT "HXS Ver " // Do not change me! # define HXS_VERSION_TEXT_LENGTH 16 # define HXS_NAME_LENGTH 24 char verText[HXS_VERSION_TEXT_LENGTH], nameBuffer[HXS_NAME_LENGTH]; saveheader_t *hdr; DENG_ASSERT(info != 0); hdr = &info->header; Reader_Read(reader, nameBuffer, HXS_NAME_LENGTH); Str_Set(&info->name, nameBuffer); Reader_Read(reader, &verText, HXS_VERSION_TEXT_LENGTH); hdr->version = atoi(&verText[8]); /*Skip junk*/ SV_Seek(4); hdr->episode = 1; hdr->map = Reader_ReadByte(reader); hdr->skill = Reader_ReadByte(reader); hdr->deathmatch = Reader_ReadByte(reader); hdr->noMonsters = Reader_ReadByte(reader); hdr->randomClasses = Reader_ReadByte(reader); hdr->magic = MY_SAVE_MAGIC; // Lets pretend... /// @note Older formats do not contain all needed values: hdr->gameMode = gameMode; // Assume the current mode. info->gameId = 0; // None. # undef HXS_NAME_LENGTH # undef HXS_VERSION_TEXT_LENGTH # undef HXS_VERSION_TEXT }
int waggle_s::read(MapStateReader *msr) { Reader1 *reader = msr->reader(); int mapVersion = msr->mapVersion(); if(mapVersion >= 4) { /*int ver =*/ Reader_ReadByte(reader); // version byte. // Start of used data members. sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); DENG_ASSERT(sector != 0); originalHeight = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); accumulator = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); accDelta = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); targetScale = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); scale = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); scaleDelta = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); ticker = Reader_ReadInt32(reader); state = wagglestate_e(Reader_ReadInt32(reader)); } else { // Its in the old pre V4 format which serialized waggle_t // Padding at the start (an old thinker_t struct) byte junk[16]; // sizeof thinker_t Reader_Read(reader, junk, 16); // Start of used data members. // A 32bit pointer to sector, serialized. sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); DENG_ASSERT(sector != 0); originalHeight = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); accumulator = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); accDelta = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); targetScale = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); scale = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); scaleDelta = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); ticker = Reader_ReadInt32(reader); state = wagglestate_e(Reader_ReadInt32(reader)); } thinker.function = (thinkfunc_t) T_FloorWaggle; P_ToXSector(sector)->specialData = this; return true; // Add this thinker. }
uint32_t Reader_ReadPackedUInt32(Reader1 *reader) { byte pack = 0; int pos = 0; uint value = 0; do { if (!Reader_Check(reader, 1)) return 0; pack = Reader_ReadByte(reader); value |= ((pack & 0x7f) << pos); pos += 7; } while (pack & 0x80); return value; }
void NetCl_UpdateFinaleState(Reader* msg) { int i, numConds; fi_state_t* s = &remoteFinaleState; // Flags. s->mode = Reader_ReadByte(msg); s->finaleId = Reader_ReadUInt32(msg); // serverside id (local is different) // Conditions. numConds = Reader_ReadByte(msg); for(i = 0; i < numConds; ++i) { byte cond = Reader_ReadByte(msg); if(i == 0) s->conditions.secret = cond; if(i == 1) s->conditions.leave_hub = cond; } #ifdef _DEBUG Con_Message("NetCl_FinaleState: Updated finale %i: mode %i, secret=%i, leave_hud=%i", s->finaleId, s->mode, s->conditions.secret, s->conditions.leave_hub); #endif }
int pillar_s::read(MapStateReader *msr) { Reader1 *reader = msr->reader(); int mapVersion = msr->mapVersion(); if(mapVersion >= 4) { // Note: the thinker class byte has already been read. /*int ver =*/ Reader_ReadByte(reader); // version byte. // Start of used data members. sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); DENG_ASSERT(sector != 0); ceilingSpeed = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); floorSpeed = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); floorDest = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); ceilingDest = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); direction = Reader_ReadInt32(reader); crush = Reader_ReadInt32(reader); } else { // Its in the old pre V4 format which serialized pillar_t // Padding at the start (an old thinker_t struct) byte junk[16]; // sizeof thinker_t Reader_Read(reader, junk, 16); // Start of used data members. // A 32bit pointer to sector, serialized. sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); DENG_ASSERT(sector != 0); ceilingSpeed = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); floorSpeed = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); floorDest = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); ceilingDest = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); direction = Reader_ReadInt32(reader); crush = Reader_ReadInt32(reader); } thinker.function = (thinkfunc_t) T_BuildPillar; P_ToXSector(sector)->specialData = this; return true; // Add this thinker. }
/** * T_FireFlicker was added to save games in ver5, therefore we don't have * an old format to support. */ int fireflicker_s::read(MapStateReader *msr) { Reader1 *reader = msr->reader(); /*int ver =*/ Reader_ReadByte(reader); // version byte. // Note: the thinker class byte has already been read. sector = (Sector*)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); DENG_ASSERT(sector != 0); maxLight = (float) Reader_ReadInt32(reader) / 255.0f; minLight = (float) Reader_ReadInt32(reader) / 255.0f; thinker.function = (thinkfunc_t) T_FireFlicker; return true; // Add this thinker. }
static void SaveInfo_Read_Hr_v13(SaveInfo* info, Reader* reader) { saveheader_t* hdr = &info->header; char nameBuffer[V13_SAVESTRINGSIZE]; char vcheck[VERSIONSIZE]; int i; assert(info); Reader_Read(reader, nameBuffer, V13_SAVESTRINGSIZE); nameBuffer[V13_SAVESTRINGSIZE - 1] = 0; Str_Set(&info->name, nameBuffer); Reader_Read(reader, vcheck, VERSIONSIZE); //assert(!strncmp(vcheck, "version ", 8)); // Ensure save state format has been recognised by now. hdr->version = atoi(&vcheck[8]); hdr->skill = (skillmode_t) Reader_ReadByte(reader); // Interpret skill levels outside the normal range as "spawn no things". if(hdr->skill < SM_BABY || hdr->skill >= NUM_SKILL_MODES) hdr->skill = SM_NOTHINGS; hdr->episode = Reader_ReadByte(reader)-1; hdr->map = Reader_ReadByte(reader)-1; for(i = 0; i < 4; ++i) { hdr->players[i] = Reader_ReadByte(reader); } memset(&hdr->players[4], 0, sizeof(*hdr->players) * (MAXPLAYERS-4)); // Get the map time. { int a = Reader_ReadByte(reader); int b = Reader_ReadByte(reader); int c = Reader_ReadByte(reader); hdr->mapTime = (a << 16) + (b << 8) + c; } hdr->magic = 0; // Initialize with *something*. /// @note Older formats do not contain all needed values: hdr->gameMode = gameMode; // Assume the current mode. hdr->deathmatch = 0; hdr->noMonsters = 0; hdr->respawnMonsters = 0; info->gameId = 0; // None. }
int lightflash_s::read(MapStateReader *msr) { Reader1 *reader = msr->reader(); int mapVersion = msr->mapVersion(); if(mapVersion >= 5) { // Note: the thinker class byte has already been read. /*int ver =*/ Reader_ReadByte(reader); // version byte. // Start of used data members. sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); DENG_ASSERT(sector != 0); count = Reader_ReadInt32(reader); maxLight = (float) Reader_ReadInt32(reader) / 255.0f; minLight = (float) Reader_ReadInt32(reader) / 255.0f; maxTime = Reader_ReadInt32(reader); minTime = Reader_ReadInt32(reader); } else { // Its in the old pre V5 format which serialized lightflash_t // Padding at the start (an old thinker_t struct) byte junk[16]; // sizeof thinker_t Reader_Read(reader, junk, 16); // Start of used data members. // A 32bit pointer to sector, serialized. sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); DENG_ASSERT(sector != 0); count = Reader_ReadInt32(reader); maxLight = (float) Reader_ReadInt32(reader) / 255.0f; minLight = (float) Reader_ReadInt32(reader) / 255.0f; maxTime = Reader_ReadInt32(reader); minTime = Reader_ReadInt32(reader); } thinker.function = (thinkfunc_t) T_LightFlash; return true; // Add this thinker. }
static void readArchivedUri(Uri &uri, int version, reader_s &reader) { if(version >= 4) { // A serialized, percent encoded URI. Uri_Read(reinterpret_cast<uri_s *>(&uri), &reader); } else if(version == 3) { // A percent encoded textual URI. ddstring_t *_uri = Str_NewFromReader(&reader); uri.setUri(Str_Text(_uri), RC_NULL); Str_Delete(_uri); } else if(version == 2) { // An unencoded textual URI. ddstring_t *_uri = Str_NewFromReader(&reader); uri.setUri(QString(QByteArray(Str_Text(_uri), Str_Length(_uri)).toPercentEncoding()), RC_NULL); Str_Delete(_uri); } else // ver 1 { // A short textual path (unencoded). uri.setPath(readArchivedPath(reader)); // Plus a legacy scheme id. int oldSchemeId = Reader_ReadByte(&reader); switch(oldSchemeId) { case 0: uri.setScheme("Textures"); break; case 1: uri.setScheme("Flats"); break; case 2: uri.setScheme("Sprites"); break; case 3: uri.setScheme("System"); break; default: throw Error("readArchiveUri", QString("Unknown old-scheme id #%1, expected [0..3)").arg(oldSchemeId)); } } }
void SV_ReadSector(Sector *sec, MapStateReader *msr) { xsector_t *xsec = P_ToXSector(sec); Reader1 *reader = msr->reader(); int mapVersion = msr->mapVersion(); // A type byte? int type = 0; #if __JHEXEN__ if(mapVersion < 4) type = sc_ploff; else #else if(mapVersion <= 1) type = sc_normal; else #endif type = Reader_ReadByte(reader); // A version byte? int ver = 1; #if __JHEXEN__ if(mapVersion > 2) #else if(mapVersion > 4) #endif { ver = Reader_ReadByte(reader); } int fh = Reader_ReadInt16(reader); int ch = Reader_ReadInt16(reader); P_SetIntp(sec, DMU_FLOOR_HEIGHT, fh); P_SetIntp(sec, DMU_CEILING_HEIGHT, ch); #if __JHEXEN__ // Update the "target heights" of the planes. P_SetIntp(sec, DMU_FLOOR_TARGET_HEIGHT, fh); P_SetIntp(sec, DMU_CEILING_TARGET_HEIGHT, ch); // The move speed is not saved; can cause minor problems. P_SetIntp(sec, DMU_FLOOR_SPEED, 0); P_SetIntp(sec, DMU_CEILING_SPEED, 0); #endif world_Material *floorMaterial = 0, *ceilingMaterial = 0; #if !__JHEXEN__ if(mapVersion == 1) { // The flat numbers are absolute lump indices. de::Uri uri("Flats:", RC_NULL); uri.setPath(CentralLumpIndex()[Reader_ReadInt16(reader)].name().fileNameWithoutExtension()); floorMaterial = (world_Material *)P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(reinterpret_cast<uri_s *>(&uri))); uri.setPath(CentralLumpIndex()[Reader_ReadInt16(reader)].name().fileNameWithoutExtension()); ceilingMaterial = (world_Material *)P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(reinterpret_cast<uri_s *>(&uri))); } else if(mapVersion >= 4) #endif { // The flat numbers are actually archive numbers. floorMaterial = msr->material(Reader_ReadInt16(reader), 0); ceilingMaterial = msr->material(Reader_ReadInt16(reader), 0); } P_SetPtrp(sec, DMU_FLOOR_MATERIAL, floorMaterial); P_SetPtrp(sec, DMU_CEILING_MATERIAL, ceilingMaterial); if(ver >= 3) { P_SetIntp(sec, DMU_FLOOR_FLAGS, Reader_ReadInt16(reader)); P_SetIntp(sec, DMU_CEILING_FLAGS, Reader_ReadInt16(reader)); } byte lightlevel; #if __JHEXEN__ lightlevel = (byte) Reader_ReadInt16(reader); #else // In Ver1 the light level is a short if(mapVersion == 1) { lightlevel = (byte) Reader_ReadInt16(reader); } else { lightlevel = Reader_ReadByte(reader); } #endif P_SetFloatp(sec, DMU_LIGHT_LEVEL, (float) lightlevel / 255.f); #if !__JHEXEN__ if(mapVersion > 1) #endif { byte rgb[3]; Reader_Read(reader, rgb, 3); for(int i = 0; i < 3; ++i) P_SetFloatp(sec, DMU_COLOR_RED + i, rgb[i] / 255.f); } // Ver 2 includes surface colours if(ver >= 2) { byte rgb[3]; Reader_Read(reader, rgb, 3); for(int i = 0; i < 3; ++i) P_SetFloatp(sec, DMU_FLOOR_COLOR_RED + i, rgb[i] / 255.f); Reader_Read(reader, rgb, 3); for(int i = 0; i < 3; ++i) P_SetFloatp(sec, DMU_CEILING_COLOR_RED + i, rgb[i] / 255.f); } xsec->special = Reader_ReadInt16(reader); /*xsec->tag =*/ Reader_ReadInt16(reader); #if __JHEXEN__ xsec->seqType = seqtype_t(Reader_ReadInt16(reader)); #endif if(type == sc_ploff #if !__JHEXEN__ || type == sc_xg1 #endif ) { P_SetFloatp(sec, DMU_FLOOR_MATERIAL_OFFSET_X, Reader_ReadFloat(reader)); P_SetFloatp(sec, DMU_FLOOR_MATERIAL_OFFSET_Y, Reader_ReadFloat(reader)); P_SetFloatp(sec, DMU_CEILING_MATERIAL_OFFSET_X, Reader_ReadFloat(reader)); P_SetFloatp(sec, DMU_CEILING_MATERIAL_OFFSET_Y, Reader_ReadFloat(reader)); } #if !__JHEXEN__ if(type == sc_xg1) { SV_ReadXGSector(sec, reader, mapVersion); } #endif #if !__JHEXEN__ if(mapVersion <= 1) #endif { xsec->specialData = 0; } // We'll restore the sound targets latter on xsec->soundTarget = 0; }
void readHeader(reader_s &reader) { assertSegment(ASEG_MATERIAL_ARCHIVE, reader); version = Reader_ReadByte(&reader); }
/** * Things to handle: * * T_MoveCeiling, (ceiling_t: Sector * swizzle), - active list * T_Door, (door_t: Sector * swizzle), * T_MoveFloor, (floor_t: Sector * swizzle), * T_LightFlash, (lightflash_t: Sector * swizzle), * T_StrobeFlash, (strobe_t: Sector *), * T_Glow, (glow_t: Sector *), * T_PlatRaise, (plat_t: Sector *), - active list */ static void P_v13_UnArchiveSpecials(void) { enum { tc_ceiling, tc_door, tc_floor, tc_plat, tc_flash, tc_strobe, tc_glow, tc_endspecials }; byte tclass; ceiling_t* ceiling; door_t* door; floor_t* floor; plat_t* plat; lightflash_t* flash; strobe_t* strobe; glow_t* glow; // Read in saved thinkers. for(;;) { tclass = Reader_ReadByte(svReader); switch(tclass) { case tc_endspecials: return; // End of list. case tc_ceiling: ceiling = Z_Calloc(sizeof(*ceiling), PU_MAP, NULL); SV_ReadCeiling(ceiling); Thinker_Add(&ceiling->thinker); break; case tc_door: door = Z_Calloc(sizeof(*door), PU_MAP, NULL); SV_ReadDoor(door); Thinker_Add(&door->thinker); break; case tc_floor: floor = Z_Calloc(sizeof(*floor), PU_MAP, NULL); SV_ReadFloor(floor); Thinker_Add(&floor->thinker); break; case tc_plat: plat = Z_Calloc(sizeof(*plat), PU_MAP, NULL); SV_ReadPlat(plat); Thinker_Add(&plat->thinker); break; case tc_flash: flash = Z_Calloc(sizeof(*flash), PU_MAP, NULL); SV_ReadFlash(flash); Thinker_Add(&flash->thinker); break; case tc_strobe: strobe = Z_Calloc(sizeof(*strobe), PU_MAP, NULL); SV_ReadStrobe(strobe); Thinker_Add(&strobe->thinker); break; case tc_glow: glow = Z_Calloc(sizeof(*glow), PU_MAP, NULL); SV_ReadGlow(glow); Thinker_Add(&glow->thinker); break; default: Con_Error("P_UnarchiveSpecials:Unknown tclass %i " "in savegame", tclass); } } }
/** * Read a view angle and coords packet. NOTE: The Z coordinate of the * camera is the real eye Z coordinate, not the player mobj's Z coord. */ void Demo_ReadLocalCamera(void) { ddplayer_t *pl = &ddPlayers[consolePlayer].shared; mobj_t *mo = pl->mo; int flags; float z; int intertics = LOCALCAM_WRITE_TICS; int dang; float dlook; if(!mo) return; if(netBuffer.msg.type == PKT_DEMOCAM_RESUME) { intertics = 1; } // Framez keeps track of the current camera Z. demoFrameZ += demoZ; flags = Reader_ReadByte(msgReader); demoOnGround = (flags & LCAMF_ONGROUND) != 0; if(flags & LCAMF_CAMERA) pl->flags |= DDPF_CAMERA; else pl->flags &= ~DDPF_CAMERA; // X and Y coordinates are easy. Calculate deltas to the new coords. posDelta[VX] = (FIX2FLT((Reader_ReadInt16(msgReader) << 16) + (Reader_ReadByte(msgReader) << 8)) - mo->origin[VX]) / intertics; posDelta[VY] = (FIX2FLT((Reader_ReadInt16(msgReader) << 16) + (Reader_ReadByte(msgReader) << 8)) - mo->origin[VY]) / intertics; // The Z coordinate is a bit trickier. We are tracking the *camera's* // Z coordinate (z+viewheight), not the player mobj's Z. z = FIX2FLT((Reader_ReadInt16(msgReader) << 16) + (Reader_ReadByte(msgReader) << 8)); posDelta[VZ] = (z - demoFrameZ) / LOCALCAM_WRITE_TICS; // View angles. dang = Reader_ReadInt16(msgReader) << 16; dlook = Reader_ReadInt16(msgReader) * 110.0f / DDMAXSHORT; // FOV included? if(flags & LCAMF_FOV) fieldOfView = Reader_ReadInt16(msgReader) * 180.0f / DDMAXSHORT; if(intertics == 1 || demoFrameZ == 1) { // Immediate change. /*pl->clAngle = dang; pl->clLookDir = dlook;*/ pl->mo->angle = dang; pl->lookDir = dlook; /* $unifiedangles */ viewangleDelta = 0; lookdirDelta = 0; } else { viewangleDelta = (dang - pl->mo->angle) / intertics; lookdirDelta = (dlook - pl->lookDir) / intertics; /* $unifiedangles */ } // The first one gets no delta. if(demoFrameZ == 1) { // This must be the first democam packet. // Initialize framez to the height we just read. demoFrameZ = z; posDelta[VZ] = 0; } // demo_z is the offset to demo_framez for the current tic. // It is incremented by pos_delta[VZ] every tic. demoZ = 0; if(intertics == 1) { // Instantaneous move. R_ResetViewer(); demoFrameZ = z; ClPlayer_MoveLocal(posDelta[VX], posDelta[VY], z, demoOnGround); posDelta[VX] = posDelta[VY] = posDelta[VZ] = 0; } }
void Cl_Frame2Received(int packetType) { // The first thing in the frame is the gameTime. frameGameTime = Reader_ReadFloat(msgReader); // All frames that arrive before the first frame are ignored. // They are most likely from the wrong map. if (packetType == PSV_FIRST_FRAME2) { gotFirstFrame = true; } else if (!gotFirstFrame) { // Just ignore. If this was a legitimate frame, the server will // send it again when it notices no ack is coming. return; } // Read and process the message. while (!Reader_AtEnd(msgReader)) { byte const deltaType = Reader_ReadByte(msgReader); switch (deltaType) { case DT_CREATE_MOBJ: // The mobj will be created/shown. ClMobj_ReadDelta(); break; case DT_MOBJ: // The mobj will be hidden if it's not yet Created. ClMobj_ReadDelta(); break; case DT_NULL_MOBJ: // The mobj will be removed. ClMobj_ReadNullDelta(); break; case DT_PLAYER: ClPlayer_ReadDelta(); break; case DT_SECTOR: Cl_ReadSectorDelta(deltaType); break; //case DT_SIDE_R6: // Old format. case DT_SIDE: Cl_ReadSideDelta(deltaType); break; case DT_POLY: Cl_ReadPolyDelta(); break; case DT_SOUND: case DT_MOBJ_SOUND: case DT_SECTOR_SOUND: case DT_SIDE_SOUND: case DT_POLY_SOUND: Cl_ReadSoundDelta((deltatype_t) deltaType); break; default: LOG_NET_ERROR("Received unknown delta type %i (message size: %i bytes)") << deltaType << netBuffer.length; return; } } if (!gotFrame) { LOGDEV_NET_NOTE("First frame received"); } // We have now received a frame. gotFrame = true; }
int plat_t::read(MapStateReader *msr) { Reader *reader = msr->reader(); int mapVersion = msr->mapVersion(); #if __JHEXEN__ if(mapVersion >= 4) #else if(mapVersion >= 5) #endif { // Note: the thinker class byte has already been read. /*int ver =*/ Reader_ReadByte(reader); // version byte. thinker.function = T_PlatRaise; #if !__JHEXEN__ // Should we put this into stasis? if(mapVersion == 5) { if(!Reader_ReadByte(reader)) Thinker_SetStasis(&thinker, true); } #endif type = plattype_e(Reader_ReadByte(reader)); sector = (Sector *)P_ToPtr(DMU_SECTOR, Reader_ReadInt32(reader)); DENG_ASSERT(sector != 0); speed = FIX2FLT(Reader_ReadInt32(reader)); low = (float) Reader_ReadInt16(reader); high = (float) Reader_ReadInt16(reader); wait = Reader_ReadInt32(reader); count = Reader_ReadInt32(reader); state = platstate_e(Reader_ReadByte(reader)); oldState = platstate_e(Reader_ReadByte(reader)); crush = (dd_bool) Reader_ReadByte(reader); tag = Reader_ReadInt32(reader); } else { // Its in the old format which serialized plat_t // Padding at the start (an old thinker_t struct) int32_t junk[4]; // sizeof thinker_t Reader_Read(reader, (byte *)junk, 16); // Start of used data members. // A 32bit pointer to sector, serialized. sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); DENG_ASSERT(sector != 0); speed = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); low = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); high = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); wait = Reader_ReadInt32(reader); count = Reader_ReadInt32(reader); state = platstate_e(Reader_ReadInt32(reader)); oldState = platstate_e(Reader_ReadInt32(reader)); crush = Reader_ReadInt32(reader); tag = Reader_ReadInt32(reader); type = plattype_e(Reader_ReadInt32(reader)); thinker.function = T_PlatRaise; #if !__JHEXEN__ if(junk[2] == 0) { Thinker_SetStasis(&thinker, true); } #endif } P_ToXSector(sector)->specialData = this; return true; // Add this thinker. }
/** * Reads all versions of archived lines. * Including the old Ver1. */ void SV_ReadLine(Line *li, MapStateReader *msr) { xline_t *xli = P_ToXLine(li); Reader1 *reader = msr->reader(); int mapVersion = msr->mapVersion(); bool xgDataFollows = false; #if __JHEXEN__ if(mapVersion >= 4) #else if(mapVersion >= 2) #endif { xgDataFollows = Reader_ReadByte(reader) == 1; } #ifdef __JHEXEN__ DENG2_UNUSED(xgDataFollows); #endif // A version byte? int ver = 1; #if __JHEXEN__ if(mapVersion >= 3) #else if(mapVersion >= 5) #endif { ver = (int) Reader_ReadByte(reader); } if(ver >= 4) { P_SetIntp(li, DMU_FLAGS, Reader_ReadInt16(reader)); } int flags = Reader_ReadInt16(reader); if(xli->flags & ML_TWOSIDED) { flags |= ML_TWOSIDED; } if(ver < 4) { // Translate old line flags. int ddLineFlags = 0; if(flags & 0x0001) // old ML_BLOCKING flag { ddLineFlags |= DDLF_BLOCKING; flags &= ~0x0001; } if(flags & 0x0008) // old ML_DONTPEGTOP flag { ddLineFlags |= DDLF_DONTPEGTOP; flags &= ~0x0008; } if(flags & 0x0010) // old ML_DONTPEGBOTTOM flag { ddLineFlags |= DDLF_DONTPEGBOTTOM; flags &= ~0x0010; } P_SetIntp(li, DMU_FLAGS, ddLineFlags); } if(ver < 3) { if(flags & ML_MAPPED) { int lineIDX = P_ToIndex(li); // Set line as having been seen by all players.. de::zap(xli->mapped); for(int i = 0; i < MAXPLAYERS; ++i) { P_SetLineAutomapVisibility(i, lineIDX, true); } } } xli->flags = flags; if(ver >= 3) { for(int i = 0; i < MAXPLAYERS; ++i) { xli->mapped[i] = Reader_ReadByte(reader); } } #if __JHEXEN__ xli->special = Reader_ReadByte(reader); xli->arg1 = Reader_ReadByte(reader); xli->arg2 = Reader_ReadByte(reader); xli->arg3 = Reader_ReadByte(reader); xli->arg4 = Reader_ReadByte(reader); xli->arg5 = Reader_ReadByte(reader); #else xli->special = Reader_ReadInt16(reader); /*xli->tag =*/ Reader_ReadInt16(reader); #endif // For each side for(int i = 0; i < 2; ++i) { Side *si = (Side *)P_GetPtrp(li, (i? DMU_BACK:DMU_FRONT)); if(!si) continue; // Versions latter than 2 store per surface texture offsets. if(ver >= 2) { float offset[2]; offset[VX] = (float) Reader_ReadInt16(reader); offset[VY] = (float) Reader_ReadInt16(reader); P_SetFloatpv(si, DMU_TOP_MATERIAL_OFFSET_XY, offset); offset[VX] = (float) Reader_ReadInt16(reader); offset[VY] = (float) Reader_ReadInt16(reader); P_SetFloatpv(si, DMU_MIDDLE_MATERIAL_OFFSET_XY, offset); offset[VX] = (float) Reader_ReadInt16(reader); offset[VY] = (float) Reader_ReadInt16(reader); P_SetFloatpv(si, DMU_BOTTOM_MATERIAL_OFFSET_XY, offset); } else { float offset[2]; offset[VX] = (float) Reader_ReadInt16(reader); offset[VY] = (float) Reader_ReadInt16(reader); P_SetFloatpv(si, DMU_TOP_MATERIAL_OFFSET_XY, offset); P_SetFloatpv(si, DMU_MIDDLE_MATERIAL_OFFSET_XY, offset); P_SetFloatpv(si, DMU_BOTTOM_MATERIAL_OFFSET_XY, offset); } if(ver >= 3) { P_SetIntp(si, DMU_TOP_FLAGS, Reader_ReadInt16(reader)); P_SetIntp(si, DMU_MIDDLE_FLAGS, Reader_ReadInt16(reader)); P_SetIntp(si, DMU_BOTTOM_FLAGS, Reader_ReadInt16(reader)); } world_Material *topMaterial = 0, *bottomMaterial = 0, *middleMaterial = 0; #if !__JHEXEN__ if(mapVersion >= 4) #endif { topMaterial = msr->material(Reader_ReadInt16(reader), 1); bottomMaterial = msr->material(Reader_ReadInt16(reader), 1); middleMaterial = msr->material(Reader_ReadInt16(reader), 1); } P_SetPtrp(si, DMU_TOP_MATERIAL, topMaterial); P_SetPtrp(si, DMU_BOTTOM_MATERIAL, bottomMaterial); P_SetPtrp(si, DMU_MIDDLE_MATERIAL, middleMaterial); // Ver2 includes surface colours if(ver >= 2) { float rgba[4]; int flags; for(int k = 0; k < 3; ++k) rgba[k] = (float) Reader_ReadByte(reader) / 255.f; rgba[3] = 1; P_SetFloatpv(si, DMU_TOP_COLOR, rgba); for(int k = 0; k < 3; ++k) rgba[k] = (float) Reader_ReadByte(reader) / 255.f; rgba[3] = 1; P_SetFloatpv(si, DMU_BOTTOM_COLOR, rgba); for(int k = 0; k < 4; ++k) rgba[k] = (float) Reader_ReadByte(reader) / 255.f; P_SetFloatpv(si, DMU_MIDDLE_COLOR, rgba); P_SetIntp(si, DMU_MIDDLE_BLENDMODE, Reader_ReadInt32(reader)); flags = Reader_ReadInt16(reader); if(mapVersion < 12) { if(P_GetIntp(si, DMU_FLAGS) & SDF_SUPPRESS_BACK_SECTOR) flags |= SDF_SUPPRESS_BACK_SECTOR; } P_SetIntp(si, DMU_FLAGS, flags); } } #if !__JHEXEN__ if(xgDataFollows) { SV_ReadXGLine(li, msr); } #endif }
int mobj_s::read(MapStateReader *msr) { #define FF_FULLBRIGHT 0x8000 ///< Used to be a flag in thing->frame. #define FF_FRAMEMASK 0x7fff Reader1 *reader = msr->reader(); int ver = Reader_ReadByte(reader); #if !__JHEXEN__ if(ver >= 2) // Version 2 has mobj archive numbers. { msr->addMobjToThingArchive(this, Reader_ReadInt16(reader)); } #endif #if !__JHEXEN__ target = 0; if(ver >= 2) { target = INT2PTR(mobj_t, Reader_ReadInt16(reader)); } #endif #if __JDOOM__ || __JDOOM64__ tracer = 0; if(ver >= 5) { tracer = INT2PTR(mobj_t, Reader_ReadInt16(reader)); } #endif onMobj = 0; #if __JHEXEN__ if(ver >= 8) #else if(ver >= 5) #endif { onMobj = INT2PTR(mobj_t, Reader_ReadInt16(reader)); } origin[VX] = FIX2FLT(Reader_ReadInt32(reader)); origin[VY] = FIX2FLT(Reader_ReadInt32(reader)); origin[VZ] = FIX2FLT(Reader_ReadInt32(reader)); angle = Reader_ReadInt32(reader); sprite = Reader_ReadInt32(reader); frame = Reader_ReadInt32(reader); // might be ORed with FF_FULLBRIGHT if(frame & FF_FULLBRIGHT) frame &= FF_FRAMEMASK; // not used anymore. #if __JHEXEN__ if(ver < 6) { /*floorflat =*/ Reader_ReadInt32(reader); } #else floorZ = FIX2FLT(Reader_ReadInt32(reader)); ceilingZ = FIX2FLT(Reader_ReadInt32(reader)); #endif radius = FIX2FLT(Reader_ReadInt32(reader)); height = FIX2FLT(Reader_ReadInt32(reader)); mom[MX] = FIX2FLT(Reader_ReadInt32(reader)); mom[MY] = FIX2FLT(Reader_ReadInt32(reader)); mom[MZ] = FIX2FLT(Reader_ReadInt32(reader)); valid = Reader_ReadInt32(reader); type = Reader_ReadInt32(reader); #if __JHEXEN__ if(ver < 7) { /*info = (mobjinfo_t *)*/ Reader_ReadInt32(reader); } #endif info = &MOBJINFO[type]; if(info->flags2 & MF2_FLOATBOB) mom[MZ] = 0; if(info->flags & MF_SOLID) ddFlags |= DDMF_SOLID; if(info->flags2 & MF2_DONTDRAW) ddFlags |= DDMF_DONTDRAW; tics = Reader_ReadInt32(reader); state = INT2PTR(state_t, Reader_ReadInt32(reader)); #if __JHEXEN__ damage = Reader_ReadInt32(reader); #endif flags = Reader_ReadInt32(reader); #if __JHEXEN__ flags2 = Reader_ReadInt32(reader); if(ver >= 5) { flags3 = Reader_ReadInt32(reader); } special1 = Reader_ReadInt32(reader); special2 = Reader_ReadInt32(reader); #endif health = Reader_ReadInt32(reader); #if __JHERETIC__ if(ver < 8) { // Fix a bunch of kludges in the original Heretic. switch(type) { case MT_MACEFX1: case MT_MACEFX2: case MT_MACEFX3: case MT_HORNRODFX2: case MT_HEADFX3: case MT_WHIRLWIND: case MT_TELEGLITTER: case MT_TELEGLITTER2: special3 = health; if(type == MT_HORNRODFX2 && special3 > 16) special3 = 16; health = MOBJINFO[type].spawnHealth; break; default: break; } } #endif moveDir = Reader_ReadInt32(reader); moveCount = Reader_ReadInt32(reader); #if __JHEXEN__ target = INT2PTR(mobj_t, Reader_ReadInt32(reader)); #endif reactionTime = Reader_ReadInt32(reader); threshold = Reader_ReadInt32(reader); player = INT2PTR(player_t, Reader_ReadInt32(reader)); lastLook = Reader_ReadInt32(reader); #if __JHEXEN__ floorClip = FIX2FLT(Reader_ReadInt32(reader)); msr->addMobjToThingArchive(this, Reader_ReadInt32(reader)); tid = Reader_ReadInt32(reader); #else // For nightmare respawn. if(ver >= 6) { spawnSpot.origin[VX] = FIX2FLT(Reader_ReadInt32(reader)); spawnSpot.origin[VY] = FIX2FLT(Reader_ReadInt32(reader)); spawnSpot.origin[VZ] = FIX2FLT(Reader_ReadInt32(reader)); spawnSpot.angle = Reader_ReadInt32(reader); if(ver < 10) { /*spawnSpot.type =*/ Reader_ReadInt32(reader); } spawnSpot.flags = Reader_ReadInt32(reader); } else { spawnSpot.origin[VX] = (float) Reader_ReadInt16(reader); spawnSpot.origin[VY] = (float) Reader_ReadInt16(reader); spawnSpot.origin[VZ] = 0; // Initialize with "something". spawnSpot.angle = (angle_t) (ANG45 * (Reader_ReadInt16(reader) / 45)); /*spawnSpot.type = (int)*/ Reader_ReadInt16(reader); spawnSpot.flags = (int) Reader_ReadInt16(reader); } # if __JDOOM__ || __JDOOM64__ if(ver >= 3) # elif __JHERETIC__ if(ver >= 5) # endif { intFlags = Reader_ReadInt32(reader); dropOffZ = FIX2FLT(Reader_ReadInt32(reader)); gear = Reader_ReadInt32(reader); } # if __JDOOM__ || __JDOOM64__ if(ver >= 6) { damage = Reader_ReadInt32(reader); flags2 = Reader_ReadInt32(reader); } else // flags2 will be applied from the defs. { damage = DDMAXINT; // Use the value set in mo->info->damage } # elif __JHERETIC__ damage = Reader_ReadInt32(reader); flags2 = Reader_ReadInt32(reader); # endif if(ver >= 7) { flags3 = Reader_ReadInt32(reader); } // Else flags3 will be applied from the defs. #endif #if __JHEXEN__ special = Reader_ReadInt32(reader); Reader_Read(reader, args, 1 * 5); #elif __JHERETIC__ special1 = Reader_ReadInt32(reader); special2 = Reader_ReadInt32(reader); if(ver >= 8) { special3 = Reader_ReadInt32(reader); } #endif #if __JHEXEN__ if(ver >= 2) #else if(ver >= 4) #endif { translucency = Reader_ReadByte(reader); } #if __JHEXEN__ if(ver >= 3) #else if(ver >= 5) #endif { visTarget = (short) (Reader_ReadByte(reader)) -1; } #if __JHEXEN__ if(ver >= 4) { tracer = INT2PTR(mobj_t, Reader_ReadInt32(reader)); } if(ver >= 4) { lastEnemy = INT2PTR(mobj_t, Reader_ReadInt32(reader)); } #else if(ver >= 5) { floorClip = FIX2FLT(Reader_ReadInt32(reader)); } #endif #if __JHERETIC__ if(ver >= 7) { generator = INT2PTR(mobj_t, Reader_ReadInt16(reader)); } else { generator = 0; } #endif /* * Restore! (unmangle) */ info = &MOBJINFO[type]; Mobj_SetState(this, PTR2INT(state)); #if __JHEXEN__ if(flags2 & MF2_DORMANT) { tics = -1; } #endif if(player) { // The player number translation table is used to find out the // *current* (actual) player number of the referenced player. player = msr->player(PTR2INT(player)); #if __JHEXEN__ if(!player) { // This saved player does not exist in the current game! // Destroy this mobj. Mobj_Destroy(this); return false; } #endif dPlayer = player->plr; dPlayer->mo = this; //dPlayer->clAngle = angle; /* $unifiedangles */ dPlayer->lookDir = 0; /* $unifiedangles */ } visAngle = angle >> 16; #if !__JHEXEN__ if(dPlayer && !dPlayer->inGame) { dPlayer->mo = 0; Mobj_Destroy(this); return false; } #endif #if !__JDOOM64__ // Do we need to update this mobj's flag values? if(ver < MOBJ_SAVEVERSION) { SV_TranslateLegacyMobjFlags(this, ver); } #endif P_MobjLink(this); floorZ = P_GetDoublep(Mobj_Sector(this), DMU_FLOOR_HEIGHT); ceilingZ = P_GetDoublep(Mobj_Sector(this), DMU_CEILING_HEIGHT); return false; #undef FF_FRAMEMASK #undef FF_FULLBRIGHT }
void playerheader_s::read(Reader1 *reader, int saveVersion) { #if __JHEXEN__ if(saveVersion >= 4) #else if(saveVersion >= 5) #endif { int ver = Reader_ReadByte(reader); #if !__JHERETIC__ DENG2_UNUSED(ver); #endif numPowers = Reader_ReadInt32(reader); numKeys = Reader_ReadInt32(reader); numFrags = Reader_ReadInt32(reader); numWeapons = Reader_ReadInt32(reader); numAmmoTypes = Reader_ReadInt32(reader); numPSprites = Reader_ReadInt32(reader); #if __JHERETIC__ if(ver >= 2) numInvItemTypes = Reader_ReadInt32(reader); else numInvItemTypes = NUM_INVENTORYITEM_TYPES; #endif #if __JHEXEN__ || __JDOOM64__ numInvItemTypes = Reader_ReadInt32(reader); #endif #if __JHEXEN__ numArmorTypes = Reader_ReadInt32(reader); #endif } else // The old format didn't save the counts. { #if __JHEXEN__ numPowers = 9; numKeys = 11; numFrags = 8; numWeapons = 4; numAmmoTypes = 2; numPSprites = 2; numInvItemTypes = 33; numArmorTypes = 4; #elif __JDOOM__ || __JDOOM64__ numPowers = 6; numKeys = 6; numFrags = 4; // Why was this only 4? numWeapons = 9; numAmmoTypes = 4; numPSprites = 2; # if __JDOOM64__ numInvItemTypes = 3; # endif #elif __JHERETIC__ numPowers = 9; numKeys = 3; numFrags = 4; // ? numWeapons = 8; numInvItemTypes = 14; numAmmoTypes = 6; numPSprites = 2; #endif } }