Troubles with Animations...

Started by ForeverZer0, July 07, 2012, 11:04:44 pm

Previous topic - Next topic

ForeverZer0

Well, I have gotten down to the last two panels: Animations and System. The System panel is a cinch, so I figured I would work on the Animations panel to get the more difficult of the two out of the way. As I mentioned before, Animations.arc fails to load, I presume from the Table class size issue that Blizzard discovered. Now, as far as I am can see/understand, my Table class does handle 0 sized tables appropriately, so I am at a bit of a loss as to what the issue is, because it still does not load.

I was wondering if either of you two could take a look at it and see if you see something that I don't with the logic. I can't seem to find what the problem is. I get an error that the byte identifier is unrecognized, so I assume that the _load method is reading too little or too many bytes and the stream position is getting screwed up.

It would make creating/debugging the Animations panel SOOOO much easier if I real data to be working with instead of trying to build a few complete animations at runtime just to test with.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Blizzard

I took at look at everything and I think that your C# implementation of ARC::Data does not the C++ implementation. I noticed that during loading you're not mapping objects/arrays/hashes/strings at all. During dumping you are actually dumping the hash code of the object which won't work well because of 1) hash codes can overlap and you get the same hash code for two different objects, 2) the hash code works as an ID, but the dumper is not aware that the object was dumped because the hash code is stored nowhere and 3) ARC's format requires that the IDs start at 1 and increment by one for each new string/array/hash/object. Though I think I might have not been so clear about the last thing in the specification so I am going to update it.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


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.

ForeverZer0

I haven't done much testing at all with dumping, so I am sure you that you're right and some things need fixed with that. I actually forgot to change the hash code thing. I wrote that while I was still trying to understand how it all worked, and ended up moving on to loading and from their using real data in the editor, etc. etc.

Quote from: Blizzard on July 08, 2012, 04:21:00 am
I took at look at everything and I think that your C# implementation of ARC::Data does not the C++ implementation. I noticed that during loading you're not mapping objects/arrays/hashes/strings at all.

I don't understand what you mean here at all. All strings/arrays/hashes/objects get mapped into their respective lists. It is why there are the _strings, _arrays, _hashes, and _objects lists and the MapObject and FindMapping methods. I think all of that is pretty much what it should be. With the exception of Animations, everything loads perfectly fine, which it would not if the objects weren't mapped.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Blizzard

July 08, 2012, 09:35:23 am #3 Last Edit: July 08, 2012, 09:40:34 am by Blizzard
I don't see any calls for stuff being mapped. The C# implementations differs logically from the other 3 implementations.

		int id = __LOAD_INT32;
VALUE obj = __FIND_MAPPED(arrays, id);
if (!NIL_P(obj))
{
return obj;
}
obj = rb_ary_new();
__MAP(arrays, obj);
int size = __LOAD_INT32;
for_iter (i, 0, size)
{
rb_ary_push(obj, ARC_Data::_load());
}
return obj;


		int id = _loadInt32();
dynamic obj = FindMapping(ref _arrays, id);
if (obj != null)
return obj;
int size = _loadInt32();
List<dynamic> array = new List<dynamic>(size);
for (int i = 0; i < size; i++)
array.Add(_load());
return array;


Pseudocode: ShowHide
		id = load_int32();
obj = find_mapped(arrays at id);
if obj exists:
return obj;
obj = create new array;
map(obj into arrays);
size = load_int32();
for each i in size
obj.add(load another ARC object);
return obj;


The C# implementation is missing this step in the implementation:

map(obj into arrays);


And _loadArray is not the only method that is missing that step.
The rest is loading properly because there are no cross-references of objects in most of the data files. I can guarantee you that your code is faulty.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


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.

ForeverZer0

Damn it, your right. When I checked last night after you said that, I looked at the load method for string, which is the one object that I actually did it right on. The rest omitted the mapping step... :facepalm:

Spoiler: ShowHide
		/// <summary>
/// Reads a string from the stream
/// </summary>
/// <returns>String value</returns>
private static string _loadString()
{
int id = _loadInt32();
string obj = (string)FindMapping(ref _strings, id);
if (obj != null)
return String.Copy(obj);
int size = _loadInt32();
obj = _stream.ReadByteString(size);
MapObject(ref _strings, obj);
return obj;
}
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Blizzard

Yeah, the string method was the only one where you actually did it. xD
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


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.

ForeverZer0

Okay, question time.

Here's the code for loading of a Table:
	VALUE Table::rb_load(VALUE self, VALUE value)
{
// load Table size data
VALUE sliced_string = rb_str_substr(value, 0, 20);
VALUE data = rb_f_str_unpack(sliced_string, "LLLLL");
int dimensions = NUM2INT(rb_ary_shift(data));
VALUE rb_xSize = rb_ary_shift(data);
VALUE rb_ySize = rb_ary_shift(data);
VALUE rb_zSize = rb_ary_shift(data);
int size = NUM2INT(rb_xSize) * NUM2INT(rb_ySize) * NUM2INT(rb_zSize);
// create the table
VALUE argv[3] = {rb_xSize, rb_ySize, rb_zSize};
VALUE rb_table = Table::create(dimensions, argv);
RB_VAR2CPP(rb_table, Table, table);
// loading data entries
sliced_string = rb_str_substr(value, 20, size * 2);
data = rb_f_str_unpack(sliced_string, hstr('S', size).c_str());
for_iter (i, 0, size)
{
table->data[i] = (short)NUM2INT(rb_ary_shift(data));
}
return rb_table;
}


	public static Table _arc_load(byte[] bytes)
{
int nx, ny, nz, dimensions, size;
dimensions = BitConverter.ToInt32(bytes, 0);
nx = BitConverter.ToInt32(bytes, 4);
ny = BitConverter.ToInt32(bytes, 8);
nz = BitConverter.ToInt32(bytes, 12);
size = nx * ny * nz;
Table table = new Table(nx, ny, nz);
int[] data = new int[size];
for (int i = 0; i < size; i++)
data[i] = BitConverter.ToInt16(bytes, 16 + (i * 2));
table._data = data;
table._dimensions = dimensions;
return table;
}


The C# implementation takes 16 bytes before reading data from the table.

  • 1st 4: Dimension

  • 2nd 4: X Size

  • 3rd 4: Y Size

  • 4th 4: Z Size



It then begins reading data using an offset of 16 bytes, to account for what is already been read.


I may just be misunderstanding the code a bit, but it appears the C++ (and Python) implementation reads 20 bytes.

  • 1st 4: Dimension

  • 2nd 4: X Size

  • 3rd 4: Y Size

  • 4th 4: Z Size

  • 5th 4: ??????



It then begins with an offset of 20 bytes when reading the data. My question is: Am I misinterpreting the "rb_ary_shift(data)" and "rb_str_substr(value, 20, size * 2)" and what they do, or are there 4 unused bytes in there. What I don't understand is, if it is the latter, how do Tables load correctly at all? I realize it would really only mess up the first two loaded values in the table, but as far as I can see, they appear to be completely accurate to the original.

All the other possible faults with my serialization implementation aside, I am just not seeing why these damned Animations will not load. None of the _dump errors or mapping errors (which have been fixed) seem to have anything to do with the particular problem, unless I am mistaken.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Blizzard

RMXP's Table uses 20 bytes because it also saves the size of the table (which is basically x * y * z so it's redundant). ARC's format does not include the size information so it has only 16 bytes. There is a method called rb_arcLoad just further below. I once mistook them as well and started fixing it. Then I scrolled further down and had to massively facepalm myself. I think that the RMXP implementation is still there because of save data.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


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.

ForeverZer0

Lol, that explains it. Add another :facepalm: to my list.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Blizzard

You could post here so everybody gets a laugh out of it. :V:
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


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.

ForeverZer0

I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

ForeverZer0

HELL YES! I FINALLY discovered the source of the errors!

Pathetically enough, it has nothing to do with the Table class. I forget to add _arc_load and _arc_dump methods to the Color and Tone class. You know what this means:

Spoiler: ShowHide
:facepalm: :facepalm: :facepalm: :facepalm: :facepalm: :facepalm: :facepalm:
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Blizzard

Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


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.