]> git.mxchange.org Git - quix0rs-blobwars.git/blobdiff - src/CGraphics.cpp
Fix grenades going backwards when the player is moving.
[quix0rs-blobwars.git] / src / CGraphics.cpp
index 7c6319385c106de010100efbc0c53bb0166d9e4e..30f775507dbb8a26bc2bf466622e819790c4fc33 100644 (file)
@@ -1,5 +1,6 @@
 /*
-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
@@ -20,6 +21,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #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++)
@@ -31,6 +37,9 @@ Graphics::Graphics()
        infoMessage = NULL;
 
        fontSize = 0;
+       
+       medalMessageTimer = 0;
+       medalType = 0;
 
        currentLoading = 0;
 
@@ -88,7 +97,11 @@ void Graphics::destroy()
                        TTF_CloseFont(font[i]);
                }
        }
-
+       
+       if (medalMessage != NULL)
+       {
+               SDL_FreeSurface(medalMessage);
+       }
 
        if (fadeBlack)
        {
@@ -99,6 +112,15 @@ void Graphics::destroy()
        {
                SDL_FreeSurface(infoBar);
        }
+       
+       for (int i = 0 ; i < 4 ; i++)
+       {
+               if (medal[i] != NULL)
+               {
+                       SDL_FreeSurface(medal[i]);
+                       medal[i] = NULL;
+               }
+       }
 }
 
 void Graphics::registerEngine(Engine *engine)
@@ -124,11 +146,11 @@ void Graphics::mapColors()
        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);
+       
+       medalMessage = NULL;
 }
 
 Sprite *Graphics::getSpriteHead()
@@ -138,19 +160,46 @@ Sprite *Graphics::getSpriteHead()
 
 void Graphics::setTransparent(SDL_Surface *sprite)
 {
-       SDL_SetColorKey(sprite, (SDL_SRCCOLORKEY|SDL_RLEACCEL), SDL_MapRGB(sprite->format, 0, 0, 0));
+       SDL_SetColorKey(sprite, SDL_TRUE, SDL_MapRGB(sprite->format, 0, 0, 0));
+}
+
+bool Graphics::canShowMedalMessage() const
+{
+       return (medalMessageTimer <= 0);
 }
 
 void Graphics::updateScreen()
 {
-       SDL_Flip(screen);
-       SDL_Delay(1);
+       if (medalMessageTimer > 0)
+       {
+               int padding = 0;
+               
+               medalMessageTimer--;
+               
+               if (medalType >= 0)
+               {
+                       padding = 18;
+               }
+               
+               drawRect(screen->w - (medalMessage->w + 5 + padding), 5, medalMessage->w + padding - 2, 20, grey, screen);
+               drawRect(screen->w - (medalMessage->w + 5 + padding - 1), 6, medalMessage->w + padding - 4, 18, black, screen);
+               blit(medalMessage, screen->w - (medalMessage->w + 5), 7, screen, false);
+               
+               if (medalType >= 0)
+               {
+                       blit(medal[medalType], screen->w - (medalMessage->w + 5 + 16), 7, screen, false);
+               }
+       }
+       
+       SDL_UpdateTexture(texture, NULL, screen->pixels, screen->w * 4);
+       SDL_RenderCopy(renderer, texture, NULL, NULL);
+       SDL_RenderPresent(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++;
                }
@@ -158,21 +207,21 @@ void Graphics::updateScreen()
                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;
        }
 }
 
@@ -180,7 +229,7 @@ void Graphics::delay(int time)
 {
        unsigned long then = SDL_GetTicks();
 
-       engine->keyState[SDLK_ESCAPE] = 0;
+       engine->keyState[SDL_SCANCODE_ESCAPE] = 0;
 
        while (true)
        {
@@ -194,7 +243,7 @@ void Graphics::delay(int time)
                engine->getInput();
                
                /*
-               if (engine->keyState[SDLK_ESCAPE])
+               if (engine->keyState[SDL_SCANCODE_ESCAPE])
                {
                        break;
                }
@@ -299,7 +348,7 @@ void Graphics::HSVtoRGB(float *r, float *g, float *b, float h, float s, float v)
        }
 }
 
-SDL_Surface *Graphics::loadImage(const char *filename)
+SDL_Surface *Graphics::loadImage(const char *filename, bool srcalpha)
 {
        SDL_Surface *image, *newImage;
 
@@ -314,7 +363,7 @@ SDL_Surface *Graphics::loadImage(const char *filename)
        if (!image)
                showErrorAndExit(ERR_FILE, filename);
 
-       newImage = SDL_DisplayFormat(image);
+       newImage = SDL_ConvertSurface(image, screen->format, 0);
 
        if (newImage)
        {
@@ -326,7 +375,10 @@ SDL_Surface *Graphics::loadImage(const char *filename)
                newImage = image;
        }
 
-       setTransparent(newImage);
+       if(srcalpha)
+               SDL_SetAlpha(newImage, 255);
+       else
+               setTransparent(newImage);
 
        return newImage;
 }
@@ -384,7 +436,7 @@ SDL_Surface *Graphics::loadImage(const char *filename, int hue, int sat, int val
                }
        }
 
-       newImage = SDL_DisplayFormat(image);
+       newImage = SDL_ConvertSurface(image, screen->format, 0);
 
        if (newImage)
        {
@@ -411,7 +463,7 @@ SDL_Surface *Graphics::quickSprite(const char *name, SDL_Surface *image)
 
 void Graphics::fade(int amount)
 {
-       SDL_SetAlpha(fadeBlack, SDL_SRCALPHA|SDL_RLEACCEL, amount);
+       SDL_SetAlpha(fadeBlack, amount);
        blit(fadeBlack, 0, 0, screen, false);
 }
 
@@ -421,7 +473,7 @@ void Graphics::fadeToBlack()
 
        while (start < 50)
        {
-               SDL_SetAlpha(fadeBlack, SDL_SRCALPHA|SDL_RLEACCEL, start);
+               SDL_SetAlpha(fadeBlack, start);
                blit(fadeBlack, 0, 0, screen, false);
                delay(60);
                start++;
@@ -432,7 +484,7 @@ void Graphics::loadMapTiles(const char *baseDir)
 {
        bool found, autoAlpha;
        char filename[255];
-       strcpy(filename, "");
+       filename[0] = 0;
 
        autoAlpha = false;
        
@@ -449,7 +501,7 @@ void Graphics::loadMapTiles(const char *baseDir)
        {
                found = true;
 
-               sprintf(filename, "%s/%d.png", baseDir, i);
+               snprintf(filename, sizeof filename, "%s/%d.png", baseDir, i);
 
                #if USEPAK
                
@@ -473,7 +525,7 @@ void Graphics::loadMapTiles(const char *baseDir)
                        {
                                if ((i < MAP_EXITSIGN) || (i >= MAP_WATERANIM))
                                {
-                                       SDL_SetAlpha(tile[i], SDL_SRCALPHA|SDL_RLEACCEL, 130);
+                                       SDL_SetAlpha(tile[i], 130);
                                }
                        }
                        else
@@ -507,7 +559,7 @@ void Graphics::loadFont(int i, const char *filename, int pixelSize)
        
        char tempPath[PATH_MAX];
        
-       sprintf(tempPath, "%sfont.ttf", engine->userHomeDirectory);
+       snprintf(tempPath, sizeof tempPath, "%sfont.ttf", engine->userHomeDirectory);
 
        bool found = false;
        int size = 0;
@@ -569,7 +621,7 @@ void Graphics::loadFont(int i, const char *filename, int pixelSize)
 Sprite *Graphics::addSprite(const char *name)
 {
        Sprite *sprite = new Sprite;
-       strcpy(sprite->name, name);
+       strlcpy(sprite->name, name, sizeof sprite->name);
 
        spriteList.add(sprite);
 
@@ -615,17 +667,17 @@ void Graphics::animateSprites()
        }
 }
 
-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;
 }
@@ -816,8 +868,6 @@ void Graphics::setFontColor(int red, int green, int blue, int red2, int green2,
        fontBackground.r = red2;
        fontBackground.g = green2;
        fontBackground.b = blue2;
-
-       fontForeground.unused = fontBackground.unused = 0;
 }
 
 void Graphics::setFontSize(int size)
@@ -848,26 +898,59 @@ void Graphics::drawString(const char *in, int x, int y, int alignment, SDL_Surfa
        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)
@@ -903,7 +986,7 @@ void Graphics::drawChatString(SDL_Surface *surface, int y)
                        continue;
                }
 
-               sprintf(wordWithSpace, "%s ", word);
+               snprintf(wordWithSpace, sizeof wordWithSpace, "%s ", word);
 
                wordSurface = getString(wordWithSpace, false);
 
@@ -915,14 +998,62 @@ void Graphics::drawChatString(SDL_Surface *surface, int y)
 
                blit(wordSurface, x, y, surface, false);
 
-               SDL_FreeSurface(wordSurface);
-
                x += wordSurface->w;
 
+               SDL_FreeSurface(wordSurface);
+
                word = strtok(NULL, " ");
        }
 }
 
+void Graphics::showMedalMessage(int type, const char *in)
+{
+       char message[1024];
+       
+       if (medalMessage != NULL)
+       {
+               SDL_FreeSurface(medalMessage);
+       }
+       
+       setFontSize(0);
+       
+       switch (type)
+       {
+               // Bronze
+               case 1:
+                       setFontColor(0xA6, 0x7D, 0x3D, 0x00, 0x00, 0x00);
+                       break;
+               
+               // Silver
+               case 2:
+                       setFontColor(0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00);
+                       break;
+                       
+               // Gold
+               case 3:
+                       setFontColor(0xFF, 0xCC, 0x33, 0x00, 0x00, 0x00);
+                       break;
+                       
+               // Ruby
+               case 4:
+                       setFontColor(0xFF, 0x11, 0x55, 0x00, 0x00, 0x00);
+                       break;
+       }
+       
+       medalType = type - 1; // for indexing on the image
+       if (type != -1)
+       {
+               snprintf(message, sizeof message, "  Medal Earned - %s  ", in);
+               medalMessage = getString(message, true);
+       }
+       else
+       {
+               snprintf(message, sizeof message, "  %s  ", in);
+               medalMessage = getString(message, true);
+       }
+       medalMessageTimer = (5 * 60);
+}
+
 void Graphics::drawWidgetRect(int x, int y, int w, int h)
 {
        drawRect(x - 5, y - 4, w + 10, h + 8, white, screen);
@@ -939,7 +1070,7 @@ SDL_Surface *Graphics::createSurface(int width, int height)
        if (surface == NULL)
                showErrorAndExit("CreateRGBSurface failed: %s\n", SDL_GetError());
 
-       newImage = SDL_DisplayFormat(surface);
+       newImage = SDL_ConvertSurface(surface, screen->format, 0);
 
        SDL_FreeSurface(surface);
 
@@ -952,7 +1083,7 @@ SDL_Surface *Graphics::alphaRect(int width, int height, Uint8 red, Uint8 green,
 
        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;
 }
@@ -963,7 +1094,7 @@ void Graphics::colorize(SDL_Surface *image, int red, int green, int blue)
 
        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)
@@ -1028,7 +1159,7 @@ void Graphics::showLicenseErrorAndExit()
        {
                updateScreen();
                engine->getInput();
-               if (engine->keyState[SDLK_ESCAPE])
+               if (engine->keyState[SDL_SCANCODE_ESCAPE])
                        exit(1);
                SDL_Delay(16);
        }
@@ -1044,7 +1175,7 @@ void Graphics::showErrorAndExit(const char *error, const char *param)
        }
 
        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);
@@ -1075,7 +1206,7 @@ void Graphics::showErrorAndExit(const char *error, const char *param)
        {
                updateScreen();
                engine->getInput();
-               if (engine->keyState[SDLK_ESCAPE])
+               if (engine->keyState[SDL_SCANCODE_ESCAPE])
                {
                        exit(1);
                }
@@ -1104,11 +1235,11 @@ void Graphics::showRootWarning()
                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);
                }