From aa5b06312ee0c6517b9125d7a60eb038bd07d5d1 Mon Sep 17 00:00:00 2001 From: tA Date: Sun, 24 May 2020 17:54:13 +1200 Subject: [PATCH] working animation, but ugly --- .gitignore | 1 + Makefile | 3 +- animation.sym | 54 -------- inc/structs.asm | 367 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/.actor.asm.swp | Bin 12288 -> 0 bytes src/.entry.asm.swp | Bin 12288 -> 0 bytes src/actor.asm | 12 +- src/animation.asm | 170 ++++++++++++++++++++----- src/dma.asm | 1 + src/entry.asm | 138 +++----------------- src/main.asm | 2 + src/misc.asm | 16 ++- 12 files changed, 543 insertions(+), 221 deletions(-) delete mode 100644 animation.sym create mode 100644 inc/structs.asm delete mode 100644 src/.actor.asm.swp delete mode 100644 src/.entry.asm.swp diff --git a/.gitignore b/.gitignore index 378eac2..89efb0f 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ build +*.swp diff --git a/Makefile b/Makefile index 652a748..b49a37a 100644 --- a/Makefile +++ b/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} diff --git a/animation.sym b/animation.sym deleted file mode 100644 index a673909..0000000 --- a/animation.sym +++ /dev/null @@ -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 diff --git a/inc/structs.asm b/inc/structs.asm new file mode 100644 index 0000000..0e02c83 --- /dev/null +++ b/inc/structs.asm @@ -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 diff --git a/src/.actor.asm.swp b/src/.actor.asm.swp deleted file mode 100644 index e3410fe37e37c7091788e35e67a4febacd7ba93a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI2JBSle6oyaK#z$6hK|v6%5k)2MeHgPU#<)mev%6&1tgJ zDA?#?WvhjyY$YgIXeAbcg{_K>h_#LX+|0`m2-^q?XW(OUPtM%?-!DlqWVCoOmlvsM zl5p%G`u*+YrPbXlfwys@)@9jlSoHyi-jP?^h8)mEbX`ptTQ-_Yu_Y}g8+u)udb1I0 z8KsyknN1@qTlIm{a044)18X(VHmi|TkVcXT{IZGmhxUo#o#)m%3-_}DHoykh02^Qf zY=8~00XDFX4VcRTx`F%~>^)4_=RnWd9`cC|umLu}2G{@_U;}J`4X^<=zy{a=8(4=1 zWSQvZR-(Jx5FY>kJNN%Tw-bE<@4-8;0v>~V;2NldMKA?UfaBmGH~{v7VXzVW86x@x zzJt%;19%Nq!87m_JOsDF6;K4HK@{u(Lm&t?fgeGlPv8xB0iJ*d;6Atos-OT)f+JuT z*a9{K0$;JmkKh$}4jut(-**5XY=8~00XDz}*Z><~18jf|{67QHsv+x@Vso-lCLu&w z6Cxf~B*w!c?yE&oVUZZ~YSviw;_UQUHB~?A)eiZV5D{_eu!xCKa*DX)Pzkbnp9G`c zEY?aY!H8FL6Zn$434BTI1Zs)i1Xm(4zyqcT9m()$*OKK-jOY|m~mFi>e2=_zjeiIU7|J0$XZyg)xTeqjx z#CV)C)>G!Wa;=h1Q`FRJl~!6^)DiAG6m6MCyJX@WRYNDuO=jnFGt(lZDxt6_%;fPH zZAT5~F-=;OJNEF5G^KBtZMGX`#Xv=~8|F-DS{Gov&@^i03*Bz@`n-DGvz{nQLzf!D mia8Yx0Tv3Gd{|_ra%ZO(Qx|dH9_c-3qPr)Nah|j9*Yp>lav6C5 diff --git a/src/.entry.asm.swp b/src/.entry.asm.swp deleted file mode 100644 index 07c6146bb196df6e5cb644efafbf3e11c73b29c3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI2Uu+ab9LERhA5amZF~kSV2sJ5kZSPJCrIpxTdshnWUG23{to4}No8GS7?w-4Q zoF|R{5`94u6BDCB3`R|W2V;%#$zT)pMZhP+gE9DI;-83#8WMQ&JF~mj+x`)1;sbGy zez=>N-|T#U-}$rK^zzYt{e!fv}xvOrqOC!N-H-UtJ=cs>1$pl33><15mO<)6P0GIC|mp(tOr+bC*%q^2R;WMgAc%);0TxjCO8Q8f<0gp*Z>;9<=Zem z_#T`Gb6^&{4UU1=zzmoI2S5+l3ho7K!5VO7Eg^q^FTrW>5;zPv7z2Z#3+w=E!Cz}I zCb$SLfDged;A!v#$b!9~5v&G(-U@%fSuh7?!AWo&90f0f36KIYumx-amu?~C2kJBT%#`qQ&hZBA>FT zp+x8c37xy3j#p_#({*Z?4$X6XhG0X~(;~yr+^KMG&=MhO zK?1tT3UYkitU!vxZR*K4OC{6R94NAc;aBl9@O`RJG zr!pV{gL8OdQbpy;6g4p~ zl;NM4L(ySA4OJ_u(ljq2F_*Cjt;jGxivm~NUEmKCSjMPa(!UC)%;IuYc}vRm0dAUd zV+5514UJ>Yd{;%BFU7SaE~@H`T22DyN@12&6;ot$CqmQWQ=Vge7wA|($ik&Jw#>py z%X)t*YWCTrvst`ICslQ-n1;hN!=|iIu&_DBRM_kg#|E{_x`QI(TsMRurdL?irjP8R z@wPU!^vGF*_zD&-9TOn|2PsoI);#uE+8F@4%;NZn3UpEET1PY}&0jrqz{<_aEH_Frc%D7#d4#|%Z=4~ zU8me=z1$d1(tjs6UX!#~?#?z})YxKC)Sa(I?nak%H@dT}&fQo%N}Gn5ZLiqfc}a`q z{&(&|e4Sh@MLn<#2QvGcy3<*?W6-Du8s)Z9daVy(XFG7@SqMyN8&1yX}iJ@qqXQFSYu8b#u2V${UG>RY5r_)Vi0C(}+ zpnHFodC7_qO?MwU+*EbWEI&vusIad-$(jrqTz?E<7-6>Ro=Pd56@5XqK5{bplYTvl z5Za$i;UpXAPVW^;xkj=Mvz!i+P4<~O wBD%>}^086cxP2!P&vkwsm6Z?2iFYTMkBn`{w|d