mirror of
https://github.com/Pixinn/rogue-like.git
synced 2024-06-01 12:41:29 +00:00
Compare commits
9 Commits
BLOG_POST_
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
261b7276b5 | ||
|
7c90129e9b | ||
|
5bbb62f36a | ||
|
d1a3affa1d | ||
|
abbd59fd9e | ||
|
4da93af1cb | ||
|
3841faa027 | ||
|
eff3827d20 | ||
|
7fcdb9d800 |
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,4 +1,5 @@
|
|||
.vscode/
|
||||
.DS_Store
|
||||
*.out
|
||||
*.a2
|
||||
*.o
|
||||
|
|
23
Makefile
23
Makefile
|
@ -1,18 +1,23 @@
|
|||
APPLE2_CL := $(CC65_HOME)/bin/cl65
|
||||
APPLE2_SRC := src/main.asm src/math.asm src/random.asm \
|
||||
src/game_loop.asm src/display.asm src/tiles.asm src/world.asm src/player.asm \
|
||||
src/debug.asm
|
||||
APPLE2_SRC := src/main.asm src/math.asm src/memory.asm src/random.asm \
|
||||
src/game_loop.asm src/display.asm src/tiles.asm src/player.asm \
|
||||
src/world/world.asm src/world/level.asm \
|
||||
src/builder/builder.asm src/builder/rooms.asm src/builder/maze.asm src/builder/unite.asm \
|
||||
src/actors/reactions.asm src/actors/actors.asm \
|
||||
src/debug.asm src/display_map.asm \
|
||||
src/io/title.asm src/io/textio.asm src/io/gr.asm src/io/files.asm
|
||||
APPLE2_MAP := escape.map
|
||||
APPLE2_CFLAGS := -Oirs -v -t apple2 -vm --cpu 6502
|
||||
APPLE2_OUT := bin/escape.a2
|
||||
APPLE2_OUT := floppy/ESCAPE
|
||||
|
||||
all: directories apple2
|
||||
|
||||
directories:
|
||||
mkdir -p bin
|
||||
all: apple2
|
||||
|
||||
apple2: $(APPLE2_SRC)
|
||||
$(APPLE2_CL) -m $(APPLE2_MAP) -o $(APPLE2_OUT) $? $(APPLE2_CFLAGS) -C src/escape.cfg
|
||||
|
||||
clean: $(SRC)
|
||||
rm -f $(APPLE2_MAP) src/*.o src/*.s gmon.out & rm -r bin/
|
||||
rm -f $(APPLE2_MAP) floppy/ESCAPE src/*.o src/builder/*.o src/io/*.o src/world/*.o src/actors/*.o gmon.out
|
||||
|
||||
install: apple2
|
||||
./scripts/add-to-disk.sh $(APPLE_COMMANDER) ./floppy escape.dsk
|
||||
|
43
README.md
43
README.md
|
@ -1,34 +1,39 @@
|
|||
# What is it?
|
||||
## What is it?
|
||||
|
||||
**Escape** (working title) is a homebrew *Rogue-Like** game developped for the Apple II computers.
|
||||
**Escape** (working title) is a homebrew *Rogue-Like** game developed for the Apple II computers.
|
||||
|
||||
It is written in assembly and serves two purposes:
|
||||
1. Be fun
|
||||
2. Document the proccess of coding for the Apple II on [my blog](https://www.xtof.info):
|
||||
- [A tile engine for the Apple II](https://www.xtof.info/blog/?p=1044)
|
||||
- [Raycasting a Line of Sight](https://www.xtof.info/blog/?p=1071)
|
||||
- [A tile engine for the Apple II](https://www.xtof.info/an-hires-tile-engine-for-the-apple-ii.html)
|
||||
- [Raycasting a Line of Sight](https://www.xtof.info/appleii-roguelike-line-of-sight.html)
|
||||
- [Random level generation on Apple II](https://www.xtof.info/random-level-generation-on-apple-ii.html)
|
||||
|
||||
# How to build
|
||||
## How to build
|
||||
|
||||
## Building
|
||||
### Prerequisites
|
||||
|
||||
Just type
|
||||
* The build process relies on the assembler provided by the [CC65 compiler suite](https://github.com/cc65/cc65).
|
||||
* Set the environment variable **CC65_HOME** to the root folder of CC65
|
||||
* Builds are guaranteed to be successful using version 2.19 (commit 555282497c3ecf8). They should also work with any subsequent versions.
|
||||
* A makefile compatible with GNU Make is provided.
|
||||
* [AppleCommander](http://applecommander.sourceforge.net/) is used to produce a disk image that can be loaded in any emulator. Apple Commander requires a Java Runtime.
|
||||
* Export the variable **APPLE_COMMANDER** to the path of the jar file.
|
||||
|
||||
make
|
||||
### How to build
|
||||
|
||||
```bash
|
||||
make
|
||||
```
|
||||
|
||||
This will produce *bin/escape.a2* which is a binary executable for Apple's II PRODOS.
|
||||
|
||||
##Prerequisite in order to build:
|
||||
```bash
|
||||
make install
|
||||
```
|
||||
|
||||
The [cc65 compiler suite](https://github.com/cc65/cc65), with the environment variable *CC65_HOME* set to its folder
|
||||
Will produce the executable binary and copy it along with all the required files into the floppy image *escape.dsk*
|
||||
|
||||
## Prerequisite in order to produce the disk image
|
||||
### How to play
|
||||
|
||||
- Java Runtime
|
||||
- [AppleCommander](http://applecommander.sourceforge.net/)
|
||||
|
||||
## Embedding the Apple II' executable into the disk image
|
||||
|
||||
Run
|
||||
|
||||
scripts/add-to-disk.sh
|
||||
You can navigate the levels using the IJKL keys and display a map by pressing TAB.
|
||||
|
|
BIN
assets/tiles.psd
Normal file
BIN
assets/tiles.psd
Normal file
Binary file not shown.
55
doc/Doc.md
Normal file
55
doc/Doc.md
Normal file
|
@ -0,0 +1,55 @@
|
|||
# Documentation
|
||||
|
||||
## Actors
|
||||
|
||||
Actors can be **static** or **dynamic**.
|
||||
Static actors are immutable while dynamic have a link to their status. Both react to the player's actions. For instance a floor or an opened door will let the player pass, while a table or a monster will block him. Dynamic actors can also have a behavior which can evolute by itself each turn, driven by a finite state machine.
|
||||
|
||||
There can be 128 actors of 128 different kinds in a single level. Actor #0 is always the player.
|
||||
|
||||
As there are immutable, many instances of a static actor can be represented by a single ID, while each instance of a dynamic actor require a unique ID.
|
||||
|
||||
In memory, tiles contain the actor ID, which serves as an offset to render the tile, compute its behavior, and so on.
|
||||
|
||||
## Level generation
|
||||
|
||||
Read [this page](https://www.xtof.info/random-level-generation-on-apple-ii.html) for a presentation of the general principle concerning the random level generation.
|
||||
|
||||
The level configuration is given by the *level.conf* file.
|
||||
|
||||
### LEVELS.CONF
|
||||
|
||||
Description of the levels for the random builder.
|
||||
All values are 8-bit integers.
|
||||
|
||||
```text
|
||||
[NB_LEVELS]
|
||||
# level conf * NB_LEVELS
|
||||
[NUMBER]
|
||||
[SIZE]
|
||||
# number of actors of each types * NB_ACTORS_MAX (128)
|
||||
[NB_ACTORS]
|
||||
.
|
||||
.
|
||||
.
|
||||
[NB_ACTORS]
|
||||
```
|
||||
|
||||
### STATES
|
||||
|
||||
State of the levels
|
||||
|
||||
```text
|
||||
"LVLS"
|
||||
CURRENT_LEVEL 1 byte
|
||||
NB_LEVELS 1 byte
|
||||
# level state * NB_LEVELS
|
||||
"LVL"
|
||||
VISITED 1 byte
|
||||
PLAYER_TILE 1 byte
|
||||
LAYOUT 4096 bytes
|
||||
"ACTS"
|
||||
# actor state * NB_LEVELS
|
||||
"ACT"
|
||||
STATE sizeof(actor_t)
|
||||
```
|
BIN
escape.dsk
BIN
escape.dsk
Binary file not shown.
BIN
floppy/ESCAPE
Normal file
BIN
floppy/ESCAPE
Normal file
Binary file not shown.
BIN
floppy/LEVELS.ACTS
Normal file
BIN
floppy/LEVELS.ACTS
Normal file
Binary file not shown.
BIN
floppy/LEVELS.CONF
Normal file
BIN
floppy/LEVELS.CONF
Normal file
Binary file not shown.
BIN
floppy/STATES
Normal file
BIN
floppy/STATES
Normal file
Binary file not shown.
|
@ -6,14 +6,26 @@ set -e
|
|||
|
||||
if (( $# != 3 )); then
|
||||
echo "Bad number of arguments"
|
||||
echo "usage: add_to_disk.sh PATH_TO_APPLECOMMANDER.jar PATH_TO_BINARY.a2 PATH_TO_DISK"
|
||||
echo "usage: add_to_disk.sh PATH_TO_APPLECOMMANDER.jar PATH_TO_FLOPPYDIR PATH_TO_DISK"
|
||||
exit
|
||||
fi
|
||||
|
||||
echo " . revoving previous instance of ESCAPE form the disk"
|
||||
# ###
|
||||
# NOTE:
|
||||
# The loader must have the same basename as the game loaded
|
||||
# ###
|
||||
echo " . removing previous instance of ESCAPE from the disk"
|
||||
java -jar ${1} -d ${3} ESCAPE
|
||||
java -jar ${1} -d ${3} ESCAPE.SYSTEM
|
||||
java -jar ${1} -d ${3} LEVELS.CONF
|
||||
java -jar ${1} -d ${3} LEVELS.ACTS
|
||||
java -jar ${1} -d ${3} STATES
|
||||
|
||||
echo " .. adding ESCAPE to the disk"
|
||||
java -jar ${1} -cc65 ${3} ESCAPE BIN < ${2}
|
||||
echo " .. adding files to the disk"
|
||||
java -jar ${1} -as ${3} ESCAPE BIN < ${2}/ESCAPE
|
||||
java -jar ${1} -p ${3} ESCAPE.SYSTEM SYS < ${CC65_HOME}/target/apple2/util/loader.system
|
||||
java -jar ${1} -p ${3} LEVELS.CONF BIN < ${2}/LEVELS.CONF
|
||||
java -jar ${1} -p ${3} LEVELS.ACTS BIN < ${2}/LEVELS.ACTS
|
||||
java -jar ${1} -p ${3} STATES BIN < ${2}/STATES
|
||||
|
||||
echo "DONE."
|
||||
|
|
|
@ -38,21 +38,52 @@ def fill_rect(x,y,color):
|
|||
outline = (0,0,128),
|
||||
fill = color)
|
||||
|
||||
# returns rays from (x0, y0) to (x1, y1)
|
||||
# output in rays
|
||||
def compute_rays(x0, y0, x1, y1, rays):
|
||||
ray = list(bresenham(x0, y0, x1, y1))
|
||||
# Duplicate the ray so that x and y are not incremented at the same time
|
||||
duplicated = False
|
||||
ray_x = [] # x incremented before y
|
||||
ray_y = [] # y incremented before x
|
||||
x = ray[0][0]
|
||||
y = ray[0][1]
|
||||
for tile in ray[1:]:
|
||||
if tile[0] != x and tile[1] != y:
|
||||
duplicated = True
|
||||
ray_x.append((tile[0], y))
|
||||
ray_x.append((tile[0], tile[1]))
|
||||
ray_y.append((x, tile[1]))
|
||||
ray_y.append((tile[0], tile[1]))
|
||||
else:
|
||||
ray_x.append((tile[0], tile[1]))
|
||||
ray_y.append((tile[0], tile[1]))
|
||||
x = tile[0]
|
||||
y = tile[1]
|
||||
|
||||
rays.append(ray_x)
|
||||
|
||||
if duplicated:
|
||||
rays.append(ray_y)
|
||||
|
||||
return rays
|
||||
|
||||
|
||||
|
||||
if __name__=="__main__":
|
||||
rays = []
|
||||
y = 0
|
||||
for x in range(0,SIZE_GRID-1):
|
||||
rays.append(list(bresenham(x_player,y_player,x,y)))
|
||||
rays = compute_rays(x_player,y_player,x,y, rays)
|
||||
x = SIZE_GRID-1
|
||||
for y in range(0,SIZE_GRID-1):
|
||||
rays.append(list(bresenham(x_player,y_player,x,y)))
|
||||
rays = compute_rays(x_player,y_player,x,y, rays)
|
||||
y = SIZE_GRID-1
|
||||
for x in range(SIZE_GRID-1,0,-1):
|
||||
rays.append(list(bresenham(x_player,y_player,x,y)))
|
||||
rays = compute_rays(x_player,y_player,x,y, rays)
|
||||
x = 0
|
||||
for y in range(SIZE_GRID-1,0,-1):
|
||||
rays.append(list(bresenham(x_player,y_player,x,y)))
|
||||
rays = compute_rays(x_player,y_player,x,y, rays)
|
||||
|
||||
|
||||
# create the grid
|
||||
|
@ -67,7 +98,7 @@ if __name__=="__main__":
|
|||
nb_cells = 0
|
||||
rgb = 0
|
||||
for ray in rays:
|
||||
for tile in ray[1:]:
|
||||
for tile in ray:
|
||||
fill_rect(tile[0], tile[1], (rgb,rgb,rgb))
|
||||
nb_cells += 1
|
||||
rgb += int(200 / len(rays))
|
||||
|
@ -78,8 +109,8 @@ if __name__=="__main__":
|
|||
str_ray = "; Nb rays: {}\n".format(len(rays))
|
||||
str_ray += "; A ray: length (nb_tiles), offset_from_view_in_world_low, offset_from_view_in_world_high, offset_view\nRays:\n"
|
||||
for ray in rays:
|
||||
str_ray += ".byte " + str(len(ray)-1)
|
||||
for tile in ray[1:]:
|
||||
str_ray += ".byte " + str(len(ray))
|
||||
for tile in ray:
|
||||
offset_view = tile[0] + SIZE_GRID*tile[1]
|
||||
offset_world = (tile[0] + WIDTH_WORLD*tile[1])
|
||||
offset_world_low = offset_world & 0xFF
|
||||
|
@ -90,4 +121,4 @@ if __name__=="__main__":
|
|||
print(str_ray)
|
||||
Im.show()
|
||||
|
||||
|
||||
|
||||
|
|
185
src/actors/actors.asm
Normal file
185
src/actors/actors.asm
Normal file
|
@ -0,0 +1,185 @@
|
|||
.include "../common.inc"
|
||||
.include "../random.inc"
|
||||
.include "../memory.inc"
|
||||
.include "../math.inc"
|
||||
.include "../world/world.inc"
|
||||
.include "actors.inc"
|
||||
|
||||
.import Rooms
|
||||
.import World
|
||||
.import Compute_Maze_Addr
|
||||
|
||||
.export ActorsInLevel
|
||||
.export ActorPositions
|
||||
.export ActorStates
|
||||
.export ActorTypes
|
||||
.export ActorTransparent
|
||||
|
||||
|
||||
.BSS
|
||||
|
||||
; struc actors_t {
|
||||
.align 256
|
||||
ActorsInLevel:
|
||||
; aligned 256
|
||||
ActorPositions: .res 256 ; coords_t positions[NB_ACTORS_MAX];
|
||||
; aligned 256
|
||||
ActorStates: .res 256 ; actor_state_t* states[NB_ACTORS_MAX];
|
||||
; aligned 256
|
||||
ActorTypes: .res 128 ; uint8_t types[NB_ACTORS_MAX];
|
||||
; }
|
||||
; NOTE: Modify SIZEOF_ACTORS_T if necessary!!
|
||||
|
||||
.RODATA
|
||||
|
||||
.align 256
|
||||
ActorTransparent: ; NB_ACTORS_MAX
|
||||
; player
|
||||
.byte TRUE
|
||||
; floors
|
||||
.byte TRUE, TRUE, TRUE, TRUE, TRUE, TRUE
|
||||
; walls
|
||||
.byte FALSE, FALSE, FALSE, FALSE
|
||||
; stair down
|
||||
.byte TRUE
|
||||
; stair up
|
||||
.byte FALSE
|
||||
; monsters
|
||||
.byte TRUE, TRUE, TRUE
|
||||
; others
|
||||
.byte TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE
|
||||
.byte TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE
|
||||
.byte TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE
|
||||
.byte TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE
|
||||
.byte TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE
|
||||
.byte TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE
|
||||
.byte TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE
|
||||
|
||||
.CODE
|
||||
|
||||
; code
|
||||
.export Place_Actors
|
||||
.export Actors_Init
|
||||
|
||||
Actors_Init:
|
||||
|
||||
; positions
|
||||
ldx #(2*NB_ACTORS_MAX - 1)
|
||||
lda #UNDEF
|
||||
loop_actors_pos_init:
|
||||
sta ActorPositions, x
|
||||
dex
|
||||
bne loop_actors_pos_init
|
||||
|
||||
; types
|
||||
ldx #eACTORTYPES::LAST_STATIC
|
||||
loop_actors_types_init:
|
||||
txa
|
||||
sta ActorTypes, X
|
||||
dex
|
||||
bne loop_actors_types_init
|
||||
ldx #eACTORTYPES::LAST_MONSTER+1
|
||||
loop_actors_types_init_2:
|
||||
txa
|
||||
sta ActorTypes, X
|
||||
inx
|
||||
cpx #eACTORTYPES::NB_ACTORS
|
||||
bne loop_actors_types_init_2
|
||||
|
||||
rts
|
||||
|
||||
|
||||
|
||||
.define PTR_ROOM ZERO_2_1 ; 2 bytes
|
||||
.define PTR_TILE ZERO_2_1 ; 2 bytes
|
||||
; the two following defines must be the same as in Build_Level
|
||||
.define ROOM_X ZERO_3
|
||||
.define ROOM_Y ZERO_2_4
|
||||
.define ROOM_W ZERO_2_5
|
||||
.define ROOM_H ZERO_2_6
|
||||
|
||||
; parameters:
|
||||
.define NB_ROOMS ZERO_9_9
|
||||
.define ACTOR_ID ZERO_9_1
|
||||
.define ACTOR_TYPE ZERO_9_2
|
||||
Place_Actors:
|
||||
|
||||
loop_find_location:
|
||||
|
||||
jsr Random8
|
||||
ldx NB_ROOMS
|
||||
jsr Modulus
|
||||
|
||||
; sizeof(room_t) == 4
|
||||
asl
|
||||
asl
|
||||
clc
|
||||
adc #<Rooms
|
||||
sta PTR_ROOM
|
||||
lda #0
|
||||
adc #>Rooms
|
||||
sta PTR_ROOM+1
|
||||
|
||||
ldy #0
|
||||
lda (PTR_ROOM), Y
|
||||
sta ROOM_H
|
||||
iny
|
||||
lda (PTR_ROOM), Y
|
||||
sta ROOM_W
|
||||
iny
|
||||
lda (PTR_ROOM), Y
|
||||
sta ROOM_X
|
||||
iny
|
||||
lda (PTR_ROOM), Y
|
||||
sta ROOM_Y
|
||||
|
||||
; x = room->x + rand() % (room->width - 2) + 1;
|
||||
sec
|
||||
lda ROOM_W
|
||||
sbc #2
|
||||
sta ROOM_W
|
||||
jsr Random8
|
||||
ldx ROOM_W
|
||||
jsr Modulus
|
||||
clc
|
||||
adc ROOM_X
|
||||
adc #1
|
||||
sta ROOM_X
|
||||
|
||||
; y = room->y + rand() % (room->height - 2) + 1;
|
||||
sec
|
||||
lda ROOM_H
|
||||
sbc #2
|
||||
sta ROOM_H
|
||||
jsr Random8
|
||||
ldx ROOM_H
|
||||
jsr Modulus
|
||||
clc
|
||||
adc ROOM_Y
|
||||
adc #1
|
||||
sta ROOM_Y
|
||||
tay
|
||||
|
||||
ldx ROOM_X
|
||||
jsr Compute_Maze_Addr
|
||||
stx PTR_TILE
|
||||
sta PTR_TILE+1
|
||||
ldy #0
|
||||
lda (PTR_TILE), Y
|
||||
cmp #eACTORTYPES::FLOOR_2
|
||||
bne loop_find_location
|
||||
|
||||
; save position
|
||||
ldx ACTOR_ID
|
||||
lda ROOM_X
|
||||
sta ActorPositions, X
|
||||
lda ROOM_Y
|
||||
sta ActorPositions+1, X
|
||||
; save type
|
||||
lda ACTOR_TYPE
|
||||
sta ActorTypes, X
|
||||
|
||||
txa
|
||||
sta (PTR_TILE), Y
|
||||
|
||||
rts
|
46
src/actors/actors.inc
Normal file
46
src/actors/actors.inc
Normal file
|
@ -0,0 +1,46 @@
|
|||
|
||||
|
||||
.define NB_ACTORS_MAX 128
|
||||
.define SIZEOF_ACTORS_T 256+256+128
|
||||
|
||||
.enum eACTORTYPES
|
||||
|
||||
PLAYER = 0 ; PLAYER MUST ALWAYS BE 0
|
||||
; STATIC ACTORS
|
||||
; FLOOR
|
||||
FLOOR_1 = 1
|
||||
FLOOR_2 ; FLOOR BY DEFAULT
|
||||
FLOOR_3
|
||||
FLOOR_4
|
||||
FLOOR_5
|
||||
FLOOR_6
|
||||
LAST_FLOOR = FLOOR_6
|
||||
; WALLS
|
||||
WALL_1
|
||||
WALL_2
|
||||
WALL_3
|
||||
WALL_4
|
||||
LAST_STATIC = WALL_4
|
||||
|
||||
; DYNAMIC ACTORS
|
||||
STAIR_DOWN ; 11
|
||||
FIRST_DYNAMIC = STAIR_DOWN
|
||||
STAIR_UP
|
||||
|
||||
; ITEMS
|
||||
MAP ; 13
|
||||
|
||||
; MONSTERS
|
||||
RAT ; 14
|
||||
FIRST_MONSTER = RAT
|
||||
TARENTULA
|
||||
SERPENT
|
||||
LAST_MONSTER = SERPENT ;16
|
||||
|
||||
NB_ACTORS = 127
|
||||
UNKNOWN = NB_ACTORS
|
||||
|
||||
.endenum
|
||||
|
||||
|
||||
|
198
src/actors/reactions.asm
Normal file
198
src/actors/reactions.asm
Normal file
|
@ -0,0 +1,198 @@
|
|||
; Copyright (C) 2020 Christophe Meneboeuf <christophe@xtof.info>
|
||||
;
|
||||
; This program is free software: you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation, either version 3 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
.include "actors.inc"
|
||||
.include "../world/level.inc"
|
||||
.include "../io/textio.inc"
|
||||
.include "../common.inc"
|
||||
|
||||
.export Reactions_lsb
|
||||
.export Reactions_msb
|
||||
.export ReactionStairUp
|
||||
.export ReactionStairDown
|
||||
.export ReactionMap
|
||||
|
||||
.import ActorPositions
|
||||
.import World_PickedObject
|
||||
|
||||
.DATA
|
||||
|
||||
STR_REACTION_WALL: ASCIIZ "YOU HIT A WALL"
|
||||
STR_REACTION_STAIR_UP: ASCIIZ "YOU GO UPSTAIRS TO TO THE NEXT LEVEL"
|
||||
STR_REACTION_STAIR_DOWN: ASCIIZ "YOU GO DOWNSTAIRS THE PREVIOUS LEVEL"
|
||||
STR_REACTION_MAP: ASCIIZ "YOU FOUND A MAP!"
|
||||
STR_REACTION_RAT: ASCIIZ "YOU ATTACK THE RAT"
|
||||
STR_REACTION_SPIDER: ASCIIZ "YOU ATTACK THE SPIDER"
|
||||
STR_REACTION_SERPENT: ASCIIZ "YOU ATTACK THE SERPENT"
|
||||
|
||||
.align 256
|
||||
|
||||
; functions address seperated in LSB / MSB to use the same X/Y offset
|
||||
; They must be in the very same order as the actor's types
|
||||
Reactions_lsb:
|
||||
; player
|
||||
.byte 0
|
||||
; floors
|
||||
.byte <ReactionFloor, <ReactionFloor, <ReactionFloor, <ReactionFloor, <ReactionFloor, <ReactionFloor
|
||||
; walls
|
||||
.byte <ReactionWall, <ReactionWall, <ReactionWall, <ReactionWall
|
||||
; stairs
|
||||
.byte <ReactionStairDown, <ReactionStairUp
|
||||
; items
|
||||
.byte <ReactionMap
|
||||
; monsters
|
||||
.byte <ReactionRat, <ReactionSpider, <ReactionSerpent
|
||||
; other
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0
|
||||
|
||||
Reactions_msb:
|
||||
; player
|
||||
.byte 0
|
||||
; floors
|
||||
.byte >ReactionFloor, >ReactionFloor, >ReactionFloor, >ReactionFloor, >ReactionFloor, >ReactionFloor
|
||||
; walls
|
||||
.byte >ReactionWall, >ReactionWall, >ReactionWall, >ReactionWall
|
||||
; stairs
|
||||
.byte >ReactionStairDown, >ReactionStairUp
|
||||
; items
|
||||
.byte >ReactionMap
|
||||
; monsters
|
||||
.byte >ReactionRat, >ReactionSpider, >ReactionSerpent
|
||||
; others
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.byte 0, 0, 0, 0, 0, 0, 0
|
||||
|
||||
|
||||
.CODE
|
||||
|
||||
|
||||
ReactionFloor:
|
||||
lda #TRUE
|
||||
rts
|
||||
|
||||
ReactionWall:
|
||||
PRINT STR_REACTION_WALL
|
||||
lda #FALSE
|
||||
rts
|
||||
|
||||
ReactionStairUp:
|
||||
PRINT STR_REACTION_STAIR_UP
|
||||
lda CurrentLevel
|
||||
sta NextLevel
|
||||
inc NextLevel
|
||||
lda #TRUE
|
||||
sta ExitLevel
|
||||
lda #FALSE
|
||||
rts
|
||||
|
||||
ReactionStairDown:
|
||||
PRINT STR_REACTION_STAIR_DOWN
|
||||
lda CurrentLevel
|
||||
sta NextLevel
|
||||
dec NextLevel
|
||||
lda #TRUE
|
||||
sta ExitLevel
|
||||
lda #FALSE
|
||||
rts
|
||||
|
||||
; @param actor_id in X
|
||||
ReactionMap:
|
||||
|
||||
; index of &ActorPositions[actor_id]
|
||||
txa
|
||||
asl
|
||||
tax
|
||||
lda #UNDEF
|
||||
sta ActorPositions, X
|
||||
sta ActorPositions+1, X
|
||||
|
||||
PRINT STR_REACTION_MAP
|
||||
|
||||
lda #TRUE
|
||||
sta World_PickedObject
|
||||
|
||||
rts
|
||||
|
||||
ReactionRat:
|
||||
PRINT STR_REACTION_RAT
|
||||
lda #FALSE
|
||||
rts
|
||||
|
||||
ReactionSpider:
|
||||
PRINT STR_REACTION_SPIDER
|
||||
lda #FALSE
|
||||
rts
|
||||
|
||||
ReactionSerpent:
|
||||
PRINT STR_REACTION_SERPENT
|
||||
lda #FALSE
|
||||
rts
|
32
src/builder/actors.inc
Normal file
32
src/builder/actors.inc
Normal file
|
@ -0,0 +1,32 @@
|
|||
.define NB_ACTORS_MAX 128
|
||||
|
||||
|
||||
|
||||
.enum ACTORS
|
||||
|
||||
PLAYER = 0
|
||||
; FLOOR
|
||||
FLOOR_1 = 1
|
||||
FLOOR_2 ; FLOOR BY DEFAULT
|
||||
FLOOR_3
|
||||
FLOOR_4
|
||||
FLOOR_5
|
||||
FLOOR_6
|
||||
STAIR_DOWN
|
||||
; OBJECT
|
||||
MAP
|
||||
; WALLS
|
||||
STAIR_UP
|
||||
WALKABLE = STAIR_UP ; Player won't be allowed to go on anything > WALKABLE
|
||||
|
||||
NOT_TRANSPARENT = STAIR_UP
|
||||
NOT_WALKABLE
|
||||
|
||||
WALL_1 = NOT_WALKABLE
|
||||
WALL_2
|
||||
|
||||
UNKNOWN
|
||||
|
||||
NB_ACTORS
|
||||
|
||||
.endenum
|
339
src/builder/builder.asm
Normal file
339
src/builder/builder.asm
Normal file
|
@ -0,0 +1,339 @@
|
|||
|
||||
; Copyright (C) 2019 Christophe Meneboeuf <christophe@xtof.info>
|
||||
;
|
||||
; This program is free software: you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation, either version 3 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
; All the dungeon builder is based on this article: http://journal.stuffwithstuff.com/2014/12/21/rooms-and-mazes/
|
||||
|
||||
.include "rooms.inc"
|
||||
.include "maze.inc"
|
||||
.include "unite.inc"
|
||||
.include "../common.inc"
|
||||
.include "../actors/actors.inc"
|
||||
.include "../io/textio.inc"
|
||||
.include "../math.inc"
|
||||
.include "../monitor.inc"
|
||||
.include "../memory.inc"
|
||||
.include "../world/world.inc"
|
||||
.include "../world/level.inc"
|
||||
|
||||
; code
|
||||
.import Random8
|
||||
.import Grow_Maze ; to patch
|
||||
.import Compute_Maze_Addr
|
||||
.import Place_Actors
|
||||
; data
|
||||
.import World
|
||||
.import Tile_player_standing_actor
|
||||
|
||||
.export Init_Dimensions_Maze
|
||||
.export Build_Level
|
||||
|
||||
.export Rooms
|
||||
.export WIDTH_MAZE
|
||||
.export HEIGHT_MAZE
|
||||
|
||||
.BSS
|
||||
|
||||
; Describes a room to be built
|
||||
; typedef struct {
|
||||
; uint8_t height;
|
||||
; uint8_t width;
|
||||
; uint8_t x;
|
||||
; uint8_t y;
|
||||
; } room_t;
|
||||
.define SIZEOF_ROOM_T 4
|
||||
.align 256
|
||||
Rooms: .res SIZEOF_ROOM_T*MAX_NB_ROOMS ; MAX 1 page of data!
|
||||
|
||||
WIDTH_MAZE: .res 1
|
||||
HEIGHT_MAZE: .res 1
|
||||
|
||||
.DATA
|
||||
STR_SIZE_MAZE_1: ASCIIZ "PLEASE ENTER THE SIZE OF THE LEVEL."
|
||||
STR_SIZE_MAZE_2: ASCIIZ "A:TINY B:SMALL C:NORMAL D:BIG E:HUGE"
|
||||
STR_SIZE_MAZE_3: ASCIIZ "PLEASE ENTER A VALID CHOICE."
|
||||
|
||||
STR_ROOMS: ASCIIZ "CARVING ROOMS..."
|
||||
STR_MAZE: ASCIIZ "GROWING THE MAZE..."
|
||||
STR_DOORS: ASCIIZ "OPENING DOORS..."
|
||||
STR_DEADENDS: ASCIIZ "FILLING DEAD ENDS..."
|
||||
STR_UNITE: ASCIIZ "UNITING THE ROOMS..."
|
||||
STR_ACTORS: ASCIIZ "PLACING ACTORS..."
|
||||
|
||||
|
||||
|
||||
.CODE
|
||||
|
||||
|
||||
; @brief Fills border walls
|
||||
; @param type of the "wall" in A
|
||||
; destroys ZERO_2_1, ZERO_2_2
|
||||
.define ADDR_WORLD ZERO_2_1
|
||||
.macro WORLD_NEXT_LINE
|
||||
clc
|
||||
lda ADDR_WORLD
|
||||
adc #WIDTH_WORLD
|
||||
sta ADDR_WORLD
|
||||
lda ADDR_WORLD+1
|
||||
adc #0
|
||||
sta ADDR_WORLD+1
|
||||
.endmacro
|
||||
; DO NOT MESS WITH THIS FUNCTION: IT IS PATCHED!!
|
||||
.define PATCH_WIDTH_MAZE_1 0
|
||||
.define PATCH_HEIGHT_MAZE_2 0
|
||||
_build_fences:
|
||||
|
||||
ldx #<World
|
||||
stx ADDR_WORLD
|
||||
ldx #>World
|
||||
stx ADDR_WORLD+1
|
||||
ldy #PATCH_WIDTH_MAZE_1
|
||||
|
||||
loop_wall_top:
|
||||
sta (ADDR_WORLD), Y
|
||||
dey
|
||||
bne loop_wall_top
|
||||
sta (ADDR_WORLD), Y
|
||||
|
||||
ldx #PATCH_HEIGHT_MAZE_2
|
||||
loop_wall_left_right:
|
||||
pha
|
||||
WORLD_NEXT_LINE
|
||||
pla
|
||||
ldy #PATCH_WIDTH_MAZE_1
|
||||
sta (ADDR_WORLD), Y
|
||||
ldy #0
|
||||
sta (ADDR_WORLD), Y
|
||||
dex
|
||||
bne loop_wall_left_right
|
||||
|
||||
pha
|
||||
WORLD_NEXT_LINE
|
||||
pla
|
||||
ldy #PATCH_WIDTH_MAZE_1
|
||||
loop_wall_bottom:
|
||||
sta (ADDR_WORLD), Y
|
||||
dey
|
||||
bne loop_wall_bottom
|
||||
sta (ADDR_WORLD), Y
|
||||
|
||||
rts
|
||||
.undefine ADDR_WORLD
|
||||
|
||||
; @brief Sets the Maze's dimentions
|
||||
; @param width in X
|
||||
; @param height in Y
|
||||
Init_Dimensions_Maze:
|
||||
|
||||
stx WIDTH_MAZE
|
||||
; patch WIDTH_MAZE usage NO MORE PATCH: comment to be removed
|
||||
dex
|
||||
stx _build_fences + $9
|
||||
stx _build_fences + $23
|
||||
stx _build_fences + $3D
|
||||
; patch HEIGHT_MAZE usage NO MORE PATCH: comment to be removed
|
||||
sty HEIGHT_MAZE
|
||||
dey
|
||||
dey
|
||||
sty _build_fences + $12
|
||||
|
||||
rts
|
||||
|
||||
; @brief Builds a whole level
|
||||
; @param Uses NextLevel to get the conf
|
||||
; @return player position in X and Y
|
||||
.define DST_WORLD World
|
||||
.define ADDR_TO_PATCH init_world_line + 3
|
||||
.define NB_ROOMS ZERO_9_9 ; use same location as Place_Actors
|
||||
Build_Level:
|
||||
|
||||
lda #UNDEF
|
||||
sta Tile_player_standing_actor
|
||||
|
||||
; Filling World with eACTORTYPES::WALL_1
|
||||
ldy #HEIGHT_WORLD
|
||||
init_world:
|
||||
ldx #0
|
||||
init_world_line:
|
||||
lda #eACTORTYPES::WALL_1
|
||||
sta DST_WORLD, x
|
||||
inx
|
||||
cpx #WIDTH_WORLD
|
||||
bne init_world_line
|
||||
; patching DST_WORLD
|
||||
lda ADDR_TO_PATCH
|
||||
clc
|
||||
adc #WIDTH_WORLD
|
||||
sta ADDR_TO_PATCH
|
||||
lda ADDR_TO_PATCH + 1
|
||||
adc #0
|
||||
sta ADDR_TO_PATCH + 1
|
||||
dey
|
||||
bne init_world
|
||||
; patching back for a future execution
|
||||
lda #<DST_WORLD
|
||||
sta ADDR_TO_PATCH
|
||||
lda #>DST_WORLD
|
||||
sta ADDR_TO_PATCH+1
|
||||
|
||||
PRINT STR_ROOMS
|
||||
|
||||
lda #MAX_NB_ROOMS+1
|
||||
jsr Carve_Rooms
|
||||
sta NB_ROOMS
|
||||
|
||||
lda #eACTORTYPES::FLOOR_1
|
||||
jsr _build_fences
|
||||
|
||||
PRINT STR_MAZE
|
||||
jsr Grow_Maze
|
||||
|
||||
lda #eACTORTYPES::WALL_1
|
||||
jsr _build_fences
|
||||
|
||||
PRINT STR_DOORS
|
||||
.define PERCENT_7 #17
|
||||
ldx PERCENT_7
|
||||
lda NB_ROOMS
|
||||
jsr Connect_Rooms
|
||||
|
||||
PRINT STR_DEADENDS
|
||||
jsr Remove_Dead_Ends
|
||||
|
||||
PRINT STR_UNITE
|
||||
jsr Unite_Rooms
|
||||
|
||||
; the two following defines must be the same as in Place_Actors
|
||||
.define POS_X ZERO_3 ; ROOM_X in Place_Actors
|
||||
.define POS_Y ZERO_2_4 ; ROOM_Y in Place_Actors
|
||||
.define POS_STARDOWN_X ZERO_5_1
|
||||
.define POS_STARDOWN_Y ZERO_5_2
|
||||
.define ACTOR_NB ZERO_4_2
|
||||
.define ACTOR_ID ZERO_9_1 ; use same location as Place_Actors
|
||||
.define ACTOR_TYPE ZERO_9_2 ; use same location as Place_Actors
|
||||
.define CURR_ACTOR_OFFSET ZERO_4_3
|
||||
.define ADDR_LEVEL_CONF ZERO_5_3 ; 2 bytes
|
||||
.define ADDR_ACTOR ZERO_4_3 ; 2 bytes
|
||||
|
||||
; place actors
|
||||
PRINT STR_ACTORS
|
||||
; offset to level conf
|
||||
|
||||
lda NextLevel
|
||||
jsr level_get_config_offset
|
||||
pha
|
||||
clc
|
||||
txa
|
||||
adc #<LevelConfigs
|
||||
sta ADDR_LEVEL_CONF
|
||||
pla
|
||||
adc #>LevelConfigs
|
||||
sta ADDR_LEVEL_CONF+1
|
||||
lda #eACTORTYPES::LAST_STATIC + 1 ; 1st dynamic actor id
|
||||
sta ACTOR_ID
|
||||
sta ACTOR_TYPE
|
||||
tay
|
||||
iny
|
||||
iny ; offset to actors[ACTOR_ID] in level conf
|
||||
loop_actors: ; loop over actors from conf
|
||||
sty CURR_ACTOR_OFFSET
|
||||
lda (ADDR_LEVEL_CONF), Y
|
||||
sta ACTOR_NB
|
||||
loop_actor_id:
|
||||
beq end_loop_actor_id
|
||||
|
||||
jsr Place_Actors
|
||||
|
||||
; save stair down position
|
||||
lda ACTOR_TYPE
|
||||
cmp #eACTORTYPES::STAIR_DOWN
|
||||
bne not_stair_down
|
||||
lda POS_X
|
||||
sta POS_STARDOWN_X
|
||||
lda POS_Y
|
||||
sta POS_STARDOWN_Y
|
||||
not_stair_down:
|
||||
|
||||
inc ACTOR_ID
|
||||
dec ACTOR_NB ; next
|
||||
lda ACTOR_NB
|
||||
jmp loop_actor_id
|
||||
end_loop_actor_id:
|
||||
|
||||
ldy CURR_ACTOR_OFFSET
|
||||
iny
|
||||
inc ACTOR_TYPE
|
||||
lda ACTOR_TYPE
|
||||
cmp #(NB_ACTORS_MAX-1)
|
||||
bne loop_actors
|
||||
|
||||
; Set the 1st position of the player in the level
|
||||
; offset to level state
|
||||
lda NextLevel
|
||||
cmp #0
|
||||
bne not_first_level
|
||||
; Special case: first level
|
||||
; TODO avoid non empty floor...
|
||||
ldx Rooms+2 ; Rooms[0].x
|
||||
ldy Rooms+3 ; Rooms[0].y
|
||||
rts
|
||||
not_first_level:
|
||||
ldx POS_STARDOWN_X
|
||||
ldy POS_STARDOWN_Y
|
||||
jsr Compute_Maze_Addr
|
||||
; addr offseted by - witdh_maze to access all tiles with offset
|
||||
sta ADDR_ACTOR+1
|
||||
txa
|
||||
sec
|
||||
sbc #WIDTH_WORLD
|
||||
sta ADDR_ACTOR
|
||||
lda ADDR_ACTOR+1
|
||||
sbc #0
|
||||
sta ADDR_ACTOR+1
|
||||
ldx POS_STARDOWN_X
|
||||
; NOTE: There is at least one solution, the tile is not surrounded!
|
||||
; if (World[pos_stair_down.y][pos_stair_down.x - 1] == FLOOR_2)
|
||||
ldy #(WIDTH_WORLD - 1)
|
||||
lda (ADDR_ACTOR), Y
|
||||
cmp #eACTORTYPES::FLOOR_2
|
||||
bne not_x_minus
|
||||
ldy POS_STARDOWN_Y
|
||||
dex
|
||||
rts
|
||||
not_x_minus:
|
||||
; if (World[pos_stair_down.y - 1][pos_stair_down.x] == FLOOR_2)
|
||||
ldy #0
|
||||
lda (ADDR_ACTOR), Y
|
||||
cmp #eACTORTYPES::FLOOR_2
|
||||
bne not_y_minus
|
||||
ldy POS_STARDOWN_Y
|
||||
dey
|
||||
rts
|
||||
not_y_minus:
|
||||
; if (World[pos_stair_down.y + 1][pos_stair_down.x] == FLOOR_2)
|
||||
ldy #(WIDTH_WORLD * 2)
|
||||
lda (ADDR_ACTOR), Y
|
||||
cmp #eACTORTYPES::FLOOR_2
|
||||
bne not_y_plus
|
||||
ldy POS_STARDOWN_Y
|
||||
iny
|
||||
rts
|
||||
not_y_plus:
|
||||
ldy POS_STARDOWN_Y
|
||||
inx
|
||||
|
||||
rts
|
||||
|
18
src/builder/builder.inc
Normal file
18
src/builder/builder.inc
Normal file
|
@ -0,0 +1,18 @@
|
|||
; Copyright (C) 2019 Christophe Meneboeuf <christophe@xtof.info>
|
||||
;
|
||||
; This program is free software: you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation, either version 3 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
.import Init_Dimensions_Maze
|
||||
.import Build_Level
|
||||
.import Rooms
|
534
src/builder/maze.asm
Normal file
534
src/builder/maze.asm
Normal file
|
@ -0,0 +1,534 @@
|
|||
; Copyright (C) 2019 Christophe Meneboeuf <christophe@xtof.info>
|
||||
;
|
||||
; This program is free software: you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation, either version 3 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be usefuELEFT,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
.include "../memory.inc"
|
||||
.include "../random.inc"
|
||||
.include "../math.inc"
|
||||
.include "../common.inc"
|
||||
.include "../world/world.inc"
|
||||
.include "../actors/actors.inc"
|
||||
|
||||
|
||||
.export Grow_Maze
|
||||
.export Remove_Dead_Ends
|
||||
|
||||
.import Compute_Maze_Addr
|
||||
.import World
|
||||
.import WIDTH_MAZE
|
||||
.import HEIGHT_MAZE
|
||||
|
||||
; using HGR2 space as the stack
|
||||
; Stack contains pointers to tiles (2 byte long)
|
||||
.define STACK_ADDR $3FFE ; Will be 2 byte incremented before 1st push
|
||||
|
||||
|
||||
.define Y_TILE ZERO_2_4
|
||||
.define X_TILE ZERO_2_5
|
||||
.define PTR_STACK ZERO_4_1 ; 2 bytes
|
||||
.define PTR_NEW_TILE ZERO_4_3 ; 2 bytes
|
||||
|
||||
|
||||
; increments the stack pointer then pushes address A:X (little endian)
|
||||
; *ptr_stack = x
|
||||
; *(ptr_stack+1) = a
|
||||
; ptr_stack += 2
|
||||
.macro PUSHAX
|
||||
pha
|
||||
; increment stack pointer
|
||||
clc
|
||||
lda PTR_STACK
|
||||
adc #2
|
||||
sta PTR_STACK
|
||||
lda PTR_STACK+1
|
||||
adc #0
|
||||
sta PTR_STACK+1
|
||||
; push A:X to the stack
|
||||
pla
|
||||
ldy #1
|
||||
sta (PTR_STACK),Y
|
||||
dey
|
||||
txa
|
||||
sta (PTR_STACK),Y
|
||||
.endmacro
|
||||
|
||||
; ptr_newtile is offseted by -WIDTH_WORLD so we can access all its neighbors
|
||||
; with positive offsets using Y indirect addressing
|
||||
.macro PTR_UP_TILE
|
||||
sec
|
||||
ldy #0
|
||||
lda (PTR_STACK),Y
|
||||
sbc #(2*WIDTH_WORLD)
|
||||
sta PTR_NEW_TILE
|
||||
iny
|
||||
lda (PTR_STACK),Y
|
||||
sbc #0
|
||||
sta PTR_NEW_TILE+1
|
||||
.endmacro
|
||||
.macro PTR_LEFT_TILE
|
||||
sec
|
||||
ldy #0
|
||||
lda (PTR_STACK),Y
|
||||
sbc #(WIDTH_WORLD+1)
|
||||
sta PTR_NEW_TILE
|
||||
iny
|
||||
lda (PTR_STACK),Y
|
||||
sbc #0
|
||||
sta PTR_NEW_TILE+1
|
||||
.endmacro
|
||||
.macro PTR_RIGHT_TILE
|
||||
sec
|
||||
ldy #0
|
||||
lda (PTR_STACK),Y
|
||||
sbc #(WIDTH_WORLD-1)
|
||||
sta PTR_NEW_TILE
|
||||
iny
|
||||
lda (PTR_STACK),Y
|
||||
sbc #0
|
||||
sta PTR_NEW_TILE+1
|
||||
.endmacro
|
||||
.macro PTR_DOWN_TILE
|
||||
ldy #0
|
||||
lda (PTR_STACK),Y
|
||||
sta PTR_NEW_TILE
|
||||
iny
|
||||
lda (PTR_STACK),Y
|
||||
sta PTR_NEW_TILE+1
|
||||
.endmacro
|
||||
.macro PTR_CURR_TILE
|
||||
sec
|
||||
ldy #0
|
||||
lda (PTR_STACK),Y
|
||||
sbc #(WIDTH_WORLD)
|
||||
sta PTR_NEW_TILE
|
||||
iny
|
||||
lda (PTR_STACK),Y
|
||||
sbc #0
|
||||
sta PTR_NEW_TILE+1
|
||||
.endmacro
|
||||
|
||||
; test if the tile offseted from PTR_NEW_TILE is walkable
|
||||
.macro ISWALKABLE offset
|
||||
ldy offset
|
||||
lda (PTR_NEW_TILE),Y
|
||||
cmp #eACTORTYPES::LAST_FLOOR+1
|
||||
bcc cannot_carve
|
||||
.endmacro
|
||||
|
||||
|
||||
|
||||
.define OFFSET_NIL #WIDTH_WORLD
|
||||
.define OFFSET_UP #0
|
||||
.define OFFSET_RIGHT #(WIDTH_WORLD+1)
|
||||
.define OFFSET_DOWN #(2*WIDTH_WORLD)
|
||||
.define OFFSET_LEFT #(WIDTH_WORLD-1)
|
||||
|
||||
|
||||
.macro IS_TILE_WALLED
|
||||
PTR_CURR_TILE
|
||||
|
||||
ldy OFFSET_NIL
|
||||
lda (PTR_NEW_TILE),Y
|
||||
cmp #eACTORTYPES::LAST_FLOOR
|
||||
bcc end_loop_stack
|
||||
|
||||
ldy OFFSET_UP
|
||||
lda (PTR_NEW_TILE),Y
|
||||
cmp #eACTORTYPES::LAST_FLOOR
|
||||
bcc end_loop_stack
|
||||
|
||||
ldy OFFSET_RIGHT
|
||||
lda (PTR_NEW_TILE),Y
|
||||
cmp #eACTORTYPES::LAST_FLOOR
|
||||
bcc end_loop_stack
|
||||
|
||||
ldy OFFSET_DOWN
|
||||
lda (PTR_NEW_TILE),Y
|
||||
cmp #eACTORTYPES::LAST_FLOOR
|
||||
bcc end_loop_stack
|
||||
|
||||
ldy OFFSET_LEFT
|
||||
lda (PTR_NEW_TILE),Y
|
||||
cmp #eACTORTYPES::LAST_FLOOR
|
||||
bcc end_loop_stack
|
||||
|
||||
.endmacro
|
||||
|
||||
|
||||
; @brief Fills the empty space with a perfect maze
|
||||
.define PATCH_WIDTH_MAZE_4 0
|
||||
.define PATCH_HEIGHT_MAZE_4 0
|
||||
Grow_Maze:
|
||||
|
||||
; Groth start location
|
||||
ldx #2
|
||||
stx X_TILE
|
||||
stx Y_TILE
|
||||
|
||||
loop_grow_maze:
|
||||
|
||||
; init the stack
|
||||
lda #<STACK_ADDR
|
||||
sta PTR_STACK
|
||||
lda #>STACK_ADDR
|
||||
sta PTR_STACK+1
|
||||
|
||||
; Test if the tile is suitable
|
||||
ldy Y_TILE
|
||||
ldx X_TILE
|
||||
jsr Compute_Maze_Addr ; result addr in A:X
|
||||
|
||||
; test if the tile is walled
|
||||
PUSHAX
|
||||
IS_TILE_WALLED
|
||||
|
||||
; carve
|
||||
ldy #WIDTH_WORLD
|
||||
lda #eACTORTYPES::FLOOR_1
|
||||
sta (PTR_NEW_TILE),Y
|
||||
|
||||
|
||||
.define IDX ZERO_2_6
|
||||
; while the stack is not empty: carve
|
||||
loop_stack:
|
||||
|
||||
jsr _random_directions
|
||||
|
||||
tax
|
||||
stx IDX
|
||||
loop_find_dir: ; find a direction suitable to carvingm
|
||||
jsr _can_carve
|
||||
cmp #1 ; cannot carve -> test other directions
|
||||
beq carve_the_tile
|
||||
lda IDX
|
||||
and #3 ; 4th direction?
|
||||
cmp #3
|
||||
beq test_stack
|
||||
inc IDX
|
||||
ldx IDX
|
||||
jmp loop_find_dir
|
||||
test_stack:
|
||||
lda PTR_STACK+1
|
||||
cmp #>(STACK_ADDR+2)
|
||||
bne unstack
|
||||
lda PTR_STACK
|
||||
cmp #<(STACK_ADDR+2)
|
||||
beq end_loop_stack ; stack is empty -> break
|
||||
unstack:
|
||||
sec
|
||||
lda PTR_STACK
|
||||
sbc #2
|
||||
sta PTR_STACK
|
||||
lda PTR_STACK+1
|
||||
sbc #0
|
||||
sta PTR_STACK+1
|
||||
jmp loop_stack
|
||||
carve_the_tile:
|
||||
; carve the tile
|
||||
ldy #0
|
||||
lda #eACTORTYPES::FLOOR_1
|
||||
sta (PTR_NEW_TILE),Y
|
||||
jmp loop_stack
|
||||
end_loop_stack:
|
||||
|
||||
inc X_TILE
|
||||
ldx WIDTH_MAZE
|
||||
dex
|
||||
dex
|
||||
cpx X_TILE
|
||||
beq incr_y_tile
|
||||
jmp loop_grow_maze
|
||||
incr_y_tile:
|
||||
ldx #2
|
||||
stx X_TILE
|
||||
inc Y_TILE
|
||||
ldy HEIGHT_MAZE
|
||||
dey
|
||||
cpy Y_TILE
|
||||
beq end_loop_grow_maze
|
||||
jmp loop_grow_maze
|
||||
|
||||
end_loop_grow_maze:
|
||||
rts
|
||||
|
||||
|
||||
|
||||
.enum
|
||||
EUP = 0
|
||||
ERIGHT
|
||||
EDOWN
|
||||
ELEFT
|
||||
.endenum
|
||||
|
||||
; 24 direction quartets
|
||||
RandomDirection:
|
||||
.byte EUP,ERIGHT,EDOWN,ELEFT,EUP,ERIGHT,ELEFT,EDOWN,EUP,EDOWN,ERIGHT,ELEFT,EUP,EDOWN,ELEFT,ERIGHT,EUP,ELEFT,ERIGHT,EDOWN,EUP,ELEFT,EDOWN,ERIGHT
|
||||
.byte ERIGHT,EUP,EDOWN,ELEFT,ERIGHT,EUP,ELEFT,EDOWN,ERIGHT,EDOWN,EUP,ELEFT,ERIGHT,EDOWN,ELEFT,EUP,ERIGHT,ELEFT,EUP,EDOWN,ERIGHT,ELEFT,EDOWN,EUP
|
||||
.byte EDOWN,ERIGHT,EUP,ELEFT,EDOWN,ERIGHT,ELEFT,EUP,EDOWN,ELEFT,EUP,ERIGHT,EDOWN,ELEFT,ERIGHT,EUP,EDOWN,EUP,ELEFT,ERIGHT,EDOWN,EUP,ERIGHT,ELEFT
|
||||
.byte ELEFT,ERIGHT,EDOWN,EUP,ELEFT,ERIGHT,EDOWN,EUP,ELEFT,EDOWN,ERIGHT,EUP,ELEFT,EDOWN,EUP,ERIGHT,ELEFT,EUP,ERIGHT,EDOWN,ELEFT,EUP,EDOWN,ERIGHT
|
||||
|
||||
; Uses a precomputed table to quickly return an offset to one of the direction quartets
|
||||
_random_directions:
|
||||
|
||||
jsr Random8
|
||||
and #31
|
||||
ldx #24
|
||||
jsr Modulus
|
||||
asl
|
||||
asl ; offset to a direction quartet
|
||||
rts
|
||||
|
||||
; @brief Returns A=1 if the tile can be carved, A=0 otherwise.
|
||||
; some difficulties for the branches to be in range to end_can_carve.
|
||||
; thus the jsr and jmp and the breakdown of the routine
|
||||
_can_carve:
|
||||
|
||||
lda RandomDirection,X
|
||||
can_carve_up:
|
||||
cmp #EUP
|
||||
bne can_carve_right
|
||||
jmp _can_carve_up
|
||||
|
||||
can_carve_right:
|
||||
cmp #ERIGHT
|
||||
bne can_carve_down
|
||||
jmp _can_carve_right
|
||||
|
||||
can_carve_down:
|
||||
cmp #EDOWN
|
||||
bne can_carve_left
|
||||
PTR_DOWN_TILE ; ptr_newtile = down - width_world
|
||||
ISWALKABLE OFFSET_NIL ; the new tile
|
||||
ISWALKABLE OFFSET_RIGHT ; new tile's right neighbor
|
||||
ISWALKABLE OFFSET_DOWN ; new tile's bottom neighbor
|
||||
ISWALKABLE OFFSET_LEFT ; new tile's left neighbor
|
||||
jmp _save_ptr_newtile
|
||||
|
||||
can_carve_left:
|
||||
cmp #ELEFT
|
||||
bne end_can_carve
|
||||
PTR_LEFT_TILE ; ptr_newtile = left - width_world
|
||||
ISWALKABLE OFFSET_NIL ; the new tile
|
||||
ISWALKABLE OFFSET_UP ; new tile's upper neighbor
|
||||
ISWALKABLE OFFSET_DOWN ; new tile's bottom neighbor
|
||||
ISWALKABLE OFFSET_LEFT ; new tile's left neighbor
|
||||
jmp _save_ptr_newtile
|
||||
|
||||
cannot_carve:
|
||||
lda #0
|
||||
end_can_carve:
|
||||
rts
|
||||
|
||||
_can_carve_up:
|
||||
PTR_UP_TILE ; ptr_newtile = up - width_world
|
||||
ISWALKABLE OFFSET_NIL ; the new tile
|
||||
ISWALKABLE OFFSET_UP ; new tile's upper neighbor
|
||||
ISWALKABLE OFFSET_RIGHT ; new tile's right neighbor
|
||||
ISWALKABLE OFFSET_LEFT ; new tile's left neighbor
|
||||
jmp _save_ptr_newtile
|
||||
|
||||
_can_carve_right:
|
||||
PTR_RIGHT_TILE ; ptr_newtile = rigth - width_world
|
||||
ISWALKABLE OFFSET_NIL ; the new tile
|
||||
ISWALKABLE OFFSET_RIGHT ; new tile's right neighbor
|
||||
ISWALKABLE OFFSET_DOWN ; new tile's bottom neighbor
|
||||
ISWALKABLE OFFSET_UP ; new tile's upper neighbor
|
||||
; jmp _save_ptr_newtile
|
||||
|
||||
|
||||
; save new tile on the stack
|
||||
_save_ptr_newtile:
|
||||
clc
|
||||
lda PTR_NEW_TILE
|
||||
adc #WIDTH_WORLD
|
||||
sta PTR_NEW_TILE
|
||||
tax
|
||||
lda PTR_NEW_TILE+1
|
||||
adc #0
|
||||
sta PTR_NEW_TILE+1
|
||||
PUSHAX
|
||||
|
||||
;CREUSER???
|
||||
|
||||
lda #1
|
||||
jmp end_can_carve
|
||||
|
||||
.undefine Y_TILE
|
||||
.undefine X_TILE
|
||||
.undefine PTR_STACK
|
||||
.undefine PTR_NEW_TILE
|
||||
|
||||
|
||||
.define PTR_TILE ZERO_2_1 ; 2 bytes
|
||||
.define PTR_NEXT_TILE ZERO_2_3 ; 2 bytes
|
||||
.define NB_WALLS ZERO_2_5
|
||||
.define ADDR_END ZERO_4_1 ; 2 bytes
|
||||
.define HEIGHTxWIDTH WIDTH_WORLD*HEIGHT_WORLD
|
||||
; @brief Removes all the dead ends
|
||||
Remove_Dead_Ends:
|
||||
|
||||
; Compute addr_end as the preprocessor cannot handle 16bit multiplications (???)
|
||||
lda #WIDTH_WORLD
|
||||
sta FAC1
|
||||
lda #HEIGHT_WORLD
|
||||
sta FAC2
|
||||
jsr mul8
|
||||
sta ADDR_END+1
|
||||
stx ADDR_END
|
||||
lda #<World
|
||||
clc
|
||||
adc ADDR_END
|
||||
sta ADDR_END
|
||||
lda #>World
|
||||
adc ADDR_END+1
|
||||
sta ADDR_END+1
|
||||
|
||||
; starting tile: offsetted by - width_world
|
||||
lda #<(World + 1) ; &World[1][1] - width_world
|
||||
sta PTR_TILE
|
||||
lda #>(World + 1)
|
||||
sta PTR_TILE+1
|
||||
|
||||
loop_tiles:
|
||||
jsr _is_tile_dead_end
|
||||
lda NB_WALLS
|
||||
cmp #3
|
||||
bcc next_tile
|
||||
|
||||
jsr _follow_dead_end
|
||||
|
||||
next_tile:
|
||||
clc
|
||||
lda PTR_TILE
|
||||
adc #1
|
||||
sta PTR_TILE
|
||||
lda PTR_TILE+1
|
||||
adc #0
|
||||
sta PTR_TILE+1
|
||||
|
||||
; end?
|
||||
lda PTR_TILE+1
|
||||
cmp ADDR_END+1
|
||||
bne loop_tiles
|
||||
lda PTR_TILE
|
||||
cmp ADDR_END
|
||||
bne loop_tiles
|
||||
end_loop_tiles:
|
||||
|
||||
rts
|
||||
.undefine ADDR_END
|
||||
|
||||
_follow_dead_end:
|
||||
|
||||
; saving ptr_tile
|
||||
lda PTR_TILE
|
||||
pha
|
||||
lda PTR_TILE+1
|
||||
pha
|
||||
|
||||
loop_follow:
|
||||
ldy #WIDTH_WORLD
|
||||
lda #eACTORTYPES::WALL_1
|
||||
sta (PTR_TILE), Y
|
||||
|
||||
lda PTR_NEXT_TILE
|
||||
sta PTR_TILE
|
||||
lda PTR_NEXT_TILE+1
|
||||
sta PTR_TILE+1
|
||||
|
||||
jsr _is_tile_dead_end
|
||||
lda NB_WALLS
|
||||
cmp #3
|
||||
bcs loop_follow
|
||||
|
||||
end_loop_follow:
|
||||
|
||||
; restoring ptr_tile
|
||||
pla
|
||||
sta PTR_TILE+1
|
||||
pla
|
||||
sta PTR_TILE
|
||||
|
||||
rts
|
||||
|
||||
|
||||
.define ADD_FACTOR ZERO_4_3
|
||||
; REM: PTR_TILE is already offsetted by -WIDTH_WORLD
|
||||
; for easy access to adjacent tiles by indirect indexing
|
||||
; Returns : NB_WALLS >= 3 if it is a dead end
|
||||
_is_tile_dead_end:
|
||||
|
||||
lda #0
|
||||
sta NB_WALLS
|
||||
ldy #WIDTH_WORLD
|
||||
sty ADD_FACTOR
|
||||
|
||||
; Returns if the tile is a wall
|
||||
lda #eACTORTYPES::LAST_FLOOR
|
||||
cmp (PTR_TILE), Y
|
||||
bcc end_tst_up_tile
|
||||
|
||||
tst_up_tile:
|
||||
ldy #0
|
||||
cmp (PTR_TILE), Y
|
||||
bcc up_non_walkable
|
||||
sty ADD_FACTOR
|
||||
bcs tst_right_tile
|
||||
up_non_walkable:
|
||||
inc NB_WALLS
|
||||
tst_right_tile:
|
||||
ldy #(WIDTH_WORLD + 1)
|
||||
cmp (PTR_TILE), Y
|
||||
bcc right_non_walkable
|
||||
sty ADD_FACTOR
|
||||
bcs tst_down_tile
|
||||
right_non_walkable:
|
||||
inc NB_WALLS
|
||||
tst_down_tile:
|
||||
ldy #(2*WIDTH_WORLD)
|
||||
cmp (PTR_TILE), Y
|
||||
bcc down_non_walkable
|
||||
sty ADD_FACTOR
|
||||
bcs tst_left_tile
|
||||
down_non_walkable:
|
||||
inc NB_WALLS
|
||||
tst_left_tile:
|
||||
ldy #(WIDTH_WORLD - 1)
|
||||
cmp (PTR_TILE), Y
|
||||
bcc left_non_walkable
|
||||
sty ADD_FACTOR
|
||||
bcs end_tests
|
||||
left_non_walkable:
|
||||
inc NB_WALLS
|
||||
|
||||
end_tests:
|
||||
; computing ptr_next_tile
|
||||
clc
|
||||
lda PTR_TILE
|
||||
adc ADD_FACTOR
|
||||
sta PTR_NEXT_TILE
|
||||
lda PTR_TILE+1
|
||||
adc #0
|
||||
sta PTR_NEXT_TILE+1
|
||||
; offseting ptr_next_tile
|
||||
sec
|
||||
lda PTR_NEXT_TILE
|
||||
sbc #WIDTH_WORLD
|
||||
sta PTR_NEXT_TILE
|
||||
lda PTR_NEXT_TILE+1
|
||||
sbc #0
|
||||
sta PTR_NEXT_TILE+1
|
||||
|
||||
end_tst_up_tile:
|
||||
rts
|
2
src/builder/maze.inc
Normal file
2
src/builder/maze.inc
Normal file
|
@ -0,0 +1,2 @@
|
|||
.import Grow_Maze
|
||||
.import Remove_Dead_Ends
|
662
src/builder/rooms.asm
Normal file
662
src/builder/rooms.asm
Normal file
|
@ -0,0 +1,662 @@
|
|||
|
||||
; Copyright (C) 2019 Christophe Meneboeuf <christophe@xtof.info>
|
||||
;
|
||||
; This program is free software: you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation, either version 3 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
.include "../memory.inc"
|
||||
.include "../random.inc"
|
||||
.include "../math.inc"
|
||||
.include "../common.inc"
|
||||
.include "../world/world.inc"
|
||||
.include "../actors/actors.inc"
|
||||
|
||||
.export Carve_Rooms
|
||||
.export Connect_Rooms
|
||||
|
||||
.import Rooms
|
||||
.import Compute_Maze_Addr
|
||||
.import World
|
||||
.import WIDTH_MAZE
|
||||
.import HEIGHT_MAZE
|
||||
|
||||
|
||||
.BSS
|
||||
|
||||
; Configration to build rooms
|
||||
; FIXME??? CA65 will locate this struct at address 0 !!!
|
||||
.struct Config_Room
|
||||
width_min .byte
|
||||
width_max .byte
|
||||
height_min .byte
|
||||
height_max .byte
|
||||
.endstruct
|
||||
|
||||
.CODE
|
||||
|
||||
.define NB_ATTEMPTS ZERO_2_1
|
||||
.define NB_ROOMS_OK ZERO_2_2
|
||||
.define NB_ROOMS_TO_DRAW NB_ATTEMPTS
|
||||
.define IDX_ROOMS ZERO_3
|
||||
|
||||
; @params A nb_attempts
|
||||
; @returns NB_ROOMS_OK in A
|
||||
Carve_Rooms:
|
||||
|
||||
sta NB_ATTEMPTS
|
||||
|
||||
; height_max + width_max shall be < 64
|
||||
lda #9
|
||||
sta Config_Room::height_max
|
||||
lda #3
|
||||
sta Config_Room::height_min
|
||||
lda #11
|
||||
sta Config_Room::width_max
|
||||
lda #3
|
||||
sta Config_Room::width_min
|
||||
|
||||
ldx #0
|
||||
stx NB_ROOMS_OK
|
||||
|
||||
loop_rooms:
|
||||
|
||||
dec NB_ATTEMPTS
|
||||
beq end_loop_rooms
|
||||
lda NB_ROOMS_OK ; NB_ROOMS_OK*sizeof(room_t) -> X
|
||||
asl
|
||||
asl
|
||||
tax
|
||||
|
||||
jsr _Build_Room
|
||||
|
||||
lda NB_ROOMS_OK
|
||||
jsr _Is_intersecting
|
||||
cmp #TRUE ; not intersecting with another room?
|
||||
beq loop_rooms
|
||||
|
||||
inc NB_ROOMS_OK
|
||||
jmp loop_rooms
|
||||
|
||||
end_loop_rooms:
|
||||
|
||||
lda NB_ROOMS_OK
|
||||
sta NB_ROOMS_TO_DRAW
|
||||
|
||||
ldx #0
|
||||
loop_draw_rooms:
|
||||
|
||||
jsr _Draw_Room
|
||||
|
||||
inx
|
||||
inx
|
||||
inx
|
||||
inx
|
||||
|
||||
dec NB_ROOMS_TO_DRAW
|
||||
bne loop_draw_rooms
|
||||
|
||||
end_loop_draw_rooms:
|
||||
|
||||
lda NB_ROOMS_OK
|
||||
|
||||
rts
|
||||
.undefine NB_ATTEMPTS
|
||||
.undefine NB_ROOMS_OK
|
||||
.undefine NB_ROOMS_TO_DRAW
|
||||
.undefine IDX_ROOMS
|
||||
|
||||
|
||||
.define ADDR_WORLD ZERO_2_3 ; 2 bytes
|
||||
.define NB_LINE ZERO_2_5
|
||||
.define LINE_LENGTH ZERO_2_6
|
||||
.define IDX_ROOMS ZERO_3
|
||||
_Draw_Room:
|
||||
|
||||
stx IDX_ROOMS
|
||||
|
||||
ldy Rooms+3, X ; room->y
|
||||
lda Rooms+2, X ; rooms->x
|
||||
tax
|
||||
PUSH ZERO_2_1
|
||||
PUSH ZERO_2_2
|
||||
jsr Compute_Maze_Addr
|
||||
stx ADDR_WORLD
|
||||
sta ADDR_WORLD+1
|
||||
POP ZERO_2_2
|
||||
POP ZERO_2_1
|
||||
|
||||
|
||||
ldx IDX_ROOMS
|
||||
ldy Rooms, X ; room->height
|
||||
sty NB_LINE
|
||||
lda Rooms+1, X ; room->width
|
||||
sta LINE_LENGTH
|
||||
loop_draw_line:
|
||||
lda #eACTORTYPES::FLOOR_1
|
||||
ldy #0
|
||||
loop_draw_tile:
|
||||
sta (ADDR_WORLD), Y
|
||||
iny
|
||||
cpy LINE_LENGTH
|
||||
bne loop_draw_tile
|
||||
end_loop_draw_tile:
|
||||
clc
|
||||
lda ADDR_WORLD
|
||||
adc #WIDTH_WORLD
|
||||
sta ADDR_WORLD
|
||||
lda ADDR_WORLD+1
|
||||
adc #0
|
||||
sta ADDR_WORLD+1
|
||||
dec NB_LINE
|
||||
bne loop_draw_line
|
||||
end_loop_draw_line:
|
||||
|
||||
ldx IDX_ROOMS
|
||||
rts
|
||||
.undefine ADDR_WORLD
|
||||
.undefine NB_LINE
|
||||
.undefine LINE_LENGTH
|
||||
.undefine IDX_ROOMS
|
||||
|
||||
|
||||
.define MODULUS ZERO_2_3
|
||||
.define WIDTH_ROOM ZERO_2_5
|
||||
.define HEIGHT_ROOM ZERO_2_6
|
||||
.define OFFSET_ROOMS ZERO_5_1
|
||||
; @param X offset to the room to be built from Rooms
|
||||
; @return offset room in X
|
||||
_Build_Room:
|
||||
|
||||
stx OFFSET_ROOMS
|
||||
|
||||
; room.height = config->height_min + Random8() % (config->height_max - config->height_min - 1);
|
||||
sec
|
||||
lda Config_Room::height_max
|
||||
sbc Config_Room::height_min
|
||||
sbc #1
|
||||
sta MODULUS
|
||||
jsr Random8
|
||||
and #7
|
||||
ldx MODULUS
|
||||
jsr Modulus
|
||||
ldx OFFSET_ROOMS
|
||||
clc
|
||||
adc Config_Room::height_min
|
||||
ora #1
|
||||
sta Rooms, x ; height
|
||||
sta HEIGHT_ROOM
|
||||
inx
|
||||
stx OFFSET_ROOMS
|
||||
|
||||
; room.width = config->width_min + Random8() % (config->width_max - config->width_min - 1);
|
||||
sec
|
||||
lda Config_Room::width_max
|
||||
sbc Config_Room::width_min
|
||||
sbc #1
|
||||
sta MODULUS
|
||||
jsr Random8
|
||||
and #$F ; room's height shall be < 16
|
||||
ldx MODULUS
|
||||
jsr Modulus
|
||||
ldx OFFSET_ROOMS
|
||||
clc
|
||||
adc Config_Room::width_min
|
||||
ora #1
|
||||
sta Rooms, x ; width
|
||||
sta WIDTH_ROOM
|
||||
inx
|
||||
stx OFFSET_ROOMS
|
||||
|
||||
|
||||
; room.x = 3 + Random8() % (WIDTH_MAZE - room.width - 5);
|
||||
sec
|
||||
lda WIDTH_MAZE
|
||||
sbc WIDTH_ROOM
|
||||
sbc #5
|
||||
sta MODULUS
|
||||
jsr Random8
|
||||
and #$7F
|
||||
ldx MODULUS
|
||||
jsr Modulus
|
||||
ldx OFFSET_ROOMS
|
||||
clc
|
||||
adc #3
|
||||
ora #1
|
||||
sta Rooms, x ; x
|
||||
inx
|
||||
stx OFFSET_ROOMS
|
||||
|
||||
; room.y = 3 + Random8() % (HEIGHT_MAZE - room.height - 5);
|
||||
sec
|
||||
lda HEIGHT_MAZE
|
||||
sbc HEIGHT_ROOM
|
||||
sbc #5
|
||||
sta MODULUS
|
||||
jsr Random8
|
||||
and #$7F
|
||||
ldx MODULUS
|
||||
jsr Modulus
|
||||
ldx OFFSET_ROOMS
|
||||
clc
|
||||
adc #3
|
||||
ora #1
|
||||
sta Rooms, x ; y
|
||||
inx
|
||||
stx OFFSET_ROOMS
|
||||
|
||||
rts
|
||||
.undefine MODULUS
|
||||
.undefine WIDTH_ROOM
|
||||
.undefine HEIGHT_ROOM
|
||||
.undefine OFFSET_ROOMS
|
||||
|
||||
|
||||
; @brief test ifthe room is intersecting with other rooms
|
||||
; @param A : nb rooms already carved
|
||||
; @return 0 if no intersection, 1 otherwise
|
||||
.define NB_ROOMS ZERO_3
|
||||
.define OFFSET_Y ZERO_2_4
|
||||
.define OFFSET_X ZERO_2_5
|
||||
_Is_intersecting:
|
||||
|
||||
cmp #0
|
||||
bne compare
|
||||
; first room
|
||||
lda #FALSE
|
||||
clc
|
||||
bcc end_intersecting ; branch always
|
||||
|
||||
; previous rooms were carved
|
||||
compare:
|
||||
sta NB_ROOMS
|
||||
asl ; * sizeof(room_t) to get offset to the last room randomized
|
||||
asl
|
||||
tax ; offset to new room in X
|
||||
stx OFFSET_X
|
||||
ldy #0 ; offset to carved rooms in Y
|
||||
|
||||
loop_intersecting: ; each test must be true
|
||||
sty OFFSET_Y
|
||||
clc
|
||||
lda Rooms+2, Y ; room->x
|
||||
adc Rooms+1, Y ; room->width
|
||||
cmp Rooms+2, X
|
||||
bcc false ; branch if room->x + room->width < new_room->x
|
||||
clc
|
||||
lda Rooms+2, X ; new_room->x
|
||||
adc Rooms+1, X ; new_room->width
|
||||
cmp Rooms+2, Y ; room->x
|
||||
bcc false ; branch if new_room->x + new_room->width < room->x
|
||||
clc
|
||||
lda Rooms+3, Y ; room->y
|
||||
adc Rooms, Y ; room->height
|
||||
cmp Rooms+3, X ; new_room->y
|
||||
bcc false ; branch if room->y + room->height < new_room->y
|
||||
clc
|
||||
lda Rooms+3, X ; new_room->y
|
||||
adc Rooms, X ; new_room->height
|
||||
cmp Rooms+3, Y ; room->y
|
||||
bcc false ; branch if new_room->y + new_room->height < room->y
|
||||
; all test are true: rooms are intersecting
|
||||
lda #TRUE ; return value
|
||||
clc
|
||||
bcc end_intersecting
|
||||
|
||||
false:
|
||||
ldx OFFSET_X
|
||||
lda OFFSET_Y
|
||||
adc #4
|
||||
tay
|
||||
dec NB_ROOMS
|
||||
bne loop_intersecting
|
||||
|
||||
lda #FALSE ; no room intersects
|
||||
|
||||
end_intersecting:
|
||||
rts
|
||||
|
||||
|
||||
; using HGR2 space as the stack
|
||||
; Stack contains pointers to the tiles encompassing a room (except the corners)
|
||||
.define STACK_ADDR $4000
|
||||
.define PTR_TILE_TOP ZERO_2_3 ; 2 bytes
|
||||
.define PTR_TILE_BOT ZERO_4_4 ; 2 bytes
|
||||
.define PTR_TILE_LEFT ZERO_2_3 ; 2 bytes
|
||||
.define PTR_TILE_RIGHT ZERO_4_4 ; 2 bytes
|
||||
.define PTR_TILE ZERO_2_1
|
||||
.define PTR_STACK ZERO_4_1 ; 2 bytes
|
||||
.define PROBABILITY_OPENING ZERO_4_3
|
||||
.define NB_DOORS ZERO_5_1
|
||||
.define NB_WALKABLE ZERO_5_2
|
||||
.define SIZE_STACK ZERO_5_3 ; 2 bytes
|
||||
.define WIDTH_ROOM ZERO_2_5
|
||||
.define HEIGHT_ROOM ZERO_2_6
|
||||
.define OFFSET_ROOMS ZERO_5_5
|
||||
|
||||
; @brief Connects the rooms to the maze's galleries
|
||||
; @param A number of rooms
|
||||
; @param X probability to make an opening in a wall tile
|
||||
; @detail One opening is made, then all remaning encompassing wall tiles
|
||||
; can be opened. Depending on the provided probability
|
||||
Connect_Rooms:
|
||||
|
||||
sta NB_ROOMS
|
||||
stx PROBABILITY_OPENING
|
||||
|
||||
lda #0
|
||||
sta OFFSET_ROOMS
|
||||
; for each room
|
||||
loop_connect_rooms:
|
||||
|
||||
; # Build a stack of encompassing tiles. Except corners
|
||||
lda #<STACK_ADDR
|
||||
sta PTR_STACK
|
||||
lda #>STACK_ADDR
|
||||
sta PTR_STACK+1
|
||||
|
||||
; ## stacking horizontal walls
|
||||
; ### init ptr_top
|
||||
ldx OFFSET_ROOMS
|
||||
inx
|
||||
inx
|
||||
lda Rooms, X ; room->x
|
||||
sta PTR_TILE_TOP
|
||||
clc
|
||||
lda #<World
|
||||
adc PTR_TILE_TOP
|
||||
sta PTR_TILE_TOP
|
||||
lda #>World
|
||||
adc #0
|
||||
sta PTR_TILE_TOP+1
|
||||
inx
|
||||
lda Rooms, X ; room->y
|
||||
tax
|
||||
dex
|
||||
stx FAC1
|
||||
lda #WIDTH_WORLD
|
||||
sta FAC2
|
||||
jsr mul8
|
||||
tay
|
||||
txa
|
||||
clc
|
||||
adc PTR_TILE_TOP
|
||||
sta PTR_TILE_TOP
|
||||
tya
|
||||
adc PTR_TILE_TOP+1
|
||||
sta PTR_TILE_TOP+1
|
||||
|
||||
; ### init ptr_bottom
|
||||
ldx OFFSET_ROOMS
|
||||
lda Rooms, X ; room->height
|
||||
sta HEIGHT_ROOM
|
||||
tax
|
||||
inx
|
||||
stx FAC1
|
||||
lda #WIDTH_WORLD
|
||||
sta FAC2
|
||||
jsr mul8
|
||||
tay
|
||||
txa
|
||||
clc
|
||||
adc PTR_TILE_TOP
|
||||
sta PTR_TILE_BOT
|
||||
tya
|
||||
adc PTR_TILE_TOP+1
|
||||
sta PTR_TILE_BOT+1
|
||||
|
||||
; ## stacking
|
||||
ldx OFFSET_ROOMS
|
||||
inx
|
||||
lda Rooms, X ; room->width
|
||||
sta WIDTH_ROOM
|
||||
; for x = 0; x < room->width; x++
|
||||
ldx #0
|
||||
loop_stack_horiz:
|
||||
ldy #0
|
||||
clc
|
||||
txa
|
||||
adc PTR_TILE_TOP
|
||||
sta (PTR_STACK), Y
|
||||
iny
|
||||
lda #0
|
||||
adc PTR_TILE_TOP+1
|
||||
sta (PTR_STACK), Y
|
||||
iny
|
||||
txa
|
||||
adc PTR_TILE_BOT
|
||||
sta (PTR_STACK), Y
|
||||
iny
|
||||
lda #0
|
||||
adc PTR_TILE_BOT+1
|
||||
sta (PTR_STACK), Y
|
||||
iny
|
||||
; incr ptr_stack
|
||||
tya
|
||||
clc
|
||||
adc PTR_STACK
|
||||
sta PTR_STACK
|
||||
lda #0
|
||||
adc PTR_STACK+1
|
||||
sta PTR_STACK+1
|
||||
; next x
|
||||
inx
|
||||
cpx WIDTH_ROOM
|
||||
bne loop_stack_horiz
|
||||
|
||||
; ## stacking vertical walls
|
||||
; ### init ptr_left
|
||||
clc
|
||||
lda #(WIDTH_WORLD-1)
|
||||
adc PTR_TILE_TOP
|
||||
sta PTR_TILE_LEFT
|
||||
lda #0
|
||||
adc PTR_TILE_TOP+1
|
||||
sta PTR_TILE_LEFT+1
|
||||
; ### init ptr_right
|
||||
clc
|
||||
lda WIDTH_ROOM
|
||||
adc #1
|
||||
adc PTR_TILE_LEFT
|
||||
sta PTR_TILE_RIGHT
|
||||
lda #0
|
||||
adc PTR_TILE_LEFT+1
|
||||
sta PTR_TILE_RIGHT+1
|
||||
; ### stacking
|
||||
; for y = 0; y < room->height; y++
|
||||
ldx #0
|
||||
loop_stack_vertical:
|
||||
ldy #1
|
||||
lda PTR_TILE_LEFT+1
|
||||
sta (PTR_STACK), Y
|
||||
dey
|
||||
lda PTR_TILE_LEFT
|
||||
sta (PTR_STACK), Y
|
||||
clc
|
||||
adc #WIDTH_WORLD
|
||||
sta PTR_TILE_LEFT
|
||||
lda PTR_TILE_LEFT+1
|
||||
adc #0
|
||||
sta PTR_TILE_LEFT+1
|
||||
iny
|
||||
iny
|
||||
iny
|
||||
lda PTR_TILE_RIGHT+1
|
||||
sta (PTR_STACK), Y
|
||||
dey
|
||||
lda PTR_TILE_RIGHT
|
||||
sta (PTR_STACK), Y
|
||||
clc
|
||||
adc #WIDTH_WORLD
|
||||
sta PTR_TILE_RIGHT
|
||||
lda PTR_TILE_RIGHT+1
|
||||
adc #0
|
||||
sta PTR_TILE_RIGHT+1
|
||||
; incr ptr_stack
|
||||
clc
|
||||
lda #4
|
||||
adc PTR_STACK
|
||||
sta PTR_STACK
|
||||
lda #0
|
||||
adc PTR_STACK+1
|
||||
sta PTR_STACK+1
|
||||
; next y
|
||||
inx
|
||||
cpx HEIGHT_ROOM
|
||||
bne loop_stack_vertical
|
||||
|
||||
; ## Compute stack's size
|
||||
; UTILISER DIRECTEMENT L ADRESSE DE FIN ET BREAKER QUAND ON L ATTEINT
|
||||
sec
|
||||
lda PTR_STACK
|
||||
sbc #<STACK_ADDR
|
||||
pha
|
||||
lda PTR_STACK+1
|
||||
sbc #>STACK_ADDR
|
||||
lsr
|
||||
sta SIZE_STACK+1
|
||||
pla
|
||||
ror
|
||||
sta SIZE_STACK
|
||||
|
||||
; # Opening the first door
|
||||
lda #0
|
||||
sta NB_DOORS
|
||||
lda #<STACK_ADDR
|
||||
sta PTR_STACK ; here stack size < 128, no need for hsb of the address
|
||||
loop_first_door:
|
||||
jsr Random8
|
||||
ldx SIZE_STACK
|
||||
jsr Modulus
|
||||
asl
|
||||
tay
|
||||
lda (PTR_STACK), Y
|
||||
;PTR_TILE = *PTR_STACK - WIDTH_WORLD
|
||||
sec
|
||||
sbc #WIDTH_WORLD
|
||||
sta PTR_TILE
|
||||
iny
|
||||
lda (PTR_STACK), Y
|
||||
sbc #0
|
||||
sta PTR_TILE+1
|
||||
jsr _nb_walkable
|
||||
lda NB_WALKABLE
|
||||
cmp #2
|
||||
bcc loop_first_door ; nb_walkable < 2
|
||||
inc NB_DOORS
|
||||
ldy #WIDTH_WORLD
|
||||
lda #eACTORTYPES::FLOOR_1
|
||||
sta (PTR_TILE), Y
|
||||
|
||||
; # Opening the other doors
|
||||
.define IDX ZERO_2_3
|
||||
lda #<STACK_ADDR
|
||||
sta PTR_STACK ; here stack size < 128, no need for hsb of the address
|
||||
lda #$FF
|
||||
sta IDX
|
||||
loop_other_doors:
|
||||
inc IDX
|
||||
; test if end
|
||||
lda SIZE_STACK
|
||||
asl
|
||||
cmp IDX
|
||||
beq end_loop_other_doors
|
||||
; random number to be compare to the probability of a door
|
||||
jsr Random8
|
||||
cmp PROBABILITY_OPENING
|
||||
bcc test_door
|
||||
beq test_door
|
||||
inc IDX
|
||||
bcs loop_other_doors ; always jump as the previous bcc failed
|
||||
; test if the tile can be linked to the maze
|
||||
test_door:
|
||||
ldy IDX
|
||||
lda (PTR_STACK), Y
|
||||
;PTR_TILE = *PTR_STACK - WIDTH_WORLD
|
||||
sec
|
||||
sbc #WIDTH_WORLD
|
||||
sta PTR_TILE
|
||||
iny
|
||||
lda (PTR_STACK), Y
|
||||
sbc #0
|
||||
sta PTR_TILE+1
|
||||
sty IDX
|
||||
jsr _nb_walkable
|
||||
lda NB_WALKABLE
|
||||
cmp #2
|
||||
bcs carve_a_door
|
||||
bcc loop_other_doors ; always jump as the previous bcs failed
|
||||
carve_a_door:
|
||||
ldy #WIDTH_WORLD
|
||||
lda #eACTORTYPES::FLOOR_1
|
||||
sta (PTR_TILE), Y
|
||||
inc NB_DOORS
|
||||
jmp loop_other_doors
|
||||
end_loop_other_doors:
|
||||
|
||||
dec NB_ROOMS
|
||||
beq end_loop_connect_rooms
|
||||
|
||||
; next room
|
||||
lda OFFSET_ROOMS
|
||||
clc
|
||||
adc #.sizeof(Config_Room)
|
||||
sta OFFSET_ROOMS
|
||||
jmp loop_connect_rooms
|
||||
|
||||
end_loop_connect_rooms:
|
||||
rts
|
||||
|
||||
; @brief returns the number of walkable neighbours. >= 2 if it can be carved
|
||||
; @detailed PTR_TILE is offsetted by -WIDTH_WORLD
|
||||
_nb_walkable:
|
||||
lda #0
|
||||
sta NB_WALKABLE
|
||||
lda #eACTORTYPES::FLOOR_1
|
||||
tst_up:
|
||||
ldy #0
|
||||
cmp (PTR_TILE), Y
|
||||
bne tst_left
|
||||
inc NB_WALKABLE
|
||||
tst_left:
|
||||
ldy #(WIDTH_WORLD-1)
|
||||
cmp (PTR_TILE), Y
|
||||
bne tst_right
|
||||
inc NB_WALKABLE
|
||||
tst_right:
|
||||
ldy #(WIDTH_WORLD+1)
|
||||
cmp (PTR_TILE), Y
|
||||
bne tst_down
|
||||
inc NB_WALKABLE
|
||||
tst_down:
|
||||
ldy #(2*WIDTH_WORLD)
|
||||
cmp (PTR_TILE), Y
|
||||
bne end_is_door_possible
|
||||
inc NB_WALKABLE
|
||||
end_is_door_possible:
|
||||
rts
|
||||
|
||||
.undefine STACK_ADDR
|
||||
.undefine PTR_TILE_TOP
|
||||
.undefine PTR_TILE_BOT
|
||||
.undefine PTR_TILE_LEFT
|
||||
.undefine PTR_TILE_RIGHT
|
||||
.undefine PTR_TILE
|
||||
.undefine PTR_STACK
|
||||
.undefine PROBABILITY_OPENING
|
||||
.undefine NB_DOORS
|
||||
.undefine NB_WALKABLE
|
||||
.undefine SIZE_STACK
|
||||
.undefine WIDTH_ROOM
|
||||
.undefine HEIGHT_ROOM
|
||||
.undefine OFFSET_ROOMS
|
||||
|
20
src/builder/rooms.inc
Normal file
20
src/builder/rooms.inc
Normal file
|
@ -0,0 +1,20 @@
|
|||
|
||||
; Copyright (C) 2019 Christophe Meneboeuf <christophe@xtof.info>
|
||||
;
|
||||
; This program is free software: you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation, either version 3 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
.import Carve_Rooms
|
||||
.import Connect_Rooms
|
||||
|
||||
.define MAX_NB_ROOMS 64 ; MAX_NB_ROOMS *MUST BE* <= 64 and a power of 2
|
561
src/builder/unite.asm
Normal file
561
src/builder/unite.asm
Normal file
|
@ -0,0 +1,561 @@
|
|||
|
||||
; Copyright (C) 2020 Christophe Meneboeuf <christophe@xtof.info>
|
||||
;
|
||||
; This program is free software: you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation, either version 3 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
|
||||
.include "rooms.inc"
|
||||
.include "maze.inc"
|
||||
.include "../io/textio.inc"
|
||||
.include "../memory.inc"
|
||||
.include "../math.inc"
|
||||
.include "../common.inc"
|
||||
.include "../world/world.inc"
|
||||
.include "../actors/actors.inc"
|
||||
|
||||
.import World
|
||||
.import Rooms
|
||||
.import WIDTH_MAZE
|
||||
.import HEIGHT_MAZE
|
||||
|
||||
.import Compute_Maze_Addr
|
||||
|
||||
.export Unite_Rooms
|
||||
|
||||
|
||||
|
||||
.CODE
|
||||
|
||||
|
||||
.define PTR_TILE ZERO_2_1 ; 2 bytes
|
||||
.define ZONE_NR ZERO_2_4
|
||||
.define CPT_X ZERO_2_5
|
||||
.define CPT_Y ZERO_2_6
|
||||
|
||||
|
||||
.define QUEUE_ADDR $4000
|
||||
|
||||
|
||||
.define REPLACED_NR ZERO_3
|
||||
.define PTR_QUEUE ZERO_4_1 ; 2 bytes
|
||||
.define PTR_TILE_LOCAL ZERO_4_3 ; 2 bytes
|
||||
.define FILL_NR ZERO_4_5
|
||||
; @param X fill color
|
||||
; @param A replaced
|
||||
; @return TRUE in A some tiles were filled, FALSE otherwise
|
||||
_Flood_Fill :
|
||||
|
||||
stx FILL_NR
|
||||
ldy #0
|
||||
cmp (PTR_TILE), Y ; if (*ptr_tile != replaced) return;
|
||||
beq fill_1
|
||||
lda #FALSE
|
||||
rts
|
||||
|
||||
fill_1:
|
||||
sta REPLACED_NR
|
||||
txa
|
||||
sta (PTR_TILE), Y
|
||||
lda #<QUEUE_ADDR
|
||||
sta PTR_QUEUE
|
||||
lda #>QUEUE_ADDR
|
||||
sta PTR_QUEUE+1
|
||||
; offset ptr_tile by -width_world to be quickly accessed with an Y offset
|
||||
lda PTR_TILE
|
||||
sec
|
||||
sbc #WIDTH_WORLD
|
||||
sta QUEUE_ADDR
|
||||
lda PTR_TILE+1
|
||||
sbc #0
|
||||
sta QUEUE_ADDR+1
|
||||
|
||||
ldx #0
|
||||
loop_fill:
|
||||
|
||||
; while ptr_queue >= QUEUE_ADDR
|
||||
lda PTR_QUEUE
|
||||
cmp #<(QUEUE_ADDR-2)
|
||||
bne continue_fill
|
||||
lda PTR_QUEUE+1
|
||||
cmp #>(QUEUE_ADDR-2)
|
||||
bne continue_fill
|
||||
jmp end_fill
|
||||
|
||||
continue_fill:
|
||||
; ptr_tile = *(ptr_queue--);
|
||||
ldy #0
|
||||
lda (PTR_QUEUE), Y
|
||||
sta PTR_TILE_LOCAL
|
||||
iny
|
||||
lda (PTR_QUEUE), Y
|
||||
sta PTR_TILE_LOCAL+1
|
||||
DEC16 PTR_QUEUE, #2
|
||||
|
||||
tile_west:
|
||||
; if (*tile_west == replaced)
|
||||
ldy #(WIDTH_WORLD+1)
|
||||
lda REPLACED_NR
|
||||
cmp (PTR_TILE_LOCAL),Y
|
||||
bne tile_east
|
||||
; *tile_west = fill;
|
||||
lda FILL_NR
|
||||
sta (PTR_TILE_LOCAL),Y
|
||||
; *(++ptr_queue) = tile_w
|
||||
ADD16 PTR_QUEUE, #2, #0
|
||||
clc
|
||||
lda #1
|
||||
adc PTR_TILE_LOCAL
|
||||
ldy #0
|
||||
sta (PTR_QUEUE),Y
|
||||
lda #0
|
||||
adc PTR_TILE_LOCAL+1
|
||||
iny
|
||||
sta (PTR_QUEUE),Y
|
||||
|
||||
|
||||
tile_east:
|
||||
; if (*tile_east == replaced)
|
||||
ldy #(WIDTH_WORLD-1)
|
||||
lda REPLACED_NR
|
||||
cmp (PTR_TILE_LOCAL),Y
|
||||
bne tile_north
|
||||
; *tile_east = fill;
|
||||
lda FILL_NR
|
||||
sta (PTR_TILE_LOCAL),Y
|
||||
; *(++ptr_queue) = tile_tile_east
|
||||
ADD16 PTR_QUEUE, #2, #0
|
||||
sec
|
||||
lda PTR_TILE_LOCAL
|
||||
sbc #1
|
||||
ldy #0
|
||||
sta (PTR_QUEUE),Y
|
||||
lda PTR_TILE_LOCAL+1
|
||||
sbc #0
|
||||
iny
|
||||
sta (PTR_QUEUE),Y
|
||||
|
||||
tile_north:
|
||||
; if (*tile_north == replaced)
|
||||
ldy #0
|
||||
lda REPLACED_NR
|
||||
cmp (PTR_TILE_LOCAL),Y
|
||||
bne tile_south
|
||||
; *tile_north = fill;
|
||||
lda FILL_NR
|
||||
sta (PTR_TILE_LOCAL),Y
|
||||
; *(++ptr_queue) = tile_tile_north
|
||||
ADD16 PTR_QUEUE, #2, #0
|
||||
sec
|
||||
lda PTR_TILE_LOCAL
|
||||
sbc #WIDTH_WORLD
|
||||
ldy #0
|
||||
sta (PTR_QUEUE),Y
|
||||
lda PTR_TILE_LOCAL+1
|
||||
sbc #0
|
||||
iny
|
||||
sta (PTR_QUEUE),Y
|
||||
|
||||
tile_south:
|
||||
; if (*tile_south == replaced)
|
||||
ldy #(2*WIDTH_WORLD)
|
||||
lda REPLACED_NR
|
||||
cmp (PTR_TILE_LOCAL),Y
|
||||
bne end_tiles
|
||||
; *tile_south = fill;
|
||||
lda FILL_NR
|
||||
sta (PTR_TILE_LOCAL),Y
|
||||
; *(++ptr_queue) = tile_tile_south
|
||||
ADD16 PTR_QUEUE, #2, #0
|
||||
clc
|
||||
lda #WIDTH_WORLD
|
||||
adc PTR_TILE_LOCAL
|
||||
ldy #0
|
||||
sta (PTR_QUEUE),Y
|
||||
lda #0
|
||||
adc PTR_TILE_LOCAL+1
|
||||
iny
|
||||
sta (PTR_QUEUE),Y
|
||||
|
||||
end_tiles:
|
||||
jmp loop_fill
|
||||
|
||||
|
||||
end_fill:
|
||||
lda #TRUE
|
||||
rts
|
||||
|
||||
|
||||
|
||||
.define ROOM_NR ZERO_3
|
||||
.define SAVE_X ZERO_4_1
|
||||
.define PTR_ROOM ZERO_4_2 ; 2 bytes
|
||||
.define ZONE_0 eACTORTYPES::FLOOR_1 ; 1st useful zone: ZONE_1
|
||||
Unite_Rooms:
|
||||
|
||||
; *** flood fill room to identify separated zones ***
|
||||
; &Wordl[1][1] -> ptr_tile
|
||||
clc
|
||||
lda #<World
|
||||
adc #WIDTH_WORLD+1
|
||||
sta PTR_TILE
|
||||
lda #>World
|
||||
adc #0
|
||||
sta PTR_TILE+1
|
||||
lda #1
|
||||
sta CPT_X
|
||||
sta CPT_Y
|
||||
|
||||
lda #ZONE_0
|
||||
sta ZONE_NR
|
||||
inc ZONE_NR
|
||||
|
||||
loop_flood:
|
||||
ldx ZONE_NR
|
||||
lda #ZONE_0
|
||||
jsr _Flood_Fill
|
||||
cmp #TRUE
|
||||
bne loop_flood_next
|
||||
inc ZONE_NR
|
||||
|
||||
loop_flood_next:
|
||||
;next tile
|
||||
ADD16 PTR_TILE, #1, #0
|
||||
; end line?
|
||||
inc CPT_X
|
||||
ldx CPT_X
|
||||
cpx #WIDTH_WORLD-1
|
||||
bne loop_flood
|
||||
ldx #0
|
||||
stx CPT_X
|
||||
; next
|
||||
ADD16 PTR_TILE, #1, #0
|
||||
; the end?
|
||||
inc CPT_Y
|
||||
ldy CPT_Y
|
||||
cpy #HEIGHT_WORLD-1
|
||||
bne loop_flood
|
||||
|
||||
; ***
|
||||
; reunite rooms that are not in the first zone
|
||||
; find the location of a room in zone_1
|
||||
; Its origin will be targeted by th other zones to join
|
||||
; ***
|
||||
.define SIZEOF_ROOM_T 4
|
||||
.define ROOM_ZONE_1 ZERO_5_4
|
||||
lda #0 ; FIXEME : useless?
|
||||
sta ROOM_NR ; FIXEME : useless?
|
||||
ldx #3
|
||||
lda #WIDTH_WORLD
|
||||
sta FAC2
|
||||
loop_find_room:
|
||||
lda Rooms, X
|
||||
tay
|
||||
stx SAVE_X
|
||||
dex
|
||||
lda Rooms, X
|
||||
tax
|
||||
jsr Compute_Maze_Addr
|
||||
sta PTR_TILE+1
|
||||
stx PTR_TILE
|
||||
ldy #0
|
||||
lda (PTR_TILE), Y
|
||||
cmp #(ZONE_0 + 1)
|
||||
beq room_found
|
||||
; next room
|
||||
lda SAVE_X
|
||||
clc
|
||||
adc #(SIZEOF_ROOM_T)
|
||||
tax
|
||||
jmp loop_find_room
|
||||
|
||||
room_found:
|
||||
ldx SAVE_X
|
||||
stx ROOM_ZONE_1
|
||||
|
||||
; ***
|
||||
; Connect one room of each zone to the location found
|
||||
.define END_LOOP_ZONE ZERO_5_1
|
||||
lda ZONE_NR
|
||||
sta END_LOOP_ZONE
|
||||
lda #(ZONE_0 + 2) ; zone_2
|
||||
cmp END_LOOP_ZONE
|
||||
beq end_loop_zone ; only one zone
|
||||
sta ZONE_NR
|
||||
|
||||
; loop over the zones
|
||||
loop_zones:
|
||||
|
||||
ldx #3
|
||||
loop_rooms: ; find a room of the zone
|
||||
lda Rooms, X
|
||||
tay
|
||||
stx SAVE_X
|
||||
dex
|
||||
lda Rooms, X
|
||||
tax
|
||||
jsr Compute_Maze_Addr
|
||||
stx ZERO_5_2
|
||||
sta ZERO_5_3
|
||||
ldy #0
|
||||
lda (ZERO_5_2), Y
|
||||
cmp ZONE_NR
|
||||
beq zone_found
|
||||
; next room
|
||||
lda SAVE_X
|
||||
clc
|
||||
adc #(SIZEOF_ROOM_T)
|
||||
tax
|
||||
jmp loop_rooms
|
||||
|
||||
zone_found:
|
||||
jsr _Connect_Room
|
||||
; next zone
|
||||
inc ZONE_NR
|
||||
; end loop?
|
||||
lda END_LOOP_ZONE
|
||||
cmp ZONE_NR
|
||||
beq end_loop_zone
|
||||
; loop
|
||||
jmp loop_zones
|
||||
|
||||
end_loop_zone:
|
||||
|
||||
|
||||
|
||||
rts
|
||||
|
||||
; to compute ptr_romm += ix / iy or ptr_romm += ix / iy, the code is patched.
|
||||
.macro PATCH_POS address, address2
|
||||
lda #$18 ; clc
|
||||
sta address
|
||||
sta address2
|
||||
lda #$69 ; adc imm
|
||||
sta address+3 ; adc #1 / #WIDTH_WORLD
|
||||
sta address+9 ; adc #0
|
||||
sta address2+3 ; adc #1 / #WIDTH_WORLD
|
||||
sta address2+9 ; adc #0
|
||||
.endmacro
|
||||
.macro PATCH_NEG address, address2
|
||||
lda #$38 ; sec
|
||||
sta address
|
||||
sta address2
|
||||
lda #$E9 ; sbc imm
|
||||
sta address+3 ; sbc #1 / #WIDTH_WORLD
|
||||
sta address+9 ; sbc #0
|
||||
sta address2+3 ; sbc #1 / #WIDTH_WORLD
|
||||
sta address2+9 ; sbc #0
|
||||
.endmacro
|
||||
|
||||
.define DELTA_X ZERO_9_1
|
||||
.define DELTA_Y ZERO_9_2
|
||||
.define DELTA_X_2 ZERO_9_3
|
||||
.define DELTA_Y_2 ZERO_9_4
|
||||
.define ROOM_Y ZERO_9_5
|
||||
.define ROOM_X ZERO_9_6
|
||||
.define D ZERO_9_7
|
||||
.define ROOM_FOUND SAVE_X
|
||||
_Connect_Room:
|
||||
|
||||
; d = 0
|
||||
lda #0
|
||||
sta D
|
||||
|
||||
; delta_y = zone1_y - room->y
|
||||
ldx ROOM_FOUND
|
||||
lda Rooms, X
|
||||
sta ROOM_Y ; room->y
|
||||
dex
|
||||
lda Rooms, X
|
||||
sta ROOM_X ; room->x
|
||||
ldx ROOM_ZONE_1
|
||||
lda Rooms, X ; zone1_y
|
||||
sec
|
||||
sbc ROOM_Y
|
||||
sta DELTA_Y
|
||||
; delta_x = zone1_x - room->x
|
||||
dex
|
||||
lda Rooms, X ; zone1_x
|
||||
sec
|
||||
sbc ROOM_X
|
||||
sta DELTA_X
|
||||
|
||||
; delta_x = delta_x > 0 ? delta_x : -delta_x
|
||||
lda #0
|
||||
cmp DELTA_X
|
||||
bmi end_abs_x
|
||||
sec
|
||||
sbc DELTA_X
|
||||
sta DELTA_X
|
||||
end_abs_x:
|
||||
; int dx2 = 2 * dx
|
||||
lda DELTA_X
|
||||
asl
|
||||
sta DELTA_X_2
|
||||
|
||||
; delta_y = delta_y > 0 ? delta_y : -delta_y
|
||||
abs_delta_y:
|
||||
lda #0
|
||||
cmp DELTA_Y
|
||||
bmi end_abs_y
|
||||
sec
|
||||
sbc DELTA_Y
|
||||
sta DELTA_Y
|
||||
end_abs_y:
|
||||
; int dy2 = 2 * dy
|
||||
lda DELTA_Y
|
||||
asl
|
||||
sta DELTA_Y_2
|
||||
|
||||
; uint8_t* ptr_room = &World[room->y][room->x]
|
||||
ldx ROOM_X
|
||||
ldy ROOM_Y
|
||||
jsr Compute_Maze_Addr
|
||||
stx PTR_ROOM
|
||||
stx PTR_TILE
|
||||
sta PTR_ROOM+1
|
||||
sta PTR_TILE+1
|
||||
|
||||
ldx ROOM_ZONE_1
|
||||
dex
|
||||
; int ix = room->x < zone1_x ? 1 : -1
|
||||
ix:
|
||||
lda ROOM_X
|
||||
cmp Rooms, X
|
||||
bcc ix_positive
|
||||
PATCH_NEG patch_ix1, patch_ix2
|
||||
jmp iy
|
||||
ix_positive:
|
||||
PATCH_POS patch_ix1, patch_ix2
|
||||
; int iy = room->y < zone1_y ? WIDTH_WORLD : -WIDTH_WORLD;
|
||||
iy:
|
||||
inx
|
||||
lda ROOM_Y
|
||||
cmp Rooms, X
|
||||
bcc iy_positive
|
||||
PATCH_NEG patch_iy1, patch_iy2
|
||||
jmp iterate
|
||||
iy_positive:
|
||||
PATCH_POS patch_iy1, patch_iy2
|
||||
|
||||
iterate:
|
||||
ldy #0
|
||||
lda DELTA_X
|
||||
cmp DELTA_Y
|
||||
bcc dy_sup
|
||||
; if (dx >= dy)
|
||||
dx_sup:
|
||||
while_1:
|
||||
; ptr_room += ix
|
||||
patch_ix1:
|
||||
ADD16 PTR_ROOM, #1, #0
|
||||
; d += dy2
|
||||
clc
|
||||
lda DELTA_Y_2
|
||||
adc D
|
||||
sta D
|
||||
cmp DELTA_X
|
||||
bcc d_infequal_dx
|
||||
beq d_infequal_dx
|
||||
; if (d > dx)
|
||||
; if (*ptr_room != zone_nr && *ptr_room <= WALKABLE) break;
|
||||
lda (PTR_ROOM), Y ; Y = 0
|
||||
cmp ZONE_NR
|
||||
beq continue_1a
|
||||
cmp #eACTORTYPES::LAST_FLOOR
|
||||
beq end
|
||||
bpl continue_1a
|
||||
jmp end
|
||||
continue_1a:
|
||||
; *ptr_room = zone_nr
|
||||
lda ZONE_NR
|
||||
sta (PTR_ROOM), Y ; Y = 0
|
||||
; ptr_room += iy
|
||||
patch_iy1:
|
||||
ADD16 PTR_ROOM, #WIDTH_WORLD, #0
|
||||
; d -= dx2
|
||||
sec
|
||||
lda D
|
||||
sbc DELTA_X_2
|
||||
sta D
|
||||
d_infequal_dx:
|
||||
; if (*ptr_room != zone_nr && *ptr_room <= WALKABLE) break;
|
||||
lda (PTR_ROOM), Y ; Y = 0
|
||||
cmp ZONE_NR
|
||||
beq continue_1b
|
||||
cmp #eACTORTYPES::LAST_FLOOR
|
||||
beq end
|
||||
bpl continue_1b
|
||||
jmp end
|
||||
continue_1b:
|
||||
lda ZONE_NR
|
||||
sta (PTR_ROOM), Y ; Y = 0
|
||||
jmp while_1
|
||||
|
||||
; end label in the middle to be reachable by the branches
|
||||
end:
|
||||
|
||||
; flood fills works on ptr_tile
|
||||
ldx #(ZONE_0 + 1)
|
||||
lda ZONE_NR
|
||||
jsr _Flood_Fill
|
||||
rts
|
||||
|
||||
dy_sup:
|
||||
while_2:
|
||||
; ptr_room += iy
|
||||
patch_iy2:
|
||||
ADD16 PTR_ROOM, #WIDTH_WORLD, #0
|
||||
; d += dx2
|
||||
clc
|
||||
lda DELTA_X_2
|
||||
adc D
|
||||
sta D
|
||||
cmp DELTA_Y
|
||||
bcc d_infequal_dy
|
||||
beq d_infequal_dy
|
||||
; if (d > dy) {
|
||||
; if (*ptr_room != zone_nr && *ptr_room <= WALKABLE) break;
|
||||
lda (PTR_ROOM), Y ; Y = 0
|
||||
cmp ZONE_NR
|
||||
beq continue_2a
|
||||
cmp #eACTORTYPES::LAST_FLOOR
|
||||
beq end
|
||||
bpl continue_2a
|
||||
jmp end
|
||||
continue_2a:
|
||||
; *ptr_room = zone_nr
|
||||
lda ZONE_NR
|
||||
sta (PTR_ROOM), Y ; Y = 0
|
||||
; ptr_room += ix;
|
||||
patch_ix2:
|
||||
ADD16 PTR_ROOM, #1, #0
|
||||
; d -= dy2
|
||||
sec
|
||||
lda D
|
||||
sbc DELTA_Y_2
|
||||
sta D
|
||||
d_infequal_dy:
|
||||
; (*ptr_room != zone_nr && *ptr_room <= WALKABLE)
|
||||
lda (PTR_ROOM), Y ; Y = 0
|
||||
cmp ZONE_NR
|
||||
beq continue_2b
|
||||
cmp #eACTORTYPES::LAST_FLOOR
|
||||
beq end
|
||||
bpl continue_2b
|
||||
jmp end
|
||||
continue_2b:
|
||||
lda ZONE_NR
|
||||
sta (PTR_ROOM), Y ; Y = 0
|
||||
jmp while_2
|
16
src/builder/unite.inc
Normal file
16
src/builder/unite.inc
Normal file
|
@ -0,0 +1,16 @@
|
|||
; Copyright (C) 2020 Christophe Meneboeuf <christophe@xtof.info>
|
||||
;
|
||||
; This program is free software: you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation, either version 3 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
.import Unite_Rooms
|
18
src/common.inc
Normal file
18
src/common.inc
Normal file
|
@ -0,0 +1,18 @@
|
|||
; Copyright (C) 2020 Christophe Meneboeuf <christophe@xtof.info>
|
||||
;
|
||||
; This program is free software: you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation, either version 3 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
.define TRUE 1
|
||||
.define FALSE 0
|
||||
.define UNDEF $FF
|
|
@ -1,8 +1,28 @@
|
|||
; Copyright (C) 2020 Christophe Meneboeuf <christophe@xtof.info>
|
||||
;
|
||||
; This program is free software: you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation, either version 3 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
|
||||
.include "memory.inc"
|
||||
|
||||
; nb of bytes to be displayed in DBG_TRACES[0]
|
||||
.export DBG_TRACE
|
||||
; bytes to be displayed
|
||||
.export DBG_TRACES
|
||||
|
||||
|
||||
.CODE
|
||||
.define STROUT $DB3A ; Applesoft: OUTPUTS AY-POINTED NULL TERMINATED STRING
|
||||
.define LINPTR $ED24 ; Applesoft: Displays the number A(high)X(low) in decimal
|
||||
|
@ -39,3 +59,6 @@ str_space: .byte " ", 0
|
|||
|
||||
.BSS
|
||||
DBG_TRACES: .res 7 ; bytes to be displayed by TRACE
|
||||
|
||||
|
||||
|
||||
|
|
140
src/display.asm
140
src/display.asm
|
@ -14,13 +14,14 @@
|
|||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
.include "world/world.inc"
|
||||
.include "actors/actors.inc"
|
||||
.include "display.inc"
|
||||
.include "world.inc"
|
||||
.include "tiles.inc"
|
||||
.include "math.inc"
|
||||
.include "memory.inc"
|
||||
.include "monitor.inc"
|
||||
.include "common.inc"
|
||||
|
||||
|
||||
; Init the view. To be called before anything else!
|
||||
|
@ -42,9 +43,11 @@
|
|||
; X: TILE_COORD_X
|
||||
; Y: TILE_COORD_Y
|
||||
|
||||
.import compute_maze_addr
|
||||
.import Compute_Maze_Addr
|
||||
.import World
|
||||
.import Player_XY
|
||||
.import ActorTransparent
|
||||
.import ActorTypes
|
||||
|
||||
.import DBG_TRACE
|
||||
.import DBG_TRACES
|
||||
|
@ -97,6 +100,7 @@ loop_view_init:
|
|||
|
||||
rts
|
||||
|
||||
|
||||
; this routine will create the view and populate View_Future
|
||||
; destroys ZERO_4_3, ZERO_4_4, ZERO_5_1, ZERO_5_2, ZERO_5_3
|
||||
; ZERO_5_4, ZERO_5_5, ZERO_5_6, ZERO_7_1, ZERO_7_2
|
||||
|
@ -106,7 +110,7 @@ _build_view:
|
|||
lda #0
|
||||
ldx #(GRID_WIDTH * GRID_HEIGHT - 1)
|
||||
loop_init_view:
|
||||
lda #ACTORS::UNKNOWN
|
||||
lda #eACTORTYPES::UNKNOWN
|
||||
sta View_Future,X
|
||||
dex
|
||||
bne loop_init_view
|
||||
|
@ -115,17 +119,18 @@ _build_view:
|
|||
; 2 - Player
|
||||
.define OFFSET_PLAYER_IN_VIEW PLAYER_X+PLAYER_Y*GRID_WIDTH
|
||||
ldx #(OFFSET_PLAYER_IN_VIEW)
|
||||
lda #ACTORS::PLAYER
|
||||
lda #eACTORTYPES::PLAYER
|
||||
sta View_Future,X
|
||||
|
||||
; 3 - Casting rays
|
||||
.define NB_RAYS 36
|
||||
.define NB_RAYS 68
|
||||
.define NB_ITER ZERO_4_3
|
||||
.define NB_TILES_IN_RAY ZERO_4_4
|
||||
.define NB_TILES_IN_RAY_LEFT ZERO_5_1
|
||||
.define SRC_TILE_IN_WORLD ZERO_5_2 ; 2 bytes
|
||||
.define PTR_RAY ZERO_5_4 ; 2 bytes
|
||||
.define TMP ZERO_5_6
|
||||
.define TMP2 ZERO_7_1
|
||||
|
||||
|
||||
; loading ptr_rays - 1 as it will be incremented
|
||||
|
@ -183,15 +188,21 @@ _build_view:
|
|||
iny
|
||||
sty TMP
|
||||
lda (PTR_RAY),Y ; offset_view
|
||||
tax
|
||||
sta TMP2
|
||||
ldy #0
|
||||
lda (SRC_TILE_IN_WORLD),Y
|
||||
sta View_Future,X
|
||||
lda (SRC_TILE_IN_WORLD), Y
|
||||
; sta View_Future, X ; ptr tile in view future
|
||||
ldy TMP
|
||||
iny
|
||||
; break if non-transparent
|
||||
cmp #ACTORS::NOT_TRANSPARENT
|
||||
bcs end_loop_ray
|
||||
; break if non-transparent
|
||||
tax
|
||||
lda ActorTypes, X
|
||||
ldx TMP2
|
||||
sta View_Future, X
|
||||
tax
|
||||
lda ActorTransparent, X
|
||||
cmp #TRUE
|
||||
bne end_loop_ray
|
||||
; loop if tiles are left in the ray
|
||||
|
||||
ldx NB_TILES_IN_RAY_LEFT
|
||||
|
@ -249,6 +260,7 @@ view_refresh:
|
|||
|
||||
; 3 - build the view to be displayed
|
||||
jsr _build_view
|
||||
;jsr _dbg_build_view
|
||||
|
||||
; 4 - display the tiles viewed
|
||||
.define SAVE_X ZERO_3
|
||||
|
@ -282,7 +294,7 @@ loop_display_tiles_y:
|
|||
|
||||
rts
|
||||
.undef VIEW_WORLD
|
||||
SHIFT_VIEW: .word WIDTH_MAZE*PLAYER_Y + PLAYER_X ; shift to center the view on the player
|
||||
SHIFT_VIEW: .word WIDTH_WORLD*PLAYER_Y + PLAYER_X ; shift to center the view on the player
|
||||
|
||||
.CODE
|
||||
set_view_coords:
|
||||
|
@ -290,7 +302,7 @@ set_view_coords:
|
|||
; 1. Compute offset from the starting address of the maze
|
||||
stx ZERO_2_1
|
||||
sty FAC1
|
||||
lda #WIDTH_MAZE
|
||||
lda #WIDTH_WORLD
|
||||
sta FAC2
|
||||
jsr mul8
|
||||
tay ; high part
|
||||
|
@ -437,7 +449,7 @@ PATCH_8:
|
|||
|
||||
|
||||
|
||||
.DATA
|
||||
.RODATA
|
||||
|
||||
; Adress of the tiles in the HIRES screen
|
||||
; T0 T1 T2
|
||||
|
@ -454,45 +466,77 @@ HGR_GRID:
|
|||
.word $2050, $2054, $2058, $205C, $2060, $2064, $2068, $206C, $2070, $2074
|
||||
.word $2150, $2154, $2158, $215C, $2160, $2164, $2168, $216C, $2170, $2174
|
||||
|
||||
; Nb rays: 36
|
||||
; Nb rays: 68
|
||||
; A ray: length (nb_tiles), offset_from_view_in_world_low, offset_from_view_in_world_high, offset_view
|
||||
Rays:
|
||||
.byte 5, 4, 1, 44, 195, 0, 33, 130, 0, 22, 65, 0, 11, 0, 0, 0
|
||||
.byte 5, 4, 1, 44, 195, 0, 33, 131, 0, 23, 66, 0, 12, 1, 0, 1
|
||||
.byte 5, 4, 1, 44, 196, 0, 34, 131, 0, 23, 67, 0, 13, 2, 0, 2
|
||||
.byte 5, 5, 1, 45, 196, 0, 34, 132, 0, 24, 67, 0, 13, 3, 0, 3
|
||||
.byte 5, 5, 1, 45, 197, 0, 35, 132, 0, 24, 68, 0, 14, 4, 0, 4
|
||||
.byte 10, 68, 1, 54, 4, 1, 44, 3, 1, 43, 195, 0, 33, 194, 0, 32, 130, 0, 22, 129, 0, 21, 65, 0, 11, 64, 0, 10, 0, 0, 0
|
||||
.byte 10, 5, 1, 45, 4, 1, 44, 196, 0, 34, 195, 0, 33, 131, 0, 23, 130, 0, 22, 66, 0, 12, 65, 0, 11, 1, 0, 1, 0, 0, 0
|
||||
.byte 9, 68, 1, 54, 4, 1, 44, 3, 1, 43, 195, 0, 33, 131, 0, 23, 130, 0, 22, 66, 0, 12, 65, 0, 11, 1, 0, 1
|
||||
.byte 9, 5, 1, 45, 4, 1, 44, 196, 0, 34, 195, 0, 33, 131, 0, 23, 67, 0, 13, 66, 0, 12, 2, 0, 2, 1, 0, 1
|
||||
.byte 8, 68, 1, 54, 4, 1, 44, 196, 0, 34, 195, 0, 33, 131, 0, 23, 67, 0, 13, 66, 0, 12, 2, 0, 2
|
||||
.byte 8, 5, 1, 45, 4, 1, 44, 196, 0, 34, 132, 0, 24, 131, 0, 23, 67, 0, 13, 3, 0, 3, 2, 0, 2
|
||||
.byte 7, 5, 1, 45, 4, 1, 44, 196, 0, 34, 132, 0, 24, 131, 0, 23, 67, 0, 13, 3, 0, 3
|
||||
.byte 7, 5, 1, 45, 197, 0, 35, 196, 0, 34, 132, 0, 24, 68, 0, 14, 67, 0, 13, 3, 0, 3
|
||||
.byte 6, 5, 1, 45, 197, 0, 35, 196, 0, 34, 132, 0, 24, 68, 0, 14, 4, 0, 4
|
||||
.byte 6, 5, 1, 45, 197, 0, 35, 133, 0, 25, 132, 0, 24, 68, 0, 14, 4, 0, 4
|
||||
.byte 5, 5, 1, 45, 197, 0, 35, 133, 0, 25, 69, 0, 15, 5, 0, 5
|
||||
.byte 5, 5, 1, 45, 197, 0, 35, 134, 0, 26, 70, 0, 16, 6, 0, 6
|
||||
.byte 5, 5, 1, 45, 198, 0, 36, 134, 0, 26, 71, 0, 17, 7, 0, 7
|
||||
.byte 5, 6, 1, 46, 198, 0, 36, 135, 0, 27, 71, 0, 17, 8, 0, 8
|
||||
.byte 5, 6, 1, 46, 199, 0, 37, 135, 0, 27, 72, 0, 18, 9, 0, 9
|
||||
.byte 4, 6, 1, 46, 199, 0, 37, 136, 0, 28, 73, 0, 19
|
||||
.byte 4, 6, 1, 46, 199, 0, 37, 200, 0, 38, 137, 0, 29
|
||||
.byte 4, 6, 1, 46, 7, 1, 47, 200, 0, 38, 201, 0, 39
|
||||
.byte 4, 70, 1, 56, 7, 1, 47, 8, 1, 48, 9, 1, 49
|
||||
.byte 6, 5, 1, 45, 197, 0, 35, 198, 0, 36, 134, 0, 26, 70, 0, 16, 6, 0, 6
|
||||
.byte 6, 5, 1, 45, 197, 0, 35, 133, 0, 25, 134, 0, 26, 70, 0, 16, 6, 0, 6
|
||||
.byte 7, 5, 1, 45, 6, 1, 46, 198, 0, 36, 134, 0, 26, 135, 0, 27, 71, 0, 17, 7, 0, 7
|
||||
.byte 7, 5, 1, 45, 197, 0, 35, 198, 0, 36, 134, 0, 26, 70, 0, 16, 71, 0, 17, 7, 0, 7
|
||||
.byte 8, 70, 1, 56, 6, 1, 46, 198, 0, 36, 199, 0, 37, 135, 0, 27, 71, 0, 17, 72, 0, 18, 8, 0, 8
|
||||
.byte 8, 5, 1, 45, 6, 1, 46, 198, 0, 36, 134, 0, 26, 135, 0, 27, 71, 0, 17, 7, 0, 7, 8, 0, 8
|
||||
.byte 9, 70, 1, 56, 6, 1, 46, 7, 1, 47, 199, 0, 37, 135, 0, 27, 136, 0, 28, 72, 0, 18, 73, 0, 19, 9, 0, 9
|
||||
.byte 9, 5, 1, 45, 6, 1, 46, 198, 0, 36, 199, 0, 37, 135, 0, 27, 71, 0, 17, 72, 0, 18, 8, 0, 8, 9, 0, 9
|
||||
.byte 8, 70, 1, 56, 6, 1, 46, 7, 1, 47, 199, 0, 37, 200, 0, 38, 136, 0, 28, 137, 0, 29, 73, 0, 19
|
||||
.byte 8, 5, 1, 45, 6, 1, 46, 198, 0, 36, 199, 0, 37, 135, 0, 27, 136, 0, 28, 72, 0, 18, 73, 0, 19
|
||||
.byte 7, 70, 1, 56, 6, 1, 46, 7, 1, 47, 199, 0, 37, 200, 0, 38, 201, 0, 39, 137, 0, 29
|
||||
.byte 7, 5, 1, 45, 6, 1, 46, 198, 0, 36, 199, 0, 37, 200, 0, 38, 136, 0, 28, 137, 0, 29
|
||||
.byte 6, 70, 1, 56, 6, 1, 46, 7, 1, 47, 8, 1, 48, 200, 0, 38, 201, 0, 39
|
||||
.byte 6, 5, 1, 45, 6, 1, 46, 7, 1, 47, 199, 0, 37, 200, 0, 38, 201, 0, 39
|
||||
.byte 5, 70, 1, 56, 71, 1, 57, 7, 1, 47, 8, 1, 48, 9, 1, 49
|
||||
.byte 5, 70, 1, 56, 6, 1, 46, 7, 1, 47, 8, 1, 48, 9, 1, 49
|
||||
.byte 4, 70, 1, 56, 71, 1, 57, 72, 1, 58, 73, 1, 59
|
||||
.byte 4, 70, 1, 56, 135, 1, 67, 136, 1, 68, 137, 1, 69
|
||||
.byte 4, 134, 1, 66, 135, 1, 67, 200, 1, 78, 201, 1, 79
|
||||
.byte 4, 134, 1, 66, 199, 1, 77, 200, 1, 78, 9, 2, 89
|
||||
.byte 4, 134, 1, 66, 199, 1, 77, 8, 2, 88, 73, 2, 99
|
||||
.byte 4, 134, 1, 66, 199, 1, 77, 7, 2, 87, 72, 2, 98
|
||||
.byte 4, 134, 1, 66, 198, 1, 76, 7, 2, 87, 71, 2, 97
|
||||
.byte 4, 133, 1, 65, 198, 1, 76, 6, 2, 86, 70, 2, 96
|
||||
.byte 5, 70, 1, 56, 71, 1, 57, 135, 1, 67, 136, 1, 68, 137, 1, 69
|
||||
.byte 5, 70, 1, 56, 134, 1, 66, 135, 1, 67, 136, 1, 68, 137, 1, 69
|
||||
.byte 6, 70, 1, 56, 134, 1, 66, 135, 1, 67, 136, 1, 68, 200, 1, 78, 201, 1, 79
|
||||
.byte 6, 133, 1, 65, 134, 1, 66, 135, 1, 67, 199, 1, 77, 200, 1, 78, 201, 1, 79
|
||||
.byte 7, 70, 1, 56, 134, 1, 66, 135, 1, 67, 199, 1, 77, 200, 1, 78, 201, 1, 79, 9, 2, 89
|
||||
.byte 7, 133, 1, 65, 134, 1, 66, 198, 1, 76, 199, 1, 77, 200, 1, 78, 8, 2, 88, 9, 2, 89
|
||||
.byte 8, 70, 1, 56, 134, 1, 66, 135, 1, 67, 199, 1, 77, 200, 1, 78, 8, 2, 88, 9, 2, 89, 73, 2, 99
|
||||
.byte 8, 133, 1, 65, 134, 1, 66, 198, 1, 76, 199, 1, 77, 7, 2, 87, 8, 2, 88, 72, 2, 98, 73, 2, 99
|
||||
.byte 7, 70, 1, 56, 134, 1, 66, 135, 1, 67, 199, 1, 77, 7, 2, 87, 8, 2, 88, 72, 2, 98
|
||||
.byte 7, 133, 1, 65, 134, 1, 66, 198, 1, 76, 199, 1, 77, 7, 2, 87, 71, 2, 97, 72, 2, 98
|
||||
.byte 6, 70, 1, 56, 134, 1, 66, 198, 1, 76, 199, 1, 77, 7, 2, 87, 71, 2, 97
|
||||
.byte 6, 133, 1, 65, 134, 1, 66, 198, 1, 76, 6, 2, 86, 7, 2, 87, 71, 2, 97
|
||||
.byte 5, 133, 1, 65, 134, 1, 66, 198, 1, 76, 6, 2, 86, 70, 2, 96
|
||||
.byte 5, 133, 1, 65, 197, 1, 75, 198, 1, 76, 6, 2, 86, 70, 2, 96
|
||||
.byte 4, 133, 1, 65, 197, 1, 75, 5, 2, 85, 69, 2, 95
|
||||
.byte 4, 133, 1, 65, 196, 1, 74, 4, 2, 84, 68, 2, 94
|
||||
.byte 4, 132, 1, 64, 196, 1, 74, 3, 2, 83, 67, 2, 93
|
||||
.byte 4, 132, 1, 64, 195, 1, 73, 3, 2, 83, 66, 2, 92
|
||||
.byte 4, 132, 1, 64, 195, 1, 73, 2, 2, 82, 65, 2, 91
|
||||
.byte 5, 132, 1, 64, 195, 1, 73, 194, 1, 72, 1, 2, 81, 64, 2, 90
|
||||
.byte 5, 132, 1, 64, 131, 1, 63, 194, 1, 72, 193, 1, 71, 0, 2, 80
|
||||
.byte 5, 68, 1, 54, 131, 1, 63, 130, 1, 62, 193, 1, 71, 192, 1, 70
|
||||
.byte 5, 68, 1, 54, 67, 1, 53, 130, 1, 62, 129, 1, 61, 128, 1, 60
|
||||
.byte 5, 133, 1, 65, 132, 1, 64, 196, 1, 74, 4, 2, 84, 68, 2, 94
|
||||
.byte 5, 133, 1, 65, 197, 1, 75, 196, 1, 74, 4, 2, 84, 68, 2, 94
|
||||
.byte 6, 68, 1, 54, 132, 1, 64, 196, 1, 74, 195, 1, 73, 3, 2, 83, 67, 2, 93
|
||||
.byte 6, 133, 1, 65, 132, 1, 64, 196, 1, 74, 4, 2, 84, 3, 2, 83, 67, 2, 93
|
||||
.byte 7, 68, 1, 54, 132, 1, 64, 131, 1, 63, 195, 1, 73, 3, 2, 83, 2, 2, 82, 66, 2, 92
|
||||
.byte 7, 133, 1, 65, 132, 1, 64, 196, 1, 74, 195, 1, 73, 3, 2, 83, 67, 2, 93, 66, 2, 92
|
||||
.byte 8, 68, 1, 54, 132, 1, 64, 131, 1, 63, 195, 1, 73, 194, 1, 72, 2, 2, 82, 1, 2, 81, 65, 2, 91
|
||||
.byte 8, 133, 1, 65, 132, 1, 64, 196, 1, 74, 195, 1, 73, 3, 2, 83, 2, 2, 82, 66, 2, 92, 65, 2, 91
|
||||
.byte 9, 68, 1, 54, 132, 1, 64, 131, 1, 63, 195, 1, 73, 194, 1, 72, 193, 1, 71, 1, 2, 81, 0, 2, 80, 64, 2, 90
|
||||
.byte 9, 133, 1, 65, 132, 1, 64, 196, 1, 74, 195, 1, 73, 194, 1, 72, 2, 2, 82, 1, 2, 81, 65, 2, 91, 64, 2, 90
|
||||
.byte 8, 68, 1, 54, 132, 1, 64, 131, 1, 63, 130, 1, 62, 194, 1, 72, 193, 1, 71, 192, 1, 70, 0, 2, 80
|
||||
.byte 8, 133, 1, 65, 132, 1, 64, 131, 1, 63, 195, 1, 73, 194, 1, 72, 193, 1, 71, 1, 2, 81, 0, 2, 80
|
||||
.byte 7, 68, 1, 54, 67, 1, 53, 131, 1, 63, 130, 1, 62, 129, 1, 61, 193, 1, 71, 192, 1, 70
|
||||
.byte 7, 68, 1, 54, 132, 1, 64, 131, 1, 63, 130, 1, 62, 194, 1, 72, 193, 1, 71, 192, 1, 70
|
||||
.byte 6, 68, 1, 54, 67, 1, 53, 66, 1, 52, 130, 1, 62, 129, 1, 61, 128, 1, 60
|
||||
.byte 6, 68, 1, 54, 67, 1, 53, 131, 1, 63, 130, 1, 62, 129, 1, 61, 128, 1, 60
|
||||
.byte 5, 68, 1, 54, 67, 1, 53, 66, 1, 52, 65, 1, 51, 64, 1, 50
|
||||
.byte 5, 68, 1, 54, 67, 1, 53, 2, 1, 42, 1, 1, 41, 0, 1, 40
|
||||
.byte 5, 68, 1, 54, 3, 1, 43, 2, 1, 42, 193, 0, 31, 192, 0, 30
|
||||
.byte 5, 4, 1, 44, 3, 1, 43, 194, 0, 32, 193, 0, 31, 128, 0, 20
|
||||
.byte 5, 4, 1, 44, 195, 0, 33, 194, 0, 32, 129, 0, 21, 64, 0, 10
|
||||
.byte 6, 68, 1, 54, 67, 1, 53, 66, 1, 52, 2, 1, 42, 1, 1, 41, 0, 1, 40
|
||||
.byte 6, 68, 1, 54, 67, 1, 53, 3, 1, 43, 2, 1, 42, 1, 1, 41, 0, 1, 40
|
||||
.byte 7, 68, 1, 54, 67, 1, 53, 3, 1, 43, 2, 1, 42, 1, 1, 41, 193, 0, 31, 192, 0, 30
|
||||
.byte 7, 68, 1, 54, 4, 1, 44, 3, 1, 43, 2, 1, 42, 194, 0, 32, 193, 0, 31, 192, 0, 30
|
||||
.byte 8, 68, 1, 54, 4, 1, 44, 3, 1, 43, 2, 1, 42, 194, 0, 32, 193, 0, 31, 192, 0, 30, 128, 0, 20
|
||||
.byte 8, 5, 1, 45, 4, 1, 44, 3, 1, 43, 195, 0, 33, 194, 0, 32, 193, 0, 31, 129, 0, 21, 128, 0, 20
|
||||
.byte 9, 68, 1, 54, 4, 1, 44, 3, 1, 43, 195, 0, 33, 194, 0, 32, 193, 0, 31, 129, 0, 21, 128, 0, 20, 64, 0, 10
|
||||
.byte 9, 5, 1, 45, 4, 1, 44, 196, 0, 34, 195, 0, 33, 194, 0, 32, 130, 0, 22, 129, 0, 21, 65, 0, 11, 64, 0, 10
|
||||
|
||||
.BSS
|
||||
|
||||
|
|
341
src/display_map.asm
Normal file
341
src/display_map.asm
Normal file
|
@ -0,0 +1,341 @@
|
|||
|
||||
; Copyright (C) 2019 Christophe Meneboeuf <christophe@xtof.info>
|
||||
;
|
||||
; This program is free software: you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation, either version 3 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
.include "world/world.inc"
|
||||
.include "actors/actors.inc"
|
||||
.include "io/gr.inc"
|
||||
.include "memory.inc"
|
||||
.include "math.inc"
|
||||
.include "monitor.inc"
|
||||
|
||||
; inits display of map
|
||||
.export Display_Map_Init
|
||||
; displays the map and reacts to keyboard input
|
||||
.export Map_Loop
|
||||
; displays the map
|
||||
.export Display_Map_Show
|
||||
|
||||
|
||||
|
||||
.define DBG_DISP_WIDTH 40
|
||||
.define DBG_DISP_HEIGHT 48
|
||||
|
||||
.BSS
|
||||
Map_x: .byte 1
|
||||
Map_y: .byte 1
|
||||
|
||||
.define MAX_Y HEIGHT_WORLD - DBG_DISP_HEIGHT
|
||||
.define MAX_X WIDTH_WORLD - DBG_DISP_WIDTH
|
||||
|
||||
.CODE
|
||||
|
||||
.define KEY_UP $C9
|
||||
.define KEY_LEFT $CA
|
||||
.define KEY_DOWN $CB
|
||||
.define KEY_RIGHT $CC
|
||||
.define TAB $89
|
||||
|
||||
|
||||
; ##################### MAP ##################
|
||||
|
||||
; Buffer to save the 4 bottom line of gr1
|
||||
SAVED_GR_L36: .res 40
|
||||
SAVED_GR_L37: .res 40
|
||||
SAVED_GR_L38: .res 40
|
||||
SAVED_GR_L39: .res 40
|
||||
; The 4 bottom lines of GR1
|
||||
.define SRC_GR1_L36 $650
|
||||
.define SRC_GR1_L37 $6D0
|
||||
.define SRC_GR1_L38 $750
|
||||
.define SRC_GR1_L39 $7D0
|
||||
|
||||
; @brief Displays the map and wait for action: move the view or exit
|
||||
Map_Loop:
|
||||
|
||||
; save the 4 last lines of GR1
|
||||
ldx #39
|
||||
loop_save_gr:
|
||||
lda SRC_GR1_L36, X
|
||||
sta SAVED_GR_L36, X
|
||||
lda SRC_GR1_L37, X
|
||||
sta SAVED_GR_L37, X
|
||||
lda SRC_GR1_L38, X
|
||||
sta SAVED_GR_L38, X
|
||||
lda SRC_GR1_L39, X
|
||||
sta SAVED_GR_L39, X
|
||||
dex
|
||||
bne loop_save_gr
|
||||
lda SRC_GR1_L36, X
|
||||
sta SAVED_GR_L36, X
|
||||
lda SRC_GR1_L37, X
|
||||
sta SAVED_GR_L37, X
|
||||
lda SRC_GR1_L38, X
|
||||
sta SAVED_GR_L38, X
|
||||
lda SRC_GR1_L39, X
|
||||
sta SAVED_GR_L39, X
|
||||
|
||||
disp:
|
||||
; display map
|
||||
;sta $C051 ; full screen
|
||||
sta $C054 ; page 1
|
||||
sta $C056 ; lores
|
||||
sta $C050 ; gfx
|
||||
sta $C052 ; mixed mode off
|
||||
|
||||
ldx Map_x
|
||||
ldy Map_y
|
||||
; capping X and Y
|
||||
min_x:
|
||||
cpx #$FF
|
||||
bne max_x
|
||||
ldx #0
|
||||
bvc min_y
|
||||
max_x:
|
||||
cpx #MAX_X
|
||||
bcc min_y
|
||||
ldx #MAX_X
|
||||
min_y:
|
||||
cpy #$FF
|
||||
bne max_y
|
||||
ldy #0
|
||||
bvc disp_map
|
||||
max_y:
|
||||
cpy #MAX_Y
|
||||
bcc disp_map
|
||||
ldy #MAX_Y
|
||||
disp_map:
|
||||
stx Map_x
|
||||
sty Map_y
|
||||
jsr Display_Map_Show
|
||||
|
||||
; waiting for a key to be pressed
|
||||
kbd_loop:
|
||||
lda KEYBD
|
||||
bpl kbd_loop ; bit #8 is set when a character is present (thus A < 0)
|
||||
sta KEYBD_STROBE
|
||||
|
||||
cmp #KEY_UP
|
||||
beq move_up
|
||||
cmp #KEY_RIGHT
|
||||
beq move_right
|
||||
cmp #KEY_DOWN
|
||||
beq move_down
|
||||
cmp #KEY_LEFT
|
||||
beq move_left
|
||||
cmp #TAB
|
||||
beq quit
|
||||
jmp kbd_loop
|
||||
|
||||
move_up:
|
||||
dec Map_y
|
||||
jmp disp
|
||||
move_right:
|
||||
inc Map_x
|
||||
jmp disp
|
||||
move_down:
|
||||
inc Map_y
|
||||
jmp disp
|
||||
move_left:
|
||||
dec Map_x
|
||||
jmp disp
|
||||
quit:
|
||||
; restore player's view
|
||||
;sta $C054 ; page 1
|
||||
sta $C057 ; hires
|
||||
sta $C053 ; mixed mode on
|
||||
|
||||
; restore the 4 last lines of GR1
|
||||
ldx #39
|
||||
loop_restore_gr:
|
||||
lda SAVED_GR_L36, X
|
||||
sta SRC_GR1_L36, X
|
||||
lda SAVED_GR_L37, X
|
||||
sta SRC_GR1_L37, X
|
||||
lda SAVED_GR_L38, X
|
||||
sta SRC_GR1_L38, X
|
||||
lda SAVED_GR_L39, X
|
||||
sta SRC_GR1_L39, X
|
||||
dex
|
||||
bne loop_restore_gr
|
||||
lda SAVED_GR_L36, X
|
||||
sta SRC_GR1_L36, X
|
||||
lda SAVED_GR_L37, X
|
||||
sta SRC_GR1_L37, X
|
||||
lda SAVED_GR_L38, X
|
||||
sta SRC_GR1_L38, X
|
||||
lda SAVED_GR_L39, X
|
||||
sta SRC_GR1_L39, X
|
||||
|
||||
rts
|
||||
|
||||
|
||||
|
||||
Display_Map_Init:
|
||||
; Init coords to view map
|
||||
lda #0
|
||||
sta Map_x
|
||||
sta Map_y
|
||||
|
||||
jsr Clear_Gr1
|
||||
|
||||
; display GR1
|
||||
sta $C051 ; full screen
|
||||
sta $C054 ; page 1
|
||||
sta $C056 ; lores
|
||||
sta $C050 ; gfx
|
||||
sta $C052 ; mixed mode off
|
||||
|
||||
rts
|
||||
|
||||
.import World
|
||||
.define SRC_LINE_UP ZERO_7_1
|
||||
.define SRC_LINE_DOWN ZERO_8_1
|
||||
.define SRC_OFFSET ZERO_5_5
|
||||
.define DST_GR1 ZERO_5_5
|
||||
.define CPT_FILL ZERO_5_4
|
||||
.define TMP ZERO_9_10
|
||||
|
||||
Addr_GR1: ; 3 address blocks to fill GR1 (address -1), stored in reversed endianess.
|
||||
.word $4F04, $2704, $FF03
|
||||
|
||||
|
||||
; @brief Displays the map in GR1 screen
|
||||
; @param X top-left x coordinate
|
||||
; @param Y top-left y coordinate
|
||||
; X, Y capped by WITH_WOLRD - GR_WIDTH, HEIGHT_WORLD - GR_HEIGHT
|
||||
; The code in "copy_8x2_lines" copies 16 lines from World
|
||||
; It is called 3 times to fill the entire screen. Each line
|
||||
; is two tile heigh.
|
||||
Display_Map_Show:
|
||||
|
||||
; display GR1
|
||||
sta $C051 ; full screen
|
||||
sta $C054 ; page 1
|
||||
sta $C056 ; lores
|
||||
sta $C050 ; gfx
|
||||
sta $C052 ; mixed mode off
|
||||
|
||||
ld_src:
|
||||
; compute offset
|
||||
stx TMP
|
||||
sty FAC1
|
||||
lda #WIDTH_WORLD
|
||||
sta FAC2
|
||||
jsr mul8
|
||||
sta SRC_OFFSET+1
|
||||
txa
|
||||
clc
|
||||
adc TMP
|
||||
sta SRC_OFFSET
|
||||
lda SRC_OFFSET+1
|
||||
adc #0
|
||||
sta SRC_OFFSET+1
|
||||
|
||||
; source address in World
|
||||
lda #<(World-1)
|
||||
clc
|
||||
adc SRC_OFFSET
|
||||
sta SRC_LINE_UP
|
||||
lda #>(World-1)
|
||||
adc SRC_OFFSET+1
|
||||
sta SRC_LINE_UP+1
|
||||
lda SRC_LINE_UP
|
||||
clc
|
||||
adc #WIDTH_WORLD
|
||||
sta SRC_LINE_DOWN
|
||||
lda SRC_LINE_UP+1
|
||||
adc #0
|
||||
sta SRC_LINE_DOWN+1
|
||||
|
||||
ldx #5
|
||||
stx CPT_FILL
|
||||
|
||||
; destination adress in GR1.
|
||||
lda Addr_GR1,X
|
||||
sta DST_GR1
|
||||
dex
|
||||
lda Addr_GR1,X
|
||||
sta DST_GR1+1
|
||||
dex
|
||||
stx CPT_FILL
|
||||
|
||||
fill:
|
||||
ldx #8
|
||||
copy_8x2_lines: ; call 3 times to fill the screen
|
||||
ldy #DBG_DISP_WIDTH
|
||||
copy_2_lines:
|
||||
lda (SRC_LINE_DOWN),Y
|
||||
cmp #eACTORTYPES::FIRST_DYNAMIC
|
||||
bcc keep_color_1
|
||||
lda #$F ; white
|
||||
keep_color_1:
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
sta TMP
|
||||
lda (SRC_LINE_UP),Y
|
||||
cmp #eACTORTYPES::FIRST_DYNAMIC
|
||||
bcc keep_color_2
|
||||
lda #$F ; white
|
||||
keep_color_2:
|
||||
and #$F
|
||||
ora TMP
|
||||
sta (DST_GR1), Y
|
||||
dey
|
||||
bne copy_2_lines
|
||||
|
||||
; update source
|
||||
lda SRC_LINE_UP
|
||||
clc
|
||||
adc #(2*WIDTH_WORLD)
|
||||
sta SRC_LINE_UP
|
||||
lda SRC_LINE_UP+1
|
||||
adc #0
|
||||
sta SRC_LINE_UP+1
|
||||
lda SRC_LINE_DOWN
|
||||
clc
|
||||
adc #(2*WIDTH_WORLD)
|
||||
sta SRC_LINE_DOWN
|
||||
lda SRC_LINE_DOWN+1
|
||||
adc #0
|
||||
sta SRC_LINE_DOWN+1
|
||||
; update destination
|
||||
clc
|
||||
lda DST_GR1
|
||||
adc #$80
|
||||
sta DST_GR1
|
||||
lda DST_GR1+1
|
||||
adc #0
|
||||
sta DST_GR1+1
|
||||
dex
|
||||
bne copy_8x2_lines
|
||||
|
||||
; destination adress in GR1.
|
||||
ldx CPT_FILL
|
||||
lda Addr_GR1,X
|
||||
sta DST_GR1
|
||||
dex
|
||||
lda Addr_GR1,X
|
||||
sta DST_GR1+1
|
||||
dex
|
||||
stx CPT_FILL
|
||||
|
||||
cpx #$FD
|
||||
bne fill
|
||||
|
||||
rts
|
5
src/display_map.inc
Normal file
5
src/display_map.inc
Normal file
|
@ -0,0 +1,5 @@
|
|||
; inits display of map
|
||||
.import Display_Map_Init
|
||||
|
||||
; @brief Displays the map in GR1 screen
|
||||
.import Map_Loop
|
|
@ -1,24 +1,29 @@
|
|||
# Configuration for assembler programs which don't need a special setup
|
||||
|
||||
# Configuration:
|
||||
# APPLESOFT required
|
||||
# HGR1 & HGR2 memory reserved
|
||||
# CODE2, RODATA and DATA segment are loaded contiguously in the main memory
|
||||
# but will be run from MAIN2 memory. The program has to do the relocation.
|
||||
FEATURES {
|
||||
STARTADDRESS: default = $0803;
|
||||
}
|
||||
SYMBOLS {
|
||||
__EXEHDR__: type = import;
|
||||
__FILETYPE__: type = weak, value = $0006; # ProDOS file type
|
||||
}
|
||||
MEMORY {
|
||||
ZP: file = "", start = $0000, size = $00FF;
|
||||
HEADER: file = %O, start = %S - 4, size = $0004;
|
||||
MAIN: file = %O, define = yes, start = %S, size = $C000 - %S;
|
||||
BSS: file = "", start = __MAIN_LAST__, size = $C000 - __MAIN_LAST__;
|
||||
ZP: file = "", start = $0000, size = $00FF;
|
||||
HEADER: file = %O, start = %S - $3A, size = $003A;
|
||||
HGR: file = "", define = yes, start = $2000, size = $4000;
|
||||
MAIN2: file = "", define = yes, start = $6000, size = $3000;
|
||||
BSSMEM: file = "", define = yes, start = __MAIN2_LAST__, size = $BF00 - __BSSMEM_START__;
|
||||
MAIN: file = %O, define = yes, start = %S, size = __BSSMEM_START__ - %S - __HGR_SIZE__;
|
||||
}
|
||||
SEGMENTS {
|
||||
ZEROPAGE: load = ZP, type = zp, optional = yes;
|
||||
EXEHDR: load = HEADER, type = ro;
|
||||
CODE: load = MAIN, type = rw;
|
||||
RODATA: load = MAIN, type = ro, optional = yes;
|
||||
DATA: load = MAIN, type = rw, optional = yes, align = $100;
|
||||
BSS: load = BSS, type = bss, optional = yes, define = yes, align = $100;
|
||||
# user defined segments
|
||||
TILES: load = MAIN, type = ro, align = $100;
|
||||
ZEROPAGE: load = ZP, type = zp, optional = no;
|
||||
EXEHDR: load = HEADER, type = ro;
|
||||
CODE: load = MAIN, type = rw, define = yes;
|
||||
CODE2: load = MAIN, run = MAIN2, type = rw, define = yes;
|
||||
RODATA: load = MAIN, run = MAIN2, type = ro, define = yes, align = $100;
|
||||
DATA: load = MAIN, run = MAIN2, type = rw, define = yes, align = $100;
|
||||
BSS: load = BSSMEM, type = bss, define = yes, align = $100;
|
||||
}
|
||||
|
|
|
@ -13,12 +13,15 @@
|
|||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
|
||||
.include "world.inc"
|
||||
.include "actors/actors.inc"
|
||||
.include "world/level.inc"
|
||||
.include "world/world.inc"
|
||||
.include "display.inc"
|
||||
.include "display_map.inc"
|
||||
.include "memory.inc"
|
||||
.include "monitor.inc"
|
||||
.include "common.inc"
|
||||
|
||||
|
||||
.export game_loop
|
||||
|
||||
|
@ -26,70 +29,150 @@
|
|||
.import set_view_coords
|
||||
.import view_refresh
|
||||
; player
|
||||
.import player_move
|
||||
.import player_move_inx
|
||||
.import player_move_iny
|
||||
.import player_move_dex
|
||||
.import player_move_dey
|
||||
.import Player_XY
|
||||
.import ActorPositions
|
||||
; world
|
||||
.import world_set_player
|
||||
; actors
|
||||
.import ActorPositions
|
||||
|
||||
; ************
|
||||
.include "builder/builder.inc"
|
||||
.import world_init
|
||||
.import player_init
|
||||
.import view_init
|
||||
.import Actors_Init
|
||||
; ************
|
||||
|
||||
|
||||
.define KEY_UP $C9
|
||||
.define KEY_LEFT $CA
|
||||
.define KEY_DOWN $CB
|
||||
.define KEY_RIGHT $CC
|
||||
.define KEY_UP_UPP $C9 ; 'I'
|
||||
.define KEY_UP_LOW $E9 ; 'i'
|
||||
.define KEY_LEFT_UPP $CA ; 'J'
|
||||
.define KEY_LEFT_LOW $EA ; 'j'
|
||||
.define KEY_DOWN_UPP $CB ; 'K'
|
||||
.define KEY_DOWN_LOW $EB ; 'k'
|
||||
.define KEY_RIGHT_UPP $CC ; 'L'
|
||||
.define KEY_RIGHT_LOW $EC ; 'l'
|
||||
.define TAB $89 ; '\t'
|
||||
|
||||
.define Player_XY ActorPositions + eACTORTYPES::PLAYER
|
||||
|
||||
|
||||
.CODE
|
||||
|
||||
nop ; Main can jump to a wrong game_loop's addr without this nop :/
|
||||
|
||||
; ########### GAME ##########
|
||||
|
||||
; @brief Main game loop
|
||||
game_loop:
|
||||
|
||||
ldx Player_XY
|
||||
ldy Player_XY+1
|
||||
jsr levels_init
|
||||
jsr Actors_Init
|
||||
|
||||
jsr world_set_player
|
||||
jsr set_view_coords
|
||||
jsr view_refresh
|
||||
level_loop:
|
||||
jsr level_enter ; Uses NextLevel as level number
|
||||
|
||||
; waiting for a key to be pressed
|
||||
kbd_loop:
|
||||
lda KEYBD
|
||||
bpl kbd_loop ; bit #8 is set when a character is present (thus A < 0)
|
||||
sta KEYBD_STROBE
|
||||
; *****************
|
||||
jsr Display_Map_Init
|
||||
|
||||
jsr key_action
|
||||
bvc kbd_loop
|
||||
ldx Player_XY
|
||||
ldy Player_XY + 1
|
||||
jsr world_init
|
||||
|
||||
jsr view_init
|
||||
; *****************
|
||||
|
||||
rts
|
||||
ldx Player_XY
|
||||
ldy Player_XY+1
|
||||
|
||||
jsr world_set_player
|
||||
jsr set_view_coords
|
||||
jsr view_refresh
|
||||
|
||||
; waiting for a key to be pressed
|
||||
kbd_loop:
|
||||
lda KEYBD
|
||||
bpl kbd_loop ; bit #8 is set when a character is present (thus A < 0)
|
||||
sta KEYBD_STROBE
|
||||
|
||||
jsr key_action
|
||||
|
||||
lda ExitLevel
|
||||
cmp #TRUE
|
||||
bne kbd_loop
|
||||
|
||||
jsr level_exit
|
||||
|
||||
jmp level_loop
|
||||
|
||||
rts
|
||||
|
||||
; action on key pressed
|
||||
key_action:
|
||||
cmp #KEY_UP
|
||||
cmp #KEY_UP_UPP
|
||||
beq move_up
|
||||
cmp #KEY_RIGHT
|
||||
cmp #KEY_UP_LOW
|
||||
beq move_up
|
||||
|
||||
cmp #KEY_RIGHT_UPP
|
||||
beq move_right
|
||||
cmp #KEY_DOWN
|
||||
cmp #KEY_RIGHT_LOW
|
||||
beq move_right
|
||||
|
||||
cmp #KEY_DOWN_UPP
|
||||
beq move_down
|
||||
cmp #KEY_LEFT
|
||||
cmp #KEY_DOWN_LOW
|
||||
beq move_down
|
||||
|
||||
cmp #KEY_LEFT_UPP
|
||||
beq move_left
|
||||
cmp #KEY_LEFT_LOW
|
||||
beq move_left
|
||||
|
||||
cmp #TAB
|
||||
beq display_map
|
||||
|
||||
rts
|
||||
|
||||
move_up:
|
||||
jsr player_move_dey
|
||||
bvc end_action_move
|
||||
ldx Player_XY
|
||||
ldy Player_XY+1
|
||||
dey
|
||||
jsr player_move
|
||||
jmp end_action_move
|
||||
move_right:
|
||||
jsr player_move_inx
|
||||
bvc end_action_move
|
||||
ldx Player_XY
|
||||
ldy Player_XY+1
|
||||
inx
|
||||
jsr player_move
|
||||
jmp end_action_move
|
||||
move_down:
|
||||
jsr player_move_iny
|
||||
bvc end_action_move
|
||||
ldx Player_XY
|
||||
ldy Player_XY+1
|
||||
iny
|
||||
jsr player_move
|
||||
jmp end_action_move
|
||||
move_left:
|
||||
jsr player_move_dex
|
||||
bvc end_action_move
|
||||
ldx Player_XY
|
||||
ldy Player_XY+1
|
||||
dex
|
||||
jsr player_move
|
||||
jmp end_action_move
|
||||
|
||||
end_action_move: ; update player/view coordinates and refresh the display
|
||||
jsr world_set_player
|
||||
jsr set_view_coords ; coords of the player in XY after player_move_*
|
||||
jsr view_refresh
|
||||
jsr view_refresh
|
||||
rts
|
||||
|
||||
|
||||
|
||||
display_map:
|
||||
jsr Map_Loop
|
||||
rts
|
||||
|
||||
|
|
481
src/io/files.asm
Normal file
481
src/io/files.asm
Normal file
|
@ -0,0 +1,481 @@
|
|||
; Copyright (C) 2021 Christophe Meneboeuf <christophe@xtof.info>
|
||||
;
|
||||
; This program is free software: you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation, either version 3 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
; TODO a lot of code space can be spared by factorizing ReadState and Write state. Almos the same code
|
||||
|
||||
|
||||
.include "../actors/actors.inc"
|
||||
.include "../world/level.inc"
|
||||
.include "../world/world.inc"
|
||||
.include "../common.inc"
|
||||
.include "../memory.inc"
|
||||
.include "../math.inc"
|
||||
|
||||
.import World
|
||||
.import ActorsInLevel
|
||||
.import LevelIsBuilt
|
||||
.import PlayerTile
|
||||
.import Tile_player_standing_actor
|
||||
|
||||
; data
|
||||
; TODO : should remain private!!
|
||||
.export Str_FileLevelConfs
|
||||
.export Str_FileLevelsActors
|
||||
.export Param_FileOpen
|
||||
.export Param_FileOffset
|
||||
.export Param_FilesReadWrite
|
||||
.export File_Buffer
|
||||
|
||||
|
||||
; functions
|
||||
.export ReadFile
|
||||
.export LoadState
|
||||
.export SaveState
|
||||
.export ResetIsBuilt
|
||||
.export LoadCurrentLevel
|
||||
|
||||
.define TO_PATCH 0
|
||||
|
||||
; reserve 1024 bytes for MLI file operations in the upper part of HGR2
|
||||
File_Buffer := $5C00
|
||||
|
||||
|
||||
.RODATA
|
||||
|
||||
Str_FileLevelConfs:
|
||||
.byte $19, "/PRODOS.2.4.2/LEVELS.CONF" ; Pascal string
|
||||
Str_FileLevelsActors:
|
||||
.byte $19, "/PRODOS.2.4.2/LEVELS.ACTS" ; Pascal string
|
||||
Str_FileStates:
|
||||
.byte $14, "/PRODOS.2.4.2/STATES" ; Pascal string
|
||||
|
||||
.BSS
|
||||
|
||||
Lvl_Nr: .res 1
|
||||
|
||||
.define MIN_READ_SIZE 256
|
||||
ReadWriteBuffer: .res MIN_READ_SIZE
|
||||
|
||||
.DATA
|
||||
|
||||
Param_FileOpen:
|
||||
.byte $3 ; in - nb params
|
||||
.addr TO_PATCH ; in - char* filepath
|
||||
.addr File_Buffer ; in - char* workbuffer
|
||||
Handle_File:
|
||||
.byte $0 ; out - handle on the file
|
||||
|
||||
Param_FileOffset:
|
||||
.byte $2 ; in - nb params
|
||||
.byte TO_PATCH ; in - handle on the file
|
||||
.byte TO_PATCH, TO_PATCH, 0 ; in - Offset
|
||||
|
||||
Param_FilesReadWrite:
|
||||
.byte $4 ; in - nb params
|
||||
.byte TO_PATCH ; in - handle on the file
|
||||
.addr TO_PATCH ; in - out buffer
|
||||
.word TO_PATCH ; in - max nb bytes to WRITE/READ
|
||||
.word $0000 ; out - nb bytes write/read
|
||||
|
||||
Param_FileClose:
|
||||
.byte $1 ; in - nb params
|
||||
.byte TO_PATCH ; in - handle on the file
|
||||
|
||||
|
||||
|
||||
.CODE
|
||||
|
||||
; TODO handle errors
|
||||
ReadFile:
|
||||
|
||||
; Open the file
|
||||
jsr $BF00 ; call MLI
|
||||
.byte $C8 ; Open
|
||||
.addr Param_FileOpen
|
||||
|
||||
; Set read position
|
||||
lda Handle_File
|
||||
sta Param_FileOffset+1
|
||||
jsr $BF00 ; call MLI
|
||||
.byte $CE ; Set Mark
|
||||
.addr Param_FileOffset
|
||||
|
||||
; Read the file
|
||||
lda Handle_File
|
||||
sta Param_FilesReadWrite+1
|
||||
jsr $BF00 ; call MLI
|
||||
.byte $CA ; read
|
||||
.addr Param_FilesReadWrite
|
||||
|
||||
; Close the file
|
||||
lda Handle_File
|
||||
sta Param_FileClose+1
|
||||
jsr $BF00 ; call MLI
|
||||
.byte $CC ; Close
|
||||
.addr Param_FileClose
|
||||
rts
|
||||
|
||||
|
||||
|
||||
.define READ_DST ZERO_2_4 ; 2 bytes
|
||||
|
||||
; @brief Offset in A:X (little endian)
|
||||
; HandleFile must have been set by opening the file
|
||||
_SetOffset:
|
||||
|
||||
sta Param_FileOffset+2
|
||||
stx Param_FileOffset+3
|
||||
lda Handle_File
|
||||
sta Param_FileOffset+1
|
||||
jsr $BF00 ; call MLI
|
||||
.byte $CE ; Set Mark
|
||||
.addr Param_FileOffset
|
||||
|
||||
rts
|
||||
|
||||
; @brief Size in in A:X (little endian)
|
||||
; Destination ptr in READ_DST: cannot be locate in ZERO PAGE!!!
|
||||
; HandleFile must have been set by opening the file
|
||||
_Read:
|
||||
|
||||
; Read the file
|
||||
sta Param_FilesReadWrite+4
|
||||
stx Param_FilesReadWrite+5
|
||||
lda Handle_File
|
||||
sta Param_FilesReadWrite+1
|
||||
lda READ_DST
|
||||
sta Param_FilesReadWrite+2
|
||||
lda READ_DST+1
|
||||
sta Param_FilesReadWrite+3
|
||||
jsr $BF00 ; call MLI
|
||||
.byte $CA ; read
|
||||
.addr Param_FilesReadWrite
|
||||
|
||||
rts
|
||||
|
||||
; @param LevelNr in A
|
||||
; @return isBuilt in A
|
||||
; modifies ZERO_2_3, ZERO_2_4, ZERO_2_5
|
||||
.define LVLS_HEADER_SIZE 4
|
||||
.define LVL_HEADER_SIZE 3
|
||||
.define OFFSET Param_FileOffset+2
|
||||
; compute offset and sets file position
|
||||
_FindLevelLayout:
|
||||
|
||||
; Compute the level state offset in file
|
||||
ldy #(LVLS_HEADER_SIZE + 2 + LVL_HEADER_SIZE) ; +2: current lvl + nb lvls
|
||||
sty OFFSET
|
||||
lda #0
|
||||
sta OFFSET+1
|
||||
lda Lvl_Nr
|
||||
tax
|
||||
cpx #0
|
||||
beq end_acc_offset_lvl
|
||||
acc_offset_lvl:
|
||||
ADD16 OFFSET, #<(HEIGHT_WORLD * WIDTH_WORLD), #>(HEIGHT_WORLD * WIDTH_WORLD)
|
||||
ADD16 OFFSET, #(LVL_HEADER_SIZE + 2), #0 ; +2: visited + tile
|
||||
dex
|
||||
bne acc_offset_lvl
|
||||
end_acc_offset_lvl:
|
||||
|
||||
; Set read position
|
||||
lda OFFSET
|
||||
ldx OFFSET+1
|
||||
jsr _SetOffset
|
||||
|
||||
rts
|
||||
|
||||
|
||||
.define ACTSS_HEADER_SIZE 4;
|
||||
.define ACT_HEADER_SIZE 3;
|
||||
_FindLevelActors:
|
||||
|
||||
; Compute offset
|
||||
lda #(LVLS_HEADER_SIZE + 2)
|
||||
sta OFFSET
|
||||
lda #0
|
||||
sta OFFSET+1
|
||||
ldx NbLevels
|
||||
acc_offset_lvls:
|
||||
ADD16 OFFSET, #<(HEIGHT_WORLD * WIDTH_WORLD), #>(HEIGHT_WORLD * WIDTH_WORLD)
|
||||
ADD16 OFFSET, #(LVL_HEADER_SIZE + 2), #0 ; +2: visited + tile
|
||||
dex
|
||||
bne acc_offset_lvls
|
||||
ADD16 OFFSET, #(ACTSS_HEADER_SIZE + ACT_HEADER_SIZE), #0
|
||||
|
||||
ldx Lvl_Nr
|
||||
cpx #0
|
||||
beq end_acc_offset_actors
|
||||
acc_offset_actors:
|
||||
ADD16 OFFSET, #<(ACT_HEADER_SIZE + SIZEOF_ACTORS_T), #>(ACT_HEADER_SIZE + SIZEOF_ACTORS_T)
|
||||
dex
|
||||
bne acc_offset_actors
|
||||
end_acc_offset_actors:
|
||||
|
||||
; Set read position
|
||||
lda OFFSET
|
||||
ldx OFFSET+1
|
||||
jsr _SetOffset
|
||||
|
||||
rts
|
||||
|
||||
; @param Level NR in A
|
||||
LoadState:
|
||||
|
||||
sta Lvl_Nr
|
||||
|
||||
; Open the file
|
||||
lda #<Str_FileStates
|
||||
sta Param_FileOpen+1
|
||||
lda #>Str_FileStates
|
||||
sta Param_FileOpen+2
|
||||
jsr $BF00 ; call MLI
|
||||
.byte $C8 ; Open
|
||||
.addr Param_FileOpen
|
||||
|
||||
; save the new current level
|
||||
lda #(LVLS_HEADER_SIZE)
|
||||
ldx #0
|
||||
jsr _SetOffset ; current lvl
|
||||
lda #<Lvl_Nr
|
||||
sta READ_DST
|
||||
lda #>Lvl_Nr
|
||||
sta READ_DST+1
|
||||
lda #1
|
||||
ldx #0
|
||||
jsr _Write
|
||||
|
||||
lda Lvl_Nr
|
||||
jsr _FindLevelLayout ; compute offset and sets file read position
|
||||
|
||||
lda #<ReadWriteBuffer
|
||||
sta READ_DST
|
||||
lda #>ReadWriteBuffer
|
||||
sta READ_DST+1
|
||||
lda #<MIN_READ_SIZE
|
||||
ldx #>MIN_READ_SIZE
|
||||
jsr _Read
|
||||
lda ReadWriteBuffer
|
||||
sta LevelIsBuilt
|
||||
lda ReadWriteBuffer+1
|
||||
sta Tile_player_standing_actor
|
||||
|
||||
lda LevelIsBuilt
|
||||
cmp #FALSE
|
||||
beq LoadState_end
|
||||
|
||||
; Read the level's layout
|
||||
; Set read position
|
||||
ADD16 OFFSET, #2, #0 ; offset past "visited" & "tile"
|
||||
lda OFFSET
|
||||
ldx OFFSET+1
|
||||
jsr _SetOffset
|
||||
; Read the file
|
||||
lda #<World
|
||||
sta READ_DST
|
||||
lda #>World
|
||||
sta READ_DST+1
|
||||
lda #<(HEIGHT_WORLD * WIDTH_WORLD)
|
||||
ldx #>(HEIGHT_WORLD * WIDTH_WORLD)
|
||||
jsr _Read
|
||||
|
||||
; Read level actors state
|
||||
jsr _FindLevelActors ; compute offset and sets file read position
|
||||
; Read the file
|
||||
lda #<ActorsInLevel
|
||||
sta READ_DST
|
||||
lda #>ActorsInLevel
|
||||
sta READ_DST+1
|
||||
lda #<(SIZEOF_ACTORS_T)
|
||||
ldx #>(SIZEOF_ACTORS_T)
|
||||
jsr _Read
|
||||
|
||||
LoadState_end:
|
||||
|
||||
; Close the file
|
||||
lda Handle_File
|
||||
sta Param_FileClose+1
|
||||
jsr $BF00 ; call MLI
|
||||
.byte $CC ; Close
|
||||
.addr Param_FileClose
|
||||
|
||||
rts
|
||||
|
||||
|
||||
|
||||
.define WRITE_DST ZERO_2_4 ; 2 bytes
|
||||
; @brief Size in in A:X (little endian)
|
||||
; Destination ptr in WRITE_DST: cannot be locate in ZERO PAGE!!!
|
||||
; HandleFile must have been set by opening the file
|
||||
_Write:
|
||||
|
||||
; Wr the file
|
||||
sta Param_FilesReadWrite+4
|
||||
stx Param_FilesReadWrite+5
|
||||
lda Handle_File
|
||||
sta Param_FilesReadWrite+1
|
||||
lda WRITE_DST
|
||||
sta Param_FilesReadWrite+2
|
||||
lda WRITE_DST+1
|
||||
sta Param_FilesReadWrite+3
|
||||
jsr $BF00 ; call MLI
|
||||
.byte $CB ; write
|
||||
.addr Param_FilesReadWrite
|
||||
|
||||
rts
|
||||
|
||||
|
||||
; @param Level NR in A
|
||||
SaveState:
|
||||
|
||||
sta Lvl_Nr
|
||||
|
||||
; Open the file
|
||||
lda #<Str_FileStates
|
||||
sta Param_FileOpen+1
|
||||
lda #>Str_FileStates
|
||||
sta Param_FileOpen+2
|
||||
jsr $BF00 ; call MLI
|
||||
.byte $C8 ; Open
|
||||
.addr Param_FileOpen
|
||||
|
||||
lda Lvl_Nr
|
||||
jsr _FindLevelLayout ; compute offset and sets file write position
|
||||
|
||||
; Write the file
|
||||
lda #TRUE
|
||||
sta ReadWriteBuffer
|
||||
lda Tile_player_standing_actor
|
||||
sta ReadWriteBuffer+1
|
||||
lda #<ReadWriteBuffer
|
||||
sta WRITE_DST
|
||||
lda #>ReadWriteBuffer
|
||||
sta WRITE_DST+1
|
||||
lda #<MIN_READ_SIZE
|
||||
ldx #>MIN_READ_SIZE
|
||||
jsr _Write
|
||||
|
||||
; Write the level's layout
|
||||
; Set write position
|
||||
ADD16 OFFSET, #2, #0 ; offset past "visited" & "tile"
|
||||
lda OFFSET
|
||||
ldx OFFSET+1
|
||||
jsr _SetOffset
|
||||
; Write the file
|
||||
lda #<World
|
||||
sta WRITE_DST
|
||||
lda #>World
|
||||
sta WRITE_DST+1
|
||||
lda #<(HEIGHT_WORLD * WIDTH_WORLD)
|
||||
ldx #>(HEIGHT_WORLD * WIDTH_WORLD)
|
||||
jsr _Write
|
||||
|
||||
; Write level actors state
|
||||
jsr _FindLevelActors ; compute offset and sets file write position
|
||||
; Write the file
|
||||
lda #<ActorsInLevel
|
||||
sta WRITE_DST
|
||||
lda #>ActorsInLevel
|
||||
sta WRITE_DST+1
|
||||
lda #<(SIZEOF_ACTORS_T)
|
||||
ldx #>(SIZEOF_ACTORS_T)
|
||||
jsr _Write
|
||||
|
||||
; Close the file
|
||||
lda Handle_File
|
||||
sta Param_FileClose+1
|
||||
jsr $BF00 ; call MLI
|
||||
.byte $CC ; Close
|
||||
.addr Param_FileClose
|
||||
|
||||
rts
|
||||
|
||||
; @param LevelNr in A
|
||||
ResetIsBuilt:
|
||||
|
||||
sta Lvl_Nr
|
||||
|
||||
; Open the file
|
||||
lda #<Str_FileStates
|
||||
sta Param_FileOpen+1
|
||||
lda #>Str_FileStates
|
||||
sta Param_FileOpen+2
|
||||
jsr $BF00 ; call MLI
|
||||
.byte $C8 ; Open
|
||||
.addr Param_FileOpen
|
||||
|
||||
for_each_lvl:
|
||||
dec Lvl_Nr
|
||||
jsr _FindLevelLayout ; compute offset and sets file write position
|
||||
inc Lvl_Nr
|
||||
|
||||
lda #FALSE
|
||||
sta ReadWriteBuffer
|
||||
lda #<ReadWriteBuffer
|
||||
sta WRITE_DST
|
||||
lda #>ReadWriteBuffer
|
||||
sta WRITE_DST+1
|
||||
lda #<MIN_READ_SIZE
|
||||
ldx #>MIN_READ_SIZE
|
||||
jsr _Write
|
||||
|
||||
dec Lvl_Nr
|
||||
bne for_each_lvl
|
||||
|
||||
; Close the file
|
||||
lda Handle_File
|
||||
sta Param_FileClose+1
|
||||
jsr $BF00 ; call MLI
|
||||
.byte $CC ; Close
|
||||
.addr Param_FileClose
|
||||
|
||||
rts
|
||||
|
||||
|
||||
|
||||
LoadCurrentLevel:
|
||||
|
||||
; Open the file
|
||||
lda #<Str_FileStates
|
||||
sta Param_FileOpen+1
|
||||
lda #>Str_FileStates
|
||||
sta Param_FileOpen+2
|
||||
jsr $BF00 ; call MLI
|
||||
.byte $C8 ; Open
|
||||
.addr Param_FileOpen
|
||||
|
||||
; load the current level
|
||||
lda #(LVLS_HEADER_SIZE)
|
||||
ldx #0
|
||||
jsr _SetOffset ; current lvl
|
||||
lda #<ReadWriteBuffer
|
||||
sta READ_DST
|
||||
lda #>ReadWriteBuffer
|
||||
sta READ_DST+1
|
||||
lda #<MIN_READ_SIZE
|
||||
ldx #>MIN_READ_SIZE
|
||||
jsr _Read
|
||||
lda ReadWriteBuffer
|
||||
sta NextLevel
|
||||
|
||||
; Close the file
|
||||
lda Handle_File
|
||||
sta Param_FileClose+1
|
||||
jsr $BF00 ; call MLI
|
||||
.byte $CC ; Close
|
||||
.addr Param_FileClose
|
||||
|
||||
rts
|
30
src/io/files.inc
Normal file
30
src/io/files.inc
Normal file
|
@ -0,0 +1,30 @@
|
|||
; Copyright (C) 2021 Christophe Meneboeuf <christophe@xtof.info>
|
||||
;
|
||||
; This program is free software: you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation, either version 3 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
; data
|
||||
; TODO : should remain private!!
|
||||
.import Str_FileLevelConfs
|
||||
.import Str_FileLevelsActors
|
||||
.import Param_FileOpen
|
||||
.import Param_FileOffset
|
||||
.import Param_FilesReadWrite
|
||||
|
||||
; functions
|
||||
.import ReadFile
|
||||
.import LoadState
|
||||
.import SaveState
|
||||
.import ResetIsBuilt
|
||||
.import LoadCurrentLevel
|
48
src/io/gr.asm
Normal file
48
src/io/gr.asm
Normal file
|
@ -0,0 +1,48 @@
|
|||
; Copyright (C) 2019 Christophe Meneboeuf <christophe@xtof.info>
|
||||
;
|
||||
; This program is free software: you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation, either version 3 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
.export Clear_Gr1
|
||||
|
||||
|
||||
.CODE
|
||||
|
||||
;@brief Clears GR1 screen
|
||||
; BEWARE : It will fill the "holes" with 0s
|
||||
Clear_Gr1:
|
||||
|
||||
lda #0 ; black
|
||||
ldx #0
|
||||
clear_gr1_1:
|
||||
sta $400, X
|
||||
inx
|
||||
bne clear_gr1_1
|
||||
ldx #0
|
||||
clear_gr1_2:
|
||||
sta $500, X
|
||||
inx
|
||||
bne clear_gr1_2
|
||||
ldx #0
|
||||
clear_gr1_3:
|
||||
sta $600, X
|
||||
inx
|
||||
bne clear_gr1_3
|
||||
ldx #0
|
||||
clear_gr1_4:
|
||||
sta $700, X
|
||||
inx
|
||||
bne clear_gr1_4
|
||||
|
||||
rts
|
1
src/io/gr.inc
Normal file
1
src/io/gr.inc
Normal file
|
@ -0,0 +1 @@
|
|||
.import Clear_Gr1
|
187
src/io/textio.asm
Normal file
187
src/io/textio.asm
Normal file
|
@ -0,0 +1,187 @@
|
|||
; Copyright (C) 2019 Christophe Meneboeuf <christophe@xtof.info>
|
||||
;
|
||||
; This program is free software: you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation, either version 3 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
.include "../memory.inc"
|
||||
|
||||
.export CIN_STR
|
||||
.export Cin_Str
|
||||
.export Cin_Char
|
||||
.export Print
|
||||
.export ClearTxt
|
||||
|
||||
|
||||
.define SPACE $A0
|
||||
.define CURSOR $5F
|
||||
.define RETURN $8D
|
||||
.define DELETE $FF
|
||||
.define LEFT $88
|
||||
|
||||
|
||||
.DATA
|
||||
|
||||
CIN_STR:
|
||||
.byte 0
|
||||
.res 40 ; input string buffer char[40]
|
||||
|
||||
|
||||
.CODE
|
||||
|
||||
; brief Clears the 4 line in text zone (mixed mode)
|
||||
ClearTxt:
|
||||
ldx #39
|
||||
lda #SPACE
|
||||
loop_clear_lines:
|
||||
sta TXT1_LINE20, X
|
||||
sta TXT1_LINE21, X
|
||||
sta TXT1_LINE22, X
|
||||
sta TXT1_LINE23, X
|
||||
dex
|
||||
bpl loop_clear_lines
|
||||
rts
|
||||
|
||||
|
||||
; brief Scrolls the lines in text zone (mixed mode)
|
||||
_ScrollTxt:
|
||||
ldx #39
|
||||
loop_scroll_lines:
|
||||
lda TXT1_LINE21, X
|
||||
sta TXT1_LINE20, X
|
||||
lda TXT1_LINE22, X
|
||||
sta TXT1_LINE21, X
|
||||
lda TXT1_LINE23, X
|
||||
sta TXT1_LINE22, X
|
||||
lda #SPACE
|
||||
sta TXT1_LINE23, X
|
||||
dex
|
||||
bpl loop_scroll_lines
|
||||
rts
|
||||
|
||||
|
||||
.define ADDR_STR ZERO_7_1 ; 2 bytes same as FAC1 and FAC2
|
||||
; @brief Print the null terminated str
|
||||
; @param A,X Adress of the string (hi, low)
|
||||
Print:
|
||||
stx ADDR_STR
|
||||
sta ADDR_STR+1
|
||||
|
||||
jsr _ScrollTxt
|
||||
|
||||
ldy #0
|
||||
loop_print_str:
|
||||
lda (ADDR_STR), Y
|
||||
cmp #0
|
||||
beq break_print_str
|
||||
sta TXT1_LINE23, Y
|
||||
iny
|
||||
cpy #40
|
||||
bne loop_print_str
|
||||
break_print_str:
|
||||
|
||||
rts
|
||||
|
||||
.macro INC_SEED
|
||||
clc
|
||||
lda SEED0
|
||||
adc #1
|
||||
sta SEED0
|
||||
lda SEED1
|
||||
adc #0
|
||||
sta SEED1
|
||||
lda SEED2
|
||||
adc #0
|
||||
sta SEED2
|
||||
lda SEED3
|
||||
adc #0
|
||||
sta SEED3
|
||||
.endmacro
|
||||
|
||||
|
||||
; @brief Gets an input string into the CIN_STR buffer
|
||||
; @details It will also init the seed
|
||||
Cin_Str:
|
||||
|
||||
jsr _ScrollTxt
|
||||
|
||||
; position the cursor
|
||||
ldx #0
|
||||
lda #CURSOR
|
||||
sta TXT1_LINE23, X
|
||||
|
||||
; wait for keyboard
|
||||
cin_str_kbd_loop:
|
||||
INC_SEED
|
||||
lda KEYBD
|
||||
bpl cin_str_kbd_loop ; bit #8 is set when a character is present (thus A < 0)
|
||||
sta KEYBD_STROBE
|
||||
|
||||
cmp #RETURN
|
||||
beq break_cin ; break if "Return"
|
||||
|
||||
cmp #DELETE
|
||||
beq delete
|
||||
|
||||
cmp #LEFT
|
||||
beq delete
|
||||
|
||||
; print key and avance the cursor
|
||||
sta TXT1_LINE23, X
|
||||
sta CIN_STR, X
|
||||
inx
|
||||
cpx #40 ; eol -> ends anyway
|
||||
beq break_cin
|
||||
lda #CURSOR
|
||||
sta TXT1_LINE23, X
|
||||
jmp cin_str_kbd_loop
|
||||
|
||||
break_cin:
|
||||
lda #SPACE
|
||||
sta TXT1_LINE23, X ; erase the cursor
|
||||
lda #0
|
||||
sta CIN_STR, X
|
||||
|
||||
rts
|
||||
|
||||
delete:
|
||||
cpx #0 ; cannot delete when at pos 0
|
||||
beq cin_str_kbd_loop
|
||||
lda #SPACE
|
||||
sta TXT1_LINE23, X
|
||||
dex
|
||||
lda #0
|
||||
sta CIN_STR, X
|
||||
lda #CURSOR
|
||||
sta TXT1_LINE23, X
|
||||
jmp cin_str_kbd_loop
|
||||
|
||||
|
||||
|
||||
; @brief Gets an input char
|
||||
; @detals Entered char in A
|
||||
Cin_Char:
|
||||
|
||||
jsr _ScrollTxt
|
||||
|
||||
lda #CURSOR
|
||||
sta TXT1_LINE23
|
||||
|
||||
; wait for keyboard
|
||||
cin_char_kbd_loop:
|
||||
lda KEYBD
|
||||
bpl cin_char_kbd_loop ; bit #8 is set when a character is present (thus A < 0)
|
||||
sta KEYBD_STROBE
|
||||
sta TXT1_LINE23
|
||||
|
||||
rts
|
23
src/io/textio.inc
Normal file
23
src/io/textio.inc
Normal file
|
@ -0,0 +1,23 @@
|
|||
.import Print
|
||||
.import ClearTxt
|
||||
.import Cin_Str
|
||||
.import Cin_Char
|
||||
|
||||
.import CIN_STR
|
||||
|
||||
|
||||
; --- string with high-bit set, null-terminated
|
||||
; Apple II char < 128 are inverted
|
||||
.macro ASCIIZ str
|
||||
.repeat .strlen (str), c
|
||||
.byte .strat (str, c) | $80
|
||||
.endrep
|
||||
.byte 0
|
||||
.endmacro
|
||||
|
||||
|
||||
.macro PRINT string
|
||||
lda #>string
|
||||
ldx #<string
|
||||
jsr Print
|
||||
.endmacro
|
135
src/io/title.asm
Normal file
135
src/io/title.asm
Normal file
|
@ -0,0 +1,135 @@
|
|||
; Copyright (C) 2019 Christophe Meneboeuf <christophe@xtof.info>
|
||||
;
|
||||
; This program is free software: you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation, either version 3 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
.include "../monitor.inc"
|
||||
.include "../memory.inc"
|
||||
.include "../io/textio.inc"
|
||||
.include "gr.inc"
|
||||
|
||||
.export Title
|
||||
|
||||
|
||||
.DATA
|
||||
GR_TITLE_00 : .byte $0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0
|
||||
GR_TITLE_01 : .byte $0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0
|
||||
GR_TITLE_02 : .byte $0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0
|
||||
GR_TITLE_03 : .byte $0,$0,$99,$99,$99,$99,$99,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$99,$99,$99,$99,$99,$0
|
||||
GR_TITLE_04 : .byte $0,$0,$99,$99,$99,$99,$99,$0,$0,$88,$88,$88,$88,$0,$0,$88,$88,$88,$88,$0,$0,$0,$88,$88,$0,$0,$0,$88,$88,$88,$88,$88,$0,$0,$99,$99,$99,$99,$99,$0
|
||||
GR_TITLE_05 : .byte $0,$0,$99,$0,$0,$0,$0,$0,$88,$0,$0,$0,$0,$0,$88,$0,$0,$0,$0,$0,$0,$88,$0,$0,$88,$0,$0,$88,$0,$0,$0,$0,$88,$0,$99,$0,$0,$0,$0,$0
|
||||
GR_TITLE_06 : .byte $0,$0,$99,$0,$0,$0,$0,$0,$88,$0,$0,$0,$0,$0,$88,$0,$0,$0,$0,$0,$88,$0,$0,$0,$0,$88,$0,$88,$0,$0,$0,$0,$88,$0,$99,$0,$0,$0,$0,$0
|
||||
GR_TITLE_07 : .byte $0,$0,$99,$99,$99,$0,$0,$0,$88,$88,$88,$88,$0,$0,$88,$0,$0,$0,$0,$0,$88,$0,$0,$0,$0,$88,$0,$88,$88,$88,$88,$88,$0,$0,$99,$99,$99,$0,$0,$0
|
||||
GR_TITLE_08 : .byte $0,$0,$99,$0,$0,$0,$0,$0,$0,$0,$0,$0,$88,$0,$88,$0,$0,$0,$0,$0,$88,$88,$88,$88,$88,$88,$0,$88,$0,$0,$0,$0,$0,$0,$99,$0,$0,$0,$0,$0
|
||||
GR_TITLE_09 : .byte $0,$0,$99,$0,$0,$0,$0,$0,$0,$0,$0,$0,$88,$0,$88,$0,$0,$0,$0,$0,$88,$0,$0,$0,$0,$88,$0,$88,$0,$0,$0,$0,$0,$0,$99,$0,$0,$0,$0,$0
|
||||
GR_TITLE_10 : .byte $0,$0,$99,$99,$99,$99,$99,$0,$88,$0,$0,$0,$88,$0,$88,$0,$0,$0,$0,$0,$88,$0,$0,$0,$0,$88,$0,$88,$0,$0,$0,$0,$0,$0,$99,$99,$99,$99,$99,$0
|
||||
GR_TITLE_11 : .byte $0,$0,$99,$99,$99,$99,$99,$0,$88,$88,$88,$88,$0,$0,$0,$88,$88,$88,$88,$0,$88,$0,$0,$0,$0,$88,$0,$88,$0,$0,$0,$0,$0,$0,$99,$99,$99,$99,$99,$0
|
||||
GR_TITLE_12 : .byte $0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0
|
||||
GR_TITLE_13 : .byte $0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0
|
||||
GR_TITLE_14 : .byte $0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$55,$55,$55,$55,$0,$0,$55,$55,$55,$55,$55,$55,$0,$55,$55,$55,$55,$55,$55,$0,$55,$55,$55,$55,$55,$0,$0,$0
|
||||
GR_TITLE_15 : .byte $0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$55,$0,$0,$0,$0,$55,$0,$0,$0,$0,$0,$0,$55,$0,$55,$0,$0,$0,$0,$0,$0,$55,$0,$0,$0,$0,$55,$0,$0
|
||||
GR_TITLE_16 : .byte $0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$55,$55,$55,$55,$55,$55,$0,$55,$55,$55,$55,$55,$55,$0,$55,$55,$55,$55,$0,$0,$0,$55,$55,$55,$55,$55,$0,$0,$0
|
||||
GR_TITLE_17 : .byte $0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$55,$0,$0,$0,$0,$55,$0,$55,$0,$0,$0,$0,$0,$0,$55,$0,$0,$0,$0,$0,$0,$55,$0,$0,$0,$0,$0,$0,$0
|
||||
GR_TITLE_18 : .byte $0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$55,$0,$0,$0,$0,$55,$0,$55,$55,$55,$55,$55,$55,$0,$55,$0,$0,$0,$0,$0,$0,$55,$0,$0,$0,$0,$0,$0,$0
|
||||
GR_TITLE_19 : .byte $0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0
|
||||
|
||||
|
||||
.CODE
|
||||
|
||||
|
||||
Scroll:
|
||||
|
||||
ldx #39
|
||||
loop_scroll:
|
||||
lda TXT1_LINE1, X
|
||||
sta TXT1_LINE0, X
|
||||
lda TXT1_LINE2, X
|
||||
sta TXT1_LINE1, X
|
||||
lda TXT1_LINE3, X
|
||||
sta TXT1_LINE2, X
|
||||
lda TXT1_LINE4, X
|
||||
sta TXT1_LINE3, X
|
||||
lda TXT1_LINE5, X
|
||||
sta TXT1_LINE4, X
|
||||
lda TXT1_LINE6, X
|
||||
sta TXT1_LINE5, X
|
||||
lda TXT1_LINE7, X
|
||||
sta TXT1_LINE6, X
|
||||
lda TXT1_LINE8, X
|
||||
sta TXT1_LINE7, X
|
||||
lda TXT1_LINE9, X
|
||||
sta TXT1_LINE8, X
|
||||
lda TXT1_LINE10, X
|
||||
sta TXT1_LINE9, X
|
||||
lda TXT1_LINE11, X
|
||||
sta TXT1_LINE10, X
|
||||
lda TXT1_LINE12, X
|
||||
sta TXT1_LINE11, X
|
||||
lda TXT1_LINE13, X
|
||||
sta TXT1_LINE12, X
|
||||
lda TXT1_LINE14, X
|
||||
sta TXT1_LINE13, X
|
||||
lda TXT1_LINE15, X
|
||||
sta TXT1_LINE14, X
|
||||
lda TXT1_LINE16, X
|
||||
sta TXT1_LINE15, X
|
||||
lda TXT1_LINE17, X
|
||||
sta TXT1_LINE16, X
|
||||
lda TXT1_LINE18, X
|
||||
sta TXT1_LINE17, X
|
||||
lda TXT1_LINE19, X
|
||||
sta TXT1_LINE18, X
|
||||
dex
|
||||
bpl loop_scroll
|
||||
|
||||
rts
|
||||
|
||||
.DATA
|
||||
Title_Scr_Addr:
|
||||
.word GR_TITLE_01, GR_TITLE_02, GR_TITLE_03, GR_TITLE_04, GR_TITLE_05, GR_TITLE_06, GR_TITLE_07, GR_TITLE_08, GR_TITLE_09, GR_TITLE_10
|
||||
.word GR_TITLE_11, GR_TITLE_12, GR_TITLE_13, GR_TITLE_14, GR_TITLE_15, GR_TITLE_16, GR_TITLE_17, GR_TITLE_18, GR_TITLE_19
|
||||
|
||||
.CODE
|
||||
; @brief Displays's the title screen and main game menu
|
||||
Title:
|
||||
|
||||
; Title Screen
|
||||
jsr Clear_Gr1
|
||||
jsr ClearTxt
|
||||
|
||||
sta $C054 ; page 1
|
||||
sta $C056 ; lores
|
||||
sta $C050 ; gfx
|
||||
sta $C053 ; mixed mode on
|
||||
|
||||
ldy #$FE
|
||||
loop_scrolling:
|
||||
lda #$A2 ; wait for 66ms
|
||||
jsr WAIT
|
||||
ldx #39
|
||||
loop_lines:
|
||||
lda GR_TITLE_00, X
|
||||
sta TXT1_LINE19, X
|
||||
dex
|
||||
bpl loop_lines
|
||||
jsr Scroll
|
||||
iny
|
||||
iny
|
||||
lda Title_Scr_Addr, Y
|
||||
sta loop_lines+1
|
||||
lda Title_Scr_Addr+1, Y
|
||||
sta loop_lines+2
|
||||
cpy #$26
|
||||
bne loop_scrolling
|
||||
|
||||
rts
|
157
src/main.asm
157
src/main.asm
|
@ -17,33 +17,158 @@
|
|||
.include "random.inc"
|
||||
.include "memory.inc"
|
||||
.include "monitor.inc"
|
||||
.include "display_map.inc"
|
||||
.include "builder/builder.inc"
|
||||
.include "io/textio.inc"
|
||||
.include "io/files.inc"
|
||||
|
||||
.export _main
|
||||
|
||||
; functions
|
||||
.import world_init
|
||||
.import player_init
|
||||
.import view_init
|
||||
.import game_loop
|
||||
.import Title
|
||||
.import level_reset_states
|
||||
|
||||
.import memcpy
|
||||
.import memset
|
||||
.import meminit
|
||||
|
||||
; data
|
||||
.import __CODE2_LOAD__
|
||||
.import __CODE2_RUN__
|
||||
.import __CODE2_SIZE__
|
||||
.import __RODATA_LOAD__
|
||||
.import __RODATA_RUN__
|
||||
.import __RODATA_SIZE__
|
||||
.import __DATA_LOAD__
|
||||
.import __DATA_RUN__
|
||||
.import __DATA_SIZE__
|
||||
|
||||
.DATA
|
||||
|
||||
STR_EMPTY: ASCIIZ " "
|
||||
STR_NEWGAME: ASCIIZ "(N)EW GAME"
|
||||
STR_JOURNEY: ASCIIZ "(J)OURNEY ONWARD"
|
||||
STR_NAME: ASCIIZ "WHAT'S YOUR NAME, ADVENTURER?"
|
||||
|
||||
.CODE
|
||||
|
||||
_main:
|
||||
|
||||
; init the seed of rnd
|
||||
lda #$DE
|
||||
sta SEED0
|
||||
lda #$AD
|
||||
sta SEED1
|
||||
lda #$BE
|
||||
sta SEED2
|
||||
lda #$EF
|
||||
sta SEED3
|
||||
|
||||
jsr player_init
|
||||
jsr world_init
|
||||
jsr view_init
|
||||
|
||||
jsr game_loop
|
||||
|
||||
; jsr meminit // Uncomment to zero memory, for debug
|
||||
|
||||
; Relocations after the HGR "hole"
|
||||
; relocating code
|
||||
lda #<__CODE2_LOAD__
|
||||
sta FROM
|
||||
lda #>__CODE2_LOAD__
|
||||
sta FROM+1
|
||||
lda #<__CODE2_RUN__
|
||||
sta TO
|
||||
lda #>__CODE2_RUN__
|
||||
sta TO+1
|
||||
lda #<__CODE2_SIZE__
|
||||
sta SIZEL
|
||||
lda #>__CODE2_SIZE__
|
||||
sta SIZEH
|
||||
jsr memcpy
|
||||
; relocating RODATA
|
||||
lda #<__RODATA_LOAD__
|
||||
sta FROM
|
||||
lda #>__RODATA_LOAD__
|
||||
sta FROM+1
|
||||
lda #<__RODATA_RUN__
|
||||
sta TO
|
||||
lda #>__RODATA_RUN__
|
||||
sta TO+1
|
||||
lda #<__RODATA_SIZE__
|
||||
sta SIZEL
|
||||
lda #>__RODATA_SIZE__
|
||||
sta SIZEH
|
||||
jsr memcpy
|
||||
; relocating DATA
|
||||
lda #<__DATA_LOAD__
|
||||
sta FROM
|
||||
lda #>__DATA_LOAD__
|
||||
sta FROM+1
|
||||
lda #<__DATA_RUN__
|
||||
sta TO
|
||||
lda #>__DATA_RUN__
|
||||
sta TO+1
|
||||
lda #<__DATA_SIZE__
|
||||
sta SIZEL
|
||||
lda #>__DATA_SIZE__
|
||||
sta SIZEH
|
||||
jsr memcpy
|
||||
|
||||
jsr _StartMenu ; will init the seed
|
||||
|
||||
; overwrite the seed to debug
|
||||
; lda #$0
|
||||
; sta SEED0
|
||||
; lda #$0
|
||||
; sta SEED1
|
||||
; lda #$0
|
||||
; sta SEED2
|
||||
; lda #$0
|
||||
; sta SEED3
|
||||
|
||||
jsr Random8_Init
|
||||
|
||||
; Run
|
||||
jsr game_loop
|
||||
|
||||
rts
|
||||
|
||||
|
||||
; @brief Starting game menu
|
||||
_StartMenu:
|
||||
|
||||
; Scrolling Title
|
||||
jsr Title
|
||||
|
||||
; New game or continue
|
||||
lda #>STR_NEWGAME
|
||||
ldx #<STR_NEWGAME
|
||||
jsr Print
|
||||
lda #>STR_JOURNEY
|
||||
ldx #<STR_JOURNEY
|
||||
jsr Print
|
||||
kbd_wait:
|
||||
lda KEYBD
|
||||
bpl kbd_wait
|
||||
|
||||
sta KEYBD_STROBE
|
||||
|
||||
cmp #($4E + $80) ; 'N'
|
||||
beq new_game
|
||||
cmp #($6E + $80) ; 'n'
|
||||
beq new_game
|
||||
|
||||
cmp #($4A + $80) ; 'J'
|
||||
beq journey_onward
|
||||
cmp #($6A + $80) ; 'j'
|
||||
beq journey_onward
|
||||
|
||||
bne kbd_wait
|
||||
|
||||
journey_onward:
|
||||
jsr LoadCurrentLevel
|
||||
jmp start_menu_end
|
||||
|
||||
new_game:
|
||||
; Ask for name
|
||||
lda #>STR_NAME
|
||||
ldx #<STR_NAME
|
||||
jsr Print
|
||||
jsr Cin_Str ; Init seed
|
||||
|
||||
; delete progress
|
||||
jsr level_reset_states
|
||||
|
||||
start_menu_end:
|
||||
|
||||
rts
|
||||
|
|
88
src/math.asm
88
src/math.asm
|
@ -5,6 +5,7 @@
|
|||
.define FAC2 ZERO_7_2
|
||||
|
||||
.export mul8
|
||||
.export Modulus
|
||||
|
||||
.CODE
|
||||
|
||||
|
@ -19,13 +20,90 @@ mul8:
|
|||
|
||||
lda #$00
|
||||
ldx #$08
|
||||
clc
|
||||
clc
|
||||
m0: bcc m1
|
||||
clc
|
||||
clc
|
||||
adc FAC2
|
||||
m1: ror
|
||||
m1: ror
|
||||
ror FAC1
|
||||
dex
|
||||
dex
|
||||
bpl m0
|
||||
ldx FAC1
|
||||
rts
|
||||
|
||||
rts
|
||||
|
||||
|
||||
; 8 bit division
|
||||
; Inputs:
|
||||
; FAC1 = 8-bit numerator
|
||||
; FAC2 = 8-bit denominator
|
||||
; Outputs:
|
||||
; FAC1 = 8-bit quotient of TQ / B
|
||||
; A = remainder of TQ / B
|
||||
; source: http://6502org.wikidot.com/software-math-intdiv
|
||||
; div8:
|
||||
; lda #0
|
||||
; ldx #8
|
||||
; asl FAC1
|
||||
; lbl_1:
|
||||
; rol A
|
||||
; cmp FAC2
|
||||
; bcc lbl_2
|
||||
; sbc FAC2
|
||||
; lbl_2:
|
||||
; rol FAC1
|
||||
; dex
|
||||
; bne lbl_1
|
||||
|
||||
; rts
|
||||
|
||||
|
||||
; source: https://www.codebase64.org/doku.php?id=base:8bit_divide_8bit_product
|
||||
; 8bit/8bit division
|
||||
; by White Flame
|
||||
;
|
||||
; Input: num, denom in zeropage
|
||||
; Output: num = quotient, .A = remainder
|
||||
|
||||
; div8:
|
||||
; lda #$00
|
||||
; ldx #$07
|
||||
; clc
|
||||
; : rol FAC1
|
||||
; rol
|
||||
; cmp FAC2
|
||||
; bcc :+
|
||||
; sbc FAC2
|
||||
; : dex
|
||||
; bpl :--
|
||||
; rol FAC1
|
||||
|
||||
; 19 bytes
|
||||
;
|
||||
; Best case = 154 cycles
|
||||
; Worst case = 170 cycles
|
||||
;
|
||||
; With immediate denom:
|
||||
; Best case = 146 cycles
|
||||
; Worst case = 162 cycles
|
||||
;
|
||||
; Unrolled with variable denom:
|
||||
; Best case = 106 cycles
|
||||
; Worst case = 127 cycles
|
||||
;
|
||||
; Unrolled with immediate denom:
|
||||
; Best case = 98 cycles
|
||||
; Worst case = 111 cycles
|
||||
|
||||
; Returns A % X in A
|
||||
; Source: http://forum.6502.org/viewtopic.php?t=130
|
||||
Modulus:
|
||||
sec
|
||||
stx FAC2
|
||||
lbl_modulus:
|
||||
sbc FAC2
|
||||
bcs lbl_modulus
|
||||
|
||||
adc FAC2
|
||||
|
||||
rts
|
||||
|
|
27
src/math.inc
27
src/math.inc
|
@ -13,11 +13,13 @@
|
|||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
|
||||
.define FAC1 ZERO_7_1
|
||||
.define FAC2 ZERO_7_2
|
||||
|
||||
.import mul8
|
||||
.import Modulus
|
||||
.import div8
|
||||
|
||||
; Inverts a positive number to its 2's complement counterpart
|
||||
; The bits are all reversed then one is added
|
||||
|
@ -28,3 +30,26 @@
|
|||
clc
|
||||
adc #$01
|
||||
.endmacro
|
||||
|
||||
|
||||
.macro ADD16 addr, csteL, csteH
|
||||
clc
|
||||
lda addr
|
||||
adc csteL
|
||||
sta addr
|
||||
lda addr+1
|
||||
adc csteH
|
||||
sta addr+1
|
||||
.endmacro
|
||||
|
||||
|
||||
.macro DEC16 addr, cste
|
||||
sec
|
||||
lda addr
|
||||
sbc cste
|
||||
sta addr
|
||||
lda addr+1
|
||||
sbc #0
|
||||
sta addr+1
|
||||
.endmacro
|
||||
|
||||
|
|
138
src/memory.asm
Normal file
138
src/memory.asm
Normal file
|
@ -0,0 +1,138 @@
|
|||
|
||||
; Copyright (C) 2019 Christophe Meneboeuf <christophe@xtof.info>
|
||||
;
|
||||
; This program is free software: you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation, either version 3 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
.include "memory.inc"
|
||||
|
||||
.export memcpy
|
||||
.export memset
|
||||
.export meminit
|
||||
|
||||
|
||||
.CODE
|
||||
|
||||
; http://www.6502.org/source/general/memory_move.html
|
||||
; Move memory up
|
||||
;
|
||||
; FROM = source start address
|
||||
; TO = destination start address
|
||||
; SIZE = number of bytes to move
|
||||
;
|
||||
memcpy: LDX SIZEH ; the last byte must be moved first
|
||||
CLC ; start at the final pages of FROM and TO
|
||||
TXA
|
||||
ADC FROM+1
|
||||
STA FROM+1
|
||||
CLC
|
||||
TXA
|
||||
ADC TO+1
|
||||
STA TO+1
|
||||
INX ; allows the use of BNE after the DEX below
|
||||
LDY SIZEL
|
||||
BEQ MU3
|
||||
DEY ; move bytes on the last page first
|
||||
BEQ MU2
|
||||
MU1: LDA (FROM),Y
|
||||
STA (TO),Y
|
||||
DEY
|
||||
BNE MU1
|
||||
MU2: LDA (FROM),Y ; handle Y = 0 separately
|
||||
STA (TO),Y
|
||||
MU3: DEY
|
||||
DEC FROM+1 ; move the next page (if any)
|
||||
DEC TO+1
|
||||
DEX
|
||||
BNE MU1
|
||||
RTS
|
||||
|
||||
; Sets a block of memory to the provided value
|
||||
;
|
||||
; A = value to set
|
||||
; TO = memory to be set starting address
|
||||
; SIZE = number of bytes to set. Max value: $FEFF
|
||||
;
|
||||
; !!! TO and SIZE are overwritten !!
|
||||
memset:
|
||||
cmp SIZEH
|
||||
beq memset_remain
|
||||
memset_loop_hi:
|
||||
ldy #$FF
|
||||
memset_loop_low:
|
||||
sta (TO),Y
|
||||
dey
|
||||
bne memset_loop_low
|
||||
sta (TO),Y
|
||||
inc TO+1 ; next 256 byte block
|
||||
dec SIZEH
|
||||
bne memset_loop_hi
|
||||
memset_remain:
|
||||
ldy SIZEL
|
||||
cpy #0
|
||||
beq memset_end
|
||||
memset_loop_remain:
|
||||
sta (TO),Y
|
||||
dey
|
||||
bne memset_loop_remain
|
||||
memset_end:
|
||||
rts
|
||||
|
||||
; DEBUG: zeros the useful memory locations
|
||||
meminit:
|
||||
|
||||
lda #0
|
||||
sta TO
|
||||
ldx #$60
|
||||
stx TO+1
|
||||
ldx #$FF
|
||||
stx SIZEL
|
||||
ldx #$05
|
||||
stx SIZEH
|
||||
jsr memset
|
||||
|
||||
lda #0
|
||||
sta ZERO_2_1
|
||||
sta ZERO_2_2
|
||||
sta ZERO_2_3
|
||||
sta ZERO_2_4
|
||||
sta ZERO_2_5
|
||||
sta ZERO_2_6
|
||||
sta ZERO_3
|
||||
sta ZERO_4_1
|
||||
sta ZERO_4_2
|
||||
sta ZERO_4_3
|
||||
sta ZERO_4_4
|
||||
sta ZERO_4_5
|
||||
sta ZERO_5_1
|
||||
sta ZERO_5_2
|
||||
sta ZERO_5_3
|
||||
sta ZERO_5_4
|
||||
sta ZERO_5_5
|
||||
sta ZERO_5_6
|
||||
sta ZERO_7_1
|
||||
sta ZERO_7_2
|
||||
sta ZERO_8_1
|
||||
sta ZERO_8_2
|
||||
sta ZERO_9_1
|
||||
sta ZERO_9_2
|
||||
sta ZERO_9_3
|
||||
sta ZERO_9_4
|
||||
sta ZERO_9_5
|
||||
sta ZERO_9_6
|
||||
sta ZERO_9_7
|
||||
sta ZERO_9_8
|
||||
sta ZERO_9_9
|
||||
sta ZERO_9_10
|
||||
|
||||
rts
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
; Copyright (C) 2018 Christophe Meneboeuf <christophe@xtof.info>
|
||||
; Copyright (C) 2019 Christophe Meneboeuf <christophe@xtof.info>
|
||||
;
|
||||
; This program is free software: you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
|
@ -19,7 +19,11 @@
|
|||
; Free locations in Zero Page: not used by either
|
||||
; the Monitor, Applesoft, Integer Basic, DOS3.3 or PRODOS
|
||||
|
||||
; reserved locations
|
||||
.define RESERVED01 $52
|
||||
|
||||
; locations for the random generator
|
||||
; little endian
|
||||
.define SEED0 $6
|
||||
.define SEED1 $7
|
||||
.define SEED2 $8
|
||||
|
@ -53,11 +57,76 @@
|
|||
.define ZERO_7_2 $CF
|
||||
|
||||
.define ZERO_8_1 $D6
|
||||
.define ZERO_8_2 $D7
|
||||
.define ZERO_8_2 $D7
|
||||
|
||||
.define ZERO_9_1 $F0
|
||||
.define ZERO_9_2 $F1
|
||||
.define ZERO_9_3 $F2
|
||||
.define ZERO_9_4 $F3
|
||||
.define ZERO_9_5 $F4
|
||||
.define ZERO_9_6 $F5
|
||||
.define ZERO_9_7 $F6
|
||||
.define ZERO_9_8 $F7
|
||||
.define ZERO_9_9 $F8
|
||||
.define ZERO_9_10 $F9
|
||||
|
||||
; ************ I/O ************
|
||||
.define KEYBD $C000
|
||||
.define KEYBD_STROBE $C010
|
||||
|
||||
; *********** HIRES ************
|
||||
.define ADDR_HGR1 $2000
|
||||
.define ADDR_HGR1 $2000
|
||||
.define ADDR_HGR2 $4000
|
||||
|
||||
; ********** TEXT *************
|
||||
.define TXT1_LINE0 $400
|
||||
.define TXT1_LINE1 $480
|
||||
.define TXT1_LINE2 $500
|
||||
.define TXT1_LINE3 $580
|
||||
.define TXT1_LINE4 $600
|
||||
.define TXT1_LINE5 $680
|
||||
.define TXT1_LINE6 $700
|
||||
.define TXT1_LINE7 $780
|
||||
.define TXT1_LINE8 $428
|
||||
.define TXT1_LINE9 $4A8
|
||||
.define TXT1_LINE10 $528
|
||||
.define TXT1_LINE11 $5A8
|
||||
.define TXT1_LINE12 $628
|
||||
.define TXT1_LINE13 $6A8
|
||||
.define TXT1_LINE14 $728
|
||||
.define TXT1_LINE15 $7A8
|
||||
.define TXT1_LINE16 $450
|
||||
.define TXT1_LINE17 $4D0
|
||||
.define TXT1_LINE18 $550
|
||||
.define TXT1_LINE19 $5D0
|
||||
.define TXT1_LINE20 $650
|
||||
.define TXT1_LINE21 $6D0
|
||||
.define TXT1_LINE22 $750
|
||||
.define TXT1_LINE23 $7D0
|
||||
|
||||
.import TXT1_LINES
|
||||
|
||||
|
||||
; *********** CUSTOM ROUTINES *********
|
||||
.define FROM ZERO_2_1 ; 2 bytes
|
||||
.define TO ZERO_2_3 ; 2 bytes
|
||||
.define SIZEH ZERO_8_2
|
||||
.define SIZEL ZERO_8_1
|
||||
|
||||
|
||||
; ************ MACROS ***********
|
||||
|
||||
; pushes addr to the stack
|
||||
; A is detroyed
|
||||
.macro PUSH addr
|
||||
lda addr
|
||||
pha
|
||||
.endmacro
|
||||
|
||||
|
||||
; pops addr from the stack
|
||||
; A is detroyed
|
||||
.macro POP addr
|
||||
pla
|
||||
sta addr
|
||||
.endmacro
|
|
@ -50,6 +50,7 @@
|
|||
.define VTAB $fc22 ; Vertical tab
|
||||
.define VTABZ $fc24 ; Vertical tab (alternate entry)
|
||||
.define HOME $fc58 ; Home cursor and clear to end of page
|
||||
.define WAIT $fca8 ; wait : read "Assembly Cookbook for the Apple II/IIe"
|
||||
.define RDKEY $fd0c ; Get an input character
|
||||
.define CROUT $fd8e ; Issue a carriage return
|
||||
.define PRBYTE $fdda ; Print a hexadecimal byte
|
||||
|
|
175
src/player.asm
175
src/player.asm
|
@ -14,156 +14,107 @@
|
|||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
.include "world.inc"
|
||||
|
||||
.include "common.inc"
|
||||
.include "memory.inc"
|
||||
.include "monitor.inc"
|
||||
.include "io/textio.inc"
|
||||
.include "world/world.inc"
|
||||
.include "actors/actors.inc"
|
||||
|
||||
|
||||
; init the player's structures
|
||||
.export player_init
|
||||
|
||||
; exectutes the tile's reaction and updates the player's position if possible
|
||||
; Destroys ZEROS_2_1 -> 2_5
|
||||
.export player_move
|
||||
|
||||
; All the following functions returns the new player position:
|
||||
; x in X and y in Y
|
||||
; They may be unmodified ;)
|
||||
; DESTROY A, X, Y, ZERO_2_1, ZERO_2_2
|
||||
|
||||
; Increments Player's X position
|
||||
.export player_move_inx
|
||||
; Increments Player's Y position
|
||||
.export player_move_iny
|
||||
; Decrements Player's X position
|
||||
.export player_move_dex
|
||||
; Decrements Player's Y position
|
||||
.export player_move_dey
|
||||
|
||||
; Player coordinates in the maze ([0:255], [0:255])
|
||||
.export Player_XY
|
||||
|
||||
.import compute_maze_addr
|
||||
.import Compute_Maze_Addr
|
||||
.import Reactions_lsb
|
||||
.import Reactions_msb
|
||||
.import ActorTypes
|
||||
.import ActorPositions
|
||||
|
||||
|
||||
.BSS
|
||||
|
||||
Player_XY: .res 2
|
||||
|
||||
.define TO_BE_PATCHED 0
|
||||
.define Player_XY ActorPositions + eACTORTYPES::PLAYER
|
||||
|
||||
.DATA
|
||||
|
||||
STR_HIT_WALL: ASCIIZ "YOU HIT A WALL"
|
||||
|
||||
.CODE
|
||||
|
||||
; Player starts at [1:1]
|
||||
; @brief Player initial coords
|
||||
; @param X player's x
|
||||
; @param Y player's y
|
||||
player_init:
|
||||
ldx #1
|
||||
stx Player_XY
|
||||
stx Player_XY+1
|
||||
sty Player_XY+1
|
||||
rts
|
||||
|
||||
; @param X target tile's x
|
||||
; @param Y target tile's y
|
||||
; @return TRUE in A if the player can move to the tile, FALE otherwise
|
||||
.define ADDR_IN_MAZE ZERO_2_1 ; 2 bytes
|
||||
.define NEW_PLAYER_XY ZERO_2_4 ; 2 bytes
|
||||
player_move:
|
||||
|
||||
; !!! ALL THE MOVE FUNCTION HAVE TO BE GROUPED TOGHETHER
|
||||
; AS THERE IS A COMMON RETURN POINT TO WHICH THEY BRANHC (KEEP PC's DISTANCE < 127) !!!
|
||||
stx NEW_PLAYER_XY
|
||||
sty NEW_PLAYER_XY+1
|
||||
|
||||
.define ADDR_IN_MAZE ZERO_2_1
|
||||
player_move_inx:
|
||||
jsr Compute_Maze_Addr
|
||||
|
||||
; check if moving is possible
|
||||
ldx Player_XY
|
||||
; test for border
|
||||
cpx #WIDTH_MAZE - 1 ; last tile is always a wall...
|
||||
beq return_from_player_move
|
||||
; test that x+1 is "WALKABLE"
|
||||
ldy Player_XY+1
|
||||
jsr compute_maze_addr ; we get the adress for x,y then we increment x
|
||||
; get the actor id
|
||||
stx ADDR_IN_MAZE
|
||||
sta ADDR_IN_MAZE+1
|
||||
ldy #1 ; will look at x+1
|
||||
lda #ACTORS::WALKABLE
|
||||
cmp (ADDR_IN_MAZE), Y
|
||||
bcc return_from_player_move ; carry cleared if A is strictly the lesser --> not walkable
|
||||
ldy #0
|
||||
lda (ADDR_IN_MAZE), Y
|
||||
tax
|
||||
|
||||
; get the actor's type
|
||||
lda ActorTypes, X
|
||||
tay
|
||||
|
||||
; get the reaction address
|
||||
lda Reactions_lsb, Y
|
||||
sta FUNC_REACTION + 1
|
||||
lda Reactions_msb, Y
|
||||
sta FUNC_REACTION+2
|
||||
|
||||
FUNC_REACTION : jsr TO_BE_PATCHED ; actord id in Y
|
||||
|
||||
cmp #TRUE
|
||||
bne end_player_move
|
||||
ldx NEW_PLAYER_XY
|
||||
stx Player_XY
|
||||
ldy NEW_PLAYER_XY+1
|
||||
sty Player_XY+1
|
||||
|
||||
end_player_move:
|
||||
ldx Player_XY
|
||||
inx
|
||||
stx Player_XY ; walkable
|
||||
bvc return_from_player_move
|
||||
|
||||
|
||||
|
||||
player_move_dex:
|
||||
|
||||
; check if moving is possible
|
||||
ldx Player_XY
|
||||
; test for border
|
||||
cpx #1 ; 1st tile is always a wall...
|
||||
beq return_from_player_move
|
||||
; test that x+1 is "WALKABLE"
|
||||
dex
|
||||
ldy Player_XY+1
|
||||
jsr compute_maze_addr ; we get the adress for x-1
|
||||
stx ADDR_IN_MAZE
|
||||
sta ADDR_IN_MAZE+1
|
||||
ldy #0 ; will look at x-1
|
||||
lda #ACTORS::WALKABLE
|
||||
cmp (ADDR_IN_MAZE), Y
|
||||
bcc return_from_player_move ; carry cleared if A is strictly the lesser --> not walkable
|
||||
ldx Player_XY
|
||||
dex
|
||||
stx Player_XY ; walkable
|
||||
bvc return_from_player_move
|
||||
|
||||
rts
|
||||
|
||||
|
||||
; Common code to return from the moves.
|
||||
; Moves BRANCH to here
|
||||
return_from_player_move:
|
||||
|
||||
; return player's coordinates
|
||||
ldx Player_XY
|
||||
ldy Player_XY+1
|
||||
rts
|
||||
|
||||
hit_wall:
|
||||
PRINT STR_HIT_WALL
|
||||
jmp return_from_player_move
|
||||
|
||||
|
||||
player_move_iny:
|
||||
|
||||
; check if moving is possible
|
||||
ldy Player_XY+1
|
||||
; test for border
|
||||
cpy #HEIGHT_MAZE - 1 ; last tile is always a wall...
|
||||
beq return_from_player_move
|
||||
; test that y+1 is "WALKABLE"
|
||||
ldx Player_XY
|
||||
iny
|
||||
jsr compute_maze_addr ; we get the adress for x,y+1
|
||||
stx ADDR_IN_MAZE
|
||||
sta ADDR_IN_MAZE+1
|
||||
ldy #0
|
||||
lda #ACTORS::WALKABLE
|
||||
cmp (ADDR_IN_MAZE), Y
|
||||
bcc return_from_player_move ; carry cleared if A is strictly the lesser --> not walkable
|
||||
|
||||
ldy Player_XY+1 ; walkable
|
||||
iny
|
||||
sty Player_XY+1
|
||||
bvc return_from_player_move
|
||||
|
||||
|
||||
player_move_dey:
|
||||
|
||||
; check if moving is possible
|
||||
ldy Player_XY+1
|
||||
; test for border
|
||||
cpy #1 ; 1st tile is always a wall...
|
||||
beq return_from_player_move
|
||||
; test that y-1 is "WALKABLE"
|
||||
ldx Player_XY
|
||||
dey
|
||||
jsr compute_maze_addr ; we get the adress for x,y-1
|
||||
stx ADDR_IN_MAZE
|
||||
sta ADDR_IN_MAZE+1
|
||||
ldy #0
|
||||
lda #ACTORS::WALKABLE
|
||||
cmp (ADDR_IN_MAZE), Y
|
||||
bcc return_from_player_move ; carry cleared if A is strictly the lesser --> not walkable
|
||||
|
||||
ldy Player_XY+1 ; walkable
|
||||
dey
|
||||
sty Player_XY+1
|
||||
bvc return_from_player_move
|
||||
|
||||
|
||||
.undef ADDR_IN_MAZE
|
||||
|
|
236
src/random.asm
236
src/random.asm
|
@ -3,63 +3,26 @@
|
|||
|
||||
.include "memory.inc"
|
||||
|
||||
.export random8
|
||||
.export Random8
|
||||
.export Random8_Init
|
||||
.export Random8_RestoreRandomness
|
||||
.export Random8_SaveRandomness
|
||||
.export DBG_SEED
|
||||
|
||||
.define TMP ZERO_2_1 ; requires 4 bytes
|
||||
.define MOD ZERO_2_5
|
||||
.define TMP RESERVED01
|
||||
|
||||
.BSS
|
||||
|
||||
.align 256
|
||||
T0: .res 256
|
||||
T1: .res 256
|
||||
T2: .res 256
|
||||
T3: .res 256
|
||||
T0COPY: .res 256
|
||||
|
||||
.CODE
|
||||
;.align 256
|
||||
|
||||
; Linear congruential pseudo-random number generator
|
||||
;
|
||||
; Get the next SEED and obtain an 8-bit random number from it
|
||||
;
|
||||
; Requires the RAND subroutine
|
||||
;
|
||||
; Enter with:
|
||||
;
|
||||
; accumulator = modulus
|
||||
;
|
||||
; Exit with:
|
||||
;
|
||||
; accumulator = random number, 0 <= accumulator < modulus
|
||||
;
|
||||
; MOD, TMP, TMP+1, and TMP+2 are overwritten
|
||||
;
|
||||
; Note that TMP to TMP+2 are only used after RAND is called.
|
||||
;
|
||||
random8: STA MOD ; store modulus in MOD
|
||||
JSR RAND ; get next seed
|
||||
LDA #0 ; multiply SEED by MOD
|
||||
STA TMP+2
|
||||
STA TMP+1
|
||||
STA TMP
|
||||
SEC
|
||||
ROR MOD ; shift out modulus, shifting in a 1 (will loop 8 times)
|
||||
R8A: BCC R8B ; branch if a zero was shifted out
|
||||
CLC ; add SEED, keep upper 8 bits of product in accumulator
|
||||
TAX
|
||||
LDA TMP
|
||||
ADC SEED0
|
||||
STA TMP
|
||||
LDA TMP+1
|
||||
ADC SEED1
|
||||
STA TMP+1
|
||||
LDA TMP+2
|
||||
ADC SEED2
|
||||
STA TMP+2
|
||||
TXA
|
||||
ADC SEED3
|
||||
R8B: ROR ; shift product right
|
||||
ROR TMP+2
|
||||
ROR TMP+1
|
||||
ROR TMP
|
||||
LSR MOD ; loop until all 8 bits of MOD have been shifted out
|
||||
BNE R8A
|
||||
RTS
|
||||
|
||||
|
||||
DBG_SEED: .byte 0,0,0,0 ; MUST NOT BE RELOCATED!
|
||||
|
||||
; Linear congruential pseudo-random number generator
|
||||
;
|
||||
|
@ -79,79 +42,116 @@ R8B: ROR ; shift product right
|
|||
; SEED2 = byte 2 of seed
|
||||
; SEED3 = byte 3 of seed
|
||||
;
|
||||
; TMP, TMP+1, TMP+2 and TMP+3 are overwritten
|
||||
; TMP is overwritten
|
||||
;
|
||||
; Assuming that (a) SEED0 to SEED3 and TMP+0 to TMP+3 are all located on page
|
||||
; zero, and (b) none of the branches cross a page boundary:
|
||||
; For maximum speed, locate each table on a page boundary
|
||||
;
|
||||
; Space: 106 bytes
|
||||
; Speed: JSR RAND takes 517 cycles
|
||||
; Assuming that (a) SEED0 to SEED3 and TMP are located on page zero, and (b)
|
||||
; all four tables start on a page boundary:
|
||||
;
|
||||
|
||||
RAND: CLC ; copy SEED into TMP
|
||||
LDA SEED0 ; and compute SEED = SEED * $10000 + SEED + 1
|
||||
STA TMP
|
||||
; Space: 58 bytes for the routine
|
||||
; 1024 bytes for the tables
|
||||
; Speed: JSR RAND takes 94 cycles
|
||||
;
|
||||
Random8:
|
||||
CLC ; compute lower 32 bits of:
|
||||
LDX SEED0 ; 1664525 * ($100 * SEED1 + SEED0) + 1
|
||||
LDY SEED1
|
||||
LDA T0,X
|
||||
ADC #1
|
||||
STA SEED0
|
||||
LDA SEED1
|
||||
STA TMP+1
|
||||
ADC #0
|
||||
LDA T1,X
|
||||
ADC T0,Y
|
||||
STA SEED1
|
||||
LDA SEED2
|
||||
STA TMP+2
|
||||
ADC TMP
|
||||
LDA T2,X
|
||||
ADC T1,Y
|
||||
STA TMP
|
||||
LDA T3,X
|
||||
ADC T2,Y
|
||||
TAY ; keep byte 3 in Y for now (for speed)
|
||||
CLC ; add lower 32 bits of:
|
||||
LDX SEED2 ; 1664525 * ($10000 * SEED2)
|
||||
LDA TMP
|
||||
ADC T0,X
|
||||
STA SEED2
|
||||
LDA SEED3
|
||||
STA TMP+3
|
||||
ADC TMP+1
|
||||
TYA
|
||||
ADC T1,X
|
||||
CLC
|
||||
LDX SEED3 ; add lower 32 bits of:
|
||||
ADC T0,X ; 1664525 * ($1000000 * SEED3)
|
||||
STA SEED3
|
||||
;
|
||||
; Bit 7 of $00, $19, $66, and $0D is 0, so only 6 shifts are necessary
|
||||
;
|
||||
LDY #5
|
||||
RAND1: ASL TMP ; shift TMP (old seed) left
|
||||
ROL TMP+1
|
||||
ROL TMP+2
|
||||
ROL TMP+3
|
||||
;
|
||||
; Get X from the RAND4 table. When:
|
||||
;
|
||||
; X = $00, SEED = SEED + $10000 * TMP
|
||||
; X = $01, SEED = SEED + $100 * TMP
|
||||
; X = $FE, SEED = SEED + $10000 * TMP + TMP
|
||||
; X = $FF, SEED = SEED + $100 * TMP + TMP
|
||||
;
|
||||
LDX RAND4,Y
|
||||
BPL RAND2 ; branch if X = $00 or X = $01
|
||||
CLC ; SEED = SEED + TMP
|
||||
LDA SEED0
|
||||
ADC TMP
|
||||
STA SEED0
|
||||
LDA SEED1
|
||||
ADC TMP+1
|
||||
STA SEED1
|
||||
LDA SEED2
|
||||
ADC TMP+2
|
||||
STA SEED2
|
||||
LDA SEED3
|
||||
ADC TMP+3
|
||||
STA SEED3
|
||||
INX ; $FE -> $00, $FF -> $01
|
||||
INX
|
||||
RAND2: CLC
|
||||
BEQ RAND3 ; if X = $00, SEED = SEED + TMP * $10000
|
||||
LDA SEED1 ; SEED = SEED + TMP * $100
|
||||
ADC TMP
|
||||
STA SEED1
|
||||
RAND3: LDA SEED2
|
||||
ADC TMP,X
|
||||
STA SEED2
|
||||
LDA SEED3
|
||||
ADC TMP+1,X
|
||||
STA SEED3
|
||||
DEY
|
||||
BPL RAND1
|
||||
RTS
|
||||
RAND4: .byte $01,$01,$00,$FE,$FF,$01
|
||||
;
|
||||
; Generate T0, T1, T2 and T3 tables
|
||||
;
|
||||
; A different multiplier can be used by simply replacing the four bytes
|
||||
; that are commented below
|
||||
;
|
||||
; To speed this routine up (which will make the routine one byte longer):
|
||||
; 1. Delete the first INX instruction
|
||||
; 2. Replace LDA Tn-1,X with LDA Tn,X (n = 0 to 3)
|
||||
; 3. Replace STA Tn,X with STA Tn+1,X (n = 0 to 3)
|
||||
; 4. Insert CPX #$FF between the INX and BNE GT1
|
||||
;
|
||||
Random8_Init:
|
||||
; Xtof's dbg Saving the seed
|
||||
lda SEED0
|
||||
sta DBG_SEED
|
||||
lda SEED1
|
||||
sta DBG_SEED+1
|
||||
lda SEED2
|
||||
sta DBG_SEED+2
|
||||
lda SEED3
|
||||
sta DBG_SEED+3
|
||||
; Xtof's dbg
|
||||
LDX #0 ; 1664525 * 0 = 0
|
||||
STX T0
|
||||
STX T1
|
||||
STX T2
|
||||
STX T3
|
||||
INX
|
||||
CLC
|
||||
GT1: LDA T0-1,X ; add 1664525 to previous entry to get next entry
|
||||
ADC #$0D ; byte 0 of multiplier
|
||||
STA T0,X
|
||||
LDA T1-1,X
|
||||
ADC #$66 ; byte 1 of multiplier
|
||||
STA T1,X
|
||||
LDA T2-1,X
|
||||
ADC #$19 ; byte 2 of multiplier
|
||||
STA T2,X
|
||||
LDA T3-1,X
|
||||
ADC #$00 ; byte 3 of multiplier
|
||||
STA T3,X
|
||||
INX ; note: carry will be clear here
|
||||
BNE GT1
|
||||
RTS
|
||||
|
||||
|
||||
|
||||
Random8_RestoreRandomness:
|
||||
|
||||
ldx #$FF
|
||||
restore_loop:
|
||||
lda T0COPY, X
|
||||
sta T0, X
|
||||
dex
|
||||
bne restore_loop
|
||||
lda T0COPY, X
|
||||
sta T0, X
|
||||
|
||||
rts
|
||||
|
||||
|
||||
Random8_SaveRandomness:
|
||||
|
||||
ldx #$FF
|
||||
save_loop:
|
||||
lda T0, X
|
||||
sta T0COPY, X
|
||||
dex
|
||||
bne save_loop
|
||||
lda T0, X
|
||||
sta T0COPY, X
|
||||
|
||||
rts
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
|
||||
; Enter with:
|
||||
; accumulator = modulus
|
||||
;
|
||||
; Exit with:
|
||||
; accumulator = random number, 0 <= accumulator < modulus
|
||||
.import random8
|
||||
|
||||
; A = random number
|
||||
.import Random8
|
||||
|
||||
.import Random8_Init
|
||||
|
||||
.import Random8_RestoreRandomness
|
||||
|
||||
.import Random8_SaveRandomness
|
||||
|
|
180
src/tiles.asm
180
src/tiles.asm
|
@ -16,7 +16,7 @@
|
|||
|
||||
.export TILES
|
||||
|
||||
.SEGMENT "TILES"
|
||||
.SEGMENT "RODATA"
|
||||
.ALIGN 256
|
||||
|
||||
PLAYER:
|
||||
|
@ -36,7 +36,7 @@ PLAYER:
|
|||
.byte 16, 16, 66, 0
|
||||
.byte 16, 16, 66, 0
|
||||
.byte 16, 20, 74, 0
|
||||
FLOOR_BLACK:
|
||||
FLOOR_1:
|
||||
.byte $00, $00, $00, $00
|
||||
.byte $00, $00, $00, $00
|
||||
.byte $00, $00, $00, $00
|
||||
|
@ -53,7 +53,7 @@ FLOOR_BLACK:
|
|||
.byte $00, $00, $00, $00
|
||||
.byte $00, $00, $00, $00
|
||||
.byte $00, $00, $00, $00
|
||||
FLOOR_ORANGE:
|
||||
FLOOR_2:
|
||||
.byte 85, 42, 85, 42
|
||||
.byte 1, 32, 0, 0
|
||||
.byte 1, 32, 0, 0
|
||||
|
@ -70,7 +70,7 @@ FLOOR_ORANGE:
|
|||
.byte 16, 0, 64, 0
|
||||
.byte 16, 0, 64, 0
|
||||
.byte 16, 0, 64, 0
|
||||
FLOOR_VIOLET:
|
||||
FLOOR_3:
|
||||
.byte $55, $2A, $55, $2A
|
||||
.byte $55, $2A, $55, $2A
|
||||
.byte $55, $2A, $55, $2A
|
||||
|
@ -87,7 +87,7 @@ FLOOR_VIOLET:
|
|||
.byte $55, $2A, $55, $2A
|
||||
.byte $55, $2A, $55, $2A
|
||||
.byte $55, $2A, $55, $2A
|
||||
FLOOR_BLUE:
|
||||
FLOOR_4:
|
||||
.byte $D5, $AA, $D5, $AA
|
||||
.byte $D5, $AA, $D5, $AA
|
||||
.byte $D5, $AA, $D5, $AA
|
||||
|
@ -104,24 +104,41 @@ FLOOR_BLUE:
|
|||
.byte $D5, $AA, $D5, $AA
|
||||
.byte $D5, $AA, $D5, $AA
|
||||
.byte $D5, $AA, $D5, $AA
|
||||
STAIR_DOWN:
|
||||
.byte $55, $2A, $55, $2A
|
||||
.byte $11, $00, $40, $00
|
||||
.byte $71, $7F, $7F, $1F
|
||||
.byte $71, $01, $C5, $82
|
||||
.byte $71, $79, $80, $8A
|
||||
.byte $71, $79, $3C, $00
|
||||
.byte $71, $79, $3C, $1E
|
||||
.byte $71, $79, $3C, $1E
|
||||
.byte $71, $79, $3C, $1E
|
||||
.byte $71, $79, $3C, $1E
|
||||
.byte $71, $79, $3C, $1E
|
||||
.byte $71, $79, $3C, $1E
|
||||
.byte $71, $79, $3C, $1E
|
||||
.byte $71, $79, $3C, $1E
|
||||
.byte $71, $7F, $7F, $1F
|
||||
.byte $01, $8A, $95, $A8
|
||||
STAIR_UP:
|
||||
.byte $55, $2A, $55, $2A
|
||||
.byte $01, $00, $90, $F8
|
||||
.byte $01, $AA, $70, $79
|
||||
.byte $01, $E2, $73, $79
|
||||
.byte $01, $60, $73, $79
|
||||
.byte $41, $67, $73, $79
|
||||
.byte $41, $67, $73, $79
|
||||
.byte $41, $67, $73, $79
|
||||
.byte $41, $67, $73, $79
|
||||
.byte $41, $67, $73, $79
|
||||
.byte $40, $67, $73, $79
|
||||
.byte $40, $67, $73, $79
|
||||
.byte $40, $67, $73, $79
|
||||
.byte $40, $67, $F3, $A1
|
||||
.byte $40, $67, $D3, $A8
|
||||
.byte $C0, $A7, $91, $A8
|
||||
WALL_1:
|
||||
.byte $7F, $7F, $7F, $7F
|
||||
.byte $7F, $7F, $7F, $7F
|
||||
.byte $7F, $7F, $7F, $7F
|
||||
.byte $7F, $7F, $7F, $7F
|
||||
.byte $7F, $7F, $7F, $7F
|
||||
.byte $7F, $7F, $7F, $7F
|
||||
.byte $7F, $7F, $7F, $7F
|
||||
.byte $7F, $7F, $7F, $7F
|
||||
.byte $7F, $7F, $7F, $7F
|
||||
.byte $7F, $7F, $7F, $7F
|
||||
.byte $7F, $7F, $7F, $7F
|
||||
.byte $7F, $7F, $7F, $7F
|
||||
.byte $7F, $7F, $7F, $7F
|
||||
.byte $7F, $7F, $7F, $7F
|
||||
.byte $7F, $7F, $7F, $7F
|
||||
.byte $7F, $7F, $7F, $7F
|
||||
WALL_2:
|
||||
.byte 197, 138, 213, 168
|
||||
.byte 197, 138, 213, 168
|
||||
.byte 197, 138, 213, 168
|
||||
|
@ -138,6 +155,91 @@ WALL_2:
|
|||
.byte 209, 130, 213, 168
|
||||
.byte 209, 138, 212, 168
|
||||
.byte 0, 0, 0, 0
|
||||
WALL_2:
|
||||
.byte $7F, $7F, $7F, $7F
|
||||
.byte $7F, $7F, $7F, $7F
|
||||
.byte $7F, $7F, $7F, $7F
|
||||
.byte $7F, $7F, $7F, $7F
|
||||
.byte $7F, $7F, $7F, $7F
|
||||
.byte $7F, $7F, $7F, $7F
|
||||
.byte $7F, $7F, $7F, $7F
|
||||
.byte $7F, $7F, $7F, $7F
|
||||
.byte $7F, $7F, $7F, $7F
|
||||
.byte $7F, $7F, $7F, $7F
|
||||
.byte $7F, $7F, $7F, $7F
|
||||
.byte $7F, $7F, $7F, $7F
|
||||
.byte $7F, $7F, $7F, $7F
|
||||
.byte $7F, $7F, $7F, $7F
|
||||
.byte $7F, $7F, $7F, $7F
|
||||
.byte $7F, $7F, $7F, $7F
|
||||
COFFER:
|
||||
.byte $55, $2A, $55, $2A
|
||||
.byte $01, $20, $00, $00
|
||||
.byte $01, $7E, $0F, $00
|
||||
.byte $41, $67, $3C, $00
|
||||
.byte $31, $66, $4C, $01
|
||||
.byte $31, $66, $4C, $01
|
||||
.byte $31, $66, $4C, $01
|
||||
.byte $71, $7F, $7F, $01
|
||||
.byte $31, $C0, $40, $01
|
||||
.byte $35, $C0, $40, $2B
|
||||
.byte $B0, $C0, $40, $01
|
||||
.byte $30, $00, $40, $01
|
||||
.byte $30, $00, $40, $01
|
||||
.byte $70, $7F, $7F, $01
|
||||
.byte $70, $7F, $7F, $01
|
||||
.byte $10, $00, $40, $00
|
||||
RAT:
|
||||
.byte $55, $2A, $55, $2A
|
||||
.byte $01, $20, $03, $00
|
||||
.byte $01, $20, $EF, $81
|
||||
.byte $01, $20, $7C, $1F
|
||||
.byte $01, $78, $7F, $1F
|
||||
.byte $01, $7E, $BF, $85
|
||||
.byte $41, $7F, $0F, $00
|
||||
.byte $71, $7F, $03, $00
|
||||
.byte $7D, $7F, $03, $00
|
||||
.byte $5D, $7F, $57, $2A
|
||||
.byte $5C, $1F, $43, $00
|
||||
.byte $5C, $01, $43, $00
|
||||
.byte $50, $01, $4F, $00
|
||||
.byte $50, $1F, $40, $00
|
||||
.byte $10, $00, $40, $00
|
||||
.byte $10, $00, $40, $00
|
||||
SERPENT:
|
||||
.byte $55, $2A, $55, $2A
|
||||
.byte $01, $20, $03, $00
|
||||
.byte $01, $60, $0C, $00
|
||||
.byte $01, $60, $3F, $00
|
||||
.byte $01, $60, $8B, $80
|
||||
.byte $01, $60, $A3, $81
|
||||
.byte $01, $60, $00, $00
|
||||
.byte $01, $78, $00, $00
|
||||
.byte $01, $7E, $00, $00
|
||||
.byte $55, $2F, $55, $2A
|
||||
.byte $70, $01, $40, $00
|
||||
.byte $30, $18, $40, $00
|
||||
.byte $30, $78, $40, $00
|
||||
.byte $30, $60, $40, $00
|
||||
.byte $70, $79, $40, $00
|
||||
.byte $40, $1F, $40, $00
|
||||
SPIDER:
|
||||
.byte $55, $2A, $55, $2A
|
||||
.byte $01, $18, $03, $00
|
||||
.byte $01, $60, $00, $00
|
||||
.byte $01, $78, $03, $00
|
||||
.byte $01, $78, $03, $00
|
||||
.byte $01, $60, $00, $00
|
||||
.byte $01, $78, $03, $00
|
||||
.byte $71, $5F, $7F, $01
|
||||
.byte $01, $5E, $0F, $00
|
||||
.byte $75, $5F, $7F, $2B
|
||||
.byte $10, $56, $0E, $00
|
||||
.byte $70, $5F, $7F, $01
|
||||
.byte $10, $58, $43, $00
|
||||
.byte $50, $7F, $7F, $00
|
||||
.byte $10, $60, $40, $00
|
||||
.byte $10, $00, $40, $00
|
||||
UNKNOWN:
|
||||
.byte $80, $80, $80, $80
|
||||
.byte $80, $80, $80, $80
|
||||
|
@ -157,9 +259,35 @@ UNKNOWN:
|
|||
.byte $80, $80, $80, $80
|
||||
|
||||
|
||||
.SEGMENT "DATA"
|
||||
.ALIGN 256
|
||||
|
||||
|
||||
; DON"T FORGET TO UPDATE NB_TILES!!
|
||||
; Tiles used by ACTORS
|
||||
; 128 addresses
|
||||
TILES:
|
||||
.word PLAYER, FLOOR_BLACK, FLOOR_ORANGE, FLOOR_VIOLET, FLOOR_BLUE, WALL_1, WALL_2, UNKNOWN
|
||||
.word PLAYER
|
||||
; floors
|
||||
.word FLOOR_1, FLOOR_2, FLOOR_3, FLOOR_4, FLOOR_4, FLOOR_4
|
||||
; walls
|
||||
.word WALL_1, WALL_2, WALL_2, WALL_2
|
||||
; stairs
|
||||
.word STAIR_DOWN, STAIR_UP
|
||||
; items
|
||||
.word COFFER
|
||||
; monsters
|
||||
.word RAT, SPIDER, SERPENT
|
||||
; other
|
||||
; COMPLETE TO GET THE 128 TILES!!!
|
||||
.word UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN
|
||||
.word UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN
|
||||
.word UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN
|
||||
.word UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN
|
||||
.word UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN
|
||||
.word UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN
|
||||
.word UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN
|
||||
.word UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN
|
||||
.word UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN
|
||||
.word UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN
|
||||
.word UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN
|
||||
.word UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN
|
||||
.word UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN
|
||||
.word UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
.import TILES
|
||||
|
||||
.define NB_TILES 8
|
||||
|
||||
|
||||
|
||||
|
|
195
src/world.asm
195
src/world.asm
|
@ -1,195 +0,0 @@
|
|||
|
||||
; Copyright (C) 2018 Christophe Meneboeuf <christophe@xtof.info>
|
||||
;
|
||||
; This program is free software: you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation, either version 3 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
.include "world.inc"
|
||||
.include "tiles.inc"
|
||||
.include "random.inc"
|
||||
.include "math.inc"
|
||||
.include "memory.inc"
|
||||
|
||||
|
||||
|
||||
.export World
|
||||
|
||||
; initializes the world
|
||||
; DESTROYS A,X,Y, ZERO_2_1, ZERO_2_2, ZERO_2_3
|
||||
.export world_init
|
||||
|
||||
; sets the player's position onto the Maze
|
||||
; in: X = x coord in the maze
|
||||
; in: Y = y coord in the maze
|
||||
; out : X and Y as they where given
|
||||
; DESTROYS A,X,Y, ZERO_2_1, ZERO_2_2, ZERO_2_4, ZERO_2_5
|
||||
.export world_set_player
|
||||
|
||||
; Computes the adress corresponding to the coordinates in the maze
|
||||
; in: X = x coord in the maze
|
||||
; in: Y = y coord in the maze
|
||||
; out: AX = Address corresponding to (x,y) in the World array
|
||||
; DESTROYS A,X,Y, ZERO_2_1, ZERO_2_2, ZERO_2_3
|
||||
.export compute_maze_addr
|
||||
|
||||
|
||||
.define TILE_NR ZERO_2_1
|
||||
.define COORD_X ZERO_2_1
|
||||
.define COORD_Y ZERO_2_2
|
||||
.define OFFSET ZERO_2_2
|
||||
|
||||
|
||||
.BSS
|
||||
|
||||
; The tile where the player stands
|
||||
.struct Tile_player_standing
|
||||
addr .word ; adress of the location
|
||||
actor .byte ; actor on the location tile
|
||||
.endstruct
|
||||
|
||||
.CODE
|
||||
|
||||
world_init:
|
||||
; Saving the first tile on which the player stands
|
||||
; FIXME player could be standing anywhere on any type of floor
|
||||
ldx #1
|
||||
ldy #1
|
||||
jsr compute_maze_addr
|
||||
stx Tile_player_standing::addr
|
||||
sta Tile_player_standing::addr+1
|
||||
stx ZERO_2_1
|
||||
sta ZERO_2_1+1
|
||||
ldy #0
|
||||
lda (ZERO_2_1), Y
|
||||
sta Tile_player_standing::actor
|
||||
|
||||
rts
|
||||
|
||||
|
||||
; sets the player's position onto the World
|
||||
world_set_player:
|
||||
|
||||
stx ZERO_2_4
|
||||
sty ZERO_2_5
|
||||
|
||||
; restore the previous tile
|
||||
ldx Tile_player_standing::addr
|
||||
lda Tile_player_standing::addr+1
|
||||
stx ZERO_2_1
|
||||
sta ZERO_2_1+1
|
||||
ldy #0
|
||||
lda Tile_player_standing::actor
|
||||
sta (ZERO_2_1), Y
|
||||
|
||||
; save the next tile
|
||||
ldx ZERO_2_4
|
||||
ldy ZERO_2_5
|
||||
jsr compute_maze_addr ; get's player's position address in memory
|
||||
stx Tile_player_standing::addr
|
||||
sta Tile_player_standing::addr+1
|
||||
stx ZERO_2_1
|
||||
sta ZERO_2_1+1
|
||||
ldy #0
|
||||
lda (ZERO_2_1), y
|
||||
sta Tile_player_standing::actor
|
||||
|
||||
; sets the player on the tile
|
||||
lda #ACTORS::PLAYER
|
||||
sta (ZERO_2_1), y
|
||||
|
||||
; restore the given locations
|
||||
ldx ZERO_2_4
|
||||
ldy ZERO_2_5
|
||||
|
||||
rts
|
||||
|
||||
|
||||
compute_maze_addr:
|
||||
|
||||
stx COORD_X
|
||||
|
||||
; offset due to Y coord
|
||||
sty FAC1
|
||||
lda #WIDTH_WORLD
|
||||
sta FAC2
|
||||
jsr mul8
|
||||
tay ; high part of the mul
|
||||
txa ; low part of the mul
|
||||
|
||||
; adding offset due to X
|
||||
clc
|
||||
adc COORD_X
|
||||
sta OFFSET
|
||||
tya
|
||||
adc #0
|
||||
sta OFFSET+1
|
||||
|
||||
; adding the offset to the address
|
||||
lda #<World
|
||||
clc
|
||||
adc OFFSET
|
||||
tax ; low part of address to be returned in X
|
||||
lda #>World
|
||||
adc OFFSET+1 ; high part of address to be returned in X
|
||||
|
||||
rts
|
||||
|
||||
|
||||
|
||||
.DATA
|
||||
|
||||
.align 256
|
||||
|
||||
World:; .res (WIDTH_WORLD) * (HEIGHT_WORLD)
|
||||
.byte 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06
|
||||
.byte 06, 02, 02, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 06, 06, 06, 02, 02, 02, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06
|
||||
.byte 06, 02, 02, 02, 02, 02, 02, 06, 06, 06, 02, 02, 02, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 02, 02, 02, 06, 06, 06, 06, 06, 02, 02, 02, 06, 06, 02, 02, 02, 02, 02, 02, 02, 06, 06, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 06, 06
|
||||
.byte 06, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 06, 06, 02, 02, 02, 02, 02, 02, 06, 06, 02, 02, 02, 02, 02, 02, 06, 06, 06, 06, 06, 02, 02, 02, 06, 06, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 06, 06, 06, 02, 02, 02, 02, 02, 06, 06
|
||||
.byte 06, 02, 02, 02, 02, 02, 02, 06, 06, 02, 02, 02, 02, 02, 02, 06, 06, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 06, 06, 02, 02, 02, 02, 02, 02, 06, 06, 06, 02, 02, 02, 02, 06, 06, 06, 02, 02, 02, 02, 02, 06, 06
|
||||
.byte 06, 02, 02, 02, 02, 02, 02, 06, 06, 06, 02, 02, 02, 02, 02, 06, 06, 02, 02, 02, 02, 02, 02, 06, 06, 02, 02, 02, 02, 02, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 02, 02, 02, 06, 06, 06, 02, 02, 02, 02, 06, 06, 06, 06, 06, 06, 02, 06, 06, 06
|
||||
.byte 06, 02, 02, 02, 02, 02, 02, 06, 06, 06, 02, 02, 02, 02, 02, 06, 06, 02, 02, 02, 02, 02, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 02, 02, 02, 06, 06, 06, 02, 02, 02, 02, 06, 06, 06, 06, 06, 02, 02, 06, 06, 06
|
||||
.byte 06, 06, 06, 06, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 06, 06, 06, 06, 06, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 06, 06, 06, 06
|
||||
.byte 06, 06, 06, 02, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 06, 06, 06, 06, 06, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 06, 06, 06, 06
|
||||
.byte 06, 06, 06, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 06, 06, 02, 02, 02, 02, 02, 06, 06, 06, 02, 02, 02, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 02, 06, 06, 06
|
||||
.byte 06, 06, 02, 02, 02, 02, 02, 06, 06, 06, 06, 06, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 06, 06, 06, 02, 02, 02, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 02, 02, 02, 06, 06, 06
|
||||
.byte 06, 06, 02, 02, 02, 02, 02, 06, 06, 06, 06, 06, 02, 02, 02, 06, 06, 02, 02, 02, 02, 02, 06, 06, 06, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 06, 02, 02, 02, 02, 06, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 02, 06, 02, 02, 02, 02, 06, 06, 06
|
||||
.byte 06, 06, 02, 02, 02, 02, 02, 06, 06, 06, 06, 06, 02, 02, 02, 06, 06, 02, 02, 02, 02, 02, 06, 06, 06, 06, 06, 02, 06, 06, 06, 06, 06, 06, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 06, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 06, 06, 02, 02, 02, 02, 06, 06, 06
|
||||
.byte 06, 06, 02, 02, 02, 02, 02, 06, 06, 06, 06, 06, 02, 02, 02, 06, 06, 02, 02, 02, 02, 02, 06, 06, 06, 06, 06, 02, 06, 06, 06, 06, 06, 06, 02, 02, 02, 02, 02, 06, 06, 06, 06, 02, 06, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 06, 06, 02, 02, 02, 02, 06, 06, 06
|
||||
.byte 06, 06, 02, 02, 02, 02, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 06, 06, 06, 06, 06, 06, 02, 02, 02, 02, 02, 06, 06, 06, 06, 02, 06, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 06, 06, 02, 02, 02, 02, 06, 06, 06
|
||||
.byte 06, 06, 06, 06, 06, 06, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 06, 06, 06, 06, 06, 06, 02, 02, 02, 06, 06, 06, 06, 06, 06, 02, 06, 06, 06, 06
|
||||
.byte 06, 06, 06, 06, 06, 06, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 06, 06, 06, 06, 06, 06, 02, 06, 06, 06, 06, 06, 06, 06, 06, 02, 06, 06, 06, 06
|
||||
.byte 06, 06, 06, 06, 02, 02, 02, 06, 06, 06, 02, 02, 02, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 02, 02, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 02, 06, 06, 06, 06, 06, 02, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 02, 06, 06
|
||||
.byte 06, 06, 06, 06, 02, 02, 02, 06, 06, 06, 02, 02, 02, 02, 06, 06, 06, 06, 02, 02, 02, 02, 02, 06, 06, 02, 02, 02, 02, 02, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 02, 06, 06, 06, 06, 02, 02, 02, 02, 02, 02, 06, 06, 06, 02, 02, 02, 02, 06, 06
|
||||
.byte 06, 06, 06, 06, 02, 02, 02, 06, 06, 02, 02, 02, 02, 02, 06, 06, 06, 06, 02, 02, 02, 02, 02, 06, 06, 02, 02, 02, 02, 02, 02, 06, 06, 02, 02, 02, 02, 02, 02, 06, 06, 02, 02, 02, 02, 06, 06, 06, 06, 02, 02, 02, 02, 02, 02, 06, 06, 06, 02, 02, 02, 02, 06, 06
|
||||
.byte 06, 06, 06, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 06, 06, 06, 06, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 06, 06, 02, 02, 02, 02, 02, 02, 06, 06, 02, 02, 02, 02, 06, 06, 06, 06, 02, 02, 02, 02, 02, 02, 06, 06, 06, 02, 02, 02, 02, 06, 06
|
||||
.byte 06, 06, 06, 02, 02, 02, 02, 06, 06, 06, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 06, 06, 02, 02, 02, 02, 02, 02, 06, 06, 02, 02, 02, 02, 02, 02, 06, 06, 02, 02, 02, 02, 06, 06, 06, 06, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 06, 06
|
||||
.byte 06, 06, 06, 02, 06, 06, 06, 06, 06, 06, 02, 02, 02, 02, 06, 06, 06, 06, 02, 02, 02, 02, 02, 06, 06, 02, 02, 02, 02, 02, 02, 06, 06, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 02, 06, 06
|
||||
.byte 06, 06, 06, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 06, 06, 06, 06
|
||||
.byte 06, 06, 06, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 06, 06, 06, 06
|
||||
.byte 06, 06, 06, 02, 06, 06, 06, 06, 06, 06, 02, 02, 02, 02, 02, 06, 06, 06, 02, 02, 02, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 06, 06, 06, 06
|
||||
.byte 06, 06, 06, 02, 06, 06, 06, 06, 06, 06, 02, 02, 02, 02, 02, 06, 06, 06, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 06, 06, 06, 06, 02, 02, 02, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 02, 06
|
||||
.byte 06, 02, 02, 02, 02, 06, 06, 06, 06, 06, 02, 02, 02, 02, 02, 06, 06, 02, 02, 02, 02, 02, 06, 06, 02, 02, 02, 02, 02, 02, 02, 06, 06, 06, 06, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 06, 06, 06, 02, 02, 02, 02, 06, 06, 06, 06, 06, 06, 02, 02, 02, 06
|
||||
.byte 06, 02, 02, 02, 02, 06, 06, 06, 06, 06, 02, 02, 02, 02, 02, 06, 06, 02, 02, 02, 02, 02, 06, 06, 02, 02, 02, 02, 02, 02, 02, 06, 06, 06, 06, 02, 02, 02, 02, 06, 06, 06, 02, 02, 02, 02, 02, 06, 06, 06, 02, 02, 02, 02, 06, 06, 06, 06, 06, 06, 02, 02, 02, 06
|
||||
.byte 06, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 06, 06, 02, 06, 06, 06, 06, 06, 06, 02, 02, 02, 02, 02, 02, 02, 06, 06, 06, 06, 02, 02, 02, 02, 06, 06, 06, 02, 02, 02, 02, 02, 06, 06, 06, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 06
|
||||
.byte 06, 06, 02, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 02, 02, 06, 06, 02, 06, 06, 06, 06, 06, 06, 02, 02, 02, 02, 02, 02, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 02, 06, 06, 06, 06, 06, 06, 02, 02, 02, 06
|
||||
.byte 06, 06, 02, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 06, 06
|
||||
.byte 06, 06, 06, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 02, 06
|
||||
.byte 06, 06, 02, 02, 02, 02, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 02, 02, 02, 06, 06, 06, 06, 06, 02, 06, 06, 06, 06, 06, 02, 02, 02, 02, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 06
|
||||
.byte 06, 06, 02, 02, 02, 02, 02, 06, 06, 06, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 06, 06, 02, 02, 02, 02, 06, 06, 06, 06, 06, 02, 02, 02, 02, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 06
|
||||
.byte 06, 06, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 06, 02, 02, 02, 02, 02, 02, 06, 06, 02, 02, 02, 02, 06, 06, 06, 06, 06, 02, 02, 02, 02, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 06
|
||||
.byte 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 02, 02, 06, 06, 02, 02, 02, 02, 02, 02, 06, 06, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 06, 06, 06, 02, 02, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06
|
||||
.byte 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 02, 02, 06, 06, 02, 02, 02, 02, 02, 02, 06, 06, 02, 02, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 06, 06, 06, 06, 06, 06, 06
|
||||
.byte 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 02, 02, 02, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 02, 02, 02, 02, 02, 02, 06, 06, 06, 02, 02, 02, 06, 06, 06
|
||||
.byte 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
; The world contains a Maze, filled with Actors
|
||||
; Actors can be static, such a a floor or a wall,
|
||||
; dynamic such as a door
|
||||
; or alive, such as a monster
|
||||
|
||||
|
||||
.define WIDTH_MAZE 64
|
||||
.define HEIGHT_MAZE 40
|
||||
.define SIZE_BORDER 0
|
||||
.define WIDTH_WORLD WIDTH_MAZE + 2*SIZE_BORDER
|
||||
.define HEIGHT_WORLD HEIGHT_MAZE + 2*SIZE_BORDER
|
||||
|
||||
|
||||
.enum ACTORS
|
||||
|
||||
PLAYER = 0
|
||||
|
||||
FLOOR_BLACK = 1
|
||||
FLOOR_ORANGE
|
||||
FLOOR_VIOLET
|
||||
FLOOR_BLUE
|
||||
WALKABLE = FLOOR_BLUE ; Player won't be allowed to go on anything > WALKABLE
|
||||
|
||||
NOT_WALKABLE
|
||||
NOT_TRANSPARENT = NOT_WALKABLE
|
||||
WALL_1 = NOT_WALKABLE
|
||||
WALL_2
|
||||
|
||||
UNKNOWN
|
||||
|
||||
NB_ACTORS
|
||||
|
||||
.endenum
|
228
src/world/level.asm
Normal file
228
src/world/level.asm
Normal file
|
@ -0,0 +1,228 @@
|
|||
|
||||
; Copyright (C) 2021 Christophe Meneboeuf <christophe@xtof.info>
|
||||
;
|
||||
; This program is free software: you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation, either version 3 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
.include "../common.inc"
|
||||
.include "../memory.inc"
|
||||
.include "../random.inc"
|
||||
.include "../math.inc"
|
||||
.include "../actors/actors.inc"
|
||||
.include "../builder/builder.inc"
|
||||
.include "../io/files.inc"
|
||||
.include "level_private.inc"
|
||||
|
||||
; code
|
||||
.export levels_init
|
||||
.export level_enter
|
||||
.export level_exit
|
||||
.export level_get_config_offset
|
||||
.export level_reset_states
|
||||
; data
|
||||
.export LevelConfigs
|
||||
.export NbLevels
|
||||
.export CurrentLevel
|
||||
.export NextLevel
|
||||
.export ExitLevel
|
||||
.export LevelIsBuilt
|
||||
|
||||
.import player_init
|
||||
.import ActorsInLevel
|
||||
.import ActorPositions
|
||||
.import World
|
||||
|
||||
.BSS
|
||||
|
||||
CurrentLevel: .res 1
|
||||
NbLevels: .res 1
|
||||
NextLevel: .res 1
|
||||
ExitLevel: .res 1
|
||||
LevelIsBuilt: .res 1
|
||||
|
||||
|
||||
LevelConfigs: .res 1 + NB_LEVELS * SIZEOF_CONF_LEVEL
|
||||
|
||||
|
||||
.segment "CODE2"
|
||||
|
||||
|
||||
.define ACCUMULATOR ZERO_9_4 ; 2 bytes
|
||||
|
||||
; @param LevelNr in X
|
||||
_Set_Params_LoadSaveLevelActors:
|
||||
|
||||
; compute offset in file
|
||||
lda #0
|
||||
sta ACCUMULATOR
|
||||
sta ACCUMULATOR+1
|
||||
beq end_loop_offset
|
||||
loop_offset: ; accumulating offsets
|
||||
clc
|
||||
lda ACCUMULATOR
|
||||
adc #<(SIZEOF_ACTORS_T)
|
||||
sta ACCUMULATOR
|
||||
lda ACCUMULATOR+1
|
||||
adc #>(SIZEOF_ACTORS_T)
|
||||
sta ACCUMULATOR+1
|
||||
dex
|
||||
bne loop_offset
|
||||
end_loop_offset:
|
||||
; set function parameters
|
||||
sta Param_FileOffset+3
|
||||
lda ACCUMULATOR
|
||||
sta Param_FileOffset+2
|
||||
lda #<Str_FileLevelsActors
|
||||
sta Param_FileOpen+1
|
||||
lda #>Str_FileLevelsActors
|
||||
sta Param_FileOpen+2
|
||||
lda #<ActorsInLevel
|
||||
sta Param_FilesReadWrite+2
|
||||
lda #>ActorsInLevel
|
||||
sta Param_FilesReadWrite+3
|
||||
|
||||
rts
|
||||
|
||||
|
||||
.define NR_LEVELS ZERO_4_1
|
||||
levels_init:
|
||||
|
||||
; file path
|
||||
lda #<Str_FileLevelConfs
|
||||
sta Param_FileOpen+1
|
||||
lda #>Str_FileLevelConfs
|
||||
sta Param_FileOpen+2
|
||||
; read buffer
|
||||
lda #0
|
||||
sta Param_FileOffset+2
|
||||
sta Param_FileOffset+3
|
||||
sta Param_FileOffset+4
|
||||
lda #<LevelConfigs
|
||||
sta Param_FilesReadWrite+2
|
||||
lda #>LevelConfigs
|
||||
sta Param_FilesReadWrite+3
|
||||
lda #<(1 + SIZEOF_CONF_LEVEL * NB_LEVELS)
|
||||
sta Param_FilesReadWrite+4
|
||||
lda #>(1 + SIZEOF_CONF_LEVEL * NB_LEVELS)
|
||||
sta Param_FilesReadWrite+5
|
||||
|
||||
; load
|
||||
jsr ReadFile
|
||||
|
||||
; exploit
|
||||
lda LevelConfigs
|
||||
sta NbLevels
|
||||
sta NR_LEVELS
|
||||
inc NR_LEVELS
|
||||
|
||||
; global vars
|
||||
lda #0
|
||||
sta CurrentLevel
|
||||
sta NextLevel
|
||||
lda #FALSE
|
||||
sta ExitLevel
|
||||
|
||||
rts
|
||||
|
||||
|
||||
|
||||
; @param: Uses NextLevel as level number
|
||||
.define LEVEL_STATE_OFFSET ZERO_9_1
|
||||
.define ADDR_LEVEL_CONF ZERO_9_2 ; 2 bytes
|
||||
level_enter:
|
||||
|
||||
lda NextLevel
|
||||
jsr LoadState
|
||||
|
||||
lda LevelIsBuilt
|
||||
cmp #TRUE
|
||||
beq level_was_built
|
||||
|
||||
level_generation:
|
||||
|
||||
; compute offset to level config
|
||||
lda NextLevel
|
||||
jsr level_get_config_offset
|
||||
pha
|
||||
clc
|
||||
txa
|
||||
adc #<LevelConfigs
|
||||
sta ADDR_LEVEL_CONF
|
||||
pla
|
||||
adc #>LevelConfigs
|
||||
sta ADDR_LEVEL_CONF+1
|
||||
|
||||
; init maze size
|
||||
ldy #1
|
||||
lda (ADDR_LEVEL_CONF), Y ; size
|
||||
tax
|
||||
tay
|
||||
jsr Init_Dimensions_Maze
|
||||
|
||||
; player position returned in X and Y
|
||||
jsr Build_Level
|
||||
jsr player_init ; param: player pos in X and Y
|
||||
|
||||
level_was_built:
|
||||
|
||||
ldx ActorPositions + eACTORTYPES::PLAYER
|
||||
ldy ActorPositions + eACTORTYPES::PLAYER + 1
|
||||
jsr player_init
|
||||
|
||||
level_enter_end:
|
||||
|
||||
lda #FALSE
|
||||
sta ExitLevel
|
||||
|
||||
lda NextLevel
|
||||
sta CurrentLevel
|
||||
|
||||
rts
|
||||
|
||||
|
||||
.define Player_XY ActorPositions + eACTORTYPES::PLAYER
|
||||
level_exit:
|
||||
|
||||
lda CurrentLevel
|
||||
jsr SaveState
|
||||
|
||||
rts
|
||||
|
||||
; @param Level_Nr in A
|
||||
; @return Config offset for the level in X
|
||||
level_get_config_offset:
|
||||
|
||||
sta FAC1
|
||||
ldx #SIZEOF_CONF_LEVEL
|
||||
stx FAC2
|
||||
jsr mul8
|
||||
; first byte of conf is the number of levels
|
||||
pha
|
||||
clc
|
||||
txa
|
||||
adc #1
|
||||
tax
|
||||
pla
|
||||
adc #0
|
||||
|
||||
rts
|
||||
|
||||
; @brief reset the states of all levels
|
||||
level_reset_states:
|
||||
|
||||
lda #0
|
||||
sta CurrentLevel
|
||||
lda #NB_LEVELS
|
||||
jsr ResetIsBuilt
|
||||
|
||||
rts
|
55
src/world/level.inc
Normal file
55
src/world/level.inc
Normal file
|
@ -0,0 +1,55 @@
|
|||
; Copyright (C) 2021 Christophe Meneboeuf <christophe@xtof.info>
|
||||
;
|
||||
; This program is free software: you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation, either version 3 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
|
||||
.import levels_init
|
||||
.import level_enter ; param: A = level_nr
|
||||
.import level_exit
|
||||
.import level_get_config_offset
|
||||
|
||||
.import CurrentLevel
|
||||
.import NextLevel
|
||||
.import ExitLevel
|
||||
.import LevelConfigs
|
||||
.import NbLevels
|
||||
|
||||
.enum LEVELSIZE
|
||||
TINY = 20
|
||||
SMALL = 24
|
||||
NORMAL = 32
|
||||
BIG = 48
|
||||
HUGE = 64
|
||||
.endenum
|
||||
|
||||
|
||||
; struct Level
|
||||
; {
|
||||
; uint8_t is_built;
|
||||
; uint8_t seed[4]; //< seed used to build the level
|
||||
; coords_t pos_player_enter; //< position of player when entering the level (x,y)
|
||||
; }
|
||||
;
|
||||
|
||||
; nb_levels >>>> ALWAYS OFFSET + 1!!! <<<<
|
||||
; array [
|
||||
; struct LevelsConf
|
||||
; {
|
||||
; uint8_t level_nr;
|
||||
; uint8_t size; //< eLEVELSIZE
|
||||
; uint8_t actors[NB_ACTORS_MAX]; //< number of actors of each kind added in the level after building the maze
|
||||
; }
|
||||
; ]
|
||||
|
25
src/world/level_private.inc
Normal file
25
src/world/level_private.inc
Normal file
|
@ -0,0 +1,25 @@
|
|||
; Copyright (C) 2021 Christophe Meneboeuf <christophe@xtof.info>
|
||||
;
|
||||
; This program is free software: you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation, either version 3 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
|
||||
; BEWARE: NB_LEVELS * SIZEOF_STATE_LEVEL shall not be > 256
|
||||
.define SIZEOF_STATE_LEVEL 7
|
||||
|
||||
.define SIZEOF_CONF_LEVEL 130 ;( NB_ACTORS_MAX + 2 )
|
||||
.define NB_LEVELS 3
|
||||
|
||||
|
||||
|
175
src/world/world.asm
Normal file
175
src/world/world.asm
Normal file
|
@ -0,0 +1,175 @@
|
|||
|
||||
; Copyright (C) 2018 Christophe Meneboeuf <christophe@xtof.info>
|
||||
;
|
||||
; This program is free software: you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation, either version 3 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
.include "world.inc"
|
||||
.include "../common.inc"
|
||||
.include "../actors/actors.inc"
|
||||
.include "../tiles.inc"
|
||||
.include "../random.inc"
|
||||
.include "../math.inc"
|
||||
.include "../memory.inc"
|
||||
|
||||
|
||||
.export World
|
||||
|
||||
; initializes the world
|
||||
; DESTROYS A,X,Y, ZERO_2_1, ZERO_2_2, ZERO_2_3
|
||||
.export world_init
|
||||
|
||||
; sets the player's position onto the Maze
|
||||
; in: X = x coord in the maze
|
||||
; in: Y = y coord in the maze
|
||||
; out : X and Y as they where given
|
||||
; DESTROYS A,X,Y, ZERO_2_1, ZERO_2_2, ZERO_2_4, ZERO_2_5
|
||||
.export world_set_player
|
||||
|
||||
; Computes the adress corresponding to the coordinates in the maze
|
||||
; in: X = x coord in the maze
|
||||
; in: Y = y coord in the maze
|
||||
; out: AX = Address corresponding to (x,y) in the World array
|
||||
; DESTROYS A,X,Y, ZERO_2_1, ZERO_2_2, ZERO_2_3
|
||||
.export Compute_Maze_Addr
|
||||
|
||||
; #TRUE if an object has been picked by the player
|
||||
.export World_PickedObject
|
||||
|
||||
.export Tile_player_standing_actor
|
||||
|
||||
.define COORD_X ZERO_2_1
|
||||
.define COORD_Y ZERO_2_2
|
||||
.define OFFSET ZERO_2_2
|
||||
|
||||
|
||||
.BSS
|
||||
|
||||
; The tile where the player stands
|
||||
; The two memory locations must be adjacent
|
||||
Tile_player_standing_addr: .res 2
|
||||
Tile_player_standing_actor: .res 1
|
||||
|
||||
.DATA
|
||||
|
||||
World_PickedObject: .byte 0
|
||||
|
||||
.CODE
|
||||
|
||||
; @param X Player's x
|
||||
; @param Y Player's y
|
||||
world_init:
|
||||
; Saving the first tile on which the player stands
|
||||
; FIXME player could be standing anywhere on any type of floor
|
||||
jsr Compute_Maze_Addr
|
||||
stx Tile_player_standing_addr
|
||||
sta Tile_player_standing_addr+1
|
||||
|
||||
lda Tile_player_standing_actor
|
||||
cmp #UNDEF
|
||||
bne world_init_end
|
||||
lda #eACTORTYPES::FLOOR_2
|
||||
sta Tile_player_standing_actor
|
||||
|
||||
world_init_end:
|
||||
rts
|
||||
|
||||
|
||||
; sets the player's position onto the World
|
||||
.define PLAYER_XY ZERO_2_1; 2 bytes
|
||||
.define NEXT_TILE_XY ZERO_2_4 ; 2 bytes
|
||||
world_set_player:
|
||||
|
||||
stx NEXT_TILE_XY
|
||||
sty NEXT_TILE_XY+1
|
||||
|
||||
; restore the previous tile
|
||||
ldx Tile_player_standing_addr
|
||||
lda Tile_player_standing_addr+1
|
||||
stx PLAYER_XY
|
||||
sta PLAYER_XY+1
|
||||
ldy #0
|
||||
lda Tile_player_standing_actor
|
||||
sta (PLAYER_XY), Y
|
||||
|
||||
; save the next tile
|
||||
ldx NEXT_TILE_XY
|
||||
ldy NEXT_TILE_XY+1
|
||||
jsr Compute_Maze_Addr ; get's player's position address in memory
|
||||
stx Tile_player_standing_addr
|
||||
sta Tile_player_standing_addr+1
|
||||
stx PLAYER_XY
|
||||
sta PLAYER_XY+1
|
||||
ldy #0
|
||||
lda (PLAYER_XY), y
|
||||
sta Tile_player_standing_actor
|
||||
; if an object was picked
|
||||
; override to force save a floor tile
|
||||
lda World_PickedObject
|
||||
cmp #TRUE
|
||||
bne no_object_picked
|
||||
lda #eACTORTYPES::FLOOR_2
|
||||
sta Tile_player_standing_actor
|
||||
lda #FALSE
|
||||
sta World_PickedObject
|
||||
no_object_picked:
|
||||
|
||||
; sets the player on the tile
|
||||
lda #eACTORTYPES::PLAYER
|
||||
sta (PLAYER_XY), y
|
||||
|
||||
; restore the given locations
|
||||
ldx NEXT_TILE_XY
|
||||
ldy NEXT_TILE_XY+1
|
||||
|
||||
rts
|
||||
|
||||
; Destroys ZERO_2_1, ZERO_2_2, ZERO_2_3 ZERO_7_1 and ZERO_7_2
|
||||
Compute_Maze_Addr:
|
||||
|
||||
stx COORD_X
|
||||
|
||||
; offset due to Y coord
|
||||
sty FAC1
|
||||
lda #WIDTH_WORLD
|
||||
sta FAC2
|
||||
jsr mul8
|
||||
tay ; high part of the mul
|
||||
txa ; low part of the mul
|
||||
|
||||
; adding offset due to X
|
||||
clc
|
||||
adc COORD_X
|
||||
sta OFFSET
|
||||
tya
|
||||
adc #0
|
||||
sta OFFSET+1
|
||||
|
||||
; adding the offset to the address
|
||||
lda #<World
|
||||
clc
|
||||
adc OFFSET
|
||||
tax ; low part of address to be returned in X
|
||||
lda #>World
|
||||
adc OFFSET+1 ; high part of address to be returned in A
|
||||
|
||||
rts
|
||||
|
||||
|
||||
|
||||
.BSS
|
||||
|
||||
.align 256
|
||||
|
||||
World: .res (WIDTH_WORLD) * (HEIGHT_WORLD)
|
31
src/world/world.inc
Normal file
31
src/world/world.inc
Normal file
|
@ -0,0 +1,31 @@
|
|||
; Copyright (C) 2018-2021 Christophe Meneboeuf <christophe@xtof.info>
|
||||
;
|
||||
; This program is free software: you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation, either version 3 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
|
||||
|
||||
; The world contains a Maze, filled with Actors
|
||||
; Actors can be static, such a a floor or a wall,
|
||||
; dynamic such as a door
|
||||
; or alive, such as a monster
|
||||
|
||||
|
||||
.define MAXIMUM_WIDTH_MAZE 64 ; must be a power of 2
|
||||
.define MAXIMUM_HEIGHT_MAZE 64 ; must be a power of 2
|
||||
.define WIDTH_WORLD 64
|
||||
.define NEG_WIDTH_WORLD $C0
|
||||
.define HEIGHT_WORLD 64
|
||||
.define NEG_HEIGHT_WORLD $C0
|
||||
|
Loading…
Reference in New Issue
Block a user