diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/AssetManager.cpp | 59 | ||||
-rw-r--r-- | src/AssetManager.hpp | 4 | ||||
-rw-r--r-- | src/Block.cpp | 531 | ||||
-rw-r--r-- | src/Block.hpp | 13 | ||||
-rw-r--r-- | src/Event.cpp | 5 | ||||
-rw-r--r-- | src/Framebuffer.cpp | 12 | ||||
-rw-r--r-- | src/Game.cpp | 241 | ||||
-rw-r--r-- | src/Game.hpp | 30 | ||||
-rw-r--r-- | src/GameState.cpp | 4 | ||||
-rw-r--r-- | src/GameState.hpp | 2 | ||||
-rw-r--r-- | src/GlobalState.cpp | 238 | ||||
-rw-r--r-- | src/GlobalState.hpp | 25 | ||||
-rw-r--r-- | src/Plugin.cpp | 261 | ||||
-rw-r--r-- | src/Plugin.hpp | 19 | ||||
-rw-r--r-- | src/Render.cpp | 107 | ||||
-rw-r--r-- | src/Render.hpp | 1 | ||||
-rw-r--r-- | src/Renderer.cpp | 3 | ||||
-rw-r--r-- | src/RendererEntity.cpp | 3 | ||||
-rw-r--r-- | src/RendererSection.cpp | 4 | ||||
-rw-r--r-- | src/RendererSectionData.cpp | 5 | ||||
-rw-r--r-- | src/RendererSky.cpp | 9 | ||||
-rw-r--r-- | src/RendererWorld.cpp | 70 | ||||
-rw-r--r-- | src/RendererWorld.hpp | 9 | ||||
-rw-r--r-- | src/Utility.cpp | 2 | ||||
-rw-r--r-- | src/World.cpp | 12 | ||||
-rw-r--r-- | src/main.cpp | 4 |
26 files changed, 786 insertions, 887 deletions
diff --git a/src/AssetManager.cpp b/src/AssetManager.cpp index 71800d7..19cd452 100644 --- a/src/AssetManager.cpp +++ b/src/AssetManager.cpp @@ -11,8 +11,10 @@ #define STB_IMAGE_IMPLEMENTATION #define STBI_ONLY_PNG #include <stb_image.h> +#include <optick.h> #include "Utility.hpp" +#include "Plugin.hpp" namespace fs = std::experimental::filesystem::v1; @@ -28,6 +30,7 @@ std::map<BlockId, BlockFaces> blockIdToBlockFaces; void LoadIds(); void LoadAssets(); void LoadTextures(); +void LoadScripts(); void WalkDirEntry(const fs::directory_entry &dirEntry, AssetTreeNode *node); void ParseAsset(AssetTreeNode &node); @@ -35,6 +38,7 @@ void ParseAssetTexture(AssetTreeNode &node); void ParseAssetBlockModel(AssetTreeNode &node); void ParseAssetBlockState(AssetTreeNode &node); void ParseAssetShader(AssetTreeNode &node); +void ParseAssetScript(AssetTreeNode &node); void ParseBlockModels(); @@ -58,6 +62,9 @@ void AssetManager::InitAssetManager() LoadIds(); ParseBlockModels(); + + PluginSystem::Init(); + LoadScripts(); } void LoadIds() { @@ -96,6 +103,36 @@ void LoadTextures() { atlas = std::make_unique<TextureAtlas>(textureData); } +void LoadScripts() { + AssetTreeNode *node = AssetManager::GetAssetByAssetName("/"); + for (auto &it : node->childs) { + for (auto &child : it->childs) { + if (child->name == "scripts") { + for (auto &script : child->childs) + { + if (script->name != "init") + continue; + + AssetScript *asset = dynamic_cast<AssetScript *>(script->asset.get()); + if (!asset) { + LOG(ERROR) << "Unrecognised script file /" << it->name; + continue; + } + try { + PluginSystem::Execute(asset->code, true); + } + catch (std::exception & e) { + LOG(ERROR) << "Failed loading script '" << script->name << "' in '" << it->name << "'"; + } + + break; + } + } + } + } + LOG(INFO) << "Scripts loaded"; +} + void WalkDirEntry(const fs::directory_entry &dirEntry, AssetTreeNode *node) { for (auto &file : fs::directory_iterator(dirEntry)) { node->childs.push_back(std::make_unique<AssetTreeNode>()); @@ -138,6 +175,11 @@ void ParseAsset(AssetTreeNode &node) { ParseAssetShader(node); return; } + + if (node.parent->name == "scripts") { + ParseAssetScript(node); + return; + } } void ParseAssetTexture(AssetTreeNode &node) { @@ -380,6 +422,14 @@ void ParseAssetShader(AssetTreeNode &node) { } } +void ParseAssetScript(AssetTreeNode &node) { + node.asset = std::make_unique<AssetScript>(); + AssetScript *asset = dynamic_cast<AssetScript*>(node.asset.get()); + asset->code = std::string((char*)node.data.data(), (char*)node.data.data() + node.data.size()); + node.data.clear(); + node.data.shrink_to_fit(); +} + void ParseBlockModels() { std::string textureName; @@ -563,16 +613,16 @@ BlockFaces &AssetManager::GetBlockModelByBlockId(BlockId block) { return blockIdToBlockFaces.find(block)->second; } - auto blockStateName = TransformBlockIdToBlockStateName(block); - AssetBlockState *asset = GetAsset<AssetBlockState>("/minecraft/blockstates/" + blockStateName.first); + BlockInfo blockInfo = GetBlockInfo(block); + AssetBlockState *asset = GetAsset<AssetBlockState>("/minecraft/blockstates/" + blockInfo.blockstate); if (!asset) return GetBlockModelByBlockId(BlockId{ 7788,0 }); BlockState &blockState = asset->blockState; - if (blockState.variants.find(blockStateName.second) == blockState.variants.end()) + if (blockState.variants.find(blockInfo.variant) == blockState.variants.end()) return GetBlockModelByBlockId(BlockId{ 7788,0 }); - BlockStateVariant &variant = blockState.variants[blockStateName.second]; + BlockStateVariant &variant = blockState.variants[blockInfo.variant]; if (variant.models.empty()) return GetBlockModelByBlockId(BlockId{ 7788,0 }); @@ -622,6 +672,7 @@ std::string AssetManager::GetAssetNameByBlockId(BlockId block) { } Asset *AssetManager::GetAssetPtr(const std::string & assetName) { + OPTICK_EVENT(); AssetTreeNode *node; if (assetName[0] != '/') node = GetAssetByAssetName('/' + assetName); diff --git a/src/AssetManager.hpp b/src/AssetManager.hpp index de3881e..bf948b3 100644 --- a/src/AssetManager.hpp +++ b/src/AssetManager.hpp @@ -167,6 +167,10 @@ struct AssetShader : Asset { std::unique_ptr<Shader> shader; }; +struct AssetScript : Asset { + std::string code; +}; + namespace AssetManager { void InitAssetManager(); diff --git a/src/Block.cpp b/src/Block.cpp index a12db9d..48c099d 100644 --- a/src/Block.cpp +++ b/src/Block.cpp @@ -1,525 +1,20 @@ #include "Block.hpp" -std::pair<std::string, std::string> TransformBlockIdToBlockStateName(BlockId blockId) { - switch (blockId.id) { - case 1: { - if (blockId.state > 6) - break; - static const std::pair<std::string, std::string> ids[] = { - std::pair<std::string,std::string>("stone", "normal"), - std::pair<std::string,std::string>("granite", "normal"), - std::pair<std::string,std::string>("smooth_granite", "normal"), - std::pair<std::string,std::string>("diorite", "normal"), - std::pair<std::string,std::string>("smooth_diorite", "normal"), - std::pair<std::string,std::string>("andesite", "normal"), - std::pair<std::string,std::string>("smooth_andesite", "normal"), - }; - return ids[blockId.state]; - } - case 2: { - return std::make_pair("grass", "snowy=false"); - } - case 3: { - if (blockId.state > 2) - break; - static const std::pair<std::string, std::string> ids[] = { - std::pair<std::string,std::string>("dirt", "normal"), - std::pair<std::string,std::string>("coarse_dirt", "normal"), - std::pair<std::string,std::string>("podzol", "snowy=false"), - }; - return ids[blockId.state]; - } - case 4: { - return std::make_pair("cobblestone", "normal"); - } - case 5: { - if (blockId.state > 5) - break; - static const std::pair<std::string, std::string> ids[] = { - std::pair<std::string,std::string>("oak_planks", "normal"), - std::pair<std::string,std::string>("spruce_planks", "normal"), - std::pair<std::string,std::string>("birch_planks", "normal"), - std::pair<std::string,std::string>("jungle_planks", "normal"), - std::pair<std::string,std::string>("acacia_planks", "normal"), - std::pair<std::string,std::string>("dark_oak_planks", "normal"), - }; - return ids[blockId.state]; - } - case 7: { - return std::make_pair("bedrock", "normal"); - } - case 8: - case 9: { - return std::make_pair("water", "normal"); - } - case 10: - case 11: { - return std::make_pair("lava", "normal"); - } - case 12: { - if (blockId.state > 1) - break; - static const std::pair<std::string, std::string> ids[] = { - std::pair<std::string,std::string>("sand", "normal"), - std::pair<std::string,std::string>("red_sand", "normal"), - }; - return ids[blockId.state]; - } - case 13: { - return std::make_pair("gravel", "normal"); - } - case 14: { - return std::make_pair("gold_ore", "normal"); - } - case 15: { - return std::make_pair("iron_ore", "normal"); - } - case 16: { - return std::make_pair("coal_ore", "normal"); - } - case 17: { - unsigned char type = blockId.state & 0x3; - unsigned char dir = (blockId.state & 0xC) >> 2; - static const std::string types[] = { - "oak_log", - "spruce_log", - "birch_log", - "jungle_log", - }; - static const std::string dirs[] = { - "axis=y", - "axis=x", - "axis=z", - "axis=none", - }; - return std::make_pair(types[type], dirs[dir]); - } - case 18: { - static const std::pair<std::string, std::string> ids[] = { - std::pair<std::string,std::string>("oak_leaves", "normal"), - std::pair<std::string,std::string>("spruce_leaves", "normal"), - std::pair<std::string,std::string>("birch_leaves", "normal"), - std::pair<std::string,std::string>("jungle_leaves", "normal"), - }; - return ids[blockId.state & 0x3]; - } - case 20: { - return std::make_pair("glass", "normal"); - } - case 21: { - return std::make_pair("lapis_ore", "normal"); - } - case 22: { - return std::make_pair("lapis_block", "normal"); - } - case 24: { - if (blockId.state > 2) - break; - static const std::pair<std::string, std::string> ids[] = { - std::pair<std::string,std::string>("sandstone", "normal"), - std::pair<std::string,std::string>("chiseled_sandstone", "normal"), - std::pair<std::string,std::string>("smooth_sandstone", "normal"), - }; - return ids[blockId.state]; - } - case 30: { - return std::make_pair("web", "normal"); - } - case 31: { - if (blockId.state > 2) - break; - static const std::pair<std::string, std::string> ids[] = { - std::pair<std::string,std::string>("dead_bush", "normal"), - std::pair<std::string,std::string>("tall_grass", "normal"), - std::pair<std::string,std::string>("fern", "normal"), - }; - return ids[blockId.state]; - } - case 32: { - return std::make_pair("dead_bush", "normal"); - } - case 35: { - static const std::pair<std::string, std::string> ids[] = { - std::pair<std::string,std::string>("white_wool", "normal"), - std::pair<std::string,std::string>("orange_wool", "normal"), - std::pair<std::string,std::string>("magenta_wool", "normal"), - std::pair<std::string,std::string>("light_blue_wool", "normal"), - std::pair<std::string,std::string>("yellow_wool", "normal"), - std::pair<std::string,std::string>("lime_wool", "normal"), - std::pair<std::string,std::string>("pink_wool", "normal"), - std::pair<std::string,std::string>("gray_wool", "normal"), - std::pair<std::string,std::string>("silver_wool", "normal"), - std::pair<std::string,std::string>("cyan_wool", "normal"), - std::pair<std::string,std::string>("purple_wool", "normal"), - std::pair<std::string,std::string>("blue_wool", "normal"), - std::pair<std::string,std::string>("brown_wool", "normal"), - std::pair<std::string,std::string>("green_wool", "normal"), - std::pair<std::string,std::string>("red_wool", "normal"), - std::pair<std::string,std::string>("black_wool", "normal"), - }; - return ids[blockId.state]; - } - case 37: { - return std::make_pair("dandelion", "normal"); - } - case 38: { - if (blockId.state > 8) - break; - static const std::pair<std::string, std::string> ids[] = { - std::pair<std::string,std::string>("poppy", "normal"), - std::pair<std::string,std::string>("blue_orchid", "normal"), - std::pair<std::string,std::string>("allium", "normal"), - std::pair<std::string,std::string>("houstonia", "normal"), - std::pair<std::string,std::string>("red_tulip", "normal"), - std::pair<std::string,std::string>("orange_tulip", "normal"), - std::pair<std::string,std::string>("white_tulip", "normal"), - std::pair<std::string,std::string>("pink_tulip", "normal"), - std::pair<std::string,std::string>("oxeye_daisy", "normal"), - }; - return ids[blockId.state]; - } - case 39: { - return std::make_pair("brown_mushroom","normal"); - } - case 40: { - return std::make_pair("red_mushroom", "normal"); - } - case 41: { - return std::make_pair("gold_block", "normal"); - } - case 44: { - return std::make_pair("stone_slab", "half=" + std::string(!(blockId.state >> 3) ? "bottom" : "top")); - } - case 45: { - return std::make_pair("brick_block", "normal"); - } - case 46: { - return std::make_pair("tnt", "normal"); - } - case 47: { - return std::make_pair("bookshelf", "normal"); - } - case 48: { - return std::make_pair("mossy_cobblestone", "normal"); - } - case 49: { - return std::make_pair("obsidian", "normal"); - } - case 50: { - if (blockId.state > 5) - break; - static const std::pair<std::string, std::string> ids[] = { - std::pair<std::string,std::string>("", ""), - std::pair<std::string,std::string>("torch", "facing=east"), - std::pair<std::string,std::string>("torch", "facing=west"), - std::pair<std::string,std::string>("torch", "facing=south"), - std::pair<std::string,std::string>("torch", "facing=north"), - std::pair<std::string,std::string>("torch", "facing=up"), - }; - return ids[blockId.state]; - } - case 53: { - bool isUp = blockId.state >> 2; - unsigned char dir = blockId.state & 0x3; - static const std::string dirs[] = { - "facing=east,half=", - "facing=west,half=", - "facing=south,half=", - "facing=north,half=", - }; +#include <map> - return std::make_pair("oak_stairs", dirs[dir] + (isUp? "top" : "bottom") +",shape=straight"); - } - case 56: { - return std::make_pair("diamond_ore", "normal"); - } - case 57: { - return std::make_pair("diamond_block", "normal"); - } - case 59: { - return std::make_pair("wheat", "age=" + std::to_string(blockId.state)); - } - case 60: { - return std::make_pair("farmland", "moisture=" + std::to_string(7 - blockId.state)); - } - case 61: { - static const std::string dirs[] = { - "", - "", - "facing=north", - "facing=south", - "facing=west", - "facing=east", - }; - return std::make_pair("furnace", dirs[blockId.state]); - } - case 64: { - bool isUp = !(blockId.state >> 3); - bool hingeIsLeft = true; - bool isOpen = 0; - unsigned char dir = 0; - if (isUp) - hingeIsLeft = blockId.state & 0x1; - else { - isOpen = (blockId.state >> 1) & 0x1; - dir = blockId.state >> 2; - } - static const std::string dirs[] = { - "east", - "south", - "west", - "north", - }; +#include "Plugin.hpp" - return std::make_pair("wooden_door", "facing=" + dirs[dir] + ",half=" + (isUp ? "upper" : "lower") + ",hinge=" + (hingeIsLeft ? "left" : "right") + ",open=" + (isOpen ? "true" : "false")); - } - case 67: { - bool isUp = blockId.state >> 2; - unsigned char dir = blockId.state & 0x3; - static const std::string dirs[] = { - "facing=east,half=", - "facing=west,half=", - "facing=south,half=", - "facing=north,half=", - }; +std::map<BlockId, BlockInfo> staticBlockInfo; - return std::make_pair("stone_stairs", dirs[dir] + (isUp ? "top" : "bottom") + ",shape=straight"); - } - case 69: { - bool isActive = blockId.state >> 3; - static const std::string types[] = { - "facing=down_x", - "facing=east", - "facing=west", - "facing=south", - "facing=north", - "facing=up_z", - "facing=up_x", - "facing=down_z", - }; - - return std::make_pair("lever", types[blockId.state & 0x7] + ",powered=" + (isActive ? "true" : "false")); - } - case 73: { - return std::make_pair("redstone_ore", "normal"); - } - case 74: { - return std::make_pair("redstone_ore", "normal"); - } - case 78: { - if (blockId.state > 7) - break; - static const std::pair<std::string, std::string> ids[] = { - std::pair<std::string,std::string>("snow_layer", "layers=1"), - std::pair<std::string,std::string>("snow_layer", "layers=2"), - std::pair<std::string,std::string>("snow_layer", "layers=3"), - std::pair<std::string,std::string>("snow_layer", "layers=4"), - std::pair<std::string,std::string>("snow_layer", "layers=5"), - std::pair<std::string,std::string>("snow_layer", "layers=6"), - std::pair<std::string,std::string>("snow_layer", "layers=7"), - std::pair<std::string,std::string>("snow_layer", "layers=8"), - }; - return ids[blockId.state]; - } - case 79: { - return std::make_pair("ice", "normal"); - } - case 80: { - return std::make_pair("snow", "normal"); - } - case 81: { - return std::make_pair("cactus", "normal"); - } - case 82: { - return std::make_pair("clay", "normal"); - } - case 83: { - return std::make_pair("reeds", "normal"); - } - case 86: { - if (blockId.state > 3) - break; - static const std::pair<std::string, std::string> ids[] = { - std::pair<std::string,std::string>("pumpkin", "facing=south"), - std::pair<std::string,std::string>("pumpkin", "facing=west"), - std::pair<std::string,std::string>("pumpkin", "facing=north"), - std::pair<std::string,std::string>("pumpkin", "facing=east"), - }; - return ids[blockId.state]; - } - case 87: { - return std::make_pair("netherrack", "normal"); - } - case 88: { - return std::make_pair("soul_sand", "normal"); - } - case 89: { - return std::make_pair("glowstone", "normal"); - } - case 90: { - return std::make_pair("portal", blockId.state == 1 ? "axis=x" : "axis=z"); - } - case 93: { - static const std::string dirs[] = { - "east", - "south", - "west", - "north", - }; - unsigned char dir = blockId.state & 0x3; - unsigned char delay = (blockId.state >> 2) + 1; - return std::make_pair("unpowered_repeater", "delay=" + std::to_string(delay) + ",facing=" + dirs[dir] + ",locked=false"); - } - case 94: { - static const std::string dirs[] = { - "east", - "south", - "west", - "north", - }; - unsigned char dir = blockId.state & 0x3; - unsigned char delay = (blockId.state >> 2) + 1; - return std::make_pair("powered_repeater", "delay=" + std::to_string(delay) + ",facing=" + dirs[dir] + ",locked=false"); - } - case 99: { - static const std::string variants[] = { - "variant=all_inside", - "variant=north_west", - "variant=north", - "variant=north_east", - "variant=west", - "variant=center", - "variant=east", - "variant=south_west", - "variant=south", - "variant=south_east", - "variant=stem", - "variant=all_outside", - "variant=all_stem", - }; - return std::make_pair("brown_mushroom_block", variants[blockId.state]); - } - case 100: { - static const std::string variants[] = { - "variant=all_inside", - "variant=north_west", - "variant=north", - "variant=north_east", - "variant=west", - "variant=center", - "variant=east", - "variant=south_west", - "variant=south", - "variant=south_east", - "variant=stem", - "variant=all_outside", - "variant=all_stem", - }; - return std::make_pair("red_mushroom_block", variants[blockId.state]); - } - case 103: { - return std::make_pair("melon_block", "normal"); - } - case 106: { - static const std::string values[] = { - "false", - "true", - }; - return std::make_pair("vine", "east=" + values[(blockId.state >> 3) & 0x1] + ",north=" + values[(blockId.state >> 2) & 0x1] + ",south=" + values[blockId.state & 0x1] + ",up=" + values[blockId.state == 0] + ",west=" + values[(blockId.state >> 1) & 0x1]); - } - case 111: { - return std::make_pair("waterlily", "normal"); - } - case 112: { - return std::make_pair("nether_brick", "normal"); - } - case 121: { - return std::make_pair("end_stone", "normal"); - } - case 129: { - return std::make_pair("emerald_ore", "normal"); - } - case 133: { - return std::make_pair("emerald_block", "normal"); - } - case 141: { - return std::make_pair("carrots", "age=" + std::to_string(blockId.state)); - } - case 142: { - return std::make_pair("potatoes", "age=" + std::to_string(blockId.state)); - } - case 149: { - static const std::string dirs[] = { - "east", - "south", - "west", - "north", - }; - unsigned char dir = blockId.state & 0x3; - bool substractMode = (blockId.state >> 2) & 0x1; - bool isPowered = blockId.state >> 3; - return std::make_pair("unpowered_comparator", "facing=" + dirs[dir] + ",mode=" + (substractMode ? "subtract" : "compare") + ",powered=" + (isPowered ? "true" : "false")); - } - case 153: { - return std::make_pair("quartz_ore", "normal"); - } - case 155: { - return std::make_pair("quartz_block", "normal"); - } - case 161: { - if ((blockId.state & 0x3) > 2) - break; - static const std::pair<std::string, std::string> ids[] = { - std::pair<std::string,std::string>("acacia_leaves", "normal"), - std::pair<std::string,std::string>("dark_oak_leaves", "normal"), - }; - return ids[blockId.state & 0x3]; - } - case 162: { - unsigned char type = blockId.state & 0x3; - if (type > 2) - break; - unsigned char dir = (blockId.state & 0xC) >> 2; - static const std::string types[] = { - "acacia_log", - "dark_oak_log", - }; - static const std::string dirs[] = { - "axis=y", - "axis=x", - "axis=z", - "axis=none", - }; - return std::make_pair(types[type], dirs[dir]); - } - case 175: { - bool high = ((blockId.state >> 3) & 0x1); - unsigned char type = blockId.state & 0x7; - - static const std::string types[] = { - "sunflower", - "syringa", - "double_grass", - "double_fern", - "double_rose", - "paeonia", - }; +void RegisterStaticBlockInfo(BlockId blockId, BlockInfo blockInfo) { + staticBlockInfo[blockId] = blockInfo; +} - static const std::string isHigh[] = { - "half=lower", - "half=upper", - }; - return std::make_pair(types[type], isHigh[high]); - } - case 207: { - return std::make_pair("beetroots", "age=" + std::to_string(blockId.state)); - } - case 208: { - return std::make_pair("grass_path", "normal"); - } - default: - break; - } - - return std::make_pair("", ""); +BlockInfo GetBlockInfo(BlockId blockId, Vector blockPos) { + auto it = staticBlockInfo.find(blockId); + if (it != staticBlockInfo.end()) + return it->second; + if (blockPos == Vector()) + return BlockInfo{ true, "", "" }; + return PluginSystem::RequestBlockInfo(blockPos); } diff --git a/src/Block.hpp b/src/Block.hpp index fa8b51a..fbeeaeb 100644 --- a/src/Block.hpp +++ b/src/Block.hpp @@ -3,6 +3,8 @@ #include <utility> #include <string> +#include "Vector.hpp" + struct BlockId { unsigned short id : 13; unsigned char state : 4; @@ -39,5 +41,12 @@ namespace std { }; } -//returns name of blockstate and name of variant -std::pair<std::string, std::string> TransformBlockIdToBlockStateName(BlockId blockId);
\ No newline at end of file +struct BlockInfo { + bool collides; + std::string blockstate; + std::string variant; +}; + +void RegisterStaticBlockInfo(BlockId blockId, BlockInfo blockInfo); + +BlockInfo GetBlockInfo(BlockId blockId, Vector blockPos = Vector(0,0,0));
\ No newline at end of file diff --git a/src/Event.cpp b/src/Event.cpp index 5c126bb..ea09af3 100644 --- a/src/Event.cpp +++ b/src/Event.cpp @@ -1,5 +1,7 @@ #include "Event.hpp" +#include <optick.h> + std::list<EventListener*> EventSystem::listeners; std::recursive_mutex EventSystem::listenersMutex; @@ -14,6 +16,7 @@ EventListener::~EventListener() { } void EventListener::HandleEvent() { + OPTICK_EVENT(); if (!NotEmpty()) return; @@ -27,6 +30,7 @@ void EventListener::HandleEvent() { } void EventListener::HandleAllEvents() { + OPTICK_EVENT(); if (!NotEmpty()) return; @@ -54,6 +58,7 @@ void EventListener::RegisterHandler(size_t eventId, const EventListener::Handler } void EventListener::PollEvents() { + OPTICK_EVENT(); std::lock_guard<std::recursive_mutex> rawLock (rawEventsMutex); if (rawEvents.empty()) return; diff --git a/src/Framebuffer.cpp b/src/Framebuffer.cpp index fb7ebc7..d81b0e0 100644 --- a/src/Framebuffer.cpp +++ b/src/Framebuffer.cpp @@ -3,11 +3,13 @@ #include <string> #include "Utility.hpp" #include "AssetManager.hpp" +#include <optick.h> const GLuint magic = 316784; GLuint quadVao = magic, quadVbo = magic; Framebuffer::Framebuffer(unsigned int width, unsigned int height, bool createDepthStencilBuffer) : width(width), height(height) { + OPTICK_EVENT(); if (quadVao == magic) { float quadVertices[] = { // positions // texCoords @@ -70,11 +72,13 @@ Framebuffer::~Framebuffer() { } void Framebuffer::Activate() { + OPTICK_EVENT(); glViewport(0, 0, width, height); glBindFramebuffer(GL_FRAMEBUFFER, fbo); } void Framebuffer::RenderTo(Framebuffer &target) { + OPTICK_EVENT(); glBindFramebuffer(GL_FRAMEBUFFER, target.fbo); glViewport(0, 0, target.width, target.height); AssetManager::GetAsset<AssetShader>("/altcraft/shaders/fbo")->shader->Activate(); @@ -96,8 +100,8 @@ void Framebuffer::Resize(unsigned int newWidth, unsigned int newHeight) { } } -Framebuffer &Framebuffer::GetDefault() -{ +Framebuffer &Framebuffer::GetDefault() { + OPTICK_EVENT(); static char fboDefaultData[sizeof(Framebuffer)]; static Framebuffer *fboDefault = nullptr; if (fboDefault == nullptr) { @@ -111,8 +115,8 @@ Framebuffer &Framebuffer::GetDefault() return *fboDefault; } -void Framebuffer::Clear(bool color, bool depth, bool stencil) -{ +void Framebuffer::Clear(bool color, bool depth, bool stencil) { + OPTICK_EVENT(); Activate(); GLbitfield clearBits = 0; if (color) diff --git a/src/Game.cpp b/src/Game.cpp new file mode 100644 index 0000000..c69ff5d --- /dev/null +++ b/src/Game.cpp @@ -0,0 +1,241 @@ +#include "Game.hpp" + +#include <memory> + +#include <optick.h> + +#include "Render.hpp" +#include "GameState.hpp" +#include "NetworkClient.hpp" +#include "Plugin.hpp" + +bool isRunning = true; +bool isMoving[5] = { 0,0,0,0,0 }; +State state; +std::unique_ptr<NetworkClient> nc; +std::unique_ptr<GameState> gs; +std::unique_ptr<Render> render; +std::unique_ptr<LoopExecutionTimeController> timer; +EventListener listener; + +void InitEvents() { + /* + * Network Events + */ + + listener.RegisterHandler("ConnectToServer", [](const Event & eventData) { + auto data = eventData.get <std::tuple<std::string, unsigned short, std::string>>(); //address,port,username + if (std::get<0>(data) == "" || std::get<1>(data) == 0) + LOG(FATAL) << "NOT VALID CONNECT-TO-SERVER EVENT"; + if (nc != nullptr) { + LOG(ERROR) << "Already connected"; + return; + } + LOG(INFO) << "Connecting to server at address " + std::get<0>(data) + ":" + std::to_string(std::get<1>(data)) + " as " + std::get<2>(data); + PUSH_EVENT("Connecting",0); + gs = std::make_unique<GameState>(); + try { + nc = std::make_unique<NetworkClient>(std::get<0>(data), + std::get<1>(data), + std::get<2>(data)); + } catch (std::exception &e) { + LOG(WARNING) << "Connection failed"; + PUSH_EVENT("ConnectionFailed", std::string(e.what())); + gs.reset(); + return; + } + LOG(INFO) << "Connected to server"; + PUSH_EVENT("ConnectionSuccessfull", 0); + }); + + listener.RegisterHandler("Disconnect", [](const Event& eventData) { + auto data = eventData.get<std::string>(); + PUSH_EVENT("Disconnected", data); + LOG(INFO) << "Disconnected: " << data; + nc.reset(); + }); + + listener.RegisterHandler("NetworkClientException", [](const Event& eventData) { + auto data = eventData.get < std::string>(); + PUSH_EVENT("Disconnect", data); + }); + + /* + * GameState Events + */ + + listener.RegisterHandler("Exit", [](const Event&) { + isRunning = false; + }); + + listener.RegisterHandler("Disconnected", [](const Event&) { + if (!gs) + return; + gs.reset(); + }); + + listener.RegisterHandler("SendChatMessage", [](const Event& eventData) { + auto message = eventData.get<std::string>(); + if (message[0] == '!' && message[1] != '!') { + PluginSystem::Execute(message.substr(1)); + return; + } + if (message[0] == '!') + message = message.substr(1); + auto packet = std::static_pointer_cast<Packet>(std::make_shared<PacketChatMessageSB>(message)); + PUSH_EVENT("SendPacket",packet); + }); + + /* + * Phys Events + */ + + listener.RegisterHandler("KeyPressed", [](const Event& eventData) { + if (!gs) + return; + switch (eventData.get<SDL_Scancode>()) { + case SDL_SCANCODE_W: + isMoving[GameState::FORWARD] = true; + break; + case SDL_SCANCODE_A: + isMoving[GameState::LEFT] = true; + break; + case SDL_SCANCODE_S: + isMoving[GameState::BACKWARD] = true; + break; + case SDL_SCANCODE_D: + isMoving[GameState::RIGHT] = true; + break; + case SDL_SCANCODE_SPACE: + isMoving[GameState::JUMP] = true; + break; + default: + break; + } + }); + + listener.RegisterHandler("KeyReleased", [](const Event& eventData) { + if (!gs) + return; + switch (eventData.get<SDL_Scancode>()) { + case SDL_SCANCODE_W: + isMoving[GameState::FORWARD] = false; + break; + case SDL_SCANCODE_A: + isMoving[GameState::LEFT] = false; + break; + case SDL_SCANCODE_S: + isMoving[GameState::BACKWARD] = false; + break; + case SDL_SCANCODE_D: + isMoving[GameState::RIGHT] = false; + break; + case SDL_SCANCODE_SPACE: + isMoving[GameState::JUMP] = false; + break; + default: + break; + } + }); + + listener.RegisterHandler("MouseMove", [](const Event& eventData) { + if (!gs) + return; + auto data = eventData.get<std::tuple<double,double>>(); + gs->HandleRotation(std::get<0>(data),std::get<1>(data)); + }); + + listener.RegisterHandler("ReceivedPacket", [](const Event& eventData) { + if (!gs) + return; + std::shared_ptr<Packet> packet = eventData.get<std::shared_ptr<Packet>>(); + gs->UpdatePacket(packet); + }); + + listener.RegisterHandler("LmbPressed",[](const Event& eventData) { + if (!gs) + return; + gs->StartDigging(); + }); + + listener.RegisterHandler("LmbReleased",[](const Event& eventData) { + if (!gs) + return; + gs->CancelDigging(); + }); + + listener.RegisterHandler("RmbPressed", [](const Event& eventData) { + if (!gs) + return; + gs->PlaceBlock(); + }); + + listener.RegisterHandler("SelectedBlockChanged", [](const Event& eventData) { + if (!gs) + return; + //TODO: + //gs->CancelDigging(); + }); +} + +void RunGame() { + OPTICK_THREAD("Main"); + InitEvents(); + + timer = std::make_unique<LoopExecutionTimeController>(std::chrono::milliseconds(16)); + + render = std::make_unique<Render>(900, 480, "AltCraft"); + + SetState(State::MainMenu); + + while (isRunning) { + OPTICK_FRAME("MainThread"); + listener.HandleAllEvents(); + PluginSystem::CallOnTick(timer->GetRealDeltaS()); + if (gs) { + if (GetState() == State::Playing) { + if (isMoving[GameState::FORWARD]) + gs->HandleMovement(GameState::FORWARD, timer->GetRealDeltaS()); + if (isMoving[GameState::BACKWARD]) + gs->HandleMovement(GameState::BACKWARD, timer->GetRealDeltaS()); + if (isMoving[GameState::LEFT]) + gs->HandleMovement(GameState::LEFT, timer->GetRealDeltaS()); + if (isMoving[GameState::RIGHT]) + gs->HandleMovement(GameState::RIGHT, timer->GetRealDeltaS()); + if (isMoving[GameState::JUMP]) + gs->HandleMovement(GameState::JUMP, timer->GetRealDeltaS()); + } + gs->Update(timer->GetRealDeltaS()); + } + render->Update(); + timer->Update(); + } + + render.reset(); +} + +State GetState() { + return state; +} + +void SetState(State newState) { + if (newState != state) + PUSH_EVENT("StateUpdated", 0); + state = newState; +} + +GameState *GetGameState() { + return gs.get(); +} + +Render *GetRender() { + return render.get(); +} + +NetworkClient *GetNetworkClient() { + return nc.get(); +} + +LoopExecutionTimeController* GetTime() { + return timer.get(); +} diff --git a/src/Game.hpp b/src/Game.hpp new file mode 100644 index 0000000..f7efd11 --- /dev/null +++ b/src/Game.hpp @@ -0,0 +1,30 @@ +#pragma once + +class GameState; +class Render; +class NetworkClient; +class LoopExecutionTimeController; + +enum class State { + InitialLoading, + MainMenu, + Loading, + Playing, + Paused, + Inventory, + Chat, +}; + +void RunGame(); + +State GetState(); + +void SetState(State newState); + +GameState* GetGameState(); + +Render* GetRender(); + +NetworkClient* GetNetworkClient(); + +LoopExecutionTimeController *GetTime();
\ No newline at end of file diff --git a/src/GameState.cpp b/src/GameState.cpp index ace2488..e4278ec 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -2,11 +2,13 @@ #include <glm/gtc/matrix_transform.hpp> #include <easylogging++.h> +#include <optick.h> #include "Event.hpp" #include "Packet.hpp" -void GameState::Update(float deltaTime) { +void GameState::Update(double deltaTime) { + OPTICK_EVENT(); if (!gameStatus.isGameStarted) return; diff --git a/src/GameState.hpp b/src/GameState.hpp index 8318c8a..5489ac6 100644 --- a/src/GameState.hpp +++ b/src/GameState.hpp @@ -70,7 +70,7 @@ class GameState { std::vector<Window> openedWindows; public: - void Update(float deltaTime); + void Update(double deltaTime); void UpdatePacket(std::shared_ptr<Packet> ptr); diff --git a/src/GlobalState.cpp b/src/GlobalState.cpp deleted file mode 100644 index afa1a56..0000000 --- a/src/GlobalState.cpp +++ /dev/null @@ -1,238 +0,0 @@ -#include "GlobalState.hpp" - -#include "NetworkClient.hpp" -#include "GameState.hpp" -#include "Render.hpp" -#include "DebugInfo.hpp" -#include "Event.hpp" - -//Global game variables -std::unique_ptr<NetworkClient> nc; -std::unique_ptr<GameState> gs; -std::shared_ptr<GameState> gsReadOnly; -std::unique_ptr<Render> render; -bool isRunning; -bool isPhysRunning; -EventListener listener; -bool isMoving[5] = { 0,0,0,0,0 }; -std::thread threadPhys; -State state; -std::mutex gsCopyMutex; - -void PhysExec(); - -void InitEvents() { - /* - * Network Events - */ - - listener.RegisterHandler("Exit", [](const Event&) { - isRunning = false; - }); - - listener.RegisterHandler("ConnectToServer", [](const Event& eventData) { - auto data = eventData.get <std::tuple<std::string, unsigned short, std::string>>(); //address,port,username - if (std::get<0>(data) == "" || std::get<1>(data) == 0) - LOG(FATAL) << "NOT VALID CONNECT-TO-SERVER EVENT"; - if (nc != nullptr) { - LOG(ERROR) << "Already connected"; - return; - } - LOG(INFO) << "Connecting to server at address " + std::get<0>(data) + ":" + std::to_string(std::get<1>(data)) + " as " + std::get<2>(data); - PUSH_EVENT("Connecting",0); - gs = std::make_unique<GameState>(); - isPhysRunning = true; - threadPhys = std::thread(&PhysExec); - try { - nc = std::make_unique<NetworkClient>(std::get<0>(data), - std::get<1>(data), - std::get<2>(data)); - } catch (std::exception &e) { - LOG(WARNING) << "Connection failed"; - PUSH_EVENT("ConnectionFailed", std::string(e.what())); - isPhysRunning = false; - threadPhys.join(); - gs.reset(); - return; - } - LOG(INFO) << "Connected to server"; - PUSH_EVENT("ConnectionSuccessfull", 0); - }); - - listener.RegisterHandler("Disconnect", [](const Event& eventData) { - auto data = eventData.get<std::string>(); - PUSH_EVENT("Disconnected", data); - LOG(INFO) << "Disconnected: " << data; - nc.reset(); - }); - - listener.RegisterHandler("NetworkClientException", [](const Event& eventData) { - auto data = eventData.get < std::string>(); - PUSH_EVENT("Disconnect", data); - }); - - /* - * GameState Events - */ - - listener.RegisterHandler("Exit", [](const Event&) { - isRunning = false; - }); - - listener.RegisterHandler("Disconnected", [](const Event&) { - if (!gs) - return; - isPhysRunning = false; - threadPhys.join(); - gs.reset(); - }); - - listener.RegisterHandler("SendChatMessage", [](const Event& eventData) { - auto message = eventData.get<std::string>(); - auto packet = std::static_pointer_cast<Packet>(std::make_shared<PacketChatMessageSB>(message)); - PUSH_EVENT("SendPacket",packet); - }); -} - -void PhysExec() { - EventListener listener; - - listener.RegisterHandler("KeyPressed", [](const Event& eventData) { - if (!gs) - return; - switch (eventData.get<SDL_Scancode>()) { - case SDL_SCANCODE_W: - isMoving[GameState::FORWARD] = true; - break; - case SDL_SCANCODE_A: - isMoving[GameState::LEFT] = true; - break; - case SDL_SCANCODE_S: - isMoving[GameState::BACKWARD] = true; - break; - case SDL_SCANCODE_D: - isMoving[GameState::RIGHT] = true; - break; - case SDL_SCANCODE_SPACE: - isMoving[GameState::JUMP] = true; - break; - default: - break; - } - }); - - listener.RegisterHandler("KeyReleased", [](const Event& eventData) { - if (!gs) - return; - switch (eventData.get<SDL_Scancode>()) { - case SDL_SCANCODE_W: - isMoving[GameState::FORWARD] = false; - break; - case SDL_SCANCODE_A: - isMoving[GameState::LEFT] = false; - break; - case SDL_SCANCODE_S: - isMoving[GameState::BACKWARD] = false; - break; - case SDL_SCANCODE_D: - isMoving[GameState::RIGHT] = false; - break; - case SDL_SCANCODE_SPACE: - isMoving[GameState::JUMP] = false; - break; - default: - break; - } - }); - - listener.RegisterHandler("MouseMove", [](const Event& eventData) { - if (!gs) - return; - auto data = eventData.get<std::tuple<double,double>>(); - gs->HandleRotation(std::get<0>(data),std::get<1>(data)); - }); - - listener.RegisterHandler("ReceivedPacket", [](const Event& eventData) { - std::shared_ptr<Packet> packet = eventData.get<std::shared_ptr<Packet>>(); - gs->UpdatePacket(packet); - }); - - listener.RegisterHandler("LmbPressed",[](const Event& eventData) { - gs->StartDigging(); - }); - - listener.RegisterHandler("LmbReleased",[](const Event& eventData) { - gs->CancelDigging(); - }); - - listener.RegisterHandler("RmbPressed", [](const Event& eventData) { - gs->PlaceBlock(); - }); - - listener.RegisterHandler("SelectedBlockChanged", [](const Event& eventData) { - //TODO: - //gs->CancelDigging(); - }); - - LoopExecutionTimeController timer(std::chrono::milliseconds(8)); - - while (isPhysRunning) { - DebugInfo::gameThreadTime = timer.GetRealDeltaS() * 1000'00.0f; - - if (state == State::Playing) { - if (isMoving[GameState::FORWARD]) - gs->HandleMovement(GameState::FORWARD, timer.GetRealDeltaS()); - if (isMoving[GameState::BACKWARD]) - gs->HandleMovement(GameState::BACKWARD, timer.GetRealDeltaS()); - if (isMoving[GameState::LEFT]) - gs->HandleMovement(GameState::LEFT, timer.GetRealDeltaS()); - if (isMoving[GameState::RIGHT]) - gs->HandleMovement(GameState::RIGHT, timer.GetRealDeltaS()); - if (isMoving[GameState::JUMP]) - gs->HandleMovement(GameState::JUMP, timer.GetRealDeltaS()); - } - - gs->Update(timer.GetRealDeltaS()); - - listener.HandleAllEvents(); - - gsCopyMutex.lock(); - gsReadOnly = std::make_shared<GameState>(*gs.get()); - gsCopyMutex.unlock(); - - timer.Update(); - } -} - -void GlobalState::Exec() { - render = std::make_unique<Render>(900, 480, "AltCraft"); - isRunning = true; - InitEvents(); - GlobalState::SetState(State::MainMenu); - while (isRunning) { - render->Update(); - listener.HandleAllEvents(); - } - PUSH_EVENT("Exit", 0); - isRunning = false; - render.reset(); -} - -std::shared_ptr<GameState> GlobalState::GetGameState() { - std::lock_guard<std::mutex> guard(gsCopyMutex); - return gsReadOnly; -} - -Render *GlobalState::GetRender() { - return render.get(); -} - -State GlobalState::GetState() { - return state; -} - -void GlobalState::SetState(const State &newState) { - if (newState != state) - PUSH_EVENT("StateUpdated", 0); - state = newState; -} diff --git a/src/GlobalState.hpp b/src/GlobalState.hpp deleted file mode 100644 index bc7224f..0000000 --- a/src/GlobalState.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include <memory> - -class NetworkClient; -class GameState; -class Render; - -enum class State { - InitialLoading, - MainMenu, - Loading, - Playing, - Paused, - Inventory, - Chat, -}; - -struct GlobalState { - static std::shared_ptr<GameState> GetGameState(); - static Render *GetRender(); - static void Exec(); - static State GetState(); - static void SetState(const State &newState); -};
\ No newline at end of file diff --git a/src/Plugin.cpp b/src/Plugin.cpp new file mode 100644 index 0000000..8d2de94 --- /dev/null +++ b/src/Plugin.cpp @@ -0,0 +1,261 @@ +#include "Plugin.hpp" + +#include <vector> + +#include <easylogging++.h> +#include <sol.hpp> +#include <optick.h> + +#include "GameState.hpp" +#include "Game.hpp" +#include "Event.hpp" +#include "AssetManager.hpp" + + +struct Plugin { + int errors; + const std::string name; + const std::string displayName; + const std::function<void()> onLoad; + const std::function<void()> onUnload; + const std::function<void(std::string)> onChangeState; + const std::function<void(double)> onTick; + const std::function<BlockInfo(Vector)> onRequestBlockInfo; +}; + + +std::vector<Plugin> plugins; +sol::state lua; + + +namespace PluginApi { + + void RegisterPlugin(sol::table plugin) { + Plugin nativePlugin { + 0, + plugin["name"].get_or<std::string>(""), + plugin["displayName"].get_or<std::string>(""), + plugin["onLoad"].get_or(std::function<void()>()), + plugin["onUnload"].get_or(std::function<void()>()), + plugin["onChangeState"].get_or(std::function<void(std::string)>()), + plugin["onTick"].get_or(std::function<void(double)>()), + plugin["onRequestBlockInfo"].get_or(std::function<BlockInfo(Vector)>()), + }; + plugins.push_back(nativePlugin); + nativePlugin.onLoad(); + + LOG(INFO) << "Loaded plugin " << (!nativePlugin.displayName.empty() ? nativePlugin.displayName : nativePlugin.name); + } + + void LogWarning(std::string text) { + LOG(WARNING) << text; + } + + void LogInfo(std::string text) { + LOG(INFO) << text; + } + + void LogError(std::string text) { + LOG(ERROR) << text; + } + + GameState *GetGameState() { + return ::GetGameState(); + } + + void RegisterBlock(BlockId blockId, bool collides, std::string blockstate, std::string variant) { + RegisterStaticBlockInfo(blockId, BlockInfo{ + collides, + blockstate, + variant + }); + } +} + +int LoadFileRequire(lua_State* L) { + std::string path = sol::stack::get<std::string>(L); + + std::string package = path.substr(0, path.find('/')); + std::string script = path.substr(path.find('/') + 1); + + std::string scriptPath = "/" + package + "/scripts/" + script; + + AssetScript *asset = AssetManager::GetAsset<AssetScript>(scriptPath); + if (!asset) { + sol::stack::push(L, "Module '" + scriptPath + "' not found"); + return 1; + } + + luaL_loadbuffer(L, asset->code.data(), asset->code.size(), path.c_str()); + return 1; +} + +void PluginSystem::Init() { + OPTICK_EVENT(); + LOG(INFO) << "Initializing plugin system"; + for (Plugin &plugin : plugins) { + if (plugin.onUnload && plugin.errors < 10) + plugin.onUnload(); + } + + plugins.clear(); + lua = sol::state(); + lua.open_libraries(); + + lua["package"]["searchers"] = lua.create_table_with( + 1, LoadFileRequire + ); + + lua.new_usertype<Entity>("Entity", + "pos", &Entity::pos); + + lua.new_usertype<GameState>("GameState", + "GetPlayer", &GameState::GetPlayer, + "GetWorld", &GameState::GetWorld, + "GetTimeStatus", &GameState::GetTimeStatus, + "GetGameStatus", &GameState::GetGameStatus, + "GetPlayerStatus", &GameState::GetPlayerStatus, + "GetSelectionStatus", &GameState::GetSelectionStatus, + "GetInventory", &GameState::GetInventory); + + lua.new_usertype<TimeStatus>("TimeStatus", + "interpolatedTimeOfDay", &TimeStatus::interpolatedTimeOfDay, + "worldAge", &TimeStatus::worldAge, + "timeOfDay", &TimeStatus::timeOfDay, + "doDaylightCycle", &TimeStatus::doDaylightCycle); + + lua.new_usertype<GameStatus>("GameStatus", + "levelType", &GameStatus::levelType, + "spawnPosition", &GameStatus::spawnPosition, + "gamemode", &GameStatus::gamemode, + "dimension", &GameStatus::dimension, + "difficulty", &GameStatus::difficulty, + "maxPlayers", &GameStatus::maxPlayers, + "isGameStarted", &GameStatus::isGameStarted, + "reducedDebugInfo", &GameStatus::reducedDebugInfo); + + lua.new_usertype<SelectionStatus>("SelectionStatus", + "raycastHit", &SelectionStatus::raycastHit, + "selectedBlock", &SelectionStatus::selectedBlock, + "distanceToSelectedBlock", &SelectionStatus::distanceToSelectedBlock, + "isBlockSelected", &SelectionStatus::isBlockSelected); + + lua.new_usertype<PlayerStatus>("PlayerStatus", + "uid", &PlayerStatus::uid, + "name", &PlayerStatus::name, + "flyingSpeed", &PlayerStatus::flyingSpeed, + "fovModifier", &PlayerStatus::fovModifier, + "health", &PlayerStatus::health, + "eid", &PlayerStatus::eid, + "invulnerable", &PlayerStatus::invulnerable, + "flying", &PlayerStatus::flying, + "allowFlying", &PlayerStatus::allowFlying, + "creativeMode", &PlayerStatus::creativeMode); + + lua.new_usertype<World>("World", + "GetEntitiesList", &World::GetEntitiesList, + "GetEntity",&World::GetEntityPtr, + "Raycast", &World::Raycast, + "GetBlockId", &World::GetBlockId, + "SetBlockId", &World::SetBlockId); + + auto bidFactory1 = []() { + return BlockId{ 0,0 }; + }; + auto bidFactory2 = [](unsigned short id, unsigned char state) { + return BlockId{ id,state }; + }; + + lua.new_usertype<BlockId>("BlockId", + "new", sol::factories([]() {return BlockId{ 0,0 };}, + [](unsigned short id, unsigned char state) {return BlockId{ id, state };}), + "id", sol::property( + [](BlockId & bid) { return bid.id; }, + [](BlockId & bid, unsigned short id) { bid.id = id; }), + "state", sol::property( + [](BlockId & bid) { return bid.state; }, + [](BlockId & bid, unsigned char state) { bid.state = state; })); + + lua.new_usertype<Vector>("Vector", + sol::constructors<Vector(),Vector(long long, long long, long long)>(), + "x", &Vector::x, + "y", &Vector::y, + "z", &Vector::z); + + lua.new_usertype<VectorF>("VectorF", + sol::constructors<VectorF(), VectorF(double, double, double)>(), + "x", &VectorF::x, + "y", &VectorF::y, + "z", &VectorF::z); + + lua.new_usertype<BlockInfo>("BlockInfo", + "collides", &BlockInfo::collides, + "blockstate", &BlockInfo::blockstate, + "variant", &BlockInfo::variant); + + sol::table apiTable = lua["AC"].get_or_create<sol::table>(); + + apiTable["RegisterPlugin"] = PluginApi::RegisterPlugin; + apiTable["LogWarning"] = PluginApi::LogWarning; + apiTable["LogInfo"] = PluginApi::LogInfo; + apiTable["LogError"] = PluginApi::LogError; + apiTable["GetGameState"] = PluginApi::GetGameState; + apiTable["RegisterBlock"] = PluginApi::RegisterBlock; +} + +void PluginSystem::Execute(const std::string &luaCode, bool except) { + OPTICK_EVENT(); + try { + lua.safe_script(luaCode); + } catch (sol::error &e) { + LOG(ERROR) << e.what(); + if (except) + throw; + } +} + +void PluginSystem::CallOnChangeState(std::string newState) { + OPTICK_EVENT(); + for (Plugin &plugin : plugins) { + if (plugin.onChangeState && plugin.errors < 10) + try { + plugin.onChangeState(newState); + } + catch (sol::error &e) { + LOG(ERROR) << e.what(); + plugin.errors++; + } + } +} + +void PluginSystem::CallOnTick(double deltaTime) { + OPTICK_EVENT(); + for (Plugin& plugin : plugins) { + if (plugin.onTick && plugin.errors < 10) + try { + plugin.onTick(deltaTime); + } + catch (sol::error &e) { + LOG(ERROR) << e.what(); + plugin.errors++; + } + } +} + +BlockInfo PluginSystem::RequestBlockInfo(Vector blockPos) { + OPTICK_EVENT(); + BlockInfo ret; + for (Plugin& plugin : plugins) { + if (plugin.onRequestBlockInfo && plugin.errors < 10) + try { + ret = plugin.onRequestBlockInfo(blockPos); + if (!ret.blockstate.empty()) + break; + } + catch (sol::error & e) { + LOG(ERROR) << e.what(); + plugin.errors++; + } + } + return ret; +} diff --git a/src/Plugin.hpp b/src/Plugin.hpp new file mode 100644 index 0000000..a849f5c --- /dev/null +++ b/src/Plugin.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include <string> + +#include "Vector.hpp" + +class BlockInfo; + +namespace PluginSystem { + void Init(); + + void Execute(const std::string &luaCode, bool except = false); + + void CallOnChangeState(std::string newState); + + void CallOnTick(double deltaTime); + + BlockInfo RequestBlockInfo(Vector blockPos); +}
\ No newline at end of file diff --git a/src/Render.cpp b/src/Render.cpp index cf108e4..128c877 100644 --- a/src/Render.cpp +++ b/src/Render.cpp @@ -2,22 +2,23 @@ #include <imgui.h> #include <easylogging++.h> +#include <optick.h> #include "imgui_impl_sdl_gl3.h" #include "Shader.hpp" #include "AssetManager.hpp" #include "Event.hpp" #include "DebugInfo.hpp" -#include "GlobalState.hpp" +#include "Game.hpp" #include "World.hpp" #include "GameState.hpp" #include "RendererWorld.hpp" #include "Settings.hpp" #include "Framebuffer.hpp" +#include "Plugin.hpp" Render::Render(unsigned int windowWidth, unsigned int windowHeight, - std::string windowTitle) - : timer(std::chrono::milliseconds(16)) { + std::string windowTitle) { InitEvents(); Settings::Load(); @@ -47,9 +48,9 @@ Render::Render(unsigned int windowWidth, unsigned int windowHeight, if (fieldSensetivity != sensetivity) sensetivity = fieldSensetivity; isWireframe = fieldWireframe; - timer.SetDelayLength(std::chrono::duration<double, std::milli>(1.0 / fieldTargetFps * 1000.0)); + GetTime()->SetDelayLength(std::chrono::duration<double, std::milli>(1.0 / fieldTargetFps * 1000.0)); if (fieldVsync) { - timer.SetDelayLength(std::chrono::milliseconds(0)); + GetTime()->SetDelayLength(std::chrono::milliseconds(0)); SDL_GL_SetSwapInterval(1); } else @@ -71,7 +72,9 @@ Render::~Render() { Settings::WriteDouble("brightness", fieldBrightness); Settings::WriteDouble("resolutionScale", fieldResolutionScale); Settings::Save(); - + + PluginSystem::Init(); + framebuffer.reset(); ImGui_ImplSdlGL3_Shutdown(); SDL_GL_DeleteContext(glContext); @@ -171,6 +174,7 @@ void Render::UpdateKeyboard() { } void Render::RenderFrame() { + OPTICK_EVENT(); framebuffer->Clear(); Framebuffer::GetDefault().Clear(); @@ -188,10 +192,12 @@ void Render::RenderFrame() { RenderGui(); if (world) { - world->Update(timer.RemainTimeMs()); + world->Update(GetTime()->RemainTimeMs()); } - SDL_GL_SwapWindow(window); + + OPTICK_EVENT("VSYNC"); + SDL_GL_SwapWindow(window); } void Render::HandleEvents() { @@ -225,11 +231,11 @@ void Render::HandleEvents() { case SDL_WINDOWEVENT_FOCUS_LOST: { HasFocus = false; - auto state = GlobalState::GetState(); + State state = GetState(); if (state == State::Inventory || state == State::Playing || state == State::Chat) { - GlobalState::SetState(State::Paused); + SetState(State::Paused); } break; } @@ -241,13 +247,13 @@ void Render::HandleEvents() { case SDL_KEYDOWN: { switch (event.key.keysym.scancode) { case SDL_SCANCODE_ESCAPE: { - auto state = GlobalState::GetState(); + auto state = GetState(); if (state == State::Playing) { - GlobalState::SetState(State::Paused); + SetState(State::Paused); } else if (state == State::Paused || state == State::Inventory || state == State::Chat) { - GlobalState::SetState(State::Playing); + SetState(State::Playing); } else if (state == State::MainMenu) { LOG(INFO) << "Received close event by esc"; PUSH_EVENT("Exit", 0); @@ -257,11 +263,11 @@ void Render::HandleEvents() { } case SDL_SCANCODE_E: { - auto state = GlobalState::GetState(); + auto state = GetState(); if (state == State::Playing) { - GlobalState::SetState(State::Inventory); + SetState(State::Inventory); } else if (state == State::Inventory) { - GlobalState::SetState(State::Playing); + SetState(State::Playing); } break; @@ -270,11 +276,11 @@ void Render::HandleEvents() { case SDL_SCANCODE_SLASH: case SDL_SCANCODE_T: { if (!ImGui::GetIO().WantCaptureKeyboard) { - auto state = GlobalState::GetState(); + auto state = GetState(); if (state == State::Playing) { - GlobalState::SetState(State::Chat); + SetState(State::Chat); } else if (state == State::Chat) { - GlobalState::SetState(State::Playing); + SetState(State::Playing); } } @@ -348,20 +354,18 @@ void Render::SetMouseCapture(bool IsCaptured) { } void Render::Update() { - if (world) - world->UpdateGameState(GlobalState::GetGameState()); - + OPTICK_EVENT(); HandleEvents(); - if (HasFocus && GlobalState::GetState() == State::Playing) UpdateKeyboard(); + if (HasFocus && GetState() == State::Playing) UpdateKeyboard(); if (isMouseCaptured) HandleMouseCapture(); glCheckError(); RenderFrame(); listener.HandleAllEvents(); - timer.Update(); } void Render::RenderGui() { + OPTICK_EVENT(); ImGui_ImplSdlGL3_NewFrame(window); if (isMouseCaptured) { @@ -385,9 +389,9 @@ void Render::RenderGui() { ImGui::Text("FPS: %.1f (%.3fms)", ImGui::GetIO().Framerate, 1000.0f / ImGui::GetIO().Framerate); float gameTime = DebugInfo::gameThreadTime / 100.0f; if (world) { - Entity *playerPtr = world->GameStatePtr()->GetPlayer(); - SelectionStatus selectionStatus = world->GameStatePtr()->GetSelectionStatus(); - const World *worldPtr = &world->GameStatePtr()->GetWorld(); + Entity *playerPtr = GetGameState()->GetPlayer(); + SelectionStatus selectionStatus = GetGameState()->GetSelectionStatus(); + const World *worldPtr = &GetGameState()->GetWorld(); ImGui::Text("TPS: %.1f (%.2fms)", 1000.0f / gameTime, gameTime); ImGui::Text("Sections loaded: %d", (int) DebugInfo::totalSections); @@ -428,7 +432,7 @@ void Render::RenderGui() { ImGui::Text( "Player health: %.1f/%.1f", - world->GameStatePtr()->GetPlayerStatus().health, 20.0f); + GetGameState()->GetPlayerStatus().health, 20.0f); ImGui::Text( "Selected block: %d %d %d : %.1f", @@ -447,13 +451,13 @@ void Render::RenderGui() { AssetManager::GetAssetNameByBlockId(BlockId{ worldPtr->GetBlockId(selectionStatus.selectedBlock).id,0 }).c_str()); ImGui::Text("Selected block variant: %s:%s", - TransformBlockIdToBlockStateName(worldPtr->GetBlockId(selectionStatus.selectedBlock)).first.c_str(), - TransformBlockIdToBlockStateName(worldPtr->GetBlockId(selectionStatus.selectedBlock)).second.c_str()); + GetBlockInfo(worldPtr->GetBlockId(selectionStatus.selectedBlock)).blockstate.c_str(), + GetBlockInfo(worldPtr->GetBlockId(selectionStatus.selectedBlock)).variant.c_str()); } ImGui::End(); - switch (GlobalState::GetState()) { + switch (GetState()) { case State::MainMenu: { ImGui::SetNextWindowPosCenter(); ImGui::Begin("Menu", 0, windowFlags); @@ -510,7 +514,7 @@ void Render::RenderGui() { }; ImGui::SetNextWindowPosCenter(); ImGui::Begin("Inventory", 0, windowFlags); - const Window& inventory = world->GameStatePtr()->GetInventory(); + const Window& inventory = GetGameState()->GetInventory(); //Hand and drop slots if (renderSlot(inventory.handSlot, -1)) { @@ -597,7 +601,7 @@ void Render::RenderGui() { ImGui::SetNextWindowPosCenter(); ImGui::Begin("Pause Menu", 0, windowFlags); if (ImGui::Button("Continue")) { - GlobalState::SetState(State::Playing); + SetState(State::Playing); } ImGui::Separator(); @@ -626,12 +630,12 @@ void Render::RenderGui() { if (fieldSensetivity != sensetivity) sensetivity = fieldSensetivity; - world->GameStatePtr()->GetPlayer()->isFlying = fieldFlight; + GetGameState()->GetPlayer()->isFlying = fieldFlight; isWireframe = fieldWireframe; - timer.SetDelayLength(std::chrono::duration<double, std::milli>(1.0 / fieldTargetFps * 1000.0)); + GetTime()->SetDelayLength(std::chrono::duration<double, std::milli>(1.0 / fieldTargetFps * 1000.0)); if (fieldVsync) { - timer.SetDelayLength(std::chrono::milliseconds(0)); + GetTime()->SetDelayLength(std::chrono::milliseconds(0)); SDL_GL_SetSwapInterval(1); } else SDL_GL_SetSwapInterval(0); @@ -672,7 +676,7 @@ void Render::InitEvents() { listener.RegisterHandler("PlayerConnected", [this](const Event&) { stateString = "Loading terrain..."; - world = std::make_unique<RendererWorld>(GlobalState::GetGameState()); + world = std::make_unique<RendererWorld>(); world->MaxRenderingDistance = fieldDistance; PUSH_EVENT("UpdateSectionsRender", 0); }); @@ -680,9 +684,9 @@ void Render::InitEvents() { listener.RegisterHandler("RemoveLoadingScreen", [this](const Event&) { stateString = "Playing"; renderWorld = true; - GlobalState::SetState(State::Playing); + SetState(State::Playing); glClearColor(0, 0, 0, 1.0f); - world->GameStatePtr()->GetPlayer()->isFlying = this->fieldFlight; + GetGameState()->GetPlayer()->isFlying = this->fieldFlight; PUSH_EVENT("SetMinLightLevel", fieldBrightness); }); @@ -690,7 +694,7 @@ void Render::InitEvents() { stateString = "Connection failed: " + eventData.get <std::string>(); renderWorld = false; world.reset(); - GlobalState::SetState(State::MainMenu); + SetState(State::MainMenu); glClearColor(0.8, 0.8, 0.8, 1.0f); }); @@ -698,13 +702,13 @@ void Render::InitEvents() { stateString = "Disconnected: " + eventData.get<std::string>(); renderWorld = false; world.reset(); - GlobalState::SetState(State::MainMenu); + SetState(State::MainMenu); glClearColor(0.8, 0.8, 0.8, 1.0f); }); listener.RegisterHandler("Connecting", [this](const Event&) { stateString = "Connecting to the server..."; - GlobalState::SetState(State::Loading); + SetState(State::Loading); }); listener.RegisterHandler("ChatMessageReceived", [this](const Event& eventData) { @@ -714,16 +718,33 @@ void Render::InitEvents() { }); listener.RegisterHandler("StateUpdated", [this](const Event& eventData) { - switch (GlobalState::GetState()) { + switch (GetState()) { case State::Playing: SetMouseCapture(true); + PluginSystem::CallOnChangeState("Playing"); break; case State::InitialLoading: + PluginSystem::CallOnChangeState("InitialLoading"); + SetMouseCapture(false); + break; case State::MainMenu: + PluginSystem::CallOnChangeState("MainMenu"); + SetMouseCapture(false); + break; case State::Loading: + PluginSystem::CallOnChangeState("Loading"); + SetMouseCapture(false); + break; case State::Paused: + PluginSystem::CallOnChangeState("Paused"); + SetMouseCapture(false); + break; case State::Inventory: + PluginSystem::CallOnChangeState("Inventory"); + SetMouseCapture(false); + break; case State::Chat: + PluginSystem::CallOnChangeState("Chat"); SetMouseCapture(false); break; } diff --git a/src/Render.hpp b/src/Render.hpp index eea5450..8e2e233 100644 --- a/src/Render.hpp +++ b/src/Render.hpp @@ -25,7 +25,6 @@ class Render { std::unique_ptr<RendererWorld> world; bool renderWorld = false; RenderState renderState; - LoopExecutionTimeController timer; std::map<SDL_Scancode, bool> isKeyPressed; bool HasFocus=true; float sensetivity = 0.1f; diff --git a/src/Renderer.cpp b/src/Renderer.cpp index 0db23db..947fd6f 100644 --- a/src/Renderer.cpp +++ b/src/Renderer.cpp @@ -1,6 +1,9 @@ #include "Renderer.hpp" +#include <optick.h> + void RenderState::SetActiveVao(GLuint Vao) { + OPTICK_EVENT(); glBindVertexArray(Vao); ActiveVao = Vao; } diff --git a/src/RendererEntity.cpp b/src/RendererEntity.cpp index 25403be..fcbf79a 100644 --- a/src/RendererEntity.cpp +++ b/src/RendererEntity.cpp @@ -2,12 +2,12 @@ #include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/type_ptr.hpp> +#include <optick.h> #include "Entity.hpp" #include "GameState.hpp" #include "Renderer.hpp" #include "AssetManager.hpp" -#include "GlobalState.hpp" const GLfloat vertices[] = { -0.5f, 0.5f, 0.5f, @@ -124,6 +124,7 @@ RendererEntity::~RendererEntity() { } void RendererEntity::Render(RenderState& renderState, const World *world) { + OPTICK_EVENT(); glm::mat4 model = glm::mat4(1.0); const Entity &entity = world->GetEntity(entityId); model = glm::translate(model, entity.pos.glm()); diff --git a/src/RendererSection.cpp b/src/RendererSection.cpp index 1521c6f..d797771 100644 --- a/src/RendererSection.cpp +++ b/src/RendererSection.cpp @@ -1,6 +1,7 @@ #include "RendererSection.hpp" #include <easylogging++.h> +#include <optick.h> #include "Utility.hpp" #include "Renderer.hpp" @@ -31,6 +32,7 @@ GLuint RendererSection::VboVertices = magicUniqueConstant; GLuint RendererSection::VboUvs = magicUniqueConstant; RendererSection::RendererSection(const RendererSectionData &data) { + OPTICK_EVENT(); if (VboVertices == magicUniqueConstant) { glGenBuffers(1, &VboVertices); glGenBuffers(1, &VboUvs); @@ -155,6 +157,7 @@ void swap(RendererSection & lhs, RendererSection & rhs) { } void RendererSection::Render(RenderState &renderState) { + OPTICK_EVENT(); renderState.SetActiveVao(Vao); glDrawArraysInstanced(GL_TRIANGLES, 0, 6, numOfFaces); glCheckError(); @@ -169,6 +172,7 @@ size_t RendererSection::GetHash() { } void RendererSection::UpdateData(const RendererSectionData & data) { + OPTICK_EVENT(); glBindBuffer(GL_ARRAY_BUFFER, Vbo[TEXTURES]); glBufferData(GL_ARRAY_BUFFER, data.textures.size() * sizeof(glm::vec4), data.textures.data(), GL_DYNAMIC_DRAW); diff --git a/src/RendererSectionData.cpp b/src/RendererSectionData.cpp index 3b51809..69ed665 100644 --- a/src/RendererSectionData.cpp +++ b/src/RendererSectionData.cpp @@ -3,6 +3,7 @@ #include <array> #include <glm/gtc/matrix_transform.hpp> +#include <optick.h> #include "World.hpp" @@ -101,8 +102,8 @@ std::array<BlockId, 4096> SetBlockIdData(const SectionsData §ions) { return blockIdData; } -RendererSectionData ParseSection(const SectionsData §ions) -{ +RendererSectionData ParseSection(const SectionsData §ions) { + OPTICK_EVENT(); RendererSectionData data; std::vector<std::pair<BlockId, BlockFaces*>> idModels; diff --git a/src/RendererSky.cpp b/src/RendererSky.cpp index d0e9518..1eab369 100644 --- a/src/RendererSky.cpp +++ b/src/RendererSky.cpp @@ -1,5 +1,7 @@ #include "RendererSky.hpp" +#include <optick.h> + #include "Renderer.hpp" #include "Utility.hpp" @@ -127,16 +129,15 @@ RendererSky::RendererSky() { glCheckError(); } -RendererSky::~RendererSky() -{ +RendererSky::~RendererSky() { glDeleteBuffers(1, &VboVert); glDeleteBuffers(1, &VboUv); glDeleteVertexArrays(1, &Vao); //glCheckError(); } -void RendererSky::Render(RenderState &renderState) -{ +void RendererSky::Render(RenderState &renderState) { + OPTICK_EVENT(); renderState.SetActiveVao(Vao); glDrawArrays(GL_TRIANGLES, 0, 36); glCheckError(); diff --git a/src/RendererWorld.cpp b/src/RendererWorld.cpp index 7f7c850..ebb049d 100644 --- a/src/RendererWorld.cpp +++ b/src/RendererWorld.cpp @@ -2,6 +2,7 @@ #include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/type_ptr.hpp> +#include <optick.h> #include "DebugInfo.hpp" #include "Frustum.hpp" @@ -12,11 +13,14 @@ #include "GameState.hpp" #include "Section.hpp" #include "RendererSectionData.hpp" +#include "Game.hpp" void RendererWorld::WorkerFunction(size_t workerId) { + OPTICK_THREAD("Worker"); EventListener tasksListener; tasksListener.RegisterHandler("ParseSection", [&](const Event &eventData) { + OPTICK_EVENT("EV_ParseSection"); auto data = eventData.get<std::tuple<size_t, size_t, bool>>(); if (std::get<0>(data) != workerId) return; @@ -36,6 +40,7 @@ void RendererWorld::WorkerFunction(size_t workerId) { } void RendererWorld::ParseQueueUpdate() { + OPTICK_EVENT(); while (!parseQueue.empty()) { size_t id = 0; for (; id < RendererWorld::parsingBufferSize && parsing[id].parsing; ++id) {} @@ -52,13 +57,13 @@ void RendererWorld::ParseQueueUpdate() { vec.y -= 4500; } - parsing[id].data.section = gs->GetWorld().GetSection(vec); - parsing[id].data.north = gs->GetWorld().GetSection(vec + Vector(0, 0, 1)); - parsing[id].data.south = gs->GetWorld().GetSection(vec + Vector(0, 0, -1)); - parsing[id].data.west = gs->GetWorld().GetSection(vec + Vector(1, 0, 0)); - parsing[id].data.east = gs->GetWorld().GetSection(vec + Vector(-1, 0, 0)); - parsing[id].data.bottom = gs->GetWorld().GetSection(vec + Vector(0, -1, 0)); - parsing[id].data.top = gs->GetWorld().GetSection(vec + Vector(0, 1, 0)); + parsing[id].data.section = GetGameState()->GetWorld().GetSection(vec); + parsing[id].data.north = GetGameState()->GetWorld().GetSection(vec + Vector(0, 0, 1)); + parsing[id].data.south = GetGameState()->GetWorld().GetSection(vec + Vector(0, 0, -1)); + parsing[id].data.west = GetGameState()->GetWorld().GetSection(vec + Vector(1, 0, 0)); + parsing[id].data.east = GetGameState()->GetWorld().GetSection(vec + Vector(-1, 0, 0)); + parsing[id].data.bottom = GetGameState()->GetWorld().GetSection(vec + Vector(0, -1, 0)); + parsing[id].data.top = GetGameState()->GetWorld().GetSection(vec + Vector(0, 1, 0)); parsing[id].parsing = true; @@ -69,6 +74,7 @@ void RendererWorld::ParseQueueUpdate() { } void RendererWorld::ParseQeueueRemoveUnnecessary() { + OPTICK_EVENT(); size_t size = parseQueue.size(); static std::vector<Vector> elements; elements.clear(); @@ -86,7 +92,7 @@ void RendererWorld::ParseQeueueRemoveUnnecessary() { if (std::find(elements.begin(), elements.end(), vec) != elements.end()) continue; - const Section& section = gs->GetWorld().GetSection(vec); + const Section& section = GetGameState()->GetWorld().GetSection(vec); bool skip = false; @@ -112,10 +118,11 @@ void RendererWorld::ParseQeueueRemoveUnnecessary() { } void RendererWorld::UpdateAllSections(VectorF playerPos) { - Vector playerChunk(std::floor(gs->GetPlayer()->pos.x / 16), 0, std::floor(gs->GetPlayer()->pos.z / 16)); + OPTICK_EVENT(); + Vector playerChunk(std::floor(GetGameState()->GetPlayer()->pos.x / 16), 0, std::floor(GetGameState()->GetPlayer()->pos.z / 16)); std::vector<Vector> suitableChunks; - auto chunks = gs->GetWorld().GetSectionsList(); + auto chunks = GetGameState()->GetWorld().GetSectionsList(); for (auto& it : chunks) { double distance = (Vector(it.x, 0, it.z) - playerChunk).GetLength(); if (distance > MaxRenderingDistance) @@ -134,7 +141,7 @@ void RendererWorld::UpdateAllSections(VectorF playerPos) { PUSH_EVENT("DeleteSectionRender", it); } - playerChunk.y = std::floor(gs->GetPlayer()->pos.y / 16.0); + playerChunk.y = std::floor(GetGameState()->GetPlayer()->pos.y / 16.0); std::sort(suitableChunks.begin(), suitableChunks.end(), [playerChunk](Vector lhs, Vector rhs) { double leftLengthToPlayer = (playerChunk - lhs).GetLength(); double rightLengthToPlayer = (playerChunk - rhs).GetLength(); @@ -146,8 +153,8 @@ void RendererWorld::UpdateAllSections(VectorF playerPos) { } } -RendererWorld::RendererWorld(std::shared_ptr<GameState> ptr) { - gs = ptr; +RendererWorld::RendererWorld() { + OPTICK_EVENT(); MaxRenderingDistance = 2; numOfWorkers = _max(1, (signed int) std::thread::hardware_concurrency() - 2); @@ -158,6 +165,7 @@ RendererWorld::RendererWorld(std::shared_ptr<GameState> ptr) { PrepareRender(); listener->RegisterHandler("DeleteSectionRender", [this](const Event& eventData) { + OPTICK_EVENT("EV_DeleteSectionRender"); auto vec = eventData.get<Vector>(); auto it = sections.find(vec); if (it == sections.end()) @@ -166,6 +174,7 @@ RendererWorld::RendererWorld(std::shared_ptr<GameState> ptr) { }); listener->RegisterHandler("SectionParsed",[this](const Event &eventData) { + OPTICK_EVENT("EV_SectionParsed"); auto id = eventData.get<size_t>(); parsing[id].parsing = false; @@ -185,8 +194,9 @@ RendererWorld::RendererWorld(std::shared_ptr<GameState> ptr) { }); listener->RegisterHandler("EntityChanged", [this](const Event& eventData) { + OPTICK_EVENT("EV_EntityChanged"); auto data = eventData.get<unsigned int>(); - for (unsigned int entityId : gs->GetWorld().GetEntitiesList()) { + for (unsigned int entityId : GetGameState()->GetWorld().GetEntitiesList()) { if (entityId == data) { entities.push_back(RendererEntity(entityId)); } @@ -194,11 +204,12 @@ RendererWorld::RendererWorld(std::shared_ptr<GameState> ptr) { }); listener->RegisterHandler("ChunkChanged", [this](const Event& eventData) { + OPTICK_EVENT("EV_ChunkChanged"); auto vec = eventData.get<Vector>(); if (vec == Vector()) return; - Vector playerChunk(std::floor(gs->GetPlayer()->pos.x / 16), 0, std::floor(gs->GetPlayer()->pos.z / 16)); + Vector playerChunk(std::floor(GetGameState()->GetPlayer()->pos.x / 16), 0, std::floor(GetGameState()->GetPlayer()->pos.z / 16)); double distanceToChunk = (Vector(vec.x, 0, vec.z) - playerChunk).GetLength(); if (MaxRenderingDistance != 1000 && distanceToChunk > MaxRenderingDistance) { @@ -211,11 +222,12 @@ RendererWorld::RendererWorld(std::shared_ptr<GameState> ptr) { }); listener->RegisterHandler("ChunkChangedForce", [this](const Event& eventData) { + OPTICK_EVENT("EV_ChunkChangedForce"); auto vec = eventData.get<Vector>(); if (vec == Vector()) return; - Vector playerChunk(std::floor(gs->GetPlayer()->pos.x / 16), 0, std::floor(gs->GetPlayer()->pos.z / 16)); + Vector playerChunk(std::floor(GetGameState()->GetPlayer()->pos.x / 16), 0, std::floor(GetGameState()->GetPlayer()->pos.z / 16)); double distanceToChunk = (Vector(vec.x, 0, vec.z) - playerChunk).GetLength(); if (MaxRenderingDistance != 1000 && distanceToChunk > MaxRenderingDistance) { @@ -230,7 +242,7 @@ RendererWorld::RendererWorld(std::shared_ptr<GameState> ptr) { }); listener->RegisterHandler("UpdateSectionsRender", [this](const Event&) { - UpdateAllSections(gs->GetPlayer()->pos); + UpdateAllSections(GetGameState()->GetPlayer()->pos); }); listener->RegisterHandler("PlayerPosChanged", [this](const Event& eventData) { @@ -271,12 +283,13 @@ RendererWorld::~RendererWorld() { } void RendererWorld::Render(RenderState & renderState) { + OPTICK_EVENT(); //Common glm::mat4 projection = glm::perspective( glm::radians(70.0f), (float) renderState.WindowWidth / (float) renderState.WindowHeight, 0.1f, 10000000.0f ); - glm::mat4 view = gs->GetViewMatrix(); + glm::mat4 view = GetGameState()->GetViewMatrix(); glm::mat4 projView = projection * view; //Render Entities @@ -286,14 +299,14 @@ void RendererWorld::Render(RenderState & renderState) { entityShader->SetUniform("projection", projection); entityShader->SetUniform("view", view); glCheckError(); - + renderState.SetActiveVao(RendererEntity::GetVao()); for (auto& it : entities) { - it.Render(renderState, &gs->GetWorld()); + it.Render(renderState, &GetGameState()->GetWorld()); } //Render selected block - Vector selectedBlock = gs->GetSelectionStatus().selectedBlock; + Vector selectedBlock = GetGameState()->GetSelectionStatus().selectedBlock; if (selectedBlock != Vector()) { glLineWidth(2.0f); { @@ -311,7 +324,7 @@ void RendererWorld::Render(RenderState & renderState) { //Render raycast hit const bool renderHit = false; if (renderHit) { - VectorF hit = gs->GetSelectionStatus().raycastHit; + VectorF hit = GetGameState()->GetSelectionStatus().raycastHit; glLineWidth(2.0f); { glm::mat4 model; @@ -331,16 +344,16 @@ void RendererWorld::Render(RenderState & renderState) { glCheckError(); //Render sky - renderState.TimeOfDay = gs->GetTimeStatus().timeOfDay; + renderState.TimeOfDay = GetGameState()->GetTimeStatus().timeOfDay; Shader *skyShader = AssetManager::GetAsset<AssetShader>("/altcraft/shaders/sky")->shader.get(); skyShader->Activate(); skyShader->SetUniform("projection", projection); skyShader->SetUniform("view", view); glm::mat4 model = glm::mat4(1.0); - model = glm::translate(model, gs->GetPlayer()->pos.glm()); + model = glm::translate(model, GetGameState()->GetPlayer()->pos.glm()); const float scale = 1000000.0f; model = glm::scale(model, glm::vec3(scale, scale, scale)); - float shift = gs->GetTimeStatus().interpolatedTimeOfDay / 24000.0f; + float shift = GetGameState()->GetTimeStatus().interpolatedTimeOfDay / 24000.0f; if (shift < 0) shift *= -1.0f; model = glm::rotate(model, glm::radians(90.0f), glm::vec3(0, 1.0f, 0.0f)); @@ -357,7 +370,7 @@ void RendererWorld::Render(RenderState & renderState) { const float moonriseLength = moonriseMax - moonriseMin; float mixLevel = 0; - float dayTime = gs->GetTimeStatus().interpolatedTimeOfDay; + float dayTime = GetGameState()->GetTimeStatus().interpolatedTimeOfDay; if (dayTime < 0) dayTime *= -1; while (dayTime > 24000) @@ -434,6 +447,7 @@ void RendererWorld::PrepareRender() { } void RendererWorld::Update(double timeToUpdate) { + OPTICK_EVENT(); static auto timeSincePreviousUpdate = std::chrono::steady_clock::now(); if (parseQueueNeedRemoveUnnecessary) @@ -451,7 +465,3 @@ void RendererWorld::Update(double timeToUpdate) { DebugInfo::readyRenderer = parseQueue.size(); DebugInfo::renderSections = sections.size(); } - -GameState* RendererWorld::GameStatePtr() { - return gs.get(); -} diff --git a/src/RendererWorld.hpp b/src/RendererWorld.hpp index 913e510..d031179 100644 --- a/src/RendererWorld.hpp +++ b/src/RendererWorld.hpp @@ -27,7 +27,6 @@ class RendererWorld { }; //General - std::shared_ptr<GameState> gs; std::unique_ptr<EventListener> listener; size_t numOfWorkers; size_t currentWorker = 0; @@ -51,7 +50,7 @@ class RendererWorld { Texture *skyTexture; RendererSky rendererSky; public: - RendererWorld(std::shared_ptr<GameState> ptr); + RendererWorld(); ~RendererWorld(); void Render(RenderState& renderState); @@ -61,11 +60,5 @@ public: void Update(double timeToUpdate); - GameState *GameStatePtr(); - int culledSections = 0; - - inline void UpdateGameState(std::shared_ptr<GameState> newPtr) { - gs = newPtr; - } };
\ No newline at end of file diff --git a/src/Utility.cpp b/src/Utility.cpp index 848ee02..09696fd 100644 --- a/src/Utility.cpp +++ b/src/Utility.cpp @@ -2,9 +2,11 @@ #include <thread> +#include <optick.h> #include <easylogging++.h> GLenum glCheckError_(const char *file, int line) { + OPTICK_EVENT(); GLenum errorCode; while ((errorCode = glGetError()) != GL_NO_ERROR) { std::string error; diff --git a/src/World.cpp b/src/World.cpp index da0a33b..00a1a19 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -2,6 +2,7 @@ #include <bitset> #include <glm/glm.hpp> +#include <optick.h> #include "Event.hpp" #include "DebugInfo.hpp" @@ -97,7 +98,7 @@ bool World::isPlayerCollides(double X, double Y, double Z) const { for (int y = 0; y < 16; y++) { for (int z = 0; z < 16; z++) { BlockId block = section.GetBlockId(Vector(x, y, z)); - if (block.id == 0 || block.id == 31 || block.id == 37 || block.id == 38 || block.id == 175) + if (!GetBlockInfo(block).collides) continue; AABB blockColl{ (x + it.x * 16.0), (y + it.y * 16.0), @@ -131,6 +132,7 @@ const Section &World::GetSection(Vector sectionPos) const { // TODO: skip liquid blocks RaycastResult World::Raycast(glm::vec3 position, glm::vec3 direction) const { + OPTICK_EVENT(); const float maxLen = 5.0; const float step = 0.01; glm::vec3 pos = glm::vec3(0.0); @@ -150,6 +152,7 @@ RaycastResult World::Raycast(glm::vec3 position, glm::vec3 direction) const { } void World::UpdatePhysics(float delta) { + OPTICK_EVENT(); struct CollisionResult { bool isCollide; //Vector block; @@ -158,6 +161,7 @@ void World::UpdatePhysics(float delta) { }; auto testCollision = [this](double width, double height, VectorF pos)->CollisionResult { + OPTICK_EVENT("testCollision"); int blockXBegin = pos.x - width - 1.0; int blockXEnd = pos.x + width + 0.5; int blockYBegin = pos.y - 0.5; @@ -177,9 +181,10 @@ void World::UpdatePhysics(float delta) { for (int y = blockYBegin; y <= blockYEnd; y++) { for (int z = blockZBegin; z <= blockZEnd; z++) { for (int x = blockXBegin; x <= blockXEnd; x++) { + OPTICK_EVENT("testCollision"); BlockId block = this->GetBlockId(Vector(x, y, z)); - if (block.id == 0 || block.id == 31 || block.id == 37 || block.id == 38 || block.id == 175 || block.id == 78) - continue; + if (block.id == 0 || !GetBlockInfo(block).collides) + continue; AABB blockColl{ x,y,z,1.0,1.0,1.0 }; if (TestCollision(entityCollBox, blockColl)) { return { true }; @@ -191,6 +196,7 @@ void World::UpdatePhysics(float delta) { }; for (auto& it : entities) { + OPTICK_EVENT("Foreach entities"); if (it.isFlying) { VectorF newPos = it.pos + VectorF(it.vel.x, it.vel.y, it.vel.z) * delta; auto coll = testCollision(it.width, it.height, newPos); diff --git a/src/main.cpp b/src/main.cpp index cb2daa8..2ed2b85 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,6 @@ #include "Event.hpp" #include "Utility.hpp" -#include "GlobalState.hpp" +#include "Game.hpp" #include <set> @@ -48,7 +48,7 @@ int main(int argc, char** argv) { return -1; } - GlobalState::Exec(); + RunGame(); return 0; }
\ No newline at end of file |