My first quickBMS script

Programming related discussions related to game research
AnonBaiter
Posts: 1125
Joined: Tue Feb 02, 2016 2:35 am

Re: My first quickBMS script

Post by AnonBaiter »

aluigi wrote:Do you mean that there are files like NAME.DIR, NAME.IMG and alos NAME_1.IMG and NAME_2.IMG?
If yes then it's possible that one of the fields assigned to the filename is the ID of the archive to use.

Of course. But then again what's the proposed solution for that?

Anyway, I'm writing another script, this time on a different format:

Code: Select all

00000000  56 45 52 32 BC 01 00 00 07 00 00 00 FB 04 00 00  VER2¼.......û...
00000010  62 63 65 73 61 34 77 2E 69 66 70 00 AC 00 AD 00  bcesa4w.ifp.¬...
00000020  AE 00 AF 00 B0 00 B1 00 02 05 00 00 01 00 00 00  ®.¯.°.±.........
00000030  62 63 65 73 61 34 77 2E 63 75 74 00 AC 00 AD 00  bcesa4w.cut.¬...
00000040  AE 00 AF 00 B0 00 B1 00 03 05 00 00 02 00 00 00  ®.¯.°.±.........
00000050  62 63 65 73 61 34 77 2E 64 61 74 00 AC 00 AD 00  bcesa4w.dat.¬...
00000060  AE 00 AF 00 B0 00 B1 00 05 05 00 00 AA 03 00 00  ®.¯.°.±.....ª...
00000070  62 63 65 73 61 35 77 2E 69 66 70 00 AC 00 AD 00  bcesa5w.ifp.¬...
00000080  AE 00 AF 00 B0 00 B1 00 AF 08 00 00 01 00 00 00  ®.¯.°.±.¯.......
00000090  62 63 65 73 61 35 77 2E 63 75 74 00 AC 00 AD 00  bcesa5w.cut.¬...
000000A0  AE 00 AF 00 B0 00 B1 00 B0 08 00 00 05 00 00 00  ®.¯.°.±.°.......
000000B0  62 63 65 73 61 35 77 2E 64 61 74 00 AC 00 AD 00  bcesa5w.dat.¬...
000000C0  AE 00 AF 00 B0 00 B1 00 B5 08 00 00 A4 05 00 00  ®.¯.°.±.µ...¤...
000000D0  62 63 65 73 61 72 32 2E 69 66 70 00 AC 00 AD 00  bcesar2.ifp.¬...
000000E0  AE 00 AF 00 B0 00 B1 00 59 0E 00 00 01 00 00 00  ®.¯.°.±.Y.......
000000F0  62 63 65 73 61 72 32 2E 63 75 74 00 AC 00 AD 00  bcesar2.cut.¬...
00000100  AE 00 AF 00 B0 00 B1 00 5A 0E 00 00 04 00 00 00  ®.¯.°.±.Z.......


This is the script I'm writing for the format:

Code: Select all

getdstring SIGN 4
get FILES long
for i = 0 < FILES
   get OFFSET long
   get SIZE long
   getdstring NAME 0xC
   get UNKNOWN1 long
   get UNKNOWN2 long
   get UNKNOWN3 long
   math OFFSET * 0x800
   math SIZE * 0x800
   putarray 0 i OFFSET
   putarray 1 i SIZE
   putarray 2 i NAME
next i

It'll be finished after I make a few tests.
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: My first quickBMS script

Post by aluigi »

A solution for the multiple archives can be like the one in the script for the warriors, search "LAST_ARCHIVE_NUM" in the script (the method can be done also without recording the currently open archive but it makes everything faster).
AnonBaiter
Posts: 1125
Joined: Tue Feb 02, 2016 2:35 am

Re: My first quickBMS script

Post by AnonBaiter »

Huh. That's what I should have considered doing before deleting all the files I've tested with.
Anyways, I have two .IMG files(GTA3.IMG, GTA3_1.IMG, no .DIR file). Should I do it like this:

Code: Select all

getdstring SIGN 4
get FILES long

math LAST_ARCHIVE_NUM = -1
for i = 0 < FILES
   get OFFSET long
   get SIZE long
   getdstring NAME 0x18
   math OFFSET * 0x800
   math SIZE * 0x800
   
   if LAST_ARCHIVE_NUM != ARCHIVE_NUM
      math LAST_ARCHIVE_NUM = ARCHIVE_NUM
      getarray ARCHIVE_NAME 0 ARCHIVE_NUM
      open FDSE ARCHIVE_NAME 1
   endif
   
   putarray 0 i OFFSET
   putarray 1 i SIZE
   putarray 2 i NAME
   log NAME OFFSET SIZE
next i
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: My first quickBMS script

Post by aluigi »

You have to read the ARCHIVE_NUM field from the archive and then building the name of the img to open.
AnonBaiter
Posts: 1125
Joined: Tue Feb 02, 2016 2:35 am

Re: My first quickBMS script

Post by AnonBaiter »

I think I'm puzzled here, can you elaborate on this so that I can get the idea?
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: My first quickBMS script

Post by aluigi »

You need to locate the field in the index file where is placed the number of the archive to use, like to for GTA3.IMG, 1 for GTA3_1.IMG and so on.
As you said there is only one index file and 3 archives, right?

building the name of the package to load is simple:

Code: Select all

get TMP basename
if ARCHIVE_NUM == 0
    string TMP p "%s.img" TMP
else
    string TMP p "%s_%d.img" TMP ARCHIVE_NUM
endif
open FDSE TMP 1
AnonBaiter
Posts: 1125
Joined: Tue Feb 02, 2016 2:35 am

Re: My first quickBMS script

Post by AnonBaiter »

>TMP
Dammit, how could I forget that?

Uhh, by the way, the "load" keyword is detected as invalid on the quickbms application.
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: My first quickBMS script

Post by aluigi »

My fault: load -> open
AnonBaiter
Posts: 1125
Joined: Tue Feb 02, 2016 2:35 am

Re: My first quickBMS script

Post by AnonBaiter »

Well, it looks better now.
But there's one problem left to solve though: with this solution, the script tries to load a non-existent file(GTA3_0.IMG). So is there any way to load a file that has that "_1.IMG" file rather than "_0.IMG"?
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: My first quickBMS script

Post by aluigi »

The snippest of code I pasted loads GTA3.IMG if ARCHIVE_NUM is zero.
Have you read the ARCHIVE_NUM field from the index file?
AnonBaiter
Posts: 1125
Joined: Tue Feb 02, 2016 2:35 am

Re: My first quickBMS script

Post by AnonBaiter »

Well, maybe I didn't actually "read" the field but both of these files look strikingly similar.

GTA3.IMG

Code: Select all

00000000  56 45 52 32 58 3F 00 00 FE 00 00 00 02 00 00 00  VER2X?..þ.......
00000010  6C 65 76 65 6C 6D 61 70 5F 73 74 72 65 61 6D 30  levelmap_stream0
00000020  2E 69 70 6C 00 00 B1 00 00 01 00 00 03 00 00 00  .ipl..±.........
00000030  6C 65 76 65 6C 6D 61 70 5F 73 74 72 65 61 6D 31  levelmap_stream1
00000040  2E 69 70 6C 00 00 B1 00 03 01 00 00 3B 00 00 00  .ipl..±.....;...
00000050  6C 65 76 65 6C 6D 61 70 5F 31 2E 63 6F 6C 00 00  levelmap_1.col..
00000060  AE 00 AF 00 B0 00 B1 00 3E 01 00 00 47 00 00 00  ®.¯.°.±.>...G...
00000070  77 65 65 6D 61 70 2E 74 78 64 00 00 AC 00 AD 00  weemap.txd..¬...
00000080  AE 00 AF 00 B0 00 B1 00 85 01 00 00 04 00 00 00  ®.¯.°.±.….......
00000090  62 72 69 64 67 65 5F 31 2E 64 66 66 00 00 AD 00  bridge_1.dff....
000000A0  AE 00 AF 00 B0 00 B1 00 89 01 00 00 02 00 00 00  ®.¯.°.±.‰.......
000000B0  64 5F 73 69 67 6E 2E 64 66 66 00 00 AC 00 AD 00  d_sign.dff..¬...
000000C0  AE 00 AF 00 B0 00 B1 00 8B 01 00 00 01 00 00 00  ®.¯.°.±.‹.......
000000D0  64 5F 73 69 67 6E 30 31 2E 64 66 66 00 00 AD 00  d_sign01.dff....
000000E0  AE 00 AF 00 B0 00 B1 00 8C 01 00 00 02 00 00 00  ®.¯.°.±.Œ.......
000000F0  68 65 6C 69 70 61 64 2E 64 66 66 00 AC 00 AD 00  helipad.dff.¬...

GTA3_1.IMG

Code: Select all

00000000  56 45 52 32 58 3F 00 00 FE 00 00 00 02 00 00 00  VER2X?..þ.......
00000010  6C 65 76 65 6C 6D 61 70 5F 73 74 72 65 61 6D 30  levelmap_stream0
00000020  2E 69 70 6C 00 00 B1 00 00 01 00 00 03 00 00 00  .ipl..±.........
00000030  6C 65 76 65 6C 6D 61 70 5F 73 74 72 65 61 6D 31  levelmap_stream1
00000040  2E 69 70 6C 00 00 B1 00 03 01 00 00 3B 00 00 00  .ipl..±.....;...
00000050  6C 65 76 65 6C 6D 61 70 5F 31 2E 63 6F 6C 00 00  levelmap_1.col..
00000060  AE 00 AF 00 B0 00 B1 00 3E 01 00 00 47 00 00 00  ®.¯.°.±.>...G...
00000070  77 65 65 6D 61 70 2E 74 78 64 00 00 AC 00 AD 00  weemap.txd..¬...
00000080  AE 00 AF 00 B0 00 B1 00 85 01 00 00 04 00 00 00  ®.¯.°.±.….......
00000090  62 72 69 64 67 65 5F 31 2E 64 66 66 00 00 AD 00  bridge_1.dff....
000000A0  AE 00 AF 00 B0 00 B1 00 89 01 00 00 02 00 00 00  ®.¯.°.±.‰.......
000000B0  64 5F 73 69 67 6E 2E 64 66 66 00 00 AC 00 AD 00  d_sign.dff..¬...
000000C0  AE 00 AF 00 B0 00 B1 00 8B 01 00 00 01 00 00 00  ®.¯.°.±.‹.......
000000D0  64 5F 73 69 67 6E 30 31 2E 64 66 66 00 00 AD 00  d_sign01.dff....
000000E0  AE 00 AF 00 B0 00 B1 00 8C 01 00 00 02 00 00 00  ®.¯.°.±.Œ.......
000000F0  68 65 6C 69 70 61 64 2E 64 66 66 00 AC 00 AD 00  helipad.dff.¬...

Which is why I assume they're duplicates.
eatrawmeat391
Posts: 9
Joined: Sun Jul 17, 2016 5:23 am

Re: My first quickBMS script

Post by eatrawmeat391 »

The GTA3_1.IMG is a duplicate of GTA3.IMG.If you have a PS2 version of GTA SA there is a file called 'FILELOAD.NM'.Open it in hex and search for 'GTA3_%d.IMG',replace it with just 'GTA3.IMG'.This will bypass the GTA3_1.IMG reading and you can safety delete GTA3_1.IMG.Just mod GTA3.IMG
AnonBaiter
Posts: 1125
Joined: Tue Feb 02, 2016 2:35 am

Re: My first quickBMS script

Post by AnonBaiter »

...aaaand done. I'll consider that solution for when I actually feel like testing the game on an emulator or real hardware but for now I'll just release the script as is.
AnonBaiter
Posts: 1125
Joined: Tue Feb 02, 2016 2:35 am

Re: My first quickBMS script

Post by AnonBaiter »

So far I'm working on a script focusing on the .bsa file.

Code: Select all

goto 0
get FILES short
get DUMMY short
for i = 0 < FILES
   goto -18
   savepos OFFSET
   getdstring NAME 0xE
   get SIZE long
   math OFFSET - SIZE
   goto OFFSET
next i

The index itself is at the very end of the file, as you can see here:

Code: Select all

00FFB5B0                    30 31 41 58 45 2E 43 46 41 00        01AXE.CFA.
00FFB5C0  00 00 00 00 E1 02 00 00 30 31 42 41 52 41 54 54  ....á...01BARATT
00FFB5D0  2E 43 46 41 00 00 D7 14 00 00 30 31 42 41 52 57  .CFA..×...01BARW
00FFB5E0  4C 4B 2E 43 46 41 00 00 E0 2A 00 00 30 31 42 41  LK.CFA..à*..01BA
00FFB5F0  58 45 2E 43 46 41 00 00 00 00 AD 04 00 00 30 31  XE.CFA........01
00FFB600  42 4D 41 43 45 2E 43 46 41 00 00 00              BMACE.CFA...

The problem though is that when I test the script on debug mode, it doesn't detect the next file:

Code: Select all

- current_folder: E:\quickbms
- bms_folder:     E:\reverse.engineering.stuff
- exe_folder:     E:\quickbms
- file_folder:    E:\IBM - PC compatible (Non-Europe-CD)\ARENA_CD
- output_folder:  E:\quickbms
- temp_folder:    C:\Users\TCA\AppData\Local\Temp\
- open input file E:\IBM - PC compatible (Non-Europe-CD)\ARENA_CD\GLOBAL.BSA
- open script E:\reverse.engineering.stuff\bethesda_bsa.bms
- set output folder .

  offset   filesize   filename
--------------------------------------
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4
.
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4
.
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4
.
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4
.
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4
.
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4
.
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4
.
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4
.
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4
.
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4
.
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4
.
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4
.
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4
.
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4
.
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4
.
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4
.
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4
.
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4
.
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4
.
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4
.
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4
.
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4
.
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4
.
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4
.
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4
.
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4
.
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4
.
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4
.
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4
.
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4
.
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4
.
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4
.
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4
.
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4
.
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4
.
. 01006146 getdstr NAME       "ZOMBIE6.CFA" 14
    5a 4f 4d 42 49 45 36 2e 43 46 41 00 00 00         ZOMBIE6.CFA...
. 01006154 get     SIZE       0x00000d6c 4

Am I doing something wrong?
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: My first quickBMS script

Post by aluigi »

You return ever to -0x18, that's an absolute offset and not a relative one.
Are you 100% sure that this format must be read from the end in that way?
AnonBaiter
Posts: 1125
Joined: Tue Feb 02, 2016 2:35 am

Re: My first quickBMS script

Post by AnonBaiter »

Well, that's what I'm trying to do.
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: My first quickBMS script

Post by aluigi »

Probably you have to find where the toc starts by doing: xmath INFO_OFF "ARCHIVE_SIZE - (FILES * (0xe + 0x4))"
And then using the OFFSET 4 as starting offset for the files.
AnonBaiter
Posts: 1125
Joined: Tue Feb 02, 2016 2:35 am

Re: My first quickBMS script

Post by AnonBaiter »

"OFFSET 4"... like this:

Code: Select all

get FILES short
get DUMMY short
savepos INFO_OFF
xmath INFO_OFF "ARCHIVE_SIZE - (FILES * (0xe + 0x4))"
for i = 0 < FILES
   goto -18
   savepos OFFSET
   log MEMORY_FILE OFFSET 4
...
Last edited by AnonBaiter on Tue Jul 26, 2016 11:24 am, edited 1 time in total.
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: My first quickBMS script

Post by aluigi »

Because 4 is the sum of the 2 shorts you have read at the beginning.
AnonBaiter
Posts: 1125
Joined: Tue Feb 02, 2016 2:35 am

Re: My first quickBMS script

Post by AnonBaiter »

I'm still clueless, do I have to use both the two shorts as the starting offset for the files? I'm still thinking on removing the "goto -18" line but...