about summary refs log tree commit diff
path: root/src/engine/client/ec_gfx.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/client/ec_gfx.c')
-rw-r--r--src/engine/client/ec_gfx.c1020
1 files changed, 0 insertions, 1020 deletions
diff --git a/src/engine/client/ec_gfx.c b/src/engine/client/ec_gfx.c
deleted file mode 100644
index 1ea9f407..00000000
--- a/src/engine/client/ec_gfx.c
+++ /dev/null
@@ -1,1020 +0,0 @@
-/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
-
-#include <base/detect.h>
-
-#include "SDL.h"
-
-#ifdef CONF_FAMILY_WINDOWS
-	#define WIN32_LEAN_AND_MEAN
-	#include <windows.h>
-#endif
-
-#ifdef CONF_PLATFORM_MACOSX
-	#include <OpenGL/gl.h>
-	#include <OpenGL/glu.h>
-#else
-	#include <GL/gl.h>
-	#include <GL/glu.h>
-#endif
-
-#include <base/system.h>
-#include <engine/external/pnglite/pnglite.h>
-
-#include <engine/e_client_interface.h>
-#include <engine/e_engine.h>
-#include <engine/e_config.h>
-#include <engine/e_keys.h>
-
-#include <string.h>
-#include <stdio.h>
-#include <math.h>
-
-/* compressed textures */
-#define GL_COMPRESSED_RGB_ARB 0x84ED
-#define GL_COMPRESSED_RGBA_ARB 0x84EE
-#define GL_COMPRESSED_ALPHA_ARB 0x84E9
-
-#define TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
-
-enum
-{
-	DRAWING_QUADS=1,
-	DRAWING_LINES=2
-};
-
-/* */
-typedef struct { float x, y, z; } VEC3;
-typedef struct { float u, v; } TEXCOORD;
-typedef struct { float r, g, b, a; } COLOR;
-
-typedef struct
-{
-	VEC3 pos;
-	TEXCOORD tex;
-	COLOR color;
-} VERTEX;
-
-const int vertex_buffer_size = 32*1024;
-static VERTEX *vertices = 0;
-static int num_vertices = 0;
-
-static int no_gfx = 0;
-
-static COLOR color[4];
-static TEXCOORD texture[4];
-
-static int do_screenshot = 0;
-static int render_enable = 1;
-
-static int screen_width = -1;
-static int screen_height = -1;
-static float rotation = 0;
-static int drawing = 0;
-
-static float screen_x0 = 0;
-static float screen_y0 = 0;
-static float screen_x1 = 0;
-static float screen_y1 = 0;
-
-static int invalid_texture = 0;
-
-typedef struct
-{
-	GLuint tex;
-	int memsize;
-	int flags;
-	int next;
-} TEXTURE;
-
-enum
-{
-	MAX_TEXTURES = 1024*4
-};
-
-static TEXTURE textures[MAX_TEXTURES];
-static int first_free_texture;
-static int memory_usage = 0;
-
-static SDL_Surface *screen_surface;
-
-static const unsigned char null_texture_data[] = {
-	0xff,0x00,0x00,0xff, 0xff,0x00,0x00,0xff, 0x00,0xff,0x00,0xff, 0x00,0xff,0x00,0xff, 
-	0xff,0x00,0x00,0xff, 0xff,0x00,0x00,0xff, 0x00,0xff,0x00,0xff, 0x00,0xff,0x00,0xff, 
-	0x00,0x00,0xff,0xff, 0x00,0x00,0xff,0xff, 0xff,0xff,0x00,0xff, 0xff,0xff,0x00,0xff, 
-	0x00,0x00,0xff,0xff, 0x00,0x00,0xff,0xff, 0xff,0xff,0x00,0xff, 0xff,0xff,0x00,0xff, 
-};
-
-static void flush()
-{
-	if(num_vertices == 0)
-		return;
-		
-	if(no_gfx)
-	{
-		num_vertices = 0;
-		return;
-	}
-	
-		
-	//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
-	//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
-	glVertexPointer(3, GL_FLOAT,
-			sizeof(VERTEX),
-			(char*)vertices);
-	glTexCoordPointer(2, GL_FLOAT,
-			sizeof(VERTEX),
-			(char*)vertices + sizeof(float)*3);
-	glColorPointer(4, GL_FLOAT,
-			sizeof(VERTEX),
-			(char*)vertices + sizeof(float)*5);
-	glEnableClientState(GL_VERTEX_ARRAY);
-	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-	glEnableClientState(GL_COLOR_ARRAY);
-	
-	if(render_enable)
-	{
-		if(drawing == DRAWING_QUADS)
-			glDrawArrays(GL_QUADS, 0, num_vertices);
-		else if(drawing == DRAWING_LINES)
-			glDrawArrays(GL_LINES, 0, num_vertices);
-	}
-	
-	/* Reset pointer */
-	num_vertices = 0;
-}
-
-static void add_vertices(int count)
-{
-	num_vertices += count;
-	if((num_vertices + count) >= vertex_buffer_size)
-		flush();
-}
-
-static int try_init()
-{
-	const SDL_VideoInfo *info;
-	int flags = SDL_OPENGL;
-	
-	screen_width = config.gfx_screen_width;
-	screen_height = config.gfx_screen_height;
-
-	info = SDL_GetVideoInfo();
-
-	/* set flags */
-	flags  = SDL_OPENGL;
-	flags |= SDL_GL_DOUBLEBUFFER;
-	flags |= SDL_HWPALETTE;
-	if(config.dbg_resizable)
-		flags |= SDL_RESIZABLE;
-
-	if(info->hw_available)
-		flags |= SDL_HWSURFACE;
-	else
-		flags |= SDL_SWSURFACE;
-
-	if(info->blit_hw)
-		flags |= SDL_HWACCEL;
-
-	if(config.gfx_fullscreen)
-		flags |= SDL_FULLSCREEN;
-
-	/* set gl attributes */
-	if(config.gfx_fsaa_samples)
-	{
-		SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
-		SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, config.gfx_fsaa_samples);
-	}
-	else
-	{
-		SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
-		SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
-	}
-
-	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
-	SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, config.gfx_vsync);
-
-	/* set caption */
-	SDL_WM_SetCaption("Teeworlds", "Teeworlds");
-	
-	/* create window */
-	screen_surface = SDL_SetVideoMode(screen_width, screen_height, 0, flags);
-	if(screen_surface == NULL)
-	{
-		dbg_msg("gfx", "unable to set video mode: %s", SDL_GetError());
-		return -1;
-	}
-	
-	return 0;
-}
-
-void gfx_font_init();
-
-static int gfx_init_window()
-{
-	if(try_init() == 0)
-		return 0;
-	
-	/* try disabling fsaa */
-	while(config.gfx_fsaa_samples)
-	{
-		config.gfx_fsaa_samples--;
-		
-		if(config.gfx_fsaa_samples)
-			dbg_msg("gfx", "lowering FSAA to %d and trying again", config.gfx_fsaa_samples);
-		else
-			dbg_msg("gfx", "disabling FSAA and trying again");
-
-		if(try_init() == 0)
-			return 0;
-	}
-
-	/* try lowering the resolution */
-	if(config.gfx_screen_width != 640 || config.gfx_screen_height != 480)
-	{
-		dbg_msg("gfx", "setting resolution to 640x480 and trying again");
-		config.gfx_screen_width = 640;
-		config.gfx_screen_height = 480;
-
-		if(try_init() == 0)
-			return 0;
-	}
-
-	dbg_msg("gfx", "out of ideas. failed to init graphics");
-					
-	return -1;		
-}
-
-int gfx_init()
-{
-	int i;
-
-	if(config.dbg_stress)
-		no_gfx = 1;
-
-	{
-		int systems = 0;
-		
-		if(!no_gfx)
-			systems |= SDL_INIT_VIDEO;
-			
-		if(config.snd_enable)
-			systems |= SDL_INIT_AUDIO;
-
-		if(config.cl_eventthread)
-			systems |= SDL_INIT_EVENTTHREAD;
-		
-		if(SDL_Init(systems) < 0)
-		{
-			dbg_msg("gfx", "unable to init SDL: %s", SDL_GetError());
-			return -1;
-		}
-	}
-	
-    atexit(SDL_Quit);
-
-	if(!no_gfx)
-	{
-		#ifdef CONF_FAMILY_WINDOWS
-			if(!getenv("SDL_VIDEO_WINDOW_POS") && !getenv("SDL_VIDEO_CENTERED"))
-				putenv("SDL_VIDEO_WINDOW_POS=8,27");
-		#endif
-		
-		if(gfx_init_window() != 0)
-			return -1;
-	}
-	
-	/* Init vertices */
-	if (vertices)
-		mem_free(vertices);
-	vertices = (VERTEX*)mem_alloc(sizeof(VERTEX) * vertex_buffer_size, 1);
-	num_vertices = 0;
-
-
-	/*
-	dbg_msg("gfx", "OpenGL version %d.%d.%d", context.version_major(),
-											  context.version_minor(),
-											  context.version_rev());*/
-
-	
-	/* Set all z to -5.0f */
-	for (i = 0; i < vertex_buffer_size; i++)
-		vertices[i].pos.z = -5.0f;
-
-	/* init textures */
-	first_free_texture = 0;
-	for(i = 0; i < MAX_TEXTURES; i++)
-		textures[i].next = i+1;
-	textures[MAX_TEXTURES-1].next = -1;
-	
-	if(!no_gfx)
-	{
-		SDL_ShowCursor(0);
-		gfx_mapscreen(0,0,config.gfx_screen_width, config.gfx_screen_height);
-
-		/* set some default settings */	
-		glEnable(GL_BLEND);
-		glDisable(GL_CULL_FACE);
-		glDisable(GL_DEPTH_TEST);
-		glMatrixMode(GL_MODELVIEW);
-		glLoadIdentity();
-		
-		glAlphaFunc(GL_GREATER, 0);
-		glEnable(GL_ALPHA_TEST);
-		glDepthMask(0);
-
-		
-		//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-		//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-	}
-
-	/* init input */
-	inp_init();
-	
-	/* create null texture, will get id=0 */
-	invalid_texture = gfx_load_texture_raw(4,4,IMG_RGBA,null_texture_data,IMG_RGBA,TEXLOAD_NORESAMPLE);
-	dbg_msg("", "invalid texture id: %d %d", invalid_texture, textures[invalid_texture].tex);
-
-
-	/* font init */
-	gfx_font_init();
-	/* perform some tests */
-	/* pixeltest_dotesting(); */
-	
-	/*if(config.dbg_stress)
-		gfx_minimize();*/
-
-	return 0;
-}
-
-float gfx_screenaspect()
-{
-    return gfx_screenwidth()/(float)gfx_screenheight();
-}
-
-int gfx_window_active()
-{
-	return SDL_GetAppState()&SDL_APPINPUTFOCUS;
-}
-
-int gfx_window_open()
-{
-	return SDL_GetAppState()&SDL_APPACTIVE;
-}
-
-VIDEO_MODE fakemodes[] = {
-	{320,240,8,8,8}, {400,300,8,8,8}, {640,480,8,8,8},
-	{720,400,8,8,8}, {768,576,8,8,8}, {800,600,8,8,8},
-	{1024,600,8,8,8}, {1024,768,8,8,8}, {1152,864,8,8,8},
-	{1280,768,8,8,8}, {1280,800,8,8,8}, {1280,960,8,8,8},
-	{1280,1024,8,8,8}, {1368,768,8,8,8}, {1400,1050,8,8,8},
-	{1440,900,8,8,8}, {1440,1050,8,8,8}, {1600,1000,8,8,8},
-	{1600,1200,8,8,8}, {1680,1050,8,8,8}, {1792,1344,8,8,8},
-	{1800,1440,8,8,8}, {1856,1392,8,8,8}, {1920,1080,8,8,8},
-	{1920,1200,8,8,8}, {1920,1440,8,8,8}, {1920,2400,8,8,8},
-	{2048,1536,8,8,8},
-		
-	{320,240,5,6,5}, {400,300,5,6,5}, {640,480,5,6,5},
-	{720,400,5,6,5}, {768,576,5,6,5}, {800,600,5,6,5},
-	{1024,600,5,6,5}, {1024,768,5,6,5}, {1152,864,5,6,5},
-	{1280,768,5,6,5}, {1280,800,5,6,5}, {1280,960,5,6,5},
-	{1280,1024,5,6,5}, {1368,768,5,6,5}, {1400,1050,5,6,5},
-	{1440,900,5,6,5}, {1440,1050,5,6,5}, {1600,1000,5,6,5},
-	{1600,1200,5,6,5}, {1680,1050,5,6,5}, {1792,1344,5,6,5},
-	{1800,1440,5,6,5}, {1856,1392,5,6,5}, {1920,1080,5,6,5},
-	{1920,1200,5,6,5}, {1920,1440,5,6,5}, {1920,2400,5,6,5},
-	{2048,1536,5,6,5}
-};
-
-int gfx_get_video_modes(VIDEO_MODE *list, int maxcount)
-{
-	int num_modes = sizeof(fakemodes)/sizeof(VIDEO_MODE);
-	SDL_Rect **modes;
-
-	if(config.gfx_display_all_modes)
-	{
-		int count = sizeof(fakemodes)/sizeof(VIDEO_MODE);
-		mem_copy(list, fakemodes, sizeof(fakemodes));
-		if(maxcount < count)
-			count = maxcount;
-		return count;
-	}
-	
-	/* TODO: fix this code on osx or windows */
-		
-	modes = SDL_ListModes(NULL, SDL_OPENGL|SDL_GL_DOUBLEBUFFER|SDL_FULLSCREEN);
-	if(modes == NULL)
-	{
-		/* no modes */
-		num_modes = 0;
-	}
-	else if(modes == (SDL_Rect**)-1)
-	{
-		/* all modes */
-	}
-	else
-	{
-		int i;
-		num_modes = 0;
-		for(i = 0; modes[i]; ++i)
-		{
-			if(num_modes == maxcount)
-				break;
-			list[num_modes].width = modes[i]->w;
-			list[num_modes].height = modes[i]->h;
-			list[num_modes].red = 8;
-			list[num_modes].green = 8;
-			list[num_modes].blue = 8;
-			num_modes++;
-		}
-	}
-	
-	return num_modes;
-}
-
-int gfx_unload_texture(int index)
-{
-	if(index == invalid_texture)
-		return 0;
-		
-	if(index < 0)
-		return 0;
-		
-	glDeleteTextures(1, &textures[index].tex);
-	textures[index].next = first_free_texture;
-	memory_usage -= textures[index].memsize;
-	first_free_texture = index;
-	return 0;
-}
-
-void gfx_blend_none()
-{
-	if(no_gfx) return;
-	glDisable(GL_BLEND);
-}
-
-void gfx_blend_normal()
-{
-	if(no_gfx) return;
-	glEnable(GL_BLEND);
-	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-}
-
-void gfx_blend_additive()
-{
-	if(no_gfx) return;
-	glEnable(GL_BLEND);
-	glBlendFunc(GL_SRC_ALPHA, GL_ONE);
-}
-
-int gfx_memory_usage() { return memory_usage; }
-
-static unsigned char sample(int w, int h, const unsigned char *data, int u, int v, int offset)
-{
-	return (data[(v*w+u)*4+offset]+
-	data[(v*w+u+1)*4+offset]+
-	data[((v+1)*w+u)*4+offset]+
-	data[((v+1)*w+u+1)*4+offset])/4;
-}
-
-int gfx_load_texture_raw(int w, int h, int format, const void *data, int store_format, int flags)
-{
-	int mipmap = 1;
-	unsigned char *texdata = (unsigned char *)data;
-	unsigned char *tmpdata = 0;
-	int oglformat = 0;
-	int store_oglformat = 0;
-	int tex = 0;
-	
-	/* don't waste memory on texture if we are stress testing */
-	if(config.dbg_stress || no_gfx)
-		return 	invalid_texture;
-	
-	/* grab texture */
-	tex = first_free_texture;
-	first_free_texture = textures[tex].next;
-	textures[tex].next = -1;
-	
-	/* resample if needed */
-	if(!(flags&TEXLOAD_NORESAMPLE) && config.gfx_texture_quality==0)
-	{
-		if(w > 16 && h > 16 && format == IMG_RGBA)
-		{
-			unsigned char *tmpdata;
-			int c = 0;
-			int x, y;
-
-			tmpdata = (unsigned char *)mem_alloc(w*h*4, 1);
-
-			w/=2;
-			h/=2;
-
-			for(y = 0; y < h; y++)
-				for(x = 0; x < w; x++, c++)
-				{
-					tmpdata[c*4] = sample(w*2, h*2, texdata, x*2,y*2, 0);
-					tmpdata[c*4+1] = sample(w*2, h*2, texdata, x*2,y*2, 1);
-					tmpdata[c*4+2] = sample(w*2, h*2, texdata, x*2,y*2, 2);
-					tmpdata[c*4+3] = sample(w*2, h*2, texdata, x*2,y*2, 3);
-				}
-			texdata = tmpdata;
-		}
-	}
-	
-	oglformat = GL_RGBA;
-	if(format == IMG_RGB)
-		oglformat = GL_RGB;
-	else if(format == IMG_ALPHA)
-		oglformat = GL_ALPHA;
-	
-	/* upload texture */
-	if(config.gfx_texture_compression)
-	{
-		store_oglformat = GL_COMPRESSED_RGBA_ARB;
-		if(store_format == IMG_RGB)
-			store_oglformat = GL_COMPRESSED_RGB_ARB;
-		else if(store_format == IMG_ALPHA)
-			store_oglformat = GL_COMPRESSED_ALPHA_ARB;
-	}
-	else
-	{
-		store_oglformat = GL_RGBA;
-		if(store_format == IMG_RGB)
-			store_oglformat = GL_RGB;
-		else if(store_format == IMG_ALPHA)
-			store_oglformat = GL_ALPHA;
-	}
-		
-	glGenTextures(1, &textures[tex].tex);
-	glBindTexture(GL_TEXTURE_2D, textures[tex].tex);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
-	gluBuild2DMipmaps(GL_TEXTURE_2D, store_oglformat, w, h, oglformat, GL_UNSIGNED_BYTE, texdata);
-	
-	/* calculate memory usage */
-	{
-		int pixel_size = 4;
-		if(store_format == IMG_RGB)
-			pixel_size = 3;
-		else if(store_format == IMG_ALPHA)
-			pixel_size = 1;
-
-		textures[tex].memsize = w*h*pixel_size;
-		if(mipmap)
-		{
-			while(w > 2 && h > 2)
-			{
-				w>>=1;
-				h>>=1;
-				textures[tex].memsize += w*h*pixel_size;
-			}
-		}
-	}
-	
-	memory_usage += textures[tex].memsize;
-	mem_free(tmpdata);
-	return tex;
-}
-
-/* simple uncompressed RGBA loaders */
-int gfx_load_texture(const char *filename, int store_format, int flags)
-{
-	int l = strlen(filename);
-	int id;
-	IMAGE_INFO img;
-	
-	if(l < 3)
-		return -1;
-	if(gfx_load_png(&img, filename))
-	{
-		if (store_format == IMG_AUTO)
-			store_format = img.format;
-
-		id = gfx_load_texture_raw(img.width, img.height, img.format, img.data, store_format, flags);
-		mem_free(img.data);
-		return id;
-	}
-	
-	return invalid_texture;
-}
-
-int gfx_load_png(IMAGE_INFO *img, const char *filename)
-{
-	char completefilename[512];
-	unsigned char *buffer;
-	png_t png;
-	
-	/* open file for reading */
-	png_init(0,0);
-
-	engine_getpath(completefilename, sizeof(completefilename), filename, IOFLAG_READ);
-	
-	if(png_open_file(&png, completefilename) != PNG_NO_ERROR)
-	{
-		dbg_msg("game/png", "failed to open file. filename='%s'", completefilename);
-		return 0;
-	}
-	
-	if(png.depth != 8 || (png.color_type != PNG_TRUECOLOR && png.color_type != PNG_TRUECOLOR_ALPHA))
-	{
-		dbg_msg("game/png", "invalid format. filename='%s'", completefilename);
-		png_close_file(&png);
-        return 0;
-	}
-		
-	buffer = (unsigned char *)mem_alloc(png.width * png.height * png.bpp, 1);
-	png_get_data(&png, buffer);
-	png_close_file(&png);
-	
-	img->width = png.width;
-	img->height = png.height;
-	if(png.color_type == PNG_TRUECOLOR)
-		img->format = IMG_RGB;
-	else if(png.color_type == PNG_TRUECOLOR_ALPHA)
-		img->format = IMG_RGBA;
-	img->data = buffer;
-	return 1;
-}
-
-void gfx_shutdown()
-{
-	if (vertices)
-		mem_free(vertices);
-
-	/* TODO: SDL, is this correct? */
-	SDL_Quit();
-}
-
-void gfx_screenshot()
-{
-	do_screenshot = 1;
-}
-
-
-extern int text_render_codepaths_usage[5];
-
-void gfx_swap()
-{
-	/*dbg_msg("", "%d %d %d %d %d",
-		text_render_codepaths_usage[0],
-		text_render_codepaths_usage[1],
-		text_render_codepaths_usage[2],
-		text_render_codepaths_usage[3],
-		text_render_codepaths_usage[4]);
-
-	text_render_codepaths_usage[0] = 0;
-	text_render_codepaths_usage[1] = 0;
-	text_render_codepaths_usage[2] = 0;
-	text_render_codepaths_usage[3] = 0;
-	text_render_codepaths_usage[4] = 0;*/
-
-	if(do_screenshot)
-	{
-		/* find filename */
-		char filename[128];
-		static int index = 1;
-
-		for(; index < 1000; index++)
-		{
-			IOHANDLE io;
-			str_format(filename, sizeof(filename), "screenshots/screenshot%04d.png", index);
-			io = engine_openfile(filename, IOFLAG_READ);
-			if(io)
-				io_close(io);
-			else
-				break;
-		}
-
-		gfx_screenshot_direct(filename);
-	
-		do_screenshot = 0;	
-	}
-	
-	{
-		static PERFORMACE_INFO pscope = {"glfwSwapBuffers", 0};
-		perf_start(&pscope);
-		SDL_GL_SwapBuffers();
-		perf_end();
-	}
-	
-	if(render_enable && config.gfx_finish)
-		glFinish();
-}
-
-void gfx_screenshot_direct(const char *filename)
-{
-	/* fetch image data */
-	int y;
-	int w = screen_width;
-	int h = screen_height;
-	unsigned char *pixel_data = (unsigned char *)mem_alloc(w*(h+1)*4, 1);
-	unsigned char *temp_row = pixel_data+w*h*4;
-	glReadPixels(0,0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixel_data);
-	
-	/* flip the pixel because opengl works from bottom left corner */
-	for(y = 0; y < h/2; y++)
-	{
-		mem_copy(temp_row, pixel_data+y*w*4, w*4);
-		mem_copy(pixel_data+y*w*4, pixel_data+(h-y-1)*w*4, w*4);
-		mem_copy(pixel_data+(h-y-1)*w*4, temp_row,w*4);
-	}
-	
-	/* find filename */
-	{
-		char wholepath[1024];
-		png_t png;
-
-		engine_savepath(filename, wholepath, sizeof(wholepath));
-	
-		/* save png */
-		dbg_msg("client", "saved screenshot to '%s'", wholepath);
-		png_open_file_write(&png, wholepath);
-		png_set_data(&png, w, h, 8, PNG_TRUECOLOR_ALPHA, (unsigned char *)pixel_data);
-		png_close_file(&png);
-	}
-
-	/* clean up */
-	mem_free(pixel_data);
-}
-
-int gfx_screenwidth()
-{
-	return screen_width;
-}
-
-int gfx_screenheight()
-{
-	return screen_height;
-}
-
-void gfx_texture_set(int slot)
-{
-	dbg_assert(drawing == 0, "called gfx_texture_set within begin");
-	if(no_gfx) return;
-	if(slot == -1)
-	{
-		glDisable(GL_TEXTURE_2D);
-	}
-	else
-	{
-		glEnable(GL_TEXTURE_2D);
-		glBindTexture(GL_TEXTURE_2D, textures[slot].tex);
-	}
-}
-
-void gfx_clear(float r, float g, float b)
-{
-	if(no_gfx) return;
-	glClearColor(r,g,b,0.0f);
-	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-}
-
-void gfx_mapscreen(float tl_x, float tl_y, float br_x, float br_y)
-{
-	screen_x0 = tl_x;
-	screen_y0 = tl_y;
-	screen_x1 = br_x;
-	screen_y1 = br_y;
-	if(no_gfx) return;
-	glMatrixMode(GL_PROJECTION);
-	glLoadIdentity();
-	glOrtho(tl_x, br_x, br_y, tl_y, 1.0f, 10.f);
-}
-
-void gfx_getscreen(float *tl_x, float *tl_y, float *br_x, float *br_y)
-{
-	*tl_x = screen_x0;
-	*tl_y = screen_y0;
-	*br_x = screen_x1;
-	*br_y = screen_y1;
-}
-
-void gfx_quads_begin()
-{
-	dbg_assert(drawing == 0, "called quads_begin twice");
-	drawing = DRAWING_QUADS;
-	
-	gfx_quads_setsubset(0,0,1,1);
-	gfx_quads_setrotation(0);
-	gfx_setcolor(1,1,1,1);
-}
-
-void gfx_quads_end()
-{
-	dbg_assert(drawing == DRAWING_QUADS, "called quads_end without begin");
-	flush();
-	drawing = 0;
-}
-
-
-void gfx_quads_setrotation(float angle)
-{
-	dbg_assert(drawing == DRAWING_QUADS, "called gfx_quads_setrotation without begin");
-	rotation = angle;
-}
-
-void gfx_setcolorvertex(int i, float r, float g, float b, float a)
-{
-	dbg_assert(drawing != 0, "called gfx_quads_setcolorvertex without begin");
-	color[i].r = r;
-	color[i].g = g;
-	color[i].b = b;
-	color[i].a = a;
-}
-
-void gfx_setcolor(float r, float g, float b, float a)
-{
-	dbg_assert(drawing != 0, "called gfx_quads_setcolor without begin");
-	gfx_setcolorvertex(0, r, g, b, a);
-	gfx_setcolorvertex(1, r, g, b, a);
-	gfx_setcolorvertex(2, r, g, b, a);
-	gfx_setcolorvertex(3, r, g, b, a);
-}
-
-void gfx_quads_setsubset(float tl_u, float tl_v, float br_u, float br_v)
-{
-	dbg_assert(drawing == DRAWING_QUADS, "called gfx_quads_setsubset without begin");
-
-	texture[0].u = tl_u;	texture[1].u = br_u;
-	texture[0].v = tl_v;	texture[1].v = tl_v;
-
-	texture[3].u = tl_u;	texture[2].u = br_u;
-	texture[3].v = br_v;	texture[2].v = br_v;
-}
-
-void gfx_quads_setsubset_free(
-	float x0, float y0, float x1, float y1,
-	float x2, float y2, float x3, float y3)
-{
-	texture[0].u = x0; texture[0].v = y0;
-	texture[1].u = x1; texture[1].v = y1;
-	texture[2].u = x2; texture[2].v = y2;
-	texture[3].u = x3; texture[3].v = y3;
-}
-
-
-static void rotate(VEC3 *center, VEC3 *point)
-{
-	float x = point->x - center->x;
-	float y = point->y - center->y;
-	point->x = x * cosf(rotation) - y * sinf(rotation) + center->x;
-	point->y = x * sinf(rotation) + y * cosf(rotation) + center->y;
-}
-
-void gfx_quads_draw(float x, float y, float w, float h)
-{
-	gfx_quads_drawTL(x-w/2, y-h/2,w,h);
-}
-
-void gfx_quads_drawTL(float x, float y, float width, float height)
-{
-	VEC3 center;
-
-	dbg_assert(drawing == DRAWING_QUADS, "called quads_draw without begin");
-
-	center.x = x + width/2;
-	center.y = y + height/2;
-	center.z = 0;
-	
-	vertices[num_vertices].pos.x = x;
-	vertices[num_vertices].pos.y = y;
-	vertices[num_vertices].tex = texture[0];
-	vertices[num_vertices].color = color[0];
-	rotate(&center, &vertices[num_vertices].pos);
-
-	vertices[num_vertices + 1].pos.x = x+width;
-	vertices[num_vertices + 1].pos.y = y;
-	vertices[num_vertices + 1].tex = texture[1];
-	vertices[num_vertices + 1].color = color[1];
-	rotate(&center, &vertices[num_vertices + 1].pos);
-
-	vertices[num_vertices + 2].pos.x = x + width;
-	vertices[num_vertices + 2].pos.y = y+height;
-	vertices[num_vertices + 2].tex = texture[2];
-	vertices[num_vertices + 2].color = color[2];
-	rotate(&center, &vertices[num_vertices + 2].pos);
-
-	vertices[num_vertices + 3].pos.x = x;
-	vertices[num_vertices + 3].pos.y = y+height;
-	vertices[num_vertices + 3].tex = texture[3];
-	vertices[num_vertices + 3].color = color[3];
-	rotate(&center, &vertices[num_vertices + 3].pos);
-	
-	add_vertices(4);
-}
-
-void gfx_quads_draw_freeform(
-	float x0, float y0, float x1, float y1,
-	float x2, float y2, float x3, float y3)
-{
-	dbg_assert(drawing == DRAWING_QUADS, "called quads_draw_freeform without begin");
-	
-	vertices[num_vertices].pos.x = x0;
-	vertices[num_vertices].pos.y = y0;
-	vertices[num_vertices].tex = texture[0];
-	vertices[num_vertices].color = color[0];
-
-	vertices[num_vertices + 1].pos.x = x1;
-	vertices[num_vertices + 1].pos.y = y1;
-	vertices[num_vertices + 1].tex = texture[1];
-	vertices[num_vertices + 1].color = color[1];
-
-	vertices[num_vertices + 2].pos.x = x3;
-	vertices[num_vertices + 2].pos.y = y3;
-	vertices[num_vertices + 2].tex = texture[3];
-	vertices[num_vertices + 2].color = color[3];
-
-	vertices[num_vertices + 3].pos.x = x2;
-	vertices[num_vertices + 3].pos.y = y2;
-	vertices[num_vertices + 3].tex = texture[2];
-	vertices[num_vertices + 3].color = color[2];
-	
-	add_vertices(4);
-}
-
-void gfx_quads_text(float x, float y, float size, float r, float g, float b, float a, const char *text)
-{
-	float startx = x;
-
-	gfx_quads_begin();
-	gfx_setcolor(r,g,b,a);
-
-	while(*text)
-	{
-		char c = *text;
-		text++;
-		
-		if(c == '\n')
-		{
-			x = startx;
-			y += size;
-		}
-		else
-		{
-			gfx_quads_setsubset(
-				(c%16)/16.0f,
-				(c/16)/16.0f,
-				(c%16)/16.0f+1.0f/16.0f,
-				(c/16)/16.0f+1.0f/16.0f);
-			
-			gfx_quads_drawTL(x,y,size,size);
-			x += size/2;
-		}
-	}
-	
-	gfx_quads_end();
-}
-
-void gfx_lines_begin()
-{
-	dbg_assert(drawing == 0, "called begin twice");
-	drawing = DRAWING_LINES;
-	gfx_setcolor(1,1,1,1);
-}
-
-void gfx_lines_end()
-{
-	dbg_assert(drawing == DRAWING_LINES, "called end without begin");
-	flush();
-	drawing = 0;
-}
-
-void gfx_lines_draw(float x0, float y0, float x1, float y1)
-{
-	dbg_assert(drawing == DRAWING_LINES, "called draw without begin");
-	
-	vertices[num_vertices].pos.x = x0;
-	vertices[num_vertices].pos.y = y0;
-	vertices[num_vertices].tex = texture[0];
-	vertices[num_vertices].color = color[0];
-
-	vertices[num_vertices + 1].pos.x = x1;
-	vertices[num_vertices + 1].pos.y = y1;
-	vertices[num_vertices + 1].tex = texture[1];
-	vertices[num_vertices + 1].color = color[1];
-	
-	add_vertices(2);
-}
-
-void gfx_clip_enable(int x, int y, int w, int h)
-{
-	if(no_gfx) return;
-	glScissor(x, gfx_screenheight()-(y+h), w, h);
-	glEnable(GL_SCISSOR_TEST);
-}
-
-void gfx_clip_disable()
-{
-	if(no_gfx) return;
-	glDisable(GL_SCISSOR_TEST);
-}
-
-void gfx_minimize()
-{
-	SDL_WM_IconifyWindow();
-}
-
-void gfx_maximize()
-{
-	/* TODO: SDL */
-}