Compare commits

..

No commits in common. "96d6a52a74293b38bc206f02a38553e85d7d2821" and "fb7f91185d9e9634f5fcf7be151ab10be67db8d5" have entirely different histories.

9 changed files with 92 additions and 44 deletions

View File

@ -51,6 +51,7 @@ add_library(kaliber SHARED
../../../src/base/log.cc ../../../src/base/log.cc
../../../src/base/task_runner.cc ../../../src/base/task_runner.cc
../../../src/base/thread_pool.cc ../../../src/base/thread_pool.cc
../../../src/base/timer.cc
../../../src/demo/credits.cc ../../../src/demo/credits.cc
../../../src/demo/demo.cc ../../../src/demo/demo.cc
../../../src/demo/enemy.cc ../../../src/demo/enemy.cc

View File

@ -15,6 +15,7 @@ source_set("base") {
"task_runner.h", "task_runner.h",
"thread_pool.cc", "thread_pool.cc",
"thread_pool.h", "thread_pool.h",
"timer.cc",
"timer.h", "timer.h",
"vecmath.h", "vecmath.h",
] ]

46
src/base/timer.cc Normal file
View File

@ -0,0 +1,46 @@
#include "base/timer.h"
#include <thread>
namespace base {
Timer::Timer() {
Reset();
}
void Timer::Reset() {
gettimeofday(&last_time_, nullptr);
seconds_passed_ = 0.0f;
seconds_accumulated_ = 0.0f;
}
void Timer::Update() {
timeval currentTime;
gettimeofday(&currentTime, nullptr);
seconds_passed_ =
(float)(currentTime.tv_sec - last_time_.tv_sec) +
0.000001f * (float)(currentTime.tv_usec - last_time_.tv_usec);
last_time_ = currentTime;
seconds_accumulated_ += seconds_passed_;
}
void Timer::Sleep(float duration) {
Timer timer;
float accumulator = 0.0;
constexpr float epsilon = 0.0001f;
while (accumulator < duration) {
timer.Update();
accumulator += timer.GetSecondsPassed();
if (duration - accumulator > epsilon) {
float sleep_time = duration - accumulator - epsilon;
std::this_thread::sleep_for(
std::chrono::microseconds((int)(sleep_time * 1000000.0f)));
}
};
}
} // namespace base

View File

@ -1,47 +1,31 @@
#ifndef BASE_TIMER_H #ifndef BASE_TIMER_H
#define BASE_TIMER_H #define BASE_TIMER_H
#include <chrono> #include <sys/time.h>
#include <thread>
namespace base { namespace base {
class ElapsedTimer { class Timer {
public: public:
ElapsedTimer() { time_ = std::chrono::high_resolution_clock::now(); } Timer();
~Timer() = default;
// Return seconds passed since creating the object. void Reset();
double Elapsed() const {
auto current_time = std::chrono::high_resolution_clock::now(); void Update();
std::chrono::duration<double> diff = current_time - time_;
return diff.count(); static void Sleep(float duration);
}
float GetSecondsPassed() const { return seconds_passed_; }
float GetSecondsAccumulated() const { return seconds_accumulated_; }
private: private:
std::chrono::time_point<std::chrono::high_resolution_clock> time_; float seconds_passed_ = 0.0f;
float seconds_accumulated_ = 0.0f;
timeval last_time_;
}; };
class DeltaTimer {
public:
DeltaTimer() { time_ = std::chrono::high_resolution_clock::now(); }
// Return seconds passed since the last call to this function.
double Delta() {
auto current_time = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> diff = current_time - time_;
time_ = current_time;
return diff.count();
}
private:
std::chrono::time_point<std::chrono::high_resolution_clock> time_;
};
inline void Sleep(double seconds) {
std::this_thread::sleep_for(
std::chrono::duration<double, std::milli>(seconds * 1000));
}
} // namespace base } // namespace base
#endif // BASE_TIMER_H #endif // BASE_TIMER_H

View File

@ -150,7 +150,7 @@ void Player::AddNuke(int n) {
if (!nuke_symbol_animator_.IsPlaying(Animator::kRotation)) { if (!nuke_symbol_animator_.IsPlaying(Animator::kRotation)) {
nuke_symbol_animator_.SetRotation( nuke_symbol_animator_.SetRotation(
PIf * 5, 2, std::bind(SmootherStep, std::placeholders::_1)); M_PI * 5, 2, std::bind(SmootherStep, std::placeholders::_1));
nuke_symbol_animator_.Play(Animator::kRotation, false); nuke_symbol_animator_.Play(Animator::kRotation, false);
} }
} }
@ -220,7 +220,7 @@ void Player::Fire(DamageType type, Vector2f dir) {
dir.Normalize(); dir.Normalize();
float cos_theta = dir.DotProduct(Vector2f(1, 0)); float cos_theta = dir.DotProduct(Vector2f(1, 0));
float theta = acos(cos_theta) + PIf; float theta = acos(cos_theta) + M_PI;
beam_[type].SetTheta(theta); beam_[type].SetTheta(theta);
auto offset = beam_[type].GetRotation() * (len / 2); auto offset = beam_[type].GetRotation() * (len / 2);
beam_[type].Translate({offset.y, -offset.x}); beam_[type].Translate({offset.y, -offset.x});
@ -285,7 +285,7 @@ void Player::SetupWeapons() {
weapon_[i].SetFrame(wepon_warmup_frame[i]); weapon_[i].SetFrame(wepon_warmup_frame[i]);
warmup_animator_[i].SetFrames(wepon_warmup_frame_count, wepon_anim_speed); warmup_animator_[i].SetFrames(wepon_warmup_frame_count, wepon_anim_speed);
warmup_animator_[i].SetRotation(PIf * 2, 20.0f); warmup_animator_[i].SetRotation(M_PI * 2, 20.0f);
warmup_animator_[i].Attach(&weapon_[i]); warmup_animator_[i].Attach(&weapon_[i]);
warmup_animator_[i].Play(Animator::kRotation, true); warmup_animator_[i].Play(Animator::kRotation, true);

View File

@ -5,7 +5,6 @@
#include <alsa/asoundlib.h> #include <alsa/asoundlib.h>
#include "base/log.h" #include "base/log.h"
#include "base/timer.h"
using namespace base; using namespace base;
@ -187,7 +186,7 @@ void AudioSinkAlsa::AudioThreadMain() {
if (terminate_audio_thread_.load(std::memory_order_relaxed)) if (terminate_audio_thread_.load(std::memory_order_relaxed))
return; return;
// Avoid busy-looping. // Avoid busy-looping.
Sleep(1); std::this_thread::sleep_for(std::chrono::milliseconds(1));
} }
delegate_->RenderAudio(buffer.get(), num_frames); delegate_->RenderAudio(buffer.get(), num_frames);

View File

@ -2,7 +2,6 @@
#include "base/log.h" #include "base/log.h"
#include "base/task_runner.h" #include "base/task_runner.h"
#include "base/timer.h"
#include "engine/animator.h" #include "engine/animator.h"
#include "engine/asset/font.h" #include "engine/asset/font.h"
#include "engine/asset/image.h" #include "engine/asset/image.h"
@ -73,7 +72,7 @@ Engine& Engine::Get() {
void Engine::Run() { void Engine::Run() {
Initialize(); Initialize();
DeltaTimer timer; timer_.Reset();
float accumulator = 0.0; float accumulator = 0.0;
float frame_frac = 0.0f; float frame_frac = 0.0f;
@ -84,13 +83,17 @@ void Engine::Run() {
if (platform_->should_exit()) if (platform_->should_exit())
return; return;
if (!renderer_->IsInitialzed()) if (!renderer_->IsInitialzed()) {
timer_.Reset();
input_queue_.clear();
continue; continue;
}
Draw(frame_frac); Draw(frame_frac);
// Accumulate time. // Accumulate time.
accumulator += timer.Delta(); timer_.Update();
accumulator += timer_.GetSecondsPassed();
// Subdivide the frame time using fixed time steps. // Subdivide the frame time using fixed time steps.
while (accumulator >= time_step_) { while (accumulator >= time_step_) {
@ -508,6 +511,7 @@ void Engine::LostFocus() {
} }
void Engine::GainedFocus(bool from_interstitial_ad) { void Engine::GainedFocus(bool from_interstitial_ad) {
timer_.Reset();
audio_mixer_->Resume(); audio_mixer_->Resume();
if (game_) if (game_)

View File

@ -9,6 +9,7 @@
#include "base/random.h" #include "base/random.h"
#include "base/thread_pool.h" #include "base/thread_pool.h"
#include "base/timer.h"
#include "base/vecmath.h" #include "base/vecmath.h"
#include "engine/persistent_data.h" #include "engine/persistent_data.h"
#include "engine/platform/platform_observer.h" #include "engine/platform/platform_observer.h"
@ -213,6 +214,7 @@ class Engine : public PlatformObserver {
unsigned int replay_index_ = 0; unsigned int replay_index_ = 0;
base::ThreadPool thread_pool_; base::ThreadPool thread_pool_;
base::Timer timer_;
base::Randomf random_; base::Randomf random_;
void Initialize(); void Initialize();

View File

@ -1536,13 +1536,24 @@ bool VulkanContext::SwapBuffers() {
/*pWaitSemaphores*/ /*pWaitSemaphores*/
(separate_present_queue_) ? &image_ownership_semaphores_[frame_index_] (separate_present_queue_) ? &image_ownership_semaphores_[frame_index_]
: &draw_complete_semaphores_[frame_index_], : &draw_complete_semaphores_[frame_index_],
/*swapchainCount*/ 1, /*swapchainCount*/ 0,
/*pSwapchains*/ &window_.swapchain, /*pSwapchain*/ nullptr,
/*pImageIndices*/ &window_.current_buffer, /*pImageIndices*/ nullptr,
/*pResults*/ nullptr, /*pResults*/ nullptr,
}; };
VkSwapchainKHR* swapchains = (VkSwapchainKHR*)alloca(sizeof(VkSwapchainKHR*));
uint32_t* pImageIndices = (uint32_t*)alloca(sizeof(uint32_t*));
present.pSwapchains = swapchains;
present.pImageIndices = pImageIndices;
DCHECK(window_.swapchain != VK_NULL_HANDLE); DCHECK(window_.swapchain != VK_NULL_HANDLE);
swapchains[present.swapchainCount] = window_.swapchain;
pImageIndices[present.swapchainCount] = window_.current_buffer;
present.swapchainCount++;
err = QueuePresentKHR(present_queue_, &present); err = QueuePresentKHR(present_queue_, &present);
frame_index_ += 1; frame_index_ += 1;