Small documentation fixups regarding joysticks/gamepads
[lsnes.git] / lsnes-dumpavi.cpp
blob6e6de39f935178e72710a826301adbb74de3969b
1 #include <sstream>
2 #include "mainloop.hpp"
3 #include "command.hpp"
4 #include "lua.hpp"
5 #include "moviedata.hpp"
6 #include "rrdata.hpp"
7 #include "lsnes.hpp"
8 #include "rom.hpp"
9 #include "keymapper.hpp"
10 #include "misc.hpp"
11 #include "window.hpp"
12 #include <sys/time.h>
13 #include <snes/snes.hpp>
14 #include <ui-libsnes/libsnes.hpp>
15 #include "framerate.hpp"
16 #include "avsnoop.hpp"
18 namespace
20 class myavsnoop : public av_snooper
22 public:
23 myavsnoop(uint64_t frames_to_dump)
25 frames_dumped = 0;
26 total = frames_to_dump;
29 ~myavsnoop()
33 void frame(struct lcscreen& _frame, uint32_t fps_n, uint32_t fps_d) throw(std::bad_alloc,
34 std::runtime_error)
36 frames_dumped++;
37 if(frames_dumped % 100 == 0) {
38 std::cout << "Dumping frame " << frames_dumped << "/" << total << " ("
39 << (100 * frames_dumped / total) << "%)" << std::endl;
41 if(frames_dumped == total) {
42 //Rough way to end it.
43 av_snooper::end(true);
44 exit(1);
48 void sample(short l, short r) throw(std::bad_alloc, std::runtime_error)
52 void end() throw(std::bad_alloc, std::runtime_error)
54 std::cout << "Finished!" << std::endl;
57 void gameinfo(const std::string& gamename, const std::list<std::pair<std::string, std::string>>&
58 authors, double gametime, const std::string& rerecords) throw(std::bad_alloc,
59 std::runtime_error)
62 private:
63 uint64_t frames_dumped;
64 uint64_t total;
67 void dumper_startup(const std::vector<std::string>& cmdline)
69 unsigned level = 7;
70 std::string prefix = "avidump";
71 uint64_t length = 0;
72 for(auto i = cmdline.begin(); i != cmdline.end(); i++) {
73 std::string a = *i;
74 if(a.length() > 9 && a.substr(0, 9) == "--prefix=")
75 prefix = a.substr(9);
76 if(a.length() > 8 && a.substr(0, 8) == "--level=")
77 try {
78 level = boost::lexical_cast<unsigned>(a.substr(8));
79 if(level < 0 || level > 18)
80 throw std::runtime_error("Level out of range (0-18)");
81 } catch(std::exception& e) {
82 std::cerr << "Bad --level: " << e.what() << std::endl;
83 exit(1);
85 if(a.length() > 9 && a.substr(0, 9) == "--length=")
86 try {
87 length = boost::lexical_cast<uint64_t>(a.substr(9));
88 if(!length)
89 throw std::runtime_error("Length out of range (1-)");
90 } catch(std::exception& e) {
91 std::cerr << "Bad --length: " << e.what() << std::endl;
92 exit(1);
95 if(!length) {
96 std::cerr << "--length=<frames> has to be specified" << std::endl;
97 exit(1);
99 std::cout << "Invoking dumper" << std::endl;
100 std::ostringstream cmd;
101 cmd << "dump-avi " << level << " " << prefix;
102 command::invokeC(cmd.str());
103 if(av_snooper::dump_in_progress()) {
104 std::cout << "Dumper attach confirmed" << std::endl;
105 } else {
106 std::cout << "Can't start dumper!" << std::endl;
107 exit(1);
109 myavsnoop* s = new myavsnoop(length);
112 void startup_lua_scripts(const std::vector<std::string>& cmdline)
114 for(auto i = cmdline.begin(); i != cmdline.end(); i++) {
115 std::string a = *i;
116 if(a.length() > 6 && a.substr(0, 6) == "--lua=") {
117 command::invokeC("run-lua " + a.substr(6));
123 class my_interfaced : public SNES::Interface
125 string path(SNES::Cartridge::Slot slot, const string &hint)
127 return "./";
132 int main(int argc, char** argv)
134 std::vector<std::string> cmdline;
135 for(int i = 1; i < argc; i++)
136 cmdline.push_back(argv[i]);
137 my_interfaced intrf;
138 SNES::system.interface = &intrf;
140 set_random_seed();
143 std::ostringstream x;
144 x << snes_library_id() << " (" << SNES::Info::Profile << " core)";
145 bsnes_core_version = x.str();
147 init_lua();
149 messages << "BSNES version: " << bsnes_core_version << std::endl;
150 messages << "lsnes version: lsnes rr" << lsnes_version << std::endl;
151 messages << "Command line is: ";
152 for(auto k = cmdline.begin(); k != cmdline.end(); k++)
153 messages << "\"" << *k << "\" ";
154 messages << std::endl;
156 std::string cfgpath = get_config_path();
158 messages << "--- Loading ROM ---" << std::endl;
159 struct loaded_rom r;
160 try {
161 r = load_rom_from_commandline(cmdline);
162 r.load();
163 } catch(std::bad_alloc& e) {
164 OOM_panic();
165 } catch(std::exception& e) {
166 messages << "FATAL: Can't load ROM: " << e.what() << std::endl;
167 fatal_error();
168 exit(1);
170 messages << "Detected region: " << gtype::tostring(r.rtype, r.region) << std::endl;
171 if(r.region == REGION_PAL)
172 set_nominal_framerate(322445.0/6448.0);
173 else if(r.region == REGION_NTSC)
174 set_nominal_framerate(10738636.0/178683.0);
176 messages << "--- Internal memory mappings ---" << std::endl;
177 dump_region_map();
178 messages << "--- End of Startup --- " << std::endl;
180 dumper_startup(cmdline);
181 startup_lua_scripts(cmdline);
183 moviefile movie;
184 try {
185 bool tried = false;
186 bool loaded = false;
187 for(auto i = cmdline.begin(); i != cmdline.end(); i++)
188 if(i->length() > 0 && (*i)[0] != '-') {
189 try {
190 tried = true;
191 movie = moviefile(*i);
192 loaded = true;
193 } catch(std::bad_alloc& e) {
194 OOM_panic();
195 } catch(std::exception& e) {
196 messages << "Error loading '" << *i << "': " << e.what() << std::endl;
199 if(!tried)
200 throw std::runtime_error("Specifying movie is required");
201 if(!loaded)
202 throw std::runtime_error("Can't load any of the movies specified");
203 main_loop(r, movie, true);
204 } catch(std::bad_alloc& e) {
205 OOM_panic();
206 } catch(std::exception& e) {
207 messages << "FATAL: " << e.what() << std::endl;
208 fatal_error();
209 return 1;
211 rrdata::close();
212 return 0;