1 #include "moviefile.hpp"
8 std::string
name_romtype(rom_type r
)
10 if(r
== ROMTYPE_SNES
) return "SNES";
11 if(r
== ROMTYPE_BSX
) return "BS-X (non-slotted)";
12 if(r
== ROMTYPE_BSXSLOTTED
) return "BS-X (slotted)";
13 if(r
== ROMTYPE_SUFAMITURBO
) return "Sufami turbo";
14 if(r
== ROMTYPE_SGB
) return "SGB";
18 std::string
name_region(rom_region r
)
20 if(r
== REGION_PAL
) return "PAL";
21 if(r
== REGION_NTSC
) return "NTSC";
25 std::string
name_porttype(porttype_t r
)
27 if(r
== PT_NONE
) return "No device";
28 if(r
== PT_GAMEPAD
) return "Gamepad";
29 if(r
== PT_MULTITAP
) return "Multitap";
30 if(r
== PT_MOUSE
) return "Mouse";
31 if(r
== PT_SUPERSCOPE
) return "Super Scope";
32 if(r
== PT_JUSTIFIER
) return "Justifier";
33 if(r
== PT_JUSTIFIERS
) return "2 Justifiers";
37 std::string
escape_string(std::string x
)
39 std::ostringstream out
;
40 for(size_t i
= 0; i
< x
.length(); i
++)
41 if((x
[i
] < 0 || x
[i
] > 31) && x
[i
] != '\\')
44 unsigned char y
= static_cast<unsigned char>(x
[i
]);
45 out
<< "\\" << ('0' + static_cast<char>((y
>> 6) & 7))
46 << ('0' + static_cast<char>((y
>> 3) & 7))
47 << ('0' + static_cast<char>(y
& 7));
52 int main(int argc
, char** argv
)
55 std::cerr
<< "Syntax: " << argv
[0] << " <moviefile>" << std::endl
;
59 uint64_t starting_point
= 0;
60 struct moviefile
m(argv
[1]);
61 rom_type rtype
= gtype::toromtype(m
.gametype
);
62 rom_region reg
= gtype::toromregion(m
.gametype
);
63 std::cout
<< "Console: " << name_romtype(rtype
) << std::endl
;
64 std::cout
<< "Region: " << name_region(reg
) << std::endl
;
65 std::cout
<< "Port #1: " << name_porttype(m
.port1
) << std::endl
;
66 std::cout
<< "Port #2: " << name_porttype(m
.port1
) << std::endl
;
67 std::cout
<< "Used emulator core: " << escape_string(m
.coreversion
) << std::endl
;
69 std::cout
<< "Game name: " << escape_string(m
.gamename
) << std::endl
;
71 std::cout
<< "No game name available" << std::endl
;
72 std::cout
<< "Project ID: " << escape_string(m
.projectid
) << std::endl
;
73 if(m
.rom_sha256
!= "") {
74 std::cout
<< "ROM checksum: " << escape_string(m
.rom_sha256
) << std::endl
;
75 if(m
.romxml_sha256
!= "")
76 std::cout
<< "ROM XML checksum: " << escape_string(m
.romxml_sha256
) << std::endl
;
78 std::cout
<< "Using default settings for ROM" << std::endl
;
80 std::cout
<< "No main ROM present" << std::endl
;
81 if(m
.slota_sha256
!= "") {
82 std::cout
<< "BS/ST-A/DMG checksum: " << escape_string(m
.slota_sha256
) << std::endl
;
83 if(m
.slotaxml_sha256
!= "")
84 std::cout
<< "BS/ST-A/DMG XML checksum: " << escape_string(m
.slotaxml_sha256
)
87 std::cout
<< "Using default settings for BS/ST-A/DMG" << std::endl
;
89 std::cout
<< "No BS/ST-A/DMG present" << std::endl
;
90 if(m
.slotb_sha256
!= "") {
91 std::cout
<< "ST-B checksum: " << escape_string(m
.slotb_sha256
) << std::endl
;
92 if(m
.slotbxml_sha256
!= "")
93 std::cout
<< "ST-B XML checksum: " << escape_string(m
.slotbxml_sha256
)
96 std::cout
<< "Using default settings for BS/ST-A/DMG" << std::endl
;
98 std::cout
<< "No ST-B present" << std::endl
;
99 for(auto i
= m
.authors
.begin(); i
!= m
.authors
.end(); i
++) {
100 if(i
->first
!= "" && i
->second
!= "")
101 std::cout
<< "Author: " << escape_string(i
->first
) << " (" << escape_string(i
->second
)
103 else if(i
->first
!= "" && i
->second
== "")
104 std::cout
<< "Author: " << escape_string(i
->first
) << std::endl
;
105 else if(i
->first
== "" && i
->second
!= "")
106 std::cout
<< "Author: (" << escape_string(i
->second
) << ")" << std::endl
;
108 if(m
.authors
.size() == 0)
109 std::cout
<< "No author info available" << std::endl
;
111 std::cout
<< "Movie starts from savestate" << std::endl
;
112 for(auto i
= m
.movie_sram
.begin(); i
!= m
.movie_sram
.end(); i
++)
113 std::cout
<< "Start SRAM: " << escape_string(i
->first
) << ": [" << i
->second
.size()
114 << " bytes of binary data]" << std::endl
;
115 if(!m
.movie_sram
.size())
116 std::cout
<< "No starting SRAM" << std::endl
;
117 for(auto i
= m
.sram
.begin(); i
!= m
.sram
.end(); i
++)
118 std::cout
<< "Saved SRAM: " << escape_string(i
->first
) << ": [" << i
->second
.size()
119 << " bytes of binary data]" << std::endl
;
121 std::cout
<< "No saved SRAM" << std::endl
;
122 std::cout
<< "Savestate: [" << m
.savestate
.size() << " bytes of binary data]" << std::endl
;
123 std::cout
<< "Host memory: [" << m
.host_memory
.size() << " bytes of binary data]"
125 std::cout
<< "Screenshot: [" << m
.screenshot
.size() << " bytes of binary data]" << std::endl
;
126 if(m
.screenshot
.size() >= 4) {
127 uint16_t a
= static_cast<uint8_t>(m
.screenshot
[0]);
128 uint16_t b
= static_cast<uint8_t>(m
.screenshot
[1]);
129 std::cout
<< "Screenshot size: " << (a
* 256 + b
) << "*" << (m
.screenshot
.size() - 2)
130 / (a
* 256 + b
) / 2 << std::endl
;
132 std::cout
<< "Screenshot is corrupt" << std::endl
;
133 std::cout
<< "Movie state: [" << m
.movie_state
.size() << " bytes of binary data]" << std::endl
;
134 if(m
.movie_state
.size() == 512) {
136 for(unsigned i
= 32; i
< 40; i
++)
137 x
= 256 * x
+ static_cast<uint64_t>(static_cast<uint8_t>(m
.movie_state
[i
]));
139 std::cout
<< "Starting frame: " << x
<< std::endl
;
141 std::cout
<< "Movie state is corrupt" << std::endl
;
142 } else if(m
.movie_sram
.size() > 0) {
143 std::cout
<< "Movie starts from SRAM" << std::endl
;
144 for(auto i
= m
.movie_sram
.begin(); i
!= m
.movie_sram
.end(); i
++)
145 std::cout
<< "Start SRAM: " << escape_string(i
->first
) << " (" << i
->second
.size()
146 << " bytes)" << std::endl
;
148 std::cout
<< "Movie starts from clean state" << std::endl
;
149 if(m
.get_frame_count() > starting_point
)
150 std::cout
<< "Movie frame count: " << (m
.get_frame_count() - starting_point
) << std::endl
;
152 std::cout
<< "Movie frame count: 0" << std::endl
;
153 uint64_t length
= m
.get_movie_length(starting_point
);
155 std::ostringstream x
;
156 if(length
>= 3600000000000ULL) {
157 x
<< (length
/ 3600000000000ULL) << ":";
158 length
%= 3600000000000ULL;
160 x
<< std::setw(2) << std::setfill('0') << (length
/ 60000000000ULL) << ":";
161 length
%= 60000000000ULL;
162 x
<< std::setw(2) << std::setfill('0') << (length
/ 1000000000ULL) << ".";
163 length
%= 1000000000ULL;
164 x
<< std::setw(3) << std::setfill('0') << (length
+ 500000) / 1000000;
165 std::cout
<< "Movie length: " << x
.str() << std::endl
;
167 std::cout
<< "Rerecord count: " << rrdata::count(m
.c_rrdata
) << std::endl
;
168 } catch(std::exception
& e
) {
169 std::cerr
<< "ERROR: " << e
.what() << std::endl
;