From 5f0614d75116493a51e95f68ad02ab690f7c1255 Mon Sep 17 00:00:00 2001 From: Pavel <68122101+red-prig@users.noreply.github.com> Date: Mon, 19 Dec 2022 17:14:39 +0300 Subject: [PATCH] playgo_info --- tools/playgo/playgo_info.lpi | 69 +++++ tools/playgo/playgo_info.lpr | 474 +++++++++++++++++++++++++++++++++++ 2 files changed, 543 insertions(+) create mode 100644 tools/playgo/playgo_info.lpi create mode 100644 tools/playgo/playgo_info.lpr diff --git a/tools/playgo/playgo_info.lpi b/tools/playgo/playgo_info.lpi new file mode 100644 index 0000000..66046a4 --- /dev/null +++ b/tools/playgo/playgo_info.lpi @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + <UseAppBundle Value="False"/> + <ResourceType Value="res"/> + </General> + <BuildModes Count="1"> + <Item1 Name="Default" Default="True"/> + </BuildModes> + <PublishOptions> + <Version Value="2"/> + <UseFileFilters Value="True"/> + </PublishOptions> + <RunParams> + <FormatVersion Value="2"/> + </RunParams> + <Units Count="1"> + <Unit0> + <Filename Value="playgo_info.lpr"/> + <IsPartOfProject Value="True"/> + </Unit0> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="playgo_info"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <CodeGeneration> + <SmartLinkUnit Value="True"/> + </CodeGeneration> + <Linking> + <Debugging> + <DebugInfoType Value="dsDwarf2"/> + </Debugging> + </Linking> + </CompilerOptions> + <Debugging> + <Exceptions Count="3"> + <Item1> + <Name Value="EAbort"/> + </Item1> + <Item2> + <Name Value="ECodetoolError"/> + </Item2> + <Item3> + <Name Value="EFOpenError"/> + </Item3> + </Exceptions> + </Debugging> +</CONFIG> diff --git a/tools/playgo/playgo_info.lpr b/tools/playgo/playgo_info.lpr new file mode 100644 index 0000000..8bf9399 --- /dev/null +++ b/tools/playgo/playgo_info.lpr @@ -0,0 +1,474 @@ + +uses + {$IFDEF Linux} + cmem, + cthreads, + {$ENDIF} + Classes, + sysutils; + +const + PLAYGO_CONTENT_ID_SIZE=$30; + + PLAYGO_MAX_IMAGES =2; + PLAYGO_MAX_DISCS =2; + PLAYGO_MAX_LAYERS_FOR_DISC1=2; + PLAYGO_MAX_LAYERS_FOR_DISC2=1; + PLAYGO_MAX_CHUNKS =1000; + PLAYGO_MAX_MCHUNKS =8000; + PLAYGO_MAX_SCENARIOS =32; + PLAYGO_MAX_LANGUAGES =64; + + PLAYGO_SCENARIO_TYPE_SP=1; + PLAYGO_SCENARIO_TYPE_MP=2; + + PLAYGO_SCENARIO_TYPE_USER_00=(16+1); + + PLAYGO_ALL_LANGUAGES_MASK:QWORD=$FFFFFFFFFFFFFFFF; + + PLAYGO_LANG_JAPANESE = 0; + PLAYGO_LANG_ENGLISH_US = 1; + PLAYGO_LANG_FRENCH = 2; + PLAYGO_LANG_SPANISH = 3; + PLAYGO_LANG_GERMAN = 4; + PLAYGO_LANG_ITALIAN = 5; + PLAYGO_LANG_DUTCH = 6; + PLAYGO_LANG_PORTUGUESE_PT = 7; + PLAYGO_LANG_RUSSIAN = 8; + PLAYGO_LANG_KOREAN = 9; + PLAYGO_LANG_CHINESE_TRADITIONAL = 10; + PLAYGO_LANG_CHINESE_SIMPLIFIED = 11; + PLAYGO_LANG_FINNISH = 12; + PLAYGO_LANG_SWEDISH = 13; + PLAYGO_LANG_DANISH = 14; + PLAYGO_LANG_NORWEGIAN = 15; + PLAYGO_LANG_POLISH = 16; + PLAYGO_LANG_PORTUGUESE_BR = 17; + PLAYGO_LANG_ENGLISH_UK = 18; + PLAYGO_LANG_TURKISH = 19; + PLAYGO_LANG_SPANISH_LA = 20; + PLAYGO_LANG_ARABIC = 21; + PLAYGO_LANG_FRENCH_CA = 22; + + PLAYGO_LANG_USER_00 = 48; + PLAYGO_LANG_USER_01 = 49; + PLAYGO_LANG_USER_02 = 50; + PLAYGO_LANG_USER_03 = 51; + PLAYGO_LANG_USER_04 = 52; + PLAYGO_LANG_USER_05 = 53; + PLAYGO_LANG_USER_06 = 54; + PLAYGO_LANG_USER_07 = 55; + PLAYGO_LANG_USER_08 = 56; + PLAYGO_LANG_USER_09 = 57; + PLAYGO_LANG_USER_10 = 58; + PLAYGO_LANG_USER_11 = 59; + PLAYGO_LANG_USER_12 = 60; + PLAYGO_LANG_USER_13 = 61; + PLAYGO_LANG_USER_14 = 62; + + PLAYGO_LOCUS_NOT_DOWNLOADED = 0; + PLAYGO_LOCUS_LOCAL_SLOW = 2; + PLAYGO_LOCUS_LOCAL_FAST = 3; + + PLAYGO_INSTALL_SPEED_SUSPENDED = 0; + PLAYGO_INSTALL_SPEED_TRICKLE = 1; + PLAYGO_INSTALL_SPEED_FULL = 2; + + PLAYGO_MAGIC=$6F676C70; + + PLAYGO_HEADER_SIZE=$100; + PLAYGO_SCENARIO_ATTRIBUTE_ENTRY_SIZE=$20; + PLAYGO_CHUNK_ATTRIBUTE_ENTRY_SIZE =$20; + PLAYGO_MCHUNK_ATTRIBUTE_ENTRY_SIZE =$10; + +type + t_playgo_lang_desc=packed record + code:DWORD; + name:PChar; + iso1:PChar; + iso2:PChar; + end; + + p_playgo_scenario_attr_desc=^t_playgo_scenario_attr_desc; + t_playgo_scenario_attr_desc=packed record + _type :DWORD; + initial_chunk_count:DWORD; + chunk_count :DWORD; + _label:PChar; + chunks:PWord; + end; + + p_playgo_chunk_attr_desc=^t_playgo_chunk_attr_desc; + t_playgo_chunk_attr_desc=packed record + flag :DWORD; + disc_no :DWORD; + layer_no :DWORD; + image_no :DWORD; + req_locus :DWORD; + mchunk_count:DWORD; + language_mask:QWORD; + _label:PChar; + mchunks:PWord; + end; + + p_playgo_mchunk_attr_desc=^t_playgo_mchunk_attr_desc; + t_playgo_mchunk_attr_desc=packed record + offset:QWORD; + size:QWORD; + image_no:DWORD; + end; + + t_playgo=packed record + version_major:Word; + version_minor:Word; + + file_size:DWORD; + + sdk_version:DWORD; + attrib :WORD; + + image_count :WORD; + chunk_count :WORD; + mchunk_count :WORD; + scenario_count:WORD; + disc_count :WORD; + + layer_bmp :WORD; + default_scenario_id:WORD; + + content_id:array[0..PLAYGO_CONTENT_ID_SIZE] of AnsiChar; + + scenario_attrs :p_playgo_scenario_attr_desc; + chunk_attrs :p_playgo_chunk_attr_desc; + mchunk_attrs :p_playgo_mchunk_attr_desc; + inner_mchunk_attrs:p_playgo_mchunk_attr_desc; + end; + + bits4 =0..((1 shl 4)-1); + bits48=0..((1 shl 48)-1); + + t_playgo_chunk_loc=packed record + Case Byte of + 0:(bits:bitpacked record + offset:bits48; + _align1:Byte; + image_no:bits4; + _align2:bits4; + end); + 1:(raw:QWORD); + end; + + t_playgo_chunk_size=packed record + Case Byte of + 0:(bits:bitpacked record + size:bits48; + _align:Word; + end); + 1:(raw:QWORD); + end; + + t_chunk=packed record + offset:DWORD; + size :DWORD; + end; + + t_playgo_header=packed record + magic:DWORD; + + version_major :Word; + version_minor :Word; + image_count :Word; // [0;1] + chunk_count :Word; // [0;1000] + mchunk_count :Word; // [0;8000] + scenario_count:Word; // [0;32] + + file_size :DWORD; + default_scenario_id:Word; + attrib :Word; + sdk_version:DWORD; + disc_count :Word; // [0;2] (if equals to 0 then disc count = 1) + layer_bmp :Word; + + reserved:array[0..31] of Byte; + + content_id:array[0..127] of AnsiChar; + + // chunk attributes + chunk_attrs:t_chunk; // [0;32000] + + // chunk mchunks + chunk_mchunks:t_chunk; + + // chunk labels + chunk_labels:t_chunk; // [0;16000] + + // mchunk attributes + mchunk_attrs:t_chunk; // [0;12800] + + // scenario attributes + scenario_attrs:t_chunk; // [0;1024] + + // scenarios chunks + scenario_chunks:t_chunk; + + // scenario labels + scenario_labels:t_chunk; + + // inner mchunk attributes + inner_mchunk_attrs:t_chunk; // [0;12800] + end; + + p_playgo_scenario_attr_entry=^t_playgo_scenario_attr_entry; + t_playgo_scenario_attr_entry=packed record + _type:Byte; + _unk:array[0..18] of Byte; + initial_chunk_count:WORD; + chunk_count :WORD; + chunks_offset:DWORD; + label_offset :DWORD; + end; + + p_playgo_chunk_attr_entry=^t_playgo_chunk_attr_entry; + t_playgo_chunk_attr_entry=packed record + flag:Byte; + image_disc_layer_no:Byte; + req_locus:Byte; + unk:array[0..10] of Char; + mchunk_count:Word; + language_mask:QWORD; + mchunks_offset:DWORD; + label_offset:DWORD; + end; + + p_playgo_mchunk_attr_entry=^t_playgo_mchunk_attr_entry; + t_playgo_mchunk_attr_entry=packed record + loc:t_playgo_chunk_loc; + size:t_playgo_chunk_size; + end; + +const + s_languages:array[0..37] of t_playgo_lang_desc=( + (code:PLAYGO_LANG_JAPANESE ;name:'Japanese' ;iso1:'ja' ;iso2:nil), + (code:PLAYGO_LANG_ENGLISH_US ;name:'English' ;iso1:'en-US' ;iso2:'en'), + (code:PLAYGO_LANG_FRENCH ;name:'French' ;iso1:'fr' ;iso2:nil), + (code:PLAYGO_LANG_SPANISH ;name:'Spanish' ;iso1:'es-ES' ;iso2:'es'), + (code:PLAYGO_LANG_GERMAN ;name:'German' ;iso1:'de' ;iso2:nil), + (code:PLAYGO_LANG_ITALIAN ;name:'Italian' ;iso1:'it' ;iso2:nil), + (code:PLAYGO_LANG_DUTCH ;name:'Dutch' ;iso1:'nl' ;iso2:nil), + (code:PLAYGO_LANG_PORTUGUESE_PT ;name:'Portuguese' ;iso1:'pt-PT' ;iso2:'pt'), + (code:PLAYGO_LANG_RUSSIAN ;name:'Russian' ;iso1:'ru' ;iso2:nil), + (code:PLAYGO_LANG_KOREAN ;name:'Korean' ;iso1:'ko' ;iso2:nil), + (code:PLAYGO_LANG_CHINESE_TRADITIONAL;name:'Trad.Chinese' ;iso1:'zh-Hant';iso2:nil), + (code:PLAYGO_LANG_CHINESE_SIMPLIFIED ;name:'Simp.Chinese' ;iso1:'zh-Hans';iso2:nil), + (code:PLAYGO_LANG_FINNISH ;name:'Finnish' ;iso1:'fi' ;iso2:nil), + (code:PLAYGO_LANG_SWEDISH ;name:'Swedish' ;iso1:'sv' ;iso2:nil), + (code:PLAYGO_LANG_DANISH ;name:'Danish' ;iso1:'da' ;iso2:nil), + (code:PLAYGO_LANG_NORWEGIAN ;name:'Norwegian' ;iso1:'no' ;iso2:nil), + (code:PLAYGO_LANG_POLISH ;name:'Polish' ;iso1:'pl' ;iso2:nil), + (code:PLAYGO_LANG_PORTUGUESE_BR ;name:'Braz.Portuguese' ;iso1:'pt-BR' ;iso2:nil), + (code:PLAYGO_LANG_ENGLISH_UK ;name:'UK English' ;iso1:'en-GB' ;iso2:nil), + (code:PLAYGO_LANG_TURKISH ;name:'Turkish' ;iso1:'tr' ;iso2:nil), + (code:PLAYGO_LANG_SPANISH_LA ;name:'Latin American Spanish' ;iso1:'es-LA' ;iso2:nil), + (code:PLAYGO_LANG_ARABIC ;name:'Arabic' ;iso1:'ar' ;iso2:nil), + (code:PLAYGO_LANG_FRENCH_CA ;name:'Canadian French' ;iso1:'fr-CA' ;iso2:nil), + + (code:PLAYGO_LANG_USER_00 ;name:'User-defined Language #0' ;iso1:'user00' ;iso2:nil), + (code:PLAYGO_LANG_USER_01 ;name:'User-defined Language #1' ;iso1:'user01' ;iso2:nil), + (code:PLAYGO_LANG_USER_02 ;name:'User-defined Language #2' ;iso1:'user02' ;iso2:nil), + (code:PLAYGO_LANG_USER_03 ;name:'User-defined Language #3' ;iso1:'user03' ;iso2:nil), + (code:PLAYGO_LANG_USER_04 ;name:'User-defined Language #4' ;iso1:'user04' ;iso2:nil), + (code:PLAYGO_LANG_USER_05 ;name:'User-defined Language #5' ;iso1:'user05' ;iso2:nil), + (code:PLAYGO_LANG_USER_06 ;name:'User-defined Language #6' ;iso1:'user06' ;iso2:nil), + (code:PLAYGO_LANG_USER_07 ;name:'User-defined Language #7' ;iso1:'user07' ;iso2:nil), + (code:PLAYGO_LANG_USER_08 ;name:'User-defined Language #8' ;iso1:'user08' ;iso2:nil), + (code:PLAYGO_LANG_USER_09 ;name:'User-defined Language #9' ;iso1:'user09' ;iso2:nil), + (code:PLAYGO_LANG_USER_10 ;name:'User-defined Language #10';iso1:'user10' ;iso2:nil), + (code:PLAYGO_LANG_USER_11 ;name:'User-defined Language #11';iso1:'user11' ;iso2:nil), + (code:PLAYGO_LANG_USER_12 ;name:'User-defined Language #12';iso1:'user12' ;iso2:nil), + (code:PLAYGO_LANG_USER_13 ;name:'User-defined Language #13';iso1:'user13' ;iso2:nil), + (code:PLAYGO_LANG_USER_14 ;name:'User-defined Language #14';iso1:'user14' ;iso2:nil) + ); + +function get_str_t_chunk(t:t_chunk):RawByteString; +begin + Result:='offset:0x'+HexStr(t.offset,8)+' size:0x'+HexStr(t.size,8); +end; + +function get_str_scenario_type(_type:Byte):RawByteString; +begin + Case _type of + PLAYGO_SCENARIO_TYPE_SP:Result:='sp'; + PLAYGO_SCENARIO_TYPE_MP:Result:='mp'; + PLAYGO_SCENARIO_TYPE_USER_00..$FF: + begin + Result:='User-defined Scenario #'+IntTostr(_type-PLAYGO_SCENARIO_TYPE_USER_00+1); + end; + else + Result:=IntToStr(_type); + end; +end; + +function LoadPlaygoFile(Const name:RawByteString):Boolean; +Var + F:THandle; + + i,count:DWORD; + + hdr:t_playgo_header; + + scenario_attrs:p_playgo_scenario_attr_entry; + scenario_chunks:PWord; + scenario_labels:PChar; + + chunk_attrs:p_playgo_chunk_attr_entry; + chunk_mchunks:PWord; + chunk_labels:PChar; + + mchunk_attrs:p_playgo_mchunk_attr_entry; + inner_mchunk_attrs:p_playgo_mchunk_attr_entry; + + function load_chunk(t:t_chunk):Pointer; + begin + Result:=AllocMem(t.size); + FileSeek(F,t.offset,fsFromBeginning); + FileRead(F,Result^,t.size); + end; + +begin + Result:=False; + if (name='') then Exit; + F:=FileOpen(name,fmOpenRead or fmShareDenyNone); + + if (F=feInvalidHandle) then + begin + Writeln('Error open file:',name); + Exit; + end; + + hdr:=Default(t_playgo_header); + + FileRead(F,hdr,SizeOf(hdr)); + + Writeln('magic :0x',HexStr(hdr.magic,8)); + + if (hdr.magic<>PLAYGO_MAGIC) then + begin + Writeln('Invalid playgo file:',name); + FileClose(F); + Exit; + end; + + Writeln('version :0x',HexStr((hdr.version_major),4),'.0x',HexStr(hdr.version_minor,4)); + Writeln('image_count :',hdr.image_count ); + Writeln('chunk_count :',hdr.chunk_count ); + Writeln('mchunk_count :',hdr.mchunk_count ); + Writeln('scenario_count :',hdr.scenario_count ); + Writeln('file_size :',hdr.file_size ); + Writeln('default_scenario_id :',hdr.default_scenario_id ); + Writeln('attrib :',hdr.attrib ); + Writeln('sdk_version :0x',HexStr(hdr.sdk_version,8) ); + Writeln('disc_count :',hdr.disc_count ); + Writeln('layer_bmp :',hdr.layer_bmp ); + Writeln('content_id :',hdr.content_id ); + Writeln('chunk_attrs :',get_str_t_chunk(hdr.chunk_attrs )); + Writeln('chunk_mchunks :',get_str_t_chunk(hdr.chunk_mchunks )); + Writeln('chunk_labels :',get_str_t_chunk(hdr.chunk_labels )); + Writeln('mchunk_attrs :',get_str_t_chunk(hdr.mchunk_attrs )); + Writeln('scenario_attrs :',get_str_t_chunk(hdr.scenario_attrs )); + Writeln('scenario_chunks :',get_str_t_chunk(hdr.scenario_chunks )); + Writeln('scenario_labels :',get_str_t_chunk(hdr.scenario_labels )); + Writeln('inner_mchunk_attrs :',get_str_t_chunk(hdr.inner_mchunk_attrs)); + + scenario_attrs :=load_chunk(hdr.scenario_attrs); + scenario_chunks :=load_chunk(hdr.scenario_chunks); + scenario_labels :=load_chunk(hdr.scenario_labels); + chunk_attrs :=load_chunk(hdr.chunk_attrs);; + chunk_mchunks :=load_chunk(hdr.chunk_mchunks); + chunk_labels :=load_chunk(hdr.chunk_labels); + mchunk_attrs :=load_chunk(hdr.mchunk_attrs); + inner_mchunk_attrs:=load_chunk(hdr.inner_mchunk_attrs); + + // + + count:=hdr.scenario_attrs.size div SizeOf(t_playgo_scenario_attr_entry); + if (count<>0) then + begin + For i:=0 to count-1 do + begin + Writeln('[scenario_attrs]:',i); + Writeln(' type :',get_str_scenario_type(scenario_attrs[i]._type)); + Writeln(' initial_chunk_count:',scenario_attrs[i].initial_chunk_count); + Writeln(' chunk_count :',scenario_attrs[i].chunk_count ); + Writeln(' chunks_offset :',scenario_attrs[i].chunks_offset ); + Writeln(' label_offset :',scenario_attrs[i].label_offset ); + Writeln(' label :',PChar(scenario_labels+scenario_attrs[i].label_offset)) + end; + end; + + // + + count:=hdr.chunk_attrs.size div SizeOf(t_playgo_chunk_attr_entry); + if (count<>0) then + begin + For i:=0 to count-1 do + begin + Writeln('[chunk_attrs]:',i); + Writeln(' flag :',chunk_attrs[i].flag ); + Writeln(' image_no :',(chunk_attrs[i].image_disc_layer_no shl 4) and $F); + Writeln(' disc_no :',(chunk_attrs[i].image_disc_layer_no shl 2) and $3); + Writeln(' layer_no :',(chunk_attrs[i].image_disc_layer_no shl 0) and $3); + Writeln(' req_locus :',chunk_attrs[i].req_locus ); + Writeln(' mchunk_count :',chunk_attrs[i].mchunk_count ); + Writeln(' language_mask :0x',HexStr(chunk_attrs[i].language_mask,16)); + Writeln(' mchunks_offset :',chunk_attrs[i].mchunks_offset ); + Writeln(' label_offset :',chunk_attrs[i].label_offset ); + Writeln(' label :',PChar(chunk_labels+chunk_attrs[i].label_offset)) + end; + end; + + FileClose(F); +end; + +var + i,n:Integer; + +label + promo; + +begin + DefaultSystemCodePage:=CP_UTF8; + DefaultUnicodeCodePage:=CP_UTF8; + DefaultFileSystemCodePage:=CP_UTF8; + DefaultRTLFileSystemCodePage:=CP_UTF8; + UTF8CompareLocale:=CP_UTF8; + + if (ParamCount=0) then + begin + promo: + Writeln('Tool for print playgo data'); + Writeln(' Parameters:'); + Writeln(' -i <name> //file name to load playgo-chunk.dat'); + Exit; + end; + + n:=-1; + For i:=1 to ParamCount do + begin + case LowerCase(ParamStr(i)) of + '-i':n:=0; + else + if (n<>-1) then + begin + Case n of + 0:LoadPlaygoFile(ParamStr(i)); + end; + n:=-1; + end; + end; + end; + + writeln; +end. + + +