1.3 is now trunk, added 1.2 branch

This commit is contained in:
p.kosyh 2010-10-30 12:54:41 +00:00
parent e9723397be
commit fe5b324fff
36 changed files with 1207 additions and 399 deletions

View file

@ -1,4 +1,4 @@
VERSION := 1.2.3
VERSION := 1.3.0
PREFIX=./
DESTDIR=

View file

@ -1,6 +1,6 @@
# Contributor: Peter Kosyh <p.kosyhgmail.com>
pkgname=instead
pkgver=1.2.3
pkgver=1.3.0
pkgrel=1
pkgdesc="instead quest interpreter"
arch=('i686' 'x86_64')

View file

@ -1,4 +1,4 @@
VERSION := 1.2.3
VERSION := 1.3.0
DESTDIR=
BIN=

View file

@ -1,4 +1,4 @@
VERSION := 1.2.3
VERSION := 1.3.0
DESTDIR=
BIN=

View file

@ -1,4 +1,4 @@
VERSION := 1.2.3
VERSION := 1.3.0
PREFIX=/usr/local
DESTDIR=

View file

@ -1,4 +1,4 @@
VERSION := 1.2.3
VERSION := 1.3.0
PREFIX=./
DESTDIR=

View file

@ -1,4 +1,4 @@
VERSION := 1.2.3
VERSION := 1.3.0
PREFIX=
DESTDIR=

19
debian/changelog vendored
View file

@ -1,3 +1,22 @@
instead (1.3.0) unstable; urgency=low
* bug fix (resample sounds while HZ change);
* bug fix (empty bg);
* bug fix (cursor center scaling);
* changing themes from game;
* strike ougth text;
* *.fnt.height theme parameter;
* scroller positions in theme;
* escaping ^ and delim;
* box: and blank:;
* pad: ;
* speed up;
* picture flow;
* prefs:purge now removes vars;
* dialog:empty added;
-- Peter Kosyh <p.kosyh@gmail.com> Tue, 12 Oct 2010 22:42:00 +0300
instead (1.2.3) unstable; urgency=low
* android build;

View file

@ -1,6 +1,6 @@
[Desktop Entry]
Encoding=UTF-8
Version=1.2.3
Version=1.3.0
Type=Application
Name=INSTEAD
Name[ru]=INSTEAD

View file

@ -13,7 +13,7 @@ body { font-family: Verdana, Arial, Helvetica, sans-serif;
</style>
<title>INSTEAD -- interpreter of simple text adventures for Unix and Windows</title>
</head><body bgcolor="#f0f0f0">
<h2>INSTEAD 1.2.3</h2>
<h2>INSTEAD 1.3.0</h2>
<p>INSTEAD -- interpreter of simple text adventures for Unix and Windows.<br>
INSTEAD was designed to interpret the games that are the mix of visual novels, text quests and classical 90'ss quests.</p>

View file

@ -1,4 +1,4 @@
.TH INSTEAD 6 "Version 1.2.3" Instead GAMES
.TH INSTEAD 6 "Version 1.3.0" Instead GAMES
.SH NAME

View file

@ -1,6 +1,6 @@
===== 0. General information =====
Game code for STEAD is written in lua (5.1), therefore it is useful to know the language, though not necessary. The engine code in lua is about ~2000 lines long. And it is the best documentation.
Game code for STEAD is written in lua (5.1), therefore it is useful to know the language, though not necessary. The engine code in lua is about ~3000 lines long. And it is the best documentation.
The main game window contains information about static and dynamic parts of the scene, active events and the scene picture with possible passages to other scenes (in the graphic interpreter).
@ -30,9 +30,9 @@ At the beginning of “main.lua” file a header may be defined. It consists of
-- $Name: The most interesting game!$
</code>
From version 1.2.0 after headers you must define required STEAD API version. It is "1.2.2" currently.
From version 1.2.0 after headers you must define required STEAD API version. It is "1.3.0" currently.
<code>
instead_version "1.2.2"
instead_version "1.3.0"
</code>
Game initialization should be defined as init function. For example:
@ -854,7 +854,6 @@ Or:
p 'Guard entered the room.'
return true -- The event will be printed before objects description.
</code>
===== 17. Graphics and music =====
Graphic interpreter analyzes the scene “pic” attribute and treats it as a path to the picture. For example:
@ -880,6 +879,21 @@ knife = obj {
}
</code>
From version 1.3.0 text flow is supported. Using functions imgl/imgr, picture can be inserted at left/right. border. Those pictures can not be links.
For padding, you can use 'pad:'. For example:
<code lua>
imgl 'pad:16,picture.png' -- padding 16px;
imgl 'pad:0 16 16 4,picture.png' -- padding: top 0, right 16, bottom 16, left 4
imgl 'pad:0 16,picture.png' -- padding: top 0, right 16, bottom 0, left 16
</code>
You can use pseudo-images for blank areas and boxes:
<code lua>
dsc = img 'blank:32x32'..[[Line with blank image.]];
dsc = img 'box:32x32,red,128'..[[Line with red semi-transparent square.]];
</code>
In current version you can use disp attribute:
<code>
knife = obj {
@ -921,7 +935,6 @@ To stop music use stop_music() function (from version 1.0.0).
Use is_music() to check if music is playing. (from version 1.0.0)
===== 18. Advices =====
==== Modules ====
Starting from version 1.2.0 you can use modules via “require” function call. At the moment the following modules are available:
@ -935,6 +948,7 @@ Starting from version 1.2.0 you can use modules via “require” function call.
* snapshots — snapshots;
* format — formats the output;
* object — improved objects;
* theme — theme manipulations;
Modules can be used like this:
<code>
@ -1031,13 +1045,15 @@ format.quotes = false -- changes quotes on << >>;
format.filter = nil -- user formatting function;
</code>
You may use modules para/dash/quotes to enable specific feature.
==== Formatting ====
You can do simple text formatting with functions:
txtc() - center align;
txtr() - right align;
txtl() - left align;
* txtc() - center align;
* txtr() - right align;
* txtl() - left align;
* txttop() - top of line;
* txtbottom() - bottom of line;
* txtmiddle() - middle (by default);
For example:
<code>
@ -1049,10 +1065,10 @@ main = room {
You can define text style with functions:
txtb() - bold;
txtem() - emboss;
txtu() - underline;
* txtb() - bold;
* txtem() - emboss;
* txtu() - underline;
* txtst() - strikesthrougth;
For example:
<code>
main = room {
@ -1432,7 +1448,6 @@ The object created will be saved every time the game is saved. ''new()'' returns
o_name = deref(new('myconstructor()'));
delete(o_name);
</code>
==== Complex output from event handlers ====
Sometimes the we need to form event handler output from several parts depending on some conditions. In this case ''p()'' and ''pn()'' functions can be useful. These functions add text to the internal buffer of the handler. The content of this buffer is returned from the handler.
<code>
@ -1450,7 +1465,7 @@ There is a function ''pr()'' in versions 1.1.6 and later, that does not add anyt
To clear the buffer you can use ''pclr()''. To return the status of the action along with the text, use ''pget()'' or just return.
<code>
use = function(s, w)
if w == 'apple' then
if w == apple then
p 'I peeled the apple';
apple._peeled = true
return
@ -1478,7 +1493,6 @@ For ingame simple debugger insert this:
require "dbg"
</code>
just after version line in main.lua. Then use F7 to call debugger.
===== 19. Themes for sdl-instead =====
Graphic interpreter supports theme mechanism. A theme is a directory with the “theme.ini” file inside.
@ -1531,8 +1545,12 @@ win.fnt.name = path to the font file (string)
win.fnt.size = font size for the main window (number)
win.fnt.height = line height as float number (1.0 by default)
win.gfx.up, win.gfx.down = paths to the pictures of up/down scrollers for the main window (string)
win.up.x, win.up.y, win.down.x, win.down.y = coordinates of scrollers (position or -1)
win.col.fg = font color for the main window (color)
win.col.link = link color for the main window (color)
@ -1553,8 +1571,12 @@ inv.fnt.name = path to the inventory font file (string)
inv.fnt.size = inventory font size (number)
inv.fnt.height = line height as float number (1.0 by default)
inv.gfx.up, inv.gfx.down = paths to the pictures of inventory up/down scrollers (string)
inv.up.x, inv.up.y, inv.down.x, inv.down.y = coordinates of scrollers (position or -1)
menu.col.bg = menu background (color)
menu.col.fg = menu text color (color)
@ -1573,6 +1595,8 @@ menu.fnt.name = paths to menu font file (string)
menu.fnt.size = menu font size (number)
menu.fnt.height = line height as float number (1.0 by default)
menu.gfx.button = path to the menu icon (string)
menu.button.x, menu.button.y = menu button coordinates (number)
@ -1594,4 +1618,4 @@ The interpreter searches for themes in the “themes” directory. Unix version
TODO
Full list of objects and methods.
Translation: vopros@pochta.ru
Translation: vopros@pochta.ru

View file

@ -1,6 +1,6 @@
===== 0. Общие сведения =====
Код игр для STEAD пишется на lua (5.1), поэтому, знание этого языка полезно, хотя и не необходимо. Код движка на lua занимает около ~2000 строк и лучшей документацией является изучение его кода.
====== Базовая документация ======
===== Общие сведения =====
Код игр для STEAD пишется на lua (5.1), поэтому, знание этого языка полезно, хотя и не необходимо. Код движка на lua занимает около ~3000 строк и лучшей документацией является изучение его кода.
Главное окно игры содержит информацию о статической и динамической части сцены, активные события и картинку сцены с возможными переходами в другие сцены (в графическом интерпретаторе).
@ -30,12 +30,12 @@
-- $Name: Самая интересная игра!$
</code>
Начиная с версии 1.2.0 сразу после заголовков вам необходимо указать версию STEAD API, которая требуется игре. На данный момент последняя версия 1.2.2.
Сразу после заголовков вам необходимо указать версию STEAD API, которая требуется игре. На данный момент последняя версия 1.3.0.
<code lua>
instead_version "1.2.2"
instead_version "1.3.0"
</code>
Если version отсутствует, то STEAD API будет работать в режиме совместимости (устаревшее API).
Если version отсутствует, то STEAD API будет работать в режиме совместимости (устаревшее API).
Инициализацию игры следует описывать в функции init:
<code lua>
@ -47,9 +47,8 @@ end
</code>
Графический интерпретатор ищет доступные игры в каталоге games. Unix версия интерпретатора кроме этого каталога просматривает также игры в каталоге ~/.instead/games.
Windows версия (>=0.8.7): Documents and Settings/USER/Local Settings/Application Data/instead/games.
Начиная с версии 1.2.0, для Windows версии и standalone Unix версии игры ищутся в каталоге ./appdata/games, если он существует.
Windows версия: Documents and Settings/USER/Local Settings/Application Data/instead/games.
В Windows и standalone Unix версии игры ищутся в каталоге ./appdata/games, если он существует.
===== 1. Сцена =====
@ -853,7 +852,6 @@ return 'В комнату вошел охранник.', true
</code>
При этом текст события будет выведен до описания объектов.
===== 17. Графика и музыка =====
Графический интерпретатор анализирует атрибут сцены pic, и воспринимает его как путь к картинке, например:
@ -878,6 +876,21 @@ knife = obj {
}
</code>
А начиная с 1.3.0 поддерживается обтекание картинок текстом. Если картинка вставляется с помощью функции imgl/imgr, она будет расположена у левого/правого края. Такие картинки не могут быть ссылками.
Для задания отступов вокруг изображения используйте pad, например:
<code lua>
imgl 'pad:16,picture.png' -- отступы по 16 от каждого края
imgl 'pad:0 16 16 4,picture.png' -- отступы: вверху 0, справа 16, внизу 16, слева 4
imgl 'pad:0 16,picture.png' -- отступы: вверху 0, справа 16, внизу 0, слева 16
</code>
Вы можете использовать псевдо-файлы для изображений прямоугольников и пустых областей:
<code lua>
dsc = img 'blank:32x32'..[[Строка с пустым изображением.]];
dsc = img 'box:32x32,red,128'..[[Строка красным полупрозрачным квадратом.]];
</code>
В современной версии INSTEAD вы можете использовать атрибут disp:
<code lua>
knife = obj {
@ -932,6 +945,7 @@ is_music() позволяет узнать, проигрывается ли му
* snapshots — модуль поддержки снапшотов;
* format — модуль оформления вывода;
* object — модуль улучшенных объектов;
* theme — управление темой;
Использование модуля выглядит так:
<code lua>
@ -972,6 +986,8 @@ require "dbg"
</code>
При этом, объект может быть объектом или именем объекта.
**Примечание**: начиная с версии 1.2.2 используется следующий формат ссылок: {объект|строка}.
В этом модуле определены также такие объекты как xact и xdsc.
xact -- объект - простейшая реакция. Например:
@ -1027,13 +1043,15 @@ format.filter = nil -- пользовательская функция заме
</code>
Вы можете пользоваться модулями para, dash, quotes для включения отдельных настроек.
==== Форматирование ====
Вы можете делать простое форматирование текста с помощью функций:
* txtc() - разместить по центру;
* txtr() - разместить справа;
* txtl() - разместить слева;
* txttop() - сверху строки;
* txtbottom() - снизу строки;
* txtmiddle() - середина строки (по умолчанию);
Например:
<code lua>
@ -1048,6 +1066,7 @@ main = room {
* txtb() - жирный;
* txtem() - курсив;
* txtu() - подчеркнутый;
* txtst() - перечеркнутый;
Например:
<code lua>
@ -1437,7 +1456,7 @@ end
Для очистки буфера, используйте pclr(). Если вам нужно вернуть статус действия, используйте pget(), или просто используйте return.
<code lua>
use = function(s, w)
if w == 'apple' then
if w == apple then
p 'Гм... Я почистил яблоко.';
apple._peeled = true
return
@ -1465,7 +1484,6 @@ iface:shell();
require "dbg"
</code>
Отладчик вызывается по F7.
===== 19. Темы для sdl-instead =====
Графический интерпретатор поддерживает механизм тем. Тема представляет из себя каталог, с файлом theme.ini внутри.
@ -1518,8 +1536,12 @@ win.fnt.name = путь к файлу-шрифту (строка)
win.fnt.size = размер шрифта главного окна (размер)
win.fnt.height = междустрочный интервал как число с плавающей запятой (1.0 по умолчанию)
win.gfx.up, win.gfx.down = пути к файлам-изображениям скорллеров вверх/вниз для главного окна (строка)
win.up.x, win.up.y, win.down.x, win.down.y = координаты скроллеров (координата или -1)
win.col.fg = цвет текста главного окна (цвет)
win.col.link = цвет ссылок главного окна (цвет)
@ -1540,8 +1562,12 @@ inv.fnt.name = путь к файлу-шрифту инвентаря (стро
inv.fnt.size = размер шрифта инвентаря (размер)
inv.fnt.height = междустрочный интервал как число с плавающей запятой (1.0 по умолчанию)
inv.gfx.up, inv.gfx.down = пути к файлам-изображениям скорллеров вверх/вниз для инвентаря (строка)
inv.up.x, inv.up.y, inv.down.x, inv.down.y = координаты скроллеров (координата или -1)
menu.col.bg = фон меню (цвет)
menu.col.fg = цвет текста меню (цвет)
@ -1560,6 +1586,8 @@ menu.fnt.name = путь к файлу-шрифту меню (строка)
menu.fnt.size = размер шрифта меню (размер)
menu.fnt.height = междустрочный интервал как число с плавающей запятой (1.0 по умолчанию)
menu.gfx.button = путь к файлу изображению значка меню (строка)
menu.button.x, menu.button.y = координаты кнопки меню (числа)

View file

@ -1,6 +1,6 @@
Summary: simply text adventures/visual novels engine and game
Name: instead
Version: 1.2.3
Version: 1.3.0
Release: 1%{?dist}
License: GPLv2
URL: http://instead.googlecode.com

View file

@ -1,4 +1,4 @@
INSTEAD 1.2.3
INSTEAD 1.3.0
=============
WARNING! For successfull building you must install these development packages (names may vary in your distribution):

View file

@ -192,6 +192,7 @@ static void __cache_shrink(__cache_t *c)
} else
break;
}
// fprintf(stderr,"%d/%d\n", c->size, c->used);
}
int cache_add(cache_t cache, const char *name, void *p)

View file

@ -10,6 +10,7 @@ char game_cwd[PATH_MAX];
char *curgame_dir = NULL;
int game_own_theme = 0;
int game_theme_changed = 0;
static int game_pic_w = 0;
static int game_pic_h = 0;
@ -78,14 +79,34 @@ static struct game *game_lookup(const char *name)
return NULL;
}
int game_reset(void)
{
game_release_theme();
free_last();
if (game_select(curgame_dir))
goto out;
if (game_apply_theme())
goto out;
return 0;
out:
game_done(0);
if (game_init(NULL)) {
game_error("");
return -1;
}
return -1;
}
int game_select(const char *name)
{
struct game *g;
FREE(last_cmd);
game_stop_mus(500);
g = game_lookup(name);
if ((!name || !*name) && !g)
return 0;
if ((!name || !*name) && !g) {
game_use_theme();
return game_theme_init();
}
if (setdir(game_cwd))
return -1;
if (g) {
@ -100,12 +121,24 @@ int game_select(const char *name)
curgame_dir = oldgame;
return -1;
}
game_use_theme();
if (instead_load(dirpath(MAIN_FILE))) {
curgame_dir = oldgame;
return -1;
}
instead_function("game:ini", NULL); instead_clear();
if (game_theme_init()) {
curgame_dir = oldgame;
return -1;
}
return 0;
} else {
game_use_theme();
game_theme_init();
}
return 0;
}
@ -462,29 +495,13 @@ static int inv_enabled(void)
return (game_theme.inv_mode != INV_MODE_DISABLED);
}
int game_apply_theme(void)
{
layout_t lay;
textbox_t box;
int w = opt_mode[0];
int h = opt_mode[1];
if ((w == -1)
&& (gfx_get_max_mode(&w, &h) || (game_theme.w <= w && game_theme.h <= h))) {
w = opt_mode[0];
h = opt_mode[1];
}
if (game_theme_init(w, h))
return -1;
memset(objs, 0, sizeof(struct el) * el_max);
if (gfx_set_mode(game_theme.w, game_theme.h, opt_fs)) {
opt_mode[0] = opt_mode[1] = -1; opt_fs = 0; /* safe options */
return -1;
}
if (game_theme_optimize())
return -1;
gfx_bg(game_theme.bgcol);
game_clear(0, 0, game_theme.w, game_theme.h);
gfx_flip();
@ -498,11 +515,11 @@ int game_apply_theme(void)
txt_layout_link_color(lay, game_theme.lcol);
// txt_layout_link_style(lay, 4);
txt_layout_active_color(lay, game_theme.acol);
txt_layout_font_height(lay, game_theme.font_height);
txt_box_set(box, lay);
el_set(el_scene, elt_box, game_theme.win_x, 0, box);
if (inv_enabled()) {
lay = txt_layout(game_theme.inv_font, INV_ALIGN(game_theme.inv_mode),
game_theme.inv_w, game_theme.inv_h);
@ -511,6 +528,7 @@ int game_apply_theme(void)
txt_layout_color(lay, game_theme.icol);
txt_layout_link_color(lay, game_theme.ilcol);
txt_layout_active_color(lay, game_theme.iacol);
txt_layout_font_height(lay, game_theme.inv_font_height);
box = txt_box(game_theme.inv_w, game_theme.inv_h);
if (!box)
@ -527,7 +545,8 @@ int game_apply_theme(void)
txt_layout_color(lay, game_theme.fgcol);
txt_layout_link_color(lay, game_theme.lcol);
txt_layout_active_color(lay, game_theme.acol);
txt_layout_font_height(lay, game_theme.font_height);
el_set(el_title, elt_layout, game_theme.win_x, game_theme.win_y, lay);
lay = txt_layout(game_theme.font, ALIGN_CENTER, game_theme.win_w, 0);
@ -537,7 +556,8 @@ int game_apply_theme(void)
txt_layout_color(lay, game_theme.fgcol);
txt_layout_link_color(lay, game_theme.lcol);
txt_layout_active_color(lay, game_theme.acol);
txt_layout_font_height(lay, game_theme.font_height);
el_set(el_ways, elt_layout, game_theme.win_x, 0, lay);
el_set(el_sdown, elt_image, 0, 0, game_theme.a_down);
@ -604,6 +624,8 @@ int game_change_vol(int d, int val)
return 0;
}
static void sounds_reload(void);
int game_change_hz(int hz)
{
if (!hz)
@ -614,6 +636,7 @@ int game_change_hz(int hz)
snd_volume_mus(cur_vol);
snd_free_wav(game_theme.click);
game_theme.click = snd_load_wav(game_theme.click_name);
sounds_reload();
game_music_player();
opt_hz = snd_hz();
return 0;
@ -684,6 +707,32 @@ int counter_fn(int interval, void *p)
return interval;
}
int game_use_theme(void)
{
int rc = 0;
game_theme_changed = 0;
game_own_theme = 0;
game_theme.changed = CHANGED_ALL;
if (game_default_theme()) {
fprintf(stderr, "Can't load default theme.\n");
return -1;
}
if (curgame_dir && !access(dirpath(THEME_FILE), R_OK)) {
game_own_theme = 1;
}
if (game_own_theme && opt_owntheme) {
theme_relative = 1;
rc = theme_load(dirpath(THEME_FILE));
theme_relative = 0;
} else if (curtheme_dir && strcmp(DEFAULT_THEME, curtheme_dir)) {
rc = game_theme_load(curtheme_dir);
}
return rc;
}
int game_init(const char *name)
{
getdir(game_cwd, sizeof(game_cwd));
@ -698,43 +747,35 @@ int game_init(const char *name)
snd_init(opt_hz);
game_change_vol(0, opt_vol);
if (game_default_theme()) {
fprintf(stderr, "Can't load default theme.\n");
if (game_select(name))
return -1;
if (gfx_set_mode(game_theme.w, game_theme.h, opt_fs)) {
opt_mode[0] = opt_mode[1] = -1; opt_fs = 0; /* safe options */
return -1;
}
if (game_select(name))
if (game_theme_optimize())
return -1;
if (curgame_dir && !access(dirpath(THEME_FILE), R_OK)) {
game_own_theme = 1;
}
if (game_own_theme && opt_owntheme) {
if (theme_load(dirpath(THEME_FILE)))
return -1;
} else if (curtheme_dir && strcmp(DEFAULT_THEME, curtheme_dir)) {
game_theme_load(curtheme_dir);
}
if (game_apply_theme()) {
game_theme_select(DEFAULT_THEME);
return -1;
}
timer_han = gfx_add_timer(HZ, counter_fn, NULL);
if (!curgame_dir) {
game_menu(menu_games);
} else {
if (!game_load(-1)) /* tmp save */
return 0;
goto out;
if (opt_autosave && !game_load(0)) /* autosave */
return 0;
goto out;
game_cmd("look");
custom_theme_warn();
if (opt_autosave)
game_save(0);
}
out:
return 0;
}
@ -760,10 +801,35 @@ void free_last(void)
sounds_free();
}
void game_done(int err)
void game_release_theme(void)
{
int i;
mouse_reset(1);
game_cursor(CURSOR_OFF);
if (el_img(el_spic))
gfx_free_image(el_img(el_spic));
for (i = 0; i < el_max; i++) {
struct el *o;
o = el(i);
if (o->type == elt_layout && o->p.p) {
txt_layout_free(o->p.lay);
} else if (o->type == elt_box && o->p.p) {
txt_layout_free(txt_box_layout(o->p.box));
txt_box_free(o->p.box);
}
o->p.p = NULL;
o->drawn = 0;
}
if (menu)
gfx_free_image(menu);
if (menubg)
gfx_free_image(menubg);
menu = menubg = NULL;
}
void game_done(int err)
{
gfx_del_timer(timer_han);
timer_han = NULL;
@ -774,33 +840,8 @@ void game_done(int err)
if (menu_shown)
menu_toggle();
mouse_reset(1);
game_cursor(CURSOR_OFF);
if (el_img(el_spic))
gfx_free_image(el_img(el_spic));
for (i = 0; i < el_max; i++) {
struct el *o;
o = el(i);
// if (o->type == elt_image && o->p.p) {
// if (!o->clone)
// gfx_free_image(o->p.img);
// } else
if (o->type == elt_layout && o->p.p) {
txt_layout_free(o->p.lay);
} else if (o->type == elt_box && o->p.p) {
txt_layout_free(txt_box_layout(o->p.box));
txt_box_free(o->p.box);
}
o->p.p = NULL;
o->drawn = 0;
}
game_release_theme();
free_last();
if (menu)
gfx_free_image(menu);
if (menubg)
gfx_free_image(menubg);
menu = menubg = NULL;
game_theme_free();
input_clear();
snd_done();
@ -907,29 +948,45 @@ void box_update_scrollbar(int n)
int off;
int w, h, hh;
el_size(n, &w, &h);
x1 = el(n)->x + w + game_theme.pad;
y1 = el(n)->y;
x2 = x1;
y2 = y1 + h - gfx_img_h(game_theme.a_down);
l = txt_box_layout(el_box(n));
txt_layout_real_size(l, NULL, &hh);
off = txt_box_off(el_box(n));
if (n == el_scene) {
elup = el(el_sup);
eldown = el(el_sdown);
x1 = game_theme.a_up_x;
y1 = game_theme.a_up_y;
x2 = game_theme.a_down_x;
y2 = game_theme.a_down_y;
// elslide = el(el_sslide);
} else if (n == el_inv) {
elup = el(el_iup);
eldown = el(el_idown);
x1 = game_theme.inv_a_up_x;
y1 = game_theme.inv_a_up_y;
x2 = game_theme.inv_a_down_x;
y2 = game_theme.inv_a_down_y;
// elslide = el(el_islide);
}
if (!elup || !eldown)
return;
if (x1 == -1 || y1 == -1 || x2 == -1 || y2 == -1)
el_size(n, &w, &h);
if (x1 == -1)
x1 = el(n)->x + w + game_theme.pad;
if (y1 == -1)
y1 = el(n)->y;
if (x2 == -1)
x2 = x1;
if (y2 == -1)
y2 = y1 + h - gfx_img_h(game_theme.a_down);
l = txt_box_layout(el_box(n));
txt_layout_real_size(l, NULL, &hh);
off = txt_box_off(el_box(n));
if (el_clear(elup->id)) {
if (elup->x != x1 || elup->y != y1)
el_update(elup->id);
@ -1026,7 +1083,7 @@ int game_menu_box_wh(const char *txt, int *w, int *h)
int b = game_theme.border_w;
int pad = game_theme.pad;
lay = txt_layout(game_theme.menu_font, ALIGN_CENTER, game_theme.win_w - 2 * (b + pad), 0);
lay = txt_layout(game_theme.menu_font, ALIGN_CENTER, game_theme.w - 2 * (b + pad), 0);
txt_layout_set(lay, (char*)txt);
txt_layout_real_size(lay, w, h);
txt_layout_free(lay);
@ -1084,6 +1141,8 @@ void game_menu_box_width(int show, const char *txt, int width)
txt_layout_color(lay, game_theme.menu_fg);
txt_layout_link_color(lay, game_theme.menu_link);
txt_layout_active_color(lay, game_theme.menu_alink);
txt_layout_font_height(lay, game_theme.menu_font_height);
txt_layout_set(lay, (char*)txt);
txt_layout_real_size(lay, &w, &h);
if (width)
@ -1096,8 +1155,8 @@ void game_menu_box_width(int show, const char *txt, int width)
gfx_img_fill(menu, 0, 0, w + (b + pad)*2, h + (b + pad)*2, game_theme.border_col);
gfx_img_fill(menu, b, b, w + pad*2, h + pad*2, game_theme.menu_bg);
gfx_set_alpha(menu, game_theme.menu_alpha);
x = (game_theme.win_w - w)/2 + game_theme.win_x; //(game_theme.w - w)/2;
y = (game_theme.win_h - h)/2 + game_theme.win_y; //(game_theme.h - h)/2;
x = (game_theme.w - w)/2;
y = (game_theme.h - h)/2;
mx = x - b - pad;
my = y - b - pad;
mw = w + (b + pad) * 2;
@ -1177,24 +1236,6 @@ static int check_fading(void)
return rc?st:0;
}
void scene_scrollbar(void)
{
layout_t l;
int h, off;
int hh;
el_clear(el_sdown);
el_clear(el_sup);
el_size(el_scene, NULL, &hh);
el(el_sup)->y = el(el_scene)->y;
l = txt_box_layout(el_box(el_scene));
txt_layout_size(l, NULL, &h);
off = txt_box_off(el_box(el_scene));
if (h - off >= hh)
el_draw(el_sdown);
if (off)
el_draw(el_sup);
}
static void game_autosave(void)
{
int b,r;
@ -1315,6 +1356,15 @@ static void sounds_free(void)
}
}
static void sounds_reload(void)
{
int i;
for (i = 0; i < MAX_WAVS; i++) {
snd_free_wav(wavs[i].wav);
wavs[i].wav = snd_load_wav(wavs[i].fname);
}
}
void game_sound_player(void)
{
wav_t w;
@ -1391,15 +1441,19 @@ static void scroll_to_diff(const char *cmdstr, int cur_off)
int off = 0;
int pos = 0;
int h = 0;
int hh = 0;
pos = find_diff_pos(cmdstr, last_cmd);
if (pos == -1)
off = cur_off;
else
off = txt_layout_pos2off(txt_box_layout(el_box(el_scene)), pos);
off = txt_layout_pos2off(txt_box_layout(el_box(el_scene)), pos, &hh);
el_size(el_scene, NULL, &h);
if (cur_off <= off && (cur_off + h) > off)
if (cur_off <= off && (cur_off + h) > off + hh) {
off = cur_off;
txt_box_scroll(el_box(el_scene), off);
hh = 0;
} else if (off < cur_off || off + hh <= cur_off + h)
hh = 0;
txt_box_scroll(el_box(el_scene), off + hh);
}
int game_highlight(int x, int y, int on);
@ -1446,6 +1500,9 @@ int game_cmd(char *cmd)
fading = check_fading();
if (game_theme_changed == 2 && opt_owntheme && !fading)
fading = 1; /* one frame at least */
if (fading) { /* take old screen */
game_cursor(CURSOR_CLEAR);
img_t offscreen = gfx_new(game_theme.w, game_theme.h);
@ -1453,14 +1510,22 @@ int game_cmd(char *cmd)
gfx_draw(oldscreen, 0, 0);
}
if (game_theme_changed == 2 && opt_owntheme) {
game_theme_update();
game_theme_changed = 1;
new_place = 1;
if (pict)
new_pict = 1;
}
if (new_place)
el_clear(el_title);
if (title && *title) {
snprintf(buf, sizeof(buf), "<b><c><a:look>%s</a></c></b>", title);
snprintf(buf, sizeof(buf), "<a:look>%s</a>", title);
txt_layout_set(el_layout(el_title), buf);
txt_layout_size(el_layout(el_title), NULL, &title_h);
title_h += game_theme.font_size / 2; // todo?
title_h += game_theme.font_size * game_theme.font_height / 2; // todo?
} else
txt_layout_set(el_layout(el_title), NULL);
@ -1538,8 +1603,9 @@ int game_cmd(char *cmd)
p = malloc(strlen(cmdstr) + ((waystr)?strlen(waystr):0) + 16);
if (p) {
*p = 0;
if (waystr) {
strcpy(p, waystr);
if ((waystr && *waystr) || el_img(el_spic)) { /* is this hack needed? */
if (waystr)
strcpy(p, waystr);
strcat(p, "\n"); /* small hack */
}
strcat(p, cmdstr);
@ -1563,6 +1629,7 @@ int game_cmd(char *cmd)
last_cmd = cmdstr;
el(el_ways)->y = el(el_title)->y + title_h + pict_h;
if (waystr)
free(waystr);
@ -1602,7 +1669,6 @@ inv:
el_clear(el_inv);
el_draw(el_inv);
}
// scene_scrollbar();
if (fading) {
img_t offscreen;
@ -2598,9 +2664,8 @@ int game_loop(void)
game_save(9);
} else if (!is_key(&ev, "f9") && curgame_dir && !menu_shown) {
if (!access(game_save_path(0, 9), R_OK)) {
mouse_reset(1);
game_select(curgame_dir);
game_load(9);
if (!game_reset())
game_load(9);
}
} else if (!is_key(&ev, "f5") && curgame_dir && !menu_shown) {
mouse_reset(1);

View file

@ -9,6 +9,7 @@
#define HZ 100
extern int game_running;
extern int game_theme_changed;
extern int nosound_sw;
extern int alsa_sw;
@ -29,10 +30,15 @@ extern char *game_tmp_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(int err);
extern int game_load_theme(const char *path);
extern int game_apply_theme(void);
extern int game_use_theme(void);
extern void game_release_theme(void);
extern int game_reset(void);
extern void game_music_player(void);
extern void game_stop_mus(int ms);

View file

@ -582,7 +582,11 @@ img_t gfx_alpha_img(img_t src, int alpha)
Uint32 col;
int size;
SDL_Surface *img = SDL_DisplayFormatAlpha((SDL_Surface*)src);
SDL_Surface *img;
if (screen)
img = SDL_DisplayFormatAlpha((SDL_Surface*)src);
else
img = gfx_new(Surf(src)->w, Surf(src)->h);
if (!img)
return NULL;
ptr = (Uint32*)img->pixels;
@ -613,30 +617,123 @@ img_t gfx_combine(img_t src, img_t dst)
return new;
}
/* blank:WxH */
static img_t _gfx_load_special_image(char *filename)
static img_t img_pad(char *fname)
{
int l,r,t,b, rc;
img_t img, img2;
int wh[2] = { 0, 0 };
if (strncmp(filename, "blank:", 6))
SDL_Rect to;
char *p = fname;
p += strcspn(p, ",");
if (*p != ',')
return NULL;
filename += 6;
if (parse_mode(filename, wh))
p ++;
rc = sscanf(fname, "%d %d %d %d,", &t, &r, &b, &l);
if (rc == 1) {
r = b = l = t;
} else if (rc == 2) {
b = t; l = r;
} else if (rc == 3) {
l = r;
} else if (rc == 4) {
;
} else
return NULL;
if (wh[0] <= 0 || wh[1] <= 0)
return NULL;
img = gfx_new(wh[0], wh[1]);
img = gfx_load_image(p);
if (!img)
return NULL;
img2 = gfx_alpha_img(img, 0);
img2 = gfx_new(gfx_img_w(img) + l + r, gfx_img_h(img) + t + b);
if (!img2) {
gfx_free_image(img);
return NULL;
} else {
img_t img = gfx_alpha_img(img2, 0);
if (img) {
gfx_free_image(img2);
img2 = img;
}
}
to.x = l;
to.y = t;
SDL_gfxBlitRGBA(img, NULL, img2, &to);
gfx_free_image(img);
return img2;
}
/* blank:WxH */
static img_t _gfx_load_special_image(char *f)
{
int alpha = 0;
int blank = 0;
char *filename;
img_t img, img2;
char *pc = NULL, *pt = NULL;
int wh[2] = { 0, 0 };
if (!f)
return NULL;
if (!(f = filename = strdup(f)))
return NULL;
if (!strncmp(filename, "blank:", 6)) {
filename += 6;
blank = 1;
} else if (!strncmp(filename, "box:", 4)) {
filename += 4;
alpha = 255;
} else if (!strncmp(filename, "pad:", 4)) {
filename += 4;
img2 = img_pad(filename);
goto out;
} else
goto err;
if (strchr(filename, ';'))
goto err; /* combined */
if (blank)
goto skip;
pc = filename + strcspn(filename, ",");
if (*pc == ',') {
*pc = 0;
pc ++;
pt = pc + strcspn(pc, ",");
if (*pt == ',') {
*pt = 0;
pt ++;
} else
pt = NULL;
} else
pc = NULL;
skip:
if (parse_mode(filename, wh))
goto err;
if (wh[0] <= 0 || wh[1] <= 0)
goto err;
img = gfx_new(wh[0], wh[1]);
if (!img)
goto err;
if (pc) {
color_t col = { .r = 255, .g = 255, .b = 255 };
gfx_parse_color(pc, &col);
gfx_img_fill(img, 0, 0, wh[0], wh[1], col);
}
if (pt)
alpha = atoi(pt);
img2 = gfx_alpha_img(img, alpha);
gfx_free_image(img);
out:
free(f);
return img2;
err:
free(f);
return NULL;
}
static img_t _gfx_load_image(char *filename)
{
SDL_Surface *img;
int nr = 0;
filename = strip(filename);
img = _gfx_load_special_image(filename);
if (img)
return img;
@ -1198,6 +1295,7 @@ struct word {
int w;
int unbrake;
int valign;
int img_align;
char *word;
img_t img;
struct word *next; /* in line */
@ -1231,6 +1329,7 @@ struct word *word_new(const char *str)
w->xref = NULL;
w->style = 0;
w->img = NULL;
w->img_align = 0;
w->unbrake = 0;
w->prerend = NULL;
w->hlprerend = NULL;
@ -1238,6 +1337,7 @@ struct word *word_new(const char *str)
}
struct line {
int x;
int y;
int h;
int w;
@ -1250,6 +1350,7 @@ struct line {
struct layout *layout;
};
static int vertical_align(struct word *w, int *hh);
int word_geom(word_t v, int *x, int *y, int *w, int *h)
{
@ -1261,14 +1362,10 @@ int word_geom(word_t v, int *x, int *y, int *w, int *h)
return -1;
img = word->img;
line = word->line;
xx = word->x;
yy = line->y;
xx = word->x + line->x;
ww = word->w;
hh = line->h;
if (img) { /* todo */
hh = gfx_img_h(img);
yy += (line->h - hh) / 2;
}
yy = line->y;
yy += vertical_align(v, &hh);
if (x)
*x = xx;
if (y)
@ -1289,6 +1386,7 @@ struct line *line_new(void)
l->words = NULL;
l->next = NULL;
l->prev = NULL;
l->x = 0;
l->w = 0;
l->y = 0;
l->h = 0;
@ -1310,7 +1408,7 @@ void line_justify(struct line *line, int width)
w = line->words;
while (w) {
lw += w->w;
if (!w->unbrake)
if (!w->unbrake && !w->img_align)
lnum ++;
w = w->next;
}
@ -1320,14 +1418,15 @@ void line_justify(struct line *line, int width)
sp = (width - lw) / (lnum - 1);
spm = (width - lw) % (lnum - 1);
while (w) {
w->x = x;
if (w->next && w->next->unbrake)
x += w->w;
else {
x += w->w + sp + ((spm)?1:0);
if (spm)
spm --;
if (!w->img_align) {
w->x = x;
if (w->next && w->next->unbrake)
x += w->w;
else {
x += w->w + sp + ((spm)?1:0);
if (spm)
spm --;
}
}
w = w->next;
}
@ -1342,7 +1441,9 @@ void line_right(struct line *line, int width)
sp = width - line->w;
w = line->words;
while (w) {
w->x += sp;
if (!w->img_align) {
w->x += sp;
}
w = w->next;
}
}
@ -1355,7 +1456,9 @@ void line_center(struct line *line, int width)
sp = (width - line->w)/2;
w = line->words;
while (w) {
w->x += sp;
if (!w->img_align) {
w->x += sp;
}
w = w->next;
}
}
@ -1440,9 +1543,36 @@ void image_free(struct image *image)
struct textbox;
#define ALIGN_NEST 16
struct margin;
struct margin {
struct margin *next;
int w;
int h;
int y;
int align;
struct word *word;
};
struct margin *margin_new(void)
{
struct margin *m = malloc(sizeof(struct margin));
if (!m)
return NULL;
m->w = m->h = m->align = 0;
m->next = NULL;
return m;
}
void margin_free(struct margin *m)
{
if (m)
free(m);
}
struct layout {
fnt_t fn;
float fn_height;
color_t col;
color_t lcol;
color_t acol;
@ -1450,6 +1580,7 @@ struct layout {
struct xref *xrefs;
struct line *lines;
struct textbox *box;
struct margin *margin;
int w;
int h;
int align;
@ -1466,11 +1597,6 @@ struct layout {
cache_t hlprerend_cache;
};
struct word_list {
struct word_list *next;
struct word *word;
};
struct xref {
struct xref *next;
struct xref *prev;
@ -1563,6 +1689,43 @@ void layout_add_line(struct layout *layout, struct line *line)
return;
}
void layout_add_margin(struct layout *layout, struct margin *margin)
{
struct margin *m = layout->margin;
if (!m) {
layout->margin = margin;
return;
}
while (m->next)
m = m->next;
m->next = margin;
return;
}
int layout_find_margin(struct layout *layout, int y, int *w)
{
struct margin *m = layout->margin;
int xpos = 0;
int rpos = layout->w;
if (!m) {
if (w)
*w = layout->w;
return 0;
}
while (m) {
if (y >= m->y && y < m->y + m->h) {
if (m->align == ALIGN_LEFT)
xpos = (xpos < m->w)?m->w:xpos;
else
rpos = (rpos > layout->w - m->w)?layout->w - m->w:rpos;
}
m = m->next;
}
if (w)
*w = rpos - xpos;
return xpos;
}
struct image *_layout_lookup_image(struct layout *layout, const char *name)
{
struct image *g = layout->images;
@ -1641,11 +1804,13 @@ struct layout *layout_new(fnt_t fn, int w, int h)
l->w = w;
l->h = h;
l->fn = fn;
l->fn_height = 1.0f;
l->align = ALIGN_JUSTIFY;
l->valign = 0;
l->style = 0;
l->lstyle = 0;
l->xrefs = NULL;
l->margin = NULL;
l->col = gfx_col(0, 0, 0);
l->lcol = gfx_col(0, 0, 255);
l->acol = gfx_col(255, 0, 0);
@ -1693,6 +1858,7 @@ void _txt_layout_free(layout_t lay)
struct line *l;
struct image *g;
struct xref *x;
struct margin *m;
if (!layout)
return;
l = layout->lines;
@ -1707,6 +1873,12 @@ void _txt_layout_free(layout_t lay)
x = x->next;
xref_free(ox);
}
m = layout->margin;
while (m) {
struct margin *om = m;
m = m->next;
margin_free(om);
}
g = layout->images;
while (g) {
struct image *og = g;
@ -1719,6 +1891,8 @@ void _txt_layout_free(layout_t lay)
layout->images = NULL;
layout->xrefs = NULL;
layout->lines = NULL;
layout->margin = NULL;
memset(layout->scnt, 0, sizeof(layout->scnt));
memset(layout->saved_align, 0, sizeof(layout->saved_align));
memset(layout->saved_valign, 0, sizeof(layout->saved_valign));
@ -2080,6 +2254,15 @@ void txt_layout_color(layout_t lay, color_t fg)
return;
layout->col = fg;
}
void txt_layout_font_height(layout_t lay, float height)
{
struct layout *layout = (struct layout*)lay;
if (!lay)
return;
layout->fn_height = height;
}
void txt_layout_link_color(layout_t lay, color_t link)
{
struct layout *layout = (struct layout*)lay;
@ -2204,6 +2387,10 @@ static int vertical_align(struct word *w, int *hh)
h = fnt_height(layout->fn);
if (hh)
*hh = h;
if (w->img && w->img_align)
return 0;
if (w->valign == ALIGN_TOP)
return 0;
else if (w->valign == ALIGN_BOTTOM)
@ -2211,6 +2398,39 @@ static int vertical_align(struct word *w, int *hh)
return (line->h - h) / 2;
}
static void word_image_render(struct word *word, int x, int y, clear_fn clear, update_fn update)
{
struct line *line = word->line;
struct layout *layout = line->layout;
int yy;
if (clear && !word->xref)
return;
yy = vertical_align(word, NULL);
if (clear) {
if (word->img) {
if (word->img_align)
clear(x + word->x, y + line->y + yy, gfx_img_w(word->img), gfx_img_h(word->img));
else
clear(x + line->x + word->x, y + line->y + yy, gfx_img_w(word->img), gfx_img_h(word->img));
} else
clear(x + line->x + word->x, y + line->y/* + yy*/, word->w, line->h);
}
if (word->img) {
if (word->img_align)
gfx_draw(word->img, x + word->x, y + line->y + yy);
else
gfx_draw(word->img, x + line->x + word->x, y + line->y + yy);
if (update)
update(x + word->x, y + line->y + yy, gfx_img_w(word->img), gfx_img_h(word->img));
} else {
word_render(layout, word, x + line->x + word->x, y + yy + line->y);
if (update)
update(x + line->x + word->x, y + line->y + yy, word->w, line->h);
}
}
void xref_update(xref_t pxref, int x, int y, clear_fn clear, update_fn update)
{
int i;
@ -2227,36 +2447,19 @@ void xref_update(xref_t pxref, int x, int y, clear_fn clear, update_fn update)
}
for (i = 0; i < xref->num; i ++) {
int yy;
struct line *line;
word = xref->words[i];
line = word->line;
yy = vertical_align(word, NULL);
if (clear) {
if (word->img)
clear(x + word->x, y + line->y + yy, gfx_img_w(word->img), gfx_img_h(word->img));
else
clear(x + word->x, y + line->y/* + yy*/, word->w, line->h);
}
if (word->img) {
gfx_draw(word->img, x + word->x, y + line->y + yy);
update(x + word->x, y + line->y + yy, gfx_img_w(word->img), gfx_img_h(word->img));
continue;
}
word_render(layout, word, x + word->x, y + yy + line->y);
update(x + word->x, y + line->y + yy, word->w, line->h);
word_image_render(word, x, y, clear, update);
}
gfx_noclip();
}
void txt_layout_draw_ex(layout_t lay, struct line *line, int x, int y, int off, int height, clear_fn clear)
{
void *v;
img_t img;
struct layout *layout = (struct layout*)lay;
// struct line *line;
struct margin *margin;
struct word *word;
// line = layout->lines;
// gfx_clip(x, y, layout->w, layout->h);
@ -2264,30 +2467,24 @@ void txt_layout_draw_ex(layout_t lay, struct line *line, int x, int y, int off,
return;
for (v = NULL; (img = txt_layout_images(lay, &v)); )
gfx_dispose_gif(img);
for (margin = layout->margin; margin; margin = margin->next) {
if (margin->y + margin->h < off)
continue;
if (margin->y - off > height)
continue;
word_image_render(margin->word, x, y, clear, NULL);
}
if (!line)
line = layout->lines;
for (; line; line= line->next) {
int yy;
if ((line->y + line->h) < off)
continue;
if (line->y - off > height)
break;
for (word = line->words; word; word = word->next ) {
if (clear && !word->xref)
continue;
yy = vertical_align(word, NULL);
if (clear) {
if (word->img)
clear(x + word->x, y + line->y + yy, gfx_img_w(word->img), gfx_img_h(word->img));
else
clear(x + word->x, y + line->y/* + yy*/, word->w, line->h);
}
if (word->img) {
yy = (line->h - gfx_img_h(word->img)) / 2;
gfx_draw(word->img, x + word->x, y + line->y + yy);
continue;
}
word_render(layout, word, x + word->x, y + yy + line->y);
if (!word->img_align)
word_image_render(word, x, y, clear, NULL);
}
}
cache_shrink(layout->prerend_cache);
@ -2578,14 +2775,14 @@ xref_t txt_box_xref(textbox_t tbox, int x, int y)
yy = vertical_align(word, &hh);
if (y < line->y + yy || y > line->y + yy + hh)
continue;
if (x < word->x)
if (x < line->x + word->x)
continue;
xref = word->xref;
if (!xref)
continue;
if (x < word->x + word->w)
if (x < line->x + word->x + word->w)
break;
if (word->next && word->next->xref == xref && x < word->next->x + word->next->w) {
if (word->next && word->next->xref == xref && x < line->x + word->next->x + word->next->w) {
yy = vertical_align(word->next, &hh);
if (y < line->y + yy || y > line->y + yy + hh)
continue;
@ -2659,17 +2856,28 @@ void txt_layout_update_links(layout_t layout, int x, int y, clear_fn clear)
// gfx_noclip();
}
img_t get_img(struct layout *layout, char *p)
img_t get_img(struct layout *layout, char *p, int *al)
{
int len;
int align;
img_t img;
struct image *image;
*al = 0;
len = word_img(p, NULL);
if (!len)
return NULL;
p += 3;
p[len - 1] = 0;
align = strcspn(p, "|");
if (!p[align])
align = 0;
else {
p[align] = 0;
if (!strcmp(p + align + 1, "left"))
*al = ALIGN_LEFT;
else if (!strcmp(p + align + 1, "right"))
*al = ALIGN_RIGHT;
}
img = layout_lookup_image(layout, p);
if (img)
goto out;
@ -2691,6 +2899,8 @@ img_t get_img(struct layout *layout, char *p)
cache_add(layout->img_cache, p, img);
}
out:
if (align)
p[align] = '|';
p[len - 1] = '>';
return img;
}
@ -2869,7 +3079,7 @@ int get_unbrakable_len(struct layout *layout, const char *ptr)
return w;
}
int txt_layout_pos2off(layout_t lay, int pos)
int txt_layout_pos2off(layout_t lay, int pos, int *hh)
{
int off = 0;
struct line *line;
@ -2877,7 +3087,9 @@ int txt_layout_pos2off(layout_t lay, int pos)
if (!layout)
return 0;
for (line = layout->lines; line && (line->pos <= pos); line = line->next) {
off = line->y;
off = line->y; // + line->h;
if (hh)
*hh = line->h;
}
return off;
}
@ -2886,6 +3098,10 @@ void _txt_layout_add(layout_t lay, char *txt)
{
int sp = 0;
int saved_style;
int width;
int img_align;
struct margin *m;
struct line *line, *lastline = NULL;
struct layout *layout = (struct layout*)lay;
char *p, *eptr;
@ -2915,6 +3131,8 @@ void _txt_layout_add(layout_t lay, char *txt)
line = lastline;
}
line->x = layout_find_margin(layout, line->y, &width);
while (ptr && *ptr) {
struct word *word;
int sp2, addlen;
@ -2942,20 +3160,26 @@ void _txt_layout_add(layout_t lay, char *txt)
if (!p)
break;
addlen = get_unbrakable_len(layout, eptr);
img = get_img(layout, p);
img = get_img(layout, p, &img_align);
if (img) {
w = gfx_img_w(img);
h = gfx_img_h(img);
if (img_align && width - w <= 0)
img_align = 0;
} else {
p = get_word_token(p);
TTF_SizeUTF8((TTF_Font *)(layout->fn), p, &w, &h);
h *= layout->fn_height;
}
nl = !*p;
if (!line->h) /* first word ? */
if (!line->h && !img_align && !line->num) /* first word ? */
line->h = h;
if ((line->num && (line->w + ((sp && line->w)?spw:0) + w + addlen) > layout->w) || nl) {
if (img_align && !line->w)
line->h = 0;
if ((line->num && (line->w + ((sp && line->w)?spw:0) + w + addlen) > width) || nl) {
struct line *ol = line;
h = 0; /* reset h for new line */
if ((layout->h) && (line->y + line->h) >= layout->h)
@ -2963,8 +3187,8 @@ void _txt_layout_add(layout_t lay, char *txt)
if (line != lastline) {
layout_add_line(layout, line);
}
line_align(line, layout->w, line->align, nl);
line_align(line, width, line->align, nl);
line = line_new();
if (!line) {
free(p);
@ -2973,6 +3197,9 @@ void _txt_layout_add(layout_t lay, char *txt)
line->align = layout->align;
line->h = 0;//h;
line->y = ol->y + ol->h;
// line->x = 0;
line->x = layout_find_margin(layout, line->y, &width);
// fprintf(stderr,"%d %d\n", line->x, width);
if (nl) {
ptr = eptr + 1;
}
@ -2982,7 +3209,8 @@ void _txt_layout_add(layout_t lay, char *txt)
continue;
}
if (h > line->h)
if (h > line->h && !img_align)
line->h = h;
word = word_new(p);
@ -3003,6 +3231,35 @@ void _txt_layout_add(layout_t lay, char *txt)
word->x = line->w;
word->img = img;
word->img_align = img_align;
if (img_align && (m = margin_new())) {
int x2, w2;
x2 = layout_find_margin(layout, line->y, &w2);
if (img_align == ALIGN_LEFT) {
line->x += w;
m->w = x2 + w;
}
else
m->w = layout->w - x2 - w2 + w;
width -= w;
m->h = h;
m->y = line->y;
m->align = img_align;
m->word = word;
word->w = 0;
if (img_align == ALIGN_LEFT)
word->x = x2;
else
word->x = x2 + w2 - w;
h = 0;
w = 0;
layout_add_margin(layout, m);
}
// if (line->w)
// w += spw;
@ -3025,7 +3282,7 @@ void _txt_layout_add(layout_t lay, char *txt)
// if (line->num) {
if (line != lastline)
layout_add_line(layout, line);
line_align(line, layout->w, line->align, nl);
line_align(line, width, line->align, nl);
// } else
// line_free(line);
if (xref)
@ -3100,7 +3357,7 @@ int xref_position(xref_t x, int *xc, int *yc)
return -1;
if (xc)
*xc = word->x + (word->w + w);
*xc = line->x + word->x + (word->w + w);
if (yc)
*yc = line->y + line->h / 2;
return 0;
@ -3124,11 +3381,11 @@ xref_t txt_layout_xref(layout_t lay, int x, int y)
yy = vertical_align(word, &hh);
if (y < line->y + yy || y > line->y + yy + hh)
continue;
if (x < word->x)
if (x < line->x + word->x)
continue;
if (x <= word->x + word->w)
if (x <= line->x + word->x + word->w)
return xref;
if (word->next && word->next->xref == xref && x < word->next->x + word->next->w) {
if (word->next && word->next->xref == xref && x < line->x + word->next->x + word->next->w) {
yy = vertical_align(word->next, &hh);
if (y < line->y + yy || y > line->y + yy + hh)
continue;
@ -3198,6 +3455,7 @@ void txt_layout_real_size(layout_t lay, int *pw, int *ph)
{
int w = 0;
int h = 0;
struct margin *margin;
struct line *line;
struct layout *layout = (struct layout*)lay;
if (!layout)
@ -3210,6 +3468,12 @@ void txt_layout_real_size(layout_t lay, int *pw, int *ph)
if (line->num && line->y + line->h > h)
h = line->y + line->h;
}
for (margin = layout->margin; margin; margin = margin->next) {
if (margin->y + margin->h > h)
h = margin->y + margin->h;
}
if (pw)
*pw = w;
if (ph)

View file

@ -103,6 +103,7 @@ extern void txt_layout_free(layout_t lay);
extern xref_t txt_layout_xref(layout_t lay, int x, int y);
extern void txt_layout_color(layout_t lay, color_t fg);
extern fnt_t txt_layout_font(layout_t lay);
extern void txt_layout_font_height(layout_t lay, float height);
extern void txt_layout_link_color(layout_t lay, color_t link);
extern void txt_layout_active_color(layout_t lay, color_t link);
@ -135,7 +136,7 @@ typedef void (*clear_fn)(int x, int y, int w, int h);
extern void txt_box_update_links(textbox_t tbox, int x, int y, clear_fn);
extern void txt_layout_update_links(layout_t layout, int x, int y, clear_fn clear);
extern void txt_layout_real_size(layout_t lay, int *w, int *h);
extern int txt_layout_pos2off(layout_t lay, int pos);
extern int txt_layout_pos2off(layout_t lay, int pos, int *hh);
extern img_t txt_box_render(textbox_t tbox);

View file

@ -6,6 +6,9 @@
#include "internals.h"
/* the Lua interpreter */
static gtimer_t instead_timer = NULL;
static int instead_timer_nr = 0;
char *fromgame(const char *s);
char *togame(const char *s);
lua_State *L = NULL;
@ -24,6 +27,8 @@ static int report (lua_State *L, int status)
free(p);
lua_pop(L, 1);
status = -1;
gfx_del_timer(instead_timer); /* to avoid error loops */
instead_timer = NULL;
}
return status;
}
@ -91,7 +96,6 @@ char *getstring(char *cmd)
return s;
}
int instead_eval(char *s)
{
if (!L)
@ -450,8 +454,6 @@ static int luaB_get_steadpath(lua_State *L) {
return 1;
}
static gtimer_t instead_timer = NULL;
static int instead_timer_nr = 0;
extern void mouse_reset(int hl); /* too bad */
@ -487,6 +489,7 @@ static int luaB_set_timer(lua_State *L) {
const char *delay = luaL_optstring(L, 1, NULL);
int d;
gfx_del_timer(instead_timer);
instead_timer = NULL;
if (!delay)
d = 0;
else
@ -498,6 +501,31 @@ static int luaB_set_timer(lua_State *L) {
return 0;
}
extern int theme_setvar(char *name, char *val);
extern char *theme_getvar(const char *name);
static int luaB_theme_var(lua_State *L) {
const char *var = luaL_optstring(L, 1, NULL);
const char *val = luaL_optstring(L, 2, NULL);
if (var && !val) { /* get */
char *p = theme_getvar(var);
if (p) {
lua_pushstring(L, p);
free(p);
return 1;
}
return 0;
}
if (!val || !var)
return 0;
game_own_theme = 1;
if (!opt_owntheme)
return 0;
if (!theme_setvar((char*)var, (char*)val))
game_theme_changed = 2;
return 0;
}
static const luaL_Reg base_funcs[] = {
{"doencfile", luaB_doencfile},
{"dofile", luaB_dofile},
@ -507,6 +535,7 @@ static const luaL_Reg base_funcs[] = {
{"get_gamepath", luaB_get_gamepath},
{"get_steadpath", luaB_get_steadpath},
{"set_timer", luaB_set_timer},
{"theme_var", luaB_theme_var},
{NULL, NULL}
};
@ -582,6 +611,7 @@ int instead_init(void)
void instead_done(void)
{
gfx_del_timer(instead_timer);
instead_timer = NULL;
#ifdef _HAVE_ICONV
if (fromcp)
free(fromcp);

View file

@ -492,10 +492,11 @@ int game_menu_act(const char *a)
if (!curgame_dir)
return 0;
// free_last();
game_select(curgame_dir);
game_menu_box(0, NULL);
game_load(nr);
cur_menu = menu_main;
if (!game_reset()) {
game_load(nr);
cur_menu = menu_main;
}
// game_menu_box(0, NULL);
} else if (!strcmp(a, "/new")) {
char *s;
@ -507,11 +508,11 @@ int game_menu_act(const char *a)
s = game_save_path(0, 0);
if (s && !access(s, R_OK) && opt_autosave)
unlink (s);
game_select(curgame_dir);
game_menu_box(0, NULL);
// instead_eval("game:ini()"); instead_clear();
game_cmd("look");
custom_theme_warn();
if (!game_reset()) {
game_cmd("look");
custom_theme_warn();
}
} else if (!strcmp(a,"/main")) {
if (restart_needed) {
game_restart();

View file

@ -1,6 +1,9 @@
#include "externals.h"
#include "internals.h"
int theme_relative = 0;
char *curtheme_dir = NULL;
static int parse_gfx_mode(const char *v, void *data)
@ -17,6 +20,29 @@ static int parse_gfx_mode(const char *v, void *data)
return 0;
}
static int out_gfx_mode(const void *v, char **out)
{
char *o;
switch (*((int*)v)) {
case GFX_MODE_FIXED:
o = strdup("fixed");
break;
case GFX_MODE_EMBEDDED:
o = strdup("embedded");
break;
case GFX_MODE_FLOAT:
o = strdup("float");
break;
default:
o = strdup("");
break;
}
if (!o)
return -1;
*out = o;
return 0;
}
static int parse_inv_mode(const char *v, void *data)
{
int *i = (int *)data;
@ -39,12 +65,53 @@ static int parse_inv_mode(const char *v, void *data)
return 0;
}
static int out_inv_mode(const void *v, char **out)
{
char *o;
int m = *((int*)v);
o = malloc(64);
if (!o)
return -1;
if (m == INV_MODE_DISABLED) {
sprintf(o, "disabled");
*out = o;
return 0;
}
if (m & INV_MODE_VERT) {
sprintf(o, "vertical");
} else if (m & INV_MODE_HORIZ) {
sprintf(o, "vertical");
}
if ((m & INV_ALIGN_SET(ALIGN_CENTER)) == INV_ALIGN_SET(ALIGN_CENTER)) {
strcat(o, "-center");
} else if ((m & INV_ALIGN_SET(ALIGN_LEFT)) == INV_ALIGN_SET(ALIGN_LEFT)) {
strcat(o, "-left");
} else if ((m & INV_ALIGN_SET(ALIGN_RIGHT)) == INV_ALIGN_SET(ALIGN_RIGHT)) {
strcat(o, "-right");
}
*out = o;
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 out_color(const void *v, char **out)
{
char *o;
color_t *c = (color_t *)v;
o = malloc(16);
if (!o)
return -1;
sprintf(o, "#%02x%02x%02x", c->r, c->g, c->b);
*out = o;
return 0;
}
static int parse_include(const char *v, void *data)
{
int rc;
@ -59,18 +126,17 @@ static int parse_include(const char *v, void *data)
setdir(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_full_path, &game_theme.bg_name },
{ "scr.gfx.cursor.normal", parse_full_path, &game_theme.cursor_name },
{ "scr.gfx.bg", parse_full_path, &game_theme.bg_name, CHANGED_BG },
{ "scr.gfx.cursor.normal", parse_full_path, &game_theme.cursor_name, CHANGED_CURSOR },
{ "scr.gfx.cursor.x", parse_int, &game_theme.cur_x },
{ "scr.gfx.cursor.y", parse_int, &game_theme.cur_y },
{ "scr.gfx.use", parse_full_path, &game_theme.use_name }, /* compat */
{ "scr.gfx.cursor.use", parse_full_path, &game_theme.use_name },
{ "scr.gfx.pad", parse_int, &game_theme.pad },
{ "scr.gfx.use", parse_full_path, &game_theme.use_name, CHANGED_USE }, /* compat */
{ "scr.gfx.cursor.use", parse_full_path, &game_theme.use_name, CHANGED_USE },
{ "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 },
@ -79,33 +145,43 @@ struct parser cmd_parser[] = {
{ "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_full_path, &game_theme.font_name },
{ "win.fnt.size", parse_int, &game_theme.font_size },
{ "win.w", parse_int, &game_theme.win_w },
{ "win.h", parse_int, &game_theme.win_h },
{ "win.fnt.name", parse_full_path, &game_theme.font_name, CHANGED_FONT },
{ "win.fnt.size", parse_int, &game_theme.font_size, CHANGED_FONT },
{ "win.fnt.height", parse_float, &game_theme.font_height },
/* compat mode directive */
{ "win.gfx.h", parse_int, &game_theme.max_scene_h },
/* here it was */
{ "win.gfx.up", parse_full_path, &game_theme.a_up_name },
{ "win.gfx.down", parse_full_path, &game_theme.a_down_name },
{ "win.gfx.up", parse_full_path, &game_theme.a_up_name, CHANGED_UP },
{ "win.gfx.down", parse_full_path, &game_theme.a_down_name, CHANGED_DOWN },
{ "win.up.x", parse_int, &game_theme.a_up_x },
{ "win.up.y", parse_int, &game_theme.a_up_y },
{ "win.down.x", parse_int, &game_theme.a_down_x },
{ "win.down.y", parse_int, &game_theme.a_down_y },
{ "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.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.horiz", parse_inv_mode, &game_theme.inv_mode },
{ "inv.col.fg", parse_color, &game_theme.icol },
{ "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_full_path, &game_theme.inv_font_name },
{ "inv.fnt.size", parse_int, &game_theme.inv_font_size },
{ "inv.gfx.up", parse_full_path, &game_theme.inv_a_up_name },
{ "inv.gfx.down", parse_full_path, &game_theme.inv_a_down_name },
{ "inv.fnt.name", parse_full_path, &game_theme.inv_font_name, CHANGED_IFONT },
{ "inv.fnt.size", parse_int, &game_theme.inv_font_size, CHANGED_IFONT },
{ "inv.fnt.height", parse_float, &game_theme.inv_font_height },
{ "inv.gfx.up", parse_full_path, &game_theme.inv_a_up_name, CHANGED_IUP },
{ "inv.gfx.down", parse_full_path, &game_theme.inv_a_down_name, CHANGED_IDOWN },
{ "inv.up.x", parse_int, &game_theme.inv_a_up_x },
{ "inv.up.y", parse_int, &game_theme.inv_a_up_y },
{ "inv.down.x", parse_int, &game_theme.inv_a_down_x },
{ "inv.down.y", parse_int, &game_theme.inv_a_down_y },
{ "menu.col.bg", parse_color, &game_theme.menu_bg },
{ "menu.col.fg", parse_color, &game_theme.menu_fg },
@ -113,21 +189,67 @@ struct parser cmd_parser[] = {
{ "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_full_path, &game_theme.menu_font_name },
{ "menu.fnt.size", parse_int, &game_theme.menu_font_size },
{ "menu.gfx.button", parse_full_path, &game_theme.menu_button_name },
{ "menu.bw", parse_int, &game_theme.border_w},
{ "menu.fnt.name", parse_full_path, &game_theme.menu_font_name, CHANGED_MFONT },
{ "menu.fnt.size", parse_int, &game_theme.menu_font_size, CHANGED_MFONT },
{ "menu.fnt.height", parse_float, &game_theme.menu_font_height },
{ "menu.gfx.button", parse_full_path, &game_theme.menu_button_name, CHANGED_BUTTON },
{ "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 },
{ "snd.click", parse_full_path, &game_theme.click_name, CHANGED_CLICK },
{ "include", parse_include, NULL },
{ NULL, },
};
#define TF_POSX 1
#define TF_POSY 2
#define TF_NEG 4
typedef struct {
const char *name;
int *val;
int flags;
} theme_scalable_t;
static theme_scalable_t theme_scalables[] = {
{ "scr.w", &game_theme.w },
{ "scr.h", &game_theme.h },
{ "scr.gfx.cursor.x", &game_theme.cur_x },
{ "scr.gfx.cursor.y", &game_theme.cur_y },
{ "scr.gfx.pad", &game_theme.pad },
{ "scr.gfx.x", &game_theme.gfx_x, TF_POSX },
{ "scr.gfx.y", &game_theme.gfx_y, TF_POSY },
{ "scr.gfx.w", &game_theme.max_scene_w, TF_NEG },
{ "scr.gfx.h", &game_theme.max_scene_h, TF_NEG },
{ "win.x", &game_theme.win_x, TF_POSX },
{ "win.y", &game_theme.win_y, TF_POSY },
{ "win.w", &game_theme.win_w },
{ "win.h", &game_theme.win_h },
{ "win.fnt.size", &game_theme.font_size },
{ "inv.x", &game_theme.inv_x, TF_POSX },
{ "inv.y", &game_theme.inv_y, TF_POSY },
{ "inv.w", &game_theme.inv_w },
{ "inv.h", &game_theme.inv_h },
{ "inv.fnt.size", &game_theme.inv_font_size },
{ "menu.fnt.size", &game_theme.menu_font_size },
{ "menu.button.x", &game_theme.menu_button_x, TF_POSX },
{ "menu.button.y", &game_theme.menu_button_y, TF_POSY },
{ "win.up.x", &game_theme.a_up_x, TF_POSX | TF_NEG },
{ "win.up.y", &game_theme.a_up_y, TF_POSY | TF_NEG },
{ "win.down.x", &game_theme.a_down_x, TF_POSX | TF_NEG },
{ "win.down.y", &game_theme.a_down_y, TF_POSY | TF_NEG },
{ "inv.up.x", &game_theme.inv_a_up_x, TF_POSX | TF_NEG },
{ "inv.up.y", &game_theme.inv_a_up_y, TF_POSY | TF_NEG },
{ "inv.down.x", &game_theme.inv_a_down_x, TF_POSX | TF_NEG },
{ "inv.down.y", &game_theme.inv_a_down_y, TF_POSY | TF_NEG },
{ NULL, },
};
static int theme_scalables_unscaled[sizeof(theme_scalables)/sizeof(theme_scalable_t)];
struct game_theme game_theme = {
.scale = 1.0f,
.w = 800,
@ -141,18 +263,29 @@ struct game_theme game_theme = {
.cur_x = 0,
.cur_y = 0,
.font_name = NULL,
.font_height = 1.0f,
.font = NULL,
.a_up_name = NULL,
.a_down_name = NULL,
.a_up = NULL,
.a_down = NULL,
.a_up_x = -1,
.a_up_y = -1,
.a_down_x = -1,
.a_down_y = -1,
.inv_font_name = NULL,
.inv_font = NULL,
.inv_font_height = 1.0f,
.inv_a_up_name = NULL,
.inv_a_down_name = NULL,
.inv_a_up_x = -1,
.inv_a_up_y = -1,
.inv_a_down_x = -1,
.inv_a_down_y = -1,
.inv_a_up = NULL,
.inv_a_down = NULL,
.menu_font_name = NULL,
.menu_font_height = 1.0f,
.menu_font = NULL,
.menu_button_name = NULL,
.menu_button = NULL,
@ -162,8 +295,9 @@ struct game_theme game_theme = {
.click = NULL,
.xoff = 0,
.yoff = 0,
.changed = 0,
};
struct game_theme game_theme;
static void free_theme_strings(void)
{
@ -179,7 +313,7 @@ static void free_theme_strings(void)
FREE(t->inv_font_name);
FREE(t->menu_font_name);
FREE(t->menu_button_name);
/* FREE(t->click_name); must be reloaded, ugly :(*/
FREE(t->click_name);
}
int game_theme_free(void)
@ -221,7 +355,6 @@ int game_theme_free(void)
game_theme.bg = NULL;
game_theme.click = NULL;
game_theme.cur_x = game_theme.cur_y = 0;
// game_theme.slide = gfx_load_image("slide.png", 1);
return 0;
}
@ -238,9 +371,9 @@ int theme_img_scale(img_t *p)
*p = pic;
return 0;
}
static int game_theme_scale(int w, int h)
{
int i;
float xs, ys, v;
int xoff, yoff;
struct game_theme *t = &game_theme;
@ -249,9 +382,10 @@ static int game_theme_scale(int w, int h)
t->scale = 1.0f;
t->xoff = 0;
t->yoff = 0;
return 0;
w = t->w;
h = t->h;
goto out;
}
xs = (float)w / (float)t->w;
ys = (float)h / (float)t->h;
@ -259,60 +393,137 @@ static int game_theme_scale(int w, int h)
xoff = (w - t->w*v)/2;
yoff = (h - t->h*v)/2;
t->w = w;
t->h = h;
if (xoff < 0)
xoff = 0;
if (yoff < 0)
yoff = 0;
t->pad *= v;
t->win_x *= v; t->win_x += xoff;
t->win_y *= v; t->win_y += yoff;
t->win_w *= v;
t->win_h *= v;
t->font_size *= v;
t->gfx_x *= v; t->gfx_x += xoff;
t->gfx_y *= v; t->gfx_y += yoff;
if (t->max_scene_w != -1)
t->max_scene_w *= v;
if (t->max_scene_h != -1)
t->max_scene_h *= v;
t->inv_x *= v; t->inv_x += xoff;
t->inv_y *= v; t->inv_y += yoff;
t->inv_w *= v;
t->inv_h *= v;
t->inv_font_size *= v;
t->menu_font_size *= v;
t->menu_button_x *= v; t->menu_button_x += xoff;
t->menu_button_y *= v; t->menu_button_y += yoff;
t->cur_x *= v;
t->cur_y *= v;
t->scale = v;
t->xoff = xoff;
t->yoff = yoff;
out:
for (i = 0; theme_scalables[i].name; i++) {
int val = *(theme_scalables[i].val);
theme_scalables_unscaled[i] = val;
if (val == -1 && (theme_scalables[i].flags & TF_NEG))
continue;
val *= t->scale;
if (theme_scalables[i].flags & TF_POSX)
val += t->xoff;
if (theme_scalables[i].flags & TF_POSY)
val += t->yoff;
*(theme_scalables[i].val) = val;
}
t->w = w;
t->h = h;
return 0;
}
extern int parse_relative_path;
static int theme_gfx_scale(void)
char *theme_getvar(char *name)
{
struct game_theme *t = &game_theme;
if (theme_img_scale(&t->a_up) ||
theme_img_scale(&t->a_down) ||
theme_img_scale(&t->inv_a_up) ||
theme_img_scale(&t->inv_a_down) ||
theme_img_scale(&t->use) ||
theme_img_scale(&t->cursor) ||
theme_img_scale(&t->menu_button) ||
theme_img_scale(&t->bg))
int i;
for (i = 0; theme_scalables[i].name; i ++) {
int val;
char buf[64];
if (strcmp(theme_scalables[i].name, name))
continue;
val = theme_scalables_unscaled[i];
sprintf(buf, "%d", val);
return strdup(buf);
}
/* so, it is a string or like this */
for (i = 0; cmd_parser[i].cmd; i++) {
int *num;
char *s;
float *f;
char buf[64];
if (strcmp(cmd_parser[i].cmd, name))
continue;
if (cmd_parser[i].fn == parse_int) {
num = (int *)cmd_parser[i].p;
sprintf(buf, "%d", *num);
return strdup(buf);
} else if (cmd_parser[i].fn == parse_full_path) {
s = *((char **)cmd_parser[i].p);
if (!s)
return NULL;
return strdup(s);
} else if (cmd_parser[i].fn == parse_inv_mode) {
if (out_inv_mode(cmd_parser[i].p, &s))
return NULL;
return s;
} else if (cmd_parser[i].fn == parse_gfx_mode) {
if (out_gfx_mode(cmd_parser[i].p, &s))
return NULL;
return s;
} else if (cmd_parser[i].fn == parse_float) {
f = (float*)cmd_parser[i].p;
sprintf(buf, "%f", *f);
return strdup(buf);
} else if (cmd_parser[i].fn == parse_color) {
if (out_color(cmd_parser[i].p, &s))
return NULL;
return s;
} else
return NULL;
break;
}
return NULL;
}
static int theme_process_cmd(char *n, char *v, struct parser *cmd_parser)
{
int i;
n = strip(n);
v = strip(v);
if (process_cmd(n, v, cmd_parser))
return -1;
for (i = 0; cmd_parser[i].cmd; i++) {
if (!strcmp(cmd_parser[i].cmd, n)) {
game_theme.changed |= cmd_parser[i].aux;
return 0;
}
}
return -1;
}
int theme_setvar(char *name, char *val)
{
int rc = -1;
struct game_theme *t = &game_theme;
theme_relative = 1;
if (!theme_process_cmd(name, val, cmd_parser)) {
int i;
for (i = 0; theme_scalables[i].name; i++) {
int val;
if (strcmp(theme_scalables[i].name, name))
continue;
val = *(theme_scalables[i].val);
theme_scalables_unscaled[i] = val;
if (val == -1 && (theme_scalables[i].flags & TF_NEG))
continue;
val *= t->scale;
if (theme_scalables[i].flags & TF_POSX)
val += t->xoff;
if (theme_scalables[i].flags & TF_POSY)
val += t->yoff;
*(theme_scalables[i].val) = val;
break;
}
rc = 0;
}
theme_relative = 0;
return rc;
}
static int theme_bg_scale(void)
{
struct game_theme *t = &game_theme;
if (t->bg) {
img_t screen, pic;
int xoff = (t->w - gfx_img_w(t->bg))/2;
@ -359,105 +570,148 @@ int game_theme_optimize(void)
return 0;
}
int game_theme_init(int w, int h)
static int game_theme_update_data(void)
{
struct game_theme *t = &game_theme;
game_theme_scale(w, h);
if (t->font_name) {
if (t->font_name && (t->changed & CHANGED_FONT)) {
fnt_free(t->font);
if (!(t->font = fnt_load(t->font_name, FONT_SZ(t->font_size))))
goto err;
}
if (t->inv_font_name) {
if (t->inv_font_name && (t->changed & CHANGED_IFONT)) {
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) {
if (t->menu_font_name && (t->changed & CHANGED_MFONT)) {
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) {
if (t->a_up_name && (t->changed & CHANGED_UP)) {
gfx_free_image(t->a_up);
if (!(t->a_up = gfx_load_image(t->a_up_name)))
goto err;
if (theme_img_scale(&t->a_up))
goto err;
}
if (t->a_down_name) {
if (t->a_down_name && (t->changed & CHANGED_DOWN)) {
gfx_free_image(t->a_down);
if (!(t->a_down = gfx_load_image(t->a_down_name)))
goto err;
if (theme_img_scale(&t->a_down))
goto err;
}
if (t->inv_a_up_name) {
if (t->inv_a_up_name && (t->changed & CHANGED_IUP)) {
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)))
if (theme_img_scale(&t->inv_a_up))
goto err;
}
if (t->bg_name) {
if (t->inv_a_down_name && (t->changed & CHANGED_IDOWN)) {
gfx_free_image(t->inv_a_down);
if (!(t->inv_a_down = gfx_load_image(t->inv_a_down_name)))
goto err;
if (theme_img_scale(&t->inv_a_down))
goto err;
}
if (t->bg_name && (t->changed & CHANGED_BG)) {
gfx_free_image(t->bg);
t->bg = NULL;
if (t->bg_name[0] && !(t->bg = gfx_load_image(t->bg_name)))
goto err;
if (theme_img_scale(&t->bg))
goto err;
if (theme_bg_scale())
goto err;
}
if (t->use_name) {
if (t->use_name && (t->changed & CHANGED_USE)) {
gfx_free_image(t->use);
if (!(t->use = gfx_load_image(t->use_name)))
goto err;
if (theme_img_scale(&t->use))
goto err;
}
if (t->cursor_name) {
if (t->cursor_name && (t->changed & CHANGED_CURSOR)) {
gfx_free_image(t->cursor);
if (!(t->cursor = gfx_load_image(t->cursor_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)))
if (theme_img_scale(&t->cursor))
goto err;
}
if (t->click_name) {
if (t->menu_button_name && (t->changed & CHANGED_BUTTON)) {
gfx_free_image(t->menu_button);
if (!(t->menu_button = gfx_load_image(t->menu_button_name)))
goto err;
if (theme_img_scale(&t->menu_button))
goto err;
}
if (t->click_name && (t->changed & CHANGED_CLICK)) {
snd_free_wav(t->click);
t->click = snd_load_wav(t->click_name);
}
free_theme_strings();
// free_theme_strings(); /* todo, font */
t->changed = 0;
if (!t->cursor || !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. Not all required elements are defined.\n");
goto err;
}
if (theme_gfx_scale()) {
fprintf(stderr, "Can't scale theme.\n");
goto err;
}
return 0;
err:
fprintf(stderr, "Can not init theme!\n");
game_theme_free();
t->changed = 0;
return -1;
}
int game_theme_update(void)
{
game_release_theme();
if (game_theme_update_data()) {
fprintf(stderr, "Can not update theme!\n");
return -1;
}
if (game_apply_theme()) {
fprintf(stderr, "Can not apply theme!\n");
return -1;
}
return 0;
}
int game_theme_init(void)
{
int w = opt_mode[0];
int h = opt_mode[1];
if ((w == -1)
&& (gfx_get_max_mode(&w, &h) || (game_theme.w <= w && game_theme.h <= h))) {
w = opt_mode[0];
h = opt_mode[1];
}
game_theme_scale(w, h);
if (game_theme_update_data()) {
fprintf(stderr, "Can not init theme!\n");
game_theme_free();
game_theme_select(DEFAULT_THEME);
return -1;
}
return 0;
}
static int theme_parse(const char *path)
{
@ -473,8 +727,6 @@ 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;
}
@ -607,14 +859,18 @@ int game_theme_load(const char *name)
{
struct theme *theme;
char cwd[PATH_MAX];
int rel = theme_relative;
getdir(cwd, sizeof(cwd));
setdir(game_cwd);
theme = theme_lookup(name);
theme_relative = 0;
if (!theme || setdir(theme->path) || theme_load(dirpath(THEME_FILE))) {
setdir(cwd);
theme_relative = rel;
return -1;
}
setdir(cwd);
theme_relative = rel;
return 0;
}

View file

@ -33,6 +33,7 @@ struct game_theme {
char *font_name;
int font_size;
float font_height;
fnt_t font;
int gfx_x;
@ -44,6 +45,8 @@ struct game_theme {
char *a_down_name;
img_t a_up;
img_t a_down;
int a_up_x; int a_up_y;
int a_down_x; int a_down_y;
color_t fgcol;
color_t lcol;
@ -59,12 +62,16 @@ struct game_theme {
color_t iacol;
char *inv_font_name;
int inv_font_size;
float inv_font_height;
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 inv_a_up_x; int inv_a_up_y;
int inv_a_down_x; int inv_a_down_y;
// int lstyle;
// int ilstyle;
@ -78,6 +85,7 @@ struct game_theme {
int border_w;
char *menu_font_name;
int menu_font_size;
float menu_font_height;
fnt_t menu_font;
char *menu_button_name;
@ -90,8 +98,22 @@ struct game_theme {
void *click;
int xoff;
int yoff;
int changed;
};
#define CHANGED_FONT 1
#define CHANGED_IFONT 2
#define CHANGED_MFONT 4
#define CHANGED_BG 8
#define CHANGED_CLICK 0x10
#define CHANGED_CURSOR 0x20
#define CHANGED_USE 0x40
#define CHANGED_UP 0x80
#define CHANGED_DOWN 0x100
#define CHANGED_IUP 0x200
#define CHANGED_IDOWN 0x400
#define CHANGED_BUTTON 0x800
#define CHANGED_ALL 0xffff
struct theme {
char *path;
char *name;
@ -103,18 +125,25 @@ extern int themes_nr;
extern char *curtheme_dir;
extern struct game_theme game_theme;
extern struct game_theme game_theme_unscaled;
extern int game_default_theme(void);
extern int game_theme_select(const char *name);
extern int themes_lookup(const char *path);
extern int themes_rename(void);
extern int game_theme_load(const char *name);
extern int game_theme_init(void);
extern int game_theme_free(void);
extern int game_theme_init(int w, int h);
extern int game_theme_optimize(void);
extern int game_theme_update(void);
extern int theme_load(const char *name);
extern char *game_local_themes_path(void);
extern int theme_img_scale(img_t *p);
extern int theme_relative;
#define GFX_MODE_FLOAT 0
#define GFX_MODE_FIXED 1
#define GFX_MODE_EMBEDDED 2

View file

@ -51,7 +51,7 @@ char *strip(char *s)
return s;
}
static int process_cmd(char *n, char *v, struct parser *cmd_parser)
int process_cmd(char *n, char *v, struct parser *cmd_parser)
{
int i;
n = strip(n);
@ -80,6 +80,7 @@ static int fgetsesc(char *oline, size_t size, FILE *fp)
if (line[i - 1] == '\\') {
line[i - 1] = 0;
strncat(oline, line, size);
line[0] = 0;
size -= strlen(line);
if (size <= 0)
return nr;
@ -261,10 +262,38 @@ int parse_int(const char *v, void *data)
return 0;
}
int parse_float(const char *v, void *data)
{
float *f = (float *)data;
if (sscanf(v, "%f", f) != 1)
return -1;
return 0;
}
static int parse_path(const char *v, void *data)
{
char **p = ((char **)data);
if (*p)
free(*p);
if (!v[0]) {
*p = strdup("");
return (*p)?0:-1;
}
*p = strdup(v);
if (!*p)
return -1;
*p = sdl_path(*p);
return 0;
}
extern int theme_relative; /* hack, theme layer here :( */
int parse_full_path(const char *v, void *data)
{
char cwd[PATH_MAX];
char **p = ((char **)data);
if (theme_relative || !strncmp(v, "blank:", 6) || !strncmp(v, "box:", 4)) /* hack for special files*/
return parse_path(v, data);
if (*p)
free(*p);
if (!v[0]) {

View file

@ -7,6 +7,7 @@ struct parser {
const char *cmd;
parser_fn fn;
void *p;
long aux;
};
extern int is_space(int c);
@ -22,7 +23,11 @@ extern char *lookup_lang_tag(const char *fname, const char *tag, const char *com
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_float(const char *v, void *data);
extern int parse_full_path(const char *v, void *data);
extern int process_cmd(char *n, char *v, struct parser *cmd_parser);
extern char *encode_esc_string(const char *v);
extern char *find_in_esc(const char *l, const char *s);
#ifdef _HAVE_ICONV

View file

@ -25,6 +25,8 @@ install:
$(INSTALL) kbd.lua $(STEADPATH)/kbd.lua
$(INSTALL) hotkeys.lua $(STEADPATH)/hotkeys.lua
$(INSTALL) hideinv.lua $(STEADPATH)/hideinv.lua
$(INSTALL) theme.lua $(STEADPATH)/theme.lua
$(INSTALL) visual.lua $(STEADPATH)/visual.lua
uninstall:
$(RM) $(STEADPATH)/stead.lua

View file

@ -22,3 +22,5 @@ install:
copy kbd.lua ..\bin\stead
copy hotkeys.lua ..\bin\stead
copy hideinv.lua ..\bin\stead
copy theme.lua ..\bin\stead
copy visual.lua ..\bin\stead

View file

@ -3,7 +3,8 @@ format = {
para_space = ' ';
quotes = false;
dash = false;
filter = nil
filter = nil;
nopara = '_';
}
stead.fmt = stead.hook(stead.fmt, function(f, ...)
@ -26,8 +27,7 @@ stead.fmt = stead.hook(stead.fmt, function(f, ...)
r = r:gsub(',,',''):gsub("''",'');
end
if call_bool(format, 'para') then
r = r:gsub('\n([^\n])', '<&para;>%1'):gsub('<&para;>[ \t]*', '\n'..txtnb(format.para_space));
r = r:gsub('^[ \t]*',txtnb(format.para_space))
r = r:gsub('^[ \t]*', '<&para;>'):gsub('\n([^\n])', '<&para;>%1'):gsub('<&para;>[ \t]*'..format.nopara,''):gsub('<&para;>[ \t]*', '\n'..txtnb(format.para_space));
end
end
return r;

View file

@ -33,7 +33,7 @@ go = function (self, where, back, noenter, noexit, nodsc)
stead.in_exit_call = true -- to break recurse
v,r = call(ref(self.where), 'exit', ref(where));
stead.in_exit_call = nil
if r == false then
if r == false or (stead.api_version >= "1.3.0" and v == false and r == nil) then
return v, ret(r)
end
if self.where ~= was then
@ -51,7 +51,7 @@ go = function (self, where, back, noenter, noexit, nodsc)
if not jump and not noenter then
v, r = call(ref(where), 'enter', ref(was));
if r == false then
if r == false or (stead.api_version >= "1.3.0" and v == false and r == nil) then
self.where = was;
return par('^^', res, v), ret(r)
end

View file

@ -50,10 +50,19 @@ iface.img = function(self, str)
return "<g:"..str..">";
end;
iface.nb = function(self, str)
iface.imgl = function(self, str)
if str == nil then return nil; end;
if str == '' then return ''; end
return "<w:"..str..">";
return "<g:"..str.."|left>";
end;
iface.imgr = function(self, str)
if str == nil then return nil; end;
return "<g:"..str.."|right>";
end;
iface.nb = function(self, str)
if type(str) ~= 'string' then return nil end
return "<w:"..str:gsub("\\","\\\\\\\\"):gsub(">","\\\\>"):gsub("%^","\\%^")..">";
end;
iface.under = function(self, str)
@ -115,29 +124,27 @@ iface.ways = function(self, str)
end;
function get_inv(horiz)
str = iface:cmd("inv");
str = me():inv();
if str then
str = stead.string.gsub(str, '\n$','');
str = stead.string.gsub(str, '\\'..stead.delim, '<&delim;>')
str = stead.string.gsub(str, stead.delim..'$', '')
-- str = stead.string.gsub(str, stead.delim..'$', '')
if not horiz then
str = stead.string.gsub(str, stead.delim, game.gui.inv_delim);
str = stead.string.gsub(str, '\\?[\\'.. stead.delim ..']', { [stead.delim] = game.gui.inv_delim });
else
str = stead.string.gsub(str, stead.delim, game.gui.hinv_delim);
str = stead.string.gsub(str, '\\?[\\'.. stead.delim ..']', { [stead.delim] = game.gui.hinv_delim });
end
str = stead.string.gsub(str, '<&delim;>', stead.delim);
str = stead.string.gsub(str, '\\(.)', '%1');
end
return str
end
instead.get_inv = get_inv;
function get_ways()
str = iface:cmd("way");
if str then
str = me():ways();
if str and str ~= '' then
str = stead.string.gsub(str, '\n$','');
str = stead.string.gsub(str, '\\'..stead.delim, '<&delim;>');
str = stead.string.gsub(str, stead.delim, game.gui.ways_delim);
str = stead.string.gsub(str, '<&delim;>', stead.delim);
str = stead.string.gsub(str, '\\?[\\'.. stead.delim ..']', { [stead.delim] = game.gui.ways_delim });
str = stead.string.gsub(str, '\\(.)', '%1');
return iface:center(str);
end
return str
@ -152,8 +159,9 @@ function get_title()
if type(s) ~= 'string' then
s = call(here(), 'nam');
end
if type(s) == 'string' then
s = stead.string.gsub(s, '\\'..stead.delim, stead.delim);
if type(s) == 'string' and s ~= '' then
s = stead.string.gsub(s, '\\(.)', '%1');
s = "<c><b>"..s.."</b></c>";
end
return s
end
@ -246,7 +254,8 @@ fmt = function(...)
end
for i=1,stead.table.maxn(arg) do
if type(arg[i]) == 'string' then
local s = stead.string.gsub(arg[i],'\t', ' '):gsub('[\n]+', ' '):gsub('%^','\n');
local s = stead.string.gsub(arg[i],'\t', ' '):gsub('[\n]+', ' ');
s = stead.string.gsub(s, '\\?[\\^]', { ['^'] = '\n' }):gsub('\\(.)', '%1');
res = stead.par('', res, s);
end
end

View file

@ -5,7 +5,7 @@ kbden = {
["3"] = "#",
["4"] = "$",
["5"] = "%",
["6"] = "6",
["6"] = "^",
["7"] = "&",
["8"] = "*",
["9"] = "(",
@ -268,7 +268,8 @@ function input_esc(s)
return txtnb(s)
end
if not s then return end
return s:gsub("\\","\\\\"):gsub(">","\\>"):gsub("[^ ]+", rep):gsub("[ \t]", rep);
-- return s:gsub("\\","\\\\\\\\"):gsub(">","\\\\>"):gsub("%^","\\%^"):
return s:gsub("[^ ]+", rep):gsub("[ \t]", rep);
end
function inp(n, info, txt)

View file

@ -22,6 +22,12 @@ prefs = obj {
end,
purge = function(s)
local name = get_savepath() .. '/prefs';
local k,v
for k,v in pairs(s) do
if type(v) ~= 'function' and k ~= 'nam' and k ~= 'system_type' then
s[k] = nil
end
end
return stead.os.remove(name);
end
};

View file

@ -1,5 +1,5 @@
stead = {
version = "1.2.3",
version = "1.3.0",
api_version = "1.1.6", -- last version before 1.2.0
table = table,
delim = ',',
@ -205,6 +205,16 @@ function img(v)
return iface:img(v);
end
function imgl(v)
if type(v) ~= 'string' then return nil; end;
return iface:imgl(v);
end
function imgr(v)
if type(v) ~= 'string' then return nil; end;
return iface:imgr(v);
end
function txtem(v)
if type(v) ~= 'string' then return nil; end;
return iface:em(v)
@ -269,8 +279,8 @@ fmt = function(...)
if type(arg[i]) == 'string' then
local s = stead.string.gsub(arg[i],'[\t ]+',' ');
s = stead.string.gsub(s, '[\n]+', ' ');
s = stead.string.gsub(s,'%^','\n');
res = stead.par('',res,s);
s = stead.string.gsub(s, '\\?[\\^]', { ['^'] = '\n' }):gsub('\\(.)', '%1');
res = stead.par('', res, s);
end
end
return res
@ -360,7 +370,7 @@ end
function obj_xref(self,str)
function xrefrep(str)
local s = stead.string.gsub(str,'[{}]','');
local s = stead.string.gsub(str,'[\001\002]','');
return xref(s, self);
end
if not str then
@ -369,7 +379,7 @@ function obj_xref(self,str)
if not isObject(self) then
return str;
end
local s = stead.string.gsub(str,'{[^}]+}',xrefrep);
local s = stead.string.gsub(str, '\\?[\\{}]', { ['{'] = '\001', ['}'] = '\002' }):gsub('\001([^\002]+)\002', xrefrep);
return s;
end
@ -948,6 +958,9 @@ function dialog_rescan(self)
return true
end
function dialog_empty(self)
return not dialog_rescan(self);
end
function dialog_phrase(self, num)
if not tonumber(num) then
@ -1049,6 +1062,9 @@ function dlg(v) --constructor
if v.punseen == nil then
v.punseen = dialog_punseen;
end
if v.empty == nil then
v.empty = dialog_empty;
end
v = room(v);
return v;
end

View file

@ -34,15 +34,15 @@ __do_xact = function(str, self)
return ''
end
local xrefrep = function(str)
local s = stead.string.gsub(str,'[{}]','');
local s = stead.string.gsub(str,'[\001\002]','');
local o,d,a, oo;
local delim = ':'
if stead.api_version >= "1.2.2" then
delim = stead.delim;
end
s = s:gsub("\\"..delim, "<&delim;>");
local i = s:find(delim, 1, true);
s = s:gsub('\\?[\\'..delim..']', { [delim] = '\001' });
local i = s:find('\001', 1, true);
aarg = {}
if i then
o = s:sub(1, i - 1);
@ -71,20 +71,23 @@ __do_xact = function(str, self)
else
error("Wrong link: "..s, 3);
end
d = d:gsub("<&delim;>", delim);
d = d:gsub("\001", delim);
return xref(d, ref(oo, true), unpack(aarg));
end
if type(str) ~= 'string' then return end
local s = stead.string.gsub(str,'{[^}]+}', xrefrep);
local s = stead.string.gsub(str, '\\?[\\{}]', { ['{'] = '\001', ['}'] = '\002' }):gsub('\001([^\002]+)\002',xrefrep);
return s;
end
stead.fmt = stead.hook(stead.fmt, function(f, ...)
local r = f(unpack(arg))
if type(r) == 'string' and stead.state then
r = __do_xact(r);
local i, res, s
for i=1,stead.table.maxn(arg) do
if type(arg[i]) == 'string' then
s = __do_xact(arg[i]);
res = stead.par('', res, s);
end
end
return r;
return f(res);
end)
obj = stead.inherit(obj, function(v)

View file

@ -21,11 +21,16 @@ win.h = 568
win.fnt.name = sans.ttf
win.fnt.size = 16
win.fnt.height = 1.0
win.gfx.up = aup.png
win.gfx.down = adown.png
win.col.fg = black
win.col.link = #b02c00
win.col.alink = #606060
win.up.x = -1
win.up.y = -1
win.down.x = -1
win.down.y = -1
inv.x = 620
inv.y = 8
@ -34,13 +39,18 @@ inv.h = 564
inv.fnt.name = sans.ttf
inv.fnt.size = 16
inv.fnt.height = 1.0
inv.gfx.up = aup.png
inv.gfx.down = adown.png
inv.col.fg = #CCCCCC
inv.col.link = #CCCCCC
inv.col.alink = goldenrod
inv.mode = vertical
inv.up.x = -1
inv.up.y = -1
inv.down.x = -1
inv.down.y = -1
menu.col.bg = white
menu.col.fg = black
menu.col.link = blue
@ -50,6 +60,7 @@ menu.col.border = black
menu.bw = 1
menu.fnt.name = sans.ttf
menu.fnt.size = 15
menu.fnt.height = 1.0
menu.gfx.button = menu.png
menu.button.x = 776
menu.button.y = 576