kolibrios/programs/games/checkers/trunk/dos-draw.h

383 lines
10 KiB
C
Raw Permalink Normal View History

#include "gr-draw.h"
#ifndef _DOS_GRAPHIC_DRAW_H
#define _DOS_GRAPHIC_DRAW_H
#include "dosmouse.h"
#include "keysym.h"
#include <graphics.h>
#include <conio.h>
#include <stdio.h>
#include <limits.h>
class TDosGraphDraw : public TBaseGraphDraw<TDosGraphDraw>
{
typedef TBaseGraphDraw<TDosGraphDraw> TGraphDraw;
public:
TDosGraphDraw(const char *s = 0);
~TDosGraphDraw() {}
public:
static unsigned long GetKeySym(unsigned int key);
protected:
unsigned long bgcolor;
int quit;
TCursorVisible cursor;
public:
unsigned long GetBlackColor() {return 0;}
unsigned long GetWhiteColor() {return 15;}
unsigned long CreateColor(unsigned short red,
unsigned short green, unsigned short blue);
void FreeColor(unsigned long c) {}
unsigned long GetBgColor() {return bgcolor;}
void SetBgColor(unsigned long c) {bgcolor = c;}
int GetStatus() {return (graphresult() == grOk) ? 1 : 0;}
int Init() {return 0;}
int Run(int evmask = 0, int w = INT_MIN, int h = INT_MIN);
void GetSize(int &w, int &h);
int OpenDraw();
int IsDraw() {return graphresult() == grOk && cursor.IsHidden();}
void CloseDraw() {cursor.Show();}
int SetColor(unsigned long c);
int DrawLine(int x0, int y0, int x1, int y1);
int DrawText(int x0, int y0, char *text);
int DrawClear();
int GetTextH(const char *s) {return 8;}
int GetTextW(const char *s) {return 8 * sizeof(s);}
void Quit(int q = 1) {quit = (q > 0) ? q : 0;}
};
unsigned long TDosGraphDraw::GetKeySym(unsigned int key)
{
switch(key)
{
case 331: return XK_Left;
case 333: return XK_Right;
case 328: return XK_Up;
case 336: return XK_Down;
case 13: return XK_Return;
case 32: return XK_space;
case 27: return XK_Escape;
case 44: return XK_comma;
case 46: return XK_period;
case 60: return XK_comma;
case 62: return XK_period;
case 45: return XK_minus;
case 61: return XK_equal;
case 95: return XK_underscore;
case 43: return XK_plus;
case 339: return XK_Delete;
case 47: return XK_slash;
case 63: return XK_question;
case 315: return XK_F1;
case 316: return XK_F2;
case 317: return XK_F3;
case 318: return XK_F4;
case 319: return XK_F5;
case 320: return XK_F6;
case 321: return XK_F7;
case 322: return XK_F8;
case 323: return XK_F9;
case 324: return XK_F10;
case 389: return XK_F11;
case 390: return XK_F12;
case 97: return XK_a;
case 98: return XK_b;
case 99: return XK_c;
case 100: return XK_d;
case 101: return XK_e;
case 102: return XK_f;
case 103: return XK_g;
case 104: return XK_h;
case 105: return XK_i;
case 106: return XK_j;
case 107: return XK_k;
case 108: return XK_l;
case 109: return XK_m;
case 110: return XK_n;
case 111: return XK_o;
case 112: return XK_p;
case 113: return XK_q;
case 114: return XK_r;
case 115: return XK_s;
case 116: return XK_t;
case 117: return XK_u;
case 118: return XK_v;
case 119: return XK_w;
case 120: return XK_x;
case 121: return XK_y;
case 122: return XK_z;
case 65: return XK_A;
case 66: return XK_B;
case 67: return XK_C;
case 68: return XK_D;
case 69: return XK_E;
case 70: return XK_F;
case 71: return XK_G;
case 72: return XK_H;
case 73: return XK_I;
case 74: return XK_J;
case 75: return XK_K;
case 76: return XK_L;
case 77: return XK_M;
case 78: return XK_N;
case 79: return XK_O;
case 80: return XK_P;
case 81: return XK_Q;
case 82: return XK_R;
case 83: return XK_S;
case 84: return XK_T;
case 85: return XK_U;
case 86: return XK_V;
case 87: return XK_W;
case 88: return XK_X;
case 89: return XK_Y;
case 90: return XK_Z;
default: return XK_VoidSymbol;
}
}
TDosGraphDraw::TDosGraphDraw(const char *s) : TGraphDraw(s)
{
bgcolor = GetWhiteColor();
}
unsigned long TDosGraphDraw::CreateColor(unsigned short red,
unsigned short green, unsigned short blue)
{
const unsigned short PD = 12288U, PM = 36863U, PL = 65535U;
const unsigned short COLOR[16][3] =
{{0U, 0U, 0U}, {0U, 0U, PM}, {0U, PM, 0U}, {0U, PM, PM},
{PM, 0U, 0U}, {PM, 0U, PM}, {PM, PM, 0U}, {PM, PM, PM},
{PD, PD, PD}, {PD, PD, PL}, {PD, PL, PD}, {PD, PL, PL},
{PL, PD, PD}, {PL, PD, PL}, {PL, PL, PD}, {PL, PL, PL}};
int b[3];
if (red > green)
{
if (green > blue) {b[0] = 4; b[1] = 2; b[2] = 1;}
else if (red > blue) {b[0] = 4; b[1] = 1; b[2] = 2;}
else {b[0] = 1; b[1] = 4; b[2] = 2;}
}
else
{
if (red > blue) {b[0] = 2; b[1] = 4; b[2] = 1;}
else if (green > blue) {b[0] = 2; b[1] = 1; b[2] = 4;}
else {b[0] = 1; b[1] = 2; b[2] = 4;}
}
int i, j, c, c0 = 0;
long d, d0 = LONG_MAX;
for (j = 0; j <= 8; j += 8) for (i = 0, c = j; i <= 3; c |= b[i++])
{
d = labs((long)red - COLOR[c][0]) + labs((long)green - COLOR[c][1]) +
labs((long)blue - COLOR[c][2]);
if (d0 >= d) {d0 = d; c0 = c;}
}
return c0;
}
void TDosGraphDraw::GetSize(int &w, int &h)
{
if (graphresult() == grOk)
{
w = getmaxx() + 1; h = getmaxy() + 1;
}
else TGraphDraw::GetSize(w, h);
}
int TDosGraphDraw::OpenDraw()
{
if (graphresult() == grOk)
{
cursor.Hide();
return 1;
}
else return 0;
}
int TDosGraphDraw::SetColor(unsigned long c)
{
if (!IsDraw()) return 0;
else {setcolor((int)c); return 1;}
}
int TDosGraphDraw::DrawLine(int x0, int y0, int x1, int y1)
{
if (!IsDraw()) return 0;
else {line(x0, y0, x1, y1); return 1;}
}
int TDosGraphDraw::DrawText(int x0, int y0, char *text)
{
if (!IsDraw()) return 0;
else {outtextxy(x0, y0, text); return 1;}
}
int TDosGraphDraw::DrawClear()
{
if (!IsDraw()) return 0;
setbkcolor((int)bgcolor); setcolor((int)bgcolor);
bar(0, 0, getmaxx(), getmaxy());
setbkcolor(0);
return 1;
}
int TDosGraphDraw::Run(int evmask, int /*w*/, int /*h*/)
{
if (!evfunc) return -2;
int wasgraph = graphresult();
if (!wasgraph)
{
int gdriver = DETECT, gmode, errorcode;
initgraph(&gdriver, &gmode, "");
if ((errorcode = graphresult()) != grOk)
{
printf("Graphics error: %s\n", grapherrormsg(errorcode));
return -1;
}
}
event ev;
int ch = INT_MIN, stpr = 0;
int old_mx = -1000, old_my = -1000;
clock_t old_mtime = clock();
int show_cur = TCursorVisible::C.IsShowed();
freopen("NUL", "wt", stdout);
quit = 0;
while (quit == 0)
{
if (stpr == 0)
{
ev.type = event::start;
ev.any.drw = this;
evfunc(ev);
CloseDraw();
stpr = 1;
}
else if (stpr == 1)
{
ev.type = event::draw;
ev.any.drw = this;
evfunc(ev);
CloseDraw();
stpr = 2;
}
else if (ch >= 0 && (evmask & key_down_mask))
{
ev.type = event::key_up;
ev.key.drw = this;
ev.key.k = ch;
evfunc(ev);
CloseDraw();
ch = INT_MIN;
}
else if (kbhit())
{
if (MouseStatus && TCursorVisible::C.IsShowed() &&
(unsigned long)(clock() - old_mtime) > 5 * CLK_TCK)
{
TCursorVisible::C.Hide();
old_mtime = clock();
}
int ch = (unsigned char)getch();
if (!ch && kbhit()) ch = 0x100 | (unsigned char)getch();
if (evmask & key_down_mask)
{
ev.type = event::key_down;
ev.key.drw = this;
ev.key.k = GetKeySym(ch);
evfunc(ev);
CloseDraw();
}
}
else if (MouseStatus && (evmask & (button_down_mask |
button_up_mask | mouse_move_mask | mouse_drag_mask)))
{
int k, x, y, z;
for (k = 0; k < MouseStatus; k++)
{
z = GetButtonDown(k, x, y);
if (z)
{
TCursorVisible::C.Show();
old_mx = x; old_my = y;
old_mtime = clock();
if (evmask & button_down_mask)
{
ev.type = event::button_down;
ev.button.drw = this;
ev.button.x = x; ev.button.y = y;
ev.button.n = k + 1;
evfunc(ev);
CloseDraw();
}
old_mtime = clock();
k = -1; break;
}
z = GetButtonUp(k, x, y);
if (z)
{
TCursorVisible::C.Show();
old_mx = x; old_my = y;
old_mtime = clock();
if (evmask & button_up_mask)
{
ev.type = event::button_up;
ev.button.drw = this;
ev.button.x = x; ev.button.y = y;
ev.button.n = k + 1;
evfunc(ev);
CloseDraw();
}
k = -1; break;
}
}
if (k >= 0)
{
z = PosCursor(x, y);
if (x != old_mx || y != old_my)
{
TCursorVisible::C.Show();
old_mx = x; old_my = y;
old_mtime = clock();
if (evmask & (mouse_move_mask | mouse_drag_mask))
{
for (k = 0; k < MouseStatus; k++)
{
if (z & (1 << k)) break;
}
if (evmask & ((k == MouseStatus) ? mouse_move_mask : mouse_drag_mask))
{
ev.type = event::mouse_move;
ev.button.drw = this;
ev.button.x = x; ev.button.y = y;
ev.button.n = (k >= MouseStatus) ? 0 : (k + 1);
evfunc(ev);
CloseDraw();
}
}
}
else if (TCursorVisible::C.IsShowed() &&
(unsigned long)(clock() - old_mtime) > 30 * CLK_TCK)
{
TCursorVisible::C.Hide();
old_mtime = clock();
}
}
}
if (quit == 1)
{
ev.type = event::close;
ev.any.drw = this;
Quit(evfunc(ev));
CloseDraw();
}
}
TCursorVisible::C.Set(show_cur);
if (!wasgraph) closegraph();
freopen("CON", "wt", stdout);
return quit;
}
#endif //_DOS_GRAPHIC_DRAW_H