summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThorbjørn Lindeijer <bjorn@lindeijer.nl>2024-01-25 15:41:57 +0100
committerThorbjørn Lindeijer <bjorn@lindeijer.nl>2024-01-25 15:41:57 +0100
commit2c51c98625b225cecfb9628c30d62d4e30f7e3e1 (patch)
tree5f8f85a40785439b6a9ea249a75e81e26d1b44f1
parent8fdbae08d7f269c72889f89b56493071a2279350 (diff)
downloadmana-client-2c51c98625b225cecfb9628c30d62d4e30f7e3e1.tar.gz
mana-client-2c51c98625b225cecfb9628c30d62d4e30f7e3e1.tar.bz2
mana-client-2c51c98625b225cecfb9628c30d62d4e30f7e3e1.tar.xz
mana-client-2c51c98625b225cecfb9628c30d62d4e30f7e3e1.zip
Ported to SDL2
-rw-r--r--CMakeLists.txt4
-rw-r--r--src/CMakeLists.txt53
-rw-r--r--src/client.cpp121
-rw-r--r--src/client.h13
-rw-r--r--src/compoundsprite.cpp18
-rw-r--r--src/game.cpp4
-rw-r--r--src/graphics.cpp367
-rw-r--r--src/graphics.h99
-rw-r--r--src/gui/gui.cpp18
-rw-r--r--src/gui/gui.h2
-rw-r--r--src/gui/sdlinput.cpp120
-rw-r--r--src/gui/sdlinput.h22
-rw-r--r--src/gui/setup_keyboard.cpp4
-rw-r--r--src/gui/setup_video.cpp34
-rw-r--r--src/gui/truetypefont.cpp4
-rw-r--r--src/gui/viewport.cpp2
-rw-r--r--src/gui/widgets/desktop.cpp24
-rw-r--r--src/gui/widgets/emoteshortcutcontainer.cpp2
-rw-r--r--src/gui/widgets/itemshortcutcontainer.cpp2
-rw-r--r--src/gui/widgets/textfield.cpp43
-rw-r--r--src/gui/widgets/textfield.h6
-rw-r--r--src/gui/windowmenu.cpp2
-rw-r--r--src/joystick.cpp2
-rw-r--r--src/keyboardconfig.cpp6
-rw-r--r--src/keyboardconfig.h2
-rw-r--r--src/net/download.cpp2
-rw-r--r--src/net/tmwa/network.cpp2
-rw-r--r--src/openglgraphics.cpp75
-rw-r--r--src/openglgraphics.h9
-rw-r--r--src/resources/ambientlayer.cpp22
-rw-r--r--src/resources/image.cpp291
-rw-r--r--src/resources/image.h58
-rw-r--r--src/sound.cpp3
-rw-r--r--src/utils/copynpaste.cpp310
-rw-r--r--src/utils/copynpaste.h10
35 files changed, 656 insertions, 1100 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c049d6d4..6d0d62ab 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,5 +1,5 @@
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-CMAKE_POLICY(VERSION 2.6)
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12)
+CMAKE_POLICY(VERSION 2.8.12)
PROJECT(MANA)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 6c0b3081..7aa6cdcb 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,9 +1,10 @@
-FIND_PACKAGE(SDL REQUIRED)
-FIND_PACKAGE(SDL_image REQUIRED)
-FIND_PACKAGE(SDL_mixer REQUIRED)
-FIND_PACKAGE(SDL_net REQUIRED)
-FIND_PACKAGE(SDL_ttf REQUIRED)
-FIND_PACKAGE(SDL_gfx REQUIRED)
+include(FindPkgConfig)
+pkg_check_modules(SDL2 REQUIRED sdl2>=2.0.1)
+pkg_check_modules(SDL2IMAGE REQUIRED SDL2_image)
+pkg_check_modules(SDL2MIXER REQUIRED SDL2_mixer)
+pkg_check_modules(SDL2NET REQUIRED SDL2_net)
+pkg_check_modules(SDL2TTF REQUIRED SDL2_ttf)
+pkg_check_modules(SDL2GFX REQUIRED SDL2_gfx)
FIND_PACKAGE(CURL REQUIRED)
FIND_PACKAGE(LibXml2 REQUIRED)
FIND_PACKAGE(PhysFS REQUIRED)
@@ -69,8 +70,7 @@ ELSEIF (CMAKE_SYSTEM_NAME STREQUAL SunOS)
SET(EXTRA_LIBRARIES intl)
ENDIF()
-SET(GUICHAN_COMPONENTS "SDL")
-FIND_PACKAGE(Guichan REQUIRED ${GUICHAN_COMPONENTS})
+FIND_PACKAGE(Guichan REQUIRED)
IF (WITH_OPENGL)
FIND_PACKAGE(OpenGL REQUIRED)
@@ -87,12 +87,12 @@ ENDIF (USE_X11)
INCLUDE_DIRECTORIES(
${CMAKE_CURRENT_SOURCE_DIR}
- ${SDL_INCLUDE_DIR}
- ${SDLIMAGE_INCLUDE_DIR}
- ${SDLMIXER_INCLUDE_DIR}
- ${SDLNET_INCLUDE_DIR}
- ${SDLTTF_INCLUDE_DIR}
- ${SDLGFX_INCLUDE_DIR}
+ ${SDL2_INCLUDE_DIRS}
+ ${SDL2IMAGE_INCLUDE_DIRS}
+ ${SDL2MIXER_INCLUDE_DIRS}
+ ${SDL2NET_INCLUDE_DIRS}
+ ${SDL2TTF_INCLUDE_DIRS}
+ ${SDL2GFX_INCLUDE_DIRS}
${PNG_INCLUDE_DIR}
${PHYSFS_INCLUDE_DIR}
${CURL_INCLUDE_DIR}
@@ -116,19 +116,6 @@ IF (MINGW)
"<CMAKE_RC_COMPILER> <FLAGS> <DEFINES> -O coff -o <OBJECT> <SOURCE>")
ENDIF()
-# Fix some stuff that gets not hidden by mainline modules
-MARK_AS_ADVANCED(PHYSFS_INCLUDE_DIR)
-MARK_AS_ADVANCED(PHYSFS_LIBRARY)
-MARK_AS_ADVANCED(SDLIMAGE_INCLUDE_DIR)
-MARK_AS_ADVANCED(SDLIMAGE_LIBRARY)
-MARK_AS_ADVANCED(SDLMAIN_LIBRARY)
-MARK_AS_ADVANCED(SDLMIXER_INCLUDE_DIR)
-MARK_AS_ADVANCED(SDLMIXER_LIBRARY)
-MARK_AS_ADVANCED(SDLNET_INCLUDE_DIR)
-MARK_AS_ADVANCED(SDLNET_LIBRARY)
-MARK_AS_ADVANCED(SDL_INCLUDE_DIR)
-MARK_AS_ADVANCED(SDL_LIBRARY)
-
SET(SRCS
gui/widgets/avatarlistbox.cpp
gui/widgets/avatarlistbox.h
@@ -677,12 +664,12 @@ ENDIF(ENABLE_MANASERV)
TARGET_LINK_LIBRARIES(mana
${INTERNAL_LIBRARIES}
- ${SDLGFX_LIBRARIES}
- ${SDL_LIBRARY}
- ${SDLIMAGE_LIBRARY}
- ${SDLMIXER_LIBRARY}
- ${SDLNET_LIBRARY}
- ${SDLTTF_LIBRARY}
+ ${SDL2_LIBRARIES}
+ ${SDL2GFX_LIBRARIES}
+ ${SDL2IMAGE_LIBRARIES}
+ ${SDL2MIXER_LIBRARIES}
+ ${SDL2NET_LIBRARIES}
+ ${SDL2TTF_LIBRARIES}
${PNG_LIBRARIES}
${PHYSFS_LIBRARY}
${CURL_LIBRARIES}
diff --git a/src/client.cpp b/src/client.cpp
index b7dca379..4030b042 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -241,11 +241,6 @@ Client::Client(const Options &options):
}
atexit(SDL_Quit);
- SDL_EnableUNICODE(1);
- SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
-
- SDL_WM_SetCaption(branding.getValue("appName", "Mana").c_str(), NULL);
-
ResourceManager *resman = ResourceManager::getInstance();
if (!resman->setWriteDir(mLocalDataDir))
@@ -254,8 +249,6 @@ Client::Client(const Options &options):
"Exiting.", mLocalDataDir.c_str()));
}
- Image::SDLsetEnableAlphaCache(config.getValue("alphaCache", true));
-
#if defined __APPLE__
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle);
@@ -300,6 +293,39 @@ Client::Client(const Options &options):
// Add the local data directory to PhysicsFS search path
resman->addToSearchPath(mLocalDataDir, false);
+ bool useOpenGL = !mOptions.noOpenGL && (config.getValue("opengl", 1) == 1);
+
+ // Set up the transparency option for low CPU when not using OpenGL.
+ if (!useOpenGL && (config.getValue("disableTransparency", 0) == 1))
+ Image::SDLdisableTransparency();
+
+#ifdef USE_OPENGL
+ // Setup image loading for the right image format
+ Image::setLoadAsOpenGL(useOpenGL);
+
+ // Create the graphics context
+ graphics = useOpenGL ? new OpenGLGraphics : new Graphics;
+#else
+ // Create the graphics context
+ graphics = new Graphics;
+#endif
+
+ const int width = config.getIntValue("screenwidth");
+ const int height = config.getIntValue("screenheight");
+ const bool fullscreen = config.getBoolValue("screen");
+
+ // Try to set the desired video mode
+ if (!graphics->setVideoMode(width, height, fullscreen))
+ {
+ logger->error(strprintf("Couldn't set %dx%d video mode: %s",
+ width, height, SDL_GetError()));
+ }
+
+ SDL_SetWindowTitle(graphics->getTarget(),
+ branding.getValue("appName", "Mana").c_str());
+
+ Image::setRenderer(graphics->getRenderer());
+
std::string iconFile = branding.getValue("appIcon", "icons/mana");
#ifdef _WIN32
iconFile += ".ico";
@@ -325,42 +351,10 @@ Client::Client(const Options &options):
mIcon = IMG_Load(iconFile.c_str());
if (mIcon)
{
- SDL_SetAlpha(mIcon, SDL_SRCALPHA, SDL_ALPHA_OPAQUE);
- SDL_WM_SetIcon(mIcon, NULL);
+ SDL_SetWindowIcon(graphics->getTarget(), mIcon);
}
#endif
- bool useOpenGL = !mOptions.noOpenGL && (config.getValue("opengl", 1) == 1);
-
- // Set up the transparency option for low CPU when not using OpenGL.
- if (!useOpenGL && (config.getValue("disableTransparency", 0) == 1))
- Image::SDLdisableTransparency();
-
-#ifdef USE_OPENGL
-
- // Setup image loading for the right image format
- Image::setLoadAsOpenGL(useOpenGL);
-
- // Create the graphics context
- graphics = useOpenGL ? new OpenGLGraphics : new Graphics;
-#else
- // Create the graphics context
- graphics = new Graphics;
-#endif
-
- const int width = config.getIntValue("screenwidth");
- const int height = config.getIntValue("screenheight");
- const int bpp = 0;
- const bool fullscreen = config.getBoolValue("screen");
- const bool hwaccel = config.getBoolValue("hwaccel");
-
- // Try to set the desired video mode
- if (!graphics->setVideoMode(width, height, bpp, fullscreen, hwaccel))
- {
- logger->error(strprintf("Couldn't set %dx%dx%d video mode: %s",
- width, height, bpp, SDL_GetError()));
- }
-
// Initialize for drawing
graphics->_beginDraw();
@@ -511,8 +505,12 @@ int Client::exec()
case SDL_KEYDOWN:
break;
- case SDL_VIDEORESIZE:
- handleVideoResize(event.resize.w, event.resize.h);
+ case SDL_WINDOWEVENT:
+ switch (event.window.event) {
+ case SDL_WINDOWEVENT_RESIZED:
+ handleVideoResize(event.window.data1, event.window.data2);
+ break;
+ }
break;
}
@@ -1374,27 +1372,17 @@ void Client::accountLogin(LoginData *loginData)
void Client::handleVideoResize(int width, int height)
{
- // Keep a minimum size. This isn't adhered to by the actual window, but
- // it keeps some window positions from getting messed up.
- width = std::max(640, width);
- height = std::max(480, height);
-
if (graphics->getWidth() == width && graphics->getHeight() == height)
return;
- if (graphics->changeVideoMode(width,
- height,
- graphics->getBpp(),
- false,
- graphics->getHWAccel()))
- {
- videoResized(width, height);
+ graphics->videoResized(width, height);
- // Since everything appears to have worked out, remember to store the
- // new size in the configuration.
- config.setValue("screenwidth", width);
- config.setValue("screenheight", height);
- }
+ videoResized(width, height);
+
+ // Since everything appears to have worked out, remember to store the
+ // new size in the configuration.
+ config.setValue("screenwidth", width);
+ config.setValue("screenheight", height);
}
void Client::videoResized(int width, int height)
@@ -1410,3 +1398,18 @@ void Client::videoResized(int width, int height)
if (mGame)
mGame->videoResized(width, height);
}
+
+bool Client::isActive()
+{
+ return !(SDL_GetWindowFlags(graphics->getTarget()) & SDL_WINDOW_MINIMIZED);
+}
+
+bool Client::hasInputFocus()
+{
+ return SDL_GetWindowFlags(graphics->getTarget()) & SDL_WINDOW_INPUT_FOCUS;
+}
+
+bool Client::hasMouseFocus()
+{
+ return SDL_GetWindowFlags(graphics->getTarget()) & SDL_WINDOW_MOUSE_FOCUS;
+}
diff --git a/src/client.h b/src/client.h
index 4ad5562d..28fd4445 100644
--- a/src/client.h
+++ b/src/client.h
@@ -29,7 +29,7 @@
#include <guichan/actionlistener.hpp>
#include <SDL.h>
-#include <SDL_framerate.h>
+#include <SDL2_framerate.h>
#include <string>
@@ -214,14 +214,9 @@ public:
*/
void videoResized(int width, int height);
- static bool isActive()
- { return SDL_GetAppState() & SDL_APPACTIVE; }
-
- static bool hasInputFocus()
- { return SDL_GetAppState() & SDL_APPINPUTFOCUS; }
-
- static bool hasMouseFocus()
- { return SDL_GetAppState() & SDL_APPMOUSEFOCUS; }
+ static bool isActive();
+ static bool hasInputFocus();
+ static bool hasMouseFocus();
private:
void initRootDir();
diff --git a/src/compoundsprite.cpp b/src/compoundsprite.cpp
index cd07ca51..0f231535 100644
--- a/src/compoundsprite.cpp
+++ b/src/compoundsprite.cpp
@@ -20,7 +20,6 @@
#include "compoundsprite.h"
-#include "game.h"
#include "graphics.h"
#include "map.h"
@@ -223,6 +222,7 @@ int CompoundSprite::getDuration() const
return duration;
}
+#if 0
static void updateValues(int &dimension, int &pos, int imgDimUL, int imgDimRD, int imgOffset)
{
// Handle going beyond the left/up
@@ -238,11 +238,18 @@ static void updateValues(int &dimension, int &pos, int imgDimUL, int imgDimRD, i
if (temp > dimension)
dimension = temp;
}
-
-#include "localplayer.h"
+#endif
void CompoundSprite::redraw() const
{
+#if 1 // TODO_SDL2: Does it make sense to implement CompoundSprite?
+ mWidth = mSprites.at(0)->getWidth();
+ mHeight = mSprites.at(0)->getHeight();
+ mOffsetX = 0;
+ mOffsetY = 0;
+ mNeedsRedraw = false;
+#else
+
#ifdef USE_OPENGL
// TODO OpenGL support
if (Image::getLoadAsOpenGL())
@@ -295,7 +302,7 @@ void CompoundSprite::redraw() const
int amask = 0xff000000;
#endif
- SDL_Surface *surface = SDL_CreateRGBSurface(SDL_HWSURFACE, mWidth, mHeight,
+ SDL_Surface *surface = SDL_CreateRGBSurface(0, mWidth, mHeight,
32, rmask, gmask, bmask, amask);
if (!surface)
@@ -322,7 +329,7 @@ void CompoundSprite::redraw() const
delete graphics;
- SDL_Surface *surfaceA = SDL_CreateRGBSurface(SDL_HWSURFACE, mWidth, mHeight,
+ SDL_Surface *surfaceA = SDL_CreateRGBSurface(0, mWidth, mHeight,
32, rmask, gmask, bmask, amask);
SDL_SetAlpha(surface, 0, SDL_ALPHA_OPAQUE);
@@ -338,4 +345,5 @@ void CompoundSprite::redraw() const
SDL_FreeSurface(surfaceA);
mNeedsRedraw = false;
+#endif
}
diff --git a/src/game.cpp b/src/game.cpp
index 222e56df..f71d8575 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -398,10 +398,10 @@ void Game::handleInput()
{
bool used = false;
- if (event.type == SDL_VIDEORESIZE)
+ if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_RESIZED)
{
// Let the client deal with this one (it'll pass down from there)
- Client::instance()->handleVideoResize(event.resize.w, event.resize.h);
+ Client::instance()->handleVideoResize(event.window.data1, event.window.data2);
}
// Keyboard events (for discontinuous keys)
else if (event.type == SDL_KEYDOWN)
diff --git a/src/graphics.cpp b/src/graphics.cpp
index ac3735f5..b4c65b0a 100644
--- a/src/graphics.cpp
+++ b/src/graphics.cpp
@@ -19,8 +19,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <cassert>
-
#include "graphics.h"
#include "log.h"
@@ -28,103 +26,95 @@
#include "utils/gettext.h"
-#include <SDL_gfxBlitFunc.h>
+#include <guichan/exception.hpp>
-Graphics::Graphics():
- mWidth(0),
- mHeight(0),
- mBpp(0),
- mFullscreen(false),
- mHWAccel(false),
- mBlitMode(BLIT_NORMAL)
+Graphics::~Graphics()
{
+ _endDraw();
}
-Graphics::~Graphics()
+void Graphics::setTarget(SDL_Window *target)
{
_endDraw();
+
+ mTarget = target;
+
+ if (mTarget)
+ _beginDraw();
}
-bool Graphics::setVideoMode(int w, int h, int bpp, bool fs, bool hwaccel)
+bool Graphics::setVideoMode(int w, int h, bool fs)
{
logger->log("Setting video mode %dx%d %s",
w, h, fs ? "fullscreen" : "windowed");
- logger->log("Bits per pixel: %d", bpp);
-
- int displayFlags = SDL_ANYFORMAT;
+ int windowFlags = SDL_WINDOW_ALLOW_HIGHDPI;
if (fs)
- displayFlags |= SDL_FULLSCREEN;
+ windowFlags |= SDL_WINDOW_FULLSCREEN;
else
- displayFlags |= SDL_RESIZABLE;
+ windowFlags |= SDL_WINDOW_RESIZABLE;
- if (hwaccel)
- displayFlags |= SDL_HWSURFACE | SDL_DOUBLEBUF;
- else
- displayFlags |= SDL_SWSURFACE;
+ // TODO_SDL2: Support SDL_WINDOW_FULLSCREEN_DESKTOP
- setTarget(SDL_SetVideoMode(w, h, bpp, displayFlags));
+ SDL_Window *window = nullptr;
+ SDL_Renderer *renderer = nullptr;
+ SDL_CreateWindowAndRenderer(w, h, windowFlags, &window, &renderer);
- if (!mTarget)
+ if (!window)
return false;
+ SDL_SetWindowMinimumSize(window, 640, 480);
+ SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
+
+ setTarget(window);
+
+ mRenderer = renderer;
mWidth = w;
mHeight = h;
- mBpp = bpp;
mFullscreen = fs;
- mHWAccel = hwaccel;
- char videoDriverName[64];
-
- if (SDL_VideoDriverName(videoDriverName, 64))
- logger->log("Using video driver: %s", videoDriverName);
+ if (const char *driver = SDL_GetCurrentVideoDriver())
+ logger->log("Using video driver: %s", driver);
else
- logger->log("Using video driver: unknown");
-
- const SDL_VideoInfo *vi = SDL_GetVideoInfo();
-
- logger->log("Possible to create hardware surfaces: %s",
- vi->hw_available ? "yes" : "no");
- logger->log("Window manager available: %s",
- vi->wm_available ? "yes" : "no");
- logger->log("Accelerated hardware to hardware blits: %s",
- vi->blit_hw ? "yes" : "no");
- logger->log("Accelerated hardware to hardware colorkey blits: %s",
- vi->blit_hw_CC ? "yes" : "no");
- logger->log("Accelerated hardware to hardware alpha blits: %s",
- vi->blit_hw_A ? "yes" : "no");
- logger->log("Accelerated software to hardware blits: %s",
- vi->blit_sw ? "yes" : "no");
- logger->log("Accelerated software to hardware colorkey blits: %s",
- vi->blit_sw_CC ? "yes" : "no");
- logger->log("Accelerated software to hardware alpha blits: %s",
- vi->blit_sw_A ? "yes" : "no");
- logger->log("Accelerated color fills: %s",
- vi->blit_fill ? "yes" : "no");
- logger->log("Available video memory: %d", vi->video_mem);
+ logger->log("Using video driver: not initialized");
+
+ SDL_RendererInfo info;
+
+ if (SDL_GetRendererInfo(mRenderer, &info) == 0) {
+ logger->log("Using renderer: %s", info.name);
+
+ logger->log("The renderer is a software fallback: %s",
+ (info.flags & SDL_RENDERER_SOFTWARE) ? "yes" : "no");
+ logger->log("The renderer is hardware accelerated: %s",
+ (info.flags & SDL_RENDERER_ACCELERATED) ? "yes" : "no");
+ logger->log("Vsync: %s",
+ (info.flags & SDL_RENDERER_PRESENTVSYNC) ? "on" : "off");
+ logger->log("Renderer supports rendering to texture: %s",
+ (info.flags & SDL_RENDERER_TARGETTEXTURE) ? "yes" : "no");
+ logger->log("Max texture size: %dx%d",
+ info.max_texture_width, info.max_texture_height);
+ }
return true;
}
-bool Graphics::changeVideoMode(int w, int h, int bpp, bool fs, bool hwaccel)
+bool Graphics::changeVideoMode(int w, int h, bool fs)
{
// Just return success if we're already in this mode
if (mWidth == w &&
mHeight == h &&
- mBpp == bpp &&
- mFullscreen == fs &&
- mHWAccel == hwaccel)
+ mFullscreen == fs)
return true;
_endDraw();
- bool success = setVideoMode(w, h, bpp, fs, hwaccel);
+ bool success = setVideoMode(w, h, fs);
// If it didn't work, try to restore the previous mode. If that doesn't
// work either, we're in big trouble and bail out.
if (!success) {
- if (!setVideoMode(mWidth, mHeight, mBpp, mFullscreen, mHWAccel)) {
+ if (!setVideoMode(mWidth, mHeight, mFullscreen)) {
logger->error(_("Failed to change video mode and couldn't "
"switch back to the previous mode!"));
}
@@ -135,6 +125,12 @@ bool Graphics::changeVideoMode(int w, int h, int bpp, bool fs, bool hwaccel)
return success;
}
+void Graphics::videoResized(int w, int h)
+{
+ mWidth = w;
+ mHeight = h;
+}
+
int Graphics::getWidth() const
{
return mWidth;
@@ -147,10 +143,10 @@ int Graphics::getHeight() const
bool Graphics::drawImage(Image *image, int x, int y)
{
- if (image)
- return drawImage(image, 0, 0, x, y, image->mBounds.w, image->mBounds.h);
- else
+ if (!image)
return false;
+
+ return drawImage(image, 0, 0, x, y, image->mBounds.w, image->mBounds.h);
}
bool Graphics::drawRescaledImage(Image *image, int srcX, int srcY,
@@ -160,15 +156,7 @@ bool Graphics::drawRescaledImage(Image *image, int srcX, int srcY,
bool useColor)
{
// Check that preconditions for blitting are met.
- if (!mTarget || !image)
- return false;
- if (!image->mSDLSurface)
- return false;
-
- Image *tmpImage = image->SDLgetScaledImage(desiredWidth, desiredHeight);
- bool returnValue = false;
-
- if (!tmpImage)
+ if (!mTarget || !image || !image->mTexture)
return false;
dstX += mClipStack.top().xOffset;
@@ -183,76 +171,35 @@ bool Graphics::drawRescaledImage(Image *image, int srcX, int srcY,
srcRect.x = srcX; srcRect.y = srcY;
srcRect.w = width;
srcRect.h = height;
+ dstRect.w = desiredWidth;
+ dstRect.h = desiredHeight;
- returnValue = !(SDL_BlitSurface(tmpImage->mSDLSurface, &srcRect,
- mTarget, &dstRect) < 0);
-
- tmpImage->decRef(Resource::DeleteImmediately);
-
- return returnValue;
+ return !(SDL_RenderCopy(mRenderer, image->mTexture, &srcRect, &dstRect) < 0);
}
bool Graphics::drawImage(Image *image, int srcX, int srcY, int dstX, int dstY,
- int width, int height, bool)
+ int width, int height, bool useColor)
{
- // Check that preconditions for blitting are met.
- if (!mTarget || !image || !image->mSDLSurface)
+ if (!image)
return false;
- dstX += mClipStack.top().xOffset;
- dstY += mClipStack.top().yOffset;
-
- srcX += image->mBounds.x;
- srcY += image->mBounds.y;
-
- SDL_Rect dstRect;
- SDL_Rect srcRect;
- dstRect.x = dstX; dstRect.y = dstY;
- srcRect.x = srcX; srcRect.y = srcY;
- srcRect.w = width;
- srcRect.h = height;
-
- if (mBlitMode == BLIT_NORMAL)
- return !(SDL_BlitSurface(image->mSDLSurface, &srcRect, mTarget, &dstRect) < 0);
- else
- return !(SDL_gfxBlitRGBA(image->mSDLSurface, &srcRect, mTarget, &dstRect) < 0);
+ return drawRescaledImage(image,
+ srcX, srcY,
+ dstX, dstY,
+ width, height,
+ width, height, useColor);
}
void Graphics::drawImagePattern(Image *image, int x, int y, int w, int h)
{
// Check that preconditions for blitting are met.
- if (!mTarget || !image)
- return;
- if (!image->mSDLSurface)
+ if (!image)
return;
const int iw = image->getWidth();
const int ih = image->getHeight();
- if (iw == 0 || ih == 0)
- return;
-
- for (int py = 0; py < h; py += ih) // Y position on pattern plane
- {
- int dh = (py + ih >= h) ? h - py : ih;
- int srcY = image->mBounds.y;
- int dstY = y + py + mClipStack.top().yOffset;
-
- for (int px = 0; px < w; px += iw) // X position on pattern plane
- {
- int dw = (px + iw >= w) ? w - px : iw;
- int srcX = image->mBounds.x;
- int dstX = x + px + mClipStack.top().xOffset;
-
- SDL_Rect dstRect;
- SDL_Rect srcRect;
- dstRect.x = dstX; dstRect.y = dstY;
- srcRect.x = srcX; srcRect.y = srcY;
- srcRect.w = dw; srcRect.h = dh;
-
- SDL_BlitSurface(image->mSDLSurface, &srcRect, mTarget, &dstRect);
- }
- }
+ drawRescaledImagePattern(image, x, y, w, h, iw, ih);
}
void Graphics::drawRescaledImagePattern(Image *image,
@@ -261,50 +208,34 @@ void Graphics::drawRescaledImagePattern(Image *image,
int scaledWidth, int scaledHeight)
{
// Check that preconditions for blitting are met.
- if (!mTarget || !image)
- return;
- if (!image->mSDLSurface)
+ if (!mTarget || !image || !image->mTexture)
return;
if (scaledHeight == 0 || scaledWidth == 0)
return;
- Image *tmpImage = image->SDLgetScaledImage(scaledWidth, scaledHeight);
- if (!tmpImage)
- return;
-
- const int iw = tmpImage->getWidth();
- const int ih = tmpImage->getHeight();
-
- if (iw == 0 || ih == 0)
- {
- tmpImage->decRef(Resource::DeleteImmediately);
- return;
- }
-
- for (int py = 0; py < h; py += ih) // Y position on pattern plane
+ for (int py = 0; py < h; py += scaledHeight) // Y position on pattern plane
{
- int dh = (py + ih >= h) ? h - py : ih;
- int srcY = tmpImage->mBounds.y;
+ int dh = (py + scaledHeight >= h) ? h - py : scaledHeight;
+ int srcY = image->mBounds.y;
int dstY = y + py + mClipStack.top().yOffset;
- for (int px = 0; px < w; px += iw) // X position on pattern plane
+ for (int px = 0; px < w; px += scaledWidth) // X position on pattern plane
{
- int dw = (px + iw >= w) ? w - px : iw;
- int srcX = tmpImage->mBounds.x;
+ int dw = (px + scaledWidth >= w) ? w - px : scaledWidth;
+ int srcX = image->mBounds.x;
int dstX = x + px + mClipStack.top().xOffset;
SDL_Rect dstRect;
SDL_Rect srcRect;
dstRect.x = dstX; dstRect.y = dstY;
+ dstRect.w = dw; dstRect.h = dh;
srcRect.x = srcX; srcRect.y = srcY;
srcRect.w = dw; srcRect.h = dh;
- SDL_BlitSurface(tmpImage->mSDLSurface, &srcRect, mTarget, &dstRect);
+ SDL_RenderCopy(mRenderer, image->mTexture, &srcRect, &dstRect);
}
}
-
- tmpImage->decRef(Resource::DeleteImmediately);
}
void Graphics::drawImageRect(int x, int y, int w, int h,
@@ -361,7 +292,7 @@ void Graphics::drawImageRect(int x, int y, int w, int h,
void Graphics::updateScreen()
{
- SDL_Flip(mTarget);
+ SDL_RenderPresent(mRenderer);
}
SDL_Surface *Graphics::getScreenshot()
@@ -377,10 +308,140 @@ SDL_Surface *Graphics::getScreenshot()
#endif
int amask = 0x00000000;
- SDL_Surface *screenshot = SDL_CreateRGBSurface(SDL_SWSURFACE, mTarget->w,
- mTarget->h, 24, rmask, gmask, bmask, amask);
-
- SDL_BlitSurface(mTarget, NULL, screenshot, NULL);
+ SDL_Surface *screenshot = SDL_CreateRGBSurface(0, mWidth,
+ mHeight, 24, rmask, gmask, bmask, amask);
+ SDL_RenderReadPixels(mRenderer, NULL, SDL_PIXELFORMAT_RGB888, screenshot->pixels, screenshot->pitch);
return screenshot;
}
+
+bool Graphics::pushClipArea(gcn::Rectangle area)
+{
+ bool result = gcn::Graphics::pushClipArea(area);
+ updateSDLClipRect();
+ return result;
+}
+
+void Graphics::popClipArea()
+{
+ gcn::Graphics::popClipArea();
+ updateSDLClipRect();
+}
+
+void Graphics::updateSDLClipRect()
+{
+ if (mClipStack.empty())
+ {
+ SDL_RenderSetClipRect(mRenderer, NULL);
+ return;
+ }
+
+ const gcn::ClipRectangle &carea = mClipStack.top();
+ SDL_Rect rect;
+ rect.x = carea.x;
+ rect.y = carea.y;
+ rect.w = carea.width;
+ rect.h = carea.height;
+
+ SDL_RenderSetClipRect(mRenderer, &rect);
+}
+
+void Graphics::drawPoint(int x, int y)
+{
+ if (mClipStack.empty())
+ {
+ throw GCN_EXCEPTION("Clip stack is empty, perhaps you called a draw funtion outside of _beginDraw() and _endDraw()?");
+ }
+
+ const gcn::ClipRectangle &top = mClipStack.top();
+
+ x += top.xOffset;
+ y += top.yOffset;
+
+ if (!top.isPointInRect(x, y))
+ return;
+
+ SDL_SetRenderDrawColor(mRenderer,
+ (Uint8)(mColor.r),
+ (Uint8)(mColor.g),
+ (Uint8)(mColor.b),
+ (Uint8)(mColor.a));
+ SDL_RenderDrawPoint(mRenderer, x, y);
+}
+
+void Graphics::drawLine(int x1, int y1, int x2, int y2)
+{
+ if (mClipStack.empty())
+ {
+ throw GCN_EXCEPTION("Clip stack is empty, perhaps you called a draw funtion outside of _beginDraw() and _endDraw()?");
+ }
+
+ const gcn::ClipRectangle &top = mClipStack.top();
+
+ x1 += top.xOffset;
+ y1 += top.yOffset;
+ x2 += top.xOffset;
+ y2 += top.yOffset;
+
+ SDL_SetRenderDrawColor(mRenderer,
+ (Uint8)(mColor.r),
+ (Uint8)(mColor.g),
+ (Uint8)(mColor.b),
+ (Uint8)(mColor.a));
+ SDL_RenderDrawLine(mRenderer, x1, y1, x2, y2);
+}
+
+void Graphics::drawRectangle(const gcn::Rectangle &rectangle)
+{
+ if (mClipStack.empty())
+ {
+ throw GCN_EXCEPTION("Clip stack is empty, perhaps you called a draw funtion outside of _beginDraw() and _endDraw()?");
+ }
+
+ const gcn::ClipRectangle &top = mClipStack.top();
+
+ SDL_Rect rect;
+ rect.x = rectangle.x + top.xOffset;
+ rect.y = rectangle.y + top.yOffset;
+ rect.w = rectangle.width;
+ rect.h = rectangle.height;
+
+ SDL_SetRenderDrawColor(mRenderer,
+ (Uint8)(mColor.r),
+ (Uint8)(mColor.g),
+ (Uint8)(mColor.b),
+ (Uint8)(mColor.a));
+ SDL_RenderDrawRect(mRenderer, &rect);
+}
+
+void Graphics::fillRectangle(const gcn::Rectangle &rectangle)
+{
+ if (mClipStack.empty())
+ {
+ throw GCN_EXCEPTION("Clip stack is empty, perhaps you called a draw funtion outside of _beginDraw() and _endDraw()?");
+ }
+
+ const gcn::ClipRectangle &top = mClipStack.top();
+
+ gcn::Rectangle area = rectangle;
+ area.x += top.xOffset;
+ area.y += top.yOffset;
+
+ if(!area.isIntersecting(top))
+ {
+ return;
+ }
+
+ SDL_Rect rect;
+ rect.x = area.x;
+ rect.y = area.y;
+ rect.w = area.width;
+ rect.h = area.height;
+
+ SDL_SetRenderDrawColor(mRenderer,
+ (Uint8)(mColor.r),
+ (Uint8)(mColor.g),
+ (Uint8)(mColor.b),
+ (Uint8)(mColor.a));
+ SDL_RenderFillRect(mRenderer, &rect);
+}
diff --git a/src/graphics.h b/src/graphics.h
index dc3d249e..813d4200 100644
--- a/src/graphics.h
+++ b/src/graphics.h
@@ -22,13 +22,14 @@
#ifndef GRAPHICS_H
#define GRAPHICS_H
-#include <guichan/sdl/sdlgraphics.hpp>
+#include <SDL.h>
+
+#include <guichan/color.hpp>
+#include <guichan/graphics.hpp>
class Image;
class ImageRect;
-struct SDL_Surface;
-
static const int defaultScreenWidth = 800;
static const int defaultScreenHeight = 600;
@@ -49,8 +50,9 @@ static const int defaultScreenHeight = 600;
* Sections 0, 2, 6 and 8 will remain as is. 1, 3, 4, 5 and 7 will be
* repeated to fit the size of the widget.
*/
-struct ImageRect
+class ImageRect
{
+public:
enum ImagePosition
{
UPPER_LEFT = 0,
@@ -70,28 +72,36 @@ struct ImageRect
/**
* A central point of control for graphics.
*/
-class Graphics : public gcn::SDLGraphics
+class Graphics : public gcn::Graphics
{
public:
- enum BlitMode {
- BLIT_NORMAL = 0,
- BLIT_GFX
- };
-
- Graphics();
+ Graphics() = default;
virtual ~Graphics();
/**
+ * Sets the target SDL_Window to draw to. This funtion also pushes a
+ * clip areas corresponding to the dimension of the target.
+ *
+ * @param target the target to draw to.
+ */
+ virtual void setTarget(SDL_Window *target);
+
+ SDL_Window *getTarget() const { return mTarget; }
+ SDL_Renderer *getRenderer() const { return mRenderer; }
+
+ /**
* Try to create a window with the given settings.
*/
- virtual bool setVideoMode(int w, int h, int bpp, bool fs, bool hwaccel);
+ virtual bool setVideoMode(int w, int h, bool fs);
/**
* Change the video mode. Can be used for switching to full screen,
* changing resolution or adapting after window resize.
*/
- bool changeVideoMode(int w, int h, int bpp, bool fs, bool hwaccel);
+ bool changeVideoMode(int w, int h, bool fs);
+
+ virtual void videoResized(int w, int h);
/**
* Blits an image onto the screen.
@@ -176,12 +186,6 @@ class Graphics : public gcn::SDLGraphics
drawImageRect(area.x, area.y, area.width, area.height, imgRect);
}
- void setBlitMode(BlitMode mode)
- { mBlitMode = mode; }
-
- BlitMode getBlitMode()
- { return mBlitMode; }
-
/**
* Updates the screen. This is done by either copying the buffer to the
* screen or swapping pages.
@@ -199,36 +203,57 @@ class Graphics : public gcn::SDLGraphics
int getHeight() const;
/**
- * Returns the amount of bits per pixel that was requested (not the
- * actual amount that's currently active).
- */
- int getBpp() const { return mBpp; }
-
- /**
* Returns whether we're in a full screen mode.
*/
bool getFullscreen() const { return mFullscreen; }
/**
- * Returns whether old-fashioned SDL-based hardware acceleration was
- * requested (not whether it's currently active).
- */
- bool getHWAccel() const { return mHWAccel; }
-
- /**
* Takes a screenshot and returns it as SDL surface.
*/
virtual SDL_Surface *getScreenshot();
gcn::Font *getFont() const { return mFont; }
+ virtual bool pushClipArea(gcn::Rectangle area);
+
+ virtual void popClipArea();
+
+ virtual void drawImage(const gcn::Image *image,
+ int srcX,
+ int srcY,
+ int dstX,
+ int dstY,
+ int width,
+ int height) {} // not used
+
+ virtual void drawPoint(int x, int y);
+
+ virtual void drawLine(int x1, int y1, int x2, int y2);
+
+ virtual void drawRectangle(const gcn::Rectangle &rectangle);
+
+ virtual void fillRectangle(const gcn::Rectangle &rectangle);
+
+ virtual void setColor(const gcn::Color &color)
+ {
+ mColor = color;
+ }
+
+ virtual const gcn::Color &getColor() const
+ {
+ return mColor;
+ }
+
protected:
- int mWidth;
- int mHeight;
- int mBpp;
- bool mFullscreen;
- bool mHWAccel;
- BlitMode mBlitMode;
+ void updateSDLClipRect();
+
+ int mWidth = 0;
+ int mHeight = 0;
+ bool mFullscreen = false;
+ gcn::Color mColor;
+
+ SDL_Window *mTarget = nullptr;
+ SDL_Renderer *mRenderer = nullptr;
};
extern Graphics *graphics;
diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp
index 019d3002..64509e21 100644
--- a/src/gui/gui.cpp
+++ b/src/gui/gui.cpp
@@ -26,6 +26,7 @@
#include "gui/sdlinput.h"
#include "gui/truetypefont.h"
+#include "gui/widgets/textfield.h"
#include "gui/widgets/window.h"
#include "gui/widgets/windowcontainer.h"
@@ -190,6 +191,12 @@ void Gui::logic()
Palette::advanceGradients();
gcn::Gui::logic();
+
+ while (!guiInput->isTextQueueEmpty())
+ {
+ TextInput textInput = guiInput->dequeueTextInput();
+ handleTextInput(textInput);
+ }
}
void Gui::draw()
@@ -264,3 +271,14 @@ void Gui::handleMouseMoved(const gcn::MouseInput &mouseInput)
gcn::Gui::handleMouseMoved(mouseInput);
mMouseInactivityTimer = 0;
}
+
+void Gui::handleTextInput(const TextInput &textInput)
+{
+ if (auto focused = mFocusHandler->getFocused())
+ {
+ if (auto textField = dynamic_cast<TextField*>(focused))
+ {
+ textField->textInput(textInput);
+ }
+ }
+}
diff --git a/src/gui/gui.h b/src/gui/gui.h
index 006987da..998b6ec8 100644
--- a/src/gui/gui.h
+++ b/src/gui/gui.h
@@ -26,6 +26,7 @@
#include <guichan/gui.hpp>
+class TextInput;
class Graphics;
class GuiConfigListener;
class ImageSet;
@@ -114,6 +115,7 @@ class Gui : public gcn::Gui
protected:
void handleMouseMoved(const gcn::MouseInput &mouseInput);
+ void handleTextInput(const TextInput &textInput);
private:
GuiConfigListener *mConfigListener;
diff --git a/src/gui/sdlinput.cpp b/src/gui/sdlinput.cpp
index 4ccb7580..6eb58a36 100644
--- a/src/gui/sdlinput.cpp
+++ b/src/gui/sdlinput.cpp
@@ -106,6 +106,23 @@ gcn::MouseInput SDLInput::dequeueMouseInput()
return mouseInput;
}
+bool SDLInput::isTextQueueEmpty() const
+{
+ return mTextInputQueue.empty();
+}
+
+TextInput SDLInput::dequeueTextInput()
+{
+ if (mTextInputQueue.empty())
+ {
+ throw GCN_EXCEPTION("The queue is empty.");
+ }
+
+ TextInput textInput(mTextInputQueue.front());
+ mTextInputQueue.pop();
+ return textInput;
+}
+
void SDLInput::pushInput(SDL_Event event)
{
gcn::KeyInput keyInput;
@@ -119,8 +136,8 @@ void SDLInput::pushInput(SDL_Event event)
keyInput.setShiftPressed(event.key.keysym.mod & KMOD_SHIFT);
keyInput.setControlPressed(event.key.keysym.mod & KMOD_CTRL);
keyInput.setAltPressed(event.key.keysym.mod & KMOD_ALT);
- keyInput.setMetaPressed(event.key.keysym.mod & KMOD_META);
- keyInput.setNumericPad(event.key.keysym.sym >= SDLK_KP0
+ keyInput.setMetaPressed(event.key.keysym.mod & KMOD_GUI);
+ keyInput.setNumericPad(event.key.keysym.sym >= SDLK_KP_0
&& event.key.keysym.sym <= SDLK_KP_EQUALS);
mKeyInputQueue.push(keyInput);
@@ -132,8 +149,8 @@ void SDLInput::pushInput(SDL_Event event)
keyInput.setShiftPressed(event.key.keysym.mod & KMOD_SHIFT);
keyInput.setControlPressed(event.key.keysym.mod & KMOD_CTRL);
keyInput.setAltPressed(event.key.keysym.mod & KMOD_ALT);
- keyInput.setMetaPressed(event.key.keysym.mod & KMOD_META);
- keyInput.setNumericPad(event.key.keysym.sym >= SDLK_KP0
+ keyInput.setMetaPressed(event.key.keysym.mod & KMOD_GUI);
+ keyInput.setNumericPad(event.key.keysym.sym >= SDLK_KP_0
&& event.key.keysym.sym <= SDLK_KP_EQUALS);
mKeyInputQueue.push(keyInput);
@@ -144,19 +161,7 @@ void SDLInput::pushInput(SDL_Event event)
mouseInput.setX(event.button.x);
mouseInput.setY(event.button.y);
mouseInput.setButton(convertMouseButton(event.button.button));
-
- if (event.button.button == SDL_BUTTON_WHEELDOWN)
- {
- mouseInput.setType(gcn::MouseInput::WHEEL_MOVED_DOWN);
- }
- else if (event.button.button == SDL_BUTTON_WHEELUP)
- {
- mouseInput.setType(gcn::MouseInput::WHEEL_MOVED_UP);
- }
- else
- {
- mouseInput.setType(gcn::MouseInput::PRESSED);
- }
+ mouseInput.setType(gcn::MouseInput::PRESSED);
mouseInput.setTimeStamp(SDL_GetTicks());
mMouseInputQueue.push(mouseInput);
break;
@@ -180,6 +185,35 @@ void SDLInput::pushInput(SDL_Event event)
mMouseInputQueue.push(mouseInput);
break;
+ case SDL_MOUSEWHEEL:
+ if (event.wheel.y) {
+#if SDL_VERSION_ATLEAST(2, 26, 0)
+ mouseInput.setX(event.wheel.mouseX);
+ mouseInput.setY(event.wheel.mouseY);
+#else
+ int x, y;
+ SDL_GetMouseState(&x, &y);
+ mouseInput.setX(x);
+ mouseInput.setY(y);
+#endif
+ mouseInput.setButton(gcn::MouseInput::EMPTY);
+ mouseInput.setType(event.wheel.y > 0 ? gcn::MouseInput::WHEEL_MOVED_UP
+ : gcn::MouseInput::WHEEL_MOVED_DOWN);
+ mouseInput.setTimeStamp(SDL_GetTicks());
+ mMouseInputQueue.push(mouseInput);
+ }
+ break;
+
+ case SDL_TEXTINPUT:
+ mTextInputQueue.emplace(event.text.text);
+ break;
+
+ // TODO_SDL2: This is now a window event
+ // case SDL_WINDOWEVENT:
+ // switch (event.window.event) {
+ // }
+ // break;
+#if 0
case SDL_ACTIVEEVENT:
/*
* This occurs when the mouse leaves the window and the Gui-chan
@@ -206,7 +240,7 @@ void SDLInput::pushInput(SDL_Event event)
mMouseInWindow = true;
}
break;
-
+#endif
} // end switch
}
@@ -228,9 +262,9 @@ int SDLInput::convertMouseButton(int button)
int SDLInput::convertKeyCharacter(SDL_Event event)
{
- SDL_keysym keysym = event.key.keysym;
+ SDL_Keysym keysym = event.key.keysym;
- int value = keysym.unicode;
+ int value = keysym.sym;
switch (keysym.sym)
{
@@ -262,16 +296,10 @@ int SDLInput::convertKeyCharacter(SDL_Event event)
value = Key::PAUSE;
break;
case SDLK_SPACE:
- // Special characters like ~ (tilde) ends up
- // with the keysym.sym SDLK_SPACE which
- // without this check would be lost. The check
- // is only valid on key down events in SDL.
- if (event.type == SDL_KEYUP || keysym.unicode == ' ')
- {
- value = Key::SPACE;
- }
+ value = Key::SPACE;
break;
case SDLK_ESCAPE:
+ case SDLK_AC_BACK:
value = Key::ESCAPE;
break;
case SDLK_DELETE:
@@ -289,7 +317,7 @@ int SDLInput::convertKeyCharacter(SDL_Event event)
case SDLK_PAGEUP:
value = Key::PAGE_UP;
break;
- case SDLK_PRINT:
+ case SDLK_PRINTSCREEN:
value = Key::PRINT_SCREEN;
break;
case SDLK_PAGEDOWN:
@@ -340,27 +368,21 @@ int SDLInput::convertKeyCharacter(SDL_Event event)
case SDLK_F15:
value = Key::F15;
break;
- case SDLK_NUMLOCK:
+ case SDLK_NUMLOCKCLEAR:
value = Key::NUM_LOCK;
break;
case SDLK_CAPSLOCK:
value = Key::CAPS_LOCK;
break;
- case SDLK_SCROLLOCK:
+ case SDLK_SCROLLLOCK:
value = Key::SCROLL_LOCK;
break;
- case SDLK_RMETA:
+ case SDLK_RGUI:
value = Key::RIGHT_META;
break;
- case SDLK_LMETA:
+ case SDLK_LGUI:
value = Key::LEFT_META;
break;
- case SDLK_LSUPER:
- value = Key::LEFT_SUPER;
- break;
- case SDLK_RSUPER:
- value = Key::RIGHT_SUPER;
- break;
case SDLK_MODE:
value = Key::ALT_GR;
break;
@@ -391,34 +413,34 @@ int SDLInput::convertKeyCharacter(SDL_Event event)
{
switch (keysym.sym)
{
- case SDLK_KP0:
+ case SDLK_KP_0:
value = Key::INSERT;
break;
- case SDLK_KP1:
+ case SDLK_KP_1:
value = Key::END;
break;
- case SDLK_KP2:
+ case SDLK_KP_2:
value = Key::DOWN;
break;
- case SDLK_KP3:
+ case SDLK_KP_3:
value = Key::PAGE_DOWN;
break;
- case SDLK_KP4:
+ case SDLK_KP_4:
value = Key::LEFT;
break;
- case SDLK_KP5:
+ case SDLK_KP_5:
value = 0;
break;
- case SDLK_KP6:
+ case SDLK_KP_6:
value = Key::RIGHT;
break;
- case SDLK_KP7:
+ case SDLK_KP_7:
value = Key::HOME;
break;
- case SDLK_KP8:
+ case SDLK_KP_8:
value = Key::UP;
break;
- case SDLK_KP9:
+ case SDLK_KP_9:
value = Key::PAGE_UP;
break;
default:
diff --git a/src/gui/sdlinput.h b/src/gui/sdlinput.h
index 90f70df3..09bb788e 100644
--- a/src/gui/sdlinput.h
+++ b/src/gui/sdlinput.h
@@ -61,13 +61,15 @@
#include <queue>
-#include <SDL/SDL.h>
+#include <SDL.h>
#include <guichan/input.hpp>
#include <guichan/keyinput.hpp>
#include <guichan/mouseinput.hpp>
#include <guichan/platform.hpp>
+#include <string>
+
namespace Key
{
enum
@@ -122,6 +124,19 @@ namespace Key
};
}
+class TextInput
+{
+public:
+ TextInput(const char *text)
+ : mText(text)
+ {}
+
+ const std::string &getText() const { return mText; }
+
+private:
+ std::string mText;
+};
+
/**
* SDL implementation of Input.
*/
@@ -160,6 +175,10 @@ public:
virtual gcn::MouseInput dequeueMouseInput();
+ bool isTextQueueEmpty() const;
+
+ TextInput dequeueTextInput();
+
protected:
/**
* Converts a mouse button from SDL to a Guichan mouse button
@@ -181,6 +200,7 @@ protected:
std::queue<gcn::KeyInput> mKeyInputQueue;
std::queue<gcn::MouseInput> mMouseInputQueue;
+ std::queue<TextInput> mTextInputQueue;
bool mMouseDown;
bool mMouseInWindow;
diff --git a/src/gui/setup_keyboard.cpp b/src/gui/setup_keyboard.cpp
index 5e29519b..b66ba3aa 100644
--- a/src/gui/setup_keyboard.cpp
+++ b/src/gui/setup_keyboard.cpp
@@ -178,8 +178,8 @@ void Setup_Keyboard::refreshAssignedKey(int index)
caption = keyboard.getKeyCaption(index) + ": ";
else
{
- char *temp = SDL_GetKeyName(
- (SDLKey) keyboard.getKeyValue(index));
+ const char *temp = SDL_GetKeyName(
+ (SDL_Scancode) keyboard.getKeyValue(index));
caption = strprintf("%-25s",
(keyboard.getKeyCaption(index) + ": ").c_str()) + toString(temp);
diff --git a/src/gui/setup_video.cpp b/src/gui/setup_video.cpp
index c4fe60a1..c9d1dbc9 100644
--- a/src/gui/setup_video.cpp
+++ b/src/gui/setup_video.cpp
@@ -26,7 +26,6 @@
#include "game.h"
#include "graphics.h"
#include "localplayer.h"
-#include "log.h"
#include "main.h"
#include "particle.h"
@@ -91,26 +90,21 @@ class ModeListModel : public gcn::ListModel
ModeListModel::ModeListModel()
{
/* Get available fullscreen/hardware modes */
- SDL_Rect **modes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_HWSURFACE);
-
- /* Check which modes are available */
- if (modes == (SDL_Rect **)0)
- logger->log("No modes available");
- else if (modes == (SDL_Rect **)-1)
- logger->log("All resolutions available");
- else
+ const int numModes = SDL_GetNumDisplayModes(0);
+ for (int i = 0; i < numModes; i++)
{
- for (int i = 0; modes[i]; ++i)
- {
- const int width = modes[i]->w;
- const int height = modes[i]->h;
+ SDL_DisplayMode mode;
+ if (SDL_GetDisplayMode(0, i, &mode) != 0)
+ continue;
- // Skip the unreasonably small modes
- if (width < 640 || height < 480)
- continue;
+ // Skip the unreasonably small modes
+ if (mode.w < 640 || mode.h < 480)
+ continue;
- mVideoModes.push_back(toString(width) + "x" + toString(height));
- }
+ // TODO_SDL2: Modes now dinstinguish between pixel format and refresh rate as well
+ // TODO_SDL2: Fullscreen mode needs display selection
+
+ mVideoModes.push_back(toString(mode.w) + "x" + toString(mode.h));
}
}
@@ -326,9 +320,7 @@ void Setup_Video::apply()
{
if (!graphics->changeVideoMode(screenWidth,
screenHeight,
- graphics->getBpp(),
- fullscreen,
- graphics->getHWAccel()))
+ fullscreen))
{
std::stringstream errorMessage;
if (fullscreen)
diff --git a/src/gui/truetypefont.cpp b/src/gui/truetypefont.cpp
index 620ba191..443adaa5 100644
--- a/src/gui/truetypefont.cpp
+++ b/src/gui/truetypefont.cpp
@@ -28,6 +28,7 @@
#include "utils/stringutils.h"
+#include <guichan/color.hpp>
#include <guichan/exception.hpp>
const unsigned int CACHE_SIZE = 256;
@@ -53,9 +54,10 @@ class TextChunk
void generate(TTF_Font *font)
{
SDL_Color sdlCol;
- sdlCol.b = color.b;
sdlCol.r = color.r;
sdlCol.g = color.g;
+ sdlCol.b = color.b;
+ sdlCol.a = color.a;
const char *str = getSafeUtf8String(text);
SDL_Surface *surface = TTF_RenderUTF8_Blended(
diff --git a/src/gui/viewport.cpp b/src/gui/viewport.cpp
index e06c5f8d..b4ad1b1d 100644
--- a/src/gui/viewport.cpp
+++ b/src/gui/viewport.cpp
@@ -310,7 +310,7 @@ void Viewport::_followMouse()
if (mPlayerFollowMouse && button & SDL_BUTTON(1))
{
// We create a mouse event and send it to mouseDragged.
- Uint8 *keys = SDL_GetKeyState(NULL);
+ const Uint8 *keys = SDL_GetKeyboardState(NULL);
gcn::MouseEvent mouseEvent(NULL,
(keys[SDLK_LSHIFT] || keys[SDLK_RSHIFT]),
false,
diff --git a/src/gui/widgets/desktop.cpp b/src/gui/widgets/desktop.cpp
index ce609891..07d1d887 100644
--- a/src/gui/widgets/desktop.cpp
+++ b/src/gui/widgets/desktop.cpp
@@ -86,14 +86,9 @@ void Desktop::draw(gcn::Graphics *graphics)
if (mWallpaper)
{
- if (!Image::useOpenGL())
- g->drawImage(mWallpaper,
- (getWidth() - mWallpaper->getWidth()) / 2,
- (getHeight() - mWallpaper->getHeight()) / 2);
- else
- g->drawRescaledImage(mWallpaper, 0, 0, 0, 0,
- mWallpaper->getWidth(), mWallpaper->getHeight(),
- getWidth(), getHeight(), false);
+ g->drawRescaledImage(mWallpaper, 0, 0, 0, 0,
+ mWallpaper->getWidth(), mWallpaper->getHeight(),
+ getWidth(), getHeight(), false);
}
// Draw a thin border under the application version...
@@ -125,19 +120,6 @@ void Desktop::setBestFittingWallpaper()
mWallpaper->decRef(Resource::DeleteImmediately);
mWallpaper = wallpaper;
-
- // In software mode we try to prescale the image for performance
- if (!wallpaper->useOpenGL() &&
- (wallpaper->getWidth() != width ||
- wallpaper->getHeight() != height))
- {
- if (Image *prescaled = wallpaper->SDLgetScaledImage(width, height))
- {
- // Make sure the original can be freed
- wallpaper->decRef();
- mWallpaper = prescaled;
- }
- }
}
else
{
diff --git a/src/gui/widgets/emoteshortcutcontainer.cpp b/src/gui/widgets/emoteshortcutcontainer.cpp
index 3105a762..cdb2d3c4 100644
--- a/src/gui/widgets/emoteshortcutcontainer.cpp
+++ b/src/gui/widgets/emoteshortcutcontainer.cpp
@@ -92,7 +92,7 @@ void EmoteShortcutContainer::draw(gcn::Graphics *graphics)
// Draw emote keyboard shortcut.
const char *key = SDL_GetKeyName(
- (SDLKey) keyboard.getKeyValue(keyboard.KEY_EMOTE_1 + i));
+ (SDL_Scancode) keyboard.getKeyValue(keyboard.KEY_EMOTE_1 + i));
graphics->setColor(Theme::getThemeColor(Theme::TEXT));
g->drawText(key, emoteX + 2, emoteY + 2, gcn::Graphics::LEFT);
diff --git a/src/gui/widgets/itemshortcutcontainer.cpp b/src/gui/widgets/itemshortcutcontainer.cpp
index f1690d43..396de3bd 100644
--- a/src/gui/widgets/itemshortcutcontainer.cpp
+++ b/src/gui/widgets/itemshortcutcontainer.cpp
@@ -86,7 +86,7 @@ void ItemShortcutContainer::draw(gcn::Graphics *graphics)
// Draw item keyboard shortcut.
const char *key = SDL_GetKeyName(
- (SDLKey) keyboard.getKeyValue(keyboard.KEY_SHORTCUT_1 + i));
+ (SDL_Scancode) keyboard.getKeyValue(keyboard.KEY_SHORTCUT_1 + i));
graphics->setColor(Theme::getThemeColor(Theme::TEXT));
g->drawText(key, itemX + 2, itemY + 2, gcn::Graphics::LEFT);
diff --git a/src/gui/widgets/textfield.cpp b/src/gui/widgets/textfield.cpp
index e7c279b2..c4c00ae4 100644
--- a/src/gui/widgets/textfield.cpp
+++ b/src/gui/widgets/textfield.cpp
@@ -36,6 +36,8 @@
#include <guichan/font.hpp>
+#include <SDL.h>
+
#undef DELETE //Win32 compatibility hack
int TextField::instances = 0;
@@ -162,33 +164,7 @@ int TextField::getValue() const
void TextField::keyPressed(gcn::KeyEvent &keyEvent)
{
- int val = keyEvent.getKey().getValue();
-
- if (val >= 32)
- {
- int l;
- if (val < 128) l = 1; // 0xxxxxxx
- else if (val < 0x800) l = 2; // 110xxxxx 10xxxxxx
- else if (val < 0x10000) l = 3; // 1110xxxx 10xxxxxx 10xxxxxx
- else l = 4; // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
-
- char buf[4];
- for (int i = 0; i < l; ++i)
- {
- buf[i] = val >> (6 * (l - i - 1));
- if (i > 0) buf[i] = (buf[i] & 63) | 128;
- }
-
- if (l > 1) buf[0] |= 255 << (8 - l);
-
- mText.insert(mCaretPosition, std::string(buf, buf + l));
- mCaretPosition += l;
- }
-
- /* In UTF-8, 10xxxxxx is only used for inner parts of characters. So skip
- them when processing key presses. */
-
- switch (val)
+ switch (keyEvent.getKey().getValue())
{
case Key::LEFT:
{
@@ -302,8 +278,9 @@ void TextField::keyPressed(gcn::KeyEvent &keyEvent)
return;
break;
- case 22: // Control code 22, SYNCHRONOUS IDLE, sent on Ctrl+v
- handlePaste();
+ case SDLK_v:
+ if (keyEvent.isControlPressed())
+ handlePaste();
break;
}
@@ -311,6 +288,12 @@ void TextField::keyPressed(gcn::KeyEvent &keyEvent)
fixScroll();
}
+void TextField::textInput(const TextInput &textInput)
+{
+ mText.insert(mCaretPosition, textInput.getText());
+ mCaretPosition += textInput.getText().length();
+}
+
void TextField::autoComplete()
{
if (mAutoComplete && mText.size() > 0)
@@ -383,7 +366,7 @@ void TextField::handlePaste()
std::string text = getText();
std::string::size_type caretPos = getCaretPosition();
- if (RetrieveBuffer(text, caretPos)) {
+ if (insertFromClipboard(text, caretPos)) {
setText(text);
setCaretPosition(caretPos);
}
diff --git a/src/gui/widgets/textfield.h b/src/gui/widgets/textfield.h
index 94cada41..bf60cbc3 100644
--- a/src/gui/widgets/textfield.h
+++ b/src/gui/widgets/textfield.h
@@ -26,6 +26,7 @@
#include <vector>
+class TextInput;
class ImageRect;
class TextField;
@@ -116,6 +117,11 @@ class TextField : public gcn::TextField
void keyPressed(gcn::KeyEvent &keyEvent);
/**
+ * Handle text input (should possibly be new event in Guichan).
+ */
+ void textInput(const TextInput &textInput);
+
+ /**
* Set the minimum value for a range
*/
void setMinimum(int min) { mMinimum = min; }
diff --git a/src/gui/windowmenu.cpp b/src/gui/windowmenu.cpp
index 12624bf1..9a53479e 100644
--- a/src/gui/windowmenu.cpp
+++ b/src/gui/windowmenu.cpp
@@ -170,7 +170,7 @@ static std::string createShortcutCaption(const std::string& text,
if (key != KeyboardConfig::KEY_NO_VALUE)
{
caption += " (";
- caption += SDL_GetKeyName((SDLKey) keyboard.getKeyValue(key));
+ caption += SDL_GetKeyName((SDL_Scancode) keyboard.getKeyValue(key));
caption += ")";
}
return caption;
diff --git a/src/joystick.cpp b/src/joystick.cpp
index cc6e532b..a1da181c 100644
--- a/src/joystick.cpp
+++ b/src/joystick.cpp
@@ -37,7 +37,7 @@ void Joystick::init()
joystickCount = SDL_NumJoysticks();
logger->log("%i joysticks/gamepads found", joystickCount);
for (int i = 0; i < joystickCount; i++)
- logger->log("- %s", SDL_JoystickName(i));
+ logger->log("- %s", SDL_JoystickNameForIndex(i));
}
Joystick::Joystick(int no):
diff --git a/src/keyboardconfig.cpp b/src/keyboardconfig.cpp
index 30f27e9f..76168f66 100644
--- a/src/keyboardconfig.cpp
+++ b/src/keyboardconfig.cpp
@@ -101,8 +101,8 @@ static KeyData const keyData[KeyboardConfig::KEY_TOTAL] = {
{"keyChatNextTab", SDLK_RIGHTBRACKET, _("Next Chat Tab")},
{"keyOK", SDLK_SPACE, _("Select OK")},
{"keyQuit", SDLK_ESCAPE, _("Quit")},
- {"keyIgnoreInput1", SDLK_LSUPER, _("Ignore input 1")},
- {"keyIgnoreInput2", SDLK_RSUPER, _("Ignore input 2")}
+ {"keyIgnoreInput1", SDLK_LGUI, _("Ignore input 1")},
+ {"keyIgnoreInput2", SDLK_RGUI, _("Ignore input 2")}
};
void KeyboardConfig::init()
@@ -233,5 +233,5 @@ bool KeyboardConfig::isKeyActive(int index) const
void KeyboardConfig::refreshActiveKeys()
{
- mActiveKeys = SDL_GetKeyState(NULL);
+ mActiveKeys = SDL_GetKeyboardState(NULL);
}
diff --git a/src/keyboardconfig.h b/src/keyboardconfig.h
index 34aad4c4..03f39551 100644
--- a/src/keyboardconfig.h
+++ b/src/keyboardconfig.h
@@ -229,7 +229,7 @@ class KeyboardConfig
KeyFunction mKey[KEY_TOTAL]; /**< Pointer to all the key data */
- uint8_t *mActiveKeys; /**< Stores a list of all the keys */
+ const uint8_t *mActiveKeys; /**< Stores a list of all the keys */
std::string mBindError;
};
diff --git a/src/net/download.cpp b/src/net/download.cpp
index bccba7a3..61cdf114 100644
--- a/src/net/download.cpp
+++ b/src/net/download.cpp
@@ -124,7 +124,7 @@ bool Download::start()
{
logger->log("Starting download: %s", mUrl.c_str());
- mThread = SDL_CreateThread(downloadThread, this);
+ mThread = SDL_CreateThread(downloadThread, "Download", this);
if (!mThread)
{
diff --git a/src/net/tmwa/network.cpp b/src/net/tmwa/network.cpp
index 14cfe65f..ed564b46 100644
--- a/src/net/tmwa/network.cpp
+++ b/src/net/tmwa/network.cpp
@@ -159,7 +159,7 @@ bool Network::connect(ServerInfo server)
mToSkip = 0;
mState = CONNECTING;
- mWorkerThread = SDL_CreateThread(networkThread, this);
+ mWorkerThread = SDL_CreateThread(networkThread, "Network", this);
if (!mWorkerThread)
{
setError("Unable to create network worker thread");
diff --git a/src/openglgraphics.cpp b/src/openglgraphics.cpp
index f30e866d..d831d9ff 100644
--- a/src/openglgraphics.cpp
+++ b/src/openglgraphics.cpp
@@ -61,7 +61,13 @@ OpenGLGraphics::~OpenGLGraphics()
void OpenGLGraphics::setSync(bool sync)
{
+ if (mSync == sync)
+ return;
+
mSync = sync;
+
+ if (mContext)
+ SDL_GL_SetSwapInterval(sync ? 1 : 0);
}
void OpenGLGraphics::setReduceInputLag(bool reduceInputLag)
@@ -69,44 +75,57 @@ void OpenGLGraphics::setReduceInputLag(bool reduceInputLag)
mReduceInputLag = reduceInputLag;
}
-bool OpenGLGraphics::setVideoMode(int w, int h, int bpp, bool fs, bool hwaccel)
+bool OpenGLGraphics::setVideoMode(int w, int h, bool fs)
{
logger->log("Setting video mode %dx%d %s",
w, h, fs ? "fullscreen" : "windowed");
- int displayFlags = SDL_ANYFORMAT | SDL_OPENGL;
+ // TODO_SDL2: Support SDL_WINDOW_ALLOW_HIGHDPI, but check handling of clip area
- mWidth = w;
- mHeight = h;
- mBpp = bpp;
- mFullscreen = fs;
- mHWAccel = hwaccel;
+ int windowFlags = SDL_WINDOW_OPENGL;
if (fs)
{
- displayFlags |= SDL_FULLSCREEN;
+ windowFlags |= SDL_WINDOW_FULLSCREEN;
}
else
{
// Resizing currently not supported on Windows, where it would require
// reuploading all textures.
#if !defined(_WIN32)
- displayFlags |= SDL_RESIZABLE;
+ windowFlags |= SDL_WINDOW_RESIZABLE;
#endif
}
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
- if (!(mTarget = SDL_SetVideoMode(w, h, bpp, displayFlags)))
+ SDL_Window *window = SDL_CreateWindow("Mana",
+ SDL_WINDOWPOS_UNDEFINED,
+ SDL_WINDOWPOS_UNDEFINED,
+ w, h, windowFlags);
+ if (!window) {
+ logger->log("Failed to create window: %s", SDL_GetError());
return false;
+ }
+
+ SDL_SetWindowMinimumSize(window, 640, 480);
+
+ SDL_GLContext glContext = SDL_GL_CreateContext(window);
+ if (!glContext) {
+ logger->log("Failed to create OpenGL context: %s", SDL_GetError());
+ return false;
+ }
+
+ mTarget = window;
+ mContext = glContext;
+ mWidth = w;
+ mHeight = h;
+ mFullscreen = fs;
-#ifdef __APPLE__
if (mSync)
{
- const GLint VBL = 1;
- CGLSetParameter(CGLGetCurrentContext(), kCGLCPSwapInterval, &VBL);
+ SDL_GL_SetSwapInterval(1);
}
-#endif
// Setup OpenGL
glViewport(0, 0, w, h);
@@ -139,6 +158,18 @@ bool OpenGLGraphics::setVideoMode(int w, int h, int bpp, bool fs, bool hwaccel)
return true;
}
+void OpenGLGraphics::videoResized(int w, int h)
+{
+ _endDraw();
+
+ mWidth = w;
+ mHeight = h;
+
+ glViewport(0, 0, w, h);
+
+ _beginDraw();
+}
+
static inline void drawQuad(Image *image,
int srcX, int srcY, int dstX, int dstY,
int width, int height)
@@ -610,7 +641,7 @@ void OpenGLGraphics::drawRescaledImagePattern(Image *image,
void OpenGLGraphics::updateScreen()
{
- SDL_GL_SwapBuffers();
+ SDL_GL_SwapWindow(mTarget);
/*
* glFinish flushes all OpenGL commands and makes sure they have been
@@ -634,7 +665,7 @@ void OpenGLGraphics::_beginDraw()
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
- glOrtho(0.0, (double)mTarget->w, (double)mTarget->h, 0.0, -1.0, 1.0);
+ glOrtho(0.0, (double)mWidth, (double)mHeight, 0.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
@@ -646,7 +677,7 @@ void OpenGLGraphics::_beginDraw()
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- pushClipArea(gcn::Rectangle(0, 0, mTarget->w, mTarget->h));
+ pushClipArea(gcn::Rectangle(0, 0, mWidth, mHeight));
}
void OpenGLGraphics::_endDraw()
@@ -656,8 +687,8 @@ void OpenGLGraphics::_endDraw()
SDL_Surface* OpenGLGraphics::getScreenshot()
{
- int h = mTarget->h;
- int w = mTarget->w;
+ int w, h;
+ SDL_GL_GetDrawableSize(mTarget, &w, &h);
GLint pack = 1;
SDL_Surface *screenshot = SDL_CreateRGBSurface(
@@ -708,6 +739,7 @@ bool OpenGLGraphics::pushClipArea(gcn::Rectangle area)
transY = -mClipStack.top().yOffset;
}
+ // Skip Graphics::popClipArea since we don't need to interact with SDL2
bool result = gcn::Graphics::pushClipArea(area);
transX += mClipStack.top().xOffset;
@@ -716,7 +748,7 @@ bool OpenGLGraphics::pushClipArea(gcn::Rectangle area)
glPushMatrix();
glTranslatef(transX, transY, 0);
glScissor(mClipStack.top().x,
- mTarget->h - mClipStack.top().y - mClipStack.top().height,
+ mHeight - mClipStack.top().y - mClipStack.top().height,
mClipStack.top().width,
mClipStack.top().height);
@@ -725,6 +757,7 @@ bool OpenGLGraphics::pushClipArea(gcn::Rectangle area)
void OpenGLGraphics::popClipArea()
{
+ // Skip Graphics::popClipArea since we don't need to interact with SDL2
gcn::Graphics::popClipArea();
if (mClipStack.empty())
@@ -732,7 +765,7 @@ void OpenGLGraphics::popClipArea()
glPopMatrix();
glScissor(mClipStack.top().x,
- mTarget->h - mClipStack.top().y - mClipStack.top().height,
+ mHeight - mClipStack.top().y - mClipStack.top().height,
mClipStack.top().width,
mClipStack.top().height);
}
diff --git a/src/openglgraphics.h b/src/openglgraphics.h
index 63c32261..01bca360 100644
--- a/src/openglgraphics.h
+++ b/src/openglgraphics.h
@@ -37,8 +37,8 @@ class OpenGLGraphics : public Graphics
~OpenGLGraphics();
/**
- * Sets whether vertical refresh syncing is enabled. Takes effect after
- * the next call to setVideoMode(). Only implemented on MacOS for now.
+ * Sets whether vertical refresh syncing is enabled. Takes effect
+ * immediately.
*/
void setSync(bool sync);
bool getSync() const { return mSync; }
@@ -53,7 +53,9 @@ class OpenGLGraphics : public Graphics
void setReduceInputLag(bool reduceInputLag);
bool getReduceInputLag() const { return mReduceInputLag; }
- bool setVideoMode(int w, int h, int bpp, bool fs, bool hwaccel);
+ bool setVideoMode(int w, int h, bool fs);
+
+ void videoResized(int w, int h);
bool drawImage(Image *image,
int srcX, int srcY,
@@ -118,6 +120,7 @@ class OpenGLGraphics : public Graphics
void drawQuadArrayii(int size);
+ SDL_GLContext mContext = nullptr;
GLfloat *mFloatTexArray;
GLint *mIntTexArray;
GLint *mIntVertArray;
diff --git a/src/resources/ambientlayer.cpp b/src/resources/ambientlayer.cpp
index c31afbac..301927f8 100644
--- a/src/resources/ambientlayer.cpp
+++ b/src/resources/ambientlayer.cpp
@@ -33,25 +33,6 @@ AmbientLayer::AmbientLayer(Image *img, float parallax,
mKeepRatio(keepRatio)
{
mImage->incRef();
-
- if (keepRatio && !mImage->useOpenGL()
- && defaultScreenWidth != 0
- && defaultScreenHeight != 0
- && graphics->getWidth() != defaultScreenWidth
- && graphics->getHeight() != defaultScreenHeight)
- {
- // Rescale the overlay to keep the ratio as if we were on
- // the default resolution...
- Image *rescaledOverlay = mImage->SDLgetScaledImage(
- (int) mImage->getWidth() / defaultScreenWidth * graphics->getWidth(),
- (int) mImage->getHeight() / defaultScreenHeight * graphics->getHeight());
-
- if (rescaledOverlay)
- {
- mImage->decRef();
- mImage = rescaledOverlay;
- }
- }
}
AmbientLayer::~AmbientLayer()
@@ -86,7 +67,7 @@ void AmbientLayer::update(int timePassed, float dx, float dy)
void AmbientLayer::draw(Graphics *graphics, int x, int y)
{
- if (!mImage->useOpenGL() || !mKeepRatio)
+ if (!mKeepRatio)
graphics->drawImagePattern(mImage,
(int) -mPosX, (int) -mPosY, x + (int) mPosX, y + (int) mPosY);
else
@@ -94,5 +75,4 @@ void AmbientLayer::draw(Graphics *graphics, int x, int y)
(int) -mPosX, (int) -mPosY, x + (int) mPosX, y + (int) mPosY,
(int) mImage->getWidth() / defaultScreenWidth * graphics->getWidth(),
(int) mImage->getHeight() / defaultScreenHeight * graphics->getHeight());
-
}
diff --git a/src/resources/image.cpp b/src/resources/image.cpp
index 7e592198..6f2609b0 100644
--- a/src/resources/image.cpp
+++ b/src/resources/image.cpp
@@ -29,10 +29,8 @@
#endif
#include "log.h"
-#include "configuration.h"
#include <SDL_image.h>
-#include <SDL_rotozoom.h>
#ifdef USE_OPENGL
bool Image::mUseOpenGL = false;
@@ -40,47 +38,38 @@ bool Image::mPowerOfTwoTextures = true;
int Image::mTextureType = 0;
int Image::mTextureSize = 0;
#endif
-bool Image::mEnableAlphaCache = false;
// The low CPU mode is disabled per default
bool Image::mDisableTransparency = false;
-Image::Image(SDL_Surface *image, bool hasAlphaChannel, Uint8 *alphaChannel):
+SDL_Renderer *Image::mRenderer;
+
+Image::Image(SDL_Texture *texture, int width, int height):
mAlpha(1.0f),
- mSDLSurface(image),
- mAlphaChannel(alphaChannel),
- mHasAlphaChannel(hasAlphaChannel)
+ mTexture(texture)
{
#ifdef USE_OPENGL
mGLImage = 0;
#endif
- mUseAlphaCache = Image::mEnableAlphaCache;
-
mBounds.x = 0;
mBounds.y = 0;
+ mBounds.w = width;
+ mBounds.h = height;
- mLoaded = false;
+ mLoaded = mTexture != nullptr;
- if (mSDLSurface)
+ if (!mLoaded)
{
- mBounds.w = mSDLSurface->w;
- mBounds.h = mSDLSurface->h;
-
- mLoaded = true;
- }
- else
logger->log(
"Image::Image(SDL_Surface*): Couldn't load invalid Surface!");
+ }
}
#ifdef USE_OPENGL
Image::Image(GLuint glimage, int width, int height, int texWidth, int texHeight):
mAlpha(1.0f),
- mSDLSurface(0),
- mAlphaChannel(0),
- mHasAlphaChannel(true),
- mUseAlphaCache(false),
+ mTexture(0),
mGLImage(glimage),
mTexWidth(texWidth),
mTexHeight(texHeight)
@@ -140,10 +129,8 @@ Resource *Image::load(SDL_RWops *rw, Dye const &dye)
rgba.Gmask = 0x00FF0000; rgba.Gloss = 0; rgba.Gshift = 16;
rgba.Bmask = 0x0000FF00; rgba.Bloss = 0; rgba.Bshift = 8;
rgba.Amask = 0x000000FF; rgba.Aloss = 0; rgba.Ashift = 0;
- rgba.colorkey = 0;
- rgba.alpha = 255;
- SDL_Surface *surf = SDL_ConvertSurface(tmpImage, &rgba, SDL_SWSURFACE);
+ SDL_Surface *surf = SDL_ConvertSurface(tmpImage, &rgba, 0);
SDL_FreeSurface(tmpImage);
Uint32 *pixels = static_cast< Uint32 * >(surf->pixels);
@@ -173,34 +160,14 @@ Image *Image::load(SDL_Surface *tmpImage)
return _SDLload(tmpImage);
}
-void Image::SDLcleanCache()
-{
- ResourceManager *resman = ResourceManager::getInstance();
-
- for (std::map<float, SDL_Surface*>::iterator
- i = mAlphaCache.begin(), i_end = mAlphaCache.end();
- i != i_end; ++i)
- {
- if (mSDLSurface != i->second)
- resman->scheduleDelete(i->second);
- i->second = 0;
- }
- mAlphaCache.clear();
-}
-
void Image::unload()
{
mLoaded = false;
- if (mSDLSurface)
+ if (mTexture)
{
- SDLcleanCache();
- // Free the image surface.
- SDL_FreeSurface(mSDLSurface);
- mSDLSurface = NULL;
-
- delete[] mAlphaChannel;
- mAlphaChannel = NULL;
+ SDL_DestroyTexture(mTexture);
+ mTexture = NULL;
}
#ifdef USE_OPENGL
@@ -221,27 +188,6 @@ bool Image::useOpenGL()
#endif
}
-bool Image::hasAlphaChannel()
-{
- if (!mLoaded)
- return false;
-
-#ifdef USE_OPENGL
- if (mUseOpenGL)
- return true;
-#endif
-
- return mHasAlphaChannel;
-}
-
-SDL_Surface *Image::getByAlpha(float alpha)
-{
- std::map<float, SDL_Surface*>::iterator it = mAlphaCache.find(alpha);
- if (it != mAlphaCache.end())
- return (*it).second;
- return 0;
-}
-
void Image::setAlpha(float alpha)
{
if (!useOpenGL() && mDisableTransparency)
@@ -253,188 +199,26 @@ void Image::setAlpha(float alpha)
if (alpha < 0.0f || alpha > 1.0f)
return;
- if (mSDLSurface)
- {
- if (mUseAlphaCache)
- {
- SDL_Surface *surface = getByAlpha(mAlpha);
- if (!surface)
- {
- if (mAlphaCache.size() > 100)
- SDLcleanCache();
-
- mAlphaCache[mAlpha] = mSDLSurface;
- }
- surface = getByAlpha(alpha);
- if (surface)
- {
- mAlphaCache.erase(alpha);
- mSDLSurface = surface;
- mAlpha = alpha;
- return;
- }
- else
- {
- mSDLSurface = Image::SDLduplicateSurface(mSDLSurface);
- }
- }
-
- mAlpha = alpha;
-
- if (!hasAlphaChannel())
- {
- // Set the alpha value this image is drawn at
- SDL_SetAlpha(mSDLSurface, SDL_SRCALPHA, (int) (255 * mAlpha));
- }
- else
- {
- if (SDL_MUSTLOCK(mSDLSurface))
- SDL_LockSurface(mSDLSurface);
-
- // Precompute as much as possible
- int maxHeight = std::min((mBounds.y + mBounds.h), mSDLSurface->h);
- int maxWidth = std::min((mBounds.x + mBounds.w), mSDLSurface->w);
- int i = 0;
-
- for (int y = mBounds.y; y < maxHeight; y++)
- for (int x = mBounds.x; x < maxWidth; x++)
- {
- i = y * mSDLSurface->w + x;
- // Only change the pixel if it was visible at load time...
- Uint8 sourceAlpha = mAlphaChannel[i];
- if (sourceAlpha > 0)
- {
- Uint8 r, g, b, a;
- SDL_GetRGBA(((Uint32*) mSDLSurface->pixels)[i],
- mSDLSurface->format,
- &r, &g, &b, &a);
-
- a = (Uint8) (sourceAlpha * mAlpha);
-
- // Here is the pixel we want to set
- ((Uint32 *)(mSDLSurface->pixels))[i] =
- SDL_MapRGBA(mSDLSurface->format, r, g, b, a);
- }
- }
-
- if (SDL_MUSTLOCK(mSDLSurface))
- SDL_UnlockSurface(mSDLSurface);
- }
- }
- else
- {
- mAlpha = alpha;
- }
-}
-
-Image *Image::SDLgetScaledImage(int width, int height)
-{
- if (width == 0 || height == 0)
- return 0;
+ mAlpha = alpha;
- // Increase our reference count and return ourselves in case of same size
- if (width == getWidth() && height == getHeight())
+ if (mTexture)
{
- incRef();
- return this;
- }
-
- if (!mSDLSurface)
- return 0;
-
- ResourceManager *resman = ResourceManager::getInstance();
-
- // Generate a unique ID path for storing the scaled version in the
- // resource manager.
- std::string idPath = getIdPath();
- idPath += ":scaled:";
- idPath += toString(width);
- idPath += "x";
- idPath += toString(height);
-
- // Try whether a scaled version is already available
- Image *scaledImage = static_cast<Image*>(resman->get(idPath));
-
- if (!scaledImage)
- {
- // No scaled version with this size exists already, so create one
- SDL_Surface *scaledSurface = zoomSurface(mSDLSurface,
- (double) width / getWidth(),
- (double) height / getHeight(),
- 1);
-
- if (scaledSurface)
- {
- scaledImage = load(scaledSurface);
- SDL_FreeSurface(scaledSurface);
-
- // Place the scaled image in the resource manager
- resman->addResource(idPath, scaledImage);
- }
+ SDL_SetTextureAlphaMod(mTexture, (Uint8) (255 * mAlpha));
}
-
- return scaledImage;
}
-SDL_Surface* Image::SDLduplicateSurface(SDL_Surface* tmpImage)
+Image *Image::_SDLload(SDL_Surface *image)
{
- if (!tmpImage || !tmpImage->format)
+ if (!image || !mRenderer)
return NULL;
- return SDL_ConvertSurface(tmpImage, tmpImage->format, SDL_SWSURFACE);
+ SDL_Texture *texture = SDL_CreateTextureFromSurface(mRenderer, image);
+ return new Image(texture, image->w, image->h);
}
-Image *Image::_SDLload(SDL_Surface *tmpImage)
+void Image::setRenderer(SDL_Renderer *renderer)
{
- if (!tmpImage)
- return NULL;
-
- bool hasAlpha = false;
-
- // The alpha channel to be filled with alpha values
- Uint8 *alphaChannel = new Uint8[tmpImage->w * tmpImage->h];
-
- if (tmpImage->format->BitsPerPixel == 32)
- {
- // Figure out whether the image uses its alpha layer
- for (int i = 0; i < tmpImage->w * tmpImage->h; ++i)
- {
- Uint8 r, g, b, a;
- SDL_GetRGBA(
- ((Uint32*) tmpImage->pixels)[i],
- tmpImage->format,
- &r, &g, &b, &a);
-
- if (a != 255)
- hasAlpha = true;
-
- alphaChannel[i] = a;
- }
- }
-
- SDL_Surface *image;
-
- // Convert the surface to the current display format
- if (hasAlpha)
- image = SDL_DisplayFormatAlpha(tmpImage);
- else
- {
- image = SDL_DisplayFormat(tmpImage);
-
- // We also delete the alpha channel since
- // it's not used.
- delete[] alphaChannel;
- alphaChannel = NULL;
- }
-
- if (!image)
- {
- logger->log("Error: Image convert failed.");
- delete[] alphaChannel;
- return NULL;
- }
-
- return new Image(image, hasAlpha, alphaChannel);
+ mRenderer = renderer;
}
#ifdef USE_OPENGL
@@ -489,7 +273,7 @@ Image *Image::_GLload(SDL_Surface *image)
}
// Make sure the alpha channel is not used, but copied to destination
- SDL_SetAlpha(oldImage, 0, SDL_ALPHA_OPAQUE);
+ SDL_SetSurfaceBlendMode(oldImage, SDL_BLENDMODE_NONE);
SDL_BlitSurface(oldImage, NULL, image, NULL);
}
@@ -583,38 +367,24 @@ Image *Image::getSubImage(int x, int y, int width, int height)
mTexWidth, mTexHeight);
#endif
- return new SubImage(this, mSDLSurface,
+ return new SubImage(this, mTexture,
mBounds.x + x,
mBounds.y + y,
width, height);
}
-void Image::SDLterminateAlphaCache()
-{
- SDLcleanCache();
- mUseAlphaCache = false;
-}
-
//============================================================================
// SubImage Class
//============================================================================
-SubImage::SubImage(Image *parent, SDL_Surface *image,
+SubImage::SubImage(Image *parent, SDL_Texture *texture,
int x, int y, int width, int height):
- Image(image),
+ Image(texture, width, height),
mParent(parent)
{
if (mParent)
{
mParent->incRef();
- mParent->SDLterminateAlphaCache();
- mHasAlphaChannel = mParent->hasAlphaChannel();
- mAlphaChannel = mParent->SDLgetAlphaChannel();
- }
- else
- {
- mHasAlphaChannel = false;
- mAlphaChannel = 0;
}
// Set up the rectangle.
@@ -622,7 +392,6 @@ SubImage::SubImage(Image *parent, SDL_Surface *image,
mBounds.y = y;
mBounds.w = width;
mBounds.h = height;
- mUseAlphaCache = false;
}
#ifdef USE_OPENGL
@@ -644,10 +413,8 @@ SubImage::SubImage(Image *parent, GLuint image,
SubImage::~SubImage()
{
- // Avoid destruction of the image
- mSDLSurface = 0;
- // Avoid possible destruction of its alpha channel
- mAlphaChannel = 0;
+ // Avoid destruction of the texture
+ mTexture = nullptr;
#ifdef USE_OPENGL
mGLImage = 0;
#endif
diff --git a/src/resources/image.h b/src/resources/image.h
index b762bf2a..efe2262e 100644
--- a/src/resources/image.h
+++ b/src/resources/image.h
@@ -37,8 +37,6 @@
#include <SDL_opengl.h>
#endif
-#include <map>
-
class Dye;
class Position;
@@ -129,12 +127,6 @@ class Image : public Resource
*/
Image *getSubImage(int x, int y, int width, int height);
- /**
- * Tells if the image has got an alpha channel
- * @return true if it's true, false otherwise.
- */
- bool hasAlphaChannel();
-
// SDL only public functions
/**
@@ -146,31 +138,7 @@ class Image : public Resource
static bool SDLisTransparencyDisabled()
{ return mDisableTransparency; }
- /**
- * Gets an scaled instance of an image. The returned image is managed
- * by the ResourceManager.
- *
- * @param width The desired width of the scaled image.
- * @param height The desired height of the scaled image.
- *
- * @return An Image resource, or 0 on failure.
- */
- Image *SDLgetScaledImage(int width, int height);
-
- /**
- * Get the alpha Channel of a SDL surface.
- */
- Uint8 *SDLgetAlphaChannel() const
- { return mAlphaChannel; }
-
- SDL_Surface* SDLduplicateSurface(SDL_Surface* tmpImage);
-
- void SDLcleanCache();
-
- void SDLterminateAlphaCache();
-
- static void SDLsetEnableAlphaCache(bool n)
- { mEnableAlphaCache = n; }
+ static void setRenderer(SDL_Renderer *renderer);
#ifdef USE_OPENGL
@@ -204,30 +172,18 @@ class Image : public Resource
// -----------------------
/** SDL Constructor */
- Image(SDL_Surface *image, bool hasAlphaChannel = false,
- Uint8 *alphaChannel = NULL);
+ Image(SDL_Texture *texture, int width, int height);
- /** SDL_Surface to SDL_Surface Image loader */
+ /** SDL_Surface to SDL_Texture Image loader */
static Image *_SDLload(SDL_Surface *tmpImage);
- SDL_Surface *getByAlpha(float alpha);
-
- SDL_Surface *mSDLSurface;
-
- /** Alpha Channel pointer used for 32bit based SDL surfaces */
- Uint8 *mAlphaChannel;
- bool mHasAlphaChannel;
-
- /** Alpha cache: The cache stores a copy of the image
- for specific requested opacities, hence, increasing
- the image disply speed */
- std::map<float, SDL_Surface*> mAlphaCache;
- bool mUseAlphaCache;
- static bool mEnableAlphaCache;
+ SDL_Texture *mTexture;
/** Stores whether the transparency is disabled */
static bool mDisableTransparency;
+ static SDL_Renderer *mRenderer;
+
// -----------------------
// OpenGL protected members
// -----------------------
@@ -261,7 +217,7 @@ class Image : public Resource
class SubImage : public Image
{
public:
- SubImage(Image *parent, SDL_Surface *image,
+ SubImage(Image *parent, SDL_Texture *texture,
int x, int y, int width, int height);
#ifdef USE_OPENGL
SubImage(Image *parent, GLuint image, int x, int y,
diff --git a/src/sound.cpp b/src/sound.cpp
index 1af1f136..2fc4f87f 100644
--- a/src/sound.cpp
+++ b/src/sound.cpp
@@ -112,7 +112,6 @@ void Sound::info()
{
SDL_version compiledVersion;
const SDL_version *linkedVersion;
- char driver[40] = "Unknown";
const char *format = "Unknown";
int rate = 0;
Uint16 audioFormat = 0;
@@ -121,7 +120,7 @@ void Sound::info()
MIX_VERSION(&compiledVersion);
linkedVersion = Mix_Linked_Version();
- SDL_AudioDriverName(driver, 40);
+ const char *driver = SDL_GetCurrentAudioDriver();
Mix_QuerySpec(&rate, &audioFormat, &channels);
switch (audioFormat)
diff --git a/src/utils/copynpaste.cpp b/src/utils/copynpaste.cpp
index 2bb8fb49..ccb36d79 100644
--- a/src/utils/copynpaste.cpp
+++ b/src/utils/copynpaste.cpp
@@ -1,7 +1,6 @@
/*
- * Retrieve string pasted depending on OS mechanisms.
- * Copyright (C) 2001-2010 Wormux Team
- * Copyright (C) 2010-2012 The Mana Developers
+ * Clipboard Interaction.
+ * Copyright (C) 2010-2024 The Mana Developers
*
* This file is part of The Mana Client.
*
@@ -19,301 +18,18 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/*
- * IMPORTANT!
- *
- * This code was taken from Wormux svn trunk at Feb 25 2010. Please don't
- * make any unnecessary modifications, and try to sync up modifications
- * when possible.
- */
-
-#ifdef _MSC_VER
-# include "msvc/config.h"
-#elif defined(HAVE_CONFIG_H)
-# include "config.h"
-#endif
-
-#include <SDL_syswm.h>
-#include "copynpaste.h"
-
-#ifdef _WIN32
-bool RetrieveBuffer(std::string& text, std::string::size_type& pos)
-{
- bool ret = false;
-
- if (!OpenClipboard(NULL))
- return false;
-
- HANDLE h = GetClipboardData(CF_UNICODETEXT);
- if (h)
- {
- LPCWSTR data = (LPCWSTR)GlobalLock(h);
+#include "utils/copynpaste.h"
- if (data)
- {
- int len = WideCharToMultiByte(CP_UTF8, 0, data, -1, NULL, 0, NULL, NULL);
- if (len > 0)
- {
- // Convert from UTF-16 to UTF-8
- void *temp = malloc(len);
- if (WideCharToMultiByte(CP_UTF8, 0, data, -1, (LPSTR)temp, len, NULL, NULL))
- {
- text.insert(pos, (char*)temp);
- pos += len-1;
- }
- free(temp);
- ret = true;
- }
- }
- GlobalUnlock(h);
- }
- else
- {
- h = GetClipboardData(CF_TEXT);
-
- if (h)
- {
- const char *data = (char*)GlobalLock(h);
- if (data)
- {
- text.insert(pos, data);
- pos += strlen(data);
- ret = true;
- }
- GlobalUnlock(h);
- }
- }
-
- CloseClipboard();
- return ret;
-}
-#elif defined(__APPLE__)
+#include <SDL.h>
-#ifdef Status
-#undef Status
-#endif
-
-#include <Carbon/Carbon.h>
-
-// Sorry for the very long code, all nicer OS X APIs are coded in Objective C and not C!
-// Also it does very thorough error handling
-bool GetDataFromPasteboard( PasteboardRef inPasteboard, char* flavorText /* out */, const int bufSize )
+bool insertFromClipboard(std::string &text, std::string::size_type &pos)
{
- OSStatus err = noErr;
- PasteboardSyncFlags syncFlags;
- ItemCount itemCount;
-
- syncFlags = PasteboardSynchronize( inPasteboard );
-
- //require_action( syncFlags & kPasteboardModified, PasteboardOutOfSync,
- // err = badPasteboardSyncErr );
-
- err = PasteboardGetItemCount( inPasteboard, &itemCount );
- require_noerr( err, CantGetPasteboardItemCount );
-
- for (UInt32 itemIndex = 1; itemIndex <= itemCount; itemIndex++)
- {
- PasteboardItemID itemID;
- CFArrayRef flavorTypeArray;
- CFIndex flavorCount;
-
- err = PasteboardGetItemIdentifier( inPasteboard, itemIndex, &itemID );
- require_noerr( err, CantGetPasteboardItemIdentifier );
-
- err = PasteboardCopyItemFlavors( inPasteboard, itemID, &flavorTypeArray );
- require_noerr( err, CantCopyPasteboardItemFlavors );
-
- flavorCount = CFArrayGetCount( flavorTypeArray );
-
- for (CFIndex flavorIndex = 0; flavorIndex < flavorCount; flavorIndex++)
- {
- CFStringRef flavorType;
- CFDataRef flavorData;
- CFIndex flavorDataSize;
- flavorType = (CFStringRef)CFArrayGetValueAtIndex(flavorTypeArray, flavorIndex);
-
- // we're only interested by text...
- if (UTTypeConformsTo(flavorType, CFSTR("public.utf8-plain-text")))
- {
- err = PasteboardCopyItemFlavorData( inPasteboard, itemID,
- flavorType, &flavorData );
- require_noerr( err, CantCopyFlavorData );
- flavorDataSize = CFDataGetLength( flavorData );
- flavorDataSize = (flavorDataSize<254) ? flavorDataSize : 254;
-
- if (flavorDataSize+2 > bufSize)
- {
- fprintf(stderr, "Cannot copy clipboard, contents is too big!\n");
- return false;
- }
-
- for (short dataIndex = 0; dataIndex <= flavorDataSize; dataIndex++)
- {
- char byte = *(CFDataGetBytePtr( flavorData ) + dataIndex);
- flavorText[dataIndex] = byte;
- }
-
- flavorText[flavorDataSize] = '\0';
- flavorText[flavorDataSize+1] = '\n';
-
- CFRelease (flavorData);
- return true;
- }
-
- continue;
- CantCopyFlavorData: fprintf(stderr, "Cannot copy clipboard, CantCopyFlavorData!\n");
- }
-
- CFRelease (flavorTypeArray);
- continue;
-
- CantCopyPasteboardItemFlavors: fprintf(stderr, "Cannot copy clipboard, CantCopyPasteboardItemFlavors!\n"); continue;
- CantGetPasteboardItemIdentifier: fprintf(stderr, "Cannot copy clipboard, CantGetPasteboardItemIdentifier!\n"); continue;
- }
- fprintf(stderr, "Cannot copy clipboard, found no acceptable flavour!\n");
- return false;
-
- CantGetPasteboardItemCount: fprintf(stderr, "Cannot copy clipboard, CantGetPasteboardItemCount!\n"); return false;
- //PasteboardOutOfSync: fprintf(stderr, "Cannot copy clipboard, PasteboardOutOfSync!\n"); return false;
-}
-
-bool getClipBoard(char* text /* out */, const int bufSize )
-{
- OSStatus err = noErr;
-
- PasteboardRef theClipboard;
- err = PasteboardCreate( kPasteboardClipboard, &theClipboard );
- require_noerr( err, PasteboardCreateFailed );
-
- if (!GetDataFromPasteboard(theClipboard, text, bufSize))
- {
- fprintf(stderr, "Cannot copy clipboard, GetDataFromPasteboardFailed!\n");
- return false;
- }
-
- CFRelease(theClipboard);
-
- return true;
-
- // ---- error handling
- PasteboardCreateFailed: fprintf(stderr, "Cannot copy clipboard, PasteboardCreateFailed!\n");
- CFRelease(theClipboard);
- return false;
-}
-
-bool RetrieveBuffer(std::string& text, std::string::size_type& pos)
-{
- const int bufSize = 512;
- char buffer[bufSize];
-
- if (getClipBoard(buffer, bufSize))
- {
- text = buffer;
- pos += strlen(buffer);
- return true;
- }
- else
- {
- return false;
- }
-}
-
-#elif USE_X11
-static char* getSelection(Display *dpy, Window us, Atom selection)
-{
- int max_events = 50;
- Window owner = XGetSelectionOwner (dpy, selection);
- int ret;
-
- //printf("XConvertSelection on %s\n", XGetAtomName(dpy, selection));
- if (owner == None)
- {
- //printf("No owner\n");
- return NULL;
- }
- XConvertSelection(dpy, selection, XA_STRING, XA_PRIMARY, us, CurrentTime);
- XFlush(dpy);
-
- while (max_events--)
- {
- XEvent e;
-
- XNextEvent(dpy, &e);
- if(e.type == SelectionNotify)
- {
- //printf("Received %s\n", XGetAtomName(dpy, e.xselection.selection));
- if(e.xselection.property == None)
- {
- //printf("Couldn't convert\n");
- return NULL;
- }
-
- long unsigned len, left, dummy;
- int format;
- Atom type;
- unsigned char *data = NULL;
-
- XGetWindowProperty(dpy, us, e.xselection.property, 0, 0, False,
- AnyPropertyType, &type, &format, &len, &left, &data);
- if (left < 1)
- return NULL;
-
- ret = XGetWindowProperty(dpy, us, e.xselection.property, 0, left, False,
- AnyPropertyType, &type, &format, &len, &dummy, &data);
- if (ret != Success)
- {
- //printf("Failed to get property: %p on %lu\n", data, len);
- return NULL;
- }
-
- //printf(">>> Got %s: len=%lu left=%lu (event %i)\n", data, len, left, 50-max_events);
- return (char*)data;
- }
- }
- return NULL;
-}
-
-bool RetrieveBuffer(std::string& text, std::string::size_type& pos)
-{
- SDL_SysWMinfo info;
-
- //printf("Retrieving buffer...\n");
- SDL_VERSION(&info.version);
- if ( SDL_GetWMInfo(&info) )
- {
- Display *dpy = info.info.x11.display;
- Window us = info.info.x11.window;
- char *data = NULL;
-
- if (!data)
- {
- data = getSelection(dpy, us, XA_PRIMARY);
- }
- if (!data)
- {
- data = getSelection(dpy, us, XA_SECONDARY);
- }
- if (!data)
- {
- Atom XA_CLIPBOARD = XInternAtom(dpy, "CLIPBOARD", 0);
- data = getSelection(dpy, us, XA_CLIPBOARD);
- }
- if (data)
- {
- // check cursor position
- if (pos > text.size()) {
- pos = text.size();
- }
-
- text.insert(pos, data);
- pos += strlen(data);
- XFree(data);
-
- return true;
- }
- }
- return false;
+ char *buf = SDL_GetClipboardText();
+ const size_t len = strlen(buf);
+ if (len > 0) {
+ text.insert(pos, buf);
+ pos += len;
+ }
+ SDL_free(buf);
+ return len > 0;
}
-#else
-bool RetrieveBuffer(std::string&, std::string::size_type&) { return false; }
-#endif
diff --git a/src/utils/copynpaste.h b/src/utils/copynpaste.h
index c2430e1c..b6aa0de0 100644
--- a/src/utils/copynpaste.h
+++ b/src/utils/copynpaste.h
@@ -1,7 +1,6 @@
/*
- * Retrieve string pasted depending on OS mechanisms.
- * Copyright (C) 2001-2010 Wormux Team
- * Copyright (C) 2010-2012 The Mana Developers
+ * Clipboard Interaction.
+ * Copyright (C) 2010-2024 The Mana Developers
*
* This file is part of The Mana Client.
*
@@ -25,10 +24,7 @@
* Attempts to retrieve text from the clipboard buffer and inserts it in
* \a text at position \pos. The characters are encoded in utf-8.
*
- * Implemented for Windows, X11 and Mac OS X.
- *
* @return <code>true</code> when successful or <code>false</code> when there
* was a problem retrieving the clipboard buffer.
*/
-bool RetrieveBuffer(std::string& text, std::string::size_type& pos);
-
+bool insertFromClipboard(std::string &text, std::string::size_type &pos);