make "changed" more flexible

This commit is contained in:
Nico 2021-03-18 20:00:59 +00:00
parent d0444cfc80
commit 48a5e67be4
1 changed files with 12 additions and 16 deletions

28
main.fs
View File

@ -8,14 +8,15 @@
: move-right ( x -- ) esc[ 0 .R ." C" ; \ 0 .R : print a number without trailing space
\ some of these values (member cost, device count) have two cells.
\ the first cell stores the value, the second cell stores if the value has changed.
\ the second cell is used to store if the value has changed or not.
\ for flexibility, these all take an offset of the cell the flag is stored in.
\ this is useful as it means we only redraw the display if a relevant value has changed.
\ the word "changed" sets one of these values as being changed.
: changed ( addr -- ) 1 cells + -1 swap ! ;
: changed ( addr offset -- ) cells + -1 swap ! ;
\ the word "cleared" sets one of these values as having been used, clearing the change flag.
: cleared ( addr -- ) 1 cells + 0 swap ! ;
: cleared ( addr offset -- ) cells + 0 swap ! ;
\ the word changed? leaves a -1 if the value has changed since last clear, 0 otherwise.
: changed? ( addr -- flag ) 1 cells + @ ;
: changed? ( addr offset -- flag ) cells + @ ;
\ initialise some variables that encode game state.
\ the variable "counter" holds the count of the current tick. It always starts at 0.
@ -33,16 +34,11 @@ variable membercount
variable count-messages-shown
\ message contains a string message which is printed on the screen.
\ because forth is weird, strings can be stored in variables but it's easier to just store them someplace else and then store that address and the string's length in the variable (this is what S" " does and what "type" expects)
\ as I'd like changed? etc to work on this, it needs to have three cells, arranged like this:
\ [length change-flag address]
\ TODO this is a terrible idea. Potential better ideas:
\ * have the change flag be the first value, so then the subsequent values can be any length
\ * learn how strings work in this language, store the message inside message
create message 0 , 0 , 0 ,
\ set-message sets the message
: set-message ( addr len -- ) message ! message 2 cells + ! message changed ;
: set-message ( addr len -- ) message ! message 1 cells + ! message 2 changed ;
\ get-message gets the message
: get-message ( -- addr len ) message @ message 2 cells + @ swap ;
: get-message ( -- addr len ) message @ message 1 cells + @ swap ;
\ set an initial message
S" you feel like throwing some stuff into the pool." set-message
@ -52,9 +48,9 @@ S" you feel like throwing some stuff into the pool." set-message
\ 10 membercost !
\ any-change? leaves a -1 on the stack if any value has changed, 0 otherwise
: any-change? ( -- flag ) membercost changed? devices changed? message changed? or or ;
: any-change? ( -- flag ) membercost 1 changed? devices 1 changed? message 2 changed? or or ;
\ clear-all clears the change flag on all values.
: clear-all membercost cleared devices cleared message cleared ;
: clear-all membercost 1 cleared devices 1 cleared message 2 cleared ;
\ the word !0= tests if something is non-zero
: !0= 0= 0= ;
@ -86,7 +82,7 @@ S" you feel like throwing some stuff into the pool." set-message
counter @ devicerate @ mod 0= if
1 devices +!
set-count-message
devices changed then ;
devices 1 changed then ;
\ TODO saving
\ the word exit-game exits the game.
@ -108,7 +104,7 @@ S" you feel like throwing some stuff into the pool." set-message
then
1 membercount +! \ add a member to the count
membercount @ 2 * 5 + membercost +! \ increase the cost of buying a new member
membercost changed
membercost 1 changed
S" " set-message \ blank the message, because we did a thing.
then ;
@ -120,7 +116,7 @@ S" you feel like throwing some stuff into the pool." set-message
page ;
\ throw-device throws a device into the pool.
: throw-device 1 devices +! devices changed ;
: throw-device 1 devices +! devices 1 changed ;
\ the word handle-input handles input every time around the game loop.
: handle-input