diff --git a/binding-mri/plane-binding.cpp b/binding-mri/plane-binding.cpp index 626b7d7..0ec65c9 100644 --- a/binding-mri/plane-binding.cpp +++ b/binding-mri/plane-binding.cpp @@ -35,15 +35,17 @@ RB_METHOD(planeInitialize) p->initDynAttribs(); + wrapProperty(self, &p->getSrcRect(), "src_rect", RectType); wrapProperty(self, &p->getColor(), "color", ColorType); wrapProperty(self, &p->getTone(), "tone", ToneType); return self; } -DEF_PROP_OBJ_REF(Plane, Bitmap, Bitmap, "bitmap") -DEF_PROP_OBJ_VAL(Plane, Color, Color, "color") -DEF_PROP_OBJ_VAL(Plane, Tone, Tone, "tone") +DEF_PROP_OBJ_REF(Plane, Bitmap, Bitmap, "bitmap") +DEF_PROP_OBJ_VAL(Plane, Rect, SrcRect, "src_rect") +DEF_PROP_OBJ_VAL(Plane, Color, Color, "color") +DEF_PROP_OBJ_VAL(Plane, Tone, Tone, "tone") DEF_PROP_I(Plane, OX) DEF_PROP_I(Plane, OY) @@ -66,6 +68,7 @@ planeBindingInit() _rb_define_method(klass, "initialize", planeInitialize); INIT_PROP_BIND( Plane, Bitmap, "bitmap" ); + INIT_PROP_BIND( Plane, SrcRect, "src_rect" ); INIT_PROP_BIND( Plane, OX, "ox" ); INIT_PROP_BIND( Plane, OY, "oy" ); INIT_PROP_BIND( Plane, ZoomX, "zoom_x" ); diff --git a/scripts/Data_TileText.rb b/scripts/Data_TileText.rb new file mode 100644 index 0000000..e69de29 diff --git a/scripts/Game_Character 3.rb b/scripts/Game_Character 3.rb index 197207d..5bc4357 100644 --- a/scripts/Game_Character 3.rb +++ b/scripts/Game_Character 3.rb @@ -11,6 +11,8 @@ class Game_Character # turn_enabled : a flag permits direction change on that spot #-------------------------------------------------------------------------- def move_down(turn_enabled = true) + # Only emit footprint if already facing down + emit = @direction == 2 # Turn down if turn_enabled turn_down @@ -19,6 +21,8 @@ class Game_Character if passable?(@x, @y, 2) # Turn down turn_down + # Emit footprint + emit_footprint(2) if emit # Update coordinates @y += 1 # Increase steps @@ -42,6 +46,8 @@ class Game_Character if passable?(@x, @y, 4) # Turn left turn_left + # Emit footprint + emit_footprint(4) # Update coordinates @x -= 1 # Increase steps @@ -65,6 +71,8 @@ class Game_Character if passable?(@x, @y, 6) # Turn right turn_right + # Emit footprint + emit_footprint(6) # Update coordinates @x += 1 # Increase steps @@ -88,6 +96,8 @@ class Game_Character if passable?(@x, @y, 8) # Turn up turn_up + # Emit footprint + emit_footprint(8) # Update coordinates @y -= 1 # Increase steps @@ -481,4 +491,10 @@ class Game_Character sy > 0 ? turn_down : turn_up end end + #-------------------------------------------------------------------------- + # * Emit Footprint + #-------------------------------------------------------------------------- + def emit_footprint(direction) + $scene.new_footprint(direction, @x, @y) + end end diff --git a/scripts/Game_Map.rb b/scripts/Game_Map.rb index 32d5317..7733c69 100644 --- a/scripts/Game_Map.rb +++ b/scripts/Game_Map.rb @@ -30,6 +30,9 @@ class Game_Map attr_accessor :particles_type # particles name attr_accessor :clamped_x # panorama is horizontally clamped? attr_accessor :clamped_y # panorama is vertically clamped? + attr_accessor :pan_onetoone # panorama is 1:1 + attr_accessor :pan_animate # panorama is animated + attr_accessor :pan_zoom # panorama zoom attr_accessor :wrapping # map is wrapping? attr_accessor :pan_offset_y # offset of y-coord of panorama attr_accessor :ambient # ambient light @@ -52,6 +55,16 @@ class Game_Map CLAMPED_Y = [ 'red_obsdesk', ] + ANIMATED = [ + 'blue_water', + ] + ONETOONE = [ + 'blue_water', + 'dark_water', + ] + NOZOOM = [ + 'dark_water', + ] #-------------------------------------------------------------------------- # * Object Initialization #-------------------------------------------------------------------------- @@ -138,6 +151,10 @@ class Game_Map @clamped_x = false @clamped_y = false end + # Animated/One-to-one/zoom + @pan_animate = ANIMATED.include? @panorama_name + @pan_onetoone = ONETOONE.include? @panorama_name + @pan_zoom = NOZOOM.include?(@panorama_name) ? 1 : 2 # Unwrap map @wrapping = false @pan_offset_y = 0 diff --git a/scripts/Particles.rb b/scripts/Particles.rb index 8c0f32a..bb8b9cb 100644 --- a/scripts/Particles.rb +++ b/scripts/Particles.rb @@ -107,3 +107,34 @@ class ParticleLayer @particles = nil end end + +class Particle_Shrimp < Particle + @@bitmap = RPG::Cache.picture('shrimp') + TAU = Math::PI * 2 + + def initialize(viewport) + super(viewport, @@bitmap) + @angle = rand(0..TAU) + @speed = rand(0.2..4.0) + self.scale = rand(0.04..0.08) + end + + def update + case rand(0..10) + when 0..1 + @angle += rand(-TAU / 8..TAU / 8) + when 2 + @speed += rand(1.0..5.0) + @speed = 5.0 if @speed > 5.0 + when 3..4 + @speed -= rand(1.0..2.0) + @speed = 0.2 if @speed < 0.2 + else + # no-op + end + vx = Math.cos(@angle) * @speed + vy = Math.sin(@angle) * @speed + self.x += vx + self.y += vy + end +end diff --git a/scripts/RPG.rb b/scripts/RPG.rb index deddca4..41248c8 100644 --- a/scripts/RPG.rb +++ b/scripts/RPG.rb @@ -14,6 +14,9 @@ module RPG def self.light(filename) self.load_bitmap("Graphics/Lights/", filename) end + def self.misc(filename) + self.load_bitmap("Graphics/Misc/", filename) + end end end diff --git a/scripts/Scene_Map.rb b/scripts/Scene_Map.rb index d1d8af0..a70e074 100644 --- a/scripts/Scene_Map.rb +++ b/scripts/Scene_Map.rb @@ -406,4 +406,7 @@ class Scene_Map #-------------------------------------------------------------------------- # * Misc operations #-------------------------------------------------------------------------- + def new_footprint(direction, x, y) + @spriteset.new_footprint(direction, x, y) + end end diff --git a/scripts/Script.rb b/scripts/Script.rb index 0ea264e..f635e9c 100644 --- a/scripts/Script.rb +++ b/scripts/Script.rb @@ -117,7 +117,11 @@ end # Map specific settings def green_ambient - ambient -40, -40, -40 + ambient(-40, -40, -40) +end + +def blue_ambient + ambient(-40, -40, -40) end # Travel diff --git a/scripts/Sprite_Footprint.rb b/scripts/Sprite_Footprint.rb new file mode 100644 index 0000000..c4965c9 --- /dev/null +++ b/scripts/Sprite_Footprint.rb @@ -0,0 +1,28 @@ +class Sprite_Footprint < Sprite + def initialize(viewport, direction, x, y) + super(viewport) + @direction = direction + @real_x = x * 4 * 32 + @real_y = y * 4 * 32 + + self.zoom_x = 2 + self.zoom_y = 2 + self.ox = 8 + self.oy = 16 + self.bitmap = RPG::Cache.misc('footprints') + self.src_rect.set(0, 16 * (direction / 2 - 1), 16, 16) + update + end + + def update + return if disposed? + + self.x = (@real_x - $game_map.display_x + 3) / 4 + 16 + self.y = (@real_y - $game_map.display_y + 3) / 4 + 32 + + self.opacity -= 4 + if self.opacity == 0 + dispose + end + end +end diff --git a/scripts/Spriteset_Map.rb b/scripts/Spriteset_Map.rb index 8e361f3..710c5ce 100644 --- a/scripts/Spriteset_Map.rb +++ b/scripts/Spriteset_Map.rb @@ -37,7 +37,7 @@ class Spriteset_Map @tilemap.map_data = $game_map.data @tilemap.priorities = $game_map.priorities # Make panorama plane - @panorama = Plane.new(@viewport) + @panorama = Plane.new(@viewport_bg) @panorama.z = -1000 # Make fog plane @fog = Plane.new(@viewport) @@ -52,6 +52,8 @@ class Spriteset_Map @character_sprites.push(Sprite_Character.new(@viewport, @viewport_lights, follower)) end @character_sprites.push(Sprite_Character.new(@viewport, @viewport_lights, $game_player)) + # Make footprints + @footprint_sprites = [] # Make weather @weather = RPG::Weather.new(@viewport) # Make picture sprites @@ -66,6 +68,8 @@ class Spriteset_Map @bulb = Sprite.new(@viewport_lights) @bulb.bitmap = RPG::Cache.light('bulb') @bulb.opacity = has_lightbulb? ? 255 : 0 + # Panorama animation timer + @pan_animate_timer = 0 # Frame update update end @@ -84,7 +88,11 @@ class Spriteset_Map # Dispose of fog plane @fog.dispose # Dispose of character sprites - for sprite in @character_sprites + @character_sprites.each do |sprite| + sprite.dispose + end + # Dispose of footprints + @footprint_sprites.each do |sprite| sprite.dispose end # Dispose of weather @@ -180,32 +188,45 @@ class Spriteset_Map klass = Particle_Firefly count = 30 layer = :front + when :shrimp + klass = Particle_Shrimp + count = 80 + layer = :back else raise 'invalid particle type' end @particles = ParticleLayer.new(@viewport_particles, klass, count) - @viewport_particles.z = (layer == :front) ? 500 : 50 + @viewport_particles.z = (layer == :front) ? 500 : -400 end end # Update bg plane - @viewport_bg.ox = $game_map.display_x / 4 - @viewport_bg.oy = $game_map.display_y / 4 + @bg.ox = $game_map.display_x / 4 + @bg.oy = $game_map.display_y / 4 # Update tilemap @tilemap.ox = $game_map.display_x / 4 @tilemap.oy = $game_map.display_y / 4 @tilemap.update # Update panorama plane 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 * $game_map.pan_zoom - 640) @panorama.ox = x < 0.0 ? 0.0 : x else - @panorama.ox = $game_map.display_x / 8 + @panorama.ox = $game_map.display_x / ($game_map.pan_onetoone ? 4 : 8) end if $game_map.clamped_y - y = ($game_player.real_y.to_f / (($game_map.height - 1) * 128)) * (@panorama.bitmap.height - 480) + y = ($game_player.real_y.to_f / (($game_map.height - 1) * 128)) * (@panorama.bitmap.height * $game_map.pan_zoom - 480) @panorama.oy = y < 0.0 ? 0.0 : y else - @panorama.oy = $game_map.pan_offset_y + $game_map.display_y / 8 + @panorama.oy = $game_map.pan_offset_y + $game_map.display_y / ($game_map.pan_onetoone ? 4 : 8) + end + @panorama.zoom_x = @panorama.zoom_y = $game_map.pan_zoom + # Animate panorama + if $game_map.pan_animate + @pan_animate_timer = (@pan_animate_timer + 1) % 16 + @panorama.src_rect.width = @panorama.src_rect.height + if @pan_animate_timer == 0 + @panorama.src_rect.x = (@panorama.src_rect.x + @panorama.src_rect.height) % @panorama.bitmap.width + end end # Update fog plane @fog.zoom_x = $game_map.fog_zoom / 100.0 @@ -216,9 +237,14 @@ class Spriteset_Map @fog.oy = $game_map.display_y / 4 + $game_map.fog_oy @fog.tone = $game_map.fog_tone # Update character sprites - for sprite in @character_sprites + @character_sprites.each do |sprite| sprite.update end + # Update footprints + @footprint_sprites.delete_if do |sprite| + sprite.update + sprite.disposed? + end # Update weather graphic @weather.type = $game_screen.weather_type @weather.max = $game_screen.weather_max @@ -255,4 +281,10 @@ class Spriteset_Map @viewport_flash.update @viewport_lights.update end + #-------------------------------------------------------------------------- + # * Misc operations + #-------------------------------------------------------------------------- + def new_footprint(direction, x, y) + @footprint_sprites << Sprite_Footprint.new(@viewport, direction, x, y) + end end diff --git a/scripts/_scripts.txt b/scripts/_scripts.txt index 8087f46..50df74d 100644 --- a/scripts/_scripts.txt +++ b/scripts/_scripts.txt @@ -33,6 +33,7 @@ Sprite_Battler Sprite_Picture Sprite_Timer Sprite_Light +Sprite_Footprint Spriteset_Map FastTravel diff --git a/shader/distort.frag b/shader/distort.frag new file mode 100644 index 0000000..9161c35 --- /dev/null +++ b/shader/distort.frag @@ -0,0 +1,7 @@ +uniform sampler2D qt_Texture0; +varying vec4 qt_TexCoord0; + +void main(void) +{ + gl_FragColor = texture2D(qt_Texture0, qt_TexCoord0.st); +} diff --git a/src/plane.cpp b/src/plane.cpp index e3de3a0..53746f9 100644 --- a/src/plane.cpp +++ b/src/plane.cpp @@ -24,6 +24,7 @@ #include "sharedstate.h" #include "bitmap.h" #include "etc.h" +#include "etc-internal.h" #include "util.h" #include "gl-util.h" @@ -46,6 +47,8 @@ struct PlanePrivate { Bitmap *bitmap; + Rect *srcRect; + NormValue opacity; BlendType blendType; Color *color; @@ -63,9 +66,11 @@ struct PlanePrivate EtcTemps tmp; sigc::connection prepareCon; + sigc::connection srcRectCon; PlanePrivate() : bitmap(0), + srcRect(&tmp.rect), opacity(255), blendType(BlendNormal), color(&tmp.color), @@ -74,6 +79,7 @@ struct PlanePrivate zoomX(1), zoomY(1), quadSourceDirty(false) { + updateSrcRectCon(); prepareCon = shState->prepareDraw.connect (sigc::mem_fun(this, &PlanePrivate::prepare)); @@ -82,12 +88,30 @@ struct PlanePrivate ~PlanePrivate() { + srcRectCon.disconnect(); prepareCon.disconnect(); } + void onSrcRectChange() + { + quadSourceDirty = true; + } + + void updateSrcRectCon() + { + /* Cut old connection */ + srcRectCon.disconnect(); + /* Create new one */ + srcRectCon = srcRect->valueChanged.connect + (sigc::mem_fun(this, &PlanePrivate::onSrcRectChange)); + } + void updateQuadSource() { - if (gl.npot_repeat) + if (nullOrDisposed(bitmap)) + return; + + if (gl.npot_repeat && srcRect->toIntRect() == bitmap->rect()) { FloatRect srcRect; srcRect.x = (sceneGeo.orig.x + ox) / zoomX; @@ -101,12 +125,9 @@ struct PlanePrivate return; } - if (nullOrDisposed(bitmap)) - return; - /* Scaled (zoomed) bitmap dimensions */ - float sw = bitmap->width() * zoomX; - float sh = bitmap->height() * zoomY; + float sw = srcRect->width * zoomX; + float sh = srcRect->height * zoomY; /* Plane offset wrapped by scaled bitmap dims */ float wox = fwrap(ox, sw); @@ -120,7 +141,7 @@ struct PlanePrivate size_t tilesX = ceil((vpw - sw + wox) / sw) + 1; size_t tilesY = ceil((vph - sh + woy) / sh) + 1; - FloatRect tex = bitmap->rect(); + FloatRect tex = srcRect->toFloatRect(); qArray.resize(tilesX * tilesY); @@ -161,6 +182,7 @@ DEF_ATTR_RD_SIMPLE(Plane, ZoomX, float, p->zoomX) DEF_ATTR_RD_SIMPLE(Plane, ZoomY, float, p->zoomY) DEF_ATTR_RD_SIMPLE(Plane, BlendType, int, p->blendType) +DEF_ATTR_SIMPLE(Plane, SrcRect, Rect&, *p->srcRect) DEF_ATTR_SIMPLE(Plane, Opacity, int, p->opacity) DEF_ATTR_SIMPLE(Plane, Color, Color&, *p->color) DEF_ATTR_SIMPLE(Plane, Tone, Tone&, *p->tone) @@ -180,6 +202,9 @@ void Plane::setBitmap(Bitmap *value) return; value->ensureNonMega(); + + *p->srcRect = value->rect(); + p->onSrcRectChange(); } void Plane::setOX(int value) @@ -247,8 +272,11 @@ void Plane::setBlendType(int value) void Plane::initDynAttribs() { + p->srcRect = new Rect; p->color = new Color; p->tone = new Tone; + + p->updateSrcRectCon(); } void Plane::draw() diff --git a/src/plane.h b/src/plane.h index c6b2d6a..532d154 100644 --- a/src/plane.h +++ b/src/plane.h @@ -38,6 +38,7 @@ public: ~Plane(); DECL_ATTR( Bitmap, Bitmap* ) + DECL_ATTR( SrcRect, Rect& ) DECL_ATTR( OX, int ) DECL_ATTR( OY, int ) DECL_ATTR( ZoomX, float )