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