├── LICENSE ├── README.md ├── libpsp2link ├── Makefile ├── include │ ├── psp2link.h │ └── psp2link_internal.h └── source │ ├── commands.c │ ├── emulink.c │ ├── psp2link.c │ └── requests.c └── sample ├── Makefile ├── file_chooser.c ├── file_chooser.h ├── font.c ├── font.h ├── font_data.c ├── logo.h └── main.c /LICENSE: -------------------------------------------------------------------------------- 1 | COPYRIGHT FOR PSP2LINK 2 | ---------------------------------------------------------------------------- 3 | 4 | Copyright (c) 2003 Tord Lindstrom (pukko@home.se) 5 | (c) 2003 adresd (adresd_ps2dev@yahoo.com) 6 | (c) 2004 Khaled Daham 7 | (c) 2004 Nicolas 'Pixel' Noble 8 | (c) 2003,2015 Antonio Jose Ramos Marquez aka bigboss @psxdev on twitter 9 | 10 | The Academic Free License 11 | v. 2.0 12 | 13 | This Academic Free License (the "License") applies to any original work 14 | of authorship (the "Original Work") whose owner (the "Licensor") has 15 | placed the following notice immediately following the copyright notice 16 | for the Original Work: 17 | 18 | *Licensed under the Academic Free License version 2.0* 19 | 20 | 1) *Grant of Copyright License.* Licensor hereby grants You a 21 | world-wide, royalty-free, non-exclusive, perpetual, sublicenseable 22 | license to do the following: 23 | 24 | a) to reproduce the Original Work in copies; 25 | 26 | b) to prepare derivative works ("Derivative Works") based upon the 27 | Original Work; 28 | 29 | c) to distribute copies of the Original Work and Derivative Works to 30 | the public; 31 | 32 | d) to perform the Original Work publicly; and 33 | 34 | e) to display the Original Work publicly. 35 | 36 | 2) *Grant of Patent License.* Licensor hereby grants You a world-wide, 37 | royalty-free, non-exclusive, perpetual, sublicenseable license, under 38 | patent claims owned or controlled by the Licensor that are embodied in 39 | the Original Work as furnished by the Licensor, to make, use, sell and 40 | offer for sale the Original Work and Derivative Works. 41 | 42 | 3) *Grant of Source Code License.* The term "Source Code" means the 43 | preferred form of the Original Work for making modifications to it and 44 | all available documentation describing how to modify the Original Work. 45 | Licensor hereby agrees to provide a machine-readable copy of the Source 46 | Code of the Original Work along with each copy of the Original Work that 47 | Licensor distributes. Licensor reserves the right to satisfy this 48 | obligation by placing a machine-readable copy of the Source Code in an 49 | information repository reasonably calculated to permit inexpensive and 50 | convenient access by You for as long as Licensor continues to distribute 51 | the Original Work, and by publishing the address of that information 52 | repository in a notice immediately following the copyright notice that 53 | applies to the Original Work. 54 | 55 | 4) *Exclusions From License Grant. *Neither the names of Licensor, nor 56 | the names of any contributors to the Original Work, nor any of their 57 | trademarks or service marks, may be used to endorse or promote products 58 | derived from this Original Work without express prior written permission 59 | of the Licensor. Nothing in this License shall be deemed to grant any 60 | rights to trademarks, copyrights, patents, trade secrets or any other 61 | intellectual property of Licensor except as expressly stated herein. No 62 | patent license is granted to make, use, sell or offer to sell 63 | embodiments of any patent claims other than the licensed claims defined 64 | in Section 2. No right is granted to the trademarks of Licensor even if 65 | such marks are included in the Original Work. Nothing in this License 66 | shall be interpreted to prohibit Licensor from licensing under different 67 | terms from this License any Original Work that Licensor otherwise would 68 | have a right to license. 69 | 70 | 5) This section intentionally omitted. 71 | 72 | 6) *Attribution Rights.* You must retain, in the Source Code of any 73 | Derivative Works that You create, all copyright, patent or trademark 74 | notices from the Source Code of the Original Work, as well as any 75 | notices of licensing and any descriptive text identified therein as an 76 | "Attribution Notice." You must cause the Source Code for any Derivative 77 | Works that You create to carry a prominent Attribution Notice reasonably 78 | calculated to inform recipients that You have modified the Original Work. 79 | 80 | 7) *Warranty of Provenance and Disclaimer of Warranty.* Licensor 81 | warrants that the copyright in and to the Original Work and the patent 82 | rights granted herein by Licensor are owned by the Licensor or are 83 | sublicensed to You under the terms of this License with the permission 84 | of the contributor(s) of those copyrights and patent rights. Except as 85 | expressly stated in the immediately proceeding sentence, the Original 86 | Work is provided under this License on an "AS IS" BASIS and WITHOUT 87 | WARRANTY, either express or implied, including, without limitation, the 88 | warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A 89 | PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL 90 | WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential 91 | part of this License. No license to Original Work is granted hereunder 92 | except under this disclaimer. 93 | 94 | 8) *Limitation of Liability.* Under no circumstances and under no legal 95 | theory, whether in tort (including negligence), contract, or otherwise, 96 | shall the Licensor be liable to any person for any direct, indirect, 97 | special, incidental, or consequential damages of any character arising 98 | as a result of this License or the use of the Original Work including, 99 | without limitation, damages for loss of goodwill, work stoppage, 100 | computer failure or malfunction, or any and all other commercial damages 101 | or losses. This limitation of liability shall not apply to liability for 102 | death or personal injury resulting from Licensor's negligence to the 103 | extent applicable law prohibits such limitation. Some jurisdictions do 104 | not allow the exclusion or limitation of incidental or consequential 105 | damages, so this exclusion and limitation may not apply to You. 106 | 107 | 9) *Acceptance and Termination.* If You distribute copies of the 108 | Original Work or a Derivative Work, You must make a reasonable effort 109 | under the circumstances to obtain the express assent of recipients to 110 | the terms of this License. Nothing else but this License (or another 111 | written agreement between Licensor and You) grants You permission to 112 | create Derivative Works based upon the Original Work or to exercise any 113 | of the rights granted in Section 1 herein, and any attempt to do so 114 | except under the terms of this License (or another written agreement 115 | between Licensor and You) is expressly prohibited by U.S. copyright law, 116 | the equivalent laws of other countries, and by international treaty. 117 | Therefore, by exercising any of the rights granted to You in Section 1 118 | herein, You indicate Your acceptance of this License and all of its 119 | terms and conditions. 120 | 121 | 10) *Termination for Patent Action.* This License shall terminate 122 | automatically and You may no longer exercise any of the rights granted 123 | to You by this License as of the date You commence an action, including 124 | a cross-claim or counterclaim, for patent infringement (i) against 125 | Licensor with respect to a patent applicable to software or (ii) against 126 | any entity with respect to a patent applicable to the Original Work (but 127 | excluding combinations of the Original Work with other software or 128 | hardware). 129 | 130 | 11) *Jurisdiction, Venue and Governing Law.* Any action or suit relating 131 | to this License may be brought only in the courts of a jurisdiction 132 | wherein the Licensor resides or in which Licensor conducts its primary 133 | business, and under the laws of that jurisdiction excluding its 134 | conflict-of-law provisions. The application of the United Nations 135 | Convention on Contracts for the International Sale of Goods is expressly 136 | excluded. Any use of the Original Work outside the scope of this License 137 | or after its termination shall be subject to the requirements and 138 | penalties of the U.S. Copyright Act, 17 U.S.C. § 101 et seq., the 139 | equivalent laws of other countries, and international treaty. This 140 | section shall survive the termination of this License. 141 | 142 | 12) *Attorneys Fees.* In any action to enforce the terms of this License 143 | or seeking damages relating thereto, the prevailing party shall be 144 | entitled to recover its costs and expenses, including, without 145 | limitation, reasonable attorneys' fees and costs incurred in connection 146 | with such action, including any appeal of such action. This section 147 | shall survive the termination of this License. 148 | 149 | 13) *Miscellaneous.* This License represents the complete agreement 150 | concerning the subject matter hereof. If any provision of this License 151 | is held to be unenforceable, such provision shall be reformed only to 152 | the extent necessary to make it enforceable. 153 | 154 | 14) *Definition of "You" in This License.* "You" throughout this 155 | License, whether in upper or lower case, means an individual or a legal 156 | entity exercising rights under, and complying with all of the terms of, 157 | this License. For legal entities, "You" includes any entity that 158 | controls, is controlled by, or is under common control with you. For 159 | purposes of this definition, "control" means (i) the power, direct or 160 | indirect, to cause the direction or management of such entity, whether 161 | by contract or otherwise, or (ii) ownership of fifty percent (50%) or 162 | more of the outstanding shares, or (iii) beneficial ownership of such 163 | entity. 164 | 165 | 15) *Right to Use.* You may use the Original Work in all ways not 166 | otherwise restricted or conditioned by this License or by law, and 167 | Licensor promises not to interfere with or be responsible for such uses 168 | by You. 169 | 170 | This license is Copyright (C) 2003 Lawrence E. Rosen. All rights 171 | reserved. Permission is hereby granted to copy and distribute this 172 | license without modification. This license may not be modified without 173 | the express written permission of its copyright owner. 174 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | PSP2LINK FOR VITA 2 | ================= 3 | 4 | =================== 5 | What does this do? 6 | =================== 7 | 8 | psp2link is a library for vita to communicate and use host file system with psp2client host tool. It is the same method that we used in ps2dev days, so basically it is the same protocol than ps2link and ps2client have been using since 2003. 9 | 10 | Functions availables are defined like native sceIoxx functions so it is easy for homebrew developer to use these new functions: 11 | ``` 12 | int psp2LinkIoOpen(const char *file, int flags, SceMode mode); 13 | int psp2LinkIoClose(SceUID fd); 14 | int psp2LinkIoRead(SceUID fd, void *data, SceSize size); 15 | int psp2LinkIoWrite(SceUID fd, const void *data, SceSize size); 16 | int psp2LinkIoLseek(SceUID fd, int offset, int whence); 17 | int psp2LinkIoRemove(const char *file); 18 | int psp2LinkIoMkdir(const char *dirname, SceMode mode); 19 | int psp2LinkIoRmdir(const char *dirname); 20 | int psp2LinkIoDopen(const char *dirname); 21 | int psp2LinkIoDread(SceUID fd, SceIoDirent *dir); 22 | int psp2LinkIoDclose(SceUID fd); 23 | ``` 24 | 25 | 26 | ================== 27 | How do I use it? 28 | ================== 29 | 30 | 1) Compile and install library and include file 31 | 32 | You need the last vita toolchain installed in your environment ,libdebugnet and libvita2d installed and VITASDK must be defined. 33 | 34 | 35 | ``` 36 | cd libpsp2link 37 | make 38 | make install 39 | ``` 40 | 41 | 2) Compile sample 42 | 43 | ``` 44 | cd sample 45 | edit main.c and change your mac/linux server ip and your base directory for example host0:/usr/local 46 | make 47 | ``` 48 | 49 | 3) Run sample with rejuvenete on vita and when you see psp2link splash screen you are ready to run psp2client in your mac/linux 50 | 51 | ``` 52 | psp2client -h ipofyourvita listen 53 | ``` 54 | 55 | Command protocol is implemented and you can extend it with your custom code. Examples can be run with: 56 | 57 | ``` 58 | psp2client -h ipofyourvita -t 5 execelf host0:filename 59 | ``` 60 | 61 | ``` 62 | psp2client -h ipofyourvita -t 5 execsprx host0:filename 63 | ``` 64 | 65 | ``` 66 | psp2client -h ipofyourvita -t 5 exit 67 | ``` 68 | 69 | You will see logs in terminal window output from your PlayStation Vita using libdebugnet udp log feauture and you can browse over folder in your hard disk. 70 | 71 | Sample is showing only browser example you have full io r/w access to your hard disk and you can test how commands can be implemented 72 | 73 | ``` 74 | ./psp2client -h yourvitaip listen 75 | [INFO]: Client connected from xxx.xxx.xxx.xxx port: 30915 76 | [INFO]: sock psp2link_fileio set 50 connected 1 77 | [INFO]: Waiting for connection 78 | [INFO]: psp2link connected 1 79 | [DEBUG]: dir open req (host0:/usr/local) 80 | [DEBUG]: dir open reply received (ret 0) 81 | [DEBUG]: dir read req (0) 82 | [DEBUG]: dir read reply received (ret 1) 83 | [DEBUG]: dir read req (0) 84 | [DEBUG]: dir read reply received (ret 1) 85 | [DEBUG]: dir read req (0) 86 | [DEBUG]: dir read reply received (ret 1) 87 | [DEBUG]: dir read req (0) 88 | [DEBUG]: dir read reply received (ret 1) 89 | [DEBUG]: dir read req (0) 90 | [DEBUG]: dir read reply received (ret 1) 91 | [DEBUG]: dir read req (0) 92 | [DEBUG]: dir read reply received (ret 1) 93 | [DEBUG]: dir read req (0) 94 | [DEBUG]: dir read reply received (ret 1) 95 | [DEBUG]: dir read req (0) 96 | [DEBUG]: dir read reply received (ret 1) 97 | [DEBUG]: dir read req (0) 98 | [DEBUG]: dir read reply received (ret 1) 99 | [DEBUG]: dir read req (0) 100 | [DEBUG]: dir read reply received (ret 1) 101 | [DEBUG]: dir read req (0) 102 | [DEBUG]: dir read reply received (ret 1) 103 | [DEBUG]: dir read req (0) 104 | [DEBUG]: dir read reply received (ret 1) 105 | [DEBUG]: dir read req (0) 106 | [DEBUG]: dir read reply received (ret 1) 107 | [DEBUG]: dir read req (0) 108 | [DEBUG]: dir read reply received (ret 1) 109 | [DEBUG]: dir read req (0) 110 | [DEBUG]: dir read reply received (ret 1) 111 | [DEBUG]: dir read req (0) 112 | [DEBUG]: dir read reply received (ret 1) 113 | [DEBUG]: dir read req (0) 114 | [DEBUG]: dir read reply received (ret 1) 115 | [DEBUG]: dir read req (0) 116 | [DEBUG]: dir read reply received (ret 1) 117 | [DEBUG]: dir read req (0) 118 | [DEBUG]: dir read reply received (ret 1) 119 | [DEBUG]: dir read req (0) 120 | [DEBUG]: dir read reply received (ret 0) 121 | [DEBUG]: psp2link_file: dir close req (fd: 0) 122 | [DEBUG]: dir close reply received (ret 0) 123 | ``` 124 | 125 | ``` 126 | ./psp2client -h yourvitaip -t 10 execelf host0:README.md 127 | [ERROR]: [PSP2LINK] Client reconnected 128 | [INFO]: [PSP2LINK] sock psp2link_fileio set 124 connected 1 129 | [INFO]: [PSP2LINK] Waiting for connection 130 | [DEBUG]: [PSP2LINK] commands listener received packet size (266) 131 | [DEBUG]: [PSP2LINK] Received command execelf argc=1 argv=host0:README.md 132 | [DEBUG]: [PSP2LINK] file open req (host0:README.md, 1 0) 133 | Opening README.md flags 0 134 | Open return 5 135 | [DEBUG]: [PSP2LINK] file open reply received (ret 5) 136 | [DEBUG]: [PSP2LINK] file lseek req (fd: 5) 137 | 3382 result of lseek 0 offset 2 whence 138 | [DEBUG]: [PSP2LINK] psp2link_lseek_file: lseek reply received (ret 3382) 139 | [DEBUG]: [PSP2LINK] file lseek req (fd: 5) 140 | 0 result of lseek 0 offset 0 whence 141 | [DEBUG]: [PSP2LINK] psp2link_lseek_file: lseek reply received (ret 0) 142 | [DEBUG]: [PSP2LINK] psp2link_read_file: Reply said there's 3382 bytes to read (wanted 3382) 143 | [DEBUG]: [PSP2LINK] psp2link_file: file close req (fd: 5) 144 | [DEBUG]: [PSP2LINK] psp2link_close_file: close reply received (ret 0) 145 | [DEBUG]: [PSP2LINK] commands listener waiting for next command 146 | ``` 147 | 148 | 149 | 5) ready to have a lot of fun :P 150 | 151 | =================== 152 | What next? 153 | =================== 154 | 155 | Well, this library can be extended adding differents commands like ps2link was defined. It could be incorporated inside uvloader code and it would let load elf from hosts and provide host io fuctionality to homebrew apps. I am not going to do a loader when we have already uvloader backend. If it is not incorporated inside uvloader you can use like library showed in sample. 156 | 157 | About logging i like more udp log system like libdebugnet instead logging system incorporated in uvloader, but it is only my preference based only in my own experience since ps2dev days. 158 | 159 | If you don't want to use logging, initialize psp2link with right loglevel check libdebugnet sources to see differents log levels availables. 160 | 161 | =========================== 162 | Credits 163 | =========================== 164 | 165 | Special thanks goes to: 166 | 167 | - ps2dev old comrades. 168 | - All people who collaborated in PSP2SDK: @173210, @xerpi, @frangar, @frtomtomdu80, @hykemthedemon , @SMOKE587, @Josh_Axey ... 169 | - font in logo from http://www.fontspace.com/nal/the-rave-is-in-your-pants 170 | - xyzz for help with new toolchain 171 | 172 | -------------------------------------------------------------------------------- /libpsp2link/Makefile: -------------------------------------------------------------------------------- 1 | TARGET_LIB = libpsp2link.a 2 | OBJS = source/requests.o source/commands.o source/psp2link.o source/emulink.o 3 | INCLUDES = include 4 | PREFIX = arm-vita-eabi 5 | CC = $(PREFIX)-gcc 6 | AR = $(PREFIX)-ar 7 | CFLAGS = -Wl,-q -Wall -O3 -I$(INCLUDES) 8 | ASFLAGS = $(CFLAGS) 9 | 10 | all: $(TARGET_LIB) 11 | 12 | 13 | $(TARGET_LIB): $(OBJS) 14 | $(AR) -rc $@ $^ 15 | 16 | clean: 17 | @rm -rf $(TARGET_LIB) $(OBJS) 18 | 19 | install: $(TARGET_LIB) 20 | @cp $(TARGET_LIB) $(VITASDK)/arm-vita-eabi/lib 21 | @cp include/psp2link.h $(VITASDK)/arm-vita-eabi/include 22 | @echo "Installed!" -------------------------------------------------------------------------------- /libpsp2link/include/psp2link.h: -------------------------------------------------------------------------------- 1 | /* 2 | * psp2link library for PSP2 to communicate and use host file system with psp2client host tool 3 | * Copyright (C) 2003,2015 Antonio Jose Ramos Marquez (aka bigboss) @psxdev on twitter 4 | * Repository https://github.com/psxdev/psp2link 5 | * based on ps2vfs, ps2client, ps2link, ps2http tools. 6 | * Credits goes for all people involved in ps2dev project https://github.com/ps2dev 7 | * This file is subject to the terms and conditions of the PSP2Link License. 8 | * See the file LICENSE in the main directory of this distribution for more 9 | * details. 10 | */ 11 | 12 | #ifndef _PSP2LINK_H_ 13 | #define _PSP2LINK_H_ 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | typedef struct psp2LinkConfiguration 21 | { 22 | int psp2link_fileio_active; 23 | int psp2link_cmdsio_active; 24 | 25 | int psp2link_requests_port; 26 | int psp2link_commands_port; 27 | int psp2link_debug_port; 28 | 29 | int psp2link_fileio_sock; 30 | 31 | int psp2link_initialized; 32 | 33 | int psp2link_commands_sock; 34 | int psp2link_requests_sock; 35 | 36 | debugNetConfiguration *debugconf; 37 | 38 | 39 | 40 | } psp2LinkConfiguration; 41 | typedef enum psp2LinkValue 42 | { 43 | FILEIO_ACTIVE=1, 44 | CMDSIO_ACTIVE=2, 45 | DEBUGNET_ACTIVE=3, 46 | PSP2LINK_ACTIVE=4, 47 | REQUESTS_PORT=5, 48 | COMMANDS_PORT=6, 49 | DEBUG_PORT=7, 50 | FILEIO_SOCK=8, 51 | REQUESTS_SOCK=9, 52 | COMMANDS_SOCK=10, 53 | DEBUG_SOCK=11, 54 | LOG_LEVEL=12, 55 | } psp2LinkValue; 56 | 57 | 58 | int psp2LinkIoGetstat(const char *file, SceIoStat *stat); 59 | int psp2LinkIoChstat(const char *file, SceIoStat *stat,int bit); 60 | int psp2LinkIoGetstatByFd(SceUID fd, SceIoStat *stat); 61 | int psp2LinkIoRename(const char *oldname, const char *newname); 62 | int psp2LinkIoGetCwd(char *dirname); 63 | int psp2LinkIoSetCwd(const char *dirname); 64 | int psp2LinkIoOpen(const char *file, int flags, SceMode mode); 65 | int psp2LinkIoClose(SceUID fd); 66 | int psp2LinkIoRead(SceUID fd, void *data, SceSize size); 67 | int psp2LinkIoWrite(SceUID fd, const void *data, SceSize size); 68 | int psp2LinkIoLseek(SceUID fd, int offset, int whence); 69 | int psp2LinkIoRemove(const char *file); 70 | int psp2LinkIoMkdir(const char *dirname, SceMode mode); 71 | int psp2LinkIoRmdir(const char *dirname); 72 | int psp2LinkIoDopen(const char *dirname); 73 | int psp2LinkIoDread(SceUID fd, SceIoDirent *dir); 74 | int psp2LinkIoDclose(SceUID fd); 75 | 76 | //emu IO 77 | int emuIoGetstat(const char *file, SceIoStat *stat); 78 | int emuIoChstat(const char *file, SceIoStat *stat,int bit); 79 | int emuIoGetstatByFd(SceUID fd, SceIoStat *stat); 80 | int emuIoRename(const char *oldname, const char *newname); 81 | int emuIoGetCwd(char *dirname); 82 | int emuIoSetCwd(const char *dirname); 83 | int emuIoOpen(const char *file, int flags, SceMode mode); 84 | int emuIoClose(SceUID fd); 85 | int emuIoRead(SceUID fd, void *data, SceSize size); 86 | int emuIoWrite(SceUID fd, const void *data, SceSize size); 87 | int emuIoLseek(SceUID fd, int offset, int whence); 88 | int emuIoRemove(const char *file); 89 | int emuIoMkdir(const char *dirname, SceMode mode); 90 | int emuIoRmdir(const char *dirname); 91 | int emuIoDopen(const char *dirname); 92 | int emuIoDread(SceUID fd, SceIoDirent *dir); 93 | int emuIoDclose(SceUID fd); 94 | int emuIoSetLocalDir(char *path); 95 | int emuIoSetRemoteDir(char *path); 96 | char * emuIoGetLocalDir(); 97 | char * emuIoGetRemoteDir(); 98 | int emuIoCheckByFd(SceUID fd); 99 | int emuIoCheckFreeFd(); 100 | int emuIoInit(char *local,char *remote); 101 | int emuIoFinish(); 102 | 103 | 104 | void psp2LinkRequestsAbort(); 105 | int psp2LinkRequestsIsConnected(); 106 | int psp2LinkGetValue(psp2LinkValue val); 107 | psp2LinkConfiguration *psp2LinkGetConfig(); 108 | int psp2LinkSetConfig(psp2LinkConfiguration *conf); 109 | int psp2LinkCreateConf(); 110 | int psp2LinkInitWithConf(psp2LinkConfiguration *conf); 111 | int psp2LinkInit(char *serverIp, int requestPort,int debugPort, int commandPort, int level); 112 | void psp2LinkFinish(); 113 | 114 | 115 | 116 | #endif 117 | -------------------------------------------------------------------------------- /libpsp2link/include/psp2link_internal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * psp2link library for PSP2 to communicate and use host file system with psp2client host tool 3 | * Copyright (C) 2003,2015 Antonio Jose Ramos Marquez (aka bigboss) @psxdev on twitter 4 | * Repository https://github.com/psxdev/psp2link 5 | * based on ps2vfs, ps2client, ps2link, ps2http tools. 6 | * Credits goes for all people involved in ps2dev project https://github.com/ps2dev 7 | * This file is subject to the terms and conditions of the PSP2Link License. 8 | * See the file LICENSE in the main directory of this distribution for more 9 | * details. 10 | */ 11 | 12 | #ifndef _PSP2LINK_INTERNAL_H_ 13 | #define _PSP2LINK_INTERNAL_H_ 14 | 15 | #define PSP2LINK_OPEN_CMD 0xbabe0111 16 | #define PSP2LINK_OPEN_RLY 0xbabe0112 17 | #define PSP2LINK_CLOSE_CMD 0xbabe0121 18 | #define PSP2LINK_CLOSE_RLY 0xbabe0122 19 | #define PSP2LINK_READ_CMD 0xbabe0131 20 | #define PSP2LINK_READ_RLY 0xbabe0132 21 | #define PSP2LINK_WRITE_CMD 0xbabe0141 22 | #define PSP2LINK_WRITE_RLY 0xbabe0142 23 | #define PSP2LINK_LSEEK_CMD 0xbabe0151 24 | #define PSP2LINK_LSEEK_RLY 0xbabe0152 25 | #define PSP2LINK_OPENDIR_CMD 0xbabe0161 26 | #define PSP2LINK_OPENDIR_RLY 0xbabe0162 27 | #define PSP2LINK_CLOSEDIR_CMD 0xbabe0171 28 | #define PSP2LINK_CLOSEDIR_RLY 0xbabe0172 29 | #define PSP2LINK_READDIR_CMD 0xbabe0181 30 | #define PSP2LINK_READDIR_RLY 0xbabe0182 31 | #define PSP2LINK_REMOVE_CMD 0xbabe0191 32 | #define PSP2LINK_REMOVE_RLY 0xbabe0192 33 | #define PSP2LINK_MKDIR_CMD 0xbabe01a1 34 | #define PSP2LINK_MKDIR_RLY 0xbabe01a2 35 | #define PSP2LINK_RMDIR_CMD 0xbabe01b1 36 | #define PSP2LINK_RMDIR_RLY 0xbabe01b2 37 | #define PSP2LINK_GETCWD_CMD 0xbabe01c1 38 | #define PSP2LINK_GETCWD_RLY 0xbabe01c2 39 | #define PSP2LINK_SETCWD_CMD 0xbabe01d1 40 | #define PSP2LINK_SETCWD_RLY 0xbabe01d2 41 | #define PSP2LINK_CHSTAT_CMD 0xbabe01e1 42 | #define PSP2LINK_CHSTAT_RLY 0xbabe01e2 43 | #define PSP2LINK_GETSTAT_CMD 0xbabe01f1 44 | #define PSP2LINK_GETSTAT_RLY 0xbabe01f2 45 | #define PSP2LINK_FGETSTAT_CMD 0xbabe0211 46 | #define PSP2LINK_FGETSTAT_RLY 0xbabe0212 47 | #define PSP2LINK_RENAME_CMD 0xbabe0221 48 | #define PSP2LINK_RENAME_RLY 0xbabe0222 49 | 50 | 51 | 52 | //stats name still 256. For path 1024 53 | #define PSP2LINK_MAX_PATH 1024 54 | 55 | 56 | typedef struct 57 | { 58 | unsigned int cmd; 59 | unsigned short len; 60 | } __attribute__((packed)) psp2link_pkt_hdr; 61 | 62 | typedef struct 63 | { 64 | unsigned int cmd; 65 | unsigned short len; 66 | int retval; 67 | } __attribute__((packed)) psp2link_pkt_file_rly; 68 | 69 | typedef struct 70 | { 71 | unsigned int cmd; 72 | unsigned short len; 73 | int flags; 74 | char path[PSP2LINK_MAX_PATH]; 75 | } __attribute__((packed)) psp2link_pkt_open_req; 76 | 77 | typedef struct 78 | { 79 | unsigned int cmd; 80 | unsigned short len; 81 | int fd; 82 | } __attribute__((packed)) psp2link_pkt_close_req; 83 | 84 | typedef struct 85 | { 86 | unsigned int cmd; 87 | unsigned short len; 88 | int fd; 89 | int nbytes; 90 | } __attribute__((packed)) psp2link_pkt_read_req; 91 | 92 | typedef struct 93 | { 94 | unsigned int cmd; 95 | unsigned short len; 96 | int retval; 97 | int nbytes; 98 | } __attribute__((packed)) psp2link_pkt_read_rly; 99 | 100 | typedef struct 101 | { 102 | unsigned int cmd; 103 | unsigned short len; 104 | int fd; 105 | int nbytes; 106 | } __attribute__((packed)) psp2link_pkt_write_req; 107 | 108 | typedef struct 109 | { 110 | unsigned int cmd; 111 | unsigned short len; 112 | int fd; 113 | int offset; 114 | int whence; 115 | } __attribute__((packed)) psp2link_pkt_lseek_req; 116 | 117 | typedef struct 118 | { 119 | unsigned int cmd; 120 | unsigned short len; 121 | char name[PSP2LINK_MAX_PATH]; 122 | } __attribute__((packed)) psp2link_pkt_remove_req; 123 | 124 | typedef struct 125 | { 126 | unsigned int cmd; 127 | unsigned short len; 128 | int mode; 129 | char name[PSP2LINK_MAX_PATH]; 130 | } __attribute__((packed)) psp2link_pkt_mkdir_req; 131 | 132 | typedef struct 133 | { 134 | unsigned int cmd; 135 | unsigned short len; 136 | char name[PSP2LINK_MAX_PATH]; 137 | } __attribute__((packed)) psp2link_pkt_rmdir_req; 138 | 139 | typedef struct 140 | { 141 | unsigned int cmd; 142 | unsigned short len; 143 | int fd; 144 | } __attribute__((packed)) psp2link_pkt_dread_req; 145 | 146 | typedef struct 147 | { 148 | unsigned int cmd; 149 | unsigned short len; 150 | int retval; 151 | unsigned int mode; 152 | unsigned int attr; 153 | unsigned int size; 154 | unsigned short ctime[8]; 155 | unsigned short atime[8]; 156 | unsigned short mtime[8]; 157 | char name[256]; 158 | } __attribute__((packed)) psp2link_pkt_dread_rly; 159 | 160 | typedef struct 161 | { 162 | unsigned int cmd; 163 | unsigned short len; 164 | int retval; 165 | char name[PSP2LINK_MAX_PATH]; 166 | } __attribute__((packed)) psp2link_pkt_getcwd_rly; 167 | 168 | typedef struct 169 | { 170 | unsigned int cmd; 171 | unsigned short len; 172 | char path[PSP2LINK_MAX_PATH]; 173 | } __attribute__((packed)) psp2link_pkt_setcwd_req; 174 | 175 | typedef struct 176 | { 177 | unsigned int cmd; 178 | unsigned short len; 179 | char path[PSP2LINK_MAX_PATH]; 180 | } __attribute__((packed)) psp2link_pkt_getstat_req; 181 | 182 | typedef struct 183 | { 184 | unsigned int cmd; 185 | unsigned short len; 186 | int retval; 187 | unsigned int mode; 188 | unsigned int attr; 189 | unsigned int size; 190 | unsigned short ctime[8]; 191 | unsigned short atime[8]; 192 | unsigned short mtime[8]; 193 | } __attribute__((packed)) psp2link_pkt_getstat_rly; 194 | 195 | typedef struct 196 | { 197 | unsigned int cmd; 198 | unsigned short len; 199 | char path[PSP2LINK_MAX_PATH]; 200 | unsigned int mode; 201 | } __attribute__((packed)) psp2link_pkt_chstat_req; 202 | 203 | typedef struct 204 | { 205 | unsigned int cmd; 206 | unsigned short len; 207 | int fd; 208 | } __attribute__((packed)) psp2link_pkt_fgetstat_req; 209 | 210 | typedef struct 211 | { 212 | unsigned int cmd; 213 | unsigned short len; 214 | char path[PSP2LINK_MAX_PATH]; 215 | char newpath[PSP2LINK_MAX_PATH]; 216 | } __attribute__((packed)) psp2link_pkt_rename_req; 217 | 218 | 219 | 220 | #define PSP2LINK_EXECELF_CMD 0xbabe0201 221 | #define PSP2LINK_EXECSPRX_CMD 0xbabe0202 222 | #define PSP2LINK_EXIT_CMD 0xbabe0203 223 | 224 | 225 | typedef struct 226 | { 227 | unsigned int cmd; 228 | unsigned short len; 229 | int argc; 230 | char argv[PSP2LINK_MAX_PATH]; 231 | } __attribute__((packed)) psp2link_pkt_exec_cmd; 232 | 233 | 234 | #define PSP2LINK_MAX_WRITE_SEGMENT (65535 - sizeof(psp2link_pkt_write_req)) //1460 235 | #define PSP2LINK_MAX_READ_SEGMENT (65535 - sizeof(psp2link_pkt_read_rly)) //1460 236 | 237 | int psp2link_requests_thread(SceSize args, void *argp); 238 | int psp2link_commands_thread(SceSize args, void *argp); 239 | void psp2LinkCommandsAbort(); 240 | void psp2LinkRequestsAbort(); 241 | 242 | 243 | #endif 244 | -------------------------------------------------------------------------------- /libpsp2link/source/commands.c: -------------------------------------------------------------------------------- 1 | /* 2 | * psp2link library for PSP2 to communicate and use host file system with psp2client host tool 3 | * Copyright (C) 2003,2015 Antonio Jose Ramos Marquez (aka bigboss) @psxdev on twitter 4 | * Repository https://github.com/psxdev/psp2link 5 | * based on ps2vfs, ps2client, ps2link, ps2http tools. 6 | * Credits goes for all people involved in ps2dev project https://github.com/ps2dev 7 | * This file is subject to the terms and conditions of the PSP2Link License. 8 | * See the file LICENSE in the main directory of this distribution for more 9 | * details. 10 | */ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include "psp2link_internal.h" 21 | #include "psp2link.h" 22 | 23 | //int server_commands_sockfd = -1; 24 | extern psp2LinkConfiguration *configuration; 25 | #define BUF_SIZE 1024 26 | static char recvbuf[BUF_SIZE] __attribute__((aligned(16))); 27 | 28 | 29 | 30 | void psp2LinkCmdExecElf(psp2link_pkt_exec_cmd *pkg) 31 | { 32 | char *buf;//buffer for elf file 33 | int fd; //descriptor to manage file from host0 34 | int filesize;//variable to control file size 35 | int numread;//control read 36 | debugNetPrintf(DEBUG,"[PSP2LINK] Received command execelf argc=%x argv=%s\n",sceNetNtohl(pkg->argc),pkg->argv); 37 | 38 | //we open file in read only from host0 ps4sh include the full path with host0:/....... 39 | fd=psp2LinkIoOpen(pkg->argv,SCE_O_RDONLY,0); 40 | 41 | //If we can't open file from host0 print the error and return 42 | if(fd<0) 43 | { 44 | debugNetPrintf(DEBUG,"[PSP2LINK] psp2LinkOpen returned error %d\n",fd); 45 | return; 46 | } 47 | //Seek to final to get file size 48 | filesize=psp2LinkIoLseek(fd,0,SCE_SEEK_END); 49 | //If we get an error print it and return 50 | if(filesize<0) 51 | { 52 | debugNetPrintf(DEBUG,"[PSP2LINK] psp2LinkSeek returned error %d\n",fd); 53 | psp2LinkIoClose(fd); 54 | return; 55 | } 56 | //Seek back to start 57 | psp2LinkIoLseek(fd,0,SCE_SEEK_SET); 58 | //Reserve memory for read buffer 59 | buf=malloc(filesize); 60 | //Read filsesize bytes to buf 61 | numread=psp2LinkIoRead(fd,buf,filesize); 62 | //if we don't get filesize bytes we are in trouble 63 | if(numread!=filesize) 64 | { 65 | debugNetPrintf(DEBUG,"[PSP2LINK] ps4LinkRead returned error %d\n",numread); 66 | psp2LinkIoClose(fd); 67 | return; 68 | } 69 | //Close file 70 | psp2LinkIoClose(fd); 71 | 72 | //buffer with elf it's ready time to call load elf stuff.... 73 | 74 | 75 | return; 76 | } 77 | void psp2LinkCmdExecSprx(psp2link_pkt_exec_cmd *pkg) 78 | { 79 | debugNetPrintf(DEBUG,"[PSP2LINK] Received command execsprx argc=%d argv=%s\n",sceNetNtohl(pkg->argc),pkg->argv); 80 | //TODO check psp2LinkCmdExecElf 81 | } 82 | void psp2LinkCmdExit(psp2link_pkt_exec_cmd *pkg) 83 | { 84 | debugNetPrintf(DEBUG,"[PSP2LINK] Received command exit. Closing PSP2Link...\n"); 85 | 86 | psp2LinkFinish(); 87 | 88 | } 89 | void psp2LinkCommandsAbort() 90 | { 91 | int ret; 92 | if(psp2LinkGetValue(COMMANDS_SOCK)) 93 | { 94 | debugNetPrintf(DEBUG,"[PSP2LINK] Aborting psp2link_commands_sock\n"); 95 | 96 | ret = sceNetSocketAbort(psp2LinkGetValue(COMMANDS_SOCK),1); 97 | if (ret < 0) { 98 | debugNetPrintf(DEBUG,"[PSP2LINK] abort psp2link_commands_sock returned error 0x%08X\n", ret); 99 | } 100 | } 101 | } 102 | int psp2link_commands_thread(SceSize args, void *argp) 103 | { 104 | struct SceNetSockaddrIn serveraddr; 105 | struct SceNetSockaddrIn remote_addr; 106 | int ret; 107 | int len; 108 | unsigned int addrlen; 109 | unsigned int cmd; 110 | psp2link_pkt_hdr *header; 111 | 112 | debugNetPrintf(DEBUG,"[PSP2LINK] Command Thread Started.\n" ); 113 | 114 | configuration->psp2link_commands_sock = sceNetSocket("commands_server_sock",SCE_NET_AF_INET, SCE_NET_SOCK_DGRAM, SCE_NET_IPPROTO_UDP); 115 | 116 | if (psp2LinkGetValue(COMMANDS_SOCK) >=0) 117 | { 118 | debugNetPrintf(DEBUG,"[PSP2LINK] Created psp2link_commands_sock: %d\n", psp2LinkGetValue(COMMANDS_SOCK)); 119 | } 120 | else 121 | { 122 | debugNetPrintf(DEBUG,"[PSP2LINK] Error creating socket psp2link_commands_sock 0x%08X\n", psp2LinkGetValue(COMMANDS_SOCK)); 123 | psp2LinkFinish(); 124 | return -1; 125 | } 126 | /* Fill the server's address */ 127 | memset(&serveraddr, 0, sizeof serveraddr); 128 | serveraddr.sin_family = SCE_NET_AF_INET; 129 | serveraddr.sin_addr.s_addr = sceNetHtonl(SCE_NET_INADDR_ANY); 130 | serveraddr.sin_port = sceNetHtons(psp2LinkGetValue(COMMANDS_PORT)); 131 | 132 | ret = sceNetBind(psp2LinkGetValue(COMMANDS_SOCK), (SceNetSockaddr *)&serveraddr, sizeof(serveraddr)); 133 | 134 | 135 | 136 | 137 | if (ret < 0) 138 | { 139 | debugNetPrintf(DEBUG,"[PSP2LINK] command listener sceNetBind error: 0x%08X\n", ret); 140 | sceNetSocketClose(psp2LinkGetValue(COMMANDS_SOCK)); 141 | psp2LinkFinish(); 142 | return -1; 143 | } 144 | // Do tha thing 145 | debugNetPrintf(DEBUG,"[PSP2LINK] Command listener waiting for commands...\n"); 146 | 147 | while(psp2LinkGetValue(CMDSIO_ACTIVE)) { 148 | 149 | addrlen = sizeof(remote_addr); 150 | //wait for new command 151 | 152 | len = sceNetRecvfrom(psp2LinkGetValue(COMMANDS_SOCK), &recvbuf[0], BUF_SIZE, 0, (struct SceNetSockaddr *)&remote_addr,&addrlen); 153 | debugNetPrintf(DEBUG,"[PSP2LINK] commands listener received packet size (%d)\n", len); 154 | 155 | if (len < 0) { 156 | debugNetPrintf(DEBUG,"[PSP2LINK] commands listener recvfrom size error (%d)\n", len); 157 | continue; 158 | } 159 | if (len < sizeof(psp2link_pkt_hdr)) { 160 | debugNetPrintf(DEBUG,"[PSP2LINK] commands listener recvfrom header size error (%d)\n", len); 161 | continue; 162 | } 163 | 164 | header = (psp2link_pkt_hdr *)recvbuf; 165 | cmd = sceNetHtonl(header->cmd); 166 | 167 | switch (cmd) { 168 | 169 | case PSP2LINK_EXECELF_CMD: 170 | psp2LinkCmdExecElf((psp2link_pkt_exec_cmd *)recvbuf); 171 | break; 172 | case PSP2LINK_EXECSPRX_CMD: 173 | psp2LinkCmdExecSprx((psp2link_pkt_exec_cmd *)recvbuf); 174 | break; 175 | case PSP2LINK_EXIT_CMD: 176 | psp2LinkCmdExit((psp2link_pkt_exec_cmd *)recvbuf); 177 | break; 178 | default: 179 | debugNetPrintf(DEBUG,"[PSP2LINK] Unknown command received\n"); 180 | break; 181 | } 182 | debugNetPrintf(DEBUG,"[PSP2LINK] commands listener waiting for next command\n"); 183 | } 184 | debugNetPrintf(DEBUG,"[PSP2LINK] exit commands listener thread\n"); 185 | if(psp2LinkGetValue(COMMANDS_SOCK)) 186 | { 187 | debugNetPrintf(DEBUG,"[PSP2LINK] closing server_commands_sock\n"); 188 | sceNetSocketClose(psp2LinkGetValue(COMMANDS_SOCK)); 189 | configuration->psp2link_commands_sock=-1; 190 | } 191 | 192 | sceKernelExitDeleteThread(0); 193 | return 0; 194 | } 195 | -------------------------------------------------------------------------------- /libpsp2link/source/emulink.c: -------------------------------------------------------------------------------- 1 | /* 2 | * psp2link library for PSP2 to communicate and use host file system with psp2client host tool 3 | * Copyright (C) 2003,2015 Antonio Jose Ramos Marquez (aka bigboss) @psxdev on twitter 4 | * Repository https://github.com/psxdev/psp2link 5 | * based on ps2vfs, ps2client, ps2link, ps2http tools. 6 | * Credits goes for all people involved in ps2dev project https://github.com/ps2dev 7 | * This file is subject to the terms and conditions of the PSP2Link License. 8 | * See the file LICENSE in the main directory of this distribution for more 9 | * details. 10 | */ 11 | 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include "psp2link_internal.h" 22 | #include "psp2link.h" 23 | 24 | #define HOST0 "host0:" 25 | #define UX0 "ux0:" 26 | #define MAX_OPEN_DESCRIPTORS 10 27 | char *localPath; 28 | char *remotePath; 29 | 30 | int psp2link_open_descriptors[MAX_OPEN_DESCRIPTORS]; 31 | 32 | int emuIoSetLocalDir(char *path) 33 | { 34 | if(path) 35 | { 36 | if (strncmp(path, HOST0, sizeof(HOST0) - 1) != 0) 37 | { 38 | strcpy(localPath,path); 39 | return 0; 40 | } 41 | else 42 | { 43 | debugNetPrintf(DEBUG,"[PSP2LINK] %s is not a valid local directory\n",path); 44 | } 45 | } 46 | return 0x80010016; 47 | } 48 | int emuIoSetRemoteDir(char *path) 49 | { 50 | if(path) 51 | { 52 | if (strncmp(path, HOST0, sizeof(HOST0) - 1) == 0) 53 | { 54 | strcpy(remotePath,path); 55 | return 0; 56 | } 57 | else 58 | { 59 | debugNetPrintf(DEBUG,"[PSP2LINK] %s is not a valid remote directory\n",path); 60 | } 61 | 62 | } 63 | return 0x80010016; 64 | 65 | } 66 | char * emuIoGetLocalDir() 67 | { 68 | if(!localPath) 69 | { 70 | return NULL; 71 | } 72 | return localPath; 73 | } 74 | char * emuIoGetRemoteDir() 75 | { 76 | if(!remotePath) 77 | { 78 | return NULL; 79 | } 80 | return remotePath; 81 | } 82 | char * emuIoCreateFullPath(char *path,int pathmode) 83 | { 84 | if(!path || pathmode<0) 85 | { 86 | return NULL; 87 | } 88 | char *new_path=NULL; 89 | char *base_path=NULL; 90 | if(pathmode) 91 | { 92 | base_path=emuIoGetRemoteDir(); 93 | if(!base_path) 94 | { 95 | return NULL; 96 | } 97 | new_path=malloc(strlen(base_path)+strlen(path)+2); 98 | snprintf(new_path, PSP2LINK_MAX_PATH, "%s/%s", base_path,path); 99 | } 100 | else 101 | { 102 | base_path=emuIoGetLocalDir(); 103 | if(!base_path) 104 | { 105 | return NULL; 106 | } 107 | new_path=malloc(strlen(base_path)+strlen(path)+2); 108 | snprintf(new_path, PSP2LINK_MAX_PATH, "%s/%s", base_path,path); 109 | } 110 | return new_path; 111 | 112 | } 113 | int emuIoCheckByFd(SceUID fd) 114 | { 115 | if(fd<0) 116 | { 117 | return -1; 118 | } 119 | int i = 0; 120 | int slot = -1; 121 | 122 | // search slot 123 | for (i=0; i=0) 181 | { 182 | psp2LinkIoClose(psp2link_open_descriptors[i]); 183 | } 184 | psp2link_open_descriptors[i]=-1; 185 | } 186 | free(localPath); 187 | free(remotePath); 188 | return 0; 189 | } 190 | int emuIoGetstat(const char *file, SceIoStat *stat) 191 | { 192 | if(!file || !stat) 193 | { 194 | return 0x80010016; 195 | } 196 | if (strncmp(file, HOST0, sizeof(HOST0) - 1) != 0) 197 | { 198 | return sceIoGetstat(file,stat); 199 | } 200 | return psp2LinkIoGetstat(file,stat); 201 | } 202 | int emuIoChstat(const char *file, SceIoStat *stat,int bit) 203 | { 204 | if(!file || !stat) 205 | { 206 | return 0x80010016; 207 | } 208 | if (strncmp(file, HOST0, sizeof(HOST0) - 1) != 0) 209 | { 210 | return sceIoChstat(file,stat,bit); 211 | } 212 | return psp2LinkIoChstat(file,stat,bit); 213 | 214 | } 215 | int emuIoGetstatByFd(SceUID fd, SceIoStat *stat) 216 | { 217 | if(!stat || fd<0) 218 | { 219 | return 0x80010016; 220 | } 221 | int slot = -1; 222 | // search slot 223 | slot=emuIoCheckByFd(fd); 224 | 225 | if (slot == -1) 226 | { 227 | return sceIoGetstatByFd(fd,stat); 228 | } 229 | 230 | return psp2LinkIoGetstatByFd(fd,stat); 231 | } 232 | int emuIoRename(const char *oldname, const char *newname) 233 | { 234 | if(!oldname || !newname) 235 | { 236 | return 0x80010016; 237 | } 238 | if (strncmp(oldname, HOST0, sizeof(HOST0) - 1) != 0 && strncmp(newname, HOST0, sizeof(HOST0) - 1) != 0) 239 | { 240 | return sceIoRename(oldname,newname); 241 | } 242 | if (strncmp(oldname, HOST0, sizeof(HOST0) - 1) == 0 && strncmp(newname, HOST0, sizeof(HOST0) - 1) == 0) 243 | { 244 | return psp2LinkIoRename(oldname,newname); 245 | } 246 | //names have not a valid host0 device 247 | return 0x80010013; 248 | ; 249 | } 250 | int emuIoGetCwd(char *dirname) 251 | { 252 | if(!dirname) 253 | { 254 | return 0x80010016; 255 | } 256 | if (strncmp(dirname, HOST0, sizeof(HOST0) - 1) != 0) 257 | { 258 | //return sceIoGetcwd(dirname); 259 | return -1; 260 | } 261 | return psp2LinkIoGetCwd(dirname); 262 | } 263 | int emuIoSetCwd(const char *dirname) 264 | { 265 | if(!dirname) 266 | { 267 | return 0x80010016; 268 | } 269 | if (strncmp(dirname, HOST0, sizeof(HOST0) - 1) != 0) 270 | { 271 | //return sceIoSetCwd(dirname); 272 | return -1; 273 | } 274 | return psp2LinkIoSetCwd(dirname); 275 | } 276 | int emuIoOpen(const char *file, int flags, SceMode mode) 277 | { 278 | int ret; 279 | int result=-1; 280 | if(!file) 281 | { 282 | return 0x80010016; 283 | } 284 | if (strncmp(file, HOST0, sizeof(HOST0) - 1) == 0) 285 | { 286 | result=emuIoCheckFreeFd(); 287 | if (result != -1) 288 | { 289 | ret=psp2LinkIoOpen(file, flags, mode); 290 | if(ret>=0) 291 | { 292 | psp2link_open_descriptors[result]=ret; 293 | } 294 | return ret; 295 | } 296 | else 297 | { 298 | debugNetPrintf(DEBUG,"[PSP2LINK] too much open descritptors\n"); 299 | return 0x80010018; 300 | } 301 | } 302 | else 303 | { 304 | return sceIoOpen(file, flags, mode); 305 | } 306 | } 307 | int emuIoClose(SceUID fd) 308 | { 309 | int slot = -1; 310 | // search slot 311 | if(fd<0) 312 | { 313 | return 0x80010016; 314 | } 315 | slot=emuIoCheckByFd(fd); 316 | 317 | if (slot == -1) 318 | { 319 | return sceIoClose(fd); 320 | } 321 | psp2link_open_descriptors[slot]= -1; 322 | return psp2LinkIoClose(fd); 323 | } 324 | int emuIoRead(SceUID fd, void *data, SceSize size) 325 | { 326 | if(fd<0 || !data) 327 | { 328 | return 0x80010016; 329 | } 330 | int slot = -1; 331 | // search slot 332 | slot=emuIoCheckByFd(fd); 333 | 334 | if (slot == -1) 335 | { 336 | return sceIoRead(fd,data,size); 337 | } 338 | return psp2LinkIoRead(fd,data,size); 339 | } 340 | int emuIoWrite(SceUID fd, const void *data, SceSize size) 341 | { 342 | if(fd<0 || !data) 343 | { 344 | return 0x80010016; 345 | } 346 | int slot = -1; 347 | // search slot 348 | slot=emuIoCheckByFd(fd); 349 | 350 | if (slot == -1) 351 | { 352 | return sceIoWrite(fd,data,size); 353 | } 354 | return psp2LinkIoWrite(fd,data,size); 355 | } 356 | int emuIoLseek(SceUID fd, int offset, int whence) 357 | { 358 | if(fd<0) 359 | { 360 | return 0x80010016; 361 | } 362 | int slot = -1; 363 | // search slot 364 | slot=emuIoCheckByFd(fd); 365 | 366 | if (slot == -1) 367 | { 368 | return sceIoLseek(fd,offset,whence); 369 | } 370 | return psp2LinkIoLseek(fd,offset,whence); 371 | } 372 | int emuIoRemove(const char *file) 373 | { 374 | if(!file) 375 | { 376 | return 0x80010016; 377 | } 378 | if (strncmp(file, HOST0, sizeof(HOST0) - 1) != 0) 379 | { 380 | return sceIoRemove(file); 381 | } 382 | return psp2LinkIoRemove(file); 383 | 384 | } 385 | int emuIoMkdir(const char *dirname, SceMode mode) 386 | { 387 | if(!dirname) 388 | { 389 | return 0x80010016; 390 | } 391 | if (strncmp(dirname, HOST0, sizeof(HOST0) - 1) != 0) 392 | { 393 | return sceIoMkdir(dirname,mode); 394 | } 395 | return psp2LinkIoMkdir(dirname,mode); 396 | } 397 | int emuIoRmdir(const char *dirname) 398 | { 399 | if(!dirname) 400 | { 401 | return 0x80010016; 402 | } 403 | if (strncmp(dirname, HOST0, sizeof(HOST0) - 1) != 0) 404 | { 405 | return sceIoRmdir(dirname); 406 | } 407 | return psp2LinkIoRmdir(dirname); 408 | } 409 | int emuIoDopen(const char *dirname) 410 | { 411 | int ret; 412 | if(!dirname) 413 | { 414 | return 0x80010016; 415 | } 416 | int result=-1; 417 | if (strncmp(dirname, HOST0, sizeof(HOST0) - 1) == 0) 418 | { 419 | result=emuIoCheckFreeFd(); 420 | if (result != -1) 421 | { 422 | ret=psp2LinkIoDopen(dirname); 423 | if(ret>=0) 424 | { 425 | psp2link_open_descriptors[result]=ret; 426 | } 427 | return ret; 428 | } 429 | else 430 | { 431 | debugNetPrintf(DEBUG,"[PSP2LINK] too much open descritptors\n"); 432 | return 0x80010018; 433 | } 434 | } 435 | else 436 | { 437 | return sceIoDopen(dirname); 438 | } 439 | } 440 | int emuIoDread(SceUID fd, SceIoDirent *dir) 441 | { 442 | if(!dir || fd<0) 443 | { 444 | return 0x80010016; 445 | } 446 | int slot = -1; 447 | // search slot 448 | slot=emuIoCheckByFd(fd); 449 | 450 | if (slot == -1) 451 | { 452 | return sceIoDread(fd,dir); 453 | } 454 | return psp2LinkIoDread(fd,dir); 455 | } 456 | int emuIoDclose(SceUID fd) 457 | { 458 | if(fd<0) 459 | { 460 | return 0x80010016; 461 | } 462 | int slot = -1; 463 | // search slot 464 | slot=emuIoCheckByFd(fd); 465 | 466 | if (slot == -1) 467 | { 468 | return sceIoDclose(fd); 469 | } 470 | psp2link_open_descriptors[slot]= -1; 471 | return psp2LinkIoDclose(fd); 472 | } 473 | -------------------------------------------------------------------------------- /libpsp2link/source/psp2link.c: -------------------------------------------------------------------------------- 1 | /* 2 | * psp2link library for PSP2 to communicate and use host file system with psp2client host tool 3 | * Copyright (C) 2003,2015 Antonio Jose Ramos Marquez (aka bigboss) @psxdev on twitter 4 | * Repository https://github.com/psxdev/psp2link 5 | * based on ps2vfs, ps2client, ps2link, ps2http tools. 6 | * Credits goes for all people involved in ps2dev project https://github.com/ps2dev 7 | * This file is subject to the terms and conditions of the PSP2Link License. 8 | * See the file LICENSE in the main directory of this distribution for more 9 | * details. 10 | */ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | #include 21 | #include "psp2link.h" 22 | #include "psp2link_internal.h" 23 | 24 | 25 | int psp2link_requests_thread(SceSize args, void *argp); 26 | int psp2link_commands_thread(SceSize args, void *argp); 27 | 28 | 29 | 30 | SceUID server_request_thid; 31 | SceUID server_command_thid; 32 | 33 | psp2LinkConfiguration *configuration=NULL; 34 | 35 | int external_conf=0; 36 | 37 | 38 | /** 39 | * Init psp2link library 40 | * 41 | * @par Example: 42 | * @code 43 | * int ret; 44 | * ret = psp2LinkInit("172.26.0.2",0x4711,0x4712,0x4712, DEBUG); 45 | * @endcode 46 | * 47 | * @param serverIp - server ip for udp debug 48 | * @param requestPort - psp2 port server for requests 49 | * @param debugPort - udp port for debug 50 | * @param commandPort - psp2 port server for commands 51 | * @param level - DEBUG,ERROR,INFO or NONE 52 | */ 53 | int psp2LinkInit(char *serverIp, int requestPort,int debugPort, int commandPort, int level) 54 | { 55 | int ret; 56 | 57 | if(psp2LinkCreateConf()) 58 | { 59 | return psp2LinkGetValue(PSP2LINK_ACTIVE); 60 | } 61 | configuration->psp2link_requests_port=requestPort; 62 | configuration->psp2link_commands_port=commandPort; 63 | configuration->psp2link_debug_port=debugPort; 64 | 65 | if(debugNetInit(serverIp,debugPort,level)) 66 | { 67 | 68 | 69 | configuration->debugconf=debugNetGetConf(); 70 | 71 | server_request_thid = sceKernelCreateThread("psp2link_request_server_thread", psp2link_requests_thread, 64, 0x80000, 0, 0, NULL); 72 | 73 | 74 | if(server_request_thid<0) 75 | { 76 | debugNetPrintf(ERROR,"[PSP2LINK] Server request thread could not create error: 0x%08X\n", server_request_thid); 77 | psp2LinkFinish(); 78 | return 0; 79 | } 80 | debugNetPrintf(DEBUG,"[PSP2LINK] Server request thread UID: 0x%08X\n", server_request_thid); 81 | 82 | 83 | /* Start the server request thread */ 84 | ret=sceKernelStartThread(server_request_thid, 0, NULL); 85 | if(ret<0) 86 | { 87 | 88 | debugNetPrintf(ERROR,"Server command thread could not start error: 0x%08X\n", ret); 89 | sceKernelDeleteThread(server_request_thid); 90 | psp2LinkFinish(); 91 | return 0; 92 | 93 | } 94 | 95 | 96 | server_command_thid = sceKernelCreateThread("psp2link_command_server_thread", psp2link_commands_thread, 0x10000100, 0x10000, 0, 0, NULL); 97 | 98 | if(server_command_thid<0) 99 | { 100 | debugNetPrintf(ERROR,"Server command thread could not create error: 0x%08X\n", server_command_thid); 101 | sceKernelDeleteThread(server_request_thid); 102 | psp2LinkFinish(); 103 | return 0; 104 | } 105 | debugNetPrintf(DEBUG,"Server command thread UID: 0x%08X\n", server_command_thid); 106 | 107 | 108 | /* Start the server command thread */ 109 | ret=sceKernelStartThread(server_command_thid, 0, NULL); 110 | if(ret<0) 111 | { 112 | debugNetPrintf(ERROR,"Server command thread could not start error: 0x%08X\n", ret); 113 | sceKernelDeleteThread(server_command_thid); 114 | sceKernelDeleteThread(server_request_thid); 115 | psp2LinkFinish(); 116 | return 0; 117 | } 118 | 119 | 120 | 121 | 122 | /*library psp2link initialized*/ 123 | configuration->psp2link_initialized = 1; 124 | 125 | } 126 | else 127 | { 128 | configuration->psp2link_initialized = 0; 129 | psp2LinkFinish(); 130 | } 131 | 132 | return psp2LinkGetValue(PSP2LINK_ACTIVE); 133 | 134 | } 135 | /** 136 | * Set configuration to PSP2Link Library 137 | * 138 | * @par Example: 139 | * @code 140 | * psp2LinkSetConfig(myConf); 141 | * @endcode 142 | */ 143 | int psp2LinkSetConfig(psp2LinkConfiguration *conf) 144 | { 145 | if(!conf) 146 | { 147 | return 0; 148 | } 149 | configuration=conf; 150 | external_conf=1; 151 | return 1; 152 | } 153 | /** 154 | * Get configuration from PSP2Link Library 155 | * 156 | * @par Example: 157 | * @code 158 | * psp2LinkConfiguration *myConf=psp2LinkGetConfig(); 159 | * @endcode 160 | */ 161 | psp2LinkConfiguration *psp2LinkGetConfig() 162 | { 163 | if(!configuration) 164 | { 165 | return NULL; 166 | } 167 | return configuration; 168 | } 169 | /** 170 | * Init with configuration 171 | * 172 | * @par Example: 173 | * @code 174 | * psp2LinkInitWithConf(externalconf); 175 | * @endcode 176 | */ 177 | int psp2LinkInitWithConf(psp2LinkConfiguration *conf) 178 | { 179 | 180 | int ret; 181 | ret=psp2LinkSetConfig(conf); 182 | if(ret) 183 | { 184 | if(debugNetInitWithConf(conf->debugconf)) 185 | { 186 | 187 | debugNetPrintf(INFO,"psp2link already initialized using configuration from psp2link\n"); 188 | debugNetPrintf(INFO,"psp2link_fileio_active=%d\n",psp2LinkGetValue(FILEIO_ACTIVE)); 189 | debugNetPrintf(INFO,"psp2link_cmdsio_active=%d\n",psp2LinkGetValue(CMDSIO_ACTIVE)); 190 | debugNetPrintf(INFO,"psp2link_initialized=%d\n",psp2LinkGetValue(PSP2LINK_ACTIVE)); 191 | debugNetPrintf(INFO,"psp2link_requests_port=%d\n",psp2LinkGetValue(REQUESTS_PORT)); 192 | debugNetPrintf(INFO,"psp2link_commands_port=%d\n",psp2LinkGetValue(COMMANDS_PORT)); 193 | debugNetPrintf(INFO,"psp2link_debug_port=%d\n",psp2LinkGetValue(DEBUG_PORT)); 194 | debugNetPrintf(INFO,"psp2link_fileio_sock=%d\n",psp2LinkGetValue(FILEIO_SOCK)); 195 | debugNetPrintf(INFO,"psp2link_requests_sock=%d\n",psp2LinkGetValue(REQUESTS_SOCK)); 196 | debugNetPrintf(INFO,"psp2link_commands_sock=%d\n",psp2LinkGetValue(COMMANDS_SOCK)); 197 | return psp2LinkGetValue(PSP2LINK_ACTIVE); 198 | } 199 | else 200 | { 201 | return 0; 202 | } 203 | } 204 | else 205 | { 206 | return 0; 207 | } 208 | } 209 | /** 210 | * Create configuration values from PSP2Link library 211 | * 212 | * @par Example: 213 | * @code 214 | * psp2LinkCreateConf(); 215 | * @endcode 216 | */ 217 | int psp2LinkCreateConf() 218 | { 219 | if(!configuration) 220 | { 221 | configuration=malloc(sizeof(psp2LinkConfiguration)); 222 | configuration->psp2link_fileio_active=1; 223 | configuration->psp2link_cmdsio_active=1; 224 | configuration->psp2link_initialized=0; 225 | configuration->psp2link_fileio_sock=-1; 226 | configuration->psp2link_requests_sock=-1; 227 | configuration->psp2link_commands_sock=-1; 228 | return 0; 229 | } 230 | if(configuration->psp2link_initialized) 231 | { 232 | return 1; 233 | } 234 | return 0; 235 | } 236 | 237 | 238 | /** 239 | * Get configuration values from PSP2Link library 240 | * 241 | * @par Example: 242 | * @code 243 | * psp2LinkGetValue(PS4LINK_ACTIVE); 244 | * @endcode 245 | */ 246 | int psp2LinkGetValue(psp2LinkValue val) 247 | { 248 | int ret; 249 | switch(val) 250 | { 251 | case FILEIO_ACTIVE: 252 | ret=configuration->psp2link_fileio_active; 253 | break; 254 | case CMDSIO_ACTIVE: 255 | ret=configuration->psp2link_cmdsio_active; 256 | break; 257 | case DEBUGNET_ACTIVE: 258 | ret=configuration->debugconf->debugnet_initialized; 259 | break; 260 | case PSP2LINK_ACTIVE: 261 | ret=configuration->psp2link_initialized; 262 | break; 263 | case REQUESTS_PORT: 264 | ret=configuration->psp2link_requests_port; 265 | break; 266 | case COMMANDS_PORT: 267 | ret=configuration->psp2link_commands_port; 268 | break; 269 | case DEBUG_PORT: 270 | ret=configuration->psp2link_debug_port; 271 | break; 272 | case FILEIO_SOCK: 273 | ret=configuration->psp2link_fileio_sock; 274 | break; 275 | case REQUESTS_SOCK: 276 | ret=configuration->psp2link_requests_sock; 277 | break; 278 | case COMMANDS_SOCK: 279 | ret=configuration->psp2link_commands_sock; 280 | break; 281 | case DEBUG_SOCK: 282 | ret=configuration->debugconf->SocketFD; 283 | break; 284 | case LOG_LEVEL: 285 | ret=configuration->debugconf->logLevel; 286 | break; 287 | default: 288 | ret=0; 289 | break; 290 | } 291 | return ret; 292 | } 293 | 294 | /** 295 | * Finish debugnet library 296 | * 297 | * @par Example: 298 | * @code 299 | * psp2LinkFinish(); 300 | * @endcode 301 | */ 302 | void psp2LinkFinish() 303 | { 304 | 305 | if(!external_conf) 306 | { 307 | configuration->psp2link_fileio_active=0; 308 | configuration->psp2link_cmdsio_active=0; 309 | configuration->psp2link_initialized=0; 310 | psp2LinkRequestsAbort(); 311 | psp2LinkCommandsAbort(); 312 | sceKernelWaitThreadEnd(server_request_thid, NULL, NULL); 313 | sceKernelWaitThreadEnd(server_command_thid, NULL, NULL); 314 | debugNetFinish(); 315 | free(configuration->debugconf); 316 | free(configuration); 317 | } 318 | } 319 | -------------------------------------------------------------------------------- /libpsp2link/source/requests.c: -------------------------------------------------------------------------------- 1 | /* 2 | * psp2link library for PSP2 to communicate and use host file system with psp2client host tool 3 | * Copyright (C) 2003,2015 Antonio Jose Ramos Marquez (aka bigboss) @psxdev on twitter 4 | * Repository https://github.com/psxdev/psp2link 5 | * based on ps2vfs, ps2client, ps2link, ps2http tools. 6 | * Credits goes for all people involved in ps2dev project https://github.com/ps2dev 7 | * This file is subject to the terms and conditions of the PSP2Link License. 8 | * See the file LICENSE in the main directory of this distribution for more 9 | * details. 10 | */ 11 | 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include "psp2link_internal.h" 24 | #include "psp2link.h" 25 | 26 | 27 | #define PACKET_MAXSIZE 4096 28 | 29 | static char send_packet[PACKET_MAXSIZE] __attribute__((aligned(16))); 30 | static char recv_packet[PACKET_MAXSIZE] __attribute__((aligned(16))); 31 | unsigned int remote_pc_addr = 0xffffffff; 32 | 33 | //int server_requests_sock = -1; 34 | //int psp2link_fileio_sock = -1; 35 | //extern int psp2link_fileio_active; 36 | //extern int psp2link_requests_port; 37 | 38 | 39 | extern psp2LinkConfiguration *configuration; 40 | int psp2link_requests_connected; 41 | 42 | 43 | int psp2LinkRequestsIsConnected() 44 | { 45 | if(psp2link_requests_connected) 46 | { 47 | debugNetPrintf(INFO,"[PSP2LINK] psp2link connected %d\n", psp2link_requests_connected); 48 | } 49 | else 50 | { 51 | // debugNetPrintf(INFO,"psp2link is not connected %d\n", psp2link_requests_connected); 52 | } 53 | return psp2link_requests_connected; 54 | } 55 | void psp2LinkRequestsAbort() 56 | { 57 | int ret; 58 | if(psp2LinkGetValue(REQUESTS_SOCK)) 59 | { 60 | debugNetPrintf(DEBUG,"[PSP2LINK] Aborting psp2link_requests_sock\n"); 61 | 62 | ret = sceNetSocketAbort(psp2LinkGetValue(REQUESTS_SOCK),1); 63 | if (ret < 0) { 64 | debugNetPrintf(DEBUG,"[PSP2LINK] abort psp2link_requests_sock returned error 0x%08X\n", ret); 65 | } 66 | } 67 | } 68 | void psp2link_close_socket(void) 69 | { 70 | int ret; 71 | 72 | ret = sceNetSocketClose(psp2LinkGetValue(FILEIO_SOCK)); 73 | if (ret < 0) { 74 | debugNetPrintf(ERROR,"[PSP2LINK] disconnect returned error %d\n", ret); 75 | } 76 | configuration->psp2link_fileio_sock = -1; 77 | 78 | } 79 | 80 | 81 | /*void psp2link_close_fsys(void) 82 | { 83 | if (psp2LinkGetValue(FILEIO_SOCK) > 0) { 84 | sceNetSocketClose(psp2LinkGetValue(FILEIO_SOCK)); 85 | } 86 | configuration->psp2link_fileio_active = 0; 87 | return; 88 | }*/ 89 | 90 | static inline int psp2link_send(int sock, void *buf, int len, int flag) 91 | { 92 | int ret; 93 | ret = sceNetSend(sock, buf, len, flag); 94 | if (ret < 0) 95 | { 96 | debugNetPrintf(ERROR,"[PSP2LINK] sceNetSend error 0x%08X\n", ret); 97 | psp2link_close_socket(); 98 | return -1; 99 | } 100 | else 101 | { 102 | return ret; 103 | } 104 | } 105 | 106 | 107 | int psp2link_recv_bytes(int sock, char *buf, int bytes) 108 | { 109 | int left; 110 | int len; 111 | 112 | left = bytes; 113 | 114 | while (left > 0) 115 | { 116 | len = sceNetRecv(sock, &buf[bytes - left], left, SCE_NET_MSG_WAITALL); 117 | if (len < 0) 118 | { 119 | debugNetPrintf(ERROR,"[PSP2LINK] psp2link_recv_bytes error!! 0x%08X\n",len); 120 | return -1; 121 | } 122 | left -= len; 123 | } 124 | return bytes; 125 | } 126 | 127 | 128 | int psp2link_accept_pkt(int sock, char *buf, int len, int pkt_type) 129 | { 130 | int length; 131 | psp2link_pkt_hdr *hdr; 132 | unsigned int hcmd; 133 | unsigned short hlen; 134 | 135 | 136 | length = psp2link_recv_bytes(sock, buf, sizeof(psp2link_pkt_hdr)); 137 | if (length < 0) { 138 | debugNetPrintf(ERROR,"[PSP2LINK] psp2link_accept_pkt recv error\n"); 139 | return -1; 140 | } 141 | 142 | if (length < sizeof(psp2link_pkt_hdr)) { 143 | debugNetPrintf(ERROR,"[PSP2LINK] did not receive a full header!!!! " "Fix this! (%d)\n", length); 144 | } 145 | 146 | hdr = (psp2link_pkt_hdr *)buf; 147 | hcmd = sceNetNtohl(hdr->cmd); 148 | hlen = sceNetNtohs(hdr->len); 149 | 150 | if (hcmd != pkt_type) { 151 | debugNetPrintf(ERROR,"[PSP2LINK] psp2link_accept_pkt: Expected %x, got %x\n",pkt_type, hcmd); 152 | return 0; 153 | } 154 | 155 | if (hlen > len) { 156 | debugNetPrintf(ERROR,"[PSP2LINK] psp2link_accept_pkt: hdr->len is too large!! " "(%d, can only receive %d)\n", hlen, len); 157 | return 0; 158 | } 159 | 160 | // get the actual packet data 161 | length = psp2link_recv_bytes(sock, buf + sizeof(psp2link_pkt_hdr),hlen - sizeof(psp2link_pkt_hdr)); 162 | 163 | if (length < 0) { 164 | debugNetPrintf(ERROR,"[PSP2LINK] accept recv2 error!!\n"); 165 | return 0; 166 | } 167 | 168 | if (length < (hlen - sizeof(psp2link_pkt_hdr))) { 169 | debugNetPrintf(ERROR,"[PSP2LINK] psp2link_accept_pkt: Did not receive full packet!!! " ,"Fix this! (%d)\n", length); 170 | } 171 | 172 | return 1; 173 | } 174 | int psp2LinkIoGetCwd(char *dirname) 175 | { 176 | psp2link_pkt_hdr *getcwdreq; 177 | psp2link_pkt_getcwd_rly *getcwdrly; 178 | if (psp2LinkGetValue(FILEIO_SOCK) < 0) 179 | { 180 | debugNetPrintf(DEBUG,"[PSP2LINK] getcwd req but psp2link_fileio_sock is not active\n"); 181 | return -1; 182 | } 183 | debugNetPrintf(DEBUG,"[PSP2LINK] getcwd req\n"); 184 | getcwdreq = (psp2link_pkt_hdr *)&send_packet[0]; 185 | 186 | // Build packet 187 | getcwdreq->cmd = sceNetHtonl(PSP2LINK_GETCWD_CMD); 188 | getcwdreq->len = sceNetHtons((unsigned short)sizeof(psp2link_pkt_hdr)); 189 | 190 | if (psp2link_send(psp2LinkGetValue(FILEIO_SOCK), getcwdreq, sizeof(psp2link_pkt_hdr), SCE_NET_MSG_DONTWAIT) < 0) { 191 | return -1; 192 | } 193 | 194 | if (!psp2link_accept_pkt(psp2LinkGetValue(FILEIO_SOCK), recv_packet, sizeof(psp2link_pkt_getcwd_rly), PSP2LINK_GETCWD_RLY)) { 195 | debugNetPrintf(ERROR,"[PSP2LINK] psp2link_file: psp2link_getcwd: did not receive GETCWD_RLY\n"); 196 | return -1; 197 | } 198 | 199 | getcwdrly = (psp2link_pkt_getcwd_rly *)recv_packet; 200 | 201 | debugNetPrintf(DEBUG,"[PSP2LINK] getcwd reply received (ret %d)\n", sceNetNtohl(getcwdrly->retval)); 202 | if(sceNetNtohl(getcwdrly->retval)) 203 | { 204 | strncpy(dirname,getcwdrly->name,PSP2LINK_MAX_PATH); 205 | } 206 | 207 | return sceNetNtohl(getcwdrly->retval); 208 | 209 | } 210 | int psp2LinkIoSetCwd(const char *dirpath) 211 | { 212 | psp2link_pkt_setcwd_req *setcwdreq; 213 | psp2link_pkt_file_rly *setcwdrly; 214 | if (psp2LinkGetValue(FILEIO_SOCK) < 0) 215 | { 216 | debugNetPrintf(DEBUG,"[PSP2LINK] setcwd req but psp2link_fileio_sock is not active\n"); 217 | return -1; 218 | } 219 | debugNetPrintf(DEBUG,"[PSP2LINK] setcwd req to %s\n",dirpath); 220 | setcwdreq = (psp2link_pkt_setcwd_req *)&send_packet[0]; 221 | 222 | // Build packet 223 | setcwdreq->cmd = sceNetHtonl(PSP2LINK_SETCWD_CMD); 224 | setcwdreq->len = sceNetHtons((unsigned short)sizeof(psp2link_pkt_setcwd_req)); 225 | strncpy(setcwdreq->path, dirpath, PSP2LINK_MAX_PATH); 226 | setcwdreq->path[PSP2LINK_MAX_PATH - 1] = 0; // Make sure it's null-terminated 227 | 228 | 229 | if (psp2link_send(psp2LinkGetValue(FILEIO_SOCK), setcwdreq, sizeof(psp2link_pkt_setcwd_req), SCE_NET_MSG_DONTWAIT) < 0) { 230 | return -1; 231 | } 232 | 233 | if (!psp2link_accept_pkt(psp2LinkGetValue(FILEIO_SOCK), recv_packet, sizeof(psp2link_pkt_file_rly), PSP2LINK_SETCWD_RLY)) { 234 | debugNetPrintf(ERROR,"[PSP2LINK] psp2link_file: psp2link_setcwd: did not receive SETCWD_RLY\n"); 235 | return -1; 236 | } 237 | 238 | setcwdrly = (psp2link_pkt_file_rly *)recv_packet; 239 | 240 | debugNetPrintf(DEBUG,"[PSP2LINK] setcwd reply received (ret %d)\n", sceNetNtohl(setcwdrly->retval)); 241 | 242 | 243 | return sceNetNtohl(setcwdrly->retval); 244 | 245 | } 246 | int psp2LinkIoGetstat(const char *file, SceIoStat *stat) 247 | { 248 | psp2link_pkt_getstat_req *getstatreq; 249 | psp2link_pkt_getstat_rly *getstatrly; 250 | 251 | if (psp2LinkGetValue(REQUESTS_SOCK) < 0) { 252 | return -1; 253 | } 254 | 255 | debugNetPrintf(DEBUG,"[PSP2LINK] getstat req \n"); 256 | 257 | getstatreq = (psp2link_pkt_getstat_req *)&send_packet[0]; 258 | 259 | // Build packet 260 | getstatreq->cmd = sceNetHtonl(PSP2LINK_GETSTAT_CMD); 261 | getstatreq->len = sceNetHtons((unsigned short)sizeof(psp2link_pkt_getstat_req)); 262 | strncpy(getstatreq->path, file, PSP2LINK_MAX_PATH); 263 | getstatreq->path[PSP2LINK_MAX_PATH - 1] = 0; // Make sure it's null-terminated 264 | 265 | if (psp2link_send(psp2LinkGetValue(FILEIO_SOCK), getstatreq, sizeof(psp2link_pkt_getstat_req), SCE_NET_MSG_DONTWAIT) < 0) { 266 | return -1; 267 | } 268 | 269 | if (!psp2link_accept_pkt(psp2LinkGetValue(FILEIO_SOCK), recv_packet, sizeof(psp2link_pkt_getstat_rly), PSP2LINK_GETSTAT_RLY)) { 270 | debugNetPrintf(ERROR,"[PSP2LINK] psp2link_getstat: did not receive GETSTAT_RLY\n"); 271 | return -1; 272 | } 273 | 274 | getstatrly = (psp2link_pkt_getstat_rly *)recv_packet; 275 | 276 | debugNetPrintf(DEBUG,"[PSP2LINK] getstat reply received (ret %d)\n", sceNetNtohl(getstatrly->retval)); 277 | 278 | if(getstatrly->retval==0) 279 | { 280 | // now handle the return buffer translation, to build reply bit 281 | stat->st_mode = sceNetNtohl(getstatrly->mode); 282 | stat->st_attr = sceNetNtohl(getstatrly->attr); //no attr on pc/mac side ignore 0 is returned 283 | stat->st_size = sceNetNtohl(getstatrly->size); 284 | stat->st_ctime.microsecond = 0; 285 | stat->st_ctime.second = sceNetNtohs(getstatrly->ctime[1]); 286 | stat->st_ctime.minute = sceNetNtohs(getstatrly->ctime[2]); 287 | stat->st_ctime.hour = sceNetNtohs(getstatrly->ctime[3]); 288 | stat->st_ctime.day = sceNetNtohs(getstatrly->ctime[4]); 289 | stat->st_ctime.month = sceNetNtohs(getstatrly->ctime[5]); 290 | stat->st_ctime.year = sceNetNtohs(getstatrly->ctime[6]); 291 | 292 | stat->st_atime.microsecond = 0; 293 | stat->st_atime.second = sceNetNtohs(getstatrly->atime[1]); 294 | stat->st_atime.minute = sceNetNtohs(getstatrly->atime[2]); 295 | stat->st_atime.hour = sceNetNtohs(getstatrly->atime[3]); 296 | stat->st_atime.day = sceNetNtohs(getstatrly->atime[4]); 297 | stat->st_atime.month = sceNetNtohs(getstatrly->atime[5]); 298 | stat->st_atime.year = sceNetNtohs(getstatrly->atime[6]); 299 | stat->st_mtime.microsecond = 0; 300 | stat->st_mtime.second = sceNetNtohs(getstatrly->mtime[1]); 301 | stat->st_mtime.minute = sceNetNtohs(getstatrly->mtime[2]); 302 | stat->st_mtime.hour = sceNetNtohs(getstatrly->mtime[3]); 303 | stat->st_mtime.day = sceNetNtohs(getstatrly->mtime[4]); 304 | stat->st_mtime.month = sceNetNtohs(getstatrly->mtime[5]); 305 | stat->st_mtime.year = sceNetNtohs(getstatrly->mtime[6]); 306 | 307 | 308 | 309 | //stat->st_private[] don't know how to fill leave as is 310 | } 311 | return sceNetNtohl(getstatrly->retval); 312 | 313 | } 314 | int psp2LinkIoChstat(const char *file, SceIoStat *stat,int bit) 315 | { 316 | //we will ignore bit only consider changes on file permission in stat mask 0x1FF in stat->mode 317 | psp2link_pkt_chstat_req *getstatreq; 318 | psp2link_pkt_getstat_rly *getstatrly; 319 | 320 | if (psp2LinkGetValue(REQUESTS_SOCK) < 0) { 321 | return -1; 322 | } 323 | 324 | debugNetPrintf(DEBUG,"[PSP2LINK] chstat req %s maskbit %d\n",file,bit); 325 | 326 | getstatreq = (psp2link_pkt_chstat_req *)&send_packet[0]; 327 | 328 | // Build packet 329 | getstatreq->cmd = sceNetHtonl(PSP2LINK_CHSTAT_CMD); 330 | getstatreq->len = sceNetHtons((unsigned short)sizeof(psp2link_pkt_chstat_req)); 331 | strncpy(getstatreq->path, file, PSP2LINK_MAX_PATH); 332 | getstatreq->path[PSP2LINK_MAX_PATH - 1] = 0; // Make sure it's null-terminated 333 | getstatreq->mode = sceNetHtonl(stat->st_mode); //we suppose that only stat->mode&0x1ff is modified by user because stat is managed on pc/mac side 334 | 335 | 336 | if (psp2link_send(psp2LinkGetValue(FILEIO_SOCK), getstatreq, sizeof(psp2link_pkt_chstat_req), SCE_NET_MSG_DONTWAIT) < 0) { 337 | return -1; 338 | } 339 | 340 | if (!psp2link_accept_pkt(psp2LinkGetValue(FILEIO_SOCK), recv_packet, sizeof(psp2link_pkt_getstat_rly), PSP2LINK_CHSTAT_RLY)) { 341 | debugNetPrintf(ERROR,"[PSP2LINK] psp2link_chstat: did not receive CHSTAT_RLY\n"); 342 | return -1; 343 | } 344 | 345 | getstatrly = (psp2link_pkt_getstat_rly *)recv_packet; 346 | 347 | debugNetPrintf(DEBUG,"[PSP2LINK] chstat reply received (ret %d)\n", sceNetNtohl(getstatrly->retval)); 348 | 349 | if(getstatrly->retval==0) 350 | { 351 | // now handle the return buffer translation, to build reply bit 352 | stat->st_mode = sceNetNtohl(getstatrly->mode); 353 | stat->st_attr = sceNetNtohl(getstatrly->attr); //no attr on pc/mac side ignore 0 is returned 354 | stat->st_size = sceNetNtohl(getstatrly->size); 355 | stat->st_ctime.microsecond = 0; 356 | stat->st_ctime.second = sceNetNtohs(getstatrly->ctime[1]); 357 | stat->st_ctime.minute = sceNetNtohs(getstatrly->ctime[2]); 358 | stat->st_ctime.hour = sceNetNtohs(getstatrly->ctime[3]); 359 | stat->st_ctime.day = sceNetNtohs(getstatrly->ctime[4]); 360 | stat->st_ctime.month = sceNetNtohs(getstatrly->ctime[5]); 361 | stat->st_ctime.year = sceNetNtohs(getstatrly->ctime[6]); 362 | 363 | stat->st_atime.microsecond = 0; 364 | stat->st_atime.second = sceNetNtohs(getstatrly->atime[1]); 365 | stat->st_atime.minute = sceNetNtohs(getstatrly->atime[2]); 366 | stat->st_atime.hour = sceNetNtohs(getstatrly->atime[3]); 367 | stat->st_atime.day = sceNetNtohs(getstatrly->atime[4]); 368 | stat->st_atime.month = sceNetNtohs(getstatrly->atime[5]); 369 | stat->st_atime.year = sceNetNtohs(getstatrly->atime[6]); 370 | stat->st_mtime.microsecond = 0; 371 | stat->st_mtime.second = sceNetNtohs(getstatrly->mtime[1]); 372 | stat->st_mtime.minute = sceNetNtohs(getstatrly->mtime[2]); 373 | stat->st_mtime.hour = sceNetNtohs(getstatrly->mtime[3]); 374 | stat->st_mtime.day = sceNetNtohs(getstatrly->mtime[4]); 375 | stat->st_mtime.month = sceNetNtohs(getstatrly->mtime[5]); 376 | stat->st_mtime.year = sceNetNtohs(getstatrly->mtime[6]); 377 | 378 | 379 | 380 | //stat->st_private[] don't know how to fill leave as is 381 | } 382 | return sceNetNtohl(getstatrly->retval); 383 | 384 | } 385 | int psp2LinkIoRename(const char *oldname, const char *newname) 386 | { 387 | psp2link_pkt_rename_req *renamereq; 388 | psp2link_pkt_file_rly *renamerly; 389 | 390 | if (psp2LinkGetValue(REQUESTS_SOCK) < 0) { 391 | return -1; 392 | } 393 | 394 | debugNetPrintf(DEBUG,"[PSP2LINK] file rename req (%s) to (%s)\n", oldname,newname); 395 | 396 | renamereq = (psp2link_pkt_rename_req *)&send_packet[0]; 397 | 398 | // Build packet 399 | renamereq->cmd = sceNetHtonl(PSP2LINK_RENAME_CMD); 400 | renamereq->len = sceNetHtons((unsigned short)sizeof(psp2link_pkt_rename_req)); 401 | strncpy(renamereq->path, oldname, PSP2LINK_MAX_PATH); 402 | renamereq->path[PSP2LINK_MAX_PATH - 1] = 0; // Make sure it's null-terminated 403 | strncpy(renamereq->newpath, newname, PSP2LINK_MAX_PATH); 404 | renamereq->newpath[PSP2LINK_MAX_PATH - 1] = 0; // Make sure it's null-terminated 405 | 406 | if (psp2link_send(psp2LinkGetValue(FILEIO_SOCK), renamereq, sizeof(psp2link_pkt_rename_req), SCE_NET_MSG_DONTWAIT) < 0) { 407 | return -1; 408 | } 409 | 410 | if (!psp2link_accept_pkt(psp2LinkGetValue(FILEIO_SOCK), recv_packet, sizeof(psp2link_pkt_file_rly), PSP2LINK_RENAME_RLY)) { 411 | debugNetPrintf(ERROR,"[PSP2LINK] psp2link_remove: did not receive RENAME_RLY\n"); 412 | return -1; 413 | } 414 | 415 | renamerly = (psp2link_pkt_file_rly *)recv_packet; 416 | debugNetPrintf(DEBUG,"[PSP2LINK] file rename reply received (ret %d)\n", sceNetNtohl(renamerly->retval)); 417 | return sceNetNtohl(renamerly->retval); 418 | } 419 | 420 | int psp2LinkIoGetstatByFd(SceUID fd, SceIoStat *stat) 421 | { 422 | psp2link_pkt_fgetstat_req *getstatreq; 423 | psp2link_pkt_getstat_rly *getstatrly; 424 | 425 | if (psp2LinkGetValue(REQUESTS_SOCK) < 0) { 426 | return -1; 427 | } 428 | 429 | debugNetPrintf(DEBUG,"[PSP2LINK] getstatbyfd req fd=%d \n",fd); 430 | 431 | getstatreq = (psp2link_pkt_fgetstat_req *)&send_packet[0]; 432 | 433 | // Build packet 434 | getstatreq->cmd = sceNetHtonl(PSP2LINK_FGETSTAT_CMD); 435 | getstatreq->len = sceNetHtons((unsigned short)sizeof(psp2link_pkt_fgetstat_req)); 436 | getstatreq->fd = sceNetHtonl(fd); 437 | 438 | if (psp2link_send(psp2LinkGetValue(FILEIO_SOCK), getstatreq, sizeof(psp2link_pkt_fgetstat_req), SCE_NET_MSG_DONTWAIT) < 0) { 439 | return -1; 440 | } 441 | 442 | if (!psp2link_accept_pkt(psp2LinkGetValue(FILEIO_SOCK), recv_packet, sizeof(psp2link_pkt_getstat_rly), PSP2LINK_FGETSTAT_RLY)) { 443 | debugNetPrintf(ERROR,"[PSP2LINK] psp2link_getstat: did not receive GETSTAT_RLY\n"); 444 | return -1; 445 | } 446 | 447 | getstatrly = (psp2link_pkt_getstat_rly *)recv_packet; 448 | 449 | debugNetPrintf(DEBUG,"[PSP2LINK] getstatbyfd reply received (ret %d)\n", sceNetNtohl(getstatrly->retval)); 450 | 451 | if(getstatrly->retval==0) 452 | { 453 | // now handle the return buffer translation, to build reply bit 454 | stat->st_mode = sceNetNtohl(getstatrly->mode); 455 | stat->st_attr = sceNetNtohl(getstatrly->attr); //no attr on pc/mac side ignore 0 is returned 456 | stat->st_size = sceNetNtohl(getstatrly->size); 457 | stat->st_ctime.microsecond = 0; 458 | stat->st_ctime.second = sceNetNtohs(getstatrly->ctime[1]); 459 | stat->st_ctime.minute = sceNetNtohs(getstatrly->ctime[2]); 460 | stat->st_ctime.hour = sceNetNtohs(getstatrly->ctime[3]); 461 | stat->st_ctime.day = sceNetNtohs(getstatrly->ctime[4]); 462 | stat->st_ctime.month = sceNetNtohs(getstatrly->ctime[5]); 463 | stat->st_ctime.year = sceNetNtohs(getstatrly->ctime[6]); 464 | 465 | stat->st_atime.microsecond = 0; 466 | stat->st_atime.second = sceNetNtohs(getstatrly->atime[1]); 467 | stat->st_atime.minute = sceNetNtohs(getstatrly->atime[2]); 468 | stat->st_atime.hour = sceNetNtohs(getstatrly->atime[3]); 469 | stat->st_atime.day = sceNetNtohs(getstatrly->atime[4]); 470 | stat->st_atime.month = sceNetNtohs(getstatrly->atime[5]); 471 | stat->st_atime.year = sceNetNtohs(getstatrly->atime[6]); 472 | stat->st_mtime.microsecond = 0; 473 | stat->st_mtime.second = sceNetNtohs(getstatrly->mtime[1]); 474 | stat->st_mtime.minute = sceNetNtohs(getstatrly->mtime[2]); 475 | stat->st_mtime.hour = sceNetNtohs(getstatrly->mtime[3]); 476 | stat->st_mtime.day = sceNetNtohs(getstatrly->mtime[4]); 477 | stat->st_mtime.month = sceNetNtohs(getstatrly->mtime[5]); 478 | stat->st_mtime.year = sceNetNtohs(getstatrly->mtime[6]); 479 | 480 | 481 | 482 | //stat->st_private[] don't know how to fill leave as is 483 | } 484 | return sceNetNtohl(getstatrly->retval); 485 | 486 | } 487 | 488 | int psp2LinkIoOpen(const char *file, int flags, SceMode mode) 489 | { 490 | psp2link_pkt_open_req *openreq; 491 | psp2link_pkt_file_rly *openrly; 492 | 493 | if (psp2LinkGetValue(FILEIO_SOCK) < 0) { 494 | debugNetPrintf(DEBUG,"[PSP2LINK] file open req (%s, %x) but psp2link_fileio_sock is not active\n", file, flags); 495 | 496 | return -1; 497 | } 498 | 499 | debugNetPrintf(DEBUG,"[PSP2LINK] file open req (%s, %x %x)\n", file, flags, mode); 500 | 501 | openreq = (psp2link_pkt_open_req *)&send_packet[0]; 502 | 503 | // Build packet 504 | openreq->cmd = sceNetHtonl(PSP2LINK_OPEN_CMD); 505 | openreq->len = sceNetHtons((unsigned short)sizeof(psp2link_pkt_open_req)); 506 | openreq->flags = sceNetHtonl(flags); 507 | strncpy(openreq->path, file, PSP2LINK_MAX_PATH); 508 | openreq->path[PSP2LINK_MAX_PATH - 1] = 0; // Make sure it's null-terminated 509 | 510 | if (psp2link_send(psp2LinkGetValue(FILEIO_SOCK), openreq, sizeof(psp2link_pkt_open_req), SCE_NET_MSG_DONTWAIT) < 0) { 511 | return -1; 512 | } 513 | 514 | if (!psp2link_accept_pkt(psp2LinkGetValue(FILEIO_SOCK), recv_packet, sizeof(psp2link_pkt_file_rly), PSP2LINK_OPEN_RLY)) { 515 | debugNetPrintf(ERROR,"[PSP2LINK] psp2link_file: psp2link_open_file: did not receive OPEN_RLY\n"); 516 | return -1; 517 | } 518 | 519 | openrly = (psp2link_pkt_file_rly *)recv_packet; 520 | 521 | debugNetPrintf(DEBUG,"[PSP2LINK] file open reply received (ret %d)\n", sceNetNtohl(openrly->retval)); 522 | 523 | return sceNetNtohl(openrly->retval); 524 | 525 | 526 | } 527 | int psp2LinkIoClose(SceUID fd) 528 | { 529 | 530 | psp2link_pkt_close_req *closereq; 531 | psp2link_pkt_file_rly *closerly; 532 | 533 | 534 | if (psp2LinkGetValue(FILEIO_SOCK) < 0) { 535 | return -1; 536 | } 537 | 538 | debugNetPrintf(DEBUG,"[PSP2LINK] psp2link_file: file close req (fd: %d)\n", fd); 539 | 540 | closereq = (psp2link_pkt_close_req *)&send_packet[0]; 541 | closerly = (psp2link_pkt_file_rly *)&recv_packet[0]; 542 | 543 | closereq->cmd = sceNetHtonl(PSP2LINK_CLOSE_CMD); 544 | closereq->len = sceNetHtons((unsigned short)sizeof(psp2link_pkt_close_req)); 545 | closereq->fd = sceNetHtonl(fd); 546 | 547 | if (psp2link_send(psp2LinkGetValue(FILEIO_SOCK), closereq, sizeof(psp2link_pkt_close_req), SCE_NET_MSG_DONTWAIT) < 0) { 548 | return -1; 549 | } 550 | 551 | if(!psp2link_accept_pkt(psp2LinkGetValue(FILEIO_SOCK), (char *)closerly, sizeof(psp2link_pkt_file_rly), PSP2LINK_CLOSE_RLY)) { 552 | debugNetPrintf(ERROR,"[PSP2LINK] psp2link_close_file: did not receive PSP2LINK_CLOSE_RLY\n"); 553 | return -1; 554 | } 555 | 556 | debugNetPrintf(DEBUG,"[PSP2LINK] psp2link_close_file: close reply received (ret %d)\n", sceNetNtohl(closerly->retval)); 557 | 558 | return sceNetNtohl(closerly->retval); 559 | 560 | 561 | 562 | } 563 | int psp2LinkIoRead(SceUID fd, void *data, SceSize size) 564 | { 565 | int nbytes; 566 | int i; 567 | psp2link_pkt_read_req *readcmd; 568 | psp2link_pkt_read_rly *readrly; 569 | 570 | 571 | if (psp2LinkGetValue(FILEIO_SOCK) < 0) { 572 | return -1; 573 | } 574 | 575 | readcmd = (psp2link_pkt_read_req *)&send_packet[0]; 576 | readrly = (psp2link_pkt_read_rly *)&recv_packet[0]; 577 | 578 | readcmd->cmd = sceNetHtonl(PSP2LINK_READ_CMD); 579 | readcmd->len = sceNetHtons((unsigned short)sizeof(psp2link_pkt_read_req)); 580 | readcmd->fd = sceNetHtonl(fd); 581 | 582 | 583 | if (size < 0) { 584 | debugNetPrintf(ERROR,"[PSP2LINK] psp2link_read_file: illegal req!! (whish to read < 0 bytes!)\n"); 585 | return -1; 586 | } 587 | 588 | readcmd->nbytes = sceNetHtonl(size); 589 | 590 | i = psp2link_send(psp2LinkGetValue(FILEIO_SOCK), readcmd, sizeof(psp2link_pkt_read_req), SCE_NET_MSG_DONTWAIT); 591 | if (i<0) 592 | { 593 | debugNetPrintf(ERROR,"[PSP2LINK] psp2link_file: psp2link_read_file: send failed (%d)\n", i); 594 | return -1; 595 | } 596 | 597 | if(!psp2link_accept_pkt(psp2LinkGetValue(FILEIO_SOCK), (char *)readrly, sizeof(psp2link_pkt_read_rly), PSP2LINK_READ_RLY)) { 598 | debugNetPrintf(ERROR,"[PSP2LINK] psp2link_read_file: " "did not receive PSP2LINK_READ_RLY\n"); 599 | return -1; 600 | } 601 | 602 | nbytes = sceNetNtohl(readrly->nbytes); 603 | debugNetPrintf(DEBUG,"[PSP2LINK] psp2link_read_file: Reply said there's %d bytes to read " "(wanted %d)\n", nbytes, size); 604 | 605 | // Now read the actual file data 606 | i = psp2link_recv_bytes(psp2LinkGetValue(FILEIO_SOCK), &data[0], nbytes); 607 | if (i < 0) { 608 | debugNetPrintf(ERROR,"[PSP2LINK] psp2link_read_file, data read error\n"); 609 | return -1; 610 | } 611 | return nbytes; 612 | } 613 | int psp2LinkIoWrite(SceUID fd, const void *data, SceSize size) 614 | { 615 | psp2link_pkt_write_req *writecmd; 616 | psp2link_pkt_file_rly *writerly; 617 | int hlen; 618 | int writtenbytes; 619 | int nbytes; 620 | int retval; 621 | 622 | if (psp2LinkGetValue(FILEIO_SOCK) < 0) { 623 | return -1; 624 | } 625 | 626 | debugNetPrintf(DEBUG,"[PSP2LINK] file write req (fd: %d)\n", fd); 627 | 628 | writecmd = (psp2link_pkt_write_req *)&send_packet[0]; 629 | writerly = (psp2link_pkt_file_rly *)&recv_packet[0]; 630 | 631 | hlen = (unsigned short)sizeof(psp2link_pkt_write_req); 632 | writecmd->cmd = sceNetHtonl(PSP2LINK_WRITE_CMD); 633 | writecmd->len = sceNetHtons(hlen); 634 | writecmd->fd = sceNetHtonl(fd); 635 | 636 | // Divide the write request 637 | writtenbytes = 0; 638 | while (writtenbytes < size) { 639 | 640 | if ((size - writtenbytes) > PSP2LINK_MAX_WRITE_SEGMENT) { 641 | // Need to split in several read reqs 642 | nbytes = PSP2LINK_MAX_READ_SEGMENT; 643 | } 644 | else 645 | { 646 | nbytes = size - writtenbytes; 647 | } 648 | 649 | writecmd->nbytes = sceNetHtonl(nbytes); 650 | /* Send the packet header. */ 651 | if (psp2link_send(psp2LinkGetValue(FILEIO_SOCK), writecmd, hlen, SCE_NET_MSG_DONTWAIT) < 0) 652 | return -1; 653 | /* Send the write() data. */ 654 | if (psp2link_send(psp2LinkGetValue(FILEIO_SOCK), &data[writtenbytes], nbytes, SCE_NET_MSG_DONTWAIT) < 0) 655 | return -1; 656 | 657 | // Get reply 658 | if(!psp2link_accept_pkt(psp2LinkGetValue(FILEIO_SOCK), (char *)writerly, sizeof(psp2link_pkt_file_rly), PSP2LINK_WRITE_RLY)) { 659 | debugNetPrintf(ERROR,"[PSP2LINK] psp2link_write_file: " "did not receive PSP2LINK_WRITE_RLY\n"); 660 | return -1; 661 | } 662 | retval = sceNetNtohl(writerly->retval); 663 | 664 | debugNetPrintf(DEBUG,"[PSP2LINK] wrote %d bytes (asked for %d)\n", retval, nbytes); 665 | 666 | if (retval < 0) { 667 | // Error 668 | debugNetPrintf(ERROR,"[PSP2LINK] psp2link_write_file: received error on write req (%d)\n",retval); 669 | return retval; 670 | } 671 | 672 | writtenbytes += retval; 673 | if (retval < nbytes) { 674 | // EOF? 675 | break; 676 | } 677 | } 678 | 679 | return writtenbytes; 680 | 681 | 682 | } 683 | int psp2LinkIoLseek(SceUID fd, int offset, int whence) 684 | { 685 | psp2link_pkt_lseek_req *lseekreq; 686 | psp2link_pkt_file_rly *lseekrly; 687 | 688 | 689 | if (psp2LinkGetValue(REQUESTS_SOCK) < 0) { 690 | return -1; 691 | } 692 | 693 | debugNetPrintf(DEBUG,"[PSP2LINK] file lseek req (fd: %d)\n", fd); 694 | 695 | lseekreq = (psp2link_pkt_lseek_req *)&send_packet[0]; 696 | lseekrly = (psp2link_pkt_file_rly *)&recv_packet[0]; 697 | 698 | lseekreq->cmd = sceNetHtonl(PSP2LINK_LSEEK_CMD); 699 | lseekreq->len = sceNetHtons((unsigned short)sizeof(psp2link_pkt_lseek_req)); 700 | lseekreq->fd = sceNetHtonl(fd); 701 | lseekreq->offset = sceNetHtonl(offset); 702 | lseekreq->whence = sceNetHtonl(whence); 703 | 704 | if(psp2link_send(psp2LinkGetValue(FILEIO_SOCK), lseekreq, sizeof(psp2link_pkt_lseek_req), SCE_NET_MSG_DONTWAIT) < 0) { 705 | return -1; 706 | } 707 | 708 | if(!psp2link_accept_pkt(psp2LinkGetValue(FILEIO_SOCK), (char *)lseekrly,sizeof(psp2link_pkt_file_rly), PSP2LINK_LSEEK_RLY)) { 709 | debugNetPrintf(ERROR,"[PSP2LINK] psp2link_lseek_file: did not receive PSP2LINK_LSEEK_RLY\n"); 710 | return -1; 711 | } 712 | 713 | debugNetPrintf(DEBUG,"[PSP2LINK] psp2link_lseek_file: lseek reply received (ret %d)\n",sceNetNtohl(lseekrly->retval)); 714 | 715 | return sceNetNtohl(lseekrly->retval); 716 | 717 | } 718 | int psp2LinkIoRemove(const char *file) 719 | { 720 | psp2link_pkt_remove_req *removereq; 721 | psp2link_pkt_file_rly *removerly; 722 | 723 | if (psp2LinkGetValue(REQUESTS_SOCK) < 0) { 724 | return -1; 725 | } 726 | 727 | debugNetPrintf(DEBUG,"[PSP2LINK] file remove req (%s)\n", file); 728 | 729 | removereq = (psp2link_pkt_remove_req *)&send_packet[0]; 730 | 731 | // Build packet 732 | removereq->cmd = sceNetHtonl(PSP2LINK_REMOVE_CMD); 733 | removereq->len = sceNetHtons((unsigned short)sizeof(psp2link_pkt_remove_req)); 734 | strncpy(removereq->name, file, PSP2LINK_MAX_PATH); 735 | removereq->name[PSP2LINK_MAX_PATH - 1] = 0; // Make sure it's null-terminated 736 | 737 | if (psp2link_send(psp2LinkGetValue(FILEIO_SOCK), removereq, sizeof(psp2link_pkt_remove_req), SCE_NET_MSG_DONTWAIT) < 0) { 738 | return -1; 739 | } 740 | 741 | if (!psp2link_accept_pkt(psp2LinkGetValue(FILEIO_SOCK), recv_packet, sizeof(psp2link_pkt_file_rly), PSP2LINK_REMOVE_RLY)) { 742 | debugNetPrintf(ERROR,"[PSP2LINK] psp2link_remove: did not receive REMOVE_RLY\n"); 743 | return -1; 744 | } 745 | 746 | removerly = (psp2link_pkt_file_rly *)recv_packet; 747 | debugNetPrintf(DEBUG,"[PSP2LINK] file remove reply received (ret %d)\n", sceNetNtohl(removerly->retval)); 748 | return sceNetNtohl(removerly->retval); 749 | } 750 | int psp2LinkIoMkdir(const char *dirname, SceMode mode) 751 | { 752 | psp2link_pkt_mkdir_req *mkdirreq; 753 | psp2link_pkt_file_rly *mkdirrly; 754 | 755 | if (psp2LinkGetValue(REQUESTS_SOCK) < 0) { 756 | return -1; 757 | } 758 | 759 | debugNetPrintf(DEBUG,"[PSP2LINK] make dir req (%s)\n", dirname); 760 | 761 | mkdirreq = (psp2link_pkt_mkdir_req *)&send_packet[0]; 762 | 763 | // Build packet 764 | mkdirreq->cmd = sceNetHtonl(PSP2LINK_MKDIR_CMD); 765 | mkdirreq->len = sceNetHtons((unsigned short)sizeof(psp2link_pkt_mkdir_req)); 766 | mkdirreq->mode = mode; 767 | strncpy(mkdirreq->name, dirname, PSP2LINK_MAX_PATH); 768 | mkdirreq->name[PSP2LINK_MAX_PATH - 1] = 0; // Make sure it's null-terminated 769 | 770 | if (psp2link_send(psp2LinkGetValue(FILEIO_SOCK), mkdirreq, sizeof(psp2link_pkt_mkdir_req), SCE_NET_MSG_DONTWAIT) < 0) { 771 | return -1; 772 | } 773 | 774 | if (!psp2link_accept_pkt(psp2LinkGetValue(FILEIO_SOCK), recv_packet, sizeof(psp2link_pkt_file_rly), PSP2LINK_MKDIR_RLY)) { 775 | debugNetPrintf(ERROR,"[PSP2LINK] psp2link_mkdir: did not receive MKDIR_RLY\n"); 776 | return -1; 777 | } 778 | 779 | mkdirrly = (psp2link_pkt_file_rly *)recv_packet; 780 | debugNetPrintf(DEBUG,"[PSP2LINK] psp2link_file: make dir reply received (ret %d)\n", sceNetNtohl(mkdirrly->retval)); 781 | return sceNetNtohl(mkdirrly->retval); 782 | } 783 | int psp2LinkIoRmdir(const char *dirname) 784 | { 785 | psp2link_pkt_rmdir_req *rmdirreq; 786 | psp2link_pkt_file_rly *rmdirrly; 787 | 788 | if (psp2LinkGetValue(REQUESTS_SOCK) < 0) { 789 | return -1; 790 | } 791 | 792 | debugNetPrintf(DEBUG,"[PSP2LINK] psp2link_file: remove dir req (%s)\n", dirname); 793 | 794 | rmdirreq = (psp2link_pkt_rmdir_req *)&send_packet[0]; 795 | 796 | // Build packet 797 | rmdirreq->cmd = sceNetHtonl(PSP2LINK_RMDIR_CMD); 798 | rmdirreq->len = sceNetHtons((unsigned short)sizeof(psp2link_pkt_rmdir_req)); 799 | strncpy(rmdirreq->name, dirname, PSP2LINK_MAX_PATH); 800 | rmdirreq->name[PSP2LINK_MAX_PATH - 1] = 0; // Make sure it's null-terminated 801 | 802 | if (psp2link_send(psp2LinkGetValue(FILEIO_SOCK), rmdirreq, sizeof(psp2link_pkt_rmdir_req), SCE_NET_MSG_DONTWAIT) < 0) { 803 | return -1; 804 | } 805 | 806 | if (!psp2link_accept_pkt(psp2LinkGetValue(FILEIO_SOCK), recv_packet, sizeof(psp2link_pkt_file_rly), PSP2LINK_RMDIR_RLY)) { 807 | debugNetPrintf(ERROR,"[PSP2LINK] psp2link_file: psp2link_rmdir: did not receive RMDIR_RLY\n"); 808 | return -1; 809 | } 810 | 811 | rmdirrly = (psp2link_pkt_file_rly *)recv_packet; 812 | debugNetPrintf(DEBUG,"[PSP2LINK] psp2link_file: remove dir reply received (ret %d)\n", sceNetNtohl(rmdirrly->retval)); 813 | return sceNetNtohl(rmdirrly->retval); 814 | } 815 | int psp2LinkIoDopen(const char *dirname) 816 | { 817 | psp2link_pkt_open_req *openreq; 818 | psp2link_pkt_file_rly *openrly; 819 | 820 | if (psp2LinkGetValue(REQUESTS_SOCK) < 0) { 821 | return -1; 822 | } 823 | 824 | debugNetPrintf(DEBUG,"[PSP2LINK] dir open req (%s)\n", dirname); 825 | 826 | openreq = (psp2link_pkt_open_req *)&send_packet[0]; 827 | 828 | // Build packet 829 | openreq->cmd = sceNetHtonl(PSP2LINK_OPENDIR_CMD); 830 | openreq->len = sceNetHtons((unsigned short)sizeof(psp2link_pkt_open_req)); 831 | openreq->flags = sceNetHtonl(0); 832 | strncpy(openreq->path, dirname, PSP2LINK_MAX_PATH); 833 | openreq->path[PSP2LINK_MAX_PATH - 1] = 0; // Make sure it's null-terminated 834 | 835 | if (psp2link_send(psp2LinkGetValue(FILEIO_SOCK), openreq, sizeof(psp2link_pkt_open_req), SCE_NET_MSG_DONTWAIT) < 0) { 836 | return -1; 837 | } 838 | 839 | if (!psp2link_accept_pkt(psp2LinkGetValue(FILEIO_SOCK), recv_packet, sizeof(psp2link_pkt_file_rly), PSP2LINK_OPENDIR_RLY)) { 840 | debugNetPrintf(ERROR,"[PSP2LINK] psp2link_open_dir: did not receive OPENDIR_RLY\n"); 841 | return -1; 842 | } 843 | 844 | openrly = (psp2link_pkt_file_rly *)recv_packet; 845 | 846 | debugNetPrintf(DEBUG,"[PSP2LINK] dir open reply received (ret %d)\n", sceNetNtohl(openrly->retval)); 847 | 848 | return sceNetNtohl(openrly->retval); 849 | } 850 | int psp2LinkIoDread(SceUID fd, SceIoDirent *dir) 851 | { 852 | psp2link_pkt_dread_req *dirreq; 853 | psp2link_pkt_dread_rly *dirrly; 854 | SceIoDirent *dirent; 855 | 856 | if (psp2LinkGetValue(REQUESTS_SOCK) < 0) { 857 | return -1; 858 | } 859 | 860 | debugNetPrintf(DEBUG,"[PSP2LINK] dir read req (%d)\n", fd); 861 | 862 | dirreq = (psp2link_pkt_dread_req *)&send_packet[0]; 863 | 864 | // Build packet 865 | dirreq->cmd = sceNetHtonl(PSP2LINK_READDIR_CMD); 866 | dirreq->len = sceNetHtons((unsigned short)sizeof(psp2link_pkt_dread_req)); 867 | dirreq->fd = sceNetHtonl(fd); 868 | 869 | if (psp2link_send(psp2LinkGetValue(FILEIO_SOCK), dirreq, sizeof(psp2link_pkt_dread_req), SCE_NET_MSG_DONTWAIT) < 0) { 870 | return -1; 871 | } 872 | 873 | if (!psp2link_accept_pkt(psp2LinkGetValue(FILEIO_SOCK), recv_packet, sizeof(psp2link_pkt_dread_rly), PSP2LINK_READDIR_RLY)) { 874 | debugNetPrintf(ERROR,"[PSP2LINK] psp2link_read_dir: did not receive OPENDIR_RLY\n"); 875 | return -1; 876 | } 877 | 878 | dirrly = (psp2link_pkt_dread_rly *)recv_packet; 879 | 880 | debugNetPrintf(DEBUG,"[PSP2LINK] dir read reply received (ret %d)\n", sceNetNtohl(dirrly->retval)); 881 | 882 | 883 | dirent = (SceIoDirent *) dir; 884 | // now handle the return buffer translation, to build reply bit 885 | dirent->d_stat.st_mode = sceNetNtohl(dirrly->mode); 886 | dirent->d_stat.st_attr = sceNetNtohl(dirrly->attr); 887 | dirent->d_stat.st_size = sceNetNtohl(dirrly->size); 888 | dirent->d_stat.st_ctime.microsecond = 0; 889 | dirent->d_stat.st_ctime.second = sceNetNtohs(dirrly->ctime[1]); 890 | dirent->d_stat.st_ctime.minute = sceNetNtohs(dirrly->ctime[2]); 891 | dirent->d_stat.st_ctime.hour = sceNetNtohs(dirrly->ctime[3]); 892 | dirent->d_stat.st_ctime.day = sceNetNtohs(dirrly->ctime[4]); 893 | dirent->d_stat.st_ctime.month = sceNetNtohs(dirrly->ctime[5]); 894 | dirent->d_stat.st_ctime.year = sceNetNtohs(dirrly->ctime[6]); 895 | 896 | dirent->d_stat.st_atime.microsecond = 0; 897 | dirent->d_stat.st_atime.second = sceNetNtohs(dirrly->atime[1]); 898 | dirent->d_stat.st_atime.minute = sceNetNtohs(dirrly->atime[2]); 899 | dirent->d_stat.st_atime.hour = sceNetNtohs(dirrly->atime[3]); 900 | dirent->d_stat.st_atime.day = sceNetNtohs(dirrly->atime[4]); 901 | dirent->d_stat.st_atime.month = sceNetNtohs(dirrly->atime[5]); 902 | dirent->d_stat.st_atime.year = sceNetNtohs(dirrly->atime[6]); 903 | dirent->d_stat.st_mtime.microsecond = 0; 904 | dirent->d_stat.st_mtime.second = sceNetNtohs(dirrly->mtime[1]); 905 | dirent->d_stat.st_mtime.minute = sceNetNtohs(dirrly->mtime[2]); 906 | dirent->d_stat.st_mtime.hour = sceNetNtohs(dirrly->mtime[3]); 907 | dirent->d_stat.st_mtime.day = sceNetNtohs(dirrly->mtime[4]); 908 | dirent->d_stat.st_mtime.month = sceNetNtohs(dirrly->mtime[5]); 909 | dirent->d_stat.st_mtime.year = sceNetNtohs(dirrly->mtime[6]); 910 | 911 | 912 | 913 | //dirent->stat.hisize = ntohl(dirrly->hisize); 914 | 915 | 916 | 917 | strncpy(dirent->d_name,dirrly->name,256); 918 | dirent->d_private = 0; 919 | 920 | return sceNetNtohl(dirrly->retval); 921 | } 922 | int psp2LinkIoDclose(SceUID fd) 923 | { 924 | psp2link_pkt_close_req *closereq; 925 | psp2link_pkt_file_rly *closerly; 926 | 927 | 928 | if (psp2LinkGetValue(REQUESTS_SOCK) < 0) { 929 | return -1; 930 | } 931 | 932 | debugNetPrintf(DEBUG,"[PSP2LINK] psp2link_file: dir close req (fd: %d)\n", fd); 933 | 934 | closereq = (psp2link_pkt_close_req *)&send_packet[0]; 935 | closerly = (psp2link_pkt_file_rly *)&recv_packet[0]; 936 | 937 | closereq->cmd = sceNetHtonl(PSP2LINK_CLOSEDIR_CMD); 938 | closereq->len = sceNetHtons((unsigned short)sizeof(psp2link_pkt_close_req)); 939 | closereq->fd = sceNetHtonl(fd); 940 | 941 | if (psp2link_send(psp2LinkGetValue(FILEIO_SOCK), closereq, sizeof(psp2link_pkt_close_req), SCE_NET_MSG_DONTWAIT) < 0) { 942 | return -1; 943 | } 944 | 945 | if(!psp2link_accept_pkt(psp2LinkGetValue(FILEIO_SOCK), (char *)closerly, sizeof(psp2link_pkt_file_rly), PSP2LINK_CLOSEDIR_RLY)) { 946 | debugNetPrintf(ERROR,"[PSP2LINK] psp2link_close_dir: did not receive PSP2LINK_CLOSEDIR_RLY\n"); 947 | return -1; 948 | } 949 | 950 | debugNetPrintf(DEBUG,"[PSP2LINK] dir close reply received (ret %d)\n", sceNetNtohl(closerly->retval)); 951 | 952 | return sceNetNtohl(closerly->retval); 953 | } 954 | int psp2link_requests_thread(SceSize args, void *argp) 955 | { 956 | int ret; 957 | struct SceNetSockaddrIn serveraddr; 958 | /* Create server socket */ 959 | configuration->psp2link_requests_sock = sceNetSocket("requests_server_sock",SCE_NET_AF_INET,SCE_NET_SOCK_STREAM,0); 960 | if(psp2LinkGetValue(REQUESTS_SOCK)>=0) 961 | { 962 | debugNetPrintf(DEBUG,"[PSP2LINK] Created psp2link_requests_sock: %d\n", psp2LinkGetValue(REQUESTS_SOCK)); 963 | 964 | } 965 | memset(&serveraddr, 0, sizeof serveraddr); 966 | 967 | /* Fill the server's address */ 968 | serveraddr.sin_family = SCE_NET_AF_INET; 969 | serveraddr.sin_addr.s_addr = sceNetHtonl(SCE_NET_INADDR_ANY); 970 | serveraddr.sin_port = sceNetHtons(psp2LinkGetValue(REQUESTS_PORT)); 971 | 972 | /* Bind the server's address to the socket */ 973 | ret = sceNetBind(psp2LinkGetValue(REQUESTS_SOCK), (SceNetSockaddr *)&serveraddr, sizeof(serveraddr)); 974 | if(ret<0) 975 | { 976 | debugNetPrintf(ERROR,"[PSP2LINK] sceNetBind error: 0x%08X\n", ret); 977 | sceNetSocketClose(psp2LinkGetValue(REQUESTS_SOCK)); 978 | return -1; 979 | } 980 | /* Start listening */ 981 | ret = sceNetListen(psp2LinkGetValue(REQUESTS_SOCK), 5); 982 | if(ret<0) 983 | { 984 | debugNetPrintf(ERROR,"[PSP2LINK] sceNetListen error: 0x%08X\n", ret); 985 | sceNetSocketClose(psp2LinkGetValue(REQUESTS_SOCK)); 986 | return -1; 987 | } 988 | 989 | 990 | 991 | 992 | while(psp2LinkGetValue(FILEIO_ACTIVE)) 993 | { 994 | debugNetPrintf(INFO,"[PSP2LINK] Waiting for connection\n", ret); 995 | 996 | /* Accept clients */ 997 | SceNetSockaddrIn clientaddr; 998 | int client_sock; 999 | unsigned int addrlen = sizeof(clientaddr); 1000 | client_sock = sceNetAccept(psp2LinkGetValue(REQUESTS_SOCK), (SceNetSockaddr *)&clientaddr, &addrlen); 1001 | if (client_sock < 0) { 1002 | debugNetPrintf(ERROR,"[PSP2LINK] sceNetAccept error (%d)", client_sock); 1003 | continue; 1004 | } 1005 | 1006 | /* Get the client's IP address */ 1007 | remote_pc_addr = clientaddr.sin_addr.s_addr; 1008 | char remote_ip[16]; 1009 | sceNetInetNtop(SCE_NET_AF_INET,&clientaddr.sin_addr.s_addr,remote_ip,sizeof(remote_ip)); 1010 | debugNetPrintf(INFO,"[PSP2LINK] Client connected from %s port: %i\n ",remote_ip, clientaddr.sin_port); 1011 | if (psp2LinkGetValue(REQUESTS_SOCK) > 0) { 1012 | debugNetPrintf(ERROR,"[PSP2LINK] Client reconnected\n"); 1013 | // sceNetSocketClose(psp2LinkGetValue(REQUESTS_SOCK)); 1014 | } 1015 | 1016 | configuration->psp2link_fileio_sock = client_sock; 1017 | psp2link_requests_connected=1; 1018 | 1019 | debugNetPrintf(INFO,"[PSP2LINK] sock psp2link_fileio set %d connected %d\n",psp2LinkGetValue(FILEIO_SOCK),psp2link_requests_connected); 1020 | 1021 | 1022 | } 1023 | debugNetPrintf(INFO,"[PSP2LINK] exit thread requests\n"); 1024 | if(psp2LinkGetValue(FILEIO_SOCK)) 1025 | { 1026 | debugNetPrintf(DEBUG,"[PSP2LINK] closing fileio_sock\n"); 1027 | sceNetSocketClose(psp2LinkGetValue(FILEIO_SOCK)); 1028 | configuration->psp2link_fileio_sock=-1; 1029 | } 1030 | if(psp2LinkGetValue(REQUESTS_SOCK)) 1031 | { 1032 | debugNetPrintf(DEBUG,"[PSP2LINK] closing server_request_sock\n"); 1033 | sceNetSocketClose(psp2LinkGetValue(REQUESTS_SOCK)); 1034 | configuration->psp2link_requests_sock=-1; 1035 | } 1036 | 1037 | 1038 | psp2link_requests_connected=0; 1039 | 1040 | 1041 | sceKernelExitDeleteThread(0); 1042 | return 0; 1043 | } 1044 | -------------------------------------------------------------------------------- /sample/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2015 Antonio Jose Ramos Marquez aka bigboss (@psxdev) 3 | # 4 | 5 | TARGET := psp2linksample 6 | 7 | OBJS= main.o font.o font_data.o file_chooser.o 8 | LIBS=-lvita2d -lSceKernel_stub -lSceDisplay_stub -lSceGxm_stub \ 9 | -lSceSysmodule_stub -ldebugnet -lpsp2link -lSceNet_stub -lSceNetCtl_stub -lSceCtrl_stub -lScePgf_stub \ 10 | -lSceCommonDialog_stub -lpng -ljpeg -lfreetype -lz -lm -lc 11 | 12 | PREFIX = arm-vita-eabi 13 | CC = $(PREFIX)-gcc 14 | CFLAGS = -Wl,-q -Wall -O3 15 | ASFLAGS = $(CFLAGS) 16 | 17 | all: $(TARGET).velf 18 | 19 | %.velf: %.elf 20 | $(PREFIX)-strip -g $< 21 | vita-elf-create $< $@ 22 | 23 | $(TARGET).elf: $(OBJS) 24 | $(CC) $(CFLAGS) $^ $(LIBS) -o $@ 25 | 26 | clean: 27 | @rm -rf $(TARGET).velf $(TARGET).elf $(OBJS) 28 | 29 | 30 | copy: 31 | cp $(TARGET).velf /usr/local/vitadev/rejuvenate/homebrew.elf 32 | -------------------------------------------------------------------------------- /sample/file_chooser.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include "font.h" 14 | #include "file_chooser.h" 15 | 16 | 17 | #define SCREEN_W 960 18 | #define SCREEN_H 544 19 | #define LIST_MAX_ONSCREEN ((SCREEN_H-40)/20) 20 | 21 | #define min(a,b) ((a) < (b) ? (a) : (b)) 22 | #define max(a,b) ((a) > (b) ? (a) : (b)) 23 | 24 | #define WHITE RGBA8(255, 255, 255, 255) 25 | #define GREEN RGBA8(0, 255, 0 , 255) 26 | 27 | typedef struct file_list_entry { 28 | char name[PATH_MAX]; 29 | int is_dir; 30 | int supported; 31 | struct file_list_entry *next; 32 | } file_list_entry; 33 | 34 | typedef struct file_list { 35 | file_list_entry *head; 36 | int length; 37 | int scroll; 38 | } file_list; 39 | 40 | 41 | static void file_list_add_entry(file_list *list, file_list_entry *entry) 42 | { 43 | if (list->head == NULL) { 44 | list->head = entry; 45 | entry->next = NULL; 46 | } else { 47 | file_list_entry *tmp = list->head; 48 | list->head = entry; 49 | entry->next = tmp; 50 | } 51 | list->length++; 52 | } 53 | 54 | static void file_list_empty(file_list *list) 55 | { 56 | file_list_entry *p = list->head; 57 | file_list_entry *q; 58 | while (p) { 59 | q = p->next; 60 | free(p); 61 | p = q; 62 | } 63 | memset(list, 0, sizeof(*list)); 64 | } 65 | 66 | static int file_supported(const char *filename, const char *supported_ext[]) 67 | { 68 | int i; 69 | const char *ext = strrchr(filename, '.'); 70 | if (ext) { 71 | i = 0; 72 | while (supported_ext[i]) { 73 | if (strcmp(ext + 1, supported_ext[i]) == 0) { 74 | return 1; 75 | } 76 | i++; 77 | } 78 | } 79 | return 0; 80 | } 81 | 82 | static int file_list_build(const char *path, file_list *list, const char *supported_ext[]) 83 | { 84 | SceUID dir; 85 | SceIoDirent dirent; 86 | 87 | //dir = sceIoDopen(path); 88 | dir = psp2LinkIoDopen(path); 89 | 90 | if (dir < 0) { 91 | return 0; 92 | } 93 | 94 | memset(&dirent, 0, sizeof(dirent)); 95 | memset(list, 0, sizeof(*list)); 96 | 97 | while (psp2LinkIoDread(dir, &dirent) > 0) { 98 | 99 | file_list_entry *entry = (file_list_entry *)malloc(sizeof(*entry)); 100 | 101 | strcpy(entry->name, dirent.d_name); 102 | entry->is_dir = SCE_S_ISDIR(dirent.d_stat.st_mode); 103 | if (!entry->is_dir) { 104 | entry->supported = file_supported(entry->name, supported_ext); 105 | } 106 | 107 | file_list_add_entry(list, entry); 108 | 109 | memset(&dirent, 0, sizeof(dirent)); 110 | } 111 | 112 | psp2LinkIoDclose(dir); 113 | 114 | //file_list_entry *up = (file_list_entry *)malloc(sizeof(*up)); 115 | //strcpy(up->name, ".."); 116 | //up->is_dir = 1; 117 | //up->next = NULL; 118 | //file_list_add_entry(list, up); 119 | 120 | return 0; 121 | } 122 | 123 | static file_list_entry *file_list_get_nth_entry(const file_list *list, int n) 124 | { 125 | file_list_entry *entry = list->head; 126 | while (n--) { 127 | entry = entry->next; 128 | } 129 | return entry; 130 | } 131 | 132 | static void dir_up(char *path) 133 | { 134 | size_t len_in = strlen(path); 135 | char *pch = strrchr(path, '/'); 136 | if (pch) { 137 | size_t s = len_in - (pch - path); 138 | memset(pch, '\0', s); 139 | } 140 | if (strcmp(path, "host0:/") < 0) { 141 | strcpy(path, "host0:/"); 142 | } 143 | } 144 | 145 | int file_choose(const char *start_path, char *chosen_file, const char *title, const char *supported_ext[]) 146 | { 147 | SceCtrlData pad, old_pad; 148 | unsigned int keys_down; 149 | int i; 150 | int selected = 0; 151 | char cur_path[PATH_MAX]; 152 | 153 | pad.buttons = old_pad.buttons = 0; 154 | 155 | strcpy(cur_path, start_path); 156 | 157 | file_list list; 158 | file_list_entry *entry; 159 | 160 | file_list_build(cur_path, &list, supported_ext); 161 | 162 | while (1) { 163 | sceCtrlPeekBufferPositive(0, &pad, 1); 164 | if (pad.buttons & SCE_CTRL_SELECT) break; 165 | keys_down = pad.buttons & ~old_pad.buttons; 166 | 167 | if (keys_down & SCE_CTRL_UP) { 168 | selected--; 169 | if (selected < list.scroll) { 170 | list.scroll--; 171 | } 172 | if (selected < 0) { 173 | selected = list.length - 1; 174 | list.scroll = max(0, list.length - LIST_MAX_ONSCREEN); 175 | } 176 | } else if (keys_down & SCE_CTRL_DOWN) { 177 | selected++; 178 | if (selected == list.scroll + LIST_MAX_ONSCREEN) { 179 | list.scroll++; 180 | } 181 | if (selected == list.length) { 182 | selected = 0; 183 | list.scroll = 0; 184 | } 185 | } 186 | 187 | if (keys_down & (SCE_CTRL_CROSS | SCE_CTRL_START)) { 188 | file_list_entry *entry = file_list_get_nth_entry(&list, selected); 189 | 190 | if (entry->is_dir) { 191 | if (strcmp(entry->name, "..") == 0) { 192 | dir_up(cur_path); 193 | } else { 194 | char new_path[PATH_MAX]; 195 | // no valid elf with new toolchain with sprintf(new_path, "%s/%s", cur_path, entry->name); 196 | sceClibSnprintf(new_path, PATH_MAX, "%s/%s", cur_path, entry->name); 197 | strcpy(cur_path, new_path); 198 | } 199 | file_list_empty(&list); 200 | file_list_build(cur_path, &list, supported_ext); 201 | selected = 0; 202 | } else if (entry->supported) { 203 | // no valid elf with new toolchain with sprintfsprintf(chosen_file, "%s/%s", cur_path, entry->name); 204 | sceClibSnprintf(chosen_file,PATH_MAX, "%s/%s", cur_path, entry->name); 205 | 206 | file_list_empty(&list); 207 | return 1; 208 | } 209 | } else if (keys_down & SCE_CTRL_CIRCLE) { 210 | dir_up(cur_path); 211 | file_list_empty(&list); 212 | file_list_build(cur_path, &list, supported_ext); 213 | selected = 0; 214 | } 215 | 216 | 217 | vita2d_start_drawing(); 218 | vita2d_clear_screen(); 219 | 220 | font_draw_stringf(10, 10, WHITE, title); 221 | 222 | entry = file_list_get_nth_entry(&list, list.scroll); 223 | for (i = list.scroll; i < min(list.length, list.scroll + LIST_MAX_ONSCREEN); i++) { 224 | 225 | font_draw_stringf( 226 | 10, 227 | 40 + (i - list.scroll)*20, 228 | (!entry->is_dir && entry->supported) ? GREEN : WHITE, 229 | "%s %s", 230 | (selected == i) ? ">" : "", 231 | entry->name); 232 | 233 | entry = entry->next; 234 | } 235 | 236 | old_pad = pad; 237 | vita2d_end_drawing(); 238 | vita2d_swap_buffers(); 239 | } 240 | 241 | return 0; 242 | } -------------------------------------------------------------------------------- /sample/file_chooser.h: -------------------------------------------------------------------------------- 1 | #ifndef FILE_CHOOSER_H 2 | #define FILE_CHOOSER_H 3 | 4 | int file_choose(const char *start_path, char *chosen_file, const char *title, const char *supported_ext[]); 5 | 6 | #endif -------------------------------------------------------------------------------- /sample/font.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Sergi Granell (xerpi) 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include "font.h" 9 | 10 | extern const unsigned char msx_font[]; 11 | 12 | void font_draw_char(int x, int y, unsigned int color, char c) 13 | { 14 | unsigned char *font = (unsigned char *)(msx_font + (c - (unsigned int)' ') * 8); 15 | int i, j, pos_x, pos_y; 16 | for (i = 0; i < 8; ++i) { 17 | pos_y = y + i*2; 18 | for (j = 0; j < 8; ++j) { 19 | pos_x = x + j*2; 20 | if ((*font & (128 >> j))) { 21 | vita2d_draw_rectangle(pos_x, pos_y, 2, 2, color); 22 | } 23 | } 24 | ++font; 25 | } 26 | } 27 | 28 | void font_draw_string(int x, int y, unsigned int color, const char *string) 29 | { 30 | if (string == NULL) return; 31 | 32 | int startx = x; 33 | const char *s = string; 34 | 35 | while (*s) { 36 | if (*s == '\n') { 37 | x = startx; 38 | y += 16; 39 | } else if (*s == ' ') { 40 | x += 16; 41 | } else if(*s == '\t') { 42 | x += 16*4; 43 | } else { 44 | font_draw_char(x, y, color, *s); 45 | x += 16; 46 | } 47 | ++s; 48 | } 49 | } 50 | 51 | void font_draw_stringf(int x, int y, unsigned int color, const char *s, ...) 52 | { 53 | char buf[256]; 54 | va_list argptr; 55 | va_start(argptr, s); 56 | //invalid elf with new toolchain with vsnprintf(buf, sizeof(buf), s, argptr); 57 | sceClibVsnprintf(buf, sizeof(buf), s, argptr); 58 | va_end(argptr); 59 | font_draw_string(x, y, color, buf); 60 | } -------------------------------------------------------------------------------- /sample/font.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Sergi Granell (xerpi) 3 | */ 4 | 5 | #ifndef FONT_H 6 | #define FONT_H 7 | 8 | #include 9 | 10 | void font_draw_char(int x, int y, unsigned int color, char c); 11 | void font_draw_string(int x, int y, unsigned int color, const char *string); 12 | void font_draw_stringf(int x, int y, unsigned int color, const char *s, ...); 13 | 14 | #endif -------------------------------------------------------------------------------- /sample/font_data.c: -------------------------------------------------------------------------------- 1 | /* 2 | * PSP Software Development Kit - http://www.pspdev.org 3 | * ----------------------------------------------------------------------- 4 | * Licensed under the BSD license, see LICENSE in PSPSDK root for details. 5 | * 6 | * font.c - Debug Font. 7 | * 8 | * Copyright (c) 2005 Marcus R. Brown 9 | * Copyright (c) 2005 James Forshaw 10 | * Copyright (c) 2005 John Kelley 11 | * 12 | * $Id: font.c 540 2005-07-08 19:35:10Z warren $ 13 | */ 14 | 15 | const unsigned char msx_font[] __attribute((aligned(4))) = 16 | /*"\x00\x00\x00\x00\x00\x00\x00\x00\x3c\x42\xa5\x81\xa5\x99\x42\x3c" 17 | "\x3c\x7e\xdb\xff\xff\xdb\x66\x3c\x6c\xfe\xfe\xfe\x7c\x38\x10\x00" 18 | "\x10\x38\x7c\xfe\x7c\x38\x10\x00\x10\x38\x54\xfe\x54\x10\x38\x00" 19 | "\x10\x38\x7c\xfe\xfe\x10\x38\x00\x00\x00\x00\x30\x30\x00\x00\x00" 20 | "\xff\xff\xff\xe7\xe7\xff\xff\xff\x38\x44\x82\x82\x82\x44\x38\x00" 21 | "\xc7\xbb\x7d\x7d\x7d\xbb\xc7\xff\x0f\x03\x05\x79\x88\x88\x88\x70" 22 | "\x38\x44\x44\x44\x38\x10\x7c\x10\x30\x28\x24\x24\x28\x20\xe0\xc0" 23 | "\x3c\x24\x3c\x24\x24\xe4\xdc\x18\x10\x54\x38\xee\x38\x54\x10\x00" 24 | "\x10\x10\x10\x7c\x10\x10\x10\x10\x10\x10\x10\xff\x00\x00\x00\x00" 25 | "\x00\x00\x00\xff\x10\x10\x10\x10\x10\x10\x10\xf0\x10\x10\x10\x10" 26 | "\x10\x10\x10\x1f\x10\x10\x10\x10\x10\x10\x10\xff\x10\x10\x10\x10" 27 | "\x10\x10\x10\x10\x10\x10\x10\x10\x00\x00\x00\xff\x00\x00\x00\x00" 28 | "\x00\x00\x00\x1f\x10\x10\x10\x10\x00\x00\x00\xf0\x10\x10\x10\x10" 29 | "\x10\x10\x10\x1f\x00\x00\x00\x00\x10\x10\x10\xf0\x00\x00\x00\x00" 30 | "\x81\x42\x24\x18\x18\x24\x42\x81\x01\x02\x04\x08\x10\x20\x40\x80" 31 | "\x80\x40\x20\x10\x08\x04\x02\x01\x00\x10\x10\xff\x10\x10\x00\x00"*/ 32 | "\x00\x00\x00\x00\x00\x00\x00\x00\x20\x20\x20\x20\x00\x00\x20\x00" 33 | "\x50\x50\x50\x00\x00\x00\x00\x00\x50\x50\xf8\x50\xf8\x50\x50\x00" 34 | "\x20\x78\xa0\x70\x28\xf0\x20\x00\xc0\xc8\x10\x20\x40\x98\x18\x00" 35 | "\x40\xa0\x40\xa8\x90\x98\x60\x00\x10\x20\x40\x00\x00\x00\x00\x00" 36 | "\x10\x20\x40\x40\x40\x20\x10\x00\x40\x20\x10\x10\x10\x20\x40\x00" 37 | "\x20\xa8\x70\x20\x70\xa8\x20\x00\x00\x20\x20\xf8\x20\x20\x00\x00" 38 | "\x00\x00\x00\x00\x00\x20\x20\x40\x00\x00\x00\x78\x00\x00\x00\x00" 39 | "\x00\x00\x00\x00\x00\x60\x60\x00\x00\x00\x08\x10\x20\x40\x80\x00" 40 | "\x70\x88\x98\xa8\xc8\x88\x70\x00\x20\x60\xa0\x20\x20\x20\xf8\x00" 41 | "\x70\x88\x08\x10\x60\x80\xf8\x00\x70\x88\x08\x30\x08\x88\x70\x00" 42 | "\x10\x30\x50\x90\xf8\x10\x10\x00\xf8\x80\xe0\x10\x08\x10\xe0\x00" 43 | "\x30\x40\x80\xf0\x88\x88\x70\x00\xf8\x88\x10\x20\x20\x20\x20\x00" 44 | "\x70\x88\x88\x70\x88\x88\x70\x00\x70\x88\x88\x78\x08\x10\x60\x00" 45 | "\x00\x00\x20\x00\x00\x20\x00\x00\x00\x00\x20\x00\x00\x20\x20\x40" 46 | "\x18\x30\x60\xc0\x60\x30\x18\x00\x00\x00\xf8\x00\xf8\x00\x00\x00" 47 | "\xc0\x60\x30\x18\x30\x60\xc0\x00\x70\x88\x08\x10\x20\x00\x20\x00" 48 | "\x70\x88\x08\x68\xa8\xa8\x70\x00\x20\x50\x88\x88\xf8\x88\x88\x00" 49 | "\xf0\x48\x48\x70\x48\x48\xf0\x00\x30\x48\x80\x80\x80\x48\x30\x00" 50 | "\xe0\x50\x48\x48\x48\x50\xe0\x00\xf8\x80\x80\xf0\x80\x80\xf8\x00" 51 | "\xf8\x80\x80\xf0\x80\x80\x80\x00\x70\x88\x80\xb8\x88\x88\x70\x00" 52 | "\x88\x88\x88\xf8\x88\x88\x88\x00\x70\x20\x20\x20\x20\x20\x70\x00" 53 | "\x38\x10\x10\x10\x90\x90\x60\x00\x88\x90\xa0\xc0\xa0\x90\x88\x00" 54 | "\x80\x80\x80\x80\x80\x80\xf8\x00\x88\xd8\xa8\xa8\x88\x88\x88\x00" 55 | "\x88\xc8\xc8\xa8\x98\x98\x88\x00\x70\x88\x88\x88\x88\x88\x70\x00" 56 | "\xf0\x88\x88\xf0\x80\x80\x80\x00\x70\x88\x88\x88\xa8\x90\x68\x00" 57 | "\xf0\x88\x88\xf0\xa0\x90\x88\x00\x70\x88\x80\x70\x08\x88\x70\x00" 58 | "\xf8\x20\x20\x20\x20\x20\x20\x00\x88\x88\x88\x88\x88\x88\x70\x00" 59 | "\x88\x88\x88\x88\x50\x50\x20\x00\x88\x88\x88\xa8\xa8\xd8\x88\x00" 60 | "\x88\x88\x50\x20\x50\x88\x88\x00\x88\x88\x88\x70\x20\x20\x20\x00" 61 | "\xf8\x08\x10\x20\x40\x80\xf8\x00\x70\x40\x40\x40\x40\x40\x70\x00" 62 | "\x00\x00\x80\x40\x20\x10\x08\x00\x70\x10\x10\x10\x10\x10\x70\x00" 63 | "\x20\x50\x88\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8\x00" 64 | "\x40\x20\x10\x00\x00\x00\x00\x00\x00\x00\x70\x08\x78\x88\x78\x00" 65 | "\x80\x80\xb0\xc8\x88\xc8\xb0\x00\x00\x00\x70\x88\x80\x88\x70\x00" 66 | "\x08\x08\x68\x98\x88\x98\x68\x00\x00\x00\x70\x88\xf8\x80\x70\x00" 67 | "\x10\x28\x20\xf8\x20\x20\x20\x00\x00\x00\x68\x98\x98\x68\x08\x70" 68 | "\x80\x80\xf0\x88\x88\x88\x88\x00\x20\x00\x60\x20\x20\x20\x70\x00" 69 | "\x10\x00\x30\x10\x10\x10\x90\x60\x40\x40\x48\x50\x60\x50\x48\x00" 70 | "\x60\x20\x20\x20\x20\x20\x70\x00\x00\x00\xd0\xa8\xa8\xa8\xa8\x00" 71 | "\x00\x00\xb0\xc8\x88\x88\x88\x00\x00\x00\x70\x88\x88\x88\x70\x00" 72 | "\x00\x00\xb0\xc8\xc8\xb0\x80\x80\x00\x00\x68\x98\x98\x68\x08\x08" 73 | "\x00\x00\xb0\xc8\x80\x80\x80\x00\x00\x00\x78\x80\xf0\x08\xf0\x00" 74 | "\x40\x40\xf0\x40\x40\x48\x30\x00\x00\x00\x90\x90\x90\x90\x68\x00" 75 | "\x00\x00\x88\x88\x88\x50\x20\x00\x00\x00\x88\xa8\xa8\xa8\x50\x00" 76 | "\x00\x00\x88\x50\x20\x50\x88\x00\x00\x00\x88\x88\x98\x68\x08\x70" 77 | "\x00\x00\xf8\x10\x20\x40\xf8\x00\x18\x20\x20\x40\x20\x20\x18\x00" 78 | "\x20\x20\x20\x00\x20\x20\x20\x00\xc0\x20\x20\x10\x20\x20\xc0\x00" 79 | "\x40\xa8\x10\x00\x00\x00\x00\x00\x00\x00\x20\x50\xf8\x00\x00\x00" 80 | "\x70\x88\x80\x80\x88\x70\x20\x60\x90\x00\x00\x90\x90\x90\x68\x00" 81 | /*"\x10\x20\x70\x88\xf8\x80\x70\x00\x20\x50\x70\x08\x78\x88\x78\x00" 82 | "\x48\x00\x70\x08\x78\x88\x78\x00\x20\x10\x70\x08\x78\x88\x78\x00" 83 | "\x20\x00\x70\x08\x78\x88\x78\x00\x00\x70\x80\x80\x80\x70\x10\x60" 84 | "\x20\x50\x70\x88\xf8\x80\x70\x00\x50\x00\x70\x88\xf8\x80\x70\x00" 85 | "\x20\x10\x70\x88\xf8\x80\x70\x00\x50\x00\x00\x60\x20\x20\x70\x00" 86 | "\x20\x50\x00\x60\x20\x20\x70\x00\x40\x20\x00\x60\x20\x20\x70\x00" 87 | "\x50\x00\x20\x50\x88\xf8\x88\x00\x20\x00\x20\x50\x88\xf8\x88\x00" 88 | "\x10\x20\xf8\x80\xf0\x80\xf8\x00\x00\x00\x6c\x12\x7e\x90\x6e\x00" 89 | "\x3e\x50\x90\x9c\xf0\x90\x9e\x00\x60\x90\x00\x60\x90\x90\x60\x00" 90 | "\x90\x00\x00\x60\x90\x90\x60\x00\x40\x20\x00\x60\x90\x90\x60\x00" 91 | "\x40\xa0\x00\xa0\xa0\xa0\x50\x00\x40\x20\x00\xa0\xa0\xa0\x50\x00" 92 | "\x90\x00\x90\x90\xb0\x50\x10\xe0\x50\x00\x70\x88\x88\x88\x70\x00" 93 | "\x50\x00\x88\x88\x88\x88\x70\x00\x20\x20\x78\x80\x80\x78\x20\x20" 94 | "\x18\x24\x20\xf8\x20\xe2\x5c\x00\x88\x50\x20\xf8\x20\xf8\x20\x00" 95 | "\xc0\xa0\xa0\xc8\x9c\x88\x88\x8c\x18\x20\x20\xf8\x20\x20\x20\x40" 96 | "\x10\x20\x70\x08\x78\x88\x78\x00\x10\x20\x00\x60\x20\x20\x70\x00" 97 | "\x20\x40\x00\x60\x90\x90\x60\x00\x20\x40\x00\x90\x90\x90\x68\x00" 98 | "\x50\xa0\x00\xa0\xd0\x90\x90\x00\x28\x50\x00\xc8\xa8\x98\x88\x00" 99 | "\x00\x70\x08\x78\x88\x78\x00\xf8\x00\x60\x90\x90\x90\x60\x00\xf0" 100 | "\x20\x00\x20\x40\x80\x88\x70\x00\x00\x00\x00\xf8\x80\x80\x00\x00" 101 | "\x00\x00\x00\xf8\x08\x08\x00\x00\x84\x88\x90\xa8\x54\x84\x08\x1c" 102 | "\x84\x88\x90\xa8\x58\xa8\x3c\x08\x20\x00\x00\x20\x20\x20\x20\x00" 103 | "\x00\x00\x24\x48\x90\x48\x24\x00\x00\x00\x90\x48\x24\x48\x90\x00" 104 | "\x28\x50\x20\x50\x88\xf8\x88\x00\x28\x50\x70\x08\x78\x88\x78\x00" 105 | "\x28\x50\x00\x70\x20\x20\x70\x00\x28\x50\x00\x20\x20\x20\x70\x00" 106 | "\x28\x50\x00\x70\x88\x88\x70\x00\x50\xa0\x00\x60\x90\x90\x60\x00" 107 | "\x28\x50\x00\x88\x88\x88\x70\x00\x50\xa0\x00\xa0\xa0\xa0\x50\x00" 108 | "\xfc\x48\x48\x48\xe8\x08\x50\x20\x00\x50\x00\x50\x50\x50\x10\x20" 109 | "\xc0\x44\xc8\x54\xec\x54\x9e\x04\x10\xa8\x40\x00\x00\x00\x00\x00" 110 | "\x00\x20\x50\x88\x50\x20\x00\x00\x88\x10\x20\x40\x80\x28\x00\x00" 111 | "\x7c\xa8\xa8\x68\x28\x28\x28\x00\x38\x40\x30\x48\x48\x30\x08\x70" 112 | "\x00\x00\x00\x00\x00\x00\xff\xff\xf0\xf0\xf0\xf0\x0f\x0f\x0f\x0f" 113 | "\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00" 114 | "\x00\x00\x00\x3c\x3c\x00\x00\x00\xff\xff\xff\xff\xff\xff\x00\x00" 115 | "\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\x0f\x0f\x0f\x0f\xf0\xf0\xf0\xf0" 116 | "\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\x03\x03\x03\x03\x03\x03\x03\x03" 117 | "\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x11\x22\x44\x88\x11\x22\x44\x88" 118 | "\x88\x44\x22\x11\x88\x44\x22\x11\xfe\x7c\x38\x10\x00\x00\x00\x00" 119 | "\x00\x00\x00\x00\x10\x38\x7c\xfe\x80\xc0\xe0\xf0\xe0\xc0\x80\x00" 120 | "\x01\x03\x07\x0f\x07\x03\x01\x00\xff\x7e\x3c\x18\x18\x3c\x7e\xff" 121 | "\x81\xc3\xe7\xff\xff\xe7\xc3\x81\xf0\xf0\xf0\xf0\x00\x00\x00\x00" 122 | "\x00\x00\x00\x00\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x00\x00\x00\x00" 123 | "\x00\x00\x00\x00\xf0\xf0\xf0\xf0\x33\x33\xcc\xcc\x33\x33\xcc\xcc" 124 | "\x00\x20\x20\x50\x50\x88\xf8\x00\x20\x20\x70\x20\x70\x20\x20\x00" 125 | "\x00\x00\x00\x50\x88\xa8\x50\x00\xff\xff\xff\xff\xff\xff\xff\xff" 126 | "\x00\x00\x00\x00\xff\xff\xff\xff\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0" 127 | "\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\xff\xff\xff\xff\x00\x00\x00\x00" 128 | "\x00\x00\x68\x90\x90\x90\x68\x00\x30\x48\x48\x70\x48\x48\x70\xc0" 129 | "\xf8\x88\x80\x80\x80\x80\x80\x00\xf8\x50\x50\x50\x50\x50\x98\x00" 130 | "\xf8\x88\x40\x20\x40\x88\xf8\x00\x00\x00\x78\x90\x90\x90\x60\x00" 131 | "\x00\x50\x50\x50\x50\x68\x80\x80\x00\x50\xa0\x20\x20\x20\x20\x00" 132 | "\xf8\x20\x70\xa8\xa8\x70\x20\xf8\x20\x50\x88\xf8\x88\x50\x20\x00" 133 | "\x70\x88\x88\x88\x50\x50\xd8\x00\x30\x40\x40\x20\x50\x50\x50\x20" 134 | "\x00\x00\x00\x50\xa8\xa8\x50\x00\x08\x70\xa8\xa8\xa8\x70\x80\x00" 135 | "\x38\x40\x80\xf8\x80\x40\x38\x00\x70\x88\x88\x88\x88\x88\x88\x00" 136 | "\x00\xf8\x00\xf8\x00\xf8\x00\x00\x20\x20\xf8\x20\x20\x00\xf8\x00" 137 | "\xc0\x30\x08\x30\xc0\x00\xf8\x00\x18\x60\x80\x60\x18\x00\xf8\x00" 138 | "\x10\x28\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\xa0\x40" 139 | "\x00\x20\x00\xf8\x00\x20\x00\x00\x00\x50\xa0\x00\x50\xa0\x00\x00" 140 | "\x00\x18\x24\x24\x18\x00\x00\x00\x00\x30\x78\x78\x30\x00\x00\x00" 141 | "\x00\x00\x00\x00\x30\x00\x00\x00\x3e\x20\x20\x20\xa0\x60\x20\x00" 142 | "\xa0\x50\x50\x50\x00\x00\x00\x00\x40\xa0\x20\x40\xe0\x00\x00\x00" 143 | "\x00\x38\x38\x38\x38\x38\x38\x00\x00\x00\x00\x00\x00\x00\x00"*/; -------------------------------------------------------------------------------- /sample/logo.h: -------------------------------------------------------------------------------- 1 | //png image with psp2link text font from http://www.fontspace.com/nal/the-rave-is-in-your-pants 2 | 3 | static const unsigned char psp2link_png[] = { 4 | 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 5 | 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x02, 0x20, 6 | 0x08, 0x06, 0x00, 0x00, 0x00, 0x4a, 0xe5, 0x00, 0xad, 0x00, 0x00, 0x00, 7 | 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xa0, 8 | 0xbd, 0xa7, 0x93, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 9 | 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 10 | 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdf, 0x08, 0x0c, 11 | 0x12, 0x00, 0x36, 0x85, 0x02, 0x12, 0xa4, 0x00, 0x00, 0x1e, 0x1d, 0x49, 12 | 0x44, 0x41, 0x54, 0x78, 0xda, 0xed, 0xdd, 0x7d, 0x6c, 0x95, 0xe5, 0xdd, 13 | 0xc0, 0xf1, 0x5f, 0x4b, 0x4b, 0x6d, 0x81, 0x29, 0x8a, 0x2c, 0xa0, 0x4e, 14 | 0x26, 0xae, 0x2a, 0x22, 0x75, 0x4c, 0x13, 0xa5, 0xc5, 0x89, 0x9a, 0x89, 15 | 0x4e, 0x66, 0x64, 0x5b, 0x74, 0x2e, 0x63, 0x66, 0xd3, 0x28, 0xa2, 0x61, 16 | 0x71, 0xc6, 0x31, 0x8d, 0x9b, 0xc1, 0x4d, 0x14, 0x6b, 0x83, 0xf5, 0x0d, 17 | 0x5c, 0x36, 0xf7, 0x12, 0xdf, 0x62, 0x36, 0x33, 0x5d, 0x44, 0x1c, 0x2a, 18 | 0x63, 0x42, 0x18, 0x88, 0x32, 0x5f, 0xd0, 0x5a, 0x45, 0x94, 0x37, 0x65, 19 | 0xa0, 0x54, 0xa1, 0x50, 0xda, 0x72, 0x3d, 0x7f, 0x3c, 0x63, 0xcf, 0xb6, 20 | 0x47, 0xe8, 0x69, 0x6d, 0xcb, 0x79, 0xf9, 0x7c, 0x92, 0xdf, 0x7f, 0xe7, 21 | 0x94, 0x9e, 0xab, 0xd7, 0xb9, 0x7b, 0x7f, 0x39, 0xe7, 0xdc, 0x2d, 0x8a, 22 | 0x88, 0x14, 0x00, 0x00, 0x00, 0x90, 0xe7, 0x8a, 0x2d, 0x01, 0x00, 0x00, 23 | 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x08, 24 | 0x60, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x20, 0x80, 0x01, 25 | 0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 26 | 0x00, 0x01, 0x0c, 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 27 | 0x0c, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 28 | 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 29 | 0x20, 0x80, 0x01, 0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 0x80, 0x00, 30 | 0x06, 0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 31 | 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 32 | 0x04, 0x30, 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 0x10, 0xc0, 33 | 0x00, 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 34 | 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 0x80, 35 | 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x18, 36 | 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 37 | 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 0x10, 38 | 0xc0, 0x00, 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 0x40, 0x00, 0x03, 39 | 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 40 | 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x08, 41 | 0x60, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 42 | 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 43 | 0x40, 0x00, 0x03, 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 44 | 0x0c, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 45 | 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 46 | 0x08, 0x60, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x20, 0x80, 47 | 0x01, 0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 48 | 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 49 | 0x04, 0x30, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x04, 0x30, 50 | 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 51 | 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 0x80, 52 | 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x18, 53 | 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 54 | 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 0x10, 55 | 0xc0, 0x00, 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 0x40, 0x00, 0x03, 56 | 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 57 | 0x80, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 58 | 0x18, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 59 | 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 60 | 0x40, 0x00, 0x03, 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 0x40, 0x00, 61 | 0x03, 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 62 | 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 63 | 0x08, 0x60, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x20, 0x80, 64 | 0x01, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 65 | 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 0x00, 66 | 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x04, 0x30, 67 | 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 68 | 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x20, 69 | 0x80, 0x01, 0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 0x80, 0x00, 0x06, 70 | 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 71 | 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 0x04, 72 | 0x30, 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 73 | 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 74 | 0x80, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 75 | 0x18, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 76 | 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 77 | 0x10, 0xc0, 0x00, 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 0x40, 0x00, 78 | 0x03, 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 79 | 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 80 | 0x02, 0x18, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x08, 0x60, 81 | 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 82 | 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 0x00, 83 | 0x01, 0x0c, 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x0c, 84 | 0x00, 0x00, 0x00, 0xb9, 0xa8, 0xc4, 0x12, 0xc0, 0x9e, 0xa5, 0x94, 0xf2, 85 | 0xee, 0x31, 0xed, 0xda, 0xb5, 0x2b, 0x5a, 0x5a, 0x5a, 0xa2, 0xb9, 0xb9, 86 | 0x39, 0xfe, 0xf1, 0x8f, 0x7f, 0xc4, 0xfa, 0xf5, 0xeb, 0xe3, 0x8d, 0x37, 87 | 0xde, 0x88, 0x17, 0x5f, 0x7c, 0x31, 0x16, 0x2d, 0x5a, 0x14, 0xaf, 0xbe, 88 | 0xfa, 0x6a, 0x41, 0xfc, 0x6c, 0x47, 0x8f, 0x1e, 0x1d, 0x63, 0xc6, 0x8c, 89 | 0x89, 0xaa, 0xaa, 0xaa, 0xa8, 0xac, 0xac, 0x8c, 0x21, 0x43, 0x86, 0xc4, 90 | 0xa0, 0x41, 0x83, 0xa2, 0xbc, 0xbc, 0x3c, 0xfa, 0xf6, 0xed, 0x1b, 0xc5, 91 | 0xc5, 0xbd, 0xf3, 0xff, 0x83, 0x45, 0x45, 0x45, 0xf6, 0x5f, 0x37, 0xee, 92 | 0x3f, 0x6b, 0xd6, 0x33, 0x6b, 0xb6, 0x63, 0xc7, 0x8e, 0x28, 0x2f, 0x2f, 93 | 0x77, 0xfc, 0xef, 0xe4, 0xba, 0x54, 0x54, 0x54, 0xc4, 0xcf, 0x7e, 0xf6, 94 | 0xb3, 0x38, 0xef, 0xbc, 0xf3, 0x62, 0xf0, 0xe0, 0xc1, 0xb1, 0x78, 0xf1, 95 | 0xe2, 0xa8, 0xad, 0xad, 0x8d, 0x79, 0xf3, 0xe6, 0xe5, 0xfd, 0xfa, 0x6d, 96 | 0xdf, 0xbe, 0x3d, 0xf6, 0xdb, 0x6f, 0xbf, 0x1e, 0x3f, 0x06, 0xe6, 0xdb, 97 | 0xde, 0xac, 0xa8, 0xa8, 0x88, 0xda, 0xda, 0xda, 0x98, 0x3c, 0x79, 0xf2, 98 | 0x5e, 0x6f, 0xd7, 0xd4, 0xd4, 0x14, 0x53, 0xa7, 0x4e, 0x8d, 0xdf, 0xfc, 99 | 0xe6, 0x37, 0x4e, 0xd6, 0xa0, 0x2b, 0xc7, 0x78, 0x63, 0xcc, 0x27, 0x4f, 100 | 0x21, 0x5a, 0xb5, 0x6a, 0x55, 0xba, 0xf1, 0xc6, 0x1b, 0xd3, 0xd0, 0xa1, 101 | 0x43, 0xf3, 0xee, 0xe7, 0x39, 0x6c, 0xd8, 0xb0, 0x74, 0xeb, 0xad, 0xb7, 102 | 0xa6, 0xb5, 0x6b, 0xd7, 0x66, 0xcd, 0x7a, 0xdb, 0x7f, 0xdd, 0xbb, 0xff, 103 | 0xac, 0x59, 0xcf, 0xac, 0xd9, 0xf6, 0xed, 0xdb, 0x1d, 0xff, 0xbb, 0xb0, 104 | 0x2e, 0x75, 0x75, 0x75, 0x9f, 0x78, 0xbf, 0xc7, 0x1f, 0x7f, 0x3c, 0x1d, 105 | 0x7e, 0xf8, 0xe1, 0x79, 0xbd, 0x7e, 0xdb, 0xb7, 0x6f, 0xef, 0x95, 0x63, 106 | 0x60, 0x3e, 0xed, 0xcd, 0x93, 0x4f, 0x3e, 0x39, 0x35, 0x36, 0x36, 0x76, 107 | 0xf8, 0x98, 0x9f, 0x7e, 0xfa, 0xe9, 0x74, 0xd8, 0x61, 0x87, 0x39, 0x4f, 108 | 0x33, 0xa6, 0xeb, 0x63, 0x11, 0x8c, 0x71, 0x32, 0xfd, 0xff, 0x35, 0x37, 109 | 0x37, 0xa7, 0x19, 0x33, 0x66, 0xa4, 0xb2, 0xb2, 0xb2, 0x9c, 0xff, 0x39, 110 | 0xf6, 0xeb, 0xd7, 0x2f, 0xcd, 0x9a, 0x35, 0x2b, 0xed, 0xdc, 0xb9, 0x33, 111 | 0xeb, 0xd6, 0xd9, 0xfe, 0xeb, 0xde, 0xfd, 0x67, 0xcd, 0x7a, 0x66, 0xcd, 112 | 0x04, 0x70, 0xd7, 0xd6, 0x65, 0xf5, 0xea, 0xd5, 0x7b, 0xbc, 0xef, 0xc7, 113 | 0x1f, 0x7f, 0x9c, 0xae, 0xba, 0xea, 0xaa, 0x54, 0x5c, 0x5c, 0x2c, 0x80, 114 | 0x0b, 0x7c, 0x6f, 0x96, 0x96, 0x96, 0xa6, 0x9b, 0x6e, 0xba, 0x29, 0xb5, 115 | 0xb6, 0xb6, 0x76, 0xf8, 0x1c, 0x9f, 0x3a, 0x75, 0xaa, 0xf3, 0x33, 0x63, 116 | 0x04, 0xb0, 0x31, 0x02, 0xb8, 0x27, 0xbd, 0xfc, 0xf2, 0xcb, 0xe9, 0x73, 117 | 0x9f, 0xfb, 0x5c, 0xce, 0xfe, 0x0c, 0x8f, 0x3c, 0xf2, 0xc8, 0xd4, 0xd0, 118 | 0xd0, 0x90, 0xb5, 0xeb, 0x6b, 0xff, 0x75, 0xef, 0xfe, 0xa3, 0x67, 0xd6, 119 | 0x4c, 0x00, 0x77, 0x6d, 0x5d, 0xda, 0xda, 0xda, 0x3a, 0xfc, 0x1a, 0x2f, 120 | 0xbc, 0xf0, 0x42, 0x3a, 0xe1, 0x84, 0x13, 0x04, 0x70, 0x81, 0xee, 0xcd, 121 | 0xe3, 0x8e, 0x3b, 0x2e, 0xad, 0x58, 0xb1, 0xa2, 0xc3, 0xc7, 0xb9, 0x74, 122 | 0xe9, 0xd2, 0x74, 0xd4, 0x51, 0x47, 0x39, 0x37, 0x33, 0xa6, 0x1b, 0xc6, 123 | 0x45, 0xb0, 0x80, 0xbd, 0x1a, 0x39, 0x72, 0x64, 0x3c, 0xf7, 0xdc, 0x73, 124 | 0x31, 0x74, 0xe8, 0xd0, 0x9c, 0xfb, 0xde, 0x87, 0x0d, 0x1b, 0x16, 0x7f, 125 | 0xfd, 0xeb, 0x5f, 0xa3, 0xb2, 0xb2, 0xd2, 0x0f, 0xd2, 0xfe, 0xb3, 0x66, 126 | 0xf4, 0xba, 0x3e, 0x7d, 0xfa, 0x74, 0x78, 0x9b, 0x2f, 0x7e, 0xf1, 0x8b, 127 | 0xb1, 0x64, 0xc9, 0x92, 0x98, 0x35, 0x6b, 0x56, 0xf4, 0xef, 0xdf, 0xdf, 128 | 0xa2, 0x15, 0x88, 0xa2, 0xa2, 0xa2, 0xb8, 0xe6, 0x9a, 0x6b, 0x62, 0xd9, 129 | 0xb2, 0x65, 0x51, 0x55, 0x55, 0xb5, 0xc7, 0xdb, 0xb5, 0xb6, 0xb6, 0xc6, 130 | 0x0d, 0x37, 0xdc, 0x10, 0x27, 0x9f, 0x7c, 0x72, 0x34, 0x34, 0x34, 0x58, 131 | 0x38, 0xe8, 0x8e, 0xe7, 0xdf, 0x3f, 0x4b, 0x18, 0xf8, 0x04, 0xf9, 0x78, 132 | 0x41, 0x9d, 0xae, 0x5a, 0xb2, 0x64, 0x49, 0x54, 0x57, 0x57, 0xc7, 0xae, 133 | 0x5d, 0xbb, 0x72, 0xe2, 0xfb, 0x2d, 0x29, 0x29, 0x89, 0x65, 0xcb, 0x96, 134 | 0xc5, 0xf1, 0xc7, 0x1f, 0x9f, 0xf5, 0x27, 0x41, 0xf6, 0x5f, 0xf7, 0xed, 135 | 0x3f, 0x6b, 0xd6, 0x33, 0x6b, 0xe6, 0x22, 0x58, 0x5d, 0x5b, 0x97, 0xce, 136 | 0xee, 0xc7, 0x35, 0x6b, 0xd6, 0xc4, 0x15, 0x57, 0x5c, 0x11, 0x8f, 0x3d, 137 | 0xf6, 0x58, 0xce, 0xaf, 0x9f, 0x8b, 0x60, 0xed, 0xd9, 0x11, 0x47, 0x1c, 138 | 0x11, 0xbf, 0xfd, 0xed, 0x6f, 0xa3, 0xba, 0xba, 0x7a, 0xaf, 0xb7, 0x5b, 139 | 0xb9, 0x72, 0x65, 0x4c, 0x9a, 0x34, 0x29, 0x96, 0x2f, 0x5f, 0xee, 0x80, 140 | 0x06, 0x02, 0x18, 0x7a, 0xc7, 0xdc, 0xb9, 0x73, 0xf3, 0xee, 0x31, 0x95, 141 | 0x94, 0x94, 0xc4, 0x01, 0x07, 0x1c, 0x10, 0x47, 0x1d, 0x75, 0x54, 0x0c, 142 | 0x18, 0x30, 0xa0, 0x53, 0xf7, 0xbd, 0xfc, 0xf2, 0xcb, 0xe3, 0x9e, 0x7b, 143 | 0xee, 0xc9, 0x89, 0xc7, 0xf9, 0xc3, 0x1f, 0xfe, 0x30, 0x6a, 0x6b, 0x6b, 144 | 0x3b, 0x75, 0x9f, 0x2d, 0x5b, 0xb6, 0x44, 0x63, 0x63, 0x63, 0x6c, 0xd9, 145 | 0xb2, 0x25, 0xda, 0xdb, 0xdb, 0x7b, 0xe5, 0xfb, 0x3c, 0xeb, 0xac, 0xb3, 146 | 0xec, 0xbf, 0x6e, 0xdc, 0x7f, 0xd6, 0xac, 0xf3, 0x6b, 0x26, 0x80, 0xb3, 147 | 0x27, 0x80, 0x77, 0xfb, 0xc3, 0x1f, 0xfe, 0x10, 0x57, 0x5e, 0x79, 0x65, 148 | 0xac, 0x5f, 0xbf, 0x5e, 0x00, 0xe7, 0xd9, 0xde, 0xbc, 0xf4, 0xd2, 0x4b, 149 | 0xa3, 0xb6, 0xb6, 0x76, 0xaf, 0xaf, 0xf6, 0xef, 0xda, 0xb5, 0x2b, 0xea, 150 | 0xeb, 0xeb, 0x63, 0xda, 0xb4, 0x69, 0xd1, 0xd2, 0xd2, 0xe2, 0x64, 0x0c, 151 | 0x7a, 0xe2, 0x18, 0x6f, 0x8c, 0x29, 0xc0, 0xcf, 0x3f, 0x14, 0x17, 0xa7, 152 | 0x71, 0xe3, 0xc6, 0xa5, 0x05, 0x0b, 0x16, 0x64, 0xfc, 0xd9, 0xc2, 0x77, 153 | 0xdf, 0x7d, 0x37, 0x27, 0x2e, 0xd8, 0x52, 0x52, 0x52, 0x92, 0x36, 0x6c, 154 | 0xd8, 0x90, 0xf1, 0xe3, 0x9a, 0x37, 0x6f, 0x5e, 0xaa, 0xae, 0xae, 0x4e, 155 | 0x45, 0x45, 0x45, 0xf6, 0x86, 0xfd, 0x57, 0x70, 0x6b, 0xe6, 0x33, 0xc0, 156 | 0x3d, 0xb7, 0x2e, 0x9f, 0x46, 0x53, 0x53, 0x53, 0x9a, 0x32, 0x65, 0x4a, 157 | 0xce, 0x1e, 0x97, 0x7c, 0x06, 0xf8, 0x3f, 0x67, 0xc8, 0x90, 0x21, 0xe9, 158 | 0x89, 0x27, 0x9e, 0xe8, 0xf0, 0xf1, 0xac, 0x5e, 0xbd, 0x3a, 0x9d, 0x7a, 159 | 0xea, 0xa9, 0x7e, 0x4f, 0x18, 0xe3, 0x22, 0x58, 0xc6, 0x98, 0x9e, 0x9a, 160 | 0xa2, 0xa2, 0xa2, 0x34, 0x67, 0xce, 0x9c, 0x8c, 0x4f, 0xca, 0x4e, 0x3b, 161 | 0xed, 0xb4, 0xac, 0x7f, 0x4c, 0x67, 0x9f, 0x7d, 0x76, 0xc6, 0x8f, 0xe7, 162 | 0xf6, 0xdb, 0x6f, 0xb7, 0x0f, 0xec, 0xbf, 0x82, 0x5e, 0x33, 0x01, 0x9c, 163 | 0x9d, 0x01, 0xbc, 0xdb, 0x92, 0x25, 0x4b, 0xd2, 0xa8, 0x51, 0xa3, 0x04, 164 | 0x70, 0x0e, 0xef, 0xcd, 0xf3, 0xcf, 0x3f, 0x3f, 0x6d, 0xda, 0xb4, 0xa9, 165 | 0xc3, 0xc7, 0x72, 0xdf, 0x7d, 0xf7, 0xa5, 0x01, 0x03, 0x06, 0xf8, 0xdd, 166 | 0x60, 0x8c, 0x00, 0x36, 0xc6, 0xf4, 0xc6, 0x2b, 0xa6, 0xaf, 0xbf, 0xfe, 167 | 0x7a, 0x46, 0x27, 0x1b, 0x37, 0xdf, 0x7c, 0x73, 0xd6, 0x3f, 0x9e, 0x59, 168 | 0xb3, 0x66, 0x65, 0xf4, 0x58, 0x5e, 0x7a, 0xe9, 0xa5, 0x82, 0x7e, 0x45, 169 | 0xd1, 0xfe, 0xb3, 0x66, 0x02, 0x38, 0xfb, 0x03, 0x38, 0xa5, 0x94, 0x76, 170 | 0xee, 0xdc, 0x99, 0x6e, 0xb9, 0xe5, 0x96, 0x54, 0x5e, 0x5e, 0x2e, 0x80, 171 | 0x73, 0x68, 0x6f, 0x0e, 0x1c, 0x38, 0x30, 0x3d, 0xf8, 0xe0, 0x83, 0x1d, 172 | 0x3e, 0x86, 0xf7, 0xde, 0x7b, 0x2f, 0x7d, 0xed, 0x6b, 0x5f, 0x73, 0x6c, 173 | 0x33, 0xc6, 0x55, 0xa0, 0x81, 0xde, 0xd2, 0xd6, 0xd6, 0x16, 0x77, 0xdd, 174 | 0x75, 0x57, 0x46, 0xb7, 0x3d, 0xe1, 0x84, 0x13, 0xb2, 0xfe, 0xf1, 0x7c, 175 | 0xe9, 0x4b, 0x5f, 0xca, 0xe8, 0x76, 0x77, 0xde, 0x79, 0x67, 0xce, 0x5c, 176 | 0xd4, 0xcb, 0xfe, 0xcb, 0x9d, 0xfd, 0x67, 0xcd, 0xe8, 0x6e, 0xa5, 0xa5, 177 | 0xa5, 0x71, 0xcd, 0x35, 0xd7, 0xc4, 0xab, 0xaf, 0xbe, 0x1a, 0x67, 0x9e, 178 | 0x79, 0xa6, 0x05, 0xc9, 0x01, 0xe3, 0xc7, 0x8f, 0x8f, 0x97, 0x5f, 0x7e, 179 | 0x39, 0x2e, 0xb8, 0xe0, 0x82, 0xbd, 0xde, 0xee, 0xd1, 0x47, 0x1f, 0x8d, 180 | 0x91, 0x23, 0x47, 0xe6, 0xc5, 0x85, 0xcf, 0x20, 0x57, 0x08, 0x60, 0x20, 181 | 0x22, 0x22, 0x16, 0x2c, 0x58, 0x90, 0xd1, 0xed, 0x86, 0x0d, 0x1b, 0x96, 182 | 0xf5, 0x8f, 0xe5, 0xf3, 0x9f, 0xff, 0x7c, 0x46, 0xb7, 0x7b, 0xf6, 0xd9, 183 | 0x67, 0xfd, 0xe0, 0xed, 0x3f, 0x6b, 0xc6, 0x3e, 0x57, 0x5f, 0x5f, 0x1f, 184 | 0xb7, 0xdd, 0x76, 0x5b, 0xec, 0xdc, 0xb9, 0xb3, 0xc3, 0x63, 0xdb, 0x93, 185 | 0x4f, 0x3e, 0x19, 0x0f, 0x3c, 0xf0, 0x40, 0x0c, 0x1e, 0x3c, 0xd8, 0xc2, 186 | 0x65, 0xa1, 0x8a, 0x8a, 0x8a, 0xb8, 0xe7, 0x9e, 0x7b, 0x62, 0xee, 0xdc, 187 | 0xb9, 0x71, 0xc8, 0x21, 0x87, 0xec, 0xf1, 0x76, 0x4d, 0x4d, 0x4d, 0xf1, 188 | 0xdd, 0xef, 0x7e, 0x37, 0x26, 0x4e, 0x9c, 0x18, 0x9b, 0x36, 0x6d, 0xb2, 189 | 0x70, 0xd0, 0xcb, 0xbc, 0x14, 0x6e, 0x8c, 0x49, 0x9f, 0xf9, 0xcc, 0x67, 190 | 0x32, 0x7a, 0xbb, 0xd9, 0xe6, 0xcd, 0x9b, 0xb3, 0xfe, 0xb1, 0x34, 0x37, 191 | 0x37, 0x67, 0xf4, 0x58, 0xfa, 0xf6, 0xed, 0xeb, 0x67, 0x6f, 0xff, 0x15, 192 | 0xfc, 0x9a, 0x79, 0x0b, 0xf4, 0xbe, 0x7f, 0x0b, 0x74, 0xff, 0xfe, 0xfd, 193 | 0x53, 0x44, 0xa4, 0x63, 0x8e, 0x39, 0x26, 0x3d, 0xfb, 0xec, 0xb3, 0x19, 194 | 0xdd, 0xe7, 0x83, 0x0f, 0x3e, 0x48, 0x17, 0x5f, 0x7c, 0xb1, 0xb7, 0x40, 195 | 0x67, 0xd1, 0xde, 0x1c, 0x33, 0x66, 0x4c, 0x6a, 0x6c, 0x6c, 0xec, 0xf0, 196 | 0x7b, 0x9e, 0x3f, 0x7f, 0x7e, 0x3a, 0xec, 0xb0, 0xc3, 0x1c, 0xc7, 0x8c, 197 | 0xf1, 0x16, 0x68, 0x60, 0x5f, 0x6a, 0x6e, 0x6e, 0xce, 0xe8, 0x76, 0x65, 198 | 0x65, 0x65, 0x59, 0xff, 0x58, 0x32, 0xf9, 0x93, 0x18, 0x2d, 0x2d, 0x2d, 199 | 0x1d, 0xbe, 0xda, 0x82, 0xfd, 0x67, 0xcd, 0xe8, 0x69, 0x2d, 0x2d, 0x2d, 200 | 0xb1, 0x75, 0xeb, 0xd6, 0x88, 0x88, 0x78, 0xed, 0xb5, 0xd7, 0x62, 0xdc, 201 | 0xb8, 0x71, 0x31, 0x69, 0xd2, 0xa4, 0x78, 0xff, 0xfd, 0xf7, 0xf7, 0x7a, 202 | 0xbf, 0x81, 0x03, 0x07, 0xc6, 0x2f, 0x7e, 0xf1, 0x8b, 0x58, 0xb8, 0x70, 203 | 0x61, 0x1c, 0x73, 0xcc, 0x31, 0x16, 0x72, 0x1f, 0x2a, 0x2d, 0x2d, 0x8d, 204 | 0x19, 0x33, 0x66, 0xc4, 0xc2, 0x85, 0x0b, 0xe3, 0xc8, 0x23, 0x8f, 0xdc, 205 | 0xeb, 0x73, 0x76, 0xea, 0xd4, 0xa9, 0x71, 0xc6, 0x19, 0x67, 0xc4, 0x9a, 206 | 0x35, 0x6b, 0x2c, 0x1c, 0xec, 0x23, 0x02, 0x18, 0x88, 0x88, 0x88, 0xfd, 207 | 0xf7, 0xdf, 0xbf, 0x5b, 0x4f, 0xba, 0xb3, 0x5d, 0x57, 0xff, 0x3e, 0x27, 208 | 0xf6, 0x9f, 0x35, 0xa3, 0xa7, 0x8f, 0x45, 0xbf, 0xfb, 0xdd, 0xef, 0xe2, 209 | 0xe8, 0xa3, 0x8f, 0x8e, 0xd9, 0xb3, 0x67, 0x77, 0xf8, 0x37, 0xc9, 0xc7, 210 | 0x8e, 0x1d, 0x1b, 0x2f, 0xbe, 0xf8, 0x62, 0x4c, 0x9f, 0x3e, 0xdd, 0x7f, 211 | 0x76, 0xec, 0x03, 0xa3, 0x46, 0x8d, 0x8a, 0xe7, 0x9f, 0x7f, 0x3e, 0xa6, 212 | 0x4d, 0x9b, 0x16, 0x7d, 0xfa, 0xf4, 0xd9, 0xe3, 0xed, 0x96, 0x2e, 0x5d, 213 | 0x1a, 0xa3, 0x47, 0x8f, 0x8e, 0xfa, 0xfa, 0x7a, 0x8b, 0x06, 0x02, 0x18, 214 | 0xc8, 0x06, 0x23, 0x46, 0x8c, 0xc8, 0xe8, 0x76, 0x1b, 0x37, 0x6e, 0xb4, 215 | 0x58, 0xd8, 0x7f, 0xd6, 0x8c, 0x1e, 0xb6, 0x65, 0xcb, 0x96, 0x98, 0x3c, 216 | 0x79, 0x72, 0x8c, 0x19, 0x33, 0x26, 0x5e, 0x78, 0xe1, 0x85, 0xbd, 0xde, 217 | 0xb6, 0xac, 0xac, 0x2c, 0xae, 0xbf, 0xfe, 0xfa, 0x78, 0xe9, 0xa5, 0x97, 218 | 0x62, 0xdc, 0xb8, 0x71, 0x16, 0xaf, 0x37, 0x4e, 0xa0, 0x8b, 0x8b, 0x63, 219 | 0xda, 0xb4, 0x69, 0xb1, 0x74, 0xe9, 0xd2, 0x18, 0x35, 0x6a, 0xd4, 0x1e, 220 | 0x6f, 0xd7, 0xda, 0xda, 0x1a, 0x3f, 0xfd, 0xe9, 0x4f, 0x63, 0xcc, 0x98, 221 | 0x31, 0xd1, 0xd0, 0xd0, 0x60, 0xe1, 0x40, 0x00, 0x03, 0xd9, 0xe2, 0xec, 222 | 0xb3, 0xcf, 0xce, 0xe8, 0x76, 0x6f, 0xbe, 0xf9, 0xa6, 0xc5, 0xc2, 0xfe, 223 | 0xb3, 0x66, 0xf4, 0x92, 0xa5, 0x4b, 0x97, 0xc6, 0x89, 0x27, 0x9e, 0x18, 224 | 0x53, 0xa7, 0x4e, 0x8d, 0xa6, 0xa6, 0xa6, 0xbd, 0xde, 0xb6, 0xb2, 0xb2, 225 | 0x32, 0x9e, 0x79, 0xe6, 0x99, 0xb8, 0xef, 0xbe, 0xfb, 0xe2, 0xa0, 0x83, 226 | 0x0e, 0xb2, 0x78, 0x3d, 0x64, 0xf8, 0xf0, 0xe1, 0xb1, 0x70, 0xe1, 0xc2, 227 | 0x98, 0x31, 0x63, 0xc6, 0x5e, 0x5f, 0x75, 0x5f, 0xb9, 0x72, 0x65, 0x9c, 228 | 0x74, 0xd2, 0x49, 0x31, 0x7d, 0xfa, 0xf4, 0x0e, 0x5f, 0xc9, 0x07, 0x7a, 229 | 0x97, 0x0f, 0x43, 0x1b, 0x53, 0xe0, 0x33, 0x64, 0xc8, 0x90, 0xf4, 0xc1, 230 | 0x07, 0x1f, 0x64, 0x74, 0xc1, 0x91, 0x1f, 0xfd, 0xe8, 0x47, 0x05, 0x71, 231 | 0xf1, 0x1a, 0x63, 0xff, 0x15, 0xca, 0x9a, 0x79, 0xbe, 0xec, 0xdb, 0x8b, 232 | 0x60, 0x75, 0x66, 0x6d, 0x87, 0x0c, 0x19, 0x92, 0x1e, 0x7a, 0xe8, 0xa1, 233 | 0x8c, 0xbe, 0xee, 0xc6, 0x8d, 0x1b, 0xd3, 0xa4, 0x49, 0x93, 0x5c, 0x04, 234 | 0xab, 0x9b, 0xe7, 0xb2, 0xcb, 0x2e, 0x4b, 0x1f, 0x7f, 0xfc, 0xf1, 0x5e, 235 | 0xbf, 0xa7, 0xf6, 0xf6, 0xf6, 0x54, 0x57, 0x57, 0x97, 0xca, 0xca, 0xca, 236 | 0x1c, 0xaf, 0x8c, 0xc9, 0xce, 0xb1, 0x08, 0xc6, 0x14, 0xfa, 0x89, 0xf4, 237 | 0xb2, 0x65, 0xcb, 0x32, 0xbe, 0x5a, 0xe9, 0x88, 0x11, 0x23, 0x04, 0xb0, 238 | 0xb1, 0xff, 0xf2, 0x68, 0xcd, 0x3c, 0x5f, 0x72, 0x27, 0x80, 0x77, 0xcf, 239 | 0x19, 0x67, 0x9c, 0x91, 0x1a, 0x1a, 0x1a, 0x32, 0xfa, 0xfa, 0xf3, 0xe7, 240 | 0xcf, 0x4f, 0x47, 0x1e, 0x79, 0xa4, 0x00, 0xee, 0x86, 0xe7, 0xdd, 0xdc, 241 | 0xb9, 0x73, 0x3b, 0xfc, 0x7e, 0xde, 0x7e, 0xfb, 0xed, 0xf4, 0xe5, 0x2f, 242 | 0x7f, 0xd9, 0xf1, 0xdd, 0x18, 0x01, 0x6c, 0x8c, 0xc9, 0x96, 0x29, 0x2e, 243 | 0x2e, 0x4e, 0x07, 0x1e, 0x78, 0x60, 0xaa, 0xa9, 0xa9, 0x49, 0x33, 0x66, 244 | 0xcc, 0xc8, 0xf8, 0x55, 0xa4, 0x94, 0x52, 0x5a, 0xbc, 0x78, 0x71, 0xc1, 245 | 0x9c, 0xb8, 0x1a, 0xfb, 0xaf, 0x50, 0xd6, 0xcc, 0xf3, 0x25, 0xf7, 0x02, 246 | 0x38, 0x22, 0x52, 0xdf, 0xbe, 0x7d, 0xd3, 0x4f, 0x7e, 0xf2, 0x93, 0x8c, 247 | 0xfe, 0xec, 0x5b, 0x73, 0x73, 0x73, 0xba, 0xee, 0xba, 0xeb, 0x52, 0x69, 248 | 0x69, 0xa9, 0x00, 0xee, 0xc2, 0x5c, 0x70, 0xc1, 0x05, 0x69, 0xf3, 0xe6, 249 | 0xcd, 0x1d, 0x7e, 0x2f, 0xbf, 0xfa, 0xd5, 0xaf, 0xd2, 0x80, 0x01, 0x03, 250 | 0x1c, 0xeb, 0x8d, 0xc9, 0xf2, 0x29, 0xda, 0x5d, 0xc1, 0x40, 0xd7, 0x1c, 251 | 0x7b, 0xec, 0xb1, 0x51, 0x53, 0x53, 0x13, 0xc7, 0x1f, 0x7f, 0x7c, 0x54, 252 | 0x56, 0x56, 0xc6, 0xd0, 0xa1, 0x43, 0xe3, 0xe0, 0x83, 0x0f, 0x8e, 0x8a, 253 | 0x8a, 0x8a, 0x28, 0x2b, 0x2b, 0x8b, 0xe2, 0xe2, 0xfc, 0xf9, 0xa8, 0xfd, 254 | 0xe9, 0xa7, 0x9f, 0x1e, 0xcf, 0x3c, 0xf3, 0x4c, 0xf6, 0x7f, 0xae, 0x23, 255 | 0x83, 0x2b, 0x3c, 0xef, 0xd8, 0xb1, 0x23, 0xa3, 0x3f, 0x97, 0x64, 0xff, 256 | 0xe5, 0xdf, 0xfe, 0xb3, 0x66, 0x85, 0xfb, 0x7c, 0xe9, 0xed, 0xe3, 0x48, 257 | 0x6f, 0xac, 0xed, 0xf0, 0xe1, 0xc3, 0xe3, 0xce, 0x3b, 0xef, 0x8c, 0xf1, 258 | 0xe3, 0xc7, 0x77, 0x78, 0xdb, 0x95, 0x2b, 0x57, 0xc6, 0xe4, 0xc9, 0x93, 259 | 0x63, 0xe1, 0xc2, 0x85, 0x3d, 0xbe, 0x7e, 0xdb, 0xb7, 0x6f, 0x8f, 0xfd, 260 | 0xf6, 0xdb, 0xaf, 0xc3, 0xdb, 0x15, 0x15, 0x15, 0x65, 0xed, 0xde, 0x1c, 261 | 0x38, 0x70, 0x60, 0xdc, 0x73, 0xcf, 0x3d, 0x71, 0xfe, 0xf9, 0xe7, 0xef, 262 | 0xf5, 0x76, 0xef, 0xbf, 0xff, 0x7e, 0x5c, 0x72, 0xc9, 0x25, 0xf1, 0xf8, 263 | 0xe3, 0x8f, 0x3b, 0x29, 0x82, 0x5c, 0x39, 0xc6, 0x1b, 0x63, 0x3a, 0x37, 264 | 0x43, 0x87, 0x0e, 0x4d, 0x37, 0xde, 0x78, 0x63, 0x5a, 0xb5, 0x6a, 0x55, 265 | 0x2a, 0x14, 0xb3, 0x67, 0xcf, 0x2e, 0xa8, 0x57, 0x6e, 0xec, 0xbf, 0xfc, 266 | 0xda, 0x7f, 0xd6, 0xcc, 0x2b, 0xc0, 0x91, 0x67, 0xaf, 0x00, 0xff, 0xf7, 267 | 0x7c, 0xf3, 0x9b, 0xdf, 0x4c, 0x6b, 0xd7, 0xae, 0xcd, 0xe8, 0xdf, 0xfc, 268 | 0xf5, 0xaf, 0x7f, 0x9d, 0x06, 0x0d, 0x1a, 0xe4, 0x15, 0xe0, 0xbd, 0xcc, 269 | 0xf8, 0xf1, 0xe3, 0xd3, 0xba, 0x75, 0xeb, 0x32, 0xfa, 0x1e, 0x1e, 0x79, 270 | 0xe4, 0x91, 0xd4, 0xb7, 0x6f, 0x5f, 0xe7, 0x47, 0xc6, 0x78, 0x0b, 0xb4, 271 | 0x31, 0xf9, 0x37, 0x65, 0x65, 0x65, 0x69, 0xc6, 0x8c, 0x19, 0x19, 0xff, 272 | 0x62, 0xcf, 0x17, 0x4f, 0x3c, 0xf1, 0x44, 0x2a, 0x29, 0x29, 0x11, 0xc0, 273 | 0xf6, 0x5f, 0xce, 0xed, 0x3f, 0x6b, 0x26, 0x80, 0x0b, 0x25, 0x80, 0x23, 274 | 0x22, 0xf5, 0xef, 0xdf, 0x3f, 0xd5, 0xd5, 0xd5, 0xa5, 0xd6, 0xd6, 0xd6, 275 | 0x0e, 0xff, 0xdd, 0xcd, 0x9b, 0x37, 0xa7, 0x4b, 0x2e, 0xb9, 0x44, 0x00, 276 | 0xff, 0xd7, 0xf4, 0xeb, 0xd7, 0x2f, 0xcd, 0x9e, 0x3d, 0xbb, 0xd3, 0xcf, 277 | 0xb9, 0x45, 0x8b, 0x16, 0xa5, 0x83, 0x0f, 0x3e, 0xd8, 0xb9, 0x92, 0x31, 278 | 0x02, 0xd8, 0x98, 0xfc, 0x99, 0xc3, 0x0e, 0x3b, 0x2c, 0xfd, 0xfd, 0xef, 279 | 0x7f, 0x4f, 0x85, 0xe6, 0xae, 0xbb, 0xee, 0xca, 0xa9, 0xf8, 0xcd, 0xd7, 280 | 0x13, 0x7a, 0xfb, 0xcf, 0x9a, 0xf5, 0xd4, 0x9a, 0x09, 0xe0, 0xfc, 0x09, 281 | 0xe0, 0xdd, 0x53, 0x55, 0x55, 0x95, 0x16, 0x2f, 0x5e, 0x9c, 0xf1, 0xe7, 282 | 0xc4, 0xab, 0xaa, 0xaa, 0x04, 0x70, 0x44, 0xaa, 0xae, 0xae, 0x4e, 0x6f, 283 | 0xbe, 0xf9, 0x66, 0x97, 0x9f, 0x7b, 0x6f, 0xbf, 0xfd, 0x76, 0x1a, 0x39, 284 | 0x72, 0xa4, 0x73, 0x26, 0x63, 0x04, 0xb0, 0x31, 0xf9, 0x71, 0xd5, 0xd5, 285 | 0x77, 0xde, 0x79, 0xa7, 0xa0, 0x4e, 0xa2, 0x9f, 0x7f, 0xfe, 0xf9, 0x74, 286 | 0xda, 0x69, 0xa7, 0x15, 0xec, 0x89, 0xab, 0xfd, 0x97, 0xdb, 0xfb, 0xcf, 287 | 0x9a, 0x79, 0xc7, 0x44, 0x21, 0x07, 0xf0, 0xee, 0xb9, 0xe4, 0x92, 0x4b, 288 | 0xd2, 0xa6, 0x4d, 0x9b, 0x3a, 0xfc, 0x1e, 0x5a, 0x5b, 0x5b, 0x53, 0x5d, 289 | 0x5d, 0x5d, 0xea, 0xdf, 0xbf, 0x7f, 0x41, 0x06, 0x70, 0x69, 0x69, 0x69, 290 | 0xba, 0xf9, 0xe6, 0x9b, 0x53, 0x5b, 0x5b, 0xdb, 0xa7, 0x7e, 0x1e, 0x36, 291 | 0x35, 0x35, 0xa5, 0xaf, 0x7e, 0xf5, 0xab, 0xce, 0x9d, 0x8c, 0x11, 0xc0, 292 | 0xc6, 0xe4, 0xf6, 0x15, 0x58, 0x33, 0xfd, 0x9f, 0xf4, 0x5c, 0xb7, 0x6e, 293 | 0xdd, 0xba, 0x34, 0x67, 0xce, 0x9c, 0x34, 0x76, 0xec, 0xd8, 0x82, 0x3f, 294 | 0x71, 0xb5, 0xff, 0x72, 0x77, 0xff, 0x59, 0x33, 0x01, 0x2c, 0x80, 0xff, 295 | 0x6f, 0x06, 0x0d, 0x1a, 0x94, 0xee, 0xbb, 0xef, 0xbe, 0x8c, 0xbe, 0x97, 296 | 0xb5, 0x6b, 0xd7, 0xa6, 0x6f, 0x7c, 0xe3, 0x1b, 0x05, 0x15, 0xc0, 0xa3, 297 | 0x46, 0x8d, 0xea, 0xf6, 0x77, 0x8a, 0xb4, 0xb5, 0xb5, 0xa5, 0x1f, 0xfc, 298 | 0xe0, 0x07, 0xce, 0xa1, 0x8c, 0x71, 0x15, 0x68, 0xc8, 0x4d, 0x93, 0x27, 299 | 0x4f, 0x8e, 0xbb, 0xef, 0xbe, 0xbb, 0x53, 0xf7, 0xf9, 0xf8, 0xe3, 0x8f, 300 | 0xa3, 0xa1, 0xa1, 0x21, 0x3e, 0xfc, 0xf0, 0xc3, 0x68, 0x6f, 0x6f, 0xcf, 301 | 0xaa, 0xc7, 0xb3, 0x6b, 0xd7, 0xae, 0x68, 0x6d, 0x6d, 0x8d, 0x6d, 0xdb, 302 | 0xb6, 0xc5, 0xa6, 0x4d, 0x9b, 0x62, 0xdd, 0xba, 0x75, 0xd1, 0xd8, 0xd8, 303 | 0x18, 0x2b, 0x56, 0xac, 0x88, 0xb7, 0xdf, 0x7e, 0x3b, 0x2f, 0x7e, 0x66, 304 | 0x29, 0x8f, 0xae, 0x6a, 0x6b, 0xff, 0x59, 0xb3, 0x9e, 0x5e, 0xb3, 0xe4, 305 | 0x2a, 0xd0, 0x3d, 0xb6, 0x2e, 0xd9, 0xb4, 0xb6, 0x63, 0xc7, 0x8e, 0x8d, 306 | 0xbb, 0xef, 0xbe, 0x3b, 0x46, 0x8e, 0x1c, 0xd9, 0xe1, 0x6d, 0x9f, 0x7c, 307 | 0xf2, 0xc9, 0x98, 0x32, 0x65, 0x4a, 0xac, 0x5a, 0xb5, 0xaa, 0xcb, 0xff, 308 | 0x5e, 0xb6, 0x5f, 0x05, 0xba, 0xb8, 0xb8, 0x38, 0xae, 0xb9, 0xe6, 0x9a, 309 | 0xb8, 0xe1, 0x86, 0x1b, 0xa2, 0xac, 0xac, 0x6c, 0x8f, 0xb7, 0x6b, 0x6d, 310 | 0x6d, 0x8d, 0x3e, 0x7d, 0xfa, 0x74, 0xe9, 0xea, 0xf0, 0xf7, 0xde, 0x7b, 311 | 0x6f, 0x4c, 0x99, 0x32, 0x25, 0xda, 0xda, 0xda, 0x9c, 0x4c, 0x41, 0xb6, 312 | 0x1d, 0xe3, 0x8d, 0x31, 0x7b, 0x7e, 0x25, 0xa9, 0x33, 0x6f, 0xa3, 0x7c, 313 | 0xe6, 0x99, 0x67, 0xd2, 0xa9, 0xa7, 0x9e, 0x9a, 0x8a, 0x8b, 0x8b, 0xad, 314 | 0x9f, 0x57, 0x80, 0xed, 0xbf, 0x1c, 0x58, 0xb3, 0x05, 0x0b, 0x16, 0x14, 315 | 0xfc, 0x9a, 0x79, 0x05, 0x38, 0xbf, 0x5f, 0x01, 0xfe, 0xf7, 0x29, 0x29, 316 | 0x29, 0x49, 0xd7, 0x5e, 0x7b, 0x6d, 0xc6, 0x7f, 0x3b, 0xf8, 0xfa, 0xeb, 317 | 0xaf, 0xef, 0xf2, 0xd5, 0x8d, 0xb3, 0xf9, 0x15, 0xe0, 0xe1, 0xc3, 0x87, 318 | 0xa7, 0x45, 0x8b, 0x16, 0x75, 0xf8, 0xb5, 0x5f, 0x79, 0xe5, 0x95, 0x34, 319 | 0x7a, 0xf4, 0xe8, 0x34, 0x61, 0xc2, 0x84, 0xd4, 0xd4, 0xd4, 0xd4, 0xa5, 320 | 0x57, 0x83, 0x9f, 0x7e, 0xfa, 0xe9, 0x34, 0x70, 0xe0, 0x40, 0xbf, 0x9b, 321 | 0x8d, 0xf1, 0x16, 0x68, 0x63, 0x72, 0x63, 0xce, 0x38, 0xe3, 0x8c, 0x8c, 322 | 0x7f, 0xc9, 0xcd, 0x9e, 0x3d, 0x3b, 0x15, 0x15, 0x15, 0x59, 0x37, 0x27, 323 | 0xf4, 0xf6, 0x5f, 0x8e, 0xac, 0xd9, 0xbd, 0xf7, 0xde, 0x6b, 0xcd, 0x04, 324 | 0x70, 0x41, 0x05, 0xf0, 0xbf, 0x07, 0xe0, 0x9f, 0xff, 0xfc, 0xe7, 0x8c, 325 | 0xbe, 0xbf, 0xd7, 0x5f, 0x7f, 0x3d, 0x9d, 0x7e, 0xfa, 0xe9, 0x79, 0x13, 326 | 0xc0, 0x97, 0x5d, 0x76, 0x59, 0xda, 0xba, 0x75, 0xeb, 0x5e, 0xbf, 0x66, 327 | 0x7b, 0x7b, 0x7b, 0xba, 0xed, 0xb6, 0xdb, 0x52, 0x59, 0x59, 0xd9, 0xbf, 328 | 0xee, 0x37, 0x62, 0xc4, 0x88, 0xd4, 0xd8, 0xd8, 0xd8, 0xa5, 0x08, 0x7e, 329 | 0xe3, 0x8d, 0x37, 0x52, 0x65, 0x65, 0xa5, 0xdf, 0xcf, 0xc6, 0x08, 0x60, 330 | 0x63, 0xb2, 0x7f, 0x6a, 0x6b, 0x6b, 0x33, 0xfa, 0xe5, 0xb6, 0x72, 0xe5, 331 | 0xca, 0x9c, 0xbb, 0x52, 0xb2, 0x13, 0xd7, 0xed, 0xf6, 0x5f, 0x01, 0x3f, 332 | 0x67, 0x5f, 0x7b, 0xed, 0xb5, 0x54, 0x5a, 0x5a, 0x6a, 0xcd, 0x04, 0x70, 333 | 0x41, 0x06, 0xf0, 0xee, 0xf9, 0xce, 0x77, 0xbe, 0x93, 0x36, 0x6e, 0xdc, 334 | 0x98, 0xd1, 0xf7, 0x79, 0xff, 0xfd, 0xf7, 0xa7, 0xcf, 0x7e, 0xf6, 0xb3, 335 | 0x39, 0x1b, 0xc0, 0x43, 0x87, 0x0e, 0x4d, 0x4f, 0x3e, 0xf9, 0x64, 0x87, 336 | 0x5f, 0x6f, 0xd5, 0xaa, 0x55, 0xe9, 0x94, 0x53, 0x4e, 0xf9, 0xc4, 0xaf, 337 | 0x31, 0x70, 0xe0, 0xc0, 0x8c, 0xff, 0xe3, 0xe0, 0xbf, 0x7d, 0xf0, 0xc1, 338 | 0x07, 0x5d, 0xfa, 0x8f, 0x04, 0x63, 0x8c, 0x00, 0x36, 0xa6, 0x57, 0x67, 339 | 0xc1, 0x82, 0x05, 0x19, 0xfd, 0x62, 0xbb, 0xfc, 0xf2, 0xcb, 0xad, 0x97, 340 | 0x13, 0x7a, 0xfb, 0x2f, 0x87, 0xd6, 0x6c, 0xca, 0x94, 0x29, 0xd6, 0x4b, 341 | 0x00, 0x17, 0x7c, 0x00, 0x47, 0x44, 0x3a, 0xf0, 0xc0, 0x03, 0x33, 0xbe, 342 | 0x48, 0xd6, 0x87, 0x1f, 0x7e, 0x98, 0xa6, 0x4c, 0x99, 0x92, 0xd1, 0x3b, 343 | 0x27, 0xb2, 0x29, 0x80, 0xbf, 0xf5, 0xad, 0x6f, 0xa5, 0xcd, 0x9b, 0x37, 344 | 0x77, 0xf8, 0xb5, 0x7e, 0xf9, 0xcb, 0x5f, 0x76, 0x78, 0x25, 0xec, 0x3e, 345 | 0x7d, 0xfa, 0xa4, 0xdb, 0x6f, 0xbf, 0xbd, 0x4b, 0x11, 0xbc, 0x73, 0xe7, 346 | 0xce, 0x74, 0xe9, 0xa5, 0x97, 0x3a, 0xee, 0x18, 0x23, 0x80, 0x8d, 0xc9, 347 | 0xde, 0x79, 0xf7, 0xdd, 0x77, 0x33, 0xfa, 0xa5, 0x76, 0xf4, 0xd1, 0x47, 348 | 0x5b, 0x2f, 0x27, 0xf4, 0xf6, 0x5f, 0x0e, 0xad, 0xd9, 0x31, 0xc7, 0x1c, 349 | 0x63, 0xbd, 0x04, 0xb0, 0x00, 0xfe, 0xb7, 0x39, 0xf5, 0xd4, 0x53, 0x53, 350 | 0x43, 0x43, 0x43, 0x46, 0xdf, 0xf3, 0xb2, 0x65, 0xcb, 0xd2, 0x09, 0x27, 351 | 0x9c, 0x90, 0xf5, 0x01, 0x7c, 0xe0, 0x81, 0x07, 0xa6, 0x87, 0x1f, 0x7e, 352 | 0xb8, 0xc3, 0xaf, 0xb1, 0x61, 0xc3, 0x86, 0x74, 0xce, 0x39, 0xe7, 0x74, 353 | 0x6a, 0xbd, 0xbe, 0xf7, 0xbd, 0xef, 0xa5, 0x1d, 0x3b, 0x76, 0x74, 0x29, 354 | 0x84, 0x67, 0xcd, 0x9a, 0xe5, 0x5a, 0x21, 0xc6, 0x08, 0x60, 0x63, 0xb2, 355 | 0x73, 0xb6, 0x6d, 0xdb, 0x96, 0xd1, 0x2f, 0xb3, 0xae, 0x5e, 0x24, 0xc4, 356 | 0x38, 0xa1, 0xb7, 0xff, 0xf6, 0xcd, 0x9a, 0xfd, 0xfb, 0x67, 0xfb, 0x3c, 357 | 0x5f, 0x04, 0xb0, 0x00, 0xfe, 0xdf, 0xe9, 0xdb, 0xb7, 0x6f, 0x9a, 0x3e, 358 | 0x7d, 0x7a, 0x46, 0x61, 0xd7, 0xd6, 0xd6, 0x96, 0xee, 0xbc, 0xf3, 0xce, 359 | 0xb4, 0xff, 0xfe, 0xfb, 0x67, 0x65, 0x00, 0x9f, 0x75, 0xd6, 0x59, 0x69, 360 | 0xfd, 0xfa, 0xf5, 0x1d, 0xde, 0xff, 0x91, 0x47, 0x1e, 0x49, 0x07, 0x1d, 361 | 0x74, 0x50, 0x97, 0xd6, 0x6b, 0xcc, 0x98, 0x31, 0xe9, 0xbd, 0xf7, 0xde, 362 | 0xeb, 0x52, 0x04, 0x3f, 0xf1, 0xc4, 0x13, 0x69, 0xc0, 0x80, 0x01, 0x8e, 363 | 0x41, 0xc6, 0x08, 0x60, 0x63, 0xb2, 0x6b, 0xda, 0xdb, 0xdb, 0x3b, 0xfc, 364 | 0x25, 0xb6, 0x63, 0xc7, 0x0e, 0x6b, 0x95, 0x83, 0x27, 0xae, 0xdb, 0xb6, 365 | 0x6d, 0xb3, 0xff, 0xf2, 0x70, 0xda, 0xda, 0xda, 0x32, 0x7a, 0x1b, 0xa2, 366 | 0xb5, 0xea, 0xdc, 0xf3, 0xa5, 0xa5, 0xa5, 0xc5, 0xba, 0x14, 0x40, 0x00, 367 | 0xef, 0x9e, 0xa3, 0x8f, 0x3e, 0x3a, 0x2d, 0x5c, 0xb8, 0x30, 0xa3, 0xef, 368 | 0x7f, 0xc3, 0x86, 0x0d, 0xe9, 0xc2, 0x0b, 0x2f, 0xfc, 0x7f, 0x5f, 0x23, 369 | 0xd3, 0x57, 0x47, 0x3f, 0xed, 0xfa, 0xfd, 0xf7, 0x31, 0xb0, 0x5f, 0xbf, 370 | 0x7e, 0x69, 0xce, 0x9c, 0x39, 0x19, 0x7d, 0x26, 0xf7, 0xdb, 0xdf, 0xfe, 371 | 0xf6, 0xa7, 0x5e, 0xab, 0x43, 0x0f, 0x3d, 0x34, 0x2d, 0x5f, 0xbe, 0xbc, 372 | 0x4b, 0x11, 0xfc, 0xca, 0x2b, 0xaf, 0xa4, 0x61, 0xc3, 0x86, 0x39, 0x0e, 373 | 0x19, 0x23, 0x80, 0x8d, 0xf1, 0xca, 0x88, 0xe9, 0xfa, 0xec, 0xbf, 0xff, 374 | 0xfe, 0x19, 0xfd, 0xdc, 0x36, 0x6f, 0xde, 0x6c, 0xff, 0xe5, 0xe1, 0x64, 375 | 0xf2, 0xe7, 0x5d, 0xbc, 0x6a, 0xde, 0xb5, 0x57, 0xea, 0x0a, 0x6d, 0xcd, 376 | 0x0a, 0x39, 0x80, 0x77, 0xcf, 0xc5, 0x17, 0x5f, 0x9c, 0xd1, 0x67, 0x67, 377 | 0x53, 0x4a, 0x69, 0xfe, 0xfc, 0xf9, 0xff, 0xba, 0xd2, 0xf1, 0x80, 0x01, 378 | 0x03, 0x32, 0x8e, 0xc0, 0x4f, 0xbb, 0x7e, 0x29, 0xa5, 0x7f, 0x7d, 0x6e, 379 | 0xb7, 0xba, 0xba, 0x3a, 0xbd, 0xf9, 0xe6, 0x9b, 0x1d, 0xde, 0x7e, 0xde, 380 | 0xbc, 0x79, 0xe9, 0x90, 0x43, 0x0e, 0xe9, 0xb6, 0x75, 0x2a, 0x2f, 0x2f, 381 | 0x4f, 0x0f, 0x3e, 0xf8, 0x60, 0x97, 0x22, 0x78, 0xe3, 0xc6, 0x8d, 0xa9, 382 | 0xba, 0xba, 0xda, 0xb1, 0xc8, 0x18, 0x01, 0x6c, 0x8c, 0x00, 0x31, 0x5d, 383 | 0x9b, 0xaa, 0xaa, 0xaa, 0x8c, 0x7e, 0x6e, 0x8d, 0x8d, 0x8d, 0xf6, 0x5f, 384 | 0x1e, 0xce, 0x9a, 0x35, 0x6b, 0x7c, 0x6e, 0xba, 0x93, 0x93, 0xc9, 0xdb, 385 | 0x44, 0x53, 0x4a, 0x05, 0xf7, 0x67, 0x5c, 0x04, 0xf0, 0xff, 0xce, 0xe0, 386 | 0xc1, 0x83, 0xd3, 0x03, 0x0f, 0x3c, 0x90, 0xf1, 0xab, 0xb1, 0xb7, 0xdc, 387 | 0x72, 0x4b, 0xa7, 0x2e, 0x12, 0xd5, 0x1d, 0x01, 0x3c, 0x6b, 0xd6, 0xac, 388 | 0x34, 0x6b, 0xd6, 0xac, 0x0e, 0xdf, 0x01, 0xb2, 0x75, 0xeb, 0xd6, 0x1e, 389 | 0xbd, 0x00, 0xde, 0xb5, 0xd7, 0x5e, 0x9b, 0xd1, 0x3b, 0x77, 0x3e, 0x69, 390 | 0xdd, 0x26, 0x4d, 0x9a, 0xe4, 0x78, 0x64, 0x8c, 0x00, 0x36, 0x46, 0x80, 391 | 0x98, 0xce, 0xcf, 0xd4, 0xa9, 0x53, 0x33, 0xfa, 0xb9, 0x3d, 0xf5, 0xd4, 392 | 0x53, 0xf6, 0x5f, 0x1e, 0xce, 0x5f, 0xfe, 0xf2, 0x97, 0x8c, 0xd6, 0x6d, 393 | 0xf2, 0xe4, 0xc9, 0xd6, 0xeb, 0x9f, 0xf3, 0xdc, 0x73, 0xcf, 0x65, 0xb4, 394 | 0x66, 0x85, 0x76, 0xf5, 0x5a, 0x01, 0xfc, 0x9f, 0x73, 0xe6, 0x99, 0x67, 395 | 0xa6, 0x55, 0xab, 0x56, 0xa5, 0xee, 0xd6, 0x1d, 0x01, 0x9c, 0x89, 0xc5, 396 | 0x8b, 0x17, 0xa7, 0x2f, 0x7c, 0xe1, 0x0b, 0x3d, 0xbe, 0x4e, 0x13, 0x26, 397 | 0x4c, 0x48, 0x4d, 0x4d, 0x4d, 0x5d, 0xfa, 0x1e, 0x6f, 0xba, 0xe9, 0x26, 398 | 0xc7, 0x24, 0x63, 0x7a, 0x61, 0x8a, 0x03, 0x20, 0x4f, 0x94, 0x94, 0x94, 399 | 0xc4, 0xe4, 0xc9, 0x93, 0x33, 0xba, 0xed, 0xf3, 0xcf, 0x3f, 0x6f, 0xc1, 400 | 0xf2, 0x50, 0xa6, 0x3f, 0xd7, 0x2b, 0xae, 0xb8, 0x22, 0x4a, 0x4a, 0x4a, 401 | 0x2c, 0x58, 0x44, 0x2c, 0x5f, 0xbe, 0xdc, 0x9a, 0xd1, 0xa1, 0x79, 0xf3, 402 | 0xe6, 0xc5, 0xb1, 0xc7, 0x1e, 0x1b, 0x33, 0x67, 0xce, 0x8c, 0xd6, 0xd6, 403 | 0xd6, 0x9c, 0xf9, 0xbe, 0x77, 0xee, 0xdc, 0x19, 0xd7, 0x5d, 0x77, 0x5d, 404 | 0xd4, 0xd4, 0xd4, 0x44, 0x63, 0x63, 0x63, 0x8f, 0xff, 0x7b, 0x8f, 0x3f, 405 | 0xfe, 0x78, 0x9c, 0x7c, 0xf2, 0xc9, 0xf1, 0xd6, 0x5b, 0x6f, 0x75, 0xfa, 406 | 0xbe, 0x3f, 0xfe, 0xf1, 0x8f, 0xe3, 0xf7, 0xbf, 0xff, 0x7d, 0x54, 0x54, 407 | 0x54, 0xd8, 0x70, 0xd0, 0xc3, 0xfc, 0x4f, 0x80, 0x31, 0x5e, 0x81, 0xcb, 408 | 0xf9, 0x29, 0x2a, 0x2a, 0x4a, 0xb3, 0x67, 0xcf, 0xce, 0xf8, 0x7f, 0xda, 409 | 0xc7, 0x8d, 0x1b, 0x67, 0xff, 0xe5, 0xe1, 0x7c, 0xe5, 0x2b, 0x5f, 0xc9, 410 | 0x78, 0x0f, 0xcc, 0x9e, 0x3d, 0x3b, 0xa3, 0xbf, 0x67, 0x9a, 0xef, 0x73, 411 | 0xce, 0x39, 0xe7, 0x64, 0xbc, 0x66, 0x77, 0xdc, 0x71, 0x47, 0xc1, 0xac, 412 | 0x99, 0x57, 0x80, 0xf7, 0x3c, 0xa3, 0x46, 0x8d, 0x4a, 0x4b, 0x96, 0x2c, 413 | 0xc9, 0xfa, 0x57, 0x80, 0x5f, 0x7a, 0xe9, 0xa5, 0x54, 0x55, 0x55, 0xb5, 414 | 0x4f, 0xd6, 0x68, 0xe0, 0xc0, 0x81, 0x69, 0xfe, 0xfc, 0xf9, 0x5d, 0xfa, 415 | 0xbe, 0x97, 0x2f, 0x5f, 0xde, 0xad, 0x9f, 0x51, 0x36, 0xc6, 0x78, 0x0b, 416 | 0xb4, 0x31, 0x02, 0x24, 0xcf, 0xc2, 0xb7, 0xa6, 0xa6, 0xa6, 0x53, 0x27, 417 | 0x1a, 0xef, 0xbc, 0xf3, 0x4e, 0x4e, 0x9c, 0xc4, 0xdb, 0x7f, 0x9d, 0x9f, 418 | 0x3e, 0x7d, 0xfa, 0x64, 0xfc, 0x39, 0xe0, 0x94, 0x52, 0x7a, 0xfa, 0xe9, 419 | 0xa7, 0xd3, 0x29, 0xa7, 0x9c, 0x52, 0xd0, 0x7f, 0x93, 0xb3, 0xb4, 0xb4, 420 | 0xb4, 0x53, 0x7f, 0xca, 0xe5, 0xa9, 0xa7, 0x9e, 0x4a, 0x35, 0x35, 0x35, 421 | 0x79, 0xbf, 0x66, 0x02, 0xb8, 0xe3, 0x63, 0xef, 0x15, 0x57, 0x5c, 0xd1, 422 | 0xe5, 0xb7, 0xfb, 0xf6, 0x64, 0x00, 0xb7, 0xb5, 0xb5, 0xa5, 0x99, 0x33, 423 | 0x67, 0xee, 0xf3, 0x0b, 0xb7, 0xf5, 0xe9, 0xd3, 0x27, 0xd5, 0xd7, 0xd7, 424 | 0x77, 0xe9, 0x31, 0xac, 0x5b, 0xb7, 0xae, 0xc3, 0xbf, 0xb5, 0x6c, 0x8c, 425 | 0xe9, 0xe2, 0xf1, 0x6b, 0x77, 0x05, 0x03, 0x9f, 0xf0, 0xf6, 0x88, 0xd4, 426 | 0xf1, 0xd3, 0x63, 0xc7, 0x8e, 0x1d, 0x51, 0x5e, 0x5e, 0x6e, 0xb1, 0xfe, 427 | 0x69, 0xee, 0xdc, 0xb9, 0xbd, 0xf2, 0xef, 0x14, 0x17, 0x17, 0xc7, 0x01, 428 | 0x07, 0x1c, 0x10, 0x95, 0x95, 0x95, 0x71, 0xc0, 0x01, 0x07, 0x74, 0xea, 429 | 0xbe, 0x53, 0xa6, 0x4c, 0x89, 0xbb, 0xef, 0xbe, 0xdb, 0xfe, 0xcb, 0x53, 430 | 0x57, 0x5e, 0x79, 0x65, 0xd4, 0xd7, 0xd7, 0x77, 0xea, 0x3e, 0x1f, 0x7d, 431 | 0xf4, 0x51, 0x34, 0x34, 0x34, 0xc4, 0x96, 0x2d, 0x5b, 0xa2, 0xbd, 0xbd, 432 | 0x3d, 0xaf, 0xd6, 0x63, 0xe7, 0xce, 0x9d, 0x71, 0xee, 0xb9, 0xe7, 0xee, 433 | 0xf5, 0x36, 0x57, 0x5f, 0x7d, 0x75, 0xdc, 0x7a, 0xeb, 0xad, 0x9d, 0xfa, 434 | 0xba, 0x4d, 0x4d, 0x4d, 0xd1, 0xd0, 0xd0, 0x10, 0x4d, 0x4d, 0x4d, 0x39, 435 | 0xbb, 0x66, 0x67, 0x9d, 0x75, 0x56, 0x8f, 0x3e, 0xff, 0x0a, 0xe1, 0x39, 436 | 0x7c, 0xc8, 0x21, 0x87, 0xc4, 0x1d, 0x77, 0xdc, 0x11, 0xe7, 0x9d, 0x77, 437 | 0x5e, 0x97, 0xee, 0x5f, 0x54, 0x54, 0xf4, 0xa9, 0xd6, 0xef, 0xbf, 0xbd, 438 | 0xf5, 0xd6, 0x5b, 0x71, 0xd1, 0x45, 0x17, 0xc5, 0x73, 0xcf, 0x3d, 0x97, 439 | 0x35, 0x6b, 0xf4, 0xfd, 0xef, 0x7f, 0x3f, 0xee, 0xba, 0xeb, 0xae, 0x28, 440 | 0x2b, 0x2b, 0xeb, 0xd4, 0xfd, 0x9a, 0x9b, 0x9b, 0xe3, 0xa2, 0x8b, 0x2e, 441 | 0x8a, 0x47, 0x1e, 0x79, 0xc4, 0x81, 0x1d, 0xba, 0xfb, 0x1c, 0xcb, 0x18, 442 | 0xe3, 0x15, 0xb8, 0xde, 0x5c, 0xb3, 0x7d, 0xe9, 0x6f, 0x7f, 0xfb, 0x5b, 443 | 0xce, 0xbc, 0x72, 0x65, 0xff, 0x75, 0xf1, 0xe2, 0x16, 0xc5, 0xc5, 0x69, 444 | 0xe9, 0xd2, 0xa5, 0x89, 0xcc, 0xf7, 0x48, 0x69, 0x69, 0x69, 0x5a, 0xb1, 445 | 0x62, 0x45, 0xc1, 0xad, 0x4d, 0x78, 0x05, 0xb8, 0xdb, 0xe6, 0xdc, 0x73, 446 | 0xcf, 0x4d, 0xef, 0xbe, 0xfb, 0xee, 0x3e, 0x7d, 0x05, 0x78, 0xce, 0x9c, 447 | 0x39, 0xa9, 0x5f, 0xbf, 0x7e, 0x59, 0xb9, 0x3e, 0x63, 0xc6, 0x8c, 0xe9, 448 | 0xd4, 0x3b, 0x2d, 0x76, 0x6b, 0x6f, 0x6f, 0x4f, 0xd7, 0x5f, 0x7f, 0xbd, 449 | 0x63, 0xbb, 0x31, 0x2e, 0x82, 0x05, 0xd0, 0x79, 0xeb, 0xd6, 0xad, 0x8b, 450 | 0xaf, 0x7f, 0xfd, 0xeb, 0xb1, 0x6b, 0xd7, 0x2e, 0x8b, 0x91, 0xc7, 0x76, 451 | 0xed, 0xda, 0x15, 0x13, 0x27, 0x4e, 0x8c, 0xb5, 0x6b, 0xd7, 0x5a, 0x8c, 452 | 0x0c, 0xb5, 0xb6, 0xb6, 0xc6, 0xc4, 0x89, 0x13, 0x63, 0xe3, 0xc6, 0x8d, 453 | 0x16, 0x83, 0x2e, 0xf9, 0xe3, 0x1f, 0xff, 0x18, 0x23, 0x46, 0x8c, 0x88, 454 | 0xfa, 0xfa, 0xfa, 0x5e, 0x7f, 0x47, 0xc0, 0xfa, 0xf5, 0xeb, 0xe3, 0xec, 455 | 0xb3, 0xcf, 0x8e, 0x4b, 0x2f, 0xbd, 0x34, 0xb6, 0x6d, 0xdb, 0x96, 0x95, 456 | 0xeb, 0xb3, 0x78, 0xf1, 0xe2, 0x38, 0xf1, 0xc4, 0x13, 0xe3, 0x85, 0x17, 457 | 0x5e, 0xe8, 0xd4, 0xfd, 0x8a, 0x8b, 0x8b, 0x63, 0xfa, 0xf4, 0xe9, 0x71, 458 | 0xff, 0xfd, 0xf7, 0x77, 0xfa, 0x15, 0x64, 0x60, 0x0f, 0xcf, 0x2b, 0x4b, 459 | 0x00, 0x14, 0x82, 0xd7, 0x5e, 0x7b, 0x2d, 0x6a, 0x6a, 0x6a, 0x44, 0x51, 460 | 0x81, 0x58, 0xbb, 0x76, 0x6d, 0xd4, 0xd4, 0xd4, 0xc4, 0x2b, 0xaf, 0xbc, 461 | 0x62, 0x31, 0x32, 0xb4, 0x6a, 0xd5, 0xaa, 0x5e, 0xbb, 0x52, 0x2e, 0xf9, 462 | 0x69, 0xeb, 0xd6, 0xad, 0x31, 0x75, 0xea, 0xd4, 0x38, 0xe9, 0xa4, 0x93, 463 | 0x62, 0xc5, 0x8a, 0x15, 0x1d, 0xde, 0xbe, 0xa3, 0x50, 0xce, 0x24, 0xa4, 464 | 0x1f, 0x7a, 0xe8, 0xa1, 0x18, 0x39, 0x72, 0x64, 0xaf, 0x7d, 0xfc, 0xe6, 465 | 0xd3, 0x58, 0xb3, 0x66, 0x4d, 0xd4, 0xd4, 0xd4, 0xc4, 0xc3, 0x0f, 0x3f, 466 | 0xdc, 0xe9, 0xfb, 0x5e, 0x78, 0xe1, 0x85, 0xb1, 0x60, 0xc1, 0x82, 0x18, 467 | 0x3c, 0x78, 0xb0, 0x8d, 0x06, 0xdd, 0xc0, 0x4b, 0xe1, 0xc6, 0x78, 0xfb, 468 | 0x5a, 0xde, 0xbe, 0x05, 0xba, 0xa5, 0xa5, 0x25, 0xd5, 0xd5, 0xd5, 0xa5, 469 | 0xf2, 0xf2, 0x72, 0xfb, 0xaf, 0x00, 0x67, 0xbf, 0xfd, 0xf6, 0x4b, 0x33, 470 | 0x67, 0xce, 0x4c, 0x3b, 0x76, 0xec, 0xf0, 0x16, 0xe8, 0x0c, 0xa7, 0x7f, 471 | 0xff, 0xfe, 0xa9, 0xbe, 0xbe, 0x3e, 0xb5, 0xb6, 0xb6, 0x7a, 0x0b, 0xb4, 472 | 0xb7, 0x40, 0x7f, 0xaa, 0x0b, 0x40, 0x5d, 0x7d, 0xf5, 0xd5, 0x69, 0xeb, 473 | 0xd6, 0xad, 0x7b, 0x7c, 0xec, 0xab, 0x57, 0xaf, 0xde, 0xeb, 0xd7, 0x78, 474 | 0xe7, 0x9d, 0x77, 0xf6, 0x78, 0xdf, 0xcd, 0x9b, 0x37, 0xa7, 0x0b, 0x2e, 475 | 0xb8, 0x20, 0x67, 0xd7, 0xe7, 0xba, 0xeb, 0xae, 0x4b, 0xed, 0xed, 0xed, 476 | 0x9d, 0xde, 0xb3, 0xab, 0x57, 0xaf, 0x4e, 0xa3, 0x46, 0x8d, 0x72, 0x7c, 477 | 0x37, 0xc6, 0x55, 0xa0, 0x8d, 0x11, 0x20, 0x02, 0xf8, 0x3f, 0xad, 0x5d, 478 | 0xbb, 0x36, 0xcd, 0x9c, 0x39, 0x33, 0x1d, 0x7e, 0xf8, 0xe1, 0xf6, 0x9f, 479 | 0x49, 0x87, 0x1e, 0x7a, 0x68, 0xba, 0xe9, 0xa6, 0x9b, 0xf6, 0x7a, 0x42, 480 | 0x2d, 0x80, 0xff, 0x73, 0x8e, 0x38, 0xe2, 0x88, 0x74, 0xdb, 0x6d, 0xb7, 481 | 0xa5, 0xf5, 0xeb, 0xd7, 0x0b, 0x60, 0x01, 0xdc, 0xe5, 0x39, 0xfc, 0xf0, 482 | 0xc3, 0xd3, 0x9f, 0xfe, 0xf4, 0xa7, 0x4f, 0x7c, 0xec, 0x75, 0x75, 0x75, 483 | 0x7b, 0xbd, 0x6f, 0x5d, 0x5d, 0xdd, 0x27, 0xde, 0xef, 0xb1, 0xc7, 0x1e, 484 | 0x4b, 0x43, 0x86, 0x0c, 0xc9, 0xf9, 0xb5, 0x99, 0x30, 0x61, 0x42, 0x97, 485 | 0xae, 0xa2, 0xfd, 0xd1, 0x47, 0x1f, 0xa5, 0x09, 0x13, 0x26, 0x38, 0xb6, 486 | 0x1b, 0xe3, 0x2a, 0xd0, 0xd0, 0x03, 0x6f, 0x8f, 0x70, 0x15, 0xde, 0x1e, 487 | 0x59, 0xb3, 0xee, 0xd2, 0xd2, 0xd2, 0x12, 0xdb, 0xb7, 0x6f, 0x8f, 0x4d, 488 | 0x9b, 0x36, 0xc5, 0x86, 0x0d, 0x1b, 0xe2, 0x8d, 0x37, 0xde, 0x88, 0x15, 489 | 0x2b, 0x56, 0xc4, 0xa2, 0x45, 0x8b, 0xe2, 0xc5, 0x17, 0x5f, 0xb4, 0xff, 490 | 0xf8, 0x44, 0xc7, 0x1d, 0x77, 0x5c, 0x8c, 0x1d, 0x3b, 0x36, 0x8e, 0x3f, 491 | 0xfe, 0xf8, 0xa8, 0xac, 0xac, 0x8c, 0xa1, 0x43, 0x87, 0xc6, 0xa0, 0x41, 492 | 0x83, 0xa2, 0xa2, 0xa2, 0x22, 0x4a, 0x4b, 0x4b, 0xa3, 0xb8, 0x38, 0xbf, 493 | 0x3e, 0x1d, 0xf4, 0x69, 0xf7, 0x48, 0x51, 0x51, 0x51, 0x8c, 0x1e, 0x3d, 494 | 0x3a, 0xaa, 0xab, 0xab, 0xa3, 0xaa, 0xaa, 0x2a, 0x2a, 0x2b, 0x2b, 0x63, 495 | 0xc8, 0x90, 0x21, 0x31, 0x68, 0xd0, 0xa0, 0x28, 0x2f, 0x2f, 0x8f, 0xbe, 496 | 0x7d, 0xfb, 0xe6, 0xec, 0xda, 0x7c, 0xda, 0x2b, 0x10, 0xbb, 0x0a, 0x74, 497 | 0xe6, 0xc6, 0x8f, 0x1f, 0x1f, 0x57, 0x5d, 0x75, 0x55, 0x54, 0x57, 0x57, 498 | 0xc7, 0xa6, 0x4d, 0x9b, 0xe2, 0xd1, 0x47, 0x1f, 0x8d, 0x6b, 0xaf, 0xbd, 499 | 0x36, 0x9a, 0x9b, 0x9b, 0xf7, 0x78, 0x9f, 0x8a, 0x8a, 0x8a, 0xf8, 0xf9, 500 | 0xcf, 0x7f, 0x1e, 0x13, 0x27, 0x4e, 0x8c, 0x41, 0x83, 0x06, 0xc5, 0xe2, 501 | 0xc5, 0x8b, 0xa3, 0xb6, 0xb6, 0x36, 0xe6, 0xcd, 0x9b, 0x97, 0x37, 0xeb, 502 | 0x32, 0x62, 0xc4, 0x88, 0x78, 0xec, 0xb1, 0xc7, 0x62, 0xf8, 0xf0, 0xe1, 503 | 0x9d, 0xba, 0x5f, 0x7b, 0x7b, 0x7b, 0x4c, 0x9b, 0x36, 0x2d, 0x6a, 0x6b, 504 | 0x6b, 0x1d, 0xd4, 0xa1, 0xb3, 0xc7, 0x7e, 0x01, 0x0c, 0x00, 0x00, 0x40, 505 | 0x21, 0x70, 0x11, 0x2c, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 506 | 0x08, 0x60, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x20, 0x80, 507 | 0x01, 0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 508 | 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 509 | 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x04, 0x30, 510 | 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 511 | 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 0x80, 512 | 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x80, 0x00, 0x06, 513 | 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 514 | 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 0x10, 515 | 0xc0, 0x00, 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 0x40, 0x00, 0x03, 516 | 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 517 | 0x80, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 518 | 0x18, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 519 | 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 520 | 0x40, 0x00, 0x03, 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 0x40, 0x00, 521 | 0x03, 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 522 | 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 523 | 0x08, 0x60, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x20, 0x80, 524 | 0x01, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 525 | 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 0x00, 526 | 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x04, 0x30, 527 | 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 528 | 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x20, 529 | 0x80, 0x01, 0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 0x80, 0x00, 0x06, 530 | 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 531 | 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 0x04, 532 | 0x30, 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 533 | 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 534 | 0x80, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 535 | 0x18, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 536 | 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 537 | 0x10, 0xc0, 0x00, 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 0x40, 0x00, 538 | 0x03, 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 539 | 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 540 | 0x02, 0x18, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x08, 0x60, 541 | 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 542 | 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 0x40, 543 | 0x00, 0x5b, 0x02, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x08, 544 | 0x60, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x20, 0x80, 0x01, 545 | 0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 546 | 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x01, 547 | 0x0c, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 548 | 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 549 | 0x20, 0x80, 0x01, 0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 0x80, 0x00, 550 | 0x06, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 551 | 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 552 | 0x04, 0x30, 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 0x10, 0xc0, 553 | 0x00, 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 554 | 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 0x80, 555 | 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x18, 556 | 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 557 | 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 0x40, 558 | 0x00, 0x03, 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 0x40, 0x00, 0x03, 559 | 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 560 | 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x08, 561 | 0x60, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x20, 0x80, 0x01, 562 | 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 563 | 0x40, 0x00, 0x03, 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 564 | 0x0c, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 565 | 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 566 | 0x08, 0x60, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x20, 0x80, 567 | 0x01, 0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 568 | 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 569 | 0x04, 0x30, 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 0x04, 0x30, 570 | 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 571 | 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 0x80, 572 | 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x18, 573 | 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 574 | 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 0x10, 575 | 0xc0, 0x00, 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 0x40, 0x00, 0x03, 576 | 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 577 | 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 578 | 0x18, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 579 | 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 580 | 0x40, 0x00, 0x03, 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 0x40, 0x00, 581 | 0x03, 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 582 | 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 583 | 0x08, 0x60, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x20, 0x80, 584 | 0x01, 0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 585 | 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 0x00, 586 | 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x04, 0x30, 587 | 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 588 | 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x20, 589 | 0x80, 0x01, 0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 0x80, 0x00, 0x06, 590 | 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 591 | 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 0x10, 592 | 0xc0, 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 593 | 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 594 | 0x80, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 595 | 0x18, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 596 | 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 597 | 0x10, 0xc0, 0x00, 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 0x40, 0x00, 598 | 0x03, 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 599 | 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 600 | 0x02, 0x18, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x08, 0x60, 601 | 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 602 | 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 0x00, 603 | 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x01, 0x0c, 604 | 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 605 | 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x20, 606 | 0x80, 0x01, 0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 0x80, 0x00, 0x06, 607 | 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 608 | 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x04, 609 | 0x30, 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 610 | 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 611 | 0x80, 0x00, 0x06, 0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 0x80, 0x00, 612 | 0x06, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 613 | 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 614 | 0x10, 0xc0, 0x00, 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 0x40, 0x00, 615 | 0x03, 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 616 | 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 617 | 0x02, 0x18, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x08, 0x60, 618 | 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 619 | 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 0x40, 620 | 0x00, 0x03, 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x0c, 621 | 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 622 | 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x08, 623 | 0x60, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x20, 0x80, 0x01, 624 | 0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 625 | 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x04, 626 | 0x30, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 627 | 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 628 | 0x20, 0x80, 0x01, 0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 0x80, 0x00, 629 | 0x06, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 630 | 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 631 | 0x04, 0x30, 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 0x10, 0xc0, 632 | 0x00, 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 633 | 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x80, 634 | 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x18, 635 | 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 636 | 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 0x40, 637 | 0x00, 0x03, 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 0x40, 0x00, 0x03, 638 | 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 639 | 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x08, 640 | 0x60, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x20, 0x80, 0x01, 641 | 0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 642 | 0x40, 0x00, 0x03, 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 643 | 0x0c, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 644 | 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 645 | 0x20, 0x80, 0x01, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x20, 0x80, 646 | 0x01, 0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 0x80, 0x00, 0x06, 0x00, 647 | 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 648 | 0x04, 0x30, 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 0x10, 0xc0, 649 | 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 650 | 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 0x80, 651 | 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x18, 652 | 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x02, 0xd8, 0x12, 0x00, 653 | 0x00, 0x00, 0x20, 0x80, 0x01, 0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 654 | 0x40, 0xee, 0xf8, 0x1f, 0xf5, 0x8c, 0x17, 0xdf, 0xf7, 0x46, 0xd0, 0x86, 655 | 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, 656 | }; 657 | -------------------------------------------------------------------------------- /sample/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * psp2link sample for PSP2 to communicate and use host file system with psp2client host tool 3 | * Copyright (C) 2003,2015 Antonio Jose Ramos Marquez (aka bigboss) @psxdev on twitter 4 | * Repository https://github.com/psxdev/psp2link 5 | * based on ps2vfs, ps2client, ps2link, ps2http tools. 6 | * Credits goes for all people involved in ps2dev project https://github.com/ps2dev 7 | * File chooser, font and vita2d from @xerpi and @SMOKE587 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | 23 | #include 24 | #include 25 | 26 | #include "logo.h" 27 | 28 | //#define imgpath "cache0:/VitaDefilerClient/Documents/psp2link.png" 29 | static const char *supported_ext[] = { 30 | "elf", NULL 31 | }; 32 | 33 | //enable debug level 3 34 | #define LOGLEVEL 3 35 | int main() 36 | { 37 | int ret; 38 | char rom_path[256]; 39 | //ip mac/linux, port udp, port request, port command, log level 40 | ret=psp2LinkInit("192.168.1.3",0x4711,0x4712,0x4712,LOGLEVEL); 41 | if(!ret) 42 | { 43 | psp2LinkFinish(); 44 | return ret; 45 | } 46 | debugNetPrintf(DEBUG,"Test debug level %d\n",ret); 47 | vita2d_init(); 48 | 49 | vita2d_set_clear_color(RGBA8(0x40, 0x40, 0x40, 0xFF)); 50 | vita2d_texture *splash = vita2d_create_empty_texture(960, 544); 51 | //splash = vita2d_load_PNG_file(imgpath); 52 | splash = vita2d_load_PNG_buffer(psp2link_png); 53 | 54 | 55 | while(!psp2LinkRequestsIsConnected()) 56 | { 57 | vita2d_start_drawing(); 58 | vita2d_clear_screen(); 59 | vita2d_draw_texture(splash, 0, 0); 60 | vita2d_end_drawing(); 61 | vita2d_swap_buffers(); 62 | } 63 | 64 | while(1) 65 | { 66 | //for unix machine host0:/foo/bar format 67 | //for windows machine host0:c:\\foo\\bar 68 | file_choose( 69 | "host0:/usr/local", 70 | rom_path, 71 | "Choose a host file:", 72 | supported_ext 73 | ); 74 | } 75 | vita2d_free_texture(splash); 76 | vita2d_fini(); 77 | psp2LinkFinish(); 78 | sceKernelExitProcess(0); 79 | return 0; 80 | 81 | } 82 | --------------------------------------------------------------------------------