Page MenuHomePhorge

rlutil.h
No OneTemporary

Size
21 KB
Referenced Files
None
Subscribers
None

rlutil.h

#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) 2010 Tapio Vierros
*
* About: Licensing
* See <License>
*/
//#ifndef RLUTIL_HEADERFILE
//#define RLUTIL_HEADERFILE
/// 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
#ifndef RLUTIL_INLINE
#ifdef _MSC_VER
#define RLUTIL_INLINE __inline
#else
#define RLUTIL_INLINE static __inline__
#endif
#endif
#ifdef __cplusplus
/// Common C++ headers
#include <iostream>
#include <string>
#include <cstdio> // for getch()
/// Namespace forward declarations
namespace rlutil {
RLUTIL_INLINE void locate(int x, int y);
}
//Work Arround (atartpoint)
#define TXTCOLOR_BLACK 0
#define TXTCOLOR_BLUE 1
#define TXTCOLOR_GREEN 2
#define TXTCOLOR_CYAN 3
#define TXTCOLOR_RED 4
#define TXTCOLOR_MAGENTA 5
#define TXTCOLOR_BROWN 6
#define TXTCOLOR_GREY 7
#define TXTCOLOR_DARKGREY 8
#define TXTCOLOR_LIGHTBLUE 9
#define TXTCOLOR_LIGHTGREEN 10
#define TXTCOLOR_LIGHTCYAN 11
#define TXTCOLOR_LIGHTRED 12
#define TXTCOLOR_LIGHTMAGENTA 13
#define TXTCOLOR_YELLOW 14
#define TXTCOLOR_WHITE 15
#else
#include <stdio.h> // for getch() / printf()
#include <string.h> // for strlen()
RLUTIL_INLINE void locate(int x, int y); // Forward declare for C to avoid warnings
#endif // __cplusplus
#ifdef _WIN32
#include <windows.h> // for WinAPI and Sleep()
#define _NO_OLDNAMES // for MinGW compatibility
#include <conio.h> // for getch() and kbhit()
#define getch _getch
#define kbhit _kbhit
#else
#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
RLUTIL_INLINE int getch(void) {
// 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
RLUTIL_INLINE int kbhit(void) {
// 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>.
RLUTIL_INLINE void 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
#define RLUTIL_PRINT(st) do { std::cout << st; } while(false)
#else // __cplusplus
#ifndef RLUTIL_STRING_T
typedef const char* RLUTIL_STRING_T;
#endif // RLUTIL_STRING_T
#define RLUTIL_PRINT(st) printf("%s", st)
#endif // __cplusplus
/**
* Enums: Color codes
*
* BLACK - Black
* BLUE - Blue
* GREEN - Green
* CYAN - Cyan
* RED - Red
* MAGENTA - Magenta / purple
* BROWN - Brown / dark yellow
* GREY - Grey / dark white
* DARKGREY - Dark grey / light black
* LIGHTBLUE - Light blue
* LIGHTGREEN - Light green
* LIGHTCYAN - Light cyan
* LIGHTRED - Light red
* LIGHTMAGENTA - Light magenta / light purple
* YELLOW - Yellow (bright)
* WHITE - White (bright)
*/
enum {
BLACK,
BLUE,
GREEN,
CYAN,
RED,
MAGENTA,
BROWN,
GREY,
DARKGREY,
LIGHTBLUE,
LIGHTGREEN,
LIGHTCYAN,
LIGHTRED,
LIGHTMAGENTA,
YELLOW,
WHITE
};
/**
* Consts: ANSI escape strings
*
* ANSI_CLS - Clears screen
* ANSI_CONSOLE_TITLE_PRE - Prefix for changing the window title, print the window title in between
* ANSI_CONSOLE_TITLE_POST - Suffix for changing the window title, print the window title in between
* ANSI_ATTRIBUTE_RESET - Resets all attributes
* ANSI_CURSOR_HIDE - Hides the cursor
* ANSI_CURSOR_SHOW - Shows the cursor
* ANSI_CURSOR_HOME - Moves the cursor home (0,0)
* 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)
* ANSI_BACKGROUND_BLACK - Black background
* ANSI_BACKGROUND_RED - Red background
* ANSI_BACKGROUND_GREEN - Green background
* ANSI_BACKGROUND_YELLOW - Yellow background
* ANSI_BACKGROUND_BLUE - Blue background
* ANSI_BACKGROUND_MAGENTA - Magenta / purple background
* ANSI_BACKGROUND_CYAN - Cyan background
* ANSI_BACKGROUND_WHITE - White background
*/
const RLUTIL_STRING_T ANSI_CLS = "\033[2J\033[3J";
const RLUTIL_STRING_T ANSI_CONSOLE_TITLE_PRE = "\033]0;";
const RLUTIL_STRING_T ANSI_CONSOLE_TITLE_POST = "\007";
const RLUTIL_STRING_T ANSI_ATTRIBUTE_RESET = "\033[0m";
const RLUTIL_STRING_T ANSI_CURSOR_HIDE = "\033[?25l";
const RLUTIL_STRING_T ANSI_CURSOR_SHOW = "\033[?25h";
const RLUTIL_STRING_T ANSI_CURSOR_HOME = "\033[H";
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";
const RLUTIL_STRING_T ANSI_BACKGROUND_BLACK = "\033[40m";
const RLUTIL_STRING_T ANSI_BACKGROUND_RED = "\033[41m";
const RLUTIL_STRING_T ANSI_BACKGROUND_GREEN = "\033[42m";
const RLUTIL_STRING_T ANSI_BACKGROUND_YELLOW = "\033[43m";
const RLUTIL_STRING_T ANSI_BACKGROUND_BLUE = "\033[44m";
const RLUTIL_STRING_T ANSI_BACKGROUND_MAGENTA = "\033[45m";
const RLUTIL_STRING_T ANSI_BACKGROUND_CYAN = "\033[46m";
const RLUTIL_STRING_T ANSI_BACKGROUND_WHITE = "\033[47m";
// Remaining colors not supported as background colors
/**
* Enums: 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
*/
enum {
KEY_ESCAPE = 0,
KEY_ENTER = 1,
KEY_SPACE = 32,
KEY_INSERT = 2,
KEY_HOME = 3,
KEY_PGUP = 4,
KEY_DELETE = 5,
KEY_END = 6,
KEY_PGDOWN = 7,
KEY_UP = 14,
KEY_DOWN = 15,
KEY_LEFT = 16,
KEY_RIGHT = 17,
KEY_F1 = 18,
KEY_F2 = 19,
KEY_F3 = 20,
KEY_F4 = 21,
KEY_F5 = 22,
KEY_F6 = 23,
KEY_F7 = 24,
KEY_F8 = 25,
KEY_F9 = 26,
KEY_F10 = 27,
KEY_F11 = 28,
KEY_F12 = 29,
KEY_NUMDEL = 30,
KEY_NUMPAD0 = 31,
KEY_NUMPAD1 = 127,
KEY_NUMPAD2 = 128,
KEY_NUMPAD3 = 129,
KEY_NUMPAD4 = 130,
KEY_NUMPAD5 = 131,
KEY_NUMPAD6 = 132,
KEY_NUMPAD7 = 133,
KEY_NUMPAD8 = 134,
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.
RLUTIL_INLINE 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_NUMPAD2;
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.
RLUTIL_INLINE int nb_getch(void) {
if (kbhit()) return getch();
else return 0;
}
/// Function: getANSIColor
/// Return ANSI color escape sequence for specified number 0-15.
///
/// See <Color Codes>
RLUTIL_INLINE RLUTIL_STRING_T getANSIColor(const int c) {
switch (c) {
case BLACK : return ANSI_BLACK;
case BLUE : return ANSI_BLUE; // non-ANSI
case GREEN : return ANSI_GREEN;
case CYAN : return ANSI_CYAN; // non-ANSI
case RED : return ANSI_RED; // non-ANSI
case MAGENTA : return ANSI_MAGENTA;
case BROWN : return ANSI_BROWN;
case GREY : return ANSI_GREY;
case DARKGREY : return ANSI_DARKGREY;
case LIGHTBLUE : return ANSI_LIGHTBLUE; // non-ANSI
case LIGHTGREEN : return ANSI_LIGHTGREEN;
case LIGHTCYAN : return ANSI_LIGHTCYAN; // non-ANSI;
case LIGHTRED : return ANSI_LIGHTRED; // non-ANSI;
case LIGHTMAGENTA: return ANSI_LIGHTMAGENTA;
case YELLOW : return ANSI_YELLOW; // non-ANSI
case WHITE : return ANSI_WHITE;
default: return "";
}
}
/// Function: getANSIBackgroundColor
/// Return ANSI background color escape sequence for specified number 0-15.
///
/// See <Color Codes>
RLUTIL_INLINE RLUTIL_STRING_T getANSIBackgroundColor(const int c) {
switch (c) {
case BLACK : return ANSI_BACKGROUND_BLACK;
case BLUE : return ANSI_BACKGROUND_BLUE;
case GREEN : return ANSI_BACKGROUND_GREEN;
case CYAN : return ANSI_BACKGROUND_CYAN;
case RED : return ANSI_BACKGROUND_RED;
case MAGENTA: return ANSI_BACKGROUND_MAGENTA;
case BROWN : return ANSI_BACKGROUND_YELLOW;
case GREY : return ANSI_BACKGROUND_WHITE;
default: return "";
}
}
/// Function: setColor
/// Change color specified by number (Windows / QBasic colors).
/// Don't change the background color
///
/// See <Color Codes>
RLUTIL_INLINE void setColor(int c) {
#if defined(_WIN32) && !defined(RLUTIL_USE_ANSI)
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(hConsole, &csbi);
SetConsoleTextAttribute(hConsole, (csbi.wAttributes & 0xFFF0) | (WORD)c); // Foreground colors take up the least significant byte
#else
RLUTIL_PRINT(getANSIColor(c));
#endif
}
/// Function: setBackgroundColor
/// Change background color specified by number (Windows / QBasic colors).
/// Don't change the foreground color
///
/// See <Color Codes>
RLUTIL_INLINE void setBackgroundColor(int c) {
#if defined(_WIN32) && !defined(RLUTIL_USE_ANSI)
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(hConsole, &csbi);
SetConsoleTextAttribute(hConsole, (csbi.wAttributes & 0xFF0F) | (((WORD)c) << 4)); // Background colors take up the second-least significant byte
#else
RLUTIL_PRINT(getANSIBackgroundColor(c));
#endif
}
/// Function: saveDefaultColor
/// Call once to preserve colors for use in resetColor()
/// on Windows without ANSI, no-op otherwise
///
/// See <Color Codes>
/// See <resetColor>
RLUTIL_INLINE int saveDefaultColor(void) {
#if defined(_WIN32) && !defined(RLUTIL_USE_ANSI)
static char initialized = 0; // bool
static WORD attributes;
if (!initialized) {
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
attributes = csbi.wAttributes;
initialized = 1;
}
return (int)attributes;
#else
return -1;
#endif
}
/// Function: resetColor
/// Reset color to default
/// Requires a call to saveDefaultColor() to set the defaults
///
/// See <Color Codes>
/// See <setColor>
/// See <saveDefaultColor>
RLUTIL_INLINE void resetColor(void) {
#if defined(_WIN32) && !defined(RLUTIL_USE_ANSI)
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), (WORD)saveDefaultColor());
#else
RLUTIL_PRINT(ANSI_ATTRIBUTE_RESET);
#endif
}
/// Function: cls
/// Clears screen, resets all attributes and moves cursor home.
RLUTIL_INLINE void cls(void) {
#if defined(_WIN32) && !defined(RLUTIL_USE_ANSI)
// Based on https://msdn.microsoft.com/en-us/library/windows/desktop/ms682022%28v=vs.85%29.aspx
const HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
const COORD coordScreen = {0, 0};
DWORD cCharsWritten;
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(hConsole, &csbi);
const DWORD dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
FillConsoleOutputCharacter(hConsole, (TCHAR)' ', dwConSize, coordScreen, &cCharsWritten);
GetConsoleScreenBufferInfo(hConsole, &csbi);
FillConsoleOutputAttribute(hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten);
SetConsoleCursorPosition(hConsole, coordScreen);
#else
RLUTIL_PRINT(ANSI_CLS);
RLUTIL_PRINT(ANSI_CURSOR_HOME);
#endif
}
/// Function: locate
/// Sets the cursor position to 1-based x,y.
RLUTIL_INLINE void locate(int x, int y) {
#if defined(_WIN32) && !defined(RLUTIL_USE_ANSI)
COORD coord;
// TODO: clamping/assert for x/y <= 0?
coord.X = (SHORT)(x - 1);
coord.Y = (SHORT)(y - 1); // Windows uses 0-based coordinates
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
#else // _WIN32 || USE_ANSI
#ifdef __cplusplus
RLUTIL_PRINT("\033[" << y << ";" << x << "H");
#else // __cplusplus
char buf[32];
sprintf(buf, "\033[%d;%df", y, x);
RLUTIL_PRINT(buf);
#endif // __cplusplus
#endif // _WIN32 || USE_ANSI
}
/// Function: setString
/// Prints the supplied string without advancing the cursor
#ifdef __cplusplus
RLUTIL_INLINE void setString(const RLUTIL_STRING_T & str_) {
//Work Around (startpoint)
const char * const str_temp = str_.data(); //Changed: "str" -> "str_temp"
wchar_t* str=new wchar_t[4096]; //Add this line
MultiByteToWideChar(CP_ACP, 0, str_temp, -1, str, 4096); //Add this line
//Work Around (endpoint)
unsigned int len = str_.size();
#else // __cplusplus
RLUTIL_INLINE void setString(RLUTIL_STRING_T str) {
unsigned int len = strlen(str);
#endif // __cplusplus
#if defined(_WIN32) && !defined(RLUTIL_USE_ANSI)
HANDLE hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD numberOfCharsWritten;
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(hConsoleOutput, &csbi);
WriteConsoleOutputCharacter(hConsoleOutput, str, len, csbi.dwCursorPosition, &numberOfCharsWritten);
#else // _WIN32 || USE_ANSI
RLUTIL_PRINT(str);
#ifdef __cplusplus
RLUTIL_PRINT("\033[" << len << 'D');
#else // __cplusplus
char buf[3 + 20 + 1]; // 20 = max length of 64-bit unsigned int when printed as dec
sprintf(buf, "\033[%uD", len);
RLUTIL_PRINT(buf);
#endif // __cplusplus
#endif // _WIN32 || USE_ANSI
}
/// Function: setChar
/// Sets the character at the cursor without advancing the cursor
RLUTIL_INLINE void setChar(char ch) {
const char buf[] = {ch, 0};
setString(buf);
}
/// Function: setCursorVisibility
/// Shows/hides the cursor.
RLUTIL_INLINE void setCursorVisibility(char visible) {
#if defined(_WIN32) && !defined(RLUTIL_USE_ANSI)
HANDLE hConsoleOutput = GetStdHandle( STD_OUTPUT_HANDLE );
CONSOLE_CURSOR_INFO structCursorInfo;
GetConsoleCursorInfo( hConsoleOutput, &structCursorInfo ); // Get current cursor size
structCursorInfo.bVisible = (visible ? TRUE : FALSE);
SetConsoleCursorInfo( hConsoleOutput, &structCursorInfo );
#else // _WIN32 || USE_ANSI
RLUTIL_PRINT((visible ? ANSI_CURSOR_SHOW : ANSI_CURSOR_HIDE));
#endif // _WIN32 || USE_ANSI
}
/// Function: hidecursor
/// Hides the cursor.
RLUTIL_INLINE void hidecursor(void) {
setCursorVisibility(0);
}
/// Function: showcursor
/// Shows the cursor.
RLUTIL_INLINE void showcursor(void) {
setCursorVisibility(1);
}
/// Function: msleep
/// Waits given number of milliseconds before continuing.
RLUTIL_INLINE void 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
}
/// Function: trows
/// Get the number of rows in the terminal window or -1 on error.
RLUTIL_INLINE int trows(void) {
#ifdef _WIN32
CONSOLE_SCREEN_BUFFER_INFO csbi;
if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi))
return -1;
else
return csbi.srWindow.Bottom - csbi.srWindow.Top + 1; // Window height
// return csbi.dwSize.Y; // Buffer height
#else
#ifdef TIOCGSIZE
struct ttysize ts;
ioctl(STDIN_FILENO, TIOCGSIZE, &ts);
return ts.ts_lines;
#elif defined(TIOCGWINSZ)
struct winsize ts;
ioctl(STDIN_FILENO, TIOCGWINSZ, &ts);
return ts.ws_row;
#else // TIOCGSIZE
return -1;
#endif // TIOCGSIZE
#endif // _WIN32
}
/// Function: tcols
/// Get the number of columns in the terminal window or -1 on error.
RLUTIL_INLINE int tcols(void) {
#ifdef _WIN32
CONSOLE_SCREEN_BUFFER_INFO csbi;
if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi))
return -1;
else
return csbi.srWindow.Right - csbi.srWindow.Left + 1; // Window width
// return csbi.dwSize.X; // Buffer width
#else
#ifdef TIOCGSIZE
struct ttysize ts;
ioctl(STDIN_FILENO, TIOCGSIZE, &ts);
return ts.ts_cols;
#elif defined(TIOCGWINSZ)
struct winsize ts;
ioctl(STDIN_FILENO, TIOCGWINSZ, &ts);
return ts.ws_col;
#else // TIOCGSIZE
return -1;
#endif // TIOCGSIZE
#endif // _WIN32
}
/// Function: anykey
/// Waits until a key is pressed.
/// In C++, it either takes no arguments
/// or a template-type-argument-deduced
/// argument.
/// In C, it takes a const char* representing
/// the message to be displayed, or NULL
/// for no message.
#ifdef __cplusplus
RLUTIL_INLINE void anykey() {
getch();
}
template <class T> void anykey(const T& msg) {
RLUTIL_PRINT(msg);
#else
RLUTIL_INLINE void anykey(RLUTIL_STRING_T msg) {
if (msg)
RLUTIL_PRINT(msg);
#endif // __cplusplus
getch();
}
RLUTIL_INLINE void setConsoleTitle(RLUTIL_STRING_T title) {
const char * true_title =
#ifdef __cplusplus
title.c_str();
#else // __cplusplus
title;
#endif // __cplusplus
#if defined(_WIN32) && !defined(RLUTIL_USE_ANSI)
SetConsoleTitleA(true_title);
#else
RLUTIL_PRINT(ANSI_CONSOLE_TITLE_PRE);
RLUTIL_PRINT(true_title);
RLUTIL_PRINT(ANSI_CONSOLE_TITLE_POST);
#endif // defined(_WIN32) && !defined(RLUTIL_USE_ANSI)
}
// 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
//#endif

File Metadata

Mime Type
text/x-c++
Expires
Sun, Jun 8, 6:55 PM (19 h, 29 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
149922
Default Alt Text
rlutil.h (21 KB)

Event Timeline