summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKyle K <kylek389@gmail.com>2011-07-18 11:03:31 -0500
committerKamil Kaminski <kamilkss@gmail.com>2011-07-18 11:03:31 -0500
commita780d11c48d0901a9e019687ce127a1d4f4672fb (patch)
tree86928872ba8857b9881b02544d048809183f28eb
parenta40d0cdbb0dff7cf2b65a18be7b7085f0eca3408 (diff)
downloadGLPyramid-a780d11c48d0901a9e019687ce127a1d4f4672fb.tar.gz
GLPyramid-a780d11c48d0901a9e019687ce127a1d4f4672fb.tar.bz2
GLPyramid-a780d11c48d0901a9e019687ce127a1d4f4672fb.zip
sdl: implement loading config file using Lua
-rw-r--r--sdl/Makefile13
-rw-r--r--sdl/config.lua14
-rw-r--r--sdl/luatools.c163
-rw-r--r--sdl/luatools.h28
-rw-r--r--sdl/mingw324
-rw-r--r--sdl/platform.c112
-rw-r--r--sdl/platform.h35
-rw-r--r--sdl/pyramid.c91
-rw-r--r--sdl/sdltools.c6
-rw-r--r--sdl/sdltools.h2
-rw-r--r--sdl/window.c2
11 files changed, 376 insertions, 94 deletions
diff --git a/sdl/Makefile b/sdl/Makefile
index 269c69e..d6df1f7 100644
--- a/sdl/Makefile
+++ b/sdl/Makefile
@@ -1,6 +1,6 @@
BIN = pyramid
SRC = pyramid.c math3d.c gltools.c glframe.c shader.c platform.c window.c \
- gldraw.c sdltools.c
+ gldraw.c sdltools.c luatools.c
CC = gcc
CFLAGS = -Wall -std=gnu99
DBGFLAGS = -g -O0
@@ -9,7 +9,7 @@ ifdef DEBUG
else
CFLAGS += -O2 -march=native -mtune=native
endif
-LDFLAGS = -lGLEW -lGL -lGLU -lm -lglut
+LDFLAGS = -lGLEW -lGL -lGLU -lm -lglut -llua
SDL_CFLAGS := $(shell sdl-config --cflags)
SDL_LDFLAGS := $(shell sdl-config --libs)
SDL_image_CFLAGS := $(shell pkg-config --cflags SDL_image)
@@ -21,7 +21,7 @@ OBJ_FILES = $(addprefix $(OBJ_DIR)/, $(addsuffix .o, $(subst .c,,$(SRC))))
$(BIN): $(OBJ_DIR) $(OBJ_FILES)
$(CC) $(LDFLAGS) $(SDL_LDFLAGS) $(SDL_image_LDFLAGS) $(OBJ_FILES) -o $@
-$(OBJ_DIR)/pyramid.o: $(OBJ_DIR)/%.o: %.c math3d.h gltools.h glframe.h platform.h sdltools.h
+$(OBJ_DIR)/pyramid.o: $(OBJ_DIR)/%.o: %.c gldraw.h glframe.h gltools.h luatools.h math3d.h platform.h sdltools.h window.h
$(CC) -c $(CFLAGS) $(SDL_CFLAGS) $(SDL_image_CFLAGS) $< -o $@
$(OBJ_DIR)/math3d.o: $(OBJ_DIR)/%.o: %.c %.h
@@ -30,7 +30,7 @@ $(OBJ_DIR)/math3d.o: $(OBJ_DIR)/%.o: %.c %.h
$(OBJ_DIR)/gltools.o: $(OBJ_DIR)/%.o: %.c %.h
$(CC) -c $(CFLAGS) $< -o $@
-$(OBJ_DIR)/glframe.o: $(OBJ_DIR)/%.o: %.c %.h math3d.h
+$(OBJ_DIR)/glframe.o: $(OBJ_DIR)/%.o: %.c %.h math3d.h glframe.h luatools.h gldraw.h gltools.h luatools.h sdltools.h
$(CC) -c $(CFLAGS) $< -o $@
$(OBJ_DIR)/shader.o: $(OBJ_DIR)/%.o: %.c %.h
@@ -45,7 +45,10 @@ $(OBJ_DIR)/window.o: $(OBJ_DIR)/%.o: %.c %.h
$(OBJ_DIR)/gldraw.o: $(OBJ_DIR)/%.o: %.c %.h math3d.h
$(CC) -c $(CFLAGS) $< -o $@
-$(OBJ_DIR)/sdltools.o: $(OBJ_DIR)/%.o: %.c %.h math3d.h
+$(OBJ_DIR)/sdltools.o: $(OBJ_DIR)/%.o: %.c %.h math3d.h glframe.h
+ $(CC) -c $(CFLAGS) $< -o $@
+
+$(OBJ_DIR)/luatools.o: $(OBJ_DIR)/%.o: %.c %.h math3d.h
$(CC) -c $(CFLAGS) $< -o $@
$(OBJ_DIR):
diff --git a/sdl/config.lua b/sdl/config.lua
new file mode 100644
index 0000000..34a7920
--- /dev/null
+++ b/sdl/config.lua
@@ -0,0 +1,14 @@
+platform =
+{
+ name = "Textured Pyramid",
+ icon = "tux.png",
+ xres = 640,
+ yres = 480,
+ bpp = 32,
+ af = 8,
+ fovy = 40.0,
+ znear = 1.0,
+ zfar = 40.0,
+ maxfps = 60
+}
+
diff --git a/sdl/luatools.c b/sdl/luatools.c
new file mode 100644
index 0000000..5116df1
--- /dev/null
+++ b/sdl/luatools.c
@@ -0,0 +1,163 @@
+/* luatools.c
+ *
+ * Lua Tools
+ *
+ *
+ */
+
+#include <lauxlib.h>
+#include <lualib.h>
+#include <stdio.h>
+#include <string.h>
+#include "luatools.h"
+
+const char *luaGetFieldString(lua_State *L, const char *key)
+{
+ if (!L || !key)
+ return NULL;
+
+ const char *ret = NULL;
+
+ /* push the key string onto stack */
+ lua_pushstring(L, key);
+
+ lua_gettable(L, -2);
+ if (!lua_isstring(L, -1))
+ {
+ fprintf(stderr, "Lua: \"%s\" field within the table is not a string\n", key);
+ lua_pop(L, 1);
+
+ return ret;
+ }
+
+ ret = lua_tostring(L, -1);
+ lua_pop(L, 1);
+
+ return ret;
+}
+
+double luaGetFieldNumber(lua_State *L, const char *key)
+{
+ if (!L || !key)
+ return -1.0;
+
+ double ret = -1.0;
+
+ /* push the key string onto stack */
+ lua_pushstring(L, key);
+
+ /* remember, -1 points to top of the stack, our table should a second
+ * item from the top, this call effectively accesses t[key] and
+ * pushes that value on the stack */
+ lua_gettable(L, -2);
+ if (!lua_isnumber(L, -1))
+ {
+ fprintf(stderr, "Lua: \"%s\" field within the table is NaN\n", key);
+ lua_pop(L, 1);
+
+ return ret;
+ }
+
+ /* finally retrieve our value */
+ ret = lua_tonumber(L, -1);
+
+ /* value is no longer needed, pop it */
+ lua_pop(L, 1);
+
+ return ret;
+}
+
+int luaLoadConfig(lua_State *L, const char *fname)
+{
+ if (!L || !fname)
+ return -1;
+
+ int status;
+
+ /* load the file containing the config */
+ /* call a function, what function? dry run the script? */
+ status = (luaL_loadfile(L, fname) || lua_pcall(L, 0, 0, 0));
+ if (status)
+ {
+ fprintf(stderr, "Lua: %s\n", lua_tostring(L, -1));
+ return -1;
+ }
+
+ return 0;
+}
+
+int luaFillTablePlatform(lua_State *L, struct luat_table_platform *p)
+{
+ if (!L || !p)
+ return -1;
+
+ double ret;
+ const char *ret_str = NULL;
+
+ /* pushes the table on the stack */
+ lua_getglobal(L, "platform");
+
+ if (!lua_istable(L, -1))
+ {
+ fprintf(stderr, "Lua: failed to parse \"platform\" table\n");
+ lua_pop(L, 1);
+ return -1;
+ }
+
+ if ((ret_str = luaGetFieldString(L, "name")) != NULL)
+ p->name = ret_str;
+
+ if ((ret_str = luaGetFieldString(L, "icon")) != NULL)
+ p->icon = ret_str;
+
+ if ((ret = luaGetFieldNumber(L, "xres")) != -1.0)
+ p->xres = (unsigned int) ret;
+
+ if ((ret = luaGetFieldNumber(L, "yres")) != -1.0)
+ p->yres = (unsigned int) ret;
+
+ if ((ret = luaGetFieldNumber(L, "bpp")) != -1.0)
+ p->bpp = (unsigned int) ret;
+
+ if ((ret = luaGetFieldNumber(L, "af")) != -1.0)
+ p->af = (unsigned int) ret;
+
+ if ((ret = luaGetFieldNumber(L, "fovy")) != -1.0)
+ p->fovy = (float) ret;
+
+ if ((ret = luaGetFieldNumber(L, "znear")) != -1.0)
+ p->znear = (float) ret;
+
+ if ((ret = luaGetFieldNumber(L, "zfar")) != -1.0)
+ p->zfar = (float) ret;
+
+ if ((ret = luaGetFieldNumber(L, "maxfps")) != -1.0)
+ p->maxfps = (unsigned int) ret;
+
+ /* pop the table */
+ lua_pop(L, 1);
+
+ return 0;
+}
+
+void luaPrintTablePlatform(struct luat_table_platform *p)
+{
+ if (!p)
+ return;
+
+ printf("-- Lua platform config file --\n"
+ " name : %s\n"
+ " icon : %s\n"
+ " xres : %u\n"
+ " yres : %u\n"
+ " bpp : %u\n"
+ " af : %u\n"
+ " fovy : %f\n"
+ " znear : %f\n"
+ " zfar : %f\n"
+ " maxfps: %u\n",
+ p->name, p->icon, p->xres, p->yres, p->bpp, p->af,
+ p->fovy, p->znear, p->zfar, p->maxfps);
+ puts("");
+}
+
diff --git a/sdl/luatools.h b/sdl/luatools.h
new file mode 100644
index 0000000..e05cb6b
--- /dev/null
+++ b/sdl/luatools.h
@@ -0,0 +1,28 @@
+#ifndef _LUATOOLS_H_
+#define _LUATOOLS_H_
+
+#include <lua.h>
+
+/* lua table to c struct converter would be very useful */
+struct luat_table_platform
+{
+ const char *name;
+ const char *icon;
+ unsigned int xres;
+ unsigned int yres;
+ unsigned int bpp;
+ unsigned int af;
+ float fovy;
+ float znear;
+ float zfar;
+ unsigned int maxfps;
+};
+
+const char *luaGetFieldString(lua_State *L, const char *);
+double luaGetFieldNumber(lua_State *, const char *);
+int luaLoadConfig(lua_State *, const char *);
+int luaFillTablePlatform(lua_State *, struct luat_table_platform *);
+void luaPrintTablePlatform(struct luat_table_platform *);
+
+#endif
+
diff --git a/sdl/mingw32 b/sdl/mingw32
index 591f975..1607875 100644
--- a/sdl/mingw32
+++ b/sdl/mingw32
@@ -1,6 +1,6 @@
BIN = pyramid
SRC = pyramid.c math3d.c gltools.c glframe.c shader.c platform.c window.c \
- gldraw.c sdltools.c
+ gldraw.c sdltools.c luatools.c
CC = gcc
CFLAGS = -Wall -std=c99 -MD
DBGFLAGS = -g -O0
@@ -9,7 +9,7 @@ ifdef DEBUG
else
CFLAGS += -O2 -march=native -mtune=native
endif
-LDFLAGS = -lglew32 -lopengl32 -lglu32 -lm -lfreeglut -lmingw32 -lsdlmain -lsdl -lsdl_image -mwindows
+LDFLAGS = -lglew32 -lopengl32 -lglu32 -lm -lfreeglut -lmingw32 -lsdlmain -lsdl -lsdl_image -mwindows -llua
OBJ_DIR = obj
DEPS_DIR = obj
diff --git a/sdl/platform.c b/sdl/platform.c
index aba5789..a44bfd4 100644
--- a/sdl/platform.c
+++ b/sdl/platform.c
@@ -6,11 +6,17 @@
*
*/
+#include <lauxlib.h>
+#include <lualib.h>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <GL/glew.h>
+#include <string.h>
+#include "gldraw.h"
#include "gltools.h"
+#include "luatools.h"
#include "platform.h"
+#include "sdltools.h"
/* few light arrays */
const GLfloat fNoLight[] = { 0.0f, 0.0f, 0.0f, 1.0f };
@@ -23,13 +29,109 @@ const GLfloat fBrightLight[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat lightPos[] = { -10.f, 5.0f, 5.0f, 1.0f };
/* variables that should be already defined and declared for us by main program */
-extern const unsigned int xres_w;
-extern const unsigned int yres_w;
-extern const unsigned int bpp_w;
-extern const unsigned int af_w;
-extern const unsigned int sdl_video_flags;
+extern unsigned int xres_w;
+extern unsigned int yres_w;
+extern unsigned int bpp_w;
+extern unsigned int af_w;
extern const char *window_caption;
extern const char *window_icon_path;
+extern const unsigned int sdl_video_flags;
+extern unsigned int maxfps_w;
+
+void platform_init(struct platform *p)
+{
+ memset(p, 0, sizeof(struct platform));
+
+ /* Lua */
+ /* create new lua state */
+ p->L = luaL_newstate();
+
+ /* load lua libraries */
+ luaL_openlibs(p->L);
+
+ /* ToDo: how would you make platform more generic? */
+ /* note, this should be already zero'ed out */
+ memset(&p->config_table, 0, sizeof(p->config_table));
+
+ /* initialize SDL, GLEW, and OpenGL */
+ load_config(p);
+ p->screen = setup_sdl();
+ setup_glew();
+ setup_opengl();
+
+ /* set the camera to <0,0,0> */
+ glframe_reset(&p->camera);
+ p->textures[0] = gltLoadTGATexture("stone.tga");
+ p->textures[1] = gltLoadTGATexture("grass.tga");
+
+ /* display list, precompile commands */
+ p->ground_list = glGenLists(2);
+ p->triangle_list = p->ground_list + 1;
+
+ /* a triangle with a texture */
+ glNewList(p->triangle_list, GL_COMPILE);
+ glBindTexture(GL_TEXTURE_2D, p->textures[0]);
+ /* glBindTexture(GL_TEXTURE_2D, p->textures[1]); */
+ glColor3f(1.0f, 1.0f, 1.0f);
+ glDrawTriangle();
+ glEndList();
+
+ /* a ground drawn using magneta lines */
+ glNewList(p->ground_list, GL_COMPILE);
+ glColor3ub(255, 0, 255);
+ glDrawGround();
+ glEndList();
+
+ /* add a simple timer / callback function */
+ p->timer_id = SDL_AddTimer(5000, sdlTimerCallback, &(p->camera));
+
+ /* apply a custom cursor */
+ p->my_cursor = sdlInitCursor(arrow);
+ SDL_SetCursor(p->my_cursor);
+}
+
+void platform_destroy(struct platform *p)
+{
+ glDeleteTextures(2, p->textures);
+ glDeleteLists(p->ground_list, 2);
+
+ SDL_FreeSurface(p->screen);
+
+ lua_close(p->L);
+}
+
+/* load Lua config file from the disk */
+void load_config(struct platform *p)
+{
+ if (luaLoadConfig(p->L, "config.lua") ||
+ luaFillTablePlatform(p->L, &p->config_table) != -1)
+ {
+ /* print was was loaded from config.lua to stdout */
+ luaPrintTablePlatform(&p->config_table);
+
+ /* override any globals that config.lua redefines */
+ if (p->config_table.xres)
+ xres_w = p->config_table.xres;
+
+ if (p->config_table.yres)
+ yres_w = p->config_table.yres;
+
+ if (p->config_table.bpp)
+ bpp_w = p->config_table.bpp;
+
+ if (p->config_table.af)
+ af_w = p->config_table.af;
+
+ if (p->config_table.name)
+ window_caption = p->config_table.name;
+
+ if (p->config_table.icon)
+ window_icon_path = p->config_table.icon;
+
+ if (p->config_table.maxfps)
+ maxfps_w = p->config_table.maxfps;
+ }
+}
void setup_opengl(void)
{
diff --git a/sdl/platform.h b/sdl/platform.h
index 09028d1..dc34788 100644
--- a/sdl/platform.h
+++ b/sdl/platform.h
@@ -1,6 +1,38 @@
#ifndef _PLATFORM_H_
#define _PLATFORM_H_
+#include <SDL/SDL.h>
+#include <SDL/SDL_image.h>
+#include <GL/glew.h>
+#include "glframe.h"
+#include "luatools.h"
+
+/* platform struct */
+struct platform
+{
+ GLFrame camera;
+
+ /* display lists identifiers */
+ GLuint ground_list;
+ GLuint triangle_list;
+
+ /* pyramid texture handle */
+ GLuint textures[2];
+
+ GLfloat xrot;
+ GLfloat yrot;
+
+ /* SDL surface, our screen */
+ SDL_Surface *screen;
+
+ SDL_TimerID timer_id;
+ SDL_Cursor *my_cursor;
+
+ /* Lua */
+ lua_State *L;
+ struct luat_table_platform config_table;
+};
+
extern const GLfloat fNoLight[];
extern const GLfloat fLowLight[];
extern const GLfloat fShinyLight[];
@@ -8,6 +40,9 @@ extern const GLfloat fBrightLight[];
extern const GLfloat lightPos[];
/* function prototypes */
+void platform_init(struct platform *);
+void platform_destroy(struct platform *);
+void load_config(struct platform *);
void setup_opengl(void);
SDL_Surface *setup_sdl_video(int, int, int, unsigned int);
SDL_Surface *setup_sdl(void);
diff --git a/sdl/pyramid.c b/sdl/pyramid.c
index bc0fd7a..1260dff 100644
--- a/sdl/pyramid.c
+++ b/sdl/pyramid.c
@@ -14,6 +14,8 @@
*
* it might be time to split the code, and make a shader version...
*
+ * ToDo: on linux, update the makefile dependencies, and check out lua-config
+ *
*/
#include <SDL/SDL.h>
@@ -32,41 +34,21 @@
/* function prototypes */
static void keys(SDL_keysym *, const unsigned int *, const int);
static void process_events(void);
-static void platform_init(void);
-static void platform_destroy(void);
static void render(void);
-/* global */
+/* globals */
+struct platform p;
+
+/* sane defaults, these can be overwritten by config.lua */
int program_running = 1;
-const unsigned int xres_w = 640;
-const unsigned int yres_w = 480;
-const unsigned int bpp_w = 32;
-const unsigned int af_w = 8;
+unsigned int xres_w = 640;
+unsigned int yres_w = 480;
+unsigned int bpp_w = 32;
+unsigned int af_w = 8;
const char *window_caption = "Textured Pyramid";
const char *window_icon_path = "tux.png";
const unsigned int sdl_video_flags = SDL_OPENGL | SDL_RESIZABLE;
-
-/* platform struct */
-static struct
-{
- GLFrame camera;
-
- /* display lists identifiers */
- GLuint ground_list;
- GLuint triangle_list;
-
- /* pyramid texture handle */
- GLuint textures[2];
-
- GLfloat xrot;
- GLfloat yrot;
-
- /* SDL surface, our screen */
- SDL_Surface *screen;
-
- SDL_TimerID timer_id;
- SDL_Cursor *my_cursor;
-} p;
+unsigned int maxfps_w = 60;
static void keys(SDL_keysym *keysym, const unsigned int *keys_held, const int flag)
{
@@ -163,49 +145,6 @@ static void process_events(void)
flag = !flag;
}
-static void platform_init(void)
-{
- memset(&p, 0, sizeof(p));
-
- /* set the camera to <0,0,0> */
- glframe_reset(&p.camera);
- p.textures[0] = gltLoadTGATexture("stone.tga");
- p.textures[1] = gltLoadTGATexture("grass.tga");
-
- /* display list, precompile commands */
- p.ground_list = glGenLists(2);
- p.triangle_list = p.ground_list + 1;
-
- /* a triangle with a texture */
- glNewList(p.triangle_list, GL_COMPILE);
- glBindTexture(GL_TEXTURE_2D, p.textures[0]);
- /* glBindTexture(GL_TEXTURE_2D, p.textures[1]); */
- glColor3f(1.0f, 1.0f, 1.0f);
- glDrawTriangle();
- glEndList();
-
- /* a ground drawn using magneta lines */
- glNewList(p.ground_list, GL_COMPILE);
- glColor3ub(255, 0, 255);
- glDrawGround();
- glEndList();
-
- /* add a simple timer / callback function */
- p.timer_id = SDL_AddTimer(5000, sdlTimerCallback, &(p.camera));
-
- /* apply a custom cursor */
- p.my_cursor = sdlInitCursor(arrow);
- SDL_SetCursor(p.my_cursor);
-}
-
-static void platform_destroy(void)
-{
- glDeleteTextures(2, p.textures);
- glDeleteLists(p.ground_list, 2);
-
- SDL_FreeSurface(p.screen);
-}
-
static void render(void)
{
/* clear the window with current clearing color */
@@ -243,10 +182,8 @@ static void render(void)
int main(int argc, char **argv)
{
- p.screen = setup_sdl();
- setup_glew();
- setup_opengl();
- platform_init();
+ platform_init(&p);
+
gltErrorCheck();
gltOpenGLInfo();
@@ -261,7 +198,7 @@ int main(int argc, char **argv)
sdlFrameControl(startclock);
}
- platform_destroy();
+ platform_destroy(&p);
puts("bye!");
return 0;
diff --git a/sdl/sdltools.c b/sdl/sdltools.c
index c98a968..aea91bb 100644
--- a/sdl/sdltools.c
+++ b/sdl/sdltools.c
@@ -12,6 +12,8 @@
#include "math3d.h"
#include "glframe.h"
+extern unsigned int maxfps_w;
+
/* creates a new mouse cursor from an XPM */
const char *arrow[] = {
/* width height num_colors chars_per_pixel */
@@ -59,8 +61,8 @@ const char *arrow[] = {
inline void sdlFrameControl(const unsigned int startclock)
{
unsigned int deltaclock = SDL_GetTicks() - startclock;
- if (deltaclock < 1000 / FRAMES_PER_SECOND)
- SDL_Delay((1000 / FRAMES_PER_SECOND) - deltaclock);
+ if (deltaclock < 1000 / maxfps_w)
+ SDL_Delay((1000 / maxfps_w) - deltaclock);
#ifdef STAT_FPS
char buffer[30] = { 0 };
diff --git a/sdl/sdltools.h b/sdl/sdltools.h
index 63478ec..852096f 100644
--- a/sdl/sdltools.h
+++ b/sdl/sdltools.h
@@ -1,8 +1,6 @@
#ifndef _SDL_TOOLS_
#define _SDL_TOOLS_
-#define FRAMES_PER_SECOND 60
-
extern const char *arrow[];
/* function prototypes */
diff --git a/sdl/window.c b/sdl/window.c
index a96eef6..50bc72d 100644
--- a/sdl/window.c
+++ b/sdl/window.c
@@ -10,7 +10,7 @@
#include <GL/glew.h>
#include "window.h"
-extern const unsigned int bpp_w;
+extern unsigned int bpp_w;
extern const unsigned int sdl_video_flags;
void window_resize(int w, int h)