not tested version of locale-support code

refactoring
This commit is contained in:
p.kosyh 2009-09-05 04:44:45 +00:00
parent 91ddbce2dd
commit 7652f176b9
27 changed files with 2080 additions and 1511 deletions

View file

@ -6,6 +6,7 @@ STEADPATH=./stead
THEMESPATH=./themes
GAMESPATH=./games
ICONPATH=./icon
LANGPATH=./languages
DOCPATH=
LUA_CFLAGS=$(shell pkg-config --cflags lua5.1)

View file

@ -8,6 +8,7 @@ THEMESPATH=$(STEADPATH)/themes
GAMESPATH=$(STEADPATH)/games
ICONPATH=$(DESTDIR)$(PREFIX)/share/pixmaps
DOCPATH=$(DESTDIR)$(PREFIX)/share/doc/instead
LANGPATH=$(STEADPATH)/languages
LUA_CFLAGS=$(shell pkg-config --cflags lua5.1)
LUA_LFLAGS=$(shell pkg-config --libs lua5.1)
@ -23,8 +24,8 @@ SDL_LFLAGS=$(shell sdl-config --libs) -lSDL_ttf -lSDL_mixer -lSDL_image
CFLAGS += -Wall -D_HAVE_ICONV -DRUSSIAN
INSTALLD=install -d -m 0775
INSTALL=install -m 0775
INSTALLD=install -d -m 0755
INSTALL=install -m 0755
EXE=
PLATFORM=unix.c
RESOURCES=

8
languages/Makefile Normal file
View file

@ -0,0 +1,8 @@
include ../Rules.make
clean:
all:
install:
install -d -m0755 $(LANGPATH)
for f in *.ini; do \
install -m0755 $$f $(LANGPATH)/$$f;\
done

View file

@ -0,0 +1,7 @@
include ../Rules.make
clean:
all:
install:
if not exist ..\bin\languages mkdir ..\bin\languages
copy /Y *.ini ..\bin\languages

107
languages/en.ini Normal file
View file

@ -0,0 +1,107 @@
;$Name:English$
UNKNOWN_ERROR = Unknown error.
ERROR_MENU = Error while loading game:\n\
'%s'\n\
\n\
<a:/select>Ok</a>
WARNING_MENU = Error while processing game:\n\
'%s'\n\
\n\
<a:/resume>Ok</a>
SAVE_SLOT_EMPTY = empty
SELECT_LOAD_MENU = Load game\n\n
AUTOSAVE_SLOT = Autosave
BROKEN_SLOT = error
SELECT_SAVE_MENU = Save game\n\n
MAIN_MENU = \
<a:/resume>Resume game</a>\n\
<a:/select>Select game</a>\n\
<a:/themes>Select theme</a>\n\
<a:/new>Restart game</a>\n\
<a:/load_menu>Load game</a>\n\
<a:/save_menu>Save game</a>\n\
<a:/about>About</a>\n\
<a:/settings>Settings</a>\n\
<a:/ask_quit>Quit</a>
ABOUT_MENU = \
INSTEAD SDL - %s\n\
\n\
Written by Peter Kosyh '2009\n\
Ported to Windows by Ilja Ryndin\n\
\n\
Homepage:\n\
<u>http://instead.googlecode.com</u>\n\
\n\
<a:/main>Back</a>
BACK_MENU = <a:/main>Back</a>
ON = on
OFF = off
SELECT_GAME_MENU = Select game to play\n\n
SELECT_THEME_MENU = Select theme\n\n
SETTINGS_MENU = \
Volume\n\
<a:/vol--><<</a><a:/vol-><</a> <a:/mtoggle>%d%%</a> <a:/vol+>></a><a:/vol++>>></a>\n\
\n\
Quality\n\
<a:/hz-><<</a> %dHz <a:/hz+>>></a>\n\
\n\
Music: <a:/music>%s</a>\n\
Click sound: <a:/click>%s</a>\n\
\n\
Full Screen: <a:/fs>%s</a>\n\
Font scaling: <a:/fs--><<</a>%d<a:/fs++>>></a>\n\
Refs highlighting: <a:/hl>%s</a>\n\
Motion mode: <a:/motion>%s</a>\n\
Mouse filter: <a:/filter>%s</a>\n\
\n\
Language: <a:/lang--><<</a>%s<a:/lang++>>></a>\n\
Custom game themes: <a:/owntheme>%s</a>\n\
Аutosave: <a:/autosave>%s</a>\n\
\n\
<a:/main>Apply</a>
OWN_THEME_MENU = \
Warning!!!\n\
\n\
Current game have custom theme.\n\
So, changes will be ignored.\n\
\n\
<i>You can disable custom themes\n\
in settings menu.</i>\n\
\n\
<a:/resume>Ok</a>
CUSTOM_THEME_MENU = \
Warning!!!\n\
\n\
This game have custom theme, but custom theme setting is disabled. \
Game may look differ than author's design.\n\
\n\
<i>You can enable custom theme support in settings menu.</i>\n\
\n\
<a:/resume>Ok</a>
QUIT_MENU = \
Really quit?\n\
\n\
<a:/quit>Yes</a> | <a:/main>No</a>
SAVED_MENU = \
Current Game saved!\n\
\n\
<a:/main>Ok</a>
NOGAMES_MENU = \
No games found. \n\
Please, put any game in the this directory:\n'%s'
NOTHEMES_MENU = \
No themes found.\n\
Please, write any theme in this directory:\n'%s'

108
languages/ru.ini Normal file
View file

@ -0,0 +1,108 @@
;$Name:Русский$
UNKNOWN_ERROR = Неизвестная ошибка.
ERROR_MENU = Во время инициализации игры произошла ошибка:\n\
'%s'\n\
\n\
<a:/select>Да</a>
WARNING_MENU = Во время работы игры произошла ошибка:\n\
'%s'\n\
\n\
<a:/resume>Да</a>
SAVE_SLOT_EMPTY = пусто
SELECT_LOAD_MENU = Загрузите игру\n\n
AUTOSAVE_SLOT = Автосохранение
BROKEN_SLOT = ошибка
SELECT_SAVE_MENU = Сохраните игру\n\n
MAIN_MENU = \
<a:/resume>Вернуться в игру</a>\n\
<a:/select>Выбор игры</a>\n\
<a:/themes>Выбор темы</a>\n\
<a:/new>Начать заново</a>\n\
<a:/load_menu>Загрузить игру</a>\n\
<a:/save_menu>Сохранить игру</a>\n\
<a:/about>Информация</a>\n\
<a:/settings>Настройки</a>\n\
<a:/ask_quit>Выход</a>
ABOUT_MENU = \
INSTEAD SDL - %s\n\
\n\
Интерпретатор простых\n\
текстовых приключений:\n\
Косых П.А. '2009\n\
\n\
Адаптация для Windows:\n\
Рындин И.В. '2009\n\
\n\
Сайт проекта:\n\
<u>http://instead.googlecode.com</u>\n\
\n\
<a:/main>Назад</a>
BACK_MENU = <a:/main>Назад</a>
ON = Да
OFF = Нет
SETTINGS_MENU = \
Громкость\n\
<a:/vol--><<</a><a:/vol-><</a> <a:/mtoggle>%d%%</a> <a:/vol+>></a><a:/vol++>>></a>\n\
\n\
Качество звука\n<a:/hz-><<</a> %dГц <a:/hz+>>></a>\n\
\n\
Музыка: <a:/music>%s</a>\n\
Звук щелчка: <a:/click>%s</a>\n\
\n\
Полный экран: <a:/fs>%s</a>\n\
Масштаб шрифта: <a:/fs--><<</a>%d<a:/fs++>>></a>\n\
Подсветка ссылок: <a:/hl>%s</a>\n\
Режим прокрутки: <a:/motion>%s</a>\n\
Фильтр мышки: <a:/filter>%s</a>\n\
\n\
Язык интерфейса: <a:/lang--><<</a>%s<a:/lang++>>></a>\n\
Собственные темы игр: <a:/owntheme>%s</a>\n\
Автосохранение: <a:/autosave>%s</a>\n\
\n\
<a:/main>Применить</a>
CUSTOM_THEME_MENU = \
Внимание!!!\n\
\n\
Игра содержит собственную тему, но поддержка собственных тем отключена в настройках. \
Игра может выглядеть не так, как задумывал ее автор.\n\
\n\
<i>Вы можете разрешить возможность переопределения тем в настройках.</i>\n\
\n\
<a:/resume>Да</a>
OWN_THEME_MENU = \
Внимание!!!\n\
\n\
Выбранная игра переопределяет тему. Изменения не вступят в силу.\n\
\n\
<i>Вы можете запретить возможность переопределения тем в настройках.</i>\n\
\n\
<a:/resume>Да</a>
QUIT_MENU = \
На самом деле выйти?\n\
\n\
<a:/quit>Да</a> | <a:/main>Нет</a>
SELECT_GAME_MENU = Выбор игры\n\n
SELECT_THEME_MENU = Выбор темы\n\n
SAVED_MENU = \
Игра сохранена!\n\
\n\
<a:/main>Да</a>
NOGAMES_MENU = \
Не найдена ни одна игра.\n\
Пожалуйста, скопируйте хотя бы одну игру в каталог:\n'%s'
NOTHEMES_MENU = \
Не найдена ни одна тема.\n\
Пожалуйста, скопируйте хотя бы одну тему в каталог:\n'%s'

View file

@ -1,10 +1,10 @@
include ../../Rules.make
CFLAGS += $(SDL_CFLAGS) $(LUA_CFLAGS) -DSTEAD_PATH=\"${STEADPATH}/\" -DGAMES_PATH=\"${GAMESPATH}/\" -DTHEMES_PATH=\"${THEMESPATH}/\" -DVERSION=$(VERSION) -DICON_PATH=\"${ICONPATH}/\"
CFLAGS += $(SDL_CFLAGS) $(LUA_CFLAGS) -DLANG_PATH=\"${LANGPATH}/\" -DSTEAD_PATH=\"${STEADPATH}/\" -DGAMES_PATH=\"${GAMESPATH}/\" -DTHEMES_PATH=\"${THEMESPATH}/\" -DVERSION=$(VERSION) -DICON_PATH=\"${ICONPATH}/\"
LDFLAGS += $(SDL_LFLAGS) $(LUA_LFLAGS)
SRC := graphics.c input.c game.c main.c instead.c sound.c SDL_rotozoom.c $(PLATFORM)
SRC := graphics.c input.c game.c main.c instead.c sound.c SDL_rotozoom.c config.c themes.c menu.c util.c $(PLATFORM)
OBJ := $(patsubst %.c, %.o, $(SRC))

79
src/sdl-instead/config.c Normal file
View file

@ -0,0 +1,79 @@
#include "externals.h"
#include "internals.h"
int opt_fsize = 0;
#ifndef MAEMO
int opt_fs = 0;
int opt_owntheme = 1;
int opt_hl = 1;
#else
int opt_fs = 1;
int opt_owntheme = 0;
int opt_hl = 0;
#endif
int opt_hz = 22050;
int opt_vol = 127;
int opt_motion = 1;
int opt_click = 1;
int opt_music = 1;
int opt_autosave = 1;
int opt_filter = 1;
char *opt_game = NULL;
char *opt_theme = NULL;
char *opt_lang = NULL;
static struct parser cfg_parser[] = {
{ "hz", parse_int, &opt_hz },
{ "fs", parse_int, &opt_fs },
{ "vol", parse_int, &opt_vol },
{ "hl", parse_int, &opt_hl },
{ "game", parse_string, &opt_game },
{ "theme", parse_string, &opt_theme },
{ "autosave", parse_int, &opt_autosave },
{ "motion", parse_int, &opt_motion },
{ "click", parse_int, &opt_click },
{ "music", parse_int, &opt_music },
{ "fscale", parse_int, &opt_fsize },
{ "filter", parse_int, &opt_filter },
{ "owntheme", parse_int, &opt_owntheme },
{ "lang", parse_string, &opt_lang },
{ NULL, },
};
static int cfg_parse(const char *path)
{
return parse_ini(path, cfg_parser);
}
int cfg_load(void)
{
char *p = game_cfg_path();
if (!p)
return -1;
if (access(p, R_OK))
return 0;
return cfg_parse(p);
}
int cfg_save(void)
{
FILE *fp;
char *p = game_cfg_path();
if (!p)
return -1;
fp = fopen(p, "w");
if (!fp)
return -1;
fprintf(fp, "fs = %d\nhl = %d\nhz = %d\nvol = %d\nautosave = %d\n\
game = %s\nfscale = %d\nmotion = %d\n\
click = %d\nmusic = %d\ntheme = %s\n\
filter = %d\nowntheme = %d\nlang = %s",
opt_fs, opt_hl, opt_hz, opt_vol, opt_autosave,
curgame_dir?curgame_dir:"", opt_fsize, opt_motion,
opt_click, opt_music, curtheme_dir?curtheme_dir:DEFAULT_THEME,
opt_filter, opt_owntheme, opt_lang);
fclose(fp);
return 0;
}

24
src/sdl-instead/config.h Normal file
View file

@ -0,0 +1,24 @@
#ifndef __CONFIG_H_INCLUDED
#define __CONFIG_H_INCLUDED
#define FONT_SZ(v) ((v) * (1.0f + ((0.1f * opt_fsize))))
extern int opt_fsize;
extern int opt_fs;
extern int opt_owntheme;
extern int opt_hl;
extern int opt_hz;
extern int opt_vol;
extern int opt_motion;
extern int opt_click;
extern int opt_music;
extern int opt_autosave;
extern int opt_filter;
extern char *opt_game;
extern char *opt_theme;
extern char *opt_lang;
extern int cfg_load(void);
extern int cfg_save(void);
#endif

View file

@ -0,0 +1,41 @@
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include <SDL_mutex.h>
#include <SDL_mixer.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
// #include <libintl.h>
#include <unistd.h>
#ifdef _HAVE_ICONV
#include <iconv.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <pwd.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdio.h>
#include <errno.h>
#include <sys/fcntl.h>
#include <string.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include <time.h>

File diff suppressed because it is too large Load diff

View file

@ -5,46 +5,61 @@
#define GAMES_PATH "./games"
#endif
#define DEFAULT_THEME "default"
#ifndef THEMES_PATH
#define THEMES_PATH "./themes"
#endif
#define MAIN_FILE "main.lua"
#define THEME_FILE "theme.ini"
#define MENU_GAMES_MAX 8
#define MENU_THEMES_MAX 8
#define FONT_MIN_SZ 8
#define FONT_MAX_SZ 64
#define MAX_SAVE_SLOTS 6
extern char *game_local_games_path(void);
extern char *game_local_themes_path(void);
extern int cfg_load(void);
extern int cfg_save(void);
extern char *opt_game;
extern int nosound_sw;
extern int alsa_sw;
extern int fullscreen_sw;
extern int window_sw;
extern int opt_fs;
extern char *opt_theme;
extern char *curtheme;
extern int game_theme_select(const char *name);
extern int game_load_theme(const char *path);
extern int game_init(const char *game);
extern void game_done(void);
extern int game_loop(void);
extern int nosound_sw;
extern int alsa_sw;
extern int fullscreen_sw;
extern int window_sw;
extern int game_own_theme; /* current game has own theme */
extern char *err_msg; /* last error message */
extern char game_cwd[]; /* current game cwd */
extern char *curgame_dir;
extern char *game_local_games_path(void);
extern int game_theme_select(const char *name);
extern int game_init(const char *game);
extern int game_loop(void);
extern void game_done(void);
extern int game_load_theme(const char *path);
extern void game_music_player(void);
extern void game_stop_mus(int ms);
extern int game_change_vol(int d, int val);
extern int game_change_hz(int hz);
extern int games_lookup(const char *path);
extern void game_err_msg(const char *s);
extern int game_error(const char *name);
extern int game_restart(void);
extern int game_select(const char *name);
extern int game_cmd(char *cmd);
extern void game_menu(int nr); /* select and show menu */
extern void game_menu_box(int show, const char *txt); /* show menu */
extern int game_load(int nr);
extern int game_save(int nr);
extern char *game_cfg_path(void);
extern char *game_save_path(int rc, int nr);
extern char *game_locale(void);
struct game {
char *path;
char *name;
char *dir;
};
extern struct game *games;
extern int games_nr;
extern int games_lookup(const char *path);
extern int themes_lookup(const char *path);
extern void game_err_msg(const char *s);
extern int game_error(const char *name);
#endif

View file

@ -1,11 +1,5 @@
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include <SDL_mutex.h>
#include "SDL_rotozoom.h"
#include "input.h"
#include "graphics.h"
#include "math.h"
#include "externals.h"
#include "internals.h"
static SDL_Surface *screen;

View file

@ -1,7 +1,5 @@
#include <SDL.h>
#include "input.h"
#include <strings.h>
#include <stdio.h>
#include "externals.h"
#include "internals.h"
void push_user_event(void (*p) (void*), void *data)
{

View file

@ -2,20 +2,9 @@
#define STEAD_PATH "./stead"
#endif
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
// #include <libintl.h>
#include <unistd.h>
#include "gui.h"
#ifdef _HAVE_ICONV
#include <iconv.h>
#endif
#include "game.h"
#include "externals.h"
#include "internals.h"
/* the Lua interpreter */
char *fromgame(const char *s);

View file

@ -0,0 +1,10 @@
#include "graphics.h"
#include "sound.h"
#include "game.h"
#include "themes.h"
#include "menu.h"
#include "config.h"
#include "input.h"
#include "util.h"
#include "instead.h"
#include "SDL_rotozoom.h"

View file

@ -1,10 +1,5 @@
#include <unistd.h>
#include <stdlib.h>
#include "graphics.h"
#include "game.h"
#include <stdio.h>
#include <sys/fcntl.h>
#include <string.h>
#include "externals.h"
#include "internals.h"
extern int debug_init(void);
extern void debug_done(void);
@ -47,7 +42,6 @@ int main(int argc, char **argv)
}
if (debug_sw) {
debug_init();
}
@ -56,7 +50,14 @@ int main(int argc, char **argv)
opt_fs = 0;
if (fullscreen_sw)
opt_fs = 1;
menu_langs_lookup(LANG_PATH);
if (!langs_nr) {
fprintf(stderr, "No languages found in: %s.\n", LANG_PATH);
exit(1);
}
if (games_sw)
games_lookup(games_sw);
@ -79,7 +80,7 @@ int main(int argc, char **argv)
if (opt_theme)
game_theme_select(opt_theme);
if (!curtheme)
if (!curtheme_dir)
game_theme_select(DEFAULT_THEME);
if (game_init(opt_game)) {

615
src/sdl-instead/menu.c Normal file
View file

@ -0,0 +1,615 @@
#include "externals.h"
#include "internals.h"
#ifdef RUSSIAN
//#include "menu-ru.h"
#else
//#include "menu-en.h"
#endif
static int restart_needed = 0;
static int games_menu_from = 0;
static int themes_menu_from = 0;
static int cur_lang = 0;
int cur_menu = 0;
char *UNKNOWN_ERROR = NULL;
char *ERROR_MENU = NULL;
char *WARNING_MENU = NULL;
char *SAVE_SLOT_EMPTY = NULL;
char *SELECT_LOAD_MENU = NULL;
char *AUTOSAVE_SLOT = NULL;
char *BROKEN_SLOT = NULL;
char *SELECT_SAVE_MENU = NULL;
char *MAIN_MENU = NULL;
char *ABOUT_MENU = NULL;
char *BACK_MENU = NULL;
char *SETTINGS_MENU = NULL;
char *CUSTOM_THEME_MENU = NULL;
char *OWN_THEME_MENU = NULL;
char *SELECT_GAME_MENU = NULL;
char *SELECT_THEME_MENU = NULL;
char *SAVED_MENU = NULL;
char *NOGAMES_MENU = NULL;
char *NOTHEMES_MENU = NULL;
char *QUIT_MENU = NULL;
char *ON = NULL;
char *OFF = NULL;
static char menu_buff[4096];
static char *slot_name(const char *path)
{
struct stat st;
int brk = 0;
char *l; char line[1024];
FILE *fd = fopen(path, "r");
if (!fd)
return NULL;
while ((l = fgets(line, sizeof(line), fd)) && !brk) {
l = parse_tag(l, "$Name:", "--", &brk);
if (l) {
char *s = fromgame(l);
free(l);
return s;
}
}
fclose(fd);
if (stat(path, &st))
return NULL;
l = ctime(&st.st_ctime);
if (!l)
return NULL;
l[strcspn(l,"\n")] = 0;
return strdup(l);
}
static void load_menu(void)
{
int i;
*menu_buff = 0;
sprintf(menu_buff, SELECT_LOAD_MENU);
for (i = 0; i < MAX_SAVE_SLOTS; i ++) {
char tmp[PATH_MAX];
char *s = game_save_path(0, i);
if (!s || access(s, R_OK)) {
if (!i)
continue;
snprintf(tmp, sizeof(tmp), "<l>%d - %s\n</l>", i, SAVE_SLOT_EMPTY);
} else {
char *name;
if (!i)
name = strdup(AUTOSAVE_SLOT);
else
name = slot_name(s);
if (!name)
snprintf(tmp, sizeof(tmp), "<l>%d - %s</l>\n", i, BROKEN_SLOT);
else {
snprintf(tmp, sizeof(tmp), "<l>%d - <a:/load%d>%s</a></l>\n", i, i, name);
free(name);
}
}
strcat(menu_buff, tmp);
}
strcat(menu_buff,"\n<a:/resume>Отмена</a>");
}
static void save_menu(void)
{
int i;
*menu_buff = 0;
sprintf(menu_buff, SELECT_SAVE_MENU);
for (i = 1; i < MAX_SAVE_SLOTS; i ++) {
char tmp[PATH_MAX];
char *s = game_save_path(0, i);
if (!s || access(s, R_OK))
snprintf(tmp, sizeof(tmp), "<l>%d - <a:/save%d>%s</a></l>\n", i, i, SAVE_SLOT_EMPTY);
else {
char *name;
if (!i)
name = strdup(AUTOSAVE_SLOT);
else
name = slot_name(s);
if (!name)
snprintf(tmp, sizeof(tmp), "<l>%d - <a:/save%d>%s</a></l>\n", i, i, BROKEN_SLOT);
else {
snprintf(tmp, sizeof(tmp), "<l>%d - <a:/save%d>%s</a></l>\n", i, i, name);
free(name);
}
}
strcat(menu_buff, tmp);
}
strcat(menu_buff,"\n<a:/resume>Отмена</a>");
}
static void games_menu(void)
{
int i;
*menu_buff = 0;
sprintf(menu_buff, SELECT_GAME_MENU);
for (i = games_menu_from; i < games_nr && i - games_menu_from < MENU_GAMES_MAX; i ++) {
char tmp[PATH_MAX];
if (curgame_dir && !strcmp(games[i].dir, curgame_dir))
snprintf(tmp, sizeof(tmp), "<a:/resume><b>%s</b></a>\n", games[i].name);
else
snprintf(tmp, sizeof(tmp), "<a:%s>%s</a>\n", games[i].dir, games[i].name);
strcat(menu_buff, tmp);
}
if (!games_nr)
sprintf(menu_buff, NOGAMES_MENU, GAMES_PATH);
strcat(menu_buff,"\n");
if (games_menu_from)
strcat(menu_buff,"<a:/games_prev><<</a> ");
strcat(menu_buff, BACK_MENU);
if (games_menu_from + MENU_GAMES_MAX < games_nr)
strcat(menu_buff," <a:/games_next>>></a>");
}
static void themes_menu(void)
{
int i;
*menu_buff = 0;
sprintf(menu_buff, SELECT_THEME_MENU);
for (i = themes_menu_from; i < themes_nr && i - themes_menu_from < MENU_THEMES_MAX; i ++) {
char tmp[PATH_MAX];
if (curtheme_dir && !strcmp(themes[i].dir, curtheme_dir))
snprintf(tmp, sizeof(tmp), "<a:/resume><b>%s</b></a>\n", themes[i].name);
else
snprintf(tmp, sizeof(tmp), "<a:%s>%s</a>\n", themes[i].dir, themes[i].name);
strcat(menu_buff, tmp);
}
if (!themes_nr)
sprintf(menu_buff, NOTHEMES_MENU, THEMES_PATH);
strcat(menu_buff,"\n");
if (themes_menu_from)
strcat(menu_buff,"<a:/themes_prev><<</a> ");
strcat(menu_buff, BACK_MENU);
if (themes_menu_from + MENU_THEMES_MAX < themes_nr)
strcat(menu_buff," <a:/themes_next>>></a>");
}
char *game_menu_gen(void)
{
if (cur_menu == menu_main) {
snprintf(menu_buff, sizeof(menu_buff), MAIN_MENU);
} else if (cur_menu == menu_about) {
snprintf(menu_buff, sizeof(menu_buff), ABOUT_MENU, VERSION);
} else if (cur_menu == menu_settings) {
snprintf(menu_buff, sizeof(menu_buff), SETTINGS_MENU,
snd_vol_to_pcn(snd_volume_mus(-1)), snd_hz(), opt_music?ON:OFF, opt_click?ON:OFF,
opt_fs?ON:OFF, opt_fsize, opt_hl?ON:OFF, opt_motion?ON:OFF, opt_filter?ON:OFF,
langs[cur_lang].name, opt_owntheme?ON:OFF, opt_autosave?ON:OFF);
} else if (cur_menu == menu_askquit) {
snprintf(menu_buff, sizeof(menu_buff), QUIT_MENU);
} else if (cur_menu == menu_saved) {
snprintf(menu_buff, sizeof(menu_buff),
SAVED_MENU);
} else if (cur_menu == menu_games) {
games_menu();
} else if (cur_menu == menu_themes) {
themes_menu();
} else if (cur_menu == menu_own_theme) {
snprintf(menu_buff, sizeof(menu_buff),
OWN_THEME_MENU);
} else if (cur_menu == menu_custom_theme) {
snprintf(menu_buff, sizeof(menu_buff),
CUSTOM_THEME_MENU);
} else if (cur_menu == menu_load) {
load_menu();
} else if (cur_menu == menu_save) {
save_menu();
} else if (cur_menu == menu_error) {
snprintf(menu_buff, sizeof(menu_buff),
ERROR_MENU, err_msg?err_msg:UNKNOWN_ERROR);
game_err_msg(NULL);
} else if (cur_menu == menu_warning) {
snprintf(menu_buff, sizeof(menu_buff),
WARNING_MENU, err_msg?err_msg:UNKNOWN_ERROR);
game_err_msg(NULL);
}
return menu_buff;
}
int game_menu_act(const char *a)
{
int static old_vol = 0;
if (!strcmp(a, "/autosave")) {
opt_autosave ^= 1;
game_menu_box(1, game_menu_gen());
} else if (!strcmp(a, "/owntheme")) {
opt_owntheme ^= 1;
if (game_own_theme)
restart_needed = 1;
game_menu_box(1, game_menu_gen());
} else if (!strcmp(a, "/motion")) {
opt_motion ^= 1;
game_menu_box(1, game_menu_gen());
} else if (!strcmp(a, "/filter")) {
opt_filter ^= 1;
game_menu_box(1, game_menu_gen());
} else if (!strcmp(a, "/click")) {
opt_click ^= 1;
game_menu_box(1, game_menu_gen());
} else if (!strcmp(a, "/fs--")) {
opt_fsize --;
if (FONT_SZ(game_theme.font_size) > FONT_MIN_SZ) {
restart_needed = 1;
} else
opt_fsize ++;
game_menu_box(1, game_menu_gen());
} else if (!strcmp(a, "/fs++")) {
opt_fsize ++;
if (FONT_SZ(game_theme.font_size) < FONT_MAX_SZ) {
restart_needed = 1;
} else
opt_fsize --;
game_menu_box(1, game_menu_gen());
} else if (!strcmp(a, "/hl")) {
opt_hl ^= 1;
game_menu_box(1, game_menu_gen());
} else if (!strcmp(a, "/fs")) {
restart_needed = 1;
opt_fs ^= 1;
game_menu_box(1, game_menu_gen());
} else if (!strcmp(a, "/games_prev")) {
games_menu_from -= MENU_GAMES_MAX;
if (games_menu_from < 0)
games_menu_from = 0;
game_menu_box(1, game_menu_gen());
} else if (!strcmp(a, "/games_next")) {
if (games_menu_from + MENU_GAMES_MAX < games_nr)
games_menu_from += MENU_GAMES_MAX;
game_menu_box(1, game_menu_gen());
} else if (!strcmp(a, "/themes_prev")) {
themes_menu_from -= MENU_THEMES_MAX;
if (themes_menu_from < 0)
themes_menu_from = 0;
game_menu_box(1, game_menu_gen());
} else if (!strcmp(a, "/themes_next")) {
if (themes_menu_from + MENU_THEMES_MAX < themes_nr)
themes_menu_from += MENU_THEMES_MAX;
game_menu_box(1, game_menu_gen());
} else if (!strcmp(a, "/select")) {
game_menu(menu_games);
} else if (!strcmp(a, "/themes")) {
game_menu(menu_themes);
} else if (!strcmp(a, "/save_menu")) {
if (curgame_dir)
game_menu(menu_save);
} else if (!strncmp(a, "/save", 5)) {
if (!game_save(atoi(a + 5))) {
game_menu(menu_saved);
}
} else if (!strcmp(a, "/load_menu")) {
if (curgame_dir)
game_menu(menu_load);
} else if (!strncmp(a, "/load", 5)) {
int nr = atoi(a + 5);
if (!curgame_dir)
return 0;
// free_last();
game_select(curgame_dir);
game_menu_box(0, NULL);
game_load(nr);
cur_menu = menu_main;
// game_menu_box(0, NULL);
} else if (!strcmp(a, "/new")) {
char *s;
if (!curgame_dir)
return 0;
// free_last();
game_select(curgame_dir);
game_menu_box(0, NULL);
instead_eval("game:ini()");
game_cmd("look");
s = game_save_path(0, 0);
if (s && !access(s, R_OK) && opt_autosave)
unlink (s);
custom_theme_warn();
} else if (!strcmp(a,"/main")) {
if (restart_needed) {
game_restart();
restart_needed = 0;
}
game_menu(menu_main);
} else if (!strcmp(a,"/ask_quit")) {
game_menu(menu_askquit);
} else if (!strcmp(a,"/about")) {
game_menu(menu_about);
} else if (!strcmp(a,"/mtoggle")) {
if (!old_vol) {
old_vol = snd_volume_mus(-1);
game_change_vol(0, 0);
} else {
game_change_vol(0, old_vol);
old_vol = 0;
}
} else if (!strcmp(a,"/music")) {
opt_music ^= 1;
if (!opt_music) {
game_stop_mus(0);
} else
game_music_player();
game_menu_box(1, game_menu_gen());
} else if (!strcmp(a,"/resume")) {
cur_menu = menu_main;
game_menu_box(0, NULL);
} else if (!strcmp(a, "/settings")) {
game_menu(menu_settings);
} else if (!strcmp(a, "/vol--")) {
game_change_vol(-10, 0);
game_menu_box(1, game_menu_gen());
} else if (!strcmp(a, "/vol++")) {
game_change_vol(+10, 0);
game_menu_box(1, game_menu_gen());
} else if (!strcmp(a, "/vol-")) {
game_change_vol(-1, 0);
game_menu_box(1, game_menu_gen());
} else if (!strcmp(a, "/vol+")) {
game_change_vol(+1, 0);
game_menu_box(1, game_menu_gen());
} else if (!strcmp(a, "/hz-")) {
int hz = snd_hz();
if (hz == 48000)
hz = 44100;
else if (hz == 44100)
hz = 22050;
else if (hz == 22050)
hz = 11025;
else
hz = 0;
game_change_hz(hz);
game_menu_box(1, game_menu_gen());
} else if (!strcmp(a, "/hz+")) {
int hz = snd_hz();
if (hz == 11025)
hz = 22050;
else if (hz == 22050)
hz = 44100;
else if (hz == 44100)
hz = 48000;
else
hz = 0;
game_change_hz(hz);
game_menu_box(1, game_menu_gen());
} else if (!strcmp(a, "/lang++")) {
do {
cur_lang ++;
if (cur_lang >= langs_nr)
cur_lang = 0;
} while (menu_lang_select(langs[cur_lang].file));
game_menu_box(1, game_menu_gen());
} else if (!strcmp(a, "/lang--")) {
do {
cur_lang --;
if (cur_lang < 0)
cur_lang = langs_nr - 1;
} while (menu_lang_select(langs[cur_lang].file));
game_menu_box(1, game_menu_gen());
} else if (!strcmp(a,"/quit")) {
return -1;
} else if (cur_menu == menu_games) {
char *p;
p = strdup(a);
if (p) {
game_done();
if (game_init(p)) {
game_error(p);
}
free(p);
}
} else if (cur_menu == menu_themes) {
char *p;
p = strdup(a);
if (p) {
if (game_theme_select(p))
fprintf(stderr, "Can't select theme:%s:%s\n", p, strerror(errno));
char *og = curgame_dir;
game_save(-1);
game_done();
if (game_init(og))
game_error(og);
else if (curgame_dir && game_own_theme && opt_owntheme) {
game_menu(menu_own_theme);
}
free(p);
}
}
return 0;
}
void custom_theme_warn(void)
{
if (game_own_theme && !opt_owntheme) {
game_menu(menu_custom_theme);
}
}
struct lang *langs = NULL;
int langs_nr = 0;
static void lang_free(void)
{
FREE(UNKNOWN_ERROR);
FREE(ERROR_MENU);
FREE(WARNING_MENU);
FREE(SAVE_SLOT_EMPTY);
FREE(SELECT_LOAD_MENU);
FREE(AUTOSAVE_SLOT);
FREE(BROKEN_SLOT);
FREE(SELECT_SAVE_MENU);
FREE(MAIN_MENU);
FREE(ABOUT_MENU);
FREE(BACK_MENU);
FREE(SETTINGS_MENU);
FREE(CUSTOM_THEME_MENU);
FREE(OWN_THEME_MENU);
FREE(SELECT_GAME_MENU);
FREE(SELECT_THEME_MENU);
FREE(SAVED_MENU);
FREE(NOGAMES_MENU);
FREE(NOTHEMES_MENU);
FREE(QUIT_MENU);
FREE(ON);
FREE(OFF);
}
static int lang_ok(void)
{
if (UNKNOWN_ERROR && ERROR_MENU && WARNING_MENU && SAVE_SLOT_EMPTY &&
SELECT_LOAD_MENU && AUTOSAVE_SLOT && BROKEN_SLOT && SELECT_SAVE_MENU &&
MAIN_MENU && ABOUT_MENU && BACK_MENU && SETTINGS_MENU &&
CUSTOM_THEME_MENU && OWN_THEME_MENU && SELECT_GAME_MENU && SELECT_THEME_MENU &&
SAVED_MENU && NOGAMES_MENU && NOTHEMES_MENU && QUIT_MENU &&
ON && OFF)
return 0;
return -1;
}
struct parser lang_parser[] = {
{ "UNKNOWN_ERROR", parse_esc_string, &UNKNOWN_ERROR },
{ "ERROR_MENU", parse_esc_string, &ERROR_MENU },
{ "WARNING_MENU", parse_esc_string, &WARNING_MENU },
{ "SAVE_SLOT_EMPTY", parse_esc_string, &SAVE_SLOT_EMPTY },
{ "SELECT_LOAD_MENU", parse_esc_string, &SELECT_LOAD_MENU },
{ "AUTOSAVE_SLOT", parse_esc_string, &AUTOSAVE_SLOT },
{ "BROKEN_SLOT", parse_esc_string, &BROKEN_SLOT },
{ "SELECT_SAVE_MENU", parse_esc_string, &SELECT_SAVE_MENU },
{ "MAIN_MENU", parse_esc_string, &MAIN_MENU },
{ "ABOUT_MENU", parse_esc_string, &ABOUT_MENU },
{ "BACK_MENU", parse_esc_string, &BACK_MENU },
{ "SETTINGS_MENU", parse_esc_string, &SETTINGS_MENU },
{ "CUSTOM_THEME_MENU", parse_esc_string, &CUSTOM_THEME_MENU },
{ "OWN_THEME_MENU", parse_esc_string, &OWN_THEME_MENU },
{ "SELECT_GAME_MENU", parse_esc_string, &SELECT_GAME_MENU },
{ "SELECT_THEME_MENU", parse_esc_string, &SELECT_THEME_MENU },
{ "SAVED_MENU", parse_esc_string, &SAVED_MENU },
{ "NOGAMES_MENU", parse_esc_string, &NOGAMES_MENU },
{ "NOTHEMES_MENU", parse_esc_string, &NOTHEMES_MENU },
{ "QUIT_MENU", parse_esc_string, &QUIT_MENU },
{ "ON", parse_esc_string, &ON },
{ "OFF", parse_esc_string, &OFF },
{ NULL, },
};
static int lang_parse(const char *path)
{
return parse_ini(path, lang_parser);
}
static int is_lang(const char *path, const char *n)
{
char *p = getfilepath(path, n);
if (!p)
return 0;
if (access(p, F_OK))
return 0;
free(p);
if (!(p = strstr(n, ".ini")))
return 0;
if (strcmp(p, ".ini"))
return 0;
return 1;
}
static char *lang_code(const char *str)
{
char *p = strdup(str);
if (!p)
return NULL;
p[strcspn(p, ".")] = 0;
return p;
}
static char *lang_name(const char *path, const char *file)
{
int brk = 0;
char *l; char line[1024];
FILE *fd = fopen(path, "r");
if (!fd)
goto err;
while ((l = fgets(line, sizeof(line), fd)) && !brk) {
l = parse_tag(l, "$Name:", ";", &brk);
if (l)
return l;
}
fclose(fd);
err:
return lang_code(file);
}
int menu_langs_lookup(const char *path)
{
char *p;
int n = 0, i = 0;
DIR *d;
struct dirent *de;
if (!path)
return 0;
d = opendir(path);
if (!d)
return -1;
while ((de = readdir(d))) {
if (!is_lang(path, de->d_name))
continue;
n ++;
}
rewinddir(d);
if (!n)
return 0;
langs = realloc(langs, sizeof(struct lang) * (n + langs_nr));
while ((de = readdir(d)) && i < n) {
if (!is_lang(path, de->d_name))
continue;
p = getfilepath(path, de->d_name);
langs[langs_nr].path = p;
langs[langs_nr].file = lang_code(de->d_name);
langs[langs_nr].name = lang_name(p, de->d_name);
langs_nr ++;
i ++;
}
closedir(d);
return 0;
}
int menu_lang_select(const char *name)
{
int i;
char cwd[PATH_MAX];
if (!name)
return -1;
getcwd(cwd, sizeof(cwd));
chdir(game_cwd);
for (i = 0; i<langs_nr; i ++) {
if (!strcmp(langs[i].file, name)) {
lang_free();
if (lang_parse(langs[i].path) || lang_ok()) {
fprintf(stderr,"Error while loading language: %s\n", langs[i].file);
chdir(cwd);
return -1;
}
cur_lang = i;
FREE(opt_lang); opt_lang = strdup(langs[i].file);
chdir(cwd);
return 0;
}
}
chdir(cwd);
return -1;
}

View file

@ -1,105 +1,47 @@
#define UNKNOWN_ERROR "Неизвестная ошибка."
#define ERROR_MENU "Во время инициализации игры произошла ошибка:\n\
'%s'\n\
\n\
<a:/select>Да</a>"
#ifndef __MENU_H_INCLUDED
#define __MENU_H_INCLUDED
#define WARNING_MENU "Во время работы игры произошла ошибка:\n\
'%s'\n\
\n\
<a:/resume>Да</a>"
#define MENU_GAMES_MAX 8
#define MENU_THEMES_MAX 8
#define SAVE_SLOT_EMPTY "пусто"
#define SELECT_LOAD_MENU "Загрузите игру\n\n"
#define AUTOSAVE_SLOT "Автосохранение"
#define BROKEN_SLOT "ошибка"
#define SELECT_SAVE_MENU "Сохраните игру\n\n"
#define FONT_MIN_SZ 8
#define FONT_MAX_SZ 64
#define MAIN_MENU \
"<a:/resume>Вернуться в игру</a>\n\
<a:/select>Выбор игры</a>\n\
<a:/themes>Выбор темы</a>\n\
<a:/new>Начать заново</a>\n\
<a:/load_menu>Загрузить игру</a>\n\
<a:/save_menu>Сохранить игру</a>\n\
<a:/about>Информация</a>\n\
<a:/settings>Настройки</a>\n\
<a:/ask_quit>Выход</a>"
#define MAX_SAVE_SLOTS 6
#define ABOUT_MENU \
"INSTEAD SDL - "VERSION"\n\
\n\
Интерпретатор простых\n\
текстовых приключений:\n\
Косых П.А. '2009\n\
\n\
Адаптация для Windows:\n\
Рындин И.В. '2009\n\
\n\
Сайт проекта:\n\
<u>http://instead.googlecode.com</u>\n\
\n\
<a:/main>Назад</a>"
#define LANG_DEF "en.ini"
#define BACK_MENU "<a:/main>Назад</a>"
#define ON "Да"
#define OFF "Нет"
extern int cur_menu;
extern char *game_menu_gen(void);
extern int game_menu_act(const char *a);
extern void custom_theme_warn(void);
extern int menu_langs_lookup(const char *path);
extern int menu_lang_select(const char *name);
#define SETTINGS_MENU \
"Громкость\n\
<a:/vol--><<</a><a:/vol-><</a> <a:/mtoggle>%d%%</a> <a:/vol+>></a><a:/vol++>>></a>\n\
\n\
Качество звука\n<a:/hz-><<</a> %dГц <a:/hz+>>></a>\n\
\n\
Музыка: <a:/music>%s</a>\n\
Звук щелчка: <a:/click>%s</a>\n\
\n\
Полный экран: <a:/fs>%s</a>\n\
Масштаб шрифта: <a:/fs--><<</a>%d<a:/fs++>>></a>\n\
Подсветка ссылок: <a:/hl>%s</a>\n\
Режим прокрутки: <a:/motion>%s</a>\n\
Фильтр мышки: <a:/filter>%s</a>\n\
\n\
Собственные темы игр: <a:/owntheme>%s</a>\n\
Автосохранение: <a:/autosave>%s</a>\n\
\n\
<a:/main>Применить</a>"
struct lang {
char *path;
char *name;
char *file;
};
extern struct lang *langs;
extern int langs_nr;
#define CUSTOM_THEME_MENU \
"Внимание!!!\n\
\n\
Игра содержит собственную тему, но поддержка собственных тем отключена в настройках. \
Игра может выглядеть не так, как задумывал ее автор.\n\
\n\
<i>Вы можете разрешить возможность переопределения тем в настройках.</i>\n\
\n\
<a:/resume>Да</a>"
enum {
menu_main = 0,
menu_about,
menu_settings,
menu_quit,
menu_askquit,
menu_saved,
menu_games,
menu_themes,
menu_own_theme,
menu_custom_theme,
menu_load,
menu_save,
menu_error,
menu_warning,
};
#define OWN_THEME_MENU \
"Внимание!!!\n\
\n\
Выбранная игра переопределяет тему. Изменения не вступят в силу.\n\
\n\
<i>Вы можете запретить возможность переопределения тем в настройках.</i>\n\
\n\
<a:/resume>Да</a>"
#define QUIT_MENU \
"На самом деле выйти?\n\
\n\
<a:/quit>Да</a> | <a:/main>Нет</a>"
#define SELECT_GAME_MENU "Выбор игры\n\n"
#define SELECT_THEME_MENU "Выбор темы\n\n"
#define SAVED_MENU \
"Игра сохранена!\n\
\n\
<a:/main>Да</a>"
#define NOGAMES_MENU \
"Не найдена ни одна игра.\n\
Пожалуйста, скопируйте хотя бы одну игру в каталог:\n'%s'"
#define NOTHEMES_MENU \
"Не найдена ни одна тема.\n\
Пожалуйста, скопируйте хотя бы одну тему в каталог:\n'%s'"
#endif

View file

@ -1,11 +1,5 @@
#include "sound.h"
#include "input.h"
#include <SDL.h>
#include <SDL_mixer.h>
#include <stdio.h>
#include <stdlib.h>
#include "externals.h"
#include "internals.h"
Mix_Music *music = NULL;
@ -213,3 +207,13 @@ void snd_done(void)
Mix_CloseAudio();
SDL_QuitSubSystem(SDL_INIT_AUDIO);
}
int snd_vol_from_pcn(int v)
{
return (v * 127) / 100;
}
int snd_vol_to_pcn(int v)
{
return (v * 100) / 127;
}

View file

@ -24,4 +24,7 @@ extern int snd_playing_mus();
extern void snd_stop_mus(int ms);
extern int snd_volume_mus(int vol);
extern void snd_done(void);
extern int snd_vol_from_pcn(int v);
extern int snd_vol_to_pcn(int v);
#endif

438
src/sdl-instead/themes.c Normal file
View file

@ -0,0 +1,438 @@
#include "externals.h"
#include "internals.h"
char *curtheme_dir = NULL;
static int parse_gfx_mode(const char *v, void *data)
{
int *i = (int *)data;
if (!strcmp(v, "fixed"))
*i = GFX_MODE_FIXED;
else if (!strcmp(v, "embedded"))
*i = GFX_MODE_EMBEDDED;
else if (!strcmp(v, "float"))
*i = GFX_MODE_FLOAT;
else
return -1;
return 0;
}
static int parse_inv_mode(const char *v, void *data)
{
int *i = (int *)data;
if (!strcmp(v, "vertical") || !strcmp(v, "0"))
*i = INV_MODE_VERT;
else if (!strcmp(v, "horizontal") || !strcmp(v, "1"))
*i = INV_MODE_HORIZ;
else
return -1;
return 0;
}
static int parse_color(const char *v, void *data)
{
color_t *c = (color_t *)data;
return gfx_parse_color(v, c);
}
static int parse_include(const char *v, void *data)
{
int rc;
char cwd[PATH_MAX];
if (!strcmp(v, DEFAULT_THEME))
return 0;
getcwd(cwd, sizeof(cwd));
chdir(game_cwd);
rc = game_theme_load(v);
// if (!rc)
// game_theme_select(v);
chdir(cwd);
return rc;
}
struct parser cmd_parser[] = {
{ "scr.w", parse_int, &game_theme.w },
{ "scr.h", parse_int, &game_theme.h },
{ "scr.col.bg", parse_color, &game_theme.bgcol },
{ "scr.gfx.bg", parse_string, &game_theme.bg_name },
{ "scr.gfx.use", parse_string, &game_theme.use_name },
{ "scr.gfx.pad", parse_int, &game_theme.pad },
{ "scr.gfx.x", parse_int, &game_theme.gfx_x },
{ "scr.gfx.y", parse_int, &game_theme.gfx_y },
{ "scr.gfx.w", parse_int, &game_theme.max_scene_w },
{ "scr.gfx.h", parse_int, &game_theme.max_scene_h },
{ "scr.gfx.mode", parse_gfx_mode, &game_theme.gfx_mode },
{ "win.x", parse_int, &game_theme.win_x },
{ "win.y", parse_int, &game_theme.win_y },
{ "win.w", parse_int, &game_theme.win_w },
{ "win.h", parse_int, &game_theme.win_h },
{ "win.fnt.name", parse_string, &game_theme.font_name },
{ "win.fnt.size", parse_int, &game_theme.font_size },
/* compat mode directive */
{ "win.gfx.h", parse_int, &game_theme.max_scene_h },
/* here it was */
{ "win.gfx.up", parse_string, &game_theme.a_up_name },
{ "win.gfx.down", parse_string, &game_theme.a_down_name },
{ "win.col.fg", parse_color, &game_theme.fgcol },
{ "win.col.link", parse_color, &game_theme.lcol },
{ "win.col.alink", parse_color, &game_theme.acol },
{ "inv.x", parse_int, &game_theme.inv_x },
{ "inv.y", parse_int, &game_theme.inv_y },
{ "inv.w", parse_int, &game_theme.inv_w },
{ "inv.h", parse_int, &game_theme.inv_h },
{ "inv.mode", parse_inv_mode, &game_theme.inv_mode },
{ "inv.horiz", parse_inv_mode, &game_theme.inv_mode },
{ "inv.col.fg", parse_color, &game_theme.icol },
{ "inv.col.link", parse_color, &game_theme.ilcol },
{ "inv.col.alink", parse_color, &game_theme.iacol },
{ "inv.fnt.name", parse_string, &game_theme.inv_font_name },
{ "inv.fnt.size", parse_int, &game_theme.inv_font_size },
{ "inv.gfx.up", parse_string, &game_theme.inv_a_up_name },
{ "inv.gfx.down", parse_string, &game_theme.inv_a_down_name },
{ "menu.col.bg", parse_color, &game_theme.menu_bg },
{ "menu.col.fg", parse_color, &game_theme.menu_fg },
{ "menu.col.link", parse_color, &game_theme.menu_link },
{ "menu.col.alink", parse_color, &game_theme.menu_alink },
{ "menu.col.alpha", parse_int, &game_theme.menu_alpha },
{ "menu.col.border", parse_color, &game_theme.border_col },
{ "menu.bw", parse_int, &game_theme.border_w },
{ "menu.fnt.name", parse_string, &game_theme.menu_font_name },
{ "menu.fnt.size", parse_int, &game_theme.menu_font_size },
{ "menu.gfx.button", parse_string, &game_theme.menu_button_name },
{ "menu.button.x", parse_int, &game_theme.menu_button_x },
{ "menu.button.y", parse_int, &game_theme.menu_button_y },
/* compat */
{ "menu.buttonx", parse_int, &game_theme.menu_button_x },
{ "menu.buttony", parse_int, &game_theme.menu_button_y },
{ "snd.click", parse_full_path, &game_theme.click_name },
{ "include", parse_include, NULL },
{ NULL, },
};
struct game_theme game_theme = {
.w = 800,
.h = 480,
.bg_name = NULL,
.bg = NULL,
.use_name = NULL,
.use = NULL,
.font_name = NULL,
.font = NULL,
.a_up_name = NULL,
.a_down_name = NULL,
.a_up = NULL,
.a_down = NULL,
.inv_font_name = NULL,
.inv_font = NULL,
.inv_a_up_name = NULL,
.inv_a_down_name = NULL,
.inv_a_up = NULL,
.inv_a_down = NULL,
.menu_font_name = NULL,
.menu_font = NULL,
.menu_button_name = NULL,
.menu_button = NULL,
.gfx_mode = GFX_MODE_EMBEDDED,
.inv_mode = INV_MODE_VERT,
.click_name = NULL,
.click = NULL,
};
static void free_theme_strings(void)
{
struct game_theme *t = &game_theme;
FREE(t->use_name);
FREE(t->bg_name);
FREE(t->inv_a_up_name);
FREE(t->inv_a_down_name);
FREE(t->a_down_name);
FREE(t->a_up_name);
FREE(t->font_name);
FREE(t->inv_font_name);
FREE(t->menu_font_name);
FREE(t->menu_button_name);
/* FREE(t->click_name); must be reloaded, ugly :(*/
}
int game_theme_free(void)
{
free_theme_strings();
if (game_theme.font)
fnt_free(game_theme.font);
if (game_theme.inv_font)
fnt_free(game_theme.inv_font);
if (game_theme.menu_font)
fnt_free(game_theme.menu_font);
if (game_theme.a_up)
gfx_free_image(game_theme.a_up);
if (game_theme.a_down)
gfx_free_image(game_theme.a_down);
if (game_theme.inv_a_up)
gfx_free_image(game_theme.inv_a_up);
if (game_theme.inv_a_down)
gfx_free_image(game_theme.inv_a_down);
if (game_theme.use)
gfx_free_image(game_theme.use);
if (game_theme.bg)
gfx_free_image(game_theme.bg);
if (game_theme.menu_button)
gfx_free_image(game_theme.menu_button);
if (game_theme.click)
snd_free_wav(game_theme.click);
game_theme.font = game_theme.inv_font = game_theme.menu_font = NULL;
game_theme.a_up = game_theme.a_down = game_theme.use = NULL;
game_theme.inv_a_up = game_theme.inv_a_down = NULL;
game_theme.menu_button = NULL;
game_theme.bg = NULL;
game_theme.click = NULL;
// game_theme.slide = gfx_load_image("slide.png", 1);
return 0;
}
static int game_theme_init(void)
{
struct game_theme *t = &game_theme;
if (t->font_name) {
fnt_free(t->font);
if (!(t->font = fnt_load(t->font_name, FONT_SZ(t->font_size))))
goto err;
}
if (t->inv_font_name) {
fnt_free(t->inv_font);
if (!(t->inv_font = fnt_load(t->inv_font_name, FONT_SZ(t->inv_font_size))))
goto err;
}
if (t->menu_font_name) {
fnt_free(t->menu_font);
if (!(t->menu_font = fnt_load(t->menu_font_name, t->menu_font_size))) /* do not scale menu!!! */
goto err;
}
if (t->a_up_name) {
gfx_free_image(t->a_up);
if (!(t->a_up = gfx_load_image(t->a_up_name)))
goto err;
}
if (t->a_down_name) {
gfx_free_image(t->a_down);
if (!(t->a_down = gfx_load_image(t->a_down_name)))
goto err;
}
if (t->inv_a_up_name) {
gfx_free_image(t->inv_a_up);
if (!(t->inv_a_up = gfx_load_image(t->inv_a_up_name)))
goto err;
}
if (t->inv_a_down_name) {
gfx_free_image(t->inv_a_down);
if (!(t->inv_a_down = gfx_load_image(t->inv_a_down_name)))
goto err;
}
if (t->bg_name) {
gfx_free_image(t->bg);
t->bg = NULL;
if (t->bg_name[0] && !(t->bg = gfx_load_image(t->bg_name)))
goto err;
}
if (t->use_name) {
gfx_free_image(t->use);
if (!(t->use = gfx_load_image(t->use_name)))
goto err;
}
if (t->menu_button_name) {
gfx_free_image(t->menu_button);
if (!(t->menu_button = gfx_load_image(t->menu_button_name)))
goto err;
}
if (t->click_name) {
snd_free_wav(t->click);
t->click = snd_load_wav(t->click_name);
}
free_theme_strings();
if (!t->use || !t->inv_a_up || !t->inv_a_down || !t->a_down || !t->a_up ||
!t->font || !t->inv_font || !t->menu_font || !t->menu_button) {
fprintf(stderr,"Can't init theme.\n");
return -1;
}
return 0;
err:
fprintf(stderr, "Can not init theme!\n");
game_theme_free();
return -1;
}
static int theme_parse(const char *path)
{
if (parse_ini(path, cmd_parser)) {
fprintf(stderr, "Theme parsed with errors!\n");
// game_theme_free();
return -1;
}
return 0;
}
int theme_load(const char *name)
{
if (theme_parse(name))
return 0; /* no theme loaded if error in parsing */
if (game_theme_init())
return -1;
return 0;
}
struct theme *themes = NULL;
int themes_nr = 0;
static int is_theme(const char *path, const char *n)
{
int rc = 0;
char *p = getpath(path, n);
char *pp;
if (!p)
return 0;
pp = malloc(strlen(p) + strlen(THEME_FILE) + 1);
if (pp) {
strcpy(pp, p);
strcat(pp, THEME_FILE);
if (!access(pp, R_OK))
rc = 1;
free(pp);
}
free(p);
return rc;
}
static char *theme_name(const char *path, const char *d_name)
{
int brk = 0;
char *p = getfilepath(path, THEME_FILE);
if (p) {
char *l; char line[1024];
FILE *fd = fopen(p, "r");
free(p);
if (!fd)
goto err;
while ((l = fgets(line, sizeof(line), fd)) && !brk) {
l = parse_tag(l, "$Name:", ";", &brk);
if (l)
return l;
}
fclose(fd);
}
err:
return strdup(d_name);
}
int themes_lookup(const char *path)
{
char *p;
int n = 0, i = 0;
DIR *d;
struct dirent *de;
if (!path)
return 0;
d = opendir(path);
if (!d)
return -1;
while ((de = readdir(d))) {
if (!is_theme(path, de->d_name))
continue;
n ++;
}
rewinddir(d);
if (!n)
return 0;
themes = realloc(themes, sizeof(struct theme) * (n + themes_nr));
while ((de = readdir(d)) && i < n) {
/*if (de->d_type != DT_DIR)
continue;*/
if (!is_theme(path, de->d_name))
continue;
p = getpath(path, de->d_name);
themes[themes_nr].path = p;
themes[themes_nr].dir = strdup(de->d_name);
themes[themes_nr].name = theme_name(p, de->d_name);
themes_nr ++;
i ++;
}
closedir(d);
return 0;
}
static struct theme *theme_lookup(const char *name)
{
int i;
if (!name || !*name) {
if (themes_nr == 1)
return &themes[0];
}
for (i = 0; i<themes_nr; i ++) {
if (!strcmp(themes[i].dir, name)) {
return &themes[i];
}
}
return NULL;
}
int game_theme_load(const char *name)
{
struct theme *theme;
char cwd[PATH_MAX];
getcwd(cwd, sizeof(cwd));
chdir(game_cwd);
theme = theme_lookup(name);
if (!theme || chdir(theme->path) || theme_load(THEME_FILE)) {
chdir(cwd);
return -1;
}
chdir(cwd);
return 0;
}
int game_theme_select(const char *name)
{
struct theme *theme;
theme = theme_lookup(name);
if (!theme)
return -1;
curtheme_dir = theme->dir;
return 0;
}
int game_default_theme(void)
{
return game_theme_load(DEFAULT_THEME);
}

115
src/sdl-instead/themes.h Normal file
View file

@ -0,0 +1,115 @@
#ifndef __THEMES_INCLUDED_H
#define __THEMES_INCLUDED_H
#include "graphics.h"
#include "sound.h"
#define DEFAULT_THEME "default"
#ifndef THEMES_PATH
#define THEMES_PATH "./themes"
#endif
#define THEME_FILE "theme.ini"
struct game_theme {
int w;
int h;
color_t bgcol;
char *bg_name;
img_t bg;
char *use_name;
img_t use;
int pad;
int win_x;
int win_y;
int win_w;
int win_h;
char *font_name;
int font_size;
fnt_t font;
int gfx_x;
int gfx_y;
int max_scene_w;
int max_scene_h;
char *a_up_name;
char *a_down_name;
img_t a_up;
img_t a_down;
color_t fgcol;
color_t lcol;
color_t acol;
int inv_x;
int inv_y;
int inv_w;
int inv_h;
color_t icol;
color_t ilcol;
color_t iacol;
char *inv_font_name;
int inv_font_size;
fnt_t inv_font;
char *inv_a_up_name;
char *inv_a_down_name;
img_t inv_a_up;
img_t inv_a_down;
// int lstyle;
// int ilstyle;
color_t menu_bg;
color_t menu_fg;
color_t border_col;
color_t menu_link;
color_t menu_alink;
int menu_alpha;
int border_w;
char *menu_font_name;
int menu_font_size;
fnt_t menu_font;
char *menu_button_name;
img_t menu_button;
int menu_button_x;
int menu_button_y;
int gfx_mode;
int inv_mode;
char *click_name;
void *click;
};
struct theme {
char *path;
char *name;
char *dir;
};
extern struct theme *themes;
extern int themes_nr;
extern char *curtheme_dir;
extern struct game_theme game_theme;
extern int game_default_theme(void);
extern int game_theme_select(const char *name);
extern int themes_lookup(const char *path);
extern int game_theme_load(const char *name);
extern int game_theme_free(void);
extern int theme_load(const char *name);
extern char *game_local_themes_path(void);
#define GFX_MODE_FLOAT 0
#define GFX_MODE_FIXED 1
#define GFX_MODE_EMBEDDED 2
#define INV_MODE_VERT 0
#define INV_MODE_HORIZ 1
#endif

View file

@ -6,14 +6,15 @@
#include <stdio.h>
#include <errno.h>
#include <sys/fcntl.h>
#include <string.h>
#include <stdlib.h>
#include "internals.h"
#ifndef PATH_MAX
#define PATH_MAX 4096
#endif
extern char *curgame;
extern char *curgame_dir;
static char save_path[PATH_MAX];
static char local_games_path[PATH_MAX];
static char local_themes_path[PATH_MAX];
@ -24,6 +25,17 @@ void nsleep(int u)
usleep(u);
}
char *game_locale(void)
{
char *p;
char *s = strdup(getenv("LANG"));
if (!s)
return NULL;
if ((p = strchr(s, '_')))
*p = 0;
return s;
}
char *game_local_games_path(void)
{
struct passwd *pw;
@ -66,7 +78,7 @@ char *game_cfg_path(void)
char *game_save_path(int cr, int nr)
{
struct passwd *pw;
if (!curgame)
if (!curgame_dir)
return NULL;
pw = getpwuid(getuid());
if (!pw)

218
src/sdl-instead/util.c Normal file
View file

@ -0,0 +1,218 @@
#include "externals.h"
#include "util.h"
char *getfilepath(const char *d, const char *n)
{
int i = strlen(d) + strlen(n) + 3;
char *p = malloc(i);
if (p) {
strcpy(p, d);
strcat(p, "/");
strcat(p, n);
}
return p;
}
char *getpath(const char *d, const char *n)
{
char *p = getfilepath(d, n);
strcat(p, "/");
return p;
}
char *strip(char *s)
{
char *e;
while (isspace(*s))
s ++;
if (!*s)
return s;
e = s + strlen(s) - 1;
while (e != s && isspace(*e)) {
*e = 0;
e --;
}
return s;
}
static int process_cmd(char *n, char *v, struct parser *cmd_parser)
{
int i;
n = strip(n);
v = strip(v);
for (i = 0; cmd_parser[i].cmd; i++) {
if (!strcmp(cmd_parser[i].cmd, n)) {
return cmd_parser[i].fn(v, cmd_parser[i].p);
}
}
return -1;
}
static int fgetsesc(char *oline, size_t size, FILE *fp)
{
int nr = 0;
char line[1024];
*oline = 0;
*line = 0;
while (fgets(line, sizeof(line), fp)) {
int i;
nr ++;
i = strcspn(line, "\n\r");
if (!i || !line[i])
break;
if (line[i - 1] == '\\') {
line[i - 1] = 0;
strncat(oline, line, size);
size -= strlen(line);
if (size <= 0)
return nr;
} else {
break;
}
}
strncat(oline, line, size);
return nr;
}
int parse_ini(const char *path, struct parser *cmd_parser)
{
int nr;
int rc = 0;
int line_nr = 1;
FILE *fp;
char line[4096];
fp = fopen(path, "r");
if (!fp)
return -1;
while ((nr = fgetsesc(line, sizeof(line), fp))) {
char *p = line;
char *val;
int len;
line_nr += nr;
p += strspn(p, " \t");
if (*p == ';')
continue;
len = strcspn(p, "=");
if (p[len] != '=') /* just ignore it */
continue;
p[len] = 0;
val = p + len + 1;
len = strcspn(p, " \t");
p[len] = 0;
// printf("%s\n", p);
val += strspn(val, " \t");
val[strcspn(val, ";\n")] = 0;
if (process_cmd(p, val, cmd_parser)) {
rc = -1;
fprintf(stderr, "Can't process cmd '%s' on line %d : %s\n", p, line_nr - nr, strerror(errno));
}
}
fclose(fp);
return rc;
}
int parse_string(const char *v, void *data)
{
char **p = ((char **)data);
if (*p)
free(*p);
*p = strdup(v);
if (!*p)
return -1;
return 0;
}
int parse_esc_string(const char *v, void *data)
{
int esc = 0;
char *ptr;
char **p = ((char **)data);
if (*p)
free(*p);
*p = strdup(v);
if (!*p)
return -1;
for (ptr = *p; *v; v ++) {
if (esc) {
switch (*v) {
case 'n':
*ptr = '\n';
break;
case '\\':
*ptr = '\\';
break;
case 'r':
*ptr = '\n';
break;
default:
break;
}
esc = 0;
ptr ++;
continue;
} else if (*v != '\\') {
*ptr = *v;
ptr ++;
continue;
} else
esc = 1;
}
*ptr = 0;
return 0;
}
int parse_int(const char *v, void *data)
{
int *i = (int *)data;
char *eptr = NULL;
*i = strtol(v, &eptr, 0);
if (!eptr || *eptr)
return -1;
return 0;
}
int parse_full_path(const char *v, void *data)
{
char cwd[PATH_MAX];
char **p = ((char **)data);
if (*p)
free(*p);
getcwd(cwd, sizeof(cwd));
*p = malloc(strlen(v) + strlen(cwd) + 2);
if (!*p)
return -1;
strcpy(*p, cwd);
strcat(*p,"/");
strcat(*p, v);
return 0;
}
void unix_path(char *path)
{
char *p = path;
if (!path)
return;
while (*p) { /* bad bad Windows!!! */
if (*p == '\\')
*p = '/';
p ++;
}
return;
}
char *parse_tag(char *line, const char *tag, const char *comm, int *brk)
{
char *l = line;
l += strspn(l, " \t");
if (strncmp(l, comm, strlen(comm))) { /* non coment block */
*brk = 1;
return NULL;
}
l += strlen(comm); l += strspn(l, " \t");
if (strncmp(l, tag, strlen(tag)))
return NULL;
l += strlen(tag);
l += strspn(l, " \t");
l[strcspn(l, "$\n\r")] = 0;
return strdup(l);
}

31
src/sdl-instead/util.h Normal file
View file

@ -0,0 +1,31 @@
#ifndef __UTIL_H_INCLUDED
#define __UTIL_H_INCLUDED
typedef int (*parser_fn)(const char *v, void *data);
struct parser {
const char *cmd;
parser_fn fn;
void *p;
};
extern int parse_ini(const char *path, struct parser *cmd_parser);
extern char *getpath(const char *d, const char *n);
extern char *strip(char *s);
char *getfilepath(const char *d, const char *n);
extern int parse_esc_string(const char *v, void *data);
extern int parse_string(const char *v, void *data);
extern int parse_int(const char *v, void *data);
extern int parse_full_path(const char *v, void *data);
extern void unix_path(char *path);
extern char *parse_tag(char *line, const char *tag, const char *comm, int *brk);
#ifndef PATH_MAX
#define PATH_MAX 4096
#endif
#define FREE(v) do { if ((v)) free((v)); v = NULL; } while(0)
#endif

View file

@ -7,9 +7,7 @@
#include <stdlib.h>
#include <errno.h>
#ifndef PATH_MAX
#define PATH_MAX 4096
#endif
#include "internals.h"
extern char *curgame;
extern char *curgame_dir;
@ -24,6 +22,16 @@ void nsleep(int u)
Sleep(u);
}
char *game_locale(void)
{
char buff[64];
buff[0] = 0;
if (!GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME,
buff,sizeof(buff) - 1))
return NULL;
return strdup(buff);
}
char *app_dir( void );
char *game_local_games_path(void)