mirror of
https://github.com/mkxp-z/mkxp-z.git
synced 2025-08-04 05:55:31 +02:00
Merge branch 'windows-console' into 'dev'
Implement a debug console for Windows See merge request mkxp-z/mkxp-z!31
This commit is contained in:
commit
524dff4346
3 changed files with 99 additions and 0 deletions
|
@ -47,6 +47,10 @@ extern "C" {
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <string>
|
||||
#include <zlib.h>
|
||||
|
@ -70,6 +74,7 @@ extern const char module_rpg3[];
|
|||
static void mriBindingExecute();
|
||||
static void mriBindingTerminate();
|
||||
static void mriBindingReset();
|
||||
static void configureWindowsStreams();
|
||||
|
||||
ScriptBinding scriptBindingImpl = {mriBindingExecute, mriBindingTerminate,
|
||||
mriBindingReset};
|
||||
|
@ -219,6 +224,10 @@ static void mriBindingInit() {
|
|||
rb_gv_set("TEST", debug);
|
||||
|
||||
rb_gv_set("BTEST", rb_bool_new(shState->config().editor.battleTest));
|
||||
|
||||
// Set $stdout and its ilk accordingly on Windows
|
||||
if (shState->config().editor.debug)
|
||||
configureWindowsStreams();
|
||||
|
||||
// Load zlib, if it's present. Requires --with-static-linked-ext or zlib.so.
|
||||
// It's okay if it fails, normally it wouldn't be defined anyway.
|
||||
|
@ -746,6 +755,41 @@ static void runRMXPScripts(BacktraceData &btData) {
|
|||
}
|
||||
#endif
|
||||
|
||||
// Attempts to set $stdout and $stdin accordingly on Windows. Only
|
||||
// called when debug mode is on, since that's when the console
|
||||
// should be active.
|
||||
static void configureWindowsStreams() {
|
||||
#ifdef __WINDOWS__
|
||||
#define HANDLE_VALID(handle) handle && handle != INVALID_HANDLE_VALUE
|
||||
|
||||
const HANDLE outputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
|
||||
// Configure $stdout
|
||||
if (HANDLE_VALID(outputHandle)) {
|
||||
const int stdoutFD = _open_osfhandle((intptr_t)outputHandle, _O_TEXT);
|
||||
|
||||
VALUE winStdout = rb_funcall(rb_cIO, rb_intern("new"), 2,
|
||||
INT2NUM(stdoutFD), rb_str_new_cstr("w"));
|
||||
|
||||
rb_gv_set("stdout", winStdout);
|
||||
}
|
||||
|
||||
const HANDLE inputHandle = GetStdHandle(STD_INPUT_HANDLE);
|
||||
|
||||
// Configure $stdin
|
||||
if (HANDLE_VALID(inputHandle)) {
|
||||
const int stdinFD = _open_osfhandle((intptr_t)inputHandle, _O_TEXT);
|
||||
|
||||
VALUE winStdin = rb_funcall(rb_cIO, rb_intern("new"), 2,
|
||||
INT2NUM(stdinFD), rb_str_new_cstr("r"));
|
||||
|
||||
rb_gv_set("stdin", winStdin);
|
||||
}
|
||||
|
||||
#undef HANDLE_VALID
|
||||
#endif // #ifdef __WINDOWS__
|
||||
}
|
||||
|
||||
static void showExc(VALUE exc, const BacktraceData &btData) {
|
||||
VALUE bt = rb_funcall2(exc, rb_intern("backtrace"), 0, NULL);
|
||||
VALUE msg = rb_funcall2(exc, rb_intern("message"), 0, NULL);
|
||||
|
@ -821,9 +865,15 @@ static void mriBindingExecute() {
|
|||
/* Normally only a ruby executable would do a sysinit,
|
||||
* but not doing it will lead to crashes due to closed
|
||||
* stdio streams on some platforms (eg. Windows) */
|
||||
#ifdef __WINDOWS__
|
||||
if (!conf.editor.debug) {
|
||||
#endif
|
||||
int argc = 0;
|
||||
char **argv = 0;
|
||||
ruby_sysinit(&argc, &argv);
|
||||
#ifdef __WINDOWS__
|
||||
}
|
||||
#endif
|
||||
|
||||
RUBY_INIT_STACK;
|
||||
ruby_init();
|
||||
|
|
15
src/main.cpp
15
src/main.cpp
|
@ -48,6 +48,7 @@
|
|||
#if defined(__WINDOWS__)
|
||||
#include "resource.h"
|
||||
#include <Winsock2.h>
|
||||
#include "util/win-consoleutils.h"
|
||||
#endif
|
||||
|
||||
#ifdef MKXPZ_STEAM
|
||||
|
@ -282,6 +283,20 @@ int main(int argc, char *argv[]) {
|
|||
showInitError(
|
||||
std::string(buf)); // Not an error worth ending the program over
|
||||
}
|
||||
|
||||
// Create a debug console in debug mode
|
||||
if (conf.editor.debug) {
|
||||
HANDLE winConsoleHandle;
|
||||
|
||||
if (setupWindowsConsole(winConsoleHandle)) {
|
||||
reopenWindowsStreams();
|
||||
} else {
|
||||
char buf[200];
|
||||
snprintf(buf, sizeof(buf), "Error allocating console: %lu",
|
||||
GetLastError());
|
||||
showInitError(std::string(buf));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
SDL_Window *win;
|
||||
|
|
34
src/util/win-consoleutils.h
Normal file
34
src/util/win-consoleutils.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
#ifndef WIN_CONSOLEUTIL_H
|
||||
#define WIN_CONSOLEUTIL_H
|
||||
|
||||
#include <iostream>
|
||||
#include "windows.h"
|
||||
|
||||
// Attempts to allocate a console and fetch the output handle.
|
||||
// Returns whether the operation was successful.
|
||||
// Extended error information can be received via GetLastError().
|
||||
bool setupWindowsConsole(HANDLE &handle)
|
||||
{
|
||||
if (!AllocConsole())
|
||||
return false;
|
||||
|
||||
handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
|
||||
return (handle != NULL && handle != INVALID_HANDLE_VALUE);
|
||||
}
|
||||
|
||||
// Reopens the file streams. This should be done after successfully
|
||||
// setting up the console.
|
||||
void reopenWindowsStreams()
|
||||
{
|
||||
FILE* fDummy;
|
||||
freopen_s(&fDummy, "CONOUT$", "w", stdout);
|
||||
freopen_s(&fDummy, "CONOUT$", "w", stderr);
|
||||
freopen_s(&fDummy, "CONIN$", "r", stdin);
|
||||
std::cout.clear();
|
||||
std::clog.clear();
|
||||
std::cerr.clear();
|
||||
std::cin.clear();
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Add table
Reference in a new issue