mirror of
https://github.com/mkxp-z/mkxp-z.git
synced 2025-06-30 21:55:18 +02:00
Multiple changes
+ Time is now measured in fractions of a second, not microseconds + Viewports in RGSS1 will now only retain weak references to their children + Invalid Sprite bitmaps found during Graphics.update will be treated as null + Bitmap#mega? and Bitmap#animated? are properly rescued
This commit is contained in:
parent
d7bf67fada
commit
0072c19371
14 changed files with 79 additions and 42 deletions
|
@ -326,8 +326,7 @@ RB_METHOD(mriP) {
|
|||
|
||||
RB_METHOD(mkxpDelta) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
return ULL2NUM(shState->runTime());
|
||||
return rb_float_new(shState->runTime());
|
||||
}
|
||||
|
||||
RB_METHOD(mkxpDataDirectory) {
|
||||
|
|
|
@ -434,7 +434,11 @@ RB_METHOD(bitmapGetMega){
|
|||
|
||||
Bitmap *b = getPrivateData<Bitmap>(self);
|
||||
|
||||
return rb_bool_new(b->isMega());
|
||||
VALUE ret;
|
||||
|
||||
GFX_GUARD_EXC(ret = rb_bool_new(b->isMega()););
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
RB_METHOD(bitmapGetAnimated){
|
||||
|
@ -444,7 +448,11 @@ RB_METHOD(bitmapGetAnimated){
|
|||
|
||||
Bitmap *b = getPrivateData<Bitmap>(self);
|
||||
|
||||
return rb_bool_new(b->isAnimated());
|
||||
VALUE ret;
|
||||
|
||||
GFX_GUARD_EXC(ret = rb_bool_new(b->isAnimated()););
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
RB_METHOD(bitmapGetPlaying){
|
||||
|
|
|
@ -37,6 +37,8 @@ disposableAddChild(VALUE disp, VALUE child)
|
|||
return;
|
||||
}
|
||||
|
||||
VALUE objID = rb_obj_id(child);
|
||||
|
||||
VALUE children = rb_iv_get(disp, "children");
|
||||
|
||||
bool exists = false;
|
||||
|
@ -47,11 +49,11 @@ disposableAddChild(VALUE disp, VALUE child)
|
|||
rb_iv_set(disp, "children", children);
|
||||
}
|
||||
else {
|
||||
exists = RTEST(rb_funcall(children, rb_intern("include?"), 1, child));
|
||||
exists = RTEST(rb_funcall(children, rb_intern("include?"), 1, objID));
|
||||
}
|
||||
|
||||
if (!exists)
|
||||
rb_ary_push(children, child);
|
||||
rb_ary_push(children, objID);
|
||||
GFX_UNLOCK;
|
||||
}
|
||||
|
||||
|
@ -63,11 +65,13 @@ disposableRemoveChild(VALUE disp, VALUE child)
|
|||
return;
|
||||
}
|
||||
|
||||
VALUE objID = rb_obj_id(child);
|
||||
|
||||
VALUE children = rb_iv_get(disp, "children");
|
||||
if (NIL_P(children))
|
||||
return;
|
||||
|
||||
VALUE index = rb_funcall(children, rb_intern("index"), 1, child);
|
||||
VALUE index = rb_funcall(children, rb_intern("index"), 1, objID);
|
||||
if (NIL_P(index))
|
||||
return;
|
||||
|
||||
|
@ -83,10 +87,16 @@ disposableDisposeChildren(VALUE disp)
|
|||
if (NIL_P(children))
|
||||
return;
|
||||
|
||||
ID dispFun = rb_intern("_mkxp_dispose_alias");
|
||||
|
||||
for (long i = 0; i < RARRAY_LEN(children); ++i)
|
||||
rb_funcall2(rb_ary_entry(children, i), dispFun, 0, 0);
|
||||
for (long i = 0; i < RARRAY_LEN(children); ++i) {
|
||||
int state;
|
||||
rb_protect([](VALUE args){
|
||||
VALUE objectspace = rb_const_get(rb_cObject, rb_intern("ObjectSpace"));
|
||||
VALUE ref = rb_funcall(objectspace, rb_intern("_id2ref"), 1, args);
|
||||
rb_funcall(ref, rb_intern("_mkxp_dispose_alias"), 0);
|
||||
return Qnil;
|
||||
}, rb_ary_entry(children, i), &state);
|
||||
}
|
||||
//rb_funcall2(rb_ary_entry(children, i), dispFun, 0, 0);
|
||||
}
|
||||
|
||||
template<class C>
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
RB_METHOD(graphicsDelta) {
|
||||
RB_UNUSED_PARAM;
|
||||
GFX_LOCK;
|
||||
VALUE ret = ULL2NUM(shState->graphics().getDelta());
|
||||
VALUE ret = rb_float_new(shState->graphics().getDelta());
|
||||
GFX_UNLOCK;
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
RB_METHOD(inputDelta) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
return ULL2NUM(shState->input().getDelta());
|
||||
return rb_float_new(shState->input().getDelta());
|
||||
}
|
||||
|
||||
RB_METHOD(inputUpdate) {
|
||||
|
|
|
@ -166,12 +166,11 @@ struct BitmapPrivate
|
|||
std::vector<TEXFBO> frames;
|
||||
float fps;
|
||||
int lastFrame;
|
||||
unsigned long long startTime;
|
||||
unsigned long long playTime;
|
||||
double startTime, playTime;
|
||||
|
||||
inline unsigned int currentFrameIRaw() {
|
||||
if (fps <= 0) return lastFrame;
|
||||
return floor(lastFrame + (playTime / ((1 / fps) * 1000000)));
|
||||
return floor(lastFrame + (playTime / (1 / fps)));
|
||||
}
|
||||
|
||||
unsigned int currentFrameI() {
|
||||
|
@ -2104,6 +2103,24 @@ int Bitmap::maxSize(){
|
|||
return glState.caps.maxTexSize;
|
||||
}
|
||||
|
||||
// This might look ridiculous, but apparently, it is possible
|
||||
// to encounter seemingly empty bitmaps during Graphics::update,
|
||||
// or specifically, during a Sprite's prepare function.
|
||||
|
||||
// I have no idea why it happens, but it seems like just skipping
|
||||
// them makes it okay, so... that's what this function is for, at
|
||||
// least unless the actual source of the problem gets found, at
|
||||
// which point I'd get rid of it.
|
||||
|
||||
// I get it to happen by trying to beat the first rival fight in
|
||||
// Pokemon Flux, on macOS. I don't think I've seen anyone bring up
|
||||
// something like this happening anywhere else, so... I dunno.
|
||||
// If a game suddenly explodes during Graphics.update, maybe try
|
||||
// breakpointing this?
|
||||
bool Bitmap::invalid() const {
|
||||
return p == 0;
|
||||
}
|
||||
|
||||
void Bitmap::releaseResources()
|
||||
{
|
||||
if (p->megaSurface)
|
||||
|
|
|
@ -158,6 +158,8 @@ public:
|
|||
sigslot::signal<> modified;
|
||||
|
||||
static int maxSize();
|
||||
|
||||
bool invalid() const;
|
||||
|
||||
private:
|
||||
void releaseResources();
|
||||
|
|
|
@ -797,7 +797,7 @@ struct GraphicsPrivate {
|
|||
int frameCount;
|
||||
int brightness;
|
||||
|
||||
unsigned long long last_update;
|
||||
double last_update;
|
||||
|
||||
|
||||
FPSLimiter fpsLimiter;
|
||||
|
@ -816,8 +816,8 @@ struct GraphicsPrivate {
|
|||
bool integerScaleActive;
|
||||
bool integerLastMileScaling;
|
||||
|
||||
std::vector<unsigned long long> avgFPSData;
|
||||
unsigned long long last_avg_update;
|
||||
std::vector<double> avgFPSData;
|
||||
double last_avg_update;
|
||||
SDL_mutex *avgFPSLock;
|
||||
|
||||
SDL_mutex *glResourceLock;
|
||||
|
@ -837,7 +837,7 @@ struct GraphicsPrivate {
|
|||
last_update(0), last_avg_update(0), backingScaleFactor(1), integerScaleFactor(0, 0),
|
||||
integerScaleActive(rtData->config.integerScaling.active),
|
||||
integerLastMileScaling(rtData->config.integerScaling.lastMileScaling) {
|
||||
avgFPSData = std::vector<unsigned long long>();
|
||||
avgFPSData = std::vector<double>();
|
||||
avgFPSLock = SDL_CreateMutex();
|
||||
glResourceLock = SDL_CreateMutex();
|
||||
|
||||
|
@ -1079,7 +1079,7 @@ struct GraphicsPrivate {
|
|||
if (avgFPSData.size() > 40)
|
||||
avgFPSData.erase(avgFPSData.begin());
|
||||
|
||||
unsigned long long time = shState->runTime();
|
||||
double time = shState->runTime();
|
||||
avgFPSData.push_back(time - last_avg_update);
|
||||
last_avg_update = time;
|
||||
SDL_UnlockMutex(avgFPSLock);
|
||||
|
@ -1102,10 +1102,10 @@ struct GraphicsPrivate {
|
|||
double averageFPS() {
|
||||
double ret = 0;
|
||||
SDL_LockMutex(avgFPSLock);
|
||||
for (unsigned long long times : avgFPSData)
|
||||
for (double times : avgFPSData)
|
||||
ret += times;
|
||||
|
||||
ret = 1 / (ret / avgFPSData.size() / 1000000);
|
||||
ret = 1 / (ret / avgFPSData.size());
|
||||
SDL_UnlockMutex(avgFPSLock);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1138,11 +1138,11 @@ Graphics::Graphics(RGSSThreadData *data) {
|
|||
|
||||
Graphics::~Graphics() { delete p; }
|
||||
|
||||
unsigned long long Graphics::getDelta() {
|
||||
double Graphics::getDelta() {
|
||||
return shState->runTime() - p->last_update;
|
||||
}
|
||||
|
||||
unsigned long long Graphics::lastUpdate() {
|
||||
double Graphics::lastUpdate() {
|
||||
return p->last_update;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,8 +36,8 @@ struct Movie;
|
|||
class Graphics
|
||||
{
|
||||
public:
|
||||
unsigned long long getDelta();
|
||||
unsigned long long lastUpdate();
|
||||
double getDelta();
|
||||
double lastUpdate();
|
||||
|
||||
void update(bool checkForShutdown = true);
|
||||
void freeze();
|
||||
|
|
|
@ -188,6 +188,9 @@ struct SpritePrivate
|
|||
if (nullOrDisposed(bitmap))
|
||||
return;
|
||||
|
||||
if (bitmap->invalid())
|
||||
return;
|
||||
|
||||
if (!opacity)
|
||||
return;
|
||||
|
||||
|
|
|
@ -707,14 +707,12 @@ struct InputPrivate
|
|||
unsigned int rawRepeatCount;
|
||||
unsigned int buttonRepeatCount;
|
||||
|
||||
unsigned long long repeatTime;
|
||||
unsigned long long rawRepeatTime;
|
||||
unsigned long long buttonRepeatTime;
|
||||
double repeatTime, rawRepeatTime, buttonRepeatTime;
|
||||
|
||||
unsigned int repeatStart;
|
||||
unsigned int repeatDelay;
|
||||
|
||||
unsigned long long last_update;
|
||||
double last_update;
|
||||
|
||||
int vScrollDistance;
|
||||
|
||||
|
@ -1185,7 +1183,7 @@ Input::Input(const RGSSThreadData &rtData)
|
|||
p = new InputPrivate(rtData);
|
||||
}
|
||||
|
||||
unsigned long long Input::getDelta() {
|
||||
double Input::getDelta() {
|
||||
return shState->runTime() - p->last_update;
|
||||
}
|
||||
|
||||
|
@ -1301,7 +1299,7 @@ unsigned int Input::count(int button) {
|
|||
return p->repeatCount;
|
||||
}
|
||||
|
||||
unsigned long long Input::repeatTime(int button) {
|
||||
double Input::repeatTime(int button) {
|
||||
if (button != p->repeating)
|
||||
return 0;
|
||||
|
||||
|
@ -1367,7 +1365,7 @@ unsigned int Input::controllerRepeatcount(int button) {
|
|||
return p->buttonRepeatCount;
|
||||
}
|
||||
|
||||
unsigned long long Input::repeatTimeEx(int code, bool isVKey) {
|
||||
double Input::repeatTimeEx(int code, bool isVKey) {
|
||||
int c = code;
|
||||
if (isVKey) {
|
||||
try { c = vKeyToScancode[code]; }
|
||||
|
@ -1380,7 +1378,7 @@ unsigned long long Input::repeatTimeEx(int code, bool isVKey) {
|
|||
return shState->runTime() - p->rawRepeatTime;
|
||||
}
|
||||
|
||||
unsigned long long Input::controllerRepeatTimeEx(int button) {
|
||||
double Input::controllerRepeatTimeEx(int button) {
|
||||
if (button != p->buttonRepeating)
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ public:
|
|||
|
||||
void recalcRepeat(unsigned int fps);
|
||||
|
||||
unsigned long long getDelta();
|
||||
double getDelta();
|
||||
void update();
|
||||
|
||||
std::vector<std::string> getBindings(ButtonCode code);
|
||||
|
@ -68,21 +68,21 @@ public:
|
|||
bool isRepeated(int button);
|
||||
bool isReleased(int button);
|
||||
unsigned int count(int button);
|
||||
unsigned long long repeatTime(int button);
|
||||
double repeatTime(int button);
|
||||
|
||||
bool isPressedEx(int code, bool isVKey);
|
||||
bool isTriggeredEx(int code, bool isVKey);
|
||||
bool isRepeatedEx(int code, bool isVKey);
|
||||
bool isReleasedEx(int code, bool isVKey);
|
||||
unsigned int repeatcount(int code, bool isVKey);
|
||||
unsigned long long repeatTimeEx(int code, bool isVKey);
|
||||
double repeatTimeEx(int code, bool isVKey);
|
||||
|
||||
bool controllerIsPressedEx(int button);
|
||||
bool controllerIsTriggeredEx(int button);
|
||||
bool controllerIsRepeatedEx(int button);
|
||||
bool controllerIsReleasedEx(int button);
|
||||
unsigned int controllerRepeatcount(int button);
|
||||
unsigned long long controllerRepeatTimeEx(int button);
|
||||
double controllerRepeatTimeEx(int button);
|
||||
|
||||
uint8_t *rawKeyStates();
|
||||
unsigned int rawKeyStatesLength();
|
||||
|
|
|
@ -363,10 +363,10 @@ Font &SharedState::defaultFont() const
|
|||
return *p->defaultFont;
|
||||
}
|
||||
|
||||
unsigned long long SharedState::runTime() {
|
||||
double SharedState::runTime() {
|
||||
if (!p) return 0;
|
||||
const auto now = std::chrono::steady_clock::now();
|
||||
return std::chrono::duration_cast<std::chrono::microseconds>(now - p->startupTime).count();
|
||||
return std::chrono::duration_cast<std::chrono::microseconds>(now - p->startupTime).count() / 1000.0 / 1000.0;
|
||||
}
|
||||
|
||||
unsigned int SharedState::genTimeStamp()
|
||||
|
|
|
@ -86,7 +86,7 @@ struct SharedState
|
|||
unsigned int genTimeStamp();
|
||||
|
||||
// Returns time since SharedState was constructed in microseconds
|
||||
unsigned long long runTime();
|
||||
double runTime();
|
||||
|
||||
/* Returns global quad IBO, and ensures it has indices
|
||||
* for at least minSize quads */
|
||||
|
|
Loading…
Add table
Reference in a new issue