├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── LICENSE ├── MinecraftC ├── ChatLine.c ├── ChatLine.h ├── Entity.c ├── Entity.h ├── GUI │ ├── BlockSelectScreen.c │ ├── BlockSelectScreen.h │ ├── Button.c │ ├── Button.h │ ├── ChatInputScreen.c │ ├── ChatInputScreen.h │ ├── ControlsScreen.c │ ├── ControlsScreen.h │ ├── ErrorScreen.c │ ├── ErrorScreen.h │ ├── FontRenderer.c │ ├── FontRenderer.h │ ├── GUIScreen.c │ ├── GUIScreen.h │ ├── GenerateLevelScreen.c │ ├── GenerateLevelScreen.h │ ├── HUDScreen.c │ ├── HUDScreen.h │ ├── LevelNameScreen.c │ ├── LevelNameScreen.h │ ├── LoadLevelScreen.c │ ├── LoadLevelScreen.h │ ├── ModsScreen.c │ ├── ModsScreen.h │ ├── OptionsScreen.c │ ├── OptionsScreen.h │ ├── PauseScreen.c │ ├── PauseScreen.h │ ├── SaveLevelScreen.c │ ├── SaveLevelScreen.h │ ├── Screen.c │ └── Screen.h ├── GameSettings.c ├── GameSettings.h ├── Level │ ├── Generator │ │ ├── LevelGenerator.c │ │ ├── LevelGenerator.h │ │ └── Noise │ │ │ ├── CombinedNoise.c │ │ │ ├── CombinedNoise.h │ │ │ ├── Noise.c │ │ │ ├── Noise.h │ │ │ ├── OctaveNoise.c │ │ │ ├── OctaveNoise.h │ │ │ ├── PerlinNoise.c │ │ │ └── PerlinNoise.h │ ├── Level.c │ ├── Level.h │ ├── NextTickListEntry.h │ └── Tile │ │ ├── Block.c │ │ ├── Block.h │ │ ├── BookshelfBlock.c │ │ ├── BookshelfBlock.h │ │ ├── FlowerBlock.c │ │ ├── FlowerBlock.h │ │ ├── GlassBlock.c │ │ ├── GlassBlock.h │ │ ├── GrassBlock.c │ │ ├── GrassBlock.h │ │ ├── LeavesBlock.c │ │ ├── LeavesBlock.h │ │ ├── LiquidBlock.c │ │ ├── LiquidBlock.h │ │ ├── LogBlock.c │ │ ├── LogBlock.h │ │ ├── MetalBlock.c │ │ ├── MetalBlock.h │ │ ├── MushroomBlock.c │ │ ├── MushroomBlock.h │ │ ├── SandBlock.c │ │ ├── SandBlock.h │ │ ├── SaplingBlock.c │ │ ├── SaplingBlock.h │ │ ├── SlabBlock.c │ │ ├── SlabBlock.h │ │ ├── SpongeBlock.c │ │ ├── SpongeBlock.h │ │ ├── StillLiquidBlock.c │ │ ├── StillLiquidBlock.h │ │ ├── TNTBlock.c │ │ ├── TNTBlock.h │ │ ├── TileSound.c │ │ └── TileSound.h ├── Minecraft.c ├── Minecraft.h ├── Mods │ ├── Matrix.h │ ├── PrimedTNT.c │ ├── PrimedTNT.h │ ├── Raytracer.c │ └── Raytracer.h ├── MovingObjectPosition.h ├── Particle │ ├── Particle.c │ ├── Particle.h │ ├── ParticleManager.c │ ├── ParticleManager.h │ ├── SmokeParticle.c │ ├── SmokeParticle.h │ ├── TerrainParticle.c │ ├── TerrainParticle.h │ ├── WaterDropParticle.c │ └── WaterDropParticle.h ├── Physics │ ├── AABB.c │ ├── AABB.h │ └── Vector3D.h ├── Player │ ├── InputHandler.c │ ├── InputHandler.h │ ├── Inventory.c │ ├── Inventory.h │ ├── Player.c │ ├── Player.h │ ├── PlayerAI.c │ └── PlayerAI.h ├── ProgressBarDisplay.c ├── ProgressBarDisplay.h ├── Render │ ├── Chunk.c │ ├── Chunk.h │ ├── Frustum.c │ ├── Frustum.h │ ├── HeldBlock.h │ ├── LevelRenderer.c │ ├── LevelRenderer.h │ ├── Renderer.c │ ├── Renderer.h │ ├── ShapeRenderer.c │ ├── ShapeRenderer.h │ ├── Texture │ │ ├── AnimatedTexture.c │ │ ├── AnimatedTexture.h │ │ ├── LavaTexture.c │ │ ├── LavaTexture.h │ │ ├── WaterTexture.c │ │ └── WaterTexture.h │ ├── TextureManager.c │ └── TextureManager.h ├── SessionData.c ├── SessionData.h ├── Sound │ ├── SoundManager.c │ └── SoundManager.h ├── Timer.c ├── Timer.h └── Utilities │ ├── List.c │ ├── List.h │ ├── Log.c │ ├── Log.h │ ├── OpenCL.h │ ├── OpenGL.h │ ├── Random.c │ ├── Random.h │ ├── SinTable.c │ ├── SinTable.h │ ├── String.c │ ├── String.h │ └── Time.h ├── README.md ├── Resources ├── App │ ├── AppIcon.icns │ ├── AppIcon.ico │ └── AppIcon.rc ├── Clouds.h ├── Clouds.png ├── Default.h ├── Default.png ├── Dirt.h ├── Dirt.png ├── GUI │ ├── GUI.h │ ├── GUI.png │ ├── Icons.h │ └── Icons.png ├── Music │ ├── Calm1.h │ ├── Calm1.ogg │ ├── Calm2.h │ ├── Calm2.ogg │ ├── Calm3.h │ └── Calm3.ogg ├── Particles.h ├── Particles.png ├── Rain.h ├── Rain.png ├── Rock.h ├── Rock.png ├── Shaders │ ├── DistanceField.cl │ ├── DistanceField.h │ ├── Raytracer.cl │ └── Raytracer.h ├── Sound │ └── Step │ │ ├── Grass1.h │ │ ├── Grass1.ogg │ │ ├── Grass2.h │ │ ├── Grass2.ogg │ │ ├── Grass3.h │ │ ├── Grass3.ogg │ │ ├── Grass4.h │ │ ├── Grass4.ogg │ │ ├── Gravel1.h │ │ ├── Gravel1.ogg │ │ ├── Gravel2.h │ │ ├── Gravel2.ogg │ │ ├── Gravel3.h │ │ ├── Gravel3.ogg │ │ ├── Gravel4.h │ │ ├── Gravel4.ogg │ │ ├── Stone1.h │ │ ├── Stone1.ogg │ │ ├── Stone2.h │ │ ├── Stone2.ogg │ │ ├── Stone3.h │ │ ├── Stone3.ogg │ │ ├── Stone4.h │ │ ├── Stone4.ogg │ │ ├── Wood1.h │ │ ├── Wood1.ogg │ │ ├── Wood2.h │ │ ├── Wood2.ogg │ │ ├── Wood3.h │ │ ├── Wood3.ogg │ │ ├── Wood4.h │ │ └── Wood4.ogg ├── Terrain.h ├── Terrain.png ├── Water.h └── Water.png ├── SDL2.cmake └── Scripts ├── EmbedResources.py └── MacOS-App.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | Build/* -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "External/SDL"] 2 | path = External/SDL 3 | url = https://github.com/libsdl-org/SDL.git 4 | [submodule "External/OpenCL-Headers"] 5 | path = External/OpenCL-Headers 6 | url = https://github.com/KhronosGroup/OpenCL-Headers 7 | [submodule "External/OpenCL-ICD-Loader"] 8 | path = External/OpenCL-ICD-Loader 9 | url = https://github.com/KhronosGroup/OpenCL-ICD-Loader 10 | [submodule "External/stb"] 11 | path = External/stb 12 | url = https://github.com/nothings/stb.git 13 | [submodule "External/cute_headers"] 14 | path = External/cute_headers 15 | url = https://github.com/johnpayne-dev/cute_headers.git 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 johnpayne-dev 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MinecraftC/ChatLine.c: -------------------------------------------------------------------------------- 1 | #include "ChatLine.h" 2 | #include 3 | 4 | void ChatLineCreate(ChatLine * line, char * message) { 5 | *line = (ChatLine) { 6 | .message = StringCreate(message), 7 | .time = 0, 8 | }; 9 | } 10 | 11 | void ChatLineDestroy(ChatLine * line) { 12 | StringFree(line->message); 13 | } 14 | -------------------------------------------------------------------------------- /MinecraftC/ChatLine.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Utilities/String.h" 3 | 4 | typedef struct ChatLine { 5 | String message; 6 | int time; 7 | } ChatLine; 8 | 9 | void ChatLineCreate(ChatLine * line, char * message); 10 | void ChatLineDestroy(ChatLine * line); 11 | -------------------------------------------------------------------------------- /MinecraftC/Entity.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Physics/AABB.h" 3 | #include "Render/TextureManager.h" 4 | #include "Player/Player.h" 5 | #include "Mods/PrimedTNT.h" 6 | #include "Particle/Particle.h" 7 | 8 | typedef enum EntityType { 9 | EntityTypeNone, 10 | EntityTypePrimedTNT, 11 | EntityTypeParticle, 12 | EntityTypePlayer, 13 | } EntityType; 14 | 15 | typedef struct Entity { 16 | struct Level * level; 17 | float xo, yo, zo; 18 | float x, y, z; 19 | float xd, yd, zd; 20 | float yRot, xRot; 21 | float yRotO, xRotO; 22 | AABB aabb; 23 | bool onGround; 24 | bool horizontalCollision; 25 | bool collision; 26 | bool slide; 27 | bool removed; 28 | float heightOffset; 29 | float aabbWidth; 30 | float aabbHeight; 31 | float oldWalkDistance; 32 | float walkDistance; 33 | bool makeStepSound; 34 | float fallDistance; 35 | int nextStep; 36 | float ySlideOffset; 37 | float footSize; 38 | bool noPhysics; 39 | EntityType type; 40 | union { 41 | PlayerData player; 42 | ParticleData particle; 43 | #if MINECRAFTC_MODS 44 | PrimedTNTData tnt; 45 | #endif 46 | }; 47 | } Entity; 48 | 49 | void EntityCreate(Entity * entity, struct Level * level); 50 | void EntityResetPosition(Entity * entity); 51 | void EntityRemove(Entity * entity); 52 | void EntitySetSize(Entity * entity, float w, float h); 53 | void EntitySetPosition(Entity * entity, float x, float y, float z); 54 | void EntityTurn(Entity * entity, float rx, float ry); 55 | void EntityTick(Entity * entity); 56 | bool EntityIsFree(Entity * entity, float x, float y, float z); 57 | void EntityMove(Entity * entity, float x, float y, float z); 58 | bool EntityIsInWater(Entity * entity); 59 | bool EntityIsUnderWater(Entity * entity); 60 | bool EntityIsInLava(Entity * entity); 61 | void EntityMoveRelative(Entity * entity, float x, float z, float speed); 62 | float EntityGetBrightness(Entity * entity, float t); 63 | void EntitySetLevel(Entity * entity, struct Level * level); 64 | void EntityPlaySound(Entity * entity, char * name, float volume, float pitch); 65 | bool EntityIsPickable(Entity * entity); 66 | void EntityRender(Entity * entity, TextureManager * textures, float dt); 67 | -------------------------------------------------------------------------------- /MinecraftC/GUI/BlockSelectScreen.c: -------------------------------------------------------------------------------- 1 | #include "BlockSelectScreen.h" 2 | #include "Screen.h" 3 | #include "../SessionData.h" 4 | #include "../Minecraft.h" 5 | #include "../Level/Tile/Block.h" 6 | #include "../Render/ShapeRenderer.h" 7 | #include "../Utilities/OpenGL.h" 8 | 9 | void BlockSelectScreenCreate(BlockSelectScreen * screen) { 10 | GUIScreenCreate(screen); 11 | screen->type = GUIScreenTypeBlockSelect; 12 | screen->grabsMouse = true; 13 | } 14 | 15 | static int GetBlockOnScreen(BlockSelectScreen * screen, int mx, int my) { 16 | for (int32_t i = 0; i < ListLength(SessionDataAllowedBlocks); i++) { 17 | int x = screen->width / 2 + i % 9 * 24 + -108 - 3; 18 | int y = screen->height / 2 + i / 9 * 24 + -60 + 3; 19 | if (mx >= x && mx <= x + 24 && my >= y - 12 && my <= y + 12) { return i; } 20 | } 21 | return -1; 22 | } 23 | 24 | void BlockSelectScreenRender(BlockSelectScreen * screen, int mx, int my) { 25 | int blockNum = GetBlockOnScreen(screen, mx, my); 26 | ScreenDrawFadingBox(screen->width / 2 - 120, 30, screen->width / 2 + 120, 180, 0x05050090, 0x303060C0); 27 | if (blockNum >= 0) { 28 | int x = screen->width / 2 + blockNum % 9 * 24 + -108; 29 | int y = screen->height / 2 + blockNum / 9 * 24 + -60; 30 | ScreenDrawFadingBox(x - 3, y - 8, x + 23, y + 24 - 6, 0xFFFFFF90, 0xFFFFFFC0); 31 | } 32 | ScreenDrawCenteredString(screen->font, "Select block", screen->width / 2, 40, 0xffffffff); 33 | 34 | glBindTexture(GL_TEXTURE_2D, TextureManagerLoad(&screen->minecraft->textureManager, "Terrain.png")); 35 | for (int i = 0; i < ListLength(SessionDataAllowedBlocks); i++) { 36 | BlockType tile = SessionDataAllowedBlocks[i]; 37 | glPushMatrix(); 38 | int x = screen->width / 2 + i % 9 * 24 + -108; 39 | int y = screen->height / 2 + i / 9 * 24 + -60; 40 | glTranslatef(x, y, 0.0); 41 | glScalef(10.0, 10.0, 10.0); 42 | glTranslatef(1.0, 0.5, 8.0); 43 | glRotatef(-30.0, 1.0, 0.0, 0.0); 44 | glRotatef(45.0, 0.0, 1.0, 0.0); 45 | if (blockNum == i) { glScalef(1.6, 1.6, 1.6); } 46 | glTranslatef(-1.5, 0.5, 0.5); 47 | glScalef(-1.0, -1.0, -1.0); 48 | ShapeRendererBegin(); 49 | BlockRenderFullBrightness(&Blocks.table[tile]); 50 | ShapeRendererEnd(); 51 | glPopMatrix(); 52 | } 53 | } 54 | 55 | void BlockSelectScreenOnMouseClicked(BlockSelectScreen * screen, int x, int y, int button) { 56 | if (button == SDL_BUTTON_LEFT) { 57 | InventoryReplaceSlot(&screen->minecraft->player.player.inventory, GetBlockOnScreen(screen, x, y )); 58 | MinecraftSetCurrentScreen(screen->minecraft, NULL); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /MinecraftC/GUI/BlockSelectScreen.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "GUIScreen.h" 3 | 4 | typedef GUIScreen BlockSelectScreen; 5 | 6 | void BlockSelectScreenCreate(BlockSelectScreen * screen); 7 | void BlockSelectScreenRender(BlockSelectScreen * screen, int mx, int my); 8 | void BlockSelectScreenOnMouseClicked(BlockSelectScreen * screen, int x, int y, int button); 9 | -------------------------------------------------------------------------------- /MinecraftC/GUI/Button.c: -------------------------------------------------------------------------------- 1 | #include "Button.h" 2 | #include 3 | 4 | void ButtonCreate(Button * button, int buttonID, int x, int y, char * text) { 5 | ButtonCreateSize(button, buttonID, x, y, 200, 20, text); 6 | } 7 | 8 | void ButtonCreateSize(Button * button, int buttonID, int x, int y, int w, int h, char * text) { 9 | *button = (struct Button) { 10 | .id = buttonID, 11 | .x = x, 12 | .y = y, 13 | .width = w, 14 | .height = 20, 15 | .text = StringCreate(text), 16 | .visible = true, 17 | .active = true, 18 | }; 19 | } 20 | 21 | void ButtonDestroy(Button * button) { 22 | StringFree(button->text); 23 | } 24 | -------------------------------------------------------------------------------- /MinecraftC/GUI/Button.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "../Utilities/String.h" 4 | 5 | typedef struct Button { 6 | int x, y; 7 | int width, height; 8 | String text; 9 | int id; 10 | bool active; 11 | bool visible; 12 | } Button; 13 | 14 | void ButtonCreate(Button * button, int buttonID, int x, int y, char * text); 15 | void ButtonCreateSize(Button * button, int buttonID, int x, int y, int w, int h, char * text); 16 | void ButtonDestroy(Button * button); 17 | -------------------------------------------------------------------------------- /MinecraftC/GUI/ChatInputScreen.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "ChatInputScreen.h" 3 | #include "Screen.h" 4 | #include "../Minecraft.h" 5 | 6 | void ChatInputScreenCreate(ChatInputScreen * screen) { 7 | GUIScreenCreate(screen); 8 | screen->type = GUIScreenTypeChatInput; 9 | screen->chatInput = (ChatInputScreenData) { 10 | .message = StringCreate(""), 11 | .counter = 0, 12 | }; 13 | } 14 | 15 | void ChatInputScreenOnOpen(ChatInputScreen * screen) { 16 | } 17 | 18 | void ChatInputScreenOnClose(ChatInputScreen * screen) { 19 | } 20 | 21 | void ChatInputScreenTick(ChatInputScreen * screen) { 22 | screen->chatInput.counter++; 23 | } 24 | 25 | void ChatInputScreenRender(ChatInputScreen * screen, int mx, int my) { 26 | ScreenDrawBox(2, screen->height - 14, screen->width - 2, screen->height - 2, 0x00000080); 27 | String msg = StringCreate(screen->chatInput.message); 28 | StringConcatFront("> ", &msg); 29 | StringConcat(&msg, screen->chatInput.counter / 6 % 2 == 0 ? "_" : ""); 30 | ScreenDrawString(screen->font, msg, 4, screen->height - 12, 0xE0E0E0FF); 31 | StringFree(msg); 32 | } 33 | 34 | void ChatInputScreenOnKeyPressed(ChatInputScreen * screen, char eventChar, int eventKey) { 35 | if (eventKey == SDL_SCANCODE_ESCAPE) { MinecraftSetCurrentScreen(screen->minecraft, NULL); } 36 | else if (eventKey == SDL_SCANCODE_RETURN) { 37 | MinecraftSetCurrentScreen(screen->minecraft, NULL); 38 | } else { 39 | if (eventKey == SDL_SCANCODE_BACKSPACE && StringLength(screen->chatInput.message) > 0) { 40 | screen->chatInput.message = StringSub(screen->chatInput.message, 0, StringLength(screen->chatInput.message) - 2); 41 | } 42 | String allowedChars = StringCreate("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ,.:-_\'*!\\\"#%/()=+?[]{}<>@|$;"); 43 | if (StringIndexOf(allowedChars, eventChar) >= 0 && StringLength(screen->chatInput.message) < 64 - (2)) { 44 | StringConcat(&screen->chatInput.message, (char[]){ eventChar, '\0' }); 45 | } 46 | StringFree(allowedChars); 47 | } 48 | } 49 | 50 | void ChatInputScreenOnMouseClicked(ChatInputScreen * screen, int x, int y, int button) { 51 | if (button == SDL_BUTTON_LEFT && screen->minecraft->hud.hoveredPlayer != NULL) { 52 | if (StringLength(screen->chatInput.message) > 0 && screen->chatInput.message[StringLength(screen->chatInput.message) - 1] != ' ') { StringConcat(&screen->chatInput.message, " "); } 53 | StringConcat(&screen->chatInput.message, (char *)screen->minecraft->hud.hoveredPlayer); 54 | int len = 64; 55 | if (StringLength(screen->chatInput.message) > len) { screen->chatInput.message = StringSub(screen->chatInput.message, 0, len - 1); } 56 | } 57 | } 58 | 59 | void ChatInputScreenDestroy(ChatInputScreen * screen) { 60 | StringFree(screen->chatInput.message); 61 | } 62 | -------------------------------------------------------------------------------- /MinecraftC/GUI/ChatInputScreen.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "GUIScreen.h" 3 | #include "../Utilities/String.h" 4 | 5 | typedef GUIScreen ChatInputScreen; 6 | 7 | typedef struct ChatInputScreenData ChatInputScreenData; 8 | 9 | void ChatInputScreenCreate(ChatInputScreen * screen); 10 | void ChatInputScreenOnOpen(ChatInputScreen * screen); 11 | void ChatInputScreenOnClose(ChatInputScreen * screen); 12 | void ChatInputScreenTick(ChatInputScreen * screen); 13 | void ChatInputScreenRender(ChatInputScreen * screen, int mx, int my); 14 | void ChatInputScreenOnKeyPressed(ChatInputScreen * screen, char eventChar, int eventKey); 15 | void ChatInputScreenOnMouseClicked(ChatInputScreen * screen, int x, int y, int button); 16 | void ChatInputScreenDestroy(ChatInputScreen * screen); 17 | -------------------------------------------------------------------------------- /MinecraftC/GUI/ControlsScreen.c: -------------------------------------------------------------------------------- 1 | #include "ControlsScreen.h" 2 | #include "Screen.h" 3 | #include "../Minecraft.h" 4 | #include "../Utilities/Log.h" 5 | 6 | void ControlsScreenCreate(ControlsScreen * screen, GUIScreen * parent, GameSettings * settings) { 7 | GUIScreenCreate(screen); 8 | screen->type = GUIScreenTypeControls; 9 | screen->controls.parent = parent; 10 | screen->controls.selected = -1; 11 | screen->controls.settings = settings; 12 | screen->controls.title = "Controls"; 13 | } 14 | 15 | void ControlsScreenOnOpen(ControlsScreen * screen) { 16 | for (int i = 0; i < ListLength(screen->controls.settings->bindings); i++) { 17 | String text = GameSettingsGetBinding(screen->controls.settings, i); 18 | Button button; 19 | ButtonCreateSize(&button, i, screen->width / 2 - 155 + i % 2 * 160, screen->height / 6 + 24 * (i / 2 + 1) - 24, 150, 20, text); 20 | screen->buttons = ListPush(screen->buttons, &button); 21 | StringFree(text); 22 | } 23 | Button button; 24 | ButtonCreate(&button, 200, screen->width / 2 - 100, screen->height / 6 + 168, "Done"); 25 | screen->buttons = ListPush(screen->buttons, &button); 26 | } 27 | 28 | void ControlsScreenRender(ControlsScreen * screen, int mx, int my) { 29 | ScreenDrawFadingBox(0, 0, screen->width, screen->height, 0x05050060, 0x303060A0); 30 | ScreenDrawCenteredString(screen->font, screen->controls.title, screen->width / 2, 20, 0xFFFFFFFF); 31 | } 32 | 33 | void ControlsScreenOnKeyPressed(ControlsScreen * screen, char eventChar, int eventKey) { 34 | if (screen->controls.selected >= 0) { 35 | GameSettingsSetBinding(screen->controls.settings, screen->controls.selected, eventKey); 36 | String text = GameSettingsGetBinding(screen->controls.settings, screen->controls.selected); 37 | StringSet(&screen->buttons[screen->controls.selected].text, text); 38 | screen->controls.selected = -1; 39 | StringFree(text); 40 | } else { 41 | screen->type = GUIScreenTypeNone; 42 | GUIScreenOnKeyPressed(screen, eventChar, eventKey); 43 | screen->type = GUIScreenTypeControls; 44 | } 45 | } 46 | 47 | void ControlsScreenOnButtonClicked(ControlsScreen * screen, Button * button) { 48 | for (int i = 0; i < ListLength(screen->controls.settings->bindings); i++) { 49 | String text = GameSettingsGetBinding(screen->controls.settings, i); 50 | StringSet(&screen->buttons[i].text, text); 51 | StringFree(text); 52 | } 53 | 54 | if (button->id == 200) { 55 | MinecraftSetCurrentScreen(screen->minecraft, screen->controls.parent); 56 | } else { 57 | screen->controls.selected = button->id; 58 | String text = GameSettingsGetBinding(screen->controls.settings, button->id); 59 | StringConcatFront("> ", &text); 60 | StringConcat(&text, " <"); 61 | StringSet(&button->text, text); 62 | StringFree(text); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /MinecraftC/GUI/ControlsScreen.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "GUIScreen.h" 3 | #include "../GameSettings.h" 4 | 5 | typedef GUIScreen ControlsScreen; 6 | 7 | typedef struct ControlsScreenData ControlsScreenData; 8 | 9 | void ControlsScreenCreate(ControlsScreen * screen, GUIScreen * parent, GameSettings * settings); 10 | void ControlsScreenOnOpen(ControlsScreen * screen); 11 | void ControlsScreenRender(ControlsScreen * screen, int mx, int my); 12 | void ControlsScreenOnKeyPressed(ControlsScreen * screen, char eventChar, int eventKey); 13 | void ControlsScreenOnButtonClicked(ControlsScreen * screen, Button * button); 14 | -------------------------------------------------------------------------------- /MinecraftC/GUI/ErrorScreen.c: -------------------------------------------------------------------------------- 1 | #include "ErrorScreen.h" 2 | #include "Screen.h" 3 | 4 | void ErrorScreenCreate(ErrorScreen * screen, char * title, char * text) { 5 | GUIScreenCreate(screen); 6 | screen->type = GUIScreenTypeError; 7 | screen->error.title = title; 8 | screen->error.text = text; 9 | } 10 | 11 | void ErrorScreenOnOpen(ErrorScreen * screen) { 12 | } 13 | 14 | void ErrorScreenRender(ErrorScreen * screen, int mx, int my) { 15 | ScreenDrawFadingBox(0, 0, screen->width, screen->height, 0x402020FF, 0x501010FF); 16 | ScreenDrawCenteredString(screen->font, screen->error.title, screen->width / 2, 90, 0xffffffff); 17 | ScreenDrawCenteredString(screen->font, screen->error.text, screen->width / 2, 110, 0xffffffff); 18 | } 19 | 20 | void ErrorScreenOnKeyPressed(ErrorScreen * screen, char eventChar, int eventKey) { 21 | } 22 | -------------------------------------------------------------------------------- /MinecraftC/GUI/ErrorScreen.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "GUIScreen.h" 3 | 4 | typedef GUIScreen ErrorScreen; 5 | 6 | typedef struct ErrorScreenData ErrorScreenData; 7 | 8 | void ErrorScreenCreate(ErrorScreen * screen, char * title, char * text); 9 | void ErrorScreenOnOpen(ErrorScreen * screen); 10 | void ErrorScreenRender(ErrorScreen * screen, int mx, int my); 11 | void ErrorScreenOnKeyPressed(ErrorScreen * screen, char eventChar, int eventKey); 12 | -------------------------------------------------------------------------------- /MinecraftC/GUI/FontRenderer.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "FontRenderer.h" 3 | #include "../Render/ShapeRenderer.h" 4 | #include "../Utilities/String.h" 5 | #include "../Utilities/Log.h" 6 | #include "../Utilities/OpenGL.h" 7 | 8 | #include "../../Resources/Default.h" 9 | 10 | void FontRendererCreate(FontRenderer * font, GameSettings * settings, char * name, TextureManager * textures) { 11 | *font = (FontRenderer){ 0 }; 12 | font->settings = settings; 13 | font->textureName = name; 14 | 15 | int width = 0; 16 | int * pixels = NULL; 17 | if (strcmp(name, "Default.png") == 0) { pixels = (int *)Resource_Default_RGBA; width = Resource_Default_Width; } 18 | if (pixels == NULL) { LogFatal("Failed to load image %s.\n", name); } 19 | 20 | for (int i = 0; i < 128; i++) { 21 | int xt = i % 16; 22 | int yt = i / 16; 23 | int x = 0; 24 | for (bool emptyColumn = false; x < 8 && !emptyColumn; x++) { 25 | int xPixel = xt * 8 + x; 26 | emptyColumn = true; 27 | for (int y = 0; y < 8 && emptyColumn; y++) { 28 | int yPixel = (yt * 8 + y) * width; 29 | int pixel = pixels[xPixel + yPixel] & 0xff; 30 | if (pixel > 128) { emptyColumn = false; } 31 | } 32 | } 33 | 34 | if (i == 32) { x = 4; } 35 | font->widthMap[i] = x; 36 | } 37 | font->texture = TextureManagerLoad(textures, name); 38 | } 39 | 40 | static void Render(FontRenderer * font, char * str, int x, int y, uint32_t color, bool darken) { 41 | if (str != NULL) { 42 | if (darken) { color = (color & 0xfcfcfc) >> 2; } 43 | glBindTexture(GL_TEXTURE_2D, font->texture); 44 | ShapeRendererBegin(); 45 | ShapeRendererColor(color); 46 | for (int i = 0, w = 0; i < strlen(str); i++) { 47 | if (str[i] == 38 && strlen(str) > i + 1) { 48 | String hex = StringCreate("0123456789abcdef"); 49 | int index = StringIndexOf(hex, str[i + 1]); 50 | StringFree(hex); 51 | if (index < 0) { index = 15; } 52 | uint8_t v = (index & 0x08) << 3; 53 | uint8_t r = ((index & 0x04) >> 2) * 191 + v; 54 | uint8_t g = ((index & 0x02) >> 1) * 191 + v; 55 | uint8_t b = (index & 0x01) * 191 + v; 56 | if (font->settings->anaglyph) { 57 | uint8_t ar = (r * 30 + g * 59 + b * 11) / 100; 58 | uint8_t ag = (r * 30 + g * 70) / 100; 59 | uint8_t ab = (r * 30 + b * 70) / 100; 60 | r = ar; 61 | g = ag; 62 | b = ab; 63 | } 64 | color = r << 24 | g << 16 | b << 8; 65 | i += 2; 66 | if (darken) { color = (color & 0xfcfcfc) >> 2; } 67 | ShapeRendererColor(color); 68 | } 69 | 70 | int u = str[i] % 16 << 3; 71 | int v = str[i] / 16 << 3; 72 | float s = 7.99; 73 | ShapeRendererVertexUV(x + w, y + s, 0.0, u / 128.0, (v + s) / 128.0); 74 | ShapeRendererVertexUV(x + w + s, y + s, 0.0, (u + s) / 128.0, (v + s) / 128.0); 75 | ShapeRendererVertexUV(x + w + s, y, 0.0, (u + s) / 128.0, v / 128.0); 76 | ShapeRendererVertexUV(x + w, y, 0.0, u / 128.0 , v / 128.0); 77 | w += font->widthMap[(int)str[i]]; 78 | } 79 | ShapeRendererEnd(); 80 | } 81 | } 82 | 83 | void FontRendererRender(FontRenderer * font, char * str, int x, int y, uint32_t color) { 84 | Render(font, str, x + 1, y + 1, color, true); 85 | Render(font, str, x, y, color, false); 86 | } 87 | 88 | void FontRendererRenderNoShadow(FontRenderer * font, char * str, int x, int y, uint32_t color) { 89 | Render(font, str, x, y, color, false); 90 | } 91 | 92 | int FontRendererGetWidth(FontRenderer * font, char * str) { 93 | if (str == NULL) { 94 | return 0; 95 | } else { 96 | int width = 0; 97 | for (int i = 0; i < strlen(str); i++) 98 | { 99 | if (str[i] == 38) { i++; } 100 | else { width += font->widthMap[(int)str[i]]; } 101 | } 102 | return width; 103 | } 104 | } 105 | 106 | String FontRendererStripColor(char * str) { 107 | String string = StringCreate(str); 108 | for (int i = 0; i < strlen(str); i++) { 109 | if (str[i] == 38) { i++; } 110 | else { StringConcat(&string, (char[]){ str[i], '\0' }); } 111 | } 112 | return string; 113 | } 114 | -------------------------------------------------------------------------------- /MinecraftC/GUI/FontRenderer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "../Render/TextureManager.h" 4 | #include "../Utilities/String.h" 5 | 6 | typedef struct FontRenderer { 7 | int widthMap[256]; 8 | char * textureName; 9 | int texture; 10 | GameSettings * settings; 11 | } FontRenderer; 12 | 13 | void FontRendererCreate(FontRenderer * font, GameSettings * settings, char * name, TextureManager * textures); 14 | void FontRendererRender(FontRenderer * font, char * str, int x, int y, uint32_t color); 15 | void FontRendererRenderNoShadow(FontRenderer * font, char * str, int x, int y, uint32_t color); 16 | int FontRendererGetWidth(FontRenderer * font, char * str); 17 | String FontRendererStripColor(char * str); 18 | -------------------------------------------------------------------------------- /MinecraftC/GUI/GUIScreen.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Utilities/List.h" 3 | #include "Button.h" 4 | #include "FontRenderer.h" 5 | 6 | typedef enum GUIScreenType { 7 | GUIScreenTypeNone, 8 | GUIScreenTypeBlockSelect, 9 | GUIScreenTypeChatInput, 10 | GUIScreenTypeControls, 11 | GUIScreenTypeError, 12 | GUIScreenTypeGameOver, 13 | GUIScreenTypeGenerateLevel, 14 | GUIScreenTypeLevelName, 15 | GUIScreenTypeLoadLevel, 16 | GUIScreenTypeOptions, 17 | GUIScreenTypePause, 18 | GUIScreenTypeSaveLevel, 19 | #if MINECRAFTC_MODS 20 | GUIScreenTypeMods, 21 | #endif 22 | } GUIScreenType; 23 | 24 | typedef struct GUIScreen { 25 | struct Minecraft * minecraft; 26 | int width, height; 27 | List(Button) buttons; 28 | bool grabsMouse; 29 | FontRenderer * font; 30 | GUIScreenType type; 31 | union { 32 | struct ChatInputScreenData { 33 | String message; 34 | int counter; 35 | } chatInput; 36 | struct ControlsScreenData { 37 | struct GUIScreen * parent; 38 | char * title; 39 | GameSettings * settings; 40 | int selected; 41 | } controls; 42 | struct ErrorScreenData { 43 | char * title; 44 | char * text; 45 | } error; 46 | struct GenerateLevelScreenData { 47 | struct GUIScreen * parent; 48 | } generateLevel; 49 | struct LevelNameScreenData { 50 | struct GUIScreen * parent; 51 | char * title; 52 | int id; 53 | String name; 54 | int counter; 55 | } levelName; 56 | struct LoadLevelScreenData { 57 | struct GUIScreen * parent; 58 | char * title; 59 | String names[5]; 60 | } level; 61 | struct OptionsScreenData { 62 | struct GUIScreen * parent; 63 | char * title; 64 | GameSettings * settings; 65 | } options; 66 | #if MINECRAFTC_MODS 67 | struct ModsScreenData { 68 | struct GUIScreen * parent; 69 | char * title; 70 | GameSettings * settings; 71 | } mods; 72 | #endif 73 | }; 74 | } GUIScreen; 75 | 76 | void GUIScreenCreate(GUIScreen * screen); 77 | void GUIScreenRender(GUIScreen * screen, int mouseX, int mouseY); 78 | void GUIScreenOnKeyPressed(GUIScreen * screen, char eventChar, int eventKey); 79 | void GUIScreenOnMouseClicked(GUIScreen * screen, int x, int y, int button); 80 | void GUIScreenOnButtonClicked(GUIScreen * screen, Button * button); 81 | void GUIScreenOpen(GUIScreen * screen, struct Minecraft * minecraft, int width, int height); 82 | void GUIScreenOnOpen(GUIScreen * screen); 83 | void GUIScreenDoInput(GUIScreen * screen, List(SDL_Event) events); 84 | void GUIScreenMouseEvent(GUIScreen * screen, SDL_Event event); 85 | void GUIScreenKeyboardEvent(GUIScreen * screen, SDL_Event event); 86 | void GUIScreenTick(GUIScreen * screen); 87 | void GUIScreenOnClose(GUIScreen * screen); 88 | void GUIScreenDestroy(GUIScreen * screen); 89 | -------------------------------------------------------------------------------- /MinecraftC/GUI/GenerateLevelScreen.c: -------------------------------------------------------------------------------- 1 | #include "GenerateLevelScreen.h" 2 | #include "Screen.h" 3 | #include "../Minecraft.h" 4 | 5 | void GenerateLevelScreenCreate(GenerateLevelScreen * screen, GUIScreen * parent) { 6 | GUIScreenCreate(screen); 7 | screen->type = GUIScreenTypeGenerateLevel; 8 | screen->generateLevel.parent = parent; 9 | } 10 | 11 | void GenerateLevelScreenOnOpen(GenerateLevelScreen * screen) { 12 | screen->buttons = ListPush(screen->buttons, &(Button){ 0 }); 13 | ButtonCreate(&screen->buttons[0], 0, screen->width / 2 - 100, screen->height / 4, "Small"); 14 | screen->buttons = ListPush(screen->buttons, &(Button){ 0 }); 15 | ButtonCreate(&screen->buttons[1], 1, screen->width / 2 - 100, screen->height / 4 + 24, "Normal"); 16 | screen->buttons = ListPush(screen->buttons, &(Button){ 0 }); 17 | ButtonCreate(&screen->buttons[2], 2, screen->width / 2 - 100, screen->height / 4 + 48, "Huge"); 18 | #if MINECRAFTC_MODS 19 | if (screen->minecraft->settings.largerWorldGen) { 20 | screen->buttons = ListPush(screen->buttons, &(Button){ 0 }); 21 | ButtonCreate(&screen->buttons[3], 3, screen->width / 2 - 100, screen->height / 4 + 72, "Extra huge"); 22 | } 23 | #endif 24 | screen->buttons = ListPush(screen->buttons, &(Button){ 0 }); 25 | ButtonCreate(&screen->buttons[ListLength(screen->buttons) - 1], 100, screen->width / 2 - 100, screen->height / 4 + 120, "Cancel"); 26 | } 27 | 28 | void GenerateLevelScreenOnButtonClicked(GenerateLevelScreen * screen, Button * button) { 29 | if (button->id == 100) { 30 | MinecraftSetCurrentScreen(screen->minecraft, screen->generateLevel.parent); 31 | } else { 32 | MinecraftRegenerateLevel(screen->minecraft, button->id); 33 | MinecraftSetCurrentScreen(screen->minecraft, NULL); 34 | MinecraftGrabMouse(screen->minecraft); 35 | } 36 | } 37 | 38 | void GenerateLevelScreenRender(GenerateLevelScreen * screen, int mx, int my) { 39 | ScreenDrawFadingBox(0, 0, screen->width, screen->height, 0x05050060, 0x303060A0); 40 | ScreenDrawCenteredString(screen->font, "Generate new level", screen->width / 2, 40, 0xffffffff); 41 | } 42 | -------------------------------------------------------------------------------- /MinecraftC/GUI/GenerateLevelScreen.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "GUIScreen.h" 3 | 4 | typedef GUIScreen GenerateLevelScreen; 5 | 6 | typedef struct GenerateLevelScreenData GenerateLevelScreenData; 7 | 8 | void GenerateLevelScreenCreate(GenerateLevelScreen * screen, GUIScreen * parent); 9 | void GenerateLevelScreenOnOpen(GenerateLevelScreen * screen); 10 | void GenerateLevelScreenOnButtonClicked(GenerateLevelScreen * screen, Button * button); 11 | void GenerateLevelScreenRender(GenerateLevelScreen * screen, int mx, int my); 12 | -------------------------------------------------------------------------------- /MinecraftC/GUI/HUDScreen.c: -------------------------------------------------------------------------------- 1 | #include "HUDScreen.h" 2 | #include "Screen.h" 3 | #include "../Minecraft.h" 4 | #include "../Render/ShapeRenderer.h" 5 | #include "../Utilities/Time.h" 6 | #include "../Utilities/SinTable.h" 7 | #include "../Utilities/OpenGL.h" 8 | 9 | void HUDScreenCreate(HUDScreen * hud, struct Minecraft * minecraft, int width, int height) { 10 | *hud = (HUDScreen) { 11 | .chat = ListCreate(sizeof(ChatLine)), 12 | .hoveredPlayer = NULL, 13 | .minecraft = minecraft, 14 | .width = width * 240 / height, 15 | .height = height * 240 / height, 16 | }; 17 | RandomGeneratorCreate(&hud->random, time(NULL)); 18 | } 19 | 20 | void HUDScreenRender(HUDScreen * hud, float dt, int mx, int my) { 21 | PlayerData * player = &hud->minecraft->player.player; 22 | RendererEnableGUIMode(&hud->minecraft->renderer); 23 | glBindTexture(GL_TEXTURE_2D, TextureManagerLoad(&hud->minecraft->textureManager, "GUI/GUI.png")); 24 | glColor4f(1.0, 1.0, 1.0, 1.0); 25 | glEnable(GL_BLEND); 26 | ScreenDrawImage(hud->width / 2 - 91, hud->height - 22, 0, 0, 182, 22, -90.0); 27 | ScreenDrawImage(hud->width / 2 - 92 + player->inventory.selected * 20, hud->height - 23, 0, 22, 24, 22, -90.0); 28 | glBindTexture(GL_TEXTURE_2D, TextureManagerLoad(&hud->minecraft->textureManager, "GUI/Icons.png")); 29 | ScreenDrawImage(hud->width / 2 - 7, hud->height / 2 - 7, 0, 0, 16, 16, -90.0); 30 | 31 | glDisable(GL_BLEND); 32 | for (int i = 0; i < 9; i++) { 33 | int x = hud->width / 2 - 90 + i * 20; 34 | int y = hud->height - 16; 35 | BlockType tile = player->inventory.slots[i]; 36 | if (tile != -1 && tile != 0) { 37 | glPushMatrix(); 38 | glTranslatef(x, y, -50.0); 39 | glScalef(10.0, 10.0, 10.0); 40 | glTranslatef(1.0, 0.5, 0.0); 41 | glRotatef(-30.0, 1.0, 0.0, 0.0); 42 | glRotatef(45.0, 0.0, 1.0, 0.0); 43 | glTranslatef(-1.5, 0.5, 0.5); 44 | glScalef(-1.0, -1.0, -1.0); 45 | glBindTexture(GL_TEXTURE_2D, TextureManagerLoad(&hud->minecraft->textureManager, "Terrain.png")); 46 | ShapeRendererBegin(); 47 | BlockRenderFullBrightness(&Blocks.table[tile]); 48 | ShapeRendererEnd(); 49 | glPopMatrix(); 50 | } 51 | } 52 | 53 | FontRendererRender(&hud->minecraft->font, "0.30", 2, 2, 0xffffffff); 54 | if (hud->minecraft->settings.showFrameRate) { FontRendererRender(&hud->minecraft->font, hud->minecraft->debug, 2, 12, 0xffffffff); } 55 | 56 | int maxLines = 10; 57 | bool chatScreen = false; 58 | if (hud->minecraft->currentScreen != NULL && hud->minecraft->currentScreen->type == GUIScreenTypeChatInput) { 59 | maxLines = 20; 60 | chatScreen = true; 61 | } 62 | for (int i = 0; i < ListLength(hud->chat) && i < maxLines; i++) { 63 | if (hud->chat[i].time < 200 || chatScreen) { FontRendererRender(&hud->minecraft->font, hud->chat[i].message, 2, hud->height - 28 - i * 9, 0xffffffff); } 64 | } 65 | 66 | hud->hoveredPlayer = NULL; 67 | /*if (Keyboard.isKeyDown(15) && hud->Minecraft->NetworkManager != NULL && NetworkManagerIsConnected(hud->Minecraft->NetworkManager)) 68 | { 69 | List var22 = this.mc.networkManager.getPlayers(); 70 | GL11.glEnable(3042); 71 | GL11.glDisable(3553); 72 | GL11.glBlendFunc(770, 771); 73 | GL11.glBegin(7); 74 | GL11.glColor4f(0.0F, 0.0F, 0.0F, 0.7F); 75 | GL11.glVertex2f((float)(var14 + 128), (float)(var15 - 68 - 12)); 76 | GL11.glVertex2f((float)(var14 - 128), (float)(var15 - 68 - 12)); 77 | GL11.glColor4f(0.2F, 0.2F, 0.2F, 0.8F); 78 | GL11.glVertex2f((float)(var14 - 128), (float)(var15 + 68)); 79 | GL11.glVertex2f((float)(var14 + 128), (float)(var15 + 68)); 80 | GL11.glEnd(); 81 | GL11.glDisable(3042); 82 | GL11.glEnable(3553); 83 | var21 = "Connected players:"; 84 | var5.render(var21, var14 - var5.getWidth(var21) / 2, var15 - 64 - 12, 16777215); 85 | for(var11 = 0; var11 < var22.size(); ++var11) 86 | { 87 | int var28 = var14 + var11 % 2 * 120 - 120; 88 | int var17 = var15 - 64 + (var11 / 2 << 3); 89 | if(var2 && var3 >= var28 && var4 >= var17 && var3 < var28 + 120 && var4 < var17 + 8) 90 | { 91 | this.hoveredPlayer = (String)var22.get(var11); 92 | var5.renderNoShadow((String)var22.get(var11), var28 + 2, var17, 16777215); 93 | } 94 | else 95 | { 96 | var5.renderNoShadow((String)var22.get(var11), var28, var17, 15658734); 97 | } 98 | } 99 | }*/ 100 | } 101 | 102 | void HUDScreenAddChat(HUDScreen * screen, char * message) { 103 | screen->chat = ListPush(screen->chat, &(ChatLine){ 0 }); 104 | ChatLineCreate(&screen->chat[ListLength(screen->chat) - 1], message); 105 | while (ListLength(screen->chat) > 50) { screen->chat = ListRemove(screen->chat, 0); } 106 | } 107 | 108 | void HUDScreenDestroy(HUDScreen * hud) { 109 | for (int i = 0; i < ListLength(hud->chat); i++) { ChatLineDestroy(&hud->chat[i]); } 110 | ListFree(hud->chat); 111 | } 112 | -------------------------------------------------------------------------------- /MinecraftC/GUI/HUDScreen.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../ChatLine.h" 3 | #include "../Utilities/List.h" 4 | #include "../Utilities/Random.h" 5 | #include 6 | 7 | typedef struct HUDScreen { 8 | List(ChatLine) chat; 9 | RandomGenerator random; 10 | struct Minecraft * minecraft; 11 | int width, height; 12 | const char * hoveredPlayer; 13 | int ticks; 14 | } HUDScreen; 15 | 16 | void HUDScreenCreate(HUDScreen * hud, struct Minecraft * minecraft, int width, int height); 17 | void HUDScreenRender(HUDScreen * hud, float dt, int mx, int my); 18 | void HUDScreenAddChat(HUDScreen * hud, char * message); 19 | void HUDScreenDestroy(HUDScreen * hud); 20 | -------------------------------------------------------------------------------- /MinecraftC/GUI/LevelNameScreen.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "LevelNameScreen.h" 3 | #include "Screen.h" 4 | #include "../Minecraft.h" 5 | #include "../Utilities/Log.h" 6 | 7 | void LevelNameScreenCreate(LevelNameScreen * screen, GUIScreen * parent, char * name, int id) { 8 | GUIScreenCreate(screen); 9 | screen->type = GUIScreenTypeLevelName; 10 | screen->levelName.title = "Enter level name:"; 11 | screen->levelName.counter = 0; 12 | screen->levelName.parent = parent; 13 | screen->levelName.name = StringCreate(name); 14 | screen->levelName.id = id; 15 | if (strcmp(name, "---") == 0) { StringSet(&screen->levelName.name, ""); } 16 | } 17 | 18 | void LevelNameScreenOnOpen(LevelNameScreen * screen) { 19 | screen->buttons = ListPush(screen->buttons, &(Button){ 0 }); 20 | ButtonCreate(&screen->buttons[ListLength(screen->buttons) - 1], 0, screen->width / 2 - 100, screen->height / 4 + 120, "Save"); 21 | screen->buttons = ListPush(screen->buttons, &(Button){ 0 }); 22 | ButtonCreate(&screen->buttons[ListLength(screen->buttons) - 1], 1, screen->width / 2 - 100, screen->height / 4 + 144, "Cancel"); 23 | screen->buttons[0].active = StringLength(screen->levelName.name) > 0; 24 | } 25 | 26 | void LevelNameScreenOnClose(LevelNameScreen * screen) { 27 | } 28 | 29 | void LevelNameScreenTick(LevelNameScreen * screen) { 30 | screen->levelName.counter++; 31 | } 32 | 33 | void LevelNameScreenRender(LevelNameScreen * screen, int mx, int my) { 34 | ScreenDrawFadingBox(0, 0, screen->width, screen->height, 0x05050060, 0x303060A0); 35 | ScreenDrawCenteredString(screen->font, screen->levelName.title, screen->width / 2, 40, 0xffffffff); 36 | int x = screen->width / 2 - 100; 37 | int y = screen->height / 2 - 10; 38 | ScreenDrawBox(x - 1, y - 1, x + 201, y + 21, 0xA0A0A0FF); 39 | ScreenDrawBox(x, y, x + 200, y + 20, 0x000000ff); 40 | String string = StringCreate(screen->levelName.name); 41 | StringConcat(&string, screen->levelName.counter / 6 % 2 == 0 ? "_" : ""); 42 | ScreenDrawString(screen->font, string, x + 4, y + 6, 0xE0E0E0FF); 43 | StringFree(string); 44 | } 45 | 46 | void LevelNameScreenOnKeyPressed(LevelNameScreen * screen, char eventChar, int eventKey) { 47 | if (eventKey == SDL_SCANCODE_BACKSPACE && StringLength(screen->levelName.name) > 0) { 48 | screen->levelName.name = StringSub(screen->levelName.name, 0, StringLength(screen->levelName.name) - 2); 49 | } 50 | 51 | String allowedChars = StringCreate("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ,.:-_\'*!\"#%/()=+?[]{}<>"); 52 | if (StringIndexOf(allowedChars, eventChar) >= 0 && StringLength(screen->levelName.name) < 64) { 53 | StringConcat(&screen->levelName.name, (char[]){ eventChar, '\0' }); 54 | } 55 | StringFree(allowedChars); 56 | screen->buttons[0].active = StringLength(screen->levelName.name) > 0; 57 | } 58 | 59 | void LevelNameScreenOnButtonClicked(LevelNameScreen * screen, Button * button) { 60 | if (button->active) { 61 | if (button->id == 0 && StringLength(screen->levelName.name) > 0) { 62 | String filePath = StringCreate(screen->minecraft->workingDirectory); 63 | StringConcat(&filePath, "Level0.dat"); 64 | filePath[StringLength(filePath) - 5] += screen->levelName.id; 65 | bool success = LevelSave(&screen->minecraft->level, filePath, screen->levelName.name); 66 | StringFree(filePath); 67 | if (!success) { 68 | LogWarning("failed to save level: %s\n", SDL_GetError()); 69 | } 70 | 71 | MinecraftSetCurrentScreen(screen->minecraft, NULL); 72 | MinecraftGrabMouse(screen->minecraft); 73 | } 74 | 75 | if (button->id == 1) { 76 | MinecraftSetCurrentScreen(screen->minecraft, screen->levelName.parent); 77 | } 78 | } 79 | } 80 | 81 | void LevelNameScreenDestroy(LevelNameScreen * screen) { 82 | StringFree(screen->levelName.name); 83 | } 84 | -------------------------------------------------------------------------------- /MinecraftC/GUI/LevelNameScreen.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "GUIScreen.h" 3 | 4 | typedef GUIScreen LevelNameScreen; 5 | 6 | typedef struct LevelNameScreenData LevelNameScreenData; 7 | 8 | void LevelNameScreenCreate(LevelNameScreen * screen, GUIScreen * parent, char * name, int id); 9 | void LevelNameScreenOnOpen(LevelNameScreen * screen); 10 | void LevelNameScreenOnClose(LevelNameScreen * screen); 11 | void LevelNameScreenTick(LevelNameScreen * screen); 12 | void LevelNameScreenRender(LevelNameScreen * screen, int mx, int my); 13 | void LevelNameScreenOnKeyPressed(LevelNameScreen * screen, char eventChar, int eventKey); 14 | void LevelNameScreenOnButtonClicked(LevelNameScreen * screen, Button * button); 15 | void LevelNameScreenDestroy(LevelNameScreen * screen); 16 | -------------------------------------------------------------------------------- /MinecraftC/GUI/LoadLevelScreen.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "LoadLevelScreen.h" 3 | #include "SaveLevelScreen.h" 4 | #include "../Minecraft.h" 5 | #include "Screen.h" 6 | #include "../Utilities/Log.h" 7 | 8 | void LoadLevelScreenCreate(LoadLevelScreen * screen, GUIScreen * parent) { 9 | GUIScreenCreate(screen); 10 | screen->type = GUIScreenTypeLoadLevel; 11 | screen->level.parent = parent; 12 | screen->level.title = "Load level"; 13 | for (int i = 0; i < 5; i++) { 14 | screen->level.names[i] = StringCreate(""); 15 | 16 | String filePath = StringCreate(parent->minecraft->workingDirectory); 17 | StringConcat(&filePath, "Level0.dat"); 18 | filePath[StringLength(filePath) - 5] += i; 19 | SDL_RWops * file = SDL_RWFromFile(filePath, "rb"); 20 | if (file == NULL) { 21 | continue; 22 | } 23 | char nameChar; 24 | do { 25 | SDL_RWread(file, &nameChar, 1, 1); 26 | StringConcat(&screen->level.names[i], (char []){ nameChar, '\0' }); 27 | } while (nameChar != '\0'); 28 | 29 | SDL_RWclose(file); 30 | StringFree(filePath); 31 | } 32 | } 33 | 34 | void LoadLevelScreenOnOpen(LoadLevelScreen * screen) { 35 | for (int i = 0; i < 5; i++) { 36 | char * name = screen->level.names[i]; 37 | if (name[0] == '\0') { 38 | name = "---"; 39 | } 40 | screen->buttons = ListPush(screen->buttons, &(Button){ 0 }); 41 | ButtonCreate(&screen->buttons[i], i, screen->width / 2 - 100, screen->height / 6 + i * 24, name); 42 | screen->buttons[i].active = screen->type != GUIScreenTypeLoadLevel || screen->level.names[i][0] != '\0'; 43 | } 44 | screen->buttons = ListPush(screen->buttons, &(Button){ 0 }); 45 | ButtonCreate(&screen->buttons[ListLength(screen->buttons) - 1], 5, screen->width / 2 - 100, screen->height / 6 + 132, "Load file..."); 46 | screen->buttons[5].active = false; 47 | screen->buttons = ListPush(screen->buttons, &(Button){ 0 }); 48 | ButtonCreate(&screen->buttons[ListLength(screen->buttons) - 1], 6, screen->width / 2 - 100, screen->height / 6 + 168, "Cancel"); 49 | if (screen->type == GUIScreenTypeSaveLevel) { SaveLevelScreenOnOpen(screen); return; } 50 | } 51 | 52 | void LoadLevelScreenOnButtonClicked(LoadLevelScreen * screen, Button * button) { 53 | if (button->active) { 54 | if (button->id < 5) { 55 | LoadLevelScreenOpenLevel(screen, button->id); 56 | } else if (button->id == 5) { 57 | } else if (button->id == 6) { 58 | MinecraftSetCurrentScreen(screen->minecraft, screen->level.parent); 59 | } 60 | } 61 | } 62 | 63 | void LoadLevelScreenOpenLevel(LoadLevelScreen * screen, int id) { 64 | if (screen->type == GUIScreenTypeSaveLevel) { 65 | SaveLevelScreenOpenLevel(screen, id); 66 | return; 67 | } 68 | String filePath = StringCreate(screen->minecraft->workingDirectory); 69 | StringConcat(&filePath, "Level0.dat"); 70 | filePath[StringLength(filePath) - 5] += id; 71 | LevelLoad(&screen->minecraft->level, filePath); 72 | StringFree(filePath); 73 | 74 | MinecraftSetCurrentScreen(screen->minecraft, NULL); 75 | MinecraftGrabMouse(screen->minecraft); 76 | } 77 | 78 | void LoadLevelScreenOpenLevelFromFile(LoadLevelScreen * screen, char * file) { 79 | if (screen->type == GUIScreenTypeSaveLevel) { SaveLevelScreenOpenLevelFromFile(screen, file); return; } 80 | MinecraftSetCurrentScreen(screen->minecraft, screen->level.parent); 81 | } 82 | 83 | void LoadLevelScreenRender(LoadLevelScreen * screen, int mx, int my) { 84 | ScreenDrawFadingBox(0, 0, screen->width, screen->height, 0x05050060, 0x303060A0); 85 | ScreenDrawCenteredString(screen->font, screen->level.title, screen->width / 2, 20, 0xffffffff); 86 | GUIScreenType type = screen->type; 87 | screen->type = GUIScreenTypeNone; 88 | GUIScreenRender(screen, mx, my); 89 | screen->type = type; 90 | } 91 | -------------------------------------------------------------------------------- /MinecraftC/GUI/LoadLevelScreen.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "GUIScreen.h" 4 | 5 | typedef GUIScreen LoadLevelScreen; 6 | 7 | typedef struct LoadLevelScreenData LoadLevelScreenData; 8 | 9 | void LoadLevelScreenCreate(LoadLevelScreen * screen, GUIScreen * parent); 10 | void LoadLevelScreenOnOpen(LoadLevelScreen * screen); 11 | void LoadLevelScreenOnButtonClicked(LoadLevelScreen * screen, Button * button); 12 | void LoadLevelScreenOpenLevel(LoadLevelScreen * screen, int level); 13 | void LoadLevelScreenOpenLevelFromFile(LoadLevelScreen * screen, char * file); 14 | void LoadLevelScreenRender(LoadLevelScreen * screen, int mx, int my); 15 | -------------------------------------------------------------------------------- /MinecraftC/GUI/ModsScreen.c: -------------------------------------------------------------------------------- 1 | #if MINECRAFTC_MODS 2 | #include "ModsScreen.h" 3 | #include "Screen.h" 4 | #include "../Minecraft.h" 5 | 6 | void ModsScreenCreate(ModsScreen * screen, GUIScreen * parent, GameSettings * settings) { 7 | GUIScreenCreate(screen); 8 | screen->type = GUIScreenTypeMods; 9 | screen->mods.parent = parent; 10 | screen->mods.title = "Mods"; 11 | screen->mods.settings = settings; 12 | } 13 | 14 | void ModsScreenOnOpen(ModsScreen * screen) { 15 | for (int i = 0; i < screen->mods.settings->modsCount; i++) { 16 | screen->buttons = ListPush(screen->buttons, &(Button){ 0 }); 17 | String text = GameSettingsGetSetting(screen->mods.settings, screen->mods.settings->settingsCount + i); 18 | ButtonCreateSize(&screen->buttons[i], i, screen->width / 2 - 155 + i % 2 * 160, screen->height / 6 + 24 * (i / 2 + 1) - 24, 150, 20, text); 19 | } 20 | Button button; 21 | ButtonCreate(&button, 200, screen->width / 2 - 100, screen->height / 6 + 168, "Done"); 22 | screen->buttons = ListPush(screen->buttons, &button); 23 | } 24 | 25 | void ModsScreenRender(ModsScreen * screen, int mx, int my) { 26 | ScreenDrawFadingBox(0, 0, screen->width, screen->height, 0x05050060, 0x303060A0); 27 | ScreenDrawCenteredString(screen->font, screen->mods.title, screen->width / 2, 20, 0xFFFFFFFF); 28 | } 29 | 30 | void ModsScreenOnButtonClicked(ModsScreen * screen, Button * button) { 31 | if (button->id < 100 && button->active) { 32 | GameSettingsToggleSetting(screen->mods.settings, screen->mods.settings->settingsCount + button->id); 33 | StringSet(&button->text, GameSettingsGetSetting(screen->mods.settings, screen->mods.settings->settingsCount + button->id)); 34 | } 35 | if (button->id == 200) { 36 | MinecraftSetCurrentScreen(screen->minecraft, screen->mods.parent); 37 | } 38 | } 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /MinecraftC/GUI/ModsScreen.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #if MINECRAFTC_MODS 3 | #include "GUIScreen.h" 4 | 5 | typedef GUIScreen ModsScreen; 6 | 7 | typedef struct ModsScreenData ModsScreenData; 8 | 9 | void ModsScreenCreate(ModsScreen * screen, GUIScreen * parent, GameSettings * settings); 10 | void ModsScreenOnOpen(ModsScreen * screen); 11 | void ModsScreenRender(ModsScreen * screen, int mx, int my); 12 | void ModsScreenOnButtonClicked(ModsScreen * screen, Button * button); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /MinecraftC/GUI/OptionsScreen.c: -------------------------------------------------------------------------------- 1 | #include "OptionsScreen.h" 2 | #include "ControlsScreen.h" 3 | #include "ModsScreen.h" 4 | #include "Screen.h" 5 | #include "../Minecraft.h" 6 | 7 | void OptionsScreenCreate(OptionsScreen * screen, GUIScreen * parent, GameSettings * settings) { 8 | GUIScreenCreate(screen); 9 | screen->type = GUIScreenTypeOptions; 10 | screen->options.parent = parent; 11 | screen->options.settings = settings; 12 | screen->options.title = "Options"; 13 | } 14 | 15 | void OptionsScreenOnOpen(OptionsScreen * screen) { 16 | for (int i = 0; i < screen->options.settings->settingsCount; i++) { 17 | screen->buttons = ListPush(screen->buttons, &(Button){ 0 }); 18 | ButtonCreateSize(&screen->buttons[i], i, screen->width / 2 - 155 + i % 2 * 160, screen->height / 6 + 24 * (i / 2 + 1) - 24, 150, 20, GameSettingsGetSetting(screen->options.settings, i)); 19 | } 20 | #if MINECRAFTC_MODS 21 | screen->buttons = ListPush(screen->buttons, &(Button){ 0 }); 22 | ButtonCreate(&screen->buttons[ListLength(screen->buttons) - 1], 100, screen->width / 2 - 100, screen->height / 6 + 108, "Controls..."); 23 | screen->buttons = ListPush(screen->buttons, &(Button){ 0 }); 24 | ButtonCreate(&screen->buttons[ListLength(screen->buttons) - 1], 150, screen->width / 2 - 100, screen->height / 6 + 132, "Mods..."); 25 | #else 26 | screen->buttons = ListPush(screen->buttons, &(Button){ 0 }); 27 | ButtonCreate(&screen->buttons[ListLength(screen->buttons) - 1], 100, screen->width / 2 - 100, screen->height / 6 + 132, "Controls..."); 28 | #endif 29 | screen->buttons = ListPush(screen->buttons, &(Button){ 0 }); 30 | ButtonCreate(&screen->buttons[ListLength(screen->buttons) - 1], 200, screen->width / 2 - 100, screen->height / 6 + 168, "Done"); 31 | } 32 | 33 | void OptionsScreenOnButtonClicked(OptionsScreen * screen, Button * button) { 34 | if (button->active) { 35 | if (button->id < 100) { 36 | GameSettingsToggleSetting(screen->options.settings, button->id); 37 | StringSet(&button->text, GameSettingsGetSetting(screen->options.settings, button->id)); 38 | } 39 | if (button->id == 100) { 40 | ControlsScreen * controls = malloc(sizeof(ControlsScreen)); 41 | ControlsScreenCreate(controls, screen, screen->options.settings); 42 | MinecraftSetCurrentScreen(screen->minecraft, controls); 43 | } 44 | #if MINECRAFTC_MODS 45 | if (button->id == 150) { 46 | ModsScreen * mods = malloc(sizeof(ModsScreen)); 47 | ModsScreenCreate(mods, screen, &screen->minecraft->settings); 48 | MinecraftSetCurrentScreen(screen->minecraft, mods); 49 | } 50 | #endif 51 | if (button->id == 200) { 52 | MinecraftSetCurrentScreen(screen->minecraft, screen->options.parent); 53 | } 54 | } 55 | } 56 | 57 | void OptionsScreenRender(OptionsScreen * screen, int mx, int my) { 58 | ScreenDrawFadingBox(0, 0, screen->width, screen->height, 0x05050060, 0x303060A0); 59 | ScreenDrawCenteredString(screen->font, screen->options.title, screen->width / 2, 20, 0xffffffff); 60 | } 61 | -------------------------------------------------------------------------------- /MinecraftC/GUI/OptionsScreen.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "GUIScreen.h" 3 | #include "../GameSettings.h" 4 | 5 | typedef GUIScreen OptionsScreen; 6 | 7 | typedef struct OptionsScreenData OptionsScreenData; 8 | 9 | void OptionsScreenCreate(OptionsScreen * screen, GUIScreen * parent, GameSettings * settings); 10 | void OptionsScreenOnOpen(OptionsScreen * screen); 11 | void OptionsScreenOnButtonClicked(OptionsScreen * screen, Button * button); 12 | void OptionsScreenRender(OptionsScreen * screen, int mx, int my); 13 | -------------------------------------------------------------------------------- /MinecraftC/GUI/PauseScreen.c: -------------------------------------------------------------------------------- 1 | #include "PauseScreen.h" 2 | #include "OptionsScreen.h" 3 | #include "GenerateLevelScreen.h" 4 | #include "LoadLevelScreen.h" 5 | #include "SaveLevelScreen.h" 6 | #include "Screen.h" 7 | #include "../Minecraft.h" 8 | 9 | void PauseScreenCreate(PauseScreen * screen) { 10 | GUIScreenCreate(screen); 11 | screen->type = GUIScreenTypePause; 12 | } 13 | 14 | void PauseScreenOnOpen(PauseScreen * screen) { 15 | screen->buttons = ListPush(screen->buttons, &(Button){ 0 }); 16 | ButtonCreate(&screen->buttons[0], 0, screen->width / 2 - 100, screen->height / 4, "Options..."); 17 | screen->buttons = ListPush(screen->buttons, &(Button){ 0 }); 18 | ButtonCreate(&screen->buttons[1], 1, screen->width / 2 - 100, screen->height / 4 + 24, "Generate new level..."); 19 | screen->buttons = ListPush(screen->buttons, &(Button){ 0 }); 20 | ButtonCreate(&screen->buttons[2], 2, screen->width / 2 - 100, screen->height / 4 + 48, "Save level.."); 21 | screen->buttons = ListPush(screen->buttons, &(Button){ 0 }); 22 | ButtonCreate(&screen->buttons[3], 3, screen->width / 2 - 100, screen->height / 4 + 72, "Load level.."); 23 | screen->buttons = ListPush(screen->buttons, &(Button){ 0 }); 24 | ButtonCreate(&screen->buttons[4], 4, screen->width / 2 - 100, screen->height / 4 + 120, "Back to game"); 25 | } 26 | 27 | void PauseScreenOnButtonClicked(PauseScreen * screen, Button * button) { 28 | if (button->id == 0) { 29 | OptionsScreen * options = malloc(sizeof(OptionsScreen)); 30 | OptionsScreenCreate(options, screen, &screen->minecraft->settings); 31 | MinecraftSetCurrentScreen(screen->minecraft, options); 32 | } 33 | if (button->id == 1) { 34 | GenerateLevelScreen * generate = malloc(sizeof(GenerateLevelScreen)); 35 | GenerateLevelScreenCreate(generate, screen); 36 | MinecraftSetCurrentScreen(screen->minecraft, generate); 37 | } 38 | if (button->id == 2) { 39 | SaveLevelScreen * saveLevel = malloc(sizeof(SaveLevelScreen)); 40 | SaveLevelScreenCreate(saveLevel, screen); 41 | MinecraftSetCurrentScreen(screen->minecraft, saveLevel); 42 | } 43 | if (button->id == 3) { 44 | LoadLevelScreen * loadLevel = malloc(sizeof(LoadLevelScreen)); 45 | LoadLevelScreenCreate(loadLevel, screen); 46 | MinecraftSetCurrentScreen(screen->minecraft, loadLevel); 47 | } 48 | if (button->id == 4) { 49 | MinecraftGrabMouse(screen->minecraft); 50 | MinecraftSetCurrentScreen(screen->minecraft, NULL); 51 | } 52 | } 53 | 54 | void PauseScreenRender(PauseScreen * screen, int mx, int my) { 55 | ScreenDrawFadingBox(0, 0, screen->width, screen->height, 0x05050060, 0x303060A0); 56 | ScreenDrawCenteredString(screen->font, "Game menu", screen->width / 2, 20, 0xffffffff); 57 | } 58 | -------------------------------------------------------------------------------- /MinecraftC/GUI/PauseScreen.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "GUIScreen.h" 3 | 4 | typedef GUIScreen PauseScreen; 5 | 6 | void PauseScreenCreate(PauseScreen * screen); 7 | void PauseScreenOnOpen(PauseScreen * screen); 8 | void PauseScreenOnButtonClicked(PauseScreen * screen, Button * button); 9 | void PauseScreenRender(PauseScreen * screen, int mx, int my); 10 | -------------------------------------------------------------------------------- /MinecraftC/GUI/SaveLevelScreen.c: -------------------------------------------------------------------------------- 1 | #include "SaveLevelScreen.h" 2 | #include "LevelNameScreen.h" 3 | #include "Screen.h" 4 | #include "../Minecraft.h" 5 | 6 | void SaveLevelScreenCreate(SaveLevelScreen * screen, GUIScreen * parent) { 7 | LoadLevelScreenCreate(screen, parent); 8 | screen->type = GUIScreenTypeSaveLevel; 9 | screen->level.title = "Save level"; 10 | screen->level.parent = parent; 11 | } 12 | 13 | void SaveLevelScreenOnOpen(SaveLevelScreen * screen) { 14 | StringSet(&screen->buttons[5].text, "Save file..."); 15 | } 16 | 17 | void SaveLevelScreenOpenLevel(SaveLevelScreen * screen, int level) { 18 | LevelNameScreen * levelName = malloc(sizeof(LevelNameScreen)); 19 | LevelNameScreenCreate(levelName, screen, screen->buttons[level].text, level); 20 | MinecraftSetCurrentScreen(screen->minecraft, levelName); 21 | } 22 | 23 | void SaveLevelScreenOpenLevelFromFile(SaveLevelScreen * screen, char * file) { 24 | MinecraftSetCurrentScreen(screen->minecraft, screen->level.parent); 25 | } 26 | -------------------------------------------------------------------------------- /MinecraftC/GUI/SaveLevelScreen.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "LoadLevelScreen.h" 3 | 4 | typedef LoadLevelScreen SaveLevelScreen; 5 | 6 | void SaveLevelScreenCreate(SaveLevelScreen * screen, GUIScreen * parent); 7 | void SaveLevelScreenOnOpen(SaveLevelScreen * screen); 8 | void SaveLevelScreenOpenLevel(SaveLevelScreen * screen, int level); 9 | void SaveLevelScreenOpenLevelFromFile(SaveLevelScreen * screen, char * file); 10 | -------------------------------------------------------------------------------- /MinecraftC/GUI/Screen.c: -------------------------------------------------------------------------------- 1 | #include "Screen.h" 2 | #include "../Render/ShapeRenderer.h" 3 | #include "../Utilities/OpenGL.h" 4 | 5 | void ScreenDrawBox(int x0, int y0, int x1, int y1, uint32_t color) { 6 | glEnable(GL_BLEND); 7 | glDisable(GL_TEXTURE_2D); 8 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 9 | glColor4f((color >> 24) / 255.0, ((color >> 16) & 0xff) / 255.0, ((color >> 8) & 0xff) / 255.0, (color & 0xff) / 255.0); 10 | ShapeRendererBegin(); 11 | ShapeRendererVertex(x0, y1, 0.0); 12 | ShapeRendererVertex(x1, y1, 0.0); 13 | ShapeRendererVertex(x1, y0, 0.0); 14 | ShapeRendererVertex(x0, y0, 0.0); 15 | ShapeRendererEnd(); 16 | glEnable(GL_TEXTURE_2D); 17 | glDisable(GL_BLEND); 18 | } 19 | 20 | void ScreenDrawFadingBox(int x0, int y0, int x1, int y1, uint32_t col0, uint32_t col1) { 21 | glEnable(GL_BLEND); 22 | glDisable(GL_TEXTURE_2D); 23 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 24 | glBegin(GL_QUADS); 25 | glColor4f((col0 >> 24) / 255.0, ((col0 >> 16) & 0xff) / 255.0, ((col0 >> 8) & 0xff) / 255.0, (col0 & 0xff) / 255.0); 26 | glVertex2f(x1, y0); 27 | glVertex2f(x0, y0); 28 | glColor4f((col1 >> 24) / 255.0, ((col1 >> 16) & 0xff) / 255.0, ((col1 >> 8) & 0xff) / 255.0, (col1 & 0xff) / 255.0); 29 | glVertex2f(x0, y1); 30 | glVertex2f(x1, y1); 31 | glEnd(); 32 | glEnable(GL_TEXTURE_2D); 33 | glDisable(GL_BLEND); 34 | } 35 | 36 | void ScreenDrawCenteredString(FontRenderer * font, char * str, int x, int y, uint32_t color) { 37 | FontRendererRender(font, str, x - FontRendererGetWidth(font, str) / 2, y, color); 38 | } 39 | 40 | void ScreenDrawString(FontRenderer * font, char * str, int x, int y, uint32_t color) { 41 | FontRendererRender(font, str, x, y, color); 42 | } 43 | 44 | void ScreenDrawImage(int x0, int y0, int x1, int y1, int u, int v, float imgZ) { 45 | float s = 0.00390625; 46 | ShapeRendererBegin(); 47 | ShapeRendererVertexUV(x0, y0 + v, imgZ, x1 * s, (y1 + v) * s); 48 | ShapeRendererVertexUV(x0 + u, y0 + v, imgZ, (x1 + u) * s, (y1 + v) * s); 49 | ShapeRendererVertexUV(x0 + u, y0, imgZ, (x1 + u) * s, y1 * s); 50 | ShapeRendererVertexUV(x0, y0, imgZ, x1 * s, y1 * s); 51 | ShapeRendererEnd(); 52 | } 53 | -------------------------------------------------------------------------------- /MinecraftC/GUI/Screen.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "FontRenderer.h" 3 | 4 | void ScreenDrawBox(int x0, int y0, int x1, int y1, uint32_t color); 5 | void ScreenDrawFadingBox(int x0, int y0, int x1, int y1, uint32_t col0, uint32_t col1); 6 | void ScreenDrawCenteredString(FontRenderer * font, char * str, int x, int y, uint32_t color); 7 | void ScreenDrawString(FontRenderer * font, char * str, int x, int y, uint32_t color); 8 | void ScreenDrawImage(int x0, int y0, int x1, int y1, int u, int v, float imgZ); 9 | -------------------------------------------------------------------------------- /MinecraftC/GameSettings.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include "Utilities/List.h" 6 | #include "Utilities/String.h" 7 | 8 | typedef struct KeyBinding { 9 | char * name; 10 | int key; 11 | } KeyBinding; 12 | 13 | typedef struct GameSettings { 14 | bool music; 15 | bool sound; 16 | bool invertMouse; 17 | bool showFrameRate; 18 | int viewDistance; 19 | bool viewBobbing; 20 | bool anaglyph; 21 | bool limitFramerate; 22 | KeyBinding forwardKey; 23 | KeyBinding leftKey; 24 | KeyBinding backKey; 25 | KeyBinding rightKey; 26 | KeyBinding jumpKey; 27 | KeyBinding buildKey; 28 | KeyBinding chatKey; 29 | KeyBinding toggleFogKey; 30 | KeyBinding saveLocationKey; 31 | KeyBinding loadLocationKey; 32 | List(KeyBinding *) bindings; 33 | #if MINECRAFTC_MODS 34 | bool explodingTNT; 35 | bool raytracing; 36 | bool largerWorldGen; 37 | int modsCount; 38 | #endif 39 | struct Minecraft * minecraft; 40 | String file; 41 | int settingsCount; 42 | } GameSettings; 43 | 44 | void GameSettingsCreate(GameSettings * settings, struct Minecraft * minecraft); 45 | String GameSettingsGetBinding(GameSettings * settings, int binding); 46 | void GameSettingsSetBinding(GameSettings * settings, int binding, int key); 47 | void GameSettingsToggleSetting(GameSettings * settings, int setting); 48 | String GameSettingsGetSetting(GameSettings * settings, int setting); 49 | void GameSettingsDestroy(GameSettings * settings); 50 | -------------------------------------------------------------------------------- /MinecraftC/Level/Generator/LevelGenerator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../../ProgressBarDisplay.h" 3 | #include "../../Utilities/Random.h" 4 | 5 | struct Level; 6 | 7 | typedef struct LevelGenerator { 8 | ProgressBarDisplay * progressBar; 9 | int width, depth, height; 10 | RandomGenerator random; 11 | uint8_t * blocks; 12 | int waterLevel; 13 | int * floodData; 14 | } LevelGenerator; 15 | 16 | void LevelGeneratorCreate(LevelGenerator * generator, ProgressBarDisplay * progressBar); 17 | void LevelGeneratorGenerate(LevelGenerator * generator, int width, int depth, struct Level * level); 18 | void LevelGeneratorDestroy(LevelGenerator * generator); 19 | -------------------------------------------------------------------------------- /MinecraftC/Level/Generator/Noise/CombinedNoise.c: -------------------------------------------------------------------------------- 1 | #include "CombinedNoise.h" 2 | #include 3 | 4 | void CombinedNoiseCreate(CombinedNoise * noise, Noise * n1, Noise * n2) { 5 | NoiseCreate(noise); 6 | noise->type = NoiseTypeCombined; 7 | noise->combined = (struct CombinedNoiseData) { 8 | .noise1 = n1, 9 | .noise2 = n2, 10 | }; 11 | } 12 | 13 | float CombinedNoiseCompute(CombinedNoise * noise, float x, float y) { 14 | return NoiseCompute(noise->combined.noise1, x + NoiseCompute(noise->combined.noise2, x, y), y); 15 | } 16 | -------------------------------------------------------------------------------- /MinecraftC/Level/Generator/Noise/CombinedNoise.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Noise.h" 3 | 4 | typedef Noise CombinedNoise; 5 | 6 | typedef struct CombinedNoiseData CombinedNoiseData; 7 | 8 | void CombinedNoiseCreate(CombinedNoise * noise, Noise * n1, Noise * n2); 9 | float CombinedNoiseCompute(CombinedNoise * noise, float x, float y); 10 | -------------------------------------------------------------------------------- /MinecraftC/Level/Generator/Noise/Noise.c: -------------------------------------------------------------------------------- 1 | #include "Noise.h" 2 | #include "OctaveNoise.h" 3 | #include "CombinedNoise.h" 4 | #include "PerlinNoise.h" 5 | #include 6 | 7 | void NoiseCreate(Noise * noise) { 8 | *noise = (Noise){ 0 }; 9 | } 10 | 11 | float NoiseCompute(Noise * noise, float x, float y) { 12 | if (noise->type == NoiseTypeOctave) { return OctaveNoiseCompute(noise, x, y); } 13 | if (noise->type == NoiseTypePerlin) { return PerlinNoiseCompute(noise, x, y); } 14 | if (noise->type == NoiseTypeCombined) { return CombinedNoiseCompute(noise, x, y); } 15 | return 0.0; 16 | } 17 | 18 | void NoiseDestroy(Noise * noise) { 19 | if (noise->type == NoiseTypeOctave) { OctaveNoiseDestroy(noise); } 20 | } 21 | -------------------------------------------------------------------------------- /MinecraftC/Level/Generator/Noise/Noise.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef enum NoiseType { 4 | NoiseTypeNone, 5 | NoiseTypePerlin, 6 | NoiseTypeOctave, 7 | NoiseTypeCombined, 8 | } NoiseType; 9 | 10 | typedef struct Noise { 11 | NoiseType type; 12 | union { 13 | struct PerlinNoiseData { 14 | int hash[512]; 15 | } perlin; 16 | struct OctaveNoiseData { 17 | int count; 18 | struct Noise * noises; 19 | } octave; 20 | struct CombinedNoiseData { 21 | struct Noise * noise1; 22 | struct Noise * noise2; 23 | } combined; 24 | }; 25 | } Noise; 26 | 27 | void NoiseCreate(Noise * noise); 28 | float NoiseCompute(Noise * noise, float x, float y); 29 | void NoiseDestroy(Noise * noise); 30 | -------------------------------------------------------------------------------- /MinecraftC/Level/Generator/Noise/OctaveNoise.c: -------------------------------------------------------------------------------- 1 | #include "OctaveNoise.h" 2 | #include 3 | 4 | void OctaveNoiseCreate(OctaveNoise * noise, RandomGenerator * random, int octaveCount) { 5 | NoiseCreate(noise); 6 | noise->type = NoiseTypeOctave; 7 | noise->octave = (struct OctaveNoiseData) { 8 | .count = octaveCount, 9 | .noises = malloc(octaveCount * sizeof(PerlinNoise)), 10 | }; 11 | for (int i = 0; i < octaveCount; i++) { 12 | PerlinNoiseCreate(&noise->octave.noises[i], random); 13 | } 14 | } 15 | 16 | float OctaveNoiseCompute(OctaveNoise * noise, float x, float y) { 17 | float a = 0.0; 18 | float b = 1.0; 19 | for (int i = 0; i < noise->octave.count; i++) { 20 | a += NoiseCompute(&noise->octave.noises[i], x / b, y / b) * b; 21 | b *= 2; 22 | } 23 | return a; 24 | } 25 | 26 | void OctaveNoiseDestroy(OctaveNoise * noise) { 27 | free(noise->octave.noises); 28 | } 29 | -------------------------------------------------------------------------------- /MinecraftC/Level/Generator/Noise/OctaveNoise.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Noise.h" 3 | #include "PerlinNoise.h" 4 | 5 | typedef Noise OctaveNoise; 6 | 7 | typedef struct OctaveNoiseData OctaveNoiseData; 8 | 9 | void OctaveNoiseCreate(OctaveNoise * noise, RandomGenerator * random, int octaveCount); 10 | float OctaveNoiseCompute(OctaveNoise * noise, float x, float y); 11 | void OctaveNoiseDestroy(OctaveNoise * noise); 12 | -------------------------------------------------------------------------------- /MinecraftC/Level/Generator/Noise/PerlinNoise.c: -------------------------------------------------------------------------------- 1 | #include "PerlinNoise.h" 2 | #include 3 | #include 4 | 5 | void PerlinNoiseCreate(PerlinNoise * noise, RandomGenerator * random) { 6 | NoiseCreate(noise); 7 | noise->type = NoiseTypePerlin; 8 | for (int i = 0; i < 256; i++) { noise->perlin.hash[i] = i; } 9 | for (int i = 0; i < 256; i++) { 10 | int r1 = (int)RandomGeneratorIntegerRange(random, 0, 256 - i - 1) + i; 11 | int r2 = noise->perlin.hash[i]; 12 | noise->perlin.hash[i] = noise->perlin.hash[r1]; 13 | noise->perlin.hash[r1] = r2; 14 | noise->perlin.hash[i + 256] = noise->perlin.hash[i]; 15 | } 16 | } 17 | 18 | static float F(float x) { 19 | return x * x * x * (x * (x * 6.0 - 15.0) + 10.0); 20 | } 21 | 22 | static float Lerp(float t, float a, float b) { 23 | return a + t * (b - a); 24 | } 25 | 26 | static float Grad(int i, float x, float y, float z) { 27 | i &= 15; 28 | float a = i < 8 ? x : y; 29 | float b = i < 4 ? y : (i != 12 && i != 14 ? z : x); 30 | return ((i & 1) == 0 ? a : -a) + ((i & 2) == 0 ? b : -b); 31 | } 32 | 33 | float PerlinNoiseCompute(PerlinNoise * noise, float x, float y) { 34 | float vx = x, vy = y, vz = 0.0; 35 | int ix = ((int)vx) & 255, iy = ((int)vy) & 255, iz = ((int)vz) & 255; 36 | vx -= floor(vx); 37 | vy -= floor(vy); 38 | vz -= floor(vz); 39 | float xd = F(vx), yd = F(vy), zd = F(vz); 40 | int aaa, aba, aab, abb, baa, bba, bab, bbb; 41 | aaa = noise->perlin.hash[noise->perlin.hash[noise->perlin.hash[ix] + iy] + iz]; 42 | aba = noise->perlin.hash[noise->perlin.hash[noise->perlin.hash[ix] + iy + 1] + iz]; 43 | aab = noise->perlin.hash[noise->perlin.hash[noise->perlin.hash[ix] + iy] + iz + 1]; 44 | abb = noise->perlin.hash[noise->perlin.hash[noise->perlin.hash[ix] + iy + 1] + iz + 1]; 45 | baa = noise->perlin.hash[noise->perlin.hash[noise->perlin.hash[ix + 1] + iy] + iz]; 46 | bba = noise->perlin.hash[noise->perlin.hash[noise->perlin.hash[ix + 1] + iy + 1] + iz]; 47 | bab = noise->perlin.hash[noise->perlin.hash[noise->perlin.hash[ix + 1] + iy] + iz + 1]; 48 | bbb = noise->perlin.hash[noise->perlin.hash[noise->perlin.hash[ix + 1] + iy + 1] + iz + 1]; 49 | float l1 = Lerp(xd, Grad(aaa, vx, vy, vz), Grad(baa, vx - 1.0, vy, vz)); 50 | float l2 = Lerp(xd, Grad(aba, vx, vy - 1.0, vz), Grad(bba, vx - 1.0, vy - 1.0, vz)); 51 | float l3 = Lerp(xd, Grad(aab, vx, vy, vz - 1.0), Grad(bab, vx - 1.0, vy, vz - 1.0)); 52 | float l4 = Lerp(xd, Grad(abb, vx, vy - 1.0, vz - 1.0), Grad(bbb, vx - 1.0, vy - 1.0, vz - 1.0)); 53 | float l = Lerp(zd, Lerp(yd, l1, l2), Lerp(yd, l3, l4)); 54 | return l; 55 | } 56 | -------------------------------------------------------------------------------- /MinecraftC/Level/Generator/Noise/PerlinNoise.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Noise.h" 3 | #include "../../../Utilities/Random.h" 4 | 5 | typedef Noise PerlinNoise; 6 | 7 | typedef struct PerlinNoiseData PerlinNoiseData; 8 | 9 | void PerlinNoiseCreate(PerlinNoise * noise, RandomGenerator * random); 10 | float PerlinNoiseCompute(PerlinNoise * noise, float x, float y); 11 | -------------------------------------------------------------------------------- /MinecraftC/Level/Level.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "Tile/Block.h" 4 | #include "NextTickListEntry.h" 5 | #include "../MovingObjectPosition.h" 6 | #include "../Utilities/List.h" 7 | #include "../Utilities/Random.h" 8 | #include "../Particle/ParticleManager.h" 9 | #include "../Physics/AABB.h" 10 | #include "../GUI/FontRenderer.h" 11 | #include "../Entity.h" 12 | #include "Generator/LevelGenerator.h" 13 | 14 | typedef struct Level { 15 | int width, height, depth; 16 | uint8_t * blocks; 17 | int xSpawn, ySpawn, zSpawn; 18 | float spawnRotation; 19 | struct LevelRenderer * renderer; 20 | int * lightBlockers; 21 | RandomGenerator random; 22 | int randomValue; 23 | List(NextTickListEntry) tickList; 24 | int waterLevel; 25 | uint32_t skyColor; 26 | uint32_t fogColor; 27 | uint32_t cloudColor; 28 | int unprocessed; 29 | int tickCount; 30 | Entity * player; 31 | List(Entity *) entities; 32 | ParticleManager * particleEngine; 33 | LevelGenerator generator; 34 | ProgressBarDisplay * progressBar; 35 | #if MINECRAFTC_MODS 36 | uint8_t * distanceField; 37 | #endif 38 | } Level; 39 | 40 | void LevelCreate(Level * level, ProgressBarDisplay * progressBar, int size); 41 | void LevelRegenerate(Level * level, int size); 42 | bool LevelLoad(Level * level, char * filePath); 43 | bool LevelSave(Level * level, char * filePath, char * name); 44 | void LevelSetData(Level * level, int w, int d, int h, uint8_t * blocks); 45 | #if MINECRAFTC_MODS 46 | void LevelCreateDistanceField(Level * level); 47 | void LevelDestroyDistanceField(Level * level); 48 | #endif 49 | void LevelFindSpawn(Level * level); 50 | void LevelCalculateLightDepths(Level * level, int x0, int y0, int x1, int y1); 51 | void LevelSetRenderer(Level * level, struct LevelRenderer * listener); 52 | bool LevelIsLightBlocker(Level * level, int x, int y, int z); 53 | List(AABB) LevelGetCubes(Level * level, AABB box); 54 | void LevelSwap(Level * level, int x0, int y0, int z0, int x1, int y1, int z1); 55 | bool LevelSetTile(Level * level, int x, int y, int z, BlockType tile); 56 | bool LevelSetTileNoNeighborChange(Level * level, int x, int y, int z, BlockType tile); 57 | void LevelUpdateNeighborsAt(Level * Level, int x, int y, int z, BlockType tile); 58 | bool LevelSetTileNoUpdate(Level * level, int x, int y, int z, BlockType tile); 59 | bool LevelIsLit(Level * level, int x, int y, int z); 60 | BlockType LevelGetTile(Level * level, int x, int y, int z); 61 | bool LevelIsSolidTile(Level * level, int x, int y, int z); 62 | void LevelTickEntities(Level * level); 63 | void LevelTick(Level * level); 64 | bool LevelIsInBounds(Level * level, int x, int y, int z); 65 | float LevelGetGroundLevel(Level * level); 66 | float LevelGetWaterLevel(Level * level); 67 | bool LevelContainsAnyLiquid(Level * level, AABB box); 68 | bool LevelContainsLiquid(Level * level, AABB box, LiquidType liquidID); 69 | void LevelAddToNextTick(Level * level, int x, int y, int z, BlockType tile); 70 | bool LevelIsSolidSearch(Level * level, float x, float y, float z, float radius); 71 | int LevelGetHighestTile(Level * level, int x, int z); 72 | void LevelSetSpawnPosition(Level * level, int x, int y, int z, float rotation); 73 | float LevelGetBrightness(Level * level, int x, int y, int z); 74 | bool LevelIsWater(Level * level, int x, int y, int z); 75 | MovingObjectPosition LevelClip(Level * level, Vector3D v0, Vector3D v1); 76 | void LevelPlaySound(Level * level, char * sound, Entity * entity, float volume, float pitch); 77 | void LevelPlaySoundAt(Level * level, char * sound, float x, float y, float z, float volume, float pitch); 78 | bool LevelMaybeGrowTree(Level * level, int x, int y, int z); 79 | Entity * LevelGetPlayer(Level * level); 80 | void LevelAddEntity(Level * level, Entity * entity); 81 | void LevelRenderEntities(Level * level, TextureManager * textures, float dt); 82 | void LevelExplode(Level * level, float x, float y, float z, float radius); 83 | Entity * LevelFindPlayer(Level * level); 84 | void LevelDestroy(Level * level); 85 | -------------------------------------------------------------------------------- /MinecraftC/Level/NextTickListEntry.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef struct NextTickListEntry { 4 | int x, y, z; 5 | BlockType Tile; 6 | int Ticks; 7 | } NextTickListEntry; 8 | -------------------------------------------------------------------------------- /MinecraftC/Level/Tile/Block.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "TileSound.h" 3 | #include "../../Utilities/Random.h" 4 | #include "../../Physics/AABB.h" 5 | #include "../../Particle/ParticleManager.h" 6 | 7 | typedef enum BlockType { 8 | BlockTypeNone, 9 | BlockTypeStone, 10 | BlockTypeGrass, 11 | BlockTypeDirt, 12 | BlockTypeCobbleStone, 13 | BlockTypeWood, 14 | BlockTypeSapling, 15 | BlockTypeBedrock, 16 | BlockTypeWater, 17 | BlockTypeStillWater, 18 | BlockTypeLava, 19 | BlockTypeStillLava, 20 | BlockTypeSand, 21 | BlockTypeGravel, 22 | BlockTypeGoldOre, 23 | BlockTypeIronOre, 24 | BlockTypeCoalOre, 25 | BlockTypeLog, 26 | BlockTypeLeaves, 27 | BlockTypeSponge, 28 | BlockTypeGlass, 29 | BlockTypeRedWool, 30 | BlockTypeOrangeWool, 31 | BlockTypeYellowWool, 32 | BlockTypeLimeWool, 33 | BlockTypeGreenWool, 34 | BlockTypeAquaGreenWool, 35 | BlockTypeCyanWool, 36 | BlockTypeBlueWool, 37 | BlockTypePurpleWool, 38 | BlockTypeIndigoWool, 39 | BlockTypeVioletWool, 40 | BlockTypeMagentaWool, 41 | BlockTypePinkWool, 42 | BlockTypeBlackWool, 43 | BlockTypeGrayWool, 44 | BlockTypeWhiteWool, 45 | BlockTypeDandelion, 46 | BlockTypeRose, 47 | BlockTypeBrownMushroom, 48 | BlockTypeRedMushroom, 49 | BlockTypeGold, 50 | BlockTypeIron, 51 | BlockTypeDoubleSlab, 52 | BlockTypeSlab, 53 | BlockTypeBrick, 54 | BlockTypeTNT, 55 | BlockTypeBookshelf, 56 | BlockTypeMossyCobbleStone, 57 | BlockTypeObsidian, 58 | BlockTypeCount, 59 | } BlockType; 60 | 61 | typedef enum LiquidType { 62 | LiquidTypeNone, 63 | LiquidTypeWater, 64 | LiquidTypeLava, 65 | } LiquidType; 66 | 67 | typedef struct Block { 68 | int textureID; 69 | TileSound sound; 70 | bool explodable; 71 | float x0, y0, z0; 72 | float x1, y1, z1; 73 | float particleGravity; 74 | BlockType type; 75 | union { 76 | struct LiquidBlockData { 77 | LiquidType type; 78 | BlockType stillID; 79 | BlockType movingID; 80 | } liquid; 81 | struct SlabBlockData { 82 | bool doubleSlab; 83 | } slab; 84 | }; 85 | } Block; 86 | 87 | void BlockCreate(Block * block, BlockType type, int textureID, TileSound sound, float particleGravity); 88 | bool BlockIsCube(Block * block); 89 | void BlockSetPhysics(Block * block, bool physics); 90 | void BlockSetBounds(Block * block, float x0, float y0, float z0, float x1, float y1, float z1); 91 | void BlockRenderFullBrightness(Block * block); 92 | float BlockGetBrightness(Block * block, struct Level * level, int x, int y, int z); 93 | bool BlockCanRenderSide(Block * block, struct Level * level, int x, int y, int z, int side); 94 | int BlockGetTextureID(Block * block, int side); 95 | void BlockRenderInside(Block * block, int x, int y, int z, int side); 96 | void BlockRenderSideWithTexture(Block * block, int x, int y, int z, int side, int tex); 97 | void BlockRenderSide(Block * block, int x, int y, int z, int side); 98 | AABB BlockGetSelectionAABB(Block * block, int x, int y, int z); 99 | AABB BlockGetCollisionAABB(Block * block, int x, int y, int z); 100 | bool BlockIsOpaque(Block * block); 101 | bool BlockIsSolid(Block * block); 102 | void BlockUpdate(Block * block, struct Level * level, int x, int y, int z, RandomGenerator * random); 103 | void BlockSpawnBreakParticles(Block * block, struct Level * level, int x, int y, int z, ParticleManager * particles, GameSettings * settings); 104 | LiquidType BlockGetLiquidType(Block * block); 105 | void BlockOnNeighborChanged(Block * block, struct Level * level, int x, int y, int z, BlockType tile); 106 | void BlockOnPlaced(Block * block, struct Level * level, int x, int y, int z); 107 | int BlockGetTickDelay(Block * block); 108 | void BlockOnAdded(Block * block, struct Level * level, int x, int y, int z); 109 | void BlockOnRemoved(Block * block, struct Level * level, int x, int y, int z); 110 | void BlockRenderPreview(Block * block); 111 | bool BlockCanExplode(Block * block); 112 | MovingObjectPosition BlockClip(Block * block, int x, int y, int z, Vector3D v0, Vector3D v1); 113 | void BlockExplode(Block * block, struct Level * level, int x, int y, int z); 114 | bool BlockRender(Block * block, struct Level * level, int x, int y, int z); 115 | int BlockGetRenderPass(Block * block); 116 | 117 | extern struct Blocks { 118 | Block table[256]; 119 | bool physics[256]; 120 | bool liquid[256]; 121 | } Blocks; 122 | 123 | void BlocksInitialize(void); 124 | -------------------------------------------------------------------------------- /MinecraftC/Level/Tile/BookshelfBlock.c: -------------------------------------------------------------------------------- 1 | #include "BookshelfBlock.h" 2 | 3 | void BookshelfBlockCreate(BookshelfBlock * block, TileSound sound, float particleGravity) { 4 | BlockCreate(block, BlockTypeBookshelf, 35, sound, particleGravity); 5 | } 6 | 7 | int BookshelfBlockGetTextureID(BookshelfBlock * block, int face) { 8 | return face <= 1 ? 4 : block->textureID; 9 | } 10 | -------------------------------------------------------------------------------- /MinecraftC/Level/Tile/BookshelfBlock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Block.h" 3 | 4 | typedef Block BookshelfBlock; 5 | 6 | void BookshelfBlockCreate(BookshelfBlock * block, TileSound sound, float particleGravity); 7 | int BookshelfBlockGetTextureID(BookshelfBlock * block, int face); 8 | -------------------------------------------------------------------------------- /MinecraftC/Level/Tile/FlowerBlock.c: -------------------------------------------------------------------------------- 1 | #include "FlowerBlock.h" 2 | #include "MushroomBlock.h" 3 | #include "SaplingBlock.h" 4 | #include "../Level.h" 5 | #include "../../Render/ShapeRenderer.h" 6 | #include "../../Utilities/SinTable.h" 7 | 8 | void FlowerBlockCreate(FlowerBlock * block, BlockType type, int textureID, TileSound sound, float particleGravity) { 9 | BlockCreate(block, type, textureID, sound, particleGravity); 10 | BlockSetPhysics(block, true); 11 | float w = 0.2; 12 | BlockSetBounds(block, 0.5 - w, 0.0, 0.5 - w, 0.5 + w, 3.0 * w, 0.5 + w); 13 | } 14 | 15 | void FlowerBlockUpdate(FlowerBlock * block, Level * level, int x, int y, int z, RandomGenerator * random) { 16 | if (block->type == BlockTypeRedMushroom || block->type == BlockTypeBrownMushroom) { MushroomBlockUpdate(block, level, x, y, z, random); return; } 17 | if (block->type == BlockTypeSapling) { SaplingBlockUpdate(block, level, x, y, z, random); return; } 18 | 19 | BlockType tile = LevelGetTile(level, x, y - 1, z); 20 | if (!LevelIsLit(level, x, y, z) || (tile != BlockTypeDirt && tile != BlockTypeGrass)) { 21 | LevelSetTile(level, x, y, z, BlockTypeNone); 22 | } 23 | } 24 | 25 | AABB FlowerBlockGetCollisionAABB(FlowerBlock * block, int x, int y, int z) { 26 | return (AABB){ .null = true }; 27 | } 28 | 29 | bool FlowerBlockIsOpaque(FlowerBlock * block) { 30 | return false; 31 | } 32 | 33 | bool FlowerBlockIsSolid(FlowerBlock * block) { 34 | return false; 35 | } 36 | 37 | static void Render(FlowerBlock * block, float x, float y, float z) { 38 | int tex = BlockGetTextureID(block, 15); 39 | int u0 = (tex % 16) << 4; 40 | int v0 = (tex / 16) << 4; 41 | float u1 = u0 / 256.0; 42 | float v1 = v0 / 256.0; 43 | float u2 = (u0 + 15.99) / 256.0; 44 | float v2 = (v0 + 15.99) / 256.0; 45 | for (int i = 0; i < 2; i++) { 46 | float s = tsin(i * M_PI / 2.0 + M_PI / 4.0) * 0.5; 47 | float c = tcos(i * M_PI / 2.0 + M_PI / 4.0) * 0.5; 48 | float x1 = x + 0.5 - s; 49 | float y1 = y + 1.0; 50 | float z1 = z + 0.5 - c; 51 | s += x + 0.5; 52 | c += z + 0.5; 53 | ShapeRendererVertexUV(x1, y1, z1, u2, v1); 54 | ShapeRendererVertexUV(s, y1, c, u1, v1); 55 | ShapeRendererVertexUV(s, y, c, u1, v2); 56 | ShapeRendererVertexUV(x1, y, z1, u2, v2); 57 | ShapeRendererVertexUV(s, y1, c, u2, v1); 58 | ShapeRendererVertexUV(x1, y1, z1, u1, v1); 59 | ShapeRendererVertexUV(x1, y, z1, u1, v2); 60 | ShapeRendererVertexUV(s, y, c, u2, v2); 61 | } 62 | } 63 | 64 | void FlowerBlockRenderPreview(FlowerBlock * block) { 65 | ShapeRendererNormal(0.0, 1.0, 0.0); 66 | ShapeRendererBegin(); 67 | Render(block, 0.0, 0.4, -0.3); 68 | ShapeRendererEnd(); 69 | } 70 | 71 | bool FlowerBlockIsCube(FlowerBlock * block) { 72 | return false; 73 | } 74 | 75 | bool FlowerBlockRender(FlowerBlock * block, Level * level, int x, int y, int z) { 76 | float brightness = LevelGetBrightness(level, x, y, z); 77 | ShapeRendererColorf(brightness, brightness, brightness); 78 | Render(block, x, y, z); 79 | return true; 80 | } 81 | 82 | void FlowerBlockRenderFullBrightness(FlowerBlock * block) { 83 | ShapeRendererColorf(1.0, 1.0, 1.0); 84 | Render(block, -2.0, 0.0, 0.0); 85 | } 86 | -------------------------------------------------------------------------------- /MinecraftC/Level/Tile/FlowerBlock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Block.h" 3 | 4 | typedef Block FlowerBlock; 5 | 6 | void FlowerBlockCreate(FlowerBlock * block, BlockType type, int textureID, TileSound sound, float particleGravity); 7 | void FlowerBlockUpdate(FlowerBlock * block, struct Level * level, int x, int y, int z, RandomGenerator * random); 8 | AABB FlowerBlockGetCollisionAABB(FlowerBlock * block, int x, int y, int z); 9 | bool FlowerBlockIsOpaque(FlowerBlock * block); 10 | bool FlowerBlockIsSolid(FlowerBlock * block); 11 | void FlowerBlockRenderPreview(FlowerBlock * block); 12 | bool FlowerBlockIsCube(FlowerBlock * block); 13 | bool FlowerBlockRender(FlowerBlock * block, struct Level * level, int x, int y, int z); 14 | void FlowerBlockRenderFullBrightness(FlowerBlock * block); 15 | -------------------------------------------------------------------------------- /MinecraftC/Level/Tile/GlassBlock.c: -------------------------------------------------------------------------------- 1 | #include "GlassBlock.h" 2 | #include "../Level.h" 3 | 4 | void GlassBlockCreate(GlassBlock * block, TileSound sound, float particleGravity) { 5 | BlockCreate(block, BlockTypeGlass, 49, sound, particleGravity); 6 | } 7 | 8 | bool GlassBlockCanRenderSide(GlassBlock * block, Level * level, int x, int y, int z, int side) { 9 | BlockType tile = LevelGetTile(level, x, y, z); 10 | return tile == block->type ? false : !LevelIsSolidTile(level, x, y, z); 11 | } 12 | 13 | bool GlassBlockIsOpaque(GlassBlock * block) { 14 | return false; 15 | } 16 | 17 | bool GlassBlockIsSolid(GlassBlock * block) { 18 | return false; 19 | } 20 | -------------------------------------------------------------------------------- /MinecraftC/Level/Tile/GlassBlock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Block.h" 3 | 4 | typedef Block GlassBlock; 5 | 6 | void GlassBlockCreate(GlassBlock * block, TileSound sound, float particleGravity); 7 | bool GlassBlockCanRenderSide(GlassBlock * block, struct Level * level, int x, int y, int z, int side); 8 | bool GlassBlockIsOpaque(GlassBlock * block); 9 | bool GlassBlockIsSolid(GlassBlock * block); 10 | -------------------------------------------------------------------------------- /MinecraftC/Level/Tile/GrassBlock.c: -------------------------------------------------------------------------------- 1 | #include "GrassBlock.h" 2 | #include "../Level.h" 3 | 4 | void GrassBlockCreate(GrassBlock * block, TileSound sound, float particleGravity) { 5 | BlockCreate(block, BlockTypeGrass, 3, sound, particleGravity); 6 | BlockSetPhysics(block, true); 7 | } 8 | 9 | int GrassBlockGetTextureID(GrassBlock * block, int side) { 10 | return side == 1 ? 0 : (side == 0 ? 2 : 3); 11 | } 12 | 13 | void GrassBlockUpdate(GrassBlock * block, Level * level, int x, int y, int z, RandomGenerator * random) { 14 | if (RandomGeneratorIntegerRange(random, 0, 3) == 0) { 15 | if (!LevelIsLit(level, x, y, z)) { 16 | LevelSetTile(level, x, y, z, BlockTypeDirt); 17 | } else { 18 | for (int i = 0; i < 4; i++) { 19 | int vx = x + (int)RandomGeneratorIntegerRange(random, 0, 2) - 1; 20 | int vy = y + (int)RandomGeneratorIntegerRange(random, 0, 4) - 3; 21 | int vz = z + (int)RandomGeneratorIntegerRange(random, 0, 2) - 1; 22 | if (LevelGetTile(level, vx, vy, vz) == BlockTypeDirt && LevelIsLit(level, vx, vy, vz)) { LevelSetTile(level, vx, vy, vz, BlockTypeGrass); } 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /MinecraftC/Level/Tile/GrassBlock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Block.h" 3 | 4 | typedef Block GrassBlock; 5 | 6 | void GrassBlockCreate(GrassBlock * block, TileSound sound, float particleGravity); 7 | int GrassBlockGetTextureID(GrassBlock * block, int side); 8 | void GrassBlockUpdate(GrassBlock * block, struct Level * level, int x, int y, int z, RandomGenerator * random); 9 | -------------------------------------------------------------------------------- /MinecraftC/Level/Tile/LeavesBlock.c: -------------------------------------------------------------------------------- 1 | #include "LeavesBlock.h" 2 | #include "../Level.h" 3 | 4 | void LeavesBlockCreate(LeavesBlock * block, TileSound sound, float particleGravity) { 5 | BlockCreate(block, BlockTypeLeaves, 22, sound, particleGravity); 6 | } 7 | 8 | bool LeavesBlockCanRenderSide(LeavesBlock * block, Level * level, int x, int y, int z, int side) { 9 | return !LevelIsSolidTile(level, x, y, z); 10 | } 11 | 12 | bool LeavesBlockIsSolid(LeavesBlock * block) { 13 | return false; 14 | } 15 | 16 | bool LeavesBlockIsOpaque(LeavesBlock * block) { 17 | return false; 18 | } 19 | -------------------------------------------------------------------------------- /MinecraftC/Level/Tile/LeavesBlock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Block.h" 3 | 4 | typedef Block LeavesBlock; 5 | 6 | void LeavesBlockCreate(LeavesBlock * block, TileSound sound, float particleGravity); 7 | bool LeavesBlockCanRenderSide(LeavesBlock * block, struct Level * level, int x, int y, int z, int side); 8 | bool LeavesBlockIsSolid(LeavesBlock * block); 9 | bool LeavesBlockIsOpaque(LeavesBlock * block); 10 | -------------------------------------------------------------------------------- /MinecraftC/Level/Tile/LiquidBlock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Block.h" 3 | 4 | typedef Block LiquidBlock; 5 | 6 | void LiquidBlockCreate(LiquidBlock * block, BlockType blockType, LiquidType liquidType, TileSound sound, float particleGravity); 7 | bool LiquidBlockIsCube(LiquidBlock * block); 8 | void LiquidBlockOnPlaced(LiquidBlock * block, struct Level * level, int x, int y, int z); 9 | void LiquidBlockUpdate(LiquidBlock * block, struct Level * level, int x, int y, int z, RandomGenerator * random); 10 | float LiquidBlockGetBrightness(LiquidBlock * block, struct Level * level, int x, int y, int z); 11 | bool LiquidBlockCanRenderSide(LiquidBlock * block, struct Level * level, int x, int y, int z, int side); 12 | void LiquidBlockRenderInside(LiquidBlock * block, int x, int y, int z, int side); 13 | AABB LiquidBlockGetSelectionAABB(LiquidBlock * block, int x, int y, int z); 14 | bool LiquidBlockIsOpaque(LiquidBlock * block); 15 | bool LiquidBlockIsSolid(LiquidBlock * block); 16 | LiquidType LiquidBlockGetLiquidType(LiquidBlock * block); 17 | void LiquidBlockOnNeighborChanged(LiquidBlock * block, struct Level * level, int x, int y, int z, BlockType tile); 18 | int LiquidBlockGetTickDelay(LiquidBlock * block); 19 | int LiquidBlockGetRenderPass(LiquidBlock * block); 20 | -------------------------------------------------------------------------------- /MinecraftC/Level/Tile/LogBlock.c: -------------------------------------------------------------------------------- 1 | #include "LogBlock.h" 2 | 3 | void LogBlockCreate(LogBlock * block, TileSound sound, float particleGravity) { 4 | BlockCreate(block, BlockTypeLog, 20, sound, particleGravity); 5 | } 6 | 7 | int LogBlockGetTextureID(LogBlock * block, int face) { 8 | return face == 1 ? 21 : (face == 0 ? 21 : 20); 9 | } 10 | -------------------------------------------------------------------------------- /MinecraftC/Level/Tile/LogBlock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Block.h" 3 | 4 | typedef Block LogBlock; 5 | 6 | void LogBlockCreate(LogBlock * block, TileSound sound, float particleGravity); 7 | int LogBlockGetTextureID(LogBlock * block, int face); 8 | -------------------------------------------------------------------------------- /MinecraftC/Level/Tile/MetalBlock.c: -------------------------------------------------------------------------------- 1 | #include "MetalBlock.h" 2 | 3 | void MetalBlockCreate(MetalBlock * block, BlockType type, int textureID, TileSound sound, float particleGravity) { 4 | BlockCreate(block, type, textureID, sound, particleGravity); 5 | } 6 | 7 | int MetalBlockGetTextureID(MetalBlock * block, int face) { 8 | return face == 1 ? block->textureID - 16 : (face == 0 ? block->textureID + 16 : block->textureID); 9 | } 10 | -------------------------------------------------------------------------------- /MinecraftC/Level/Tile/MetalBlock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Block.h" 3 | 4 | typedef Block MetalBlock; 5 | 6 | void MetalBlockCreate(MetalBlock * block, BlockType type, int textureID, TileSound sound, float particleGravity); 7 | int MetalBlockGetTextureID(MetalBlock * block, int face); 8 | -------------------------------------------------------------------------------- /MinecraftC/Level/Tile/MushroomBlock.c: -------------------------------------------------------------------------------- 1 | #include "MushroomBlock.h" 2 | #include "../Level.h" 3 | 4 | void MushroomBlockCreate(MushroomBlock * block, BlockType type, int textureID, TileSound sound, float particleGravity) { 5 | FlowerBlockCreate(block, type, textureID, sound, particleGravity); 6 | BlockSetBounds(block, 0.3, 0.0, 0.3, 0.7, 0.4, 0.7); 7 | } 8 | 9 | void MushroomBlockUpdate(MushroomBlock * block, Level * level, int x, int y, int z, RandomGenerator * random) { 10 | BlockType tile = LevelGetTile(level, x, y - 1, z); 11 | if (LevelIsLit(level, x, y, z) || (tile != BlockTypeStone && tile != BlockTypeGravel && tile != BlockTypeCobbleStone)) { 12 | LevelSetTile(level, x, y, z, BlockTypeNone); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /MinecraftC/Level/Tile/MushroomBlock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "FlowerBlock.h" 3 | 4 | typedef FlowerBlock MushroomBlock; 5 | 6 | void MushroomBlockCreate(MushroomBlock * block, BlockType type, int textureID, TileSound sound, float particleGravity); 7 | void MushroomBlockUpdate(MushroomBlock * block, struct Level * level, int x, int y, int z, RandomGenerator * random); 8 | -------------------------------------------------------------------------------- /MinecraftC/Level/Tile/SandBlock.c: -------------------------------------------------------------------------------- 1 | #include "SandBlock.h" 2 | #include "../Level.h" 3 | 4 | void SandBlockCreate(SandBlock * block, BlockType type, int texture, TileSound sound, float particleGravity) { 5 | BlockCreate(block, type, texture, sound, particleGravity); 6 | } 7 | 8 | static void Fall(SandBlock * block, Level * level, int x, int y, int z) { 9 | int vx = x, vy = y, vz = z; 10 | while (true) { 11 | BlockType tile = LevelGetTile(level, vx, vy - 1, vz); 12 | LiquidType liquidTile = tile == BlockTypeNone ? LiquidTypeNone : BlockGetLiquidType(&Blocks.table[tile]); 13 | if (!(tile == BlockTypeNone ? true : (liquidTile == LiquidTypeWater ? true : liquidTile == LiquidTypeLava)) || vy <= 0) { 14 | if (y != vy) { 15 | tile = LevelGetTile(level, vx, vy, vz); 16 | if (tile != BlockTypeNone && BlockGetLiquidType(&Blocks.table[tile]) != LiquidTypeNone) { 17 | LevelSetTileNoUpdate(level, vx, vy, vz, BlockTypeNone); 18 | } 19 | LevelSwap(level, x, y, z, vx, vy, vz); 20 | } 21 | return; 22 | } 23 | vy--; 24 | } 25 | } 26 | 27 | void SandBlockOnNeighborChanged(SandBlock * block, Level * level, int x, int y, int z, BlockType tile) { 28 | Fall(block, level, x, y, z); 29 | } 30 | 31 | void SandBlockOnPlaced(SandBlock * block, Level * level, int x, int y, int z) { 32 | Fall(block, level, x, y, z); 33 | } 34 | -------------------------------------------------------------------------------- /MinecraftC/Level/Tile/SandBlock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Block.h" 3 | 4 | typedef Block SandBlock; 5 | 6 | void SandBlockCreate(SandBlock * block, BlockType type, int texture, TileSound sound, float particleGravity); 7 | void SandBlockOnNeighborChanged(SandBlock * block, struct Level * level, int x, int y, int z, BlockType tile); 8 | void SandBlockOnPlaced(SandBlock * block, struct Level * level, int x, int y, int z); 9 | -------------------------------------------------------------------------------- /MinecraftC/Level/Tile/SaplingBlock.c: -------------------------------------------------------------------------------- 1 | #include "SaplingBlock.h" 2 | #include "../Level.h" 3 | 4 | void SaplingBlockCreate(SaplingBlock * block, TileSound sound, float particleGravity) { 5 | FlowerBlockCreate(block, BlockTypeSapling, 15, sound, particleGravity); 6 | BlockSetBounds(block, 0.1, 0.0, 0.1, 0.9, 0.8, 0.9); 7 | } 8 | 9 | void SaplingBlockUpdate(SaplingBlock * block, Level * level, int x, int y, int z, RandomGenerator * random) { 10 | BlockType tile = LevelGetTile(level, x, y - 1, z); 11 | if (LevelIsLit(level, x, y, z) && (tile == BlockTypeDirt || tile == BlockTypeGrass)) { 12 | if (RandomIntegerRange(0, 4) == 0) { 13 | LevelSetTileNoUpdate(level, x, y, z, BlockTypeNone); 14 | if (!LevelMaybeGrowTree(level, x, y, z)) { LevelSetTileNoUpdate(level, x, y, z, block->type); } 15 | } 16 | } else { LevelSetTile(level, x, y, z, BlockTypeNone); } 17 | } 18 | -------------------------------------------------------------------------------- /MinecraftC/Level/Tile/SaplingBlock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "FlowerBlock.h" 3 | 4 | typedef FlowerBlock SaplingBlock; 5 | 6 | void SaplingBlockCreate(SaplingBlock * block, TileSound sound, float particleGravity); 7 | void SaplingBlockUpdate(SaplingBlock * block, struct Level * level, int x, int y, int z, RandomGenerator * random); 8 | -------------------------------------------------------------------------------- /MinecraftC/Level/Tile/SlabBlock.c: -------------------------------------------------------------------------------- 1 | #include "SlabBlock.h" 2 | #include "../Level.h" 3 | 4 | void SlabBlockCreate(SlabBlock * block, BlockType type, bool doubleSlab, TileSound sound, float particleGravity) { 5 | BlockCreate(block, type, 6, sound, particleGravity); 6 | block->slab.doubleSlab = doubleSlab; 7 | if (!doubleSlab) { BlockSetBounds(block, 0, 0, 0, 1, 0.5, 1); } 8 | } 9 | 10 | int SlabBlockGetTextureID(SlabBlock * block, int face) { 11 | return face <= 1 ? 6 : 5; 12 | } 13 | 14 | bool SlabBlockIsSolid(SlabBlock * block) { 15 | return block->type == BlockTypeDoubleSlab; 16 | } 17 | 18 | void SlabBlockOnNeighborChanged(SlabBlock * block, Level * level, int x, int y, int z, int side) { 19 | if (block->type == BlockTypeSlab) { 20 | } 21 | } 22 | 23 | void SlabBlockOnAdded(SlabBlock * block, Level * level, int x, int y, int z) { 24 | if (LevelGetTile(level, x, y - 1, z) == BlockTypeSlab) { 25 | LevelSetTile(level, x, y, z, BlockTypeNone); 26 | LevelSetTile(level, x, y - 1, z, BlockTypeDoubleSlab); 27 | } 28 | } 29 | 30 | bool SlabBlockIsCube(SlabBlock * block) { 31 | return block->type == BlockTypeDoubleSlab; 32 | } 33 | 34 | bool SlabBlockCanRenderSide(SlabBlock * block, Level * level, int x, int y, int z, int side) { 35 | return side == 1 ? true : (LevelIsSolidTile(level, x, y, z) ? false : (side == 0 ? true : LevelGetTile(level, x, y, z) != block->type)); 36 | } 37 | -------------------------------------------------------------------------------- /MinecraftC/Level/Tile/SlabBlock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Block.h" 3 | 4 | typedef Block SlabBlock; 5 | 6 | void SlabBlockCreate(SlabBlock * block, BlockType type, bool doubleSlab, TileSound sound, float particleGravity); 7 | int SlabBlockGetTextureID(SlabBlock * block, int face); 8 | bool SlabBlockIsSolid(SlabBlock * block); 9 | void SlabBlockOnNeighborChanged(SlabBlock * block, struct Level * level, int x, int y, int z, int side); 10 | void SlabBlockOnAdded(SlabBlock * block, struct Level * level, int x, int y, int z); 11 | bool SlabBlockIsCube(SlabBlock * block); 12 | bool SlabBlockCanRenderSide(SlabBlock * block, struct Level * level, int x, int y, int z, int side); 13 | -------------------------------------------------------------------------------- /MinecraftC/Level/Tile/SpongeBlock.c: -------------------------------------------------------------------------------- 1 | #include "SpongeBlock.h" 2 | #include "../Level.h" 3 | 4 | void SpongeBlockCreate(SpongeBlock * block, TileSound sound, float particleGravity) { 5 | BlockCreate(block, BlockTypeSponge, 48, sound, particleGravity); 6 | } 7 | 8 | void SpongeBlockOnAdded(SpongeBlock * block, Level * level, int x, int y, int z) { 9 | for (int i = x - 2; i <= x + 2; i++) { 10 | for (int j = y - 2; j <= y + 2; j++) { 11 | for (int k = z - 2; k <= z + 2; k++) { 12 | if (LevelIsWater(level, i, j, k)) { LevelSetTileNoNeighborChange(level, i, j, k, BlockTypeNone); } 13 | } 14 | } 15 | } 16 | } 17 | 18 | void SpongeBlockOnRemoved(SpongeBlock * block, Level * level, int x, int y, int z) { 19 | for (int i = x - 2; i <= x + 2; i++) { 20 | for (int j = y - 2; j <= y + 2; j++) { 21 | for (int k = z - 2; k <= z + 2; k++) { 22 | LevelUpdateNeighborsAt(level, i, j, k, LevelGetTile(level, i, j, k)); 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /MinecraftC/Level/Tile/SpongeBlock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Block.h" 3 | 4 | typedef Block SpongeBlock; 5 | 6 | void SpongeBlockCreate(SpongeBlock * block, TileSound sound, float particleGravity); 7 | void SpongeBlockOnAdded(SpongeBlock * block, struct Level * level, int x, int y, int z); 8 | void SpongeBlockOnRemoved(SpongeBlock * block, struct Level * level, int x, int y, int z); 9 | -------------------------------------------------------------------------------- /MinecraftC/Level/Tile/StillLiquidBlock.c: -------------------------------------------------------------------------------- 1 | #include "StillLiquidBlock.h" 2 | #include "../Level.h" 3 | 4 | void StillLiquidBlockCreate(StillLiquidBlock * block, BlockType blockType, LiquidType liquidType, TileSound sound, float particleGravity) { 5 | LiquidBlockCreate(block, blockType, liquidType, sound, particleGravity); 6 | block->liquid.movingID = blockType - 1; 7 | block->liquid.stillID = blockType; 8 | BlockSetPhysics(block, false); 9 | } 10 | 11 | void StillLiquidBlockUpdate(StillLiquidBlock * block, Level * level, int x, int y, int z, RandomGenerator * random) { 12 | return; 13 | } 14 | 15 | void StillLiquidBlockOnNeighborChanged(StillLiquidBlock * block, Level * level, int x, int y, int z, BlockType tile) { 16 | bool update = false; 17 | if (LevelGetTile(level, x - 1, y, z) == BlockTypeNone) { update = true; } 18 | if (LevelGetTile(level, x + 1, y, z) == BlockTypeNone) { update = true; } 19 | if (LevelGetTile(level, x, y - 1, z) == BlockTypeNone) { update = true; } 20 | if (LevelGetTile(level, x, y, z - 1) == BlockTypeNone) { update = true; } 21 | if (LevelGetTile(level, x, y, z + 1) == BlockTypeNone) { update = true; } 22 | if (tile != BlockTypeNone) { 23 | LiquidType liquidType = BlockGetLiquidType(&Blocks.table[tile]); 24 | if ((block->liquid.type == LiquidTypeWater && liquidType == LiquidTypeLava) || (liquidType == LiquidTypeWater && block->liquid.type == LiquidTypeLava)) { 25 | LevelSetTile(level, x, y, z, BlockTypeStone); 26 | return; 27 | } 28 | } 29 | if (update) { 30 | LevelSetTileNoUpdate(level, x, y, z, block->liquid.movingID); 31 | LevelAddToNextTick(level, x, y, z, block->liquid.movingID); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /MinecraftC/Level/Tile/StillLiquidBlock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "LiquidBlock.h" 3 | 4 | typedef LiquidBlock StillLiquidBlock; 5 | 6 | void StillLiquidBlockCreate(StillLiquidBlock * block, BlockType blockType, LiquidType liquidType, TileSound sound, float particleGravity); 7 | void StillLiquidBlockUpdate(StillLiquidBlock * block, struct Level * level, int x, int y, int z, RandomGenerator * random); 8 | void StillLiquidBlockOnNeighborChanged(StillLiquidBlock * block, struct Level * level, int x, int y, int z, BlockType tile); 9 | -------------------------------------------------------------------------------- /MinecraftC/Level/Tile/TNTBlock.c: -------------------------------------------------------------------------------- 1 | #include "TNTBlock.h" 2 | #include "../Level.h" 3 | #include "../../Mods/PrimedTNT.h" 4 | 5 | void TNTBlockCreate(TNTBlock * block, TileSound sound, float particleGravity) { 6 | BlockCreate(block, BlockTypeTNT, 8, sound, particleGravity); 7 | } 8 | 9 | int TNTBlockGetTextureID(TNTBlock * block, int face) { 10 | return face == 0 ? block->textureID + 2 : (face == 1 ? block->textureID + 1 : block->textureID); 11 | } 12 | 13 | void TNTBlockExplode(TNTBlock * block, Level * level, int x, int y, int z) { 14 | #if MINECRAFTC_MODS 15 | PrimedTNT * tnt = malloc(sizeof(PrimedTNT)); 16 | PrimedTNTCreate(tnt, level, x + 0.5, y + 0.5, z + 0.5); 17 | tnt->tnt.life = RandomIntegerRange(5, 14); 18 | LevelAddEntity(level, tnt); 19 | #endif 20 | } 21 | 22 | void TNTBlockSpawnBreakParticles(TNTBlock * block, Level * level, int x, int y, int z, ParticleManager * particles) { 23 | #if MINECRAFTC_MODS 24 | PrimedTNT * tnt = malloc(sizeof(PrimedTNT)); 25 | PrimedTNTCreate(tnt, level, x + 0.5, y + 0.5, z + 0.5f); 26 | LevelAddEntity(level, tnt); 27 | #endif 28 | } 29 | -------------------------------------------------------------------------------- /MinecraftC/Level/Tile/TNTBlock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Block.h" 3 | 4 | typedef Block TNTBlock; 5 | 6 | void TNTBlockCreate(TNTBlock * block, TileSound sound, float particleGravity); 7 | int TNTBlockGetTextureID(TNTBlock * block, int face); 8 | void TNTBlockExplode(TNTBlock * block, struct Level * level, int x, int y, int z); 9 | void TNTBlockSpawnBreakParticles(TNTBlock * block, struct Level * level, int x, int y, int z, ParticleManager * particles); 10 | -------------------------------------------------------------------------------- /MinecraftC/Level/Tile/TileSound.c: -------------------------------------------------------------------------------- 1 | #include "TileSound.h" 2 | #include "../../Utilities/Random.h" 3 | 4 | struct TileSounds TileSounds = { 5 | .none = { .name = "-", .volume = 0.0, .pitch = 0.0, .type = TileSoundTypeNone }, 6 | .grass = { .name = "Grass", .volume = 0.6, .pitch = 1.0, .type = TileSoundTypeGrass }, 7 | .cloth = { .name = "Grass", .volume = 0.7, .pitch = 1.2, .type = TileSoundTypeCloth }, 8 | .gravel = { .name = "Gravel", .volume = 1.0, .pitch = 1.0, .type = TileSoundTypeGravel }, 9 | .stone = { .name = "Stone", .volume = 1.0, .pitch = 1.0, .type = TileSoundTypeStone }, 10 | .metal = { .name = "Stone", .volume = 1.0, .pitch = 2.0, .type = TileSoundTypeMetal }, 11 | .wood = { .name = "Wood", .volume = 1.0, .pitch = 1.0, .type = TileSoundTypeWood }, 12 | }; 13 | 14 | float TileSoundGetVolume(TileSound sound) { 15 | return sound.volume / (RandomUniform() * 0.4 + 1.0) * 0.5; 16 | } 17 | 18 | float TileSoundGetPitch(TileSound sound) { 19 | return sound.pitch / (RandomUniform() * 0.2 + 0.9); 20 | } 21 | -------------------------------------------------------------------------------- /MinecraftC/Level/Tile/TileSound.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef enum TileSoundType { 4 | TileSoundTypeNone, 5 | TileSoundTypeGrass, 6 | TileSoundTypeCloth, 7 | TileSoundTypeGravel, 8 | TileSoundTypeStone, 9 | TileSoundTypeMetal, 10 | TileSoundTypeWood, 11 | } TileSoundType; 12 | 13 | typedef struct TileSound { 14 | const char * name; 15 | float volume; 16 | float pitch; 17 | TileSoundType type; 18 | } TileSound; 19 | 20 | extern struct TileSounds { 21 | TileSound none; 22 | TileSound grass; 23 | TileSound cloth; 24 | TileSound gravel; 25 | TileSound stone; 26 | TileSound metal; 27 | TileSound wood; 28 | } TileSounds; 29 | 30 | float TileSoundGetVolume(TileSound sound); 31 | float TileSoundGetPitch(TileSound sound); 32 | -------------------------------------------------------------------------------- /MinecraftC/Minecraft.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "Render/LevelRenderer.h" 4 | #include "Particle/ParticleManager.h" 5 | #include "GUI/GUIScreen.h" 6 | #include "GUI/HUDScreen.h" 7 | #include "Render/Renderer.h" 8 | #include "Timer.h" 9 | #include "SessionData.h" 10 | #include "ProgressBarDisplay.h" 11 | #include "Sound/SoundManager.h" 12 | 13 | typedef struct Minecraft { 14 | bool fullScreen; 15 | int width, frameWidth; 16 | int height, frameHeight; 17 | Timer timer; 18 | Level level; 19 | LevelRenderer levelRenderer; 20 | Player player; 21 | ParticleManager particleManager; 22 | SDL_Window * window; 23 | SDL_GLContext context; 24 | TextureManager textureManager; 25 | FontRenderer font; 26 | GUIScreen * currentScreen; 27 | ProgressBarDisplay progressBar; 28 | Renderer renderer; 29 | int ticks; 30 | HUDScreen hud; 31 | MovingObjectPosition selected; 32 | GameSettings settings; 33 | bool running; 34 | String debug; 35 | bool hasMouse; 36 | int lastClick; 37 | bool raining; 38 | char * workingDirectory; 39 | SoundManager sound; 40 | } Minecraft; 41 | 42 | void MinecraftCreate(Minecraft * minecraft, int width, int height, bool fullScreen); 43 | void MinecraftSetCurrentScreen(Minecraft * minecraft, GUIScreen * screen); 44 | void MinecraftRun(Minecraft * minecraft); 45 | void MinecraftGrabMouse(Minecraft * minecraft); 46 | void MinecraftRegenerateLevel(Minecraft * minecraft, int size); 47 | void MinecraftPause(Minecraft * minecraft); 48 | void MinecraftDestroy(Minecraft * minecraft); 49 | -------------------------------------------------------------------------------- /MinecraftC/Mods/Matrix.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #if MINECRAFTC_MODS 3 | 4 | typedef struct Matrix4x4 { 5 | float m00, m10, m20, m30; 6 | float m01, m11, m21, m31; 7 | float m02, m12, m22, m32; 8 | float m03, m13, m23, m33; 9 | } Matrix4x4; 10 | 11 | #define Matrix4x4Identity (Matrix4x4){ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 } 12 | 13 | static inline Matrix4x4 Matrix4x4Multiply(Matrix4x4 l, Matrix4x4 r) { 14 | return (Matrix4x4){ 15 | r.m00 * l.m00 + r.m10 * l.m01 + r.m20 * l.m02 + r.m30 * l.m03, 16 | r.m00 * l.m10 + r.m10 * l.m11 + r.m20 * l.m12 + r.m30 * l.m13, 17 | r.m00 * l.m20 + r.m10 * l.m21 + r.m20 * l.m22 + r.m30 * l.m23, 18 | r.m00 * l.m30 + r.m10 * l.m31 + r.m20 * l.m32 + r.m30 * l.m33, 19 | r.m01 * l.m00 + r.m11 * l.m01 + r.m21 * l.m02 + r.m31 * l.m03, 20 | r.m01 * l.m10 + r.m11 * l.m11 + r.m21 * l.m12 + r.m31 * l.m13, 21 | r.m01 * l.m20 + r.m11 * l.m21 + r.m21 * l.m22 + r.m31 * l.m23, 22 | r.m01 * l.m30 + r.m11 * l.m31 + r.m21 * l.m32 + r.m31 * l.m33, 23 | r.m02 * l.m00 + r.m12 * l.m01 + r.m22 * l.m02 + r.m32 * l.m03, 24 | r.m02 * l.m10 + r.m12 * l.m11 + r.m22 * l.m12 + r.m32 * l.m13, 25 | r.m02 * l.m20 + r.m12 * l.m21 + r.m22 * l.m22 + r.m32 * l.m23, 26 | r.m02 * l.m30 + r.m12 * l.m31 + r.m22 * l.m32 + r.m32 * l.m33, 27 | r.m03 * l.m00 + r.m13 * l.m01 + r.m23 * l.m02 + r.m33 * l.m03, 28 | r.m03 * l.m10 + r.m13 * l.m11 + r.m23 * l.m12 + r.m33 * l.m13, 29 | r.m03 * l.m20 + r.m13 * l.m21 + r.m23 * l.m22 + r.m33 * l.m23, 30 | r.m03 * l.m30 + r.m13 * l.m31 + r.m23 * l.m32 + r.m33 * l.m33, 31 | }; 32 | } 33 | 34 | static inline Matrix4x4 Matrix4x4FromTranslate(float vx, float vy, float vz) { 35 | return (Matrix4x4){ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, vx, vy, vz, 1.0 }; 36 | } 37 | 38 | static inline Matrix4x4 Matrix4x4FromAxisAngle(float vx, float vy, float vz, float a) { 39 | float c = cosf(a), c2 = 1.0 - cosf(a), s = sinf(a), xx = vx * vx, xy = vx * vy, xz = vx * vz, yy = vy * vy, yz = vy * vz, zz = vz * vz; 40 | return (Matrix4x4){ 41 | (xx + (yy + zz) * c), (xy * c2 + vz * s), (xz * c2 - vy * s), 0.0f, 42 | (xy * c2 - vz * s), (yy + (xx + zz) * c), (yz * c2 + vx * s), 0.0f, 43 | (xz * c2 + vy * s), (yz * c2 - vx * s), (zz + (xx + yy) * c), 0.0f, 44 | 0.0f, 0.0f, 0.0f, 1.0f 45 | }; 46 | } 47 | 48 | static inline Matrix4x4 Matrix4x4FromEulerAngles(float vx, float vy, float vz) { 49 | Matrix4x4 matrix = Matrix4x4Identity; 50 | matrix = Matrix4x4Multiply(Matrix4x4FromAxisAngle(0.0, 0.0, 1.0, vz), matrix); 51 | matrix = Matrix4x4Multiply(Matrix4x4FromAxisAngle(1.0, 0.0, 0.0, vy), matrix); 52 | matrix = Matrix4x4Multiply(Matrix4x4FromAxisAngle(0.0, 1.0, 0.0, vx), matrix); 53 | return matrix; 54 | } 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /MinecraftC/Mods/PrimedTNT.c: -------------------------------------------------------------------------------- 1 | #if MINECRAFTC_MODS 2 | 3 | #include "PrimedTNT.h" 4 | #include "../Particle/SmokeParticle.h" 5 | #include "../Particle/TerrainParticle.h" 6 | #include "../Utilities/SinTable.h" 7 | #include "../Utilities/OpenGL.h" 8 | #include "../Level/Level.h" 9 | 10 | void PrimedTNTCreate(PrimedTNT * entity, Level * level, float x, float y, float z) { 11 | EntityCreate(entity, level); 12 | entity->type = EntityTypePrimedTNT; 13 | EntitySetSize(entity, 0.98, 0.98); 14 | entity->heightOffset = entity->aabbHeight / 2.0; 15 | EntitySetPosition(entity, x, y, z); 16 | entity->makeStepSound = false; 17 | entity->xo = x; 18 | entity->yo = y; 19 | entity->zo = z; 20 | float r = RandomUniform() * 2.0 * M_PI; 21 | PrimedTNTData * this = &entity->tnt; 22 | this->xd = -tsin(r * M_PI / 180.0) * 0.02; 23 | this->yd = 0.2; 24 | this->zd = -cos(r * M_PI / 180.0) * 0.02; 25 | this->life = 40; 26 | this->defused = false; 27 | } 28 | 29 | void PrimedTNTOnHit(PrimedTNT * entity) { 30 | if (!entity->removed) { EntityRemove(entity); } 31 | } 32 | 33 | bool PrimedTNTIsPickable(PrimedTNT * entity) { 34 | return !entity->removed; 35 | } 36 | 37 | void PrimedTNTTick(PrimedTNT * entity) { 38 | PrimedTNTData * this = &entity->tnt; 39 | entity->xo = entity->x; 40 | entity->yo = entity->y; 41 | entity->zo = entity->z; 42 | this->yd -= 0.04; 43 | EntityMove(entity, this->xd, this->yd, this->zd); 44 | this->xd *= 0.98; 45 | this->yd *= 0.98; 46 | this->zd *= 0.98; 47 | if (entity->onGround) { 48 | this->xd *= 0.7; 49 | this->yd *= -0.5; 50 | this->zd *= 0.7; 51 | } 52 | 53 | if (!this->defused) { 54 | this->life--; 55 | if (this->life > 0) { 56 | SmokeParticle * particle = malloc(sizeof(SmokeParticle)); 57 | SmokeParticleCreate(particle, entity->level, entity->x, entity->y + 0.6, entity->z); 58 | ParticleManagerSpawnParticle(entity->level->particleEngine, particle); 59 | } else { 60 | EntityRemove(entity); 61 | RandomGenerator random; 62 | RandomGeneratorCreate(&random, time(NULL)); 63 | float radius = 4.0; 64 | LevelExplode(entity->level, entity->x, entity->y, entity->z, radius); 65 | for (int i = 0; i < 100; i++) { 66 | float ox = RandomGeneratorNormal(&random, 1.0) * radius / 4.0; 67 | float oy = RandomGeneratorNormal(&random, 1.0) * radius / 4.0; 68 | float oz = RandomGeneratorNormal(&random, 1.0) * radius / 4.0; 69 | float l = ox * ox + oy * oy + oz * oz; 70 | TerrainParticle * particle = malloc(sizeof(TerrainParticle)); 71 | TerrainParticleCreate(particle, entity->level, entity->x + ox, entity->y + oy, entity->z + oz, ox / l, oy / l, oz / l, &Blocks.table[BlockTypeTNT]); 72 | ParticleManagerSpawnParticle(entity->level->particleEngine, particle); 73 | } 74 | } 75 | } 76 | } 77 | 78 | void PrimedTNTRender(PrimedTNT * tnt, TextureManager * textures, float dt) { 79 | PrimedTNTData * this = &tnt->tnt; 80 | int texture = TextureManagerLoad(textures, "Terrain.png"); 81 | glBindTexture(GL_TEXTURE_2D, texture); 82 | float brightness = LevelGetBrightness(tnt->level, tnt->x, tnt->y, tnt->z); 83 | glPushMatrix(); 84 | glColor4f(brightness, brightness, brightness, 1.0); 85 | float vx = tnt->xo + (tnt->x - tnt->xo) * dt - 0.5; 86 | float vy = tnt->yo + (tnt->y - tnt->yo) * dt - 0.5; 87 | float vz = tnt->zo + (tnt->z - tnt->zo) * dt - 0.5; 88 | glTranslatef(vx, vy, vz); 89 | glPushMatrix(); 90 | BlockRenderPreview(&Blocks.table[BlockTypeTNT]); 91 | glDisable(GL_TEXTURE_2D); 92 | glDisable(GL_LIGHTING); 93 | glColor4f(1.0, 1.0, 1.0, ((this->life / 4 + 1) % 2) * 0.4); 94 | if (this->life <= 16) { glColor4f(1.0, 1.0, 1.0, ((this->life + 1) % 2) * 0.6); } 95 | if (this->life <= 2) { glColor4f(1.0, 1.0, 1.0, 0.9); } 96 | 97 | glEnable(GL_BLEND); 98 | glBlendFunc(GL_SRC_ALPHA, GL_ONE); 99 | BlockRenderPreview(&Blocks.table[BlockTypeTNT]); 100 | glDisable(GL_BLEND); 101 | glEnable(GL_TEXTURE_2D); 102 | glEnable(GL_LIGHTING); 103 | glPopMatrix(); 104 | glPopMatrix(); 105 | } 106 | 107 | #endif 108 | -------------------------------------------------------------------------------- /MinecraftC/Mods/PrimedTNT.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #if MINECRAFTC_MODS 3 | 4 | #include 5 | #include "../Render/TextureManager.h" 6 | 7 | struct Level; 8 | 9 | typedef struct Entity PrimedTNT; 10 | 11 | typedef struct PrimedTNTData { 12 | float xd, yd, zd; 13 | int life; 14 | bool defused; 15 | } PrimedTNTData; 16 | 17 | void PrimedTNTCreate(PrimedTNT * tnt, struct Level * level, float x, float y, float z); 18 | void PrimedTNTOnHit(PrimedTNT * tnt); 19 | bool PrimedTNTIsPickable(PrimedTNT * tnt); 20 | void PrimedTNTTick(PrimedTNT * tnt); 21 | void PrimedTNTRender(PrimedTNT * tnt, TextureManager * textures, float t); 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /MinecraftC/Mods/Raytracer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #if MINECRAFTC_MODS 3 | 4 | #include "../Utilities/OpenCL.h" 5 | #include "../Render/TextureManager.h" 6 | #include "../Level/Tile/Block.h" 7 | 8 | struct OctreeRenderer { 9 | int width, height; 10 | cl_device_id device; 11 | cl_context context; 12 | cl_program raytracer; 13 | cl_kernel traceKernel; 14 | cl_program distanceFieldShader; 15 | cl_kernel iteratekernel; 16 | cl_command_queue queue; 17 | cl_mem blockBuffer; 18 | cl_mem outputTexture; 19 | cl_mem terrainTexture; 20 | cl_mem distanceFieldBuffer; 21 | uint8_t iteration; 22 | uint32_t textureID; 23 | TextureManager * textures; 24 | struct Level * level; 25 | } extern Raytracer; 26 | 27 | bool RaytracerInitialize(TextureManager * textures, struct Level * level, int width, int height); 28 | void RaytracerReload(void); 29 | void RaytracerEnqueue(float dt, float time, bool doBobbing); 30 | void RaytracerResize(int width, int height); 31 | void RaytracerDestroy(void); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /MinecraftC/MovingObjectPosition.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Physics/Vector3D.h" 3 | 4 | typedef struct MovingObjectPosition { 5 | int entityPosition; 6 | int x, y, z; 7 | int face; 8 | Vector3D vector; 9 | struct Entity * entity; 10 | bool null; 11 | } MovingObjectPosition; 12 | -------------------------------------------------------------------------------- /MinecraftC/Particle/Particle.c: -------------------------------------------------------------------------------- 1 | #include "Particle.h" 2 | #include "SmokeParticle.h" 3 | #include "TerrainParticle.h" 4 | #include "WaterDropParticle.h" 5 | #include "../Level/Level.h" 6 | #include "../Render/ShapeRenderer.h" 7 | 8 | void ParticleCreate(Particle * entity, Level * level, float x, float y, float z, float xd, float yd, float zd) { 9 | EntityCreate(entity, level); 10 | entity->type = EntityTypeParticle; 11 | EntitySetSize(entity, 0.2, 0.2); 12 | entity->heightOffset = entity->aabbHeight / 2.0; 13 | EntitySetPosition(entity, x, y, z); 14 | entity->makeStepSound = false; 15 | ParticleData * this = &entity->particle; 16 | *this = (ParticleData) { 17 | .r = 1.0, 18 | .g = 1.0, 19 | .b = 1.0, 20 | .xd = xd + (RandomUniform() * 2.0 - 1.0) * 0.4, 21 | .yd = yd + (RandomUniform() * 2.0 - 1.0) * 0.4, 22 | .zd = zd + (RandomUniform() * 2.0 - 1.0) * 0.4, 23 | .u = RandomUniform() * 3.0, 24 | .v = RandomUniform() * 3.0, 25 | .size = RandomUniform() * 0.5 + 0.5, 26 | .lifeTime = 4.0 / (RandomUniform() * 0.9 + 0.1), 27 | .age = 0, 28 | }; 29 | float s = (RandomUniform() + RandomUniform() + 1.0) * 0.15 * 0.4 / sqrtf(this->xd * this->xd + this->yd * this->yd + this->zd * this->zd); 30 | this->xd *= s; 31 | this->yd *= s; 32 | this->zd *= s; 33 | this->yd += 0.1; 34 | } 35 | 36 | void ParticleTick(Particle * particle) { 37 | ParticleData * this = &particle->particle; 38 | if (this->type == ParticleTypeSmoke) { SmokeParticleTick(particle); } 39 | if (this->type == ParticleTypeWaterDrop) { WaterDropParticleTick(particle); } 40 | 41 | particle->xo = particle->x; 42 | particle->yo = particle->y; 43 | particle->zo = particle->z; 44 | if (this->age++ >= this->lifeTime) { EntityRemove(particle); } 45 | this->yd -= 0.04 * this->gravity; 46 | EntityMove(particle, this->xd, this->yd, this->zd); 47 | this->xd *= 0.98; 48 | this->yd *= 0.98; 49 | this->zd *= 0.98; 50 | if (particle->onGround) { 51 | this->xd *= 0.7; 52 | this->zd *= 0.7; 53 | } 54 | } 55 | 56 | void ParticleRender(Particle * particle, float dt, float x, float y, float z, float v6, float v7) { 57 | ParticleData * this = &particle->particle; 58 | if (this->type == ParticleTypeTerrain) { TerrainParticleRender(particle, dt, x, y, z, v6, v7); return; } 59 | 60 | float u0 = ((this->texture % 16) + this->u / 4.0) / 16.0; 61 | float v0 = ((this->texture / 16) + this->v / 4.0) / 16.0; 62 | float u1 = u0 + 0.0624375; 63 | float v1 = v0 + 0.0624375; 64 | float s = 0.1 * this->size; 65 | float vx = particle->xo + (particle->x - particle->xo) * dt; 66 | float vy = particle->yo + (particle->y - particle->yo) * dt; 67 | float vz = particle->zo + (particle->z - particle->zo) * dt; 68 | float brightness = EntityGetBrightness(particle, dt); 69 | ShapeRendererColorf(this->r * brightness, this->g * brightness, this->b * brightness); 70 | ShapeRendererVertexUV(vx - x * s - v6 * s, vy - y * s, vz - z * s - v7 * s, u0, v1); 71 | ShapeRendererVertexUV(vx - x * s + v6 * s, vy + y * s, vz - z * s + v7 * s, u0, v0); 72 | ShapeRendererVertexUV(vx + x * s + v6 * s, vy + y * s, vz + z * s + v7 * s, u1, v0); 73 | ShapeRendererVertexUV(vx + x * s - v6 * s, vy - y * s, vz + z * s - v7 * s, u1, v1); 74 | } 75 | 76 | int ParticleGetParticleTexture(Particle * particle) { 77 | ParticleData * this = &particle->particle; 78 | if (this->type == ParticleTypeTerrain) { return TerrainParticleGetTexture(particle); } 79 | return 0; 80 | } 81 | -------------------------------------------------------------------------------- /MinecraftC/Particle/Particle.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct Level; 4 | 5 | typedef enum ParticleType { 6 | ParticleTypeNone, 7 | ParticleTypeSmoke, 8 | ParticleTypeTerrain, 9 | ParticleTypeWaterDrop, 10 | } ParticleType; 11 | 12 | typedef struct ParticleData { 13 | float xd, yd, zd; 14 | int texture; 15 | float u, v; 16 | int age; 17 | int lifeTime; 18 | float size; 19 | float gravity; 20 | float r, g, b; 21 | ParticleType type; 22 | } ParticleData; 23 | 24 | typedef struct Entity Particle; 25 | 26 | void ParticleCreate(Particle * particle, struct Level * level, float x, float y, float z, float xd, float yd, float zd); 27 | void ParticleTick(Particle * particle); 28 | void ParticleRender(Particle * particle, float t, float x, float y, float z, float v6, float v7); 29 | int ParticleGetParticleTexture(Particle * particle); 30 | -------------------------------------------------------------------------------- /MinecraftC/Particle/ParticleManager.c: -------------------------------------------------------------------------------- 1 | #include "ParticleManager.h" 2 | #include "../Level/Level.h" 3 | 4 | void ParticleMangerCreate(ParticleManager * particles, Level * level, TextureManager * textures) { 5 | *particles = (ParticleManager) { 6 | .textures = textures, 7 | }; 8 | if (level != NULL) { level->particleEngine = particles; } 9 | for (int i = 0; i < 2; i++) { particles->particles[i] = ListCreate(sizeof(Particle *)); } 10 | } 11 | 12 | void ParticleManagerSpawnParticle(ParticleManager * manager, Particle * particle) { 13 | int tex = ParticleGetParticleTexture(particle); 14 | manager->particles[tex] = ListPush(manager->particles[tex], &particle); 15 | } 16 | 17 | void ParticleManagerTick(ParticleManager * manager) { 18 | for (int i = 0; i < 2; i++) { 19 | for (int j = 0; j < ListLength(manager->particles[i]); j++) { 20 | ParticleTick(manager->particles[i][j]); 21 | if (manager->particles[i][j]->removed) { 22 | manager->particles[i] = ListRemove(manager->particles[i], j--); 23 | } 24 | } 25 | } 26 | } 27 | 28 | void ParticleManagerDestroy(ParticleManager * manager) { 29 | for (int i = 0; i < 2; i++) { ListFree(manager->particles[i]); } 30 | } 31 | -------------------------------------------------------------------------------- /MinecraftC/Particle/ParticleManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Utilities/List.h" 3 | #include "../Render/TextureManager.h" 4 | #include "Particle.h" 5 | 6 | typedef struct ParticleManager { 7 | List(Particle *) particles[2]; 8 | TextureManager * textures; 9 | } ParticleManager; 10 | 11 | void ParticleMangerCreate(ParticleManager * particles, struct Level * level, TextureManager * textures); 12 | void ParticleManagerSpawnParticle(ParticleManager * particles, Particle * particle); 13 | void ParticleManagerTick(ParticleManager * particles); 14 | void ParticleManagerDestroy(ParticleManager * particles); 15 | -------------------------------------------------------------------------------- /MinecraftC/Particle/SmokeParticle.c: -------------------------------------------------------------------------------- 1 | #include "SmokeParticle.h" 2 | #include "../Level/Level.h" 3 | 4 | void SmokeParticleCreate(SmokeParticle * particle, Level * level, float x, float y, float z) { 5 | ParticleCreate(particle, level, x, y, z, 0, 0, 0); 6 | ParticleData * this = &particle->particle; 7 | this->type = ParticleTypeSmoke; 8 | this->xd *= 0.1; 9 | this->yd *= 0.1; 10 | this->zd *= 0.1; 11 | this->r = RandomUniform() * 0.3; 12 | this->g = this->r; 13 | this->b = this->r; 14 | this->lifeTime = 8.0 / (RandomUniform() * 0.8 + 0.2); 15 | particle->noPhysics = true; 16 | } 17 | 18 | void SmokeParticleTick(SmokeParticle * particle) { 19 | ParticleData * this = &particle->particle; 20 | particle->xo = particle->x; 21 | particle->yo = particle->y; 22 | particle->zo = particle->z; 23 | if (this->age++ >= this->lifeTime) { EntityRemove(particle); } 24 | this->texture = 7 - (this->age << 3) / this->lifeTime; 25 | this->yd += 0.004; 26 | EntityMove(particle, this->xd, this->yd, this->zd); 27 | this->xd *= 0.96; 28 | this->yd *= 0.96; 29 | this->zd *= 0.96; 30 | if (particle->onGround) { 31 | this->xd *= 0.7; 32 | this->yd *= 0.7; 33 | this->zd *= 0.7; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /MinecraftC/Particle/SmokeParticle.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Particle.h" 3 | 4 | typedef Particle SmokeParticle; 5 | 6 | void SmokeParticleCreate(SmokeParticle * particle, struct Level * level, float x, float y, float z); 7 | void SmokeParticleTick(SmokeParticle * particle); 8 | -------------------------------------------------------------------------------- /MinecraftC/Particle/TerrainParticle.c: -------------------------------------------------------------------------------- 1 | #include "TerrainParticle.h" 2 | #include "../Level/Level.h" 3 | #include "../Render/ShapeRenderer.h" 4 | 5 | void TerrainParticleCreate(TerrainParticle * particle, Level * level, float x, float y, float z, float xd, float yd, float zd, Block * block) { 6 | ParticleCreate(particle, level, x, y, z, xd, yd, zd); 7 | ParticleData * this = &particle->particle; 8 | this->texture = block->textureID; 9 | this->gravity = block->particleGravity; 10 | this->r = 0.6; 11 | this->g = 0.6; 12 | this->b = 0.6; 13 | this->type = ParticleTypeTerrain; 14 | } 15 | 16 | int TerrainParticleGetTexture(TerrainParticle * particle) { 17 | return 1; 18 | } 19 | 20 | void TerrainParticleRender(TerrainParticle * particle, float dt, float x, float y, float z, float v6, float v7) { 21 | ParticleData * this = &particle->particle; 22 | float u0 = ((this->texture % 16) + this->u / 4.0) / 16.0; 23 | float v0 = ((this->texture / 16) + this->v / 4.0) / 16.0; 24 | float u1 = u0 + 0.015609375; 25 | float v1 = v0 + 0.015609375; 26 | float s = 0.1 * this->size; 27 | float vx = particle->xo + (particle->x - particle->xo) * dt; 28 | float vy = particle->yo + (particle->y - particle->yo) * dt; 29 | float vz = particle->zo + (particle->z - particle->zo) * dt; 30 | float brightness = EntityGetBrightness(particle, dt); 31 | ShapeRendererColorf(this->r * brightness, this->g * brightness, this->b * brightness); 32 | ShapeRendererVertexUV(vx - x * s - v6 * s, vy - y * s, vz - z * s - v7 * s, u0, v1); 33 | ShapeRendererVertexUV(vx - x * s + v6 * s, vy + y * s, vz - z * s + v7 * s, u0, v0); 34 | ShapeRendererVertexUV(vx + x * s + v6 * s, vy + y * s, vz + z * s + v7 * s, u1, v0); 35 | ShapeRendererVertexUV(vx + x * s - v6 * s, vy - y * s, vz + z * s - v7 * s, u1, v1); 36 | } 37 | -------------------------------------------------------------------------------- /MinecraftC/Particle/TerrainParticle.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Particle.h" 3 | #include "../Level/Tile/Block.h" 4 | 5 | typedef Particle TerrainParticle; 6 | 7 | void TerrainParticleCreate(TerrainParticle * particle, struct Level * level, float x, float y, float z, float xd, float yd, float zd, Block * block); 8 | int TerrainParticleGetTexture(TerrainParticle * particle); 9 | void TerrainParticleRender(TerrainParticle * particle, float t, float x, float y, float z, float v6, float v7); 10 | -------------------------------------------------------------------------------- /MinecraftC/Particle/WaterDropParticle.c: -------------------------------------------------------------------------------- 1 | #include "WaterDropParticle.h" 2 | #include "../Level/Level.h" 3 | 4 | void WaterDropParticleCreate(WaterDropParticle * particle, Level * level, float x, float y, float z) { 5 | ParticleCreate(particle, level, x, y, z, 0.0, 0.0, 0.0); 6 | ParticleData * this = &particle->particle; 7 | this->type = ParticleTypeWaterDrop; 8 | this->xd *= 0.3; 9 | this->zd *= 0.3; 10 | this->yd = RandomUniform() * 0.2 + 0.1; 11 | this->r = 1.0; 12 | this->g = 1.0; 13 | this->b = 1.0; 14 | this->texture = 16; 15 | EntitySetSize(particle, 0.01, 0.01); 16 | this->lifeTime = 8.0 / (RandomUniform() * 0.8 + 0.2); 17 | } 18 | 19 | void WaterDropParticleTick(WaterDropParticle * particle) { 20 | ParticleData * this = &particle->particle; 21 | particle->xo = particle->x; 22 | particle->yo = particle->y; 23 | particle->zo = particle->z; 24 | this->yd -= 0.06; 25 | EntityMove(particle, this->xd, this->yd, this->zd); 26 | this->xd *= 0.98; 27 | this->yd *= 0.98; 28 | this->zd *= 0.98; 29 | if (this->lifeTime-- <= 0) { EntityRemove(particle); } 30 | if (particle->onGround) { 31 | if (RandomUniform() < 0.5) { EntityRemove(particle); } 32 | this->xd *= 0.7; 33 | this->zd *= 0.7; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /MinecraftC/Particle/WaterDropParticle.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Particle.h" 3 | 4 | typedef Particle WaterDropParticle; 5 | 6 | void WaterDropParticleCreate(WaterDropParticle * particle, struct Level * level, float x, float y, float z); 7 | void WaterDropParticleTick(WaterDropParticle * particle); 8 | -------------------------------------------------------------------------------- /MinecraftC/Physics/AABB.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "../MovingObjectPosition.h" 4 | 5 | typedef struct AABB { 6 | float x0, y0, z0; 7 | float x1, y1, z1; 8 | bool null; 9 | } AABB; 10 | 11 | AABB AABBExpand(AABB c, float x, float y, float z); 12 | AABB AABBGrow(AABB c, float x, float y, float z); 13 | AABB AABBMove(AABB c, float x, float y, float z); 14 | float AABBClipXCollide(AABB c0, AABB c1, float xa); 15 | float AABBClipYCollide(AABB c0, AABB c1, float ya); 16 | float AABBClipZCollide(AABB c0, AABB c1, float za); 17 | bool AABBIntersects(AABB c0, AABB c1); 18 | bool AABBIntersectsInner(AABB c0, AABB c1); 19 | MovingObjectPosition AABBClip(AABB c, Vector3D v1, Vector3D v2); 20 | -------------------------------------------------------------------------------- /MinecraftC/Physics/Vector3D.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #define Vector3DNull (Vector3D){ INFINITY, INFINITY, INFINITY } 5 | 6 | typedef struct Vector3D { 7 | float x, y, z; 8 | } Vector3D; 9 | 10 | static inline Vector3D Vector3DAdd(Vector3D a, Vector3D b) { 11 | return (Vector3D){ a.x + b.x, a.y + b.y, a.z + b.z }; 12 | } 13 | 14 | static inline Vector3D Vector3DSubtract(Vector3D a, Vector3D b) { 15 | return (Vector3D){ a.x - b.x, a.y - b.y, a.z - b.z }; 16 | } 17 | 18 | static inline float Vector3DLength(Vector3D a) { 19 | return sqrtf(a.x * a.x + a.y * a.y + a.z * a.z); 20 | } 21 | 22 | static inline float Vector3DSqDistance(Vector3D a, Vector3D b) { 23 | return (b.x - a.x) * (b.x - a.x) + (b.y - a.y) * (b.y - a.y) + (b.z - a.z) * (b.z - a.z); 24 | } 25 | 26 | static inline Vector3D Vector3DNormalize(Vector3D a) { 27 | float len = Vector3DLength(a); 28 | return (Vector3D){ a.x / len, a.y / len, a.z / len }; 29 | } 30 | 31 | static inline Vector3D Vector3DGetXIntersection(Vector3D v0, Vector3D v1, float s) { 32 | Vector3D d = Vector3DSubtract(v1, v0); 33 | s = (s - v0.x) / d.x; 34 | return d.x * d.x < 1.0E-7 ? Vector3DNull : (s >= 0.0 && s <= 1.0 ? (Vector3D){ v0.x + d.x * s, v0.y + d.y * s, v0.z + d.z * s } : Vector3DNull); 35 | } 36 | 37 | static inline Vector3D Vector3DGetYIntersection(Vector3D v0, Vector3D v1, float s) { 38 | Vector3D d = Vector3DSubtract(v1, v0); 39 | s = (s - v0.y) / d.y; 40 | return d.y * d.y < 1.0E-7 ? Vector3DNull : (s >= 0.0 && s <= 1.0 ? (Vector3D){ v0.x + d.x * s, v0.y + d.y * s, v0.z + d.z * s } : Vector3DNull); 41 | } 42 | 43 | static inline Vector3D Vector3DGetZIntersection(Vector3D v0, Vector3D v1, float s) { 44 | Vector3D d = Vector3DSubtract(v1, v0); 45 | s = (s - v0.z) / d.z; 46 | return d.z * d.z < 1.0E-7 ? Vector3DNull : (s >= 0.0 && s <= 1.0 ? (Vector3D){ v0.x + d.x * s, v0.y + d.y * s, v0.z + d.z * s } : Vector3DNull); 47 | } 48 | 49 | static inline bool Vector3DIsNull(Vector3D v) { 50 | return v.x == INFINITY && v.y == INFINITY && v.z == INFINITY; 51 | } 52 | -------------------------------------------------------------------------------- /MinecraftC/Player/InputHandler.c: -------------------------------------------------------------------------------- 1 | #include "InputHandler.h" 2 | 3 | void InputHandlerCreate(InputHandler * input, GameSettings * settings) { 4 | *input = (struct InputHandler) { 5 | .settings = settings, 6 | }; 7 | } 8 | 9 | void InputHandlerSetKeyState(InputHandler * input, int key, bool state) { 10 | if (key == input->settings->forwardKey.key) { input->keyStates[0] = state; } 11 | if (key == input->settings->backKey.key) { input->keyStates[1] = state; } 12 | if (key == input->settings->leftKey.key) { input->keyStates[2] = state; } 13 | if (key == input->settings->rightKey.key) { input->keyStates[3] = state; } 14 | if (key == input->settings->jumpKey.key) { input->keyStates[4] = state; } 15 | } 16 | 17 | void InputHandlerResetKeys(InputHandler * input) { 18 | for (int i = 0; i < 10; i++) { input->keyStates[i] = false; } 19 | } 20 | 21 | void InputHandlerUpdateMovement(InputHandler * input) { 22 | input->x = 0.0; 23 | input->y = 0.0; 24 | if (input->keyStates[0]) { input->y--; } 25 | if (input->keyStates[1]) { input->y++; } 26 | if (input->keyStates[2]) { input->x--; } 27 | if (input->keyStates[3]) { input->x++; } 28 | input->jumping = input->keyStates[4]; 29 | } 30 | -------------------------------------------------------------------------------- /MinecraftC/Player/InputHandler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "../GameSettings.h" 4 | 5 | typedef struct InputHandler { 6 | bool keyStates[10]; 7 | GameSettings * settings; 8 | float x, y; 9 | bool jumping; 10 | } InputHandler; 11 | 12 | void InputHandlerCreate(InputHandler * input, GameSettings * settings); 13 | void InputHandlerSetKeyState(InputHandler * input, int key, bool state); 14 | void InputHandlerResetKeys(InputHandler * input); 15 | void InputHandlerUpdateMovement(InputHandler * input); 16 | -------------------------------------------------------------------------------- /MinecraftC/Player/Inventory.c: -------------------------------------------------------------------------------- 1 | #include "Inventory.h" 2 | #include "../SessionData.h" 3 | 4 | void InventoryCreate(Inventory * inventory) { 5 | *inventory = (Inventory) { 6 | .selected = 0, 7 | }; 8 | for (int i = 0; i < 9; i++) { 9 | inventory->slots[i] = -1; 10 | } 11 | } 12 | 13 | BlockType InventoryGetSelected(Inventory * inventory) { 14 | return inventory->slots[inventory->selected]; 15 | } 16 | 17 | static int GetSlot(Inventory * inventory, BlockType tile) { 18 | for (int i = 0; i < 9; i++) { 19 | if (tile == inventory->slots[i]) { return i; } 20 | } 21 | return -1; 22 | } 23 | 24 | void InventoryGrabTexture(Inventory * inventory, BlockType tile) { 25 | int slot = GetSlot(inventory, tile); 26 | if (slot >= 0) { inventory->selected = slot; } 27 | else { 28 | if (tile != BlockTypeNone && ListContains(SessionDataAllowedBlocks, &(BlockType){ Blocks.table[tile].type })) { 29 | InventoryReplaceSlotWithBlock(inventory, &Blocks.table[tile]); 30 | } 31 | } 32 | } 33 | 34 | void InventorySwapPaint(Inventory * inventory, int slot) { 35 | slot = slot > 0 ? 1 : (slot < 0 ? -1 : slot); 36 | 37 | for (inventory->selected -= slot; inventory->selected < 0; inventory->selected += 9) { } 38 | while (inventory->selected >= 9) { inventory->selected -= 9; } 39 | } 40 | 41 | void InventoryReplaceSlot(Inventory * inventory, int sessionBlock) { 42 | if (sessionBlock >= 0) { InventoryReplaceSlotWithBlock(inventory, &Blocks.table[SessionDataAllowedBlocks[sessionBlock]]); } 43 | } 44 | 45 | void InventoryReplaceSlotWithBlock(Inventory * inventory, Block * block) { 46 | if (block != NULL) { 47 | int slot = GetSlot(inventory, block->type); 48 | if (slot >= 0) { inventory->slots[slot] = inventory->slots[inventory->selected]; } 49 | inventory->slots[inventory->selected] = block->type; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /MinecraftC/Player/Inventory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Level/Tile/Block.h" 3 | 4 | typedef struct Inventory { 5 | BlockType slots[9]; 6 | int selected; 7 | } Inventory; 8 | 9 | void InventoryCreate(Inventory * inventory); 10 | BlockType InventoryGetSelected(Inventory * inventory); 11 | void InventoryGrabTexture(Inventory * inventory, BlockType tile); 12 | void InventorySwapPaint(Inventory * inventory, int slot); 13 | void InventoryReplaceSlot(Inventory * inventory, int sessionBlock); 14 | void InventoryReplaceSlotWithBlock(Inventory * inventory, Block * block); 15 | -------------------------------------------------------------------------------- /MinecraftC/Player/Player.c: -------------------------------------------------------------------------------- 1 | #include "Player.h" 2 | #include "PlayerAI.h" 3 | #include "../Utilities/OpenGL.h" 4 | #include "../Level/Level.h" 5 | 6 | void PlayerCreate(Player * entity, Level * level) { 7 | EntityCreate(entity, level); 8 | entity->type = EntityTypePlayer; 9 | entity->footSize = 0.5; 10 | entity->heightOffset = 1.62; 11 | EntitySetPosition(entity, entity->x, entity->y, entity->z); 12 | PlayerData * player = &entity->player; 13 | *player = (PlayerData) { 14 | .bodyRotation = 0.0, 15 | .oldBodyRotation = 0.0, 16 | .userType = 0, 17 | }; 18 | InventoryCreate(&player->inventory); 19 | PlayerAICreate(&player->ai, entity); 20 | if (level != NULL) { 21 | level->player = entity; 22 | LevelAddEntity(level, entity); 23 | } 24 | } 25 | 26 | void PlayerTick(Player * player) { 27 | PlayerData * this = &player->player; 28 | this->oldTilt = this->tilt; 29 | if (EntityIsInWater(player)) { player->fallDistance = 0.0; } 30 | 31 | this->oldBodyRotation = this->bodyRotation; 32 | player->xRotO = player->xRot; 33 | player->yRotO = player->yRot; 34 | PlayerStepAI(player); 35 | float dx = player->x - player->xo; 36 | float dz = player->z - player->zo; 37 | float len = sqrtf(dx * dx + dz * dz); 38 | float rot = this->bodyRotation; 39 | float f1 = 0.0; 40 | if (len > 0.05) { 41 | f1 = len * 3.0; 42 | rot = atan2(dz, dx) * (180.0 / M_PI) - 90.0; 43 | } 44 | 45 | float a; 46 | for (a = rot - this->bodyRotation; a < -180.0; a += 360.0); 47 | while (a >= 180.0) { a -= 360.0; } 48 | this->bodyRotation += a * 0.1; 49 | for (a = player->yRot - this->bodyRotation; a < -180.0; a += 360.0); 50 | while (a >= 180.0) { a -= 360.0; } 51 | bool b = a < -90.0 || a >= 90.0; 52 | if (a < -75.0) { a = -75.0; } 53 | if (a > 75.0) { a = 75.0; } 54 | this->bodyRotation = player->yRot - a; 55 | this->bodyRotation += a * 0.1; 56 | if (b) { f1 = -f1; } 57 | while (player->yRot - player->yRotO < -180.0) { player->yRotO -= 360.0; } 58 | while (player->yRot - player->yRotO >= 180.0) { player->yRotO += 360.0; } 59 | while (this->bodyRotation - this->oldBodyRotation < -180.0) { this->oldBodyRotation -= 360.0; } 60 | while (this->bodyRotation - this->oldBodyRotation >= 180.0) { this->oldBodyRotation += 360.0; } 61 | while (player->xRot - player->xRotO < -180.0) { player->xRotO -= 360.0; } 62 | while (player->xRot - player->xRotO >= 180.0) { player->xRotO += 360.0; } 63 | } 64 | 65 | void PlayerTravel(Player * player, float x, float y) { 66 | if (EntityIsInWater(player)) { 67 | float z = player->y; 68 | EntityMoveRelative(player, x, y, 0.02); 69 | EntityMove(player, player->xd, player->yd, player->zd); 70 | player->xd *= 0.8; 71 | player->yd *= 0.8; 72 | player->zd *= 0.8; 73 | player->yd -= 0.02; 74 | if (player->horizontalCollision && EntityIsFree(player, player->xd, player->yd + 0.6 - player->y + z, player->zd)) { player->yd = 0.3; } 75 | } else if (EntityIsInLava(player)) { 76 | float z = player->y; 77 | EntityMoveRelative(player, x, y, 0.02); 78 | EntityMove(player, player->xd, player->yd, player->zd); 79 | player->xd *= 0.5; 80 | player->yd *= 0.5; 81 | player->zd *= 0.5; 82 | player->yd -= 0.02; 83 | if (player->horizontalCollision && EntityIsFree(player, player->xd, player->yd + 0.6 - player->y + z, player->zd)) { player->yd = 0.3; } 84 | } else { 85 | EntityMoveRelative(player, x, y, player->onGround ? 0.1 : 0.02); 86 | EntityMove(player, player->xd, player->yd, player->zd); 87 | player->xd *= 0.91; 88 | player->yd *= 0.98; 89 | player->zd *= 0.91; 90 | player->yd -= 0.08; 91 | if (player->onGround) { 92 | player->xd *= 0.6; 93 | player->zd *= 0.6; 94 | } 95 | } 96 | } 97 | 98 | void PlayerResetPosition(Player * entity) { 99 | entity->heightOffset = 1.62; 100 | EntitySetSize(entity, 0.6, 1.8); 101 | entity->type = EntityTypeNone; 102 | EntityResetPosition(entity); 103 | entity->type = EntityTypePlayer; 104 | if (entity->level != NULL) { entity->level->player = entity; } 105 | } 106 | 107 | void PlayerStepAI(Player * player) { 108 | PlayerData * this = &player->player; 109 | this->oldBobbing = this->bobbing; 110 | InputHandlerUpdateMovement(&this->input); 111 | PlayerAITick(&this->ai, player); 112 | float bob = sqrtf(player->xd * player->xd + player->zd * player->zd); 113 | float tilt = atan(-player->yd * 0.2) * 15.0; 114 | if (bob > 0.1) { bob = 0.1; } 115 | if (!player->onGround) { bob = 0.0; } 116 | if (player->onGround) { tilt = 0.0; } 117 | this->bobbing += (bob - this->bobbing) * 0.4; 118 | this->tilt += (tilt - this->tilt) * 0.8; 119 | } 120 | 121 | void PlayerReleaseAllKeys(Player * player) { 122 | PlayerData * this = &player->player; 123 | InputHandlerResetKeys(&this->input); 124 | } 125 | 126 | void PlayerSetKey(Player * player, int key, bool state) { 127 | PlayerData * this = &player->player; 128 | InputHandlerSetKeyState(&this->input, key, state); 129 | } 130 | -------------------------------------------------------------------------------- /MinecraftC/Player/Player.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "InputHandler.h" 3 | #include "Inventory.h" 4 | #include "PlayerAI.h" 5 | #include "../Player/Player.h" 6 | 7 | struct Level; 8 | 9 | typedef struct Entity Player; 10 | 11 | typedef struct PlayerData { 12 | float bodyRotation; 13 | float oldBodyRotation; 14 | float oldAnimationStep; 15 | float tilt; 16 | float oldTilt; 17 | PlayerAI ai; 18 | InputHandler input; 19 | Inventory inventory; 20 | int userType; 21 | float bobbing; 22 | float oldBobbing; 23 | } PlayerData; 24 | 25 | void PlayerCreate(Player * player, struct Level * level); 26 | void PlayerTick(Player * player); 27 | void PlayerTravel(Player * player, float x, float y); 28 | void PlayerResetPosition(Player * player); 29 | void PlayerStepAI(Player * player); 30 | void PlayerReleaseAllKeys(Player * player); 31 | void PlayerSetKey(Player * player, int key, bool state); 32 | -------------------------------------------------------------------------------- /MinecraftC/Player/PlayerAI.c: -------------------------------------------------------------------------------- 1 | #include "PlayerAI.h" 2 | #include "Player.h" 3 | #include "../Entity.h" 4 | #include 5 | 6 | void PlayerAICreate(PlayerAI * ai, Player * parent) { 7 | *ai = (PlayerAI) { 8 | .jumping = false, 9 | .parent = parent, 10 | }; 11 | RandomGeneratorCreate(&ai->random, TimeNano()); 12 | } 13 | 14 | void PlayerAIUpdate(PlayerAI * ai) { 15 | PlayerData * player = &ai->parent->player; 16 | ai->jumping = player->input.jumping; 17 | ai->x = player->input.x; 18 | ai->y = player->input.y; 19 | } 20 | 21 | void PlayerAITick(PlayerAI * ai, Entity * mob) { 22 | ai->mob = mob; 23 | PlayerAIUpdate(ai); 24 | 25 | bool inWater = EntityIsInWater(mob); 26 | bool inLava = EntityIsInLava(mob); 27 | if (ai->jumping) { 28 | if (inWater) { mob->yd += 0.04; } 29 | else if (inLava) { mob->yd += 0.04; } 30 | else if (mob->onGround) { PlayerAIJumpFromGround(ai); } 31 | } 32 | 33 | ai->x *= 0.98; 34 | ai->y *= 0.98; 35 | PlayerTravel(mob, ai->x, ai->y); 36 | } 37 | 38 | void PlayerAIJumpFromGround(PlayerAI * ai) { 39 | ai->mob->yd = 0.42; 40 | } 41 | -------------------------------------------------------------------------------- /MinecraftC/Player/PlayerAI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Utilities/Random.h" 3 | #include 4 | 5 | typedef struct PlayerAI { 6 | RandomGenerator random; 7 | float x, y; 8 | struct Entity * mob; 9 | bool jumping; 10 | struct Entity * parent; 11 | } PlayerAI; 12 | 13 | void PlayerAICreate(PlayerAI * ai, struct Entity * parent); 14 | void PlayerAIUpdate(PlayerAI * ai); 15 | void PlayerAITick(PlayerAI * ai, struct Entity * mob); 16 | void PlayerAIJumpFromGround(PlayerAI * ai); 17 | -------------------------------------------------------------------------------- /MinecraftC/ProgressBarDisplay.c: -------------------------------------------------------------------------------- 1 | #include "ProgressBarDisplay.h" 2 | #include "Minecraft.h" 3 | #include "Utilities/Time.h" 4 | #include "Utilities/Log.h" 5 | #include "Utilities/OpenGL.h" 6 | #include "Render/ShapeRenderer.h" 7 | 8 | void ProgressBarDisplayCreate(ProgressBarDisplay * display, Minecraft * minecraft) { 9 | *display = (ProgressBarDisplay) { 10 | .text = "", 11 | .minecraft = minecraft, 12 | .title = "", 13 | .start = TimeMilli(), 14 | }; 15 | } 16 | 17 | void ProgressBarDisplaySetTitle(ProgressBarDisplay * display, char * title) { 18 | display->title = title; 19 | int a1 = display->minecraft->width * 240 / display->minecraft->height; 20 | int a2 = display->minecraft->height * 240 / display->minecraft->height; 21 | glClear(GL_DEPTH_BUFFER_BIT); 22 | glMatrixMode(GL_PROJECTION); 23 | glLoadIdentity(); 24 | glOrtho(0.0, a1, a2, 0.0, 100.0, 300.0); 25 | glMatrixMode(GL_MODELVIEW); 26 | glLoadIdentity(); 27 | glTranslatef(0.0, 0.0, -200.0); 28 | } 29 | 30 | void ProgressBarDisplaySetText(ProgressBarDisplay * display, char * text) { 31 | display->text = text; 32 | ProgressBarDisplaySetProgress(display, -1); 33 | } 34 | 35 | void ProgressBarDisplaySetProgress(ProgressBarDisplay * display, int progress) { 36 | int64_t time = TimeMilli(); 37 | if (time - display->start < 0 || time - display->start >= 20) { 38 | display->start = time; 39 | int a1 = display->minecraft->width * 240 / display->minecraft->height; 40 | int a2 = display->minecraft->height * 240 / display->minecraft->height; 41 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 42 | glBindTexture(GL_TEXTURE_2D, TextureManagerLoad(&display->minecraft->textureManager, "Dirt.png")); 43 | ShapeRendererBegin(); 44 | ShapeRendererColor(0x404040ff); 45 | ShapeRendererVertexUV(0.0, a2, 0.0, 0.0, a2 / 32.0); 46 | ShapeRendererVertexUV(a1, a2, 0.0, a1 / 32.0, a2 / 32.0); 47 | ShapeRendererVertexUV(a1, 0.0, 0.0, a1 / 32.0, 0.0); 48 | ShapeRendererVertexUV(0.0, 0.0, 0.0, 0.0, 0.0); 49 | ShapeRendererEnd(); 50 | if (progress >= 0) { 51 | int b1 = a1 / 2 - 50; 52 | int b2 = a2 / 2 + 16; 53 | glDisable(GL_TEXTURE_2D); 54 | ShapeRendererBegin(); 55 | ShapeRendererColor(0x808080ff); 56 | ShapeRendererVertex(b1, b2, 0.0); 57 | ShapeRendererVertex(b1, b2 + 2, 0.0); 58 | ShapeRendererVertex(b1 + 100, b2 + 2, 0.0); 59 | ShapeRendererVertex(b1 + 100, b2, 0.0); 60 | ShapeRendererColor(0x80ff80ff); 61 | ShapeRendererVertex(b1, b2, 0.0); 62 | ShapeRendererVertex(b1, b2 + 2, 0.0); 63 | ShapeRendererVertex(b1 + progress, b2 + 2, 0.0); 64 | ShapeRendererVertex(b1 + progress, b2, 0.0); 65 | ShapeRendererEnd(); 66 | glEnable(GL_TEXTURE_2D); 67 | } 68 | 69 | FontRendererRender(&display->minecraft->font, display->title, (a1 - FontRendererGetWidth(&display->minecraft->font, display->title)) / 2, a2 / 2 - 4 - 16, 0xffffffff); 70 | FontRendererRender(&display->minecraft->font, display->text, (a1 - FontRendererGetWidth(&display->minecraft->font, display->text)) / 2, a2 / 2 - 4 + 8, 0xffffffff); 71 | 72 | while (SDL_PollEvent(&(SDL_Event){ 0 })); 73 | SDL_GL_SwapWindow(display->minecraft->window); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /MinecraftC/ProgressBarDisplay.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | typedef struct ProgressBarDisplay { 5 | struct Minecraft * minecraft; 6 | char * text; 7 | char * title; 8 | int64_t start; 9 | } ProgressBarDisplay; 10 | 11 | void ProgressBarDisplayCreate(ProgressBarDisplay * display, struct Minecraft * minecraft); 12 | void ProgressBarDisplaySetTitle(ProgressBarDisplay * display, char * title); 13 | void ProgressBarDisplaySetText(ProgressBarDisplay * display, char * text); 14 | void ProgressBarDisplaySetProgress(ProgressBarDisplay * display, int progress); 15 | -------------------------------------------------------------------------------- /MinecraftC/Render/Chunk.c: -------------------------------------------------------------------------------- 1 | #include "Chunk.h" 2 | #include "ShapeRenderer.h" 3 | #include "../Utilities/Log.h" 4 | #include "../Utilities/OpenGL.h" 5 | 6 | int ChunkUpdates = 0; 7 | 8 | void ChunkCreate(Chunk * chunk, Level * level, int x, int y, int z, int chunkSize, int baseListID) { 9 | *chunk = (Chunk) { 10 | .visible = false, 11 | .level = level, 12 | .x = x, 13 | .y = y, 14 | .z = z, 15 | .width = 16, 16 | .height = 16, 17 | .depth = 16, 18 | .baseListID = baseListID, 19 | }; 20 | ChunkSetAllDirty(chunk); 21 | } 22 | 23 | void ChunkUpdate(Chunk * chunk) { 24 | ChunkUpdates++; 25 | int x0 = chunk->x, y0 = chunk->y, z0 = chunk->z; 26 | int x1 = chunk->x + chunk->width; 27 | int y1 = chunk->y + chunk->height; 28 | int z1 = chunk->z + chunk->depth; 29 | 30 | for (int i = 0; i < 2; i++) { 31 | chunk->dirty[i] = true; 32 | } 33 | for (int i = 0; i < 2; i++) { 34 | bool b0 = false; 35 | bool b1 = false; 36 | glNewList(chunk->baseListID + i, GL_COMPILE); 37 | ShapeRendererBegin(); 38 | for (int x = x0; x < x1; x++) { 39 | for (int y = y0; y < y1; y++) { 40 | for (int z = z0; z < z1; z++) { 41 | BlockType tile = LevelGetTile(chunk->level, x, y, z); 42 | if (tile != BlockTypeNone) { 43 | Block * block = &Blocks.table[tile]; 44 | if (BlockGetRenderPass(block) != i) { b0 = true; } 45 | else { b1 |= BlockRender(block, chunk->level, x, y, z); } 46 | } 47 | } 48 | } 49 | } 50 | ShapeRendererEnd(); 51 | glEndList(); 52 | if (b1) { chunk->dirty[i] = false; } 53 | if (!b0) { break; } 54 | } 55 | } 56 | 57 | float ChunkDistanceSquared(Chunk * chunk, Player * player) { 58 | return (player->x - chunk->x) * (player->x - chunk->x) + (player->y - chunk->y) * (player->y - chunk->y) + (player->z - chunk->z) * (player->z - chunk->z); 59 | } 60 | 61 | void ChunkSetAllDirty(Chunk * chunk) { 62 | for (int i = 0; i < 2; i++) { 63 | chunk->dirty[i] = true; 64 | } 65 | } 66 | 67 | void ChunkDispose(Chunk * chunk) { 68 | ChunkSetAllDirty(chunk); 69 | } 70 | 71 | int ChunkAppendLists(Chunk * chunk, int dataCache[], int count, int pass) { 72 | if (!chunk->visible) { return count; } 73 | else { 74 | if (!chunk->dirty[pass]) { dataCache[count++] = chunk->baseListID + pass; } 75 | return count; 76 | } 77 | } 78 | 79 | void ChunkClip(Chunk * chunk, Frustum frustum) { 80 | chunk->visible = FrustumContainsBox(frustum, chunk->x, chunk->y, chunk->z, chunk->x + chunk->width, chunk->y + chunk->height, chunk->z + chunk->depth); 81 | } 82 | 83 | int ChunkDistanceComparator(const void * a, const void * b) { 84 | Chunk * ca = *(Chunk **)a; 85 | Chunk * cb = *(Chunk **)b; 86 | float apx = ca->level->player->x, apy = ca->level->player->y, apz = ca->level->player->z; 87 | float bpx = cb->level->player->x, bpy = cb->level->player->y, bpz = cb->level->player->z; 88 | float distA = (ca->x - apx) * (ca->x - apx) + (ca->y - apy) * (ca->y - apy) + (ca->z - apz) * (ca->z - apz); 89 | float distB = (cb->x - bpx) * (cb->x - bpx) + (cb->y - bpy) * (cb->y - bpy) + (cb->z - bpz) * (cb->z - bpz); 90 | return distA == distB ? 0 : (distA > distB ? 1 : -1); 91 | } 92 | 93 | int ChunkVisibleDistanceComparator(const void * a, const void * b) { 94 | Chunk * ca = *(Chunk **)a; 95 | Chunk * cb = *(Chunk **)b; 96 | if (ca->visible || !cb->visible) { 97 | if (cb->visible) { 98 | float apx = ca->level->player->x, apy = ca->level->player->y, apz = ca->level->player->z; 99 | float bpx = cb->level->player->x, bpy = cb->level->player->y, bpz = cb->level->player->z; 100 | float distA = (ca->x - apx) * (ca->x - apx) + (ca->y - apy) * (ca->y - apy) + (ca->z - apz) * (ca->z - apz); 101 | float distB = (cb->x - bpx) * (cb->x - bpx) + (cb->y - bpy) * (cb->y - bpy) + (cb->z - bpz) * (cb->z - bpz); 102 | return distA == distB ? 0 : (distA > distB ? 1 : -1); 103 | } else { return -1; } 104 | } else { return 1; } 105 | } 106 | -------------------------------------------------------------------------------- /MinecraftC/Render/Chunk.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Level/Level.h" 3 | #include "../Player/Player.h" 4 | #include "../Render/Frustum.h" 5 | 6 | typedef struct Chunk { 7 | Level * level; 8 | int baseListID; 9 | int x, y, z; 10 | int width, depth, height; 11 | bool visible; 12 | bool dirty[2]; 13 | bool loaded; 14 | } Chunk; 15 | 16 | extern int ChunkUpdates; 17 | 18 | void ChunkCreate(Chunk * chunk, Level * level, int x, int y, int z, int chunkSize, int baseListID); 19 | void ChunkUpdate(Chunk * chunk); 20 | float ChunkDistanceSquared(Chunk * chunk, Player * player); 21 | void ChunkSetAllDirty(Chunk * chunk); 22 | void ChunkDispose(Chunk * chunk); 23 | int ChunkAppendLists(Chunk * chunk, int dataCache[], int count, int pass); 24 | void ChunkClip(Chunk * chunk, Frustum frustum); 25 | 26 | int ChunkDistanceComparator(const void * a, const void * b); 27 | int ChunkVisibleDistanceComparator(const void * a, const void * b); 28 | -------------------------------------------------------------------------------- /MinecraftC/Render/Frustum.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Physics/AABB.h" 3 | 4 | typedef struct Frustum { 5 | float planes[6][16]; 6 | float projection[16]; 7 | float modelView[16]; 8 | float clip[16]; 9 | } Frustum; 10 | 11 | Frustum FrustumUpdate(void); 12 | bool FrustumContainsBox(Frustum frustum, float ax, float ay, float az, float bx, float by, float bz); 13 | -------------------------------------------------------------------------------- /MinecraftC/Render/HeldBlock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Level/Tile/Block.h" 3 | 4 | typedef struct HeldBlock { 5 | struct Minecraft * minecraft; 6 | Block * block; 7 | float position; 8 | float lastPosition; 9 | int offset; 10 | bool moving; 11 | } HeldBlock; 12 | -------------------------------------------------------------------------------- /MinecraftC/Render/LevelRenderer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Chunk.h" 3 | #include "../Level/Level.h" 4 | 5 | typedef struct LevelRenderer { 6 | Level * level; 7 | TextureManager * textures; 8 | int listID; 9 | List(Chunk *) chunks; 10 | Chunk ** loadQueue; 11 | Chunk ** chunkCache; 12 | int chunkCacheCount; 13 | int xChunks, yChunks, zChunks; 14 | int baseListID; 15 | int * chunkDataCache; 16 | int ticks; 17 | float lastLoadX, lastLoadY, lastLoadZ; 18 | } LevelRenderer; 19 | 20 | void LevelRendererCreate(LevelRenderer * renderer, struct Minecraft * minecraft, Level * level, TextureManager * textures); 21 | void LevelRendererRefresh(LevelRenderer * renderer); 22 | int LevelRendererSortChunks(LevelRenderer * renderer, Player * player, int pass); 23 | void LevelRendererQueueChunks(LevelRenderer * renderer, int x0, int y0, int z0, int x1, int y1, int z1); 24 | void LevelRendererDestroy(LevelRenderer * renderer); 25 | -------------------------------------------------------------------------------- /MinecraftC/Render/Renderer.c: -------------------------------------------------------------------------------- 1 | #include "Renderer.h" 2 | #include "../Minecraft.h" 3 | #include "../Utilities/SinTable.h" 4 | #include "../Utilities/OpenGL.h" 5 | 6 | void RendererCreate(Renderer * renderer, Minecraft * minecraft) { 7 | *renderer = (Renderer) { 8 | .minecraft = minecraft, 9 | .fogColorMultiplier = 1.0, 10 | .displayActive = false, 11 | .fogEnd = 0.0, 12 | .heldBlock = (HeldBlock){ .minecraft = minecraft }, 13 | .entity = NULL, 14 | }; 15 | RandomGeneratorCreate(&renderer->random, time(NULL)); 16 | } 17 | 18 | Vector3D RendererGetPlayerVector(Renderer * renderer, float dt) { 19 | Player * entity = &renderer->minecraft->player; 20 | return (Vector3D){ entity->xo + (entity->x - entity->xo) * dt, entity->yo + (entity->y - entity->yo) * dt, entity->zo + (entity->z - entity->zo) * dt }; 21 | } 22 | 23 | void RendererApplyBobbing(Renderer * renderer, float dt) { 24 | Player * entity = &renderer->minecraft->player; 25 | PlayerData * player = &entity->player; 26 | float walk = entity->walkDistance - entity->oldWalkDistance; 27 | walk = entity->walkDistance + walk * dt; 28 | float bob = player->oldBobbing + (player->bobbing - player->oldBobbing) * dt; 29 | float tilt = player->oldTilt + (player->tilt - player->oldTilt) * dt; 30 | glTranslatef(tsin(walk * M_PI) * bob * 0.5, -fabs(tcos(walk * M_PI) * bob), 0.0); 31 | glRotatef(tsin(walk * M_PI) * bob * 3.0, 0.0, 0.0, 1.0); 32 | glRotatef(fabs(tcos(walk * M_PI + 0.2) * bob) * 5.0, 1.0, 0.0, 0.0); 33 | glRotatef(tilt, 1.0, 0.0, 0.0); 34 | } 35 | 36 | void RendererSetLighting(Renderer * renderer, bool lighting) { 37 | if (!lighting) { 38 | glDisable(GL_LIGHTING); 39 | glDisable(GL_LIGHT0); 40 | } else { 41 | glEnable(GL_LIGHTING); 42 | glEnable(GL_LIGHT0); 43 | glEnable(GL_COLOR_MATERIAL); 44 | Vector3D pos = Vector3DNormalize((Vector3D){ 0.0, -1.0, 0.5 }); 45 | glLightfv(GL_LIGHT0, GL_POSITION, (float[]){ pos.x, pos.y, pos.z, 0.0 }); 46 | glLightfv(GL_LIGHT0, GL_DIFFUSE, (float[]){ 0.3, 0.3, 0.3, 1.0 }); 47 | glLightfv(GL_LIGHT0, GL_AMBIENT, (float[]){ 0.0, 0.0, 0.0, 1.0 }); 48 | glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float[]){ 0.7, 0.7, 0.7, 1.0 }); 49 | } 50 | } 51 | 52 | void RendererEnableGUIMode(Renderer * renderer) { 53 | int w = renderer->minecraft->width * 240 / renderer->minecraft->height; 54 | int h = renderer->minecraft->height * 240 / renderer->minecraft->height; 55 | glClear(GL_DEPTH_BUFFER_BIT); 56 | glMatrixMode(GL_PROJECTION); 57 | glLoadIdentity(); 58 | glOrtho(0.0, w, h, 0.0, 100.0, 300.0); 59 | glMatrixMode(GL_MODELVIEW); 60 | glLoadIdentity(); 61 | glTranslatef(0.0, 0.0, -200.0); 62 | } 63 | 64 | void RendererUpdateFog(Renderer * renderer) { 65 | Level * level = &renderer->minecraft->level; 66 | Player * player = &renderer->minecraft->player; 67 | glFogfv(GL_FOG_COLOR, (float []){ renderer->fogR, renderer->fogG, renderer->fogB, 1.0 }); 68 | glNormal3f(0.0, -1.0, 0.0); 69 | glColor4f(1.0, 1.0, 1.0, 1.0); 70 | Block * block = &Blocks.table[LevelGetTile(level, player->x, player->y + 0.12, player->z)]; 71 | if (block->type != BlockTypeNone && BlockGetLiquidType(block) != LiquidTypeNone) { 72 | LiquidType liquid = BlockGetLiquidType(block); 73 | glFogi(GL_FOG_MODE, GL_EXP); 74 | if (liquid == LiquidTypeWater) { 75 | glFogf(GL_FOG_DENSITY, 0.1); 76 | Vector3D a = { 0.4, 0.4, 0.9 }; 77 | if (renderer->minecraft->settings.anaglyph) { 78 | a = (Vector3D){ (a.x * 30.0 + a.y * 59.0 + a.z * 11.0) / 100.0, (a.x * 30.0 + a.y * 70.0) / 100.0, (a.x * 30.0 + a.z * 70.0) / 100.0 }; 79 | } 80 | glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float []){ a.x, a.y, a.z, 1.0 }); 81 | } else if (liquid == LiquidTypeLava) { 82 | glFogf(GL_FOG_DENSITY, 2.0); 83 | Vector3D a = { 0.4, 0.3, 0.3 }; 84 | if (renderer->minecraft->settings.anaglyph) { 85 | a = (Vector3D){ (a.x * 30.0 + a.y * 59.0 + a.z * 11.0) / 100.0, (a.x * 30.0 + a.y * 70.0) / 100.0, (a.x * 30.0 + a.z * 70.0) / 100.0 }; 86 | } 87 | glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float []){ a.x, a.y, a.z, 1.0 }); 88 | } 89 | } else { 90 | glFogi(GL_FOG_MODE, GL_LINEAR); 91 | glFogf(GL_FOG_START, 0.0); 92 | glFogf(GL_FOG_END, renderer->fogEnd); 93 | glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float []){ 1.0, 1.0, 1.0, 1.0 }); 94 | } 95 | glEnable(GL_COLOR_MATERIAL); 96 | glColorMaterial(GL_FRONT, GL_AMBIENT); 97 | } 98 | -------------------------------------------------------------------------------- /MinecraftC/Render/Renderer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "HeldBlock.h" 3 | #include "../Entity.h" 4 | 5 | typedef struct Renderer { 6 | struct Minecraft * minecraft; 7 | float fogColorMultiplier; 8 | bool displayActive; 9 | float fogEnd; 10 | HeldBlock heldBlock; 11 | Entity * entity; 12 | RandomGenerator random; 13 | float fogR, fogG, fogB; 14 | } Renderer; 15 | 16 | void RendererCreate(Renderer * renderer, struct Minecraft * minecraft); 17 | Vector3D RendererGetPlayerVector(Renderer * renderer, float dt); 18 | void RendererApplyBobbing(Renderer * renderer, float dt); 19 | void RendererSetLighting(Renderer * renderer, bool lighting); 20 | void RendererEnableGUIMode(Renderer * renderer); 21 | void RendererUpdateFog(Renderer * renderer); 22 | -------------------------------------------------------------------------------- /MinecraftC/Render/ShapeRenderer.c: -------------------------------------------------------------------------------- 1 | #include "ShapeRenderer.h" 2 | #include "../Utilities/Log.h" 3 | #include "../Utilities/OpenGL.h" 4 | #include 5 | 6 | struct ShapeRenderer ShapeRenderer = { 0 }; 7 | static int MaxFloats = 524288; 8 | 9 | void ShapeRendererInitialize() { 10 | ShapeRenderer.buffer = malloc(MaxFloats * sizeof(float)); 11 | ShapeRenderer.vertices = 0; 12 | ShapeRenderer.hasColor = false; 13 | ShapeRenderer.hasTexture = false; 14 | ShapeRenderer.vertexLength = 3; 15 | ShapeRenderer.length = 0; 16 | ShapeRenderer.noColor = false; 17 | } 18 | 19 | void ShapeRendererBegin() { 20 | ShapeRendererClear(); 21 | ShapeRenderer.hasTexture = false; 22 | ShapeRenderer.hasColor = false; 23 | ShapeRenderer.noColor = false; 24 | } 25 | 26 | void ShapeRendererEnd() { 27 | if (ShapeRenderer.vertices > 0) { 28 | if (ShapeRenderer.hasTexture && ShapeRenderer.hasColor) { glInterleavedArrays(GL_T2F_C3F_V3F, 0, ShapeRenderer.buffer); } 29 | else if (ShapeRenderer.hasTexture) { glInterleavedArrays(GL_T2F_V3F, 0, ShapeRenderer.buffer); } 30 | else if (ShapeRenderer.hasColor) { glInterleavedArrays(GL_C3F_V3F, 0, ShapeRenderer.buffer); } 31 | else { glInterleavedArrays(GL_V3F, 0, ShapeRenderer.buffer); } 32 | 33 | glEnableClientState(GL_VERTEX_ARRAY); 34 | if (ShapeRenderer.hasTexture) { glEnableClientState(GL_TEXTURE_COORD_ARRAY); } 35 | if (ShapeRenderer.hasColor) { glEnableClientState(GL_COLOR_ARRAY); } 36 | 37 | glDrawArrays(GL_QUADS, 0, ShapeRenderer.vertices); 38 | glDisableClientState(GL_VERTEX_ARRAY); 39 | if (ShapeRenderer.hasTexture) { glDisableClientState(GL_TEXTURE_COORD_ARRAY); } 40 | if (ShapeRenderer.hasColor) { glDisableClientState(GL_COLOR_ARRAY); } 41 | } 42 | 43 | ShapeRendererClear(); 44 | } 45 | 46 | void ShapeRendererClear() { 47 | ShapeRenderer.vertices = 0; 48 | ShapeRenderer.length = 0; 49 | } 50 | 51 | void ShapeRendererColorf(float r, float g, float b) { 52 | if (!ShapeRenderer.noColor) { 53 | if (!ShapeRenderer.hasColor) { ShapeRenderer.vertexLength += 3; } 54 | ShapeRenderer.hasColor = true; 55 | ShapeRenderer.r = r; 56 | ShapeRenderer.g = g; 57 | ShapeRenderer.b = b; 58 | } 59 | } 60 | 61 | void ShapeRendererColor(uint32_t c) { 62 | ShapeRendererColorf((c >> 24) / 255.0, ((c >> 16) & 0xff) / 255.0, ((c >> 8) & 0xff) / 255.0); 63 | } 64 | 65 | void ShapeRendererVertexUV(float x, float y, float z, float u, float v) { 66 | if (!ShapeRenderer.hasTexture) { ShapeRenderer.vertexLength += 2; } 67 | ShapeRenderer.hasTexture = true; 68 | ShapeRenderer.u = u; 69 | ShapeRenderer.v = v; 70 | ShapeRendererVertex(x, y, z); 71 | } 72 | 73 | void ShapeRendererVertex(float x, float y, float z) { 74 | if (ShapeRenderer.hasTexture) { 75 | ShapeRenderer.buffer[ShapeRenderer.length++] = ShapeRenderer.u; 76 | ShapeRenderer.buffer[ShapeRenderer.length++] = ShapeRenderer.v; 77 | } 78 | 79 | if (ShapeRenderer.hasColor) { 80 | ShapeRenderer.buffer[ShapeRenderer.length++] = ShapeRenderer.r; 81 | ShapeRenderer.buffer[ShapeRenderer.length++] = ShapeRenderer.g; 82 | ShapeRenderer.buffer[ShapeRenderer.length++] = ShapeRenderer.b; 83 | } 84 | 85 | ShapeRenderer.buffer[ShapeRenderer.length++] = x; 86 | ShapeRenderer.buffer[ShapeRenderer.length++] = y; 87 | ShapeRenderer.buffer[ShapeRenderer.length++] = z; 88 | 89 | ShapeRenderer.vertices++; 90 | if (ShapeRenderer.vertices % 4 == 0 && ShapeRenderer.length >= MaxFloats - (ShapeRenderer.vertexLength * 4)) { 91 | ShapeRendererEnd(); 92 | ShapeRenderer.vertexLength = 3; 93 | } 94 | } 95 | 96 | void ShapeRendererNoColor() { 97 | ShapeRenderer.noColor = true; 98 | } 99 | 100 | void ShapeRendererNormal(float nx, float ny, float nz) { 101 | glNormal3f(nx, ny, nz); 102 | } 103 | 104 | void ShapeRendererDeinitialize() { 105 | free(ShapeRenderer.buffer); 106 | } 107 | -------------------------------------------------------------------------------- /MinecraftC/Render/ShapeRenderer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | extern struct ShapeRenderer { 6 | float * buffer; 7 | int vertices; 8 | float u, v; 9 | float r, g, b; 10 | bool hasColor; 11 | bool hasTexture; 12 | int vertexLength; 13 | int length; 14 | bool noColor; 15 | } ShapeRenderer; 16 | 17 | void ShapeRendererInitialize(void); 18 | void ShapeRendererBegin(void); 19 | void ShapeRendererEnd(void); 20 | void ShapeRendererClear(void); 21 | void ShapeRendererColor(uint32_t color); 22 | void ShapeRendererColorf(float r, float g, float b); 23 | void ShapeRendererVertexUV(float x, float y, float z, float u, float v); 24 | void ShapeRendererVertex(float x, float y, float z); 25 | void ShapeRendererNoColor(void); 26 | void ShapeRendererNormal(float nx, float ny, float nz); 27 | void ShapeRendererDeinitialize(void); 28 | -------------------------------------------------------------------------------- /MinecraftC/Render/Texture/AnimatedTexture.c: -------------------------------------------------------------------------------- 1 | #include "AnimatedTexture.h" 2 | #include "LavaTexture.h" 3 | #include "WaterTexture.h" 4 | #include 5 | 6 | void AnimatedTextureCreate(AnimatedTexture * texture, int textureID) { 7 | *texture = (AnimatedTexture) { 8 | .textureID = textureID, 9 | }; 10 | } 11 | 12 | void AnimatedTextureAnimate(AnimatedTexture * texture) { 13 | if (texture->type == AnimatedTextureTypeLava) { LavaTextureAnimate(texture); return; } 14 | if (texture->type == AnimatedTextureTypeWater) { WaterTextureAnimate(texture); return; } 15 | } 16 | -------------------------------------------------------------------------------- /MinecraftC/Render/Texture/AnimatedTexture.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "WaterTexture.h" 5 | #include "LavaTexture.h" 6 | 7 | typedef enum AnimatedTextureType { 8 | AnimatedTextureTypeNone, 9 | AnimatedTextureTypeWater, 10 | AnimatedTextureTypeLava, 11 | } AnimatedTextureType; 12 | 13 | typedef struct AnimatedTexture { 14 | uint8_t data[1024]; 15 | int textureID; 16 | bool anaglyph; 17 | AnimatedTextureType type; 18 | union { 19 | WaterTextureData water; 20 | LavaTextureData lava; 21 | }; 22 | } AnimatedTexture; 23 | 24 | void AnimatedTextureCreate(AnimatedTexture * texture, int textureID); 25 | void AnimatedTextureAnimate(AnimatedTexture * texture); 26 | -------------------------------------------------------------------------------- /MinecraftC/Render/Texture/LavaTexture.c: -------------------------------------------------------------------------------- 1 | #include "LavaTexture.h" 2 | #include "../../Level/Tile/Block.h" 3 | #include "../../Utilities/SinTable.h" 4 | 5 | void LavaTextureCreate(LavaTexture * texture) { 6 | AnimatedTextureCreate(texture, Blocks.table[BlockTypeLava].textureID); 7 | texture->type = AnimatedTextureTypeLava; 8 | texture->lava = (LavaTextureData){ 0 }; 9 | } 10 | 11 | void LavaTextureAnimate(LavaTexture * texture) { 12 | LavaTextureData * this = &texture->lava; 13 | for (int x = 0; x < 16; x++) { 14 | for (int y = 0; y < 16; y++) { 15 | int sy = tsin(y * M_PI / 8.0) * 1.2; 16 | int sx = tsin(x * M_PI / 8.0) * 1.2; 17 | float v = 0.0; 18 | for (int i = x - 1; i <= x + 1; i++) { 19 | for (int j = y - 1; j <= y + 1; j++) { 20 | int a = i + sy & 15; 21 | int b = j + sx & 15; 22 | v += this->red[a + (b << 4)]; 23 | } 24 | } 25 | this->green[x + (y << 4)] = v / 10.0 + (this->blue[(x & 15) + ((y & 15) << 4)] + this->blue[(x + 1 & 15) + ((y & 15) << 4)] + this->blue[(x + 1 & 15) + ((y + 1 & 15) << 4)] + this->blue[(x & 15) + ((y + 1 & 15) << 4)]) / 4.0 * 0.8; 26 | this->blue[x + (y << 4)] += this->alpha[x + (y << 4)] * 0.01; 27 | if (this->blue[x + (y << 4)] < 0.0) { this->blue[x + (y << 4)] = 0.0; } 28 | this->alpha[x + (y << 4)] -= 0.06; 29 | if (RandomUniform() < 0.005) { this->alpha[x + (y << 4)] = 1.5; } 30 | } 31 | } 32 | 33 | for (int i = 0; i < 256; i++) { 34 | float red = this->red[i]; 35 | this->red[i] = this->green[i]; 36 | this->green[i] = red; 37 | float v = this->red[i] * 2.0; 38 | if (v > 1.0) { v = 1.0; } 39 | if (v < 0.0) { v = 0.0; } 40 | int a = v * 100.0 + 155.0; 41 | int b = v * v * 255.0; 42 | int c = v * v * v * v * 128.0; 43 | if (texture->anaglyph) { 44 | int aa = (a * 30 + b * 59 + c * 11) / 100; 45 | int bb = (a * 30 + b * 70) / 100; 46 | int cc = (a * 30 + c * 70) / 100; 47 | a = aa; 48 | b = bb; 49 | c = cc; 50 | } 51 | texture->data[i << 2] = a; 52 | texture->data[(i << 2) + 1] = b; 53 | texture->data[(i << 2) + 2] = c; 54 | texture->data[(i << 2) + 3] = -1; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /MinecraftC/Render/Texture/LavaTexture.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef struct AnimatedTexture LavaTexture; 4 | 5 | typedef struct LavaTextureData { 6 | float red[256]; 7 | float green[256]; 8 | float blue[256]; 9 | float alpha[256]; 10 | } LavaTextureData; 11 | 12 | void LavaTextureCreate(LavaTexture * texture); 13 | void LavaTextureAnimate(LavaTexture * texture); 14 | -------------------------------------------------------------------------------- /MinecraftC/Render/Texture/WaterTexture.c: -------------------------------------------------------------------------------- 1 | #include "WaterTexture.h" 2 | #include "../../Level/Tile/Block.h" 3 | 4 | void WaterTextureCreate(WaterTexture * texture) { 5 | AnimatedTextureCreate(texture, Blocks.table[BlockTypeWater].textureID); 6 | texture->type = AnimatedTextureTypeWater; 7 | texture->water = (WaterTextureData){ 0 }; 8 | } 9 | 10 | void WaterTextureAnimate(WaterTexture * texture) { 11 | WaterTextureData * this = &texture->water; 12 | this->updates++; 13 | 14 | for (int x = 0; x < 16; x++) { 15 | for (int y = 0; y < 16; y++) { 16 | float v = 0.0; 17 | for (int i = x - 1; i <= x + 1; i++) { 18 | int a = i & 15; 19 | int b = y & 15; 20 | v += this->red[a + (b << 4)]; 21 | } 22 | this->blue[x + (y << 4)] = v / 3.3 + this->green[x + (y << 4)] * 0.8; 23 | } 24 | } 25 | for (int x = 0; x < 16; x++) { 26 | for (int y = 0; y < 16; y++) { 27 | this->green[x + (y << 4)] += this->alpha[x + (y << 4)] * 0.05; 28 | if (this->green[x + (y << 4)] < 0.0) { this->green[x + (y << 4)] = 0.0; } 29 | this->alpha[x + (y << 4)] -= 0.1; 30 | if (RandomUniform() < 0.05) { this->alpha[x + (y << 4)] = 0.5; } 31 | } 32 | } 33 | 34 | for (int i = 0; i < 256; i++) { 35 | float blue = this->blue[i]; 36 | this->blue[i] = this->red[i]; 37 | this->red[i] = blue; 38 | float v = this->red[i]; 39 | if (v > 1.0) { v = 1.0; } 40 | if (v < 0.0) { v = 0.0; } 41 | int a = 32.0 + v * v * 32.0; 42 | int b = 50.0 + v * v * 64.0; 43 | int c = 255; 44 | int d = 146.0 + v * v * 50.0; 45 | if (texture->anaglyph) { 46 | int aa = (a * 30 + b * 59 + c * 11) / 100; 47 | int bb = (a * 30 + b * 70) / 100; 48 | int cc = (a * 30 + c * 70) / 100; 49 | a = aa; 50 | b = bb; 51 | c = cc; 52 | } 53 | texture->data[i << 2] = a; 54 | texture->data[(i << 2) + 1] = b; 55 | texture->data[(i << 2) + 2] = c; 56 | texture->data[(i << 2) + 3] = d; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /MinecraftC/Render/Texture/WaterTexture.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef struct AnimatedTexture WaterTexture; 4 | 5 | typedef struct WaterTextureData { 6 | float red[256]; 7 | float green[256]; 8 | float blue[256]; 9 | float alpha[256]; 10 | int updates; 11 | } WaterTextureData; 12 | 13 | void WaterTextureCreate(WaterTexture * texutre); 14 | void WaterTextureAnimate(WaterTexture * texture); 15 | -------------------------------------------------------------------------------- /MinecraftC/Render/TextureManager.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "TextureManager.h" 3 | #include "../Utilities/Log.h" 4 | #include "../Utilities/OpenGL.h" 5 | #include "../../Resources/GUI/GUI.h" 6 | #include "../../Resources/GUI/Icons.h" 7 | #include "../../Resources/Clouds.h" 8 | #include "../../Resources/Default.h" 9 | #include "../../Resources/Dirt.h" 10 | #include "../../Resources/Particles.h" 11 | #include "../../Resources/Rain.h" 12 | #include "../../Resources/Rock.h" 13 | #include "../../Resources/Terrain.h" 14 | #include "../../Resources/Water.h" 15 | #include 16 | 17 | void TextureManagerCreate(TextureManager * manager, GameSettings * settings) { 18 | *manager = (TextureManager) { 19 | .settings = settings, 20 | .animations = ListCreate(sizeof(AnimatedTexture *)), 21 | .textureBuffer = malloc(512 * 512), 22 | .textures = ListCreate(sizeof(unsigned int)), 23 | .textureNames = ListCreate(sizeof(char *)), 24 | }; 25 | } 26 | 27 | int TextureManagerLoad(TextureManager * manager, char * resource) { 28 | bool loaded = false; 29 | int index = -1; 30 | for (int i = 0; i < ListLength(manager->textureNames); i++) { 31 | if (strcmp(manager->textureNames[i], resource) == 0) { 32 | loaded = true; 33 | index = i; 34 | } 35 | } 36 | if (loaded) { return manager->textures[index]; } 37 | 38 | int width = 0, height = 0; 39 | uint8_t * p = NULL; 40 | if (strcmp(resource, "Clouds.png") == 0) { p = (uint8_t *)Resource_Clouds_RGBA; width = Resource_Clouds_Width; height = Resource_Clouds_Height; } 41 | if (strcmp(resource, "Default.png") == 0) { p = (uint8_t *)Resource_Default_RGBA; width = Resource_Default_Width; height = Resource_Default_Height; } 42 | if (strcmp(resource, "Dirt.png") == 0) { p = (uint8_t *)Resource_Dirt_RGBA; width = Resource_Dirt_Width; height = Resource_Dirt_Height; } 43 | if (strcmp(resource, "Particles.png") == 0) { p = (uint8_t *)Resource_Particles_RGBA; width = Resource_Particles_Width; height = Resource_Particles_Height; } 44 | if (strcmp(resource, "Rain.png") == 0) { p = (uint8_t *)Resource_Rain_RGBA; width = Resource_Rain_Width; height = Resource_Rain_Height; } 45 | if (strcmp(resource, "Rock.png") == 0) { p = (uint8_t *)Resource_Rock_RGBA; width = Resource_Rock_Width; height = Resource_Rock_Height; } 46 | if (strcmp(resource, "Terrain.png") == 0) { p = (uint8_t *)Resource_Terrain_RGBA; width = Resource_Terrain_Width; height = Resource_Terrain_Height; } 47 | if (strcmp(resource, "Water.png") == 0) { p = (uint8_t *)Resource_Water_RGBA; width = Resource_Water_Width; height = Resource_Water_Height; } 48 | if (strcmp(resource, "GUI/GUI.png") == 0) { p = (uint8_t *)Resource_GUI_GUI_RGBA; width = Resource_GUI_GUI_Width; height = Resource_GUI_GUI_Height; } 49 | if (strcmp(resource, "GUI/Icons.png") == 0) { p = (uint8_t *)Resource_GUI_Icons_RGBA; width = Resource_GUI_Icons_Width; height = Resource_GUI_Icons_Height; } 50 | if (p == NULL) { LogFatal("Failed to load image %s.\n", resource); } 51 | 52 | uint8_t * pixels = malloc(4 * width * height); 53 | if (manager->settings->anaglyph) { 54 | for (int i = 0; i < 4 * width * height; i += 4) { 55 | uint8_t color[] = { (p[i + 0] * 30 + p[i + 1] * 59 + p[i + 2] * 11) / 100, (p[i + 0] * 30 + p[i + 1] * 70) / 100, (p[i + 0] * 30 + p[i + 2] * 70) / 100, p[i + 3] }; 56 | memcpy(pixels + i, color, sizeof(color)); 57 | } 58 | } else { memcpy(pixels, p, 4 * width * height); } 59 | 60 | glGenTextures(1, &manager->idBuffer); 61 | glBindTexture(GL_TEXTURE_2D, manager->idBuffer); 62 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 63 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 64 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); 65 | free(pixels); 66 | 67 | manager->textureNames = ListPush(manager->textureNames, &resource); 68 | manager->textures = ListPush(manager->textures, &manager->idBuffer); 69 | return manager->idBuffer; 70 | } 71 | 72 | void TextureManagerReload(TextureManager * manager) { 73 | for (int i = 0; i < ListLength(manager->textures); i++) { glDeleteTextures(1, &manager->textures[i]); } 74 | manager->textures = ListClear(manager->textures); 75 | manager->textureNames = ListClear(manager->textureNames); 76 | } 77 | 78 | void TextureManagerRegisterAnimation(TextureManager * manager, AnimatedTexture * texture) { 79 | manager->animations = ListPush(manager->animations, &texture); 80 | AnimatedTextureAnimate(texture); 81 | } 82 | 83 | void TextureManagerDestroy(TextureManager * manager) { 84 | ListFree(manager->textures); 85 | ListFree(manager->textureNames); 86 | ListFree(manager->animations); 87 | free(manager->textureBuffer); 88 | } 89 | 90 | -------------------------------------------------------------------------------- /MinecraftC/Render/TextureManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Utilities/List.h" 3 | #include "../GameSettings.h" 4 | #include "Texture/AnimatedTexture.h" 5 | 6 | typedef struct TextureManager { 7 | List(unsigned int) textures; 8 | List(char *) textureNames; 9 | uint8_t * textureBuffer; 10 | unsigned int idBuffer; 11 | List(AnimatedTexture *) animations; 12 | GameSettings * settings; 13 | } TextureManager; 14 | 15 | void TextureManagerCreate(TextureManager * manager, GameSettings * settings); 16 | int TextureManagerLoad(TextureManager * manager, char * resource); 17 | void TextureManagerReload(TextureManager * manager); 18 | void TextureManagerRegisterAnimation(TextureManager * textures, AnimatedTexture * texture); 19 | void TextureManagerDestroy(TextureManager * textures); 20 | -------------------------------------------------------------------------------- /MinecraftC/SessionData.c: -------------------------------------------------------------------------------- 1 | #include "SessionData.h" 2 | 3 | List(BlockType) SessionDataAllowedBlocks = NULL; 4 | 5 | void SessionDataInitialize() { 6 | SessionDataAllowedBlocks = ListCreate(sizeof(BlockType)); 7 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeStone }); 8 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeCobbleStone }); 9 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeBrick }); 10 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeDirt }); 11 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeWood }); 12 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeLog }); 13 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeLeaves }); 14 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeGlass }); 15 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeSlab }); 16 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeMossyCobbleStone }); 17 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeSapling }); 18 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeDandelion }); 19 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeRose }); 20 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeBrownMushroom }); 21 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeRedMushroom }); 22 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeSand }); 23 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeGravel }); 24 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeSponge }); 25 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeRedWool }); 26 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeOrangeWool }); 27 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeYellowWool }); 28 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeLimeWool }); 29 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeGreenWool }); 30 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeAquaGreenWool }); 31 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeCyanWool }); 32 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeBlueWool }); 33 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypePurpleWool }); 34 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeIndigoWool }); 35 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeVioletWool }); 36 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeMagentaWool }); 37 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypePinkWool }); 38 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeBlackWool }); 39 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeGrayWool }); 40 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeWhiteWool }); 41 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeCoalOre }); 42 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeIronOre }); 43 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeGoldOre }); 44 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeIron }); 45 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeGold }); 46 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeBookshelf }); 47 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeTNT }); 48 | SessionDataAllowedBlocks = ListPush(SessionDataAllowedBlocks, &(BlockType){ BlockTypeObsidian }); 49 | } 50 | 51 | void SessionDataFree() { 52 | ListFree(SessionDataAllowedBlocks); 53 | } 54 | -------------------------------------------------------------------------------- /MinecraftC/SessionData.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Utilities/String.h" 3 | #include "Level/Tile/Block.h" 4 | 5 | extern List(BlockType) SessionDataAllowedBlocks; 6 | void SessionDataInitialize(void); 7 | void SessionDataFree(void); 8 | -------------------------------------------------------------------------------- /MinecraftC/Sound/SoundManager.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "SoundManager.h" 5 | #include "../Utilities/Log.h" 6 | #include "../../Resources/Music/Calm1.h" 7 | #include "../../Resources/Music/Calm2.h" 8 | #include "../../Resources/Music/Calm3.h" 9 | #include "../../Resources/Sound/Step/Grass1.h" 10 | #include "../../Resources/Sound/Step/Grass2.h" 11 | #include "../../Resources/Sound/Step/Grass3.h" 12 | #include "../../Resources/Sound/Step/Grass4.h" 13 | #include "../../Resources/Sound/Step/Gravel1.h" 14 | #include "../../Resources/Sound/Step/Gravel2.h" 15 | #include "../../Resources/Sound/Step/Gravel3.h" 16 | #include "../../Resources/Sound/Step/Gravel4.h" 17 | #include "../../Resources/Sound/Step/Stone1.h" 18 | #include "../../Resources/Sound/Step/Stone2.h" 19 | #include "../../Resources/Sound/Step/Stone3.h" 20 | #include "../../Resources/Sound/Step/Stone4.h" 21 | #include "../../Resources/Sound/Step/Wood1.h" 22 | #include "../../Resources/Sound/Step/Wood2.h" 23 | #include "../../Resources/Sound/Step/Wood3.h" 24 | #include "../../Resources/Sound/Step/Wood4.h" 25 | 26 | void SoundManagerCreate(SoundManager * manager) { 27 | *manager = (SoundManager){ 28 | .lastMusic = 0, 29 | }; 30 | RandomGeneratorCreate(&manager->random, time(NULL)); 31 | 32 | manager->calm[0] = cs_read_mem_ogg((void *)Resource_Music_Calm1, sizeof(Resource_Music_Calm1), NULL); 33 | manager->calm[1] = cs_read_mem_ogg((void *)Resource_Music_Calm2, sizeof(Resource_Music_Calm2), NULL); 34 | manager->calm[2] = cs_read_mem_ogg((void *)Resource_Music_Calm3, sizeof(Resource_Music_Calm3), NULL); 35 | manager->grass[0] = cs_read_mem_ogg((void *)Resource_Sound_Step_Grass1, sizeof(Resource_Sound_Step_Grass1), NULL); 36 | manager->grass[1] = cs_read_mem_ogg((void *)Resource_Sound_Step_Grass2, sizeof(Resource_Sound_Step_Grass2), NULL); 37 | manager->grass[2] = cs_read_mem_ogg((void *)Resource_Sound_Step_Grass3, sizeof(Resource_Sound_Step_Grass3), NULL); 38 | manager->grass[3] = cs_read_mem_ogg((void *)Resource_Sound_Step_Grass4, sizeof(Resource_Sound_Step_Grass4), NULL); 39 | manager->gravel[0] = cs_read_mem_ogg((void *)Resource_Sound_Step_Gravel1, sizeof(Resource_Sound_Step_Gravel1), NULL); 40 | manager->gravel[1] = cs_read_mem_ogg((void *)Resource_Sound_Step_Gravel2, sizeof(Resource_Sound_Step_Gravel2), NULL); 41 | manager->gravel[2] = cs_read_mem_ogg((void *)Resource_Sound_Step_Gravel3, sizeof(Resource_Sound_Step_Gravel3), NULL); 42 | manager->gravel[3] = cs_read_mem_ogg((void *)Resource_Sound_Step_Gravel4, sizeof(Resource_Sound_Step_Gravel4), NULL); 43 | manager->stone[0] = cs_read_mem_ogg((void *)Resource_Sound_Step_Stone1, sizeof(Resource_Sound_Step_Stone1), NULL); 44 | manager->stone[1] = cs_read_mem_ogg((void *)Resource_Sound_Step_Stone2, sizeof(Resource_Sound_Step_Stone2), NULL); 45 | manager->stone[2] = cs_read_mem_ogg((void *)Resource_Sound_Step_Stone3, sizeof(Resource_Sound_Step_Stone3), NULL); 46 | manager->stone[3] = cs_read_mem_ogg((void *)Resource_Sound_Step_Stone4, sizeof(Resource_Sound_Step_Stone4), NULL); 47 | manager->wood[0] = cs_read_mem_ogg((void *)Resource_Sound_Step_Wood1, sizeof(Resource_Sound_Step_Wood1), NULL); 48 | manager->wood[1] = cs_read_mem_ogg((void *)Resource_Sound_Step_Wood2, sizeof(Resource_Sound_Step_Wood2), NULL); 49 | manager->wood[2] = cs_read_mem_ogg((void *)Resource_Sound_Step_Wood3, sizeof(Resource_Sound_Step_Wood3), NULL); 50 | manager->wood[3] = cs_read_mem_ogg((void *)Resource_Sound_Step_Wood4, sizeof(Resource_Sound_Step_Wood4), NULL); 51 | } 52 | 53 | void SoundManagerPlayMusic(SoundManager * manager, char * music) { 54 | if (strcmp(music, "Calm") == 0) { 55 | cs_music_stop(0.0); 56 | cs_music_play(manager->calm[RandomGeneratorIntegerRange(&manager->random, 0, 2)], 0.0); 57 | cs_music_set_loop(false); 58 | } 59 | } 60 | 61 | void SoundManagerPlaySound(SoundManager * manager, char * sound, float volume, float pitch) { 62 | if (strcmp(sound, "Grass") == 0) { 63 | cs_play_sound(manager->grass[RandomGeneratorIntegerRange(&manager->random, 0, 3)], (cs_sound_params_t){ .pan = 0.5, .volume = volume }); 64 | } 65 | if (strcmp(sound, "Gravel") == 0) { 66 | cs_play_sound(manager->gravel[RandomGeneratorIntegerRange(&manager->random, 0, 3)], (cs_sound_params_t){ .pan = 0.5, .volume = volume }); 67 | } 68 | if (strcmp(sound, "Stone") == 0) { 69 | cs_play_sound(manager->stone[RandomGeneratorIntegerRange(&manager->random, 0, 3)], (cs_sound_params_t){ .pan = 0.5, .volume = volume }); 70 | } 71 | if (strcmp(sound, "Wood") == 0) { 72 | cs_play_sound(manager->wood[RandomGeneratorIntegerRange(&manager->random, 0, 3)], (cs_sound_params_t){ .pan = 0.5, .volume = volume }); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /MinecraftC/Sound/SoundManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Utilities/Random.h" 3 | #define STB_VORBIS_HEADER_ONLY 4 | #include 5 | #include 6 | 7 | typedef struct SoundManager { 8 | uint64_t lastMusic; 9 | RandomGenerator random; 10 | cs_audio_source_t * calm[3]; 11 | cs_audio_source_t * grass[4]; 12 | cs_audio_source_t * gravel[4]; 13 | cs_audio_source_t * stone[4]; 14 | cs_audio_source_t * wood[4]; 15 | float volume[4]; 16 | float pitch[4]; 17 | } SoundManager; 18 | 19 | void SoundManagerCreate(SoundManager * manager); 20 | void SoundManagerPlayMusic(SoundManager * manager, char * music); 21 | void SoundManagerPlaySound(SoundManager * manager, char * sound, float volume, float pitch); 22 | -------------------------------------------------------------------------------- /MinecraftC/Timer.c: -------------------------------------------------------------------------------- 1 | #include "Timer.h" 2 | #include "Utilities/Time.h" 3 | #include 4 | 5 | void TimerCreate(Timer * timer, float ticksPerSecond) { 6 | *timer = (Timer) { 7 | .speed = 1.0, 8 | .elapsedDelta = 0.0, 9 | .adjustment = 1.0, 10 | .ticksPerSecond = ticksPerSecond, 11 | .lastSystemClock = TimeMilli(), 12 | .lastHRClock = TimeNano() / 1e6, 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /MinecraftC/Timer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | typedef struct Timer { 5 | float ticksPerSecond; 6 | float lastHR; 7 | int elapsedTicks; 8 | float delta; 9 | float speed; 10 | float elapsedDelta; 11 | uint64_t lastSystemClock; 12 | uint64_t lastHRClock; 13 | float adjustment; 14 | } Timer; 15 | 16 | void TimerCreate(Timer * timer, float ticksPerSecond); 17 | -------------------------------------------------------------------------------- /MinecraftC/Utilities/List.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "List.h" 4 | 5 | struct ListInfo { 6 | uint32_t elementSize; 7 | uint32_t capacity; 8 | uint32_t length; 9 | }; 10 | 11 | List(void) ListCreate(uint32_t elementSize) { 12 | struct ListInfo * list = malloc(sizeof(struct ListInfo) + elementSize); 13 | list->elementSize = elementSize; 14 | list->capacity = 1; 15 | list->length = 0; 16 | return list + 1; 17 | } 18 | 19 | uint32_t ListLength(List(void) list) { 20 | return ((struct ListInfo *)list - 1)->length; 21 | } 22 | 23 | uint32_t ListElementSize(List(void) list) { 24 | return ((struct ListInfo *)list - 1)->elementSize; 25 | } 26 | 27 | uint32_t ListCapacity(List(void) list) { 28 | return ((struct ListInfo *)list - 1)->capacity; 29 | } 30 | 31 | List(void) ListInsert(List(void) list, void * element, int32_t index) { 32 | struct ListInfo * info = (struct ListInfo *)list - 1; 33 | info->length++; 34 | if (info->length == info->capacity) { 35 | info->capacity *= 2; 36 | info = realloc(info, sizeof(struct ListInfo) + info->capacity * info->elementSize); 37 | list = info + 1; 38 | } 39 | memmove((uint8_t *)list + (index + 1) * info->elementSize, (uint8_t *)list + index * info->elementSize, (info->length - 1 - index) * info->elementSize); 40 | memcpy((uint8_t *)list + index * info->elementSize, element, info->elementSize); 41 | return list; 42 | } 43 | 44 | List(void) ListRemove(List(void) list, int32_t index) { 45 | struct ListInfo * info = (struct ListInfo *)list - 1; 46 | for (uint32_t j = (index + 1) * info->elementSize; j < info->length * info->elementSize; j++) { 47 | ((uint8_t *)list)[j - info->elementSize] = ((uint8_t *)list)[j]; 48 | } 49 | info->length--; 50 | if (info->length == info->capacity / 2 - 1) { 51 | info->capacity /= 2; 52 | info = realloc(info, sizeof(struct ListInfo) + info->capacity * info->elementSize); 53 | list = info + 1; 54 | } 55 | return list; 56 | } 57 | 58 | List(void) ListPush(List(void) list, void * value) { 59 | return ListInsert(list, value, ListLength(list)); 60 | } 61 | 62 | List(void) ListPop(List(void) list) { 63 | return ListRemove(list, ListLength(list) - 1); 64 | } 65 | 66 | List(void) ListRemoveAll(List(void) list, void * value) { 67 | for (uint32_t i = 0; i < ListLength(list); i++) { 68 | if (memcmp((uint8_t *)list + i * ListElementSize(list), value, ListElementSize(list)) == 0) { 69 | list = ListRemove(list, i); 70 | i--; 71 | } 72 | } 73 | return list; 74 | } 75 | 76 | void ListSet(List(void) list, int32_t index, void * element) { 77 | struct ListInfo * info = (struct ListInfo *)list - 1; 78 | memcpy((uint8_t *)list + index * info->elementSize, element, info->elementSize); 79 | } 80 | 81 | void * ListGet(List(void) list, int32_t index) { 82 | struct ListInfo * info = (struct ListInfo *)list - 1; 83 | return (uint8_t *)list + index * info->elementSize; 84 | } 85 | 86 | int32_t ListIndexOf(List(void) list, void * value) { 87 | for (uint32_t i = 0; i < ListLength(list); i++) { 88 | if (memcmp((uint8_t *)list + i * ListElementSize(list), value, ListElementSize(list)) == 0) { return i; } 89 | } 90 | return -1; 91 | } 92 | 93 | bool ListContains(List(void) list, void * value) { 94 | return ListIndexOf(list, value) >= 0; 95 | } 96 | 97 | List(void) ListClear(List(void) list) { 98 | List(void) newList = ListCreate(ListElementSize(list)); 99 | ListFree(list); 100 | return newList; 101 | } 102 | 103 | List(void) ListClone(List(void) list) { 104 | uint64_t size = sizeof(struct ListInfo) + ListElementSize(list) * ListCapacity(list); 105 | struct ListInfo * clone = malloc(size); 106 | memcpy(clone, (struct ListInfo *)list - 1, size); 107 | return clone + 1; 108 | } 109 | 110 | void ListFree(List(void) list) { 111 | free((struct ListInfo *)list - 1); 112 | } 113 | -------------------------------------------------------------------------------- /MinecraftC/Utilities/List.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #define List(type) type* 7 | 8 | List(void) ListCreate(uint32_t elementSize); 9 | 10 | uint32_t ListLength(List(void) list); 11 | 12 | uint32_t ListElementSize(List(void) list); 13 | 14 | uint32_t ListCapacity(List(void) list); 15 | 16 | List(void) ListInsert(List(void) list, void * value, int32_t index); 17 | 18 | List(void) ListRemove(List(void) list, int32_t index); 19 | 20 | List(void) ListPush(List(void) list, void * value); 21 | 22 | List(void) ListPop(List(void) list); 23 | 24 | List(void) ListRemoveAll(List(void) list, void * value); 25 | 26 | List(void) ListRemoveFirst(List(void) list, void * value); 27 | 28 | List(void) ListRemoveLast(List(void) list, void * value); 29 | 30 | void ListSet(List(void) list, int32_t index, void * value); 31 | 32 | void * ListGet(List(void) list, int32_t index); 33 | 34 | int32_t ListIndexOf(List(void) list, void * value); 35 | 36 | bool ListContains(List(void) list, void * value); 37 | 38 | List(void) ListClear(List(void) list); 39 | 40 | List(void) ListClone(List(void) list); 41 | 42 | void ListFree(List(void) list); 43 | 44 | -------------------------------------------------------------------------------- /MinecraftC/Utilities/Log.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "Log.h" 7 | 8 | static struct { 9 | FILE * file; 10 | LogType level; 11 | bool quiet; 12 | bool useColors; 13 | } LogState = { 0 }; 14 | 15 | static const char * LevelNames[] = { "TRACE", "DEBUG", "INFO", "WARNING", "ERROR", "FATAL" }; 16 | 17 | static const char * LevelColors[] = { "\x1b[94m", "\x1b[36m", "\x1b[32m", "\x1b[33m", "\x1b[31m", "\x1b[35m" }; 18 | 19 | void LogSetFile(FILE * file) { LogState.file = file; } 20 | 21 | void LogSetLevel(LogType level) { LogState.level = level; } 22 | 23 | void LogSetQuiet(bool enable) { LogState.quiet = enable; } 24 | 25 | void LogUseColors(bool enable) { LogState.useColors = enable; } 26 | 27 | void Log(LogType level, const char * file, int line, const char * format, ...) { 28 | if (level < LogState.level) { return; } 29 | 30 | time_t t = time(NULL); 31 | #ifdef _WIN32 32 | struct tm l; 33 | struct tm * lt = &l; 34 | localtime_s(lt, &t); 35 | #else 36 | struct tm *lt = localtime(&t); 37 | #endif 38 | 39 | if (!LogState.quiet) { 40 | va_list args; 41 | char buf[16]; 42 | buf[strftime(buf, sizeof(buf), "%H:%M:%S", lt)] = '\0'; 43 | if (LogState.useColors) { fprintf(stderr, "%s \x1b[90m%s:%d:\x1b[0m %s%-5s\x1b[0m", buf, file, line, LevelColors[level], LevelNames[level]); } 44 | else { fprintf(stderr, "%s %s:%d %-5s: ", buf, file, line, LevelNames[level]); } 45 | 46 | va_start(args, format); 47 | vfprintf(stderr, format, args); 48 | va_end(args); 49 | fprintf(stderr, ""); 50 | fflush(stderr); 51 | } 52 | 53 | if (LogState.file != NULL) { 54 | va_list args; 55 | char buf[32]; 56 | buf[strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", lt)] = '\0'; 57 | fprintf(LogState.file, "%s %-5s %s:%d: ", buf, LevelNames[level], file, line); 58 | va_start(args, format); 59 | vfprintf(LogState.file, format, args); 60 | va_end(args); 61 | fprintf(LogState.file, "\n"); 62 | fflush(LogState.file); 63 | } 64 | 65 | if (level == LogTypeFatal) { abort(); } 66 | } 67 | -------------------------------------------------------------------------------- /MinecraftC/Utilities/Log.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | typedef enum LogType { 8 | LogTypeTrace, 9 | LogTypeDebug, 10 | LogTypeInfo, 11 | LogTypeWarning, 12 | LogTypeError, 13 | LogTypeFatal, 14 | } LogType; 15 | 16 | void LogSetFile(FILE * file); 17 | 18 | void LogSetLevel(LogType level); 19 | 20 | void LogSetQuiet(bool enable); 21 | 22 | void LogUseColors(bool enable); 23 | 24 | void Log(LogType level, const char * file, int line, const char * format, ...); 25 | 26 | #define LogTrace(...) Log(LogTypeTrace, __FILE__, __LINE__, __VA_ARGS__) 27 | #define LogDebug(...) Log(LogTypeDebug, __FILE__, __LINE__, __VA_ARGS__) 28 | #define LogInfo(...) Log(LogTypeInfo, __FILE__, __LINE__, __VA_ARGS__) 29 | #define LogWarning(...) Log(LogTypeWarning, __FILE__, __LINE__, __VA_ARGS__) 30 | #define LogError(...) Log(LogTypeError, __FILE__, __LINE__, __VA_ARGS__) 31 | #define LogFatal(...) Log(LogTypeFatal, __FILE__, __LINE__, __VA_ARGS__) 32 | -------------------------------------------------------------------------------- /MinecraftC/Utilities/OpenCL.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #if defined(__APPLE__) 4 | #include 5 | #include 6 | #include 7 | #else 8 | #include 9 | #include 10 | #endif 11 | -------------------------------------------------------------------------------- /MinecraftC/Utilities/OpenGL.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #if defined(__APPLE__) 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #elif defined(_WIN32) 10 | #include 11 | #include 12 | #include 13 | #elif defined(__linux) 14 | #include 15 | #include 16 | #endif 17 | -------------------------------------------------------------------------------- /MinecraftC/Utilities/Random.c: -------------------------------------------------------------------------------- 1 | #include "Random.h" 2 | #include 3 | #include 4 | 5 | #ifndef M_PI 6 | #define M_PI 3.14159265358979 7 | #endif 8 | 9 | void RandomGeneratorCreate(RandomGenerator * generator, uint64_t seed) { 10 | generator->seed = seed; 11 | generator->state = seed; 12 | generator->lastNormal = INFINITY; 13 | } 14 | 15 | uint64_t RandomGeneratorInteger(RandomGenerator * generator) { 16 | generator->state ^= (generator->state >> 12); 17 | generator->state ^= (generator->state << 25); 18 | generator->state ^= (generator->state >> 27); 19 | return generator->state * 2685821657736338717ULL; 20 | } 21 | 22 | int64_t RandomGeneratorIntegerRange(RandomGenerator * generator, int64_t min, int64_t max) { 23 | return min + RandomGeneratorInteger(generator) % (max + 1 - min); 24 | } 25 | 26 | double RandomGeneratorUniform(RandomGenerator * generator) { 27 | return (double)RandomGeneratorInteger(generator) / (double)UINT64_MAX; 28 | } 29 | 30 | double RandomGeneratorUniformRange(RandomGenerator * generator, double min, double max) { 31 | return min + RandomGeneratorUniform(generator) * (max - min); 32 | } 33 | 34 | double RandomGeneratorNormal(RandomGenerator * generator, double stddev) { 35 | if (generator->lastNormal != INFINITY) { 36 | double r = generator->lastNormal; 37 | generator->lastNormal = INFINITY; 38 | return r * stddev; 39 | } 40 | 41 | double r = sqrt(-2.0 * log(1.0 - RandomGeneratorUniform(generator))); 42 | double phi = 2.0 * M_PI * (1.0 - RandomGeneratorUniform(generator)); 43 | 44 | generator->lastNormal = r * cos(phi); 45 | return r * sin(phi) * stddev; 46 | } 47 | 48 | void RandomSetSeed(unsigned int seed) { 49 | srand(seed); 50 | } 51 | 52 | int RandomInteger() { 53 | return rand(); 54 | } 55 | 56 | int RandomIntegerRange(int min, int max) { 57 | return RandomInteger() % (max - min) + min; 58 | } 59 | 60 | double RandomUniform() { 61 | return (double)rand() / (double)RAND_MAX; 62 | } 63 | 64 | double RandomUniformRange(double min, double max) { 65 | return RandomUniform() * (max - min) + min; 66 | } 67 | -------------------------------------------------------------------------------- /MinecraftC/Utilities/Random.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Time.h" 3 | 4 | typedef struct RandomGenerator { 5 | uint64_t seed; 6 | uint64_t state; 7 | double lastNormal; 8 | } RandomGenerator; 9 | 10 | void RandomGeneratorCreate(RandomGenerator * generator, uint64_t seed); 11 | 12 | uint64_t RandomGeneratorInteger(RandomGenerator * generator); 13 | 14 | int64_t RandomGeneratorIntegerRange(RandomGenerator * generator, int64_t min, int64_t max); 15 | 16 | double RandomGeneratorUniform(RandomGenerator * generator); 17 | 18 | double RandomGeneratorUniformRange(RandomGenerator * generator, double min, double max); 19 | 20 | double RandomGeneratorNormal(RandomGenerator * generator, double stddev); 21 | 22 | void RandomSetSeed(unsigned int seed); 23 | 24 | int RandomInteger(void); 25 | 26 | int RandomIntegerRange(int min, int max); 27 | 28 | double RandomUniform(void); 29 | 30 | double RandomUniformRange(double min, double max); 31 | -------------------------------------------------------------------------------- /MinecraftC/Utilities/SinTable.c: -------------------------------------------------------------------------------- 1 | #include "SinTable.h" 2 | 3 | static float SinTable[0x10000]; 4 | 5 | void SinTableInitialize() { 6 | for (int i = 0; i < sizeof(SinTable) / sizeof(float); i++) { 7 | SinTable[i] = sin(i * 2.0 * M_PI / (float)0xFFFF); 8 | } 9 | } 10 | 11 | float tsin(float x) { return SinTable[(int)(x * 10430.378f) & 0xFFFF]; } 12 | float tcos(float x) { return SinTable[(int)(x * 10430.378f + 16384.0f) & 0xFFFF]; } 13 | -------------------------------------------------------------------------------- /MinecraftC/Utilities/SinTable.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #ifndef M_PI 5 | #define M_PI 3.14159265358979 6 | #endif 7 | 8 | void SinTableInitialize(void); 9 | 10 | float tsin(float x); 11 | float tcos(float x); 12 | -------------------------------------------------------------------------------- /MinecraftC/Utilities/String.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "String.h" 5 | 6 | String StringCreate(const char * chars) { 7 | String string = malloc(strlen(chars) + 1); 8 | memcpy(string, chars, strlen(chars) + 1); 9 | return string; 10 | } 11 | 12 | String StringCreateFromInt(int n) { 13 | int len = n == 0 ? 1 : ceil(log10(abs(n) + 1.0)); 14 | String string = StringCreate(""); 15 | for (int i = 0; i < len; i++) { 16 | int digit = (int)((float)abs(n) / pow(10.0, i)) % 10; 17 | StringConcatFront((char[]){ digit + 48, '\0' }, &string); 18 | } 19 | if (n < 0) { 20 | StringConcatFront("-", &string); 21 | } 22 | return string; 23 | } 24 | 25 | int32_t StringLength(String string) { 26 | return (int32_t)strlen(string); 27 | } 28 | 29 | void StringConcat(String * string, const char * chars) { 30 | StringInsert(string, StringLength(*string), chars); 31 | } 32 | 33 | void StringConcatFront(const char * chars, String * string) { 34 | StringInsert(string, 0, chars); 35 | } 36 | 37 | String StringSub(String string, int32_t indexStart, int32_t indexEnd) { 38 | if (indexStart < 0) { indexStart = 0; } 39 | if (indexEnd > StringLength(string) - 1) { indexEnd = StringLength(string) - 1; } 40 | if (indexStart > indexEnd) { return StringCreate(""); } 41 | char orig = string[indexEnd + 1]; 42 | string[indexEnd + 1] = '\0'; 43 | String newString = StringCreate(string + indexStart); 44 | string[indexEnd + 1] = orig; 45 | return newString; 46 | } 47 | 48 | int32_t StringIndexOf(String string, char chr) { 49 | for (int32_t i = 0; i < StringLength(string); i++) { 50 | if (string[i] == chr) { return i; } 51 | } 52 | return -1; 53 | } 54 | 55 | void StringSet(String * string, const char * chars) { 56 | StringFree(*string); 57 | *string = StringCreate(chars); 58 | } 59 | 60 | void StringSetFromInt(String * string, int number) { 61 | StringFree(*string); 62 | *string = StringCreateFromInt(number); 63 | } 64 | 65 | void StringInsert(String * string, int32_t index, const char * chars) { 66 | int32_t len1 = StringLength(*string), len2 = (int32_t)strlen(chars); 67 | if (index > len1) { index = len1; } 68 | *string = realloc(*string, len1 + len2 + 1); 69 | for (int32_t i = len1; i >= index; i--) { (*string)[i + len2] = (*string)[i]; } 70 | memcpy(*string + index, chars, len2); 71 | } 72 | 73 | void StringRemove(String * string, int32_t indexStart, int32_t indexEnd) { 74 | if (indexStart < 0) { indexStart = 0; } 75 | if (indexEnd > StringLength(*string) - 1) { indexEnd = StringLength(*string) - 1; } 76 | if (indexStart > indexEnd) { StringSet(string, ""); } 77 | for (int i = 0; i < StringLength(*string) - indexEnd; i++) { 78 | (*string)[indexStart + i] = (*string)[indexEnd + i + 1]; 79 | } 80 | *string = realloc(*string, StringLength(*string) - (indexEnd - indexStart + 1)); 81 | } 82 | 83 | bool StringEquals(String string, const char * chars) { 84 | return strcmp(string, chars) == 0; 85 | } 86 | 87 | int StringToInt(String string) { 88 | int n = 0; 89 | for (int i = StringLength(string) - 1, j = 0; i >= 0; i--, j++) { 90 | if (string[i] == '-' && i == 0) { n *= -1; break; } 91 | n += (string[i] - 48) * pow(10, j); 92 | } 93 | return n; 94 | } 95 | 96 | void StringFree(String string) { 97 | free(string); 98 | } 99 | -------------------------------------------------------------------------------- /MinecraftC/Utilities/String.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | typedef char * String; 6 | 7 | String StringCreate(const char * chars); 8 | 9 | String StringCreateFromInt(int number); 10 | 11 | int32_t StringLength(String string); 12 | 13 | void StringConcat(String * string, const char * chars); 14 | 15 | void StringConcatFront(const char * chars, String * string); 16 | 17 | String StringSub(String string, int32_t indexStart, int32_t indexEnd); 18 | 19 | int32_t StringIndexOf(String string, const char chr); 20 | 21 | void StringSet(String * string, const char * chars); 22 | 23 | void StringSetFromInt(String * string, int number); 24 | 25 | void StringInsert(String * string, int32_t index, const char * chars); 26 | 27 | void StringRemove(String * string, int32_t indexStart, int32_t indexEnd); 28 | 29 | bool StringEquals(String string, const char * chars); 30 | 31 | int StringToInt(String string); 32 | 33 | void StringFree(String string); 34 | -------------------------------------------------------------------------------- /MinecraftC/Utilities/Time.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #ifdef _WIN32 5 | #include 6 | #include 7 | #else 8 | #include 9 | #endif 10 | 11 | #ifdef _WIN32 12 | static inline int gettimeofday(struct timeval * tp, void * tzp) { 13 | FILETIME file_time; 14 | SYSTEMTIME system_time; 15 | ULARGE_INTEGER ularge; 16 | GetSystemTime(&system_time); 17 | SystemTimeToFileTime(&system_time, &file_time); 18 | ularge.LowPart = file_time.dwLowDateTime; 19 | ularge.HighPart = file_time.dwHighDateTime; 20 | tp->tv_sec = (long)((ularge.QuadPart - ((unsigned __int64)116444736000000000ULL)) / 10000000L); 21 | tp->tv_usec = (long)(system_time.wMilliseconds * 1000); 22 | return 0; 23 | } 24 | #endif 25 | 26 | static inline uint64_t TimeNano() { 27 | struct timeval time; 28 | gettimeofday(&time, NULL); 29 | return 1000 * ((uint64_t)(time.tv_sec % 10000) * 1000000 + (uint64_t)time.tv_usec); 30 | } 31 | 32 | static inline uint64_t TimeMilli() { 33 | return TimeNano() / 1000000; 34 | } 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MinecraftC - A Raytraced Minecraft Classic Port to C 2 | 3 | ### Features: 4 | - True to the original version (0.0.30a) 5 | - Implemented fully in C using SDL2 and OpenGL 1.1 6 | - Original music and sounds 7 | - A modded and vanilla version 8 | - Works on Windows, Linux, and MacOS 9 | - CMake build system 10 | #### Raytracing: 11 | - Uses an 8-bit distance field as an acceleration structure 12 | - In some cases, performance is better than the original 13 | - 60+ fps at 1080p on the integrated graphics cards I've tested 14 | - To enable raytracing, download the modded binary and enable it in the mods screen under options 15 | 16 | ## Screenshots 17 | Screen Shot 2022-07-31 at 12 57 49 PM 18 | Screen Shot 2022-07-31 at 12 57 54 PM 19 | Screen Shot 2022-07-31 at 12 43 33 PM 20 | Screen Shot 2022-07-31 at 12 43 39 PM 21 | 22 | ## Downloads 23 | - There are two versions, modded and vanilla, where vanilla doesn't have the option to turn on mods 24 | - [Windows 32 bit](https://github.com/johnpayne-dev/MinecraftC/releases) 25 | - [Windows 64 bit](https://github.com/johnpayne-dev/MinecraftC/releases) 26 | - [MacOS x86_64](https://github.com/johnpayne-dev/MinecraftC/releases) 27 | - [MacOS ARM](https://github.com/johnpayne-dev/MinecraftC/releases) 28 | 29 | ## Building 30 | Note: if you would like to build the vanilla version, remove `-DMINECRAFTC_MODS=1` from the cmake command 31 | ### Requirements: 32 | - `git` 33 | - `cmake` 34 | - A compiler of your choice 35 | 36 | ### Windows instructions for Visual Studio: 37 | 1. Run the following commands: 38 | ```sh 39 | git clone --recursive https://github.com/johnpayne-dev/MinecraftC.git 40 | cd MinecraftC 41 | mkdir Build 42 | cd Build 43 | cmake -DMINECRAFTC_MODS=1 -G"Visual Studio 17" .. # replace "Visual Studio 17" with your version 44 | ``` 45 | 2. You should now have `MinecraftC.sln` in your directory that you can open with Visual Studio and build 46 | 47 | ### MacOS instructions for Xcode: 48 | 1. Run the following commands: 49 | ```sh 50 | git clone --recursive https://github.com/johnpayne-dev/MinecraftC.git 51 | cd MinecraftC 52 | mkdir Build && cd Build 53 | cmake -DMINECRAFTC_MODS -GXcode .. 54 | ``` 55 | 2. You should now have `MinecraftC.xcodeproj` in your directory that you open with Xcode and build 56 | 57 | 3. (optional) If you would like it in a .app format, you can run this command to convert your executable: 58 | ``` 59 | python3 Scripts/MacOS-App.py [developer-id] 60 | ``` 61 | Providing the developer id will sign the .app, which you can find by running `security find-identity` 62 | 63 | ### Linux instructions (untested): 64 | 1. If you don't have SDL2 already, run these commands: 65 | ```sh 66 | sudo apt-get update 67 | sudo apt-get install libsdl2-dev 68 | ``` 69 | 2. Run the following commands: 70 | ```sh 71 | git clone --recursive https://github.com/johnpayne-dev/MinecraftC.git 72 | cd MinecraftC 73 | mkdir Build && cd Build 74 | cmake -DMINECRAFTC_MODS=1 .. 75 | make 76 | ``` 77 | 78 | ### Modifying Resources 79 | If you're creating a mod and want to change or add any `.png` or `.ogg` resouces, then run this script to update the resource headers: 80 | ```sh 81 | python3 Scripts/EmbedResources.py 82 | ``` 83 | It will recursively go through all `.png` and `.ogg` files in `Resources/`, and convert them to `.h` 84 | 85 | ## Known Issues 86 | - There is no survival mode, it was removed for simplicity and compatibility with raytracing 87 | - A few sounds have the incorrect pitch, I'm waiting for cute_sound.h to implement pitch shifting 88 | - Load file and save file are not implemented 89 | - If raytracing doesn't turn on, then something is going wrong with OpenCL, report an issue and I can help troubleshoot 90 | -------------------------------------------------------------------------------- /Resources/App/AppIcon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnpayne-dev/MinecraftC/43928d42e1f32bd76a994f0bb22c0153a7271b3f/Resources/App/AppIcon.icns -------------------------------------------------------------------------------- /Resources/App/AppIcon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnpayne-dev/MinecraftC/43928d42e1f32bd76a994f0bb22c0153a7271b3f/Resources/App/AppIcon.ico -------------------------------------------------------------------------------- /Resources/App/AppIcon.rc: -------------------------------------------------------------------------------- 1 | IDI_ICON1 ICON DISCARDABLE "AppIcon.ico" -------------------------------------------------------------------------------- /Resources/Clouds.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnpayne-dev/MinecraftC/43928d42e1f32bd76a994f0bb22c0153a7271b3f/Resources/Clouds.png -------------------------------------------------------------------------------- /Resources/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnpayne-dev/MinecraftC/43928d42e1f32bd76a994f0bb22c0153a7271b3f/Resources/Default.png -------------------------------------------------------------------------------- /Resources/Dirt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnpayne-dev/MinecraftC/43928d42e1f32bd76a994f0bb22c0153a7271b3f/Resources/Dirt.png -------------------------------------------------------------------------------- /Resources/GUI/GUI.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnpayne-dev/MinecraftC/43928d42e1f32bd76a994f0bb22c0153a7271b3f/Resources/GUI/GUI.png -------------------------------------------------------------------------------- /Resources/GUI/Icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnpayne-dev/MinecraftC/43928d42e1f32bd76a994f0bb22c0153a7271b3f/Resources/GUI/Icons.png -------------------------------------------------------------------------------- /Resources/Music/Calm1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnpayne-dev/MinecraftC/43928d42e1f32bd76a994f0bb22c0153a7271b3f/Resources/Music/Calm1.ogg -------------------------------------------------------------------------------- /Resources/Music/Calm2.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnpayne-dev/MinecraftC/43928d42e1f32bd76a994f0bb22c0153a7271b3f/Resources/Music/Calm2.ogg -------------------------------------------------------------------------------- /Resources/Music/Calm3.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnpayne-dev/MinecraftC/43928d42e1f32bd76a994f0bb22c0153a7271b3f/Resources/Music/Calm3.ogg -------------------------------------------------------------------------------- /Resources/Particles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnpayne-dev/MinecraftC/43928d42e1f32bd76a994f0bb22c0153a7271b3f/Resources/Particles.png -------------------------------------------------------------------------------- /Resources/Rain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnpayne-dev/MinecraftC/43928d42e1f32bd76a994f0bb22c0153a7271b3f/Resources/Rain.png -------------------------------------------------------------------------------- /Resources/Rock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnpayne-dev/MinecraftC/43928d42e1f32bd76a994f0bb22c0153a7271b3f/Resources/Rock.png -------------------------------------------------------------------------------- /Resources/Shaders/DistanceField.cl: -------------------------------------------------------------------------------- 1 | 2 | __kernel void iterate(__global uchar * distanceField, uchar iteration, int levelSize) { 3 | int x = get_global_id(0); 4 | int y = get_global_id(1); 5 | int z = get_global_id(2); 6 | uchar d = distanceField[(y * levelSize + z) * levelSize + x]; 7 | if (d != iteration) { 8 | return; 9 | } 10 | for (int i = -1; i <= 1; i++) { 11 | for (int j = -1; j <= 1; j++) { 12 | for (int k = -1; k <= 1; k++) { 13 | if (y + j < 0 || y + j >= 64 || x + i < 0 || x + i >= levelSize || z + k < 0 || z + k >= levelSize) { 14 | continue; 15 | } 16 | int n = ((y + j) * levelSize + z + k) * levelSize + x + i; 17 | if (d + 1 < distanceField[n]) { 18 | distanceField[n] = d + 1; 19 | } 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Resources/Shaders/DistanceField.h: -------------------------------------------------------------------------------- 1 | static const unsigned char Resource_Shaders_DistanceField[] = { 2 | 0x0a, 0x5f, 0x5f, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x20, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x69, 3 | 0x74, 0x65, 0x72, 0x61, 0x74, 0x65, 0x28, 0x5f, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 4 | 0x75, 0x63, 0x68, 0x61, 0x72, 0x20, 0x2a, 0x20, 0x64, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 5 | 0x46, 0x69, 0x65, 0x6c, 0x64, 0x2c, 0x20, 0x75, 0x63, 0x68, 0x61, 0x72, 0x20, 0x69, 0x74, 0x65, 6 | 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x6c, 0x65, 0x76, 0x65, 7 | 0x6c, 0x53, 0x69, 0x7a, 0x65, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x69, 0x6e, 0x74, 0x20, 0x78, 0x20, 8 | 0x3d, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x28, 9 | 0x30, 0x29, 0x3b, 0x0a, 0x09, 0x69, 0x6e, 0x74, 0x20, 0x79, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 10 | 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x28, 0x31, 0x29, 0x3b, 0x0a, 0x09, 11 | 0x69, 0x6e, 0x74, 0x20, 0x7a, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 12 | 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x28, 0x32, 0x29, 0x3b, 0x0a, 0x09, 0x75, 0x63, 0x68, 0x61, 0x72, 13 | 0x20, 0x64, 0x20, 0x3d, 0x20, 0x64, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x46, 0x69, 0x65, 14 | 0x6c, 0x64, 0x5b, 0x28, 0x79, 0x20, 0x2a, 0x20, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x53, 0x69, 0x7a, 15 | 0x65, 0x20, 0x2b, 0x20, 0x7a, 0x29, 0x20, 0x2a, 0x20, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x53, 0x69, 16 | 0x7a, 0x65, 0x20, 0x2b, 0x20, 0x78, 0x5d, 0x3b, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x28, 0x64, 0x20, 17 | 0x21, 0x3d, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x20, 0x7b, 0x0a, 18 | 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x0a, 0x09, 0x7d, 0x0a, 0x09, 0x66, 0x6f, 19 | 0x72, 0x20, 0x28, 0x69, 0x6e, 0x74, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x2d, 0x31, 0x3b, 0x20, 0x69, 20 | 0x20, 0x3c, 0x3d, 0x20, 0x31, 0x3b, 0x20, 0x69, 0x2b, 0x2b, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 21 | 0x66, 0x6f, 0x72, 0x20, 0x28, 0x69, 0x6e, 0x74, 0x20, 0x6a, 0x20, 0x3d, 0x20, 0x2d, 0x31, 0x3b, 22 | 0x20, 0x6a, 0x20, 0x3c, 0x3d, 0x20, 0x31, 0x3b, 0x20, 0x6a, 0x2b, 0x2b, 0x29, 0x20, 0x7b, 0x0a, 23 | 0x09, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x28, 0x69, 0x6e, 0x74, 0x20, 0x6b, 0x20, 0x3d, 0x20, 24 | 0x2d, 0x31, 0x3b, 0x20, 0x6b, 0x20, 0x3c, 0x3d, 0x20, 0x31, 0x3b, 0x20, 0x6b, 0x2b, 0x2b, 0x29, 25 | 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x79, 0x20, 0x2b, 0x20, 0x6a, 26 | 0x20, 0x3c, 0x20, 0x30, 0x20, 0x7c, 0x7c, 0x20, 0x79, 0x20, 0x2b, 0x20, 0x6a, 0x20, 0x3e, 0x3d, 27 | 0x20, 0x36, 0x34, 0x20, 0x7c, 0x7c, 0x20, 0x78, 0x20, 0x2b, 0x20, 0x69, 0x20, 0x3c, 0x20, 0x30, 28 | 0x20, 0x7c, 0x7c, 0x20, 0x78, 0x20, 0x2b, 0x20, 0x69, 0x20, 0x3e, 0x3d, 0x20, 0x6c, 0x65, 0x76, 29 | 0x65, 0x6c, 0x53, 0x69, 0x7a, 0x65, 0x20, 0x7c, 0x7c, 0x20, 0x7a, 0x20, 0x2b, 0x20, 0x6b, 0x20, 30 | 0x3c, 0x20, 0x30, 0x20, 0x7c, 0x7c, 0x20, 0x7a, 0x20, 0x2b, 0x20, 0x6b, 0x20, 0x3e, 0x3d, 0x20, 31 | 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x53, 0x69, 0x7a, 0x65, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 32 | 0x09, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 33 | 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x69, 0x6e, 0x74, 0x20, 0x6e, 0x20, 0x3d, 0x20, 0x28, 0x28, 34 | 0x79, 0x20, 0x2b, 0x20, 0x6a, 0x29, 0x20, 0x2a, 0x20, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x53, 0x69, 35 | 0x7a, 0x65, 0x20, 0x2b, 0x20, 0x7a, 0x20, 0x2b, 0x20, 0x6b, 0x29, 0x20, 0x2a, 0x20, 0x6c, 0x65, 36 | 0x76, 0x65, 0x6c, 0x53, 0x69, 0x7a, 0x65, 0x20, 0x2b, 0x20, 0x78, 0x20, 0x2b, 0x20, 0x69, 0x3b, 37 | 0x0a, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x64, 0x20, 0x2b, 0x20, 0x31, 0x20, 0x3c, 38 | 0x20, 0x64, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x5b, 0x6e, 39 | 0x5d, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x64, 0x69, 0x73, 0x74, 0x61, 0x6e, 40 | 0x63, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x5b, 0x6e, 0x5d, 0x20, 0x3d, 0x20, 0x64, 0x20, 0x2b, 41 | 0x20, 0x31, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 42 | 0x09, 0x7d, 0x0a, 0x09, 0x7d, 0x0a, 0x7d, 0x0a, 0x00 43 | }; 44 | -------------------------------------------------------------------------------- /Resources/Sound/Step/Grass1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnpayne-dev/MinecraftC/43928d42e1f32bd76a994f0bb22c0153a7271b3f/Resources/Sound/Step/Grass1.ogg -------------------------------------------------------------------------------- /Resources/Sound/Step/Grass2.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnpayne-dev/MinecraftC/43928d42e1f32bd76a994f0bb22c0153a7271b3f/Resources/Sound/Step/Grass2.ogg -------------------------------------------------------------------------------- /Resources/Sound/Step/Grass3.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnpayne-dev/MinecraftC/43928d42e1f32bd76a994f0bb22c0153a7271b3f/Resources/Sound/Step/Grass3.ogg -------------------------------------------------------------------------------- /Resources/Sound/Step/Grass4.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnpayne-dev/MinecraftC/43928d42e1f32bd76a994f0bb22c0153a7271b3f/Resources/Sound/Step/Grass4.ogg -------------------------------------------------------------------------------- /Resources/Sound/Step/Gravel1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnpayne-dev/MinecraftC/43928d42e1f32bd76a994f0bb22c0153a7271b3f/Resources/Sound/Step/Gravel1.ogg -------------------------------------------------------------------------------- /Resources/Sound/Step/Gravel2.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnpayne-dev/MinecraftC/43928d42e1f32bd76a994f0bb22c0153a7271b3f/Resources/Sound/Step/Gravel2.ogg -------------------------------------------------------------------------------- /Resources/Sound/Step/Gravel3.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnpayne-dev/MinecraftC/43928d42e1f32bd76a994f0bb22c0153a7271b3f/Resources/Sound/Step/Gravel3.ogg -------------------------------------------------------------------------------- /Resources/Sound/Step/Gravel4.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnpayne-dev/MinecraftC/43928d42e1f32bd76a994f0bb22c0153a7271b3f/Resources/Sound/Step/Gravel4.ogg -------------------------------------------------------------------------------- /Resources/Sound/Step/Stone1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnpayne-dev/MinecraftC/43928d42e1f32bd76a994f0bb22c0153a7271b3f/Resources/Sound/Step/Stone1.ogg -------------------------------------------------------------------------------- /Resources/Sound/Step/Stone2.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnpayne-dev/MinecraftC/43928d42e1f32bd76a994f0bb22c0153a7271b3f/Resources/Sound/Step/Stone2.ogg -------------------------------------------------------------------------------- /Resources/Sound/Step/Stone3.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnpayne-dev/MinecraftC/43928d42e1f32bd76a994f0bb22c0153a7271b3f/Resources/Sound/Step/Stone3.ogg -------------------------------------------------------------------------------- /Resources/Sound/Step/Stone4.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnpayne-dev/MinecraftC/43928d42e1f32bd76a994f0bb22c0153a7271b3f/Resources/Sound/Step/Stone4.ogg -------------------------------------------------------------------------------- /Resources/Sound/Step/Wood1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnpayne-dev/MinecraftC/43928d42e1f32bd76a994f0bb22c0153a7271b3f/Resources/Sound/Step/Wood1.ogg -------------------------------------------------------------------------------- /Resources/Sound/Step/Wood2.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnpayne-dev/MinecraftC/43928d42e1f32bd76a994f0bb22c0153a7271b3f/Resources/Sound/Step/Wood2.ogg -------------------------------------------------------------------------------- /Resources/Sound/Step/Wood3.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnpayne-dev/MinecraftC/43928d42e1f32bd76a994f0bb22c0153a7271b3f/Resources/Sound/Step/Wood3.ogg -------------------------------------------------------------------------------- /Resources/Sound/Step/Wood4.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnpayne-dev/MinecraftC/43928d42e1f32bd76a994f0bb22c0153a7271b3f/Resources/Sound/Step/Wood4.ogg -------------------------------------------------------------------------------- /Resources/Terrain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnpayne-dev/MinecraftC/43928d42e1f32bd76a994f0bb22c0153a7271b3f/Resources/Terrain.png -------------------------------------------------------------------------------- /Resources/Water.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnpayne-dev/MinecraftC/43928d42e1f32bd76a994f0bb22c0153a7271b3f/Resources/Water.png -------------------------------------------------------------------------------- /Scripts/EmbedResources.py: -------------------------------------------------------------------------------- 1 | from PIL import Image 2 | import os 3 | import sys 4 | 5 | RESOURCE_PATH = os.path.realpath(__file__ + '/../../Resources') 6 | 7 | def embed_png(filePath, outPath): 8 | cName = filePath[len(RESOURCE_PATH) + 1:-4].replace(os.sep, '_') 9 | 10 | image = Image.open(filePath).convert('RGBA') 11 | pixels = image.load() 12 | width, height = image.size 13 | 14 | output = open(outPath, 'w') 15 | output.write(f'static const unsigned int Resource_{cName}_Width = {width};\n\n') 16 | output.write(f'static const unsigned int Resource_{cName}_Height = {height};\n\n') 17 | output.write(f'static const unsigned char Resource_{cName}_RGBA[] = {{') 18 | for y in range(height): 19 | for x in range(width): 20 | if (y * width + x) % 4 == 0: output.write('\n\t') 21 | r, g, b, a = pixels[x, y] 22 | output.write('0x%0.2X, ' % r) 23 | output.write('0x%0.2X, ' % g) 24 | output.write('0x%0.2X, ' % b) 25 | output.write('0x%0.2X, ' % a) 26 | output.write('\n};\n') 27 | output.close() 28 | 29 | image.close() 30 | 31 | def embed_file(filePath, outPath): 32 | input, output = open(filePath, 'rb'), open(outPath, 'w') 33 | cName = filePath[len(RESOURCE_PATH) + 1:filePath.rfind('.')].replace(os.sep, '_') 34 | output.write(f'static const unsigned char Resource_{cName}[] = {{') 35 | for i, byte in enumerate(input.read()): 36 | if i % 16 == 0: output.write('\n\t') 37 | output.write('0x{0:02x}, '.format(byte)) 38 | output.write('0x00\n};\n') 39 | input.close() 40 | output.close() 41 | 42 | if len(sys.argv) == 2: 43 | for subdir, dirs, files in os.walk(RESOURCE_PATH): 44 | for fileName in files: 45 | filePath = subdir + os.sep + fileName 46 | if filePath.endswith(sys.argv[1]): 47 | embed_file(filePath, filePath[:-len(sys.argv[1])] + '.h') 48 | else: 49 | for subdir, dirs, files in os.walk(RESOURCE_PATH): 50 | for fileName in files: 51 | filePath = subdir + os.sep + fileName 52 | if filePath.endswith('.png'): 53 | embed_png(filePath, filePath[:-4] + '.h') 54 | elif filePath.endswith('.ogg'): 55 | embed_file(filePath, filePath[:-4] + '.h') 56 | elif filePath.endswith('.cl'): 57 | embed_file(filePath, filePath[:-3] + '.h') 58 | -------------------------------------------------------------------------------- /Scripts/MacOS-App.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | import shutil 4 | 5 | ICON_PATH = os.path.realpath(__file__ + '/../../Resources/App/AppIcon.icns') 6 | 7 | if len(sys.argv) == 2 or len(sys.argv) == 3: 8 | path = os.path.realpath(sys.argv[1]) 9 | appPath = path[:path.rfind('/')] + '/MinecraftC.app' 10 | os.makedirs(appPath + '/Contents/MacOS', exist_ok=True) 11 | os.makedirs(appPath + '/Contents/Resources', exist_ok=True) 12 | shutil.copy2(path, appPath + '/Contents/MacOS') 13 | shutil.copy2(ICON_PATH, appPath + '/Contents/Resources') 14 | with open(appPath + '/Contents/Info.plist', 'w') as info: 15 | plist = """ 16 | 17 | 18 | 19 | 20 | CFBundleDevelopmentRegion 21 | en 22 | CFBundleExecutable 23 | MinecraftC 24 | CFBundleIdentifier 25 | com.NotMojang.MinecraftC 26 | CFBundleInfoDictionaryVersion 27 | 6.0 28 | CFBundleName 29 | MinecraftC 30 | CFBundlePackageType 31 | APPL 32 | CFBundleShortVersionString 33 | 1.0 34 | CFBundleSignature 35 | ???? 36 | CFBundleVersion 37 | 1 38 | CFBundleIconFile 39 | AppIcon 40 | 41 | 42 | """ 43 | info.write(plist) 44 | if len(sys.argv) == 3: 45 | os.system('xattr -cr ' + appPath) 46 | os.system(f'codesign --deep --force -s {sys.argv[2]} --timestamp {appPath}') 47 | else: 48 | print('usage: python MacOS-App.py [developer-id]') 49 | --------------------------------------------------------------------------------