Преглед изворни кода

Add ini parser, setup custom config

We use minIni to parse ini files instead of implementing our own. This
is useful for config modifiable by the user, such as controls.

However, we haven't implemented a fault-tolerant config that writes to
the config when the existing file is corrupted or non-existent. We will
have to define a "save" as soon as we have all values defined for our
in-memory config, regardless if we have retrieved the values
successfully or provided default hardcoded values.

Since we use an external dependency to manage our configs, the CMake
config must be modified and the source files included in the build. How
do we organize the dependencies from other Git repositories moving forward?
feature/data-structs
TheoryOfNekomata пре 2 година
родитељ
комит
aa41c57db6
4 измењених фајлова са 115 додато и 20 уклоњено
  1. +15
    -2
      CMakeLists.txt
  2. +21
    -0
      assets/config.ini
  3. +1
    -0
      dependencies.txt
  4. +78
    -18
      src/packages/game/main.c

+ 15
- 2
CMakeLists.txt Прегледај датотеку

@@ -5,7 +5,10 @@ project(izanagi C)

set(CMAKE_C_STANDARD 11)

include_directories("${PROJECT_SOURCE_DIR}/dependencies/SDL2/include")
include_directories(
"${PROJECT_SOURCE_DIR}/dependencies/SDL2/include"
"${PROJECT_SOURCE_DIR}/dependencies/minIni/dev"
)

if (WIN32)
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
@@ -16,7 +19,12 @@ if (WIN32)
endif ()

link_directories("${PROJECT_SOURCE_DIR}/dependencies/SDL2/lib/${PROJECT_ARCH}")
add_executable(izanagi src/packages/game/main.c)
add_executable(
izanagi
dependencies/minIni/dev/minIni.h
dependencies/minIni/dev/minIni.c
src/packages/game/main.c
)
target_link_libraries(izanagi SDL2main SDL2)

if (WIN32)
@@ -25,3 +33,8 @@ if (WIN32)
"${PROJECT_SOURCE_DIR}/dependencies/SDL2/lib/${PROJECT_ARCH}/SDL2.dll" # <--this is in-file
$<TARGET_FILE_DIR:izanagi>) # <--this is out-file path
endif ()

add_custom_command(TARGET izanagi POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different # which executes "cmake - E copy_if_different..."
"${PROJECT_SOURCE_DIR}/assets/config.ini" # <--this is in-file
$<TARGET_FILE_DIR:izanagi>) # <--this is out-file path

+ 21
- 0
assets/config.ini Прегледај датотеку

@@ -0,0 +1,21 @@
[Video]
Width=640
Height=480

[Controls.0.Keyboard]
Right=Right
Down=Down
Left=Left
Up=Up
Affirm=Return
Negate=Backspace
Action0=A
Action1=S
Action2=D
Action3=F
Action4=Z
Action5=X
Action6=C
Action7=V
Action8=W
Action9=E

+ 1
- 0
dependencies.txt Прегледај датотеку

@@ -0,0 +1 @@
https://github.com/compuphase/minIni

+ 78
- 18
src/packages/game/main.c Прегледај датотеку

@@ -1,14 +1,14 @@
#include <SDL.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <minIni.h>

const char* APP_NAME = "SDL2";
const unsigned int SCREEN_WIDTH = 640;
const unsigned int SCREEN_HEIGHT = 480;
static const unsigned char CONTROLS = 16;
static const unsigned char PLAYERS = 1;

const unsigned char CONTROLS = 16;

const SDL_KeyCode KEYBOARD_CONTROLS[CONTROLS] = {
static const SDL_KeyCode KEYBOARD_CONTROLS[CONTROLS] = {
SDLK_RIGHT,
SDLK_DOWN,
SDLK_LEFT,
@@ -27,9 +27,69 @@ const SDL_KeyCode KEYBOARD_CONTROLS[CONTROLS] = {
SDLK_e, // action9
};

static const char* ACTION_NAMES[CONTROLS] = {
"Right",
"Down",
"Left",
"Up",
"Affirm",
"Negate",
"Action0",
"Action1",
"Action2",
"Action3",
"Action4",
"Action5",
"Action6",
"Action7",
"Action8",
"Action9",
};

typedef struct {
unsigned int width;
unsigned int height;
} IZ_VideoConfig;

typedef SDL_KeyCode IZ_KeyCode;

typedef int IZ_PadButton;

typedef struct {
IZ_KeyCode keyboard[CONTROLS];
IZ_PadButton gamepad[CONTROLS];
} IZ_ControlsConfig;

typedef struct {
IZ_VideoConfig video;
IZ_ControlsConfig controls[PLAYERS];
} IZ_Config;

static void IZ_GetConfigPath(char* config_path) {
//const char* config_path_dir = SDL_GetPrefPath("Modal Studios", APP_NAME);
const char* config_path_dir = SDL_GetBasePath();
memcpy_s(config_path, 128, config_path_dir, 128);
strcat_s(config_path, 128, "config.ini");
}

static void IZ_LoadConfig(IZ_Config* config) {
static char config_path[128];
IZ_GetConfigPath(config_path);
// TODO check if file exists first
config->video.width = ini_getl("Video", "Width", 640l, config_path);
config->video.height = ini_getl("Video", "Height", 480l, config_path);
char buffer[128];
for (int i = 0; i < CONTROLS; i += 1) {
ini_gets("Controls.0.Keyboard", ACTION_NAMES[i], SDL_GetKeyName(KEYBOARD_CONTROLS[i]), buffer, 128, config_path);
config->controls[0].keyboard[i] = SDL_GetKeyFromName(buffer);
}
}

int main(int argc, char* args[]) {
SDL_Window* window = NULL;
SDL_Surface* screenSurface = NULL;
SDL_Surface* screen_surface = NULL;
IZ_Config config;
IZ_LoadConfig(&config);

if (SDL_Init(
SDL_INIT_VIDEO
@@ -42,10 +102,10 @@ int main(int argc, char* args[]) {

window = SDL_CreateWindow(
APP_NAME,
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
SCREEN_WIDTH,
SCREEN_HEIGHT,
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
config.video.width,
config.video.height,
SDL_WINDOW_SHOWN
);

@@ -56,11 +116,11 @@ int main(int argc, char* args[]) {

bool quit = false;
SDL_Event e;
screenSurface = SDL_GetWindowSurface(window);
screen_surface = SDL_GetWindowSurface(window);

unsigned short action = 0;
while (!quit) {
SDL_FillRect(screenSurface, NULL, SDL_MapRGB(screenSurface->format, 0x00, 0x00, 0x00));
SDL_FillRect(screen_surface, NULL, SDL_MapRGB(screen_surface->format, 0x00, 0x00, 0x00));
uint64_t ticks = SDL_GetTicks64();
for (unsigned char i = 0; i < 64; i += 1) {
const unsigned char column = (64 - i) % 32;
@@ -68,12 +128,12 @@ int main(int argc, char* args[]) {
const uint64_t bitflag = (0x1lu << i);
const unsigned char size = 4;
if (ticks & bitflag) {
SDL_FillRect(screenSurface, &(SDL_Rect) {
SDL_FillRect(screen_surface, &(SDL_Rect) {
column * size,
SCREEN_HEIGHT - ((row + 1) * size),
config.video.height - ((row + 1) * size),
size,
size
}, SDL_MapRGB(screenSurface->format, 0x00, 0xff, 0xff));
}, SDL_MapRGB(screen_surface->format, 0x00, 0xff, 0xff));
}
}

@@ -84,7 +144,7 @@ int main(int argc, char* args[]) {

for (unsigned char i = 0; i < CONTROLS; i += 1) {
// TODO do same for gamepad
if (e.key.keysym.sym == KEYBOARD_CONTROLS[i]) {
if (e.key.keysym.sym == config.controls[0].keyboard[i]) {
const unsigned short bitflag = (0x1 << i);
if (e.type == SDL_KEYDOWN) {
action |= bitflag;
@@ -100,12 +160,12 @@ int main(int argc, char* args[]) {
const unsigned short bitflag = (0x1 << i);
const unsigned char size = 4;
if (action & bitflag) {
SDL_FillRect(screenSurface, &(SDL_Rect) {
SDL_FillRect(screen_surface, &(SDL_Rect) {
column * size,
row * size,
size,
size
}, SDL_MapRGB(screenSurface->format, 0xff, 0xff, 0x00));
}, SDL_MapRGB(screen_surface->format, 0xff, 0xff, 0x00));
}
}



Loading…
Откажи
Сачувај