overlayPrint() fixed. Console and Logo suppression separated. Unwanted console window on Windows fixed. Mouse mapping matches Singe 1.xx.

This commit is contained in:
Scott Duensing 2020-03-14 17:31:10 -05:00
parent bd35674b21
commit 4f7c0c38b3
10 changed files with 142 additions and 115 deletions

View file

@ -19,14 +19,19 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
G_OUTPATH=$1
G_L="-------------------------------------------------------------------------------"
for V in *.m2v; do
F="${V%.*}"
echo ${G_L}
echo Working on ${F}...
echo Working on ${G_OUTPATH}${F}...
echo ${G_L}
if [[ -f ${F}.mkv ]]; then
rm ${F}.mkv
if [[ ! -f ${G_OUTPATH}${F}.mkv ]]; then
if [[ -f ${F}.ogg ]]; then
ffmpeg -hide_banner -loglevel error -stats -i ${F}.m2v -i ${F}.ogg -c:v libx264 -c:a aac -strict experimental ${G_OUTPATH}${F}.mkv
else
ffmpeg -hide_banner -loglevel error -stats -f lavfi -i anullsrc=channel_layout=stereo:sample_rate=44100 -i ${F}.m2v -shortest -c:v libx264 -c:a aac -strict experimental ${G_OUTPATH}${F}.mkv
fi
fi
ffmpeg -i ${F}.m2v -i ${F}.ogg -c:v libx264 -c:a copy -strict experimental ${F}.mkv
done

View file

@ -288,7 +288,7 @@ SCANCODE = {
SCANCODE_MIN = 4 -- Lowest value
SCANCODE_MAX = 286 -- Highest value, not the number of items in the table.
GAMEPAD_1 = {
GAMEPAD_0 = {
AXIS_LEFT_X = { name = "AXIS_LEFT_X", value = 500 },
AXIS_LEFT_X_L = { name = "AXIS_LEFT_X_L", value = 501 },
AXIS_LEFT_X_R = { name = "AXIS_LEFT_X_R", value = 502 },
@ -324,27 +324,27 @@ GAMEPAD_1 = {
DPAD_RIGHT = { name = "DPAD_RIGHT", value = 532 }
}
GAMEPAD_1_MIN = 500 -- Lowest value
GAMEPAD_1_MAX = 532 -- Highest value, not the number of items in the table.
GAMEPAD_0_MIN = 500 -- Lowest value
GAMEPAD_0_MAX = 532 -- Highest value, not the number of items in the table.
GAMEPAD_2 = deepcopy(GAMEPAD_1)
GAMEPAD_3 = deepcopy(GAMEPAD_1)
GAMEPAD_4 = deepcopy(GAMEPAD_1)
GAMEPAD_1 = deepcopy(GAMEPAD_0)
GAMEPAD_2 = deepcopy(GAMEPAD_0)
GAMEPAD_3 = deepcopy(GAMEPAD_0)
for key, value in pairs(GAMEPAD_1) do
GAMEPAD_2[key].value = GAMEPAD_2[key].value + 100
GAMEPAD_3[key].value = GAMEPAD_3[key].value + 200
GAMEPAD_4[key].value = GAMEPAD_4[key].value + 300
for key, value in pairs(GAMEPAD_0) do
GAMEPAD_1[key].value = GAMEPAD_1[key].value + 100
GAMEPAD_2[key].value = GAMEPAD_2[key].value + 200
GAMEPAD_3[key].value = GAMEPAD_3[key].value + 300
end
GAMEPAD_2_MIN = GAMEPAD_1_MAX + 100
GAMEPAD_2_MAX = GAMEPAD_1_MAX + 100
GAMEPAD_1_MIN = GAMEPAD_0_MAX + 100
GAMEPAD_1_MAX = GAMEPAD_0_MAX + 100
GAMEPAD_3_MIN = GAMEPAD_1_MAX + 200
GAMEPAD_3_MAX = GAMEPAD_1_MAX + 200
GAMEPAD_2_MIN = GAMEPAD_0_MAX + 200
GAMEPAD_2_MAX = GAMEPAD_0_MAX + 200
GAMEPAD_4_MIN = GAMEPAD_1_MAX + 300
GAMEPAD_4_MAX = GAMEPAD_1_MAX + 300
GAMEPAD_3_MIN = GAMEPAD_0_MAX + 300
GAMEPAD_3_MAX = GAMEPAD_0_MAX + 300
GAMEPAD_AXIS_LEFT_X = 0
GAMEPAD_AXIS_LEFT_Y = 1
@ -353,7 +353,7 @@ GAMEPAD_AXIS_RIGHT_Y = 3
GAMEPAD_AXIS_LEFT_TRIGGER = 4
GAMEPAD_AXIS_RIGHT_TRIGGER = 5
MOUSE_1 = {
MOUSE_0 = {
BUTTON_LEFT = { name = "BUTTON_LEFT", value = 1000 },
BUTTON_RIGHT = { name = "BUTTON_RIGHT", value = 1001 },
BUTTON_MIDDLE = { name = "BUTTON_MIDDLE", value = 1002 },
@ -363,27 +363,27 @@ MOUSE_1 = {
WHEEL_DOWN = { name = "WHEEL_DOWN", value = 1006 }
}
MOUSE_1_MIN = 1000
MOUSE_1_MAX = 1006
MOUSE_0_MIN = 1000
MOUSE_0_MAX = 1006
MOUSE_2 = deepcopy(MOUSE_1)
MOUSE_3 = deepcopy(MOUSE_1)
MOUSE_4 = deepcopy(MOUSE_1)
MOUSE_1 = deepcopy(MOUSE_0)
MOUSE_2 = deepcopy(MOUSE_0)
MOUSE_3 = deepcopy(MOUSE_0)
for key, value in pairs(MOUSE_1) do
MOUSE_2[key].value = MOUSE_2[key].value + 100
MOUSE_3[key].value = MOUSE_3[key].value + 200
MOUSE_4[key].value = MOUSE_4[key].value + 300
for key, value in pairs(MOUSE_0) do
MOUSE_1[key].value = MOUSE_1[key].value + 100
MOUSE_2[key].value = MOUSE_2[key].value + 200
MOUSE_3[key].value = MOUSE_3[key].value + 300
end
MOUSE_2_MIN = MOUSE_1_MAX + 100
MOUSE_2_MAX = MOUSE_1_MAX + 100
MOUSE_1_MIN = MOUSE_0_MAX + 100
MOUSE_1_MAX = MOUSE_0_MAX + 100
MOUSE_3_MIN = MOUSE_1_MAX + 200
MOUSE_3_MAX = MOUSE_1_MAX + 200
MOUSE_2_MIN = MOUSE_0_MAX + 200
MOUSE_2_MAX = MOUSE_0_MAX + 200
MOUSE_4_MIN = MOUSE_1_MAX + 300
MOUSE_4_MAX = MOUSE_1_MAX + 300
MOUSE_3_MIN = MOUSE_0_MAX + 300
MOUSE_3_MAX = MOUSE_0_MAX + 300
SWITCH_BUTTON4 = 21
SWITCH_TILT = 22

View file

@ -2,27 +2,27 @@
DEAD_ZONE = 8000
INPUT_UP = { SCANCODE.UP, SCANCODE.KP_8, GAMEPAD_1.AXIS_LEFT_Y_U, GAMEPAD_1.AXIS_RIGHT_Y_U, GAMEPAD_1.DPAD_UP }
INPUT_LEFT = { SCANCODE.LEFT, SCANCODE.KP_4, GAMEPAD_1.AXIS_LEFT_X_L, GAMEPAD_1.AXIS_RIGHT_X_L, GAMEPAD_1.DPAD_LEFT }
INPUT_DOWN = { SCANCODE.DOWN, SCANCODE.KP_2, GAMEPAD_1.AXIS_LEFT_Y_D, GAMEPAD_1.AXIS_RIGHT_Y_D, GAMEPAD_1.DPAD_DOWN }
INPUT_RIGHT = { SCANCODE.RIGHT, SCANCODE.KP_6, GAMEPAD_1.AXIS_LEFT_X_R, GAMEPAD_1.AXIS_RIGHT_X_R, GAMEPAD_1.DPAD_RIGHT }
INPUT_1P_COIN = { SCANCODE.MAIN_5, SCANCODE.C, GAMEPAD_1.BUTTON_LEFT_BUMPER }
INPUT_UP = { SCANCODE.UP, SCANCODE.KP_8, GAMEPAD_0.AXIS_LEFT_Y_U, GAMEPAD_0.AXIS_RIGHT_Y_U, GAMEPAD_0.DPAD_UP }
INPUT_LEFT = { SCANCODE.LEFT, SCANCODE.KP_4, GAMEPAD_0.AXIS_LEFT_X_L, GAMEPAD_0.AXIS_RIGHT_X_L, GAMEPAD_0.DPAD_LEFT }
INPUT_DOWN = { SCANCODE.DOWN, SCANCODE.KP_2, GAMEPAD_0.AXIS_LEFT_Y_D, GAMEPAD_0.AXIS_RIGHT_Y_D, GAMEPAD_0.DPAD_DOWN }
INPUT_RIGHT = { SCANCODE.RIGHT, SCANCODE.KP_6, GAMEPAD_0.AXIS_LEFT_X_R, GAMEPAD_0.AXIS_RIGHT_X_R, GAMEPAD_0.DPAD_RIGHT }
INPUT_1P_COIN = { SCANCODE.MAIN_5, SCANCODE.C, GAMEPAD_0.BUTTON_LEFT_BUMPER }
INPUT_2P_COIN = { SCANCODE.MAIN_6 }
INPUT_1P_START = { SCANCODE.MAIN_1, GAMEPAD_1.BUTTON_RIGHT_BUMPER }
INPUT_1P_START = { SCANCODE.MAIN_1, GAMEPAD_0.BUTTON_RIGHT_BUMPER }
INPUT_2P_START = { SCANCODE.MAIN_2 }
INPUT_ACTION_1 = { SCANCODE.SPACE, SCANCODE.LCTRL, GAMEPAD_1.BUTTON_A, MOUSE_1.BUTTON_LEFT }
INPUT_ACTION_2 = { SCANCODE.LALT, GAMEPAD_1.BUTTON_B, MOUSE_1.BUTTON_RIGHT }
INPUT_ACTION_3 = { SCANCODE.LSHIFT, GAMEPAD_1.BUTTON_X, MOUSE_1.BUTTON_MIDDLE }
INPUT_ACTION_4 = { SCANCODE.RSHIFT, GAMEPAD_1.BUTTON_Y, MOUSE_1.BUTTON_X1 }
INPUT_ACTION_1 = { SCANCODE.SPACE, SCANCODE.LCTRL, GAMEPAD_0.BUTTON_A, MOUSE_0.BUTTON_RIGHT }
INPUT_ACTION_2 = { SCANCODE.LALT, GAMEPAD_0.BUTTON_B, MOUSE_0.BUTTON_MIDDLE }
INPUT_ACTION_3 = { SCANCODE.LSHIFT, GAMEPAD_0.BUTTON_X, MOUSE_0.BUTTON_LEFT }
INPUT_ACTION_4 = { SCANCODE.RSHIFT, GAMEPAD_0.BUTTON_Y, MOUSE_0.BUTTON_X1 }
INPUT_SKILL_EASY = { SCANCODE.KP_DIVIDE }
INPUT_SKILL_MEDIUM = { SCANCODE.KP_MULTIPLY }
INPUT_SKILL_HARD = { SCANCODE.KP_MINUS }
INPUT_SERVICE = { SCANCODE.MAIN_9 }
INPUT_TEST_MODE = { SCANCODE.F2 }
INPUT_RESET_CPU = { SCANCODE.F3 }
INPUT_SCREENSHOT = { SCANCODE.F12, SCANCODE.F11, GAMEPAD_1.BUTTON_BACK }
INPUT_SCREENSHOT = { SCANCODE.F12, SCANCODE.F11, GAMEPAD_0.BUTTON_BACK }
INPUT_QUIT = { SCANCODE.ESCAPE, SCANCODE.Q }
INPUT_PAUSE = { SCANCODE.P, GAMEPAD_1.BUTTON_START }
INPUT_PAUSE = { SCANCODE.P, GAMEPAD_0.BUTTON_START }
INPUT_CONSOLE = { SCANCODE.GRAVE }
INPUT_TILT = { SCANCODE.T }
INPUT_GRAB = { SCANCODE.G }

View file

@ -240,16 +240,15 @@ int32_t frameFileSeek(int32_t frameFileHandle, int64_t seekFrame, int32_t *video
// Search through loaded video segments
/*
// Daphne-like framefile searching
found = f->count - 1;
for (i=f->count - 1; i>=0; i--) {
if (seekFrame <= f->files[i].frame) {
found = 0;
for (i=0; i<f->count; i++) {
if (seekFrame >= f->files[i].frame) {
found = i;
}
}
*/
/*
// Strict framefile searching
for (i=0; i<f->count; i++) {
if ((seekFrame >= f->files[i].frame) && (seekFrame <= (f->files[i].frame + videoGetFrameCount(f->files[i].videoHandle)))) {
@ -257,6 +256,7 @@ int32_t frameFileSeek(int32_t frameFileHandle, int64_t seekFrame, int32_t *video
break;
}
}
*/
if (found >= 0) {
// Frame is in this video

View file

@ -61,11 +61,11 @@ typedef struct ModeS {
} ModeT;
void extractFile(char *filename, unsigned char *data, int32_t length);
bool extractFile(char *filename, unsigned char *data, int32_t length);
void showUsage(char *name, char *message);
void extractFile(char *filename, unsigned char *data, int32_t length) {
bool extractFile(char *filename, unsigned char *data, int32_t length) {
FILE *out;
if (!utilFileExists(filename)) {
@ -73,14 +73,21 @@ void extractFile(char *filename, unsigned char *data, int32_t length) {
if (!out) utilDie("Unable to create %s", filename);
fwrite(data, length, 1, out);
fclose(out);
utilSay("Created File: %s", filename);
return true;
}
return false;
}
__attribute__((noreturn))
void showUsage(char *name, char *message) {
char *temp = NULL;
int32_t result = 0;
char *temp = NULL;
bool created = false;
int32_t result = 0;
utilRedirectConsole();
// 00000000011111111112222222222333333333344444444445555555555666666666677777777778
// 12345678901234567890123456789012345678901234567890123456789012345678901234567890
@ -98,9 +105,9 @@ void showUsage(char *name, char *message) {
utilSay(" -f, --fullscreen run in full screen mode");
utilSay(" -g, --sindengun=PARAMS enable Sinden Light Gun support");
utilSay(" -h, --help this display");
utilSay(" -k, --nologos kill the splash screens");
utilSay(" -l, --volume_vldp=PERCENT specify laserdisc volume in percent");
utilSay(" -m, --nomouse disable mouse");
//utilSay(" -n, --noserversend do not send usage statistics");
utilSay(" -o, --scalefactor=PERCENT reduce screen size for overscan compensation");
utilSay(" -s, --nosound, --mutesound mutes all sound");
utilSay(" -t, --trace trace script execution to screen and file");
@ -109,26 +116,29 @@ void showUsage(char *name, char *message) {
utilSay(" -w, --fullscreen_window run in windowed full screen mode");
utilSay(" -x, --xresolution=VALUE specify horizontal resolution");
utilSay(" -y, --yresolution=VALUE specify vertical resolution");
utilSay(" -z, --noconsole zero console output, no splash screens");
utilSay(" -z, --noconsole zero console output");
utilSay("");
if (message) {
utilSay("Error: %s", message);
utilSay("");
result = 1;
}
// Extract any missing support files. We do this here so they're not generated if launched from a front end.
if (!utilPathExists("Singe")) utilMkDirP("Singe", 0777);
// Singe/Framework.singe
temp = utilCreateString("Singe%cFramework.singe", utilGetPathSeparator());
extractFile(temp, Framework_singe, Framework_singe_len);
created |= extractFile(temp, Framework_singe, Framework_singe_len);
free(temp);
// Singe/controls.cfg.example
temp = utilCreateString("Singe%ccontrols.cfg.example", utilGetPathSeparator());
extractFile(temp, controls_cfg, controls_cfg_len);
created |= extractFile(temp, controls_cfg, controls_cfg_len);
free(temp);
temp = NULL;
if (created) utilSay("");
if (message) {
utilSay("Error: %s", message);
utilSay("");
result = 1;
}
#ifdef _WIN32
getchar();
#endif
@ -170,9 +180,9 @@ int main(int argc, char *argv[]) {
{ 'f', "fullscreen", ap_no },
{ 'g', "sindengun", ap_yes },
{ 'h', "help", ap_no },
{ 'k', "nologos", ap_no },
{ 'l', "volume_vldp", ap_yes },
{ 'm', "nomouse", ap_no },
// { 'n', "noserversend", ap_no },
{ 'o', "scalefactor", ap_yes },
{ 's', "nosound", ap_no },
{ 't', "trace", ap_no },
@ -215,9 +225,6 @@ int main(int argc, char *argv[]) {
exeName = (char *)argv[0];
// For that dumb OS
utilRedirectConsole();
if (!ap_init(&parser, argc, cargv, options, 0)) {
utilDie("Out of memory parsing arguments.");
}
@ -278,6 +285,11 @@ int main(int argc, char *argv[]) {
showUsage(exeName, NULL);
break;
// No Logos
case 'k':
_confNoLogos = true;
break;
// Video Volume
case 'l':
_confVolumeVldp = atoi(arg);
@ -289,11 +301,6 @@ int main(int argc, char *argv[]) {
_confNoMouse = true;
break;
// No Server Statss
case 'n':
_confNoStats = true;
break;
// Overscan Zoom
case 'o':
_confScaleFactor = atoi(arg);
@ -350,6 +357,9 @@ int main(int argc, char *argv[]) {
}
}
// For that dumb OS
if (!_confNoConsole) utilRedirectConsole();
// Did we get a filename or path to open?
if ((argc - argCount) != 1) showUsage(exeName, "No script file specified.");
_confScriptFile = strdup(argv[argCount]);

View file

@ -21,10 +21,11 @@
if [[ -z $1 ]]; then
G_PLATFORM=mac
G_PLATFORM=pi
# G_PLATFORM=mac
# G_PLATFORM=mingw
# G_PLATFORM=linux
G_BITS=64
G_BITS=32
G_THIRDPARTY=$(pwd)/thirdparty
G_DEST="$(pwd)/../thirdparty-build/${G_PLATFORM}/${G_BITS}"
G_TYPE=static

View file

@ -159,12 +159,12 @@ char *_confDataDir = NULL;
bool _confIsFrameFile = false;
bool _confStretchVideo = false;
bool _confNoMouse = false;
bool _confNoStats = false;
bool _confNoSound = false;
bool _confFullScreen = false;
bool _confFullScreenWindow = false;
bool _confShowCalculated = false;
bool _confNoConsole = false;
bool _confNoLogos = false;
int32_t _confVolumeVldp = 100;
int32_t _confVolumeNonVldp = 100;
int32_t _confScaleFactor = 100;
@ -1014,8 +1014,8 @@ int32_t apiOverlayPrint(lua_State *L) {
src.y = 0;
src.w = _consoleFontWidth;
src.h = _consoleFontHeight;
dst.x = lua_tonumber(L, 1);
dst.y = lua_tonumber(L, 2);
dst.x = lua_tonumber(L, 1) * _consoleFontWidth;
dst.y = lua_tonumber(L, 2) * _consoleFontHeight;
dst.w = _consoleFontWidth;
dst.h = _consoleFontHeight;
s = (char *)lua_tostring(L, 3);
@ -2186,7 +2186,7 @@ void processKey(bool down, int32_t keysym, int32_t scancode) {
for (index=0; index<_controlMappings[move].inputCount; index++) {
//utilSay("Checking %s %d = %d", _controlMappings[move].name, _controlMappings[move].input[index], scancode);
if (_controlMappings[move].input[index] == scancode) {
//utilSay("Found %s %d", _controlMappings[move].name, _controlMappings[move].input[index]);
//utilSay("Sending move %d - %s %d - %s", move, _controlMappings[move].name, _controlMappings[move].input[index], down ? "down" : "up");
if (!down) {
if ((move == INPUT_PAUSE) && (_pauseEnabled)) {
//***TODO*** g_game->toggle_game_pause();
@ -2232,6 +2232,7 @@ void singe(SDL_Window *window, SDL_Renderer *renderer) {
int32_t intReturn = 0;
int64_t thisFrame = -1;
int64_t lastFrame = -1;
uint32_t frameClock = 0;
char *temp = NULL;
char *temp2 = NULL;
SDL_Rect windowTarget;
@ -2329,7 +2330,7 @@ void singe(SDL_Window *window, SDL_Renderer *renderer) {
lua_close(_luaContext);
// Show splash screens
if (!_confNoConsole) {
if (!_confNoLogos) {
doLogos();
}
@ -2788,9 +2789,12 @@ void singe(SDL_Window *window, SDL_Renderer *renderer) {
}
// Call game code
callLua("onOverlayUpdate", ">i", &intReturn);
if (intReturn == 1) {
_refreshDisplay = true;
if (SDL_GetTicks() > frameClock) {
callLua("onOverlayUpdate", ">i", &intReturn);
if (intReturn == 1) {
_refreshDisplay = true;
}
frameClock = SDL_GetTicks() + 15; // Don't eat all the CPU.
}
// Update video
@ -2847,6 +2851,8 @@ void singe(SDL_Window *window, SDL_Renderer *renderer) {
takeScreenshot();
}
}
SDL_Delay(1);
}
// End game

View file

@ -31,7 +31,7 @@
// Don't forget to update singe.rc!
#define SINGE_VERSION 2.00
#define VERSION_STRING "v2.00b10"
#define VERSION_STRING "v2.00b11"
#define COPYRIGHT_END_YEAR "2020"
@ -52,12 +52,12 @@ extern char *_confDataDir;
extern bool _confIsFrameFile;
extern bool _confStretchVideo;
extern bool _confNoMouse;
extern bool _confNoStats;
extern bool _confNoSound;
extern bool _confFullScreen;
extern bool _confFullScreenWindow;
extern bool _confShowCalculated;
extern bool _confNoConsole;
extern bool _confNoLogos;
extern int32_t _confVolumeVldp;
extern int32_t _confVolumeNonVldp;
extern int32_t _confScaleFactor;

View file

@ -1,7 +1,7 @@
101 ICON "/tmp/icon.ico"
1 VERSIONINFO
FILEVERSION 2,0,0,10
PRODUCTVERSION 2,0,0,10
FILEVERSION 2,0,0,11
PRODUCTVERSION 2,0,0,11
BEGIN
BLOCK "StringFileInfo"
BEGIN
@ -9,12 +9,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Kangaroo Punch Studios"
VALUE "FileDescription", "Somewhat Interactive Nostalgic Game Engine"
VALUE "FileVersion", "2.00b10"
VALUE "FileVersion", "2.00b11"
VALUE "InternalName", "Singe"
VALUE "LegalCopyright", "Copyright 2006-2020 Scott C. Duensing"
VALUE "OriginalFilename", "singe.exe"
VALUE "ProductName", "Singe"
VALUE "ProductVersion", "2.00b10"
VALUE "ProductVersion", "2.00b11"
END
END
BLOCK "VarFileInfo"

View file

@ -331,35 +331,40 @@ void utilRedirectConsole(void) {
intptr_t lStdHandle;
CONSOLE_SCREEN_BUFFER_INFO coninfo;
FILE *fp;
static bool consoleOpen = false;
// allocate a console for this app
AllocConsole();
if (!consoleOpen) {
consoleOpen = true;
// set the screen buffer to be big enough to let us scroll text
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
coninfo.dwSize.Y = CONSOLE_LINES;
SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
// allocate a console for this app
AllocConsole();
// redirect unbuffered STDOUT to the console
lStdHandle = (intptr_t)GetStdHandle(STD_OUTPUT_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen(hConHandle, "w");
*stdout = *fp;
setvbuf(stdout, NULL, _IONBF, 0);
// set the screen buffer to be big enough to let us scroll text
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
coninfo.dwSize.Y = CONSOLE_LINES;
SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
// redirect unbuffered STDIN to the console
lStdHandle = (intptr_t)GetStdHandle(STD_INPUT_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen(hConHandle, "r");
*stdin = *fp;
setvbuf(stdin, NULL, _IONBF, 0);
// redirect unbuffered STDOUT to the console
lStdHandle = (intptr_t)GetStdHandle(STD_OUTPUT_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen(hConHandle, "w");
*stdout = *fp;
setvbuf(stdout, NULL, _IONBF, 0);
// redirect unbuffered STDERR to the console
lStdHandle = (intptr_t)GetStdHandle(STD_ERROR_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen(hConHandle, "w");
*stderr = *fp;
setvbuf(stderr, NULL, _IONBF, 0);
// redirect unbuffered STDIN to the console
lStdHandle = (intptr_t)GetStdHandle(STD_INPUT_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen(hConHandle, "r");
*stdin = *fp;
setvbuf(stdin, NULL, _IONBF, 0);
// redirect unbuffered STDERR to the console
lStdHandle = (intptr_t)GetStdHandle(STD_ERROR_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen(hConHandle, "w");
*stderr = *fp;
setvbuf(stderr, NULL, _IONBF, 0);
}
#endif
}