Compare commits

..

No commits in common. "228cdfec9ec067ae6c266abdf320371024c775f8" and "9b347b9e76778ac2ead0ea712d73f1068c51ccbf" have entirely different histories.

6 changed files with 35 additions and 46 deletions

Binary file not shown.

View File

@ -1,21 +1,17 @@
# DMGTRIS
DMGTRIS is a block stacking game for the original game boy written in assembly.
This is a block stacking game for the game boy using the TGM2 era ARS rotation rules (no floor kicks, but with sonic drop) for the original black and white game boy written in assembly.
The game is heavily inspired by the TGM series of games and has the following features:
- TLS (ghost piece) until 1G speeds.
- IRS (initial rotation system).
- IHS (initial hold system) as well as holds.
- Faithful implementations of concepts such are lock delay, piece spawn delay and DAS.
- Several RNG options available. You can choose between pure RNG, 4 history with 4 retries, 4 history with 6 retries, 4 history with infinite retries, or a 35bag with 4 history and 6 retries with drought prevention.
- A choice between sonic drop (pressing up grounds the piece but does not lock it), hard drop (pressing up locks the piece), or neither (pressing up does nothing at all.)
- A choice between traditional ARS for rotation, or TGM3 era ARS with extra kicks.
- Scoring is a hybrid between TGM1 and TGM2.
- A speed curve reminiscent of TGM, starting slightly faster and skipping the awkward speed reset. The game continues infinitely... But so does the speed increase.
- A rock solid 60FPS with a traditional 20x10 grid.
It supports TLS (until 1G), IRS, IHS, ARE, Lock Delay, and other such buzz words.
Scoring is somewhat like TGM1 within the bounds of what the Z80 CPU can calculate quickly enough.
## Modes
There are eight available game modes:
The speed curve starts at 1/16G, so slightly faster than TGM, and goes smoothly toward 20G at level 500. There is no speed drop at level 200, and the game doesn't end at level 999. 20G mode starts at TGM1 speeds, then transitions to TGM2 speeds, TGM3 speeds, and finally it goes beyond even shirase mode.
The Randomizer uses a TGM2-style 4-history randomizer preloaded with SSZZ, and with 4 rerolls by default. This number can be changed and is shown at the top right of the playfield.
The game itself runs at a constant 60fps as well as at the traditional 20 row visible grid.
There are five available game modes:
- TGM1: 4 history w/ 4 rerolls, never start with O, S or Z.
- TGM2: 4 history w/ 6 rerolls, never start with O, S or Z. Sonic drop.
- TGM3: 4 history w/ 6 rerolls and drought protection, never start with O, S or Z. Sonic drop. Extra floor and wall kicks for I and T pieces.
@ -26,26 +22,6 @@ There are eight available game modes:
- EAWY: EASY but with hard drop.
## Scoring
After each piece is dropped, a check is made:
### No line clear
Combo is reset to 1 and no points are awarded.
### Lines were cleared
Lines = Lines cleared. In TGM3 modes, 3 lines are worth 4, and 4 lines are worth 6.
Level = The level before the lines were cleared.
Soft = Amount of frames the down button was held during this piece + 10 if the piece was sonic or hard dropped.
Combo = Old combo + (2 x Lines) - 2
ScoreIncrement = ((Level + Lines) >> 4 + 1 + Soft) x Combo x Lines.
ScoreIncrement points are then awarded.
## Playing
You can build the game yourself, or use the binary [here](https://git.villadelfia.org/villadelfia/dmgtris/raw/branch/master/DMGTRIS.GB) or [here](https://github.com/Villadelfia/DMGTRIS/raw/master/DMGTRIS.GB).
@ -66,7 +42,7 @@ Please do not try running it on older emulators such as VBA, since this game use
- B — Rotate 2
- Select — Hold
- Start — Pause
- Up — Sonic/Hard drop
- Up — Sonic drop
- Down — Soft drop/Lock
- Left/Right — Move
@ -76,21 +52,23 @@ Please do not try running it on older emulators such as VBA, since this game use
## Building
The game can be built using gnu make and the RGBDS toolchain.
This game was created using Game Boy assembly using the RGBDS toolchain and GNU make.
## Issues
- In very rare cases the frame time in TGM3 and TGW3 modes can be exceeded due to the way the RNG for those modes works. When this happens, the screen will appear slightly glitched for 1 frame but no frame drops will occur. This issues is fundamentally impossible to completely avoid though more optimization may cause it to occur less frequently.
- In frames where both rotation and translation happens at the same time, the ghost piece may be drawn one space too high or too low. Fixing this would require calculating the distance-to-stack twice and that wouldn't be possible on the original game boy. This issue is only a visual glitch and only for one frame sometimes. It will not be fixed.
## Future Goals
- Improve main menu.
- Decouple rotation rules, rng rules, and speed curve from each other.
- Add 20G mode.
- Multiplayer.
- Multiplayer with items.
- Colorization.
- Three previews for TGM3 modes.
- ...
## License
Copyright (C) 2023 - Randy Thiemann <randy.thiemann@gmail.com>

Binary file not shown.

View File

@ -529,7 +529,7 @@ Tiles::
DB $00,$00,$00,$00,$44,$44,$CA,$CA
DB $4A,$4A,$4A,$4A,$E4,$E4,$00,$00
DB $00,$00,$00,$00,$CC,$CC,$22,$22
DB $44,$44,$82,$82,$EC,$EC,$00,$00
DB $44,$44,$88,$88,$EE,$EE,$00,$00
DB $00,$00,$00,$00,$04,$04,$0A,$0A
DB $0E,$0E,$0A,$0A,$0A,$0A,$00,$00
TilesEnd::

View File

@ -64,10 +64,6 @@ RNGInit::
ld bc, 7
call UnsafeMemCopy
; Start with a random piece held.
call Next7Piece
ldh [hHeldPiece], a
; If we're in HELL mode, we don't care about anything but a random piece to start with.
ldh a, [hSimulationMode]
cp a, MODE_HELL

View File

@ -39,7 +39,7 @@ hCurrentPiece:: ds 1
hCurrentPieceX:: ds 1
hCurrentPieceY:: ds 1
hCurrentPieceRotationState:: ds 1
hHeldPiece:: ds 1
hHeldPiece: ds 1
hHoldSpent:: ds 1
hSkipJingle: ds 1
hMode: ds 1
@ -91,7 +91,9 @@ SwitchToGameplay::
call LevelInit
call FieldInit
; We don't start with hold spent.
; We don't start with a held piece.
ld a, PIECE_NONE
ldh [hHeldPiece], a
xor a, a
ldh [hHoldSpent], a
@ -462,6 +464,8 @@ gameOverMode:
call ScoreInit
call LevelInit
call FieldInit
ld a, PIECE_NONE
ldh [hHeldPiece], a
xor a, a
ldh [hHoldSpent], a
ld a, MODE_LEADY
@ -582,7 +586,18 @@ DoHold:
ldh [hCurrentPieceRotationState], a
.doHoldOperation
ld b, a
; If we're not holding a piece, hold the current piece and get a new one.
ldh a, [hHeldPiece]
cp a, PIECE_NONE
jr nz, :+
ldh a, [hCurrentPiece]
ldh [hHeldPiece], a
ldh a, [hNextPiece]
ldh [hCurrentPiece], a
call GetNextPiece
ret
: ld b, a
ldh a, [hCurrentPiece]
ldh [hHeldPiece], a
ld a, b