]> gitweb.ps.run Git - npengine/blobdiff - src/main.cpp
wie vorher
[npengine] / src / main.cpp
index c0272ac72651fee4944ba675bdbc29748be71955..888035d5eef6f39cbcce52cf640aa0c7677a4aea 100644 (file)
-#define DIRECTINPUT_VERSION 0x0800\r
-#include <windows.h>\r
-#include <dinput.h>\r
+#include <fstream>\r
 #include <stdio.h>\r
 #include <stdio.h>\r
-#include <time.h>\r
 #include <string>\r
 #include <string>\r
-#include <fstream>\r
+#include <time.h>\r
+#include <windows.h>\r
+#include <Richedit.h>\r
 \r
 #pragma comment(lib, "user32.lib")\r
 \r
 #pragma comment(lib, "user32.lib")\r
-#pragma comment(lib, "dinput8.lib")\r
-#pragma comment(lib, "dxguid.lib")\r
 \r
 \r
-HWND hwnd = NULL;\r
+#define CONSOLE\r
 \r
 \r
-const int WIDTH = 43, HEIGHT = 25;\r
-int x = 0, y = 0;\r
-bool right = true;\r
+#ifdef CONSOLE\r
+#pragma comment(linker, "/subsystem:console")\r
+#else\r
+#pragma comment(linker, "/subsystem:windows")\r
+#endif\r
 \r
 \r
-clock_t update_clock = clock();\r
-double update_time = 40;\r
+using namespace std;\r
 \r
 \r
-bool keys[4] = { false, false, false, false };\r
-bool keys_old[4] = { false, false, false, false };\r
 \r
 \r
-int jumping = 0;\r
+const int WIDTH = 56, HEIGHT = 29;\r
 \r
 \r
-clock_t jump_clock = clock();\r
-double jump_time1 = 50;\r
-double jump_time2 = 100;\r
-int jump_height = 3;\r
+std::string map;\r
 \r
 \r
-DWORD wait_time = 10;\r
+clock_t game_clock;\r
+double frame_time = 30;\r
 \r
 \r
-void press_down(WORD vk) {\r
-  INPUT ip;\r
+int lvl = 0;\r
 \r
 \r
-  ip.type = INPUT_KEYBOARD;\r
-  ip.ki.wScan = 0;\r
-  ip.ki.time = 0;\r
-  ip.ki.dwExtraInfo = 0;\r
+// Util\r
 \r
 \r
-  ip.ki.wVk = vk;\r
-  ip.ki.dwFlags = 0;\r
-  SendInput(1, &ip, sizeof(INPUT));\r
+double get_dur(clock_t then) {\r
+  double result = (double)(clock() - then) / CLOCKS_PER_SEC;\r
+  return result * 1000;\r
 }\r
 \r
 }\r
 \r
-void press_up(WORD vk) {\r
-  INPUT ip;\r
-  ip.type = INPUT_KEYBOARD;\r
-  ip.ki.wScan = 0;\r
-  ip.ki.time = 0;\r
-  ip.ki.dwExtraInfo = 0;\r
+// Edit\r
 \r
 \r
-  ip.ki.dwFlags = KEYEVENTF_KEYUP;\r
-  SendInput(1, &ip, sizeof(INPUT));\r
-}\r
+HWND hwnd_notepad = NULL;\r
+HWND hwnd_edit = NULL;\r
 \r
 \r
-void press(WORD vk) {\r
-  press_down(vk);\r
-  press_up(vk);\r
-  GetAsyncKeyState(vk);\r
+string get_text() {\r
+  int len = SendMessageA(hwnd_edit, WM_GETTEXTLENGTH, 0, 0);\r
+  char *buffer = new char[len + 1];\r
+  int read = SendMessageA(hwnd_edit, WM_GETTEXT, len + 1, (LPARAM)buffer);\r
+  if (read != len)\r
+    puts("???");\r
+  buffer[read] = 0;\r
+  string result(buffer);\r
+  delete[] buffer;\r
+  return result;\r
 }\r
 \r
 }\r
 \r
-void key_down(char c) {\r
-  if (hwnd == NULL)\r
-    puts("oh no");\r
-  INPUT ip;\r
-  ip.type = INPUT_KEYBOARD;\r
-  ip.ki.time = 0;\r
-  ip.ki.dwExtraInfo = 0;\r
-\r
-  ip.ki.dwFlags = KEYEVENTF_UNICODE;\r
-  ip.ki.wVk = 0;\r
-  ip.ki.wScan = c;\r
-  SendInput(1, &ip, sizeof(INPUT));\r
+void select_all() {\r
+  SendMessage(hwnd_edit, EM_SETSEL, 0, get_text().size());\r
 }\r
 \r
 }\r
 \r
-void key_up(char c) {\r
-  if (hwnd == NULL)\r
-    puts("oh no");\r
-  INPUT ip;\r
-  ip.type = INPUT_KEYBOARD;\r
-  ip.ki.time = 0;\r
-  ip.ki.dwExtraInfo = 0;\r
-\r
-  // Release key\r
-  ip.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;\r
-  SendInput(1, &ip, sizeof(INPUT));\r
+void select_length(int from, int length) {\r
+  SendMessage(hwnd_edit, EM_SETSEL, from, from + length);\r
 }\r
 \r
 }\r
 \r
-void key(char c) {\r
-  key_down(c);\r
-  key_up(c);\r
+void select_from_to(int from, int to) {\r
+  SendMessage(hwnd_edit, EM_SETSEL, from, to);\r
 }\r
 \r
 }\r
 \r
-LPDIRECTINPUT8 di;\r
-LPDIRECTINPUTDEVICE8 keyboard;\r
-\r
-HRESULT initializedirectinput8() {\r
-  HRESULT hr;\r
-  // Create a DirectInput device\r
-  if (FAILED(hr = DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION,\r
-                                     IID_IDirectInput8, (VOID **)&di, NULL))) {\r
-    return hr;\r
-  }\r
-  return 0;\r
+void replace(string str) {\r
+  SendMessage(hwnd_edit, EM_REPLACESEL, FALSE, (LPARAM)str.c_str());\r
 }\r
 \r
 }\r
 \r
-void createdikeyboard() {\r
-  di->CreateDevice(GUID_SysKeyboard, &keyboard, NULL);\r
-  keyboard->SetDataFormat(&c_dfDIKeyboard);\r
-  keyboard->SetCooperativeLevel(NULL, DISCL_FOREGROUND | DISCL_EXCLUSIVE);\r
-  keyboard->Acquire();\r
+int get_pos(int x, int y) {\r
+  return (y + 1) * (WIDTH + 4) + x + 1;\r
 }\r
 \r
 }\r
 \r
-void destroydikeyboard() {\r
-  keyboard->Unacquire();\r
-  keyboard->Release();\r
+char get_block(int x, int y) {\r
+  return map[get_pos(x, y)];\r
 }\r
 \r
 }\r
 \r
-#define keydown(name, key) (name[key] & 0x80)\r
+// Player\r
+struct Player {\r
+  bool left = false;\r
+  int x, y;\r
+  int x_spawn, y_spawn;\r
+  int jumping = 0;\r
+\r
+  void clear() {\r
+    int pos = get_pos(x, y);\r
+    select_length(pos, 1);\r
+    replace({ map[pos], 0 });\r
+  }\r
+  \r
+  void draw() {\r
+    int pos = get_pos(x, y);\r
+    select_length(pos, 1);\r
+    replace({ left ? '<' : '>', 0 });\r
+  }\r
+\r
+  void move_to(int x, int y) {\r
+    clear();\r
+    if (this->x > x) left = true;\r
+    if (this->x < x) left = false;\r
+    this->x = x;\r
+    this->y = y;\r
+    draw();\r
+  }\r
+\r
+  void move(int dx, int dy) {\r
+    move_to(x + dx, y + dy);\r
+  }\r
+\r
+  bool collision_x(int n) {\r
+    if (x + n < 0 || x + n >= WIDTH)\r
+      return true;\r
+    for (int i = 0; i != n; i += (n < 0 ? -1 : 1))\r
+      if (get_block(x + i + (n < 0 ? -1 : 1), y) == 'X')\r
+        return true;\r
+    return false;\r
+  }\r
+  bool collision_y(int n) {\r
+    if (y + n < 0 || y + n >= HEIGHT)\r
+      return true;\r
+    for (int i = 0; i != n; i += (n < 0 ? -1 : 1))\r
+      if (get_block(x, y + i + (n < 0 ? -1 : 1)) == 'X')\r
+        return true;\r
+    return false;\r
+  }\r
+};\r
+Player player { 0, 0 };\r
+\r
+// Lvl\r
 \r
 \r
-std::string read_map() {\r
-  std::ifstream ifs("lvl/1.txt", std::ios::in | std::ios::binary);\r
+std::string read_map(int lvl) {\r
+  std::ifstream ifs("lvl/" + std::to_string(lvl) + ".txt",\r
+                    std::ios::in | std::ios::binary);\r
   if (!ifs.good())\r
     puts("mist");\r
   ifs.seekg(0, std::ios::end);\r
   if (!ifs.good())\r
     puts("mist");\r
   ifs.seekg(0, std::ios::end);\r
@@ -135,156 +144,241 @@ std::string read_map() {
   delete buffer;\r
   return result;\r
 }\r
   delete buffer;\r
   return result;\r
 }\r
-std::string map = read_map();\r
 \r
 \r
-char get_block(int x, int y) {\r
-  char result = map[WIDTH + 8 + y * (WIDTH + 4) + x + 1];\r
-  return result;\r
+void redraw() {\r
+  select_all();\r
+  replace(map);\r
+  player.draw();\r
 }\r
 \r
 }\r
 \r
-double get_dur(clock_t then) {\r
-  double result = (double)(clock() - then) / CLOCKS_PER_SEC;\r
-  return result * 1000;\r
+void load_level(int l) {\r
+  lvl = l;\r
+  map = read_map(l);\r
+  redraw();\r
+  for (int x = 0; x < WIDTH; x++) {\r
+    for (int y = 0; y < HEIGHT; y++) {\r
+      if (map[get_pos(x, y)] == 'S') {\r
+        player.x_spawn = x;\r
+        player.y_spawn = y;\r
+        player.move_to(x, y);\r
+        return;\r
+      }\r
+    }\r
+  }\r
 }\r
 \r
 }\r
 \r
-void draw() {\r
-  press(VK_BACK);\r
-  key(right ? '>' : '<');\r
-}\r
+// Notepad\r
 \r
 \r
-void erase() {\r
-  press(VK_BACK);\r
-  key(get_block(x, y));\r
-}\r
+STARTUPINFOA si;\r
+PROCESS_INFORMATION pi;\r
 \r
 \r
-void move(int dx, int dy) {\r
-  erase();\r
-\r
-  for (int i = 0; i < dx; i++) {\r
-    right = true;\r
-    press(VK_RIGHT);\r
-  }\r
-  for (int i = 0; i > dx; i--) {\r
-    right = false;\r
-    press(VK_LEFT);\r
+BOOL CALLBACK ew_cb(HWND hwnd, LPARAM lp) {\r
+  DWORD pid;\r
+  DWORD tid = GetWindowThreadProcessId(hwnd, &pid);\r
+  if (pi.dwProcessId == pid && pi.dwThreadId == tid) {\r
+    hwnd_notepad = hwnd;\r
+    return false;\r
   }\r
   }\r
-  for (int i = 0; i < dy; i++) {\r
-    press(VK_DOWN);\r
-  }\r
-  for (int i = 0; i > dy; i--) {\r
-    press(VK_UP);\r
+  return true;\r
+}\r
+BOOL CALLBACK ecw_cb(HWND child, LPARAM in) {\r
+  char buffer[1024 + 1];\r
+  int len = GetClassNameA(child, buffer, 1024);\r
+  buffer[len] = 0;\r
+  if (strcmp(buffer, "Edit") == 0) {\r
+    hwnd_edit = child;\r
+    return false;\r
   }\r
   }\r
+  return true;\r
+}\r
 \r
 \r
-  draw();\r
-  \r
-  x += dx;\r
-  y += dy;\r
-  \r
-  printf("%d %d\n", x, y);\r
+void start_notepad() {\r
+  ZeroMemory(&si, sizeof(si));\r
+  si.cb = sizeof(si);\r
+  ZeroMemory(&pi, sizeof(pi));\r
+\r
+  if (!CreateProcessA(NULL,  // No module name (use command line)\r
+                      "notepad.exe",   // Command line\r
+                      NULL,  // Process handle not inheritable\r
+                      NULL,  // Thread handle not inheritable\r
+                      FALSE, // Set handle inheritance to FALSE\r
+                      0,     // No creation flags\r
+                      NULL,  // Use parent's environment block\r
+                      NULL,  // Use parent's starting directory\r
+                      &si,   // Pointer to STARTUPINFO structure\r
+                      &pi)   // Pointer to PROCESS_INFORMATION structure\r
+  ) {\r
+    printf("CreateProcess failed (%d).\n", GetLastError());\r
+  }\r
+  Sleep(100);\r
+  EnumWindows(ew_cb, 0);\r
+  EnumChildWindows(hwnd_notepad, ecw_cb, 0);\r
+  SendMessage(hwnd_edit, EM_SETREADONLY, TRUE, NULL);\r
+}\r
+void close_notepad() {\r
+  TerminateProcess(pi.hProcess, 0);\r
+  CloseHandle(pi.hProcess);\r
+  CloseHandle(pi.hThread);\r
 }\r
 \r
 }\r
 \r
-void move_to(int _x, int _y) {\r
-  move(_x - x, _y - y);\r
+// Keys\r
+\r
+enum class Key {\r
+  Left,\r
+  Right,\r
+  Jump,\r
+  Exit,\r
+  Redraw,\r
+  COUNT\r
+};\r
+\r
+bool key_state[(uint64_t)Key::COUNT];\r
+bool key_state_old[(uint64_t)Key::COUNT];\r
+\r
+int key_get_vk(Key key) {\r
+  switch (key) {\r
+    case Key::Left: return 'A';\r
+    case Key::Right: return 'D';\r
+    case Key::Jump: return VK_SPACE;\r
+    case Key::Exit: return VK_ESCAPE;\r
+    case Key::Redraw: return 'R';\r
+    default: return 0;\r
+  }\r
 }\r
 \r
 }\r
 \r
-void print_text(int text_x, int text_y, const char *text, int delay) {\r
-  for (int i = x; i < text_x; i++) press(VK_RIGHT);\r
-  for (int i = x; i > text_x; i--) press(VK_LEFT);\r
-  for (int i = y; i < text_y; i++) press(VK_DOWN);\r
-  for (int i = y; i > text_y; i--) press(VK_UP);\r
+void update_key_state() {\r
+  for (int i = 0; i < (int)Key::COUNT; i++) {\r
+    key_state[i] = GetAsyncKeyState(key_get_vk((Key)i));\r
+  }\r
+}\r
 \r
 \r
-  int len = strlen(text);\r
-  for (int i = 0; i < len; i++) {\r
-    press(VK_DELETE);\r
-    key(text[i]);\r
-    Sleep(delay);\r
+void update_key_state_old() {\r
+  for (int i = 0; i < (int)Key::COUNT; i++) {\r
+    key_state_old[i] = key_state[i];\r
   }\r
   }\r
-  for (int i = text_x + len; i < x; i++) press(VK_RIGHT);\r
-  for (int i = text_x + len; i > x; i--) press(VK_LEFT);\r
-  for (int i = text_y; i < y; i++) press(VK_DOWN);\r
-  for (int i = text_y; i > y; i--) press(VK_UP);\r
+}\r
 \r
 \r
-  draw();\r
+bool key_pressed(Key key) {\r
+  return key_state[(int)key] && !key_state_old[(int)key];\r
+}\r
 \r
 \r
-  Sleep(100);\r
+bool key_down(Key key) {\r
+  return key_state[(int)key];\r
 }\r
 \r
 }\r
 \r
-void update_play(bool can_jump = true, int x_min = 0, int x_max = WIDTH - 1) {\r
-  if (get_dur(update_clock) >= update_time) {\r
-    update_clock = clock();\r
-\r
-    if (keys[0] &&\r
-        x > x_min &&\r
-        get_block(x - 1, y) != 'x')\r
-      move(-1, 0);\r
-    if (keys[1] &&\r
-        x < x_max &&\r
-        get_block(x + 1, y) != 'x')\r
-      move(+1, 0);\r
-  }\r
+bool key_up(Key key) {\r
+  return !key_state[(int)key];\r
+}\r
+\r
+// Gameplay\r
+  \r
+clock_t jump_clock = clock();\r
+int jump_height = 3;\r
+double jump_time1 = 50;\r
+double jump_time2 = 100;\r
+int text_speed = 50;\r
 \r
 \r
-  if (keys[2] && !keys_old[2] && jumping == 0 && can_jump) {\r
-    jumping = 1;\r
-    move(0, -1);\r
+void update_play(bool can_jump = true, int x_min = 0, int x_max = WIDTH - 1) {\r
+  if (key_down(Key::Left) &&\r
+      !player.collision_x(-1) &&\r
+      player.x > x_min)\r
+      player.move(-1, 0);\r
+  if (key_down(Key::Right) &&\r
+      !player.collision_x(1) &&\r
+      player.x < x_max)\r
+    player.move(+1, 0);\r
+\r
+  if (key_pressed(Key::Jump) &&\r
+      can_jump &&\r
+      player.jumping == 0 &&\r
+      !player.collision_y(-1)) {\r
+    player.jumping = 1;\r
+    player.move(0, -1);\r
     jump_clock = clock();\r
   }\r
     jump_clock = clock();\r
   }\r
-  if (jumping != 0) {\r
-    if (jumping < jump_height && get_dur(jump_clock) > jump_time1) {\r
-      if (get_block(x, y - 1) != 'x') {\r
-          move(0, -1);\r
-          jumping++;\r
-          jump_clock = clock();\r
+  if (player.jumping != 0) {\r
+    if (player.jumping < jump_height && get_dur(jump_clock) > jump_time1) {\r
+      if (!player.collision_y(-1)) {\r
+        player.move(0, -1);\r
+        player.jumping++;\r
+        jump_clock = clock();\r
       } else {\r
       } else {\r
-        jumping = jump_height;\r
+        player.jumping = jump_height;\r
       }\r
       }\r
-    }\r
-    else if (jumping == jump_height && get_dur(jump_clock) > jump_time2) {\r
-      jumping = 0;\r
+    } else if (player.jumping == jump_height && get_dur(jump_clock) > jump_time2) {\r
+      player.jumping = 0;\r
     }\r
   }\r
     }\r
   }\r
-  if (!jumping && get_block(x, y + 1) != 'x' && y < HEIGHT - 1)\r
-      move(0, +1);\r
+  if (!player.jumping && !player.collision_y(1))\r
+    player.move(0, +1);\r
+\r
+  char b = get_block(player.x, player.y);\r
+  if (b == '/' || b == '\\' || b == '<' || b == '>')\r
+    player.move_to(player.x_spawn, player.y_spawn);\r
 }\r
 \r
 }\r
 \r
-int lvl = 0;\r
+void print_text(int x, int y, string text, int delay) {\r
+  for (int i = 0; i < text.size(); i++) {\r
+    select_length(get_pos(x + i, y), 1);\r
+    replace(text.substr(i, 1));\r
+    Sleep(delay);\r
+  }\r
+}\r
 \r
 void intro() {\r
   static int progress = 0;\r
   switch (progress) {\r
   case 0:\r
 \r
 void intro() {\r
   static int progress = 0;\r
   switch (progress) {\r
   case 0:\r
-    press(VK_DOWN);\r
-    press(VK_RIGHT);\r
-    press(VK_RIGHT);\r
-\r
-    move_to(1, 24);\r
-\r
-    print_text(4, 2, "Move with left/right.", 30);\r
+    print_text(4, 2, "Move with left/right.", text_speed);\r
 \r
     progress++;\r
     break;\r
   case 1:\r
     update_play(false);\r
 \r
     progress++;\r
     break;\r
   case 1:\r
     update_play(false);\r
-    if (x == 5) {\r
-      print_text(4, 4, "Jump with up.", 30);\r
-      print_text(4, 6, "Stand on x.", 30);\r
+    if (player.x == 17) {\r
+      print_text(4, 4, "Jump with up.", text_speed);\r
+      print_text(4, 6, "Stand on x.", text_speed);\r
       progress++;\r
     }\r
     break;\r
   case 2:\r
     update_play();\r
       progress++;\r
     }\r
     break;\r
   case 2:\r
     update_play();\r
-    if (x == 8) {\r
-      print_text(4, 8, "Collect ? for ???.", 30);\r
+    if (player.x == 22) {\r
+      print_text(4, 8, "Collect ? for ???.", text_speed);\r
       progress++;\r
     }\r
     break;\r
   case 3:\r
       progress++;\r
     }\r
     break;\r
   case 3:\r
-    update_play(true, 0, 22);\r
-    if (get_block(x, y) == '?') {\r
-      print_text(4, 10, "Avoid /\\.", 30);\r
+    update_play(true, 0, 33);\r
+    if (get_block(player.x, player.y) == '?') {\r
+      print_text(4, 10, "Avoid /\\.", text_speed);\r
       progress++;\r
     }\r
     break;\r
   case 4:\r
       progress++;\r
     }\r
     break;\r
   case 4:\r
+    update_play();\r
+    if (player.x == 39) {\r
+      print_text(4, 14, "Finish lvl by reaching O.", text_speed);\r
+      progress++;\r
+    }\r
+    break;\r
+  case 5:\r
+    update_play();\r
+    if (get_block(player.x, player.y) == 'O') {\r
+      load_level(1);\r
+    }\r
+    break;\r
+  }\r
+}\r
+\r
+void lvl1() {\r
+  static int progress = 0;\r
+  switch (progress) {\r
+  case 0:\r
+    print_text(4, 2, "Also avoid > and <.", text_speed);\r
+    progress++;\r
+    break;\r
+  case 1:\r
     update_play();\r
     break;\r
   }\r
     update_play();\r
     break;\r
   }\r
@@ -295,89 +389,41 @@ void update_game() {
   case 0:\r
     intro();\r
     break;\r
   case 0:\r
     intro();\r
     break;\r
+  case 1:\r
+    lvl1();\r
+    break;\r
   }\r
 }\r
 \r
   }\r
 }\r
 \r
-/*\r
-  Todo:\r
-  - Restart\r
-  - Next Level\r
-*/\r
+#ifdef CONSOLE\r
 int main(int argc, char **argv) {\r
 int main(int argc, char **argv) {\r
-  // Dies zu programmieren mit der reduzierten Inputrate.\r
-  // Ist nicht angenehm. Ich werde es ändern.......\r
-\r
-  // printf("%c", get_block(6, 23));\r
-  // printf("%c", get_block(6, 24));\r
-\r
-  STARTUPINFOA si;\r
-  PROCESS_INFORMATION pi;\r
-\r
-  ZeroMemory( &si, sizeof(si) );\r
-  si.cb = sizeof(si);\r
-  ZeroMemory( &pi, sizeof(pi) );\r
-  \r
-  //MessageBoxA(NULL, "Guten Tag.", "Spiel Name???", MB_OK);\r
-\r
-  // Start the child process. \r
-  if( !CreateProcessA( NULL,   // No module name (use command line)\r
-      "notepad.exe lvl/1.txt",        // Command line\r
-      NULL,           // Process handle not inheritable\r
-      NULL,           // Thread handle not inheritable\r
-      FALSE,          // Set handle inheritance to FALSE\r
-      0,              // No creation flags\r
-      NULL,           // Use parent's environment block\r
-      NULL,           // Use parent's starting directory \r
-      &si,            // Pointer to STARTUPINFO structure\r
-      &pi )           // Pointer to PROCESS_INFORMATION structure\r
-  ) \r
-  {\r
-      printf( "CreateProcess failed (%d).\n", GetLastError() );\r
-      return 0;\r
+#else\r
+int WinMain(HINSTANCE a0, HINSTANCE a1, LPSTR a2, int a3) {\r
+#endif\r
+  start_notepad();\r
+  if (hwnd_notepad == NULL || hwnd_edit == NULL) {\r
+    puts("error");\r
+    return 1;\r
   }\r
   }\r
-  \r
-  Sleep(100);\r
-\r
-  hwnd = FindWindowA(NULL, "1.txt - Editor");\r
-\r
-  HRESULT hr;\r
-  BYTE dikeys[256];\r
-  initializedirectinput8();\r
-  createdikeyboard();\r
-\r
-  MSG Msg;\r
-       while (true) {\r
-    hr = keyboard->GetDeviceState(256, dikeys);\r
-    if (keydown(dikeys, DIK_ESCAPE)) {\r
-      TerminateProcess(pi.hProcess, 0);\r
-      //MessageBoxA(NULL, "beendet...", "Schönes Wochenende.", MB_OK);\r
-                       break;\r
-               }\r
-    keys[0] = keydown(dikeys, DIK_LEFTARROW);\r
-    keys[1] = keydown(dikeys, DIK_RIGHTARROW);\r
-    keys[2] = keydown(dikeys, DIK_UPARROW);\r
-\r
-    if (keys[0] && !keys_old[0]) press(VK_RIGHT);\r
-    if (keys[1] && !keys_old[1]) press(VK_LEFT);\r
-    if (keys[2] && !keys_old[2]) press(VK_DOWN);\r
 \r
 \r
+  load_level(0);\r
+  \r
+  while (true) {\r
+    //dt = ((double)clock() - game_clock) / CLOCKS_PER_SEC * 1000;\r
+    if (get_dur(game_clock) < frame_time) continue;\r
+    game_clock = clock();\r
+    update_key_state();\r
+\r
+    if (key_pressed(Key::Exit))\r
+      break;\r
+    if (key_pressed(Key::Redraw))\r
+      redraw();\r
+    \r
     update_game();\r
 \r
     update_game();\r
 \r
-    keys_old[0] = keys[0];\r
-    keys_old[1] = keys[1];\r
-    keys_old[2] = keys[2];\r
-    keys_old[3] = keys[3];\r
-\r
-    WaitForSingleObject( pi.hProcess, wait_time);\r
-\r
-    SetWindowPos(hwnd, HWND_TOPMOST, 100, 100, 750, 750, SWP_SHOWWINDOW);\r
+    update_key_state_old();\r
   }\r
   }\r
-\r
-  destroydikeyboard();\r
-\r
-  // Close process and thread handles. \r
-  CloseHandle( pi.hProcess );\r
-  CloseHandle( pi.hThread );\r
+  close_notepad();\r
 \r
   return 0;\r
 }
\ No newline at end of file
 \r
   return 0;\r
 }
\ No newline at end of file