working animation, but ugly
This commit is contained in:
		
							parent
							
								
									f3fd560eae
								
							
						
					
					
						commit
						aa5b06312e
					
				
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -1 +1,2 @@
 | 
			
		|||
build
 | 
			
		||||
*.swp
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										3
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								Makefile
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -9,8 +9,9 @@ BUILD=./build
 | 
			
		|||
ENTRY=${SRC}/main.asm
 | 
			
		||||
ROM_OUTPUT=${BUILD}/${NAME}.gb
 | 
			
		||||
OBJECT_OUTPUT=${BUILD}/${NAME}.o
 | 
			
		||||
SYMFILE_OUTPUT=${BUILD}/${NAME}.sym
 | 
			
		||||
 | 
			
		||||
all : ${ENTRY}
 | 
			
		||||
	${ASSEMBLER} -o ${OBJECT_OUTPUT} ${ENTRY} \
 | 
			
		||||
		&& ${LINKER} -o ${ROM_OUTPUT} -n ${NAME}.sym ${OBJECT_OUTPUT} \
 | 
			
		||||
		&& ${LINKER} -o ${ROM_OUTPUT} -n ${SYMFILE_OUTPUT} ${OBJECT_OUTPUT} \
 | 
			
		||||
		&& ${POSTPROC} -v -p 0 ${ROM_OUTPUT}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,54 +0,0 @@
 | 
			
		|||
; File generated by rgblink
 | 
			
		||||
 | 
			
		||||
00:0634 parecivo_tile_data
 | 
			
		||||
00:0234 Map
 | 
			
		||||
00:01F8 CheckBoundry
 | 
			
		||||
00:01E5 game_loop
 | 
			
		||||
00:0230 CheckBoundry.skipRender
 | 
			
		||||
00:021E CheckBoundry.swap
 | 
			
		||||
00:022C CheckBoundry.render
 | 
			
		||||
00:0150 Start
 | 
			
		||||
00:0017 dPlayerHeight
 | 
			
		||||
00:0016 dPlayerWidth
 | 
			
		||||
00:0018 dPlayerSpriteTiles
 | 
			
		||||
00:0008 CopyDMARoutine
 | 
			
		||||
00:0004 DMARoutine.wait
 | 
			
		||||
00:0000 DMARoutine
 | 
			
		||||
00:0008 DMARoutine.end
 | 
			
		||||
00:000F CopyDMARoutine.copy
 | 
			
		||||
00:0853 Read_Pad
 | 
			
		||||
00:084A MemCpy.copy
 | 
			
		||||
00:0883 Read_Pad.onenibble
 | 
			
		||||
00:086C Read_Pad.legalUpDown
 | 
			
		||||
00:0875 Read_Pad.legalLeftRight
 | 
			
		||||
00:084A MemCpy
 | 
			
		||||
00:0744 Wait_VBlank
 | 
			
		||||
00:0816 Clear_Map
 | 
			
		||||
00:0824 Load_Tiles
 | 
			
		||||
00:07D7 PC_Update
 | 
			
		||||
00:0750 Player_To_OAM
 | 
			
		||||
00:0747 Wait_VBlank.wait
 | 
			
		||||
00:07D1 Player_To_OAM.add4hl
 | 
			
		||||
00:0762 Player_To_OAM.finner
 | 
			
		||||
00:075E Player_To_OAM.fouter
 | 
			
		||||
00:0786 Player_To_OAM.sinner
 | 
			
		||||
00:077B Player_To_OAM.souter
 | 
			
		||||
00:07A5 Player_To_OAM.tloop1
 | 
			
		||||
00:07AA Player_To_OAM.tloop2
 | 
			
		||||
00:07C1 Player_To_OAM.lloop1
 | 
			
		||||
00:07C6 Player_To_OAM.lloop2
 | 
			
		||||
00:07E6 PC_Update.up
 | 
			
		||||
00:07F1 PC_Update.left
 | 
			
		||||
00:07FC PC_Update.right
 | 
			
		||||
00:0807 PC_Update.last
 | 
			
		||||
00:081D Clear_Map.loop
 | 
			
		||||
00:C005 rPlayerX
 | 
			
		||||
00:C006 rPlayerY
 | 
			
		||||
00:C004 ANS
 | 
			
		||||
00:C002 N
 | 
			
		||||
00:C000 X
 | 
			
		||||
00:C100 wShadowOAM
 | 
			
		||||
00:FF88 hVBlankFlag
 | 
			
		||||
00:FF89 hCurKeys
 | 
			
		||||
00:FF8A hNewKeys
 | 
			
		||||
00:FF80 hOAMDMA
 | 
			
		||||
							
								
								
									
										367
									
								
								inc/structs.asm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										367
									
								
								inc/structs.asm
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,367 @@
 | 
			
		|||
 | 
			
		||||
; MIT License
 | 
			
		||||
;
 | 
			
		||||
; Copyright (c) 2018-2019 Eldred Habert
 | 
			
		||||
; Originally hosted at https://github.com/ISSOtm/rgbds-structs
 | 
			
		||||
;
 | 
			
		||||
; Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
; of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
; in the Software without restriction, including without limitation the rights
 | 
			
		||||
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
; copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
; furnished to do so, subject to the following conditions:
 | 
			
		||||
;
 | 
			
		||||
; The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
; copies or substantial portions of the Software.
 | 
			
		||||
;
 | 
			
		||||
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
; SOFTWARE.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
; !!! WARNING ABOUT READABILITY OF THIS CODE !!!
 | 
			
		||||
;
 | 
			
		||||
; RGBDS, being the venerable/old/decrepit (pick on depending on mood) assembler that it is, requires
 | 
			
		||||
; all label, variable etc. definitions to be on column 0. As in, no whitespace allowed (otherwise, syntax error)
 | 
			
		||||
; Meanwhile, these macros tend to use a lot of nesting (requiring indenting for readability),
 | 
			
		||||
; as well as variable definitions (requiring none to work).
 | 
			
		||||
; As you can probably tell, those two conflict and result in very poor readability
 | 
			
		||||
; Sadly, there is nothing I can do against that short of using a special preprocessor,
 | 
			
		||||
; which I refuse to do for usability's sake.
 | 
			
		||||
; You have all my apologies, how little they may matter, if you are trying to read this code
 | 
			
		||||
; I still did my best to use explicit comments and variable names, hope they will help!
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
; strreplace variable_name, original_char, new_char
 | 
			
		||||
strreplace: MACRO
 | 
			
		||||
DOT_POS = STRIN("{\1}", \2)
 | 
			
		||||
    IF DOT_POS != 0
 | 
			
		||||
TMP equs STRCAT(STRSUB("{\1}", 1, DOT_POS + (-1)), STRCAT(\3, STRSUB("{\1}", DOT_POS + 1, STRLEN("{\1}") - DOT_POS)))
 | 
			
		||||
        PURGE \1
 | 
			
		||||
\1 equs "{TMP}"
 | 
			
		||||
        PURGE TMP
 | 
			
		||||
        strreplace \1, \2, \3
 | 
			
		||||
    ENDC
 | 
			
		||||
    IF DEF(DOT_POS)
 | 
			
		||||
        PURGE DOT_POS
 | 
			
		||||
    ENDC
 | 
			
		||||
ENDM
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
; rgbds_structs_version version_string
 | 
			
		||||
; Call with the expected version string to ensure you're using a compatible version
 | 
			
		||||
; Example: rgbds_structs_version 1.0.0
 | 
			
		||||
rgbds_structs_version: MACRO
 | 
			
		||||
CURRENT_VERSION equs "1,2,1"
 | 
			
		||||
EXPECTED_VERSION equs "\1"
 | 
			
		||||
    strreplace EXPECTED_VERSION, ".", "\,"
 | 
			
		||||
check_ver: MACRO
 | 
			
		||||
    IF \1 != \4 || \2 > \5 || \3 > \6
 | 
			
		||||
        PURGE EXPECTED_VERSION
 | 
			
		||||
    ENDC
 | 
			
		||||
ENDM
 | 
			
		||||
 | 
			
		||||
CHECK_VER_CALL equs "check_ver {EXPECTED_VERSION},{CURRENT_VERSION}"
 | 
			
		||||
    CHECK_VER_CALL
 | 
			
		||||
    IF !DEF(EXPECTED_VERSION)
 | 
			
		||||
        strreplace CURRENT_VERSION, "\,", "."
 | 
			
		||||
        FAIL "RGBDS-structs version \1 is required, which is incompatible with current version {CURRENT_VERSION}"
 | 
			
		||||
    ENDC
 | 
			
		||||
    PURGE CHECK_VER_CALL
 | 
			
		||||
    PURGE check_ver
 | 
			
		||||
    PURGE CURRENT_VERSION
 | 
			
		||||
    PURGE EXPECTED_VERSION
 | 
			
		||||
ENDM
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
; struct struct_name
 | 
			
		||||
; Begins a struct declaration
 | 
			
		||||
struct: MACRO
 | 
			
		||||
    IF DEF(NB_FIELDS)
 | 
			
		||||
        FAIL "Please close struct definitions using `end_struct`"
 | 
			
		||||
    ENDC
 | 
			
		||||
 | 
			
		||||
STRUCT_NAME equs "\1"
 | 
			
		||||
 | 
			
		||||
NB_FIELDS = 0
 | 
			
		||||
    RSRESET
 | 
			
		||||
ENDM
 | 
			
		||||
 | 
			
		||||
; end_struct
 | 
			
		||||
; Ends a struct declaration
 | 
			
		||||
end_struct: MACRO
 | 
			
		||||
    ; Set nb of fields
 | 
			
		||||
STRUCT_NB_FIELDS equs "{STRUCT_NAME}_nb_fields"
 | 
			
		||||
STRUCT_NB_FIELDS = NB_FIELDS
 | 
			
		||||
    PURGE STRUCT_NB_FIELDS
 | 
			
		||||
 | 
			
		||||
    ; Set size of struct
 | 
			
		||||
STRUCT_SIZEOF equs "sizeof_{STRUCT_NAME}"
 | 
			
		||||
STRUCT_SIZEOF RB 0
 | 
			
		||||
    PURGE STRUCT_SIZEOF
 | 
			
		||||
 | 
			
		||||
    PURGE NB_FIELDS
 | 
			
		||||
    PURGE STRUCT_NAME
 | 
			
		||||
ENDM
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
; get_nth_field_info field_id
 | 
			
		||||
; Defines EQUS strings pertaining to a struct's Nth field
 | 
			
		||||
; For internal use, please do not use externally
 | 
			
		||||
get_nth_field_info: MACRO
 | 
			
		||||
    ; Field's name
 | 
			
		||||
STRUCT_FIELD equs "{STRUCT_NAME}_field{d:\1}"
 | 
			
		||||
STRUCT_FIELD_NAME equs "{STRUCT_FIELD}_name"
 | 
			
		||||
STRUCT_FIELD_TYPE equs "{STRUCT_FIELD}_type"
 | 
			
		||||
STRUCT_FIELD_NBEL equs "{STRUCT_FIELD}_nb_el" ; Number of elements
 | 
			
		||||
STRUCT_FIELD_SIZE equs "{STRUCT_FIELD}_size" ; sizeof(type) * nb_el
 | 
			
		||||
ENDM
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
; new_field nb_elems, rs_type, field_name
 | 
			
		||||
; For internal use, please do not use externally
 | 
			
		||||
new_field: MACRO
 | 
			
		||||
    IF !DEF(STRUCT_NAME) || !DEF(NB_FIELDS)
 | 
			
		||||
        FAIL "Please start defining a struct, using `define_struct`"
 | 
			
		||||
    ENDC
 | 
			
		||||
 | 
			
		||||
    get_nth_field_info NB_FIELDS
 | 
			
		||||
    ; Set field name (keep in mind `STRUCT_FIELD_NAME` is *itself* an EQUS!)
 | 
			
		||||
STRUCT_FIELD_NAME equs "\"\3\""
 | 
			
		||||
    PURGE STRUCT_FIELD_NAME
 | 
			
		||||
 | 
			
		||||
    ; Set field offset
 | 
			
		||||
STRUCT_FIELD \2 (\1)
 | 
			
		||||
    ; Alias this in a human-comprehensive manner
 | 
			
		||||
STRUCT_FIELD_NAME equs "{STRUCT_NAME}_\3"
 | 
			
		||||
STRUCT_FIELD_NAME = STRUCT_FIELD
 | 
			
		||||
 | 
			
		||||
    ; Compute field size
 | 
			
		||||
CURRENT_RS RB 0
 | 
			
		||||
STRUCT_FIELD_SIZE = CURRENT_RS - STRUCT_FIELD
 | 
			
		||||
 | 
			
		||||
    ; Set properties
 | 
			
		||||
STRUCT_FIELD_NBEL = \1
 | 
			
		||||
STRUCT_FIELD_TYPE equs STRSUB("\2", 2, 1)
 | 
			
		||||
 | 
			
		||||
    PURGE STRUCT_FIELD
 | 
			
		||||
    PURGE STRUCT_FIELD_NAME
 | 
			
		||||
    PURGE STRUCT_FIELD_TYPE
 | 
			
		||||
    PURGE STRUCT_FIELD_NBEL
 | 
			
		||||
    PURGE STRUCT_FIELD_SIZE
 | 
			
		||||
    PURGE CURRENT_RS
 | 
			
		||||
 | 
			
		||||
NB_FIELDS = NB_FIELDS + 1
 | 
			
		||||
ENDM
 | 
			
		||||
 | 
			
		||||
; bytes nb_bytes, field_name
 | 
			
		||||
; Defines a field of N bytes
 | 
			
		||||
bytes: MACRO
 | 
			
		||||
    new_field \1, RB, \2
 | 
			
		||||
ENDM
 | 
			
		||||
 | 
			
		||||
; words nb_words, field_name
 | 
			
		||||
; Defines a field of N*2 bytes
 | 
			
		||||
words: MACRO
 | 
			
		||||
    new_field \1, RW, \2
 | 
			
		||||
ENDM
 | 
			
		||||
 | 
			
		||||
; longs nb_longs, field_name
 | 
			
		||||
; Defines a field of N*4 bytes
 | 
			
		||||
longs: MACRO
 | 
			
		||||
    new_field \1, RL, \2
 | 
			
		||||
ENDM
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
; dstruct struct_type, INSTANCE_NAME[, ...]
 | 
			
		||||
; Allocates space for a struct in memory
 | 
			
		||||
; If no further arguments are supplied, the space is simply allocated (using `ds`)
 | 
			
		||||
; Otherwise, the data is written to memory using the appropriate types
 | 
			
		||||
; For example, a struct defined with `bytes 1, Field1` and `words 3, Field2` would have four extra arguments, one byte then three words.
 | 
			
		||||
dstruct: MACRO
 | 
			
		||||
NB_FIELDS equs "\1_nb_fields"
 | 
			
		||||
    IF !DEF(NB_FIELDS)
 | 
			
		||||
        FAIL "Struct \1 isn't defined!"
 | 
			
		||||
    ELIF _NARG != 2 && _NARG != NB_FIELDS + 2 ; We must have either a RAM declaration (no data args) or a ROM one (RAM args + data args)
 | 
			
		||||
EXPECTED_NARG = 2 + NB_FIELDS
 | 
			
		||||
        FAIL "Invalid number of arguments, expected 2 or {d:EXPECTED_NARG} but got {d:_NARG}"
 | 
			
		||||
    ENDC
 | 
			
		||||
 | 
			
		||||
    ; Define the two fields required by `get_nth_field_info`
 | 
			
		||||
STRUCT_NAME   equs "\1" ; Which struct `get_nth_field_info` should pull info about
 | 
			
		||||
INSTANCE_NAME equs "\2" ; The instance's base name
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    ; RGBASM always expands `\X` macro args, so `IF _NARG > 2 && STRIN("\3", "=")` will error out when there are only 2 args
 | 
			
		||||
    ; Therefore, the condition is checked here (we can't nest the `IF`s over there because that doesn't translate well to `ELSE`)
 | 
			
		||||
IS_NAMED_INVOCATION = 0
 | 
			
		||||
    IF _NARG > 2
 | 
			
		||||
        IF STRIN("\3", "=")
 | 
			
		||||
IS_NAMED_INVOCATION = 1
 | 
			
		||||
        ENDC
 | 
			
		||||
    ENDC
 | 
			
		||||
 | 
			
		||||
    IF IS_NAMED_INVOCATION
 | 
			
		||||
        ; This is a named instantiation, translate that to an ordered one
 | 
			
		||||
        ; This is needed because data has to be laid out in order, so some translation is needed anyways
 | 
			
		||||
        ; And finally, it's better to re-use the existing code at the cost of a single nested macro, I believe
 | 
			
		||||
MACRO_CALL equs "dstruct \1, \2" ; This will be used later, but define it now because `SHIFT` will be run
 | 
			
		||||
        ; In practice `SHIFT` has no effect outside of one when invoked inside of a REPT block, but I hope this behavior is changed (causes a problem elsewhere)
 | 
			
		||||
 | 
			
		||||
ARG_NUM = 3
 | 
			
		||||
        REPT NB_FIELDS
 | 
			
		||||
            ; Find out which argument the current one is
 | 
			
		||||
CUR_ARG equs "\3"
 | 
			
		||||
            ; Remove all whitespace to obtain something like ".name=value" (whitespace are unnecessary and complexify parsing)
 | 
			
		||||
            strreplace CUR_ARG, " ",  ""
 | 
			
		||||
            strreplace CUR_ARG, "\t", ""
 | 
			
		||||
 | 
			
		||||
EQUAL_POS = STRIN("{CUR_ARG}", "=")
 | 
			
		||||
            IF EQUAL_POS == 0
 | 
			
		||||
                FAIL "Argument #{ARG_NUM} (\3) does not contain an equal sign in this named instantiation"
 | 
			
		||||
            ELIF STRCMP(STRSUB("{CUR_ARG}", 1, 1), ".")
 | 
			
		||||
                FAIL "Argument #{ARG_NUM} (\3) does not start with a period"
 | 
			
		||||
            ENDC
 | 
			
		||||
 | 
			
		||||
FIELD_ID = -1
 | 
			
		||||
CUR_FIELD_ID = 0
 | 
			
		||||
            REPT NB_FIELDS
 | 
			
		||||
 | 
			
		||||
                ; Get the name of the Nth field and compare
 | 
			
		||||
TMP equs "{STRUCT_NAME}_field{d:CUR_FIELD_ID}_name"
 | 
			
		||||
CUR_FIELD_NAME equs TMP
 | 
			
		||||
                PURGE TMP
 | 
			
		||||
 | 
			
		||||
                IF !STRCMP(STRUPR("{CUR_FIELD_NAME}"), STRUPR(STRSUB("{CUR_ARG}", 2, EQUAL_POS - 2)))
 | 
			
		||||
                    ; Match found!
 | 
			
		||||
                    IF FIELD_ID == -1
 | 
			
		||||
FIELD_ID = CUR_FIELD_ID
 | 
			
		||||
                    ELSE
 | 
			
		||||
TMP equs "{STRUCT_NAME}_field{d:CUR_FIELD_ID}_name"
 | 
			
		||||
CONFLICTING_FIELD_NAME equs TMP
 | 
			
		||||
                        PURGE TMP
 | 
			
		||||
                        FAIL "Fields {CUR_FIELD_NAME} and {CONFLICTING_FIELD_NAME} have conflicting names (case-insensitive), cannot perform named instantiation"
 | 
			
		||||
                    ENDC
 | 
			
		||||
                ENDC
 | 
			
		||||
 | 
			
		||||
                PURGE CUR_FIELD_NAME
 | 
			
		||||
CUR_FIELD_ID = CUR_FIELD_ID + 1
 | 
			
		||||
            ENDR
 | 
			
		||||
            PURGE CUR_FIELD_ID
 | 
			
		||||
 | 
			
		||||
            IF FIELD_ID == -1
 | 
			
		||||
                FAIL "Argument #{d:ARG_NUM} (\3) does not match any field of the struct"
 | 
			
		||||
            ENDC
 | 
			
		||||
 | 
			
		||||
INITIALIZER_NAME equs "FIELD_{d:FIELD_ID}_INITIALIZER"
 | 
			
		||||
INITIALIZER_NAME equs STRSUB("{CUR_ARG}", EQUAL_POS + 1, STRLEN("{CUR_ARG}") - EQUAL_POS)
 | 
			
		||||
            PURGE INITIALIZER_NAME
 | 
			
		||||
 | 
			
		||||
            ; Go to next arg
 | 
			
		||||
ARG_NUM = ARG_NUM + 1
 | 
			
		||||
            SHIFT
 | 
			
		||||
            PURGE CUR_ARG
 | 
			
		||||
 | 
			
		||||
        ENDR
 | 
			
		||||
 | 
			
		||||
        ; Now that we matched each named initializer to their order, invoke the macro again but without names
 | 
			
		||||
FIELD_ID = 0
 | 
			
		||||
        REPT NB_FIELDS
 | 
			
		||||
TMP equs "{MACRO_CALL}"
 | 
			
		||||
            PURGE MACRO_CALL
 | 
			
		||||
INITIALIZER_VALUE equs "{FIELD_{d:FIELD_ID}_INITIALIZER}"
 | 
			
		||||
DELETE_INITIALIZER equs "PURGE FIELD_{d:FIELD_ID}_INITIALIZER"
 | 
			
		||||
            DELETE_INITIALIZER
 | 
			
		||||
            PURGE DELETE_INITIALIZER
 | 
			
		||||
MACRO_CALL equs "{TMP}, {INITIALIZER_VALUE}"
 | 
			
		||||
            PURGE TMP
 | 
			
		||||
            PURGE INITIALIZER_VALUE
 | 
			
		||||
FIELD_ID = FIELD_ID + 1
 | 
			
		||||
        ENDR
 | 
			
		||||
 | 
			
		||||
        PURGE FIELD_ID
 | 
			
		||||
        ; Clean up vars for nested invocation, otherwise some `equs` will be expanded
 | 
			
		||||
        PURGE INSTANCE_NAME
 | 
			
		||||
        PURGE STRUCT_NAME
 | 
			
		||||
        PURGE IS_NAMED_INVOCATION
 | 
			
		||||
        PURGE NB_FIELDS
 | 
			
		||||
 | 
			
		||||
        MACRO_CALL ; Now do call the macro
 | 
			
		||||
        PURGE MACRO_CALL
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    ELSE
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
INSTANCE_NAME:: ; Declare the struct's root
 | 
			
		||||
        ; Define instance's properties from struct's
 | 
			
		||||
\2_nb_fields = NB_FIELDS
 | 
			
		||||
sizeof_\2 = sizeof_\1
 | 
			
		||||
 | 
			
		||||
        ; Start defining fields
 | 
			
		||||
FIELD_ID = 0
 | 
			
		||||
        REPT NB_FIELDS
 | 
			
		||||
 | 
			
		||||
            get_nth_field_info FIELD_ID
 | 
			
		||||
 | 
			
		||||
FIELD_NAME equs STRCAT("{INSTANCE_NAME}_", STRUCT_FIELD_NAME)
 | 
			
		||||
FIELD_NAME::
 | 
			
		||||
 | 
			
		||||
            ; We have defined a label, but now we also need the data backing it
 | 
			
		||||
            ; There are basically two options:
 | 
			
		||||
            IF _NARG == 2 ; RAM definition, no data
 | 
			
		||||
                ds STRUCT_FIELD_SIZE
 | 
			
		||||
            ELSE
 | 
			
		||||
 | 
			
		||||
DATA_TYPE equs STRCAT("D", {{STRUCT_FIELD_TYPE}})
 | 
			
		||||
 | 
			
		||||
                REPT STRUCT_FIELD_NBEL
 | 
			
		||||
                    DATA_TYPE \3
 | 
			
		||||
                    SHIFT
 | 
			
		||||
                ENDR
 | 
			
		||||
                PURGE DATA_TYPE
 | 
			
		||||
            ENDC
 | 
			
		||||
 | 
			
		||||
            ; Clean up vars for next iteration
 | 
			
		||||
            PURGE STRUCT_FIELD
 | 
			
		||||
            PURGE STRUCT_FIELD_NAME
 | 
			
		||||
            PURGE STRUCT_FIELD_TYPE
 | 
			
		||||
            PURGE STRUCT_FIELD_NBEL
 | 
			
		||||
            PURGE STRUCT_FIELD_SIZE
 | 
			
		||||
            PURGE FIELD_NAME
 | 
			
		||||
 | 
			
		||||
FIELD_ID = FIELD_ID + 1
 | 
			
		||||
        ENDR
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        ; Clean up
 | 
			
		||||
        PURGE FIELD_ID
 | 
			
		||||
        ; Make sure to keep what's here in sync with cleanup at the end of a named invocation
 | 
			
		||||
        PURGE INSTANCE_NAME
 | 
			
		||||
        PURGE STRUCT_NAME
 | 
			
		||||
        PURGE IS_NAMED_INVOCATION
 | 
			
		||||
        PURGE NB_FIELDS
 | 
			
		||||
    ENDC
 | 
			
		||||
ENDM
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
; dstructs nb_structs, struct_type, INSTANCE_NAME
 | 
			
		||||
; Allocates space for an array of structs in memory
 | 
			
		||||
; Each struct will have the index appended to its name **as hex**
 | 
			
		||||
; (for example: `dstructs 32, NPC, wNPC` will define wNPC0, wNPC1, and so on until wNPC1F)
 | 
			
		||||
; This is a limitation because RGBASM does not provide an easy way to get the decimal representation of a number
 | 
			
		||||
; Does not support data declarations because I think each struct should be defined individually for that purpose
 | 
			
		||||
dstructs: MACRO
 | 
			
		||||
STRUCT_ID = 0
 | 
			
		||||
    REPT \1
 | 
			
		||||
        dstruct \2, \3{X:STRUCT_ID}
 | 
			
		||||
STRUCT_ID = STRUCT_ID + 1
 | 
			
		||||
    ENDR
 | 
			
		||||
 | 
			
		||||
    PURGE STRUCT_ID
 | 
			
		||||
ENDM
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| 
						 | 
				
			
			@ -2,23 +2,15 @@
 | 
			
		|||
; Actor Animation
 | 
			
		||||
;-----------------
 | 
			
		||||
 | 
			
		||||
SECTION "Actor Variables Struct", WRAM, ALIGN[8]
 | 
			
		||||
 | 
			
		||||
wWorldX: dw
 | 
			
		||||
wWorldY: dw
 | 
			
		||||
wActorState: db
 | 
			
		||||
wActorCounter: db
 | 
			
		||||
wActorData: dw
 | 
			
		||||
wActorTile: dw
 | 
			
		||||
 | 
			
		||||
SECTION "Actor", ROM0
 | 
			
		||||
 | 
			
		||||
Actor::
 | 
			
		||||
ActorROM::
 | 
			
		||||
.structs:
 | 
			
		||||
   dw ActorIdle
 | 
			
		||||
.tiles:
 | 
			
		||||
ActorIdle::
 | 
			
		||||
   db 60
 | 
			
		||||
   db 15
 | 
			
		||||
   dw .framePa
 | 
			
		||||
   db 15
 | 
			
		||||
   dw .frameRe
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,20 +2,33 @@
 | 
			
		|||
; Animation Subs
 | 
			
		||||
;----------------
 | 
			
		||||
 | 
			
		||||
SECTION "Animation Variables", HRAM
 | 
			
		||||
   struct Actor
 | 
			
		||||
   bytes 1, YPos
 | 
			
		||||
   bytes 1, XPos
 | 
			
		||||
   bytes 1, GFXCounter
 | 
			
		||||
   bytes 1, GFXState
 | 
			
		||||
   words 1, GFXData
 | 
			
		||||
   bytes 1, TileData
 | 
			
		||||
   end_struct
 | 
			
		||||
 | 
			
		||||
   hCameraX: dw
 | 
			
		||||
   hCameraY: dw
 | 
			
		||||
SECTION "Actor STructs", WRAM0
 | 
			
		||||
 | 
			
		||||
   hWorkingX: dw
 | 
			
		||||
   hWorkingY: dw
 | 
			
		||||
   hWorkingScreenX: db
 | 
			
		||||
   hWorkingScreenY: db
 | 
			
		||||
   hWorkingState: db
 | 
			
		||||
   hWorkingCounter: db
 | 
			
		||||
   hWorkingData: dw
 | 
			
		||||
   hWorkingTile: dw
 | 
			
		||||
hWorkingEnd:
 | 
			
		||||
   dstruct Actor, Player
 | 
			
		||||
 | 
			
		||||
SECTION "Animation Variables", WRAM0
 | 
			
		||||
 | 
			
		||||
wCameraX: dw
 | 
			
		||||
wCameraY: dw
 | 
			
		||||
 | 
			
		||||
wWorkingX: dw
 | 
			
		||||
wWorkingY: dw
 | 
			
		||||
wWorkingScreenX: db
 | 
			
		||||
wWorkingScreenY: db
 | 
			
		||||
wWorkingState: db
 | 
			
		||||
wWorkingCounter: db
 | 
			
		||||
wWorkingData: dw
 | 
			
		||||
wWorkingTile: db
 | 
			
		||||
wWorkingEnd:
 | 
			
		||||
 | 
			
		||||
SECTION "Animations Subs", ROM0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -32,28 +45,119 @@ SECTION "Animations Subs", ROM0
 | 
			
		|||
;  copied to shadowOAM (wShadowOAM)
 | 
			
		||||
 | 
			
		||||
RenderActor::
 | 
			
		||||
 | 
			
		||||
; load world X and Y to temp RAM
 | 
			
		||||
   ; @input: hl <- Player
 | 
			
		||||
   ; @input: de <- ShadowOAM place
 | 
			
		||||
   ld a, [hli] ; a <- YPos
 | 
			
		||||
   ld [wWorkingScreenY], a
 | 
			
		||||
   ld a, [hli] ; a <- XPos
 | 
			
		||||
   ld [wWorkingScreenX], a
 | 
			
		||||
   push hl
 | 
			
		||||
   ld a, [hli] ; a <- GFXCounter
 | 
			
		||||
   ld [wWorkingCounter], a
 | 
			
		||||
   ld a, [hli] ; a <- GFXState
 | 
			
		||||
   ld [wWorkingState], a
 | 
			
		||||
   ld a, [hli] ; a <- GFXData(Low)
 | 
			
		||||
   ld [wWorkingData+1], a
 | 
			
		||||
   ld a, [hli] ; a <- GFXData (High)
 | 
			
		||||
   ld [wWorkingData], a
 | 
			
		||||
   ld a, [hl] ; a <- TileData
 | 
			
		||||
   ld [wWorkingTile], a
 | 
			
		||||
; fin loading data
 | 
			
		||||
   ld a, [wWorkingData]
 | 
			
		||||
   ld l, a
 | 
			
		||||
   ld a, [wWorkingData+1]
 | 
			
		||||
   ld h, a
 | 
			
		||||
; add actor struct offset saved in wWorkingState
 | 
			
		||||
   ld a, [wWorkingState]
 | 
			
		||||
   rlca                  ; double state offset because of word length
 | 
			
		||||
   add a, l
 | 
			
		||||
   ld l, a
 | 
			
		||||
   adc a, h
 | 
			
		||||
   sub l
 | 
			
		||||
   ld h, a               ; hl contains state struct pointer
 | 
			
		||||
   ld a, [hli]
 | 
			
		||||
   ld [hWorkingX], a
 | 
			
		||||
   ld a, [hli]
 | 
			
		||||
   ld [hWorkingX+1], a
 | 
			
		||||
   ld a, [hli]
 | 
			
		||||
   ld [hWorkingY], a
 | 
			
		||||
   ld a, [hli]
 | 
			
		||||
   ld [hWorkingY+1], a
 | 
			
		||||
; done loading X and Y
 | 
			
		||||
; figure out if within 256 of camera
 | 
			
		||||
; ---------
 | 
			
		||||
; first compare upper byte of XXYY
 | 
			
		||||
; if this is more than 1 away, break
 | 
			
		||||
   ld a, [hCameraX]
 | 
			
		||||
   ld b, a
 | 
			
		||||
   ld a, [hWorkingX]
 | 
			
		||||
; b = camera byte
 | 
			
		||||
; a = actor byte
 | 
			
		||||
; work out if actor minus camera is <= 1
 | 
			
		||||
  sub b
 | 
			
		||||
; ---------
 | 
			
		||||
   ld a, [hl]
 | 
			
		||||
   ld l, b
 | 
			
		||||
   ld h, a
 | 
			
		||||
   ld a, [hli]           ; a <- state frame limit
 | 
			
		||||
   ld b, a
 | 
			
		||||
   ld a, [wWorkingCounter]
 | 
			
		||||
   inc a
 | 
			
		||||
   ld c, a
 | 
			
		||||
   ld a, b
 | 
			
		||||
   ld b, c
 | 
			
		||||
   cp b
 | 
			
		||||
   ld a, b
 | 
			
		||||
   jr nc, .continueAnimation
 | 
			
		||||
   xor a
 | 
			
		||||
.continueAnimation
 | 
			
		||||
   ; TODO: make counter 0 indexed so doesnt skip first frame
 | 
			
		||||
   ld [wWorkingCounter], a
 | 
			
		||||
   ld b, h
 | 
			
		||||
   ld c, l
 | 
			
		||||
   pop hl
 | 
			
		||||
   ld [hl], a
 | 
			
		||||
   ld h, b
 | 
			
		||||
   ld l, c
 | 
			
		||||
.loopFrameFind
 | 
			
		||||
   ld b, a      ; b <- current frame count
 | 
			
		||||
   ld a, [hli]  ; a <- next frame block
 | 
			
		||||
   ld c, a
 | 
			
		||||
   ld a, b
 | 
			
		||||
   ld b, c
 | 
			
		||||
   sub b
 | 
			
		||||
   jr z, .foundFrame
 | 
			
		||||
   jr c, .foundFrame
 | 
			
		||||
   inc hl
 | 
			
		||||
   inc hl
 | 
			
		||||
   jr .loopFrameFind
 | 
			
		||||
.foundFrame
 | 
			
		||||
   ld a, [hli]
 | 
			
		||||
   ld b, a
 | 
			
		||||
   ld a, [hl]
 | 
			
		||||
   ld h, a
 | 
			
		||||
   ld l, b     ; hl <- pointer to frame data
 | 
			
		||||
   ld a, [hli]
 | 
			
		||||
   ld b, a     ; b <- sprite counter
 | 
			
		||||
.spriteLoop
 | 
			
		||||
   ; load Y position, then offset by -16
 | 
			
		||||
   ld a, [hli]
 | 
			
		||||
   ld c, a
 | 
			
		||||
   ld a, [wWorkingScreenY]
 | 
			
		||||
   add c
 | 
			
		||||
   ld c, 16
 | 
			
		||||
   add c
 | 
			
		||||
   ld [de], a          ; store YPos in shadowOAM
 | 
			
		||||
   inc de
 | 
			
		||||
   ; load X position, then offset by -8
 | 
			
		||||
   ld a, [hli]
 | 
			
		||||
   ld c, a
 | 
			
		||||
   ld a, [wWorkingScreenX]
 | 
			
		||||
   add c
 | 
			
		||||
   ld c, 8
 | 
			
		||||
   add c
 | 
			
		||||
   ld [de], a          ; store YPos in shadowOAM
 | 
			
		||||
   inc de
 | 
			
		||||
   ; load tile offset, and add to base tile pointer
 | 
			
		||||
   ld a, [hli]
 | 
			
		||||
   ld c, a
 | 
			
		||||
   ld a, [wWorkingTile]
 | 
			
		||||
   add c
 | 
			
		||||
   ld [de], a
 | 
			
		||||
   inc de
 | 
			
		||||
   ; load attributes and xor them
 | 
			
		||||
   ld a, [hli]
 | 
			
		||||
   ld c, a
 | 
			
		||||
   ld a, 0    ; TO DO: set base attributes
 | 
			
		||||
   xor c
 | 
			
		||||
   ld [de], a
 | 
			
		||||
   inc de
 | 
			
		||||
   ; end of single sprite
 | 
			
		||||
   dec b
 | 
			
		||||
   jr nz, .spriteLoop
 | 
			
		||||
   ret
 | 
			
		||||
 | 
			
		||||
.skipRendering
 | 
			
		||||
BUFFER       EQU 160
 | 
			
		||||
TRUE         EQU $42
 | 
			
		||||
FALSE        EQU $69
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -57,3 +57,4 @@ hOAMDMA:
 | 
			
		|||
SECTION "Shadow OAM", WRAM0,ALIGN[8]
 | 
			
		||||
wShadowOAM::
 | 
			
		||||
   ds 4*40
 | 
			
		||||
wShadowOAMEnd::
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										138
									
								
								src/entry.asm
									
									
									
									
									
								
							
							
						
						
									
										138
									
								
								src/entry.asm
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -2,9 +2,7 @@
 | 
			
		|||
; Program Start
 | 
			
		||||
;----------------
 | 
			
		||||
 | 
			
		||||
BUFFER       EQU 160
 | 
			
		||||
TRUE         EQU $42
 | 
			
		||||
FALSE        EQU $69
 | 
			
		||||
INCLUDE "src/actor.asm"
 | 
			
		||||
 | 
			
		||||
SECTION "Program Start", ROM0[$150]
 | 
			
		||||
Start:
 | 
			
		||||
| 
						 | 
				
			
			@ -17,6 +15,7 @@ Start:
 | 
			
		|||
   xor a
 | 
			
		||||
   ldh [rLCDC], a
 | 
			
		||||
   call Clear_Map
 | 
			
		||||
   call Clear_OAM
 | 
			
		||||
   call Load_Tiles
 | 
			
		||||
   ; call Load_Map
 | 
			
		||||
   ld a, %11100100
 | 
			
		||||
| 
						 | 
				
			
			@ -32,129 +31,26 @@ Start:
 | 
			
		|||
   call CopyDMARoutine 
 | 
			
		||||
 | 
			
		||||
   ld a, 72
 | 
			
		||||
   ld [rPlayerX], a
 | 
			
		||||
   ld a, 88
 | 
			
		||||
   ld [rPlayerY], a
 | 
			
		||||
 | 
			
		||||
;----
 | 
			
		||||
; Testing
 | 
			
		||||
;----
 | 
			
		||||
   ld a, HIGH(ANS)
 | 
			
		||||
   ld h, a
 | 
			
		||||
   ld a, LOW(ANS)
 | 
			
		||||
   ld l, a
 | 
			
		||||
 | 
			
		||||
; Case One: Camera@E100 vs Actor@E195 (Pass)
 | 
			
		||||
   ld a, $E1
 | 
			
		||||
   ld [N], a
 | 
			
		||||
   ld a, $E1
 | 
			
		||||
   ld [X], a
 | 
			
		||||
   ld a, $00
 | 
			
		||||
   ld [N+1], a
 | 
			
		||||
   ld a, $95
 | 
			
		||||
   ld [X+1], a
 | 
			
		||||
   call CheckBoundry
 | 
			
		||||
 | 
			
		||||
; Case One: Camera@E095 vs Actor@E120 (Pass)
 | 
			
		||||
   ld a, $E0
 | 
			
		||||
   ld [N], a
 | 
			
		||||
   ld a, $E1
 | 
			
		||||
   ld [X], a
 | 
			
		||||
   ld a, $95
 | 
			
		||||
   ld [N+1], a
 | 
			
		||||
   ld a, $20
 | 
			
		||||
   ld [X+1], a
 | 
			
		||||
   call CheckBoundry
 | 
			
		||||
 | 
			
		||||
; Case One: Camera@E100 vs Actor@E1FF (Fail)
 | 
			
		||||
   ld a, $E1
 | 
			
		||||
   ld [N], a
 | 
			
		||||
   ld a, $E1
 | 
			
		||||
   ld [X], a
 | 
			
		||||
   ld a, $00
 | 
			
		||||
   ld [N+1], a
 | 
			
		||||
   ld a, $FF
 | 
			
		||||
   ld [X+1], a
 | 
			
		||||
   call CheckBoundry
 | 
			
		||||
 | 
			
		||||
; Case One: Camera@E1F0 vs Actor@E2DE (Fail)
 | 
			
		||||
   ld a, $E1
 | 
			
		||||
   ld [N], a
 | 
			
		||||
   ld a, $E2
 | 
			
		||||
   ld [X], a
 | 
			
		||||
   ld a, $F0
 | 
			
		||||
   ld [N+1], a
 | 
			
		||||
   ld a, $DE
 | 
			
		||||
   ld [X+1], a
 | 
			
		||||
   call CheckBoundry
 | 
			
		||||
   ld [Player_YPos], a
 | 
			
		||||
   ld a, 80
 | 
			
		||||
   ld [Player_XPos], a
 | 
			
		||||
   xor a
 | 
			
		||||
   ld [Player_GFXCounter], a
 | 
			
		||||
   ld [Player_GFXState], a
 | 
			
		||||
   ld [Player_TileData], a
 | 
			
		||||
   ld a, HIGH(ActorROM)
 | 
			
		||||
   ld [Player_GFXData], a
 | 
			
		||||
   ld a, LOW(ActorROM)
 | 
			
		||||
   ld [Player_GFXData + 1], a
 | 
			
		||||
 | 
			
		||||
game_loop:
 | 
			
		||||
   call Wait_VBlank
 | 
			
		||||
   call Read_Pad
 | 
			
		||||
   call PC_Update
 | 
			
		||||
   call Player_To_OAM
 | 
			
		||||
   call Clear_OAM
 | 
			
		||||
   ld de, wShadowOAM
 | 
			
		||||
   ld hl, Player
 | 
			
		||||
   call RenderActor
 | 
			
		||||
   ld a, HIGH(wShadowOAM)
 | 
			
		||||
   call hOAMDMA
 | 
			
		||||
   jr game_loop
 | 
			
		||||
 | 
			
		||||
CheckBoundry::
 | 
			
		||||
;-----
 | 
			
		||||
; Check if word X is within BUFFER ahead of N
 | 
			
		||||
; BUFFER is always <= 255
 | 
			
		||||
; hl contains address to save result to
 | 
			
		||||
;-----
 | 
			
		||||
   ;= load high bytes
 | 
			
		||||
   ld a, [N]
 | 
			
		||||
   ld b, a
 | 
			
		||||
   ld a, [X]
 | 
			
		||||
   sub b
 | 
			
		||||
   ;= if carry is set, N is behind X, so skip
 | 
			
		||||
   jr c, .skipRender
 | 
			
		||||
   ld b, a
 | 
			
		||||
   ld a, 2
 | 
			
		||||
   cp b
 | 
			
		||||
   ;= if the difference is 2 or greater
 | 
			
		||||
   ;= we are not within BUFFER, so skip
 | 
			
		||||
   jr c, .skipRender
 | 
			
		||||
   jr z, .skipRender
 | 
			
		||||
   dec a
 | 
			
		||||
   cp b
 | 
			
		||||
   ;= if the high byte differ by 1, we
 | 
			
		||||
   ;= need to check over a a page
 | 
			
		||||
   jr z, .swap
 | 
			
		||||
   ;= load the low bytes
 | 
			
		||||
   ld a, [N+1]
 | 
			
		||||
   ld b, a
 | 
			
		||||
   ld a, [X+1]
 | 
			
		||||
   sub b
 | 
			
		||||
   ld b, a
 | 
			
		||||
   ld a, BUFFER
 | 
			
		||||
   cp b
 | 
			
		||||
   ;= if the difference is greater than
 | 
			
		||||
   ;= the buffer, skip
 | 
			
		||||
   jr c, .skipRender
 | 
			
		||||
   jr .render
 | 
			
		||||
.swap
 | 
			
		||||
   ;= load the low bytes in the opposite order
 | 
			
		||||
   ld a, [X+1]
 | 
			
		||||
   ld b, a
 | 
			
		||||
   ld a, [N+1]
 | 
			
		||||
   sub b
 | 
			
		||||
   ld b, a
 | 
			
		||||
   ld a, $FF - BUFFER
 | 
			
		||||
   cp b
 | 
			
		||||
   ;= if they differ by the inverse of the buffer
 | 
			
		||||
   ;= they will not be within the gap between pages
 | 
			
		||||
   jr nc, .skipRender
 | 
			
		||||
.render
 | 
			
		||||
   ;= success, do rendering stuff
 | 
			
		||||
   ; beep boop rendering stuff
 | 
			
		||||
   ld a, TRUE
 | 
			
		||||
   ld [hli], a
 | 
			
		||||
   ret
 | 
			
		||||
.skipRender
 | 
			
		||||
   ;= failure, skip this one
 | 
			
		||||
   ; doing other stuff here
 | 
			
		||||
   ld a, FALSE
 | 
			
		||||
   ld [hli], a
 | 
			
		||||
   ret
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,9 @@
 | 
			
		|||
INCLUDE "inc/hardware.inc"
 | 
			
		||||
INCLUDE "inc/structs.asm"
 | 
			
		||||
INCLUDE "ass/parecivo.ass"
 | 
			
		||||
INCLUDE "ass/tiles.ass"
 | 
			
		||||
INCLUDE "ass/map.ass"
 | 
			
		||||
INCLUDE "src/animation.asm"
 | 
			
		||||
INCLUDE "src/entry.asm"
 | 
			
		||||
INCLUDE "src/header.asm"
 | 
			
		||||
INCLUDE "src/defines.asm"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										22
									
								
								src/misc.asm
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								src/misc.asm
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -134,16 +134,28 @@ PC_Update:
 | 
			
		|||
   ret
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Clear_Map:
 | 
			
		||||
   xor a
 | 
			
		||||
   ld hl, _SCRN0
 | 
			
		||||
   ld bc, _SCRN0_END - _SCRN0
 | 
			
		||||
Clear_OAM:
 | 
			
		||||
   ld hl, wShadowOAM
 | 
			
		||||
   ld bc, wShadowOAMEnd - wShadowOAM
 | 
			
		||||
.loop:
 | 
			
		||||
   xor a
 | 
			
		||||
   ld [hli], a
 | 
			
		||||
   dec bc
 | 
			
		||||
   ld a, b
 | 
			
		||||
   or c
 | 
			
		||||
   jr z, .loop
 | 
			
		||||
   jr nz, .loop
 | 
			
		||||
   ret
 | 
			
		||||
 | 
			
		||||
Clear_Map:
 | 
			
		||||
   ld hl, _SCRN0
 | 
			
		||||
   ld bc, _SCRN0_END - _SCRN0
 | 
			
		||||
.loop:
 | 
			
		||||
   xor a
 | 
			
		||||
   ld [hli], a
 | 
			
		||||
   dec bc
 | 
			
		||||
   ld a, b
 | 
			
		||||
   or c
 | 
			
		||||
   jr nz, .loop
 | 
			
		||||
   ret
 | 
			
		||||
 | 
			
		||||
Load_Tiles:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue