Drawing on windows console
This commit is contained in:
parent
f7d4c2013c
commit
160dbcd50f
378
MD_AnsiCons.c
Normal file
378
MD_AnsiCons.c
Normal file
@ -0,0 +1,378 @@
|
||||
#include <windows.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <io.h>
|
||||
|
||||
#ifndef FOREGROUND_MASK
|
||||
# define FOREGROUND_MASK (FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN)
|
||||
#endif
|
||||
|
||||
#ifndef BACKGROUND_MASK
|
||||
# define BACKGROUND_MASK (BACKGROUND_RED|BACKGROUND_BLUE|BACKGROUND_GREEN)
|
||||
#endif
|
||||
|
||||
int ansi_write(FILE* fp, const char* buf, int len) {
|
||||
static int first = 1;
|
||||
static int state = 0;
|
||||
static int n;
|
||||
static int v[6];
|
||||
static COORD saved_coord = { 0, 0 };
|
||||
int type;
|
||||
HANDLE handle = INVALID_HANDLE_VALUE;
|
||||
static WORD attr;
|
||||
DWORD written, csize;
|
||||
CONSOLE_CURSOR_INFO cci;
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
COORD coord;
|
||||
const char* ptr = buf;
|
||||
int w, h;
|
||||
if (fp == stdout) {
|
||||
type = 0;
|
||||
}
|
||||
else if (fp == stderr) {
|
||||
type = 1;
|
||||
}
|
||||
else {
|
||||
type = 0;
|
||||
}
|
||||
|
||||
handle = (HANDLE)_get_osfhandle(fileno(fp));
|
||||
GetConsoleScreenBufferInfo(handle, &csbi);
|
||||
attr = csbi.wAttributes;
|
||||
|
||||
int z = 0;
|
||||
|
||||
for (z = 0; z < len; z++) {
|
||||
if (state == 0) {
|
||||
if (ptr[z] == '\033') {
|
||||
state = 1;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
fputc(ptr[z], fp);
|
||||
}
|
||||
}
|
||||
else if (state == 1) {
|
||||
if (ptr[z] == '[') {
|
||||
state = 2;
|
||||
}
|
||||
else {
|
||||
state = 0;
|
||||
}
|
||||
} else if (state == 2) {
|
||||
n = 0;
|
||||
for (int j = 0; j < 6; j++) {
|
||||
v[j] = 0;
|
||||
}
|
||||
state = 3;
|
||||
}
|
||||
if (state == 3) {
|
||||
if (ptr[z] == ';') {
|
||||
if (n < 6) {
|
||||
n++;
|
||||
}
|
||||
continue;
|
||||
} else if (isdigit(ptr[z])) {
|
||||
if (n == 0) {
|
||||
n = 1;
|
||||
}
|
||||
v[n-1] = v[n-1] * 10 + (ptr[z] - '0');
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
state = 4;
|
||||
}
|
||||
}
|
||||
if (state == 4) {
|
||||
state = 0;
|
||||
switch (ptr[z]) {
|
||||
case 'h':
|
||||
for (int i = 0; i < n; i++) {
|
||||
switch (v[i]) {
|
||||
case 3:
|
||||
GetConsoleScreenBufferInfo(handle, &csbi);
|
||||
w = csbi.dwSize.X;
|
||||
h = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
|
||||
csize = w * (h + 1);
|
||||
coord.X = 0;
|
||||
coord.Y = csbi.srWindow.Top;
|
||||
FillConsoleOutputCharacter(handle, ' ', csize, coord, &written);
|
||||
FillConsoleOutputAttribute(handle, csbi.wAttributes, csize, coord, &written);
|
||||
SetConsoleCursorPosition(handle, csbi.dwCursorPosition);
|
||||
csbi.dwSize.X = 132;
|
||||
SetConsoleScreenBufferSize(handle, csbi.dwSize);
|
||||
csbi.srWindow.Right = csbi.srWindow.Left + 131;
|
||||
SetConsoleWindowInfo(handle, TRUE, &csbi.srWindow);
|
||||
break;
|
||||
case 5:
|
||||
attr =
|
||||
((attr & FOREGROUND_MASK) << 4) |
|
||||
((attr & BACKGROUND_MASK) >> 4);
|
||||
SetConsoleTextAttribute(handle, attr);
|
||||
break;
|
||||
case 9:
|
||||
break;
|
||||
case 25:
|
||||
GetConsoleCursorInfo(handle, &cci);
|
||||
cci.bVisible = TRUE;
|
||||
SetConsoleCursorInfo(handle, &cci);
|
||||
break;
|
||||
case 47:
|
||||
coord.X = 0;
|
||||
coord.Y = 0;
|
||||
SetConsoleCursorPosition(handle, coord);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case 'l':
|
||||
for (int i = 0; i < n; i++) {
|
||||
switch (v[i]) {
|
||||
case 3:
|
||||
GetConsoleScreenBufferInfo(handle, &csbi);
|
||||
w = csbi.dwSize.X;
|
||||
h = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
|
||||
csize = w * (h + 1);
|
||||
coord.X = 0;
|
||||
coord.Y = csbi.srWindow.Top;
|
||||
FillConsoleOutputCharacter(handle, ' ', csize, coord, &written);
|
||||
FillConsoleOutputAttribute(handle, csbi.wAttributes, csize, coord, &written);
|
||||
SetConsoleCursorPosition(handle, csbi.dwCursorPosition);
|
||||
csbi.srWindow.Right = csbi.srWindow.Left + 79;
|
||||
SetConsoleWindowInfo(handle, TRUE, &csbi.srWindow);
|
||||
csbi.dwSize.X = 80;
|
||||
SetConsoleScreenBufferSize(handle, csbi.dwSize);
|
||||
break;
|
||||
case 5:
|
||||
attr =
|
||||
((attr & FOREGROUND_MASK) << 4) |
|
||||
((attr & BACKGROUND_MASK) >> 4);
|
||||
SetConsoleTextAttribute(handle, attr);
|
||||
break;
|
||||
case 25:
|
||||
GetConsoleCursorInfo(handle, &cci);
|
||||
cci.bVisible = FALSE;
|
||||
SetConsoleCursorInfo(handle, &cci);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'm':
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (v[i] == -1 || v[i] == 0) {
|
||||
attr &= ~(FOREGROUND_INTENSITY);
|
||||
attr |= FOREGROUND_MASK;
|
||||
attr &= ~(BACKGROUND_MASK);
|
||||
}
|
||||
else if (v[i] == 1)
|
||||
attr |= FOREGROUND_INTENSITY;
|
||||
else if (v[i] == 4)
|
||||
attr |= FOREGROUND_INTENSITY;
|
||||
else if (v[i] == 5)
|
||||
attr |= FOREGROUND_INTENSITY;
|
||||
else if (v[i] == 7)
|
||||
attr =
|
||||
((attr & FOREGROUND_MASK) << 4) |
|
||||
((attr & BACKGROUND_MASK) >> 4);
|
||||
else if (v[i] == 10)
|
||||
; // symbol on
|
||||
else if (v[i] == 11)
|
||||
; // symbol off
|
||||
else if (v[i] == 22)
|
||||
attr &= ~FOREGROUND_INTENSITY;
|
||||
else if (v[i] == 24)
|
||||
attr &= ~FOREGROUND_INTENSITY;
|
||||
else if (v[i] == 25)
|
||||
attr &= ~FOREGROUND_INTENSITY;
|
||||
else if (v[i] == 27)
|
||||
attr =
|
||||
((attr & FOREGROUND_MASK) << 4) |
|
||||
((attr & BACKGROUND_MASK) >> 4);
|
||||
else if (v[i] >= 30 && v[i] <= 37) {
|
||||
attr = (attr & (BACKGROUND_MASK | FOREGROUND_INTENSITY));
|
||||
if ((v[i] - 30) & 1)
|
||||
attr |= FOREGROUND_RED;
|
||||
if ((v[i] - 30) & 2)
|
||||
attr |= FOREGROUND_GREEN;
|
||||
if ((v[i] - 30) & 4)
|
||||
attr |= FOREGROUND_BLUE;
|
||||
}
|
||||
//else if (v[i] == 39)
|
||||
//attr = (~attr & BACKGROUND_MASK);
|
||||
else if (v[i] >= 40 && v[i] <= 47) {
|
||||
attr = (attr & (FOREGROUND_MASK | BACKGROUND_INTENSITY));
|
||||
if ((v[i] - 40) & 1)
|
||||
attr |= BACKGROUND_RED;
|
||||
if ((v[i] - 40) & 2)
|
||||
attr |= BACKGROUND_GREEN;
|
||||
if ((v[i] - 40) & 4)
|
||||
attr |= BACKGROUND_BLUE;
|
||||
}
|
||||
else if (v[i] >= 90 && v[i] <= 97) {
|
||||
attr = (attr & BACKGROUND_MASK) | FOREGROUND_INTENSITY;
|
||||
if ((v[i] - 90) & 1)
|
||||
attr |= FOREGROUND_RED;
|
||||
if ((v[i] - 90) & 2)
|
||||
attr |= FOREGROUND_GREEN;
|
||||
if ((v[i] - 90) & 4)
|
||||
attr |= FOREGROUND_BLUE;
|
||||
}
|
||||
else if (v[i] >= 100 && v[i] <= 107) {
|
||||
attr = (attr & FOREGROUND_MASK) | BACKGROUND_INTENSITY;
|
||||
if ((v[i] - 100) & 1)
|
||||
attr |= BACKGROUND_RED;
|
||||
if ((v[i] - 100) & 2)
|
||||
attr |= BACKGROUND_GREEN;
|
||||
if ((v[i] - 100) & 4)
|
||||
attr |= BACKGROUND_BLUE;
|
||||
}
|
||||
//else if (v[i] == 49)
|
||||
//attr = (~attr & FOREGROUND_MASK);
|
||||
|
||||
}
|
||||
SetConsoleTextAttribute(handle, attr);
|
||||
break;
|
||||
case 'K':
|
||||
GetConsoleScreenBufferInfo(handle, &csbi);
|
||||
coord = csbi.dwCursorPosition;
|
||||
switch (v[0]) {
|
||||
default:
|
||||
case 0:
|
||||
csize = csbi.dwSize.X - coord.X;
|
||||
break;
|
||||
case 1:
|
||||
csize = coord.X;
|
||||
coord.X = 0;
|
||||
break;
|
||||
case 2:
|
||||
csize = csbi.dwSize.X;
|
||||
coord.X = 0;
|
||||
break;
|
||||
}
|
||||
FillConsoleOutputCharacter(handle, ' ', csize, coord, &written);
|
||||
FillConsoleOutputAttribute(handle, attr, csize, coord, &written);
|
||||
SetConsoleCursorPosition(handle, csbi.dwCursorPosition);
|
||||
break;
|
||||
case 'J':
|
||||
GetConsoleScreenBufferInfo(handle, &csbi);
|
||||
w = csbi.dwSize.X;
|
||||
h = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
|
||||
coord = csbi.dwCursorPosition;
|
||||
switch (v[0]) {
|
||||
default:
|
||||
case 0:
|
||||
csize = w * (h - coord.Y) - coord.X;
|
||||
coord.X = 0;
|
||||
break;
|
||||
case 1:
|
||||
csize = w * coord.Y + coord.X;
|
||||
coord.X = 0;
|
||||
coord.Y = csbi.srWindow.Top;
|
||||
break;
|
||||
case 2:
|
||||
csize = w * (h + 1);
|
||||
coord.X = 0;
|
||||
coord.Y = csbi.srWindow.Top;
|
||||
break;
|
||||
}
|
||||
FillConsoleOutputCharacter(handle, ' ', csize, coord, &written);
|
||||
FillConsoleOutputAttribute(handle, attr, csize, coord, &written);
|
||||
SetConsoleCursorPosition(handle, csbi.dwCursorPosition);
|
||||
break;
|
||||
case 'H':
|
||||
GetConsoleScreenBufferInfo(handle, &csbi);
|
||||
coord = csbi.dwCursorPosition;
|
||||
if (v[0] != -1) {
|
||||
if (v[1] != -1) {
|
||||
coord.Y = csbi.srWindow.Top + v[0] - 1;
|
||||
coord.X = v[1] - 1;
|
||||
}
|
||||
else
|
||||
coord.X = v[0] - 1;
|
||||
}
|
||||
else {
|
||||
coord.X = 0;
|
||||
coord.Y = csbi.srWindow.Top;
|
||||
}
|
||||
if (coord.X < csbi.srWindow.Left)
|
||||
coord.X = csbi.srWindow.Left;
|
||||
else if (coord.X > csbi.srWindow.Right)
|
||||
coord.X = csbi.srWindow.Right;
|
||||
if (coord.Y < csbi.srWindow.Top)
|
||||
coord.Y = csbi.srWindow.Top;
|
||||
else if (coord.Y > csbi.srWindow.Bottom)
|
||||
coord.Y = csbi.srWindow.Bottom;
|
||||
SetConsoleCursorPosition(handle, coord);
|
||||
break;
|
||||
case 'A': // Move up
|
||||
GetConsoleScreenBufferInfo(handle, &csbi);
|
||||
coord = csbi.dwCursorPosition;
|
||||
if (n > 0) {
|
||||
coord.Y = coord.Y - v[0];
|
||||
}
|
||||
else {
|
||||
coord.Y = coord.Y - 1;
|
||||
}
|
||||
if (coord.Y < csbi.srWindow.Top) coord.Y = csbi.srWindow.Top;
|
||||
SetConsoleCursorPosition(handle, coord);
|
||||
SetConsoleTextAttribute(handle, attr);
|
||||
break;
|
||||
case 'B': // Move down
|
||||
GetConsoleScreenBufferInfo(handle, &csbi);
|
||||
coord = csbi.dwCursorPosition;
|
||||
if (n > 0) {
|
||||
coord.Y = coord.Y + v[0];
|
||||
}
|
||||
else {
|
||||
coord.Y = coord.Y + 1;
|
||||
}
|
||||
if (coord.Y > csbi.srWindow.Bottom) coord.Y = csbi.srWindow.Bottom;
|
||||
SetConsoleCursorPosition(handle, coord);
|
||||
SetConsoleTextAttribute(handle, attr);
|
||||
break;
|
||||
case 'C': // Move forward / right
|
||||
GetConsoleScreenBufferInfo(handle, &csbi);
|
||||
coord = csbi.dwCursorPosition;
|
||||
if (n > 0) {
|
||||
coord.X = coord.X + v[0];
|
||||
}
|
||||
else {
|
||||
coord.X = coord.X + 1;
|
||||
}
|
||||
if (coord.X > csbi.srWindow.Right) coord.X = csbi.srWindow.Right;
|
||||
SetConsoleCursorPosition(handle, coord);
|
||||
SetConsoleTextAttribute(handle, attr);
|
||||
break;
|
||||
case 'D': // Move backward / left
|
||||
GetConsoleScreenBufferInfo(handle, &csbi);
|
||||
coord = csbi.dwCursorPosition;
|
||||
if (n > 0) {
|
||||
coord.X = coord.X - v[0];
|
||||
}
|
||||
else {
|
||||
coord.X = coord.X - 1;
|
||||
}
|
||||
if (coord.X < csbi.srWindow.Left) coord.X = csbi.srWindow.Left;
|
||||
SetConsoleCursorPosition(handle, coord);
|
||||
SetConsoleTextAttribute(handle, attr);
|
||||
break;
|
||||
case 's':
|
||||
GetConsoleScreenBufferInfo(handle, &csbi);
|
||||
saved_coord = csbi.dwCursorPosition;
|
||||
break;
|
||||
case 'u':
|
||||
SetConsoleCursorPosition(handle, saved_coord);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return z;
|
||||
}
|
4
MD_AnsiCons.h
Normal file
4
MD_AnsiCons.h
Normal file
@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
#include <stdio.h>
|
||||
|
||||
extern int ansi_write(FILE* fp, const char* buf, int len);
|
@ -4,12 +4,16 @@
|
||||
#include <unistd.h>
|
||||
#if defined(_MSC_VER) || defined(WIN32)
|
||||
#include <winsock2.h>
|
||||
#include "MD_AnsiCons.h"
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#include "MagiDoor.h"
|
||||
|
||||
void md_putchar(char c) {
|
||||
#if defined(_MSC_VER) || defined(WIN32)
|
||||
ansi_write(stdout, &c, 1);
|
||||
#endif
|
||||
if (mdcontrol.socket == -1) {
|
||||
write(STDOUT_FILENO, &c, 1);
|
||||
} else {
|
||||
|
@ -3,7 +3,7 @@ i686-w64-mingw32-gcc -c MD_Init.c
|
||||
i686-w64-mingw32-gcc -c MD_Printf.c
|
||||
i686-w64-mingw32-gcc -c MD_Getc.c
|
||||
i686-w64-mingw32-gcc -c MD_Sendfile.c
|
||||
|
||||
i686-w64-mingw32-gcc -c MD_AnsiCons.c
|
||||
i686-w64-mingw32-gcc -shared -o mdoor.dll *.o -lws2_32 -Wl,--out-implib,libmdoor.a
|
||||
|
||||
rm *.o
|
||||
|
Loading…
x
Reference in New Issue
Block a user