[go: nahoru, domu]

Skip to content

Commit

Permalink
Add TRT statistic
Browse files Browse the repository at this point in the history
  • Loading branch information
ejona86 committed Jun 8, 2019
1 parent 773051a commit b5e4300
Show file tree
Hide file tree
Showing 7 changed files with 166 additions and 11 deletions.
9 changes: 7 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ all: tetris taus screens custom

# Manually list prerequisites that are generated. Non-generated files will
# automatically be computed.
build/taus.o: build/tetris.inc
build/taus.o: build/tetris.inc build/taus.chrs/
build/screens.o: build/tetris.inc
# List linker dependencies
build/tetris.nes: build/tetris.o build/tetris-PRG.o
Expand All @@ -28,9 +28,14 @@ build/%: %.cfg
build/%.nes: build/%.ips build/tetris.nes
cp $<.lbl build/$*.lbl
cp $<.dbg build/$*.dbg
flips --apply $< build/tetris.nes $@ > /dev/null
# If the first time fails, run it a second time to display output
flips --apply $< build/tetris.nes $@ > /dev/null || flips --apply $< build/tetris.nes $@
flips --create build/tetris.nes $@ build/$*.dist.ips > /dev/null

build/%.chrs/: %.chr | build
[ -d build/$*.chrs ] || mkdir build/$*.chrs
split -x -b 16 $< build/$*.chrs/

build/tetris-PRG.s: tetris-PRG.info tetris-PRG.bin Makefile | build
da65 -i tetris-PRG.info -o $@ tetris-PRG.bin

Expand Down
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,29 @@ The main project is the Actually Useful Statistics Tetris mod. However, the
repository also contains disassembly knowledge for tetris, a structure for
building NES ips/nes files, and a LUA-based unit/integration test helpers.

## TAUS

TAUS provides the statistics:
* DHT: The drought. The number of pieces since the last line
* BRN: The burn. The number of lines cleared since the last tetris
* EFF: The efficiency. The score per lines as if on level 0. Individual
clears have score per lines of: 40 for a single, 50 for a double, 100 for a
triple, 300 for a tetris
* TRT: The tetris rate. The percentage of clears that were tetrises

The mod also allows skipping the legal screen.

EFF is similar in purpose to the conventional TRT. Both assume you die because
you reach too high of a level (e.g., level 29) and both let you know for "how
well are you doing" in the middle of the game. But EFF can be a more precise
predictor of your final score. For example, let's say you start on level 9 and
die after 100 lines. If you alternate between tetrises and singles, your final
score will be ~248k. But if you alternate between tetrises and triples, your
final score will be ~214k (ignoring the fact you can get over 100 lines by
finishing with a tetris). In both cases your TRT is 50%, but your EFF was 248
and 214, respectively. If your EFF increases by 10%, then your score increases
~10% for the same number of lines.

## Set up

Dependencies (should be in PATH):
Expand Down
26 changes: 23 additions & 3 deletions ips.inc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
IPSPRGOFFSET = -16+$8000
IPSPRGOFFSET = 16-$8000

; Generates an IPS hunk header for named segment, which specifes the location
; and length where an IPS tool will place the segment in the modded file.
Expand All @@ -8,12 +8,32 @@ IPSPRGOFFSET = -16+$8000
; Is equivalent to:
; .import __HUNK1_LOAD__, __HUNK1_SIZE__
; .byte 0
; .dbyt __HUNK1_LOAD__-IPSPRGOFFSET
; .dbyt __HUNK1_LOAD__+IPSPRGOFFSET
; .dbyt __HUNK1_SIZE__
.macro ips_hunkhdr name
.import .ident(.concat("__", name, "_LOAD__"))
.import .ident(.concat("__", name, "_SIZE__"))
.byte 0
.dbyt .ident(.concat("__", name, "_LOAD__"))-IPSPRGOFFSET
; Dunno why -(-x) is necessary. But otherwise get a range error
.dbyt .ident(.concat("__", name, "_LOAD__"))-(-IPSPRGOFFSET)
.dbyt .ident(.concat("__", name, "_SIZE__"))
.endmacro

IPSCHROFFSET = 16+$8000
CHR00 = $0000
CHR01 = $2000
CHR_LEFT = $0000
CHR_RIGHT = $1000
TILE_SIZE = $10

; Generates an IPS hunk header for tiles, which specifes the location and
; length where an IPS tool will place the tiles in the modded file.
;
; For example, to replace a tile in the "left" (first) section of CHR01 in at
; row 0 and column 3:
; ips_tilehdr CHR01+CHR_LEFT,$03
.macro ips_tilehdr mapper_addr,tile
.byte 0
.dbyt (mapper_addr)+(tile*TILE_SIZE)+IPSCHROFFSET
.dbyt TILE_SIZE
.endmacro
27 changes: 27 additions & 0 deletions taus-test.lua
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ function test_demo ()
assertbyteoff("BRN", 1, 0x00)
assertbyteoff("EFF", 0, 0x88)
assertbyteoff("EFF", 1, 0x01)
assertbyteoff("TRT", 0, 0x25)
assertbyteoff("TRT", 1, 0x00)
end

function test_divmod ()
Expand Down Expand Up @@ -91,6 +93,31 @@ function test_binaryToBcd ()
end
end

function test_multiplyBy100 ()
local tests = {
{0, 0},
{3, 300},
{100, 10000},
{655, 65500},
}
for _, test in ipairs(tests) do
asm.waitbefore()
asm.waitbefore()
local bin = test[1]
local bcd = test[2]
memory.writebyte(labels.tmp1, test[1] % 256)
memory.writebyte(labels.tmp2, test[1] / 256)
local startcycles = debugger.getcyclescount()
asm.jsr(labels.multiplyBy100)
local cycles = debugger.getcyclescount() - startcycles
print("cycles: " .. cycles)
assertbyte("tmp1", math.floor(test[2] % 256))
assertbyte("tmp2", math.floor(test[2] / 256))
asm.waitbefore()
emu.poweron()
end
end

function test_benchdoDiv ()
asm.waitbefore()
asm.waitbefore()
Expand Down
Binary file added taus.chr
Binary file not shown.
2 changes: 2 additions & 0 deletions taus.ips.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ MEMORY {
GAME_BG: start = $BF3C, size = $8000;
CODEHDR:start = $0000, size = $0005;
CODE: start = $D6C9, size = $0837;
IPSCHR: start = $0000, size = $8000;
IPSEOF: start = $0000, size = $0003;
}

SEGMENTS {
IPSHEADER:load = IPSHDR;
IPSEOF: load = IPSEOF;
IPSCHR: load = IPSCHR;
CODEHDR: load = CODEHDR;
CODE: load = CODE, define = yes;
HUNK1HDR: load = HUNK1HDR;
Expand Down
90 changes: 84 additions & 6 deletions taus.s
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,13 @@ BRN_index = $01
BRN := statsByType + BRN_index * 2
EFF_index = $02
EFF := statsByType + EFF_index * 2
lvl0ScoreIndex = $03 ; stored as little endian binary, divided by 2
TRT_index = $03
TRT := statsByType + TRT_index * 2
tetrisClears = statsByType + $04 * 2
lineClears = statsByType + $04 * 2 + 1
lvl0ScoreIndex = $05 ; stored as little endian binary, divided by 2
lvl0Score := statsByType + lvl0ScoreIndex * 2
binaryLinesIndex = $04 ; stored as little endian binary; 9 bits
binaryLinesIndex = $06 ; stored as little endian binary; 9 bits
binaryLines := statsByType + binaryLinesIndex * 2

statsPerBlock:
Expand Down Expand Up @@ -123,6 +127,26 @@ doDiv:
lda tmp2
sta EFF+1

updateTrt:
inc lineClears
lda completedLines
cmp #$04
bne calcTrt
inc tetrisClears
calcTrt:
lda tetrisClears
sta tmp1
lda #$00
sta tmp2
jsr multiplyBy100
lda lineClears
jsr divmod
lda #$00
jsr binaryToBcd
sta TRT
lda tmp2
sta TRT+1

statsPerLineClearDone:
lda #$00
sta completedLines
Expand Down Expand Up @@ -206,6 +230,48 @@ divmod_checkDone:
lda tmp1
rts

; Multiply 16 bit number by 100
; tmp1: (input) LO
; (output) LO
; tmp2: (input) HI
; (output) HI
multiplyBy100:
asl tmp1 ; input =<< 2
rol tmp2
asl tmp1
rol tmp2

lda tmp1 ; output = input
ldx tmp2

asl tmp1 ; input =<< 3
rol tmp2
asl tmp1
rol tmp2
asl tmp1
rol tmp2

clc ; output += input
adc tmp1
tay
txa
adc tmp2
tax
tya

asl tmp1 ; input =<< 1
rol tmp2

clc ; output += input
adc tmp1
tay
txa
adc tmp2

sty tmp1
sta tmp2
rts

.segment "GAME_BGHDR"
ips_hunkhdr "GAME_BG"

Expand All @@ -230,7 +296,7 @@ divmod_checkDone:
.byte $21,$E0,$20,$77,$3B,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$3C,$33,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$34,$33,$FF,$FF,$FF,$FF,$34,$78,$83,$70
.byte $22,$00,$20,$77,$3B,$0E,$0F,$0F,$FF,$00,$00,$00,$FF,$3C,$33,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$34,$33,$FF,$FF,$FF,$FF,$34,$72,$7A,$80
.byte $22,$20,$20,$87,$3B,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$3C,$33,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$34,$33,$FF,$FF,$FF,$FF,$34,$77,$78,$73
.byte $22,$40,$20,$71,$3B,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$3C,$33,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$34,$35,$36,$36,$36,$36,$37,$87,$67,$77
.byte $22,$40,$20,$71,$3B,$1D,$1B,$1D,$FF,$00,$00,$00,$B0,$3C,$33,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$34,$35,$36,$36,$36,$36,$37,$87,$67,$77
.byte $22,$60,$20,$81,$3B,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$3C,$33,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$34,$38,$39,$39,$39,$39,$39,$3A,$77,$87
.byte $22,$80,$20,$7A,$3B,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$3C,$33,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$34,$3B,$15,$0E,$1F,$0E,$15,$3C,$77,$78
.byte $22,$A0,$20,$7A,$3B,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$3C,$33,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$34,$3B,$FF,$FF,$FF,$FF,$FF,$3C,$87,$67
Expand All @@ -244,8 +310,14 @@ divmod_checkDone:
.byte $23,$A0,$20,$80,$7A,$87,$78,$84,$7A,$77,$87,$78,$84,$7A,$67,$87,$77,$87,$77,$72,$83,$80,$81,$77,$67,$82,$79,$7A,$67,$77,$78,$83,$72,$7A,$67

;attributes
.byte $23,$C0,$20,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$AF,$AF,$EF,$FF,$FF,$BF,$2F,$CF,$AA,$AA,$EE,$FF,$FF,$FF,$33,$CC,$AA,$AA,$EE,$FF,$FF
.byte $23,$E0,$20,$BF,$23,$CC,$AA,$AA,$EE,$FF,$FF,$BB,$22,$CC,$AA,$AA,$EE,$FF,$FF,$FB,$F2,$FC,$FA,$FA,$FE,$FF,$FF,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F
.byte $23,$C0,$20,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
.byte $FF,$FF,$FF,$AF,$AF,$EF,$FF,$FF
.byte $BF,$2F,$CF,$AA,$AA,$EE,$FF,$FF
.byte $FF,$33,$CC,$AA,$AA,$EE,$FF,$FF
.byte $23,$E0,$20,$FF,$33,$CC,$AA,$AA,$EE,$FF,$FF
.byte $BB,$22,$CC,$AA,$AA,$EE,$FF,$FF
.byte $FB,$F2,$FC,$FA,$FA,$FE,$FF,$FF
.byte $0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F
.byte $FF

.segment "STATS_NUMBERHDR"
Expand All @@ -254,7 +326,7 @@ divmod_checkDone:
.segment "STATS_NUMBER"

; Only show 3 stats
cmp #$03
cmp #$04


.segment "JMP_STATS_PER_LINE_CLEARHDR"
Expand All @@ -265,3 +337,9 @@ divmod_checkDone:
; at end of addLineClearPoints, replaces "lda #0; sta completedLines"
jsr statsPerLineClear
nop

.segment "IPSCHR"

ips_tilehdr CHR01+CHR_RIGHT,$B0
; percent
.incbin "build/taus.chrs/00"

0 comments on commit b5e4300

Please sign in to comment.