]> git.localhorst.tv Git - l2e.git/commitdiff
added basic defeat state
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Tue, 19 Feb 2013 17:59:02 +0000 (18:59 +0100)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Tue, 19 Feb 2013 17:59:02 +0000 (18:59 +0100)
refs #4

src/battle/BattleState.cpp
src/battle/Resources.cpp
src/battle/Resources.h
src/battle/states/DefeatState.cpp [new file with mode: 0644]
src/battle/states/DefeatState.h [new file with mode: 0644]
src/sdl/Desaturate.cpp [new file with mode: 0644]
src/sdl/Desaturate.h [new file with mode: 0644]
test-data/test.l2s

index 1f68acfa8bf05576202233639e008bc0d31d0c43..c6f07cd814d9247fae9caa609a14ddebc63b9a79 100644 (file)
@@ -1,6 +1,7 @@
 #include "BattleState.h"
 
 #include "PartyLayout.h"
+#include "states/DefeatState.h"
 #include "states/SelectMoveAction.h"
 #include "states/PerformAttacks.h"
 #include "states/VictoryState.h"
@@ -129,7 +130,12 @@ void BattleState::OnResumeState(SDL_Surface *screen) {
                return;
        }
        if (battle.Defeat()) {
-               Ctrl().PopState();
+               if (alreadyPushed) {
+                       Ctrl().PopState();
+               } else {
+                       Ctrl().PushState(new DefeatState(&battle, this));
+                       alreadyPushed = true;
+               }
                return;
        }
        // TODO: this should not push a state while quitting
index 9db29e1787809613859b1daac68faadcfd7ae8e2..3e61cf5017621fcb57375fce9b26fc45edaf9c9b 100644 (file)
@@ -61,6 +61,7 @@ Resources::Resources()
 , noEquipmentText("MISSING TRANSLATION")
 
 , escapeText("MISSING TRANSLATION")
+, defeatText("MISSING TRANSLATION")
 
 , numberAnimationPrototype(0)
 , bigNumberSprite(0)
@@ -152,6 +153,7 @@ void Resources::CreateTypeDescription() {
        td.AddField("noEquipmentText", FieldDescription(((char *)&r.noEquipmentText) - ((char *)&r), Interpreter::STRING_ID).SetReferenced().SetDescription("text to show for missing equipment"));
 
        td.AddField("escapeText", FieldDescription(((char *)&r.escapeText) - ((char *)&r), Interpreter::STRING_ID).SetReferenced().SetDescription("displayed when the party escapes"));
+       td.AddField("defeatText", FieldDescription(((char *)&r.defeatText) - ((char *)&r), Interpreter::STRING_ID).SetReferenced().SetDescription("displayed when the party was defeated"));
 
        td.AddField("numberAnimationPrototype", FieldDescription(((char *)&r.numberAnimationPrototype) - ((char *)&r), Animation::TYPE_ID).SetReferenced().SetDescription("animation of an attack's result digit"));
 
index 0a8a1e8db444a618be0cc43a37284f965245051e..6624910a61e37dcf0822e32c2623923c7e3d0bd0 100644 (file)
@@ -62,6 +62,7 @@ struct Resources {
        const char *noEquipmentText;
 
        const char *escapeText;
+       const char *defeatText;
 
        const graphics::Animation *numberAnimationPrototype;
 
diff --git a/src/battle/states/DefeatState.cpp b/src/battle/states/DefeatState.cpp
new file mode 100644 (file)
index 0000000..77b3f8e
--- /dev/null
@@ -0,0 +1,111 @@
+#include "DefeatState.h"
+
+#include "../Battle.h"
+#include "../BattleState.h"
+#include "../Resources.h"
+#include "../../app/Application.h"
+#include "../../app/Input.h"
+#include "../../math/Vector.h"
+#include "../../graphics/ColorFade.h"
+#include "../../graphics/Font.h"
+#include "../../graphics/Frame.h"
+#include "../../sdl/Desaturate.h"
+
+using app::Application;
+using app::Input;
+using graphics::ColorFade;
+using graphics::Font;
+using graphics::Frame;
+using math::Vector;
+using std::vector;
+
+namespace battle {
+
+DefeatState::DefeatState(
+               Battle *battle,
+               BattleState *parent)
+: battle(battle)
+, parent(parent)
+, cache(0)
+, format(0) {
+
+}
+
+
+void DefeatState::OnEnterState(SDL_Surface *screen) {
+       timer = GraphicsTimers().StartCountdown(1500);
+       format = screen->format;
+       OnResize(screen->w, screen->h);
+}
+
+void DefeatState::OnExitState(SDL_Surface *screen) {
+       if (cache) {
+               SDL_FreeSurface(cache);
+               cache = 0;
+       }
+}
+
+void DefeatState::OnResumeState(SDL_Surface *screen) {
+
+}
+
+void DefeatState::OnPauseState(SDL_Surface *screen) {
+
+}
+
+
+void DefeatState::OnResize(int width, int height) {
+       const Resources &res = parent->Res();
+       const Frame &frame = *res.titleFrame;
+       const Font &font = *res.titleFont;
+
+       framePosition = parent->ScreenOffset();
+       frameSize = Vector<int> (
+                       parent->Width(),
+                       frame.BorderHeight() * 2 + font.CharHeight());
+
+       textPosition = Vector<int>(
+                       (parent->Width() - strlen(res.defeatText) * font.CharWidth()) / 2,
+                       frame.BorderHeight());
+
+       parent->Resize(width, height);
+       if (cache) {
+               SDL_FreeSurface(cache);
+       }
+       cache = SDL_CreateRGBSurface(0, width, height, format->BitsPerPixel,
+                       format->Rmask, format->Gmask, format->Bmask, format->Amask);
+       parent->Render(cache);
+       parent->RenderHeroes(cache);
+       RenderTitleBar(cache);
+}
+
+
+void DefeatState::HandleEvents(const Input &input) {
+       if (timer.Finished()) {
+               Ctrl().PopState();
+       }
+}
+
+
+void DefeatState::UpdateWorld(Uint32 deltaT) {
+
+}
+
+void DefeatState::Render(SDL_Surface *screen) {
+       if (screen->format->palette
+                       || cache->format->palette) {
+               // I refuse to desaturate an indexed color urface
+               SDL_BlitSurface(cache, 0, screen, 0);
+               return;
+       }
+
+       sdl::Desaturate(cache, screen, timer.Remaining() * 255 / 1500);
+}
+
+void DefeatState::RenderTitleBar(SDL_Surface *screen) {
+       const Resources &res = parent->Res();
+       res.titleFrame->Draw(screen, framePosition, frameSize.X(), frameSize.Y());
+       res.titleFont->DrawString(res.defeatText, screen, textPosition);
+}
+
+}
diff --git a/src/battle/states/DefeatState.h b/src/battle/states/DefeatState.h
new file mode 100644 (file)
index 0000000..998bff4
--- /dev/null
@@ -0,0 +1,54 @@
+#ifndef BATTLE_DEFEATSTATE_H_
+#define BATTLE_DEFEATSTATE_H_
+
+namespace battle {
+       class Battle;
+       class BattleState;
+}
+
+#include "../../app/State.h"
+#include "../../math/Vector.h"
+
+#include <SDL.h>
+
+namespace battle {
+
+class DefeatState
+: public app::State {
+
+public:
+       DefeatState(
+                       Battle *battle,
+                       BattleState *parent);
+
+public:
+       virtual void HandleEvents(const app::Input &);
+       virtual void UpdateWorld(Uint32 deltaT);
+       virtual void Render(SDL_Surface *);
+
+private:
+       virtual void OnEnterState(SDL_Surface *screen);
+       virtual void OnExitState(SDL_Surface *screen);
+       virtual void OnResumeState(SDL_Surface *screen);
+       virtual void OnPauseState(SDL_Surface *screen);
+
+       virtual void OnResize(int width, int height);
+
+private:
+       void RenderTitleBar(SDL_Surface *screen);
+
+private:
+       Battle *battle;
+       BattleState *parent;
+       SDL_Surface *cache;
+       SDL_PixelFormat *format;
+       app::Timer<Uint32> timer;
+       math::Vector<int> framePosition;
+       math::Vector<int> frameSize;
+       math::Vector<int> textPosition;
+
+};
+
+}
+
+#endif
diff --git a/src/sdl/Desaturate.cpp b/src/sdl/Desaturate.cpp
new file mode 100644 (file)
index 0000000..175e1b9
--- /dev/null
@@ -0,0 +1,127 @@
+#include "Desaturate.h"
+
+#include <stdexcept>
+
+using std::runtime_error;
+
+
+namespace sdl {
+
+template<typename SrcType, typename DestType>
+void DesaturatePixel(
+               SrcType *src, SDL_PixelFormat *srcFmt,
+               DestType *dest, SDL_PixelFormat *destFmt,
+               Uint8 amount) {
+
+       Uint8 srcRed = (((*src) & srcFmt->Rmask)
+                       >> srcFmt->Rshift) << srcFmt->Rloss;
+       Uint8 srcGreen = (((*src) & srcFmt->Gmask)
+                       >> srcFmt->Gshift) << srcFmt->Gloss;
+       Uint8 srcBlue = (((*src) & srcFmt->Bmask)
+                       >> srcFmt->Bshift) << srcFmt->Bloss;
+
+       Uint8 srcGrey = (srcRed * 76 + srcGreen * 150 + srcBlue * 29) / 255;
+
+       Uint8 destRed = (srcRed * amount + srcGrey * (255 - amount)) / 255;
+       Uint8 destGreen = (srcGreen * amount + srcGrey * (255 - amount)) / 255;
+       Uint8 destBlue = (srcBlue * amount + srcGrey * (255 - amount)) / 255;
+
+       *dest
+               = ((destRed >> destFmt->Rloss) << destFmt->Rshift)
+               | ((destGreen >> destFmt->Gloss) << destFmt->Gshift)
+               | ((destBlue >> destFmt->Bloss) << destFmt->Bshift)
+               | (*dest & destFmt->Amask);
+}
+
+void Desaturate(
+               SDL_Surface *src,
+               SDL_Surface *dest,
+               Uint8 amount) {
+       Uint32 size = src->w * src->h;
+       SDL_LockSurface(src);
+       SDL_LockSurface(dest);
+       SDL_PixelFormat *srcFmt = src->format;
+       SDL_PixelFormat *destFmt = dest->format;
+       Uint8 srcBPP = srcFmt->BytesPerPixel;
+       Uint8 destBPP = destFmt->BytesPerPixel;
+       switch (srcBPP) {
+       default:
+               SDL_UnlockSurface(dest);
+               SDL_UnlockSurface(src);
+               throw runtime_error("unable to read src format");
+       case 2: {
+               Uint16 *srcIter = reinterpret_cast<Uint16 *>(
+                               src->pixels);
+               Uint16 *srcEnd = srcIter + size;
+               switch (destBPP) {
+               default:
+                       SDL_UnlockSurface(dest);
+                       SDL_UnlockSurface(src);
+                       throw runtime_error("unable to read src format");
+               case 2: {
+                       Uint16 *destIter = reinterpret_cast<Uint16 *>(
+                                       dest->pixels);
+                       Uint16 *destEnd = destIter + size;
+                       for (;srcIter < srcEnd && destIter < destEnd;
+                                       ++srcIter, ++destIter) {
+                               DesaturatePixel(
+                                               srcIter, srcFmt,
+                                               destIter, destFmt,
+                                               amount);
+                       }
+                       break; }
+               case 4: {
+                       Uint32 *destIter = reinterpret_cast<Uint32 *>(
+                                       dest->pixels);
+                       Uint32 *destEnd = destIter + size;
+                       for (;srcIter < srcEnd && destIter < destEnd;
+                                       ++srcIter, ++destIter) {
+                               DesaturatePixel(
+                                               srcIter, srcFmt,
+                                               destIter, destFmt,
+                                               amount);
+                       }
+                       break; }
+               }
+               break; }
+       case 4: {
+               Uint32 *srcIter = reinterpret_cast<Uint32 *>(
+                               src->pixels);
+               Uint32 *srcEnd = srcIter + size;
+               switch (destBPP) {
+               default:
+                       SDL_UnlockSurface(dest);
+                       SDL_UnlockSurface(src);
+                       throw runtime_error("unable to read src format");
+               case 2: {
+                       Uint16 *destIter = reinterpret_cast<Uint16 *>(
+                                       dest->pixels);
+                       Uint16 *destEnd = destIter + size;
+                       for (;srcIter < srcEnd && destIter < destEnd;
+                                       ++srcIter, ++destIter) {
+                               DesaturatePixel(
+                                               srcIter, srcFmt,
+                                               destIter, destFmt,
+                                               amount);
+                       }
+                       break; }
+               case 4: {
+                       Uint32 *destIter = reinterpret_cast<Uint32 *>(
+                                       dest->pixels);
+                       Uint32 *destEnd = destIter + size;
+                       for (;srcIter < srcEnd && destIter < destEnd;
+                                       ++srcIter, ++destIter) {
+                               DesaturatePixel(
+                                               srcIter, srcFmt,
+                                               destIter, destFmt,
+                                               amount);
+                       }
+                       break; }
+               }
+               break; }
+       }
+       SDL_UnlockSurface(dest);
+       SDL_UnlockSurface(src);
+}
+
+}
diff --git a/src/sdl/Desaturate.h b/src/sdl/Desaturate.h
new file mode 100644 (file)
index 0000000..45dff7c
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef SDL_DESATURATE_H_
+#define SDL_DESATURATE_H_
+
+#include <SDL.h>
+
+namespace sdl {
+
+/// Copy src to dest, desaturated by amount/255.
+void Desaturate(
+               SDL_Surface *src,
+               SDL_Surface *dest,
+               Uint8 amount);
+
+}
+
+#endif
index 500039f8e5756048daf9638b3fca42c40f994483..59de5240c90524a28cdcef31b4200c4ff51de2a8 100644 (file)
@@ -651,6 +651,7 @@ export BattleResources battleResources {
        noEquipmentText: "No equip",
 
        escapeText: "Escapes.",
+       defeatText: "Total Defeat.",
 
        victoryGetsText: "Gets",
        victoryExpText: "EXP",