├── .clang-format
├── .gitignore
├── LICENSE
├── README.md
├── demo
├── DuskDemo
│ ├── .gitignore
│ ├── LICENSE
│ ├── Makefile
│ ├── README.md
│ ├── asset
│ │ ├── build
│ │ │ ├── .gitignore
│ │ │ ├── Makefile
│ │ │ └── build.wox
│ │ ├── img
│ │ │ ├── chars
│ │ │ │ ├── egg.png
│ │ │ │ ├── gob.png
│ │ │ │ └── kik.png
│ │ │ ├── logo
│ │ │ │ └── dusk.png
│ │ │ ├── mus
│ │ │ │ └── musviz.png
│ │ │ ├── part
│ │ │ │ ├── lvs1.png
│ │ │ │ ├── lvs10.png
│ │ │ │ ├── lvs11.png
│ │ │ │ ├── lvs12.png
│ │ │ │ ├── lvs13.png
│ │ │ │ ├── lvs14.png
│ │ │ │ ├── lvs15.png
│ │ │ │ ├── lvs16.png
│ │ │ │ ├── lvs17.png
│ │ │ │ ├── lvs18.png
│ │ │ │ ├── lvs19.png
│ │ │ │ ├── lvs2.png
│ │ │ │ ├── lvs20.png
│ │ │ │ ├── lvs21.png
│ │ │ │ ├── lvs22.png
│ │ │ │ ├── lvs23.png
│ │ │ │ ├── lvs24.png
│ │ │ │ ├── lvs25.png
│ │ │ │ ├── lvs26.png
│ │ │ │ ├── lvs27.png
│ │ │ │ ├── lvs28.png
│ │ │ │ ├── lvs29.png
│ │ │ │ ├── lvs3.png
│ │ │ │ ├── lvs30.png
│ │ │ │ ├── lvs31.png
│ │ │ │ ├── lvs32.png
│ │ │ │ ├── lvs33.png
│ │ │ │ ├── lvs34.png
│ │ │ │ ├── lvs35.png
│ │ │ │ ├── lvs36.png
│ │ │ │ ├── lvs37.png
│ │ │ │ ├── lvs38.png
│ │ │ │ ├── lvs39.png
│ │ │ │ ├── lvs4.png
│ │ │ │ ├── lvs5.png
│ │ │ │ ├── lvs6.png
│ │ │ │ ├── lvs7.png
│ │ │ │ ├── lvs8.png
│ │ │ │ └── lvs9.png
│ │ │ └── thred
│ │ │ │ └── cap.png
│ │ ├── map
│ │ │ ├── autumn_sheet.png
│ │ │ ├── autumn_sheet.tsx
│ │ │ ├── fountain.tmx
│ │ │ ├── fountain_tiles.png
│ │ │ ├── fountain_tiles.tsx
│ │ │ └── september.tmx
│ │ ├── rawmap
│ │ │ ├── dusk_bg.png
│ │ │ └── dusk_bg.xcf
│ │ └── snd
│ │ │ ├── Boom.wav
│ │ │ ├── Megalovania.xm
│ │ │ └── runu5.xm
│ ├── build.wox
│ └── src
│ │ ├── main.c
│ │ ├── scenes.h
│ │ └── scenes
│ │ ├── audio.c
│ │ ├── autumn.c
│ │ ├── background.c
│ │ ├── logo.c
│ │ ├── merge.c
│ │ ├── randbit.c
│ │ └── thred.c
└── Fountain2
│ ├── .gitignore
│ ├── LICENSE
│ ├── Makefile
│ ├── asset
│ ├── build
│ │ ├── .gitignore
│ │ ├── Makefile
│ │ └── custom.mk
│ ├── img
│ │ ├── chars
│ │ │ ├── egg.png
│ │ │ ├── gob.png
│ │ │ └── kik.png
│ │ └── logo
│ │ │ └── dusk.png
│ └── map
│ │ ├── central.tmx
│ │ ├── east.tmx
│ │ ├── fountain_tiles.png
│ │ ├── fountain_tiles.tsx
│ │ ├── north.tmx
│ │ ├── northwest.tmx
│ │ └── west.tmx
│ └── src
│ ├── fountain2.c
│ ├── logo.c
│ ├── main.c
│ └── scenes.h
├── doc
├── dlang.md
└── tips.md
├── media
├── duskdemo.webp
├── fountain2.webp
└── icon.png
└── src
└── dusk
├── Makefile
├── include
├── contrib
│ ├── gbamap.h
│ ├── gbamap_object.h
│ ├── gbfs.h
│ └── mgba.h
├── ds_load.h
├── ds_sav.h
├── ds_spr.h
├── ds_sys.h
└── dusk.h
└── src
├── contrib
├── background.h
├── bitField.h
├── initMapRegisters.c
├── libgbfs.c
├── loadMapFromROM.c
├── loadObject.c
├── loadObjectID.c
├── loadPosition.c
├── loadString.c
├── memoryMap.h
├── mgba.c
├── popValue.c
├── setMapOnScreen.c
├── shiftMap.c
├── shiftMapLayer.c
├── shiftMapObjects.c
├── types.h
└── video.h
├── load.c
├── sprites.c
└── sys.c
/.clang-format:
--------------------------------------------------------------------------------
1 | BasedOnStyle: LLVM
2 | IndentWidth: 4
3 | ColumnLimit: 120
4 | # Force pointers to the type
5 | DerivePointerAlignment: false
6 | PointerAlignment: Left
7 | SortIncludes: false
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # VSCode
2 | .vscode
3 |
4 | # GBA outputs
5 | *.gba
6 | *.gbfs
7 | *.sav
8 |
9 | # ---> C
10 | # Prerequisites
11 | *.d
12 |
13 | # Object files
14 | *.o
15 | *.ko
16 | *.obj
17 | *.elf
18 |
19 | # Linker output
20 | *.ilk
21 | *.map
22 | *.exp
23 |
24 | # Precompiled Headers
25 | *.gch
26 | *.pch
27 |
28 | # Libraries
29 | *.lib
30 | *.a
31 | *.la
32 | *.lo
33 |
34 | # Shared objects (inc. Windows DLLs)
35 | *.dll
36 | *.so
37 | *.so.*
38 | *.dylib
39 |
40 | # Executables
41 | *.exe
42 | *.out
43 | *.app
44 | *.i*86
45 | *.x86_64
46 | *.hex
47 |
48 | # Debug files
49 | *.dSYM/
50 | *.su
51 | *.idb
52 | *.pdb
53 |
54 | # Kernel Module Compile Results
55 | *.mod*
56 | *.cmd
57 | .tmp_versions/
58 | modules.order
59 | Module.symvers
60 | Mkfile.old
61 | dkms.conf
62 |
63 | # ---> Linux
64 | *~
65 |
66 | # temporary files which can be created if a process still has a handle open of a deleted file
67 | .fuse_hidden*
68 |
69 | # KDE directory preferences
70 | .directory
71 |
72 | # Linux trash folder which might appear on any partition or disk
73 | .Trash-*
74 |
75 | # .nfs files are created when an open file is removed but is still being accessed
76 | .nfs*
77 |
78 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | 
3 |
4 | # dusk
5 |
6 | DUsK, a library for gba dev
7 |
8 | ## media!
9 |
10 |
11 |
12 |
13 | ## features
14 | + simple, intuitive C API
15 | + library integration
16 | + built in support for TONC, GBFS
17 | + graphics
18 | + scene architecture
19 | + 8bpp texture atlas packing
20 | + sprite/animation helpers
21 | + tiled map exporter and loader (via Tiled2GBA)
22 | + (WIP) saves
23 |
24 | ## ideas
25 |
26 | dusk is built all around the idea of simplicity, clarity, and readability.
27 | the exposed api is minimal, but not limiting.
28 |
29 | ## samples
30 |
31 | sample projects can be found here: https://github.com/redthing1/dusk/tree/main/demo
32 |
33 | these demo projects are written simply and cleanly.
34 |
35 | they have plenty of comments explaining what and why the code does what it does.
36 |
37 | furthermore, they demonstrate many of the different features provided by dusk.
38 |
39 | ## documentation
40 |
41 | in the spirit of simplicity and minimalism, and to back up the claims that dusk is simple and easy:
42 |
43 | documentation is provided in the literate style, interspersed within a few header files.
44 | these header files contain the entirety of the dusk core api.
45 |
46 | view these self documenting files here: https://github.com/redthing1/dusk/tree/main/src/dusk/include
47 |
48 | ## hacking
49 |
50 | ### requirements
51 | + devkitARM's `gba-dev` ([setup](https://devkitpro.org/wiki/Getting_Started))
52 | + [Tiled2GBA](https://github.com/LucvandenBrand/Tiled2GBA/tree/master/converter) converter in path as `Tiled2GBA`
53 | + [crunch](https://github.com/xdrie/crunch) atlas packer in path as `crunch_gen`
54 |
55 | ### build
56 |
57 | enter `demo/DuskDemo` and run:
58 |
59 | ```sh
60 | make
61 | ```
62 |
63 | this will output `DuskDemo.gba`, which can be loaded up in your favorite GBA emulator.
64 |
--------------------------------------------------------------------------------
/demo/DuskDemo/.gitignore:
--------------------------------------------------------------------------------
1 | # GBA outputs
2 | *.gba
3 | *.gbfs
4 | *.sav
5 |
6 | # ---> C
7 | # Prerequisites
8 | *.d
9 |
10 | # Object files
11 | *.o
12 | *.ko
13 | *.obj
14 | *.elf
15 |
16 | # Linker output
17 | *.ilk
18 | *.map
19 | *.exp
20 |
21 | # Precompiled Headers
22 | *.gch
23 | *.pch
24 |
25 | # Libraries
26 | *.lib
27 | *.a
28 | *.la
29 | *.lo
30 |
31 | # Shared objects (inc. Windows DLLs)
32 | *.dll
33 | *.so
34 | *.so.*
35 | *.dylib
36 |
37 | # Executables
38 | *.exe
39 | *.out
40 | *.app
41 | *.i*86
42 | *.x86_64
43 | *.hex
44 |
45 | # Debug files
46 | *.dSYM/
47 | *.su
48 | *.idb
49 | *.pdb
50 |
51 | # Kernel Module Compile Results
52 | *.mod*
53 | *.cmd
54 | .tmp_versions/
55 | modules.order
56 | Module.symvers
57 | Mkfile.old
58 | dkms.conf
59 |
60 | # ---> Linux
61 | *~
62 |
63 | # temporary files which can be created if a process still has a handle open of a deleted file
64 | .fuse_hidden*
65 |
66 | # KDE directory preferences
67 | .directory
68 |
69 | # Linux trash folder which might appear on any partition or disk
70 | .Trash-*
71 |
72 | # .nfs files are created when an open file is removed but is still being accessed
73 | .nfs*
74 |
75 |
--------------------------------------------------------------------------------
/demo/DuskDemo/LICENSE:
--------------------------------------------------------------------------------
1 | Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Creative
2 | Commons Corporation ("Creative Commons") is not a law firm and does not provide
3 | legal services or legal advice. Distribution of Creative Commons public licenses
4 | does not create a lawyer-client or other relationship. Creative Commons makes
5 | its licenses and related information available on an "as-is" basis. Creative
6 | Commons gives no warranties regarding its licenses, any material licensed
7 | under their terms and conditions, or any related information. Creative Commons
8 | disclaims all liability for damages resulting from their use to the fullest
9 | extent possible.
10 |
11 | Using Creative Commons Public Licenses
12 |
13 | Creative Commons public licenses provide a standard set of terms and conditions
14 | that creators and other rights holders may use to share original works of
15 | authorship and other material subject to copyright and certain other rights
16 | specified in the public license below. The following considerations are for
17 | informational purposes only, are not exhaustive, and do not form part of our
18 | licenses.
19 |
20 | Considerations for licensors: Our public licenses are intended for use by
21 | those authorized to give the public permission to use material in ways otherwise
22 | restricted by copyright and certain other rights. Our licenses are irrevocable.
23 | Licensors should read and understand the terms and conditions of the license
24 | they choose before applying it. Licensors should also secure all rights necessary
25 | before applying our licenses so that the public can reuse the material as
26 | expected. Licensors should clearly mark any material not subject to the license.
27 | This includes other CC-licensed material, or material used under an exception
28 | or limitation to copyright. More considerations for licensors : wiki.creativecommons.org/Considerations_for_licensors
29 |
30 | Considerations for the public: By using one of our public licenses, a licensor
31 | grants the public permission to use the licensed material under specified
32 | terms and conditions. If the licensor's permission is not necessary for any
33 | reason–for example, because of any applicable exception or limitation to copyright–then
34 | that use is not regulated by the license. Our licenses grant only permissions
35 | under copyright and certain other rights that a licensor has authority to
36 | grant. Use of the licensed material may still be restricted for other reasons,
37 | including because others have copyright or other rights in the material. A
38 | licensor may make special requests, such as asking that all changes be marked
39 | or described. Although not required by our licenses, you are encouraged to
40 | respect those requests where reasonable. More considerations for the public
41 | : wiki.creativecommons.org/Considerations_for_licensees
42 |
43 | Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Public
44 | License
45 |
46 | By exercising the Licensed Rights (defined below), You accept and agree to
47 | be bound by the terms and conditions of this Creative Commons Attribution-NonCommercial-ShareAlike
48 | 4.0 International Public License ("Public License"). To the extent this Public
49 | License may be interpreted as a contract, You are granted the Licensed Rights
50 | in consideration of Your acceptance of these terms and conditions, and the
51 | Licensor grants You such rights in consideration of benefits the Licensor
52 | receives from making the Licensed Material available under these terms and
53 | conditions.
54 |
55 | Section 1 – Definitions.
56 |
57 | a. Adapted Material means material subject to Copyright and Similar Rights
58 | that is derived from or based upon the Licensed Material and in which the
59 | Licensed Material is translated, altered, arranged, transformed, or otherwise
60 | modified in a manner requiring permission under the Copyright and Similar
61 | Rights held by the Licensor. For purposes of this Public License, where the
62 | Licensed Material is a musical work, performance, or sound recording, Adapted
63 | Material is always produced where the Licensed Material is synched in timed
64 | relation with a moving image.
65 |
66 | b. Adapter's License means the license You apply to Your Copyright and Similar
67 | Rights in Your contributions to Adapted Material in accordance with the terms
68 | and conditions of this Public License.
69 |
70 | c. BY-NC-SA Compatible License means a license listed at creativecommons.org/compatiblelicenses,
71 | approved by Creative Commons as essentially the equivalent of this Public
72 | License.
73 |
74 | d. Copyright and Similar Rights means copyright and/or similar rights closely
75 | related to copyright including, without limitation, performance, broadcast,
76 | sound recording, and Sui Generis Database Rights, without regard to how the
77 | rights are labeled or categorized. For purposes of this Public License, the
78 | rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights.
79 |
80 | e. Effective Technological Measures means those measures that, in the absence
81 | of proper authority, may not be circumvented under laws fulfilling obligations
82 | under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996,
83 | and/or similar international agreements.
84 |
85 | f. Exceptions and Limitations means fair use, fair dealing, and/or any other
86 | exception or limitation to Copyright and Similar Rights that applies to Your
87 | use of the Licensed Material.
88 |
89 | g. License Elements means the license attributes listed in the name of a Creative
90 | Commons Public License. The License Elements of this Public License are Attribution,
91 | NonCommercial, and ShareAlike.
92 |
93 | h. Licensed Material means the artistic or literary work, database, or other
94 | material to which the Licensor applied this Public License.
95 |
96 | i. Licensed Rights means the rights granted to You subject to the terms and
97 | conditions of this Public License, which are limited to all Copyright and
98 | Similar Rights that apply to Your use of the Licensed Material and that the
99 | Licensor has authority to license.
100 |
101 | j. Licensor means the individual(s) or entity(ies) granting rights under this
102 | Public License.
103 |
104 | k. NonCommercial means not primarily intended for or directed towards commercial
105 | advantage or monetary compensation. For purposes of this Public License, the
106 | exchange of the Licensed Material for other material subject to Copyright
107 | and Similar Rights by digital file-sharing or similar means is NonCommercial
108 | provided there is no payment of monetary compensation in connection with the
109 | exchange.
110 |
111 | l. Share means to provide material to the public by any means or process that
112 | requires permission under the Licensed Rights, such as reproduction, public
113 | display, public performance, distribution, dissemination, communication, or
114 | importation, and to make material available to the public including in ways
115 | that members of the public may access the material from a place and at a time
116 | individually chosen by them.
117 |
118 | m. Sui Generis Database Rights means rights other than copyright resulting
119 | from Directive 96/9/EC of the European Parliament and of the Council of 11
120 | March 1996 on the legal protection of databases, as amended and/or succeeded,
121 | as well as other essentially equivalent rights anywhere in the world.
122 |
123 | n. You means the individual or entity exercising the Licensed Rights under
124 | this Public License. Your has a corresponding meaning.
125 |
126 | Section 2 – Scope.
127 |
128 | a. License grant.
129 |
130 | 1. Subject to the terms and conditions of this Public License, the Licensor
131 | hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive,
132 | irrevocable license to exercise the Licensed Rights in the Licensed Material
133 | to:
134 |
135 | A. reproduce and Share the Licensed Material, in whole or in part, for NonCommercial
136 | purposes only; and
137 |
138 | B. produce, reproduce, and Share Adapted Material for NonCommercial purposes
139 | only.
140 |
141 | 2. Exceptions and Limitations. For the avoidance of doubt, where Exceptions
142 | and Limitations apply to Your use, this Public License does not apply, and
143 | You do not need to comply with its terms and conditions.
144 |
145 | 3. Term. The term of this Public License is specified in Section 6(a).
146 |
147 | 4. Media and formats; technical modifications allowed. The Licensor authorizes
148 | You to exercise the Licensed Rights in all media and formats whether now known
149 | or hereafter created, and to make technical modifications necessary to do
150 | so. The Licensor waives and/or agrees not to assert any right or authority
151 | to forbid You from making technical modifications necessary to exercise the
152 | Licensed Rights, including technical modifications necessary to circumvent
153 | Effective Technological Measures. For purposes of this Public License, simply
154 | making modifications authorized by this Section 2(a)(4) never produces Adapted
155 | Material.
156 |
157 | 5. Downstream recipients.
158 |
159 | A. Offer from the Licensor – Licensed Material. Every recipient of the Licensed
160 | Material automatically receives an offer from the Licensor to exercise the
161 | Licensed Rights under the terms and conditions of this Public License.
162 |
163 | B. Additional offer from the Licensor – Adapted Material. Every recipient
164 | of Adapted Material from You automatically receives an offer from the Licensor
165 | to exercise the Licensed Rights in the Adapted Material under the conditions
166 | of the Adapter's License You apply.
167 |
168 | C. No downstream restrictions. You may not offer or impose any additional
169 | or different terms or conditions on, or apply any Effective Technological
170 | Measures to, the Licensed Material if doing so restricts exercise of the Licensed
171 | Rights by any recipient of the Licensed Material.
172 |
173 | 6. No endorsement. Nothing in this Public License constitutes or may be construed
174 | as permission to assert or imply that You are, or that Your use of the Licensed
175 | Material is, connected with, or sponsored, endorsed, or granted official status
176 | by, the Licensor or others designated to receive attribution as provided in
177 | Section 3(a)(1)(A)(i).
178 |
179 | b. Other rights.
180 |
181 | 1. Moral rights, such as the right of integrity, are not licensed under this
182 | Public License, nor are publicity, privacy, and/or other similar personality
183 | rights; however, to the extent possible, the Licensor waives and/or agrees
184 | not to assert any such rights held by the Licensor to the limited extent necessary
185 | to allow You to exercise the Licensed Rights, but not otherwise.
186 |
187 | 2. Patent and trademark rights are not licensed under this Public License.
188 |
189 | 3. To the extent possible, the Licensor waives any right to collect royalties
190 | from You for the exercise of the Licensed Rights, whether directly or through
191 | a collecting society under any voluntary or waivable statutory or compulsory
192 | licensing scheme. In all other cases the Licensor expressly reserves any right
193 | to collect such royalties, including when the Licensed Material is used other
194 | than for NonCommercial purposes.
195 |
196 | Section 3 – License Conditions.
197 |
198 | Your exercise of the Licensed Rights is expressly made subject to the following
199 | conditions.
200 |
201 | a. Attribution.
202 |
203 | 1. If You Share the Licensed Material (including in modified form), You must:
204 |
205 | A. retain the following if it is supplied by the Licensor with the Licensed
206 | Material:
207 |
208 | i. identification of the creator(s) of the Licensed Material and any others
209 | designated to receive attribution, in any reasonable manner requested by the
210 | Licensor (including by pseudonym if designated);
211 |
212 | ii. a copyright notice;
213 |
214 | iii. a notice that refers to this Public License;
215 |
216 | iv. a notice that refers to the disclaimer of warranties;
217 |
218 |
219 |
220 | v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable;
221 |
222 | B. indicate if You modified the Licensed Material and retain an indication
223 | of any previous modifications; and
224 |
225 | C. indicate the Licensed Material is licensed under this Public License, and
226 | include the text of, or the URI or hyperlink to, this Public License.
227 |
228 | 2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner
229 | based on the medium, means, and context in which You Share the Licensed Material.
230 | For example, it may be reasonable to satisfy the conditions by providing a
231 | URI or hyperlink to a resource that includes the required information.
232 |
233 | 3. If requested by the Licensor, You must remove any of the information required
234 | by Section 3(a)(1)(A) to the extent reasonably practicable.
235 |
236 | b. ShareAlike.In addition to the conditions in Section 3(a), if You Share
237 | Adapted Material You produce, the following conditions also apply.
238 |
239 | 1. The Adapter's License You apply must be a Creative Commons license with
240 | the same License Elements, this version or later, or a BY-NC-SA Compatible
241 | License.
242 |
243 | 2. You must include the text of, or the URI or hyperlink to, the Adapter's
244 | License You apply. You may satisfy this condition in any reasonable manner
245 | based on the medium, means, and context in which You Share Adapted Material.
246 |
247 | 3. You may not offer or impose any additional or different terms or conditions
248 | on, or apply any Effective Technological Measures to, Adapted Material that
249 | restrict exercise of the rights granted under the Adapter's License You apply.
250 |
251 | Section 4 – Sui Generis Database Rights.
252 |
253 | Where the Licensed Rights include Sui Generis Database Rights that apply to
254 | Your use of the Licensed Material:
255 |
256 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract,
257 | reuse, reproduce, and Share all or a substantial portion of the contents of
258 | the database for NonCommercial purposes only;
259 |
260 | b. if You include all or a substantial portion of the database contents in
261 | a database in which You have Sui Generis Database Rights, then the database
262 | in which You have Sui Generis Database Rights (but not its individual contents)
263 | is Adapted Material, including for purposes of Section 3(b); and
264 |
265 | c. You must comply with the conditions in Section 3(a) if You Share all or
266 | a substantial portion of the contents of the database.
267 |
268 | For the avoidance of doubt, this Section 4 supplements and does not replace
269 | Your obligations under this Public License where the Licensed Rights include
270 | other Copyright and Similar Rights.
271 |
272 | Section 5 – Disclaimer of Warranties and Limitation of Liability.
273 |
274 | a. Unless otherwise separately undertaken by the Licensor, to the extent possible,
275 | the Licensor offers the Licensed Material as-is and as-available, and makes
276 | no representations or warranties of any kind concerning the Licensed Material,
277 | whether express, implied, statutory, or other. This includes, without limitation,
278 | warranties of title, merchantability, fitness for a particular purpose, non-infringement,
279 | absence of latent or other defects, accuracy, or the presence or absence of
280 | errors, whether or not known or discoverable. Where disclaimers of warranties
281 | are not allowed in full or in part, this disclaimer may not apply to You.
282 |
283 | b. To the extent possible, in no event will the Licensor be liable to You
284 | on any legal theory (including, without limitation, negligence) or otherwise
285 | for any direct, special, indirect, incidental, consequential, punitive, exemplary,
286 | or other losses, costs, expenses, or damages arising out of this Public License
287 | or use of the Licensed Material, even if the Licensor has been advised of
288 | the possibility of such losses, costs, expenses, or damages. Where a limitation
289 | of liability is not allowed in full or in part, this limitation may not apply
290 | to You.
291 |
292 | c. The disclaimer of warranties and limitation of liability provided above
293 | shall be interpreted in a manner that, to the extent possible, most closely
294 | approximates an absolute disclaimer and waiver of all liability.
295 |
296 | Section 6 – Term and Termination.
297 |
298 | a. This Public License applies for the term of the Copyright and Similar Rights
299 | licensed here. However, if You fail to comply with this Public License, then
300 | Your rights under this Public License terminate automatically.
301 |
302 | b. Where Your right to use the Licensed Material has terminated under Section
303 | 6(a), it reinstates:
304 |
305 | 1. automatically as of the date the violation is cured, provided it is cured
306 | within 30 days of Your discovery of the violation; or
307 |
308 | 2. upon express reinstatement by the Licensor.
309 |
310 | For the avoidance of doubt, this Section 6(b) does not affect any right the
311 | Licensor may have to seek remedies for Your violations of this Public License.
312 |
313 | c. For the avoidance of doubt, the Licensor may also offer the Licensed Material
314 | under separate terms or conditions or stop distributing the Licensed Material
315 | at any time; however, doing so will not terminate this Public License.
316 |
317 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public License.
318 |
319 | Section 7 – Other Terms and Conditions.
320 |
321 | a. The Licensor shall not be bound by any additional or different terms or
322 | conditions communicated by You unless expressly agreed.
323 |
324 | b. Any arrangements, understandings, or agreements regarding the Licensed
325 | Material not stated herein are separate from and independent of the terms
326 | and conditions of this Public License.
327 |
328 | Section 8 – Interpretation.
329 |
330 | a. For the avoidance of doubt, this Public License does not, and shall not
331 | be interpreted to, reduce, limit, restrict, or impose conditions on any use
332 | of the Licensed Material that could lawfully be made without permission under
333 | this Public License.
334 |
335 | b. To the extent possible, if any provision of this Public License is deemed
336 | unenforceable, it shall be automatically reformed to the minimum extent necessary
337 | to make it enforceable. If the provision cannot be reformed, it shall be severed
338 | from this Public License without affecting the enforceability of the remaining
339 | terms and conditions.
340 |
341 | c. No term or condition of this Public License will be waived and no failure
342 | to comply consented to unless expressly agreed to by the Licensor.
343 |
344 | d. Nothing in this Public License constitutes or may be interpreted as a limitation
345 | upon, or waiver of, any privileges and immunities that apply to the Licensor
346 | or You, including from the legal processes of any jurisdiction or authority.
347 |
348 | Creative Commons is not a party to its public licenses. Notwithstanding, Creative
349 | Commons may elect to apply one of its public licenses to material it publishes
350 | and in those instances will be considered the "Licensor." The text of the
351 | Creative Commons public licenses is dedicated to the public domain under the
352 | CC0 Public Domain Dedication. Except for the limited purpose of indicating
353 | that material is shared under a Creative Commons public license or as otherwise
354 | permitted by the Creative Commons policies published at creativecommons.org/policies,
355 | Creative Commons does not authorize the use of the trademark "Creative Commons"
356 | or any other trademark or logo of Creative Commons without its prior written
357 | consent including, without limitation, in connection with any unauthorized
358 | modifications to any of its public licenses or any other arrangements, understandings,
359 | or agreements concerning use of licensed material. For the avoidance of doubt,
360 | this paragraph does not form part of the public licenses.
361 |
362 | Creative Commons may be contacted at creativecommons.org.
363 |
--------------------------------------------------------------------------------
/demo/DuskDemo/Makefile:
--------------------------------------------------------------------------------
1 | PATH := $(DEVKITARM)/bin:$(PATH)
2 |
3 | TITLE := DuskDemo
4 |
5 | # Project settings
6 |
7 | NAME := $(TITLE)
8 | SOURCE_DIR := src
9 | LIB_DIR := lib
10 | DUSK_DIR := ../../src/dusk
11 | DATA_DIR := asset/build
12 | SPECS := -specs=gba.specs
13 |
14 | # Compilation settings
15 |
16 | CROSS ?= arm-none-eabi-
17 | AS := $(CROSS)as
18 | CC := $(CROSS)gcc
19 | LD := $(CROSS)gcc
20 | OBJCOPY := $(CROSS)objcopy
21 |
22 | ARCH := -mthumb-interwork -mthumb
23 |
24 | INCFLAGS := -I$(DUSK_DIR)/include -I$(DEVKITPRO)/libtonc/include -I$(DEVKITPRO)/libgba/include -I$(SOURCE_DIR) -I$(DATA_DIR)
25 | LIBFLAGS := -L$(DUSK_DIR)/lib -ldusk -L$(DEVKITPRO)/libtonc/lib -ltonc -L$(DEVKITPRO)/libgba/lib -lmm
26 | ASFLAGS := -mthumb-interwork
27 | CFLAGS := $(ARCH) -Wall -Werror -fno-strict-aliasing -mcpu=arm7tdmi -mtune=arm7tdmi $(INCFLAGS) $(LIBFLAGS)
28 | LDFLAGS := $(ARCH) $(SPECS) $(LIBFLAGS) -Wl,-Map,$(TITLE).map
29 |
30 | ASSET_MKFLAGS :=
31 | DUSK_MKFLAGS :=
32 |
33 | ifeq ($(DEBUG),1)
34 | CFLAGS += -O2 -g
35 | DUSK_MKFLAGS += DEBUG=1
36 | else
37 | # non-debug
38 | CFLAGS += -O2 -fomit-frame-pointer -ffast-math
39 | endif
40 |
41 | .PHONY : build clean
42 |
43 | # Find and predetermine all relevant source files
44 |
45 | APP_MAIN_SOURCE := $(shell find $(SOURCE_DIR) -name '*main.c')
46 | APP_MAIN_OBJECT := $(APP_MAIN_SOURCE:%.c=%.o)
47 | APP_SOURCES_C := $(shell find $(SOURCE_DIR) -name '*.c' ! -name "*main.c" ! -name "*.test.c")
48 | APP_SOURCES_S := $(shell find $(SOURCE_DIR) -name '*.s')
49 | APP_OBJECTS_C := $(APP_SOURCES_C:%.c=%.o)
50 | APP_OBJECTS_S := $(APP_SOURCES_S:%.s=%.o)
51 | APP_OBJECTS := $(APP_OBJECTS_C) $(APP_OBJECTS_S)
52 |
53 | # Build commands and dependencies
54 |
55 | .PHONY: libs assets
56 |
57 | build: assets libs $(NAME).gba
58 |
59 | no-content: libs $(NAME)-code.gba
60 |
61 | libs:
62 | cd $(DUSK_DIR) && make $(DUSK_MKFLAGS)
63 |
64 | assets:
65 | cd asset/build && make $(ASSET_MKFLAGS)
66 |
67 | $(NAME).gba : $(NAME)-code.gba $(NAME).gbfs
68 | cat $^ > $(NAME).gba
69 |
70 | $(NAME)-code.gba : $(NAME).elf
71 | $(OBJCOPY) -v -O binary $< $@
72 | -@gbafix $@ -t$(NAME)
73 | padbin 256 $@
74 |
75 | $(NAME).elf : $(APP_OBJECTS) $(APP_MAIN_OBJECT)
76 | $(LD) $^ $(LDFLAGS) -o $@
77 |
78 | $(APP_OBJECTS_C) : %.o : %.c assets libs
79 | $(CC) $(CFLAGS) -c $< -o $@
80 |
81 | $(APP_OBJECTS_S) : %.o : %.s
82 | $(CC) $(CFLAGS) -c $< -o $@
83 |
84 | $(APP_MAIN_OBJECT) : $(APP_MAIN_SOURCE)
85 | $(CC) $(CFLAGS) -c $< -o $@
86 |
87 | $(NAME).gbfs: assets
88 | gbfs $@ $(shell find $(DATA_DIR) -name '*.bin')
89 |
90 | clean:
91 | @rm -fv *.gba
92 | @rm -fv *.elf
93 | @rm -fv *.sav
94 | @rm -fv *.gbfs
95 | @rm -rf $(APP_OBJECTS)
96 | @rm -rf $(APP_MAIN_OBJECT)
97 | cd $(DUSK_DIR) && make clean
98 | cd asset/build && make clean
99 |
--------------------------------------------------------------------------------
/demo/DuskDemo/README.md:
--------------------------------------------------------------------------------
1 |
2 | # duskdemo
3 |
4 | ## build
5 |
6 | default:
7 | `make build`
8 |
9 | debug:
10 | `make build DEBUG=1`
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/build/.gitignore:
--------------------------------------------------------------------------------
1 | # generated data
2 | *.bin
3 | *.b
4 | *.h
5 | atl*
6 | a_*
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/build/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: clean atlas
2 |
3 | IMGS_DIR := ../img
4 | MAPS_DIR := ../map
5 | RAWMAPS_DIR := ../rawmap
6 | SOUND_DIR := ../snd
7 |
8 | ATLS_SRC := $(shell find $(IMGS_DIR) -mindepth 1 -type d)
9 | ATLS_OUT := $(patsubst %,a_%_,$(notdir $(ATLS_SRC)))
10 | ATLS_PNG := $(ATLS_OUT:%_=%_0.png)
11 |
12 | IMGS_BIN := $(notdir $(ATLS_PNG:%.png=%.img.bin))
13 |
14 | RAWMAPS_SRC := $(shell find $(RAWMAPS_DIR) -name '*.png')
15 | RAWMAPS_BIN := $(notdir $(RAWMAPS_SRC:%.png=%.bin))
16 |
17 | MAPS_SRC := $(shell find $(MAPS_DIR) -name '*.tmx')
18 | MAPS_BIN := $(notdir $(MAPS_SRC:%.tmx=%.bin))
19 |
20 | SOUND_SRC := $(shell find $(SOUND_DIR) -type f)
21 | SOUND_BIN := soundbank.bin
22 | SOUND_H := soundbank.h
23 |
24 | GRIT_BPP := 8
25 | GRIT_FLAGS := -gt -p -g -gB $(GRIT_BPP) -gu32 -pu32 -ftb -fh!
26 | CRUNCH_FLAGS := -p -j -b -s256 -p0
27 |
28 | all: $(MAPS_BIN) $(RAWMAPS_BIN) $(IMGS_BIN) $(SOUND_BIN) $(SOUND_H)
29 |
30 | clean:
31 | rm -rfv *.bin
32 | rm -rfv *.b
33 | rm -rfv *.h
34 | rm -rfv atl*
35 | rm -rfv *.png
36 | rm -rfv *.hash
37 | rm -rfv *.json
38 |
39 | # define a function: atlpng2grit(size), this will set Mw and Mh to size
40 | atlpng2grit = grit "$<" $(GRIT_FLAGS) -Mh $(1) -Mw $(1) -o "$@"
41 |
42 | # default rule for atlpng -> img bin
43 | %.img.bin: %.png
44 | grit "$<" $(GRIT_FLAGS) -o "$@"
45 |
46 | # import custom recipes
47 | a_part_0.img.bin: a_part_0.png
48 | $(call atlpng2grit,1)
49 |
50 | a_chars_0.img.bin: a_chars_0.png
51 | $(call atlpng2grit,2)
52 |
53 | a_logo_0.img.bin: a_logo_0.png
54 | $(call atlpng2grit,8)
55 |
56 | a_thred_0.img.bin: a_thred_0.png
57 | $(call atlpng2grit,8)
58 |
59 | a_mus_0.img.bin: a_mus_0.png
60 | $(call atlpng2grit,8)
61 |
62 | # rule for building atlas pngs from sprite dirs
63 | # build a_thing_
64 | a_%_: ../img/%
65 | crunch_gen "$@" "$<" $(CRUNCH_FLAGS)
66 | # convert a_thing_ to a_thing_0.png (fake recipe)
67 | $(ATLS_PNG): $(ATLS_OUT)
68 | @true
69 |
70 | # rule for building tmx maps
71 | %.bin: ../map/%.tmx
72 | Tiled2GBA -b $< $@
73 |
74 | # rule for building raw maps
75 | %.bin: ../rawmap/%.png
76 | grit "$<" -p -m -g -gB 8 -gu32 -pu32 -ftb -o "$@"
77 |
78 | # rule for building soundbank
79 | $(SOUND_BIN) $(SOUND_H): $(SOUND_SRC)
80 | @mmutil $^ -osoundbank.bin -hsoundbank.h
81 | @true
82 |
83 | # debug:
84 | # $(foreach var,$(.VARIABLES),$(info $(var) = $($(var))))
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/build/build.wox:
--------------------------------------------------------------------------------
1 | import "wox" for W, R
2 |
3 | var BASE_DIR = "./asset/build/"
4 |
5 | var IMGS_DIR = "%(BASE_DIR)../img"
6 | var MAPS_DIR = "%(BASE_DIR)../map"
7 | var RAWMAPS_DIR = "%(BASE_DIR)../rawmap"
8 | var SOUND_DIR = "%(BASE_DIR)../snd"
9 |
10 | var ATLS_SRC = W.lines(W.shell("find %(IMGS_DIR) -mindepth 1 -type d"))
11 | var ATLS_PNG = ATLS_SRC.map{|x|
12 | var y = W.path_basename(x)
13 | return "%(BASE_DIR)./a_%(y)_0.png"
14 | }.toList
15 |
16 | var IMGS_BINS = ATLS_PNG.map{|x|
17 | return x.replace(".png", ".img.bin")
18 | }
19 |
20 | var RAWMAPS_SRCS = W.lines(W.shell("find %(RAWMAPS_DIR) -name '*.png'"))
21 | var RAWMAPS_BINSS = RAWMAPS_SRCS.map{|x|
22 | var y = W.path_basename(x).replace(".png", ".img.bin")
23 | return "%(BASE_DIR)./%(y)"
24 | }.toList
25 |
26 | var MAPS_SRCS = W.lines(W.shell("find %(MAPS_DIR) -name '*.tmx'"))
27 | var MAPS_BINS = MAPS_SRCS.map{|x|
28 | var y = W.path_basename(x).replace(".tmx", ".bin")
29 | return "%(BASE_DIR)./%(y)"
30 | }.toList
31 |
32 | var SOUND_SRCS = W.lines(W.shell("find %(SOUND_DIR) -type f"))
33 | var SOUND_BIN = "%(BASE_DIR)./soundbank.bin"
34 | var SOUND_H = "%(BASE_DIR)./soundbank.h"
35 |
36 | var GRIT_BPP = 8
37 | var GRIT_FLAGS = "-gt -p -g -gB %(GRIT_BPP) -gu32 -pu32 -ftb -fh!"
38 | var CRUNCH_FLAGS = "-p -j -b -s256 -p0"
39 |
40 | var gen_atl2png2grit_cmd = Fn.new{|input, output, size|
41 | return "grit %(input) %(GRIT_FLAGS) -Mh %(size) -Mw %(size) -o %(output)"
42 | }
43 |
44 | var custom_imgbins = [
45 | ["%(BASE_DIR)./a_part_0.png", 1],
46 | ["%(BASE_DIR)./a_chars_0.png", 2],
47 | ["%(BASE_DIR)./a_logo_0.png", 8],
48 | ["%(BASE_DIR)./a_thred_0.png", 8],
49 | ["%(BASE_DIR)./a_mus_0.png", 8]
50 | ]
51 |
52 | var custom_imgbin_recipes = custom_imgbins.map{|x|
53 | var in_name = x[0]
54 | var out_name = x[0].replace(".png", ".img.bin")
55 | var size = x[1]
56 | var cmd = gen_atl2png2grit_cmd.call(in_name, out_name, size)
57 | return W.recipe(out_name, [in_name], [out_name], [R.c(cmd)])
58 | }.toList
59 |
60 | var atlas_png_sprite_dir_pairs = W.zip(ATLS_PNG, ATLS_SRC)
61 | var atlas_png_recipes = atlas_png_sprite_dir_pairs.map{|x|
62 | var in_name = x[1]
63 | var out_name = x[0]
64 | var out_prefix = W.ext_remove(out_name)[0..-2]
65 | var cmd = "crunch_gen %(out_prefix) %(in_name) %(CRUNCH_FLAGS)"
66 | // W.log_inf("atlas png recipe: %(out_name) <- %(in_name)")
67 | return W.recipe(out_name, [in_name], [out_name], [R.c(cmd)])
68 | }.toList
69 |
70 | // tmx maps
71 | var tmx_map_bin_pairs = W.zip(MAPS_BINS, MAPS_SRCS)
72 | var tmx_map_recipes = tmx_map_bin_pairs.map{|x|
73 | var in_name = x[1]
74 | var out_name = x[0]
75 | var cmd = "Tiled2GBA -b %(in_name) %(out_name)"
76 | return W.recipe(out_name, [in_name], [out_name], [R.c(cmd)])
77 | }.toList
78 |
79 | // raw maps
80 | var raw_map_bin_pairs = W.zip(RAWMAPS_BINSS, RAWMAPS_SRCS)
81 | var raw_map_recipes = raw_map_bin_pairs.map{|x|
82 | var in_name = x[1]
83 | var out_name = x[0]
84 | var cmd = "grit %(in_name) -p -m -g -gB 8 -gu32 -pu32 -ftb -o %(out_name)"
85 | return W.recipe(out_name, [in_name], [out_name], [R.c(cmd)])
86 | }.toList
87 |
88 | // soundbank
89 | var soundbank_recipe = W.recipe(SOUND_BIN, SOUND_SRCS, [SOUND_BIN, SOUND_H],
90 | [R.c("mmutil %(W.join(SOUND_SRCS)) -o%(SOUND_BIN) -h%(SOUND_H)")]
91 | )
92 |
93 | var ASSET_RECIPES = atlas_png_recipes + tmx_map_recipes + raw_map_recipes + custom_imgbin_recipes + [soundbank_recipe]
94 | var ASSET_OUTPUTS = W.flatten(ASSET_RECIPES.map{|x|
95 | return x.outputs
96 | }).map{|x|
97 | return x.name
98 | }.toList
99 |
100 | // var clean_recipe = W.virtual_recipe("clean", [],
101 | // [
102 | // R.c("rm -rf *.bin"),
103 | // R.c("rm -rf *.b"),
104 | // R.c("rm -rf *.h"),
105 | // R.c("rm -rf atl*"),
106 | // R.c("rm -rf *.png"),
107 | // R.c("rm -rf *.hash"),
108 | // R.c("rm -rf *.json")
109 | // ]
110 | // )
111 | // var all_recipe = W.meta_recipe("all", asset_recipes)
112 |
113 | // var BUILD_RECIPES = asset_recipes + [all_recipe, clean_recipe]
114 |
115 | // class Build {
116 | // static recipes { BUILD_RECIPES }
117 | // static default_recipe { "all" }
118 | // }
119 |
120 | class PartialBuild_Assets {
121 | static recipes { ASSET_RECIPES }
122 | static outputs { ASSET_OUTPUTS }
123 | }
124 |
125 |
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/chars/egg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/chars/egg.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/chars/gob.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/chars/gob.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/chars/kik.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/chars/kik.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/logo/dusk.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/logo/dusk.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/mus/musviz.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/mus/musviz.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs1.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs10.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs11.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs12.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs13.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs13.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs14.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs14.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs15.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs15.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs16.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs17.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs17.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs18.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs18.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs19.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs19.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs2.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs20.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs21.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs21.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs22.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs22.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs23.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs23.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs24.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs24.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs25.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs25.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs26.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs26.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs27.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs27.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs28.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs28.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs29.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs29.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs3.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs30.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs30.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs31.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs31.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs32.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs33.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs33.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs34.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs34.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs35.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs35.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs36.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs36.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs37.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs38.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs38.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs39.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs39.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs4.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs5.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs6.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs7.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs8.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/part/lvs9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/part/lvs9.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/img/thred/cap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/img/thred/cap.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/map/autumn_sheet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/map/autumn_sheet.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/map/autumn_sheet.tsx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/map/fountain.tmx:
--------------------------------------------------------------------------------
1 |
2 |
10 |
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/map/fountain_tiles.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/map/fountain_tiles.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/map/fountain_tiles.tsx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/map/september.tmx:
--------------------------------------------------------------------------------
1 |
2 |
10 |
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/rawmap/dusk_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/rawmap/dusk_bg.png
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/rawmap/dusk_bg.xcf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/rawmap/dusk_bg.xcf
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/snd/Boom.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/snd/Boom.wav
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/snd/Megalovania.xm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/snd/Megalovania.xm
--------------------------------------------------------------------------------
/demo/DuskDemo/asset/snd/runu5.xm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/DuskDemo/asset/snd/runu5.xm
--------------------------------------------------------------------------------
/demo/DuskDemo/build.wox:
--------------------------------------------------------------------------------
1 | import "wox" for W, R
2 | import "./asset/build/build.wox" for PartialBuild_Assets
3 |
4 | var TITLE = "DuskDemo"
5 |
6 | var DEBUG = W.cliopt_bool("-g", false)
7 |
8 | var DEVKITARM = W.env("DEVKITARM", "")
9 | var DEVKITPRO = W.env("DEVKITPRO", "")
10 |
11 | for (devkit_env in ["DEVKITARM", "DEVKITPRO"]) {
12 | if (W.env(devkit_env, "") == "") {
13 | W.log_err("Please set %(devkit_env) in your environment.")
14 | W.fail()
15 | }
16 | }
17 |
18 | // Project settings
19 | var SOURCE_DIR = "./src"
20 | var LIB_DIR = "./lib"
21 | var DUSK_DIR = "../../src/dusk"
22 | var LIBDUSK_A = "%(DUSK_DIR)/lib/libdusk.a"
23 | var DATA_DIR = "./asset/build"
24 | var SPECS = "-specs=gba.specs"
25 |
26 | // Compilation settings
27 | var CROSS = "arm-none-eabi-"
28 | var AS = "%(CROSS)as"
29 | var CC = "%(CROSS)gcc"
30 | var LD = "%(CROSS)gcc"
31 | var OBJCOPY = "%(CROSS)objcopy"
32 |
33 | var ARCH = "-mthumb-interwork -mthumb"
34 |
35 | var INCFLAGS = "-I%(DUSK_DIR)/include -I%(DEVKITPRO)/libtonc/include -I%(DEVKITPRO)/libgba/include -I%(SOURCE_DIR) -I%(DATA_DIR)"
36 | var LIBFLAGS = "-L%(DUSK_DIR)/lib -ldusk -L%(DEVKITPRO)/libtonc/lib -ltonc -L%(DEVKITPRO)/libgba/lib -lmm"
37 | var ASFLAGS = "-mthumb-interwork"
38 | var CFLAGS = "%(ARCH) -Wall -Werror -fno-strict-aliasing -mcpu=arm7tdmi -mtune=arm7tdmi %(INCFLAGS) %(LIBFLAGS)"
39 | var LDFLAGS = "%(ARCH) %(SPECS) %(LIBFLAGS) -Wl,-Map,%(TITLE).map"
40 |
41 | var ASSET_MKFLAGS = ""
42 | var DUSK_MKFLAGS = ""
43 |
44 | if (DEBUG) {
45 | CFLAGS = CFLAGS + " -O2 -g"
46 | DUSK_MKFLAGS = DUSK_MKFLAGS + " DEBUG=1"
47 | } else {
48 | CFLAGS = CFLAGS + "-O2 -fomit-frame-pointer -ffast-math"
49 | }
50 |
51 | // Find and predetermine all relevant source files
52 | var APP_MAIN_SOURCE = W.lines(W.shell("find %(SOURCE_DIR) -name '*main.c' | head -n 1"))[0]
53 | var APP_MAIN_OBJECT = APP_MAIN_SOURCE.replace(".c", ".o")
54 | var APP_SOURCES_C = W.lines(W.shell("find %(SOURCE_DIR) -name '*.c' ! -name '*main.c' ! -name '*.test.c'"))
55 | var APP_SOURCES_S = W.lines(W.shell("find %(SOURCE_DIR) -name '*.s'"))
56 | var APP_OBJECTS_C = W.exts_replace(APP_SOURCES_C, ".c", ".o")
57 | var APP_OBJECTS_S = W.exts_replace(APP_SOURCES_S, ".s", ".o")
58 | var APP_OBJECTS = APP_OBJECTS_C + APP_OBJECTS_S
59 |
60 | var TARGET_GBA = "%(TITLE).gba"
61 | var TARGET_GBA_CODE = "%(TITLE)-code.gba"
62 | var TARGET_ELF = "%(TITLE).elf"
63 | var TARGET_GBFS = "%(TITLE).gbfs"
64 |
65 | // assets
66 | // var assets_bins_recipes = W.make_recipes_relative(DATA_DIR, PartialBuild_Assets.recipes)
67 | var assets_bins_recipes = PartialBuild_Assets.recipes
68 | var assets_meta_recipe = W.meta_recipe("assets", assets_bins_recipes)
69 |
70 | // var assets_outputs = W.relative_paths(DATA_DIR, PartialBuild_Assets.outputs)
71 | var assets_outputs = PartialBuild_Assets.outputs
72 | // W.log_inf("assets outputs: %(assets_outputs)")
73 |
74 | // C objects
75 | var c_obj_pairs = W.zip(APP_SOURCES_C, APP_OBJECTS_C)
76 | var c_obj_recipes = c_obj_pairs.map { |x|
77 | return W.recipe(x[1], [x[0]] + assets_outputs, [x[1]],
78 | [ R.c("%(CC) %(CFLAGS) -c %(x[0]) -o %(x[1])") ]
79 | )
80 | }.toList
81 |
82 | // S objects
83 | var s_obj_pairs = W.zip(APP_SOURCES_S, APP_OBJECTS_S)
84 | var s_obj_recipes = s_obj_pairs.map { |x|
85 | return W.recipe(x[1], [x[0]], [x[1]],
86 | [ R.c("%(CC) %(CFLAGS) -c %(x[0]) -o %(x[1])") ]
87 | )
88 | }.toList
89 |
90 | // main source
91 | var main_obj_recipe = W.recipe(APP_MAIN_OBJECT, [APP_MAIN_SOURCE], [APP_MAIN_OBJECT],
92 | [ R.c("%(CC) %(CFLAGS) -c %(APP_MAIN_SOURCE) -o %(APP_MAIN_OBJECT)") ]
93 | )
94 |
95 | var obj_recipes = [main_obj_recipe] + c_obj_recipes + s_obj_recipes
96 |
97 | // libraries
98 | var libdusk_recipe = W.recipe("libdusk", [], [LIBDUSK_A],
99 | [ R.c("cd %(DUSK_DIR) && make %(DUSK_MKFLAGS)") ]
100 | )
101 |
102 | var lib_targets = [LIBDUSK_A]
103 | var lib_recipes = [libdusk_recipe]
104 |
105 | // main recipes
106 | var target_elf_recipe = W.recipe("target_elf", [APP_MAIN_OBJECT] + APP_OBJECTS + lib_targets, [TARGET_ELF],
107 | [ R.c("%(LD) %(W.join(APP_OBJECTS)) %(APP_MAIN_OBJECT) %(LDFLAGS) -o %(TARGET_ELF)") ]
108 | )
109 |
110 | var target_gba_code_recipe = W.recipe("target_gba_code", [TARGET_ELF], [TARGET_GBA_CODE],
111 | [
112 | R.c("%(OBJCOPY) -v -O binary %(TARGET_ELF) %(TARGET_GBA_CODE)"),
113 | R.c("gbafix %(TARGET_GBA_CODE) -t%(TITLE)"),
114 | R.c("padbin 256 %(TARGET_GBA_CODE)")
115 | ]
116 | )
117 |
118 | var target_gbfs_recipe = W.recipe("target_gbfs", assets_outputs, [TARGET_GBFS],
119 | [ R.c("gbfs %(TARGET_GBFS) %(W.join(assets_outputs))") ]
120 | )
121 |
122 | var target_gba_recipe = W.recipe("target_gba", [TARGET_GBA_CODE, TARGET_GBFS], [TARGET_GBA],
123 | [ R.c("cat %(TARGET_GBA_CODE) %(TARGET_GBFS) > %(TARGET_GBA)") ]
124 | )
125 |
126 | var clean_recipe = W.virtual_recipe("clean", [],
127 | [
128 | R.c("rm -f *.gba"),
129 | R.c("rm -f *.elf"),
130 | R.c("rm -f *.sav"),
131 | R.c("rm -f *.gbfs"),
132 | R.c("rm -rf %(APP_OBJECTS)"),
133 | R.c("rm -rf %(APP_MAIN_OBJECT)"),
134 | R.c("cd %(DUSK_DIR) && make clean"),
135 | R.c("cd %(DATA_DIR) && make clean")
136 | ]
137 | )
138 |
139 | var all_recipe = W.meta_recipe("all", [target_gba_recipe])
140 |
141 | var BUILD_RECIPES = obj_recipes + lib_recipes + PartialBuild_Assets.recipes + [assets_meta_recipe, target_elf_recipe, target_gba_code_recipe, target_gbfs_recipe, target_gba_recipe, clean_recipe, all_recipe]
142 |
143 | class Build {
144 | static recipes { BUILD_RECIPES }
145 | static default_recipe { "all" }
146 | }
147 |
--------------------------------------------------------------------------------
/demo/DuskDemo/src/main.c:
--------------------------------------------------------------------------------
1 | #include "dusk.h"
2 | #include "scenes.h"
3 |
4 | #define NUM_DEMOS 7
5 |
6 | int main() {
7 | dusk_init_all();
8 |
9 | Scene demos[NUM_DEMOS] = {
10 | logo_scene,
11 | thred_scene,
12 | audio_scene,
13 | background_scene,
14 | merge_scene,
15 | autumn_scene,
16 | randbit_scene,
17 | };
18 | int demo_ix = 0;
19 |
20 | dusk_scene_set(demos[demo_ix]);
21 |
22 | while (TRUE) {
23 | key_poll(); // update input
24 | if (key_hit(KEY_START)) {
25 | demo_ix = (demo_ix + 1) % NUM_DEMOS;
26 | dusk_scene_set(demos[demo_ix]);
27 | }
28 |
29 | dusk_scene_update();
30 | }
31 | }
--------------------------------------------------------------------------------
/demo/DuskDemo/src/scenes.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "ds_sys.h"
4 |
5 | extern Scene logo_scene;
6 | extern Scene thred_scene;
7 | extern Scene merge_scene;
8 | extern Scene audio_scene;
9 | extern Scene autumn_scene;
10 | extern Scene background_scene;
11 | extern Scene randbit_scene;
--------------------------------------------------------------------------------
/demo/DuskDemo/src/scenes/audio.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "dusk.h"
3 | #include "tonc.h"
4 | #include "maxmod.h"
5 | #include "soundbank.h"
6 |
7 | mm_sound_effect boom;
8 | Sprite* vizspr;
9 | Anim vz_anim1;
10 |
11 | void audio_start() {
12 | dusk_init_graphics_mode0();
13 |
14 | // irq setup for maxmod dma
15 | irq_init(NULL);
16 | irq_add(II_VBLANK, mmVBlank);
17 | irq_enable(II_VBLANK);
18 |
19 | // load soundbank
20 | u32 soundbank_len;
21 | const u32* soundbank_bin = gbfs_get_obj(gbfs_dat, "soundbank.bin", &soundbank_len);
22 |
23 | // initialise maxmod with soundbank and 8 channels
24 | mmInitDefault((mm_addr)soundbank_bin, 8);
25 |
26 | // play module
27 | mmStart(MOD_RUNU5, MM_PLAY_LOOP);
28 |
29 | // define sfx
30 | boom.handle = 0;
31 | boom.id = SFX_BOOM;
32 | boom.rate = (int)(1.0f * (1 << 10));
33 | boom.volume = 255;
34 | boom.panning = 255;
35 |
36 | pal_bg_mem[0] = 0x0C02; // background color
37 |
38 | // load sprite atlas
39 | dusk_sprites_init();
40 | SpriteAtlas atlas = dusk_load_atlas("a_mus");
41 | dusk_sprites_upload_atlas(&atlas);
42 |
43 | vizspr = dusk_sprites_make(0, 64, 64,
44 | (Sprite){
45 | .x = SCREEN_WIDTH / 2 - 32,
46 | .y = SCREEN_HEIGHT / 2 - 32,
47 | .base_tid = 0,
48 | });
49 | vz_anim1 = MAKE_ANIM(0, 16);
50 |
51 | // init text engine
52 | REG_DISPCNT |= DCNT_BG1;
53 | tte_init_chr4c(1, BG_CBB(0) | BG_SBB(31), 0, 0x0201, CLR_GRAY, NULL, NULL);
54 | tte_init_con();
55 | // tte_printf("#{P:12,12}audio (bank: %d KB)", soundbank_len / 1000); // this line is problematic on TempGBA
56 | tte_printf("#{P:12,12} § music demo");
57 | tte_printf("#{P:200,140}next >");
58 | }
59 |
60 | void audio_update() {
61 | dusk_frame(); // video frame
62 | mmFrame(); // audio frame
63 |
64 | dusk_sprites_anim_play(vizspr, &vz_anim1);
65 |
66 | int a_press = key_is_down(KEY_A);
67 |
68 | if (a_press) {
69 | // play sfx
70 | mmEffectEx(&boom);
71 | }
72 |
73 | // update sprites
74 | dusk_sprites_update();
75 | }
76 |
77 | void audio_end() {
78 | mmStop();
79 | }
80 |
81 | Scene audio_scene = {
82 | .start = audio_start,
83 | .update = audio_update,
84 | .end = audio_end,
85 | };
--------------------------------------------------------------------------------
/demo/DuskDemo/src/scenes/autumn.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "dusk.h"
3 |
4 | Map atm_map;
5 | SpriteAtlasLayout atlas_layout;
6 | const int GRAVITY = 1;
7 |
8 | typedef struct LeafInfo {
9 | s8 fall_points;
10 | u8 max_fall_points;
11 | u8 side_stage;
12 | u8 side_prd;
13 | s8 slant;
14 | u8 slant_prd;
15 | u16 col;
16 | } LeafInfo;
17 |
18 | #define NUM_LEAVES 32
19 | #define SIDE_STAGE_SZ 35
20 |
21 | const s8 SIDE_STAGES[SIDE_STAGE_SZ] = {5, 5, 5, 4, 4, 3, 3, 2, 1, 0, -1, -2, -3, -3, -4, -4, -5, -5,
22 | -5, -4, -4, -3, -3, -2, -1, 0, 1, 2, 3, 3, 4, 4, 5, 5, 5};
23 | LeafInfo leaves[NUM_LEAVES];
24 |
25 | SpriteAtlasEntry* pick_random_leaf() {
26 | int entry_ix = qran_range(0, atlas_layout.num_entries);
27 | SpriteAtlasEntry* entry = &atlas_layout.entries[entry_ix];
28 | return entry;
29 | }
30 |
31 | Sprite* respawn_leaf(int i, int x, int y) {
32 | SpriteAtlasEntry* leaf_entry = pick_random_leaf();
33 | Sprite* leaf = dusk_sprites_make(
34 | i, leaf_entry->w * 8, leaf_entry->h * 8,
35 | (Sprite){
36 | .x = x,
37 | .y = y,
38 | .base_tid = dusk_sprites_pos_to_tid(leaf_entry->x, leaf_entry->y, atlas_layout.width, atlas_layout.height),
39 | });
40 |
41 | leaves[i].max_fall_points = qran_range(0, 4);
42 | leaves[i].side_prd = qran_range(2, 5);
43 | leaves[i].col = x;
44 | leaves[i].side_stage = qran_range(0, SIDE_STAGE_SZ);
45 | sprites[i].x = leaves[i].col + SIDE_STAGES[leaves[i].side_stage];
46 |
47 | // 30% to have slant
48 | leaves[i].slant = 0;
49 | if (qran_range(0, 10) <= 2) {
50 | leaves[i].slant = qran_range(-1, 2);
51 | leaves[i].slant_prd = qran_range(1, 3);
52 | }
53 |
54 | return leaf;
55 | }
56 |
57 | void autumn_start() {
58 | dusk_init_graphics_mode0();
59 |
60 | // set up background
61 | atm_map = dusk_load_map("september");
62 | map_init_registers();
63 | map_set_onscreen(atm_map);
64 |
65 | // load sprite atlas
66 | dusk_sprites_init();
67 | SpriteAtlas atlas = dusk_load_atlas("a_part");
68 | dusk_sprites_upload_atlas(&atlas);
69 |
70 | // load atlas layout
71 | atlas_layout = dusk_load_atlas_layout("a_part");
72 |
73 | // set up N leaf sprites
74 | for (int i = 0; i < NUM_LEAVES; i++) {
75 | int ix = qran_range(0, SCREEN_WIDTH);
76 | int iy = qran_range(0, SCREEN_HEIGHT);
77 | respawn_leaf(i, ix, iy);
78 | }
79 |
80 | // update map position
81 | BackgroundPoint bg_shift = (BackgroundPoint){0, 0};
82 | map_shift(atm_map, bg_shift);
83 | }
84 |
85 | void autumn_update() {
86 | dusk_frame();
87 |
88 | // update leaves
89 | for (int i = 0; i < NUM_LEAVES; i++) {
90 | // respawn if out of range
91 | if (sprites[i].y > SCREEN_HEIGHT) {
92 | int ix = qran_range(0, SCREEN_WIDTH);
93 | int iy = -8;
94 | respawn_leaf(i, ix, iy);
95 | }
96 | // - motion
97 |
98 | // 1. update fall points
99 | leaves[i].fall_points--;
100 | if (leaves[i].fall_points < 0) {
101 | leaves[i].fall_points = qran_range(0, leaves[i].max_fall_points);
102 | sprites[i].y += GRAVITY;
103 | if ((frame_count % leaves[i].slant_prd) == 0) {
104 | leaves[i].col += leaves[i].slant;
105 | }
106 | }
107 | // 2. update side stages
108 | if ((frame_count % leaves[i].side_prd) == 0) {
109 | leaves[i].side_stage = (leaves[i].side_stage + 1) % SIDE_STAGE_SZ;
110 | sprites[i].x = leaves[i].col + SIDE_STAGES[leaves[i].side_stage];
111 | }
112 | }
113 |
114 | // update sprites
115 | dusk_sprites_update();
116 | }
117 |
118 | void autumn_end() { dusk_free_atlas_layout(&atlas_layout); }
119 |
120 | Scene autumn_scene = {
121 | .start = autumn_start,
122 | .update = autumn_update,
123 | .end = autumn_end,
124 | };
--------------------------------------------------------------------------------
/demo/DuskDemo/src/scenes/background.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "dusk.h"
3 | #include "tonc.h"
4 |
5 | void background_start() {
6 | dusk_init_graphics_mode0();
7 |
8 | // load bg
9 | GritImage bg_img = dusk_load_image("dusk_bg");
10 | dusk_background_upload_raw(&bg_img, 0, 30);
11 |
12 | dusk_background_make(0, BG_REG_32x32, (Background){.x = 0, .y = 0, .cbb = 0, .sbb = 30});
13 | }
14 |
15 | void background_update() { dusk_frame(); }
16 |
17 | void background_end() {}
18 |
19 | Scene background_scene = {
20 | .start = background_start,
21 | .update = background_update,
22 | .end = background_end,
23 | };
--------------------------------------------------------------------------------
/demo/DuskDemo/src/scenes/logo.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "dusk.h"
3 | #include "tonc.h"
4 |
5 | Sprite* logo;
6 | const int FADE_LENGTH = 60; // fade length in frames
7 | int start_frame;
8 | int fade_step;
9 |
10 | void logo_start() {
11 | dusk_init_graphics_mode0();
12 |
13 | start_frame = frame_count;
14 |
15 | pal_bg_mem[0] = 0x0C02; // background color
16 |
17 | // load sprite atlas
18 | dusk_sprites_init();
19 | SpriteAtlas atlas = dusk_load_atlas("a_logo");
20 | dusk_sprites_upload_atlas(&atlas);
21 |
22 | logo = dusk_sprites_make(0, 64, 64,
23 | (Sprite){
24 | .x = SCREEN_WIDTH / 2 - 32,
25 | .y = SCREEN_HEIGHT / 2 - 32,
26 | .base_tid = 0,
27 | });
28 |
29 | // enable blend on this object
30 | OBJ_ATTR* logo_attr = &obj_buffer[0];
31 | obj_set_attr(logo_attr, logo_attr->attr0 | ATTR0_BLEND, logo_attr->attr1, logo_attr->attr2);
32 |
33 | // set up blending registers
34 | REG_BLDCNT = BLD_OBJ | BLD_BG1 | BLD_BLACK;
35 | REG_BLDY = BLDY_BUILD(16);
36 |
37 | fade_step = FADE_LENGTH / 16;
38 |
39 | // ----------
40 |
41 | REG_DISPCNT |= DCNT_BG1;
42 | tte_init_chr4c(1, BG_CBB(0)|BG_SBB(31), 0, 0x0201, CLR_WHITE, &verdana9Font, NULL);
43 | tte_init_con();
44 |
45 | pal_gradient_ex(pal_bg_mem, 1, 4, CLR_YELLOW, CLR_ORANGE);
46 | pal_gradient_ex(pal_bg_mem, 5, 8, CLR_BLACK, CLR_WHITE);
47 |
48 | tte_printf("#{P:12,12}#{ci:4}dusk #{ci:2}demo");
49 | tte_printf("#{P:12,24}#{ci:2}¯¯¯¯¯¯¯");
50 |
51 | tte_printf("#{P:200,140}#{ci:7}start >");
52 | }
53 |
54 | void logo_update() {
55 | dusk_frame();
56 |
57 | int progress = (frame_count - start_frame);
58 | if (progress <= FADE_LENGTH) {
59 | int fade = clamp(progress / fade_step, 0, 16);
60 | REG_BLDY = BLDY_BUILD(16 - fade);
61 | }
62 |
63 | // update sprites
64 | dusk_sprites_update();
65 | }
66 |
67 | void logo_end() {
68 | // clear blending registers
69 | REG_BLDCNT = BLD_OFF;
70 | }
71 |
72 | Scene logo_scene = {
73 | .start = logo_start,
74 | .update = logo_update,
75 | .end = logo_end,
76 | };
--------------------------------------------------------------------------------
/demo/DuskDemo/src/scenes/merge.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "dusk.h"
3 | #include "tonc.h"
4 |
5 | Sprite* me_spr1;
6 | Sprite* me_spr2;
7 | Anim me_anim1;
8 |
9 | void merge_start() {
10 | dusk_init_graphics_mode0();
11 |
12 | pal_bg_mem[0] = 0x0C02; // background color
13 |
14 | // load sprite atlas
15 | dusk_sprites_init();
16 | SpriteAtlas chrs_atlas = dusk_load_atlas("a_chars");
17 | SpriteAtlasLayout chrs_atlas_layout = dusk_load_atlas_layout("a_chars");
18 |
19 | SpriteAtlas logo_atlas = dusk_load_atlas("a_logo");
20 | SpriteAtlasLayout logo_atlas_layout = dusk_load_atlas_layout("a_logo");
21 |
22 | dusk_sprites_upload_atlas_section(&chrs_atlas_layout, &chrs_atlas, &chrs_atlas_layout.entries[2], 0, 0);
23 | dusk_sprites_upload_atlas_section(&logo_atlas_layout, &logo_atlas, &logo_atlas_layout.entries[0], 16, 16);
24 | // dusk_sprites_upload_atlas_section(&logo_atlas_layout, &logo_atlas, &logo_atlas_layout.entries[0], 0, 0);
25 |
26 | me_spr1 = dusk_sprites_make(0, 16, 16, (Sprite){.x = 40, .y = 40, .base_tid = 0, .flags = SPRITEFLAG_PRIORITY(3)});
27 | me_spr2 = dusk_sprites_make(1, 64, 64, (Sprite){.x = 80, .y = 80, .base_tid = 16});
28 | me_anim1 = MAKE_ANIM(0, 4);
29 |
30 |
31 | // REG_DISPCNT |= DCNT_BG1;
32 | // tte_init_chr4c(1, BG_CBB(0) | BG_SBB(31), 0, 0x0201, CLR_GRAY, NULL, NULL);
33 | // tte_init_con();
34 |
35 | // SpriteAtlas print_atlas = logo_atlas;
36 | // SpriteAtlasLayout print_atlas_layout = logo_atlas_layout;
37 |
38 | // printf("ne: %d ", print_atlas_layout.num_entries);
39 | // SpriteAtlasEntry* th_ent = &print_atlas_layout.entries[0];
40 | // printf("ent: %s, %d, %d, %d, %d\n", th_ent->name, th_ent->x, th_ent->y, th_ent->w, th_ent->h);
41 | // printf("atl: %d, %d ", print_atlas.pal_sz, print_atlas.tile_sz);
42 |
43 | // tte_printf("#{P:12,12}merge");
44 | // tte_printf("#{P:200,140}next >");
45 | }
46 |
47 | void merge_update() {
48 | dusk_frame();
49 |
50 | dusk_sprites_anim_play(me_spr1, &me_anim1);
51 |
52 | // update sprites
53 | dusk_sprites_update();
54 | }
55 |
56 | void merge_end() {}
57 |
58 | Scene merge_scene = {
59 | .start = merge_start,
60 | .update = merge_update,
61 | .end = merge_end,
62 | };
--------------------------------------------------------------------------------
/demo/DuskDemo/src/scenes/randbit.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "dusk.h"
3 |
4 | void randbit_start() {
5 | // set up mode 3
6 | dusk_init_graphics_mode3();
7 |
8 | sqran(0);
9 | }
10 |
11 | void fill_garbage() {
12 | for (int x = 0; x < M3_WIDTH; x++) {
13 | for (int y = 0; y < M3_HEIGHT; y++) {
14 | u32 rnd = qran();
15 | u16 col = (rnd & 0xFFFF);
16 | vid_mem[y * M3_WIDTH + x] = col;
17 | }
18 | }
19 | }
20 |
21 | void randbit_update() {
22 | fill_garbage();
23 |
24 | dusk_frame();
25 | }
26 |
27 | void randbit_end() {}
28 |
29 | Scene randbit_scene = {
30 | .start = randbit_start,
31 | .update = randbit_update,
32 | .end = randbit_end,
33 | };
--------------------------------------------------------------------------------
/demo/DuskDemo/src/scenes/thred.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "dusk.h"
3 | #include "tonc.h"
4 |
5 | Sprite* thred;
6 | Anim th_anim1;
7 |
8 | void thred_start() {
9 | dusk_init_graphics_mode0();
10 |
11 | pal_bg_mem[0] = 0x0C02; // background color
12 |
13 | // load sprite atlas
14 | dusk_sprites_init();
15 | SpriteAtlas atlas = dusk_load_atlas("a_thred");
16 | dusk_sprites_upload_atlas(&atlas);
17 |
18 | thred = dusk_sprites_make(0, 64, 64,
19 | (Sprite){
20 | .x = SCREEN_WIDTH / 2 - 32,
21 | .y = SCREEN_HEIGHT / 2 - 32,
22 | .base_tid = 0,
23 | .page = 0,
24 | });
25 |
26 | th_anim1 = MAKE_ANIM(0, 16);
27 |
28 | // ----------
29 |
30 | REG_DISPCNT |= DCNT_BG1;
31 | tte_init_chr4c(1, BG_CBB(0)|BG_SBB(31), 0, 0x0201, CLR_GRAY, NULL, NULL);
32 | tte_init_con();
33 |
34 | tte_printf("#{P:12,12}rendered 3d");
35 | tte_printf("#{P:200,140}next >");
36 | }
37 |
38 | void thred_update() {
39 | dusk_frame();
40 |
41 | dusk_sprites_anim_play(thred, &th_anim1);
42 |
43 | // update sprites
44 | dusk_sprites_update();
45 | }
46 |
47 | void thred_end() {}
48 |
49 | Scene thred_scene = {
50 | .start = thred_start,
51 | .update = thred_update,
52 | .end = thred_end,
53 | };
--------------------------------------------------------------------------------
/demo/Fountain2/.gitignore:
--------------------------------------------------------------------------------
1 | # GBA outputs
2 | *.gba
3 | *.gbfs
4 | *.sav
5 |
6 | # ---> C
7 | # Prerequisites
8 | *.d
9 |
10 | # Object files
11 | *.o
12 | *.ko
13 | *.obj
14 | *.elf
15 |
16 | # Linker output
17 | *.ilk
18 | *.map
19 | *.exp
20 |
21 | # Precompiled Headers
22 | *.gch
23 | *.pch
24 |
25 | # Libraries
26 | *.lib
27 | *.a
28 | *.la
29 | *.lo
30 |
31 | # Shared objects (inc. Windows DLLs)
32 | *.dll
33 | *.so
34 | *.so.*
35 | *.dylib
36 |
37 | # Executables
38 | *.exe
39 | *.out
40 | *.app
41 | *.i*86
42 | *.x86_64
43 | *.hex
44 |
45 | # Debug files
46 | *.dSYM/
47 | *.su
48 | *.idb
49 | *.pdb
50 |
51 | # Kernel Module Compile Results
52 | *.mod*
53 | *.cmd
54 | .tmp_versions/
55 | modules.order
56 | Module.symvers
57 | Mkfile.old
58 | dkms.conf
59 |
60 | # ---> Linux
61 | *~
62 |
63 | # temporary files which can be created if a process still has a handle open of a deleted file
64 | .fuse_hidden*
65 |
66 | # KDE directory preferences
67 | .directory
68 |
69 | # Linux trash folder which might appear on any partition or disk
70 | .Trash-*
71 |
72 | # .nfs files are created when an open file is removed but is still being accessed
73 | .nfs*
74 |
75 |
--------------------------------------------------------------------------------
/demo/Fountain2/LICENSE:
--------------------------------------------------------------------------------
1 | Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Creative
2 | Commons Corporation ("Creative Commons") is not a law firm and does not provide
3 | legal services or legal advice. Distribution of Creative Commons public licenses
4 | does not create a lawyer-client or other relationship. Creative Commons makes
5 | its licenses and related information available on an "as-is" basis. Creative
6 | Commons gives no warranties regarding its licenses, any material licensed
7 | under their terms and conditions, or any related information. Creative Commons
8 | disclaims all liability for damages resulting from their use to the fullest
9 | extent possible.
10 |
11 | Using Creative Commons Public Licenses
12 |
13 | Creative Commons public licenses provide a standard set of terms and conditions
14 | that creators and other rights holders may use to share original works of
15 | authorship and other material subject to copyright and certain other rights
16 | specified in the public license below. The following considerations are for
17 | informational purposes only, are not exhaustive, and do not form part of our
18 | licenses.
19 |
20 | Considerations for licensors: Our public licenses are intended for use by
21 | those authorized to give the public permission to use material in ways otherwise
22 | restricted by copyright and certain other rights. Our licenses are irrevocable.
23 | Licensors should read and understand the terms and conditions of the license
24 | they choose before applying it. Licensors should also secure all rights necessary
25 | before applying our licenses so that the public can reuse the material as
26 | expected. Licensors should clearly mark any material not subject to the license.
27 | This includes other CC-licensed material, or material used under an exception
28 | or limitation to copyright. More considerations for licensors : wiki.creativecommons.org/Considerations_for_licensors
29 |
30 | Considerations for the public: By using one of our public licenses, a licensor
31 | grants the public permission to use the licensed material under specified
32 | terms and conditions. If the licensor's permission is not necessary for any
33 | reason–for example, because of any applicable exception or limitation to copyright–then
34 | that use is not regulated by the license. Our licenses grant only permissions
35 | under copyright and certain other rights that a licensor has authority to
36 | grant. Use of the licensed material may still be restricted for other reasons,
37 | including because others have copyright or other rights in the material. A
38 | licensor may make special requests, such as asking that all changes be marked
39 | or described. Although not required by our licenses, you are encouraged to
40 | respect those requests where reasonable. More considerations for the public
41 | : wiki.creativecommons.org/Considerations_for_licensees
42 |
43 | Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Public
44 | License
45 |
46 | By exercising the Licensed Rights (defined below), You accept and agree to
47 | be bound by the terms and conditions of this Creative Commons Attribution-NonCommercial-ShareAlike
48 | 4.0 International Public License ("Public License"). To the extent this Public
49 | License may be interpreted as a contract, You are granted the Licensed Rights
50 | in consideration of Your acceptance of these terms and conditions, and the
51 | Licensor grants You such rights in consideration of benefits the Licensor
52 | receives from making the Licensed Material available under these terms and
53 | conditions.
54 |
55 | Section 1 – Definitions.
56 |
57 | a. Adapted Material means material subject to Copyright and Similar Rights
58 | that is derived from or based upon the Licensed Material and in which the
59 | Licensed Material is translated, altered, arranged, transformed, or otherwise
60 | modified in a manner requiring permission under the Copyright and Similar
61 | Rights held by the Licensor. For purposes of this Public License, where the
62 | Licensed Material is a musical work, performance, or sound recording, Adapted
63 | Material is always produced where the Licensed Material is synched in timed
64 | relation with a moving image.
65 |
66 | b. Adapter's License means the license You apply to Your Copyright and Similar
67 | Rights in Your contributions to Adapted Material in accordance with the terms
68 | and conditions of this Public License.
69 |
70 | c. BY-NC-SA Compatible License means a license listed at creativecommons.org/compatiblelicenses,
71 | approved by Creative Commons as essentially the equivalent of this Public
72 | License.
73 |
74 | d. Copyright and Similar Rights means copyright and/or similar rights closely
75 | related to copyright including, without limitation, performance, broadcast,
76 | sound recording, and Sui Generis Database Rights, without regard to how the
77 | rights are labeled or categorized. For purposes of this Public License, the
78 | rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights.
79 |
80 | e. Effective Technological Measures means those measures that, in the absence
81 | of proper authority, may not be circumvented under laws fulfilling obligations
82 | under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996,
83 | and/or similar international agreements.
84 |
85 | f. Exceptions and Limitations means fair use, fair dealing, and/or any other
86 | exception or limitation to Copyright and Similar Rights that applies to Your
87 | use of the Licensed Material.
88 |
89 | g. License Elements means the license attributes listed in the name of a Creative
90 | Commons Public License. The License Elements of this Public License are Attribution,
91 | NonCommercial, and ShareAlike.
92 |
93 | h. Licensed Material means the artistic or literary work, database, or other
94 | material to which the Licensor applied this Public License.
95 |
96 | i. Licensed Rights means the rights granted to You subject to the terms and
97 | conditions of this Public License, which are limited to all Copyright and
98 | Similar Rights that apply to Your use of the Licensed Material and that the
99 | Licensor has authority to license.
100 |
101 | j. Licensor means the individual(s) or entity(ies) granting rights under this
102 | Public License.
103 |
104 | k. NonCommercial means not primarily intended for or directed towards commercial
105 | advantage or monetary compensation. For purposes of this Public License, the
106 | exchange of the Licensed Material for other material subject to Copyright
107 | and Similar Rights by digital file-sharing or similar means is NonCommercial
108 | provided there is no payment of monetary compensation in connection with the
109 | exchange.
110 |
111 | l. Share means to provide material to the public by any means or process that
112 | requires permission under the Licensed Rights, such as reproduction, public
113 | display, public performance, distribution, dissemination, communication, or
114 | importation, and to make material available to the public including in ways
115 | that members of the public may access the material from a place and at a time
116 | individually chosen by them.
117 |
118 | m. Sui Generis Database Rights means rights other than copyright resulting
119 | from Directive 96/9/EC of the European Parliament and of the Council of 11
120 | March 1996 on the legal protection of databases, as amended and/or succeeded,
121 | as well as other essentially equivalent rights anywhere in the world.
122 |
123 | n. You means the individual or entity exercising the Licensed Rights under
124 | this Public License. Your has a corresponding meaning.
125 |
126 | Section 2 – Scope.
127 |
128 | a. License grant.
129 |
130 | 1. Subject to the terms and conditions of this Public License, the Licensor
131 | hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive,
132 | irrevocable license to exercise the Licensed Rights in the Licensed Material
133 | to:
134 |
135 | A. reproduce and Share the Licensed Material, in whole or in part, for NonCommercial
136 | purposes only; and
137 |
138 | B. produce, reproduce, and Share Adapted Material for NonCommercial purposes
139 | only.
140 |
141 | 2. Exceptions and Limitations. For the avoidance of doubt, where Exceptions
142 | and Limitations apply to Your use, this Public License does not apply, and
143 | You do not need to comply with its terms and conditions.
144 |
145 | 3. Term. The term of this Public License is specified in Section 6(a).
146 |
147 | 4. Media and formats; technical modifications allowed. The Licensor authorizes
148 | You to exercise the Licensed Rights in all media and formats whether now known
149 | or hereafter created, and to make technical modifications necessary to do
150 | so. The Licensor waives and/or agrees not to assert any right or authority
151 | to forbid You from making technical modifications necessary to exercise the
152 | Licensed Rights, including technical modifications necessary to circumvent
153 | Effective Technological Measures. For purposes of this Public License, simply
154 | making modifications authorized by this Section 2(a)(4) never produces Adapted
155 | Material.
156 |
157 | 5. Downstream recipients.
158 |
159 | A. Offer from the Licensor – Licensed Material. Every recipient of the Licensed
160 | Material automatically receives an offer from the Licensor to exercise the
161 | Licensed Rights under the terms and conditions of this Public License.
162 |
163 | B. Additional offer from the Licensor – Adapted Material. Every recipient
164 | of Adapted Material from You automatically receives an offer from the Licensor
165 | to exercise the Licensed Rights in the Adapted Material under the conditions
166 | of the Adapter's License You apply.
167 |
168 | C. No downstream restrictions. You may not offer or impose any additional
169 | or different terms or conditions on, or apply any Effective Technological
170 | Measures to, the Licensed Material if doing so restricts exercise of the Licensed
171 | Rights by any recipient of the Licensed Material.
172 |
173 | 6. No endorsement. Nothing in this Public License constitutes or may be construed
174 | as permission to assert or imply that You are, or that Your use of the Licensed
175 | Material is, connected with, or sponsored, endorsed, or granted official status
176 | by, the Licensor or others designated to receive attribution as provided in
177 | Section 3(a)(1)(A)(i).
178 |
179 | b. Other rights.
180 |
181 | 1. Moral rights, such as the right of integrity, are not licensed under this
182 | Public License, nor are publicity, privacy, and/or other similar personality
183 | rights; however, to the extent possible, the Licensor waives and/or agrees
184 | not to assert any such rights held by the Licensor to the limited extent necessary
185 | to allow You to exercise the Licensed Rights, but not otherwise.
186 |
187 | 2. Patent and trademark rights are not licensed under this Public License.
188 |
189 | 3. To the extent possible, the Licensor waives any right to collect royalties
190 | from You for the exercise of the Licensed Rights, whether directly or through
191 | a collecting society under any voluntary or waivable statutory or compulsory
192 | licensing scheme. In all other cases the Licensor expressly reserves any right
193 | to collect such royalties, including when the Licensed Material is used other
194 | than for NonCommercial purposes.
195 |
196 | Section 3 – License Conditions.
197 |
198 | Your exercise of the Licensed Rights is expressly made subject to the following
199 | conditions.
200 |
201 | a. Attribution.
202 |
203 | 1. If You Share the Licensed Material (including in modified form), You must:
204 |
205 | A. retain the following if it is supplied by the Licensor with the Licensed
206 | Material:
207 |
208 | i. identification of the creator(s) of the Licensed Material and any others
209 | designated to receive attribution, in any reasonable manner requested by the
210 | Licensor (including by pseudonym if designated);
211 |
212 | ii. a copyright notice;
213 |
214 | iii. a notice that refers to this Public License;
215 |
216 | iv. a notice that refers to the disclaimer of warranties;
217 |
218 |
219 |
220 | v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable;
221 |
222 | B. indicate if You modified the Licensed Material and retain an indication
223 | of any previous modifications; and
224 |
225 | C. indicate the Licensed Material is licensed under this Public License, and
226 | include the text of, or the URI or hyperlink to, this Public License.
227 |
228 | 2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner
229 | based on the medium, means, and context in which You Share the Licensed Material.
230 | For example, it may be reasonable to satisfy the conditions by providing a
231 | URI or hyperlink to a resource that includes the required information.
232 |
233 | 3. If requested by the Licensor, You must remove any of the information required
234 | by Section 3(a)(1)(A) to the extent reasonably practicable.
235 |
236 | b. ShareAlike.In addition to the conditions in Section 3(a), if You Share
237 | Adapted Material You produce, the following conditions also apply.
238 |
239 | 1. The Adapter's License You apply must be a Creative Commons license with
240 | the same License Elements, this version or later, or a BY-NC-SA Compatible
241 | License.
242 |
243 | 2. You must include the text of, or the URI or hyperlink to, the Adapter's
244 | License You apply. You may satisfy this condition in any reasonable manner
245 | based on the medium, means, and context in which You Share Adapted Material.
246 |
247 | 3. You may not offer or impose any additional or different terms or conditions
248 | on, or apply any Effective Technological Measures to, Adapted Material that
249 | restrict exercise of the rights granted under the Adapter's License You apply.
250 |
251 | Section 4 – Sui Generis Database Rights.
252 |
253 | Where the Licensed Rights include Sui Generis Database Rights that apply to
254 | Your use of the Licensed Material:
255 |
256 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract,
257 | reuse, reproduce, and Share all or a substantial portion of the contents of
258 | the database for NonCommercial purposes only;
259 |
260 | b. if You include all or a substantial portion of the database contents in
261 | a database in which You have Sui Generis Database Rights, then the database
262 | in which You have Sui Generis Database Rights (but not its individual contents)
263 | is Adapted Material, including for purposes of Section 3(b); and
264 |
265 | c. You must comply with the conditions in Section 3(a) if You Share all or
266 | a substantial portion of the contents of the database.
267 |
268 | For the avoidance of doubt, this Section 4 supplements and does not replace
269 | Your obligations under this Public License where the Licensed Rights include
270 | other Copyright and Similar Rights.
271 |
272 | Section 5 – Disclaimer of Warranties and Limitation of Liability.
273 |
274 | a. Unless otherwise separately undertaken by the Licensor, to the extent possible,
275 | the Licensor offers the Licensed Material as-is and as-available, and makes
276 | no representations or warranties of any kind concerning the Licensed Material,
277 | whether express, implied, statutory, or other. This includes, without limitation,
278 | warranties of title, merchantability, fitness for a particular purpose, non-infringement,
279 | absence of latent or other defects, accuracy, or the presence or absence of
280 | errors, whether or not known or discoverable. Where disclaimers of warranties
281 | are not allowed in full or in part, this disclaimer may not apply to You.
282 |
283 | b. To the extent possible, in no event will the Licensor be liable to You
284 | on any legal theory (including, without limitation, negligence) or otherwise
285 | for any direct, special, indirect, incidental, consequential, punitive, exemplary,
286 | or other losses, costs, expenses, or damages arising out of this Public License
287 | or use of the Licensed Material, even if the Licensor has been advised of
288 | the possibility of such losses, costs, expenses, or damages. Where a limitation
289 | of liability is not allowed in full or in part, this limitation may not apply
290 | to You.
291 |
292 | c. The disclaimer of warranties and limitation of liability provided above
293 | shall be interpreted in a manner that, to the extent possible, most closely
294 | approximates an absolute disclaimer and waiver of all liability.
295 |
296 | Section 6 – Term and Termination.
297 |
298 | a. This Public License applies for the term of the Copyright and Similar Rights
299 | licensed here. However, if You fail to comply with this Public License, then
300 | Your rights under this Public License terminate automatically.
301 |
302 | b. Where Your right to use the Licensed Material has terminated under Section
303 | 6(a), it reinstates:
304 |
305 | 1. automatically as of the date the violation is cured, provided it is cured
306 | within 30 days of Your discovery of the violation; or
307 |
308 | 2. upon express reinstatement by the Licensor.
309 |
310 | For the avoidance of doubt, this Section 6(b) does not affect any right the
311 | Licensor may have to seek remedies for Your violations of this Public License.
312 |
313 | c. For the avoidance of doubt, the Licensor may also offer the Licensed Material
314 | under separate terms or conditions or stop distributing the Licensed Material
315 | at any time; however, doing so will not terminate this Public License.
316 |
317 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public License.
318 |
319 | Section 7 – Other Terms and Conditions.
320 |
321 | a. The Licensor shall not be bound by any additional or different terms or
322 | conditions communicated by You unless expressly agreed.
323 |
324 | b. Any arrangements, understandings, or agreements regarding the Licensed
325 | Material not stated herein are separate from and independent of the terms
326 | and conditions of this Public License.
327 |
328 | Section 8 – Interpretation.
329 |
330 | a. For the avoidance of doubt, this Public License does not, and shall not
331 | be interpreted to, reduce, limit, restrict, or impose conditions on any use
332 | of the Licensed Material that could lawfully be made without permission under
333 | this Public License.
334 |
335 | b. To the extent possible, if any provision of this Public License is deemed
336 | unenforceable, it shall be automatically reformed to the minimum extent necessary
337 | to make it enforceable. If the provision cannot be reformed, it shall be severed
338 | from this Public License without affecting the enforceability of the remaining
339 | terms and conditions.
340 |
341 | c. No term or condition of this Public License will be waived and no failure
342 | to comply consented to unless expressly agreed to by the Licensor.
343 |
344 | d. Nothing in this Public License constitutes or may be interpreted as a limitation
345 | upon, or waiver of, any privileges and immunities that apply to the Licensor
346 | or You, including from the legal processes of any jurisdiction or authority.
347 |
348 | Creative Commons is not a party to its public licenses. Notwithstanding, Creative
349 | Commons may elect to apply one of its public licenses to material it publishes
350 | and in those instances will be considered the "Licensor." The text of the
351 | Creative Commons public licenses is dedicated to the public domain under the
352 | CC0 Public Domain Dedication. Except for the limited purpose of indicating
353 | that material is shared under a Creative Commons public license or as otherwise
354 | permitted by the Creative Commons policies published at creativecommons.org/policies,
355 | Creative Commons does not authorize the use of the trademark "Creative Commons"
356 | or any other trademark or logo of Creative Commons without its prior written
357 | consent including, without limitation, in connection with any unauthorized
358 | modifications to any of its public licenses or any other arrangements, understandings,
359 | or agreements concerning use of licensed material. For the avoidance of doubt,
360 | this paragraph does not form part of the public licenses.
361 |
362 | Creative Commons may be contacted at creativecommons.org.
363 |
--------------------------------------------------------------------------------
/demo/Fountain2/Makefile:
--------------------------------------------------------------------------------
1 | PATH := $(DEVKITARM)/bin:$(PATH)
2 |
3 | TITLE := Fountain2
4 |
5 | # Project settings
6 |
7 | NAME := $(TITLE)
8 | SOURCE_DIR := src
9 | LIB_DIR := lib
10 | DUSK_DIR := ../../src/dusk
11 | DATA_DIR := asset/build
12 | SPECS := -specs=gba.specs
13 |
14 | # Compilation settings
15 |
16 | CROSS ?= arm-none-eabi-
17 | AS := $(CROSS)as
18 | CC := $(CROSS)gcc
19 | LD := $(CROSS)gcc
20 | OBJCOPY := $(CROSS)objcopy
21 |
22 | ARCH := -mthumb-interwork -mthumb
23 |
24 | INCFLAGS := -I$(DUSK_DIR)/include -I$(DEVKITPRO)/libtonc/include -I$(DEVKITPRO)/libgba/include -I$(SOURCE_DIR) -I$(DATA_DIR)
25 | LIBFLAGS := -L$(DUSK_DIR)/lib -ldusk -L$(DEVKITPRO)/libtonc/lib -ltonc -L$(DEVKITPRO)/libgba/lib -lmm
26 | ASFLAGS := -mthumb-interwork
27 | CFLAGS := $(ARCH) -Wall -Werror -fno-strict-aliasing -mcpu=arm7tdmi -mtune=arm7tdmi $(INCFLAGS) $(LIBFLAGS)
28 | LDFLAGS := $(ARCH) $(SPECS) $(LIBFLAGS) -Wl,-Map,$(TITLE).map
29 |
30 | ASSET_MKFLAGS :=
31 | DUSK_MKFLAGS :=
32 |
33 | ifeq ($(DEBUG),1)
34 | CFLAGS += -O2 -g
35 | DUSK_MKFLAGS += DEBUG=1
36 | else
37 | # non-debug
38 | CFLAGS += -O2 -fomit-frame-pointer -ffast-math
39 | endif
40 |
41 | .PHONY : build clean
42 |
43 | # Find and predetermine all relevant source files
44 |
45 | APP_MAIN_SOURCE := $(shell find $(SOURCE_DIR) -name '*main.c')
46 | APP_MAIN_OBJECT := $(APP_MAIN_SOURCE:%.c=%.o)
47 | APP_SOURCES_C := $(shell find $(SOURCE_DIR) -name '*.c' ! -name "*main.c" ! -name "*.test.c")
48 | APP_SOURCES_S := $(shell find $(SOURCE_DIR) -name '*.s')
49 | APP_OBJECTS_C := $(APP_SOURCES_C:%.c=%.o)
50 | APP_OBJECTS_S := $(APP_SOURCES_S:%.s=%.o)
51 | APP_OBJECTS := $(APP_OBJECTS_C) $(APP_OBJECTS_S)
52 |
53 | # Build commands and dependencies
54 |
55 | .PHONY: libs assets
56 |
57 | build: assets libs $(NAME).gba
58 |
59 | no-content: libs $(NAME)-code.gba
60 |
61 | libs:
62 | cd $(DUSK_DIR) && make $(DUSK_MKFLAGS)
63 |
64 | assets:
65 | cd asset/build && make $(ASSET_MKFLAGS)
66 |
67 | $(NAME).gba : $(NAME)-code.gba $(NAME).gbfs
68 | cat $^ > $(NAME).gba
69 |
70 | $(NAME)-code.gba : $(NAME).elf
71 | $(OBJCOPY) -v -O binary $< $@
72 | -@gbafix $@ -t$(NAME)
73 | padbin 256 $@
74 |
75 | $(NAME).elf : $(APP_OBJECTS) $(APP_MAIN_OBJECT)
76 | $(LD) $^ $(LDFLAGS) -o $@
77 |
78 | $(APP_OBJECTS_C) : %.o : %.c assets libs
79 | $(CC) $(CFLAGS) -c $< -o $@
80 |
81 | $(APP_OBJECTS_S) : %.o : %.s
82 | $(CC) $(CFLAGS) -c $< -o $@
83 |
84 | $(APP_MAIN_OBJECT) : $(APP_MAIN_SOURCE)
85 | $(CC) $(CFLAGS) -c $< -o $@
86 |
87 | $(NAME).gbfs: assets
88 | gbfs $@ $(shell find $(DATA_DIR) -name '*.bin')
89 |
90 | clean:
91 | @rm -fv *.gba
92 | @rm -fv *.elf
93 | @rm -fv *.sav
94 | @rm -fv *.gbfs
95 | @rm -rf $(APP_OBJECTS)
96 | @rm -rf $(APP_MAIN_OBJECT)
97 | cd $(DUSK_DIR) && make clean
98 | cd asset/build && make clean
99 |
--------------------------------------------------------------------------------
/demo/Fountain2/asset/build/.gitignore:
--------------------------------------------------------------------------------
1 | # generated data
2 | *.bin
3 | *.h
4 | atl*
5 | a_*
--------------------------------------------------------------------------------
/demo/Fountain2/asset/build/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: clean atlas
2 |
3 | IMGS_DIR := ../img
4 | MAPS_DIR := ../map
5 | RAWMAPS_DIR := ../rawmap
6 | SOUND_DIR := ../snd
7 |
8 | ATLS_SRC := $(shell find $(IMGS_DIR) -mindepth 1 -type d)
9 | ATLS_OUT := $(patsubst %,a_%_,$(notdir $(ATLS_SRC)))
10 | ATLS_PNG := $(ATLS_OUT:%_=%_0.png)
11 |
12 | IMGS_BIN := $(notdir $(ATLS_PNG:%.png=%.img.bin))
13 |
14 | RAWMAPS_SRC := $(shell find $(RAWMAPS_DIR) -name '*.png')
15 | RAWMAPS_BIN := $(notdir $(RAWMAPS_SRC:%.png=%.bin))
16 |
17 | MAPS_SRC := $(shell find $(MAPS_DIR) -name '*.tmx')
18 | MAPS_BIN := $(notdir $(MAPS_SRC:%.tmx=%.bin))
19 |
20 | SOUND_SRC := $(shell find $(SOUND_DIR) -type f)
21 | SOUND_BIN := soundbank.bin
22 | SOUND_H := soundbank.h
23 |
24 | GRIT_FLAGS := -gt -p -g -gB 8 -gu32 -pu32 -ftb -fh!
25 | CRUNCH_FLAGS := -p -j -b -s256 -p0
26 |
27 | all: $(MAPS_BIN) $(RAWMAPS_BIN) $(IMGS_BIN) $(SOUND_BIN) $(SOUND_H)
28 |
29 | clean:
30 | rm -rfv *.bin
31 | rm -rfv *.b
32 | rm -rfv *.h
33 | rm -rfv atl*
34 | rm -rfv *.png
35 | rm -rfv *.hash
36 | rm -rfv *.json
37 |
38 | # define a function: atlpng2grit(size), this will set Mw and Mh to size
39 | atlpng2grit = grit "$<" $(GRIT_FLAGS) -Mh $(1) -Mw $(1) -o "$@"
40 |
41 | # default rule for atlpng -> img bin
42 | %.img.bin: %.png
43 | grit "$<" $(GRIT_FLAGS) -o "$@"
44 |
45 | # import custom recipes
46 | include custom.mk
47 |
48 | # rule for building atlas pngs from sprite dirs
49 | # build a_thing_
50 | a_%_: ../img/%
51 | crunch_gen "$@" "$<" $(CRUNCH_FLAGS)
52 | # convert a_thing_ to a_thing_0.png (fake recipe)
53 | $(ATLS_PNG): $(ATLS_OUT)
54 | @true
55 |
56 | # rule for building tmx maps
57 | %.bin: ../map/%.tmx
58 | Tiled2GBA -b $< $@
59 |
60 | # rule for building raw maps
61 | %.bin: ../rawmap/%.png
62 | grit "$<" -p -m -g -gB 4 -gu32 -pu32 -ftb -o "$@"
63 |
64 | # rule for building soundbank
65 | $(SOUND_BIN) $(SOUND_H): $(SOUND_SRC)
66 | # @mmutil $^ -osoundbank.bin -hsoundbank.h
67 | @true
68 |
69 | # debug:
70 | # $(foreach var,$(.VARIABLES),$(info $(var) = $($(var))))
--------------------------------------------------------------------------------
/demo/Fountain2/asset/build/custom.mk:
--------------------------------------------------------------------------------
1 | a_chars_0.img.bin: a_chars_0.png
2 | $(call atlpng2grit,2)
--------------------------------------------------------------------------------
/demo/Fountain2/asset/img/chars/egg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/Fountain2/asset/img/chars/egg.png
--------------------------------------------------------------------------------
/demo/Fountain2/asset/img/chars/gob.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/Fountain2/asset/img/chars/gob.png
--------------------------------------------------------------------------------
/demo/Fountain2/asset/img/chars/kik.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/Fountain2/asset/img/chars/kik.png
--------------------------------------------------------------------------------
/demo/Fountain2/asset/img/logo/dusk.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/Fountain2/asset/img/logo/dusk.png
--------------------------------------------------------------------------------
/demo/Fountain2/asset/map/central.tmx:
--------------------------------------------------------------------------------
1 |
2 |
10 |
--------------------------------------------------------------------------------
/demo/Fountain2/asset/map/east.tmx:
--------------------------------------------------------------------------------
1 |
2 |
10 |
--------------------------------------------------------------------------------
/demo/Fountain2/asset/map/fountain_tiles.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/demo/Fountain2/asset/map/fountain_tiles.png
--------------------------------------------------------------------------------
/demo/Fountain2/asset/map/fountain_tiles.tsx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/demo/Fountain2/asset/map/north.tmx:
--------------------------------------------------------------------------------
1 |
2 |
10 |
--------------------------------------------------------------------------------
/demo/Fountain2/asset/map/northwest.tmx:
--------------------------------------------------------------------------------
1 |
2 |
10 |
--------------------------------------------------------------------------------
/demo/Fountain2/asset/map/west.tmx:
--------------------------------------------------------------------------------
1 |
2 |
10 |
--------------------------------------------------------------------------------
/demo/Fountain2/src/fountain2.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "dusk.h"
3 | #include "contrib/gbamap.h"
4 |
5 | Map current_map;
6 | Sprite* eggcat;
7 | Anim walk;
8 | const int WALK_SPEED = 1;
9 | BackgroundPoint bg_shift;
10 |
11 | #define ROOMS_GRID_SZ 3
12 | char* rooms[ROOMS_GRID_SZ][ROOMS_GRID_SZ];
13 |
14 | /** virtual position */
15 | typedef struct VPos {
16 | short x, y;
17 | } VPos;
18 |
19 | VPos eggcat_vpos;
20 | VPos room_pos;
21 |
22 | #define SAVE_MAGIC 0xF0
23 | void load_save() {
24 | // check if save valid
25 | if (sram_mem[0] != SAVE_MAGIC)
26 | return;
27 |
28 | // load data
29 | int p = 1;
30 |
31 | SV_LOAD_ITEM(eggcat_vpos, p);
32 | SV_LOAD_ITEM(room_pos, p);
33 | }
34 |
35 | void write_save() {
36 | // set magic flag
37 | sram_mem[0] = SAVE_MAGIC;
38 |
39 | // save data
40 | int p = 1;
41 |
42 | SV_SAVE_ITEM(eggcat_vpos, p);
43 | SV_SAVE_ITEM(room_pos, p);
44 | }
45 |
46 | void fountain_start() {
47 | dusk_init_graphics_mode0();
48 |
49 | memset(rooms, 0, sizeof(rooms));
50 | rooms[1][1] = "central";
51 | rooms[1][0] = "north";
52 | rooms[0][1] = "west";
53 | rooms[2][1] = "east";
54 | rooms[0][0] = "northwest";
55 |
56 | // vars
57 | bg_shift = (BackgroundPoint){128, 248};
58 | eggcat_vpos = (VPos){128, 248};
59 | room_pos = (VPos){1, 1};
60 |
61 | // read save data
62 | load_save();
63 |
64 | // set up background
65 | current_map = dusk_load_map(rooms[room_pos.x][room_pos.y]);
66 | map_init_registers();
67 | map_set_onscreen(current_map);
68 |
69 | // load sprite atlas
70 | dusk_sprites_init();
71 | SpriteAtlas atlas = dusk_load_atlas("a_chars");
72 | dusk_sprites_upload_atlas(&atlas);
73 |
74 | // make eggcat sprite (&sprites[0])
75 | eggcat = dusk_sprites_make(0, 16, 16,
76 | (Sprite){.x = SCREEN_WIDTH / 2 - 8,
77 | .y = SCREEN_HEIGHT / 2 - 8,
78 | .base_tid = 32,
79 | .page = 0,
80 | .flags = SPRITEFLAG_PRIORITY(3)});
81 | walk = MAKE_ANIM(0, 4);
82 | }
83 |
84 | /** update background and sprite from pos */
85 | void adjust_background_to_player_vpos() {
86 | // update bg scroll
87 | bg_shift.x = eggcat_vpos.x;
88 | bg_shift.y = eggcat_vpos.y;
89 |
90 | /** keeps track of shift that goes beyond shifting bg.
91 | * negative means in the UL corner, positive is in the DR corner. */
92 | VPos bg_overlap = (VPos){0, 0};
93 |
94 | // attempt to clamp (512x512 maps)
95 | if (eggcat_vpos.y < 0) {
96 | bg_overlap.y = eggcat_vpos.y;
97 | bg_shift.y = 0;
98 | }
99 |
100 | if (eggcat_vpos.x < 0) {
101 | bg_overlap.x = eggcat_vpos.x;
102 | bg_shift.x = 0;
103 | }
104 | const int BG_CUT_Y = 512 - SCREEN_HEIGHT;
105 | const int BG_CUT_X = 512 - SCREEN_WIDTH;
106 | if (eggcat_vpos.y > BG_CUT_Y) {
107 | bg_overlap.y = eggcat_vpos.y - BG_CUT_Y;
108 | bg_shift.y = BG_CUT_Y;
109 | }
110 | if (eggcat_vpos.x > BG_CUT_X) {
111 | bg_overlap.x = eggcat_vpos.x - BG_CUT_X;
112 | bg_shift.x = BG_CUT_X;
113 | }
114 |
115 | // now apply the remaining overlap to the sprite position
116 | eggcat->x = SCREEN_WIDTH / 2 - 8;
117 | eggcat->y = SCREEN_HEIGHT / 2 - 8;
118 | if (ABS(bg_overlap.x) > 0) {
119 | eggcat->x += bg_overlap.x;
120 | }
121 | if (ABS(bg_overlap.y) > 0) {
122 | eggcat->y += bg_overlap.y;
123 | }
124 | }
125 |
126 | void check_room_doors() {
127 | // check room doors
128 | VPos new_room_pos = room_pos;
129 | bool door_l = false, door_u = false, door_r = false, door_d = false;
130 |
131 | const int UL_CUT_X = -120;
132 | const int UL_CUT_Y = -80;
133 |
134 | if (eggcat_vpos.x < UL_CUT_X) {
135 | new_room_pos.x -= 1;
136 | door_l = true;
137 | }
138 | if (eggcat_vpos.y < UL_CUT_Y) {
139 | new_room_pos.y -= 1;
140 | door_u = true;
141 | }
142 | if (eggcat_vpos.x > 512 + UL_CUT_X) {
143 | new_room_pos.x += 1;
144 | door_r = true;
145 | }
146 | if (eggcat_vpos.y > 512 + UL_CUT_Y) {
147 | new_room_pos.y += 1;
148 | door_d = true;
149 | }
150 | bool door_lr = door_l || door_r;
151 | bool door_ud = door_u || door_d;
152 | bool entered = door_lr || door_ud;
153 | // make sure it's a valid index
154 | if (entered && (new_room_pos.x >= 0 && new_room_pos.x < ROOMS_GRID_SZ) &&
155 | (new_room_pos.y >= 0 && new_room_pos.y < ROOMS_GRID_SZ)) {
156 | // make sure the room exists
157 | char* room_name = rooms[new_room_pos.x][new_room_pos.y];
158 | if (room_name) {
159 | // switch room
160 | room_pos = new_room_pos;
161 | current_map = dusk_load_map(rooms[room_pos.x][room_pos.y]);
162 | map_set_onscreen(current_map);
163 |
164 | // set new eggcat vpos
165 | if (door_lr) {
166 | if (door_l) {
167 | eggcat_vpos.x = 512 + UL_CUT_X;
168 | }
169 | if (door_r) {
170 | eggcat_vpos.x = UL_CUT_X;
171 | }
172 | }
173 | if (door_ud) {
174 | if (door_u) {
175 | eggcat_vpos.y = 512 + UL_CUT_Y;
176 | }
177 | if (door_d) {
178 | eggcat_vpos.y = UL_CUT_Y;
179 | }
180 | }
181 | }
182 | }
183 | }
184 |
185 | void fountain_update() {
186 | dusk_frame();
187 |
188 | // input
189 | int y_move = key_tri_vert();
190 | int x_move = key_tri_horz();
191 | bool moving = (y_move != 0 || x_move != 0);
192 |
193 | // update pos
194 | eggcat_vpos.x += x_move * WALK_SPEED;
195 | eggcat_vpos.y += y_move * WALK_SPEED;
196 |
197 | adjust_background_to_player_vpos();
198 |
199 | check_room_doors();
200 |
201 | if (moving)
202 | dusk_sprites_anim_play(eggcat, &walk);
203 | else
204 | eggcat->page = 0;
205 |
206 | // update map position
207 | map_shift(current_map, bg_shift);
208 |
209 | // update sprites
210 | dusk_sprites_update();
211 |
212 | // write save data
213 | if (frame_count % 60 == 0) {
214 | write_save();
215 | }
216 | }
217 |
218 | void fountain_end() {}
219 |
220 | Scene fountain_scene = {
221 | .start = fountain_start,
222 | .update = fountain_update,
223 | .end = fountain_end,
224 | };
--------------------------------------------------------------------------------
/demo/Fountain2/src/logo.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "dusk.h"
3 | #include "tonc.h"
4 | #include "scenes.h"
5 |
6 | Sprite* logo;
7 | const int FADE_LENGTH = 30; // fade length in frames
8 | int start_frame;
9 | int fade_step; // frames per fade unit
10 |
11 | void logo_start() {
12 | dusk_init_graphics_mode0();
13 |
14 | start_frame = frame_count;
15 |
16 | // load sprite atlas
17 | dusk_sprites_init();
18 | SpriteAtlas atlas = dusk_load_atlas("a_logo");
19 | dusk_sprites_upload_atlas(&atlas);
20 |
21 | logo = dusk_sprites_make(0, 64, 64,
22 | (Sprite){
23 | .x = SCREEN_WIDTH / 2 - 32,
24 | .y = SCREEN_HEIGHT / 2 - 32,
25 | .base_tid = 0,
26 | });
27 |
28 | // enable blend on this object
29 | OBJ_ATTR* logo_attr = &obj_buffer[0];
30 | obj_set_attr(logo_attr, logo_attr->attr0 | ATTR0_BLEND, logo_attr->attr1, logo_attr->attr2);
31 |
32 | // set up blending registers
33 | REG_BLDCNT = BLD_OBJ | BLD_BG1 | BLD_BLACK;
34 | REG_BLDY = BLDY_BUILD(16);
35 |
36 | fade_step = FADE_LENGTH / 16;
37 |
38 | // ----------
39 |
40 | REG_DISPCNT |= DCNT_BG1;
41 | tte_init_chr4c(1, BG_CBB(0)|BG_SBB(31), 0, 0x0201, CLR_WHITE, NULL, NULL);
42 | tte_init_con();
43 |
44 | pal_gradient_ex(pal_bg_mem, 1, 4, 0x6F98, 0x4964);
45 |
46 | tte_printf("#{P:12,12}#{ci:1}fountain #{ci:3}v2.0");
47 | tte_printf("#{P:12,24}#{ci:2}¯¯¯¯¯¯¯¯¯");
48 | }
49 |
50 | void logo_update() {
51 | dusk_frame();
52 |
53 | int progress = (frame_count - start_frame);
54 | if (progress <= FADE_LENGTH) {
55 | int fade = clamp(progress / fade_step, 0, 16);
56 | REG_BLDY = BLDY_BUILD(16 - fade);
57 | } else if (progress <= FADE_LENGTH * 2) {
58 | int fade = clamp((progress - FADE_LENGTH) / fade_step, 0, 16);
59 | REG_BLDY = BLDY_BUILD(fade);
60 | }
61 | if (progress > FADE_LENGTH * 2) {
62 | // done
63 | dusk_scene_set(fountain_scene);
64 | }
65 |
66 | // update sprites
67 | dusk_sprites_update();
68 | }
69 |
70 | void logo_end() {
71 | // clear blending registers
72 | REG_BLDCNT = BLD_OFF;
73 | }
74 |
75 | Scene logo_scene = {
76 | .start = logo_start,
77 | .update = logo_update,
78 | .end = logo_end,
79 | };
--------------------------------------------------------------------------------
/demo/Fountain2/src/main.c:
--------------------------------------------------------------------------------
1 | #include "dusk.h"
2 | #include "ds_sys.h"
3 | #include "scenes.h"
4 |
5 | int main() {
6 | dusk_init_all();
7 |
8 | dusk_scene_set(logo_scene);
9 |
10 | while (TRUE) {
11 | key_poll(); // update inputF
12 | dusk_scene_update();
13 | }
14 | }
--------------------------------------------------------------------------------
/demo/Fountain2/src/scenes.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | extern Scene logo_scene;
4 | extern Scene fountain_scene;
--------------------------------------------------------------------------------
/doc/dlang.md:
--------------------------------------------------------------------------------
1 | # dlang notes
2 |
3 | how to put section directives:
4 | https://wiki.dlang.org/LDC-specific_language_changes#.40.28ldc.attributes.section.28.22section_name.22.29.29
--------------------------------------------------------------------------------
/doc/tips.md:
--------------------------------------------------------------------------------
1 |
2 | # gfx building
3 |
4 | in GIMP, set color mode to Indexed, and select 16 or 256 depending on your bpp
5 |
6 | # iwram/ewram
7 |
8 | by default, devkitarm puts stack, heap, and static
9 |
10 | to put a var in `EWRAM`:
11 | `__attribute__((section(".ewram")))`
12 |
13 | to put a function in `IWRAM` (instead of ROM):
14 | add `IWRAM_CODE`
15 |
16 | # arm/thumb
17 |
18 | todo
--------------------------------------------------------------------------------
/media/duskdemo.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/media/duskdemo.webp
--------------------------------------------------------------------------------
/media/fountain2.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/media/fountain2.webp
--------------------------------------------------------------------------------
/media/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bmchtech/dusk/7792e009cd2954064ca84e79ad19464f5b5393d6/media/icon.png
--------------------------------------------------------------------------------
/src/dusk/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # Makefile for libdusk.
3 | #
4 |
5 | LIBNAME := dusk
6 | VERSION := 0.1.7
7 |
8 | #---------------------------------------------------------------------------------
9 | .SUFFIXES:
10 | #---------------------------------------------------------------------------------
11 |
12 | ifeq ($(strip $(DEVKITARM)),)
13 | $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM)
14 | endif
15 | ifeq ($(strip $(DEVKITPRO)),)
16 | $(error "Please set DEVKITPRO in your environment. export DEVKITPRO=devkitPro)
17 | endif
18 | include $(DEVKITARM)/gba_rules
19 |
20 | BUILD := build
21 | SRCDIRS := src src/contrib
22 | INCDIRS := include include/contrib
23 |
24 | DEPFLAGS := -I$(DEVKITPRO)/libtonc/include -L$(DEVKITPRO)/libtonc/lib -ltonc
25 |
26 | DATESTRING := $(shell date +%Y)$(shell date +%m)$(shell date +%d)
27 | GITVERSION := $(shell git describe --long --tags | sed 's/^v//;s/\([^-]*-g\)/r\1/;s/-/./g')
28 |
29 | ARCH := -mthumb -mthumb-interwork
30 | RARCH := -mthumb-interwork -mthumb
31 | IARCH := -mthumb-interwork -marm
32 |
33 | bTEMPS := 0 # Save gcc temporaries (.i and .s files)
34 | # DEBUG := 0 # Generate debug info
35 |
36 | #---------------------------------------------------------------------------------
37 | # Options for code generation
38 | #---------------------------------------------------------------------------------
39 |
40 | CBASE := $(INCLUDE) -Wall -fno-strict-aliasing #-fno-tree-loop-optimize
41 | CBASE += -O2
42 | CBASE += $(DEPFLAGS)
43 | CBASE += -Werror=implicit-function-declaration
44 |
45 | ifeq ($(DEBUG),1)
46 | CBASE += -g -DDEBUG
47 | endif
48 |
49 | DEFINES = -DGBA -DDUSK_VERSION=\"$(GITVERSION)\"
50 | CBASE += $(DEFINES)
51 |
52 | RCFLAGS := $(CBASE) $(RARCH)
53 | ICFLAGS := $(CBASE) $(IARCH) -mlong-calls #-fno-gcse
54 | CFLAGS := $(RCFLAGS)
55 |
56 | ASFLAGS := $(INCLUDE) -Wa,--warn $(ARCH)
57 |
58 | # --- Save temporary files ? ---
59 | ifeq ($(strip $(bTEMPS)), 1)
60 | RCFLAGS += -save-temps
61 | ICFLAGS += -save-temps
62 | CFLAGS += -save-temps
63 | CXXFLAGS += -save-temps
64 | endif
65 |
66 | #---------------------------------------------------------------------------------
67 | # Path to tools - this can be deleted if you set the path in windows
68 | #---------------------------------------------------------------------------------
69 |
70 | export PATH := $(DEVKITARM)/bin:$(PATH)
71 |
72 | #---------------------------------------------------------------------------------
73 |
74 | ifneq ($(BUILD),$(notdir $(CURDIR)))
75 |
76 | export TARGET := $(CURDIR)/lib/lib$(LIBNAME).a
77 |
78 | export VPATH := $(foreach dir,$(DATADIRS),$(CURDIR)/$(dir)) $(foreach dir,$(SRCDIRS),$(CURDIR)/$(dir))
79 |
80 | ICFILES := $(foreach dir,$(SRCDIRS),$(notdir $(wildcard $(dir)/*.iwram.c)))
81 | RCFILES := $(foreach dir,$(SRCDIRS),$(notdir $(wildcard $(dir)/*.c)))
82 | CFILES := $(ICFILES) $(RCFILES)
83 |
84 | SFILES := $(foreach dir,$(SRCDIRS),$(notdir $(wildcard $(dir)/*.s)))
85 |
86 | export OFILES := $(CFILES:.c=.o) $(SFILES:.s=.o)
87 | export INCLUDE := $(foreach dir,$(INCDIRS),-I$(CURDIR)/$(dir))
88 | export DEPSDIR := $(CURDIR)/build
89 |
90 | .PHONY: $(BUILD) clean docs
91 |
92 | $(BUILD):
93 | @[ -d lib ] || mkdir -p lib
94 | @[ -d $@ ] || mkdir -p $@
95 | @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
96 |
97 | clean:
98 | @echo clean ...
99 | @rm -fr $(BUILD)
100 | @rm -fr $(TARGET)
101 |
102 | install:
103 | @mkdir -p $(DESTDIR)$(DEVKITPRO)/$(LIBNAME)/lib
104 | @cp -rv include $(DESTDIR)$(DEVKITPRO)/$(LIBNAME)/include
105 | @cp -v lib/lib$(LIBNAME).a $(DESTDIR)$(DEVKITPRO)/$(LIBNAME)/lib/
106 |
107 | #---------------------------------------------------------------------------------
108 |
109 | else
110 |
111 | DEPENDS := $(OFILES:.o=.d)
112 |
113 | #---------------------------------------------------------------------------------
114 |
115 | %.a :
116 |
117 | $(TARGET): $(OFILES)
118 |
119 | %.a : $(OFILES)
120 | @echo Building $@
121 | @rm -f $@
122 | @$(AR) -crs $@ $^
123 | $(PREFIX)nm -Sn $@ > $(basename $(notdir $@)).map
124 |
125 | %.iwram.o : %.iwram.c
126 | @echo $(notdir $<)
127 | $(CC) -MMD -MP -MF $(DEPSDIR)/$(@:.o=.d) $(ICFLAGS) -c $< -o $@
128 |
129 | %.o : %.c
130 | @echo $(notdir $<)
131 | $(CC) -MMD -MP -MF $(DEPSDIR)/$*.d $(RCFLAGS) -c $< -o $@
132 |
133 | -include $(DEPENDS)
134 |
135 | endif
136 |
137 | #---------------------------------------------------------------------------------
138 |
--------------------------------------------------------------------------------
/src/dusk/include/contrib/gbamap.h:
--------------------------------------------------------------------------------
1 | #ifndef MAP_H
2 | #define MAP_H
3 |
4 | #include "gbamap_object.h"
5 |
6 | typedef struct Map {
7 | unsigned short sizeFlag,
8 | paletteLength,
9 | tileSetLength,
10 | terrainMapLength,
11 | numObjects,
12 | numLayers,
13 | tileMapLength;
14 |
15 | const unsigned short *palette,
16 | *tileSet,
17 | *terrainMap;
18 |
19 | MapObject objects[256];
20 |
21 | const unsigned short *tileMapLayers[3];
22 | } Map;
23 |
24 | typedef struct BackgroundPoint {
25 | short x, y;
26 | } __attribute__((aligned(4))) BackgroundPoint;
27 |
28 | #define MAX_LAYERS 3
29 | #define ENTRIES_IN_SCREEN_BLOCK 512
30 | #define NUM_SCREEN_BLOCKS 31
31 |
32 | Map map_load_from_rom(const unsigned short *map_data);
33 |
34 | void map_init_registers();
35 | void map_set_onscreen(Map map);
36 | void map_shift(Map map, BackgroundPoint offset);
37 | void map_shift_layer(unsigned short layer, BackgroundPoint offset);
38 |
39 | #endif
40 |
--------------------------------------------------------------------------------
/src/dusk/include/contrib/gbamap_object.h:
--------------------------------------------------------------------------------
1 | #ifndef MAP_OBJECT_H
2 | #define MAP_OBJECT_H
3 |
4 | typedef struct {
5 | unsigned short x, y;
6 | } __attribute__((aligned(4))) ObjectPoint;
7 |
8 | typedef struct
9 | {
10 | unsigned int id;
11 | ObjectPoint position;
12 | const char* name;
13 | const char* type;
14 | } MapObject;
15 |
16 | MapObject map_load_object(const unsigned short* object_data, unsigned short* index);
17 | unsigned int map_load_object_id(const unsigned short* idData, unsigned short* index);
18 | ObjectPoint map_load_object_position(const unsigned short* positionData, unsigned short* index);
19 | const char* map_load_string(const unsigned short* stringData, unsigned short* index);
20 | unsigned short map_pop_value(const unsigned short* data, unsigned short* index);
21 |
22 | void map_shift_objects(MapObject* objects, ObjectPoint shift, unsigned int count);
23 |
24 | #endif
--------------------------------------------------------------------------------
/src/dusk/include/contrib/gbfs.h:
--------------------------------------------------------------------------------
1 | /* gbfs.h
2 | access object in a GBFS file
3 |
4 | Copyright 2002 Damian Yerrick
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining
7 | a copy of this software and associated documentation files (the
8 | "Software"), to deal in the Software without restriction, including
9 | without limitation the rights to use, copy, modify, merge, publish,
10 | distribute, sublicense, and/or sell copies of the Software, and to
11 | permit persons to whom the Software is furnished to do so, subject to
12 | the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be
15 | included in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21 | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 | AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
23 | OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 | IN THE SOFTWARE.
25 |
26 | */
27 |
28 | /* Dependency on prior include files
29 |
30 | Before you #include "gbfs.h", you should define the following types:
31 | typedef (unsigned 16-bit integer) u16;
32 | typedef (unsigned 32-bit integer) u32;
33 | Your gba.h should do this for you.
34 | */
35 |
36 | #ifndef INCLUDE_GBFS_H
37 | #define INCLUDE_GBFS_H
38 | #ifdef __cplusplus
39 | extern "C" {
40 | #endif
41 |
42 | /* to make a 300 KB space called samples do GBFS_SPACE(samples, 300) */
43 |
44 | #define GBFS_SPACE(filename, kbytes) \
45 | const char filename[(kbytes)*1024] __attribute__((aligned(16))) = "PinEightGBFSSpace-" #filename "-" #kbytes;
46 |
47 | #define GBFS_ENTRY_SIZE 24
48 |
49 | typedef struct GBFS_FILE {
50 | char magic[16]; /* "PinEightGBFS\r\n\032\n" */
51 | u32 total_len; /* total length of archive */
52 | u16 dir_off; /* offset in bytes to directory */
53 | u16 dir_nmemb; /* number of files */
54 | char reserved[8]; /* for future use */
55 | } GBFS_FILE;
56 |
57 | typedef struct GBFS_ENTRY {
58 | char name[GBFS_ENTRY_SIZE]; /* filename, nul-padded */
59 | u32 len; /* length of object in bytes */
60 | u32 data_offset; /* in bytes from beginning of file */
61 | } GBFS_ENTRY;
62 |
63 | const GBFS_FILE* find_first_gbfs_file(const void* start);
64 | const void* skip_gbfs_file(const GBFS_FILE* file);
65 | const void* gbfs_get_obj(const GBFS_FILE* file, const char* name, u32* len);
66 | const void* gbfs_get_nth_obj(const GBFS_FILE* file, size_t n, char* name, u32* len);
67 | void* gbfs_copy_obj(void* dst, const GBFS_FILE* file, const char* name);
68 | size_t gbfs_count_objs(const GBFS_FILE* file);
69 |
70 | #ifdef __cplusplus
71 | }
72 | #endif
73 | #endif
74 |
--------------------------------------------------------------------------------
/src/dusk/include/contrib/mgba.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | #define REG_DEBUG_ENABLE (vu16*)0x4FFF780
9 | #define REG_DEBUG_FLAGS (vu16*)0x4FFF700
10 | #define REG_DEBUG_STRING (char*)0x4FFF600
11 |
12 | typedef enum MGBA_LOG_LEVEL {
13 | MGBA_LOG_FATAL,
14 | MGBA_LOG_ERROR,
15 | MGBA_LOG_WARN,
16 | MGBA_LOG_INFO,
17 | MGBA_LOG_DEBUG
18 | } MGBA_LOG_LEVEL;
19 |
20 | void mgba_printf(int level, const char* ptr, ...);
21 | BOOL mgba_open(void);
22 | void mgba_close(void);
--------------------------------------------------------------------------------
/src/dusk/include/ds_load.h:
--------------------------------------------------------------------------------
1 | /*
2 | DUSK: LOADER
3 | */
4 |
5 | #pragma once
6 |
7 | #include "contrib/gbfs.h"
8 | #include "contrib/gbamap.h"
9 |
10 | extern const GBFS_FILE* gbfs_dat;
11 |
12 | // represents an atlas, with bitmaps for the image and palette
13 | typedef struct SpriteAtlas {
14 | u32* tiles;
15 | u32 tile_sz;
16 | u32* pal;
17 | u32 pal_sz;
18 | } SpriteAtlas;
19 |
20 | typedef struct GritImage {
21 | u32* tiles;
22 | u32 tile_sz;
23 | u32* pal;
24 | u32 pal_sz;
25 | u32* map;
26 | u32 map_sz;
27 | } GritImage;
28 |
29 | #define ATLAS_ENTRY_LEN 6
30 |
31 | /** represents a single entry in the sprite atlas.
32 | * note that names are limited to just 5 chars and a NULL terminator. */
33 | typedef struct SpriteAtlasEntry {
34 | char name[ATLAS_ENTRY_LEN];
35 | // all of these are in tiles (8px)
36 | u8 x;
37 | u8 y;
38 | u8 w;
39 | u8 h;
40 | } SpriteAtlasEntry;
41 |
42 | /** represents the layout of items in an atlas (https://github.com/xdrie/crunch#binary-format).
43 | * we only use the first texture because the vram can only hold one */
44 | typedef struct SpriteAtlasLayout {
45 | u16 width;
46 | u16 height;
47 | u16 num_entries;
48 | SpriteAtlasEntry* entries;
49 | } SpriteAtlasLayout;
50 |
51 | /** initialize loader */
52 | void dusk_load_init();
53 |
54 | // - CONTENT LOADERS: pass filename without extension
55 |
56 | const void* dusk_load_raw(char* name, u32* len);
57 | GritImage dusk_load_image(char* name);
58 | SpriteAtlas dusk_load_atlas(char* name);
59 | SpriteAtlasLayout dusk_load_atlas_layout(const char* name);
60 | SpriteAtlasEntry* dusk_load_atlas_entry(SpriteAtlasLayout* layout, const char* entry_name);
61 | void dusk_free_atlas_layout(SpriteAtlasLayout* layout);
62 |
63 | Map dusk_load_map(char* name);
--------------------------------------------------------------------------------
/src/dusk/include/ds_sav.h:
--------------------------------------------------------------------------------
1 | /*
2 | DUSK: SAVE UTIL
3 | */
4 |
5 | #pragma once
6 |
7 | // utilities for saving and loading vars
8 |
9 | #define SV_LOAD_ITEM(var, offset) \
10 | memcpy(&var, sram_mem + offset, sizeof(typeof(var))); \
11 | offset += sizeof(typeof(var));
12 |
13 | #define SV_SAVE_ITEM(var, offset) \
14 | memcpy(sram_mem + offset, &var, sizeof(typeof(var))); \
15 | offset += sizeof(typeof(var));
16 |
17 | // utilities for saving and loading vars
--------------------------------------------------------------------------------
/src/dusk/include/ds_spr.h:
--------------------------------------------------------------------------------
1 | /*
2 | DUSK: SPRITES
3 | */
4 |
5 | #pragma once
6 |
7 | #include
8 | #include
9 | #include "ds_load.h"
10 |
11 | #define NUM_SPRITES 128
12 | #define NUM_AFFINE_SPRITES 32
13 | extern OBJ_ATTR obj_buffer[NUM_SPRITES];
14 | extern OBJ_AFFINE* obj_aff_buffer;
15 |
16 | #define SPRITEFLAG_PRIORITY_SHIFT 6
17 | #define SPRITEFLAG_PRIORITY_GET(n) ((n >> SPRITEFLAG_PRIORITY_SHIFT) & 0b11)
18 | #define SPRITEFLAG_PRIORITY(n) ((n << SPRITEFLAG_PRIORITY_SHIFT) & 0b11)
19 |
20 | #define DUSKSPRITE_FLAGS_VISIBLE (0x1 << 0)
21 | /** sprite data */
22 | typedef struct Sprite {
23 | s16 x, y;
24 | /** the number of tiles taken up by this sprite */
25 | u8 tile_sz;
26 | /** the raw tid of the top left corner tile of spritesheet frame 0 */
27 | u16 base_tid;
28 | /** the frame index of the spritesheet */
29 | u8 page;
30 | /** flags: 0/0/0/0/0/0/0/visible */
31 | u8 flags;
32 | } Sprite;
33 |
34 | /** animation metadata */
35 | typedef struct Anim {
36 | /** which page in the sprite the animation starts */
37 | u8 start;
38 | /** number of pages in this animation */
39 | u8 len;
40 | /** (60/fps), or how many frames each page lasts */
41 | u8 rate;
42 | } Anim;
43 |
44 | /** background data */
45 | typedef struct Background {
46 | s16 x, y;
47 | int cbb, sbb;
48 | } Background;
49 |
50 | /** define an animation, given a starting frame and frame count, and fps */
51 | #define MAKE_ANIM_EX(st, le, fps) \
52 | (Anim) { .start = st, .len = le, .rate = (60 / fps) }
53 | /** define an animation, given a starting frame and frame count, at 10 fps */
54 | #define MAKE_ANIM(st, le) MAKE_ANIM_EX(st, le, 10)
55 |
56 | /** memory block used to track sprites */
57 | extern Sprite sprites[NUM_SPRITES];
58 |
59 | /** initialize sprite and OAM memory */
60 | void dusk_sprites_init();
61 | /** set mode options for dusk sprites */
62 | void dusk_sprites_configure(BOOL bpp8);
63 | /** upload a sprite atlas to tile and palette memory */
64 | void dusk_sprites_upload_atlas(SpriteAtlas* atlas);
65 | /** upload a sprite atlas section to tile and palette memory */
66 | void dusk_sprites_upload_atlas_section(SpriteAtlasLayout* layout, SpriteAtlas* atlas, SpriteAtlasEntry* entry, u16 pal_offset, u16 tile_offset);
67 | /** create a sprite and store it in index of sprite memory */
68 | Sprite* dusk_sprites_make(int index, u8 width, u8 height, Sprite spr);
69 | /** synchronize a sprite from the sprites array to OAM block (vram) */
70 | void dusk_sprites_sync(int index);
71 | /** synchronize all sprites to OAM block, then upload OAM block to vram */
72 | void dusk_sprites_update();
73 | /** play an animation on a sprite */
74 | void dusk_sprites_anim_play(Sprite* spr, Anim* anim);
75 | /** calculate the tid of a sprite given pos and sheet dimens */
76 | u16 dusk_sprites_pos_to_tid(u16 x, u16 y, u16 sheet_width, u16 sheet_height);
77 | /** upload image data to background tile vram */
78 | void dusk_background_upload_raw(GritImage* img, int cbb, int sbb);
79 | /** create a background and display it */
80 | void dusk_background_make(u8 bg_id, u16 size, Background bg);
--------------------------------------------------------------------------------
/src/dusk/include/ds_sys.h:
--------------------------------------------------------------------------------
1 | /*
2 | DUSK: SYSTEM
3 | */
4 |
5 | #pragma once
6 |
7 | extern uint frame_count;
8 |
9 | typedef struct Scene {
10 | void (*start)(void);
11 | void (*end)(void);
12 | void (*update)(void);
13 | } Scene;
14 |
15 | /** initialize the system for using DUSK */
16 | void dusk_init_all();
17 | /** initialize mode0 graphics */
18 | void dusk_init_graphics_mode0();
19 | /** initialize mode3 graphics */
20 | void dusk_init_graphics_mode3();
21 | /** vsync */
22 | void dusk_frame();
23 | void dusk_scene_set(Scene next);
24 | void dusk_scene_update();
--------------------------------------------------------------------------------
/src/dusk/include/dusk.h:
--------------------------------------------------------------------------------
1 | /*
2 | DUSK: MASTER HEADER
3 | */
4 |
5 | #pragma once
6 |
7 | #include
8 | #include "ds_load.h"
9 | #include "ds_sys.h"
10 | #include "ds_spr.h"
11 | #include "ds_sav.h"
--------------------------------------------------------------------------------
/src/dusk/src/contrib/background.h:
--------------------------------------------------------------------------------
1 | #ifndef BACKGROUND_H
2 | #define BACKGROUND_H
3 |
4 | #include "./video.h"
5 |
6 | /**
7 | * Defines the background control.
8 | */
9 |
10 | typedef u16 ScreenEntry;
11 |
12 | typedef struct {
13 | u32 data[8];
14 | } Tile;
15 |
16 | typedef ScreenEntry ScreenBlock[1024];
17 | typedef Tile CharBlock[512];
18 |
19 | #define MEMORY_BACKGROUND_PALETTE ((Color*)MEMORY_PALETTE)
20 | #define MEMORY_BACKGROUND_PALETTE_SIZE 0x00200
21 |
22 | #define MEMORY_SCREEN_BLOCK ((ScreenBlock*)MEMORY_VIDEORAM)
23 | #define MEMORY_CHAR_BLOCK ((CharBlock*)MEMORY_VIDEORAM)
24 |
25 | #define REGISTER_BACKGROUND_CONTROL ((vu16*)(REGISTER_BASE+0x0008))
26 | #define REGISTER_BACKGROUND_OFFSET ((BackgroundPoint*)(REGISTER_BASE+0x0010))
27 |
28 | #define FLAG_BACKGROUND_4BPP 0
29 | #define FLAG_BACKGROUND_8BPP 0x0080
30 | #define FLAG_BACKGROUND_REGULAR_32x32 0
31 | #define FLAG_BACKGROUND_REGULAR_64x32 0x4000
32 | #define FLAG_BACKGROUND_REGULAR_32x64 0x8000
33 | #define FLAG_BACKGROUND_REGULAR_64x64 0xC000
34 |
35 | #define MASK_FLAG_BACKGROUND_CHAR_BLOCK 0x000C
36 | #define SHIFT_FLAG_BACKGROUND_CHAR_BLOCK 2
37 | #define FLAG_BACKGROUND_CHAR_BLOCK(n) ((n)<>name##_SHIFT )
6 | #define BIT_FIELD_SET(y, x, name) (y = ((y)&~name##_MASK) | BIT_FIELD_PREP(x,name) )
7 |
8 | #endif
--------------------------------------------------------------------------------
/src/dusk/src/contrib/initMapRegisters.c:
--------------------------------------------------------------------------------
1 | #include "gbamap.h"
2 | #include "./background.h"
3 |
4 | void map_init_registers() {
5 | // turn off all backgrounds
6 | for (u32 layerIndex = MAX_LAYERS; layerIndex-- > 0;) {
7 | REGISTER_BACKGROUND_CONTROL[layerIndex] = 0;
8 | }
9 |
10 | // reset display control
11 | REGISTER_DISPLAY_CONTROL = 0;
12 | }
--------------------------------------------------------------------------------
/src/dusk/src/contrib/libgbfs.c:
--------------------------------------------------------------------------------
1 | /* libgbfs.c
2 | access object in a GBFS file
3 |
4 | Copyright 2002-2004 Damian Yerrick
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining
7 | a copy of this software and associated documentation files (the
8 | "Software"), to deal in the Software without restriction, including
9 | without limitation the rights to use, copy, modify, merge, publish,
10 | distribute, sublicense, and/or sell copies of the Software, and to
11 | permit persons to whom the Software is furnished to do so, subject to
12 | the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be
15 | included in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21 | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 | AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
23 | OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 | IN THE SOFTWARE.
25 |
26 | */
27 |
28 | /* This code assumes a LITTLE ENDIAN target. It'll need a boatload
29 | of itohs and itohl calls if converted to run on Sega Genesis. It
30 | also assumes that the target uses 16-bit short and 32-bit longs.
31 | */
32 |
33 | typedef unsigned short u16;
34 | typedef unsigned long u32;
35 |
36 | #include
37 | #include
38 | #include "gbfs.h"
39 |
40 | /* change this to the end of your ROM, or to 0x02040000 for multiboot */
41 | #define GBFS_1ST_SEARCH_LIMIT ((const u32*)0x02040000)
42 | #define GBFS_2ND_SEARCH_START ((const u32*)0x08000000)
43 | #define GBFS_2ND_SEARCH_LIMIT ((const u32*)0x0a000000)
44 |
45 | /* a power of two, less than or equal to the argument passed to
46 | padbin. Increasing the stride makes find_first_gbfs_file()
47 | faster at the cost of a slightly larger binary. */
48 | #define GBFS_ALIGNMENT 256
49 |
50 | const GBFS_FILE* find_first_gbfs_file(const void* start) {
51 | /* align the pointer */
52 | const u32* here = (const u32*)((unsigned long)start & (-GBFS_ALIGNMENT));
53 | const char rest_of_magic[] = "ightGBFS\r\n\x1a\n";
54 |
55 | /* Linear-search first in multiboot space. */
56 | while (here < GBFS_1ST_SEARCH_LIMIT) {
57 | /* We have to keep the magic code in two pieces; otherwise,
58 | this function may find itself and think it's a GBFS file.
59 | This obviously won't work if your compiler stores this
60 | numeric literal just before the literal string, but Devkit
61 | Advance R4 and R5 seem to keep numeric constant pools
62 | separate enough from string pools for this to work.
63 | */
64 | if (*here == 0x456e6950) /* ASCII code for little endian "PinE" */
65 | {
66 | /* We've matched the first four bytes.
67 | If the rest of the magic matches, then we've found a file. */
68 | if (!memcmp(here + 1, rest_of_magic, 12))
69 | return (const GBFS_FILE*)here;
70 | }
71 | here += GBFS_ALIGNMENT / sizeof(*here);
72 | }
73 |
74 | /* Now search in ROM space. */
75 | if (here < GBFS_2ND_SEARCH_START)
76 | here = GBFS_2ND_SEARCH_START;
77 | while (here < GBFS_2ND_SEARCH_LIMIT) {
78 | /* Search loop same as above. */
79 | if (*here == 0x456e6950) /* ASCII code for little endian "PinE" */
80 | {
81 | if (!memcmp(here + 1, rest_of_magic, 12))
82 | return (const GBFS_FILE*)here;
83 | }
84 | here += GBFS_ALIGNMENT / sizeof(*here);
85 | }
86 | return 0;
87 | }
88 |
89 | const void* skip_gbfs_file(const GBFS_FILE* file) { return ((char*)file + file->total_len); }
90 |
91 | static int namecmp(const void* a, const void* b) { return memcmp(a, b, 24); }
92 |
93 | const void* gbfs_get_obj(const GBFS_FILE* file, const char* name, u32* len) {
94 | char key[24] = {0};
95 |
96 | const GBFS_ENTRY* dirbase = (const GBFS_ENTRY*)((const char*)file + file->dir_off);
97 | size_t n_entries = file->dir_nmemb;
98 | const GBFS_ENTRY* here;
99 |
100 | #pragma GCC diagnostic push
101 | #pragma GCC diagnostic ignored "-Wstringop-truncation"
102 | strncpy(key, name, 24);
103 | #pragma GCC diagnostic pop
104 |
105 | here = bsearch(key, dirbase, n_entries, sizeof(GBFS_ENTRY), namecmp);
106 | if (!here) {
107 | *len = 0;
108 | return NULL;
109 | }
110 |
111 | if (len)
112 | *len = here->len;
113 | return (char*)file + here->data_offset;
114 | }
115 |
116 | const void* gbfs_get_nth_obj(const GBFS_FILE* file, size_t n, char* name, u32* len) {
117 | const GBFS_ENTRY* dirbase = (const GBFS_ENTRY*)((const char*)file + file->dir_off);
118 | size_t n_entries = file->dir_nmemb;
119 | const GBFS_ENTRY* here = dirbase + n;
120 |
121 | if (n >= n_entries)
122 | return NULL;
123 |
124 | if (name) {
125 | #pragma GCC diagnostic push
126 | #pragma GCC diagnostic ignored "-Wstringop-truncation"
127 | strncpy(name, here->name, 24);
128 | #pragma GCC diagnostic pop
129 | name[24] = 0;
130 | }
131 |
132 | if (len)
133 | *len = here->len;
134 |
135 | return (char*)file + here->data_offset;
136 | }
137 |
138 | void* gbfs_copy_obj(void* dst, const GBFS_FILE* file, const char* name) {
139 | u32 len;
140 | const void* src = gbfs_get_obj(file, name, &len);
141 |
142 | if (!src)
143 | return NULL;
144 |
145 | memcpy(dst, src, len);
146 | return dst;
147 | }
148 |
149 | size_t gbfs_count_objs(const GBFS_FILE* file) { return file ? file->dir_nmemb : 0; }
150 |
--------------------------------------------------------------------------------
/src/dusk/src/contrib/loadMapFromROM.c:
--------------------------------------------------------------------------------
1 | #include "gbamap.h"
2 | #include
3 | #include "./types.h"
4 |
5 | Map map_load_from_rom(const u16 *map_data) {
6 | Map map;
7 | u16 index = 0;
8 |
9 | map.sizeFlag = map_data[index++];
10 |
11 | map.paletteLength = map_data[index++];
12 | map.palette = &map_data[index];
13 | index += map.paletteLength + 1;
14 |
15 | map.tileSetLength = map_data[index++];
16 | map.tileSet = &map_data[index];
17 | index += map.tileSetLength + 1;
18 |
19 | map.terrainMapLength = map_data[index++];
20 | map.terrainMap = &map_data[index];
21 | index += map.terrainMapLength;
22 |
23 | map.numLayers = map_data[index++];
24 | map.numLayers = map.numLayers > MAX_LAYERS ? MAX_LAYERS : map.numLayers;
25 | map.tileMapLength = map_data[index++];
26 | for (u32 layerIndex = 0; layerIndex < map.numLayers; ++layerIndex)
27 | {
28 | map.tileMapLayers[layerIndex] = &map_data[index];
29 | index += map.tileMapLength;
30 | }
31 |
32 | u16 lengthObjectData = map_data[index++];
33 | u32 endObjectData = index + lengthObjectData;
34 | u32 objectCount = 0;
35 | while (index != endObjectData) {
36 | MapObject object = map_load_object(map_data, &index);
37 | map.objects[objectCount] = object;
38 | objectCount++;
39 | }
40 | map.numObjects = objectCount;
41 |
42 | return map;
43 | }
44 |
--------------------------------------------------------------------------------
/src/dusk/src/contrib/loadObject.c:
--------------------------------------------------------------------------------
1 | #include "gbamap_object.h"
2 | #include "./types.h"
3 |
4 | MapObject map_load_object(const u16* object_data, u16* index) {
5 | MapObject object;
6 | object.id = map_load_object_id(object_data, index);
7 | object.position = map_load_object_position(object_data, index);
8 | object.name = map_load_string(object_data, index);
9 | object.type = map_load_string(object_data, index);
10 | return object;
11 | }
--------------------------------------------------------------------------------
/src/dusk/src/contrib/loadObjectID.c:
--------------------------------------------------------------------------------
1 | #include "gbamap_object.h"
2 | #include "./types.h"
3 |
4 | u32 map_load_object_id(const u16* idData, u16* index) {
5 | u32 upperID = map_pop_value(idData, index);
6 | u32 lowerID = map_pop_value(idData, index);
7 | return (upperID << 16) | lowerID;
8 | }
--------------------------------------------------------------------------------
/src/dusk/src/contrib/loadPosition.c:
--------------------------------------------------------------------------------
1 | #include "gbamap_object.h"
2 | #include "./types.h"
3 |
4 | ObjectPoint map_load_object_position(const u16* positionData, u16* index) {
5 | ObjectPoint position;
6 | position.x = map_pop_value(positionData, index);
7 | position.y = map_pop_value(positionData, index);
8 | return position;
9 | }
--------------------------------------------------------------------------------
/src/dusk/src/contrib/loadString.c:
--------------------------------------------------------------------------------
1 | #include "gbamap_object.h"
2 | #include "./types.h"
3 |
4 | const char* map_load_string(const u16* stringData, u16* index) {
5 | u16 length = map_pop_value(stringData, index);
6 | const char* string = (const char*) &stringData[*index];
7 | *index += length;
8 | return string;
9 | }
--------------------------------------------------------------------------------
/src/dusk/src/contrib/memoryMap.h:
--------------------------------------------------------------------------------
1 | #ifndef MEMORY_MAP_H
2 | #define MEMORY_MAP_H
3 |
4 | #include "types.h"
5 |
6 | /**
7 | * Defines the general memory locations.
8 | */
9 |
10 | #define MEMORY_IO 0x04000000
11 | #define MEMORY_PALETTE 0x05000000
12 | #define MEMORY_VIDEORAM 0x06000000
13 | #define MEMORY_OBJECT_ATTRIBUTES 0x07000000
14 |
15 | #define REGISTER_BASE MEMORY_IO
16 |
17 | #endif // MEMORY_MAP_H
18 |
--------------------------------------------------------------------------------
/src/dusk/src/contrib/mgba.c:
--------------------------------------------------------------------------------
1 | #include "contrib/mgba.h"
2 |
3 | #ifdef DEBUG
4 | void mgba_printf(int level, const char* ptr, ...) {
5 | va_list args;
6 | level &= 0x7;
7 | va_start(args, ptr);
8 | vsprintf(REG_DEBUG_STRING, ptr, args);
9 | va_end(args);
10 | *REG_DEBUG_FLAGS = level | 0x100;
11 | }
12 |
13 | BOOL mgba_open(void) {
14 | *REG_DEBUG_ENABLE = 0xC0DE;
15 | return *REG_DEBUG_ENABLE == 0x1DEA;
16 | }
17 |
18 | void mgba_close(void) { *REG_DEBUG_ENABLE = 0; }
19 | #else
20 | void mgba_printf(int level, const char* ptr, ...) {}
21 | BOOL mgba_open(void) { return FALSE; }
22 | void mgba_close(void) {}
23 | #endif
--------------------------------------------------------------------------------
/src/dusk/src/contrib/popValue.c:
--------------------------------------------------------------------------------
1 | #include "gbamap_object.h"
2 | #include "./types.h"
3 |
4 | u16 map_pop_value(const u16* data, u16* index) {
5 | u16 value = data[*index];
6 | *index += 1;
7 | return value;
8 | }
--------------------------------------------------------------------------------
/src/dusk/src/contrib/setMapOnScreen.c:
--------------------------------------------------------------------------------
1 | #include "./background.h"
2 | #include "gbamap.h"
3 | #include
4 |
5 | void map_set_onscreen(Map map) {
6 | memcpy(MEMORY_BACKGROUND_PALETTE, map.palette, map.paletteLength * 2);
7 | memcpy(&MEMORY_CHAR_BLOCK[0][0], map.tileSet, map.tileSetLength * 2);
8 |
9 | u32 screenBlockStep = map.tileMapLength / ENTRIES_IN_SCREEN_BLOCK;
10 | u32 usedBackgrounds = 0x00;
11 | for (u32 layerIndex = map.numLayers; layerIndex-- > 0;)
12 | {
13 | u32 screenBlockIndex = NUM_SCREEN_BLOCKS - screenBlockStep * (layerIndex + 1);
14 | memcpy(&MEMORY_SCREEN_BLOCK[screenBlockIndex][0], map.tileMapLayers[layerIndex], map.tileMapLength * 2);
15 |
16 | REGISTER_BACKGROUND_CONTROL[layerIndex] |= FLAG_BACKGROUND_CHAR_BLOCK(0) |
17 | FLAG_BACKGROUND_SCREEN_BLOCK(screenBlockIndex) |
18 | FLAG_BACKGROUND_8BPP |
19 | map.sizeFlag |
20 | FLAG_BACKGROUND_PRIORITY(map.numLayers - layerIndex);
21 | usedBackgrounds |= FLAG_BACKGROUND(layerIndex);
22 | }
23 |
24 | REGISTER_DISPLAY_CONTROL |= FLAG_MODE0 | usedBackgrounds;
25 | }
26 |
--------------------------------------------------------------------------------
/src/dusk/src/contrib/shiftMap.c:
--------------------------------------------------------------------------------
1 | #include "gbamap.h"
2 | #include "./background.h"
3 |
4 | void map_shift(Map map, BackgroundPoint offset)
5 | {
6 | for (u16 layer = 0; layer < map.numLayers; layer++)
7 | map_shift_layer(layer, offset);
8 | }
9 |
--------------------------------------------------------------------------------
/src/dusk/src/contrib/shiftMapLayer.c:
--------------------------------------------------------------------------------
1 | #include "./background.h"
2 | #include "gbamap.h"
3 |
4 | void map_shift_layer(u16 layer, BackgroundPoint offset)
5 | {
6 | REGISTER_BACKGROUND_OFFSET[layer] = offset;
7 | }
8 |
--------------------------------------------------------------------------------
/src/dusk/src/contrib/shiftMapObjects.c:
--------------------------------------------------------------------------------
1 | #include "gbamap_object.h"
2 | #include "./types.h"
3 |
4 | void map_shift_objects(MapObject* objects, ObjectPoint shift, u32 count)
5 | {
6 | for (u32 index = 0; index < count; index++)
7 | {
8 | objects[index].position.x -= shift.x;
9 | objects[index].position.y -= shift.y;
10 | }
11 | }
--------------------------------------------------------------------------------
/src/dusk/src/contrib/types.h:
--------------------------------------------------------------------------------
1 | #ifndef TYPES_H
2 | #define TYPES_H
3 |
4 | /**
5 | * Defines general data types and useful macros.
6 | */
7 |
8 | typedef unsigned char u8, byte;
9 | typedef unsigned short u16, hword;
10 | typedef unsigned int u32, word;
11 | typedef unsigned long long u64;
12 |
13 | typedef signed char s8;
14 | typedef signed short s16;
15 | typedef signed int s32;
16 | typedef signed long long s64;
17 |
18 | typedef volatile u8 vu8;
19 | typedef volatile u16 vu16;
20 | typedef volatile u32 vu32;
21 | typedef volatile u64 vu64;
22 |
23 | typedef volatile s8 vs8;
24 | typedef volatile s16 vs16;
25 | typedef volatile s32 vs32;
26 | typedef volatile s64 vs64;
27 |
28 | #define INLINE static inline
29 | #define ALIGN(n) __attribute__((aligned(n)))
30 |
31 | #define TRUE 1
32 | #define FALSE 0
33 |
34 | #endif // TYPES_H
35 |
--------------------------------------------------------------------------------
/src/dusk/src/contrib/video.h:
--------------------------------------------------------------------------------
1 | #ifndef VIDEO_H
2 | #define VIDEO_H
3 |
4 | #include "./memoryMap.h"
5 |
6 | /**
7 | * Defines general video control.
8 | */
9 |
10 | typedef u16 Color;
11 |
12 | #define SCREEN_WIDTH 240
13 | #define SCREEN_HEIGHT 160
14 |
15 | #define REGISTER_DISPLAY_CONTROL *(vu32*)(REGISTER_BASE+0x0000)
16 | #define REGISTER_VERTICAL_COUNT *(vu16*)(REGISTER_BASE+0x0006)
17 |
18 | #define FLAG_MODE0 0
19 |
20 | /**
21 | * Wait till the background has been rendered and it is safe to modify it.
22 | **/
23 | INLINE void videoSync()
24 | {
25 | while(REGISTER_VERTICAL_COUNT >= 160);
26 | while(REGISTER_VERTICAL_COUNT < 160);
27 | }
28 |
29 | #endif // VIDEO_H
30 |
--------------------------------------------------------------------------------
/src/dusk/src/load.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include "ds_load.h"
6 | #include
7 | #include
8 |
9 | const GBFS_FILE* gbfs_dat;
10 |
11 | void dusk_load_init() {
12 | // locate the main GBFS archive
13 | gbfs_dat = find_first_gbfs_file(find_first_gbfs_file);
14 | }
15 |
16 | const void* dusk_load_raw(char* name, u32* len) {
17 | return gbfs_get_obj(gbfs_dat, name, len);
18 | }
19 |
20 | GritImage dusk_load_image(char* name) {
21 | GritImage img;
22 | char tiles_name[GBFS_ENTRY_SIZE];
23 | strcpy(tiles_name, name);
24 | strcat(tiles_name, ".img.bin");
25 | char pal_name[GBFS_ENTRY_SIZE];
26 | strcpy(pal_name, name);
27 | strcat(pal_name, ".pal.bin");
28 | char map_name[GBFS_ENTRY_SIZE];
29 | strcpy(map_name, name);
30 | strcat(map_name, ".map.bin");
31 |
32 | img.tiles = (u32*)gbfs_get_obj(gbfs_dat, tiles_name, &img.tile_sz);
33 | img.pal = (u32*)gbfs_get_obj(gbfs_dat, pal_name, &img.pal_sz);
34 | img.map = (u32*)gbfs_get_obj(gbfs_dat, map_name, &img.map_sz);
35 |
36 | return img;
37 | }
38 |
39 | SpriteAtlas dusk_load_atlas(char* name) {
40 | char atlas_name[GBFS_ENTRY_SIZE];
41 | strcpy(atlas_name, name);
42 | strcat(atlas_name, "_0");
43 |
44 | GritImage img = dusk_load_image(atlas_name);
45 |
46 | SpriteAtlas atlas;
47 | atlas.tiles = img.tiles;
48 | atlas.tile_sz = img.tile_sz;
49 | atlas.pal = img.pal;
50 | atlas.pal_sz = img.pal_sz;
51 |
52 | // 1. pal_sz is some weird gradient thing
53 | // we're going to detect when more than 4 in the row are the same
54 | // so then find the actual end of the palette
55 |
56 | // NOTE: ASSERT pal_sz >= 2
57 |
58 | u16* pal_raw = (u16*)atlas.pal; // 16-bit color
59 | const int palscan_start = 0;
60 | const int palscan_inarow = 6; // how many in a row we're looking for
61 |
62 | u16 prev_color = pal_raw[palscan_start];
63 | int true_pal_sz = 2; // true size of palette (starts at 1 color, so 2 bytes)
64 | int col_match_streak = 0; // number of last few colors that matched
65 | int last_color_index = atlas.pal_sz / 2; // last color (div by 2 cause pal_sz is in bytes, and 16-bit color)
66 |
67 | for (int i = palscan_start + 1; i < last_color_index; i++) { // start at 1 cause 0's in prev_color
68 | u16 pal_col = pal_raw[i]; // color at index
69 | // printf("p: %0x\n", (int)pal_col);
70 |
71 | // check for match
72 | if (pal_col == prev_color) {
73 | col_match_streak++;
74 | } else {
75 | col_match_streak = 0;
76 | }
77 |
78 | if (col_match_streak >= palscan_inarow) { // 4 past colors are same
79 | true_pal_sz = true_pal_sz - (palscan_inarow) * 2; // we'll disregard all the last 4
80 | break; // done
81 | }
82 |
83 | prev_color = pal_col;
84 | true_pal_sz += 2;
85 | }
86 | atlas.pal_sz = true_pal_sz; // set adjusted pal size
87 | // printf("adjpal: %d\n", true_pal_sz);
88 |
89 | return atlas;
90 | }
91 |
92 | void seek_until_null(const u8* data, int* pos) {
93 | char last = data[*pos];
94 | while (last != 0) {
95 | *pos = *pos + 1; // advance pointer
96 | last = data[*pos];
97 | }
98 | }
99 |
100 | SpriteAtlasLayout dusk_load_atlas_layout(const char* name) {
101 | SpriteAtlasLayout layout;
102 | char file_name[GBFS_ENTRY_SIZE];
103 | strcpy(file_name, name);
104 | strcat(file_name, "_.sht.bin");
105 |
106 | u32 data_sz = 0;
107 | const u8* data = gbfs_get_obj(gbfs_dat, file_name, &data_sz);
108 |
109 | int pos = 0;
110 |
111 | // get the number of textures
112 | int num_tex = data[pos] | (data[pos + 1] << 8);
113 | assert(num_tex == 1); // there should only be a single texture
114 | pos += 2;
115 | // eat the texture name
116 | seek_until_null(data, &pos);
117 | pos++;
118 |
119 | layout.width = data[pos] | (data[pos + 1] << 8);
120 | pos += 2;
121 | layout.height = data[pos] | (data[pos + 1] << 8);
122 | pos += 2;
123 |
124 | layout.num_entries = data[pos] | (data[pos + 1] << 8);
125 | layout.entries = malloc(sizeof(SpriteAtlasEntry) * layout.num_entries);
126 | pos += 2;
127 |
128 | // now read blocks
129 | for (int i = 0; i < layout.num_entries; i++) {
130 | // save the entry name
131 | char last = data[pos];
132 | int name_len = 0;
133 | while (last != 0) {
134 | layout.entries[i].name[name_len] = last;
135 | name_len++;
136 | last = data[pos + name_len];
137 | }
138 | layout.entries[i].name[name_len] = '\0'; // null terminator
139 | pos += name_len + 1; // skip the name
140 |
141 | u16 x = data[pos] | (data[pos + 1] << 8);
142 | pos += 2;
143 | u16 y = data[pos] | (data[pos + 1] << 8);
144 | pos += 2;
145 | u16 w = data[pos] | (data[pos + 1] << 8);
146 | pos += 2;
147 | u16 h = data[pos] | (data[pos + 1] << 8);
148 | pos += 2;
149 | // x,y,w,h are 8-bit so don't overflow!
150 | // these are in tile units (the final div by 8)
151 | layout.entries[i].x = x / 8;
152 | layout.entries[i].y = y / 8;
153 | layout.entries[i].w = w / 8;
154 | layout.entries[i].h = h / 8;
155 | }
156 |
157 | return layout;
158 | }
159 |
160 | SpriteAtlasEntry* dusk_load_atlas_entry(SpriteAtlasLayout* layout, const char* entry_name) {
161 | for (int i = 0; i < layout->num_entries; i++) {
162 | SpriteAtlasEntry* entry = &layout->entries[i];
163 | if (strncmp(entry_name, entry->name, ATLAS_ENTRY_LEN) == 0) {
164 | return entry;
165 | }
166 | }
167 | return NULL;
168 | }
169 |
170 | void dusk_free_atlas_layout(SpriteAtlasLayout* layout) {
171 | layout->num_entries = 0;
172 | free(layout->entries);
173 | layout->entries = NULL;
174 | }
175 |
176 | Map dusk_load_map(char* name) {
177 | char ass_name[GBFS_ENTRY_SIZE];
178 | strcpy(ass_name, name);
179 | strcat(ass_name, ".bin");
180 |
181 | u32 map_data_sz = 0;
182 | const u16* map_data = gbfs_get_obj(gbfs_dat, ass_name, &map_data_sz);
183 | return map_load_from_rom(map_data);
184 | }
185 |
--------------------------------------------------------------------------------
/src/dusk/src/sprites.c:
--------------------------------------------------------------------------------
1 | #include "ds_spr.h"
2 | #include "ds_sys.h"
3 | #include
4 | #include "stdio.h"
5 |
6 | EWRAM_DATA OBJ_ATTR obj_buffer[NUM_SPRITES];
7 | OBJ_AFFINE* obj_aff_buffer = (OBJ_AFFINE*)obj_buffer;
8 |
9 | EWRAM_DATA Sprite sprites[NUM_SPRITES];
10 |
11 | /** when true, 8BPP, when false, 4BPP */
12 | BOOL sprites_bpp8 = TRUE;
13 |
14 | void dusk_sprites_init() {
15 | // initialize object buffer
16 | oam_init(obj_buffer, NUM_SPRITES);
17 | memset(sprites, 0, sizeof(Sprite) * NUM_SPRITES);
18 |
19 | // reset bpp to default
20 | sprites_bpp8 = TRUE;
21 |
22 | // enable sprite display
23 | REG_DISPCNT |= DCNT_OBJ | DCNT_OBJ_1D;
24 | }
25 |
26 | void dusk_sprites_configure(BOOL bpp8) { sprites_bpp8 = bpp8; }
27 |
28 | void dusk_sprites_upload_atlas(SpriteAtlas* atlas) {
29 | // 1. upload the atlas tile palette to palette memory
30 | // object/sprite palette, in 8bpp stores 256 colors
31 | memcpy(&pal_obj_bank[0], atlas->pal, atlas->pal_sz);
32 | // 2. upload the atlas tiles to tile memory
33 | // tile memory (can store 1024 tiles (32x32 tiles or 256x256px)
34 | // VRAM is charblocks 4 and 5, so &tile_mem[4][0] points to the first tile in object VRAM
35 | memcpy(&tile_mem[4][0], atlas->tiles, atlas->tile_sz);
36 | }
37 |
38 | void dusk_sprites_upload_atlas_section(SpriteAtlasLayout* layout, SpriteAtlas* atlas, SpriteAtlasEntry* entry,
39 | u16 pal_offset, u16 tile_offset) {
40 |
41 | // 1. upload the palette (palettes are 16-bit highcolor)
42 | memcpy(&pal_obj_bank[0][pal_offset], &atlas->pal[0], atlas->pal_sz);
43 |
44 | // pal_obj_bank[0][4] = CLR_YELLOW;
45 | // 2. upload the tiles
46 | int entry_firsttid =
47 | dusk_sprites_pos_to_tid(entry->x, entry->y, layout->width, layout->height); // tid of entry start in atlas
48 | int entry_tilecount = (entry->w) * (entry->h); // entry size in tiles
49 | int raw_firsttid = entry_firsttid * entry_tilecount * 2; // read offset
50 | // int raw_tilecount = entry_tilecount * 2;
51 | int raw_tileoffset = tile_offset * 2; // write offset
52 |
53 | // printf("ro: %d. wo: %d, n: %d\n", raw_firsttid, raw_tileoffset, raw_tilecount); // debug print tile r/w
54 |
55 | // memcpy(&tile_mem[4][raw_tileoffset], &atlas->tiles[raw_firsttid], entry_tilecount * 64);
56 |
57 | // 3. fix tiles to point at right palette
58 | // for (int i = 0; i < raw_tilecount; i += 2) {
59 | // TILE8 new_tile;
60 | // // TILE8 tile.data consists of 16 u32s (a total of 64 bytes)
61 | // // new_tile.data[j] = atlas->tiles[(entry_firsttid + i) * 2];
62 | // u32* rt = &atlas->tiles[raw_firsttid + i]; // read tile
63 |
64 | // for (int j = 0; j < 16; j++) {
65 | // new_tile.data[j] = rt[j];
66 | // // new_tile.data[j] = 0x04040404;
67 | // }
68 | // // copy in tile
69 | // memcpy(&tile_mem[4][raw_tileoffset + i], &new_tile, 64);
70 | // }
71 |
72 | // unroll malloc
73 | // memcpy(&tile_mem[4][raw_tileoffset], &atlas->tiles[raw_firsttid], 64);
74 |
75 | // reinterpret as byte pointers
76 | u8* loc_twrite = (u8*)&tile_mem[4][raw_tileoffset];
77 | u8* loc_tread = (u8*)&atlas->tiles[raw_firsttid];
78 | for (int i = 0; i < entry_tilecount; i += 1) {
79 | int c = i * 64;
80 | u8 tile[64]; // create temp tile
81 | memcpy(&tile[0], loc_tread + c, 64); // read tile
82 |
83 | // fix tile
84 | for (int j = 0; j < 64; j++) {
85 | tile[j] = tile[j] + pal_offset;
86 | }
87 |
88 | memcpy(loc_twrite + c, &tile[0], 64); // write tile
89 | }
90 | }
91 |
92 | Sprite* dusk_sprites_make(int index, u8 width, u8 height, Sprite spr) {
93 | // automatically figure out sprite size/shape attributes
94 | u16 shape_attr = 0;
95 | if (height > width) {
96 | shape_attr = ATTR0_TALL;
97 | } else if (width > height) {
98 | shape_attr = ATTR0_WIDE;
99 | } else if (width == height) {
100 | shape_attr = ATTR0_SQUARE;
101 | }
102 | u16 size_attr = 0;
103 | if (shape_attr == ATTR0_TALL) {
104 | if (width == 8 && height == 16)
105 | size_attr = ATTR1_SIZE_8x16;
106 | if (width == 8 && height == 32)
107 | size_attr = ATTR1_SIZE_8x32;
108 | if (width == 16 && height == 32)
109 | size_attr = ATTR1_SIZE_16x32;
110 | if (width == 16 && height == 64)
111 | size_attr = ATTR1_SIZE_32x64;
112 | }
113 | if (shape_attr == ATTR0_WIDE) {
114 | if (width == 16 && height == 8)
115 | size_attr = ATTR1_SIZE_16x8;
116 | if (width == 32 && height == 8)
117 | size_attr = ATTR1_SIZE_32x8;
118 | if (width == 32 && height == 16)
119 | size_attr = ATTR1_SIZE_32x16;
120 | if (width == 64 && height == 32)
121 | size_attr = ATTR1_SIZE_64x32;
122 | }
123 | if (shape_attr == ATTR0_SQUARE) {
124 | if (width == 8 && height == 8)
125 | size_attr = ATTR1_SIZE_8x8;
126 | if (width == 16 && height == 16)
127 | size_attr = ATTR1_SIZE_16x16;
128 | if (width == 32 && height == 32)
129 | size_attr = ATTR1_SIZE_32x32;
130 | if (width == 64 && height == 64)
131 | size_attr = ATTR1_SIZE_64x64;
132 | }
133 |
134 | // calculate the number of tiles used by one frame of this sprite (divide width and height by 8)
135 | spr.tile_sz = (width >> 3) * (height >> 3);
136 |
137 | // set main attributes
138 | // leave tile id (attr2) null, it will be set in sync
139 | u16 bpp_flag = (sprites_bpp8 == 1) ? ATTR0_8BPP : ATTR0_4BPP;
140 | obj_set_attr(&obj_buffer[index], ATTR0_REG | shape_attr | bpp_flag, size_attr, 0);
141 |
142 | // set default flags
143 | spr.flags = (DUSKSPRITE_FLAGS_VISIBLE);
144 |
145 | // save sprite metadata
146 | sprites[index] = spr;
147 |
148 | // sync other attributes
149 | dusk_sprites_sync(index);
150 |
151 | // return pointer to this sprite
152 | return &sprites[index];
153 | }
154 |
155 | inline void dusk_sprites_sync(int i) {
156 | Sprite* sprite = &sprites[i];
157 | OBJ_ATTR* obj = &obj_buffer[i];
158 | // position
159 | obj_set_pos(obj, sprite->x, sprite->y);
160 |
161 | // visibility
162 | if ((sprite->flags & DUSKSPRITE_FLAGS_VISIBLE) > 0) {
163 | obj_unhide(obj, ATTR0_REG);
164 | } else {
165 | obj_hide(obj);
166 | }
167 |
168 | // main attrs
169 |
170 | // logical base tid mode
171 | // obj_set_attr(obj, obj->attr0, obj->attr1, (sprite->tid + sprite->page) * sprite->tile_sz * 2);
172 |
173 | // raw base tid mode
174 | int bpp_mult = (sprites_bpp8 == 1) ? 2 : 1;
175 | u16 tid = (sprite->base_tid + (sprite->page * sprite->tile_sz)) * bpp_mult;
176 | obj_set_attr(obj, obj->attr0, obj->attr1, ATTR2_ID(tid) | ATTR2_PALBANK(0));
177 | }
178 |
179 | void dusk_sprites_update() {
180 | // sync all sprites
181 | for (int i = 0; i < NUM_SPRITES; i++) {
182 | dusk_sprites_sync(i);
183 | }
184 |
185 | // upload shadow oam to vram
186 |
187 | oam_copy(oam_mem, obj_buffer, NUM_SPRITES);
188 | // CpuFastSet(obj_buffer, oam_mem, NUM_SPRITES * 2);
189 | }
190 |
191 | void dusk_sprites_anim_play(Sprite* spr, Anim* anim) {
192 | // make sure page is within anim range
193 | if (spr->page < anim->start || spr->page >= (anim->start + anim->len)) {
194 | spr->page = anim->start; // reset to first
195 | }
196 | int ix = spr->page - anim->start;
197 | if (frame_count % anim->rate == 0) {
198 | ix = (ix + 1) % anim->len;
199 | }
200 | // set new frame
201 | spr->page = anim->start + ix;
202 | }
203 |
204 | u16 dusk_sprites_pos_to_tid(u16 x, u16 y, u16 sheet_width, u16 sheet_height) {
205 | // calculate corner tile id
206 | // first get x and y in tile coords
207 | u16 xt = x;
208 | u16 yt = y;
209 | u16 imw = sheet_width >> 3; // compute with bitshift (sheet_width / 8)
210 | // u16 imh = sheet_height >> 3;
211 | u16 tid = (yt * imw) + xt;
212 | return tid;
213 | }
214 |
215 | void enable_bg(u8 bg_id) {
216 | int bg_flag = 0;
217 | switch (bg_id) {
218 | case 0:
219 | bg_flag = DCNT_BG0;
220 | break;
221 | case 1:
222 | bg_flag = DCNT_BG1;
223 | break;
224 | case 2:
225 | bg_flag = DCNT_BG2;
226 | break;
227 | case 3:
228 | bg_flag = DCNT_BG3;
229 | break;
230 | }
231 |
232 | REG_DISPCNT |= bg_flag;
233 | }
234 |
235 | vu16* dusk_get_background_register(u8 bg_id) {
236 | switch (bg_id) {
237 | case 0:
238 | return ®_BG0CNT;
239 | case 1:
240 | return ®_BG1CNT;
241 | case 2:
242 | return ®_BG2CNT;
243 | case 3:
244 | return ®_BG3CNT;
245 | default:
246 | return NULL;
247 | }
248 | }
249 |
250 | void dusk_background_upload_raw(GritImage* img, int cbb, int sbb) {
251 | // TODO: support selecting slot
252 |
253 | // 1. upload the atlas tile palette to bg palette memory
254 | memcpy(&pal_bg_bank[0], img->pal, img->pal_sz);
255 | // 2. upload the atlas tiles to bg tile memory (CBB)
256 | memcpy(&tile_mem[cbb][0], img->tiles, img->tile_sz);
257 | // 3. upload the map (SBB)
258 | memcpy(&se_mem[sbb][0], img->map, img->map_sz);
259 | }
260 |
261 | void dusk_background_make(u8 bg_id, u16 size, Background bg) {
262 | // set bg on screen enabled
263 | enable_bg(bg_id);
264 | // set control flags
265 | vu16* bg_reg = dusk_get_background_register(bg_id);
266 |
267 | // u16 bpp_flag = (sprites_bpp8 == 1) ? BG_8BPP : BG_4BPP;
268 | *bg_reg |= BG_CBB(bg.cbb) | BG_SBB(bg.sbb) | BG_8BPP | size;
269 | }
--------------------------------------------------------------------------------
/src/dusk/src/sys.c:
--------------------------------------------------------------------------------
1 | #include "stdio.h"
2 | #include
3 | #include "ds_sys.h"
4 | #include "ds_load.h"
5 |
6 | __attribute__((used)) const char* _DUSK_LIB_VERSION = ("$DUSK " DUSK_VERSION);
7 |
8 | uint frame_count;
9 |
10 | void dusk_clear_vidmem() {
11 | // clear video memory (vram region)
12 | memset32(vid_mem, 0, VRAM_BG_SIZE / 4);
13 | // pal mem
14 | memset32(pal_bg_mem, 0, 0x00200 / 4);
15 | memset32(pal_obj_mem, 0, 0x00200 / 4);
16 | }
17 |
18 | void dusk_reset_irq() {
19 | irq_init(NULL);
20 | irq_add(II_VBLANK, NULL);
21 | }
22 |
23 | void dusk_init_all() {
24 | // 1. initialize system graphics
25 | dusk_init_graphics_mode0();
26 |
27 | dusk_reset_irq();
28 |
29 | // initialize loader
30 | dusk_load_init();
31 | }
32 |
33 | void dusk_init_graphics_mode0() {
34 | dusk_clear_vidmem();
35 | // dusk_reset_irq();
36 |
37 | // reset registers
38 | REG_DISPCNT = DCNT_MODE0;
39 | REG_BG0CNT = 0;
40 | REG_BG1CNT = 0;
41 | REG_BG2CNT = 0;
42 | REG_BG3CNT = 0;
43 | }
44 |
45 | void dusk_init_graphics_mode3() { REG_DISPCNT = DCNT_MODE3 | DCNT_BG2; }
46 |
47 | void dusk_frame() {
48 | // vid_vsync();
49 | VBlankIntrWait();
50 | frame_count++;
51 | }
52 |
53 | static bool scene_changed = false;
54 | static void nothing(void) {}
55 | static Scene next_scene = {
56 | .start = nothing,
57 | .end = nothing,
58 | .update = nothing,
59 | };
60 | static Scene current_scene = {
61 | .start = nothing,
62 | .end = nothing,
63 | .update = nothing,
64 | };
65 |
66 | void dusk_scene_set(Scene next) {
67 | scene_changed = true;
68 | next_scene = next;
69 | }
70 |
71 | void dusk_scene_update() {
72 | if (scene_changed) {
73 | scene_changed = false;
74 | current_scene.end();
75 | current_scene = next_scene;
76 | current_scene.start();
77 | }
78 | current_scene.update();
79 | }
80 |
--------------------------------------------------------------------------------