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 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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 //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.
+
+
+