Skip to content

Instantly share code, notes, and snippets.

@syureri
Last active September 25, 2020 01:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save syureri/d3933f16107c1187dc09db1de63a1fc4 to your computer and use it in GitHub Desktop.
Save syureri/d3933f16107c1187dc09db1de63a1fc4 to your computer and use it in GitHub Desktop.
#pragma once
#include <limits>
#include <cstdint>
namespace RGSS3
{
using VALUE = unsigned long;
using ID = VALUE;
constexpr VALUE Qfalse = 0;
constexpr VALUE Qtrue = 2;
constexpr VALUE Qnil = 4;
constexpr VALUE Qundef = 6;
constexpr VALUE RUBY_CLASS_NONE = 0x00;
constexpr VALUE RUBY_CLASS_OBJECT = 0x01;
constexpr VALUE RUBY_CLASS_CLASS = 0x02;
constexpr VALUE RUBY_CLASS_MODULE = 0x03;
constexpr VALUE RUBY_CLASS_FLOAT = 0x04;
constexpr VALUE RUBY_CLASS_STRING = 0x05;
constexpr VALUE RUBY_CLASS_REGEXP = 0x06;
constexpr VALUE RUBY_CLASS_ARRAY = 0x07;
constexpr VALUE RUBY_CLASS_HASH = 0x08;
constexpr VALUE RUBY_CLASS_BIGNUM = 0x0a;
constexpr VALUE RUBY_CLASS_FILE = 0x0b;
constexpr VALUE RUBY_CLASS_DATA = 0x0c;
constexpr VALUE RUBY_CLASS_NIL = 0x11;
constexpr VALUE RUBY_CLASS_TRUE = 0x12;
constexpr VALUE RUBY_CLASS_FALSE = 0x13;
constexpr VALUE RUBY_CLASS_SYMBOL = 0x14;
constexpr VALUE RUBY_CLASS_FIXNUM = 0x15;
constexpr VALUE RUBY_CLASS_UNDEF = 0x1b;
constexpr VALUE RUBY_CLASS_NODE = 0x1c;
constexpr VALUE RUBY_CLASS_ICLASS = 0x1d;
constexpr VALUE RUBY_CLASS_ZOMBIE = 0x1e;
constexpr VALUE RUBY_CLASS_MASK = 0x1f;
constexpr VALUE FL_USHIFT = 12;
static constexpr bool RTEST(VALUE v)
{
return (v & ~Qnil) != 0;
}
static constexpr bool NIL_P(VALUE p)
{
return p == Qnil;
}
template<int n>
struct FL_USER
{
static constexpr VALUE value = static_cast<VALUE>(1) << (FL_USHIFT + n);
};
template<int n>
constexpr VALUE FL_USER_V = FL_USER<n>::value;
struct RBasic
{
VALUE flags;
VALUE klass;
};
static RBasic* RBASIC(VALUE obj)
{
return reinterpret_cast<RBasic*>(static_cast<intptr_t>(obj));
}
constexpr int RSTRING_EMBED_LEN_MAX = (sizeof(VALUE) * 3) / sizeof(char) - 1;
struct RString
{
RBasic basic;
union
{
struct
{
long len;
char* ptr;
union
{
long capa;
VALUE shared;
} aux;
} heap;
char ary[RSTRING_EMBED_LEN_MAX + 1];
} as;
};
static RString* RSTRING(VALUE obj)
{
return reinterpret_cast<RString*>(static_cast<intptr_t>(obj));
}
constexpr VALUE RSTRING_NOEMBED = FL_USER_V<1>;
constexpr VALUE RSTRING_EMBED_LEN_MASK = FL_USER_V<2> | FL_USER_V<3> | FL_USER_V<4>;
constexpr VALUE RSTRING_EMBED_LEN_SHIFT = FL_USHIFT + 2;
static char* RSTRING_PTR(VALUE str)
{
return (!(RBASIC(str)->flags & RSTRING_NOEMBED)) ? RSTRING(str)->as.ary : RSTRING(str)->as.heap.ptr;
}
static long RSTRING_LEN(VALUE str)
{
RBasic* basic = RBASIC(str);
if (basic->flags & RSTRING_NOEMBED)
{
return static_cast<long>((basic->flags >> RSTRING_EMBED_LEN_SHIFT) & (RSTRING_EMBED_LEN_MASK >> RSTRING_EMBED_LEN_SHIFT));
}
return RSTRING(str)->as.heap.len;
}
constexpr int RARRAY_EMBED_LEN_MAX = 3;
struct RArray
{
RBasic basic;
union
{
struct
{
long len;
union
{
long capa;
VALUE shared;
} aux;
VALUE* ptr;
} heap;
VALUE ary[RARRAY_EMBED_LEN_MAX];
} as;
};
static RArray* RARRAY(VALUE obj)
{
return reinterpret_cast<RArray*>(static_cast<intptr_t>(obj));
}
constexpr VALUE RARRAY_EMBED_FLAG = FL_USER_V<1>;
constexpr VALUE RARRAY_EMBED_LEN_MASK = FL_USER_V<3> | FL_USER_V<4>;
constexpr VALUE RARRAY_EMBED_LEN_SHIFT = FL_USHIFT + 3;
static bool RARRAY_EMBEDDED_P(VALUE ary)
{
return RBASIC(ary)->flags & RARRAY_EMBED_FLAG;
}
static VALUE* RARRAY_PTR(VALUE ary)
{
if (RARRAY_EMBEDDED_P(ary)) return RARRAY(ary)->as.ary;
return RARRAY(ary)->as.heap.ptr;
}
static long RARRAY_EMBEDDED_LEN(VALUE ary)
{
return static_cast<long>(RBASIC(ary)->flags >> RARRAY_EMBED_LEN_SHIFT) & (RARRAY_EMBED_LEN_MASK >> RARRAY_EMBED_LEN_SHIFT);
}
static long RARRAY_LEN(VALUE ary)
{
if (RARRAY_EMBEDDED_P(ary)) return RARRAY_EMBEDDED_LEN(ary);
return RARRAY(ary)->as.heap.len;
}
struct RData
{
RBasic basic;
void (*dmark)(void*);
void (*dfree)(void*);
void* data;
};
static RData* RDATA(VALUE obj)
{
return reinterpret_cast<RData*>(static_cast<intptr_t>(obj));
}
static void*& RDATA_PTR(VALUE obj)
{
return RDATA(obj)->data;
}
constexpr VALUE RUBY_FIXNUM_FLAG = 0x01;
static constexpr long FIX2LONG(VALUE x)
{
return static_cast<long>(static_cast<long>(x) >> 1);
}
static constexpr unsigned long FIX2ULONG(VALUE x)
{
return ((x >> 1) & LONG_MAX);
}
static constexpr int FIX2INT(VALUE x)
{
return static_cast<int>(FIX2LONG(x));
}
static constexpr unsigned int FIX2UINT(VALUE x)
{
return static_cast<unsigned int>(FIX2ULONG(x));
}
static constexpr VALUE INT2FIX(int x)
{
return static_cast<VALUE>(static_cast<long>(x) << 1 | RUBY_FIXNUM_FLAG);
}
constexpr VALUE RUBY_SYMBOL_FLAG = 0x0e;
static constexpr VALUE ID2SYM(ID id)
{
return (static_cast<VALUE>(id) << 8) | RUBY_SYMBOL_FLAG;
}
constexpr unsigned long FIXNUM_MAX = static_cast<unsigned long>(LONG_MAX >> 1);
constexpr long FIXNUM_MIN = static_cast<long>(LONG_MIN) >> static_cast<int>(1);
static constexpr bool FIXNUM_P(VALUE x)
{
return ((static_cast<long>(x)) & RUBY_FIXNUM_FLAG) != 0;
}
static constexpr bool POSFIXABLE(unsigned long x)
{
return x <= FIXNUM_MAX;
}
static constexpr bool NEGFIXABLE(long x)
{
return x >= FIXNUM_MIN;
}
static constexpr bool FIXABLE(long x)
{
return (NEGFIXABLE(x) && (x <= 0 || POSFIXABLE(x)));
}
constexpr int FLONUM_MASK = 0x00;
constexpr int FLONUM_FLAG = 0x02;
struct RFloat
{
RBasic basic;
double value;
};
static RFloat* RFLOAT(VALUE f)
{
return reinterpret_cast<RFloat*>(static_cast<intptr_t>(f));
}
static double rb_float_noflonum_value(VALUE v)
{
return RFLOAT(v)->value;
}
#define RFLOAT_VALUE rb_float_noflonum_value
constexpr VALUE RUBY_IMM_MASK = 0x03;
static bool IMM_P(VALUE x)
{
return (x & RUBY_IMM_MASK) != 0;
}
constexpr VALUE RUBY_SPECIAL_SHIFT = 8;
static bool SYMBOL_P(VALUE x)
{
return ((x & ~(~static_cast<VALUE>(0) << RUBY_SPECIAL_SHIFT)) == RUBY_SYMBOL_FLAG);
}
static VALUE BUILTIN_TYPE(VALUE x)
{
return RBASIC(x)->flags & RUBY_CLASS_MASK;
}
static inline bool ARRAY_P(VALUE x) {
return !IMM_P(x) && BUILTIN_TYPE(x) == RUBY_CLASS_ARRAY;
}
static inline bool DATA_P(VALUE x) {
return !IMM_P(x) && BUILTIN_TYPE(x) == RUBY_CLASS_DATA;
}
static VALUE rb_type(VALUE obj)
{
if (IMM_P(obj))
{
if (FIXNUM_P(obj))
return RUBY_CLASS_FIXNUM;
if (obj == Qtrue)
return RUBY_CLASS_TRUE;
if (SYMBOL_P(obj))
return RUBY_CLASS_SYMBOL;
if (obj == Qundef)
return RUBY_CLASS_UNDEF;
}
else if (!RTEST(obj))
{
if (obj == Qnil)
return RUBY_CLASS_NIL;
if (obj == Qfalse)
return RUBY_CLASS_FALSE;
}
return BUILTIN_TYPE(obj);
}
static inline bool FLOAT_P(VALUE x) {
return !IMM_P(x) && BUILTIN_TYPE(x) == RUBY_CLASS_FLOAT;
}
inline static bool SPECIAL_CONST_P(VALUE x) {
return IMM_P(x) || !RTEST(x);
}
inline static bool FL_ABLE(VALUE x) {
return !SPECIAL_CONST_P(x) && BUILTIN_TYPE(x) != RUBY_CLASS_NODE;
}
inline static void FL_SET(VALUE x, VALUE f) {
if (FL_ABLE(x)) RBASIC(x)->flags |= (f);
}
constexpr VALUE FL_TAINT = FL_USER<8>::value;
constexpr VALUE FL_UNTRUSTED = FL_USER<9>::value;
using pfn_rb_funcall2 = VALUE(*)(VALUE, ID, int, const VALUE*);
using pfn_rb_define_class = VALUE(*)(const char* className, VALUE parentClass);
using pfn_rb_intern = ID(*)(const char*);
using pfn_rb_define_module = VALUE(*)(const char* moduleName);
using pfn_rb_define_module_function = void(*)(VALUE, const char*, void*, int);
using pfn_rb_define_global_const = void(*)(const char*, VALUE);
using pfn_rb_eval_string_protect = VALUE(*)(const char* code, int* state);
using pfn_rb_eval_string = VALUE(*)(const char* code);
using pfn_rb_protect = VALUE(*)(void* pfn, VALUE arg, int* state);
using pfn_rb_scan_args = int(*)(int, const VALUE*, const char*, ...);
using pfn_rb_class_new_instance = VALUE(*)(int argc, VALUE* argv, VALUE klass);
using pfn_rb_define_method = void(*)(VALUE classmod, const char* name, void* ptr, int argc);
using pfn_rb_str_new = VALUE(*)(const char*, long);
using pfn_rb_ary_new = VALUE(*)(void);
using pfn_rb_iv_set = VALUE(*)(VALUE, const char*, VALUE);
using pfn_rb_include_module = void(*)(VALUE, VALUE);
using pfn_rb_define_global_function = void(*)(const char*, void*, int);
using pfn_rb_define_const = void(*)(VALUE, const char*, VALUE);
using pfn_rb_define_alloc_func = void(*)(VALUE, VALUE(*rb_alloc_func_t)(VALUE));
using pfn_rb_undef_alloc_func = void(*)(VALUE);
using pfn_rb_define_singleton_method = void(*)(VALUE, char*, void*, int);
using pfn_rb_define_private_method = void(*)(VALUE, char*, void*, int);
using pfn_rb_attr = void(*)(VALUE, ID, int, int, int);
using pfn_rb_newobj = VALUE(*)(void);
using pfn_rb_iv_get = VALUE(*)(VALUE, const char*);
using pfn_rb_ary_aref = VALUE(*)(void);
using pfn_rb_check_type = void(*)(VALUE, int);
using pfn_rb_raise = void(*)(VALUE, const char*, ...);
using pfn_rb_sprintf = VALUE(*)(const char*, ...);
using pfn_rb_obj_is_kind_of = bool(*)(VALUE, VALUE);
using pfn_rb_safe_level = unsigned long(*)(void);
using pfn_rb_num2dbl = double(*)(VALUE);
using pfn_rgss_load_rgssad_file = unsigned(*)(const char* filename, void** ptrData, int* ptrLength);
using pfn_RGSSSetupRTP = int(*)(const wchar_t* iniPath, wchar_t* errorMessageBuffer, int bufferLength);
using pfn_RGSSSetupFonts = void(*)(void);
using pfn_RGSSInitialize3 = void(*)(void* rgssDLL);
using pfn_RGSSEval = int(*)(const char* script);
using pfn_RGSSErrorMessage = const wchar_t* (*)(void);
using pfn_RGSSGetRTPPath = int(*)(int rtpNumber);
using pfn_RGSSGetPathWithRTP = const wchar_t* (*)(int rtpID);
using pfn_RGSSFinalize = void(*)(void);
constexpr int addr_rb_funcall2 = 0x30D20;
constexpr int addr_rb_define_class = 0x5E740;
constexpr int addr_rb_intern = 0x48400;
constexpr int addr_rb_define_module = 0x5E990;
constexpr int addr_rb_define_module_function = 0x5F1E0;
constexpr int addr_rb_define_global_const = 0x68320;
constexpr int addr_rb_eval_string_protect = 0x30440;
constexpr int addr_rb_eval_string = 0x30410;
constexpr int addr_rb_protect = 0x6a240;
constexpr int addr_rb_scan_args = 0x5F380;
constexpr int addr_rb_class_new_instance = 0x33E60;
constexpr int addr_rb_define_method = 0x5EF70;
constexpr int addr_rb_str_new = 0x364C0;
constexpr int addr_rb_ary_new = 0x88F70;
constexpr int addr_rb_iv_set = 0x683D0;
constexpr int addr_rb_include_module = 0x5EBC0;
constexpr int addr_rb_define_global_function = 0x5F270;
constexpr int addr_rb_define_const = 0x682A0;
constexpr int addr_rb_define_alloc_func = 0x32E20;
constexpr int addr_rb_undef_alloc_func = 0x316A0;
constexpr int addr_rb_define_singleton_method = 0x5F1E0;
constexpr int addr_rb_define_private_method = 0x5EFA0;
constexpr int addr_rb_attr = 0x319C0;
constexpr int addr_rb_newobj = 0x592C0;
constexpr int addr_rb_iv_get = 0x683B0;
constexpr int addr_rb_ary_aref = 0x89DF0;
constexpr int addr_rb_check_type = 0x27090;
constexpr int addr_rb_raise = 0x26440;
constexpr int addr_rb_sprintf = 0x7E970;
constexpr int addr_rb_obj_is_kind_of = 0x334F0;
constexpr int addr_rb_safe_level = 0x9F880;
constexpr int addr_rb_num2dbl = 0x34DD0;
constexpr int addr_rb_cNumeric = 0x2AC04C;
constexpr int addr_rb_cFloat = 0x2AC058;
constexpr int addr_rb_cString = 0x2AC070;
constexpr int addr_rb_cBasicObject = 0x2AC07C;
constexpr int addr_rb_cClass = 0x2AC084;
constexpr int addr_rb_cObject = 0x2AC098;
constexpr int addr_rb_mKernel = 0x2AC080;
constexpr int addr_rb_eIndexError = 0x2AC0C8;
constexpr int addr_rb_eArgError = 0x2AC108;
constexpr int addr_rb_eTypeError = 0x2AC120;
constexpr int addr_rgss_load_rgssad_file = 0xC710;
extern pfn_rb_funcall2 rb_funcall2;
extern pfn_rb_define_class rb_define_class;
extern pfn_rb_intern rb_intern;
extern pfn_rb_define_module rb_define_module;
extern pfn_rb_define_module_function rb_define_module_function;
extern pfn_rb_define_global_const rb_define_global_const;
extern pfn_rb_eval_string_protect rb_eval_string_protect;
extern pfn_rb_eval_string rb_eval_string;
extern pfn_rb_protect rb_protect;
extern pfn_rb_scan_args rb_scan_args;
extern pfn_rb_class_new_instance rb_class_new_instance;
extern pfn_rb_define_method rb_define_method;
extern pfn_rb_str_new rb_str_new;
extern pfn_rb_ary_new rb_ary_new;
extern pfn_rb_iv_set rb_iv_set;
extern pfn_rb_include_module rb_include_module;
extern pfn_rb_define_global_function rb_define_global_function;
extern pfn_rb_define_const rb_define_const;
extern pfn_rb_define_alloc_func rb_define_alloc_func;
extern pfn_rb_undef_alloc_func rb_undef_alloc_func;
extern pfn_rb_define_singleton_method rb_define_singleton_method;
extern pfn_rb_define_private_method rb_define_private_method;
extern pfn_rb_attr rb_attr;
extern pfn_rb_newobj rb_newobj;
extern pfn_rb_iv_get rb_iv_get;
extern pfn_rb_ary_aref rb_ary_aref;
extern pfn_rb_check_type rb_check_type;
extern pfn_rb_raise rb_raise;
extern pfn_rb_sprintf rb_sprintf;
extern pfn_rb_obj_is_kind_of rb_obj_is_kind_of;
extern pfn_rb_safe_level rb_safe_level;
extern pfn_rb_num2dbl rb_num2dbl;
extern VALUE rb_cNumeric;
extern VALUE rb_cFloat;
extern VALUE rb_cString;
extern VALUE rb_cBasicObject;
extern VALUE rb_mKernel;
extern VALUE rb_cClass;
extern VALUE rb_cObject;
extern VALUE rb_eIndexError;
extern VALUE rb_eArgError;
extern VALUE rb_eTypeError;
extern pfn_rgss_load_rgssad_file rgss_load_rgssad_file;
extern pfn_RGSSSetupRTP RGSSSetupRTP;
extern pfn_RGSSSetupFonts RGSSSetupFonts;
extern pfn_RGSSInitialize3 RGSSInitialize3;
extern pfn_RGSSEval RGSSEval;
extern pfn_RGSSErrorMessage RGSSErrorMessage;
extern pfn_RGSSGetRTPPath RGSSGetRTPPath;
extern pfn_RGSSGetPathWithRTP RGSSGetPathWithRTP;
extern pfn_RGSSFinalize RGSSFinalize;
extern void* rgssLib;
#define NEWOBJ(obj, type) type* obj = (type*)rb_newobj();
static void OBJSETUP(void* obj, VALUE c, VALUE t) {
RBASIC((VALUE)obj)->flags = (t);
RBASIC((VALUE)obj)->klass = (c);
if (rb_safe_level() >= 3) FL_SET((VALUE)(intptr_t)obj, FL_TAINT | FL_UNTRUSTED);
}
static VALUE rb_float_new(double d) {
NEWOBJ(flt, struct RFloat);
OBJSETUP(flt, rb_cFloat, RUBY_CLASS_FLOAT);
flt->value = d;
return (VALUE)flt;
}
#define DBL2NUM rb_float_new
inline static double NUM2DBL(VALUE x) {
return FLOAT_P(x) ? RFLOAT_VALUE(x) : rb_num2dbl(x);
}
#define Check_Type(v,t) rb_check_type(VALUE(v),t)
inline static VALUE rb_data_object_alloc(VALUE klass, void* datap, void (*dmark)(void*), void (*dfree)(void*)) {
NEWOBJ(data, struct RData);
if (klass) Check_Type(klass, RUBY_CLASS_CLASS);
OBJSETUP(data, klass, RUBY_CLASS_DATA);
data->data = datap;
data->dfree = dfree;
data->dmark = dmark;
return (VALUE)data;
}
void Load();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment