sraboy / skaa_editor

Sprite Editor for Seven Kingdoms: Ancient Adversaries (7KAA).
3 stars 3 forks source link

7KAA crashes w/ edited sprite #1

Closed sraboy closed 8 years ago

sraboy commented 8 years ago

It seems that edits that change the layout, such that transparent pixels are added/removed in a way that changes the byte length of the sprite frame's data, will cause 7KAA to crash:

Exception thrown at 0x00692843 in 7kaa.exe: 0xC0000005: Access violation reading location 0x0ACAD000.

If there is a handler for this exception, the program may be safely continued.

The SPR file is loaded fine during initialization but the exception is thrown while drawing in IMGbltTransRemapDecompress() (IB_TRD.cpp @ Line 75).

7kaa.exe!IMGbltTransRemapDecompress(char * imageBuf=0x7e6f0008, int pitch=800, int desX=374, int desY=430, char * bitmapBuf=0x0ac9ab60, char * colorTable=0x006e95ce) Line 99 C++ 7kaa.exe!VgaBuf::put_bitmap_trans_remap_decompress(int x=374, int y=430, char * bitmapPtr=0x0ac9ab60, char * colorTable=0x006e95ce) Line 201 C++ 7kaa.exe!Unit::draw() Line 124 C++ 7kaa.exe!ZoomMatrix::draw_objects_now(DynArray * unitArray=0x0113b4d4, int displayLayer=1) Line 1767 C++ 7kaa.exe!ZoomMatrix::draw_objects() Line 1667 C++ 7kaa.exe!ZoomMatrix::draw_frame() Line 487 C++ 7kaa.exe!Sys::disp_zoom() Line 1012 C++ 7kaa.exe!Sys::update_view() Line 682 C++ 7kaa.exe!Sys::disp_frame() Line 571 C++ 7kaa.exe!Sys::process() Line 258 C++ 7kaa.exe!Sys::main_loop(int isLoadedGame=1) Line 733 C++ 7kaa.exe!Sys::run(int isLoadedGame=1) Line 493 C++ 7kaa.exe!Battle::run_loaded() Line 634 C++ 7kaa.exe!Game::single_player_menu() Line 609 C++ 7kaa.exe!Game::run_main_menu_option(int optionId=1) Line 299 C++ 7kaa.exe!Game::main_menu() Line 254 C++ 7kaa.exe!SDL_main(int argc=1, char * * argv=0x01650008) Line 416 C++ 7kaa.exe!main(int argc=1, char * * argv=0x01650008) Line 140 C 7kaa.exe!WinMain(HINSTANCE * hInst=0x00350000, HINSTANCE * hPrev=0x00000000, char * szCmdLine=0x01124c11, int sw=10) Line 177 C 7kaa.exe!__tmainCRTStartup() Line 618 C 7kaa.exe!WinMainCRTStartup() Line 466 C kernel32.dll!74f33744() Unknown [Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]
ntdll.dll!7704a064() Unknown ntdll.dll!7704a02f() Unknown

Notes from debugging:

data_buf=0x0AC9954D //ballista SPR In OUNITDRW.cpp @ Unit::draw() //this.Type() = Unit bitmapPtr=0x0ac9ab60 diff = bitmapPtr - data_buf //0x1613 = 5651

At bitmapPtr: "57 f2 f2 f8 28" In ballista.spr_old, that's at offset 1b27 In ballista.spr (edited), it's at 1c45

File size diff = new (82864)- old (82578) = 286 This is the same diff as 1c45-1b27, confirming the change is responsible

7k2 commented 8 years ago

You'll need to update the bitmap offsets in the SFRAME database in std.set. You can find the SFRAME record definition (SpriteFrameRec) in OSFRMRES.h.

std.set is really just multiple dBase III DBF files concatenated together, with an index tacked on at the beginning (see the Resource Formats page on the wiki: https://7kfans.com/wiki/index.php/ResourceFormats). For instance, running the file command to identify SFRAME.dbf (which I extracted from std.set) prints:

SFRAME.dbf: FoxBase+/dBase III DBF, 9048 records * 41, update-date
98-3-18, at offset 353 1st record "NORMAN  M N 1   -4 -17 35 46NO-M5-1 Y\"

The game doesn't make use of the database field descriptors (DbfRec in ODB.h), only DbfHeader. 7k2 does contain code to optionally make use of DbfRec, and can also save the records as a DBF file.

For reference, here's all the BALLISTA records from SFRAME.dbf:

Name    Act Dir Fid OffX OffY   W   H Filename BitmapPtr
BALLISTA M   N   1    -6  -30  46  67 WB-M5-1  24035
BALLISTA M   N   2    -6  -30  46  67 WB-M5-2  26084
BALLISTA M   N   3    -6  -30  46  67 WB-M5-3  28170
BALLISTA M   NE  1   -12  -24  62  65 WB-M4-1  17537
BALLISTA M   NE  2   -12  -24  63  65 WB-M4-2  19712
BALLISTA M   NE  3   -12  -24  63  65 WB-M4-3  21869
BALLISTA M   E   1   -10  -10  68  45 WB-M3-1  11128
BALLISTA M   E   2   -10  -10  69  45 WB-M3-2  13269
BALLISTA M   E   3    -9  -10  67  45 WB-M3-3  15407
BALLISTA M   SE  1   -12  -10  64  55 WB-M2-1  5277
BALLISTA M   SE  2   -12  -10  64  55 WB-M2-2  7238
BALLISTA M   SE  3   -12  -10  64  55 WB-M2-3  9185
BALLISTA M   S   1    -8   -7  48  50 WB-M1-1  0
BALLISTA M   S   2    -8   -7  48  50 WB-M1-2  1760
BALLISTA M   S   3    -8   -6  49  49 WB-M1-3  3513
BALLISTA M   SW  1   -19  -10  64  55 WB-M2-1  5277
BALLISTA M   SW  2   -19  -10  64  55 WB-M2-2  7238
BALLISTA M   SW  3   -19  -10  64  55 WB-M2-3  9185
BALLISTA M   W   1   -25  -10  68  45 WB-M3-1  11128
BALLISTA M   W   2   -26  -10  69  45 WB-M3-2  13269
BALLISTA M   W   3   -25  -10  67  45 WB-M3-3  15407
BALLISTA M   NW  1   -17  -24  62  65 WB-M4-1  17537
BALLISTA M   NW  2   -18  -24  63  65 WB-M4-2  19712
BALLISTA M   NW  3   -18  -24  63  65 WB-M4-3  21869
BALLISTA A1  N   1    -6  -30  46  67 WB-M5-1  24035
BALLISTA A1  N   2    -6  -30  46  67 WB-A5-1  70204
BALLISTA A1  N   3    -6  -31  46  68 WB-A5-2  72253
BALLISTA A1  N   4    -6  -31  46  68 WB-A5-2  72253
BALLISTA A1  N   5    -6  -31  46  68 WB-A5-3  74330
BALLISTA A1  N   6    -6  -31  46  68 WB-A5-3  74330
BALLISTA A1  NE  1   -12  -24  62  65 WB-M4-1  17537
BALLISTA A1  NE  2   -12  -26  63  67 WB-A4-1  59339
BALLISTA A1  NE  3   -12  -27  63  68 WB-A4-2  61557
BALLISTA A1  NE  4   -12  -27  63  68 WB-A4-2  61557
BALLISTA A1  NE  5   -12  -27  63  68 WB-A4-3  63728
BALLISTA A1  NE  6   -12  -27  63  68 WB-A4-3  63728
BALLISTA A1  E   1   -10  -10  68  45 WB-M3-1  11128
BALLISTA A1  E   2   -10  -10  68  45 WB-A3-1  48836
BALLISTA A1  E   3   -10  -10  69  45 WB-A3-2  50977
BALLISTA A1  E   4   -10  -10  69  45 WB-A3-2  50977
BALLISTA A1  E   5   -10  -10  69  45 WB-A3-3  53083
BALLISTA A1  E   6   -10  -10  69  45 WB-A3-3  53083
BALLISTA A1  SE  1   -12  -10  64  55 WB-M2-1  5277
BALLISTA A1  SE  2   -12  -10  64  55 WB-A2-1  39063
BALLISTA A1  SE  3   -12  -10  64  55 WB-A2-2  41024
BALLISTA A1  SE  4   -12  -10  64  55 WB-A2-2  41024
BALLISTA A1  SE  5   -12  -10  64  55 WB-A2-3  42989
BALLISTA A1  SE  6   -12  -10  64  55 WB-A2-3  42989
BALLISTA A1  S   1    -8   -7  48  50 WB-M1-1  0
BALLISTA A1  S   2    -8   -7  48  50 WB-A1-1  30263
BALLISTA A1  S   3    -8  -10  48  53 WB-A1-2  32024
BALLISTA A1  S   4    -8  -10  48  53 WB-A1-2  32024
BALLISTA A1  S   5    -8   -7  48  50 WB-A1-3  33797
BALLISTA A1  S   6    -8   -7  48  50 WB-A1-3  33797
BALLISTA A1  SW  1   -19  -10  64  55 WB-M2-1  5277
BALLISTA A1  SW  2   -19  -10  64  55 WB-A2-1  39063
BALLISTA A1  SW  3   -19  -10  64  55 WB-A2-2  41024
BALLISTA A1  SW  4   -19  -10  64  55 WB-A2-2  41024
BALLISTA A1  SW  5   -19  -10  64  55 WB-A2-3  42989
BALLISTA A1  SW  6   -19  -10  64  55 WB-A2-3  42989
BALLISTA A1  W   1   -25  -10  68  45 WB-M3-1  11128
BALLISTA A1  W   2   -25  -10  68  45 WB-A3-1  48836
BALLISTA A1  W   3   -26  -10  69  45 WB-A3-2  50977
BALLISTA A1  W   4   -26  -10  69  45 WB-A3-2  50977
BALLISTA A1  W   5   -26  -10  69  45 WB-A3-3  53083
BALLISTA A1  W   6   -26  -10  69  45 WB-A3-3  53083
BALLISTA A1  NW  1   -17  -24  62  65 WB-M4-1  17537
BALLISTA A1  NW  2   -18  -26  63  67 WB-A4-1  59339
BALLISTA A1  NW  3   -18  -27  63  68 WB-A4-2  61557
BALLISTA A1  NW  4   -18  -27  63  68 WB-A4-2  61557
BALLISTA A1  NW  5   -18  -27  63  68 WB-A4-3  63728
BALLISTA A1  NW  6   -18  -27  63  68 WB-A4-3  63728
BALLISTA A2  N   1    -6  -30  46  67 WB-M5-1  24035
BALLISTA A2  N   2    -6  -30  46  67 WB-A5-1  70204
BALLISTA A2  N   3    -6  -31  46  68 WB-A5-4  76398
BALLISTA A2  N   4    -6  -31  46  68 WB-A5-4  76398
BALLISTA A2  N   5    -6  -31  46  68 WB-A5-5  78475
BALLISTA A2  N   6    -6  -31  46  68 WB-A5-5  78475
BALLISTA A2  NE  1   -12  -24  62  65 WB-M4-1  17537
BALLISTA A2  NE  2   -12  -26  63  67 WB-A4-1  59339
BALLISTA A2  NE  3   -12  -22  63  63 WB-A4-4  65884
BALLISTA A2  NE  4   -12  -22  63  63 WB-A4-4  65884
BALLISTA A2  NE  5   -12  -22  63  63 WB-A4-5  68076
BALLISTA A2  NE  6   -12  -22  63  63 WB-A4-5  68076
BALLISTA A2  E   1   -10  -10  68  45 WB-M3-1  11128
BALLISTA A2  E   2   -10  -10  68  45 WB-A3-1  48836
BALLISTA A2  E   3   -10  -10  68  45 WB-A3-4  55170
BALLISTA A2  E   4   -10  -10  68  45 WB-A3-4  55170
BALLISTA A2  E   5   -10  -10  68  45 WB-A3-5  57274
BALLISTA A2  E   6   -10  -10  68  45 WB-A3-5  57274
BALLISTA A2  SE  1   -12  -10  64  55 WB-M2-1  5277
BALLISTA A2  SE  2   -12  -10  64  55 WB-A2-1  39063
BALLISTA A2  SE  3   -12  -11  64  56 WB-A2-4  44933
BALLISTA A2  SE  4   -12  -11  64  56 WB-A2-4  44933
BALLISTA A2  SE  5   -12  -10  64  55 WB-A2-5  46893
BALLISTA A2  SE  6   -12  -10  64  55 WB-A2-5  46893
BALLISTA A2  S   1    -8   -7  48  50 WB-M1-1  0
BALLISTA A2  S   2    -8   -7  48  50 WB-A1-1  30263
BALLISTA A2  S   3    -8  -10  49  53 WB-A1-4  35536
BALLISTA A2  S   4    -8  -10  49  53 WB-A1-4  35536
BALLISTA A2  S   5    -8   -6  49  49 WB-A1-5  37316
BALLISTA A2  S   6    -8   -6  49  49 WB-A1-5  37316
BALLISTA A2  SW  1   -19  -10  64  55 WB-M2-1  5277
BALLISTA A2  SW  2   -19  -10  64  55 WB-A2-1  39063
BALLISTA A2  SW  3   -19  -11  64  56 WB-A2-4  44933
BALLISTA A2  SW  4   -19  -11  64  56 WB-A2-4  44933
BALLISTA A2  SW  5   -19  -10  64  55 WB-A2-5  46893
BALLISTA A2  SW  6   -19  -10  64  55 WB-A2-5  46893
BALLISTA A2  W   1   -25  -10  68  45 WB-M3-1  11128
BALLISTA A2  W   2   -25  -10  68  45 WB-A3-1  48836
BALLISTA A2  W   3   -25  -10  68  45 WB-A3-4  55170
BALLISTA A2  W   4   -25  -10  68  45 WB-A3-4  55170
BALLISTA A2  W   5   -25  -10  68  45 WB-A3-5  57274
BALLISTA A2  W   6   -25  -10  68  45 WB-A3-5  57274
BALLISTA A2  NW  1   -17  -24  62  65 WB-M4-1  17537
BALLISTA A2  NW  2   -18  -26  63  67 WB-A4-1  59339
BALLISTA A2  NW  3   -18  -22  63  63 WB-A4-4  65884
BALLISTA A2  NW  4   -18  -22  63  63 WB-A4-4  65884
BALLISTA A2  NW  5   -18  -22  63  63 WB-A4-5  68076
BALLISTA A2  NW  6   -18  -22  63  63 WB-A4-5  68076
BALLISTA D       1   -15   -7  64  57 WB-D-1   80539
BALLISTA D       2   -15   -7  64  57 WB-D-1   80539
BALLISTA D       3   -15   -7  64  57 WB-D-1   80539
BALLISTA D       4   -15   -7  64  57 WB-D-1   80539
BALLISTA D       5   -15   -7  64  57 WB-D-1   80539
BALLISTA D       6   -15   -7  64  57 WB-D-1   80539
BALLISTA D       7   -15   -7  64  57 WB-D-1   80539
BALLISTA D       8   -15   -7  64  57 WB-D-1   80539
BALLISTA D       9   -15   -7  64  57 WB-D-1   80539
BALLISTA D       10  -15   -7  64  57 WB-D-1   80539
sraboy commented 8 years ago

I was just digging through this stuff the other day. Thanks for the post! I ended up borking my VS install so it's taken me a few days to fix it so I could step through the source and see how this all fits together, like how the SFRAME DB is actually referenced/used. None of the west-facing frames actually exist; they're just mirrored copies of the opposite frames in the SPR. That also means the order of the list, and order of sprites in memory, will change which offsets need to be recalculated since it's not the same order as the SPR file.

sraboy commented 8 years ago

This is currently in progress. The set_editor branch can currently load the SFRAME database from std.set into a DataTable, courtesy of Microsoft's Jet Engine, which is even older than this game.

Next up is associating a particular sprite with its DataTable and each SpriteFrame with its row in that table. From there, I'll have to work out the serialization to actually save the changes.

sraboy commented 8 years ago

Moving further. Ended up having to work out serialization/saving first since I didn't want to keep track of file paths and/or allow the user to break their own files. The project branch now saves SkaaEditor projects as SKP files, which are just ZIP archives. They currently contain the SET, RES and SPR files associated with the current project.

Also, the old set_editor branch is now useless. All the database stuff is working to this point and has been rolled into project. Hopefully another few weekends will have at least basic functionality worked out for saving an individual sprite with a new SET file. The big thing will be allowing projects to hold more than one sprite and writing new SET files for any number of edited sprites.

sraboy commented 8 years ago

See this forum post (and the whole thread really) to see the status. This issue is resolved in the write_database branch and will soon be available in beta release.