Separate engine and game

This commit is contained in:
2023-11-07 16:55:14 +01:00
parent 8a13edb838
commit 20034c96e6
922 changed files with 526 additions and 29 deletions

139
engine/breeze/core/logger.c Normal file
View File

@@ -0,0 +1,139 @@
#include "logger.h"
#include "logger_module.h"
#include "module_system.h"
#include <stdio.h>
#include <stdarg.h>
#include <time.h>
#define BZ_GET_LOGGER_MODULE() ((BzLoggerModule *) bzModuleRetrieve(BZ_MODULE_LOGGER))
bool bzLoggerInit() {
if (bzModuleIsAllocated(BZ_MODULE_LOGGER))
return false;
BzLoggerModule *logger = bzModuleAllocate(BZ_MODULE_LOGGER, sizeof(*logger));
if (logger == NULL)
return false;
logger->level = BZ_LOG_INFO;
logger->silent = false;
return true;
}
void bzLoggerDeinit() {
BzLoggerModule *logger = BZ_GET_LOGGER_MODULE();
bzModuleFree(BZ_MODULE_LOGGER);
}
void bzLoggerEnableDefaultLog(bool enable) {
BZ_GET_LOGGER_MODULE()->silent = !enable;
}
void bzLoggerSetLevel(BzLoggerLevel level) {
BZ_GET_LOGGER_MODULE()->level = level;
}
BzLoggerLevel bzLoggerGetLevel() {
return BZ_GET_LOGGER_MODULE()->level;
}
static const char *LEVEL_STRINGS[] = {
"TRACE",
"DEBUG",
"INFO",
"WARN",
"ERROR",
"FATAL"
};
static const char *LEVEL_COLORS[] = {
"\x1b[90m", // TRACE -> Bright black
"\x1b[96m", // DEBUG -> Bright cyan
"\x1b[32m", // INFO -> Green
"\x1b[33m", // WARN -> Yellow
"\x1b[31m", // ERROR -> Red
"\x1b[91m", // FATAL -> Bright red
};
static void bzLoggerStdOutCallback(BzLoggerEvent *ev) {
va_list *ap = ev->apList;
fprintf(stderr, "%s %s%-5s\x1b[0m \x1b[90m%s:%d:\x1b[0m ",
ev->time, LEVEL_STRINGS[ev->level], LEVEL_COLORS[ev->level], ev->file, ev->line);
vfprintf(stderr, ev->fmt, *ap);
fprintf(stderr, "\n");
fflush(stderr);
}
static void bzLoggerFileCallback(BzLoggerEvent *ev) {
FILE *fp = ev->userData;
va_list *ap = ev->apList;
fprintf(fp, "%s %-5s %s:%d: ", ev->time, LEVEL_STRINGS[ev->level], ev->file, ev->line);
vfprintf(fp, ev->fmt, *ap);
fflush(fp);
}
void bzLoggerLog(BzLoggerLevel level, const char *file, int line, const char *fmt, ...) {
BzLoggerEvent event = {NULL, NULL, level, file, line, fmt};
const int loggerLevel = bzLoggerGetLevel();
time_t t = time(NULL);
struct tm *lt = localtime(&t);
char timeBuf[16];
size_t lastIdx = strftime(timeBuf, sizeof(timeBuf), "%H:%M:%S", lt);
// TODO: Assert
timeBuf[lastIdx] = '\0';
event.time = timeBuf;
if (!BZ_GET_LOGGER_MODULE()->silent && level <= loggerLevel) {
event.userData = stderr;
va_list ap;
va_start(ap, fmt);
event.apList = &ap;
bzLoggerStdOutCallback(&event);
va_end(ap);
}
for (int i = 0; i < BZ_LOGGER_MAX_CALLBACKS; ++i) {
BzLoggerCallback cb = BZ_GET_LOGGER_MODULE()->callbacks[i];
if (level <= cb.level) {
event.userData = cb.userData;
va_list ap;
va_start(ap, fmt);
event.apList = &ap;
cb.callback(&event);
va_end(ap);
}
}
}
bool bzLoggerAddFP(void *fp, BzLoggerLevel level) {
return bzLoggerAddCB(&(BzLoggerCallback) {
.callback = bzLoggerFileCallback,
.level = level,
.userData = fp
});
}
bool bzLoggerAddCB(const BzLoggerCallback *callback) {
for (int i = 0; i < BZ_LOGGER_MAX_CALLBACKS; ++i) {
BzLoggerCallback *cbSlot = &BZ_GET_LOGGER_MODULE()->callbacks[i];
if (cbSlot->callback == NULL) {
*cbSlot = *callback;
return true;
}
}
return false;
}

View File

@@ -0,0 +1,53 @@
#ifndef BREEZE_LOGGER_H
#define BREEZE_LOGGER_H
#include "../defines.h"
typedef enum BzLoggerLevel {
BZ_LOG_TRACE,
BZ_LOG_DEBUG,
BZ_LOG_INFO,
BZ_LOG_WARN,
BZ_LOG_ERROR,
BZ_LOG_FATAL,
} BzLoggerLevel;
typedef struct BzLoggerEvent {
void *userData;
const char *time;
BzLoggerLevel level;
const char *file;
int line;
const char *fmt;
void *apList;
} BzLoggerEvent;
typedef struct BzLoggerCallback {
void (*callback)(BzLoggerEvent *ev);
enum BzLoggerLevel level;
void *userData;
} BzLoggerCallback;
bool bzLoggerInit();
void bzLoggerDeinit();
void bzLoggerEnableDefaultLog(bool enable);
void bzLoggerSetLevel(BzLoggerLevel level);
BzLoggerLevel bzLoggerGetLevel();
void bzLoggerLog(BzLoggerLevel level, const char *file, int line, const char *fmt, ...);
bool bzLoggerAddFP(void *fp, BzLoggerLevel level);
bool bzLoggerAddCB(const BzLoggerCallback *callback);
#define bzLogTrace(...) bzLoggerLog(BZ_LOG_TRACE, __FILE__, __LINE__, __VA_ARGS__)
#define bzLogDebug( ...) bzLoggerLog(BZ_LOG_DEBUG, __FILE__, __LINE__, __VA_ARGS__)
#define bzLogInfo(...) bzLoggerLog(BZ_LOG_INFO, __FILE__, __LINE__, __VA_ARGS__)
#define bzLogWarn(...) bzLoggerLog(BZ_LOG_WARN, __FILE__, __LINE__, __VA_ARGS__)
#define bzLogError(...) bzLoggerLog(BZ_LOG_ERROR, __FILE__, __LINE__, __VA_ARGS__)
#define bzLogFatal(...) bzLoggerLog(BZ_LOG_FATAL, __FILE__, __LINE__, __VA_ARGS__)
#endif //BREEZE_LOGGER_H

View File

@@ -0,0 +1,15 @@
#ifndef BREEZE_LOGGER_MODULE_H
#define BREEZE_LOGGER_MODULE_H
#include "logger.h"
#define BZ_LOGGER_MAX_CALLBACKS 32
typedef struct BzLoggerModule {
BzLoggerCallback callbacks[BZ_LOGGER_MAX_CALLBACKS];
int level;
bool silent;
} BzLoggerModule;
#endif //BREEZE_LOGGER_MODULE_H

View File

@@ -0,0 +1,27 @@
#include "module_system.h"
#include <malloc.h>
void *BZ_MODULES[BZ_ENGINE_MODULE_COUNT] = {NULL,};
bool bzModuleIsAllocated(BzModule module) {
return BZ_MODULES[module] != NULL;
}
void *bzModuleRetrieve(BzModule module) {
return BZ_MODULES[module];
}
void *bzModuleAllocate(BzModule module, size_t sizeBytes) {
if (bzModuleIsAllocated(module)) {
bzModuleFree(module);
}
BZ_MODULES[module] = calloc(1, sizeBytes);
return BZ_MODULES[module];
}
void bzModuleFree(BzModule module) {
if (bzModuleIsAllocated(module))
free(BZ_MODULES[module]);
BZ_MODULES[module] = NULL;
}

View File

@@ -0,0 +1,18 @@
#ifndef BREEZE_MODULE_H
#define BREEZE_MODULE_H
#include "../defines.h"
typedef enum BzModule {
BZ_MODULE_LOGGER,
BZ_MODULE_APPLICATION,
BZ_MODULE_INPUT,
BZ_ENGINE_MODULE_COUNT
} BzModule;
bool bzModuleIsAllocated(BzModule module);
void *bzModuleRetrieve(BzModule module);
void *bzModuleAllocate(BzModule module, size_t sizeBytes);
void bzModuleFree(BzModule module);
#endif //BREEZE_MODULE_H

29
engine/breeze/defines.h Normal file
View File

@@ -0,0 +1,29 @@
#ifndef BREEZE_DEFINES_H
#define BREEZE_DEFINES_H
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef int8_t i8;
typedef int16_t i16;
typedef int32_t i32;
typedef int64_t i64;
typedef float f32;
typedef double f64;
#define BZ_ASSERT(e) assert(e)
#ifndef DEBUG_MODE
#undef BZ_ASSERT
#define BZ_ASSERT(e) (void)(e)
#endif
#endif //BREEZE_DEFINES_H

80
engine/breeze/game.h Normal file
View File

@@ -0,0 +1,80 @@
#ifndef BREEZE_GAME_H
#define BREEZE_GAME_H
#include "core/logger.h"
typedef bool (*BzAppInitFunc)(void *);
typedef void (*BzAppUpdateFunc)(float, void *);
typedef void (*BzAppRenderFunc)(float, void *);
typedef void (*BzAppDeinitFunc)(void *);
typedef struct BzAppDesc {
int32_t width;
int32_t height;
const char *title;
BzAppInitFunc init;
BzAppUpdateFunc update;
BzAppRenderFunc render;
BzAppDeinitFunc deinit;
void *userData;
} BzAppDesc;
extern bool bzMain(BzAppDesc *appDesc, int argc, const char **argv);
#ifdef BZ_GAME_ENTRYPOINT
#include <raylib.h>
int main(int argc, const char **argv) {
if (!bzLoggerInit())
return 1;
bzLoggerSetLevel(BZ_LOG_INFO);
bzLogInfo("[Breeze] Logger initialized successfully.");
BzAppDesc appDesc = {
1280,
720,
"Breeze Engine"
};
bool successful = bzMain(&appDesc, argc, argv);
if (!successful) return 1;
// Validate
if (!appDesc.render) {
bzLogFatal("[Breeze] No render function specifies.");
return 1;
}
bzLogInfo("[Breeze] User initialization (bzMain) successful.");
// Initialize modules
// User initialize
if (appDesc.init && !appDesc.init(appDesc.userData)) {
return 1;
}
while (!WindowShouldClose()) {
if (appDesc.update)
appDesc.update(0.0f, appDesc.userData);
if (appDesc.render)
appDesc.render(0.0f, appDesc.userData);
}
// User deinitialize
if (appDesc.deinit)
appDesc.deinit(appDesc.userData);
// Deinitialize modules
bzLoggerDeinit();
return 0;
}
#endif
#endif //BREEZE_GAME_H

View File

@@ -0,0 +1,11 @@
#ifndef BREEZE_VEC2_H
#define BREEZE_VEC2_H
#include "breeze/defines.h"
typedef struct Vec2i {
int32_t x;
int32_t y;
} Vec2i;
#endif //BREEZE_VEC2_H

View File

@@ -0,0 +1,47 @@
#include "tokenizer.h"
Tokenizer initTokenizer(const char *source) {
int line = source ? 1 : 0;
return (Tokenizer) {source, line};
}
static bool isWhitespace(char c) {
switch (c) {
case '\n':
case ' ':
case '\r':
case '\t':
return true;
default:
return false;
}
}
static void skipWhitespace(Tokenizer *tokenizer) {
while (1) {
char c = *tokenizer->current;
if (c == '\n') {
tokenizer->line++;
continue;
}
if (!isWhitespace(c))
break;
}
}
Token scanToken(Tokenizer *tokenizer) {
skipWhitespace(tokenizer);
Token token = {tokenizer->current, 0, tokenizer->line};
if (*tokenizer->current == '\0') {
token.start = NULL;
return token;
}
while (!isWhitespace(*tokenizer->current) || *tokenizer->current != '\0') {
tokenizer->current++;
}
token.length = (int) (tokenizer->current - token.start);
return token;
}

View File

@@ -0,0 +1,20 @@
#ifndef BREEZE_TOKENIZER_H
#define BREEZE_TOKENIZER_H
#include "../defines.h"
typedef struct Token {
const char *start;
int length;
int line;
} Token;
typedef struct Tokenizer {
const char *current;
int line;
} Tokenizer;
Tokenizer initTokenizer(const char *source);
Token scanToken(Tokenizer *tokenizer);
#endif //BREEZE_TOKENIZER_H