[XP] Import certain classes from RGSS1 dll only

Started by Terv, January 17, 2013, 06:48:54 pm

Previous topic - Next topic

Terv

January 17, 2013, 06:48:54 pm Last Edit: January 17, 2013, 07:31:44 pm by Terv
Hey,
I currently run my XP game using the Ace engine (Game.exe + RGSS301.dll) and a Ruby rewrite of Tilemap. Now I know that you can load certain functions from dlls only, so would it be possible to load the C++ tilemap class from the RGSS102E.dll manually after start so I don't have to put up with that squishy rewrite?
The problem is that there are micro stutters when wandering on a relatively complex map. I am currently using Poccil's rewrite; if you know any that work better, tell me please  :haha:

Blizzard

Have you tried F0's rewrite? It might work better for you.
Check out our game brands:

Daygames
Game Night Games
Chugnar Games

Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

Terv

I am using Seph's Rewrite now (SDK (^o^)丿 ), so far there are no problems. Before that I tried to use Zer0's class because I like Zer0 but somehow it didn't work due to dependencies on the custom resolution script.. I guess some small edits are necessary to make it standalone, which I couldn't figure out.
Furthermore there are still Me(tm)'s and RTH's rewrites so I think some of these will suit my needs for sure in case Seph's won't.

G_G

Just use Zer0's full Custom Resolution script and just don't change the resolution. And it wouldn't be hard to make those edits to make it so it wouldn't require any dependencies. Honestly, out of all the rewrites I've seen, Zer0's has probably been one of the best in my opinion.

Blizzard

WHAT ABOUT MY C++ IMPLEMENTATION?! I DON'T LOVE YOU ANYMORE!
Check out our game brands:

Daygames
Game Night Games
Chugnar Games

Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

Terv

January 18, 2013, 10:30:31 am #5 Last Edit: January 18, 2013, 10:39:28 am by Terv
Quote from: Blizzard on January 18, 2013, 09:33:45 am
WHAT ABOUT MY C++ IMPLEMENTATION?! I DON'T LOVE YOU ANYMORE!
Quote from: Blizzard on January 18, 2013, 09:33:45 am
C++
The fuck, link please? How could I miss that?  :facepalm:
Thanks for the tip gameus, I'll switch to Zero's as soon as SDK starts creating errors (which will be in about 1-2 weeks, telling from my experience  :roll:)

Blizzard

Well, that implementation is for ARC so it's not really publicly available. :P But here is the class' code anyway (not that you can do too much with it). What I said there was meant more of a joke.

Spoiler: ShowHide
#include <ruby.h>

#include <april/RenderSystem.h>
#include <gtypes/Matrix4.h>
#include <gtypes/Rectangle.h>
#include <hltypes/harray.h>
#include <hltypes/hltypesUtil.h>
#include <hltypes/hstring.h>

#include "Bitmap.h"
#include "CodeSnippets.h"
#include "Graphics.h"
#include "RGSSError.h"
#include "SystemSprite.h"
#include "Table.h"
#include "Tilemap.h"
#include "Viewport.h"

#define TILE_SIZE 32

namespace rgss
{
VALUE rb_cTilemap;

static int _autotiles[6][8][4] = {
{{27, 28, 33, 34}, { 5, 28, 33, 34}, {27,  6, 33, 34}, { 5,  6, 33, 34},
{27, 28, 33, 12}, { 5, 28, 33, 12}, {27,  6, 33, 12}, { 5,  6, 33, 12}},
{{27, 28, 11, 34}, { 5, 28, 11, 34}, {27,  6, 11, 34}, { 5,  6, 11, 34},
{27, 28, 11, 12}, { 5, 28, 11, 12}, {27,  6, 11, 12}, { 5,  6, 11, 12}},
{{25, 26, 31, 32}, {25,  6, 31, 32}, {25, 26, 31, 12}, {25,  6, 31, 12},
{15, 16, 21, 22}, {15, 16, 21, 12}, {15, 16, 11, 22}, {15, 16, 11, 12}},
{{29, 30, 35, 36}, {29, 30, 11, 36}, { 5, 30, 35, 36}, { 5, 30, 11, 36},
{39, 40, 45, 46}, { 5, 40, 45, 46}, {39,  6, 45, 46}, { 5,  6, 45, 46}},
{{25, 30, 31, 36}, {15, 16, 45, 46}, {13, 14, 19, 20}, {13, 14, 19, 12},
{17, 18, 23, 24}, {17, 18, 11, 24}, {41, 42, 47, 48}, { 5, 42, 47, 48}},
{{37, 38, 43, 44}, {37,  6, 43, 44}, {13, 18, 19, 24}, {13, 14, 43, 44},
{37, 42, 43, 48}, {17, 18, 47, 48}, {13, 18, 43, 48}, { 1,  2,  7,  8}}
};

/****************************************************************************************
* Construction/Destruction
****************************************************************************************/

Tilemap::Tilemap() : SourceRenderer()
{
this->typeName = "tilemap";
this->rb_autotiles = rb_ary_new3(MAX_AUTOTILES, Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, Qnil);
this->rb_currentAutotiles = rb_ary_new3(MAX_AUTOTILES, Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, Qnil);
for_iter (i, 0, MAX_AUTOTILES)
{
this->generatedAutotiles[i] = NULL;
}
this->width = (Graphics::getWidth() + TILE_SIZE - 1) / TILE_SIZE + 1;
this->height = (Graphics::getHeight() + TILE_SIZE - 1) / TILE_SIZE + 1;
this->depth = 0;
this->autotileUpdateCount = 0;
this->rb_mapData = Qnil;
this->mapData = NULL;
this->rb_priorities = Qnil;
this->priorities = NULL;
}

Tilemap::~Tilemap()
{
this->dispose();
foreach (SystemSprite*, it, this->tileSprites)
{
delete (*it);
}
this->tileSprites.clear();
}

void Tilemap::initialize(VALUE rb_viewport)
{
SourceRenderer::initialize(rb_viewport);
this->rb_autotiles = rb_ary_new3(MAX_AUTOTILES, Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, Qnil);
this->rb_currentAutotiles = rb_ary_new3(MAX_AUTOTILES, Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, Qnil);
for_iter (i, 0, MAX_AUTOTILES)
{
this->generatedAutotiles[i] = NULL;
}
this->width = (Graphics::getWidth() + TILE_SIZE - 1) / TILE_SIZE + 1;
this->height = (Graphics::getHeight() + TILE_SIZE - 1) / TILE_SIZE + 1;
this->depth = 0;
this->autotileUpdateCount = 0;
this->rb_mapData = Qnil;
this->mapData = NULL;
this->rb_priorities = Qnil;
this->priorities = NULL;
}

void Tilemap::dispose()
{
if (!this->disposed)
{
this->rb_autotiles = Qnil;
this->rb_currentAutotiles = Qnil;
this->rb_mapData = Qnil;
this->mapData = NULL;
this->rb_priorities = Qnil;
this->priorities = NULL;
for_iter (i, 0, MAX_AUTOTILES)
{
if (this->generatedAutotiles[i] != NULL)
{
delete this->generatedAutotiles[i];
this->generatedAutotiles[i] = NULL;
}
}
foreach (SystemSprite*, it, this->tileSprites)
{
(*it)->dispose();
}
}
SourceRenderer::dispose();
}

void Tilemap::mark()
{
SourceRenderer::mark();
RB_GC_MARK(autotiles);
RB_GC_MARK(currentAutotiles);
RB_GC_MARK(mapData);
RB_GC_MARK(priorities);
}

/****************************************************************************************
* Pure C++ code
****************************************************************************************/

void Tilemap::update()
{
if (this->mapData == NULL || this->depth != this->mapData->getZSize())
{
foreach (SystemSprite*, it, this->tileSprites)
{
delete (*it);
}
this->tileSprites.clear();
}
if (this->mapData == NULL || this->disposed)
{
return;
}
if (!this->visible)
{
foreach (SystemSprite*, it, this->tileSprites)
{
(*it)->setVisible(false);
}
return;
}
this->depth = this->mapData->getZSize();
if (this->tileSprites.size() == 0)
{
SystemSprite* tileSprite;
int i;
int j;
int k;
for_iterx (k, 0, this->depth)
{
for_iterx (j, 0, this->height)
{
for_iterx (i, 0, this->width)
{
tileSprite = new SystemSprite(this->viewport);
tileSprite->getSrcRect()->set(0, 0, TILE_SIZE, TILE_SIZE);
this->tileSprites += tileSprite;
}
}
}
}
this->_updateAutotiles();
this->_updateTileSprites();
}

void Tilemap::_updateAutotiles()
{
VALUE rb_autotile;
Bitmap* generated;
static VALUE argv1[2] = {INT2FIX(256), INT2FIX(192)};
static VALUE argv2[2] = {INT2FIX(256), INT2FIX(768)};
int position;
int sx;
int sy;
int tx;
int ty;
bool animated;
int x;
int y;
int j;
for_iter (i, 0, MAX_AUTOTILES)
{
rb_autotile = rb_ary_entry(this->rb_autotiles, i);
if (rb_autotile != rb_ary_entry(this->rb_currentAutotiles, i))
{
rb_ary_store(this->rb_currentAutotiles, i, rb_autotile);
if (NIL_P(rb_autotile))
{
if (this->generatedAutotiles[i] != NULL)
{
delete this->generatedAutotiles[i];
this->generatedAutotiles[i] = NULL;
}
continue;
}
generated = this->generatedAutotiles[i];
animated = (NUM2INT(Bitmap::rb_getWidth(rb_autotile)) > 96);
if (generated == NULL)
{
generated = new Bitmap(256, (!animated ? 192 : 768));
this->generatedAutotiles[i] = generated;
}
else
{
generated->clear();
}
RB_VAR2CPP(rb_autotile, Bitmap, autotile);
for_iterx (y, 0, 6)
{
for_iterx (x, 0, 8)
{
for_iterx (j, 0, 4)
{
position = _autotiles[y][x][j] - 1;
tx = x * 32 + j % 2 * 16;
ty = y * 32 + j / 2 * 16;
sx = position % 6 * 16;
sy = position / 6 * 16;
generated->bltOver(tx, ty, autotile, sx, sy, 16, 16);
if (animated)
{
generated->bltOver(tx, ty + 192, autotile, sx + 96, sy, 16, 16);
generated->bltOver(tx, ty + 384, autotile, sx + 192, sy, 16, 16);
generated->bltOver(tx, ty + 576, autotile, sx + 288, sy, 16, 16);
}
}
}
}
}
}
}

void Tilemap::_updateTileSprites()
{
SystemSprite* tileSprite;
int i;
int j;
int k;
int priority;
int tileId;
Bitmap* autotile;
Rect* rect;
for_iterx (k, 0, this->depth)
{
for_iterx (j, 0, this->height)
{
for_iterx (i, 0, this->width)
{
tileSprite = this->tileSprites[i + this->width * (j + this->height * k)];
tileId = this->mapData->getCircularData(
-this->ox / TILE_SIZE + i, -this->oy / TILE_SIZE + j, k);
tileSprite->setX(this->ox % TILE_SIZE + i * TILE_SIZE);
tileSprite->setY(this->oy % TILE_SIZE + j * TILE_SIZE);
if (tileId < 48)
{
tileSprite->setVisible(false);
}
else
{
tileSprite->setVisible(true);
rect = tileSprite->getSrcRect();
if (tileId >= 384)
{
tileSprite->setBitmap(this->bitmap);
rect->x = ((tileId - 384) % 8) * TILE_SIZE;
rect->y = ((tileId - 384) / 8) * TILE_SIZE;
}
else
{
autotile = this->generatedAutotiles[(tileId / 48) - 1];
tileSprite->setBitmap(autotile);
rect->x = (tileId % 8) * TILE_SIZE;
rect->y = ((tileId % 48) / 8) * TILE_SIZE;
if (autotile->getHeight() > 192)
{
rect->y += this->autotileUpdateCount / 16 * 192;
}
}
}
priority = this->priorities->getData(tileId);
if (priority > 0)
{
tileSprite->setZ(tileSprite->getY() + (priority + 1) * TILE_SIZE - 1);
}
else
{
tileSprite->setZ(0);
}
}
}
}
}

/****************************************************************************************
* Ruby Interfacing, Creation, Destruction, Systematics
****************************************************************************************/

void Tilemap::init()
{
}

void Tilemap::destroy()
{
}

void Tilemap::createRubyInterface()
{
rb_cTilemap = rb_define_class("Tilemap", rb_cObject);
rb_define_alloc_func(rb_cTilemap, &Tilemap::rb_new);
// initialize
rb_define_method(rb_cTilemap, "initialize", RUBY_METHOD_FUNC(&Tilemap::rb_initialize), -1);
rb_define_method(rb_cTilemap, "initialize_clone", RUBY_METHOD_FUNC(&Tilemap::rb_initialize_clone), 1);
rb_define_method(rb_cTilemap, "initialize_dup", RUBY_METHOD_FUNC(&Tilemap::rb_initialize_dup), 1);
rb_define_method(rb_cTilemap, "dispose", RUBY_METHOD_FUNC(&Tilemap::rb_dispose), 0);
rb_define_method(rb_cTilemap, "_arc_dump", RUBY_METHOD_FUNC(&Tilemap::rb_arcDump), 0);
// getters and setters (Renderable) (except "z" and "z=")
rb_define_method(rb_cTilemap, "visible", RUBY_METHOD_FUNC(&Tilemap::rb_getVisible), 0);
rb_define_method(rb_cTilemap, "visible=", RUBY_METHOD_FUNC(&Tilemap::rb_setVisible), 1);
rb_define_method(rb_cTilemap, "ox", RUBY_METHOD_FUNC(&Tilemap::rb_getOX), 0);
rb_define_method(rb_cTilemap, "ox=", RUBY_METHOD_FUNC(&Tilemap::rb_setOX), 1);
rb_define_method(rb_cTilemap, "oy", RUBY_METHOD_FUNC(&Tilemap::rb_getOY), 0);
rb_define_method(rb_cTilemap, "oy=", RUBY_METHOD_FUNC(&Tilemap::rb_setOY), 1);
rb_define_method(rb_cTilemap, "disposed?", RUBY_METHOD_FUNC(&Tilemap::rb_isDisposed), 0);
// getters and setters (SourceRenderer) (except "opacity" and "opacity=")
rb_define_method(rb_cTilemap, "viewport", RUBY_METHOD_FUNC(&Tilemap::rb_getViewport), 0);
rb_define_method(rb_cTilemap, "tileset", RUBY_METHOD_FUNC(&Tilemap::rb_getBitmap), 0);
rb_define_method(rb_cTilemap, "tileset=", RUBY_METHOD_FUNC(&Tilemap::rb_setBitmap), 1);
// getters and setters
rb_define_method(rb_cTilemap, "autotiles", RUBY_METHOD_FUNC(&Tilemap::rb_getAutotiles), 0);
rb_define_method(rb_cTilemap, "map_data", RUBY_METHOD_FUNC(&Tilemap::rb_getMapData), 0);
rb_define_method(rb_cTilemap, "map_data=", RUBY_METHOD_FUNC(&Tilemap::rb_setMapData), 1);
rb_define_method(rb_cTilemap, "priorities", RUBY_METHOD_FUNC(&Tilemap::rb_getPriorities), 0);
rb_define_method(rb_cTilemap, "priorities=", RUBY_METHOD_FUNC(&Tilemap::rb_setPriorities), 1);
// methods
rb_define_method(rb_cTilemap, "update", RUBY_METHOD_FUNC(&Tilemap::rb_update), 0);
}

VALUE Tilemap::rb_new(VALUE classe)
{
Tilemap* tilemap;
return RB_OBJECT_NEW(classe, Tilemap, tilemap, &Tilemap::gc_mark, &Tilemap::gc_free);
}

VALUE Tilemap::rb_initialize(int argc, VALUE* argv, VALUE self)
{
RB_SELF2CPP(Tilemap, tilemap);
VALUE viewport;
rb_scan_args(argc, argv, "01", &viewport);
tilemap->initialize(viewport);
return self;
}

VALUE Tilemap::rb_initialize_clone(VALUE self, VALUE original)
{
RB_SELF2CPP(Tilemap, tilemap);
RB_CANT_CLONE_ERROR(tilemap);
return self;
}

VALUE Tilemap::rb_initialize_dup(VALUE self, VALUE original)
{
RB_SELF2CPP(Tilemap, tilemap);
RB_CANT_DUP_ERROR(tilemap);
return self;
}

/****************************************************************************************
* Ruby Getters/Setters
****************************************************************************************/

VALUE Tilemap::rb_getAutotiles(VALUE self)
{
RB_SELF2CPP(Tilemap, tilemap);
RB_CHECK_DISPOSED(tilemap);
return tilemap->rb_autotiles;
}

VALUE Tilemap::rb_getMapData(VALUE self)
{
RB_SELF2CPP(Tilemap, tilemap);
RB_CHECK_DISPOSED(tilemap);
return tilemap->rb_mapData;
}

VALUE Tilemap::rb_setMapData(VALUE self, VALUE value)
{
{
RB_SELF2CPP(Tilemap, tilemap);
RB_CHECK_DISPOSED(tilemap);
}
RB_GENERATE_SETTER(Tilemap, tilemap, Table, mapData);
return value;
}

VALUE Tilemap::rb_getPriorities(VALUE self)
{
RB_SELF2CPP(Tilemap, tilemap);
RB_CHECK_DISPOSED(tilemap);
return tilemap->rb_priorities;
}

VALUE Tilemap::rb_setPriorities(VALUE self, VALUE value)
{
{
RB_SELF2CPP(Tilemap, tilemap);
RB_CHECK_DISPOSED(tilemap);
}
RB_GENERATE_SETTER(Tilemap, tilemap, Table, priorities);
return value;
}

/****************************************************************************************
* Methods
****************************************************************************************/

VALUE Tilemap::rb_update(VALUE self)
{
RB_SELF2CPP(Tilemap, tilemap);
RB_CHECK_DISPOSED(tilemap);
tilemap->autotileUpdateCount = (tilemap->autotileUpdateCount + 1) % 64;
return Qnil;
}

}
Check out our game brands:

Daygames
Game Night Games
Chugnar Games

Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

Terv

January 18, 2013, 12:51:48 pm #7 Last Edit: January 18, 2013, 01:07:49 pm by Terv
Thank you. But there's a syntax error in line 23 when I paste it above main.  :(
	VALUE rb_cTilemap;

You need to fix that.

EDIT: nevermind.

Terv

July 17, 2013, 10:10:55 am #8 Last Edit: July 17, 2013, 06:09:22 pm by Terv
Does the ability to modify Game.exe's source code change anything about the feasibility of overwriting RGSS3's tilemap class with the one from RGSS1's dll?

Or could you use Detours to achieve this? (as you can also add Ruby packages at runtime with it)
QuoteDetours intercepts Win32 functions by re-writing the in-memory code for target functions. The Detours package also contains utilities to attach arbitrary DLLs and data segments (called payloads) to any Win32 binary.

Blizzard

Well, the RGSS.dll has a lot of Ruby C code which makes it quite hard to read since it is obfuscated and interfaced because of that.
Check out our game brands:

Daygames
Game Night Games
Chugnar Games

Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.