fallout2-ce/src/nevs.cc

227 lines
4.6 KiB
C++
Raw Normal View History

2022-05-19 01:51:26 -07:00
#include "nevs.h"
2022-09-15 02:38:23 -07:00
#include <stdlib.h>
#include <string.h>
2022-05-19 01:51:26 -07:00
#include "debug.h"
2022-07-06 04:59:54 -07:00
#include "interpreter_lib.h"
2022-05-19 01:51:26 -07:00
#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-07-06 04:59:54 -07:00
#define NEVS_COUNT 40
typedef struct Nevs {
bool used;
char name[32];
Program* program;
int proc;
int type;
int hits;
bool busy;
void (*field_38)();
} Nevs;
static Nevs* _nevs_alloc();
static void _nevs_reset(Nevs* nevs);
static void _nevs_removeprogramreferences(Program* program);
static Nevs* _nevs_find(const char* name);
2022-05-19 01:51:26 -07:00
// 0x6391C8
2022-07-06 04:59:54 -07:00
static Nevs* gNevs;
2022-05-19 01:51:26 -07:00
// 0x6391CC
2022-07-06 04:59:54 -07:00
static int gNevsHits;
2022-05-19 01:51:26 -07:00
// nevs_alloc
// 0x488340
2022-07-06 04:59:54 -07:00
static Nevs* _nevs_alloc()
2022-05-19 01:51:26 -07:00
{
2022-07-06 04:59:54 -07:00
if (gNevs == NULL) {
2022-05-19 01:51:26 -07:00
debugPrint("nevs_alloc(): nevs_initonce() not called!");
exit(99);
}
2022-07-06 04:59:54 -07:00
for (int index = 0; index < NEVS_COUNT; index++) {
Nevs* nevs = &(gNevs[index]);
if (!nevs->used) {
// NOTE: Uninline.
_nevs_reset(nevs);
2022-05-19 01:51:26 -07:00
return nevs;
}
}
return NULL;
}
2022-07-06 04:59:54 -07:00
// NOTE: Inlined.
//
// 0x488394
static void _nevs_reset(Nevs* nevs)
{
nevs->used = false;
memset(nevs, 0, sizeof(*nevs));
}
2022-05-19 01:51:26 -07:00
// 0x4883AC
void _nevs_close()
{
2022-07-06 04:59:54 -07:00
if (gNevs != NULL) {
internal_free_safe(gNevs, __FILE__, __LINE__); // "..\\int\\NEVS.C", 97
gNevs = NULL;
2022-05-19 01:51:26 -07:00
}
}
// 0x4883D4
2022-07-06 04:59:54 -07:00
static void _nevs_removeprogramreferences(Program* program)
2022-05-19 01:51:26 -07:00
{
2022-07-06 04:59:54 -07:00
if (gNevs != NULL) {
2022-05-19 01:51:26 -07:00
for (int i = 0; i < NEVS_COUNT; i++) {
2022-07-06 04:59:54 -07:00
Nevs* nevs = &(gNevs[i]);
if (nevs->used && nevs->program == program) {
// NOTE: Uninline.
_nevs_reset(nevs);
2022-05-19 01:51:26 -07:00
}
}
}
}
// nevs_initonce
// 0x488418
void _nevs_initonce()
{
intLibRegisterProgramDeleteCallback(_nevs_removeprogramreferences);
2022-05-19 01:51:26 -07:00
2022-07-06 04:59:54 -07:00
if (gNevs == NULL) {
gNevs = (Nevs*)internal_calloc_safe(sizeof(Nevs), NEVS_COUNT, __FILE__, __LINE__); // "..\\int\\NEVS.C", 131
if (gNevs == NULL) {
2022-05-19 01:51:26 -07:00
debugPrint("nevs_initonce(): out of memory");
exit(99);
}
}
}
// nevs_find
// 0x48846C
2022-07-06 04:59:54 -07:00
static Nevs* _nevs_find(const char* name)
2022-05-19 01:51:26 -07:00
{
2022-07-06 04:59:54 -07:00
if (gNevs == NULL) {
2022-05-19 01:51:26 -07:00
debugPrint("nevs_find(): nevs_initonce() not called!");
exit(99);
}
for (int index = 0; index < NEVS_COUNT; index++) {
2022-07-06 04:59:54 -07:00
Nevs* nevs = &(gNevs[index]);
if (nevs->used && compat_stricmp(nevs->name, name) == 0) {
2022-05-19 01:51:26 -07:00
return nevs;
}
}
return NULL;
}
// 0x4884C8
2022-07-06 04:59:54 -07:00
int _nevs_addevent(const char* name, Program* program, int proc, int type)
2022-05-19 01:51:26 -07:00
{
2022-07-06 04:59:54 -07:00
Nevs* nevs = _nevs_find(name);
2022-05-19 01:51:26 -07:00
if (nevs == NULL) {
nevs = _nevs_alloc();
}
if (nevs == NULL) {
return 1;
}
2022-07-06 04:59:54 -07:00
nevs->used = true;
strcpy(nevs->name, name);
2022-05-19 01:51:26 -07:00
nevs->program = program;
nevs->proc = proc;
2022-07-06 04:59:54 -07:00
nevs->type = type;
2022-05-19 01:51:26 -07:00
nevs->field_38 = NULL;
return 0;
}
// nevs_clearevent
// 0x48859C
int _nevs_clearevent(const char* a1)
{
debugPrint("nevs_clearevent( '%s');\n", a1);
Nevs* nevs = _nevs_find(a1);
2022-07-06 04:59:54 -07:00
if (nevs != NULL) {
// NOTE: Uninline.
_nevs_reset(nevs);
2022-05-19 01:51:26 -07:00
return 0;
}
return 1;
}
// nevs_signal
// 0x48862C
2022-07-06 04:59:54 -07:00
int _nevs_signal(const char* name)
2022-05-19 01:51:26 -07:00
{
2022-07-06 04:59:54 -07:00
debugPrint("nevs_signal( '%s');\n", name);
2022-05-19 01:51:26 -07:00
2022-07-06 04:59:54 -07:00
Nevs* nevs = _nevs_find(name);
2022-05-19 01:51:26 -07:00
if (nevs == NULL) {
return 1;
}
2022-07-06 04:59:54 -07:00
debugPrint("nep: %p, used = %u, prog = %p, proc = %d", nevs, nevs->used, nevs->program, nevs->proc);
2022-05-19 01:51:26 -07:00
2022-07-06 04:59:54 -07:00
if (nevs->used
&& ((nevs->program != NULL && nevs->proc != 0) || nevs->field_38 != NULL)
&& !nevs->busy) {
nevs->hits++;
gNevsHits++;
2022-05-19 01:51:26 -07:00
return 0;
}
return 1;
}
// nevs_update
// 0x4886AC
void _nevs_update()
{
2022-07-06 04:59:54 -07:00
if (gNevsHits == 0) {
2022-05-19 01:51:26 -07:00
return;
}
2022-07-06 04:59:54 -07:00
debugPrint("nevs_update(): we have anyhits = %u\n", gNevsHits);
2022-05-19 01:51:26 -07:00
2022-07-06 04:59:54 -07:00
gNevsHits = 0;
2022-05-19 01:51:26 -07:00
for (int index = 0; index < NEVS_COUNT; index++) {
2022-07-06 04:59:54 -07:00
Nevs* nevs = &(gNevs[index]);
if (nevs->used
&& ((nevs->program != NULL && nevs->proc != 0) || nevs->field_38 != NULL)
&& !nevs->busy) {
if (nevs->hits > 0) {
nevs->busy = true;
2022-05-19 01:51:26 -07:00
2022-07-06 04:59:54 -07:00
nevs->hits -= 1;
gNevsHits += nevs->hits;
2022-05-19 01:51:26 -07:00
if (nevs->field_38 == NULL) {
_executeProc(nevs->program, nevs->proc);
} else {
nevs->field_38();
}
2022-07-06 04:59:54 -07:00
nevs->busy = false;
2022-05-19 01:51:26 -07:00
2022-07-06 04:59:54 -07:00
if (nevs->type == NEVS_TYPE_EVENT) {
// NOTE: Uninline.
_nevs_reset(nevs);
2022-05-19 01:51:26 -07:00
}
}
}
}
}
2022-09-23 05:43:44 -07:00
} // namespace fallout