mirror of
https://github.com/mkxp-z/mkxp-z.git
synced 2025-06-06 01:05:54 +02:00
Add Essentials 16384px tileset limit workaround
This commit is contained in:
parent
89da4f3b8c
commit
e96ffb13a2
4 changed files with 157 additions and 0 deletions
|
@ -61,6 +61,8 @@ extern const char module_rpg1[];
|
|||
extern const char module_rpg2[];
|
||||
extern const char module_rpg3[];
|
||||
|
||||
#include "EssentialsTilemapHack.rb.xxd"
|
||||
|
||||
static void mriBindingExecute();
|
||||
static void mriBindingTerminate();
|
||||
static void mriBindingReset();
|
||||
|
@ -473,6 +475,14 @@ struct BacktraceData {
|
|||
BoostHash<std::string, std::string> scriptNames;
|
||||
};
|
||||
|
||||
bool evalScript(VALUE string, const char *filename)
|
||||
{
|
||||
int state;
|
||||
evalString(string, rb_str_new_cstr(filename), &state);
|
||||
if (state) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifndef MARIN
|
||||
#define SCRIPT_SECTION_FMT (rgssVer >= 3 ? "{%04ld}" : "Section%03ld")
|
||||
|
||||
|
@ -570,6 +580,9 @@ static void runRMXPScripts(BacktraceData &btData) {
|
|||
return;
|
||||
#endif
|
||||
|
||||
// Used to try and fix Essentials garbage later if it's detected
|
||||
int minimonsters = 0;
|
||||
|
||||
while (true) {
|
||||
#if RAPI_FULL < 200 && defined(NO_CONSOLE)
|
||||
VALUE iostr = rb_str_new2(NULL_IO);
|
||||
|
@ -596,6 +609,20 @@ static void runRMXPScripts(BacktraceData &btData) {
|
|||
fname = newStringUTF8(buf, len);
|
||||
btData.scriptNames.insert(buf, scriptName);
|
||||
|
||||
// There is 0 reason for anything other than Essentials to have this class
|
||||
if (rb_const_defined(rb_cObject, rb_intern("PokemonMapMetadata")) && minimonsters == 0)
|
||||
minimonsters = 1;
|
||||
|
||||
// Before checking to see if the next script should be skipped,
|
||||
// make sure to check whether it's the last one or not and run
|
||||
// any extra stuff before the end (primarily stupid Essentials stuff)
|
||||
// Will be placed within a build option later
|
||||
#define SCRIPT(name) rb_str_new((const char*)&___scripts_##name##_rb, ___scripts_##name##_rb_len), #name " (Internal)"
|
||||
if (minimonsters > 0 && i + 2 == scriptCount && !RTEST(rb_gv_get("Z_NOPOKEFIX"))){
|
||||
evalScript(SCRIPT(EssentialsTilemapHack));
|
||||
minimonsters = -1;
|
||||
}
|
||||
|
||||
// if the script name starts with |s|, only execute
|
||||
// it if "s" is the same first letter as the platform
|
||||
// we're running on
|
||||
|
|
|
@ -140,6 +140,7 @@ subdir('src')
|
|||
subdir('binding')
|
||||
subdir('shader')
|
||||
subdir('assets')
|
||||
subdir('scripts')
|
||||
|
||||
global_include_dirs += include_directories('src', 'binding')
|
||||
|
||||
|
|
109
scripts/EssentialsTilemapHack.rb
Normal file
109
scripts/EssentialsTilemapHack.rb
Normal file
|
@ -0,0 +1,109 @@
|
|||
# ======================================================================
|
||||
# TILEMAP VERTICAL WRAPPER
|
||||
#
|
||||
# This is a little fix for Pokemon Essentials' custom tilemap code
|
||||
# that works around MKXP's GPU texture size limit that would normally
|
||||
# stop you from playing a lot of games.
|
||||
#
|
||||
# The concept is simple enough: If your tileset is too big, a new
|
||||
# bitmap will be constructed with all the excess pixels sent to the
|
||||
# image's right side. This basically means that you now have a limit
|
||||
# far higher than you should ever actually need.
|
||||
#
|
||||
# Because of the extra math the game will have to do to find the right
|
||||
# pixels, this will probably cause a performance hit while on these
|
||||
# maps which would normally be megasurfaces.
|
||||
#
|
||||
# It can probably be improved by changing CustomTilemap.getRegularTile
|
||||
# to just find the correct pixels on its own, without having to
|
||||
# translate the coordinates afterwards, but this will satisfy me just
|
||||
# for the moment.
|
||||
#
|
||||
# Really, it'd be far better to cut up the image on the C++ end and
|
||||
# use a custom shader to get the image right or something like that,
|
||||
# but that's work for another day.
|
||||
#
|
||||
# For now, I'm just happy I can finally test whatever game I like.
|
||||
#
|
||||
$GL_TEX_CAP = 16384 # << This should be automatically set at some point.
|
||||
#
|
||||
# ~Zoro
|
||||
#=======================================================================
|
||||
|
||||
module VWrap
|
||||
|
||||
def self.clamp(val, min, max)
|
||||
val = max if val > max
|
||||
val = min if val < min
|
||||
return val
|
||||
end
|
||||
|
||||
def self.makeVWrappedTileset(originalbmp)
|
||||
width = originalbmp.width
|
||||
height = originalbmp.height
|
||||
if width == 256 && height > $GL_TEX_CAP
|
||||
columns = (height / $GL_TEX_CAP.to_f).ceil
|
||||
|
||||
return nil if columns * 256 > $GL_TEX_CAP
|
||||
bmp = Bitmap.new(256*columns, $GL_TEX_CAP)
|
||||
remainder = height % $GL_TEX_CAP
|
||||
|
||||
columns.times{|col|
|
||||
srcrect = Rect.new(0, col * $GL_TEX_CAP, width, (col + 1 == columns) ? remainder : $GL_TEX_CAP)
|
||||
bmp.blt(col*256, 0, originalbmp, srcrect)
|
||||
}
|
||||
return bmp
|
||||
end
|
||||
|
||||
return originalbmp
|
||||
end
|
||||
|
||||
def self.blitVWrappedPixels(destX, destY, dest, src, srcrect)
|
||||
merge = (srcrect.y % $GL_TEX_CAP) > ((srcrect.y + srcrect.height) % $GL_TEX_CAP)
|
||||
|
||||
srcrect.x = clamp(srcrect.x, 0,256)
|
||||
srcrect.width = clamp(srcrect.width, 0, 256 - srcrect.x)
|
||||
col = (srcrect.y / $GL_TEX_CAP.to_f).floor
|
||||
srcX = col * 256 + srcrect.x
|
||||
srcY = srcrect.y % $GL_TEX_CAP
|
||||
|
||||
if !merge
|
||||
dest.blt(destX, destY, src, Rect.new(srcX, srcY, srcrect.width, srcrect.height))
|
||||
else
|
||||
#FIXME won't work on heights longer than two columns, but nobody should need
|
||||
# more than 32k pixels high at once anyway
|
||||
side = {:a => $GL_TEX_CAP - srcY, :b => srcrect.height - ($GL_TEX_CAP - srcY)}
|
||||
dest.blt(destX, destY, src, Rect.new(srcX, srcY, srcrect.width, side[:a]))
|
||||
dest.blt(destX, destY + side[:a], src, Rect.new(srcX + 256, 0, srcrect.width, side[:b]))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# -------------------------
|
||||
if $MKXP == true
|
||||
class CustomTilemap
|
||||
def tileset=(value)
|
||||
if value.height > $GL_TEX_CAP || value.width > $GL_TEX_CAP
|
||||
@tileset = VWrap::makeVWrappedTileset(value)
|
||||
else
|
||||
@tileset = value
|
||||
end
|
||||
@tilesetchanged = true
|
||||
end
|
||||
|
||||
alias old_getRegularTile getRegularTile
|
||||
def getRegularTile(sprite, id)
|
||||
return old_getRegularTile(sprite, id) if @tileset.width <= 256
|
||||
|
||||
bitmap = @regularTileInfo[id]
|
||||
if !bitmap
|
||||
bitmap = Bitmap.new(@tileWidth, @tileHeight)
|
||||
rect=Rect.new(((id - 384)&7)*@tileSrcWidth,((id - 384)>>3)*@tileSrcHeight,
|
||||
@tileSrcWidth,@tileSrcHeight)
|
||||
VWrap::blitVWrappedPixels(0,0, bitmap, @tileset, rect)
|
||||
@regularTileInfo[id]=bitmap
|
||||
end
|
||||
sprite.bitmap = bitmap if sprite.bitmap != bitmap
|
||||
end
|
||||
end
|
||||
end
|
20
scripts/meson.build
Normal file
20
scripts/meson.build
Normal file
|
@ -0,0 +1,20 @@
|
|||
|
||||
embedded_scripts = [
|
||||
'EssentialsTilemapHack.rb'
|
||||
]
|
||||
|
||||
embedded_scripts_f = files(embedded_scripts)
|
||||
|
||||
count = 0
|
||||
foreach file : embedded_scripts_f
|
||||
global_sources += custom_target(embedded_scripts[count],
|
||||
input: file,
|
||||
output: '@0@.xxd'.format(embedded_scripts[count]),
|
||||
command: [
|
||||
xxd, '-i', '@INPUT@'
|
||||
],
|
||||
capture: true,
|
||||
depend_files: embedded_scripts_f[count]
|
||||
)
|
||||
count += 1
|
||||
endforeach
|
Loading…
Add table
Reference in a new issue