commit 6409ce0b4b938e5be1bc5d9b9d5eda40996836c2
parent 87461296f26780b9ae9fa60c17c3745b1431689a
Author: amrfti <andrew@kloet.net>
Date: Mon, 7 Jul 2025 14:57:52 -0400
store only one direction of sprites
Diffstat:
5 files changed, 146 insertions(+), 232 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,6 +1,6 @@
# Compiler and flags
CXX = g++
-CXXFLAGS = -std=c++17 -Wall -Wextra -O3 -fno-exceptions -fno-asynchronous-unwind-tables -fno-unwind-tables
+CXXFLAGS = -std=c++17 -Wall -Wextra -Os -fno-exceptions -fno-asynchronous-unwind-tables -fno-unwind-tables
LDFLAGS = -lncurses -ltinfo -Wl,--gc-sections -s
# Directories
diff --git a/src/Entity.cpp b/src/Entity.cpp
@@ -1,5 +1,6 @@
#include "Entity.h"
#include "Aquarium.h"
+#include <algorithm>
void Entity::draw() const {
auto &aquarium = Aquarium::getInstance();
@@ -55,3 +56,26 @@ void Entity::draw() const {
}
}
}
+
+size_t Entity::getMaxRowWidth(const std::vector<std::string> &image) noexcept {
+ if (image.empty()) {
+ return 0;
+ }
+
+ size_t max_width = 0;
+ for (const auto &row : image) {
+ max_width = std::max(max_width, row.length());
+ }
+
+ return max_width;
+}
+
+bool Entity::shouldBeRemoved() const noexcept {
+ const auto &aquarium = Aquarium::getInstance();
+ const auto ¤t_image = getImage();
+ const float entity_width = static_cast<float>(getMaxRowWidth(current_image));
+
+ // Default implementation: remove if completely off-screen
+ return (x + entity_width < 0) ||
+ (x > static_cast<float>(aquarium.getWidth()));
+}
diff --git a/src/Entity.h b/src/Entity.h
@@ -30,9 +30,13 @@ public:
virtual const std::vector<std::string> &getMask() const = 0;
virtual char getDefaultColor() const noexcept = 0;
- virtual bool shouldBeRemoved() const noexcept = 0;
+ virtual bool shouldBeRemoved() const noexcept;
virtual std::unique_ptr<Entity> createReplacement() const { return nullptr; }
virtual int getPreferredLayer() const noexcept = 0;
void draw() const;
+
+protected:
+ // Helper function to get the maximum width of any row in an image
+ static size_t getMaxRowWidth(const std::vector<std::string> &image) noexcept;
};
diff --git a/src/assets/FishAssets.h b/src/assets/FishAssets.h
@@ -1,235 +1,53 @@
#pragma once
#include "../Entity.h"
+#include "SpriteUtils.h"
#include <vector>
-inline std::vector<AssetPair> fishAssetPairs = {
- {
- {
- R"(???\)",
- R"(??/ \)",
- R"(>=_('>)",
- R"(??\_/)",
- R"(???/)"
- },
- {
- R"( 1)",
- R"( 1 1)",
- R"(663745)",
- R"( 111)",
- R"( 3)"
- }
- },
- {
- {
- R"(??/)",
- R"(?/ \)",
- R"(<')_=<)",
- R"(?\_/)",
- R"(??\)"
- },
- {
- R"( 2)",
- R"( 111)",
- R"(547366)",
- R"( 111)",
- R"( 3)"
- }
- },
- {
- {
- R"(?????,)",
- R"(?????}\)",
- R"(\??.' `\)",
- R"(}}< ( 6>)",
- R"(/??`, .')",
- R"(?????}/)",
- R"(?????')"
- },
- {
- R"( 2)",
- R"( 22)",
- R"(6 11 11)",
- R"(661 7 45)",
- R"(6 11 11)",
- R"( 33)",
- R"( 3)"
- }
- },
- {
- {
- R"(????,)",
- R"(???/{)",
- R"(?/' `. /)",
- R"(<6 ) >{{)",
- R"(?`. ,' \)",
- R"(???\{)",
- R"(????`)"
- },
- {
- R"( 2)",
- R"( 22)",
- R"( 11 11 6)",
- R"(54 7 166)",
- R"( 11 11 6)",
- R"( 33)",
- R"( 3)"
- }
- },
- {
- {
- R"(???????,--,_)",
- R"(__????_\.---'-.)",
- R"(\ '.-" // o\)",
- R"(/_.'-._ \\ /)",
- R"(???????`"--(/"`)"
- },
- {
- R"( 22222)",
- R"(66 121111211)",
- R"(6 6111 77 41)",
- R"(6661111 77 1)",
- R"( 11113311)"
- }
- },
- {
- {
- R"(????_,--,)",
- R"(?.-'---./_????__)",
- R"(/o \\ "-.' /)",
- R"(\ // _.-'._\)",
- R"(?`"\)--"`)"
- },
- {
- R"( 22222)",
- R"( 112111121 66)",
- R"(14 77 1116 6)",
- R"(1 77 1111666)",
- R"( 11331111)"
- }
- },
- {
- {
- R"(??__)",
- R"(><_'>)",
- R"(???')"
- },
- {
- R"( 11)",
- R"(61145)",
- R"( 3)"
- }
- },
- {
- {
- R"(?__)",
- R"(<'_><)",
- R"(?`)"
- },
- {
- R"( 11)",
- R"(54116)",
- R"( 3)"
- }
- },
- {
- {
- R"(????????_.-`\)",
- R"(?????-:`_..,_\)",
- R"(('-..:-` , '-.,)",
- R"(?} _ ;':( o :)",
- R"((.-`/'-.,__'` _.-`)",
- R"(???`'-.,/??//`)"
- },
- {
- R"( 22222)",
- R"( 222111112)",
- R"(66661111 7 1111)",
- R"( 6 1 7777 4 1)",
- R"(6666211111177 1111)",
- R"( 222222 333)"
- }
- },
- {
- {
- R"(??????/`-._)",
- R"(?????/_,.._`:-)",
- R"(?,.-' , `-:..-'))",
- R"(: o ):'; _ {)",
- R"(?`-._ `'__,.-'\`-.))",
- R"(?????`\\??\,.-'`)"
- },
- {
- R"( 22222)",
- R"( 211111222)",
- R"( 1111 7 11116666)",
- R"(1 4 7777 1 6)",
- R"( 1111 7711111126666)",
- R"( 333 222222)"
- }
- },
- {
- {
- R"(????????/\)",
- R"(????????\.\_)",
- R"(\'-,.:-` '-,)",
- R"( ) _ (>( o <)",
- R"(/.-`?':._ _.-`)",
- R"(??????;/?``)",
- },
- {
- R"( 22)",
- R"( 2121)",
- R"(66661111 111)",
- R"( 6 1 777 4 1)",
- R"(6666 1111 1111)",
- R"( 22 33)",
- }
- },
- {
- {
- R"(??????/\)",
- R"(????_/./)",
- R"(?,-' `-:.,-'/)",
- R"(> o )<) _ ()",
- R"(?`-._ _.:'?`-.\)",
- R"(?????``?\;)",
- },
- {
- R"( 22)",
- R"( 1212)",
- R"( 111 11116666)",
- R"(1 4 777 1 6)",
- R"( 1111 1111 6666)",
- R"( 33 22)",
- }
- },
- {
- {
- R"(_?????????_.*"\)",
- R"(\'-._..-*` `'*-.)",
- R"(?) , (( o >)",
- R"(/.`"*--.__)_.`_.-*`)"
- },
- {
- R"(6 11222)",
- R"(6661111111 11111)",
- R"( 6 3 77 4 1)",
- R"(6661111111311311111)",
- }
- },
- {
- {
- R"(??????/"*._?????????_)",
- R"(??.-*'` `*-.._.-'/)",
- R"(< o )) , ()",
- R"(??`*-._`._(__.--*"`.\)",
- },
- {
- R"( 22211 6)",
- R"( 11111 1111111666)",
- R"(1 4 77 3 6)",
- R"( 1111131131111111666)",
- },
- }
-};
+// Store only right-facing fish assets (half the data!)
+const std::vector<AssetPair> rightFacingFishAssets = {
+ {{R"(???\??)", R"(??/ \?)", R"(>=_('>)", R"(??\_/?)", R"(???/??)"},
+ {R"( 1 )", R"( 1 1 )", R"(663745)", R"( 111 )", R"( 3 )"}},
+ {{R"(?????,????)", R"(?????}\???)", R"(\??.' `\?)", R"(}}< ( 6>)",
+ R"(/??`, .'?)", R"(?????}/???)", R"(?????'????)"},
+ {R"( 2 )", R"( 22 )", R"(6 11 11 )", R"(661 7 45)",
+ R"(6 11 11 )", R"( 33 )", R"( 3 )"}},
+ {{R"(???????,--,_????)", R"(__????_\.---'-.?)", R"(\ '.-" // o\)",
+ R"(/_.'-._ \\ /)", R"(???????`"--(/"`?)"},
+ {R"( 22222 )", R"(66 121111211 )", R"(6 6111 77 41)",
+ R"(6661111 77 1)", R"( 11113311 )"}},
+ {{R"(??__?)", R"(><_'>)", R"(???'?)"},
+ {R"( 11 )", R"(61145)", R"( 3 )"}},
+ {{R"(????????_.-`\??????)", R"(?????-:`_..,_\?????)",
+ R"(('-..:-` , '-.,?)", R"(?} _ ;':( o :)",
+ R"((.-`/'-.,__'` _.-`?)", R"(???`'-.,/??//`?????)"},
+ {R"( 22222 )", R"( 222111112 )",
+ R"(66661111 7 1111 )", R"( 6 1 7777 4 1)",
+ R"(6666211111177 1111 )", R"( 222222 333 )"}},
+ {{
+ R"(????????/\??????)",
+ R"(????????\.\_????)",
+ R"(\'-,.:-` '-,?)",
+ R"( ) _ (>( o <)",
+ R"(/.-`?':._ _.-`?)",
+ R"(??????;/?``?????)",
+ },
+ {
+ R"( 22 )",
+ R"( 2121 )",
+ R"(66661111 111 )",
+ R"( 6 1 777 4 1)",
+ R"(6666 1111 1111 )",
+ R"( 22 33 )",
+ }},
+ {{R"(_?????????_.*"\??????)", R"(\'-._..-*` `'*-.??)",
+ R"(?) , (( o >)", R"(/.`"*--.__)_.`_.-*`??)"},
+ {
+ R"(6 11222 )",
+ R"(6661111111 11111 )",
+ R"( 6 3 77 4 1)",
+ R"(6661111111311311111 )",
+ }}};
+
+inline const std::vector<AssetPair> fishAssetPairs =
+ SpriteUtils::createBidirectionalAssets(rightFacingFishAssets);
diff --git a/src/assets/SpriteUtils.h b/src/assets/SpriteUtils.h
@@ -0,0 +1,68 @@
+#pragma once
+#include <algorithm>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+struct AssetPair;
+
+namespace SpriteUtils {
+// Character mapping for directional elements
+const std::unordered_map<char, char> charFlipMap = {
+ {'(', ')'}, {')', '('}, {'[', ']'}, {']', '['}, {'{', '}'}, {'}', '{'},
+ {'<', '>'}, {'>', '<'}, {'/', '\\'}, {'\\', '/'}, {'`', '\''}, {'\'', '`'},
+};
+
+// Mirror a single character (handle directional flipping)
+inline char mirrorChar(char c) {
+ auto it = charFlipMap.find(c);
+ return (it != charFlipMap.end()) ? it->second : c;
+}
+
+// Mirror a single row with proper character flipping
+inline std::string mirrorRow(std::string row) {
+ // First reverse the string
+ std::reverse(row.begin(), row.end());
+
+ // Then flip directional characters
+ for (char &c : row) {
+ c = mirrorChar(c);
+ }
+
+ return row;
+}
+
+// Mirror an entire sprite
+inline std::vector<std::string>
+mirrorSprite(const std::vector<std::string> &sprite) {
+ std::vector<std::string> mirrored;
+ mirrored.reserve(sprite.size());
+
+ for (const auto &row : sprite) {
+ mirrored.push_back(mirrorRow(row));
+ }
+
+ return mirrored;
+}
+
+// Mirror an AssetPair
+inline AssetPair mirrorAssetPair(const AssetPair &asset) {
+ return {mirrorSprite(asset.image), mirrorSprite(asset.mask)};
+}
+
+// Create bidirectional asset pairs from right-facing assets
+inline std::vector<AssetPair>
+createBidirectionalAssets(const std::vector<AssetPair> &rightFacingAssets) {
+ std::vector<AssetPair> result;
+ result.reserve(rightFacingAssets.size() * 2);
+
+ for (const auto &asset : rightFacingAssets) {
+ // Add right-facing version
+ result.push_back(asset);
+ // Add left-facing (mirrored) version
+ result.push_back(mirrorAssetPair(asset));
+ }
+
+ return result;
+}
+} // namespace SpriteUtils