0,0 → 1,381 |
#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 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 |