Advertisement
Tkap1

Untitled

Jul 13th, 2024
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 15.77 KB | None | 0 0
  1. // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv     FRAME START     vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
  2. f64 last_time = 0;
  3. while(running > 0) {
  4.     f64 now = performance_counter.get_ms();
  5.     f64 ms_passed = now - last_time;
  6.     g_platform_shared.delta = (ms_passed * 0.001);
  7.     last_time = now;
  8.  
  9.     while(PeekMessageA(&msg, null, 0, 0, PM_REMOVE))
  10.     {
  11.         if(LOWORD(msg.message) == WM_QUIT)
  12.         {
  13.             // @Note(tkap): We get a WM_QUIT message because we destroy the fake window, so we want to actually
  14.             // receive 2 WM_QUIT messages to quit. That is why we initially set "running" to 2 instead of 1 (true)
  15.             running -= 1;
  16.         }
  17.         TranslateMessage(&msg);
  18.         DispatchMessage(&msg);
  19.     }
  20.  
  21.     game_window.w = (float)g_window_width;
  22.     game_window.h = (float)g_window_height;
  23.     game_window.center.x = g_window_width / 2.0f;
  24.     game_window.center.y = g_window_height / 2.0f;
  25.  
  26.     la_reset(&game_network.arena);
  27.     la_reset(&arenas.string_arena);
  28.     assert(game_network.arena.push_count == 0);
  29.  
  30.     // @Note(tkap): This wont work for release, because we are targeting "build" directory.
  31.     // Not that it should, since release + internal makes no sense
  32.     #ifdef m_debug_internal
  33.     constexpr char* original_path = "build\\game.dll";
  34.     constexpr char* temp_path = "build\\temp_game.dll";
  35.     FILETIME time = get_last_write_time(original_path);
  36.     if(CompareFileTime(&dll_last_write_time, &time) != 0) {
  37.         dll_last_write_time = time;
  38.  
  39.         dll = force_load_dll(original_path, temp_path, dll);
  40.         assert(dll);
  41.         update_game = (t_update_game*)GetProcAddress(dll, "update_game");
  42.         assert(update_game);
  43.  
  44.         need_to_load_gl_functions = true;
  45.     }
  46.     #endif // m_debug_internal
  47.  
  48.     // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv     HANDLE INPUT START      vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
  49.     {
  50.         s_v2 unbound_mouse = get_window_mouse(window.handle);
  51.         g_platform_shared.platform_mouse.x = clamp(0.0f, game_window.w, unbound_mouse.x);
  52.         g_platform_shared.platform_mouse.y = clamp(0.0f, game_window.h, unbound_mouse.y);
  53.  
  54.         {
  55.             b8 should_show_cursor = unbound_mouse.x <= 0 || unbound_mouse.x >= game_window.w ||
  56.                 unbound_mouse.y <= 0 || unbound_mouse.y >= game_window.h;
  57.             should_show_cursor |= g_platform_shared.use_default_cursor;
  58.  
  59.             if(showing_cursor && !should_show_cursor) {
  60.                 ShowCursor(false);
  61.                 showing_cursor = false;
  62.             }
  63.             else if(!showing_cursor && should_show_cursor) {
  64.                 ShowCursor(true);
  65.                 showing_cursor = true;
  66.             }
  67.  
  68.         }
  69.  
  70.         #ifdef m_debug_internal
  71.         b8 is_window_active = GetActiveWindow() == window.handle;
  72.         #endif // m_debug_internal
  73.  
  74.         #ifdef m_debug_internal
  75.         if(g_platform_shared.playing_replay) {
  76.             if(g_platform_shared.render_count >= g_recorded_input->mouse.count) {
  77.                 log_info("Ran out of recorded input");
  78.                 g_platform_shared.playing_replay = false;
  79.  
  80.                 // @Note(tkap, 18/06/2024): Release ALT in case we ALT+F4'd to quit when recording
  81.                 apply_key_event(
  82.                     &g_platform_shared.update_input, key_left_alt, key_alt, false, false, 0
  83.                 );
  84.                 apply_key_event(
  85.                     &g_platform_shared.render_input, key_left_alt, key_alt, false, false, 0
  86.                 );
  87.             }
  88.             else {
  89.                 apply_recorded_input(g_platform_shared.render_count, is_window_active);
  90.             }
  91.         }
  92.  
  93.         else if(recording_data.playing_loop) {
  94.             int fake_frame = recording_data.recording_start_frame + recording_data.frames_played;
  95.             apply_recorded_input(fake_frame, is_window_active);
  96.         }
  97.         #endif // m_debug_internal
  98.     }
  99.     // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^     HANDLE INPUT END        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  100.  
  101.  
  102.     // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv     INIT ENET START     vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
  103.     if(game_network.init_connection)
  104.     {
  105.         game_network.init_connection = false;
  106.         if(network.enet_initialized)
  107.         {
  108.             if(network.me)
  109.             {
  110.                 enet_host_destroy(network.me);
  111.                 network.me = null;
  112.             }
  113.             enet_deinitialize();
  114.         }
  115.         network.enet_initialized = true;
  116.  
  117.         if(enet_initialize() != 0)
  118.         {
  119.             error(false);
  120.         }
  121.  
  122.         if(game_network.is_host)
  123.         {
  124.             ENetAddress address = zero;
  125.             address.host = ENET_HOST_ANY;
  126.             address.port = game_network.port;
  127.  
  128.             network.me = enet_host_create(
  129.                 &address, // create a client host
  130.                 enet_max_clients, // only allow 1 outgoing connection
  131.                 2, // allow up 2 channels to be used, 0 and 1
  132.                 0, // assume any amount of incoming bandwidth
  133.                 0 // assume any amount of outgoing bandwidth
  134.             );
  135.  
  136.             network.peers_active[c_host_index] = true;
  137.         }
  138.         else
  139.         {
  140.             network.me = enet_host_create(
  141.                 null, // create a client host
  142.                 1, // only allow 1 outgoing connection
  143.                 2, // allow up 2 channels to be used, 0 and 1
  144.                 0, // assume any amount of incoming bandwidth
  145.                 0 // assume any amount of outgoing bandwidth
  146.             );
  147.         }
  148.  
  149.         if(network.me == null)
  150.         {
  151.             error(false);
  152.         }
  153.     }
  154.     // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^     INIT ENET END       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  155.  
  156.  
  157.     // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv     CONNECT TO SERVER START     vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
  158.     if(game_network.connect_to_server)
  159.     {
  160.         assert(!game_network.is_host);
  161.         assert(network.me);
  162.  
  163.         game_network.connect_to_server = false;
  164.         game_network.connection_state = e_connection_state_connecting;
  165.         ENetAddress address = zero;
  166.  
  167.         assert(game_network.port);
  168.         assert(game_network.ip[0]);
  169.  
  170.         enet_address_set_host(&address, game_network.ip);
  171.         address.port = game_network.port;
  172.  
  173.         game_network.time_spent_trying_to_connect = 0;
  174.  
  175.         // @Note(tkap, 01/02/2024): I'd like to call this, but it seems to crash sometimes and I don't know which members to check
  176.         // to prevent that
  177.         // if(network.server && network.server->state != ENET_PEER_STATE_DISCONNECTED && network.server->connectID != 0) {
  178.         //  enet_peer_reset(network.server);
  179.         // }
  180.  
  181.         network.server = enet_host_connect(network.me, &address, 2, 0);
  182.  
  183.         if(network.server == null) {
  184.             game_network.connection_state = e_connection_state_not_connected;
  185.             game_network.failed_to_connect = true;
  186.             log_error("enet_host_connect failed");
  187.         }
  188.         else {
  189.             log_info("Client: Found server");
  190.         }
  191.     }
  192.     // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^     CONNECT TO SERVER END       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  193.  
  194.  
  195.  
  196.     // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv     DISCONNECT START        vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
  197.     {
  198.         if(game_network.disconnect)
  199.         {
  200.             assert(!game_network.is_host);
  201.             assert(game_network.connection_state == e_connection_state_connected);
  202.             game_network.clients_active.clear();
  203.             game_network.disconnect = false;
  204.             game_network.connection_state = e_connection_state_not_connected;
  205.             enet_peer_disconnect_now(network.server, 0);
  206.             log_info("Client: Successfully disconnected");
  207.         }
  208.     }
  209.     // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^     DISCONNECT END      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  210.  
  211.  
  212.  
  213.  
  214.     // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv     UPDATE NETWORK START        vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
  215.     if(
  216.         game_network.connection_state == e_connection_state_connected ||
  217.         game_network.connection_state == e_connection_state_connecting
  218.     )
  219.     {
  220.         if(game_network.connection_state == e_connection_state_connecting)
  221.         {
  222.             game_network.time_spent_trying_to_connect += (float)g_platform_shared.delta;
  223.             #ifdef m_debug_internal
  224.             constexpr int max_connect_time = 10;
  225.             #else // m_debug_internal
  226.             constexpr int max_connect_time = 5;
  227.             #endif // NOT m_debug_internal
  228.             if(game_network.time_spent_trying_to_connect > max_connect_time)
  229.             {
  230.                 game_network.connection_state = e_connection_state_not_connected;
  231.                 game_network.failed_to_connect = true;
  232.             }
  233.         }
  234.  
  235.         ENetEvent event = zero;
  236.         while(enet_host_service(network.me, &event, 0) > 0)
  237.         {
  238.             switch(event.type)
  239.             {
  240.  
  241.                 case ENET_EVENT_TYPE_NONE:
  242.                 {
  243.                 } break;
  244.  
  245.                 case ENET_EVENT_TYPE_CONNECT:
  246.                 {
  247.                     if(game_network.is_host)
  248.                     {
  249.                         if(game_network.reject_connections)
  250.                         {
  251.                             enet_peer_disconnect_now(event.peer, 0);
  252.                         }
  253.                         else
  254.                         {
  255.                             for(int i = 0; i < enet_max_clients; i += 1)
  256.                             {
  257.                                 if(network.peers_active[i]) { continue; }
  258.                                 network.peers_active[i] = true;
  259.                                 network.peers[i] = event.peer;
  260.  
  261.                                 assert(game_network.incoming_packets.count < max_packets);
  262.                                 s_packet packet = zero;
  263.                                 packet.type = e_packet_connect;
  264.                                 packet.sender = i;
  265.                                 log_info("Host: %i connected!", i);
  266.                                 game_network.incoming_packets.add(packet);
  267.                                 break;
  268.                             }
  269.                         }
  270.                     }
  271.                     else
  272.                     {
  273.                         assert(game_network.connection_state != e_connection_state_connected);
  274.                         assert(!game_network.just_connected);
  275.                         game_network.just_connected = true;
  276.                         log_info("Client: Connected!");
  277.                     }
  278.                 } break;
  279.  
  280.                 case ENET_EVENT_TYPE_DISCONNECT:
  281.                 {
  282.                     if(game_network.is_host)
  283.                     {
  284.                         #ifdef m_debug
  285.                         b8 found = false;
  286.                         #endif // m_debug
  287.                         for(int client_i = 1; client_i < enet_max_clients; client_i += 1)
  288.                         {
  289.                             if(!network.peers_active[client_i]) { continue; }
  290.  
  291.                             if(event.peer->connectID == network.peers[client_i]->connectID)
  292.                             {
  293.                                 #ifdef m_debug
  294.                                 found = true;
  295.                                 #endif // m_debug
  296.  
  297.                                 network.peers_active[client_i] = false;
  298.                                 network.peers[client_i] = null;
  299.                                 assert(game_network.incoming_packets.count < max_packets);
  300.                                 s_packet packet = zero;
  301.                                 packet.type = e_packet_disconnect;
  302.                                 packet.sender = client_i;
  303.                                 game_network.incoming_packets.add(packet);
  304.                                 break;
  305.                             }
  306.                         }
  307.                         assert(found);
  308.                     }
  309.                     else
  310.                     {
  311.                         assert(game_network.connection_state == e_connection_state_connected);
  312.                         game_network.connection_state = e_connection_state_not_connected;
  313.                         game_network.just_disconnected = true;
  314.                         log_info("Client: Disconnected!");
  315.                     }
  316.                 } break;
  317.  
  318.                 case ENET_EVENT_TYPE_RECEIVE:
  319.                 {
  320.                     if(game_network.is_host)
  321.                     {
  322.                         int index = -1;
  323.                         for(int client_i = 1; client_i < enet_max_clients; client_i += 1)
  324.                         {
  325.                             if(network.peers_active[client_i] && event.peer->connectID == network.peers[client_i]->connectID)
  326.                             {
  327.                                 index = client_i;
  328.                                 break;
  329.                             }
  330.                         }
  331.                         if(index != -1)
  332.                         {
  333.                             assert(game_network.incoming_packets.count < max_packets);
  334.                             s_packet packet = zero;
  335.                             packet.type = e_packet_rpc;
  336.                             packet.size = (int)event.packet->dataLength;
  337.  
  338.                             packet.data = (u8*)la_get(&game_network.arena, event.packet->dataLength);
  339.  
  340.                             packet.sender = index;
  341.                             memcpy(packet.data, event.packet->data, event.packet->dataLength);
  342.                             game_network.incoming_packets.add(packet);
  343.                             enet_packet_destroy(event.packet);
  344.                         }
  345.                         else
  346.                         {
  347.                             // @TODO(tkap): Logging
  348.                         }
  349.                     }
  350.                     else
  351.                     {
  352.                         assert(game_network.incoming_packets.count < max_packets);
  353.                         s_packet packet = zero;
  354.                         packet.size = (int)event.packet->dataLength;
  355.  
  356.                         packet.data = (u8*)la_get(&game_network.arena, event.packet->dataLength);
  357.  
  358.                         packet.type = e_packet_rpc;
  359.                         memcpy(packet.data, event.packet->data, event.packet->dataLength);
  360.                         game_network.incoming_packets.add(packet);
  361.                         enet_packet_destroy(event.packet);
  362.                     }
  363.                 } break;
  364.  
  365.                 invalid_default_case;
  366.             }
  367.         }
  368.     }
  369.  
  370.     // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^     UPDATE NETWORK END      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  371.  
  372.     #ifdef m_debug_internal
  373.     {
  374.         if(
  375.             (g_platform_shared.render_input.key_states[key_f8].down && g_platform_shared.render_input.key_states[key_f8].half_transition_count == 1) ||
  376.             g_platform_shared.render_input.key_states[key_f8].half_transition_count >= 2
  377.         )
  378.         {
  379.             transparent_window = !transparent_window;
  380.             if(transparent_window) {
  381.  
  382.                 LONG_PTR style = GetWindowLongPtrA(
  383.                     window.handle,
  384.                     GWL_EXSTYLE
  385.                 );
  386.  
  387.                 style |= WS_EX_LAYERED;
  388.  
  389.                 SetWindowLongPtrA(
  390.                     window.handle,
  391.                     GWL_EXSTYLE,
  392.                     style
  393.                 );
  394.  
  395.                 BOOL result = SetWindowPos(
  396.                     window.handle,
  397.                     HWND_TOPMOST,
  398.                     0,
  399.                     0,
  400.                     0,
  401.                     0,
  402.                     SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED
  403.                 );
  404.                 assert(result);
  405.  
  406.                 SetLayeredWindowAttributes(window.handle, RGB(0, 0, 0), 128, LWA_ALPHA);
  407.             }
  408.             else {
  409.                 LONG_PTR style = GetWindowLongPtrA(
  410.                     window.handle,
  411.                     GWL_EXSTYLE
  412.                 );
  413.  
  414.                 style &= ~WS_EX_LAYERED;
  415.  
  416.                 SetWindowLongPtrA(
  417.                     window.handle,
  418.                     GWL_EXSTYLE,
  419.                     style
  420.                 );
  421.  
  422.                 BOOL result = SetWindowPos(
  423.                     window.handle,
  424.                     HWND_NOTOPMOST,
  425.                     0,
  426.                     0,
  427.                     0,
  428.                     0,
  429.                     SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED
  430.                 );
  431.                 assert(result);
  432.  
  433.                 SetLayeredWindowAttributes(window.handle, RGB(0, 0, 0), 255, LWA_ALPHA);
  434.             }
  435.         }
  436.     }
  437.     #endif
  438.  
  439.     #ifdef m_debug_internal
  440.     // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv     record input start      vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
  441.     if(!g_platform_shared.replay_argument) {
  442.         g_recorded_input->mouse.add_checked(g_platform_shared.platform_mouse);
  443.         g_recorded_input->wheel_movement.add_checked(g_platform_shared.platform_wheel_movement);
  444.     }
  445.     // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^     record input end        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  446.     #endif // m_debug_internal
  447.  
  448.     s_audio_stuff audio_stuff = zero;
  449.     audio_stuff.audio_enabled = g_xaudio.audio_enabled;
  450.     audio_stuff.play_sound = play_sound;
  451.     audio_stuff.play_music = play_music;
  452.     audio_stuff.set_effect_volume = set_effect_volume;
  453.     audio_stuff.set_music_volume = set_music_volume;
  454.  
  455.     update_game(
  456.         game_memory, rendering_memory, game_window, &arenas,
  457.         &game_network, performance_counter, need_to_load_gl_functions, args, running <= 0, &g_platform_shared, audio_stuff
  458.         m_arg(g_recorded_input)
  459.         m_arg(&recording_data)
  460.     );
  461.     g_platform_shared.platform_wheel_movement = 0;
  462.     g_platform_shared.platform_last_mouse = g_platform_shared.platform_mouse;
  463.     g_platform_shared.mouse_delta = zero;
  464.     need_to_load_gl_functions = false;
  465.  
  466.     // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv     SEND PACKETS START      vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
  467.  
  468.     for(int i = 0; i < game_network.outgoing_packets.count; i += 1)
  469.     {
  470.         s_packet* packet = &game_network.outgoing_packets[i];
  471.         assert(packet->target >= 0);
  472.         assert(packet->target < enet_max_clients);
  473.  
  474.         ENetPacket* enet_packet = enet_packet_create(packet->data, packet->size, packet->reliable ? ENET_PACKET_FLAG_RELIABLE : 0);
  475.  
  476.         if(game_network.is_host)
  477.         {
  478.             assert(packet->target != c_host_index);
  479.             assert(network.peers_active[packet->target]);
  480.             assert(network.peers[packet->target]);
  481.  
  482.             if(packet->free_packet_callback)
  483.             {
  484.                 assert(packet->reliable);
  485.  
  486.                 clients_to_kick.add(packet->target);
  487.                 enet_packet->userData = packet->free_packet_callback;
  488.                 enet_packet->freeCallback = enet_packet_free_callback;
  489.             }
  490.             enet_peer_send(network.peers[packet->target], 0, enet_packet);
  491.  
  492.         }
  493.         else
  494.         {
  495.             assert(network.server);
  496.             assert(packet->target == c_host_index);
  497.  
  498.             // @Note(tkap, 07/12/2022): We do not allow free callbacks for clients currently
  499.             assert(!packet->free_packet_callback);
  500.             enet_peer_send(network.server, 0, enet_packet);
  501.         }
  502.  
  503.     }
  504.     game_network.outgoing_packets.count = 0;
  505.     // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^     SEND PACKETS END        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  506.  
  507.     if(game_network.deinitialize_network && clients_to_kick.count <= 0)
  508.     {
  509.         assert(game_network.connection_state == e_connection_state_connected);
  510.         game_network.deinitialize_network = false;
  511.         network.enet_initialized = false;
  512.         game_network.connection_state = e_connection_state_not_connected;
  513.  
  514.         game_network.clients_active.clear();
  515.         network.peers_active.clear();
  516.  
  517.         if(network.me)
  518.         {
  519.             enet_host_destroy(network.me);
  520.             network.me = null;
  521.         }
  522.         invalid_else;
  523.  
  524.         enet_deinitialize();
  525.     }
  526.  
  527.     g_platform_shared.ms_taken_by_last_frame = performance_counter.get_ms() - last_time;
  528.  
  529.     SwapBuffers(window.dc);
  530. }
  531. // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^     FRAME END       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement