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
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]
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
ld b, a
ld [srand], a
+ call act_sg_restore
+
+ call map_load_end
+
ret
; generates door locations for each map
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
-
-.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)