1
0
Fork 0

Add platform layer with hooks into engine

This commit is contained in:
Austin Morlan 2018-09-04 18:50:14 -07:00
parent e3f7b8e781
commit b024d821f5
Signed by: austin
GPG Key ID: FD6B27654AF5E348
7 changed files with 488 additions and 0 deletions

55
Makefile Normal file
View File

@ -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)

43
include/engine.h Normal file
View File

@ -0,0 +1,43 @@
#ifndef ENGINE_H
#include <cstdint>
// 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

44
include/platform.h Normal file
View File

@ -0,0 +1,44 @@
#ifndef PLATFORM_H
#include <SDL2/SDL.h>
// 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

12
include/util.h Normal file
View File

@ -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

15
src/engine.cpp Normal file
View File

@ -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)
{
}

73
src/main.cpp Normal file
View File

@ -0,0 +1,73 @@
#include "engine.h"
#include "platform.h"
#include <cstdint>
#include <cstdio>
#include <cstdlib>
// 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 <OBJ>\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;
}

246
src/platform.cpp Normal file
View File

@ -0,0 +1,246 @@
#include "engine.h"
#include "platform.h"
#include "util.h"
#include <cstdint>
#include <cstdio>
#include <SDL2/SDL.h>
// 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;
}
}