Stopped errors happening when trying to load a graphic without a filename

This commit is contained in:
Maruno17
2021-04-08 22:28:05 +01:00
parent 327d0de334
commit 614e0ed9a2
2 changed files with 152 additions and 151 deletions

View File

@@ -251,18 +251,19 @@ end
# Gets at least the first byte of a file. Doesn't check RTP, but does check # Gets at least the first byte of a file. Doesn't check RTP, but does check
# encrypted archives. # encrypted archives.
def pbGetFileChar(file) def pbGetFileChar(file)
file = canonicalize(file) canon_file = canonicalize(file)
if !safeExists?("./Game.rgssad") if !safeExists?("./Game.rgssad")
return nil if !safeExists?(file) return nil if !safeExists?(canon_file)
return nil if file.last == '/' # Is a directory
begin begin
File.open(file,"rb") { |f| return f.read(1) } # read one byte File.open(canon_file, "rb") { |f| return f.read(1) } # read one byte
rescue Errno::ENOENT, Errno::EINVAL, Errno::EACCES, Errno::EISDIR rescue Errno::ENOENT, Errno::EINVAL, Errno::EACCES, Errno::EISDIR
return nil return nil
end end
end end
str = nil str = nil
begin begin
str = load_data(file, true) str = load_data(canon_file, true)
rescue Errno::ENOENT, Errno::EINVAL, Errno::EACCES, Errno::EISDIR, RGSSError, MKXPError rescue Errno::ENOENT, Errno::EINVAL, Errno::EACCES, Errno::EISDIR, RGSSError, MKXPError
str = nil str = nil
end end

View File

@@ -3,24 +3,24 @@
# to make Linux and macOS versions of it for some reason # to make Linux and macOS versions of it for some reason
=begin =begin
module GifLibrary module GifLibrary
@@loadlib = Win32API.new("Kernel32.dll","LoadLibrary",'p','') @@loadlib = Win32API.new("Kernel32.dll", "LoadLibrary", 'p', '')
if safeExists?("gif.dll") if safeExists?("gif.dll")
PngDll = @@loadlib.call("gif.dll") PngDll = @@loadlib.call("gif.dll")
GifToPngFiles = Win32API.new("gif.dll","GifToPngFiles",'pp','l') GifToPngFiles = Win32API.new("gif.dll", "GifToPngFiles", 'pp', 'l')
GifToPngFilesInMemory = Win32API.new("gif.dll","GifToPngFilesInMemory",'plp','l') GifToPngFilesInMemory = Win32API.new("gif.dll", "GifToPngFilesInMemory", 'plp', 'l')
CopyDataString = Win32API.new("gif.dll","CopyDataString",'lpl','l') CopyDataString = Win32API.new("gif.dll", "CopyDataString", 'lpl', 'l')
FreeDataString = Win32API.new("gif.dll","FreeDataString",'l','') FreeDataString = Win32API.new("gif.dll", "FreeDataString", 'l', '')
else else
PngDll=nil PngDll = nil
end end
def self.getDataFromResult(result) def self.getDataFromResult(result)
datasize=CopyDataString.call(result,"",0) datasize = CopyDataString.call(result, "", 0)
ret=nil ret = nil
if datasize!=0 if datasize != 0
data="0"*datasize data = "0" * datasize
CopyDataString.call(result,data,datasize) CopyDataString.call(result, data, datasize)
ret=data.unpack("V*") ret = data.unpack("V*")
end end
FreeDataString.call(result) FreeDataString.call(result)
return ret return ret
@@ -31,14 +31,19 @@ end
class AnimatedBitmap class AnimatedBitmap
def initialize(file,hue=0) def initialize(file, hue = 0)
if file==nil raise "Filename is nil (missing graphic)." if file.nil?
raise "Filename is nil (missing graphic)." path = file
filename = ""
if file.last != '/' # Isn't just a directory
split_file = file.split(/[\\\/]/)
filename = split_file.pop
path = split_file.join('/') + '/'
end end
if file.split(/[\\\/]/)[-1][/^\[\d+(?:,\d+)?\]/] # Starts with 1 or 2 numbers in square brackets if filename[/^\[\d+(?:,\d+)?\]/] # Starts with 1 or 2 numbers in square brackets
@bitmap = PngAnimatedBitmap.new(file,hue) @bitmap = PngAnimatedBitmap.new(path, filename, hue)
else else
@bitmap = GifBitmap.new(file,hue) @bitmap = GifBitmap.new(path, filename, hue)
end end
end end
@@ -61,32 +66,34 @@ end
class PngAnimatedBitmap class PngAnimatedBitmap
attr_accessor :frames
# Creates an animated bitmap from a PNG file. # Creates an animated bitmap from a PNG file.
def initialize(file,hue=0) def initialize(dir, filename, hue = 0)
@frames=[] @frames = []
@currentFrame=0 @currentFrame = 0
@framecount=0 @framecount = 0
panorama=RPG::Cache.load_bitmap("",file,hue) panorama = RPG::Cache.load_bitmap(dir, filename, hue)
if file.split(/[\\\/]/)[-1][/^\[(\d+)(?:,(\d+))?\]/] # Starts with 1 or 2 numbers in brackets if filename[/^\[(\d+)(?:,(\d+))?\]/] # Starts with 1 or 2 numbers in brackets
# File has a frame count # File has a frame count
numFrames = $1.to_i numFrames = $1.to_i
delay = $2.to_i delay = $2.to_i
delay = 10 if delay == 0 delay = 10 if delay == 0
raise "Invalid frame count in #{file}" if numFrames<=0 raise "Invalid frame count in #{filename}" if numFrames <= 0
raise "Invalid frame delay in #{file}" if delay<=0 raise "Invalid frame delay in #{filename}" if delay <= 0
if panorama.width % numFrames != 0 if panorama.width % numFrames != 0
raise "Bitmap's width (#{panorama.width}) is not divisible by frame count: #{file}" raise "Bitmap's width (#{panorama.width}) is not divisible by frame count: #{filename}"
end end
@frameDelay = delay @frameDelay = delay
subWidth=panorama.width/numFrames subWidth = panorama.width / numFrames
for i in 0...numFrames for i in 0...numFrames
subBitmap=BitmapWrapper.new(subWidth,panorama.height) subBitmap = BitmapWrapper.new(subWidth, panorama.height)
subBitmap.blt(0,0,panorama,Rect.new(subWidth*i,0,subWidth,panorama.height)) subBitmap.blt(0, 0, panorama, Rect.new(subWidth * i, 0, subWidth, panorama.height))
@frames.push(subBitmap) @frames.push(subBitmap)
end end
panorama.dispose panorama.dispose
else else
@frames=[panorama] @frames = [panorama]
end end
end end
@@ -95,24 +102,23 @@ class PngAnimatedBitmap
end end
def width; self.bitmap.width; end def width; self.bitmap.width; end
def height; self.bitmap.height; end def height; self.bitmap.height; end
def deanimate def deanimate
for i in 1...@frames.length for i in 1...@frames.length
@frames[i].dispose @frames[i].dispose
end end
@frames=[@frames[0]] @frames = [@frames[0]]
@currentFrame=0 @currentFrame = 0
return @frames[0] return @frames[0]
end end
def bitmap def bitmap
@frames[@currentFrame] return @frames[@currentFrame]
end end
def currentIndex def currentIndex
@currentFrame return @currentFrame
end end
def frameDelay(_index) def frameDelay(_index)
@@ -120,49 +126,45 @@ class PngAnimatedBitmap
end end
def length def length
@frames.length return @frames.length
end end
def each def each
@frames.each { |item| yield item} @frames.each { |item| yield item }
end end
def totalFrames def totalFrames
@frameDelay*@frames.length return @frameDelay * @frames.length
end end
def disposed? def disposed?
@disposed return @disposed
end end
def update def update
return if disposed? return if disposed?
if @frames.length>1 if @frames.length > 1
@framecount+=1 @framecount += 1
if @framecount>=@frameDelay if @framecount >= @frameDelay
@framecount=0 @framecount = 0
@currentFrame+=1 @currentFrame += 1
@currentFrame%=@frames.length @currentFrame %= @frames.length
end end
end end
end end
def dispose def dispose
if !@disposed if !@disposed
for i in @frames @frames.each { |f| f.dispose }
i.dispose
end end
@disposed = true
end end
@disposed=true
end
attr_accessor :frames # internal
def copy def copy
x=self.clone x = self.clone
x.frames=x.frames.clone x.frames = x.frames.clone
for i in 0...x.frames.length for i in 0...x.frames.length
x.frames[i]=x.frames[i].copy x.frames[i] = x.frames[i].copy
end end
return x return x
end end
@@ -172,92 +174,95 @@ end
#internal class #internal class
class GifBitmap class GifBitmap
attr_accessor :gifbitmaps # internal
attr_accessor :gifdelays # internal
# Creates a bitmap from a GIF file with the specified # Creates a bitmap from a GIF file with the specified
# optional viewport. Can also load non-animated bitmaps. # optional viewport. Can also load non-animated bitmaps.
def initialize(file,hue=0) def initialize(dir, filename, hue = 0)
@gifbitmaps=[] @gifbitmaps = []
@gifdelays=[] @gifdelays = []
@totalframes=0 @totalframes = 0
@framecount=0 @framecount = 0
@currentIndex=0 @currentIndex = 0
@disposed=false @disposed = false
bitmap=nil bitmap = nil
filestring=nil filestring = nil
filestrName=nil filestrName = nil
file="" if !file filename = "" if !filename
file=canonicalize(file) full_path = canonicalize(dir + filename)
begin begin
bitmap=RPG::Cache.load_bitmap("",file,hue) bitmap = RPG::Cache.load_bitmap(dir, filename, hue)
rescue rescue
bitmap=nil bitmap = nil
end end
if !bitmap || (bitmap.width==32 && bitmap.height==32) if !bitmap || (bitmap.width == 32 && bitmap.height == 32)
if !file || file.length<1 || file[file.length-1]!=0x2F if !full_path || full_path.length < 1 || full_path[full_path.length - 1] != 0x2F
if (filestring=pbGetFileChar(file)) if (filestring = pbGetFileChar(full_path))
filestrName=file filestrName = full_path
elsif (filestring=pbGetFileChar(file+".gif")) elsif (filestring = pbGetFileChar(full_path + ".gif"))
filestrName=file+".gif" filestrName = full_path + ".gif"
elsif (filestring=pbGetFileChar(file+".png")) elsif (filestring = pbGetFileChar(full_path + ".png"))
filestrName=file+".png" filestrName = full_path + ".png"
# elsif (filestring=pbGetFileChar(file+".jpg")) # elsif (filestring = pbGetFileChar(full_path + ".jpg"))
# filestrName=file+".jpg" # filestrName = full_path + ".jpg"
# elsif (filestring=pbGetFileChar(file+".bmp")) # elsif (filestring = pbGetFileChar(full_path + ".bmp"))
# filestrName=file+".bmp" # filestrName = full_path + ".bmp"
end end
end end
end end
if bitmap && filestring && filestring[0].ord==0x47 && if bitmap && filestring && filestring[0].ord == 0x47 &&
bitmap.width==32 && bitmap.height==32 bitmap.width == 32 && bitmap.height == 32
#File.open("debug.txt","ab") { |f| f.puts("rejecting bitmap") } # File.open("debug.txt","ab") { |f| f.puts("rejecting bitmap") }
bitmap.dispose bitmap.dispose
bitmap=nil bitmap = nil
end end
# Note: MKXP can open .gif files just fine, first frame only # Note: MKXP can open .gif files just fine, first frame only
if bitmap if bitmap
#File.open("debug.txt","ab") { |f| f.puts("reusing bitmap") } # File.open("debug.txt","ab") { |f| f.puts("reusing bitmap") }
# Have a regular non-animated bitmap # Have a regular non-animated bitmap
@totalframes=1 @totalframes = 1
@framecount=0 @framecount = 0
@gifbitmaps=[bitmap] @gifbitmaps = [bitmap]
@gifdelays=[1] @gifdelays = [1]
else else
tmpBase=File.basename(file)+"_tmp_" tmpBase = File.basename(full_path) + "_tmp_"
filestring=pbGetFileString(filestrName) if filestring filestring = pbGetFileString(filestrName) if filestring
=begin =begin
Dir.chdir(ENV["TEMP"]) { # navigate to temp folder since game might be on a CD-ROM Dir.chdir(ENV["TEMP"]) { # navigate to temp folder since game might be on a CD-ROM
if filestring && filestring[0]==0x47 && GifLibrary::PngDll if filestring && filestring[0] == 0x47 && GifLibrary::PngDll
result=GifLibrary::GifToPngFilesInMemory.call(filestring, result = GifLibrary::GifToPngFilesInMemory.call(filestring,
filestring.length,tmpBase) filestring.length, tmpBase)
else else
result=0 result = 0
end end
if result>0 if result >0
@gifdelays=GifLibrary.getDataFromResult(result) @gifdelays = GifLibrary.getDataFromResult(result)
@totalframes=@gifdelays.pop @totalframes = @gifdelays.pop
for i in 0...@gifdelays.length for i in 0...@gifdelays.length
@gifdelays[i]=[@gifdelays[i],1].max @gifdelays[i] = [@gifdelays[i], 1].max
bmfile=sprintf("%s%d.png",tmpBase,i) bmfile = sprintf("%s%d.png", tmpBase, i)
if safeExists?(bmfile) if safeExists?(bmfile)
gifbitmap=BitmapWrapper.new(bmfile) gifbitmap = BitmapWrapper.new(bmfile)
@gifbitmaps.push(gifbitmap) @gifbitmaps.push(gifbitmap)
bmfile.hue_change(hue) if hue!=0 bmfile.hue_change(hue) if hue != 0
if hue==0 && @gifdelays.length==1 if hue == 0 && @gifdelays.length == 1
RPG::Cache.setKey(file,gifbitmap) RPG::Cache.setKey(full_path, gifbitmap)
end end
File.delete(bmfile) File.delete(bmfile)
else else
@gifbitmaps.push(BitmapWrapper.new(32,32)) @gifbitmaps.push(BitmapWrapper.new(32, 32))
end end
end end
end end
} }
=end =end
if @gifbitmaps.length==0 if @gifbitmaps.length == 0
@gifbitmaps=[BitmapWrapper.new(32,32)] @gifbitmaps = [BitmapWrapper.new(32, 32)]
@gifdelays=[1] @gifdelays = [1]
end end
if @gifbitmaps.length==1 if @gifbitmaps.length == 1
RPG::Cache.setKey(file,@gifbitmaps[0]) RPG::Cache.setKey(full_path, @gifbitmaps[0])
end end
end end
end end
@@ -270,25 +275,25 @@ class GifBitmap
for i in 1...@gifbitmaps.length for i in 1...@gifbitmaps.length
@gifbitmaps[i].dispose @gifbitmaps[i].dispose
end end
@gifbitmaps=[@gifbitmaps[0]] @gifbitmaps = [@gifbitmaps[0]]
@currentIndex=0 @currentIndex = 0
return @gifbitmaps[0] return @gifbitmaps[0]
end end
def bitmap def bitmap
@gifbitmaps[@currentIndex] return @gifbitmaps[@currentIndex]
end end
def currentIndex def currentIndex
@currentIndex return @currentIndex
end end
def frameDelay(index) def frameDelay(index)
return @gifdelay[index]/2 # Due to frame count being incremented by 2 return @gifdelay[index] / 2 # Due to frame count being incremented by 2
end end
def length def length
@gifbitmaps.length return @gifbitmaps.length
end end
def each def each
@@ -296,53 +301,48 @@ class GifBitmap
end end
def totalFrames def totalFrames
@totalframes/2 # Due to frame count being incremented by 2 return @totalframes / 2 # Due to frame count being incremented by 2
end end
def disposed? def disposed?
@disposed return @disposed
end end
def width def width
@gifbitmaps.length==0 ? 0 : @gifbitmaps[0].width return (@gifbitmaps.length == 0) ? 0 : @gifbitmaps[0].width
end end
def height def height
@gifbitmaps.length==0 ? 0 : @gifbitmaps[0].height return (@gifbitmaps.length == 0) ? 0 : @gifbitmaps[0].height
end end
# This function must be called in order to animate the GIF image. # This function must be called in order to animate the GIF image.
def update def update
return if disposed? return if disposed?
if @gifbitmaps.length>0 if @gifbitmaps.length > 0
@framecount+=2 @framecount += 2
@framecount=@totalframes<=0 ? 0 : @framecount%@totalframes @framecount = (@totalframes <= 0) ? 0 : @framecount % @totalframes
frametoshow=0 frametoshow = 0
for i in 0...@gifdelays.length for i in 0...@gifdelays.length
frametoshow=i if @gifdelays[i]<=@framecount frametoshow = i if @gifdelays[i] <= @framecount
end end
@currentIndex=frametoshow @currentIndex = frametoshow
end end
end end
def dispose def dispose
if !@disposed if !@disposed
for i in @gifbitmaps @gifbitmaps.each { |b| b.dispose }
i.dispose
end end
@disposed = true
end end
@disposed=true
end
attr_accessor :gifbitmaps # internal
attr_accessor :gifdelays # internal
def copy def copy
x=self.clone x = self.clone
x.gifbitmaps=x.gifbitmaps.clone x.gifbitmaps = x.gifbitmaps.clone
x.gifdelays=x.gifdelays.clone x.gifdelays = x.gifdelays.clone
for i in 0...x.gifbitmaps.length for i in 0...x.gifbitmaps.length
x.gifbitmaps[i]=x.gifbitmaps[i].copy x.gifbitmaps[i] = x.gifbitmaps[i].copy
end end
return x return x
end end
@@ -352,18 +352,18 @@ end
def pbGetTileBitmap(filename, tile_id, hue, width = 1, height = 1) def pbGetTileBitmap(filename, tile_id, hue, width = 1, height = 1)
return RPG::Cache.tileEx(filename, tile_id, hue, width, height) { |f| return RPG::Cache.tileEx(filename, tile_id, hue, width, height) { |f|
AnimatedBitmap.new("Graphics/Tilesets/"+filename).deanimate AnimatedBitmap.new("Graphics/Tilesets/" + filename).deanimate
} }
end end
def pbGetTileset(name,hue=0) def pbGetTileset(name,hue=0)
return AnimatedBitmap.new("Graphics/Tilesets/"+name,hue).deanimate return AnimatedBitmap.new("Graphics/Tilesets/" + name, hue).deanimate
end end
def pbGetAutotile(name,hue=0) def pbGetAutotile(name,hue=0)
return AnimatedBitmap.new("Graphics/Autotiles/"+name,hue).deanimate return AnimatedBitmap.new("Graphics/Autotiles/" + name, hue).deanimate
end end
def pbGetAnimation(name,hue=0) def pbGetAnimation(name,hue=0)
return AnimatedBitmap.new("Graphics/Animations/"+name,hue).deanimate return AnimatedBitmap.new("Graphics/Animations/" + name, hue).deanimate
end end