~sircmpwn/tetrominoes

1f7cd7a4baee482b09f07420e8f61d052d366248 — Drew DeVault 2 years ago ee5c067
Initial work on line clearing
3 files changed, 66 insertions(+), 14 deletions(-)

A assets/clear.png
M main.ha
M update.ha
A assets/clear.png => assets/clear.png +0 -0
M main.ha => main.ha +28 -4
@@ 15,6 15,7 @@ type texture = struct {
type gamestate = enum {
	SPAWN,
	FALL,
	CLEAR,
};

type state = struct {


@@ 23,6 24,7 @@ type state = struct {
	render: *sdl2::renderer,
	piece: texture,
	scene: texture,
	clear: texture,
	input: input,
	board: board,



@@ 32,6 34,7 @@ type state = struct {
	speed: u32,
	faster: bool,
	lastcolor: color,
	clearframe: int,
};

export fn main() void = {


@@ 63,16 66,14 @@ fn run() (void | sdl2::error) = {
		render = render,
		piece = load_texture(render, "assets/piece.png")?,
		scene = load_texture(render, "assets/concert.png")?,
		clear = load_texture(render, "assets/clear.png")?,
		board = board {
			offs_x = 88,
			offs_y = 74,
			...
		},
		rand = random::init(seed),
		state = gamestate::SPAWN,
		speed = 250,
		next = sdl2::get_ticks() + 250,
		lastcolor = color::EMPTY,
		...
	};
	defer sdl2::destroy_texture(state.piece.tex);


@@ 96,7 97,7 @@ fn run() (void | sdl2::error) = {
		sdl2::game_controller_close(c);
	};

	do_spawn(&state);
	do_spawn(&state, sdl2::get_ticks());

	for (state.run) {
		update(&state)?;


@@ 114,10 115,33 @@ fn draw(state: *state) (void | sdl2::error) = {
		w = 640,
		h = 480,
	})?;

	draw_board(state, &state.board)?;

	switch (state.state) {
	case gamestate::CLEAR =>
		draw_clear(state);
	case => void; // No special drawing required
	};

	sdl2::render_present(state.render);
};

fn draw_clear(state: *state) void = {
	// TODO: Expand me
	sdl2::render_copy(state.render, state.clear.tex, &sdl2::rect{
		x = state.clearframe * 4,
		y = 0,
		w = 4,
		h = 4,
	}, &sdl2::rect{
		x = 0,
		y = 0,
		w = 8,
		h = 8,
	})?;
};

fn load_texture(render: *sdl2::renderer, path: str) (texture | sdl2::error) = {
	const tex = image::load_texture(render, path)?;
	let width = 0, height = 0;

M update.ha => update.ha +38 -10
@@ 59,19 59,16 @@ fn update(state: *state) (void | sdl2::error) = {
	if (state.next <= now) {
		switch (state.state) {
		case gamestate::SPAWN =>
			do_spawn(state);
			do_spawn(state, now);
		case gamestate::FALL =>
			do_fall(state);
		};
		if (state.faster) {
			state.next = now + 100;
		} else {
			state.next = now + state.speed;
			do_fall(state, now);
		case gamestate::CLEAR =>
			do_clear(state, now);
		};
	};
};

fn do_spawn(state: *state) void = {
fn do_spawn(state: *state, now: u32) void = {
	let next = random::next(&state.rand): size % len(tetrominoes);
	let col = color::EMPTY;
	for (true) {


@@ 100,9 97,10 @@ fn do_spawn(state: *state) void = {
	state.board.active_y = -height;
	state.board.active_x = BOARD_WIDTH / 2 - width / 2;
	state.state = gamestate::FALL;
	schedule_tick(state, now);
};

fn do_fall(state: *state) void = {
fn do_fall(state: *state, now: u32) void = {
	let height = 0;
	activesize(state, null, &height);
	const active = &state.board.active[state.board.active_i];


@@ 110,7 108,21 @@ fn do_fall(state: *state) void = {
		state.board.active_y += 1;
	} else {
		commit(state);
		state.state = gamestate::SPAWN;
	};
	schedule_tick(state, now);
};

fn do_clear(state: *state, now: u32) void = {
	state.clearframe += 1;
	state.clearframe %= 12;
	state.next = now + (state.speed / 6);
};

fn schedule_tick(state: *state, now: u32) void = {
	if (state.faster) {
		state.next = now + 100;
	} else {
		state.next = now + state.speed;
	};
};



@@ 130,6 142,22 @@ fn commit(state: *state) void = {
			board[board_ix] = active[active_ix];
		};
	};

	static let clearbuf: [TETROMINO_HEIGHT]int = [0...];
	let clear = clearbuf[..0];
	state.state = gamestate::SPAWN;
	for (let y = active_y; y < BOARD_HEIGHT; y += 1)
	for (let x = 0, sum = 0; x < BOARD_WIDTH; x += 1) {
		const board_ix = y * BOARD_WIDTH + x;
		const cell = state.board.cells[board_ix];
		if (cell != 0) {
			sum += 1;
		};
		if (sum == BOARD_WIDTH) {
			state.state = gamestate::CLEAR;
			static append(clear, y);
		};
	};
};

fn move_left(state: *state) void = {