openmohaa/code/fgame/gamescript.h

206 lines
5.6 KiB
C
Raw Normal View History

2016-03-27 11:49:47 +02:00
/*
===========================================================================
Copyright (C) 2025 the OpenMoHAA team
2016-03-27 11:49:47 +02:00
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// gamescript.h: Subclass of script that preprocesses labels
#pragma once
2016-03-27 11:49:47 +02:00
#include "class.h"
#include "script.h"
#include "archive.h"
class Listener;
class ScriptThread;
2023-04-29 21:56:38 +02:00
class ScriptVariable;
2016-03-27 11:49:47 +02:00
class GameScript;
typedef struct {
2023-09-09 16:46:42 +02:00
byte *codepos; // code position pointer
const_str key; // label name
bool isprivate; // new script engine implementation
2016-03-27 11:49:47 +02:00
} script_label_t;
struct sourceinfo_t {
2023-09-09 16:46:42 +02:00
unsigned int sourcePos;
unsigned int startLinePos;
2023-09-09 16:46:42 +02:00
int column;
int line;
sourceinfo_t()
: sourcePos(0)
, column(0)
, line(0)
{}
};
2016-03-27 11:49:47 +02:00
2023-09-09 16:46:42 +02:00
class AbstractScript
{
2016-03-27 11:49:47 +02:00
public:
2023-09-09 16:46:42 +02:00
// File variables
const_str m_Filename;
char *m_SourceBuffer;
size_t m_SourceLength;
2016-03-27 11:49:47 +02:00
2023-09-09 16:46:42 +02:00
// Developper variable
2023-10-27 19:59:15 +02:00
con_set<const uchar *, sourceinfo_t> *m_ProgToSource;
2016-03-27 11:49:47 +02:00
sourceinfo_t cachedInfo[16];
size_t cachedInfoIndex;
2016-03-27 11:49:47 +02:00
public:
2023-09-09 16:46:42 +02:00
AbstractScript();
str& Filename(void);
2023-09-09 16:46:42 +02:00
const_str ConstFilename(void);
bool GetSourceAt(size_t sourcePos, str *sourceLine, int& column, int& line);
bool GetSourceAt(const unsigned char *sourcePos, str *sourceLine, int& column, int& line);
2023-09-09 16:46:42 +02:00
void PrintSourcePos(sourceinfo_t *sourcePos, bool dev);
void PrintSourcePos(size_t sourcePos, bool dev);
void PrintSourcePos(unsigned char *m_pCodePos, bool dev);
void PrintSourcePos(str sourceLine, int column, int line, bool dev);
2016-03-27 11:49:47 +02:00
};
class StateScript : public Class
{
2023-09-09 16:46:42 +02:00
friend class GameScript;
2016-03-27 11:49:47 +02:00
private:
2023-09-09 16:46:42 +02:00
// Label list
con_set<const_str, script_label_t> label_list;
2016-03-27 11:49:47 +02:00
public:
2023-09-09 16:46:42 +02:00
// Parent gamescript
GameScript *m_Parent;
2016-03-27 11:49:47 +02:00
public:
2023-09-09 16:46:42 +02:00
StateScript();
2016-03-27 11:49:47 +02:00
2023-09-09 16:46:42 +02:00
void Archive(Archiver& arc) override;
2016-03-27 11:49:47 +02:00
2023-09-09 16:46:42 +02:00
bool AddLabel(str label, unsigned char *pos, bool private_section = false);
bool AddLabel(const_str label, unsigned char *pos, bool private_section = false);
unsigned char *FindLabel(str label);
unsigned char *FindLabel(const_str label);
const_str NearestLabel(unsigned char *pos);
2016-03-27 11:49:47 +02:00
};
2023-09-09 16:46:42 +02:00
class CatchBlock
{
2016-03-27 11:49:47 +02:00
public:
2023-09-09 16:46:42 +02:00
// program variable
StateScript m_StateScript;
2016-03-27 11:49:47 +02:00
2023-09-09 16:46:42 +02:00
// code position variables
unsigned char *m_TryStartCodePos;
unsigned char *m_TryEndCodePos;
2016-03-27 11:49:47 +02:00
};
2023-09-09 16:46:42 +02:00
class GameScript : public AbstractScript
{
2016-03-27 11:49:47 +02:00
protected:
2023-09-09 16:46:42 +02:00
// try/throw variable
Container<CatchBlock *> m_CatchBlocks;
Container<StateScript *> m_StateScripts;
2016-03-27 11:49:47 +02:00
public:
2023-09-09 16:46:42 +02:00
// program variables
StateScript m_State;
unsigned char *m_ProgBuffer;
size_t m_ProgLength;
2016-03-27 11:49:47 +02:00
2023-09-09 16:46:42 +02:00
// compile variables
bool successCompile;
bool m_bPrecompiled;
2016-03-27 11:49:47 +02:00
2023-09-09 16:46:42 +02:00
// stack variables
unsigned int requiredStackSize;
2016-03-27 11:49:47 +02:00
public:
2023-09-09 16:46:42 +02:00
GameScript();
GameScript(const char *filename);
~GameScript();
2016-03-27 11:49:47 +02:00
void Archive(Archiver& arc);
2023-09-09 16:46:42 +02:00
static void Archive(Archiver& arc, GameScript *& scr);
void ArchiveCodePos(Archiver& arc, unsigned char **codePos);
2016-03-27 11:49:47 +02:00
2023-09-09 16:46:42 +02:00
void Close(void);
void Load(const void *sourceBuffer, size_t sourceLength);
2016-03-27 11:49:47 +02:00
2023-09-09 16:46:42 +02:00
bool GetCodePos(unsigned char *codePos, str& filename, int& pos);
bool SetCodePos(unsigned char *& codePos, str& filename, int pos);
2016-03-27 11:49:47 +02:00
2023-09-09 16:46:42 +02:00
unsigned int GetRequiredStackSize(void);
2016-03-27 11:49:47 +02:00
2023-09-09 16:46:42 +02:00
qboolean labelExists(const char *name);
2016-03-27 11:49:47 +02:00
2023-09-09 16:46:42 +02:00
StateScript *CreateCatchStateScript(unsigned char *try_begin_code_pos, unsigned char *try_end_code_pos);
StateScript *CreateSwitchStateScript(void);
2016-03-27 11:49:47 +02:00
2023-09-09 16:46:42 +02:00
StateScript *GetCatchStateScript(unsigned char *in, unsigned char *& out);
2016-03-27 11:49:47 +02:00
2023-09-09 16:46:42 +02:00
bool ScriptCheck(void);
2016-03-27 11:49:47 +02:00
};
2023-09-09 16:46:42 +02:00
class ScriptThreadLabel
{
2016-03-27 11:49:47 +02:00
private:
2023-09-09 16:46:42 +02:00
GameScript *m_Script;
const_str m_Label;
2016-03-27 11:49:47 +02:00
public:
2023-09-09 16:46:42 +02:00
ScriptThreadLabel();
2016-03-27 11:49:47 +02:00
ScriptThread *Create(Listener *listener) const;
void Execute(Listener *listener = NULL) const;
void Execute(Listener *listener, Event& ev) const;
void Execute(Listener *listener, Event *ev) const;
void Execute(Listener *pSelf, const SafePtr<Listener>& listener, const SafePtr<Listener>& param) const;
2016-03-27 11:49:47 +02:00
void Clear();
2023-09-09 16:46:42 +02:00
void Set(const char *label);
void Set(const_str label);
void SetScript(const ScriptVariable& label);
void SetScript(const char *label);
void SetScript(const_str label);
void SetThread(const ScriptVariable& label);
2016-03-27 11:49:47 +02:00
2023-09-09 16:46:42 +02:00
bool TrySet(const_str label);
bool TrySet(const char *label);
bool TrySetScript(const_str label);
bool TrySetScript(const char *label);
2016-03-27 11:49:47 +02:00
bool IsSet(void) const;
bool IsFile(const_str filename) const;
2018-09-05 16:55:10 +02:00
void GetScriptValue(ScriptVariable *var) const;
2018-08-05 17:56:40 +02:00
2023-09-09 16:46:42 +02:00
void Archive(Archiver& arc);
2016-03-27 11:49:47 +02:00
2023-09-09 16:46:42 +02:00
friend bool operator==(const ScriptThreadLabel& a, const ScriptThreadLabel& b);
2016-03-27 11:49:47 +02:00
};
2023-09-09 16:46:42 +02:00
inline bool operator==(const ScriptThreadLabel& a, const ScriptThreadLabel& b)
2018-09-05 16:55:10 +02:00
{
2023-09-09 16:46:42 +02:00
return a.m_Label == b.m_Label && a.m_Script == b.m_Script;
2018-09-05 16:55:10 +02:00
}