mirror of
https://github.com/love2d/love-android.git
synced 2026-08-20 04:31:26 +02:00
updated to latest mobile-common (0cf55b7da58e), removed libtiff, libpng, libmng, devil, jasper, jpeg-8d, added libturbo-jpeg
This commit is contained in:
@@ -42,7 +42,7 @@ WindowSettings::WindowSettings()
|
||||
: fullscreen(false)
|
||||
, fstype(Window::FULLSCREEN_TYPE_NORMAL)
|
||||
, vsync(true)
|
||||
, fsaa(0)
|
||||
, msaa(0)
|
||||
, resizable(false)
|
||||
, minwidth(1)
|
||||
, minheight(1)
|
||||
@@ -74,12 +74,23 @@ bool Window::getConstant(Window::Setting in, const char *&out)
|
||||
return settings.find(in, out);
|
||||
}
|
||||
|
||||
bool Window::getConstant(const char *in, MessageBoxType &out)
|
||||
{
|
||||
return messageBoxTypes.find(in, out);
|
||||
}
|
||||
|
||||
bool Window::getConstant(MessageBoxType in, const char *&out)
|
||||
{
|
||||
return messageBoxTypes.find(in, out);
|
||||
}
|
||||
|
||||
StringMap<Window::Setting, Window::SETTING_MAX_ENUM>::Entry Window::settingEntries[] =
|
||||
{
|
||||
{"fullscreen", SETTING_FULLSCREEN},
|
||||
{"fullscreentype", SETTING_FULLSCREEN_TYPE},
|
||||
{"vsync", SETTING_VSYNC},
|
||||
{"fsaa", SETTING_FSAA},
|
||||
{"msaa", SETTING_MSAA},
|
||||
{"resizable", SETTING_RESIZABLE},
|
||||
{"minwidth", SETTING_MIN_WIDTH},
|
||||
{"minheight", SETTING_MIN_HEIGHT},
|
||||
@@ -100,5 +111,14 @@ StringMap<Window::FullscreenType, Window::FULLSCREEN_TYPE_MAX_ENUM>::Entry Windo
|
||||
|
||||
StringMap<Window::FullscreenType, Window::FULLSCREEN_TYPE_MAX_ENUM> Window::fullscreenTypes(Window::fullscreenTypeEntries, sizeof(Window::fullscreenTypeEntries));
|
||||
|
||||
StringMap<Window::MessageBoxType, Window::MESSAGEBOX_MAX_ENUM>::Entry Window::messageBoxTypeEntries[] =
|
||||
{
|
||||
{"error", Window::MESSAGEBOX_ERROR},
|
||||
{"warning", Window::MESSAGEBOX_WARNING},
|
||||
{"info", Window::MESSAGEBOX_INFO},
|
||||
};
|
||||
|
||||
StringMap<Window::MessageBoxType, Window::MESSAGEBOX_MAX_ENUM> Window::messageBoxTypes(Window::messageBoxTypeEntries, sizeof(Window::messageBoxTypeEntries));
|
||||
|
||||
} // window
|
||||
} // love
|
||||
|
||||
@@ -49,7 +49,8 @@ public:
|
||||
SETTING_FULLSCREEN,
|
||||
SETTING_FULLSCREEN_TYPE,
|
||||
SETTING_VSYNC,
|
||||
SETTING_FSAA,
|
||||
SETTING_FSAA, // For backward-compatibility. TODO: remove!
|
||||
SETTING_MSAA,
|
||||
SETTING_RESIZABLE,
|
||||
SETTING_MIN_WIDTH,
|
||||
SETTING_MIN_HEIGHT,
|
||||
@@ -68,14 +69,39 @@ public:
|
||||
FULLSCREEN_TYPE_MAX_ENUM
|
||||
};
|
||||
|
||||
enum MessageBoxType
|
||||
{
|
||||
MESSAGEBOX_ERROR,
|
||||
MESSAGEBOX_WARNING,
|
||||
MESSAGEBOX_INFO,
|
||||
MESSAGEBOX_MAX_ENUM
|
||||
};
|
||||
|
||||
struct WindowSize
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
struct MessageBoxData
|
||||
{
|
||||
MessageBoxType type;
|
||||
|
||||
std::string title;
|
||||
std::string message;
|
||||
|
||||
std::vector<std::string> buttons;
|
||||
int enterButtonIndex;
|
||||
int escapeButtonIndex;
|
||||
|
||||
bool attachToWindow;
|
||||
};
|
||||
|
||||
virtual ~Window();
|
||||
|
||||
// Implements Module.
|
||||
virtual ModuleType getModuleType() const { return M_WINDOW; }
|
||||
|
||||
virtual bool setWindow(int width = 800, int height = 600, WindowSettings *settings = nullptr) = 0;
|
||||
virtual void getWindow(int &width, int &height, WindowSettings &settings) = 0;
|
||||
|
||||
@@ -86,6 +112,8 @@ public:
|
||||
|
||||
virtual int getDisplayCount() const = 0;
|
||||
|
||||
virtual const char *getDisplayName(int displayindex) const = 0;
|
||||
|
||||
virtual std::vector<WindowSize> getFullscreenSizes(int displayindex) const = 0;
|
||||
|
||||
virtual int getWidth() const = 0;
|
||||
@@ -101,6 +129,8 @@ public:
|
||||
virtual bool setIcon(love::image::ImageData *imgd) = 0;
|
||||
virtual love::image::ImageData *getIcon() = 0;
|
||||
|
||||
virtual void minimize() = 0;
|
||||
|
||||
// default no-op implementation
|
||||
virtual void swapBuffers();
|
||||
|
||||
@@ -117,8 +147,13 @@ public:
|
||||
|
||||
virtual double getPixelScale() const = 0;
|
||||
|
||||
virtual bool isTouchScreen(int displayindex) const = 0;
|
||||
|
||||
virtual const void *getHandle() const = 0;
|
||||
|
||||
virtual bool showMessageBox(MessageBoxType type, const std::string &title, const std::string &message, bool attachtowindow) = 0;
|
||||
virtual int showMessageBox(const MessageBoxData &data) = 0;
|
||||
|
||||
//virtual static Window *createSingleton() = 0;
|
||||
//virtual static Window *getSingleton() = 0;
|
||||
// No virtual statics, of course, but you are supposed to implement these statics.
|
||||
@@ -129,6 +164,9 @@ public:
|
||||
static bool getConstant(const char *in, FullscreenType &out);
|
||||
static bool getConstant(FullscreenType in, const char *&out);
|
||||
|
||||
static bool getConstant(const char *in, MessageBoxType &out);
|
||||
static bool getConstant(MessageBoxType in, const char *&out);
|
||||
|
||||
protected:
|
||||
|
||||
static Window *singleton;
|
||||
@@ -141,6 +179,9 @@ private:
|
||||
static StringMap<FullscreenType, FULLSCREEN_TYPE_MAX_ENUM>::Entry fullscreenTypeEntries[];
|
||||
static StringMap<FullscreenType, FULLSCREEN_TYPE_MAX_ENUM> fullscreenTypes;
|
||||
|
||||
static StringMap<MessageBoxType, MESSAGEBOX_MAX_ENUM>::Entry messageBoxTypeEntries[];
|
||||
static StringMap<MessageBoxType, MESSAGEBOX_MAX_ENUM> messageBoxTypes;
|
||||
|
||||
}; // Window
|
||||
|
||||
struct WindowSettings
|
||||
@@ -150,7 +191,7 @@ struct WindowSettings
|
||||
bool fullscreen; // = false
|
||||
Window::FullscreenType fstype; // = FULLSCREEN_TYPE_NORMAL
|
||||
bool vsync; // = true
|
||||
int fsaa; // = 0
|
||||
int msaa; // = 0
|
||||
bool resizable; // = false
|
||||
int minwidth; // = 1
|
||||
int minheight; // = 1
|
||||
|
||||
@@ -55,9 +55,6 @@ Window::Window()
|
||||
|
||||
Window::~Window()
|
||||
{
|
||||
if (curMode.icon)
|
||||
curMode.icon->release();
|
||||
|
||||
if (window)
|
||||
SDL_DestroyWindow(window);
|
||||
|
||||
@@ -105,11 +102,20 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
|
||||
else
|
||||
{
|
||||
sdlflags |= SDL_WINDOW_FULLSCREEN;
|
||||
SDL_DisplayMode mode = {0, width, height, 0, 0};
|
||||
|
||||
// Fullscreen window creation will bug out if no mode can be used.
|
||||
SDL_DisplayMode mode = {0, width, height, 0, 0};
|
||||
if (SDL_GetClosestDisplayMode(f.display, &mode, &mode) == 0)
|
||||
return false;
|
||||
if (SDL_GetClosestDisplayMode(f.display, &mode, &mode) == nullptr)
|
||||
{
|
||||
// GetClosestDisplayMode will fail if we request a size larger
|
||||
// than the largest available display mode, so we'll try to use
|
||||
// the largest (first) mode in that case.
|
||||
if (SDL_GetDisplayMode(f.display, 0, &mode) < 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
width = mode.w;
|
||||
height = mode.h;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,7 +131,7 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
|
||||
sdlflags |= SDL_WINDOW_ALLOW_HIGHDPI;
|
||||
#endif
|
||||
|
||||
graphics::Graphics *gfx = (graphics::Graphics *) Module::findInstance("love.graphics.");
|
||||
graphics::Graphics *gfx = Module::getInstance<graphics::Graphics>(Module::M_GRAPHICS);
|
||||
if (gfx != nullptr)
|
||||
gfx->unSetMode();
|
||||
|
||||
@@ -146,7 +152,7 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
|
||||
wflags &= testflags;
|
||||
|
||||
if (sdlflags != wflags || width != curMode.width || height != curMode.height
|
||||
|| f.display != curdisplay || f.fsaa != curMode.settings.fsaa)
|
||||
|| f.display != curdisplay || f.msaa != curMode.settings.msaa)
|
||||
{
|
||||
SDL_DestroyWindow(window);
|
||||
window = 0;
|
||||
@@ -165,31 +171,31 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
|
||||
created = false;
|
||||
|
||||
// In Windows and Linux, some GL attributes are set on window creation.
|
||||
setWindowGLAttributes(f.fsaa, f.sRGB);
|
||||
setWindowGLAttributes(f.msaa, f.sRGB);
|
||||
|
||||
const char *title = windowTitle.c_str();
|
||||
int pos = f.centered ? centeredpos : uncenteredpos;
|
||||
|
||||
window = SDL_CreateWindow(title, pos, pos, width, height, sdlflags);
|
||||
|
||||
if (!window && f.fsaa > 0)
|
||||
if (!window && f.msaa > 0)
|
||||
{
|
||||
// FSAA might have caused the failure, disable it and try again.
|
||||
// MSAA might have caused the failure, disable it and try again.
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
|
||||
|
||||
window = SDL_CreateWindow(title, pos, pos, width, height, sdlflags);
|
||||
f.fsaa = 0;
|
||||
f.msaa = 0;
|
||||
}
|
||||
|
||||
// Make sure the window keeps any previously set icon.
|
||||
if (window && curMode.icon)
|
||||
setIcon(curMode.icon);
|
||||
if (window && curMode.icon.get())
|
||||
setIcon(curMode.icon.get());
|
||||
}
|
||||
|
||||
if (!window)
|
||||
{
|
||||
displayError("Could not create window", SDL_GetError());
|
||||
showMessageBox(MESSAGEBOX_ERROR, "Could not create window", SDL_GetError(), false);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -201,7 +207,7 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
|
||||
|
||||
SDL_RaiseWindow(window);
|
||||
|
||||
if (!setContext(f.fsaa, f.vsync, f.sRGB))
|
||||
if (!setContext(f.msaa, f.vsync, f.sRGB))
|
||||
{
|
||||
created = false;
|
||||
return false;
|
||||
@@ -222,7 +228,7 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
|
||||
#endif
|
||||
|
||||
if (!gfx->setMode(width, height, curMode.settings.sRGB))
|
||||
displayError("Could not set graphics mode", "Unsupported OpenGL version?");
|
||||
showMessageBox(MESSAGEBOX_ERROR, "Could not set graphics mode", "Unsupported OpenGL version?", true);
|
||||
}
|
||||
|
||||
// Make sure the mouse keeps its previous grab setting.
|
||||
@@ -242,9 +248,9 @@ bool Window::onWindowResize(int width, int height)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Window::setContext(int fsaa, bool vsync, bool sRGB)
|
||||
bool Window::setContext(int msaa, bool vsync, bool sRGB)
|
||||
{
|
||||
// We would normally only need to recreate the context if FSAA changes or
|
||||
// We would normally only need to recreate the context if MSAA changes or
|
||||
// SDL_GL_MakeCurrent is unsuccessful, but in Windows MakeCurrent can
|
||||
// sometimes claim success but the context will actually be trashed.
|
||||
if (context)
|
||||
@@ -254,13 +260,13 @@ bool Window::setContext(int fsaa, bool vsync, bool sRGB)
|
||||
}
|
||||
|
||||
// Make sure the proper attributes are set.
|
||||
setWindowGLAttributes(fsaa, sRGB);
|
||||
setWindowGLAttributes(msaa, sRGB);
|
||||
|
||||
context = SDL_GL_CreateContext(window);
|
||||
|
||||
if (!context && fsaa > 0)
|
||||
if (!context && msaa > 0)
|
||||
{
|
||||
// FSAA might have caused the failure, disable it and try again.
|
||||
// MSAA might have caused the failure, disable it and try again.
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
|
||||
context = SDL_GL_CreateContext(window);
|
||||
@@ -283,33 +289,33 @@ bool Window::setContext(int fsaa, bool vsync, bool sRGB)
|
||||
|
||||
if (!context)
|
||||
{
|
||||
displayError("Could not create OpenGL context", SDL_GetError());
|
||||
showMessageBox(MESSAGEBOX_ERROR, "Could not create OpenGL context", SDL_GetError(), true);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set vertical synchronization.
|
||||
SDL_GL_SetSwapInterval(vsync ? 1 : 0);
|
||||
|
||||
// Verify FSAA setting.
|
||||
// Verify MSAA setting.
|
||||
int buffers;
|
||||
int samples;
|
||||
SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &buffers);
|
||||
SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &samples);
|
||||
|
||||
// Don't fail because of this, but issue a warning.
|
||||
if ((!buffers && fsaa) || (samples != fsaa))
|
||||
if ((!buffers && msaa) || (samples != msaa))
|
||||
{
|
||||
std::cerr << "Warning, FSAA setting failed! (Result: buffers: " << buffers << ", samples: " << samples << ")" << std::endl;
|
||||
fsaa = (buffers > 0) ? samples : 0;
|
||||
std::cerr << "Warning, MSAA setting failed! (Result: buffers: " << buffers << ", samples: " << samples << ")" << std::endl;
|
||||
msaa = (buffers > 0) ? samples : 0;
|
||||
}
|
||||
|
||||
curMode.settings.fsaa = fsaa;
|
||||
curMode.settings.msaa = msaa;
|
||||
curMode.settings.vsync = SDL_GL_GetSwapInterval() != 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Window::setWindowGLAttributes(int fsaa, bool /* sRGB */) const
|
||||
void Window::setWindowGLAttributes(int msaa, bool /* sRGB */) const
|
||||
{
|
||||
// Set GL window attributes.
|
||||
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
|
||||
@@ -320,9 +326,9 @@ void Window::setWindowGLAttributes(int fsaa, bool /* sRGB */) const
|
||||
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1);
|
||||
SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 0);
|
||||
|
||||
// FSAA.
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, (fsaa > 0) ? 1 : 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, (fsaa > 0) ? fsaa : 0);
|
||||
// MSAA.
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, (msaa > 0) ? 1 : 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, (msaa > 0) ? msaa : 0);
|
||||
|
||||
/* FIXME: Enable this code but make sure to try to re-create the window and
|
||||
* context with this disabled, if creation fails with it enabled.
|
||||
@@ -436,16 +442,6 @@ void Window::updateSettings(const WindowSettings &newsettings)
|
||||
curMode.settings.sRGB = newsettings.sRGB;
|
||||
}
|
||||
|
||||
void Window::displayError(const std::string &title, const std::string &text) const
|
||||
{
|
||||
std::cerr << title << ": " << text << std::endl;
|
||||
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, title.c_str(), text.c_str(), window);
|
||||
}
|
||||
|
||||
void Window::getWindow(int &width, int &height, WindowSettings &settings)
|
||||
{
|
||||
// The window might have been modified (moved, resized, etc.) by the user.
|
||||
@@ -491,7 +487,7 @@ bool Window::setFullscreen(bool fullscreen, Window::FullscreenType fstype)
|
||||
updateSettings(newsettings);
|
||||
|
||||
// Update the viewport size now instead of waiting for event polling.
|
||||
graphics::Graphics *gfx = (graphics::Graphics *) Module::findInstance("love.graphics.");
|
||||
graphics::Graphics *gfx = Module::getInstance<graphics::Graphics>(Module::M_GRAPHICS);
|
||||
if (gfx != nullptr)
|
||||
{
|
||||
int width = curMode.width;
|
||||
@@ -521,6 +517,16 @@ int Window::getDisplayCount() const
|
||||
return SDL_GetNumVideoDisplays();
|
||||
}
|
||||
|
||||
const char *Window::getDisplayName(int displayindex) const
|
||||
{
|
||||
const char *name = SDL_GetDisplayName(displayindex);
|
||||
|
||||
if (name == nullptr)
|
||||
throw love::Exception("Invalid display index: %d", displayindex + 1);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
typedef Window::WindowSize WindowSize;
|
||||
|
||||
std::vector<WindowSize> Window::getFullscreenSizes(int displayindex) const
|
||||
@@ -604,10 +610,7 @@ bool Window::setIcon(love::image::ImageData *imgd)
|
||||
if (!imgd)
|
||||
return false;
|
||||
|
||||
imgd->retain();
|
||||
if (curMode.icon)
|
||||
curMode.icon->release();
|
||||
curMode.icon = imgd;
|
||||
curMode.icon.set(imgd);
|
||||
|
||||
if (!window)
|
||||
return false;
|
||||
@@ -648,7 +651,13 @@ bool Window::setIcon(love::image::ImageData *imgd)
|
||||
|
||||
love::image::ImageData *Window::getIcon()
|
||||
{
|
||||
return curMode.icon;
|
||||
return curMode.icon.get();
|
||||
}
|
||||
|
||||
void Window::minimize()
|
||||
{
|
||||
if (window != nullptr)
|
||||
SDL_MinimizeWindow(window);
|
||||
}
|
||||
|
||||
void Window::swapBuffers()
|
||||
@@ -719,11 +728,82 @@ double Window::getPixelScale() const
|
||||
return scale;
|
||||
}
|
||||
|
||||
bool Window::isTouchScreen(int displayindex) const
|
||||
{
|
||||
#if defined(LOVE_ANDROID) || defined(LOVE_IOS)
|
||||
// Display 0 is always a touch screen on Android and iOS.
|
||||
return displayindex == 0;
|
||||
#else
|
||||
// TODO: implement for Windows and Linux.
|
||||
LOVE_UNUSED(displayindex);
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
const void *Window::getHandle() const
|
||||
{
|
||||
return window;
|
||||
}
|
||||
|
||||
SDL_MessageBoxFlags Window::convertMessageBoxType(MessageBoxType type) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case MESSAGEBOX_ERROR:
|
||||
return SDL_MESSAGEBOX_ERROR;
|
||||
case MESSAGEBOX_WARNING:
|
||||
return SDL_MESSAGEBOX_WARNING;
|
||||
case MESSAGEBOX_INFO:
|
||||
default:
|
||||
return SDL_MESSAGEBOX_INFORMATION;
|
||||
}
|
||||
}
|
||||
|
||||
bool Window::showMessageBox(MessageBoxType type, const std::string &title, const std::string &message, bool attachtowindow)
|
||||
{
|
||||
SDL_MessageBoxFlags flags = convertMessageBoxType(type);
|
||||
SDL_Window *sdlwindow = attachtowindow ? window : nullptr;
|
||||
|
||||
return SDL_ShowSimpleMessageBox(flags, title.c_str(), message.c_str(), sdlwindow) >= 0;
|
||||
}
|
||||
|
||||
int Window::showMessageBox(const MessageBoxData &data)
|
||||
{
|
||||
SDL_MessageBoxData sdldata = {};
|
||||
|
||||
sdldata.flags = convertMessageBoxType(data.type);
|
||||
sdldata.title = data.title.c_str();
|
||||
sdldata.message = data.message.c_str();
|
||||
sdldata.window = data.attachToWindow ? window : nullptr;
|
||||
|
||||
sdldata.numbuttons = (int) data.buttons.size();
|
||||
|
||||
std::vector<SDL_MessageBoxButtonData> sdlbuttons;
|
||||
|
||||
for (size_t i = 0; i < data.buttons.size(); i++)
|
||||
{
|
||||
SDL_MessageBoxButtonData sdlbutton = {};
|
||||
|
||||
sdlbutton.buttonid = (int) i;
|
||||
sdlbutton.text = data.buttons[i].c_str();
|
||||
|
||||
if ((int) i == data.enterButtonIndex)
|
||||
sdlbutton.flags |= SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT;
|
||||
|
||||
if ((int) i == data.escapeButtonIndex)
|
||||
sdlbutton.flags |= SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT;
|
||||
|
||||
sdlbuttons.push_back(sdlbutton);
|
||||
}
|
||||
|
||||
sdldata.buttons = &sdlbuttons[0];
|
||||
|
||||
int pressedbutton = -2;
|
||||
SDL_ShowMessageBox(&sdldata, &pressedbutton);
|
||||
|
||||
return pressedbutton;
|
||||
}
|
||||
|
||||
love::window::Window *Window::createSingleton()
|
||||
{
|
||||
if (!singleton)
|
||||
|
||||
@@ -51,6 +51,8 @@ public:
|
||||
|
||||
int getDisplayCount() const;
|
||||
|
||||
const char *getDisplayName(int displayindex) const;
|
||||
|
||||
std::vector<WindowSize> getFullscreenSizes(int displayindex) const;
|
||||
|
||||
int getWidth() const;
|
||||
@@ -66,6 +68,8 @@ public:
|
||||
bool setIcon(love::image::ImageData *imgd);
|
||||
love::image::ImageData *getIcon();
|
||||
|
||||
void minimize();
|
||||
|
||||
void swapBuffers();
|
||||
|
||||
bool hasFocus() const;
|
||||
@@ -81,8 +85,13 @@ public:
|
||||
|
||||
double getPixelScale() const;
|
||||
|
||||
bool isTouchScreen(int displayindex) const;
|
||||
|
||||
const void *getHandle() const;
|
||||
|
||||
bool showMessageBox(MessageBoxType type, const std::string &title, const std::string &message, bool attachtowindow);
|
||||
int showMessageBox(const MessageBoxData &data);
|
||||
|
||||
static love::window::Window *createSingleton();
|
||||
static love::window::Window *getSingleton();
|
||||
|
||||
@@ -90,14 +99,13 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
bool setContext(int fsaa, bool vsync, bool sRGB);
|
||||
void setWindowGLAttributes(int fsaa, bool sRGB) const;
|
||||
bool setContext(int msaa, bool vsync, bool sRGB);
|
||||
void setWindowGLAttributes(int msaa, bool sRGB) const;
|
||||
|
||||
// Update the saved window settings based on the window's actual state.
|
||||
void updateSettings(const WindowSettings &newsettings);
|
||||
|
||||
// Shows a warning/error message box.
|
||||
void displayError(const std::string &title, const std::string &text) const;
|
||||
SDL_MessageBoxFlags convertMessageBoxType(MessageBoxType type) const;
|
||||
|
||||
std::string windowTitle;
|
||||
|
||||
@@ -108,7 +116,7 @@ private:
|
||||
int width;
|
||||
int height;
|
||||
WindowSettings settings;
|
||||
love::image::ImageData *icon;
|
||||
Object::StrongRef<love::image::ImageData> icon;
|
||||
|
||||
} curMode;
|
||||
|
||||
|
||||
@@ -26,11 +26,22 @@ namespace love
|
||||
namespace window
|
||||
{
|
||||
|
||||
static Window *instance = nullptr;
|
||||
#define instance() (Module::getInstance<Window>(Module::M_WINDOW))
|
||||
|
||||
int w_getDisplayCount(lua_State *L)
|
||||
{
|
||||
lua_pushinteger(L, instance->getDisplayCount());
|
||||
lua_pushinteger(L, instance()->getDisplayCount());
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_getDisplayName(lua_State *L)
|
||||
{
|
||||
int index = luaL_checkint(L, 1) - 1;
|
||||
|
||||
const char *name = nullptr;
|
||||
luax_catchexcept(L, [&](){ name = instance()->getDisplayName(index); });
|
||||
|
||||
lua_pushstring(L, name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -48,7 +59,7 @@ int w_setMode(lua_State *L)
|
||||
|
||||
if (lua_isnoneornil(L, 3))
|
||||
{
|
||||
luax_pushboolean(L, instance->setWindow(w, h, 0));
|
||||
luax_pushboolean(L, instance()->setWindow(w, h, 0));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -88,7 +99,7 @@ int w_setMode(lua_State *L)
|
||||
|
||||
settings.fullscreen = luax_boolflag(L, 3, settingName(Window::SETTING_FULLSCREEN), false);
|
||||
settings.vsync = luax_boolflag(L, 3, settingName(Window::SETTING_VSYNC), true);
|
||||
settings.fsaa = luax_intflag(L, 3, settingName(Window::SETTING_FSAA), 0);
|
||||
settings.msaa = luax_intflag(L, 3, settingName(Window::SETTING_MSAA), 0);
|
||||
settings.resizable = luax_boolflag(L, 3, settingName(Window::SETTING_RESIZABLE), false);
|
||||
settings.minwidth = luax_intflag(L, 3, settingName(Window::SETTING_MIN_WIDTH), 1);
|
||||
settings.minheight = luax_intflag(L, 3, settingName(Window::SETTING_MIN_HEIGHT), 1);
|
||||
@@ -98,10 +109,17 @@ int w_setMode(lua_State *L)
|
||||
settings.highdpi = luax_boolflag(L, 3, settingName(Window::SETTING_HIGHDPI), false);
|
||||
settings.sRGB = luax_boolflag(L, 3, settingName(Window::SETTING_SRGB), false);
|
||||
|
||||
// For backward-compatibility. TODO: remove!
|
||||
int fsaa = luax_intflag(L, 3, settingName(Window::SETTING_FSAA), 0);
|
||||
if (fsaa > settings.msaa) settings.msaa = fsaa;
|
||||
|
||||
// Display index is 1-based in Lua and 0-based internally.
|
||||
settings.display--;
|
||||
|
||||
EXCEPT_GUARD(luax_pushboolean(L, instance->setWindow(w, h, &settings));)
|
||||
luax_catchexcept(L,
|
||||
[&](){ luax_pushboolean(L, instance()->setWindow(w, h, &settings)); }
|
||||
);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -109,7 +127,7 @@ int w_getMode(lua_State *L)
|
||||
{
|
||||
int w, h;
|
||||
WindowSettings settings;
|
||||
instance->getWindow(w, h, settings);
|
||||
instance()->getWindow(w, h, settings);
|
||||
lua_pushnumber(L, w);
|
||||
lua_pushnumber(L, h);
|
||||
|
||||
@@ -127,8 +145,11 @@ int w_getMode(lua_State *L)
|
||||
luax_pushboolean(L, settings.vsync);
|
||||
lua_setfield(L, -2, settingName(Window::SETTING_VSYNC));
|
||||
|
||||
lua_pushinteger(L, settings.fsaa);
|
||||
lua_setfield(L, -2, settingName(Window::SETTING_FSAA));
|
||||
lua_pushinteger(L, settings.msaa);
|
||||
lua_setfield(L, -2, settingName(Window::SETTING_MSAA));
|
||||
|
||||
lua_pushinteger(L, settings.msaa);
|
||||
lua_setfield(L, -2, settingName(Window::SETTING_FSAA)); // For backward-compatibility. TODO: remove!
|
||||
|
||||
luax_pushboolean(L, settings.resizable);
|
||||
lua_setfield(L, -2, settingName(Window::SETTING_RESIZABLE));
|
||||
@@ -162,7 +183,7 @@ int w_getFullscreenModes(lua_State *L)
|
||||
{
|
||||
int displayindex = luaL_optint(L, 1, 1) - 1;
|
||||
|
||||
std::vector<Window::WindowSize> modes = instance->getFullscreenSizes(displayindex);
|
||||
std::vector<Window::WindowSize> modes = instance()->getFullscreenSizes(displayindex);
|
||||
|
||||
lua_createtable(L, modes.size(), 0);
|
||||
|
||||
@@ -198,9 +219,9 @@ int w_setFullscreen(lua_State *L)
|
||||
|
||||
bool success = false;
|
||||
if (fstype == Window::FULLSCREEN_TYPE_MAX_ENUM)
|
||||
success = instance->setFullscreen(fullscreen);
|
||||
success = instance()->setFullscreen(fullscreen);
|
||||
else
|
||||
success = instance->setFullscreen(fullscreen, fstype);
|
||||
success = instance()->setFullscreen(fullscreen, fstype);
|
||||
|
||||
luax_pushboolean(L, success);
|
||||
return 1;
|
||||
@@ -210,7 +231,7 @@ int w_getFullscreen(lua_State *L)
|
||||
{
|
||||
int w, h;
|
||||
WindowSettings settings;
|
||||
instance->getWindow(w, h, settings);
|
||||
instance()->getWindow(w, h, settings);
|
||||
|
||||
const char *typestr;
|
||||
if (!Window::getConstant(settings.fstype, typestr))
|
||||
@@ -223,26 +244,26 @@ int w_getFullscreen(lua_State *L)
|
||||
|
||||
int w_isCreated(lua_State *L)
|
||||
{
|
||||
luax_pushboolean(L, instance->isCreated());
|
||||
luax_pushboolean(L, instance()->isCreated());
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_getWidth(lua_State *L)
|
||||
{
|
||||
lua_pushinteger(L, instance->getWidth());
|
||||
lua_pushinteger(L, instance()->getWidth());
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_getHeight(lua_State *L)
|
||||
{
|
||||
lua_pushinteger(L, instance->getHeight());
|
||||
lua_pushinteger(L, instance()->getHeight());
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_getDimensions(lua_State *L)
|
||||
{
|
||||
lua_pushinteger(L, instance->getWidth());
|
||||
lua_pushinteger(L, instance->getHeight());
|
||||
lua_pushinteger(L, instance()->getWidth());
|
||||
lua_pushinteger(L, instance()->getHeight());
|
||||
return 2;
|
||||
}
|
||||
|
||||
@@ -250,7 +271,7 @@ int w_getDesktopDimensions(lua_State *L)
|
||||
{
|
||||
int width = 0, height = 0;
|
||||
int displayindex = luaL_optint(L, 1, 1) - 1;
|
||||
instance->getDesktopDimensions(displayindex, width, height);
|
||||
instance()->getDesktopDimensions(displayindex, width, height);
|
||||
lua_pushinteger(L, width);
|
||||
lua_pushinteger(L, height);
|
||||
return 2;
|
||||
@@ -259,18 +280,15 @@ int w_getDesktopDimensions(lua_State *L)
|
||||
int w_setIcon(lua_State *L)
|
||||
{
|
||||
image::ImageData *i = luax_checktype<image::ImageData>(L, 1, "ImageData", IMAGE_IMAGE_DATA_T);
|
||||
luax_pushboolean(L, instance->setIcon(i));
|
||||
luax_pushboolean(L, instance()->setIcon(i));
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_getIcon(lua_State *L)
|
||||
{
|
||||
image::ImageData *i = instance->getIcon();
|
||||
image::ImageData *i = instance()->getIcon();
|
||||
if (i)
|
||||
{
|
||||
i->retain();
|
||||
luax_pushtype(L, "ImageData", IMAGE_IMAGE_DATA_T, i);
|
||||
}
|
||||
else
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
@@ -279,43 +297,117 @@ int w_getIcon(lua_State *L)
|
||||
int w_setTitle(lua_State *L)
|
||||
{
|
||||
std::string title = luax_checkstring(L, 1);
|
||||
instance->setWindowTitle(title);
|
||||
instance()->setWindowTitle(title);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_getTitle(lua_State *L)
|
||||
{
|
||||
luax_pushstring(L, instance->getWindowTitle());
|
||||
luax_pushstring(L, instance()->getWindowTitle());
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_hasFocus(lua_State *L)
|
||||
{
|
||||
luax_pushboolean(L, instance->hasFocus());
|
||||
luax_pushboolean(L, instance()->hasFocus());
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_hasMouseFocus(lua_State *L)
|
||||
{
|
||||
luax_pushboolean(L, instance->hasMouseFocus());
|
||||
luax_pushboolean(L, instance()->hasMouseFocus());
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_isVisible(lua_State *L)
|
||||
{
|
||||
luax_pushboolean(L, instance->isVisible());
|
||||
luax_pushboolean(L, instance()->isVisible());
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_getPixelScale(lua_State *L)
|
||||
{
|
||||
lua_pushnumber(L, instance->getPixelScale());
|
||||
lua_pushnumber(L, instance()->getPixelScale());
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_isTouchScreen(lua_State *L)
|
||||
{
|
||||
int index = luaL_optint(L, 1, 1) - 1;
|
||||
luax_pushboolean(L, instance()->isTouchScreen(index));
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_minimize(lua_State* /*L*/)
|
||||
{
|
||||
instance()->minimize();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_showMessageBox(lua_State *L)
|
||||
{
|
||||
Window::MessageBoxData data = {};
|
||||
|
||||
const char *typestr = luaL_checkstring(L, 1);
|
||||
if (!Window::getConstant(typestr, data.type))
|
||||
return luaL_error(L, "Invalid messagebox type: %s", typestr);
|
||||
|
||||
data.title = luaL_checkstring(L, 2);
|
||||
data.message = luaL_checkstring(L, 3);
|
||||
|
||||
// If we have a table argument, we assume a list of button names, which
|
||||
// means we should use the more complex message box API.
|
||||
if (lua_istable(L, 4))
|
||||
{
|
||||
size_t numbuttons = lua_objlen(L, 4);
|
||||
if (numbuttons == 0)
|
||||
return luaL_error(L, "Must have at least one messagebox button.");
|
||||
|
||||
// Array of button names.
|
||||
for (size_t i = 0; i < numbuttons; i++)
|
||||
{
|
||||
lua_rawgeti(L, 4, i + 1);
|
||||
data.buttons.push_back(luax_checkstring(L, -1));
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
// Optional table entry specifying the button to use when enter is pressed.
|
||||
lua_getfield(L, 4, "enterbutton");
|
||||
if (!lua_isnoneornil(L, -1))
|
||||
data.enterButtonIndex = luaL_checkint(L, -1) - 1;
|
||||
else
|
||||
data.enterButtonIndex = 0;
|
||||
lua_pop(L, 1);
|
||||
|
||||
// Optional table entry specifying the button to use when esc is pressed.
|
||||
lua_getfield(L, 4, "escapebutton");
|
||||
if (!lua_isnoneornil(L, -1))
|
||||
data.escapeButtonIndex = luaL_checkint(L, -1) - 1;
|
||||
else
|
||||
data.escapeButtonIndex = (int) data.buttons.size() - 1;
|
||||
lua_pop(L, 1);
|
||||
|
||||
data.attachToWindow = luax_optboolean(L, 5, true);
|
||||
|
||||
int pressedbutton = instance()->showMessageBox(data);
|
||||
lua_pushinteger(L, pressedbutton + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
data.attachToWindow = luax_optboolean(L, 4, true);
|
||||
|
||||
// Display a simple message box.
|
||||
bool success = instance()->showMessageBox(data.type, data.title, data.message, data.attachToWindow);
|
||||
luax_pushboolean(L, success);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const luaL_Reg functions[] =
|
||||
{
|
||||
{ "getDisplayCount", w_getDisplayCount },
|
||||
{ "getDisplayName", w_getDisplayName },
|
||||
{ "setMode", w_setMode },
|
||||
{ "getMode", w_getMode },
|
||||
{ "getFullscreenModes", w_getFullscreenModes },
|
||||
@@ -334,12 +426,16 @@ static const luaL_Reg functions[] =
|
||||
{ "hasMouseFocus", w_hasMouseFocus },
|
||||
{ "isVisible", w_isVisible },
|
||||
{ "getPixelScale", w_getPixelScale },
|
||||
{ "isTouchScreen", w_isTouchScreen },
|
||||
{ "minimize", w_minimize },
|
||||
{ "showMessageBox", w_showMessageBox },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
extern "C" int luaopen_love_window(lua_State *L)
|
||||
{
|
||||
EXCEPT_GUARD(instance = sdl::Window::createSingleton();)
|
||||
Window *instance = nullptr;
|
||||
luax_catchexcept(L, [&](){ instance = sdl::Window::createSingleton(); });
|
||||
|
||||
WrappedModule w;
|
||||
w.module = instance;
|
||||
|
||||
@@ -30,6 +30,7 @@ namespace window
|
||||
{
|
||||
|
||||
int w_getDisplayCount(lua_State *L);
|
||||
int w_getDisplayName(lua_State *L);
|
||||
int w_setMode(lua_State *L);
|
||||
int w_getMode(lua_State *L);
|
||||
int w_getFullscreenModes(lua_State *L);
|
||||
@@ -48,6 +49,9 @@ int w_hasFocus(lua_State *L);
|
||||
int w_hasMouseFocus(lua_State *L);
|
||||
int w_isVisible(lua_State *L);
|
||||
int w_getPixelScale(lua_State *L);
|
||||
int w_isTouchScreen(lua_State *L);
|
||||
int w_minimize(lua_State *L);
|
||||
int w_showMessageBox(lua_State *L);
|
||||
extern "C" LOVE_EXPORT int luaopen_love_window(lua_State *L);
|
||||
|
||||
} // window
|
||||
|
||||
Reference in New Issue
Block a user