Skip to content

Commit

Permalink
Merge pull request #56 from Brian-Catcow-B/update-ggez-version
Browse files Browse the repository at this point in the history
Update ggez version
  • Loading branch information
Brian-Catcow-B authored Oct 31, 2021
2 parents 5005e00 + 801e5ec commit 584f438
Show file tree
Hide file tree
Showing 14 changed files with 1,128 additions and 783 deletions.
1,534 changes: 933 additions & 601 deletions Cargo.lock

Large diffs are not rendered by default.

5 changes: 2 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ opt-level = 3


[dependencies]
# ggez = "0.5"
ggez = { git = "https://github.com/Brian-Catcow-B/ggez.git", branch = "master-custom-gamepads" }
ggez = "0.6"
rand = "0.7.3"
gilrs = "0.7.4"
glam = "0.19.0"
21 changes: 8 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,27 @@ Tetrisn-t (python version) rewritten in Rust, better.
Binaries for Windows and Linux are included in each tagged release.

# Build
Download and install cargo, then set rustup default to 1.47.0 to avoid an error in the ggez library introduced with rust 1.48.0 by running
```
rustup default 1.47.0
```
then build with
Download and install cargo, then build with
```
cargo build --release
```
and find the resulting binary in `./target/release/`

Google any errors that occur, if they do.
Google any errors that occur, if they do (there are a few necessary libraries).

# Gamepads
# Controls
In the "Controls" menu, keyboard control schemes and setting players to use gamepads are both possible and mostly self explanatory.
It is possible to connect multiple keyboards to one PC and use both separately, but the inputs show up as the same, so the keyboard control schemes are not allowed to overlap, even across separate keyboards.
There is a check in place, which will give a notice when a key is attempted to be re-used.
Unfortunately, these settings are not saved yet, so they will have to be reconfigured each time the program is opened; eventually, saved control schemes will be implemented.
Unfortunately, these settings are not saved yet, so they will have to be reconfigured each time the program is opened.

Setting a player to use a gamepad is easily done in the "Controls" menu by pressing 'G', as it states.
The game decides which specific gamepad controls which player by assigning a gamepad's id to the first player that doesn't yet have an assigned gamepad id as soon as an unassigned gamepad has a button/axis pressed during gameplay.
Because of weird coding stuff, this is done each game no matter what, but might eventually be extended to be the entire instance of the program.
The game decides which gamepad controls which player by assigning gamepads to players as inputs are made.
Due to easier coding, this is done each game no matter what.

## Custom Layouts and Obscure Compatibility
## Custom Gamepad Layouts and Obscure Compatibility
### Windows
Because ggez only supports xinput, a program like rewasd is required for non-xinput controllers, which allows remapping of non-xinput controllers to act as an xinput controller.
rewasd does cost money (unless you download an earlier version from 3rd party), but here's an alternative: http://ds4windows.com/
Because ggez only supports xinput for Windows, a program like rewasd is required for non-xinput controllers, which allows remapping of non-xinput controllers to act as an xinput controller.

### Linux
For linux, this program uses SDL2 gamepad configurations for controllers.
Expand Down
2 changes: 1 addition & 1 deletion src/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ impl Control {
}

// this is run once every frame and passes control off to whichever state the game is in
impl EventHandler for Control {
impl EventHandler<ggez::GameError> for Control {
fn update(&mut self, ctx: &mut Context) -> GameResult<()> {
const DESIRED_FPS: u32 = 60;

Expand Down
178 changes: 94 additions & 84 deletions src/game.rs

Large diffs are not rendered by default.

34 changes: 17 additions & 17 deletions src/game/board.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,14 @@ impl BoardHandler {
pub fn new(board_width: u8, board_height: u8, num_players: u8, mode: GameMode) -> Self {
// determine some rules based on gamemode
let (board_height_buffer, spawn_row) = match mode {
GameMode::None => panic!(BH_MODE_NONE),
GameMode::None => unreachable!("{}", BH_MODE_NONE),
GameMode::Rotatris => (0, (board_height - 1) / 2),
GameMode::Classic => (2, 0),
};
let mut classic: Option<BoardClassic> = None;
let mut rotatris: Option<BoardRotatris> = None;
match mode {
GameMode::None => panic!(BH_MODE_NONE),
GameMode::None => unreachable!("{}", BH_MODE_NONE),
GameMode::Rotatris => {
rotatris = Some(BoardRotatris::new(board_width, spawn_row, num_players))
}
Expand All @@ -86,31 +86,31 @@ impl BoardHandler {
// get...
pub fn get_width(&mut self) -> u8 {
match self.mode {
GameMode::None => panic!(BH_MODE_NONE),
GameMode::None => unreachable!("{}", BH_MODE_NONE),
GameMode::Classic => self.classic.as_mut().expect(BH_WRONG_MODE).width,
GameMode::Rotatris => self.rotatris.as_mut().expect(BH_WRONG_MODE).board_size,
}
}

pub fn get_height(&mut self) -> u8 {
match self.mode {
GameMode::None => panic!(BH_MODE_NONE),
GameMode::None => unreachable!("{}", BH_MODE_NONE),
GameMode::Classic => self.classic.as_mut().expect(BH_WRONG_MODE).height,
GameMode::Rotatris => self.rotatris.as_mut().expect(BH_WRONG_MODE).board_size,
}
}

pub fn get_height_buffer(&mut self) -> u8 {
match self.mode {
GameMode::None => panic!(BH_MODE_NONE),
GameMode::None => unreachable!("{}", BH_MODE_NONE),
GameMode::Classic => self.classic.as_mut().expect(BH_WRONG_MODE).height_buffer,
GameMode::Rotatris => 0u8,
}
}

pub fn get_active_from_pos(&mut self, y: u8, x: u8) -> bool {
match self.mode {
GameMode::None => panic!(BH_MODE_NONE),
GameMode::None => unreachable!("{}", BH_MODE_NONE),
GameMode::Classic => {
self.classic.as_mut().expect(BH_WRONG_MODE).matrix[y as usize][x as usize].active
}
Expand All @@ -122,7 +122,7 @@ impl BoardHandler {

pub fn get_empty_from_pos(&mut self, y: u8, x: u8) -> bool {
match self.mode {
GameMode::None => panic!(BH_MODE_NONE),
GameMode::None => unreachable!("{}", BH_MODE_NONE),
GameMode::Classic => {
self.classic.as_mut().expect(BH_WRONG_MODE).matrix[y as usize][x as usize].empty
}
Expand All @@ -134,7 +134,7 @@ impl BoardHandler {

pub fn get_player_from_pos(&mut self, y: u8, x: u8) -> u8 {
match self.mode {
GameMode::None => panic!(BH_MODE_NONE),
GameMode::None => unreachable!("{}", BH_MODE_NONE),
GameMode::Classic => {
self.classic.as_mut().expect(BH_WRONG_MODE).matrix[y as usize][x as usize].player
}
Expand All @@ -146,7 +146,7 @@ impl BoardHandler {

pub fn get_shape_from_pos(&mut self, y: u8, x: u8) -> Shapes {
match self.mode {
GameMode::None => panic!(BH_MODE_NONE),
GameMode::None => unreachable!("{}", BH_MODE_NONE),
GameMode::Classic => {
self.classic.as_mut().expect(BH_WRONG_MODE).matrix[y as usize][x as usize].shape
}
Expand All @@ -158,7 +158,7 @@ impl BoardHandler {

pub fn get_shape_from_player(&mut self, player: u8) -> Shapes {
match self.mode {
GameMode::None => panic!(BH_MODE_NONE),
GameMode::None => unreachable!("{}", BH_MODE_NONE),
GameMode::Classic => {
self.classic.as_mut().expect(BH_WRONG_MODE).vec_active_piece[player as usize].shape
}
Expand All @@ -174,7 +174,7 @@ impl BoardHandler {

pub fn get_fall_delay_from_level(&mut self, level: u8) -> u8 {
match self.mode {
GameMode::None => panic!(BH_MODE_NONE),
GameMode::None => unreachable!("{}", BH_MODE_NONE),
GameMode::Classic => FALL_DELAY_VALUES_CLASSIC[level as usize],
GameMode::Rotatris => FALL_DELAY_VALUES_ROTATRIS[level as usize],
}
Expand All @@ -188,7 +188,7 @@ impl BoardHandler {
spawn_piece_shape: Shapes,
) -> (bool, bool) {
match self.mode {
GameMode::None => panic!(BH_MODE_NONE),
GameMode::None => unreachable!("{}", BH_MODE_NONE),
GameMode::Classic => self
.classic
.as_mut()
Expand All @@ -204,7 +204,7 @@ impl BoardHandler {

pub fn attempt_clear(&mut self, level: u8) -> (u8, u32) {
match self.mode {
GameMode::None => panic!(BH_MODE_NONE),
GameMode::None => unreachable!("{}", BH_MODE_NONE),
GameMode::Classic => self
.classic
.as_mut()
Expand All @@ -220,7 +220,7 @@ impl BoardHandler {

pub fn attempt_piece_movement(&mut self, m: Movement, p: u8) -> (bool, bool) {
match self.mode {
GameMode::None => panic!(BH_MODE_NONE),
GameMode::None => unreachable!("{}", BH_MODE_NONE),
GameMode::Classic => self
.classic
.as_mut()
Expand All @@ -236,7 +236,7 @@ impl BoardHandler {

pub fn attempt_rotate_board(&mut self, rd: Movement) -> bool {
match self.mode {
GameMode::None => panic!(BH_MODE_NONE),
GameMode::None => unreachable!("{}", BH_MODE_NONE),
GameMode::Classic => {
println!("[!] `attempt_rotate_board` called but mode is GameMode::Classic");
false
Expand All @@ -251,7 +251,7 @@ impl BoardHandler {

pub fn playerify_piece(&mut self, player: u8) {
match self.mode {
GameMode::None => panic!(BH_MODE_NONE),
GameMode::None => unreachable!("{}", BH_MODE_NONE),
GameMode::Classic => self
.classic
.as_mut()
Expand Down Expand Up @@ -982,7 +982,7 @@ impl BoardRotatris {
}
}
Gravity::Invalid => {
panic!("[!] Gravity::Invalid attempted to be used in `should_lock()`")
unreachable!("[!] Gravity::Invalid attempted to be used in `should_lock()`")
}
}
}
Expand Down
28 changes: 16 additions & 12 deletions src/game/piece.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::game::board::Gravity;
use crate::movement::Movement;

use std::convert::TryFrom;

#[repr(u8)]
#[derive(PartialEq, Eq, Copy, Clone)]
pub enum Shapes {
Expand All @@ -14,17 +16,19 @@ pub enum Shapes {
None,
}

impl From<u8> for Shapes {
fn from(value: u8) -> Shapes {
impl TryFrom<u8> for Shapes {
type Error = &'static str;

fn try_from(value: u8) -> Result<Self, Self::Error> {
match value {
0 => Shapes::I,
1 => Shapes::O,
2 => Shapes::T,
3 => Shapes::J,
4 => Shapes::S,
5 => Shapes::L,
6 => Shapes::Z,
_ => panic!("Unknown Shapes value: {}", value),
0 => Ok(Shapes::I),
1 => Ok(Shapes::O),
2 => Ok(Shapes::T),
3 => Ok(Shapes::J),
4 => Ok(Shapes::S),
5 => Ok(Shapes::L),
6 => Ok(Shapes::Z),
_ => Err("Conversion failed (u8 -> Shapes): Invalid value"),
}
}
}
Expand Down Expand Up @@ -234,7 +238,7 @@ impl Piece {
}
};
if piece_copy.shape == Shapes::None {
panic!("[!] Error: `Piece::spawn_pos()` called with shape: Shapes::None");
unreachable!("[!] Error: `Piece::spawn_pos()` called with shape: Shapes::None");
} else if piece_copy.shape == Shapes::O {
piece_copy.positions
} else {
Expand All @@ -252,7 +256,7 @@ impl Piece {
piece_copy.positions = piece_copy.rotate(false);
piece_copy.piece_pos(Movement::Down)
}
Gravity::Invalid => panic!("[!] Gravity::Invalid passed into `spawn_pos()`"),
Gravity::Invalid => unreachable!("[!] Gravity::Invalid passed into `spawn_pos()`"),
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/game/player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use crate::game::{DETECT_GAMEPAD_AXIS_THRESHOLD, UNDETECT_GAMEPAD_AXIS_THRESHOLD
use crate::inputs::{Input, KeyboardControlScheme};
use crate::movement::Movement;

use std::convert::TryFrom;

pub const SPAWN_DELAY: i16 = 20i16;

pub struct Player {
Expand Down Expand Up @@ -49,7 +51,7 @@ impl Player {
break;
}
}
Shapes::from(rand % 7)
Shapes::try_from(rand % 7).expect("Unable to get random piece")
},
redraw_next_piece_flag: true,
fall_countdown: INITIAL_HANG_FRAMES,
Expand Down
4 changes: 2 additions & 2 deletions src/game/tile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,11 @@ const PLAYER_RGBA: [(u8, u8, u8, u8); NUM_PLAYERCOLORS as usize] = [
(80u8, 200u8, 60u8, 0xffu8),
(230u8, 230u8, 50u8, 0xffu8),
(220u8, 150u8, 70u8, 0xffu8),
(160u8, 230u8, 250u8, 0xffu8),
(125u8, 125u8, 125u8, 0xffu8),
(230u8, 100u8, 210u8, 0xffu8),
];

const BASE_PLAYER_COLOR: (u8, u8, u8, u8) = (20u8, 80u8, 150u8, 0xffu8);
const BASE_PLAYER_COLOR: (u8, u8, u8, u8) = (25u8, 80u8, 212u8, 0xffu8);

#[derive(Copy, Clone)]
pub struct Tile {
Expand Down
16 changes: 7 additions & 9 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use ggez::event;
use ggez::graphics;
use ggez::input::gamepad::gilrs;
use ggez::ContextBuilder;

// file systems stuff
Expand Down Expand Up @@ -31,7 +31,7 @@ fn main() {
context = context.add_resource_path(path);
}

let (ctx, event_loop) = &mut context.build().expect("[!] Failed to build context");
let (mut ctx, event_loop) = context.build().expect("[!] Failed to build context");

// custom controller setup stuffs
let mut gilrs_builder = gilrs::GilrsBuilder::new().add_included_mappings(false);
Expand All @@ -55,17 +55,15 @@ fn main() {
ctx.gamepad_context = Box::new(GilrsGamepadContext::from(gilrs_builder.build().unwrap()));

// set window size
graphics::set_resizable(ctx, true).expect("[!] Failed to set window to resizable");
graphics::set_drawable_size(ctx, 800.0, 600.0).expect("[!] Failed to resize window");
graphics::set_resizable(&mut ctx, true).expect("[!] Failed to set window to resizable");
graphics::set_drawable_size(&mut ctx, 800.0, 600.0).expect("[!] Failed to resize window");

// make it not blurry
graphics::set_default_filter(ctx, graphics::FilterMode::Nearest);
graphics::set_default_filter(&mut ctx, graphics::FilterMode::Nearest);

// create an instance of the event handler
let mut control = Control::new(ctx);
let control = Control::new(&mut ctx);

// loop that controls the ProgramState
if let Err(e) = event::run(ctx, event_loop, &mut control) {
println!("[!] Error occured: {}", e);
}
ggez::event::run(ctx, event_loop, control)
}
12 changes: 6 additions & 6 deletions src/menu/choosemode.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use ggez::graphics::{self, DrawParam, Text};
use ggez::nalgebra::Point2;
use ggez::mint::Point2;
use ggez::Context;

use crate::game::GameMode;
Expand Down Expand Up @@ -90,14 +90,14 @@ impl ChooseModeMenu {
vertical_position: f32,
window_dimensions: &(f32, f32),
) {
let (text_width, text_height) = text_var.dimensions(ctx);
let text_var_dimensions = text_var.dimensions(ctx);
graphics::draw(
ctx,
text_var,
DrawParam::new().dest(Point2::new(
(window_dimensions.0 - text_width as f32) / 2.0,
(window_dimensions.1 - text_height as f32) * vertical_position,
)),
DrawParam::new().dest(Point2::from_slice(&[
(window_dimensions.0 - text_var_dimensions.w as f32) / 2.0,
(window_dimensions.1 - text_var_dimensions.h as f32) * vertical_position,
])),
)
.unwrap();
}
Expand Down
Loading

0 comments on commit 584f438

Please sign in to comment.