mapgen: refactored map loader
authorLukas Krickl <lukas@krickl.dev>
Thu, 21 Aug 2025 03:58:30 +0000 (05:58 +0200)
committerLukas Krickl <lukas@krickl.dev>
Thu, 21 Aug 2025 03:58:30 +0000 (05:58 +0200)
src/map.s
src/mapgen.s
src/roompatterns.s

index a1463a2e798568d8597ca31c06caceba2851f513..3cbf1286d9805c4f8bfe2597a53da4ae092afcdb 100644 (file)
--- a/src/map.s
+++ b/src/map.s
@@ -1,3 +1,26 @@
+       
+       ; disables the lcd
+       ; call before map_load
+map_load_start:
+  ; disable interruts
+  ; wait for next blank
+  ; disable lcd
+  call disableinterrutpts
+  call next_vblank_wait 
+  call lcd_off
+       ret
+       
+       ; draws the map
+       ; enables the lcd
+       ; call after map_load
+map_load_end:
+  call map_draw_all
+
+  ; restore lcd and interrupts
+  call lcd_on
+  call vblank_wait
+  call enableinterrupts
+       ret
 
   ; loads a new map
   ; inputs:
   ; TODO: do not touch lcd or interrupts if 
   ; they were not enabled!
 map_load:
-       push hl
-       call act_sg_store
-       pop hl
-
        ; backup the map header
        ld a, l
        ld [map_header], a
        ld a, h
        ld [map_header+1], a
 
-  ; disable interruts
-  ; wait for next blank
-  ; disable lcd
-  call disableinterrutpts
-  call next_vblank_wait 
-  call lcd_off
   
   push hl
   call map_draw_area_title
@@ -47,63 +60,6 @@ map_load:
   push hl
   call map_load_exit_table
   pop hl
-  
-  push hl
-  call map_call_gen
-  pop hl
-
-       push hl
-       call act_sg_restore
-       pop hl
-
-  call map_draw_all
-
-  ; restore lcd and interrupts
-  call lcd_on
-  call vblank_wait
-  call enableinterrupts
-
-  ret
-
-  ; calls mapgen unless disabled
-  ; for current map
-  ; loads the seed based on map offset
-  ; inputs:
-  ;   hl: map_ptr
-map_call_gen:
-  push hl
-  
-  ; check if rand is disabled
-  ld de, map_flags_1
-  add hl, de
-  ld a, [hl]
-  and a, MAPF1_NO_RAND
-
-  pop hl
-  ; bail if flag is set
-  ret nz
-
-  ; load seed offset
-  push hl
-  
-       ld a, [player_map_cursor]
-
-  ; * 2 because it is a 2-byte table
-  add a, a
-  ld d, 0
-  ld e, a  
-  ld hl, map_seeds
-  add hl, de
-  ; hl = seeds+offset
-  ld a, [hl+] ; a = seed LO
-  ld d, a
-  ld a, [hl]
-  ld e, a ; de = seed
-
-  pop hl
-  
-  ld hl, map
-  call mapgen
 
   ret
 
index 8a1bf62ffbb6ea99b825ef5fbb123df851ec5ed8..374a3f4e4f100d8012c55665116a17e8f278c37a 100644 (file)
@@ -8,16 +8,49 @@ mapgen_init:
        call act_save_init
        call mapgen_seed
        call mapgen_make_doors
-       call mapgen_select_map
-       call map_load
+       call mapgen
        ret
        
+       ; selects a room pattern table
+       ; returns:
+       ;               hl: pattern table
+       ;                a: size
+mapgen_select_pattern_table:
+       ; TODO: select different tables based on floor
+       ld hl, room_patterns_floor1
+       ld a, ((room_patterns_floor1_end - room_patterns_floor1) / 2) - 1
+       ret
+
        ; selects a map from the tables based on the current floor
        ; and the current cursor seed
        ; returns:
        ;               hl: map pointer
 mapgen_select_map:
-  ld hl, map_c_header 
+       call mapgen_select_pattern_table
+       push hl
+
+  ld b, a
+  call rand
+  and a, b ; cap rand to table size
+
+       pop hl
+
+       add a, a ; * 2 because its a 2-byte table
+
+  ld b, 0
+  ld c, a
+  add hl, bc
+
+  ; load table ptr
+  ld a, [hl+]
+  ld c, a
+  ld a, [hl]
+  ld b, a
+
+       ld l, c
+       ld h, b
+
+
        ret
 
 
@@ -38,26 +71,37 @@ mapgen_seed:
 
 
   ret
+       
+       ; loads the current seed based on player map cursor
+       ; returns:
+       ;               de: the seed
+mapgen_load_seed:
+       ld a, [player_map_cursor]
+       add a, a ; * 2 because it is a 2-byte table
+       ld d, 0
+       ld e, a
+       ld hl, map_seeds
+       add hl, de
+       ; hl = seeds+offset
+       ld a, [hl+]
+       ld d, a
+       ld a, [hl]
+       ld e, a ; de = seed
+       ret
 
   ; places a rectangular room
   ; into the currently loaded map
-  ; 1) places room patterns in top left, top right, bottom left, bottom right
-  ;    patterns are chosen from a list of valid patterns which is determined by
-  ;    the current floor
-  ; 6) place larger room patterns that may overwrite existing patterns
-  ; 5) run floor-based post processing (look up routine from table)
-  ; 7) palce actors on floor tiles based on a table of actors 
-  ;    chosen based on the floor
-  ; inputs:
-  ;   hl: writable decompressed tile array (e.g [map]) 
-  ;       of size MAP_H * MAP_W
-  ;   de: the seed used
-       ;       map_header: the current map header
+       ;       1) selects a random map to draw
+       ;               2) places doors
+       ;               3) places actors
+       ;               4) reloads actor sg
+       ;               5) draws map
   ; preserves:
   ;   srand
 mapgen:
-  ; roll a room size
+       call map_load_start
 
+       call act_sg_store
   ; load seed
   ; and back it up
   ld a, [srand]
@@ -65,20 +109,19 @@ mapgen:
   ld a, [srand+1]
   ld c, a
   push bc
+
+
+       call mapgen_load_seed
   
   ; load seed param
   ld a, e
   ld [srand+1], a
   ld a, d
   ld [srand], a
-  
-  ; generate first room
-  call mapgen_up_left_room
-  call mapgen_bottom_left_room
-  call mapgen_up_right_room
-  call mapgen_bottom_right_room
-
-  call mapgen_place_special_room
+       
+       call mapgen_select_map
+       call map_load
+       ld hl, map
        
        call mapgen_draw_doors
 
@@ -92,6 +135,10 @@ mapgen:
   ld b, a
   ld [srand], a
 
+       call act_sg_restore
+
+       call map_load_end
+
   ret
        
        ; generates door locations for each map
@@ -178,337 +225,12 @@ mapgen_draw_doors:
 
        ret
 
-  ; selects a random room pattern
-  ; inputs:
-  ;   hl: room pattern table
-  ;    a: table size
-  ; returns: 
-  ;   bc: room pattern ptr
-mapgen_select_pattern:
-  push hl
-
-  ld b, a
-  call rand
-  and a, b ; cap rand to table size
-
-  pop hl
-
-  ld b, 0
-  ld c, a
-  add hl, bc
-
-
-  ; load table ptr
-  ld a, [hl+]
-  ld c, a
-  ld a, [hl]
-  ld b, a
-
-  ret
-
-  ; select room pattern 6x6
-  ; preserves: hl
-mapgen_select_pattern_6x6:
-  push hl
-  ld a, ROOM_PATTERN_6X6_SIZE
-  ld hl, room_pattern_6x6
-  call mapgen_select_pattern
-  pop hl
-  ret
-
-  ; inputs:
-  ;   hl: [map]
-  ; preserves: hl
-mapgen_up_left_room:
-  push hl
-  
-  ; move to correct location on map
-  ld bc, MAP_W*c_size
-  add hl, bc
-  inc hl
-  inc hl 
-
-  call mapgen_select_pattern_6x6
-
-  call mapgen_draw_room_pattern
-  pop hl
-  ret
-
-
-  ; inputs:
-  ;   hl: [map]
-  ; preserves: hl
-mapgen_bottom_left_room:
-  push hl
-  
-  ; move to correct location on map
-  ld bc, MAP_W*9*c_size
-  add hl, bc
-  inc hl
-  inc hl 
-
-  call mapgen_select_pattern_6x6
-
-  call mapgen_draw_room_pattern
-  pop hl
-  ret
-
-  ; inputs:
-  ;   hl: [map]
-  ; preserves: hl
-mapgen_up_right_room:
-  push hl
-  
-  ; move to correct location on map
-  ld bc, (MAP_W/2)*c_size + MAP_W*c_size
-  add hl, bc
-  inc hl
-  inc hl 
-
-  call mapgen_select_pattern_6x6
-
-  call mapgen_draw_room_pattern
-  pop hl
-  ret
-
-
-  ; inputs:
-  ;   hl: [map]
-  ; preserves: hl
-mapgen_bottom_right_room:
-  push hl
-  
-  ; move to correct location on map
-  ld bc, (MAP_W/2)*c_size + MAP_W*9*c_size
-  add hl, bc
-  inc hl
-  inc hl 
-
-  call mapgen_select_pattern_6x6
-
-  call mapgen_draw_room_pattern
-  pop hl
-  ret
-  
-  ; rolls rng
-  ; if value > 128 a random special room is placed
-  ; special rooms overwrite other rooms and are larger room
-  ; patterns
-  ; special rooms are placed starting in the top left corner 
-  ; inputs:
-  ;   hl: [map]
-       ; preserves: hl
-mapgen_place_special_room:
-  push hl
-  call rand
-  and a, 0x80
-  pop hl
-  ret z ; bail if no speical room is requested
-
-       push hl
-
-  ; move to correct location on map
-  ld bc, MAP_W*c_size
-  add hl, bc
-  inc hl
-  inc hl 
-  ; pick a room from the special pattern list
-
-  push hl
-  ld a, ROOM_PATTERN_SPECIAL_SIZE
-  ld hl, room_pattern_special
-  call mapgen_select_pattern
-  pop hl
-
-  call mapgen_draw_room_pattern
-       
-       pop hl
-  ret
-
-
-  ; draws a room pattern to the map
-  ; inputs:
-  ;   hl: origin inside of map struct
-  ;   bc: room pattern header pointer
-mapgen_draw_room_pattern:
-  ld a, [bc] ; read room pattern size
-  and a, 0x0F ; number of tiles per row 
-  ; e = tile per row counter
-  ld e, a
-
-  ld a, [bc]
-  and a, 0xF0 ; number of rows
-  swap a
-  ld d, a ; d = number of rows
-  
-  inc bc ; move past header
-  ; bc = first room pattern entry
-@y_loop:
-    push hl
-    call mapgen_draw_room_pattern_row
-    pop hl
-    
-    push bc
-    ld bc, MAP_W*c_size
-    add hl, bc ; next row
-    pop bc
-
-    dec d
-  jr nz, @y_loop REL
-
-  ret
-
-  ; reads a value from a table
-  ; inputs:
-  ;   a: pattern value
-  ;   $1: table name
-  ; preserves: hl and de
-#macro mapgen_read_value_from_table
-    push hl
-    push de
-    ld hl, $1 
-    ld d, 0
-    ld e, a
-    add hl, de ; hl = offset into table
-    ld a, [hl]
-    pop de
-    pop hl
-#endmacro
-
-  ; draws a single map pattern row
-  ; writes tile flags
-       ; if a door is about to be placed next to 
-       ; and existing wall the door is replaced with a 
-       ; wall tile
-  ; inputs:
-  ;   hl: map ptr
-  ;   bc: room pattern 
-  ;    e: tiles per row counter
-  ; preserves:
-  ;   de
-  ; returns:
-  ;   hl: incremented by number of tiles * c_size
-  ;   bc: incremented by number of tiles
-mapgen_draw_room_pattern_row:
-  push de  
-@x_loop:
-    ld a, [bc]
-               call mapgen_fix_door_adjacent_to_collider
-               ; save result pattern value
-               push af
-
-    ; read from tile and flag tables and write to map
-
-    ; tile table first
-    mapgen_read_value_from_table room_pattern_tile_translation
-    ; write to map
-    ld [hl+], a ; write tile
-    
-    ; read pattern again
-               pop af
-    
-    ; now flags table
-    mapgen_read_value_from_table room_pattern_flags_translation
-
-    ; write to flags
-    ld [hl+], a
-
-    ; hl = next tile
-    inc bc ; next pattern
-
-    ; tiles--
-    dec e
-  jr nz, @x_loop REL
-
-  pop de
-  ret
-
-
-       ; performs fix by checking if a tile 
-       ; at a certain offset relative to a door
-       ; is a collider
-       ; inputs:
-       ;               $1: the offset relative to the current map position
-       ;         $2: the wall pattern to use if a collider is found
-       ;               hl: map_ptr
-       ;                a: pattern entry
-       ;
-       ;       preserves:
-       ;               hl, bc, de
-#macro mapgen_fix_door_fixup
-.beginscope
-       push hl
-       push de
-
-       ; move left one tile
-       ; and check for colliders
-       ld de, ($1) & 0xFFFF
-       add hl, de
-       ; hl = tile to the left
-
-       inc hl ; go to flags
-       ld d, a ; store a for later
-       ld a, [hl]
-       and a, CF_COLLISION
-       ld a, d ; restore a's value
-
-       ; if not collider do not fix
-       jr z, @no_fix REL
-               ; otherwise load left wall into a
-               ld a, $2 
-       @no_fix:
-
-       pop de
-       pop hl
-.endscope
-#endmacro
-
-
-       ; fixed door tile if it is adjacent to
-       ; a collider tile
-       ; inputs:
-       ;       hl: map_ptr
-       ;                a: pattern entry
-       ; returns:
-       ;               a: unchanged if not next to collider or not a door pattern
-       ;   a: changed to wall tile if it is a door and is next to a collider
-       ; preserves:
-       ;               hl, bc, de
-mapgen_fix_door_adjacent_to_collider:
-       cp a, RPDU
-       jp z, @up_door 
-
-       cp a, RPDB
-       jp z, @down_door 
-
-       cp a, RPDL
-       jp z, @left_door 
-
-       cp a, RPDR
-       jp z, @right_door 
-
-       ret
-@up_door:
-       mapgen_fix_door_fixup (-c_size) * MAP_W, RPUW
-       ret
-@down_door:
-       mapgen_fix_door_fixup c_size * MAP_W, RPBW
-       ret
-@left_door:
-       mapgen_fix_door_fixup -c_size, RPLW
-       ret
-@right_door:
-       mapgen_fix_door_fixup c_size, RPRW      
-
-       ret
-
        ; places actors from a valid actor table
        ; from the current floor value. This will overwrite the 
        ; header loaded by map_load. Preserves player entry.
        ; the length of the actor table must be maskable
        ; inputs:
        ;               a loaded map
-       ;               [map_header] ptr
 mapgen_place_actors:
        ; clear everything past player
        ld hl, p0_units + act_size 
index 03838a91b662d293f22bc9a8f41e37477372bb15..6903e6064c22d4cf77d60a849288e1ab25cd105e 100644 (file)
-
-.se 0 ; roomp_header
-  ; height in tiles | width in tiles
-  ; nnnn0000         0000nnnn
-.de rp_header_width_height, 1
-.de rp_header_size, 0
-
-  ; room pattern header
-  ; inputs:
-  ;   $1: width/height 
-#macro rpheaderdef
-  .db $1
-#endmacro
-
-  ; room pattern row
-  ; inputs:
-  ;   $1-$6: RP entry
-#macro rprow
-  .db $1, $2, $3, $4, $5, $6
-#endmacro
-
-; template rooms
-; rooms are template patterns that can be placed
-; on maps
-; the room pattern tiles used depend on the current floor
-; each pattern entry has a specific flag set that is placed in the map
-; room patterns are N by M areas with the following properties:
-.se 0
-  ; room pattern up left corner
-.de RPUL, 1
-  ; room pattern up wall
-.de RPUW, 1
-  ; room pattern up right corner
-.de RPUR, 1
-  ; left wall
-.de RPLW, 1
-.de RPRW, 1
-  ; bottom right corner
-.de RPBR, 1
-  ; bottom wall
-.de RPBW, 1
-  ; bottom left corner
-.de RPBL, 1
-  ; floor
-.de RPFL, 1
-  ; door up
-.de RPDU, 1
-  ; door bottom 
-.de RPDB, 1
-  ; door left
-.de RPDL, 1
-  ; door right
-.de RPDR, 1
-       ; roof 
-.de RPRF, 1
-
-room_pattern_empty:
-  rpheaderdef 0x66
-  rprow RPFL, RPFL, RPFL, RPFL, RPFL, RPFL
-  rprow RPFL, RPFL, RPFL, RPFL, RPFL, RPFL
-  rprow RPFL, RPFL, RPFL, RPFL, RPFL, RPFL
-  rprow RPFL, RPFL, RPFL, RPFL, RPFL, RPFL
-  rprow RPFL, RPFL, RPFL, RPFL, RPFL, RPFL
-  rprow RPFL, RPFL, RPFL, RPFL, RPFL, RPFL
-
-room_pattern1:
-  rpheaderdef 0x66 
-  rprow RPUL, RPUW, RPUW, RPDU, RPUW, RPUR
-  rprow RPLW, RPRF, RPRF, RPRF, RPRF, RPRW
-  rprow RPLW, RPRF, RPRF, RPRF, RPRF, RPRW
-  rprow RPLW, RPRF, RPRF, RPRF, RPRF, RPRW
-  rprow RPLW, RPRF, RPRF, RPRF, RPRF, RPRW
-  rprow RPBL, RPBW, RPBW, RPDB, RPBW, RPBR
-
-room_pattern2:
-  rpheaderdef 0x66 
-  rprow RPUL, RPUW, RPUW, RPDU, RPUW, RPUR
-  rprow RPLW, RPRF, RPRF, RPRF, RPRF, RPRW
-  rprow RPLW, RPRF, RPRF, RPRF, RPRF, RPRW
-  rprow RPDL, RPRF, RPRF, RPRF, RPRF, RPDR
-  rprow RPLW, RPRF, RPRF, RPRF, RPRF, RPRW
-  rprow RPBL, RPBW, RPBW, RPDB, RPBW, RPBR
-
-room_pattern3:
-  rpheaderdef 0x66
-  rprow RPFL, RPFL, RPFL, RPFL, RPFL, RPFL
-  rprow RPFL, RPUL, RPUW, RPUW, RPUR, RPFL
-  rprow RPFL, RPFL, RPFL, RPFL, RPLW, RPFL
-  rprow RPFL, RPFL, RPFL, RPFL, RPLW, RPFL
-  rprow RPFL, RPFL, RPDB, RPBW, RPBR, RPFL
-  rprow RPFL, RPFL, RPFL, RPFL, RPFL, RPFL
-
-room_pattern_special1:
-  rpheaderdef 0x6E
-  .db RPUL, RPUW, RPUW, RPDU, RPUW, RPUW, RPUW, RPUW, RPUW, RPUW, RPUW, RPUW, RPUW, RPUR
-  .db RPLW, RPRF, RPRF, RPRF, RPRF, RPRF, RPRF, RPRF, RPRF, RPRF, RPRF, RPRF, RPRF, RPRW
-  .db RPLW, RPRF, RPRF, RPRF, RPRF, RPRF, RPRF, RPRF, RPRF, RPRF, RPRF, RPRF, RPRF, RPRW
-  .db RPLW, RPRF, RPRF, RPRF, RPRF, RPRF, RPRF, RPRF, RPRF, RPRF, RPRF, RPRF, RPRF, RPRW
-  .db RPLW, RPRF, RPRF, RPRF, RPRF, RPRF, RPRF, RPRF, RPRF, RPRF, RPRF, RPRF, RPRF, RPRW
-  .db RPBL, RPBW, RPBW, RPBW, RPBW, RPDB, RPBW, RPBW, RPBW, RPBW, RPBW, RPBW, RPBW, RPBR
-
 #define DOOR_TILE_TOP 0x2E
 #define DOOR_TILE_BOTTOM 0x0E
 #define DOOR_TILE_LEFT 0x0C
 #define DOOR_TILE_RIGHT 0x2C
-  
-
-  ; translation tables for tiles
-room_pattern_tile_translation:
-  ; walls
- .db 0x02, 0x04, 0x06 
- .db 0x22, 0x26, 0x46
- .db 0x44, 0x42
- .db 0x00 ; floor
- ; doors
- .db DOOR_TILE_TOP, DOOR_TILE_BOTTOM, DOOR_TILE_LEFT, DOOR_TILE_RIGHT 
- ; roof
- .db 0x48
-
-  ; translation table for flags
-room_pattern_flags_translation:
- ; walls
- .db CF_COLLISION, CF_COLLISION, CF_COLLISION 
- .db CF_COLLISION, CF_COLLISION, CF_COLLISION 
- .db CF_COLLISION, CF_COLLISION 
- .db 0x00 ; floor
- ; doors
- .db CF_COLLISION | CF_DOOR | CF_COVERED, CF_COLLISION | CF_DOOR | CF_COVERED
- .db CF_COLLISION | CF_DOOR | CF_COVERED, CF_COLLISION | CF_DOOR | CF_COVERED 
- ; roof
- .db CF_COVERED
-
-  ; table of 6 by 6 room patterns
-room_pattern_6x6:
-  ; dw room_pattern_empty
-  dw room_pattern1
-  dw room_pattern1
-  dw room_pattern2
-  dw room_pattern3
-room_pattern_6x6_end:
+       
+       ; table of possible maps
+       ; must be divisible by 2 in size
 
-#define ROOM_PATTERN_6X6_SIZE ((room_pattern_6x6_end - room_pattern_6x6) / 2)
-  
+room_patterns_floor1:
+       dw map_c_header 
+       dw map_ce_header 
+       dw map_cw_header 
+       dw map_be_header
+room_patterns_floor1_end:
 
-  ; table of special room patterns
-room_pattern_special:
-  dw room_pattern_special1
-  dw room_pattern_special1
-room_pattern_special_end:
 
-#define ROOM_PATTERN_SPECIAL_SIZE ((room_pattern_special_end - room_pattern_special) / 2)