├── .gitignore
├── LICENSE
├── Makefile
├── README.md
├── assets
├── banner.bnr
├── banner.pdn
├── banner.png
├── banner.wav
├── banner_shorter.cwav
├── banner_shorter.wav
├── box.png
├── build-cia.rsf
├── icon-24px.png
├── icon-48px.png
├── icon.pdn
└── icon.smdh
├── data
├── FreeSans.ttf
├── NotoSans.LICENSE.txt
└── NotoSans_Regular.ttf
├── include
├── am.h
├── bank_updater.hpp
├── data_manager.hpp
├── error.h
├── filter.hpp
├── font_manager.hpp
├── fs.h
├── key.h
├── lang.h
├── personal.hpp
├── phbank.hpp
├── pkdir.h
├── pokedex.hpp
├── pokemon.hpp
├── save.hpp
├── save_manager.hpp
├── smdh.h
├── text.h
├── texture_manager.hpp
├── ts.h
├── utils.h
├── version.h
├── viewer
│ ├── box_viewer.hpp
│ ├── savexit_viewer.hpp
│ ├── ultra_box_viewer.hpp
│ └── viewer.hpp
└── wonder_pokemon.hpp
└── source
├── am.c
├── bank_updater.cpp
├── data_manager.cpp
├── filter.cpp
├── font_manager.cpp
├── fs.c
├── lang.c
├── main.cpp
├── personal.cpp
├── phbank.cpp
├── pokedex.cpp
├── pokemon.cpp
├── save_manager.cpp
├── text.c
├── texture_manager.cpp
├── ts.c
├── viewer
├── box_viewer.cpp
├── savexit_viewer.cpp
├── ultra_box_viewer.cpp
└── viewer.cpp
└── wonder_pokemon.cpp
/.gitignore:
--------------------------------------------------------------------------------
1 | build/
2 | romfs/
3 | data/
4 | assets/
5 | PHBank.elf
6 | PHBank.3dsx
7 | PHBank.smdh
8 | PHBank.xml
9 | PHBank.cia
10 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 | {one line to give the program's name and a brief idea of what it does.}
635 | Copyright (C) {year} {name of author}
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | {project} Copyright (C) {year} {fullname}
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
675 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | #---------------------------------------------------------------------------------
2 | .SUFFIXES:
3 | #---------------------------------------------------------------------------------
4 |
5 | ifeq ($(strip $(DEVKITARM)),)
6 | $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM")
7 | endif
8 |
9 | TOPDIR ?= $(CURDIR)
10 | include $(DEVKITARM)/3ds_rules
11 |
12 | #---------------------------------------------------------------------------------
13 | # TARGET is the name of the output
14 | # BUILD is the directory where object files & intermediate files will be placed
15 | # SOURCES is a list of directories containing source code
16 | # DATA is a list of directories containing data files
17 | # INCLUDES is a list of directories containing header files
18 | #
19 | # NO_SMDH: if set to anything, no SMDH file is generated.
20 | # ROMFS is the directory which contains the RomFS, relative to the Makefile (Optional)
21 | # APP_TITLE is the name of the app stored in the SMDH file (Optional)
22 | # APP_DESCRIPTION is the description of the app stored in the SMDH file (Optional)
23 | # APP_AUTHOR is the author of the app stored in the SMDH file (Optional)
24 | # ICON is the filename of the icon (.png), relative to the project folder.
25 | # If not set, it attempts to use one of the following (in this order):
26 | # - .png
27 | # - icon.png
28 | # - /default_icon.png
29 | #---------------------------------------------------------------------------------
30 | TARGET := $(notdir $(CURDIR))
31 | BUILD := build
32 | DATA := data
33 | SOURCES := source source/viewer
34 | INCLUDES := include include/viewer
35 |
36 | APP_TITLE := PHBank
37 | APP_DESCRIPTION := Pokémon Homebrew Bank
38 | APP_AUTHOR := Gocario
39 |
40 | # NO_SMDH := NO_SMDH
41 | ROMFS := romfs
42 | ICON := assets/icon-48px.png
43 | 3DSX_SMDH := assets/icon.smdh
44 | CIA_RSF := assets/build-cia.rsf
45 | CIA_SMDH := assets/icon.smdh
46 | CIA_ROMFS := assets/romfs.bin
47 | CIA_BANNER := assets/banner.bnr
48 | CIA_BANNER_PNG := assets/banner.png
49 | CIA_BANNER_WAV := assets/banner_shorter.cwav
50 |
51 | #---------------------------------------------------------------------------------
52 | # options for code generation
53 | #---------------------------------------------------------------------------------
54 | ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft
55 |
56 | CFLAGS := -g -Wall -O2 -mword-relocations \
57 | -fomit-frame-pointer -ffunction-sections \
58 | $(ARCH)
59 |
60 | CFLAGS += $(INCLUDE) -DARM11 -D_3DS -D__cia
61 |
62 | CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
63 |
64 | ASFLAGS := -g $(ARCH)
65 | LDFLAGS = -specs=3dsx.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
66 |
67 | # LIBS := -lsf2d -lctru -lm
68 | LIBS := -lsfil -lsftd -lfreetype -lpng -lz -lsf2d -lctru -lm
69 |
70 | #---------------------------------------------------------------------------------
71 | # list of directories containing libraries, this must be the top level containing
72 | # include and lib
73 | #---------------------------------------------------------------------------------
74 | # LIBDIRS := $(CTRULIB)
75 | LIBDIRS := $(CTRULIB) $(PORTLIBS)
76 |
77 |
78 | #---------------------------------------------------------------------------------
79 | # no real need to edit anything past this point unless you need to add additional
80 | # rules for different file extensions
81 | #---------------------------------------------------------------------------------
82 | ifneq ($(BUILD),$(notdir $(CURDIR)))
83 | #---------------------------------------------------------------------------------
84 |
85 | export OUTPUT := $(CURDIR)/$(TARGET)
86 | export TOPDIR := $(CURDIR)
87 |
88 | export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
89 | $(foreach dir,$(DATA),$(CURDIR)/$(dir))
90 |
91 | export DEPSDIR := $(CURDIR)/$(BUILD)
92 |
93 | CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
94 | CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
95 | SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
96 | PICAFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.v.pica)))
97 | SHLISTFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.shlist)))
98 | BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
99 |
100 | #---------------------------------------------------------------------------------
101 | # use CXX for linking C++ projects, CC for standard C
102 | #---------------------------------------------------------------------------------
103 | ifeq ($(strip $(CPPFILES)),)
104 | #---------------------------------------------------------------------------------
105 | export LD := $(CC)
106 | #---------------------------------------------------------------------------------
107 | else
108 | #---------------------------------------------------------------------------------
109 | export LD := $(CXX)
110 | #---------------------------------------------------------------------------------
111 | endif
112 | #---------------------------------------------------------------------------------
113 |
114 | export OFILES := $(addsuffix .o,$(BINFILES)) \
115 | $(PICAFILES:.v.pica=.shbin.o) $(SHLISTFILES:.shlist=.shbin.o) \
116 | $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
117 |
118 | export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
119 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \
120 | -I$(CURDIR)/$(BUILD)
121 |
122 | export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
123 |
124 | ifeq ($(strip $(ICON)),)
125 | icons := $(wildcard *.png)
126 | ifneq (,$(findstring $(TARGET).png,$(icons)))
127 | export APP_ICON := $(TOPDIR)/$(TARGET).png
128 | else
129 | ifneq (,$(findstring icon.png,$(icons)))
130 | export APP_ICON := $(TOPDIR)/icon.png
131 | endif
132 | endif
133 | else
134 | export APP_ICON := $(TOPDIR)/$(ICON)
135 | endif
136 |
137 | ifeq ($(strip $(NO_SMDH)),)
138 | export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh
139 | endif
140 |
141 | ifneq ($(ROMFS),)
142 | export _3DSXFLAGS += --romfs=$(CURDIR)/$(ROMFS)
143 | endif
144 |
145 | .PHONY: $(BUILD) clean all
146 |
147 | #---------------------------------------------------------------------------------
148 | all: $(BUILD)
149 |
150 | $(BUILD):
151 | @[ -d $@ ] || mkdir -p $@
152 | @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
153 |
154 | #---------------------------------------------------------------------------------
155 | clean:
156 | @echo clean ...
157 | @rm -fr $(BUILD) $(TARGET).elf $(TARGET).3dsx $(TARGET).smdh $(TARGET).cia
158 |
159 | #---------------------------------------------------------------------------------
160 | run: $(BUILD)
161 | @echo run ...
162 | $(DEVKITPRO)/devkitCITRA/citra.exe $(TARGET).3dsx
163 |
164 | #---------------------------------------------------------------------------------
165 | 3dsx: $(BUILD)
166 | @echo built ... $(TARGET).3dsx
167 |
168 | #---------------------------------------------------------------------------------
169 | cia: $(BUILD)
170 | # @bannertool makebanner -o $(CIA_BANNER) -i $(CIA_BANNER_PNG) -ca $(CIA_BANNER_WAV)
171 | # @echo built ... $(CIA_BANNER)
172 | # @bannertool makesmdh -o $(CIA_SMDH) -i $(ICON) -s "$(APP_TITLE)" -l "$(APP_DESCRIPTION)" -p "$(APP_AUTHOR)" -fvisible
173 | # @echo built ... $(TARGET).smdh
174 | # @3dstool -c -t romfs -f $(CIA_ROMFS) --romfs-dir $(ROMFS)
175 | # @echo built ... $(CIA_ROMFS)
176 | @makerom -f cia -target t -o $(TARGET).cia -rsf $(CIA_RSF) -elf $(TARGET).elf -icon $(CIA_SMDH) -banner $(CIA_BANNER) -exefslogo -romfs $(CIA_ROMFS)
177 | @echo built ... $(TARGET).cia
178 |
179 | #---------------------------------------------------------------------------------
180 | else
181 |
182 | DEPENDS := $(OFILES:.o=.d)
183 |
184 | #---------------------------------------------------------------------------------
185 | # main targets
186 | #---------------------------------------------------------------------------------
187 | ifeq ($(strip $(NO_SMDH)),)
188 | $(OUTPUT).3dsx : $(OUTPUT).elf $(OUTPUT).smdh
189 | else
190 | $(OUTPUT).3dsx : $(OUTPUT).elf
191 | endif
192 |
193 | $(OUTPUT).elf : $(OFILES)
194 |
195 | #---------------------------------------------------------------------------------
196 | # you need a rule like this for each extension you use as binary data
197 | #---------------------------------------------------------------------------------
198 | %.bin.o : %.bin
199 | #---------------------------------------------------------------------------------
200 | @echo $(notdir $<)
201 | @$(bin2o)
202 |
203 | #---------------------------------------------------------------------------------
204 | %.ttf.o : %.ttf
205 | #---------------------------------------------------------------------------------
206 | @echo $(notdir $<)
207 | @$(bin2o)
208 |
209 | #---------------------------------------------------------------------------------
210 | # rules for assembling GPU shaders
211 | #---------------------------------------------------------------------------------
212 | define shader-as
213 | $(eval CURBIN := $(patsubst %.shbin.o,%.shbin,$(notdir $@)))
214 | picasso -o $(CURBIN) $1
215 | bin2s $(CURBIN) | $(AS) -o $@
216 | echo "extern const u8" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > `(echo $(CURBIN) | tr . _)`.h
217 | echo "extern const u8" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> `(echo $(CURBIN) | tr . _)`.h
218 | echo "extern const u32" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(CURBIN) | tr . _)`.h
219 | endef
220 |
221 | %.shbin.o : %.v.pica %.g.pica
222 | @echo $(notdir $^)
223 | @$(call shader-as,$^)
224 |
225 | %.shbin.o : %.v.pica
226 | @echo $(notdir $<)
227 | @$(call shader-as,$<)
228 |
229 | %.shbin.o : %.shlist
230 | @echo $(notdir $<)
231 | @$(call shader-as,$(foreach file,$(shell cat $<),$(dir $<)/$(file)))
232 |
233 | -include $(DEPENDS)
234 |
235 | #---------------------------------------------------------------------------------------
236 | endif
237 | #---------------------------------------------------------------------------------------
238 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # [Pokémon Homebrew Bank](https://gbatemp.net/threads/398718/)
3 |
4 | PHBank is a homebrew which allows to manage a local bank for XY and ORAS Pokémon games, just like the Pokébank, but as a free offline service.
5 | This homebrew is not intended to cheat (not even cloning). It's just a storage solution.
6 |
7 | The source code is available under the [GPLv3 license](https://github.com/gocario/PHBank/blob/master/LICENSE) on [github](https://github.com/gocario/PHBank), and the resources are available on [github](https://github.com/gocario/PKBrew) too.
8 |
9 |
10 | ## What this Homebrew can do:
11 | * Work on o3ds and n3ds!
12 | * Navigate through the PC boxes of a XY/ORAS save and the Bank boxes.
13 | * Display a more specific resume per Pokémon (like IVs/EVs).
14 | * Select one Pokémon (with stylus or buttons) and move it to another slot/box.
15 | * Select some Pokémon (with buttons) and move them to another box.
16 | * Swap an entire box content to another one (pc <-> bank).
17 | * Autocomplete the Pokédex when importing Pokémon to a gamesave.
18 | * Prompt a dialog to save/exit/backup during the homebrew execution.
19 | * Export/Import the savedata directly to/from the game, without the need of external tools (/main).
20 | * Load/Save the bankdata to/from the bank, located in the SD card (/pk/bank/bank).
21 |
22 | ## How to install it:
23 | * Just extract the archive at (to?) the root of your SD card.
24 | * It must contains:
25 | * The homebrew files /3ds/PHBank/[PHBankFiles].
26 | * The cia installer in /cia/PHBank.cia
27 | * The data files /pk/[DataFiles].
28 |
29 | ## How to import from <= [v1.1.4-beta-a]:
30 | * Install PHBank normally, see above.
31 | * Copy the bank file from /pkbank/bank to /pk/bank/bank.
32 | * You can delete the /pkbank/ folder.
33 |
34 | ## Controls
35 |
36 | ### Everywhere
37 | * DPad/CPad: Move the cursor inbox, change box, change pc/bank.
38 | * L/R: Change the current box.
39 | * LZ/RZ: Switch from PC to Bank and vice versa (can be done with Pad and/or stylus too).
40 | * Start: Open the savexit menu, for exiting or backing up.
41 | * Select: Switch the selection mode (Single -> Quick -> Multiple).
42 |
43 | ### Touchscreen
44 | * Move the cursor inbox.
45 | * Change the current box.
46 | * Switch PC/Bank.
47 | * Drag & Drop Pokémon.
48 | * Change the selection mode.
49 |
50 | ### In Single selection mode (Red):
51 | * A: Select Pokémon / Move Pokémon if one is already selected.
52 | * B: Cancel selection.
53 | ### In Quick selection mdoe (Blue):
54 | * A: Select Pokémon / Move Pokémon if one is already selected.
55 | * B: Cancel selection.
56 | * Y: Swap the current PC box content with the current Bank box content.
57 |
58 | ### In Multiple selection mdoe (Blue):
59 | * Y: Activate the box selector (TODO: transform it as a button on screen).
60 |
61 | ## Todo List
62 | * Wonder box ;)
63 | * Display more specific information per Pokémon (Tabs for contest/met/etc).
64 | * Enhance more the GUI.
65 | * When moving Pokémon with the DPad/A, switch the held Pokémon.
66 |
67 | ## Nota Bene
68 | I only tested this homebrew with Pokémon Alpha Sapphire on a cartridge on a n3ds.
69 | Not cheat, no kidding.
70 |
71 | ## Credits
72 | Thanks to [suloku](https://github.com/suloku) for all his work on the project.
73 |
74 | Thanks to [Kaphotics](https://github.com/kwsch) & [Asia81](https://github.com/Asia81) (and [PKHex](https://github.com/kwsch/PKHeX)'s contributors) for the save functions (offset, algorithms) and the data (personal, text).
75 |
76 | Thanks to [Slashcash](https://github.com/Slashcash) & [Stracker](https://github.com/Strackeror) (and [PCHex](https://github.com/Strackeror/PCHex)/[PCHex++](https://github.com/Slashcash/PCHex-plusplus)'s contributors) for their help.
77 |
78 | Thanks to @Xenosaiga and [ihaveamac](https://github.com/ihaveamac) for being the cia build.
79 |
80 | Thanks to [xerpi](https://github.com/xerpi) (and [SF2D](https://github.com/xerpi/sf2dlib)/[SFTD](https://github.com/xerpi/sftdlib)/[SFIL](https://github.com/xerpi/sfillib)'s contributores) for the graphic library.
81 |
82 | Thanks to [profi200](https://github.com/profi200) and other people on #3dsdev who helped me.
83 |
84 | Thanks to [smealum](https://github.com/smealum) and [yellows8](https://github.com/yellows8) for the exploits and [ctrulib](https://github.com/smealum/ctrulib).
85 |
86 | Merci !
87 |
88 | __Disclaimer: I'm not responsible if you lose or corrupt your save by using this homebrew. It mays contain bugs even within the normal intended use. Use it at your own risk.__
89 |
90 | ****ALWAYS MAKE A BACKUP!**** __(Hold L while launching homebrew or/and use tvds/svdt/JKSM)__
91 |
--------------------------------------------------------------------------------
/assets/banner.bnr:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gocario/PHBank/a956ab39060148c8dafdb1f472c96632b22dcc65/assets/banner.bnr
--------------------------------------------------------------------------------
/assets/banner.pdn:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gocario/PHBank/a956ab39060148c8dafdb1f472c96632b22dcc65/assets/banner.pdn
--------------------------------------------------------------------------------
/assets/banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gocario/PHBank/a956ab39060148c8dafdb1f472c96632b22dcc65/assets/banner.png
--------------------------------------------------------------------------------
/assets/banner.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gocario/PHBank/a956ab39060148c8dafdb1f472c96632b22dcc65/assets/banner.wav
--------------------------------------------------------------------------------
/assets/banner_shorter.cwav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gocario/PHBank/a956ab39060148c8dafdb1f472c96632b22dcc65/assets/banner_shorter.cwav
--------------------------------------------------------------------------------
/assets/banner_shorter.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gocario/PHBank/a956ab39060148c8dafdb1f472c96632b22dcc65/assets/banner_shorter.wav
--------------------------------------------------------------------------------
/assets/box.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gocario/PHBank/a956ab39060148c8dafdb1f472c96632b22dcc65/assets/box.png
--------------------------------------------------------------------------------
/assets/build-cia.rsf:
--------------------------------------------------------------------------------
1 | BasicInfo:
2 | Title : PHBank
3 | ProductCode : CTR-P-KBKZ
4 | Logo : Homebrew # Nintendo / Licensed / Distributed / iQue / iQueForSystem / Homebrew
5 |
6 | RomFs:
7 | # Specifies the root path of the read only file system to include in the ROM.
8 | RootPath : romfs
9 |
10 | TitleInfo:
11 | Category : Application
12 | UniqueId : 0x0f04ed
13 |
14 | Option:
15 | UseOnSD : true # true if App is to be installed to SD
16 | FreeProductCode : true # Removes limitations on ProductCode
17 | MediaFootPadding : false # If true CCI files are created with padding
18 | EnableCrypt : false # Enables encryption for NCCH and CIA
19 | EnableCompress : true # Compresses where applicable (currently only exefs:/.code)
20 |
21 | AccessControlInfo:
22 | CoreVersion : 2
23 |
24 | # Exheader Format Version
25 | DescVersion : 2
26 |
27 | # Minimum Required Kernel Version (below is for 4.5.0)
28 | ReleaseKernelMajor : "02"
29 | ReleaseKernelMinor : "33"
30 |
31 | # ExtData
32 | UseExtSaveData : false # enables ExtData
33 | #ExtSaveDataId : 0x300 # only set this when the ID is different to the UniqueId
34 |
35 | # FS:USER Archive Access Permissions
36 | # Uncomment as required
37 | FileSystemAccess:
38 | #- CategorySystemApplication
39 | #- CategoryHardwareCheck
40 | - CategoryFileSystemTool
41 | #- Debug
42 | #- TwlCardBackup
43 | #- TwlNandData
44 | #- Boss
45 | - DirectSdmc
46 | #- Core
47 | #- CtrNandRo
48 | #- CtrNandRw
49 | #- CtrNandRoWrite
50 | #- CategorySystemSettings
51 | #- CardBoard
52 | #- ExportImportIvs
53 | #- DirectSdmcWrite
54 | #- SwitchCleanup
55 | #- SaveDataMove
56 | #- Shop
57 | #- Shell
58 | - CategoryHomeMenu
59 |
60 | # Process Settings
61 | MemoryType : Application # Application/System/Base
62 | SystemMode : 64MB # 64MB(Default)/96MB/80MB/72MB/32MB
63 | IdealProcessor : 0
64 | AffinityMask : 1
65 | Priority : 16
66 | MaxCpu : 0 # Let system decide
67 | HandleTableSize : 0x200
68 | DisableDebug : false
69 | EnableForceDebug : false
70 | CanWriteSharedPage : true
71 | CanUsePrivilegedPriority : false
72 | CanUseNonAlphabetAndNumber : true
73 | PermitMainFunctionArgument : true
74 | CanShareDeviceMemory : true
75 | RunnableOnSleep : false
76 | SpecialMemoryArrange : true
77 |
78 | # New3DS Exclusive Process Settings
79 | SystemModeExt : 124MB # Legacy(Default)/124MB/178MB Legacy:Use Old3DS SystemMode
80 | CpuSpeed : 268MHz # 268MHz(Default)/804MHz
81 | EnableL2Cache : true # false(default)/true
82 | CanAccessCore2 : true
83 |
84 | # Virtual Address Mappings
85 | IORegisterMapping:
86 | - 1ff00000-1ff7ffff # DSP memory
87 | MemoryMapping:
88 | - 1f000000-1f5fffff:r # VRAM
89 |
90 | # Accessible SVCs, :
91 | SystemCallAccess:
92 | ArbitrateAddress: 34
93 | Break: 60
94 | CancelTimer: 28
95 | ClearEvent: 25
96 | ClearTimer: 29
97 | CloseHandle: 35
98 | ConnectToPort: 45
99 | ControlMemory: 1
100 | CreateAddressArbiter: 33
101 | CreateEvent: 23
102 | CreateMemoryBlock: 30
103 | CreateMutex: 19
104 | CreateSemaphore: 21
105 | CreateThread: 8
106 | CreateTimer: 26
107 | DuplicateHandle: 39
108 | ExitProcess: 3
109 | ExitThread: 9
110 | GetCurrentProcessorNumber: 17
111 | GetHandleInfo: 41
112 | GetProcessId: 53
113 | GetProcessIdOfThread: 54
114 | GetProcessIdealProcessor: 6
115 | GetProcessInfo: 43
116 | GetResourceLimit: 56
117 | GetResourceLimitCurrentValues: 58
118 | GetResourceLimitLimitValues: 57
119 | GetSystemInfo: 42
120 | GetSystemTick: 40
121 | GetThreadContext: 59
122 | GetThreadId: 55
123 | GetThreadIdealProcessor: 15
124 | GetThreadInfo: 44
125 | GetThreadPriority: 11
126 | MapMemoryBlock: 31
127 | OutputDebugString: 61
128 | QueryMemory: 2
129 | ReleaseMutex: 20
130 | ReleaseSemaphore: 22
131 | SendSyncRequest1: 46
132 | SendSyncRequest2: 47
133 | SendSyncRequest3: 48
134 | SendSyncRequest4: 49
135 | SendSyncRequest: 50
136 | SetThreadPriority: 12
137 | SetTimer: 27
138 | SignalEvent: 24
139 | SleepThread: 10
140 | UnmapMemoryBlock: 32
141 | WaitSynchronization1: 36
142 | WaitSynchronizationN: 37
143 | Backdoor: 123
144 |
145 | # Service List
146 | # Maximum 34 services (32 if firmware is prior to 9.3.0)
147 | ServiceAccessControl:
148 | - cfg:u
149 | - fs:USER
150 | - gsp::Gpu
151 | - hid:USER
152 | - ndm:u
153 | - pxi:dev
154 | - APT:U
155 | - ac:u
156 | - act:u
157 | - am:net
158 | - boss:U
159 | - cam:u
160 | - cecd:u
161 | - csnd:SND
162 | - frd:u
163 | - http:C
164 | - ir:USER
165 | - ir:u
166 | - ir:rst
167 | - ldr:ro
168 | - mic:u
169 | - news:u
170 | - nfc:u
171 | - nim:aoc
172 | - nwm::UDS
173 | - ptm:u
174 | - qtm:u
175 | - soc:U
176 | - ssl:C
177 | - y2r:u
178 |
179 |
180 | SystemControlInfo:
181 | SaveDataSize: 0K
182 | RemasterVersion: 0
183 | StackSize: 0x40000
184 |
185 | # Modules that run services listed above should be included below
186 | # Maximum 48 dependencies
187 | # If a module is listed that isn't present on the 3DS, the title will get stuck at the logo (3ds waves)
188 | # So act, nfc and qtm are commented for 4.x support. Uncomment if you need these.
189 | # :
190 | Dependency:
191 | ac: 0x0004013000002402
192 | #act: 0x0004013000003802
193 | am: 0x0004013000001502
194 | boss: 0x0004013000003402
195 | camera: 0x0004013000001602
196 | cecd: 0x0004013000002602
197 | cfg: 0x0004013000001702
198 | codec: 0x0004013000001802
199 | csnd: 0x0004013000002702
200 | dlp: 0x0004013000002802
201 | dsp: 0x0004013000001a02
202 | friends: 0x0004013000003202
203 | gpio: 0x0004013000001b02
204 | gsp: 0x0004013000001c02
205 | hid: 0x0004013000001d02
206 | http: 0x0004013000002902
207 | i2c: 0x0004013000001e02
208 | ir: 0x0004013000003302
209 | mcu: 0x0004013000001f02
210 | mic: 0x0004013000002002
211 | ndm: 0x0004013000002b02
212 | news: 0x0004013000003502
213 | #nfc: 0x0004013000004002
214 | nim: 0x0004013000002c02
215 | nwm: 0x0004013000002d02
216 | pdn: 0x0004013000002102
217 | ps: 0x0004013000003102
218 | ptm: 0x0004013000002202
219 | #qtm: 0x0004013020004202
220 | ro: 0x0004013000003702
221 | socket: 0x0004013000002e02
222 | spi: 0x0004013000002302
223 | ssl: 0x0004013000002f02
--------------------------------------------------------------------------------
/assets/icon-24px.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gocario/PHBank/a956ab39060148c8dafdb1f472c96632b22dcc65/assets/icon-24px.png
--------------------------------------------------------------------------------
/assets/icon-48px.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gocario/PHBank/a956ab39060148c8dafdb1f472c96632b22dcc65/assets/icon-48px.png
--------------------------------------------------------------------------------
/assets/icon.pdn:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gocario/PHBank/a956ab39060148c8dafdb1f472c96632b22dcc65/assets/icon.pdn
--------------------------------------------------------------------------------
/assets/icon.smdh:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gocario/PHBank/a956ab39060148c8dafdb1f472c96632b22dcc65/assets/icon.smdh
--------------------------------------------------------------------------------
/data/FreeSans.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gocario/PHBank/a956ab39060148c8dafdb1f472c96632b22dcc65/data/FreeSans.ttf
--------------------------------------------------------------------------------
/data/NotoSans.LICENSE.txt:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
--------------------------------------------------------------------------------
/data/NotoSans_Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gocario/PHBank/a956ab39060148c8dafdb1f472c96632b22dcc65/data/NotoSans_Regular.ttf
--------------------------------------------------------------------------------
/include/am.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | /**
3 | * @file am.h
4 | * @brief Application Manager Services for Pokémon titles
5 | */
6 | #ifndef AM_H
7 | #define AM_H
8 |
9 | #ifdef __cplusplus
10 | extern "C" {
11 | #endif
12 |
13 | #include <3ds/types.h>
14 | #include <3ds/services/fs.h>
15 | #include <3ds/services/am.h>
16 |
17 | #include "smdh.h"
18 |
19 | /// A simple titleid/mediatype struct with a magic smdh.
20 | typedef struct
21 | {
22 | u64 titleid;
23 | smdh_s* smdh;
24 | FS_MediaType mediatype;
25 | } AM_TitleMediaEntry;
26 |
27 | /**
28 | * @brief Gets a list of Pokémon title IDs paired with its mediatype.
29 | * @param count Pointer to write the title count to.
30 | * @param titleList Buffer to write retrieved title media entries to. (it's malloc'd inside)
31 | * @see AM_FreePokemonTitleEntryList(AM_TitleMediaEntry*, u32)
32 | */
33 | Result AM_GetPokemonTitleEntryList(AM_TitleMediaEntry** titleList, u32* count);
34 |
35 | /**
36 | * @brief Frees the title media entries buffer previously alocated.
37 | * @param count The title count.
38 | * @param titleList Buffer to free.
39 | * @see AM_GetPokemonTitleEntryList(AM_TitleMediaEntry**, u32*)
40 | */
41 | Result AM_FreePokemonTitleEntryList(AM_TitleMediaEntry* titleList, u32 count);
42 |
43 | #ifdef __cplusplus
44 | }
45 | #endif
46 |
47 | #endif // AM_H
48 |
--------------------------------------------------------------------------------
/include/bank_updater.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 | /**
3 | * @file bank_updater.hpp
4 | */
5 | #ifndef BANK_UPDATER_HPP
6 | #define BANK_UPDATER_HPP
7 |
8 | #include "version.h"
9 | #include "save.hpp"
10 |
11 | namespace BankUpdater
12 | {
13 | /**
14 | * @brief Updates a bankbuffer to the latest version.
15 | * @param bankbuffer The bank buffer of the bank file.
16 | * @param bytesRead The number of read bytes.
17 | * @return Whether the buffer is up to date.
18 | * @see VERSION
19 | */
20 | bool updateBank(bankbuffer_t bankbuffer, u32 bytesRead);
21 | }
22 |
23 | #endif // BANK_UPDATER_HPP
24 |
--------------------------------------------------------------------------------
/include/data_manager.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 | /**
3 | * @file data_manager.hpp
4 | * @brief Data Manager
5 | */
6 | #ifndef DATA_MANAGER_HPP
7 | #define DATA_MANAGER_HPP
8 |
9 | #include <3ds/types.h>
10 |
11 | #define BANK_TEXT_COUNT (29) // 0: Blank
12 | #define DEX_ABILITIES_COUNT (192) // 0: None
13 | #define DEX_ITEMS_COUNT (776) // 0: None
14 | #define DEX_MOVES_COUNT (622) // 0: None
15 | #define DEX_NATURES_COUNT (25)
16 | #define DEX_SPECIES_COUNT (722) // 0: Egg
17 | #define DEX_TYPES_COUNT (18) // 0: Normal
18 |
19 | enum class BankText : u8
20 | {
21 | Blank = 0,
22 | BOX_VIEWER = 1,
23 | GameTrainer = 2,
24 | Level = 3,
25 | DexNo = 4,
26 | OriginalTrainer = 5,
27 | Stat = 6,
28 | Value = 7,
29 | IV = 8,
30 | EV = 9,
31 | HitPoint = 10,
32 | Attack = 11,
33 | Defense = 12,
34 | SpAttack = 13,
35 | SpDefense = 14,
36 | Speed = 15,
37 | Nature = 16,
38 | Ability = 17,
39 | Item = 18,
40 | HiddenPower = 19,
41 | Moves = 20,
42 | Box = 21,
43 |
44 | SAVEXIT_VIEWER = 23,
45 | ExitMessage = 24,
46 | SaveExit = 25,
47 | Exit = 26,
48 | Backup = 27,
49 | Return = 28,
50 | };
51 |
52 | class DataManager
53 | {
54 | private:
55 | uint32_t* wText[BANK_TEXT_COUNT];
56 | uint32_t* wAbilities[DEX_ABILITIES_COUNT];
57 | uint32_t* wItems[DEX_ITEMS_COUNT];
58 | uint32_t* wMoves[DEX_MOVES_COUNT];
59 | uint32_t* wNatures[DEX_NATURES_COUNT];
60 | uint32_t* wSpecies[DEX_SPECIES_COUNT];
61 | uint32_t* wTypes[DEX_TYPES_COUNT];
62 |
63 | public:
64 | DataManager(void);
65 | ~DataManager(void);
66 |
67 | Result load(void);
68 |
69 | const char* lang(void);
70 | const uint32_t* text(BankText text);
71 | const uint32_t* abilities(u32 ability);
72 | const uint32_t* items(u32 item);
73 | const uint32_t* moves(u32 move);
74 | const uint32_t* natures(u32 nature);
75 | const uint32_t* species(u32 species);
76 | const uint32_t* types(u8 type);
77 |
78 | private:
79 | Result loadPersonal(const char* file, bool ao, u32 personalCount, u32 personalInfoSize);
80 | Result loadDataFile(const char* file, uint32_t** data, u32 lineCount);
81 | void loadDataLines(const u8* src, uint32_t** data, u32 srcSize, u32 lineCount);
82 | void freeDataLines(uint32_t** data, u32 lineCount);
83 | };
84 |
85 | #endif // DATA_MANAGER_HPP
86 |
--------------------------------------------------------------------------------
/include/error.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #define ERR_SAVE (1 << 2)
4 | #define ERR_DATA (1 << 3)
5 | #define ERR_FONT (1 << 4)
6 | #define ERR_GRAPHICS (1 << 5)
7 | #define ERR_FILESYSTEM (1 << 7)
8 |
--------------------------------------------------------------------------------
/include/filter.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 | /**
3 | * @file filter.hpp
4 | * @brief Filter module
5 | */
6 | #ifndef FILTER_HPP
7 | #define FILTER_HPP
8 |
9 | #include "save.hpp"
10 |
11 | namespace Filter
12 | {
13 | /**
14 | * @brief Runs a filter to see if the Pokémon can be transfered from Bank to XY
15 | * @param pkm The Pokémon to filter.
16 | * @return Wether the Pokémon runs through the filter.
17 | */
18 | bool filterToXY(pkm_s* pkm);
19 |
20 | /**
21 | * @brief Runs a filter to see if the Pokémon can be transfered from the Bank to ORAS
22 | * @param pkm The Pokémon to filter.
23 | * @return Wether the Pokémon runs through the filter.
24 | */
25 | bool filterFromXY(pkm_s* pkm);
26 |
27 | /**
28 | * @brief Runs a filter to see if the Pokémon can be transfered from the Bank to ORAS
29 | * @param pkm The Pokémon to filter.
30 | * @return Wether the Pokémon runs through the filter.
31 | */
32 | bool filterToORAS(pkm_s* pkm);
33 |
34 | /**
35 | * @brief Runs a filter to see if the Pokémon can be transfered from ORAS to the Bank
36 | * @param pkm The Pokémon to filter.
37 | * @return Wether the Pokémon runs through the filter.
38 | */
39 | bool filterFromORAS(pkm_s* pkm);
40 | };
41 |
42 | #endif // FILTER_HPP
43 |
--------------------------------------------------------------------------------
/include/font_manager.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 | /**
3 | * @file font_manager.hpp
4 | * @brief Font Manager
5 | */
6 | #ifndef FONT_MANAGER_HPP
7 | #define FONT_MANAGER_HPP
8 |
9 | #include
10 |
11 | class FontManager
12 | {
13 | public:
14 | FontManager(void);
15 | ~FontManager(void);
16 |
17 | Result load(void);
18 |
19 | private:
20 | bool loadFonts(void);
21 | };
22 |
23 | #endif // FONT_MANAGER_HPP
24 |
--------------------------------------------------------------------------------
/include/fs.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | /**
3 | * @file fs.h
4 | * @brief Filesystem Services
5 | */
6 | #ifndef FS_H
7 | #define FS_H
8 |
9 | #ifdef __cplusplus
10 | extern "C" {
11 | #endif
12 |
13 | #include <3ds/services/fs.h>
14 |
15 | /// The data of a user savedata archive's lowpath.
16 | typedef struct
17 | {
18 | u32 mediatype; ///< The mediatype of the FS_Path.
19 | u32 lowid; ///< The lower word of the saveid.
20 | u32 highid; ///< The upper word of the saveid.
21 | } FS_UserSaveData_LowPathData;
22 |
23 | /// Attribute flags extended.
24 | enum
25 | {
26 | FS_ATTRIBUTE_NONE = 0, ///< None.
27 | };
28 |
29 | extern FS_Archive saveArchive;
30 |
31 | /**
32 | * @brief Reads a file (path) to dst.
33 | * @param[in] path The path of the file to read.
34 | * @param[out] dst The destination buffer.
35 | * @param maxSize The max size in bytes to read.
36 | * @param[in] archive The archive handle where the file is located.
37 | * @param[out] bytesRead The total of read bytes.
38 | */
39 | Result FS_ReadFile(const char* path, void* dst, u64 maxSize, FS_Archive archive, u32* bytesRead);
40 |
41 | /**
42 | * @brief Writes src to a file (path).
43 | * @param[in] path The path of the file to write.
44 | * @param[in] src The source buffer.
45 | * @param size The size in bytes to write.
46 | * @param[in] archive The archive handle where the file is located.
47 | * @param[out] bytesWritten The total of written bytes.
48 | */
49 | Result FS_WriteFile(const char* path, const void* src, u64 size, FS_Archive archive, u32* bytesWritten);
50 |
51 | /**
52 | * @brief Deletes a file (path).
53 | * @param[in] path The path of the file to delete.
54 | * @param[in] archive The archive handle where the file is located.
55 | */
56 | Result FS_DeleteFile(const char* path, FS_Archive archive);
57 |
58 | /**
59 | * @brief Commits an archive.
60 | * @param[in] The archive handle to commit.
61 | */
62 | Result FS_CommitArchive(FS_Archive archive);
63 |
64 | #ifdef __cia
65 |
66 | /**
67 | * @brief Initializes the filesystem service for the CIA build.
68 | */
69 | Result FSCIA_Init(u64 titleid, FS_MediaType mediatype);
70 |
71 | /**
72 | * @brief Exits the filesystem service.
73 | */
74 | Result FSCIA_Exit(void);
75 |
76 | #else
77 |
78 | /**
79 | * @brief Initializes the filesystem service.
80 | */
81 | Result FS_Init(void);
82 |
83 | /**
84 | * @brief Exits the filesystem service.
85 | */
86 | Result FS_Exit(void);
87 |
88 | #endif // __cia
89 |
90 | #ifdef __cplusplus
91 | }
92 | #endif
93 |
94 | #endif // FS_H
95 |
--------------------------------------------------------------------------------
/include/key.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | /**
3 | * @file key.h
4 | */
5 | #ifndef KEY_HPP
6 | #define KEY_HPP
7 |
8 | #ifdef __cplusplus
9 | extern "C" {
10 | #endif
11 |
12 | #include <3ds/services/apt.h>
13 | #include <3ds/services/hid.h>
14 | #include <3ds/services/gspgpu.h>
15 |
16 | /**
17 | * @brief Key value.
18 | */
19 | enum
20 | {
21 | KEY_ANY = 0b11111111000100001100111111111111, ///< Any key
22 | };
23 |
24 | /**
25 | * @brief Blocks the running process until some keys are pressed.
26 | * @param key The key(s) to press.
27 | */
28 | inline void waitKey(u32 key)
29 | {
30 | while (aptMainLoop())
31 | {
32 | gspWaitForVBlank();
33 | hidScanInput();
34 | // TODO Change hidKeysDown to hidKeysHeld?
35 | if (hidKeysDown() & key) break;
36 | }
37 | }
38 |
39 | #ifdef __cplusplus
40 | }
41 | #endif
42 |
43 | #endif // KEY_HPP
44 |
--------------------------------------------------------------------------------
/include/lang.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | /**
3 | * @file lang.h
4 | */
5 | #ifndef LANG_H
6 | #define LANG_H
7 |
8 | typedef enum
9 | {
10 | LANGUAGE_JP = 1, ///< Japan
11 | LANGUAGE_EN = 2, ///< English
12 | LANGUAGE_FR = 3, ///< French
13 | LANGUAGE_IT = 4, ///< Italian
14 | LANGUAGE_DE = 5, ///< German
15 | LANGUAGE_x6 = 6, ///< 0x6
16 | LANGUAGE_ES = 7, ///< Spanish
17 | LANGUAGE_KR = 8, ///< Korean
18 | } Language;
19 |
20 | extern Language userlang;
21 |
22 | #ifdef __cplusplus
23 | extern "C" {
24 | #endif
25 |
26 | void updateSystemLanguage(void);
27 |
28 | #ifdef __cplusplus
29 | }
30 | #endif
31 |
32 | #endif // LANG_H
33 |
--------------------------------------------------------------------------------
/include/personal.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include <3ds/types.h>
4 |
5 | #define PERSONAL_XY_COUNT (799)
6 | #define PERSONAL_AO_COUNT (826)
7 | #define PERSONAL_INFO_XY_SIZE (0x40)
8 | #define PERSONAL_INFO_AO_SIZE (0x50)
9 |
10 | struct PersonalInfo
11 | {
12 | uint8_t HP;
13 | uint8_t ATK;
14 | uint8_t DEF;
15 | uint8_t SPE;
16 | uint8_t SPA;
17 | uint8_t SPD;
18 | uint8_t types[2];
19 | uint16_t items[3];
20 | uint8_t gender;
21 | uint8_t baseFriendship;
22 | uint8_t expGrowth;
23 | uint16_t formStats;
24 | uint16_t formSprite;
25 | uint8_t formCount;
26 | uint8_t color;
27 | };
28 |
29 | class PersonalMaster
30 | {
31 | private:
32 | u32 personalCount;
33 | u32 personalSize;
34 | PersonalInfo* personals;
35 |
36 | public:
37 | PersonalMaster(void);
38 | ~PersonalMaster(void);
39 | void import(const u8* buffer, u32 personalCount, u32 personalSize);
40 |
41 | const PersonalInfo& operator()(u16 species) const;
42 | const PersonalInfo& operator()(u16 species, u8 form) const;
43 | };
44 |
45 | extern PersonalMaster Personal;
46 |
--------------------------------------------------------------------------------
/include/phbank.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 | /**
3 | * @file phbank.hpp
4 | * @brief Master-manager
5 | */
6 | #ifndef PHBANK_HPP
7 | #define PHBANK_HPP
8 |
9 | #include "save_manager.hpp"
10 | #include "data_manager.hpp"
11 | #include "font_manager.hpp"
12 | #include "texture_manager.hpp"
13 |
14 | // TODO Rename back to PHBank
15 | namespace PHBanku
16 | {
17 | extern SaveManager* save;
18 | extern DataManager* data;
19 | extern FontManager* font;
20 | extern TextureManager* texture;
21 | }
22 |
23 | #endif // PHBANK_HPP
24 |
--------------------------------------------------------------------------------
/include/pkdir.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | /**
3 | * @file pkdir.h
4 | * @brief Constants of pkbrew.
5 | */
6 | #ifndef PKDIR_H
7 | #define PKDIR_H
8 |
9 | /**
10 | * @brief Brew files.
11 | */
12 | #define SAVE_FILE "main"
13 | #define BANK_FILE "bank"
14 |
15 | /**
16 | * @brief Devices.
17 | */
18 | #define ROOT "/"
19 | #define SDMC "sdmc:/"
20 | #define ROMFS "romfs:/"
21 | #define SAVE "pksave:/"
22 |
23 | /**
24 | * @brief Shared folders.
25 | */
26 | #define BASE_FOLDER "pk/"
27 | #define BACKUP_FOLDER "pk/backup/"
28 | #define DATA_FOLDER "pk/data/"
29 | #define ROMFS_FOLDER "pk/romfs/"
30 |
31 | /**
32 | * @brief Brew folders.
33 | */
34 | #define BANK_FOLDER "pk/bank/"
35 |
36 | #endif // PKDIR_H
37 |
--------------------------------------------------------------------------------
/include/pokedex.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 | /**
3 | * @file pokedex.hpp
4 | */
5 | #ifndef POKEDEX_HPP
6 | #define POKEDEX_HPP
7 |
8 | #include "save.hpp"
9 |
10 | namespace Pokedex
11 | {
12 | /**
13 | * @brief Registers a Pokémon into a Pokédex.
14 | * @param version The version of the game.
15 | * @param sav The save buffer of the Pokédex.
16 | * @param pkm The Pokémon to register.
17 | */
18 | void importToGame(GameVersion version, savebuffer_t sav, pkm_s* pkm);
19 | }
20 |
21 | #endif // POKEDEX_HPP
22 |
--------------------------------------------------------------------------------
/include/pokemon.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 | /**
3 | * @file pokemon.hpp
4 | */
5 | #ifndef POKEMON_HPP
6 | #define POKEMON_HPP
7 |
8 | #include "save.hpp"
9 |
10 | namespace Stat
11 | {
12 | typedef enum stat_e
13 | {
14 | HP = 0,
15 | ATK = 1,
16 | DEF = 2,
17 | SPE = 3,
18 | SPA = 4,
19 | SPD = 5
20 | } stat_e;
21 | }
22 | typedef Stat::stat_e stat_e;
23 |
24 | namespace Pokemon
25 | {
26 | /* Checksum */
27 | void computeChecksum(pkm_s* pkm);
28 |
29 | /* Quicker */
30 | u16 PSV(pkm_s* pkm);
31 | u16 TSV(u16 _TID, u16 _SID);
32 | u16 TSV(pkm_s* pkm);
33 | bool isShiny(pkm_s* pkm, u16 _TID, u16 _SID);
34 | bool isShiny(pkm_s* pkm);
35 | bool isInfected(pkm_s* pkm);
36 | bool isCured(pkm_s* pkm);
37 | bool isKalosBorn(pkm_s* pkm);
38 | bool isGen6Born(pkm_s* pkm);
39 | bool isGen5Born(pkm_s* pkm);
40 | bool isGen4Born(pkm_s* pkm);
41 | bool isGen3Born(pkm_s* pkm);
42 | bool generation(pkm_s* pkm);
43 |
44 | u8 level(pkm_s* pkm);
45 | u16 stat(u16 species, u8 IV, u8 EV, u8 nature, u8 level, u8 stat, u8 form);
46 | u16 HP(pkm_s* pkm);
47 | u16 ATK(pkm_s* pkm);
48 | u16 DEF(pkm_s* pkm);
49 | u16 SPA(pkm_s* pkm);
50 | u16 SPD(pkm_s* pkm);
51 | u16 SPE(pkm_s* pkm);
52 | u16 HP(pkm_s* pkm, u8 level);
53 | u16 ATK(pkm_s* pkm, u8 level);
54 | u16 DEF(pkm_s* pkm, u8 level);
55 | u16 SPA(pkm_s* pkm, u8 level);
56 | u16 SPD(pkm_s* pkm, u8 level);
57 | u16 SPE(pkm_s* pkm, u8 level);
58 | u8 HPType(pkm_s* pkm);
59 |
60 |
61 | // Region A
62 | u32 encryptionKey(pkm_s* pkm);
63 | u16 sanity(pkm_s* pkm);
64 | u16 checksum(pkm_s* pkm);
65 | u16 speciesID(pkm_s* pkm);
66 | u16 itemID(pkm_s* pkm);
67 | u16 TID(pkm_s* pkm);
68 | u16 SID(pkm_s* pkm);
69 | u32 EXP(pkm_s* pkm);
70 | u8 ability(pkm_s* pkm);
71 | u8 abilityNumber(pkm_s* pkm);
72 | u8 trainingBagHits(pkm_s* pkm);
73 | u8 triningBag(pkm_s* pkm);
74 | u32 PID(pkm_s* pkm);
75 | u8 nature(pkm_s* pkm);
76 | bool fatefulEncounter(pkm_s* pkm);
77 | u8 gender(pkm_s* pkm);
78 | u8 formID(pkm_s* pkm);
79 | u8 EV_HP(pkm_s* pkm);
80 | u8 EV_ATK(pkm_s* pkm);
81 | u8 EV_DEF(pkm_s* pkm);
82 | u8 EV_SPE(pkm_s* pkm);
83 | u8 EV_SPA(pkm_s* pkm);
84 | u8 EV_SPD(pkm_s* pkm);
85 | u8 CNT_Cool(pkm_s* pkm);
86 | u8 CNT_Beauty(pkm_s* pkm);
87 | u8 CNT_Cute(pkm_s* pkm);
88 | u8 CNT_Smart(pkm_s* pkm);
89 | u8 CNT_Tough(pkm_s* pkm);
90 | u8 CNT_Sheen(pkm_s* pkm);
91 | bool circle(pkm_s* pkm);
92 | bool triangle(pkm_s* pkm);
93 | bool square(pkm_s* pkm);
94 | bool heart(pkm_s* pkm);
95 | bool star(pkm_s* pkm);
96 | bool diamond(pkm_s* pkm);
97 | u8 PKRS_days(pkm_s* pkm);
98 | u8 PKRS_strain(pkm_s* pkm);
99 | bool unused0(pkm_s* pkm);
100 | bool unused1(pkm_s* pkm);
101 | bool ST1_SPA(pkm_s* pkm);
102 | bool ST1_HP(pkm_s* pkm);
103 | bool ST1_ATK(pkm_s* pkm);
104 | bool ST1_SPD(pkm_s* pkm);
105 | bool ST1_SPE(pkm_s* pkm);
106 | bool ST1_DEF(pkm_s* pkm);
107 | bool ST2_SPA(pkm_s* pkm);
108 | bool ST2_HP(pkm_s* pkm);
109 | bool ST2_ATK(pkm_s* pkm);
110 | bool ST2_SPD(pkm_s* pkm);
111 | bool ST2_SPE(pkm_s* pkm);
112 | bool ST2_DEF(pkm_s* pkm);
113 | bool ST3_SPA(pkm_s* pkm);
114 | bool ST3_HP(pkm_s* pkm);
115 | bool ST3_ATK(pkm_s* pkm);
116 | bool ST3_SPD(pkm_s* pkm);
117 | bool ST3_SPE(pkm_s* pkm);
118 | bool ST3_DEF(pkm_s* pkm);
119 | bool ST4_1(pkm_s* pkm);
120 | bool ST5_1(pkm_s* pkm);
121 | bool ST5_2(pkm_s* pkm);
122 | bool ST5_3(pkm_s* pkm);
123 | bool ST5_4(pkm_s* pkm);
124 | bool ST6_1(pkm_s* pkm);
125 | bool ST6_2(pkm_s* pkm);
126 | bool ST6_3(pkm_s* pkm);
127 | bool ST7_1(pkm_s* pkm);
128 | bool ST7_2(pkm_s* pkm);
129 | bool ST7_3(pkm_s* pkm);
130 | bool ST8_1(pkm_s* pkm);
131 | bool RIB0_0(pkm_s* pkm);
132 | bool RIB0_1(pkm_s* pkm);
133 | bool RIB0_2(pkm_s* pkm);
134 | bool RIB0_3(pkm_s* pkm);
135 | bool RIB0_4(pkm_s* pkm);
136 | bool RIB0_5(pkm_s* pkm);
137 | bool RIB0_6(pkm_s* pkm);
138 | bool RIB0_7(pkm_s* pkm);
139 | bool RIB1_0(pkm_s* pkm);
140 | bool RIB1_1(pkm_s* pkm);
141 | bool RIB1_2(pkm_s* pkm);
142 | bool RIB1_3(pkm_s* pkm);
143 | bool RIB1_4(pkm_s* pkm);
144 | bool RIB1_5(pkm_s* pkm);
145 | bool RIB1_6(pkm_s* pkm);
146 | bool RIB1_7(pkm_s* pkm);
147 | bool RIB2_0(pkm_s* pkm);
148 | bool RIB2_1(pkm_s* pkm);
149 | bool RIB2_2(pkm_s* pkm);
150 | bool RIB2_3(pkm_s* pkm);
151 | bool RIB2_4(pkm_s* pkm);
152 | bool RIB2_5(pkm_s* pkm);
153 | bool RIB2_6(pkm_s* pkm);
154 | bool RIB2_7(pkm_s* pkm);
155 | bool RIB3_0(pkm_s* pkm);
156 | bool RIB3_1(pkm_s* pkm);
157 | bool RIB3_2(pkm_s* pkm);
158 | bool RIB3_3(pkm_s* pkm);
159 | bool RIB3_4(pkm_s* pkm);
160 | bool RIB3_5(pkm_s* pkm);
161 | bool RIB3_6(pkm_s* pkm);
162 | bool RIB3_7(pkm_s* pkm);
163 | bool RIB4_0(pkm_s* pkm);
164 | bool RIB4_1(pkm_s* pkm);
165 | bool RIB4_2(pkm_s* pkm);
166 | bool RIB4_3(pkm_s* pkm);
167 | bool RIB4_4(pkm_s* pkm);
168 | bool RIB4_5(pkm_s* pkm);
169 | bool RIB4_6(pkm_s* pkm);
170 | bool RIB4_7(pkm_s* pkm);
171 | bool RIB5_0(pkm_s* pkm);
172 | bool RIB5_1(pkm_s* pkm);
173 | bool RIB5_2(pkm_s* pkm);
174 | bool RIB5_3(pkm_s* pkm);
175 | bool RIB5_4(pkm_s* pkm);
176 | bool RIB5_5(pkm_s* pkm);
177 | bool RIB5_6(pkm_s* pkm);
178 | bool RIB5_7(pkm_s* pkm);
179 | u8 _0x36(pkm_s* pkm);
180 | u8 _0x37(pkm_s* pkm);
181 | u8 contestCount(pkm_s* pkm);
182 | u8 battleCount(pkm_s* pkm);
183 | bool dist1(pkm_s* pkm);
184 | bool dist2(pkm_s* pkm);
185 | bool dist3(pkm_s* pkm);
186 | bool dist4(pkm_s* pkm);
187 | bool dist5(pkm_s* pkm);
188 | bool dist6(pkm_s* pkm);
189 | bool dist7(pkm_s* pkm);
190 | bool dist8(pkm_s* pkm);
191 | u8 _0x3B(pkm_s* pkm);
192 | u8 _0x3C(pkm_s* pkm);
193 | u8 _0x3D(pkm_s* pkm);
194 | u8 _0x3E(pkm_s* pkm);
195 | u8 _0x3F(pkm_s* pkm);
196 |
197 | // Region B
198 | u16* NK_name(pkm_s* pkm);
199 | u16 move1(pkm_s* pkm);
200 | u16 move2(pkm_s* pkm);
201 | u16 move3(pkm_s* pkm);
202 | u16 move4(pkm_s* pkm);
203 | u8 move1PP(pkm_s* pkm);
204 | u8 move2PP(pkm_s* pkm);
205 | u8 move3PP(pkm_s* pkm);
206 | u8 move4PP(pkm_s* pkm);
207 | u8 move1PPPlus(pkm_s* pkm);
208 | u8 move2PPPlus(pkm_s* pkm);
209 | u8 move3PPPlus(pkm_s* pkm);
210 | u8 move4PPPlus(pkm_s* pkm);
211 | u16 relearnMove1(pkm_s* pkm);
212 | u16 relearnMove2(pkm_s* pkm);
213 | u16 relearnMove3(pkm_s* pkm);
214 | u16 relearnMove4(pkm_s* pkm);
215 | bool secretSuperTraining(pkm_s* pkm);
216 | u8 _0x73(pkm_s* pkm);
217 | u8 IV_HP(pkm_s* pkm);
218 | u8 IV_ATK(pkm_s* pkm);
219 | u8 IV_DEF(pkm_s* pkm);
220 | u8 IV_SPE(pkm_s* pkm);
221 | u8 IV_SPA(pkm_s* pkm);
222 | u8 IV_SPD(pkm_s* pkm);
223 | bool isEgg(pkm_s* pkm);
224 | bool isNicknamed(pkm_s* pkm);
225 |
226 | // Region C
227 | u16* HT_name(pkm_s* pkm);
228 | u8 HT_gender(pkm_s* pkm);
229 | u8 currentHandler(pkm_s* pkm);
230 | u8 geo1Region(pkm_s* pkm);
231 | u8 geo1Country(pkm_s* pkm);
232 | u8 geo2Region(pkm_s* pkm);
233 | u8 geo2Country(pkm_s* pkm);
234 | u8 geo3Region(pkm_s* pkm);
235 | u8 geo3Country(pkm_s* pkm);
236 | u8 geo4Region(pkm_s* pkm);
237 | u8 geo4Country(pkm_s* pkm);
238 | u8 geo5Region(pkm_s* pkm);
239 | u8 geo5Country(pkm_s* pkm);
240 | u8 _0x9E(pkm_s* pkm);
241 | u8 _0x9F(pkm_s* pkm);
242 | u8 _0xA0(pkm_s* pkm);
243 | u8 _0xA1(pkm_s* pkm);
244 | u8 HT_friendship(pkm_s* pkm);
245 | u8 HT_affection(pkm_s* pkm);
246 | u8 HT_intensity(pkm_s* pkm);
247 | u8 HT_memory(pkm_s* pkm);
248 | u8 HT_feeling(pkm_s* pkm);
249 | u8 _0xA7(pkm_s* pkm);
250 | u16 HT_textVar(pkm_s* pkm);
251 | u8 _0xAA(pkm_s* pkm);
252 | u8 _0xAB(pkm_s* pkm);
253 | u8 _0xAC(pkm_s* pkm);
254 | u8 _0xAD(pkm_s* pkm);
255 | u8 fullness(pkm_s* pkm);
256 | u8 enjoyment(pkm_s* pkm);
257 |
258 | // Region D
259 | u16* OT_name(pkm_s* pkm);
260 | u8 OT_friendship(pkm_s* pkm);
261 | u8 OT_affection(pkm_s* pkm);
262 | u8 OT_intensity(pkm_s* pkm);
263 | u8 OT_memory(pkm_s* pkm);
264 | u16 OT_textVar(pkm_s* pkm);
265 | u8 OT_feeling(pkm_s* pkm);
266 | u8 eggYear(pkm_s* pkm);
267 | u8 eggMonth(pkm_s* pkm);
268 | u8 eggDay(pkm_s* pkm);
269 | u8 metYear(pkm_s* pkm);
270 | u8 metMonth(pkm_s* pkm);
271 | u8 metDay(pkm_s* pkm);
272 | u8 _0xD7(pkm_s* pkm);
273 | u16 eggLocation(pkm_s* pkm);
274 | u16 metLocation(pkm_s* pkm);
275 | u8 ball(pkm_s* pkm);
276 | u8 metLevel(pkm_s* pkm);
277 | u8 OT_gender(pkm_s* pkm);
278 | u8 encounterType(pkm_s* pkm);
279 | u8 version(pkm_s* pkm);
280 | u8 country(pkm_s* pkm);
281 | u8 region(pkm_s* pkm);
282 | u8 consoleRegion(pkm_s* pkm);
283 | u8 language(pkm_s* pkm);
284 |
285 | // Battle stats
286 | u8 statLevel(pkm_s* pkm);
287 | u8 statCurrentHP(pkm_s* pkm);
288 | u8 statMaxHP(pkm_s* pkm);
289 | u8 statATK(pkm_s* pkm);
290 | u8 statDEF(pkm_s* pkm);
291 | u8 statSPE(pkm_s* pkm);
292 | u8 statSPA(pkm_s* pkm);
293 | u8 statSPD(pkm_s* pkm);
294 |
295 | /* Abstract values */
296 | u8 markings(pkm_s* pkm);
297 | u8 PKRS(pkm_s* pkm);
298 | u8 ST1(pkm_s* pkm);
299 | u8 ST2(pkm_s* pkm);
300 | u8 ST3(pkm_s* pkm);
301 | u8 ST4(pkm_s* pkm);
302 | u8 RIB0(pkm_s* pkm);
303 | u8 RIB1(pkm_s* pkm);
304 | u8 RIB2(pkm_s* pkm);
305 | u8 RIB3(pkm_s* pkm);
306 | u8 RIB4(pkm_s* pkm);
307 | u8 RIB5(pkm_s* pkm);
308 | u8 dist(pkm_s* pkm);
309 | u32 IV32(pkm_s* pkm);
310 |
311 |
312 | // Region A
313 | void encryptionKey(pkm_s* pkm, u32 v);
314 | void sanity(pkm_s* pkm, u16 v);
315 | void checksum(pkm_s* pkm, u16 v);
316 | void speciesID(pkm_s* pkm, u16 v);
317 | void itemID(pkm_s* pkm, u16 v);
318 | void TID(pkm_s* pkm, u16 v);
319 | void SID(pkm_s* pkm, u16 v);
320 | void EXP(pkm_s* pkm, u32 v);
321 | void ability(pkm_s* pkm, u8 v);
322 | void abilityNumber(pkm_s* pkm, u8 v);
323 | void trainingBagHits(pkm_s* pkm, u8 v);
324 | void triningBag(pkm_s* pkm, u8 v);
325 | void PID(pkm_s* pkm, u32 v);
326 | void nature(pkm_s* pkm, u8 v);
327 | void fatefulEncounter(pkm_s* pkm, bool v);
328 | void gender(pkm_s* pkm, u8 v);
329 | void formID(pkm_s* pkm, u8 v);
330 | void EV_HP(pkm_s* pkm, u8 v);
331 | void EV_ATK(pkm_s* pkm, u8 v);
332 | void EV_DEF(pkm_s* pkm, u8 v);
333 | void EV_SPE(pkm_s* pkm, u8 v);
334 | void EV_SPA(pkm_s* pkm, u8 v);
335 | void EV_SPD(pkm_s* pkm, u8 v);
336 | void CNT_Cool(pkm_s* pkm, u8 v);
337 | void CNT_Beauty(pkm_s* pkm, u8 v);
338 | void CNT_Cute(pkm_s* pkm, u8 v);
339 | void CNT_Smart(pkm_s* pkm, u8 v);
340 | void CNT_Tough(pkm_s* pkm, u8 v);
341 | void CNT_Sheen(pkm_s* pkm, u8 v);
342 | void circle(pkm_s* pkm, bool v);
343 | void triangle(pkm_s* pkm, bool v);
344 | void square(pkm_s* pkm, bool v);
345 | void heart(pkm_s* pkm, bool v);
346 | void star(pkm_s* pkm, bool v);
347 | void diamond(pkm_s* pkm, bool v);
348 | void PKRS_days(pkm_s* pkm, u8 v);
349 | void PKRS_strain(pkm_s* pkm, u8 v);
350 | void unused0(pkm_s* pkm, bool v);
351 | void unused1(pkm_s* pkm, bool v);
352 | void ST1_SPA(pkm_s* pkm, bool v);
353 | void ST1_HP(pkm_s* pkm, bool v);
354 | void ST1_ATK(pkm_s* pkm, bool v);
355 | void ST1_SPD(pkm_s* pkm, bool v);
356 | void ST1_SPE(pkm_s* pkm, bool v);
357 | void ST1_DEF(pkm_s* pkm, bool v);
358 | void ST2_SPA(pkm_s* pkm, bool v);
359 | void ST2_HP(pkm_s* pkm, bool v);
360 | void ST2_ATK(pkm_s* pkm, bool v);
361 | void ST2_SPD(pkm_s* pkm, bool v);
362 | void ST2_SPE(pkm_s* pkm, bool v);
363 | void ST2_DEF(pkm_s* pkm, bool v);
364 | void ST3_SPA(pkm_s* pkm, bool v);
365 | void ST3_HP(pkm_s* pkm, bool v);
366 | void ST3_ATK(pkm_s* pkm, bool v);
367 | void ST3_SPD(pkm_s* pkm, bool v);
368 | void ST3_SPE(pkm_s* pkm, bool v);
369 | void ST3_DEF(pkm_s* pkm, bool v);
370 | void ST4_1(pkm_s* pkm, bool v);
371 | void ST5_1(pkm_s* pkm, bool v);
372 | void ST5_2(pkm_s* pkm, bool v);
373 | void ST5_3(pkm_s* pkm, bool v);
374 | void ST5_4(pkm_s* pkm, bool v);
375 | void ST6_1(pkm_s* pkm, bool v);
376 | void ST6_2(pkm_s* pkm, bool v);
377 | void ST6_3(pkm_s* pkm, bool v);
378 | void ST7_1(pkm_s* pkm, bool v);
379 | void ST7_2(pkm_s* pkm, bool v);
380 | void ST7_3(pkm_s* pkm, bool v);
381 | void ST8_1(pkm_s* pkm, bool v);
382 | void RIB0_0(pkm_s* pkm, bool v);
383 | void RIB0_1(pkm_s* pkm, bool v);
384 | void RIB0_2(pkm_s* pkm, bool v);
385 | void RIB0_3(pkm_s* pkm, bool v);
386 | void RIB0_4(pkm_s* pkm, bool v);
387 | void RIB0_5(pkm_s* pkm, bool v);
388 | void RIB0_6(pkm_s* pkm, bool v);
389 | void RIB0_7(pkm_s* pkm, bool v);
390 | void RIB1_0(pkm_s* pkm, bool v);
391 | void RIB1_1(pkm_s* pkm, bool v);
392 | void RIB1_2(pkm_s* pkm, bool v);
393 | void RIB1_3(pkm_s* pkm, bool v);
394 | void RIB1_4(pkm_s* pkm, bool v);
395 | void RIB1_5(pkm_s* pkm, bool v);
396 | void RIB1_6(pkm_s* pkm, bool v);
397 | void RIB1_7(pkm_s* pkm, bool v);
398 | void RIB2_0(pkm_s* pkm, bool v);
399 | void RIB2_1(pkm_s* pkm, bool v);
400 | void RIB2_2(pkm_s* pkm, bool v);
401 | void RIB2_3(pkm_s* pkm, bool v);
402 | void RIB2_4(pkm_s* pkm, bool v);
403 | void RIB2_5(pkm_s* pkm, bool v);
404 | void RIB2_6(pkm_s* pkm, bool v);
405 | void RIB2_7(pkm_s* pkm, bool v);
406 | void RIB3_0(pkm_s* pkm, bool v);
407 | void RIB3_1(pkm_s* pkm, bool v);
408 | void RIB3_2(pkm_s* pkm, bool v);
409 | void RIB3_3(pkm_s* pkm, bool v);
410 | void RIB3_4(pkm_s* pkm, bool v);
411 | void RIB3_5(pkm_s* pkm, bool v);
412 | void RIB3_6(pkm_s* pkm, bool v);
413 | void RIB3_7(pkm_s* pkm, bool v);
414 | void RIB4_0(pkm_s* pkm, bool v);
415 | void RIB4_1(pkm_s* pkm, bool v);
416 | void RIB4_2(pkm_s* pkm, bool v);
417 | void RIB4_3(pkm_s* pkm, bool v);
418 | void RIB4_4(pkm_s* pkm, bool v);
419 | void RIB4_5(pkm_s* pkm, bool v);
420 | void RIB4_6(pkm_s* pkm, bool v);
421 | void RIB4_7(pkm_s* pkm, bool v);
422 | void RIB5_0(pkm_s* pkm, bool v);
423 | void RIB5_1(pkm_s* pkm, bool v);
424 | void RIB5_2(pkm_s* pkm, bool v);
425 | void RIB5_3(pkm_s* pkm, bool v);
426 | void RIB5_4(pkm_s* pkm, bool v);
427 | void RIB5_5(pkm_s* pkm, bool v);
428 | void RIB5_6(pkm_s* pkm, bool v);
429 | void RIB5_7(pkm_s* pkm, bool v);
430 | void _0x36(pkm_s* pkm, u8 v);
431 | void _0x37(pkm_s* pkm, u8 v);
432 | void contestCount(pkm_s* pkm, u8 v);
433 | void battleCount(pkm_s* pkm, u8 v);
434 | void dist1(pkm_s* pkm, bool v);
435 | void dist2(pkm_s* pkm, bool v);
436 | void dist3(pkm_s* pkm, bool v);
437 | void dist4(pkm_s* pkm, bool v);
438 | void dist5(pkm_s* pkm, bool v);
439 | void dist6(pkm_s* pkm, bool v);
440 | void dist7(pkm_s* pkm, bool v);
441 | void dist8(pkm_s* pkm, bool v);
442 | void _0x3B(pkm_s* pkm, u8 v);
443 | void _0x3C(pkm_s* pkm, u8 v);
444 | void _0x3D(pkm_s* pkm, u8 v);
445 | void _0x3E(pkm_s* pkm, u8 v);
446 | void _0x3F(pkm_s* pkm, u8 v);
447 |
448 | // Region B
449 | void NK_name(pkm_s* pkm, u16* v);
450 | void move1(pkm_s* pkm, u16 v);
451 | void move2(pkm_s* pkm, u16 v);
452 | void move3(pkm_s* pkm, u16 v);
453 | void move4(pkm_s* pkm, u16 v);
454 | void move1PP(pkm_s* pkm, u8 v);
455 | void move2PP(pkm_s* pkm, u8 v);
456 | void move3PP(pkm_s* pkm, u8 v);
457 | void move4PP(pkm_s* pkm, u8 v);
458 | void move1PPPlus(pkm_s* pkm, u8 v);
459 | void move2PPPlus(pkm_s* pkm, u8 v);
460 | void move3PPPlus(pkm_s* pkm, u8 v);
461 | void move4PPPlus(pkm_s* pkm, u8 v);
462 | void relearnMove1(pkm_s* pkm, u16 v);
463 | void relearnMove2(pkm_s* pkm, u16 v);
464 | void relearnMove3(pkm_s* pkm, u16 v);
465 | void relearnMove4(pkm_s* pkm, u16 v);
466 | void secretSuperTraining(pkm_s* pkm, bool v);
467 | void _0x73(pkm_s* pkm, u8 v);
468 | void IV_HP(pkm_s* pkm, u8 v);
469 | void IV_ATK(pkm_s* pkm, u8 v);
470 | void IV_DEF(pkm_s* pkm, u8 v);
471 | void IV_SPE(pkm_s* pkm, u8 v);
472 | void IV_SPA(pkm_s* pkm, u8 v);
473 | void IV_SPD(pkm_s* pkm, u8 v);
474 | void isEgg(pkm_s* pkm, bool v);
475 | void isNicknamed(pkm_s* pkm, bool v);
476 |
477 | // Region C
478 | void HT_name(pkm_s* pkm, u16* v);
479 | void HT_gender(pkm_s* pkm, u8 v);
480 | void currentHandler(pkm_s* pkm, u8 v);
481 | void geo1Region(pkm_s* pkm, u8 v);
482 | void geo1Country(pkm_s* pkm, u8 v);
483 | void geo2Region(pkm_s* pkm, u8 v);
484 | void geo2Country(pkm_s* pkm, u8 v);
485 | void geo3Region(pkm_s* pkm, u8 v);
486 | void geo3Country(pkm_s* pkm, u8 v);
487 | void geo4Region(pkm_s* pkm, u8 v);
488 | void geo4Country(pkm_s* pkm, u8 v);
489 | void geo5Region(pkm_s* pkm, u8 v);
490 | void geo5Country(pkm_s* pkm, u8 v);
491 | void _0x9E(pkm_s* pkm, u8 v);
492 | void _0x9F(pkm_s* pkm, u8 v);
493 | void _0xA0(pkm_s* pkm, u8 v);
494 | void _0xA1(pkm_s* pkm, u8 v);
495 | void HT_friendship(pkm_s* pkm, u8 v);
496 | void HT_affection(pkm_s* pkm, u8 v);
497 | void HT_intensity(pkm_s* pkm, u8 v);
498 | void HT_memory(pkm_s* pkm, u8 v);
499 | void HT_feeling(pkm_s* pkm, u8 v);
500 | void _0xA7(pkm_s* pkm, u8 v);
501 | void HT_textVar(pkm_s* pkm, u16 v);
502 | void _0xAA(pkm_s* pkm, u8 v);
503 | void _0xAB(pkm_s* pkm, u8 v);
504 | void _0xAC(pkm_s* pkm, u8 v);
505 | void _0xAD(pkm_s* pkm, u8 v);
506 | void fullness(pkm_s* pkm, u8 v);
507 | void enjoyment(pkm_s* pkm, u8 v);
508 |
509 | // Region D
510 | void OT_name(pkm_s* pkm, u16* v);
511 | void OT_friendship(pkm_s* pkm, u8 v);
512 | void OT_affection(pkm_s* pkm, u8 v);
513 | void OT_intensity(pkm_s* pkm, u8 v);
514 | void OT_memory(pkm_s* pkm, u8 v);
515 | void OT_textVar(pkm_s* pkm, u16 v);
516 | void OT_feeling(pkm_s* pkm, u8 v);
517 | void eggYear(pkm_s* pkm, u8 v);
518 | void eggMonth(pkm_s* pkm, u8 v);
519 | void eggDay(pkm_s* pkm, u8 v);
520 | void metYear(pkm_s* pkm, u8 v);
521 | void metMonth(pkm_s* pkm, u8 v);
522 | void metDay(pkm_s* pkm, u8 v);
523 | void _0xD7(pkm_s* pkm, u8 v);
524 | void eggLocation(pkm_s* pkm, u16 v);
525 | void metLocation(pkm_s* pkm, u16 v);
526 | void ball(pkm_s* pkm, u8 v);
527 | void metLevel(pkm_s* pkm, u8 v);
528 | void OT_gender(pkm_s* pkm, u8 v);
529 | void encounterType(pkm_s* pkm, u8 v);
530 | void version(pkm_s* pkm, u8 v);
531 | void country(pkm_s* pkm, u8 v);
532 | void region(pkm_s* pkm, u8 v);
533 | void consoleRegion(pkm_s* pkm, u8 v);
534 | void language(pkm_s* pkm, u8 v);
535 |
536 | // Battle stats
537 | void statLevel(pkm_s* pkm, u8 v);
538 | void statCurrentHP(pkm_s* pkm, u8 v);
539 | void statMaxHP(pkm_s* pkm, u8 v);
540 | void statATK(pkm_s* pkm, u8 v);
541 | void statDEF(pkm_s* pkm, u8 v);
542 | void statSPE(pkm_s* pkm, u8 v);
543 | void statSPA(pkm_s* pkm, u8 v);
544 | void statSPD(pkm_s* pkm, u8 v);
545 |
546 | /* Abstract values */
547 | void markings(pkm_s* pkm, u8 v);
548 | void PKRS(pkm_s* pkm, u8 v);
549 | void ST1(pkm_s* pkm, u8 v);
550 | void ST2(pkm_s* pkm, u8 v);
551 | void ST3(pkm_s* pkm, u8 v);
552 | void ST4(pkm_s* pkm, u8 v);
553 | void RIB0(pkm_s* pkm, u8 v);
554 | void RIB1(pkm_s* pkm, u8 v);
555 | void RIB2(pkm_s* pkm, u8 v);
556 | void RIB3(pkm_s* pkm, u8 v);
557 | void RIB4(pkm_s* pkm, u8 v);
558 | void RIB5(pkm_s* pkm, u8 v);
559 | void dist(pkm_s* pkm, u8 v);
560 | void IV32(pkm_s* pkm, u32 v);
561 | };
562 |
563 | #endif // POKEMON_HPP
564 |
--------------------------------------------------------------------------------
/include/save.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 | /**
3 | * @file save.hpp
4 | */
5 | #ifndef SAVE_HPP
6 | #define SAVE_HPP
7 |
8 | #include <3ds/types.h>
9 |
10 | #define BOX_ROW_PKM_COUNT (5)
11 | #define BOX_COL_PKM_COUNT (6)
12 | #define BOX_PKM_COUNT (BOX_ROW_PKM_COUNT * BOX_COL_PKM_COUNT)
13 | #define PKM_COUNT (721)
14 | #define PC_BOX_COUNT (31)
15 | #define BK_BOX_COUNT (100)
16 |
17 | #define PKM_SIZE (0xE8) // 232
18 | #define BOX_SIZE (PKM_SIZE * BOX_PKM_COUNT)
19 |
20 | #define SAVEDATA_SIZE (0x76000)
21 | #define BANKDATA_SIZE (0xAEA00)
22 | #define EK6_SIZE PKM_SIZE
23 | #define PK6_SIZE PKM_SIZE
24 |
25 | typedef u8 ek6_t; ///< Encrypted Pokémon Gen6 type.
26 | typedef u8 pk6_t; ///< Pokémon Gen6 type.
27 |
28 | typedef u8 savebuffer_t[SAVEDATA_SIZE]; ///< Save buffer type.
29 | typedef u8 bankbuffer_t[BANKDATA_SIZE]; ///< Bank buffer type.
30 |
31 | struct pkm_s
32 | {
33 | ek6_t* ek6 = NULL; ///< Pointer to MainBuffer. (don't free)
34 | pk6_t* pk6 = NULL; ///< Pointer to OwnBuffer. (do free)
35 | bool fromBank : 1; ///< If the Pokémon was in the bank.
36 | bool checked : 1; ///< If the Pokémon has been checked for multi-select.
37 | bool moved : 1; ///< If the Pokémon has moved.
38 | bool modified : 1; ///< If the Pokémon was modified.
39 | bool isEggy : 1; ///< If the Pokémon is an egg.
40 | bool isShiny : 1; ///< If the Pokémon is shiny.
41 | unsigned: 2;
42 |
43 | u16 speciesID; ///< The species of the Pokémon.
44 | u16 itemID; ///< The held item of the Pokémon.
45 | u8 formID; ///< The form of the Pokémon.
46 | u8 gender; ///< The gender of the Pokémon.
47 |
48 | // TODO: Add recurrent attributes!
49 | };
50 |
51 | struct box_s
52 | {
53 | pkm_s slot[BOX_PKM_COUNT]; ///< The slots of the box.
54 | uint32_t title[0x11]; ///< The title of the box.
55 | u8 background; ///< The background id of the box.
56 | u8 number; ///< The number (id) of the box.
57 | u16 count; ///< The count of Pokémon (static).
58 | // TODO: Make that variable runtime dynamic!
59 | };
60 |
61 | struct pc_s
62 | {
63 | box_s box[PC_BOX_COUNT]; ///< Boxes
64 | u8 boxUnlocked; ///< Unlocked boxes
65 | };
66 |
67 | struct bk_s
68 | {
69 | box_s wbox; ///< Wonderbox
70 | box_s tbox; ///< Trashbox
71 | box_s box[BK_BOX_COUNT]; ///< Boxes
72 | u8 boxUnlocked; ///< Unlocked boxes
73 | bool wboxUnlocked; ///< Wonder box unlocked
74 | };
75 |
76 | struct savedata_s
77 | {
78 | pc_s pc;
79 | u16 TID, SID, TSV; ///< The ID of the trainer
80 | u8 GEORegion; ///< The region of the trainer
81 | u8 GEOCountry; ///< The country of the trainer
82 | u8 OTGender; ///< The gender of the trainer
83 | u16 OT_name[0xD]; ///< The name of the trainer /!\ MODIFIED
84 | uint32_t OTName[0xD];
85 | };
86 |
87 | struct bankdata_s
88 | {
89 | u32 magic;
90 | u32 version;
91 | bk_s bk;
92 | };
93 |
94 | namespace Game
95 | {
96 | enum gameVersion_e
97 | {
98 | None = 0,
99 | X = 1 << 0, // 24
100 | Y = 1 << 1, // 25
101 | XY = X | Y,
102 | OR = 1 << 2, // 26
103 | AS = 1 << 3, // 27
104 | ORAS = OR | AS,
105 | };
106 |
107 | inline bool is(gameVersion_e g1, gameVersion_e g2) { return (g1 & g2); }
108 | };
109 |
110 | typedef Game::gameVersion_e GameVersion;
111 |
112 | typedef u32 saveConst_t;
113 |
114 | namespace SaveConst
115 | {
116 | const saveConst_t XY_size = 0x65600;
117 | const saveConst_t XY_offsetPCLayout = 0x4400;
118 | const saveConst_t XY_offsetPCBackground = XY_offsetPCLayout + 0x41E;
119 | const saveConst_t XY_offsetPC = 0x22600;
120 | const saveConst_t XY_offsetTrainerCard = 0x14000;
121 | const saveConst_t XY_offsetDex = 0x15000; // 0x1A400 - 0x5400
122 |
123 | const saveConst_t ORAS_size = 0x76000;
124 | const saveConst_t ORAS_offsetPCLayout = 0x4400;
125 | const saveConst_t ORAS_offsetPCBackground = ORAS_offsetPCLayout + 0x41E;
126 | const saveConst_t ORAS_offsetPC = 0x33000;
127 | const saveConst_t ORAS_offsetTrainerCard = 0x14000;
128 | const saveConst_t ORAS_offsetDex = 0x15000; // 0x1A400 - 0x5400
129 |
130 | const saveConst_t BANK_size = 0xACA00;
131 | const saveConst_t BANK_offsetMagicNumber = 0x00;
132 | const saveConst_t BANK_offsetVersion = 0x04;
133 | const saveConst_t BANK_offsetOffsetBK = 0x20;
134 | const saveConst_t BANK_offsetOffsetBKLayout = 0x24;
135 | const saveConst_t BANK_offsetOffsetBKBackground = 0x28;
136 | const saveConst_t BANK_offsetOffsetWonderBox = 0x30;
137 | const saveConst_t BANK_offsetOffsetTrashBox = 0x34;
138 | }
139 |
140 | #endif // SAVE_HPP
141 |
--------------------------------------------------------------------------------
/include/save_manager.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 | /**
3 | * @file save_manager.hpp
4 | * @brief Save Manager
5 | */
6 | #ifndef SAVE_MANAGER_HPP
7 | #define SAVE_MANAGER_HPP
8 |
9 | #include "save.hpp"
10 |
11 | class SaveManager
12 | {
13 | public:
14 | GameVersion version;
15 |
16 | savebuffer_t savebuffer;
17 | bankbuffer_t bankbuffer;
18 | savedata_s savedata;
19 | bankdata_s bankdata;
20 | bool dev;
21 |
22 | public:
23 | /* PC Offsets */
24 | saveConst_t offsetTrainerCard;
25 | saveConst_t offsetPCLayout;
26 | saveConst_t offsetPCBackground;
27 | saveConst_t offsetPC;
28 |
29 | /* BK Offsets */
30 | saveConst_t offsetBK;
31 | saveConst_t offsetBKLayout;
32 | saveConst_t offsetBKBackground;
33 | saveConst_t offsetWonderBox;
34 | saveConst_t offsetTrashBox;
35 |
36 | /* Global const */
37 | saveConst_t sizeSave;
38 | saveConst_t sizeBank;
39 |
40 | public:
41 | SaveManager(void);
42 | ~SaveManager(void);
43 |
44 | Result load(void);
45 | Result save(void);
46 | Result backupFile(void);
47 |
48 | void setGame(u32 bytesRead);
49 | void setGameOffsets(void);
50 | void setBank(u32 bytesRead);
51 | void setBankOffsets(void);
52 |
53 | bool isPkmEmpty(pkm_s* pkm);
54 | bool isSlotEmpty(u16 boxId, u16 slotId, bool inBank);
55 | box_s* countBox(u16 boxId, bool inBank);
56 | box_s* getWBox(void);
57 | box_s* getTBox(void);
58 | box_s* getBox(u16 boxId, bool inBank);
59 | pkm_s* getWPkm(u16 slotId);
60 | pkm_s* getTPkm(u16 slotId);
61 | pkm_s* getPkm(u16 slotId, bool inBank);
62 | pkm_s* getPkm(u16 boxId, u16 slotId, bool inBank);
63 | bool movePkm(pkm_s* src, pkm_s* dst);
64 | bool movePkm(pkm_s* src, pkm_s* dst, bool srcBanked, bool dstBanked);
65 | bool pastePkm(pkm_s* src, pkm_s* dst);
66 | bool pastePkm(pkm_s* src, pkm_s* dst, bool srcBanked, bool dstBanked);
67 | void moveBox(u16 boxId_1, bool inBank_1, u16 boxId_2, bool inBank_2);
68 | bool filterPkm(pkm_s* pkm, bool toBank, bool fromBank);
69 |
70 | void addDex(pkm_s* pkm);
71 | void tradePkm(pkm_s* pkm);
72 | void tradePkmHT(pkm_s* pkm);
73 |
74 |
75 | void decryptEk6(pkm_s* pkm);
76 | void encryptPk6(pkm_s* pkm);
77 | void shufflePk6(pk6_t* pk6, u8 sv);
78 | void rewriteSaveCHK(void);
79 |
80 | u32 LCRNG(u32 seed);
81 | u32 CHKOffset(u32 i);
82 | u32 CHKLength(u32 i);
83 | u16 ccitt16(u8* data, u32 len);
84 |
85 | private:
86 |
87 | Result loadFile(void);
88 | Result saveFile(void);
89 |
90 | Result loadSaveFile(void);
91 | Result loadBankFile(void);
92 | Result saveSaveFile(void);
93 | Result saveBankFile(void);
94 | Result backupSaveFile(void);
95 | Result backupBankFile(void);
96 |
97 | // Load Data
98 | void loadData(void);
99 | void loadSaveData(void);
100 | void loadBankData(void);
101 | // Load Pokemon (pkm_s)
102 | // To <- From
103 | pkm_s* loadPkmPC(u16 boxId, u16 slotId);
104 | pkm_s* loadPkmBK(u16 boxId, u16 slotId);
105 | pkm_s* loadPkmWBK(u16 slotId);
106 | pkm_s* loadPkmTBK(u16 slotId);
107 | void loadEk6PC(pkm_s* pkm, u32 offsetSlot);
108 | void loadEk6BK(pkm_s* pkm, u32 offsetSlot);
109 | void loadEk6WBK(pkm_s* pkm, u32 offsetSlot);
110 | void loadEk6TBK(pkm_s* pkm, u32 offsetSlot);
111 | void loadPk6Ek6(pkm_s* pkm);
112 | void loadPkmPk6(pkm_s* pkm);
113 |
114 | // Save Data
115 | void saveData(void);
116 | void saveSaveData(void);
117 | void saveBankData(void);
118 | // Save Pokemon (pkm_s)
119 | // From -> To
120 | void savePkmPC(u16 boxId, u16 slotId);
121 | void savePkmBK(u16 boxId, u16 slotId);
122 | void saveEk6PC(pkm_s* pkm);
123 | void saveEk6BK(pkm_s* pkm);
124 | void savePk6Ek6(pkm_s* pkm);
125 | void savePkmPk6(pkm_s* pkm);
126 | };
127 |
128 | #endif // SAVE_MANAGER_HPP
129 |
--------------------------------------------------------------------------------
/include/smdh.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | /**
3 | * @file smdh.h
4 | */
5 | #ifndef SMDH_H
6 | #define SMDH_H
7 |
8 | #include <3ds/types.h>
9 |
10 | #define SMDH_HEADER_MAGIC (0x48444D53)
11 |
12 | typedef struct
13 | {
14 | u32 magic;
15 | u16 version;
16 | u16 reserved;
17 | } smdhHeader_s;
18 |
19 | typedef struct
20 | {
21 | u16 shortDescription[0x40];
22 | u16 longDescription[0x80];
23 | u16 publisher[0x40];
24 | } smdhTitle_s;
25 |
26 | typedef struct
27 | {
28 | u8 gameRatings[0x10];
29 | u32 regionLock;
30 | u8 matchMakerId[0xC];
31 | u32 flags;
32 | u16 eulaVersion;
33 | u16 reserved;
34 | u32 defaultFrame;
35 | u32 cecId;
36 | } smdhSettings_s;
37 |
38 | typedef struct
39 | {
40 | smdhHeader_s header;
41 | smdhTitle_s applicationTitles[16];
42 | smdhSettings_s settings;
43 | u8 reserved[0x8];
44 | u8 smallIconData[0x480];
45 | u16 bigIconData[0x900];
46 | } smdh_s;
47 |
48 | #endif // SMDH_H
49 |
--------------------------------------------------------------------------------
/include/text.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | /**
3 | * @file text.hpp
4 | */
5 | #ifndef TEXT_HPP
6 | #define TEXT_HPP
7 |
8 | #include
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | extern sftd_font* font;
15 | extern sftd_font* font_bold;
16 |
17 | void sftd_draw_text_pkm(const u16 x, const u16 y, const char* text, ...);
18 | void sftd_draw_text_white(const u16 x, const u16 y, const char* text, ...);
19 | void sftd_draw_text_black(const u16 x, const u16 y, const char* text, ...);
20 |
21 | void sftd_draw_wtext_pkm(uint16_t x, uint16_t y, const uint32_t* text);
22 | void sftd_draw_wtext_white(uint16_t x, uint16_t y, const uint32_t* text);
23 | void sftd_draw_wtext_black(uint16_t x, uint16_t y, const uint32_t* text);
24 | void sftd_draw_wtextf_pkm(uint16_t x, uint16_t y, const wchar_t* text, ...);
25 | void sftd_draw_wtextf_white(uint16_t x, uint16_t y, const wchar_t* text, ...);
26 | void sftd_draw_wtextf_black(uint16_t x, uint16_t y, const wchar_t* text, ...);
27 |
28 | #ifdef __cplusplus
29 | }
30 | #endif
31 |
32 | #endif // TEXT_HPP
33 |
--------------------------------------------------------------------------------
/include/texture_manager.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 | /**
3 | * @file texture_manager.hpp
4 | * @brief Texture Manager
5 | */
6 | #ifndef TEXTURE_MANAGER_HPP
7 | #define TEXTURE_MANAGER_HPP
8 |
9 | #include
10 |
11 | class TextureManager
12 | {
13 | public:
14 | sf2d_texture* ballLoadingScreen;
15 | sf2d_texture* pkmIcons; ///< The sprite sheet for Pokémon icons.
16 | sf2d_texture* pkmShinyIcons; ///< The sprite sheet for shiny Pokémon icons.
17 | sf2d_texture* pkmFormIcons; ///< The sprite sheet for Pokémon Form icons.
18 | sf2d_texture* pkmShinyFormIcons; ///< The sprite sheet for shiny Pokémon Form icons.
19 | sf2d_texture* itemIcons; ///< The sprite sheet for item icons.
20 | sf2d_texture* ballIcons; ///< The sprite sheet for ball icons.
21 | sf2d_texture* types; ///< The sprite sheet for lang types images.
22 | sf2d_texture* boxTiles; ///< The sheet for box sprites (cursor, button, etc).
23 | sf2d_texture* boxBackgrounds; ///< The backgrounds of the box.
24 | sf2d_texture* resumeBackground; ///< The resume background for top screen.
25 |
26 | public:
27 | TextureManager(void);
28 | ~TextureManager(void);
29 |
30 | Result load(void);
31 |
32 | void drawStaticLoadingScreen(void);
33 |
34 | private:
35 | bool loadTextures(void);
36 | void drawLoadingTopScreen();
37 | void drawLoadingBottomScreen();
38 | inline void drawLoadingPokeball(int x, int y);
39 | inline void drawLoadingGreatball(int x, int y);
40 | inline void drawLoadingUltraball(int x, int y);
41 | inline void drawLoadingBackball(int x, int y);
42 | inline void drawLoadingText(int rx, int ry);
43 | friend void _loadingScreen(void* arg);
44 | friend void _loadTextures(void* arg);
45 | };
46 |
47 | #endif // TEXTURE_MANAGER_HPP
48 |
--------------------------------------------------------------------------------
/include/ts.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | /**
3 | * @file am.h
4 | * @brief Title Selector Module for Pokémon titles
5 | */
6 | #ifndef TS_H
7 | #define TS_H
8 |
9 | #ifdef __cplusplus
10 | extern "C" {
11 | #endif
12 |
13 | #include "am.h"
14 |
15 | extern AM_TitleMediaEntry titleEntry;
16 |
17 | /**
18 | * @brief Starts the loop of the title selector.
19 | * @return Whether the title selector has selected a title.
20 | */
21 | bool TS_Loop(void);
22 |
23 | #ifdef __cplusplus
24 | }
25 | #endif
26 |
27 | #endif // TS_H
28 |
--------------------------------------------------------------------------------
/include/utils.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | /**
3 | * @file utils.h
4 | */
5 | #ifndef UTILS_H
6 | #define UTILS_H
7 |
8 | #ifdef __cplusplus
9 | extern "C" {
10 | #endif
11 |
12 | #include <3ds/types.h>
13 |
14 | /**
15 | * @brief Compares two u16 strings.
16 | * @param[in] str1 The first u16 string.
17 | * @param[in] str2 The second u16 string.
18 | * @return The char16 difference between the strings.
19 | */
20 | inline s32 str16cmp(const u16* str1, const u16* str2)
21 | {
22 | if (!str1 || !str2) return 0;
23 | u16 ii;
24 | for (ii = 0; str1[ii] && str2[ii] && str1[ii] == str2[ii]; ii++);
25 | return str1[ii] - str2[ii];
26 | }
27 |
28 | /**
29 | * @brief Compares two u16 strings.
30 | * @param[in] str1 The first u16 string.
31 | * @param[in] str2 The second u16 string.
32 | * @param max The max length of the strings.
33 | * @return The char16 difference between the strings.
34 | */
35 | inline s32 str16ncmp(const u16* str1, const u16* str2, s16 max)
36 | {
37 | if (!str1 || !str2) return 0;
38 | for (u16 ii = 0; ii < max; ii++)
39 | if (!str1[ii] || !str2[ii] || str1[ii] != str2[ii])
40 | return str1[ii] - str2[ii];
41 | return 0;
42 | }
43 |
44 | /**
45 | * @brief Replaces some character of a string.
46 | * @param[in/out] str The u16 string.
47 | * @param max The max length of the string.
48 | * @return The number of characters replaced.
49 | */
50 | inline u8 str16nfix(u16* str, s16 max)
51 | {
52 | if (!str) return 0;
53 | u8 i = 1;
54 | for (u16 ii = 0; str[ii] && ii < max; ii++)
55 | {
56 | if (str[ii] == 0xE08F) str[ii] = 0x2640; // Nidoran ♂
57 | else if (str[ii] == 0xE08E) str[ii] = 0x2642; // Nidoran ♀
58 | else if (str[ii] == 0x2019) str[ii] = 0x0027; // Farfetch'd
59 | else i--; i++;
60 | }
61 | return i-1;
62 | }
63 |
64 | /**
65 | * @brief Replaces some character of a string.
66 | * @param[in/out] str The u32 string.
67 | * @param max The max length of the string.
68 | * @return The number of characters replaced.
69 | */
70 | inline u8 str32nfix(u32* str, s16 max)
71 | {
72 | if (!str) return 0;
73 | u8 i = 1;
74 | for (u16 ii = 0; str[ii] && ii < max; ii++)
75 | {
76 | if (str[ii] == 0xE08F) str[ii] = 0x2640; // Nidoran ♂
77 | else if (str[ii] == 0xE08E) str[ii] = 0x2642; // Nidoran ♀
78 | else if (str[ii] == 0x2019) str[ii] = 0x0027; // Farfetch'd
79 | else i--; i++;
80 | }
81 | return i-1;
82 | }
83 |
84 | /**
85 | * @brief Gets the length of a u8 string.
86 | * @param[in] str The u8 string.
87 | * @param max The max length of the string.
88 | * @return The length of the string.
89 | */
90 | inline u16 str8nlen(const u8* str, s16 max)
91 | {
92 | if (!str) return 0;
93 | u16 i = 0;
94 | for (u16 ii = 0; ii < max && str[ii]; ii++)
95 | if ((str[ii] & 0xC0) ^ 0x80)
96 | i++;
97 | return i;
98 | }
99 |
100 | #ifdef __cplusplus
101 | }
102 | #endif
103 |
104 | #endif // UTILS_H
105 |
--------------------------------------------------------------------------------
/include/version.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | /**
3 | * @file version.h
4 | */
5 |
6 | /**
7 | * MAJOR VERSION (0-99)
8 | * MINOR VERSION (0-99)
9 | * PATCH VERSION (0-99)
10 | * KIND VERSION (0xA-0xF)
11 | * PATCH (0xA-0xF)
12 | *
13 | * e.g: 2.1.0-beta-a (020100BA)
14 | */
15 | #define VERSION 0x020101B0
16 |
--------------------------------------------------------------------------------
/include/viewer/box_viewer.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 | /**
3 | * @file box_viewer.hpp
4 | */
5 | #ifndef BOX_VIEWER_HPP
6 | #define BOX_VIEWER_HPP
7 |
8 | #include "viewer.hpp"
9 | #include "phbank.hpp"
10 | #include "save.hpp"
11 |
12 | /// Structure containing the data displayed on top screen
13 | struct vPkm_s
14 | {
15 | pkm_s* pkm = NULL;
16 | bool emptySlot : 1;
17 | bool isKalosBorn : 1;
18 | bool isInfected : 1;
19 | bool isCured : 1;
20 | unsigned : 4;
21 | bool circle : 1;
22 | bool triangle : 1;
23 | bool square : 1;
24 | bool heart : 1;
25 | bool star : 1;
26 | bool diamond : 1;
27 | unsigned : 2;
28 | uint32_t NKName[0xD];
29 | uint32_t OTName[0xD];
30 | uint32_t HTName[0xD];
31 | sf2d_texture* icon;
32 | const uint32_t* ability;
33 | const uint32_t* item;
34 | const uint32_t* moves[4];
35 | const uint32_t* nature;
36 | const uint32_t* species;
37 | const uint32_t* hpType;
38 | u16 PSV;
39 | u8 level;
40 | u16 stats[6];
41 | u16 ivs[6];
42 | u16 evs[6];
43 | u8 ball;
44 | u8 gen;
45 | };
46 |
47 | // TODO: Reformat like PHBankGB
48 | struct BoxSlot_s
49 | {
50 | bool inBank = false;
51 | s16 slot = 0;
52 | s16 inslot = 0;
53 | s16 box = 0;
54 | s16 row = 0;
55 | s16 col = 0;
56 | s16 rowCount = 0;
57 | s16 colCount = 0;
58 | };
59 |
60 | // TODO: Reformat like PHBankGB
61 | struct CursorBox_s
62 | {
63 | bool inBank = false;
64 | s16 slot = 0;
65 | s16 inslot = 0;
66 | s16 boxPC = 0;
67 | s16 boxBK = 0;
68 | s16* box = NULL;
69 | s16 row = 0;
70 | s16 col = 0;
71 | };
72 |
73 | struct HeldTick_s
74 | {
75 | u64 KEY_RIGHT = 0;
76 | u64 KEY_LEFT = 0;
77 | u64 KEY_UP = 0;
78 | u64 KEY_DOWN = 0;
79 | u64 KEY_R = 0;
80 | u64 KEY_L = 0;
81 | };
82 |
83 | enum class CursorType : u8
84 | {
85 | SingleSelect = 0,
86 | QuickSelect = 1,
87 | MultiSelect = 2,
88 | DevSelect = 3,
89 | };
90 |
91 | void computeSlot(CursorBox_s* cursorBox);
92 | void extractBoxSlot(CursorBox_s* cursorBox, BoxSlot_s* boxSlot);
93 | void injectBoxSlot(CursorBox_s* cursorBox, BoxSlot_s* boxSlot);
94 |
95 | class BoxViewer : public Viewer
96 | {
97 | public:
98 | BoxViewer(Viewer* parent = NULL);
99 | BoxViewer(ViewType vType, Viewer* parent = NULL);
100 | ~BoxViewer();
101 |
102 | Result initialize() override;
103 | Result drawTopScreen() override;
104 | Result drawBotScreen() override;
105 | Result updateControls(const u32& kDown = 0, const u32& kHeld = 0, const u32& kUp = 0, const touchPosition* touch = NULL) override;
106 |
107 | void selectViewBox(uint16_t boxId, bool inBank);
108 |
109 | private:
110 | SaveManager* save;
111 | DataManager* data;
112 | CursorBox_s cursorBox;
113 | CursorType cursorType = CursorType::SingleSelect;
114 | touchPosition touch;
115 | HeldTick_s heldTick;
116 | bool isPkmHeld = false; ///< Is a Pokémon held using the buttons?
117 | bool isPkmDragged = false; ///< Is a Pokémon dragged using the stylus?
118 | bool isPkmChecking = false; ///< Is there Pokémon being (un)checked?
119 | bool checkToggle; ///< How to toggle the checked Pokémon?
120 | BoxSlot_s sSlot;
121 | pkm_s* sPkm = NULL;
122 | pkm_s* sPkms[BOX_PKM_COUNT];
123 | bool sPkmBanked[BOX_PKM_COUNT];
124 | u8 sPkmCount;
125 | vPkm_s vPkm;
126 | box_s* vPCBox = NULL;
127 | box_s* vBKBox = NULL;
128 |
129 | float cursorPositionOffY = 0.0f;
130 | float cursorPositionMaxY = 8.0f;
131 | float cursorPositionShiftY = 0.5f;
132 | bool cursorPositionDirY = true;
133 |
134 | void drawBox(box_s* box, int16_t x, int16_t y, bool cursor);
135 | void drawPokemon(pkm_s* pkm, int16_t x, int16_t y, bool shadow);
136 | void drawPokemonScale(pkm_s* pkm, int16_t x, int16_t y, float scale);
137 | void drawViewPokemon(vPkm_s* vPkm, int16_t x, int16_t y);
138 | void drawCursorButton(int16_t x, int16_t y);
139 |
140 | bool isWonderBox(u16 boxId, bool inBank);
141 | bool isTrashBox(u16 boxId, bool inBank);
142 |
143 | void selectCursorType(CursorType cursorType);
144 | void switchCursorType();
145 | void selectViewBox();
146 | void selectViewPokemon();
147 | void selectMovePokemon();
148 | void selectMultiMovePokemon(bool check);
149 | void selectPastePokemon();
150 | void selectMultiPastePokemon(bool check);
151 | void cancelMovePokemon();
152 | void populateVPkmData(vPkm_s* vPkm, pkm_s* pkm);
153 | };
154 |
155 | #endif // BOX_VIEWER_HPP
156 |
--------------------------------------------------------------------------------
/include/viewer/savexit_viewer.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 | /**
3 | * @file savexit_viewer.hpp
4 | */
5 | #ifndef SAVEXIT_VIEWER_HPP
6 | #define SAVEXIT_VIEWER_HPP
7 |
8 | #include "viewer.hpp"
9 |
10 | class SavexitViewer : public Viewer
11 | {
12 | public:
13 | SavexitViewer(Viewer* parent = NULL);
14 | SavexitViewer(ViewType vType, Viewer* parent = NULL);
15 | ~SavexitViewer();
16 |
17 | Result initialize() override;
18 | Result drawTopScreen() override;
19 | Result drawBotScreen() override;
20 | Result updateControls(const u32& kDown = 0, const u32& kHeld = 0, const u32& kUp = 0, const touchPosition* touch = NULL) override;
21 | };
22 |
23 | #endif // SAVEXIT_VIEWER_HPP
24 |
--------------------------------------------------------------------------------
/include/viewer/ultra_box_viewer.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 | /**
3 | * @file ultra_box_viewer.hpp
4 | */
5 | #ifndef ULTRA_BOX_VIEWER_HPP
6 | #define ULTRA_BOX_VIEWER_HPP
7 |
8 | #include "viewer.hpp"
9 | #include "phbank.hpp"
10 | #include "save.hpp"
11 |
12 | struct CursorUBox_s
13 | {
14 | bool inBank = false;
15 | int16_t slot = 0;
16 | int16_t row = 0;
17 | int16_t col = 0;
18 | };
19 |
20 | void computeSlot(CursorUBox_s* cursorUBox);
21 |
22 | class UltraBoxViewer : public Viewer
23 | {
24 | public:
25 | UltraBoxViewer(Viewer* parent = NULL);
26 | UltraBoxViewer(ViewType vType, Viewer* parent = NULL);
27 | ~UltraBoxViewer();
28 |
29 | Result initialize() override;
30 | Result drawTopScreen() override;
31 | Result drawBotScreen() override;
32 | Result updateControls(const u32& kDown = 0, const u32& kHeld = 0, const u32& kUp = 0, const touchPosition* touch = NULL) override;
33 |
34 | bool selectViewBox(uint16_t boxID, bool inBank);
35 |
36 | protected:
37 | CursorUBox_s cursorUBox;
38 | touchPosition touch;
39 | touchPosition originalTouch;
40 | box_s* vBox = NULL;
41 | uint16_t boxCount;
42 | uint16_t rowCount;
43 | uint16_t colCount;
44 |
45 | int16_t marginBottom = 40;
46 | int16_t offsetTop = 0;
47 | int16_t offsetLeft = 0;
48 | int16_t originalOffsetTop = 0;
49 | int16_t originalOffsetLeft = 0;
50 |
51 | bool selectViewBox();
52 | bool selectMoveBox();
53 | int16_t currentColCount(int16_t row);
54 | ViewState closeViewer(bool save = false);
55 | };
56 |
57 | #endif // ULTRA_BOX_VIEWER_HPP
58 |
--------------------------------------------------------------------------------
/include/viewer/viewer.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 | /**
3 | * @file viewer.hpp
4 | */
5 | #ifndef VIEWER_HPP
6 | #define VIEWER_HPP
7 |
8 | #include <3ds.h>
9 | #include
10 |
11 | #define SUCCESS_STEP 0
12 | #define CHILD_STEP 1
13 | #define PARENT_STEP 2
14 |
15 | enum class ViewState : u8
16 | {
17 | Running = 0,
18 | Exiting = 1,
19 | Continuing = 2,
20 | Aborting = 3,
21 | Saving = 4,
22 | };
23 |
24 | enum class ViewType : u8
25 | {
26 | Regular = 0,
27 | Overlay = 1,
28 | };
29 |
30 | class Viewer
31 | {
32 | public:
33 | /*-- Viewer Destructor --*/
34 | virtual ~Viewer();
35 | /*-----------------------*/
36 |
37 | /*-- Viewer Methods --*/
38 | virtual Result initialize();
39 | virtual Result drawTopScreen();
40 | virtual Result drawBotScreen();
41 | virtual Result updateControls(const u32& kDown = 0, const u32& kHeld = 0, const u32& kUp = 0, const touchPosition* touch = NULL);
42 | /*--------------------*/
43 |
44 | /*-- Viewer Hierarchy --*/
45 | bool hasParent();
46 | bool hasChild();
47 | bool isChild();
48 | bool isParent();
49 | bool hasRegularChild();
50 | bool hasOverlayChild();
51 | /*----------------------*/
52 |
53 | /*-- Viewer Type --*/
54 | bool isRegular();
55 | bool isOverlay();
56 | virtual void setType(ViewType type);
57 | /*------------------*/
58 |
59 | /*-- Viewer State --*/
60 | virtual ViewState close();
61 | virtual ViewState state();
62 | virtual bool isRunning();
63 | virtual void setState(ViewState state);
64 | /*--------------------*/
65 |
66 | /*-- Utils --*/
67 | bool touchWithin(s16 px, s16 py, s16 x, s16 y, s16 w, s16 h);
68 | /*-----------*/
69 |
70 | /*-- Viewer Starter --*/
71 | static ViewState startMainLoop(Viewer* viewer);
72 | /*--------------------*/
73 |
74 | protected:
75 | /*-- Viewer Constructors --*/
76 | Viewer(Viewer* parent = NULL);
77 | Viewer(ViewType type, Viewer* parent = NULL);
78 | /*-------------------------*/
79 |
80 | /*-- Viewer Hierarchy --*/
81 | Viewer* parent = NULL;
82 | Viewer* child = NULL;
83 | /*----------------------*/
84 |
85 | /*-- Viewer Type --*/
86 | ViewType vType = ViewType::Regular;
87 | /*------------------*/
88 |
89 | /*-- Viewer Type --*/
90 | ViewState vState = ViewState::Running;
91 | /*--------------------*/
92 | };
93 |
94 | #endif // VIEWER_HPP
95 |
--------------------------------------------------------------------------------
/include/wonder_pokemon.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 | /**
3 | * @file wonder_pokemon.hpp
4 | */
5 | #ifndef WONDER_POKEMON_HPP
6 | #define WONDER_POKEMON_HPP
7 |
8 | #include "save.hpp"
9 |
10 | namespace WonderPokemon
11 | {
12 | extern const pk6_t PK6_Celebi_Pokebank;
13 | }
14 |
15 | #endif // WONDER_POKEMON_HPP
16 |
--------------------------------------------------------------------------------
/source/am.c:
--------------------------------------------------------------------------------
1 | #include "am.h"
2 | #include "fs.h"
3 |
4 | #include <3ds/result.h>
5 |
6 | #include
7 |
8 | // #define AM_DEBUG
9 |
10 | #ifdef AM_DEBUG
11 | #include
12 | #define debug_print(fmt, args ...) printf(fmt, ##args)
13 | #define r(fmt, args ...) printf(fmt, ##args)
14 | #else
15 | #define debug_print(fmt, args ...)
16 | #define r(fmt, args ...)
17 | #endif
18 |
19 | static const u32 pokemonTitleCount = 4;
20 | static const u64 pokemonTitleIDs[] = {
21 | 0x0004000000055D00, ///< Pokémon X
22 | 0x0004000000055E00, ///< Pokémon Y
23 | 0x000400000011C400, ///< Pokémon Omega Ruby
24 | 0x000400000011C500, ///< Pokémon Alpha Sapphire
25 | 0x0000000000000000, ///< Not Pokémon
26 | };
27 |
28 | static Result AM_GetSmdh(AM_TitleMediaEntry* title)
29 | {
30 | if (!title || title->smdh) return -1;
31 |
32 | Result ret;
33 | u32 bytesRead;
34 | Handle fileHandle;
35 |
36 | debug_print("AM_GetSmdh:\n");
37 |
38 | u32 archivePath[] = { title->titleid & 0xFFFFFFFF, (title->titleid >> 32) & 0xFFFFFFFF, title->mediatype, 0x00000000 };
39 | u32 filePath[] = { 0x00000000, 0x00000000, 0x00000002, 0x6E6F6369, 0x00000000 };
40 |
41 | ret = FSUSER_OpenFileDirectly(&fileHandle, ARCHIVE_SAVEDATA_AND_CONTENT, (FS_Path) { PATH_BINARY, 16, archivePath }, (FS_Path) { PATH_BINARY, 20, filePath }, FS_OPEN_READ, FS_ATTRIBUTE_NONE);
42 | r(" > FSUSER_OpenFileDirectly: %lx\n", ret);
43 |
44 | if (R_SUCCEEDED(ret))
45 | {
46 | title->smdh = (smdh_s*) malloc(sizeof(smdh_s));
47 |
48 | ret = FSFILE_Read(fileHandle, &bytesRead, 0LL, title->smdh, sizeof(smdh_s));
49 | r(" > FSFILE_Read: %lx\n", ret);
50 | }
51 |
52 | if (R_FAILED(ret))
53 | {
54 | free(title->smdh);
55 | title->smdh = NULL;
56 | }
57 |
58 | FSFILE_Close(fileHandle);
59 | r(" > FSFILE_Close\n");
60 |
61 | return ret;
62 | }
63 |
64 | Result AM_GetPokemonTitleEntryList(AM_TitleMediaEntry** titleList, u32* count)
65 | {
66 | if (!titleList) return -1;
67 |
68 | Result ret;
69 | u32 ccount = 0;
70 | u32 count_SD = 0;
71 | u32 count_Card = 0;
72 | u32 pkmCount_SD = 0;
73 | u32 pkmCount_Card = 0;
74 | u32 pkmCount_Total = 0;
75 | u64* titleIDs_SD = NULL;
76 | u64* titleIDs_Card = NULL;
77 |
78 | debug_print("AM_GetPokemonTitleEntryList:\n");
79 |
80 | ret = AM_GetTitleCount(MEDIATYPE_SD, &count_SD);
81 | r(" > AM_GetTitleCount: %lx\n", ret);
82 |
83 | ret = AM_GetTitleCount(MEDIATYPE_GAME_CARD, &count_Card);
84 | r(" > AM_GetTitleCount: %lx\n", ret);
85 |
86 | titleIDs_SD = (u64*) malloc(count_SD * sizeof(u64));
87 | titleIDs_Card = (u64*) malloc(count_Card * sizeof(u64));
88 |
89 | ret = AM_GetTitleList(NULL, MEDIATYPE_SD, count_SD, titleIDs_SD);
90 | r(" > AM_GetTitleList: %lx\n", ret);
91 |
92 | ret = AM_GetTitleList(NULL, MEDIATYPE_GAME_CARD, count_Card, titleIDs_Card);
93 | r(" > AM_GetTitleList: %lx\n", ret);
94 |
95 | debug_print("Count SD : %lu\n", count_SD);
96 | debug_print("Count Card: %lu\n", count_Card);
97 |
98 | for (u32 i = 0; i < count_SD; i++)
99 | for (u32 ii = 0; ii < pokemonTitleCount; ii++)
100 | if (titleIDs_SD[i] == pokemonTitleIDs[ii])
101 | pkmCount_SD++;
102 |
103 | for (u32 i = 0; i < count_Card; i++)
104 | for (u32 ii = 0; ii < pokemonTitleCount; ii++)
105 | if (titleIDs_Card[i] == pokemonTitleIDs[ii])
106 | pkmCount_Card++;
107 |
108 | pkmCount_Total = pkmCount_SD + pkmCount_Card;
109 | if (count) *count = pkmCount_Total;
110 |
111 | debug_print("PkmCount SD : %lu\n", pkmCount_SD);
112 | debug_print("PkmCount Card: %lu\n", pkmCount_Card);
113 | debug_print("PkmCount Total: %lu\n", pkmCount_Total);
114 |
115 | AM_TitleMediaEntry* titleIDs = (AM_TitleMediaEntry*) malloc(pkmCount_Total * sizeof(AM_TitleMediaEntry));
116 | *titleList = titleIDs;
117 |
118 | debug_print("Caring about card! (%lu/%lu done)\n", ccount, pkmCount_Total);
119 | // Card first for the final list.
120 | for (u32 i = 0; i < count_Card; i++)
121 | for (u32 ii = 0; ii < pokemonTitleCount; ii++)
122 | if (titleIDs_Card[i] == pokemonTitleIDs[ii])
123 | {
124 | debug_print("Adding title: %016llx (%lu/%lu)", pokemonTitleIDs[ii], ccount+1, pkmCount_Total);
125 | titleIDs[ccount] = (AM_TitleMediaEntry) { pokemonTitleIDs[ii], NULL, MEDIATYPE_GAME_CARD };
126 | ret = AM_GetSmdh(&(titleIDs[ccount]));
127 | r(" > AM_GetSmdh: %lx\n", ret);
128 | ccount++;
129 | }
130 |
131 | debug_print("Caring about SD! (%lu/%lu done)\n", ccount , pkmCount_Total);
132 | // SD second for the final list.
133 | for (u32 i = 0; i < count_SD; i++)
134 | for (u32 ii = 0; ii < pokemonTitleCount; ii++)
135 | if (titleIDs_SD[i] == pokemonTitleIDs[ii])
136 | {
137 | debug_print("Adding title: %016llx (%lu/%lu)", pokemonTitleIDs[ii], ccount+1, pkmCount_Total);
138 | titleIDs[ccount] = (AM_TitleMediaEntry) { pokemonTitleIDs[ii], NULL, MEDIATYPE_SD };
139 | ret = AM_GetSmdh(&(titleIDs[ccount]));
140 | r(" > AM_GetSmdh: %lx\n", ret);
141 | ccount++;
142 | }
143 |
144 | free(titleIDs_SD);
145 | free(titleIDs_Card);
146 |
147 | return ret;
148 | }
149 |
150 | Result AM_FreePokemonTitleEntryList(AM_TitleMediaEntry* titleList, u32 count)
151 | {
152 | if (!titleList) return -1;
153 |
154 | debug_print("AM_FreePokemonTitleEntryList:\n");
155 |
156 | for (u32 i = 0; i < count; i++)
157 | free(titleList[i].smdh);
158 | free(titleList);
159 |
160 | return 0;
161 | }
162 |
--------------------------------------------------------------------------------
/source/bank_updater.cpp:
--------------------------------------------------------------------------------
1 | #include "bank_updater.hpp"
2 |
3 | #include
4 |
5 | namespace BankUpdater
6 | {
7 | /// DEBUG_FUNCTION
8 | static inline void write(u8* buf, u32 off, u32 count)
9 | {
10 | printf("[@0x%lu](%lu):\n", off, count);
11 | for (u32 i = 0; i < count; i++)
12 | {
13 | printf("%02x ", buf[off+i]);
14 | if (i % 0x10 == 0xF) printf("\n");
15 | }
16 | printf("\n");
17 | }
18 |
19 | static inline uint32_t MakeMagic(char a, char b, char c, char d)
20 | {
21 | return (a | b << 8 | c << 16 | d << 24);
22 | }
23 |
24 | bool updateBank(bankbuffer_t bankbuffer, u32 bytesRead)
25 | {
26 | // It can't even read the magic/version
27 | if (bytesRead < 0x10) return false;
28 |
29 | u32 version = *(u32*)(bankbuffer + 0x4);
30 |
31 | printf("Bank code version: %8x\n", VERSION);
32 | printf("Bank file version: %8lx\n", version);
33 |
34 | // If the version is already the current
35 | if (version == VERSION) return true;
36 |
37 | // Before the versioning starts or blank file
38 | if (version == 0x00000000)
39 | {
40 | printf("\a0x00000000->0x020000B0\n");
41 |
42 | *(u32*)(bankbuffer + 0x00) = MakeMagic('B', 'A', 'N', 'K');
43 | printf("\r"); // It is really needed else it will freeze
44 |
45 | // bankbuffer[0] = 'B';
46 | // bankbuffer[1] = 'A';
47 | // bankbuffer[2] = 'N';
48 | // bankbuffer[3] = 'K';
49 |
50 | *(u32*)(bankbuffer + 0x04) = version = 0x020000B0;
51 | *(u32*)(bankbuffer + 0x20) = 0x00000100; ///< Box data offset (NEW)
52 | *(u32*)(bankbuffer + 0x24) = 0x000A9FC0; ///< Box name offset (NEW)
53 | *(u32*)(bankbuffer + 0x28) = 0x000AACF8; ///< Box background offset (NEW)
54 | *(u32*)(bankbuffer + 0x2C) = 0x00000000; ///< ??? offset (NEW)
55 | }
56 |
57 | // Before the wonderbox
58 | if (version == 0x020000B0)
59 | {
60 | printf("\a0x020000B0->0x020001B0\n");
61 |
62 | *(u32*)(bankbuffer + 0x04) = version = 0x020001B0;
63 | *(u32*)(bankbuffer + 0x30) = 0x000AAE00; ///< Wonder box data offset (NEW)
64 | }
65 |
66 | // Current version
67 | if (version == 0x020001B0)
68 | {
69 | printf("\a0x020001B0->0x020101B0\n");
70 |
71 | *(u32*)(bankbuffer + 0x04) = version = 0x020101B0;
72 | *(u32*)(bankbuffer + 0x34) = 0x000AC930; ///< Trash box data offset (NEW)
73 |
74 | return true;
75 | }
76 |
77 | if (version == 0x020101B0)
78 | {
79 | printf("\a0x020001B0\n");
80 | return true;
81 | }
82 |
83 | // Current real version
84 | return version == VERSION;
85 | }
86 |
87 | /**
88 | * @brief data[@offset](#size)
89 | *
90 | * Box data[@0x00000100](#0xA9EC0)
91 | * Box name[@0x000A9FC0](#0xD48)
92 | * Box background[@0x000AACF8](#0x64)
93 | * Wonder box data[@0x000AAE00](#0x1B30)
94 | **/
95 | }
96 |
--------------------------------------------------------------------------------
/source/data_manager.cpp:
--------------------------------------------------------------------------------
1 | #include "data_manager.hpp"
2 |
3 | #include "lang.h"
4 | #include "utils.h"
5 | #include "pkdir.h"
6 | #include "personal.hpp"
7 |
8 | extern "C" {
9 | #include <3ds/result.h>
10 | #include <3ds/util/utf.h>
11 | }
12 |
13 | #include
14 | #include
15 |
16 | // wstring for "(None)", just a safe case
17 | const uint32_t wNone[] = { 0x00000028, 0x0000004E, 0x0000004F, 0x0000004E, 0x00000045, 0x00000029, 0x00000000 };
18 |
19 | DataManager::DataManager(void)
20 | {
21 |
22 | }
23 |
24 | DataManager::~DataManager(void)
25 | {
26 | freeDataLines(wText, BANK_TEXT_COUNT);
27 | freeDataLines(wAbilities, DEX_ABILITIES_COUNT);
28 | freeDataLines(wItems, DEX_ITEMS_COUNT);
29 | freeDataLines(wMoves, DEX_MOVES_COUNT);
30 | freeDataLines(wNatures, DEX_NATURES_COUNT);
31 | freeDataLines(wSpecies, DEX_SPECIES_COUNT);
32 | freeDataLines(wTypes, DEX_TYPES_COUNT);
33 | }
34 |
35 | const char* DataManager::lang(void)
36 | {
37 | switch (userlang)
38 | {
39 | // case LANGUAGE_JP: return "jp"; ///< Japan
40 | case LANGUAGE_FR: return "fr"; ///< French
41 | case LANGUAGE_IT: return "it"; ///< Italian
42 | case LANGUAGE_DE: return "de"; ///< German
43 | case LANGUAGE_ES: return "es"; ///< Spanish
44 | // case LANGUAGE_KR: return "kr"; ///< Korean
45 | default: return "en"; ///< English
46 | }
47 | }
48 |
49 | const uint32_t* DataManager::text(BankText text)
50 | {
51 | if ((u8) text < BANK_TEXT_COUNT)
52 | return wText[(u8) text];
53 | else
54 | return wText[0];
55 | }
56 |
57 | const uint32_t* DataManager::abilities(u32 ability)
58 | {
59 | if (ability < DEX_ABILITIES_COUNT)
60 | return wAbilities[ability];
61 | else
62 | return wAbilities[0];
63 | }
64 |
65 | const uint32_t* DataManager::items(u32 item)
66 | {
67 | if (item < DEX_ITEMS_COUNT)
68 | return wItems[item];
69 | else
70 | return wItems[0];
71 | }
72 |
73 | const uint32_t* DataManager::moves(u32 move)
74 | {
75 | if (move < DEX_MOVES_COUNT)
76 | return wMoves[move];
77 | else
78 | return wMoves[0];
79 | }
80 |
81 | const uint32_t* DataManager::natures(u32 nature)
82 | {
83 | if (nature < DEX_NATURES_COUNT)
84 | return wNatures[nature];
85 | else
86 | return wNone;
87 | }
88 |
89 | const uint32_t* DataManager::species(u32 species)
90 | {
91 | if (species < DEX_SPECIES_COUNT)
92 | return wSpecies[species];
93 | else
94 | return wNone;
95 | }
96 |
97 | const uint32_t* DataManager::types(u8 type)
98 | {
99 | if (type < DEX_TYPES_COUNT)
100 | return wTypes[type];
101 | else
102 | return wNone;
103 | }
104 |
105 | Result DataManager::load()
106 | {
107 | updateSystemLanguage();
108 |
109 | Result ret;
110 |
111 | ret = loadDataFile("bank_text", wText, BANK_TEXT_COUNT);
112 | if (R_FAILED(ret)) return ret;
113 |
114 | ret = loadDataFile("abilities", wAbilities, DEX_ABILITIES_COUNT);
115 | if (R_FAILED(ret)) return ret;
116 |
117 | ret = loadDataFile("items", wItems, DEX_ITEMS_COUNT);
118 | if (R_FAILED(ret)) return ret;
119 |
120 | ret = loadDataFile("moves", wMoves, DEX_MOVES_COUNT);
121 | if (R_FAILED(ret)) return ret;
122 |
123 | ret = loadDataFile("natures", wNatures, DEX_NATURES_COUNT);
124 | if (R_FAILED(ret)) return ret;
125 |
126 | ret = loadDataFile("species", wSpecies, DEX_SPECIES_COUNT);
127 | if (R_FAILED(ret)) return ret;
128 |
129 | ret = loadDataFile("types", wTypes, DEX_TYPES_COUNT);
130 | if (R_FAILED(ret)) return ret;
131 |
132 | ret = loadPersonal("personal_ao", true, PERSONAL_AO_COUNT, PERSONAL_INFO_AO_SIZE);
133 | return ret;
134 | }
135 |
136 | Result DataManager::loadPersonal(const char* file, bool ao, u32 personalCount, u32 personalInfoSize)
137 | {
138 | FILE* fp;
139 | char path[0x30];
140 |
141 | // Try to load from sdmc:/
142 | sprintf(path, SDMC DATA_FOLDER "%s", file);
143 | fp = fopen(path, "rb");
144 | if (!fp)
145 | {
146 | // Try to load from romfs:/
147 | sprintf(path, ROMFS DATA_FOLDER "%s", file);
148 | fp = fopen(path, "rb");
149 | if (!fp) return -1;
150 | }
151 |
152 | u8* personal_ao = new u8[personalCount * personalInfoSize];
153 |
154 | size_t personalInfoRead = fread(personal_ao, personalInfoSize, personalCount, fp);
155 | fclose(fp);
156 |
157 | if (personalInfoRead == personalCount)
158 | {
159 | Personal.import(personal_ao, personalInfoRead, personalInfoSize);
160 | }
161 |
162 | delete[] personal_ao;
163 |
164 | return (personalInfoRead == personalCount ? 0 : -3);
165 | }
166 |
167 | Result DataManager::loadDataFile(const char* file, uint32_t** data, u32 lineCount)
168 | {
169 | FILE* fp;
170 | char path[0x30];
171 |
172 | // Try to load the lang from sdmc:/
173 | sprintf(path, SDMC DATA_FOLDER "%s/%s_%s.txt", lang(), file, lang());
174 | fp = fopen(path, "r");
175 | if (!fp)
176 | {
177 | // Try to load the lang from romfs:/
178 | sprintf(path, ROMFS DATA_FOLDER "%s/%s_%s.txt", lang(), file, lang());
179 | fp = fopen(path, "r");
180 | if (!fp)
181 | {
182 | // Try to load the default lang from sdmc:/
183 | sprintf(path, SDMC DATA_FOLDER "en/%s_en.txt", file);
184 | fp = fopen(path, "r");
185 | if (!fp)
186 | {
187 | // Try to load the default lang from romfs:/
188 | sprintf(path, ROMFS DATA_FOLDER "en/%s_en.txt", file);
189 | fp = fopen(path, "r");
190 | if (!fp) return -1;
191 | }
192 | }
193 | }
194 |
195 | fseek(fp, 0L, SEEK_END);
196 | size_t size = ftell(fp);
197 | fseek(fp, 0L, SEEK_SET);
198 |
199 | u8* buffer = new u8[size];
200 |
201 | fread(buffer, 1, size, fp);
202 | fclose(fp);
203 |
204 | loadDataLines(buffer, data, size, lineCount);
205 |
206 | delete[] buffer;
207 |
208 | return 0;
209 | }
210 |
211 | void DataManager::loadDataLines(const u8* src, uint32_t** data, u32 srcSize, u32 lineCount)
212 | {
213 | u32 count = 0;
214 | u32 lineLength;
215 | u32 sourceOffset = 0; // 0: No BOM | 3: With BOM
216 | while (count < lineCount)
217 | {
218 | // Calculate the length of the string (in UTF-8)
219 | for (lineLength = 0; src[sourceOffset + lineLength] != '\n' && sourceOffset + lineLength < srcSize; lineLength++);
220 |
221 | // Generate the wstring (+1 for null terminator)
222 | data[count] = new uint32_t[lineLength+1];
223 | memset(data[count], 0, (lineLength+1) * sizeof(uint32_t));
224 |
225 | // Convert the UTF-8 string to a UTF-32 string for wstring
226 | utf8_to_utf32(data[count], src + sourceOffset, lineLength);
227 |
228 | // Clear the rest of the wstring.
229 | u16 len8 = str8nlen(src + sourceOffset, lineLength);
230 | data[count][len8] = '\0';
231 |
232 | sourceOffset += lineLength + 1;
233 | count++;
234 | }
235 | }
236 |
237 | void DataManager::freeDataLines(uint32_t** data, u32 lineCount)
238 | {
239 | for (u32 i = 0; i < lineCount; i++)
240 | delete data[i];
241 | // delete[] data;
242 | }
243 |
--------------------------------------------------------------------------------
/source/filter.cpp:
--------------------------------------------------------------------------------
1 | #include "filter.hpp"
2 |
3 | #include "pokemon.hpp"
4 |
5 | namespace Filter
6 | {
7 | static bool filterItemORASExclusiv(u16 itemID)
8 | {
9 | const u16 itemCount = 64; // 6;
10 | const u16 itemFilterList[itemCount] = {
11 | // 0x1a9, 0x1c2, 0x1d7, 0x26b, 0x2c9, 0x2cc, // XY
12 | 0x1a9, 0x1c2, 0x1d7, 0x26b, 0x2c9, 0x2cc, 0x2ce, 0x2cf, 0x2d0, 0x2d1, 0x2d2, 0x2d3, 0x2d4, 0x2d5, 0x2d6, 0x2d7, 0x2d8, 0x2d9, 0x2da, 0x2db, 0x2dc, 0x2dd, 0x2de, 0x2df, 0x2e0, 0x2e1, 0x2e2, 0x2e3, 0x2e4, 0x2e5, 0x2e6, 0x2e7, 0x2e8, 0x2e9, 0x2ea, 0x2eb, 0x2ec, 0x2ed, 0x2ee, 0x2ef, 0x2f0, 0x2f1, 0x2f2, 0x2f3, 0x2f4, 0x2f5, 0x2f6, 0x2f7, 0x2f8, 0x2f9, 0x2fa, 0x2fb, 0x2fc, 0x2fd, 0x2fe, 0x2ff, 0x300, 0x301, 0x302, 0x303, 0x304, 0x305, 0x306, 0x307
13 | };
14 |
15 | bool isFiltered = true;
16 |
17 | for (u32 i = 0; i < itemCount && isFiltered; i++)
18 | {
19 | if (itemFilterList[i] == itemID)
20 | isFiltered = false;
21 | }
22 |
23 | // printf(" Item[%x] %s\n", itemID, (isFiltered ? "allowed" : "forbidden"));
24 |
25 | return isFiltered;
26 | }
27 |
28 | static bool filterMoveORASExclusiv(u16 moveID)
29 | {
30 | const u16 moveCount = 4;
31 | const u16 moveFilterList[moveCount] = {
32 | 0x26a, 0x26b, 0x26c, 0x26d
33 | };
34 |
35 | bool isFiltered = true;
36 |
37 | for (u32 i = 0; i < moveCount && isFiltered; i++)
38 | {
39 | if (moveFilterList[i] == moveID)
40 | isFiltered = false;
41 | }
42 |
43 | // printf(" Move[%x] %s\n", moveID, (isFiltered ? "allowed" : "forbidden"));
44 |
45 | return isFiltered;
46 | }
47 |
48 | static bool filterAbilityORASExclusiv(u16 abilityID)
49 | {
50 | // const u16 abilityCount = 3;
51 | // const u16 abilityFilterList[abilityCount] = {
52 | // 0xbd, 0xbe, 0xbf
53 | // };
54 |
55 | bool isFiltered = true;
56 |
57 | // for (u32 i = 0; i < abilityCount && isFiltered; i++)
58 | // {
59 | // if (abilityFilterList[i] == abilityID)
60 | // isFiltered = false;
61 | // }
62 |
63 | // printf(" Ability[%x] %s\n", abilityID, (isFiltered ? "allowed" : "forbidden"));
64 |
65 | return isFiltered;
66 | }
67 |
68 | static bool filterSchoolGirlPikachu(u16 speciesID, u16 formID)
69 | {
70 | bool isFiltered = true;
71 |
72 | if (speciesID == 25 && formID > 0)
73 | isFiltered = false;
74 |
75 | // printf(" School girl %s\n", (isFiltered ? "allowed" : "forbidden"));
76 |
77 | return isFiltered;
78 | }
79 |
80 | bool filterToXY(pkm_s* pkm)
81 | {
82 | bool isFiltered = true;
83 |
84 | isFiltered &= Filter::filterItemORASExclusiv(Pokemon::itemID(pkm));
85 | isFiltered &= Filter::filterMoveORASExclusiv(Pokemon::move1(pkm));
86 | isFiltered &= Filter::filterMoveORASExclusiv(Pokemon::move2(pkm));
87 | isFiltered &= Filter::filterMoveORASExclusiv(Pokemon::move3(pkm));
88 | isFiltered &= Filter::filterMoveORASExclusiv(Pokemon::move4(pkm));
89 | isFiltered &= Filter::filterAbilityORASExclusiv(Pokemon::ability(pkm));
90 | // isFiltered &= Filter::filterSchoolGirlPikachu(Pokemon::speciesID(pkm), Pokemon::formID(pkm));
91 |
92 | // printf("To XY %s\n", (isFiltered ? "allowed" : "forbidden"));
93 |
94 | return isFiltered;
95 | }
96 |
97 | bool filterFromXY(pkm_s* pkm)
98 | {
99 | bool isFiltered = true;
100 |
101 | // printf("From XY %s\n", (isFiltered ? "allowed" : "forbidden"));
102 |
103 | return isFiltered;
104 | }
105 |
106 | bool filterToORAS(pkm_s* pkm)
107 | {
108 | bool isFiltered = true;
109 |
110 | // printf("To ORAS %s\n", (isFiltered ? "allowed" : "forbidden"));
111 |
112 | return isFiltered;
113 | }
114 |
115 | bool filterFromORAS(pkm_s* pkm)
116 | {
117 | bool isFiltered = true;
118 |
119 | isFiltered &= Filter::filterSchoolGirlPikachu(Pokemon::speciesID(pkm), Pokemon::formID(pkm));
120 |
121 | // printf("From ORAS %s\n", (isFiltered ? "allowed" : "forbidden"));
122 |
123 | return isFiltered;
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/source/font_manager.cpp:
--------------------------------------------------------------------------------
1 | #include "font_manager.hpp"
2 |
3 | #include "NotoSans_Regular_ttf.h"
4 | #include "text.h"
5 |
6 | #include
7 |
8 | FontManager::FontManager(void)
9 | {
10 |
11 | }
12 |
13 | FontManager::~FontManager(void)
14 | {
15 | if (font) sftd_free_font(font);
16 | }
17 |
18 | Result FontManager::load(void)
19 | {
20 | Result ret = (loadFonts() ? 0 : -5);
21 | if (R_FAILED(ret)) return ret;
22 |
23 | return ret;
24 | }
25 |
26 | bool FontManager::loadFonts(void)
27 | {
28 | font = sftd_load_font_mem(NotoSans_Regular_ttf, NotoSans_Regular_ttf_size);
29 | printf("Loading font: @%p\n", font);
30 | if (!font) return false;
31 |
32 | return (font);
33 | return true;
34 | }
35 |
--------------------------------------------------------------------------------
/source/fs.c:
--------------------------------------------------------------------------------
1 | #include "fs.h"
2 |
3 | #include <3ds/services/fs.h>
4 | #include <3ds/result.h>
5 | #include <3ds/ipc.h>
6 | #include <3ds/srv.h>
7 | #include <3ds/svc.h>
8 | #include
9 |
10 | // #define DEBUG_FS
11 |
12 | #ifdef DEBUG_FS
13 | #include
14 | #define debug_print(fmt, args ...) printf(fmt, ##args)
15 | #define r(fmt, args ...) printf(fmt, ##args)
16 | #else
17 | #define debug_print(fmt, args ...)
18 | #define r(fmt, args ...)
19 | #endif
20 |
21 | static bool saveInitialized = false;
22 | FS_Archive saveArchive;
23 |
24 | Result FS_ReadFile(const char* path, void* dst, u64 maxSize, FS_Archive archive, u32* bytesRead)
25 | {
26 | if (!path || !dst || !archive || !bytesRead) return -1;
27 |
28 | Result ret;
29 | u64 size;
30 | Handle fileHandle;
31 |
32 | debug_print("FS_ReadFile:\n");
33 |
34 | ret = FSUSER_OpenFile(&fileHandle, archive, fsMakePath(PATH_ASCII, path), FS_OPEN_READ, FS_ATTRIBUTE_NONE);
35 | r(" > FSUSER_OpenFile: %lx\n", ret);
36 | if (R_FAILED(ret)) return ret;
37 |
38 | ret = FSFILE_GetSize(fileHandle, &size);
39 | r(" > FSFILE_GetSize: %lx\n", ret);
40 | if (R_FAILED(ret) || size > maxSize) ret = -2;
41 |
42 | if (R_SUCCEEDED(ret))
43 | {
44 | ret = FSFILE_Read(fileHandle, bytesRead, 0x0, dst, size);
45 | r(" > FSFILE_Read: %lx\n", ret);
46 | if (R_FAILED(ret) || *bytesRead < size) ret = -3;
47 | }
48 |
49 | FSFILE_Close(fileHandle);
50 | r(" > FSFILE_Close\n");
51 |
52 | return ret;
53 | }
54 |
55 | Result FS_WriteFile(const char* path, const void* src, u64 size, FS_Archive archive, u32* bytesWritten)
56 | {
57 | if (!path || !src || !archive || !bytesWritten) return -1;
58 |
59 | Result ret;
60 | Handle fileHandle;
61 |
62 | debug_print("FS_WriteFile:\n");
63 |
64 | ret = FSUSER_OpenFile(&fileHandle, archive, fsMakePath(PATH_ASCII, path), FS_OPEN_WRITE | FS_OPEN_CREATE, FS_ATTRIBUTE_NONE);
65 | r(" > FSUSER_OpenFile: %lx\n", ret);
66 | if (R_FAILED(ret)) return ret;
67 |
68 | if (R_SUCCEEDED(ret))
69 | {
70 | ret = FSFILE_Write(fileHandle, bytesWritten, 0L, src, size, FS_WRITE_FLUSH);
71 | r(" > FSFILE_Write: %lx\n", ret);
72 | if (R_FAILED(ret) || *bytesWritten != size) ret = -2;
73 | }
74 |
75 | FSFILE_Close(fileHandle);
76 | r(" > FSFILE_Close\n");
77 |
78 | return ret;
79 | }
80 |
81 | Result FS_DeleteFile(const char* path, FS_Archive archive)
82 | {
83 | if (!path || !archive) return -1;
84 |
85 | Result ret;
86 |
87 | debug_print("FS_DeleteFile:\n");
88 |
89 | ret = FSUSER_DeleteFile(archive, fsMakePath(PATH_ASCII, path));
90 | r(" > FSUSER_DeleteFile: %lx\n", ret);
91 |
92 | return ret;
93 | }
94 |
95 | Result FS_CommitArchive(FS_Archive archive)
96 | {
97 | if (!archive) return -1;
98 |
99 | Result ret;
100 |
101 | debug_print("FS_CommitArchive:\n");
102 |
103 | ret = FSUSER_ControlArchive(archive, ARCHIVE_ACTION_COMMIT_SAVE_DATA, NULL, 0, NULL, 0);
104 | r(" > FSUSER_ControlArchive: %lx\n", ret);
105 |
106 | return ret;
107 | }
108 |
109 | #ifdef __cia
110 |
111 | static u32 lowPath[3];
112 |
113 | Result FSCIA_Init(u64 titleid, FS_MediaType mediatype)
114 | {
115 | Result ret = 1;
116 |
117 | debug_print("FSCIA_Init:\n");
118 |
119 | if (!saveInitialized)
120 | {
121 | lowPath[0] = mediatype;
122 | lowPath[1] = titleid; /// titleid & 0xFFFFFFFF
123 | lowPath[2] = titleid >> 32; // (titleid >> 32) & 0xFFFFFFFF
124 |
125 | debug_print(" > [0]: 0x%016lx\n", lowPath[0]);
126 | debug_print(" > [1]: 0x%016lx\n", lowPath[1]);
127 | debug_print(" > [2]: 0x%016lx\n", lowPath[2]);
128 |
129 | ret = FSUSER_OpenArchive(&saveArchive, ARCHIVE_USER_SAVEDATA, (FS_Path) { PATH_BINARY, 12, lowPath });
130 | r(" > FSUSER_OpenArchive: %lx\n", ret);
131 |
132 | saveInitialized = R_SUCCEEDED(ret); // true
133 | }
134 | else
135 | {
136 | debug_print(" > Save already initialized\n");
137 | }
138 |
139 | return ret;
140 | }
141 |
142 | Result FSCIA_Exit(void)
143 | {
144 | Result ret = 1;
145 |
146 | debug_print("FSCIA_Exit:\n");
147 |
148 | if (saveInitialized)
149 | {
150 | ret = FS_CommitArchive(saveArchive);
151 | r(" > FS_CommitArchive: %lx\n", ret);
152 |
153 | ret = FSUSER_CloseArchive(saveArchive);
154 | r(" > FSUSER_CloseArchive: %lx\n", ret);
155 |
156 | saveInitialized = !R_SUCCEEDED(ret); // false
157 | }
158 | else
159 | {
160 | debug_print(" > Save not initialized\n");
161 | }
162 |
163 | return ret;
164 | }
165 |
166 | #else // __3dsx
167 |
168 | static Handle fsHandle;
169 |
170 | Result FS_Init(void)
171 | {
172 | Result ret = 1;
173 |
174 | debug_print("FS_Init:\n");
175 |
176 | ret = srvGetServiceHandleDirect(&fsHandle, "fs:USER");
177 | r(" > srvGetServiceHandleDirect: %lx\n", ret);
178 | if (R_FAILED(ret)) return ret;
179 |
180 | ret = FSUSER_Initialize(fsHandle);
181 | r(" > FSUSER_Initialize: %lx\n", ret);
182 | if (R_FAILED(ret)) return ret;
183 |
184 | fsUseSession(fsHandle);
185 | debug_print(" > fsUseSession\n");
186 |
187 | if (!saveInitialized)
188 | {
189 | ret = FSUSER_OpenArchive(&saveArchive, ARCHIVE_SAVEDATA, fsMakePath(PATH_EMPTY, NULL));
190 | r(" > FSUSER_OpenArchive: %lx\n", ret);
191 |
192 | saveInitialized = R_SUCCEEDED(ret); // true
193 | }
194 | else
195 | {
196 | debug_print(" > Save already initialized\n");
197 | }
198 |
199 | return ret;
200 | }
201 |
202 | Result FS_Exit(void)
203 | {
204 | Result ret = 1;
205 |
206 | debug_print("FS_Exit:\n");
207 |
208 | if (saveInitialized)
209 | {
210 | ret = FS_CommitArchive(saveArchive);
211 | r(" > FS_CommitArchive: %lx\n", ret);
212 |
213 | ret = FSUSER_CloseArchive(saveArchive);
214 | r(" > FSUSER_CloseArchive: %lx\n", ret);
215 |
216 | saveInitialized = !R_SUCCEEDED(ret); // false
217 | }
218 | else
219 | {
220 | debug_print(" > Save not initialized\n");
221 | }
222 |
223 | fsEndUseSession();
224 | debug_print(" > fsEndUseSession\n");
225 |
226 | ret = svcCloseHandle(fsHandle);
227 | r(" > svcCloseHandle: %lx\n", ret);
228 |
229 | return ret;
230 | }
231 |
232 | #endif
233 |
--------------------------------------------------------------------------------
/source/lang.c:
--------------------------------------------------------------------------------
1 | #include "lang.h"
2 |
3 | #include <3ds/types.h>
4 | #include <3ds/result.h>
5 | #include <3ds/services/cfgu.h>
6 |
7 | Language userlang = LANGUAGE_EN;
8 |
9 | void updateSystemLanguage(void)
10 | {
11 | Result ret;
12 | u8 language = 0;
13 |
14 | cfguInit();
15 | ret = CFGU_GetConfigInfoBlk2(1, 0xA0002, &language);
16 | cfguExit();
17 |
18 | if (R_SUCCEEDED(ret))
19 | {
20 | switch (language)
21 | {
22 | case CFG_LANGUAGE_JP: userlang = LANGUAGE_JP; break;
23 | case CFG_LANGUAGE_FR: userlang = LANGUAGE_FR; break;
24 | case CFG_LANGUAGE_IT: userlang = LANGUAGE_IT; break;
25 | case CFG_LANGUAGE_DE: userlang = LANGUAGE_DE; break;
26 | case CFG_LANGUAGE_ES: userlang = LANGUAGE_ES; break;
27 | case CFG_LANGUAGE_KO: userlang = LANGUAGE_KR; break;
28 | default: userlang = LANGUAGE_EN; break;
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/source/main.cpp:
--------------------------------------------------------------------------------
1 | #include <3ds.h> // Useless --v
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | #include "fs.h"
8 | #include "key.h"
9 | #include "error.h"
10 | #include "version.h"
11 | #include "phbank.hpp"
12 | #include "box_viewer.hpp"
13 |
14 | #ifdef __cia
15 | #include "ts.h"
16 | #endif
17 |
18 | extern PrintConsole* currentConsole;
19 | /// A very bad implementation for consoleExit, only for debug.
20 | PrintConsole* consoleExit(gfxScreen_t screen, PrintConsole* console)
21 | {
22 | // TODO Future implementation!
23 | *currentConsole = *consoleGetDefault();
24 | gfxSetScreenFormat(screen, GSP_BGR8_OES);
25 | gfxSetDoubleBuffering(screen, true);
26 | gspWaitForVBlank();
27 | return console;
28 | }
29 |
30 | int main(void)
31 | {
32 | Result ret = 0, error = 0;
33 |
34 | sf2d_init();
35 | sftd_init();
36 | romfsInit();
37 |
38 | srand(osGetTime());
39 |
40 | // consoleInit(GFX_TOP, NULL); // TODO: Comment it!
41 | // consoleInit(GFX_BOTTOM, NULL); // TODO: Comment it!
42 |
43 | printf("> Loading texture manager\n");
44 | PHBanku::texture = new TextureManager();
45 | ret = PHBanku::texture->load();
46 | if (R_FAILED(ret))
47 | {
48 | // Graphics
49 | error |= ERR_GRAPHICS;
50 | }
51 |
52 | printf("> Loading font manager\n");
53 | PHBanku::font = new FontManager();
54 | ret = PHBanku::font->load();
55 | if (R_FAILED(ret))
56 | {
57 | // Font
58 | error |= ERR_FONT;
59 | }
60 |
61 | printf("> Loading data manager\n");
62 | PHBanku::data = new DataManager();
63 | ret = PHBanku::data->load();
64 | if (R_FAILED(ret))
65 | {
66 | // Data
67 | error |= ERR_DATA;
68 | }
69 |
70 | #ifdef __cia
71 | printf("> Starting title selector\n");
72 | while (!error && TS_Loop())
73 | {
74 |
75 | // Draw the static loading screen again because of ts.h
76 | PHBanku::texture->drawStaticLoadingScreen();
77 |
78 | printf("> Loading filesystem services\n");
79 | ret = FSCIA_Init(titleEntry.titleid, titleEntry.mediatype);
80 | if (R_FAILED(ret))
81 | {
82 | // Filesystem
83 | error |= ERR_FILESYSTEM;
84 | }
85 | #else // __3dsx
86 | printf("> Loading filesystem services\n");
87 | ret = FS_Init();
88 | if (R_FAILED(ret))
89 | {
90 | // Filesystem
91 | error |= ERR_FILESYSTEM;
92 | }
93 | #endif
94 |
95 | printf("> Loading save manager\n");
96 | PHBanku::save = new SaveManager();
97 | ret = PHBanku::save->load();
98 | if (R_FAILED(ret))
99 | {
100 | // Save
101 | error |= ERR_SAVE;
102 | }
103 |
104 | if (!error)
105 | {
106 | printf("> Starting box viewer...\n");
107 | Viewer* viewer = new BoxViewer();
108 |
109 | ViewState state = Viewer::startMainLoop(viewer);
110 |
111 | if (state == ViewState::Saving)
112 | {
113 | // TODO Remove when better save display!
114 | consoleInit(GFX_TOP, NULL);
115 | printf("Saving...\n");
116 | // ^
117 |
118 | PHBanku::save->save();
119 | }
120 | else
121 | {
122 | // TODO Remove when better exit display!
123 | consoleInit(GFX_TOP, NULL);
124 | printf("Exiting...\n");
125 | // ^
126 | }
127 |
128 | delete viewer;
129 | }
130 |
131 | delete PHBanku::save;
132 |
133 | #ifdef __cia
134 | FSCIA_Exit();
135 | consoleExit(GFX_TOP, NULL);
136 | break; // TODO Remove! The app crash itself after the 2nd ts, unknown cause.
137 | } // while (TS_LOOP())
138 | #else // __3dsx
139 | FS_Exit();
140 | #endif
141 |
142 | if (error)
143 | {
144 | // TODO Remove when better error display!
145 | consoleInit(GFX_TOP, NULL);
146 | // ^
147 |
148 | printf("\nProblem happened: 0x%lx\n", error);
149 | if (error & ERR_SAVE) printf(" \a Save\n");
150 | if (error & ERR_DATA) printf(" \a Data\n");
151 | if (error & ERR_FONT) printf(" \a Font\n");
152 | if (error & ERR_GRAPHICS) printf(" \a Graphics\n");
153 | if (error & ERR_FILESYSTEM) printf(" \a Filesystem\n");
154 | printf("PHBank version: %08x\n", VERSION);
155 | printf("Can't start the viewer.\n");
156 | printf("Press any key to exit\n");
157 | waitKey(KEY_ANY);
158 | }
159 | else
160 | {
161 | // TODO Remove when better exit display!
162 | consoleInit(GFX_BOTTOM, NULL);
163 | // ^
164 |
165 | printf("\nThe app execution ended!\n");
166 | printf("Thanks for being awesome!\n");
167 | }
168 |
169 | delete PHBanku::data;
170 | delete PHBanku::font;
171 | delete PHBanku::texture;
172 |
173 | romfsExit();
174 | sftd_fini();
175 | sf2d_fini();
176 | return 0;
177 | }
178 |
--------------------------------------------------------------------------------
/source/personal.cpp:
--------------------------------------------------------------------------------
1 | #include "personal.hpp"
2 |
3 | // #include
4 |
5 | static void PersonalInfo_Import(PersonalInfo* pInfo, const u8* buf)
6 | {
7 | if (!buf) return;
8 |
9 | pInfo->HP = buf[0x0];
10 | pInfo->ATK = buf[0x1];
11 | pInfo->DEF = buf[0x2];
12 | pInfo->SPE = buf[0x3];
13 | pInfo->SPA = buf[0x4];
14 | pInfo->SPD = buf[0x5];
15 |
16 | pInfo->types[0] = buf[0x6];
17 | pInfo->types[1] = buf[0x7];
18 |
19 | pInfo->items[0] = *(u16*)(buf+0xC);
20 | pInfo->items[1] = *(u16*)(buf+0xE);
21 | pInfo->items[2] = *(u16*)(buf+0x10);
22 | pInfo->gender = buf[0x12];
23 | pInfo->baseFriendship = buf[0x14];
24 | pInfo->expGrowth = buf[0x15];
25 |
26 | pInfo->formStats = *(u16*)(buf+0x1C);
27 | pInfo->formSprite = *(u16*)(buf+0x1E);
28 | pInfo->formCount = buf[0x20];
29 | pInfo->color = buf[0x21];
30 |
31 | // memcpy(pInfo, buf, sizeof(PersonalInfo));
32 | }
33 |
34 | PersonalMaster::PersonalMaster(void) : personals(NULL)
35 | {
36 |
37 | }
38 |
39 | PersonalMaster::~PersonalMaster(void)
40 | {
41 | delete[] personals;
42 | }
43 |
44 | void PersonalMaster::import(const u8* buffer, u32 pCount, u32 pSize)
45 | {
46 | personalCount = pCount;
47 | personalSize = pSize;
48 | personals = new PersonalInfo[pCount];
49 | for (u16 i = 0; i < pCount; i++)
50 | {
51 | PersonalInfo_Import(&personals[i], (u8*)(buffer+pSize*i));
52 | }
53 | }
54 |
55 | const PersonalInfo& PersonalMaster::operator()(u16 species) const
56 | {
57 | return personals[species];
58 | }
59 |
60 | const PersonalInfo& PersonalMaster::operator()(u16 species, u8 form) const
61 | {
62 | return form == 0 || personals[species].formStats == 0 ? personals[species] : personals[personals[species].formStats + form - 1];
63 | }
64 |
65 | PersonalMaster Personal;
66 |
--------------------------------------------------------------------------------
/source/phbank.cpp:
--------------------------------------------------------------------------------
1 | #include "phbank.hpp"
2 |
3 | namespace PHBanku
4 | {
5 | SaveManager* save = NULL;
6 | DataManager* data = NULL;
7 | FontManager* font = NULL;
8 | TextureManager* texture = NULL;
9 | }
10 |
--------------------------------------------------------------------------------
/source/pokedex.cpp:
--------------------------------------------------------------------------------
1 | #include "pokedex.hpp"
2 | #include "pokemon.hpp"
3 | #include "personal.hpp"
4 |
5 | #include <3ds.h>
6 | #include
7 |
8 | namespace Pokedex
9 | {
10 | /**
11 | * @brief Gets a bit of a buffer.
12 | * @param buf The buffer to extract the bit from.
13 | * @param off The offset (in byte).
14 | * @param bit The offset (in bit).
15 | */
16 | static inline bool getOffsetBit(const u8* buf, u32 off, u32 bit)
17 | {
18 | return ((buf[off+(bit/8)] >> (bit%8)) & 0x1) == 1;
19 | }
20 |
21 | /**
22 | * @brief Sets a bit of a buffer.
23 | * @param buf The buffer to inject the bit to.
24 | * @param off The offset (in byte).
25 | * @param bit The offset (in bit).
26 | * @param v The new value of the bit.
27 | */
28 | static inline void setOffsetBit(u8* buf, u32 off, u32 bit, bool v)
29 | {
30 | buf[off+(bit/8)] = (buf[off+(bit/8)] & ~(0x1 << (bit%8))) | ((v?1:0) << (bit%8));
31 | }
32 |
33 | /**
34 | * @brief Gets the bit offset of a Pokémon form of a XY game.
35 | * @param species The species of the Pokémon.
36 | * @return The bit offset of the form, -1 if none.
37 | * @see getFormDexOffsetORAS(u16)
38 | */
39 | static s32 getFormDexOffsetXY(u16 species)
40 | {
41 | switch (species)
42 | {
43 | case 460: return 187; // 2 Abomasnow
44 | case 448: return 185; // 2 Lucario
45 | case 445: return 183; // 2 Garchomp
46 | case 381: return 181; // 2 Latios
47 | case 380: return 179; // 2 Latias
48 | case 359: return 177; // 2 Absol
49 | case 354: return 175; // 2 Banette
50 | case 310: return 173; // 2 Manetric
51 | case 308: return 171; // 2 Medicham
52 | case 306: return 169; // 2 Aggron
53 | case 303: return 167; // 2 Mawile
54 | case 282: return 165; // 2 Gardevoir
55 | case 257: return 163; // 2 Blaziken
56 | case 248: return 161; // 2 Tyranitar
57 | case 229: return 159; // 2 Houndoom
58 | case 214: return 157; // 2 Heracros
59 | case 212: return 155; // 2 Scizor
60 | case 181: return 153; // 2 Ampharos
61 | case 150: return 150; // 3 Mewtwo
62 | case 142: return 148; // 2 Aerodactyl
63 | case 130: return 146; // 2 Gyarados
64 | case 127: return 144; // 2 Pinsir
65 | case 115: return 142; // 2 Kangaskhan
66 | case 94: return 140; // 2 Gengar
67 | case 65: return 138; // 2 Alakazam
68 | case 9: return 136; // 2 Blastoise
69 | case 6: return 133; // 3 Charizard
70 | case 3: return 131; // 2 Venusaur
71 | case 716: return 129; // 2 Xerneas
72 | case 681: return 127; // 2 Aegislash
73 | case 711: return 123; // 4 Gourgeist
74 | case 710: return 119; // 4 Pumpkaboo
75 | case 671: return 114; // 5 Florges
76 | case 670: return 108; // 6 Floette
77 | case 669: return 103; // 5 Flabébé
78 | case 666: return 83; // 20 Vivillion
79 | case 645: return 81; // 2 Landorus
80 | case 641: return 79; // 2 Tornadus
81 | case 642: return 77; // 2 Thundurus
82 | case 647: return 75; // 2 Keldeo
83 | case 646: return 72; // 3 Kyurem
84 | case 550: return 70; // 2 Basculin
85 | case 555: return 68; // 2 Darmanitan
86 | case 648: return 66; // 2 Meloetta
87 | case 586: return 62; // 4 Sawsbuck
88 | case 585: return 58; // 4 Deerling
89 | case 421: return 56; // 2 Cherrim
90 | case 351: return 52; // 4 Castform
91 | case 413: return 49; // 3 Wormadam
92 | case 412: return 46; // 3 Burmy
93 | case 423: return 44; // 2 Gastrodon
94 | case 422: return 42; // 2 Shellos
95 | case 479: return 36; // 6 Rotom
96 | case 487: return 34; // 2 Giratina
97 | case 492: return 32; // 2 Shaymin
98 | case 386: return 28; // 4 Deoxys
99 | case 201: return 0; // 28 Unown
100 | default: return -1;
101 | }
102 | }
103 |
104 | /**
105 | * @brief Gets the bit offset of a Pokémon form of an ORAS game.
106 | * @param species The species of the Pokémon.
107 | * @return The bit offset of the form, -1 if none.
108 | * @see getFormDexOffsetXY(u16)
109 | */
110 | static s32 getFormDexOffsetORAS(u16 species)
111 | {
112 | switch (species)
113 | {
114 | case 676: return 261; // 10 Furfrou
115 | case 649: return 256; // 5 Genesect
116 | case 493: return 238; // 18 Arceus
117 | case 383: return 236; // 2 Groudon
118 | case 382: return 234; // 2 Kyogre
119 | case 719: return 232; // 2 Diancie
120 | case 531: return 230; // 2 Audino
121 | case 475: return 228; // 2 Gallade
122 | case 428: return 226; // 2 Lopunny
123 | case 384: return 224; // 2 Rayquaza
124 | case 376: return 222; // 2 Metagross
125 | case 373: return 220; // 2 Salamence
126 | case 362: return 218; // 2 Glalie
127 | case 334: return 216; // 2 Altaria
128 | case 323: return 214; // 2 Camerupt
129 | case 319: return 212; // 2 Sharpedo
130 | case 302: return 210; // 2 Sableye
131 | case 360: return 208; // 2 Swampert
132 | case 254: return 206; // 2 Sceptile
133 | case 208: return 204; // 2 Steelix
134 | case 80: return 202; // 2 Slowbro
135 | case 18: return 200; // 2 Pidgeot
136 | case 15: return 198; // 2 Beedrill
137 | case 720: return 196; // 2 Hoopa
138 | case 25: return 189; // 7 Pikachu
139 | // case 720: return 196; // 2 Hoopa
140 | // case 25: return 195; // 1 Cosplay Pikachu
141 | // case 25: return 190; // 5 Unused (Cosplay Pikachu)
142 | // case 25: return 189; // 1 Pikachu
143 | default: return getFormDexOffsetXY(species);
144 | }
145 | }
146 |
147 | /// Regex to add printfs:
148 | /// ([s]et.* /\* (.*)(_OFFSET) \*/.*;)
149 | /// { printf("$2_FLAG\\n"); $1 }
150 | /// Regex to remove printfs:
151 | /// \{ (printf.*;) (.*;) \}
152 | /// $2
153 |
154 | void importToGame(GameVersion version, savebuffer_t sav, pkm_s* pkm)
155 | {
156 | const u32 SAV_offsetDex = (Game::is(version, Game::XY) ? SaveConst::XY_offsetDex : SaveConst::ORAS_offsetDex);
157 | const u32 SAV_offsetFormDex = SAV_offsetDex + 0x368;
158 | const u32 SAV_lengthForm = (Game::is(version, Game::XY) ? 0x18 : 0x26);
159 |
160 | bool isShiny = Pokemon::isShiny(pkm); bool shiny = isShiny;
161 | bool isFemale = Pokemon::gender(pkm) % 2; bool gender = isFemale;
162 | bool isKalosBorn = Pokemon::isKalosBorn(pkm);
163 | u16 speciesID = Pokemon::speciesID(pkm);
164 | u8 formID = Pokemon::formID(pkm);
165 | u8 lang = Pokemon::language(pkm);
166 | if (lang-- > 5) lang--; // {1|2|3|4|5|.|7|8} -> {0|1|2|3|4|5|6|7}
167 | u16 species = speciesID--;
168 | u8 form = formID;
169 |
170 | const PersonalInfo pInfo = Personal(species, form);
171 |
172 | printf("\naddDex: [%03u|%u]\n", species, form);
173 |
174 | bool alreadySeen = false;
175 | bool alreadyDisplayed = false;
176 | for (u8 i = 0; i < 4; i++)
177 | {
178 | alreadySeen |= getOffsetBit(sav, SAV_offsetDex + 0x8 + 0x60 + 0x60*(i%2) + 0x60*2*(i/2) /* SH_SEEN_OFFSET */, speciesID);
179 | alreadyDisplayed |= getOffsetBit(sav, SAV_offsetDex + 0x8 + 0x60*5 + 0x60*(i%2) + 0x60*2*(i/2) /* SH_DISPLAYED_OFFSET */, speciesID);
180 | }
181 |
182 | // Formdex
183 | if (pInfo.formCount > 0)
184 | {
185 | s32 formdexBit = Game::is(version, Game::XY) ? getFormDexOffsetXY(species) : getFormDexOffsetORAS(species);
186 |
187 | if (formdexBit >= 0)
188 | {
189 | // Form Seen
190 | switch (species)
191 | {
192 | case 351: // Castform
193 | case 421: // Cherrim
194 | case 555: // Darmanitan
195 | case 648: // Meloetta
196 | case 681: // Aegislash
197 | {
198 | for (u8 i = 0; i < pInfo.formCount; i++)
199 | {
200 | { printf("SH_FORM_SEEN_FLAG\n"); setOffsetBit(sav, SAV_offsetFormDex + SAV_lengthForm*(shiny) /* SH_FORM_SEEN_OFFSET */, formdexBit + i, true); }
201 | }
202 | break;
203 | }
204 | case 25: // Pikacha
205 | {
206 | { printf("SH_FORM_SEEN_FLAG\n"); setOffsetBit(sav, SAV_offsetFormDex + SAV_lengthForm*(shiny) /* SH_FORM_SEEN_OFFSET */, formdexBit, true); }
207 | { printf("SH_FORM_SEEN_FLAG\n"); setOffsetBit(sav, SAV_offsetFormDex + SAV_lengthForm*(shiny) /* SH_FORM_SEEN_OFFSET */, formdexBit + 6, true); }
208 | break;
209 | }
210 | // TODO: Handle Mega forms
211 | // case XXX: // Mega
212 | // {
213 | // if (formID > 0)
214 | // {
215 | // { printf("SH_FORM_SEEN_FLAG\n"); setOffsetBit(sav, SAV_offsetFormDex + SAV_lengthForm*(shiny) /* SH_FORM_SEEN_OFFSET */, formdexBit, true); }
216 | // }
217 | // { printf("SH_FORM_SEEN_FLAG\n"); setOffsetBit(sav, SAV_offsetFormDex + SAV_lengthForm*(shiny) /* SH_FORM_SEEN_OFFSET */, formdexBit + formID, true); }
218 | // break;
219 | // }
220 | default:
221 | {
222 | { printf("SH_FORM_SEEN_FLAG\n"); setOffsetBit(sav, SAV_offsetFormDex + SAV_lengthForm*(shiny) /* SH_FORM_SEEN_OFFSET */, formdexBit + formID, true); }
223 | }
224 | }
225 |
226 | formdexBit += formID;
227 |
228 | // Form Displayed
229 | if (!alreadySeen && !alreadyDisplayed) // Not seen nor displayed
230 | {
231 | { printf("SH_FORM_DISPLAYED_FLAG\n"); setOffsetBit(sav, SAV_offsetFormDex + SAV_lengthForm*(shiny+2) /* SH_FORM_DISPLAYED_OFFSET */, formdexBit + formID, true); }
232 | }
233 | else // Already seen or displayed
234 | {
235 | // 'Fix' for filthy hackers..
236 | // Should not happens in a regular use.
237 |
238 | bool alreadyFormDisplayed = false;
239 | for (u8 i = 0; i < pInfo.formCount; i++)
240 | for (u8 j = 0; j < 2; j++)
241 | {
242 | alreadyFormDisplayed |= getOffsetBit(sav, SAV_offsetFormDex + SAV_lengthForm*(j+2) /* SH_FORM_DISPLAYED_OFFSET */, i);
243 | }
244 |
245 | if (!alreadyFormDisplayed) // Seen but not form displayed
246 | {
247 | { printf("SH_FORM_DISPLAYED_FLAG\n"); setOffsetBit(sav, SAV_offsetFormDex + SAV_lengthForm*(shiny+2) /* SH_FORM_DISPLAYED_OFFSET */, formdexBit, true); }
248 | }
249 | else // Seen and form displayed
250 | {
251 | alreadyFormDisplayed = false;
252 | for (u8 i = 0; i < pInfo.formCount; i++)
253 | for (u8 j = 0; j < 2; j++)
254 | {
255 | if (getOffsetBit(sav, SAV_offsetFormDex + SAV_lengthForm*(j+2) /* SH_FORM_DISPLAYED_OFFSET */, i))
256 | {
257 | if (!getOffsetBit(sav, SAV_offsetFormDex + SAV_lengthForm*(j) /* SH_FORM_SEEN_OFFSET */, i))
258 | {
259 | { printf("~SH_FORM_DISPLAYED_FLAG\n"); setOffsetBit(sav, SAV_offsetFormDex + SAV_lengthForm*(j+2) /* SH_FORM_DISPLAYED_OFFSET */, i, false); }
260 | }
261 | else alreadyFormDisplayed = true;
262 | }
263 | }
264 |
265 | if (!alreadyFormDisplayed && !alreadyDisplayed)
266 | {
267 | { printf("SH_FORM_DISPLAYED_FLAG\n"); setOffsetBit(sav, SAV_offsetFormDex + SAV_lengthForm*(shiny+2) /* SH_FORM_DISPLAYED_OFFSET */, formdexBit, true); }
268 | }
269 | }
270 | }
271 | }
272 | }
273 |
274 | // Seen
275 | { printf("SH_SEEN_FLAG\n"); setOffsetBit(sav, SAV_offsetDex + 0x8 + 0x60 + 0x60*(gender) + 0x60*2*(shiny) /* SH_SEEN_OFFSET */, speciesID, true); }
276 |
277 | // Displayed
278 | if (!alreadyDisplayed)
279 | {
280 | { printf("SH_DISPLAYED_FLAG\n"); setOffsetBit(sav, SAV_offsetDex + 0x8 + 0x60*5 + 0x60*(gender) + 0x60*2*(shiny) /* SH_DISPLAYED_OFFSET */, speciesID, true); }
281 | }
282 |
283 | // Lang
284 | if (lang >= 0 && lang < 7)
285 | {
286 | { printf("LANG_FLAG\n"); setOffsetBit(sav, SAV_offsetDex + 0x3C8 /* LANG_OFFSET */, speciesID * 7 + lang, true); }
287 | }
288 |
289 | // Foreign
290 | if (Game::is(version, Game::XY) && !isKalosBorn && species < 650)
291 | {
292 | { printf("FOREIGN_FLAG\n"); setOffsetBit(sav, SAV_offsetDex + 0x64C /* FOREIGN_OFFSET */, speciesID, true); }
293 | }
294 | // Owned
295 | else if (Game::is(version, Game::ORAS) || isKalosBorn)
296 | {
297 | { printf("OWNED_FLAG\n"); setOffsetBit(sav, SAV_offsetDex + 0x8 /* OWNED_OFFSET */, speciesID, true); }
298 | }
299 |
300 | // DexNav
301 | if (Game::is(version, Game::ORAS))
302 | {
303 | u16* dexNav = (u16*)(sav + SAV_offsetDex + 0x686 /* DEXNAV_OFFSET */ + speciesID * 2);
304 | if (*dexNav == 0) { printf("DEXNAV_SET\n"); *dexNav = 1; }
305 | }
306 | }
307 | }
308 |
--------------------------------------------------------------------------------
/source/text.c:
--------------------------------------------------------------------------------
1 | #include "text.h"
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | sftd_font* font;
9 | sftd_font* font_bold;
10 |
11 | void sftd_draw_text_pkm(u16 x, u16 y, const char* text, ...)
12 | {
13 | char buffer[256];
14 | va_list args;
15 | va_start(args, text);
16 | vsnprintf(buffer, 256, text, args);
17 | sftd_draw_text(font, x+1, y+1, RGBA8(0x00,0x00,0x00,0xAF), 12, buffer);
18 | sftd_draw_text(font, x, y, RGBA8(0xFF,0xFF,0xFF,0xFF), 12, buffer);
19 | va_end(args);
20 | }
21 |
22 | void sftd_draw_text_white(u16 x, u16 y, const char* text, ...)
23 | {
24 | char buffer[256];
25 | va_list args;
26 | va_start(args, text);
27 | vsnprintf(buffer, 256, text, args);
28 | sftd_draw_text(font, x, y, RGBA8(0xFF,0xFF,0xFF,0xFF), 12, buffer);
29 | va_end(args);
30 | }
31 |
32 | void sftd_draw_text_black(u16 x, u16 y, const char* text, ...)
33 | {
34 | char buffer[256];
35 | va_list args;
36 | va_start(args, text);
37 | vsnprintf(buffer, 256, text, args);
38 | sftd_draw_text(font, x, y, RGBA8(0x00, 0x00,0x00,0xFF), 12, buffer);
39 | va_end(args);
40 | }
41 |
42 | void sftd_draw_wtext_pkm(uint16_t x, uint16_t y, const uint32_t* text)
43 | {
44 | sftd_draw_wtext(font, x+1, y+1, RGBA8(0x00,0x00,0x00,0xAF), 12, (wchar_t*) text);
45 | sftd_draw_wtext(font, x, y, RGBA8(0xFF,0xFF,0xFF,0xFF), 12, (wchar_t*) text);
46 | }
47 |
48 | void sftd_draw_wtext_white(uint16_t x, uint16_t y, const uint32_t* text)
49 | {
50 | sftd_draw_wtext(font, x, y, RGBA8(0xFF,0xFF,0xFF,0xFF), 12, (wchar_t*) text);
51 | }
52 |
53 | void sftd_draw_wtext_black(uint16_t x, uint16_t y, const uint32_t* text)
54 | {
55 | sftd_draw_wtext(font, x, y, RGBA8(0x00,0x00,0x00,0xFF), 12, (wchar_t*) text);
56 | }
57 |
58 | void sftd_draw_wtextf_pkm(uint16_t x, uint16_t y, const wchar_t* text, ...)
59 | {
60 | wchar_t buffer[256];
61 | va_list args;
62 | va_start(args, text);
63 | vswprintf(buffer, 256, text, args);
64 | sftd_draw_wtext(font, x+1, y+1, RGBA8(0x00,0x00,0x00,0xAF), 12, buffer);
65 | sftd_draw_wtext(font, x, y, RGBA8(0xFF,0xFF,0xFF,0xFF), 12, buffer);
66 | va_end(args);
67 | }
68 |
69 | void sftd_draw_wtextf_white(uint16_t x, uint16_t y, const wchar_t* text, ...)
70 | {
71 | wchar_t buffer[256];
72 | va_list args;
73 | va_start(args, text);
74 | vswprintf(buffer, 256, text, args);
75 | sftd_draw_wtext(font, x, y, RGBA8(0xFF,0xFF,0xFF,0xFF), 12, buffer);
76 | va_end(args);
77 | }
78 |
79 | void sftd_draw_wtextf_black(uint16_t x, uint16_t y, const wchar_t* text, ...)
80 | {
81 | wchar_t buffer[256];
82 | va_list args;
83 | va_start(args, text);
84 | vswprintf(buffer, 256, text, args);
85 | sftd_draw_wtext(font, x, y, RGBA8(0x00,0x00,0x00,0xFF), 12, buffer);
86 | va_end(args);
87 | }
88 |
--------------------------------------------------------------------------------
/source/texture_manager.cpp:
--------------------------------------------------------------------------------
1 | #include "texture_manager.hpp"
2 |
3 | #include
4 | #include
5 |
6 | #define ROMFS "/pk/romfs/"
7 |
8 | static bool threadMainLoop;
9 |
10 | static const int rowBackball[4][2] = {
11 | {24, 0},
12 | {16, +24},
13 | { 8, +48},
14 | };
15 |
16 | void _loadingScreen(void* arg)
17 | {
18 | TextureManager* that = (TextureManager*) arg;
19 |
20 | sf2d_set_clear_color(RGBA8(0xF8,0xF8,0xF8,0xFF));
21 | sf2d_set_vblank_wait(false);
22 | while (threadMainLoop)
23 | {
24 | sf2d_start_frame(GFX_TOP, GFX_LEFT);
25 | that->drawLoadingTopScreen();
26 | sf2d_end_frame();
27 | sf2d_start_frame(GFX_BOTTOM, GFX_LEFT);
28 | that->drawLoadingBottomScreen();
29 | sf2d_end_frame();
30 | sf2d_swapbuffers();
31 | }
32 | sf2d_set_vblank_wait(true);
33 | }
34 |
35 | void _loadTextures(void* arg)
36 | {
37 | TextureManager* that = (TextureManager*) arg;
38 |
39 | that->loadTextures();
40 |
41 | threadMainLoop = false;
42 | }
43 |
44 | TextureManager::TextureManager(void)
45 | {
46 | ballLoadingScreen = NULL;
47 | pkmIcons = NULL;
48 | pkmShinyIcons = NULL;
49 | pkmFormIcons = NULL;
50 | pkmShinyFormIcons = NULL;
51 | itemIcons = NULL;
52 | ballIcons = NULL;
53 | types = NULL;
54 | boxTiles = NULL;
55 | boxBackgrounds = NULL;
56 | resumeBackground = NULL;
57 | }
58 |
59 | TextureManager::~TextureManager(void)
60 | {
61 | sf2d_free_texture(ballLoadingScreen);
62 | sf2d_free_texture(pkmIcons);
63 | sf2d_free_texture(pkmShinyIcons);
64 | sf2d_free_texture(pkmFormIcons);
65 | sf2d_free_texture(pkmShinyFormIcons);
66 | sf2d_free_texture(itemIcons);
67 | sf2d_free_texture(ballIcons);
68 | sf2d_free_texture(types);
69 | sf2d_free_texture(boxTiles);
70 | sf2d_free_texture(boxBackgrounds);
71 | sf2d_free_texture(resumeBackground);
72 | }
73 |
74 | Result TextureManager::load(void)
75 | {
76 | printf("Loading ballLoadingScreen: @%p\n", (ballLoadingScreen = sfil_load_PNG_file(ROMFS "ball_loading_screen.png", SF2D_PLACE_RAM)));
77 |
78 | if (!ballLoadingScreen) return -5;
79 |
80 | drawStaticLoadingScreen();
81 |
82 | // s32 prio = 0;
83 | // threadMainLoop = true;
84 | // svcGetThreadPriority(&prio, CUR_THREAD_HANDLE);
85 | // threadCreate(_loadingScreen, (void*) this, 4*1024, prio-1, -2, true);
86 |
87 | Result ret = (loadTextures() ? 0 : -5);
88 | if (R_FAILED(ret)) return ret;
89 |
90 | sf2d_texture_set_params(this->boxTiles, GPU_TEXTURE_MAG_FILTER(GPU_LINEAR) | GPU_TEXTURE_MIN_FILTER(GPU_LINEAR));
91 |
92 | // threadMainLoop = false;
93 |
94 | return ret;
95 | }
96 |
97 | bool TextureManager::loadTextures()
98 | {
99 | this->pkmIcons = sfil_load_PNG_file(ROMFS "pokemon_icons_spritesheet.png", SF2D_PLACE_RAM);
100 | printf("Loading pkmIcons: @%p\n", this->pkmIcons);
101 | if (!this->pkmIcons) return false;
102 |
103 | this->pkmShinyIcons = sfil_load_PNG_file(ROMFS "pokemon_shiny_icons_spritesheet.png", SF2D_PLACE_RAM);
104 | printf("Loading pkmShinyIcons: @%p\n", this->pkmShinyIcons);
105 | if (!this->pkmShinyIcons) return false;
106 |
107 | this->pkmFormIcons = sfil_load_PNG_file(ROMFS "pokemon_form_icons_spritesheet.png", SF2D_PLACE_RAM);
108 | printf("Loading pkmFormIcons: @%p\n", this->pkmFormIcons);
109 | if (!this->pkmFormIcons) return false;
110 |
111 | this->pkmShinyFormIcons = sfil_load_PNG_file(ROMFS "pokemon_shiny_form_icons_spritesheet.png", SF2D_PLACE_RAM);
112 | printf("Loading pkmShinyFormIcons: @%p\n", this->pkmShinyFormIcons);
113 | if (!this->pkmShinyFormIcons) return false;
114 |
115 | this->itemIcons = sfil_load_PNG_file(ROMFS "item_icons_spritesheet.png", SF2D_PLACE_RAM);
116 | printf("Loading itemIcons: @%p\n", this->itemIcons);
117 | if (!this->itemIcons) return false;
118 |
119 | this->ballIcons = sfil_load_PNG_file(ROMFS "ball_icons_spritesheet.png", SF2D_PLACE_RAM);
120 | printf("Loading ballIcons: @%p\n", this->ballIcons);
121 | if (!this->ballIcons) return false;
122 |
123 | this->types = sfil_load_PNG_file(ROMFS "types_lang.png", SF2D_PLACE_RAM);
124 | printf("Loading types: @%p\n", this->types);
125 | if (!this->types) return false;
126 |
127 | this->boxTiles = sfil_load_PNG_file(ROMFS "box_tiles.png", SF2D_PLACE_RAM);
128 | printf("Loading boxTiles: @%p\n", this->boxTiles);
129 | if (!this->boxTiles) return false;
130 |
131 | this->boxBackgrounds = sfil_load_PNG_file(ROMFS "box_backgrounds.png", SF2D_PLACE_RAM);
132 | printf("Loading boxBackgrounds: @%p\n", this->boxBackgrounds);
133 | if (!this->boxBackgrounds) return false;
134 |
135 | this->resumeBackground = sfil_load_PNG_file(ROMFS "resume_background.png", SF2D_PLACE_RAM);
136 | printf("Loading resumeBackground: @%p\n", this->resumeBackground);
137 | if (!this->resumeBackground) return false;
138 |
139 | return true;
140 | }
141 |
142 | void TextureManager::drawStaticLoadingScreen(void)
143 | {
144 | // Set the clear color to a false white.
145 | sf2d_set_clear_color(RGBA8(0xF8,0xF8,0xF8,0xFF));
146 |
147 | // Need to be called twice, probably a bug.
148 | sf2d_start_frame(GFX_TOP, GFX_LEFT);
149 | sf2d_end_frame();
150 |
151 | // Render a blank top screen.
152 | sf2d_start_frame(GFX_TOP, GFX_LEFT);
153 | drawLoadingTopScreen();
154 | sf2d_end_frame();
155 |
156 | // Render the loading screen on the bottom screen.
157 | sf2d_start_frame(GFX_BOTTOM, GFX_LEFT);
158 | drawLoadingBottomScreen();
159 | sf2d_end_frame();
160 |
161 | // Swap the buffers
162 | sf2d_swapbuffers();
163 | }
164 |
165 | void TextureManager::drawLoadingTopScreen()
166 | {
167 | // TOOD: Render a loading screen here too.
168 | }
169 |
170 | void TextureManager::drawLoadingBottomScreen()
171 | {
172 | u64 tick = svcGetSystemTick() / 10000000;
173 |
174 | for (u8 i = 0; i < 17; i++) // row
175 | for (u8 j = 0; j < 15; j++) // col
176 | {
177 | drawLoadingBackball(
178 | rowBackball[i%3][0] + j * 24 - 32 + tick % 16,
179 | (i/3) * 64 + rowBackball[i%3][1] - j * 8 - 16 + tick % 16
180 | );
181 | }
182 |
183 | // for (u8 i = 0; i < 9; i++) // row
184 | // for (u8 j = 0; j < 8; j++) // col
185 | // {
186 | // drawLoadingPokeball(
187 | // rowBackball[(i*2)%3][0] + (j*2) * 24 - 32 + tick % 64,
188 | // ((i*2)/3) * 64 + rowBackball[(i*2)%3][1] - (j*2) * 8 - 16 + tick % 64
189 | // );
190 | // }
191 |
192 | drawLoadingText(300, 220);
193 | }
194 |
195 | void TextureManager::drawLoadingPokeball(int x, int y)
196 | {
197 | sf2d_draw_texture_part_scale(this->ballLoadingScreen, x, y, 0, 0, 16, 16, 2.0f, 2.0f);
198 | }
199 |
200 | void TextureManager::drawLoadingGreatball(int x, int y)
201 | {
202 | sf2d_draw_texture_part_scale(this->ballLoadingScreen, x, y, 16, 0, 16, 16, 2.0f, 2.0f);
203 | }
204 |
205 | void TextureManager::drawLoadingUltraball(int x, int y)
206 | {
207 | sf2d_draw_texture_part_scale(this->ballLoadingScreen, x, y, 32, 0, 16, 16, 2.0f, 2.0f);
208 | }
209 |
210 | void TextureManager::drawLoadingBackball(int x, int y)
211 | {
212 | sf2d_draw_texture_part(this->ballLoadingScreen, x, y, 48, 0, 16, 16);
213 | }
214 |
215 | void TextureManager::drawLoadingText(int rx, int ry)
216 | {
217 | sf2d_draw_texture_part_scale(this->ballLoadingScreen, rx - 64 * 4, ry - 8 * 4, 0, 16, 64, 8, 4.0f, 4.0f);
218 | }
219 |
--------------------------------------------------------------------------------
/source/ts.c:
--------------------------------------------------------------------------------
1 | #include "ts.h"
2 | #include "key.h"
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | // #define TS_DEBUG
9 |
10 | #ifdef TS_DEBUG
11 | #include
12 | #define debug_print(fmt, args ...) printf(fmt, ##args)
13 | #define r(fmt, args ...) printf(fmt, ##args)
14 | #else
15 | #define debug_print(fmt, args ...)
16 | #define r(fmt, args ...)
17 | #endif
18 |
19 | AM_TitleMediaEntry titleEntry;
20 |
21 | static u32 titleCount;
22 | static s32 titleCurrent;
23 | static AM_TitleMediaEntry* titleList;
24 | static sf2d_texture** titleIcons;
25 |
26 | /**
27 | * @brief Updates the output title enty.
28 | */
29 | static void TS_Select(void)
30 | {
31 | debug_print("TS_Select:\n");
32 |
33 | titleEntry = titleList[titleCurrent];
34 |
35 | debug_print("Selected: %s\n[0x%014llx]\n", AM_GetPokemonTitleName(titleEntry.titleid), titleEntry.titleid);
36 | }
37 |
38 | /**
39 | * @brief Initializes the title module.
40 | */
41 | static Result TS_Init(void)
42 | {
43 | Result ret;
44 |
45 | debug_print("TS_Init:\n");
46 |
47 | titleCount = 0;
48 | titleCurrent = 0;
49 |
50 | amInit();
51 |
52 | ret = AM_GetPokemonTitleEntryList(&titleList, &titleCount);
53 | r(" > AM_GetPokemonTitleEntryList: %lx\n", ret);
54 |
55 | debug_print("Got: %li titles\n", titleCount);
56 |
57 | titleIcons = (sf2d_texture**) malloc(titleCount * sizeof(sf2d_texture*));
58 |
59 | for (u32 i = 0; i < titleCount; i++)
60 | {
61 | debug_print("Texturing %li\n", i);
62 | titleIcons[i] = sf2d_create_texture(48, 48, TEXFMT_RGB565, SF2D_PLACE_RAM);
63 | u16* dst = (u16*)(titleIcons[i]->data + 64 * 8 * 2 * sizeof(u16));
64 | u16* src = (u16*)(titleList[i].smdh->bigIconData);
65 | for (u8 j = 0; j < 48; j += 8)
66 | {
67 | memcpy(dst, src, 48 * 8 * sizeof(u16));
68 | src += 48 * 8;
69 | dst += 64 * 8;
70 | }
71 | }
72 |
73 | sf2d_set_clear_color(RGBA8(0x40,0x40,0x40,0xFF));
74 |
75 | debug_print("Textured\n");
76 |
77 | if (titleCount > 0)
78 | {
79 | TS_Select();
80 | }
81 |
82 | return ret;
83 | }
84 |
85 | /**
86 | * @brief Exits the title module.
87 | */
88 | static void TS_Exit(void)
89 | {
90 | AM_FreePokemonTitleEntryList(titleList, titleCount);
91 | free(titleIcons);
92 |
93 | amExit();
94 | }
95 | /**
96 | * @brief Selects the previous title.
97 | */
98 | static void TS_Prev(void)
99 | {
100 | titleCurrent--;
101 | if (titleCurrent < 0)
102 | titleCurrent = titleCount-1;
103 | TS_Select();
104 | }
105 |
106 | /**
107 | * @brief Selects the next title.
108 | */
109 | static void TS_Next(void)
110 | {
111 | titleCurrent++;
112 | if (titleCurrent > titleCount-1)
113 | titleCurrent = 0;
114 | TS_Select();
115 | }
116 |
117 | bool TS_Loop(void)
118 | {
119 | TS_Init();
120 |
121 | // If no title, cancel it.
122 | if (titleCount == 0)
123 | {
124 | TS_Exit();
125 | return false;
126 | }
127 | // If only one title, select it by default.
128 | // else if (titleCount == 1)
129 | // {
130 | // TS_Select();
131 | // TS_Exit();
132 | // return true;
133 | // }
134 |
135 | bool tsReturn = false;
136 |
137 | while (aptMainLoop())
138 | {
139 | hidScanInput();
140 |
141 | u32 kState = hidKeysDown();
142 |
143 | if (kState & (KEY_UP | KEY_LEFT))
144 | {
145 | TS_Prev();
146 | }
147 | if (kState & (KEY_DOWN | KEY_RIGHT))
148 | {
149 | TS_Next();
150 | }
151 |
152 | if (kState & KEY_A)
153 | {
154 | tsReturn = true;
155 | break;
156 | }
157 |
158 | if (kState & (KEY_B | KEY_START))
159 | {
160 | tsReturn = false;
161 | break;
162 | }
163 |
164 | #ifdef TS_DEBUG
165 | gspWaitForVBlank();
166 | #else
167 | sf2d_start_frame(GFX_TOP, GFX_LEFT);
168 | {
169 | // sf2d_draw_rectangle(151, 63, titleIcons[titleCurrent]->width*2+2, titleIcons[titleCurrent]->height*2+2, RGBA8(0xFF,0xAA,0x55,0xFF));
170 | // sf2d_draw_rectangle(152, 64, titleIcons[titleCurrent]->width*2, titleIcons[titleCurrent]->height*2, RGBA8(0x55,0xAA,0xFF,0xFF));
171 |
172 | // sf2d_draw_rectangle( 63, 95, titleIcons[titleCurrent]->width+2, titleIcons[titleCurrent]->height+2, RGBA8(0xAA,0x88,0x55,0xFF));
173 | // sf2d_draw_rectangle( 64, 96, titleIcons[titleCurrent]->width, titleIcons[titleCurrent]->height, RGBA8(0x55,0x88,0xAA,0xFF));
174 |
175 | // sf2d_draw_rectangle(287, 95, titleIcons[titleCurrent]->width+2, titleIcons[titleCurrent]->height+2, RGBA8(0xAA,0x88,0x55,0xFF));
176 | // sf2d_draw_rectangle(288, 96, titleIcons[titleCurrent]->width, titleIcons[titleCurrent]->height, RGBA8(0x55,0x88,0xAA,0xFF));
177 |
178 | if (titleCount > 0)
179 | {
180 | sf2d_draw_texture_scale(titleIcons[titleCurrent], 152, 160, 2.0f, -2.0f);
181 |
182 | // sf2d_draw_texture_scale(titleIcons[titleCurrent], 152, 64, 2.0f, 2.0f);
183 |
184 | if (titleList[titleCurrent].mediatype == MEDIATYPE_GAME_CARD)
185 | {
186 | sf2d_draw_rectangle(248, 64, 8, 16, RGBA8(0xFF,0xFF,0xFF,0xFF));
187 | }
188 | }
189 |
190 | if (titleCurrent > 0)
191 | {
192 | sf2d_draw_texture_scale(titleIcons[titleCurrent-1], 64, 144, 1.0f, -1.0f);
193 |
194 | // sf2d_draw_texture(titleIcons[titleCurrent-1], 64, 96);
195 |
196 | if (titleList[titleCurrent-1].mediatype == MEDIATYPE_GAME_CARD)
197 | {
198 | sf2d_draw_rectangle(112, 96, 4, 8, RGBA8(0xFF,0xFF,0xFF,0xFF));
199 | }
200 | }
201 | else if (titleCurrent < titleCount-1)
202 | {
203 | sf2d_draw_texture_scale(titleIcons[titleCount-1], 64, 144, 1.0f, -1.0f);
204 |
205 | if (titleList[titleCount-1].mediatype == MEDIATYPE_GAME_CARD)
206 | {
207 | sf2d_draw_rectangle(112, 96, 4, 8, RGBA8(0xFF,0xFF,0xFF,0xFF));
208 | }
209 | }
210 |
211 | if (titleCurrent < titleCount-1)
212 | {
213 | sf2d_draw_texture_scale(titleIcons[titleCurrent+1], 288, 144, 1.0f, -1.0f);
214 |
215 | // sf2d_draw_texture(titleIcons[titleCurrent+1], 288, 96);
216 |
217 | if (titleList[titleCurrent+1].mediatype == MEDIATYPE_GAME_CARD)
218 | {
219 | sf2d_draw_rectangle(336, 96, 4, 8, RGBA8(0xFF,0xFF,0xFF,0xFF));
220 | }
221 | }
222 | else if (titleCurrent > 0)
223 | {
224 | sf2d_draw_texture_scale(titleIcons[0], 288, 144, 1.0f, -1.0f);
225 |
226 | if (titleList[0].mediatype == MEDIATYPE_GAME_CARD)
227 | {
228 | sf2d_draw_rectangle(336, 96, 4, 8, RGBA8(0xFF,0xFF,0xFF,0xFF));
229 | }
230 | }
231 | }
232 | sf2d_end_frame();
233 | sf2d_start_frame(GFX_BOTTOM, GFX_LEFT);
234 | sf2d_end_frame();
235 | sf2d_swapbuffers();
236 | #endif
237 | }
238 |
239 | TS_Exit();
240 | return tsReturn;
241 | }
242 |
--------------------------------------------------------------------------------
/source/viewer/savexit_viewer.cpp:
--------------------------------------------------------------------------------
1 | #include "savexit_viewer.hpp"
2 |
3 | #include "text.h"
4 | #include "phbank.hpp"
5 |
6 | #include
7 |
8 | /*----------------------------------------------------------*\
9 | | Viewer Class |
10 | \*----------------------------------------------------------*/
11 |
12 |
13 | /*--------------------------------------------------*\
14 | | Constructor / Destructor |
15 | \*--------------------------------------------------*/
16 |
17 |
18 | // --------------------------------------------------
19 | SavexitViewer::SavexitViewer(Viewer* parent) : Viewer(parent) { }
20 | // --------------------------------------------------
21 |
22 |
23 | // --------------------------------------------------
24 | SavexitViewer::SavexitViewer(ViewType vType, Viewer* parent) : Viewer(vType, parent) { }
25 | // --------------------------------------------------
26 |
27 |
28 | // --------------------------------------------------
29 | SavexitViewer::~SavexitViewer()
30 | // --------------------------------------------------
31 | {
32 | // Destruct your allocated memory here!
33 | // TODO: Content may be missing!
34 | }
35 |
36 |
37 | /*--------------------------------------------------*\
38 | | Viewer Methods |
39 | \*--------------------------------------------------*/
40 |
41 |
42 | /*------------------------------------------*\
43 | | Public Methods |
44 | \*------------------------------------------*/
45 |
46 |
47 | // --------------------------------------------------
48 | Result SavexitViewer::initialize()
49 | // --------------------------------------------------
50 | {
51 | if (hasChild()) { if (child->initialize() == PARENT_STEP) ; else return CHILD_STEP; }
52 |
53 | return SUCCESS_STEP;
54 | }
55 |
56 |
57 | // --------------------------------------------------
58 | Result SavexitViewer::drawTopScreen()
59 | // --------------------------------------------------
60 | {
61 | if (hasRegularChild()) { if (child->drawTopScreen() == PARENT_STEP); else return CHILD_STEP; }
62 |
63 | sf2d_draw_rectangle(79, 66, 240, 135, RGBA8(0x48, 0xA2, 0x3E, 0xE8));
64 |
65 | uint32_t x, y;
66 |
67 | x = 88;
68 | y = 67;
69 | sftd_draw_wtext_pkm(x, (y+=15), PHBanku::data->text(BankText::ExitMessage));
70 | sftd_draw_wtextf_pkm(x, (y+=15), L" A - %S", PHBanku::data->text(BankText::SaveExit));
71 | sftd_draw_wtextf_pkm(x, (y+=15), L" X - %S", PHBanku::data->text(BankText::Exit));
72 | sftd_draw_wtextf_pkm(x, (y+=15), L" Y - %S", PHBanku::data->text(BankText::Backup));
73 | sftd_draw_wtextf_pkm(x, (y+=15), L" B - %S", PHBanku::data->text(BankText::Return));
74 |
75 | if (hasOverlayChild()) { child->drawTopScreen(); }
76 | return SUCCESS_STEP;
77 | }
78 |
79 |
80 | // --------------------------------------------------
81 | Result SavexitViewer::drawBotScreen()
82 | // --------------------------------------------------
83 | {
84 | if (hasRegularChild()) { if (child->drawBotScreen() == PARENT_STEP); else return CHILD_STEP; }
85 |
86 | // Draw bottom screen here!
87 | // TODO: Content is missing!
88 |
89 | if (hasOverlayChild()) { child->drawBotScreen(); }
90 | return SUCCESS_STEP;
91 | }
92 |
93 |
94 | // --------------------------------------------------
95 | Result SavexitViewer::updateControls(const u32& kDown, const u32& kHeld, const u32& kUp, const touchPosition* touch)
96 | // --------------------------------------------------
97 | {
98 | if (hasRegularChild() || hasOverlayChild()) { if (child->updateControls(kDown, kHeld, kUp, touch) == PARENT_STEP); else return CHILD_STEP; }
99 |
100 | if (kDown & KEY_A)
101 | {
102 | // Return the "You have to save" code
103 | parent->setState(ViewState::Saving);
104 | close();
105 | return CHILD_STEP;
106 | }
107 |
108 | if (kDown & (KEY_B | KEY_START))
109 | {
110 | // Return to the main viewer
111 | parent->setState(ViewState::Continuing);
112 | close();
113 | return PARENT_STEP;
114 | }
115 |
116 | if (kDown & KEY_X)
117 | {
118 | // Exit the homebrew
119 | parent->setState(ViewState::Exiting);
120 | close();
121 | return CHILD_STEP;
122 | }
123 |
124 | if (kDown & KEY_Y)
125 | {
126 | // Backup the data and return to the main viewer
127 | PHBanku::save->backupFile();
128 | parent->setState(ViewState::Continuing);
129 | close();
130 | return PARENT_STEP;
131 | }
132 |
133 | return SUCCESS_STEP;
134 | }
135 |
136 |
137 | /*------------------------------------------*\
138 | | Protected Methods |
139 | \*------------------------------------------*/
140 |
141 |
142 | /*------------------------------------------*\
143 | | Private Methods |
144 | \*------------------------------------------*/
145 |
146 |
--------------------------------------------------------------------------------
/source/viewer/ultra_box_viewer.cpp:
--------------------------------------------------------------------------------
1 | #include "ultra_box_viewer.hpp"
2 |
3 | #include "text.h"
4 |
5 | #include "box_viewer.hpp"
6 |
7 | #include
8 |
9 | #define SCREEN_WIDTH (320)
10 | #define SCREEN_HEIGHT (240)
11 |
12 | #define ROW_COUNT (7)
13 | #define COL_COUNT (10)
14 | #define BOX_WIDTH (32) // Real: 64
15 | #define BOX_HEIGHT (32) // Real: 64
16 |
17 |
18 | // --------------------------------------------------
19 | void computeSlot(CursorUBox_s* cursorUBox)
20 | // --------------------------------------------------
21 | {
22 | cursorUBox->slot = cursorUBox->row * COL_COUNT + cursorUBox->col;
23 | }
24 |
25 |
26 | /*----------------------------------------------------------*\
27 | | Viewer Class |
28 | \*----------------------------------------------------------*/
29 |
30 |
31 | /*--------------------------------------------------*\
32 | | Constructor / Destructor |
33 | \*--------------------------------------------------*/
34 |
35 |
36 | // --------------------------------------------------
37 | UltraBoxViewer::UltraBoxViewer(Viewer* parent) : Viewer(parent) { }
38 | // --------------------------------------------------
39 |
40 |
41 | // --------------------------------------------------
42 | UltraBoxViewer::UltraBoxViewer(ViewType vType, Viewer* parent) : Viewer(vType, parent) { }
43 | // --------------------------------------------------
44 |
45 |
46 | // --------------------------------------------------
47 | UltraBoxViewer::~UltraBoxViewer()
48 | // --------------------------------------------------
49 | {
50 | // Destruct your allocated memory here!
51 | // TODO: Content may be missing!
52 | }
53 |
54 |
55 | /*--------------------------------------------------*\
56 | | Viewer Methods |
57 | \*--------------------------------------------------*/
58 |
59 |
60 | /*------------------------------------------*\
61 | | Public Methods |
62 | \*------------------------------------------*/
63 |
64 |
65 | // --------------------------------------------------
66 | Result UltraBoxViewer::initialize()
67 | // --------------------------------------------------
68 | {
69 | if (hasChild()) { if (child->initialize() == PARENT_STEP); else return CHILD_STEP; }
70 |
71 | consoleClear();
72 | printf("Initialize();\n");
73 | computeSlot(&cursorUBox);
74 | selectViewBox();
75 |
76 | boxCount = (cursorUBox.inBank ? PHBanku::save->bankdata.bk.boxUnlocked : PHBanku::save->savedata.pc.boxUnlocked);
77 | rowCount = (boxCount / COL_COUNT) + 1;
78 | colCount = (boxCount % COL_COUNT);
79 |
80 | printf("\x1B[8;0H[%i | %i | %i]", boxCount, rowCount, colCount);
81 |
82 | return SUCCESS_STEP;
83 | }
84 |
85 |
86 | // --------------------------------------------------
87 | Result UltraBoxViewer::drawTopScreen()
88 | // --------------------------------------------------
89 | {
90 | if (hasRegularChild()) { if (child->drawTopScreen() == PARENT_STEP); else return CHILD_STEP; }
91 |
92 | printf("\x1B[28;0HSlot: %-2i Row: %-2i Col: %-2i", cursorUBox.slot + 1, cursorUBox.row + 1, cursorUBox.col + 1);
93 |
94 | // printf("\x1B[9;8H ");
95 | // printf("\x1B[10;8H /------------------------------\\ ");
96 | // printf("\x1B[11;8H | | ");
97 | // printf("\x1B[12;8H | You are about to exit PHBank | ");
98 | // printf("\x1B[13;8H | A - Save and exit | ");
99 | // printf("\x1B[14;8H | B - Exit without saving | ");
100 | // printf("\x1B[15;8H | X - Return to PHBank | ");
101 | // printf("\x1B[16;8H | Y - Backup the save | ");
102 | // printf("\x1B[17;8H | | ");
103 | // printf("\x1B[18;8H \\------------------------------/ ");
104 | // printf("\x1B[19;8H ");
105 |
106 | if (hasOverlayChild()) { child->drawTopScreen(); }
107 | return SUCCESS_STEP;
108 | }
109 |
110 |
111 | // --------------------------------------------------
112 | Result UltraBoxViewer::drawBotScreen()
113 | // --------------------------------------------------
114 | {
115 | if (hasRegularChild()) { if (child->drawBotScreen() == PARENT_STEP); else return CHILD_STEP; }
116 |
117 | // Draw the box icons
118 | for (uint16_t row = 0; row < rowCount; row++)
119 | {
120 | for (uint16_t col = 0; col < currentColCount(row); col++)
121 | {
122 | // Draw the box icon
123 | sf2d_draw_texture_part_scale(PHBanku::texture->boxTiles, col * BOX_WIDTH, row * BOX_HEIGHT - offsetTop, 0, 128, 64, 64, 0.5f, 0.5f);
124 |
125 | // If the current box is the box currently selected
126 | if (row == cursorUBox.row && col == cursorUBox.col)
127 | {
128 | // Draw the selected box icon
129 | sf2d_draw_rectangle(col * BOX_WIDTH, row * BOX_HEIGHT - offsetTop, BOX_WIDTH, BOX_HEIGHT, RGBA8(0x55,0xAA,0x88,0xAA));
130 | }
131 | }
132 | }
133 |
134 | // Draw the bottom-bar
135 | // TODO: REMOVE THIS SHIT OMAGAWD, IT'S HORRIBLE
136 | sf2d_draw_rectangle(0, 224, 320, 16, RGBA8(0xFF, 0xFF, 0xFF, 0xFF));
137 |
138 | sftd_draw_wtextf_black(8, 225, L"%S (%u/%u)", vBox->title, vBox->count, BOX_PKM_COUNT);
139 |
140 | if (hasOverlayChild()) { child->drawBotScreen(); }
141 | return SUCCESS_STEP;
142 | }
143 |
144 |
145 | // --------------------------------------------------
146 | Result UltraBoxViewer::updateControls(const u32& kDown, const u32& kHeld, const u32& kUp, const touchPosition* touch)
147 | // --------------------------------------------------
148 | {
149 | if (hasRegularChild() || hasOverlayChild()) { if (child->updateControls(kDown, kHeld, kUp, touch) == PARENT_STEP); else return CHILD_STEP; }
150 |
151 | if (kDown & KEY_START)
152 | {
153 | // Savexit viewer
154 | closeViewer(false);
155 | return PARENT_STEP;
156 | }
157 |
158 | if (kDown & KEY_A)
159 | {
160 | // Close the viewer and update the box of the main viewer
161 | closeViewer(true);
162 | return CHILD_STEP;
163 | }
164 |
165 | if (kDown & KEY_B)
166 | {
167 | // Close the viewer
168 | closeViewer(false);
169 | return CHILD_STEP;
170 | }
171 |
172 | {
173 | bool boolMod = false;
174 | int16_t rowMod = 0;
175 | int16_t colMod = 0;
176 |
177 | if (kDown & KEY_UP) rowMod--;
178 | else if (kDown & KEY_DOWN) rowMod++;
179 |
180 | if (kDown & KEY_LEFT) colMod--;
181 | else if (kDown & KEY_RIGHT) colMod++;
182 |
183 | if (rowMod || colMod)
184 | {
185 | cursorUBox.row += rowMod;
186 | cursorUBox.col += colMod;
187 |
188 | if (rowCount < 6) // in pc
189 | {
190 | if (cursorUBox.row < 0) { if (cursorUBox.col > colCount-1) cursorUBox.row = rowCount-2; else cursorUBox.row = rowCount-1; }
191 | else if (cursorUBox.row > rowCount-1) { cursorUBox.row = 0; }
192 | else if (cursorUBox.row > rowCount-2) { if (cursorUBox.col > colCount-1) if (colMod) cursorUBox.row = rowCount-1; else cursorUBox.row = 0; else cursorUBox.row = rowCount-1; }
193 |
194 | offsetTop = 0;
195 | }
196 | else // if in bank
197 | {
198 | if (cursorUBox.row < 0)
199 | {
200 | cursorUBox.row = rowCount + (cursorUBox.col > colCount-1 ? -2 : -1);
201 | offsetTop = (rowCount > ROW_COUNT ? cursorUBox.row+1 - ROW_COUNT : 0) * BOX_HEIGHT;
202 | }
203 |
204 | if (cursorUBox.row > rowCount-1)
205 | {
206 | cursorUBox.row = 0;
207 | offsetTop = 0;
208 | }
209 |
210 | if (cursorUBox.row > rowCount-2)
211 | {
212 | cursorUBox.row = (cursorUBox.col > colCount-1 && !colMod ? 0 : rowCount-1);
213 | }
214 |
215 | if (offsetTop >= cursorUBox.row * BOX_HEIGHT)
216 | {
217 | offsetTop = (cursorUBox.row + (cursorUBox.row > 0 ? -1 : 0)) * BOX_HEIGHT;
218 | }
219 |
220 | else if (cursorUBox.row > ROW_COUNT-2 && rowMod > 0 && offsetTop + (ROW_COUNT-2) * BOX_HEIGHT < cursorUBox.row * BOX_HEIGHT)
221 | {
222 | offsetTop = (cursorUBox.row + (cursorUBox.row < rowCount-1 ? 1 : 0) - ROW_COUNT) * BOX_HEIGHT;
223 | }
224 | }
225 |
226 | if (cursorUBox.col < 0) cursorUBox.col = currentColCount(cursorUBox.row)-1;
227 | else if (cursorUBox.col > currentColCount(cursorUBox.row)-1) cursorUBox.col = 0;
228 |
229 | boolMod = true;
230 | }
231 |
232 | if (boolMod)
233 | {
234 | // Update the current box
235 | selectViewBox();
236 | }
237 | }
238 |
239 | {
240 | if (kDown & KEY_TOUCH)
241 | {
242 | originalTouch.py = touch->py;
243 | originalOffsetTop = offsetTop;
244 | // originalTouch.px = touch->px;
245 | // originalOffsetLeft = offsetLeft;
246 |
247 | uint16_t px = touch->px;
248 | uint16_t py = touch->py;
249 |
250 | // if (touchWithin(px, py, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT - 40))
251 | // {
252 | printf("\x1B[1;20H{%3u, %3u}", ((py + offsetTop) / BOX_WIDTH), ((px + offsetLeft) / BOX_HEIGHT));
253 |
254 | uint16_t oldRow = cursorUBox.row;
255 | uint16_t oldCol = cursorUBox.col;
256 |
257 | cursorUBox.row = ((py + offsetTop) / BOX_WIDTH);
258 | cursorUBox.col = ((px + offsetLeft) / BOX_HEIGHT);
259 |
260 | // If we click on the selected box
261 | if (cursorUBox.row == oldRow && cursorUBox.col == oldCol)
262 | {
263 | closeViewer(true);
264 | return CHILD_STEP;
265 | }
266 | else if (cursorUBox.row < 0 || cursorUBox.row > (rowCount-1) || cursorUBox.col < 0 || cursorUBox.col > (currentColCount(cursorUBox.row)-1))
267 | {
268 | printf("\x1B[11;20HHors-limites \n");
269 | cursorUBox.row = oldRow;
270 | cursorUBox.col = oldCol;
271 | }
272 | else
273 | {
274 | printf("\x1B[11;20HselectViewBox()\n");
275 | selectViewBox();
276 | }
277 |
278 | printf("\x1B[2;20H{%3u, %3u}", cursorUBox.row, cursorUBox.col);
279 |
280 | printf("\x1B[15;20H");
281 | // }
282 | }
283 | else if (kHeld & KEY_TOUCH)
284 | {
285 | this->touch = *touch;
286 |
287 | if (boxCount == PHBanku::save->bankdata.bk.boxUnlocked)
288 | {
289 | offsetTop = originalOffsetTop + originalTouch.py - touch->py;
290 | // offsetLeft = originalOffsetLeft + originalTouch.px - touch->px;
291 |
292 | if (offsetTop < 0)
293 | offsetTop = 0;
294 | else if (offsetTop + ROW_COUNT * BOX_HEIGHT > (rowCount-1) * BOX_HEIGHT)
295 | offsetTop = (rowCount-1) * BOX_HEIGHT - ROW_COUNT * BOX_HEIGHT;
296 | }
297 | }
298 | }
299 |
300 | if (kDown & KEY_Y)
301 | {
302 | printf("OffsetTop = %i (%i)\n", offsetTop, cursorUBox.row);
303 | }
304 |
305 | return SUCCESS_STEP;
306 | }
307 |
308 |
309 | // --------------------------------------------------
310 | bool UltraBoxViewer::selectViewBox(uint16_t boxID, bool inBank)
311 | // --------------------------------------------------
312 | {
313 | cursorUBox.inBank = inBank;
314 | cursorUBox.slot = boxID;
315 | cursorUBox.row = (boxID / COL_COUNT);
316 | cursorUBox.col = (boxID % COL_COUNT);
317 |
318 | return selectViewBox();
319 | }
320 |
321 |
322 | /*------------------------------------------*\
323 | | Protected Methods |
324 | \*------------------------------------------*/
325 |
326 |
327 | /*------------------------------------------*\
328 | | Private Methods |
329 | \*------------------------------------------*/
330 |
331 |
332 | // --------------------------------------------------
333 | bool UltraBoxViewer::selectViewBox()
334 | // --------------------------------------------------
335 | {
336 | computeSlot(&cursorUBox);
337 |
338 | if (cursorUBox.slot != -1)
339 | {
340 | PHBanku::save->countBox(cursorUBox.slot, cursorUBox.inBank);
341 | vBox = PHBanku::save->getBox(cursorUBox.slot, cursorUBox.inBank);
342 | printf("View Box: [@%p]\n", vBox);
343 | return true;
344 | }
345 |
346 | return false;
347 | }
348 |
349 |
350 | // --------------------------------------------------
351 | bool UltraBoxViewer::selectMoveBox()
352 | // --------------------------------------------------
353 | {
354 | if (vBox)
355 | {
356 | ((BoxViewer*) parent)->selectViewBox(cursorUBox.slot, cursorUBox.inBank);
357 | return true;
358 | }
359 |
360 | return false;
361 | }
362 |
363 |
364 | // --------------------------------------------------
365 | int16_t UltraBoxViewer::currentColCount(int16_t row)
366 | // --------------------------------------------------
367 | {
368 | return (row == rowCount - 1 ? colCount : COL_COUNT);
369 | }
370 |
371 |
372 | // --------------------------------------------------
373 | ViewState UltraBoxViewer::closeViewer(bool save)
374 | // --------------------------------------------------
375 | {
376 | if (save) selectMoveBox();
377 | this->setState(ViewState::Exiting);
378 | return close();
379 | }
380 |
--------------------------------------------------------------------------------
/source/viewer/viewer.cpp:
--------------------------------------------------------------------------------
1 | #include "viewer.hpp"
2 |
3 | #include
4 |
5 | /*----------------------------------------------------------*\
6 | | Viewer Class |
7 | \*----------------------------------------------------------*/
8 |
9 |
10 | /*--------------------------------------------------*\
11 | | Constructor / Destructor |
12 | \*--------------------------------------------------*/
13 |
14 |
15 | // --------------------------------------------------
16 | Viewer::Viewer(Viewer* parent)
17 | // --------------------------------------------------
18 | {
19 | this->parent = parent;
20 | this->child = NULL;
21 |
22 | if (this->parent)
23 | {
24 | this->parent->child = this;
25 | }
26 | }
27 |
28 |
29 | // --------------------------------------------------
30 | Viewer::Viewer(ViewType vType, Viewer* parent) : Viewer(parent)
31 | // --------------------------------------------------
32 | {
33 | this->vType = vType;
34 | }
35 |
36 |
37 | // --------------------------------------------------
38 | Viewer::~Viewer()
39 | // --------------------------------------------------
40 | {
41 | if (this->parent)
42 | {
43 | this->parent->child = NULL;
44 | this->parent = NULL;
45 | }
46 |
47 | delete child;
48 | }
49 |
50 |
51 | /*--------------------------------------------------*\
52 | | Viewer Methods |
53 | \*--------------------------------------------------*/
54 |
55 |
56 | /*------------------------------------------*\
57 | | Public Methods |
58 | \*------------------------------------------*/
59 |
60 |
61 | /*----------------------------------*\
62 | | Viewer Methods |
63 | \*----------------------------------*/
64 |
65 |
66 | // --------------------------------------------------
67 | Result Viewer::initialize()
68 | // --------------------------------------------------
69 | {
70 | return SUCCESS_STEP;
71 | }
72 |
73 |
74 | // --------------------------------------------------
75 | Result Viewer::drawTopScreen()
76 | // --------------------------------------------------
77 | {
78 | return SUCCESS_STEP;
79 | }
80 |
81 |
82 | // --------------------------------------------------
83 | Result Viewer::drawBotScreen()
84 | // --------------------------------------------------
85 | {
86 | return SUCCESS_STEP;
87 | }
88 |
89 |
90 | // --------------------------------------------------
91 | Result Viewer::updateControls(const u32& kDown, const u32& kHeld, const u32& kUp, const touchPosition* touch)
92 | // --------------------------------------------------
93 | {
94 | return SUCCESS_STEP;
95 | }
96 |
97 |
98 | /*----------------------------------*\
99 | | Hierarchy Section |
100 | \*----------------------------------*/
101 |
102 |
103 | // --------------------------------------------------
104 | bool Viewer::hasParent() { return this->parent; }
105 | // --------------------------------------------------
106 |
107 |
108 | // --------------------------------------------------
109 | bool Viewer::hasChild() { return this->child; }
110 | // --------------------------------------------------
111 |
112 |
113 | // --------------------------------------------------
114 | bool Viewer::isParent() { return this->child; }
115 | // --------------------------------------------------
116 |
117 |
118 | // --------------------------------------------------
119 | bool Viewer::isChild() { return this->parent; }
120 | // --------------------------------------------------
121 |
122 |
123 | // --------------------------------------------------
124 | bool Viewer::hasRegularChild()
125 | // --------------------------------------------------
126 | {
127 | return this->hasChild() && child->isRegular();
128 | }
129 |
130 |
131 | // --------------------------------------------------
132 | bool Viewer::hasOverlayChild()
133 | // --------------------------------------------------
134 | {
135 | return this->hasChild() && child->isOverlay();
136 | }
137 |
138 |
139 | /*----------------------------------*\
140 | | State Methods |
141 | \*----------------------------------*/
142 |
143 |
144 | // --------------------------------------------------
145 | bool Viewer::isRegular()
146 | // --------------------------------------------------
147 | {
148 | return vType == ViewType::Regular;
149 | }
150 |
151 |
152 | // --------------------------------------------------
153 | bool Viewer::isOverlay()
154 | // --------------------------------------------------
155 | {
156 | return vType == ViewType::Overlay;
157 | }
158 |
159 |
160 | // --------------------------------------------------
161 | void Viewer::setType(ViewType vType)
162 | // --------------------------------------------------
163 | {
164 | this->vType = vType;
165 | }
166 |
167 |
168 | /*----------------------------------*\
169 | | State Methods |
170 | \*----------------------------------*/
171 |
172 |
173 | // --------------------------------------------------
174 | bool Viewer::isRunning()
175 | // --------------------------------------------------
176 | {
177 | return vState == ViewState::Running || vState == ViewState::Continuing;
178 | }
179 |
180 |
181 | // --------------------------------------------------
182 | ViewState Viewer::close()
183 | // --------------------------------------------------
184 | {
185 | ViewState state = this->state();
186 | if (this->isChild()) delete this;
187 | return state;
188 | }
189 |
190 |
191 | // --------------------------------------------------
192 | ViewState Viewer::state()
193 | // --------------------------------------------------
194 | {
195 | return this->vState;
196 | }
197 |
198 |
199 | // --------------------------------------------------
200 | void Viewer::setState(ViewState vState)
201 | // --------------------------------------------------
202 | {
203 | this->vState = vState;
204 | }
205 |
206 |
207 | /*----------------------------------*\
208 | | Utils Methods |
209 | \*----------------------------------*/
210 |
211 |
212 | // --------------------------------------------------
213 | bool Viewer::touchWithin(s16 px, s16 py, s16 x, s16 y, s16 w, s16 h)
214 | // --------------------------------------------------
215 | {
216 | return (px >= x && py >= y) && (px <= x + w && py <= y + h);
217 | }
218 |
219 |
220 | /*------------------------------------------*\
221 | | Protected Methods |
222 | \*------------------------------------------*/
223 |
224 |
225 | /*------------------------------------------*\
226 | | Private Methods |
227 | \*------------------------------------------*/
228 |
229 |
230 | /*----------------------------------------------------------*\
231 | | Static Section |
232 | \*----------------------------------------------------------*/
233 |
234 | // --------------------------------------------------
235 | ViewState Viewer::startMainLoop(Viewer* viewer)
236 | // --------------------------------------------------
237 | {
238 | viewer->initialize();
239 |
240 | u32 kDown, kHeld, kUp;
241 | touchPosition touch;
242 | while(viewer->isRunning() && aptMainLoop())
243 | {
244 | hidScanInput();
245 | kDown = hidKeysDown();
246 | kHeld = hidKeysHeld();
247 | kUp = hidKeysUp();
248 | if ((kDown | kHeld) & KEY_TOUCH)
249 | hidTouchRead(&touch);
250 |
251 | sf2d_start_frame(GFX_TOP, GFX_LEFT);
252 | viewer->drawTopScreen();
253 | sf2d_end_frame();
254 | sf2d_start_frame(GFX_BOTTOM, GFX_LEFT);
255 | viewer->drawBotScreen();
256 | sf2d_end_frame();
257 | sf2d_swapbuffers();
258 |
259 | viewer->updateControls(kDown, kHeld, kUp, &touch);
260 | }
261 |
262 | return viewer->state();
263 | }
264 |
--------------------------------------------------------------------------------
/source/wonder_pokemon.cpp:
--------------------------------------------------------------------------------
1 | #include "wonder_pokemon.hpp"
2 |
3 | const pk6_t WonderPokemon::PK6_Celebi_Pokebank = '\0';
4 |
--------------------------------------------------------------------------------