Jump to content

Help with READ_ASCII


Recommended Posts

Ok, I have been banging my head against this and just cannot find the mistake. I have the following patch function with PATCH_PRINT's interspersed for debugging:

//Return ith header as a string (e.g. cloning). If header out of bounds, returns the empty string.
DEFINE_PATCH_FUNCTION GET_INDEXED_HEADER_AS_STRING INT_VAR header = 0 RET string BEGIN
    TEXT_SPRINT string ""
    LPF GET_INDEXED_HEADER_OFFSET INT_VAR header = %header% RET header_offset = offset END
    PATCH_PRINT "Header offset is: %header_offset%."
    PATCH_IF NOT (header_offset = 0) BEGIN
        READ_ASCII header_offset string (SPELL_HEADER_SIZE)
        SET len = STRING_LENGTH string
        PATCH_PRINT "Length of read block is: %len%."
        PATCH_PRINT "Read block is:%LNL%%string%"
    END
END

When applied to spwi120 (Reflected Image as changed by SR) I get in the console:

Installing [Spell Macros Testing] [v1.0]
Copying and patching 1 file ...
Copying and patching 1 file ...

Header offset is: 114.

Length of read block is: 6.

Read block is:
SPWI120B

So the header offset is correct (The argument passed was 0, so was getting the offset of first header -- GET_INDEXED_HEADER_OFFSET is working as it should) but everything else is a mess. The length does not even coincide with the length "SPWI120B". And SPELL_HEADER_SIZE is what you think it is: a constant with the size of a header (0x28). So what the heck is going wrong? Why is it not reading the whole header? I somehow suspect that this is one of those newbie errors that will put me to shame...

note(s):

- according to IESDP the first four fields of a header are: Spell form (char), Flags (char), Location (word) and Memorised icon (8 chars). Memorised icon is precisely "SPWI120B" so if the other fields are all 0's that *could* explain the totally counter-intuitive behavior of STRING_LENGTH and PATCH_PRINT. If that is the case, then can I be sure that the block read is indeed 0x28 bytes long despite the null-terminated shenanigans of string functions do not allow to test that? And is there a way to treat the string as an array of bytes to test it -- maybe looping over it and read byte by byte with READ_BYTE?

Edited by grodrigues
Typos. Note.
Link to comment
STRING_LENGTH string

Should be:

STRING_LENGTH ~%string%~

If this makes you feel stupid, don't worry.  You wouldn't believe how many times I've accidentally done the same when comparing strings.

3 hours ago, grodrigues said:

And is there a way to treat the string as an array of bytes to test it -- maybe looping over it and read byte by byte with READ_BYTE?

Yes:

INNER_PATCH ~%string%~
  READ_BYTE  0x00 type
  READ_BYTE  0x01 flags
  READ_SHORT 0x02 location
  // etc.
END

 

Link to comment

Thanks, that solved it, as the length of the string is the expected 40. The output of PATCH_PRINT of the read block is probably explained as in the note, by the nulls that snuck in there, and the quirks of both WeiDU and the console.

Yeah, newbie error... WeiDU is a great tool but it has lots of quirks and it lacks some facilities that general programming languages have to save us from shooting our feet. Miss me some Python. Or even better, Haskell.

Link to comment

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...