Add platform layer with hooks into engine
This commit is contained in:
parent
e3f7b8e781
commit
b024d821f5
|
@ -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)
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue