示例#1
0
ddstring_t *Str_Copy(ddstring_t *str, const ddstring_t *other)
{
    DENG_ASSERT(str);
    DENG_ASSERT(other);
    if(!str || !other) return str;

    Str_Free(str);

    if(!other->size)
    {
        // The original string has no memory allocated; it's a static string.
        allocateString(str, other->length, false);
        if(other->str)
            strcpy(str->str, other->str);
        str->length = other->length;
    }
    else
    {
        // Duplicate the other string's buffer in its entirety.
        str->str = str->memAlloc(other->size);
        memcpy(str->str, other->str, other->size);
        str->size = other->size;
        str->length = other->length;
    }
    return str;
}
示例#2
0
char const *Str_CopyDelim2(ddstring_t *str, char const *src, char delimiter, int cdflags)
{
    DENG_ASSERT(str);
    if(!str) return 0;

    Str_Clear(str);

    if(!src) return 0;

    { char const *cursor;
    ddstring_t buf; Str_Init(&buf);
    for(cursor = src; *cursor && *cursor != delimiter; ++cursor)
    {
        if((cdflags & CDF_OMIT_WHITESPACE) && isspace(*cursor))
            continue;
        Str_PartAppend(&buf, cursor, 0, 1);
    }
    if(!Str_IsEmpty(&buf))
        Str_Copy(str, &buf);
    Str_Free(&buf);

    if(!*cursor)
        return 0; // It ended.

    if(!(cdflags & CDF_OMIT_DELIMITER))
        Str_PartAppend(str, cursor, 0, 1);

    // Skip past the delimiter.
    return cursor + 1;
    }
}
示例#3
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
}
示例#4
0
static void deleteString(Str *str)
{
    DENG_ASSERT(str);
    if(!str) return;

    Str_Free(str);
    M_Free(str);
}
示例#5
0
void Buffer_Kill(BUFFER *bf)
{
    Str_Require(bf!=NULL);
    Str_Require(bf->at == NULL && bf->capacity == 0 && bf->count == 0 ||
                bf->at != NULL && bf->capacity >= bf->count );

    if ( bf->at )
        Str_Free(bf->at);

    bf->count = bf->capacity = 0;
}
示例#6
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;
}
 virtual ~SequenceCompleteCommandHandler()
 {
     Str_Free(&commandTemplate);
 }
 ~EventSequence()
 {
     Str_Free(&sequence);
     if(args) delete[] args;
     delete &handler;
 }
示例#9
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;
}
示例#10
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;
}
示例#11
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);
    }
}
示例#12
0
void SaveInfo_Delete(SaveInfo *info)
{
    DENG_ASSERT(info != 0);
    Str_Free(&info->name);
    M_Free(info);
}