diff --git a/.gitignore b/.gitignore index 81a3690..8d32390 100644 --- a/.gitignore +++ b/.gitignore @@ -4,13 +4,23 @@ *.vert.xxd *.frag.xxd *.ttf.xxd +*.png.xxd +*.h.xxd Makefile mkxp +mkxp.wasm +mkxp.html +mkxp.js xxd+ /build +/deps +/CMakeFiles + +CMakeCache.txt +cmake_install.cmake # Codeblocks mkxp.layout diff --git a/CMakeLists.txt b/CMakeLists.txt index 3685ac1..6400572 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -379,15 +379,11 @@ if(APPLE) endif() link_directories( - ../libsigc++-2.10.3/sigc++/.libs - ../pixman-0.40.0/pixman/.libs - ../physfs-3.0.2 - ../ruby - #../mruby/build/host/lib - ../mruby/build/x86_64-pc-linux-gnu/lib - libs + deps/libsigc++/sigc++/.libs + deps/pixman/pixman/.libs + deps/physfs + deps/mruby/build/wasm32-unknown-gnu/lib - #../SDL_sound/.libs ${SDL2_LIBRARY_DIRS} ) @@ -405,34 +401,18 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE target_include_directories(${PROJECT_NAME} PRIVATE src windows - ../libsigc++-2.10.3 - ../pixman-0.40.0/pixman - ../physfs-3.0.2/src - ../mruby/include - - - #../SDL_sound + deps/libsigc++ + deps/pixman/pixman + deps/physfs/src + deps/mruby/include ${SDL2_INCLUDE_DIRS} - #${VORBISFILE_INCLUDE_DIRS} ${FLUID_INCLUDE_DIRS} ${OPENAL_INCLUDE_DIR} ) target_link_libraries(${PROJECT_NAME} - #ruby-static.a - - sigc-2.0.a physfs.a pixman-1.a - #sigc-2.0.x86.a physfs.x86.a SDL_sound.x86.a pixman-1.x86.a - - mruby.a - - #SDL_sound.a - #ruby-static.x86.a - #crypt - #dl - #pthread - #rt + sigc-2.0.a physfs.a pixman-1.a mruby.a ${SDL2_LIBRARIES} ${SDL2_IMAGE_LIBRARIES} @@ -462,7 +442,6 @@ set_target_properties( PROPERTIES OUTPUT_NAME "mkxp" SUFFIX ".html" -# SUFFIX ".out" ) PostBuildMacBundle(${PROJECT_NAME} "" "${PLATFORM_COPY_LIBS}") diff --git a/extra/build_config.rb b/extra/build_config.rb new file mode 100644 index 0000000..0972677 --- /dev/null +++ b/extra/build_config.rb @@ -0,0 +1,20 @@ +MRuby::Build.new do |conf| + toolchain :gcc + conf.gembox 'default' +end + +MRuby::CrossBuild.new('wasm32-unknown-gnu') do |conf| + toolchain :clang + + conf.gembox 'default' + conf.gem :github => 'take-cheeze/mruby-marshal' + conf.gem :github => 'monochromegane/mruby-time-strftime' + conf.gem :core => 'mruby-eval' + conf.cc.command = 'emcc' + conf.cc.flags = %W(-O3 -g0) + conf.cxx.command = 'em++' + conf.cxx.flags = %W(-O3 -g0) + + conf.linker.command = 'emcc' + conf.archiver.command = 'emar' +end diff --git a/extra/convert.sh b/extra/convert_audio.sh similarity index 100% rename from extra/convert.sh rename to extra/convert_audio.sh diff --git a/js/localforage.min.js b/extra/js/localforage.min.js similarity index 100% rename from js/localforage.min.js rename to extra/js/localforage.min.js diff --git a/extra/make_mapping.sh b/extra/make_mapping.sh index 9f56990..8965c86 100755 --- a/extra/make_mapping.sh +++ b/extra/make_mapping.sh @@ -7,7 +7,13 @@ do filename="${file%.*}" fl="$(echo "$filename" | tr '[:upper:]' '[:lower:]')" -md5=`md5sum "${file}" | awk '{ print $1 }'` + +if [ -f $file ] +then + md5=`md5sum "${file}" | awk '{ print $1 }'` +else + md5='' +fi echo "\"$fl\": \"${file}?h=${md5}\"," >> mapping.js diff --git a/extra/rgss.rb b/extra/rgss.rb new file mode 100644 index 0000000..e6cd4c3 --- /dev/null +++ b/extra/rgss.rb @@ -0,0 +1,1476 @@ +module RPG + module Cache + @cache = {} + def self.load_bitmap(folder_name, filename, hue = 0) + path = folder_name + filename + if not @cache.include?(path) or @cache[path].disposed? + if filename != "" + @cache[path] = Bitmap.new(path) + else + @cache[path] = Bitmap.new(32, 32) + end + end + if hue == 0 + @cache[path] + else + key = [path, hue] + if not @cache.include?(key) or @cache[key].disposed? + @cache[key] = @cache[path].clone + @cache[key].hue_change(hue) + end + @cache[key] + end + end + def self.animation(filename, hue) + self.load_bitmap("Graphics/Animations/", filename, hue) + end + def self.autotile(filename) + self.load_bitmap("Graphics/Autotiles/", filename) + end + def self.battleback(filename) + self.load_bitmap("Graphics/Battlebacks/", filename) + end + def self.battler(filename, hue) + self.load_bitmap("Graphics/Battlers/", filename, hue) + end + def self.character(filename, hue) + self.load_bitmap("Graphics/Characters/", filename, hue) + end + def self.fog(filename, hue) + self.load_bitmap("Graphics/Fogs/", filename, hue) + end + def self.gameover(filename) + self.load_bitmap("Graphics/Gameovers/", filename) + end + def self.icon(filename) + self.load_bitmap("Graphics/Icons/", filename) + end + def self.panorama(filename, hue) + self.load_bitmap("Graphics/Panoramas/", filename, hue) + end + def self.picture(filename) + self.load_bitmap("Graphics/Pictures/", filename) + end + def self.tileset(filename) + self.load_bitmap("Graphics/Tilesets/", filename) + end + def self.title(filename) + self.load_bitmap("Graphics/Titles/", filename) + end + def self.windowskin(filename) + self.load_bitmap("Graphics/Windowskins/", filename) + end + def self.tile(filename, tile_id, hue) + key = [filename, tile_id, hue] + if not @cache.include?(key) or @cache[key].disposed? + @cache[key] = Bitmap.new(32, 32) + x = (tile_id - 384) % 8 * 32 + y = (tile_id - 384) / 8 * 32 + rect = Rect.new(x, y, 32, 32) + @cache[key].blt(0, 0, self.tileset(filename), rect) + @cache[key].hue_change(hue) + end + @cache[key] + end + def self.clear + @cache = {} + GC.start + end + end + + class Sprite < ::Sprite + @@_animations = [] + @@_reference_count = {} + def initialize(viewport = nil) + super(viewport) + @_whiten_duration = 0 + @_appear_duration = 0 + @_escape_duration = 0 + @_collapse_duration = 0 + @_damage_duration = 0 + @_animation_duration = 0 + @_blink = false + end + def dispose + dispose_damage + dispose_animation + dispose_loop_animation + super + end + def whiten + self.blend_type = 0 + self.color.set(255, 255, 255, 128) + self.opacity = 255 + @_whiten_duration = 16 + @_appear_duration = 0 + @_escape_duration = 0 + @_collapse_duration = 0 + end + def appear + self.blend_type = 0 + self.color.set(0, 0, 0, 0) + self.opacity = 0 + @_appear_duration = 16 + @_whiten_duration = 0 + @_escape_duration = 0 + @_collapse_duration = 0 + end + def escape + self.blend_type = 0 + self.color.set(0, 0, 0, 0) + self.opacity = 255 + @_escape_duration = 32 + @_whiten_duration = 0 + @_appear_duration = 0 + @_collapse_duration = 0 + end + def collapse + self.blend_type = 1 + self.color.set(255, 64, 64, 255) + self.opacity = 255 + @_collapse_duration = 48 + @_whiten_duration = 0 + @_appear_duration = 0 + @_escape_duration = 0 + end + def damage(value, critical) + dispose_damage + if value.is_a?(Numeric) + damage_string = value.abs.to_s + else + damage_string = value.to_s + end + bitmap = Bitmap.new(160, 48) + bitmap.font.name = "Arial Black" + bitmap.font.size = 32 + bitmap.font.color.set(0, 0, 0) + bitmap.draw_text(-1, 12-1, 160, 36, damage_string, 1) + bitmap.draw_text(+1, 12-1, 160, 36, damage_string, 1) + bitmap.draw_text(-1, 12+1, 160, 36, damage_string, 1) + bitmap.draw_text(+1, 12+1, 160, 36, damage_string, 1) + if value.is_a?(Numeric) and value < 0 + bitmap.font.color.set(176, 255, 144) + else + bitmap.font.color.set(255, 255, 255) + end + bitmap.draw_text(0, 12, 160, 36, damage_string, 1) + if critical + bitmap.font.size = 20 + bitmap.font.color.set(0, 0, 0) + bitmap.draw_text(-1, -1, 160, 20, "CRITICAL", 1) + bitmap.draw_text(+1, -1, 160, 20, "CRITICAL", 1) + bitmap.draw_text(-1, +1, 160, 20, "CRITICAL", 1) + bitmap.draw_text(+1, +1, 160, 20, "CRITICAL", 1) + bitmap.font.color.set(255, 255, 255) + bitmap.draw_text(0, 0, 160, 20, "CRITICAL", 1) + end + @_damage_sprite = ::Sprite.new(self.viewport) + @_damage_sprite.bitmap = bitmap + @_damage_sprite.ox = 80 + @_damage_sprite.oy = 20 + @_damage_sprite.x = self.x + @_damage_sprite.y = self.y - self.oy / 2 + @_damage_sprite.z = 3000 + @_damage_duration = 40 + end + def animation(animation, hit) + dispose_animation + @_animation = animation + return if @_animation == nil + @_animation_hit = hit + @_animation_duration = @_animation.frame_max + animation_name = @_animation.animation_name + animation_hue = @_animation.animation_hue + bitmap = RPG::Cache.animation(animation_name, animation_hue) + if @@_reference_count.include?(bitmap) + @@_reference_count[bitmap] += 1 + else + @@_reference_count[bitmap] = 1 + end + @_animation_sprites = [] + if @_animation.position != 3 or not @@_animations.include?(animation) + for i in 0..15 + sprite = ::Sprite.new(self.viewport) + sprite.bitmap = bitmap + sprite.visible = false + @_animation_sprites.push(sprite) + end + unless @@_animations.include?(animation) + @@_animations.push(animation) + end + end + update_animation + end + def loop_animation(animation) + return if animation == @_loop_animation + dispose_loop_animation + @_loop_animation = animation + return if @_loop_animation == nil + @_loop_animation_index = 0 + animation_name = @_loop_animation.animation_name + animation_hue = @_loop_animation.animation_hue + bitmap = RPG::Cache.animation(animation_name, animation_hue) + if @@_reference_count.include?(bitmap) + @@_reference_count[bitmap] += 1 + else + @@_reference_count[bitmap] = 1 + end + @_loop_animation_sprites = [] + for i in 0..15 + sprite = ::Sprite.new(self.viewport) + sprite.bitmap = bitmap + sprite.visible = false + @_loop_animation_sprites.push(sprite) + end + update_loop_animation + end + def dispose_damage + if @_damage_sprite != nil + @_damage_sprite.bitmap.dispose + @_damage_sprite.dispose + @_damage_sprite = nil + @_damage_duration = 0 + end + end + def dispose_animation + if @_animation_sprites != nil + sprite = @_animation_sprites[0] + if sprite != nil + @@_reference_count[sprite.bitmap] -= 1 + if @@_reference_count[sprite.bitmap] == 0 + sprite.bitmap.dispose + end + end + for sprite in @_animation_sprites + sprite.dispose + end + @_animation_sprites = nil + @_animation = nil + end + end + def dispose_loop_animation + if @_loop_animation_sprites != nil + sprite = @_loop_animation_sprites[0] + if sprite != nil + @@_reference_count[sprite.bitmap] -= 1 + if @@_reference_count[sprite.bitmap] == 0 + sprite.bitmap.dispose + end + end + for sprite in @_loop_animation_sprites + sprite.dispose + end + @_loop_animation_sprites = nil + @_loop_animation = nil + end + end + def blink_on + unless @_blink + @_blink = true + @_blink_count = 0 + end + end + def blink_off + if @_blink + @_blink = false + self.color.set(0, 0, 0, 0) + end + end + def blink? + @_blink + end + def effect? + @_whiten_duration > 0 or + @_appear_duration > 0 or + @_escape_duration > 0 or + @_collapse_duration > 0 or + @_damage_duration > 0 or + @_animation_duration > 0 + end + def update + super + if @_whiten_duration > 0 + @_whiten_duration -= 1 + self.color.alpha = 128 - (16 - @_whiten_duration) * 10 + end + if @_appear_duration > 0 + @_appear_duration -= 1 + self.opacity = (16 - @_appear_duration) * 16 + end + if @_escape_duration > 0 + @_escape_duration -= 1 + self.opacity = 256 - (32 - @_escape_duration) * 10 + end + if @_collapse_duration > 0 + @_collapse_duration -= 1 + self.opacity = 256 - (48 - @_collapse_duration) * 6 + end + if @_damage_duration > 0 + @_damage_duration -= 1 + case @_damage_duration + when 38..39 + @_damage_sprite.y -= 4 + when 36..37 + @_damage_sprite.y -= 2 + when 34..35 + @_damage_sprite.y += 2 + when 28..33 + @_damage_sprite.y += 4 + end + @_damage_sprite.opacity = 256 - (12 - @_damage_duration) * 32 + if @_damage_duration == 0 + dispose_damage + end + end + if @_animation != nil and (Graphics.frame_count % 2 == 0) + @_animation_duration -= 1 + update_animation + end + if @_loop_animation != nil and (Graphics.frame_count % 2 == 0) + update_loop_animation + @_loop_animation_index += 1 + @_loop_animation_index %= @_loop_animation.frame_max + end + if @_blink + @_blink_count = (@_blink_count + 1) % 32 + if @_blink_count < 16 + alpha = (16 - @_blink_count) * 6 + else + alpha = (@_blink_count - 16) * 6 + end + self.color.set(255, 255, 255, alpha) + end + @@_animations.clear + end + def update_animation + if @_animation_duration > 0 + frame_index = @_animation.frame_max - @_animation_duration + cell_data = @_animation.frames[frame_index].cell_data + position = @_animation.position + animation_set_sprites(@_animation_sprites, cell_data, position) + for timing in @_animation.timings + if timing.frame == frame_index + animation_process_timing(timing, @_animation_hit) + end + end + else + dispose_animation + end + end + def update_loop_animation + frame_index = @_loop_animation_index + cell_data = @_loop_animation.frames[frame_index].cell_data + position = @_loop_animation.position + animation_set_sprites(@_loop_animation_sprites, cell_data, position) + for timing in @_loop_animation.timings + if timing.frame == frame_index + animation_process_timing(timing, true) + end + end + end + def animation_set_sprites(sprites, cell_data, position) + for i in 0..15 + sprite = sprites[i] + pattern = cell_data[i, 0] + if sprite == nil or pattern == nil or pattern == -1 + sprite.visible = false if sprite != nil + next + end + sprite.visible = true + sprite.src_rect.set(pattern % 5 * 192, pattern / 5 * 192, 192, 192) + if position == 3 + if self.viewport != nil + sprite.x = self.viewport.rect.width / 2 + sprite.y = self.viewport.rect.height - 160 + else + sprite.x = 320 + sprite.y = 240 + end + else + sprite.x = self.x - self.ox + self.src_rect.width / 2 + sprite.y = self.y - self.oy + self.src_rect.height / 2 + sprite.y -= self.src_rect.height / 4 if position == 0 + sprite.y += self.src_rect.height / 4 if position == 2 + end + sprite.x += cell_data[i, 1] + sprite.y += cell_data[i, 2] + sprite.z = 2000 + sprite.ox = 96 + sprite.oy = 96 + sprite.zoom_x = cell_data[i, 3] / 100.0 + sprite.zoom_y = cell_data[i, 3] / 100.0 + sprite.angle = cell_data[i, 4] + sprite.mirror = (cell_data[i, 5] == 1) + sprite.opacity = cell_data[i, 6] * self.opacity / 255.0 + sprite.blend_type = cell_data[i, 7] + end + end + def animation_process_timing(timing, hit) + if (timing.condition == 0) or + (timing.condition == 1 and hit == true) or + (timing.condition == 2 and hit == false) + if timing.se.name != "" + se = timing.se + Audio.se_play("Audio/SE/" + se.name, se.volume, se.pitch) + end + case timing.flash_scope + when 1 + self.flash(timing.flash_color, timing.flash_duration * 2) + when 2 + if self.viewport != nil + self.viewport.flash(timing.flash_color, timing.flash_duration * 2) + end + when 3 + self.flash(nil, timing.flash_duration * 2) + end + end + end + def x=(x) + sx = x - self.x + if sx != 0 + if @_animation_sprites != nil + for i in 0..15 + @_animation_sprites[i].x += sx + end + end + if @_loop_animation_sprites != nil + for i in 0..15 + @_loop_animation_sprites[i].x += sx + end + end + end + super + end + def y=(y) + sy = y - self.y + if sy != 0 + if @_animation_sprites != nil + for i in 0..15 + @_animation_sprites[i].y += sy + end + end + if @_loop_animation_sprites != nil + for i in 0..15 + @_loop_animation_sprites[i].y += sy + end + end + end + super + end + end + + class Weather + def initialize(viewport = nil) + @type = 0 + @max = 0 + @ox = 0 + @oy = 0 + color1 = Color.new(255, 255, 255, 255) + color2 = Color.new(255, 255, 255, 128) + @rain_bitmap = Bitmap.new(7, 56) + for i in 0..6 + @rain_bitmap.fill_rect(6-i, i*8, 1, 8, color1) + end + @storm_bitmap = Bitmap.new(34, 64) + for i in 0..31 + @storm_bitmap.fill_rect(33-i, i*2, 1, 2, color2) + @storm_bitmap.fill_rect(32-i, i*2, 1, 2, color1) + @storm_bitmap.fill_rect(31-i, i*2, 1, 2, color2) + end + @snow_bitmap = Bitmap.new(6, 6) + @snow_bitmap.fill_rect(0, 1, 6, 4, color2) + @snow_bitmap.fill_rect(1, 0, 4, 6, color2) + @snow_bitmap.fill_rect(1, 2, 4, 2, color1) + @snow_bitmap.fill_rect(2, 1, 2, 4, color1) + @sprites = [] + for i in 1..40 + sprite = Sprite.new(viewport) + sprite.z = 1000 + sprite.visible = false + sprite.opacity = 0 + @sprites.push(sprite) + end + end + def dispose + for sprite in @sprites + sprite.dispose + end + @rain_bitmap.dispose + @storm_bitmap.dispose + @snow_bitmap.dispose + end + def type=(type) + return if @type == type + @type = type + case @type + when 1 + bitmap = @rain_bitmap + when 2 + bitmap = @storm_bitmap + when 3 + bitmap = @snow_bitmap + else + bitmap = nil + end + for i in 1..40 + sprite = @sprites[i] + if sprite != nil + sprite.visible = (i <= @max) + sprite.bitmap = bitmap + end + end + end + def ox=(ox) + return if @ox == ox; + @ox = ox + for sprite in @sprites + sprite.ox = @ox + end + end + def oy=(oy) + return if @oy == oy; + @oy = oy + for sprite in @sprites + sprite.oy = @oy + end + end + def max=(max) + return if @max == max; + @max = [[max, 0].max, 40].min + for i in 1..40 + sprite = @sprites[i] + if sprite != nil + sprite.visible = (i <= @max) + end + end + end + def update + return if @type == 0 + for i in 1..@max + sprite = @sprites[i] + if sprite == nil + break + end + if @type == 1 + sprite.x -= 2 + sprite.y += 16 + sprite.opacity -= 8 + end + if @type == 2 + sprite.x -= 8 + sprite.y += 16 + sprite.opacity -= 12 + end + if @type == 3 + sprite.x -= 2 + sprite.y += 8 + sprite.opacity -= 8 + end + x = sprite.x - @ox + y = sprite.y - @oy + if sprite.opacity < 64 or x < -50 or x > 750 or y < -300 or y > 500 + sprite.x = rand(800) - 50 + @ox + sprite.y = rand(800) - 200 + @oy + sprite.opacity = 255 + end + end + end + attr_reader :type + attr_reader :max + attr_reader :ox + attr_reader :oy + end + + class Map + def initialize(width, height) + @tileset_id = 1 + @width = width + @height = height + @autoplay_bgm = false + @bgm = RPG::AudioFile.new + @autoplay_bgs = false + @bgs = RPG::AudioFile.new("", 80) + @encounter_list = [] + @encounter_step = 30 + @data = Table.new(width, height, 3) + @events = {} + end + attr_accessor :tileset_id + attr_accessor :width + attr_accessor :height + attr_accessor :autoplay_bgm + attr_accessor :bgm + attr_accessor :autoplay_bgs + attr_accessor :bgs + attr_accessor :encounter_list + attr_accessor :encounter_step + attr_accessor :data + attr_accessor :events + end + + class MapInfo + def initialize + @name = "" + @parent_id = 0 + @order = 0 + @expanded = false + @scroll_x = 0 + @scroll_y = 0 + end + attr_accessor :name + attr_accessor :parent_id + attr_accessor :order + attr_accessor :expanded + attr_accessor :scroll_x + attr_accessor :scroll_y + end + + class Event + class Page + class Condition + def initialize + @switch1_valid = false + @switch2_valid = false + @variable_valid = false + @self_switch_valid = false + @switch1_id = 1 + @switch2_id = 1 + @variable_id = 1 + @variable_value = 0 + @self_switch_ch = "A" + end + attr_accessor :switch1_valid + attr_accessor :switch2_valid + attr_accessor :variable_valid + attr_accessor :self_switch_valid + attr_accessor :switch1_id + attr_accessor :switch2_id + attr_accessor :variable_id + attr_accessor :variable_value + attr_accessor :self_switch_ch + end + + class Graphic + def initialize + @tile_id = 0 + @character_name = "" + @character_hue = 0 + @direction = 2 + @pattern = 0 + @opacity = 255 + @blend_type = 0 + end + attr_accessor :tile_id + attr_accessor :character_name + attr_accessor :character_hue + attr_accessor :direction + attr_accessor :pattern + attr_accessor :opacity + attr_accessor :blend_type + end + + def initialize + @condition = RPG::Event::Page::Condition.new + @graphic = RPG::Event::Page::Graphic.new + @move_type = 0 + @move_speed = 3 + @move_frequency = 3 + @move_route = RPG::MoveRoute.new + @walk_anime = true + @step_anime = false + @direction_fix = false + @through = false + @always_on_top = false + @trigger = 0 + @list = [RPG::EventCommand.new] + end + attr_accessor :condition + attr_accessor :graphic + attr_accessor :move_type + attr_accessor :move_speed + attr_accessor :move_frequency + attr_accessor :move_route + attr_accessor :walk_anime + attr_accessor :step_anime + attr_accessor :direction_fix + attr_accessor :through + attr_accessor :always_on_top + attr_accessor :trigger + attr_accessor :list + end + + def initialize(x, y) + @id = 0 + @name = "" + @x = x + @y = y + @pages = [RPG::Event::Page.new] + end + attr_accessor :id + attr_accessor :name + attr_accessor :x + attr_accessor :y + attr_accessor :pages + end + + class EventCommand + def initialize(code = 0, indent = 0, parameters = []) + @code = code + @indent = indent + @parameters = parameters + end + attr_accessor :code + attr_accessor :indent + attr_accessor :parameters + end + + class MoveRoute + def initialize + @repeat = true + @skippable = false + @list = [RPG::MoveCommand.new] + end + attr_accessor :repeat + attr_accessor :skippable + attr_accessor :list + end + + class MoveCommand + def initialize(code = 0, parameters = []) + @code = code + @parameters = parameters + end + attr_accessor :code + attr_accessor :parameters + end + + class Actor + def initialize + @id = 0 + @name = "" + @class_id = 1 + @initial_level = 1 + @final_level = 99 + @exp_basis = 30 + @exp_inflation = 30 + @character_name = "" + @character_hue = 0 + @battler_name = "" + @battler_hue = 0 + @parameters = Table.new(6,100) + for i in 1..99 + @parameters[0,i] = 500+i*50 + @parameters[1,i] = 500+i*50 + @parameters[2,i] = 50+i*5 + @parameters[3,i] = 50+i*5 + @parameters[4,i] = 50+i*5 + @parameters[5,i] = 50+i*5 + end + @weapon_id = 0 + @armor1_id = 0 + @armor2_id = 0 + @armor3_id = 0 + @armor4_id = 0 + @weapon_fix = false + @armor1_fix = false + @armor2_fix = false + @armor3_fix = false + @armor4_fix = false + end + attr_accessor :id + attr_accessor :name + attr_accessor :class_id + attr_accessor :initial_level + attr_accessor :final_level + attr_accessor :exp_basis + attr_accessor :exp_inflation + attr_accessor :character_name + attr_accessor :character_hue + attr_accessor :battler_name + attr_accessor :battler_hue + attr_accessor :parameters + attr_accessor :weapon_id + attr_accessor :armor1_id + attr_accessor :armor2_id + attr_accessor :armor3_id + attr_accessor :armor4_id + attr_accessor :weapon_fix + attr_accessor :armor1_fix + attr_accessor :armor2_fix + attr_accessor :armor3_fix + attr_accessor :armor4_fix + end + + class Class + class Learning + def initialize + @level = 1 + @skill_id = 1 + end + attr_accessor :level + attr_accessor :skill_id + end + + def initialize + @id = 0 + @name = "" + @position = 0 + @weapon_set = [] + @armor_set = [] + @element_ranks = Table.new(1) + @state_ranks = Table.new(1) + @learnings = [] + end + attr_accessor :id + attr_accessor :name + attr_accessor :position + attr_accessor :weapon_set + attr_accessor :armor_set + attr_accessor :element_ranks + attr_accessor :state_ranks + attr_accessor :learnings + end + + class Skill + def initialize + @id = 0 + @name = "" + @icon_name = "" + @description = "" + @scope = 0 + @occasion = 1 + @animation1_id = 0 + @animation2_id = 0 + @menu_se = RPG::AudioFile.new("", 80) + @common_event_id = 0 + @sp_cost = 0 + @power = 0 + @atk_f = 0 + @eva_f = 0 + @str_f = 0 + @dex_f = 0 + @agi_f = 0 + @int_f = 100 + @hit = 100 + @pdef_f = 0 + @mdef_f = 100 + @variance = 15 + @element_set = [] + @plus_state_set = [] + @minus_state_set = [] + end + attr_accessor :id + attr_accessor :name + attr_accessor :icon_name + attr_accessor :description + attr_accessor :scope + attr_accessor :occasion + attr_accessor :animation1_id + attr_accessor :animation2_id + attr_accessor :menu_se + attr_accessor :common_event_id + attr_accessor :sp_cost + attr_accessor :power + attr_accessor :atk_f + attr_accessor :eva_f + attr_accessor :str_f + attr_accessor :dex_f + attr_accessor :agi_f + attr_accessor :int_f + attr_accessor :hit + attr_accessor :pdef_f + attr_accessor :mdef_f + attr_accessor :variance + attr_accessor :element_set + attr_accessor :plus_state_set + attr_accessor :minus_state_set + end + + class Item + def initialize + @id = 0 + @name = "" + @icon_name = "" + @description = "" + @scope = 0 + @occasion = 0 + @animation1_id = 0 + @animation2_id = 0 + @menu_se = RPG::AudioFile.new("", 80) + @common_event_id = 0 + @price = 0 + @consumable = true + @parameter_type = 0 + @parameter_points = 0 + @recover_hp_rate = 0 + @recover_hp = 0 + @recover_sp_rate = 0 + @recover_sp = 0 + @hit = 100 + @pdef_f = 0 + @mdef_f = 0 + @variance = 0 + @element_set = [] + @plus_state_set = [] + @minus_state_set = [] + end + attr_accessor :id + attr_accessor :name + attr_accessor :icon_name + attr_accessor :description + attr_accessor :scope + attr_accessor :occasion + attr_accessor :animation1_id + attr_accessor :animation2_id + attr_accessor :menu_se + attr_accessor :common_event_id + attr_accessor :price + attr_accessor :consumable + attr_accessor :parameter_type + attr_accessor :parameter_points + attr_accessor :recover_hp_rate + attr_accessor :recover_hp + attr_accessor :recover_sp_rate + attr_accessor :recover_sp + attr_accessor :hit + attr_accessor :pdef_f + attr_accessor :mdef_f + attr_accessor :variance + attr_accessor :element_set + attr_accessor :plus_state_set + attr_accessor :minus_state_set + end + + class Weapon + def initialize + @id = 0 + @name = "" + @icon_name = "" + @description = "" + @animation1_id = 0 + @animation2_id = 0 + @price = 0 + @atk = 0 + @pdef = 0 + @mdef = 0 + @str_plus = 0 + @dex_plus = 0 + @agi_plus = 0 + @int_plus = 0 + @element_set = [] + @plus_state_set = [] + @minus_state_set = [] + end + attr_accessor :id + attr_accessor :name + attr_accessor :icon_name + attr_accessor :description + attr_accessor :animation1_id + attr_accessor :animation2_id + attr_accessor :price + attr_accessor :atk + attr_accessor :pdef + attr_accessor :mdef + attr_accessor :str_plus + attr_accessor :dex_plus + attr_accessor :agi_plus + attr_accessor :int_plus + attr_accessor :element_set + attr_accessor :plus_state_set + attr_accessor :minus_state_set + end + + class Armor + def initialize + @id = 0 + @name = "" + @icon_name = "" + @description = "" + @kind = 0 + @auto_state_id = 0 + @price = 0 + @pdef = 0 + @mdef = 0 + @eva = 0 + @str_plus = 0 + @dex_plus = 0 + @agi_plus = 0 + @int_plus = 0 + @guard_element_set = [] + @guard_state_set = [] + end + attr_accessor :id + attr_accessor :name + attr_accessor :icon_name + attr_accessor :description + attr_accessor :kind + attr_accessor :auto_state_id + attr_accessor :price + attr_accessor :pdef + attr_accessor :mdef + attr_accessor :eva + attr_accessor :str_plus + attr_accessor :dex_plus + attr_accessor :agi_plus + attr_accessor :int_plus + attr_accessor :guard_element_set + attr_accessor :guard_state_set + end + + class Enemy + class Action + def initialize + @kind = 0 + @basic = 0 + @skill_id = 1 + @condition_turn_a = 0 + @condition_turn_b = 1 + @condition_hp = 100 + @condition_level = 1 + @condition_switch_id = 0 + @rating = 5 + end + attr_accessor :kind + attr_accessor :basic + attr_accessor :skill_id + attr_accessor :condition_turn_a + attr_accessor :condition_turn_b + attr_accessor :condition_hp + attr_accessor :condition_level + attr_accessor :condition_switch_id + attr_accessor :rating + end + + def initialize + @id = 0 + @name = "" + @battler_name = "" + @battler_hue = 0 + @maxhp = 500 + @maxsp = 500 + @str = 50 + @dex = 50 + @agi = 50 + @int = 50 + @atk = 100 + @pdef = 100 + @mdef = 100 + @eva = 0 + @animation1_id = 0 + @animation2_id = 0 + @element_ranks = Table.new(1) + @state_ranks = Table.new(1) + @actions = [RPG::Enemy::Action.new] + @exp = 0 + @gold = 0 + @item_id = 0 + @weapon_id = 0 + @armor_id = 0 + @treasure_prob = 100 + end + attr_accessor :id + attr_accessor :name + attr_accessor :battler_name + attr_accessor :battler_hue + attr_accessor :maxhp + attr_accessor :maxsp + attr_accessor :str + attr_accessor :dex + attr_accessor :agi + attr_accessor :int + attr_accessor :atk + attr_accessor :pdef + attr_accessor :mdef + attr_accessor :eva + attr_accessor :animation1_id + attr_accessor :animation2_id + attr_accessor :element_ranks + attr_accessor :state_ranks + attr_accessor :actions + attr_accessor :exp + attr_accessor :gold + attr_accessor :item_id + attr_accessor :weapon_id + attr_accessor :armor_id + attr_accessor :treasure_prob + end + + class Troop + class Member + def initialize + @enemy_id = 1 + @x = 0 + @y = 0 + @hidden = false + @immortal = false + end + attr_accessor :enemy_id + attr_accessor :x + attr_accessor :y + attr_accessor :hidden + attr_accessor :immortal + end + + class Page + class Condition + def initialize + @turn_valid = false + @enemy_valid = false + @actor_valid = false + @switch_valid = false + @turn_a = 0 + @turn_b = 0 + @enemy_index = 0 + @enemy_hp = 50 + @actor_id = 1 + @actor_hp = 50 + @switch_id = 1 + end + attr_accessor :turn_valid + attr_accessor :enemy_valid + attr_accessor :actor_valid + attr_accessor :switch_valid + attr_accessor :turn_a + attr_accessor :turn_b + attr_accessor :enemy_index + attr_accessor :enemy_hp + attr_accessor :actor_id + attr_accessor :actor_hp + attr_accessor :switch_id + end + + def initialize + @condition = RPG::Troop::Page::Condition.new + @span = 0 + @list = [RPG::EventCommand.new] + end + attr_accessor :condition + attr_accessor :span + attr_accessor :list + end + + def initialize + @id = 0 + @name = "" + @members = [] + @pages = [RPG::BattleEventPage.new] + end + attr_accessor :id + attr_accessor :name + attr_accessor :members + attr_accessor :pages + end + + class State + def initialize + @id = 0 + @name = "" + @animation_id = 0 + @restriction = 0 + @nonresistance = false + @zero_hp = false + @cant_get_exp = false + @cant_evade = false + @slip_damage = false + @rating = 5 + @hit_rate = 100 + @maxhp_rate = 100 + @maxsp_rate = 100 + @str_rate = 100 + @dex_rate = 100 + @agi_rate = 100 + @int_rate = 100 + @atk_rate = 100 + @pdef_rate = 100 + @mdef_rate = 100 + @eva = 0 + @battle_only = true + @hold_turn = 0 + @auto_release_prob = 0 + @shock_release_prob = 0 + @guard_element_set = [] + @plus_state_set = [] + @minus_state_set = [] + end + attr_accessor :id + attr_accessor :name + attr_accessor :animation_id + attr_accessor :restriction + attr_accessor :nonresistance + attr_accessor :zero_hp + attr_accessor :cant_get_exp + attr_accessor :cant_evade + attr_accessor :slip_damage + attr_accessor :rating + attr_accessor :hit_rate + attr_accessor :maxhp_rate + attr_accessor :maxsp_rate + attr_accessor :str_rate + attr_accessor :dex_rate + attr_accessor :agi_rate + attr_accessor :int_rate + attr_accessor :atk_rate + attr_accessor :pdef_rate + attr_accessor :mdef_rate + attr_accessor :eva + attr_accessor :battle_only + attr_accessor :hold_turn + attr_accessor :auto_release_prob + attr_accessor :shock_release_prob + attr_accessor :guard_element_set + attr_accessor :plus_state_set + attr_accessor :minus_state_set + end + + class Animation + class Frame + def initialize + @cell_max = 0 + @cell_data = Table.new(0, 0) + end + attr_accessor :cell_max + attr_accessor :cell_data + end + + class Timing + def initialize + @frame = 0 + @se = RPG::AudioFile.new("", 80) + @flash_scope = 0 + @flash_color = Color.new(255,255,255,255) + @flash_duration = 5 + @condition = 0 + end + attr_accessor :frame + attr_accessor :se + attr_accessor :flash_scope + attr_accessor :flash_color + attr_accessor :flash_duration + attr_accessor :condition + end + + def initialize + @id = 0 + @name = "" + @animation_name = "" + @animation_hue = 0 + @position = 1 + @frame_max = 1 + @frames = [RPG::Animation::Frame.new] + @timings = [] + end + attr_accessor :id + attr_accessor :name + attr_accessor :animation_name + attr_accessor :animation_hue + attr_accessor :position + attr_accessor :frame_max + attr_accessor :frames + attr_accessor :timings + end + + class Tileset + def initialize + @id = 0 + @name = "" + @tileset_name = "" + @autotile_names = [""]*7 + @panorama_name = "" + @panorama_hue = 0 + @fog_name = "" + @fog_hue = 0 + @fog_opacity = 64 + @fog_blend_type = 0 + @fog_zoom = 200 + @fog_sx = 0 + @fog_sy = 0 + @battleback_name = "" + @passages = Table.new(384) + @priorities = Table.new(384) + @priorities[0] = 5 + @terrain_tags = Table.new(384) + end + attr_accessor :id + attr_accessor :name + attr_accessor :tileset_name + attr_accessor :autotile_names + attr_accessor :panorama_name + attr_accessor :panorama_hue + attr_accessor :fog_name + attr_accessor :fog_hue + attr_accessor :fog_opacity + attr_accessor :fog_blend_type + attr_accessor :fog_zoom + attr_accessor :fog_sx + attr_accessor :fog_sy + attr_accessor :battleback_name + attr_accessor :passages + attr_accessor :priorities + attr_accessor :terrain_tags + end + + class CommonEvent + def initialize + @id = 0 + @name = "" + @trigger = 0 + @switch_id = 1 + @list = [RPG::EventCommand.new] + end + attr_accessor :id + attr_accessor :name + attr_accessor :trigger + attr_accessor :switch_id + attr_accessor :list + end + + class System + class Words + def initialize + @gold = "" + @hp = "" + @sp = "" + @str = "" + @dex = "" + @agi = "" + @int = "" + @atk = "" + @pdef = "" + @mdef = "" + @weapon = "" + @armor1 = "" + @armor2 = "" + @armor3 = "" + @armor4 = "" + @attack = "" + @skill = "" + @guard = "" + @item = "" + @equip = "" + end + attr_accessor :gold + attr_accessor :hp + attr_accessor :sp + attr_accessor :str + attr_accessor :dex + attr_accessor :agi + attr_accessor :int + attr_accessor :atk + attr_accessor :pdef + attr_accessor :mdef + attr_accessor :weapon + attr_accessor :armor1 + attr_accessor :armor2 + attr_accessor :armor3 + attr_accessor :armor4 + attr_accessor :attack + attr_accessor :skill + attr_accessor :guard + attr_accessor :item + attr_accessor :equip + end + + class TestBattler + def initialize + @actor_id = 1 + @level = 1 + @weapon_id = 0 + @armor1_id = 0 + @armor2_id = 0 + @armor3_id = 0 + @armor4_id = 0 + end + attr_accessor :actor_id + attr_accessor :level + attr_accessor :weapon_id + attr_accessor :armor1_id + attr_accessor :armor2_id + attr_accessor :armor3_id + attr_accessor :armor4_id + end + + def initialize + @magic_number = 0 + @party_members = [1] + @elements = [nil, ""] + @switches = [nil, ""] + @variables = [nil, ""] + @windowskin_name = "" + @title_name = "" + @gameover_name = "" + @battle_transition = "" + @title_bgm = RPG::AudioFile.new + @battle_bgm = RPG::AudioFile.new + @battle_end_me = RPG::AudioFile.new + @gameover_me = RPG::AudioFile.new + @cursor_se = RPG::AudioFile.new("", 80) + @decision_se = RPG::AudioFile.new("", 80) + @cancel_se = RPG::AudioFile.new("", 80) + @buzzer_se = RPG::AudioFile.new("", 80) + @equip_se = RPG::AudioFile.new("", 80) + @shop_se = RPG::AudioFile.new("", 80) + @save_se = RPG::AudioFile.new("", 80) + @load_se = RPG::AudioFile.new("", 80) + @battle_start_se = RPG::AudioFile.new("", 80) + @escape_se = RPG::AudioFile.new("", 80) + @actor_collapse_se = RPG::AudioFile.new("", 80) + @enemy_collapse_se = RPG::AudioFile.new("", 80) + @words = RPG::System::Words.new + @test_battlers = [] + @test_troop_id = 1 + @start_map_id = 1 + @start_x = 0 + @start_y = 0 + @battleback_name = "" + @battler_name = "" + @battler_hue = 0 + @edit_map_id = 1 + end + attr_accessor :magic_number + attr_accessor :party_members + attr_accessor :elements + attr_accessor :switches + attr_accessor :variables + attr_accessor :windowskin_name + attr_accessor :title_name + attr_accessor :gameover_name + attr_accessor :battle_transition + attr_accessor :title_bgm + attr_accessor :battle_bgm + attr_accessor :battle_end_me + attr_accessor :gameover_me + attr_accessor :cursor_se + attr_accessor :decision_se + attr_accessor :cancel_se + attr_accessor :buzzer_se + attr_accessor :equip_se + attr_accessor :shop_se + attr_accessor :save_se + attr_accessor :load_se + attr_accessor :battle_start_se + attr_accessor :escape_se + attr_accessor :actor_collapse_se + attr_accessor :enemy_collapse_se + attr_accessor :words + attr_accessor :test_battlers + attr_accessor :test_troop_id + attr_accessor :start_map_id + attr_accessor :start_x + attr_accessor :start_y + attr_accessor :battleback_name + attr_accessor :battler_name + attr_accessor :battler_hue + attr_accessor :edit_map_id + end + + class AudioFile + def initialize(name = "", volume = 100, pitch = 100) + @name = name + @volume = volume + @pitch = pitch + end + attr_accessor :name + attr_accessor :volume + attr_accessor :pitch + end +end diff --git a/extra/vm.c.patch b/extra/vm.c.patch new file mode 100644 index 0000000..acc1f9f --- /dev/null +++ b/extra/vm.c.patch @@ -0,0 +1,19 @@ +--- src/vm.c 2020-10-18 23:00:12.865875587 +0530 ++++ src/vm.c 2020-10-18 23:06:10.887618558 +0530 +@@ -2262,13 +2262,15 @@ + switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) { + case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM): + #ifdef MRB_WITHOUT_FLOAT ++#else + { + mrb_int x = mrb_fixnum(regs[a]); + mrb_int y = mrb_fixnum(regs[a+1]); + SET_INT_VALUE(regs[a], y ? x / y : 0); + } ++ NEXT; + break; +-#else ++ + x = (mrb_float)mrb_fixnum(regs[a]); + y = (mrb_float)mrb_fixnum(regs[a+1]); + break;