Advertisement
Guest User

Untitled

a guest
Oct 18th, 2016
418
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 67.27 KB | None | 0 0
  1. #include <Windows.h>
  2. #include <windowsx.h>
  3. #include <Shlwapi.h>
  4. #include <atlimage.h>
  5. #include <gdiplus.h>
  6. #include <iostream>
  7. #include <math.h>
  8. using Gdiplus::Color;
  9. using Gdiplus::Point;
  10. using Gdiplus::Rect;
  11. using Gdiplus::Status;
  12. using Gdiplus::ImageLockMode;
  13. using Gdiplus::PixelFormat;
  14. using Gdiplus::BitmapData;
  15. using Gdiplus::GdiplusStartupInput;
  16. using Gdiplus::GdiplusStartupOutput;
  17. using Gdiplus::GdiplusStartup;
  18. using Gdiplus::GdiplusShutdown;
  19. using Gdiplus::Image;
  20. using Gdiplus::Bitmap;
  21. using Gdiplus::Graphics;
  22. using std::cout;
  23. using std::endl;
  24. using std::cin;
  25. #define cxscreen GetSystemMetrics(SM_CXSCREEN)
  26. #define cyscreen GetSystemMetrics(SM_CYSCREEN)
  27. #define countof _countof
  28. #pragma comment(linker,"\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
  29. class BGRA { public: byte B, G, R, A; BGRA(byte b = 0, byte g = 0, byte r = 0, byte a = 0) : B(b), G(g), R(r), A(a) {} };
  30. class BGR { public: byte B, G, R; BGR(byte b = 0, byte g = 0, byte r = 0) : B(b), G(g), R(r) {} };
  31. //class RGBA { public: byte R, G, B, A; RGBA(byte r = 0, byte g = 0, byte b = 0, byte a = 0) : R(r), G(g), B(b), A(a) {} };
  32. //class RGB { public: byte R, G, B; RGB(byte r = 0, byte g = 0, byte b = 0) : R(r), G(g), B(b) {} };
  33. enum
  34. {
  35. colors_order_BGRA,
  36. colors_order_BGR,
  37. colors_order_RGBA,
  38. colors_order_RGB
  39. };
  40. bool game_is_paused = false;
  41. USHORT dibsection_width = cxscreen / 2,
  42. dibsection_height = cyscreen / 2,
  43. StretchBlt_x_dest = 0, StretchBlt_y_dest = 0, StretchBlt_w_dest = dibsection_width, StretchBlt_h_dest = dibsection_height;
  44. UINT dibsection_number_of_colors = dibsection_width * dibsection_height, dibsection_index = 0;
  45. HBITMAP hDibSection = nullptr;
  46. BGRA* dibsection_colors = nullptr;
  47. HDC dibsection_hdc = CreateCompatibleDC(nullptr);
  48. BITMAPINFO bitmap_info = {0};
  49. HANDLE hMessenger = nullptr, hRenderer = nullptr;
  50. ULONG64 fps = 0, fps_counter = 0;
  51. char fpstr[21] = {'\0'};
  52. byte fpstr_len = 0;
  53. HMENU hMenu = CreateMenu(), hMenuAbout = CreatePopupMenu();
  54. //bool is_world_infinite = true;
  55. enum menu_item
  56. {
  57. menu_item_resize_done,
  58. menu_item_hide_menu_and_enter_fullscreen_mode,
  59. menu_item_enter_exit_fullscreen_mode,
  60. menu_item_set_size,
  61. menu_item_pause_resume,
  62. menu_item_hide,
  63. menu_item_stretch_to_fill_the_entire_whole_window_s_client_keep_aspect_ratio_while_resizing,
  64. menu_item_about,
  65. menu_item_close_button_just_does_what_it_does,
  66. menu_item_close_button_is_either_disabled_or_hidden,
  67. menu_item_close_button_asks_before_it_does_what_it_does,
  68. menu_item_close_button_just_shows_a_message_box,
  69. menu_item_close_button_does_nothing,
  70. menu_item_maximize_box_just_does_what_it_does,
  71. menu_item_maximize_box_is_either_disabled_or_hidden,
  72. menu_item_maximize_box_asks_before_it_does_what_it_does,
  73. menu_item_maximize_box_just_shows_a_message_box,
  74. menu_item_maximize_box_does_nothing,
  75. menu_item_minimize_box_just_does_what_it_does,
  76. menu_item_minimize_box_is_either_disabled_or_hidden,
  77. menu_item_minimize_box_asks_before_it_does_what_it_does,
  78. menu_item_minimize_box_just_shows_a_message_box,
  79. menu_item_minimize_box_does_nothing,
  80. menu_item_resize_done_command_is_disabled,
  81. menu_item_resize_done_commands_are_hidden,
  82. menu_item_set_map_size,
  83. menu_item_map_is_immense
  84. };
  85. enum
  86. {
  87. Gdiplus_Bitmap_constructor = 0,
  88. Gdiplus_Bitmap_FromFile_static_member_function = 1
  89. };
  90. enum
  91. {
  92. Gdiplus_Image_constructor = 1,
  93. Gdiplus_Image_FromFile_static_member_function = 2
  94. };
  95. enum { CImage_Load_member_function = 1 };
  96. enum
  97. {
  98. LoadImageA_function = 1,
  99. LoadImageW_function = 2
  100. };
  101. #define if_prefered_use_first_load_image_method switch (first_load_image_with) \
  102. { \
  103. case LoadImageA_function: to_load_the_image_file_use = 0; goto load_the_image_file_now; \
  104. case LoadImageW_function: mbstowcs(widefilename, filename, sizeof(filename)); to_load_the_image_file_use = 1; goto load_the_image_file_now; \
  105. }
  106. #define if_prefered_use_second_load_image_method switch (second_load_image_with) \
  107. { \
  108. case CImage_Load_member_function: to_load_the_image_file_use = 2; goto load_the_image_file_now; \
  109. }
  110. #define if_prefered_use_third_load_image_method switch (third_load_image_with) \
  111. { \
  112. case Gdiplus_Image_constructor: mbstowcs(widefilename, filename, sizeof(filename)); to_load_the_image_file_use = 3; goto load_the_image_file_now; \
  113. case Gdiplus_Image_FromFile_static_member_function: mbstowcs(widefilename, filename, sizeof(filename)); to_load_the_image_file_use = 4; goto load_the_image_file_now; \
  114. }
  115. #define use_last_resort_load_image_method switch (last_resort_load_image_with) \
  116. { \
  117. default: \
  118. case Gdiplus_Bitmap_constructor: mbstowcs(widefilename, filename, sizeof(filename)); to_load_the_image_file_use = 5; goto load_the_image_file_now; \
  119. case Gdiplus_Bitmap_FromFile_static_member_function: mbstowcs(widefilename, filename, sizeof(filename)); to_load_the_image_file_use = 6; goto load_the_image_file_now; \
  120. }
  121. enum
  122. {
  123. first_load_image_method,
  124. second_load_image_method,
  125. third_load_image_method,
  126. last_resort_load_image_method
  127. };
  128. enum sprite_id
  129. {
  130. empty_id,
  131. block_id,
  132. start_id,
  133. end_id,
  134. outside_id,
  135. standing_right_id,
  136. standing_down_id,
  137. standing_left_id,
  138. standing_up_id,
  139. walking_right_id,
  140. walking_down_id,
  141. walking_left_id,
  142. walking_up_id,
  143. running_right_id,
  144. running_down_id,
  145. running_left_id,
  146. running_up_id
  147. };
  148. enum timer_id_event
  149. {
  150. timer_id_event_every_second,
  151. timer_id_event_empty_animator,
  152. timer_id_event_outside_animator,
  153. timer_id_event_character_animator
  154. };
  155. char* names_of_images_to_load[] = { "empty", "block", "start", "end", "outside",
  156. "standing right", "standing down", "standing left", "standing up",
  157. "walking right", "walking down", "walking left", "walking up",
  158. "running right", "running down", "running left", "running up" };
  159. byte numbers_of_frames[countof(names_of_images_to_load)] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
  160. frame_index_of_empty = 0,
  161. frame_index_of_outside = 0,
  162. character_id = standing_up_id,
  163. frame_index_of_character = 0;
  164. LONG64 view_x = 0, view_y = 0, character_x = 0, character_y = 0, character_speed = 5;
  165. double view_w = 10.0, view_h = 10.0, zoom_speed = 0.1;
  166. ULONG64 square_w = 0, square_h = 0, camera_speed = 3, num_rows = 0, num_cols = 0;
  167. bool IsBounded = false, *map = nullptr;
  168. void put_remove_block_at(LONG64 x = 0, LONG64 y = 0)
  169. {
  170. if (IsBounded)
  171. map[y * num_cols + x] = !map[y * num_cols + x];
  172. else
  173. {
  174. }
  175. }
  176. enum Direction
  177. {
  178. Direction_Undefined,
  179. Direction_Right,
  180. Direction_Down,
  181. Direction_Left,
  182. Direction_Up
  183. };
  184. class PathSquare
  185. {
  186. public:
  187. bool collectible;
  188. Direction direction;
  189. PathSquare(bool collectible = true, Direction direction = Direction_Undefined) : collectible(collectible), direction(direction) {};
  190. };
  191. PathSquare* path_squares = nullptr;
  192. class HeapItem
  193. {
  194. public:
  195. LONG64 x, y;
  196. ULONG64 distance;
  197. HeapItem(LONG64 x = 0, LONG64 y = 0, ULONG64 distance = 0) : x(x), y(y), distance(distance) {}
  198. };
  199. HeapItem* heap_of_points = nullptr;
  200. ULONG64 HeapCount = 0, HeapCapacity = 0, whenever_heap_array_is_full_reallocate_and_grow_it_by = 2;
  201. bool whenever_heap_array_is_full_reallocate_and_multiply_its_capacity = true, heap_points_are_stored_on_an_array = true;
  202. bool add_point_to_heap(LONG64 x = 0, LONG64 y = 0, LONG64 tx = 1, LONG64 ty = 1)
  203. {
  204. if (heap_points_are_stored_on_an_array)
  205. {
  206. if (HeapCount == HeapCapacity)
  207. {
  208. if (whenever_heap_array_is_full_reallocate_and_multiply_its_capacity)
  209. {
  210. if (whenever_heap_array_is_full_reallocate_and_grow_it_by == 1)
  211. return true;
  212. HeapItem* new_array = new HeapItem[HeapCapacity * whenever_heap_array_is_full_reallocate_and_grow_it_by];
  213. CopyMemory(new_array, heap_of_points, HeapCapacity * sizeof(HeapItem));
  214. delete[] heap_of_points;
  215. heap_of_points = new_array;
  216. HeapCapacity *= whenever_heap_array_is_full_reallocate_and_grow_it_by;
  217. }
  218. else
  219. {
  220. if (whenever_heap_array_is_full_reallocate_and_grow_it_by == 0)
  221. return true;
  222. HeapItem* new_array = new HeapItem[HeapCapacity + whenever_heap_array_is_full_reallocate_and_grow_it_by];
  223. CopyMemory(new_array, heap_of_points, HeapCapacity * sizeof(HeapItem));
  224. delete[] heap_of_points;
  225. heap_of_points = new_array;
  226. HeapCapacity += whenever_heap_array_is_full_reallocate_and_grow_it_by;
  227. }
  228. }
  229. heap_of_points[HeapCount].x = x;
  230. heap_of_points[HeapCount].y = y;
  231. heap_of_points[HeapCount].distance = (tx - x) * (tx - x) + (ty - y) * (ty - y);
  232. ULONG64 pos = HeapCount++;
  233. while (pos > 0 && heap_of_points[(pos - 1) / 2].distance > heap_of_points[pos].distance)
  234. {
  235. HeapItem temp = heap_of_points[pos];
  236. heap_of_points[pos] = heap_of_points[(pos - 1) / 2];
  237. heap_of_points[(pos - 1) / 2] = temp;
  238. pos = (pos - 1) / 2;
  239. }
  240. }
  241. else
  242. {
  243. }
  244. return false;
  245. }
  246. bool heap_of_points_capacity_is_always_equals_to_map_size = true,
  247. empty_heap_whenever_calculation_is_done = true,
  248. clear_path_on_failure = true, clear_path_after_done_moving_over_it = true, path_already_cleared = true,
  249. memory_allocate_and_deallocate_path_squares_instead_of_clearing_them = false,
  250. memory_deallocate_heap_of_points_whenever_emptying_it = false,
  251. currently_moving_over_route = false, walk_over_route = true,
  252. calculate_route_function_fails_if_heap_of_points_is_full = false,
  253. calculate_route_function_fails_if_unable_to_add_points_to_heap_anymore = true;
  254. #define memory_allocate_heap_of_points_by_size_of_map heap_of_points_capacity_is_always_equals_to_map_size
  255. #define path_squares_is_always_allocated (memory_allocate_and_deallocate_path_squares_instead_of_clearing_them == false)
  256. #define path_squares_is_allocated_only_when_necessary memory_allocate_and_deallocate_path_squares_instead_of_clearing_them
  257. #define heap_of_points_is_always_allocated (memory_deallocate_heap_of_points_whenever_emptying_it == false)
  258. #define heap_of_points_is_allocated_only_when_necessary memory_deallocate_heap_of_points_whenever_emptying_it
  259. class HeapNode : public HeapItem
  260. {
  261. public:
  262. HeapNode *next, *prev, *left, *right, *parent;
  263. HeapNode(LONG64 x = 0, LONG64 y = 0, ULONG64 distance = 0,
  264. HeapNode* next = nullptr, HeapNode* prev = nullptr, HeapNode* left = nullptr, HeapNode* right = nullptr, HeapNode* parent = nullptr) : HeapItem(x, y, distance),
  265. next(next), prev(prev), left(left), right(right), parent(parent) {}
  266. };
  267. bool calculate_route(LONG64 x = 0, LONG64 y = 0, LONG64 tx = 1, LONG64 ty = 1)
  268. {
  269. if (IsBounded)
  270. {
  271. if (path_squares_is_allocated_only_when_necessary)
  272. path_squares = new PathSquare[num_rows * num_cols];
  273. else
  274. {
  275. if (path_already_cleared == false)
  276. for (UINT i = 0; i < num_rows * num_cols; i++)
  277. {
  278. path_squares[i].collectible = true;
  279. path_squares[i].direction = Direction_Undefined;
  280. }
  281. else
  282. path_already_cleared = false;
  283. }
  284. if (heap_points_are_stored_on_an_array)
  285. {
  286. if (empty_heap_whenever_calculation_is_done == false)
  287. {
  288. HeapCount = 0;
  289. if (heap_of_points_is_allocated_only_when_necessary)
  290. {
  291. heap_of_points = new HeapItem[heap_of_points_capacity_is_always_equals_to_map_size ? num_cols * num_rows : 1];
  292. HeapCapacity = heap_of_points_capacity_is_always_equals_to_map_size ? num_cols * num_rows : 1;
  293. }
  294. }
  295. path_squares[y * num_cols + x].collectible = false;
  296. while (x != tx || y != ty)
  297. {
  298. if (x > 0 && map[y * num_cols + x - 1] == false && path_squares[y * num_cols + x - 1].collectible)
  299. {
  300. if ((calculate_route_function_fails_if_heap_of_points_is_full && HeapCount == HeapCapacity) ||
  301. (calculate_route_function_fails_if_unable_to_add_points_to_heap_anymore && add_point_to_heap(x - 1, y, tx, ty)))
  302. return true;
  303. path_squares[y * num_cols + x - 1].collectible = false;
  304. path_squares[y * num_cols + x - 1].direction = Direction_Right;
  305. }
  306. if (y > 0 && map[(y - 1) * num_cols + x] == false && path_squares[(y - 1) * num_cols + x].collectible)
  307. {
  308. if ((calculate_route_function_fails_if_heap_of_points_is_full && HeapCount == HeapCapacity) ||
  309. (calculate_route_function_fails_if_unable_to_add_points_to_heap_anymore && add_point_to_heap(x, y - 1, tx, ty)))
  310. return true;
  311. path_squares[(y - 1) * num_cols + x].collectible = false;
  312. path_squares[(y - 1) * num_cols + x].direction = Direction_Down;
  313. }
  314. if (x + 1 < num_cols && map[y * num_cols + x + 1] == false && path_squares[y * num_cols + x + 1].collectible)
  315. {
  316. if ((calculate_route_function_fails_if_heap_of_points_is_full && HeapCount == HeapCapacity) ||
  317. (calculate_route_function_fails_if_unable_to_add_points_to_heap_anymore && add_point_to_heap(x + 1, y, tx, ty)))
  318. return true;
  319. path_squares[y * num_cols + x + 1].collectible = false;
  320. path_squares[y * num_cols + x + 1].direction = Direction_Left;
  321. }
  322. if (y + 1 < num_rows && map[(y + 1) * num_cols + x] == false && path_squares[(y + 1) * num_cols + x].collectible)
  323. {
  324. if ((calculate_route_function_fails_if_heap_of_points_is_full && HeapCount == HeapCapacity) ||
  325. (calculate_route_function_fails_if_unable_to_add_points_to_heap_anymore && add_point_to_heap(x, y + 1, tx, ty)))
  326. return true;
  327. path_squares[(y + 1) * num_cols + x].collectible = false;
  328. path_squares[(y + 1) * num_cols + x].direction = Direction_Up;
  329. }
  330. if (HeapCount == 0)
  331. {
  332. if (clear_path_on_failure)
  333. {
  334. for (UINT i = 0; i < num_rows * num_cols; i++)
  335. {
  336. path_squares[i].collectible = true;
  337. path_squares[i].direction = Direction_Undefined;
  338. }
  339. path_already_cleared = true;
  340. }
  341. return true;
  342. }
  343. //if (heap_of_points->x - x == 1)
  344. // path_squares[y * num_cols + x].direction = Direction_Right;
  345. //else if (heap_of_points->x - x == -1)
  346. // path_squares[y * num_cols + x].direction = Direction_Left;
  347. //else if (heap_of_points->y - y == 1)
  348. // path_squares[y * num_cols + x].direction = Direction_Down;
  349. //else if (heap_of_points->y - y == -1)
  350. // path_squares[y * num_cols + x].direction = Direction_Up;
  351. x = heap_of_points->x;
  352. y = heap_of_points->y;
  353. switch (path_squares[y * num_cols + x].direction)
  354. {
  355. case Direction_Left: path_squares[y * num_cols + x - 1].direction = Direction_Right; break;
  356. case Direction_Up: path_squares[(y - 1) * num_cols + x].direction = Direction_Down; break;
  357. case Direction_Right: path_squares[y * num_cols + x + 1].direction = Direction_Left; break;
  358. case Direction_Down: path_squares[(y + 1) * num_cols + x].direction = Direction_Up; break;
  359. }
  360. *heap_of_points = heap_of_points[--HeapCount];
  361. ULONG64 pos = 0;
  362. while (2 * pos + 1 < HeapCount)
  363. {
  364. if (2 * pos + 2 >= HeapCount || heap_of_points[2 * pos + 1].distance < heap_of_points[2 * pos + 2].distance)
  365. {
  366. if (heap_of_points[pos].distance > heap_of_points[2 * pos + 1].distance)
  367. {
  368. HeapItem temp = heap_of_points[pos];
  369. heap_of_points[pos] = heap_of_points[2 * pos + 1];
  370. heap_of_points[2 * pos + 1] = temp;
  371. pos = 2 * pos + 1;
  372. }
  373. else
  374. break;
  375. }
  376. else
  377. {
  378. if (heap_of_points[pos].distance > heap_of_points[2 * pos + 2].distance)
  379. {
  380. HeapItem temp = heap_of_points[pos];
  381. heap_of_points[pos] = heap_of_points[2 * pos + 2];
  382. heap_of_points[2 * pos + 2] = temp;
  383. pos = 2 * pos + 2;
  384. }
  385. else
  386. break;
  387. }
  388. }
  389. }
  390. path_squares[y * num_cols + x].direction = Direction_Undefined;
  391. }
  392. else
  393. {
  394. if (empty_heap_whenever_calculation_is_done == false)
  395. {
  396. HeapCount = 0;
  397. for (HeapNode *c = (HeapNode*)heap_of_points, *n = c ? c->next : nullptr; c; c = n, n = n ? n->next : nullptr)
  398. delete c;
  399. heap_of_points = nullptr;
  400. }
  401. }
  402. }
  403. else
  404. {
  405. if (heap_points_are_stored_on_an_array)
  406. {
  407. }
  408. else
  409. {
  410. }
  411. }
  412. if (empty_heap_whenever_calculation_is_done)
  413. {
  414. HeapCount = 0;
  415. if (heap_points_are_stored_on_an_array)
  416. {
  417. if (memory_deallocate_heap_of_points_whenever_emptying_it && heap_of_points)
  418. {
  419. delete[] heap_of_points;
  420. heap_of_points = nullptr;
  421. }
  422. }
  423. else
  424. {
  425. for (HeapNode *c = (HeapNode*)heap_of_points, *n = c ? c->next : nullptr; c; c = n, n = n ? n->next : nullptr)
  426. delete c;
  427. heap_of_points = nullptr;
  428. }
  429. }
  430. return false;
  431. }
  432. LRESULT CALLBACK WinProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  433. {
  434. static RECT previous_window_rect = {0};
  435. static bool process_wm_size_message = false;
  436. switch (Msg)
  437. {
  438. case WM_COMMAND:
  439. if (HIWORD(wParam) == 0)
  440. {
  441. switch (LOWORD(wParam))
  442. {
  443. case menu_item_resize_done:
  444. process_wm_size_message = false;
  445. if (GetWindowLongPtr(hWnd, GWL_STYLE) & WS_SIZEBOX)
  446. {
  447. ModifyMenu(hMenu, menu_item_resize_done, MF_ENABLED, menu_item_resize_done, "Resize");
  448. if (IsMaximized(hWnd))
  449. EnableMenuItem(hMenu, menu_item_resize_done, MF_DISABLED | MF_GRAYED);
  450. SuspendThread(hRenderer);
  451. SetWindowLongPtr(hWnd, GWL_STYLE, GetWindowLongPtr(hWnd, GWL_STYLE) & ~WS_SIZEBOX);
  452. DeleteBitmap(hDibSection);
  453. RECT client_rect = {0};
  454. GetClientRect(hWnd, &client_rect);
  455. char first_letter[2] = {'\0'};
  456. GetMenuString(hMenu, menu_item_stretch_to_fill_the_entire_whole_window_s_client_keep_aspect_ratio_while_resizing, first_letter, sizeof(first_letter), MF_BYCOMMAND);
  457. if (*first_letter == 'K')
  458. {
  459. dibsection_width = client_rect.right;
  460. dibsection_height = client_rect.bottom;
  461. StretchBlt_x_dest = 0;
  462. StretchBlt_y_dest = 0;
  463. StretchBlt_w_dest = dibsection_width;
  464. StretchBlt_h_dest = dibsection_height;
  465. }
  466. else
  467. {
  468. StretchBlt_h_dest = client_rect.bottom;
  469. StretchBlt_w_dest = dibsection_width * StretchBlt_h_dest / dibsection_height;
  470. if (StretchBlt_w_dest < client_rect.right)
  471. {
  472. StretchBlt_y_dest = 0;
  473. StretchBlt_x_dest = 0;//(client_rect.right - StretchBlt_w_dest) / 2;
  474. }
  475. else
  476. {
  477. StretchBlt_w_dest = client_rect.right;
  478. StretchBlt_h_dest = dibsection_height * StretchBlt_w_dest / dibsection_width;
  479. StretchBlt_x_dest = 0;
  480. StretchBlt_y_dest = 0;//(client_rect.bottom - StretchBlt_h_dest) / 2;
  481. }
  482. dibsection_width = StretchBlt_w_dest;
  483. dibsection_height = StretchBlt_h_dest;
  484. process_wm_size_message = false;
  485. RECT window_rect = { 0, 0, dibsection_width, dibsection_height };
  486. AdjustWindowRect(&window_rect, WS_CAPTION, (BOOL)GetMenu(hWnd));
  487. SetWindowPos(hWnd, nullptr, 0, 0, window_rect.right - window_rect.left, window_rect.bottom - window_rect.top, SWP_NOMOVE | SWP_NOZORDER);
  488. RECT new_client_rect = {0,0,0,0};
  489. GetClientRect(hWnd, &new_client_rect);
  490. if (new_client_rect.right != dibsection_width || new_client_rect.bottom != dibsection_height)
  491. MessageBox(hWnd, "The new dibsection does not fit to the new client area of thw window! The bottom and/or right sides of the image are clipped! This happened because the new dibsection is extremely tiny!", "Warning", MB_ICONWARNING | MB_OK);
  492. }
  493. dibsection_number_of_colors = dibsection_width * dibsection_height;
  494. bitmap_info.bmiHeader.biWidth = dibsection_width;
  495. bitmap_info.bmiHeader.biHeight = -dibsection_height;
  496. hDibSection = CreateDIBSection(nullptr, &bitmap_info, DIB_RGB_COLORS, (void**)&dibsection_colors, nullptr, 0);
  497. SelectBitmap(dibsection_hdc, hDibSection);
  498. dibsection_index = 0;
  499. ResumeThread(hRenderer);
  500. }
  501. else
  502. {
  503. SetWindowLongPtr(hWnd, GWL_STYLE, GetWindowLongPtr(hWnd, GWL_STYLE) | WS_SIZEBOX);
  504. ModifyMenu(hMenu, menu_item_resize_done, MF_ENABLED, menu_item_resize_done, "Done");
  505. }
  506. break;
  507. case menu_item_set_size:
  508. game_is_paused = true;
  509. ShowWindow(GetConsoleWindow(), SW_SHOW);
  510. SwitchToThisWindow(GetConsoleWindow(), true);
  511. if (GetWindowLongPtr(hWnd, GWL_STYLE) & WS_SIZEBOX)
  512. {
  513. RECT client_rect = {0};
  514. GetClientRect(hWnd, &client_rect);
  515. cout << "current window's client width = " << client_rect.right << endl;
  516. cout << "current window's client height = " << client_rect.bottom << endl;
  517. cout << endl;
  518. cout << "new window's client width = ";
  519. cin >> client_rect.right;
  520. cout << "new window's client height = ";
  521. cin >> client_rect.bottom;
  522. system("cls");
  523. AdjustWindowRect(&client_rect, WS_CAPTION, true);
  524. process_wm_size_message = false;
  525. SetWindowPos(hWnd, nullptr, 0, 0, client_rect.right - client_rect.left, client_rect.bottom - client_rect.top, SWP_NOMOVE | SWP_NOZORDER);
  526. }
  527. else
  528. {
  529. dibsection_index = 0;
  530. cout << "current dibsection width = " << dibsection_width << endl;
  531. cout << "current dibsection height = " << dibsection_height << endl;
  532. cout << endl;
  533. cout << "new dibsection width = ";
  534. cin >> dibsection_width;
  535. cout << "new dibsection height = ";
  536. cin >> dibsection_height;
  537. system("cls");
  538. dibsection_number_of_colors = dibsection_width * dibsection_height;
  539. DeleteBitmap(hDibSection);
  540. bitmap_info.bmiHeader.biWidth = dibsection_width;
  541. bitmap_info.bmiHeader.biHeight = -dibsection_height;
  542. hDibSection = CreateDIBSection(nullptr, &bitmap_info, DIB_RGB_COLORS, (void**)&dibsection_colors, nullptr, 0);
  543. SelectBitmap(dibsection_hdc, hDibSection);
  544. {
  545. RECT new_window_rect = { 0, 0, dibsection_width, dibsection_height }, new_client_rect = {0};
  546. AdjustWindowRect(&new_window_rect, WS_CAPTION, true);
  547. process_wm_size_message = false;
  548. SetWindowPos(hWnd, nullptr, 0, 0, new_window_rect.right - new_window_rect.left, new_window_rect.bottom - new_window_rect.top, SWP_NOMOVE | SWP_NOZORDER);
  549. GetClientRect(hWnd, &new_client_rect);
  550. if (new_client_rect.right != dibsection_width || new_client_rect.bottom != dibsection_height)
  551. MessageBox(hWnd, "The new dibsection does not fit to the new client area of the window! The bottom and/or right sides of the image are clipped! This happened because the new dibsection is extremely tiny", "Warning", MB_ICONWARNING | MB_OK);
  552. }
  553. }
  554. ShowWindow(GetConsoleWindow(), SW_HIDE);
  555. SwitchToThisWindow(hWnd, true);
  556. game_is_paused = false;
  557. ResumeThread(hRenderer);
  558. break;
  559. case menu_item_enter_exit_fullscreen_mode:
  560. case menu_item_hide_menu_and_enter_fullscreen_mode:
  561. if (GetWindowLongPtr(hWnd, GWL_STYLE) & WS_BORDER)
  562. {
  563. GetWindowRect(hWnd, &previous_window_rect);
  564. if (LOWORD(wParam) == menu_item_hide_menu_and_enter_fullscreen_mode)
  565. {
  566. process_wm_size_message = false;
  567. SetMenu(hWnd, nullptr);
  568. }
  569. else
  570. ModifyMenu(hMenu, menu_item_enter_exit_fullscreen_mode, MF_ENABLED, menu_item_enter_exit_fullscreen_mode, "Exit fullscreen mode");
  571. SetWindowLongPtr(hWnd, GWL_STYLE, (GetWindowLongPtr(hWnd, GWL_STYLE) & ~WS_BORDER) & ~WS_CAPTION);
  572. process_wm_size_message = true;
  573. SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, cxscreen, cyscreen, 0);
  574. }
  575. else
  576. {
  577. if (LOWORD(wParam) == menu_item_hide_menu_and_enter_fullscreen_mode && GetMenu(hWnd))
  578. {
  579. process_wm_size_message = true;
  580. SetMenu(hWnd, nullptr);
  581. }
  582. else
  583. {
  584. SetWindowLongPtr(hWnd, GWL_STYLE, (GetWindowLongPtr(hWnd, GWL_STYLE) | WS_BORDER) | WS_CAPTION);
  585. if (LOWORD(wParam) == menu_item_hide_menu_and_enter_fullscreen_mode)
  586. {
  587. process_wm_size_message = false;
  588. SetMenu(hWnd, hMenu);
  589. }
  590. else
  591. ModifyMenu(hMenu, menu_item_enter_exit_fullscreen_mode, MF_ENABLED, menu_item_enter_exit_fullscreen_mode, "Enter fullscreen mode");
  592. process_wm_size_message = true;
  593. SetWindowPos(hWnd, nullptr, previous_window_rect.left, previous_window_rect.top,
  594. previous_window_rect.right - previous_window_rect.left,
  595. previous_window_rect.bottom - previous_window_rect.top, 0);
  596. }
  597. }
  598. break;
  599. case menu_item_stretch_to_fill_the_entire_whole_window_s_client_keep_aspect_ratio_while_resizing:
  600. {
  601. char first_letter[2] = {'\0'};
  602. GetMenuString(hMenu, menu_item_stretch_to_fill_the_entire_whole_window_s_client_keep_aspect_ratio_while_resizing,
  603. first_letter, sizeof(first_letter), MF_BYCOMMAND);
  604. if (*first_letter == 'S')
  605. ModifyMenu(hMenu, menu_item_stretch_to_fill_the_entire_whole_window_s_client_keep_aspect_ratio_while_resizing, MF_BYCOMMAND,
  606. menu_item_stretch_to_fill_the_entire_whole_window_s_client_keep_aspect_ratio_while_resizing,
  607. "Keep aspect ratio while resizing");
  608. else
  609. ModifyMenu(hMenu, menu_item_stretch_to_fill_the_entire_whole_window_s_client_keep_aspect_ratio_while_resizing, MF_BYCOMMAND,
  610. menu_item_stretch_to_fill_the_entire_whole_window_s_client_keep_aspect_ratio_while_resizing,
  611. "Stretch to fill the entire/whole window's client while resizing");
  612. }
  613. break;
  614. case menu_item_hide: process_wm_size_message = true; SetMenu(hWnd, nullptr); break;
  615. case menu_item_set_map_size:
  616. game_is_paused = true;
  617. ShowWindow(GetConsoleWindow(), SW_SHOW);
  618. SwitchToThisWindow(GetConsoleWindow(), true);
  619. cout << "cols = ";
  620. cin >> num_cols;
  621. cout << "rows = ";
  622. cin >> num_rows;
  623. system("cls");
  624. if (IsBounded)
  625. {
  626. if (map)
  627. delete[] map;
  628. if (path_squares)
  629. delete[] path_squares;
  630. map = new bool[num_cols * num_rows];
  631. if (currently_moving_over_route || path_squares_is_always_allocated)
  632. path_squares = new PathSquare[num_cols * num_rows];
  633. if (heap_of_points_capacity_is_always_equals_to_map_size)
  634. {
  635. if (heap_of_points)
  636. {
  637. if (heap_points_are_stored_on_an_array)
  638. delete[] heap_of_points;
  639. else for (HeapNode *c = (HeapNode*)heap_of_points, *n = c ? c->next : nullptr; c; c = n, n = n ? n->next : nullptr)
  640. delete c;
  641. }
  642. if (heap_points_are_stored_on_an_array)
  643. heap_of_points = new HeapItem[num_cols * num_rows];
  644. }
  645. }
  646. else
  647. {
  648. IsBounded = true;
  649. }
  650. EnableMenuItem(hMenu, menu_item_map_is_immense, MF_ENABLED);
  651. ShowWindow(GetConsoleWindow(), SW_HIDE);
  652. ResumeThread(hRenderer);
  653. break;
  654. case menu_item_map_is_immense:
  655. if (IsBounded)
  656. {
  657. if (map)
  658. {
  659. delete[] map;
  660. map = nullptr;
  661. }
  662. if (path_squares)
  663. {
  664. delete[] path_squares;
  665. path_squares = nullptr;
  666. }
  667. }
  668. else
  669. {
  670. }
  671. IsBounded = false;
  672. EnableMenuItem(hMenu, menu_item_map_is_immense, MF_DISABLED | MF_GRAYED);
  673. break;
  674. }
  675. DrawMenuBar(hWnd);
  676. }
  677. break;
  678. case WM_SIZING:
  679. InvalidateRect(hWnd, nullptr, true);
  680. {
  681. RECT client_rect = {0};
  682. GetClientRect(hWnd, &client_rect);
  683. char first_letter[2] = {'\0'};
  684. GetMenuString(hMenu, menu_item_stretch_to_fill_the_entire_whole_window_s_client_keep_aspect_ratio_while_resizing, first_letter, sizeof(first_letter), MF_BYCOMMAND);
  685. if (*first_letter == 'K')
  686. {
  687. StretchBlt_x_dest = 0;
  688. StretchBlt_y_dest = 0;
  689. StretchBlt_w_dest = client_rect.right;
  690. StretchBlt_h_dest = client_rect.bottom;
  691. }
  692. else
  693. {
  694. StretchBlt_h_dest = client_rect.bottom;
  695. StretchBlt_w_dest = dibsection_width * StretchBlt_h_dest / dibsection_height;
  696. if (StretchBlt_w_dest <= client_rect.right)
  697. {
  698. StretchBlt_y_dest = 0;
  699. StretchBlt_x_dest = (client_rect.right - StretchBlt_w_dest) / 2;
  700. }
  701. else
  702. {
  703. StretchBlt_w_dest = client_rect.right;
  704. StretchBlt_h_dest = dibsection_height * StretchBlt_w_dest / dibsection_width;
  705. StretchBlt_x_dest = 0;
  706. StretchBlt_y_dest = (client_rect.bottom - StretchBlt_h_dest) / 2;
  707. }
  708. }
  709. }
  710. break;
  711. case WM_SIZE:
  712. InvalidateRect(hWnd, nullptr, true);
  713. if (process_wm_size_message && (wParam == SIZE_MAXIMIZED || wParam == SIZE_RESTORED) && (GetWindowLongPtr(hWnd, GWL_STYLE) & WS_SIZEBOX) == false)
  714. {
  715. process_wm_size_message = false;
  716. game_is_paused = true;
  717. DeleteBitmap(hDibSection);
  718. char first_letter[2] = {'\0'};
  719. GetMenuString(hMenu, menu_item_stretch_to_fill_the_entire_whole_window_s_client_keep_aspect_ratio_while_resizing, first_letter, sizeof(first_letter), MF_BYCOMMAND);
  720. if (*first_letter == 'K')
  721. {
  722. dibsection_width = LOWORD(lParam);
  723. dibsection_height = HIWORD(lParam);
  724. StretchBlt_x_dest = 0;
  725. StretchBlt_y_dest = 0;
  726. StretchBlt_w_dest = dibsection_width;
  727. StretchBlt_h_dest = dibsection_height;
  728. }
  729. else
  730. {
  731. StretchBlt_h_dest = HIWORD(lParam);
  732. StretchBlt_w_dest = dibsection_width * StretchBlt_h_dest / dibsection_height;
  733. if (StretchBlt_w_dest <= LOWORD(lParam))
  734. {
  735. StretchBlt_y_dest = 0;
  736. StretchBlt_x_dest = (LOWORD(lParam) - StretchBlt_w_dest) / 2;
  737. }
  738. else
  739. {
  740. StretchBlt_w_dest = LOWORD(lParam);
  741. StretchBlt_h_dest = dibsection_height * StretchBlt_w_dest / dibsection_width;
  742. if (StretchBlt_h_dest <= HIWORD(lParam))
  743. {
  744. StretchBlt_x_dest = 0;
  745. StretchBlt_y_dest = (HIWORD(lParam) - StretchBlt_h_dest) / 2;
  746. }
  747. else
  748. {
  749. StretchBlt_x_dest = 0;
  750. StretchBlt_y_dest = 0;
  751. StretchBlt_w_dest = LOWORD(lParam);
  752. StretchBlt_h_dest = HIWORD(lParam);
  753. }
  754. }
  755. dibsection_width = StretchBlt_w_dest;
  756. dibsection_height = StretchBlt_h_dest;
  757. }
  758. dibsection_number_of_colors = dibsection_width * dibsection_height;
  759. square_w = dibsection_width / view_w;
  760. square_h = dibsection_height / view_h;
  761. bitmap_info.bmiHeader.biWidth = dibsection_width;
  762. bitmap_info.bmiHeader.biHeight = -dibsection_height;
  763. hDibSection = CreateDIBSection(nullptr, &bitmap_info, DIB_RGB_COLORS, (void**)&dibsection_colors, nullptr, 0);
  764. dibsection_index = 0;
  765. SelectBitmap(dibsection_hdc, hDibSection);
  766. game_is_paused = false;
  767. ResumeThread(hRenderer);
  768. }
  769. break;
  770. case WM_KEYDOWN:
  771. switch (wParam)
  772. {
  773. case VK_ESCAPE:
  774. if ((GetWindowLongPtr(hWnd, GWL_STYLE) & WS_BORDER) == false && GetMenu(hWnd) == nullptr)
  775. {
  776. char first_letter[2] = {'\0'};
  777. GetMenuString(hMenu, menu_item_resize_done, first_letter, sizeof(first_letter), MF_BYCOMMAND);
  778. if (*first_letter == 'R' && IsMaximized(hWnd))
  779. EnableMenuItem(hMenu, menu_item_resize_done, MF_DISABLED | MF_GRAYED);
  780. else
  781. EnableMenuItem(hMenu, menu_item_resize_done, MF_ENABLED);
  782. SetWindowLongPtr(hWnd, GWL_STYLE, (GetWindowLongPtr(hWnd, GWL_STYLE) | (*first_letter == 'R' ? WS_BORDER : WS_SIZEBOX)) | WS_CAPTION);
  783. process_wm_size_message = false;
  784. SetMenu(hWnd, hMenu);
  785. process_wm_size_message = true;
  786. SetWindowPos(hWnd, nullptr, previous_window_rect.left, previous_window_rect.top,
  787. previous_window_rect.right - previous_window_rect.left,
  788. previous_window_rect.bottom - previous_window_rect.top, 0);
  789. process_wm_size_message = true;
  790. }
  791. break;
  792. case VK_BACK:
  793. process_wm_size_message = true;
  794. SetMenu(hWnd, hMenu);
  795. DrawMenuBar(hWnd);
  796. {
  797. char first_letter[2] = {'\0'};
  798. GetMenuString(hMenu, menu_item_resize_done, first_letter, sizeof(first_letter), MF_BYCOMMAND);
  799. if (*first_letter == 'R' && (IsMaximized(hWnd) || (GetWindowLongPtr(hWnd, GWL_STYLE) & WS_BORDER) == false))
  800. EnableMenuItem(hMenu, menu_item_resize_done, MF_DISABLED | MF_GRAYED);
  801. else
  802. EnableMenuItem(hMenu, menu_item_resize_done, MF_ENABLED);
  803. }
  804. break;
  805. }
  806. break;
  807. case WM_RBUTTONDOWN:
  808. if (GET_X_LPARAM(lParam) >= StretchBlt_x_dest && GET_Y_LPARAM(lParam) >= StretchBlt_y_dest &&
  809. GET_X_LPARAM(lParam) < StretchBlt_x_dest + StretchBlt_w_dest &&
  810. GET_Y_LPARAM(lParam) < StretchBlt_y_dest + StretchBlt_h_dest)
  811. {
  812. USHORT x = (GET_X_LPARAM(lParam) - StretchBlt_x_dest) * dibsection_width / StretchBlt_w_dest,
  813. y = (GET_Y_LPARAM(lParam) - StretchBlt_y_dest) * dibsection_height / StretchBlt_h_dest;
  814. put_remove_block_at((view_x + x) / square_w - (view_x + x < 0),
  815. (view_y + y) / square_h - (view_y + y < 0));
  816. }
  817. break;
  818. case WM_LBUTTONDOWN:
  819. if (GET_X_LPARAM(lParam) >= StretchBlt_x_dest && GET_Y_LPARAM(lParam) >= StretchBlt_y_dest &&
  820. GET_X_LPARAM(lParam) < StretchBlt_x_dest + StretchBlt_w_dest &&
  821. GET_Y_LPARAM(lParam) < StretchBlt_y_dest + StretchBlt_h_dest)
  822. {
  823. USHORT x = (GET_X_LPARAM(lParam) - StretchBlt_x_dest) * dibsection_width / StretchBlt_w_dest,
  824. y = (GET_Y_LPARAM(lParam) - StretchBlt_y_dest) * dibsection_height / StretchBlt_h_dest;
  825. game_is_paused = true;
  826. Sleep(100);
  827. calculate_route(character_x / square_w - (character_x < 0),
  828. character_y / square_h - (character_y < 0),
  829. (view_x + x) / square_w - (view_x + x < 0),
  830. (view_y + y) / square_h - (view_y + y < 0));
  831. game_is_paused = false;
  832. ResumeThread(hRenderer);
  833. }
  834. break;
  835. case WM_MOUSEHWHEEL:
  836. view_w += GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA * zoom_speed;
  837. view_h += GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA * zoom_speed;
  838. square_w = dibsection_width / view_w;
  839. square_h = dibsection_height / view_h;
  840. break;
  841. case WM_SYSCOMMAND:
  842. if (wParam == SC_MAXIMIZE)
  843. {
  844. char first_letter[2] = {'\0'};
  845. GetMenuString(hMenu, menu_item_resize_done, first_letter, sizeof(first_letter), MF_BYCOMMAND);
  846. if (*first_letter == 'R')
  847. EnableMenuItem(hMenu, menu_item_resize_done, MF_DISABLED | MF_GRAYED);
  848. }
  849. else if (wParam == SC_RESTORE)
  850. EnableMenuItem(hMenu, menu_item_resize_done, MF_ENABLED);
  851. if (wParam == SC_MAXIMIZE || wParam == SC_RESTORE)
  852. process_wm_size_message = true;
  853. default: return DefWindowProc(hWnd, Msg, wParam, lParam);
  854. }
  855. }
  856. DWORD WINAPI Renderer(LPVOID lpParameter)
  857. {
  858. HWND hWnd = (HWND)lpParameter;
  859. char filename[MAX_PATH] = {'\0'};
  860. WCHAR* widenames_of_images_to_load[] = { L"empty", L"block", L"start", L"end", L"outside",
  861. L"standing right", L"standing down", L"standing left", L"standing up",
  862. L"walking right", L"walking down", L"walking left", L"walking up",
  863. L"running right", L"running down", L"running left", L"running up" },
  864. widefilename[MAX_PATH] = {L'\0'};
  865. BITMAP BITMAPs[countof(names_of_images_to_load)] = {{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0}};
  866. CImage CImages[countof(names_of_images_to_load)] = {};
  867. BGRA* Colors[countof(names_of_images_to_load)] = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr };
  868. //BGRA* BGRAs[countof(names_of_images_to_load)] = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr };
  869. //BGR* BGRs[countof(names_of_images_to_load)] = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr };
  870. UINT numbers_of_colors[countof(names_of_images_to_load)] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  871. USHORT frames_widths[countof(names_of_images_to_load)] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
  872. frames_heights[countof(names_of_images_to_load)] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  873. byte bits_per_pixels[countof(names_of_images_to_load)] = { 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32 },
  874. ColorsOrder[countof(names_of_images_to_load)] = { colors_order_BGRA, colors_order_BGRA, colors_order_BGRA, colors_order_BGRA, colors_order_BGRA, colors_order_BGRA, colors_order_BGRA, colors_order_BGRA, colors_order_BGRA,
  875. colors_order_BGRA, colors_order_BGRA, colors_order_BGRA, colors_order_BGRA, colors_order_BGRA, colors_order_BGRA, colors_order_BGRA },
  876. first_load_image_with = 0/*LoadImageA_function*/,
  877. second_load_image_with = 0/*CImage_Load_member_function*/,
  878. third_load_image_with = 0/*Gdiplus_Image_constructor*/,
  879. last_resort_load_image_with = Gdiplus_Bitmap_constructor,
  880. to_load_the_image_file_use = 0,
  881. to_load_bmp_files_use = first_load_image_method,
  882. to_load_gif_files_use = second_load_image_method,
  883. to_load_jpeg_files_use = second_load_image_method,
  884. to_load_png_files_use = second_load_image_method,
  885. to_load_tiff_files_use = second_load_image_method,
  886. to_load_emf_files_use = third_load_image_method;
  887. //as_much_as_possible_load_images_with = LoadImageA_function;
  888. GetModuleFileName(nullptr, filename, sizeof(filename));
  889. PathRemoveFileSpec(filename);
  890. FILE* FilePtr = nullptr;
  891. PathAppend(filename, "first load image with.txt");
  892. if (fopen_s(&FilePtr, filename, "r") == 0)
  893. {
  894. char c = getc(FilePtr);
  895. if (isdigit(c))
  896. first_load_image_with = c - '0';
  897. else
  898. {
  899. char s[100] = {'\0'};
  900. byte i = 0;
  901. for (i = 0; i < sizeof(s) - 1 && (isalpha(c) || isspace(c) || c == '_'); i++)
  902. {
  903. s[i] = c;
  904. c = getc(FilePtr);
  905. }
  906. s[i] = '\0';
  907. }
  908. fclose(FilePtr);
  909. }
  910. PathRemoveFileSpec(filename);
  911. PathAppend(filename, "second load image with.txt");
  912. if (fopen_s(&FilePtr, filename, "r") == 0)
  913. {
  914. char c = getc(FilePtr);
  915. if (isdigit(c))
  916. second_load_image_with = c - '0';
  917. else
  918. {
  919. char s[100] = {'\0'};
  920. byte i = 0;
  921. for (i = 0; i < sizeof(s) - 1 && (isalpha(c) || isspace(c) || c == '_'); i++)
  922. {
  923. s[i] = c;
  924. c = getc(FilePtr);
  925. }
  926. s[i] = '\0';
  927. }
  928. fclose(FilePtr);
  929. }
  930. PathRemoveFileSpec(filename);
  931. PathAppend(filename, "third load image with.txt");
  932. if (fopen_s(&FilePtr, filename, "r") == 0)
  933. {
  934. char c = getc(FilePtr);
  935. if (isdigit(c))
  936. third_load_image_with = c - '0';
  937. else
  938. {
  939. char s[100] = {'\0'};
  940. byte i = 0;
  941. for (i = 0; i < sizeof(s) - 1 && (isalpha(c) || isspace(c) || c == '_'); i++)
  942. {
  943. s[i] = c;
  944. c = getc(FilePtr);
  945. }
  946. s[i] = '\0';
  947. }
  948. fclose(FilePtr);
  949. }
  950. PathRemoveFileSpec(filename);
  951. PathAppend(filename, "last resort load image with.txt");
  952. if (fopen_s(&FilePtr, filename, "r") == 0)
  953. {
  954. char c = getc(FilePtr);
  955. if (isdigit(c))
  956. last_resort_load_image_with = c - '0';
  957. else
  958. {
  959. char s[100] = {'\0'};
  960. byte i = 0;
  961. for (i = 0; i < sizeof(s) - 1 && (isalpha(c) || isspace(c) || c == '_'); i++)
  962. {
  963. s[i] = c;
  964. c = getc(FilePtr);
  965. }
  966. s[i] = '\0';
  967. }
  968. fclose(FilePtr);
  969. }
  970. PathRemoveFileSpec(filename);
  971. PathAppend(filename, "to load bmp files use.txt");
  972. if (fopen_s(&FilePtr, filename, "r") == 0)
  973. {
  974. char c = getc(FilePtr);
  975. if (isdigit(c))
  976. to_load_bmp_files_use = c - '0';
  977. else
  978. {
  979. char s[100] = {'\0'};
  980. byte i = 0;
  981. for (i = 0; i < sizeof(s) - 1 && (isalpha(c) || isspace(c) || c == '_'); i++)
  982. {
  983. s[i] = c;
  984. c = getc(FilePtr);
  985. }
  986. s[i] = '\0';
  987. }
  988. fclose(FilePtr);
  989. }
  990. PathRemoveFileSpec(filename);
  991. PathAppend(filename, "to load gif files use.txt");
  992. if (fopen_s(&FilePtr, filename, "r") == 0)
  993. {
  994. char c = getc(FilePtr);
  995. if (isdigit(c))
  996. to_load_gif_files_use = c - '0';
  997. else
  998. {
  999. char s[100] = {'\0'};
  1000. byte i = 0;
  1001. for (i = 0; i < sizeof(s) - 1 && (isalpha(c) || isspace(c) || c == '_'); i++)
  1002. {
  1003. s[i] = c;
  1004. c = getc(FilePtr);
  1005. }
  1006. s[i] = '\0';
  1007. }
  1008. fclose(FilePtr);
  1009. }
  1010. PathRemoveFileSpec(filename);
  1011. PathAppend(filename, "to load jpeg files use.txt");
  1012. if (fopen_s(&FilePtr, filename, "r") == 0)
  1013. {
  1014. char c = getc(FilePtr);
  1015. if (isdigit(c))
  1016. to_load_jpeg_files_use = c - '0';
  1017. else
  1018. {
  1019. char s[100] = {'\0'};
  1020. byte i = 0;
  1021. for (i = 0; i < sizeof(s) - 1 && (isalpha(c) || isspace(c) || c == '_'); i++)
  1022. {
  1023. s[i] = c;
  1024. c = getc(FilePtr);
  1025. }
  1026. s[i] = '\0';
  1027. }
  1028. fclose(FilePtr);
  1029. }
  1030. PathRemoveFileSpec(filename);
  1031. PathAppend(filename, "to load png files use.txt");
  1032. if (fopen_s(&FilePtr, filename, "r") == 0)
  1033. {
  1034. char c = getc(FilePtr);
  1035. if (isdigit(c))
  1036. to_load_png_files_use = c - '0';
  1037. else
  1038. {
  1039. char s[100] = {'\0'};
  1040. byte i = 0;
  1041. for (i = 0; i < sizeof(s) - 1 && (isalpha(c) || isspace(c) || c == '_'); i++)
  1042. {
  1043. s[i] = c;
  1044. c = getc(FilePtr);
  1045. }
  1046. s[i] = '\0';
  1047. }
  1048. fclose(FilePtr);
  1049. }
  1050. PathRemoveFileSpec(filename);
  1051. PathAppend(filename, "to load tiff files use.txt");
  1052. if (fopen_s(&FilePtr, filename, "r") == 0)
  1053. {
  1054. char c = getc(FilePtr);
  1055. if (isdigit(c))
  1056. to_load_tiff_files_use = c - '0';
  1057. else
  1058. {
  1059. char s[100] = {'\0'};
  1060. byte i = 0;
  1061. for (i = 0; i < sizeof(s) - 1 && (isalpha(c) || isspace(c) || c == '_'); i++)
  1062. {
  1063. s[i] = c;
  1064. c = getc(FilePtr);
  1065. }
  1066. s[i] = '\0';
  1067. }
  1068. fclose(FilePtr);
  1069. }
  1070. PathRemoveFileSpec(filename);
  1071. PathAppend(filename, "to load emf files use.txt");
  1072. if (fopen_s(&FilePtr, filename, "r") == 0)
  1073. {
  1074. char c = getc(FilePtr);
  1075. if (isdigit(c))
  1076. to_load_emf_files_use = c - '0';
  1077. else
  1078. {
  1079. char s[100] = {'\0'};
  1080. byte i = 0;
  1081. for (i = 0; i < sizeof(s) - 1 && (isalpha(c) || isspace(c) || c == '_'); i++)
  1082. {
  1083. s[i] = c;
  1084. c = getc(FilePtr);
  1085. }
  1086. s[i] = '\0';
  1087. }
  1088. fclose(FilePtr);
  1089. }
  1090. PathRemoveFileSpec(filename);
  1091.  
  1092. //PathAppend(filename, "as much as possible load images with.txt");
  1093. //FILE* FilePtr = nullptr;
  1094. //if (fopen_s(&FilePtr, filename, "r") == 0)
  1095. //{
  1096. // char c = getc(FilePtr);
  1097. // if (isdigit(c))
  1098. // as_much_as_possible_load_images_with = c - '0';
  1099. // else
  1100. // {
  1101. // char input_string[100] = {'\0'};
  1102. // byte i = 0;
  1103. // for (i = 0; i < sizeof(input_string) && c != '\n' && c != '\r' && c != '\0' && c != EOF; i++)
  1104. // input_string[i] = c;
  1105. // input_string[i] = '\0';
  1106. // if (strcmp(input_string, "Gdiplus Bitmap constructor") == 0)
  1107. // as_much_as_possible_load_images_with = Gdiplus_Bitmap_constructor;
  1108. // else if (strcmp(input_string, "Gdiplus Bitmap FromFile static member function") == 0)
  1109. // as_much_as_possible_load_images_with = Gdiplus_Bitmap_FromFile_static_member_function;
  1110. // else if (strcmp(input_string, "Gdiplus Image constructor") == 0)
  1111. // as_much_as_possible_load_images_with = Gdiplus_Image_constructor;
  1112. // else if (strcmp(input_string, "Gdiplus Image FromFile static member function") == 0)
  1113. // as_much_as_possible_load_images_with = Gdiplus_Image_FromFile_static_member_function;
  1114. // else if (strcmp(input_string, "CImage Load member function") == 0)
  1115. // as_much_as_possible_load_images_with = CImage_Load_member_function;
  1116. // else if (strcmp(input_string, "LoadImageW function") == 0)
  1117. // as_much_as_possible_load_images_with = LoadImageW_function;
  1118. // else
  1119. // as_much_as_possible_load_images_with = LoadImageA_function;
  1120. // }
  1121. // fclose(FilePtr);
  1122. //}
  1123. //PathRemoveFileSpec(filename);
  1124. //GetModuleFileNameW(nullptr, widefilename, countof(widefilename));
  1125. //PathRemoveFileSpecW(widefilename);
  1126.  
  1127. ULONG_PTR token = 0;
  1128. GdiplusStartupInput gsi;
  1129. GdiplusStartup(&token, &gsi, nullptr);
  1130. for (byte i = 0; i < countof(names_of_images_to_load); i++)
  1131. {
  1132. PathAppend(filename, names_of_images_to_load[i]);
  1133. strcat_s(filename, " number of frames.txt");
  1134. if (fopen_s(&FilePtr, filename, "r") == 0)
  1135. {
  1136. fscanf_s(FilePtr, "%hhu", numbers_of_frames + i);
  1137. fclose(FilePtr);
  1138. }
  1139. PathRemoveFileSpec(filename);
  1140. PathAppend(filename, names_of_images_to_load[i]);
  1141. PathAddExtension(filename, ".bmp");
  1142. if (PathFileExists(filename))
  1143. switch (to_load_bmp_files_use)
  1144. {
  1145. default:
  1146. case first_load_image_method: if_prefered_use_first_load_image_method
  1147. case second_load_image_method: if_prefered_use_second_load_image_method
  1148. case third_load_image_method: if_prefered_use_third_load_image_method
  1149. case last_resort_load_image_method: use_last_resort_load_image_method
  1150. }
  1151. PathRemoveExtension(filename);
  1152. PathAddExtension(filename, ".gif");
  1153. if (PathFileExists(filename))
  1154. switch (to_load_gif_files_use)
  1155. {
  1156. default:
  1157. case second_load_image_method: if_prefered_use_second_load_image_method
  1158. case third_load_image_method: if_prefered_use_third_load_image_method
  1159. case last_resort_load_image_method: use_last_resort_load_image_method
  1160. }
  1161. PathRemoveExtension(filename);
  1162. PathAddExtension(filename, ".jpg");
  1163. if (PathFileExists(filename))
  1164. switch (to_load_jpeg_files_use)
  1165. {
  1166. default:
  1167. case second_load_image_method: if_prefered_use_second_load_image_method
  1168. case third_load_image_method: if_prefered_use_third_load_image_method
  1169. case last_resort_load_image_method: use_last_resort_load_image_method
  1170. }
  1171. PathRemoveExtension(filename);
  1172. PathAddExtension(filename, ".jpeg");
  1173. if (PathFileExists(filename))
  1174. switch (to_load_jpeg_files_use)
  1175. {
  1176. default:
  1177. case second_load_image_method: if_prefered_use_second_load_image_method
  1178. case third_load_image_method: if_prefered_use_third_load_image_method
  1179. case last_resort_load_image_method: use_last_resort_load_image_method
  1180. }
  1181. PathRemoveExtension(filename);
  1182. PathAddExtension(filename, ".png");
  1183. if (PathFileExists(filename))
  1184. switch (to_load_png_files_use)
  1185. {
  1186. default:
  1187. case second_load_image_method: if_prefered_use_second_load_image_method
  1188. case third_load_image_method: if_prefered_use_third_load_image_method
  1189. case last_resort_load_image_method: use_last_resort_load_image_method
  1190. }
  1191. PathRemoveExtension(filename);
  1192. PathAddExtension(filename, ".tiff");
  1193. if (PathFileExists(filename))
  1194. switch (to_load_tiff_files_use)
  1195. {
  1196. default:
  1197. case second_load_image_method: if_prefered_use_second_load_image_method
  1198. case third_load_image_method: if_prefered_use_third_load_image_method
  1199. case last_resort_load_image_method: use_last_resort_load_image_method
  1200. }
  1201. PathRemoveExtension(filename);
  1202. PathAddExtension(filename, ".emf");
  1203. if (PathFileExists(filename))
  1204. switch (to_load_emf_files_use)
  1205. {
  1206. default:
  1207. case third_load_image_method: if_prefered_use_third_load_image_method
  1208. case last_resort_load_image_method: use_last_resort_load_image_method
  1209. }
  1210. PathRemoveExtension(filename);
  1211. PathAddExtension(filename, ".wmf");
  1212. if (PathFileExists(filename))
  1213. use_last_resort_load_image_method
  1214. PathRemoveExtension(filename);
  1215. PathAddExtension(filename, ".exif");
  1216. if (PathFileExists(filename))
  1217. use_last_resort_load_image_method
  1218. else
  1219. {
  1220. char text[200] = {'\0'};
  1221. sprintf_s(text, "There is no \"%s\" image file in module's directory! Please add one now and then click on the \"Retry\" button or \"Cancel\" button to exit now!", names_of_images_to_load[i]);
  1222. if (MessageBox(hWnd, text, "Warning", MB_ICONWARNING | MB_RETRYCANCEL) == IDRETRY)
  1223. {
  1224. PathRemoveFileSpec(filename);
  1225. i--;
  1226. continue;
  1227. }
  1228. else
  1229. ExitProcess(0);
  1230. }
  1231. load_the_image_file_now:
  1232. switch (to_load_the_image_file_use)
  1233. {
  1234. case 0:
  1235. case 1:
  1236. {
  1237. HBITMAP hBitmap = (HBITMAP)(to_load_the_image_file_use ?
  1238. LoadImageW(nullptr, widefilename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE) :
  1239. LoadImage(nullptr, filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE));
  1240. GetObject(hBitmap, sizeof(BITMAP), BITMAPs + i);
  1241. DeleteBitmap(hBitmap);
  1242. frames_widths[i] = BITMAPs[i].bmWidth;
  1243. frames_heights[i] = BITMAPs[i].bmHeight / numbers_of_frames[i];
  1244. numbers_of_colors[i] = frames_widths[i] * frames_heights[i];
  1245. bits_per_pixels[i] = BITMAPs[i].bmBitsPixel;
  1246. ColorsOrder[i] = BITMAPs[i].bmBitsPixel == 32 ? colors_order_BGRA : colors_order_BGR;
  1247. Colors[i] = (BGRA*)BITMAPs[i].bmBits;
  1248. }
  1249. break;
  1250. case 2:
  1251. CImages[i].Load(filename);
  1252. frames_widths[i] = CImages[i].GetWidth();
  1253. frames_heights[i] = CImages[i].GetHeight() / numbers_of_frames[i];
  1254. numbers_of_colors[i] = frames_widths[i] * frames_heights[i];
  1255. bits_per_pixels[i] = CImages[i].GetBPP();
  1256. ColorsOrder[i] = CImages[i].GetBPP() == 24 ? colors_order_BGR : colors_order_BGRA;
  1257. //Bits[i] = (byte*)CImages[i].GetBits() - (numbers_of_colors[i] - frames_widths[i]) * CImages[i].GetBPP() / 8;
  1258. {
  1259. HBITMAP hBitmap = CImages[i];
  1260. if (CImages[i].GetBPP() == 24)
  1261. Colors[i] = (BGRA*)new BGR[numbers_of_colors[i] * numbers_of_frames[i]];
  1262. else
  1263. Colors[i] = new BGRA[numbers_of_colors[i] * numbers_of_frames[i]];
  1264. GetBitmapBits(hBitmap, numbers_of_colors[i] * numbers_of_frames[i] * (CImages[i].GetBPP() / 8), Colors[i]);
  1265. //GetObject(hBitmap, sizeof(BITMAP), BITMAPs + i);
  1266. //Bits[i] = BITMAPs[i].bmBits;
  1267. DeleteBitmap(hBitmap);
  1268. }
  1269. CImages[i].Destroy();
  1270. break;
  1271. case 3:
  1272. {
  1273. Image image(widefilename);
  1274. frames_widths[i] = image.GetWidth();
  1275. frames_heights[i] = image.GetHeight() / numbers_of_frames[i];
  1276. numbers_of_colors[i] = frames_widths[i] * frames_heights[i];
  1277. HBITMAP hBitmap = CreateCompatibleBitmap(nullptr, image.GetWidth(), image.GetHeight());
  1278. HDC hDC = CreateCompatibleDC(nullptr);
  1279. SelectBitmap(hDC, hBitmap);
  1280. Graphics graphics(hDC);
  1281. graphics.DrawImage(&image, 0, 0);
  1282. DeleteDC(hDC);
  1283. switch (image.GetPixelFormat())
  1284. {
  1285. case PixelFormat24bppRGB:
  1286. bits_per_pixels[i] = 24;
  1287. ColorsOrder[i] = colors_order_RGB;
  1288. //Bits[i] = (BGRA*)new RGB[image.GetWidth() * image.GetHeight()];
  1289. //GetBitmapBits(hBitmap, image.GetWidth() * image.GetHeight() * sizeof(RGB), Bits[i]);
  1290. break;
  1291. }
  1292. DeleteBitmap(hBitmap);
  1293. }
  1294. break;
  1295. case 4:
  1296. {
  1297. Image* image = Image::FromFile(widefilename);
  1298. frames_widths[i] = image->GetWidth();
  1299. frames_heights[i] = image->GetHeight() / numbers_of_frames[i];
  1300. numbers_of_colors[i] = frames_widths[i] * frames_heights[i];
  1301. HBITMAP hBitmap = CreateCompatibleBitmap(nullptr, image->GetWidth(), image->GetHeight());
  1302. HDC hDC = CreateCompatibleDC(nullptr);
  1303. SelectBitmap(hDC, hBitmap);
  1304. Graphics graphics(hDC);
  1305. graphics.DrawImage(image, 0, 0);
  1306. switch (image->GetPixelFormat())
  1307. {
  1308. case PixelFormat24bppRGB:
  1309. bits_per_pixels[i] = 24;
  1310. ColorsOrder[i] = colors_order_RGB;
  1311. //Bits[i] = (BGRA*)new RGB[image->GetWidth() * image->GetHeight()];
  1312. //GetBitmapBits(hBitmap, image->GetWidth() * image->GetHeight() * sizeof(RGB), Bits[i]);
  1313. break;
  1314. }
  1315. delete image;
  1316. DeleteDC(hDC);
  1317. //Colors[i] = new Color[frames_widths[i] * frames_heights[i] * numbers_of_frames[i]];
  1318. //GetBitmapBits(hBitmap, frames_widths[i] * frames_heights[i] * numbers_of_frames[i] * sizeof(Color), Colors[i]);
  1319. DeleteBitmap(hBitmap);
  1320. }
  1321. break;
  1322. case 5:
  1323. {
  1324. Bitmap bitmap(widefilename);
  1325. frames_widths[i] = bitmap.GetWidth() /*+ 1*/;
  1326. frames_heights[i] = bitmap.GetHeight() / numbers_of_frames[i];
  1327. numbers_of_colors[i] = frames_widths[i] * frames_heights[i];
  1328. //HBITMAP hBitmap = nullptr;
  1329. //bitmap.GetHBITMAP(0, &hBitmap);
  1330. Colors[i] = new BGRA[numbers_of_colors[i] * numbers_of_frames[i]];
  1331. //GetBitmapBits(hBitmap, numbers_of_colors[i] * sizeof(BGRA), Bits[i]);
  1332. //DeleteBitmap(hBitmap);
  1333. bits_per_pixels[i] = 32;
  1334. ColorsOrder[i] = colors_order_BGRA;
  1335. //switch (bitmap.GetPixelFormat())
  1336. //{
  1337. // case PixelFormat24bppRGB:
  1338. // bits_per_pixels[i] = 24;
  1339. // ColorsOrder[i] = colors_order_RGB;
  1340. // Bits[i] = new RGB[numbers_of_colors[i] * numbers_of_frames[i]];
  1341. // break;
  1342. //}
  1343. Rect rect(0, 0, (INT)bitmap.GetWidth(), (INT)bitmap.GetHeight());
  1344. BitmapData bd = {0};
  1345. /*switch /*if*/ /*(*/bitmap.LockBits(&rect, ImageLockMode::ImageLockModeRead, PixelFormat32bppRGB, &bd); /*!= Status::Ok*//*)*/
  1346. //{
  1347. // MessageBox(hWnd, "Gdiplus Bitmap LockBits failed!", "Error", MB_ICONERROR | MB_OK);
  1348. // ExitProcess(0);
  1349. //}
  1350. //{
  1351. // default:
  1352. // case Status::AccessDenied: MessageBox(hWnd, "Gdiplus Bitmap LockBits failed! Reason: Access Denied!", "Error", MB_ICONERROR | MB_OK); ExitProcess(0);
  1353. // case Status::FileNotFound: MessageBox(hWnd, "Gdiplus Bitmap LockBits failed! Reason: File Not Found!", "Error", MB_ICONERROR | MB_OK); ExitProcess(0);
  1354. // case Status::GdiplusNotInitialized: MessageBox(hWnd, "Gdiplus Bitmap LockBits failed! Reason: Gdiplus Not Initialized!", "Error", MB_ICONERROR | MB_OK); ExitProcess(0);
  1355. // case Status::GenericError: MessageBox(hWnd, "Gdiplus Bitmap LockBits failed! Reason: Generic Error!", "Error", MB_ICONERROR | MB_OK); ExitProcess(0);
  1356. // case Status::InsufficientBuffer: MessageBox(hWnd, "Gdiplus Bitmap LockBits failed! Reason: Insufficient Buffer!", "Error", MB_ICONERROR | MB_OK); ExitProcess(0);
  1357. // case Status::InvalidParameter: MessageBox(hWnd, "Gdiplus Bitmap LockBits failed! Reason: Invalid Parameter!", "Error", MB_ICONERROR | MB_OK); ExitProcess(0);
  1358. // case Status::Aborted: MessageBox(hWnd, "Gdiplus Bitmap LockBits failed! Reason: Aborted!", "Error", MB_ICONERROR | MB_OK); ExitProcess(0);
  1359. // case Status::NotImplemented: MessageBox(hWnd, "Gdiplus Bitmap LockBits failed! Reason: Not Implemented!", "Error", MB_ICONERROR | MB_OK); ExitProcess(0);
  1360. // case Status::ObjectBusy: MessageBox(hWnd, "Gdiplus Bitmap LockBits failed! Reason: Object Busy!", "Error", MB_ICONERROR | MB_OK); ExitProcess(0);
  1361. // case Status::OutOfMemory: MessageBox(hWnd, "Gdiplus Bitmap LockBits failed! Reason: Out Of Memory!", "Error", MB_ICONERROR | MB_OK); ExitProcess(0);
  1362. // case Status::Ok: break;
  1363. //}
  1364. CopyMemory(Colors[i], bd.Scan0, bd.Stride * bd.Height);
  1365. //Bits[i] = bd.Scan0;
  1366. /*if (*/bitmap.UnlockBits(&bd);/* != Status::Ok)*/
  1367. //{
  1368. // MessageBox(hWnd, "Gdiplus Bitmap UnlockBits failed!", "Error", MB_ICONERROR | MB_OK);
  1369. // ExitProcess(0);
  1370. //}
  1371. }
  1372. break;
  1373. case 6:
  1374. {
  1375. Bitmap* bitmap = Bitmap::FromFile(widefilename);
  1376. frames_widths[i] = bitmap->GetWidth();
  1377. frames_heights[i] = bitmap->GetHeight() / numbers_of_frames[i];
  1378. numbers_of_colors[i] = frames_widths[i] * frames_heights[i];
  1379. switch (bitmap->GetPixelFormat())
  1380. {
  1381. case PixelFormat24bppRGB:
  1382. bits_per_pixels[i] = 24;
  1383. ColorsOrder[i] = colors_order_RGB;
  1384. break;
  1385. }
  1386. Rect rect = { 0, 0, (INT)bitmap->GetWidth(), (INT)bitmap->GetHeight() };
  1387. BitmapData bd;
  1388. bitmap->LockBits(&rect, ImageLockMode::ImageLockModeRead, bitmap->GetPixelFormat(), &bd);
  1389. Colors[i] = (BGRA*)bd.Scan0;
  1390. bitmap->UnlockBits(&bd);
  1391. delete bitmap;
  1392. }
  1393. break;
  1394. }
  1395. PathRemoveFileSpec(filename);
  1396. }
  1397. GdiplusShutdown(token);
  1398.  
  1399. HDC window_hdc = GetDC(hWnd);
  1400. RECT client_rect = {0};
  1401. LONG64 view_x = 0, view_y = 0;
  1402. square_w = dibsection_width / view_w;
  1403. square_h = dibsection_height / view_h;
  1404. //byte keys[256] = {0};
  1405. start:
  1406. while (IsWindow(hWnd))
  1407. {
  1408. if (game_is_paused)
  1409. SuspendThread(GetCurrentThread());
  1410. for (dibsection_index = 0; dibsection_index < dibsection_number_of_colors; dibsection_index++)
  1411. {
  1412. if (game_is_paused)
  1413. goto start;
  1414. USHORT x = dibsection_index % dibsection_width,
  1415. y = dibsection_index / dibsection_width;
  1416. if (view_x + x >= character_x && view_y + y >= character_y && view_x + x <= character_x + square_w && view_y + y <= character_y + square_h &&
  1417. Colors[character_id][frame_index_of_character * numbers_of_colors[character_id] +
  1418. (view_y + y - character_y) * frames_heights[character_id] / square_h * frames_widths[character_id] +
  1419. (view_x + x - character_x) * frames_widths[character_id] / square_w].A)
  1420. dibsection_colors[dibsection_index] = Colors[character_id][frame_index_of_character * numbers_of_colors[character_id] +
  1421. (view_y + y - character_y) * frames_heights[character_id] / square_h * frames_widths[character_id] +
  1422. (view_x + x - character_x) * frames_widths[character_id] / square_w];
  1423. else if (IsBounded == false || (view_x + x >= 0 && view_y + y >= 0 && view_x + x < square_w * num_cols && view_y + y < square_h * num_rows))
  1424. {
  1425. if (map[((view_y + y) / square_h - (view_y + y < 0)) * num_cols + (view_x + x) / square_w - (view_x + x < 0)])
  1426. {
  1427. USHORT sx = (view_x + x >= 0 ? (view_x + x) % square_w : square_w + (view_x + x) % square_w) * frames_widths[block_id] / square_w,
  1428. sy = (view_y + y >= 0 ? (view_y + y) % square_h : (view_y + y) % square_h) * frames_heights[block_id] / square_h;
  1429. dibsection_colors[dibsection_index] = Colors[block_id][sy * frames_heights[block_id] + sx];
  1430. }
  1431. else
  1432. {
  1433. USHORT sx = (view_x + x >= 0 ? (view_x + x) % square_w : square_w + (view_x + x) % square_w) * frames_widths[empty_id] / square_w,
  1434. sy = (view_y + y >= 0 ? (view_y + y) % square_h : (view_y + y) % square_h) * frames_heights[empty_id] / square_h;
  1435. dibsection_colors[dibsection_index] = Colors[empty_id][frame_index_of_empty * numbers_of_colors[empty_id] + sy * frames_widths[empty_id] + sx];
  1436. }
  1437. }
  1438. else
  1439. {
  1440. USHORT sx = (view_x + x >= 0 ? (view_x + x) % square_w : square_w + (view_x + x) % square_w) * frames_widths[outside_id] / square_w,
  1441. sy = (view_y + y >= 0 ? (view_y + y) % square_h : (view_y + y) % square_h) * frames_heights[outside_id] / square_h;
  1442. dibsection_colors[dibsection_index] = Colors[outside_id][frame_index_of_outside * numbers_of_colors[outside_id] + sy * frames_widths[outside_id] + sx];
  1443. }
  1444. }
  1445. TextOut(dibsection_hdc, 10, 10, fpstr, fpstr_len);
  1446. if (GetWindowLongPtr(hWnd, GWL_STYLE) & WS_SIZEBOX)
  1447. StretchBlt(window_hdc, StretchBlt_x_dest, StretchBlt_y_dest, StretchBlt_w_dest, StretchBlt_h_dest, dibsection_hdc, 0, 0, dibsection_width, dibsection_height, SRCCOPY);
  1448. else
  1449. BitBlt(window_hdc, StretchBlt_x_dest, StretchBlt_y_dest, dibsection_width, dibsection_height, dibsection_hdc, 0, 0, SRCCOPY);
  1450. fps_counter++;
  1451. //GetKeyboardState(keys);
  1452. if (GetForegroundWindow() == hWnd)
  1453. {
  1454. if (GetAsyncKeyState(VK_LEFT))
  1455. view_x -= camera_speed;
  1456. if (GetAsyncKeyState(VK_UP))
  1457. view_y -= camera_speed;
  1458. if (GetAsyncKeyState(VK_RIGHT))
  1459. view_x += camera_speed;
  1460. if (GetAsyncKeyState(VK_DOWN))
  1461. view_y += camera_speed;
  1462. }
  1463. LONG64 x = character_x / square_w - (character_x < 0), y = character_y / square_h - (character_y < 0);
  1464. switch (path_squares[y * num_cols + x].direction)
  1465. {
  1466. case Direction_Right: character_id = walking_right_id; character_x += character_speed; break;
  1467. case Direction_Down: character_id = walking_down_id; character_y += character_speed; break;
  1468. case Direction_Left: character_id = walking_left_id; character_x -= character_speed; break;
  1469. case Direction_Up: character_id = walking_up_id; character_y -= character_speed; break;
  1470. case Direction_Undefined:
  1471. default: switch (character_id)
  1472. {
  1473. case walking_right_id: frame_index_of_character = 0; character_id = standing_right_id;
  1474. if (IsBounded)
  1475. {
  1476. if (path_squares_is_allocated_only_when_necessary)
  1477. {
  1478. delete[] path_squares;
  1479. path_squares = nullptr;
  1480. }
  1481. else if (clear_path_after_done_moving_over_it)
  1482. {
  1483. for (ULONG64 i = 0; i < num_cols * num_rows; i++)
  1484. {
  1485. path_squares[i].collectible = true;
  1486. path_squares[i].direction = Direction_Undefined;
  1487. }
  1488. path_already_cleared = true;
  1489. }
  1490. }
  1491. else
  1492. {
  1493. }
  1494. break;
  1495. case walking_down_id: frame_index_of_character = 0; character_id = standing_down_id;
  1496. if (IsBounded)
  1497. {
  1498. if (path_squares_is_allocated_only_when_necessary)
  1499. {
  1500. delete[] path_squares;
  1501. path_squares = nullptr;
  1502. }
  1503. else if (clear_path_after_done_moving_over_it)
  1504. {
  1505. for (ULONG64 i = 0; i < num_cols * num_rows; i++)
  1506. {
  1507. path_squares[i].collectible = true;
  1508. path_squares[i].direction = Direction_Undefined;
  1509. }
  1510. path_already_cleared = true;
  1511. }
  1512. }
  1513. else
  1514. {
  1515. }
  1516. break;
  1517. case walking_left_id: frame_index_of_character = 0; character_id = standing_left_id;
  1518. if (IsBounded)
  1519. {
  1520. if (path_squares_is_allocated_only_when_necessary)
  1521. {
  1522. delete[] path_squares;
  1523. path_squares = nullptr;
  1524. }
  1525. else if (clear_path_after_done_moving_over_it)
  1526. {
  1527. for (ULONG64 i = 0; i < num_cols * num_rows; i++)
  1528. {
  1529. path_squares[i].collectible = true;
  1530. path_squares[i].direction = Direction_Undefined;
  1531. }
  1532. path_already_cleared = true;
  1533. }
  1534. }
  1535. else
  1536. {
  1537. }
  1538. break;
  1539. case walking_up_id: frame_index_of_character = 0; character_id = standing_up_id;
  1540. if (IsBounded)
  1541. {
  1542. if (path_squares_is_allocated_only_when_necessary)
  1543. {
  1544. delete[] path_squares;
  1545. path_squares = nullptr;
  1546. }
  1547. else if (clear_path_after_done_moving_over_it)
  1548. {
  1549. for (ULONG64 i = 0; i < num_cols * num_rows; i++)
  1550. {
  1551. path_squares[i].collectible = true;
  1552. path_squares[i].direction = Direction_Undefined;
  1553. }
  1554. path_already_cleared = true;
  1555. }
  1556. }
  1557. else
  1558. {
  1559. }
  1560. break;
  1561. }
  1562. }
  1563. }
  1564. return 0;
  1565. }
  1566. void CALLBACK every_second(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
  1567. {
  1568. fps = fps_counter;
  1569. fps_counter = 0;
  1570. if (fps >= 60)
  1571. SetTextColor(dibsection_hdc, 0xFFFFFF);
  1572. else if (fps >= 45)
  1573. SetTextColor(dibsection_hdc, 0x00FF00);
  1574. else if (fps >= 30)
  1575. SetTextColor(dibsection_hdc, 0x00FFFF);
  1576. else if (fps >= 15)
  1577. SetTextColor(dibsection_hdc, 0x0099FF);
  1578. else
  1579. SetTextColor(dibsection_hdc, 0x0000FF);
  1580. sprintf_s(fpstr, "%llu", fps);
  1581. fpstr_len = strlen(fpstr);
  1582. }
  1583. void CALLBACK empty_animator(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime) { frame_index_of_empty = (frame_index_of_empty + 1) % numbers_of_frames[empty_id]; }
  1584. void CALLBACK character_animator(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime) { frame_index_of_character = (frame_index_of_character + 1) % numbers_of_frames[character_id]; }
  1585. void CALLBACK outside_animator(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime) { frame_index_of_outside = (frame_index_of_outside + 1) % numbers_of_frames[outside_id]; }
  1586. void main()
  1587. {
  1588. hMessenger = GetCurrentThread();
  1589. char filename[MAX_PATH] = {'\0'};
  1590. GetModuleFileName(nullptr, filename, sizeof(filename));
  1591. PathRemoveFileSpec(filename);
  1592. PathAppend(filename, "initial size.txt");
  1593. FILE* FilePtr = nullptr;
  1594. if (fopen_s(&FilePtr, filename, "r") == 0)
  1595. {
  1596. fscanf_s(FilePtr, "%u%u", &dibsection_width, &dibsection_height);
  1597. dibsection_number_of_colors = dibsection_width * dibsection_height;
  1598. StretchBlt_w_dest = dibsection_width;
  1599. StretchBlt_h_dest = dibsection_height;
  1600. fclose(FilePtr);
  1601. }
  1602. PathRemoveFileSpec(filename);
  1603. PathAppend(filename, "map.txt");
  1604. if (fopen_s(&FilePtr, filename, "r") == 0)
  1605. {
  1606. IsBounded = getc(FilePtr) - '0';
  1607. if (IsBounded)
  1608. {
  1609. fscanf_s(FilePtr, "%u%u", &num_cols, &num_rows);
  1610. map = new bool[num_cols * num_rows];
  1611. if (path_squares_is_always_allocated)
  1612. path_squares = new PathSquare[num_cols * num_rows];
  1613. if (heap_of_points_is_always_allocated)
  1614. heap_of_points = new HeapItem[num_cols * num_rows];
  1615. HeapCount = 0;
  1616. HeapCapacity = num_cols * num_rows;
  1617. ZeroMemory(map, num_cols * num_rows);
  1618. }
  1619. else
  1620. {
  1621. }
  1622. fclose(FilePtr);
  1623. }
  1624. system("Title route calculator");
  1625. system("color 0F");
  1626. ShowWindow(GetConsoleWindow(), SW_HIDE);
  1627. RECT init_wnd_rect = { 0, 0, dibsection_width, dibsection_height};
  1628. AdjustWindowRect(&init_wnd_rect, WS_CAPTION, true);
  1629. init_wnd_rect.right -= init_wnd_rect.left;
  1630. init_wnd_rect.bottom -= init_wnd_rect.top;
  1631. AppendMenu(hMenu, MF_ENABLED, menu_item_resize_done, "Resize");
  1632. AppendMenu(hMenu, MF_ENABLED, menu_item_hide_menu_and_enter_fullscreen_mode, "Hide menu and enter fullscreen mode");
  1633. AppendMenu(hMenu, MF_ENABLED, menu_item_enter_exit_fullscreen_mode, "Enter fullscreen mode");
  1634. AppendMenu(hMenu, MF_ENABLED, menu_item_set_size, "Set Size");
  1635. AppendMenu(hMenu, MF_ENABLED, menu_item_pause_resume, "Pause");
  1636. AppendMenu(hMenu, MF_ENABLED, menu_item_hide, "Hide");
  1637. AppendMenu(hMenu, MF_ENABLED, menu_item_stretch_to_fill_the_entire_whole_window_s_client_keep_aspect_ratio_while_resizing, "Stretch to fill the entire/whole window's client while resizing");
  1638. AppendMenu(hMenu, MF_POPUP, (UINT_PTR)hMenuAbout, "About");
  1639. AppendMenu(hMenuAbout, MF_DISABLED | MF_GRAYED, 0, "Close button");
  1640. AppendMenu(hMenuAbout, MF_CHECKED | MFT_RADIOCHECK, menu_item_close_button_just_does_what_it_does, "just does what it does");
  1641. AppendMenu(hMenuAbout, MF_UNCHECKED, menu_item_close_button_is_either_disabled_or_hidden, "it is either disabled or hidden");
  1642. AppendMenu(hMenuAbout, MF_UNCHECKED, menu_item_close_button_asks_before_it_does_what_it_does, "it asks before it does what it does");
  1643. AppendMenu(hMenuAbout, MF_UNCHECKED, menu_item_close_button_just_shows_a_message_box, "just shows a message box");
  1644. AppendMenu(hMenuAbout, MF_UNCHECKED, menu_item_close_button_does_nothing, "it does nothing");
  1645. AppendMenu(hMenuAbout, MF_DISABLED | MF_GRAYED, 0, "Maximize box");
  1646. AppendMenu(hMenuAbout, MF_CHECKED | MFT_RADIOCHECK, menu_item_maximize_box_just_does_what_it_does, "just does what it does");
  1647. AppendMenu(hMenuAbout, MF_UNCHECKED, menu_item_maximize_box_is_either_disabled_or_hidden, "it is either disabled or hidden");
  1648. AppendMenu(hMenuAbout, MF_UNCHECKED, menu_item_maximize_box_asks_before_it_does_what_it_does, "it asks before it does what it does");
  1649. AppendMenu(hMenuAbout, MF_UNCHECKED, menu_item_maximize_box_just_shows_a_message_box, "just shows a message box");
  1650. AppendMenu(hMenuAbout, MF_UNCHECKED, menu_item_maximize_box_does_nothing, "it does nothing");
  1651. AppendMenu(hMenuAbout, MF_DISABLED | MF_GRAYED, 0, "Minimize box");
  1652. AppendMenu(hMenuAbout, MF_CHECKED | MFT_RADIOCHECK, menu_item_maximize_box_just_does_what_it_does, "just does what it does");
  1653. AppendMenu(hMenuAbout, MF_UNCHECKED, menu_item_minimize_box_is_either_disabled_or_hidden, "it is either disabled or hidden");
  1654. AppendMenu(hMenuAbout, MF_UNCHECKED, menu_item_minimize_box_asks_before_it_does_what_it_does, "it asks before it does what it does");
  1655. AppendMenu(hMenuAbout, MF_UNCHECKED, menu_item_minimize_box_just_shows_a_message_box, "just shows a message box");
  1656. AppendMenu(hMenuAbout, MF_UNCHECKED, menu_item_minimize_box_does_nothing, "it does nothing");
  1657. AppendMenu(hMenuAbout, MF_DISABLED | MF_GRAYED, 0, "Resize/Done");
  1658. AppendMenu(hMenuAbout, MF_DISABLED | MF_GRAYED, 0, "Enter fullscreen mode");
  1659. AppendMenu(hMenuAbout, MF_DISABLED | MF_GRAYED, 0, "Set Size");
  1660. AppendMenu(hMenuAbout, MF_DISABLED | MF_GRAYED, 0, "Pause/Resume");
  1661. AppendMenu(hMenuAbout, MF_DISABLED | MF_GRAYED, 0, "Hide");
  1662. AppendMenu(hMenu, MF_ENABLED, menu_item_set_map_size, "set map size");
  1663. AppendMenu(hMenu, MF_ENABLED, menu_item_map_is_immense, "map is immense");
  1664. HWND hWnd = CreateWindow("mdiclient", "route calculator", WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_VISIBLE,
  1665. (cxscreen - init_wnd_rect.right) / 2,
  1666. (cyscreen - init_wnd_rect.bottom) / 2, init_wnd_rect.right, init_wnd_rect.bottom, nullptr, hMenu, nullptr, nullptr);
  1667. //RECT client_rect = {0};
  1668. //GetClientRect(hWnd, &client_rect);
  1669. //if (client_rect.right != dibsection_width || client_rect.bottom != dibsection_height)
  1670. // MessageBox(hWnd, "Window client area was initialized badly!", "Warning", MB_ICONWARNING | MB_OK);
  1671. SetWindowLongPtr(hWnd, GWL_WNDPROC, (LONG)&WinProc);
  1672. bitmap_info.bmiHeader.biBitCount = 32;
  1673. bitmap_info.bmiHeader.biClrImportant = 0;
  1674. bitmap_info.bmiHeader.biClrUsed = 0;
  1675. bitmap_info.bmiHeader.biCompression = BI_RGB;
  1676. bitmap_info.bmiHeader.biHeight = -dibsection_height;
  1677. bitmap_info.bmiHeader.biPlanes = 1;
  1678. bitmap_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  1679. bitmap_info.bmiHeader.biSizeImage = 0;
  1680. bitmap_info.bmiHeader.biWidth = dibsection_width;
  1681. bitmap_info.bmiHeader.biXPelsPerMeter = 0;
  1682. bitmap_info.bmiHeader.biYPelsPerMeter = 0;
  1683. hDibSection = CreateDIBSection(nullptr, &bitmap_info, DIB_RGB_COLORS, (void**)&dibsection_colors, nullptr, 0);
  1684. SelectBitmap(dibsection_hdc, hDibSection);
  1685. SetStretchBltMode(dibsection_hdc, HALFTONE);
  1686. SetBkMode(dibsection_hdc, TRANSPARENT);
  1687. hRenderer = CreateThread(nullptr, 0, &Renderer, hWnd, 0, nullptr);
  1688. SetTimer(hWnd, timer_id_event_every_second, 1000, &every_second);
  1689. SetTimer(hWnd, timer_id_event_empty_animator, 100, &empty_animator);
  1690. SetTimer(hWnd, timer_id_event_character_animator, 100, &character_animator);
  1691. SetTimer(hWnd, timer_id_event_outside_animator, 100, &outside_animator);
  1692. MSG msg = {0};
  1693. while (GetMessage(&msg, hWnd, 0, 0) > 0)
  1694. {
  1695. TranslateMessage(&msg);
  1696. DispatchMessage(&msg);
  1697. }
  1698. Sleep(1000);
  1699. DeleteDC(dibsection_hdc);
  1700. DeleteBitmap(hDibSection);
  1701. KillTimer(hWnd, 0);
  1702. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement