]> gitweb.ps.run Git - npengine/blob - src/main.cpp
54931486efe6459a28e71d1e5b58fbf1484904e8
[npengine] / src / main.cpp
1 #define DIRECTINPUT_VERSION 0x0800\r
2 #include <windows.h>\r
3 #include <dinput.h>\r
4 #include <stdio.h>\r
5 #include <time.h>\r
6 #include <string>\r
7 #include <fstream>\r
8 \r
9 #pragma comment(lib, "user32.lib")\r
10 #pragma comment(lib, "dinput8.lib")\r
11 #pragma comment(lib, "dxguid.lib")\r
12 \r
13 HWND hwnd = NULL;\r
14 \r
15 const int WIDTH = 43, HEIGHT = 25;\r
16 int x = 0, y = 0;\r
17 bool right = true;\r
18 \r
19 clock_t update_clock = clock();\r
20 double update_time = 40;\r
21 \r
22 bool keys[4] = { false, false, false, false };\r
23 bool keys_old[4] = { false, false, false, false };\r
24 \r
25 int jumping = 0;\r
26 \r
27 clock_t jump_clock = clock();\r
28 double jump_time1 = 50;\r
29 double jump_time2 = 100;\r
30 int jump_height = 3;\r
31 \r
32 DWORD wait_time = 10;\r
33 \r
34 void press_down(WORD vk) {\r
35   INPUT ip;\r
36 \r
37   ip.type = INPUT_KEYBOARD;\r
38   ip.ki.wScan = 0;\r
39   ip.ki.time = 0;\r
40   ip.ki.dwExtraInfo = 0;\r
41 \r
42   ip.ki.wVk = vk;\r
43   ip.ki.dwFlags = 0;\r
44   SendInput(1, &ip, sizeof(INPUT));\r
45 }\r
46 \r
47 void press_up(WORD vk) {\r
48   INPUT ip;\r
49   ip.type = INPUT_KEYBOARD;\r
50   ip.ki.wScan = 0;\r
51   ip.ki.time = 0;\r
52   ip.ki.dwExtraInfo = 0;\r
53 \r
54   ip.ki.dwFlags = KEYEVENTF_KEYUP;\r
55   SendInput(1, &ip, sizeof(INPUT));\r
56 }\r
57 \r
58 void press(WORD vk) {\r
59   press_down(vk);\r
60   press_up(vk);\r
61   GetAsyncKeyState(vk);\r
62 }\r
63 \r
64 void key_down(char c) {\r
65   if (hwnd == NULL)\r
66     puts("oh no");\r
67   INPUT ip;\r
68   ip.type = INPUT_KEYBOARD;\r
69   ip.ki.time = 0;\r
70   ip.ki.dwExtraInfo = 0;\r
71 \r
72   ip.ki.dwFlags = KEYEVENTF_UNICODE;\r
73   ip.ki.wVk = 0;\r
74   ip.ki.wScan = c;\r
75   SendInput(1, &ip, sizeof(INPUT));\r
76 }\r
77 \r
78 void key_up(char c) {\r
79   if (hwnd == NULL)\r
80     puts("oh no");\r
81   INPUT ip;\r
82   ip.type = INPUT_KEYBOARD;\r
83   ip.ki.time = 0;\r
84   ip.ki.dwExtraInfo = 0;\r
85 \r
86   // Release key\r
87   ip.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;\r
88   SendInput(1, &ip, sizeof(INPUT));\r
89 }\r
90 \r
91 void key(char c) {\r
92   key_down(c);\r
93   key_up(c);\r
94 }\r
95 \r
96 LPDIRECTINPUT8 di;\r
97 LPDIRECTINPUTDEVICE8 keyboard;\r
98 \r
99 HRESULT initializedirectinput8() {\r
100   HRESULT hr;\r
101   // Create a DirectInput device\r
102   if (FAILED(hr = DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION,\r
103                                      IID_IDirectInput8, (VOID **)&di, NULL))) {\r
104     return hr;\r
105   }\r
106   return 0;\r
107 }\r
108 \r
109 void createdikeyboard() {\r
110   di->CreateDevice(GUID_SysKeyboard, &keyboard, NULL);\r
111   keyboard->SetDataFormat(&c_dfDIKeyboard);\r
112   keyboard->SetCooperativeLevel(NULL, DISCL_FOREGROUND | DISCL_EXCLUSIVE);\r
113   keyboard->Acquire();\r
114 }\r
115 \r
116 void destroydikeyboard() {\r
117   keyboard->Unacquire();\r
118   keyboard->Release();\r
119 }\r
120 \r
121 #define keydown(name, key) (name[key] & 0x80)\r
122 \r
123 std::string read_map() {\r
124   std::ifstream ifs("lvl/1.txt", std::ios::in | std::ios::binary);\r
125   if (!ifs.good())\r
126     puts("mist");\r
127   ifs.seekg(0, std::ios::end);\r
128   int length = ifs.tellg();\r
129   ifs.seekg(0, std::ios::beg);\r
130   char *buffer = new char[length + 1];\r
131   ifs.read(buffer, length);\r
132   ifs.close();\r
133   buffer[length] = 0;\r
134   std::string result(buffer);\r
135   delete buffer;\r
136   return result;\r
137 }\r
138 std::string map = read_map();\r
139 \r
140 char get_block(int x, int y) {\r
141   char result = map[WIDTH + 8 + y * (WIDTH + 4) + x + 1];\r
142   return result;\r
143 }\r
144 \r
145 double get_dur(clock_t then) {\r
146   double result = (double)(clock() - then) / CLOCKS_PER_SEC;\r
147   return result * 1000;\r
148 }\r
149 \r
150 void draw() {\r
151   press(VK_BACK);\r
152   key(right ? '>' : '<');\r
153 }\r
154 \r
155 void erase() {\r
156   press(VK_BACK);\r
157   key(get_block(x, y));\r
158 }\r
159 \r
160 void move(int dx, int dy) {\r
161   erase();\r
162 \r
163   for (int i = 0; i < dx; i++) {\r
164     right = true;\r
165     press(VK_RIGHT);\r
166   }\r
167   for (int i = 0; i > dx; i--) {\r
168     right = false;\r
169     press(VK_LEFT);\r
170   }\r
171   for (int i = 0; i < dy; i++) {\r
172     press(VK_DOWN);\r
173   }\r
174   for (int i = 0; i > dy; i--) {\r
175     press(VK_UP);\r
176   }\r
177 \r
178   draw();\r
179   \r
180   x += dx;\r
181   y += dy;\r
182   \r
183   printf("%d %d\n", x, y);\r
184 }\r
185 \r
186 void move_to(int _x, int _y) {\r
187   move(_x - x, _y - y);\r
188 }\r
189 \r
190 void print_text(int text_x, int text_y, const char *text, int delay) {\r
191   for (int i = x; i < text_x; i++) press(VK_RIGHT);\r
192   for (int i = x; i > text_x; i--) press(VK_LEFT);\r
193   for (int i = y; i < text_y; i++) press(VK_DOWN);\r
194   for (int i = y; i > text_y; i--) press(VK_UP);\r
195 \r
196   int len = strlen(text);\r
197   for (int i = 0; i < len; i++) {\r
198     press(VK_DELETE);\r
199     key(text[i]);\r
200     Sleep(delay);\r
201   }\r
202   for (int i = text_x + len; i < x; i++) press(VK_RIGHT);\r
203   for (int i = text_x + len; i > x; i--) press(VK_LEFT);\r
204   for (int i = text_y; i < y; i++) press(VK_DOWN);\r
205   for (int i = text_y; i > y; i--) press(VK_UP);\r
206 \r
207   draw();\r
208 \r
209   Sleep(100);\r
210 }\r
211 \r
212 void update_play(bool can_jump = true) {\r
213   if (get_dur(update_clock) >= update_time) {\r
214     update_clock = clock();\r
215 \r
216     if (keys[0] &&\r
217         x > 0 &&\r
218         get_block(x - 1, y) != 'x')\r
219       move(-1, 0);\r
220     if (keys[1] &&\r
221         x < WIDTH - 1 &&\r
222         get_block(x + 1, y) != 'x')\r
223       move(+1, 0);\r
224   }\r
225 \r
226   // bool left = false;\r
227   // bool right = false;\r
228   // bool up = false;\r
229   // bool down = false;\r
230 \r
231   if (keys[2] && !keys_old[2] && jumping == 0 && can_jump) {\r
232     jumping = 1;\r
233     move(0, -1);\r
234     jump_clock = clock();\r
235   }\r
236   if (jumping != 0) {\r
237     if (jumping < jump_height && get_dur(jump_clock) > jump_time1) {\r
238       if (get_block(x, y - 1) != 'x') {\r
239           move(0, -1);\r
240           jumping++;\r
241           jump_clock = clock();\r
242       } else {\r
243         jumping = jump_height;\r
244       }\r
245     }\r
246     else if (jumping == jump_height && get_dur(jump_clock) > jump_time2) {\r
247       jumping = 0;\r
248     }\r
249   }\r
250   if (!jumping && get_block(x, y + 1) != 'x' && y < HEIGHT - 1)\r
251       move(0, +1);\r
252 \r
253   char block = get_block(x, y);\r
254   switch (block) {\r
255   case '/':\r
256   case '\\':\r
257     move_to(0, 24);\r
258     break;\r
259   case '?':\r
260     puts("?");\r
261     break;\r
262   case 'O':\r
263     puts("O");\r
264     break;\r
265   }\r
266 }\r
267 \r
268 int lvl = 0;\r
269 \r
270 void intro() {\r
271   static int progress = 0;\r
272   switch (progress) {\r
273   case 0:\r
274     press(VK_DOWN);\r
275     press(VK_RIGHT);\r
276     press(VK_RIGHT);\r
277 \r
278     move_to(1, 24);\r
279 \r
280     print_text(4, 2, "Move with left/right.", 30);\r
281 \r
282     progress++;\r
283     break;\r
284   case 1:\r
285     update_play(false);\r
286     if (x == 5) {\r
287       print_text(4, 4, "Jump with up.", 30);\r
288       print_text(4, 6, "Stand on x.", 30);\r
289       progress++;\r
290     }\r
291     break;\r
292   case 2:\r
293     update_play();\r
294     if (x == 8) {\r
295       print_text(4, 8, "Collect ? for ???.", 30);\r
296     }\r
297     break;\r
298   }\r
299 }\r
300 \r
301 void update_game() {\r
302   switch (lvl) {\r
303   case 0:\r
304     intro();\r
305     break;\r
306   }\r
307 }\r
308 \r
309 /*\r
310   Todo:\r
311   - Restart\r
312   - Next Level\r
313 */\r
314 int main(int argc, char **argv) {\r
315   // Dies zu programmieren mit der reduzierten Inputrate.\r
316   // Ist nicht angenehm. Ich werde es ändern.......\r
317 \r
318   // printf("%c", get_block(6, 23));\r
319   // printf("%c", get_block(6, 24));\r
320 \r
321   STARTUPINFOA si;\r
322   PROCESS_INFORMATION pi;\r
323 \r
324   ZeroMemory( &si, sizeof(si) );\r
325   si.cb = sizeof(si);\r
326   ZeroMemory( &pi, sizeof(pi) );\r
327   \r
328   //MessageBoxA(NULL, "Guten Tag.", "Spiel Name???", MB_OK);\r
329 \r
330   // Start the child process. \r
331   if( !CreateProcessA( NULL,   // No module name (use command line)\r
332       "notepad.exe lvl/1.txt",        // Command line\r
333       NULL,           // Process handle not inheritable\r
334       NULL,           // Thread handle not inheritable\r
335       FALSE,          // Set handle inheritance to FALSE\r
336       0,              // No creation flags\r
337       NULL,           // Use parent's environment block\r
338       NULL,           // Use parent's starting directory \r
339       &si,            // Pointer to STARTUPINFO structure\r
340       &pi )           // Pointer to PROCESS_INFORMATION structure\r
341   ) \r
342   {\r
343       printf( "CreateProcess failed (%d).\n", GetLastError() );\r
344       return 0;\r
345   }\r
346   \r
347   Sleep(100);\r
348 \r
349   hwnd = FindWindowA(NULL, "1.txt - Editor");\r
350 \r
351   HRESULT hr;\r
352   BYTE dikeys[256];\r
353   initializedirectinput8();\r
354   createdikeyboard();\r
355 \r
356   MSG Msg;\r
357         while (true) {\r
358     hr = keyboard->GetDeviceState(256, dikeys);\r
359     if (keydown(dikeys, DIK_ESCAPE)) {\r
360       TerminateProcess(pi.hProcess, 0);\r
361       //MessageBoxA(NULL, "beendet...", "Schönes Wochenende.", MB_OK);\r
362                         break;\r
363                 }\r
364     keys[0] = keydown(dikeys, DIK_LEFTARROW);\r
365     keys[1] = keydown(dikeys, DIK_RIGHTARROW);\r
366     keys[2] = keydown(dikeys, DIK_UPARROW);\r
367 \r
368     if (keys[0] && !keys_old[0]) press(VK_RIGHT);\r
369     if (keys[1] && !keys_old[1]) press(VK_LEFT);\r
370     if (keys[2] && !keys_old[2]) press(VK_DOWN);\r
371 \r
372     update_game();\r
373 \r
374     keys_old[0] = keys[0];\r
375     keys_old[1] = keys[1];\r
376     keys_old[2] = keys[2];\r
377     keys_old[3] = keys[3];\r
378 \r
379     WaitForSingleObject( pi.hProcess, wait_time);\r
380 \r
381     SetWindowPos(hwnd, HWND_TOPMOST, 100, 100, 750, 750, SWP_SHOWWINDOW);\r
382   }\r
383 \r
384   destroydikeyboard();\r
385 \r
386   // Close process and thread handles. \r
387   CloseHandle( pi.hProcess );\r
388   CloseHandle( pi.hThread );\r
389 \r
390   return 0;\r
391 }