From cccda573516f3bce30efbaba3fc20e4148d3cdc8 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Tue, 7 Aug 2012 20:00:08 +0200 Subject: [PATCH] added Frame class for drawing bordered windows --- Debug/src/graphics/subdir.mk | 3 + Release/src/graphics/subdir.mk | 3 + src/battle/BattleState.cpp | 2 +- src/battle/BattleState.h | 11 +++- src/battle/HeroTag.cpp | 23 ++----- src/battle/HeroTag.h | 7 ++- src/graphics/Frame.cpp | 108 +++++++++++++++++++++++++++++++++ src/graphics/Frame.h | 41 +++++++++++++ src/graphics/Sprite.cpp | 8 +-- src/graphics/Sprite.h | 6 +- src/main.cpp | 7 ++- test-data/tag-frames.png | Bin 0 -> 197 bytes 12 files changed, 191 insertions(+), 28 deletions(-) create mode 100644 src/graphics/Frame.cpp create mode 100644 src/graphics/Frame.h create mode 100644 test-data/tag-frames.png diff --git a/Debug/src/graphics/subdir.mk b/Debug/src/graphics/subdir.mk index 63083ec..b7c5c2d 100644 --- a/Debug/src/graphics/subdir.mk +++ b/Debug/src/graphics/subdir.mk @@ -4,12 +4,15 @@ # Add inputs and outputs from these tool invocations to the build variables CPP_SRCS += \ +../src/graphics/Frame.cpp \ ../src/graphics/Sprite.cpp OBJS += \ +./src/graphics/Frame.o \ ./src/graphics/Sprite.o CPP_DEPS += \ +./src/graphics/Frame.d \ ./src/graphics/Sprite.d diff --git a/Release/src/graphics/subdir.mk b/Release/src/graphics/subdir.mk index 6325d12..1471b9c 100644 --- a/Release/src/graphics/subdir.mk +++ b/Release/src/graphics/subdir.mk @@ -4,12 +4,15 @@ # Add inputs and outputs from these tool invocations to the build variables CPP_SRCS += \ +../src/graphics/Frame.cpp \ ../src/graphics/Sprite.cpp OBJS += \ +./src/graphics/Frame.o \ ./src/graphics/Sprite.o CPP_DEPS += \ +./src/graphics/Frame.d \ ./src/graphics/Sprite.d diff --git a/src/battle/BattleState.cpp b/src/battle/BattleState.cpp index 30a33b6..36c1997 100644 --- a/src/battle/BattleState.cpp +++ b/src/battle/BattleState.cpp @@ -50,7 +50,7 @@ void BattleState::EnterState(Application &ctrl, SDL_Surface *screen) { heroesLayout->CalculatePositions(background->w, background->h, heroesPositions); attackChoices.resize(heroes.size()); for (vector::size_type i(0), end(heroes.size()); i < end; ++i) { - heroTags.push_back(HeroTag(&heroes[i], &attackChoices[i], HeroTag::Alignment((i + 1) % 2))); + heroTags.push_back(HeroTag(&heroes[i], &attackChoices[i], heroTagFrame, activeHeroTagFrame, HeroTag::Alignment((i + 1) % 2))); } } diff --git a/src/battle/BattleState.h b/src/battle/BattleState.h index 42094d6..f4f8bc1 100644 --- a/src/battle/BattleState.h +++ b/src/battle/BattleState.h @@ -22,7 +22,10 @@ #include namespace app { class Input; } -namespace graphics { class Sprite; } +namespace graphics { + class Frame; + class Sprite; +} namespace battle { @@ -32,10 +35,12 @@ class BattleState : public app::State { public: - BattleState(SDL_Surface *background, const PartyLayout &monstersLayout, const PartyLayout &heroesLayout, const graphics::Sprite *attackIcons, const graphics::Sprite *moveIcons) + BattleState(SDL_Surface *background, const PartyLayout &monstersLayout, const PartyLayout &heroesLayout, const graphics::Sprite *attackIcons, const graphics::Sprite *moveIcons, const graphics::Frame *heroTagFrame, const graphics::Frame *activeHeroTagFrame) : background(background) , monstersLayout(&monstersLayout) , heroesLayout(&heroesLayout) + , heroTagFrame(heroTagFrame) + , activeHeroTagFrame(activeHeroTagFrame) , attackTypeMenu(attackIcons) , moveMenu(moveIcons) , activeHero(-1) { } @@ -84,6 +89,8 @@ private: SDL_Surface *background; const PartyLayout *monstersLayout; const PartyLayout *heroesLayout; + const graphics::Frame *heroTagFrame; + const graphics::Frame *activeHeroTagFrame; AttackTypeMenu attackTypeMenu; MoveMenu moveMenu; std::vector > monsterPositions; diff --git a/src/battle/HeroTag.cpp b/src/battle/HeroTag.cpp index 713fb8f..0b7aa27 100644 --- a/src/battle/HeroTag.cpp +++ b/src/battle/HeroTag.cpp @@ -10,6 +10,7 @@ #include "Hero.h" #include "../geometry/operators.h" #include "../geometry/Vector.h" +#include "../graphics/Frame.h" #include "../graphics/Sprite.h" using geometry::Point; @@ -18,23 +19,11 @@ using geometry::Vector; namespace battle { void HeroTag::Render(SDL_Surface *screen, int width, int height, Point position, bool active) const { - SDL_Rect destRect; - destRect.x = position.X(); - destRect.y = position.Y(); - destRect.w = width; - destRect.h = height; - - destRect.x += 1; - destRect.y += 1; - destRect.w -= 2; - destRect.h -= 2; - SDL_FillRect(screen, &destRect, SDL_MapRGB(screen->format, 0xFF, active ? 0 : 0xFF, active ? 0 : 0xFF)); - - destRect.x += 1; - destRect.y += 1; - destRect.w -= 2; - destRect.h -= 2; - SDL_FillRect(screen, &destRect, SDL_MapRGB(screen->format, 0, 0, 0)); + if (active) { + activeFrame->Draw(screen, position, width, height); + } else { + frame->Draw(screen, position, width, height); + } Vector heroOffset( (align == LEFT) ? 3 : width - hero->Sprite()->Width() - 3, diff --git a/src/battle/HeroTag.h b/src/battle/HeroTag.h index 3e42edd..6799e94 100644 --- a/src/battle/HeroTag.h +++ b/src/battle/HeroTag.h @@ -12,6 +12,8 @@ #include +namespace graphics { class Frame; } + namespace battle { class AttackChoice; @@ -26,7 +28,8 @@ public: }; public: - HeroTag(const Hero *hero, const AttackChoice *choice, Alignment align) : hero(hero), choice(choice), align(align) { } + HeroTag(const Hero *hero, const AttackChoice *choice, const graphics::Frame *frame, const graphics::Frame *activeFrame, Alignment align) + : hero(hero), choice(choice), frame(frame), activeFrame(activeFrame), align(align) { } ~HeroTag() { } public: @@ -35,6 +38,8 @@ public: private: const Hero *hero; const AttackChoice *choice; + const graphics::Frame *frame; + const graphics::Frame *activeFrame; Alignment align; }; diff --git a/src/graphics/Frame.cpp b/src/graphics/Frame.cpp new file mode 100644 index 0000000..ac394d1 --- /dev/null +++ b/src/graphics/Frame.cpp @@ -0,0 +1,108 @@ +/* + * Frame.cpp + * + * Created on: Aug 7, 2012 + * Author: holy + */ + +#include "Frame.h" + +using geometry::Point; + +namespace graphics { + +// TODO: maybe create a cache for frames? +void Frame::Draw(SDL_Surface *dest, Point position, int width, int height) const { + // top-left corner + SDL_Rect srcRect; + srcRect.x = xOffset; + srcRect.y = yOffset; + srcRect.w = borderWidth; + srcRect.h = borderHeight; + SDL_Rect destRect; + destRect.x = position.X(); + destRect.y = position.Y(); + SDL_BlitSurface(surface, &srcRect, dest, &destRect); + + // top border + srcRect.x += borderWidth; + srcRect.w = repeatWidth; + destRect.x += borderWidth; + int fullRepeatWidth(width - (2 * borderWidth)); + int repeatCursor(0); + while (repeatCursor < fullRepeatWidth) { + SDL_BlitSurface(surface, &srcRect, dest, &destRect); + destRect.x += repeatWidth; + repeatCursor += repeatWidth; + } + + // top-right corner + srcRect.x += repeatWidth; + srcRect.w = borderWidth; + SDL_BlitSurface(surface, &srcRect, dest, &destRect); + + // middle + destRect.y += borderHeight; + int fullRepeatHeight(height - (2 * borderHeight)); + int hRepeatCursor(0); + while (hRepeatCursor < fullRepeatHeight) { + + // left border + srcRect.x = xOffset; + srcRect.y = yOffset + borderHeight; + srcRect.w = borderWidth; + srcRect.h = repeatHeight; + destRect.x = position.X(); + SDL_BlitSurface(surface, &srcRect, dest, &destRect); + + // fill + repeatCursor = 0; + srcRect.x += borderWidth; + srcRect.w = repeatWidth; + destRect.x += borderWidth; + while (repeatCursor < fullRepeatWidth) { + SDL_BlitSurface(surface, &srcRect, dest, &destRect); + destRect.x += repeatWidth; + repeatCursor += repeatWidth; + } + + // right border + srcRect.x += repeatWidth; + srcRect.w = borderWidth; + SDL_BlitSurface(surface, &srcRect, dest, &destRect); + + destRect.y += repeatHeight; + hRepeatCursor += repeatHeight; + } + + // bottom-left corner + srcRect.x = xOffset; + srcRect.y = yOffset + borderHeight + repeatHeight; + srcRect.w = borderWidth; + srcRect.h = borderHeight; + destRect.x = position.X(); + SDL_BlitSurface(surface, &srcRect, dest, &destRect); + + // bottom border + srcRect.x += borderWidth; + srcRect.w = repeatWidth; + destRect.x += borderWidth; + repeatCursor = 0; + while (repeatCursor < fullRepeatWidth) { + SDL_BlitSurface(surface, &srcRect, dest, &destRect); + destRect.x += repeatWidth; + repeatCursor += repeatWidth; + } + if (fullRepeatWidth < fullRepeatWidth) { + srcRect.w = fullRepeatWidth - fullRepeatWidth; + SDL_BlitSurface(surface, &srcRect, dest, &destRect); + destRect.x += fullRepeatWidth - fullRepeatWidth; + } + + // bottom-right corner + srcRect.x += repeatWidth; + srcRect.w = borderWidth; + SDL_BlitSurface(surface, &srcRect, dest, &destRect); +} + +} diff --git a/src/graphics/Frame.h b/src/graphics/Frame.h new file mode 100644 index 0000000..0f1287c --- /dev/null +++ b/src/graphics/Frame.h @@ -0,0 +1,41 @@ +/* + * Frame.h + * + * Created on: Aug 7, 2012 + * Author: holy + */ + +#ifndef GRAPHICS_FRAME_H_ +#define GRAPHICS_FRAME_H_ + +#include "../geometry/Point.h" + +#include + +namespace graphics { + +class Frame { + +public: + Frame(SDL_Surface *s, int borderWidth, int borderHeight, int repeatWidth = 1, int repeatHeight = 1, int xOffset = 0, int yOffset = 0) + : surface(s), borderWidth(borderWidth), borderHeight(borderHeight), repeatWidth(repeatWidth), repeatHeight(repeatHeight), xOffset(xOffset), yOffset(yOffset) { } + +public: + int MinWidth() const { return 2 * borderWidth; } + int MinHeight() const { return 2 * borderHeight; } + void Draw(SDL_Surface *dest, geometry::Point position, int width, int height) const; + +private: + SDL_Surface *surface; + int borderWidth; + int borderHeight; + int repeatWidth; + int repeatHeight; + int xOffset; + int yOffset; + +}; + +} + +#endif /* GRAPHICS_FRAME_H_ */ diff --git a/src/graphics/Sprite.cpp b/src/graphics/Sprite.cpp index 5b974bd..363be11 100644 --- a/src/graphics/Sprite.cpp +++ b/src/graphics/Sprite.cpp @@ -13,17 +13,17 @@ namespace graphics { void Sprite::Draw(SDL_Surface *dest, Point position, int col, int row) const { SDL_Rect srcRect, destRect; - srcRect.x = col * Width(); - srcRect.y = row * Height(); + srcRect.x = xOffset + col * Width(); + srcRect.y = yOffset + row * Height(); srcRect.w = Width(); srcRect.h = Height(); destRect.x = position.X(); destRect.y = position.Y(); - destRect.w = Width(); - destRect.h = Height(); if (surface) { SDL_BlitSurface(surface, &srcRect, dest, &destRect); } else { + destRect.w = Width(); + destRect.h = Height(); bool red(true); while (destRect.w > 1 && destRect.h > 1) { SDL_FillRect(dest, &destRect, SDL_MapRGB(dest->format, red ? 0xFF : 0, 0, 0)); diff --git a/src/graphics/Sprite.h b/src/graphics/Sprite.h index 475d863..202b96f 100644 --- a/src/graphics/Sprite.h +++ b/src/graphics/Sprite.h @@ -17,8 +17,8 @@ namespace graphics { class Sprite { public: - Sprite(SDL_Surface *s, int width, int height) - : surface(s), width(width), height(height) { } + Sprite(SDL_Surface *s, int width, int height, int xOffset = 0, int yOffset = 0) + : surface(s), width(width), height(height), xOffset(xOffset), yOffset(yOffset) { } public: int Width() const { return width; } @@ -35,6 +35,8 @@ private: SDL_Surface *surface; int width; int height; + int xOffset; + int yOffset; }; diff --git a/src/main.cpp b/src/main.cpp index 8077843..767464b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -12,6 +12,7 @@ #include "battle/Monster.h" #include "battle/PartyLayout.h" #include "geometry/Point.h" +#include "graphics/Frame.h" #include "graphics/Sprite.h" #include "sdl/InitImage.h" #include "sdl/InitScreen.h" @@ -29,6 +30,7 @@ using battle::Hero; using battle::Monster; using battle::PartyLayout; using geometry::Point; +using graphics::Frame; using graphics::Sprite; using sdl::InitImage; using sdl::InitScreen; @@ -82,8 +84,11 @@ int main(int argc, char **argv) { Sprite attackIconsSprite(attackIcons, 32, 32); SDL_Surface *moveIcons(IMG_Load("test-data/move-icons.png")); Sprite moveIconsSprite(moveIcons, 32, 32); + SDL_Surface *tagFrames(IMG_Load("test-data/tag-frames.png")); + Frame heroTagFrame(tagFrames, 8, 8, 1, 1, 17); + Frame activeHeroTagFrame(tagFrames, 8, 8); - BattleState *battleState(new BattleState(bg, monstersLayout, heroesLayout, &attackIconsSprite, &moveIconsSprite)); + BattleState *battleState(new BattleState(bg, monstersLayout, heroesLayout, &attackIconsSprite, &moveIconsSprite, &heroTagFrame, &activeHeroTagFrame)); battleState->AddMonster(monster); battleState->AddMonster(monster); battleState->AddMonster(monster); diff --git a/test-data/tag-frames.png b/test-data/tag-frames.png new file mode 100644 index 0000000000000000000000000000000000000000..6387c4da0a7e0e4a56b004f4af28c1bc057fa564 GIT binary patch literal 197 zcmeAS@N?(olHy`uVBq!ia0vp^DnKm6!3HFam1{JBRF9{NV~EG`vz8t{IK3@l-+`yU z#m&!|dt^wMJ>b?XiBIO1Omfb;&?+D-CvUQ6N8vukxxRb~uKL{bSZ+3GpYmW`@!W_ayRR?yizc0ahomg%*wzp|3;|aarQY=fbL@OboFyt=akR{0FApua{vGU literal 0 HcmV?d00001 -- 2.39.2