mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-06 06:01:46 +00:00
More renaming and rearranging, fixed typo from earlier commit, tweaked splash and title screen code
This commit is contained in:
369
Data/Scripts/007_Objects and windows/008_AnimatedBitmap.rb
Normal file
369
Data/Scripts/007_Objects and windows/008_AnimatedBitmap.rb
Normal file
@@ -0,0 +1,369 @@
|
||||
# Disabling animated GIF stuff because gif.dll is awful,
|
||||
# but leaving the code here just in case someone wants
|
||||
# to make Linux and macOS versions of it for some reason
|
||||
=begin
|
||||
module GifLibrary
|
||||
@@loadlib = Win32API.new("Kernel32.dll","LoadLibrary",'p','')
|
||||
if safeExists?("gif.dll")
|
||||
PngDll = @@loadlib.call("gif.dll")
|
||||
GifToPngFiles = Win32API.new("gif.dll","GifToPngFiles",'pp','l')
|
||||
GifToPngFilesInMemory = Win32API.new("gif.dll","GifToPngFilesInMemory",'plp','l')
|
||||
CopyDataString = Win32API.new("gif.dll","CopyDataString",'lpl','l')
|
||||
FreeDataString = Win32API.new("gif.dll","FreeDataString",'l','')
|
||||
else
|
||||
PngDll=nil
|
||||
end
|
||||
|
||||
def self.getDataFromResult(result)
|
||||
datasize=CopyDataString.call(result,"",0)
|
||||
ret=nil
|
||||
if datasize!=0
|
||||
data="0"*datasize
|
||||
CopyDataString.call(result,data,datasize)
|
||||
ret=data.unpack("V*")
|
||||
end
|
||||
FreeDataString.call(result)
|
||||
return ret
|
||||
end
|
||||
end
|
||||
=end
|
||||
|
||||
|
||||
|
||||
class AnimatedBitmap
|
||||
def initialize(file,hue=0)
|
||||
if file==nil
|
||||
raise "Filename is nil (missing graphic)."
|
||||
end
|
||||
if file.split(/[\\\/]/)[-1][/^\[\d+(?:,\d+)?\]/] # Starts with 1 or 2 numbers in square brackets
|
||||
@bitmap = PngAnimatedBitmap.new(file,hue)
|
||||
else
|
||||
@bitmap = GifBitmap.new(file,hue)
|
||||
end
|
||||
end
|
||||
|
||||
def [](index); @bitmap[index]; end
|
||||
def width; @bitmap.bitmap.width; end
|
||||
def height; @bitmap.bitmap.height; end
|
||||
def length; @bitmap.length; end
|
||||
def each; @bitmap.each { |item| yield item }; end
|
||||
def bitmap; @bitmap.bitmap; end
|
||||
def currentIndex; @bitmap.currentIndex; end
|
||||
def frameDelay; @bitmap.frameDelay; end
|
||||
def totalFrames; @bitmap.totalFrames; end
|
||||
def disposed?; @bitmap.disposed?; end
|
||||
def update; @bitmap.update; end
|
||||
def dispose; @bitmap.dispose; end
|
||||
def deanimate; @bitmap.deanimate; end
|
||||
def copy; @bitmap.copy; end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class PngAnimatedBitmap
|
||||
# Creates an animated bitmap from a PNG file.
|
||||
def initialize(file,hue=0)
|
||||
@frames=[]
|
||||
@currentFrame=0
|
||||
@framecount=0
|
||||
panorama=RPG::Cache.load_bitmap("",file,hue)
|
||||
if file.split(/[\\\/]/)[-1][/^\[(\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
|
||||
raise "Invalid frame count in #{file}" if numFrames<=0
|
||||
raise "Invalid frame delay in #{file}" if delay<=0
|
||||
if panorama.width % numFrames != 0
|
||||
raise "Bitmap's width (#{panorama.width}) is not divisible by frame count: #{file}"
|
||||
end
|
||||
@frameDelay = delay
|
||||
subWidth=panorama.width/numFrames
|
||||
for i in 0...numFrames
|
||||
subBitmap=BitmapWrapper.new(subWidth,panorama.height)
|
||||
subBitmap.blt(0,0,panorama,Rect.new(subWidth*i,0,subWidth,panorama.height))
|
||||
@frames.push(subBitmap)
|
||||
end
|
||||
panorama.dispose
|
||||
else
|
||||
@frames=[panorama]
|
||||
end
|
||||
end
|
||||
|
||||
def [](index)
|
||||
return @frames[index]
|
||||
end
|
||||
|
||||
def width; self.bitmap.width; end
|
||||
|
||||
def height; self.bitmap.height; end
|
||||
|
||||
def deanimate
|
||||
for i in 1...@frames.length
|
||||
@frames[i].dispose
|
||||
end
|
||||
@frames=[@frames[0]]
|
||||
@currentFrame=0
|
||||
return @frames[0]
|
||||
end
|
||||
|
||||
def bitmap
|
||||
@frames[@currentFrame]
|
||||
end
|
||||
|
||||
def currentIndex
|
||||
@currentFrame
|
||||
end
|
||||
|
||||
def frameDelay(_index)
|
||||
return @frameDelay
|
||||
end
|
||||
|
||||
def length
|
||||
@frames.length
|
||||
end
|
||||
|
||||
def each
|
||||
@frames.each { |item| yield item}
|
||||
end
|
||||
|
||||
def totalFrames
|
||||
@frameDelay*@frames.length
|
||||
end
|
||||
|
||||
def disposed?
|
||||
@disposed
|
||||
end
|
||||
|
||||
def update
|
||||
return if disposed?
|
||||
if @frames.length>1
|
||||
@framecount+=1
|
||||
if @framecount>=@frameDelay
|
||||
@framecount=0
|
||||
@currentFrame+=1
|
||||
@currentFrame%=@frames.length
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def dispose
|
||||
if !@disposed
|
||||
for i in @frames
|
||||
i.dispose
|
||||
end
|
||||
end
|
||||
@disposed=true
|
||||
end
|
||||
|
||||
attr_accessor :frames # internal
|
||||
|
||||
def copy
|
||||
x=self.clone
|
||||
x.frames=x.frames.clone
|
||||
for i in 0...x.frames.length
|
||||
x.frames[i]=x.frames[i].copy
|
||||
end
|
||||
return x
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
#internal class
|
||||
class GifBitmap
|
||||
# Creates a bitmap from a GIF file with the specified
|
||||
# optional viewport. Can also load non-animated bitmaps.
|
||||
def initialize(file,hue=0)
|
||||
@gifbitmaps=[]
|
||||
@gifdelays=[]
|
||||
@totalframes=0
|
||||
@framecount=0
|
||||
@currentIndex=0
|
||||
@disposed=false
|
||||
bitmap=nil
|
||||
filestring=nil
|
||||
filestrName=nil
|
||||
file="" if !file
|
||||
file=canonicalize(file)
|
||||
begin
|
||||
bitmap=RPG::Cache.load_bitmap("",file,hue)
|
||||
rescue
|
||||
bitmap=nil
|
||||
end
|
||||
if !bitmap || (bitmap.width==32 && bitmap.height==32)
|
||||
if !file || file.length<1 || file[file.length-1]!=0x2F
|
||||
if (filestring=pbGetFileChar(file))
|
||||
filestrName=file
|
||||
elsif (filestring=pbGetFileChar(file+".gif"))
|
||||
filestrName=file+".gif"
|
||||
elsif (filestring=pbGetFileChar(file+".png"))
|
||||
filestrName=file+".png"
|
||||
# elsif (filestring=pbGetFileChar(file+".jpg"))
|
||||
# filestrName=file+".jpg"
|
||||
# elsif (filestring=pbGetFileChar(file+".bmp"))
|
||||
# filestrName=file+".bmp"
|
||||
end
|
||||
end
|
||||
end
|
||||
if bitmap && filestring && filestring[0].ord==0x47 &&
|
||||
bitmap.width==32 && bitmap.height==32
|
||||
#File.open("debug.txt","ab") { |f| f.puts("rejecting bitmap") }
|
||||
bitmap.dispose
|
||||
bitmap=nil
|
||||
end
|
||||
# Note: MKXP can open .gif files just fine, first frame only
|
||||
if bitmap
|
||||
#File.open("debug.txt","ab") { |f| f.puts("reusing bitmap") }
|
||||
# Have a regular non-animated bitmap
|
||||
@totalframes=1
|
||||
@framecount=0
|
||||
@gifbitmaps=[bitmap]
|
||||
@gifdelays=[1]
|
||||
else
|
||||
tmpBase=File.basename(file)+"_tmp_"
|
||||
filestring=pbGetFileString(filestrName) if filestring
|
||||
=begin
|
||||
Dir.chdir(ENV["TEMP"]) { # navigate to temp folder since game might be on a CD-ROM
|
||||
if filestring && filestring[0]==0x47 && GifLibrary::PngDll
|
||||
result=GifLibrary::GifToPngFilesInMemory.call(filestring,
|
||||
filestring.length,tmpBase)
|
||||
else
|
||||
result=0
|
||||
end
|
||||
if result>0
|
||||
@gifdelays=GifLibrary.getDataFromResult(result)
|
||||
@totalframes=@gifdelays.pop
|
||||
for i in 0...@gifdelays.length
|
||||
@gifdelays[i]=[@gifdelays[i],1].max
|
||||
bmfile=sprintf("%s%d.png",tmpBase,i)
|
||||
if safeExists?(bmfile)
|
||||
gifbitmap=BitmapWrapper.new(bmfile)
|
||||
@gifbitmaps.push(gifbitmap)
|
||||
bmfile.hue_change(hue) if hue!=0
|
||||
if hue==0 && @gifdelays.length==1
|
||||
RPG::Cache.setKey(file,gifbitmap)
|
||||
end
|
||||
File.delete(bmfile)
|
||||
else
|
||||
@gifbitmaps.push(BitmapWrapper.new(32,32))
|
||||
end
|
||||
end
|
||||
end
|
||||
}
|
||||
=end
|
||||
if @gifbitmaps.length==0
|
||||
@gifbitmaps=[BitmapWrapper.new(32,32)]
|
||||
@gifdelays=[1]
|
||||
end
|
||||
if @gifbitmaps.length==1
|
||||
RPG::Cache.setKey(file,@gifbitmaps[0])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def [](index)
|
||||
return @gifbitmaps[index]
|
||||
end
|
||||
|
||||
def deanimate
|
||||
for i in 1...@gifbitmaps.length
|
||||
@gifbitmaps[i].dispose
|
||||
end
|
||||
@gifbitmaps=[@gifbitmaps[0]]
|
||||
@currentIndex=0
|
||||
return @gifbitmaps[0]
|
||||
end
|
||||
|
||||
def bitmap
|
||||
@gifbitmaps[@currentIndex]
|
||||
end
|
||||
|
||||
def currentIndex
|
||||
@currentIndex
|
||||
end
|
||||
|
||||
def frameDelay(index)
|
||||
return @gifdelay[index]/2 # Due to frame count being incremented by 2
|
||||
end
|
||||
|
||||
def length
|
||||
@gifbitmaps.length
|
||||
end
|
||||
|
||||
def each
|
||||
@gifbitmaps.each { |item| yield item }
|
||||
end
|
||||
|
||||
def totalFrames
|
||||
@totalframes/2 # Due to frame count being incremented by 2
|
||||
end
|
||||
|
||||
def disposed?
|
||||
@disposed
|
||||
end
|
||||
|
||||
def width
|
||||
@gifbitmaps.length==0 ? 0 : @gifbitmaps[0].width
|
||||
end
|
||||
|
||||
def height
|
||||
@gifbitmaps.length==0 ? 0 : @gifbitmaps[0].height
|
||||
end
|
||||
|
||||
# This function must be called in order to animate the GIF image.
|
||||
def update
|
||||
return if disposed?
|
||||
if @gifbitmaps.length>0
|
||||
@framecount+=2
|
||||
@framecount=@totalframes<=0 ? 0 : @framecount%@totalframes
|
||||
frametoshow=0
|
||||
for i in 0...@gifdelays.length
|
||||
frametoshow=i if @gifdelays[i]<=@framecount
|
||||
end
|
||||
@currentIndex=frametoshow
|
||||
end
|
||||
end
|
||||
|
||||
def dispose
|
||||
if !@disposed
|
||||
for i in @gifbitmaps
|
||||
i.dispose
|
||||
end
|
||||
end
|
||||
@disposed=true
|
||||
end
|
||||
|
||||
attr_accessor :gifbitmaps # internal
|
||||
attr_accessor :gifdelays # internal
|
||||
|
||||
def copy
|
||||
x=self.clone
|
||||
x.gifbitmaps=x.gifbitmaps.clone
|
||||
x.gifdelays=x.gifdelays.clone
|
||||
for i in 0...x.gifbitmaps.length
|
||||
x.gifbitmaps[i]=x.gifbitmaps[i].copy
|
||||
end
|
||||
return x
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
def pbGetTileBitmap(filename, tile_id, hue, width = 1, height = 1)
|
||||
return RPG::Cache.tileEx(filename, tile_id, hue, width, height) { |f|
|
||||
AnimatedBitmap.new("Graphics/Tilesets/"+filename).deanimate
|
||||
}
|
||||
end
|
||||
|
||||
def pbGetTileset(name,hue=0)
|
||||
return AnimatedBitmap.new("Graphics/Tilesets/"+name,hue).deanimate
|
||||
end
|
||||
|
||||
def pbGetAutotile(name,hue=0)
|
||||
return AnimatedBitmap.new("Graphics/Autotiles/"+name,hue).deanimate
|
||||
end
|
||||
|
||||
def pbGetAnimation(name,hue=0)
|
||||
return AnimatedBitmap.new("Graphics/Animations/"+name,hue).deanimate
|
||||
end
|
||||
Reference in New Issue
Block a user