Added obscured/scratched window puzzle

This commit is contained in:
Mathew Velasquez 2016-01-28 23:32:29 -05:00
parent 71b2187e50
commit ba0203169e
22 changed files with 324 additions and 28 deletions

View File

@ -26,6 +26,19 @@ RB_METHOD(oneshotMsgBox)
return rb_bool_new(shState->oneshot().msgbox(type, body, title)); return rb_bool_new(shState->oneshot().msgbox(type, body, title));
} }
RB_METHOD(oneshotResetObscured)
{
RB_UNUSED_PARAM;
shState->oneshot().resetObscured();
return Qnil;
}
RB_METHOD(oneshotObscuredCleared)
{
RB_UNUSED_PARAM;
return shState->oneshot().obscuredCleared() ? Qtrue : Qfalse;
}
void oneshotBindingInit() void oneshotBindingInit()
{ {
VALUE module = rb_define_module("Oneshot"); VALUE module = rb_define_module("Oneshot");
@ -43,4 +56,6 @@ void oneshotBindingInit()
//Functions //Functions
_rb_define_module_function(module, "set_yes_no", oneshotSetYesNo); _rb_define_module_function(module, "set_yes_no", oneshotSetYesNo);
_rb_define_module_function(module, "msgbox", oneshotMsgBox); _rb_define_module_function(module, "msgbox", oneshotMsgBox);
_rb_define_module_function(module, "reset_obscured", oneshotResetObscured);
_rb_define_module_function(module, "obscured_cleared?", oneshotObscuredCleared);
} }

View File

@ -69,6 +69,7 @@ DEF_PROP_F(Sprite, Angle)
DEF_PROP_F(Sprite, WavePhase) DEF_PROP_F(Sprite, WavePhase)
DEF_PROP_B(Sprite, Mirror) DEF_PROP_B(Sprite, Mirror)
DEF_PROP_B(Sprite, Obscured)
RB_METHOD(spriteWidth) RB_METHOD(spriteWidth)
{ {
@ -121,6 +122,7 @@ spriteBindingInit()
INIT_PROP_BIND( Sprite, BlendType, "blend_type" ); INIT_PROP_BIND( Sprite, BlendType, "blend_type" );
INIT_PROP_BIND( Sprite, Color, "color" ); INIT_PROP_BIND( Sprite, Color, "color" );
INIT_PROP_BIND( Sprite, Tone, "tone" ); INIT_PROP_BIND( Sprite, Tone, "tone" );
INIT_PROP_BIND( Sprite, Obscured, "obscured" );
if (rgssVer >= 2) if (rgssVer >= 2)
{ {

View File

@ -242,6 +242,7 @@ EMBED = \
shader/simpleAlpha.frag \ shader/simpleAlpha.frag \
shader/simpleAlphaUni.frag \ shader/simpleAlphaUni.frag \
shader/flashMap.frag \ shader/flashMap.frag \
shader/obscured.frag \
shader/minimal.vert \ shader/minimal.vert \
shader/simple.vert \ shader/simple.vert \
shader/simpleColor.vert \ shader/simpleColor.vert \

View File

@ -7,8 +7,8 @@ class Ed_Message
def initialize def initialize
@viewport = Viewport.new(0, 0, 640, 480) @viewport = Viewport.new(0, 0, 640, 480)
@sprite_bg = Sprite.new(@viewport) @sprite_bg = Sprite.new(@viewport)
@sprite_bg.bitmap = RPG::Cache.menu('ed') @sprite_bg.bitmap = Bitmap.new(640, 480)
@sprite_bg.blend_type = 2 @sprite_bg.bitmap.fill_rect(0, 0, 640, 480, Color.new(0, 0, 0, 128))
@sprite_text = Sprite.new(@viewport) @sprite_text = Sprite.new(@viewport)
@contents = Bitmap.new(640, HEIGHT) @contents = Bitmap.new(640, HEIGHT)
@sprite_text.bitmap = @contents @sprite_text.bitmap = @contents

View File

@ -23,10 +23,13 @@ class Game_Map
attr_accessor :battleback_name # battleback file name attr_accessor :battleback_name # battleback file name
attr_accessor :display_x # display x-coordinate * 128 attr_accessor :display_x # display x-coordinate * 128
attr_accessor :display_y # display y-coordinate * 128 attr_accessor :display_y # display y-coordinate * 128
attr_accessor :wrap_x # display x-coordinate * 128 for wrap
attr_accessor :wrap_y # display y-coordinate * 128 for wrap
attr_accessor :need_refresh # refresh request flag attr_accessor :need_refresh # refresh request flag
attr_accessor :bg_name # bg file name attr_accessor :bg_name # bg file name
attr_accessor :particles_type # particles name attr_accessor :particles_type # particles name
attr_accessor :clamped_panorama # panorama is clamped? attr_accessor :clamped_x # panorama is horizontally clamped?
attr_accessor :clamped_y # panorama is vertically clamped?
attr_accessor :wrapping # map is wrapping? attr_accessor :wrapping # map is wrapping?
attr_accessor :ambient # ambient light attr_accessor :ambient # ambient light
attr_reader :passages # passage table attr_reader :passages # passage table
@ -39,10 +42,15 @@ class Game_Map
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
# * List of clamped panorama images # * List of clamped panorama images
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
CLAMPED_PANORAMAS = [ CLAMPED = [
'red', 'red',
'red_distort', 'red_distort',
] ]
CLAMPED_X = [
]
CLAMPED_Y = [
'red_obsdesk',
]
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
# * Object Initialization # * Object Initialization
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
@ -85,6 +93,8 @@ class Game_Map
# Initialize displayed coordinates # Initialize displayed coordinates
@display_x = 0 @display_x = 0
@display_y = 0 @display_y = 0
@wrap_x = 0
@wrap_y = 0
# Clear refresh request flag # Clear refresh request flag
@need_refresh = false @need_refresh = false
# Set map event data # Set map event data
@ -114,7 +124,19 @@ class Game_Map
# Clear particles # Clear particles
@particles_type = nil @particles_type = nil
# Unclamp panorama # Unclamp panorama
@clamped_panorama = CLAMPED_PANORAMAS.include? @panorama_name if CLAMPED.include? @panorama_name
@clamped_x = true
@clamped_y = true
elsif CLAMPED_X.include? @panorama_name
@clamped_x = true
@clamped_y = false
elsif CLAMPED_Y.include? @panorama_name
@clamped_x = false
@clamped_y = true
else
@clamped_x = false
@clamped_y = false
end
# Unwrap map # Unwrap map
@wrapping = false @wrapping = false
# Full bright ambient light # Full bright ambient light

View File

@ -54,6 +54,7 @@ class Game_Temp
attr_accessor :debug_top_row # debug screen: for saving conditions attr_accessor :debug_top_row # debug screen: for saving conditions
attr_accessor :debug_index # debug screen: for saving conditions attr_accessor :debug_index # debug screen: for saving conditions
attr_accessor :footstep_sfx # current footstep sfx array attr_accessor :footstep_sfx # current footstep sfx array
attr_accessor :filmsprite # film puzzle sprite
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
# * Object Initialization # * Object Initialization
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
@ -104,5 +105,6 @@ class Game_Temp
@debug_top_row = 0 @debug_top_row = 0
@debug_index = 0 @debug_index = 0
@footstep_sfx = nil @footstep_sfx = nil
@filmsprite = nil
end end
end end

View File

@ -6,6 +6,7 @@
#============================================================================== #==============================================================================
class Interpreter class Interpreter
@@chill_pill = false
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
# * Object Initialization # * Object Initialization
# depth : nest depth # depth : nest depth
@ -129,6 +130,11 @@ class Interpreter
Graphics.update Graphics.update
@loop_count = 0 @loop_count = 0
end end
# Chill pill
if @@chill_pill
@@chill_pill = false
return
end
# If map is different than event startup time # If map is different than event startup time
if $game_map.map_id != @map_id if $game_map.map_id != @map_id
# Change event ID to 0 # Change event ID to 0
@ -306,4 +312,8 @@ class Interpreter
end end
end end
end end
# Chill out
def self.take_a_chill_pill
@@chill_pill = true
end
end end

14
scripts/Puzzle_Film.rb Normal file
View File

@ -0,0 +1,14 @@
def film_puzzle_begin
Oneshot.reset_obscured
$game_temp.filmsprite.dispose if $game_temp.filmsprite
filmsprite = Sprite.new
filmsprite.bitmap = RPG::Cache.picture('numbersheet')
filmsprite.z = 9999
filmsprite.obscured = true
$game_temp.filmsprite = filmsprite
end
def film_puzzle_end
$game_temp.filmsprite.dispose if $game_temp.filmsprite
$game_temp.filmsprite = nil
end

View File

@ -50,6 +50,13 @@ def has_lightbulb?
$game_party.item_number(1) > 0 $game_party.item_number(1) > 0
end end
def button_pressed?
(1..18).each do |i|
return true if Input.trigger?(i)
end
return false
end
def enter_name def enter_name
$game_temp.name_calling = true $game_temp.name_calling = true
end end
@ -100,10 +107,6 @@ def clear_lights
#$scene.clear_lights #$scene.clear_lights
end end
def clamp_panorama
$game_map.clamped_panorama = true
end
def wrap_map def wrap_map
$game_map.wrapping = true $game_map.wrapping = true
end end
@ -134,3 +137,7 @@ end
def plight_update_timer def plight_update_timer
Script.tmp_v1 = ((Time.now - $game_oneshot.plight_timer) / 60).to_i Script.tmp_v1 = ((Time.now - $game_oneshot.plight_timer) / 60).to_i
end end
def quit
$scene = nil
end

View File

@ -195,13 +195,16 @@ class Spriteset_Map
@tilemap.oy = $game_map.display_y / 4 @tilemap.oy = $game_map.display_y / 4
@tilemap.update @tilemap.update
# Update panorama plane # Update panorama plane
if $game_map.clamped_panorama if $game_map.clamped_x
x = ($game_player.real_x.to_f / (($game_map.width - 1) * 128)) * (@panorama.bitmap.width - 640) x = ($game_player.real_x.to_f / (($game_map.width - 1) * 128)) * (@panorama.bitmap.width - 640)
y = ($game_player.real_y.to_f / (($game_map.height - 1) * 128)) * (@panorama.bitmap.height - 480)
@panorama.ox = x < 0.0 ? 0.0 : x @panorama.ox = x < 0.0 ? 0.0 : x
@panorama.oy = y < 0.0 ? 0.0 : y
else else
@panorama.ox = $game_map.display_x / 8 @panorama.ox = $game_map.display_x / 8
end
if $game_map.clamped_y
y = ($game_player.real_y.to_f / (($game_map.height - 1) * 128)) * (@panorama.bitmap.height - 480)
@panorama.oy = y < 0.0 ? 0.0 : y
else
@panorama.oy = $game_map.display_y / 8 @panorama.oy = $game_map.display_y / 8
end end
# Update fog plane # Update fog plane

View File

@ -139,6 +139,17 @@ class Window_Item < Window_Selectable
$game_system.se_play($data_system.buzzer_se) $game_system.se_play($data_system.buzzer_se)
return return
end end
# Run common event of item if valid
item = @data[@index]
if item.common_event_id > 0
$game_temp.common_event_id = item.common_event_id
$game_system.se_play($data_system.decision_se)
@fade_out = true
return
end
# Select or combine items
item_a = $game_variables[1] item_a = $game_variables[1]
item_b = @data[@index].id item_b = @data[@index].id
if item_a == item_b if item_a == item_b

View File

@ -194,7 +194,7 @@ class Window_Message < Window_Selectable
@text.sub!(/\[([0-9]+)\]/, "") @text.sub!(/\[([0-9]+)\]/, "")
color = $1.to_i color = $1.to_i
if color >= 0 and color <= 7 if color >= 0 and color <= 7
self.contents.font.color = text_color(color) self.contents.font.color = Window_Base.text_color(color)
end end
# go to next text # go to next text
next next

12
shader/obscured.frag Normal file
View File

@ -0,0 +1,12 @@
uniform sampler2D texture;
uniform sampler2D obscured;
varying vec2 v_texCoord;
void main()
{
vec4 color = texture2D(texture, v_texCoord);
color.a *= texture2D(obscured, v_texCoord).r;
gl_FragColor = color;
}

View File

@ -38,6 +38,8 @@
#include "al-util.h" #include "al-util.h"
#include "debugwriter.h" #include "debugwriter.h"
#include "oneshot.h"
#include <string.h> #include <string.h>
#include <map> #include <map>
@ -546,6 +548,19 @@ int EventThread::eventFilter(void *data, SDL_Event *event)
Debug() << "SDL_APP_LOWMEMORY"; Debug() << "SDL_APP_LOWMEMORY";
return 0; return 0;
/* Workaround for Windows pausing on drag */
case SDL_WINDOWEVENT:
if (event->window.event == SDL_WINDOWEVENT_MOVED)
{
if (shState->rgssVersion > 0)
{
shState->oneshot().setWindowPos(event->window.data1, event->window.data2);
shState->graphics().update(false);
}
return 0;
}
return 1;
// case SDL_RENDER_TARGETS_RESET : // case SDL_RENDER_TARGETS_RESET :
// Debug() << "****** SDL_RENDER_TARGETS_RESET"; // Debug() << "****** SDL_RENDER_TARGETS_RESET";
// return 0; // return 0;

View File

@ -37,6 +37,7 @@
#include "intrulist.h" #include "intrulist.h"
#include "binding.h" #include "binding.h"
#include "debugwriter.h" #include "debugwriter.h"
#include "oneshot.h"
#include <SDL_video.h> #include <SDL_video.h>
#include <SDL_timer.h> #include <SDL_timer.h>
@ -484,6 +485,8 @@ struct GraphicsPrivate
* (disposed on reset) */ * (disposed on reset) */
IntruList<Disposable> dispList; IntruList<Disposable> dispList;
TEX::ID obscuredTex;
GraphicsPrivate(RGSSThreadData *rtData) GraphicsPrivate(RGSSThreadData *rtData)
: scRes(DEF_SCREEN_W, DEF_SCREEN_H), : scRes(DEF_SCREEN_W, DEF_SCREEN_H),
scSize(scRes), scSize(scRes),
@ -516,6 +519,12 @@ struct GraphicsPrivate
TEXFBO::linkFBO(transBuffer); TEXFBO::linkFBO(transBuffer);
fpsLimiter.resetFrameAdjust(); fpsLimiter.resetFrameAdjust();
obscuredTex = TEX::gen();
TEX::bind(obscuredTex);
TEX::setRepeat(false);
TEX::setSmooth(false);
gl.TexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE8, 640, 480, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0);
} }
~GraphicsPrivate() ~GraphicsPrivate()
@ -612,6 +621,12 @@ struct GraphicsPrivate
void redrawScreen() void redrawScreen()
{ {
if (shState->oneshot().obscuredDirty)
{
TEX::bind(obscuredTex);
TEX::uploadSubImage(0, 0, 640, 480, shState->oneshot().obscuredMap().data(), GL_LUMINANCE);
shState->oneshot().obscuredDirty = false;
}
screen.composite(); screen.composite();
GLMeta::blitBeginScreen(winSize); GLMeta::blitBeginScreen(winSize);
@ -665,7 +680,7 @@ Graphics::~Graphics()
delete p; delete p;
} }
void Graphics::update() void Graphics::update(bool limitFps)
{ {
p->checkShutDownReset(); p->checkShutDownReset();
p->checkSyncLock(); p->checkSyncLock();
@ -673,23 +688,33 @@ void Graphics::update()
if (p->frozen) if (p->frozen)
return; return;
if (p->fpsLimiter.frameSkipRequired()) if (limitFps)
{ {
if (p->threadData->config.frameSkip) if (p->fpsLimiter.frameSkipRequired())
{ {
/* Skip frame */ if (p->threadData->config.frameSkip)
p->fpsLimiter.delay(); {
++p->frameCount; /* Skip frame */
p->threadData->ethread->notifyFrame(); p->fpsLimiter.delay();
++p->frameCount;
p->threadData->ethread->notifyFrame();
return; return;
} }
else else
{ {
/* Just reset frame adjust counter */ /* Just reset frame adjust counter */
p->fpsLimiter.resetFrameAdjust(); p->fpsLimiter.resetFrameAdjust();
}
} }
} }
else
{
if (!p->fpsLimiter.frameSkipRequired())
return;
}
shState->oneshot().update();
p->checkResize(); p->checkResize();
p->redrawScreen(); p->redrawScreen();
@ -1062,3 +1087,8 @@ void Graphics::remDisposable(Disposable *d)
{ {
p->dispList.remove(d->link); p->dispList.remove(d->link);
} }
const TEX::ID &Graphics::obscuredTex() const
{
return p->obscuredTex;
}

View File

@ -23,6 +23,7 @@
#define GRAPHICS_H #define GRAPHICS_H
#include "util.h" #include "util.h"
#include "gl-util.h"
class Scene; class Scene;
class Bitmap; class Bitmap;
@ -34,7 +35,7 @@ struct AtomicFlag;
class Graphics class Graphics
{ {
public: public:
void update(); void update(bool limitFps = true);
void freeze(); void freeze();
void transition(int duration = 8, void transition(int duration = 8,
const char *filename = "", const char *filename = "",
@ -70,6 +71,8 @@ public:
void repaintWait(const AtomicFlag &exitCond, void repaintWait(const AtomicFlag &exitCond,
bool checkReset = true); bool checkReset = true);
const TEX::ID &obscuredTex() const;
private: private:
Graphics(RGSSThreadData *data); Graphics(RGSSThreadData *data);
~Graphics(); ~Graphics();

View File

@ -80,6 +80,12 @@ struct OneshotPrivate
std::string txtYes; std::string txtYes;
std::string txtNo; std::string txtNo;
//Alpha texture data for portions of window obscured by screen edges
int winX, winY;
bool winPosChanged;
std::vector<uint8_t> obscuredMap;
bool obscuredCleared;
#if defined OS_LINUX #if defined OS_LINUX
//GTK+ //GTK+
void *libgtk; void *libgtk;
@ -205,6 +211,11 @@ Oneshot::Oneshot(const RGSSThreadData &threadData)
p = new OneshotPrivate(); p = new OneshotPrivate();
p->window = threadData.window; p->window = threadData.window;
p->savePath = threadData.config.commonDataPath.substr(0, threadData.config.commonDataPath.size() - 1); p->savePath = threadData.config.commonDataPath.substr(0, threadData.config.commonDataPath.size() - 1);
p->obscuredMap.resize(640 * 480, 255);
obscuredDirty = true;
p->winX = 0;
p->winY = 0;
p->winPosChanged = false;
/******************** /********************
* USERNAME/SAVE PATH * USERNAME/SAVE PATH
@ -337,6 +348,69 @@ Oneshot::~Oneshot()
delete p; delete p;
} }
void Oneshot::update()
{
if (p->winPosChanged)
{
p->winPosChanged = false;
//Map of unobscured pixels in this frame
static std::vector<bool> obscuredFrame(p->obscuredMap.size());
std::fill(obscuredFrame.begin(), obscuredFrame.end(), true);
SDL_Rect screenRect;
screenRect.x = p->winX;
screenRect.y = p->winY;
screenRect.w = 640;
screenRect.h = 480;
//Update obscured map and texture for window portion offscreen
for (int i = 0, max = SDL_GetNumVideoDisplays(); i < max; ++i)
{
SDL_Rect bounds;
SDL_GetDisplayBounds(i, &bounds);
//If it's fully within the monitor, it's completely unobscured
//and no texture update is necessary
if (p->winX >= bounds.x && p->winY >= bounds.y && p->winX + 640 <= bounds.x + bounds.w && p->winY + 480 <= bounds.y + bounds.h)
return;
//Update obscuredFrame otherwise
SDL_Rect intersect;
if (!SDL_IntersectRect(&screenRect, &bounds, &intersect))
continue;
intersect.x -= p->winX;
intersect.y -= p->winY;
for (int y = intersect.y; y < intersect.y + intersect.h; ++y)
{
int start = y * 640 + intersect.x;
std::fill(obscuredFrame.begin() + start, obscuredFrame.begin() + (start + intersect.w), false);
}
}
//Update the obscured map, and return prematurely if we don't have any changes
//to make to the texture
bool needsUpdate = false;
bool cleared = true;
for (size_t i = 0; i < obscuredFrame.size(); ++i)
{
if (obscuredFrame[i])
{
p->obscuredMap[i] = 0;
needsUpdate = true;
}
if (p->obscuredMap[i] == 255)
cleared = false;
}
p->obscuredCleared = cleared;
if (!needsUpdate)
return;
//Flag as dirty
obscuredDirty = true;
}
}
const std::string &Oneshot::lang() const const std::string &Oneshot::lang() const
{ {
return p->lang; return p->lang;
@ -352,6 +426,16 @@ const std::string &Oneshot::savePath() const
return p->savePath; return p->savePath;
} }
const std::vector<uint8_t> &Oneshot::obscuredMap() const
{
return p->obscuredMap;
}
bool Oneshot::obscuredCleared() const
{
return p->obscuredCleared;
}
void Oneshot::setYesNo(const char *yes, const char *no) void Oneshot::setYesNo(const char *yes, const char *no)
{ {
p->txtYes = yes; p->txtYes = yes;
@ -458,3 +542,16 @@ bool Oneshot::msgbox(int type, const char *body, const char *title)
return button ? true : false; return button ? true : false;
#endif #endif
} }
void Oneshot::setWindowPos(int x, int y)
{
p->winX = x;
p->winY = y;
p->winPosChanged = true;
}
void Oneshot::resetObscured()
{
std::fill(p->obscuredMap.begin(), p->obscuredMap.end(), 255);
obscuredDirty = true;
}

View File

@ -42,17 +42,26 @@ public:
GRADIENT_VERTICAL, GRADIENT_VERTICAL,
}; };
void update();
//Accessors //Accessors
const std::string &lang() const; const std::string &lang() const;
const std::string &userName() const; const std::string &userName() const;
const std::string &savePath() const; const std::string &savePath() const;
const std::vector<uint8_t> &obscuredMap() const;
bool obscuredCleared() const;
//Mutators //Mutators
void setYesNo(const char *yes, const char *no); void setYesNo(const char *yes, const char *no);
void setWindowPos(int x, int y);
void resetObscured();
//Functions //Functions
bool msgbox(int type, const char *body, const char *title); bool msgbox(int type, const char *body, const char *title);
//Dirty flag for obscured texture
bool obscuredDirty;
private: private:
OneshotPrivate *p; OneshotPrivate *p;
}; };

View File

@ -52,6 +52,7 @@
#include "blurH.vert.xxd" #include "blurH.vert.xxd"
#include "blurV.vert.xxd" #include "blurV.vert.xxd"
#include "tilemapvx.vert.xxd" #include "tilemapvx.vert.xxd"
#include "obscured.frag.xxd"
#define INIT_SHADER(vert, frag, name) \ #define INIT_SHADER(vert, frag, name) \
@ -641,3 +642,17 @@ void BltShader::setOpacity(float value)
{ {
gl.Uniform1f(u_opacity, value); gl.Uniform1f(u_opacity, value);
} }
ObscuredShader::ObscuredShader()
{
INIT_SHADER(simple, obscured, ObscuredShader);
ShaderBase::init();
GET_U(obscured);
}
void ObscuredShader::setObscured(const TEX::ID value)
{
setTexUniform(u_obscured, 1, value);
}

View File

@ -304,6 +304,18 @@ private:
GLint u_source, u_destination, u_subRect, u_opacity; GLint u_source, u_destination, u_subRect, u_opacity;
}; };
/* Obscured graphic */
class ObscuredShader : public ShaderBase
{
public:
ObscuredShader();
void setObscured(const TEX::ID value);
private:
GLint u_obscured;
};
/* Global object containing all available shaders */ /* Global object containing all available shaders */
struct ShaderSet struct ShaderSet
{ {
@ -325,6 +337,7 @@ struct ShaderSet
SimpleMatrixShader simpleMatrix; SimpleMatrixShader simpleMatrix;
BlurShader blur; BlurShader blur;
TilemapVXShader tilemapVX; TilemapVXShader tilemapVX;
ObscuredShader obscured;
}; };
#endif // SHADER_H #endif // SHADER_H

View File

@ -33,6 +33,8 @@
#include "shader.h" #include "shader.h"
#include "glstate.h" #include "glstate.h"
#include "quadarray.h" #include "quadarray.h"
#include "config.h"
#include "debugwriter.h"
#include <math.h> #include <math.h>
@ -64,6 +66,8 @@ struct SpritePrivate
* the screen if drawn? */ * the screen if drawn? */
bool isVisible; bool isVisible;
bool obscured;
Color *color; Color *color;
Tone *tone; Tone *tone;
@ -95,6 +99,7 @@ struct SpritePrivate
opacity(255), opacity(255),
blendType(BlendNormal), blendType(BlendNormal),
isVisible(false), isVisible(false),
obscured(false),
color(&tmp.color), color(&tmp.color),
tone(&tmp.tone) tone(&tmp.tone)
@ -322,6 +327,7 @@ DEF_ATTR_SIMPLE(Sprite, Opacity, int, p->opacity)
DEF_ATTR_SIMPLE(Sprite, SrcRect, Rect&, *p->srcRect) DEF_ATTR_SIMPLE(Sprite, SrcRect, Rect&, *p->srcRect)
DEF_ATTR_SIMPLE(Sprite, Color, Color&, *p->color) DEF_ATTR_SIMPLE(Sprite, Color, Color&, *p->color)
DEF_ATTR_SIMPLE(Sprite, Tone, Tone&, *p->tone) DEF_ATTR_SIMPLE(Sprite, Tone, Tone&, *p->tone)
DEF_ATTR_SIMPLE(Sprite, Obscured, bool, p->obscured)
void Sprite::setBitmap(Bitmap *bitmap) void Sprite::setBitmap(Bitmap *bitmap)
{ {
@ -518,7 +524,15 @@ void Sprite::draw()
flashing || flashing ||
p->bushDepth != 0; p->bushDepth != 0;
if (renderEffect) if (p->obscured)
{
ObscuredShader &shader = shState->shaders().obscured;
shader.bind();
shader.applyViewportProj();
shader.setObscured(shState->graphics().obscuredTex());
base = &shader;
}
else if (renderEffect)
{ {
SpriteShader &shader = shState->shaders().sprite; SpriteShader &shader = shState->shaders().sprite;

View File

@ -66,6 +66,7 @@ public:
DECL_ATTR( WaveLength, int ) DECL_ATTR( WaveLength, int )
DECL_ATTR( WaveSpeed, int ) DECL_ATTR( WaveSpeed, int )
DECL_ATTR( WavePhase, float ) DECL_ATTR( WavePhase, float )
DECL_ATTR( Obscured, bool )
void initDynAttribs(); void initDynAttribs();