dmgtris/src/rng.asm

478 lines
8.5 KiB
NASM
Raw Normal View History

2023-10-21 15:28:38 +00:00
; DMGTRIS
; Copyright (C) 2023 - Randy Thiemann <randy.thiemann@gmail.com>
; This program is free software: you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
; You should have received a copy of the GNU General Public License
; along with this program. If not, see <https://www.gnu.org/licenses/>.
2023-10-13 06:38:10 +00:00
IF !DEF(RNG_ASM)
DEF RNG_ASM EQU 1
INCLUDE "globals.asm"
2023-10-21 18:49:52 +00:00
SECTION "High RNG Variables", HRAM
hRNGSeed: ds 4
2023-10-22 18:28:08 +00:00
hPieceHistory: ds 4
2023-10-21 18:49:52 +00:00
hNextPiece:: ds 1
2023-10-26 13:58:08 +00:00
hUpcomingPiece1:: ds 1
hUpcomingPiece2:: ds 1
2023-10-13 06:38:10 +00:00
2023-10-22 18:28:08 +00:00
SECTION "TGM3 RNG Variables", WRAM0
wTGM3Bag: ds 35
wTGM3Droughts: ds 7
wTGM3GeneratedIdx: ds 1
wTGM3WorstDroughtIdx: ds 1
2023-10-10 08:32:24 +00:00
section "RNG Functions", ROM0
2023-11-07 03:51:54 +00:00
HarvestEntropy::
2023-11-07 08:14:43 +00:00
ld hl, $C000
2023-11-07 04:30:03 +00:00
ld de, $E000
.loop
ldh a, [hRNGSeed]
xor a, [hl]
2023-11-07 08:14:43 +00:00
inc hl
2023-11-07 04:30:03 +00:00
ldh [hRNGSeed], a
ldh a, [hRNGSeed+1]
xor a, [hl]
2023-11-07 08:14:43 +00:00
inc hl
2023-11-07 04:30:03 +00:00
ldh [hRNGSeed+1], a
ldh a, [hRNGSeed+2]
xor a, [hl]
2023-11-07 08:14:43 +00:00
inc hl
2023-11-07 04:30:03 +00:00
ldh [hRNGSeed+2], a
ldh a, [hRNGSeed+3]
xor a, [hl]
2023-11-07 08:14:43 +00:00
inc hl
2023-11-07 04:30:03 +00:00
ldh [hRNGSeed+3], a
ld a, h
cp a, d
jr nz, .loop
ld a, l
cp a, e
jr nz, .loop
2023-11-07 03:51:54 +00:00
ret
2023-10-27 19:37:32 +00:00
; Snapshots the initial seed for a game, then initializes the history and piece queue.
2023-10-18 02:45:58 +00:00
RNGInit::
2023-10-13 06:38:10 +00:00
; Do some bit fuckery on the seed using the gameboy's free-running timers.
2023-11-07 03:51:54 +00:00
ld hl, rDIV
ldh a, [hRNGSeed]
2023-10-13 06:38:10 +00:00
xor a, [hl]
2023-10-21 18:49:52 +00:00
ldh [hRNGSeed], a
2023-11-07 03:51:54 +00:00
ldh a, [hRNGSeed+2]
2023-10-13 06:38:10 +00:00
xor a, [hl]
2023-10-21 18:49:52 +00:00
ldh [hRNGSeed+2], a
2023-10-13 06:38:10 +00:00
2023-11-07 03:51:54 +00:00
ld hl, rTIMA
ldh a, [hRNGSeed+1]
xor a, [hl]
ldh [hRNGSeed+1], a
ldh a, [hRNGSeed+3]
2023-10-13 06:38:10 +00:00
xor a, [hl]
2023-10-21 18:49:52 +00:00
ldh [hRNGSeed+3], a
2023-10-13 06:38:10 +00:00
2023-10-22 18:28:08 +00:00
; TGM3 vars
2023-10-28 17:04:55 +00:00
ld b, BANK_GAMEPLAY
rst RSTSwitchBank
2023-10-22 18:28:08 +00:00
ld de, sTGM3Bag
ld hl, wTGM3Bag
ld bc, 35
call UnsafeMemCopy
ld de, sTGM3Droughts
ld hl, wTGM3Droughts
ld bc, 7
call UnsafeMemCopy
2023-10-28 17:04:55 +00:00
rst RSTRestoreBank
2023-10-22 18:28:08 +00:00
; Start with a random non-S/Z piece held.
: call Next7Piece
cp a, PIECE_Z
jr z, :-
cp a, PIECE_S
jr z, :-
ldh [hHeldPiece], a
2023-10-22 18:28:08 +00:00
; If we're in HELL mode, we don't care about anything but a random piece to start with.
2023-10-23 10:16:16 +00:00
ld a, [wRNGModeState]
cp a, RNG_MODE_HELL
2023-10-22 18:28:08 +00:00
jr nz, .complexinit
call Next7Piece
2023-10-26 13:58:08 +00:00
ld [hUpcomingPiece2], a
2023-11-07 08:14:43 +00:00
call Next7Piece
ld [hUpcomingPiece1], a
call Next7Piece
ld [hNextPiece], a
xor a, a
ldh [hPieceHistory], a
ldh [hPieceHistory+1], a
ldh [hPieceHistory+2], a
ldh [hPieceHistory+3], a
2023-10-22 18:28:08 +00:00
ret
; Otherwise do complex init.
.complexinit
2023-10-13 06:38:10 +00:00
ld a, PIECE_Z
2023-10-21 18:53:54 +00:00
ldh [hPieceHistory], a
ldh [hPieceHistory+1], a
2023-10-22 18:28:08 +00:00
ldh [hPieceHistory+2], a
ldh [hPieceHistory+3], a
2023-10-23 10:16:16 +00:00
ld a, [wRNGModeState]
cp a, RNG_MODE_TGM1
2023-10-22 18:28:08 +00:00
jr z, :+
2023-10-13 06:38:10 +00:00
ld a, PIECE_S
2023-10-21 18:53:54 +00:00
ldh [hPieceHistory+2], a
ldh [hPieceHistory+3], a
2023-10-13 06:38:10 +00:00
; Get the first piece and make sure it's not Z, S or O.
2023-10-22 18:28:08 +00:00
: call Next7Piece
2023-10-13 06:38:10 +00:00
cp a, PIECE_Z
jr z, :-
cp a, PIECE_S
jr z, :-
cp a, PIECE_O
jr z, :-
2023-10-22 18:28:08 +00:00
; Save the generated piece and put it in the history.
2023-10-21 18:49:52 +00:00
ldh [hPieceHistory], a
2023-11-07 08:14:43 +00:00
ldh [hUpcomingPiece1], a
ldh [hUpcomingPiece2], a
2023-10-26 13:58:08 +00:00
; Generate the next 2 to fill up the queue.
call GetNextPiece
2023-10-27 19:37:32 +00:00
jp GetNextPiece
2023-10-13 06:38:10 +00:00
2023-10-22 18:28:08 +00:00
; Shift the generated piece into the history and save it.
ShiftHistory:
2023-10-26 13:58:08 +00:00
ld b, a
ldh a, [hUpcomingPiece1]
2023-10-22 18:28:08 +00:00
ldh [hNextPiece], a
2023-10-26 13:58:08 +00:00
ldh a, [hUpcomingPiece2]
ldh [hUpcomingPiece1], a
ld a, b
ldh [hUpcomingPiece2], a
2023-10-22 18:28:08 +00:00
ldh a, [hPieceHistory+2]
ldh [hPieceHistory+3], a
ldh a, [hPieceHistory+1]
ldh [hPieceHistory+2], a
ldh a, [hPieceHistory]
ldh [hPieceHistory+1], a
2023-10-26 13:58:08 +00:00
ldh a, [hUpcomingPiece2]
2023-10-22 18:28:08 +00:00
ldh [hPieceHistory], a
ret
2023-10-22 18:28:08 +00:00
; A random piece. Get fucked.
GetNextHellPiece:
call Next7Piece
2023-10-26 13:58:08 +00:00
jr ShiftHistory
2023-10-22 18:28:08 +00:00
; 4 history, 4 rerolls.
GetNextTGM1Piece:
ld a, 5
ld e, a
2023-10-22 18:28:08 +00:00
: dec e
jr z, :+
call Next7Piece
ld hl, hPieceHistory
cp a, [hl]
jr z, :-
inc hl
cp a, [hl]
jr z, :-
inc hl
cp a, [hl]
jr z, :-
inc hl
cp a, [hl]
jr z, :-
: jr ShiftHistory
; 4 history, 6 rerolls.
GetNextTGM2Piece:
ld a, 7
2023-10-21 19:25:57 +00:00
ld e, a
2023-10-22 18:28:08 +00:00
: dec e
jr z, :+
call Next7Piece
ld hl, hPieceHistory
cp a, [hl]
jr z, :-
inc hl
cp a, [hl]
jr z, :-
inc hl
cp a, [hl]
jr z, :-
inc hl
cp a, [hl]
jr z, :-
: jr ShiftHistory
2023-10-23 10:16:16 +00:00
; 1 history, 1 reroll.
GetNextNesPiece:
2023-10-22 18:28:08 +00:00
call Next7Piece
2023-10-21 18:49:52 +00:00
ld hl, hPieceHistory
2023-10-13 06:38:10 +00:00
cp a, [hl]
2023-10-23 10:16:16 +00:00
jr nz, ShiftHistory
call Next7Piece
2023-10-26 13:58:08 +00:00
jr ShiftHistory
2023-10-22 18:28:08 +00:00
2023-10-22 18:28:08 +00:00
; TGM3 mode... It's complex.
GetNextTGM3Piece:
ld a, 7
ld e, a
: dec e
jr z, :+
; Get a random index into the 35bag
call Next35Piece
ld [wTGM3GeneratedIdx], a
; Fetch the piece from the 35bag.
ld c, a
xor a, a
ld b, a
2023-10-22 18:28:08 +00:00
ld hl, wTGM3Bag
add hl, bc
ld a, [hl]
2023-10-22 18:28:08 +00:00
; Is it in the history?
ld hl, hPieceHistory
cp a, [hl]
jr z, :-
inc hl
cp a, [hl]
2023-10-22 18:28:08 +00:00
jr z, :-
inc hl
cp a, [hl]
2023-10-22 18:28:08 +00:00
jr z, :-
inc hl
cp a, [hl]
jr z, :-
2023-10-13 06:38:10 +00:00
2023-10-22 18:28:08 +00:00
; We have a piece. Save it.
: call ShiftHistory
; Increment all drought counters.
: ld hl, wTGM3Droughts
inc [hl]
inc hl
inc [hl]
inc hl
inc [hl]
inc hl
inc [hl]
inc hl
inc [hl]
inc hl
inc [hl]
inc hl
inc [hl]
; Set the drought of our most recently drawn piece to 0.
2023-11-07 08:14:43 +00:00
: ldh a, [hUpcomingPiece2]
2023-10-22 18:28:08 +00:00
ld c, a
xor a, a
2023-10-13 06:38:10 +00:00
ld b, a
2023-10-22 18:28:08 +00:00
ld hl, wTGM3Droughts
add hl, bc
ld [hl], a
; We pick an arbitrary piece to have the worst drought.
: call Next7Piece
ld [wTGM3WorstDroughtIdx], a
; And then save that drought in e.
ld c, a
xor a, a
ld b, a
ld hl, wTGM3Droughts
add hl, bc
ld e, [hl]
; Is idx 0 worse?
: ld hl, wTGM3Droughts
ld a, [hl+]
cp a, e
jr z, :+ ; Same.
jr c, :+ ; Nope.
ld e, a
2023-11-13 02:35:09 +00:00
xor a, a
2023-10-22 18:28:08 +00:00
ld [wTGM3WorstDroughtIdx], a
; Is idx 1 worse?
: ld a, [hl+]
cp a, e
jr z, :+ ; Same.
jr c, :+ ; Nope.
ld e, a
ld a, 1
ld [wTGM3WorstDroughtIdx], a
; Is idx 2 worse?
: ld a, [hl+]
cp a, e
jr z, :+ ; Same.
jr c, :+ ; Nope.
ld e, a
ld a, 2
ld [wTGM3WorstDroughtIdx], a
; Is idx 3 worse?
: ld a, [hl+]
cp a, e
jr z, :+ ; Same.
jr c, :+ ; Nope.
ld e, a
ld a, 3
ld [wTGM3WorstDroughtIdx], a
; Is idx 4 worse?
: ld a, [hl+]
cp a, e
jr z, :+ ; Same.
jr c, :+ ; Nope.
ld e, a
ld a, 4
ld [wTGM3WorstDroughtIdx], a
; Is idx 5 worse?
: ld a, [hl+]
cp a, e
jr z, :+ ; Same.
jr c, :+ ; Nope.
ld e, a
ld a, 5
ld [wTGM3WorstDroughtIdx], a
; Is idx 6 worse?
: ld a, [hl+]
cp a, e
jr z, :+ ; Same.
jr c, :+ ; Nope.
ld e, a
ld a, 6
ld [wTGM3WorstDroughtIdx], a
; We now have the worst drought index as well as the slot in the bag that needs to be replaced.
: ld a, [wTGM3GeneratedIdx]
ld c, a
xor a, a
ld b, a
ld hl, wTGM3Bag
add hl, bc
ld a, [wTGM3WorstDroughtIdx]
; Replace that slot.
ld [hl], a
2023-10-13 06:38:10 +00:00
ret
2023-10-27 19:37:32 +00:00
; Gets the next piece depending on RNG mode.
2023-10-22 18:28:08 +00:00
GetNextPiece::
2023-10-27 19:37:32 +00:00
ld hl, .nextpiecejumps
2023-10-23 10:16:16 +00:00
ld a, [wRNGModeState]
2023-10-27 19:37:32 +00:00
ld b, 0
ld c, a
add a, c
add a, c
ld c, a
add hl, bc
jp hl
.nextpiecejumps
jp GetNextTGM1Piece
jp GetNextTGM2Piece
jp GetNextTGM3Piece
jp GetNextHellPiece
jp GetNextNesPiece
2023-10-22 18:28:08 +00:00
2023-10-27 19:37:32 +00:00
; Tries generating bytes until it gets one in [0; 35)
2023-10-22 18:28:08 +00:00
Next35Piece:
: call NextByte
and a, $3F
cp a, 35
jr nc, :-
ret
2023-10-27 19:37:32 +00:00
; Tries generating bytes until it gets one in [0; 7)
2023-10-22 18:28:08 +00:00
Next7Piece:
: call NextByte
2023-10-13 06:38:10 +00:00
and a, $07
cp a, 7
2023-10-22 18:28:08 +00:00
jr nc, :-
2023-10-13 06:38:10 +00:00
ret
2023-10-22 18:28:08 +00:00
2023-10-27 19:37:32 +00:00
; Cyrcles the RNG returning a random byte in a.
2023-10-13 06:38:10 +00:00
NextByte:
2023-10-10 08:32:24 +00:00
; Load seed
2023-10-21 18:49:52 +00:00
ld hl, hRNGSeed+3
2023-10-13 06:38:10 +00:00
ld a, [hl-]
ld b, a
ld a, [hl-]
ld c, a
ld a, [hl-]
2023-10-10 08:32:24 +00:00
; Multiply by 0x01010101
add [hl]
2023-10-13 06:38:10 +00:00
ld d, a
2023-10-10 08:32:24 +00:00
adc c
2023-10-13 06:38:10 +00:00
ld c, a
2023-10-10 08:32:24 +00:00
adc b
2023-10-13 06:38:10 +00:00
ld b, a
2023-10-10 08:32:24 +00:00
; Add 0x31415927 and write back
2023-10-13 06:38:10 +00:00
ld a, [hl]
2023-10-10 08:32:24 +00:00
add $27
2023-10-13 06:38:10 +00:00
ld [hl+], a
ld a, d
2023-10-10 08:32:24 +00:00
adc $59
2023-10-13 06:38:10 +00:00
ld [hl+], a
ld a, c
2023-10-10 08:32:24 +00:00
adc $41
2023-10-13 06:38:10 +00:00
ld [hl+], a
ld c, a
ld a, b
2023-10-10 08:32:24 +00:00
adc $31
2023-10-13 06:38:10 +00:00
ld [hl], a
2023-10-10 08:32:24 +00:00
ret
2023-10-13 06:38:10 +00:00
ENDC