aboutsummaryrefslogtreecommitdiff
path: root/source/30-game/Player.cpp
diff options
context:
space:
mode:
authorrtk0c <[email protected]>2023-09-20 23:58:58 -0700
committerrtk0c <[email protected]>2023-09-20 23:58:58 -0700
commitf138311d2d2e0cc9ba0496d523bb46f2c1c9fb73 (patch)
treef96100a813a4ffb28dcd074455d3a2f8ee426430 /source/30-game/Player.cpp
Copy from the PlasticSCM repo, replace vendored glm wtih conan
Diffstat (limited to 'source/30-game/Player.cpp')
-rw-r--r--source/30-game/Player.cpp139
1 files changed, 139 insertions, 0 deletions
diff --git a/source/30-game/Player.cpp b/source/30-game/Player.cpp
new file mode 100644
index 0000000..34c4549
--- /dev/null
+++ b/source/30-game/Player.cpp
@@ -0,0 +1,139 @@
+#include "Player.hpp"
+
+#include "AppConfig.hpp"
+#include "CommonVertexIndex.hpp"
+#include "ScopeGuard.hpp"
+#include "Utils.hpp"
+
+#include <cstdio>
+#include <cstdlib>
+
+// Keep the same number as # of fields in `struct {}` in PlayerKeyBinds
+constexpr int kPlayerKeyBindCount = 4;
+
+// Here be dragons: this treats consecutive fiels as an array, technically UB
+std::span<int> PlayerKeyBinds::GetKeyArray() {
+ return { &keyLeft, kPlayerKeyBindCount };
+}
+std::span<bool> PlayerKeyBinds::GetKeyStatusArray() {
+ return { &pressedLeft, kPlayerKeyBindCount };
+}
+
+Player::Player(GameWorld* world, int id)
+ : GameObject(KD_Player, world)
+ , mId{ id } {
+ renderObject.SetMaterial(gDefaultMaterial.Get());
+ renderObject.SetFormat(gVformatStandard.Get(), Tags::IT_16Bit);
+ renderObject.RebuildIfNecessary();
+}
+
+void Player::Awaken() {
+ LoadFromFile();
+}
+
+void Player::Resleep() {
+ SaveToFile();
+}
+
+void Player::Update() {
+ using namespace Tags;
+
+ if (keybinds.pressedLeft) {
+ }
+ if (keybinds.pressedRight) {
+ }
+
+ // TODO jump controller
+
+ // TODO attack controller
+
+ // TODO set default sprite to get rid of this check
+ if (sprite.GetDefinition()) {
+ int prevFrame = sprite.GetFrame();
+ sprite.PlayFrame();
+ int currFrame = sprite.GetFrame();
+ if (prevFrame != currFrame) {
+ uint16_t indices[6];
+ Index_U16::Assign(indices, 0);
+ renderObject.GetIndexBuffer()->Upload((const std::byte*)indices, IT_16Bit, std::size(indices));
+
+ Vertex_PTC vertices[4];
+ Vertex_PTC::Assign(vertices, Rect<float>{ GetPos(), sprite.GetDefinition()->GetBoundingBox() });
+ Vertex_PTC::Assign(vertices, 0.0f);
+ Vertex_PTC::Assign(vertices, RgbaColor(255, 255, 255));
+ Vertex_PTC::Assign(vertices, sprite.GetFrameSubregion());
+ renderObject.GetVertexBufferBindings().bindings[0]->Upload((const std::byte*)vertices, sizeof(vertices));
+ }
+ }
+}
+
+Material* Player::GetMaterial() const {
+ return renderObject.GetMaterial();
+}
+
+void Player::SetMaterial(Material* material) {
+ renderObject.SetMaterial(material);
+ renderObject.RebuildIfNecessary();
+}
+
+std::span<const RenderObject> Player::GetRenderObjects() const {
+ return { &renderObject, 1 };
+}
+
+void Player::HandleKeyInput(int key, int action) {
+ bool pressed;
+ if (action == GLFW_PRESS) {
+ pressed = true;
+ } else if (action == GLFW_REPEAT) {
+ return;
+ } else /* action == GLFW_RELEASE */ {
+ pressed = false;
+ }
+
+ for (int i = 0; i < kPlayerKeyBindCount; ++i) {
+ int kbKey = keybinds.GetKeyArray()[i];
+ bool& kbStatus = keybinds.GetKeyStatusArray()[i];
+
+ if (kbKey == key) {
+ kbStatus = pressed;
+ break;
+ }
+ }
+}
+
+#pragma push_macro("PLAYERKEYBINDS_DO_IO")
+#undef PLAYERKEYBINDS_DO_IO
+#define PLAYERKEYBINDS_DO_IO(function, fieldPrefix) \
+ function(file, "left=%d\n", fieldPrefix keybinds.keyLeft); \
+ function(file, "right=%d\n", fieldPrefix keybinds.keyRight); \
+ function(file, "jump=%d\n", fieldPrefix keybinds.keyJump); \
+ function(file, "attack=%d\n", fieldPrefix keybinds.keyAttack);
+
+static FILE* OpenPlayerConfigFile(Player* player, Utils::IoMode mode) {
+ char path[2048];
+ snprintf(path, sizeof(path), "%s/player%d.txt", AppConfig::dataDir.c_str(), player->GetId());
+
+ return Utils::OpenCstdioFile(path, mode);
+}
+
+bool Player::LoadFromFile() {
+ auto file = OpenPlayerConfigFile(this, Utils::Read);
+ if (!file) return false;
+ DEFER { fclose(file); };
+
+ // TODO input validation
+ PLAYERKEYBINDS_DO_IO(fscanf, &);
+
+ return true;
+}
+
+bool Player::SaveToFile() {
+ auto file = OpenPlayerConfigFile(this, Utils::WriteTruncate);
+ if (!file) return false;
+ DEFER { fclose(file); };
+
+ PLAYERKEYBINDS_DO_IO(fprintf, );
+
+ return true;
+}
+#pragma pop_macro("PLAYERKEYBINDS_DO_IO")