/*
-Copyright (C) 2004 Parallel Realities
+Copyright (C) 2004-2011 Parallel Realities
+Copyright (C) 2011-2015 Perpendicular Dimensions
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
#include "headers.h"
+void SDL_SetAlpha(SDL_Surface *surface, uint8_t value) {
+ SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_BLEND);
+ SDL_SetSurfaceAlphaMod(surface, value);
+}
+
Graphics::Graphics()
{
for (int i = 0 ; i < MAX_TILES ; i++)
fontForeground.r = fontForeground.g = fontForeground.b = 0xff;
fontBackground.r = fontBackground.g = fontBackground.b = 0x00;
- fontForeground.unused = fontBackground.unused = 0;
-
fadeBlack = alphaRect(640, 480, 0x00, 0x00, 0x00);
infoBar = alphaRect(640, 25, 0x00, 0x00, 0x00);
void Graphics::setTransparent(SDL_Surface *sprite)
{
- SDL_SetColorKey(sprite, (SDL_SRCCOLORKEY|SDL_RLEACCEL), SDL_MapRGB(sprite->format, 0, 0, 0));
+ if (sprite)
+ SDL_SetColorKey(sprite, SDL_TRUE, SDL_MapRGB(sprite->format, 0, 0, 0));
}
-bool Graphics::canShowMedalMessage()
+bool Graphics::canShowMedalMessage() const
{
return (medalMessageTimer <= 0);
}
}
}
- SDL_Flip(screen);
- SDL_Delay(1);
+ SDL_UpdateTexture(texture, NULL, screen->pixels, screen->w * 4);
+ SDL_RenderCopy(renderer, texture, NULL, NULL);
+ SDL_RenderPresent(renderer);
+ SDL_RenderClear(renderer);
if (takeRandomScreenShots)
{
if ((Math::prand() % 500) == 0)
{
- sprintf(screenshot, "screenshots/screenshot%.3d.bmp", screenShotNumber);
+ snprintf(screenshot, sizeof screenshot, "screenshots/screenshot%.3d.bmp", screenShotNumber);
SDL_SaveBMP(screen, screenshot);
screenShotNumber++;
}
SDL_Delay(16);
}
- if (engine->keyState[SDLK_F12])
+ if (engine->keyState[SDL_SCANCODE_F12])
{
- sprintf(screenshot, "screenshots/screenshot%.3d.bmp", screenShotNumber);
+ snprintf(screenshot, sizeof screenshot, "screenshots/screenshot%.3d.bmp", screenShotNumber);
SDL_SaveBMP(screen, screenshot);
screenShotNumber++;
- engine->keyState[SDLK_F12] = 0;
+ engine->keyState[SDL_SCANCODE_F12] = 0;
}
- if ((engine->keyState[SDLK_F10]) || ((engine->keyState[SDLK_RETURN]) && (engine->keyState[SDLK_LALT])))
+ if ((engine->keyState[SDL_SCANCODE_F10]) || ((engine->keyState[SDL_SCANCODE_RETURN]) && (engine->keyState[SDL_SCANCODE_LALT])))
{
- SDL_WM_ToggleFullScreen(screen);
engine->fullScreen = !engine->fullScreen;
+ SDL_SetWindowFullscreen(window, engine->fullScreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
- engine->keyState[SDLK_F10] = engine->keyState[SDLK_LALT] = engine->keyState[SDLK_RETURN] = 0;
+ engine->keyState[SDL_SCANCODE_F10] = engine->keyState[SDL_SCANCODE_LALT] = engine->keyState[SDL_SCANCODE_RETURN] = 0;
}
}
{
unsigned long then = SDL_GetTicks();
- engine->keyState[SDLK_ESCAPE] = 0;
+ engine->keyState[SDL_SCANCODE_ESCAPE] = 0;
while (true)
{
engine->getInput();
/*
- if (engine->keyState[SDLK_ESCAPE])
+ if (engine->keyState[SDL_SCANCODE_ESCAPE])
{
break;
}
}
}
-SDL_Surface *Graphics::loadImage(const char *filename)
+SDL_Surface *Graphics::loadImage(const char *filename, bool srcalpha)
{
SDL_Surface *image, *newImage;
#endif
if (!image)
- showErrorAndExit(ERR_FILE, filename);
+ return showErrorAndExit(ERR_FILE, filename), image;
- newImage = SDL_DisplayFormat(image);
+ newImage = SDL_ConvertSurface(image, screen->format, 0);
if (newImage)
{
newImage = image;
}
- setTransparent(newImage);
+ if(srcalpha)
+ SDL_SetAlpha(newImage, 255);
+ else
+ setTransparent(newImage);
return newImage;
}
#endif
if (!image)
- showErrorAndExit(ERR_FILE, filename);
+ return showErrorAndExit(ERR_FILE, filename), image;
if ((hue != 0) || (sat != 0) || (value != 0))
{
}
}
- newImage = SDL_DisplayFormat(image);
+ newImage = SDL_ConvertSurface(image, screen->format, 0);
if (newImage)
{
void Graphics::fade(int amount)
{
- SDL_SetAlpha(fadeBlack, SDL_SRCALPHA|SDL_RLEACCEL, amount);
+ SDL_SetAlpha(fadeBlack, amount);
blit(fadeBlack, 0, 0, screen, false);
}
while (start < 50)
{
- SDL_SetAlpha(fadeBlack, SDL_SRCALPHA|SDL_RLEACCEL, start);
+ SDL_SetAlpha(fadeBlack, start);
blit(fadeBlack, 0, 0, screen, false);
delay(60);
start++;
{
bool found, autoAlpha;
char filename[255];
- strcpy(filename, "");
+ filename[0] = 0;
autoAlpha = false;
{
found = true;
- sprintf(filename, "%s/%d.png", baseDir, i);
+ snprintf(filename, sizeof filename, "%s/%d.png", baseDir, i);
#if USEPAK
{
tile[i] = loadImage(filename);
+ if (!tile[i])
+ abort();
+
if (autoAlpha)
{
if ((i < MAP_EXITSIGN) || (i >= MAP_WATERANIM))
{
- SDL_SetAlpha(tile[i], SDL_SRCALPHA|SDL_RLEACCEL, 130);
+ SDL_SetAlpha(tile[i], 130);
}
}
else
}
}
-/*
-Note : We need to search for the right >>> PIXEL SIZE <<< and NOT point size!!
-If a user has a resolution other than approximately 72dpi then
-they will get a small or larger font and this won't work. This might look
-weird since we'll load and delete multiple fonts, but it works...
-*/
-void Graphics::loadFont(int i, const char *filename, int pixelSize)
+void Graphics::loadFont(int i, const char *filename, int pointSize)
{
- int minx, maxx, miny, maxy, advance;
-
- debug(("Attempting to load a font with pixel size of %d...\n", pixelSize));
+ debug(("Attempting to load font %s with point size of %d...\n", filename, pointSize));
if (font[i])
{
TTF_CloseFont(font[i]);
}
- char tempPath[PATH_MAX];
-
- sprintf(tempPath, "%sfont.ttf", engine->userHomeDirectory);
+ #if USEPAK
+ (void)filename;
+ char tempPath[PATH_MAX];
+ snprintf(tempPath, sizeof tempPath, "%sfont.ttf", engine->userHomeDirectory);
+ font[i] = TTF_OpenFont(tempPath, pointSize);
+ #else
+ font[i] = TTF_OpenFont(filename, pointSize);
+ #endif
- bool found = false;
- int size = 0;
-
- while (!found)
+ if (!font[i])
{
- if (font[i])
- {
- TTF_CloseFont(font[i]);
- }
-
- #if USEPAK
- font[i] = TTF_OpenFont(tempPath, ++size);
- #else
- font[i] = TTF_OpenFont("data/vera.ttf", ++size);
- #endif
-
- if (!font[i])
- {
- engine->reportFontFailure();
- }
-
- TTF_GlyphMetrics(font[i], '8', &minx, &maxx, &miny, &maxy, &advance);
-
- // great! we have an exact match
- if (maxx == pixelSize)
- {
- break;
- }
-
- // we've overshot, so we'll use the previous size!
- if (maxx > pixelSize)
- {
- TTF_CloseFont(font[i]);
-
- #if USEPAK
- font[i] = TTF_OpenFont(tempPath, size - 1);
- #else
- font[i] = TTF_OpenFont("data/vera.ttf", size - 1);
- #endif
-
- TTF_GlyphMetrics(font[i], '8', &minx, &maxx, &miny, &maxy, &advance);
-
- break;
- }
-
- if (size >= 100)
- {
- debug(("Pixel size has exceeded 99 pixels! I'm giving up!\n"));
- engine->reportFontFailure();
- }
+ engine->reportFontFailure();
}
TTF_SetFontStyle(font[i], TTF_STYLE_NORMAL);
-
- debug(("Got a match for font size %d - Nearest = %d\n", pixelSize, maxx));
}
Sprite *Graphics::addSprite(const char *name)
{
Sprite *sprite = new Sprite;
- strcpy(sprite->name, name);
+ strlcpy(sprite->name, name, sizeof sprite->name);
spriteList.add(sprite);
}
}
-int Graphics::getWaterAnim()
+int Graphics::getWaterAnim() const
{
return waterAnim;
}
-int Graphics::getSlimeAnim()
+int Graphics::getSlimeAnim() const
{
return slimeAnim;
}
-int Graphics::getLavaAnim()
+int Graphics::getLavaAnim() const
{
return lavaAnim;
}
{
if (!image)
{
- showErrorAndExit("graphics::blit() - NULL pointer", SDL_GetError());
+ return showErrorAndExit("graphics::blit() - NULL pointer", SDL_GetError());
}
if ((x < -image->w) || (x > 640 + image->w))
fontBackground.r = red2;
fontBackground.g = green2;
fontBackground.b = blue2;
-
- fontForeground.unused = fontBackground.unused = 0;
}
void Graphics::setFontSize(int size)
text = TTF_RenderUTF8_Shaded(font[fontSize], "FONT_ERROR", fontForeground, fontBackground);
}
+ if (!text)
+ {
+ fprintf(stderr, "Unable to render text: %s\n", SDL_GetError());
+ abort();
+ }
+
if (transparent)
setTransparent(text);
SDL_Surface *text = TTF_RenderUTF8_Shaded(font[fontSize], in, fontForeground, fontBackground);
if (!text)
- {
text = TTF_RenderUTF8_Shaded(font[fontSize], "FONT_ERROR", fontForeground, fontBackground);
- }
+
+ if (!text)
+ return;
+
+ setTransparent(text);
if (alignment == TXT_RIGHT) x -= text->w;
if (alignment == TXT_CENTERED) center = true;
- setTransparent(text);
blit(text, x, y, dest, center);
SDL_FreeSurface(text);
}
+void Graphics::drawString(const char *in, int x, int y, int alignment, SDL_Surface *dest, SurfaceCache &cache)
+{
+ bool center = false;
+
+ if(!cache.text || strcmp(in, cache.text)) {
+ if(cache.surface)
+ SDL_FreeSurface(cache.surface);
+
+ if(cache.text)
+ ::free(cache.text);
+
+ cache.text = strdup(in);
+
+ cache.surface = TTF_RenderUTF8_Shaded(font[fontSize], in, fontForeground, fontBackground);
+
+ if (!cache.surface)
+ cache.surface = TTF_RenderUTF8_Shaded(font[fontSize], "FONT_ERROR", fontForeground, fontBackground);
+
+ if(!cache.surface)
+ return;
+
+ setTransparent(cache.surface);
+ }
+
+ if (alignment == TXT_RIGHT) x -= cache.surface->w;
+ if (alignment == TXT_CENTERED) center = true;
+
+ blit(cache.surface, x, y, dest, center);
+}
+
void Graphics::clearChatString()
{
- strcpy(chatString, "");
+ chatString[0] = 0;
}
void Graphics::createChatString(const char *in)
{
- sprintf(chatString, "%s %s", chatString, in);
+ strlcat(chatString, " ", sizeof chatString);
+ strlcat(chatString, in, sizeof chatString);
}
void Graphics::drawChatString(SDL_Surface *surface, int y)
continue;
}
- sprintf(wordWithSpace, "%s ", word);
+ snprintf(wordWithSpace, sizeof wordWithSpace, "%s ", word);
wordSurface = getString(wordWithSpace, false);
blit(wordSurface, x, y, surface, false);
- SDL_FreeSurface(wordSurface);
-
x += wordSurface->w;
+ SDL_FreeSurface(wordSurface);
+
word = strtok(NULL, " ");
}
}
medalType = type - 1; // for indexing on the image
if (type != -1)
{
- sprintf(message, " Medal Earned - %s ", in);
+ snprintf(message, sizeof message, " Medal Earned - %s ", in);
medalMessage = getString(message, true);
}
else
{
- sprintf(message, " %s ", in);
+ snprintf(message, sizeof message, " %s ", in);
medalMessage = getString(message, true);
}
medalMessageTimer = (5 * 60);
if (surface == NULL)
showErrorAndExit("CreateRGBSurface failed: %s\n", SDL_GetError());
- newImage = SDL_DisplayFormat(surface);
+ newImage = SDL_ConvertSurface(surface, screen->format, 0);
SDL_FreeSurface(surface);
SDL_FillRect(surface, NULL, SDL_MapRGB(surface->format, red, green, blue));
- SDL_SetAlpha(surface, SDL_SRCALPHA|SDL_RLEACCEL, 130);
+ SDL_SetAlpha(surface, 130);
return surface;
}
blit(alpha, 0, 0, image, false);
- SDL_SetColorKey(image, (SDL_SRCCOLORKEY|SDL_RLEACCEL), SDL_MapRGB(image->format, red / 2, green / 2, blue / 2));
+ SDL_SetColorKey(image, SDL_TRUE, SDL_MapRGB(image->format, red / 2, green / 2, blue / 2));
}
void Graphics::lock(SDL_Surface *surface)
drawRect(120, 420, 400, 10, black, white, screen);
drawRect(121, 421, currentLoading, 8, red, screen);
-
- SDL_UpdateRect(screen, 120, 420, 400, 10);
+ #else
+ (void)amount;
+ (void)max;
#endif
}
{
updateScreen();
engine->getInput();
- if (engine->keyState[SDLK_ESCAPE])
+ if (engine->keyState[SDL_SCANCODE_ESCAPE])
exit(1);
SDL_Delay(16);
}
}
char message[256];
- sprintf(message, error, param);
+ snprintf(message, sizeof message, error, param);
setFontSize(3); setFontColor(0xff, 0x00, 0x00, 0x00, 0x00, 0x00);
drawString("An unforseen error has occurred", 320, 50, true, screen);
{
updateScreen();
engine->getInput();
- if (engine->keyState[SDLK_ESCAPE])
+ if (engine->keyState[SDL_SCANCODE_ESCAPE])
{
exit(1);
}
updateScreen();
engine->getInput();
- if (engine->keyState[SDLK_ESCAPE])
+ if (engine->keyState[SDL_SCANCODE_ESCAPE])
{
return;
}
- else if (engine->keyState[SDLK_SPACE])
+ else if (engine->keyState[SDL_SCANCODE_SPACE])
{
exit(0);
}