Beispiel #1
0
/**
 * 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;
}
Beispiel #2
0
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
}
Beispiel #3
0
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);
}
Beispiel #4
0
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;
}
Beispiel #5
0
/**
 * 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
}
Beispiel #6
0
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));
    }
Beispiel #8
0
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));
    }
}
Beispiel #11
0
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!
}
Beispiel #12
0
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));
}
Beispiel #13
0
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  ));
}
Beispiel #14
0
    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();
        }
    }
Beispiel #15
0
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));
        }
    }
}
Beispiel #17
0
/**
 * 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;
}
Beispiel #18
0
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;
}
Beispiel #19
0
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);
}
Beispiel #20
0
/**
 * 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.
    }
}
Beispiel #21
0
/**
 * 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;
}
Beispiel #22
0
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
}
Beispiel #23
0
Uri* Uri_SetUriStr(Uri* uri, ddstring_t const* path)
{
    SELF(uri);
    return reinterpret_cast<Uri*>(&self->setUri(Str_Text(path)));
}
Beispiel #24
0
/// @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;
}
Beispiel #25
0
int Str_CompareIgnoreCase(const ddstring_t *str, char const *text)
{
    DENG_ASSERT(str);
    return strcasecmp(Str_Text(str), text);
}
Beispiel #26
0
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]);
}