summaryrefslogtreecommitdiff
path: root/src/app/init.rs
blob: c7a8653212ef7e604b68b9297271440d76e87a11 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/*
	Copyright 2021-2023 Gabriel Jensen.

This file is part of Luma.
Luma is free software: you can redistribute it
and/or modify it under the terms of the GNU
	Affero General Public License as published by
	the Free Software Foundation, either version 3
	of the License, or (at your option) any later
	version.

	Luma is distributed in the hope that it will be
	useful, but WITHOUT ANY WARRANTY; without even
	the implied warranty of MERCHANTABILITY or
	FITNESS FOR A PARTICULAR PURPOSE. See the GNU
	Affero General Public License for more details.

	You should have received a copy of the GNU
	Affero General Public License along with Luma.
	If not, see <https://www.gnu.org/licenses/>.
*/

use crate::{SCREEN_SIZE, VERSION};
use crate::app::App;
use crate::configuration::Configuration;

use sdl2::pixels::Color;
use sdl2::render::BlendMode;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};

impl App {
	pub fn init(configuration: Configuration) -> Result<Self, String> {
		let got_terminate = Arc::new(AtomicBool::new(false));

		match ctrlc::set_handler({
			let got_terminate = got_terminate.clone();
			move || got_terminate.store(true, Ordering::Relaxed)
		}) {
			Err(..) => return Err("unable to set signal handler".to_string()),
			_       => {},
		};

		let sdl = match sdl2::init() {
			Ok( sdl) => sdl,
			Err(..)  => return Err("unable to initialise sdl2".to_string()),
		};

		let sdl_video = match sdl.video() {
			Ok( video) => video,
			Err(..)    => return Err("unable to initialise video".to_string()),
		};

		let window_title = format!("Luma {:X}.{:X}", VERSION.0, VERSION.1);

		let mut window_builder = sdl_video.window(&window_title, SCREEN_SIZE.0 as u32 * configuration.scale, SCREEN_SIZE.1 as u32 * configuration.scale);
		window_builder.position_centered();

		let window = match window_builder.build() {
			Ok( window) => window,
			Err(..)     => return Err("unable to open window".to_string()),
		};

		let mut canvas = match window.into_canvas().build() {
			Ok( canvas) => canvas,
			Err(..)     => return Err("unable to build canvas".to_string()),
		};

		canvas.set_blend_mode(BlendMode::Blend);

		let clear_colour = Color::RGB(0x00, 0x00, 0x00);
		canvas.set_draw_color(clear_colour);
		canvas.clear();
		canvas.present();

		return Ok(App {
			bootloader: configuration.bootloader,
			image:      configuration.image,

			scale: configuration.scale,

			got_terminate: got_terminate,

			sdl:    sdl,
			canvas: canvas,
		});
	}
}