DANGEROUS. working tech demo of sprites
This commit is contained in:
parent
8d4dc02cef
commit
2b7b025456
1
debian/changelog
vendored
1
debian/changelog
vendored
|
@ -5,6 +5,7 @@ instead (1.3.5) unstable; urgency=low
|
|||
* bug fix in jump to pos logic;
|
||||
* bug fix lags in sound;
|
||||
* bug fix with wince/windows with themes load;
|
||||
* experemental sprites technology;
|
||||
* global dir is now readdir;
|
||||
* multichannal sound system (add_sound, stop_sound);
|
||||
* -appdata parameter;
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
".\symbian_gamedata\stead\para.lua" -"!:\data\instead\stead\para.lua"
|
||||
".\symbian_gamedata\stead\theme.lua" -"!:\data\instead\stead\theme.lua"
|
||||
".\symbian_gamedata\stead\prefs.lua" -"!:\data\instead\stead\prefs.lua"
|
||||
".\symbian_gamedata\stead\sprites.lua" -"!:\data\instead\stead\sprites.lua"
|
||||
".\symbian_gamedata\lang\ru.ini" -"!:\data\instead\lang\ru.ini"
|
||||
".\symbian_gamedata\lang\en.ini" -"!:\data\instead\lang\en.ini"
|
||||
".\symbian_gamedata\themes\fantasy\down.png" -"!:\data\instead\themes\fantasy\down.png"
|
||||
|
|
|
@ -2,11 +2,13 @@
|
|||
#include <string.h>
|
||||
#include "list.h"
|
||||
#include "cache.h"
|
||||
extern unsigned long hash_string(const char *str);
|
||||
|
||||
#define HASH_SIZE 511
|
||||
|
||||
typedef struct {
|
||||
struct list_head list;
|
||||
struct list_head unused;
|
||||
int auto_grow;
|
||||
int size;
|
||||
int max_size;
|
||||
|
@ -56,14 +58,14 @@ static unsigned long hash_long64(unsigned long key)
|
|||
return key;
|
||||
}
|
||||
|
||||
static unsigned long hash_addr(void *p)
|
||||
unsigned long hash_addr(void *p)
|
||||
{
|
||||
if (sizeof(long) == 8)
|
||||
return hash_long64((unsigned long)p);
|
||||
return hash_long32((unsigned long)p);
|
||||
}
|
||||
|
||||
static unsigned long hash_string(const char *str)
|
||||
unsigned long hash_string(const char *str)
|
||||
{
|
||||
unsigned long hash = 0;
|
||||
int c;
|
||||
|
@ -79,6 +81,7 @@ cache_t cache_init(int size, cache_free_fn free_fn)
|
|||
if (!c)
|
||||
return NULL;
|
||||
INIT_LIST_HEAD(&c->list);
|
||||
INIT_LIST_HEAD(&c->unused);
|
||||
c->auto_grow = 0;
|
||||
c->size = 0;
|
||||
c->used = 0;
|
||||
|
@ -98,14 +101,17 @@ static void cache_e_free(cache_t cache, __cache_e_t *cc)
|
|||
__cache_t *c = cache;
|
||||
if (!c)
|
||||
return;
|
||||
free(cc->name);
|
||||
if (c->free_fn && !cc->used)
|
||||
c->free_fn(cc->data);
|
||||
|
||||
list_del(cc->hash);
|
||||
free(cc->hash);
|
||||
list_del(cc->vhash);
|
||||
list_del(&cc->list);
|
||||
|
||||
if (c->free_fn && !cc->used) {
|
||||
c->free_fn(cc->data);
|
||||
}
|
||||
free(cc->name);
|
||||
free(cc->hash);
|
||||
free(cc->vhash);
|
||||
list_del((struct list_head*)cc);
|
||||
free(cc);
|
||||
}
|
||||
|
||||
|
@ -116,6 +122,8 @@ void cache_zap(cache_t cache)
|
|||
return;
|
||||
while (!list_empty(&c->list))
|
||||
cache_e_free(cache, (__cache_e_t *)(c->list.next));
|
||||
while (!list_empty(&c->unused))
|
||||
cache_e_free(cache, (__cache_e_t *)(c->unused.next));
|
||||
c->size = 0;
|
||||
c->used = 0;
|
||||
}
|
||||
|
@ -128,7 +136,7 @@ void cache_free(cache_t cache)
|
|||
free(cache);
|
||||
}
|
||||
|
||||
static __cache_e_t *cache_lookup(cache_t cache, const char *name)
|
||||
static __cache_e_t *_cache_lookup(cache_t cache, const char *name)
|
||||
{
|
||||
struct list_head *pos;
|
||||
struct list_head *list;
|
||||
|
@ -165,11 +173,16 @@ static __cache_e_t *cache_data(cache_t cache, void *p)
|
|||
|
||||
int cache_forget(cache_t cache, void *p)
|
||||
{
|
||||
__cache_t *c = cache;
|
||||
__cache_e_t *cc = cache_data(cache, p);
|
||||
// if (cc)
|
||||
// fprintf(stderr, "Forget %p at %d\n", p, cc->used);
|
||||
if (cc && cc->used) {
|
||||
cc->used --;
|
||||
if (!cc->used)
|
||||
if (!cc->used) {
|
||||
((__cache_t*)cache)->used --;
|
||||
list_move_tail(&cc->list, &c->unused);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
|
@ -181,14 +194,26 @@ void *cache_get(cache_t cache, const char *name)
|
|||
__cache_t *c = cache;
|
||||
if (!c || !name)
|
||||
return NULL;
|
||||
cc = cache_lookup(cache, name);
|
||||
cc = _cache_lookup(cache, name);
|
||||
if (!cc)
|
||||
return NULL;
|
||||
cc->used ++; /* need again! */
|
||||
if (cc->used == 1)
|
||||
((__cache_t*)cache)->used ++;
|
||||
list_move((struct list_head*)cc, &c->list); /* first place */
|
||||
// printf("%p\n", cc->data);
|
||||
list_move(&cc->list, &c->list); /* first place */
|
||||
// printf("cache_get %s:%p %d\n", name, cc->data, cc->used);
|
||||
return cc->data;
|
||||
}
|
||||
|
||||
void *cache_lookup(cache_t cache, const char *name)
|
||||
{
|
||||
__cache_e_t *cc;
|
||||
__cache_t *c = cache;
|
||||
if (!c || !name)
|
||||
return NULL;
|
||||
cc = _cache_lookup(cache, name);
|
||||
if (!cc)
|
||||
return NULL;
|
||||
return cc->data;
|
||||
}
|
||||
|
||||
|
@ -206,14 +231,10 @@ int cache_have(cache_t cache, void *p)
|
|||
|
||||
static void __cache_shrink(__cache_t *c)
|
||||
{
|
||||
while (c->size > c->max_size) {
|
||||
__cache_e_t *cc;
|
||||
cc = (__cache_e_t *)c->list.prev;
|
||||
if (!cc->used) {
|
||||
c->size --;
|
||||
cache_e_free(c, (__cache_e_t *)c->list.prev);
|
||||
} else
|
||||
break;
|
||||
while (c->size && c->size > c->max_size && !list_empty(&c->unused)) {
|
||||
__cache_e_t *cc = (__cache_e_t *)(c->unused.next);
|
||||
c->size --;
|
||||
cache_e_free(c, cc);
|
||||
}
|
||||
// fprintf(stderr,"%d/%d\n", c->size, c->used);
|
||||
}
|
||||
|
@ -227,7 +248,7 @@ int cache_add(cache_t cache, const char *name, void *p)
|
|||
struct list_head *list;
|
||||
if (!c || !name)
|
||||
return -1;
|
||||
cc = cache_lookup(cache, name);
|
||||
cc = _cache_lookup(cache, name);
|
||||
if (cc)
|
||||
return 0;
|
||||
cc = malloc(sizeof(__cache_e_t));
|
||||
|
@ -271,6 +292,7 @@ int cache_add(cache_t cache, const char *name, void *p)
|
|||
c->used ++;
|
||||
if (c->auto_grow && c->used > c->max_size)
|
||||
c->max_size = c->used;
|
||||
// printf("cache_add %s:%p %d\n", name, cc->data, cc->used);
|
||||
// __cache_shrink(c);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,10 @@ extern int cache_forget(cache_t cache, void *p);
|
|||
extern void cache_zap(cache_t cache);
|
||||
extern void cache_shrink(cache_t cache);
|
||||
extern void *cache_get(cache_t cache, const char *name);
|
||||
extern void *cache_lookup(cache_t cache, const char *name);
|
||||
extern int cache_add(cache_t cache, const char *name, void *p);
|
||||
extern int cache_have(cache_t cache, void *p);
|
||||
extern unsigned long hash_addr(void *p);
|
||||
extern unsigned long hash_string(const char *str);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -311,8 +311,8 @@ void game_clear(int x, int y, int w, int h)
|
|||
if (menu_shown) {
|
||||
int xx = x - mx;
|
||||
int yy = y - my;
|
||||
gfx_draw_from(menubg, xx, yy, x, y, w, h);
|
||||
gfx_draw_from(menu, xx, yy, x, y, w, h);
|
||||
gfx_draw_from(menubg, xx, yy, w, h, NULL, x, y);
|
||||
gfx_draw_from(menu, xx, yy, w, h, NULL, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -358,9 +358,9 @@ enum {
|
|||
el_max,
|
||||
};
|
||||
|
||||
struct el objs[el_max];
|
||||
static struct el objs[el_max];
|
||||
|
||||
void el_set(int i, int t, int x, int y, void *p)
|
||||
static void el_set(int i, int t, int x, int y, void *p)
|
||||
{
|
||||
objs[i].id = i;
|
||||
objs[i].x = x;
|
||||
|
@ -370,27 +370,22 @@ void el_set(int i, int t, int x, int y, void *p)
|
|||
objs[i].drawn = 0;
|
||||
// objs[i].clone = 0;
|
||||
}
|
||||
void el_set_clone(int i, int t, int x, int y, void *p)
|
||||
{
|
||||
el_set(i, t, x, y, p);
|
||||
// objs[i].clone = 1;
|
||||
}
|
||||
|
||||
struct el *el(int num)
|
||||
static struct el *el(int num)
|
||||
{
|
||||
return &objs[num];
|
||||
}
|
||||
textbox_t el_box(int num)
|
||||
static textbox_t el_box(int num)
|
||||
{
|
||||
return objs[num].p.box;
|
||||
}
|
||||
|
||||
layout_t el_layout(int num)
|
||||
static layout_t el_layout(int num)
|
||||
{
|
||||
return objs[num].p.lay;
|
||||
}
|
||||
|
||||
img_t el_img(int num)
|
||||
static img_t el_img(int num)
|
||||
{
|
||||
return objs[num].p.img;
|
||||
}
|
||||
|
@ -414,7 +409,7 @@ int game_error(const char *name)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void el_draw(int n);
|
||||
static void el_draw(int n);
|
||||
|
||||
int window_sw = 0;
|
||||
int fullscreen_sw = 0;
|
||||
|
@ -645,6 +640,7 @@ int game_change_hz(int hz)
|
|||
}
|
||||
|
||||
unsigned int timer_counter = 0;
|
||||
|
||||
gtimer_t timer_han = NULL_TIMER;
|
||||
|
||||
static void anigif_do(void *data)
|
||||
|
@ -847,7 +843,7 @@ void game_done(int err)
|
|||
// SDL_Quit();
|
||||
}
|
||||
|
||||
void el_size(int i, int *w, int *h)
|
||||
static void el_size(int i, int *w, int *h)
|
||||
{
|
||||
int type;
|
||||
type = el(i)->type;
|
||||
|
@ -863,7 +859,10 @@ void el_size(int i, int *w, int *h)
|
|||
}
|
||||
}
|
||||
|
||||
int el_clear(int n)
|
||||
#define el_clear(n) _el_clear(n, game_clear)
|
||||
#define el_clear_nobg(n) _el_clear(n, NULL)
|
||||
|
||||
static int _el_clear(int n, clear_fn clear)
|
||||
{
|
||||
void *v;
|
||||
img_t img;
|
||||
|
@ -876,7 +875,8 @@ int el_clear(int n)
|
|||
y = o->y;
|
||||
el_size(n, &w, &h);
|
||||
o->drawn = 0;
|
||||
game_clear(x, y, w, h);
|
||||
if (clear)
|
||||
clear(x, y, w, h);
|
||||
if (o->type == elt_box) {
|
||||
for (v = NULL; (img = txt_layout_images(txt_box_layout(el_box(n)), &v)); )
|
||||
gfx_dispose_gif(img);
|
||||
|
@ -889,7 +889,7 @@ int el_clear(int n)
|
|||
return 1;
|
||||
}
|
||||
|
||||
void el_update(int n)
|
||||
static void el_update(int n)
|
||||
{
|
||||
int x, y, w, h;
|
||||
struct el *o;
|
||||
|
@ -904,6 +904,18 @@ void el_update(int n)
|
|||
return;
|
||||
}
|
||||
|
||||
static void el_clip(int n)
|
||||
{
|
||||
int x, y, w, h;
|
||||
struct el *o;
|
||||
o = el(n);
|
||||
x = o->x;
|
||||
y = o->y;
|
||||
el_size(n, &w, &h);
|
||||
gfx_clip(x, y, w, h);
|
||||
return;
|
||||
}
|
||||
|
||||
int box_isscroll_up(int n)
|
||||
{
|
||||
if (el(n)->type != elt_box)
|
||||
|
@ -1017,6 +1029,7 @@ void el_draw(int n)
|
|||
y = o->y;
|
||||
if (!o->p.p)
|
||||
return;
|
||||
|
||||
game_cursor(CURSOR_CLEAR);
|
||||
if (o->type == elt_image)
|
||||
gfx_draw(o->p.img, x, y);
|
||||
|
@ -1039,6 +1052,9 @@ img_t game_pict_scale(img_t img, int ww, int hh)
|
|||
game_pic_w = gfx_img_w(img);
|
||||
game_pic_h = gfx_img_h(img);
|
||||
|
||||
if (!cache_have(gfx_image_cache(), img))
|
||||
return img; /* do not scale sprites! */
|
||||
|
||||
if (game_theme.scale > 1.0f)
|
||||
theme_img_scale(&img);
|
||||
|
||||
|
@ -1205,6 +1221,7 @@ int check_new_place(char *title)
|
|||
int check_new_pict(char *pict)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!pict && !last_pict)
|
||||
return 0;
|
||||
|
||||
|
@ -1500,6 +1517,65 @@ static void scroll_to_diff(const char *cmdstr, int cur_off)
|
|||
|
||||
int game_highlight(int x, int y, int on);
|
||||
|
||||
int game_pict_modify(img_t p)
|
||||
{
|
||||
static int modify = 0;
|
||||
int last = modify;
|
||||
if (p && (el_img(el_spic) == p))
|
||||
modify = 1;
|
||||
else
|
||||
modify = 0;
|
||||
return last;
|
||||
}
|
||||
|
||||
static void game_pict_clip(void)
|
||||
{
|
||||
int x, y, w, h;
|
||||
|
||||
if (game_theme.gfx_mode == GFX_MODE_EMBEDDED) {
|
||||
el_clip(el_scene);
|
||||
return;
|
||||
}
|
||||
|
||||
if (game_theme.gfx_mode != GFX_MODE_FLOAT) {
|
||||
x = game_theme.win_x;
|
||||
y = game_theme.win_y;
|
||||
w = game_theme.win_w;
|
||||
h = game_theme.win_h;
|
||||
if (game_theme.max_scene_h >=0)
|
||||
h = game_theme.max_scene_h;
|
||||
} else {
|
||||
x = game_theme.gfx_x;
|
||||
y = game_theme.gfx_y;
|
||||
w = game_theme.max_scene_w;
|
||||
h = game_theme.max_scene_h;
|
||||
}
|
||||
gfx_clip(x, y, w, h);
|
||||
}
|
||||
|
||||
static void game_redraw_pic(void)
|
||||
{
|
||||
int x, y, ox, oy;
|
||||
if (game_pict_coord(&x, &y, NULL, NULL))
|
||||
return;
|
||||
game_pict_clip();
|
||||
|
||||
ox = el(el_spic)->x;
|
||||
oy = el(el_spic)->y;
|
||||
|
||||
el(el_spic)->x = x;
|
||||
el(el_spic)->y = y;
|
||||
|
||||
el_clear(el_spic);
|
||||
el_draw(el_spic);
|
||||
|
||||
gfx_noclip();
|
||||
el_update(el_spic);
|
||||
|
||||
el(el_spic)->x = ox;
|
||||
el(el_spic)->y = oy;
|
||||
}
|
||||
|
||||
int game_cmd(char *cmd)
|
||||
{
|
||||
int old_off;
|
||||
|
@ -1515,16 +1591,32 @@ int game_cmd(char *cmd)
|
|||
char *title = NULL;
|
||||
char *pict = NULL;
|
||||
img_t oldscreen = NULL;
|
||||
int dd = (game_theme.gfx_mode == GFX_MODE_DIRECT);
|
||||
if (menu_shown)
|
||||
return -1;
|
||||
|
||||
if (dd)
|
||||
game_cursor(CURSOR_CLEAR);
|
||||
|
||||
cmdstr = instead_cmd(cmd); instead_clear();
|
||||
|
||||
game_music_player();
|
||||
game_sound_player();
|
||||
|
||||
if (!cmdstr)
|
||||
if (game_theme.gfx_mode == GFX_MODE_DIRECT) {
|
||||
if (cmdstr)
|
||||
free(cmdstr);
|
||||
goto out;
|
||||
} else if (dd) { /* disable direct mode on the fly */
|
||||
game_theme_changed = 2; /* force redraw */
|
||||
game_cursor(CURSOR_DRAW);
|
||||
}
|
||||
|
||||
if (!cmdstr) {
|
||||
if (game_pict_modify(NULL)) /* redraw pic only */
|
||||
game_redraw_pic();
|
||||
goto inv; /* hackish? ok, yes it is... */
|
||||
}
|
||||
|
||||
fading = check_fading();
|
||||
|
||||
|
@ -1541,7 +1633,7 @@ int game_cmd(char *cmd)
|
|||
unix_path(pict);
|
||||
|
||||
new_pict = check_new_pict(pict);
|
||||
|
||||
|
||||
if (game_theme_changed == 2 && opt_owntheme && !fading)
|
||||
fading = 1; /* one frame at least */
|
||||
|
||||
|
@ -1571,14 +1663,18 @@ int game_cmd(char *cmd)
|
|||
} else
|
||||
txt_layout_set(el_layout(el_title), NULL);
|
||||
|
||||
if (new_pict || fading ||
|
||||
if (new_pict || fading || game_pict_modify(NULL) ||
|
||||
(new_place && (game_theme.gfx_mode == GFX_MODE_FIXED))) {
|
||||
redraw_pict = 1;
|
||||
}
|
||||
game_pict_clip();
|
||||
|
||||
if (redraw_pict) {
|
||||
if (el_img(el_spic)) {
|
||||
el_clear(el_spic);
|
||||
if (game_theme.gfx_mode == GFX_MODE_EMBEDDED)
|
||||
el_clear_nobg(el_spic);
|
||||
else
|
||||
el_clear(el_spic);
|
||||
if (new_pict) {
|
||||
gfx_free_image(el_img(el_spic));
|
||||
el(el_spic)->p.p = NULL;
|
||||
|
@ -1617,6 +1713,9 @@ int game_cmd(char *cmd)
|
|||
pict_h = h;
|
||||
}
|
||||
}
|
||||
gfx_noclip();
|
||||
|
||||
|
||||
/* clear area */
|
||||
el_clear(el_ways);
|
||||
el_clear(el_scene);
|
||||
|
@ -1689,11 +1788,15 @@ int game_cmd(char *cmd)
|
|||
|
||||
if (game_theme.gfx_mode != GFX_MODE_EMBEDDED) {
|
||||
el_draw(el_ways);
|
||||
if (redraw_pict)
|
||||
if (redraw_pict) {
|
||||
game_pict_clip();
|
||||
el_draw(el_spic);
|
||||
gfx_noclip();
|
||||
}
|
||||
}
|
||||
|
||||
txt_box_resize(el_box(el_scene), game_theme.win_w, game_theme.win_h - title_h - ways_h - pict_h);
|
||||
|
||||
el_draw(el_scene);
|
||||
|
||||
inv:
|
||||
|
@ -1730,6 +1833,7 @@ inv:
|
|||
gfx_cursor(&x, &y);
|
||||
game_highlight(x, y, 1);
|
||||
}
|
||||
out:
|
||||
game_cursor(CURSOR_DRAW);
|
||||
gfx_flip();
|
||||
// input_clear();
|
||||
|
@ -1844,6 +1948,9 @@ xref_t look_xref(int x, int y, struct el **elem)
|
|||
static xref_t old_xref = NULL;
|
||||
static struct el *old_el = NULL;
|
||||
|
||||
static int click_x = -1;
|
||||
static int click_y = -1;
|
||||
|
||||
int game_paused(void)
|
||||
{
|
||||
return browse_dialog || menu_shown || use_xref || old_xref || gfx_fading() || minimized();
|
||||
|
@ -1891,11 +1998,20 @@ void mouse_reset(int hl)
|
|||
game_highlight(-1, -1, 0);
|
||||
else
|
||||
game_highlight(-1, -1, -1);
|
||||
|
||||
disable_use();
|
||||
motion_mode = 0;
|
||||
|
||||
if (motion_mode) {
|
||||
click_x = -1;
|
||||
click_y = -1;
|
||||
}
|
||||
|
||||
if (hl)
|
||||
motion_mode = 0;
|
||||
old_xref = old_el = NULL;
|
||||
}
|
||||
|
||||
|
||||
static void menu_toggle(void)
|
||||
{
|
||||
mouse_reset(1);
|
||||
|
@ -1959,7 +2075,15 @@ int game_click(int x, int y, int action, int filter)
|
|||
char buf[1024];
|
||||
xref_t xref = NULL;
|
||||
char *xref_txt;
|
||||
|
||||
|
||||
if (!action) {
|
||||
click_x = x;
|
||||
click_y = y;
|
||||
} else {
|
||||
click_x = -1;
|
||||
click_y = -1;
|
||||
}
|
||||
|
||||
if (action)
|
||||
motion_mode = 0;
|
||||
|
||||
|
@ -2092,6 +2216,12 @@ int game_click(int x, int y, int action, int filter)
|
|||
return 1;
|
||||
}
|
||||
|
||||
void mouse_restore(void)
|
||||
{
|
||||
if (click_x != -1 && click_y != -1)
|
||||
game_click(click_x, click_y, 0, 0);
|
||||
}
|
||||
|
||||
void game_cursor(int on)
|
||||
{
|
||||
static img_t grab = NULL;
|
||||
|
@ -2471,12 +2601,13 @@ static int is_key(struct inp_event *ev, const char *name)
|
|||
{
|
||||
return strcmp(ev->sym, name);
|
||||
}
|
||||
|
||||
static int game_pic_coord(int x, int y, int *ox, int *oy)
|
||||
int game_pict_coord(int *x, int *y, int *w, int *h)
|
||||
{
|
||||
int xx, yy, ww, hh;
|
||||
img_t img;
|
||||
int ww, hh;
|
||||
int xx, yy;
|
||||
word_t word;
|
||||
|
||||
img = el_img(el_spic);
|
||||
if (!img)
|
||||
return -1;
|
||||
|
@ -2488,23 +2619,40 @@ static int game_pic_coord(int x, int y, int *ox, int *oy)
|
|||
goto out;
|
||||
}
|
||||
el_size(el_scene, &ww, &hh);
|
||||
|
||||
if (x < el(el_scene)->x || y < el(el_scene)->y || x >= el(el_scene)->x + ww ||
|
||||
y >= el(el_scene)->y + hh)
|
||||
return -1; /* no scene layout */
|
||||
|
||||
for (word = NULL; (word = txt_layout_words(txt_box_layout(el_box(el_scene)), word)); ) { /* scene */
|
||||
if (word_image(word) != el_img(el_spic))
|
||||
continue;
|
||||
if (word_image(word) != img) {
|
||||
word = NULL;
|
||||
/* first word is always pic */
|
||||
break;
|
||||
// continue;
|
||||
}
|
||||
word_geom(word, &xx, &yy, &ww, &hh);
|
||||
yy -= txt_box_off(el_box(el_scene));
|
||||
xx += el(el_scene)->x;
|
||||
yy += el(el_scene)->y;
|
||||
goto out;
|
||||
break;
|
||||
}
|
||||
if (!word)
|
||||
return -1;
|
||||
out:
|
||||
if (x)
|
||||
*x = xx;
|
||||
if (y)
|
||||
*y = yy;
|
||||
if (w)
|
||||
*w = ww;
|
||||
if (h)
|
||||
*h = hh;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int game_pic_click(int x, int y, int *ox, int *oy)
|
||||
{
|
||||
int xx, yy, ww, hh;
|
||||
|
||||
if (game_pict_coord(&xx, &yy, &ww, &hh))
|
||||
return -1;
|
||||
|
||||
if (x >= xx && y >= yy && x < (xx + ww) && y < (yy + hh)) {
|
||||
*ox = x - xx;
|
||||
*oy = y - yy;
|
||||
|
@ -2521,7 +2669,7 @@ out:
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int game_bg_coord(int x, int y, int *ox, int *oy)
|
||||
static int game_bg_click(int x, int y, int *ox, int *oy)
|
||||
{
|
||||
struct el *o;
|
||||
struct game_theme *t = &game_theme;
|
||||
|
@ -2563,8 +2711,8 @@ static int game_input(int down, const char *key, int x, int y, int mb)
|
|||
} else {
|
||||
int px = -1;
|
||||
int py = -1;
|
||||
game_pic_coord(x, y, &px, &py); /* got picture coord */
|
||||
if (game_bg_coord(x, y, &x, &y)) /* no click on bg */
|
||||
game_pic_click(x, y, &px, &py); /* got picture coord */
|
||||
if (game_bg_click(x, y, &x, &y)) /* no click on bg */
|
||||
return -1;
|
||||
snprintf(tx, sizeof(tx), "%d", x);
|
||||
snprintf(ty, sizeof(ty), "%d", y);
|
||||
|
@ -2595,6 +2743,7 @@ static int game_input(int down, const char *key, int x, int y, int mb)
|
|||
if (opt_click && mb != -1)
|
||||
snd_play(game_theme.click, -1, 0);
|
||||
game_cmd(p); free(p);
|
||||
mouse_restore();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2763,6 +2912,18 @@ int game_loop(void)
|
|||
mouse_reset(1);
|
||||
game_menu(menu_askquit);
|
||||
#endif
|
||||
} else if (alt_pressed && (!is_key(&ev, "q") || !is_key(&ev, "f4"))) {
|
||||
break;
|
||||
} else if (alt_pressed &&
|
||||
(!is_key(&ev, "enter") || !is_key(&ev, "return"))) {
|
||||
int old_menu = (menu_shown) ? cur_menu: -1;
|
||||
shift_pressed = alt_pressed = 0;
|
||||
opt_fs ^= 1;
|
||||
game_restart();
|
||||
if (old_menu != -1)
|
||||
game_menu(old_menu);
|
||||
} else if (game_theme.gfx_mode == GFX_MODE_DIRECT) {
|
||||
; // nothing todo
|
||||
} else if (!alt_pressed && (!is_key(&ev, "return") || !is_key(&ev, "enter")
|
||||
#ifdef S60
|
||||
|| !is_key(&ev, ".")
|
||||
|
@ -2854,17 +3015,9 @@ int game_loop(void)
|
|||
else
|
||||
select_frame(0);
|
||||
#endif
|
||||
} else if (alt_pressed && (!is_key(&ev, "q") || !is_key(&ev, "f4"))) {
|
||||
break;
|
||||
} else if (alt_pressed &&
|
||||
(!is_key(&ev, "enter") || !is_key(&ev, "return"))) {
|
||||
int old_menu = (menu_shown) ? cur_menu: -1;
|
||||
shift_pressed = alt_pressed = 0;
|
||||
opt_fs ^= 1;
|
||||
game_restart();
|
||||
if (old_menu != -1)
|
||||
game_menu(old_menu);
|
||||
}
|
||||
} else if (game_theme.gfx_mode == GFX_MODE_DIRECT) {
|
||||
; // nothing todo
|
||||
} else if (ev.type == MOUSE_DOWN) {
|
||||
if (ev.code != 1)
|
||||
disable_use();
|
||||
|
|
|
@ -78,6 +78,9 @@ extern char *open_file_dialog(void);
|
|||
|
||||
extern int game_from_disk(void);
|
||||
|
||||
extern int game_pict_modify(img_t p);
|
||||
extern int game_pict_coord(int *x, int *y, int *w, int *h);
|
||||
|
||||
#define CURSOR_CLEAR -1
|
||||
#define CURSOR_OFF 0
|
||||
#define CURSOR_ON 1
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#define Surf(p) ((SDL_Surface *)p)
|
||||
|
||||
static SDL_Surface *screen = NULL;
|
||||
static cache_t images = NULL;
|
||||
|
||||
static struct {
|
||||
const char *name;
|
||||
|
@ -249,6 +250,7 @@ struct _anigif_t {
|
|||
};
|
||||
|
||||
typedef struct _anigif_t *anigif_t;
|
||||
extern int timer_counter;
|
||||
|
||||
static int anigif_spawn(anigif_t ag, int x, int y, int w, int h)
|
||||
{
|
||||
|
@ -287,7 +289,6 @@ static anigif_t anigif_find(anigif_t g)
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
extern int timer_counter;
|
||||
|
||||
static void anigif_disposal(anigif_t g)
|
||||
{
|
||||
|
@ -429,6 +430,8 @@ void gfx_free_image(img_t p)
|
|||
anigif_t ag;
|
||||
if (!p)
|
||||
return;
|
||||
if (!cache_forget(images, p))
|
||||
return; /* cached sprite */
|
||||
if ((ag = is_anigif(p))) {
|
||||
if (ag->drawn)
|
||||
anigif_drawn_nr --;
|
||||
|
@ -669,7 +672,7 @@ static img_t img_pad(char *fname)
|
|||
static img_t _gfx_load_combined_image(char *filename);
|
||||
|
||||
/* blank:WxH */
|
||||
static img_t _gfx_load_special_image(char *f)
|
||||
static img_t _gfx_load_special_image(char *f, int combined)
|
||||
{
|
||||
int alpha = 0;
|
||||
int blank = 0;
|
||||
|
@ -680,13 +683,17 @@ static img_t _gfx_load_special_image(char *f)
|
|||
if (!f)
|
||||
return NULL;
|
||||
|
||||
|
||||
if (!(f = filename = strdup(f)))
|
||||
return NULL;
|
||||
|
||||
if (!strncmp(filename, "blank:", 6)) {
|
||||
filename += 6;
|
||||
blank = 1;
|
||||
} else if (!strncmp(filename, "spr:", 4) && !combined) {
|
||||
// filename += 4;
|
||||
img2 = cache_get(images, filename);
|
||||
// fprintf(stderr, "get:%s %p\n", filename, img2);
|
||||
goto out;
|
||||
} else if (!strncmp(filename, "box:", 4)) {
|
||||
filename += 4;
|
||||
alpha = 255;
|
||||
|
@ -726,6 +733,7 @@ skip:
|
|||
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);
|
||||
|
@ -733,6 +741,7 @@ skip:
|
|||
}
|
||||
if (pt)
|
||||
alpha = atoi(pt);
|
||||
|
||||
img2 = gfx_alpha_img(img, alpha);
|
||||
gfx_free_image(img);
|
||||
out:
|
||||
|
@ -743,12 +752,17 @@ err:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static img_t _gfx_load_image(char *filename)
|
||||
cache_t gfx_image_cache(void)
|
||||
{
|
||||
return images;
|
||||
}
|
||||
|
||||
static img_t _gfx_load_image(char *filename, int combined)
|
||||
{
|
||||
SDL_Surface *img;
|
||||
int nr = 0;
|
||||
filename = strip(filename);
|
||||
img = _gfx_load_special_image(filename);
|
||||
img = _gfx_load_special_image(filename, combined);
|
||||
if (img)
|
||||
return img;
|
||||
filename = dirpath(filename);
|
||||
|
@ -802,7 +816,7 @@ static img_t _gfx_load_combined_image(char *filename)
|
|||
goto err; /* first image is a base image */
|
||||
*ep = 0;
|
||||
|
||||
base = _gfx_load_image(strip(p));
|
||||
base = _gfx_load_image(strip(p), 1);
|
||||
if (!base)
|
||||
goto err;
|
||||
p = ep + 1;
|
||||
|
@ -825,7 +839,7 @@ static img_t _gfx_load_combined_image(char *filename)
|
|||
} else if (*ep) {
|
||||
goto err;
|
||||
}
|
||||
img = _gfx_load_image(strip(p));
|
||||
img = _gfx_load_image(strip(p), 1);
|
||||
if (img) {
|
||||
to.x = x; to.y = y;
|
||||
if (c) {
|
||||
|
@ -852,7 +866,7 @@ img_t gfx_load_image(char *filename)
|
|||
if (!filename)
|
||||
return NULL;
|
||||
/* if (!access(filename, R_OK)) */
|
||||
img = _gfx_load_image(filename);
|
||||
img = _gfx_load_image(filename, 0);
|
||||
if (!img)
|
||||
img = _gfx_load_combined_image(filename);
|
||||
if (!img)
|
||||
|
@ -875,10 +889,13 @@ void gfx_draw_bg(img_t p, int x, int y, int width, int height)
|
|||
SDL_BlitSurface(pixbuf, &src, screen, &dest);
|
||||
}
|
||||
|
||||
void gfx_draw_from(img_t p, int x, int y, int xx, int yy, int width, int height)
|
||||
void gfx_draw_from(img_t p, int x, int y, int width, int height, img_t to, int xx, int yy)
|
||||
{
|
||||
SDL_Surface *pixbuf = (SDL_Surface *)p;
|
||||
SDL_Surface *scr = (SDL_Surface *)to;
|
||||
SDL_Rect dest, src;
|
||||
if (!scr)
|
||||
scr = screen;
|
||||
src.x = x;
|
||||
src.y = y;
|
||||
src.w = width;
|
||||
|
@ -887,7 +904,7 @@ void gfx_draw_from(img_t p, int x, int y, int xx, int yy, int width, int height)
|
|||
dest.y = yy;
|
||||
dest.w = width;
|
||||
dest.h = height;
|
||||
SDL_BlitSurface(pixbuf, &src, screen, &dest);
|
||||
SDL_BlitSurface(pixbuf, &src, scr, &dest);
|
||||
}
|
||||
|
||||
void gfx_draw(img_t p, int x, int y)
|
||||
|
@ -945,19 +962,18 @@ int gfx_frame_gif(img_t img)
|
|||
{
|
||||
anigif_t ag;
|
||||
ag = is_anigif(img);
|
||||
|
||||
|
||||
if (!ag)
|
||||
return 0;
|
||||
|
||||
|
||||
if (!ag->drawn || !ag->active)
|
||||
return 0;
|
||||
|
||||
if (ag->loop == -1)
|
||||
return 0;
|
||||
|
||||
|
||||
if ((timer_counter - ag->delay) < (ag->frames[ag->cur_frame].delay / HZ))
|
||||
return 0;
|
||||
|
||||
|
||||
if (ag->cur_frame != ag->nr_frames - 1 || ag->loop > 1 || !ag->loop)
|
||||
anigif_disposal(ag);
|
||||
|
||||
|
@ -977,6 +993,7 @@ int gfx_frame_gif(img_t img)
|
|||
}
|
||||
if (ag->loop != -1)
|
||||
anigif_frame(ag);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -2150,24 +2167,38 @@ void _txt_layout_free(layout_t lay)
|
|||
layout->vcnt = 0;
|
||||
}
|
||||
|
||||
word_t txt_layout_words(layout_t lay, word_t v)
|
||||
word_t txt_layout_words_ex(layout_t lay, struct line *line, word_t v, int off, int height)
|
||||
{
|
||||
struct layout *layout = (struct layout*)lay;
|
||||
struct word *w = (struct word*)v;
|
||||
struct layout *layout = (struct layout *)lay;
|
||||
struct line *line;
|
||||
if (!layout)
|
||||
|
||||
if (!lay)
|
||||
return NULL;
|
||||
|
||||
if (!w) {
|
||||
if (!(line = layout->lines))
|
||||
if (!line)
|
||||
line = layout->lines;
|
||||
if (!line)
|
||||
return NULL;
|
||||
w = line->words;
|
||||
} else {
|
||||
line = w->line;
|
||||
w = w->next;
|
||||
}
|
||||
for (; !w && line->next; line = line->next, w = line->words);
|
||||
return w;
|
||||
|
||||
for (; (!w || (line->y + line->h) < off) && line->next; line = line->next, w = line->words);
|
||||
if ((line->y + line->h) < off)
|
||||
w = NULL;
|
||||
else if (height >= 0 && line->y - off > height)
|
||||
w = NULL;
|
||||
return w;
|
||||
}
|
||||
|
||||
word_t txt_layout_words(layout_t lay, word_t v)
|
||||
{
|
||||
return txt_layout_words_ex(lay, NULL, v, 0, -1);
|
||||
}
|
||||
|
||||
void txt_layout_free(layout_t lay)
|
||||
{
|
||||
struct layout *layout = (struct layout *)lay;
|
||||
|
@ -2724,7 +2755,6 @@ void xref_update(xref_t pxref, int x, int y, clear_fn clear, update_fn 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;
|
||||
|
@ -3891,11 +3921,18 @@ int gfx_init(void)
|
|||
fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
|
||||
return -1;
|
||||
}
|
||||
if (!(images = cache_init(-1, gfx_free_image))) {
|
||||
fprintf(stderr, "Can't init cache subsystem.\n");
|
||||
gfx_done();
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gfx_done(void)
|
||||
{
|
||||
cache_free(images);
|
||||
images = NULL;
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ extern void gfx_done(void);
|
|||
|
||||
extern int gfx_parse_color (const char *spec, color_t *def);
|
||||
extern void gfx_flip(void);
|
||||
extern cache_t gfx_image_cache(void);
|
||||
extern img_t gfx_screen(img_t nscreen);
|
||||
extern void gfx_bg(color_t col);
|
||||
extern void gfx_noclip(void);
|
||||
|
@ -86,7 +87,7 @@ extern img_t gfx_alpha_img(img_t src, int alpha);
|
|||
extern img_t gfx_display_alpha(img_t src);
|
||||
extern img_t gfx_scale(img_t src, float xscale, float yscale);
|
||||
extern void gfx_draw_bg(img_t p, int x, int y, int width, int height);
|
||||
extern void gfx_draw_from(img_t p, int x, int y, int xx, int yy, int width, int height);
|
||||
extern void gfx_draw_from(img_t p, int x, int y, int width, int height, img_t to, int xx, int yy);
|
||||
extern void gfx_cursor(int *xp, int *yp);
|
||||
extern void gfx_warp_cursor(int x, int y);
|
||||
extern void gfx_change_screen(img_t src, int steps);
|
||||
|
@ -98,6 +99,7 @@ extern fnt_t fnt_load(const char *fname, int size);
|
|||
extern void fnt_free(fnt_t);
|
||||
extern int fnt_height(fnt_t fn);
|
||||
extern void fnt_style(fnt_t fn, int style);
|
||||
extern img_t fnt_render(fnt_t fn, const char *p, color_t col);
|
||||
|
||||
extern void txt_draw(fnt_t fnt, const char *txt, int x, int y, color_t col);
|
||||
extern void txt_size(fnt_t fnt, const char *txt, int *w, int *h);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "externals.h"
|
||||
#include "internals.h"
|
||||
#include "list.h"
|
||||
|
||||
#ifndef STEAD_PATH
|
||||
#define STEAD_PATH "./stead"
|
||||
|
@ -458,6 +459,7 @@ static int luaB_get_steadpath(lua_State *L) {
|
|||
|
||||
|
||||
extern void mouse_reset(int hl); /* too bad */
|
||||
extern void mouse_restore(void);
|
||||
|
||||
static void instead_timer_do(void *data)
|
||||
{
|
||||
|
@ -472,7 +474,9 @@ static void instead_timer_do(void *data)
|
|||
if (!p)
|
||||
goto out;
|
||||
mouse_reset(0);
|
||||
// fprintf(stderr, "cmd =%s\n", p);
|
||||
game_cmd(p); free(p);
|
||||
mouse_restore();
|
||||
game_cursor(CURSOR_ON);
|
||||
out:
|
||||
instead_timer_nr = 0;
|
||||
|
@ -531,6 +535,489 @@ static int luaB_theme_var(lua_State *L) {
|
|||
extern int dir_iter_factory (lua_State *L);
|
||||
extern int luaopen_lfs (lua_State *L);
|
||||
|
||||
static LIST_HEAD(sprites);
|
||||
|
||||
static LIST_HEAD(fonts);
|
||||
|
||||
typedef struct {
|
||||
struct list_head list;
|
||||
char *name;
|
||||
fnt_t fnt;
|
||||
} _fnt_t;
|
||||
|
||||
typedef struct {
|
||||
struct list_head list;
|
||||
char *name;
|
||||
img_t img;
|
||||
} _spr_t;
|
||||
|
||||
static void sprites_free(void)
|
||||
{
|
||||
// fprintf(stderr, "sprites free \n");
|
||||
while (!list_empty(&sprites)) {
|
||||
_spr_t *sp = (_spr_t*)(sprites.next);
|
||||
free(sp->name);
|
||||
cache_forget(gfx_image_cache(), sp->img);
|
||||
list_del(&sp->list);
|
||||
free(sp);
|
||||
}
|
||||
while (!list_empty(&fonts)) {
|
||||
_fnt_t *fn = (_fnt_t*)(fonts.next);
|
||||
fnt_free(fn->fnt);
|
||||
free(fn->name);
|
||||
list_del(&fn->list);
|
||||
free(fn);
|
||||
}
|
||||
game_pict_modify(NULL);
|
||||
cache_shrink(gfx_image_cache());
|
||||
}
|
||||
|
||||
static _spr_t *sprite_lookup(const char *name)
|
||||
{
|
||||
struct list_head *pos;
|
||||
_spr_t *sp;
|
||||
list_for_each(pos, &sprites) {
|
||||
sp = (_spr_t*)pos;
|
||||
if (!strcmp(name, sp->name)) {
|
||||
list_move(&sp->list, &sprites); // move it on head
|
||||
return sp;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static _fnt_t *font_lookup(const char *name)
|
||||
{
|
||||
struct list_head *pos;
|
||||
_fnt_t *fn;
|
||||
list_for_each(pos, &fonts) {
|
||||
fn = (_fnt_t*)pos;
|
||||
if (!strcmp(name, fn->name)) {
|
||||
list_move(&fn->list, &fonts); // move it on head
|
||||
return fn;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static _spr_t *sprite_new(const char *name, img_t img)
|
||||
{
|
||||
_spr_t *sp;
|
||||
sp = malloc(sizeof(_spr_t));
|
||||
if (!sp)
|
||||
return NULL;
|
||||
INIT_LIST_HEAD(&sp->list);
|
||||
sp->name = strdup(name);
|
||||
if (!sp->name) {
|
||||
free(sp);
|
||||
return NULL;
|
||||
}
|
||||
sp->img = img;
|
||||
if (cache_add(gfx_image_cache(), name, img)) {
|
||||
free(sp->name);
|
||||
free(sp);
|
||||
return NULL;
|
||||
}
|
||||
// fprintf(stderr, "added: %s\n", name);
|
||||
list_add(&sp->list, &sprites);
|
||||
return sp;
|
||||
}
|
||||
|
||||
static _fnt_t *font_new(const char *name, fnt_t fnt)
|
||||
{
|
||||
_fnt_t *fn;
|
||||
fn = malloc(sizeof(_fnt_t));
|
||||
if (!fn)
|
||||
return NULL;
|
||||
INIT_LIST_HEAD(&fn->list);
|
||||
fn->name = strdup(name);
|
||||
if (!fn->name) {
|
||||
free(fn);
|
||||
return NULL;
|
||||
}
|
||||
fn->fnt = fnt;
|
||||
list_add(&fn->list, &fonts);
|
||||
return fn;
|
||||
}
|
||||
|
||||
static void sprite_name(const char *name, char *sname, int size)
|
||||
{
|
||||
unsigned long h = 0;
|
||||
if (!sname || !size)
|
||||
return;
|
||||
h = hash_string(name);
|
||||
do { /* new uniq name */
|
||||
snprintf(sname, size, "spr:%lx", h);
|
||||
h ++;
|
||||
} while (sprite_lookup(sname) || cache_lookup(gfx_image_cache(), sname));
|
||||
sname[size - 1] = 0;
|
||||
}
|
||||
|
||||
static void font_name(const char *name, char *sname, int size)
|
||||
{
|
||||
unsigned long h = 0;
|
||||
if (!sname || !size)
|
||||
return;
|
||||
h = hash_string(name);
|
||||
do { /* new uniq name */
|
||||
snprintf(sname, size, "fnt:%lx", h);
|
||||
h ++;
|
||||
} while (font_lookup(sname));
|
||||
sname[size - 1] = 0;
|
||||
}
|
||||
|
||||
static int luaB_free_sprites(lua_State *L) {
|
||||
sprites_free();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int luaB_load_sprite(lua_State *L) {
|
||||
img_t img = NULL;
|
||||
_spr_t *sp;
|
||||
const char *key;
|
||||
char sname[sizeof(unsigned long) * 2 + 16];
|
||||
|
||||
const char *fname = luaL_optstring(L, 1, NULL);
|
||||
const char *desc = luaL_optstring(L, 2, NULL);
|
||||
|
||||
if (!fname)
|
||||
return 0;
|
||||
|
||||
img = gfx_load_image((char*)fname);
|
||||
|
||||
if (img)
|
||||
theme_img_scale(&img);
|
||||
|
||||
if (!img)
|
||||
goto err;
|
||||
|
||||
if (!desc || sprite_lookup(desc)) {
|
||||
key = sname;
|
||||
sprite_name(fname, sname, sizeof(sname));
|
||||
} else
|
||||
key = desc;
|
||||
sp = sprite_new(key, img);
|
||||
if (!sp)
|
||||
goto err;
|
||||
|
||||
lua_pushstring(L, key);
|
||||
return 1;
|
||||
err:
|
||||
gfx_free_image(img);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int luaB_load_font(lua_State *L) {
|
||||
fnt_t fnt = NULL;
|
||||
_fnt_t *fn;
|
||||
const char *key;
|
||||
char sname[sizeof(unsigned long) * 2 + 16];
|
||||
struct game_theme *t = &game_theme;
|
||||
|
||||
const char *fname = luaL_optstring(L, 1, NULL);
|
||||
int sz = luaL_optnumber(L, 2, t->font_size) * game_theme.scale;
|
||||
const char *desc = luaL_optstring(L, 3, NULL);
|
||||
if (!fname)
|
||||
return 0;
|
||||
|
||||
fnt = fnt_load((char*)fname, sz);
|
||||
|
||||
if (!fnt)
|
||||
return 0;
|
||||
|
||||
if (!desc || font_lookup(desc)) {
|
||||
key = sname;
|
||||
font_name(fname, sname, sizeof(sname));
|
||||
} else
|
||||
key = desc;
|
||||
|
||||
fn = font_new(key, fnt);
|
||||
if (!fn)
|
||||
goto err;
|
||||
|
||||
lua_pushstring(L, key);
|
||||
return 1;
|
||||
err:
|
||||
fnt_free(fnt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int luaB_text_size(lua_State *L) {
|
||||
_fnt_t *fn;
|
||||
int w = 0, h = 0;
|
||||
|
||||
const char *font = luaL_optstring(L, 1, NULL);
|
||||
const char *text = luaL_optstring(L, 2, NULL);
|
||||
|
||||
if (!font)
|
||||
return 0;
|
||||
|
||||
fn = font_lookup(font);
|
||||
|
||||
if (!fn)
|
||||
return 0;
|
||||
if (!text) {
|
||||
w = 0;
|
||||
h = fnt_height(fn->fnt);
|
||||
} else
|
||||
txt_size(fn->fnt, text, &w, &h);
|
||||
lua_pushnumber(L, w);
|
||||
lua_pushnumber(L, h);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int luaB_text_sprite(lua_State *L) {
|
||||
img_t img = NULL;
|
||||
_spr_t *sp;
|
||||
_fnt_t *fn;
|
||||
const char *key;
|
||||
char sname[sizeof(unsigned long) * 2 + 16];
|
||||
|
||||
const char *font = luaL_optstring(L, 1, NULL);
|
||||
const char *text = luaL_optstring(L, 2, NULL);
|
||||
char txtkey[8];
|
||||
const char *color = luaL_optstring(L, 3, NULL);
|
||||
int style = luaL_optnumber(L, 4, 0);
|
||||
color_t col = { .r = game_theme.fgcol.r, .g = game_theme.fgcol.g, .b = game_theme.fgcol.b };
|
||||
|
||||
if (!font)
|
||||
return 0;
|
||||
if (color)
|
||||
gfx_parse_color (color, &col);
|
||||
if (!text)
|
||||
text = "";
|
||||
|
||||
fn = font_lookup(font);
|
||||
|
||||
if (!fn)
|
||||
return 0;
|
||||
|
||||
fnt_style(fn->fnt, style);
|
||||
|
||||
img = fnt_render(fn->fnt, text, col);
|
||||
if (!img)
|
||||
return 0;
|
||||
key = sname;
|
||||
|
||||
strncpy(txtkey, text, sizeof(txtkey));
|
||||
txtkey[sizeof(txtkey) - 1] = 0;
|
||||
|
||||
sprite_name(text, sname, sizeof(sname));
|
||||
|
||||
sp = sprite_new(key, img);
|
||||
|
||||
if (!sp)
|
||||
goto err;
|
||||
|
||||
lua_pushstring(L, key);
|
||||
return 1;
|
||||
err:
|
||||
gfx_free_image(img);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int luaB_sprite_size(lua_State *L) {
|
||||
img_t s = NULL;
|
||||
float v;
|
||||
int w, h;
|
||||
const char *src = luaL_optstring(L, 1, NULL);
|
||||
if (!src)
|
||||
return 0;
|
||||
s = cache_lookup(gfx_image_cache(), src);
|
||||
if (!s)
|
||||
return 0;
|
||||
|
||||
v = game_theme.scale;
|
||||
|
||||
w = gfx_img_w(s) / v;
|
||||
h = gfx_img_h(s) / v;
|
||||
lua_pushnumber(L, w);
|
||||
lua_pushnumber(L, h);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static img_t grab_sprite(const char *dst, int *xoff, int *yoff)
|
||||
{
|
||||
img_t d;
|
||||
if (game_theme.gfx_mode == GFX_MODE_DIRECT && !strcmp(dst, "screen")) {
|
||||
d = gfx_screen(NULL);
|
||||
*xoff = game_theme.xoff;
|
||||
*yoff = game_theme.yoff;
|
||||
} else
|
||||
d = cache_lookup(gfx_image_cache(), dst);
|
||||
return d;
|
||||
}
|
||||
|
||||
static int luaB_draw_sprite(lua_State *L) {
|
||||
img_t s, d;
|
||||
img_t img2 = NULL;
|
||||
float v;
|
||||
const char *src = luaL_optstring(L, 1, NULL);
|
||||
int x = luaL_optnumber(L, 2, 0);
|
||||
int y = luaL_optnumber(L, 3, 0);
|
||||
int w = luaL_optnumber(L, 4, 0);
|
||||
int h = luaL_optnumber(L, 5, 0);
|
||||
const char *dst = luaL_optstring(L, 6, NULL);
|
||||
int xx = luaL_optnumber(L, 7, 0);
|
||||
int yy = luaL_optnumber(L, 8, 0);
|
||||
int alpha = luaL_optnumber(L, 9, 255);
|
||||
int xoff = 0, yoff = 0;
|
||||
int xoff0 = 0, yoff0 = 0;
|
||||
if (!src || !dst)
|
||||
return 0;
|
||||
|
||||
s = grab_sprite(src, &xoff0, &yoff0);
|
||||
|
||||
d = grab_sprite(dst, &xoff, &yoff);
|
||||
|
||||
if (!s || !d)
|
||||
return 0;
|
||||
|
||||
v = game_theme.scale;
|
||||
|
||||
if (v != 1.0f) {
|
||||
x *= v;
|
||||
y *= v;
|
||||
w *= v;
|
||||
h *= v;
|
||||
xx *= v;
|
||||
yy *= v;
|
||||
}
|
||||
|
||||
if (!w)
|
||||
w = gfx_img_w(s) - 2 * xoff0;
|
||||
if (!h)
|
||||
h = gfx_img_h(s) - 2 * yoff0;
|
||||
|
||||
game_pict_modify(d);
|
||||
|
||||
if (alpha != 255) {
|
||||
img2 = gfx_alpha_img(s, alpha);
|
||||
if (img2)
|
||||
s = img2;
|
||||
}
|
||||
gfx_draw_from(s, x + xoff0, y + yoff0, w, h, d, xx + xoff, yy + yoff);
|
||||
gfx_free_image(img2);
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int luaB_alpha_sprite(lua_State *L) {
|
||||
_spr_t *sp;
|
||||
img_t s;
|
||||
img_t img2 = NULL;
|
||||
const char *key;
|
||||
char sname[sizeof(unsigned long) * 2 + 16];
|
||||
|
||||
const char *src = luaL_optstring(L, 1, NULL);
|
||||
int alpha = luaL_optnumber(L, 2, 255);
|
||||
const char *desc = luaL_optstring(L, 3, NULL);
|
||||
|
||||
if (!src)
|
||||
return 0;
|
||||
|
||||
s = cache_lookup(gfx_image_cache(), src);
|
||||
if (!s)
|
||||
return 0;
|
||||
|
||||
img2 = gfx_alpha_img(s, alpha);
|
||||
if (!img2)
|
||||
return 0;
|
||||
|
||||
if (!desc || sprite_lookup(desc)) {
|
||||
key = sname;
|
||||
sprite_name(src, sname, sizeof(sname));
|
||||
} else
|
||||
key = desc;
|
||||
|
||||
sp = sprite_new(key, img2);
|
||||
if (!sp)
|
||||
goto err;
|
||||
lua_pushstring(L, sname);
|
||||
return 1;
|
||||
err:
|
||||
gfx_free_image(img2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int luaB_fill_sprite(lua_State *L) {
|
||||
img_t d;
|
||||
float v;
|
||||
const char *dst = luaL_optstring(L, 1, NULL);
|
||||
int x = luaL_optnumber(L, 2, 0);
|
||||
int y = luaL_optnumber(L, 3, 0);
|
||||
int w = luaL_optnumber(L, 4, 0);
|
||||
int h = luaL_optnumber(L, 5, 0);
|
||||
const char *color = luaL_optstring(L, 6, 0);
|
||||
int xoff = 0, yoff = 0;
|
||||
color_t col = { .r = game_theme.bgcol.r, .g = game_theme.bgcol.g, .b = game_theme.bgcol.b };
|
||||
if (!dst)
|
||||
return 0;
|
||||
|
||||
d = grab_sprite(dst, &xoff, &yoff);
|
||||
|
||||
if (color)
|
||||
gfx_parse_color(color, &col);
|
||||
|
||||
if (!d)
|
||||
return 0;
|
||||
|
||||
v = game_theme.scale;
|
||||
|
||||
if (v != 1.0f) {
|
||||
x *= v;
|
||||
y *= v;
|
||||
w *= v;
|
||||
h *= v;
|
||||
}
|
||||
if (!w)
|
||||
w = gfx_img_w(d) - 2 * xoff;
|
||||
if (!h)
|
||||
h = gfx_img_h(d) - 2 * yoff;
|
||||
game_pict_modify(d);
|
||||
gfx_img_fill(d, x + xoff, y + yoff, w, h, col);
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int luaB_free_sprite(lua_State *L) {
|
||||
const char *key = luaL_optstring(L, 1, NULL);
|
||||
_spr_t *sp;
|
||||
if (!key)
|
||||
return 0;
|
||||
|
||||
sp = sprite_lookup(key);
|
||||
if (!sp)
|
||||
return 0;
|
||||
|
||||
cache_forget(gfx_image_cache(), sp->img);
|
||||
cache_shrink(gfx_image_cache());
|
||||
|
||||
list_del(&sp->list);
|
||||
free(sp->name); free(sp);
|
||||
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int luaB_free_font(lua_State *L) {
|
||||
const char *key = luaL_optstring(L, 1, NULL);
|
||||
_fnt_t *fn;
|
||||
if (!key)
|
||||
return 0;
|
||||
|
||||
fn = font_lookup(key);
|
||||
if (!fn)
|
||||
return 0;
|
||||
|
||||
list_del(&fn->list);
|
||||
free(fn->name); free(fn);
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const luaL_Reg base_funcs[] = {
|
||||
{"doencfile", luaB_doencfile},
|
||||
{"dofile", luaB_dofile},
|
||||
|
@ -542,6 +1029,19 @@ static const luaL_Reg base_funcs[] = {
|
|||
{"set_timer", luaB_set_timer},
|
||||
{"theme_var", luaB_theme_var},
|
||||
{"readdir", dir_iter_factory},
|
||||
|
||||
{"font_load", luaB_load_font},
|
||||
{"font_free", luaB_free_font},
|
||||
|
||||
{"sprite_load", luaB_load_sprite},
|
||||
{"sprite_text", luaB_text_sprite},
|
||||
{"sprite_free", luaB_free_sprite},
|
||||
{"sprites_free", luaB_free_sprites},
|
||||
{"sprite_draw", luaB_draw_sprite},
|
||||
{"sprite_fill", luaB_fill_sprite},
|
||||
{"sprite_alpha", luaB_alpha_sprite},
|
||||
{"sprite_size", luaB_sprite_size},
|
||||
{"sprite_text_size", luaB_text_size},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
@ -612,6 +1112,7 @@ int instead_init(void)
|
|||
}
|
||||
/* cleanup Lua */
|
||||
instead_clear();
|
||||
srand(time(NULL));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -629,6 +1130,7 @@ void instead_done(void)
|
|||
#ifdef _HAVE_ICONV
|
||||
fromcp = NULL;
|
||||
#endif
|
||||
sprites_free();
|
||||
}
|
||||
|
||||
int instead_encode(const char *s, const char *d)
|
||||
|
@ -665,4 +1167,3 @@ int instead_encode(const char *s, const char *d)
|
|||
fclose(dst);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@ static int parse_gfx_mode(const char *v, void *data)
|
|||
*i = GFX_MODE_EMBEDDED;
|
||||
else if (!strcmp(v, "float"))
|
||||
*i = GFX_MODE_FLOAT;
|
||||
else if (!strcmp(v, "direct"))
|
||||
*i = GFX_MODE_DIRECT;
|
||||
else
|
||||
return -1;
|
||||
return 0;
|
||||
|
@ -33,6 +35,9 @@ static int out_gfx_mode(const void *v, char **out)
|
|||
case GFX_MODE_FLOAT:
|
||||
o = strdup("float");
|
||||
break;
|
||||
case GFX_MODE_DIRECT:
|
||||
o = strdup("direct");
|
||||
break;
|
||||
default:
|
||||
o = strdup("");
|
||||
break;
|
||||
|
@ -364,6 +369,10 @@ int theme_img_scale(img_t *p)
|
|||
float v = game_theme.scale;
|
||||
if (!p || !*p || v == 1.0f)
|
||||
return 0;
|
||||
|
||||
if (!cache_have(gfx_image_cache(), p))
|
||||
return 0; /* do not scale sprites! */
|
||||
|
||||
pic = gfx_scale(*p, v, v);
|
||||
if (!pic)
|
||||
return -1;
|
||||
|
|
|
@ -147,6 +147,7 @@ extern int theme_relative;
|
|||
#define GFX_MODE_FLOAT 0
|
||||
#define GFX_MODE_FIXED 1
|
||||
#define GFX_MODE_EMBEDDED 2
|
||||
#define GFX_MODE_DIRECT 3
|
||||
|
||||
#define INV_MODE_DISABLED -1
|
||||
#define INV_MODE_VERT 0
|
||||
|
|
|
@ -26,6 +26,7 @@ install:
|
|||
$(INSTALL) hotkeys.lua $(STEADPATH)/hotkeys.lua
|
||||
$(INSTALL) hideinv.lua $(STEADPATH)/hideinv.lua
|
||||
$(INSTALL) theme.lua $(STEADPATH)/theme.lua
|
||||
$(INSTALL) sprites.lua $(STEADPATH)/sprites.lua
|
||||
|
||||
uninstall:
|
||||
$(RM) $(STEADPATH)/stead.lua
|
||||
|
|
|
@ -23,3 +23,4 @@ install:
|
|||
copy hotkeys.lua ..\bin\stead
|
||||
copy hideinv.lua ..\bin\stead
|
||||
copy theme.lua ..\bin\stead
|
||||
copy sprites.lua ..\bin\stead
|
||||
|
|
60
stead/sprites.lua
Normal file
60
stead/sprites.lua
Normal file
|
@ -0,0 +1,60 @@
|
|||
require "theme"
|
||||
sprite = {
|
||||
nam = 'sprites';
|
||||
object_type = true;
|
||||
system_type = true;
|
||||
|
||||
ini = function(s)
|
||||
if type(s.load) == 'function' then
|
||||
sprites_free();
|
||||
sprite.init();
|
||||
end
|
||||
end;
|
||||
|
||||
screen = function(s)
|
||||
if theme.get 'scr.gfx.mode' ~= 'direct' then
|
||||
return
|
||||
end
|
||||
return 'screen'
|
||||
end;
|
||||
font = function(font, size)
|
||||
return font_load(font, size);
|
||||
end;
|
||||
free_font = function(font)
|
||||
return font_free(key);
|
||||
end;
|
||||
alpha = function(name, alpha)
|
||||
return sprite_alpha(name, alpha);
|
||||
end;
|
||||
text = function(font, text, col, style)
|
||||
return sprite_text(font, text, col, style);
|
||||
end;
|
||||
size = function(spr)
|
||||
return sprite_size(spr);
|
||||
end;
|
||||
text_size = function(spr)
|
||||
return sprite_text_size(spr);
|
||||
end;
|
||||
draw = function(s, fx, fy, fw, fh, d, x, y, alpha)
|
||||
if d == nil and x == nil and y == nil then
|
||||
return sprite_draw(s, 0, 0, 0, 0, fx, fy, fw, fh);
|
||||
end
|
||||
return sprite_draw(s, fx, fy, fw, fh, d, x, y, alpha);
|
||||
end;
|
||||
fill = function(d, x, y, w, h, col)
|
||||
if h == nil and col == nil then
|
||||
return sprite_fill(d, 0, 0, 0, 0, x, y, w);
|
||||
end
|
||||
return sprite_fill(d, x, y, w, h, col);
|
||||
end;
|
||||
load = function(fname)
|
||||
return sprite_load(fname);
|
||||
end;
|
||||
free = function(key)
|
||||
return sprite_free(key);
|
||||
end;
|
||||
}
|
||||
|
||||
stead.module_init(function()
|
||||
sprites_free();
|
||||
end)
|
|
@ -1540,9 +1540,8 @@ function do_ini(self, load)
|
|||
local function call_ini(k, o, ...)
|
||||
v = stead.par('', v, call(o, 'ini'), ...);
|
||||
end
|
||||
|
||||
math.randomseed(tonumber(os.date("%m%d%H%M%S")))
|
||||
rnd(1); rnd(1); rnd(1); -- Lua bug?
|
||||
math.randomseed(os.time(os.date("*t")))
|
||||
rnd(1); rnd(2); rnd(3); -- Lua bug?
|
||||
|
||||
game.pl = deref(game.pl);
|
||||
game.where = deref(game.where);
|
||||
|
|
Reference in a new issue