update api

This commit is contained in:
NishiOwO 2025-04-16 17:51:23 +09:00
parent ec15a060bb
commit 7e75c0357e
No known key found for this signature in database
GPG Key ID: 27EF69B208EB9343
30 changed files with 530 additions and 265 deletions

44
engine/gf_client.c Normal file
View File

@ -0,0 +1,44 @@
#define GF_EXPOSE_CLIENT
#include <gf_pre.h>
/* External library */
/* Interface */
#include <gf_client.h>
/* Engine */
#include <gf_draw.h>
#include <gf_log.h>
/* Standard */
#include <stdlib.h>
#include <string.h>
void gf_client_begin(void) { gf_draw_begin(); }
void gf_client_end(void) { gf_draw_end(); }
gf_client_t* gf_client_create(gf_engine_t* engine, const char* title) {
gf_client_t* client = malloc(sizeof(*client));
memset(client, 0, sizeof(*client));
client->engine = engine;
client->draw = gf_draw_create(engine, title);
if(client->draw == NULL) {
gf_log_function(engine, "Failed to create drawing interface", "");
gf_client_destroy(client);
return NULL;
}
return client;
}
void gf_client_destroy(gf_client_t* client) {
if(client->draw != NULL) gf_draw_destroy(client->draw);
gf_log_function(client->engine, "Destroyed client interface", "");
free(client);
}
int gf_client_step(gf_client_t* client) {
int s = gf_draw_step(client->draw);
return s;
}

View File

@ -11,8 +11,8 @@
#include <gf_core.h>
/* Engine */
#include <gf_draw.h>
#include <gf_physics.h>
#include <gf_client.h>
#include <gf_server.h>
#include <gf_log.h>
#include <gf_version.h>
@ -37,13 +37,13 @@ void gf_engine_begin(void) {
WSAStartup(MAKEWORD(1, 1), &wsa);
gf_log_function(NULL, "Winsock ready", "");
#endif
gf_draw_begin();
gf_physics_begin();
gf_client_begin();
gf_server_begin();
}
void gf_engine_end(void) {
gf_physics_end();
gf_draw_end();
gf_server_end();
gf_client_end();
}
gf_engine_t* gf_engine_create(const char* title, int nogui) {
@ -51,49 +51,47 @@ gf_engine_t* gf_engine_create(const char* title, int nogui) {
memset(engine, 0, sizeof(*engine));
engine->log = stderr;
if(nogui) {
gf_log_function(NULL, "No GUI mode", "");
engine->draw = NULL;
gf_log_function(engine, "No GUI mode", "");
engine->client = NULL;
} else {
gf_log_function(NULL, "GUI mode", "");
engine->draw = gf_draw_create(engine, title);
if(engine->draw == NULL) {
gf_log_function(NULL, "Failed to create drawing interface", "");
free(engine);
gf_log_function(engine, "GUI mode", "");
engine->client = gf_client_create(engine, title);
if(engine->client == NULL) {
gf_log_function(engine, "Failed to create client interface", "");
gf_engine_destroy(engine);
return NULL;
}
gf_log_function(engine, "Switching to graphical console", "");
}
engine->physics = gf_physics_create();
engine->server = gf_server_create(engine);
return engine;
}
void gf_engine_set_draw(gf_engine_t* engine, void (*func)(gf_draw_t*)) { gf_draw_set_draw(engine->draw, func); }
/**
* Writing this so I don't forget
*
* 1. Calls gf_draw_step
* 2. gf_draw_step calls gf_draw_platform_step (Platform-dependent)
* 3. gf_draw_platform_step processes platform-dependent stuffs (e.g. events)
* 4. gf_draw_platform_step calls gf_draw_driver_before
* 5. gf_draw_platform_step calls gf_draw_frame
* 6. gf_draw_frame calls gf_draw_t.draw to draw frame
* 7. gf_draw_frame draws more stuffs if required
* 1. Calls gf_client_step
* 2. gf_client_step calls gf_draw_step
* 3. gf_draw_step calls gf_draw_platform_step (Platform-dependent)
* 4. gf_draw_platform_step processes platform-dependent stuffs (e.g. events)
* 5. gf_draw_platform_step calls gf_draw_driver_before
* 6. gf_draw_platform_step calls gf_draw_frame
* 7. gf_draw_frame draws stuffs
* 8. gf_draw_platform_step calls gf_draw_driver_after
* 9. gf_draw_platform_step swaps buffers
* 10. Comes back here
*/
void gf_engine_loop(gf_engine_t* engine) {
while(1) {
if(engine->draw != NULL) {
if(gf_draw_step(engine->draw) != 0) break;
if(engine->client != NULL) {
if(gf_client_step(engine->client) != 0) break;
}
}
}
void gf_engine_destroy(gf_engine_t* engine) {
if(engine->physics != NULL) gf_physics_destroy(engine->physics);
if(engine->draw != NULL) gf_draw_destroy(engine->draw);
if(engine->server != NULL) gf_server_destroy(engine->server);
if(engine->client != NULL) gf_client_destroy(engine->client);
free(engine);
gf_log_function(NULL, "Destroyed engine", "");
}

View File

@ -15,6 +15,7 @@
#include <gf_draw_driver.h>
#include <gf_texture.h>
#include <gf_graphic.h>
#include <gf_font.h>
#include <gf_gui.h>
/* Standard */
@ -31,6 +32,7 @@ gf_texture_t* test_texture;
gf_draw_t* gf_draw_create(gf_engine_t* engine, const char* title) {
gf_draw_t* draw = malloc(sizeof(*draw));
memset(draw, 0, sizeof(*draw));
draw->engine = engine;
draw->x = 0;
draw->y = 0;
draw->width = 640;
@ -38,10 +40,10 @@ gf_draw_t* gf_draw_create(gf_engine_t* engine, const char* title) {
draw->running = 0;
draw->draw_3d = 0;
strcpy(draw->title, title);
gf_draw_platform_create(draw);
draw->platform = gf_draw_platform_create(engine, draw);
if(draw->platform != NULL) {
gf_log_function(NULL, "Created drawing interface successfully", "");
gf_draw_driver_init(draw);
int i;
draw->driver = gf_draw_driver_create(engine, draw);
gf_draw_reshape(draw);
draw->running = 1;
@ -58,15 +60,30 @@ gf_draw_t* gf_draw_create(gf_engine_t* engine, const char* title) {
draw->lookat[1] = 0;
draw->lookat[2] = 0;
draw->gui = gf_gui_create(draw);
draw->gui = gf_gui_create(engine, draw);
if(1) {
int w, h, c;
unsigned char* d = stbi_load("texture/test.bmp", &w, &h, &c, 4);
test_texture = gf_texture_register(draw, w, h, d);
test_texture = gf_texture_create(draw, w, h, d);
free(d);
}
for(i = 0; i < sizeof(gf_font) / sizeof(gf_font[0]); i++) {
unsigned char* font = malloc(8 * 8 * 4);
int j;
for(j = 0; j < 8 * 8; j++) {
unsigned char val = (gf_font[i][j / 8] >> (j % 8)) & 1 ? 255 : 0;
font[j * 4 + 0] = val;
font[j * 4 + 1] = val;
font[j * 4 + 2] = val;
font[j * 4 + 3] = val;
}
draw->font[i] = gf_texture_create(draw, 8, 8, font);
free(font);
}
gf_log_function(engine, "Registered %d glyphs", sizeof(gf_font) / sizeof(gf_font[0]));
} else {
free(draw);
gf_draw_destroy(draw);
draw = NULL;
}
return draw;
@ -78,28 +95,25 @@ void gf_draw_reshape(gf_draw_t* draw) { gf_draw_driver_reshape(draw); }
void gf_draw_frame(gf_draw_t* draw) {
gf_graphic_color_t color;
color.r = color.g = color.b = color.a = 255;
if(draw->draw_3d) {
if(!draw->draw_3d) {
gf_graphic_draw_texture_polygon(draw, test_texture, color, GF_GRAPHIC_3D, 4,
/* clang-format off */
0.0, 0.0,
-1.0, 0.0, -1.0,
0.0, 4.0,
-1.0, 0.0, 1.0,
4.0, 4.0,
1.0, 0.0, 1.0,
4.0, 0.0,
1.0, 0.0, -1.0
/* clang-format on */
);
}
gf_graphic_draw_texture_polygon(draw, test_texture, color, GF_GRAPHIC_3D, 4,
/* clang-format off */
0.0, 0.0,
-1.0, 0.0, -1.0,
0.0, 8.0,
-1.0, 0.0, 1.0,
8.0, 8.0,
1.0, 0.0, 1.0,
8.0, 0.0,
1.0, 0.0, -1.0
/* clang-format on */
);
if(draw->draw != NULL) draw->draw(draw);
}
void gf_draw_set_draw(gf_draw_t* draw, void (*func)(gf_draw_t*)) { draw->draw = func; }
int gf_draw_step(gf_draw_t* draw) {
int ret = gf_draw_platform_step(draw);
if(ret != 0) return ret;
@ -109,10 +123,14 @@ int gf_draw_step(gf_draw_t* draw) {
}
void gf_draw_destroy(gf_draw_t* draw) {
int i;
if(draw->running) {
gf_draw_driver_destroy(draw);
int i;
for(i = 0; i < sizeof(gf_font) / sizeof(gf_font[0]); i++) {
gf_texture_destroy(draw->font[i]);
}
}
gf_draw_platform_destroy(draw);
gf_log_function(NULL, "Destroyed drawing interface", "");
if(draw->driver != NULL) gf_draw_driver_destroy(draw->driver);
if(draw->platform != NULL) gf_draw_platform_destroy(draw->platform);
gf_log_function(draw->engine, "Destroyed drawing interface", "");
free(draw);
}

View File

@ -18,10 +18,12 @@
gf_graphic_color_t gf_gui_base_color;
gf_graphic_color_t gf_gui_font_color;
gf_gui_t* gf_gui_create(gf_draw_t* draw) {
gf_gui_t* gf_gui_create(gf_engine_t* engine, gf_draw_t* draw) {
gf_gui_t* gui = malloc(sizeof(*gui));
gf_gui_id_t i;
gui->draw = draw;
memset(gui, 0, sizeof(*gui));
gui->engine = engine;
gui->draw = draw;
GF_SET_COLOR(gf_gui_base_color, 48, 96, 48, 255);
GF_SET_COLOR(gf_gui_font_color, 256 - 32, 256 - 32, 256 - 32, 255);

View File

@ -18,8 +18,9 @@ void gf_physics_begin(void) { dInitODE(); }
void gf_physics_end(void) { dCloseODE(); }
gf_physics_t* gf_physics_create(void) {
gf_physics_t* gf_physics_create(gf_engine_t* engine) {
gf_physics_t* physics = malloc(sizeof(*physics));
physics->engine = engine;
physics->id = dWorldCreate();
dWorldSetGravity(physics->id, 0, 0, -9.81);
return physics;
@ -27,6 +28,6 @@ gf_physics_t* gf_physics_create(void) {
void gf_physics_destroy(gf_physics_t* physics) {
dWorldDestroy(physics->id);
gf_log_function(physics->engine, "Destroyed physics interface", "");
free(physics);
gf_log_function(NULL, "Destroyed physics", "");
}

39
engine/gf_server.c Normal file
View File

@ -0,0 +1,39 @@
#define GF_EXPOSE_SERVER
#include <gf_pre.h>
/* External library */
/* Interface */
#include <gf_server.h>
/* Engine */
#include <gf_physics.h>
#include <gf_log.h>
/* Standard */
#include <stdlib.h>
#include <string.h>
void gf_server_begin(void) { gf_physics_begin(); }
void gf_server_end(void) { gf_physics_end(); }
gf_server_t* gf_server_create(gf_engine_t* engine) {
gf_server_t* server = malloc(sizeof(*server));
memset(server, 0, sizeof(*server));
server->engine = engine;
server->physics = gf_physics_create(engine);
if(server->physics == NULL) {
gf_log_function(engine, "Failed to create physics interface", "");
gf_server_destroy(server);
return NULL;
}
return server;
}
void gf_server_destroy(gf_server_t* server) {
if(server->physics != NULL) gf_physics_destroy(server->physics);
gf_log_function(server->engine, "Destroyed server interface", "");
free(server);
}

View File

@ -14,7 +14,7 @@
/* Standard */
#include <stdlib.h>
gf_texture_t* gf_texture_register(gf_draw_t* draw, int width, int height, unsigned char* data) {
gf_texture_t* gf_texture_create(gf_draw_t* draw, int width, int height, unsigned char* data) {
gf_texture_t* texture = malloc(sizeof(*texture));
gf_draw_driver_texture_t* ddtexture;
texture->internal_width = width;

View File

@ -15,7 +15,6 @@
#include <gf_texture.h>
#include <gf_draw.h>
#include <gf_log.h>
#include <gf_font.h>
#include <gf_math.h>
#include <gf_graphic.h>
@ -66,12 +65,14 @@ void gf_draw_driver_destroy_texture(gf_draw_driver_texture_t* t) {
free(t);
}
void gf_draw_driver_init(gf_draw_t* draw) {
int i;
int w, h, ch;
draw->driver = malloc(sizeof(*draw->driver));
gf_draw_driver_t* gf_draw_driver_create(gf_engine_t* engine, gf_draw_t* draw) {
int i;
int w, h, ch;
gf_draw_driver_t* draw_driver = malloc(sizeof(*draw_driver));
memset(draw_driver, 0, sizeof(*draw_driver));
draw_driver->engine = engine;
gf_log_function(NULL, "OpenGL renderer: %s", (char*)glGetString(GL_RENDERER));
gf_log_function(engine, "OpenGL renderer: %s", (char*)glGetString(GL_RENDERER));
glEnable(GL_BLEND);
glEnable(GL_NORMALIZE);
@ -94,22 +95,9 @@ void gf_draw_driver_init(gf_draw_t* draw) {
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightwht);
glLightfv(GL_LIGHT0, GL_SPECULAR, lightwht);
for(i = 0; i < sizeof(gf_font) / sizeof(gf_font[0]); i++) {
unsigned char* font = malloc(8 * 8 * 4);
int j;
for(j = 0; j < 8 * 8; j++) {
unsigned char val = (gf_font[i][j / 8] >> (j % 8)) & 1 ? 255 : 0;
font[j * 4 + 0] = val;
font[j * 4 + 1] = val;
font[j * 4 + 2] = val;
font[j * 4 + 3] = val;
}
draw->font[i] = gf_texture_register(draw, 8, 8, font);
free(font);
}
gf_log_function(NULL, "Registered %d glyphs", sizeof(gf_font) / sizeof(gf_font[0]));
glClearColor(0, 0, 0, 1);
return draw_driver;
}
int gf_draw_driver_has_extension(gf_draw_t* draw, const char* query) {
@ -145,11 +133,9 @@ void gf_draw_driver_end_texture_2d(gf_draw_t* draw) {
void gf_draw_driver_set_color(gf_draw_t* draw, gf_graphic_color_t color) { glColor4f(color.r / 255, color.g / 255, color.b / 255, color.a / 255); }
void gf_draw_driver_destroy(gf_draw_t* draw) {
int i;
for(i = 0; i < sizeof(gf_font) / sizeof(gf_font[0]); i++) {
gf_texture_destroy(draw->font[i]);
}
void gf_draw_driver_destroy(gf_draw_driver_t* driver) {
gf_log_function(driver->engine, "Destroyed drawing driver", "");
free(driver);
}
void gf_draw_driver_before(gf_draw_t* draw) {

View File

@ -63,30 +63,32 @@ int gf_draw_platform_step(gf_draw_t* draw) {
return ret;
}
void gf_draw_platform_create(gf_draw_t* draw) {
draw->platform = malloc(sizeof(*draw->platform));
memset(draw->platform, 0, sizeof(*draw->platform));
gf_draw_platform_t* gf_draw_platform_create(gf_engine_t* engine, gf_draw_t* draw) {
gf_draw_platform_t* platform = malloc(sizeof(*platform));
memset(platform, 0, sizeof(*platform));
platform->engine = engine;
draw->platform->window = glfwCreateWindow(draw->width, draw->height, draw->title, NULL, NULL);
if(draw->platform->window == NULL) {
gf_log_function(NULL, "Failed to create window", "");
gf_draw_destroy(draw);
return;
platform->window = glfwCreateWindow(draw->width, draw->height, draw->title, NULL, NULL);
if(platform->window == NULL) {
gf_log_function(engine, "Failed to create window", "");
gf_draw_platform_destroy(platform);
return NULL;
}
glfwSetWindowUserPointer(draw->platform->window, draw);
glfwSetWindowSizeCallback(draw->platform->window, gf_glfw_size);
glfwSetWindowUserPointer(platform->window, draw);
glfwSetWindowSizeCallback(platform->window, gf_glfw_size);
glfwMakeContextCurrent(draw->platform->window);
glfwMakeContextCurrent(platform->window);
#ifdef DO_SWAP_INTERVAL
glfwSwapInterval(1);
#endif
return platform;
}
void gf_draw_platform_destroy(gf_draw_t* draw) {
if(draw->platform->window != NULL) {
glfwDestroyWindow(draw->platform->window);
void gf_draw_platform_destroy(gf_draw_platform_t* platform) {
if(platform->window != NULL) {
glfwDestroyWindow(platform->window);
}
free(draw->platform);
draw->platform = NULL;
gf_log_function(platform->engine, "Destroyed platform-dependent part of drawing driver", "");
free(platform);
}

View File

@ -51,7 +51,7 @@ int gf_draw_platform_has_extension(gf_draw_t* draw, const char* query) {
return ((ptr != NULL) && ((ptr[len] == ' ') || (ptr[len] == '\0')));
}
void gf_draw_platform_create(gf_draw_t* draw) {
gf_draw_platform_t* gf_draw_platform_create(gf_engine_t* engine, gf_draw_t* draw) {
int i = 0;
int attribs[64];
int screen;
@ -60,15 +60,15 @@ void gf_draw_platform_create(gf_draw_t* draw) {
XSetWindowAttributes attr;
XSizeHints hints;
int interval = 0;
gf_draw_platform_t* platform = malloc(sizeof(*platform));
memset(platform, 0, sizeof(*platform));
platform->engine = engine;
draw->platform = malloc(sizeof(*draw->platform));
memset(draw->platform, 0, sizeof(*draw->platform));
draw->platform->display = XOpenDisplay(NULL);
if(draw->platform->display == NULL) {
gf_log_function(NULL, "Failed to open display", "");
gf_draw_destroy(draw);
return;
platform->display = XOpenDisplay(NULL);
if(platform->display == NULL) {
gf_log_function(engine, "Failed to open display", "");
gf_draw_platform_destroy(platform);
return NULL;
}
attribs[i++] = GLX_RGBA;
attribs[i++] = GLX_DOUBLEBUFFER;
@ -84,52 +84,52 @@ void gf_draw_platform_create(gf_draw_t* draw) {
attribs[i++] = None;
screen = DefaultScreen(draw->platform->display);
root = RootWindow(draw->platform->display, screen);
screen = DefaultScreen(platform->display);
root = RootWindow(platform->display, screen);
visual = glXChooseVisual(draw->platform->display, screen, attribs);
visual = glXChooseVisual(platform->display, screen, attribs);
if(visual == NULL) {
gf_log_function(NULL, "Failed to get visual", "");
gf_draw_destroy(draw);
return;
gf_log_function(engine, "Failed to get visual", "");
gf_draw_platform_destroy(platform);
return NULL;
}
attr.colormap = XCreateColormap(draw->platform->display, root, visual->visual, AllocNone);
attr.event_mask = StructureNotifyMask | ExposureMask | PointerMotionMask;
draw->platform->window = XCreateWindow(draw->platform->display, root, draw->width, draw->height, draw->width, draw->height, 0, visual->depth, InputOutput, visual->visual, CWColormap | CWEventMask, &attr);
attr.colormap = XCreateColormap(platform->display, root, visual->visual, AllocNone);
attr.event_mask = StructureNotifyMask | ExposureMask | PointerMotionMask;
platform->window = XCreateWindow(platform->display, root, draw->width, draw->height, draw->width, draw->height, 0, visual->depth, InputOutput, visual->visual, CWColormap | CWEventMask, &attr);
hints.x = draw->x;
hints.y = draw->y;
hints.width = draw->width;
hints.height = draw->height;
hints.flags = USSize | USPosition;
XSetNormalHints(draw->platform->display, draw->platform->window, &hints);
XSetStandardProperties(draw->platform->display, draw->platform->window, draw->title, "GoldFish", None, (char**)NULL, 0, &hints);
XSetNormalHints(platform->display, platform->window, &hints);
XSetStandardProperties(platform->display, platform->window, draw->title, "GoldFish", None, (char**)NULL, 0, &hints);
draw->platform->wm_delete_window = XInternAtom(draw->platform->display, "WM_DELETE_WINDOW", False);
XSetWMProtocols(draw->platform->display, draw->platform->window, &draw->platform->wm_delete_window, 1);
platform->wm_delete_window = XInternAtom(platform->display, "WM_DELETE_WINDOW", False);
XSetWMProtocols(platform->display, platform->window, &platform->wm_delete_window, 1);
draw->platform->context = glXCreateContext(draw->platform->display, visual, NULL, True);
if(draw->platform->context == NULL) {
platform->context = glXCreateContext(platform->display, visual, NULL, True);
if(platform->context == NULL) {
XFree(visual);
gf_log_function(NULL, "Failed to get OpenGL context", "");
gf_draw_destroy(draw);
return;
gf_log_function(engine, "Failed to get OpenGL context", "");
gf_draw_platform_destroy(platform);
return NULL;
}
XFree(visual);
XMapWindow(draw->platform->display, draw->platform->window);
glXMakeCurrent(draw->platform->display, draw->platform->window, draw->platform->context);
XMapWindow(platform->display, platform->window);
glXMakeCurrent(platform->display, platform->window, platform->context);
#ifdef DO_SWAP_INTERVAL
if(gf_draw_platform_has_extension(draw, "GLX_EXT_swap_control")) {
unsigned int tmp = -1;
PFNGLXSWAPINTERVALEXTPROC proc = (PFNGLXSWAPINTERVALEXTPROC)glXGetProcAddressARB("glXSwapIntervalEXT");
if(proc != NULL) {
proc(draw->platform->display, draw->platform->window, 1);
proc(platform->display, platform->window, 1);
}
glXQueryDrawable(draw->platform->display, draw->platform->window, GLX_SWAP_INTERVAL_EXT, &tmp);
glXQueryDrawable(platform->display, platform->window, GLX_SWAP_INTERVAL_EXT, &tmp);
interval = tmp;
} else if(gf_draw_platform_has_extension(draw, "GLX_MESA_swap_control")) {
PFNGLXGETSWAPINTERVALMESAPROC proc = (PFNGLXGETSWAPINTERVALMESAPROC)glXGetProcAddressARB("glXGetSwapIntervalMESA");
@ -144,9 +144,10 @@ void gf_draw_platform_create(gf_draw_t* draw) {
interval = 1;
}
if(interval > 0) {
gf_log_function(NULL, "Enabled VSync", "");
gf_log_function(engine, "Enabled VSync", "");
}
#endif
return platform;
}
int gf_draw_platform_step(gf_draw_t* draw) {
@ -181,15 +182,15 @@ int gf_draw_platform_step(gf_draw_t* draw) {
return ret;
}
void gf_draw_platform_destroy(gf_draw_t* draw) {
if(draw->platform->context != NULL) {
glXMakeCurrent(draw->platform->display, None, NULL);
glXDestroyContext(draw->platform->display, draw->platform->context);
void gf_draw_platform_destroy(gf_draw_platform_t* platform) {
if(platform->context != NULL) {
glXMakeCurrent(platform->display, None, NULL);
glXDestroyContext(platform->display, platform->context);
}
if(draw->platform->display != NULL) {
XDestroyWindow(draw->platform->display, draw->platform->window);
XCloseDisplay(draw->platform->display);
if(platform->display != NULL) {
XDestroyWindow(platform->display, platform->window);
XCloseDisplay(platform->display);
}
free(draw->platform);
draw->platform = NULL;
gf_log_function(platform->engine, "Destroyed platform-dependent part of drawing driver", "");
free(platform);
}

View File

@ -97,26 +97,24 @@ int gf_draw_platform_step(gf_draw_t* draw) {
return ret;
}
void gf_draw_platform_create(gf_draw_t* draw) {
gf_draw_platform_t* gf_draw_platform_create(gf_engine_t* engine, gf_draw_t* draw) {
WNDCLASSEX wc;
PIXELFORMATDESCRIPTOR desc;
#ifdef DO_SWAP_INTERVAL
PFNWGLSWAPINTERVALPROC wglSwapIntervalEXT;
#endif
RECT rect;
int fmt;
DWORD style;
RECT rect;
int fmt;
DWORD style;
gf_draw_platform_t* platform = malloc(sizeof(*platform));
memset(platform, 0, sizeof(*platform));
platform->engine = engine;
draw->platform = malloc(sizeof(*draw->platform));
memset(draw->platform, 0, sizeof(*draw->platform));
draw->platform->instance = (HINSTANCE)GetModuleHandle(NULL);
if(draw->platform->instance == NULL) {
gf_log_function(NULL, "Failed to get instance", "");
gf_draw_destroy(draw);
return;
} else {
gf_log_function(NULL, "Got instance", "");
platform->instance = (HINSTANCE)GetModuleHandle(NULL);
if(platform->instance == NULL) {
gf_log_function(engine, "Failed to get instance", "");
gf_draw_platform_destroy(platform);
return NULL;
}
wc.cbSize = sizeof(wc);
@ -124,31 +122,27 @@ void gf_draw_platform_create(gf_draw_t* draw) {
wc.lpfnWndProc = gf_draw_platform_proc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = draw->platform->instance;
wc.hIcon = LoadIcon(draw->platform->instance, "GAME");
wc.hInstance = platform->instance;
wc.hIcon = LoadIcon(platform->instance, "GAME");
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = "goldfish";
wc.hIconSm = LoadIcon(draw->platform->instance, "GAME");
wc.hIconSm = LoadIcon(platform->instance, "GAME");
if(!RegisterClassEx(&wc)) {
gf_log_function(NULL, "Failed to register class", "");
gf_draw_destroy(draw);
return;
} else {
gf_log_function(NULL, "Registered class", "");
gf_log_function(engine, "Failed to register class", "");
gf_draw_platform_destroy(platform);
return NULL;
}
draw->platform->window = CreateWindow("goldfish", draw->title, (WS_OVERLAPPEDWINDOW), draw->x, draw->y, draw->width, draw->height, NULL, 0, draw->platform->instance, NULL);
if(draw->platform->window == NULL) {
gf_log_function(NULL, "Failed to create window", "");
gf_draw_destroy(draw);
return;
} else {
gf_log_function(NULL, "Created window", "");
platform->window = CreateWindow("goldfish", draw->title, (WS_OVERLAPPEDWINDOW), draw->x, draw->y, draw->width, draw->height, NULL, 0, platform->instance, NULL);
if(platform->window == NULL) {
gf_log_function(engine, "Failed to create window", "");
gf_draw_platform_destroy(platform);
return NULL;
}
SetWindowLongPtr(draw->platform->window, GWLP_USERDATA, (LONG_PTR)draw);
SetWindowLongPtr(platform->window, GWLP_USERDATA, (LONG_PTR)draw);
memset(&desc, 0, sizeof(desc));
desc.nSize = sizeof(desc);
@ -159,51 +153,51 @@ void gf_draw_platform_create(gf_draw_t* draw) {
desc.cAlphaBits = 8;
desc.cDepthBits = 32;
draw->platform->dc = GetDC(draw->platform->window);
platform->dc = GetDC(platform->window);
fmt = ChoosePixelFormat(draw->platform->dc, &desc);
SetPixelFormat(draw->platform->dc, fmt, &desc);
fmt = ChoosePixelFormat(platform->dc, &desc);
SetPixelFormat(platform->dc, fmt, &desc);
draw->platform->glrc = wglCreateContext(draw->platform->dc);
if(draw->platform->glrc == NULL) {
gf_log_function(NULL, "Failed to create OpenGL context", "");
gf_draw_destroy(draw);
return;
} else {
gf_log_function(NULL, "Created OpenGL context", "");
platform->glrc = wglCreateContext(platform->dc);
if(platform->glrc == NULL) {
gf_log_function(engine, "Failed to create OpenGL context", "");
gf_draw_platform_destroy(platform);
return NULL;
}
wglMakeCurrent(draw->platform->dc, draw->platform->glrc);
wglMakeCurrent(platform->dc, platform->glrc);
#ifdef DO_SWAP_INTERVAL
wglSwapIntervalEXT = (PFNWGLSWAPINTERVALPROC)wglGetProcAddress("wglSwapIntervalEXT");
if(wglSwapIntervalEXT != NULL) {
gf_log_function(NULL, "Enabled VSync", "");
gf_log_function(engine, "Enabled VSync", "");
wglSwapIntervalEXT(1);
}
#endif
SetRect(&rect, 0, 0, draw->width, draw->height);
style = (DWORD)GetWindowLongPtr(draw->platform->window, GWL_STYLE);
style = (DWORD)GetWindowLongPtr(platform->window, GWL_STYLE);
AdjustWindowRect(&rect, style, FALSE);
SetWindowPos(draw->platform->window, NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOMOVE);
SetWindowPos(platform->window, NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOMOVE);
ShowWindow(draw->platform->window, SW_NORMAL);
UpdateWindow(draw->platform->window);
ShowWindow(platform->window, SW_NORMAL);
UpdateWindow(platform->window);
return platform;
}
void gf_draw_platform_destroy(gf_draw_t* draw) {
if(draw->platform->glrc != NULL) {
void gf_draw_platform_destroy(gf_draw_platform_t* platform) {
if(platform->glrc != NULL) {
wglMakeCurrent(NULL, NULL);
}
if(draw->platform->dc != NULL) {
ReleaseDC(draw->platform->window, draw->platform->dc);
if(platform->dc != NULL) {
ReleaseDC(platform->window, platform->dc);
}
if(draw->platform->glrc != NULL) {
wglDeleteContext(draw->platform->glrc);
if(platform->glrc != NULL) {
wglDeleteContext(platform->glrc);
}
if(draw->platform->window != NULL) {
DestroyWindow(draw->platform->window);
if(platform->window != NULL) {
DestroyWindow(platform->window);
}
free(draw->platform);
draw->platform = NULL;
gf_log_function(platform->engine, "Destroyed platform-dependent part of drawing driver", "");
free(platform);
}

View File

@ -0,0 +1,57 @@
/**
* @file gf_client.h
* @~english
* @brief Client interface
*/
#ifndef __GF_CLIENT_H__
#define __GF_CLIENT_H__
#include <gf_pre.h>
#include <gf_macro.h>
/* Type */
#include <gf_type/client.h>
/* Engine */
#include <gf_type/core.h>
/* Standard */
/**
* @~english
* @brief Initialize client interface
*/
GF_EXPORT void gf_client_begin(void);
/**
* @~english
* @brief Cleanup client interface
*/
GF_EXPORT void gf_client_end(void);
/**
* @~english
* @brief Create client interface
* @param engine Engine instance
* @param title Window title
* @return Client interface
*/
GF_EXPORT gf_client_t* gf_client_create(gf_engine_t* engine, const char* title);
/**
* @~english
* @brief Destroy client interface
* @param client Client interface
*/
GF_EXPORT void gf_client_destroy(gf_client_t* client);
/**
* @~english
* @brief Do client single step
* @param client Client interface
* @return `0` if successful, otherwise if failed
*/
GF_EXPORT int gf_client_step(gf_client_t* client);
#endif

View File

@ -47,14 +47,6 @@ GF_EXPORT gf_engine_t* gf_engine_create(const char* title, int nogui);
*/
GF_EXPORT void gf_engine_loop(gf_engine_t* engine);
/**
* @~english
* @brief Set user-drawing callback
* @param engine Engine instance
* @param func Callback
*/
GF_EXPORT void gf_engine_set_draw(gf_engine_t* engine, void (*func)(gf_draw_t*));
/**
* @~english
* @brief Destroy engine instance

View File

@ -62,14 +62,6 @@ GF_EXPORT void gf_draw_begin(void);
*/
GF_EXPORT void gf_draw_end(void);
/**
* @~english
* @brief Set user-drawing callback
* @param engine Engine instance
* @param func User-drawing callback
*/
GF_EXPORT void gf_draw_set_draw(gf_draw_t* engine, void (*func)(gf_draw_t*));
/**
* @~english
* @brief Do stuffs required on resizing window

View File

@ -18,22 +18,25 @@
#include <gf_type/draw.h>
#include <gf_type/texture.h>
#include <gf_type/graphic.h>
#include <gf_type/core.h>
/* Standard */
/**
* @~english
* @brief Initialize drawing driver
* @param engine Engine instance
* @param draw Drawing interface
* @return Drawing driver
*/
GF_EXPORT void gf_draw_driver_init(gf_draw_t* draw);
GF_EXPORT gf_draw_driver_t* gf_draw_driver_create(gf_engine_t* engine, gf_draw_t* draw);
/**
* @~english
* @brief Destroy drawing driver
* @param draw Drawing interface
* @param driver Drawing driver
*/
GF_EXPORT void gf_draw_driver_destroy(gf_draw_t* draw);
GF_EXPORT void gf_draw_driver_destroy(gf_draw_driver_t* driver);
/**
* @~english

View File

@ -16,22 +16,25 @@
/* Engine */
#include <gf_type/draw.h>
#include <gf_type/core.h>
/* Standard */
/**
* @~english
* @brief Create platform-dependent part of drawing driver
* @param engine Engine instance
* @param draw Drawing interface
* @return Platform-dependent part of drawing driver
*/
GF_EXPORT void gf_draw_platform_create(gf_draw_t* draw);
GF_EXPORT gf_draw_platform_t* gf_draw_platform_create(gf_engine_t* engine, gf_draw_t* draw);
/**
* @~english
* @brief Destroy platform-dependent part of drawing driver
* @param draw Drawing interface
* @param platform Platform-dependent part of drawing driver
*/
GF_EXPORT void gf_draw_platform_destroy(gf_draw_t* draw);
GF_EXPORT void gf_draw_platform_destroy(gf_draw_platform_t* platform);
/**
* @~english

View File

@ -15,6 +15,7 @@
/* Engine */
#include <gf_type/draw.h>
#include <gf_type/core.h>
/* Standard */
@ -39,11 +40,12 @@
/**
* @~english
* @brief Create GUI
* @param engine Engine instance
* @param draw Drawing interface
* @return GUI
* @note You should not have to call this - simply use gf_draw_t::gui
*/
GF_EXPORT gf_gui_t* gf_gui_create(gf_draw_t* draw);
GF_EXPORT gf_gui_t* gf_gui_create(gf_engine_t* engine, gf_draw_t* draw);
/**
* @~english

View File

@ -89,6 +89,22 @@
#define GF_EXPOSE_THREAD
#endif
#ifndef GF_EXPOSE_CLIENT
/**
* @~english
* @brief Expose client interface properties
*/
#define GF_EXPOSE_CLIENT
#endif
#ifndef GF_EXPOSE_SERVER
/**
* @~english
* @brief Expose server interface properties
*/
#define GF_EXPOSE_SERVER
#endif
#ifndef GF_EXPOSE_GRAPHIC
/**
* @~english

View File

@ -12,6 +12,7 @@
/* Type */
#include <gf_type/physics.h>
#include <gf_type/core.h>
/* Engine */
@ -32,9 +33,10 @@ GF_EXPORT void gf_physics_end(void);
/**
* @~english
* @brief Create physics interface
* @param engine Engine instance
* @return Physics interface
*/
GF_EXPORT gf_physics_t* gf_physics_create(void);
GF_EXPORT gf_physics_t* gf_physics_create(gf_engine_t* engine);
/**
* @~english

View File

@ -0,0 +1,48 @@
/**
* @file gf_server.h
* @~english
* @brief Client interface
*/
#ifndef __GF_SERVER_H__
#define __GF_SERVER_H__
#include <gf_pre.h>
#include <gf_macro.h>
/* Type */
#include <gf_type/server.h>
/* Engine */
#include <gf_type/core.h>
/* Standard */
/**
* @~english
* @brief Initialize server interface
*/
GF_EXPORT void gf_server_begin(void);
/**
* @~english
* @brief Cleanup server interface
*/
GF_EXPORT void gf_server_end(void);
/**
* @~english
* @brief Create server interface
* @param engine Engine instance
* @return Server interface
*/
GF_EXPORT gf_server_t* gf_server_create(gf_engine_t* engine);
/**
* @~english
* @brief Destroy server interface
* @param server Server interface
*/
GF_EXPORT void gf_server_destroy(gf_server_t* server);
#endif

View File

@ -20,14 +20,14 @@
/**
* @~english
* @brief Register texture
* @brief Create texture
* @param draw Drawing interface
* @param width Width of texture
* @param height Height of texture
* @param data Texture data
* @return Texture
*/
GF_EXPORT gf_texture_t* gf_texture_register(gf_draw_t* draw, int width, int height, unsigned char* data);
GF_EXPORT gf_texture_t* gf_texture_create(gf_draw_t* draw, int width, int height, unsigned char* data);
/**
* @~english

View File

@ -0,0 +1,30 @@
/**
* @file gf_type/client.h
* @~english
* @brief Type definitions related to client interface
*/
#ifndef __GF_TYPE_CLIENT_H__
#define __GF_TYPE_CLIENT_H__
#include <gf_pre.h>
#include <gf_macro.h>
#ifdef GF_EXPOSE_CLIENT
/* External library */
/* Engine */
#include <gf_type/core.h>
#include <gf_type/draw.h>
/* Standard */
GF_DECLARE_TYPE(client, {
gf_engine_t* engine;
gf_draw_t* draw;
});
#else
typedef void gf_client_t;
#endif
#endif

View File

@ -14,8 +14,8 @@
/* External library */
/* Engine */
#include <gf_type/physics.h>
#include <gf_type/draw.h>
#include <gf_type/server.h>
#include <gf_type/client.h>
/* Standard */
#include <stdio.h>
@ -25,13 +25,11 @@
* @~english
* @brief Engine instance
*
* @var gf_engine_t::physics
* @brief Physics interface
* @todo Create gf_server_t and move physics there
* @var gf_engine_t::server
* @brief Server interface
*
* @var gf_engine_t::draw
* @brief Drawing interface
* @todo Create gf_client_t and move draw there
* @var gf_engine_t::client
* @brief Client interface
*
* @var gf_engine_t::log
* @brief Log output
@ -40,9 +38,9 @@
* @warning Destroying engien instance **does not** `fclose` this
*/
GF_DECLARE_TYPE(engine, {
gf_physics_t* physics;
gf_draw_t* draw;
FILE* log;
gf_server_t* server;
gf_client_t* client;
FILE* log;
});
#else
typedef void gf_engine_t;

View File

@ -23,13 +23,14 @@
/* Standard */
GF_DECLARE_TYPE(draw, );
/**
* @struct gf_draw_t
* @~english
* @brief Drawing interface
*
* @var gf_draw_t::engine
* @brief Engine instance
*
* @var gf_draw_t::platform
* @brief Platform-dependent part of drawing driver
*
@ -78,11 +79,9 @@ GF_DECLARE_TYPE(draw, );
*
* @var gf_draw_t::camera
* @brief Camera location
*
* @var gf_draw_t::draw
* @brief User-drawing callback
*/
GF_DECLARE_TYPE(draw, {
gf_engine_t* engine;
gf_draw_platform_t* platform;
gf_draw_driver_t* driver;
gf_gui_t* gui;
@ -98,7 +97,6 @@ GF_DECLARE_TYPE(draw, {
gf_math_vector_t light;
gf_math_vector_t lookat;
gf_math_vector_t camera;
void (*draw)(gf_draw_t*);
});
#else
typedef void gf_draw_t;

View File

@ -17,15 +17,17 @@
#endif
/* Engine */
#include <gf_type/core.h>
/* Standard */
#if defined(DRV_OPENGL)
GF_DECLARE_TYPE(draw_driver, { int unused; });
GF_DECLARE_TYPE(draw_driver, { gf_engine_t* engine; });
GF_DECLARE_TYPE(draw_driver_texture, {
GLuint id;
int width;
int height;
gf_engine_t* engine;
GLuint id;
int width;
int height;
});
#else
/**

View File

@ -17,26 +17,32 @@
#endif
/* Engine */
#include <gf_type/core.h>
/* Standard */
#if defined(DRV_OPENGL)
#if defined(USE_GLX)
GF_DECLARE_TYPE(draw_platform, {
Display* display;
Window window;
GLXContext context;
Atom wm_delete_window;
gf_engine_t* engine;
Display* display;
Window window;
GLXContext context;
Atom wm_delete_window;
});
#elif defined(USE_WGL)
GF_DECLARE_TYPE(draw_platform, {
HINSTANCE instance;
HWND window;
HDC dc;
HGLRC glrc;
gf_engine_t* engine;
HINSTANCE instance;
HWND window;
HDC dc;
HGLRC glrc;
});
#elif defined(USE_GLFW)
GF_DECLARE_TYPE(draw_platform, { GLFWwindow* window; });
GF_DECLARE_TYPE(draw_platform, {
gf_engine_t* engine;
GLFWwindow* window;
});
#endif
#else
/**

View File

@ -21,6 +21,7 @@ typedef int gf_gui_id_t;
/* Engine */
#include <gf_type/draw.h>
#include <gf_type/core.h>
/* Standard */
@ -112,6 +113,7 @@ GF_DECLARE_TYPE(gui_component, {
* @brief Created components
*/
GF_DECLARE_TYPE(gui, {
gf_engine_t* engine;
gf_draw_t* draw;
gf_gui_component_t area[GF_GUI_MAX_COMPONENTS];
});

View File

@ -15,6 +15,7 @@
#include <ode/ode.h>
/* Engine */
#include <gf_type/core.h>
/* Standard */
@ -23,10 +24,16 @@
* @~english
* @brief Physics interface
*
* @var gf_physics_t::engine
* @brief Engine instance
*
* @var gf_physics_t::id
* @brief ODE's world ID
*/
GF_DECLARE_TYPE(physics, { dWorldID id; });
GF_DECLARE_TYPE(physics, {
gf_engine_t* engine;
dWorldID id;
});
#else
typedef void gf_physics_t;
#endif

View File

@ -0,0 +1,30 @@
/**
* @file gf_type/server.h
* @~english
* @brief Type definitions related to server interface
*/
#ifndef __GF_TYPE_SERVER_H__
#define __GF_TYPE_SERVER_H__
#include <gf_pre.h>
#include <gf_macro.h>
#ifdef GF_EXPOSE_SERVER
/* External library */
/* Engine */
#include <gf_type/core.h>
#include <gf_type/physics.h>
/* Standard */
GF_DECLARE_TYPE(server, {
gf_engine_t* engine;
gf_physics_t* physics;
});
#else
typedef void gf_server_t;
#endif
#endif

View File

@ -13,13 +13,6 @@
gf_engine_t* engine;
gf_gui_id_t button1 = -1;
void draw_frame(gf_draw_t* draw) {
if(button1 == -1) button1 = gf_gui_create_button(draw->gui, 10, 10, 100, 50, "Test");
gf_gui_render(draw->gui);
}
int main(int argc, char** argv) {
char title[64];
gf_version_t ver;
@ -32,7 +25,6 @@ int main(int argc, char** argv) {
gf_engine_end();
return 1;
}
gf_engine_set_draw(engine, draw_frame);
gf_engine_loop(engine);
gf_engine_destroy(engine);
gf_engine_end();