259 lines
6.5 KiB
C
259 lines
6.5 KiB
C
#include "pakman.h"
|
|
|
|
static GHashTable *paks;
|
|
|
|
void
|
|
pakman_init ()
|
|
{
|
|
paks = g_hash_table_new (g_str_hash, g_str_equal);
|
|
}
|
|
|
|
static SCM
|
|
_scm_get_program (SCM pak_scm, SCM key_scm)
|
|
{
|
|
const char *pak = scm_to_utf8_string (pak_scm);
|
|
const char *key = scm_to_utf8_string (key_scm);
|
|
return scm_from_int (pakman_pak_program (pak, key));
|
|
}
|
|
|
|
static SCM
|
|
_scm_get_texture (SCM pak_scm, SCM key_scm)
|
|
{
|
|
const char *pak = scm_to_utf8_string (pak_scm);
|
|
const char *key = scm_to_utf8_string (key_scm);
|
|
return scm_from_int (pakman_pak_texture (pak, key));
|
|
}
|
|
|
|
static SCM
|
|
_scm_get_uidef (SCM pak_scm, SCM key_scm)
|
|
{
|
|
const char *pak = scm_to_utf8_string (pak_scm);
|
|
const char *key = scm_to_utf8_string (key_scm);
|
|
return scm_from_pointer (pakman_pak_uidef (pak, key), NULL);
|
|
}
|
|
|
|
void
|
|
pakman_guile_register ()
|
|
{
|
|
scm_c_define_gsubr ("pak-program", 2, 0, 0, _scm_get_program);
|
|
scm_c_define_gsubr ("pak-texture", 2, 0, 0, _scm_get_texture);
|
|
scm_c_define_gsubr ("pak-uidef", 2, 0, 0, _scm_get_uidef);
|
|
}
|
|
|
|
unsigned int
|
|
_pm_load_program (const char *v_path, const char *f_path)
|
|
{
|
|
char *v_src;
|
|
|
|
if (!g_file_get_contents (v_path, &v_src, NULL, NULL))
|
|
{
|
|
g_warning ("File `%s' does not exist.", v_path);
|
|
}
|
|
|
|
char *f_src;
|
|
|
|
if (!g_file_get_contents (f_path, &f_src, NULL, NULL))
|
|
{
|
|
g_warning ("File `%s' does not exist.", f_path);
|
|
}
|
|
|
|
unsigned int program = program_create (v_src, f_src);
|
|
g_free (v_src);
|
|
g_free (f_src);
|
|
return program;
|
|
}
|
|
|
|
unsigned int
|
|
_pm_load_texture (const char *path)
|
|
{
|
|
SDL_Surface *surface = IMG_Load (path);
|
|
|
|
if (surface == NULL)
|
|
{
|
|
g_warning ("Failed to load texture from path %s: %s", path, SDL_GetError ());
|
|
return 0;
|
|
}
|
|
|
|
unsigned int texture = texture_create (surface->w, surface->h, surface->pixels);
|
|
return texture;
|
|
}
|
|
|
|
void
|
|
pakman_load_pak (const char *path)
|
|
{
|
|
GError *err = NULL;
|
|
GKeyFile *key_file = g_key_file_new ();
|
|
|
|
char *manifest_path = g_build_filename (path, "manifest.cfg", NULL);
|
|
|
|
g_debug ("Loading .pak mainfest from %s...", manifest_path);
|
|
|
|
if (!g_key_file_load_from_file (key_file, manifest_path, G_KEY_FILE_NONE, &err))
|
|
{
|
|
g_error ("Error loading .pak manifest.cfg: %s", err->message);
|
|
return;
|
|
}
|
|
|
|
PakFile *pak = g_new0 (PakFile, 1);
|
|
pak->programs = g_hash_table_new (g_str_hash, g_str_equal);
|
|
pak->textures = g_hash_table_new (g_str_hash, g_str_equal);
|
|
pak->uidefs = g_hash_table_new (g_str_hash, g_str_equal);
|
|
|
|
char **programs = g_key_file_get_keys (key_file, "Programs", NULL, &err);
|
|
|
|
for (char **p = programs; *p != NULL; p++)
|
|
{
|
|
size_t n_shaders;
|
|
char **shaders = g_key_file_get_string_list (key_file, "Programs", *p, &n_shaders, &err);
|
|
|
|
if (n_shaders == 2)
|
|
{
|
|
g_hash_table_insert (pak->programs, g_strdup (*p), GUINT_TO_POINTER (_pm_load_program (shaders[0], shaders[1])));
|
|
}
|
|
else
|
|
{
|
|
g_warning ("Program %s does not have 2 shaders.", *p);
|
|
}
|
|
}
|
|
|
|
char **textures = g_key_file_get_keys (key_file, "Textures", NULL, &err);
|
|
|
|
for (char **t = textures; *t != NULL; t++)
|
|
{
|
|
char *texture = g_key_file_get_string (key_file, "Textures", *t, &err);
|
|
g_hash_table_insert (pak->textures, g_strdup (*t), GUINT_TO_POINTER (_pm_load_texture (texture)));
|
|
}
|
|
|
|
char **uidefs = g_key_file_get_keys (key_file, "UIDefs", NULL, &err);
|
|
|
|
for (char **u = uidefs; *u != NULL; u++)
|
|
{
|
|
char *uidef_path = g_key_file_get_string (key_file, "UIDefs", *u, &err);
|
|
SCM uidef_scm = scm_c_primitive_load (uidef_path);
|
|
Widget *uidef = (Widget *) scm_to_pointer (uidef_scm);
|
|
g_hash_table_insert (pak->uidefs, g_strdup (*u), uidef);
|
|
}
|
|
|
|
char *id = g_key_file_get_string (key_file, "Metadata", "id", &err);
|
|
g_hash_table_insert (paks, g_strdup (id), pak);
|
|
|
|
/* Some hacks. */
|
|
program_use (pakman_pak_program (id, "chunk"));
|
|
program_set_int_array (pakman_pak_program (id, "chunk"), "materials", 5, (int[5]) { 0, 1, 2, 3, 4 });
|
|
program_use (pakman_pak_program (id, "uiwidget"));
|
|
program_set_int (pakman_pak_program (id, "uiwidget"), "background_image", 0);
|
|
program_set_int (pakman_pak_program (id, "uiwidget"), "icons", 1);
|
|
|
|
g_key_file_free (key_file);
|
|
}
|
|
|
|
unsigned int
|
|
pakman_pak_program (const char *pak, const char *program)
|
|
{
|
|
PakFile *p = g_hash_table_lookup (paks, pak);
|
|
|
|
if (!p)
|
|
{
|
|
g_warning ("Pak `%s' not found.", pak);
|
|
return 0;
|
|
}
|
|
|
|
gpointer value = g_hash_table_lookup (p->programs, program);
|
|
|
|
if (!value)
|
|
{
|
|
g_warning ("Program `%s' not found in pak `%s'.", program, pak);
|
|
return 0;
|
|
}
|
|
|
|
return GPOINTER_TO_UINT (value);
|
|
}
|
|
|
|
unsigned int
|
|
pakman_pak_texture (const char *pak, const char *texture)
|
|
{
|
|
PakFile *p = g_hash_table_lookup (paks, pak);
|
|
|
|
if (!p)
|
|
{
|
|
g_warning ("Pak `%s' not found.", pak);
|
|
return 0;
|
|
}
|
|
|
|
gpointer value = g_hash_table_lookup (p->textures, texture);
|
|
|
|
if (!value)
|
|
{
|
|
g_warning ("Texture `%s' not found in pak `%s'.", texture, pak);
|
|
return 0;
|
|
}
|
|
|
|
return GPOINTER_TO_UINT (value);
|
|
}
|
|
|
|
Widget *
|
|
pakman_pak_uidef (const char *pak, const char *uidef)
|
|
{
|
|
PakFile *p = g_hash_table_lookup (paks, pak);
|
|
|
|
if (!p)
|
|
{
|
|
g_warning ("Pak `%s' not found.", pak);
|
|
return NULL;
|
|
}
|
|
|
|
Widget *value = g_hash_table_lookup (p->uidefs, uidef);
|
|
|
|
if (!value)
|
|
{
|
|
g_warning ("Uidef `%s' not found in pak `%s'.", uidef, pak);
|
|
return NULL;
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
void
|
|
pakman_all_paks_set_mat4 (const char *uniform, mat4 value)
|
|
{
|
|
GHashTableIter pack_iter;
|
|
PakFile *pak;
|
|
|
|
g_hash_table_iter_init (&pack_iter, paks);
|
|
while (g_hash_table_iter_next (&pack_iter, NULL, (void **) &pak))
|
|
{
|
|
GHashTableIter program_iter;
|
|
void *program_value;
|
|
|
|
g_hash_table_iter_init (&program_iter, pak->programs);
|
|
while (g_hash_table_iter_next (&program_iter, NULL, (void **) &program_value))
|
|
{
|
|
unsigned int program = GPOINTER_TO_UINT (program_value);
|
|
program_use (program);
|
|
program_set_mat4 (program, uniform, value);
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
pakman_all_paks_set_float (const char *uniform, float value)
|
|
{
|
|
GHashTableIter pack_iter;
|
|
PakFile *pak;
|
|
|
|
g_hash_table_iter_init (&pack_iter, paks);
|
|
while (g_hash_table_iter_next (&pack_iter, NULL, (void **) &pak))
|
|
{
|
|
GHashTableIter program_iter;
|
|
void *program_value;
|
|
|
|
g_hash_table_iter_init (&program_iter, pak->programs);
|
|
while (g_hash_table_iter_next (&program_iter, NULL, (void **) &program_value))
|
|
{
|
|
unsigned int program = GPOINTER_TO_UINT (program_value);
|
|
program_use (program);
|
|
program_set_float (program, uniform, value);
|
|
}
|
|
}
|
|
}
|