fix/finish SDL2 port

* implement gamma
* menu keys fixed
* add support for horizontal mousewheel and some more mouse buttons
* fix keyrepeat
* fix window resizing
* fix compiler warnings
* use SDL to access clipboard
* remove X11-dependency
* some surplus SDL headers removed
* fix setdesktopres
* fix vsync
* improve fullscreentoggle on linux
* remove togglegrab
This commit is contained in:
ac-stef
2018-02-10 11:28:49 +01:00
committed by aurhat
parent f86579533a
commit e75dfbe4c7
33 changed files with 662 additions and 6654 deletions
+131 -103
View File
@@ -121,16 +121,13 @@ static bool grabinput = false, minimized = false;
void inputgrab(bool on)
{
#ifndef WIN32
if(!(SDL_GetWindowFlags(screen) & SDL_WINDOW_FULLSCREEN)) SDL_SetRelativeMouseMode(SDL_FALSE);
//if(!(SDL_GetWindowFlags(screen) & SDL_WINDOW_FULLSCREEN)) SDL_SetWindowGrab(screen, SDL_FALSE);
else
#endif
SDL_SetRelativeMouseMode(on ? SDL_TRUE : SDL_FALSE);
SDL_SetWindowGrab(screen, on ? SDL_TRUE : SDL_FALSE);
SDL_ShowCursor(on ? 0 : 1);
}
#if !defined(WIN32) && !defined(__APPLE__)
bool fullscreen_is_desktopres = true;
#endif
void setfullscreen(bool enable)
{
if(!screen) return;
@@ -139,8 +136,8 @@ void setfullscreen(bool enable)
#else
if(enable == !(SDL_GetWindowFlags(screen) & SDL_WINDOW_FULLSCREEN))
{
SDL_SetWindowFullscreen(screen, enable ? SDL_WINDOW_FULLSCREEN : 0);
inputgrab(grabinput);
SDL_SetWindowFullscreen(screen, enable ? (fullscreen_is_desktopres ? SDL_WINDOW_FULLSCREEN_DESKTOP : SDL_WINDOW_FULLSCREEN) : 0);
inputgrab(grabinput = enable || grabinput);
}
#endif
}
@@ -160,7 +157,6 @@ void writeinitcfg()
stream *f = openfile(path("config/init.cfg", true), "w");
if(!f) return;
f->printf("// automatically written on exit, DO NOT MODIFY\n// modify settings in game\n");
extern int fullscreen;
f->printf("fullscreen %d\n", fullscreen);
f->printf("scr_w %d\n", scr_w);
f->printf("scr_h %d\n", scr_h);
@@ -451,20 +447,7 @@ void screenres(int w, int h)
#else
return;
}
//SDL_Surface *surf = SDL_SetVideoMode(w, h, 0, SDL_OPENGL|SDL_RESIZABLE|(SDL_GetWindowFlags(screen) & SDL_WINDOW_FULLSCREEN));
//if(!surf) return;
//screen = surf;
// TODO SDL2: check if this works / is right
if(SDL_GetWindowFlags(screen) & SDL_WINDOW_FULLSCREEN) {
SDL_DisplayMode dm;
memset(&dm, 0, sizeof(dm));
dm.format = SDL_PIXELFORMAT_UNKNOWN;
dm.w = w;
dm.h = h;
SDL_SetWindowDisplayMode(screen, &dm);
} else {
SDL_SetWindowSize(screen, w, h);
}
if(!(SDL_GetWindowFlags(screen) & SDL_WINDOW_FULLSCREEN)) SDL_SetWindowSize(screen, w, h);
scr_w = windowwidth();
scr_h = windowheight();
glViewport(0, 0, scr_w, scr_h);
@@ -484,33 +467,43 @@ COMMANDF(screenres, "ii", (int *w, int *h) { screenres(*w, *h); });
VAR(desktopw, 1, 0, 0);
VAR(desktoph, 1, 0, 0);
int SDL_SetGamma(float r, float g, float b)
int setgamma(int newgamma) // replacement for SDL_SetGamma
{
// FIXME SDL2: implement gamma and get rid of this function
// this is here only to keep the compiler happy.
return -1;
static Uint16 ramp[256];
double g = 100.0f / double(newgamma);
loopi(256)
{
int val = (int)(pow((double)i/256.0, g) * 65535.0 + 0.5);
if(val > 65535) val = 65535;
ramp[i] = (Uint16)val;
}
return SDL_SetWindowGammaRamp(screen, ramp, ramp, ramp);
}
static int curgamma = 100;
VARNFP(gamma, vgamma, 30, 100, 300,
{
if(vgamma == curgamma) return;
curgamma = vgamma;
float f = vgamma/100.0f;
if(SDL_SetGamma(f,f,f)==-1) conoutf("Could not set gamma: %s", SDL_GetError());
if(vgamma != curgamma)
{
if(setgamma(vgamma) == -1) conoutf("Could not set gamma: %s", SDL_GetError());
curgamma = vgamma;
}
});
void cleargamma()
{
if(curgamma != 100) SDL_SetGamma(1, 1, 1);
if(curgamma != 100) setgamma(100);
}
void restoregamma()
{
if(curgamma == 100) return;
float f = curgamma/100.0f;
SDL_SetGamma(1, 1, 1);
SDL_SetGamma(f, f, f);
if(curgamma != 100)
{
setgamma(100);
setgamma(curgamma);
}
}
void getdisplayresolutions()
@@ -535,25 +528,19 @@ void setupscreen(int &usedcolorbits, int &useddepthbits, int &usedfsaa)
#endif
if(fullscreen) flags |= SDL_WINDOW_FULLSCREEN;
/* FIXME SDL2: do we need the following? Everything seems alright...
SDL_Rect **modes = SDL_ListModes(NULL, SDL_OPENGL|flags);
if(modes && modes!=(SDL_Rect **)-1)
int modes = SDL_GetNumDisplayModes(0), bppavail = 0;
if(modes >= 1)
{
bool hasmode = false;
for(int i = 0; modes[i]; i++)
SDL_DisplayMode mode;
loopi(modes)
{
if(scr_w <= modes[i]->w && scr_h <= modes[i]->h) { hasmode = true; break; }
if(SDL_GetDisplayMode(0, i, &mode) == 0 && scr_w <= mode.w && scr_h <= mode.h) { bppavail = SDL_BITSPERPIXEL(mode.format); hasmode = true; break; }
}
if(!hasmode) { scr_w = modes[0]->w; scr_h = modes[0]->h; }
}
*/
bool hasbpp = true;
// FIXME SDL2: do this right or get rid of it
//if(colorbits && modes)
// hasbpp = SDL_VideoModeOK(modes!=(SDL_Rect **)-1 ? modes[0]->w : scr_w, modes!=(SDL_Rect **)-1 ? modes[0]->h : scr_h, colorbits, SDL_OPENGL|flags)==colorbits;
if(!hasmode && SDL_GetDisplayMode(0, 0, &mode) == 0) { scr_w = mode.w; scr_h = mode.h; bppavail = SDL_BITSPERPIXEL(mode.format); }
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
if(vsync>=0) SDL_GL_SetSwapInterval(1);
}
bool hasbpp = !colorbits || !bppavail || colorbits <= bppavail;
static int configs[] =
{
@@ -588,11 +575,11 @@ void setupscreen(int &usedcolorbits, int &useddepthbits, int &usedfsaa)
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, config&4 ? 1 : 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, config&4 ? fsaa : 0);
}
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
screen = SDL_CreateWindow("AssaultCube",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
scr_w, scr_h,
SDL_WINDOW_OPENGL | flags);
//if(screen) break;
if(screen)
{
glcontext = SDL_GL_CreateContext(screen);
@@ -609,15 +596,19 @@ void setupscreen(int &usedcolorbits, int &useddepthbits, int &usedfsaa)
if(fsaa>0 && (config&4)==0) conoutf("%dx anti-aliasing not supported - disabling", fsaa);
}
if(vsync>=0) SDL_GL_SetSwapInterval(vsync);
scr_w = windowwidth();
scr_h = windowheight();
VIRTW = scr_w*VIRTH/scr_h;
inputgrab(grabinput = fullscreen);
inputgrab(grabinput = fullscreen ? true : false);
usedcolorbits = hasbpp ? colorbits : 0;
useddepthbits = config&1 ? depthbits : 0;
usedfsaa = config&2 ? fsaa : 0;
#if !defined(WIN32) && !defined(__APPLE__)
if(fullscreen && desktoph && desktopw) fullscreen_is_desktopres = scr_w == desktopw && scr_h == desktoph;
#endif
}
extern int hirestextures;
@@ -641,7 +632,8 @@ void resetgl()
uniformtexres = !hirestextures;
c2skeepalive();
if(screen) {
if(screen)
{
SDL_GL_DeleteContext(glcontext);
SDL_DestroyWindow(screen);
glcontext = 0;
@@ -713,12 +705,7 @@ void fpsrange(int *low, int *high)
COMMAND(fpsrange, "ii");
void keyrepeat(bool on)
{
// FIXME SDL2: implement this
//SDL_EnableKeyRepeat(on ? SDL_DEFAULT_REPEAT_DELAY : 0,
// SDL_DEFAULT_REPEAT_INTERVAL);
}
bool keyrepeat = false;
vector<SDL_Event> events;
@@ -745,13 +732,6 @@ bool interceptkey(int sym)
return false;
}
void togglegrab()
{
inputgrab(grabinput = !grabinput);
}
COMMAND(togglegrab, "");
static void resetmousemotion()
{
#ifndef WIN32
@@ -805,68 +785,110 @@ static void checkmousemotion(int &dx, int &dy)
}
int ignoremouse = 5, bootstrapentropy = 2;
#define EVENTDEBUG(x) x
//#define EVENTDEBUG(x) x
EVENTDEBUG(VAR(debugevents, 0, 1, 2));
void checkinput()
{
SDL_Event event;
int lasttype = 0, lastbut = 0;
Uint32 lasttype = 0, lastbut = 0;
int tdx=0,tdy=0;
while(events.length() || SDL_PollEvent(&event))
{
if(events.length()) event = events.remove(0);
extern void textinput(const char *);
EVENTDEBUG(int thres = 1; defformatstring(eb)("EVENT %d", event.type));
switch(event.type)
{
case SDL_QUIT:
quit();
break;
#if !defined(WIN32) && !defined(__APPLE__)
case SDL_WINDOWEVENT_RESIZED:
screenres(event.window.data1, event.window.data2);
break;
#endif
case SDL_KEYDOWN:
if(bootstrapentropy > 0 && (--bootstrapentropy & 2)) mapscreenshot(NULL, false, -1, 1000.0f / (1000 + rnd(400)), 0, 0);
case SDL_KEYUP:
EVENTDEBUG(thres = 2; concatstring(eb, event.type == SDL_KEYUP ? "(SDL_KEYUP)" : "(SDL_KEYDOWN)"));
entropy_add_byte(event.key.keysym.sym ^ totalmillis);
//keypress(event.key.keysym.sym, event.key.state==SDL_PRESSED, event.key.keysym.unicode, event.key.keysym.mod);
// FIXME console input broken here
keypress(event.key.keysym.sym, event.key.state==SDL_PRESSED, SDL_GetModState());
EVENTDEBUG(concatformatstring(eb, " sym %d (%Xh), scancode %d (%Xh), state %d, repeat %d", event.key.keysym.sym, event.key.keysym.sym, event.key.keysym.scancode, event.key.keysym.scancode, event.key.state, event.key.repeat));
if(event.key.keysym.sym == SDLK_SCANCODE_MASK) event.key.keysym.sym |= event.key.keysym.scancode; // workaround SDL 2.0.5 bug which returns sym == 40000000h for all dead keys
if(!event.key.repeat || keyrepeat) keypress(event.key.keysym.sym, event.key.state==SDL_PRESSED, (SDL_Keymod)event.key.keysym.mod);
break;
case SDL_TEXTINPUT:
EVENTDEBUG(concatformatstring(eb, "(SDL_TEXTINPUT) %s", escapestring(event.text.text)));
textinput(event.text.text);
break;
case SDL_WINDOWEVENT:
{
EVENTDEBUG(concatstring(eb, "(SDL_WINDOWEVENT) "));
switch(event.window.event)
{
case SDL_WINDOWEVENT_FOCUS_GAINED:
inputgrab(grabinput);
case SDL_WINDOWEVENT_SHOWN: // window has been shown
EVENTDEBUG(concatstring(eb, " SDL_WINDOWEVENT_SHOWN"));
break;
case SDL_WINDOWEVENT_FOCUS_LOST:
inputgrab(grabinput = false);
case SDL_WINDOWEVENT_HIDDEN: // window has been hidden
EVENTDEBUG(concatstring(eb, " SDL_WINDOWEVENT_HIDDEN"));
break;
case SDL_WINDOWEVENT_MINIMIZED:
case SDL_WINDOWEVENT_EXPOSED: // window has been exposed and should be redrawn
EVENTDEBUG(concatstring(eb, " SDL_WINDOWEVENT_EXPOSED"));
break;
case SDL_WINDOWEVENT_MOVED: // window has been moved to data1, data2
EVENTDEBUG(concatstring(eb, " SDL_WINDOWEVENT_MOVED"));
break;
#if !defined(WIN32) && !defined(__APPLE__)
case SDL_WINDOWEVENT_RESIZED: // window has been resized to data1 x data2; this is event is always preceded by SDL_WINDOWEVENT_SIZE_CHANGED
EVENTDEBUG(concatformatstring(eb, " SDL_WINDOWEVENT_RESIZED %d x %d", event.window.data1, event.window.data2));
screenres(event.window.data1, event.window.data2);
break;
#endif
case SDL_WINDOWEVENT_SIZE_CHANGED: // window size has changed, either as a result of an API call or through the system or user changing the window size; this event is followed by SDL_WINDOWEVENT_RESIZED if the size was changed by an external event, i.e. the user or the window manager
EVENTDEBUG(concatstring(eb, " SDL_WINDOWEVENT_SIZE_CHANGED"));
break;
case SDL_WINDOWEVENT_MINIMIZED: // window has been minimized
EVENTDEBUG(concatstring(eb, " SDL_WINDOWEVENT_MINIMIZED"));
inputgrab(false);
minimized = 1;
break;
case SDL_WINDOWEVENT_RESTORED:
case SDL_WINDOWEVENT_MAXIMIZED:
case SDL_WINDOWEVENT_MAXIMIZED: // window has been maximized
case SDL_WINDOWEVENT_RESTORED: // window has been restored to normal size and position
EVENTDEBUG(concatstring(eb, event.window.event == SDL_WINDOWEVENT_RESTORED ? "SDL_WINDOWEVENT_RESTORED" : "SDL_WINDOWEVENT_MAXIMIZED"));
minimized = 0;
inputgrab(grabinput);
break;
case SDL_WINDOWEVENT_ENTER: // window has gained mouse focus
EVENTDEBUG(concatstring(eb, " SDL_WINDOWEVENT_ENTER"));
break;
case SDL_WINDOWEVENT_LEAVE: // window has lost mouse focus
EVENTDEBUG(concatstring(eb, " SDL_WINDOWEVENT_LEAVE"));
break;
case SDL_WINDOWEVENT_FOCUS_GAINED: // window has gained keyboard focus
EVENTDEBUG(concatstring(eb, " SDL_WINDOWEVENT_FOCUS_GAINED"));
inputgrab(grabinput = true);
break;
case SDL_WINDOWEVENT_FOCUS_LOST: // window has lost keyboard focus
EVENTDEBUG(concatstring(eb, " SDL_WINDOWEVENT_FOCUS_LOST"));
inputgrab(grabinput = false);
break;
}
break;
}
case SDL_MOUSEMOTION:
EVENTDEBUG(thres = 2; concatformatstring(eb, "(SDL_MOUSEMOTION) x %d, y %d, dx %d, dy %d", event.motion.x, event.motion.y, event.motion.xrel, event.motion.yrel));
if(ignoremouse) { ignoremouse--; break; }
if(grabinput && !skipmousemotion(event))
{
@@ -881,24 +903,36 @@ void checkinput()
case SDL_MOUSEBUTTONDOWN:
if(!grabinput)
{
EVENTDEBUG(concatformatstring(eb, "(SDL_MOUSEBUTTONDOWN) button %d, state %d, clicks %d, x %d, y %d", event.button.button, event.button.state, event.button.clicks, event.button.x, event.button.y));
inputgrab(grabinput = true);
break;
}
case SDL_MOUSEBUTTONUP:
EVENTDEBUG(concatformatstring(eb, "(SDL_MOUSEBUTTON%s) button %d, state %d, clicks %d, x %d, y %d", event.type == SDL_MOUSEBUTTONUP ? "UP" : "DOWN", event.button.button, event.button.state, event.button.clicks, event.button.x, event.button.y));
if(lasttype==event.type && lastbut==event.button.button) break;
keypress(-event.button.button, event.button.state!=0);
keypress(-(event.button.button > 3 ? (event.button.button + 4) : event.button.button), event.button.state != SDL_RELEASED);
lasttype = event.type;
lastbut = event.button.button;
break;
case SDL_MOUSEWHEEL:
int key = event.wheel.y > 0 ? SDL_AC_BUTTON_WHEELUP : SDL_AC_BUTTON_WHEELDOWN;
// Emulate SDL1-style mouse wheel events by immediately "releasing" the wheel "button"
keypress(key, true);
keypress(key, false);
EVENTDEBUG(concatformatstring(eb, "(SDL_MOUSEWHEEL) x %d, y %d", event.wheel.x, event.wheel.y));
if(event.wheel.y)
{
int key = event.wheel.y > 0 ? SDL_AC_BUTTON_WHEELUP : SDL_AC_BUTTON_WHEELDOWN;
keypress(key, true); // Emulate SDL1-style mouse wheel events by immediately "releasing" the wheel "button"
keypress(key, false);
}
if(event.wheel.x)
{
int key = event.wheel.x > 0 ? SDL_AC_BUTTON_RIGHT : SDL_AC_BUTTON_LEFT;
keypress(key, true);
keypress(key, false);
}
break;
}
EVENTDEBUG(if(debugevents >= thres) conoutf("%s", eb));
}
if(tdx || tdy)
{
@@ -1061,10 +1095,9 @@ void initclientlog() // rotate old logfiles and create new one
/// text input is enabled (text field in menu item active, chat prompt...)
int textinputfilter(void *userdata, SDL_Event *event)
{
extern bool saycommandon;
extern bool menutextinputon();
extern bool saycommandon, menutextinputon;
if(event->type != SDL_TEXTINPUT) return 1;
return (saycommandon || menutextinputon()) ? 1 : 0;
return (saycommandon || menutextinputon) ? 1 : 0;
}
#ifdef _DEBUG
@@ -1230,19 +1263,15 @@ int main(int argc, char **argv)
if(SDL_InitSubSystem(SDL_INIT_VIDEO)<0) fatal("Unable to initialize SDL Video");
initlog("video: mode");
/* const SDL_VideoInfo *video = SDL_GetVideoInfo();
if(video)
SDL_DisplayMode desktopmode;
if(SDL_GetDesktopDisplayMode(0, &desktopmode) == 0)
{
desktopw = video->current_w;
desktoph = video->current_h;
}*/
desktopw = desktopmode.w;
desktoph = desktopmode.h;
}
int usedcolorbits = 0, useddepthbits = 0, usedfsaa = 0;
setupscreen(usedcolorbits, useddepthbits, usedfsaa);
// no more TTF ATM.
//initlog("font");
//initfont();
initlog("video: misc");
#ifndef __APPLE__
@@ -1250,7 +1279,6 @@ int main(int argc, char **argv)
SDL_SetWindowIcon(screen, icon);
#endif
keyrepeat(false);
SDL_ShowCursor(0);
initlog("gl");