1 extern crate libloading; |
1 extern crate libloading; |
2 |
2 |
3 use libloading::{Library, Symbol}; |
3 use libloading::{Library, Symbol}; |
4 use std::ops::Deref; |
4 use std::ops::Deref; |
|
5 use std::cmp::{min,max}; |
5 use std::env; |
6 use std::env; |
6 use getopts::Options; |
7 use getopts::Options; |
7 use std::io::prelude::*; |
8 use std::io::prelude::*; |
8 use std::io::{self, Read}; |
9 use std::io::{self, Read}; |
9 use std::net::{Shutdown, TcpStream}; |
10 use std::net::{Shutdown, TcpStream}; |
10 use image::{GrayImage, imageops}; |
|
11 |
11 |
12 struct EngineInstance {} |
12 struct EngineInstance {} |
13 |
13 |
14 struct Engine<'a> { |
14 struct Engine<'a> { |
15 protocol_version: Symbol<'a, unsafe fn() -> u32>, |
15 protocol_version: Symbol<'a, unsafe fn() -> u32>, |
26 struct PreviewInfo { |
26 struct PreviewInfo { |
27 width: u32, |
27 width: u32, |
28 height: u32, |
28 height: u32, |
29 hedgehogs_number: u8, |
29 hedgehogs_number: u8, |
30 land: *const u8, |
30 land: *const u8, |
|
31 } |
|
32 |
|
33 const PREVIEW_WIDTH: u32 = 256; |
|
34 const PREVIEW_HEIGHT: u32 = 128; |
|
35 const PREVIEW_NPIXELS: usize = (PREVIEW_WIDTH * PREVIEW_HEIGHT) as usize; |
|
36 const SCALE_FACTOR: u32 = 16; |
|
37 |
|
38 fn resize_mono_preview(mono_pixels: &[u8], in_width: u32, in_height: u32, preview_pixels: &mut [u8]) { |
|
39 |
|
40 assert!(mono_pixels.len() == (in_width * in_height) as usize); |
|
41 |
|
42 let v_offset: u32 = max(0, PREVIEW_HEIGHT as i64 - (in_height / SCALE_FACTOR) as i64) as u32; |
|
43 let h_offset: u32 = max(0, (PREVIEW_WIDTH as i64 / 2) - (in_width / SCALE_FACTOR / 2) as i64) as u32; |
|
44 |
|
45 for y in v_offset..PREVIEW_HEIGHT { |
|
46 |
|
47 let in_y = v_offset + (y * SCALE_FACTOR); |
|
48 |
|
49 for x in h_offset..(PREVIEW_WIDTH - h_offset) { |
|
50 |
|
51 let in_x = h_offset + (x * SCALE_FACTOR); |
|
52 |
|
53 let out_px_address = (PREVIEW_WIDTH * y + x) as usize; |
|
54 let in_px_address = (in_width * in_y + in_x) as usize; |
|
55 |
|
56 preview_pixels[out_px_address] = mono_pixels[in_px_address]; |
|
57 } |
|
58 } |
31 } |
59 } |
32 |
60 |
33 fn main() { |
61 fn main() { |
34 let hwlib = Library::new("libhedgewars_engine.so").unwrap(); |
62 let hwlib = Library::new("libhedgewars_engine.so").unwrap(); |
35 |
63 |
99 height: 0, |
127 height: 0, |
100 hedgehogs_number: 0, |
128 hedgehogs_number: 0, |
101 land: std::ptr::null(), |
129 land: std::ptr::null(), |
102 }; |
130 }; |
103 |
131 |
|
132 println!("Generating preview..."); |
|
133 |
104 engine.generate_preview.deref()(engine_state, preview_info); |
134 engine.generate_preview.deref()(engine_state, preview_info); |
105 |
|
106 println!("Sending preview..."); |
|
107 |
135 |
108 //println!("Preview: w = {}, h = {}, n = {}", preview_info.width, preview_info.height, preview_info.hedgehogs_number); |
136 //println!("Preview: w = {}, h = {}, n = {}", preview_info.width, preview_info.height, preview_info.hedgehogs_number); |
109 |
137 |
110 let land_size: usize = (preview_info.width * preview_info.height) as usize; |
138 let land_size: usize = (preview_info.width * preview_info.height) as usize; |
111 |
139 |
112 let land_array: &[u8] = std::slice::from_raw_parts(preview_info.land, land_size); |
140 let land_array: &[u8] = std::slice::from_raw_parts(preview_info.land, land_size); |
113 |
141 |
114 let raw_image = GrayImage::from_raw(preview_info.width, preview_info.height, land_array.to_vec()).unwrap(); |
|
115 |
|
116 const PREVIEW_WIDTH: u32 = 256; |
142 const PREVIEW_WIDTH: u32 = 256; |
117 const PREVIEW_HEIGHT: u32 = 128; |
143 const PREVIEW_HEIGHT: u32 = 128; |
118 |
144 |
119 let preview_image = imageops::resize(&raw_image, PREVIEW_WIDTH, PREVIEW_HEIGHT, imageops::FilterType::Triangle); |
145 println!("Resizing preview..."); |
120 |
146 |
121 stream.write(preview_image.as_raw()).unwrap(); |
147 let preview_image: &mut [u8] = &mut [0; PREVIEW_NPIXELS]; |
|
148 resize_mono_preview(land_array, preview_info.width, preview_info.height, preview_image); |
|
149 |
|
150 println!("Sending preview..."); |
|
151 |
|
152 stream.write(preview_image).unwrap(); |
122 stream.flush().unwrap(); |
153 stream.flush().unwrap(); |
123 stream.write(&[preview_info.hedgehogs_number]).unwrap(); |
154 stream.write(&[preview_info.hedgehogs_number]).unwrap(); |
124 stream.flush().unwrap(); |
155 stream.flush().unwrap(); |
125 |
156 |
126 println!("Preview sent, disconnect"); |
157 println!("Preview sent, disconnect"); |