1 #define DIRECTINPUT_VERSION 0x0800
\r
9 #pragma comment(lib, "user32.lib")
\r
10 #pragma comment(lib, "dinput8.lib")
\r
11 #pragma comment(lib, "dxguid.lib")
\r
16 #pragma comment(linker, "/subsystem:console")
\r
18 #pragma comment(linker, "/subsystem:windows")
\r
24 PROCESS_INFORMATION pi;
\r
26 const int WIDTH = 56, HEIGHT = 29;
\r
28 int spawn_x, spawn_y;
\r
31 clock_t update_clock = clock();
\r
32 double update_time = 40;
\r
35 bool keys[4] = {false, false, false, false};
\r
36 bool keys_old[4] = {false, false, false, false};
\r
40 clock_t jump_clock = clock();
\r
41 double jump_time1 = 50;
\r
42 double jump_time2 = 100;
\r
43 int jump_height = 3;
\r
45 DWORD wait_time = 10;
\r
51 void press_down(WORD vk) {
\r
54 ip.type = INPUT_KEYBOARD;
\r
57 ip.ki.dwExtraInfo = 0;
\r
61 SendInput(1, &ip, sizeof(INPUT));
\r
64 void press_up(WORD vk) {
\r
66 ip.type = INPUT_KEYBOARD;
\r
69 ip.ki.dwExtraInfo = 0;
\r
72 ip.ki.dwFlags = KEYEVENTF_KEYUP;
\r
73 SendInput(1, &ip, sizeof(INPUT));
\r
76 void press(WORD vk) {
\r
81 void key_down(char c) {
\r
83 ip.type = INPUT_KEYBOARD;
\r
85 ip.ki.dwExtraInfo = 0;
\r
87 ip.ki.dwFlags = KEYEVENTF_UNICODE;
\r
90 SendInput(1, &ip, sizeof(INPUT));
\r
93 void key_up(char c) {
\r
95 ip.type = INPUT_KEYBOARD;
\r
97 ip.ki.dwExtraInfo = 0;
\r
99 ip.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
\r
100 SendInput(1, &ip, sizeof(INPUT));
\r
109 LPDIRECTINPUTDEVICE8 keyboard;
\r
111 HRESULT initializedirectinput8() {
\r
113 // Create a DirectInput device
\r
114 if (FAILED(hr = DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION,
\r
115 IID_IDirectInput8, (VOID **)&di, NULL))) {
\r
121 void createdikeyboard() {
\r
122 di->CreateDevice(GUID_SysKeyboard, &keyboard, NULL);
\r
123 keyboard->SetDataFormat(&c_dfDIKeyboard);
\r
124 keyboard->SetCooperativeLevel(NULL, DISCL_FOREGROUND | DISCL_EXCLUSIVE);
\r
125 keyboard->Acquire();
\r
128 void destroydikeyboard() {
\r
129 keyboard->Unacquire();
\r
130 keyboard->Release();
\r
133 #define keydown(name, key) (name[key] & 0x80)
\r
135 std::string read_map(int lvl) {
\r
136 std::ifstream ifs("lvl/" + std::to_string(lvl) + ".txt",
\r
137 std::ios::in | std::ios::binary);
\r
140 ifs.seekg(0, std::ios::end);
\r
141 int length = ifs.tellg();
\r
142 ifs.seekg(0, std::ios::beg);
\r
143 char *buffer = new char[length + 1];
\r
144 ifs.read(buffer, length);
\r
146 buffer[length] = 0;
\r
147 std::string result(buffer);
\r
152 char get_block(int x, int y) {
\r
153 char result = map[(y + 1) * (WIDTH + 4) + x + 1];
\r
157 double get_dur(clock_t then) {
\r
158 double result = (double)(clock() - then) / CLOCKS_PER_SEC;
\r
159 return result * 1000;
\r
164 key(right ? '>' : '<');
\r
169 key(get_block(x, y));
\r
172 void move(int dx, int dy) {
\r
175 for (int i = 0; i < dx; i++) {
\r
179 for (int i = 0; i > dx; i--) {
\r
183 for (int i = 0; i < dy; i++) {
\r
186 for (int i = 0; i > dy; i--) {
\r
195 printf("%d %d\n", x, y);
\r
198 void move_to(int _x, int _y) { move(_x - x, _y - y); }
\r
200 void print_text(int text_x, int text_y, const char *text, int delay,
\r
201 bool move = true) {
\r
203 for (int i = x; i < text_x; i++)
\r
205 for (int i = x; i > text_x; i--)
\r
207 for (int i = y; i < text_y; i++)
\r
209 for (int i = y; i > text_y; i--)
\r
213 int len = strlen(text);
\r
214 for (int i = 0; i < len; i++) {
\r
215 if (text[i] == '\r')
\r
220 map[(text_y + 1) * (WIDTH + 4) + text_x + 1 + i] = text[i];
\r
225 for (int i = text_x + len; i < x; i++)
\r
227 for (int i = text_x + len; i > x; i--)
\r
229 for (int i = text_y; i < y; i++)
\r
231 for (int i = text_y; i > y; i--)
\r
240 void update_play(bool can_jump = true, int x_min = 0, int x_max = WIDTH - 1) {
\r
241 if (get_dur(update_clock) >= update_time) {
\r
242 update_clock = clock();
\r
244 if (keys[0] && x > x_min && get_block(x - 1, y) != 'X')
\r
246 if (keys[1] && x < x_max && get_block(x + 1, y) != 'X')
\r
250 if (keys[2] && !keys_old[2] && jumping == 0 && can_jump) {
\r
253 jump_clock = clock();
\r
255 if (jumping != 0) {
\r
256 if (jumping < jump_height && get_dur(jump_clock) > jump_time1) {
\r
257 if (get_block(x, y - 1) != 'X') {
\r
260 jump_clock = clock();
\r
262 jumping = jump_height;
\r
264 } else if (jumping == jump_height && get_dur(jump_clock) > jump_time2) {
\r
268 if (!jumping && get_block(x, y + 1) != 'X' && y < HEIGHT - 1)
\r
271 char b = get_block(x, y);
\r
272 if (b == '/' || b == '\\' || b == '<' || b == '>')
\r
273 move_to(spawn_x, spawn_y);
\r
277 press_down(VK_CONTROL);
\r
279 press_up(VK_CONTROL);
\r
283 int _x = x, _y = y;
\r
284 print_text(0, 0, map.c_str(), 1, false);
\r
285 for (int i = 0; i < 100; i++)
\r
287 for (int i = 0; i < 100; i++)
\r
304 for (int i = 0; i < WIDTH; i++)
\r
305 for (int j = 0; j < HEIGHT; j++)
\r
306 if (get_block(i, j) == 'S') {
\r
311 move_to(spawn_x, spawn_y);
\r
314 void load_level(int l, bool terminate = true) {
\r
316 map = read_map(lvl);
\r
318 TerminateProcess(pi.hProcess, 0);
\r
321 sprintf(cmd, "notepad.exe lvl/%d.txt", lvl);
\r
323 if (!CreateProcessA(NULL, // No module name (use command line)
\r
324 cmd, // Command line
\r
325 NULL, // Process handle not inheritable
\r
326 NULL, // Thread handle not inheritable
\r
327 FALSE, // Set handle inheritance to FALSE
\r
328 0, // No creation flags
\r
329 NULL, // Use parent's environment block
\r
330 NULL, // Use parent's starting directory
\r
331 &si, // Pointer to STARTUPINFO structure
\r
332 &pi) // Pointer to PROCESS_INFORMATION structure
\r
334 printf("CreateProcess failed (%d).\n", GetLastError());
\r
341 sprintf(title, "%d.txt - Editor", lvl);
\r
342 hwnd = FindWindowA(NULL, title);
\r
344 SetWindowPos(hwnd, HWND_TOP, 100, 100, 965, 905, SWP_SHOWWINDOW);
\r
347 for (int i = 0; i < 10; i++) {
\r
348 press_down(VK_CONTROL);
\r
349 press(VK_OEM_PLUS);
\r
350 press_up(VK_CONTROL);
\r
357 static int progress = 0;
\r
358 switch (progress) {
\r
360 print_text(4, 2, "Move with left/right.", text_speed);
\r
365 update_play(false);
\r
367 print_text(4, 4, "Jump with up.", text_speed);
\r
368 print_text(4, 6, "Stand on x.", text_speed);
\r
375 print_text(4, 8, "Collect ? for ???.", text_speed);
\r
380 update_play(true, 0, 33);
\r
381 if (get_block(x, y) == '?') {
\r
382 print_text(4, 10, "Avoid /\\.", text_speed);
\r
389 print_text(4, 14, "Finish lvl by reaching O.", text_speed);
\r
395 if (get_block(x, y) == 'O') {
\r
403 static int progress = 0;
\r
404 switch (progress) {
\r
406 print_text(4, 2, "Also avoid > and <.", text_speed);
\r
415 void update_game() {
\r
426 void enter_keys(std::string input, int delay) {
\r
427 for (int i = 0; i < input.size(); i++) {
\r
428 if (input[i] == 't') {
\r
432 else if (input[i] == 's') {
\r
436 else if (input[i] == '~') {
\r
437 press_down(VK_LSHIFT);
\r
438 enter_keys(input.substr(i+1, 1), delay);
\r
439 press_up(VK_LSHIFT);
\r
445 while (input[i+len] >= '0' && input[i+len] <= '9') {
\r
447 n += input[i+len] - '0';
\r
450 for (int j = 0; j < n; j++) {
\r
451 if (input[i+len] == '~') {
\r
452 enter_keys(input.substr(i+len, 2), delay);
\r
455 enter_keys(input.substr(i+len, 1), delay);
\r
458 if (input[i+len] == '~')
\r
465 void toggle_key_repeat() {
\r
466 WinExec("c:\\windows\\system32\\control.exe /name Microsoft.EaseOfAccessCenter /page pageKeyboardEasierToUse", SW_NORMAL);
\r
469 enter_keys("6ts9ts7~ts13ts5~tss6ts", 10);
\r
473 press_down(VK_CONTROL);
\r
475 press_up(VK_CONTROL);
\r
485 - Set Accessibility
\r
490 int main(int argc, char **argv) {
\r
492 int WinMain(HINSTANCE a0, HINSTANCE a1, LPSTR a2, int a3) {
\r
494 toggle_key_repeat();
\r
495 // Dies zu programmieren mit der reduzierten Inputrate.
\r
496 // Ist nicht angenehm. Ich werde es ändern.......
\r
498 // printf("%c", get_block(6, 23));
\r
499 // printf("%c", get_block(6, 24));
\r
501 ZeroMemory(&si, sizeof(si));
\r
502 si.cb = sizeof(si);
\r
503 ZeroMemory(&pi, sizeof(pi));
\r
505 // MessageBoxA(NULL, "Guten Tag.", "Spiel Name???", MB_OK);
\r
508 initializedirectinput8();
\r
509 createdikeyboard();
\r
511 load_level(0, false);
\r
515 hr = keyboard->GetDeviceState(256, dikeys);
\r
516 if (keydown(dikeys, DIK_ESCAPE)) {
\r
517 TerminateProcess(pi.hProcess, 0);
\r
518 // MessageBoxA(NULL, "beendet...", "Schönes Wochenende.", MB_OK);
\r
521 if (keydown(dikeys, DIK_R)) {
\r
524 keys[0] = keydown(dikeys, DIK_LEFTARROW);
\r
525 keys[1] = keydown(dikeys, DIK_RIGHTARROW);
\r
526 keys[2] = keydown(dikeys, DIK_UPARROW);
\r
528 if (keys[0] && !keys_old[0])
\r
530 if (keys[1] && !keys_old[1])
\r
532 if (keys[2] && !keys_old[2])
\r
537 keys_old[0] = keys[0];
\r
538 keys_old[1] = keys[1];
\r
539 keys_old[2] = keys[2];
\r
540 keys_old[3] = keys[3];
\r
542 WaitForSingleObject(pi.hProcess, wait_time);
\r
545 toggle_key_repeat();
\r
547 destroydikeyboard();
\r
549 // Close process and thread handles.
\r
550 CloseHandle(pi.hProcess);
\r
551 CloseHandle(pi.hThread);
\r