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