From 7652f176b949b1ca403615b6c429e48e93c98a4a Mon Sep 17 00:00:00 2001 From: "p.kosyh" Date: Sat, 5 Sep 2009 04:44:45 +0000 Subject: [PATCH] not tested version of locale-support code refactoring --- Rules.make.standalone | 1 + Rules.make.system | 5 +- languages/Makefile | 8 + languages/Makefile.windows | 7 + languages/en.ini | 107 +++ languages/ru.ini | 108 +++ src/sdl-instead/Makefile | 4 +- src/sdl-instead/config.c | 79 ++ src/sdl-instead/config.h | 24 + src/sdl-instead/externals.h | 41 + src/sdl-instead/game.c | 1446 +++-------------------------------- src/sdl-instead/game.h | 91 ++- src/sdl-instead/graphics.c | 10 +- src/sdl-instead/input.c | 6 +- src/sdl-instead/instead.c | 15 +- src/sdl-instead/internals.h | 10 + src/sdl-instead/main.c | 21 +- src/sdl-instead/menu.c | 615 +++++++++++++++ src/sdl-instead/menu.h | 134 +--- src/sdl-instead/sound.c | 20 +- src/sdl-instead/sound.h | 3 + src/sdl-instead/themes.c | 438 +++++++++++ src/sdl-instead/themes.h | 115 +++ src/sdl-instead/unix.c | 20 +- src/sdl-instead/util.c | 218 ++++++ src/sdl-instead/util.h | 31 + src/sdl-instead/windows.c | 14 +- 27 files changed, 2080 insertions(+), 1511 deletions(-) create mode 100644 languages/Makefile create mode 100644 languages/Makefile.windows create mode 100644 languages/en.ini create mode 100644 languages/ru.ini create mode 100644 src/sdl-instead/config.c create mode 100644 src/sdl-instead/config.h create mode 100644 src/sdl-instead/externals.h create mode 100644 src/sdl-instead/internals.h create mode 100644 src/sdl-instead/menu.c create mode 100644 src/sdl-instead/themes.c create mode 100644 src/sdl-instead/themes.h create mode 100644 src/sdl-instead/util.c create mode 100644 src/sdl-instead/util.h diff --git a/Rules.make.standalone b/Rules.make.standalone index 344c055..e9b0c7c 100644 --- a/Rules.make.standalone +++ b/Rules.make.standalone @@ -6,6 +6,7 @@ STEADPATH=./stead THEMESPATH=./themes GAMESPATH=./games ICONPATH=./icon +LANGPATH=./languages DOCPATH= LUA_CFLAGS=$(shell pkg-config --cflags lua5.1) diff --git a/Rules.make.system b/Rules.make.system index c449db4..35c26e0 100644 --- a/Rules.make.system +++ b/Rules.make.system @@ -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= diff --git a/languages/Makefile b/languages/Makefile new file mode 100644 index 0000000..3191c69 --- /dev/null +++ b/languages/Makefile @@ -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 diff --git a/languages/Makefile.windows b/languages/Makefile.windows new file mode 100644 index 0000000..b0261f9 --- /dev/null +++ b/languages/Makefile.windows @@ -0,0 +1,7 @@ +include ../Rules.make + +clean: +all: +install: + if not exist ..\bin\languages mkdir ..\bin\languages + copy /Y *.ini ..\bin\languages diff --git a/languages/en.ini b/languages/en.ini new file mode 100644 index 0000000..b8a6fd4 --- /dev/null +++ b/languages/en.ini @@ -0,0 +1,107 @@ +;$Name:English$ +UNKNOWN_ERROR = Unknown error. +ERROR_MENU = Error while loading game:\n\ +'%s'\n\ +\n\ +Ok + +WARNING_MENU = Error while processing game:\n\ +'%s'\n\ +\n\ +Ok + +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 = \ +Resume game\n\ +Select game\n\ +Select theme\n\ +Restart game\n\ +Load game\n\ +Save game\n\ +About\n\ +Settings\n\ +Quit + +ABOUT_MENU = \ +INSTEAD SDL - %s\n\ +\n\ +Written by Peter Kosyh '2009\n\ +Ported to Windows by Ilja Ryndin\n\ +\n\ +Homepage:\n\ +http://instead.googlecode.com\n\ +\n\ +Back + +BACK_MENU = Back +ON = on +OFF = off + +SELECT_GAME_MENU = Select game to play\n\n +SELECT_THEME_MENU = Select theme\n\n + +SETTINGS_MENU = \ +Volume\n\ +<<< %d%% >>>\n\ +\n\ +Quality\n\ +<< %dHz >>\n\ +\n\ +Music: %s\n\ +Click sound: %s\n\ +\n\ +Full Screen: %s\n\ +Font scaling: <<%d>>\n\ +Refs highlighting: %s\n\ +Motion mode: %s\n\ +Mouse filter: %s\n\ +\n\ +Language: <<%s>>\n\ +Custom game themes: %s\n\ +Аutosave: %s\n\ +\n\ +Apply + +OWN_THEME_MENU = \ +Warning!!!\n\ +\n\ +Current game have custom theme.\n\ +So, changes will be ignored.\n\ +\n\ +You can disable custom themes\n\ +in settings menu.\n\ +\n\ +Ok + +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\ +You can enable custom theme support in settings menu.\n\ +\n\ +Ok + +QUIT_MENU = \ +Really quit?\n\ +\n\ +Yes | No + +SAVED_MENU = \ +Current Game saved!\n\ +\n\ +Ok + +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' diff --git a/languages/ru.ini b/languages/ru.ini new file mode 100644 index 0000000..b2ff8c7 --- /dev/null +++ b/languages/ru.ini @@ -0,0 +1,108 @@ +;$Name:Русский$ + +UNKNOWN_ERROR = Неизвестная ошибка. +ERROR_MENU = Во время инициализации игры произошла ошибка:\n\ +'%s'\n\ +\n\ +Да + +WARNING_MENU = Во время работы игры произошла ошибка:\n\ +'%s'\n\ +\n\ +Да + +SAVE_SLOT_EMPTY = пусто +SELECT_LOAD_MENU = Загрузите игру\n\n +AUTOSAVE_SLOT = Автосохранение +BROKEN_SLOT = ошибка +SELECT_SAVE_MENU = Сохраните игру\n\n + +MAIN_MENU = \ +Вернуться в игру\n\ +Выбор игры\n\ +Выбор темы\n\ +Начать заново\n\ +Загрузить игру\n\ +Сохранить игру\n\ +Информация\n\ +Настройки\n\ +Выход + +ABOUT_MENU = \ +INSTEAD SDL - %s\n\ +\n\ +Интерпретатор простых\n\ +текстовых приключений:\n\ +Косых П.А. '2009\n\ +\n\ +Адаптация для Windows:\n\ +Рындин И.В. '2009\n\ +\n\ +Сайт проекта:\n\ +http://instead.googlecode.com\n\ +\n\ +Назад + +BACK_MENU = Назад +ON = Да +OFF = Нет + +SETTINGS_MENU = \ +Громкость\n\ +<<< %d%% >>>\n\ +\n\ +Качество звука\n<< %dГц >>\n\ +\n\ +Музыка: %s\n\ +Звук щелчка: %s\n\ +\n\ +Полный экран: %s\n\ +Масштаб шрифта: <<%d>>\n\ +Подсветка ссылок: %s\n\ +Режим прокрутки: %s\n\ +Фильтр мышки: %s\n\ +\n\ +Язык интерфейса: <<%s>>\n\ +Собственные темы игр: %s\n\ +Автосохранение: %s\n\ +\n\ +Применить + +CUSTOM_THEME_MENU = \ +Внимание!!!\n\ +\n\ +Игра содержит собственную тему, но поддержка собственных тем отключена в настройках. \ +Игра может выглядеть не так, как задумывал ее автор.\n\ +\n\ +Вы можете разрешить возможность переопределения тем в настройках.\n\ +\n\ +Да + +OWN_THEME_MENU = \ +Внимание!!!\n\ +\n\ +Выбранная игра переопределяет тему. Изменения не вступят в силу.\n\ +\n\ +Вы можете запретить возможность переопределения тем в настройках.\n\ +\n\ +Да + +QUIT_MENU = \ +На самом деле выйти?\n\ +\n\ +Да | Нет + +SELECT_GAME_MENU = Выбор игры\n\n +SELECT_THEME_MENU = Выбор темы\n\n +SAVED_MENU = \ +Игра сохранена!\n\ +\n\ +Да + +NOGAMES_MENU = \ +Не найдена ни одна игра.\n\ +Пожалуйста, скопируйте хотя бы одну игру в каталог:\n'%s' + +NOTHEMES_MENU = \ +Не найдена ни одна тема.\n\ +Пожалуйста, скопируйте хотя бы одну тему в каталог:\n'%s' diff --git a/src/sdl-instead/Makefile b/src/sdl-instead/Makefile index d756552..1a5f69e 100644 --- a/src/sdl-instead/Makefile +++ b/src/sdl-instead/Makefile @@ -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)) diff --git a/src/sdl-instead/config.c b/src/sdl-instead/config.c new file mode 100644 index 0000000..ee504ae --- /dev/null +++ b/src/sdl-instead/config.c @@ -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; +} + diff --git a/src/sdl-instead/config.h b/src/sdl-instead/config.h new file mode 100644 index 0000000..03a0c3b --- /dev/null +++ b/src/sdl-instead/config.h @@ -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 \ No newline at end of file diff --git a/src/sdl-instead/externals.h b/src/sdl-instead/externals.h new file mode 100644 index 0000000..b06c563 --- /dev/null +++ b/src/sdl-instead/externals.h @@ -0,0 +1,41 @@ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +// #include +#include +#ifdef _HAVE_ICONV +#include +#endif + +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + diff --git a/src/sdl-instead/game.c b/src/sdl-instead/game.c index cf35d67..b1d9f63 100644 --- a/src/sdl-instead/game.c +++ b/src/sdl-instead/game.c @@ -1,51 +1,12 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "graphics.h" -#include "sound.h" -#include "game.h" -#include "input.h" -#include "instead.h" - -#ifdef RUSSIAN -#include "menu.h" -#else -#include "menu-en.h" -#endif - -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; +#include "externals.h" +#include "internals.h" char *err_msg = NULL; -#ifndef PATH_MAX -#define PATH_MAX 4096 -#endif - #define ERR_MSG_MAX 512 +char game_cwd[PATH_MAX]; +char *curgame_dir = NULL; + +int game_own_theme = 0; void game_err_msg(const char *s) { @@ -61,593 +22,6 @@ void game_err_msg(const char *s) err_msg = NULL; } -char game_cwd[PATH_MAX]; -char *curgame = NULL; -char *curgame_dir = NULL; -static int own_theme = 0; -char *curtheme = NULL; -char *curtheme_dir = NULL; -int cfg_parse(const char *path); - -extern char *game_cfg_path(void); -extern char *game_save_path(int rc, int nr); - -int game_save(int nr); - -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", - 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); - fclose(fp); - return 0; -} - -void game_menu_box(int show, const char *txt); - -void game_cursor(int on); - -#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 - -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; -} 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, -}; - -#define FREE(v) do { if ((v)) free((v)); v = NULL; } while(0) - -void free_theme_strings() -{ - 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; -} - -#define FONT_SZ(v) ((v) * (1.0f + ((0.1f * opt_fsize)))) - -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; -} - -typedef int (*parser_fn)(const char *v, void *data); - -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_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; -} - -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; -} - -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; -} - -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_color(const char *v, void *data) -{ - color_t *c = (color_t *)data; - return gfx_parse_color(v, c); -} -int game_theme_load(const char *name); -int game_theme_select(const char *name); - -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 { - const char *cmd; - parser_fn fn; - void *p; -}; - -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 }, - { NULL, }, -}; - -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, }, -}; - -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; -} - -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; -} - -int parse_ini(const char *path, struct parser *cmd_parser) -{ - int rc = 0; - int line_nr = 0; - FILE *fp; - char line[1024]; - fp = fopen(path, "r"); - if (!fp) - return -1; - while (fgets(line, sizeof(line), fp)) { - char *p = line; - char *val; - int len; - line_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, strerror(errno)); - } - } - fclose(fp); - return rc; -} - -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; -} - -int cfg_parse(const char *path) -{ - return parse_ini(path, cfg_parser); -} - -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; -} - static int is_game(const char *path, const char *n) { @@ -668,20 +42,15 @@ static int is_game(const char *path, const char *n) return rc; } -struct game { - char *path; - char *name; - char *dir; -}; - struct game *games = NULL; int games_nr = 0; - - +void free_last(void); + int game_select(const char *name) { int i; + free_last(); if (!name || !*name) { if (games_nr == 1) name = games[0].dir; @@ -698,7 +67,6 @@ int game_select(const char *name) return -1; if (instead_load(MAIN_FILE)) return -1; - curgame = games[i].name; curgame_dir = games[i].dir; return 0; } @@ -706,22 +74,6 @@ int game_select(const char *name) return 0; } -static 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); -} static char *game_name(const char *path, const char *d_name) { @@ -786,142 +138,6 @@ int games_lookup(const char *path) return 0; } -struct theme *themes = NULL; -int themes_nr = 0; - -struct theme { - char *path; - char *name; - char *dir; -}; - -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; -} - -int theme_load(const char *name); - -struct theme *theme_lookup(const char *name) -{ - int i; - if (!name || !*name) { - if (themes_nr == 1) - return &themes[0]; - } - for (i = 0; ipath) || 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 = theme->name; - curtheme_dir = theme->dir; - return 0; -} - -int game_default_theme(void) -{ - return game_theme_load(DEFAULT_THEME); -} static int motion_mode = 0; static int motion_id = 0; @@ -933,28 +149,10 @@ static char *last_music = NULL; static int mx, my; static img_t menubg = NULL; static img_t menu = NULL; -static int cur_menu = 0; + static int menu_shown = 0; -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, -}; int game_cmd(char *cmd); -int change_vol(int d, int val); - void game_clear(int x, int y, int w, int h) { if (game_theme.bg) @@ -972,11 +170,8 @@ void game_clear(int x, int y, int w, int h) } } - - void game_clear(int x, int y, int w, int h); - struct el { int id; int x; @@ -1057,8 +252,7 @@ char *game_menu_gen(void); void game_menu(int nr) { cur_menu = nr; - menu_shown = 1; - game_menu_box(menu_shown, game_menu_gen()); + game_menu_box(1, game_menu_gen()); } int game_error(const char *name) @@ -1074,17 +268,10 @@ int game_error(const char *name) void el_draw(int n); -static void custom_theme_warn(void) -{ - if (own_theme && !opt_owntheme) { - game_menu(menu_custom_theme); - } -} - int window_sw = 0; int fullscreen_sw = 0; -static int game_load(int nr) +int game_load(int nr) { char *s; s = game_save_path(0, nr); @@ -1100,6 +287,21 @@ static int game_load(int nr) return -1; } +int game_save(int nr) +{ + char *s = game_save_path(1, nr); + char cmd[PATH_MAX]; + char *p; + if (s) { + snprintf(cmd, sizeof(cmd) - 1, "save %s", s); + p = instead_cmd(cmd); + if (p) + free(p); + return 0; + } + return -1; +} + int game_apply_theme(void) { layout_t lay; @@ -1172,9 +374,83 @@ int game_apply_theme(void) return 0; } +int game_restart(void) +{ + char *og = curgame_dir; + game_save(-1); + game_done(); + if (game_init(og)) { + game_error(og); + return 0; + } + return 0; +} +int static cur_vol = 0; +void free_last_music(void); + +void game_stop_mus(int ms) +{ + snd_stop_mus(ms); + free_last_music(); +} + +int game_change_vol(int d, int val) +{ + int v = snd_volume_mus(-1); + int pc = snd_vol_to_pcn(v); + int opc = pc; + if (d) { + pc += d; + if (pc < 0) + pc = 0; + if (pc > 100) + pc = 100; + while (snd_vol_to_pcn(v) != pc) + v += (d<0)?-1:1; + } else { + v = val; + pc = snd_vol_to_pcn(v); + } + if (!pc) + v = 0; + snd_volume_mus(v); + if (opc && !pc) { + game_stop_mus(0); + } + if (!opc && pc) { + game_music_player(); + } + cur_vol = snd_volume_mus(-1); + opt_vol = cur_vol; + return 0; +} + +int game_change_hz(int hz) +{ + if (!hz) + return -1; + snd_done(); + free_last_music(); + snd_init(hz); + snd_volume_mus(cur_vol); + snd_free_wav(game_theme.click); + game_theme.click = snd_load_wav(game_theme.click_name); + game_music_player(); + opt_hz = snd_hz(); + return 0; +} + + int game_init(const char *name) { getcwd(game_cwd, sizeof(game_cwd)); + + if (!opt_lang || !opt_lang[0]) + opt_lang = game_locale(); + + if (menu_lang_select(opt_lang) && menu_lang_select(LANG_DEF)) + return -1; + if (name) game_err_msg(NULL); @@ -1182,7 +458,7 @@ int game_init(const char *name) return -1; snd_init(opt_hz); - change_vol(0, opt_vol); + game_change_vol(0, opt_vol); if (game_default_theme()) { fprintf(stderr, "Can't load default theme.\n"); @@ -1192,11 +468,11 @@ int game_init(const char *name) if (game_select(name)) return -1; - if (curgame && !access(THEME_FILE, R_OK)) { - own_theme = 1; + if (curgame_dir && !access(THEME_FILE, R_OK)) { + game_own_theme = 1; } - if (own_theme && opt_owntheme) { + if (game_own_theme && opt_owntheme) { if (theme_load(THEME_FILE)) return -1; } else if (curtheme_dir && strcmp(DEFAULT_THEME, curtheme_dir)) { @@ -1206,7 +482,7 @@ int game_init(const char *name) if (game_apply_theme()) return -1; - if (!curgame) { + if (!curgame_dir) { game_menu(menu_games); } else { if (!game_load(-1)) /* tmp save */ @@ -1235,15 +511,14 @@ void free_last(void) free(last_pict); if (last_title) free(last_title); - free_last_music(); last_pict = last_title = NULL; - snd_stop_mus(500); + game_stop_mus(500); } void game_done(void) { int i; - if (opt_autosave && curgame) + if (opt_autosave && curgame_dir) game_save(0); chdir(game_cwd); // cfg_save(); @@ -1284,9 +559,8 @@ void game_done(void) snd_done(); instead_done(); gfx_done(); - curgame = NULL; curgame_dir = NULL; - own_theme = 0; + game_own_theme = 0; // SDL_Quit(); } @@ -1453,470 +727,6 @@ img_t game_pict_scale(img_t img, int ww, int hh) } -int vol_from_pcn(int v) -{ - return (v * 127) / 100; -} - -int vol_to_pcn(int v) -{ - return (v * 100) / 127; -} -void music_player(void); - -int static old_vol = 0; -int static cur_vol = 0; - -int change_vol(int d, int val) -{ - int v = snd_volume_mus(-1); - int pc = vol_to_pcn(v); - int opc = pc; - if (d) { - pc += d; - if (pc < 0) - pc = 0; - if (pc > 100) - pc = 100; - while (vol_to_pcn(v) != pc) - v += (d<0)?-1:1; - } else { - v = val; - pc = vol_to_pcn(v); - } - if (!pc) - v = 0; - snd_volume_mus(v); - if (opc && !pc) { - snd_stop_mus(0); - free_last_music(); - } - if (!opc && pc) { - music_player(); - } - cur_vol = snd_volume_mus(-1); - opt_vol = cur_vol; - return 0; -} - -int change_hz(int hz) -{ - if (!hz) - return -1; - snd_done(); - free_last_music(); - snd_init(hz); - snd_volume_mus(cur_vol); - snd_free_wav(game_theme.click); - game_theme.click = snd_load_wav(game_theme.click_name); - music_player(); - opt_hz = snd_hz(); - return 0; -} -static int games_menu_from = 0; - -static int themes_menu_from = 0; - -int game_save(int nr) -{ - char *s = game_save_path(1, nr); - char cmd[PATH_MAX]; - char *p; - if (s) { - snprintf(cmd, sizeof(cmd) - 1, "save %s", s); - p = instead_cmd(cmd); - if (p) - free(p); - return 0; - } - return -1; -} -static int restart_needed = 0; - -static int game_restart(void) -{ - if (restart_needed) { - restart_needed = 0; - char *og = curgame_dir; - game_save(-1); - game_done(); - if (game_init(og)) { - game_error(og); - return 0; - } - } - return 0; -} - -int game_menu_act(const char *a) -{ - if (!strcmp(a, "/autosave")) { - opt_autosave ^= 1; - game_menu_box(menu_shown, game_menu_gen()); - } else if (!strcmp(a, "/owntheme")) { - opt_owntheme ^= 1; - if (own_theme) - restart_needed = 1; - game_menu_box(menu_shown, game_menu_gen()); - } else if (!strcmp(a, "/motion")) { - opt_motion ^= 1; - game_menu_box(menu_shown, game_menu_gen()); - } else if (!strcmp(a, "/filter")) { - opt_filter ^= 1; - game_menu_box(menu_shown, game_menu_gen()); - } else if (!strcmp(a, "/click")) { - opt_click ^= 1; - game_menu_box(menu_shown, 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(menu_shown, 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(menu_shown, game_menu_gen()); - } else if (!strcmp(a, "/hl")) { - opt_hl ^= 1; - game_menu_box(menu_shown, game_menu_gen()); - } else if (!strcmp(a, "/fs")) { - restart_needed = 1; - opt_fs ^= 1; - game_menu_box(menu_shown, 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(menu_shown, 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(menu_shown, 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(menu_shown, 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(menu_shown, 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) - 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) - 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); - menu_shown = 0; - 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); - menu_shown = 0; - 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")) { - game_restart(); - 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); - change_vol(0, 0); - } else { - change_vol(0, old_vol); - old_vol = 0; - } - } else if (!strcmp(a,"/music")) { - opt_music ^= 1; - if (!opt_music) { - snd_stop_mus(0); - free_last_music(); - } else - music_player(); - game_menu_box(menu_shown, game_menu_gen()); - } else if (!strcmp(a,"/resume")) { - menu_shown = 0; - cur_menu = menu_main; - game_menu_box(0, NULL); - } else if (!strcmp(a, "/settings")) { - game_menu(menu_settings); - } else if (!strcmp(a, "/vol--")) { - change_vol(-10, 0); - game_menu_box(menu_shown, game_menu_gen()); - } else if (!strcmp(a, "/vol++")) { - change_vol(+10, 0); - game_menu_box(menu_shown, game_menu_gen()); - } else if (!strcmp(a, "/vol-")) { - change_vol(-1, 0); - game_menu_box(menu_shown, game_menu_gen()); - } else if (!strcmp(a, "/vol+")) { - change_vol(+1, 0); - game_menu_box(menu_shown, 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; - change_hz(hz); - game_menu_box(menu_shown, 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; - change_hz(hz); - game_menu_box(menu_shown, 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 && own_theme && opt_owntheme) { - game_menu(menu_own_theme); - } - free(p); - } - } - return 0; -} - -char menu_buff[4096]; - -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); -} - -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), "%d - "SAVE_SLOT_EMPTY"\n", i); - } else { - char *name; - if (!i) - name = strdup(AUTOSAVE_SLOT); - else - name = slot_name(s); - if (!name) - snprintf(tmp, sizeof(tmp), "%d - "BROKEN_SLOT"\n", i); - else { - snprintf(tmp, sizeof(tmp), "%d - %s\n", i, i, name); - free(name); - } - } - strcat(menu_buff, tmp); - } - strcat(menu_buff,"\nОтмена"); -} - -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), "%d - "SAVE_SLOT_EMPTY"\n", i, i); - else { - char *name; - if (!i) - name = strdup(AUTOSAVE_SLOT); - else - name = slot_name(s); - if (!name) - snprintf(tmp, sizeof(tmp), "%d - "BROKEN_SLOT"\n", i, i); - else { - snprintf(tmp, sizeof(tmp), "%d - %s\n", i, i, name); - free(name); - } - } - strcat(menu_buff, tmp); - } - strcat(menu_buff,"\nОтмена"); -} - -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 && !strcmp(games[i].name, curgame)) - snprintf(tmp, sizeof(tmp), "%s\n", games[i].name); - else - snprintf(tmp, sizeof(tmp), "%s\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,"<< "); - strcat(menu_buff, BACK_MENU); - if (games_menu_from + MENU_GAMES_MAX < games_nr) - strcat(menu_buff," >>"); -} - -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 && !strcmp(themes[i].name, curtheme)) - snprintf(tmp, sizeof(tmp), "%s\n", themes[i].name); - else - snprintf(tmp, sizeof(tmp), "%s\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,"<< "); - strcat(menu_buff, BACK_MENU); - if (themes_menu_from + MENU_THEMES_MAX < themes_nr) - strcat(menu_buff," >>"); -} - -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); - } else if (cur_menu == menu_settings) { - snprintf(menu_buff, sizeof(menu_buff), SETTINGS_MENU, - 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, - 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; -} void game_menu_box(int show, const char *txt) { @@ -1926,6 +736,9 @@ void game_menu_box(int show, const char *txt) int b = game_theme.border_w; int pad = game_theme.pad; layout_t lay; + + menu_shown = show; + el(el_menu)->drawn = 0; if (el_layout(el_menu)) { txt_layout_free(el_layout(el_menu)); @@ -2042,7 +855,7 @@ void scene_scrollbar(void) static void dec_music(void *data) { char *mus; - if (!curgame) + if (!curgame_dir) return; mus = instead_eval("return dec_music_loop()"); if (!mus) @@ -2057,20 +870,7 @@ void game_music_finished(void) push_user_event(&dec_music, NULL); } -void unix_path(char *path) -{ - char *p = path; - if (!path) - return; - while (*p) { /* bad bad Windows!!! */ - if (*p == '\\') - *p = '/'; - p ++; - } - return; -} - -void music_player(void) +void game_music_player(void) { int loop; char *mus; @@ -2097,18 +897,15 @@ void music_player(void) if (!mus) { if (last_music) { - free(last_music); - snd_stop_mus(500); - last_music = NULL; + game_stop_mus(500); } } else if (!last_music && mus) { + game_stop_mus(500); last_music = mus; - snd_stop_mus(500); snd_play_mus(mus, 0, loop - 1); } else if (strcmp(last_music, mus)) { - free(last_music); + game_stop_mus(500); last_music = mus; - snd_stop_mus(500); snd_play_mus(mus, 0, loop - 1); } else free(mus); @@ -2156,7 +953,7 @@ int game_cmd(char *cmd) cmdstr = instead_cmd(cmd); if (!cmdstr) goto err; - music_player(); + game_music_player(); // sound_player(); /* TODO */ title = instead_eval("return get_title();"); unix_path(title); @@ -2389,6 +1186,7 @@ void menu_update(struct el *elem) // gfx_fill(x, y, w, h, game_theme.menu_bg); } +void game_cursor(int on); int game_highlight(int x, int y, int on) { @@ -2464,10 +1262,11 @@ static void scroll_pdown(int id) el_update(id); } -static unsigned int old_counter = 0; extern unsigned int timer_counter; + int mouse_filter(void) { + static unsigned int old_counter = 0; if (!opt_filter) return 0; if (abs(old_counter - timer_counter) <= 4) /* 400 ms */ @@ -2674,11 +1473,12 @@ static void scroll_motion(int id, int off) el_update(id); } -static int alt_pressed = 0; int game_loop(void) { + static int alt_pressed = 0; static int x = 0, y = 0; struct inp_event ev; + memset(&ev, 0, sizeof(struct inp_event)); while (1) { int rc; ev.x = -1; diff --git a/src/sdl-instead/game.h b/src/sdl-instead/game.h index a85ccab..4e63eb1 100644 --- a/src/sdl-instead/game.h +++ b/src/sdl-instead/game.h @@ -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 - diff --git a/src/sdl-instead/graphics.c b/src/sdl-instead/graphics.c index fb5c13c..a17c33f 100644 --- a/src/sdl-instead/graphics.c +++ b/src/sdl-instead/graphics.c @@ -1,11 +1,5 @@ -#include -#include -#include -#include -#include "SDL_rotozoom.h" -#include "input.h" -#include "graphics.h" -#include "math.h" +#include "externals.h" +#include "internals.h" static SDL_Surface *screen; diff --git a/src/sdl-instead/input.c b/src/sdl-instead/input.c index 9dff92b..57dde21 100644 --- a/src/sdl-instead/input.c +++ b/src/sdl-instead/input.c @@ -1,7 +1,5 @@ -#include -#include "input.h" -#include -#include +#include "externals.h" +#include "internals.h" void push_user_event(void (*p) (void*), void *data) { diff --git a/src/sdl-instead/instead.c b/src/sdl-instead/instead.c index e65346c..9e61ae7 100644 --- a/src/sdl-instead/instead.c +++ b/src/sdl-instead/instead.c @@ -2,20 +2,9 @@ #define STEAD_PATH "./stead" #endif -#include -#include -#include -#include -#include -#include -#include -// #include -#include #include "gui.h" -#ifdef _HAVE_ICONV -#include -#endif -#include "game.h" +#include "externals.h" +#include "internals.h" /* the Lua interpreter */ char *fromgame(const char *s); diff --git a/src/sdl-instead/internals.h b/src/sdl-instead/internals.h new file mode 100644 index 0000000..c4e2a98 --- /dev/null +++ b/src/sdl-instead/internals.h @@ -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" diff --git a/src/sdl-instead/main.c b/src/sdl-instead/main.c index 2910348..9485379 100644 --- a/src/sdl-instead/main.c +++ b/src/sdl-instead/main.c @@ -1,10 +1,5 @@ -#include -#include -#include "graphics.h" -#include "game.h" -#include -#include -#include +#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)) { diff --git a/src/sdl-instead/menu.c b/src/sdl-instead/menu.c new file mode 100644 index 0000000..368a270 --- /dev/null +++ b/src/sdl-instead/menu.c @@ -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), "%d - %s\n", i, SAVE_SLOT_EMPTY); + } else { + char *name; + if (!i) + name = strdup(AUTOSAVE_SLOT); + else + name = slot_name(s); + if (!name) + snprintf(tmp, sizeof(tmp), "%d - %s\n", i, BROKEN_SLOT); + else { + snprintf(tmp, sizeof(tmp), "%d - %s\n", i, i, name); + free(name); + } + } + strcat(menu_buff, tmp); + } + strcat(menu_buff,"\nОтмена"); +} + +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), "%d - %s\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), "%d - %s\n", i, i, BROKEN_SLOT); + else { + snprintf(tmp, sizeof(tmp), "%d - %s\n", i, i, name); + free(name); + } + } + strcat(menu_buff, tmp); + } + strcat(menu_buff,"\nОтмена"); +} + +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), "%s\n", games[i].name); + else + snprintf(tmp, sizeof(tmp), "%s\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,"<< "); + strcat(menu_buff, BACK_MENU); + if (games_menu_from + MENU_GAMES_MAX < games_nr) + strcat(menu_buff," >>"); +} + +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), "%s\n", themes[i].name); + else + snprintf(tmp, sizeof(tmp), "%s\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,"<< "); + strcat(menu_buff, BACK_MENU); + if (themes_menu_from + MENU_THEMES_MAX < themes_nr) + strcat(menu_buff," >>"); +} + +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Да" +#ifndef __MENU_H_INCLUDED +#define __MENU_H_INCLUDED -#define WARNING_MENU "Во время работы игры произошла ошибка:\n\ -'%s'\n\ -\n\ -Да" +#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 \ -"Вернуться в игру\n\ -Выбор игры\n\ -Выбор темы\n\ -Начать заново\n\ -Загрузить игру\n\ -Сохранить игру\n\ -Информация\n\ -Настройки\n\ -Выход" +#define MAX_SAVE_SLOTS 6 -#define ABOUT_MENU \ -"INSTEAD SDL - "VERSION"\n\ -\n\ -Интерпретатор простых\n\ -текстовых приключений:\n\ -Косых П.А. '2009\n\ -\n\ -Адаптация для Windows:\n\ -Рындин И.В. '2009\n\ -\n\ -Сайт проекта:\n\ -http://instead.googlecode.com\n\ -\n\ -Назад" +#define LANG_DEF "en.ini" -#define BACK_MENU "Назад" -#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\ -<<< %d%% >>>\n\ -\n\ -Качество звука\n<< %dГц >>\n\ -\n\ -Музыка: %s\n\ -Звук щелчка: %s\n\ -\n\ -Полный экран: %s\n\ -Масштаб шрифта: <<%d>>\n\ -Подсветка ссылок: %s\n\ -Режим прокрутки: %s\n\ -Фильтр мышки: %s\n\ -\n\ -Собственные темы игр: %s\n\ -Автосохранение: %s\n\ -\n\ -Применить" +struct lang { + char *path; + char *name; + char *file; +}; +extern struct lang *langs; +extern int langs_nr; -#define CUSTOM_THEME_MENU \ -"Внимание!!!\n\ -\n\ -Игра содержит собственную тему, но поддержка собственных тем отключена в настройках. \ -Игра может выглядеть не так, как задумывал ее автор.\n\ -\n\ -Вы можете разрешить возможность переопределения тем в настройках.\n\ -\n\ -Да" +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\ -Вы можете запретить возможность переопределения тем в настройках.\n\ -\n\ -Да" -#define QUIT_MENU \ -"На самом деле выйти?\n\ -\n\ -Да | Нет" - -#define SELECT_GAME_MENU "Выбор игры\n\n" -#define SELECT_THEME_MENU "Выбор темы\n\n" -#define SAVED_MENU \ -"Игра сохранена!\n\ -\n\ -Да" - -#define NOGAMES_MENU \ -"Не найдена ни одна игра.\n\ -Пожалуйста, скопируйте хотя бы одну игру в каталог:\n'%s'" - -#define NOTHEMES_MENU \ -"Не найдена ни одна тема.\n\ -Пожалуйста, скопируйте хотя бы одну тему в каталог:\n'%s'" +#endif diff --git a/src/sdl-instead/sound.c b/src/sdl-instead/sound.c index 0c7e36e..40ed3ac 100644 --- a/src/sdl-instead/sound.c +++ b/src/sdl-instead/sound.c @@ -1,11 +1,5 @@ -#include "sound.h" -#include "input.h" - -#include -#include - -#include -#include +#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; +} diff --git a/src/sdl-instead/sound.h b/src/sdl-instead/sound.h index a2158a7..7405d87 100644 --- a/src/sdl-instead/sound.h +++ b/src/sdl-instead/sound.h @@ -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 diff --git a/src/sdl-instead/themes.c b/src/sdl-instead/themes.c new file mode 100644 index 0000000..cde2f67 --- /dev/null +++ b/src/sdl-instead/themes.c @@ -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; ipath) || 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); +} diff --git a/src/sdl-instead/themes.h b/src/sdl-instead/themes.h new file mode 100644 index 0000000..bf4af60 --- /dev/null +++ b/src/sdl-instead/themes.h @@ -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 diff --git a/src/sdl-instead/unix.c b/src/sdl-instead/unix.c index c0cc9f5..ff196d0 100644 --- a/src/sdl-instead/unix.c +++ b/src/sdl-instead/unix.c @@ -6,14 +6,15 @@ #include #include #include +#include +#include + +#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) diff --git a/src/sdl-instead/util.c b/src/sdl-instead/util.c new file mode 100644 index 0000000..4176261 --- /dev/null +++ b/src/sdl-instead/util.c @@ -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); +} diff --git a/src/sdl-instead/util.h b/src/sdl-instead/util.h new file mode 100644 index 0000000..2648233 --- /dev/null +++ b/src/sdl-instead/util.h @@ -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 diff --git a/src/sdl-instead/windows.c b/src/sdl-instead/windows.c index 38cdfff..fcd6a57 100644 --- a/src/sdl-instead/windows.c +++ b/src/sdl-instead/windows.c @@ -7,9 +7,7 @@ #include #include -#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)