1#![allow(unused_variables)]
5use crate::{
6 event::Event,
7 render::{buffer::Buffer, sprite::Sprites},
8 util::{Rand, Rect},
9};
10#[cfg(any(feature = "sdl", target_arch = "wasm32"))]
11use crate::{
12 render::adapter::gl::{color::GlColor, pixel::GlPixel, transform::GlTransform},
13 render::style::Color,
14 util::{ARect, PointF32, PointI32, PointU16},
15 LOGO_FRAME,
16};
17use std::any::Any;
18use std::sync::OnceLock;
19use std::time::Duration;
20pub mod gl;
24
25#[cfg(all(feature = "sdl", not(target_arch = "wasm32")))]
27pub mod sdl;
28
29#[cfg(target_arch = "wasm32")]
31pub mod web;
32
33#[cfg(not(any(
35 feature = "sdl",
36 target_os = "android",
37 target_os = "ios",
38 target_arch = "wasm32"
39)))]
40pub mod cross;
41
42#[cfg(any(feature = "sdl", target_arch = "wasm32"))]
46pub const PIXEL_TEXTURE_FILE: &str = "assets/pix/symbols.png";
47
48pub fn init_sym_width(width: u32) -> f32 {
50 width as f32 / 128.0
51}
52pub fn init_sym_height(height: u32) -> f32 {
53 height as f32 / 128.0
54}
55pub static PIXEL_SYM_WIDTH: OnceLock<f32> = OnceLock::new();
56pub static PIXEL_SYM_HEIGHT: OnceLock<f32> = OnceLock::new();
57
58pub const PIXEL_LOGO_WIDTH: usize = 27;
60pub const PIXEL_LOGO_HEIGHT: usize = 12;
61pub const PIXEL_LOGO: [u8; PIXEL_LOGO_WIDTH * PIXEL_LOGO_HEIGHT * 3] = [
62 32, 15, 1, 32, 202, 1, 32, 15, 1, 32, 15, 1, 32, 15, 1, 32, 239, 1, 32, 15, 1, 100, 239, 1, 32,
63 239, 1, 32, 15, 1, 32, 15, 1, 32, 15, 1, 32, 15, 1, 32, 15, 0, 32, 15, 0, 32, 15, 0, 32, 15, 0,
64 32, 15, 1, 32, 15, 1, 32, 15, 0, 32, 15, 1, 32, 15, 1, 32, 15, 0, 32, 15, 1, 32, 165, 1, 32,
65 165, 0, 32, 87, 1, 32, 15, 1, 18, 202, 1, 21, 202, 1, 19, 202, 1, 20, 202, 1, 32, 15, 1, 47,
66 239, 1, 47, 239, 1, 116, 239, 1, 32, 15, 0, 32, 15, 0, 32, 15, 0, 32, 15, 0, 32, 15, 0, 32, 15,
67 0, 32, 15, 0, 32, 15, 0, 32, 15, 0, 32, 15, 0, 32, 15, 0, 32, 15, 0, 32, 15, 0, 32, 15, 0, 32,
68 15, 0, 32, 87, 1, 32, 165, 0, 32, 165, 1, 32, 240, 1, 100, 239, 1, 100, 239, 1, 100, 239, 1,
69 100, 239, 1, 100, 239, 1, 81, 49, 1, 47, 239, 1, 32, 239, 1, 100, 239, 1, 32, 239, 1, 32, 15,
70 1, 32, 239, 1, 100, 239, 1, 32, 239, 1, 100, 239, 1, 100, 239, 1, 100, 239, 1, 100, 239, 1,
71 100, 239, 1, 32, 239, 1, 100, 239, 1, 32, 239, 1, 32, 15, 0, 32, 87, 1, 32, 15, 0, 32, 165, 0,
72 47, 239, 1, 104, 239, 1, 104, 239, 1, 104, 239, 1, 104, 239, 1, 47, 239, 1, 47, 238, 1, 47,
73 238, 1, 47, 238, 1, 47, 239, 1, 100, 239, 1, 46, 239, 1, 47, 239, 1, 47, 239, 1, 47, 239, 1,
74 104, 239, 1, 104, 239, 1, 104, 239, 1, 104, 239, 1, 47, 239, 1, 47, 239, 1, 47, 239, 1, 84,
75 239, 1, 32, 15, 0, 32, 15, 0, 32, 15, 0, 32, 15, 0, 160, 49, 1, 160, 49, 1, 160, 49, 1, 160,
76 49, 1, 81, 49, 1, 32, 15, 1, 160, 86, 1, 32, 15, 1, 160, 49, 1, 47, 236, 1, 47, 236, 1, 46,
77 234, 1, 160, 49, 1, 47, 239, 1, 81, 49, 1, 160, 49, 1, 160, 49, 1, 160, 49, 1, 160, 49, 1, 47,
78 239, 1, 160, 49, 1, 32, 15, 1, 84, 239, 1, 32, 15, 0, 32, 15, 0, 32, 15, 0, 32, 87, 1, 160, 45,
79 1, 32, 15, 1, 32, 15, 1, 32, 15, 1, 160, 45, 1, 32, 15, 1, 160, 45, 1, 32, 235, 1, 116, 235, 1,
80 160, 45, 1, 47, 236, 1, 160, 45, 1, 47, 239, 1, 116, 239, 1, 160, 45, 1, 46, 234, 1, 32, 15, 1,
81 46, 234, 1, 47, 239, 1, 116, 239, 1, 160, 45, 1, 32, 15, 1, 84, 239, 1, 32, 15, 0, 32, 15, 1,
82 32, 15, 0, 32, 197, 1, 160, 147, 1, 32, 239, 1, 100, 239, 1, 100, 239, 1, 160, 147, 1, 32, 15,
83 1, 160, 147, 1, 32, 235, 1, 116, 235, 1, 46, 235, 1, 81, 147, 1, 47, 239, 1, 47, 239, 1, 100,
84 239, 1, 160, 147, 1, 160, 147, 1, 160, 147, 1, 160, 147, 1, 47, 239, 1, 32, 15, 1, 160, 147, 1,
85 32, 239, 1, 84, 239, 1, 100, 239, 1, 100, 239, 1, 100, 239, 1, 32, 239, 1, 160, 147, 1, 47,
86 239, 1, 104, 239, 1, 104, 240, 1, 160, 147, 1, 32, 15, 1, 160, 147, 1, 32, 15, 1, 116, 235, 1,
87 160, 147, 1, 47, 239, 1, 160, 147, 1, 47, 239, 1, 47, 239, 1, 160, 147, 1, 104, 238, 1, 104,
88 238, 1, 104, 238, 1, 104, 238, 1, 47, 242, 1, 160, 147, 1, 47, 239, 1, 104, 239, 1, 104, 239,
89 1, 104, 239, 1, 47, 239, 1, 84, 239, 1, 160, 214, 1, 160, 214, 1, 160, 214, 1, 160, 214, 1, 81,
90 214, 1, 47, 239, 1, 81, 214, 1, 47, 239, 1, 160, 214, 1, 47, 239, 1, 32, 0, 1, 46, 235, 1, 160,
91 214, 1, 47, 236, 1, 81, 214, 1, 160, 214, 1, 160, 214, 1, 160, 214, 1, 160, 214, 1, 47, 242, 1,
92 81, 214, 1, 81, 214, 1, 81, 214, 1, 81, 214, 1, 81, 214, 1, 47, 239, 1, 32, 165, 1, 160, 214,
93 1, 103, 239, 1, 32, 242, 1, 32, 15, 1, 32, 15, 1, 32, 15, 1, 32, 15, 1, 32, 15, 1, 32, 0, 1,
94 32, 0, 1, 32, 87, 1, 32, 87, 0, 32, 15, 0, 32, 15, 0, 32, 15, 0, 32, 15, 0, 32, 15, 0, 32, 15,
95 0, 32, 15, 0, 32, 15, 0, 32, 15, 0, 32, 15, 0, 32, 15, 0, 32, 15, 0, 32, 15, 0, 32, 165, 0, 32,
96 165, 0, 160, 214, 1, 103, 239, 1, 32, 242, 1, 32, 97, 1, 32, 15, 0, 32, 15, 0, 32, 15, 0, 32,
97 15, 0, 32, 15, 0, 32, 15, 0, 32, 15, 0, 32, 97, 0, 32, 15, 0, 32, 15, 0, 32, 15, 0, 32, 15, 0,
98 32, 15, 0, 32, 15, 0, 32, 15, 0, 32, 15, 0, 32, 15, 0, 32, 15, 0, 32, 15, 0, 32, 15, 0, 32, 97,
99 0, 32, 165, 0, 32, 15, 1, 90, 214, 1, 47, 239, 1, 32, 0, 1, 32, 15, 0, 32, 0, 1, 32, 0, 1, 32,
100 15, 0, 32, 15, 0, 32, 15, 0, 32, 15, 0, 32, 0, 1, 32, 15, 0, 32, 0, 1, 32, 0, 1, 32, 0, 1, 32,
101 0, 1, 32, 0, 1, 32, 0, 1, 32, 0, 1, 32, 15, 0, 32, 15, 1, 32, 15, 1, 32, 15, 1, 32, 15, 1, 32,
102 15, 1, 32, 15, 1, 32, 15, 1,
103];
104
105#[derive(Clone, Copy, Default, Debug, PartialEq)]
108pub struct RenderCell {
109 pub fcolor: (f32, f32, f32, f32),
110 pub bcolor: Option<(f32, f32, f32, f32)>,
111 pub texsym: usize,
112 pub x: f32,
113 pub y: f32,
114 pub w: u32,
115 pub h: u32,
116 pub angle: f32,
117 pub cx: f32,
118 pub cy: f32,
119}
120
121pub struct AdapterBase {
122 pub game_name: String,
123 pub project_path: String,
124 pub title: String,
125 pub cell_w: u16,
126 pub cell_h: u16,
127 pub pixel_w: u32,
128 pub pixel_h: u32,
129 pub ratio_x: f32,
130 pub ratio_y: f32,
131 pub rd: Rand,
132 #[cfg(any(feature = "sdl", target_arch = "wasm32"))]
133 pub rflag: bool,
134 #[cfg(any(feature = "sdl", target_arch = "wasm32"))]
135 pub rbuf: Vec<RenderCell>,
136 #[cfg(any(feature = "sdl", target_arch = "wasm32"))]
137 pub gl: Option<glow::Context>,
138 #[cfg(any(feature = "sdl", target_arch = "wasm32"))]
139 pub gl_pixel: Option<GlPixel>,
140}
141
142impl AdapterBase {
143 pub fn new(gn: &str, project_path: &str) -> Self {
144 Self {
145 game_name: gn.to_string(),
146 project_path: project_path.to_string(),
147 title: "".to_string(),
148 cell_w: 0,
149 cell_h: 0,
150 pixel_w: 0,
151 pixel_h: 0,
152 ratio_x: 1.0,
153 ratio_y: 1.0,
154 rd: Rand::new(),
155 #[cfg(any(feature = "sdl", target_arch = "wasm32"))]
156 rflag: true,
157 #[cfg(any(feature = "sdl", target_arch = "wasm32"))]
158 rbuf: vec![],
159 #[cfg(any(feature = "sdl", target_arch = "wasm32"))]
160 gl: None,
161 #[cfg(any(feature = "sdl", target_arch = "wasm32"))]
162 gl_pixel: None,
163 }
164 }
165}
166
167pub trait Adapter {
168 fn init(&mut self, w: u16, h: u16, rx: f32, ry: f32, s: String);
169 fn reset(&mut self);
170 fn get_base(&mut self) -> &mut AdapterBase;
171 fn poll_event(&mut self, timeout: Duration, ev: &mut Vec<Event>) -> bool;
172
173 fn draw_all_to_screen(
174 &mut self,
175 current_buffer: &Buffer,
176 previous_buffer: &Buffer,
177 pixel_sprites: &mut Vec<Sprites>,
178 stage: u32,
179 ) -> Result<(), String>;
180
181 fn set_size(&mut self, w: u16, h: u16) -> &mut Self
182 where
183 Self: Sized,
184 {
185 let bs = self.get_base();
186 bs.cell_w = w;
187 bs.cell_h = h;
188 self
189 }
190
191 fn size(&mut self) -> Rect {
192 let bs = self.get_base();
193 Rect::new(0, 0, bs.cell_w, bs.cell_h)
194 }
195
196 fn set_ratiox(&mut self, rx: f32) -> &mut Self
197 where
198 Self: Sized,
199 {
200 let bs = self.get_base();
201 bs.ratio_x = rx;
202 self
203 }
204
205 fn set_ratioy(&mut self, ry: f32) -> &mut Self
206 where
207 Self: Sized,
208 {
209 let bs = self.get_base();
210 bs.ratio_y = ry;
211 self
212 }
213
214 fn set_pixel_size(&mut self) -> &mut Self
215 where
216 Self: Sized,
217 {
218 let bs = self.get_base();
219 bs.pixel_w = ((bs.cell_w + 2) as f32 * PIXEL_SYM_WIDTH.get().expect("lazylock init")
220 / bs.ratio_x) as u32;
221 bs.pixel_h = ((bs.cell_h + 2) as f32 * PIXEL_SYM_HEIGHT.get().expect("lazylock init")
222 / bs.ratio_y) as u32;
223 self
224 }
225
226 fn set_title(&mut self, s: String) -> &mut Self
227 where
228 Self: Sized,
229 {
230 let bs = self.get_base();
231 bs.title = s;
232 self
233 }
234
235 fn cell_width(&self) -> f32;
236 fn cell_height(&self) -> f32;
237 fn hide_cursor(&mut self) -> Result<(), String>;
238 fn show_cursor(&mut self) -> Result<(), String>;
239 fn set_cursor(&mut self, x: u16, y: u16) -> Result<(), String>;
240 fn get_cursor(&mut self) -> Result<(u16, u16), String>;
241
242 #[cfg(any(feature = "sdl", target_arch = "wasm32"))]
244 fn draw_all_graph(
245 &mut self,
246 current_buffer: &Buffer,
247 previous_buffer: &Buffer,
248 pixel_sprites: &mut Vec<Sprites>,
249 stage: u32,
250 ) {
251 let rbuf =
253 self.draw_all_to_render_buffer(current_buffer, previous_buffer, pixel_sprites, stage);
254 if self.get_base().rflag {
264 self.draw_render_buffer_to_texture(&rbuf, 2, false);
266 self.draw_render_textures_to_screen();
268 } else {
269 self.get_base().rbuf = rbuf;
271 }
273 }
274
275 #[cfg(any(feature = "sdl", target_arch = "wasm32"))]
276 fn only_render_buffer(&mut self) {
277 self.get_base().rflag = false;
278 }
279
280 #[cfg(any(feature = "sdl", target_arch = "wasm32"))]
281 fn draw_render_textures_to_screen(&mut self) {
282 let bs = self.get_base();
283
284 if let (Some(pix), Some(gl)) = (&mut bs.gl_pixel, &mut bs.gl) {
285 pix.bind_screen(gl);
286 let c = GlColor::new(1.0, 1.0, 1.0, 1.0);
287
288 if !pix.get_render_texture_hidden(2) {
290 let t = GlTransform::new();
291 pix.draw_general2d(gl, 2, [0.0, 0.0, 1.0, 1.0], &t, &c);
292 }
293
294 if !pix.get_render_texture_hidden(3) {
296 let pcw = pix.canvas_width as f32;
297 let pch = pix.canvas_height as f32;
298 let rx = bs.ratio_x;
299 let ry = bs.ratio_y;
300 let pw = 40.0 * PIXEL_SYM_WIDTH.get().expect("lazylock init") / rx;
301 let ph = 25.0 * PIXEL_SYM_HEIGHT.get().expect("lazylock init") / ry;
302
303 let mut t2 = GlTransform::new();
304 t2.scale(pw / pcw, ph / pch);
305 pix.draw_general2d(
306 gl,
307 3,
308 [0.0 / pcw, (pch - ph) / pch, pw / pcw, ph / pch],
309 &t2,
310 &c,
311 );
312 }
313 }
314 }
315
316 #[cfg(any(feature = "sdl", target_arch = "wasm32"))]
318 fn draw_buffer_to_texture(&mut self, buf: &Buffer, rtidx: usize) {
319 let rbuf = self.buffer_to_render_buffer(buf);
320 self.draw_render_buffer_to_texture(&rbuf, rtidx, false);
323 }
324
325 #[cfg(any(feature = "sdl", target_arch = "wasm32"))]
327 fn draw_render_buffer_to_texture(&mut self, rbuf: &[RenderCell], rtidx: usize, debug: bool) {
328 let bs = self.get_base();
329 let rx = bs.ratio_x;
330 let ry = bs.ratio_y;
331 if let (Some(pix), Some(gl)) = (&mut bs.gl_pixel, &mut bs.gl) {
332 pix.bind_target(gl, rtidx);
333 if debug {
334 pix.set_clear_color(GlColor::new(1.0, 0.0, 0.0, 1.0));
336 } else {
337 pix.set_clear_color(GlColor::new(0.0, 0.0, 0.0, 1.0));
338 }
339 pix.clear(gl);
340 pix.render_rbuf(gl, rbuf, rx, ry);
341 }
342 }
343
344 #[cfg(any(feature = "sdl", target_arch = "wasm32"))]
346 fn buffer_to_render_buffer(&mut self, cb: &Buffer) -> Vec<RenderCell> {
347 let mut rbuf = vec![];
348 let rx = self.get_base().ratio_x;
349 let ry = self.get_base().ratio_y;
350 let pz = PointI32 { x: 0, y: 0 };
351 let mut rfunc = |fc: &(u8, u8, u8, u8),
352 bc: &Option<(u8, u8, u8, u8)>,
353 _s0: ARect,
354 _s1: ARect,
355 s2: ARect,
356 texidx: usize,
357 symidx: usize| {
358 push_render_buffer(&mut rbuf, fc, bc, texidx, symidx, s2, 0.0, &pz);
359 };
360 render_main_buffer(cb, cb.area.width, rx, ry, true, &mut rfunc);
361 rbuf
362 }
363
364 #[cfg(any(feature = "sdl", target_arch = "wasm32"))]
366 fn draw_all_to_render_buffer(
367 &mut self,
368 cb: &Buffer,
369 _pb: &Buffer,
370 ps: &mut Vec<Sprites>,
371 stage: u32,
372 ) -> Vec<RenderCell> {
373 let mut rbuf = vec![];
374 let width = cb.area.width;
375 let pz = PointI32 { x: 0, y: 0 };
376
377 if stage <= LOGO_FRAME {
379 render_logo(
380 self.get_base().ratio_x,
381 self.get_base().ratio_y,
382 self.get_base().pixel_w,
383 self.get_base().pixel_h,
384 &mut self.get_base().rd,
385 stage,
386 |fc, _s1, s2, texidx, symidx| {
387 push_render_buffer(&mut rbuf, fc, &None, texidx, symidx, s2, 0.0, &pz);
388 },
389 );
390 return rbuf;
391 }
392
393 let cw = self.get_base().cell_w;
394 let ch = self.get_base().cell_h;
395 let rx = self.get_base().ratio_x;
396 let ry = self.get_base().ratio_y;
397 let mut rfunc = |fc: &(u8, u8, u8, u8),
398 bc: &Option<(u8, u8, u8, u8)>,
399 _s0: ARect,
400 _s1: ARect,
401 s2: ARect,
402 texidx: usize,
403 symidx: usize| {
404 push_render_buffer(&mut rbuf, fc, bc, texidx, symidx, s2, 0.0, &pz);
405 };
406
407 #[cfg(feature = "sdl")]
409 render_border(cw, ch, rx, ry, &mut rfunc);
410
411 if stage > LOGO_FRAME {
413 render_main_buffer(cb, width, rx, ry, false, &mut rfunc);
414 }
415
416 if stage > LOGO_FRAME {
418 for item in ps {
419 if item.is_pixel && !item.is_hidden {
420 render_pixel_sprites(
421 item,
422 rx,
423 ry,
424 |fc, bc, _s0, _s1, s2, texidx, symidx, angle, ccp| {
425 push_render_buffer(&mut rbuf, fc, bc, texidx, symidx, s2, angle, &ccp);
426 },
427 );
428 }
429 }
430 }
431 rbuf
432 }
433
434 fn as_any(&mut self) -> &mut dyn Any;
435}
436
437#[cfg(any(feature = "sdl", target_arch = "wasm32"))]
438fn push_render_buffer(
439 rbuf: &mut Vec<RenderCell>,
440 fc: &(u8, u8, u8, u8),
441 bgc: &Option<(u8, u8, u8, u8)>,
442 texidx: usize,
443 symidx: usize,
444 s: ARect,
445 angle: f64,
446 ccp: &PointI32,
447) {
448 let mut wc = RenderCell {
449 fcolor: (
450 fc.0 as f32 / 255.0,
451 fc.1 as f32 / 255.0,
452 fc.2 as f32 / 255.0,
453 fc.3 as f32 / 255.0,
454 ),
455 ..Default::default()
456 };
457 if let Some(bc) = bgc {
458 wc.bcolor = Some((
459 bc.0 as f32 / 255.0,
460 bc.1 as f32 / 255.0,
461 bc.2 as f32 / 255.0,
462 bc.3 as f32 / 255.0,
463 ));
464 } else {
465 wc.bcolor = None;
466 }
467 let x = symidx as u32 % 16u32 + (texidx as u32 % 8u32) * 16u32;
468 let y = symidx as u32 / 16u32 + (texidx as u32 / 8u32) * 16u32;
469 wc.texsym = (y * 16u32 * 8u32 + x) as usize;
470 wc.x = s.x as f32 + PIXEL_SYM_WIDTH.get().expect("lazylock init");
471 wc.y = s.y as f32 + PIXEL_SYM_HEIGHT.get().expect("lazylock init");
472 wc.w = s.w;
473 wc.h = s.h;
474 if angle == 0.0 {
475 wc.angle = angle as f32;
476 } else {
477 let mut aa = (1.0 - angle / 180.0) * std::f64::consts::PI;
478 let pi2 = std::f64::consts::PI * 2.0;
479 while aa < 0.0 {
480 aa += pi2;
481 }
482 while aa > pi2 {
483 aa -= pi2;
484 }
485 wc.angle = aa as f32;
486 }
487 wc.cx = ccp.x as f32;
488 wc.cy = ccp.y as f32;
489 rbuf.push(wc);
490}
491
492#[cfg(any(feature = "sdl", target_arch = "wasm32"))]
493fn render_helper(
494 cell_w: u16,
495 r: PointF32,
496 i: usize,
497 sh: &(u8, u8, Color, Color),
498 p: PointU16,
499 is_border: bool,
500) -> (ARect, ARect, ARect, usize, usize) {
501 let w = *PIXEL_SYM_WIDTH.get().expect("lazylock init") as i32;
502 let h = *PIXEL_SYM_HEIGHT.get().expect("lazylock init") as i32;
503 let dstx = i as u16 % cell_w;
504 let dsty = i as u16 / cell_w;
505 let tex_count = 64;
506 let tx = if sh.1 < tex_count { sh.1 as usize } else { 1 };
507 let srcy = sh.0 as u32 / w as u32 + (tx as u32 / 2u32) * w as u32;
508 let srcx = sh.0 as u32 % w as u32 + (tx as u32 % 2u32) * w as u32;
509 let bsrcy = 160u32 / w as u32;
510 let bsrcx = 160u32 % w as u32 + w as u32;
511
512 (
513 ARect {
515 x: w * bsrcx as i32,
516 y: h * bsrcy as i32,
517 w: w as u32,
518 h: h as u32,
519 },
520 ARect {
522 x: w * srcx as i32,
523 y: h * srcy as i32,
524 w: w as u32,
525 h: h as u32,
526 },
527 ARect {
529 x: (dstx + if is_border { 0 } else { 1 }) as i32 * (w as f32 / r.x) as i32 + p.x as i32,
530 y: (dsty + if is_border { 0 } else { 1 }) as i32 * (h as f32 / r.y) as i32 + p.y as i32,
531 w: (w as f32 / r.x) as u32,
532 h: (h as f32 / r.y) as u32,
533 },
534 tx,
536 sh.0 as usize,
538 )
539}
540
541#[cfg(any(feature = "sdl", target_arch = "wasm32"))]
542pub fn render_pixel_sprites<F>(pixel_spt: &mut Sprites, rx: f32, ry: f32, mut f: F)
543where
544 F: FnMut(
546 &(u8, u8, u8, u8),
547 &Option<(u8, u8, u8, u8)>,
548 ARect,
549 ARect,
550 ARect,
551 usize,
552 usize,
553 f64,
554 PointI32,
555 ),
556{
557 pixel_spt.update_render_index();
559 for si in &pixel_spt.render_index {
560 let s = &pixel_spt.sprites[si.0];
561 if s.is_hidden() {
562 continue;
563 }
564 let px = s.content.area.x;
565 let py = s.content.area.y;
566 let pw = s.content.area.width;
567 let ph = s.content.area.height;
568
569 for (i, cell) in s.content.content.iter().enumerate() {
570 let sh = &cell.get_cell_info();
571 let (s0, s1, s2, texidx, symidx) = render_helper(
572 pw,
573 PointF32 { x: rx, y: ry },
574 i,
575 sh,
576 PointU16 { x: px, y: py },
577 false,
578 );
579 let x = i % pw as usize;
580 let y = i / pw as usize;
581 let ccp = PointI32 {
583 x: ((pw as f32 / 2.0 - x as f32) * PIXEL_SYM_WIDTH.get().expect("lazylock init") / rx) as i32,
584 y: ((ph as f32 / 2.0 - y as f32) * PIXEL_SYM_HEIGHT.get().expect("lazylock init") / ry) as i32,
585 };
586 let mut fc = sh.2.get_rgba();
587 fc.3 = s.alpha;
588 let bc;
589 if sh.3 != Color::Reset {
590 let mut brgba = sh.3.get_rgba();
591 brgba.3 = s.alpha;
592 bc = Some(brgba);
593 } else {
594 bc = None;
595 }
596 f(&fc, &bc, s0, s1, s2, texidx, symidx, s.angle, ccp);
597 }
598 }
599}
600
601#[cfg(any(feature = "sdl", target_arch = "wasm32"))]
602pub fn render_main_buffer<F>(buf: &Buffer, width: u16, rx: f32, ry: f32, border: bool, mut f: F)
603where
604 F: FnMut(&(u8, u8, u8, u8), &Option<(u8, u8, u8, u8)>, ARect, ARect, ARect, usize, usize),
605{
606 for (i, cell) in buf.content.iter().enumerate() {
607 let sh = cell.get_cell_info();
609 let (s0, s1, s2, texidx, symidx) = render_helper(
610 width,
611 PointF32 { x: rx, y: ry },
612 i,
613 &sh,
614 PointU16 { x: 0, y: 0 },
615 border,
616 );
617 let fc = sh.2.get_rgba();
618 let bc = if sh.3 != Color::Reset {
619 Some(sh.3.get_rgba())
620 } else {
621 None
622 };
623 f(&fc, &bc, s0, s1, s2, texidx, symidx);
624 }
625}
626
627#[cfg(any(feature = "sdl", target_arch = "wasm32"))]
628pub fn render_border<F>(cell_w: u16, cell_h: u16, rx: f32, ry: f32, mut f: F)
629where
630 F: FnMut(&(u8, u8, u8, u8), &Option<(u8, u8, u8, u8)>, ARect, ARect, ARect, usize, usize),
631{
632 let sh_top = (102u8, 1u8, Color::Indexed(7), Color::Reset);
633 let sh_other = (24u8, 2u8, Color::Indexed(7), Color::Reset);
634 let sh_close = (214u8, 1u8, Color::Indexed(7), Color::Reset);
635
636 for n in 0..cell_h as usize + 2 {
637 for m in 0..cell_w as usize + 2 {
638 if n != 0 && n != cell_h as usize + 1 && m != 0 && m != cell_w as usize + 1 {
639 continue;
640 }
641 let rsh;
642 if n == 0 {
643 if m as u16 <= cell_w {
644 rsh = &sh_top;
645 } else {
646 rsh = &sh_close;
647 }
648 } else {
649 rsh = &sh_other;
650 }
651 let (s0, s1, s2, texidx, symidx) = render_helper(
652 cell_w + 2,
653 PointF32 { x: rx, y: ry },
654 n * (cell_w as usize + 2) + m,
655 rsh,
656 PointU16 { x: 0, y: 0 },
657 true,
658 );
659 let fc = rsh.2.get_rgba();
660 let bc = None;
661 f(&fc, &bc, s0, s1, s2, texidx, symidx);
662 }
663 }
664}
665
666#[cfg(any(feature = "sdl", target_arch = "wasm32"))]
667pub fn render_logo<F>(srx: f32, sry: f32, spw: u32, sph: u32, rd: &mut Rand, stage: u32, mut f: F)
668where
669 F: FnMut(&(u8, u8, u8, u8), ARect, ARect, usize, usize),
670{
671 let rx = srx * 1.0;
672 let ry = sry * 1.0;
673 for y in 0usize..PIXEL_LOGO_HEIGHT {
674 for x in 0usize..PIXEL_LOGO_WIDTH {
675 let sci = y * PIXEL_LOGO_WIDTH + x;
676 let symw = PIXEL_SYM_WIDTH.get().expect("lazylock init") / rx;
677 let symh = PIXEL_SYM_HEIGHT.get().expect("lazylock init") / ry;
678
679 let (_s0, s1, mut s2, texidx, symidx) = render_helper(
680 PIXEL_LOGO_WIDTH as u16,
681 PointF32 { x: rx, y: ry },
682 sci,
683 &(
684 PIXEL_LOGO[sci * 3],
685 PIXEL_LOGO[sci * 3 + 2],
686 Color::Indexed(PIXEL_LOGO[sci * 3 + 1]),
687 Color::Reset,
688 ),
689 PointU16 {
690 x: spw as u16 / 2 - (PIXEL_LOGO_WIDTH as f32 / 2.0 * symw) as u16,
691 y: sph as u16 / 2 - (PIXEL_LOGO_HEIGHT as f32 / 2.0 * symh) as u16,
692 },
693 false,
694 );
695 let fc = Color::Indexed(PIXEL_LOGO[sci * 3 + 1]).get_rgba();
696
697 let randadj = 12 - (rd.rand() % 24) as i32;
698 let sg = LOGO_FRAME as u8 / 3;
699 let r: u8;
700 let g: u8;
701 let b: u8;
702 let a: u8;
703 if stage <= sg as u32 {
704 r = (stage as u8).saturating_mul(10);
705 g = (stage as u8).saturating_mul(10);
706 b = (stage as u8).saturating_mul(10);
707 a = 255;
708 s2.x += randadj;
709 } else if stage <= sg as u32 * 2 {
710 r = fc.0;
711 g = fc.1;
712 b = fc.2;
713 a = 255;
714 } else {
715 let cc = (stage as u8 - sg * 2).saturating_mul(10);
716 r = fc.0.saturating_sub(cc);
717 g = fc.1.saturating_sub(cc);
718 b = fc.2.saturating_sub(cc);
719 a = 255;
720 }
721 f(&(r, g, b, a), s1, s2, texidx, symidx);
722 }
723 }
724}
725