Ancurio / mkxp

Free Software implementation of the Ruby Game Scripting System (RGSS)
GNU General Public License v2.0
515 stars 131 forks source link

Discussion: Windows MKXP #35

Closed hanetzer closed 6 years ago

hanetzer commented 10 years ago

been fiddling with building mkxp on windows, after catching a stray uint and trying again, it seems the main issue regarding building on windows is a gmtime_r conflict that occurs upon inclusion of ruby's win32.h

The exact error generated can be found in this gist: https://gist.github.com/ntzrmtthihu777/e81aaa9cd95277bf9991#file-gistfile1-txt Note: compiled with clang/clang++ for more verbose error output.

hanetzer commented 10 years ago

found the smallest test program one could write to trigger this output,

#include <string>
#include "ruby.h"
int main() {
  return(0)
}

compiling with g++ test.cpp -Iruby-2.1.0/ -Iruby-2.1.0/x64-mingw32/ results in the above error

cremno commented 10 years ago

Could you try compiling with -std=c++98? Maybe there is a reason why this isn't explicitly set. AFAIK mkxp itself doesn't use any GNU extensions. But even if mkxp compiles fine with this workaround, CRuby's header shouldn't unconditionally declare gmtime_r.

hanetzer commented 10 years ago

ok, will give it a shot and report back. Note, reversing the #incldue directives fixes the issue in the test.cpp program, but its probably too minimal for application in mkxp itself.

hanetzer commented 10 years ago

Nope, same error as before... this is rather annoying, windows, y u no posix!?

hanetzer commented 10 years ago

I don't suppose you have access to a windows machine to test with? this is really irksome :/

Ancurio commented 10 years ago

This is yours yes? https://www.ruby-forum.com/topic/4939821

Also this could be related: Also this could be related: http://sourceforge.net/p/mingw/bugs/1625/ (also this)

hanetzer commented 10 years ago

Yes, that is mine, and I've seen both of those pages, lol. gmtime_r is defined in pthreads.h and time.h in the msys2 package mingw-w64-{i686,x86_64}-winpthreads-git I'm going to bug the mingw-w64 folks as well

hanetzer commented 10 years ago

Hmm... I've reported it to mingw-w64 and they're gonna convert gmtime_r to an inline from a macro, but my ruby bug report has been updated with including <ctime> as fixing the test program.

hanetzer commented 10 years ago

Yep, the patch fixes the gmtime_r issue but raises a new one.

Ancurio commented 10 years ago

What new issue?

hanetzer commented 10 years ago

rand(), but including <stdlib.h> in pthread.h fixes that, now I just have to fix up this sdl_sound issue :p

hanetzer commented 10 years ago

Now the current issue is: https://gist.github.com/ntzrmtthihu777/3b754e8aea64ad73141f a whole bunch of undefined reference to ModPlug_* basically.

Ancurio commented 10 years ago

Oh, you're statically linking. Yeah, the problem is very likely my limited pkgconfig file for SDL_sound which doesn't pass on the correct linker flags in case of static linking. You could compile SDL_sound with only WAV support as a temporary workaround for now, or compile it into a dll instead.

Ancurio commented 10 years ago

Alternatively, since all this needs is a -lmodplug, you could either add that manually in the Makefile, or try adding the line Requires.private: libmodplug to your SDL_sound.pc.

hanetzer commented 10 years ago

yeah. I don't really want to link static, but I can't seem to get sdl_sound's hg version with the patch to compile into a shared library; its driving me crazy, lol.

hanetzer commented 10 years ago

Success! well, to a degree... It compiles and 'runs', but though I do hear the music and it does accept options from mkxp.conf and opens a window, the window is nothing but solid black...

hanetzer commented 10 years ago

On another note, setting -Wl,-subsystem,windows to stop cmd.exe from opening works to a degree, but unless you invoke mkxp.exe from the msys shell it won't work (eg, double clicking it or running it via rpg maker). In addition, setting FORCE32 won't compile either, resulting in this error log: https://gist.github.com/ntzrmtthihu777/79eaefcb75c9ce551522

Ancurio commented 10 years ago

I was worried that the gmtime_r issue came up again, but it seems you edited the gist and now the errors are gone?

Anyway, I have a slight idea about the first three errors. Can you apply this patch and try again?

hanetzer commented 10 years ago

Yeah, the gmtime_r issue was there again, but that was because I hadn't patched win32.h for ruby on the 32 bit side. Ok, will check it out when I get back on my main machine; note, those compilation errors on occur when compiling 32bit.

hanetzer commented 10 years ago

Nope, exact same output. I would like to mention that appending -fpermissive to the arguments does allow it to compile and 'play' (same results as the 64-bit compile) but this is akin to sweeping the problem under the rug and not really fixing anything.

If possible, I'd like to work on actually getting a playable game, though. I'll mention that mkxp.conf settings do get applied. Also, I do get the OpenGL info in the console as well:

GL Vendor    : NVIDIA Corporation
GL Renderer  : GeForce GTX 650/PCIe/SSE2
GL Version   : 4.4.0
GLSL Version : 4.40 NVIDIA via Cg compiler
Ancurio commented 10 years ago

Hm. It looks like glew.h correctly defines APIENTRY to __stdcall, but then unconditionally undefs it again, wtf? Anyway..

Yes, it looks like everything is working, but for some reason the result of the OpenGL rendering isn't being swapped to the screen. In mkxp.conf, have you turned debugMode on? If you turn that on, check the console output again for any messages.

hanetzer commented 10 years ago

Assuming the proper syntax is debugMode=true, then yes. But, it doesn't do a thing, lol. Other mkxp.conf options work, however; to test that I set the screen to 800x600

Ancurio commented 10 years ago

Can you try to compile and run this test program: https://gist.github.com/Ancurio/001987a2e0b172a036b0 (only depends on sdl2)

hanetzer commented 10 years ago

hrm... being a pita on me. gcc -c -I /mingw64/include/SDL2 with and without -Dmain=SDL_main is giving me some nice headaches :/ https://gist.github.com/ntzrmtthihu777/e1ec2c096910099b6652

hanetzer commented 10 years ago

setting main to int main(int argc, char *argv[]) fixed that up though... apparently sdl needs this exact entry point structure, strange no?

Ancurio commented 10 years ago

My bad, I have updated the gist with an improved version that should compile on windows now. Can you try again?

setting main to int main(int argc, char *argv[]) fixed that up though... apparently sdl needs this exact entry point structure, strange no?

Yes, this is because on windows your main function isn't the actual main function =) SDL2 wraps around this and renames your main function, so the types have to match exactly. C++ only allows one signature, while C let's me do silly things like void main(void).

hanetzer commented 10 years ago

There we go. gcc -o non_mainthread_gl.exe non_mainthread_gl.c -I /mingw64/include/SDL2 -lmingw32 -lSDL2main -lSDL2 gives me a nice executable that does nothing other than to display a 640 480 red window, is this correct?

Ancurio commented 10 years ago

Does it switch to blue after a while? Also try resizing the window.

hanetzer commented 10 years ago

Sorry, didn't wait for it to change, lol. and yes, as I type this its shifting through purple into blue, and I can resize it down to just a bit larger than the window manager keys. (Just tested resizing with mkxp as well, I can resize it as much as I need, including the alt+enter fullscreen mode)

hanetzer commented 10 years ago

Actually I just noticed something. I think its an issue with event polling/passing. Even if the display isn't updating, you'd think that I could at least hear myself move the cursor up/down on the title screen of a default RMXP project, but nope. To further support this idea, that little SDL2 application you had me compile, I could close that either via ctrl+c in my console or by hitting the standard x button in the corner; I couldn't close the mkxp window with the window manager button, which makes me think the window destroy event never got passed along.

Ancurio commented 10 years ago

Ah, yes, that's what I was going to ask about next. You said that the intro music plays fine though?

If you hit the x button, and wait a while, does a dialog come up saying something like "RGSS script is stuck"?

hanetzer commented 10 years ago

Yep, The RGSS Script seems to be stuck and mkxp will now force quit.

Ancurio commented 10 years ago

Good, that means the main thread is doing ok and receiving events just fine. Somehow the rgss thread must have gotten stuck somewhere (possibly before the first Graphics.update call).

Do you have gdb at your disposal? We need to find out where the thread is stuck. It's usually enough to pause execution via Ctrl C and then type thread apply all bt.

hanetzer commented 10 years ago

Yes, I have gdb :P and I have a large amount of *nix programs available on windows, in a normal filesystem hierarchy standard for arch linux.

hanetzer commented 10 years ago

urm... lets see. How would I go about getting gdb linked into the mkxp process? gdb mkxp.exe followed by run just quits when I hit ctrl c.

Ancurio commented 10 years ago

Ok, according to this there's a couple workarounds for CtrlC not working on windows. I don't know which one is simpler, but I think just running mkxp and then attaching gdb with gdb <pid of mkxp> avoids compiling a helper program. Can you try one of them?

Edit: The correct command might actually be gdb mkxp.exe <pid>

hanetzer commented 10 years ago

hrm... I don't have pidof available... lemme query my package manager... shit.

hanetzer commented 10 years ago

Got it working, just used a normal cmd.exe window (my gdb is compiled with mingw-w64, so it is native), now what info do you need?

Ancurio commented 10 years ago

I need a full backtrace of all threads, via thread apply all bt.

hanetzer commented 10 years ago

Ok, learned how to create a logfile of gdb ouput, so here you go: https://gist.github.com/ntzrmtthihu777/8403b107ffa2f252287d

Ancurio commented 10 years ago

Cool. Can you give me another dump, this time with thread apply all bt full? Afterwards, try setting fixedFramerate=-1 in the conf and run mkxp normally.

hanetzer commented 10 years ago

holy shit! one, updated the gist with the log from thread apply all bt full, and then tested with fixedFramerate=-1 and it worked! Heh, I get to the title screen and it says its running at about 3k fps, and I can start the game and move around and such, but its all very very fast. But it is 'working' better than it was, at the very least.

Ancurio commented 10 years ago

Yes, setting fixedFramerate=-1 skips execution of where the thread appears to hang =) (It also means that, without vsync turned on, the game will render as fast as possible).

I first suspected that FPSLimiter::delayTicks gets a too big number, but looking again I think this segment might be the problem:

struct timespec req;
req.tv_sec = 0;
req.tv_nsec = ticks / tickFreqNS;
while (nanosleep(&req, &req) == -1)
    ;
hanetzer commented 10 years ago

Sweet man, hope this gets fixed up soon :D On another note, from your vsync comment, I set that to true in mkxp.conf and it yealded a perfectly playable game running at 60fps, though I think the original RPG Maker XP Game.exe ran at 40fps or so. But I suspect that's another of those 'sweeping it under the rug' things. In any case, if you need testers on windows I'm more than willing to help, as I have shown, lol. I'm actually primarily a linux guy, but hey, I'd like good features on the windows version of a game I make as well :P

hanetzer commented 10 years ago

hrm. On another note, setting -Wl,-subsystem,windows to get rid of the console window popping up still fails when you double-click execute, but works fine from the shell :/

cremno commented 10 years ago

What about -mwindows instead?

hanetzer commented 10 years ago

one moment :P ... nope, same result. I'll see about editing the sdl2.pc file, I know the packager for the project I'm using does some derpy stuff with them sometimes :/

Ancurio commented 10 years ago

nanosleep might be returning -1, but not because it was interrupted but due to another error. When mkxp hangs without the fixedFramerate setting, does Task Manager show a high CPU usage for it?

hanetzer commented 10 years ago

guess that's a relative term. Without the fixedFramerate, cpu shows 17. With it, it shows 16/17. But, then again I do have a pretty beefy cpu, AMD FX-6300 hex core @ 3.5ghz

Ancurio commented 10 years ago

100% / 6 cores = ~17%, so it might indeed be spinning inside the while.

Can you apply this patch and recompile: https://gist.github.com/Ancurio/ae83d3bacc7991e5ca5b