Finished FPS agnosticism, removed particle engine

This commit is contained in:
Maruno17
2023-06-03 21:55:02 +01:00
parent 68de25562a
commit 1901675e33
39 changed files with 652 additions and 1504 deletions

View File

@@ -24,8 +24,7 @@ module MessageConfig
# 2 = Pause cursor is displayed at lower middle side
CURSOR_POSITION = 1
WINDOW_OPACITY = 255
TEXT_SPEED = nil # can be positive to wait frames, or negative
# to show multiple characters in a single frame
TEXT_SPEED = nil # Time in seconds between two characters
@@systemFrame = nil
@@defaultTextSkin = nil
@@textSpeed = nil
@@ -100,13 +99,16 @@ module MessageConfig
@@textSpeed = value
end
# Text speed is the delay in seconds between two adjacent characters being
# shown.
def self.pbSettingToTextSpeed(speed)
case speed
when 0 then return 2
when 1 then return 1
when 2 then return -2
when 0 then return 4 / 80.0 # Slow
when 1 then return 2 / 80.0 # Medium
when 2 then return 1 / 80.0 # Fast
when 3 then return 0 # Instant
end
return TEXT_SPEED || 1
return TEXT_SPEED || 2 / 80.0 # Normal
end
#-----------------------------------------------------------------------------

View File

@@ -123,7 +123,6 @@ class Window
@back_opacity = 255
@contents_opacity = 255
@cursor_rect = WindowCursorRect.new(self)
@cursorblink = 0
@cursoropacity = 255
@pause = false
@pauseopacity = 255
@@ -302,12 +301,11 @@ class Window
return if disposed?
mustchange = false
if @active
if @cursorblink == 0
@cursoropacity -= 8
@cursorblink = 1 if @cursoropacity <= 128
cursor_time = System.uptime / 0.4
if cursor_time.to_i % 2 == 0
@cursoropacity = lerp(255, 128, 0.4, cursor_time % 2)
else
@cursoropacity += 8
@cursorblink = 0 if @cursoropacity >= 255
@cursoropacity = lerp(128, 255, 0.4, (cursor_time - 1) % 2)
end
mustchange = true if !@cursor_rect.empty?
else

View File

@@ -99,11 +99,10 @@ class SpriteWindow < Window
@contents_blend_type = 0
@contents_opacity = 255
@cursor_rect = WindowCursorRect.new(self)
@cursorblink = 0
@cursoropacity = 255
@pause = false
@pauseframe = 0
@flash = 0
@flash_duration = 0
@pauseopacity = 0
@skinformat = 0
@skinrect = Rect.new(0, 0, 0, 0)
@@ -286,11 +285,13 @@ class SpriteWindow < Window
privRefresh if @visible
end
# duration is in 1/20ths of a second
def flash(color, duration)
return if disposed?
@flash = duration + 1
@flash_duration = duration / 20.0
@flash_timer_start = System.uptime
@sprites.each do |i|
i[1].flash(color, duration)
i[1].flash(color, (@flash_duration * Graphics.frame_rate).to_i) # Must be in frames
end
end
@@ -298,12 +299,11 @@ class SpriteWindow < Window
return if disposed?
mustchange = false
if @active
if @cursorblink == 0
@cursoropacity -= 8
@cursorblink = 1 if @cursoropacity <= 128
cursor_time = System.uptime / 0.4
if cursor_time.to_i % 2 == 0
@cursoropacity = lerp(255, 128, 0.4, cursor_time % 2)
else
@cursoropacity += 8
@cursorblink = 0 if @cursoropacity >= 255
@cursoropacity = lerp(128, 255, 0.4, (cursor_time - 1) % 2)
end
else
@cursoropacity = 128
@@ -312,16 +312,14 @@ class SpriteWindow < Window
if @pause
oldpauseframe = @pauseframe
oldpauseopacity = @pauseopacity
@pauseframe = (System.uptime * 5) % 4 # 4 frames, 5 frames per second
@pauseframe = (System.uptime * 5).to_i % 4 # 4 frames, 5 frames per second
@pauseopacity = [@pauseopacity + 64, 255].min
mustchange = @pauseframe != oldpauseframe || @pauseopacity != oldpauseopacity
end
privRefresh if mustchange
if @flash > 0
@sprites.each_value do |i|
i.update
end
@flash -= 1
if @flash_timer_start
@sprites.each_value { |i| i.update }
@flash_timer_start = nil if System.uptime - @flash_timer_start >= @flash_duration
end
end

View File

@@ -116,33 +116,34 @@ class Window_AdvancedTextPokemon < SpriteWindow_Base
attr_reader :waitcount
def initialize(text = "")
@cursorMode = MessageConfig::CURSOR_POSITION
@endOfText = nil
@scrollstate = 0
@realframes = 0
@scrollY = 0
@nodraw = false
@lineHeight = 32
@linesdrawn = 0
@bufferbitmap = nil
@letterbyletter = false
@starting = true
@displaying = false
@lastDrawnChar = -1
@fmtchars = []
@frameskipChanged = false
@frameskip = MessageConfig.pbGetTextSpeed
@cursorMode = MessageConfig::CURSOR_POSITION
@endOfText = nil
@scrollstate = 0
@scrollY = 0
@scroll_timer_start = nil
@realframes = 0
@nodraw = false
@lineHeight = 32
@linesdrawn = 0
@bufferbitmap = nil
@letterbyletter = false
@starting = true
@displaying = false
@lastDrawnChar = -1
@fmtchars = []
@text_delay_changed = false
@text_delay = MessageConfig.pbGetTextSpeed
super(0, 0, 33, 33)
@pausesprite = nil
@text = ""
@pausesprite = nil
@text = ""
self.contents = Bitmap.new(1, 1)
pbSetSystemFont(self.contents)
self.resizeToFit(text, Graphics.width)
colors = getDefaultTextColors(self.windowskin)
@baseColor = colors[0]
@shadowColor = colors[1]
self.text = text
@starting = false
@baseColor = colors[0]
@shadowColor = colors[1]
self.text = text
@starting = false
end
def self.newWithSize(text, x, y, width, height, viewport = nil)
@@ -189,13 +190,14 @@ class Window_AdvancedTextPokemon < SpriteWindow_Base
refresh
end
# Delay in seconds between two adjacent characters appearing.
def textspeed
@frameskip
return @text_delay
end
def textspeed=(value)
@frameskipChanged = true if @frameskip != value
@frameskip = value
@text_delay_changed = true if @text_delay != value
@text_delay = value
end
def width=(value)
@@ -285,6 +287,8 @@ class Window_AdvancedTextPokemon < SpriteWindow_Base
def setText(value)
@waitcount = 0
@wait_timer_start = nil
@display_timer = 0.0
@display_last_updated = System.uptime
@curchar = 0
@drawncurchar = -1
@lastDrawnChar = -1
@@ -292,6 +296,7 @@ class Window_AdvancedTextPokemon < SpriteWindow_Base
@textlength = unformattedTextLength(value)
@scrollstate = 0
@scrollY = 0
@scroll_timer_start = nil
@linesdrawn = 0
@realframes = 0
@textchars = []
@@ -400,7 +405,7 @@ class Window_AdvancedTextPokemon < SpriteWindow_Base
resume
visiblelines = (self.height - self.borderY) / @lineHeight
loop do
curcharSkip(999)
curcharSkip(true)
break if @curchar >= @fmtchars.length # End of message
if @textchars[@curchar] == "\1" # Pause message
@pausing = true if @curchar < @numtextchars - 1
@@ -462,7 +467,7 @@ class Window_AdvancedTextPokemon < SpriteWindow_Base
self.oy = @scrollY
numchars = @numtextchars
numchars = [@curchar, @numtextchars].min if self.letterbyletter
return if busy? && @drawncurchar == @curchar && @scrollstate == 0
return if busy? && @drawncurchar == @curchar && !@scroll_timer_start
if !self.letterbyletter || !oldcontents.equal?(self.contents)
@drawncurchar = -1
@needclear = true
@@ -508,7 +513,7 @@ class Window_AdvancedTextPokemon < SpriteWindow_Base
def redrawText
if @letterbyletter
oldPosition = self.position
self.text = self.text
self.text = self.text # Clears the text already drawn
oldPosition = @numtextchars if oldPosition > @numtextchars
while self.position != oldPosition
refresh
@@ -520,55 +525,56 @@ class Window_AdvancedTextPokemon < SpriteWindow_Base
end
def updateInternal
curcharskip = @frameskip < 0 ? @frameskip.abs : 1
time_now = System.uptime
@display_last_updated = time_now if !@display_last_updated
delta_t = time_now - @display_last_updated
@display_last_updated = time_now
visiblelines = (self.height - self.borderY) / @lineHeight
if @textchars[@curchar] == "\1"
if !@pausing
@realframes += 1
if @realframes >= @frameskip || @frameskip < 0
curcharSkip(curcharskip)
@realframes = 0
end
end
elsif @textchars[@curchar] == "\n"
if @linesdrawn >= visiblelines - 1
if @scrollstate < @lineHeight
@scrollstate += [(@lineHeight / 4), 1].max
@scrollY += [(@lineHeight / 4), 1].max
end
if @scrollstate >= @lineHeight
@realframes += 1
if @realframes >= @frameskip || @frameskip < 0
curcharSkip(curcharskip)
@linesdrawn += 1
@realframes = 0
show_more_characters = false
# Pauses and new lines
if @textchars[@curchar] == "\1" # Waiting
show_more_characters = true if !@pausing
elsif @textchars[@curchar] == "\n" # Move to new line
if @linesdrawn >= visiblelines - 1 # Need to scroll text to show new line
if @scroll_timer_start
old_y = @scrollstate
new_y = lerp(0, @lineHeight, 0.1, @scroll_timer_start, time_now)
@scrollstate = new_y
@scrollY += new_y - old_y
if @scrollstate >= @lineHeight
@scrollstate = 0
@scroll_timer_start = nil
@linesdrawn += 1
show_more_characters = true
end
else
show_more_characters = true
end
else
@realframes += 1
if @realframes >= @frameskip || @frameskip < 0
curcharSkip(curcharskip)
@linesdrawn += 1
@realframes = 0
end
end
elsif @curchar <= @numtextchars
@realframes += 1
if @realframes >= @frameskip || @frameskip < 0
curcharSkip(curcharskip)
@realframes = 0
end
if @textchars[@curchar] == "\1"
@pausing = true if @curchar < @numtextchars - 1
self.startPause
refresh
else # New line but the next line can be shown without scrolling to it
@linesdrawn += 1
show_more_characters = true
end
elsif @curchar <= @numtextchars # Displaying more text
show_more_characters = true
else
@displaying = false
@displaying = false
@scrollstate = 0
@scrollY = 0
@linesdrawn = 0
@scrollY = 0
@scroll_timer_start = nil
@linesdrawn = 0
end
# Keep displaying more text
if show_more_characters
@display_timer += delta_t
if curcharSkip
if @textchars[@curchar] == "\n" && @linesdrawn >= visiblelines - 1
@scroll_timer_start = time_now
elsif @textchars[@curchar] == "\1"
@pausing = true if @curchar < @numtextchars - 1
self.startPause
refresh
end
end
end
end
@@ -583,26 +589,33 @@ class Window_AdvancedTextPokemon < SpriteWindow_Base
return if @wait_timer_start
end
if busy?
refresh if !@frameskipChanged
refresh if !@text_delay_changed
updateInternal
# following line needed to allow "textspeed=-999" to work seamlessly
refresh if @frameskipChanged
# following line needed to allow "textspeed=0" to work seamlessly
# TODO: I don't think this is needed any more, but I don't know where to
# look to confirm it'd work properly without this line.
refresh if @text_delay_changed
end
@frameskipChanged = false
@text_delay_changed = false
end
#-----------------------------------------------------------------------------
private
def curcharSkip(skip)
skip.times do
def curcharSkip(instant = false)
ret = false
loop do
break if @display_timer < @text_delay && !instant
@display_timer -= @text_delay if !instant
ret = true
@curchar += 1
break if @textchars[@curchar] == "\n" || # newline
@textchars[@curchar] == "\1" || # pause
@textchars[@curchar] == "\2" || # letter-by-letter break
@textchars[@curchar].nil?
end
return ret
end
end
@@ -615,7 +628,8 @@ class Window_InputNumberPokemon < SpriteWindow_Base
def initialize(digits_max)
@digits_max = digits_max
@number = 0
@frame = 0
@cursor_timer_start = System.uptime
@cursor_shown = true
@sign = false
@negative = false
super(0, 0, 32, 32)
@@ -674,7 +688,11 @@ class Window_InputNumberPokemon < SpriteWindow_Base
def update
super
digits = @digits_max + (@sign ? 1 : 0)
refresh if @frame % 15 == 0
cursor_to_show = ((System.uptime - @cursor_timer_start) / 0.35).to_i % 2 == 0
if cursor_to_show != @cursor_shown
@cursor_shown = cursor_to_show
refresh
end
if self.active
if Input.repeat?(Input::UP) || Input.repeat?(Input::DOWN)
pbPlayCursorSE
@@ -696,19 +714,20 @@ class Window_InputNumberPokemon < SpriteWindow_Base
if digits >= 2
pbPlayCursorSE
@index = (@index + 1) % digits
@frame = 0
@cursor_timer_start = System.uptime
@cursor_shown = true
refresh
end
elsif Input.repeat?(Input::LEFT)
if digits >= 2
pbPlayCursorSE
@index = (@index + digits - 1) % digits
@frame = 0
@cursor_timer_start = System.uptime
@cursor_shown = true
refresh
end
end
end
@frame = (@frame + 1) % 30
end
#-----------------------------------------------------------------------------
@@ -721,8 +740,10 @@ class Window_InputNumberPokemon < SpriteWindow_Base
x + (12 - (textwidth / 2)),
y - 2 + (self.contents.text_offset_y || 0), # TEXT OFFSET (the - 2)
textwidth + 4, 32, text, @baseColor, @shadowColor)
if @index == i && @active && @frame / 15 == 0
self.contents.fill_rect(x + (12 - (textwidth / 2)), y + 30, textwidth, 2, @baseColor)
# Draw cursor
if @index == i && @active && @cursor_shown
self.contents.fill_rect(x + (12 - (textwidth / 2)), y + 28, textwidth, 4, @shadowColor)
self.contents.fill_rect(x + (12 - (textwidth / 2)), y + 28, textwidth - 2, 2, @baseColor)
end
end
end

View File

@@ -43,19 +43,19 @@ class PngAnimatedBitmap
def initialize(dir, filename, hue = 0)
@frames = []
@currentFrame = 0
@framecount = 0
@timer_start = System.uptime
panorama = RPG::Cache.load_bitmap(dir, filename, hue)
if filename[/^\[(\d+)(?:,(\d+))?\]/] # Starts with 1 or 2 numbers in brackets
# File has a frame count
numFrames = $1.to_i
delay = $2.to_i
delay = 10 if delay == 0
duration = $2.to_i
duration = 5 if duration == 0
raise "Invalid frame count in #{filename}" if numFrames <= 0
raise "Invalid frame delay in #{filename}" if delay <= 0
raise "Invalid frame duration in #{filename}" if duration <= 0
if panorama.width % numFrames != 0
raise "Bitmap's width (#{panorama.width}) is not divisible by frame count: #{filename}"
end
@frameDelay = delay
@frame_duration = duration
subWidth = panorama.width / numFrames
numFrames.times do |i|
subBitmap = Bitmap.new(subWidth, panorama.height)
@@ -68,6 +68,16 @@ class PngAnimatedBitmap
end
end
def dispose
return if @disposed
@frames.each { |f| f.dispose }
@disposed = true
end
def disposed?
return @disposed
end
def [](index)
return @frames[index]
end
@@ -75,15 +85,6 @@ class PngAnimatedBitmap
def width; self.bitmap.width; end
def height; self.bitmap.height; end
def deanimate
(1...@frames.length).each do |i|
@frames[i].dispose
end
@frames = [@frames[0]]
@currentFrame = 0
return @frames[0]
end
def bitmap
return @frames[@currentFrame]
end
@@ -92,43 +93,27 @@ class PngAnimatedBitmap
return @currentFrame
end
def frameDelay(_index)
return @frameDelay
end
def length
return @frames.length
end
# Actually returns the total number of 1/20ths of a second this animation lasts.
def totalFrames
return @frame_duration * @frames.length
end
def each
@frames.each { |item| yield item }
end
def totalFrames
return @frameDelay * @frames.length
end
def disposed?
return @disposed
end
def update
return if disposed?
if @frames.length > 1
@framecount += 1
if @framecount >= @frameDelay
@framecount = 0
@currentFrame += 1
@currentFrame %= @frames.length
end
def deanimate
(1...@frames.length).each do |i|
@frames[i].dispose
end
end
def dispose
if !@disposed
@frames.each { |f| f.dispose }
end
@disposed = true
@frames = [@frames[0]]
@currentFrame = 0
@frame_duration = 0
return @frames[0]
end
def copy
@@ -137,6 +122,13 @@ class PngAnimatedBitmap
x.frames.each_with_index { |frame, i| x.frames[i] = frame.copy }
return x
end
def update
return if disposed?
if @frames.length > 1
@currentFrame = ((System.uptime - @timer_start) / @frame_duration).to_i % @frames.length
end
end
end
#===============================================================================

View File

@@ -613,7 +613,7 @@ def pbMessageDisplay(msgwindow, message, letterbyletter = true, commandProc = ni
msgwindow.y = lerp(y_start, y_end, appear_duration, appear_timer_start, System.uptime)
end
when "ts" # Change text speed
msgwindow.textspeed = (param == "") ? -999 : param.to_i
msgwindow.textspeed = (param == "") ? 0 : param.to_i / 80.0
when "." # Wait 0.25 seconds
msgwindow.waitcount += 0.25
when "|" # Wait 1 second

View File

@@ -94,8 +94,9 @@ class Window_TextEntry < SpriteWindow_Base
end
@helper = CharacterEntryHelper.new(text)
@heading = heading
@cursor_timer_start = System.uptime
@cursor_shown = true
self.active = true
@frame = 0
refresh
end
@@ -128,7 +129,8 @@ class Window_TextEntry < SpriteWindow_Base
def insert(ch)
if @helper.insert(ch)
@frame = 0
@cursor_timer_start = System.uptime
@cursor_shown = true
self.refresh
return true
end
@@ -137,7 +139,8 @@ class Window_TextEntry < SpriteWindow_Base
def delete
if @helper.delete
@frame = 0
@cursor_timer_start = System.uptime
@cursor_shown = true
self.refresh
return true
end
@@ -145,21 +148,25 @@ class Window_TextEntry < SpriteWindow_Base
end
def update
@frame += 1
@frame %= 20
self.refresh if (@frame % 10) == 0
cursor_to_show = ((System.uptime - @cursor_timer_start) / 0.35).to_i % 2 == 0
if cursor_to_show != @cursor_shown
@cursor_shown = cursor_to_show
refresh
end
return if !self.active
# Moving cursor
if Input.repeat?(Input::LEFT) && Input.press?(Input::ACTION)
if @helper.cursor > 0
@helper.cursor -= 1
@frame = 0
@cursor_timer_start = System.uptime
@cursor_shown = true
self.refresh
end
elsif Input.repeat?(Input::RIGHT) && Input.press?(Input::ACTION)
if @helper.cursor < self.text.scan(/./m).length
@helper.cursor += 1
@frame = 0
@cursor_timer_start = System.uptime
@cursor_shown = true
self.refresh
end
elsif Input.repeat?(Input::BACK) # Backspace
@@ -201,13 +208,13 @@ class Window_TextEntry < SpriteWindow_Base
# Draw text
pbDrawShadowText(bitmap, x, y, textwidth + 4, 32, c, @baseColor, @shadowColor)
# Draw cursor if necessary
if ((@frame / 10) & 1) == 0 && i == @helper.cursor
if i == @helper.cursor && @cursor_shown
bitmap.fill_rect(x, y + 4, 2, 24, cursorcolor)
end
# Add x to drawn text width
x += textwidth
end
if ((@frame / 10) & 1) == 0 && textscan.length == @helper.cursor
if textscan.length == @helper.cursor && @cursor_shown
bitmap.fill_rect(x, y + 4, 2, 24, cursorcolor)
end
end
@@ -218,22 +225,26 @@ end
#===============================================================================
class Window_TextEntry_Keyboard < Window_TextEntry
def update
@frame += 1
@frame %= 20
self.refresh if (@frame % 10) == 0
cursor_to_show = ((System.uptime - @cursor_timer_start) / 0.35).to_i % 2 == 0
if cursor_to_show != @cursor_shown
@cursor_shown = cursor_to_show
refresh
end
return if !self.active
# Moving cursor
if Input.triggerex?(:LEFT) || Input.repeatex?(:LEFT)
if @helper.cursor > 0
@helper.cursor -= 1
@frame = 0
@cursor_timer_start = System.uptime
@cursor_shown = true
self.refresh
end
return
elsif Input.triggerex?(:RIGHT) || Input.repeatex?(:RIGHT)
if @helper.cursor < self.text.scan(/./m).length
@helper.cursor += 1
@frame = 0
@cursor_timer_start = System.uptime
@cursor_shown = true
self.refresh
end
return
@@ -260,7 +271,8 @@ class Window_MultilineTextEntry < SpriteWindow_Base
@firstline = 0
@cursorLine = 0
@cursorColumn = 0
@frame = 0
@cursor_timer_start = System.uptime
@cursor_shown = true
self.active = true
refresh
end
@@ -301,7 +313,8 @@ class Window_MultilineTextEntry < SpriteWindow_Base
def insert(ch)
@helper.cursor = getPosFromLineAndColumn(@cursorLine, @cursorColumn)
if @helper.insert(ch)
@frame = 0
@cursor_timer_start = System.uptime
@cursor_shown = true
@textchars = nil
moveCursor(0, 1)
self.refresh
@@ -313,7 +326,8 @@ class Window_MultilineTextEntry < SpriteWindow_Base
def delete
@helper.cursor = getPosFromLineAndColumn(@cursorLine, @cursorColumn)
if @helper.delete
@frame = 0
@cursor_timer_start = System.uptime
@cursor_shown = true
moveCursor(0, -1) # use old textchars
@textchars = nil
self.refresh
@@ -407,7 +421,8 @@ class Window_MultilineTextEntry < SpriteWindow_Base
# Calculate new cursor position
@helper.cursor = getPosFromLineAndColumn(@cursorLine, @cursorColumn)
if doRefresh
@frame = 0
@cursor_timer_start = System.uptime
@cursor_shown = true
self.refresh
end
@firstline = @cursorLine if @cursorLine < @firstline
@@ -450,9 +465,11 @@ class Window_MultilineTextEntry < SpriteWindow_Base
end
def update
@frame += 1
@frame %= 20
self.refresh if (@frame % 10) == 0
cursor_to_show = ((System.uptime - @cursor_timer_start) / 0.35).to_i % 2 == 0
if cursor_to_show != @cursor_shown
@cursor_shown = cursor_to_show
refresh
end
return if !self.active
# Moving cursor
if Input.triggerex?(:UP) || Input.repeatex?(:UP)
@@ -519,7 +536,7 @@ class Window_MultilineTextEntry < SpriteWindow_Base
pbDrawShadowText(bitmap, text[1], textY, textwidth, textheight, c, @baseColor, @shadowColor)
end
# Draw cursor
if ((@frame / 10) & 1) == 0
if @cursor_shown
textheight = bitmap.text_size("X").height
cursorY = (textheight * @cursorLine) - startY
cursorX = 0