Add proto data opcodes
This commit is contained in:
parent
9b02f600de
commit
ef34fdb519
12
src/proto.cc
12
src/proto.cc
|
@ -249,6 +249,12 @@ int _proto_list_str(int pid, char* proto_path)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 0x49E984
|
||||||
|
size_t proto_size(int type)
|
||||||
|
{
|
||||||
|
return type >= 0 && type < OBJ_TYPE_COUNT ? _proto_sizes[type] : 0;
|
||||||
|
}
|
||||||
|
|
||||||
// 0x49E99C
|
// 0x49E99C
|
||||||
bool _proto_action_can_use(int pid)
|
bool _proto_action_can_use(int pid)
|
||||||
{
|
{
|
||||||
|
@ -1704,12 +1710,10 @@ static int _proto_load_pid(int pid, Proto** protoPtr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocate memory for proto of given type and adds it to proto cache
|
// 0x4A1D98
|
||||||
static int _proto_find_free_subnode(int type, Proto** protoPtr)
|
static int _proto_find_free_subnode(int type, Proto** protoPtr)
|
||||||
{
|
{
|
||||||
size_t size = (type >= 0 && type < 11) ? _proto_sizes[type] : 0;
|
Proto* proto = (Proto*)internal_malloc(proto_size(type));
|
||||||
|
|
||||||
Proto* proto = (Proto*)internal_malloc(size);
|
|
||||||
*protoPtr = proto;
|
*protoPtr = proto;
|
||||||
if (proto == NULL) {
|
if (proto == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -104,6 +104,7 @@ extern char* _proto_none_str;
|
||||||
|
|
||||||
void _proto_make_path(char* path, int pid);
|
void _proto_make_path(char* path, int pid);
|
||||||
int _proto_list_str(int pid, char* proto_path);
|
int _proto_list_str(int pid, char* proto_path);
|
||||||
|
size_t proto_size(int type);
|
||||||
bool _proto_action_can_use(int pid);
|
bool _proto_action_can_use(int pid);
|
||||||
bool _proto_action_can_use_on(int pid);
|
bool _proto_action_can_use_on(int pid);
|
||||||
bool _proto_action_can_talk_to(int pid);
|
bool _proto_action_can_talk_to(int pid);
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
#include "mouse.h"
|
#include "mouse.h"
|
||||||
#include "object.h"
|
#include "object.h"
|
||||||
|
#include "proto.h"
|
||||||
#include "sfall_global_vars.h"
|
#include "sfall_global_vars.h"
|
||||||
#include "sfall_lists.h"
|
#include "sfall_lists.h"
|
||||||
#include "stat.h"
|
#include "stat.h"
|
||||||
|
@ -143,6 +144,56 @@ static void op_set_car_current_town(Program* program)
|
||||||
wmCarSetCurrentArea(area);
|
wmCarSetCurrentArea(area);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get_proto_data
|
||||||
|
static void op_get_proto_data(Program* program)
|
||||||
|
{
|
||||||
|
size_t offset = static_cast<size_t>(programStackPopInteger(program));
|
||||||
|
int pid = programStackPopInteger(program);
|
||||||
|
|
||||||
|
Proto* proto;
|
||||||
|
if (protoGetProto(pid, &proto) != 0) {
|
||||||
|
debugPrint("op_get_proto_data: bad proto %d", pid);
|
||||||
|
programStackPushInteger(program, -1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CE: Make sure the requested offset is within memory bounds and is
|
||||||
|
// properly aligned.
|
||||||
|
if (offset + sizeof(int) > proto_size(PID_TYPE(pid)) || offset % sizeof(int) != 0) {
|
||||||
|
debugPrint("op_get_proto_data: bad offset %d", offset);
|
||||||
|
programStackPushInteger(program, -1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int value = *reinterpret_cast<int*>(reinterpret_cast<unsigned char*>(proto) + offset);
|
||||||
|
programStackPushInteger(program, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set_proto_data
|
||||||
|
static void op_set_proto_data(Program* program)
|
||||||
|
{
|
||||||
|
int value = programStackPopInteger(program);
|
||||||
|
size_t offset = static_cast<size_t>(programStackPopInteger(program));
|
||||||
|
int pid = programStackPopInteger(program);
|
||||||
|
|
||||||
|
Proto* proto;
|
||||||
|
if (protoGetProto(pid, &proto) != 0) {
|
||||||
|
debugPrint("op_set_proto_data: bad proto %d", pid);
|
||||||
|
programStackPushInteger(program, -1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CE: Make sure the requested offset is within memory bounds and is
|
||||||
|
// properly aligned.
|
||||||
|
if (offset + sizeof(int) > proto_size(PID_TYPE(pid)) || offset % sizeof(int) != 0) {
|
||||||
|
debugPrint("op_set_proto_data: bad offset %d", offset);
|
||||||
|
programStackPushInteger(program, -1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
*reinterpret_cast<int*>(reinterpret_cast<unsigned char*>(proto) + offset) = value;
|
||||||
|
}
|
||||||
|
|
||||||
// list_begin
|
// list_begin
|
||||||
static void opListBegin(Program* program)
|
static void opListBegin(Program* program)
|
||||||
{
|
{
|
||||||
|
@ -362,6 +413,8 @@ void sfallOpcodesInit()
|
||||||
interpreterRegisterOpcode(0x819E, opGetGlobalInt);
|
interpreterRegisterOpcode(0x819E, opGetGlobalInt);
|
||||||
interpreterRegisterOpcode(0x81AF, opGetGameMode);
|
interpreterRegisterOpcode(0x81AF, opGetGameMode);
|
||||||
interpreterRegisterOpcode(0x81B6, op_set_car_current_town);
|
interpreterRegisterOpcode(0x81B6, op_set_car_current_town);
|
||||||
|
interpreterRegisterOpcode(0x8204, op_get_proto_data);
|
||||||
|
interpreterRegisterOpcode(0x8205, op_set_proto_data);
|
||||||
interpreterRegisterOpcode(0x820D, opListBegin);
|
interpreterRegisterOpcode(0x820D, opListBegin);
|
||||||
interpreterRegisterOpcode(0x820E, opListNext);
|
interpreterRegisterOpcode(0x820E, opListNext);
|
||||||
interpreterRegisterOpcode(0x820F, opListEnd);
|
interpreterRegisterOpcode(0x820F, opListEnd);
|
||||||
|
|
Loading…
Reference in New Issue