#include "gr-draw.h" #ifndef _DOS_GRAPHIC_DRAW_H #define _DOS_GRAPHIC_DRAW_H #include "dosmouse.h" #include "keysym.h" #include #include #include #include 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