#[cfg(feature = "px8_plugin_lua")]
extern crate px8_plugin_lua;
#[cfg(feature = "cpython")]
#[macro_use]
extern crate cpython;
#[cfg(feature = "portaudio")]
#[macro_use]
extern crate portaudio;
extern crate sdl2;
extern crate getopts;
extern crate nalgebra;
extern crate image;
extern crate gif;
extern crate regex;
extern crate png;
extern crate byteorder;
extern crate rand;
extern crate time;
extern crate chrono;
extern crate libc;
extern crate num;
extern crate glob;
extern crate rusttype;
#[macro_use]
extern crate log;
extern crate fern;
#[macro_use]
extern crate lazy_static;
extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate serde_derive;
extern crate num_traits;
extern crate noise;
use std::env;
use getopts::Options;
#[macro_use]
mod config;
mod frontend;
mod renderer;
mod gfx;
mod px8;
mod plugins;
mod cartridge;
mod sound;
use gfx::Scale;
use cartridge::Cartridge;
fn print_usage(program: &str, opts: &Options) {
let brief = format!("Usage: {} FILE [options]", program);
print!("{}", opts.usage(&brief));
}
fn main() {
let logger_config = fern::DispatchConfig {
format: Box::new(|msg: &str, level: &log::LogLevel, _location: &log::LogLocation| {
format!("[{}][{}] {}",
time::now().strftime("%Y-%m-%d][%H:%M:%S").unwrap(),
level,
msg)
}),
output: vec![fern::OutputConfig::stdout()],
level: log::LogLevelFilter::Trace,
};
let args: Vec<String> = env::args().collect();
let program = args[0].clone();
let mut opts = Options::new();
opts.optflag("c", "check", "check the cartridge");
opts.optflag("e", "editor", "edit the cartridge");
opts.optflag("o", "opengl", "enable opengl with SDL");
opts.optflag("f", "fullscreen", "display in fullscreen");
opts.optflagopt("d", "dump", "dump the cartridge", "FILE");
opts.optflagopt("t",
"transform",
"transform the PNG/PX8 cartridge in P8",
"FILE");
opts.optflagopt("s", "scale", "scale the display", "VALUE");
opts.optflagopt("b", "bind", "bind a server on a specific address", "ADDR");
opts.optflagopt("m", "mode", "Switch the compatibility mode", "MODE");
opts.optflag("v", "verbose", "Debug mode level");
opts.optflag("h", "help", "print this help menu");
let matches = match opts.parse(&args[1..]) {
Ok(m) => m,
Err(f) => panic!(f.to_string()),
};
if matches.opt_present("h") {
print_usage(&program, &opts);
return;
}
if matches.opt_present("v") {
if let Err(e) = fern::init_global_logger(logger_config, log::LogLevelFilter::Debug) {
panic!("Failed to initialize global logger: {}", e);
}
} else {
if let Err(e) = fern::init_global_logger(logger_config, log::LogLevelFilter::Info) {
panic!("Failed to initialize global logger: {}", e);
}
}
let mut mode = px8::PX8Mode::PX8;
if matches.opt_present("m") {
let mode_str = matches.opt_str("m").unwrap();
if mode_str == "pico8" {
mode = px8::PX8Mode::PICO8;
}
}
let mut scale = Scale::Scale4x;
if matches.opt_present("s") {
let value = matches.opt_str("s").unwrap().parse::<i32>().unwrap();
match value {
2 => scale = Scale::Scale2x,
3 => scale = Scale::Scale3x,
4 => scale = Scale::Scale4x,
5 => scale = Scale::Scale5x,
6 => scale = Scale::Scale6x,
8 => scale = Scale::Scale8x,
10 => scale = Scale::Scale10x,
_ => scale = Scale::Scale1x,
}
}
let fullscreen = matches.opt_present("f");
let opengl = matches.opt_present("o");
let input = if !matches.free.is_empty() {
matches.free[0].clone()
} else {
run_interactive(scale, fullscreen, opengl);
return;
};
if matches.opt_present("c") {
if input.contains(".png") {
match Cartridge::from_png_file(&input) {
Ok(mut c) => {
println!("{:?}", c);
if matches.opt_present("d") {
c.dump(&matches.opt_str("d").unwrap());
}
}
Err(e) => panic!(e),
}
} else if input.contains(".p8") {
match Cartridge::from_p8_file(&input) {
Ok(mut c) => {
println!("{:?}", c);
if matches.opt_present("d") {
c.set_mode(mode == px8::PX8Mode::PICO8);
c.dump(&matches.opt_str("d").unwrap());
}
}
Err(e) => panic!(e),
}
} else if input.contains(".px8") {
match Cartridge::from_px8_file(&input) {
Ok(c) => {
println!("{:?}", c);
}
Err(e) => panic!(e),
}
}
} else if matches.opt_present("t") {
if input.contains(".png") {
match Cartridge::from_png_file(&input) {
Ok(mut c) => {
println!("{:?}", c);
c.save_in_p8(&matches.opt_str("t").unwrap());
}
Err(e) => panic!(e),
}
}
} else {
run_cartridge(scale,
fullscreen,
opengl,
&input,
matches.opt_present("e"),
mode);
}
}
pub fn run_cartridge(scale: gfx::Scale,
fullscreen: bool,
opengl: bool,
filename: &str,
editor: bool,
mode: px8::PX8Mode) {
let mut frontend = match frontend::Frontend::init(scale, fullscreen, opengl, false) {
Err(error) => panic!("{:?}", error),
Ok(frontend) => frontend,
};
frontend.start("./sys/config/gamecontrollerdb.txt".to_string());
frontend.run_cartridge(filename, editor, mode);
}
pub fn run_interactive(scale: gfx::Scale, fullscreen: bool, opengl: bool) {
let mut frontend = match frontend::Frontend::init(scale, fullscreen, opengl, false) {
Err(error) => panic!("{:?}", error),
Ok(frontend) => frontend,
};
frontend.start("./sys/config/gamecontrollerdb.txt".to_string());
frontend.run_interactive();
}