Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. #include <windows.h>
  2. #include <string.h>
  3. #include <process.h>
  4. #include <stdio.h>
  5. #include <math.h>
  6. #include <assert.h>
  7. #include <deque.h>
  8.  
  9. #include <menuet.h>
  10. #include <me_heap.h>
  11. #include <me_file.h>
  12.  
  13. using namespace Menuet;
  14. using namespace std;
  15.  
  16. const char file_prefix[] = "";
  17. bool WasThreadCreatedBool = false;
  18.  
  19. struct TExceptToMessageLoop
  20. {
  21.         TExceptToMessageLoop() {}
  22. };
  23.  
  24. struct TThreadDataStruct
  25. {
  26.         void *user;
  27.         void *stack_begin;
  28.         TWindowData *win_data;
  29.         HWND hwnd;
  30.         int flag;
  31.         unsigned int win_time, me_time;
  32.         void *picture;
  33.         unsigned int picture_width, picture_height;
  34.         deque<unsigned char> *keys;
  35.         unsigned int bmp_data_length;
  36.         unsigned int *bmp_data;
  37.         unsigned int mouse_state;
  38. };
  39.  
  40. TThreadDataStruct /*__thread*/ ThreadDataStruct;
  41. int nCmdShow;
  42. HINSTANCE hInstance;
  43. const char szWindowClass[] = "Menuet window";
  44.  
  45. void FinalizeThreadData()
  46. {
  47.         if (ThreadDataStruct.keys)
  48.         {
  49.                 delete ThreadDataStruct.keys;
  50.                 ThreadDataStruct.keys = 0;
  51.         }
  52.         if (ThreadDataStruct.bmp_data)
  53.         {
  54.                 delete[] ThreadDataStruct.bmp_data;
  55.                 ThreadDataStruct.bmp_data = 0;
  56.         }
  57. }
  58.  
  59. unsigned int CalculateNewTime()
  60. {
  61.         unsigned int t = GetTickCount();
  62.         unsigned int dt = (unsigned int)(t - ThreadDataStruct.win_time) / 10U;
  63.         ThreadDataStruct.me_time += dt;
  64.         ThreadDataStruct.win_time += dt * 10;
  65.         return t;
  66. }
  67.  
  68. void DrawPicture(HDC hdc)
  69. {
  70.         TRecMutex xm;
  71.         InitRecMutex(&xm);
  72.         Lock(&xm);
  73.         UnLock(&xm);
  74.  
  75.         int w = ThreadDataStruct.picture_width, h = ThreadDataStruct.picture_height;
  76.         RECT rect;
  77.         if (!ThreadDataStruct.picture || !ThreadDataStruct.hwnd || w <= 0 || h <= 0) return;
  78.         if (GetClientRect(ThreadDataStruct.hwnd, &rect))
  79.         {
  80.                 rect.right -= rect.left; rect.left = 0;
  81.                 rect.bottom -= rect.top; rect.top = 0;
  82.                 if (rect.right <= 0 || rect.bottom <= 0) return;
  83.                 if (w > rect.right) w = rect.right;
  84.                 if (h > rect.bottom) h = rect.bottom;
  85.         }
  86.         if (!ThreadDataStruct.bmp_data || ThreadDataStruct.bmp_data_length < w * h)
  87.         {
  88.                 if (ThreadDataStruct.bmp_data) delete[] ThreadDataStruct.bmp_data;
  89.                 ThreadDataStruct.bmp_data_length = w * h;
  90.                 ThreadDataStruct.bmp_data = new unsigned int[ThreadDataStruct.bmp_data_length];
  91.         }
  92.         int i;
  93.         unsigned char *p = (unsigned char*)ThreadDataStruct.picture;
  94.         for (i = 0; i < w * h; i++)
  95.         {
  96.                 ThreadDataStruct.bmp_data[i] = ((unsigned int)p[0]) +
  97.                                 ((unsigned int)p[1] << 8) + ((unsigned int)p[2] << 16);
  98.                 p += 3;
  99.         }
  100.         HBITMAP bitmap = CreateBitmap(w, h, 1, 32, ThreadDataStruct.bmp_data);
  101.         if (bitmap)
  102.         {
  103.                 HDC memdc = CreateCompatibleDC(hdc);
  104.                 if (memdc)
  105.                 {
  106.                         SelectObject(memdc, bitmap);
  107.                         BitBlt(hdc, 0, 0, w, h, memdc, 0, 0, SRCCOPY);
  108.                         DeleteObject(memdc);
  109.                 }
  110.                 DeleteObject(bitmap);
  111.         }
  112. }
  113.  
  114. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  115. {
  116.         const int timeout = 20;
  117.         unsigned int t;
  118.         PAINTSTRUCT ps;
  119.         HDC hdc;
  120.         if (hWnd == ThreadDataStruct.hwnd && ThreadDataStruct.flag != -1)
  121.         {
  122.                 int window_rect[4];
  123.                 switch (message)
  124.                 {
  125.                 case WM_CREATE:
  126.                         SetTimer(hWnd, 0, timeout, NULL);
  127.                         SendMessage(hWnd, WM_SIZE, SIZE_RESTORED, 0);
  128.                         return 0;
  129.                 case WM_TIMER:
  130.                         t = CalculateNewTime();
  131.                         while (MenuetOnIdle((TThreadData)(&ThreadDataStruct)) == 0 &&
  132.                                         GetTickCount() - t + 2 < timeout);
  133.                         return 0;
  134.                 case WM_MOUSEMOVE:
  135.                         MenuetOnMouse((TThreadData)(&ThreadDataStruct));
  136.                         return 0;
  137.                 case WM_LBUTTONDOWN:
  138.                         if (!ThreadDataStruct.mouse_state) SetCapture(hWnd);
  139.                         ThreadDataStruct.mouse_state |= 1;
  140.                         MenuetOnMouse((TThreadData)(&ThreadDataStruct));
  141.                         return 0;
  142.                 case WM_LBUTTONUP:
  143.                         if (ThreadDataStruct.mouse_state & 1)
  144.                         {
  145.                                 ThreadDataStruct.mouse_state &= ~1;
  146.                                 if (!ThreadDataStruct.mouse_state) ReleaseCapture();
  147.                                 MenuetOnMouse((TThreadData)(&ThreadDataStruct));
  148.                         }
  149.                         return 0;
  150.                 case WM_RBUTTONDOWN:
  151.                         if (!ThreadDataStruct.mouse_state) SetCapture(hWnd);
  152.                         ThreadDataStruct.mouse_state |= 2;
  153.                         MenuetOnMouse((TThreadData)(&ThreadDataStruct));
  154.                         return 0;
  155.                 case WM_RBUTTONUP:
  156.                         if (ThreadDataStruct.mouse_state & 2)
  157.                         {
  158.                                 ThreadDataStruct.mouse_state &= ~2;
  159.                                 if (!ThreadDataStruct.mouse_state) ReleaseCapture();
  160.                                 MenuetOnMouse((TThreadData)(&ThreadDataStruct));
  161.                         }
  162.                         return 0;
  163.                 case WM_CAPTURECHANGED:
  164.                         if (ThreadDataStruct.mouse_state)
  165.                         {
  166.                                 ThreadDataStruct.mouse_state = 0;
  167.                                 MenuetOnMouse((TThreadData)(&ThreadDataStruct));
  168.                         }
  169.                         return 0;
  170.                 //case WM_SYSKEYDOWN: case WM_KEYDOWN:
  171.                 case WM_CHAR:
  172.                         ThreadDataStruct.keys->push_back((unsigned char)wParam);
  173.                         MenuetOnKeyPress((TThreadData)(&ThreadDataStruct));
  174.                         return 0;
  175.                 case WM_SIZE:
  176.                         GetProcessInfo(0, 0, 0, 0, window_rect);
  177.                         MenuetOnSize(window_rect, (TThreadData)(&ThreadDataStruct));
  178.                         InvalidateRect(hWnd, 0, 0);
  179.                         return 0;
  180.                 case WM_PAINT:
  181.                         hdc = BeginPaint(hWnd, &ps);
  182.                         if (ThreadDataStruct.picture) DrawPicture(hdc);
  183.                         EndPaint(hWnd, &ps);
  184.                         return 0;
  185.                 case WM_CLOSE:
  186.                         if (MenuetOnClose((TThreadData)(&ThreadDataStruct)))
  187.                         {
  188.                                 ThreadDataStruct.flag = -1;
  189.                         }
  190.                         else return 0;
  191.                 case WM_DESTROY:
  192.                         PostQuitMessage(0);
  193.                         return 0;
  194.                 }
  195.         }
  196.         return DefWindowProc(hWnd, message, wParam, lParam);
  197. }
  198.  
  199. ATOM MyRegisterClass()
  200. {
  201.         HBRUSH background = CreateSolidBrush(RGB(0, 0, 0));
  202.         WNDCLASSEX wcex;
  203.         wcex.cbSize = sizeof(WNDCLASSEX);
  204.         wcex.style                      = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
  205.         wcex.lpfnWndProc        = (WNDPROC)WndProc;
  206.         wcex.cbClsExtra         = 0;
  207.         wcex.cbWndExtra         = 0;
  208.         wcex.hInstance          = hInstance;
  209.         wcex.hIcon                      = 0;
  210.         wcex.hCursor            = LoadCursor(NULL, IDC_ARROW);
  211.         wcex.hbrBackground      = background;
  212.         wcex.lpszMenuName       = NULL;
  213.         wcex.lpszClassName      = szWindowClass;
  214.         wcex.hIconSm            = 0;
  215.         ATOM ret = RegisterClassEx(&wcex);
  216.         DeleteObject(background);
  217.         return ret;
  218. }
  219.  
  220. HWND InitInstance(int x, int y, int w, int h)
  221. {
  222.         HWND hWnd;
  223.         MyRegisterClass();
  224.         DWORD style = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, exstyle = 0;
  225.         hWnd = CreateWindowEx(exstyle, szWindowClass, ThreadDataStruct.win_data->Title, style,
  226.                                 x, y, w, h, NULL, NULL, hInstance, NULL);
  227.         if (!hWnd) return NULL;
  228.         ShowWindow(hWnd, nCmdShow);
  229.         UpdateWindow(hWnd);
  230.         return hWnd;
  231. }
  232.  
  233. int ThreadMainProc(void *user)
  234. {
  235.         ThreadMain(user, 0);
  236.         return 0;
  237. }
  238.  
  239. namespace Menuet
  240. {
  241.         void Main() {ThreadMain();}
  242.  
  243.         void* ThreadMain(void *user, void *stack_begin)
  244.         {
  245.                 TStartData start_data;
  246.                 ThreadDataStruct.user = user;
  247.                 ThreadDataStruct.stack_begin = stack_begin;
  248.                 ThreadDataStruct.win_data = &start_data.WinData;
  249.                 ThreadDataStruct.hwnd = 0;
  250.                 ThreadDataStruct.flag = 0;
  251.                 ThreadDataStruct.win_time = GetTickCount();
  252.                 ThreadDataStruct.me_time = ThreadDataStruct.win_time / 10;
  253.                 ThreadDataStruct.keys = new deque<unsigned char>;
  254.                 ThreadDataStruct.bmp_data_length = 0;
  255.                 ThreadDataStruct.bmp_data = 0;
  256.                 ThreadDataStruct.mouse_state = 0;
  257.                 start_data.Left = 50; start_data.Width = 256;
  258.                 start_data.Top = 50; start_data.Height = 256;
  259.                 start_data.WinData.WindowType = 0x03;
  260.                 start_data.WinData.HeaderType = 0x80;
  261.                 start_data.WinData.WindowColor = 0xFFFFFF;
  262.                 start_data.WinData.HeaderColor = 0x6060FF;
  263.                 start_data.WinData.BorderColor = 0x000000;
  264.                 start_data.WinData.TitleColor = 0xFFFF40;
  265.                 start_data.WinData.Title = 0;
  266.                 if (MenuetOnStart(start_data, (TThreadData)(&ThreadDataStruct)))
  267.                 {
  268.                         while (ThreadDataStruct.flag < 0)
  269.                         {
  270.                                 ThreadDataStruct.flag &= ~0x80000000;
  271.                                 if (MenuetOnClose((TThreadData)(&ThreadDataStruct)))
  272.                                 {
  273.                                         ThreadDataStruct.flag = -1;
  274.                                         break;
  275.                                 }
  276.                         }
  277.                         if (ThreadDataStruct.flag >= 0)
  278.                         {
  279.                                 assert((ThreadDataStruct.hwnd = InitInstance(start_data.Left,
  280.                                                         start_data.Top, start_data.Width, start_data.Height)) != NULL);
  281.                                 assert(SendMessage(ThreadDataStruct.hwnd, WM_CREATE, 0, 0) == 0);
  282.                                 MSG msg;
  283.                                 HACCEL hAccelTable = 0;
  284.                                 while (GetMessage(&msg, NULL, 0, 0))
  285.                                 {
  286.                                         if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
  287.                                         {
  288.                                                 TranslateMessage(&msg);
  289.                                                 DispatchMessage(&msg);
  290.                                         }
  291.                                 }
  292.                         }
  293.                         assert(ThreadDataStruct.flag == -1);
  294.                 }
  295.                 FinalizeThreadData();
  296.                 return ThreadDataStruct.stack_begin;
  297.         }
  298.  
  299.         void GetWindowData(TWindowData &win_data)
  300.         {
  301.                 win_data = *ThreadDataStruct.win_data;
  302.         }
  303.  
  304.         void GetWindowData(TWindowData &win_data, TThreadData thread_data)
  305.         {
  306.                 win_data = *((TThreadDataStruct*)thread_data)->win_data;
  307.         }
  308.  
  309.         void SetWindowData(const TWindowData &win_data)
  310.         {
  311.                 *ThreadDataStruct.win_data = win_data;
  312.                 if (ThreadDataStruct.hwnd)
  313.                 {
  314.                         SetWindowText(ThreadDataStruct.hwnd, ThreadDataStruct.win_data->Title);
  315.                         InvalidateRect(ThreadDataStruct.hwnd, NULL, FALSE);
  316.                 }
  317.         }
  318.  
  319.         void SetWindowData(const TWindowData &win_data, TThreadData thread_data)
  320.         {
  321.                 *((TThreadDataStruct*)thread_data)->win_data = win_data;
  322.                 if (((TThreadDataStruct*)thread_data)->hwnd)
  323.                 {
  324.                         SetWindowText(((TThreadDataStruct*)thread_data)->hwnd,
  325.                                                 ((TThreadDataStruct*)thread_data)->win_data->Title);
  326.                         InvalidateRect(((TThreadDataStruct*)thread_data)->hwnd, NULL, FALSE);
  327.                 }
  328.         }
  329.  
  330.         void CloseWindow()
  331.         {
  332.                 if (ThreadDataStruct.hwnd)
  333.                 {
  334.                         SendMessage(ThreadDataStruct.hwnd, WM_CLOSE, 0, 0);
  335.                 }
  336.                 else ThreadDataStruct.flag |= 0x80000000;
  337.         }
  338.  
  339.         void CloseWindow(TThreadData thread_data)
  340.         {
  341.                 if (((TThreadDataStruct*)thread_data)->hwnd)
  342.                 {
  343.                         SendMessage(((TThreadDataStruct*)thread_data)->hwnd, WM_CLOSE, 0, 0);
  344.                 }
  345.                 else ((TThreadDataStruct*)thread_data)->flag |= 0x80000000;
  346.         }
  347.  
  348.         void Redraw(int /*frame*/)
  349.         {
  350.                 if (ThreadDataStruct.hwnd)
  351.                 {
  352.                         InvalidateRect(ThreadDataStruct.hwnd, NULL, FALSE);
  353.                         SendMessage(ThreadDataStruct.hwnd, WM_PAINT, 0, 0);
  354.                 }
  355.         }
  356.  
  357.         void Redraw(int /*frame*/, TThreadData thread_data)
  358.         {
  359.                 if (((TThreadDataStruct*)thread_data)->hwnd)
  360.                 {
  361.                         InvalidateRect(((TThreadDataStruct*)thread_data)->hwnd, NULL, FALSE);
  362.                         SendMessage(((TThreadDataStruct*)thread_data)->hwnd, WM_PAINT, 0, 0);
  363.                 }
  364.         }
  365.  
  366.         void Invalidate(int /*frame*/)
  367.         {
  368.                 if (ThreadDataStruct.hwnd)
  369.                 {
  370.                         InvalidateRect(ThreadDataStruct.hwnd, NULL, FALSE);
  371.                 }
  372.         }
  373.  
  374.         void Invalidate(int /*frame*/, TThreadData thread_data)
  375.         {
  376.                 if (((TThreadDataStruct*)thread_data)->hwnd)
  377.                 {
  378.                         InvalidateRect(((TThreadDataStruct*)thread_data)->hwnd, NULL, FALSE);
  379.                 }
  380.         }
  381.  
  382.         void MoveWindow(const int window_rect[/* 4 */])
  383.         {
  384.                 if (!ThreadDataStruct.hwnd) return;
  385.                 RECT rect;
  386.                 if (window_rect[0] == -1 || window_rect[1] == -1 ||
  387.                         window_rect[2] == -1 || window_rect[3] == -1)
  388.                 {
  389.                         if (!GetWindowRect(ThreadDataStruct.hwnd, &rect)) return;
  390.                         ::MoveWindow(ThreadDataStruct.hwnd,
  391.                                         (window_rect[0] == -1) ? rect.left : window_rect[0],
  392.                                         (window_rect[1] == -1) ? rect.top : window_rect[1],
  393.                                         (window_rect[2] == -1) ? (rect.right - rect.left) : window_rect[2],
  394.                                         (window_rect[3] == -1) ? (rect.bottom - rect.top) : window_rect[3], TRUE);
  395.                 }
  396.                 else
  397.                 {
  398.                         ::MoveWindow(ThreadDataStruct.hwnd, window_rect[0],
  399.                                         window_rect[1], window_rect[2], window_rect[3], TRUE);
  400.                 }
  401.         }
  402.  
  403.         void Abort()
  404.         {
  405.                 if (ThreadDataStruct.hwnd) KillTimer(ThreadDataStruct.hwnd, 0);
  406.                 abort();
  407.         }
  408.  
  409.         void ExitProcess() {::ExitProcess(0);}
  410.  
  411.         void ExitThread() {FinalizeThreadData(); ::ExitThread(0);}
  412.  
  413.         void ExitThread(TThreadData) {FinalizeThreadData(); ::ExitThread(0);}
  414.  
  415.         void ReturnMessageLoop()
  416.         {
  417.                 TExceptToMessageLoop ex;
  418.                 throw(ex);
  419.         }
  420.  
  421.         void ReturnMessageLoop(TThreadData)
  422.         {
  423.                 TExceptToMessageLoop ex;
  424.                 throw(ex);
  425.         }
  426.  
  427.         void Delay(unsigned int time) {Sleep(time * 10);}
  428.  
  429.         unsigned int Clock() {CalculateNewTime(); return ThreadDataStruct.me_time;}
  430.  
  431.         int GetPackedTime()
  432.         {
  433.                 SYSTEMTIME time;
  434.                 GetSystemTime(&time);
  435.                 int t;
  436.                 t = (time.wSecond / 10) * 16 + (time.wSecond % 10);
  437.                 t = (time.wMinute / 10) * 16 + (time.wMinute % 10) + (t << 8);
  438.                 t = (time.wHour / 10) * 16 + (time.wHour % 10) + (t << 8);
  439.                 return t;
  440.         }
  441.  
  442.         void GetTime(int t[/* 3 */])
  443.         {
  444.                 SYSTEMTIME time;
  445.                 GetSystemTime(&time);
  446.                 t[0] = time.wSecond;
  447.                 t[1] = time.wMinute;
  448.                 t[2] = time.wHour;
  449.         }
  450.  
  451.         int GetPackedDate()
  452.         {
  453.                 SYSTEMTIME time;
  454.                 GetSystemTime(&time);
  455.                 int t;
  456.                 t = ((time.wYear / 10) % 10) * 16 + (time.wYear % 10);
  457.                 t = (time.wDay / 10) * 16 + (time.wDay % 10) + (t << 8);
  458.                 t = (time.wMonth / 10) * 16 + (time.wMonth % 10) + (t << 8);
  459.                 return t;
  460.         }
  461.  
  462.         void GetDate(int d[/* 3 */])
  463.         {
  464.                 SYSTEMTIME time;
  465.                 GetSystemTime(&time);
  466.                 d[0] = time.wDay;
  467.                 d[1] = time.wMonth;
  468.                 d[2] = time.wYear;
  469.         }
  470.  
  471.         void GetTimeDate(int t[/* 6 */])
  472.         {
  473.                 SYSTEMTIME time;
  474.                 GetSystemTime(&time);
  475.                 t[0] = time.wSecond;
  476.                 t[1] = time.wMinute;
  477.                 t[2] = time.wHour;
  478.                 t[3] = time.wDay;
  479.                 t[4] = time.wMonth;
  480.                 t[5] = time.wYear;
  481.         }
  482.  
  483.         void ReadCommonColors(unsigned int colors[/* 10 */])
  484.         {
  485.                 int i;
  486.                 for (i = 0; i < 10; i++) colors[i] = 0;
  487.         }
  488.  
  489.         unsigned int GetProcessInfo(unsigned int *use_cpu, char process_name[/* 13 */], unsigned int *use_memory,
  490.                                                                 unsigned int *pid, int window_rect[/* 4 */], unsigned int pid_for)
  491.         {
  492.                 if (use_cpu) *use_cpu = 0;
  493.                 if (process_name) strcpy(process_name, "noname");
  494.                 if (use_memory) *use_memory = 0;
  495.                 if (pid)
  496.                 {
  497.                         if ((pid_for | 15) == -1) pid_for = getpid();
  498.                         *pid = pid_for;
  499.                 }
  500.                 if (window_rect)
  501.                 {
  502.                         RECT rect;
  503.                         if (ThreadDataStruct.hwnd && GetWindowRect(ThreadDataStruct.hwnd, &rect))
  504.                         {
  505.                                 window_rect[0] = rect.left;
  506.                                 window_rect[1] = rect.top;
  507.                                 window_rect[2] = rect.right - rect.left;
  508.                                 window_rect[3] = rect.bottom - rect.top;
  509.                         }
  510.                         else
  511.                         {
  512.                                 window_rect[0] = 0; window_rect[1] = 0;
  513.                                 window_rect[2] = 0; window_rect[3] = 0;
  514.                         }
  515.                 }
  516.                 return 1;
  517.         }
  518.  
  519.         unsigned int GetPid() {return GetCurrentThreadId();}
  520.  
  521.         unsigned int GetPid(TThreadData /*thread_data*/) {return GetCurrentThreadId();}
  522.  
  523.         TThreadData GetThreadData() {return (TThreadData)(&ThreadDataStruct);}
  524.  
  525.         TThreadData GetThreadData(unsigned int /*pid*/) {return (TThreadData)(&ThreadDataStruct);}
  526.  
  527.         void* GetPicture(unsigned short &width, unsigned short &height)
  528.         {
  529.                 width = (unsigned short)ThreadDataStruct.picture_width;
  530.                 height = (unsigned short)ThreadDataStruct.picture_height;
  531.                 return ThreadDataStruct.picture;
  532.         }
  533.  
  534.         void* GetPicture(unsigned short &width, unsigned short &height, TThreadData thread_data)
  535.         {
  536.                 width = (unsigned short)((TThreadDataStruct*)thread_data)->picture_width;
  537.                 height = (unsigned short)((TThreadDataStruct*)thread_data)->picture_height;
  538.                 return ((TThreadDataStruct*)thread_data)->picture;
  539.         }
  540.        
  541.         void SetPicture(void *picture, unsigned short width, unsigned short height)
  542.         {
  543.                 ThreadDataStruct.picture_width = width;
  544.                 ThreadDataStruct.picture_height = height;
  545.                 ThreadDataStruct.picture = picture;
  546.                 if (ThreadDataStruct.hwnd)
  547.                 {
  548.                         InvalidateRect(ThreadDataStruct.hwnd, NULL, FALSE);
  549.                 }
  550.         }
  551.  
  552.         void SetPicture(void *picture, unsigned short width, unsigned short height, TThreadData thread_data)
  553.         {
  554.                 ((TThreadDataStruct*)thread_data)->picture_width = width;
  555.                 ((TThreadDataStruct*)thread_data)->picture_height = height;
  556.                 ((TThreadDataStruct*)thread_data)->picture = picture;
  557.                 if (((TThreadDataStruct*)thread_data)->hwnd)
  558.                 {
  559.                         InvalidateRect(((TThreadDataStruct*)thread_data)->hwnd, NULL, FALSE);
  560.                 }
  561.         }
  562.  
  563.         void GetBorderHeader(unsigned short &border_size, unsigned short &header_size)
  564.         {
  565.                 border_size = (unsigned short)GetSystemMetrics(SM_CXFRAME);
  566.                 header_size = (unsigned short)(GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYCAPTION));
  567.         }
  568.  
  569.         void GetBorderHeader(unsigned short &border_size, unsigned short &header_size, TThreadData /*thread_data*/)
  570.         {
  571.                 border_size = (unsigned short)GetSystemMetrics(SM_CXFRAME);
  572.                 header_size = (unsigned short)(GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYCAPTION));
  573.         }
  574.  
  575.         void GetClientSize(unsigned short &width, unsigned short &height)
  576.         {
  577.                 if (!ThreadDataStruct.hwnd) {width = 0; height = 0; return;}
  578.                 RECT rect;
  579.                 GetClientRect(ThreadDataStruct.hwnd, &rect);
  580.                 width = (unsigned short)(rect.right - rect.left);
  581.                 height = (unsigned short)(rect.bottom - rect.top);
  582.         }
  583.  
  584.         void GetClientSize(unsigned short &width, unsigned short &height, TThreadData thread_data)
  585.         {
  586.                 if (!((TThreadDataStruct*)thread_data)->hwnd) {width = 0; height = 0; return;}
  587.                 RECT rect;
  588.                 GetClientRect(((TThreadDataStruct*)thread_data)->hwnd, &rect);
  589.                 width = (unsigned short)(rect.right - rect.left);
  590.                 height = (unsigned short)(rect.bottom - rect.top);
  591.         }
  592.  
  593.         void GetClientSize(unsigned short &width, unsigned short &height, int win_width, int win_height)
  594.         {
  595.                 win_width -= 2*GetSystemMetrics(SM_CXFRAME);
  596.                 win_height -= 2*GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYCAPTION);
  597.                 if (win_width < 0) win_width = 0;
  598.                 if (win_height < 0) win_height = 0;
  599.                 width = (unsigned short)win_width; height = (unsigned short)win_height;
  600.         }
  601.  
  602.         void GetClientSize(unsigned short &width, unsigned short &height,
  603.                                                 int win_width, int win_height, TThreadData /*thread_data*/)
  604.         {
  605.                 win_width -= 2*GetSystemMetrics(SM_CXFRAME);
  606.                 win_height -= 2*GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYCAPTION);
  607.                 if (win_width < 0) win_width = 0;
  608.                 if (win_height < 0) win_height = 0;
  609.                 width = (unsigned short)win_width; height = (unsigned short)win_height;
  610.         }
  611.  
  612.         void GetScreenSize(unsigned short &width, unsigned short &height)
  613.         {
  614.                 width = (unsigned short)GetSystemMetrics(SM_CXFULLSCREEN);
  615.                 height = (unsigned short)GetSystemMetrics(SM_CYFULLSCREEN);
  616.         }
  617.  
  618.         TMutex::TMutex() {mut = (unsigned int)CreateMutex(NULL, FALSE, NULL);}
  619.  
  620.         TMutex::~TMutex() {if (mut) {CloseHandle((HANDLE)mut); mut = 0;}}
  621.  
  622.         TRecMutex::TRecMutex() {mut = (unsigned int)CreateMutex(NULL, FALSE, NULL);}
  623.  
  624.         TRecMutex::~TRecMutex() {if (mut) {CloseHandle((HANDLE)mut); mut = 0;}}
  625.  
  626.         void InitMutex(TMutex *mutex) {if (!mutex->mut) *mutex = TMutex();}
  627.  
  628.         void InitRecMutex(TRecMutex *mutex) {if (!mutex->mut) *mutex = TRecMutex();}
  629.  
  630.         bool TryLock(TMutex *mutex)
  631.         {
  632.                 DWORD ret = WaitForSingleObject((HANDLE)mutex->mut, 0);
  633.                 return ret == WAIT_OBJECT_0 || ret == WAIT_ABANDONED;
  634.         }
  635.  
  636.         bool TryLock(TRecMutex *mutex, unsigned int /*pid*/)
  637.         {
  638.                 DWORD ret = WaitForSingleObject((HANDLE)mutex->mut, 0);
  639.                 return ret == WAIT_OBJECT_0 || ret == WAIT_ABANDONED;
  640.         }
  641.  
  642.         bool TryLock(TRecMutex *mutex)
  643.         {
  644.                 DWORD ret = WaitForSingleObject((HANDLE)mutex->mut, 0);
  645.                 return ret == WAIT_OBJECT_0 || ret == WAIT_ABANDONED;
  646.         }
  647.  
  648.         bool TryLock(TRecMutex *mutex, TThreadData /*thread_data*/)
  649.         {
  650.                 DWORD ret = WaitForSingleObject((HANDLE)mutex->mut, 0);
  651.                 return ret == WAIT_OBJECT_0 || ret == WAIT_ABANDONED;
  652.         }
  653.  
  654.         void Lock(TMutex *mutex)
  655.         {
  656.                 WaitForSingleObject((HANDLE)mutex->mut, INFINITE);
  657.         }
  658.  
  659.         void Lock(TRecMutex *mutex, unsigned int /*pid*/)
  660.         {
  661.                 WaitForSingleObject((HANDLE)mutex->mut, INFINITE);
  662.         }
  663.  
  664.         void Lock(TRecMutex *mutex)
  665.         {
  666.                 WaitForSingleObject((HANDLE)mutex->mut, INFINITE);
  667.         }
  668.  
  669.         void Lock(TRecMutex *mutex, TThreadData /*thread_data*/)
  670.         {
  671.                 WaitForSingleObject((HANDLE)mutex->mut, INFINITE);
  672.         }
  673.  
  674.         bool LockTime(TMutex *mutex, unsigned int time)
  675.         {
  676.                 DWORD ret = WaitForSingleObject((HANDLE)mutex->mut, time * 10);
  677.                 return ret == WAIT_OBJECT_0 || ret == WAIT_ABANDONED;
  678.         }
  679.  
  680.         bool LockTime(TRecMutex *mutex, unsigned int time, unsigned int /*pid*/)
  681.         {
  682.                 DWORD ret = WaitForSingleObject((HANDLE)mutex->mut, time * 10);
  683.                 return ret == WAIT_OBJECT_0 || ret == WAIT_ABANDONED;
  684.         }
  685.  
  686.         bool LockTime(TRecMutex *mutex, unsigned int time)
  687.         {
  688.                 DWORD ret = WaitForSingleObject((HANDLE)mutex->mut, time * 10);
  689.                 return ret == WAIT_OBJECT_0 || ret == WAIT_ABANDONED;
  690.         }
  691.  
  692.         bool LockTime(TRecMutex *mutex, unsigned int time, TThreadData /*thread_data*/)
  693.         {
  694.                 DWORD ret = WaitForSingleObject((HANDLE)mutex->mut, time * 10);
  695.                 return ret == WAIT_OBJECT_0 || ret == WAIT_ABANDONED;
  696.         }
  697.  
  698.         void UnLock(TMutex *mutex)
  699.         {
  700.                 ReleaseMutex((HANDLE)mutex->mut);
  701.         }
  702.  
  703.         void UnLock(TRecMutex *mutex, unsigned int /*pid*/)
  704.         {
  705.                 ReleaseMutex((HANDLE)mutex->mut);
  706.         }
  707.  
  708.         void UnLock(TRecMutex *mutex)
  709.         {
  710.                 ReleaseMutex((HANDLE)mutex->mut);
  711.         }
  712.  
  713.         void UnLock(TRecMutex *mutex, TThreadData /*thread_data*/)
  714.         {
  715.                 ReleaseMutex((HANDLE)mutex->mut);
  716.         }
  717.  
  718.         void DebugPutChar(char c)
  719.         {
  720.                 DWORD num_written;
  721.                 WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), &c, 1, &num_written, NULL);
  722.         }
  723.  
  724.         void DebugPutString(const char *s)
  725.         {
  726.                 DWORD num_written;
  727.                 WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), s, strlen(s), &num_written, NULL);
  728.         }
  729.  
  730.         int GetKey()
  731.         {
  732.                 if (ThreadDataStruct.keys->empty()) return -1;
  733.                 else
  734.                 {
  735.                         unsigned char c = ThreadDataStruct.keys->front();
  736.                         ThreadDataStruct.keys->pop_front();
  737.                         return c;
  738.                 }
  739.         }
  740.  
  741.         int GetMouseButton()
  742.         {
  743.                 return ThreadDataStruct.mouse_state;
  744.         }
  745.  
  746.         void GetMousePosition(short &x, short &y, bool absolute)
  747.         {
  748.                 POINT point;
  749.                 if (!GetCursorPos(&point)) {x = -1; y = -1;}
  750.                 else if (absolute) {x = (short)point.x; y = (short)point.y;}
  751.                 else
  752.                 {
  753.                         RECT rect;
  754.                         if (!ThreadDataStruct.hwnd || !GetWindowRect(ThreadDataStruct.hwnd, &rect))
  755.                         {
  756.                                 x = -1; y = -1;
  757.                         }
  758.                         else
  759.                         {
  760.                                 x = (short)(point.x - rect.left);
  761.                                 y = (short)(point.y - rect.top);
  762.                         }
  763.                 }
  764.         }
  765.  
  766.         void GetMousePosPicture(short &x, short &y)
  767.         {
  768.                 POINT point;
  769.                 if (!GetCursorPos(&point)) {x = -1; y = -1;}
  770.                 else if (!ThreadDataStruct.hwnd || !ScreenToClient(ThreadDataStruct.hwnd, &point))
  771.                 {
  772.                         x = -1; y = -1;
  773.                 }
  774.                 else
  775.                 {
  776.                         x = (short)point.x;
  777.                         y = (short)point.y;
  778.                 }
  779.         }
  780.  
  781.         bool WasThreadCreated() {return WasThreadCreatedBool;}
  782.        
  783.         unsigned int CreateThread(void *user, unsigned int stack_size, void* /*stack_end*/)
  784.         {
  785.                 unsigned long pid = -1;
  786.                 WasThreadCreatedBool = true;
  787.                 if (!::CreateThread(NULL, stack_size, (LPTHREAD_START_ROUTINE)ThreadMainProc, user, 0, &pid))
  788.                 {
  789.                         return -1;
  790.                 }
  791.                 return pid;
  792.         }
  793.  
  794.         unsigned int StrLen(const char *str) {return ::strlen(str);}
  795.  
  796.         char *StrCopy(char *dest, const char *src) {return ::strcpy(dest, src);}
  797.  
  798.         void *MemCopy(void *dest, const void *src, unsigned int n) {return ::memcpy(dest, src, n);}
  799.  
  800.         void *MemSet(void *s, char c, unsigned int n) {return ::memset(s, c, n);}
  801.  
  802.         double Floor(double x) {return floor(x);}
  803.  
  804.         void *Alloc(unsigned int size) {return malloc(size);}
  805.  
  806.         void *ReAlloc(void *mem, unsigned int size) {return realloc(mem, size);}
  807.        
  808.         void Free(void *mem) {free(mem);}
  809.  
  810.         TFileData FileOpen(const char *name, unsigned int /*buffer_length*/)
  811.         {
  812.                 if (!name || !name[0]) return 0;
  813.                 TFileData file_data = (TFileData)Alloc(sizeof(unsigned int) +
  814.                                         strlen(file_prefix) + strlen(name) + 1);
  815.                 if (!file_data) return 0;
  816.                 file_data->data = 0;
  817.                 strcpy((char*)file_data + sizeof(unsigned int), file_prefix);
  818.                 strcat((char*)file_data + sizeof(unsigned int), name);
  819.                 return file_data;
  820.         }
  821.  
  822.         int FileClose(TFileData file_data)
  823.         {
  824.                 if (!file_data) return -1;
  825.                 if (file_data->data) CloseHandle((HANDLE)file_data->data);
  826.                 Free(file_data);
  827.                 return 0;
  828.         }
  829.  
  830.         bool FileEof(TFileData file_data)
  831.         {
  832.                 unsigned int pos;
  833.                 if (FileTestRead(file_data) < 0) return false;
  834.                 pos = SetFilePointer((HANDLE)file_data->data, 0, NULL, FILE_CURRENT);
  835.                 if (pos == -1) return false;
  836.                 return pos >= GetFileSize((HANDLE)file_data->data, NULL);
  837.         }
  838.  
  839.         unsigned int FileGetPosition(TFileData file_data)
  840.         {
  841.                 unsigned int pos;
  842.                 if (FileTestRead(file_data) < 0) return 0;
  843.                 pos = SetFilePointer((HANDLE)file_data->data, 0, NULL, FILE_CURRENT);
  844.                 return (pos == -1) ? 0 : pos;
  845.         }
  846.  
  847.         void FileSetPosition(TFileData file_data, unsigned int pos)
  848.         {
  849.                 if (FileTestRead(file_data) < 0) return;
  850.                 SetFilePointer((HANDLE)file_data->data, pos, NULL, FILE_BEGIN);
  851.         }
  852.  
  853.         void FileReset(TFileData file_data)
  854.         {
  855.                 if (!file_data || !file_data->data) return;
  856.                 FlushFileBuffers((HANDLE)file_data->data);
  857.         }
  858.  
  859.         unsigned int FileGetLength(TFileData file_data)
  860.         {
  861.                 if (FileTestRead(file_data) < 0) return -1;
  862.                 return GetFileSize((HANDLE)file_data->data, NULL);
  863.         }
  864.  
  865.         int FileTestRead(TFileData file_data)
  866.         {
  867.                 if (!file_data) return -1;
  868.                 if (!file_data->data)
  869.                 {
  870.                         file_data->data = (unsigned int)CreateFile((char*)file_data + sizeof(unsigned int),
  871.                                         GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING,
  872.                                         FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, 0);
  873.                         if (!file_data->data) return -512;
  874.                 }
  875.                 return 0;
  876.         }
  877.  
  878.         int FileRead(TFileData file_data, void *mem, int size)
  879.         {
  880.                 if (!file_data || !mem || size <= 0) return -1;
  881.                 int res = FileTestRead(file_data);
  882.                 if (res < 0) return res;
  883.                 if (!ReadFile((HANDLE)file_data->data, mem, size, (unsigned long*)&res, NULL))
  884.                 {
  885.                         return -512;
  886.                 }
  887.                 return (res >= 0) ? res : (-1);
  888.         }
  889. }
  890.  
  891. bool CheckAllocConsole(LPSTR lpCmdLine)
  892. {
  893.         char Console[] = "-console";
  894.         int ConsoleL = ::strlen(Console);
  895.         char *s;
  896.         for (s = lpCmdLine; *s; s++)
  897.         {
  898.                 if ((s == lpCmdLine || isspace(s[-1])) && memcmp(s, Console, ConsoleL) == 0 &&
  899.                         (!s[ConsoleL] || isspace(s[ConsoleL])))
  900.                 {
  901.                         AllocConsole();
  902.                         SetConsoleTitle("Debug Console");
  903.                         return true;
  904.                 }
  905.         }
  906.         return false;
  907. }
  908.  
  909. int APIENTRY WinMain(HINSTANCE hInstance,
  910.                                          HINSTANCE /*hPrevInstance*/,
  911.                                          LPSTR     lpCmdLine,
  912.                                          int       nCmdShow)
  913. {
  914.         ::nCmdShow = nCmdShow;
  915.         ::hInstance = hInstance;
  916.         CheckAllocConsole(lpCmdLine);
  917.         Main();
  918.         //::ExitThread(0);
  919.         return 0;
  920. }
  921.  
  922.