Ported from ModShot-core Ruby 3 changes, custom window title

This commit is contained in:
ZakatTeamI2P 2026-04-03 00:23:19 +04:00
parent 9b448a08ec
commit dc0c4ab781
4 changed files with 244 additions and 116 deletions

View file

@ -32,10 +32,7 @@
int volume = 100; \ int volume = 100; \
int pitch = 100; \ int pitch = 100; \
double pos = 0.0; \ double pos = 0.0; \
if (rgssVer >= 3) \ rb_get_args(argc, argv, "z|iif", &filename, &volume, &pitch, &pos RB_ARG_END); \
rb_get_args(argc, argv, "z|iif", &filename, &volume, &pitch, &pos RB_ARG_END); \
else \
rb_get_args(argc, argv, "z|ii", &filename, &volume, &pitch RB_ARG_END); \
GUARD_EXC( shState->audio().entity##Play(filename, volume, pitch, pos); ) \ GUARD_EXC( shState->audio().entity##Play(filename, volume, pitch, pos); ) \
return Qnil; \ return Qnil; \
} \ } \

View file

@ -587,6 +587,8 @@ static void mriBindingExecute()
ruby_sysinit(&argc, &argv); ruby_sysinit(&argc, &argv);
ruby_setup(); ruby_setup();
char options_argv1[] = "oneshot", options_argv2[] = "-e", options_argv3[] = "";
char* options_argv[] = {options_argv1, options_argv2, options_argv3, NULL};
rb_enc_set_default_external(rb_enc_from_encoding(rb_utf8_encoding())); rb_enc_set_default_external(rb_enc_from_encoding(rb_utf8_encoding()));
Config &conf = shState->rtData().config; Config &conf = shState->rtData().config;

View file

@ -30,8 +30,25 @@
#include "exception.h" #include "exception.h"
enum RbException #include <ruby.h>
{ #ifndef MKXPZ_LEGACY_RUBY
#include <ruby/version.h>
#else
#include <version.h>
#endif
#ifdef RUBY_API_VERSION_MAJOR
#define RAPI_MAJOR RUBY_API_VERSION_MAJOR
#define RAPI_MINOR RUBY_API_VERSION_MINOR
#define RAPI_TEENY RUBY_API_VERSION_TEENY
#else
#define RAPI_MAJOR RUBY_VERSION_MAJOR
#define RAPI_MINOR RUBY_VERSION_MINOR
#define RAPI_TEENY RUBY_VERSION_TEENY
#endif
#define RAPI_FULL ((RAPI_MAJOR * 100) + (RAPI_MINOR * 10) + RAPI_TEENY)
enum RbException {
RGSS = 0, RGSS = 0,
Reset, Reset,
PHYSFS, PHYSFS,
@ -48,8 +65,7 @@ enum RbException
RbExceptionsMax RbExceptionsMax
}; };
struct RbData struct RbData{
{
VALUE exc[RbExceptionsMax]; VALUE exc[RbExceptionsMax];
/* Input module (RGSS3) */ /* Input module (RGSS3) */
@ -63,21 +79,19 @@ RbData *getRbData();
struct Exception; struct Exception;
void void raiseRbExc(const Exception &exc);
raiseRbExc(const Exception &exc);
#define DECL_TYPE(Klass) \ #if RAPI_FULL > 187
extern rb_data_type_t Klass##Type #define DECL_TYPE(Klass) extern rb_data_type_t Klass##Type
/* 2.1 has added a new field (flags) to rb_data_type_t */ #if RAPI_FULL >= 210
#include <ruby/version.h>
#if RUBY_API_VERSION_MAJOR >= 2 && RUBY_API_VERSION_MINOR >= 1
/* TODO: can mkxp use RUBY_TYPED_FREE_IMMEDIATELY here? */ /* TODO: can mkxp use RUBY_TYPED_FREE_IMMEDIATELY here? */
#define DEF_TYPE_FLAGS 0 #define DEF_TYPE_FLAGS 0
#else #else
#define DEF_TYPE_FLAGS #define DEF_TYPE_FLAGS
#endif #endif
#endif
/* /*
#define DEF_TYPE_CUSTOMNAME_AND_FREE(Klass, Name, Free) \ #define DEF_TYPE_CUSTOMNAME_AND_FREE(Klass, Name, Free) \
rb_data_type_t Klass##Type = { Name, { 0, Free, 0, { 0, 0 } }, 0, 0, (void*)DEF_TYPE_FLAGS } rb_data_type_t Klass##Type = { Name, { 0, Free, 0, { 0, 0 } }, 0, 0, (void*)DEF_TYPE_FLAGS }
@ -95,81 +109,181 @@ raiseRbExc(const Exception &exc);
#define DEF_TYPE(Klass) DEF_TYPE_CUSTOMNAME(Klass, #Klass) #define DEF_TYPE(Klass) DEF_TYPE_CUSTOMNAME(Klass, #Klass)
template<rb_data_type_t *rbType> // Ruby 1.8 helper stuff
static VALUE classAllocate(VALUE klass) #if RAPI_MAJOR < 2
{
/* 2.3 has changed the name of this function */ #if RAPI_MINOR < 9
#if RUBY_API_VERSION_MAJOR >= 2 && RUBY_API_VERSION_MINOR >= 3 #define RUBY_T_FIXNUM T_FIXNUM
return rb_data_typed_object_wrap(klass, 0, rbType); #define RUBY_T_TRUE T_TRUE
#define RUBY_T_FALSE T_FALSE
#define RUBY_T_NIL T_NIL
#define RUBY_T_UNDEF T_UNDEF
#define RUBY_T_SYMBOL T_SYMBOL
#define RUBY_T_FLOAT T_FLOAT
#define RUBY_T_STRING T_STRING
#define RUBY_T_ARRAY T_ARRAY
#else #else
return rb_data_typed_object_alloc(klass, 0, rbType); #define T_FIXNUM RUBY_T_FIXNUM
#define T_TRUE RUBY_T_TRUE
#define T_FALSE RUBY_T_FALSE
#define T_NIL RUBY_T_NIL
#define T_UNDEF RUBY_T_UNDEF
#define T_SYMBOL RUBY_T_SYMBOL
#define T_FLOAT RUBY_T_FLOAT
#define T_STRING RUBY_T_STRING
#define T_ARRAY RUBY_T_ARRAY
#endif #endif
#if RAPI_MINOR < 9
#define RUBY_Qtrue Qtrue
#define RUBY_Qfalse Qfalse
#define RUBY_Qnil Qnil
#define RUBY_Qundef Qundef
#endif
#if RAPI_MINOR < 9
#define RB_FIXNUM_P(obj) FIXNUM_P(obj)
#define RB_SYMBOL_P(obj) SYMBOL_P(obj)
#define RB_TYPE_P(obj, type) \
(((type) == RUBY_T_FIXNUM) \
? RB_FIXNUM_P(obj) \
: ((type) == RUBY_T_TRUE) \
? ((obj) == RUBY_Qtrue) \
: ((type) == RUBY_T_FALSE) \
? ((obj) == RUBY_Qfalse) \
: ((type) == RUBY_T_NIL) \
? ((obj) == RUBY_Qnil) \
: ((type) == RUBY_T_UNDEF) \
? ((obj) == RUBY_Qundef) \
: ((type) == RUBY_T_SYMBOL) \
? RB_SYMBOL_P(obj) \
: (!SPECIAL_CONST_P(obj) && \
BUILTIN_TYPE(obj) == (type)))
#endif
#define OBJ_INIT_COPY(a, b) rb_obj_init_copy(a, b)
#define DEF_ALLOCFUNC_CUSTOMFREE(type, free) \
static VALUE type##Allocate(VALUE klass) { \
return Data_Wrap_Struct(klass, 0, free, 0); \
} }
template<class C> #define DEF_ALLOCFUNC(type) DEF_ALLOCFUNC_CUSTOMFREE(type, freeInstance<type>)
static void freeInstance(void *inst)
{ #if RAPI_MINOR < 9
delete static_cast<C*>(inst); #define rb_utf8_str_new_cstr rb_str_new2
#define rb_utf8_str_new rb_str_new
#endif
#define PRIsVALUE "s"
#endif
// end
#if RAPI_FULL > 187
template <rb_data_type_t *rbType> static VALUE classAllocate(VALUE klass) {
/* 2.3 has changed the name of this function */
#if RAPI_FULL >= 230
return rb_data_typed_object_wrap(klass, 0, rbType);
#else
return rb_data_typed_object_alloc(klass, 0, rbType);
#endif
}
#endif
template <class C> static void freeInstance(void *inst) {
delete static_cast<C *>(inst);
} }
void void raiseDisposedAccess(VALUE self);
raiseDisposedAccess(VALUE self); template <class C> inline C *getPrivateData(VALUE self) {
#if RAPI_FULL > 187
template<class C> C *c = static_cast<C *>(RTYPEDDATA_DATA(self));
inline C * #else
getPrivateData(VALUE self) C *c = static_cast<C *>(DATA_PTR(self));
{ #endif
C *c = static_cast<C*>(RTYPEDDATA_DATA(self)); if (!c) {
raiseRbExc(Exception(Exception::MKXPError, "No instance data for variable (missing call to super?)"));
}
return c; return c;
} }
template<class C> template <class C>
static inline C * static inline C *
#if RAPI_FULL > 187
getPrivateDataCheck(VALUE self, const rb_data_type_t &type) getPrivateDataCheck(VALUE self, const rb_data_type_t &type)
#else
getPrivateDataCheck(VALUE self, const char *type)
#endif
{ {
void *obj = Check_TypedStruct(self, &type); #if RAPI_FULL <= 187
return static_cast<C*>(obj); rb_check_type(self, T_DATA);
VALUE otherObj = rb_const_get(rb_cObject, rb_intern(type));
const char *ownname, *othername;
if (!rb_obj_is_kind_of(self, otherObj)) {
ownname = rb_obj_classname(self);
othername = rb_obj_classname(otherObj);
rb_raise(rb_eTypeError, "Can't convert %s into %s", othername, ownname);
}
void *obj = DATA_PTR(self);
#else
const char *ownname = rb_obj_classname(self);
if (!rb_typeddata_is_kind_of(self, &type))
rb_raise(rb_eTypeError, "Can't convert %s into %s", ownname,
type.wrap_struct_name);
void *obj = RTYPEDDATA_DATA(self);
#endif
return static_cast<C *>(obj);
} }
static inline void static inline void setPrivateData(VALUE self, void *p) {
setPrivateData(VALUE self, void *p) #if RAPI_FULL > 187
{
RTYPEDDATA_DATA(self) = p; RTYPEDDATA_DATA(self) = p;
#else
DATA_PTR(self) = p;
#endif
} }
inline VALUE inline VALUE
wrapObject(void *p, const rb_data_type_t &type, #if RAPI_FULL > 187
VALUE underKlass = rb_cObject) wrapObject(void *p, const rb_data_type_t &type, VALUE underKlass = rb_cObject)
#else
wrapObject(void *p, const char *type, VALUE underKlass = rb_cObject)
#endif
{ {
VALUE klass = rb_const_get(underKlass, rb_intern(type.wrap_struct_name)); #if RAPI_FULL > 187
VALUE obj = rb_obj_alloc(klass); VALUE klass = rb_const_get(underKlass, rb_intern(type.wrap_struct_name));
#else
VALUE klass = rb_const_get(underKlass, rb_intern(type));
#endif
VALUE obj = rb_obj_alloc(klass);
setPrivateData(obj, p); setPrivateData(obj, p);
return obj; return obj;
} }
inline VALUE inline VALUE wrapProperty(VALUE self, void *prop, const char *iv,
wrapProperty(VALUE self, void *prop, const char *iv, #if RAPI_FULL > 187
const rb_data_type_t &type, const rb_data_type_t &type,
VALUE underKlass = rb_cObject) #else
{ const char *type,
#endif
VALUE underKlass = rb_cObject) {
VALUE propObj = wrapObject(prop, type, underKlass); VALUE propObj = wrapObject(prop, type, underKlass);
rb_iv_set(self, iv, propObj); rb_iv_set(self, iv, propObj);
return propObj; return propObj;
} }
/* Implemented: oSszfibn| */ /* Implemented: oSszfibn| */
int int rb_get_args(int argc, VALUE *argv, const char *format, ...);
rb_get_args(int argc, VALUE *argv, const char *format, ...);
/* Always terminate 'rb_get_args' with this */ /* Always terminate 'rb_get_args' with this */
#ifndef NDEBUG #ifndef NDEBUG
# define RB_ARG_END_VAL ((void*) -1) # define RB_ARG_END_VAL ((void *) -1)
# define RB_ARG_END ,RB_ARG_END_VAL # define RB_ARG_END , RB_ARG_END_VAL
#else #else
# define RB_ARG_END # define RB_ARG_END
#endif #endif
@ -177,30 +291,37 @@ rb_get_args(int argc, VALUE *argv, const char *format, ...);
typedef VALUE (*RubyMethod)(int argc, VALUE *argv, VALUE self); typedef VALUE (*RubyMethod)(int argc, VALUE *argv, VALUE self);
static inline void static inline void
_rb_define_method(VALUE klass, const char *name, RubyMethod func) _rb_define_method(VALUE klass, const char *name, RubyMethod func){
{
rb_define_method(klass, name, RUBY_METHOD_FUNC(func), -1); rb_define_method(klass, name, RUBY_METHOD_FUNC(func), -1);
} }
static inline void static inline void
rb_define_class_method(VALUE klass, const char *name, RubyMethod func) rb_define_class_method(VALUE klass, const char *name, RubyMethod func){
{
rb_define_singleton_method(klass, name, RUBY_METHOD_FUNC(func), -1); rb_define_singleton_method(klass, name, RUBY_METHOD_FUNC(func), -1);
} }
static inline void static inline void
_rb_define_module_function(VALUE module, const char *name, RubyMethod func) _rb_define_module_function(VALUE module, const char *name, RubyMethod func){
{
rb_define_module_function(module, name, RUBY_METHOD_FUNC(func), -1); rb_define_module_function(module, name, RUBY_METHOD_FUNC(func), -1);
} }
#define GUARD_EXC(exp) \ #define GUARD_EXC(exp) \
{ try { exp } catch (const Exception &exc) { raiseRbExc(exc); } } { try { exp } catch (const Exception &exc) { raiseRbExc(exc); } }
template<class C> #define GFX_GUARD_EXC(exp) \
static inline VALUE {\
objectLoad(int argc, VALUE *argv, VALUE self) GFX_LOCK; \
{ try {\
exp \
} catch (const Exception &exc) {\
GFX_UNLOCK; \
raiseRbExc(exc); \
}\
GFX_UNLOCK;\
}
template <class C>
static inline VALUE objectLoad(int argc, VALUE *argv, VALUE self) {
const char *data; const char *data;
int dataLen; int dataLen;
rb_get_args(argc, argv, "s", &data, &dataLen RB_ARG_END); rb_get_args(argc, argv, "s", &data, &dataLen RB_ARG_END);
@ -209,7 +330,7 @@ objectLoad(int argc, VALUE *argv, VALUE self)
C *c = 0; C *c = 0;
GUARD_EXC( c = C::deserialize(data, dataLen); ); GUARD_EXC(c = C::deserialize(data, dataLen););
setPrivateData(obj, c); setPrivateData(obj, c);
@ -217,75 +338,83 @@ objectLoad(int argc, VALUE *argv, VALUE self)
} }
static inline VALUE static inline VALUE
rb_bool_new(bool value) rb_bool_new(bool value){
{
return value ? Qtrue : Qfalse; return value ? Qtrue : Qfalse;
} }
inline void inline void rb_float_arg(VALUE arg, double *out, int argPos = 0) {
rb_float_arg(VALUE arg, double *out, int argPos = 0) switch (rb_type(arg)) {
{ case RUBY_T_FLOAT:
switch (rb_type(arg)) *out = RFLOAT_VALUE(arg);
{ break;
case RUBY_T_FLOAT :
*out = RFLOAT_VALUE(arg);
break;
case RUBY_T_FIXNUM : case RUBY_T_FIXNUM:
*out = FIX2INT(arg); *out = FIX2INT(arg);
break; break;
default: default:
rb_raise(rb_eTypeError, "Argument %d: Expected float", argPos); rb_raise(rb_eTypeError, "Argument %d: Expected float", argPos);
} }
} }
inline void inline void rb_int_arg(VALUE arg, int *out, int argPos = 0) {
rb_int_arg(VALUE arg, int *out, int argPos = 0) switch (rb_type(arg)) {
{ case RUBY_T_FLOAT:
switch (rb_type(arg)) // FIXME check int range?
{ *out = NUM2LONG(arg);
case RUBY_T_FLOAT : break;
// FIXME check int range?
*out = NUM2LONG(arg);
break;
case RUBY_T_FIXNUM : case RUBY_T_FIXNUM:
*out = FIX2INT(arg); *out = FIX2INT(arg);
break; break;
default: default:
rb_raise(rb_eTypeError, "Argument %d: Expected fixnum", argPos); rb_raise(rb_eTypeError, "Argument %d: Expected fixnum", argPos);
} }
} }
inline void inline void rb_bool_arg(VALUE arg, bool *out, int argPos = 0) {
rb_bool_arg(VALUE arg, bool *out, int argPos = 0) switch (rb_type(arg)) {
{ case RUBY_T_TRUE:
switch (rb_type(arg)) *out = true;
{ break;
case RUBY_T_TRUE :
*out = true;
break;
case RUBY_T_FALSE : case RUBY_T_FALSE:
case RUBY_T_NIL : case RUBY_T_NIL:
*out = false; *out = false;
break; break;
default: default:
rb_raise(rb_eTypeError, "Argument %d: Expected bool", argPos); rb_raise(rb_eTypeError, "Argument %d: Expected bool", argPos);
} }
} }
inline void inline void rb_check_argc(int actual, int expected){
rb_check_argc(int actual, int expected)
{
if (actual != expected) if (actual != expected)
rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)",
actual, expected); actual, expected);
} }
#if RAPI_MAJOR < 2
static inline void rb_error_arity(int argc, int min, int max) {
if (argc > max || argc < min)
rb_raise(rb_eArgError, "Finish me! rb_error_arity()"); // TODO
}
#if RAPI_MINOR < 9
static inline VALUE rb_sprintf(const char *fmt, ...) {
return rb_str_new2("Finish me! rb_sprintf()"); // TODO
}
static inline VALUE rb_str_catf(VALUE obj, const char *fmt, ...) {
return rb_str_new2("Finish me! rb_str_catf()"); // TODO
}
static inline VALUE rb_file_open_str(VALUE filename, const char *mode) {
return rb_funcall(rb_cFile, rb_intern("open"), 2, filename,
rb_str_new2(mode));
}
#endif
#endif
#define RB_METHOD(name) \ #define RB_METHOD(name) \
static VALUE name(int argc, VALUE *argv, VALUE self) static VALUE name(int argc, VALUE *argv, VALUE self)

View file

@ -181,7 +181,7 @@ void Config::read(int argc, char *argv[])
//Hardcode some ini/version settings //Hardcode some ini/version settings
rgssVersion = 1; rgssVersion = 1;
game.title = "OneShot"; game.title = "OneShot: Sunshine";
game.scripts = "Data/xScripts.rxdata"; game.scripts = "Data/xScripts.rxdata";
defScreenW = 640; defScreenW = 640;
defScreenH = 480; defScreenH = 480;