fallout2-ce/src/export.cc

350 lines
9.7 KiB
C++
Raw Permalink Normal View History

2022-05-19 01:51:26 -07:00
#include "export.h"
2022-09-15 02:38:23 -07:00
#include <ctype.h>
#include <string.h>
2022-05-19 01:51:26 -07:00
#include "interpreter_lib.h"
#include "memory_manager.h"
#include "platform_compat.h"
2022-05-19 01:51:26 -07:00
2022-09-23 05:43:44 -07:00
namespace fallout {
2022-06-18 06:39:39 -07:00
typedef struct ExternalVariable {
char name[32];
char* programName;
2022-07-05 01:00:55 -07:00
ProgramValue value;
char* stringValue;
2022-06-18 06:39:39 -07:00
} ExternalVariable;
typedef struct ExternalProcedure {
char name[32];
Program* program;
int argumentCount;
int address;
} ExternalProcedure;
static unsigned int _hashName(const char* identifier);
static ExternalProcedure* externalProcedureFind(const char* identifier);
static ExternalProcedure* externalProcedureAdd(const char* identifier);
static ExternalVariable* externalVariableFind(const char* identifier);
static ExternalVariable* externalVariableAdd(const char* identifier);
static void _removeProgramReferences(Program* program);
2022-05-19 01:51:26 -07:00
// 0x570C00
2022-06-18 06:39:39 -07:00
static ExternalProcedure gExternalProcedures[1013];
2022-05-19 01:51:26 -07:00
// 0x57BA1C
2022-06-18 06:39:39 -07:00
static ExternalVariable gExternalVariables[1013];
2022-05-19 01:51:26 -07:00
// NOTE: Inlined.
//
// 0x440F10
unsigned int _hashName(const char* identifier)
{
unsigned int v1 = 0;
const char* pch = identifier;
while (*pch != '\0') {
int ch = *pch & 0xFF;
v1 += (tolower(ch) & 0xFF) + (v1 * 8) + (v1 >> 29);
pch++;
}
v1 = v1 % 1013;
return v1;
}
// 0x440F58
ExternalProcedure* externalProcedureFind(const char* identifier)
{
// NOTE: Uninline.
unsigned int v1 = _hashName(identifier);
unsigned int v2 = v1;
ExternalProcedure* externalProcedure = &(gExternalProcedures[v1]);
2024-01-16 07:57:49 -08:00
if (externalProcedure->program != nullptr) {
if (compat_stricmp(externalProcedure->name, identifier) == 0) {
2022-05-19 01:51:26 -07:00
return externalProcedure;
}
}
do {
v1 += 7;
if (v1 >= 1013) {
v1 -= 1013;
}
externalProcedure = &(gExternalProcedures[v1]);
2024-01-16 07:57:49 -08:00
if (externalProcedure->program != nullptr) {
if (compat_stricmp(externalProcedure->name, identifier) == 0) {
2022-05-19 01:51:26 -07:00
return externalProcedure;
}
}
} while (v1 != v2);
2024-01-16 07:57:49 -08:00
return nullptr;
2022-05-19 01:51:26 -07:00
}
// 0x441018
ExternalProcedure* externalProcedureAdd(const char* identifier)
{
// NOTE: Uninline.
unsigned int v1 = _hashName(identifier);
unsigned int a2 = v1;
ExternalProcedure* externalProcedure = &(gExternalProcedures[v1]);
if (externalProcedure->name[0] == '\0') {
return externalProcedure;
}
do {
v1 += 7;
if (v1 >= 1013) {
v1 -= 1013;
}
externalProcedure = &(gExternalProcedures[v1]);
if (externalProcedure->name[0] == '\0') {
return externalProcedure;
}
} while (v1 != a2);
2024-01-16 07:57:49 -08:00
return nullptr;
2022-05-19 01:51:26 -07:00
}
// 0x4410AC
ExternalVariable* externalVariableFind(const char* identifier)
{
// NOTE: Uninline.
unsigned int v1 = _hashName(identifier);
unsigned int v2 = v1;
ExternalVariable* exportedVariable = &(gExternalVariables[v1]);
if (compat_stricmp(exportedVariable->name, identifier) == 0) {
2022-05-19 01:51:26 -07:00
return exportedVariable;
}
do {
exportedVariable = &(gExternalVariables[v1]);
if (exportedVariable->name[0] == '\0') {
break;
}
v1 += 7;
if (v1 >= 1013) {
v1 -= 1013;
}
exportedVariable = &(gExternalVariables[v1]);
if (compat_stricmp(exportedVariable->name, identifier) == 0) {
2022-05-19 01:51:26 -07:00
return exportedVariable;
}
} while (v1 != v2);
2024-01-16 07:57:49 -08:00
return nullptr;
2022-05-19 01:51:26 -07:00
}
// 0x44118C
ExternalVariable* externalVariableAdd(const char* identifier)
{
// NOTE: Uninline.
unsigned int v1 = _hashName(identifier);
unsigned int v2 = v1;
ExternalVariable* exportedVariable = &(gExternalVariables[v1]);
if (exportedVariable->name[0] == '\0') {
return exportedVariable;
}
do {
v1 += 7;
if (v1 >= 1013) {
v1 -= 1013;
}
exportedVariable = &(gExternalVariables[v1]);
if (exportedVariable->name[0] == '\0') {
return exportedVariable;
}
} while (v1 != v2);
2024-01-16 07:57:49 -08:00
return nullptr;
2022-05-19 01:51:26 -07:00
}
// 0x44127C
2022-07-05 01:00:55 -07:00
int externalVariableSetValue(Program* program, const char* name, ProgramValue& programValue)
2022-05-19 01:51:26 -07:00
{
ExternalVariable* exportedVariable = externalVariableFind(name);
2024-01-16 07:57:49 -08:00
if (exportedVariable == nullptr) {
2022-05-19 01:51:26 -07:00
return 1;
}
if ((exportedVariable->value.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
2022-05-19 01:51:26 -07:00
internal_free_safe(exportedVariable->stringValue, __FILE__, __LINE__); // "..\\int\\EXPORT.C", 169
}
if ((programValue.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
2024-01-16 07:57:49 -08:00
if (program != nullptr) {
2022-07-05 01:00:55 -07:00
const char* stringValue = programGetString(program, programValue.opcode, programValue.integerValue);
exportedVariable->value.opcode = VALUE_TYPE_DYNAMIC_STRING;
2022-05-19 01:51:26 -07:00
2022-05-21 08:22:03 -07:00
exportedVariable->stringValue = (char*)internal_malloc_safe(strlen(stringValue) + 1, __FILE__, __LINE__); // "..\\int\\EXPORT.C", 175
2022-05-19 01:51:26 -07:00
strcpy(exportedVariable->stringValue, stringValue);
}
} else {
2022-07-05 01:00:55 -07:00
exportedVariable->value = programValue;
2022-05-19 01:51:26 -07:00
}
return 0;
}
// 0x4413D4
2022-07-05 01:00:55 -07:00
int externalVariableGetValue(Program* program, const char* name, ProgramValue& value)
2022-05-19 01:51:26 -07:00
{
ExternalVariable* exportedVariable = externalVariableFind(name);
2024-01-16 07:57:49 -08:00
if (exportedVariable == nullptr) {
2022-05-19 01:51:26 -07:00
return 1;
}
if ((exportedVariable->value.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
2022-07-05 01:00:55 -07:00
value.opcode = exportedVariable->value.opcode;
value.integerValue = programPushString(program, exportedVariable->stringValue);
2022-05-19 01:51:26 -07:00
} else {
2022-07-05 01:00:55 -07:00
value = exportedVariable->value;
2022-05-19 01:51:26 -07:00
}
return 0;
}
// 0x4414B8
int externalVariableCreate(Program* program, const char* identifier)
{
const char* programName = program->name;
ExternalVariable* exportedVariable = externalVariableFind(identifier);
2024-01-16 07:57:49 -08:00
if (exportedVariable != nullptr) {
if (compat_stricmp(exportedVariable->programName, programName) != 0) {
2022-05-19 01:51:26 -07:00
return 1;
}
if ((exportedVariable->value.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
2022-05-19 01:51:26 -07:00
internal_free_safe(exportedVariable->stringValue, __FILE__, __LINE__); // "..\\int\\EXPORT.C", 234
}
} else {
exportedVariable = externalVariableAdd(identifier);
2024-01-16 07:57:49 -08:00
if (exportedVariable == nullptr) {
2022-05-19 01:51:26 -07:00
return 1;
}
strncpy(exportedVariable->name, identifier, 31);
2022-05-21 08:22:03 -07:00
exportedVariable->programName = (char*)internal_malloc_safe(strlen(programName) + 1, __FILE__, __LINE__); // // "..\\int\\EXPORT.C", 243
2022-05-19 01:51:26 -07:00
strcpy(exportedVariable->programName, programName);
}
2022-07-05 01:00:55 -07:00
exportedVariable->value.opcode = VALUE_TYPE_INT;
exportedVariable->value.integerValue = 0;
2022-05-19 01:51:26 -07:00
return 0;
}
// 0x4414FC
void _removeProgramReferences(Program* program)
{
for (int index = 0; index < 1013; index++) {
ExternalProcedure* externalProcedure = &(gExternalProcedures[index]);
if (externalProcedure->program == program) {
externalProcedure->name[0] = '\0';
2024-01-16 07:57:49 -08:00
externalProcedure->program = nullptr;
2022-05-19 01:51:26 -07:00
}
}
}
// 0x44152C
void _initExport()
{
intLibRegisterProgramDeleteCallback(_removeProgramReferences);
2022-05-19 01:51:26 -07:00
}
// 0x441538
void externalVariablesClear()
{
for (int index = 0; index < 1013; index++) {
ExternalVariable* exportedVariable = &(gExternalVariables[index]);
if (exportedVariable->name[0] != '\0') {
internal_free_safe(exportedVariable->programName, __FILE__, __LINE__); // ..\\int\\EXPORT.C, 274
}
2022-07-05 01:00:55 -07:00
if (exportedVariable->value.opcode == VALUE_TYPE_DYNAMIC_STRING) {
2022-05-19 01:51:26 -07:00
internal_free_safe(exportedVariable->stringValue, __FILE__, __LINE__); // ..\\int\\EXPORT.C, 276
}
}
}
// 0x44158C
Program* externalProcedureGetProgram(const char* identifier, int* addressPtr, int* argumentCountPtr)
{
ExternalProcedure* externalProcedure = externalProcedureFind(identifier);
2024-01-16 07:57:49 -08:00
if (externalProcedure == nullptr) {
return nullptr;
2022-05-19 01:51:26 -07:00
}
2024-01-16 07:57:49 -08:00
if (externalProcedure->program == nullptr) {
return nullptr;
2022-05-19 01:51:26 -07:00
}
*addressPtr = externalProcedure->address;
*argumentCountPtr = externalProcedure->argumentCount;
return externalProcedure->program;
}
// 0x4415B0
int externalProcedureCreate(Program* program, const char* identifier, int address, int argumentCount)
{
ExternalProcedure* externalProcedure = externalProcedureFind(identifier);
2024-01-16 07:57:49 -08:00
if (externalProcedure != nullptr) {
2022-05-19 01:51:26 -07:00
if (program != externalProcedure->program) {
return 1;
}
} else {
externalProcedure = externalProcedureAdd(identifier);
2024-01-16 07:57:49 -08:00
if (externalProcedure == nullptr) {
2022-05-19 01:51:26 -07:00
return 1;
}
strncpy(externalProcedure->name, identifier, 31);
}
externalProcedure->argumentCount = argumentCount;
externalProcedure->address = address;
externalProcedure->program = program;
return 0;
}
// 0x441824
void _exportClearAllVariables()
{
for (int index = 0; index < 1013; index++) {
ExternalVariable* exportedVariable = &(gExternalVariables[index]);
if (exportedVariable->name[0] != '\0') {
if ((exportedVariable->value.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
2024-01-16 07:57:49 -08:00
if (exportedVariable->stringValue != nullptr) {
2022-05-19 01:51:26 -07:00
internal_free_safe(exportedVariable->stringValue, __FILE__, __LINE__); // "..\\int\\EXPORT.C", 387
}
}
2024-01-16 07:57:49 -08:00
if (exportedVariable->programName != nullptr) {
2022-05-19 01:51:26 -07:00
internal_free_safe(exportedVariable->programName, __FILE__, __LINE__); // "..\\int\\EXPORT.C", 393
2024-01-16 07:57:49 -08:00
exportedVariable->programName = nullptr;
2022-05-19 01:51:26 -07:00
}
exportedVariable->name[0] = '\0';
2022-07-05 01:00:55 -07:00
exportedVariable->value.opcode = 0;
2022-05-19 01:51:26 -07:00
}
}
}
2022-09-23 05:43:44 -07:00
} // namespace fallout