Compare commits

..

No commits in common. 'main' and '0.6.0' have entirely different histories.
main ... 0.6.0

  1. 7
      dict/compress.py
  2. 5
      dict/solver.py
  3. 8
      inc/constants.asm
  4. 137
      inc/dict.asm
  5. 30
      inc/guess.asm
  6. 33
      inc/hints.asm
  7. 97
      inc/init.asm
  8. 47
      inc/input.asm
  9. 17
      inc/interrupts.asm
  10. 8
      inc/math.asm
  11. 38
      inc/messages.asm
  12. 22
      inc/oam.asm
  13. 113
      inc/search.asm
  14. 22
      inc/wincondition.asm
  15. 1
      maps/window-game.asm
  16. 8
      maps/window-help.asm
  17. 17
      tiles/sign-arrow.asm
  18. 17
      tiles/sign-slash.asm
  19. 121
      wordle.asm
  20. BIN
      wordle.gb

7
dict/compress.py

@ -1,11 +1,4 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""
To fit the whole game into one memory bank, the dictionary is compressed.
Since only 2^5 combinations are needed to store 26 letters,
5 bits would be enough; for simplicity's sake, however, we take 6.
This way we can reduce the memory consumption by 20%.
"""
import struct import struct
def compress(in_path: str, out_path:str): def compress(in_path: str, out_path:str):

5
dict/solver.py

@ -1,9 +1,4 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""
Even though I like Wordle, it becomes very exhausting to constantly
use your brain while developing. That's why this tool exists.
"""
import random import random
print("Welcome to this debug tool!") print("Welcome to this debug tool!")

8
inc/constants.asm

@ -1,10 +1,4 @@
;; ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ;; Game Boy Constants
;; ██░▄▄░█░▄▄▀█░▄▀▄░█░▄▄████░▄▄▀█▀▄▄▀█░██░████░▄▄▀█▀▄▄▀█░▄▄▀█░▄▄█▄░▄█░▄▄▀█░▄▄▀█▄░▄█░▄▄██
;; ██░█▀▀█░▀▀░█░█▄█░█░▄▄████░▄▄▀█░██░█░▀▀░████░████░██░█░██░█▄▄▀██░██░▀▀░█░██░██░██▄▄▀██
;; ██░▀▀▄█▄██▄█▄███▄█▄▄▄████░▀▀░██▄▄██▀▀▀▄████░▀▀▄██▄▄██▄██▄█▄▄▄██▄██▄██▄█▄██▄██▄██▄▄▄██
;; ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
;; Hardware specific values and addresses
; Interrupt Flags ; Interrupt Flags
INTERRUPT_SETTINGS EQU $ffff INTERRUPT_SETTINGS EQU $ffff
INT_VBLANK_ON EQU %00000001 INT_VBLANK_ON EQU %00000001

137
inc/dict.asm

@ -1,29 +1,15 @@
;; ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ; Selects a random word from the dictionary.
;; ██░▄▄▀██▄██▀▄▀█▄░▄██▄██▀▄▄▀█░▄▄▀█░▄▄▀█░▄▄▀█░██░██ ; Sets the to be guessed and the revealed letter indices.
;; ██░██░██░▄█░█▀██░███░▄█░██░█░██░█░▀▀░█░▀▀▄█░▀▀░██
;; ██░▀▀░█▄▄▄██▄███▄██▄▄▄██▄▄██▄██▄█▄██▄█▄█▄▄█▀▀▀▄██
;; ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
;; This file contains all the functions to interact with the dictionary.
;; Therefore, a random word can be selected and it is possible to check if an entered word exists.
; Selects a random entry from the dictionary and saves it.
; ;
; Note: ; Note: The dict saves the 5 chars of the words in 4 bytes.
; In the dictionary, entries with a word length of five are stored with only four bytes.
; n+0: 11111122 ; n+0: 11111122
; n+1: 22223333 ; n+1: 22223333
; n+2: 33444444 ; n+2: 33444444
; n+3: 55555500 ; n+3: 55555500
; ~> 00111111 00222222 00333333 00444444 00555555
; ;
; -> [random_number]: depends on the current random number
; <- [currend_word]: five characters, index starts at one
select_word: select_word:
ld de, current_word ld de, current_word
; determine the starting address of the dictionary entry
; (start address + random * word length)
ld a, [random_number+0] ld a, [random_number+0]
and %00011111 and %00011111
ld h, a ld h, a
@ -109,120 +95,3 @@ select_word:
ld [de], a ld [de], a
ret ret
; In order to check whether an entered word exists in the dictionary,
; it must first be compressed according to the dictionary.
; -> [current guess]: current rate attempt, stored in five bytes
; <- bc: first two bytes of the compression
; <- de: second two bytes of the compression
compress_guess:
call get_guess_offset
; first byte
ld a, [hl+] ; letter 1
and %00111111
sla a
sla a
ld b, a
ld a, [hl] ; letter 2
and %00110000
sra a
sra a
sra a
sra a
add a, b
ld d, a
; second byte
ld a, [hl+] ; letter 2
and %00001111
sla a
sla a
sla a
sla a
ld b, a
ld a, [hl] ; letter 3
and %00111100
sra a
sra a
add a, b
ld e, a
push de
; third byte
ld a, [hl+] ; letter 3
and %00000011
sla a
sla a
sla a
sla a
sla a
sla a
ld b, a
ld a, [hl+] ; letter 4
and %00111111
add a, b
ld d, a
; fourth byte
ld a, [hl] ; letter 5
and %00111111
sla a
sla a
ld e, a
pop bc
ret
; Try to find the current guess within the dictionary
; -> bc: first two bytes of the compression
; -> de: second two bytes of the compression
; <- a: whether the entry exists
find_guess:
ld hl, dictionary
.loop:
; check if the end of the dictionary is reached
push bc
ld bc, dictionary_end
ld a, h
cp a, b
jp nz, .not_eof
ld a, l
cp a, c
jp nz, .not_eof
pop bc
jp .return
.not_eof:
pop bc
ld a, [hl+]
cp a, b
jp nz, .add3
ld a, [hl+]
cp a, c
jp nz, .add2
ld a, [hl+]
cp a, d
jp nz, .add1
ld a, [hl+]
cp a, e
jp nz, .add0
ld a, 1
ret
.add3:
inc hl
.add2:
inc hl
.add1:
inc hl
.add0:
jp .loop
.return:
ld a, 0
ret

30
inc/guess.asm

@ -1,17 +1,7 @@
;; ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
;; ██░▄▄░█░██░█░▄▄█░▄▄█░▄▄█░███░█▀▄▄▀█░▄▄▀█░█▀██
;; ██░█▀▀█░██░█░▄▄█▄▄▀█▄▄▀█▄▀░▀▄█░██░█░▀▀▄█░▄▀██
;; ██░▀▀▄██▄▄▄█▄▄▄█▄▄▄█▄▄▄██▄█▄███▄▄██▄█▄▄█▄█▄██
;; ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
;; Manages and displays the guessing attempts
; Updates the objects of the entered characters ; Updates the objects of the entered characters
; -> [guess_attempts]
; <- [obj_guess_letters]
update_guess_objects: update_guess_objects:
ld hl, obj_guess_letters ld hl, obj_guess_letters
ld de, guess_attempts ld de, guesses
ld a, $14 ld a, $14
call update_guess_row call update_guess_row
@ -30,10 +20,9 @@ update_guess_objects:
; Updates one line of entered characters ; Updates one line of entered characters
; -> hl: address of where to write obj data ; -> hl: position within obj data
; -> de: address of the current guess ; -> de: position within the guesses data
; -> a: vertical screen position ; -> a: vertical screen position
; <- [obj_guess_letters]
update_guess_row: update_guess_row:
push hl push hl
push hl push hl
@ -42,14 +31,14 @@ update_guess_row:
; distance between objects ; distance between objects
ld bc, 4 ld bc, 4
; write all five vertical positions ; vertical positions
ld [hl], a ld [hl], a
REPT 4 REPT 4
add hl, bc add hl, bc
ld [hl], a ld [hl], a
ENDR ENDR
; write all five horizontal positions ; horizontal positions
pop hl pop hl
inc hl inc hl
ld a, $30 ld a, $30
@ -60,7 +49,7 @@ REPT 4
ld [hl], a ld [hl], a
ENDR ENDR
; write all five tile indices ; tile indices
pop hl pop hl
inc hl inc hl
inc hl inc hl
@ -73,7 +62,7 @@ REPT 4
ld [hl], a ld [hl], a
ENDR ENDR
; write all five palette info ; palette info
pop hl pop hl
inc hl inc hl
inc hl inc hl
@ -91,8 +80,7 @@ ENDR
; Calculates the address of the current guess attempt, using the number of the attempt ; Calculates the position of the current guess
; -> [current_guess]: number of the current attempt
; <- hl ; <- hl
get_guess_offset: get_guess_offset:
ld a, [current_guess] ld a, [current_guess]
@ -100,7 +88,7 @@ get_guess_offset:
call multiply_ab call multiply_ab
ld b, 0 ld b, 0
ld c, a ld c, a
ld hl, guess_attempts ld hl, guesses
add hl, bc add hl, bc
ret ret

33
inc/hints.asm

@ -1,19 +1,7 @@
;; ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ; Update the character hint objects
;; ██░██░██▄██░▄▄▀█▄░▄█░▄▄██
;; ██░▄▄░██░▄█░██░██░██▄▄▀██
;; ██░██░█▄▄▄█▄██▄██▄██▄▄▄██
;; ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
;; Manages the obtained hints
; Updates the background layer with the obtained hints.
; Note: a row within the background map consists of 32 tiles
; -> [guess_hints]
; <- [BKG_LOC_9800]
update_hint_markings: update_hint_markings:
; calculate the ld hl, BKG_LOC_9800 + 20*32 + 6
ld hl, BKG_LOC_9800 + 32*20 + 6 ld de, guesses_hints
ld de, guess_hints
ld b, 6 ld b, 6
.loop_outer: .loop_outer:
@ -42,13 +30,8 @@ update_hint_markings:
; Saves the obtained hints. ; Update the hint data
; -> [current_word]
; -> [current_guess]
; -> [guess]
mark_hints: mark_hints:
; To get the beginning of the clues,
; you can use the end of the guessing attempts
call get_guess_offset call get_guess_offset
push hl push hl
pop de pop de
@ -57,7 +40,6 @@ mark_hints:
ld b, 0 ld b, 0
.loop: .loop:
; update the hints char by char
ld a, [de] ld a, [de]
call hint_for_char call hint_for_char
ld [hl], a ld [hl], a
@ -71,10 +53,9 @@ mark_hints:
; Determines the hint for one character. ; Determines the hint for one character
; -> [current_word] ; <- a: character value to check
; -> a: character value to check ; <- b: index within the guess
; -> b: position within the guess
hint_for_char: hint_for_char:
push hl push hl
push bc push bc

97
inc/init.asm

@ -1,18 +1,4 @@
;; ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ; Initialise everything for the main game state
;; █▄░▄█░▄▄▀██▄██▄░▄██▄██░▄▄▀█░███▄██▄▄░█░▄▄▀█▄░▄██▄██▀▄▄▀█░▄▄▀██
;; ██░██░██░██░▄██░███░▄█░▀▀░█░███░▄█▀▄██░▀▀░██░███░▄█░██░█░██░██
;; █▀░▀█▄██▄█▄▄▄██▄██▄▄▄█▄██▄█▄▄█▄▄▄█▄▄▄█▄██▄██▄██▄▄▄██▄▄██▄██▄██
;; ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
;; Establish a defined initial state
; Initialize everything for the main game state
; <- [current_state]
; <- [sub_state]
; <- [BKG_POS_X_REGISTER]
; <- [BKG_POS_Y_REGISTER]
; <- [LCD_CONTROL_REGISTER]
; <- [message_objs]
init_state_menu: init_state_menu:
ld a, STATE_MENU ld a, STATE_MENU
ld [current_state], a ld [current_state], a
@ -36,17 +22,7 @@ init_state_menu:
; Initialize everything for the help screen ; Initialise everything for help screen
; <- [current_state]
; <- [BKG_POS_X_REGISTER]
; <- [BKG_POS_Y_REGISTER]
; <- [WND_POS_X_REGISTER]
; <- [WND_POS_Y_REGISTER]
; <- [LCD_CONTROL_REGISTER]
; <- [current_word]
; <- [guess]
; <- [guess_hints]
; <- [message_objs]
init_state_help: init_state_help:
ld a, STATE_HELP ld a, STATE_HELP
ld [current_state], a ld [current_state], a
@ -69,27 +45,24 @@ init_state_help:
ld a, $70 ld a, $70
ld [WND_POS_Y_REGISTER], a ld [WND_POS_Y_REGISTER], a
; load the window data
ld hl, window_help ld hl, window_help
call load_window_map call load_window_map
; Set a fixed and actually impossible game state. ; set a fixed game state
; containing: [current_word], [guess] and [guess_hints]
;
; This is only possible because the memory space of these
; three variables is located directly after each other.
ld hl, current_word ld hl, current_word
ld de, help_word ld de, help_word
ld c, 65 ld c, 65
.copy_gamestate: .set_gamestate:
ld a, [de] ld a, [de]
ld [hl], a ld [hl], a
inc de inc de
inc hl inc hl
dec c dec c
jp nz, .copy_gamestate jp nz, .set_gamestate
; This is only possible because the memory space of these
; two variables is located directly after each other.
; for the rest we can use the default functions
call update_hint_markings call update_hint_markings
call update_guess_objects call update_guess_objects
@ -103,21 +76,7 @@ init_state_help:
; Initialize everything for the main game state ; Initialise everything for the main game state
; <- [current_state]
; <- [BKG_POS_X_REGISTER]
; <- [BKG_POS_Y_REGISTER]
; <- [WND_POS_X_REGISTER]
; <- [WND_POS_Y_REGISTER]
; <- [LCD_CONTROL_REGISTER]
; <- [current_word]
; <- [current_guess]
; <- [current_char]
; <- [guess]
; <- [guess_hints]
; <- [selected_letter_x]
; <- [selected_letter_y]
; <- [message_objs]
init_state_game: init_state_game:
; set the current state ; set the current state
ld a, STATE_GAME ld a, STATE_GAME
@ -139,22 +98,22 @@ init_state_game:
; set the window position ; set the window position
ld a, 3 ld a, 3
ld [WND_POS_X_REGISTER], a ld [WND_POS_X_REGISTER], a
ld a, $68 ld a, $70
ld [WND_POS_Y_REGISTER], a ld [WND_POS_Y_REGISTER], a
; load the window data ; load the window data
ld hl, window_game ld hl, window_game
call load_window_map call load_window_map
; initialize some more variables ; initialise some more variables
ld a, 0 ld a, 0
ld [selected_letter_x], a ld [selected_letter_x], a
ld [selected_letter_y], a ld [selected_letter_y], a
ld [current_guess], a ld [current_guess], a
ld [current_char], a ld [current_char], a
.reset_guess_attempts .reset_guesses
ld hl, guess_attempts ld hl, guesses
ld a, NULL ld a, NULL
ld d, 30 ld d, 30
.loop1: .loop1:
@ -163,7 +122,7 @@ init_state_game:
jp nz, .loop1 jp nz, .loop1
.reset_hints .reset_hints
ld hl, guess_hints ld hl, guesses_hints
ld a, TILE_WHITE ld a, TILE_WHITE
ld d, 30 ld d, 30
.loop2: .loop2:
@ -181,9 +140,7 @@ init_state_game:
; Switches to the state when the player has lost ; Switches to the lost state
; <- [current_state]
; <- [message_objs]
init_state_lost: init_state_lost:
ld a, STATE_LOST ld a, STATE_LOST
ld [current_state], a ld [current_state], a
@ -192,9 +149,7 @@ init_state_lost:
; Switches to the state when the player has won ; Switches to the won state
; <- [current_state]
; <- [message_objs]
init_state_won: init_state_won:
ld a, STATE_WON ld a, STATE_WON
ld [current_state], a ld [current_state], a
@ -203,10 +158,7 @@ init_state_won:
; Initialize the DMG color palettes ; Initialise the DMG color palettes
; <- [PALETTE_BKG_REGISTER]
; <- [PALETTE_OBJ0_REGISTER]
; <- [PALETTE_OBJ1_REGISTER]
init_palettes: init_palettes:
ld a, %10010011 ld a, %10010011
ld [PALETTE_BKG_REGISTER], a ld [PALETTE_BKG_REGISTER], a
@ -216,9 +168,7 @@ init_palettes:
; Copy the tile data into the vram ; Load the tile data into the vram
; -> [tiles]
; <- [TLS_LOC_8000]
load_tiles: load_tiles:
ld bc, tiles_start ld bc, tiles_start
ld hl, TLS_LOC_8000 ld hl, TLS_LOC_8000
@ -239,9 +189,7 @@ load_tiles:
; Copy the background map into the vram ; Load the background map into the vram
; -> [background]
; <- [BKG_LOC_9800]
load_background_map: load_background_map:
ld bc, background ld bc, background
ld hl, BKG_LOC_9800 ld hl, BKG_LOC_9800
@ -262,13 +210,12 @@ load_background_map:
; Copy a window map into the vram ; Load the window map into the vram
; -> hl: address of the desired window map ; -> hl
; <- [WND_LOC_9C00]
load_window_map: load_window_map:
ld bc, WND_LOC_9C00 ld bc, WND_LOC_9C00
ld d, 32 ld d, 32
ld e, 5 ld e, 4
.loop: .loop:
ld a, [hl] ld a, [hl]

47
inc/input.asm

@ -1,14 +1,6 @@
;; ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
;; █▄░▄█░▄▄▀█▀▄▄▀█░██░█▄░▄██
;; ██░██░██░█░▀▀░█░██░██░███
;; █▀░▀█▄██▄█░█████▄▄▄██▄███
;; ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
;; Handles the player inputs
; Read the current input state ; Read the current input state
; <- b: current keystates ; -> b: current keystates
; <- c: changed keys since last read ; -> c: changed keys since last read
read_input: read_input:
di di
@ -50,8 +42,7 @@ read_input:
; React to input within the menu ; React on input within the menu
; -> c: the changed keystate
handle_input_menu: handle_input_menu:
.check_movement: .check_movement:
ld a, c ld a, c
@ -63,11 +54,9 @@ handle_input_menu:
ld [sub_state], a ld [sub_state], a
and a, STATE_MENU_START and a, STATE_MENU_START
jp z, .switch_to_help jp z, .switch_to_help
.switch_to_start .switch_to_start
call show_message_menu_start call show_message_menu_start
jp .check_confirm jp .check_confirm
.switch_to_help .switch_to_help
call show_message_menu_help call show_message_menu_help
jp .check_confirm jp .check_confirm
@ -90,8 +79,6 @@ handle_input_menu:
; React to input within the help screen
; -> c: the changed keystate
handle_input_help: handle_input_help:
ld a, c ld a, c
and a, INPUT_START and a, INPUT_START
@ -102,10 +89,8 @@ handle_input_help:
; React to input within the main game ; React on input within the main game
; -> c: the changed keystate ; <- c: changed keys since last read
; <- [selected_letter_x]
; <- [selected_letter_y]
handle_input_game: handle_input_game:
ld a, [selected_letter_x] ld a, [selected_letter_x]
ld d, a ld d, a
@ -193,26 +178,22 @@ handle_input_game:
; React to input after a game round, ; React on input after a game round
; no matter if won or lost
; -> c: the changed keystate
handle_input_after: handle_input_after:
ld a, c ld a, c
and a, INPUT_START and a, INPUT_START
jp z, .nothing jp z, .nothing
call init_state_game call init_state_game
call clear_message call clear_message
.nothing .nothing
ret ret
; Select a character and add it to the current guess ; Add a character to the guess
; -> d: x position of the cursor ; -> d: x position of the cursor
; -> e: y position of the cursor ; -> e: y position of the cursor
; <- [current_guess]
; <- [current_char]
; <- [guess_attempts]
select_letter: select_letter:
push hl push hl
push af push af
@ -235,7 +216,7 @@ select_letter:
jp .return jp .return
.normal_letter: .normal_letter:
ld hl, guess_attempts ld hl, guesses
ld a, [current_guess] ld a, [current_guess]
ld b, 5 ld b, 5
call multiply_ab call multiply_ab
@ -262,17 +243,14 @@ select_letter:
; Delete the last entered letter ; Delete the last letter
; <- [current_guess]
; <- [current_char]
; <- [guess_attempts]
delete_letter: delete_letter:
push hl push hl
push af push af
push bc push bc
push de push de
ld hl, guess_attempts ld hl, guesses
ld a, [current_guess] ld a, [current_guess]
ld b, 5 ld b, 5
call multiply_ab call multiply_ab
@ -302,9 +280,6 @@ delete_letter:
; Update the object data for the alphabet cursor ; Update the object data for the alphabet cursor
; -> [selected_letter_x]
; -> [selected_letter_y]
; <- [obj_selected_letter]
update_cursor_objects: update_cursor_objects:
ld hl, obj_selected_letter ld hl, obj_selected_letter

17
inc/interrupts.asm

@ -1,12 +1,4 @@
;; ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ; Interrupt handler for the vertical blanking
;; █▄░▄█░▄▄▀█▄░▄█░▄▄█░▄▄▀█░▄▄▀█░██░█▀▄▄▀█▄░▄█░▄▄██
;; ██░██░██░██░██░▄▄█░▀▀▄█░▀▀▄█░██░█░▀▀░██░██▄▄▀██
;; █▀░▀█▄██▄██▄██▄▄▄█▄█▄▄█▄█▄▄██▄▄▄█░█████▄██▄▄▄██
;; ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
;; Handle hardware interrupts
; Interrupt handler for the vertical blanking period
int_vblank: int_vblank:
push af push af
ld a, 1 ld a, 1
@ -19,10 +11,7 @@ int_vblank:
; Interrupt handler for the timer ; Interrupt handler for the timer
; ;
; Getting random numbers is hard, here we read the vertical position of the scanline, ; Getting random numbers is hard, here we read the vertical position of the scanline,
; save them periodically and use them to get something. This approach works, ; save them periodically and use them to get something.
; but is not unbalanced because the y position only goes from 0 to 153.
; To get around this, two values are stored as in a shift register
; and not all bits of this are used when determining the random number.
int_timer: int_timer:
push hl push hl
push af push af
@ -37,7 +26,7 @@ int_timer:
ld hl, LCD_POSITION_REGISTER ld hl, LCD_POSITION_REGISTER
ld a, [hl] ld a, [hl]
; save the old and new number ; save the new number
ld hl, random_number ld hl, random_number
ld [hl+], a ld [hl+], a
ld a, d ld a, d

8
inc/math.asm

@ -1,11 +1,3 @@
;; ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
;; ██░▄▀▄░█░▄▄▀█▄░▄█░█████
;; ██░█░█░█░▀▀░██░██░▄▄░██
;; ██░███░█▄██▄██▄██▄██▄██
;; ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
;; Mathematical functions
; Multiply a and b ; Multiply a and b
; -> a, b ; -> a, b
; <- a ; <- a

38
inc/messages.asm

@ -1,16 +1,4 @@
;; ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
;; ██░▄▀▄░█░▄▄█░▄▄█░▄▄█░▄▄▀█░▄▄▄█░▄▄█░▄▄██
;; ██░█░█░█░▄▄█▄▄▀█▄▄▀█░▀▀░█░█▄▀█░▄▄█▄▄▀██
;; ██░███░█▄▄▄█▄▄▄█▄▄▄█▄██▄█▄▄▄▄█▄▄▄█▄▄▄██
;; ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
;; To give the user specific information, short messages could be displayed.
;; These are either permanent or can be provided with a timer.
;; Some of these messages are also used for highlighting in the menu.
; Highlights the menu entry "start game" ; Highlights the menu entry "start game"
; <- de: message address
; <- b: message timeout
show_message_menu_start: show_message_menu_start:
ld de, message_menu_start ld de, message_menu_start
ld b, 0 ld b, 0
@ -20,8 +8,6 @@ show_message_menu_start:
; Highlights the menu entry "how it works" ; Highlights the menu entry "how it works"
; <- de: message address
; <- b: message timeout
show_message_menu_help: show_message_menu_help:
ld de, message_menu_help ld de, message_menu_help
ld b, 0 ld b, 0
@ -31,19 +17,15 @@ show_message_menu_help:
; Inform that the current guess is not in the dictionary ; Inform that the current guess is not in the dictionary
; <- de: message address
; <- b: message timeout
show_message_unknown: show_message_unknown:
ld de, message_unknown ld de, message_unknown
ld b, 180 ; three seconds ld b, 180
call show_message call show_message
ret ret
; Inform about the users victory ; Inform about the users victory
; <- de: message address
; <- b: message timeout
show_message_won: show_message_won:
ld de, message_won ld de, message_won
ld b, 0 ld b, 0
@ -53,8 +35,6 @@ show_message_won:
; Inform about the users loss ; Inform about the users loss
; <- de: message address
; <- b: message timeout
show_message_lost: show_message_lost:
ld de, message_lost ld de, message_lost
ld b, 0 ld b, 0
@ -77,11 +57,9 @@ ENDR
; Generic function to present a message to the user ; Displays a message to the user
; -> de: message address ; <- de
; -> b: message timeout ; <- b
; <- [obj_message_letters]
; <- [message_timeout]
show_message: show_message:
push hl push hl
push bc push bc
@ -107,10 +85,7 @@ show_message:
; Checks if the current message has expired and removes it when necessary ; Checks if the current message has expired
; -> [message_timeout]
; <- [message_timeout]
; <- [obj_message_letters]
check_message_timeout: check_message_timeout:
ld a, [message_timeout] ld a, [message_timeout]
cp a, 0 cp a, 0
@ -128,8 +103,7 @@ check_message_timeout:
; Clears the current message by overwriting it with NULL values ; Clears the current message by overwriting with nothing
; <- [obj_message_letters]
clear_message: clear_message:
ld de, message_clear ld de, message_clear
ld b, 0 ld b, 0

22
inc/oam.asm

@ -1,32 +1,18 @@
;; ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ; Fill the whole oam copy with zero to prevent artifacts
;; ██░▄▄▄░█░▄▄▀███▄█░▄▄█▀▄▀█▄░▄███░▄▄▀█▄░▄█▄░▄█░▄▄▀██▄██░▄▄▀█░██░█▄░▄█░▄▄████░▄▀▄░█░▄▄█░▄▀▄░█▀▄▄▀█░▄▄▀█░██░██
;; ██░███░█░▄▄▀███░█░▄▄█░█▀██░████░▀▀░██░███░██░▀▀▄██░▄█░▄▄▀█░██░██░██░▄▄████░█░█░█░▄▄█░█▄█░█░██░█░▀▀▄█░▀▀░██
;; ██░▀▀▀░█▄▄▄▄█░▀░█▄▄▄██▄███▄████░██░██▄███▄██▄█▄▄█▄▄▄█▄▄▄▄██▄▄▄██▄██▄▄▄████░███░█▄▄▄█▄███▄██▄▄██▄█▄▄█▀▀▀▄██
;; ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
;; Contains functions to manage the object attribute memory (OAM).
;; We do not write to this area directly, but use a copy in the working memory.
;; During a v-blank, the OAM is updated using direct memory access (DMA).
;; Note: the Game Boy can only handle a total of 40 objects, and only 10 can be displayed on a line.
; Fill the whole OAM copy with zero to prevent artifacts
; <- [objects]
init_oam_copy: init_oam_copy:
ld b, 160 ld b, 160
ld a, 0 ld a, 0
ld hl, obj_start ld hl, obj_start
.copy_loop .zero_loop
ld [hl+], a ld [hl+], a
dec b dec b
jp nz, .copy_loop jp nz, .zero_loop
ret ret
; Update the OAM via DMA ; Write into OAM via DMA
; -> [objects]
; <- [OAM]
update_oam: update_oam:
; start DMA ; start DMA
ld a, $c0 ld a, $c0

113
inc/search.asm

@ -0,0 +1,113 @@
; Compresses the current guess to the same format as the dictionary
; <- bc
; <- de
compress_guess:
call get_guess_offset
; first byte
ld a, [hl+] ; letter 1
and %00111111
sla a
sla a
ld b, a
ld a, [hl] ; letter 2
and %00110000
sra a
sra a
sra a
sra a
add a, b
ld d, a
; second byte
ld a, [hl+] ; letter 2
and %00001111
sla a
sla a
sla a
sla a
ld b, a
ld a, [hl] ; letter 3
and %00111100
sra a
sra a
add a, b
ld e, a
push de
; third byte
ld a, [hl+] ; letter 3
and %00000011
sla a
sla a
sla a
sla a
sla a
sla a
ld b, a
ld a, [hl+] ; letter 4
and %00111111
add a, b
ld d, a
; fourth byte
ld a, [hl] ; letter 5
and %00111111
sla a
sla a
ld e, a
pop bc
ret
; Try to find the guess within the dictionary
; -> bc
; -> de
; <- a
find_guess:
ld hl, dictionary
.loop:
; check if the end of the dictionary is reached
push bc
ld bc, dictionary_end
ld a, h
cp a, b
jp nz, .not_eof
ld a, l
cp a, c
jp nz, .not_eof
pop bc
jp .return
.not_eof:
pop bc
ld a, [hl+]
cp a, b
jp nz, .add3
ld a, [hl+]
cp a, c
jp nz, .add2
ld a, [hl+]
cp a, d
jp nz, .add1
ld a, [hl+]
cp a, e
jp nz, .add0
ld a, 1
ret
.add3:
inc hl
.add2:
inc hl
.add1:
inc hl
.add0:
jp .loop
.return:
ld a, 0
ret

22
inc/wincondition.asm

@ -1,17 +1,4 @@
;; ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ; Check if the guess is valid
;; ██░███░██▄██░▄▄▀███▀▄▀█▀▄▄▀█░▄▄▀█░▄▀██▄██▄░▄██▄██▀▄▄▀█░▄▄▀██
;; ██░█░█░██░▄█░██░███░█▀█░██░█░██░█░█░██░▄██░███░▄█░██░█░██░██
;; ██▄▀▄▀▄█▄▄▄█▄██▄████▄███▄▄██▄██▄█▄▄██▄▄▄██▄██▄▄▄██▄▄██▄██▄██
;; ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
;; Functions to be able to detect the end of the game.
; Check if the guess attempt is valid
; -> [guess]
; -> [current_guess]
; -> [current_char]
; -> [obj_message]
; <- a: whether the test is valid or not
check_guess: check_guess:
push hl push hl
push af push af
@ -27,6 +14,7 @@ check_guess:
; and then search after it. ; and then search after it.
call compress_guess call compress_guess
call find_guess call find_guess
cp a, 1 cp a, 1
jp nz, .is_invalid jp nz, .is_invalid
@ -68,10 +56,8 @@ check_guess:
; Check if guessed correctly and therefore won ; Check the win conditions
; -> [current_word] ; <- a
; -> [current_guess]
; <- a: whether it is correct or not
check_win: check_win:
call get_guess_offset call get_guess_offset
ld bc, current_word ld bc, current_word

1
maps/window-game.asm

@ -1,5 +1,4 @@
; Window map while in game ; Window map while in game
DB $1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b
DB $1b,$1b,$01,$1b,$02,$1b,$03,$1b,$04,$1b,$05,$1b,$06,$1b,$07,$1b,$08,$1b,$09,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b DB $1b,$1b,$01,$1b,$02,$1b,$03,$1b,$04,$1b,$05,$1b,$06,$1b,$07,$1b,$08,$1b,$09,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b
DB $1b,$1b,$0a,$1b,$0b,$1b,$0c,$1b,$0d,$00,$0e,$1b,$0f,$1b,$10,$1b,$11,$1b,$12,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b DB $1b,$1b,$0a,$1b,$0b,$1b,$0c,$1b,$0d,$00,$0e,$1b,$0f,$1b,$10,$1b,$11,$1b,$12,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b
DB $1b,$1b,$13,$1b,$14,$1b,$15,$1b,$16,$1b,$17,$1b,$18,$1b,$19,$1b,$1a,$1b,$1e,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b DB $1b,$1b,$13,$1b,$14,$1b,$15,$1b,$16,$1b,$17,$1b,$18,$1b,$19,$1b,$1a,$1b,$1e,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b

8
maps/window-help.asm

@ -1,6 +1,6 @@
; Window map while within help ; Window map while within help
DB $1b,$1b,$13,$14,$01,$12,$14,$1b,$1b,$0e,$05,$17,$1b,$07,$01,$0d,$05,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b
DB $1b,$1b,$13,$05,$0c,$05,$03,$14,$1b,$03,$08,$05,$03,$0b,$1b,$17,$0f,$12,$04,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b
DB $1b,$1b,$02,$22,$01,$1b,$1b,$1b,$1b,$04,$05,$22,$13,$05,$0c,$05,$03,$14,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b
DB $1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b DB $1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b
DB $1b,$1b,$13,$14,$01,$12,$14,$1b,$22,$0e,$05,$17,$1b,$07,$01,$0d,$05,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b
DB $1b,$1b,$13,$05,$0c,$05,$03,$14,$22,$03,$08,$05,$03,$0b,$1b,$17,$0f,$12,$04,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b
DB $1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b
DB $1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b

17
tiles/sign-arrow.asm

@ -1,17 +0,0 @@
; Slash
DB %00000000, \
%00000000, \
%00000000, \
%00000000, \
%00001000, \
%00001000, \
%00000100, \
%00000100, \
%01111110, \
%01111110, \
%00000100, \
%00000100, \
%00001000, \
%00001000, \
%00000000, \
%00000000

17
tiles/sign-slash.asm

@ -0,0 +1,17 @@
; Slash
DB %00000000, \
%00000000, \
%00000010, \
%00000010, \
%00000100, \
%00000100, \
%00001000, \
%00001000, \
%00010000, \
%00010000, \
%00100000, \
%00100000, \
%01000000, \
%01000000, \
%10000000, \
%10000000, \

121
wordle.asm

@ -1,15 +1,5 @@
;; ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
;; ██░███░█▀▄▄▀█░▄▄▀█░▄▀█░██░▄▄██
;; ██░█░█░█░██░█░▀▀▄█░█░█░██░▄▄██
;; ██▄▀▄▀▄██▄▄██▄█▄▄█▄▄██▄▄█▄▄▄██
;; ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
;; The famous word puzzle
; Include hardware-specific constants
; used all over the code.
include "inc/constants.asm" include "inc/constants.asm"
;; Game specific constants ;; Game specific constants
; Game states ; Game states
STATE_MENU EQU %00000001 STATE_MENU EQU %00000001
@ -32,28 +22,28 @@ TILE_ENTER EQU $1e
TILE_RIGHT EQU $1f TILE_RIGHT EQU $1f
TILE_MISPLACED EQU $20 TILE_MISPLACED EQU $20
TILE_WRONG EQU $21 TILE_WRONG EQU $21
TILE_ARROW EQU $22 TILE_SLASH EQU $22
; Vertical blanking interrupt starting address ; Vertical blanking interrupt starting address
SECTION "ENTRY_VBLANK", ROM0[$0040] SECTION "ENTRY_VBLANK", ROM0[$0040]
jp int_vblank ; used for game logic updates jp int_vblank
; LCDC status interrupt starting address ; LCDC status interrupt starting address
SECTION "ENTRY_LCDCS", ROM0[$0048] SECTION "ENTRY_LCDCS", ROM0[$0048]
reti ; we don't use this interrupt reti
; Timer overflow interrupt starting address ; Timer overflow interrupt starting address
SECTION "ENTRY_TIMER", ROM0[$0050] SECTION "ENTRY_TIMER", ROM0[$0050]
jp int_timer ; used for generating randomness jp int_timer
; Serial transfer completion interrupt starting address ; Serial transfer completion interrupt starting address
SECTION "ENTRY_SERIAL", ROM0[$0058] SECTION "ENTRY_SERIAL", ROM0[$0058]
reti ; we don't use this interrupt reti
; Program starting address ; Program starting address
@ -64,8 +54,7 @@ SECTION "ENTRY_START", ROM0[$0100]
SECTION "MAIN", ROM0[$0150] SECTION "MAIN", ROM0[$0150]
main: main:
; turn the screen off until everything is initialized, ; turn the screen off until everything is initialised
; or wild glitches will appear
ld a, DISPLAY_OFF ld a, DISPLAY_OFF
ld [LCD_CONTROL_REGISTER], a ld [LCD_CONTROL_REGISTER], a
ld [LCD_STATUS_REGISTER], a ld [LCD_STATUS_REGISTER], a
@ -110,6 +99,7 @@ main_loop:
.within_vblank: .within_vblank:
call update_oam call update_oam
call read_input call read_input
ld a, [current_state] ld a, [current_state]
.in_menu: .in_menu:
@ -166,6 +156,7 @@ include "inc/dict.asm"
include "inc/input.asm" include "inc/input.asm"
include "inc/guess.asm" include "inc/guess.asm"
include "inc/hints.asm" include "inc/hints.asm"
include "inc/search.asm"
include "inc/messages.asm" include "inc/messages.asm"
include "inc/wincondition.asm" include "inc/wincondition.asm"
include "inc/interrupts.asm" include "inc/interrupts.asm"
@ -174,10 +165,7 @@ include "inc/interrupts.asm"
;; Game data ;; Game data
SECTION "DATA0", ROM0[$1000] SECTION "DATA0", ROM0[$1000]
; Tiles
;; Tiles
; Small 8x8 pixel images, which are addressable
; and will be used for sprite maps and objects.
tiles_start: tiles_start:
tile_null: tile_null:
include "tiles/plain-null.asm" include "tiles/plain-null.asm"
@ -197,16 +185,15 @@ tile_misplaced:
include "tiles/sign-misplaced.asm" include "tiles/sign-misplaced.asm"
tiles_wrong: tiles_wrong:
include "tiles/sign-wrong.asm" include "tiles/sign-wrong.asm"
tiles_arrow: tiles_slash:
include "tiles/sign-arrow.asm" include "tiles/sign-slash.asm"
tiles_logo: tiles_logo:
include "tiles/logo.asm" include "tiles/logo.asm"
tiles_end: tiles_end:
;; Maps
; Each map defines a grid of tile addresses, ; Maps
; which combined will form the desired image.
maps_start: maps_start:
background: background:
include "maps/background.asm" include "maps/background.asm"
@ -216,20 +203,13 @@ window_game:
include "maps/window-game.asm" include "maps/window-game.asm"
maps_end: maps_end:
;; Dictionary
; A list of known words to choose from.
dictionary: dictionary:
incbin "dict/en.dat" incbin "dict/en.dat"
dictionary_end: dictionary_end:
DB
;; Help data ; Help data
; The help screen will reuse the normal
; game mechanics to provide a manual
; how to play this game.
; Now following is hard coded-data
; to provide a set of information.
help_word: help_word:
DB $12, $09, $07, $08, $14 ; right DB $12, $09, $07, $08, $14 ; right
@ -250,11 +230,7 @@ help_guess_hints:
DB TILE_WHITE, TILE_WHITE, TILE_WHITE, TILE_WHITE, TILE_WHITE DB TILE_WHITE, TILE_WHITE, TILE_WHITE, TILE_WHITE, TILE_WHITE
;; Messages ; Messages
; This game uses a message system to
; provide feedback to the user.
; For this, nine objects are reserved
; and can be used at will.
message_clear: message_clear:
DB $00, $00, $00, $00 DB $00, $00, $00, $00
DB $00, $00, $00, $00 DB $00, $00, $00, $00
@ -289,41 +265,41 @@ message_menu_help:
DB $90, $80, 25, OBJ_ATTR_PALETTE1 ; Y DB $90, $80, 25, OBJ_ATTR_PALETTE1 ; Y
message_unknown: message_unknown:
DB $78, $38, 21, OBJ_ATTR_PALETTE1 ; U DB $74, $38, 21, OBJ_ATTR_PALETTE1 ; U
DB $78, $40, 14, OBJ_ATTR_PALETTE1 ; N DB $74, $40, 14, OBJ_ATTR_PALETTE1 ; N
DB $78, $48, 11, OBJ_ATTR_PALETTE1 ; k DB $74, $48, 11, OBJ_ATTR_PALETTE1 ; k
DB $78, $50, 14, OBJ_ATTR_PALETTE1 ; N DB $74, $50, 14, OBJ_ATTR_PALETTE1 ; N
DB $78, $58, 15, OBJ_ATTR_PALETTE1 ; O DB $74, $58, 15, OBJ_ATTR_PALETTE1 ; O
DB $78, $60, 23, OBJ_ATTR_PALETTE1 ; W DB $74, $60, 23, OBJ_ATTR_PALETTE1 ; W
DB $78, $68, 14, OBJ_ATTR_PALETTE1 ; N DB $74, $68, 14, OBJ_ATTR_PALETTE1 ; N
DB $00, $00, 0, 0 DB $00, $00, 0, 0
DB $00, $00, 0, 0 DB $00, $00, 0, 0
message_won: message_won:
DB $78, $38, 25, OBJ_ATTR_PALETTE1 ; Y DB $74, $38, 25, OBJ_ATTR_PALETTE1 ; Y
DB $78, $40, 15, OBJ_ATTR_PALETTE1 ; O DB $74, $40, 15, OBJ_ATTR_PALETTE1 ; O
DB $78, $48, 21, OBJ_ATTR_PALETTE1 ; U DB $74, $48, 21, OBJ_ATTR_PALETTE1 ; U
DB $78, $58, 23, OBJ_ATTR_PALETTE1 ; W DB $74, $58, 23, OBJ_ATTR_PALETTE1 ; W
DB $78, $60, 15, OBJ_ATTR_PALETTE1 ; O DB $74, $60, 15, OBJ_ATTR_PALETTE1 ; O
DB $78, $68, 14, OBJ_ATTR_PALETTE1 ; N DB $74, $68, 14, OBJ_ATTR_PALETTE1 ; N
DB $00, $00, 0, 0 DB $00, $00, 0, 0
DB $00, $00, 0, 0 DB $00, $00, 0, 0
DB $00, $00, 0, 0 DB $00, $00, 0, 0
message_lost: message_lost:
DB $78, $30, 9, OBJ_ATTR_PALETTE1 ; I DB $74, $30, 9, OBJ_ATTR_PALETTE1 ; I
DB $78, $38, 20, OBJ_ATTR_PALETTE1 ; T DB $74, $38, 20, OBJ_ATTR_PALETTE1 ; T
DB $78, $40, 19, OBJ_ATTR_PALETTE1 ; S DB $74, $40, 19, OBJ_ATTR_PALETTE1 ; S
DB $78, $50, 0, OBJ_ATTR_PALETTE1 ; guess[0] DB $74, $50, 0, OBJ_ATTR_PALETTE1 ; guess[0]
DB $78, $58, 0, OBJ_ATTR_PALETTE1 ; guess[1] DB $74, $58, 0, OBJ_ATTR_PALETTE1 ; guess[1]
DB $78, $60, 0, OBJ_ATTR_PALETTE1 ; guess[2] DB $74, $60, 0, OBJ_ATTR_PALETTE1 ; guess[2]
DB $78, $68, 0, OBJ_ATTR_PALETTE1 ; guess[3] DB $74, $68, 0, OBJ_ATTR_PALETTE1 ; guess[3]
DB $78, $70, 0, OBJ_ATTR_PALETTE1 ; guess[4] DB $74, $70, 0, OBJ_ATTR_PALETTE1 ; guess[4]
DB $00, $00, 0, 0 DB $00, $00, 0, 0
;; Address reservations within the working ram ; Address reservations within the working ram
SECTION "RAM", WRAM0 SECTION "RAM", WRAM0
; The first 160 Bytes are reserved for a copy ; The first 160 Bytes are reserved for a copy
; of the OAM data, which will be updated via DMA. ; of the OAM data, which will be updated via DMA.
@ -343,7 +319,7 @@ obj_dma_padding:
vblank_flag: vblank_flag:
DB DB
; Saves the current random number consisting of 16 bits ; Saves the current 16bit random number
random_number: random_number:
DS 2 DS 2
@ -351,19 +327,19 @@ random_number:
input_state: input_state:
DB DB
; Saves the current game state (see STATE constants) ; Saves the current game state
current_state: current_state:
DB DB
; Saves the subordinate state (see STATE constants) ; Saves the state in the submenu
sub_state: sub_state:
DB DB
; Number of the current guess (0..5) ; Number of the current guess
current_guess: current_guess:
DB DB
; Position within the current guess (0..4) ; Position within the current guess
current_char: current_char:
DB DB
@ -372,22 +348,21 @@ current_word:
DS 5 DS 5
; The guess attempts ; The guess attempts
guess_attempts: guesses:
DS 30 DS 30
; The corresponding hints ; The corresponding hints
guess_hints: guesses_hints:
DS 30 DS 30
; Message timeout (remaining number of frames) ; Message timeout
message_timeout: message_timeout:
DB DB
; Horizontal position of the letter selection within the alphabet grid ; Horizontal position of the letter selection
selected_letter_x: selected_letter_x:
DB DB
; Vertical position of the letter selection within the alphabet grid ; Vertical position of the letter selection
selected_letter_y: selected_letter_y:
DB DB

BIN
wordle.gb

Binary file not shown.
Loading…
Cancel
Save