/* XTERM MOUSE suport by M.Laak */ void xtermmouse_get_event (Bit8u **kbp, int *kbcount) { int btn; static int last_btn = 0; int x_pos, y_pos; /* Decode Xterm mouse information to a GPM style event */ if (*kbcount >= 3) { x_pos = (*kbp)[1] - 32; y_pos = (*kbp)[2] - 32; mouse_move_absolute(x_pos-1, y_pos-1, vga.text_width, vga.text_height); m_printf("XTERM MOUSE: movement (click follows) detected to pos x=%d: y=%d\n", x_pos, y_pos); /* Variable btn has following meaning: */ /* 0 = btn1 dn, 1 = btn2 dn, 2 = btn3 dn, 3 = btn up */ btn = (*kbp)[0] & 3; /* There seems to be no way of knowing which button was released */ /* So we assume all the buttons were released */ if (btn == 3){ if (last_btn) { mouse_move_buttons(0, 0, 0); m_printf("XTERM MOUSE: button release detected\n"); last_btn = 0; } } else { switch (btn) { case 0: mouse_move_buttons(1, 0, 0); m_printf("XTERM MOUSE: left button click detected\n"); last_btn = 1; break; case 1: mouse_move_buttons(0, 1, 0); m_printf("XTERM MOUSE: middle button click detected\n"); last_btn = 2; break; case 2: mouse_move_buttons(0, 0, 1); m_printf("XTERM MOUSE: right button click detected\n"); last_btn = 3; break; } } *kbcount -= 3; /* update count */ *kbp += 3; do_mouse_irq(); } }
void printBodies(const body *bodies, int body_count) { int i; for (i = 0; i < body_count; i++) m_printf("%i> Mass: %Le , Position: (%Le,%Le) , Velocity: (%Le,%Le)\n",i, bodies[i].mass, bodies[i].x, bodies[i].y, bodies[i].vx, bodies[i].vy); }
bool read_file_into_memory_arena(const char *file_path, memory_arena *memory_arena, void **file_data_ptr, uint *file_size_ptr) { HANDLE file_handle = CreateFileA(file_path, GENERIC_READ, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); if (file_handle == INVALID_HANDLE_VALUE) { m_last_error_str(err); m_printf("%s", err); return false; } m_scope_exit(CloseHandle(file_handle)); DWORD file_size = GetFileSize(file_handle, nullptr); if (file_size == INVALID_FILE_SIZE) { return false; } uint64 memory_arena_size = memory_arena->size; char *file_data = memory_arena_allocate<char>(memory_arena, file_size); DWORD cur_size = 0; for (;;) { DWORD n_to_read = file_size - cur_size; DWORD n_read; if (ReadFile(file_handle, file_data + cur_size, n_to_read, &n_read, nullptr) == FALSE) { memory_arena->size = memory_arena_size; return false; } if (n_read == 0) { if (cur_size != file_size) { memory_arena->size = memory_arena_size; return false; } break; } cur_size += n_read; } *file_data_ptr = file_data; *file_size_ptr = file_size; return true; }
static void xterm_mouse_close(void) { /* disable mouse tracking */ printf("\033[?1003l\033[?1002l\033[?1000l\033[9l"); /* restore old highlight mouse tracking */ printf("\033[?1001r\033[?1001l"); fflush(stdout); m_printf("XTERM MOUSE: Mouse tracking deinitialized\n"); }
static int SDL_mouse_init(void) { mouse_t *mice = &config.mouse; if (Video != &Video_SDL) return FALSE; mice->type = MOUSE_SDL; mouse_enable_native_cursor(config.X_fullscreen); /* we have the X cursor, but if we start fullscreen, grab by default */ m_printf("MOUSE: SDL Mouse being set\n"); return TRUE; }
void NetworkUpdate(lua_State* L) { if (peer != NULL) { for (packet = peer->Receive(); packet; peer->DeallocatePacket(packet), packet = peer->Receive()) { if (pRemoteFn[packet->data[0]] != NULL) { lua_rawgeti(L, LUA_REGISTRYINDEX, pRemoteFn[packet->data[0]]); if (lua_isfunction(L, -1)) { if (isServer) lua_pushinteger(L, packet->systemAddress.systemIndex + 1); RakNet::BitStream stream(packet->data, packet->length, false); stream.IgnoreBytes(sizeof(RakNet::MessageID)); lua_pushlightuserdata(L, &stream); if (isServer) { if (lua_pcall(L, 2, 0, 0) != 0) m_printf("%s", lua_tostring(L, -1)); } else { if (lua_pcall(L, 1, 0, 0) != 0) m_printf("%s", lua_tostring(L, -1)); } } else lua_remove(L, -1); } } } if (tcp != NULL && isServer) { if (tcp->ReceiveHasPackets()) { for (packet = tcp->Receive(); packet; tcp->DeallocatePacket(packet), packet = tcp->Receive()) { lua_getglobal(L, "onHTTP"); if (lua_isfunction(L, -1)) { lua_pushstring(L, (const char*)packet->data); lua_pushstring(L, (const char*)packet->systemAddress.ToString(false)); if (lua_pcall(L, 2, 1, 0) != 0) { m_printf("%s", lua_tostring(L, -1)); } else { const char* szResp = lua_tostring(L, -1); sprintf(szWebResponse, "HTTP/1.0 200 OK\nServer: RakNetLua_by_Pabloko\nConnection: close\nContent-Type: text/html; charset = UTF-8\nContent-Length: %d\n\n%s", strlen(szResp), szResp); tcp->Send(szWebResponse, strlen(szWebResponse), packet->systemAddress, false); } } else lua_remove(L, -1); } } } if (isExecutable) { int ch; while (_kbhit()) { ch = _getch(); if (ch == 0x0D) { printf("\n"); //m_printf("%s", szCmd); lua_getglobal(L, "onCmd"); if (lua_isfunction(L, -1)) { lua_pushstring(L, szCmd); if (lua_pcall(L, 1, 0, 0) != 0) m_printf("%s", lua_tostring(L, -1)); } else lua_remove(L, -1); sprintf(szCmd, ""); } else { printf("%c", ch); sprintf(szCmd, "%s%c", szCmd, ch); } } } }
DWORD game_loop_main(LPVOID thread_input) { struct common_vars common_vars = *(struct common_vars *)thread_input; profiler profiler = {}; profiler_create(&profiler); LARGE_INTEGER performance_frequency = {}; QueryPerformanceFrequency(&performance_frequency); memory_arena memory_arena = {}; if (!virtual_alloc_memory_arena(m_megabytes(16), common_vars.system_info.dwPageSize, &memory_arena)) { m_die("call to \"virtual_alloc_memory_arena\" failed(event_render_loop_thread memory arena)"); } vulkan vulkan = {}; { m_memory_arena_undo_allocations_at_scope_exit(&memory_arena); string info_string = { memory_arena_allocate<char>(&memory_arena, m_kilobytes(4)), 0, m_kilobytes(2) }; string err_string = { memory_arena_allocate<char>(&memory_arena, m_kilobytes(1)), 0, m_kilobytes(1) }; vulkan_create_info vulkan_create_info = {}; vulkan_create_info.win32_instance = common_vars.instance; vulkan_create_info.win32_window = common_vars.window; const char *shader_file_paths[] = { "shaders\\swap_chain_pipeline_image.vert.spv", "shaders\\swap_chain_pipeline_image.frag.spv" }; if (!read_file_into_memory_arena(shader_file_paths[0], &memory_arena, &vulkan_create_info.swap_chain_pipeline_image_code[0], &vulkan_create_info.swap_chain_pipeline_image_code_sizes[0]) || !read_file_into_memory_arena(shader_file_paths[1], &memory_arena, &vulkan_create_info.swap_chain_pipeline_image_code[1], &vulkan_create_info.swap_chain_pipeline_image_code_sizes[1])) { m_die("call to \"read_file_into_memory_arena\" failed(swap_chain_pipeline_image shaders)"); } if (!vulkan_create(vulkan_create_info, &memory_arena, &info_string, &err_string, &vulkan)) { m_die("%s", err_string.buf); } else { m_printf("%s", info_string.buf); } } game_buffer game_buffer = {}; vec4 game_buffer_viewport = {}; HANDLE game_buffer_gpk_file_handle = nullptr; HANDLE game_buffer_gpk_file_mapping = nullptr; void *game_buffer_gpk_file_mapping_ptr = nullptr; HANDLE game_buffer_mpk_import_shared_memory_mapping = nullptr; void *game_buffer_mpk_import_shared_memory_mapping_ptr = nullptr; HANDLE game_buffer_mpk_import_shared_memory_semaphore = nullptr; { game_buffer_create_info game_buffer_create_info = {}; if (!virtual_alloc_memory_arena(m_megabytes(512), common_vars.system_info.dwPageSize, &game_buffer_create_info.memory_arena)) { m_die("call to \"virtual_alloc_memory_arena\" failed(game buffer memory arena)"); } game_buffer_create_info.vulkan = &vulkan; game_buffer_create_info.vulkan_framebuffer_width = 1920; game_buffer_create_info.vulkan_framebuffer_height = 1080; if (!game_buffer_create(game_buffer_create_info, &game_buffer)) { m_die("call to \"game_buffer_create\" failed"); } #ifdef EDITOR_ENABLE game_buffer_editor_create_info game_buffer_editor_create_info = {}; game_buffer_editor_create_info.game_buffer = &game_buffer; game_buffer_editor_create_info.vulkan = &vulkan; game_buffer_editor_create_info.imgui_init_file = "assets\\gpks\\example.gpk.imgui.ini"; game_buffer_editor_create_info.imgui_font_file = "assets\\fonts\\OpenSans-Regular.ttf"; game_buffer_editor_create_info.imgui_font_size = GetSystemMetrics(SM_CXSCREEN) / 150; game_buffer_editor_create_info.set_imgui_keymap = [] (ImGuiIO *imgui_io) { imgui_io->KeyMap[ImGuiKey_Tab] = VK_TAB; imgui_io->KeyMap[ImGuiKey_LeftArrow] = VK_LEFT; imgui_io->KeyMap[ImGuiKey_RightArrow] = VK_RIGHT; imgui_io->KeyMap[ImGuiKey_UpArrow] = VK_UP; imgui_io->KeyMap[ImGuiKey_DownArrow] = VK_DOWN; imgui_io->KeyMap[ImGuiKey_PageUp] = VK_PRIOR; imgui_io->KeyMap[ImGuiKey_PageDown] = VK_NEXT; imgui_io->KeyMap[ImGuiKey_Home] = VK_HOME; imgui_io->KeyMap[ImGuiKey_End] = VK_END; imgui_io->KeyMap[ImGuiKey_Backspace] = VK_BACK; imgui_io->KeyMap[ImGuiKey_Enter] = VK_RETURN; imgui_io->KeyMap[ImGuiKey_Escape] = VK_ESCAPE; imgui_io->KeyMap[ImGuiKey_A] = 'A'; imgui_io->KeyMap[ImGuiKey_C] = 'C'; imgui_io->KeyMap[ImGuiKey_V] = 'V'; imgui_io->KeyMap[ImGuiKey_X] = 'X'; imgui_io->KeyMap[ImGuiKey_Y] = 'Y'; imgui_io->KeyMap[ImGuiKey_Z] = 'Z'; }; { m_memory_arena_undo_allocations_at_scope_exit(&memory_arena); const char *file_paths[] = { "shaders\\imgui.vert.spv", "shaders\\imgui.frag.spv" }; VkShaderModule shader_modules[m_countof(file_paths)] = {}; for (uint i = 0; i < m_countof(file_paths); i += 1) { void *file_data; uint file_size; if (!read_file_into_memory_arena(file_paths[i], &memory_arena, &file_data, &file_size)) { m_die("call to \"read_file_into_memory_arena\" failed(game buffer shader files)"); } VkShaderModuleCreateInfo shader_module_info = { VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO }; shader_module_info.codeSize = file_size; shader_module_info.pCode = (const uint32_t *)file_data; if(vkCreateShaderModule(vulkan.device, &shader_module_info, nullptr, &shader_modules[i]) != VK_SUCCESS) { m_die("game buffer creation failed\ncall to \"vkCreateShaderModule\" failed for shader file %s", file_paths[i]); } } game_buffer_editor_create_info.imgui_vulkan_shaders[0] = shader_modules[0]; game_buffer_editor_create_info.imgui_vulkan_shaders[1] = shader_modules[1]; } game_buffer.editor = memory_arena_allocate<game_buffer_editor>(&game_buffer.memory_arena, 1); *game_buffer.editor = {}; if (!game_buffer_editor_create(&game_buffer_editor_create_info, game_buffer.editor)) { m_die("call to \"game_buffer_editor_create\" failed"); } { uint shared_memory_size = m_megabytes(32); HANDLE shared_memory_mapping = CreateFileMappingA(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE | SEC_COMMIT, 0, shared_memory_size, m_mpk_import_shared_memory_name); if (!shared_memory_mapping) { m_last_error_str(err_str); m_die("call to \"CreateFileMappingA\" failed\nfile: %s\nerr: %s", m_mpk_import_shared_memory_name, err_str); } void *shared_memory_mapping_ptr = MapViewOfFile(shared_memory_mapping, FILE_MAP_WRITE, 0, 0, shared_memory_size); if (!shared_memory_mapping_ptr) { m_last_error_str(err_str); m_die("call to \"MapViewOfFile\" failed\nfile: %s\nerr: %s", m_mpk_import_shared_memory_name, err_str); } ((mpk_import_shared_memory_header *)shared_memory_mapping_ptr)->total_size = shared_memory_size; ((mpk_import_shared_memory_header *)shared_memory_mapping_ptr)->mpk_size = shared_memory_size - sizeof(struct mpk_import_shared_memory_header); SetLastError(ERROR_SUCCESS); HANDLE shared_memory_semaphore = CreateSemaphore(nullptr, 1, 1, m_mpk_import_shared_memory_semaphore_name); if (!shared_memory_semaphore) { m_last_error_str(err_str); m_die("call to \"CreateSemaphore\" failed\nsemaphore: %s\nerr: %s", m_mpk_import_shared_memory_semaphore_name, err_str); } if (GetLastError() == ERROR_ALREADY_EXISTS) { m_die("call to \"CreateSemaphore\" failed\nsemaphore: %s\nerr: %s", m_mpk_import_shared_memory_semaphore_name, "named semaphore already exist"); } game_buffer_mpk_import_shared_memory_mapping = shared_memory_mapping; game_buffer_mpk_import_shared_memory_mapping_ptr = shared_memory_mapping_ptr; game_buffer_mpk_import_shared_memory_semaphore = shared_memory_semaphore; } { game_buffer_editor_job *new_job = nullptr; if (game_buffer_editor_add_mpk_job(&game_buffer, &new_job)) { mpk_import_command_line cmdl = m_mpk_import_command_line_default; cmdl.job_id = new_job->id; cmdl.import_type = mpk_import_type_fbx; strcpy(cmdl.fbx_file_path, "assets\\models\\simple_man\\simple_man.fbx"); mpk_import_create_process(&cmdl, common_vars.process_group, &memory_arena); } } #endif // EDITOR_ENABLE { char gpk_file_name[] = "assets\\gpks\\example.gpk"; HANDLE gpk_file_handle = CreateFileA(gpk_file_name, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); if (gpk_file_handle == INVALID_HANDLE_VALUE) { m_last_error_str(err_str); m_die("call to \"CreateFile\" failed\nfile: %s\nerr: %s", gpk_file_name, err_str); } uint file_size = m_megabytes(32); SetFilePointer(gpk_file_handle, file_size, nullptr, FILE_BEGIN); if (!SetEndOfFile(gpk_file_handle)) { m_last_error_str(err_str); m_die("call to \"SetEndOfFile\" failed\nfile: %s\nsize: %d\nerr: %s", gpk_file_name, file_size, err_str); } HANDLE gpk_file_mapping = CreateFileMappingA(gpk_file_handle, nullptr, PAGE_READWRITE, 0, 0, nullptr); if (!gpk_file_mapping) { m_last_error_str(err_str); m_die("call to \"CreateFileMappingA\" failed\nfile: %s\nerr: %s", gpk_file_name, err_str); } void *gpk_file_mapping_ptr = MapViewOfFile(gpk_file_mapping, FILE_MAP_WRITE, 0, 0, file_size); if (!gpk_file_mapping_ptr) { m_last_error_str(err_str); m_die("call to \"MapViewOfFile\" failed\nfile: %s\nerr: %s", gpk_file_name, err_str); } uint gpk_file_initial_state_size = 0; if (!gpk_write_initial_state(gpk_file_mapping_ptr, file_size, &gpk_file_initial_state_size)) { m_die("call to \"gpk_write_initial_state\" failed"); } if (!FlushViewOfFile(gpk_file_mapping_ptr, gpk_file_initial_state_size)) { m_last_error_str(err_str); m_die("call to \"FlushViewOfFile\" failed\nfile: %s\nerr: %s", gpk_file_name, err_str); } game_buffer_gpk_file_handle = gpk_file_handle; game_buffer_gpk_file_mapping = gpk_file_mapping; game_buffer_gpk_file_mapping_ptr = gpk_file_mapping_ptr; } { game_buffer_update_vulkan_swap_chain_image(&game_buffer, &vulkan); game_buffer_viewport = rectangle_fit_into_viewport((float)vulkan.swap_chain_info.imageExtent.width, (float)vulkan.swap_chain_info.imageExtent.height, (float)game_buffer.vulkan_framebuffer_image_width, (float)game_buffer.vulkan_framebuffer_image_height); } } uint64 last_frame_time_microsecs = 0; bool mouse_down_up_same_frame[3] = {}; for (;;) { LARGE_INTEGER frame_begin_performance_count; QueryPerformanceCounter(&frame_begin_performance_count); m_scope_exit( LARGE_INTEGER frame_end_performance_count; QueryPerformanceCounter(&frame_end_performance_count); last_frame_time_microsecs = (frame_end_performance_count.QuadPart - frame_begin_performance_count.QuadPart) * 1000000 / performance_frequency.QuadPart; ); { bool mouse_down_this_frame[3] = {}; for (uint i = 0; i < 3; i += 1) { if (mouse_down_up_same_frame[i]) { mouse_down_up_same_frame[i] = false; #ifdef EDITOR_ENABLE game_buffer_editor_handle_mouse_up(&game_buffer, i); #endif } } HANDLE iocp = common_vars.io_completion_port; DWORD iocp_num_bytes = 0; ULONG_PTR iocp_completion_key = 0; LPOVERLAPPED iocp_overlapped = nullptr; DWORD iocp_time_out = 0; while (GetQueuedCompletionStatus(iocp, &iocp_num_bytes, &iocp_completion_key, &iocp_overlapped, iocp_time_out) == TRUE) { switch (iocp_completion_key) { case quit_win_main_event : { #ifdef EDITOR_ENABLE ImGui::Shutdown(); #endif ExitThread(0); } break; case window_resize_event : { uint32 new_width = LOWORD((LPARAM)iocp_overlapped); uint32 new_height = HIWORD((LPARAM)iocp_overlapped); if (vulkan.swap_chain_info.imageExtent.width != new_width || vulkan.swap_chain_info.imageExtent.height != new_height) { if (!vulkan_resize_swap_chain_images(&vulkan, new_width, new_height)) { m_die("call to \"vulkan_resize_swap_chain_images\" failed"); } game_buffer_viewport = rectangle_fit_into_viewport((float)vulkan.swap_chain_info.imageExtent.width, (float)vulkan.swap_chain_info.imageExtent.height, (float)game_buffer.vulkan_framebuffer_image_width, (float)game_buffer.vulkan_framebuffer_image_height); } } break; case key_down_event : { } break; case key_up_event : { } break; case mouse_move_event : { #ifdef EDITOR_ENABLE game_buffer_editor_handle_mouse_move(&game_buffer, game_buffer_viewport, LOWORD((LPARAM)iocp_overlapped), HIWORD((LPARAM)iocp_overlapped)); #endif } break; case mouse_lbutton_down_event : { mouse_down_this_frame[0] = true; #ifdef EDITOR_ENABLE game_buffer_editor_handle_mouse_down(&game_buffer, 0); #endif } break; case mouse_lbutton_up_event : { if (mouse_down_this_frame[0]) { mouse_down_up_same_frame[0] = true; } else { #ifdef EDITOR_ENABLE game_buffer_editor_handle_mouse_up(&game_buffer, 0); #endif } } break; case mouse_rbutton_down_event : { mouse_down_this_frame[1] = true; #ifdef EDITOR_ENABLE game_buffer_editor_handle_mouse_down(&game_buffer, 1); #endif } break; case mouse_rbutton_up_event : { if (mouse_down_this_frame[1]) { mouse_down_up_same_frame[1] = true; } else { #ifdef EDITOR_ENABLE game_buffer_editor_handle_mouse_up(&game_buffer, 1); #endif } } break; case mpk_import_named_pipe_event : { #ifdef EDITOR_ENABLE mpk_import_named_pipe_instance *named_pipe_instance = (mpk_import_named_pipe_instance *)iocp_overlapped; if (named_pipe_instance->connected) { m_printf("got message %d bytes: %s\n", iocp_num_bytes, named_pipe_instance->message.msg); game_buffer_editor_handle_mpk_import_message(&game_buffer, &named_pipe_instance->message); if (named_pipe_instance->message.type == mpk_import_named_pipe_message_type_done) { void *mpk_ptr = ((struct mpk_import_shared_memory_header *)game_buffer_mpk_import_shared_memory_mapping_ptr) + 1; struct mpk_header *mpk_header_ptr = (struct mpk_header *)mpk_ptr; ReleaseSemaphore(game_buffer_mpk_import_shared_memory_semaphore, 1, nullptr); } ReadFile(named_pipe_instance->handle, &named_pipe_instance->message, sizeof(named_pipe_instance->message), nullptr, &named_pipe_instance->overlapped); } else { m_printf("new named pipe instance connected\n"); named_pipe_instance->connected = true; ReadFile(named_pipe_instance->handle, &named_pipe_instance->message, sizeof(named_pipe_instance->message), nullptr, &named_pipe_instance->overlapped); mpk_import_add_named_pipe_instance(&common_vars); } #else m_die("game loop main: received event \"mpk_import_named_pipe_event\", but editor is not enabled"); #endif } break; default : { m_die("game loop main: call to \"GetQueuedCompletionStatus\" returned an invalid event"); } break; } } } #ifdef EDITOR_ENABLE game_buffer.editor->imgui_io->DeltaTime = (float)(last_frame_time_microsecs / 1000000.0); ImGui::NewFrame(); game_buffer_editor_imgui_new_frame(&game_buffer, &vulkan); #endif { VkResult vk_result = {}; vkWaitForFences(vulkan.device, 1, &vulkan.swap_chain_fence, VK_TRUE, UINT64_MAX); vkResetFences(vulkan.device, 1, &vulkan.swap_chain_fence); uint swap_chain_image_index = 0; if ((vk_result = vkAcquireNextImageKHR(vulkan.device, vulkan.swap_chain, UINT64_MAX, vulkan.swap_chain_image_semaphore, VK_NULL_HANDLE, &swap_chain_image_index)) != VK_SUCCESS) { m_die("call to \"vkAcquireNextImageKHR\" failed"); } VkCommandBufferBeginInfo cmd_buffer_begin_info = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; cmd_buffer_begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; vkBeginCommandBuffer(vulkan.swap_chain_cmd_buffer, &cmd_buffer_begin_info); game_buffer_record_vulkan_commands(&game_buffer, &vulkan); vulkan_record_swap_chain_commands(&vulkan, swap_chain_image_index, game_buffer_viewport); vkEndCommandBuffer(vulkan.swap_chain_cmd_buffer); VkSubmitInfo queue_submit_info = { VK_STRUCTURE_TYPE_SUBMIT_INFO }; queue_submit_info.waitSemaphoreCount = 1; queue_submit_info.pWaitSemaphores = &vulkan.swap_chain_image_semaphore; VkPipelineStageFlags wait_dst_stage_mask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; queue_submit_info.pWaitDstStageMask = &wait_dst_stage_mask; queue_submit_info.commandBufferCount = 1; queue_submit_info.pCommandBuffers = &vulkan.swap_chain_cmd_buffer; queue_submit_info.signalSemaphoreCount = 1; queue_submit_info.pSignalSemaphores = &vulkan.swap_chain_queue_semaphore; if ((vk_result = vkQueueSubmit(vulkan.device_queue, 1, &queue_submit_info, vulkan.swap_chain_fence)) != VK_SUCCESS) { m_die("call to \"vkQueueSubmit\" failed"); } VkPresentInfoKHR device_queue_present_info = { VK_STRUCTURE_TYPE_PRESENT_INFO_KHR }; device_queue_present_info.waitSemaphoreCount = 1; device_queue_present_info.pWaitSemaphores = &vulkan.swap_chain_queue_semaphore; device_queue_present_info.swapchainCount = 1; device_queue_present_info.pSwapchains = &vulkan.swap_chain; device_queue_present_info.pImageIndices = &swap_chain_image_index; if ((vk_result = vkQueuePresentKHR(vulkan.device_queue, &device_queue_present_info)) != VK_SUCCESS) { m_die("call to \"vkQueuePresentKHR\" failed"); } } }
void printhelp() { m_printf("Usage:\n"); m_printf("-f Input path of initial setting (DEFAULT: init.dat)\n"); m_printf("-i Prefix for image creation (DEFAULT: PBM)\n"); m_printf("-o Output path for saving the resulting state of bodies. (DEFAULT: result.dat)\n"); m_printf("-p BOOL Parallel execution using OpenMP. (DEFAULT: false)\n"); m_printf("-s INT Number of simulation steps (DEFAULT: 365)\n"); m_printf("-d INT Step size of the simulation (DEFAULT: 1)\n"); m_printf("-g BOOL Generate PBM images of intermediate results. (DEFAULT: false)\n"); m_printf("-x INT Generate a PBM image of the current setting every x simulation steps (DEFAULT: 1000)\n"); m_printf("-m INT Used in conjunction with -p. Parallel execution using OpenMP + MPI by locally applying Newton's Third Law for every MPI process.\n"); m_printf("-n INT Used in conjunction with -p and -m. Parallel execution using OpenMP + MPI by globally applying Newton's Third Law across all MPI processes, thus halfing the required computations.\n"); m_printf("-h This message\n"); }
int main(int argc, char **argv) { int option, steps = 365, delta = 1, body_count; char *input = "init.dat", *output = "result.dat"; bool parallel = false, mpi = false, global_newton = false; long double start; long double px, py; imggen_info img_info; body *bodies = NULL; /* PBM default values */ img_info.gen_img = false; img_info.img_steps = 1000; img_info.img_prefix = "PBM"; img_info.offset = 2; img_info.width = 600; img_info.heigth = 600; /* Read cmdline params */ while ((option = getopt(argc,argv,"phs:d:f:o:i:x:gmn")) != -1) { switch(option) { case 'p': parallel = true; break; case 's': steps = atoi(optarg); break; case 'd': delta = atoi(optarg); break; case 'f': input = optarg; break; case 'o': output = optarg; break; case 'i': img_info.img_prefix = optarg; break; case 'x': img_info.img_steps = atoi(optarg); break; case 'g': img_info.gen_img = true; break; case 'm': mpi = true; break; case 'n': global_newton = true; break; default: printhelp(); return 1; } } /* Init MPI */ MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &mpi_processors); MPI_Comm_rank(MPI_COMM_WORLD, &mpi_self); /* Validate params */ if (steps < 0 || delta < 1 || img_info.img_steps < 1) { m_printf("Wrong parameter value! Will exit!\n Steps: %i | Delta: %i | Input Filepath: %s", steps, delta, input); } bodies = readBodies(fopen(input,"r"), &body_count); if (bodies == NULL) { m_printf("Error while reading input file %s. Will exit now!\n", input); MPI_Finalize(); return 1; } /* Assert that all masses > 0 and any two particles do not share the same position */ if (!examineBodies(bodies, body_count, &img_info.max_x, &img_info.max_y)) { m_printf("Error while reading input file %s. Some value are not permitted!\n", input); printBodies(bodies, body_count); MPI_Finalize(); return 1; } totalImpulse(bodies, body_count, &px, &py); m_printf("Initial total impulse: px = %Le , py = %Le\n", px, py); MPI_Barrier(MPI_COMM_WORLD); start = seconds(); if (parallel) { m_printf("PARALLEL\n"); if (mpi) { m_printf("MPI+OMP\n"); if (global_newton) { m_printf("GLOBAL NEWTON\n"); solve_parallel_mpi_global_newton(bodies, body_count, steps, delta, img_info); } else { solve_parallel_mpi(bodies, body_count, steps, delta, img_info); } } else { m_printf("OMP\n"); solve_parallel(bodies, body_count, steps, delta, img_info); } } else { m_printf("SEQUENTIAL\n"); solve_sequential(bodies, body_count, steps, delta, img_info); } MPI_Barrier(MPI_COMM_WORLD); long double elapsed = seconds() - start; m_printf("Rate of interactions: %Lf\n", interactions(body_count, steps, elapsed)); m_printf("Elapsed time: %Lf\n", elapsed); totalImpulse(bodies, body_count, &px, &py); m_printf("Resulting total impulse: px = %Le , py = %Le\n", px, py); /* Write result to file */ FILE *f = fopen(output,"w"); if (f == NULL) { m_printf("Error while opening output file %s.\n", output); MPI_Finalize(); return 1; } writeBodies(f, bodies, body_count); MPI_Finalize(); return 0; }
inline void solve_parallel_mpi_global_newton(body *bodies, int body_count, int steps, int delta, imggen_info img_info) { int x, i, j, reduce_send_c = body_count*2, computations = (body_count) * (body_count-1) / 2,comp_sum = 0, low[mpi_processors], high[mpi_processors], recvcounts[mpi_processors], high_s, low_s, gather_sendcount; long double tmp1, tmp2, tmp3, tmp4, constants[body_count][body_count], delta_tmp = delta * 0.5, meters = MAX(img_info.max_x, img_info.max_y); vector *mutual_f = (vector *) malloc(sizeof(vector) * body_count); vector *combined_f = (vector *) malloc(sizeof(vector) * body_count); MPI_Datatype body_t; void *gather_base; /* * New datatype for positions within body struct. */ int t_xblens[] = {1,2,1}; MPI_Aint t_xdispls[] = {0,12,sizeof(body)}; MPI_Datatype t_xtypes[] = {MPI_LB, MPI_LONG_DOUBLE,MPI_UB}; MPI_Datatype pos_t; MPI_Type_create_struct(3, t_xblens, t_xdispls, t_xtypes, &pos_t); MPI_Type_commit(&pos_t); /* * New datatype for body struct. */ MPI_Type_contiguous(5, MPI_LONG_DOUBLE, &body_t); MPI_Type_commit(&body_t); /* * New datatype for vector struct. */ //MPI_Type_contiguous(2, MPI_LONG_DOUBLE, &vector_t); //MPI_Type_commit(&vector_t); //MPI_Op_create(vectorSum, true, &vectorSumOp); if (body_count < mpi_processors) { m_printf("bodies < processes - Will exit now!\n"); MPI_Finalize(); exit(1); } /* * Distribution params. */ j = 0; for(i = 0; i < mpi_processors; i++) { comp_sum = 0; low[i] = j; for (; j < body_count && comp_sum <= computations / mpi_processors; j++) { comp_sum += body_count - j+1; } high[i] = j; if(i == mpi_processors - 1) high[i] = body_count; recvcounts[i] = high[i] - low[i]; //m_printf("Process %i gets rows %i to %i with %i computations\n", i, low[i],high[i], comp_sum); } high_s = high[mpi_self]; low_s = low[mpi_self]; gather_base = bodies + low_s; gather_sendcount = recvcounts[mpi_self]; #pragma omp parallel for private (j) for (i = low_s; i < high_s; i++) for (j = i+1; j < body_count; j++) constants[i][j] = G * bodies[j].mass * bodies[i].mass * delta; for (x = 0; x < steps; x++) { for (i = 0; i < body_count; i++) { mutual_f[i].x = 0; mutual_f[i].y = 0; } #pragma omp parallel private (i, j, tmp1, tmp2, tmp3, tmp4) { vector sum[body_count]; for (i = 0; i < body_count; i++) { sum[i].x = 0; sum[i].y = 0; mutual_f[i].x = 0; mutual_f[i].y = 0; } #pragma omp for nowait for (i = low_s; i < high_s; i++) { for(j = i+1; j < body_count; j++) { tmp2 = bodies[j].x - bodies[i].x; tmp3 = bodies[j].y - bodies[i].y; tmp4 = tmp2*tmp2 + tmp3*tmp3; tmp4 *= sqrtl(tmp4); tmp1 = constants[i][j]/tmp4; long double tmp_x = tmp1*tmp2; long double tmp_y = tmp1*tmp3; sum[i].x += tmp_x; sum[i].y += tmp_y; sum[j].x -= tmp_x; sum[j].y -= tmp_y; } } for (i = 0; i < body_count; i++) { #pragma omp critical { mutual_f[i].x += sum[i].x; mutual_f[i].y += sum[i].y; } } } /* Reduce partial sums */ MPI_Allreduce(mutual_f, combined_f, reduce_send_c, MPI_LONG_DOUBLE, MPI_SUM, MPI_COMM_WORLD); #pragma omp parallel for private (tmp2, tmp3) for (i = low_s; i < high_s; i++) { tmp2 = combined_f[i].x; tmp3 = combined_f[i].y; /* Acceleration */ long double m = bodies[i].mass; tmp2 /= m; tmp3 /= m; /* Update position and velocity */ long double vx = bodies[i].vx; long double vy = bodies[i].vy; bodies[i].x = bodies[i].x + vx * delta + tmp2 * delta_tmp; bodies[i].y = bodies[i].y + vy * delta + tmp3 * delta_tmp; bodies[i].vx = vx + tmp2; bodies[i].vy = vy + tmp3; } /* Exchange positions */ MPI_Allgatherv(gather_base, gather_sendcount, pos_t, bodies, recvcounts, low, pos_t, MPI_COMM_WORLD); /* Save an image of intermediate results. */ if (img_info.gen_img && x % img_info.img_steps == 0 && mpi_self == MASTER) { saveImage(x, bodies, body_count, img_info.offset * meters, img_info.offset * meters, img_info.width, img_info.heigth, img_info.img_prefix); } } /* Consolidate data */ MPI_Allgatherv(gather_base, gather_sendcount, body_t, bodies, recvcounts, low, body_t, MPI_COMM_WORLD); /* Free custom MPI datatype */ MPI_Type_free(&body_t); free(mutual_f); free(combined_f); }
inline void solve_parallel_mpi(body *bodies, int body_count, int steps, int delta, imggen_info img_info) { int x, i, j, low[mpi_processors], high[mpi_processors], recvcounts[mpi_processors], high_s, low_s, gather_sendcount, computations = (body_count) * (body_count-1) / 2, comp_sum = 0; long double tmp2, tmp3, tmp4, constants[body_count][body_count], delta_tmp = delta * 0.5, meters = MAX(img_info.max_x, img_info.max_y); vector mutual_f[body_count][body_count]; MPI_Datatype body_t; void *gather_base; /* * New datatype for positions within body struct. */ int t_xblens[] = {1,2,1}; MPI_Aint t_xdispls[] = {0,12,sizeof(body)}; MPI_Datatype t_xtypes[] = {MPI_LB, MPI_LONG_DOUBLE,MPI_UB}; MPI_Datatype pos_t; MPI_Type_create_struct(3, t_xblens, t_xdispls, t_xtypes, &pos_t); MPI_Type_commit(&pos_t); /* * New datatype for body struct. */ MPI_Type_contiguous(5, MPI_LONG_DOUBLE, &body_t); MPI_Type_commit(&body_t); if (body_count < mpi_processors) { m_printf("bodies < processes - Will exit now!\n"); MPI_Finalize(); exit(1); } /* * Distribution params. */ j = 0; for(i = 0; i < mpi_processors; i++) { comp_sum = 0; low[i] = j; for (; j < body_count && comp_sum <= computations / mpi_processors; j++) { comp_sum += body_count - j+1; } high[i] = j; if(i == mpi_processors - 1) high[i] = body_count; recvcounts[i] = high[i] - low[i]; //m_printf("Process %i gets rows %i to %i with %i computations\n", i, low[i],high[i], comp_sum); } high_s = high[mpi_self]; low_s = low[mpi_self]; gather_base = bodies + low_s; gather_sendcount = recvcounts[mpi_self]; #pragma omp parallel for private (j) for (i = low_s; i < high_s; i++) for (j = 0; j < body_count; j++) constants[i][j] = G * bodies[j].mass * bodies[i].mass * delta; for (x = 0; x < steps; x++) { #pragma omp parallel for private (j, tmp2, tmp3, tmp4) for (i = low_s; i < high_s; i++) { for(j = 0; j < body_count; j++) { if (j < low_s || j > i) { tmp2 = bodies[j].x - bodies[i].x; tmp3 = bodies[j].y - bodies[i].y; tmp4 = tmp2*tmp2 + tmp3*tmp3; tmp4 *= sqrtl(tmp4); long double tmp1 = constants[i][j]/tmp4; mutual_f[i][j].x = tmp1 * tmp2; mutual_f[i][j].y = tmp1 * tmp3; } } } #pragma omp parallel for private (j, tmp2, tmp3) for (i = low_s; i < high_s; i++) { tmp2 = 0; tmp3 = 0; for(j = 0; j < body_count; j++) { if (j < low_s || j > i) { tmp2 += mutual_f[i][j].x; tmp3 += mutual_f[i][j].y; } else if (i != j) { tmp2 -= mutual_f[j][i].x; tmp3 -= mutual_f[j][i].y; } } /* Acceleration */ tmp2 /= bodies[i].mass; tmp3 /= bodies[i].mass; /* Update position and velocity */ bodies[i].x = bodies[i].x + bodies[i].vx * delta + tmp2 * delta_tmp; bodies[i].y = bodies[i].y + bodies[i].vy * delta + tmp3 * delta_tmp; bodies[i].vx = bodies[i].vx + tmp2; bodies[i].vy = bodies[i].vy + tmp3; } /* Exchange positions */ MPI_Allgatherv(gather_base, gather_sendcount, pos_t, bodies, recvcounts, low, pos_t, MPI_COMM_WORLD); /* Save an image of intermediate results. */ if (img_info.gen_img && x % img_info.img_steps == 0 && mpi_self == MASTER) { saveImage(x, bodies, body_count, img_info.offset * meters, img_info.offset * meters, img_info.width, img_info.heigth, img_info.img_prefix); } } /* Consolidate data */ MPI_Allgatherv(gather_base, gather_sendcount, body_t, bodies, recvcounts, low, body_t, MPI_COMM_WORLD); /* Free custom MPI datatype */ MPI_Type_free(&body_t); }
int main( void) { FILE *fp; MATRIX_T *a, *b, *c, *d, *inverse, *test, *x, *ainv; double D; /* initialize all MATRIX_T pointers to NULL */ a = NULL; b = NULL; c = NULL; d = NULL; inverse = NULL; test = NULL; x = NULL; ainv = NULL; /* it is good practice to reset the error code before doing matrix calculations */ m_reseterr(); /* open matrix file to initialize matrix variables */ if ((fp = fopen("mtest1.mat","r"))==NULL) { printf("cannot open file mtest1.mat\n"); exit(0); } /* use m_printf functions here */ /* test matrix addition */ a = m_fnew( fp); m_printf( "\n# matrix a from file: mtest1.mat", "%6.2f", a); b = m_fnew( fp); m_printf( "\n# matrix b from: mtest1.mat", "%6.2f", b); c = m_new( 3, 2); c = m_add( c, a, b); m_printf( "\n# sum of a and b", "%6.2f", c); /* test matrix subtraction */ c = m_sub( c, a, b); m_printf( "\n# difference of a and b", "%6.2f", c); /* change to using comma separated format output */ /* multiply matrix by a constant */ printf( "\ncomma separated format: matrix a\n"); m_fputcsv(stdout,a); printf( "\ncomma separated format: matrix c\n"); m_fputcsv(stdout,c); m_mupconst( c, 2.5, a); printf( "\ncsv format: 2.5 times matrix c\n"); m_fputcsv(stdout,c); /* find maximum element in matrix */ printf( "\nmax element in c is %f\n", m_max_abs_element(c)); /* test euclidean norm */ d = m_fnew( fp); printf( "\ncsv format: matrix d\n"); m_fputcsv(stdout,d); printf( "\neuclidean norm of d is %f\n", m_e_norm( d)); /* test assignment of identity matrix to a square matrix */ inverse = m_new( d->rows, d->cols); m_assign_identity( inverse); m_printf( "\nidentity matrix", "%6.2f", inverse); /* test matrix inversion */ inverse = m_inverse( inverse, d, &D, 0.0001); test = m_new(d->rows,d->cols); test = m_mup( test, d, inverse); m_printf( "\nmatrix d", "%6.2f", d); m_printf( "\nmatrix inverse", "%6.2f", inverse); m_printf( "\nproduct of d and d-inverse", "%6.2f", test); /* test solution of linear equations */ /* start by getting new values for matrices a and b note: b is a 1 by n vector (as is x) */ if ((a = m_fnew( fp)) == NULL) exit(0); if ((b = m_fnew( fp)) == NULL) exit(0); if ((x = m_new(b->rows,b->cols)) == NULL) exit(0); printf("\ncsv: a\n"); m_fputcsv(stdout,a); printf("\ncsv: b\n"); m_fputcsv(stdout,b); x = m_solve( x, a, b, 0.0000001); printf("\n\nx=ab\ncsv: solution x\n"); m_fputcsv(stdout,x); /* close files and clean up */ fclose(fp); m_free(a); m_free(b); m_free(c); m_free(d); m_free(inverse); m_free(test); m_free(x); m_free(ainv); }