user-adjustable resolution, fuck yeah
This commit is contained in:
parent
c5eba2156d
commit
3d59ba51e4
12 changed files with 266 additions and 44 deletions
|
@ -34,6 +34,7 @@ set(SRCs
|
|||
vbo.c
|
||||
stageutils.c
|
||||
matrix.c
|
||||
video.c
|
||||
menu/menu.c
|
||||
menu/mainmenu.c
|
||||
menu/options.c
|
||||
|
|
|
@ -37,7 +37,10 @@ enum {
|
|||
NO_STAGEBG,
|
||||
NO_STAGEBG_FPSLIMIT,
|
||||
|
||||
SAVE_RPY
|
||||
SAVE_RPY,
|
||||
|
||||
VID_WIDTH,
|
||||
VID_HEIGHT,
|
||||
};
|
||||
|
||||
void parse_config(char *filename);
|
||||
|
|
|
@ -41,6 +41,9 @@
|
|||
|
||||
"save_rpy" { yylval = SAVE_RPY; return tSAVE_RPY; }
|
||||
|
||||
"vid_width" { yylval = VID_WIDTH; return tVID_WIDTH; }
|
||||
"vid_height" { yylval = VID_HEIGHT; return tVID_HEIGHT; }
|
||||
|
||||
"shift" { yylval = SDLK_LSHIFT; return SKEY; }
|
||||
"ctrl" { yylval = SDLK_LCTRL; return SKEY; }
|
||||
"return" { yylval = SDLK_RETURN; return SKEY; }
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
%{
|
||||
#include "config.h"
|
||||
#include "global.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -51,6 +52,9 @@
|
|||
%token tNO_STAGEBG_FPSLIMIT
|
||||
%token tSAVE_RPY
|
||||
|
||||
%token tVID_WIDTH
|
||||
%token tVID_HEIGHT
|
||||
|
||||
%token SKEY
|
||||
|
||||
%token NUMBER
|
||||
|
@ -90,6 +94,8 @@ key_key : tKEY_UP
|
|||
| tFULLSCREEN
|
||||
| tNO_STAGEBG
|
||||
| tNO_STAGEBG_FPSLIMIT
|
||||
| tVID_WIDTH
|
||||
| tVID_HEIGHT
|
||||
| tSAVE_RPY;
|
||||
|
||||
nl : LB { lineno++; };
|
||||
|
@ -144,6 +150,9 @@ void config_preset() {
|
|||
tconfig.intval[NO_STAGEBG_FPSLIMIT] = 40;
|
||||
|
||||
tconfig.intval[SAVE_RPY] = 2;
|
||||
|
||||
tconfig.intval[VID_WIDTH] = RESX;
|
||||
tconfig.intval[VID_HEIGHT] = RESY;
|
||||
}
|
||||
|
||||
int config_sym2key(int sym) {
|
||||
|
|
16
src/global.c
16
src/global.c
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
#include "global.h"
|
||||
#include "video.h"
|
||||
#include <SDL/SDL.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
|
@ -79,19 +80,6 @@ void fade_out(float f) {
|
|||
glColor4f(1,1,1,1);
|
||||
}
|
||||
|
||||
extern SDL_Surface *display;
|
||||
|
||||
void toggle_fullscreen()
|
||||
{
|
||||
int newflags = display->flags;
|
||||
newflags ^= SDL_FULLSCREEN;
|
||||
tconfig.intval[FULLSCREEN] = newflags & SDL_FULLSCREEN;
|
||||
|
||||
SDL_FreeSurface(display);
|
||||
if((display = SDL_SetVideoMode(RESX, RESY, 32, newflags)) == NULL)
|
||||
errx(-1, "Error opening screen: %s", SDL_GetError());
|
||||
}
|
||||
|
||||
void take_screenshot()
|
||||
{
|
||||
FILE *out;
|
||||
|
@ -165,6 +153,6 @@ void global_processevent(SDL_Event *event)
|
|||
if(sym == tconfig.intval[KEY_SCREENSHOT])
|
||||
take_screenshot();
|
||||
if((sym == SDLK_RETURN && (keys[SDLK_LALT] || keys[SDLK_RALT])) || sym == tconfig.intval[KEY_FULLSCREEN])
|
||||
toggle_fullscreen();
|
||||
video_toggle_fullscreen();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,9 +35,10 @@
|
|||
#define FILE_PREFIX PREFIX "/share/taisei/"
|
||||
#define CONFIG_FILE "config"
|
||||
|
||||
enum {
|
||||
enum {
|
||||
// defaults
|
||||
RESX = 800,
|
||||
RESY = 600,
|
||||
RESY = 600,
|
||||
|
||||
SCREEN_W = 800,
|
||||
SCREEN_H = 600,
|
||||
|
|
17
src/main.c
17
src/main.c
|
@ -12,12 +12,11 @@
|
|||
#include "taisei_err.h"
|
||||
|
||||
#include "global.h"
|
||||
#include "video.h"
|
||||
#include "stage.h"
|
||||
#include "menu/mainmenu.h"
|
||||
#include "paths/native.h"
|
||||
|
||||
SDL_Surface *display;
|
||||
|
||||
void init_gl() {
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
|
||||
|
@ -35,7 +34,7 @@ void taisei_shutdown() {
|
|||
|
||||
free_resources();
|
||||
|
||||
SDL_FreeSurface(display);
|
||||
video_shutdown();
|
||||
SDL_Quit();
|
||||
printf("-- Good Bye.\n");
|
||||
}
|
||||
|
@ -63,17 +62,9 @@ int main(int argc, char** argv) {
|
|||
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||
|
||||
int flags = SDL_OPENGL;
|
||||
if(tconfig.intval[FULLSCREEN])
|
||||
flags |= SDL_FULLSCREEN;
|
||||
|
||||
if((display = SDL_SetVideoMode(RESX, RESY, 32, flags)) == NULL)
|
||||
errx(-1, "Error opening screen: %s", SDL_GetError());
|
||||
|
||||
video_init();
|
||||
printf("-- SDL viewport\n");
|
||||
|
||||
SDL_WM_SetCaption("TaiseiProject", NULL);
|
||||
|
||||
|
||||
init_gl();
|
||||
printf("-- GL\n");
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "menu.h"
|
||||
#include "options.h"
|
||||
#include "global.h"
|
||||
#include "video.h"
|
||||
#include "paths/native.h"
|
||||
#include "taisei_err.h"
|
||||
|
||||
|
@ -90,6 +91,26 @@ OptionBinding* bind_keybinding(MenuData *m, char *optname, int cfgentry)
|
|||
return bind;
|
||||
}
|
||||
|
||||
// Super-special binding type for the resulution setting
|
||||
OptionBinding* bind_resulution(MenuData *m) {
|
||||
OptionBinding *bind;
|
||||
bind = allocate_binding(m);
|
||||
|
||||
bind->enabled = True;
|
||||
bind->type = BT_Resolution;
|
||||
bind->valcount = video.mcount;
|
||||
bind->selected = -1;
|
||||
|
||||
int i; for(i = 0; i < video.mcount; ++i) {
|
||||
VideoMode *m = &(video.modes[i]);
|
||||
|
||||
if(m->width == video.intended.width && m->height == video.intended.height)
|
||||
bind->selected = i;
|
||||
}
|
||||
|
||||
return bind;
|
||||
}
|
||||
|
||||
// Returns a pointer to the first found binding that blocks input. If none found, returns NULL.
|
||||
OptionBinding* get_input_blocking_binding(MenuData *m)
|
||||
{
|
||||
|
@ -119,14 +140,20 @@ void bind_setvaluerange(OptionBinding *b, int vmin, int vmax) {
|
|||
// Called to select a value of a BT_IntValue type binding by index
|
||||
int bind_setvalue(OptionBinding *b, int v)
|
||||
{
|
||||
return b->selected = b->setter(b, v);
|
||||
if(b->setter)
|
||||
return b->selected = b->setter(b, v);
|
||||
else
|
||||
return b->selected = v;
|
||||
}
|
||||
|
||||
// Called to get the selected value of a BT_IntValue type binding by index
|
||||
int bind_getvalue(OptionBinding *b)
|
||||
{
|
||||
// query AND update
|
||||
return b->selected = b->getter(b);
|
||||
if(b->getter)
|
||||
// query AND update
|
||||
return b->selected = b->getter(b);
|
||||
else
|
||||
return b->selected;
|
||||
}
|
||||
|
||||
// Selects the next to current value of a BT_IntValue type binding
|
||||
|
@ -207,7 +234,7 @@ int bind_common_onoffset_inverted(void *b, int v)
|
|||
|
||||
int bind_fullscreen_set(void *b, int v)
|
||||
{
|
||||
toggle_fullscreen();
|
||||
video_toggle_fullscreen();
|
||||
return bind_common_onoffset(b, v);
|
||||
}
|
||||
|
||||
|
@ -313,6 +340,11 @@ void menu_save_config(MenuData *m, char *filename)
|
|||
fprintf(out, "%s = K%i\n", bind->optname, tconfig.intval[bind->configentry]);
|
||||
break;
|
||||
|
||||
case BT_Resolution:
|
||||
// at this point, the intended resolution is what the user has picked
|
||||
fprintf(out, "vid_width = %i\nvid_height = %i\n", video.intended.width, video.intended.height);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("FIXME: unhandled BindingType %i, option '%s' will NOT be saved!\n", bind->type, bind->optname);
|
||||
}
|
||||
|
@ -327,6 +359,19 @@ void menu_save_config(MenuData *m, char *filename)
|
|||
void destroy_options_menu(void *menu)
|
||||
{
|
||||
MenuData *m = (MenuData*)menu;
|
||||
OptionBinding *binds = (OptionBinding*)m->context;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < m->ecount; ++i) {
|
||||
if(binds[i].type == BT_Resolution) {
|
||||
if(binds[i].selected != -1) {
|
||||
VideoMode *m = &(video.modes[binds[i].selected]);
|
||||
video_setmode(m->width, m->height, tconfig.intval[FULLSCREEN]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
menu_save_config(m, CONFIG_FILE);
|
||||
free_bindings(menu);
|
||||
}
|
||||
|
@ -348,6 +393,9 @@ void create_options_menu(MenuData *m) {
|
|||
|
||||
#define bind_onoff(b) bind_addvalue(b, "on"); bind_addvalue(b, "off")
|
||||
|
||||
add_menu_entry(m, "Video Mode", do_nothing, NULL);
|
||||
b = bind_resulution(m);
|
||||
|
||||
add_menu_entry(m, "Fullscreen", do_nothing, NULL);
|
||||
b = bind_option(m, "fullscreen", FULLSCREEN, bind_common_onoffget, bind_fullscreen_set);
|
||||
bind_onoff(b);
|
||||
|
@ -357,7 +405,7 @@ void create_options_menu(MenuData *m) {
|
|||
bind_noaudio_set);
|
||||
bind_onoff(b);
|
||||
|
||||
add_menu_entry(m, "Shader", do_nothing, NULL);
|
||||
add_menu_entry(m, "Shaders", do_nothing, NULL);
|
||||
b = bind_option(m, "disable_shader", NO_SHADER, bind_common_onoffget_inverted,
|
||||
bind_noshader_set);
|
||||
bind_onoff(b);
|
||||
|
@ -519,6 +567,24 @@ void draw_options_menu(MenuData *menu) {
|
|||
else
|
||||
draw_text(AL_Right, origin, 20*i, SDL_GetKeyName(tconfig.intval[bind->configentry]), _fonts.standard);
|
||||
break;
|
||||
|
||||
case BT_Resolution: {
|
||||
char tmp[16];
|
||||
int w, h;
|
||||
|
||||
if(bind->selected == -1) {
|
||||
w = video.intended.width;
|
||||
h = video.intended.height;
|
||||
} else {
|
||||
VideoMode *m = &(video.modes[bind->selected]);
|
||||
w = m->width;
|
||||
h = m->height;
|
||||
}
|
||||
|
||||
snprintf(tmp, 16, "%dx%d", w, h);
|
||||
draw_text(AL_Right, origin, 20*i, tmp, _fonts.standard);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -582,24 +648,22 @@ static void options_key_action(MenuData *menu, int sym) {
|
|||
|
||||
if(bind->enabled) switch(bind->type)
|
||||
{
|
||||
case BT_IntValue: bind_setnext(bind); break;
|
||||
case BT_KeyBinding: bind->blockinput = True; break;
|
||||
}
|
||||
else
|
||||
menu->quit = 1;
|
||||
case BT_IntValue: case BT_Resolution: bind_setnext(bind); break;
|
||||
case BT_KeyBinding: bind->blockinput = True; break;
|
||||
} else menu->quit = 1;
|
||||
} else if(sym == tconfig.intval[KEY_LEFT] || sym == SDLK_LEFT) {
|
||||
menu->selected = menu->cursor;
|
||||
OptionBinding *binds = (OptionBinding*)menu->context;
|
||||
OptionBinding *bind = &(binds[menu->selected]);
|
||||
|
||||
if(bind->enabled && bind->type == BT_IntValue)
|
||||
if(bind->enabled && (bind->type == BT_IntValue || bind->type == BT_Resolution))
|
||||
bind_setprev(bind);
|
||||
} else if(sym == tconfig.intval[KEY_RIGHT] || sym == SDLK_RIGHT) {
|
||||
menu->selected = menu->cursor;
|
||||
OptionBinding *binds = (OptionBinding*)menu->context;
|
||||
OptionBinding *bind = &(binds[menu->selected]);
|
||||
|
||||
if(bind->enabled && bind->type == BT_IntValue)
|
||||
if(bind->enabled && (bind->type == BT_IntValue || bind->type == BT_Resolution))
|
||||
bind_setnext(bind);
|
||||
} else if(sym == SDLK_ESCAPE) {
|
||||
menu->quit = 1;
|
||||
|
|
|
@ -22,7 +22,8 @@ typedef int (*BindingDependence)();
|
|||
|
||||
typedef enum BindingType {
|
||||
BT_IntValue,
|
||||
BT_KeyBinding
|
||||
BT_KeyBinding,
|
||||
BT_Resolution
|
||||
} BindingType;
|
||||
|
||||
typedef struct OptionBinding {
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <SDL/SDL.h>
|
||||
#include <time.h>
|
||||
#include "global.h"
|
||||
#include "video.h"
|
||||
#include "replay.h"
|
||||
#include "config.h"
|
||||
#include "player.h"
|
||||
|
@ -246,7 +247,7 @@ void stage_draw(StageInfo *info, StageRule bgdraw, ShaderRule *shaderrules, int
|
|||
|
||||
if(!tconfig.intval[NO_SHADER]) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glViewport(0,0,RESX,RESY);
|
||||
glViewport(0, 0, video.current.width, video.current.height);
|
||||
glPushMatrix();
|
||||
if(global.plr.cha == Marisa && global.plr.shot == MarisaLaser && global.frames - global.plr.recovery < 0)
|
||||
glTranslatef(8*sin(global.frames),8*sin(global.frames+3),0);
|
||||
|
|
127
src/video.c
Normal file
127
src/video.c
Normal file
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* This software is licensed under the terms of the MIT-License
|
||||
* See COPYING for further information.
|
||||
* ---
|
||||
* Copyright (C) 2011, Lukas Weber <laochailan@web.de>
|
||||
* Copyright (C) 2012, Alexeyew Andrew <http://akari.thebadasschoobs.org/>
|
||||
*/
|
||||
|
||||
#include "global.h"
|
||||
#include "video.h"
|
||||
#include "taisei_err.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
static VideoMode common_modes[] = {
|
||||
{RESX, RESY},
|
||||
|
||||
{640, 480},
|
||||
{800, 600},
|
||||
{1024, 768},
|
||||
{1280, 960},
|
||||
{1152, 864},
|
||||
{1400, 1050},
|
||||
{1440, 1080},
|
||||
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
static void video_add_mode(int width, int height) {
|
||||
if(video.modes) {
|
||||
int i; for(i = 0; i < video.mcount; ++i) {
|
||||
VideoMode *m = &(video.modes[i]);
|
||||
if(m->width == width && m->height == height)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
video.modes = (VideoMode*)realloc(video.modes, (++video.mcount) * sizeof(VideoMode));
|
||||
video.modes[video.mcount-1].width = width;
|
||||
video.modes[video.mcount-1].height = height;
|
||||
}
|
||||
|
||||
static int video_compare_modes(const void *a, const void *b) {
|
||||
VideoMode *va = (VideoMode*)a;
|
||||
VideoMode *vb = (VideoMode*)b;
|
||||
return va->width * va->height - vb->width * vb->height;
|
||||
}
|
||||
|
||||
static void _video_setmode(int w, int h, int fs, int fallback) {
|
||||
int flags = SDL_OPENGL;
|
||||
if(fs) flags |= SDL_FULLSCREEN;
|
||||
|
||||
if(!fallback) {
|
||||
video.intended.width = w;
|
||||
video.intended.height = h;
|
||||
}
|
||||
|
||||
if(display)
|
||||
SDL_FreeSurface(display);
|
||||
|
||||
if(!(display = SDL_SetVideoMode(w, h, 32, flags))) {
|
||||
if(fallback) {
|
||||
errx(-1, "video_setmode(): error opening screen: %s", SDL_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
warnx("video_setmode(): setting %dx%d failed, falling back to %dx%d", w, h, RESX, RESY);
|
||||
_video_setmode(RESX, RESY, fs, True);
|
||||
}
|
||||
|
||||
const SDL_VideoInfo *info = SDL_GetVideoInfo();
|
||||
video.current.width = info->current_w;
|
||||
video.current.height = info->current_h;
|
||||
|
||||
glViewport(0, 0, video.current.width, video.current.height);
|
||||
}
|
||||
|
||||
void video_setmode(int w, int h, int fs) {
|
||||
_video_setmode(w, h, fs, False);
|
||||
}
|
||||
|
||||
int video_isfullscreen(void) {
|
||||
return !!(display->flags & SDL_FULLSCREEN);
|
||||
}
|
||||
|
||||
void video_toggle_fullscreen(void) {
|
||||
video_setmode(video.intended.width, video.intended.height, !video_isfullscreen());
|
||||
}
|
||||
|
||||
void video_init(void) {
|
||||
SDL_Rect **modes;
|
||||
int i;
|
||||
|
||||
memset(&video, 0, sizeof(video));
|
||||
|
||||
// First register all resolutions that are available in fullscreen
|
||||
modes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_HWSURFACE);
|
||||
if(!modes) {
|
||||
warnx("video_init(): no available fullscreen modes");
|
||||
tconfig.intval[FULLSCREEN] = False;
|
||||
} else if(modes == (SDL_Rect**)-1) {
|
||||
warnx("video_init(): you seem to have a weird video driver");
|
||||
} else {
|
||||
for(i = 0; modes[i]; ++i) {
|
||||
video_add_mode(modes[i]->w, modes[i]->h);
|
||||
}
|
||||
}
|
||||
|
||||
// Then, add some common 4:3 modes for the windowed mode if they are not there yet.
|
||||
// This is required for some multihead setups.
|
||||
for(i = 0; common_modes[i].width; ++i)
|
||||
video_add_mode(common_modes[i].width, common_modes[i].height);
|
||||
|
||||
// sort it, mainly for the options menu
|
||||
qsort(video.modes, video.mcount, sizeof(VideoMode), video_compare_modes);
|
||||
|
||||
for(i = 0; i < video.mcount; ++i) {
|
||||
printf(" +++ %dx%d\n", video.modes[i].width, video.modes[i].height);
|
||||
}
|
||||
|
||||
video_setmode(tconfig.intval[VID_WIDTH], tconfig.intval[VID_HEIGHT], tconfig.intval[FULLSCREEN]);
|
||||
SDL_WM_SetCaption("TaiseiProject", NULL);
|
||||
}
|
||||
|
||||
void video_shutdown(void) {
|
||||
SDL_FreeSurface(display);
|
||||
free(video.modes);
|
||||
}
|
33
src/video.h
Normal file
33
src/video.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* This software is licensed under the terms of the MIT-License
|
||||
* See COPYING for further information.
|
||||
* ---
|
||||
* Copyright (C) 2011, Lukas Weber <laochailan@web.de>
|
||||
* Copyright (C) 2012, Alexeyew Andrew <http://akari.thebadasschoobs.org/>
|
||||
*/
|
||||
|
||||
#ifndef VIDEO_H
|
||||
#define VIDEO_H
|
||||
|
||||
typedef struct VideoMode {
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
} VideoMode;
|
||||
|
||||
typedef struct {
|
||||
VideoMode *modes;
|
||||
int mcount;
|
||||
VideoMode intended;
|
||||
VideoMode current;
|
||||
} Video;
|
||||
|
||||
Video video;
|
||||
SDL_Surface *display;
|
||||
|
||||
void video_init(void);
|
||||
void video_shutdown(void);
|
||||
void video_setmode(int w, int h, int fs);
|
||||
int video_isfullscreen(void);
|
||||
void video_toggle_fullscreen(void);
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue