commit x64 compilation from lulu cause the other branch dont seems to compile properly at home
This commit is contained in:
173
include/engine/core/ace.cpp
Normal file
173
include/engine/core/ace.cpp
Normal file
@ -0,0 +1,173 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#include "core/ace.h"
|
||||
#include "ascii/parser.h"
|
||||
#include "log/log.h"
|
||||
|
||||
using namespace GS::ACE;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Manager::UpdateACEUnit(Unit *u, float dt)
|
||||
{
|
||||
if (!u->pc)
|
||||
u->is_done = true;
|
||||
if (u->is_done)
|
||||
return;
|
||||
|
||||
// Execute sequence until next exec opcode.
|
||||
bool has_exec_left = false, looped = false;
|
||||
|
||||
List <Command> ::Item *cpc;
|
||||
for (cpc = u->pc; cpc; cpc = cpc->Next())
|
||||
{
|
||||
Command *cmd = &cpc->Object();
|
||||
if (cmd->code == AceCommandExec)
|
||||
{
|
||||
cpc = cpc->Next();
|
||||
break;
|
||||
}
|
||||
|
||||
if (cmd->duration_left > 0.00001)
|
||||
{
|
||||
float exec_dt = cmd->duration_left;
|
||||
if (dt < cmd->duration_left)
|
||||
{
|
||||
exec_dt = dt;
|
||||
has_exec_left = true;
|
||||
}
|
||||
|
||||
u->ExecCommand(cmd, exec_dt);
|
||||
cmd->duration_left -= exec_dt;
|
||||
|
||||
if (cmd->code == AceCommandNext)
|
||||
looped = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Sequence done.
|
||||
if (looped)
|
||||
{
|
||||
// We need to reset the looping block commands duration.
|
||||
for (List <Command> ::Item *lpc = u->loop_pc; lpc != cpc; lpc = lpc->Next())
|
||||
lpc->Object().duration_left = lpc->Object().duration;
|
||||
}
|
||||
else
|
||||
if (!has_exec_left)
|
||||
u->pc = cpc;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static bool DefineNameCompare(const Define *o, const GS::String &name) { return o->id == name; }
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int Manager::LoadACECommandList(const char *s, Unit *u) const
|
||||
{
|
||||
if (!s)
|
||||
__ERR__(__LOG_E__ << "Cannot load a null command list.\n", -1);
|
||||
|
||||
u->ResetCommandList();
|
||||
|
||||
using namespace AsciiParser;
|
||||
|
||||
// Parse command list.
|
||||
const char *e = s + String::strlen(s);
|
||||
s = SkipSpace(s, e);
|
||||
|
||||
while (s < e)
|
||||
{
|
||||
Command &cc = u->list.Add(Command())->Object();
|
||||
|
||||
// Read in code.
|
||||
String command(s, SkipEntry(s, e));
|
||||
|
||||
Define *d = ArrayListFindEx(define_list, DefineNameCompare, command);
|
||||
if (!d)
|
||||
__ERR__(__LOG_E__ << "Undefined ACE command '" << command << "'.\n", -1);
|
||||
cc.code = d->code;
|
||||
|
||||
// Read in duration.
|
||||
s = NextEntry(s, e);
|
||||
if (s == e)
|
||||
__ERR__(__LOG_E__ << "No duration for ACE command '" << command << "'.\n", -1);
|
||||
|
||||
cc.duration = String(s, SkipEntry(s, e)).Float();
|
||||
if (cc.duration < 0.001f)
|
||||
cc.duration = 0.001f; // Force minimum duration to 1ms.
|
||||
cc.duration_left = cc.duration;
|
||||
|
||||
// Read up to 3 parameters.
|
||||
s = NextEntry(s, e);
|
||||
uint nparm = 0;
|
||||
|
||||
while (s < e)
|
||||
{
|
||||
if ((s[0] == '+') || (s[0] == ';'))
|
||||
break;
|
||||
|
||||
if (nparm == 3)
|
||||
__ERR__(__LOG_E__ << "ACE compiled with " << max_command_param << " command parameter(s) maximum.\n", -1);
|
||||
if (s[0] != ',')
|
||||
__ERR__(__LOG_E__ << "Expected ',' in ACE list declaration.\n", -1);
|
||||
s = SkipSpace(s + 1, e);
|
||||
if (s == e)
|
||||
__ERR__(__LOG_E__ << "Expected ACE command parameter following ','.\n", -1);
|
||||
|
||||
String parm(s, SkipEntry(s, e, true));
|
||||
cc.parm[nparm++] = parm.Float();
|
||||
s = SkipSpace(SkipEntry(s, e, true), e);
|
||||
}
|
||||
if (s == e)
|
||||
__ERR__(__LOG_E__ << "Mangled ACE command list.\n", -1);
|
||||
if ((uint)d->nparm != nparm)
|
||||
__ERR__(__LOG_E__ << "ACE command '" << command << "' takes " << d->nparm << " parameter(s), found " << nparm << ".\n", -1);
|
||||
|
||||
// Output exec command.
|
||||
if (s[0] == ';')
|
||||
u->list.Add(Command())->Object().code = AceCommandExec;
|
||||
|
||||
s = SkipSpace(s + 1, e); // Skip comma.
|
||||
}
|
||||
|
||||
// Set PC to list root command.
|
||||
u->is_done = false;
|
||||
u->pc = u->list.GetRoot();
|
||||
return u->list.GetCount();
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Manager::DefineACECommand(const char *command, int code, int nparm, bool user_code)
|
||||
{
|
||||
if (user_code && (code < 0))
|
||||
__ERR__(__LOG_E__ << "Negative command codes are reserved.\n", false)
|
||||
|
||||
Define *d = new Define;
|
||||
if (!d)
|
||||
__ERR__(__LOG_E__ << "Failed to allocate new container to define ACE command '" << command << "'.\n", false)
|
||||
|
||||
d->id = command;
|
||||
d->code = code;
|
||||
d->nparm = nparm;
|
||||
|
||||
define_list.Add(d);
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Manager::Manager()
|
||||
{
|
||||
DefineACECommand("nop", AceCommandNop, 0, false);
|
||||
DefineACECommand("loop", AceCommandLoop, 0, false);
|
||||
DefineACECommand("next", AceCommandNext, 0, false);
|
||||
}
|
||||
Manager::~Manager()
|
||||
{
|
||||
ArrayListDeleteAllPtr(Define *, define_list)
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
Reference in New Issue
Block a user