/** * Parses a textual descriptor of the conditions for triggering an event-command binding. * eventparams{+cond}* * * @param eb The results of the parsing are stored here. * @param desc Descriptor containing event information and possible additional conditions. * * @return @c true, if successful; otherwise @c false. */ boolean B_ParseEventDescriptor(evbinding_t* eb, const char* desc) { AutoStr* str = AutoStr_NewStd(); // The main part, i.e., the first part. desc = Str_CopyDelim(str, desc, '+'); if(!B_ParseEvent(eb, Str_Text(str))) { // Failure parsing the event. return false; } // Any conditions? while(desc) { statecondition_t *cond; // A new condition. desc = Str_CopyDelim(str, desc, '+'); cond = B_AllocCommandBindingCondition(eb); if(!B_ParseStateCondition(cond, Str_Text(str))) { // Failure parsing the condition. return false; } } // Success. return true; }
void P_SetYellowMessage(player_t* pl, int flags, const char* msg) { #define YELLOW_FMT "{r=1;g=0.7;b=0.3;}" #define YELLOW_FMT_LEN 18 size_t len; AutoStr* buf; if(!msg || !msg[0]) return; len = strlen(msg); buf = AutoStr_NewStd(); Str_Reserve(buf, YELLOW_FMT_LEN + len+1); Str_Set(buf, YELLOW_FMT); Str_Appendf(buf, "%s", msg); ST_LogPost(pl - players, flags, Str_Text(buf)); if(pl == &players[CONSOLEPLAYER] && cfg.echoMsg) Con_FPrintf(CPF_CYAN, "%s\n", msg); // Servers are responsible for sending these messages to the clients. /// @todo We shouldn't need to send the format string along with every /// important game message. Instead flag a bit in the packet and then /// reconstruct on the other end. NetSv_SendMessage(pl - players, Str_Text(buf)); #undef YELLOW_FMT }
void CollectFiles(const char *basepath) { FindData fd; char findspec[256], path[256]; sprintf(findspec, "%s*", basepath); if (!FindFile_FindFirst(&fd, findspec)) { // The first file found! do { if (!Str_Compare(&fd.name, ".") || !Str_Compare(&fd.name, "..")) continue; sprintf(path, "%s%s", basepath, Str_Text(&fd.name)); if (fd.attrib & A_SUBDIR) { CollectFiles(path); } else { NewFile(path, fd.size); } } while (!FindFile_FindNext(&fd)); } FindFile_Finish(&fd); }
boolean SV_RecogniseState_Hr_v13(Str const *path, SaveInfo *info) { DENG_ASSERT(path != 0 && info != 0); if(!SV_ExistingFile(path)) return false; if(SV_OpenFile_Hr_v13(Str_Text(path))) { Reader *svReader = SV_NewReader_Hr_v13(); boolean result = false; /// @todo Use the 'version' string as the "magic" identifier. /*char vcheck[VERSIONSIZE]; memset(vcheck, 0, sizeof(vcheck)); Reader_Read(svReader, vcheck, sizeof(vcheck)); if(strncmp(vcheck, "version ", 8))*/ { SaveInfo_Read_Hr_v13(info, svReader); result = (SaveInfo_Header(info)->version == V13_SAVE_VERSION); } Reader_Delete(svReader); svReader = NULL; SV_CloseFile_Hr_v13(); return result; } return false; }
/** * Open a demo file and begin recording. * Returns false if the recording can't be begun. */ boolean Demo_BeginRecording(const char* fileName, int plrNum) { DENG_UNUSED(fileName); DENG_UNUSED(plrNum); return false; #if 0 client_t* cl = &clients[plrNum]; player_t* plr = &ddPlayers[plrNum]; ddstring_t buf; // Is a demo already being recorded for this client? if(cl->recording || playback || (isDedicated && !plrNum) || !plr->shared.inGame) return false; // Compose the real file name. Str_InitStd(&buf); Str_Appendf(&buf, "%s%s", demoPath, fileName); F_ExpandBasePath(&buf, &buf); F_ToNativeSlashes(&buf, &buf); // Open the demo file. cl->demo = lzOpen(Str_Text(&buf), "wp"); Str_Free(&buf); if(!cl->demo) { return false; // Couldn't open it! } cl->recording = true; cl->recordPaused = false; writeInfo[plrNum].first = true; writeInfo[plrNum].canwrite = false; writeInfo[plrNum].cameratimer = 0; writeInfo[plrNum].fov = -1; // Must be written in the first packet. if(isServer) { // Playing demos alters gametic. This'll make sure we're going to // get updates. clients[0].lastTransmit = -1; // Servers need to send a handshake packet. // It only needs to recorded in the demo file, though. allowSending = false; Sv_Handshake(plrNum, false); // Enable sending to network. allowSending = true; } else { // Clients need a Handshake packet. // Request a new one from the server. Cl_SendHello(); } // The operation is a success. return true; #endif }
static void drawEnteringTitle(void) { int x = SCREENWIDTH/2, y = WI_TITLEY; char* mapName = NULL; uint mapNum; ddmapinfo_t minfo; patchid_t patchId; patchinfo_t info; AutoStr* mapPath; Uri* mapUri; /// @kludge We need to properly externalize the map progression. if((gameModeBits & (GM_DOOM2|GM_DOOM2_PLUT|GM_DOOM2_TNT)) && wbs->nextMap == 30) { return; } /// kludge end. // See if there is a map name. mapUri = G_ComposeMapUri(wbs->episode, wbs->nextMap); mapPath = Uri_Compose(mapUri); if(Def_Get(DD_DEF_MAP_INFO, Str_Text(mapPath), &minfo) && minfo.name) { if(Def_Get(DD_DEF_TEXT, minfo.name, &mapName) == -1) mapName = minfo.name; } Uri_Delete(mapUri); // Skip the E#M# or Map #. if(mapName) { char* ptr = strchr(mapName, ':'); if(ptr) { mapName = M_SkipWhite(ptr + 1); } } DGL_Enable(DGL_TEXTURE_2D); DGL_Color4f(1, 1, 1, 1); FR_SetFont(FID(GF_FONTB)); FR_LoadDefaultAttrib(); FR_SetColorAndAlpha(defFontRGB2[CR], defFontRGB2[CG], defFontRGB2[CB], 1); // Draw "Entering" WI_DrawPatchXY3(pEntering, Hu_ChoosePatchReplacement(cfg.inludePatchReplaceMode, pEntering), x, y, ALIGN_TOP, 0, DTF_NO_TYPEIN); if(R_GetPatchInfo(pMapNames[wbs->nextMap], &info)) y += (5 * info.geometry.size.height) / 4; // Draw map. mapNum = (wbs->episode * 9) + wbs->nextMap; patchId = (mapNum < pMapNamesSize? pMapNames[mapNum] : 0); FR_SetColorAndAlpha(defFontRGB[CR], defFontRGB[CG], defFontRGB[CB], 1); WI_DrawPatchXY3(patchId, Hu_ChoosePatchReplacement2(cfg.inludePatchReplaceMode, patchId, mapName), x, y, ALIGN_TOP, 0, DTF_NO_TYPEIN); DGL_Disable(DGL_TEXTURE_2D); }
virtual void invoke(int player, EventSequenceArg* args, int numArgs) { if(!strchr(Str_Text(&commandTemplate), '%')) { DD_Execute(true/*silent*/, Str_Text(&commandTemplate)); return; } // Compose the command from the template, inserting values for named arguments. /// @todo This logic should be extracted and made into an Str method. AutoStr* cmd = AutoStr_NewStd(); // Reserve an estimate of the composed command length. Str_Reserve(cmd, Str_Length(&commandTemplate) + numArgs + 1); int len = Str_Length(&commandTemplate); const char* start = Str_Text(&commandTemplate); const char* ch = start, *substart = start; while(ch + 1 < start + len) { if(ch[0] == '%' && ch[1] && ch[1] != '%') { Str_PartAppend(cmd, substart, 0, ch - substart); if(ch[1] == 'p') { Str_AppendChar(cmd, '0' + player); } else { int arg = ch[1] - '0' - 1; DENG_ASSERT(arg >= 0 && arg < 9); Str_AppendChar(cmd, char(args[arg])); } ch += 2; substart = ch; } else { ch++; } } // Add anything remaining. Str_Append(cmd, substart); DD_Execute(true/*silent*/, Str_Text(cmd)); }
void Str_Write(const ddstring_t *str, Writer *writer) { size_t len = Str_Length(str); DENG_ASSERT(str); Writer_WriteUInt32(writer, len); Writer_Write(writer, Str_Text(str), len); }
int StringArray_IndexOf(const StringArray *ar, char const *str) { assert(ar); for(uint i = 0; i < ar->array.size(); ++i) { if(!strcmp(str, Str_Text(*ar->array[i]))) return i; } return -1; }
void StringArray_AppendArray(StringArray *ar, StringArray const *other) { assert(ar); assert(other); assert(ar != other); for(StringArray::Strings::const_iterator i = other->array.begin(); i != other->array.end(); ++i) { StringArray_Append(ar, Str_Text(**i)); } }
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! }
size_t Str_Size(Str const *str) { DENG_ASSERT(str); if(!str) return 0; if(str->length) { return str->length; } return strlen(Str_Text(str)); }
static void readUri(Uri* uri, Reader* reader, de::String defaultScheme = "") { Uri_Clear(uri); ddstring_t scheme; Str_InitStd(&scheme); Str_Read(&scheme, reader); ddstring_t path; Str_InitStd(&path); Str_Read(&path, reader); if(Str_IsEmpty(&scheme) && !defaultScheme.isEmpty()) { Str_Set(&scheme, defaultScheme.toUtf8().constData()); } Uri_SetScheme(uri, Str_Text(&scheme)); Uri_SetPath (uri, Str_Text(&path )); }
foreach(Library* lib, loadedLibs) { if(lib->isGamePlugin) { LogBuffer_Printf(DE2_LOG_DEBUG, "Library_ReleaseGames: Closing '%s'\n", Str_Text(lib->path)); // Close the Library. DENG_ASSERT(lib->file); lib->file->clear(); } }
boolean Demo_BeginPlayback(const char* fileName) { ddstring_t buf; if(playback) return false; // Already in playback. if(netGame || isClient) return false; // Can't do it. // Check that we aren't recording anything. { int i; for(i = 0; i < DDMAXPLAYERS; ++i) { if(clients[i].recording) return false; }} // Compose the real file name. Str_InitStd(&buf); Str_Set(&buf, fileName); if(!F_IsAbsolute(&buf)) { Str_Prepend(&buf, demoPath); } F_ExpandBasePath(&buf, &buf); F_ToNativeSlashes(&buf, &buf); // Open the demo file. playdemo = lzOpen(Str_Text(&buf), "rp"); Str_Free(&buf); if(!playdemo) return false; // Failed to open the file. // OK, let's begin the demo. playback = true; isServer = false; isClient = true; readInfo.first = true; viewangleDelta = 0; lookdirDelta = 0; demoFrameZ = 1; demoZ = 0; startFOV = fieldOfView; demoStartTic = DEMOTIC; memset(posDelta, 0, sizeof(posDelta)); // Start counting frames from here. /* if(ArgCheck("-timedemo")) r_framecounter = 0; */ return true; }
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)); } } }
/** * Parse a state condition. */ boolean B_ParseStateCondition(statecondition_t* cond, const char* desc) { AutoStr* str = AutoStr_NewStd(); ddeventtype_t type; // First, we expect to encounter a device name. desc = Str_CopyDelim(str, desc, '-'); if(!Str_CompareIgnoreCase(str, "multiplayer")) { // This is only intended for multiplayer games. cond->type = SCT_STATE; cond->flags.multiplayer = true; } else if(!Str_CompareIgnoreCase(str, "modifier")) { cond->device = 0; // not used cond->type = SCT_MODIFIER_STATE; // Parse the modifier number. desc = Str_CopyDelim(str, desc, '-'); if(!B_ParseModifierId(Str_Text(str), &cond->id)) { return false; } // The final part of a modifier is the state. desc = Str_CopyDelim(str, desc, '-'); if(!B_ParseToggleState(Str_Text(str), &cond->state)) { return false; } } else if(!Str_CompareIgnoreCase(str, "key")) { cond->device = IDEV_KEYBOARD; cond->type = SCT_TOGGLE_STATE; // Parse the key. desc = Str_CopyDelim(str, desc, '-'); if(!B_ParseKeyId(Str_Text(str), &cond->id)) { return false; } // The final part of a key event is the state of the key toggle. desc = Str_CopyDelim(str, desc, '-'); if(!B_ParseToggleState(Str_Text(str), &cond->state)) { return false; } } else if(!Str_CompareIgnoreCase(str, "mouse")) { cond->device = IDEV_MOUSE; // What is being targeted? desc = Str_CopyDelim(str, desc, '-'); if(!B_ParseMouseTypeAndId(Str_Text(str), &type, &cond->id)) { return false; } desc = Str_CopyDelim(str, desc, '-'); if(type == E_TOGGLE) { cond->type = SCT_TOGGLE_STATE; if(!B_ParseToggleState(Str_Text(str), &cond->state)) { return false; } } else if(type == E_AXIS) { cond->type = SCT_AXIS_BEYOND; if(!B_ParseAxisPosition(Str_Text(str), &cond->state, &cond->pos)) { return false; } } } else if(!Str_CompareIgnoreCase(str, "joy")) { cond->device = IDEV_JOY1; // What is being targeted? desc = Str_CopyDelim(str, desc, '-'); if(!B_ParseJoystickTypeAndId(cond->device, Str_Text(str), &type, &cond->id)) { return false; } desc = Str_CopyDelim(str, desc, '-'); if(type == E_TOGGLE) { cond->type = SCT_TOGGLE_STATE; if(!B_ParseToggleState(Str_Text(str), &cond->state)) { return false; } } else if(type == E_AXIS) { cond->type = SCT_AXIS_BEYOND; if(!B_ParseAxisPosition(Str_Text(str), &cond->state, &cond->pos)) { return false; } } else // Angle. { cond->type = SCT_ANGLE_AT; if(!B_ParseAnglePosition(Str_Text(str), &cond->pos)) { return false; } } } else { Con_Message("B_ParseEvent: Device \"%s\" unknown.", Str_Text(str)); return false; } // Check for valid toggle states. if(cond->type == SCT_TOGGLE_STATE && cond->state != EBTOG_UP && cond->state != EBTOG_DOWN) { Con_Message("B_ParseStateCondition: \"%s\": Toggle condition can only be 'up' or 'down'.", desc); return false; } // Finally, there may be the negation at the end. desc = Str_CopyDelim(str, desc, '-'); if(!Str_CompareIgnoreCase(str, "not")) { cond->flags.negate = true; } // Anything left that wasn't used? if(desc) { Con_Message("B_ParseStateCondition: Unrecognized \"%s\".", desc); return false; } // No errors detected. return true; }
de::Action *EventBinding_ActionForEvent(evbinding_t *eb, ddevent_t const *event, struct bcontext_s *eventClass, bool respectHigherAssociatedContexts) { int i; inputdev_t* dev = 0; ddstring_t command; if(eb->device != event->device || eb->type != event->type) return 0; if(event->type != E_SYMBOLIC) { dev = I_GetDevice(eb->device, true); if(!dev) { // The device is not active, there is no way this could get executed. return 0; } } switch(event->type) { case E_TOGGLE: if(eb->id != event->toggle.id) return 0; if(respectHigherAssociatedContexts) { if(eventClass && dev->keys[eb->id].assoc.bContext != eventClass) return 0; // Shadowed by a more important active class. } // We're checking it, so clear the triggered flag. dev->keys[eb->id].assoc.flags &= ~IDAF_TRIGGERED; // Is the state as required? switch(eb->state) { case EBTOG_UNDEFINED: // Passes no matter what. break; case EBTOG_DOWN: if(event->toggle.state != ETOG_DOWN) return 0; break; case EBTOG_UP: if(event->toggle.state != ETOG_UP) return 0; break; case EBTOG_REPEAT: if(event->toggle.state != ETOG_REPEAT) return 0; break; case EBTOG_PRESS: if(event->toggle.state == ETOG_UP) return 0; break; default: return 0; } break; case E_AXIS: if(eb->id != event->axis.id) return 0; if(eventClass && dev->axes[eb->id].assoc.bContext != eventClass) return 0; // Shadowed by a more important active class. // Is the position as required? if(!B_CheckAxisPos(eb->state, eb->pos, I_TransformAxis(I_GetDevice(event->device, false), event->axis.id, event->axis.pos))) return 0; break; case E_ANGLE: if(eb->id != event->angle.id) return 0; if(eventClass && dev->hats[eb->id].assoc.bContext != eventClass) return 0; // Shadowed by a more important active class. // Is the position as required? if(event->angle.pos != eb->pos) return 0; break; case E_SYMBOLIC: if(strcmp(event->symbolic.name, eb->symbolicName)) return 0; break; default: return 0; } // Any conditions on the current state of the input devices? for(i = 0; i < eb->numConds; ++i) { if(!B_CheckCondition(&eb->conds[i], 0, NULL)) return 0; } // Substitute parameters in the command. Str_Init(&command); Str_Reserve(&command, strlen(eb->command)); B_SubstituteInCommand(eb->command, event, eb, &command); de::Action *act = new CommandAction(Str_Text(&command), CMDS_BIND); Str_Free(&command); return act; }
static Uri *readTextureUrn(Reader *reader, char const *schemeName) { DENG_ASSERT(reader && schemeName); return Uri_NewWithPath2(Str_Text(Str_Appendf(AutoStr_NewStd(), "urn:%s:%i", schemeName, Reader_ReadInt16(svReader))), RC_NULL); }
/** * Post Game Initialization routine. * All game-specific actions that should take place at this time go here. */ void D_PostInit(void) { AutoStr* path; Uri* uri; int p; /// @todo Kludge: Border background is different in DOOM2. /// @todo Do this properly! if(gameModeBits & GM_ANY_DOOM2) borderGraphics[0] = "Flats:GRNROCK"; else borderGraphics[0] = "Flats:FLOOR7_2"; // Common post init routine G_CommonPostInit(); // Initialize ammo info. P_InitAmmoInfo(); // Initialize weapon info. P_InitWeaponInfo(); // Game parameters. monsterInfight = GetDefInt("AI|Infight", 0); // Get skill / episode / map from parms. gameSkill = startSkill = SM_NOITEMS; startEpisode = 0; startMap = 0; autoStart = false; // Command line options. noMonstersParm = CommandLine_Check("-nomonsters")? true : false; respawnParm = CommandLine_Check("-respawn")? true : false; fastParm = CommandLine_Check("-fast")? true : false; devParm = CommandLine_Check("-devparm")? true : false; if(CommandLine_Check("-altdeath")) cfg.netDeathmatch = 2; else if(CommandLine_Check("-deathmatch")) cfg.netDeathmatch = 1; p = CommandLine_Check("-timer"); if(p && p < myargc - 1 && deathmatch) { int time = atoi(CommandLine_At(p + 1)); Con_Message("Maps will end after %d %s", time, time == 1? "minute" : "minutes"); } // Turbo option. p = CommandLine_Check("-turbo"); turboMul = 1.0f; if(p) { int scale = 200; turboParm = true; if(p < myargc - 1) scale = atoi(CommandLine_At(p + 1)); if(scale < 10) scale = 10; if(scale > 400) scale = 400; Con_Message("turbo scale: %i%%", scale); turboMul = scale / 100.f; } // Load a saved game? p = CommandLine_Check("-loadgame"); if(p && p < myargc - 1) { const int saveSlot = SV_ParseSlotIdentifier(CommandLine_At(p + 1)); if(SV_IsUserWritableSlot(saveSlot) && G_LoadGame(saveSlot)) { // No further initialization is to be done. return; } } p = CommandLine_Check("-skill"); if(p && p < myargc - 1) { startSkill = CommandLine_At(p + 1)[0] - '1'; autoStart = true; } p = CommandLine_Check("-episode"); if(p && p < myargc - 1) { startEpisode = CommandLine_At(p + 1)[0] - '1'; startMap = 0; autoStart = true; } p = CommandLine_Check("-warp"); if(p && p < myargc - 1) { if(gameModeBits & (GM_ANY_DOOM2|GM_DOOM_CHEX)) { startMap = atoi(CommandLine_At(p + 1)) - 1; autoStart = true; } else if(p < myargc - 2) { startEpisode = CommandLine_At(p + 1)[0] - '1'; startMap = CommandLine_At(p + 2)[0] - '1'; autoStart = true; } } // Are we autostarting? if(autoStart) { if(gameModeBits & (GM_ANY_DOOM2|GM_DOOM_CHEX)) Con_Message("Warp to Map %d, Skill %d", startMap+1, startSkill + 1); else Con_Message("Warp to Episode %d, Map %d, Skill %d", startEpisode+1, startMap+1, startSkill + 1); } // Validate episode and map. uri = G_ComposeMapUri((gameModeBits & (GM_DOOM|GM_DOOM_SHAREWARE|GM_DOOM_ULTIMATE))? startEpisode : 0, startMap); path = Uri_Compose(uri); if((autoStart || IS_NETGAME) && !P_MapExists(Str_Text(path))) { startEpisode = 0; startMap = 0; } Uri_Delete(uri); if(autoStart || IS_NETGAME) { G_DeferredNewGame(startSkill, startEpisode, startMap, 0/*default*/); } else { G_StartTitle(); // Start up intro loop. } }
/** * Parse the main part of the event descriptor, with no conditions included. */ boolean B_ParseEvent(evbinding_t* eb, const char* desc) { AutoStr* str = AutoStr_NewStd(); // First, we expect to encounter a device name. desc = Str_CopyDelim(str, desc, '-'); if(!Str_CompareIgnoreCase(str, "key")) { eb->device = IDEV_KEYBOARD; // Keyboards only have toggles (as far as we know). eb->type = E_TOGGLE; // Parse the key. desc = Str_CopyDelim(str, desc, '-'); if(!B_ParseKeyId(Str_Text(str), &eb->id)) { return false; } // The final part of a key event is the state of the key toggle. desc = Str_CopyDelim(str, desc, '-'); if(!B_ParseToggleState(Str_Text(str), &eb->state)) { return false; } } else if(!Str_CompareIgnoreCase(str, "mouse")) { eb->device = IDEV_MOUSE; // Next comes a button or axis name. desc = Str_CopyDelim(str, desc, '-'); if(!B_ParseMouseTypeAndId(Str_Text(str), &eb->type, &eb->id)) { return false; } // The last part determines the toggle state or the axis position. desc = Str_CopyDelim(str, desc, '-'); if(eb->type == E_TOGGLE) { if(!B_ParseToggleState(Str_Text(str), &eb->state)) { return false; } } else // Axis position. { if(!B_ParseAxisPosition(Str_Text(str), &eb->state, &eb->pos)) { return false; } } } else if(!Str_CompareIgnoreCase(str, "joy")) { eb->device = IDEV_JOY1; // Next part defined button, axis, or hat. desc = Str_CopyDelim(str, desc, '-'); if(!B_ParseJoystickTypeAndId(eb->device, Str_Text(str), &eb->type, &eb->id)) { return false; } // What is the state of the toggle, axis, or hat? desc = Str_CopyDelim(str, desc, '-'); if(eb->type == E_TOGGLE) { if(!B_ParseToggleState(Str_Text(str), &eb->state)) { return false; } } else if(eb->type == E_AXIS) { if(!B_ParseAxisPosition(Str_Text(str), &eb->state, &eb->pos)) { return false; } } else // Angle. { if(!B_ParseAnglePosition(Str_Text(str), &eb->pos)) { return false; } } } else if(!Str_CompareIgnoreCase(str, "sym")) { // It must be a symbolic event. eb->type = E_SYMBOLIC; eb->device = 0; eb->symbolicName = strdup(desc); desc = NULL; } else { Con_Message("B_ParseEvent: Device \"%s\" unknown.", Str_Text(str)); return false; } // Anything left that wasn't used? if(desc) { Con_Message("B_ParseEvent: Unrecognized \"%s\".", desc); return false; } // No errors detected. return true; }
void SV_LoadGameClient(uint /*sessionId*/) { throw de::Error("SV_LoadGameClient", "Not currently implemented"); #if 0 #if !__JHEXEN__ // unsupported in libhexen player_t *cpl = players + CONSOLEPLAYER; mobj_t *mo = cpl->plr->mo; if(!IS_CLIENT || !mo) return; de::game::GameStateFolder *session = new de::game::GameStateFolder(saveNameForClientSessionId(sessionId)); de::game::GameStateMetadata *metadata = new de::game::GameStateMetadata; //G_ReadLegacySessionMetadata(metadata, reader); metadata->set("sessionId", sessionId); session->replaceMetadata(metadata); de::Path path = de::String("/savegame") / "client" / session->path(); if(!SV_OpenFileForRead(path)) { delete session; App_Log(DE2_RES_WARNING, "SV_LoadGameClient: Failed opening \"%s\" for reading", path.toString().toLatin1().constData()); return; } if((*metadata)["magic"].value().asNumber() != MY_CLIENT_SAVE_MAGIC) { SV_CloseFile(); delete session; App_Log(DE2_RES_ERROR, "Client save file format not recognized"); return; } Reader1 *reader = SV_NewReader(); int const saveVersion = (*metadata)["version"].value().asNumber(); Uri *mapUri = Uri_NewWithPath2((*metadata)["mapUri"].value().asText().toUtf8().constData(), RC_NULL); GameRules *rules = 0; if(metadata->hasSubrecord("gameRules")) { rules = GameRules::fromRecord(metadata->subrecord("gameRules")); } // Do we need to change the map? if(gfw_Session()->mapUri() != *reinterpret_cast<de::Uri *>(mapUri)) { gfw_Session()->begin(*mapUri, 0/*default*/, *rules); } else if(rules) { gfw_Session()->rules() = *rules; } delete rules; rules = 0; Uri_Delete(mapUri); mapUri = 0; mapTime = (*metadata)["mapTime"].value().asNumber(); P_MobjUnlink(mo); mo->origin[VX] = FIX2FLT(Reader_ReadInt32(reader)); mo->origin[VY] = FIX2FLT(Reader_ReadInt32(reader)); mo->origin[VZ] = FIX2FLT(Reader_ReadInt32(reader)); P_MobjLink(mo); mo->floorZ = FIX2FLT(Reader_ReadInt32(reader)); mo->ceilingZ = FIX2FLT(Reader_ReadInt32(reader)); mo->angle = Reader_ReadInt32(reader); /* $unifiedangles */ cpl->plr->lookDir = Reader_ReadFloat(reader); /* $unifiedangles */ #if __JHEXEN__ if(saveVersion >= 4) #else if(saveVersion >= 5) #endif { SV_AssertSegment(ASEG_PLAYER_HEADER); } playerheader_t plrHdr; plrHdr.read(reader, saveVersion); cpl->read(reader, plrHdr); MapStateReader(*session).read(Str_Text(Uri_Resolved(mapUri))); SV_CloseFile(); Reader_Delete(reader); delete session; #else DENG2_UNUSED(sessionId); #endif #endif }
Uri* Uri_SetUriStr(Uri* uri, ddstring_t const* path) { SELF(uri); return reinterpret_cast<Uri*>(&self->setUri(Str_Text(path))); }
/// @note Derived from Qt's QByteArray q_toPercentEncoding ddstring_t *Str_PercentEncode2(ddstring_t *str, char const *excludeChars, char const *includeChars) { dd_bool didEncode = false; int i, span, begin, len; ddstring_t buf; DENG_ASSERT(str); if(!str) return 0; if(Str_IsEmpty(str)) return str; len = Str_Length(str); begin = span = 0; for(i = 0; i < len; ++i) { char ch = str->str[i]; // Are we encoding this? if(((ch >= 0x61 && ch <= 0x7A) // ALPHA || (ch >= 0x41 && ch <= 0x5A) // ALPHA || (ch >= 0x30 && ch <= 0x39) // DIGIT || ch == 0x2D // - || ch == 0x2E // . || ch == 0x5F // _ || ch == 0x7E // ~ || (excludeChars && strchr(excludeChars, ch))) && !(includeChars && strchr(includeChars, ch))) { // Not an encodeable. Span grows. span++; } else { // Found an encodeable. if(!didEncode) { Str_InitStd(&buf); Str_Reserve(&buf, len*3); // Worst case. didEncode = true; } Str_PartAppend(&buf, str->str, begin, span); Str_Appendf(&buf, "%%%X", (uint)ch); // Start a new span. begin += span + 1; span = 0; } } if(didEncode) { // Copy anything remaining. if(span) { Str_PartAppend(&buf, str->str, begin, span); } Str_Set(str, Str_Text(&buf)); Str_Free(&buf); } return str; }
int Str_CompareIgnoreCase(const ddstring_t *str, char const *text) { DENG_ASSERT(str); return strcasecmp(Str_Text(str), text); }
void FI_StackExecuteWithId(const char* scriptSrc, int flags, finale_mode_t mode, const char* defId) { fi_state_t* s, *prevTopScript; gamestate_t prevGamestate; ddstring_t setupCmds; finaleid_t finaleId; int i, fontIdx; if(!finaleStackInited) Con_Error("FI_StackExecute: Not initialized yet!"); // Should we ignore this? if(defId && stackHasDefId(defId)) { Con_Message("There already is a finale running with ID \"%s\"; won't execute again.", defId); return; } prevGamestate = G_GameState(); prevTopScript = stackTop(); // Configure the predefined fonts. Str_Init(&setupCmds); fontIdx = 1; Str_Appendf(&setupCmds, "prefont %i %s", fontIdx++, "a"); Str_Appendf(&setupCmds, "\nprefont %i %s", fontIdx++, "b"); Str_Appendf(&setupCmds, "\nprefont %i %s", fontIdx++, "status"); #if __JDOOM__ Str_Appendf(&setupCmds, "\nprefont %i %s", fontIdx++, "index"); #endif #if __JDOOM__ || __JDOOM64__ Str_Appendf(&setupCmds, "\nprefont %i %s", fontIdx++, "small"); #endif #if __JHERETIC__ || __JHEXEN__ Str_Appendf(&setupCmds, "\nprefont %i %s", fontIdx++, "smallin"); #endif // Configure the predefined colors. #if __JDOOM__ Str_Appendf(&setupCmds, "\nprecolor 2 %f %f %f\n", defFontRGB[CR], defFontRGB[CG], defFontRGB[CB]); Str_Appendf(&setupCmds, "\nprecolor 1 %f %f %f\n", defFontRGB2[CR], defFontRGB2[CG], defFontRGB2[CB]); Str_Appendf(&setupCmds, "\nprecolor 3 %f %f %f\n", defFontRGB3[CR], defFontRGB3[CG], defFontRGB3[CB]); i = 4; #elif __JHERETIC__ Str_Appendf(&setupCmds, "\nprecolor 3 %f %f %f\n", defFontRGB[CR], defFontRGB[CG], defFontRGB[CB]); Str_Appendf(&setupCmds, "\nprecolor 2 %f %f %f\n", defFontRGB2[CR], defFontRGB2[CG], defFontRGB2[CB]); Str_Appendf(&setupCmds, "\nprecolor 1 %f %f %f\n", defFontRGB3[CR], defFontRGB3[CG], defFontRGB3[CB]); i = 4; #elif __JHEXEN__ Str_Appendf(&setupCmds, "\nprecolor 3 %f %f %f\n", defFontRGB[CR], defFontRGB[CG], defFontRGB[CB]); Str_Appendf(&setupCmds, "\nprecolor 2 %f %f %f\n", defFontRGB2[CR], defFontRGB2[CG], defFontRGB2[CB]); Str_Appendf(&setupCmds, "\nprecolor 1 %f %f %f\n", defFontRGB3[CR], defFontRGB3[CG], defFontRGB3[CB]); i = 4; #elif __JDOOM64__ Str_Appendf(&setupCmds, "\nprecolor 2 %f %f %f\n", defFontRGB[CR], defFontRGB[CG], defFontRGB[CB]); Str_Appendf(&setupCmds, "\nprecolor 1 %f %f %f\n", defFontRGB2[CR], defFontRGB2[CG], defFontRGB2[CB]); i = 3; #else i = 0; #endif // Set the rest to white. for(; i <= FIPAGE_NUM_PREDEFINED_COLORS; ++i) { Str_Appendf(&setupCmds, "\nprecolor %i 1 1 1\n", i); } finaleId = FI_Execute2(scriptSrc, flags, Str_Text(&setupCmds)); Str_Free(&setupCmds); if(finaleId == 0) return; if(mode != FIMODE_OVERLAY) { G_ChangeGameState(GS_INFINE); } // Only the top-most script can be "active". if(prevTopScript) { FI_ScriptSuspend(prevTopScript->finaleId); } s = stackPush(finaleId, mode, prevGamestate, defId); // Do we need to transmit the state conditions to clients? if(IS_SERVER && !(flags & FF_LOCAL)) { NetSv_SendFinaleState(s); } }
char const *StringArray_At(const StringArray *ar, int index) { assert(ar); ar->assertValidIndex(index); return Str_Text(*ar->array[index]); }