#AGAIN - Help tweaking a python script for outputting sprites.

251 messages · Page 1 of 1 (latest)

dreamy cobalt
#

Origin of python script: https://reverseengineering.stackexchange.com/questions/22456/deciphering-an-unknown-graphics-format
I have managed to get the sprites from the game AGAIN: Interactive Crime Novel. They are split into 3 BIN files, two of which contain pixel (''dewey'' files) and palette data (''huey''). The script works with several files, however, it will not work with others, outputting an error:

    rows_dat[tile_y*tile_h + small_y][3*(tile_x*tile_w + small_x)] = real_pal[pixel_bytes[i]][0]
                                                                              ~~~~~~~~~~~^^^
IndexError: index out of range```

I was told to try the following: 
> Check how big the ‘huey’ file is. Then, change the function that calls make_pal() so that it reads the correct number of palette colors.
Can someone guide me how to do so? I sent a sample of one "problem" image, I can send more if needed.
#

Line 14 needs to be changed every single time I want it to output a different file

#

Line 23 is the problem, it seems

#

If I just change the value to 0. 512, I get more errors for line 8 and 24

#

am not knowledgeable in Python, myself

outer tinsel
#

I have been summoned

outer tinsel
#

I had a look at the rom and it looks like there are values such as image width, height in the graph.dti file. Do you have the script/format info for that file? If so I can whip up a new python script with my existing DS graphics code

dreamy cobalt
#

Give me a sec and I'll send it to you

dreamy cobalt
#

I got it from one of the folks in that stackexchange thread

outer tinsel
#

epic

dreamy cobalt
outer tinsel
dreamy cobalt
outer tinsel
#

A little confusing... I'm going to have another look now

dreamy cobalt
#

Good luck! and thanks again

outer tinsel
#

Note to self:
??, ??, WW, HH, Size of gfx, Offset of palette, Offset of gfx, Offset of tilemap1, Offset of tilemap2

It looks like there is animation data too... this could be a pain in the butt.

#

Going to bed now....

dreamy cobalt
#

ninies (nighty night)

outer tinsel
#

I've never played the game, do you know if it has animated sprites?

dreamy cobalt
#

It has. The backgrounds are static but...

#

the characters are animated

outer tinsel
#

Ok cool, are you more interested in the backgrounds or characters? Because the characters might be hard to get...

dreamy cobalt
#

personally... characters... but I don't wanna push u

#

here's a bit of visual example

outer tinsel
#

I'll see what I can do... good night

dreamy cobalt
#

Sleep well!

outer tinsel
#

this is a lot more crazy than I expected...

dreamy cobalt
#

Yoooooooooooo

outer tinsel
#

There is still a lot of crazy stuff I don't understand yet

dreamy cobalt
#

I assume we are past using those Python scripts?

outer tinsel
#

Yep, I made another one

dreamy cobalt
#

I see

#

I can talk to the Stackexchange guy (Lioncheese/SoItBegins) if you want to, as well

outer tinsel
#

I should be able to get this done myself but thanks for the offer

dreamy cobalt
#

No problem, and thanks again for your work

outer tinsel
#

All the outputted graphics are rotated 90 degrees like you saw above, is that ok?

dreamy cobalt
#

Say, is it possible to ask u something about another format after you're done? You can refuse if you wanna

outer tinsel
#

Yeah of course

dreamy cobalt
#

Thanks. Ill tell you after you're done, don't wanna pile up stuff on you

outer tinsel
#

Is it from this game or another game?

dreamy cobalt
#

A different DS game, by the same devs. Someone wrote instructions on reverse engineering its format, but they have hidden any means of contact. Tried using ChatGPT, to make a Py script, it was faulty...

outer tinsel
#

just survived a power cut!

#

sorry about that

dreamy cobalt
#

Don't worry, am glad you're fine

#

We are readying for any chance earthquakes where I am. Crazy month

outer tinsel
#

Are you interested in the Past View stuff? Because it's stored in a different file

dreamy cobalt
#

If you can, then sure! For me it-s not mandatory since characters are my priority, but the StackExchange guy would most likely want everything that can be taken because he wants to remake the game in an easier format.

#

He already got the game script figured out anyways

outer tinsel
#

ok

#

because there are some 3D model things in that file which I don't particularly want to deal with

dreamy cobalt
#

if you also want the py for the game script for ur tools, then do ask

#

I see

#

no biggie, is fine

#

I can get the 3D models with MelonRipper anyways (3D models are only 10 rooms with puzzles ez to deal with that way)

outer tinsel
#

In an unexpected turn of events, I managed to get all the 2d character sprites, while nearly everything else is gummed up for now...

#

They were stored as separate backgrounds, which makes for a whole lot of images

dreamy cobalt
#

Wow, that's actually great! You're awesome!

outer tinsel
#

Here's the script in its current state, it will take a while to run

dreamy cobalt
#

Aaaaa must fire up laptop now

outer tinsel
#

By the way... it will inevitably crash when it reaches the end of the file 😂

dreamy cobalt
#

lol

outer tinsel
#

Yeah, it will output that if it finds a data type that I haven't figured out yet

dreamy cobalt
#

a

outer tinsel
#

(which is most of the non-character stuff)

#

The data is just random in some places, like, there isn't even something to tell you where the background entries begin and end... I think the actual code contains offsets to the graph.dti file

#

not to worry though, it can still be done without the code file

dreamy cobalt
#

Awesome work!

#

I feel so silly that am iliterate in exchange, at this

outer tinsel
#

Most of my experience is from the Mario & Luigi games, those were even more of a challenge

dreamy cobalt
#

Those games were my childhood

outer tinsel
#

For Bowser's inside story, you had to read 2 data tables from the code files... AND there was a custom compression

dreamy cobalt
#

ooofff

#

Doing God's work

dreamy cobalt
#

ML3, BiS?

outer tinsel
#

yeah

dreamy cobalt
#

Based

#

I tried putting a custom song on BiS

#

game crashed at the battle

#

beautiful checks

#

It stopped at 542

outer tinsel
#

Did it have another number next to 542

dreamy cobalt
#

26044

outer tinsel
#

ok... so it wasn't far from the huge bank of backgrounds...

dreamy cobalt
#

@w@

#

So far, it extracted a huge number of sprites, which I consider that a big win!
They look also very accurate, at first glance

#

I may had the wrong impression about what it would extract at first, but wow

#

I pressed Enter

#

it keeps going

#

<w>

outer tinsel
#

👀

#

So there was no error?

dreamy cobalt
#

And now it froze again, does not respond to anything

#

just keeps looking like this while blinking

#

OOhhh! I see the characters now!

#

I guess it was thinking hard

#

ok so this is weird to explain but...

#

It's outputting sprites with numbers beyond 7000

#

*700

#

but doesn't show in CMD

#

clearly

outer tinsel
#

It won't output a message while it's reading backgrounds, I did it for sprites because they tend to be buggy

dreamy cobalt
#

Ah

outer tinsel
#

(character sprites = backgrounds)

dreamy cobalt
#

this is so rad, man, I feel euphoric...

outer tinsel
#

It should be over halfway done now

outer tinsel
#

so if you're uploading to TSR, only focus on the images called "Background-(whatever)"

dreamy cobalt
#

Got it. Can I credit u too?

outer tinsel
#

of course

#

same as discord name

dreamy cobalt
#

Seems that the script keeps outputting the same last 54 sprites 4 times then stops

#

with some error codes

outer tinsel
#

Can I see the error message?

dreamy cobalt
#
  File "C:\Users\Me\AppData\Local\Programs\Python\Python311\Lib\site-packages\PIL\ImageFile.py", line 518, in _save
    fh = fp.fileno()
         ^^^^^^^^^
AttributeError: '_idat' object has no attribute 'fileno'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\Me\Desktop\FINAL HOTEL DUSK DEPOSIT\AGAIN\output\Graph_Reader.py", line 248, in <module>
    img.save("Sprite{}.png".format(i))
  File "C:\Users\Me\AppData\Local\Programs\Python\Python311\Lib\site-packages\PIL\Image.py", line 2431, in save
    save_handler(self, fp, filename)
  File "C:\Users\Me\AppData\Local\Programs\Python\Python311\Lib\site-packages\PIL\PngImagePlugin.py", line 1420, in _save
    ImageFile._save(im, _idat(fp, chunk), [("zip", (0, 0) + im.size, 0, rawmode)])
  File "C:\Users\Me\AppData\Local\Programs\Python\Python311\Lib\site-packages\PIL\ImageFile.py", line 522, in _save
    _encode_tile(im, fp, tile, bufsize, None, exc)
  File "C:\Users\Me\AppData\Local\Programs\Python\Python311\Lib\site-packages\PIL\ImageFile.py", line 533, in _encode_tile
    encoder.setimage(im.im, b)
SystemError: tile cannot extend outside image```
outer tinsel
#

Ok, I'll fix that eventually

#

Did it get all the stuff you wanted?

dreamy cobalt
#

For sure! Can I show the script to the StackExchange guy?

outer tinsel
#

Yeah np

dreamy cobalt
#

Nice

#

Again (no pun intended), thank you

#

Lemme know when I can ask about the other game

outer tinsel
dreamy cobalt
#

It's not the game, but, it's made by the same devs for sure, which is also in my sights, albeit a bit lower in my list.
I do not have any reverse engineering info on this one... I only have for the two games am struggling on, Hotel Dusk and Last Window (part of one series)

#

You could ask that user what they know till now, or if you wanna help them

outer tinsel
#

Alright... I might have time tomorrow, but could end up being busy

dreamy cobalt
#

No worries, we all are

dreamy cobalt
#

Hey, am sorry to bother, but when you are available, before you get to my other game, I recommend you check that user's topic first. I start to feel bad for them, it's getting unhealthy.

outer tinsel
#

Will have a look.

#

But I should warn you I have no experience of 3d models...

dreamy cobalt
#

It's ok, they wrote about sprites

dreamy cobalt
#

Heyo, I posted the link with the question here.
To be specific, I want the BRA format (characters sprites) figured out first. However if you feel you can make other formats more easy to be ripped too if you know them, then that's good, cause it would spare the manual side of those too. But I want the BRA format personally cause it would spare me 4-6 months of my life arranging sprites by tile pieces manually. ANM from Hotel Dusk is the same thing in a way (character sprites), and MTC is like the colors over the character sprites, which has been left untouched out of all formats sadly. #1078048794085691412 message

outer tinsel
#

Sorry for not getting back, I'll look at it when I can

dreamy cobalt
#

Thanks a lot 💙

dreamy cobalt
#

Finally got em here!

dreamy cobalt
#

As for the BRA format, developments had been made and it can be extracted. there is just one thing I have yet to figure out... and I can't wrap my head on how to do it. That is, to correctly round up the RGB values

outer tinsel
#

Sorry for being dead....

#

@dreamy cobalt Is this for Hotel Dusk or its sequel?

dreamy cobalt
#

Also ur timing is good lol

#

I linked the C# tool, wanna see it?

outer tinsel
#

Ok sure

dreamy cobalt
#

Sec, idk if to link the specific thread or just tool

#

The tool is at the bottom of the thread

#

I can get u the compiled tool

outer tinsel
#

I haven't tried the tool yet, but does anything need fixing?

dreamy cobalt
#

Yes. Specifically the RGB values of the animation frames outputted

#

They are apparently at 5bit 248 instead of 255

outer tinsel
#

I see... so when the RGB value is all 1's, the pixel is supposed to be value 248? I think all my DS extractors did that too (the values came out as 255)...

#

Unless I'm mistaken

dreamy cobalt
#

Ppl with more knowledge than me worded it better in this transcript

#

A proposed solution was
(value / 248) * 255

#

For every "component"

outer tinsel
#

Ok

#

Putting my bad code here for reference
def decodepixel555(pixeldata, offset, array, invisible):
cur=pixeldata.tell()
pixeldata.seek(offset)
value=int.from_bytes(pixeldata.read(2), "little")
##if value==65535:
## #print("Value warning! (Outside the palette file)")
## for i in range(3):
## array.append(0)
## a=255
## if invisible==1:
## a=0
## array.append(a)
#Fix! (22/2/23)
#When little endian, the leftmost bit is discarded
b=(value>>10)&0b11111
b=(b<<3)|(b>>2)
g=value>>5 & 0b11111
g=(g<<3)|(g>>2)
r=value & 0b11111
r=(r<<3)|(r>>2)
a=255
if invisible==1:
a=0
array.append(r)
array.append(g)
array.append(b)
array.append(a)
pixeldata.seek(cur)

#

I used the same method as Citra but looks like it's incorrect

dreamy cobalt
#

The one that seems concerned to RGB seems to be LWBRF? sadly I don't think it will help much. Just solved an issue it had in rounding Alpha values cause it just used multiples of 36 (thanks to RTB)

outer tinsel
#

will be back

dreamy cobalt
#

Gl out there

outer tinsel
#

Ohh I see what's going on

#

My code (above) is actually the right method

dreamy cobalt
#

Oh?

outer tinsel
#

My knowledge of CS is very limited, is there a way for you to contact the tool developer?

dreamy cobalt
#

Only Github and youtube. I tried for 5+ yearss to get in touch so is a miracle

#

That last week I succeeded

#

I did a PR

outer tinsel
#

Ok this is the problem code
public static Color Palette2Color(ushort palette) {
ushort hex = Tools.SwapBytes(palette);
int R = (hex & 0x1F) * 8;
int G = (hex >> 5 & 0x1F) * 8;
int B = (hex >> 10 & 0x1F) * 8;

        //int A = (hex >> 15 & 0x01) * 255;
        //return Color.FromArgb(255-A, R, G, B);

        return Color.FromArgb(R, G, B);
    }
dreamy cobalt
#

Maybe by commenting on the PR?

#

What should the intended code look like?

outer tinsel
#

This probably won't be the right syntax but let's see
int R = (hex & 0x1F);
int R = (R<<3)|(R>>2);
int G = (hex >> 5 & 0x1F);
int G = (G<<3)|(G>>2);
int B = (hex >> 10 & 0x1F);
int B = (B<<3)|(B>>2);

#

whoops

#

Hopefully OP will see what I was trying to do

#

in file FRM.cs

#

Good luck...

dreamy cobalt
#

Wait...

#

Is the FRM file used in determining the colors of BRA?

outer tinsel
#

Yeah

dreamy cobalt
#

oohhh... didn't know that

outer tinsel
#

I mean at least in OP's code, not sure about the game data

dreamy cobalt
#

I see now, u were right

outer tinsel
#

If you know how to compile the program, maybe test my code

dreamy cobalt
#

Oh yeah ur right imma give it a shot too

outer tinsel
#

int R0 = (hex & 0x1F);
int R = (R0<<3)|(R0>>2);
int G0 = (hex >> 5 & 0x1F);
int G = (G0<<3)|(G0>>2);
int B0 = (hex >> 10 & 0x1F);
int B = (B0<<3)|(B0>>2);

#

try that?

#

As I said my CS skills are non-existent, you may need to talk to OP

dreamy cobalt
#

In a minute, this time it runs

#

Yooo

#

I ran it throught ImageMagick compare

#

only the red pixels are where it has an issue

#

but the RGB values are pretty much fixed

#

If it didn't work it would had looked like this

#

You're a genius, I hope u know that

outer tinsel
#

Are you bothered about the outline, or is it just a ripping artifact

dreamy cobalt
#

On that aspect, I would have to look further on the values of each picture

#

Putting here Automated vs Manual for later

#

Am tired, so I'll take some rest. You have my entire gratitude for this one. Sent the message to OP. If he doesn't see it, I'll try a PR, worked last time

#

Really, I can't even put it to words how glad I am

#

Yall are heroes

dreamy cobalt
#

Ik what went wrong on those pixels

#

Using RTB's alpha code along with your tweak... Is a perfect match.

#

We achieved heaven

dreamy cobalt
#

the C# program now has a color value comparison cause some sprites still have odd relations

#

specifically the colored ones in notepad menu

dreamy cobalt
# outer tinsel https://tenor.com/view/dancing-bird-fast-colorful-gif-16975392

Heyo, I am currently making a journal style post where I retrace the steps taken to get to this point with the sprites that you fixed in March, and for the sake of being a bit noob friendly and so, I wanted to ask you two questions:
-Would u like ur username to be put in the journal, or a confidential initial, like R., or something?

dreamy cobalt
#

Again, thansk a million for your contribution.

outer tinsel
#

Speaking of Cing games... I've nearly finished Another Code R, really good story!

dreamy cobalt
#

Thanks! I am glad to hear you enjoyed that game too. If you ever wanna join the Cing community, or know more of the games, lemme know. The good thing about Another Code R, is that the models can be easily ripped thanks to the SSBB scene. Not so sure about the game's script, however, but shouldn't be impossible. Sprites should in theory work too, painlessly.

dreamy cobalt
#

My second question is, by chance, you know what the difference is between an "if" statement and a "case" one?

#

because your RGB code worked better with the one highlighted in red, than green in getting as little discrepancies in pixels as possible. OP never knew why that is the case.
(Source: https://github.com/Jas2o/KyleHyde/pull/1)

#

It's fine if you don't remember. You can also ask me to give you more details into any of these if you want to, as it was a busy year.

outer tinsel
#

Let me know if it's a problem, but you did say it got the stuff you wanted

outer tinsel
dreamy cobalt
#

same for case 216 and 252, raise their alpha values each raised by 3

dreamy cobalt
#

Actually now that I look at it...

#

the code was significantly changed compared to before

#

Welp, guess it may not matter now, I'll contact the dev and get his side.

#

Oh yeah, another curiosity about AC:R (another code:r) The box states that it is wiimote only, but that's not entirely true. So keep nunchuck close cause who knows.

#

Ppl without it risk getting stuck for good.

outer tinsel
#

am back

dreamy cobalt
#

birb

outer tinsel
dreamy cobalt
#

:D

#

I am not allowed to promote or share links to other servers in this server tho, so

#

mlem