*/
#include <SDL.h>
-#include <SDL_mixer.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <math.h>
+#include <ctype.h>
#include "config.h"
#include "glext.h"
#include "vec3.h"
+#include "sync.h"
+#include "common.h"
/*---------------------------------------------------------------------------*/
config_set_d(i, d);
for (c = 0; c < SDLK_LAST; c++)
- if (strcmp(s, SDL_GetKeyName(c)) == 0)
+ if (strcmp(s, SDL_GetKeyName((SDLKey) c)) == 0)
{
config_set_d(i, c);
break;
void config_init(void)
{
- memset(option_d, 0, CONFIG_OPTION_D_COUNT * sizeof (int));
- memset(option_s, 0, CONFIG_OPTION_S_COUNT * sizeof (char *));
+ memset(option_d, 0, sizeof (option_d));
+ memset(option_s, 0, sizeof (option_s));
config_set_d(CONFIG_FULLSCREEN, DEFAULT_FULLSCREEN);
config_set_d(CONFIG_WIDTH, DEFAULT_WIDTH);
config_set_d(CONFIG_TEXTURES, DEFAULT_TEXTURES);
config_set_d(CONFIG_GEOMETRY, DEFAULT_GEOMETRY);
config_set_d(CONFIG_REFLECTION, DEFAULT_REFLECTION);
+ config_set_d(CONFIG_MULTISAMPLE, DEFAULT_MULTISAMPLE);
+ config_set_d(CONFIG_MIPMAP, DEFAULT_MIPMAP);
+ config_set_d(CONFIG_ANISO, DEFAULT_ANISO);
config_set_d(CONFIG_BACKGROUND, DEFAULT_BACKGROUND);
config_set_d(CONFIG_SHADOW, DEFAULT_SHADOW);
- config_set_d(CONFIG_AUDIO_RATE, DEFAULT_AUDIO_RATE);
config_set_d(CONFIG_AUDIO_BUFF, DEFAULT_AUDIO_BUFF);
config_set_d(CONFIG_MOUSE_SENSE, DEFAULT_MOUSE_SENSE);
config_set_d(CONFIG_MOUSE_INVERT, DEFAULT_MOUSE_INVERT);
+ config_set_d(CONFIG_VSYNC, DEFAULT_VSYNC);
config_set_d(CONFIG_NICE, DEFAULT_NICE);
config_set_d(CONFIG_FPS, DEFAULT_FPS);
config_set_d(CONFIG_SOUND_VOLUME, DEFAULT_SOUND_VOLUME);
config_set_d(CONFIG_JOYSTICK_CAMERA_1, DEFAULT_JOYSTICK_CAMERA_1);
config_set_d(CONFIG_JOYSTICK_CAMERA_2, DEFAULT_JOYSTICK_CAMERA_2);
config_set_d(CONFIG_JOYSTICK_CAMERA_3, DEFAULT_JOYSTICK_CAMERA_3);
+ config_set_d(CONFIG_JOYSTICK_DPAD_L, DEFAULT_JOYSTICK_DPAD_L);
+ config_set_d(CONFIG_JOYSTICK_DPAD_R, DEFAULT_JOYSTICK_DPAD_R);
+ config_set_d(CONFIG_JOYSTICK_DPAD_U, DEFAULT_JOYSTICK_DPAD_U);
+ config_set_d(CONFIG_JOYSTICK_DPAD_D, DEFAULT_JOYSTICK_DPAD_D);
config_set_d(CONFIG_KEY_CAMERA_1, DEFAULT_KEY_CAMERA_1);
config_set_d(CONFIG_KEY_CAMERA_2, DEFAULT_KEY_CAMERA_2);
config_set_d(CONFIG_KEY_CAMERA_3, DEFAULT_KEY_CAMERA_3);
config_set_d(CONFIG_VIEW_DZ, DEFAULT_VIEW_DZ);
config_set_d(CONFIG_ROTATE_FAST, DEFAULT_ROTATE_FAST);
config_set_d(CONFIG_ROTATE_SLOW, DEFAULT_ROTATE_SLOW);
- config_set_d(CONFIG_LAST_SET, DEFAULT_LAST_SET);
config_set_s(CONFIG_PLAYER, DEFAULT_PLAYER);
config_set_s(CONFIG_BALL, DEFAULT_BALL);
- config_set_s(CONFIG_COIN, DEFAULT_COIN);
- config_set_s(CONFIG_LANG, DEFAULT_LANG);
+ config_set_s(CONFIG_WIIMOTE_ADDR, DEFAULT_WIIMOTE_ADDR);
+ config_set_s(CONFIG_REPLAY_NAME, DEFAULT_REPLAY_NAME);
+ config_set_d(CONFIG_CHEAT, DEFAULT_CHEAT);
+ config_set_d(CONFIG_STATS, DEFAULT_STATS);
+ config_set_d(CONFIG_UNIFORM, DEFAULT_UNIFORM);
+ config_set_d(CONFIG_KEY_FORWARD, DEFAULT_KEY_FORWARD);
+ config_set_d(CONFIG_KEY_BACKWARD, DEFAULT_KEY_BACKWARD);
+ config_set_d(CONFIG_KEY_LEFT, DEFAULT_KEY_LEFT);
+ config_set_d(CONFIG_KEY_RIGHT, DEFAULT_KEY_RIGHT);
+ config_set_d(CONFIG_KEY_PAUSE, DEFAULT_KEY_PAUSE);
+ config_set_d(CONFIG_KEY_RESTART, DEFAULT_KEY_RESTART);
+ config_set_d(CONFIG_KEY_SCORE_NEXT, DEFAULT_KEY_SCORE_NEXT);
+ config_set_d(CONFIG_SCREENSHOT, DEFAULT_SCREENSHOT);
+ config_set_d(CONFIG_LOCK_GOALS, DEFAULT_LOCK_GOALS);
+}
+
+/*
+ * Scan a NUL-terminated string LINE according to the format
+ * '^<space>?<key><space><value>$' and store pointers to the start of key and
+ * value at DST_KEY and DST_VAL, respectively. No memory is allocated to store
+ * the strings; instead, the memory pointed to by LINE modified in-place as
+ * needed.
+ *
+ * Return 1 if LINE matches the format, return 0 otherwise.
+ */
+
+static int scan_key_and_value(char **dst_key, char **dst_val, char *line)
+{
+ if (line)
+ {
+ char *key, *val, *space;
+
+ for (key = line; *key && isspace(*key); key++);
+
+ if (*key)
+ {
+ if (dst_key)
+ *dst_key = key;
+ }
+ else
+ return 0;
+
+ for (space = key; *space && !isspace(*space); space++);
+
+ if (*space)
+ {
+ /* NUL-terminate the key, if necessary. */
+
+ if (dst_key)
+ {
+ *space = '\0';
+ space++;
+ }
+ }
+ else
+ return 0;
+
+ for (val = space; *val && isspace(*val); val++);
+
+ if (*val)
+ {
+ if (dst_val)
+ *dst_val = val;
+ }
+ else
+ return 0;
+
+ return 1;
+ }
+
+ return 0;
}
void config_load(void)
if ((fp = fopen(config_user(USER_CONFIG_FILE), "r")))
{
- char buf[MAXSTR];
- char key[MAXSTR];
- char val[MAXSTR];
+ char *line, *key, *val;
- while (fgets(buf, MAXSTR, fp))
- if (sscanf(buf, "%s %s", key, val) == 2)
+ while (read_line(&line, fp))
+ {
+ if (scan_key_and_value(&key, &val, line))
{
if (strcmp(key, "fullscreen") == 0)
config_set_d(CONFIG_FULLSCREEN, atoi(val));
config_set_d(CONFIG_GEOMETRY, atoi(val));
else if (strcmp(key, "reflection") == 0)
config_set_d(CONFIG_REFLECTION, atoi(val));
+ else if (strcmp(key, "multisample") == 0)
+ config_set_d(CONFIG_MULTISAMPLE, atoi(val));
+ else if (strcmp(key, "mipmap") == 0)
+ config_set_d(CONFIG_MIPMAP, atoi(val));
+ else if (strcmp(key, "aniso") == 0)
+ config_set_d(CONFIG_ANISO, atoi(val));
else if (strcmp(key, "background") == 0)
config_set_d(CONFIG_BACKGROUND, atoi(val));
else if (strcmp(key, "shadow") == 0)
config_set_d(CONFIG_SHADOW, atoi(val));
- else if (strcmp(key, "audio_rate") == 0)
- config_set_d(CONFIG_AUDIO_RATE, atoi(val));
else if (strcmp(key, "audio_buff") == 0)
config_set_d(CONFIG_AUDIO_BUFF, atoi(val));
else if (strcmp(key, "mouse_sense") == 0)
config_set_d(CONFIG_MOUSE_SENSE, atoi(val));
else if (strcmp(key, "mouse_invert") == 0)
config_set_d(CONFIG_MOUSE_INVERT, atoi(val));
+ else if (strcmp(key, "vsync") == 0)
+ config_set_d(CONFIG_VSYNC, atoi(val));
else if (strcmp(key, "nice") == 0)
config_set_d(CONFIG_NICE, atoi(val));
else if (strcmp(key, "fps") == 0)
config_set_d(CONFIG_ROTATE_FAST, atoi(val));
else if (strcmp(key, "rotate_slow") == 0)
config_set_d(CONFIG_ROTATE_SLOW, atoi(val));
- else if (strcmp(key, "last_set") == 0)
- config_set_d(CONFIG_LAST_SET, atoi(val));
+
+ else if (strcmp(key, "key_forward") == 0)
+ config_key(val, CONFIG_KEY_FORWARD, DEFAULT_KEY_FORWARD);
+ else if (strcmp(key, "key_backward") == 0)
+ config_key(val, CONFIG_KEY_BACKWARD, DEFAULT_KEY_BACKWARD);
+ else if (strcmp(key, "key_left") == 0)
+ config_key(val, CONFIG_KEY_LEFT, DEFAULT_KEY_LEFT);
+ else if (strcmp(key, "key_right") == 0)
+ config_key(val, CONFIG_KEY_RIGHT, DEFAULT_KEY_RIGHT);
else if (strcmp(key, "key_camera_1") == 0)
config_key(val, CONFIG_KEY_CAMERA_1, DEFAULT_KEY_CAMERA_1);
else if (strcmp(key, "key_camera_l") == 0)
config_key(val, CONFIG_KEY_CAMERA_L, DEFAULT_KEY_CAMERA_L);
+ else if (strcmp(key, "key_pause") == 0)
+ config_key(val, CONFIG_KEY_PAUSE, DEFAULT_KEY_PAUSE);
+ else if (strcmp(key, "key_restart") == 0)
+ config_key(val, CONFIG_KEY_RESTART, DEFAULT_KEY_RESTART);
+
+ else if (strcmp(key, "key_score_next") == 0)
+ config_key(val, CONFIG_KEY_SCORE_NEXT, DEFAULT_KEY_SCORE_NEXT);
+
else if (strcmp(key, "player") == 0)
config_set_s(CONFIG_PLAYER, val);
- else if (strcmp(key, "ball") == 0)
- config_set_s(CONFIG_BALL, val);
- else if (strcmp(key, "coin") == 0)
- config_set_s(CONFIG_COIN, val);
- else if (strcmp(key, "lang") == 0)
- config_set_s(CONFIG_LANG, val);
+ else if (strcmp(key, "ball_file") == 0)
+ config_set_s(CONFIG_BALL, val);
+ else if (strcmp(key, "wiimote_addr") == 0)
+ config_set_s(CONFIG_WIIMOTE_ADDR, val);
+ else if (strcmp(key, "replay_name") == 0)
+ config_set_s(CONFIG_REPLAY_NAME, val);
+
+ else if (strcmp(key, "cheat") == 0)
+ config_set_d(CONFIG_CHEAT, atoi(val));
+ else if (strcmp(key, "stats") == 0)
+ config_set_d(CONFIG_STATS, atoi(val));
+ else if (strcmp(key, "uniform") == 0)
+ config_set_d(CONFIG_UNIFORM, atoi(val));
+ else if (strcmp(key, "screenshot") == 0)
+ config_set_d(CONFIG_SCREENSHOT, atoi(val));
+ else if (strcmp(key, "lock_goals") == 0)
+ config_set_d(CONFIG_LOCK_GOALS, atoi(val));
}
+ free(line);
+ }
+
fclose(fp);
dirty = 0;
option_d[CONFIG_GEOMETRY]);
fprintf(fp, "reflection %d\n",
option_d[CONFIG_REFLECTION]);
+ fprintf(fp, "multisample %d\n",
+ option_d[CONFIG_MULTISAMPLE]);
+ fprintf(fp, "mipmap %d\n",
+ option_d[CONFIG_MIPMAP]);
+ fprintf(fp, "aniso %d\n",
+ option_d[CONFIG_ANISO]);
fprintf(fp, "background %d\n",
option_d[CONFIG_BACKGROUND]);
fprintf(fp, "shadow %d\n",
option_d[CONFIG_SHADOW]);
- fprintf(fp, "audio_rate %d\n",
- option_d[CONFIG_AUDIO_RATE]);
fprintf(fp, "audio_buff %d\n",
option_d[CONFIG_AUDIO_BUFF]);
fprintf(fp, "mouse_sense %d\n",
option_d[CONFIG_MOUSE_SENSE]);
fprintf(fp, "mouse_invert %d\n",
option_d[CONFIG_MOUSE_INVERT]);
+ fprintf(fp, "vsync %d\n",
+ option_d[CONFIG_VSYNC]);
fprintf(fp, "nice %d\n",
option_d[CONFIG_NICE]);
fprintf(fp, "fps %d\n",
option_d[CONFIG_ROTATE_FAST]);
fprintf(fp, "rotate_slow %d\n",
option_d[CONFIG_ROTATE_SLOW]);
- fprintf(fp, "last_set %d\n",
- option_d[CONFIG_LAST_SET]);
+
+ fprintf(fp, "key_forward %s\n",
+ SDL_GetKeyName((SDLKey) option_d[CONFIG_KEY_FORWARD]));
+ fprintf(fp, "key_backward %s\n",
+ SDL_GetKeyName((SDLKey) option_d[CONFIG_KEY_BACKWARD]));
+ fprintf(fp, "key_left %s\n",
+ SDL_GetKeyName((SDLKey) option_d[CONFIG_KEY_LEFT]));
+ fprintf(fp, "key_right %s\n",
+ SDL_GetKeyName((SDLKey) option_d[CONFIG_KEY_RIGHT]));
fprintf(fp, "key_camera_1 %s\n",
- SDL_GetKeyName(option_d[CONFIG_KEY_CAMERA_1]));
+ SDL_GetKeyName((SDLKey) option_d[CONFIG_KEY_CAMERA_1]));
fprintf(fp, "key_camera_2 %s\n",
- SDL_GetKeyName(option_d[CONFIG_KEY_CAMERA_2]));
+ SDL_GetKeyName((SDLKey) option_d[CONFIG_KEY_CAMERA_2]));
fprintf(fp, "key_camera_3 %s\n",
- SDL_GetKeyName(option_d[CONFIG_KEY_CAMERA_3]));
+ SDL_GetKeyName((SDLKey) option_d[CONFIG_KEY_CAMERA_3]));
fprintf(fp, "key_camera_r %s\n",
- SDL_GetKeyName(option_d[CONFIG_KEY_CAMERA_R]));
+ SDL_GetKeyName((SDLKey) option_d[CONFIG_KEY_CAMERA_R]));
fprintf(fp, "key_camera_l %s\n",
- SDL_GetKeyName(option_d[CONFIG_KEY_CAMERA_L]));
+ SDL_GetKeyName((SDLKey) option_d[CONFIG_KEY_CAMERA_L]));
+
+ fprintf(fp, "key_pause %s\n",
+ SDL_GetKeyName((SDLKey) option_d[CONFIG_KEY_PAUSE]));
+ fprintf(fp, "key_restart %s\n",
+ SDL_GetKeyName((SDLKey) option_d[CONFIG_KEY_RESTART]));
+
+ fprintf(fp, "key_score_next %s\n",
+ SDL_GetKeyName((SDLKey) option_d[CONFIG_KEY_SCORE_NEXT]));
- fprintf(fp, "player %s\n", option_s[CONFIG_PLAYER]);
- fprintf(fp, "ball %s\n", option_s[CONFIG_BALL]);
- fprintf(fp, "coin %s\n", option_s[CONFIG_COIN]);
- fprintf(fp, "lang %s\n", option_s[CONFIG_LANG]);
+ if (strlen(option_s[CONFIG_PLAYER]) > 0)
+ fprintf(fp, "player %s\n", option_s[CONFIG_PLAYER]);
+ if (strlen(option_s[CONFIG_BALL]) > 0)
+ fprintf(fp, "ball_file %s\n", option_s[CONFIG_BALL]);
+ if (strlen(option_s[CONFIG_WIIMOTE_ADDR]) > 0)
+ fprintf(fp, "wiimote_addr %s\n", option_s[CONFIG_WIIMOTE_ADDR]);
+ if (strlen(option_s[CONFIG_REPLAY_NAME]) > 0)
+ fprintf(fp, "replay_name %s\n", option_s[CONFIG_REPLAY_NAME]);
+
+ fprintf(fp, "stats %d\n", option_d[CONFIG_STATS]);
+ fprintf(fp, "uniform %d\n", option_d[CONFIG_UNIFORM]);
+ fprintf(fp, "screenshot %d\n", option_d[CONFIG_SCREENSHOT]);
+ fprintf(fp, "lock_goals %d\n", option_d[CONFIG_LOCK_GOALS]);
+
+ if (config_cheat())
+ fprintf(fp, "cheat %d\n", option_d[CONFIG_CHEAT]);
fclose(fp);
}
/*---------------------------------------------------------------------------*/
-int config_mode(int f, int w, int h)
+int check_extension(const char *needle)
{
- int stereo = config_get_d(CONFIG_STEREO) ? 1 : 0;
- int stencil = config_get_d(CONFIG_REFLECTION) ? 1 : 0;
+ const GLubyte *haystack, *c;
+
+ /* Search for the given string in the OpenGL extension strings. */
+
+ for (haystack = glGetString(GL_EXTENSIONS); *haystack; haystack++)
+ {
+ for (c = (const GLubyte *) needle; *c && *haystack; c++, haystack++)
+ if (*c != *haystack)
+ break;
+
+ if ((*c == 0) && (*haystack == ' ' || *haystack == '\0'))
+ return 1;
+ }
+
+ return 0;
+}
- SDL_GL_SetAttribute(SDL_GL_STEREO, stereo);
- SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, stencil);
+int config_mode(int f, int w, int h)
+{
+ int stereo = config_get_d(CONFIG_STEREO) ? 1 : 0;
+ int stencil = config_get_d(CONFIG_REFLECTION) ? 1 : 0;
+ int buffers = config_get_d(CONFIG_MULTISAMPLE) ? 1 : 0;
+ int samples = config_get_d(CONFIG_MULTISAMPLE);
+ int vsync = config_get_d(CONFIG_VSYNC) ? 1 : 0;
+
+ SDL_GL_SetAttribute(SDL_GL_STEREO, stereo);
+ SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, stencil);
+ SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, buffers);
+ SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, samples);
+ SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, vsync);
/* Try to set the currently specified mode. */
if (SDL_SetVideoMode(w, h, 0, SDL_OPENGL | (f ? SDL_FULLSCREEN : 0)))
{
- option_d[CONFIG_FULLSCREEN] = f;
- option_d[CONFIG_WIDTH] = w;
- option_d[CONFIG_HEIGHT] = h;
- option_d[CONFIG_SHADOW] = option_d[CONFIG_SHADOW];
+ config_set_d(CONFIG_FULLSCREEN, f);
+ config_set_d(CONFIG_WIDTH, w);
+ config_set_d(CONFIG_HEIGHT, h);
glViewport(0, 0, w, h);
glClearColor(0.0f, 0.0f, 0.1f, 0.0f);
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glEnable(GL_LIGHTING);
+ glEnable(GL_BLEND);
+
+ glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,
+ GL_SEPARATE_SPECULAR_COLOR);
+ glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
+
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glDepthFunc(GL_LEQUAL);
+
+ /*
+ * Mac OS X might still need this, because apparently SDL doesn't do
+ * SDL_GL_SWAP_CONTROL on OS X. TODO: investigate.
+ */
+#if 0
+ if (vsync) sync_init();
+#endif
+
+ /* If GL supports multisample, and SDL got a multisample buffer... */
+
+#ifdef GL_ARB_multisample
+ if (check_extension("ARB_multisample"))
+ {
+ SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &buffers);
+ if (buffers)
+ glEnable(GL_MULTISAMPLE_ARB);
+ }
+#endif
return 1;
}
return config_mode(f, w, h);
}
+ /* If the mode failed, try decreasing the level of multisampling. */
+
+ else if (buffers)
+ {
+ config_set_d(CONFIG_MULTISAMPLE, samples / 2);
+ return config_mode(f, w, h);
+ }
+
/* If that mode failed, try it without reflections. */
else if (stencil)
/*---------------------------------------------------------------------------*/
-static char data_path[MAXSTR];
-static char user_path[MAXSTR];
+static float ms = 0;
+static int fps = 0;
+static int last = 0;
+static int ticks = 0;
+static int frames = 0;
-/*
- * Given a path and a file name relative to that path, create an
- * absolute path name and return a temporary pointer to it.
- */
-static const char *config_file(const char *path, const char *file)
+int config_perf(void)
{
- static char absolute[MAXSTR];
-
- size_t d = strlen(path);
-
- strncpy(absolute, path, MAXSTR - 1);
- strncat(absolute, "/", MAXSTR - d - 1);
- strncat(absolute, file, MAXSTR - d - 2);
-
- return absolute;
+ return fps;
}
-static int config_test(const char *path, const char *file)
+void config_swap(void)
{
- if (file)
- {
- FILE *fp;
+ int dt;
- if ((fp = fopen(config_file(path, file), "r")))
- {
- fclose(fp);
- return 1;
- }
- return 0;
- }
- return 1;
-}
+ SDL_GL_SwapBuffers();
-const char *config_data(const char *file)
-{
- return config_file(data_path, file);
-}
+ /* Accumulate time passed and frames rendered. */
-const char *config_user(const char *file)
-{
- return config_file(user_path, file);
-}
+ dt = (int) SDL_GetTicks() - last;
-/*---------------------------------------------------------------------------*/
+ frames += 1;
+ ticks += dt;
+ last += dt;
-/*
- * Attempt to find the game data directory. Search the command line
- * paramater, the environment, and the hard-coded default, in that
- * order. Confirm it by checking for presense of the named file.
- */
-int config_data_path(const char *path, const char *file)
-{
- char *dir;
+ /* Average over 250ms. */
- if (path && config_test(path, file))
+ if (ticks > 1000)
{
- strncpy(data_path, path, MAXSTR);
- return 1;
- }
+ /* Round the frames-per-second value to the nearest integer. */
- if ((dir = getenv("NEVERBALL_DATA")) && config_test(dir, file))
- {
- strncpy(data_path, dir, MAXSTR);
- return 1;
- }
+ double k = 1000.0 * frames / ticks;
+ double f = floor(k);
+ double c = ceil (k);
- if (CONFIG_DATA && config_test(CONFIG_DATA, file))
- {
- strncpy(data_path, CONFIG_DATA, MAXSTR);
- return 1;
- }
+ /* Compute frame time and frames-per-second stats. */
- return 0;
-}
+ fps = (int) ((c - k < k - f) ? c : f);
+ ms = (float) ticks / (float) frames;
-/*
- * Determine the location of the user's home directory. Ensure there
- * is a directory there for storing configuration, high scores, and
- * replays.
- *
- * HACK: under Windows just assume the user has permission to write to
- * the data directory. This is more reliable than trying to devine
- * anything reasonable from the environment.
- */
-int config_user_path(const char *file)
-{
-#ifdef _WIN32
- size_t d = strlen(CONFIG_USER);
-
- strncpy(user_path, data_path, MAXSTR - 1);
- strncat(user_path, "\\", MAXSTR - d - 1);
- strncat(user_path, CONFIG_USER, MAXSTR - d - 2);
+ /* Reset the counters for the next update. */
- if ((mkdir(user_path) == 0) || (errno = EEXIST))
- if (config_test(user_path, file))
- return 1;
-#else
- char *dir;
+ frames = 0;
+ ticks = 0;
- if ((dir = getenv("HOME")))
- {
- size_t d = strlen(dir);
+ /* Output statistics if configured. */
- strncpy(user_path, getenv("HOME"), MAXSTR - 1);
- strncat(user_path, "/", MAXSTR - d - 1);
- strncat(user_path, CONFIG_USER, MAXSTR - d - 2);
+ if (option_d[CONFIG_STATS])
+ fprintf(stdout, "%4d %8.4f\n", fps, ms);
}
-
- if ((mkdir(user_path, 0777) == 0) || (errno = EEXIST))
- if (config_test(user_path, file))
- return 1;
-#endif
-
- return 0;
}
/*---------------------------------------------------------------------------*/
void config_tgl_d(int i)
{
option_d[i] = (option_d[i] ? 0 : 1);
+ dirty = 1;
}
int config_tst_d(int i, int d)
strncpy(dst, option_s[i], len);
}
-const char * config_simple_get_s(int i)
-{
- return option_s[i];
-}
-
/*---------------------------------------------------------------------------*/
static int grabbed = 0;
-static int paused = 0;
-void config_set_grab(void)
+void config_set_grab(int w)
{
- SDL_WarpMouse(config_get_d(CONFIG_WIDTH) / 2,
- config_get_d(CONFIG_HEIGHT) / 2);
+ if (w)
+ {
+ SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
+
+ SDL_WarpMouse(config_get_d(CONFIG_WIDTH) / 2,
+ config_get_d(CONFIG_HEIGHT) / 2);
+
+ SDL_EventState(SDL_MOUSEMOTION, SDL_ENABLE);
+ }
+
SDL_WM_GrabInput(SDL_GRAB_ON);
SDL_ShowCursor(SDL_DISABLE);
+
grabbed = 1;
}
return grabbed;
}
-int config_get_pause(void)
+/*---------------------------------------------------------------------------*/
+
+int config_cheat(void)
{
- return paused;
+ return config_get_d(CONFIG_CHEAT);
}
-void config_set_pause(void)
+void config_set_cheat(void)
{
- Mix_PauseMusic();
- paused = 1;
-
- if (grabbed)
- {
- SDL_ShowCursor(SDL_ENABLE);
- SDL_WM_GrabInput(SDL_GRAB_OFF);
- }
+ config_set_d(CONFIG_CHEAT, 1);
}
-void config_clr_pause(void)
+void config_clr_cheat(void)
{
- Mix_ResumeMusic();
- paused = 0;
-
- if (grabbed)
- {
- SDL_WM_GrabInput(SDL_GRAB_ON);
- SDL_ShowCursor(SDL_DISABLE);
- }
+ config_set_d(CONFIG_CHEAT, 0);
}
-void config_tgl_pause(void)
+/*---------------------------------------------------------------------------*/
+
+int config_screenshot(void)
{
- if (paused)
- config_clr_pause();
- else
- config_set_pause();
+ return ++option_d[CONFIG_SCREENSHOT];
}
+
/*---------------------------------------------------------------------------*/
void config_push_persp(float fov, float n, float f)
GLdouble s = sin(r);
GLdouble c = cos(r) / s;
- GLdouble a = ((GLdouble) option_d[CONFIG_WIDTH] /
+ GLdouble a = ((GLdouble) option_d[CONFIG_WIDTH] /
(GLdouble) option_d[CONFIG_HEIGHT]);
glMatrixMode(GL_PROJECTION);