From b024d821f58a61045c09bca65ab5dd9deceebbf9 Mon Sep 17 00:00:00 2001 From: Austin Morlan Date: Tue, 4 Sep 2018 18:50:14 -0700 Subject: [PATCH] Add platform layer with hooks into engine --- Makefile | 55 ++++++++++ include/engine.h | 43 ++++++++ include/platform.h | 44 ++++++++ include/util.h | 12 +++ src/engine.cpp | 15 +++ src/main.cpp | 73 ++++++++++++++ src/platform.cpp | 246 +++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 488 insertions(+) create mode 100644 Makefile create mode 100644 include/engine.h create mode 100644 include/platform.h create mode 100644 include/util.h create mode 100644 src/engine.cpp create mode 100644 src/main.cpp create mode 100644 src/platform.cpp diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1df73ef --- /dev/null +++ b/Makefile @@ -0,0 +1,55 @@ +# Verbosity of make output +ifeq ("$(VERBOSE)","1") +V := +else +V := @ +endif + +# Debugging +ifeq ("$(DEBUG)","0") +D := +else +D := -g +endif + +# Optimizations +ifeq ("$(OPTIMIZE)","1") +O := -O1 +else ifeq ("$(OPTIMIZE)", "2") +O := -O2 +else ifeq ("$(OPTIMIZE)", "3") +O := -O3 +else +O := -O0 +endif + +SRC_DIR=src +INCLUDE_DIR=include +BUILD_DIR=build + +CC=clang++ +WARNINGS_ON=-Weverything +WARNINGS_OFF=-Wno-missing-braces -Wno-gnu-anonymous-struct -Wno-old-style-cast\ + -Wno-zero-as-null-pointer-constant -Wno-nested-anon-types\ + -Wno-padded + +CFLAGS=$(D) $(O) -std=c++11 $(WARNINGS_ON) $(WARNINGS_OFF) -I$(INCLUDE_DIR) +LIBS=-lSDL2 + +_HEADERS = engine.h platform.h util.h +HEADERS = $(patsubst %,$(INCLUDE_DIR)/%,$(_HEADERS)) + +_OBJS = engine.o main.o platform.o +OBJS = $(patsubst %,$(BUILD_DIR)/%,$(_OBJS)) + +$(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp $(HEADERS) + @ if [ ! -d $(BUILD_DIR) ]; then mkdir $(BUILD_DIR); fi + $(V) $(CC) -c -o $@ $< $(CFLAGS) + +$(BUILD_DIR)/engine: $(OBJS) + $(V) $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + +.PHONY: clean + +clean: + rm -rf $(BUILD_DIR) diff --git a/include/engine.h b/include/engine.h new file mode 100644 index 0000000..fda860b --- /dev/null +++ b/include/engine.h @@ -0,0 +1,43 @@ +#ifndef ENGINE_H + +#include + + +// ENUMS +enum Engine_Input +{ + TRANSLATE_X_POS, + TRANSLATE_X_NEG, + TRANSLATE_Y_POS, + TRANSLATE_Y_NEG, + TRANSLATE_Z_POS, + TRANSLATE_Z_NEG, + ROTATE_X_POS, + ROTATE_X_NEG, + ROTATE_Y_POS, + ROTATE_Y_NEG, + ROTATE_Z_POS, + ROTATE_Z_NEG, + SCALE_UP, + SCALE_DOWN +}; + + +// STRUCTURES +struct Engine_Buffer +{ + uint32_t *pixels; + int width; + int height; +}; + + +// FUNCTIONS +int Engine_Init(char *filename); +void Engine_Render(Engine_Buffer &buffer, uint32_t input); +void Engine_Shutdown(void); + + +#define ENGINE_H +#endif + diff --git a/include/platform.h b/include/platform.h new file mode 100644 index 0000000..4f475a9 --- /dev/null +++ b/include/platform.h @@ -0,0 +1,44 @@ +#ifndef PLATFORM_H + +#include + + +// ENUMERATIONS +enum Platform_Status +{ + PLATFORM_ERROR = -1, + PLATFORM_OK, + PLATFORM_QUIT +}; + + +// STRUCTURES +struct Platform +{ + SDL_Window *window; + SDL_Surface *surface; + uint32_t input; + uint32_t framerateMillis; + uint32_t frameStartMillis; +}; + + +// FUNCTIONS +int Platform_Init(Platform &platform, int width, int height); + +int Platform_CheckForEvents(Platform &platform); + +void Platform_ClearWindow(Platform &platform); + +void Platform_UpdateWindow(Platform &platform); + +void Platform_GetFrameTime(Platform &platform); + +void Platform_SyncToFramerate(Platform &platform); + +void Platform_Shutdown(Platform &platform); + + +#define PLATFORM_H +#endif + diff --git a/include/util.h b/include/util.h new file mode 100644 index 0000000..4c873f1 --- /dev/null +++ b/include/util.h @@ -0,0 +1,12 @@ +#ifndef UTIL_H + + +// MACROS +#define SET_BIT(x, bit) (x |= (1UL << bit)) +#define CLEAR_BIT(x, bit) (x &= ~(1UL << bit)) +#define CHECK_BIT(x, bit) (x & (1UL << bit)) + + +#define UTIL_H +#endif + diff --git a/src/engine.cpp b/src/engine.cpp new file mode 100644 index 0000000..abc9ff4 --- /dev/null +++ b/src/engine.cpp @@ -0,0 +1,15 @@ +#include "engine.h" + +int Engine_Init(char *filename) +{ + return 0; +} + +void Engine_Render(Engine_Buffer &buffer, uint32_t input) +{ +} + +void Engine_Shutdown(void) +{ +} + diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..824401e --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,73 @@ +#include "engine.h" +#include "platform.h" +#include +#include +#include + + +// CONSTANTS +const unsigned int WINDOW_WIDTH = 800; +const unsigned int WINDOW_HEIGHT = 600; +const unsigned int WINDOW_FPS = 30; + + +// MAIN +int main(int argc, char *argv[]) +{ + if (argc != 2) + { + fprintf(stderr, "Usage: %s \n", argv[0]); + return EXIT_FAILURE; + } + + char *filename = argv[1]; + Platform platform = {}; + + int result = Platform_Init(platform, WINDOW_WIDTH, WINDOW_HEIGHT); + platform.framerateMillis = (1000 / WINDOW_FPS); + + if (result == PLATFORM_OK) + { + Engine_Buffer buffer = {}; + buffer.pixels = (uint32_t*)platform.surface->pixels; + buffer.width = platform.surface->w; + buffer.height = platform.surface->h; + + result = Engine_Init(filename); + + if (result < 0) + { + return EXIT_FAILURE; + } + + while (true) + { + Platform_GetFrameTime(platform); + + result = Platform_CheckForEvents(platform); + if (result == PLATFORM_QUIT) + { + break; + } + + Platform_ClearWindow(platform); + + Engine_Render(buffer, platform.input); + + Platform_UpdateWindow(platform); + + Platform_SyncToFramerate(platform); + } + + Engine_Shutdown(); + + Platform_Shutdown(platform); + } + else + { + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + diff --git a/src/platform.cpp b/src/platform.cpp new file mode 100644 index 0000000..1abe7f8 --- /dev/null +++ b/src/platform.cpp @@ -0,0 +1,246 @@ +#include "engine.h" +#include "platform.h" +#include "util.h" +#include +#include +#include + + +// PRIVATE PROTOTYPES +static void HandleEvent(Platform &platform, SDL_Event &event); + + +// PUBLIC FUNCTIONS +int Platform_Init(Platform &platform, int width, int height) +{ + int result = SDL_Init(SDL_INIT_VIDEO); + if (result < 0) + { + fprintf(stderr, "Error initializing SDL: %s\n", SDL_GetError()); + return PLATFORM_ERROR; + } + + + SDL_Window *window = SDL_CreateWindow( + "Soft 3D Engine", + SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, + width, height, + SDL_WINDOW_SHOWN); + if (window == NULL) + { + fprintf(stderr, "Error creating SDL window: %s\n", SDL_GetError()); + return PLATFORM_ERROR; + } + + + SDL_Surface *surface = SDL_GetWindowSurface(window); + if (surface == NULL) + { + fprintf(stderr, "Error getting SDL window surface: %s\n", SDL_GetError()); + return PLATFORM_ERROR; + } + + + result = SDL_ShowCursor(SDL_DISABLE); + if (result < 0) + { + fprintf(stderr, "Error disabling cursor in SDL window: %s\n", SDL_GetError()); + return PLATFORM_ERROR; + } + + + platform.window = window; + platform.surface = surface; + + return PLATFORM_OK; +} + +int Platform_CheckForEvents(Platform &platform) +{ + SDL_Event event; + + while (SDL_PollEvent(&event) != 0) + { + if (event.type == SDL_QUIT) + { + return PLATFORM_QUIT; + } + else + { + HandleEvent(platform, event); + } + } + + return PLATFORM_OK; +} + +void Platform_ClearWindow(Platform &platform) +{ + SDL_LockSurface(platform.surface); + SDL_FillRect(platform.surface, NULL, 0); +} + +void Platform_UpdateWindow(Platform &platform) +{ + SDL_UnlockSurface(platform.surface); + SDL_UpdateWindowSurface(platform.window); +} + +void Platform_GetFrameTime(Platform &platform) +{ + platform.frameStartMillis = SDL_GetTicks(); +} + +void Platform_SyncToFramerate(Platform &platform) +{ + uint32_t stopTimeMillis = SDL_GetTicks(); + uint32_t framerateMillis = stopTimeMillis - platform.frameStartMillis; + + // Delay if time to spare + if (framerateMillis < platform.framerateMillis) + { + uint32_t delayMillis = platform.framerateMillis - framerateMillis; + SDL_Delay(delayMillis); + } +} + +void Platform_Shutdown(Platform &platform) +{ + SDL_DestroyWindow(platform.window); + SDL_Quit(); +} + + +// PRIVATE FUNCTIONS +static void HandleEvent( + Platform &platform, SDL_Event &event) +{ + switch(event.type) + { + case SDL_KEYDOWN: + { + switch (event.key.keysym.sym) + { + case SDLK_w: + { + SET_BIT(platform.input, TRANSLATE_Z_POS); + } break; + case SDLK_s: + { + SET_BIT(platform.input, TRANSLATE_Z_NEG); + } break; + case SDLK_a: + { + SET_BIT(platform.input, TRANSLATE_X_NEG); + } break; + case SDLK_d: + { + SET_BIT(platform.input, TRANSLATE_X_POS); + } break; + case SDLK_q: + { + SET_BIT(platform.input, TRANSLATE_Y_NEG); + } break; + case SDLK_e: + { + SET_BIT(platform.input, TRANSLATE_Y_POS); + } break; + case SDLK_i: + { + SET_BIT(platform.input, ROTATE_Z_POS); + } break; + case SDLK_k: + { + SET_BIT(platform.input, ROTATE_Z_NEG); + } break; + case SDLK_j: + { + SET_BIT(platform.input, ROTATE_X_NEG); + } break; + case SDLK_l: + { + SET_BIT(platform.input, ROTATE_X_POS); + } break; + case SDLK_u: + { + SET_BIT(platform.input, ROTATE_Y_NEG); + } break; + case SDLK_o: + { + SET_BIT(platform.input, ROTATE_Y_POS); + } break; + case SDLK_UP: + { + SET_BIT(platform.input, SCALE_UP); + } break; + case SDLK_DOWN: + { + SET_BIT(platform.input, SCALE_DOWN); + } break; + } + } break; + case SDL_KEYUP: + { + switch (event.key.keysym.sym) + { + case SDLK_w: + { + CLEAR_BIT(platform.input, TRANSLATE_Z_POS); + } break; + case SDLK_s: + { + CLEAR_BIT(platform.input, TRANSLATE_Z_NEG); + } break; + case SDLK_a: + { + CLEAR_BIT(platform.input, TRANSLATE_X_NEG); + } break; + case SDLK_d: + { + CLEAR_BIT(platform.input, TRANSLATE_X_POS); + } break; + case SDLK_q: + { + CLEAR_BIT(platform.input, TRANSLATE_Y_NEG); + } break; + case SDLK_e: + { + CLEAR_BIT(platform.input, TRANSLATE_Y_POS); + } break; + case SDLK_i: + { + CLEAR_BIT(platform.input, ROTATE_Z_POS); + } break; + case SDLK_k: + { + CLEAR_BIT(platform.input, ROTATE_Z_NEG); + } break; + case SDLK_j: + { + CLEAR_BIT(platform.input, ROTATE_X_NEG); + } break; + case SDLK_l: + { + CLEAR_BIT(platform.input, ROTATE_X_POS); + } break; + case SDLK_u: + { + CLEAR_BIT(platform.input, ROTATE_Y_NEG); + } break; + case SDLK_o: + { + CLEAR_BIT(platform.input, ROTATE_Y_POS); + } break; + case SDLK_UP: + { + CLEAR_BIT(platform.input, SCALE_UP); + } break; + case SDLK_DOWN: + { + CLEAR_BIT(platform.input, SCALE_DOWN); + } break; + } + } break; + } +} +