commit 39e1736ea647e294da95e4cd9c7e86f45ccbde73 Author: joel16 Date: Thu Dec 15 11:16:01 2022 -0500 Inital commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea48bfd --- /dev/null +++ b/.gitignore @@ -0,0 +1,57 @@ +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex +app/*.prx +app/drivers +app/data/fs_driver.prx +*.PBP +*.SFO + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf +!fs_driver/exports.exp diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9230b23 --- /dev/null +++ b/Makefile @@ -0,0 +1,7 @@ +SUBDIRS = fs_driver app + +all: + @for dir in $(SUBDIRS); do $(MAKE) -C $$dir; done + +clean: + @for dir in $(SUBDIRS); do $(MAKE) clean -C $$dir; done diff --git a/README.md b/README.md new file mode 100644 index 0000000..89e46f4 --- /dev/null +++ b/README.md @@ -0,0 +1,19 @@ +# VLFFM - VLF File Manager for PSP + +VLFFM (VLF File Manager) unlike other file manager applications for the PSP, it's the first of its kind to use the native VLF library (XMB like interface). Although it isn't a fully functional file manager due to the constraints of working with an incomplete VLF library, it does still offer the basic features necessary. However, I would still consider this application something that is merely just a proof of concept. + +

+ VLFFM +

+ +**Features:** + +- Copy files/folders. +- Move files/folders. +- Delete files/folders. (Recursive doesn't seem to work) +- File properties. (File size and modification time) + +**Credits:** + +- Dark_AleX for the VLF Library. +- TheOfficialFloW for some of the FS code (namely the linked list implementation) used in this application. diff --git a/app/Makefile b/app/Makefile new file mode 100755 index 0000000..2b13ce1 --- /dev/null +++ b/app/Makefile @@ -0,0 +1,40 @@ +TARGET = VLFFM + +SOURCES := data drivers source +CFILES := $(foreach dir, $(SOURCES), $(wildcard $(dir)/*.c)) +SFILES := $(foreach dir, $(SOURCES), $(wildcard $(dir)/*.S)) +CPPFILES := $(foreach dir, $(SOURCES), $(wildcard $(dir)/*.cpp)) +BMPFILES := $(foreach dir, $(SOURCES), $(wildcard $(dir)/*.bmp)) +PRXFILES := $(foreach dir, $(SOURCES), $(wildcard $(dir)/*.prx)) + +OBJS := $(addsuffix .o,$(BINFILES)) $(CFILES:.c=.o) $(SFILES:.S=.o) $(CPPFILES:.cpp=.o) \ + $(BMPFILES:.bmp=.o) $(PNGFILES:.png=.o) $(PRXFILES:.prx=.o) + +VERSION_MAJOR := 1 +VERSION_MINOR := 0 + +INCDIR = ../libs/ ../libs/include include +CFLAGS = -Os -G0 -Wall -fshort-wchar -fno-pic -mno-check-zero-division \ + -DVERSION_MAJOR=$(VERSION_MAJOR) -DVERSION_MINOR=$(VERSION_MINOR) +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti -std=gnu++17 +ASFLAGS := $(CFLAGS) + +BUILD_PRX = 1 +PSP_LARGE_MEMORY = 1 + +LIBDIR = ../libs/lib +LDFLAGS = -nostdlib -nodefaultlibs +LIBS = -lpspmodinfo -lpspreg -lpspumd -lvlfgui -lvlfgu -lvlfutils -lvlflibc + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = $(TARGET) v$(VERSION_MAJOR).$(VERSION_MINOR)$(VERSION_MICRO) +# PSP_EBOOT_ICON = ../ICON0.PNG + +PSPSDK=$(shell psp-config --pspsdk-path) +include ./build.mak + +%.o: %.bmp + bin2o -i $< $@ $(addsuffix _bmp, $(basename $(notdir $<) )) + +%.o: %.prx + bin2o -i $< $@ $(addsuffix _prx, $(basename $(notdir $<) )) diff --git a/app/build.mak b/app/build.mak new file mode 100755 index 0000000..82f4740 --- /dev/null +++ b/app/build.mak @@ -0,0 +1,190 @@ +# PSP Software Development Kit - http://www.pspdev.org +# ----------------------------------------------------------------------- +# Licensed under the BSD license, see LICENSE in PSPSDK root for details. +# +# build.mak - Base makefile for projects using PSPSDK. +# +# Copyright (c) 2005 Marcus R. Brown +# Copyright (c) 2005 James Forshaw +# Copyright (c) 2005 John Kelley +# +# $Id: build.mak 2333 2007-10-31 19:37:40Z tyranid $ + +# Note: The PSPSDK make variable must be defined before this file is included. +ifeq ($(PSPSDK),) +$(error $$(PSPSDK) is undefined. Use "PSPSDK := $$(shell psp-config --pspsdk-path)" in your Makefile) +endif + +CC = psp-gcc +CXX = psp-g++ +AS = psp-gcc +LD = psp-gcc +AR = psp-ar +RANLIB = psp-ranlib +STRIP = psp-strip +MKSFO = mksfo +PACK_PBP = pack-pbp +FIXUP = psp-fixup-imports + +# Add in PSPSDK includes and libraries. +INCDIR := $(INCDIR) . $(PSPSDK)/include +LIBDIR := $(LIBDIR) . $(PSPSDK)/lib + +CFLAGS := $(addprefix -I,$(INCDIR)) $(CFLAGS) +CXXFLAGS := $(CFLAGS) $(CXXFLAGS) +ASFLAGS := $(CFLAGS) $(ASFLAGS) + +ifeq ($(PSP_LARGE_MEMORY),1) +MKSFO = mksfoex -d MEMSIZE=1 +endif + +ifeq ($(PSP_FW_VERSION),) +PSP_FW_VERSION=150 +endif + +CFLAGS += -D_PSP_FW_VERSION=$(PSP_FW_VERSION) +CXXFLAGS += -D_PSP_FW_VERSION=$(PSP_FW_VERSION) + +ifeq ($(BUILD_PRX),1) +LDFLAGS := $(addprefix -L,$(LIBDIR)) -specs=$(PSPSDK)/lib/prxspecs -Wl,-q,-T$(PSPSDK)/lib/linkfile.prx $(LDFLAGS) +EXTRA_CLEAN += $(TARGET).elf +# Setup default exports if needed +ifdef PRX_EXPORTS +EXPORT_OBJ=$(patsubst %.exp,%.o,$(PRX_EXPORTS)) +EXTRA_CLEAN += $(EXPORT_OBJ) +else +EXPORT_OBJ=$(PSPSDK)/lib/prxexports.o +endif +else +LDFLAGS := $(addprefix -L,$(LIBDIR)) $(LDFLAGS) +endif + +# Library selection. By default we link with Newlib's libc. Allow the +# user to link with PSPSDK's libc if USE_PSPSDK_LIBC is set to 1. + +PSPSDK_LIBC_LIB = + +# Link with following default libraries. Other libraries should be specified in the $(LIBS) variable. +# TODO: This library list needs to be generated at configure time. +# +ifeq ($(USE_KERNEL_LIBS),1) +PSPSDK_LIBS = -lpspdebug -lpspdisplay_driver -lpspctrl_driver -lpspsdk +LIBS := $(LIBS) $(PSPSDK_LIBS) $(PSPSDK_LIBC_LIB) -lpspkernel +else +ifeq ($(USE_USER_LIBS),1) +PSPSDK_LIBS = -lpspdebug -lpspdisplay -lpspge -lpspctrl -lpspsdk +LIBS := $(LIBS) $(PSPSDK_LIBS) $(PSPSDK_LIBC_LIB) -lpspnet \ + -lpspnet_inet -lpspnet_apctl -lpspnet_resolver -lpsputility \ + -lpspuser +else +PSPSDK_LIBS = -lpspdisplay -lpspge -lpspctrl -lpspsdk +LIBS := $(LIBS) $(PSPSDK_LIBS) $(PSPSDK_LIBC_LIB) -lpspnet \ + -lpspnet_inet -lpspnet_apctl -lpspnet_resolver -lpsputility \ + -lpspuser -lpspkernel +endif +endif + +# Define the overridable parameters for EBOOT.PBP +ifndef PSP_EBOOT_TITLE +PSP_EBOOT_TITLE = $(TARGET) +endif + +ifndef PSP_EBOOT_SFO +PSP_EBOOT_SFO = PARAM.SFO +endif + +ifndef PSP_EBOOT_ICON +PSP_EBOOT_ICON = NULL +endif + +ifndef PSP_EBOOT_ICON1 +PSP_EBOOT_ICON1 = NULL +endif + +ifndef PSP_EBOOT_UNKPNG +PSP_EBOOT_UNKPNG = NULL +endif + +ifndef PSP_EBOOT_PIC1 +PSP_EBOOT_PIC1 = NULL +endif + +ifndef PSP_EBOOT_SND0 +PSP_EBOOT_SND0 = NULL +endif + +ifndef PSP_EBOOT_PSAR +PSP_EBOOT_PSAR = NULL +endif + +ifndef PSP_EBOOT +PSP_EBOOT = EBOOT.PBP +endif + +ifeq ($(BUILD_PRX),1) +ifneq ($(TARGET_LIB),) +$(error TARGET_LIB should not be defined when building a prx) +else +FINAL_TARGET = $(TARGET).prx +endif +else +ifneq ($(TARGET_LIB),) +FINAL_TARGET = $(TARGET_LIB) +else +FINAL_TARGET = $(TARGET).elf +endif +endif + +all: $(EXTRA_TARGETS) $(FINAL_TARGET) + +kxploit: $(TARGET).elf $(PSP_EBOOT_SFO) + mkdir -p "$(TARGET)" + $(STRIP) $(TARGET).elf -o $(TARGET)/$(PSP_EBOOT) + mkdir -p "$(TARGET)%" + $(PACK_PBP) "$(TARGET)%/$(PSP_EBOOT)" $(PSP_EBOOT_SFO) $(PSP_EBOOT_ICON) \ + $(PSP_EBOOT_ICON1) $(PSP_EBOOT_UNKPNG) $(PSP_EBOOT_PIC1) \ + $(PSP_EBOOT_SND0) NULL $(PSP_EBOOT_PSAR) + +SCEkxploit: $(TARGET).elf $(PSP_EBOOT_SFO) + mkdir -p "__SCE__$(TARGET)" + $(STRIP) $(TARGET).elf -o __SCE__$(TARGET)/$(PSP_EBOOT) + mkdir -p "%__SCE__$(TARGET)" + $(PACK_PBP) "%__SCE__$(TARGET)/$(PSP_EBOOT)" $(PSP_EBOOT_SFO) $(PSP_EBOOT_ICON) \ + $(PSP_EBOOT_ICON1) $(PSP_EBOOT_UNKPNG) $(PSP_EBOOT_PIC1) \ + $(PSP_EBOOT_SND0) NULL $(PSP_EBOOT_PSAR) + +$(TARGET).elf: $(OBJS) $(EXPORT_OBJ) + $(LINK.c) $^ $(LIBS) -o $@ + $(FIXUP) $@ + +$(TARGET_LIB): $(OBJS) + $(AR) cru $@ $(OBJS) + $(RANLIB) $@ + +$(PSP_EBOOT_SFO): + $(MKSFO) '$(PSP_EBOOT_TITLE)' $@ + +ifeq ($(BUILD_PRX),1) +$(PSP_EBOOT): $(TARGET).prx $(PSP_EBOOT_SFO) + $(PACK_PBP) $(PSP_EBOOT) $(PSP_EBOOT_SFO) $(PSP_EBOOT_ICON) \ + $(PSP_EBOOT_ICON1) $(PSP_EBOOT_UNKPNG) $(PSP_EBOOT_PIC1) \ + $(PSP_EBOOT_SND0) $(TARGET).prx $(PSP_EBOOT_PSAR) +else +$(PSP_EBOOT): $(TARGET).elf $(PSP_EBOOT_SFO) + $(STRIP) $(TARGET).elf -o $(TARGET)_strip.elf + $(PACK_PBP) $(PSP_EBOOT) $(PSP_EBOOT_SFO) $(PSP_EBOOT_ICON) \ + $(PSP_EBOOT_ICON1) $(PSP_EBOOT_UNKPNG) $(PSP_EBOOT_PIC1) \ + $(PSP_EBOOT_SND0) $(TARGET)_strip.elf $(PSP_EBOOT_PSAR) + -rm -f $(TARGET)_strip.elf +endif + +%.prx: %.elf + psp-prxgen $< $@ + +%.c: %.exp + psp-build-exports -b $< > $@ + +clean: + -rm -f $(FINAL_TARGET) $(EXTRA_CLEAN) $(OBJS) $(PSP_EBOOT_SFO) $(PSP_EBOOT) $(EXTRA_TARGETS) + +rebuild: clean all diff --git a/app/data/backgrounds.bmp b/app/data/backgrounds.bmp new file mode 100644 index 0000000..f6a258e Binary files /dev/null and b/app/data/backgrounds.bmp differ diff --git a/app/data/intraFont.prx b/app/data/intraFont.prx new file mode 100755 index 0000000..2b5a94b Binary files /dev/null and b/app/data/intraFont.prx differ diff --git a/app/data/iop.prx b/app/data/iop.prx new file mode 100755 index 0000000..5034ce6 Binary files /dev/null and b/app/data/iop.prx differ diff --git a/app/data/vlf.prx b/app/data/vlf.prx new file mode 100755 index 0000000..786647e Binary files /dev/null and b/app/data/vlf.prx differ diff --git a/app/include/fs.h b/app/include/fs.h new file mode 100644 index 0000000..6e1c034 --- /dev/null +++ b/app/include/fs.h @@ -0,0 +1,43 @@ +#pragma once + +#include + +#define FS_MAX_PATH 256 + +typedef struct FsFileListEntry { + struct FsFileListEntry *next; + struct FsFileListEntry *previous; + char *name; + int name_length; + bool is_folder; + SceOff size; + ScePspDateTime time; +} FsFileListEntry; + +typedef struct { + FsFileListEntry *head; + FsFileListEntry *tail; + int length; + char path[FS_MAX_PATH]; + int files; + int folders; +} FsFileList; + +typedef struct { + u64 value; + u64 max; + void (*setProgress)(int value, int max); + bool (*cancelHandler)(void); +} FileProcessParam; + +extern char g_cwd[FS_MAX_PATH]; +extern FsFileList g_file_list; + +int fsGetDirectoryEntries(FsFileList *list, const char *path); +void fsFreeDirectoryEntries(FsFileList *list); +int fsAppendDir(FsFileList *list, const char *path); +int fsParentDir(FsFileList *list); +const char *fsSetPath(FsFileListEntry *entry, const char *path); +int fsCopyPath(const char *src_path, const char *dest_path, FileProcessParam *param); +int fsMovePath(const char *src_path, const char *dest_path); +int fsDelete(const char *path, FileProcessParam *param); diff --git a/app/include/gui.h b/app/include/gui.h new file mode 100644 index 0000000..0fcd180 --- /dev/null +++ b/app/include/gui.h @@ -0,0 +1,3 @@ +#pragma once + +void guiInit(void); diff --git a/app/include/kernel.h b/app/include/kernel.h new file mode 100644 index 0000000..f0ec8a9 --- /dev/null +++ b/app/include/kernel.h @@ -0,0 +1,17 @@ +#pragma once + +int pspIoOpenDir(const char *dirname); +int pspIoReadDir(SceUID dir, SceIoDirent *dirent); +int pspIoCloseDir(SceUID dir); +int pspIoMakeDir(const char *dir, SceMode mode); +int pspIoRemoveDir(const char *path); +int pspIoOpenFile(const char *file, int flags, SceMode mode); +int pspIoReadFile(SceUID file, void *data, SceSize size); +int pspIoWriteFile(SceUID file, void *data, SceSize size); +int pspIoCloseFile(SceUID file); +int pspIoLseek(SceUID file, SceOff offset, int whence); +int pspIoLseek32(SceUID file, SceOff offset, int whence); +int pspIoGetstat(const char *file, SceIoStat *stat); +int pspIoRename(const char *oldname, const char *newname); +int pspIoRemoveFile(const char *file); +int pspIoDevctl(const char *dev, unsigned int cmd, void *indata, int inlen, void *outdata, int outlen); diff --git a/app/include/utils.h b/app/include/utils.h new file mode 100644 index 0000000..a45b17e --- /dev/null +++ b/app/include/utils.h @@ -0,0 +1,17 @@ +#pragma once + +#include +#include + +/// Checks whether a result code indicates success. +#define R_SUCCEEDED(res) ((res) >= 0) +/// Checks whether a result code indicates failure. +#define R_FAILED(res) ((res) < 0) + +extern int PSP_KEY_ENTER, PSP_KEY_CANCEL; +extern char g_err_string[1024]; + +void utilsLogError(const char *error, ...); +int utilsGetEnterButton(void); +int utilsGetCancelButton(void); +void utilsGetSizeString(char *string, int size); diff --git a/app/source/crt0.c b/app/source/crt0.c new file mode 100755 index 0000000..160113d --- /dev/null +++ b/app/source/crt0.c @@ -0,0 +1,82 @@ +#include +#include + +#include "utils.h" +#include "vlf.h" + +extern unsigned char fs_driver_prx_start[], intraFont_prx_start[], iop_prx_start[], vlf_prx_start[]; +extern unsigned int fs_driver_prx_size, intraFont_prx_size, iop_prx_size, vlf_prx_size; + +extern int app_main(int argc, char *argv[]); + +int SetupCallbacks(void) { + int CallbackThread(SceSize args, void *argp) { + int exit_callback(int arg1, int arg2, void *common) { + sceKernelExitGame(); + return 0; + } + + int cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + sceKernelSleepThreadCB(); + return 0; + } + + SceUID thread = 0; + if (R_SUCCEEDED(thread = sceKernelCreateThread("vlffm_callback_thread", CallbackThread, 0x11, 0xFA0, 0, 0))) { + sceKernelStartThread(thread, 0, 0); + } + + return thread; +} + +void LoadStartModuleBuffer(const char *path, const void *buf, int size, SceSize args, void *argp) { + SceUID mod, out; + + sceIoRemove(path); + out = sceIoOpen(path, PSP_O_WRONLY | PSP_O_CREAT, 0777); + sceIoWrite(out, buf, size); + sceIoClose(out); + + mod = sceKernelLoadModule(path, 0, NULL); + mod = sceKernelStartModule(mod, args, argp, NULL, NULL); + sceIoRemove(path); +} + +int start_thread(SceSize args, void *argp) { + char *path = (char *)argp; + int last_trail = -1; + + for(int i = 0; path[i]; i++) { + if (path[i] == '/') { + last_trail = i; + } + } + + if (last_trail >= 0) { + path[last_trail] = 0; + } + + sceIoChdir(path); + path[last_trail] = '/'; + + LoadStartModuleBuffer("fs_driver.prx", fs_driver_prx_start, fs_driver_prx_size, args, argp); + LoadStartModuleBuffer("intraFont.prx", intraFont_prx_start, intraFont_prx_size, args, argp); + LoadStartModuleBuffer("iop.prx", iop_prx_start, iop_prx_size, args, argp); + LoadStartModuleBuffer("vlf.prx", vlf_prx_start, vlf_prx_size, args, argp); + + vlfGuiInit(20480, app_main); + return sceKernelExitDeleteThread(0); +} + +int module_start(SceSize args, void *argp) { + SetupCallbacks(); + + SceUID thread = 0; + if (R_FAILED(thread = sceKernelCreateThread("vlffm_start_thread", start_thread, 0x10, 0x4000, 0, NULL))) { + return thread; + } + + sceKernelStartThread(thread, args, argp); + return 0; +} diff --git a/app/source/fs.c b/app/source/fs.c new file mode 100644 index 0000000..f67dd02 --- /dev/null +++ b/app/source/fs.c @@ -0,0 +1,548 @@ +#include +#include +#include +#include + +#include "fs.h" +#include "kernel.h" +#include "utils.h" + +// Following FS code using linked list is from VitaShell by TheOfficialFloW with slight +// modifications to use pspsdk instead of vitasdk and without VitaShell specific changes +// https://github.com/TheOfficialFloW/VitaShell/blob/master/file.c + +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) + +char g_cwd[FS_MAX_PATH] = { 0 }; +FsFileList g_file_list = { 0 }; + +static const int buf_size = 0x10000; + +static bool fsHasEndSlash(const char *path) { + return path[strlen(path) - 1] == '/'; +} + +static void fsAddEntry(FsFileList *list, FsFileListEntry *entry) { + if ((!list) || (!entry)) { + return; + } + + entry->next = NULL; + entry->previous = NULL; + + if (list->head == NULL) { + list->head = entry; + list->tail = entry; + } + else { + FsFileListEntry *p = list->head; + FsFileListEntry *previous = NULL; + + char entry_name[FS_MAX_PATH]; + strcpy(entry_name, entry->name); + + while (p) { + char p_name[FS_MAX_PATH]; + strcpy(p_name, p->name); + + // '..' is always at first + if (strcmp(entry_name, "..") == 0) { + break; + } + + if (strcmp(p_name, "..") == 0) { + previous = p; + p = p->next; + continue; + } + + // First folders then files + if (entry->is_folder > p->is_folder) { + break; + } + + // Sort by name within the same type + if (entry->is_folder == p->is_folder) { + if (strcasecmp(entry_name, p_name) < 0) { + break; + } + } + + previous = p; + p = p->next; + } + + if (previous == NULL) { // Order: entry (new head) -> p (old head) + entry->next = p; + p->previous = entry; + list->head = entry; + } + else if (previous->next == NULL) { // Order: p (old tail) -> entry (new tail) + FsFileListEntry *tail = list->tail; + tail->next = entry; + entry->previous = tail; + list->tail = entry; + } + else { // Order: previous -> entry -> p + previous->next = entry; + entry->previous = previous; + entry->next = p; + p->previous = entry; + } + } + + list->length++; +} + +int fsGetDirectoryEntries(FsFileList *list, const char *path) { + if (!list) { + return -1; + } + + SceUID dfd = 0; + if (R_FAILED(dfd = pspIoOpenDir(path))) { + utilsLogError("%s: pspIoOpenDir(%s) failed: 0x%x\n", __func__, path, dfd); + return dfd; + } + + int res = 0; + + do { + SceIoDirent dir; + memset(&dir, 0, sizeof(SceIoDirent)); + + res = pspIoReadDir(dfd, &dir); + if (res > 0) { + if (strcmp(dir.d_name, ".") == 0) { + continue; + } + + FsFileListEntry *entry = malloc(sizeof(FsFileListEntry)); + + if (entry) { + entry->is_folder = FIO_S_ISDIR(dir.d_stat.st_mode); + + if (entry->is_folder) { + entry->name_length = strlen(dir.d_name) + 1; + entry->name = malloc(entry->name_length + 1); + strcpy(entry->name, dir.d_name); + list->folders++; + } + else { + entry->name_length = strlen(dir.d_name); + entry->name = malloc(entry->name_length + 1); + strcpy(entry->name, dir.d_name); + list->files++; + } + + entry->size = dir.d_stat.st_size; + memcpy(&entry->time, &dir.d_stat.sce_st_mtime, sizeof(ScePspDateTime)); + fsAddEntry(list, entry); + } + } + } while (res > 0); + + pspIoCloseDir(dfd); + return 0; +} + +void fsFreeDirectoryEntries(FsFileList *list) { + if (!list) { + return; + } + + FsFileListEntry *entry = list->head; + + while (entry) { + FsFileListEntry *next = entry->next; + free(entry->name); + free(entry); + entry = next; + } + + list->head = NULL; + list->tail = NULL; + list->length = 0; + list->files = 0; + list->folders = 0; +} + +int fsAppendDir(FsFileList *list, const char *path) { + char cwd[FS_MAX_PATH] = { 0 }; + + if ((snprintf(cwd, FS_MAX_PATH, "%s%s%s", g_cwd, fsHasEndSlash(g_cwd) ? "" : "/", path)) > 0) { + strncpy(g_cwd, cwd, FS_MAX_PATH); + fsFreeDirectoryEntries(list); + + int ret = 0; + if (R_FAILED(ret = fsGetDirectoryEntries(list, g_cwd))) { + return ret; + } + } + + return 0; +} + +int fsParentDir(FsFileList *list) { + int cwd_len = strlen(g_cwd); + + if (g_cwd[(cwd_len - 1)] == '/') { + return 1; + } + + bool copy = false; + char cwd[FS_MAX_PATH] = { 0 }; + int len = 0; + + for (int i = cwd_len; i >= 0; i--) { + if (g_cwd[i] == '/') { + copy = true; + } + if (copy) { + cwd[i] = g_cwd[i]; + len++; + } + } + + if (len > 1 && cwd[len - 1] == '/') { + len--; + } + + cwd[len] = '\0'; + + if (cwd[len - 1] == ':') { + snprintf(g_cwd, 257, "%s/", cwd); + } + else { + strncpy(g_cwd, cwd, FS_MAX_PATH); + } + + fsFreeDirectoryEntries(list); + + int ret = 0; + if (R_FAILED(ret = fsGetDirectoryEntries(list, g_cwd))) { + return ret; + } + + return 0; +} + +const char *fsSetPath(FsFileListEntry *entry, const char *path) { + static char new_path[FS_MAX_PATH] = { 0 }; + if (R_FAILED(snprintf(new_path, FS_MAX_PATH, "%s%s%s", g_cwd, fsHasEndSlash(g_cwd) ? "" : "/", path == NULL? entry->name : path))) { + return NULL; + } + + return new_path; +} + +static int fsCopyFile(const char *src_path, const char *dest_path, FileProcessParam *param) { + // The source and destination paths are identical + if (strcasecmp(src_path, dest_path) == 0) { + return -1; + } + + // The destination is a subfolder of the source folder + int len = strlen(src_path); + if (strncasecmp(src_path, dest_path, len) == 0 && (dest_path[len] == '/' || dest_path[len - 1] == '/')) { + return -2; + } + + SceUID src_fd = 0; + if (R_FAILED(src_fd = pspIoOpenFile(src_path, PSP_O_RDONLY, 0))) { + utilsLogError("%s: pspIoOpenFile(%s) failed: 0x%x\n", __func__, src_path, src_fd); + return src_fd; + } + + u64 size = pspIoLseek(src_fd, 0, PSP_SEEK_END); + pspIoLseek(src_fd, 0, PSP_SEEK_SET); + + SceUID dest_fd = 0; + if (R_FAILED(dest_fd = pspIoOpenFile(dest_path, PSP_O_WRONLY | PSP_O_CREAT | PSP_O_TRUNC, 0777))) { + utilsLogError("%s: pspIoOpenFile(%s) failed: 0x%x\n", __func__, dest_path, dest_fd); + pspIoCloseFile(src_fd); + return dest_fd; + } + + u8 *buf = malloc(buf_size); + if (buf == NULL) { + return -3; + } + + memset(buf, 0, buf_size); + u64 offset = 0; + + do { + int ret = 0, read = 0; + if (R_FAILED(ret = read = pspIoReadFile(src_fd, buf, buf_size))) { + utilsLogError("%s: pspIoReadFile(%s) failed: 0x%08x\n", __func__, src_path, ret); + pspIoCloseFile(dest_fd); + pspIoCloseFile(src_fd); + free(buf); + return ret; + } + + offset += read; + + if (R_FAILED(ret = pspIoWriteFile(dest_fd, buf, read))) { + utilsLogError("%s: pspIoWriteFile(%s) failed: 0x%08x\n", __func__, dest_path, ret); + pspIoCloseFile(dest_fd); + pspIoCloseFile(src_fd); + free(buf); + return ret; + } + + if (param) { + param->max = size; + param->value = offset; + + if (param->setProgress) { + param->setProgress(param->value ? param->value : 0, param->max); + } + + if (param->cancelHandler && param->cancelHandler()) { + pspIoCloseFile(dest_fd); + pspIoCloseFile(src_fd); + free(buf); + return 0; + } + } + } while (offset < size); + + pspIoCloseFile(dest_fd); + pspIoCloseFile(src_fd); + free(buf); + return 1; +} + +int fsCopyPath(const char *src_path, const char *dest_path, FileProcessParam *param) { + // The source and destination paths are identical + if (strcasecmp(src_path, dest_path) == 0) { + return -1; + } + + // The destination is a subfolder of the source folder + size_t len = strlen(src_path); + if (strncasecmp(src_path, dest_path, len) == 0 && (dest_path[len] == '/' || dest_path[len - 1] == '/')) { + return -2; + } + + SceUID dfd = pspIoOpenDir(src_path); + if (dfd >= 0) { + int ret = 0; + if (R_FAILED(ret = pspIoMakeDir(dest_path, 0777))) { + utilsLogError("%s: pspIoMakeDir(%s) failed: 0x%08x\n", __func__, dest_path, ret); + pspIoCloseDir(dfd); + return ret; + } + + if (param) { + // if (param->value) { + // (param->value)++; + // } + + // if (param->setProgress) { + // param->setProgress(param->value ? param->value : 0, param->max); + // } + + if (param->cancelHandler && param->cancelHandler()) { + pspIoCloseDir(dfd); + return 0; + } + } + + int res = 0; + + do { + SceIoDirent dir; + memset(&dir, 0, sizeof(SceIoDirent)); + + res = pspIoReadDir(dfd, &dir); + if (res > 0) { + if (strcmp(dir.d_name, ".") == 0 || strcmp(dir.d_name, "..") == 0) { + continue; + } + + len = strlen(src_path) + strlen(dir.d_name) + 2; + char new_src_path[len]; + memset(new_src_path, 0, len); + snprintf(new_src_path, len, "%s%s%s", src_path, fsHasEndSlash(src_path) ? "" : "/", dir.d_name); + + len = strlen(dest_path) + strlen(dir.d_name) + 2; + char new_dest_path[len]; + memset(new_dest_path, 0, len); + snprintf(new_dest_path, len, "%s%s%s", dest_path, fsHasEndSlash(dest_path) ? "" : "/", dir.d_name); + + if (FIO_S_ISDIR(dir.d_stat.st_mode)) { + ret = fsCopyPath(new_src_path, new_dest_path, param); + } + else { + ret = fsCopyFile(new_src_path, new_dest_path, param); + } + + if (ret <= 0) { + pspIoCloseDir(dfd); + return ret; + } + } + } while (res > 0); + + pspIoCloseDir(dfd); + } + else { + return fsCopyFile(src_path, dest_path, param); + } + + return 1; +} + +int fsMovePath(const char *src_path, const char *dest_path) { + int ret = 0; + size_t i = 0; + char strage[32] = { 0 }; + char *p1 = NULL, *p2 = NULL; + + p1 = strchr(src_path, ':'); + if (p1 == NULL) { + return -1; + } + + p2 = strchr(dest_path, ':'); + if (p2 == NULL) { + return -2; + } + + if ((p1 - src_path) != (p2 - dest_path)) { + return -3; + } + + for (i = 0; (src_path + i) <= p1; i++) { + if ((i+1) >= sizeof(strage)) { + return -4; + } + + if (src_path[i] != dest_path[i]) { + return -5; + } + + strage[i] = src_path[i]; + } + + strage[i] = '\0'; + + u32 data[2] = { 0 }; + data[0] = (u32)(p1 + 1); + data[1] = (u32)(p2 + 1); + + if (R_FAILED(ret = pspIoDevctl(strage, 0x02415830, &data, sizeof(data), NULL, 0))) { + utilsLogError("%s: pspIoDevctl(%s, %s) failed: 0x%08x\n", __func__, src_path, dest_path, ret); + return ret; + } + + return 0; +} + +int fsDelete(const char *path, FileProcessParam *param) { + SceUID dfd = pspIoOpenDir(path); + if (dfd >= 0) { + int res = 0; + + do { + SceIoDirent dir; + memset(&dir, 0, sizeof(SceIoDirent)); + + res = pspIoReadDir(dfd, &dir); + if (res > 0) { + if (strcmp(dir.d_name, ".") == 0 || strcmp(dir.d_name, "..") == 0) { + continue; + } + + size_t len = strlen(path) + strlen(dir.d_name) + 2; + char new_path[512] = { 0 }; + memset(new_path, 0, len); + snprintf(new_path, 512, "%s%s%s", path, fsHasEndSlash(path) ? "" : "/", dir.d_name); + + if (FIO_S_ISDIR(dir.d_stat.st_mode)) { + int ret = fsDelete(new_path, param); + if (ret <= 0) { + utilsLogError("%s: fsDelete(%s) failed: 0x%08x\n", __func__, new_path, ret); + pspIoCloseDir(dfd); + return ret; + } + } + else { + int ret = 0; + if (R_FAILED(ret = pspIoRemoveFile(new_path))) { + utilsLogError("%s: pspIoRemoveFile(%s) failed: 0x%08x\n", __func__, new_path, ret); + pspIoCloseDir(dfd); + return ret; + } + + if (param) { + if (param->value) { + (param->value)++; + } + + if (param->setProgress) { + param->setProgress(param->value ? param->value : 0, param->max); + } + + if (param->cancelHandler && param->cancelHandler()) { + pspIoCloseDir(dfd); + return 0; + } + } + } + } + } while (res > 0); + + int ret = 0; + if (R_FAILED(ret = pspIoCloseDir(dfd))) { + utilsLogError("%s: pspIoCloseDir(%s) failed: 0x%08x\n", __func__, path, ret); + return ret; + } + + if (R_FAILED(ret = pspIoRemoveDir(path))) { + utilsLogError("%s: pspIoRemoveDir(%s) failed: 0x%08x\n", __func__, path, ret); + return ret; + } + + + if (param) { + if (param->value) { + (param->value)++; + } + + if (param->setProgress) { + param->setProgress(param->value ? param->value : 0, param->max); + } + + if (param->cancelHandler && param->cancelHandler()) { + return 0; + } + } + } + else { + int ret = 0; + if (R_FAILED(ret = pspIoRemoveFile(path))) { + utilsLogError("%s: pspIoRemoveFile(%s) failed: 0x%08x\n", __func__, path, ret); + return ret; + } + + if (param) { + if (param->value) { + (param->value)++; + } + + if (param->setProgress) { + param->setProgress(param->value ? param->value : 0, param->max); + } + + if (param->cancelHandler && param->cancelHandler()) { + return 0; + } + } + } + + return 0; +} diff --git a/app/source/gui.c b/app/source/gui.c new file mode 100644 index 0000000..c14f106 --- /dev/null +++ b/app/source/gui.c @@ -0,0 +1,596 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fs.h" +#include "gui.h" +#include "utils.h" +#include "vlf.h" + +#define NUM_GUI_CONTEXT_MENU_ITEMS 4 + +enum GuiContextMenuItems { + GUI_CONTEXT_MENU_PROPERTIES, + GUI_CONTEXT_MENU_COPY, + GUI_CONTEXT_MENU_MOVE, + GUI_CONTEXT_MENU_DELETE +}; + +enum GuiCopyActionFlags { + GUI_COPY_ACTION_NONE, + GUI_COPY_ACTION_COPY_PATH, + GUI_COPY_ACTION_MOVE_PATH +}; + +enum GuiDeviceList { + GUI_DEVICE_MS0, + GUI_DEVICE_FLASH0, + GUI_DEVICE_FLASH1, + GUI_DEVICE_FLASH2, + GUI_DEVICE_FLASH3, + GUI_DEVICE_DISC0 +}; + +typedef struct { + bool enabled; + u8 copy_flag; + char filename[FS_MAX_PATH]; + char path[FS_MAX_PATH]; +} GuiContextMenu; + +typedef struct { + int start; + int selected; + GuiContextMenu context_menu; + VlfText text[11]; + VlfText cwd; + VlfScrollBar scrollbar; + VlfProgressBar progressbar; + FsFileListEntry *entry; +} GuiFileList; + +extern unsigned char backgrounds_bmp_start[]; + +static const int start_y = 50, max_entries = 11, scrollbar_height = 222, colour = 16; +static GuiFileList gui = { 0 }; +static bool file_op_flag = false; + +static void guiDisplayDeviceList(void); +static void guiClearEventHandlers(void); + +static void guiSetTitle(char *fmt, ...) { + char text[32] = { 0 }; + va_list list; + VlfText title_text = NULL; + VlfPicture title_pic = NULL; + + va_start(list, fmt); + vsnprintf(text, 32, fmt, list); + va_end(list); + + if (title_text != NULL) { + vlfGuiRemoveText(title_text); + } + + if (title_pic != NULL) { + vlfGuiRemovePicture(title_pic); + } + + title_text = vlfGuiAddText(0, 0, text); + title_pic = vlfGuiAddPictureResource("dd_helper.rco", "tex_folder", 4, -1); + vlfGuiSetTitleBarEx(title_text, NULL, 1, 0, colour); +} + +static void guiSetBackground(void) { + vlfGuiSetBackgroundFileBuffer(backgrounds_bmp_start + colour * 6176, 6176, 1); +} + +static void guiSetScrollbar(void) { + if (gui.scrollbar == NULL) { + gui.scrollbar = vlfGuiAddScrollBar(475, start_y, scrollbar_height, ((((float)max_entries/(float)g_file_list.length) * (float)scrollbar_height))); + } +} + +static void guiSetSecondaryTitle(const char *title) { + if (gui.cwd != NULL) { + vlfGuiRemoveText(gui.cwd); + } + + gui.cwd = vlfGuiAddTextF(240, 25, strlen(title) > 45? "%.45s..." : "%s", title); + vlfGuiSetTextAlignment(gui.cwd, VLF_ALIGNMENT_CENTER); +} + +static void guiDisplayErrorDialog(void) { + vlfGuiMessageDialog(g_err_string, VLF_MD_BUTTONS_NONE); + memset(g_err_string, 0, 1024); +} + +static void guiDisplayFileBrowser(bool init) { + const int sel_dist = 20, height = 20; + + if (init) { + gui.entry = g_file_list.head; + } + + guiSetSecondaryTitle(g_cwd); + const int max = g_file_list.length > max_entries? max_entries : g_file_list.length; + + for (int i = gui.start, counter = 0; i < max || counter < max; i++, counter++) { + gui.text[counter] = vlfGuiAddTextF(15, start_y + ((sel_dist - height) / 2) + (i - gui.start) * sel_dist, + strlen(gui.entry->name) > 45? "%.45s..." : "%s%s", gui.entry->name, gui.entry->is_folder? "/" : ""); + gui.entry = gui.entry->next; + } + + if (init) { + vlfGuiSetTextFocus(gui.text[gui.selected]); + + if (g_file_list.length > max_entries) { + guiSetScrollbar(); + } + } +} + +static void guiClearFileList(void) { + for (int i = 0; i < max_entries; i++) { + if (gui.text[i] != NULL) { + vlfGuiRemoveText(gui.text[i]); + gui.text[i] = NULL; + } + } +} + +static void guiClearScrollbar(void) { + if (gui.scrollbar != NULL) { + vlfGuiRemoveScrollBar(gui.scrollbar); + gui.scrollbar = NULL; + } +} + +static void guiGetEntry(void) { + gui.entry = g_file_list.head; + + for (int i = 0; i < gui.selected; i++) { + gui.entry = gui.entry->next; + } +} + +static void guiRefreshFileList(bool init) { + guiClearFileList(); + gui.entry = g_file_list.head; + + for (int i = 0; i < gui.start; i++) { + gui.entry = gui.entry->next; + } + + if (gui.scrollbar != NULL) { + vlfGuiMoveScrollBarSlider(gui.scrollbar, (((float)gui.start/(float)g_file_list.length) * (float)scrollbar_height)); + } + + guiDisplayFileBrowser(init); + vlfGuiDrawFrame(); +} + +static void guiDisplayProperties(void) { + char message[512] = { 0 }; + char size[16] = { 0 }; + + utilsGetSizeString(size, gui.entry->size); + snprintf(message, 512, "Properties:\n\nName: %s\nSize: %s\nModified: %d/%d/%d %02d:%02d\n", + gui.entry->name, + gui.entry->is_folder? "-" : size, + gui.entry->time.year, gui.entry->time.month, gui.entry->time.day, gui.entry->time.hour, gui.entry->time.minute + ); + + vlfGuiMessageDialog(message, VLF_MD_BUTTONS_NONE); +} + +static void guiFileProcessSetProgress(int value, int max) { + if (gui.progressbar == NULL) { + gui.progressbar = vlfGuiAddProgressBar(136); + } + + if (gui.progressbar != NULL) { + vlfGuiProgressBarSetProgress(gui.progressbar, (float)value/(float)max * 100.f); + vlfGuiDrawFrame(); + } +} + +static void guiSetCopyFlag(u8 value) { + if (value > 0) { + gui.context_menu.copy_flag = value; + } + + snprintf(gui.context_menu.filename, FS_MAX_PATH, gui.entry->name); + snprintf(gui.context_menu.path, FS_MAX_PATH, fsSetPath(gui.entry, NULL)); + + gui.context_menu.enabled = false; + vlfGuiCancelLateralMenu(); +} + +static void guiResetContextMenu(u8 *flag) { + if (flag) { + *flag = GUI_COPY_ACTION_NONE; + } + + file_op_flag = false; + memset(gui.context_menu.filename, 0, FS_MAX_PATH); + memset(gui.context_menu.path, 0, FS_MAX_PATH); + + if (gui.progressbar != NULL) { + vlfGuiRemoveProgressBar(gui.progressbar); + gui.progressbar = NULL; + } + + guiGetEntry(); + fsFreeDirectoryEntries(&g_file_list); + fsGetDirectoryEntries(&g_file_list, g_cwd); + guiClearScrollbar(); + + gui.start = 0; + gui.selected = 0; + + guiRefreshFileList(true); +} + +static int guiControlContextMenuSelection(int selection) { + switch (selection) { + case GUI_CONTEXT_MENU_PROPERTIES: + guiDisplayProperties(); + break; + + case GUI_CONTEXT_MENU_COPY: + if (gui.context_menu.copy_flag == GUI_COPY_ACTION_NONE) { + guiSetCopyFlag(GUI_COPY_ACTION_COPY_PATH); + } + else { + file_op_flag = true; + FileProcessParam file_process_param = { 0 }; + file_process_param.setProgress = guiFileProcessSetProgress; + + gui.context_menu.enabled = false; + vlfGuiRemoveTextFocus(gui.text[gui.selected - gui.start], 1); + vlfGuiCancelLateralMenu(); + vlfGuiSetRectangleVisibility(0, 50, 480, 222, 0); + + char progress_message[512]; + snprintf(progress_message, 512, "Copying: %s", gui.context_menu.filename); + VlfText progress_text = vlfGuiAddText(240, 110, progress_message); + vlfGuiSetTextAlignment(progress_text, VLF_ALIGNMENT_CENTER); + + if (R_FAILED(fsCopyPath(gui.context_menu.path, fsSetPath(gui.entry, gui.context_menu.filename), &file_process_param))) { + guiDisplayErrorDialog(); + } + + if (progress_text != NULL) { + vlfGuiRemoveText(progress_text); + progress_text = NULL; + } + + vlfGuiSetRectangleVisibility(0, 50, 480, 222, 1); + guiResetContextMenu(&gui.context_menu.copy_flag); + } + break; + + case GUI_CONTEXT_MENU_MOVE: + if (gui.context_menu.copy_flag == GUI_COPY_ACTION_NONE) { + guiSetCopyFlag(GUI_COPY_ACTION_MOVE_PATH); + } + else { + gui.context_menu.enabled = false; + vlfGuiRemoveTextFocus(gui.text[gui.selected - gui.start], 1); + vlfGuiCancelLateralMenu(); + + if (R_FAILED(fsMovePath(gui.context_menu.path, fsSetPath(gui.entry, gui.context_menu.filename)))) { + guiDisplayErrorDialog(); + } + + guiResetContextMenu(&gui.context_menu.copy_flag); + } + break; + + case GUI_CONTEXT_MENU_DELETE: + char message[512] = { 0 }; + snprintf(message, 512, "This action cannot be undone. Do you wish to delete %s?", gui.entry->name); + int button_res = vlfGuiMessageDialog(message, VLF_MD_BUTTONS_YESNO | VLF_MD_INITIAL_CURSOR_NO); + + if (button_res == VLF_MD_YES) { + file_op_flag = true; + if (R_FAILED(fsDelete(fsSetPath(gui.entry, NULL), NULL))) { + guiDisplayErrorDialog(); + } + + gui.context_menu.enabled = false; + vlfGuiRemoveTextFocus(gui.text[gui.selected - gui.start], 1); + guiResetContextMenu(NULL); + vlfGuiCancelLateralMenu(); + } + break; + } + + return VLF_EV_RET_NOTHING; +} + +static void guiDisplayContextMenu(void) { + char *item_labels[NUM_GUI_CONTEXT_MENU_ITEMS] = { + "Properties", + gui.context_menu.copy_flag == 1? "Paste" : "Copy", + gui.context_menu.copy_flag == 2? "Paste" : "Move", + "Delete" + }; + + vlfGuiLateralMenuEx(NUM_GUI_CONTEXT_MENU_ITEMS, item_labels, 0, guiControlContextMenuSelection, 120, colour); + vlfGuiDrawFrame(); +} + +static int guiControlFileBrowserUp(void *param) { + if (file_op_flag) { + return VLF_EV_RET_NOTHING; + } + + vlfGuiRemoveTextFocus(gui.text[gui.selected - gui.start], 1); + gui.selected--; + + if (gui.selected < 0) { + gui.selected = (g_file_list.length - 1); + } + + if ((g_file_list.length - 1) < max_entries) { + gui.start = 0; + guiRefreshFileList(false); + } + else if (gui.start > gui.selected) { + gui.start--; + guiRefreshFileList(false); + } + else if ((gui.selected == (g_file_list.length - 1)) && ((g_file_list.length - 1) > (max_entries - 1))) { + gui.start = (g_file_list.length - 1) - (max_entries - 1); + guiRefreshFileList(false); + } + + vlfGuiSetTextFocus(gui.text[gui.selected - gui.start]); + return VLF_EV_RET_NOTHING; +} + +static int guiControlFileBrowserDown(void *param) { + if (file_op_flag) { + return VLF_EV_RET_NOTHING; + } + + vlfGuiRemoveTextFocus(gui.text[gui.selected - gui.start], 1); + gui.selected++; + + if (gui.selected > (g_file_list.length - 1)) { + gui.selected = 0; + } + + if ((gui.selected > (gui.start + (max_entries - 1))) && ((gui.start + (max_entries - 1)) < (g_file_list.length - 1))) { + gui.start++; + guiRefreshFileList(false); + } + + if (gui.selected == 0) { + gui.start = 0; + guiRefreshFileList(false); + } + + vlfGuiSetTextFocus(gui.text[gui.selected - gui.start]); + return VLF_EV_RET_NOTHING; +} + +static int guiControlContextMenu(void *param) { + if (file_op_flag) { + return VLF_EV_RET_NOTHING; + } + + gui.context_menu.enabled = !gui.context_menu.enabled; + + if (gui.context_menu.enabled) { + guiGetEntry(); + guiClearScrollbar(); + guiDisplayContextMenu(); + } + else { + vlfGuiCancelLateralMenu(); + guiSetScrollbar(); + } + + return VLF_EV_RET_NOTHING; +} + +static int guiControlFileBrowserEnter(void *param) { + if (file_op_flag) { + return VLF_EV_RET_NOTHING; + } + + guiGetEntry(); + + if (!gui.entry->is_folder) { + return VLF_EV_RET_NOTHING; + } + + vlfGuiRemoveTextFocus(gui.text[gui.selected - gui.start], 1); + + if (strncasecmp(gui.entry->name, "..", 2) == 0) { + if (R_FAILED(fsParentDir(&g_file_list))) { + guiDisplayErrorDialog(); + } + } + else if (gui.entry->is_folder) { + if (R_FAILED(fsAppendDir(&g_file_list, gui.entry->name))) { + guiDisplayErrorDialog(); + } + } + + guiClearScrollbar(); + + gui.start = 0; + gui.selected = 0; + + guiRefreshFileList(true); + return VLF_EV_RET_NOTHING; +} + +static int guiControlFileBrowserCancel(void *param) { + if (file_op_flag) { + return VLF_EV_RET_NOTHING; + } + + if (gui.context_menu.enabled) { + gui.context_menu.enabled = false; + vlfGuiCancelLateralMenu(); + guiSetScrollbar(); + return VLF_EV_RET_NOTHING; + } + + vlfGuiRemoveTextFocus(gui.text[gui.selected - gui.start], 1); + guiGetEntry(); + int ret = 0; + + if (R_FAILED(ret = fsParentDir(&g_file_list))) { + guiDisplayErrorDialog(); + } + + guiClearScrollbar(); + + gui.start = 0; + gui.selected = 0; + + // Go back to device selection + if (ret == 1) { + guiClearFileList(); + guiClearEventHandlers(); + guiDisplayDeviceList(); + return VLF_EV_RET_NOTHING; + } + + guiRefreshFileList(true); + return VLF_EV_RET_NOTHING; +} + +static void guiClearEventHandlers(void) { + vlfGuiRemoveEventHandler(guiControlFileBrowserUp); + vlfGuiRemoveEventHandler(guiControlFileBrowserDown); + vlfGuiRemoveEventHandler(guiControlContextMenu); + vlfGuiRemoveEventHandler(guiControlFileBrowserEnter); + vlfGuiRemoveEventHandler(guiControlFileBrowserCancel); +} + +static void guiControlFileBrowser(void) { + vlfGuiAddEventHandler(PSP_CTRL_UP, -1, guiControlFileBrowserUp, NULL); + vlfGuiAddEventHandler(PSP_CTRL_DOWN, -1, guiControlFileBrowserDown, NULL); + vlfGuiAddEventHandler(PSP_CTRL_TRIANGLE, -1, guiControlContextMenu, NULL); + vlfGuiAddEventHandler(PSP_KEY_ENTER, -1, guiControlFileBrowserEnter, NULL); + vlfGuiAddEventHandler(PSP_KEY_CANCEL, -1, guiControlFileBrowserCancel, NULL); +} + +static int guiControlDeviceSelection(int selection) { + int ret = 0; + fsFreeDirectoryEntries(&g_file_list); + + switch (selection) { + case GUI_DEVICE_MS0: + strncpy(g_cwd, "ms0:/", 6); + break; + + case GUI_DEVICE_FLASH0: + if ((R_FAILED(ret = sceIoUnassign("flash0:"))) && (ret != 0x80020321)) { + utilsLogError("sceIoUnassign(flash0) failed: 0x%x\n", ret); + } + + if (R_FAILED(ret = sceIoAssign("flash0:", "lflash0:0,0", "flashfat0:", IOASSIGN_RDWR, NULL, 0))) { + utilsLogError("sceIoAssign(flash0) failed: 0x%x\n", ret); + } + + strncpy(g_cwd, "flash0:/", 9); + break; + + case GUI_DEVICE_FLASH1: + if ((R_FAILED(ret = sceIoUnassign("flash1:"))) && (ret != 0x80020321)) { + utilsLogError("sceIoUnassign(flash1) failed: 0x%x\n", ret); + } + + if (R_FAILED(ret = sceIoAssign("flash1:", "lflash0:0,1", "flashfat1:", IOASSIGN_RDWR, NULL, 0))) { + utilsLogError("sceIoAssign(flash1) failed: 0x%x\n", ret); + } + + strncpy(g_cwd, "flash1:/", 9); + break; + + case GUI_DEVICE_FLASH2: + if ((R_FAILED(ret = sceIoUnassign("flash2:"))) && (ret != 0x80020321)) { + utilsLogError("sceIoUnassign(flash2) failed: 0x%x\n", ret); + } + + if (R_FAILED(ret = sceIoAssign("flash2:", "lflash0:0,2", "flashfat2:", IOASSIGN_RDWR, NULL, 0))) { + utilsLogError("sceIoAssign(flash2) failed: 0x%x\n", ret); + } + + strncpy(g_cwd, "flash2:/", 9); + break; + + case GUI_DEVICE_FLASH3: + if ((R_FAILED(ret = sceIoUnassign("flash3:"))) && (ret != 0x80020321)) { + utilsLogError("sceIoUnassign(flash3) failed: 0x%x\n", ret); + } + + if (R_FAILED(ret = sceIoAssign("flash3:", "lflash0:0,3", "flashfat3:", IOASSIGN_RDWR, NULL, 0))) { + utilsLogError("sceIoAssign(flash3) failed: 0x%x\n", ret); + } + + strncpy(g_cwd, "flash3:/", 9); + break; + + case GUI_DEVICE_DISC0: + ret = -1; + + if (sceUmdCheckMedium() != 0) { + if (R_FAILED(ret = sceUmdActivate(1, "disc0:"))) { + utilsLogError("sceUmdActivate(disc0) failed: 0x%x\n", ret); + } + + if (R_FAILED(ret = sceUmdWaitDriveStat(PSP_UMD_READY))) { + utilsLogError("sceUmdWaitDriveStat() failed: 0x%x\n", ret); + } + + strncpy(g_cwd, "disc0:/", 8); + } + else { + utilsLogError("UMD not present.\nPlease insert a UMD into the disc drive."); + } + + break; + } + + if (R_SUCCEEDED(ret)) { + vlfGuiCancelCentralMenu(); + memset(&g_file_list, 0, sizeof(FsFileList)); + fsGetDirectoryEntries(&g_file_list, g_cwd); + guiDisplayFileBrowser(true); + guiControlFileBrowser(); + } + else { + guiDisplayErrorDialog(); + ret = 0; + } + + return 0; +} + +static void guiDisplayDeviceList(void) { + const int num_menu_items = 6; + char *item_labels[] = { "ms0:/", "flash0:/", "flash1:/", "flash2:/", "flash3:/", "disc0:/" }; + + guiSetSecondaryTitle("Devices"); + vlfGuiCentralMenu(num_menu_items, item_labels, 0, guiControlDeviceSelection, 0, 0); +} + +void guiInit(void) { + guiSetTitle("VLFFM v%d.%d", VERSION_MAJOR, VERSION_MINOR); + guiSetBackground(); + guiDisplayDeviceList(); +} diff --git a/app/source/main.c b/app/source/main.c new file mode 100755 index 0000000..8f11242 --- /dev/null +++ b/app/source/main.c @@ -0,0 +1,27 @@ +#include +#include +#include + +#include "gui.h" +#include "utils.h" +#include "vlf.h" + +PSP_MODULE_INFO("VLFFM", PSP_MODULE_USER, VERSION_MAJOR, VERSION_MINOR); +PSP_MAIN_THREAD_ATTR(0); + +static bool running = true; + +int app_main(int argc, char *argv[]) { + PSP_KEY_ENTER = utilsGetEnterButton(); + PSP_KEY_CANCEL = utilsGetCancelButton(); + + vlfGuiSystemSetup(1, 1, 1); + guiInit(); + + while (running) { + vlfGuiDrawFrame(); + } + + sceKernelExitGame(); + return 0; +} diff --git a/app/source/utils.c b/app/source/utils.c new file mode 100644 index 0000000..28b49bf --- /dev/null +++ b/app/source/utils.c @@ -0,0 +1,142 @@ +#include +#include +#include +#include +#include +#include + +#include "utils.h" + +int PSP_KEY_ENTER, PSP_KEY_CANCEL; +char g_err_string[1024]; + +void utilsLogError(const char *error, ...) { + va_list list; + va_start(list, error); + vsprintf(g_err_string, error, list); + va_end(list); + printf(g_err_string); +} + +static int utilsGetRegistryValue(const char *dir, const char *name, unsigned int *value) { + int ret = 0; + struct RegParam reg_param; + REGHANDLE reg_handle = 0, reg_handle_cat = 0, reg_handle_key = 0; + unsigned int type = 0, size = 0; + + memset(®_param, 0, sizeof(struct RegParam)); + reg_param.regtype = 1; + reg_param.namelen = strlen("/system"); + reg_param.unk2 = 1; + reg_param.unk3 = 1; + strcpy(reg_param.name, "/system"); + + if (R_FAILED(ret = sceRegOpenRegistry(®_param, 2, ®_handle))) { + utilsLogError("sceRegOpenRegistry() failed: 0x%08x\n", ret); + return ret; + } + + if (R_FAILED(ret = sceRegOpenCategory(reg_handle, dir, 2, ®_handle_cat))) { + sceRegCloseRegistry(reg_handle); + utilsLogError("sceRegOpenCategory() failed: 0x%08x\n", ret); + return ret; + } + + if (R_FAILED(ret = sceRegGetKeyInfo(reg_handle_cat, name, ®_handle_key, &type, &size))) { + sceRegCloseCategory(reg_handle_cat); + sceRegCloseRegistry(reg_handle); + utilsLogError("sceRegGetKeyInfo() failed: 0x%08x\n", ret); + return ret; + } + + if (R_FAILED(ret = sceRegGetKeyValue(reg_handle_cat, reg_handle_key, value, 4))) { + sceRegCloseCategory(reg_handle_cat); + sceRegCloseRegistry(reg_handle); + utilsLogError("sceRegGetKeyValue() failed: 0x%08x\n", ret); + return ret; + } + + if (R_FAILED(ret = sceRegFlushCategory(reg_handle_cat))) { + sceRegCloseCategory(reg_handle_cat); + sceRegCloseRegistry(reg_handle); + utilsLogError("sceRegFlushCategory() failed: 0x%08x\n", ret); + return ret; + } + + if (R_FAILED(ret = sceRegCloseCategory(reg_handle_cat))) { + sceRegCloseRegistry(reg_handle); + utilsLogError("sceRegCloseCategory() failed: 0x%08x\n", ret); + return ret; + } + + if (R_FAILED(ret = sceRegFlushRegistry(reg_handle))) { + sceRegCloseRegistry(reg_handle); + utilsLogError("sceRegFlushRegistry() failed: 0x%08x\n", ret); + return ret; + } + + if (R_FAILED(ret = sceRegCloseRegistry(reg_handle))) { + utilsLogError("sceRegFlushRegistry() failed: 0x%08x\n", ret); + return ret; + } + + return 0; +} + +int utilsGetEnterButton(void) { + int ret = 0, button = -1; + + if (R_FAILED(ret = sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_UNKNOWN, &button))) { + utilsLogError("sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_UNKNOWN) failed: 0x%08x\n", ret); + unsigned int reg_button = -1; + + if (R_SUCCEEDED(utilsGetRegistryValue("/CONFIG/SYSTEM/XMB", "button_assign", ®_button))) { + if (reg_button == 0) { + return PSP_CTRL_CIRCLE; + } + + return PSP_CTRL_CROSS; + } + } + + if (button == 0) { + return PSP_CTRL_CIRCLE; + } + + return PSP_CTRL_CROSS; +} + +int utilsGetCancelButton(void) { + int ret = 0, button = -1; + + if (R_FAILED(ret = sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_UNKNOWN, &button))) { + utilsLogError("sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_UNKNOWN) failed: 0x%08x\n", ret); + unsigned int reg_button = -1; + + if (R_SUCCEEDED(utilsGetRegistryValue("/CONFIG/SYSTEM/XMB", "button_assign", ®_button))) { + if (reg_button == 0) { + return PSP_CTRL_CROSS; + } + + return PSP_CTRL_CIRCLE; + } + } + + if (button == 0) { + return PSP_CTRL_CROSS; + } + + return PSP_CTRL_CIRCLE; +} + +void utilsGetSizeString(char *string, int size) { + int i = 0; + const char *units[] = {"B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"}; + + while (size >= 1024.f) { + size /= 1024.f; + i++; + } + + sprintf(string, "%.*f %s", (i == 0) ? 0 : 2, (double)size, units[i]); +} diff --git a/fs_driver/Makefile b/fs_driver/Makefile new file mode 100644 index 0000000..d4a9b1c --- /dev/null +++ b/fs_driver/Makefile @@ -0,0 +1,27 @@ +TARGET = fs_driver +OBJS = fs_driver.o exports.o + +PRX_EXPORTS = exports.exp + +# Use the kernel's small inbuilt libc +USE_KERNEL_LIBC = 1 +# Use only kernel libraries +USE_KERNEL_LIBS = 1 + +INCDIR = ../libs/include +CFLAGS = -Os -G0 -Wall -fno-builtin-printf +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = ../libs/lib + +LDFLAGS = -nostartfiles +LIBS = -lpspsystemctrl_kernel + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build_prx.mak + +all: + psp-build-exports -s $(PRX_EXPORTS) + mv fs_driver.prx "../app/data/" + mkdir "../app/drivers/"; mv fs_driver.S "../app/drivers/" diff --git a/fs_driver/exports.exp b/fs_driver/exports.exp new file mode 100644 index 0000000..382f723 --- /dev/null +++ b/fs_driver/exports.exp @@ -0,0 +1,30 @@ +# Define the exports for the prx +PSP_BEGIN_EXPORTS + +# These four lines are mandatory (although you can add other functions like module_stop) +# syslib is a psynonym for the single mandatory export. +PSP_EXPORT_START(syslib, 0, 0x8000) +PSP_EXPORT_FUNC(module_start) +PSP_EXPORT_FUNC(module_stop) +PSP_EXPORT_VAR(module_info) +PSP_EXPORT_END + +PSP_EXPORT_START(fs_driver, 0, 0x4001) +PSP_EXPORT_FUNC(pspIoOpenDir) +PSP_EXPORT_FUNC(pspIoReadDir) +PSP_EXPORT_FUNC(pspIoCloseDir) +PSP_EXPORT_FUNC(pspIoMakeDir) +PSP_EXPORT_FUNC(pspIoRemoveDir) +PSP_EXPORT_FUNC(pspIoOpenFile) +PSP_EXPORT_FUNC(pspIoReadFile) +PSP_EXPORT_FUNC(pspIoWriteFile) +PSP_EXPORT_FUNC(pspIoCloseFile) +PSP_EXPORT_FUNC(pspIoLseek) +PSP_EXPORT_FUNC(pspIoLseek32) +PSP_EXPORT_FUNC(pspIoGetstat) +PSP_EXPORT_FUNC(pspIoRename) +PSP_EXPORT_FUNC(pspIoRemoveFile) +PSP_EXPORT_FUNC(pspIoDevctl) +PSP_EXPORT_END + +PSP_END_EXPORTS diff --git a/fs_driver/fs_driver.c b/fs_driver/fs_driver.c new file mode 100644 index 0000000..698b6f7 --- /dev/null +++ b/fs_driver/fs_driver.c @@ -0,0 +1,180 @@ +#include +#include + +#include "systemctrl.h" + +PSP_MODULE_INFO("fs_driver", PSP_MODULE_KERNEL, 1, 0); +PSP_NO_CREATE_MAIN_THREAD(); + +int pspIoOpenDir(const char *dirname) { + u32 k1 = pspSdkSetK1(0); + int level = sctrlKernelSetUserLevel(8); + + int ret = sceIoDopen(dirname); + + pspSdkSetK1(k1); + sctrlKernelSetUserLevel(level); + return ret; +} + +int pspIoReadDir(SceUID dir, SceIoDirent *dirent) { + u32 k1 = pspSdkSetK1(0); + int level = sctrlKernelSetUserLevel(8); + + int ret = sceIoDread(dir, dirent); + + pspSdkSetK1(k1); + sctrlKernelSetUserLevel(level); + return ret; +} + +int pspIoCloseDir(SceUID dir) { + u32 k1 = pspSdkSetK1(0); + int level = sctrlKernelSetUserLevel(8); + + int ret = sceIoDclose(dir); + + pspSdkSetK1(k1); + sctrlKernelSetUserLevel(level); + return ret; +} + +int pspIoMakeDir(const char *dir, SceMode mode) { + u32 k1 = pspSdkSetK1(0); + int level = sctrlKernelSetUserLevel(8); + + int ret = sceIoMkdir(dir, mode); + + pspSdkSetK1(k1); + sctrlKernelSetUserLevel(level); + return ret; +} + +int pspIoRemoveDir(const char *path) { + u32 k1 = pspSdkSetK1(0); + int level = sctrlKernelSetUserLevel(8); + + int ret = sceIoRmdir(path); + + pspSdkSetK1(k1); + sctrlKernelSetUserLevel(level); + return ret; +} + +int pspIoOpenFile(const char *file, int flags, SceMode mode) { + u32 k1 = pspSdkSetK1(0); + int level = sctrlKernelSetUserLevel(8); + + int ret = sceIoOpen(file, flags, mode); + + pspSdkSetK1(k1); + sctrlKernelSetUserLevel(level); + return ret; +} + +int pspIoReadFile(SceUID file, void *data, SceSize size) { + u32 k1 = pspSdkSetK1(0); + int level = sctrlKernelSetUserLevel(8); + + int ret = sceIoRead(file, data, size); + + pspSdkSetK1(k1); + sctrlKernelSetUserLevel(level); + return ret; +} + +int pspIoWriteFile(SceUID file, const void *data, SceSize size) { + u32 k1 = pspSdkSetK1(0); + int level = sctrlKernelSetUserLevel(8); + + int ret = sceIoWrite(file, data, size); + + pspSdkSetK1(k1); + sctrlKernelSetUserLevel(level); + return ret; +} + +int pspIoCloseFile(SceUID file) { + u32 k1 = pspSdkSetK1(0); + int level = sctrlKernelSetUserLevel(8); + + int ret = sceIoClose(file); + + pspSdkSetK1(k1); + sctrlKernelSetUserLevel(level); + return ret; +} + +int pspIoLseek(SceUID file, SceOff offset, int whence) { + u32 k1 = pspSdkSetK1(0); + int level = sctrlKernelSetUserLevel(8); + + int ret = sceIoLseek(file, offset, whence); + + pspSdkSetK1(k1); + sctrlKernelSetUserLevel(level); + return ret; +} + +int pspIoLseek32(SceUID file, SceOff offset, int whence) { + u32 k1 = pspSdkSetK1(0); + int level = sctrlKernelSetUserLevel(8); + + int ret = sceIoLseek32(file, offset, whence); + + pspSdkSetK1(k1); + sctrlKernelSetUserLevel(level); + return ret; +} + +int pspIoGetstat(const char *file, SceIoStat *stat) { + u32 k1 = pspSdkSetK1(0); + int level = sctrlKernelSetUserLevel(8); + + int ret = sceIoGetstat(file, stat); + + pspSdkSetK1(k1); + sctrlKernelSetUserLevel(level); + return ret; +} + +int pspIoRename(const char *oldname, const char *newname) { + u32 k1 = pspSdkSetK1(0); + int level = sctrlKernelSetUserLevel(8); + + int ret = sceIoRename(oldname, newname); + + pspSdkSetK1(k1); + sctrlKernelSetUserLevel(level); + return ret; +} + +int pspIoRemoveFile(const char *file) { + u32 k1 = pspSdkSetK1(0); + int level = sctrlKernelSetUserLevel(8); + + int ret = sceIoRemove(file); + + pspSdkSetK1(k1); + sctrlKernelSetUserLevel(level); + return ret; +} + +int pspIoDevctl(const char *dev, unsigned int cmd, void *indata, int inlen, void *outdata, int outlen) { + u32 k1 = pspSdkSetK1(0); + int level = sctrlKernelSetUserLevel(8); + + int ret = sceIoDevctl(dev, cmd, indata, inlen, outdata, outlen); + + pspSdkSetK1(k1); + sctrlKernelSetUserLevel(level); + return ret; +} + +int module_start(SceSize args, void *argp) { + return 0; +} + +int module_stop(void) { + return 0; +} diff --git a/libs/include/systemctrl.h b/libs/include/systemctrl.h new file mode 100644 index 0000000..831d087 --- /dev/null +++ b/libs/include/systemctrl.h @@ -0,0 +1,401 @@ +#ifndef __SCTRLLIBRARY_H__ +#define __SCTRLLIBRARY_H__ + +#if defined (__cplusplus) +extern "C" { +#endif + +#include +#include +#include +#include + +enum BootLoadFlags +{ + BOOTLOAD_VSH = 1, + BOOTLOAD_GAME = 2, + BOOTLOAD_UPDATER = 4, + BOOTLOAD_POPS = 8, + BOOTLOAD_UMDEMU = 64, /* for original NP9660 */ +}; + +/** + * Restart the vsh. + * + * @param param - Pointer to a ::SceKernelLoadExecVSHParam structure, or NULL + * + * @returns < 0 on some errors. + * +*/ +int sctrlKernelExitVSH(struct SceKernelLoadExecVSHParam *param); + +/** + * Executes a new executable from a disc. + * It is the function used by the firmware to execute the EBOOT.BIN from a disc. + * + * @param file - The file to execute. + * @param param - Pointer to a ::SceKernelLoadExecVSHParam structure, or NULL. + * + * @returns < 0 on some errors. +*/ +int sctrlKernelLoadExecVSHDisc(const char *file, struct SceKernelLoadExecVSHParam *param); + +/** + * Executes a new executable from a disc. + * It is the function used by the firmware to execute an updater from a disc. + * + * @param file - The file to execute. + * @param param - Pointer to a ::SceKernelLoadExecVSHParam structure, or NULL. + * + * @returns < 0 on some errors. +*/ +int sctrlKernelLoadExecVSHDiscUpdater(const char *file, struct SceKernelLoadExecVSHParam *param); + +/** + * Executes a new executable from a memory stick. + * It is the function used by the firmware to execute an updater from a memory stick. + * + * @param file - The file to execute. + * @param param - Pointer to a ::SceKernelLoadExecVSHParam structure, or NULL. + * + * @returns < 0 on some errors. +*/ +int sctrlKernelLoadExecVSHMs1(const char *file, struct SceKernelLoadExecVSHParam *param); + +/** + * Executes a new executable from a memory stick. + * It is the function used by the firmware to execute games (and homebrew :P) from a memory stick. + * + * @param file - The file to execute. + * @param param - Pointer to a ::SceKernelLoadExecVSHParam structure, or NULL. + * + * @returns < 0 on some errors. +*/ +int sctrlKernelLoadExecVSHMs2(const char *file, struct SceKernelLoadExecVSHParam *param); +int sctrlKernelLoadExecVSHEf2(const char *file, struct SceKernelLoadExecVSHParam *param); + +/** + * Executes a new executable from a memory stick. + * It is the function used by the firmware to execute ... ? + * + * @param file - The file to execute. + * @param param - Pointer to a ::SceKernelLoadExecVSHParam structure, or NULL. + * + * @returns < 0 on some errors. +*/ +int sctrlKernelLoadExecVSHMs3(const char *file, struct SceKernelLoadExecVSHParam *param); + +/** + * Executes a new executable from a memory stick. + * It is the function used by the firmware to execute psx games + * + * @param file - The file to execute. + * @param param - Pointer to a ::SceKernelLoadExecVSHParam structure, or NULL. + * + * @returns < 0 on some errors. +*/ +int sctrlKernelLoadExecVSHMs4(const char *file, struct SceKernelLoadExecVSHParam *param); + + +/** + * Executes a new executable with the specified apitype + * + * @param apitype - The apitype + * @param file - The file to execute. + * @param param - Pointer to a ::SceKernelLoadExecVSHParam structure, or NULL. + * + * @returns < 0 on some errors. +*/ +int sctrlKernelLoadExecVSHWithApitype(int apitype, const char *file, struct SceKernelLoadExecVSHParam *param); + +/** + * Sets the api type + * + * @param apitype - The apitype to set + * @returns the previous apitype + * + * @Note - this will modify also the value of sceKernelBootFrom, since the value of + * bootfrom is calculated from the apitype +*/ +int sctrlKernelSetInitApitype(int apitype); + +/** + * Sets the filename of the launched executable. + * + * @param filename - The filename to set + * @returns 0 on success +*/ +int sctrlKernelSetInitFileName(char *filename); + +/** + * Sets the init key config + * + * @param key - The key code + * @returns the previous key config +*/ +int sctrlKernelSetInitKeyConfig(int key); + +/** + * Sets the user level of the current thread + * + * @param level - The user level + * @return the previous user level on success + */ +int sctrlKernelSetUserLevel(int level); + +/** + * Sets the devkit version + * + * @param version - The devkit version to set + * @return the previous devkit version + * +*/ +int sctrlKernelSetDevkitVersion(int version); + +/** + * Checks if we are in SE. + * + * @returns 1 if we are in SE-C or later, 0 if we are in HEN-D or later, + * and < 0 (a kernel error code) in any other case +*/ +int sctrlHENIsSE(); + +/** + * Checks if we are in Devhook. + * + * @returns 1 if we are in SE-C/HEN-D for devhook or later, 0 if we are in normal SE-C/HEN-D or later, + * and < 0 (a kernel error code) in any other case +*/ +int sctrlHENIsDevhook(); + +/** + * Gets the HEN version + * + * @returns - The HEN version + * + * HEN D / SE-C : 0x00000400 + */ +int sctrlHENGetVersion(); + +/** + * Gets the HEN minor version + * + * @returns - The HEN minor version + */ +int sctrlHENGetMinorVersion(); + +/** + * Finds a driver + * + * @param drvname - The name of the driver (without ":" or numbers) + * + * @returns the driver if found, NULL otherwise + * + */ +PspIoDrv *sctrlHENFindDriver(char *drvname); + +/** + * Finds a function. + * + * @param modname - The module where to search the function + * @param libname - The library name + * @nid - The nid of the function + * + * @returns - The function address or 0 if not found + * +*/ +u32 sctrlHENFindFunction(char *modname, char *libname, u32 nid); + +typedef struct SceModule2 { + struct SceModule2 *next; + unsigned short attribute; + unsigned char version[2]; + char modname[27]; + char terminal; + unsigned int unknown1; + unsigned int unknown2; + SceUID modid; + unsigned int unknown3[2]; + u32 mpid_text; // 0x38 + u32 mpid_data; // 0x3C + void * ent_top; + unsigned int ent_size; + void * stub_top; + unsigned int stub_size; + unsigned int unknown4[5]; + unsigned int entry_addr; + unsigned int gp_value; + unsigned int text_addr; + unsigned int text_size; + unsigned int data_size; + unsigned int bss_size; + unsigned int nsegment; + unsigned int segmentaddr[4]; + unsigned int segmentsize[4]; +} SceModule2; + +typedef int (* STMOD_HANDLER)(SceModule2 *); + +/** + * Sets a function to be called just before module_start of a module is gonna be called (useful for patching purposes) + * + * @param handler - The function, that will receive the module structure before the module is started. + * + * @returns - The previous set function (NULL if none); + * @Note: because only one handler function is handled by HEN, you should + * call the previous function in your code. + * + * @Example: + * + * STMOD_HANDLER previous = NULL; + * + * int OnModuleStart(SceModule2 *mod); + * + * void somepointofmycode() + * { + * previous = sctrlHENSetStartModuleHandler(OnModuleStart); + * } + * + * int OnModuleStart(SceModule2 *mod) + * { + * if (strcmp(mod->modname, "vsh_module") == 0) + * { + * // Do something with vsh module here + * } + * + * if (!previous) + * return 0; + * + * // Call previous handler + * + * return previous(mod); + * } + * + * @Note2: The above example should be compiled with the flag -fno-pic + * in order to avoid problems with gp register that may lead to a crash. + * +*/ +STMOD_HANDLER sctrlHENSetStartModuleHandler(STMOD_HANDLER handler); + +typedef int (* KDEC_HANDLER)(u32 *buf, int size, int *retSize, int m); +typedef int (* MDEC_HANDLER)(u32 *tag, u8 *keys, u32 code, u32 *buf, int size, int *retSize, int m, void *unk0, int unk1, int unk2, int unk3, int unk4); + +/** + * Sets the speed (only for kernel usage) + * + * @param cpu - The cpu speed + * @param bus - The bus speed +*/ +void sctrlHENSetSpeed(int cpu, int bus); + +/** + * Sets the partition 2 and 8 memory for next loadexec. + * + * @param p2 - The size in MB for the user partition. Must be > 0 + * @param p8 - The size in MB for partition 8. Can be 0. + * + * @returns 0 on success, < 0 on error. + * This function is only available in the slim. The function will fail + * if p2+p8 > 52 or p2 == 0 +*/ +int sctrlHENSetMemory(u32 p2, u32 p8); + +void sctrlHENPatchSyscall(void *addr, void *newaddr); + +int sctrlKernelQuerySystemCall(void *func_addr); + +int sctrlKernelBootFrom(void); + +/** + * Patch module by offset + * + * @param modname - module name + * @param inst - instruction + * @param offset - module patch offset + * + * @return < 0 on error + */ +int sctrlPatchModule(char *modname, u32 inst, u32 offset); + +/** + * Get module text address + * + * @param modname - module name + * + * @return text address, or 0 if not found + */ +u32 sctrlModuleTextAddr(char *modname); + +/** + * Get sceInit module text address + * + * @note Only useful before sceInit exits + * + * @return text address, or 0 if not found + */ +u32 sctrlGetInitTextAddr(void); + +/** + * Set custom start module handler + * It can be used to replace a system module + * + * @note: func returns -1 to ignore the module and load the original module. Or new modid if replace is done. + */ +void sctrlSetCustomStartModule(int (*func)(int modid, SceSize argsize, void *argp, int *modstatus, SceKernelSMOption *opt)); + +/** + * Loads a module on next reboot. Only kernel mode. + * + * @param module_after - The path of the module which is loaded after the module to be loaded. + The module passed to this function will be loaded just before that module. + * @param buf - The buffer containing the module - Don't deallocate this one. It has to reside in kernel memory. + * @param size - The size of the module + * @param flags - The modes in which the module should be loaded, one of BootLoadFlags + * + * @Example: + * sctrlHENLoadModuleOnReboot("/kd/usersystemlib.prx", module_buffer, module_size, BOOTLOAD_GAME | BOOTLOAD_POPS | BOOTLOAD_UMDEMU); + * + * This will load the module contained in module_buffer just before /kd/usersystemlib.prx in the next reboot, if the mode of next reboot is game, pops or umdemu + * + * @Remarks: Don't use too early modules in first param like "/kd/init.prx" or "/kd/systemctrl.prx", or your module may not load properly + * Only one module will be loaded on reboot with this function. + * If this function is called many times, only the last one will be considered. + * By making a module to load itself using this function, and calling + * sctrlHENLoadModuleOnReboot on module_start, a prx can cause itself to be resident in the modes choosen by flags. + * If all flags are selected, the module will stay resident until a psp shutdown, or until sctrlHENLoadModuleOnReboot is not called. +*/ + +void sctrlHENLoadModuleOnReboot(char *module_after, void *buf, int size, int flags); + +/** + * Enable/disable NID Resolver on particular library + * + * @param libname the name of the library to be enabled/disabled + * @param enabled 0 - disabled, != 0 - enabled + * + * @Example: + * sctrlKernelSetNidResolver("sceImpose_driver", 0); // disable sceImpose_driver resolving + * + * @return previous value if set, < 0 on error + */ +int sctrlKernelSetNidResolver(char *libname, u32 enabled); + +/** + * Get a random u32 key from PSP Kirk PRNG + */ +u32 sctrlKernelRand(void); + +/** + * Get the real unspoofed Ethernet (MAC) Address of the systems WLAN chip + * + * @param mac Out-Buffer (6B) for real MAC Address + * + * @return 0 on success, < 0 on error + */ +int sctrlGetRealEthernetAddress(uint8_t * mac); + +#if defined (__cplusplus) +} +#endif + +#endif diff --git a/libs/include/vlf.h b/libs/include/vlf.h new file mode 100755 index 0000000..999f28e --- /dev/null +++ b/libs/include/vlf.h @@ -0,0 +1,2035 @@ +#ifndef __VLF_H__ +#define __VLF_H__ + +typedef struct _VlfText *VlfText; +typedef struct _VlfPicture *VlfPicture; +typedef struct _VlfShadowedPicture *VlfShadowedPicture; +typedef struct _VlfBatteryIcon *VlfBatteryIcon; +typedef struct _VlfSpin *VlfSpin; +typedef struct _VlfCheckBox *VlfCheckBox; +typedef struct _VlfProgressBar *VlfProgressBar; +typedef struct _VlfScrollBar *VlfScrollBar; +typedef struct _VlfInputBox *VlfInputBox; + + +#define VLF_DEFAULT -1 + +#define VLF_TITLEBAR_HEIGHT 22 + +#define VLF_ERROR_INVALID_INPUT (-1) +#define VLF_ERROR_INVALID_INPUT_DATA (-2) +#define VLF_ERROR_UNSUPPORTED_FORMAT (-3) +#define VLF_ERROR_OBJECT_OVERFLOW (-4) +#define VLF_ERROR_OBJECT_NOT_FOUND (-5) +#define VLF_ERROR_NO_MEMORY (-6) +#define VLF_ERROR_SYSTEM (-7) +#define VLF_ERROR_DUPLICATED (-8) + + +#define VLF_EV_RET_NOTHING 0 +#define VLF_EV_RET_REMOVE_EVENT 1 +#define VLF_EV_RET_REMOVE_OBJECTS 2 +#define VLF_EV_RET_REMOVE_HANDLERS 4 +#define VLF_EV_RET_REFRESH_ON_DELAY 8 +#define VLF_EV_RET_DELAY 0x80000000 /* Delay VLF_EV_RET_DELAY | (X << 16), 0 <= X <= 32767 milisecs */ +#define VLF_EV_RET_DELAY_FRAME (VLF_EV_RET_DELAY | 0x40000000) /* Delay VLF_EV_RET_DELAY_FRAME| (X << 16), 0 <= X <= 4095 */ + +/* Alignment */ + +enum VlfObjects +{ + VLF_TEXT = 0, + VLF_PIC = 1, + VLF_SHADOWED_PIC = 2, + VLF_PROGRESS_BAR = 3 +}; + +enum VlfTextAlignment +{ + VLF_ALIGNMENT_LEFT = 0, + VLF_ALIGNMENT_CENTER = 0x200, + VLF_ALIGNMENT_RIGHT = 0x400 +}; + +enum VlfButtonIcon +{ + VLF_ENTER = 0, + VLF_CANCEL = 1, + VLF_CROSS = 2, + VLF_CIRCLE = 3, + VLF_TRIANGLE = 4, + VLF_SQUARE = 5 +}; +/** Fade modes */ + +enum VlfFadeModesFlags +{ + VLF_FADE_MODE_IN = 1, + VLF_FADE_MODE_OUT = 2, + VLF_FADE_MODE_REPEAT = 4, +}; + +enum VlfFadeSpeed +{ + VLF_FADE_SPEED_STANDARD, + VLF_FADE_SPEED_FAST, + VLF_FADE_SPEED_VERY_FAST, + VLF_FADE_SPEED_SLOW, + VLF_FADE_SPEED_SUPER_FAST +}; + +enum VlfBatteryIconStatus +{ + VLF_BATTERY_ICON_HIGH, + VLF_BATTERY_ICON_MEDIUM, + VLF_BATTERY_ICON_LOW, + VLF_BATTERY_ICON_LOWEST +}; + +enum RCOType +{ + RCO_GRAPHIC, + RCO_OBJECT, + RCO_SOUND, + RCO_LABEL, + RCO_FILEPARAM, + RCO_ANIMPARAM +}; + +enum VLF_MDType +{ + VLF_MD_TYPE_ERROR, + VLF_MD_TYPE_NORMAL, +}; + +enum VLF_MD_Buttons +{ + VLF_MD_BUTTONS_NONE = 0, + VLF_MD_BUTTONS_YESNO = 0x10, +}; + +enum VLF_MD_InitalCursor +{ + VLF_MD_INITIAL_CURSOR_YES = 0, + VLF_MD_INITIAL_CURSOR_NO = 0x100, +}; + +enum VLF_MD_ButtonRes +{ + VLF_MD_NONE, + VLF_MD_YES, + VLF_MD_NO, + VLF_MD_BACK +}; + +enum VLF_DialogItem +{ + VLF_DI_ENTER, + VLF_DI_CANCEL, + VLF_DI_BACK, + VLF_DI_YES, + VLF_DI_NO, + VLF_DI_EDIT, +}; + +enum VLF_SpinState +{ + VLF_SPIN_STATE_NOT_FOCUS, // Spin control has not focus, buttons are not listened + VLF_SPIN_STATE_FOCUS, // Spin control text has focus but arrow is not shown, buttons are not listened + VLF_SPIN_STATE_ACTIVE, // Spin control has focus, and it is active (arrows are shown, up and down buttons are listened) +}; + +enum VLF_InputBoxType +{ + VLF_INPUTBOX_TYPE_NORMAL, + VLF_INPUTBOX_TYPE_PASSWORD +}; + +enum PspCtrlExtension +{ + PSP_CTRL_ENTER = 0x40000000, + PSP_CTRL_CANCEL = 0x80000000 +}; + +/** + * Inits VLF library + * + * @param heap_size - The heap size to be allocated. It can be negative. + * @param app_main - The program main application. +*/ +void vlfGuiInit(int heap_size, int (* app_main)(int argc, char *argv[])); + +/** + * Performs typical application initialization tasks (adding background, system model, and optionally battery icon and clock). + * + * @param battery - Inidicates if a battery icon should be added. + * @param clock - Indicates if a clock should be added. + * @param notuserwp - If user configuration is set to use a custom background and this param is 1, then the custom wallpaper won't be used. + * + * @returns 0 on success + * + * @Notes: If an user wallpaper is used, the background model ("waves") won't be added. + */ +int vlfGuiSystemSetup(int battery, int clock, int notuserwp); + +/** + * Gets language used by vlf application + * + * @returns - The language set to be used by current vlf application + * By default is initialized to user language. +*/ +int vlfGuiGetLanguage(); + +/** + * Sets language to be used by blf application + * + * @param lang - The language to be set. + * This only sets the language to be used by current vlf application, + * it doesn't overwrite user preferences in flash. + */ +void vlfGuiSetLanguage(int lang); + +/** + * Gets the button configuration used by vlf application (0 -> circle is enter, 1 -> cross is enter) + * + * @returns - The button configuration set to be used by current vlf application. + * By default is initialized with user preferences. +*/ +int vlfGuiGetButtonConfig(); + +/** + * Sets the button configuration to be used by current vlf application. + * + * @param config - The button configuration to be set (0 -> circle is enter, 1 -> cross is enter) + * This only sets the button configuration to be used by current vlf application, + * it doesn't overwrite user preferences in flash. +*/ +void vlfGuiSetButtonConfig(int config); + +/** + * Sets the directories where resources are located. + * + * @param dir - The directory that will be used to locate resources (max 256 chars including '\0') + * By default is initialized to flash0:/vsh/resource +*/ +void vlfGuiSetResourceDir(char *dir); + +/** + * Performs the draw of next frame +*/ +void vlfGuiDrawFrame(); + +/** + * Loads resources from a rco file + * + * @param rco - It can be one of following things: + * - path relative to the directory without extension (e.g. "system_plugin_bg") + * - path relative to the directory with extension (e.g. "system_plugin_bg.rco") + * - path to a file (e.g. "flash0:/vsh/resource/system_plugin_bg.rco", "ms0:/myresfile.rco") + * + * RCO param is evaluated in the order given above, so if a rco file exists in current directory with name + * "system_plugin_bg.rco", it would load the one of and not the one of current directory. (in such a case, use "./system_plugin_bg.rco") + * + * @param n - The number of resources to loads + * @param names (IN) - An array with the names of resources + * @param types (IN) - An array with the types of the resources (one of RCOType) + * @param datas (OUT) - A pointer to a variable that will receive an array of pointers to the content of each resource, + * or NULL if a specific resource has not been found. + * Pointers returned are allocated with malloc, and should be deallocated by the application. + * + * @param sizes (OUT) - It will receive the sizes of the resources + * @param pntable (OUT) - A pointer that will receive the string table. Pass NULL if no required. + * Returned pointer is allocated with malloc and should be deallocated by the application. + * + * @returns - the number of resources loaded, or < 0 if there is an error. + * + * @Example: Load battery icon pic and shadow + * + * char *names[2]; + * void *datas[2]; + * int types[2], sizes[2]; + * + * names[0] = "tex_battery"; + * names[1] = "tex_battery_shadow"; + * types[0] = types[1] = RCO_GRAPHIC; + * + * int res = vlfGuiLoadResources("system_plugin_fg", 2, names, types, datas, sizes, NULL); + * if (res != 2) // error or not all resources loaded + * { + * if (res > 0) + * { + * if (datas[0]) + * free(datas[0]); + * if (datas[1]) + * free(datas[1]); + * } + * } + * else + * { + * void *bat; + * vlfGuiAddShadowedPicture(&bat, datas[0], sizes[0], datas[1], sizes[1], 441, 4, 1, 1, 1); + * free(datas[0]); + * free(datas[1]); + * } + * +*/ +int vlfGuiLoadResources(char *rco, int n, char **names, int *types, void **datas, int *sizes, char **pntable); + +/** + * Caches a resource in RAM, so it doesn't have to be loaded from storage device anymore. + * + * @param rco - The resource. Same rules apply to this param + * + * @returns - < 0 on error. +*/ +int vlfGuiCacheResource(char *rco); + +/** + * Uncaches a resource previously cached. + * + * @param rco - The resource to be uncached. + * + * @returns - < 0 on error. +*/ +int vlfGuiUncacheResource(char *rco); + + +//int vlfGuiGetResourceSubParam(void *entry, int insize, char *ntable, char *name, void **data, int *size); + +/** + * Loads an unicode string from a resource. + * + * @param str - Buffer that receives the string + * @param rco - The resource file to load the label from. + * @param name - The name of the resource + * + * @returns - < 0 on error. +*/ +int vlfGuiLoadLabel(u16 *str, char *rco, char *name); + +/** + * Sets the background from 8888 texture data + * + * @param texture - The texture data in 8888 format + * @param width - The width of texture. Must be a power of 2. + * @param height - The height of texture. Must be multiple of 8. + * @param swizzled - Indicates if the texture is already in the psp GE fast texture format + * @param scale_x - The x scale to apply + * @param scale_y - The y scale to apply + * + * @returns 0 on success, or < 0 on error (params invalid) +*/ +int vlfGuiSetBackground(u32 *texture, int width, int height, int swizzled, float scale_x, float scale_y); + +/** + * Sets the background from a file buffer. + * Supported formats are currently: BMP, TIM, GIM and PNG, with a depth of 24 or 32 bits. + * + * @param data - The buffer with the file data + * @param size - The size of the data + * @param scale - Wether to scale the image. If it is 0, the image will be centered and filled by black. + * + * @returns - 0 on success, < 0 on error. +*/ +int vlfGuiSetBackgroundFileBuffer(void *data, int size, int scale); + +/** + * Sets the background from a file + * Supported formats are currently: BMP, TIM, GIM and PNG, with a depth of 24 or 32 bits. + * + * @param file - Path to the file. + * @param scale - Wether to scale the image. If it is 0, the image will be centered and filled by black. + * + * @returns - 0 on success, < 0 on error. +*/ +int vlfGuiSetBackgroundFile(char *file, int scale); + +/** + * Sets one of system backgrounds based on the index. + * + * @param index - The index of the background, valid values are 1-27 + * (note that 13-27 is only available on slim and will return an error on old psp) + * + * @returns 0 on success, < 0 on error +*/ +int vlfGuiSetBackgroundIndex(int index); + +/** + * Sets one of system backgrounds based on the current date + * + * @returns 0 on success, < 0 on error +*/ +int vlfGuiSetBackgroundDate(); + +/** + * Sets a background of a single color + * + * @param color - The color in XXBBGGRR format (XX is ignored). + * + * @returns - this functions always succeeds returning 0 +*/ +int vlfGuiSetBackgroundPlane(u32 color); + +/** + * Sets the background according to the system configuration + * + * @returns - 0 on success, < 0 on error. +*/ +int vlfGuiSetBackgroundSystem(int notuserwp); + +/** + * Sets the system color, used in titlebars or menus + * + * @param index - the index of the color, 1-27 +*/ +void vlfGuiSetSystemColor(int index); + +/** + * Sets the background model from a buffer. + * + * @param data - The buffer with the model in GMO format + * @param size - The size of the model + * + * @returns - 0 on success, < 0 on error. +*/ +int vlfGuiSetModel(void *data, int size); + +/** + * Sets the background model from a file. + * + * @param file - The file with the model in GMO format + * + * @returns - 0 on success, < 0 on error. +*/ +int vlfGuiSetModelFile(char *file); + +/** + * Sets the background model from a resource. + * + * @param rco - The path to the RCO file + * @param name - The name of the resource + * + * @returns - 0 on success, < 0 on error. +*/ +int vlfGuiSetModelResource(char *rco, char *name); + +/** + * Sets the background model of the system, and applies the proper world matrix to it. + * + * @returns 0 on success, < 0 on error. +*/ +int vlfGuiSetModelSystem(); + +/** + * Sets the world matrix for the model. (by default, the world matrix is the identity + * after a model has been loaded, except when calling vlfGuiSetModelSystem). + * + * @param matrix - The matrix to set. + * + * @Example: Load waves (this sample assumes the default scale of 8.5) + * + * int res = vlfGuiSetModelResource("system_plugin_bg", "mdl_bg"); + * if (res < 0) process_error; + * + * ScePspFMatrix4 matrix; + * ScePspFVector3 scale; + * + * scale.x = scale.y = scale.z = 8.5f; + * gumLoadIdentity(&matrix); + * gumScale(&matrix, &scale); + * vlfGuiSetModelWorldMatrix(&matrix); +*/ +void vlfGuiSetModelWorldMatrix(ScePspFMatrix4 *matrix); + +/** + * Gets the world matrix of the model + * + * @returns a pointer to the model world matrix +*/ +ScePspFMatrix4 *vlfGuiGetModelWorldMatrix(); + +/** + * Sets the model speed + * + * @param speed - The speed, default model speed is 1.0f/60.0f +*/ +void vlfGuiSetModelSpeed(float speed); + +/** + * Sets a title bar with the current system color. + * + * @param text - Text of the title bar. Pass NULL if no required. + * @param pic - Picture of the title bar. Pass NULL if no required. + * @param visible - If the tile bar will be visible + * @param hideobj - If 1, it will hide objects that were current added within the area of the title bar. + */ +void vlfGuiSetTitleBar(VlfText text, VlfPicture pic, int visible, int hideobj); + +/** + * Sets a title bar with the desired color. + * + * @param text - Text of the title bar. Pass NULL if no required. + * @param pic - Picture of the title bar. Pass NULL if no required. + * @param visible - If the tile bar will be visible + * @param hideobj - If 1, it will hide objects that were current added within the area of the title bar. + * @param color - The color of the title bar. +*/ +void vlfGuiSetTitleBarEx(VlfText text, VlfPicture pic, int visible, int hideobj, u32 color); + +/** + * Sets the tile bar visibility. +*/ +void vlfGuiSetTitleBarVisibility(int visible); + +/** + * Adds a new text item from an ascii string. + * + * @param x - x position + * @param y - y position + * @param string - ascii string with the desired text + * + * @returns a VlfText item on success, NULL on error. +*/ +VlfText vlfGuiAddText(int x, int y, char *string); + +/** + * Adds a new text item from an unicode string. + * + * @param x - x position + * @param y - y position + * @param string - unicode string with the desired text + * + * @returns a VlfText item on success, NULL on error. +*/ +VlfText vlfGuiAddTextW(int x, int y, u16 *string); + +/** + * Adds a new text item from a string with format + * + * @param x - x position + * @param y - y position + * @param fmt - string with format + * + * @returns a VlfText item on success, NULL on error. +*/ +VlfText vlfGuiAddTextF(int x, int y, char *fmt, ...); + +/** + * Adds a new text item from a resource label + * + * @param rco - The resource file to load the label from. + * @param name - The name of the resource. + * @param x - x position + * @param y - y position + * + * @returns a VlfText item on success, NULL on error. +*/ +VlfText vlfGuiAddTextResource(char *rco, char *name, int x, int y); + +/** + * Removes a text item. + * + * @param text - The text item to remove + * + * @returns - < 0 on error. +*/ +int vlfGuiRemoveText(VlfText text); + +/** + * Sets the text of a VlfText item from an ascii string. + * + * @param text - The text item + * @param string - The ascii string to set. + * + * @returns - < 0 on error. +*/ +int vlfGuiSetText(VlfText text, char *string); + +/** + * Sets the text of a VlfText item from an unicode string. + * + * @param text - The text item + * @param string - The unicode string to set. + * + * @returns - < 0 on error. +*/ +int vlfGuiSetTextW(VlfText text, u16 *string); + +/** + * Sets the text of a VlfText item from a string with format. + * + * @param text - The text item + * @param fmt - The string with format. + * + * @returns - < 0 on error. +*/ +int vlfGuiSetTextF(VlfText text, char *fmt, ...); + +/** + * Sets the text of a VlfText item from a resource label. + * + * @param text - The text item + * @param rco - The resource file to load the label from. + * @param name - The name of the resource. + * + * @returns - < 0 on error. +*/ +int vlfGuiSetTextResource(VlfText text, char *rco, char *name); + +/** + * Sets focus on a VlfText item. + * + * @param text - The text item to set the focus. + * + * @returns - < 0 on error. + * + * @Note: this function should only be used with a text with a single line, and + * with default font size. +*/ +int vlfGuiSetTextFocus(VlfText text); + +/** + * Removes focus on a VlfText item previously focused. + * + * @param text - The text item to remove focus. + * + * @returns - < 0 on error. +*/ +int vlfGuiRemoveTextFocus(VlfText text, int keepres); + +/** + * Sets the visibility of a VlfText item. + * + * @param text - The text item. + * @param visible - boolean for the visibility. + * + * @returns - < 0 on error. +*/ +int vlfGuiSetTextVisibility(VlfText text, int visible); + +/** + * Makes a VlfText item to blink. + * + * @param text - The text item to set blinking. + * @param nshow - The number of frames the item will be shown. + * @param nhide - The number of frames the item wil be hidden. + * + * @returns - < 0 on error + * + * @Notes: To remove blinking, pass both params to 0. +*/ +int vlfGuiSetTextBlinking(VlfText text, u32 nshow, u32 nhide); + +/** + * Makes a VlfText item to fade. + * + * @param text - The text item to fade. + * @param mode - Whatever OR combination of VlfFadeModesFlags + * @param speed - The fade speed, one of VlfFadeSpeed + * @param direction_out - If both, VLF_FADE_MODE_IN and VLF_FADE_MODE_OUT, were specified, this param indicates + * wether to start from direction out or in. Otherwise, it is ignored. + * + * @returns - < 0 on error. +*/ +int vlfGuiSetTextFade(VlfText text, int mode, int speed, int direction_out); + +/** + * Cancels a VlfText item fade. + * + * @param text - The text item to remove fade. + * + * @returns - < 0 on error +*/ +int vlfGuiCancelTextFade(VlfText text); + +/** + * Sets a callback to report the end of a fade. + * + * @param text - The text item fading. + * @param callback - The callback function that will be called at end of fade. + * @param param - param that will be passed to the callback function + * @param delay - The delay between the end of fade and the call to the callback + * + * @returns - < 0 on error +*/ +int vlfGuiSetTextFadeFinishCallback(VlfText text, void (* callback)(void *), void *param, int delay); + +/** + * Sets text item alignment + * + * @param text - The text item to set alignment + * @param alignment - One of VlfTextAlignment values + * + * @returns - < 0 on error +*/ +int vlfGuiSetTextAlignment(VlfText text, int alignment); + +/** + * Sets text position + * + * @param text - The text item to set position + * @param x - The x position + * @param y - The y position + * + * @returns - < 0 on error +*/ +int vlfGuiSetTextXY(VlfText text, int x, int y); + +/** + * Sets the font size of a text item + * + * @param text - The text to set font size + * @param size - The size of the font + * + * @returns - < 0 on error +*/ +int vlfGuiSetTextFontSize(VlfText text, float size); + +/** + * Returns the size of a text item. + * + * @param text - The text item yo get size from + * @param width - pointer to a variable that receives the width + * @param height - pointer to a variable that receivs the height + * + * @returns - < 0 on error +*/ +int vlfGuiGetTextSize(VlfText text, int *width, int *height); + +/** + * Sets a scrollbar in the specified text item. + * + * @param text - The text item + * @param height - The height of the scrollbar + * + * @returns - < 0 on error +*/ +int vlfGuiSetTextScrollBar(VlfText text, int height); + +/** + * Sets a scrollbar in the specified text item (with more options) + * + * @param text - The text item + * @param height - The height of the scrollbar + * @param dispx - displacement between text and scrollbar in X axis + * @param dispy - displacement between text and scrollbar in Y axis + * + * @returns - < 0 on error + */ +int vlfGuiSetTextScrollBarEx(VlfText text, int height, int dispx, int dispy); + +/** + * Removes a scrollbar of a text item + * + * @param text - The text item + * + * @returns - < 0 on error +*/ +int vlfGuiRemoveTextScrollBar(VlfText text); + +/** + * Sets a character that will be replaced by a button icon + * + * @param ch - The character that will be replaced. + * @param button - The button used for the replacement, one of VlfButtonIcon + * + * @returns - < 0 on error +*/ +int vlfGuiChangeCharacterByButton(u16 ch, int button); + +/** + * Adds a new picture item from a buffer. + * Supported formats are GIM, TIM, BMP and PNG. + * + * @param data - The buffer with the picture + * @param size - The size of data buffer + * @param x - x position + * @param y - y position + * + * @returns - a new VlfPivture on success, NULL on error +*/ +VlfPicture vlfGuiAddPicture(void *data, int size, int x, int y); + +/** + * Adds a new picture item from a file. + * Supported formats are GIM, TIM, BMP and PNG. + * + * @param file - The file with the picture + * @param x - x position + * @param y - y position + * + * @returns - a new VlfPivture on success, NULL on error +*/ +VlfPicture vlfGuiAddPictureFile(char *file, int x, int y); + +/** + * Adds a new picture item from a resource. + * Supported formats are GIM, TIM, BMP and PNG. + * + * @param rco - The rco + * @param name - The name of the resource + * @param x - x position + * @param y - y position + * + * @returns - a new VlfPivture on success, NULL on error +*/ +VlfPicture vlfGuiAddPictureResource(char *rco, char *name, int x, int y); + +/** + * Removes a picture + * + * @param pic - The picture to remove + * + * @returns - < 0 on error. +*/ +int vlfGuiRemovePicture(VlfPicture pic); + +/** + * Sets a picture position. + * + * @param pic - The picture + * @param x - x position + * @param y - y position + * + * @returns - < 0 on error +*/ +int vlfGuiSetPictureXY(VlfPicture pic, int x, int y); + +/** + * Gets a picture size. + * + * @param pic - The picture + * @param width - pointer to a variable that receives the width + * @param height - pointer to a variable that receives the height + * + * @returns - < 0 on error +*/ +int vlfGuiGetPictureSize(VlfPicture pic, int *width, int *height); + +/** + * Sets the picture display area + * + * @param pic - The picture + * @param x - x position of the display area, relative to the top left corner of the picture. + * @param y - y position of the display area, relative to the top left corner of the picture. + * @param width - the width of the rectangle display area + * @param height - The height of the rectangle display area + * + * @returns - < 0 on error +*/ +int vlfGuiSetPictureDisplayArea(VlfPicture pic, int x, int y, int width, int height); + +/** + * Sets picture alpha blend operation. + * + * @param pic - the picture + * @param op - Blending operation (see pspgu.h) + * @param src - Blending function for source operand (see pspgu.h) + * @param dst - Blending function for dest operand (see pspgu.h) + * @param srcfix - Fix value for GU_FIX (source operand) + * @param destfix - Fix value for GU_FIX (dest operand) + * + * @returns - < 0 on error +*/ +int vlfGuiSetPictureAlphaBlend(VlfPicture pic, int op, int src, int dst, u32 srcfix, u32 dstfix); + +/** + * Clones (duplicate) a picture + * + * @param pic - The picture to clone + * @param real - If 0, then the picture is not totally copied, but only a reference. Otherwise, a total duplication is performed. + * @param x - The x position for the cloned picture + * @param y - The y position for the cloned picture + * + * @returns - The cloned picture +*/ +VlfPicture vlfGuiClonePicture(VlfPicture pic, int real, int x, int y); + +/** + * Sets picture visibility + * + * @param pic - The picture + * @param visible - boolean indicating visibility + * + * @returns - < 0 on error +*/ +int vlfGuiSetPictureVisibility(VlfPicture pic, int visible); + +/** + * Makes a picture blink + * + * @param pic - The picture to blink + * @param nshow - The number of frames the picture will be shown + * @param nhide - The number of frames the picture will be hidden + * + * @returns - < 0 on error +*/ +int vlfGuiSetPictureBlinking(VlfPicture pic, u32 nshow, u32 nhide); + +/** + * Animates a picture. + * Frames are created from rectangle areas of the picture. + * + * @param pic - The picture to animate + * @param w - The width of each frame, must be a divisor of picture width + * @param h - The height of each frame, must be a divisor of picture height + * @param frames - The number of frames each frame is drawn. + * @param vertical - If 0, animaction is created from rectangles in horizontal direction. Otherwise, from vertical direction. + * + * @returns - < 0 on error +*/ +int vlfGuiAnimatePicture(VlfPicture pic, int w, int h, int frames, int vertical); + +/** + * Makes a VlfPicture item to fade. + * + * @param pic - The picture item to fade. + * @param mode - Whatever OR combination of VlfFadeModesFlags + * @param speed - The fade speed, one of VlfFadeSpeed + * @param direction_out - If both, VLF_FADE_MODE_IN and VLF_FADE_MODE_OUT, were specified, this param indicates + * wether to start from direction out or in. Otherwise, it is ignored. + * + * @returns - < 0 on error. + */ +int vlfGuiSetPictureFade(VlfPicture pic, int mode, int effect, int direction_out); + +/** + * Cancels a VlfPicture item fade. + * + * @param pic - The picture item to remove fade. + * + * @returns - < 0 on error +*/ +int vlfGuiCancelPictureFade(VlfPicture pic); + +/** + * Sets a callback to report the end of a fade. + * + * @param pic - The picture item fading. + * @param callback - The callback function that will be called at end of fade. + * @param param - param that will be passed to the callback function + * @param delay - The delay between the end of fade and the call to the callback + * + * @returns - < 0 on error +*/ +int vlfGuiSetPictureFadeFinishCallback(VlfPicture pic, void (* callback)(void *), void *param, int delay); + +/** + * Adds a new shadowed picture from two buffers. + * + * @param pic - The buffer with the main picture + * @param pic_size - The size of the pic buffer + * @param shpic - The buffer with the shadow picture + * @param shpic_size - The size of the shpic buffer + * @param x - x position + * @param y - y position + * @param sh_offsx - distance between the main picture and the shadow (x) + * @param sh_offsy - distance between the main picture and the shadow (y) + * @param shadow_before - indicates if shadow should be painted before + * + * @returns - a new shadowed picture on success, NULL on error +*/ +VlfShadowedPicture vlfGuiAddShadowedPicture(void *pic, int pic_size, void *shpic, int shpic_size, int x, int y, int sh_offsx, int sh_offsy, int shadow_before); + +/** + * Adds a new shadowed picture from two files + * + * @param pic - The file with the main picture + * @param shpic - The file with the shadow picture + * @param x - x position + * @param y - y position + * @param sh_offsx - distance between the main picture and the shadow (x) + * @param sh_offsy - distance between the main picture and the shadow (y) + * @param shadow_before - indicates if shadow should be painted before + * + * @returns - a new shadowed picture on success, NULL on error +*/ +VlfShadowedPicture vlfGuiAddShadowedPictureFile(char *pic, char *shpic, int x, int y, int sh_offsx, int sh_offsy, int shadow_before); + +/** + * Adds a new shadowed picture from two resources. + * + * @param rco .- The resource file + * @param pic - The name of the resource with the main picture + * @param shpic - The name of the resource with the shadow picture + * @param x - x position + * @param y - y position + * @param sh_offsx - distance between the main picture and the shadow (x) + * @param sh_offsy - distance between the main picture and the shadow (y) + * @param shadow_before - indicates if shadow should be painted before + * + * @returns - a new shadowed picture on success, NULL on error +*/ +VlfShadowedPicture vlfGuiAddShadowedPictureResource(char *rco, char *pic, char *shpic, int x, int y, int sh_offsx, int sh_offsy, int shadow_before); + +/** + * Removes a shadowed picture + * + * @param sp - The shadowed picture to remove + * + * @returns - < 0 on error. +*/ +int vlfGuiRemoveShadowedPicture(VlfShadowedPicture sp); + +/** + * Sets shadowed picture visibility + * + * @param sp - The shadowed picture + * @param visible - boolean indicating visibility + * + * @returns - < 0 on error +*/ +int vlfGuiSetShadowedPictureVisibility(VlfShadowedPicture sp, int visible); + +/** + * Makes a shadowed picture blink + * + * @param sp - The shadowed picture to blink + * @param nshow - The number of frames the picture will be shown + * @param nhide - The number of frames the picture will be hidden + * + * @returns - < 0 on error +*/ +int vlfGuiSetShadowedPictureBlinking(VlfShadowedPicture sp, u32 nshow, u32 nhide); + +/** + * Animates a shadowed picture. + * Frames are created from rectangle areas of the picture. + * + * @param sp - The shadowed picture to animate + * @param w - The width of each frame of main picture, must be a divisor of main picture width + * @param h - The height of each frame of main picure, must be a divisor of main picture height + * @param ws - The width of each frame of shadow picture, must be a divisor of shadow picture width + * @param hs - The height of each frame of shadow picure, must be a divisor of shadow picture height + * @param frames - The number of frames each frame is drawn + * @param vertical - If 0, animaction is created from rectangles in horizontal direction. Otherwise, from vertical direction. + * + * @returns - < 0 on error + * + * @Example: vlfGuiAddWaitIconEx source code. Image is divided in 17x17 rectangles, each frame is drawn for 3 frames. + * + * VlfShadowedPicture vlfGuiAddWaitIconEx(int x, int y) + * { + * VlfShadowedPicture res = vlfGuiAddShadowedPictureResource("system_plugin_fg", "tex_busy", "tex_busy_shadow", x, y, 1, 1, 0); + * + * if (!res) + * return NULL; + * + * if (vlfGuiAnimateShadowedPicture(res, 17, 17, 17, 17, 3, 1) < 0) + * { + * vlfGuiRemoveShadowedPicture(res); + * return NULL; + * } + * + * return res; + * } +*/ +int vlfGuiAnimateShadowedPicture(VlfShadowedPicture sp, int w, int h, int ws, int hs, int frames, int vertical); + +/** + * Makes a VlfShadowedPicture item to fade. + * + * @param sp - The shadowed picture item to fade. + * @param mode - Whatever OR combination of VlfFadeModesFlags + * @param speed - The fade speed, one of VlfFadeSpeed + * @param direction_out - If both, VLF_FADE_MODE_IN and VLF_FADE_MODE_OUT, were specified, this param indicates + * wether to start from direction out or in. Otherwise, it is ignored. + * + * @returns - < 0 on error. + */ +int vlfGuiSetShadowedPictureFade(VlfShadowedPicture sp, int mode, int effect, int direction_out); + +/** + * Cancels a VlfShadowedPicture item fade. + * + * @param sp - The shadowed picture item to remove fade. + * + * @returns - < 0 on error + */ +int vlfGuiCancelShadowedPictureFade(VlfShadowedPicture sp); + +/** + * Sets a callback to report the end of a fade. + * + * @param sp - The shadowed picture item fading. + * @param callback - The callback function that will be called at end of fade. + * @param param - param that will be passed to the callback function + * @param delay - The delay between the end of fade and the call to the callback + * + * @returns - < 0 on error +*/ +int vlfGuiSetShadowedPictureFadeFinishCallback(VlfShadowedPicture sp, void (* callback)(void *), void *param, int delay); + +/** + * Adds a new battery icon at its default position. Icon created by this function must be manually operated by programmer. + * + * @param status - The status, one of VlfBatteryIconStatus + * @param blink - blinking flag + * + * @returns - a new VlfBatteryIcon item +*/ +VlfBatteryIcon vlfGuiAddBatteryIcon(u32 status, int blink); + +/** + * Adds a new battery icon (with more options). Icon created by this function must be manually operated by programmer. + * + * @param x - The x position + * @param y - The y position + * @param status - The status, one of VlfBatteryIconStatus + * @param blink - blinking flag + * + * @returns - a new VlfBatteryIcon item + */ +VlfBatteryIcon vlfGuiAddBatteryIconEx(int x, int y, u32 status, int blink); + +/** + * Adds a new battery icon at its default position. + * Icon created by this function is handled automatically by the library. + * + * @param timer_ms - The miliseconds the timer that checks the battery is executed. + * + * @returns - a new VlfBatteryIcon item +*/ +VlfBatteryIcon vlfGuiAddBatteryIconSystem(int timer_ms); + +/** + * Sets battery icon status. + * + * @param baticon - The battery icon + * @param status - The status, one of VlfBatteryIconStatus + * @param blink - blinking flag + * + * @returns - < 0 on error + * + * @Note: this function shouldn't be used with a battery icon created by vlfGuiAddBatteryIconSystem. +*/ +int vlfGuiSetBatteryIconStatus(VlfBatteryIcon baticon, int status, int blink); + +/** + * Removes a battery icon. + * + * @param baticon - The battery icon to remove + * + * @returns - < 0 on error +*/ +int vlfGuiRemoveBatteryIcon(VlfBatteryIcon baticon); + +/** + * Adds a system clock. Only one clock is allowed currently + * + * @returns - < 0 on error. + * + * @Note: this function will change in future versions. +*/ +int vlfGuiAddClock(); + +/** + * Adds an animated wait icon at its default position in lower-right corner. + * + * @returns - a new wait icon. +*/ +VlfShadowedPicture vlfGuiAddWaitIcon(); + +/** + * Adds an animated wait icon at position choosed by programmer. + * + * @param x - x position + * @param y - y position + * + * @returns - a new wait icon. + */ +VlfShadowedPicture vlfGuiAddWaitIconEx(int x, int y); + +/** + * Adds a cross picture. + * + * @param x - x position + * @param y - y position + * + * @returns - a new cross picture +*/ +VlfShadowedPicture vlfGuiAddCross(int x, int y); + +/** + * Adds a circle picture. + * + * @param x - x position + * @param y - y position + * + * @returns - a new circle picture +*/ +VlfShadowedPicture vlfGuiAddCircle(int x, int y); + +/** + * Adds a triangle picture. + * + * @param x - x position + * @param y - y position + * + * @returns - a new triangle picture +*/ +VlfShadowedPicture vlfGuiAddTriangle(int x, int y); + +/** + * Adds a square picture. + * + * @param x - x position + * @param y - y position + * + * @returns - a new square picture +*/ +VlfShadowedPicture vlfGuiAddSquare(int x, int y); + +/** + * Adds an enter picture (cross or circle) + * + * @param x - x position + * @param y - y position + * + * @returns - a new enter picture +*/ +VlfShadowedPicture vlfGuiAddEnter(int x, int y); + +/** + * Adds a cancel picture (cross or circle) + * + * @param x - x position + * @param y - y position + * + * @returns - a new cancel picture +*/ +VlfShadowedPicture vlfGuiAddCancel(int x, int y); + +/** + * Adds a spinup picture. + * + * @param x - x position + * @param y - y position + * + * @returns - a new spinup picture +*/ +VlfShadowedPicture vlfGuiAddSpinUp(int x, int y); + +/** + * Adds a spindown picture. + * + * @param x - x position + * @param y - y position + * + * @returns - a new spindown picture +*/ +VlfShadowedPicture vlfGuiAddSpinDown(int x, int y); + +/** + * Adds an arrow left picture. + * + * @param x - x position + * @param y - y position + * + * @returns - a new arrow left picture +*/ +VlfShadowedPicture vlfGuiAddArrowLeft(int x, int y); + +/** + * Adds an arrow right picture. + * + * @param x - x position + * @param y - y position + * + * @returns - a new arrow right picture +*/ +VlfShadowedPicture vlfGuiAddArrowRight(int x, int y); + +/** + * Adds a new integer spin + * + * @param x - x position + * @param y - y position + * @param min - minim value of the spin + * @param max - max value of the spin + * @param cur - The initial integer value of the spin + * @param step - The step in which the value is increased/decreased + * @param loop - boolean indicating if the spin loops + * @param speed - The speed of the spin in milisecs + * @param initstate - the initial state of the spin, one of VLF_SpinState + * @param prefix - Prefix string, NULL if not needed + * @param suffix - Suffix string, NULL if not needed + * + * @returns - a new VlfSpin object on success, NULL on error +*/ +VlfSpin vlfGuiAddIntegerSpinControl(int x, int y, int min, int max, int cur, int step, int loop, int speed, int initstate, char *prefix, char *suffix); + +/** + * Removes a spin item + * + * @param spin - the spin to remove + * + * @returns - < 0 on error +*/ +int vlfGuiRemoveSpinControl(VlfSpin spin); + +/** + * Sets spin state + * + * @param spin - the spin + * @param state - the state, one of VLF_SpinState + * + * @returns - < 0 on error +*/ +int vlfGuiSetSpinState(VlfSpin spin, int state); + +/** + * Sets integer minimum and maximum values for an integer spin + * + * @param spin - The integer spin + * @param min - the minimum value + * @param max - the maximum value + * + * @returns - < 0 on error +*/ +int vlfGuiSetIntegerSpinMinMax(VlfSpin spin, int min, int max); + +/** + * Gets the integer value of an integer spin + * + * @param spin - the integer spin + * @param value - pointer to a variable that receives the value + * + * @returns - < 0 on error +*/ +int vlfGuiGetIntegerSpinValue(VlfSpin spin, int *value); + +/** + * Sets the integer value of an integer spin + * + * @param spin - the integer spin + * @param value - the integer value to set + * + * @returns - < 0 on error +*/ +int vlfGuiSetIntegerSpinValue(VlfSpin spin, int value); + +/** + * Adds a new checkbox item + * By default the checkbox is created without focus and without check. + * When a checbox has focus, library handles automatically the press of enter button to change check state + * + * @param x - x position + * @param y - y position + * + * @returns - a new VlfCheckBox item on sucess, NULL on error +*/ +VlfCheckBox vlfGuiAddCheckBox(int x, int y); + +/** + * Removes a checkbox item + * + * @param cb - The checkbox to remove + * + * @returns - < 0 on error +*/ +int vlfGuiRemoveCheckBox(VlfCheckBox cb); + +/** + * Sets checkbox check state + * + * @param cb - The checkbox to check/uncheck + * @param check - boolean indicating check + * + * @returns - < 0 on error +*/ +int vlfGuiSetCheckBoxCheck(VlfCheckBox cb, int check); + +/** + * Sets checkbox focus state + * + * @param cb - The checkbox + * @param focus - boolean indicating focus + * + * @returns - < 0 on error + */ +int vlfGuiSetCheckBoxFocus(VlfCheckBox cb, int focus); + +/** + * Boolean function that checks check state of a checkbox + * + * @param cb - the checkbox + * + * @returns 1 if the checkbox is checked, 0 otherwise +*/ +int vlfGuiIsCheckBoxChecked(VlfCheckBox cb); + +/** + * Boolean function that checks focus state of a checkbox + * + * @param cb - the checkbox + * + * @returns 1 if the checkbox has focus, 0 otherwise +*/ +int vlfGuiIsCheckBoxFocused(VlfCheckBox cb); + +/** + * Adds a new inputbox item with default width. + * By default the newly created inputbox is focused and of normal type. + * When a inputbox item is focused, library automatically handles press of enter button to show OSK. + * + * @param desc - description that will be shown in the OSK dialog. + * @param x - the x position + * @param y - the y position + * + * @returns - a new VlfInputBox on sucess, NULL on error +*/ +VlfInputBox vlfGuiAddInputBox(char *desc, int x, int y); + +/** + * Adds a new inputbox item. + * By default the newly created inputbox is focused and of normal type. + * When a inputbox item is focused, library automatically handles press of enter button to show OSK. + * + * @param desc - description that will be shown in the OSK dialog. + * @param x - the x position + * @param y - the y position + * @param width - width of the box + * + * @returns - a new VlfInputBox on sucess, NULL on error +*/ +VlfInputBox vlfGuiAddInputBoxEx(u16 *desc, int x, int y, int width); + +/** + * Removes an inputbox + * + * @param ib - the inputbox to remove + * + * @returns - < 0 on error +*/ +int vlfGuiRemoveInputBox(VlfInputBox ib); + +/** + * Sets inputbox text from an ascii string + * + * @param ib - the inputbox + * @param text - the ascii string + * + * @returns - < 0 on error +*/ +int vlfGuiSetInputBoxText(VlfInputBox ib, char *text); + +/** + * Sets inputbox text from an unicode string + * + * @param ib - the inputbox + * @param text - the unicode string + * + * @returns - < 0 on error + */ +int vlfGuiSetInputBoxTextW(VlfInputBox ib, u16 *text); + +/** + * Sets inputbox text from a string with format + * + * @param ib - the inputbox + * @param fmt - the string with format + * + * @returns - < 0 on error + */ +int vlfGuiSetInputBoxTextF(VlfInputBox ib, char *fmt, ...); + +/** + * Gets inputbox text. + * + * @param ib - thei inputbox + * @param text - output buffer that receives the strig as unicode + * + * @returns - < 0 on error +*/ +int vlfGuiGetInputBoxText(VlfInputBox ib, u16 *text); + +/** + * Sets inputbox focus state + * + * @param ib - the inputbox + * @param focus - the focus state boolean + * + * @returns - < 0 on error +*/ +int vlfGuiSetInputBoxFocus(VlfInputBox ib, int focus); + +/** + * Boolean function that checks inputbox focus state + * + * @param ib - The inputbox + * + * @returns 1 if the inputbox has focus, 0 otherwise +*/ +int vlfGuiIsInputBoxFocused(VlfInputBox ib); + +/** + * Sets inputbox type (normal or password). + * + * @param ib - the inputbox + * @param type - the type to set, one of VLF_InputBoxType + * + * @returns - < 0 on error +*/ +int vlfGuiSetInputBoxType(VlfInputBox ib, int type); + +/** + * Makes a VlfInputBox item to fade. + * + * @param ib - The inputbox item to fade. + * @param mode - Whatever OR combination of VlfFadeModesFlags + * @param speed - The fade speed, one of VlfFadeSpeed + * @param direction_out - If both, VLF_FADE_MODE_IN and VLF_FADE_MODE_OUT, were specified, this param indicates + * wether to start from direction out or in. Otherwise, it is ignored. + * + * @returns - < 0 on error. +*/ +int vlfGuiSetInputBoxFade(VlfInputBox ib, int mode, int effect, int direction_out); + +/** + * Cancels a VlfInputBox item fade. + * + * @param ib - The inputbox item to remove fade. + * + * @returns - < 0 on error +*/ +int vlfGuiCancelInputBoxFade(VlfInputBox ib); + +/** + * Sets a callback to report the end of a fade. + * + * @param ib- The inputbox item fading. + * @param callback - The callback function that will be called at end of fade. + * @param param - param that will be passed to the callback function + * @param delay - The delay between the end of fade and the call to the callback + * + * @returns - < 0 on error +*/ +int vlfGuiSetInputBoxFadeFinishCallback(VlfInputBox ib, void (* callback)(void *), void *param, int delay); + +/** + * Adds a new progressbar at default x position. + * + * @param y - y position + * + * @return - a new VlfProgressBar item on success, NULL on error +*/ +VlfProgressBar vlfGuiAddProgressBar(int y); + +/** + * Adds a new progressbar + * + * @param x - x position + * @param y - y position + * + * @return - a new VlfProgressBar item on success, NULL on error +*/ +VlfProgressBar vlfGuiAddProgressBarEx(int x, int y); + +/** + * Removes a progress bar + * + * @param pb - the progress bar to remove. + * + * @returns - < 0 on error +*/ +int vlfGuiRemoveProgressBar(VlfProgressBar pb); + +/** + * Sets the progress of a progressbar + * + * @param pb - the progress bar + * @param perc - the percentage progress + * + * @returns - < 0 on error +*/ +int vlfGuiProgressBarSetProgress(VlfProgressBar pb, u32 perc); + +/** + * Makes a VlfProgressBar item to fade. + * + * @param pb - The progressbar item to fade. + * @param mode - Whatever OR combination of VlfFadeModesFlags + * @param speed - The fade speed, one of VlfFadeSpeed + * @param direction_out - If both, VLF_FADE_MODE_IN and VLF_FADE_MODE_OUT, were specified, this param indicates + * wether to start from direction out or in. Otherwise, it is ignored. + * + * @returns - < 0 on error. +*/ +int vlfGuiSetProgressBarFade(VlfProgressBar pb, int mode, int effect, int direction_out); + +/** + * Cancels a VlfProgressBar item fade. + * + * @param pb - The progressbar item to remove fade. + * + * @returns - < 0 on error +*/ +int vlfGuiCancelProgressBarFade(VlfProgressBar pb); + +/** + * Sets a callback to report the end of a fade. + * + * @param pb - The progressbar item fading. + * @param callback - The callback function that will be called at end of fade. + * @param param - param that will be passed to the callback function + * @param delay - The delay between the end of fade and the call to the callback + * + * @returns - < 0 on error +*/ +int vlfGuiSetProgressBarFadeFinishCallback(VlfProgressBar pb, void (* callback)(void *), void *param, int delay); + +/** + * Adds a new scrollbar. (must be controlled by programmer) + * + * @param x - x position + * @param y - y position + * @param height - height of scrollbar + * @param sliderheight - height of slider + * + * @returns a new VlfScrollBar item on success, NULL on error +*/ +VlfScrollBar vlfGuiAddScrollBar(int x, int y, int height, int sliderheight); + +/** + * Removes a scrollbar itemm. + * + * @param sb - the scrollbar to remove + * + * @returns - < 0 on error +*/ +int vlfGuiRemoveScrollBar(VlfScrollBar sb); + +/** + * Moves the slider of a scrollbar + * + * @param y - the new position of the slider + * + * @returns - < 0 on error +*/ +int vlfGuiMoveScrollBarSlider(VlfScrollBar sb, int y); + +/** + * Sets the height of the slider of a scrollbar + * + * @param sb - the scrollbar + * @param height - the new height for the slider + * + * @returns - < 0 on error. +*/ +int vlfGuiSetScrollBarSliderHeight(VlfScrollBar sb, int height); + +/** + * Sets the visibility of the items in a rectangle + * + * @param x - x position of rectangle + * @param y - y position of rectangle + * @param w - width of rectangle + * @param h - height of rectangle + * @param visible . boolean indicating visibility + * + * @returns - < 0 on error +*/ +int vlfGuiSetRectangleVisibility(int x, int y, int w, int h, int visible); + +/** + * Saves the visibility context in a rectangle area + * + * @param x - x position of rectangle + * @param y - y position of rectangle + * @param w - width of rectangle + * @param h - height of rectangle + * + * @returns - the visibility context. Use vlfGuiRestoreVisibilityContext to restore it, and vlfGuiFreeVisibilityContext to deallocate it. +*/ +void *vlfGuiSaveRectangleVisibilityContext(int x, int y, int w, int h); + +/** + * Restores a visibility context. + * + * @param ctx - the visibility context +*/ +void vlfGuiRestoreVisibilityContext(void *ctx); + +/** + * Deallocates memory used by a visibility context + * + * @param ctx - the visibility context +*/ +void vlfGuiFreeVisibilityContext(void *ctx); + +/** + * Makes all items within a rectangle to fade + * + * @param x - x position of rectangle + * @param y - y position of rectangle + * @param w - width of rectangle + * @param h - height of rectangle + * @param mode - Whatever OR combination of VlfFadeModesFlags + * @param speed - The fade speed, one of VlfFadeSpeed + * @param direction_out - If both, VLF_FADE_MODE_IN and VLF_FADE_MODE_OUT, were specified, this param indicates + * wether to start from direction out or in. Otherwise, it is ignored. + * + * @returns - < 0 on error. +*/ +int vlfGuiSetRectangleFade(int x, int y, int w, int h, int mode, int effect, int direction_out, void (* callback)(void *), void *param, int delay); + +/** + * Makes all items within a rectangle to blink + * + * @param x - x position of rectangle + * @param y - y position of rectangle + * @param w - width of rectangle + * @param h - height of rectangle + * @param nshow - the numbers of frames the items will be shown + * @param nhide - the numbers of frames the items will be hidden + * + * @returns - < 0 on error. + * + * @Note: currently not all kind of items can blink. This will be fixed in future. +*/ +int vlfGuiSetRectangleBlinking(int x, int y, int w, int h, u32 nshow, u32 nhide); + +/** + * Synchronizes the blinking of one item with the one of a second one + * + * @param dst - the destiny item + * @param dst_type - the type of the destiny object, one of VlfObjects + * @param src - the source item + * @param src_type - the type of source object, one of VlfObjects + * + * @returns - < 0 on error +*/ +int vlfGuiSetSynchronizedBlinking(void *dst, int dst_type, void *src, int src_type); + +/** + * Shows a message dialog. + * + * @param msg - the message dialog + * @param flags - a combination of VLF_MDType, VLF_MD_Buttons and VLF_MD_InitalCursor + * + * @returns - one of VLF_MD_ButtonRes +*/ +int vlfGuiMessageDialog(char *msg, u32 flags); + +/** + * Shows an error dialog. + * + * @param error - the system error code + * + * @returns - one of VLF_MD_ButtonRes +*/ +int vlfGuiErrorDialog(int error); + +/** + * Shows a net config dialog. + * Network libraries must be loaded before. + * + * @returns 0 if the connection was done. +*/ +int vlfGuiNetConfDialog(); + +/** + * Shows an OSK dialog. + * + * @param intext - the initial text of the OSK, NULL if no required + * @param desc - the description that will be shown in the OSK, NULL if no required + * @param outtext - the output text + * + * @returns 0 if the text was entered. +*/ +int vlfGuiOSKDialog(u16 *intext, u16 *desc, u16 *outtext); + +/** + * Shows one or two buttons with enter/cancel icons at bottom of screen. + * Button presses are handled by the library. + * + * @param button1 - a button code, one of VLF_DialogItem. < 0 if no required + * @param button2 - a button code, one of VLF_DialogItem- < 0 if no required + * @param automatic - if automatic is 0, button1 will be the left button and button2 will be right button. + * Otherwise, the buttons are rearranged automatically acording to current button configuration. + * @param enter_is_left - if automatic is 0, this button indicates which button is assigned enter. + * @param distance - the distance between the buttons, use VLF_DEFAULT for a default distance + * @param handler - the function that will be called when enter/cancel are pressed. The function shall return VLF_REMOVE_HANDLERS if it + * wants to cancel further events, VLF_REMOVE_OBJECTS to remove bottom dialog, or both to fully remove the bottom dialog. + * + * @returns - < 0 on error. +*/ +int vlfGuiBottomDialog(int button1, int button2, int automatic, int enter_is_left, int distance, int (* handler)(int enter)); + +/** + * Shows one or two buttons with enter/cancel icons at bottom of screen. + * Button presses are handled by the library. + * + * @param button1 - button string. NULL if no required + * @param button2 - button string. NULL if no required + * @param automatic - if automatic is 0, button1 will be the left button and button2 will be right button. + * Otherwise, the buttons are rearranged automatically acording to current button configuration. + * @param enter_is_left - if automatic is 0, this button indicates which button is assigned enter. + * @param distance - the distance between the buttons, use VLF_DEFAULT for a default distance + * @param handler - the function that will be called when enter/cancel are pressed, enter param indicates if enter was pressed, otherwise cancel was pressed. + * The function shall return VLF_REMOVE_HANDLERS if it wants to cancel further events, VLF_REMOVE_OBJECTS to remove buttons, + * or both to fully remove the bottom dialog. + * + * @returns - < 0 on error. + */ +int vlfGuiCustomBottomDialog(char *button1, char *button2, int automatic, int enter_is_left, int distance, int (* handler)(int enter)); + +/** + * Cancels (remove) the bottom dialog +*/ +void vlfGuiCancelBottomDialog(); + +/** + * Creates a central menu. + * Button presses of menu are automatically handled by the library + * + * @param noptions - number of options of the menu + * @param items - an array of noptions strings + * @param defaultsel- the index of the item with the initial selection + * @param handler - the function that will be called on enter button is pressed. sel param is the index of the selected item. + * The function shall return VLF_REMOVE_HANDLERS if it wants to cancel further events, VLF_REMOVE_OBJECTS to remove items, + * or both to fully remove the central menu. + * @param dispx - displacement relative to the default centered position (x) + * @param dispy - displacement relative to the default centered position (y) + * + * @returns - < 0 on error +*/ +int vlfGuiCentralMenu(int noptions, char **items, int defaultsel, int (* handler)(int sel), int dispx, int dispy); + +/** + * Cancels (remove) the central menu +*/ +void vlfGuiCancelCentralMenu(); + +/** + * Returns the current selected item of the central menu + * + * @returns - the selected item +*/ +int vlfGuiCentralMenuSelection(); + +/** + * Creates a lateral menu with current system color. + * Button presses of menu are automatically handled by the library + * + * @param noptions - number of options of the menu + * @param items - an array of noptions strings + * @param defaultsel- the index of the item with the initial selection + * @param handler - the function that will be called on enter button is pressed. sel param is the index of the selected item. + * The function shall return VLF_REMOVE_HANDLERS if it wants to cancel further events, VLF_REMOVE_OBJECTS to remove menu, + * or both to fully remove the lateral menu. + * @param y - y position of first item + * + * @returns - < 0 on error +*/ +int vlfGuiLateralMenu(int noptions, char **items, int defaultsel, int (* handler)(int sel), int y); + +/** + * Creates a lateral menu with desired color. + * Button presses of menu are automatically handled by the library + * + * @param noptions - number of options of the menu + * @param items - an array of noptions strings + * @param defaultsel- the index of the item with the initial selection + * @param handler - the function that will be called on enter button is pressed. sel param is the index of the selected item. + * The function shall return VLF_REMOVE_HANDLERS if it wants to cancel further events, VLF_REMOVE_OBJECTS to remove menu, + * or both to fully remove the lateral menu. + * @param y - y position of first item + * @param color - the color of the lateral menu + * + * @returns - < 0 on error +*/ +int vlfGuiLateralMenuEx(int noptions, char **items, int defaultsel, int (* handler)(int sel), int y, u32 color); + +/** + * Cancels (remove) the lateral menu + */ +void vlfGuiCancelLateralMenu(); + +/** + * Returns the current selected item of the lateral menu + * + * @returns - the selected item + */ +int vlfGuiLateralMenuSelection(); + +/** + * Creates a control for previous page handling. + * + * @param handler - the function that will be called when the previous button (left) is pressed. page parameter holds the page number. + * The function shall return VLF_REMOVE_HANDLERS if it wants to cancel further events, VLF_REMOVE_OBJECTS to remove control pics and text, + * or both to fully remove the control. + * + * @returns - < 0 on error +*/ +int vlfGuiPreviousPageControl(int (* handler)(int page)); + +/** + * Creates a control for next page handling. + * + * @param handler - the function that will be called when the next button (right) is pressed. page parameter holds the page number. + * The function shall return VLF_REMOVE_HANDLERS if it wants to cancel further events, VLF_REMOVE_OBJECTS to remove control pics and text, + * or both to fully remove the control. + * + * @returns - < 0 on error + */ +int vlfGuiNextPageControl(int (* handler)(int page)); + +/** + * Cancels (remove) previous page control +*/ +void vlfGuiCancelPreviousPageControl(); + +/** + * Cancels (remove) next page control + */ +void vlfGuiCancelNextPageControl(); + +/** + * Enable or disable page control.(it does not add/remove them). + * + * @param enable - enable or disable +*/ +void vlfGuiSetPageControlEnable(int enable); + +/** + * Adds a handler for an event. + * + * @param buttons - the button event, 0 if no event (will be called every frame) + * @param wait - wait for the handler to be added. Use 0 for no wait, and -1 to make this handler impossible to delay. + * @param func - the function that will be called when the event happens. + * @param param - custom param for the handler function. The function must return one or a combination of following values: + * + * VLF_EV_RET_NOTHING: normal return, it does nothing. + * VLF_EV_RET_REMOVE_EVENT: it removes the event (button press), so other handler doesn't receive it. + * VLF_EV_RET_REMOVE_HANDLERS: it removes this handler so that it won't receive more event notifications. + * VLF_EV_RET_DELAY: the event is delayed for specified number of miliseconds. VLF_EV_RET_DELAY | (X << 16), where 0 <= X <= 32727 + * VLF_EV_RET_DELAY_FRAME: the event is delayed for specified number of frames. VLF_EV_RET_DELAY_FRAME | (X << 16), where 0 <= X <= 4095 + * VLF_EV_RET_REFRESH_ON_DELAY: the event is refreshed after a delay, so that if button/s are kept pressed until after the event, it will receive it as a new event + * + * @returns - < 0 on error +*/ +int vlfGuiAddEventHandler(int buttons, int wait, int (* func)(void *), void *param); + +/** + * Adds a handler for an event. + * Unlike the previous function, this one adds the handler to the head instead of the tail. + * + * @param buttons - the button event, 0 if no event (will be called every frame) + * @param wait - wait for the handler to be added. Use 0 for no wait, and -1 to make this handler impossible to delay. + * @param func - the function that will be called when the event happens. + * @param param - custom param for the handler function. The function must return one or a combination of following values: + * + * VLF_EV_RET_NOTHING: normal return, it does nothing. + * VLF_EV_RET_REMOVE_EVENT: it removes the event (button press), so other handler doesn't receive it. + * VLF_EV_RET_REMOVE_HANDLERS: it removes this handler so that it won't receive more event notifications. + * VLF_EV_RET_DELAY: the event is delayed for specified number of miliseconds. VLF_EV_RET_DELAY | (X << 16), where 0 <= X <= 32727 + * VLF_EV_RET_DELAY_FRAME: the event is delayed for specified number of frames. VLF_EV_RET_DELAY_FRAME | (X << 16), where 0 <= X <= 4095 + * VLF_EV_RET_REFRESH_ON_DELAY: the event is refreshed after a delay, so that if button/s are kept pressed until after the event, it will receive it as a new event + * + * @returns - < 0 on error +*/ +int vlfGuiAddEventHandlerHead(int buttons, int wait, int (* func)(void *), void *param); + +/** + * Adds a handler for a negative event. + * + * @param buttons - the negative button event. For Example if you pass PSP_CTRL_CROSS, it will mean NOT PSP_CTRL_CROSS pressed. + * @param wait - wait for the handler to be added. Use 0 for no wait, and -1 to make this handler impossible to delay. + * @param func - the function that will be called when the event happens. + * @param param - custom param for the handler function. The function must return one or a combination of following values: + * + * VLF_EV_RET_NOTHING: normal return, it does nothing. + * VLF_EV_RET_REMOVE_EVENT: it removes the event (button press), so other handler doesn't receive it. + * VLF_EV_RET_REMOVE_HANDLERS: it removes this handler so that it won't receive more event notifications. + * VLF_EV_RET_DELAY: the event is delayed for specified number of miliseconds. VLF_EV_RET_DELAY | (X << 16), where 0 <= X <= 32727 + * VLF_EV_RET_DELAY_FRAME: the event is delayed for specified number of frames. VLF_EV_RET_DELAY_FRAME | (X << 16), where 0 <= X <= 4095 + * VLF_EV_RET_REFRESH_ON_DELAY: the event is refreshed after a delay, so that if button/s are kept pressed until after the event, it will receive it as a new event + * + * @returns - < 0 on error + */ +int vlfGuiAddNegativeEventHandler(int buttons, int wait, int (* func)(void *), void *param); + +/** + * Adds a handler for a negative event. + * Unlike the previous function, this one adds the handler to the head instead of the tail. + * + * @param buttons - the negative button event. For Example if you pass PSP_CTRL_CROSS, it will mean NOT PSP_CTRL_CROSS pressed. + * @param wait - wait for the handler to be added. Use 0 for no wait, and -1 to make this handler impossible to delay. + * @param func - the function that will be called when the event happens. + * @param param - custom param for the handler function. The function must return one or a combination of following values: + * + * VLF_EV_RET_NOTHING: normal return, it does nothing. + * VLF_EV_RET_REMOVE_EVENT: it removes the event (button press), so other handler doesn't receive it. + * VLF_EV_RET_REMOVE_HANDLERS: it removes this handler so that it won't receive more event notifications. + * VLF_EV_RET_DELAY: the event is delayed for specified number of miliseconds. VLF_EV_RET_DELAY | (X << 16), where 0 <= X <= 32727 + * VLF_EV_RET_DELAY_FRAME: the event is delayed for specified number of frames. VLF_EV_RET_DELAY_FRAME | (X << 16), where 0 <= X <= 4095 + * VLF_EV_RET_REFRESH_ON_DELAY: the event is refreshed after a delay, so that if button/s are kept pressed until after the event, it will receive it as a new event + * + * @returns - < 0 on error + */ +int vlfGuiAddNegativeEventHandlerHead(int buttons, int wait, int (* func)(void *), void *param); + +/** + * Removes an event handler. Use vlfGuiRemoveHandlerEx if you have used the same handler with different params. + * + * @param func - the handler function + * + * @returns - < 0 on error +*/ +int vlfGuiRemoveEventHandler(int (* func)(void *)); + +/** + * Removes an event hnadler + * + * @param func - the handler function + * @param param - the parameter that was passed to one of the vlfGuiAddEventHandler functions. + * + * @returns - < 0 on error +*/ +int vlfGuiRemoveEventHandlerEx(int (* func)(void *), void *param); + +/** + * Boolean function that checks if a handler is registered + * + * @param func - the handler to be checked. + * + * @return - < 0 on error +*/ +int vlfGuiIsEventRegistered(int (* func)(void *)); + +/** + * Delays an event handler. Use vlfGuiSetEventDelayEx if you have used the same handler with different params. + * + * @param func - the handler function + * @param delay - the delay in milisecs + * + * @return - < 0 on error +*/ +int vlfGuiSetEventDelay(int (* func)(void *), u32 delay); + +/** + * Delays an event handler. + * + * @param func - the handler function + * @param param - the parameter that was passed to one of the vlfGuiAddEventHandler functions. + * @param delay - the delay in milisecs + * + * @return - < 0 on error + */ +int vlfGuiSetEventDelayEx(int (* func)(void *), void * param, u32 delay); + +/** + * Delays all events that can be delayed + * + * @param delay - the delay in milisecs + * + * @returns - < 0 on error +*/ +int vlfGuiDelayAllEvents(u32 delay); + + + +#endif + diff --git a/libs/lib/libpspsystemctrl_kernel.a b/libs/lib/libpspsystemctrl_kernel.a new file mode 100644 index 0000000..dc18b95 Binary files /dev/null and b/libs/lib/libpspsystemctrl_kernel.a differ diff --git a/libs/lib/libvlfgu.a b/libs/lib/libvlfgu.a new file mode 100755 index 0000000..aecd297 Binary files /dev/null and b/libs/lib/libvlfgu.a differ diff --git a/libs/lib/libvlfgui.a b/libs/lib/libvlfgui.a new file mode 100755 index 0000000..583e748 Binary files /dev/null and b/libs/lib/libvlfgui.a differ diff --git a/libs/lib/libvlflibc.a b/libs/lib/libvlflibc.a new file mode 100755 index 0000000..0aa9270 Binary files /dev/null and b/libs/lib/libvlflibc.a differ diff --git a/libs/lib/libvlfutils.a b/libs/lib/libvlfutils.a new file mode 100755 index 0000000..67b548e Binary files /dev/null and b/libs/lib/libvlfutils.a differ