fix resizing by adding an indirection to the surface for graphics

This commit is contained in:
Tim Felgentreff 2020-04-15 13:43:36 +02:00
parent 800c25b5fa
commit e884ceece2
6 changed files with 60 additions and 82 deletions
src
guichan
include/guichan/sdl
sdl
include
ui
video

View file

@ -83,22 +83,13 @@ namespace gcn
SDLGraphics();
/**
* Sets the target SDL_Surface to draw to. The target can be any
* Pointer to the target surface to render into. The target can be any
* SDL_Surface. 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_Renderer* renderer);
virtual void setTarget(SDL_Surface* target);
//virtual void setTarget(SDL_Renderer* renderer);
/**
* Gets the target SDL_Surface.
*
* @return the target SDL_Surface.
*/
virtual SDL_Surface* getTarget() const;
virtual void setTarget(SDL_Surface** surface);
/**
* Draws an SDL_Surface on the target surface. Normaly you'll
@ -156,9 +147,7 @@ namespace gcn
*/
virtual void drawVLine(int x, int y1, int y2);
SDL_Surface* mTarget;
SDL_Renderer* mRenderer;
SDL_Texture* mTargetTexture;
SDL_Surface** mTarget;
Color mColor;
bool mAlpha;
};

View file

@ -84,44 +84,19 @@ namespace gcn
Rectangle area;
area.x = 0;
area.y = 0;
area.width = mTarget->w;
area.height = mTarget->h;
area.width = (*mTarget)->w;
area.height = (*mTarget)->h;
pushClipArea(area);
//SDL_FillRect(mTarget, NULL, SDL_MapRGBA(mTarget->format, 0, 0, 0, 0));
}
void SDLGraphics::_endDraw()
{
//SDL_UpdateTexture(mTargetTexture, NULL, mTarget->pixels, mTarget->w * sizeof(Uint32));
//SDL_RenderCopy(mRenderer, mTargetTexture, NULL, NULL);
//SDL_RenderPresent(mRenderer);
popClipArea();
}
#if 0
void SDLGraphics::setTarget(SDL_Renderer* renderer)
void SDLGraphics::setTarget(SDL_Surface** targetPtr)
{
if(mTarget)
{
SDL_FreeSurface(mTarget);
SDL_DestroyTexture(mTargetTexture);
}
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
mTarget = SDL_CreateRGBSurface(0, 640, 480, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
#else
mTarget = SDL_CreateRGBSurface(0, 640, 480, 32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000);
#endif
SDL_FillRect(mTarget, NULL, SDL_MapRGBA(mTarget->format, 0, 0, 0, 0));
mTargetTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 640, 480);
mRenderer = renderer;
}
#endif
void SDLGraphics::setTarget(SDL_Surface* target)
{
mTarget = target;
mTarget = targetPtr;
}
bool SDLGraphics::pushClipArea(Rectangle area)
{
@ -134,7 +109,7 @@ namespace gcn
rect.w = carea.width;
rect.h = carea.height;
SDL_SetClipRect(mTarget, &rect);
SDL_SetClipRect(*mTarget, &rect);
return result;
}
@ -155,12 +130,7 @@ namespace gcn
rect.w = carea.width;
rect.h = carea.height;
SDL_SetClipRect(mTarget, &rect);
}
SDL_Surface* SDLGraphics::getTarget() const
{
return mTarget;
SDL_SetClipRect(*mTarget, &rect);
}
void SDLGraphics::drawImage(const Image* image, int srcX,
@ -179,9 +149,9 @@ namespace gcn
SDL_Surface* srcImage = (SDL_Surface*)image->_getData();
//SDL_LockSurface(mTarget);
SDL_BlitSurface(srcImage, &src, mTarget, &dst);
//SDL_UnlockSurface(mTarget);
//SDL_LockSurface(*mTarget);
SDL_BlitSurface(srcImage, &src, *mTarget, &dst);
//SDL_UnlockSurface(*mTarget);
}
void SDLGraphics::fillRectangle(const Rectangle& rectangle)
@ -204,18 +174,17 @@ namespace gcn
int x2 = std::min<int>(area.x + area.width, top.x + top.width);
int y2 = std::min<int>(area.y + area.height, top.y + top.height);
int x, y;
//Video.FillTransRectangle(SDL_MapRGB(mTarget->format, mColor.r, mColor.g, mColor.b),
//Video.FillTransRectangle(SDL_MapRGB((*mTarget)->format, mColor.r, mColor.g, mColor.b),
// x1, y1, x2 - x1, y2 - y1, mColor.a);
//SDL_LockSurface(mTarget);
//SDL_LockSurface(*mTarget);
for (y = y1; y < y2; y++)
{
for (x = x1; x < x2; x++)
{
SDLputPixelAlpha(mTarget, x, y, mColor);
SDLputPixelAlpha(*mTarget, x, y, mColor);
}
}
//SDL_UnlockSurface(mTarget);
//SDL_UnlockSurface(*mTarget);
}
else
{
@ -225,8 +194,8 @@ namespace gcn
rect.w = area.width;
rect.h = area.height;
Uint32 color = SDL_MapRGBA(mTarget->format, mColor.r, mColor.g, mColor.b, mColor.a);
SDL_FillRect(mTarget, &rect, color);
Uint32 color = SDL_MapRGBA((*mTarget)->format, mColor.r, mColor.g, mColor.b, mColor.a);
SDL_FillRect(*mTarget, &rect, color);
}
}
@ -241,11 +210,11 @@ namespace gcn
if (mAlpha)
{
SDLputPixelAlpha(mTarget, x, y, mColor);
SDLputPixelAlpha(*mTarget, x, y, mColor);
}
else
{
SDLputPixel(mTarget, x, y, mColor);
SDLputPixel(*mTarget, x, y, mColor);
}
}
@ -284,7 +253,7 @@ namespace gcn
x2 = top.x + top.width -1;
}
Uint32 color =
SDL_MapRGB(mTarget->format, mColor.r, mColor.g, mColor.b);
SDL_MapRGB((*mTarget)->format, mColor.r, mColor.g, mColor.b);
if (mAlpha) {
Video.DrawTransHLine(color, x1, y, x2 - x1, mColor.a);
} else {
@ -327,7 +296,7 @@ namespace gcn
y2 = top.y + top.height - 1;
}
Uint32 color =
SDL_MapRGB(mTarget->format, mColor.r, mColor.g, mColor.b);
SDL_MapRGB((*mTarget)->format, mColor.r, mColor.g, mColor.b);
if (mAlpha) {
Video.DrawTransVLine(color, x, y1,y2 - y1, mColor.a);
} else {
@ -399,11 +368,11 @@ namespace gcn
{
if (mAlpha)
{
SDLputPixelAlpha(mTarget, x, y, mColor);
SDLputPixelAlpha(*mTarget, x, y, mColor);
}
else
{
SDLputPixel(mTarget, x, y, mColor);
SDLputPixel(*mTarget, x, y, mColor);
}
}
@ -427,11 +396,11 @@ namespace gcn
{
if (mAlpha)
{
SDLputPixelAlpha(mTarget, x, y, mColor);
SDLputPixelAlpha(*mTarget, x, y, mColor);
}
else
{
SDLputPixel(mTarget, x, y, mColor);
SDLputPixel(*mTarget, x, y, mColor);
}
}
@ -471,11 +440,11 @@ namespace gcn
{
if (mAlpha)
{
SDLputPixelAlpha(mTarget, x, y, mColor);
SDLputPixelAlpha(*mTarget, x, y, mColor);
}
else
{
SDLputPixel(mTarget, x, y, mColor);
SDLputPixel(*mTarget, x, y, mColor);
}
}
@ -499,11 +468,11 @@ namespace gcn
{
if (mAlpha)
{
SDLputPixelAlpha(mTarget, x, y, mColor);
SDLputPixelAlpha(*mTarget, x, y, mColor);
}
else
{
SDLputPixel(mTarget, x, y, mColor);
SDLputPixel(*mTarget, x, y, mColor);
}
}
@ -538,6 +507,6 @@ namespace gcn
destination.x += top.xOffset;
destination.y += top.yOffset;
SDL_BlitSurface(surface, &source, mTarget, &destination);
SDL_BlitSurface(surface, &source, *mTarget, &destination);
}
}

View file

@ -328,6 +328,7 @@ extern void SetPlayersPalette();
extern SDL_Window *TheWindow;
extern SDL_Renderer *TheRenderer;
extern SDL_Surface *TheScreen;
extern SDL_Texture *TheTexture;
/// register lua function
extern void VideoCclRegister();

View file

@ -99,7 +99,7 @@ void initGuichan()
// Set the target for the graphics object to be the screen.
// In other words, we will draw to the screen.
// Note, any surface will do, it doesn't have to be the screen.
((gcn::SDLGraphics *)graphics)->setTarget(TheScreen);
((gcn::SDLGraphics *)graphics)->setTarget(&TheScreen);
Input = new gcn::SDLInput();

View file

@ -343,13 +343,6 @@ void InitVideoSdl()
if (TheWindow == NULL) {
fprintf(stderr, "Couldn't set %dx%dx%d video mode: %s\n",
Video.Width, Video.Height, Video.Depth, SDL_GetError());
if (Video.FullScreen) {
fprintf(stderr, "Re-trying video without fullscreen mode\n");
Video.FullScreen = false;
InitVideoSdl();
return;
}
fprintf(stderr, "Could not initialize video, even without fullscreen or OpenGL. Giving up.\n");
exit(1);
}
if (!TheRenderer) TheRenderer = SDL_CreateRenderer(TheWindow, -1, 0);

View file

@ -267,9 +267,35 @@ void CVideo::ClearScreen()
bool CVideo::ResizeScreen(int w, int h)
{
if (VideoValidResolution(w, h)) {
SDL_SetWindowSize(TheWindow, w, h);
ViewportWidth = w;
ViewportHeight = h;
Width = w;
Height = h;
if (!(SDL_GetWindowFlags(TheWindow) & SDL_WINDOW_FULLSCREEN_DESKTOP)) {
SDL_SetWindowSize(TheWindow, w, h);
}
SDL_RenderSetLogicalSize(TheRenderer, w, h);
// new surface
Uint32 flags = TheScreen->flags;
Uint32 rmask = TheScreen->format->Rmask;
Uint32 gmask = TheScreen->format->Gmask;
Uint32 bmask = TheScreen->format->Bmask;
Uint32 amask = TheScreen->format->Amask;
Uint8 bpp = TheScreen->format->BitsPerPixel;
SDL_FreeSurface(TheScreen);
TheScreen = SDL_CreateRGBSurface(flags, w, h, bpp, rmask, gmask, bmask, amask);
// new texture
Uint32 format;
int access, oldW, oldH;
SDL_QueryTexture(TheTexture, &format, &access, &oldW, &oldH);
SDL_DestroyTexture(TheTexture);
TheTexture = SDL_CreateTexture(TheRenderer, format, access, w, h);
SetClipping(0, 0, w - 1, h - 1);
return true;
}
return false;