kolibrios-gitea/programs/games/21days/sys.cpp

401 lines
9.7 KiB
C++
Raw Normal View History

/******************************************************************
* 21 days: a game for programmers
* Copyright (C) 2014 Maxim Grishin
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*******************************************************************/
char* windowTitle = "21 days by igevorse";
#ifdef _KOS32
#define kbhit kbhit // Prevent redeclaring kbhit() in pc.h
#include <string>
using std::string;
#pragma pack(push,1)
typedef struct {
char *name;
void *data;
} kol_struct_import;
#pragma pack(pop)
void kol_exit() {
asm volatile ("int $0x40"::"a"(-1));
}
void kol_screen_get_size(unsigned *w, unsigned *h) {
unsigned size;
asm volatile ("int $0x40":"=a"(size):"a"(14));
*w = size / 65536;
*h = size % 65536;
}
void (* __attribute__((stdcall)) con_init)(unsigned w_w, unsigned w_h, unsigned s_w, unsigned s_h, const char* t);
void (* __attribute__((cdecl)) printf2)(const char* format,...);
void (* __attribute__((stdcall)) con_exit)(char bCloseWindow);
int (* __attribute__((stdcall)) getch)();
int (* __attribute__((stdcall)) kbhit)();
void (* __attribute__((stdcall)) con_set_cursor_pos) (int x, int y);
int (* __attribute__((stdcall)) con_set_cursor_height)(int new_height);
void (* __attribute__((stdcall)) cls)();
int strcmp(const char* string1, const char* string2) {
while (1) {
if (*string1<*string2)
return -1;
if (*string1>*string2)
return 1;
if (*string1=='\0')
return 0;
string1++;
string2++;
}
}
void* kol_cofflib_procload (kol_struct_import *imp, char *name) {
for (int i=0;;i++)
if (NULL == ((imp+i) -> name))
break;
else
if (0 == strcmp(name, (imp+i)->name) )
return (imp+i)->data;
return NULL;
}
kol_struct_import* kol_cofflib_load(char *name) {
kol_struct_import* val;
asm volatile ("int $0x40":"=a"(val):"a"(68), "b"(19), "c"(name));
return val;
}
unsigned _kWinWidth = 100;
unsigned _kWinHeight = 30;
void getWinWH(int& width, int& height) {
width = _kWinWidth;
height = _kWinHeight-1;
}
void CONSOLE_INIT(char* title) {
kol_struct_import *imp = kol_cofflib_load("/sys/lib/console.obj");
if (imp == 0)
kol_exit();
con_init = ( __attribute__((stdcall)) void (*)(unsigned, unsigned, unsigned, unsigned, const char*))
kol_cofflib_procload (imp, "con_init");
if (con_init == NULL)
kol_exit();
printf2 = ( __attribute__((cdecl)) void (*)(const char*,...))
kol_cofflib_procload (imp, "con_printf");
if (printf2 == NULL)
kol_exit();
con_exit = ( __attribute__((stdcall)) void (*)(char))
kol_cofflib_procload (imp, "con_exit");
if (con_exit == NULL)
kol_exit();
getch = ( __attribute__((stdcall)) int (*)())
kol_cofflib_procload (imp, "con_getch");
if (getch == NULL)
kol_exit();
cls = ( __attribute__((stdcall)) void (*)())
kol_cofflib_procload (imp, "con_cls");
if (cls == NULL)
kol_exit();
kbhit = ( __attribute__((stdcall)) int (*)())
kol_cofflib_procload (imp, "con_kbhit");
if (kbhit == NULL)
kol_exit();
con_set_cursor_pos = ( __attribute__((stdcall)) void (*) (int, int))
kol_cofflib_procload (imp, "con_set_cursor_pos");
if (con_set_cursor_pos == NULL)
kol_exit();
con_set_cursor_height = ( __attribute__((stdcall)) int (*)(int))
kol_cofflib_procload (imp, "con_set_cursor_height");
if (con_set_cursor_height == NULL)
kol_exit();
unsigned sw, sh;
kol_screen_get_size(&sw, &sh);
// Change window w/h depending on screen w/h
// Sorry for magic numbers
if (_kWinWidth*8 >= sw)
_kWinWidth = sw / 8;
if (_kWinHeight*17 >= sh)
_kWinHeight = sh / 17;
con_init(_kWinWidth, _kWinHeight, _kWinWidth, _kWinHeight, title);
}
void hideCursor() {
con_set_cursor_height(0);
}
void showCursor() {
//nop;
}
void consoleGoto(int line, int column) {
con_set_cursor_pos(column-1, line-1);
}
string itos(int n) {
string s;
int i, sign;
if ((sign = n) < 0)
n = -n;
i = 0;
do {
s[i++] = n % 10 + '0';
} while ((n /= 10) > 0);
if (sign < 0)
s[i++] = '-';
s[i] = '\0';
int j,k;
for (k = 0, j = i-1; k<j; k++, j--) {
char c = s[k];
s[k] = s[j];
s[j] = c;
}
return s;
}
// Ok, I don't want to use vsprintf from KolibriOS
string txt(string s, int d) {
string t = s;
unsigned i = t.find("%d");
if (i != string::npos)
t.replace(i, 2, itos(d).c_str());
return t;
}
string txt(string s, char c) {
string t = s;
unsigned i = t.find("%c");
if (i != string::npos)
t.replace(i, 2, c);
return t;
}
string txt(string s, string s2) {
string t = s;
unsigned i = t.find("%s");
if (i != string::npos)
t.replace(i, 2, s2.c_str());
return t;
}
string txt(string s, string s2, string s3) {
return txt(txt(s, s2), s3);
}
string txt(string s, char ch, string s2) {
return txt(txt(s, ch), s2);
}
string txt(string s, char ch, string s2, char ch2) {
return txt(txt(txt(s, ch), s2), ch2);
}
string txt(string s, int d1, int d2) {
return txt(txt(s, d1), d2);
}
string txt(string s, int d1, int d2, int d3) {
return txt(txt(txt(s, d1), d2), d3);
}
string txt(string s, int d1, int d2, int d3, int d4) {
return txt(txt(txt(txt(s, d1), d2), d3), d4);
}
void initConsole() {
CONSOLE_INIT(windowTitle);
}
#elif defined __linux__
#define printf2 printf
#include <cstdlib> // system
#include <stdarg.h>
#include <stdio.h> // printf, vsprintf
#include <sys/ioctl.h> // get window width/height
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
#include <string>
static struct termios old, new1;
std::string txt(const char* s, ...) {
va_list args;
va_start(args,s);
char x[100000];
vsprintf(x, s, args);
va_end(args);
std::string str(x);
return str;
}
void cls() {
system("clear");
}
void hideCursor() {
printf2("\033[?25l");
}
void showCursor() {
printf2("\033[?25h");
}
void consoleGoto(int line, int column) {
printf2("\033[%d;%dH", line, column);
}
void consoleSetColor(short text = 30, short background = 47) {
printf2("\033[%d;%dm", text, background);
}
/* Initialize new terminal i/o settings */
void initTermios() {
tcgetattr(0, &old); /* grab old terminal i/o settings */
new1 = old; /* make new settings same as old settings */
new1.c_lflag &= ~ICANON; /* disable buffered i/o */
new1.c_lflag &= ~ECHO; /* set echo mode */
tcsetattr(0, TCSANOW, &new1); /* use these new terminal i/o settings now */
}
/* Restore old terminal i/o settings */
void resetTermios() {
tcsetattr(0, TCSANOW, &old);
}
int kbhit () {
struct termios oldt, newt;
int ch;
int oldf;
tcgetattr(STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~(ICANON | ECHO);
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
ch = getchar();
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
fcntl(STDIN_FILENO, F_SETFL, oldf);
if(ch != EOF) {
ungetc(ch, stdin);
return 1;
}
return 0;
}
/* Read 1 character without echo */
char getch() {
char ch;
initTermios();
ch = getchar();
resetTermios();
return ch;
}
void getWinWH(int& width, int& height) {
struct winsize w;
ioctl(0, TIOCGWINSZ, &w);
width = w.ws_col;
height = w.ws_row-1;
}
void initConsole() {
printf2("\033]0;%s\007", windowTitle);
}
#elif defined _WIN32
#define printf2 printf
#include <stdio.h> // printf, vsprintf
#include <windows.h>
#include <cstdlib> // system
#define _NO_OLDNAMES _NO_OLDNAMES
#include <conio.h> // kbhit(), getch(), getche()
#include <string>
char getch() {
return _getch();
}
int kbhit (void) {
return _kbhit();
}
std::string txt(const char* s, ...) {
va_list args;
va_start(args,s);
char x[100000];
vsprintf(x, s, args);
va_end(args);
std::string str(x);
return str;
}
void cls() {
system("cls");
}
void showCursor() {
HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO info;
info.bVisible = TRUE;
SetConsoleCursorInfo(consoleHandle, &info);
}
void hideCursor() {
HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO info;
info.bVisible = FALSE;
info.dwSize = 1;
SetConsoleCursorInfo(consoleHandle, &info);
}
void consoleGoto(int line, int column) {
COORD coord;
coord.X = column;
coord.Y = line;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
void consoleSetColor(short text = 30, short background = 47) {
printf2("\033[%d;%dm", text, background);
}
void getWinWH(int& width, int& height) {
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
width = csbi.srWindow.Right - csbi.srWindow.Left - 1;
height = csbi.srWindow.Bottom - csbi.srWindow.Top - 1;
}
void initConsole() {
SetConsoleTitle(windowTitle);
system("mode 100, 30");
}
#endif