QuickBMS errors [programming, scripting, quickbms.exe tool... NOT games]

Doubts, help and support about QuickBMS and other game research tools
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: QuickBMS errors

Post by aluigi »

In the manual quickbms.txt the fields that are handled as C strings (basically those strings that are parsed by quickbms for escape characters) are tagged as "c string".
The conversion is performed while parsing the bms script and the binary operator of the String command is the one that gets escaped strings:
set VAR binary "hello\nbye"

The reason why handling strings in quickbms may be bad in some situations it's just because it's not a scripting language for string manipulation and the escaped strings have been introduced in some specific commands/operators to avoid confusion to users not used to them.

"goto EOF 1" doesn't work but I guess it's an old compatibility with the old multiex language. It's something that should be never used and I guess I forgot it in the manual (I will check if I can fix it anyway).
"goto SEEK_END 1" and "goto 0 1 SEEK_END" work correctly.

Regarding the EXISTS field of the Open command in -w mode, well it's both right and wrong and the same time... it depends by the point of view.
Basically the -w option simply makes the opened files both readable and writable instead of read-only. With writable currently it means that it gets created if doesn't exist.
It's a behaviour that I think "may" be changed but I would avoid to create new bugs because it's a core function, anyway I will check and fix it in the next version because it may cause problems also while reimporting some scripts that check existent files.

Thanks for the feedbacks, feel free to provide more tips and suggestions.
Zim
Posts: 15
Joined: Sun Aug 30, 2015 12:19 am

Re: QuickBMS errors

Post by Zim »

Thanks.

Well if open with -w will ("may" be) stop creating a files, at least we still have an append mode and log 0 0.
But if you mean changes ("may") in behavior of its EXISTS field only, without removing the possibility of creating a files - I will not be upset at all :)

As for EOF - it's not a problem but I believe it would be nice to see it quickbms.txt too (as well as about creating a files with open and -w) cause it's really important.

So if I understood correctly, we can only use string P=, p=, x= and not any P+ etc?
Of course this is also not a problem, because we can use multiple variables and just add more commands like regular string VAR + VAR :)

P.S. I understand that QuickBMS is not a scripting language for string or some other complex manipulations, but it's really so awesome tool that many ppl using it like a powerful hex processor for many complex things, and not just for manipulation of game resources. And me too :) Though it's slower than native compiled program, but it's very flexible and easy. Thank you very much for it!


Added:
aluigi wrote:P= and P+ are the same because only the first char is the operator.
The '=' after it is only a C-like notation that means nothing to quickbms, so P or P= is the same.
Omg thanks, I finally realized that P/p/x just uses only one input argument :D And the VAR is just output only. So the "=" is not any second operator but syntactic sugar.
Last edited by Zim on Sun Aug 30, 2015 6:22 pm, edited 7 times in total.
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: QuickBMS errors

Post by aluigi »

P= and P+ are the same because only the first char is the operator.
The '=' after it is only a C-like notation that means nothing to quickbms, so P or P= is the same.
The reason I used it often in my scripts (at least till some weeks ago) is just because I'm used to other programming languages (var += var2).

Regarding EOF and -w/open/exists I will fix them.
Zim
Posts: 15
Joined: Sun Aug 30, 2015 12:19 am

Re: QuickBMS errors

Post by Zim »

Is it a bug or a limitation?

Code: Select all

StartFunction Function
    if Function_arg1 == "Function_arg1"
        print "No arguments"
    else
        print "%Function_arg1%"
    endif
EndFunction

CallFunction Function 1                   # - SCRIPT's MESSAGE:  No arguments
CallFunction Function 1 "string"          # - SCRIPT's MESSAGE:  No arguments
CallFunction Function 1 1                 # - SCRIPT's MESSAGE:  No arguments

I was just trying to find a simple way to check whether argument was passed to the function or wasn't...

Well if you replace condition from == to ^ at least you will be able to check for numeric arguments:

Code: Select all

CallFunction Function 1                   # - SCRIPT's MESSAGE:  No arguments
CallFunction Function 1 "string"          # - SCRIPT's MESSAGE:  No arguments
CallFunction Function 1 1                 # - SCRIPT's MESSAGE:  1

So it's because QuickBMS just turns strings "Function_arg1" into a Function_arg1 variables (where 1 is any number) for some reason (probably optimisation?):

Code: Select all

StartFunction Function
    set String1 string "Function_arg1"
    string String2 = "Function_arg1"
    print "Strings: '%String1%' / '%String2%'"
EndFunction

CallFunction Function 1                   # - SCRIPT's MESSAGE:  Strings: 'Function_arg1' / 'Function_arg1'
CallFunction Function 1 "string"          # - SCRIPT's MESSAGE:  Strings: 'string' / 'string'
CallFunction Function 1 1                 # - SCRIPT's MESSAGE:  Strings: '1' / '☺'


Offtopic below (not about bugs).
So for now I'm using this:

Code: Select all

StartFunction Function
    string Check_arg1 = "~Function_arg1"
    string Check_arg1 < 1
    if Function_arg1 == Check_arg1
        print "No arguments"
    else
        print "%Function_arg1%"
    endif
EndFunction

CallFunction Function 1                   # - SCRIPT's MESSAGE:  No arguments
CallFunction Function 1 "string"          # - SCRIPT's MESSAGE:  string
CallFunction Function 1 1                 # - SCRIPT's MESSAGE:  1
But maybe there is some easier way?

P.S. I placed function definition in the beginning for better readability, guys you better place it at the end of your scripts. For the same reason =)

Added:
Omg I was stupid, we don't have to assigning Check-var inside the function (also each time it's called), so here is an easier way:

Code: Select all

# combined name of var because we may have more than 1 function
string Null_Function_arg1 = "Function_arg1"
# string Null_AnotherFunction_arg1 = "AnotherFunction_arg1"
# ...
# place your CallFunction here
# ...
StartFunction Function
    if Function_arg1 == Null_Function_arg1
        print "No arguments"
    else
        print "%Function_arg1%"
    endif
EndFunction

Also for integer numeric arguments which must not be equal to 0 (so if you will check it anyway) you can just use datatype conversion:

Code: Select all

StartFunction Function
    set Function_arg1 long Function_arg1  # byte, short
    if Function_arg1 != 0
  # if Function_arg1 > 0                  # > 17
  # if Function_arg1 < 0                  # < -8
  # etc
        # your code
        # ...
    endif
EndFunction
Because any strings will become a 0, including in the case of lack of argument.
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: QuickBMS errors

Post by aluigi »

In quickbms there are no differences between strings and variables because (at least at the moment) there is no handling of constant values so VARIABLE and "VARIABLE" are referred to the same variable with equal name and content.

Checking if an argument is set requires the usage of work-arounds like the one used in http://aluigi.org/papers/bms/others/next_car_game.bms for quickbms_arg1.
It would be better if you consider the argument as already set, so mandatory instead of optional.

Are you sure isn't better to use python, perl or ruby for these tasks?
Zim
Posts: 15
Joined: Sun Aug 30, 2015 12:19 am

Re: QuickBMS errors

Post by Zim »

Thanks.
Yeah, Function_arg1 & "Function_arg" is working fine too, I was just obsessed with too strict checking :) But there is no real point to do this strictly.
I'm gonna fix my post to shorten it.
I agree that in QuickBMS scripts it's better to make the arguments mandatory, but sometimes it's really useful to make it optional, especially when the function is used many times with different sets of args.

Well I'm not sure isn't better to use python etc, but I'm using QuickBMS for game resources too, so I wanna discover such unusual tricks and methods anyway :)
Zim
Posts: 15
Joined: Sun Aug 30, 2015 12:19 am

Re: QuickBMS errors

Post by Zim »

quickbms.txt:
Math VAR OP VAR
...
                v radix (also //)
                p power (also **)

Code: Select all

set BASE 4
math BASE ** 2            # Error: invalid operator ' '

Code: Select all

set BASE 4
math BASE // 2            # Error: invalid command "math" or arguments -1 at line 2
But it's not a problem cause we still have v and p.

The real problem is in xmath:
XMath VAR INSTR
...
        ** power
        // root

Code: Select all

set BASE 4
set EXP 2

xmath OUT "BASE ** 2"
print "%OUT%"             # - SCRIPT's MESSAGE:  16
xmath OUT "BASE ** EXP"
print "%OUT%"             # - SCRIPT's MESSAGE:  1

xmath OUT "BASE // 2"
print "%OUT%"             # - SCRIPT's MESSAGE:  2
xmath OUT "BASE // EXP"
print "%OUT%"             # - SCRIPT's MESSAGE:  0
So here xmath takes the 2nd argument as 0 if it's a var.

P.S. I didn't check another operators of math/xmath except the basic =+-*/%
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: QuickBMS errors

Post by aluigi »

Regarding the first, I guess I didn't update quickbms.txt or something similar, but I will simply add a "** -> p" and "// -> v" replacer (same for >>> and <<< and <>) in quickbms to solve the problem.

The second one is interesting because it happens only with the operators of more than one char (>>> and others too), will fix it too.

Thanks a lot
Zim
Posts: 15
Joined: Sun Aug 30, 2015 12:19 am

Re: QuickBMS errors

Post by Zim »

Unfortunately arrays inside the variables like Array[i] don't work in xmath either (always treated as 0).
But math and string are fine with them.

Also I found a problem with optional arguments of user functions:

Code: Select all

StartFunction Function
    print "'%Function_arg1%'"
EndFunction

CallFunction Function 1 "argument"    # - SCRIPT's MESSAGE:  'argument'
CallFunction Function 1               # - SCRIPT's MESSAGE:  'argument'

# compare with mandatory argument:
CallFunction Function 1 ""            # - SCRIPT's MESSAGE:  ''

It looks the same as this:

Code: Select all

set VAR "VALUE"
string VAR = ""           # Nope, you can't kill me this way
print "'%VAR%'"           # - SCRIPT's MESSAGE:  'VALUE'

# compare with set:
set VAR ""
print "'%VAR%'"           # - SCRIPT's MESSAGE:  ''

I'm not sure if it is an issues, but I wanna warn the others.
So guys use set and always flush any optional arguments in the end of your function:

Code: Select all

StartFunction Function
    # place your check for argument/s here (see below)
    print "'%Function_arg1%'"

    # flush optional arguments
    set Function_arg1 ""              # (or any string)
                                      # for numeric optional arguments, strict condition:
                                      #   if Function_arg1 ^ Function_arg1
                                      #       # not a numeric argument
    # or
    set Function_arg1 "Function_arg"  # for any optional arguments, non-strict (check your strings):
                                      #   if Function_arg1 & "Function_arg"
                                      #       # no arguments
EndFunction
Quotes in the last flush & argument check were used for better readability only and are not really necessary. So never assign any value to Function_arg as a var.
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: QuickBMS errors

Post by aluigi »

It's not a bug because the "1" in callfunction forces quickbms to create and maintain any variable created in the function so Function_arg1 is then globally visible.
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: QuickBMS errors

Post by aluigi »

I'm just fixing all the issues.
Currently ARRAY[i] will be not supported in *math because they are just an experimental feature added to quickbms without a real usage.
Basically they should be not used in normal conditions because are very limited (you cannot use ARRAY[3], only ARRAY[VAR]).

The function arguments with keep_variable enabled can't be touched just because that's the way it works (and modifying that code will for sure introduce new issues).
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: QuickBMS errors

Post by aluigi »

Zim wrote:...
Also why we can't use any "0xAB" as a real string? We always get numbers/their bytes instead of strings and even with "0x" or "1x2" etc:
...

Regarding the confusion caused by strings and numbers and about how they get converted in quickbms, I have finally activated a feature that I introduced many versions ago.
Basically quickbms already had the opportunity to recognized the variables specified between quotes as constants and now I found a lame trick to allow it without modifying everything.
I'm testing it just now and it seems to work correctly but I'm sure there are some side-consequences to verify.
I will keep you update.
Zim
Posts: 15
Joined: Sun Aug 30, 2015 12:19 am

Re: QuickBMS errors

Post by Zim »

Thanks!
aluigi wrote:Currently ARRAY[i] will be not supported in *math because they are just an experimental feature added to quickbms without a real usage.
Basically they should be not used in normal conditions because are very limited (you cannot use ARRAY[3], only ARRAY[VAR]).
Well, pls don't remove it at least from math... I'm still using it, sometimes it's really much more useful than just 1 array (GetArray/PutArray) or tons of vars. And it works absolutely ok, we just must to use the same var for indexes, but it's ok! Because we always can create individual vars (per array) or temp vars (for all/several arrays) for such purpose.

Also you still can use Array[1] / 2 / 3 too - you just have to assign it! And if you wanna use it than you most likely need only few numbers, so it will not be a real problem to assign it (at least for usage inside of your function/s).
Sometimes I'm using it for fucntions which support up to several return values for a common purpose:

Code: Select all

#   ...
    if idx == 0
        set HEX HEX[idx]
    elif idx == 1
        set HEX[1] HEX[idx]
    elif idx == 2
        set HEX[2] HEX[idx]
    elif idx == 3
        set HEX[3] HEX[idx]
    elif idx == 4           # for internal usage only
        set HEX[4] HEX[idx]
    endif
EndFunction
So as you can see here is 4 return values are for user of this function (HEX - HEX[3]) and one (HEX[4]) is for internal usage by other functions (some of them uses both user made and own these HEX values in same call).
In this example an index is defined by user as an argument in CallFunction. But in other usecases it awlays returns all values, obviously you just have to add for for this.
Sometimes this way of using both Array[var] and Array[1] is really useful when you have the same set of a lot of actions to be executed with several vars (array[1], 2, 3, etc) and/or to save the ability to execute a (for) loop over them in the future.

But most of the time I'm just using Array[i] with temp/individual indexes for a lot of values.

P.S. And I'm still talking about regular usage of QuickBMS but for complex formats and/or gentle console output.

aluigi wrote:The function arguments with keep_variable enabled can't be touched just because that's the way it works (and modifying that code will for sure introduce new issues).
I totally agree, it's absolutely ok! I just forgot about KEEP_VAR, so now I'm taking this into account and using KEEP_VAR=0 or flushing methods.

aluigi wrote:I have finally activated a feature that I introduced many versions ago.
Basically quickbms already had the opportunity to recognized the variables specified between quotes as constants and now I found a lame trick to allow it without modifying everything.
Wow that sounds cool! I'm looking forward to any updates, thanks!
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: QuickBMS errors

Post by aluigi »

yeah ARRAY[i] will be left untouched. I used the wrong words :)
Currently I guess to have fixed everything was reported plus a couple of additional things so I think later I can upload a beta and you can check it telling if there is still something to fix.
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: QuickBMS errors

Post by aluigi »

Ok the beta is ready and you can find it attached to this post.
Feel free to report any issue :)
spider91
Posts: 233
Joined: Sun Aug 24, 2014 5:26 pm

Re: QuickBMS errors

Post by spider91 »

I've found an error. Using quickbms_4gb 0.6.7a i can't convert 64bit values to hex representation. Here is a screen

Image
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: QuickBMS errors

Post by aluigi »

That's sprintf.
Using %016llX and %016I64X (the correct formats in this case) doesn't work because the arguments are passed as 32bit.

In your case I suggest the following:
string VAR P "%VAR|x%"
string VAR << 2
spider91
Posts: 233
Joined: Sun Aug 24, 2014 5:26 pm

Re: QuickBMS errors

Post by spider91 »

Thanks. So it gonna work correctly for bigget and lower offsets too?
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: QuickBMS errors

Post by aluigi »

The output is exactly like %016x, so 0x0022334455667788 will be 0022334455667788
spider91
Posts: 233
Joined: Sun Aug 24, 2014 5:26 pm

Re: QuickBMS errors

Post by spider91 »

Awesome, thanks again.