Neo Mode 7 + - MGC - 11-23-2010
RMXP : Add-on for the Neo Mode 7 Engine : Neo Mode 7 +
Version: 1.0
Introduction
This add-on for the Neo Mode 7 script was designed to increase a little the performances. Results may vary depending on the machine.
Features- global performances slightly increased when rendering mode 7.
- mode 7 drawing only when moving -> lag is strongly reduced at stop.
- resolutions [R2]&[R3] applied only when moving -> not so ugly at stop (you can disable this feature by replacing "false" by "true" line 34.
Installation
Paste this script below the Neo Mode 7 script (compatible with the latest version on this board - 29/03/2010, or here), and copy the DLL at the root of your project.
Script :
Code: #============================================================================
# Add-on : Neo Mode 7 +
# V.1.0 - 15/09/10
# Author : MGC
#
# This script increases (a little) the performances of the Neo Mode 7 engine.
# It is compliant with the 29/03/10 version that can be found on rmvxp.com.
# It requires the file "MGCmode7+.dll".
#
# Paste this script below the last part of the Neo Mode 7 script.
#============================================================================
#============================================================================
# ** Game_System
#============================================================================
class Game_System
#--------------------------------------------------------------------------
# * Aliased methods (F12 compatibility)
#--------------------------------------------------------------------------
unless @already_aliased_neoM7Plus
alias initialize_neoM7Plus_game_system initialize
@already_aliased_neoM7Plus = true
end
#--------------------------------------------------------------------------
# * Public Instance Variables
# fple_always_same_res (boolean): true = same quality when moving or not
#--------------------------------------------------------------------------
attr_accessor :neoM7Plus_always_same_res
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
initialize_neoM7Plus_game_system
self.neoM7Plus_always_same_res = false
end
end
#============================================================================
# ** Sprite
#============================================================================
class Sprite
#--------------------------------------------------------------------------
# calculate x and y coordinates in mode 7 for a vertical sprite
#--------------------------------------------------------------------------
def neoM7(x_map, y_map)
x_map = 32 * x_map
y_map = 32 * y_map
y_init = $game_temp.zoom_sprites * (y_map - $game_temp.pivot - $game_map.display_y.to_i / 4)
x_init = $game_temp.zoom_sprites * (x_map - 320 - $game_map.display_x.to_i / 4)
y_intermediate = (y_init * $game_temp.cos_theta -
x_init * $game_temp.sin_theta).to_i >> 11
x_intermediate = (x_init * $game_temp.cos_theta +
y_init * $game_temp.sin_theta).to_i >> 11
self.y = $game_temp.pivot + ($game_temp.distance_h * y_intermediate *
$game_temp.cos_alpha) / (($game_temp.distance_h << 11) - y_intermediate *
$game_temp.sin_alpha)
self.x = 320 + ($game_temp.slope_value * y +
$game_temp.corrective_value) * x_intermediate
end
#--------------------------------------------------------------------------
# calculate x and y coordinates in mode 7 for a character sprite
#--------------------------------------------------------------------------
def neoM7_character(x_screen, y_screen)
y_init = $game_temp.zoom_sprites * (y_screen - $game_temp.pivot)
x_init = $game_temp.zoom_sprites * (x_screen - 320)
y_intermediate = (y_init * $game_temp.cos_theta -
x_init * $game_temp.sin_theta).to_i >> 11
x_intermediate = (x_init * $game_temp.cos_theta +
y_init * $game_temp.sin_theta).to_i >> 11
self.y = $game_temp.pivot + ($game_temp.distance_h * y_intermediate *
$game_temp.cos_alpha) / (($game_temp.distance_h << 11) - y_intermediate *
$game_temp.sin_alpha)
self.x = (320 + ($game_temp.slope_value * y +
$game_temp.corrective_value) * x_intermediate)
end
end
#============================================================================
# ** Bitmap
#============================================================================
class Bitmap
NeoMode7Plus = Win32API.new("MGCmode7+.dll", "NeoMode7Plus", "lllllll", "l")
CHLP = Win32API.new("MGCmode7+.dll", "CleanHeightLimitPlus", "lll", "l")
#--------------------------------------------------------------------------
# mode 7 transformation
#--------------------------------------------------------------------------
def neoM7(tileset, data, map_width, map_height, off_x, off_y, options)
raise RGSSError.new("Disposed bitmap") if disposed?
NeoMode7Plus.call(self.__id__, tileset.__id__, data.__id__, off_x, off_y,
[$game_temp.cos_alpha, $game_temp.sin_alpha, $game_temp.distance_h,
$game_temp.pivot_map.to_i, $game_temp.slope_value_map,
$game_temp.corrective_value_map, $game_temp.neoM7_height_limit,
$game_temp.cos_theta, $game_temp.sin_theta, $game_temp.distance_p.to_i,
$game_temp.zoom_map].__id__, options.__id__)
end
#--------------------------------------------------------------------------
def neoM7_screen(tileset, data, map_width, map_height, off_x, off_y, options)
raise RGSSError.new("Disposed bitmap") if disposed?
NeoMode7Plus.call(self.__id__, tileset.__id__, data.__id__, off_x, off_y,
[$game_temp.cos_alpha, $game_temp.sin_alpha, $game_temp.distance_h,
$game_temp.pivot.to_i, $game_temp.slope_value_map,
(131072 * $game_temp.corrective_value).to_i, $game_temp.height_limit_sprites.to_i,
$game_temp.cos_theta, $game_temp.sin_theta, 0,
$game_temp.zoom_map].__id__, options.__id__)
end
#--------------------------------------------------------------------------
# delete pixels beyond the horizon
#--------------------------------------------------------------------------
def clean_limit(old_limit, new_limit)
raise RGSSError.new("Disposed bitmap") if disposed?
CHLP.call(self.__id__, old_limit, new_limit)
end
end
#============================================================================
# ** Tilemap_neoM7
#============================================================================
class Tilemap_neoM7
#--------------------------------------------------------------------------
# * Alias : F12 compatibility
#--------------------------------------------------------------------------
unless @already_aliased_neoM7Plus
alias increase_zoom_neoM7Plus_tilemap increase_zoom
alias set_zoom_neoM7Plus_tilemap set_zoom
alias update_animated_neoM7Plus_tilemap update_animated
@already_aliased_neoM7Plus = true
end
#--------------------------------------------------------------------------
# * Attributes
#--------------------------------------------------------------------------
attr_accessor :sprite_screen # sprite used to contain the map's drawing when not moving
#--------------------------------------------------------------------------
# * Object Initialization
# viewport : viewport
#--------------------------------------------------------------------------
def initialize(viewport, spriteset)
@even = true
@viewport = viewport
@spriteset = spriteset
@id = $game_map.map_id # map's ID : used to load or save the map in Cache
self.tilesets_list = [] # contains tilesets (Bitmap)
@height = $game_map.height << 5 # @height : map's height (in pixel)
@width = $game_map.width << 5 # @width : map's width (in pixel)
@options = [0, 0, 0]
@options[0] = $game_system.neoM7_loop ? 1 : 0
@zoom = $game_system.neoM7_zoom # zoom level of the map
$game_temp.zoom_sprites = @zoom.to_f / 100
$game_temp.zoom_map = (4096 * (1.0 / $game_temp.zoom_sprites)).to_i
# tilesets graphics and data map are loaded if already in Cache
if RPG::Cache_Datamap.in_cache(@id)
@bitmap_data = RPG::Cache_Datamap.load(@id)
@map_tileset = RPG::Cache_Tileset.load(@id)
tilesets_list.push(@map_tileset)
if $game_system.neoM7_animated
@map_tileset_2 = RPG::Cache_Tileset.load(@id, 1)
@map_tileset_3 = RPG::Cache_Tileset.load(@id, 2)
@map_tileset_4 = RPG::Cache_Tileset.load(@id, 3)
tilesets_list.push(@map_tileset_2)
tilesets_list.push(@map_tileset_3)
tilesets_list.push(@map_tileset_4)
end
else # draw the data map and the tileset and save them in the Cache
draw_map
end
# create vertical elements from tiles
data_V = Data_Vertical_Sprites.new(viewport)
# @vertical_sprites : list of vertical sprites (Sprite_V)
@vertical_sprites = data_V.list_sprites_V
# @vertical_sprites_animated : list of animated vertical sprites (Sprite_V)
@vertical_sprites_animated = data_V.list_sprites_V_animated
# angle of rotation (theta)
self.theta = $game_system.neoM7_theta
theta_rad = (Math::PI * theta) / 180
# easier to work with integer value than floats ('>>' and '<<' operations)
$game_temp.cos_theta = (2048 * Math.cos(theta_rad)).to_i
$game_temp.sin_theta = (2048 * Math.sin(theta_rad)).to_i
# offsets : equivalent to display_x and display_y
@offset_x = 0
@offset_y = 0
$game_temp.distance_h = 480 # distance between the center of the map (halfwidth, pivot) and the point of view
# screenline's number of the slant's pivot = y-coordinate of the rotation center
$game_temp.pivot = $game_system.neoM7_pivot # character sprites
$game_temp.pivot_map = $game_temp.pivot /
($game_system.neoM7_resolution == 1 ? 1 :
($game_system.neoM7_resolution == 2 ? 1.33 : 2)) # map sprite
# distance between the center of the map (halfwidth, pivot) and the projection plane surface
$game_temp.distance_p = $game_temp.distance_h - $game_temp.distance_h /
($game_system.neoM7_resolution == 1 ? 1 :
($game_system.neoM7_resolution == 2 ? 1.334 : 2))
# zoom value of the map sprite
@coeff_resolution = ($game_system.neoM7_resolution == 1 ? 1 :
($game_system.neoM7_resolution == 2 ? 1.334 : 2))
# x-offset for the 3 resolutions
@offset_x_res = ($game_system.neoM7_resolution == 1 ? 0 :
($game_system.neoM7_resolution == 2 ? 80 : 160))
# y-offset for the 3 resolutions
@offset_y_res = $game_temp.pivot - $game_temp.pivot_map
@index_animated = 0 # 0..3 : index of animated tiles pattern
# map sprite
self.sprite = Sprite.new(@viewport)
sprite.x = 0
sprite.y = 0
sprite.z = - 99999 # map must not mask vertical elements
self.sprite_screen = Sprite.new(viewport)
sprite_screen.x = 0
sprite_screen.y = 0
sprite_screen.z = - 99999
if $game_system.neoM7_resolution != 1
sprite.bitmap = ($game_system.neoM7_resolution == 2 ?
Bitmap.new(480, 360) : Bitmap.new(320, 240))
else
sprite.bitmap = Bitmap.new(640, 480) # screen dimensions
end
sprite.zoom_x = @coeff_resolution
sprite.zoom_y = @coeff_resolution
if $game_system.neoM7Plus_always_same_res
sprite_screen.bitmap = sprite.bitmap
sprite_screen.zoom_x = @coeff_resolution
sprite_screen.zoom_y = @coeff_resolution
else
sprite_screen.bitmap = Bitmap.new(640, 480)
end
# angle of slant (alpha)
self.alpha = $game_system.neoM7_alpha
refresh_alpha
end
#--------------------------------------------------------------------------
# * Refresh all the parameters dependent on the angle of slant
#--------------------------------------------------------------------------
def refresh_alpha
# angle of slant
alpha_rad = (Math::PI * alpha) / 180
$game_temp.cos_alpha = (2048 * Math.cos(alpha_rad)).to_i
$game_temp.sin_alpha = (2048 * Math.sin(alpha_rad)).to_i
$game_system.neoM7_alpha = alpha
$game_system.neoM7_pivot = $game_temp.pivot
# h0, z0 : intermediate values used to calculate the slope
h0 = (- ($game_temp.distance_h) * $game_temp.pivot *
$game_temp.cos_alpha) / (($game_temp.distance_h << 11) +
$game_temp.pivot * $game_temp.sin_alpha) + $game_temp.pivot
z0 = ($game_temp.distance_h << 11).to_f /
(($game_temp.distance_h << 11) + $game_temp.pivot * $game_temp.sin_alpha)
# slope
$game_temp.slope_value = (1.0 - z0) / ($game_temp.pivot - h0)
$game_temp.slope_value_map = (131072 * $game_temp.slope_value).to_i
$game_temp.corrective_value = 1.0 - $game_temp.pivot * $game_temp.slope_value
$game_temp.corrective_value_map = (131072 * $game_temp.corrective_value / @coeff_resolution).to_i
last_line = - $game_temp.pivot_map - $game_system.neoM7_horizon
old_limit = $game_temp.neoM7_height_limit
$game_temp.neoM7_height_limit = (($game_temp.distance_h - $game_temp.distance_p) *
last_line * $game_temp.cos_alpha) / (($game_temp.distance_h << 11) -
last_line * $game_temp.sin_alpha) + $game_temp.pivot_map
if $game_system.neoM7_white_horizon
@options[1] = $game_temp.neoM7_height_limit > 0 ? 1 : 0
end
$game_temp.neoM7_height_limit = [$game_temp.neoM7_height_limit.to_i, 0].max
$game_temp.height_limit_sprites = $game_temp.neoM7_height_limit * @coeff_resolution
@even = ((old_limit - $game_temp.neoM7_height_limit) & 1 == 0 ? @even : !@even)
# delete lines beyond the new horizon
sprite.bitmap.clean_limit(old_limit,
$game_temp.neoM7_height_limit) if old_limit < $game_temp.neoM7_height_limit
@need_update = true
end
#--------------------------------------------------------------------------
# * Increase (or decrease) the angle of rotation
#--------------------------------------------------------------------------
def increase_theta(value)
self.theta += value
self.theta %= 360
theta_rad = (Math::PI * theta) / 180
$game_temp.cos_theta = (2048 * Math.cos(theta_rad)).to_i
$game_temp.sin_theta = (2048 * Math.sin(theta_rad)).to_i
$game_system.neoM7_theta = theta
@need_update = true
end
#--------------------------------------------------------------------------
# * Set the angle of rotation
#--------------------------------------------------------------------------
def set_theta(value)
self.theta = value % 360
theta_rad = (Math::PI * theta) / 180
$game_temp.cos_theta = (2048 * Math.cos(theta_rad)).to_i
$game_temp.sin_theta = (2048 * Math.sin(theta_rad)).to_i
$game_system.neoM7_theta = theta
@need_update = true
end
#--------------------------------------------------------------------------
# * Increase (or decrease) the zoom level
#--------------------------------------------------------------------------
def increase_zoom(value)
increase_zoom_neoM7Plus_tilemap(value)
@need_update = true
end
#--------------------------------------------------------------------------
# * Set the zoom level
#--------------------------------------------------------------------------
def set_zoom(value)
set_zoom_neoM7Plus_tilemap(value)
@need_update = true
end
#--------------------------------------------------------------------------
# * Update the map sprite and the vertical sprites
#--------------------------------------------------------------------------
def update
@offset_x = $game_map.display_x / 4 + @offset_x_res
@offset_y = $game_map.display_y / 4 + @offset_y_res
if !@need_update && (@offset_x != @offset_x_old || @offset_y != @offset_y_old)
@offset_x_old = @offset_x
@offset_y_old = @offset_y
@need_update = true
end
if @need_update
@need_update_anim = false
sprite_screen.visible = false
sprite.visible = true
# update map sprite
if $game_system.neoM7_filter
@even = !@even
@need_update = @even
@options[2] = @even ? 1 : 2
else
@need_update = false
end
sprite.bitmap.neoM7(@map_tileset, @bitmap_data, @width, @height, @offset_x, @offset_y, @options)
# update vertical sprites
for vertical_sprite in @vertical_sprites
vertical_sprite.update
end
@need_update_screen = true
elsif @need_update_screen || @need_update_anim
sprite_screen.visible = true
sprite.visible = false
@options[2] = 0
sprite_screen.bitmap.clear
if $game_system.neoM7Plus_always_same_res
sprite_screen.bitmap.neoM7(@map_tileset, @bitmap_data, @width, @height, @offset_x, @offset_y, @options)
else
sprite_screen.bitmap.neoM7_screen(@map_tileset, @bitmap_data, @width, @height,
$game_map.display_x / 4, $game_map.display_y / 4, @options)
end
@need_update_screen = false
@need_update_anim = false
end
end
#--------------------------------------------------------------------------
# * Update animation for animated tiles
#--------------------------------------------------------------------------
def update_animated
update_animated_neoM7Plus_tilemap
@need_update_anim = true
end
end
DLL : MGCmode7+.dll
RE: [RMXP] Neo Mode 7 + - deValdr - 11-23-2010
This pure magic. Thanks :)
RE: [RMXP] Neo Mode 7 + - MGC - 11-23-2010
(11-23-2010, 07:53 PM)Valdred Wrote: This pure magic. Thanks :)
It was already posted, but on the temporary forum...
That was the only script of my contribution that was missing here, I think.
RE: Neo Mode 7 + - natinusala - 02-03-2015
Hello,
I don't know if you know about mkxp (https://github.com/Ancurio/mkxp), it's an open-source C implementation of the RGSS engine. It's supposed to replace the Game.exe and RGSSXXXX.dll files. It's more powerful and faster than the original RGSS Player, and it's cross-platform (with it you can play RMXP games on Mac and Linux).
The thing is that mkxp doesn't have Win32API for obvious reasons, and so this script cannot work using it. It would be great if you could make a version of Neo Mode 7 working with it, could you give it a try ?
Thanks !
RE: Neo Mode 7 + - DerVVulfman - 02-04-2015
His last posting was 2010 for this system and has not been around for roughly a year. Meanwhile, without support for use of outside DLLs, MKXP will not be able to use his custom graphic dll.
RE: Neo Mode 7 + - natinusala - 02-04-2015
(02-04-2015, 04:13 AM)DerVVulfman Wrote: His last posting was 2010 for this system and has not been around for roughly a year. Meanwhile, without support for use of outside DLLs, MKXP will not be able to use his custom graphic dll. I can't send him a PM nor an email, so I tried to post it there ^^
If the functions that are currently in the DLL and needed by the scripts are built in mkxp (so in the engine) we should be able to call them without referencing the DLL, and it would be cross-platform aswell... that's why I asked MCG if he could rewrite his DLL directly into the source of mkxp (or a fork).
RE: Neo Mode 7 + - JayRay - 02-04-2015
or if he could create a Non-DLL version of his script, would be nicer, not just for mkxp, but maybe for Regal and other nonRM editors.
But to be honest, all I want is a pure PC 3d version of RMXP, no heightmaps, actual models, or at the least , come on! let's get an RPG maker 4 up here... Surely we can run Plasystation 2 Graphics!
RE: Neo Mode 7 + - natinusala - 02-05-2015
We surely could, but it would take time to do and would cost more than $20 :D
RE: Neo Mode 7 + - MetalRenard - 02-05-2015
It's called Unity.
RE: Neo Mode 7 + - natinusala - 02-06-2015
Unity is, on my opinion, very bad and hard to master... but yeah, basically it's that :p
|