1
0
Fork 0
2018-soft-3d-renderer/src/platform.cpp

247 lines
6.4 KiB
C++

#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;
}
}