Try / OpenGothic

Reimplementation of Gothic 2 Notr
MIT License
1.14k stars 80 forks source link

Gothic Classic / Gothic II Complete Classic for Switch. Results #518

Open dreimer1986 opened 11 months ago

dreimer1986 commented 11 months ago

I was just too curious... I got the Gothic Classic Cart from THQ Store and dumped it with nxdumper. Then I converted it to ROMFS and that one I just extracted then.

The file structure is this: files.txt

So it looks no too different to what we have for example in a Steam release.

Still it crashed:

---crashlog(ExceptionFilter)---
GPU: NVIDIA GeForce RTX 2080
0x00007ff7ed1b1516: dbg::call_stack<64>::collect in C:\Users\Daniel\Desktop\opengothic_win\Gothic2Notr.exe
0x00007ff7ed1b0e42: CrashLog::dumpStack in C:\Users\Daniel\Desktop\opengothic_win\Gothic2Notr.exe
0x00007ff7ed1b0ffe: exceptionHandler in C:\Users\Daniel\Desktop\opengothic_win\Gothic2Notr.exe
0x00007ffeda2dc74c: UnhandledExceptionFilter in C:\WINDOWS\System32\KERNELBASE.dll
0x00007ffedcd3897d: memcpy in C:\WINDOWS\SYSTEM32\ntdll.dll
0x00007ffedcd1f027: _C_specific_handler in C:\WINDOWS\SYSTEM32\ntdll.dll
0x00007ffedcd3430f: _chkstk in C:\WINDOWS\SYSTEM32\ntdll.dll
0x00007ffedccae456: RtlFindCharInUnicodeString in C:\WINDOWS\SYSTEM32\ntdll.dll
0x00007ffedcce4465: RtlRaiseException in C:\WINDOWS\SYSTEM32\ntdll.dll
0x00007ffeda1e535c: RaiseException in C:\WINDOWS\System32\KERNELBASE.dll
0x00007ffec2eab760: CxxThrowException in C:\WINDOWS\SYSTEM32\VCRUNTIME140D.dll
0x00007ff7ed170ae6: std::filesystem::_Throw_fs_error in C:\Users\Daniel\Desktop\opengothic_win\Gothic2Notr.exe
0x00007ff7ed17cb9f: std::filesystem::file_size in C:\Users\Daniel\Desktop\opengothic_win\Gothic2Notr.exe
0x00007ff7ed2b693c: phoenix::buffer::mmap in C:\Users\Daniel\Desktop\opengothic_win\Gothic2Notr.exe
0x00007ff7ecf97cfb: Gothic::loadScript in C:\Users\Daniel\Desktop\opengothic_win\Gothic2Notr.exe
0x00007ff7ecf97950: Gothic::createPhoenixVm in C:\Users\Daniel\Desktop\opengothic_win\Gothic2Notr.exe
0x00007ff7ed1a6531: MenuRoot::MenuRoot in C:\Users\Daniel\Desktop\opengothic_win\Gothic2Notr.exe
0x00007ff7ed0f84c1: MainWindow::MainWindow in C:\Users\Daniel\Desktop\opengothic_win\Gothic2Notr.exe
0x00007ff7ed0f5f01: main in C:\Users\Daniel\Desktop\opengothic_win\Gothic2Notr.exe
0x00007ff7ed4e0d49: invoke_main in C:\Users\Daniel\Desktop\opengothic_win\Gothic2Notr.exe
0x00007ff7ed4e0bee: __scrt_common_main_seh in C:\Users\Daniel\Desktop\opengothic_win\Gothic2Notr.exe
0x00007ff7ed4e0aae: __scrt_common_main in C:\Users\Daniel\Desktop\opengothic_win\Gothic2Notr.exe
0x00007ff7ed4e0dde: mainCRTStartup in C:\Users\Daniel\Desktop\opengothic_win\Gothic2Notr.exe
0x00007ffedb8626ad: BaseThreadInitThunk in C:\WINDOWS\System32\KERNEL32.DLL
0x00007ffedcceaa78: RtlUserThreadStart in C:\WINDOWS\SYSTEM32\ntdll.dll

Attached Debugger: Unhandled exception at 0x00007FFF511F535C in Gothic2Notr.exe: Microsoft C++ exception: std::filesystem::filesystem_error at memory location 0x000000633E1F8770.

image

Look like it looks for a L"C:/Users/Daniel/Downloads/Ready_LayeredFS_Game/gothic/gothic/_work/Data/Scripts/_compiled/MENU.DAT" and yes, this one does not exist. But a L"C:/Users/Daniel/Downloads/Ready_LayeredFS_Game/gothic/gothic/_work/Data/Scripts_DE/_compiled/MENU.DAT" indeed does. Same goes for all the other language representations. If you just copy those files from the language folder to the generic one...

image

Here the controller menu: image

Ingame: image

OpenGothic v1.0 dev
no *.ini file in path - using default settings
GPU = NVIDIA GeForce RTX 2080
Depth format = Depth32F Shadow format = Depth16
unable to load sound: "menu.sgt"
not implemented call [PERC_SETRANGE]
[phoenix] world: parsing object [MeshAndBsp % 0 0]
[phoenix] bsp_tree: parsing chunk c000
[phoenix] bsp_tree: parsing chunk c010
[phoenix] bsp_tree: parsing chunk c040
[phoenix] bsp_tree: parsing chunk c045
[phoenix] bsp_tree: parsing chunk c050
[phoenix] bsp_tree: parsing chunk c0ff
[phoenix] world: parsing object [VobTree % 0 0]
[phoenix] world: parsing object [WayNet % 0 0]
[phoenix] world: parsing object [EndMarker % 0 0]
[phoenix] model_script: detected invalid use of keyword aniin "Model" block. Ignoring rest of script.
unable to load sound fx: WOOD_NIGHT2
[phoenix] model script: syntax error (line 3188, column 2): comments must start with two slashes
comb not found: t_FIREPLACE_Stand_2_S0 -> c_FP_STAND_2_S0_(c_FP_STAND_2_S0_2)
comb not found: t_FIREPLACE_S0_2_Stand -> c_FP_STAND_2_S0_(c_FP_STAND_2_S0_2)
alias not found: t_Walk_2_WalkBL -> t_walkL_2_Walk
alias not found: t_SwimF_2_Dive -> t_swim_2_dive
alias not found: t_SwimF_2_Dive -> t_swim_2_dive
addNpc: invalid waypoint
[phoenix] model script: syntax error (line 162, column 56): string not terminated
alias not found: r_Roam1 -> r_Scratch
alias not found: t_FallenB_2_Stand -> t_Fallen_2_Stand  
[phoenix] model_script: detected invalid use of keyword *eventSFXin "Model" block. Ignoring rest of script.
alias not found: t_FistWalkBL_2_FistWalk -> t_FistWalk_2_FistWalkL
[phoenix] model script: syntax error (line 3188, column 2): comments must start with two slashes
comb not found: t_FIREPLACE_Stand_2_S0 -> c_FP_STAND_2_S0_(c_FP_STAND_2_S0_2)
comb not found: t_FIREPLACE_S0_2_Stand -> c_FP_STAND_2_S0_(c_FP_STAND_2_S0_2)
alias not found: t_Walk_2_WalkBL -> t_walkL_2_Walk
[phoenix] model script: syntax error (line 55, column 104): string not terminated
[phoenix] model script: syntax error (line 55, column 117): string not terminated
[phoenix] model_script: detected invalid use of keyword aniAliasin "Model" block. Ignoring rest of script.
[phoenix] model script: syntax error (line 138, column 55): string not terminated
comb not found: t_FIREPLACE_Stand_2_S0 -> c_FP_STAND_2_S0_(c_FP_STAND_2_S0_2)
comb not found: t_FIREPLACE_S0_2_Stand -> c_FP_STAND_2_S0_(c_FP_STAND_2_S0_2)
room not found: NLHU03
room not found: NLHU05
room not found: NLHU06
room not found: NLHU09
room not found: NLHU08
room not found: NLHU07
room not found: NLHU04
room not found: NLHU02
room not found: NLHU01
not implemented call [WLD_SETOBJECTROUTINE]
room not found: H TTE5
room not found: H TTE34
[phoenix] vm: accessing member "C_NPC.ID" without an instance set
[phoenix] vm: accessing member "C_NPC.NAME" without an instance set
room not found: NLHU03
room not found: NLHU05
room not found: NLHU06
room not found: NLHU09
room not found: NLHU08
room not found: NLHU07
room not found: NLHU04
room not found: NLHU02
room not found: NLHU01
room not found: H TTE5
room not found: H TTE34
unable to play video: "INTRO.BIK"
[phoenix] vm: accessing member "C_NPC.NAME" without an instance set
[phoenix] vm: accessing member "C_NPC.GUILD" without an instance set
[phoenix] vm: accessing member "C_NPC.GUILD" without an instance set
[phoenix] vm: accessing member "C_NPC.AIVAR" without an instance set
[phoenix] vm: accessing member "C_NPC.NAME" without an instance set
[phoenix] vm: accessing member "C_NPC.GUILD" without an instance set
[phoenix] vm: accessing member "C_NPC.AIVAR" without an instance set
not implemented call [mdl_applyrandomani]
not implemented call [mdl_applyrandomanifreq]
unable to load sound: "ban_day_std.sgt"
not implemented call [NPC_SETKNOWSPLAYER]
not implemented call [NPC_GETNEXTWP]
unable to load sound: "ow_day_std.sgt"
exception in trigger-script: Cannot call function: not found
exception in trigger-script: Cannot call function: not found
unable to load sound: "oc_day_std.sgt"
not implemented call [NPC_HASNEWS]

Saving does not work and background music or voices don't work, too. Ah and no intro movie. Looks like the engine does some tinkering here as for example the music is there as you can see on file list, still the Log claims it to be not there. Same for the Intro.bik it looks for. The game has no bik files anymore on Switch.

All in all, I am very happy and quite surprised to see this stuff working at least almost as expected. Great work!

dreimer1986 commented 11 months ago

Addendum: If @Try or @lmichaelis are interested in these dumped files, I could hand them over in some private way for research. I just don't want to spread them in public.

lmichaelis commented 11 months ago

Wow, that's pretty cool! It looks like there are some minor differences in the model scripts and VM but all in all phoenix seems to handle it pretty well. I would be interested in those files to check the differences to GOG/Steam/retail releases but as long as there are no problems with phoenix this is very low priority. If there is an issue just open an issue :)

Try commented 11 months ago

Nicely done @dreimer1986 ! :)

I got the Gothic Classic Cart from THQ Store and dumped it with nxdumper. Then I converted it to ROMFS and that one I just extracted then.

Can you correct me, if I misunderstood somethings: you took game-files from Switch, and let them run on PC with OpenGothic? Or you can run(or at least launch) OpenGothic on Switch as well?

C:/Users/Daniel/Downloads/Ready_LayeredFS_Game/gothic/gothic/_work/Data/Scripts/_compiled/MENU.DAT C:/Users/Daniel/Downloads/Ready_LayeredFS_Game/gothic/gothic/_work/Data/Scripts_DE/_compiled/MENU.DAT

Hm, this could be due to OpenGothic ignores System/Paths.d file. This is just a plain text, - can you post it content here?

dreimer1986 commented 11 months ago

You got things right, this is the extracted Switch cart of Gothic Classic. The game files were then fed to OpenGothic on PC to see what it does with them. And after a few file moving arounds it starts to do nice things with them ^^

This one to be absolutely precise: https://eu.store.thqnordic.com/de/235/gothic-classic-switch?c=20

Here is the paths.d file:

/////////////////////////////////////////////////////////////////
// GOTHIC (c) 2000 Piranha Bytes GmbH
//
// PATHS.D
//
// Definition of directories, where gothic could find all
// necessary files. The location of this file is the
// directory where the Executable can be found.
//
/////////////////////////////////////////////////////////////////

// the root-directory 
// describes relatively to the home-directory of this file
// where the root of the gothis-directory-structure is
//

CONST STRING DIR_ROOT               = "..";

// The following directories can now be declared reletivly 
// to the root-path of gothic:

// Systemdateien: EXEs sowie DLLs und alles was im gleichen Verz. wie das EXE liegen muß
CONST STRING DIR_SYSTEM             = "\system\";

// SAVEGAMES
CONST STRING DIR_SAVEGAMES          = "\saves\";

// Informationen im HTML-Format und Links
CONST STRING DIR_WEB                = "\web\";

// The data-directory contains all gothic-data
CONST STRING DIR_DATA               = "\_work\data\";

//
// The following path descrive various sub-directories
// of the data-directory. The Macro $DATA$ stand for the
// data-path set above.
//

CONST STRING DIR_ANIMS          = "$DATA$\anims\";
CONST STRING DIR_MESHES         = "$DATA$\meshes\";
CONST STRING DIR_SCRIPTS        = "$DATA$\scripts\";
CONST STRING DIR_TEX            = "$DATA$\textures\";
CONST STRING DIR_CUTSCENES      = "$DATA$\cutscenes\";
CONST STRING DIR_SOUND          = "$DATA$\sound\";
CONST STRING DIR_MUSIC          = "$DATA$\music\";  
CONST STRING DIR_VIDEO          = "$DATA$\video\";  
CONST STRING DIR_WORLD          = "$DATA$\worlds\";
CONST STRING DIR_FONTS          = "$DATA$\fonts\";
const string DIR_OUTPUTUNITS    = "$DATA$\scripts\content\cutscene\";           

CONST STRING DIR_COMPILED_ANIMS     = "$DATA$\anims\_compiled\";
CONST STRING DIR_COMPILED_MESHES    = "$DATA$\meshes\_compiled\";
CONST STRING DIR_COMPILED_SCRIPTS   = "$DATA$\scripts\_compiled\";
CONST STRING DIR_COMPILED_TEXTURES  = "$DATA$\textures\_compiled\";

// ToDo Ulf: Desktop-GFX auch als Compiled-Format benutzen?
// Dann ist diese Angabe wahrscheinlich auch nicht mehr nötig
CONST STRING DIR_TEX_DESKTOP        = "$DATA$\textures\desktop\";

// other paths during work-cycle
CONST STRING DIR_PRESETS        = "\$DATA$\presets\";
CONST STRING DIR_TOOLS_CONFIG       = "\_work\tools\";
CONST STRING DIR_TOOLS_DATA     = "\_work\tools\data\";

// Sub-directories. 
// The follwing paths describe sub-directories. It's used in various directories.
CONST STRING SUBDIR_INTERN          = "_intern\";
Try commented 11 months ago

New .ini options, introduced by THQ: GAME/language - text language GAME/voice - voice language

Meanwhile I don't see anything in scripts to map GAME/language(int) to folder name. Maybe it's a builtin in executable...

dreimer1986 commented 11 months ago

I confirm that now it starts without any need for copying script files if the new config values are added to the ini. In my case =1 in both cases. Text is german, settings menu tells us we are 2x in german mode for game and voice. Speech is not yet working and neither do the completely deplaced and converted videos. Otherwise it looks quite identical to Steam GI (as expected^^)

OpenGothic v1.0 dev
no *.ini file in path - using default settings
GPU = NVIDIA GeForce RTX 2080
Depth format = Depth32F Shadow format = Depth16
not implemented call [PERC_SETRANGE]
[phoenix] world: parsing object [MeshAndBsp % 0 0]
[phoenix] bsp_tree: parsing chunk c000
[phoenix] bsp_tree: parsing chunk c010
[phoenix] bsp_tree: parsing chunk c040
[phoenix] bsp_tree: parsing chunk c045
[phoenix] bsp_tree: parsing chunk c050
[phoenix] bsp_tree: parsing chunk c0ff
[phoenix] world: parsing object [VobTree % 0 0]
[phoenix] world: parsing object [WayNet % 0 0]
[phoenix] world: parsing object [EndMarker % 0 0]
[phoenix] model_script: detected invalid use of keyword aniin "Model" block. Ignoring rest of script.
unable to load sound fx: WOOD_NIGHT2
none of Zen-files for OU could be loaded
[phoenix] model script: syntax error (line 3188, column 2): comments must start with two slashes
comb not found: t_FIREPLACE_Stand_2_S0 -> c_FP_STAND_2_S0_(c_FP_STAND_2_S0_2)
comb not found: t_FIREPLACE_S0_2_Stand -> c_FP_STAND_2_S0_(c_FP_STAND_2_S0_2)
alias not found: t_Walk_2_WalkBL -> t_walkL_2_Walk
alias not found: t_SwimF_2_Dive -> t_swim_2_dive
alias not found: t_SwimF_2_Dive -> t_swim_2_dive
addNpc: invalid waypoint
[phoenix] model script: syntax error (line 162, column 56): string not terminated
alias not found: r_Roam1 -> r_Scratch
alias not found: t_FallenB_2_Stand -> t_Fallen_2_Stand  
[phoenix] model_script: detected invalid use of keyword *eventSFXin "Model" block. Ignoring rest of script.
alias not found: t_FistWalkBL_2_FistWalk -> t_FistWalk_2_FistWalkL
[phoenix] model script: syntax error (line 3188, column 2): comments must start with two slashes
comb not found: t_FIREPLACE_Stand_2_S0 -> c_FP_STAND_2_S0_(c_FP_STAND_2_S0_2)
comb not found: t_FIREPLACE_S0_2_Stand -> c_FP_STAND_2_S0_(c_FP_STAND_2_S0_2)
alias not found: t_Walk_2_WalkBL -> t_walkL_2_Walk
[phoenix] model script: syntax error (line 55, column 104): string not terminated
[phoenix] model script: syntax error (line 55, column 117): string not terminated
[phoenix] model_script: detected invalid use of keyword aniAliasin "Model" block. Ignoring rest of script.
[phoenix] model script: syntax error (line 138, column 55): string not terminated
comb not found: t_FIREPLACE_Stand_2_S0 -> c_FP_STAND_2_S0_(c_FP_STAND_2_S0_2)
comb not found: t_FIREPLACE_S0_2_Stand -> c_FP_STAND_2_S0_(c_FP_STAND_2_S0_2)
room not found: NLHU03
room not found: NLHU05
room not found: NLHU06
room not found: NLHU09
room not found: NLHU08
room not found: NLHU07
room not found: NLHU04
room not found: NLHU02
room not found: NLHU01
not implemented call [WLD_SETOBJECTROUTINE]
room not found: H TTE5
room not found: H TTE34
[phoenix] vm: accessing member "C_NPC.ID" without an instance set
[phoenix] vm: accessing member "C_NPC.NAME" without an instance set
room not found: NLHU03
room not found: NLHU05
room not found: NLHU06
room not found: NLHU09
room not found: NLHU08
room not found: NLHU07
room not found: NLHU04
room not found: NLHU02
room not found: NLHU01
room not found: H TTE5
room not found: H TTE34
unable to play video: "INTRO.BIK"
[phoenix] vm: accessing member "C_NPC.NAME" without an instance set
[phoenix] vm: accessing member "C_NPC.GUILD" without an instance set
[phoenix] vm: accessing member "C_NPC.GUILD" without an instance set
[phoenix] vm: accessing member "C_NPC.AIVAR" without an instance set
[phoenix] vm: accessing member "C_NPC.NAME" without an instance set
[phoenix] vm: accessing member "C_NPC.GUILD" without an instance set
[phoenix] vm: accessing member "C_NPC.AIVAR" without an instance set
not implemented call [mdl_applyrandomani]
not implemented call [mdl_applyrandomanifreq]
not implemented call [NPC_SETKNOWSPLAYER]
not implemented call [NPC_GETNEXTWP]

EDIT: Load Menu works fine and shows the saves I made with normal Gothic I and II (it even tries to load them just to fail badly), Save menu does not show anything and does not work, too. But this one is modified for Switch. Normally it should add a timestamp there if you select it on Switch and save under that timestamp.

dreimer1986 commented 9 months ago

Look, what the Deutsche Post delivered these days:

Screenshot 2023-12-02 162853 Screenshot 2023-12-02 162930 PXL_20231202_152551282

Yes, works as fine as the GI Switch version. Fine means, that there is no speech at all and all the talking is skipped ultra fast. Videos don't work as there are no Bink videos anymore and they are in another folder. Of course no Exit Button in Menu as this is a Console Port (Thus NO Bug in OpenGothic) and the save menu is not really working.

P.S. I managed to finally find out why I wasn't able to dump the Update NSP files off my Switch... Host OS Version was too new for NXDumper. Now it works fine and these pics are from the GII 1.0.1 patch applied. I did the same to GI and there it's 1.0.2 by now. Will send these new files off to @Try and @lmichaelis as soon as they are uploaded

OpenGothic v1.0 dev
GPU = NVIDIA GeForce RTX 2080
Depth format = Depth32F Shadow format = Depth16
unable to load sound: "gamestart.sgt"
not implemented call [PERC_SETRANGE]
[phoenix] world: parsing object [MeshAndBsp % 0 0]
[phoenix] bsp_tree: parsing chunk c000
[phoenix] bsp_tree: parsing chunk c010
[phoenix] bsp_tree: parsing chunk c040
[phoenix] bsp_tree: parsing chunk c045
[phoenix] bsp_tree: parsing chunk c050
[phoenix] bsp_tree: parsing chunk c0ff
[phoenix] mesh: 1 bytes remaining in section b020
[phoenix] world: parsing object [VobTree % 0 0]
[phoenix] world: parsing object [WayNet % 0 0]
[phoenix] world: parsing object [EndMarker % 0 0]
invalid particle system: "INVISIBLE_VOBBOX.3DS"
unable to load sound fx: ENV_NIGHT_TONSOFINSECTS
unable to load sound fx: OW_BIRD11
none of Zen-files for OU could be loaded
[phoenix] model_script: unexpected value for event_tag_type: "      "
[phoenix] model_script: 4 bytes remaining in section f5a3
unable to play video: "INTRO.BIK"
unable to play video: "Addon_Title.BIK"
[phoenix] vm: accessing member "C_NPC.AIVAR" without an instance set
[phoenix] vm: accessing member "C_NPC.AIVAR" without an instance set
[phoenix] vm: accessing member "C_NPC.AIVAR" without an instance set
unable to play video: "Intro_ADDON"
Try commented 9 months ago

Thanks for the dumps @dreimer1986 !

Fine means, that there is no speech at all and all the talking is skipped ultra fast.

Haven't look into G2 yet, but in G1 there was something fishy about .wav files - there was no wave-file header (and content doesn't look like a wav)