Skip to content

Commit

Permalink
Loading SDL with dlopen
Browse files Browse the repository at this point in the history
Loading the library at runtime, instead of utilizing the static
linker/ld-linux.so is way smaller.
  • Loading branch information
lnqs committed Oct 30, 2013
1 parent 7a2e3d7 commit fb480a6
Show file tree
Hide file tree
Showing 6 changed files with 196 additions and 62 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ NASM = nasm
STRIP = sstrip -z
SHADER_MINIFIER = shader_minifier.exe
CFLAGS = -m32 -std=c99 -Wall -Werror -ggdb -Oz -ffast-math -fomit-frame-pointer -march=i686 $(shell pkg-config --cflags sdl) $(shell pkg-config --cflags gl)
LDFLAGS = -melf_i386 -dynamic-linker /lib/ld-linux.so.2 $(shell pkg-config --libs sdl)
LDFLAGS = -melf_i386 -dynamic-linker /lib/ld-linux.so.2 -ldl
NASMFLAGS = -f elf

SOURCES = $(wildcard *.c)
Expand Down
119 changes: 86 additions & 33 deletions gl_functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,46 +3,99 @@

#include <GL/gl.h>
#include <SDL.h>
#include "sdl_functions.h"

static GLAPI void GLAPIENTRY (*glMatrixMode_)(GLenum);
static GLAPI void GLAPIENTRY (*glOrtho_)(GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble);
#define gl_call(name, type) ((type)gl_functions[name ## _i])

static GLAPI void GLAPIENTRY (*glBegin_)(GLenum);
static GLAPI void GLAPIENTRY (*glEnd_)();
static GLAPI void GLAPIENTRY (*glVertex3f_)(GLfloat, GLfloat, GLfloat);
#define glMatrixMode_fn \
gl_call(glMatrixMode, void GLAPIENTRY (*)(GLenum))

static GLAPI GLuint GLAPIENTRY (*glCreateShader_)(GLenum);
static GLAPI void GLAPIENTRY (*glShaderSource_)(GLuint, GLsizei count, const GLchar**, const GLint*);
static GLAPI void GLAPIENTRY (*glCompileShader_)(GLuint);
static GLAPI void GLAPIENTRY (*glAttachShader_)(GLuint, GLuint);
static GLAPI GLuint GLAPIENTRY (*glCreateProgram_)();
static GLAPI void GLAPIENTRY (*glLinkProgram_)(GLuint);
static GLAPI void GLAPIENTRY (*glUseProgram_)(GLuint);
#define glOrtho_fn \
gl_call(glOrtho, void GLAPIENTRY (*)(GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble))

static GLAPI GLint GLAPIENTRY (*glGetUniformLocation_)(GLuint, const GLchar*);
static GLAPI void GLAPIENTRY (*glUniform3fv_)(GLint, GLsizei, const GLfloat*);
static GLAPI void GLAPIENTRY (*glUniformMatrix3fv_)(GLint, GLsizei, GLboolean, const GLfloat*);
#define glBegin_fn \
gl_call(glBegin, void GLAPIENTRY (*)(GLenum))

#define glEnd_fn \
gl_call(glEnd, void GLAPIENTRY (*)())

#define glVertex3f_fn \
gl_call(glVertex3f, void GLAPIENTRY (*)(GLfloat, GLfloat, GLfloat))

#define glCreateShader_fn \
gl_call(glCreateShader, GLuint GLAPIENTRY (*)(GLenum))

#define glShaderSource_fn \
gl_call(glShaderSource, void GLAPIENTRY (*)(GLuint, GLsizei count, const GLchar**, const GLint*))

#define glCompileShader_fn \
gl_call(glCompileShader, void GLAPIENTRY (*)(GLuint))

#define glAttachShader_fn \
gl_call(glAttachShader, void GLAPIENTRY (*)(GLuint, GLuint))

#define glCreateProgram_fn \
gl_call(glCreateProgram, GLuint GLAPIENTRY (*)())

#define glLinkProgram_fn \
gl_call(glLinkProgram, void GLAPIENTRY (*)(GLuint))

#define glUseProgram_fn \
gl_call(glUseProgram, void GLAPIENTRY (*)(GLuint))

#define glGetUniformLocation_fn \
gl_call(glGetUniformLocation, GLint GLAPIENTRY (*)(GLuint, const GLchar*))

#define glUniform3fv_fn \
gl_call(glUniform3fv, void GLAPIENTRY (*)(GLint, GLsizei, const GLfloat*))

#define glUniformMatrix3fv_fn \
gl_call(glUniformMatrix3fv, void GLAPIENTRY (*)(GLint, GLsizei, GLboolean, const GLfloat*))

enum {
glMatrixMode_i,
glOrtho_i,
glBegin_i,
glEnd_i,
glVertex3f_i,
glCreateShader_i,
glShaderSource_i,
glCompileShader_i,
glAttachShader_i,
glCreateProgram_i,
glLinkProgram_i,
glUseProgram_i,
glGetUniformLocation_i,
glUniform3fv_i,
glUniformMatrix3fv_i
};

static const char* gl_symbols[] = {
"glMatrixMode",
"glOrtho",
"glBegin",
"glEnd",
"glVertex3f",
"glCreateShader",
"glShaderSource",
"glCompileShader",
"glAttachShader",
"glCreateProgram",
"glLinkProgram",
"glUseProgram",
"glGetUniformLocation",
"glUniform3fv",
"glUniformMatrix3fv"
};

static const void* gl_functions[sizeof(gl_symbols) / sizeof(const char*)];

static stdcall void initialize_gl_functions()
{
glMatrixMode_ = SDL_GL_GetProcAddress("glMatrixMode");
glOrtho_ = SDL_GL_GetProcAddress("glOrtho");

glBegin_ = SDL_GL_GetProcAddress("glBegin");
glEnd_ = SDL_GL_GetProcAddress("glEnd");
glVertex3f_ = SDL_GL_GetProcAddress("glVertex3f");

glCreateShader_ = SDL_GL_GetProcAddress("glCreateShader");
glShaderSource_ = SDL_GL_GetProcAddress("glShaderSource");
glCompileShader_ = SDL_GL_GetProcAddress("glCompileShader");
glAttachShader_ = SDL_GL_GetProcAddress("glAttachShader");
glCreateProgram_ = SDL_GL_GetProcAddress("glCreateProgram");
glLinkProgram_ = SDL_GL_GetProcAddress("glLinkProgram");
glUseProgram_ = SDL_GL_GetProcAddress("glUseProgram");

glGetUniformLocation_ = SDL_GL_GetProcAddress("glGetUniformLocation");
glUniform3fv_ = SDL_GL_GetProcAddress("glUniform3fv");
glUniformMatrix3fv_ = SDL_GL_GetProcAddress("glUniformMatrix3fv");
for (int i = 0; i < sizeof(gl_symbols) / sizeof(const char*); i++)
{
gl_functions[i] = SDL_GL_GetProcAddress_fn(gl_symbols[i]);
}
}

#endif
Expand Down
34 changes: 18 additions & 16 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <SDL.h>
#include <GL/gl.h>
#include "clib.h"
#include "sdl_functions.h"
#include "gl_functions.h"
#include "vector.h"
#include "shader.h"
Expand All @@ -24,29 +25,29 @@ static float sphere_radius;

static stdcall void initialize_sdl()
{
SDL_SetVideoMode(resolution_x, resolution_y, 0,
SDL_SetVideoMode_fn(resolution_x, resolution_y, 0,
SDL_OPENGL | (fullscreen ? SDL_FULLSCREEN : 0));
SDL_WM_SetCaption(window_caption, NULL);
SDL_ShowCursor(SDL_DISABLE);
SDL_WM_SetCaption_fn(window_caption, NULL);
SDL_ShowCursor_fn(SDL_DISABLE);
}

static stdcall void cleanup_sdl()
{
// SDL_Quit crashes since main() is removed, but we need this call to reset
// the screen resolution when running fullscreen
SDL_QuitSubSystem(SDL_INIT_VIDEO);
SDL_QuitSubSystem_fn(SDL_INIT_VIDEO);
}

static stdcall void setup_viewport()
{
glMatrixMode_(GL_PROJECTION);
glOrtho_(-window_ratio, window_ratio, -1.0, 1.0, -1.0, 1.0);
glMatrixMode_fn(GL_PROJECTION);
glOrtho_fn(-window_ratio, window_ratio, -1.0, 1.0, -1.0, 1.0);
}

static stdcall bool exit_requested()
{
SDL_Event event;
SDL_PollEvent(&event);
SDL_PollEvent_fn(&event);

if (event.type == SDL_QUIT)
{
Expand All @@ -68,7 +69,7 @@ static stdcall float linear_step(float start, float end, float position, float d

static stdcall bool update_scene()
{
Uint32 time = SDL_GetTicks();
Uint32 time = SDL_GetTicks_fn();

if (time > keypoints[sizeof(keypoints) / sizeof(struct keypoint) - 1].time)
{
Expand Down Expand Up @@ -116,27 +117,28 @@ static stdcall bool update_scene()
static stdcall void mainloop()
{
GLuint program = compile_program(vertex_glsl, fragment_glsl);
glUseProgram_(program);
glUseProgram_fn(program);

while (exit_requested() && update_scene())
{
uniform_vector3(program, "x", position);
uniform_matrix3(program, "o", orientation);
uniform_vector3(program, "f", (vector3){box_scale, box_radius, sphere_radius});

glBegin_(GL_QUADS);
glVertex3f_(-window_ratio, -1.0, 0.0);
glVertex3f_( window_ratio, -1.0, 0.0);
glVertex3f_( window_ratio, 1.0, 0.0);
glVertex3f_(-window_ratio, 1.0, 0.0);
glEnd_();
glBegin_fn(GL_QUADS);
glVertex3f_fn(-window_ratio, -1.0, 0.0);
glVertex3f_fn( window_ratio, -1.0, 0.0);
glVertex3f_fn( window_ratio, 1.0, 0.0);
glVertex3f_fn(-window_ratio, 1.0, 0.0);
glEnd_fn();

SDL_GL_SwapBuffers();
SDL_GL_SwapBuffers_fn();
}
}

void _start()
{
initialize_sdl_functions();
initialize_sdl();
initialize_gl_functions();
initialize_sound();
Expand Down
78 changes: 78 additions & 0 deletions sdl_functions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#ifndef SDL_FUNCTIONS_H
#define SDL_FUNCTIONS_H

#include <dlfcn.h>
#include <SDL.h>

#define sdl_call(name, type) ((type)sdl_functions[name ## _i])

#define SDL_GL_GetProcAddress_fn \
sdl_call(SDL_GL_GetProcAddress, void* SDLCALL (*)(const char*))

#define SDL_SetVideoMode_fn \
sdl_call(SDL_SetVideoMode, SDL_Surface* SDLCALL (*)(int, int, int, Uint32))

#define SDL_WM_SetCaption_fn \
sdl_call(SDL_WM_SetCaption, void SDLCALL (*)(const char*, const char*))

#define SDL_ShowCursor_fn \
sdl_call(SDL_ShowCursor, int SDLCALL (*)(int))

#define SDL_QuitSubSystem_fn \
sdl_call(SDL_QuitSubSystem, void SDLCALL (*)(Uint32))

#define SDL_PollEvent_fn \
sdl_call(SDL_PollEvent, int SDLCALL (*)(SDL_Event*))

#define SDL_GetTicks_fn \
sdl_call(SDL_GetTicks, Uint32 SDLCALL (*)())

#define SDL_GL_SwapBuffers_fn \
sdl_call(SDL_GL_SwapBuffers, void SDLCALL (*)())

#define SDL_OpenAudio_fn \
sdl_call(SDL_OpenAudio, int SDLCALL (*)(SDL_AudioSpec*, SDL_AudioSpec*))

#define SDL_PauseAudio_fn \
sdl_call(SDL_PauseAudio, void SDLCALL (*)(int))

enum {
SDL_GL_GetProcAddress_i,
SDL_SetVideoMode_i,
SDL_WM_SetCaption_i,
SDL_ShowCursor_i,
SDL_QuitSubSystem_i,
SDL_PollEvent_i,
SDL_GetTicks_i,
SDL_GL_SwapBuffers_i,
SDL_OpenAudio_i,
SDL_PauseAudio_i
};

static const char* sdl_symbols[] = {
"SDL_GL_GetProcAddress",
"SDL_SetVideoMode",
"SDL_WM_SetCaption",
"SDL_ShowCursor",
"SDL_QuitSubSystem",
"SDL_PollEvent",
"SDL_GetTicks",
"SDL_GL_SwapBuffers",
"SDL_OpenAudio",
"SDL_PauseAudio"
};

static const void* sdl_functions[sizeof(sdl_symbols) / sizeof(const char*)];

static stdcall void initialize_sdl_functions()
{
void* libsdl = dlopen("libSDL-1.2.so", RTLD_NOW);

for (int i = 0; i < sizeof(sdl_symbols) / sizeof(const char*); i++)
{
sdl_functions[i] = dlsym(libsdl, sdl_symbols[i]);
}
}

#endif

20 changes: 10 additions & 10 deletions shader.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,31 @@

static stdcall void add_shader(GLuint program, GLenum type, const GLchar* source)
{
GLuint shader = glCreateShader_(type);
glShaderSource_(shader, 1, &source, NULL);
glCompileShader_(shader);
glAttachShader_(program, shader);
GLuint shader = glCreateShader_fn(type);
glShaderSource_fn(shader, 1, &source, NULL);
glCompileShader_fn(shader);
glAttachShader_fn(program, shader);
}

static stdcall GLuint compile_program(const char* vertex_source, const char* fragment_source)
{
GLuint program = glCreateProgram_();
GLuint program = glCreateProgram_fn();
add_shader(program, GL_VERTEX_SHADER, vertex_source);
add_shader(program, GL_FRAGMENT_SHADER, fragment_source);
glLinkProgram_(program);
glLinkProgram_fn(program);
return program;
}

static stdcall void uniform_vector3(GLuint program, const char* identifier, const vector3 value)
{
GLint location = glGetUniformLocation_(program, identifier);
glUniform3fv_(location, 1, value);
GLint location = glGetUniformLocation_fn(program, identifier);
glUniform3fv_fn(location, 1, value);
}

static stdcall void uniform_matrix3(GLuint program, const char* identifier, const matrix3 value)
{
GLint location = glGetUniformLocation_(program, identifier);
glUniformMatrix3fv_(location, 1, GL_TRUE, (const GLfloat*)value);
GLint location = glGetUniformLocation_fn(program, identifier);
glUniformMatrix3fv_fn(location, 1, GL_TRUE, (const GLfloat*)value);
}

#endif
Expand Down
5 changes: 3 additions & 2 deletions sound.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include <SDL.h>
#include "clib.h"
#include "sdl_functions.h"
#include "4klang.inh"

static const int sound_channels = 2;
Expand All @@ -29,7 +30,7 @@ static SDL_AudioSpec sound_spec = {

static stdcall void initialize_sound()
{
SDL_OpenAudio(&sound_spec, NULL);
SDL_OpenAudio_fn(&sound_spec, NULL);
}

static stdcall void play_sound()
Expand All @@ -38,7 +39,7 @@ static stdcall void play_sound()
sound_thread_stack + sizeof(sound_thread_stack),
CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_SYSVSEM,
sound_buffer);
SDL_PauseAudio(0);
SDL_PauseAudio_fn(0);
}

#endif
Expand Down

0 comments on commit fb480a6

Please sign in to comment.