first buggy videomode switching support

This commit is contained in:
p.kosyh 2009-10-24 12:48:41 +00:00
parent 05528dfaab
commit 105813ed36
14 changed files with 310 additions and 40 deletions

View file

@ -16,8 +16,8 @@ LUA_LFLAGS=$(shell pkg-config --libs lua5.1)
# for arch linux, fedora (may be others) use this
#
# LUA_CFLAGS=$(shell pkg-config --cflags lua)
# LUA_LFLAGS=$(shell pkg-config --libs lua)
LUA_CFLAGS=$(shell pkg-config --cflags lua)
LUA_LFLAGS=$(shell pkg-config --libs lua)
#
SDL_CFLAGS=$(shell sdl-config --cflags)

View file

@ -49,6 +49,8 @@ KBD_MODE_LINKS = Links
KBD_MODE_SMART = Smart
KBD_MODE_SCROLL = Scroll
FROM_THEME = From theme
SETTINGS_MENU = \
Sound volume\n\
<a:/vol--><<</a><a:/vol-><</a> <a:/mtoggle>%d%%</a> <a:/vol+>></a><a:/vol++>>></a>\n\
@ -59,6 +61,7 @@ Sound quality\n\
Music: <a:/music>%s</a>\n\
Click sound: <a:/click>%s</a>\n\
\n\
Resolution: <a:/mode--><<</a>%s<a:/mode++>>></a>\n\
Full Screen: <a:/fs>%s</a>\n\
Font scaling: <a:/fs--><<</a>%d<a:/fs++>>></a>\n\
Links highlighting: <a:/hl>%s</a>\n\

View file

@ -50,6 +50,8 @@ KBD_MODE_LINKS = Ссылки
KBD_MODE_SMART = Умный
KBD_MODE_SCROLL = Прокрутка
FROM_THEME = Из темы
SETTINGS_MENU = \
Громкость\n\
<a:/vol--><<</a><a:/vol-><</a> <a:/mtoggle>%d%%</a> <a:/vol+>></a><a:/vol++>>></a>\n\
@ -59,6 +61,7 @@ SETTINGS_MENU = \
Музыка: <a:/music>%s</a>\n\
Звук щелчка: <a:/click>%s</a>\n\
\n\
Разрешение: <a:/mode--><<</a>%s<a:/mode++>>></a>\n\
Полный экран: <a:/fs>%s</a>\n\
Масштаб шрифта: <a:/fs--><<</a>%d<a:/fs++>>></a>\n\
Подсветка ссылок: <a:/hl>%s</a>\n\

View file

@ -23,6 +23,24 @@ int opt_kbd = KBD_SMART;
char *opt_game = NULL;
char *opt_theme = NULL;
char *opt_lang = NULL;
int opt_mode[2] = {-1, -1};
int parse_mode(const char *v, void *data)
{
int w, h;
char *eptr;
int *p = ((int *)data);
w = strtol(v, &eptr, 10);
if (!w || (eptr == v) || (*eptr != 'x'))
return -1;
eptr ++;
h = strtol(eptr, &eptr, 10);
if (!h || (*eptr))
return -1;
p[0] = w;
p[1] = h;
return 0;
}
static struct parser cfg_parser[] = {
{ "hz", parse_int, &opt_hz },
@ -40,6 +58,7 @@ static struct parser cfg_parser[] = {
{ "owntheme", parse_int, &opt_owntheme },
{ "lang", parse_string, &opt_lang },
{ "kbd", parse_int, &opt_kbd },
{ "mode", parse_mode, opt_mode },
{ NULL, },
};
@ -70,12 +89,11 @@ int cfg_save(void)
fprintf(fp, "fs = %d\nhl = %d\nhz = %d\nvol = %d\nautosave = %d\n\
game = %s\nfscale = %d\nmotion = %d\n\
click = %d\nmusic = %d\ntheme = %s\n\
filter = %d\nowntheme = %d\nlang = %s\nkbd = %d",
filter = %d\nowntheme = %d\nlang = %s\nkbd = %d\nmode = %dx%d",
opt_fs, opt_hl, opt_hz, opt_vol, opt_autosave,
curgame_dir?curgame_dir:"", opt_fsize, opt_motion,
opt_click, opt_music, curtheme_dir?curtheme_dir:DEFAULT_THEME,
opt_filter, opt_owntheme, opt_lang, opt_kbd);
opt_filter, opt_owntheme, opt_lang, opt_kbd, opt_mode[0], opt_mode[1]);
fclose(fp);
return 0;
}

View file

@ -23,6 +23,7 @@ extern int opt_autosave;
extern int opt_filter;
extern int opt_kbd;
extern int opt_mode[2];
extern char *opt_game;
extern char *opt_theme;
extern char *opt_lang;

View file

@ -318,10 +318,16 @@ int game_apply_theme(void)
layout_t lay;
textbox_t box;
if (game_theme_init(opt_mode[0], opt_mode[1]))
return -1;
memset(objs, 0, sizeof(struct el) * el_max);
if (gfx_setmode(game_theme.w, game_theme.h, opt_fs))
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;
}
gfx_bg(game_theme.bgcol);
game_clear(0, 0, game_theme.w, game_theme.h);
gfx_flip();
@ -835,7 +841,8 @@ img_t game_pict_scale(img_t img, int ww, int hh)
if (www <= 0 || hhh <=0)
break;
}
if (scale < 0)
scale = 0;
img2 = gfx_scale(img, scale, scale);
gfx_free_image(img);
return img2;

View file

@ -10,7 +10,7 @@
#define Surf(p) ((SDL_Surface *)p)
static SDL_Surface *screen;
static SDL_Surface *screen = NULL;
static struct {
const char *name;
@ -411,12 +411,21 @@ void gfx_clip(int x, int y, int w, int h)
img_t gfx_new(int w, int h)
{
SDL_Surface *dst;
dst = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h,
screen->format->BitsPerPixel,
screen->format->Rmask,
screen->format->Gmask,
screen->format->Bmask,
screen->format->Amask);
if (!screen) {
dst = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h,
32,
0xff,
0xff00,
0xff0000,
0xff000000);
} else {
dst = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h,
screen->format->BitsPerPixel,
screen->format->Rmask,
screen->format->Gmask,
screen->format->Bmask,
screen->format->Amask);
}
return dst;
}
@ -697,15 +706,103 @@ void gfx_clear(int x, int y, int w, int h)
int gfx_width;
int gfx_height;
int gfx_setmode(int w, int h, int fs)
static SDL_Rect** vid_modes = NULL;
static SDL_Rect m640x480 = { .w = 640, .h = 480 };
static SDL_Rect m800x480 = { .w = 800, .h = 480 };
static SDL_Rect m800x600 = { .w = 800, .h = 600 };
static SDL_Rect m1024x768 = { .w = 1024, .h = 768 };
static SDL_Rect m1280x800 = { .w = 1280, .h = 800 };
static SDL_Rect* std_modes[] = { &m640x480, &m800x480, &m800x600, &m1024x768, &m1280x800, NULL };
int gfx_modes(void)
{
int i = 0;
SDL_Rect** modes;
modes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_ANYFORMAT);
if (modes == (SDL_Rect**)0)/* no modes */
return 0;
if (modes == (SDL_Rect**)-1) {
vid_modes = std_modes;
return 5;
}
for (i = 0; modes[i]; ++i);
vid_modes = modes;
return i;
}
int gfx_get_mode(int n, int *w, int *h)
{
if (!vid_modes)
gfx_modes();
if (!vid_modes || !vid_modes[n])
return -1;
if (w)
*w = vid_modes[n]->w;
if (h)
*h = vid_modes[n]->h;
return 0;
}
int gfx_prev_mode(int *w, int *h)
{
int ww, hh, i = 0;
if (!w || !h)
return -1;
while ((*w != -1 && *h != -1) &&
!gfx_get_mode(i, &ww, &hh)) {
if (ww == *w && hh == *h)
break;
i ++;
}
if (*w == -1 || *h == -1)
i = gfx_modes();
if (!i)
return -1;
i --;
if (gfx_get_mode(i, &ww, &hh))
return -1;
*w = ww; *h = hh;
return 0;
}
int gfx_next_mode(int *w, int *h)
{
int ww, hh, i = 0;
if (!w || !h)
return -1;
while ((*w != -1 && *h != -1) &&
!gfx_get_mode(i, &ww, &hh)) {
i ++;
if (ww == *w && hh == *h)
break;
}
if (gfx_get_mode(i, &ww, &hh))
return -1;
*w = ww; *h = hh;
return 0;
}
int gfx_set_mode(int w, int h, int fs)
{
gfx_width = w;
gfx_height = h;
SDL_ShowCursor(SDL_DISABLE);
#ifndef MAEMO
screen = SDL_SetVideoMode(gfx_width, gfx_height, 32, SDL_DOUBLEBUF | SDL_HWSURFACE | ( ( fs ) ? SDL_FULLSCREEN : 0 ) );
if (screen == NULL) /* ok, fallback to 16 bit */
screen = SDL_SetVideoMode(gfx_width, gfx_height, 16, SDL_DOUBLEBUF | SDL_HWSURFACE | ( ( fs ) ? SDL_FULLSCREEN : 0 ) );
if (screen == NULL) /* ok, fallback to anyformat */
screen = SDL_SetVideoMode(gfx_width, gfx_height, 32, SDL_ANYFORMAT | SDL_DOUBLEBUF | SDL_HWSURFACE | ( ( fs ) ? SDL_FULLSCREEN : 0 ) );
#else
screen = SDL_SetVideoMode(gfx_width, gfx_height, 16, SDL_DOUBLEBUF | SDL_HWSURFACE | ( ( fs ) ? SDL_FULLSCREEN : 0 ) );
#endif

View file

@ -42,7 +42,10 @@ extern void gfx_clip(int x, int y, int w, int h);
extern int gfx_width;
extern int gfx_height;
extern int gfx_video_init(void);
extern int gfx_setmode(int w, int h, int fs);
extern int gfx_set_mode(int w, int h, int fs);
extern int gfx_get_mode(int n, int *w, int *h);
extern int gfx_next_mode(int *w, int *h);
extern int gfx_prev_mode(int *w, int *h);
extern void gfx_update(int x, int y, int w, int h);
extern void gfx_video_done(void);
extern void gfx_clear(int x, int y, int w, int h);

View file

@ -27,6 +27,7 @@ int input_init(void)
{
SDL_EnableKeyRepeat(500, 30);
m_focus = !!(SDL_GetAppState() & SDL_APPMOUSEFOCUS);
// putenv("SDL_MOUSE_RELATIVE=0");
return 0;
}

View file

@ -120,7 +120,6 @@ int main(int argc, char **argv)
// Initialize SDL
if (gfx_init() < 0)
return -1;
if (game_init(opt_game)) {
game_error(opt_game);
}

View file

@ -38,6 +38,8 @@ char *KBD_MODE_SMART = NULL;
char *KBD_MODE_SCROLL = NULL;
char *CANCEL_MENU = NULL;
char *FROM_THEME = NULL;
static char menu_buff[4096];
static char *slot_name(const char *path)
@ -193,6 +195,15 @@ static void themes_menu(void)
}
}
static char *opt_get_mode(void)
{
static char buff[128];
if (opt_mode[0] == -1 || opt_mode[1] == -1)
return FROM_THEME;
snprintf(buff, sizeof(buff), "%dx%d", opt_mode[0], opt_mode[1]);
return buff;
}
char *game_menu_gen(void)
{
if (cur_menu == menu_main) {
@ -203,7 +214,7 @@ char *game_menu_gen(void)
char *kbd [KBD_MAX] = { KBD_MODE_SMART, KBD_MODE_LINKS, KBD_MODE_SCROLL };
snprintf(menu_buff, sizeof(menu_buff), SETTINGS_MENU,
snd_vol_to_pcn(snd_volume_mus(-1)), snd_hz(), opt_music?ON:OFF, opt_click?ON:OFF,
opt_fs?ON:OFF, opt_fsize, opt_hl?ON:OFF, opt_motion?ON:OFF, opt_filter?ON:OFF, kbd[opt_kbd],
opt_get_mode(), opt_fs?ON:OFF, opt_fsize, opt_hl?ON:OFF, opt_motion?ON:OFF, opt_filter?ON:OFF, kbd[opt_kbd],
langs[cur_lang].name, opt_owntheme?ON:OFF, opt_autosave?ON:OFF);
} else if (cur_menu == menu_askquit) {
snprintf(menu_buff, sizeof(menu_buff), QUIT_MENU);
@ -263,6 +274,16 @@ int game_menu_act(const char *a)
} else if (!strcmp(a, "/click")) {
opt_click ^= 1;
game_menu_box(1, game_menu_gen());
} else if (!strcmp(a, "/mode++")) {
if (gfx_next_mode(&opt_mode[0], &opt_mode[1]))
opt_mode[0] = opt_mode[1] = -1;
restart_needed = 1;
game_menu_box(1, game_menu_gen());
} else if (!strcmp(a, "/mode--")) {
if (gfx_prev_mode(&opt_mode[0], &opt_mode[1]))
opt_mode[0] = opt_mode[1] = -1;
restart_needed = 1;
game_menu_box(1, game_menu_gen());
} else if (!strcmp(a, "/fs--")) {
opt_fsize --;
if (FONT_SZ(game_theme.font_size) > FONT_MIN_SZ) {
@ -493,6 +514,7 @@ static void lang_free(void)
FREE(KBD_MODE_SMART);
FREE(KBD_MODE_SCROLL);
FREE(CANCEL_MENU);
FREE(FROM_THEME);
}
static int lang_ok(void)
@ -502,7 +524,8 @@ static int lang_ok(void)
MAIN_MENU && ABOUT_MENU && BACK_MENU && SETTINGS_MENU &&
CUSTOM_THEME_MENU && OWN_THEME_MENU && SELECT_GAME_MENU && SELECT_THEME_MENU &&
SAVED_MENU && NOGAMES_MENU && NOTHEMES_MENU && QUIT_MENU &&
ON && OFF && KBD_MODE_LINKS && KBD_MODE_SMART && KBD_MODE_SCROLL && CANCEL_MENU)
ON && OFF && KBD_MODE_LINKS && KBD_MODE_SMART && KBD_MODE_SCROLL && CANCEL_MENU &&
FROM_THEME)
return 0;
return -1;
}
@ -534,6 +557,7 @@ struct parser lang_parser[] = {
{ "KBD_MODE_SMART", parse_esc_string, &KBD_MODE_SMART },
{ "KBD_MODE_SCROLL", parse_esc_string, &KBD_MODE_SCROLL },
{ "CANCEL_MENU", parse_esc_string, &CANCEL_MENU },
{ "FROM_THEME", parse_esc_string, &FROM_THEME },
{ NULL, },
};

View file

@ -54,12 +54,12 @@ struct parser cmd_parser[] = {
{ "scr.w", parse_int, &game_theme.w },
{ "scr.h", parse_int, &game_theme.h },
{ "scr.col.bg", parse_color, &game_theme.bgcol },
{ "scr.gfx.bg", parse_string, &game_theme.bg_name },
{ "scr.gfx.cursor.normal", parse_string, &game_theme.cursor_name },
{ "scr.gfx.bg", parse_full_path, &game_theme.bg_name },
{ "scr.gfx.cursor.normal", parse_full_path, &game_theme.cursor_name },
{ "scr.gfx.cursor.x", parse_int, &game_theme.cur_x },
{ "scr.gfx.cursor.y", parse_int, &game_theme.cur_y },
{ "scr.gfx.use", parse_string, &game_theme.use_name }, /* compat */
{ "scr.gfx.cursor.use", parse_string, &game_theme.use_name },
{ "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.x", parse_int, &game_theme.gfx_x },
{ "scr.gfx.y", parse_int, &game_theme.gfx_y },
@ -71,13 +71,13 @@ struct parser cmd_parser[] = {
{ "win.y", parse_int, &game_theme.win_y },
{ "win.w", parse_int, &game_theme.win_w },
{ "win.h", parse_int, &game_theme.win_h },
{ "win.fnt.name", parse_string, &game_theme.font_name },
{ "win.fnt.name", parse_full_path, &game_theme.font_name },
{ "win.fnt.size", parse_int, &game_theme.font_size },
/* compat mode directive */
{ "win.gfx.h", parse_int, &game_theme.max_scene_h },
/* here it was */
{ "win.gfx.up", parse_string, &game_theme.a_up_name },
{ "win.gfx.down", parse_string, &game_theme.a_down_name },
{ "win.gfx.up", parse_full_path, &game_theme.a_up_name },
{ "win.gfx.down", parse_full_path, &game_theme.a_down_name },
{ "win.col.fg", parse_color, &game_theme.fgcol },
{ "win.col.link", parse_color, &game_theme.lcol },
{ "win.col.alink", parse_color, &game_theme.acol },
@ -92,10 +92,10 @@ struct parser cmd_parser[] = {
{ "inv.col.fg", parse_color, &game_theme.icol },
{ "inv.col.link", parse_color, &game_theme.ilcol },
{ "inv.col.alink", parse_color, &game_theme.iacol },
{ "inv.fnt.name", parse_string, &game_theme.inv_font_name },
{ "inv.fnt.name", parse_full_path, &game_theme.inv_font_name },
{ "inv.fnt.size", parse_int, &game_theme.inv_font_size },
{ "inv.gfx.up", parse_string, &game_theme.inv_a_up_name },
{ "inv.gfx.down", parse_string, &game_theme.inv_a_down_name },
{ "inv.gfx.up", parse_full_path, &game_theme.inv_a_up_name },
{ "inv.gfx.down", parse_full_path, &game_theme.inv_a_down_name },
{ "menu.col.bg", parse_color, &game_theme.menu_bg },
{ "menu.col.fg", parse_color, &game_theme.menu_fg },
@ -104,9 +104,9 @@ struct parser cmd_parser[] = {
{ "menu.col.alpha", parse_int, &game_theme.menu_alpha },
{ "menu.col.border", parse_color, &game_theme.border_col },
{ "menu.bw", parse_int, &game_theme.border_w },
{ "menu.fnt.name", parse_string, &game_theme.menu_font_name },
{ "menu.fnt.name", parse_full_path, &game_theme.menu_font_name },
{ "menu.fnt.size", parse_int, &game_theme.menu_font_size },
{ "menu.gfx.button", parse_string, &game_theme.menu_button_name },
{ "menu.gfx.button", parse_full_path, &game_theme.menu_button_name },
{ "menu.button.x", parse_int, &game_theme.menu_button_x },
{ "menu.button.y", parse_int, &game_theme.menu_button_y },
/* compat */
@ -119,6 +119,7 @@ struct parser cmd_parser[] = {
};
struct game_theme game_theme = {
.scale = 1.0f,
.w = 800,
.h = 480,
.bg_name = NULL,
@ -212,11 +213,116 @@ int game_theme_free(void)
return 0;
}
static int game_theme_init(void)
static int theme_img_scale(img_t *p, float v)
{
img_t pic;
if (!p || !*p)
return 0;
pic = gfx_scale(*p, v, v);
if (!pic)
return -1;
gfx_free_image(*p);
*p = pic;
return 0;
}
static int game_theme_scale(int w, int h)
{
float xs, ys, v;
int xoff, yoff;
struct game_theme *t = &game_theme;
if (w == -1 || h == -1) {
t->scale = 1.0f;
return 0;
}
xs = (float)w / (float)t->w;
ys = (float)h / (float)t->h;
v = (xs < ys)?xs:ys;
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->scale = v;
return 0;
}
static int theme_gfx_scale(void)
{
struct game_theme *t = &game_theme;
float v = t->scale;
if (v == 1.0f)
return 0;
if (theme_img_scale(&t->a_up, v) ||
theme_img_scale(&t->a_down, v) ||
theme_img_scale(&t->inv_a_up, v) ||
theme_img_scale(&t->inv_a_down, v) ||
theme_img_scale(&t->use, v) ||
theme_img_scale(&t->cursor, v) ||
theme_img_scale(&t->menu_button, v) ||
theme_img_scale(&t->bg, v))
return -1;
if (t->bg) {
img_t screen, pic;
int xoff = (t->w - gfx_img_w(t->bg))/2;
int yoff = (t->h - gfx_img_h(t->bg))/2;
if (xoff < 0)
xoff = 0;
if (yoff < 0)
yoff = 0;
pic = gfx_new(t->w, t->h);
if (!pic)
return -1;
screen = gfx_screen(pic);
gfx_img_fill(pic, 0, 0, t->w, t->h, gfx_col(0,0,0));
gfx_draw(t->bg, xoff, yoff);
gfx_screen(screen);
t->bg = pic;
}
return 0;
}
int game_theme_init(int w, int h)
{
struct game_theme *t = &game_theme;
game_theme_scale(w, h);
if (t->font_name) {
fnt_free(t->font);
if (!(t->font = fnt_load(t->font_name, FONT_SZ(t->font_size))))
@ -229,7 +335,6 @@ static int game_theme_init(void)
goto err;
}
if (t->menu_font_name) {
fnt_free(t->menu_font);
if (!(t->menu_font = fnt_load(t->menu_font_name, t->menu_font_size))) /* do not scale menu!!! */
@ -297,7 +402,12 @@ static int game_theme_init(void)
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");
return -1;
goto err;
}
if (theme_gfx_scale()) {
fprintf(stderr, "Can't scale theme.\n");
goto err;
}
return 0;
err:
@ -306,6 +416,7 @@ err:
return -1;
}
static int theme_parse(const char *path)
{
if (parse_ini(path, cmd_parser)) {
@ -320,8 +431,8 @@ 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;
// if (game_theme_init())
// return -1;
return 0;
}

View file

@ -12,6 +12,7 @@
#define THEME_FILE "theme.ini"
struct game_theme {
float scale;
int w;
int h;
color_t bgcol;
@ -106,6 +107,7 @@ extern int game_theme_select(const char *name);
extern int themes_lookup(const char *path);
extern int game_theme_load(const char *name);
extern int game_theme_free(void);
extern int game_theme_init(int w, int h);
extern int theme_load(const char *name);
extern char *game_local_themes_path(void);

View file

@ -222,6 +222,7 @@ int parse_full_path(const char *v, void *data)
strcpy(*p, cwd);
strcat(*p,"/");
strcat(*p, v);
unix_path(*p);
return 0;
}