typedef signed char s8;
typedef signed short int s16;
typedef signed long s32;
typedef signed long long int s64;
typedef unsigned char u8;
typedef unsigned short int u16;
typedef unsigned long u32;
typedef unsigned long long int u64;
typedef int BOOL;
typedef unsigned long size_t;
typedef long ptrdiff_t;
#define FALSE 0
#define TRUE 1
#define NULL 0
#if !defined(__cplusplus) || __cplusplus < 201103L
#ifndef nullptr
#define nullptr NULL
#endif
#endif
#define ATTRIBUTE_ALIGN(num) __attribute__((aligned(num)))
#define EXTERN_OBJECT_NAME(name) extern const char *name##_name;
#define OBJECT_NAME(name) const char *name##_name = #name;
#define OBJECT_NAMES \
o(TObject) \
o(TMainTask)
#define TL_OBJECTS \
o(tl_su, TL_SU) \
TL_OBJECTS_AT_TL_00
#define TL_OBJECTS_AT_TL_00 \
TL_00_OBJECTS \
TL_02_OBJECTS \
o(tl_particle, TL_PARTICLE) \
TL_PARTICLE_MODEL_OBJECTS
#define TL_OBJECTS_AT_TL_00_WITHOUT_TL_PARTICLE \
TL_00_OBJECTS \
TL_02_OBJECTS \
TL_PARTICLE_MODEL_OBJECTS
#define TL_OBJECTS_AT_TL_02 \
TL_02_OBJECTS \
o(tl_particle, TL_PARTICLE) \
TL_PARTICLE_MODEL_OBJECTS
#define TL_00_OBJECTS \
o(tl_00, TL_00) \
o(tl_camera, TL_CAMERA) \
o(tl_01, TL_01)
#define TL_02_OBJECTS \
o(tl_02, TL_02) \
o(tl_item_equip, TL_ITEM_EQUIP) \
o(tl_03, TL_03) \
o(tl_loc_start, TL_LOC_START) \
o(tl_04, TL_04) \
o(tl_05, TL_05) \
o(tl_06, TL_06) \
o(tl_07, TL_07) \
o(tl_loc_end, TL_LOC_END) \
o(tl_window, TL_WINDOW)
#define TL_PARTICLE_MODEL_OBJECTS \
o(tl_particlemodel, TL_PARTICLEMODEL) \
o(tl_radermap, TL_RADERMAP) \
o(tl_clipout, TL_CLIPOUT) \
o(tl_fade, TL_FADE) \
o(tl_fadeafter, TL_FADEAFTER)
#define FOREACH_NODE(type, first, varname) for (type *varname = (type *)(first); varname != NULL; varname = (type *)(varname->next()))
#define FOREACH_NODE_NODECL(type, first, varname) for (varname = (type *)(first); varname != NULL; varname = (type *)(varname->next()))
#define FOREACH_NODE_MULTI_ITER(type, first, varname, ...) for (type *varname = (type *)(first); varname != NULL; varname = (type *)(varname->next()), __VA_ARGS__)
#define FOREACH_NODE_NODECL_MULTI_ITER(type, first, varname, ...) for (varname = (type *)(first); varname != NULL; varname = (type *)(varname->next()), __VA_ARGS__)
#define __packed__
#define PRIVATE_MEMBER_GETTER(type, name) \
type name() { \
return m_##name; \
}
#define PRIVATE_MEMBER_SETTER(type, name) \
void set_##name(type val) { \
m_##name = val; \
}
#define PRIVATE_MEMBER_GETTER_ARRAY(type, name, size) \
TArray<type, size> &name() { \
return m_##name; \
}
#define PRIVATE_MEMBER_GETTER_FUNC(ret_type, name, ...) \
ret_type (*name())(__VA_ARGS__) { \
return m_##name; \
}
#define PRIVATE_MEMBER_SETTER_FUNC(ret_type, name, ...) \
void set_##name(ret_type (*val)(__VA_ARGS__)) { \
m_##name = val; \
}
#define PRIVATE_MEMBER_ACCESSORS(type, name) \
PRIVATE_MEMBER_GETTER(type, name); \
PRIVATE_MEMBER_SETTER(type, name)
#define PRIVATE_MEMBER_ACCESSORS_ARRAY(type, name, size) \
PRIVATE_MEMBER_GETTER_ARRAY(type, name, size)
#define PRIVATE_MEMBER_ACCESSORS_FUNC(ret_type, name, ...) \
PRIVATE_MEMBER_GETTER_FUNC(ret_type, name, __VA_ARGS__); \
PRIVATE_MEMBER_SETTER_FUNC(ret_type, name, __VA_ARGS__)
#define X_OR_Y_CHILD(flags, old_flags, one_prefix, zero_prefix, suffix) \
if (flags != old_flags) { \
TMainTask *child; \
u32 bit = 1; \
FOREACH_NODE_NODECL_MULTI_ITER(TMainTask, main_task.down(), child, bit <<= 1) { \
if (flags & bit) { \
child->one_prefix##_##suffix(); \
} else { \
child->zero_prefix##_##suffix(); \
} \
} \
old_flags = flags; \
}
#define SET_OR_CLEAR_CHILD_FLAGS(flags, old_flags, flag_bit) \
X_OR_Y_CHILD(flags, old_flags, set_flag, clear_flag, flag_bit)
#define DISALLOW_OR_ALLOW_CHILD(flags, old_flags, flag_name) \
X_OR_Y_CHILD(flags, old_flags, allow, disallow, flag_name)
class THeap;
class TObject;
class TMainTask;
class TPlyGuildCardTag;
struct packet_header;
template<typename T, size_t n>
class TArray {
public:
T m_data[n];
public:
T *data() {
return m_data;
};
size_t size() {
return n;
};
size_t byte_size() {
return n * sizeof(T);
};
T &operator[](size_t i) {
return m_data[i];
};
T *start() {
return m_data;
};
T *end() {
return &m_data[size()-1];
};
template<typename T2>
T2 *as() {
return reinterpret_cast<T2 *>(m_data);
};
template<typename T2>
TArray<T2, (n * sizeof(T))/sizeof(T2)> &to() {
typedef TArray<T2, sizeof(m_data)/sizeof(T2)> to_type;
return reinterpret_cast<to_type &>(*this);
};
u8 *as_bytes() {
return reinterpret_cast<u8 *>(m_data);
};
void fill(u8 val) {
memset(m_data, val, byte_size());
};
void fill_with(u8 val) {
_fill_with<false>(val);
};
void fast_fill_with(u8 val) {
_fill_with<true>(val);
};
template<typename T2>
void copy(const T2 &val) {
_copy<T2, false>(val);
};
template<typename T2>
void copy_reverse(const T2 &val) {
_copy_reverse<T2, false>(val);
};
template<typename T2>
void fast_copy(const T2 &val) {
_copy<T2, true>(val);
};
template<typename T2>
void fast_copy_reverse(const T2 &val) {
_copy_reverse<T2, true>(val);
};
private:
template<bool do_unroll_check>
void _fill_with(u8 val) {
u8 *bytes = as_bytes();
size_t size = byte_size();
if (do_unroll_check && size <= 8) {
int i = 0;
switch (size) {
case 8: bytes[i++] = val;
case 7: bytes[i++] = val;
case 6: bytes[i++] = val;
case 5: bytes[i++] = val;
case 4: bytes[i++] = val;
case 3: bytes[i++] = val;
case 2: bytes[i++] = val;
case 1: bytes[i++] = val;
default: break;
}
} else {
for (int i = 0; i < size; ++i) {
bytes[i] = val;
}
}
};
template<typename T2, bool do_unroll_check>
void _copy(const T2 &val) {
size_t size = sizeof(T2)/sizeof(T);
const T *src = reinterpret_cast<const T *>(&val);
if (do_unroll_check && size <= 8) {
int i = 0;
switch (size) {
case 8: m_data[i] = src[i++];
case 7: m_data[i] = src[i++];
case 6: m_data[i] = src[i++];
case 5: m_data[i] = src[i++];
case 4: m_data[i] = src[i++];
case 3: m_data[i] = src[i++];
case 2: m_data[i] = src[i++];
case 1: m_data[i] = src[i++];
default: break;
}
} else {
for (int i = 0; i < size; ++i) {
m_data[i] = src[i];
}
}
};
template<typename T2, bool do_unroll_check>
void _copy_reverse(const T2 &val) {
size_t size = sizeof(T2)/sizeof(T);
const T *src = reinterpret_cast<const T *>(&val);
if (do_unroll_check && size <= 8) {
int i = size-1;
int j = 0;
switch (size) {
case 8: m_data[i--] = src[j++];
case 7: m_data[i--] = src[j++];
case 6: m_data[i--] = src[j++];
case 5: m_data[i--] = src[j++];
case 4: m_data[i--] = src[j++];
case 3: m_data[i--] = src[j++];
case 2: m_data[i--] = src[j++];
case 1: m_data[i--] = src[j++];
default: break;
}
} else {
for (int i = size-1, j = 0; i; --i, ++j) {
m_data[i] = src[j];
}
}
};
};
template <typename T>
class TMenuListEntry : public TPlyGuildCardTag {
public:
T entry;
void bswap();
TMenuListEntry &operator=(const TMenuListEntry &src);
} __packed__;
template <typename T, int num_entries, int num_pad_entries>
class TMenuList {
public:
packet_header header;
TMenuListEntry<T> pad_entries[num_pad_entries];
TMenuListEntry<T> entries[num_entries];
void bswap();
TMenuList &operator=(const TMenuList &src);
} __packed__;
template <typename T, int num_entries>
class TMenuList<T, num_entries, 0> {
public:
packet_header header;
TMenuListEntry<T> entries[num_entries];
void bswap();
TMenuList &operator=(const TMenuList &src);
} __packed__;
template <typename T, int num_pad_entries>
class TMenuList<T, 0, num_pad_entries> {
public:
packet_header header;
TMenuListEntry<T> pad_entries[num_pad_entries];
void bswap();
TMenuList &operator=(const TMenuList &src);
} __packed__;
template <typename T, int num_entries>
void TMenuList<T, num_entries, 0>::bswap() {
header.bswap();
for (int i = 0; i < num_entries; i++) {
entries[i].bswap();
}
}
template <typename T, int num_pad_entries>
void TMenuList<T, 0, num_pad_entries>::bswap() {
header.bswap();
for (int i = 0; i < num_pad_entries; i++) {
pad_entries[i].bswap();
}
}
template <typename T, int num_entries, int num_pad_entries>
void TMenuList<T, num_entries, num_pad_entries>::bswap() {
header.bswap();
if (num_pad_entries) {
for (int i = 0; i < num_pad_entries; i++) {
pad_entries[i].bswap();
}
}
if (num_entries) {
for (int i = 0; i < num_entries; i++) {
entries[i].bswap();
}
}
}
template <typename T>
void TMenuListEntry<T>::bswap() {
TPlyGuildCardTag::bswap();
entry.bswap();
}
template <typename T, int num_entries>
TMenuList<T, num_entries, 0> &TMenuList<T, num_entries, 0>::operator=(const TMenuList<T, num_entries, 0> &src) {
header = src.header;
for (int i = 0; i < num_entries; i++) {
entries[i] = src.entries[i];
}
return *this;
}
template <typename T, int num_pad_entries>
TMenuList<T, 0, num_pad_entries> &TMenuList<T, 0, num_pad_entries>::operator=(const TMenuList<T, 0, num_pad_entries> &src) {
header = src.header;
for (int i = 0; i < num_pad_entries; i++) {
pad_entries[i] = src.pad_entries[i];
}
return *this;
}
template <typename T, int num_entries, int num_pad_entries>
TMenuList<T, num_entries, num_pad_entries> &TMenuList<T, num_entries, num_pad_entries>::operator=(const TMenuList<T, num_entries, num_pad_entries> &src) {
header = src.header;
if (num_pad_entries) {
for (int i = 0; i < num_pad_entries; i++) {
pad_entries[i] = src.pad_entries[i];
}
}
if (num_entries) {
for (int i = 0; i < num_entries; i++) {
entries[i] = src.entries[i];
}
}
return *this;
}
template <typename T>
TMenuListEntry<T> &TMenuListEntry<T>::operator=(const TMenuListEntry<T> &src) {
TPlyGuildCardTag::operator=(src);
entry = src.entry;
return *this;
}
static const int tl_object_count = 20;
#define o(name) extern const char *name##_name;
OBJECT_NAMES
#undef o
#define o(var, name) extern const char *var##_name;
TL_OBJECTS
#undef o
#define o(var, name) extern TObject *var;
TL_OBJECTS
#undef o
extern THeap *obj_heap;
extern THeap *alt_heap;
extern TMainTask main_task;
extern TObject global_obj1;
extern TObject global_obj2;
u32 some_main_task_flag = 1;
u32 update_flags;
u32 old_update_flags;
u32 render_flags;
u32 old_render_flags;
u32 render_shadow_flags;
u32 old_render_shadow_flags;
u32 some_id_805c6f74;
extern void heap_xfree(void *ptr);
extern void *heap_xmalloc(size_t size);
extern void camera_stuff();
extern void set_depth_buffer_settings_1();
extern void set_depth_buffer_settings_2();
extern void set_depth_buffer_settings_3();
extern void set_depth_buffer_settings_id(u32 id);
extern void save_depth_buffer_settings();
extern void restore_depth_buffer_settings();
extern void func_80083a00();
extern void func_80141618();
extern void set_some_id(u32 id);
extern void func_803e11e8(u32 arg1);
extern void func_803e11f0();
extern void func_803369b4();
extern void bswap_16(u16 *val);
extern void bswap_32(u32 *val);
struct packet_header {
u8 command;
u8 flags;
u16 size;
void bswap();
} __packed__;
union ipv4_addr {
u32 addr;
TArray<u8, 4> addr_bytes;
};
enum object_flags {
NONE = 0,
QUEUE_DESTRUCTION = 1,
CHILD_QUEUE_DESTRUCTION = 2,
BIT_2 = 4,
BIT_3 = 8,
DISALLOW_UPDATE = 0x0F,
DISALLOW_RENDER = 0x10,
DISALLOW_DESTRUCTION = 0x20,
DISALLOW_RENDER_SHADOWS = 0x100,
BIT_9 = 0x200,
BIT_10 = 0x400,
BIT_11 = 0x800,
BIT_12 = 0x1000,
BIT_13 = 0x2000,
BIT_14 = 0x4000,
BIT_15 = 0x8000,
ALL_BITS = 0xFFFF
};
static inline object_flags operator^(object_flags a, object_flags b) { return static_cast<object_flags>(static_cast<u16>(a) ^ static_cast<u16>(b)); };
static inline object_flags operator&(object_flags a, object_flags b) { return static_cast<object_flags>(static_cast<u16>(a) & static_cast<u16>(b)); };
static inline object_flags operator|(object_flags a, object_flags b) { return static_cast<object_flags>(static_cast<u16>(a) | static_cast<u16>(b)); };
static inline object_flags operator~(object_flags a) { return static_cast<object_flags>(~static_cast<u16>(a)); }
static inline void operator^=(object_flags &a, object_flags b) { a = a ^ b; };
static inline void operator&=(object_flags &a, object_flags b) { a = a & b; };
static inline void operator|=(object_flags &a, object_flags b) { a = a | b; };
class TPlyGuildCardTag {
public:
u8 tag0;
u8 tag1;
u16 tag2;
u32 guildcard_number;
TPlyGuildCardTag &operator=(const TPlyGuildCardTag &src);
void bswap();
} __packed__;
class PSOV3EncryptionTCP : public PSOV3Encryption {
public:
PSOV3EncryptionTCP();
~PSOV3EncryptionTCP();
void reset(u32 seed);
void encrypt(void *void_data, int size);
PRIVATE_MEMBER_ACCESSORS(u32, seed);
private:
u32 m_seed;
};
class TSocket : public TObject {
private:
void set_flags(u8 flags) {
m_sock_flags |= flags;
};
void clear_flags(u8 flags) {
m_sock_flags &= ~flags;
};
void toggle_flags(u8 flags) {
m_sock_flags ^= flags;
};
u8 get_flags(u8 flags) {
return m_sock_flags & flags;
};
ipv4_addr m_dst_addr;
u16 m_dst_port;
u16 m_src_port;
ipv4_addr m_src_addr;
s16 m_sock_fd;
u8 m_sock_flags;
bool m_buffer_cleared;
s16 m_size;
s16 m_buffer_offset;
u32 m_unused;
TArray<u8, 64> m_unused2;
TArray<u8, 2048> m_packet_buffer;
s16 m_stat;
u16 m_unused3;
u32 m_send_window;
u32 m_recv_window;
void (*m_callback)(TSocket *socket);
public:
TSocket(TObject *parent);
virtual ~TSocket();
virtual int open() = 0;
virtual int close() = 0;
virtual void recv() = 0;
virtual int send(u8 *data) = 0;
virtual int send(u8 *data, size_t size) = 0;
int resolve_domain(char *domain);
void set_ip_address(u32 addr);
void set_port(u32 port);
const u8 next();
int is_empty();
PRIVATE_MEMBER_ACCESSORS(ipv4_addr, dst_addr);
PRIVATE_MEMBER_ACCESSORS(u16, dst_port);
PRIVATE_MEMBER_ACCESSORS(u16, src_port);
PRIVATE_MEMBER_ACCESSORS(ipv4_addr, src_addr);
PRIVATE_MEMBER_ACCESSORS(s16, sock_fd);
PRIVATE_MEMBER_ACCESSORS(u8, sock_flags);
PRIVATE_MEMBER_ACCESSORS(bool, buffer_cleared);
PRIVATE_MEMBER_ACCESSORS(s16, size);
PRIVATE_MEMBER_ACCESSORS(s16, buffer_offset);
PRIVATE_MEMBER_ACCESSORS(u32, unused);
PRIVATE_MEMBER_ACCESSORS_ARRAY(u8, unused2, 64);
PRIVATE_MEMBER_ACCESSORS_ARRAY(u8, packet_buffer, 2048);
PRIVATE_MEMBER_ACCESSORS(s16, stat);
PRIVATE_MEMBER_ACCESSORS(u16, unused3);
PRIVATE_MEMBER_ACCESSORS(u32, send_window);
PRIVATE_MEMBER_ACCESSORS(u32, recv_window);
PRIVATE_MEMBER_ACCESSORS_FUNC(void, callback, TSocket *socket);
};
class THeap {
public:
struct heap_node {
heap_node *next;
size_t remaining_size;
};
heap_node *heap_nodes;
size_t mbr_0x04;
size_t align;
size_t mbr_0x0C;
size_t mbr_0x10;
public:
THeap(size_t size, int align);
~THeap();
void *operator new(size_t size) { return heap_xmalloc(size); };
void operator delete(void *ptr) { heap_xfree(ptr); };
void *heap_alloc(size_t size);
void *heap_zalloc(size_t size);
void heap_free(void *ptr);
};
class TObject {
private:
void _delete_children() {
while (m_down != NULL) {
delete m_down;
}
};
void add_parent(TObject *parent, bool set_parent) {
if (set_parent) {
m_up = parent;
}
TObject *child;
if (parent == NULL) {
m_prev = this;
m_next = NULL;
return;
}
child = parent->m_down;
if (child != NULL) {
m_prev = child->m_next;
m_next = NULL;
child->m_prev->m_next = this;
child->m_prev = this;
} else {
m_prev = this;
parent->m_down = this;
m_next = NULL;
}
};
void remove_parent() {
if (m_up != NULL) {
if (m_prev == this) {
m_up->m_down = NULL;
} else if (m_up->m_down == this) {
m_up->m_down = m_next;
m_prev->m_next = NULL;
if (m_next != NULL) {
m_next->m_prev = m_prev;
}
} else {
m_prev->m_next = m_next;
if (m_next != NULL) {
m_next->m_prev = m_prev;
} else {
m_up->m_down->m_prev = m_prev;
}
}
}
};
void set_flags(object_flags flags) {
m_flags |= flags;
}
void clear_flags(object_flags flags) {
m_flags_u16 &= ~static_cast<u16>(flags);
}
void toggle_flags(object_flags flags) {
m_flags ^= flags;
}
u32 get_flags(object_flags flags) {
return m_flags & flags;
};
const char *m_name;
union {
object_flags m_flags;
u16 m_flags_u16;
};
u16 m_id;
TObject *m_prev;
TObject *m_next;
TObject *m_up;
TObject *m_down;
public:
void disallow_rendering_shadows();
void allow_rendering_shadows();
void disallow_rendering();
void allow_rendering();
void toggle_flag_3();
void set_flag_3();
void clear_flag_3();
void queue_destruction();
void set_flag_9();
u32 get_flag_9();
void clear_flag_9();
TObject(TObject *parent = NULL);
virtual ~TObject();
void *operator new (size_t size) { return alloc(size); };
void operator delete(void *ptr) { free(ptr); };
const char *name() { return m_name; };
object_flags flags() { return m_flags; };
u16 flags_u16() { return m_flags_u16; };
u16 id() { return m_id; };
TObject *prev() { return m_prev; };
TObject *next() { return m_next; };
TObject *up() { return m_up; };
TObject *down() { return m_down; };
void set_name(const char *name) { m_name = name; };
void set_obj_flags(object_flags flags) { m_flags = flags; };
void set_flags_u16(u16 flags) { m_flags_u16 = flags; };
void set_id(u16 id) { m_id = id; };
void set_prev(TObject *node) { m_prev = node; };
void set_next(TObject *node) { m_next = node; };
void set_up(TObject *node) { m_up = node; };
void set_down(TObject *node) { m_down = node; };
void delete_children();
void queue_destruction_for_each_node();
void run_tasks();
void render_nodes();
void render_shadows_for_each_node();
void render_nodes2();
void empty_func();
void set_parent(TObject *parent);
virtual void run_task();
virtual void render();
virtual void render_shadows();
void empty_func2();
void log(const char *str);
int get_node_count();
bool all_parents_unqueued_for_destruction();
static void *alloc(size_t size);
static void free(void *ptr);
bool toggle_flag_9_if_flag_10_is_clear();
};
class TMainTask : public TObject {
public:
u32 task_flags;
u32 mbr_0x20;
u32 mbr_0x24;
public:
TMainTask();
void render_screen_overlay();
void some_empty_func();
void tl_toggle_flag_3();
void tl_clear_flag_3();
void tl_delete_children();
void tl_02_toggle_flag_3();
void tl_02_clear_flag_3();
void empty_render_screen_overlay_func();
void run_tl_camera_tasks();
void unused_render_func();
void render_objects();
void render_ui();
void render_particle_effects();
void render_effects();
void render_geometry();
void func_80228bbc();
void func_80228c44(s32 arg0);
void func_80228dbc();
void render_clipout_and_fade();
void init_main_task();
virtual ~TMainTask();
virtual void run_task();
virtual void render();
virtual void render_shadows();
private:
void set_task_flags(u32 flags) {
this->task_flags |= flags;
}
void clear_task_flags(u32 flags) {
this->task_flags &= ~flags;
}
u32 get_task_flags(u32 flags) {
return this->task_flags & flags;
};
};
class PSOEncryption {
public:
PSOEncryption();
virtual void update_stream() = 0;
virtual ~PSOEncryption();
virtual void init(u32 seed) = 0;
virtual u32 next() = 0;
};
class PSOV3Encryption : public PSOEncryption {
public:
PSOV3Encryption();
virtual void update_stream() override;
virtual ~PSOV3Encryption();
virtual void init(u32 seed) override;
virtual u32 next() override;
PRIVATE_MEMBER_ACCESSORS_ARRAY(u32, buffer, 522);
PRIVATE_MEMBER_ACCESSORS(u32 *, buffer_start);
PRIVATE_MEMBER_ACCESSORS(u32 *, buffer_end);
private:
TArray<u32, 522> m_buffer;
u32 *m_buffer_start;
u32 *m_buffer_end;
};