ggdt/examples/balls_v2/src/states.rs
Gered 07f2b13f68 large amount of bitmap graphics rework
this is an unfortunately large commit. probably should've been broken
up into multiple smaller ones.

i decided to revert some earlier preparatory work i had done to organize
graphics functionality into two main streams: "indexed" and "rgb". this
was going to result in two completely different Bitmap structs which
were going to be largely similar and as i thought about it more, i
realized my earlier thinking that i wouldn't be able to generify the
Bitmap struct based on pixel-depth was actually not correct.

so, this commit re-works things significantly in a way which i think
is better but probably still not perfect. basically, we have one
Bitmap struct which provides a lot of generic functionality, but also
specialized implementations based on pixel-depth and this is now what is
separated out into graphics::bitmap::indexed and graphics::bitmap::rgb.

but the rest of the graphics functionality is not separated out by
module like this any longer.

note that i've still kept the GeneralBitmap trait and implementations.
i was originally thinking i could get rid of this since i'd now made
Bitmap generic over pixel-depth, but doing so would require me to
rename the common/general blit methods to avoid a name collision with
the specialized implementations (since they would both exist on the
same types now). and i did not like that. i dunno, maybe i will change
my mind later.
2023-03-11 16:58:13 -05:00

103 lines
2.7 KiB
Rust

use ggdt::prelude::*;
use crate::*;
pub const BALL_SIZE: i32 = 8;
pub const NUM_BALLS: usize = 32;
pub const NUM_BALL_SPRITES: usize = 16;
pub struct Context {
pub delta: f32,
pub system: System<DosLike>,
pub font: BitmaskFont,
pub sprites: Vec<IndexedBitmap>,
pub entities: Entities,
pub event_publisher: EventPublisher<Event>,
}
pub struct Game {
pub context: Context,
pub component_systems: ComponentSystems<Context, Context>,
pub event_listeners: EventListeners<Event, Context>,
}
impl Game {
pub fn new(mut system: System<DosLike>) -> Result<Self> {
let font = BitmaskFont::new_vga_font()?;
let (balls_bmp, balls_palette) = IndexedBitmap::load_pcx_file(Path::new("./assets/balls.pcx"))?;
system.res.palette = balls_palette.clone();
let mut sprites = Vec::new();
for i in 0..NUM_BALL_SPRITES {
let mut sprite = IndexedBitmap::new(BALL_SIZE as u32, BALL_SIZE as u32)?;
sprite.blit_region(
IndexedBlitMethod::Solid,
&balls_bmp,
&Rect::new(i as i32 * BALL_SIZE as i32, 0, BALL_SIZE as u32, BALL_SIZE as u32),
0,
0,
);
sprites.push(sprite);
}
let entities = Entities::new();
let mut component_systems = ComponentSystems::new();
let event_publisher = EventPublisher::new();
let mut event_listeners = EventListeners::new();
init_component_system(&mut component_systems);
init_event_listeners(&mut event_listeners);
Ok(Game {
context: Context {
delta: 0.0,
system,
font,
sprites,
entities,
event_publisher,
},
component_systems,
event_listeners,
})
}
pub fn do_events(&mut self) {
self.event_listeners.take_queue_from(&mut self.context.event_publisher);
self.event_listeners.dispatch_queue(&mut self.context);
}
}
pub struct SimulationState;
impl AppState<Game> for SimulationState {
fn update(&mut self, _state: State, context: &mut Game) -> Option<StateChange<Game>> {
if context.context.system.res.keyboard.is_key_up(Scancode::S) {
context.do_events();
context.component_systems.update(&mut context.context);
}
if context.context.system.res.keyboard.is_key_pressed(Scancode::Escape) {
return Some(StateChange::Pop(1));
}
None
}
fn render(&mut self, _state: State, context: &mut Game) {
context.context.system.res.video.clear(2);
context.component_systems.render(&mut context.context);
context.context.system.res.video.print_string("hello, world!", 10, 10, FontRenderOpts::Color(15), &context.context.font);
}
fn transition(&mut self, _state: State, _context: &mut Game) -> bool {
true
}
fn state_change(&mut self, new_state: State, _old_state: State, context: &mut Game) {
if new_state == State::Pending {
init_entities(&mut context.context.entities);
}
}
}