cmake cleanup in library/
parent
83b190b5d8
commit
fd418cd2dc
@ -1,536 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
/**
|
|
||||||
* File: rlutil.h
|
|
||||||
*
|
|
||||||
* About: Description
|
|
||||||
* This file provides some useful utilities for console mode
|
|
||||||
* roguelike game development with C and C++. It is aimed to
|
|
||||||
* be cross-platform (at least Windows and Linux).
|
|
||||||
*
|
|
||||||
* About: Copyright
|
|
||||||
* (C) 2011 The united church of gotoxy.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/// Define: RLUTIL_USE_ANSI
|
|
||||||
/// Define this to use ANSI escape sequences also on Windows
|
|
||||||
/// (defaults to using WinAPI instead).
|
|
||||||
#if 0
|
|
||||||
#define RLUTIL_USE_ANSI
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// Define: RLUTIL_STRING_T
|
|
||||||
/// Define/typedef this to your preference to override rlutil's string type.
|
|
||||||
///
|
|
||||||
/// Defaults to std::string with C++ and char* with C.
|
|
||||||
#if 0
|
|
||||||
#define RLUTIL_STRING_T char*
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
/// Common C++ headers
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
#include <sstream>
|
|
||||||
/// Namespace forward declarations
|
|
||||||
namespace rlutil
|
|
||||||
{
|
|
||||||
void locate(int x, int y);
|
|
||||||
}
|
|
||||||
#endif // __cplusplus
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
#include <windows.h> // for WinAPI and Sleep()
|
|
||||||
#include <conio.h> // for getch() and kbhit()
|
|
||||||
#else
|
|
||||||
#ifdef __cplusplus
|
|
||||||
#include <cstdio> // for getch()
|
|
||||||
#else // __cplusplus
|
|
||||||
#include <stdio.h> // for getch()
|
|
||||||
#endif // __cplusplus
|
|
||||||
#include <termios.h> // for getch() and kbhit()
|
|
||||||
#include <unistd.h> // for getch(), kbhit() and (u)sleep()
|
|
||||||
#include <sys/ioctl.h> // for getkey()
|
|
||||||
#include <sys/types.h> // for kbhit()
|
|
||||||
#include <sys/time.h> // for kbhit()
|
|
||||||
|
|
||||||
/// Function: getch
|
|
||||||
/// Get character without waiting for Return to be pressed.
|
|
||||||
/// Windows has this in conio.h
|
|
||||||
int getch()
|
|
||||||
{
|
|
||||||
// Here be magic.
|
|
||||||
struct termios oldt, newt;
|
|
||||||
int ch;
|
|
||||||
tcgetattr(STDIN_FILENO, &oldt);
|
|
||||||
newt = oldt;
|
|
||||||
newt.c_lflag &= ~(ICANON | ECHO);
|
|
||||||
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
|
|
||||||
ch = getchar();
|
|
||||||
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
|
|
||||||
return ch;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Function: kbhit
|
|
||||||
/// Determines if keyboard has been hit.
|
|
||||||
/// Windows has this in conio.h
|
|
||||||
int kbhit()
|
|
||||||
{
|
|
||||||
// Here be dragons.
|
|
||||||
static struct termios oldt, newt;
|
|
||||||
int cnt = 0;
|
|
||||||
tcgetattr(STDIN_FILENO, &oldt);
|
|
||||||
newt = oldt;
|
|
||||||
newt.c_lflag &= ~(ICANON | ECHO);
|
|
||||||
newt.c_iflag = 0; // input mode
|
|
||||||
newt.c_oflag = 0; // output mode
|
|
||||||
newt.c_cc[VMIN] = 1; // minimum time to wait
|
|
||||||
newt.c_cc[VTIME] = 1; // minimum characters to wait for
|
|
||||||
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
|
|
||||||
ioctl(0, FIONREAD, &cnt); // Read count
|
|
||||||
struct timeval tv;
|
|
||||||
tv.tv_sec = 0;
|
|
||||||
tv.tv_usec = 100;
|
|
||||||
select(STDIN_FILENO+1, NULL, NULL, NULL, &tv); // A small time delay
|
|
||||||
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
|
|
||||||
return cnt; // Return number of characters
|
|
||||||
}
|
|
||||||
#endif // WIN32
|
|
||||||
|
|
||||||
#ifndef gotoxy
|
|
||||||
/// Function: gotoxy
|
|
||||||
/// Same as <rlutil.locate>.
|
|
||||||
void inline gotoxy(int x, int y) {
|
|
||||||
#ifdef __cplusplus
|
|
||||||
rlutil::
|
|
||||||
#endif
|
|
||||||
locate(x,y);
|
|
||||||
}
|
|
||||||
#endif // gotoxy
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
/// Namespace: rlutil
|
|
||||||
/// In C++ all functions except <getch>, <kbhit> and <gotoxy> are arranged
|
|
||||||
/// under namespace rlutil. That is because some platforms have them defined
|
|
||||||
/// outside of rlutil.
|
|
||||||
namespace rlutil {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Defs: Internal typedefs and macros
|
|
||||||
* RLUTIL_STRING_T - String type depending on which one of C or C++ is used
|
|
||||||
* RLUTIL_PRINT(str) - Printing macro independent of C/C++
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
#ifndef RLUTIL_STRING_T
|
|
||||||
typedef std::string RLUTIL_STRING_T;
|
|
||||||
#endif // RLUTIL_STRING_T
|
|
||||||
|
|
||||||
void inline RLUTIL_PRINT(RLUTIL_STRING_T st) { std::cout << st; }
|
|
||||||
|
|
||||||
#else // __cplusplus
|
|
||||||
#ifndef RLUTIL_STRING_T
|
|
||||||
typedef char* RLUTIL_STRING_T;
|
|
||||||
#endif // RLUTIL_STRING_T
|
|
||||||
|
|
||||||
#define RLUTIL_PRINT(st) printf("%s", st)
|
|
||||||
#endif // __cplusplus
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enums: Color codes
|
|
||||||
*
|
|
||||||
* BLACK - Black
|
|
||||||
* RED - Red
|
|
||||||
* GREEN - Green
|
|
||||||
* BROWN - Brown / dark yellow
|
|
||||||
* BLUE - Blue
|
|
||||||
* MAGENTA - Magenta / purple
|
|
||||||
* CYAN - Cyan
|
|
||||||
* GREY - Grey / dark white
|
|
||||||
* DARKGREY - Dark grey / light black
|
|
||||||
* LIGHTRED - Light red
|
|
||||||
* LIGHTGREEN - Light green
|
|
||||||
* YELLOW - Yellow (bright)
|
|
||||||
* LIGHTBLUE - Light blue
|
|
||||||
* LIGHTMAGENTA - Light magenta / light purple
|
|
||||||
* LIGHTCYAN - Light cyan
|
|
||||||
* WHITE - White (bright)
|
|
||||||
*/
|
|
||||||
enum {
|
|
||||||
BLACK,
|
|
||||||
RED,
|
|
||||||
GREEN,
|
|
||||||
BROWN,
|
|
||||||
BLUE,
|
|
||||||
MAGENTA,
|
|
||||||
CYAN,
|
|
||||||
GREY,
|
|
||||||
DARKGREY,
|
|
||||||
LIGHTRED,
|
|
||||||
LIGHTGREEN,
|
|
||||||
YELLOW,
|
|
||||||
LIGHTBLUE,
|
|
||||||
LIGHTMAGENTA,
|
|
||||||
LIGHTCYAN,
|
|
||||||
WHITE
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Consts: ANSI color strings
|
|
||||||
*
|
|
||||||
* ANSI_CLS - Clears screen
|
|
||||||
* ANSI_BLACK - Black
|
|
||||||
* ANSI_RED - Red
|
|
||||||
* ANSI_GREEN - Green
|
|
||||||
* ANSI_BROWN - Brown / dark yellow
|
|
||||||
* ANSI_BLUE - Blue
|
|
||||||
* ANSI_MAGENTA - Magenta / purple
|
|
||||||
* ANSI_CYAN - Cyan
|
|
||||||
* ANSI_GREY - Grey / dark white
|
|
||||||
* ANSI_DARKGREY - Dark grey / light black
|
|
||||||
* ANSI_LIGHTRED - Light red
|
|
||||||
* ANSI_LIGHTGREEN - Light green
|
|
||||||
* ANSI_YELLOW - Yellow (bright)
|
|
||||||
* ANSI_LIGHTBLUE - Light blue
|
|
||||||
* ANSI_LIGHTMAGENTA - Light magenta / light purple
|
|
||||||
* ANSI_LIGHTCYAN - Light cyan
|
|
||||||
* ANSI_WHITE - White (bright)
|
|
||||||
*/
|
|
||||||
const RLUTIL_STRING_T ANSI_CLS = "\033[2J";
|
|
||||||
const RLUTIL_STRING_T ANSI_BLACK = "\033[22;30m";
|
|
||||||
const RLUTIL_STRING_T ANSI_RED = "\033[22;31m";
|
|
||||||
const RLUTIL_STRING_T ANSI_GREEN = "\033[22;32m";
|
|
||||||
const RLUTIL_STRING_T ANSI_BROWN = "\033[22;33m";
|
|
||||||
const RLUTIL_STRING_T ANSI_BLUE = "\033[22;34m";
|
|
||||||
const RLUTIL_STRING_T ANSI_MAGENTA = "\033[22;35m";
|
|
||||||
const RLUTIL_STRING_T ANSI_CYAN = "\033[22;36m";
|
|
||||||
const RLUTIL_STRING_T ANSI_GREY = "\033[22;37m";
|
|
||||||
const RLUTIL_STRING_T ANSI_DARKGREY = "\033[01;30m";
|
|
||||||
const RLUTIL_STRING_T ANSI_LIGHTRED = "\033[01;31m";
|
|
||||||
const RLUTIL_STRING_T ANSI_LIGHTGREEN = "\033[01;32m";
|
|
||||||
const RLUTIL_STRING_T ANSI_YELLOW = "\033[01;33m";
|
|
||||||
const RLUTIL_STRING_T ANSI_LIGHTBLUE = "\033[01;34m";
|
|
||||||
const RLUTIL_STRING_T ANSI_LIGHTMAGENTA = "\033[01;35m";
|
|
||||||
const RLUTIL_STRING_T ANSI_LIGHTCYAN = "\033[01;36m";
|
|
||||||
const RLUTIL_STRING_T ANSI_WHITE = "\033[01;37m";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Consts: Key codes for keyhit()
|
|
||||||
*
|
|
||||||
* KEY_ESCAPE - Escape
|
|
||||||
* KEY_ENTER - Enter
|
|
||||||
* KEY_SPACE - Space
|
|
||||||
* KEY_INSERT - Insert
|
|
||||||
* KEY_HOME - Home
|
|
||||||
* KEY_END - End
|
|
||||||
* KEY_DELETE - Delete
|
|
||||||
* KEY_PGUP - PageUp
|
|
||||||
* KEY_PGDOWN - PageDown
|
|
||||||
* KEY_UP - Up arrow
|
|
||||||
* KEY_DOWN - Down arrow
|
|
||||||
* KEY_LEFT - Left arrow
|
|
||||||
* KEY_RIGHT - Right arrow
|
|
||||||
* KEY_F1 - F1
|
|
||||||
* KEY_F2 - F2
|
|
||||||
* KEY_F3 - F3
|
|
||||||
* KEY_F4 - F4
|
|
||||||
* KEY_F5 - F5
|
|
||||||
* KEY_F6 - F6
|
|
||||||
* KEY_F7 - F7
|
|
||||||
* KEY_F8 - F8
|
|
||||||
* KEY_F9 - F9
|
|
||||||
* KEY_F10 - F10
|
|
||||||
* KEY_F11 - F11
|
|
||||||
* KEY_F12 - F12
|
|
||||||
* KEY_NUMDEL - Numpad del
|
|
||||||
* KEY_NUMPAD0 - Numpad 0
|
|
||||||
* KEY_NUMPAD1 - Numpad 1
|
|
||||||
* KEY_NUMPAD2 - Numpad 2
|
|
||||||
* KEY_NUMPAD3 - Numpad 3
|
|
||||||
* KEY_NUMPAD4 - Numpad 4
|
|
||||||
* KEY_NUMPAD5 - Numpad 5
|
|
||||||
* KEY_NUMPAD6 - Numpad 6
|
|
||||||
* KEY_NUMPAD7 - Numpad 7
|
|
||||||
* KEY_NUMPAD8 - Numpad 8
|
|
||||||
* KEY_NUMPAD9 - Numpad 9
|
|
||||||
*/
|
|
||||||
const int KEY_ESCAPE = 0;
|
|
||||||
const int KEY_ENTER = 1;
|
|
||||||
const int KEY_SPACE = 32;
|
|
||||||
|
|
||||||
const int KEY_INSERT = 2;
|
|
||||||
const int KEY_HOME = 3;
|
|
||||||
const int KEY_PGUP = 4;
|
|
||||||
const int KEY_DELETE = 5;
|
|
||||||
const int KEY_END = 6;
|
|
||||||
const int KEY_PGDOWN = 7;
|
|
||||||
|
|
||||||
const int KEY_UP = 14;
|
|
||||||
const int KEY_DOWN = 15;
|
|
||||||
const int KEY_LEFT = 16;
|
|
||||||
const int KEY_RIGHT = 17;
|
|
||||||
|
|
||||||
const int KEY_F1 = 18;
|
|
||||||
const int KEY_F2 = 19;
|
|
||||||
const int KEY_F3 = 20;
|
|
||||||
const int KEY_F4 = 21;
|
|
||||||
const int KEY_F5 = 22;
|
|
||||||
const int KEY_F6 = 23;
|
|
||||||
const int KEY_F7 = 24;
|
|
||||||
const int KEY_F8 = 25;
|
|
||||||
const int KEY_F9 = 26;
|
|
||||||
const int KEY_F10 = 27;
|
|
||||||
const int KEY_F11 = 28;
|
|
||||||
const int KEY_F12 = 29;
|
|
||||||
|
|
||||||
const int KEY_NUMDEL = 30;
|
|
||||||
const int KEY_NUMPAD0 = 31;
|
|
||||||
const int KEY_NUMPAD1 = 127;
|
|
||||||
const int KEY_NUMPAD2 = 128;
|
|
||||||
const int KEY_NUMPAD3 = 129;
|
|
||||||
const int KEY_NUMPAD4 = 130;
|
|
||||||
const int KEY_NUMPAD5 = 131;
|
|
||||||
const int KEY_NUMPAD6 = 132;
|
|
||||||
const int KEY_NUMPAD7 = 133;
|
|
||||||
const int KEY_NUMPAD8 = 134;
|
|
||||||
const int KEY_NUMPAD9 = 135;
|
|
||||||
|
|
||||||
/// Function: getkey
|
|
||||||
/// Reads a key press (blocking) and returns a key code.
|
|
||||||
///
|
|
||||||
/// See <Key codes for keyhit()>
|
|
||||||
///
|
|
||||||
/// Note:
|
|
||||||
/// Only Arrows, Esc, Enter and Space are currently working properly.
|
|
||||||
int getkey(void)
|
|
||||||
{
|
|
||||||
#ifndef WIN32
|
|
||||||
int cnt = kbhit(); // for ANSI escapes processing
|
|
||||||
#endif
|
|
||||||
int k = getch();
|
|
||||||
switch(k)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
{
|
|
||||||
int kk;
|
|
||||||
switch (kk = getch())
|
|
||||||
{
|
|
||||||
case 71: return KEY_NUMPAD7;
|
|
||||||
case 72: return KEY_NUMPAD8;
|
|
||||||
case 73: return KEY_NUMPAD9;
|
|
||||||
case 75: return KEY_NUMPAD4;
|
|
||||||
case 77: return KEY_NUMPAD6;
|
|
||||||
case 79: return KEY_NUMPAD1;
|
|
||||||
case 80: return KEY_NUMPAD4;
|
|
||||||
case 81: return KEY_NUMPAD3;
|
|
||||||
case 82: return KEY_NUMPAD0;
|
|
||||||
case 83: return KEY_NUMDEL;
|
|
||||||
default: return kk-59+KEY_F1; // Function keys
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case 224:
|
|
||||||
{
|
|
||||||
int kk;
|
|
||||||
switch (kk = getch())
|
|
||||||
{
|
|
||||||
case 71: return KEY_HOME;
|
|
||||||
case 72: return KEY_UP;
|
|
||||||
case 73: return KEY_PGUP;
|
|
||||||
case 75: return KEY_LEFT;
|
|
||||||
case 77: return KEY_RIGHT;
|
|
||||||
case 79: return KEY_END;
|
|
||||||
case 80: return KEY_DOWN;
|
|
||||||
case 81: return KEY_PGDOWN;
|
|
||||||
case 82: return KEY_INSERT;
|
|
||||||
case 83: return KEY_DELETE;
|
|
||||||
default: return kk-123+KEY_F1; // Function keys
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case 13: return KEY_ENTER;
|
|
||||||
#ifdef WIN32
|
|
||||||
case 27: return KEY_ESCAPE;
|
|
||||||
#else // WIN32
|
|
||||||
case 155: // single-character CSI
|
|
||||||
case 27:
|
|
||||||
{
|
|
||||||
// Process ANSI escape sequences
|
|
||||||
if (cnt >= 3 && getch() == '[')
|
|
||||||
{
|
|
||||||
switch (k = getch())
|
|
||||||
{
|
|
||||||
case 'A': return KEY_UP;
|
|
||||||
case 'B': return KEY_DOWN;
|
|
||||||
case 'C': return KEY_RIGHT;
|
|
||||||
case 'D': return KEY_LEFT;
|
|
||||||
}
|
|
||||||
} else return KEY_ESCAPE;
|
|
||||||
}
|
|
||||||
#endif // WIN32
|
|
||||||
default: return k;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Function: nb_getch
|
|
||||||
/// Non-blocking getch(). Returns 0 if no key was pressed.
|
|
||||||
int inline nb_getch() {
|
|
||||||
if (kbhit()) return getch();
|
|
||||||
else return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Function: getANSIColor
|
|
||||||
/// Return ANSI color escape sequence for specified number 0-15.
|
|
||||||
///
|
|
||||||
/// See <Color Codes>
|
|
||||||
RLUTIL_STRING_T getANSIColor(const int c) {
|
|
||||||
switch (c) {
|
|
||||||
case 0 : return ANSI_BLACK;
|
|
||||||
case 1 : return ANSI_BLUE; // non-ANSI
|
|
||||||
case 2 : return ANSI_GREEN;
|
|
||||||
case 3 : return ANSI_CYAN; // non-ANSI
|
|
||||||
case 4 : return ANSI_RED; // non-ANSI
|
|
||||||
case 5 : return ANSI_MAGENTA;
|
|
||||||
case 6 : return ANSI_BROWN;
|
|
||||||
case 7 : return ANSI_GREY;
|
|
||||||
case 8 : return ANSI_DARKGREY;
|
|
||||||
case 9 : return ANSI_LIGHTBLUE; // non-ANSI
|
|
||||||
case 10: return ANSI_LIGHTGREEN;
|
|
||||||
case 11: return ANSI_LIGHTCYAN; // non-ANSI;
|
|
||||||
case 12: return ANSI_LIGHTRED; // non-ANSI;
|
|
||||||
case 13: return ANSI_LIGHTMAGENTA;
|
|
||||||
case 14: return ANSI_YELLOW; // non-ANSI
|
|
||||||
case 15: return ANSI_WHITE;
|
|
||||||
default: return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Function: setColor
|
|
||||||
/// Change color specified by number (Windows / QBasic colors).
|
|
||||||
///
|
|
||||||
/// See <Color Codes>
|
|
||||||
void inline setColor(int c) {
|
|
||||||
#if defined(WIN32) && !defined(RLUTIL_USE_ANSI)
|
|
||||||
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
||||||
SetConsoleTextAttribute(hConsole, c);
|
|
||||||
#else
|
|
||||||
RLUTIL_PRINT(getANSIColor(c));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Function: cls
|
|
||||||
/// Clears screen and moves cursor home.
|
|
||||||
void inline cls() {
|
|
||||||
#if defined(WIN32) && !defined(RLUTIL_USE_ANSI)
|
|
||||||
// TODO: This is cheating...
|
|
||||||
system("cls");
|
|
||||||
#else
|
|
||||||
RLUTIL_PRINT("\033[2J\033[H");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Function: locate
|
|
||||||
/// Sets the cursor position to 1-based x,y.
|
|
||||||
void locate(int x, int y)
|
|
||||||
{
|
|
||||||
#if defined(WIN32) && !defined(RLUTIL_USE_ANSI)
|
|
||||||
COORD coord = {x-1, y-1}; // Windows uses 0-based coordinates
|
|
||||||
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
|
|
||||||
#else // WIN32 || USE_ANSI
|
|
||||||
#ifdef __cplusplus
|
|
||||||
std::ostringstream oss;
|
|
||||||
oss << "\033[" << y << ";" << x << "H";
|
|
||||||
RLUTIL_PRINT(oss.str());
|
|
||||||
#else // __cplusplus
|
|
||||||
char buf[32];
|
|
||||||
sprintf(buf, "\033[%d;%df", y, x);
|
|
||||||
RLUTIL_PRINT(buf);
|
|
||||||
#endif // __cplusplus
|
|
||||||
#endif // WIN32 || USE_ANSI
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Function: hidecursor
|
|
||||||
/// Hides the cursor.
|
|
||||||
void inline hidecursor()
|
|
||||||
{
|
|
||||||
#if defined(WIN32) && !defined(RLUTIL_USE_ANSI)
|
|
||||||
HANDLE hConsoleOutput;
|
|
||||||
CONSOLE_CURSOR_INFO structCursorInfo;
|
|
||||||
hConsoleOutput = GetStdHandle( STD_OUTPUT_HANDLE );
|
|
||||||
GetConsoleCursorInfo( hConsoleOutput, &structCursorInfo ); // Get current cursor size
|
|
||||||
structCursorInfo.bVisible = FALSE;
|
|
||||||
SetConsoleCursorInfo( hConsoleOutput, &structCursorInfo );
|
|
||||||
#else // WIN32 || USE_ANSI
|
|
||||||
RLUTIL_PRINT("\033[?25l");
|
|
||||||
#endif // WIN32 || USE_ANSI
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Function: showcursor
|
|
||||||
/// Shows the cursor.
|
|
||||||
void inline showcursor() {
|
|
||||||
#if defined(WIN32) && !defined(RLUTIL_USE_ANSI)
|
|
||||||
HANDLE hConsoleOutput;
|
|
||||||
CONSOLE_CURSOR_INFO structCursorInfo;
|
|
||||||
hConsoleOutput = GetStdHandle( STD_OUTPUT_HANDLE );
|
|
||||||
GetConsoleCursorInfo( hConsoleOutput, &structCursorInfo ); // Get current cursor size
|
|
||||||
structCursorInfo.bVisible = TRUE;
|
|
||||||
SetConsoleCursorInfo( hConsoleOutput, &structCursorInfo );
|
|
||||||
#else // WIN32 || USE_ANSI
|
|
||||||
RLUTIL_PRINT("\033[?25h");
|
|
||||||
#endif // WIN32 || USE_ANSI
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Function: msleep
|
|
||||||
/// Waits given number of milliseconds before continuing.
|
|
||||||
void inline msleep(unsigned int ms) {
|
|
||||||
#ifdef WIN32
|
|
||||||
Sleep(ms);
|
|
||||||
#else
|
|
||||||
// usleep argument must be under 1 000 000
|
|
||||||
if (ms > 1000) sleep(ms/1000000);
|
|
||||||
usleep((ms % 1000000) * 1000);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Allow optional message for anykey()?
|
|
||||||
|
|
||||||
/// Function: anykey
|
|
||||||
/// Waits until a key is pressed.
|
|
||||||
void inline anykey() {
|
|
||||||
getch();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef min
|
|
||||||
/// Function: min
|
|
||||||
/// Returns the lesser of the two arguments.
|
|
||||||
#ifdef __cplusplus
|
|
||||||
template <class T> const T& min ( const T& a, const T& b ) { return (a<b)?a:b; }
|
|
||||||
#else
|
|
||||||
#define min(a,b) (((a)<(b))?(a):(b))
|
|
||||||
#endif // __cplusplus
|
|
||||||
#endif // min
|
|
||||||
|
|
||||||
#ifndef max
|
|
||||||
/// Function: max
|
|
||||||
/// Returns the greater of the two arguments.
|
|
||||||
#ifdef __cplusplus
|
|
||||||
template <class T> const T& max ( const T& a, const T& b ) { return (b<a)?a:b; }
|
|
||||||
#else
|
|
||||||
#define max(a,b) (((b)<(a))?(a):(b))
|
|
||||||
#endif // __cplusplus
|
|
||||||
#endif // max
|
|
||||||
|
|
||||||
// Classes are here at the end so that documentation is pretty.
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
/// Class: CursorHider
|
|
||||||
/// RAII OOP wrapper for <rlutil.hidecursor>.
|
|
||||||
/// Hides the cursor and shows it again
|
|
||||||
/// when the object goes out of scope.
|
|
||||||
struct CursorHider {
|
|
||||||
CursorHider() { hidecursor(); }
|
|
||||||
~CursorHider() { showcursor(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace rlutil
|
|
||||||
#endif
|
|
@ -1,303 +0,0 @@
|
|||||||
// stdiostream.hpp
|
|
||||||
//
|
|
||||||
// Copyright (c) 2010 Michael Thomas Greer
|
|
||||||
// Distributed under the Boost Software License, Version 1.0
|
|
||||||
// (See http://www.boost.org/LICENSE_1_0.txt )
|
|
||||||
//
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#ifndef DUTHOMHAS_STDIOSTREAM_HPP
|
|
||||||
#define DUTHOMHAS_STDIOSTREAM_HPP
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <iostream>
|
|
||||||
#include <streambuf>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <ciso646>
|
|
||||||
|
|
||||||
namespace duthomhas
|
|
||||||
{
|
|
||||||
|
|
||||||
/* /////////////////////////////////////////////////////////////////////////
|
|
||||||
basic_stdiobuf
|
|
||||||
///////////////////////////////////////////////////////////////////////// */
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename CharType,
|
|
||||||
typename CharTraits = std::char_traits <CharType>
|
|
||||||
>
|
|
||||||
class basic_stdiobuf: public std::basic_streambuf <CharType, CharTraits>
|
|
||||||
{
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
public:
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
typedef CharType char_type;
|
|
||||||
typedef CharTraits traits_type;
|
|
||||||
typedef typename traits_type::int_type int_type;
|
|
||||||
typedef typename traits_type::pos_type pos_type;
|
|
||||||
typedef typename traits_type::off_type off_type;
|
|
||||||
|
|
||||||
typedef basic_stdiobuf <char_type, traits_type> this_type;
|
|
||||||
|
|
||||||
//......................................................................
|
|
||||||
basic_stdiobuf( FILE* fp = NULL ):
|
|
||||||
fp( fp )
|
|
||||||
{ }
|
|
||||||
|
|
||||||
//......................................................................
|
|
||||||
//BUG 1: Hey! I never get called! (How is that?)
|
|
||||||
~basic_stdiobuf()
|
|
||||||
{
|
|
||||||
this->close();
|
|
||||||
}
|
|
||||||
|
|
||||||
//......................................................................
|
|
||||||
bool is_open() const throw()
|
|
||||||
{
|
|
||||||
return fp != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
//......................................................................
|
|
||||||
this_type* open( const char* filename, std::ios_base::openmode mode )
|
|
||||||
{
|
|
||||||
if (is_open()) return NULL;
|
|
||||||
|
|
||||||
// Figure out the open mode flags . . . . . . . . . . . . . . . . . .
|
|
||||||
std::string fmode;
|
|
||||||
|
|
||||||
bool is_ate = mode & std::ios_base::ate;
|
|
||||||
bool is_bin = mode & std::ios_base::binary;
|
|
||||||
mode &= ~(std::ios_base::ate | std::ios_base::binary);
|
|
||||||
|
|
||||||
#define _(flag) std::ios_base::flag
|
|
||||||
if (mode == ( _(in) )) fmode = "r";
|
|
||||||
else if (mode == ( _(out) & _(trunc))) fmode = "w";
|
|
||||||
else if (mode == (_(app) & _(out) )) fmode = "a";
|
|
||||||
else if (mode == ( _(in) & _(out) )) fmode = "r+";
|
|
||||||
else if (mode == ( _(in) & _(out) & _(trunc))) fmode = "w+";
|
|
||||||
else if (mode == (_(app) & _(in) & _(out) )) fmode = "a+";
|
|
||||||
// I would prefer to throw an exception here,
|
|
||||||
// but the standard only wants a NULL result.
|
|
||||||
else return NULL;
|
|
||||||
#undef _
|
|
||||||
if (is_bin) fmode.insert( 1, 1, 'b' );
|
|
||||||
|
|
||||||
// Try opening the file . . . . . . . . . . . . . . . . . . . . . . .
|
|
||||||
fp = std::fopen( filename, fmode.c_str() );
|
|
||||||
if (!fp) return NULL;
|
|
||||||
|
|
||||||
// Reposition to EOF if wanted . . . . . . . . . . . . . . . . . . . .
|
|
||||||
if (is_ate) std::fseek( fp, 0, SEEK_END );
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//......................................................................
|
|
||||||
this_type* close()
|
|
||||||
{
|
|
||||||
if (fp)
|
|
||||||
{
|
|
||||||
std::fclose( fp );
|
|
||||||
fp = NULL;
|
|
||||||
}
|
|
||||||
pushbacks.clear();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//......................................................................
|
|
||||||
FILE* stdiofile() const
|
|
||||||
{
|
|
||||||
return fp;
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
protected:
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//......................................................................
|
|
||||||
// Get the CURRENT character without advancing the file pointer
|
|
||||||
virtual int_type underflow()
|
|
||||||
{
|
|
||||||
// Return anything previously pushed-back
|
|
||||||
if (pushbacks.size())
|
|
||||||
return pushbacks.back();
|
|
||||||
|
|
||||||
// Else do the right thing
|
|
||||||
fpos_t pos;
|
|
||||||
if (std::fgetpos( fp, &pos ) != 0)
|
|
||||||
return traits_type::eof();
|
|
||||||
|
|
||||||
int c = std::fgetc( fp );
|
|
||||||
std::fsetpos( fp, &pos );
|
|
||||||
|
|
||||||
return maybe_eof( c );
|
|
||||||
}
|
|
||||||
|
|
||||||
//......................................................................
|
|
||||||
// Get the CURRENT character AND advance the file pointer
|
|
||||||
virtual int_type uflow()
|
|
||||||
{
|
|
||||||
// Return anything previously pushed-back
|
|
||||||
if (pushbacks.size())
|
|
||||||
{
|
|
||||||
int_type c = pushbacks.back();
|
|
||||||
pushbacks.pop_back();
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Else do the right thing
|
|
||||||
return maybe_eof( std::fgetc( fp ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
//......................................................................
|
|
||||||
virtual int_type pbackfail( int_type c = traits_type::eof() )
|
|
||||||
{
|
|
||||||
if (!is_open())
|
|
||||||
return traits_type::eof();
|
|
||||||
|
|
||||||
// If the argument c is EOF and the file pointer is not at the
|
|
||||||
// beginning of the character sequence, it is decremented by one.
|
|
||||||
if (traits_type::eq_int_type( c, traits_type::eof() ))
|
|
||||||
{
|
|
||||||
pushbacks.clear();
|
|
||||||
return std::fseek( fp, -1L, SEEK_CUR )
|
|
||||||
? traits_type::eof()
|
|
||||||
: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, make the argument the next value to be returned by
|
|
||||||
// underflow() or uflow()
|
|
||||||
pushbacks.push_back( c );
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
//......................................................................
|
|
||||||
virtual int_type overflow( int_type c = traits_type::eof() )
|
|
||||||
{
|
|
||||||
pushbacks.clear();
|
|
||||||
|
|
||||||
// Do nothing
|
|
||||||
if (traits_type::eq_int_type( c, traits_type::eof() ))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Else write a character
|
|
||||||
return maybe_eof( std::fputc( c, fp ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
//......................................................................
|
|
||||||
virtual this_type* setbuf( char* s, std::streamsize n )
|
|
||||||
{
|
|
||||||
return std::setvbuf( fp, s, (s and n) ? _IOLBF : _IONBF, (size_t)n )
|
|
||||||
? NULL
|
|
||||||
: this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//......................................................................
|
|
||||||
virtual pos_type seekoff(
|
|
||||||
off_type offset,
|
|
||||||
std::ios_base::seekdir direction,
|
|
||||||
std::ios_base::openmode which = std::ios_base::in | std::ios_base::out
|
|
||||||
) {
|
|
||||||
pushbacks.clear();
|
|
||||||
return std::fseek( fp, offset,
|
|
||||||
(direction == std::ios_base::beg) ? SEEK_SET :
|
|
||||||
(direction == std::ios_base::cur) ? SEEK_CUR :
|
|
||||||
SEEK_END
|
|
||||||
) ? (-1) : std::ftell( fp );
|
|
||||||
}
|
|
||||||
|
|
||||||
//......................................................................
|
|
||||||
virtual pos_type seekpos(
|
|
||||||
pos_type position,
|
|
||||||
std::ios_base::openmode which = std::ios_base::in | std::ios_base::out
|
|
||||||
) {
|
|
||||||
pushbacks.clear();
|
|
||||||
return std::fseek( fp, (long) position, SEEK_SET )
|
|
||||||
? (-1)
|
|
||||||
: std::ftell( fp );
|
|
||||||
}
|
|
||||||
|
|
||||||
//......................................................................
|
|
||||||
virtual int sync()
|
|
||||||
{
|
|
||||||
pushbacks.clear();
|
|
||||||
return std::fflush( fp )
|
|
||||||
? traits_type::eof()
|
|
||||||
: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
private:
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
FILE* fp;
|
|
||||||
std::vector <int_type> pushbacks; // we'll treat this like a stack
|
|
||||||
|
|
||||||
//......................................................................
|
|
||||||
// Utility function to make sure EOF gets translated to the proper value
|
|
||||||
inline int_type maybe_eof( int value ) const
|
|
||||||
{
|
|
||||||
return (value == EOF) ? traits_type::eof() : value;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* /////////////////////////////////////////////////////////////////////////
|
|
||||||
basic_stdiostream
|
|
||||||
///////////////////////////////////////////////////////////////////////// */
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename CharType,
|
|
||||||
typename CharTraits = std::char_traits <CharType>
|
|
||||||
>
|
|
||||||
struct basic_stdiostream: public std::basic_iostream <CharType, CharTraits>
|
|
||||||
{
|
|
||||||
typedef CharType char_type;
|
|
||||||
typedef CharTraits traits_type;
|
|
||||||
|
|
||||||
typedef basic_stdiobuf <char_type, traits_type> sbuf_type;
|
|
||||||
typedef basic_stdiostream <char_type, traits_type> this_type;
|
|
||||||
typedef std::basic_iostream <char_type, traits_type> base_type;
|
|
||||||
|
|
||||||
//......................................................................
|
|
||||||
basic_stdiostream( FILE* fp = NULL ):
|
|
||||||
base_type( new sbuf_type( fp ) )
|
|
||||||
{ }
|
|
||||||
|
|
||||||
//......................................................................
|
|
||||||
basic_stdiostream( const char* filename, std::ios_base::openmode mode ):
|
|
||||||
//BUG 2: Oops! This is a potential memory leak!
|
|
||||||
base_type( (new sbuf_type)->open( filename, mode ) )
|
|
||||||
{ }
|
|
||||||
|
|
||||||
//......................................................................
|
|
||||||
void open(
|
|
||||||
const char* filename,
|
|
||||||
std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out
|
|
||||||
) {
|
|
||||||
sbuf_type* buf = static_cast <sbuf_type*> ( this->rdbuf() );
|
|
||||||
if (!(buf->open( filename, mode )))
|
|
||||||
this->setstate( std::ios_base::badbit );
|
|
||||||
}
|
|
||||||
|
|
||||||
//......................................................................
|
|
||||||
void close()
|
|
||||||
{
|
|
||||||
sbuf_type* buf = static_cast <sbuf_type*> ( this->rdbuf() );
|
|
||||||
buf->close();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* /////////////////////////////////////////////////////////////////////////
|
|
||||||
Useful typedefs
|
|
||||||
///////////////////////////////////////////////////////////////////////// */
|
|
||||||
|
|
||||||
typedef basic_stdiobuf <char> stdiobuf;
|
|
||||||
typedef basic_stdiostream <char> stdiostream;
|
|
||||||
|
|
||||||
} // namespace duthomhas
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// end stdiostream.hpp
|
|
Loading…
Reference in New Issue