mirror of
https://github.com/mkxp-z/mkxp-z.git
synced 2025-08-04 22:15:33 +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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __WINDOWS__
|
||||||
|
#include <fcntl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
@ -70,6 +74,7 @@ extern const char module_rpg3[];
|
||||||
static void mriBindingExecute();
|
static void mriBindingExecute();
|
||||||
static void mriBindingTerminate();
|
static void mriBindingTerminate();
|
||||||
static void mriBindingReset();
|
static void mriBindingReset();
|
||||||
|
static void configureWindowsStreams();
|
||||||
|
|
||||||
ScriptBinding scriptBindingImpl = {mriBindingExecute, mriBindingTerminate,
|
ScriptBinding scriptBindingImpl = {mriBindingExecute, mriBindingTerminate,
|
||||||
mriBindingReset};
|
mriBindingReset};
|
||||||
|
@ -219,6 +224,10 @@ static void mriBindingInit() {
|
||||||
rb_gv_set("TEST", debug);
|
rb_gv_set("TEST", debug);
|
||||||
|
|
||||||
rb_gv_set("BTEST", rb_bool_new(shState->config().editor.battleTest));
|
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.
|
// 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.
|
// It's okay if it fails, normally it wouldn't be defined anyway.
|
||||||
|
@ -746,6 +755,41 @@ static void runRMXPScripts(BacktraceData &btData) {
|
||||||
}
|
}
|
||||||
#endif
|
#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) {
|
static void showExc(VALUE exc, const BacktraceData &btData) {
|
||||||
VALUE bt = rb_funcall2(exc, rb_intern("backtrace"), 0, NULL);
|
VALUE bt = rb_funcall2(exc, rb_intern("backtrace"), 0, NULL);
|
||||||
VALUE msg = rb_funcall2(exc, rb_intern("message"), 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,
|
/* Normally only a ruby executable would do a sysinit,
|
||||||
* but not doing it will lead to crashes due to closed
|
* but not doing it will lead to crashes due to closed
|
||||||
* stdio streams on some platforms (eg. Windows) */
|
* stdio streams on some platforms (eg. Windows) */
|
||||||
|
#ifdef __WINDOWS__
|
||||||
|
if (!conf.editor.debug) {
|
||||||
|
#endif
|
||||||
int argc = 0;
|
int argc = 0;
|
||||||
char **argv = 0;
|
char **argv = 0;
|
||||||
ruby_sysinit(&argc, &argv);
|
ruby_sysinit(&argc, &argv);
|
||||||
|
#ifdef __WINDOWS__
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
RUBY_INIT_STACK;
|
RUBY_INIT_STACK;
|
||||||
ruby_init();
|
ruby_init();
|
||||||
|
|
15
src/main.cpp
15
src/main.cpp
|
@ -48,6 +48,7 @@
|
||||||
#if defined(__WINDOWS__)
|
#if defined(__WINDOWS__)
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
#include <Winsock2.h>
|
#include <Winsock2.h>
|
||||||
|
#include "util/win-consoleutils.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MKXPZ_STEAM
|
#ifdef MKXPZ_STEAM
|
||||||
|
@ -282,6 +283,20 @@ int main(int argc, char *argv[]) {
|
||||||
showInitError(
|
showInitError(
|
||||||
std::string(buf)); // Not an error worth ending the program over
|
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
|
#endif
|
||||||
|
|
||||||
SDL_Window *win;
|
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