Skip to content

Commit

Permalink
Darken background drawing to improve player/enemy/item visibility
Browse files Browse the repository at this point in the history
Based on Calinou's request and WIP branch, this improves the game's accessibility by adding an option that emphasizes dynamic objects in the game. ( Issue lethal-guitar#833 )
  • Loading branch information
Nutzzz authored and lethal-guitar committed Oct 14, 2022
1 parent f16fea1 commit 88b1f3b
Show file tree
Hide file tree
Showing 11 changed files with 232 additions and 30 deletions.
13 changes: 13 additions & 0 deletions src/data/game_options.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ namespace rigel::data
constexpr auto ENABLE_VSYNC_DEFAULT = true;
constexpr auto MUSIC_VOLUME_DEFAULT = 1.0f;
constexpr auto SOUND_VOLUME_DEFAULT = 1.0f;
constexpr auto FOREGROUND_SPRITE_BRIGHTNESS_DEFAULT = 1.0f;
constexpr auto REGULAR_SPRITE_BRIGHTNESS_DEFAULT = 1.0f;
constexpr auto BACKGROUND_SPRITE_BRIGHTNESS_DEFAULT = 1.0f;
constexpr auto FOREGROUND_TILE_BRIGHTNESS_DEFAULT = 1.0f;
constexpr auto BACKGROUND_TILE_BRIGHTNESS_DEFAULT = 1.0f;
constexpr auto BACKDROP_TILE_BRIGHTNESS_DEFAULT = 1.0f;

enum class WindowMode
{
Expand Down Expand Up @@ -156,6 +162,13 @@ struct GameOptions
bool mQuickSavingEnabled = false;
bool mSkipIntro = false;
bool mMotionSmoothing = false;
float mForeSpriteBrightness = FOREGROUND_SPRITE_BRIGHTNESS_DEFAULT;
float mRegSpriteBrightness = REGULAR_SPRITE_BRIGHTNESS_DEFAULT;
float mBackSpriteBrightness = BACKGROUND_SPRITE_BRIGHTNESS_DEFAULT;
bool mPrisonerIsBackground = false;
float mForeTileBrightness = FOREGROUND_TILE_BRIGHTNESS_DEFAULT;
float mBackTileBrightness = BACKGROUND_TILE_BRIGHTNESS_DEFAULT;
float mDropTileBrightness = BACKDROP_TILE_BRIGHTNESS_DEFAULT;

// Internal options
//
Expand Down
40 changes: 36 additions & 4 deletions src/engine/map_renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,17 +287,39 @@ void MapRenderer::switchBackdrops()

void MapRenderer::renderBackground(
const base::Vec2& sectionStart,
const base::Size& sectionSize) const
const base::Size& sectionSize,
const float backColorMod) const
{
if (backColorMod < 1.0f)
{
// const auto saved = renderer::saveState(mpRenderer);
mpRenderer->setColorModulation(base::Color{
base::roundTo<uint8_t, float>(255 * backColorMod),
base::roundTo<uint8_t, float>(255 * backColorMod),
base::roundTo<uint8_t, float>(255 * backColorMod),
255});
}
renderMapTiles(sectionStart, sectionSize, DrawMode::Background);
mpRenderer->setColorModulation(base::Color{255, 255, 255, 255});
}


void MapRenderer::renderForeground(
const base::Vec2& sectionStart,
const base::Size& sectionSize) const
const base::Size& sectionSize,
const float foreColorMod) const
{
if (foreColorMod < 1.0f)
{
// const auto saved = renderer::saveState(mpRenderer);
mpRenderer->setColorModulation(base::Color{
base::roundTo<uint8_t, float>(255 * foreColorMod),
base::roundTo<uint8_t, float>(255 * foreColorMod),
base::roundTo<uint8_t, float>(255 * foreColorMod),
255});
}
renderMapTiles(sectionStart, sectionSize, DrawMode::Foreground);
mpRenderer->setColorModulation(base::Color{255, 255, 255, 255});
}


Expand Down Expand Up @@ -397,14 +419,24 @@ renderer::TexCoords MapRenderer::calculateBackdropTexCoords(

void MapRenderer::renderBackdrop(
const base::Vec2f& cameraPosition,
const base::Size& viewportSize) const
const base::Size& viewportSize,
const float dropColorMod) const
{
const auto saved = renderer::saveState(mpRenderer);
if (dropColorMod < 1.0f)
{
// const auto saved = renderer::saveState(mpRenderer);
mpRenderer->setColorModulation(base::Color{
base::roundTo<uint8_t, float>(255 * dropColorMod),
base::roundTo<uint8_t, float>(255 * dropColorMod),
base::roundTo<uint8_t, float>(255 * dropColorMod),
255});
}
mpRenderer->setTextureRepeatEnabled(true);
mpRenderer->drawTexture(
mBackdropTexture.data(),
calculateBackdropTexCoords(cameraPosition, viewportSize),
{{}, data::tilesToPixels(viewportSize)});
mpRenderer->setColorModulation(base::Color{255, 255, 255, 255});
}


Expand Down
11 changes: 7 additions & 4 deletions src/engine/map_renderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,16 @@ class MapRenderer

void renderBackdrop(
const base::Vec2f& cameraPosition,
const base::Size& viewportSize) const;
const base::Size& viewportSize,
const float dropColorMod) const;
void renderBackground(
const base::Vec2& sectionStart,
const base::Size& sectionSize) const;
const base::Size& sectionSize,
const float backColorMod) const;
void renderForeground(
const base::Vec2& sectionStart,
const base::Size& sectionSize) const;
const base::Size& sectionSize,
const float foreColorMod) const;

void updateAnimatedMapTiles();
void updateBackdropAutoScrolling(engine::TimeDelta dt);
Expand All @@ -141,7 +144,7 @@ class MapRenderer
void renderMapTiles(
const base::Vec2& sectionStart,
const base::Size& sectionSize,
DrawMode drawMode) const;
const DrawMode drawMode) const;
data::map::TileIndex animatedTileIndex(data::map::TileIndex) const;

private:
Expand Down
55 changes: 43 additions & 12 deletions src/engine/sprite_rendering_system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ void collectVisibleSprites(
using components::DrawTopMost;
using components::ExtendedFrameList;
using components::OverrideDrawOrder;
using components::SpriteBackground;
using components::SpriteStrip;

const auto screenBox = BoundingBox{{}, viewportSize};
Expand All @@ -99,7 +100,8 @@ void collectVisibleSprites(
const bool flashingWhite,
const bool useCloakEffect,
const bool drawTopmost,
const int drawOrder) {
const int drawOrder,
const bool background) {
const auto topLeft = drawPosition(frame, position);

// Discard sprites outside visible area
Expand All @@ -115,8 +117,8 @@ void collectVisibleSprites(
engine::interpolatedPixelPosition(
previousTopLeft, topLeft, interpolationFactor),
data::tilesToPixels(frame.mDimensions)};
const auto drawSpec =
SpriteDrawSpec{destRect, frame.mImageId, flashingWhite, useCloakEffect};
const auto drawSpec = SpriteDrawSpec{
destRect, frame.mImageId, flashingWhite, useCloakEffect, background};

output.push_back({drawSpec, drawOrder, drawTopmost});
};
Expand All @@ -138,6 +140,7 @@ void collectVisibleSprites(
const auto drawOrder = entity.has_component<OverrideDrawOrder>()
? entity.component<const OverrideDrawOrder>()->mDrawOrder
: sprite.mpDrawData->mDrawOrder;
const auto background = entity.has_component<SpriteBackground>();

auto slotIndex = 0;
for (const auto& baseFrameIndex : sprite.mFramesToRender)
Expand All @@ -158,7 +161,8 @@ void collectVisibleSprites(
sprite.mFlashingWhiteStates.test(slotIndex),
sprite.mUseCloakEffect,
drawTopmost,
drawOrder);
drawOrder,
background);
++slotIndex;
}

Expand All @@ -177,7 +181,8 @@ void collectVisibleSprites(
false,
sprite.mUseCloakEffect,
drawTopmost,
drawOrder);
drawOrder,
background);
}
}

Expand Down Expand Up @@ -210,8 +215,8 @@ void collectVisibleSprites(
base::Rect<int>{data::tilesToPixels(topLeft), {width, height}};

const auto useCloakEffect = sprite.mUseCloakEffect;
const auto drawSpec =
SpriteDrawSpec{destRect, frame.mImageId, false, useCloakEffect};
const auto drawSpec = SpriteDrawSpec{
destRect, frame.mImageId, false, useCloakEffect, background};
output.push_back({drawSpec, drawOrder, drawTopmost});
}
});
Expand Down Expand Up @@ -354,29 +359,45 @@ void SpriteRenderingSystem::update(
}


void SpriteRenderingSystem::renderBackgroundSprites(
const SpecialEffectsRenderer& fx,
const float backColorMod) const
{
for (auto it = mSprites.begin(); it != miForegroundSprites; ++it)
{
if (it->mBackground)
renderSprite(*it, fx, backColorMod);
}
}


void SpriteRenderingSystem::renderRegularSprites(
const SpecialEffectsRenderer& fx) const
const SpecialEffectsRenderer& fx,
const float regColorMod) const
{
for (auto it = mSprites.begin(); it != miForegroundSprites; ++it)
{
renderSprite(*it, fx);
if (!(it->mBackground))
renderSprite(*it, fx, regColorMod);
}
}


void SpriteRenderingSystem::renderForegroundSprites(
const SpecialEffectsRenderer& fx) const
const SpecialEffectsRenderer& fx,
const float foreColorMod) const
{
for (auto it = miForegroundSprites; it != mSprites.end(); ++it)
{
renderSprite(*it, fx);
renderSprite(*it, fx, foreColorMod);
}
}


void SpriteRenderingSystem::renderSprite(
const SpriteDrawSpec& spec,
const SpecialEffectsRenderer& fx) const
const SpecialEffectsRenderer& fx,
const float colorMod) const
{
// White flash takes priority over translucency
if (spec.mIsFlashingWhite)
Expand All @@ -393,7 +414,17 @@ void SpriteRenderingSystem::renderSprite(
}
else
{
if (colorMod < 1.0f)
{
// const auto saved = renderer::saveState(mpRenderer);
mpRenderer->setColorModulation(base::Color{
base::roundTo<uint8_t, float>(255 * colorMod),
base::roundTo<uint8_t, float>(255 * colorMod),
base::roundTo<uint8_t, float>(255 * colorMod),
255});
}
mpTextureAtlas->draw(spec.mImageId, spec.mDestRect);
mpRenderer->setColorModulation(base::Color{255, 255, 255, 255});
}
}

Expand Down
15 changes: 12 additions & 3 deletions src/engine/sprite_rendering_system.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ struct SpriteDrawSpec
int mImageId;
bool mIsFlashingWhite;
bool mUseCloakEffect;
bool mBackground;
};


Expand Down Expand Up @@ -90,13 +91,21 @@ class SpriteRenderingSystem

bool cloakEffectSpritesVisible() const { return mCloakEffectSpritesVisible; }

void renderRegularSprites(const SpecialEffectsRenderer& fx) const;
void renderForegroundSprites(const SpecialEffectsRenderer& fx) const;
void renderBackgroundSprites(
const SpecialEffectsRenderer& fx,
const float backColorMod) const;
void renderRegularSprites(
const SpecialEffectsRenderer& fx,
const float regColorMod) const;
void renderForegroundSprites(
const SpecialEffectsRenderer& fx,
const float foreColorMod) const;

private:
void renderSprite(
const SpriteDrawSpec& spec,
const SpecialEffectsRenderer& fx) const;
const SpecialEffectsRenderer& fx,
const float colorMod) const;

// Temporary storage used for sorting sprites by draw order during sprite
// collection. Scope-wise, this is only needed during update(), but in order
Expand Down
6 changes: 6 additions & 0 deletions src/engine/visual_components.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ struct Sprite
std::bitset<NUM_RENDER_SLOTS> mFlashingWhiteStates;
bool mUseCloakEffect = false;
bool mShow = true;
bool mBackground = false;
};


Expand All @@ -203,6 +204,11 @@ struct ExtendedFrameList
};


struct SpriteBackground
{
};


struct SpriteStrip
{
explicit SpriteStrip(const base::Vec2& start, int frame)
Expand Down
21 changes: 21 additions & 0 deletions src/frontend/user_profile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,13 @@ nlohmann::ordered_json serialize(const data::GameOptions& options)
serialized["quickSavingEnabled"] = options.mQuickSavingEnabled;
serialized["skipIntro"] = options.mSkipIntro;
serialized["motionSmoothing"] = options.mMotionSmoothing;
serialized["foregroundSpriteBrightness"] = options.mForeSpriteBrightness;
serialized["regularSpriteBrightness"] = options.mRegSpriteBrightness;
serialized["backgroundSpriteBrightness"] = options.mBackSpriteBrightness;
serialized["prisonerIsBackground"] = options.mPrisonerIsBackground;
serialized["foregroundTileBrightness"] = options.mForeTileBrightness;
serialized["backgroundTileBrightness"] = options.mBackTileBrightness;
serialized["parallaxTileBrightness"] = options.mDropTileBrightness;
return serialized;
}

Expand Down Expand Up @@ -661,6 +668,20 @@ data::GameOptions deserialize<data::GameOptions>(const nlohmann::json& json)
extractValueIfExists("quickSavingEnabled", result.mQuickSavingEnabled, json);
extractValueIfExists("skipIntro", result.mSkipIntro, json);
extractValueIfExists("motionSmoothing", result.mMotionSmoothing, json);
extractValueIfExists(
"foregroundSpriteBrightness", result.mForeSpriteBrightness, json);
extractValueIfExists(
"regularSpriteBrightness", result.mRegSpriteBrightness, json);
extractValueIfExists(
"backgroundSpriteBrightness", result.mBackSpriteBrightness, json);
extractValueIfExists(
"prisonerIsBackground", result.mPrisonerIsBackground, json);
extractValueIfExists(
"foregroundTileBrightness", result.mForeTileBrightness, json);
extractValueIfExists(
"backgroundTileBrightness", result.mBackTileBrightness, json);
extractValueIfExists(
"parallaxTileBrightness", result.mDropTileBrightness, json);

removeInvalidKeybindings(result);

Expand Down
6 changes: 6 additions & 0 deletions src/game_logic/entity_configuration.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -1669,13 +1669,17 @@ void EntityFactory::configureEntity(
entity.component<Shootable>()->mInvincible = true;
entity.component<Shootable>()->mDestroyWhenKilled = false;
entity.assign<AppearsOnRadar>();
if (mpOptions->mPrisonerIsBackground)
entity.assign<SpriteBackground>();
break;

case ActorID::Passive_prisoner: // Monster in prison cell, passive
entity.assign<BehaviorController>(behaviors::PassivePrisoner{});
entity.assign<BoundingBox>(boundingBox);
entity.assign<ActivationSettings>(ActivationSettings::Policy::Always);
entity.assign<AppearsOnRadar>();
if (mpOptions->mPrisonerIsBackground)
entity.assign<SpriteBackground>();
break;

case ActorID::Rigelatin_soldier: // Rigelatin soldier
Expand Down Expand Up @@ -1917,6 +1921,7 @@ void EntityFactory::configureEntity(
case ActorID::Water_on_floor_1: // Shallow water (variant 1)
case ActorID::Water_on_floor_2: // Shallow water (variant 2)
entity.assign<AnimationLoop>(1);
entity.assign<SpriteBackground>();
break;

case ActorID::Messenger_drone_1: // "Your brain is ours!"
Expand Down Expand Up @@ -1961,6 +1966,7 @@ void EntityFactory::configureEntity(
case ActorID::Flame_jet_3: // Small rocket exhaust flame left
case ActorID::Flame_jet_4: // Small rocket exhaust flame right
entity.assign<AnimationLoop>(2);
entity.assign<SpriteBackground>();
break;

case ActorID::Exit_trigger:
Expand Down
Loading

0 comments on commit 88b1f3b

Please sign in to comment.