├── .github └── workflows │ └── build.yml ├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── assets ├── audio │ └── .gitkeep ├── fonts │ └── Gontserrat-Regular.ttf ├── images │ └── psl1ght.tga ├── misc │ └── .gitkeep └── videos │ └── .gitkeep ├── client ├── Makefile └── source │ └── main.c ├── ps4load ├── copper.c ├── main.c ├── scroller.c ├── ttf.c └── ttf.h ├── sce_module ├── libSceFios2.prx └── libc.prx └── sce_sys ├── about └── right.sprx └── icon0.png /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build package 2 | 3 | on: [ push, pull_request, workflow_dispatch ] 4 | 5 | jobs: 6 | build_pkg: 7 | runs-on: ubuntu-20.04 8 | steps: 9 | 10 | - name: Checkout 11 | uses: actions/checkout@v3 12 | 13 | - name: Checkout dbglogger 14 | uses: actions/checkout@v3 15 | with: 16 | repository: bucanero/dbglogger 17 | path: dbglogger 18 | 19 | - name: Checkout zip 20 | uses: actions/checkout@v3 21 | with: 22 | repository: bucanero/zip 23 | path: zip 24 | 25 | - name: Checkout oosdk_libraries 26 | uses: actions/checkout@v3 27 | with: 28 | repository: bucanero/oosdk_libraries 29 | path: oosdk_libraries 30 | 31 | - name: Checkout SDL-PS4 32 | uses: actions/checkout@v3 33 | with: 34 | repository: bucanero/SDL-PS4 35 | path: SDL-PS4 36 | ref: ps4 37 | 38 | - name: Set env vars 39 | id: slug 40 | run: | 41 | echo "sha_name=$(echo ${GITHUB_SHA} | cut -c1-8)" >> $GITHUB_ENV 42 | echo "llvm_ver=12.0" >> $GITHUB_ENV 43 | 44 | # temporary release until 0.53 is released 45 | - name: Download OpenOrbis Toolchain 46 | run: | 47 | curl -sL https://github.com/illusion0001/OpenOrbis-PS4-Toolchain/releases/download/0.0.1.416/toolchain.tar.gz | tar xvz -C ./ 48 | echo "OO_PS4_TOOLCHAIN=${GITHUB_WORKSPACE}/OpenOrbis/PS4Toolchain" >> $GITHUB_ENV 49 | cp oosdk_libraries/build_rules.mk OpenOrbis/PS4Toolchain/build_rules.mk 50 | 51 | - name: Cache LLVM and Clang 52 | id: cache-llvm 53 | uses: actions/cache@v3 54 | with: 55 | path: ./llvm 56 | key: llvm-${{ env.llvm_ver }} 57 | 58 | - name: Install LLVM and Clang 59 | uses: KyleMayes/install-llvm-action@v1 60 | with: 61 | version: ${{ env.llvm_ver }} 62 | cached: ${{ steps.cache-llvm.outputs.cache-hit }} 63 | 64 | - name: Install zlib 65 | working-directory: oosdk_libraries/zlib_partial 66 | run: | 67 | make install 68 | 69 | - name: Install zip 70 | working-directory: zip 71 | run: | 72 | make install 73 | 74 | - name: Install dbglogger 75 | working-directory: dbglogger 76 | run: | 77 | make -f Makefile.PS4 install 78 | 79 | - name: Install SDL2 library 80 | working-directory: SDL-PS4 81 | run: | 82 | mkdir orbis && cd orbis 83 | cmake --toolchain ../cmake/openorbis.cmake .. 84 | make 85 | cp libSDL2.a "${OO_PS4_TOOLCHAIN}/lib" 86 | 87 | - name: Build App Package 88 | run: | 89 | make 90 | 91 | - name: Push package artifact 92 | uses: actions/upload-artifact@v3 93 | with: 94 | name: ps4load-build_${{ env.sha_name }} 95 | path: IV0000-LOAD00044_00-SDL2GLES20000000.pkg 96 | if-no-files-found: error 97 | retention-days: 7 98 | # don't keep artifacts for too long 99 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | .tmp_versions/ 49 | modules.order 50 | Module.symvers 51 | Mkfile.old 52 | dkms.conf 53 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Package metadata. 2 | TITLE := PS4Load 3 | VERSION := 00.51 4 | TITLE_ID := LOAD00044 5 | CONTENT_ID := IV0000-LOAD00044_00-SDL2GLES20000000 6 | 7 | # Libraries linked into the ELF. 8 | LIBS := -lc -lkernel -ldbglogger -lSceSystemService -lSceSysmodule -lScePigletv2VSH -lSceAudioOut -lScePad \ 9 | -lSceUserService -lSceFreeType -lSDL2 -lSDL2_image -lzip -lz -lSceNetCtl 10 | 11 | # Additional compile flags. 12 | #EXTRAFLAGS := 13 | 14 | # Asset and module directories. 15 | ASSETS := $(wildcard assets/**/*) 16 | LIBMODULES := $(wildcard sce_module/*) 17 | 18 | # You likely won't need to touch anything below this point. 19 | 20 | # Root vars 21 | TOOLCHAIN := $(OO_PS4_TOOLCHAIN) 22 | PROJDIR := $(shell basename $(CURDIR)) 23 | INTDIR := $(PROJDIR)/x64/Debug 24 | 25 | # Define objects to build 26 | CFILES := $(wildcard $(PROJDIR)/*.c) 27 | CPPFILES := $(wildcard $(PROJDIR)/*.cpp) 28 | OBJS := $(patsubst $(PROJDIR)/%.c, $(INTDIR)/%.o, $(CFILES)) $(patsubst $(PROJDIR)/%.cpp, $(INTDIR)/%.o, $(CPPFILES)) 29 | 30 | # Define final C/C++ flags 31 | CFLAGS := --target=x86_64-pc-freebsd12-elf -fPIC -funwind-tables -c $(EXTRAFLAGS) -isysroot $(TOOLCHAIN) -isystem $(TOOLCHAIN)/include -Iinclude 32 | CXXFLAGS := $(CFLAGS) -isystem $(TOOLCHAIN)/include/c++/v1 33 | LDFLAGS := -m elf_x86_64 -pie --script $(TOOLCHAIN)/link.x --eh-frame-hdr -L$(TOOLCHAIN)/lib $(LIBS) $(TOOLCHAIN)/lib/crt1.o 34 | 35 | # Create the intermediate directory incase it doesn't already exist. 36 | _unused := $(shell mkdir -p $(INTDIR)) 37 | 38 | # Check for linux vs macOS and account for clang/ld path 39 | UNAME_S := $(shell uname -s) 40 | 41 | ifeq ($(UNAME_S),Linux) 42 | CC := clang 43 | CCX := clang++ 44 | LD := ld.lld 45 | CDIR := linux 46 | endif 47 | ifeq ($(UNAME_S),Darwin) 48 | CC := /usr/local/opt/llvm/bin/clang 49 | CCX := /usr/local/opt/llvm/bin/clang++ 50 | LD := /usr/local/opt/llvm/bin/ld.lld 51 | CDIR := macos 52 | endif 53 | 54 | all: $(CONTENT_ID).pkg 55 | 56 | $(CONTENT_ID).pkg: pkg.gp4 57 | $(TOOLCHAIN)/bin/$(CDIR)/PkgTool.Core pkg_build $< . 58 | 59 | pkg.gp4: eboot.bin sce_sys/about/right.sprx sce_sys/param.sfo sce_sys/icon0.png $(LIBMODULES) $(ASSETS) 60 | $(TOOLCHAIN)/bin/$(CDIR)/create-gp4 -out $@ --content-id=$(CONTENT_ID) --files "$^" 61 | 62 | sce_sys/param.sfo: Makefile 63 | $(TOOLCHAIN)/bin/$(CDIR)/PkgTool.Core sfo_new $@ 64 | $(TOOLCHAIN)/bin/$(CDIR)/PkgTool.Core sfo_setentry $@ APP_TYPE --type Integer --maxsize 4 --value 1 65 | $(TOOLCHAIN)/bin/$(CDIR)/PkgTool.Core sfo_setentry $@ APP_VER --type Utf8 --maxsize 8 --value '$(VERSION)' 66 | $(TOOLCHAIN)/bin/$(CDIR)/PkgTool.Core sfo_setentry $@ ATTRIBUTE --type Integer --maxsize 4 --value 32 67 | $(TOOLCHAIN)/bin/$(CDIR)/PkgTool.Core sfo_setentry $@ CATEGORY --type Utf8 --maxsize 4 --value 'gde' 68 | $(TOOLCHAIN)/bin/$(CDIR)/PkgTool.Core sfo_setentry $@ CONTENT_ID --type Utf8 --maxsize 48 --value '$(CONTENT_ID)' 69 | $(TOOLCHAIN)/bin/$(CDIR)/PkgTool.Core sfo_setentry $@ DOWNLOAD_DATA_SIZE --type Integer --maxsize 4 --value 0 70 | $(TOOLCHAIN)/bin/$(CDIR)/PkgTool.Core sfo_setentry $@ SYSTEM_VER --type Integer --maxsize 4 --value 0 71 | $(TOOLCHAIN)/bin/$(CDIR)/PkgTool.Core sfo_setentry $@ TITLE --type Utf8 --maxsize 128 --value '$(TITLE)' 72 | $(TOOLCHAIN)/bin/$(CDIR)/PkgTool.Core sfo_setentry $@ TITLE_ID --type Utf8 --maxsize 12 --value '$(TITLE_ID)' 73 | $(TOOLCHAIN)/bin/$(CDIR)/PkgTool.Core sfo_setentry $@ VERSION --type Utf8 --maxsize 8 --value '$(VERSION)' 74 | 75 | eboot.bin: $(INTDIR) $(OBJS) 76 | $(LD) $(INTDIR)/*.o -o $(INTDIR)/$(PROJDIR).elf $(LDFLAGS) 77 | $(TOOLCHAIN)/bin/$(CDIR)/create-fself -in=$(INTDIR)/$(PROJDIR).elf -out=$(INTDIR)/$(PROJDIR).oelf --eboot "eboot.bin" --paid 0x3800000000000011 --authinfo 000000000000000000000000001C004000FF000000000080000000000000000000000000000000000000008000400040000000000000008000000000000000080040FFFF000000F000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 78 | 79 | $(INTDIR)/%.o: $(PROJDIR)/%.c 80 | $(CC) $(CFLAGS) -o $@ $< 81 | 82 | $(INTDIR)/%.o: $(PROJDIR)/%.cpp 83 | $(CCX) $(CXXFLAGS) -o $@ $< 84 | 85 | clean: 86 | rm -f $(CONTENT_ID).pkg pkg.gp4 sce_sys/param.sfo eboot.bin \ 87 | $(INTDIR)/$(PROJDIR).elf $(INTDIR)/$(PROJDIR).oelf $(OBJS) 88 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PS4Load 2 | 3 | [![Downloads][img_downloads]][app_downloads] [![Release][img_latest]][app_latest] [![License][img_license]][app_license] 4 | [![Build app package](https://github.com/bucanero/ps4load/actions/workflows/build.yml/badge.svg)](https://github.com/bucanero/ps4load/actions/workflows/build.yml) 5 | 6 | PS4Load is based on the [PSL1GHT](https://github.com/ps3dev/PSL1GHT/) PS3load sample, 7 | now built using the [Open Orbis](https://github.com/OpenOrbis/OpenOrbis-PS4-Toolchain/) SDK. 8 | 9 | I hope this version helps you build PS4 homebrews easily! 10 | 11 | ## Features 12 | 13 | - You can load SELF files using the network. 14 | - You can upload and extract ZIP files to `/data/` over the network. 15 | 16 | ![PS4Load](https://user-images.githubusercontent.com/1153055/167851079-209e3ea3-84b3-4485-88ce-50b77294cf67.jpg) 17 | 18 | ## Usage 19 | 20 | Install the package on your PS4. Open the PS4Load host app, and then use the [ps3load client](https://github.com/bucanero/ps4load/tree/main/client) to send your `eboot.bin` or `.zip` file: 21 | 22 | ### Linux/macOS 23 | 24 | ```bash 25 | export PS3LOAD=tcp:192.168.x.x 26 | ./ps3load /path/to/eboot.bin 27 | ``` 28 | 29 | ### Windows 30 | 31 | ```sh 32 | set PS3LOAD=tcp:192.168.x.x 33 | ps3load.exe \path\to\eboot.bin 34 | ``` 35 | 36 | ## Building 37 | 38 | You need to have installed: 39 | 40 | - [Open Orbis SDK](https://github.com/OpenOrbis/OpenOrbis-PS4-Toolchain/) 41 | - [Zlib](https://github.com/bucanero/oosdk_libraries/tree/master/zlib_partial) library 42 | - [Zip](https://github.com/bucanero/zip) library 43 | - [SDL2](https://github.com/PacBrew/SDL/tree/ps4) library 44 | - [dbglogger](https://github.com/bucanero/dbglogger) library 45 | 46 | Run `make` to create a release build. 47 | 48 | You can also set the `PS3LOAD` environment variable to the PS4 IP address: `export PS3LOAD=tcp:x.x.x.x`. 49 | This will allow you to use a `ps3load` client and send `eboot.bin` directly to the [PS4Load host](https://github.com/bucanero/ps4load). 50 | 51 | PS4Load will also send debug messages to UDP multicast address `239.255.0.100:30000`. 52 | To receive them you can use [socat][] on your computer: 53 | 54 | $ socat udp4-recv:30000,ip-add-membership=239.255.0.100:0.0.0.0 - 55 | 56 | ## License 57 | 58 | [PS4Load](https://github.com/bucanero/ps4load/) - Copyright (C) 2022 [Damian Parrino](https://twitter.com/dparrino) 59 | 60 | This program is free software: you can redistribute it and/or modify 61 | it under the terms of the [GNU General Public License](LICENSE) as published by 62 | the Free Software Foundation, either version 2 of the License, or 63 | (at your option) any later version. 64 | 65 | [socat]: http://www.dest-unreach.org/socat/ 66 | [app_downloads]: https://github.com/bucanero/ps4load/releases 67 | [app_latest]: https://github.com/bucanero/ps4load/releases/latest 68 | [app_license]: https://github.com/bucanero/ps4load/blob/master/LICENSE 69 | [img_downloads]: https://img.shields.io/github/downloads/bucanero/ps4load/total.svg?maxAge=3600 70 | [img_latest]: https://img.shields.io/github/release/bucanero/ps4load.svg?maxAge=3600 71 | [img_license]: https://img.shields.io/github/license/bucanero/ps4load.svg?maxAge=2592000 72 | -------------------------------------------------------------------------------- /assets/audio/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bucanero/ps4load/290d979d9ce144c7985659029a030ea540375cc0/assets/audio/.gitkeep -------------------------------------------------------------------------------- /assets/fonts/Gontserrat-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bucanero/ps4load/290d979d9ce144c7985659029a030ea540375cc0/assets/fonts/Gontserrat-Regular.ttf -------------------------------------------------------------------------------- /assets/images/psl1ght.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bucanero/ps4load/290d979d9ce144c7985659029a030ea540375cc0/assets/images/psl1ght.tga -------------------------------------------------------------------------------- /assets/misc/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bucanero/ps4load/290d979d9ce144c7985659029a030ea540375cc0/assets/misc/.gitkeep -------------------------------------------------------------------------------- /assets/videos/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bucanero/ps4load/290d979d9ce144c7985659029a030ea540375cc0/assets/videos/.gitkeep -------------------------------------------------------------------------------- /client/Makefile: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------------------------------------- 2 | .SUFFIXES: 3 | #--------------------------------------------------------------------------------- 4 | 5 | #--------------------------------------------------------------------------------- 6 | # TARGET is the name of the output 7 | # BUILD is the directory where object files & intermediate files will be placed 8 | # SOURCES is a list of directories containing source code 9 | # INCLUDES is a list of directories containing extra header files 10 | #--------------------------------------------------------------------------------- 11 | TARGET := ps3load 12 | BUILD := build 13 | SOURCES := source 14 | INCLUDES := include 15 | #--------------------------------------------------------------------------------- 16 | # options for code generation 17 | #--------------------------------------------------------------------------------- 18 | DEBUGFLAGS := 19 | CFLAGS := $(DEBUGFLAGS) -Wall -O3\ 20 | 21 | CFLAGS += $(INCLUDE) 22 | 23 | LDFLAGS = $(DEBUGFLAGS) 24 | 25 | UNAME := $(shell uname -s) 26 | 27 | ifeq ($(strip $(PS3DEV)),) 28 | ifeq ($(strip $(DEVKITPS3)),) 29 | export PS3DEV := /usr/local/ps3dev 30 | else 31 | export PS3DEV := $(DEVKITPS3) 32 | endif 33 | endif 34 | 35 | ifneq (,$(findstring MINGW,$(UNAME))) 36 | EXEEXT := .exe 37 | PLATFORM_LIBS := -static -lws2_32 38 | endif 39 | 40 | ifneq (,$(findstring Darwin,$(shell uname -s))) 41 | SDK := $(shell xcrun --show-sdk-path) 42 | OSX_MIN := $(shell defaults read $(shell xcrun --show-sdk-platform-path)/Info MinimumSDKVersion 2> /dev/null || 10.4) 43 | OSXCFLAGS := -mmacosx-version-min=$(OSX_MIN) -isysroot $(SDK) 44 | OSXCXXFLAGS := $(OSXCFLAGS) 45 | CXXFLAGS += -fvisibility=hidden 46 | LDFLAGS += -mmacosx-version-min=$(OSX_MIN) -Wl,-syslibroot,$(SDK) 47 | endif 48 | 49 | ifneq (,$(findstring SunOS,$(UNAME))) 50 | PLATFORM_LIBS := -lresolv -lsocket -lnsl 51 | endif 52 | 53 | #--------------------------------------------------------------------------------- 54 | # any extra libraries we wish to link with the project 55 | #--------------------------------------------------------------------------------- 56 | LIBS := $(PLATFORM_LIBS) -lz 57 | #--------------------------------------------------------------------------------- 58 | # list of directories containing libraries, this must be the top level containing 59 | # include and lib 60 | #--------------------------------------------------------------------------------- 61 | LIBDIRS := 62 | #--------------------------------------------------------------------------------- 63 | # no real need to edit anything past this point unless you need to add additional 64 | # rules for different file extensions 65 | #--------------------------------------------------------------------------------- 66 | ifneq ($(BUILD),$(notdir $(CURDIR))) 67 | #--------------------------------------------------------------------------------- 68 | 69 | 70 | export OUTPUT := $(CURDIR)/$(TARGET)$(EXEEXT) 71 | 72 | export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) 73 | 74 | export CC := gcc 75 | export CXX := g++ 76 | export AR := ar 77 | export OBJCOPY := objcopy 78 | 79 | #--------------------------------------------------------------------------------- 80 | # automatically build a list of object files for our project 81 | #--------------------------------------------------------------------------------- 82 | CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) 83 | CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) 84 | SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) 85 | 86 | export OFILES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) 87 | #--------------------------------------------------------------------------------- 88 | # use CXX for linking C++ projects, CC for standard C 89 | #--------------------------------------------------------------------------------- 90 | ifeq ($(strip $(CPPFILES)),) 91 | #--------------------------------------------------------------------------------- 92 | export LD := $(CC) 93 | #--------------------------------------------------------------------------------- 94 | else 95 | #--------------------------------------------------------------------------------- 96 | export LD := $(CXX) 97 | #--------------------------------------------------------------------------------- 98 | endif 99 | #--------------------------------------------------------------------------------- 100 | 101 | export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ 102 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ 103 | -I$(CURDIR)/$(BUILD) 104 | 105 | export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) 106 | 107 | .PHONY: $(BUILD) clean 108 | 109 | #--------------------------------------------------------------------------------- 110 | $(BUILD): 111 | @[ -d $@ ] || mkdir -p $@ 112 | @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile 113 | 114 | #--------------------------------------------------------------------------------- 115 | clean: 116 | @echo clean ... 117 | @rm -fr $(BUILD) $(OUTPUT) 118 | 119 | #--------------------------------------------------------------------------------- 120 | install: $(BUILD) 121 | @echo Installing $(TARGET)$(EXEEXT) 122 | @[ -d $(PS3DEV)/bin ] || mkdir -p $(PS3DEV)/bin 123 | @install -m 755 $(OUTPUT) $(PS3DEV)/bin 124 | 125 | #--------------------------------------------------------------------------------- 126 | run: 127 | $(OUTPUT) 128 | 129 | #--------------------------------------------------------------------------------- 130 | else 131 | 132 | DEPENDS := $(OFILES:.o=.d) 133 | 134 | 135 | #--------------------------------------------------------------------------------- 136 | # main targets 137 | #--------------------------------------------------------------------------------- 138 | $(OUTPUT) : $(OFILES) 139 | @echo linking ... $(notdir $@) 140 | @$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@ 141 | 142 | #--------------------------------------------------------------------------------- 143 | # Compile Targets for C/C++ 144 | #--------------------------------------------------------------------------------- 145 | 146 | #--------------------------------------------------------------------------------- 147 | %.o : %.cpp 148 | @echo $(notdir $<) 149 | @$(CXX) -E -MMD $(CFLAGS) $< > /dev/null 150 | @$(CXX) $(OSXCXXFLAGS) $(CFLAGS) -o $@ -c $< 151 | 152 | #--------------------------------------------------------------------------------- 153 | %.o : %.c 154 | @echo $(notdir $<) 155 | @$(CC) -E -MMD $(CFLAGS) $< > /dev/null 156 | @$(CC) $(OSXCFLAGS) $(CFLAGS) -o $@ -c $< 157 | 158 | -include $(DEPENDS) 159 | 160 | #--------------------------------------------------------------------------------- 161 | endif 162 | #--------------------------------------------------------------------------------- 163 | -------------------------------------------------------------------------------- /client/source/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008 dhewg, #wiidev efnet 3 | * 4 | * this file is part of geckoloader 5 | * http://wiibrew.org/index.php?title=Geckoloader 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #ifndef _WIN32 32 | #include 33 | #include 34 | #include 35 | #include 36 | #else 37 | #include 38 | #endif 39 | 40 | #include 41 | 42 | #ifndef __WIN32__ 43 | static const char *desc_export = "export"; 44 | #else 45 | static const char *desc_export = "set"; 46 | #endif 47 | 48 | #define PS3LOAD_VERSION_MAYOR 0 49 | #define PS3LOAD_VERSION_MINOR 5 50 | 51 | #define LD_TCP_PORT 4299 52 | 53 | #define MAX_ARGS_LEN 1024 54 | 55 | #ifndef O_BINARY 56 | #define O_BINARY 0 57 | #endif 58 | 59 | typedef unsigned char u8; 60 | typedef unsigned short u16; 61 | typedef unsigned int u32; 62 | typedef unsigned long long u64; 63 | typedef signed char s8; 64 | typedef signed short s16; 65 | typedef signed int s32; 66 | typedef signed long long s64; 67 | 68 | typedef enum { false, true } bool; 69 | 70 | 71 | static const char *envvar = "PS3LOAD"; 72 | 73 | static bool tcp_write (int s, const void *buf, u32 len) { 74 | s32 left, block; 75 | const char *p; 76 | 77 | left = len; 78 | p = buf; 79 | while (left) { 80 | block = send (s, p, left, 0); 81 | 82 | if (block < 0) { 83 | perror ("send failed"); 84 | return false; 85 | } 86 | 87 | left -= block; 88 | p += block; 89 | } 90 | 91 | return true; 92 | } 93 | 94 | static bool send_tcp (const char *host, const u8 *buf, u32 len, u32 len_un, 95 | const char *args, u16 args_len) { 96 | struct sockaddr_in sa; 97 | struct hostent *he; 98 | int s, bc; 99 | u8 b[4]; 100 | off_t left, block; 101 | const u8 *p; 102 | 103 | #ifdef __WIN32__ 104 | WSADATA wsa_data; 105 | if (WSAStartup (MAKEWORD(2,2), &wsa_data)) { 106 | printf ("WSAStartup failed\n"); 107 | return false; 108 | } 109 | #endif 110 | 111 | memset (&sa, 0, sizeof (sa)); 112 | 113 | sa.sin_addr.s_addr = inet_addr (host); 114 | 115 | if (sa.sin_addr.s_addr == INADDR_NONE) { 116 | printf ("resolving %s\n", host); 117 | 118 | he = gethostbyname (host); 119 | 120 | if (!he) { 121 | #ifndef __WIN32__ 122 | herror ("error resolving hostname"); 123 | #else 124 | fprintf (stderr, "error resolving hostname\n"); 125 | #endif 126 | return false; 127 | } 128 | 129 | if (he->h_addrtype != AF_INET) { 130 | fprintf (stderr, "unsupported address"); 131 | return false; 132 | } 133 | 134 | sa.sin_addr.s_addr = *((u32 *) he->h_addr); 135 | } 136 | 137 | s = socket (PF_INET, SOCK_STREAM, 0); 138 | 139 | if (s < 0) { 140 | perror ("error creating socket"); 141 | return false; 142 | } 143 | 144 | sa.sin_port = htons (LD_TCP_PORT); 145 | sa.sin_family = AF_INET; 146 | 147 | printf ("connecting to %s:%d\n", inet_ntoa (sa.sin_addr), LD_TCP_PORT); 148 | 149 | if (connect (s, (struct sockaddr *) &sa, sizeof (sa)) == -1) { 150 | perror ("error connecting"); 151 | close (s); 152 | return false; 153 | } 154 | 155 | printf ("sending upload request\n"); 156 | 157 | b[0] = 'H'; 158 | b[1] = 'A'; 159 | b[2] = 'X'; 160 | b[3] = 'X'; 161 | 162 | if (!tcp_write (s, b, 4)) { 163 | close (s); 164 | return false; 165 | } 166 | 167 | b[0] = PS3LOAD_VERSION_MAYOR; 168 | b[1] = PS3LOAD_VERSION_MINOR; 169 | b[2] = (args_len >> 8) & 0xff; 170 | b[3] = args_len & 0xff; 171 | 172 | if (!tcp_write (s, b, 4)) { 173 | close (s); 174 | return false; 175 | } 176 | 177 | printf ("sending file size (%u bytes)\n", len); 178 | 179 | b[0] = (len >> 24) & 0xff; 180 | b[1] = (len >> 16) & 0xff; 181 | b[2] = (len >> 8) & 0xff; 182 | b[3] = len & 0xff; 183 | 184 | if (!tcp_write (s, b, 4)) { 185 | close (s); 186 | return false; 187 | } 188 | 189 | b[0] = (len_un >> 24) & 0xff; 190 | b[1] = (len_un >> 16) & 0xff; 191 | b[2] = (len_un >> 8) & 0xff; 192 | b[3] = len_un & 0xff; 193 | 194 | if (!tcp_write (s, b, 4)) { 195 | close (s); 196 | return false; 197 | } 198 | 199 | printf ("sending data"); 200 | fflush (stdout); 201 | 202 | left = len; 203 | p = buf; 204 | bc = 0; 205 | while (left) { 206 | block = left; 207 | if (block > 4 * 1024) 208 | block = 4 * 1024; 209 | left -= block; 210 | 211 | if (!tcp_write (s, p, block)) { 212 | close (s); 213 | return false; 214 | } 215 | 216 | p += block; 217 | bc++; 218 | 219 | if (!(bc % 16)) { 220 | printf ("."); 221 | fflush (stdout); 222 | } 223 | } 224 | 225 | printf ("\n"); 226 | 227 | if (args_len) { 228 | printf ("sending arguments (%u bytes)\n", args_len); 229 | 230 | if (!tcp_write (s, (u8 *) args, args_len)) { 231 | close (s); 232 | return false; 233 | } 234 | } 235 | 236 | #ifndef __WIN32__ 237 | close (s); 238 | #else 239 | shutdown (s, SD_SEND); 240 | closesocket (s); 241 | WSACleanup (); 242 | #endif 243 | 244 | return true; 245 | } 246 | 247 | static void usage (const char *argv0) { 248 | fprintf (stderr, "set the environment variable %s to a valid " 249 | "destination.\n\n" 250 | "examples:\n" 251 | "\ttcp mode:\n" 252 | "\t\t%s %s=tcp:wii\n" 253 | "\t\t%s %s=tcp:192.168.0.30\n\n" 254 | "usage:\n" 255 | "\t%s \n\n", 256 | envvar, 257 | desc_export, envvar, 258 | desc_export, envvar, 259 | argv0); 260 | exit (EXIT_FAILURE); 261 | } 262 | 263 | int main (int argc, char **argv) { 264 | int fd; 265 | struct stat st; 266 | char *ev; 267 | bool compress = true; 268 | u8 *buf, *bufz; 269 | off_t fsize; 270 | uLongf bufzlen = 0; 271 | u32 len, len_un; 272 | 273 | int i, c; 274 | char args[MAX_ARGS_LEN]; 275 | char *arg_pos; 276 | u16 args_len, args_left; 277 | 278 | bool res; 279 | 280 | printf ("ps3load v%u.%u\n" 281 | "coded by dhewg, #wiidev efnet\n\n", 282 | PS3LOAD_VERSION_MAYOR, PS3LOAD_VERSION_MINOR); 283 | 284 | if (argc < 2) 285 | usage (*argv); 286 | 287 | ev = getenv (envvar); 288 | if (!ev) 289 | usage (*argv); 290 | 291 | fd = open (argv[1], O_RDONLY | O_BINARY); 292 | if (fd < 0) { 293 | perror ("error opening the file"); 294 | exit (EXIT_FAILURE); 295 | } 296 | 297 | if (fstat (fd, &st)) { 298 | close (fd); 299 | perror ("error stat'ing the file"); 300 | exit (EXIT_FAILURE); 301 | } 302 | 303 | fsize = st.st_size; 304 | 305 | if (fsize < 512){ 306 | close (fd); 307 | fprintf (stderr, "error: invalid file size\n"); 308 | exit (EXIT_FAILURE); 309 | } 310 | 311 | buf = malloc (fsize); 312 | if (!buf) { 313 | close (fd); 314 | fprintf (stderr, "out of memory\n"); 315 | exit (EXIT_FAILURE); 316 | } 317 | 318 | if (read (fd, buf, fsize) != fsize) { 319 | close (fd); 320 | free (buf); 321 | perror ("error reading the file"); 322 | exit (EXIT_FAILURE); 323 | } 324 | close (fd); 325 | 326 | len = fsize; 327 | len_un = 0; 328 | 329 | if (!memcmp(buf, "PK\x03\x04", 4)) 330 | compress = false; 331 | 332 | if (compress) { 333 | bufzlen = (uLongf) ((float) fsize * 1.02); 334 | 335 | bufz = malloc (bufzlen); 336 | if (!bufz) { 337 | fprintf (stderr, "out of memory\n"); 338 | exit (EXIT_FAILURE); 339 | } 340 | 341 | printf("compressing %u bytes...", (u32) fsize); 342 | fflush(stdout); 343 | 344 | res = compress2 (bufz, &bufzlen, buf, fsize, 6); 345 | if (res != Z_OK) { 346 | free(buf); 347 | free(bufz); 348 | fprintf (stderr, "error compressing data: %d\n", res); 349 | exit (EXIT_FAILURE); 350 | } 351 | 352 | if (bufzlen < (u32) fsize) { 353 | printf(" %.2f%%\n", 100.0f * (float) bufzlen / (float) fsize); 354 | 355 | len = bufzlen; 356 | len_un = fsize; 357 | free(buf); 358 | buf = bufz; 359 | } else { 360 | printf(" compressed size gained size, discarding\n"); 361 | free(bufz); 362 | } 363 | } 364 | 365 | args_len = 0; 366 | 367 | arg_pos = args; 368 | args_left = MAX_ARGS_LEN; 369 | 370 | c = snprintf (arg_pos, args_left, "%s", basename (argv[1])); 371 | arg_pos += c + 1; 372 | args_left -= c + 1; 373 | 374 | if (argc > 2) { 375 | for (i = 2; i < argc; ++i) { 376 | c = snprintf (arg_pos, args_left, "%s", argv[i]); 377 | 378 | if (c >= args_left) { 379 | free (buf); 380 | fprintf (stderr, "argument string too long\n"); 381 | exit (EXIT_FAILURE); 382 | } 383 | 384 | arg_pos += c + 1; 385 | args_left -= c + 1; 386 | } 387 | 388 | if (args_left < 1) { 389 | free (buf); 390 | fprintf (stderr, "argument string too long\n"); 391 | exit (EXIT_FAILURE); 392 | } 393 | } 394 | 395 | arg_pos[0] = 0; 396 | args_len = MAX_ARGS_LEN - args_left + 1; 397 | 398 | if (strncmp (ev, "tcp:", 4)) { 399 | usage (*argv); 400 | } else { 401 | if (strlen (ev) < 5) 402 | usage (*argv); 403 | 404 | res = send_tcp (&ev[4], buf, len, len_un, args, args_len); 405 | } 406 | 407 | if (res) 408 | printf ("done.\n"); 409 | else 410 | printf ("transfer failed.\n"); 411 | 412 | free (buf); 413 | 414 | return 0; 415 | } 416 | 417 | -------------------------------------------------------------------------------- /ps4load/copper.c: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2002 W.P. van Paassen - peter@paassen.tmfweb.nl 2 | This program is free software; you can redistribute it and/or modify it under 3 | the terms of the GNU General Public License as published by the Free 4 | Software Foundation; either version 2 of the License, or (at your 5 | option) any later version. 6 | This program is distributed in the hope that it will be useful, but WITHOUT 7 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 8 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 9 | for more details. 10 | You should have received a copy of the GNU General Public License 11 | along with this program; see the file COPYING. If not, write to the Free 12 | Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ 13 | 14 | #include 15 | #include // random(), RAND_MAX 16 | #include // sinf() 17 | 18 | #include 19 | //#include "copper.h" 20 | 21 | #define ARGB(a, r, g, b) (r << 16) | (g << 8) | b 22 | 23 | static uint32_t color[46]; 24 | static uint16_t aSin[360]; 25 | 26 | static uint16_t 27 | red = 96, red2 = 0, red3 = 88, red4 = 0, 28 | red5 = 80, red6 = 0, red7 = 72, red8 = 0, 29 | white = 64, white2 = 0, white3 = 56, white4 = 0, 30 | white5 = 48, white6 = 0, white7 = 40, white8 = 0, 31 | blue = 32, blue2 = 0, blue3 = 24, blue4 = 0, 32 | blue5 = 16, blue6 = 0, blue7 = 8, blue8 = 0; 33 | 34 | 35 | static void compose_fadebar(uint32_t *color, uint8_t idx) 36 | { 37 | /* compose 15 faded colors, (up to 0xFF, stepping 0x20) for each of 15 lines */ 38 | uint8_t step = 0x20, c = step - 1; 39 | 40 | uint32_t *p = &color[idx]; // address pointer to indexed color 41 | 42 | for(uint8_t i=0; i<15; i++) 43 | { 44 | switch(idx) 45 | { 46 | /* red copper bar */ 47 | case 1: *p = ARGB(0xFF, c, c, 0); break; 48 | 49 | /* white copper bar */ 50 | case 16: *p = ARGB(0xFF, c, 0, c); break; 51 | 52 | /* blue copper bar */ 53 | case 31: *p = ARGB(0xFF, 0, c, c); break; 54 | 55 | default: break; 56 | } 57 | if(i == 7) step *= -1; // change step direction 58 | 59 | c += step, p++; 60 | } 61 | p = NULL; // keep safe, don't leave pointer there 62 | } 63 | 64 | void init_copperbars(void) 65 | { 66 | int i, centery = 1080 >> 1; 67 | float rad; 68 | 69 | /* create sin lookup table */ 70 | for (i = 0; i < 360; i++) 71 | { 72 | rad = (float)i * 0.0174532; 73 | aSin[i] = centery + (sinf(rad) * 100.0); 74 | } 75 | 76 | /* precompute colors */ 77 | compose_fadebar(&color[0], 1); /* red copper bar */ 78 | compose_fadebar(&color[0], 16); /* white copper bar */ 79 | compose_fadebar(&color[0], 31); /* blue copper bar */ 80 | } 81 | 82 | static void draw_copper(uint16_t * const y, int add, SDL_Renderer *renderer) 83 | { 84 | 85 | for(int i = 0; i < 15; i++) // bar height, 15px 86 | { 87 | /* use precomputed colors */ 88 | SDL_SetRenderDrawColor(renderer, (color[i + add] & 0x00FF0000) >> 16, (color[i + add] & 0x0000FF00) >> 8, (color[i + add] & 0x000000FF), 255); 89 | SDL_Rect r = {0, *y, 1920, 1}; 90 | SDL_RenderFillRect(renderer, &r); 91 | 92 | *y += 1; 93 | } 94 | } 95 | 96 | void draw_copperbars(SDL_Renderer* render) 97 | { 98 | /* draw copperbars back to front */ 99 | uint16_t y; 100 | 101 | y = aSin[blue7]; blue8 = y; blue7 += 2; blue7 %= 360; 102 | draw_copper(&y, 31, render); 103 | 104 | y = aSin[blue5]; blue6 = y; blue5 += 2; blue5 %= 360; 105 | draw_copper(&y, 31, render); 106 | 107 | y = aSin[blue3]; blue4 = y; blue3 += 2; blue3 %= 360; 108 | draw_copper(&y, 31, render); 109 | 110 | y = aSin[blue]; blue2 = y; blue += 2; blue %= 360; 111 | draw_copper(&y, 31, render); 112 | 113 | y = aSin[white7]; white8 = y; white7 += 2; white7 %= 360; 114 | draw_copper(&y, 16, render); 115 | 116 | y = aSin[white5]; white6 = y; white5 += 2; white5 %= 360; 117 | draw_copper(&y, 16, render); 118 | 119 | y = aSin[white3]; white4 = y; white3 += 2; white3 %= 360; 120 | draw_copper(&y, 16, render); 121 | 122 | y = aSin[white]; white2 = y; white += 2; white %= 360; 123 | draw_copper(&y, 16, render); 124 | 125 | y = aSin[red7]; red8 = y; red7 += 2; red7 %= 360; 126 | draw_copper(&y, 1, render); 127 | 128 | y = aSin[red5]; red6 = y; red5 += 2; red5 %= 360; 129 | draw_copper(&y, 1, render); 130 | 131 | y = aSin[red3]; red4 = y; red3 += 2; red3 %= 360; 132 | draw_copper(&y, 1, render); 133 | 134 | y = aSin[red]; red2 = y; red += 2; red %= 360; 135 | draw_copper(&y, 1, render); 136 | } 137 | -------------------------------------------------------------------------------- /ps4load/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | // PS4Load host - based on the PS3Load tool (PSL1GHT) 3 | // 4 | // compatible with the original ps3load client: 5 | // # export PS3LOAD=tcp:192.168.x.x 6 | // # ps3load /path/to/eboot.bin 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include "ttf.h" 25 | 26 | #define MIN(a, b) ((a) < (b) ? (a) : (b)) 27 | #define SELF_PATH "/data/ps4load.tmp" 28 | #define VERSION "v0.5.1" 29 | #define PORT 4299 30 | #define MAX_ARG_COUNT 0x100 31 | #define FRAME_WIDTH 1920 32 | #define FRAME_HEIGHT 1080 33 | #define CHUNK 0x4000 34 | #define PKZIP 0x04034B50 35 | 36 | #define ERROR(a, msg) { \ 37 | if (a < 0) { \ 38 | snprintf(msg_error, sizeof(msg_error), "PS4Load: " msg ); \ 39 | usleep(250); \ 40 | if(my_socket >= 0) { close(my_socket);my_socket = -1;} \ 41 | } \ 42 | } 43 | #define ERROR2(a, msg) { \ 44 | if (a < 0) { \ 45 | snprintf(msg_error, sizeof(msg_error), "PS4Load: %s", msg ); \ 46 | usleep(1000000); \ 47 | msg_error[0] = 0; \ 48 | usleep(60); \ 49 | goto reloop; \ 50 | } \ 51 | } 52 | #define continueloop() { close(c); goto reloop; } 53 | 54 | // Font faces 55 | FT_Face fontFace; 56 | 57 | char msg_error[128]; 58 | char msg_two [128]; 59 | 60 | volatile int my_socket=-1; 61 | volatile int flag_exit=0; 62 | 63 | void init_copperbars(void); 64 | void draw_copperbars(SDL_Renderer* render); 65 | 66 | void init_sinetext(SDL_Renderer* render, const char* path); 67 | void draw_sinetext(SDL_Renderer* render, int y); 68 | 69 | 70 | /* Decompress from source data to file dest until stream ends or EOF. 71 | inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be 72 | allocated for processing, Z_DATA_ERROR if the deflate data is 73 | invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and 74 | the version of the library linked do not match, or Z_ERRNO if there 75 | is an error reading or writing the files. */ 76 | int inflate_data(int source, uint32_t filesize, FILE *dest) 77 | { 78 | int ret; 79 | uint32_t have; 80 | z_stream strm; 81 | uint8_t src[CHUNK]; 82 | uint8_t out[CHUNK]; 83 | 84 | /* allocate inflate state */ 85 | memset(&strm, 0, sizeof(z_stream)); 86 | ret = inflateInit(&strm); 87 | if (ret != Z_OK) 88 | return ret; 89 | 90 | /* decompress until deflate stream ends or end of file */ 91 | do { 92 | strm.avail_in = MIN(CHUNK, filesize); 93 | ret = read(source, src, strm.avail_in); 94 | if (ret < 0) { 95 | (void)inflateEnd(&strm); 96 | return Z_ERRNO; 97 | } 98 | 99 | strm.avail_in = ret; 100 | if (strm.avail_in == 0) 101 | break; 102 | strm.next_in = src; 103 | filesize -= ret; 104 | 105 | /* run inflate() on input until output buffer not full */ 106 | do { 107 | strm.avail_out = CHUNK; 108 | strm.next_out = out; 109 | ret = inflate(&strm, Z_NO_FLUSH); 110 | switch (ret) { 111 | case Z_STREAM_ERROR: 112 | case Z_NEED_DICT: 113 | ret = Z_DATA_ERROR; /* and fall through */ 114 | case Z_DATA_ERROR: 115 | case Z_MEM_ERROR: 116 | (void)inflateEnd(&strm); 117 | return ret; 118 | } 119 | have = CHUNK - strm.avail_out; 120 | if (fwrite(out, 1, have, dest) != have || ferror(dest)) { 121 | (void)inflateEnd(&strm); 122 | return Z_ERRNO; 123 | } 124 | } while (strm.avail_out == 0); 125 | 126 | /* done when inflate() says it's done */ 127 | } while (ret != Z_STREAM_END && filesize); 128 | 129 | /* clean up and return */ 130 | (void)inflateEnd(&strm); 131 | return (ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR); 132 | } 133 | 134 | int dump_data(int source, uint32_t filesize, FILE *dest) 135 | { 136 | uint8_t data[CHUNK]; 137 | uint32_t count, pkz = PKZIP; 138 | 139 | while (filesize > 0) 140 | { 141 | count = MIN(CHUNK, filesize); 142 | int ret = read(source, data, count); 143 | if (ret < 0) 144 | return Z_DATA_ERROR; 145 | 146 | if (pkz == PKZIP) 147 | pkz = memcmp(data, &pkz, 4); 148 | 149 | fwrite(data, ret, 1, dest); 150 | filesize -= ret; 151 | } 152 | 153 | return (pkz ? Z_OK : PKZIP); 154 | } 155 | 156 | void launch_self(const char* path, const char** args) 157 | { 158 | dbglogger_log(msg_two); 159 | dbglogger_stop(); 160 | sleep(1); 161 | 162 | sceSystemServiceLoadExec(path, args); 163 | sceKernelUsleep(2 * 1000000); 164 | } 165 | 166 | int netThread(void* data) 167 | { 168 | if (access("/data/ps4load/eboot.bin", F_OK) == Z_OK) 169 | { 170 | snprintf(msg_two, sizeof(msg_two), "Loading eboot.bin..."); 171 | launch_self("/data/ps4load/eboot.bin", NULL); 172 | } 173 | 174 | OrbisNetCtlInfo ip_info; 175 | memset(&ip_info, 0, sizeof(ip_info)); 176 | sceNetCtlGetInfo(ORBIS_NET_CTL_INFO_IP_ADDRESS, &ip_info); 177 | 178 | snprintf(msg_two, sizeof(msg_two), "Creating socket..."); 179 | dbglogger_log(msg_two); 180 | 181 | my_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); 182 | ERROR(my_socket, "Error creating socket()"); 183 | 184 | struct sockaddr_in server; 185 | memset(&server, 0, sizeof(server)); 186 | server.sin_family = AF_INET; 187 | server.sin_addr.s_addr = htonl(INADDR_ANY); 188 | server.sin_port = htons(PORT); 189 | 190 | if(my_socket!=-1) { 191 | snprintf(msg_two, sizeof(msg_two), "Binding socket..."); 192 | dbglogger_log(msg_two); 193 | 194 | ERROR(bind(my_socket, (struct sockaddr*)&server, sizeof(server)), "Error bind()ing socket"); 195 | } 196 | 197 | if(my_socket!=-1) 198 | ERROR(listen(my_socket, 10), "Error calling listen()"); 199 | 200 | reloop: 201 | msg_two[0] = 0; 202 | 203 | while (1) { 204 | 205 | usleep(20000); 206 | 207 | if(flag_exit) break; 208 | if(my_socket == -1) continue; 209 | 210 | //fgColor.r = fgColor.g = fgColor.b = 0xff; 211 | snprintf(msg_two, sizeof(msg_two), "%s:%d ready for client...", ip_info.ip_address, PORT); 212 | dbglogger_log(msg_two); 213 | 214 | int c = accept(my_socket, NULL, NULL); 215 | 216 | if(flag_exit) break; 217 | if(my_socket == -1) continue; 218 | 219 | ERROR(c, "Error calling accept()"); 220 | 221 | uint32_t magic = 0; 222 | if (read(c, &magic, sizeof(magic)) < 0) 223 | continueloop(); 224 | if (strncmp((char*)&magic, "HAXX", 4)) { 225 | snprintf(msg_two, sizeof(msg_two), "Wrong HAXX magic."); 226 | dbglogger_log(msg_two); 227 | continueloop(); 228 | } 229 | if (read(c, &magic, sizeof(magic)) < 0) 230 | continueloop(); 231 | uint16_t argslen = __bswap32(magic) & 0x0000FFFF; 232 | 233 | uint32_t filesize = 0; 234 | if (read(c, &filesize, sizeof(filesize)) < 0) 235 | continueloop(); 236 | 237 | uint32_t uncompressed = 0; 238 | if (read(c, &uncompressed, sizeof(uncompressed)) < 0) 239 | continueloop(); 240 | 241 | filesize = __bswap32(filesize); 242 | uncompressed = __bswap32(uncompressed); 243 | 244 | remove(SELF_PATH); 245 | FILE *fd = fopen(SELF_PATH, "wb"); 246 | if (!fd) { 247 | close(c); 248 | ERROR2(-1, "Error opening temporary file."); 249 | } 250 | 251 | //fgColor.g = 255; 252 | snprintf(msg_two, sizeof(msg_two), "Receiving data... (0x%08x/0x%08x)", filesize, uncompressed); 253 | dbglogger_log(msg_two); 254 | 255 | int ret = uncompressed ? inflate_data(c, filesize, fd) : dump_data(c, filesize, fd); 256 | fclose(fd); 257 | 258 | if (ret != Z_OK && ret != PKZIP) 259 | continueloop(); 260 | 261 | snprintf(msg_two, sizeof(msg_two), "Receiving arguments... 0x%08x", argslen); 262 | dbglogger_log(msg_two); 263 | 264 | uint8_t* args = NULL; 265 | if (argslen) { 266 | args = (uint8_t*)malloc(argslen); 267 | if (read(c, args, argslen) < 0) 268 | continueloop(); 269 | } 270 | close(c); 271 | 272 | if (!uncompressed && ret == PKZIP) 273 | { 274 | snprintf(msg_two, sizeof(msg_two), "Extracting ZIP to /data/ ..."); 275 | dbglogger_log(msg_two); 276 | 277 | ERROR2(zip_extract(SELF_PATH, "/data/", NULL, NULL), "Error extracting ZIP file."); 278 | goto reloop; 279 | } 280 | 281 | ERROR2(chmod(SELF_PATH, 0777), "Failed to chmod() temporary file."); 282 | 283 | char* launchargv[MAX_ARG_COUNT]; 284 | memset(launchargv, 0, sizeof(launchargv)); 285 | 286 | int i = 0, pos = 0; 287 | while (pos < argslen) { 288 | int len = strlen((char*)args + pos); 289 | if (!len) 290 | break; 291 | launchargv[i] = (char*)malloc(len + 1); 292 | strcpy(launchargv[i], (char*)args + pos); 293 | pos += len + 1; 294 | i++; 295 | } 296 | 297 | snprintf(msg_two, sizeof(msg_two), "Launching..."); 298 | launch_self(SELF_PATH, (const char**)launchargv); 299 | } 300 | 301 | return 0; 302 | } 303 | 304 | int main(int argc, char *argv[]) 305 | { 306 | SDL_Event event; 307 | SDL_Window *window; 308 | SDL_Renderer *renderer; 309 | int done = 0; 310 | 311 | dbglogger_init(); 312 | 313 | if (sceSysmoduleLoadModuleInternal(ORBIS_SYSMODULE_INTERNAL_NETCTL) < 0 || sceNetCtlInit() < 0) { 314 | dbglogger_log("NetCtl init failed"); 315 | return -1; 316 | } 317 | 318 | // mandatory at least on switch, else gfx is not properly closed 319 | if (SDL_Init(SDL_INIT_VIDEO) < 0) { 320 | dbglogger_log("SDL_Init: %s", SDL_GetError()); 321 | return -1; 322 | } 323 | 324 | /// create a window (OpenGL always enabled) 325 | /// available switch SDL2 video modes : 326 | /// 1920 x 1080 @ 32 bpp (SDL_PIXELFORMAT_RGBA8888) 327 | /// 1280 x 720 @ 32 bpp (SDL_PIXELFORMAT_RGBA8888) 328 | window = SDL_CreateWindow("sdl2_gles2", 0, 0, FRAME_WIDTH, FRAME_HEIGHT, 0); 329 | if (!window) { 330 | dbglogger_log("SDL_CreateWindow: %s", SDL_GetError()); 331 | SDL_Quit(); 332 | return -1; 333 | } 334 | 335 | // create a renderer (OpenGL ES2) 336 | renderer = SDL_CreateRenderer(window, 0, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); 337 | if (!renderer) { 338 | dbglogger_log("SDL_CreateRenderer: %s", SDL_GetError()); 339 | SDL_Quit(); 340 | return -1; 341 | } 342 | 343 | // We have to force load the freetype module or we'll get unresolved NID crashes 344 | dbglogger_log("Initializing TTF"); 345 | 346 | done = sceSysmoduleLoadModule(ORBIS_SYSMODULE_FREETYPE_OL); 347 | if (done < 0) { 348 | dbglogger_log("Failed to load freetype module: %X", done); 349 | return (-1); 350 | } 351 | 352 | // Finally initialize freetype 353 | done = FT_Init_FreeType(&ftLib); 354 | if (done < 0) { 355 | dbglogger_log("Failed to init freetype lib: %X", done); 356 | return (-1); 357 | } 358 | 359 | dbglogger_log("Initializing font"); 360 | 361 | // Create a font face for debug and score text 362 | if (!InitFont(&fontFace, "/app0/assets/fonts/Gontserrat-Regular.ttf", 40)) { 363 | dbglogger_log("Failed to initialize font"); 364 | return (-1); 365 | } 366 | 367 | SDL_CreateThread(&netThread, "net", &done); 368 | init_copperbars(); 369 | init_sinetext(renderer, "/app0/assets/images/psl1ght.tga"); 370 | 371 | Color fgColor = {0xFF, 0xFF, 0xFF}; 372 | 373 | while (!done) 374 | { 375 | SDL_SetRenderDrawColor(renderer, 60, 60, 60, SDL_ALPHA_OPAQUE); 376 | SDL_RenderClear(renderer); 377 | 378 | draw_copperbars(renderer); 379 | draw_sinetext(renderer, 520); 380 | 381 | DrawString(renderer, "PS4Load " VERSION " by Bucanero", fontFace, fgColor, 0, 100); 382 | DrawString(renderer, msg_two, fontFace, fgColor, 0, 800); 383 | 384 | if (msg_error[0]) { 385 | Color errorColor = {0xFF, 0, 0}; 386 | DrawString(renderer, msg_error, fontFace, errorColor, 0, 300); 387 | } 388 | 389 | SDL_RenderPresent(renderer); 390 | } 391 | 392 | SDL_DestroyRenderer(renderer); 393 | SDL_DestroyWindow(window); 394 | SDL_Quit(); 395 | dbglogger_stop(); 396 | 397 | sceSystemServiceLoadExec("exit", NULL); 398 | return 0; 399 | } 400 | -------------------------------------------------------------------------------- /ps4load/scroller.c: -------------------------------------------------------------------------------- 1 | /* 2 | testing sinf() from math.h 3 | masterzorag@gmail.com, 2015-2018 4 | */ 5 | 6 | #include // sinf() 7 | #include // strlen() 8 | #include 9 | #include 10 | 11 | #define FONT_W 32 12 | #define FONT_H 40 13 | #define STEP_X -2 // horizontal displacement 14 | #define SWIDTH 1920 15 | #define STRING "PSL1GHT" 16 | 17 | static int sx = SWIDTH, 18 | sl = 0; 19 | 20 | static SDL_Texture* scrollText; 21 | 22 | /*********************************************************************** 23 | * Compute string len once, then reuse value 24 | ***********************************************************************/ 25 | void init_sinetext(SDL_Renderer* renderer, const char* filepath) 26 | { 27 | sl = strlen(STRING) * FONT_W; 28 | 29 | SDL_Surface* tempSurface = IMG_Load(filepath); 30 | SDL_SetColorKey(tempSurface, SDL_TRUE, SDL_MapRGB(tempSurface->format, 0, 0, 0)); 31 | 32 | scrollText = SDL_CreateTextureFromSurface(renderer, tempSurface); 33 | SDL_SetTextureBlendMode(scrollText, SDL_BLENDMODE_BLEND); 34 | 35 | // We no longer need the surface, we only need it for texture creation 36 | SDL_FreeSurface(tempSurface); 37 | } 38 | 39 | /*********************************************************************** 40 | * Move string by defined step 41 | ***********************************************************************/ 42 | static void move_sinetext(void) 43 | { 44 | sx += STEP_X; 45 | 46 | if(sx < -sl) // horizontal bound, then loop 47 | sx = SWIDTH + FONT_W; 48 | } 49 | 50 | /*********************************************************************** 51 | * Draw a string of chars, amplifing y by sin(x) 52 | ***********************************************************************/ 53 | void draw_sinetext(SDL_Renderer* renderer, int y) 54 | { 55 | int x = sx; // every call resets the initial x 56 | float amp; 57 | 58 | for(int i = 0; i < (sl / FONT_W); i++) 59 | { 60 | amp = sinf(x // testing sinf() from math.h 61 | * 0.02) // it turns out in num of bends 62 | * 20; // +/- vertical bounds over y 63 | 64 | if(x > 0 && x < SWIDTH - FONT_W) 65 | { 66 | SDL_Rect src = { 67 | .x = FONT_W * i, 68 | .y = 0, 69 | .w = FONT_W, 70 | .h = FONT_H, 71 | }; 72 | SDL_Rect pos = { 73 | .x = x, 74 | .y = y + amp, 75 | .w = FONT_W, 76 | .h = FONT_H, 77 | }; 78 | 79 | SDL_RenderCopy(renderer, scrollText, &src, &pos); 80 | } 81 | 82 | x += FONT_W; 83 | } 84 | 85 | move_sinetext(); 86 | } 87 | -------------------------------------------------------------------------------- /ps4load/ttf.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "ttf.h" 5 | 6 | FT_Library ftLib; 7 | 8 | bool InitFont(FT_Face* face, const char* fontPath, int fontSize) 9 | { 10 | int rc; 11 | 12 | rc = FT_New_Face(ftLib, fontPath, 0, face); 13 | 14 | if (rc < 0) 15 | return false; 16 | 17 | rc = FT_Set_Pixel_Sizes(*face, 0, fontSize); 18 | 19 | if (rc < 0) 20 | return false; 21 | 22 | return true; 23 | } 24 | 25 | static int SetText(SDL_Surface* surface, const char* txt, FT_Face face, Color fgColor, Color bgColor) 26 | { 27 | int rc; 28 | int xOffset = 0; 29 | int yOffset = 0; 30 | int totalWidth = 0; 31 | uint32_t* pixels = (uint32_t*)surface->pixels; 32 | 33 | // Get the glyph slot for bitmap and font metrics 34 | FT_GlyphSlot slot = face->glyph; 35 | 36 | // Iterate each character of the text to write to the screen 37 | for (int n = 0; n < strlen(txt); n++) 38 | { 39 | FT_UInt glyph_index; 40 | 41 | // Get the glyph for the ASCII code 42 | glyph_index = FT_Get_Char_Index(face, txt[n]); 43 | 44 | // Load and render in 8-bit color 45 | rc = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT); 46 | 47 | if (rc) 48 | continue; 49 | 50 | rc = FT_Render_Glyph(slot, ft_render_mode_normal); 51 | 52 | if (rc) 53 | continue; 54 | 55 | // Parse and write the bitmap to the frame buffer 56 | for (int yPos = 0; yPos < slot->bitmap.rows; yPos++) 57 | { 58 | for (int xPos = 0; xPos < slot->bitmap.width; xPos++) 59 | { 60 | // Decode the 8-bit bitmap 61 | char pixel = slot->bitmap.buffer[(yPos * slot->bitmap.width) + xPos]; 62 | 63 | // Get new pixel coordinates to account for the character position and baseline, as well as newlines 64 | int x = xPos + xOffset + (slot->metrics.horiBearingX / 64); 65 | int y = face->size->metrics.y_ppem + yPos + yOffset - slot->bitmap_top; 66 | 67 | uint8_t r = (bgColor.r * (255 - 255) + pixel * fgColor.r * 255 / 255) / 255; 68 | uint8_t g = (bgColor.g * (255 - 255) + pixel * fgColor.g * 255 / 255) / 255; 69 | uint8_t b = (bgColor.b * (255 - 255) + pixel * fgColor.b * 255 / 255) / 255; 70 | 71 | // Create new color struct with lerp'd values 72 | Color finalColor = { r, g, b }; 73 | 74 | // We need to do bounds checking before commiting the pixel write due to our transformations, or we 75 | // could write out-of-bounds of the texture's pixel array 76 | if (x < 0 || y < 0 || x >= surface->w || y >= surface->h) 77 | continue; 78 | 79 | if (x > totalWidth) totalWidth = x; 80 | 81 | if (pixel != 0x00) 82 | { 83 | // Get pixel location based on pitch 84 | int pixelIdx = (y * surface->w) + x; 85 | 86 | // Encode to 24-bit color 87 | uint32_t encodedColor = (pixel << 24) + (finalColor.r << 16) + (finalColor.g << 8) + finalColor.b; 88 | 89 | // Draw to the pixel buffer 90 | pixels[pixelIdx] = encodedColor; 91 | } 92 | 93 | // totalWidth += slot->bitmap.width; 94 | } 95 | } 96 | 97 | // Increment x offset for the next character 98 | xOffset += slot->advance.x >> 6; 99 | } 100 | 101 | return totalWidth; 102 | } 103 | 104 | static SDL_Texture* CreateText(SDL_Renderer *renderer, const char* txt, FT_Face fontFace, Color fgColor, Color bgColor, int *outWidth) 105 | { 106 | SDL_Surface* tempSurface; 107 | SDL_Texture* finalTexture; 108 | 109 | // Pre-calculate the surface size by counting the number of characters and multiplying by the horizontal pem for width, 110 | // and by using the vertical pem * 2 for the height. 111 | int w = strlen(txt) * fontFace->size->metrics.x_ppem; 112 | int h = fontFace->size->metrics.y_ppem * 2; 113 | 114 | tempSurface = SDL_CreateRGBSurface(0, w, h, 32, 0, 0, 0, 0); 115 | 116 | // Write the text pixels to the surface 117 | *outWidth = SetText(tempSurface, txt, fontFace, fgColor, bgColor); 118 | 119 | // We need to set a transparency key. However, we want to support the ability to use any arbitrary 120 | // background color *without* it getting keyed out. So we'll check the background color for extremes 121 | // (white and black), and we'll use the opposite of what is specified. 122 | Uint32 colorKey; 123 | 124 | if (bgColor.r == 0 && bgColor.g == 0 && bgColor.b == 0) 125 | colorKey = SDL_MapRGB(tempSurface->format, 255, 255, 255); 126 | else 127 | colorKey = SDL_MapRGB(tempSurface->format, 0, 0, 0); 128 | 129 | SDL_SetColorKey(tempSurface, SDL_TRUE, colorKey); 130 | 131 | // Derive the texture and make it blendable 132 | finalTexture = SDL_CreateTextureFromSurface(renderer, tempSurface); 133 | SDL_SetTextureBlendMode(finalTexture, SDL_BLENDMODE_BLEND); 134 | 135 | // We no longer need the surface, we only need it for texture creation 136 | SDL_FreeSurface(tempSurface); 137 | 138 | return finalTexture; 139 | } 140 | 141 | void DrawString(SDL_Renderer *renderer, const char* msg, FT_Face font, Color color, int x, int y) 142 | { 143 | SDL_Rect pos; 144 | Color bgColor = {0x60, 0x60, 0x60}; 145 | 146 | if (!msg[0]) 147 | return; 148 | 149 | SDL_Texture *tmpText = CreateText(renderer, msg, font, color, bgColor, &pos.x); 150 | SDL_QueryTexture(tmpText, NULL, NULL, &pos.w, &pos.h); 151 | 152 | // Center it 153 | pos.x = x ? x : ((1920 - pos.x) / 2); 154 | pos.y = y ? y : ((1080 - pos.h) / 2); 155 | 156 | SDL_RenderCopy(renderer, tmpText, NULL, &pos); 157 | SDL_DestroyTexture(tmpText); 158 | 159 | return; 160 | } 161 | -------------------------------------------------------------------------------- /ps4load/ttf.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | extern FT_Library ftLib; 7 | 8 | typedef struct Color_rgb 9 | { 10 | uint8_t r; 11 | uint8_t g; 12 | uint8_t b; 13 | } Color; 14 | 15 | bool InitFont(FT_Face* face, const char* fontPath, int fontSize); 16 | void DrawString(SDL_Renderer *renderer, const char* msg, FT_Face font, Color color, int x, int y); 17 | -------------------------------------------------------------------------------- /sce_module/libSceFios2.prx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bucanero/ps4load/290d979d9ce144c7985659029a030ea540375cc0/sce_module/libSceFios2.prx -------------------------------------------------------------------------------- /sce_module/libc.prx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bucanero/ps4load/290d979d9ce144c7985659029a030ea540375cc0/sce_module/libc.prx -------------------------------------------------------------------------------- /sce_sys/about/right.sprx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bucanero/ps4load/290d979d9ce144c7985659029a030ea540375cc0/sce_sys/about/right.sprx -------------------------------------------------------------------------------- /sce_sys/icon0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bucanero/ps4load/290d979d9ce144c7985659029a030ea540375cc0/sce_sys/icon0.png --------------------------------------------------------------------------------