From 8a3bef901248232063fe82ec1bbe6d46108d4961 Mon Sep 17 00:00:00 2001 From: Dan Peori Date: Mon, 18 Oct 2010 12:54:49 -0300 Subject: [PATCH] first commit --- LICENSE | 28 + Makefile.am | 18 + README | 216 ++ VERSION | 1 + aclocal/ac_doxygen.m4 | 312 +++ aclocal/pspdev.m4 | 61 + aclocal/version.m4 | 19 + aminclude.am | 186 ++ bootstrap | 137 ++ config.h.in | 81 + configure.ac | 118 + doxygen.cfg | 1226 ++++++++++ src/Makefile.am | 36 + src/atrac3/Makefile.am | 23 + src/atrac3/pspatrac3.h | 139 ++ src/atrac3/sceAtrac3plus.S | 82 + src/audio/Makefile.am | 51 + src/audio/pspaudio.h | 354 +++ src/audio/pspaudio_kernel.h | 49 + src/audio/pspaudiocodec.h | 31 + src/audio/pspaudiolib.c | 177 ++ src/audio/pspaudiolib.h | 53 + src/audio/sceAudio.S | 89 + src/audio/sceAudio_driver.S | 116 + src/audio/sceAudiocodec.S | 31 + src/base/Makefile.am | 17 + src/base/as_reg_compat.h | 52 + src/base/build.mak | 204 ++ src/base/build_prx.mak | 86 + src/base/linkfile.prx.in | 246 ++ src/base/prxspecs | 2 + src/base/pspimport.s | 68 + src/base/pspstub.s | 83 + src/base/psptypes.h | 434 ++++ src/ctrl/Makefile.am | 32 + src/ctrl/pspctrl.h | 206 ++ src/ctrl/pspctrl_kernel.h | 70 + src/ctrl/sceCtrl.S | 55 + src/ctrl/sceCtrl_driver.S | 85 + src/debug/Makefile.am | 50 + src/debug/callstack.c | 256 +++ src/debug/callstackget.S | 46 + src/debug/exception.c | 103 + src/debug/exception_asm.S | 334 +++ src/debug/font.c | 147 ++ src/debug/gdb-kernellib.c | 91 + src/debug/gdb-stub.c | 822 +++++++ src/debug/gdb-userlib.c | 195 ++ src/debug/kprintf.c | 45 + src/debug/profiler.c | 97 + src/debug/pspdebug.h | 443 ++++ src/debug/pspdebugkb.c | 292 +++ src/debug/pspdebugkb.h | 96 + src/debug/scr_printf.c | 478 ++++ src/debug/sio.c | 178 ++ src/debug/stacktrace.c | 111 + src/debug/stdio.c | 291 +++ src/display/Makefile.am | 30 + src/display/pspdisplay.h | 129 ++ src/display/pspdisplay_kernel.h | 72 + src/display/sceDisplay.S | 58 + src/display/sceDisplay_driver.S | 85 + src/fpu/Makefile.am | 18 + src/fpu/pspfpu.c | 151 ++ src/fpu/pspfpu.h | 185 ++ src/ge/Makefile.am | 30 + src/ge/pspge.h | 213 ++ src/ge/sceGe_driver.S | 76 + src/ge/sceGe_user.S | 58 + src/gu/Makefile.am | 36 + src/gu/callbackFin.c | 16 + src/gu/callbackSig.c | 23 + src/gu/doc/commands.txt | 999 ++++++++ src/gu/guInternal.c | 55 + src/gu/guInternal.h | 125 + src/gu/pspgu.h | 1487 ++++++++++++ src/gu/resetValues.c | 63 + src/gu/sceGuAlphaFunc.c | 15 + src/gu/sceGuAmbient.c | 15 + src/gu/sceGuAmbientColor.c | 15 + src/gu/sceGuBeginObject.c | 37 + src/gu/sceGuBlendFunc.c | 16 + src/gu/sceGuBoneMatrix.c | 25 + src/gu/sceGuBreak.c | 15 + src/gu/sceGuCallList.c | 26 + src/gu/sceGuCallMode.c | 14 + src/gu/sceGuCheckList.c | 14 + src/gu/sceGuClear.c | 74 + src/gu/sceGuClearColor.c | 15 + src/gu/sceGuClearDepth.c | 15 + src/gu/sceGuClearStencil.c | 15 + src/gu/sceGuClutLoad.c | 16 + src/gu/sceGuClutMode.c | 15 + src/gu/sceGuColor.c | 14 + src/gu/sceGuColorFunc.c | 16 + src/gu/sceGuColorMaterial.c | 14 + src/gu/sceGuContinue.c | 15 + src/gu/sceGuCopyImage.c | 21 + src/gu/sceGuDepthBuffer.c | 20 + src/gu/sceGuDepthFunc.c | 14 + src/gu/sceGuDepthMask.c | 14 + src/gu/sceGuDepthOffset.c | 17 + src/gu/sceGuDepthRange.c | 34 + src/gu/sceGuDisable.c | 54 + src/gu/sceGuDispBuffer.c | 34 + src/gu/sceGuDisplay.c | 23 + src/gu/sceGuDrawArray.c | 29 + src/gu/sceGuDrawArrayN.c | 36 + src/gu/sceGuDrawBezier.c | 29 + src/gu/sceGuDrawBuffer.c | 28 + src/gu/sceGuDrawBufferList.c | 16 + src/gu/sceGuDrawSpline.c | 29 + src/gu/sceGuEnable.c | 54 + src/gu/sceGuEndObject.c | 23 + src/gu/sceGuFinish.c | 81 + src/gu/sceGuFog.c | 21 + src/gu/sceGuFrontFace.c | 17 + src/gu/sceGuGetAllStatus.c | 14 + src/gu/sceGuGetMemory.c | 36 + src/gu/sceGuGetStatus.c | 16 + src/gu/sceGuInit.c | 72 + src/gu/sceGuLight.c | 24 + src/gu/sceGuLightAtt.c | 18 + src/gu/sceGuLightColor.c | 34 + src/gu/sceGuLightMode.c | 14 + src/gu/sceGuLightSpot.c | 21 + src/gu/sceGuLogicalOp.c | 14 + src/gu/sceGuMaterial.c | 24 + src/gu/sceGuModelColor.c | 17 + src/gu/sceGuMorphWeight.c | 14 + src/gu/sceGuOffset.c | 15 + src/gu/sceGuPatchDivide.c | 14 + src/gu/sceGuPatchFrontFace.c | 14 + src/gu/sceGuPatchPrim.c | 19 + src/gu/sceGuPixelMask.c | 15 + src/gu/sceGuScissor.c | 25 + src/gu/sceGuSendCommandf.c | 14 + src/gu/sceGuSendCommandi.c | 14 + src/gu/sceGuSendList.c | 33 + src/gu/sceGuSetAllStatus.c | 21 + src/gu/sceGuSetCallback.c | 33 + src/gu/sceGuSetDither.c | 17 + src/gu/sceGuSetMatrix.c | 67 + src/gu/sceGuSetStatus.c | 17 + src/gu/sceGuShadeModel.c | 18 + src/gu/sceGuSignal.c | 23 + src/gu/sceGuSpecular.c | 14 + src/gu/sceGuStart.c | 64 + src/gu/sceGuStencilFunc.c | 14 + src/gu/sceGuStencilOp.c | 14 + src/gu/sceGuSwapBuffers.c | 43 + src/gu/sceGuSync.c | 23 + src/gu/sceGuTerm.c | 18 + src/gu/sceGuTexEnvColor.c | 14 + src/gu/sceGuTexFilter.c | 14 + src/gu/sceGuTexFlush.c | 14 + src/gu/sceGuTexFunc.c | 17 + src/gu/sceGuTexImage.c | 33 + src/gu/sceGuTexLevelMode.c | 24 + src/gu/sceGuTexMapMode.c | 19 + src/gu/sceGuTexMode.c | 20 + src/gu/sceGuTexOffset.c | 15 + src/gu/sceGuTexProjMapMode.c | 17 + src/gu/sceGuTexScale.c | 15 + src/gu/sceGuTexSlope.c | 14 + src/gu/sceGuTexSync.c | 14 + src/gu/sceGuTexWrap.c | 14 + src/gu/sceGuViewport.c | 17 + src/gu/sendCommand.c | 37 + src/gum/Makefile.am | 59 + src/gum/gumInternal.c | 30 + src/gum/gumInternal.h | 34 + src/gum/pspgum.c | 577 +++++ src/gum/pspgum.h | 236 ++ src/gum/pspgum_vfpu.c | 627 +++++ src/hprm/Makefile.am | 30 + src/hprm/psphprm.h | 95 + src/hprm/sceHprm.S | 31 + src/hprm/sceHprm_driver.S | 61 + src/kernel/ExceptionManagerForKernel.S | 31 + src/kernel/InitForKernel.S | 40 + src/kernel/InterruptManagerForKernel.S | 139 ++ src/kernel/IoFileMgrForKernel.S | 133 ++ src/kernel/KDebugForKernel.S | 67 + src/kernel/LoadCoreForKernel.S | 97 + src/kernel/LoadExecForKernel.S | 85 + src/kernel/Makefile.am | 166 ++ src/kernel/ModuleMgrForKernel.S | 73 + src/kernel/StdioForKernel.S | 52 + src/kernel/SysMemForKernel.S | 213 ++ src/kernel/SysTimerForKernel.S | 34 + src/kernel/SysclibForKernel.S | 133 ++ src/kernel/ThreadManForKernel.S | 412 ++++ src/kernel/UtilsForKernel.S | 124 + src/kernel/pspaudiorouting.h | 32 + src/kernel/pspexception.h | 57 + src/kernel/pspidstorage.h | 60 + src/kernel/pspimpose_driver.h | 142 ++ src/kernel/pspinit.h | 74 + src/kernel/pspintrman_kernel.h | 82 + src/kernel/pspiofilemgr_kernel.h | 166 ++ src/kernel/pspkdebug.h | 59 + src/kernel/pspkernel.h | 72 + src/kernel/psploadcore.h | 146 ++ src/kernel/psploadexec_kernel.h | 165 ++ src/kernel/pspmodulemgr_kernel.h | 68 + src/kernel/pspstdio_kernel.h | 72 + src/kernel/pspsysclib.h | 43 + src/kernel/pspsyscon.h | 74 + src/kernel/pspsysevent.h | 88 + src/kernel/pspsysmem_kernel.h | 210 ++ src/kernel/pspsysreg.h | 78 + src/kernel/pspsystimer.h | 93 + src/kernel/pspthreadman_kernel.h | 234 ++ src/kernel/psputilsforkernel.h | 80 + src/kernel/sceAudioRouting_driver.S | 19 + src/kernel/sceIdStorage_driver.S | 67 + src/kernel/sceImpose_driver.S | 76 + src/kernel/sceSysEventForKernel.S | 22 + src/kernel/sceSyscon_driver.S | 346 +++ src/kernel/sceSysreg_driver.S | 460 ++++ src/libc/LIB.status | 180 ++ src/libc/Makefile.am | 73 + src/libc/alloc.c | 490 ++++ src/libc/assert.h | 34 + src/libc/ctype.h | 57 + src/libc/cxx.cpp | 50 + src/libc/init.c | 35 + src/libc/libcglue.c | 168 ++ src/libc/malloc.h | 66 + src/libc/qsort.c | 177 ++ src/libc/setjmp.S | 117 + src/libc/stdio.c | 1444 ++++++++++++ src/libc/stdio.h | 211 ++ src/libc/stdlib.c | 1239 ++++++++++ src/libc/stdlib.h | 133 ++ src/libc/string.c | 840 +++++++ src/libc/string.h | 100 + src/libc/terminate.c | 34 + src/libc/time.h | 64 + src/libc/unistd.h | 21 + src/libc/xprintf.c | 988 ++++++++ src/mp3/Makefile.am | 25 + src/mp3/pspmp3.h | 202 ++ src/mp3/sceMp3.S | 67 + src/mpeg/Makefile.am | 62 + src/mpeg/pspjpeg.h | 69 + src/mpeg/pspmpeg.h | 344 +++ src/mpeg/pspmpegbase.h | 66 + src/mpeg/sceJpeg.S | 46 + src/mpeg/sceMpeg.S | 121 + src/mpeg/sceMpegbase.S | 34 + src/mpeg/sceMpegbase_driver.S | 37 + src/nand/Makefile.am | 23 + src/nand/pspnand_driver.h | 76 + src/nand/sceNand_driver.S | 124 + src/net/Makefile.am | 101 + src/net/psphttp.h | 326 +++ src/net/pspnet.h | 107 + src/net/pspnet_adhoc.h | 310 +++ src/net/pspnet_adhocctl.h | 287 +++ src/net/pspnet_adhocmatching.h | 269 +++ src/net/pspnet_apctl.h | 171 ++ src/net/pspnet_inet.h | 47 + src/net/pspnet_resolver.h | 98 + src/net/pspssl.h | 58 + src/net/sceHttp.S | 259 +++ src/net/sceNet.S | 31 + src/net/sceNetAdhoc.S | 82 + src/net/sceNetAdhocMatching.S | 55 + src/net/sceNetAdhocctl.S | 70 + src/net/sceNetApctl.S | 31 + src/net/sceNetInet.S | 97 + src/net/sceNetResolver.S | 28 + src/net/sceNet_lib.S | 295 +++ src/net/sceSsl.S | 43 + src/openpsid/Makefile.am | 23 + src/openpsid/pspopenpsid.h | 30 + src/openpsid/sceOpenPSID.S | 13 + src/power/Makefile.am | 31 + src/power/psppower.h | 280 +++ src/power/scePower.S | 145 ++ src/power/scePower_driver.S | 199 ++ src/prof/Makefile.am | 18 + src/prof/mcount.s | 61 + src/prof/prof.c | 256 +++ src/prof/pspprof.h | 25 + src/registry/Makefile.am | 32 + src/registry/pspreg.h | 237 ++ src/registry/sceReg.S | 61 + src/registry/sceReg_driver.S | 64 + src/rtc/Makefile.am | 31 + src/rtc/psprtc.h | 265 +++ src/rtc/sceRtc.S | 131 ++ src/rtc/sceRtc_driver.S | 176 ++ src/samples/Makefile.am | 122 + src/samples/audio/polyphonic/Makefile.sample | 17 + src/samples/audio/polyphonic/main.c | 474 ++++ src/samples/audio/wavegen/Makefile.sample | 17 + src/samples/audio/wavegen/main.c | 200 ++ src/samples/controller/basic/Makefile.sample | 16 + src/samples/controller/basic/main.c | 131 ++ src/samples/debug/debugkb/Makefile.sample | 17 + src/samples/debug/debugkb/main.c | 105 + src/samples/debug/exception/Makefile.sample | 16 + src/samples/debug/exception/main.c | 120 + src/samples/debug/gdb/Makefile.sample | 21 + src/samples/debug/gdb/main.c | 114 + src/samples/debug/kprintf/Makefile.sample | 16 + src/samples/debug/kprintf/main.c | 81 + src/samples/debug/profiler/Makefile.sample | 16 + src/samples/debug/profiler/main.c | 85 + src/samples/debug/prxdecrypt/Makefile.sample | 16 + src/samples/debug/prxdecrypt/main.c | 179 ++ src/samples/debug/sio/Makefile.sample | 21 + src/samples/debug/sio/main.c | 76 + src/samples/debug/sio/readme.txt | 7 + src/samples/gu/beginobject/Makefile.sample | 18 + src/samples/gu/beginobject/beginobject.c | 244 ++ src/samples/gu/blend/Makefile.sample | 17 + src/samples/gu/blend/blend.c | 198 ++ src/samples/gu/blit/Makefile.sample | 17 + src/samples/gu/blit/blit.c | 248 ++ src/samples/gu/celshading/Makefile.sample | 20 + src/samples/gu/celshading/celshading.c | 251 ++ src/samples/gu/celshading/lightmap.raw | 1 + src/samples/gu/clut/Makefile.sample | 17 + src/samples/gu/clut/clut.c | 194 ++ src/samples/gu/common/callbacks.c | 54 + src/samples/gu/common/callbacks.h | 15 + src/samples/gu/common/geometry.c | 174 ++ src/samples/gu/common/geometry.h | 65 + src/samples/gu/common/menu.c | 316 +++ src/samples/gu/common/menu.h | 65 + src/samples/gu/common/vram.c | 46 + src/samples/gu/common/vram.h | 31 + src/samples/gu/copy/Makefile.sample | 17 + src/samples/gu/copy/copy.c | 146 ++ src/samples/gu/cube/Makefile.sample | 20 + src/samples/gu/cube/cube.c | 185 ++ src/samples/gu/cube/logo.raw | 1 + src/samples/gu/envmap/Makefile.sample | 20 + src/samples/gu/envmap/env0.raw | 1 + src/samples/gu/envmap/envmap.c | 213 ++ src/samples/gu/integerdrawing/Makefile.sample | 18 + .../gu/integerdrawing/integerdrawing.c | 286 +++ src/samples/gu/lights/Makefile.sample | 17 + src/samples/gu/lights/lights.c | 187 ++ src/samples/gu/lines/Makefile.sample | 17 + src/samples/gu/lines/lines.c | 211 ++ src/samples/gu/logic/Makefile.sample | 17 + src/samples/gu/logic/logic.c | 165 ++ src/samples/gu/morph/Makefile.sample | 17 + src/samples/gu/morph/morph.c | 230 ++ src/samples/gu/morphskin/Makefile.sample | 17 + src/samples/gu/morphskin/morphskin.c | 352 +++ src/samples/gu/ortho/Makefile.sample | 19 + src/samples/gu/ortho/ortho.c | 140 ++ src/samples/gu/reflection/Makefile.sample | 20 + src/samples/gu/reflection/reflection.c | 304 +++ src/samples/gu/rendertarget/Makefile.sample | 17 + src/samples/gu/rendertarget/rendertarget.c | 417 ++++ .../gu/shadowprojection/Makefile.sample | 17 + .../gu/shadowprojection/shadowprojection.c | 512 +++++ src/samples/gu/signals/Makefile.sample | 20 + src/samples/gu/signals/ball.raw | 1 + src/samples/gu/signals/signals.c | 534 +++++ src/samples/gu/skinning/Makefile.sample | 18 + src/samples/gu/skinning/skinning.c | 309 +++ src/samples/gu/speed/Makefile.sample | 17 + src/samples/gu/speed/speed.c | 347 +++ src/samples/gu/spharm/Image1.raw | 1 + src/samples/gu/spharm/Image2.raw | Bin 0 -> 196608 bytes src/samples/gu/spharm/Makefile.sample | 25 + src/samples/gu/spharm/cube.c | 267 +++ src/samples/gu/spharm/disablefpu.S | 22 + src/samples/gu/spharm/logo.raw | Bin 0 -> 12288 bytes src/samples/gu/spharm/mt19937.c | 63 + src/samples/gu/spharm/mt19937.h | 16 + src/samples/gu/spharm/readme | 19 + src/samples/gu/spharm/spharm.c | 654 ++++++ src/samples/gu/splinesurface/Makefile.sample | 17 + src/samples/gu/splinesurface/splinesurface.c | 326 +++ src/samples/gu/sprite/Makefile.sample | 20 + src/samples/gu/sprite/ball.raw | 1 + src/samples/gu/sprite/sprite.c | 241 ++ src/samples/gu/text/Makefile.sample | 20 + src/samples/gu/text/font.raw | Bin 0 -> 131072 bytes src/samples/gu/text/main.c | 223 ++ src/samples/gu/timing/Makefile.sample | 18 + src/samples/gu/timing/timing.c | 338 +++ src/samples/gu/vertex/Makefile.sample | 17 + src/samples/gu/vertex/vertex.c | 624 +++++ src/samples/gu/zbufferfog/Makefile.sample | 17 + src/samples/gu/zbufferfog/zbufferfog.c | 256 +++ src/samples/ir/irda/Makefile.sample | 17 + src/samples/ir/irda/main.c | 107 + src/samples/ir/sircs/Makefile.sample | 17 + src/samples/ir/sircs/main.c | 143 ++ src/samples/kernel/cwd/Makefile.sample | 17 + src/samples/kernel/cwd/main.c | 105 + src/samples/kernel/fileio/Makefile.sample | 17 + src/samples/kernel/fileio/main.c | 347 +++ src/samples/kernel/idstorage/Makefile.sample | 14 + src/samples/kernel/idstorage/main.c | 63 + src/samples/kernel/kdumper/Makefile.sample | 16 + src/samples/kernel/kdumper/main.c | 214 ++ src/samples/kernel/loadmodule/Makefile.sample | 16 + src/samples/kernel/loadmodule/main.c | 152 ++ src/samples/kernel/messagebox/Makefile.sample | 16 + src/samples/kernel/messagebox/main.c | 209 ++ src/samples/kernel/regenum/Makefile.sample | 17 + src/samples/kernel/regenum/main.c | 322 +++ src/samples/kernel/registry/Makefile.sample | 17 + src/samples/kernel/registry/main.c | 168 ++ src/samples/kernel/sysevent/Makefile.sample | 16 + src/samples/kernel/sysevent/main.c | 70 + src/samples/kernel/systimer/Makefile.sample | 16 + src/samples/kernel/systimer/main.c | 58 + .../kernel/threadstatus/Makefile.sample | 16 + src/samples/kernel/threadstatus/main.c | 104 + src/samples/me/basic/Makefile.sample | 16 + src/samples/me/basic/main.c | 68 + src/samples/me/basic/me.S | 18 + src/samples/mp3/Makefile.sample | 16 + src/samples/mp3/main.c | 335 +++ src/samples/ms/callback/Makefile.sample | 15 + src/samples/ms/callback/main.c | 56 + src/samples/nand/dumpipl/Makefile.sample | 16 + src/samples/nand/dumpipl/README | 4 + src/samples/nand/dumpipl/main.c | 212 ++ src/samples/net/resolver/Makefile.sample | 14 + src/samples/net/resolver/main.c | 216 ++ src/samples/net/simple/Makefile.sample | 14 + src/samples/net/simple/main.c | 288 +++ src/samples/net/simple_prx/Makefile.sample | 15 + src/samples/net/simple_prx/exports.exp | 12 + src/samples/net/simple_prx/main.c | 234 ++ src/samples/net/wlanscan/Makefile.sample | 17 + src/samples/net/wlanscan/main.c | 228 ++ src/samples/net/wlanscan_elf/Makefile.sample | 17 + src/samples/net/wlanscan_elf/main.c | 374 +++ src/samples/power/Makefile.sample | 12 + src/samples/power/main.c | 190 ++ src/samples/prx/prx_loader/Makefile.sample | 20 + src/samples/prx/prx_loader/MyLib.S | 7 + src/samples/prx/prx_loader/main.c | 131 ++ src/samples/prx/testprx/Makefile.sample | 19 + src/samples/prx/testprx/exports.exp | 16 + src/samples/prx/testprx/main.c | 39 + src/samples/savedata/decrypt/Makefile.sample | 20 + src/samples/savedata/decrypt/README.txt | 5 + src/samples/savedata/decrypt/decrypt.c | 162 ++ src/samples/savedata/decrypt/decrypt.h | 30 + src/samples/savedata/decrypt/main.c | 100 + src/samples/savedata/encrypt/Makefile.sample | 23 + src/samples/savedata/encrypt/README.txt | 5 + src/samples/savedata/encrypt/encrypt.c | 230 ++ src/samples/savedata/encrypt/encrypt.h | 36 + src/samples/savedata/encrypt/hash.c | 128 ++ src/samples/savedata/encrypt/hash.h | 34 + src/samples/savedata/encrypt/main.c | 107 + src/samples/savedata/encrypt/psf.c | 114 + src/samples/savedata/encrypt/psf.h | 29 + src/samples/savedata/utility/Makefile.sample | 18 + src/samples/savedata/utility/data.h | 314 +++ src/samples/savedata/utility/main.c | 369 +++ .../template/elf_template/Makefile.sample | 16 + src/samples/template/elf_template/main.c | 33 + .../template/kprx_template/Makefile.sample | 19 + .../template/kprx_template/exports.exp | 12 + src/samples/template/kprx_template/main.c | 44 + .../template/lib_template/Makefile.sample | 13 + src/samples/template/lib_template/template.c | 18 + src/samples/template/lib_template/template.h | 26 + .../template/prx_template/Makefile.sample | 15 + src/samples/template/prx_template/main.c | 29 + src/samples/usb/storage/Makefile.sample | 10 + src/samples/usb/storage/main.c | 211 ++ .../utility/gamesharing/Makefile.sample | 20 + src/samples/utility/gamesharing/main.c | 398 ++++ .../utility/htmlviewer/Makefile.sample | 17 + src/samples/utility/htmlviewer/main.c | 293 +++ src/samples/utility/msgdialog/Makefile.sample | 14 + src/samples/utility/msgdialog/main.c | 312 +++ src/samples/utility/netconf/Makefile.sample | 12 + src/samples/utility/netconf/main.c | 117 + src/samples/utility/netdialog/Makefile.sample | 22 + src/samples/utility/netdialog/main.c | 313 +++ src/samples/utility/osk/Makefile.sample | 19 + src/samples/utility/osk/main.c | 223 ++ .../utility/systemparam/Makefile.sample | 12 + src/samples/utility/systemparam/main.c | 182 ++ src/samples/wlan/Makefile.sample | 12 + src/samples/wlan/main.c | 86 + src/sdk/Makefile.am | 40 + src/sdk/fixup.c | 113 + src/sdk/fpu.S | 15 + src/sdk/inethelper.c | 104 + src/sdk/interrupt.S | 66 + src/sdk/k1set.S | 22 + src/sdk/loadmodule.c | 66 + src/sdk/modulemgr_patches.c | 145 ++ src/sdk/pspsdk.h | 296 +++ src/sdk/query_mod.c | 57 + src/sdk/threadutils.c | 343 +++ src/sircs/Makefile.am | 23 + src/sircs/pspsircs.h | 45 + src/sircs/sceSircs.S | 10 + src/startup/Makefile.am | 36 + src/startup/crt0.c | 173 ++ src/startup/crt0_prx.c | 138 ++ src/startup/dummy.c | 0 src/startup/prxexports.c | 27 + src/umd/Makefile.am | 32 + src/umd/pspumd.h | 216 ++ src/umd/sceUmd.S | 112 + src/umd/sceUmdUser.S | 52 + src/usb/Makefile.am | 51 + src/usb/pspusb.h | 92 + src/usb/pspusbacc.h | 26 + src/usb/pspusbbus.h | 308 +++ src/usb/pspusbcam.h | 576 +++++ src/usb/sceUsb.S | 34 + src/usb/sceUsbBus_driver.S | 34 + src/usb/sceUsbCam.S | 169 ++ src/usb/sceUsb_driver.S | 37 + src/usbstor/Makefile.am | 30 + src/usbstor/pspusbstor.h | 64 + src/usbstor/sceUsbstor.S | 10 + src/usbstor/sceUsbstorBoot.S | 25 + src/user/InterruptManager.S | 34 + src/user/IoFileMgrForUser.S | 115 + src/user/Kernel_Library.S | 22 + src/user/LoadExecForUser.S | 19 + src/user/Makefile.am | 116 + src/user/ModuleMgrForUser.S | 40 + src/user/StdioForUser.S | 34 + src/user/SysMemUserForUser.S | 28 + src/user/ThreadManForUser.S | 385 ++++ src/user/UtilsForUser.S | 79 + src/user/pspintrman.c | 25 + src/user/pspintrman.h | 178 ++ src/user/pspiofilemgr.h | 477 ++++ src/user/pspiofilemgr_dirent.h | 35 + src/user/pspiofilemgr_fcntl.h | 34 + src/user/pspiofilemgr_stat.h | 118 + src/user/pspkerneltypes.h | 39 + src/user/pspkerror.h | 221 ++ src/user/psploadexec.h | 88 + src/user/pspmoduleexport.h | 29 + src/user/pspmoduleinfo.h | 148 ++ src/user/pspmodulemgr.h | 218 ++ src/user/pspmscm.h | 67 + src/user/pspstdio.h | 57 + src/user/pspsuspend.h | 57 + src/user/pspsysmem.h | 124 + src/user/pspthreadman.h | 1768 ++++++++++++++ src/user/pspuser.h | 31 + src/user/psputils.h | 230 ++ src/user/sceImpose.S | 52 + src/user/sceSuspendForUser.S | 25 + src/utility/Makefile.am | 40 + src/utility/psputility.h | 58 + src/utility/psputility_avmodules.h | 52 + src/utility/psputility_gamesharing.h | 86 + src/utility/psputility_htmlviewer.h | 192 ++ src/utility/psputility_modules.h | 78 + src/utility/psputility_msgdialog.h | 102 + src/utility/psputility_netconf.h | 80 + src/utility/psputility_netmodules.h | 53 + src/utility/psputility_netparam.h | 117 + src/utility/psputility_osk.h | 181 ++ src/utility/psputility_savedata.h | 183 ++ src/utility/psputility_sysparam.h | 141 ++ src/utility/psputility_usbmodules.h | 48 + src/utility/sceUtility.S | 175 ++ src/utility/sceUtility_netparam_internal.S | 19 + src/vfpu/Makefile.am | 20 + src/vfpu/pspvfpu.c | 178 ++ src/vfpu/pspvfpu.h | 76 + src/video/Makefile.am | 27 + src/video/pspvideocodec.h | 36 + src/video/sceVideocodec.S | 43 + src/vsh/Makefile.am | 35 + src/vsh/pspchnnlsv.h | 114 + src/vsh/sceChnnlsv.S | 25 + src/vsh/scePaf.S | 2038 +++++++++++++++++ src/vsh/sceVshBridge.S | 205 ++ src/wlan/Makefile.am | 27 + src/wlan/pspwlan.h | 64 + src/wlan/sceWlanDrv.S | 16 + src/wlan/sceWlanDrv_lib.S | 61 + tools/Makefile.am | 23 + tools/bin2c.c | 73 + tools/bin2o.c | 385 ++++ tools/bin2s.c | 75 + tools/elftypes.h | 246 ++ tools/getopt.h | 68 + tools/getopt_long.c | 405 ++++ tools/mksfo.c | 78 + tools/mksfoex.c | 341 +++ tools/pack-pbp.c | 189 ++ tools/prxtypes.h | 150 ++ tools/psp-build-exports.c | 1058 +++++++++ tools/psp-config.c | 290 +++ tools/psp-fixup-imports.c | 851 +++++++ tools/psp-prxgen.c | 941 ++++++++ tools/sha1.c | 282 +++ tools/sha1.h | 84 + tools/types.h | 162 ++ tools/unpack-pbp.c | 205 ++ 612 files changed, 74685 insertions(+) create mode 100644 LICENSE create mode 100644 Makefile.am create mode 100644 README create mode 100644 VERSION create mode 100644 aclocal/ac_doxygen.m4 create mode 100644 aclocal/pspdev.m4 create mode 100644 aclocal/version.m4 create mode 100644 aminclude.am create mode 100755 bootstrap create mode 100644 config.h.in create mode 100644 configure.ac create mode 100644 doxygen.cfg create mode 100644 src/Makefile.am create mode 100644 src/atrac3/Makefile.am create mode 100644 src/atrac3/pspatrac3.h create mode 100644 src/atrac3/sceAtrac3plus.S create mode 100644 src/audio/Makefile.am create mode 100644 src/audio/pspaudio.h create mode 100755 src/audio/pspaudio_kernel.h create mode 100644 src/audio/pspaudiocodec.h create mode 100644 src/audio/pspaudiolib.c create mode 100644 src/audio/pspaudiolib.h create mode 100644 src/audio/sceAudio.S create mode 100755 src/audio/sceAudio_driver.S create mode 100644 src/audio/sceAudiocodec.S create mode 100644 src/base/Makefile.am create mode 100644 src/base/as_reg_compat.h create mode 100644 src/base/build.mak create mode 100644 src/base/build_prx.mak create mode 100644 src/base/linkfile.prx.in create mode 100644 src/base/prxspecs create mode 100644 src/base/pspimport.s create mode 100644 src/base/pspstub.s create mode 100644 src/base/psptypes.h create mode 100644 src/ctrl/Makefile.am create mode 100644 src/ctrl/pspctrl.h create mode 100644 src/ctrl/pspctrl_kernel.h create mode 100644 src/ctrl/sceCtrl.S create mode 100644 src/ctrl/sceCtrl_driver.S create mode 100644 src/debug/Makefile.am create mode 100644 src/debug/callstack.c create mode 100644 src/debug/callstackget.S create mode 100644 src/debug/exception.c create mode 100644 src/debug/exception_asm.S create mode 100644 src/debug/font.c create mode 100644 src/debug/gdb-kernellib.c create mode 100644 src/debug/gdb-stub.c create mode 100644 src/debug/gdb-userlib.c create mode 100644 src/debug/kprintf.c create mode 100644 src/debug/profiler.c create mode 100644 src/debug/pspdebug.h create mode 100644 src/debug/pspdebugkb.c create mode 100644 src/debug/pspdebugkb.h create mode 100644 src/debug/scr_printf.c create mode 100644 src/debug/sio.c create mode 100644 src/debug/stacktrace.c create mode 100644 src/debug/stdio.c create mode 100644 src/display/Makefile.am create mode 100644 src/display/pspdisplay.h create mode 100644 src/display/pspdisplay_kernel.h create mode 100644 src/display/sceDisplay.S create mode 100644 src/display/sceDisplay_driver.S create mode 100644 src/fpu/Makefile.am create mode 100644 src/fpu/pspfpu.c create mode 100644 src/fpu/pspfpu.h create mode 100644 src/ge/Makefile.am create mode 100644 src/ge/pspge.h create mode 100644 src/ge/sceGe_driver.S create mode 100644 src/ge/sceGe_user.S create mode 100644 src/gu/Makefile.am create mode 100644 src/gu/callbackFin.c create mode 100644 src/gu/callbackSig.c create mode 100644 src/gu/doc/commands.txt create mode 100644 src/gu/guInternal.c create mode 100644 src/gu/guInternal.h create mode 100644 src/gu/pspgu.h create mode 100644 src/gu/resetValues.c create mode 100644 src/gu/sceGuAlphaFunc.c create mode 100644 src/gu/sceGuAmbient.c create mode 100644 src/gu/sceGuAmbientColor.c create mode 100644 src/gu/sceGuBeginObject.c create mode 100644 src/gu/sceGuBlendFunc.c create mode 100644 src/gu/sceGuBoneMatrix.c create mode 100644 src/gu/sceGuBreak.c create mode 100644 src/gu/sceGuCallList.c create mode 100644 src/gu/sceGuCallMode.c create mode 100644 src/gu/sceGuCheckList.c create mode 100644 src/gu/sceGuClear.c create mode 100644 src/gu/sceGuClearColor.c create mode 100644 src/gu/sceGuClearDepth.c create mode 100644 src/gu/sceGuClearStencil.c create mode 100644 src/gu/sceGuClutLoad.c create mode 100644 src/gu/sceGuClutMode.c create mode 100644 src/gu/sceGuColor.c create mode 100644 src/gu/sceGuColorFunc.c create mode 100644 src/gu/sceGuColorMaterial.c create mode 100644 src/gu/sceGuContinue.c create mode 100644 src/gu/sceGuCopyImage.c create mode 100644 src/gu/sceGuDepthBuffer.c create mode 100644 src/gu/sceGuDepthFunc.c create mode 100644 src/gu/sceGuDepthMask.c create mode 100644 src/gu/sceGuDepthOffset.c create mode 100644 src/gu/sceGuDepthRange.c create mode 100644 src/gu/sceGuDisable.c create mode 100644 src/gu/sceGuDispBuffer.c create mode 100644 src/gu/sceGuDisplay.c create mode 100644 src/gu/sceGuDrawArray.c create mode 100644 src/gu/sceGuDrawArrayN.c create mode 100644 src/gu/sceGuDrawBezier.c create mode 100644 src/gu/sceGuDrawBuffer.c create mode 100644 src/gu/sceGuDrawBufferList.c create mode 100644 src/gu/sceGuDrawSpline.c create mode 100644 src/gu/sceGuEnable.c create mode 100644 src/gu/sceGuEndObject.c create mode 100644 src/gu/sceGuFinish.c create mode 100644 src/gu/sceGuFog.c create mode 100644 src/gu/sceGuFrontFace.c create mode 100644 src/gu/sceGuGetAllStatus.c create mode 100644 src/gu/sceGuGetMemory.c create mode 100644 src/gu/sceGuGetStatus.c create mode 100644 src/gu/sceGuInit.c create mode 100644 src/gu/sceGuLight.c create mode 100644 src/gu/sceGuLightAtt.c create mode 100644 src/gu/sceGuLightColor.c create mode 100644 src/gu/sceGuLightMode.c create mode 100644 src/gu/sceGuLightSpot.c create mode 100644 src/gu/sceGuLogicalOp.c create mode 100644 src/gu/sceGuMaterial.c create mode 100644 src/gu/sceGuModelColor.c create mode 100644 src/gu/sceGuMorphWeight.c create mode 100644 src/gu/sceGuOffset.c create mode 100644 src/gu/sceGuPatchDivide.c create mode 100644 src/gu/sceGuPatchFrontFace.c create mode 100644 src/gu/sceGuPatchPrim.c create mode 100644 src/gu/sceGuPixelMask.c create mode 100644 src/gu/sceGuScissor.c create mode 100644 src/gu/sceGuSendCommandf.c create mode 100644 src/gu/sceGuSendCommandi.c create mode 100644 src/gu/sceGuSendList.c create mode 100644 src/gu/sceGuSetAllStatus.c create mode 100644 src/gu/sceGuSetCallback.c create mode 100644 src/gu/sceGuSetDither.c create mode 100644 src/gu/sceGuSetMatrix.c create mode 100644 src/gu/sceGuSetStatus.c create mode 100644 src/gu/sceGuShadeModel.c create mode 100644 src/gu/sceGuSignal.c create mode 100644 src/gu/sceGuSpecular.c create mode 100644 src/gu/sceGuStart.c create mode 100644 src/gu/sceGuStencilFunc.c create mode 100644 src/gu/sceGuStencilOp.c create mode 100644 src/gu/sceGuSwapBuffers.c create mode 100644 src/gu/sceGuSync.c create mode 100644 src/gu/sceGuTerm.c create mode 100644 src/gu/sceGuTexEnvColor.c create mode 100644 src/gu/sceGuTexFilter.c create mode 100644 src/gu/sceGuTexFlush.c create mode 100644 src/gu/sceGuTexFunc.c create mode 100644 src/gu/sceGuTexImage.c create mode 100644 src/gu/sceGuTexLevelMode.c create mode 100644 src/gu/sceGuTexMapMode.c create mode 100644 src/gu/sceGuTexMode.c create mode 100644 src/gu/sceGuTexOffset.c create mode 100644 src/gu/sceGuTexProjMapMode.c create mode 100644 src/gu/sceGuTexScale.c create mode 100644 src/gu/sceGuTexSlope.c create mode 100644 src/gu/sceGuTexSync.c create mode 100644 src/gu/sceGuTexWrap.c create mode 100644 src/gu/sceGuViewport.c create mode 100644 src/gu/sendCommand.c create mode 100644 src/gum/Makefile.am create mode 100644 src/gum/gumInternal.c create mode 100644 src/gum/gumInternal.h create mode 100644 src/gum/pspgum.c create mode 100644 src/gum/pspgum.h create mode 100644 src/gum/pspgum_vfpu.c create mode 100644 src/hprm/Makefile.am create mode 100644 src/hprm/psphprm.h create mode 100644 src/hprm/sceHprm.S create mode 100644 src/hprm/sceHprm_driver.S create mode 100644 src/kernel/ExceptionManagerForKernel.S create mode 100755 src/kernel/InitForKernel.S create mode 100644 src/kernel/InterruptManagerForKernel.S create mode 100644 src/kernel/IoFileMgrForKernel.S create mode 100644 src/kernel/KDebugForKernel.S create mode 100644 src/kernel/LoadCoreForKernel.S create mode 100644 src/kernel/LoadExecForKernel.S create mode 100644 src/kernel/Makefile.am create mode 100644 src/kernel/ModuleMgrForKernel.S create mode 100644 src/kernel/StdioForKernel.S create mode 100644 src/kernel/SysMemForKernel.S create mode 100644 src/kernel/SysTimerForKernel.S create mode 100644 src/kernel/SysclibForKernel.S create mode 100644 src/kernel/ThreadManForKernel.S create mode 100644 src/kernel/UtilsForKernel.S create mode 100755 src/kernel/pspaudiorouting.h create mode 100644 src/kernel/pspexception.h create mode 100644 src/kernel/pspidstorage.h create mode 100644 src/kernel/pspimpose_driver.h create mode 100755 src/kernel/pspinit.h create mode 100644 src/kernel/pspintrman_kernel.h create mode 100644 src/kernel/pspiofilemgr_kernel.h create mode 100644 src/kernel/pspkdebug.h create mode 100644 src/kernel/pspkernel.h create mode 100644 src/kernel/psploadcore.h create mode 100644 src/kernel/psploadexec_kernel.h create mode 100644 src/kernel/pspmodulemgr_kernel.h create mode 100644 src/kernel/pspstdio_kernel.h create mode 100644 src/kernel/pspsysclib.h create mode 100644 src/kernel/pspsyscon.h create mode 100644 src/kernel/pspsysevent.h create mode 100644 src/kernel/pspsysmem_kernel.h create mode 100644 src/kernel/pspsysreg.h create mode 100644 src/kernel/pspsystimer.h create mode 100644 src/kernel/pspthreadman_kernel.h create mode 100644 src/kernel/psputilsforkernel.h create mode 100755 src/kernel/sceAudioRouting_driver.S create mode 100644 src/kernel/sceIdStorage_driver.S create mode 100644 src/kernel/sceImpose_driver.S create mode 100644 src/kernel/sceSysEventForKernel.S create mode 100644 src/kernel/sceSyscon_driver.S create mode 100644 src/kernel/sceSysreg_driver.S create mode 100644 src/libc/LIB.status create mode 100644 src/libc/Makefile.am create mode 100644 src/libc/alloc.c create mode 100644 src/libc/assert.h create mode 100644 src/libc/ctype.h create mode 100644 src/libc/cxx.cpp create mode 100644 src/libc/init.c create mode 100644 src/libc/libcglue.c create mode 100644 src/libc/malloc.h create mode 100644 src/libc/qsort.c create mode 100644 src/libc/setjmp.S create mode 100644 src/libc/stdio.c create mode 100644 src/libc/stdio.h create mode 100644 src/libc/stdlib.c create mode 100644 src/libc/stdlib.h create mode 100644 src/libc/string.c create mode 100644 src/libc/string.h create mode 100644 src/libc/terminate.c create mode 100644 src/libc/time.h create mode 100644 src/libc/unistd.h create mode 100644 src/libc/xprintf.c create mode 100755 src/mp3/Makefile.am create mode 100755 src/mp3/pspmp3.h create mode 100755 src/mp3/sceMp3.S create mode 100644 src/mpeg/Makefile.am create mode 100755 src/mpeg/pspjpeg.h create mode 100644 src/mpeg/pspmpeg.h create mode 100755 src/mpeg/pspmpegbase.h create mode 100755 src/mpeg/sceJpeg.S create mode 100644 src/mpeg/sceMpeg.S create mode 100755 src/mpeg/sceMpegbase.S create mode 100755 src/mpeg/sceMpegbase_driver.S create mode 100644 src/nand/Makefile.am create mode 100644 src/nand/pspnand_driver.h create mode 100644 src/nand/sceNand_driver.S create mode 100644 src/net/Makefile.am create mode 100644 src/net/psphttp.h create mode 100644 src/net/pspnet.h create mode 100644 src/net/pspnet_adhoc.h create mode 100644 src/net/pspnet_adhocctl.h create mode 100644 src/net/pspnet_adhocmatching.h create mode 100644 src/net/pspnet_apctl.h create mode 100644 src/net/pspnet_inet.h create mode 100644 src/net/pspnet_resolver.h create mode 100644 src/net/pspssl.h create mode 100644 src/net/sceHttp.S create mode 100644 src/net/sceNet.S create mode 100644 src/net/sceNetAdhoc.S create mode 100644 src/net/sceNetAdhocMatching.S create mode 100644 src/net/sceNetAdhocctl.S create mode 100644 src/net/sceNetApctl.S create mode 100644 src/net/sceNetInet.S create mode 100644 src/net/sceNetResolver.S create mode 100644 src/net/sceNet_lib.S create mode 100644 src/net/sceSsl.S create mode 100644 src/openpsid/Makefile.am create mode 100755 src/openpsid/pspopenpsid.h create mode 100644 src/openpsid/sceOpenPSID.S create mode 100644 src/power/Makefile.am create mode 100644 src/power/psppower.h create mode 100644 src/power/scePower.S create mode 100644 src/power/scePower_driver.S create mode 100644 src/prof/Makefile.am create mode 100644 src/prof/mcount.s create mode 100644 src/prof/prof.c create mode 100644 src/prof/pspprof.h create mode 100644 src/registry/Makefile.am create mode 100644 src/registry/pspreg.h create mode 100644 src/registry/sceReg.S create mode 100644 src/registry/sceReg_driver.S create mode 100644 src/rtc/Makefile.am create mode 100644 src/rtc/psprtc.h create mode 100644 src/rtc/sceRtc.S create mode 100644 src/rtc/sceRtc_driver.S create mode 100644 src/samples/Makefile.am create mode 100644 src/samples/audio/polyphonic/Makefile.sample create mode 100644 src/samples/audio/polyphonic/main.c create mode 100644 src/samples/audio/wavegen/Makefile.sample create mode 100644 src/samples/audio/wavegen/main.c create mode 100644 src/samples/controller/basic/Makefile.sample create mode 100644 src/samples/controller/basic/main.c create mode 100644 src/samples/debug/debugkb/Makefile.sample create mode 100644 src/samples/debug/debugkb/main.c create mode 100644 src/samples/debug/exception/Makefile.sample create mode 100644 src/samples/debug/exception/main.c create mode 100644 src/samples/debug/gdb/Makefile.sample create mode 100644 src/samples/debug/gdb/main.c create mode 100644 src/samples/debug/kprintf/Makefile.sample create mode 100644 src/samples/debug/kprintf/main.c create mode 100644 src/samples/debug/profiler/Makefile.sample create mode 100644 src/samples/debug/profiler/main.c create mode 100644 src/samples/debug/prxdecrypt/Makefile.sample create mode 100644 src/samples/debug/prxdecrypt/main.c create mode 100644 src/samples/debug/sio/Makefile.sample create mode 100644 src/samples/debug/sio/main.c create mode 100644 src/samples/debug/sio/readme.txt create mode 100644 src/samples/gu/beginobject/Makefile.sample create mode 100644 src/samples/gu/beginobject/beginobject.c create mode 100644 src/samples/gu/blend/Makefile.sample create mode 100644 src/samples/gu/blend/blend.c create mode 100644 src/samples/gu/blit/Makefile.sample create mode 100644 src/samples/gu/blit/blit.c create mode 100644 src/samples/gu/celshading/Makefile.sample create mode 100644 src/samples/gu/celshading/celshading.c create mode 100644 src/samples/gu/celshading/lightmap.raw create mode 100644 src/samples/gu/clut/Makefile.sample create mode 100644 src/samples/gu/clut/clut.c create mode 100644 src/samples/gu/common/callbacks.c create mode 100644 src/samples/gu/common/callbacks.h create mode 100644 src/samples/gu/common/geometry.c create mode 100644 src/samples/gu/common/geometry.h create mode 100644 src/samples/gu/common/menu.c create mode 100644 src/samples/gu/common/menu.h create mode 100644 src/samples/gu/common/vram.c create mode 100644 src/samples/gu/common/vram.h create mode 100644 src/samples/gu/copy/Makefile.sample create mode 100644 src/samples/gu/copy/copy.c create mode 100644 src/samples/gu/cube/Makefile.sample create mode 100644 src/samples/gu/cube/cube.c create mode 100644 src/samples/gu/cube/logo.raw create mode 100644 src/samples/gu/envmap/Makefile.sample create mode 100644 src/samples/gu/envmap/env0.raw create mode 100644 src/samples/gu/envmap/envmap.c create mode 100644 src/samples/gu/integerdrawing/Makefile.sample create mode 100644 src/samples/gu/integerdrawing/integerdrawing.c create mode 100644 src/samples/gu/lights/Makefile.sample create mode 100644 src/samples/gu/lights/lights.c create mode 100644 src/samples/gu/lines/Makefile.sample create mode 100644 src/samples/gu/lines/lines.c create mode 100644 src/samples/gu/logic/Makefile.sample create mode 100644 src/samples/gu/logic/logic.c create mode 100644 src/samples/gu/morph/Makefile.sample create mode 100644 src/samples/gu/morph/morph.c create mode 100644 src/samples/gu/morphskin/Makefile.sample create mode 100644 src/samples/gu/morphskin/morphskin.c create mode 100644 src/samples/gu/ortho/Makefile.sample create mode 100644 src/samples/gu/ortho/ortho.c create mode 100644 src/samples/gu/reflection/Makefile.sample create mode 100644 src/samples/gu/reflection/reflection.c create mode 100644 src/samples/gu/rendertarget/Makefile.sample create mode 100644 src/samples/gu/rendertarget/rendertarget.c create mode 100644 src/samples/gu/shadowprojection/Makefile.sample create mode 100644 src/samples/gu/shadowprojection/shadowprojection.c create mode 100644 src/samples/gu/signals/Makefile.sample create mode 100644 src/samples/gu/signals/ball.raw create mode 100644 src/samples/gu/signals/signals.c create mode 100644 src/samples/gu/skinning/Makefile.sample create mode 100644 src/samples/gu/skinning/skinning.c create mode 100644 src/samples/gu/speed/Makefile.sample create mode 100644 src/samples/gu/speed/speed.c create mode 100644 src/samples/gu/spharm/Image1.raw create mode 100644 src/samples/gu/spharm/Image2.raw create mode 100644 src/samples/gu/spharm/Makefile.sample create mode 100644 src/samples/gu/spharm/cube.c create mode 100644 src/samples/gu/spharm/disablefpu.S create mode 100644 src/samples/gu/spharm/logo.raw create mode 100644 src/samples/gu/spharm/mt19937.c create mode 100644 src/samples/gu/spharm/mt19937.h create mode 100644 src/samples/gu/spharm/readme create mode 100644 src/samples/gu/spharm/spharm.c create mode 100644 src/samples/gu/splinesurface/Makefile.sample create mode 100644 src/samples/gu/splinesurface/splinesurface.c create mode 100644 src/samples/gu/sprite/Makefile.sample create mode 100644 src/samples/gu/sprite/ball.raw create mode 100644 src/samples/gu/sprite/sprite.c create mode 100644 src/samples/gu/text/Makefile.sample create mode 100644 src/samples/gu/text/font.raw create mode 100644 src/samples/gu/text/main.c create mode 100644 src/samples/gu/timing/Makefile.sample create mode 100644 src/samples/gu/timing/timing.c create mode 100644 src/samples/gu/vertex/Makefile.sample create mode 100644 src/samples/gu/vertex/vertex.c create mode 100644 src/samples/gu/zbufferfog/Makefile.sample create mode 100644 src/samples/gu/zbufferfog/zbufferfog.c create mode 100644 src/samples/ir/irda/Makefile.sample create mode 100644 src/samples/ir/irda/main.c create mode 100644 src/samples/ir/sircs/Makefile.sample create mode 100644 src/samples/ir/sircs/main.c create mode 100644 src/samples/kernel/cwd/Makefile.sample create mode 100644 src/samples/kernel/cwd/main.c create mode 100644 src/samples/kernel/fileio/Makefile.sample create mode 100644 src/samples/kernel/fileio/main.c create mode 100644 src/samples/kernel/idstorage/Makefile.sample create mode 100644 src/samples/kernel/idstorage/main.c create mode 100644 src/samples/kernel/kdumper/Makefile.sample create mode 100644 src/samples/kernel/kdumper/main.c create mode 100644 src/samples/kernel/loadmodule/Makefile.sample create mode 100644 src/samples/kernel/loadmodule/main.c create mode 100644 src/samples/kernel/messagebox/Makefile.sample create mode 100644 src/samples/kernel/messagebox/main.c create mode 100644 src/samples/kernel/regenum/Makefile.sample create mode 100644 src/samples/kernel/regenum/main.c create mode 100644 src/samples/kernel/registry/Makefile.sample create mode 100644 src/samples/kernel/registry/main.c create mode 100644 src/samples/kernel/sysevent/Makefile.sample create mode 100644 src/samples/kernel/sysevent/main.c create mode 100644 src/samples/kernel/systimer/Makefile.sample create mode 100644 src/samples/kernel/systimer/main.c create mode 100644 src/samples/kernel/threadstatus/Makefile.sample create mode 100644 src/samples/kernel/threadstatus/main.c create mode 100644 src/samples/me/basic/Makefile.sample create mode 100644 src/samples/me/basic/main.c create mode 100644 src/samples/me/basic/me.S create mode 100755 src/samples/mp3/Makefile.sample create mode 100755 src/samples/mp3/main.c create mode 100644 src/samples/ms/callback/Makefile.sample create mode 100644 src/samples/ms/callback/main.c create mode 100644 src/samples/nand/dumpipl/Makefile.sample create mode 100644 src/samples/nand/dumpipl/README create mode 100644 src/samples/nand/dumpipl/main.c create mode 100644 src/samples/net/resolver/Makefile.sample create mode 100644 src/samples/net/resolver/main.c create mode 100644 src/samples/net/simple/Makefile.sample create mode 100644 src/samples/net/simple/main.c create mode 100644 src/samples/net/simple_prx/Makefile.sample create mode 100644 src/samples/net/simple_prx/exports.exp create mode 100644 src/samples/net/simple_prx/main.c create mode 100644 src/samples/net/wlanscan/Makefile.sample create mode 100644 src/samples/net/wlanscan/main.c create mode 100644 src/samples/net/wlanscan_elf/Makefile.sample create mode 100644 src/samples/net/wlanscan_elf/main.c create mode 100644 src/samples/power/Makefile.sample create mode 100644 src/samples/power/main.c create mode 100644 src/samples/prx/prx_loader/Makefile.sample create mode 100644 src/samples/prx/prx_loader/MyLib.S create mode 100644 src/samples/prx/prx_loader/main.c create mode 100644 src/samples/prx/testprx/Makefile.sample create mode 100644 src/samples/prx/testprx/exports.exp create mode 100644 src/samples/prx/testprx/main.c create mode 100644 src/samples/savedata/decrypt/Makefile.sample create mode 100644 src/samples/savedata/decrypt/README.txt create mode 100644 src/samples/savedata/decrypt/decrypt.c create mode 100644 src/samples/savedata/decrypt/decrypt.h create mode 100644 src/samples/savedata/decrypt/main.c create mode 100644 src/samples/savedata/encrypt/Makefile.sample create mode 100644 src/samples/savedata/encrypt/README.txt create mode 100644 src/samples/savedata/encrypt/encrypt.c create mode 100644 src/samples/savedata/encrypt/encrypt.h create mode 100644 src/samples/savedata/encrypt/hash.c create mode 100644 src/samples/savedata/encrypt/hash.h create mode 100644 src/samples/savedata/encrypt/main.c create mode 100644 src/samples/savedata/encrypt/psf.c create mode 100644 src/samples/savedata/encrypt/psf.h create mode 100644 src/samples/savedata/utility/Makefile.sample create mode 100644 src/samples/savedata/utility/data.h create mode 100644 src/samples/savedata/utility/main.c create mode 100644 src/samples/template/elf_template/Makefile.sample create mode 100644 src/samples/template/elf_template/main.c create mode 100644 src/samples/template/kprx_template/Makefile.sample create mode 100644 src/samples/template/kprx_template/exports.exp create mode 100644 src/samples/template/kprx_template/main.c create mode 100644 src/samples/template/lib_template/Makefile.sample create mode 100644 src/samples/template/lib_template/template.c create mode 100644 src/samples/template/lib_template/template.h create mode 100644 src/samples/template/prx_template/Makefile.sample create mode 100644 src/samples/template/prx_template/main.c create mode 100644 src/samples/usb/storage/Makefile.sample create mode 100644 src/samples/usb/storage/main.c create mode 100644 src/samples/utility/gamesharing/Makefile.sample create mode 100644 src/samples/utility/gamesharing/main.c create mode 100644 src/samples/utility/htmlviewer/Makefile.sample create mode 100644 src/samples/utility/htmlviewer/main.c create mode 100644 src/samples/utility/msgdialog/Makefile.sample create mode 100644 src/samples/utility/msgdialog/main.c create mode 100644 src/samples/utility/netconf/Makefile.sample create mode 100644 src/samples/utility/netconf/main.c create mode 100644 src/samples/utility/netdialog/Makefile.sample create mode 100644 src/samples/utility/netdialog/main.c create mode 100755 src/samples/utility/osk/Makefile.sample create mode 100755 src/samples/utility/osk/main.c create mode 100644 src/samples/utility/systemparam/Makefile.sample create mode 100644 src/samples/utility/systemparam/main.c create mode 100644 src/samples/wlan/Makefile.sample create mode 100644 src/samples/wlan/main.c create mode 100644 src/sdk/Makefile.am create mode 100644 src/sdk/fixup.c create mode 100644 src/sdk/fpu.S create mode 100644 src/sdk/inethelper.c create mode 100644 src/sdk/interrupt.S create mode 100644 src/sdk/k1set.S create mode 100644 src/sdk/loadmodule.c create mode 100644 src/sdk/modulemgr_patches.c create mode 100644 src/sdk/pspsdk.h create mode 100644 src/sdk/query_mod.c create mode 100644 src/sdk/threadutils.c create mode 100644 src/sircs/Makefile.am create mode 100644 src/sircs/pspsircs.h create mode 100644 src/sircs/sceSircs.S create mode 100644 src/startup/Makefile.am create mode 100644 src/startup/crt0.c create mode 100644 src/startup/crt0_prx.c create mode 100644 src/startup/dummy.c create mode 100644 src/startup/prxexports.c create mode 100644 src/umd/Makefile.am create mode 100644 src/umd/pspumd.h create mode 100755 src/umd/sceUmd.S create mode 100644 src/umd/sceUmdUser.S create mode 100644 src/usb/Makefile.am create mode 100644 src/usb/pspusb.h create mode 100755 src/usb/pspusbacc.h create mode 100644 src/usb/pspusbbus.h create mode 100755 src/usb/pspusbcam.h create mode 100644 src/usb/sceUsb.S create mode 100644 src/usb/sceUsbBus_driver.S create mode 100755 src/usb/sceUsbCam.S create mode 100644 src/usb/sceUsb_driver.S create mode 100644 src/usbstor/Makefile.am create mode 100644 src/usbstor/pspusbstor.h create mode 100644 src/usbstor/sceUsbstor.S create mode 100644 src/usbstor/sceUsbstorBoot.S create mode 100644 src/user/InterruptManager.S create mode 100644 src/user/IoFileMgrForUser.S create mode 100644 src/user/Kernel_Library.S create mode 100644 src/user/LoadExecForUser.S create mode 100644 src/user/Makefile.am create mode 100644 src/user/ModuleMgrForUser.S create mode 100644 src/user/StdioForUser.S create mode 100644 src/user/SysMemUserForUser.S create mode 100644 src/user/ThreadManForUser.S create mode 100644 src/user/UtilsForUser.S create mode 100644 src/user/pspintrman.c create mode 100644 src/user/pspintrman.h create mode 100644 src/user/pspiofilemgr.h create mode 100644 src/user/pspiofilemgr_dirent.h create mode 100644 src/user/pspiofilemgr_fcntl.h create mode 100644 src/user/pspiofilemgr_stat.h create mode 100644 src/user/pspkerneltypes.h create mode 100644 src/user/pspkerror.h create mode 100644 src/user/psploadexec.h create mode 100644 src/user/pspmoduleexport.h create mode 100644 src/user/pspmoduleinfo.h create mode 100644 src/user/pspmodulemgr.h create mode 100644 src/user/pspmscm.h create mode 100644 src/user/pspstdio.h create mode 100644 src/user/pspsuspend.h create mode 100644 src/user/pspsysmem.h create mode 100644 src/user/pspthreadman.h create mode 100644 src/user/pspuser.h create mode 100644 src/user/psputils.h create mode 100644 src/user/sceImpose.S create mode 100644 src/user/sceSuspendForUser.S create mode 100644 src/utility/Makefile.am create mode 100644 src/utility/psputility.h create mode 100755 src/utility/psputility_avmodules.h create mode 100644 src/utility/psputility_gamesharing.h create mode 100644 src/utility/psputility_htmlviewer.h create mode 100755 src/utility/psputility_modules.h create mode 100644 src/utility/psputility_msgdialog.h create mode 100644 src/utility/psputility_netconf.h create mode 100644 src/utility/psputility_netmodules.h create mode 100644 src/utility/psputility_netparam.h create mode 100644 src/utility/psputility_osk.h create mode 100644 src/utility/psputility_savedata.h create mode 100644 src/utility/psputility_sysparam.h create mode 100755 src/utility/psputility_usbmodules.h create mode 100644 src/utility/sceUtility.S create mode 100644 src/utility/sceUtility_netparam_internal.S create mode 100644 src/vfpu/Makefile.am create mode 100644 src/vfpu/pspvfpu.c create mode 100644 src/vfpu/pspvfpu.h create mode 100755 src/video/Makefile.am create mode 100755 src/video/pspvideocodec.h create mode 100755 src/video/sceVideocodec.S create mode 100644 src/vsh/Makefile.am create mode 100644 src/vsh/pspchnnlsv.h create mode 100644 src/vsh/sceChnnlsv.S create mode 100644 src/vsh/scePaf.S create mode 100644 src/vsh/sceVshBridge.S create mode 100644 src/wlan/Makefile.am create mode 100644 src/wlan/pspwlan.h create mode 100644 src/wlan/sceWlanDrv.S create mode 100644 src/wlan/sceWlanDrv_lib.S create mode 100644 tools/Makefile.am create mode 100644 tools/bin2c.c create mode 100644 tools/bin2o.c create mode 100644 tools/bin2s.c create mode 100644 tools/elftypes.h create mode 100644 tools/getopt.h create mode 100644 tools/getopt_long.c create mode 100644 tools/mksfo.c create mode 100644 tools/mksfoex.c create mode 100644 tools/pack-pbp.c create mode 100644 tools/prxtypes.h create mode 100644 tools/psp-build-exports.c create mode 100644 tools/psp-config.c create mode 100644 tools/psp-fixup-imports.c create mode 100644 tools/psp-prxgen.c create mode 100644 tools/sha1.c create mode 100644 tools/sha1.h create mode 100644 tools/types.h create mode 100644 tools/unpack-pbp.c diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..6a7c199b --- /dev/null +++ b/LICENSE @@ -0,0 +1,28 @@ +Copyright (c) 2005 adresd +Copyright (c) 2005 Marcus R. Brown +Copyright (c) 2005 James Forshaw +Copyright (c) 2005 John Kelley +Copyright (c) 2005 Jesper Svennevid +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 00000000..7c5eb4ef --- /dev/null +++ b/Makefile.am @@ -0,0 +1,18 @@ +ACLOCAL_AMFLAGS = -I aclocal +ACLOCAL_FILES = aclocal/version.m4 aclocal/pspdev.m4 aclocal/ac_doxygen.m4 + +SUBDIRS = src tools + +include aminclude.am + +MOSTLYCLEANFILES = $(DX_CLEANFILES) + +EXTRA_DIST = \ + $(ACLOCAL_FILES) \ + LICENSE \ + VERSION \ + $(DX_CONFIG) \ + doc/html + +dist-hook: + rm -rf `find $(distdir)/doc/html/* -name .svn -o -name CVS` diff --git a/README b/README new file mode 100644 index 00000000..9c039dfc --- /dev/null +++ b/README @@ -0,0 +1,216 @@ + PSP Software Development Kit + Version 1.0+beta2 + http://www.pspdev.org/ + + +Introduction + + The PSP Software Development Kit (PSPSDK) is a collection of Open Source +tools and libraries written for Sony's Playstation Portable (PSP) gaming +console. It also includes documentation and other resources developers can +use to write software for the PSP. + + PSPSDK is distributed under a BSD-compatible license. See the LICENSE +file for more information. + + +Features + + PSPSDK provides a full set of libraries for creating PSP software: + + * Stub libraries and headers for interfacing with the PSP operating + system, ranging from threading libraries, file io, display driver + and wifi networking. + * Basic runtime support (crt0) for executables and libraries. + * A minimal port of the Standard C Library (libc) is included. PSPSDK's + mini-libc provides portable memory allocation, string formatting, and + several other Standard C Library functions. + * Support code for linking with the full Standard C Library provided with + the PSPDEV toolchain. + * An implementation of the libGU graphics library. libGU provides an + interface to the 2D and 3D hardware acceleration features found in the + PSP's Graphic Engine. + * An implementation of the libGUM library. libGUM provides an interface + for manipulating matrices for use in 3D software. + * A simple audio library which can be used to play back PCM audio streams. + * Support for building static executables and PRX files (relocatable + modules). + + PSPSDK also includes several tools to assist in building PSP software: + + * bin2c, bin2o, and bin2s for converting binary files into C source, + object files, and assembler source files, respectively. + * mksfo for creating PARAM.SFO files. + * pack-pbp and unpack-pbp for adding files to and removing files from + EBOOT.PBP. + * psp-config for locating PSPDEV tools and libraries. + * psp-prxgen for converting specially made ELFs to PRX files. + * psp-build-exports for creating export tables + * psp-fixup-imports for fixing up import tables post-linking to remove + unused functions from the executable. + + Documentation for the libraries are also provided, and can be found in the +doc/ directory of the PSPSDK source and binary distributions. + + A library for Make (build.mak) is also included to provide an easy way to +build simple programs and libraries. See any PSPSDK sample program for +details on how build.mak is used. + + +Installation + + PSPSDK is distributed in both source and binary packages. If you only +want to use the PSPSDK tools and libraries to develop your software you'll +want to grab the binary distribution of PSPSDK specific to your development +platform. If you need fine-grained control over how PSPSDK is installed on +your system, or if you would like to modify PSPSDK then grab the source +distribution. You can also install PSPSDK from Subversion, see "Installation +from Subversion" below for details. + + Requirements + + To use PSPSDK you must have the following software installed: + + * The PSPDEV Toolchain. PSPSDK requires the GNU toolchain (GCC and + binutils) targetted to the PSP. You can find binary packages of these + tools at http://www.pspdev.org/. You can find a script to build and + install the toolchain at http://www.oopo.net/consoledev/. + + In addition to the above requirements, if you plan on building PSPSDK from +source, you will need: + + * Make. Note: GNU Make may not be required, but if you run into problems + building from source you may want to install it. You can find GNU Make + at http://www.gnu.org/software/make/. + + If you plan on building PSPSDK directly from the Subversion repository you +will need: + + * A Subversion client. A popular client for Windows is TortoiseSVN + (http://tortoisesvn.tigris.org/). + * GNU autotools. You will need a recent version of autoconf + (http://www.gnu.org/software/autoconf/) and automake + (http://sourceware.org/automake/). + + The following packages are not required to build PSPSDK, but are used to +build documentation and other optional resources: + + * Doxygen. You can find Doxygen at http://www.stack.nl/~dimitri/doxygen/. + If you want to view the pretty source dependency graphs, then you will + also need to install Graphviz (http://www.graphviz.org/). + + Installation from binary + + Download the PSPSDK binary package specific to your development system. +For example, if you are using Windows, you will want to download the file +pspsdk-1.0-win32.zip. + + Extract or unzip the package into the folder where the PSPDEV toolchain is +installed. For example, on a Windows system you may have installed the PSPDEV +toolchain to C:\pspdev. You would then unzip PSPSDK into C:\pspdev. + + Update your PATH environment variable to point to the PSPSDK tools +directory. In the above example, if you installed PSPSDK to C:\pspdev, you +would add C:\pspdev\bin to your PATH. + + Installation from source + + PSPSDK uses the GNU autotools (autoconf and automake) for its build +system. To install PSPSDK from a source distribution, run the following +commands after unpacking it: + + ./configure + make + make doxygen-doc + make install + + If you haven't installed Doxygen or don't want to build the library +documentation, you can skip the + + Installation from Subversion + + PSPSDK can be found in the Subversion repository located at +svn://svn.pspdev.org/psp. If you are using the command line version of the +Subversion client, you can the following command to download PSPSDK: + + svn co svn://svn.pspdev.org/psp/trunk/pspsdk + + Once you've downloaded PSPSDK, run the following from the pspsdk directory +to create the configure script and support files (you must have autoconf and +automake installed): + + ./bootstrap + + You can now run the commands listed in the "Installation from source" +section. + + +Notes + + * This is a BETA release of PSPSDK. Some of the features and tools + described here may not be fully implemented. + + * By default PSPSDK will install into the directory where the PSPDEV + toolchain is installed. If you decide to install PSPSDK somewhere else + then you must define a PSPSDK environment variable that points to your + alternate directory. The psp-config build utility will look for PSPSDK + in the location specified in the PSPSDK environment variable first, or + use its own location to determine where PSPSDK is installed. + + * The Makefile templates provided by the sample code are designed for + building a single executable or a library, but not both. If you plan on + using these templates in your project to build both libraries + and executables be aware that you will have to structure your project so + that each library and executable are built in a seperate directory. + + +Bugs + + If you find a bug in PSPSDK, send an e-mail describing the bug to +pspsdk-bugs@lists.ps2dev.org. If possible, include any code or documentation +that can be used by the PSPSDK developers to recreate the bug. + + +Resources + + Mailing Lists + + pspsdk-bugs@lists.ps2dev.org + + Use this list to report any bugs you find in PSPSDK. To subscribe, send an + empty e-mail message to pspsdk-bugs-subscribe@lists.ps2dev.org. + + For a full list of PSP development mailing lists, see + http://lists.ps2dev.org/. + + Web Forums + + http://forums.ps2dev.org/ + + The PSP development forums are an excellent place to find out about the + latest PSP homebrew games, demos, and other software. PSPSDK has it's own + dedicated forum titled 'PSPSDK Support and Development'. Use this forum to + find out about the most recent PSPSDK developments and to ask questions + about PSPSDK. + + Subversion + + svn://svn.pspdev.org/ + http://svn.pspdev.org/ + + PSPDEV tools and libraries can be found in the psp/ repository at + svn://svn.pspdev.org/. PSP homebrew games, demos, and other applications + can be found in the pspware/ repository located at the same URL. To view + the contents of these repositories using a Web browser, visit + http://svn.pspdev.org/. + + Internet Relay Chat (IRC) + + The PSPSDK developers can be found hanging out in the #pspdev channel + on irc.freenode.net. + +Thanks + The pspsdk developers wish to thank all the people who have contributed + bug fixes, ideas and support for the project. + Also big thanks to nem for kicking off PSP development with all his work, + the original imports system is based on his work in the hello world demo. diff --git a/VERSION b/VERSION new file mode 100644 index 00000000..5519b6c2 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +1.0+beta2 diff --git a/aclocal/ac_doxygen.m4 b/aclocal/ac_doxygen.m4 new file mode 100644 index 00000000..e9c56c20 --- /dev/null +++ b/aclocal/ac_doxygen.m4 @@ -0,0 +1,312 @@ +# This file is part of Autoconf. -*- Autoconf -*- + +# Copyright (C) 2004 Oren Ben-Kiki +# This file is distributed under the same terms as the Autoconf macro files. + +# Generate automatic documentation using Doxygen. Works in concert with the +# aminclude.m4 file and a compatible doxygen configuration file. Defines the +# following public macros: +# +# DX_???_FEATURE(ON|OFF) - control the default setting fo a Doxygen feature. +# Supported features are 'DOXYGEN' itself, 'DOT' for generating graphics, +# 'HTML' for plain HTML, 'CHM' for compressed HTML help (for MS users), 'CHI' +# for generating a seperate .chi file by the .chm file, and 'MAN', 'RTF', +# 'XML', 'PDF' and 'PS' for the appropriate output formats. The environment +# variable DOXYGEN_PAPER_SIZE may be specified to override the default 'a4wide' +# paper size. +# +# By default, HTML, PDF and PS documentation is generated as this seems to be +# the most popular and portable combination. MAN pages created by Doxygen are +# usually problematic, though by picking an appropriate subset and doing some +# massaging they might be better than nothing. CHM and RTF are specific for MS +# (note that you can't generate both HTML and CHM at the same time). The XML is +# rather useless unless you apply specialized post-processing to it. +# +# The macro mainly controls the default state of the feature. The use can +# override the default by specifying --enable or --disable. The macros ensure +# that contradictory flags are not given (e.g., --enable-doxygen-html and +# --enable-doxygen-chm, --enable-doxygen-anything with --disable-doxygen, etc.) +# Finally, each feature will be automatically disabled (with a warning) if the +# required programs are missing. +# +# Once all the feature defaults have been specified, call DX_INIT_DOXYGEN with +# the following parameters: a one-word name for the project for use as a +# filename base etc., an optional configuration file name (the default is +# 'Doxyfile', the same as Doxygen's default), and an optional output directory +# name (the default is 'doxygen-doc'). + +## ----------## +## Defaults. ## +## ----------## + +DX_ENV="" +AC_DEFUN([DX_FEATURE_doc], ON) +AC_DEFUN([DX_FEATURE_dot], ON) +AC_DEFUN([DX_FEATURE_man], OFF) +AC_DEFUN([DX_FEATURE_html], ON) +AC_DEFUN([DX_FEATURE_chm], OFF) +AC_DEFUN([DX_FEATURE_chi], OFF) +AC_DEFUN([DX_FEATURE_rtf], OFF) +AC_DEFUN([DX_FEATURE_xml], OFF) +AC_DEFUN([DX_FEATURE_pdf], ON) +AC_DEFUN([DX_FEATURE_ps], ON) + +## --------------- ## +## Private macros. ## +## --------------- ## + +# DX_ENV_APPEND(VARIABLE, VALUE) +# ------------------------------ +# Append VARIABLE="VALUE" to DX_ENV for invoking doxygen. +AC_DEFUN([DX_ENV_APPEND], [AC_SUBST([DX_ENV], ["$DX_ENV $1='$2'"])]) + +# DX_DIRNAME_EXPR +# --------------- +# Expand into a shell expression prints the directory part of a path. +AC_DEFUN([DX_DIRNAME_EXPR], + [[expr ".$1" : '\(\.\)[^/]*$' \| "x$1" : 'x\(.*\)/[^/]*$']]) + +# DX_IF_FEATURE(FEATURE, IF-ON, IF-OFF) +# ------------------------------------- +# Expands according to the M4 (static) status of the feature. +AC_DEFUN([DX_IF_FEATURE], [ifelse(DX_FEATURE_$1, ON, [$2], [$3])]) + +# DX_REQUIRE_PROG(VARIABLE, PROGRAM) +# ---------------------------------- +# Require the specified program to be found for the DX_CURRENT_FEATURE to work. +AC_DEFUN([DX_REQUIRE_PROG], [ +AC_PATH_TOOL([$1], [$2]) +if test "$DX_FLAG_[]DX_CURRENT_FEATURE$$1" = 1; then + AC_MSG_WARN([$2 not found - will not DX_CURRENT_DESCRIPTION]) + AC_SUBST([DX_FLAG_]DX_CURRENT_FEATURE, 0) +fi +]) + +# DX_TEST_FEATURE(FEATURE) +# ------------------------ +# Expand to a shell expression testing whether the feature is active. +AC_DEFUN([DX_TEST_FEATURE], [test "$DX_FLAG_$1" = 1]) + +# DX_CHECK_DEPEND(REQUIRED_FEATURE, REQUIRED_STATE) +# ------------------------------------------------- +# Verify that a required features has the right state before trying to turn on +# the DX_CURRENT_FEATURE. +AC_DEFUN([DX_CHECK_DEPEND], [ +test "$DX_FLAG_$1" = "$2" \ +|| AC_MSG_ERROR([doxygen-DX_CURRENT_FEATURE ifelse([$2], 1, + requires, contradicts) doxygen-DX_CURRENT_FEATURE]) +]) + +# DX_CLEAR_DEPEND(FEATURE, REQUIRED_FEATURE, REQUIRED_STATE) +# ---------------------------------------------------------- +# Turn off the DX_CURRENT_FEATURE if the required feature is off. +AC_DEFUN([DX_CLEAR_DEPEND], [ +test "$DX_FLAG_$1" = "$2" || AC_SUBST([DX_FLAG_]DX_CURRENT_FEATURE, 0) +]) + +# DX_FEATURE_ARG(FEATURE, DESCRIPTION, +# CHECK_DEPEND, CLEAR_DEPEND, +# REQUIRE, DO-IF-ON, DO-IF-OFF) +# -------------------------------------------- +# Parse the command-line option controlling a feature. CHECK_DEPEND is called +# if the user explicitly turns the feature on (and invokes DX_CHECK_DEPEND), +# otherwise CLEAR_DEPEND is called to turn off the default state if a required +# feature is disabled (using DX_CLEAR_DEPEND). REQUIRE performs additional +# requirement tests (DX_REQUIRE_PROG). Finally, an automake flag is set and +# DO-IF-ON or DO-IF-OFF are called according to the final state of the feature. +AC_DEFUN([DX_ARG_ABLE], [ + AC_DEFUN([DX_CURRENT_FEATURE], [$1]) + AC_DEFUN([DX_CURRENT_DESCRIPTION], [$2]) + AC_ARG_ENABLE(doxygen-$1, + [AS_HELP_STRING(DX_IF_FEATURE([$1], [--disable-doxygen-$1], + [--enable-doxygen-$1]), + DX_IF_FEATURE([$1], [don't $2], [$2]))], + [ +case "$enableval" in +#( +y|Y|yes|Yes|YES) + AC_SUBST([DX_FLAG_$1], 1) + $3 +;; #( +n|N|no|No|NO) + AC_SUBST([DX_FLAG_$1], 0) +;; #( +*) + AC_MSG_ERROR([invalid value '$enableval' given to doxygen-$1]) +;; +esac +], [ +AC_SUBST([DX_FLAG_$1], [DX_IF_FEATURE([$1], 1, 0)]) +$4 +]) +if DX_TEST_FEATURE([$1]); then + $5 + : +fi +if DX_TEST_FEATURE([$1]); then + AM_CONDITIONAL(DX_COND_$1, :) + $6 + : +else + AM_CONDITIONAL(DX_COND_$1, false) + $7 + : +fi +]) + +## -------------- ## +## Public macros. ## +## -------------- ## + +# DX_XXX_FEATURE(DEFAULT_STATE) +# ----------------------------- +AC_DEFUN([DX_DOXYGEN_FEATURE], [AC_DEFUN([DX_FEATURE_doc], [$1])]) +AC_DEFUN([DX_MAN_FEATURE], [AC_DEFUN([DX_FEATURE_man], [$1])]) +AC_DEFUN([DX_HTML_FEATURE], [AC_DEFUN([DX_FEATURE_html], [$1])]) +AC_DEFUN([DX_CHM_FEATURE], [AC_DEFUN([DX_FEATURE_chm], [$1])]) +AC_DEFUN([DX_CHI_FEATURE], [AC_DEFUN([DX_FEATURE_chi], [$1])]) +AC_DEFUN([DX_RTF_FEATURE], [AC_DEFUN([DX_FEATURE_rtf], [$1])]) +AC_DEFUN([DX_XML_FEATURE], [AC_DEFUN([DX_FEATURE_xml], [$1])]) +AC_DEFUN([DX_XML_FEATURE], [AC_DEFUN([DX_FEATURE_xml], [$1])]) +AC_DEFUN([DX_PDF_FEATURE], [AC_DEFUN([DX_FEATURE_pdf], [$1])]) +AC_DEFUN([DX_PS_FEATURE], [AC_DEFUN([DX_FEATURE_ps], [$1])]) + +# DX_INIT_DOXYGEN(PROJECT, [CONFIG-FILE], [OUTPUT-DOC-DIR]) +# --------------------------------------------------------- +# PROJECT also serves as the base name for the documentation files. +# The default CONFIG-FILE is "Doxyfile" and OUTPUT-DOC-DIR is "doxygen-doc". +AC_DEFUN([DX_INIT_DOXYGEN], [ + +# Files: +AC_SUBST([DX_PROJECT], [$1]) +AC_SUBST([DX_CONFIG], [ifelse([$2], [], Doxyfile, [$2])]) +AC_SUBST([DX_DOCDIR], [ifelse([$3], [], doxygen-doc, [$3])]) + +# Environment variables used inside doxygen.cfg: +DX_ENV_APPEND(SRCDIR, $srcdir) +DX_ENV_APPEND(PROJECT, $DX_PROJECT) +DX_ENV_APPEND(DOCDIR, $DX_DOCDIR) +DX_ENV_APPEND(VERSION, $PACKAGE_VERSION) + +# Doxygen itself: +DX_ARG_ABLE(doc, [generate any doxygen documentation], + [], + [], + [DX_REQUIRE_PROG([DX_DOXYGEN], doxygen) + DX_REQUIRE_PROG([DX_PERL], perl)], + [DX_ENV_APPEND(PERL_PATH, $DX_PERL)]) + +# Dot for graphics: +DX_ARG_ABLE(dot, [generate graphics for doxygen documentation], + [DX_CHECK_DEPEND(doc, 1)], + [DX_CLEAR_DEPEND(doc, 1)], + [DX_REQUIRE_PROG([DX_DOT], dot)], + [DX_ENV_APPEND(HAVE_DOT, YES) + DX_ENV_APPEND(DOT_PATH, [`DX_DIRNAME_EXPR($DX_DOT)`])], + [DX_ENV_APPEND(HAVE_DOT, NO)]) + +# Man pages generation: +DX_ARG_ABLE(man, [generate doxygen manual pages], + [DX_CHECK_DEPEND(doc, 1)], + [DX_CLEAR_DEPEND(doc, 1)], + [], + [DX_ENV_APPEND(GENERATE_MAN, YES)], + [DX_ENV_APPEND(GENERATE_MAN, NO)]) + +# RTF file generation: +DX_ARG_ABLE(rtf, [generate doxygen RTF documentation], + [DX_CHECK_DEPEND(doc, 1)], + [DX_CLEAR_DEPEND(doc, 1)], + [], + [DX_ENV_APPEND(GENERATE_RTF, YES)], + [DX_ENV_APPEND(GENERATE_RTF, NO)]) + +# XML file generation: +DX_ARG_ABLE(xml, [generate doxygen XML documentation], + [DX_CHECK_DEPEND(doc, 1)], + [DX_CLEAR_DEPEND(doc, 1)], + [], + [DX_ENV_APPEND(GENERATE_XML, YES)], + [DX_ENV_APPEND(GENERATE_XML, NO)]) + +# (Compressed) HTML help generation: +DX_ARG_ABLE(chm, [generate doxygen compressed HTML help documentation], + [DX_CHECK_DEPEND(doc, 1)], + [DX_CLEAR_DEPEND(doc, 1)], + [DX_REQUIRE_PROG([DX_HHC], hhc)], + [DX_ENV_APPEND(HHC_PATH, $DX_HHC) + DX_ENV_APPEND(GENERATE_HTML, YES) + DX_ENV_APPEND(GENERATE_HTMLHELP, YES)], + [DX_ENV_APPEND(GENERATE_HTMLHELP, NO)]) + +# Seperate CHI file generation. +DX_ARG_ABLE(chi, [generate doxygen seperate compressed HTML help index file], + [DX_CHECK_DEPEND(chm, 1)], + [DX_CLEAR_DEPEND(chm, 1)], + [], + [DX_ENV_APPEND(GENERATE_CHI, YES)], + [DX_ENV_APPEND(GENERATE_CHI, NO)]) + +# Plain HTML pages generation: +DX_ARG_ABLE(html, [generate doxygen plain HTML documentation], + [DX_CHECK_DEPEND(doc, 1) DX_CHECK_DEPEND(chm, 0)], + [DX_CLEAR_DEPEND(doc, 1) DX_CLEAR_DEPEND(chm, 0)], + [], + [DX_ENV_APPEND(GENERATE_HTML, YES)], + [DX_TEST_FEATURE(chm) || DX_ENV_APPEND(GENERATE_HTML, NO)]) + +# PostScript file generation: +DX_ARG_ABLE(ps, [generate doxygen PostScript documentation], + [DX_CHECK_DEPEND(doc, 1)], + [DX_CLEAR_DEPEND(doc, 1)], + [DX_REQUIRE_PROG([DX_LATEX], latex) + DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex) + DX_REQUIRE_PROG([DX_DVIPS], dvips) + DX_REQUIRE_PROG([DX_EGREP], egrep)]) + +# PDF file generation: +DX_ARG_ABLE(pdf, [generate doxygen PDF documentation], + [DX_CHECK_DEPEND(doc, 1)], + [DX_CLEAR_DEPEND(doc, 1)], + [DX_REQUIRE_PROG([DX_PDFLATEX], pdflatex) + DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex) + DX_REQUIRE_PROG([DX_EGREP], egrep)]) + +# LaTeX generation for PS and/or PDF: +if DX_TEST_FEATURE(ps) || DX_TEST_FEATURE(pdf); then + AM_CONDITIONAL(DX_COND_latex, :) + DX_ENV_APPEND(GENERATE_LATEX, YES) +else + AM_CONDITIONAL(DX_COND_latex, false) + DX_ENV_APPEND(GENERATE_LATEX, NO) +fi + +# Paper size for PS and/or PDF: +AC_ARG_VAR(DOXYGEN_PAPER_SIZE, + [a4wide (default), a4, letter, legal or executive]) +case "$DOXYGEN_PAPER_SIZE" in +#( +"") + AC_SUBST(DOXYGEN_PAPER_SIZE, "") +;; #( +a4wide|a4|letter|legal|executive) + DX_ENV_APPEND(PAPER_SIZE, $DOXYGEN_PAPER_SIZE) +;; #( +*) + AC_MSG_ERROR([unknown DOXYGEN_PAPER_SIZE='$DOXYGEN_PAPER_SIZE']) +;; +esac + +#For debugging: +#echo DX_FLAG_doc=$DX_FLAG_doc +#echo DX_FLAG_dot=$DX_FLAG_dot +#echo DX_FLAG_man=$DX_FLAG_man +#echo DX_FLAG_html=$DX_FLAG_html +#echo DX_FLAG_chm=$DX_FLAG_chm +#echo DX_FLAG_chi=$DX_FLAG_chi +#echo DX_FLAG_rtf=$DX_FLAG_rtf +#echo DX_FLAG_xml=$DX_FLAG_xml +#echo DX_FLAG_pdf=$DX_FLAG_pdf +#echo DX_FLAG_ps=$DX_FLAG_ps +#echo DX_ENV=$DX_ENV +]) diff --git a/aclocal/pspdev.m4 b/aclocal/pspdev.m4 new file mode 100644 index 00000000..66162627 --- /dev/null +++ b/aclocal/pspdev.m4 @@ -0,0 +1,61 @@ +dnl +dnl AC_PSPDEV_PATH() +dnl +dnl Check for a valid pspdev installation. + +AC_DEFUN([AC_PSPDEV_PATH], +[ + AC_ARG_WITH(pspdev, + [ --with-pspdev=DIR Path where the pspdev toolchain is installed (default is $PSPDEV)], + pspdev="$withval", pspdev="$PSPDEV") + + AC_MSG_CHECKING(for pspdev) + if test x$pspdev = x ; then + # If there's no $PSPDEV environment variable, find out where psp-gcc lives (it should be on the $PATH). + psp_gcc_path=`which psp-gcc` + if test x$psp_gcc_path = x ; then + AC_MSG_ERROR(can't find the pspdev toolchain. Use --with-pspdev or set PSPDEV) + fi + # Strip both the /psp-gcc and /bin portions from the path. + pspdev=`echo $psp_gcc_path | sed 's/\/psp-gcc//' | sed 's/\/bin//'` + fi + AC_MSG_RESULT($pspdev) + + PSPDEV="$pspdev" + AC_SUBST(PSPDEV) + + # Fill out a few common directories for things that need it. + # Note: if we ever decide to support more than just the "psp" prefix, these will have to be updated. + pspdev_includedir="$pspdev/psp/include" + pspdev_libdir="$pspdev/psp/lib" + PSPDEV_INCLUDEDIR="$pspdev_includedir" + PSPDEV_LIBDIR="$pspdev_libdir" + AC_SUBST(PSPDEV_INCLUDEDIR) + AC_SUBST(PSPDEV_LIBDIR) +]) + +dnl Check for a tool prefixed with "psp-". +dnl __PSPDEV_CHECK_TOOL(VARIABLE, PREFIX, PROG-TO-CHECK-FOR[, VALUE-IF-NOT-FOUND [, PATH]]) +AC_DEFUN([__PSPDEV_CHECK_TOOL], +[ + pspdev_tool_prefix="psp-" + AC_CHECK_PROG($1, ${pspdev_tool_prefix}$2, ${pspdev_tool_prefix}$2, $3, $4) +]) + +dnl +dnl AC_PSPDEV_TOOLCHAIN() +dnl +dnl Make sure all of the required pspdev tools exist. +dnl TODO: This could be made more robust just in case someone installs the tools wihthout +dnl the psp- prefix. That's highly unlikely though. + +AC_DEFUN([AC_PSPDEV_TOOLCHAIN], +[ + __PSPDEV_CHECK_TOOL(PSP_CC, gcc, psp-gcc) + __PSPDEV_CHECK_TOOL(PSP_CXX, g++, psp-g++) + __PSPDEV_CHECK_TOOL(PSP_AS, as, psp-as) + __PSPDEV_CHECK_TOOL(PSP_LD, ld, psp-ld) + __PSPDEV_CHECK_TOOL(PSP_AR, ar, psp-ar) + __PSPDEV_CHECK_TOOL(PSP_NM, nm, psp-nm) + __PSPDEV_CHECK_TOOL(PSP_RANLIB, ranlib, psp-ranlib) +]) diff --git a/aclocal/version.m4 b/aclocal/version.m4 new file mode 100644 index 00000000..a8777c5b --- /dev/null +++ b/aclocal/version.m4 @@ -0,0 +1,19 @@ +dnl +dnl AC_PSPSDK_VERSION() +dnl +dnl Determine the pspsdk package version. + +AC_DEFUN([AC_PSPSDK_VERSION], +[ + AC_BEFORE([$0], [AM_INIT_AUTOMAKE]) + + AC_MSG_CHECKING([for pspsdk version]) + AS_IF([test -r "${srcdir}/aclocal/version.m4"], + [], + [AC_MSG_ERROR([Unable to find aclocal/version.m4])]) + AS_IF([test -r "${srcdir}/VERSION"], + [], + [AC_MSG_ERROR([Unable to find VERSION])]) + pspsdk_version=`cat "${srcdir}/VERSION"` + AC_MSG_RESULT($pspsdk_version) +]) diff --git a/aminclude.am b/aminclude.am new file mode 100644 index 00000000..7e8d0323 --- /dev/null +++ b/aminclude.am @@ -0,0 +1,186 @@ +# Copyright (C) 2004 Oren Ben-Kiki +# This file is distributed under the same terms as the Automake macro files. + +# Generate automatic documentation using Doxygen. Goals and variables values +# are controlled by the various DX_COND_??? conditionals set by autoconf. +# +# The provided goals are: +# doxygen-doc: Generate all doxygen documentation. +# doxygen-run: Run doxygen, which will generate some of the documentation +# (HTML, CHM, CHI, MAN, RTF, XML) but will not do the post +# processing required for the rest of it (PS, PDF, and some MAN). +# doxygen-man: Rename some doxygen generated man pages. +# doxygen-ps: Generate doxygen PostScript documentation. +# doxygen-pdf: Generate doxygen PDF documentation. +# +# Note that by default these are not integrated into the automake goals. If +# doxygen is used to generate man pages, you can achieve this integration by +# setting man3_MANS to the list of man pages generated and then adding the +# dependency: +# +# $(man3_MANS): doxygen-doc +# +# This will cause make to run doxygen and generate all the documentation. +# +# The following variable is intended for use in Makefile.am: +# +# DX_CLEANFILES = everything to clean. +# +# This is usually added to MOSTLYCLEANFILES. + +## --------------------------------- ## +## Format-independent Doxygen rules. ## +## --------------------------------- ## + +if DX_COND_doc + +## ------------------------------- ## +## Rules specific for HTML output. ## +## ------------------------------- ## + +if DX_COND_html + +DX_CLEAN_HTML = @DX_DOCDIR@/html + +endif DX_COND_html + +## ------------------------------ ## +## Rules specific for CHM output. ## +## ------------------------------ ## + +if DX_COND_chm + +DX_CLEAN_CHM = @DX_DOCDIR@/chm + +if DX_COND_chi + +DX_CLEAN_CHI = @DX_DOCDIR@/@PACKAGE@.chi + +endif DX_COND_chi + +endif DX_COND_chm + +## ------------------------------ ## +## Rules specific for MAN output. ## +## ------------------------------ ## + +if DX_COND_man + +DX_CLEAN_MAN = @DX_DOCDIR@/man + +endif DX_COND_man + +## ------------------------------ ## +## Rules specific for RTF output. ## +## ------------------------------ ## + +if DX_COND_rtf + +DX_CLEAN_RTF = @DX_DOCDIR@/rtf + +endif DX_COND_rtf + +## ------------------------------ ## +## Rules specific for XML output. ## +## ------------------------------ ## + +if DX_COND_xml + +DX_CLEAN_XML = @DX_DOCDIR@/xml + +endif DX_COND_xml + +## ----------------------------- ## +## Rules specific for PS output. ## +## ----------------------------- ## + +if DX_COND_ps + +DX_CLEAN_PS = @DX_DOCDIR@/@PACKAGE@.ps + +DX_PS_GOAL = doxygen-ps + +doxygen-ps: @DX_DOCDIR@/@PACKAGE@.ps + +@DX_DOCDIR@/@PACKAGE@.ps: @DX_DOCDIR@/@PACKAGE@.tag + cd @DX_DOCDIR@/latex; \ + rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \ + $(DX_LATEX) refman.tex; \ + $(MAKEINDEX_PATH) refman.idx; \ + $(DX_LATEX) refman.tex; \ + countdown=5; \ + while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \ + refman.log > /dev/null 2>&1 \ + && test $$countdown -gt 0; do \ + $(DX_LATEX) refman.tex; \ + countdown=`expr $$countdown - 1`; \ + done; \ + $(DX_DVIPS) -o ../@PACKAGE@.ps refman.dvi + +endif DX_COND_ps + +## ------------------------------ ## +## Rules specific for PDF output. ## +## ------------------------------ ## + +if DX_COND_pdf + +DX_CLEAN_PDF = @DX_DOCDIR@/@PACKAGE@.pdf + +DX_PDF_GOAL = doxygen-pdf + +doxygen-pdf: @DX_DOCDIR@/@PACKAGE@.pdf + +@DX_DOCDIR@/@PACKAGE@.pdf: @DX_DOCDIR@/@PACKAGE@.tag + cd @DX_DOCDIR@/latex; \ + rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \ + $(DX_PDFLATEX) refman.tex; \ + $(DX_MAKEINDEX) refman.idx; \ + $(DX_PDFLATEX) refman.tex; \ + countdown=5; \ + while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \ + refman.log > /dev/null 2>&1 \ + && test $$countdown -gt 0; do \ + $(DX_PDFLATEX) refman.tex; \ + countdown=`expr $$countdown - 1`; \ + done; \ + mv refman.pdf ../@PACKAGE@.pdf + +endif DX_COND_pdf + +## ------------------------------------------------- ## +## Rules specific for LaTeX (shared for PS and PDF). ## +## ------------------------------------------------- ## + +if DX_COND_latex + +DX_CLEAN_LATEX = @DX_DOCDIR@/latex + +endif DX_COND_latex + +.PHONY: doxygen-run doxygen-doc $(DX_PS_GOAL) $(DX_PDF_GOAL) + +.INTERMEDIATE: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL) + +doxygen-run: @DX_DOCDIR@/@PACKAGE@.tag + +doxygen-doc: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL) + +@DX_DOCDIR@/@PACKAGE@.tag: $(DX_CONFIG) $(pkginclude_HEADERS) +# rm -rf @DX_DOCDIR@ + $(DX_ENV) $(DX_DOXYGEN) $(srcdir)/$(DX_CONFIG) + +DX_CLEANFILES = \ + @DX_DOCDIR@/@PACKAGE@.tag \ + -r \ + $(DX_CLEAN_HTML) \ + $(DX_CLEAN_CHM) \ + $(DX_CLEAN_CHI) \ + $(DX_CLEAN_MAN) \ + $(DX_CLEAN_RTF) \ + $(DX_CLEAN_XML) \ + $(DX_CLEAN_PS) \ + $(DX_CLEAN_PDF) \ + $(DX_CLEAN_LATEX) + +endif DX_COND_doc diff --git a/bootstrap b/bootstrap new file mode 100755 index 00000000..d7ed407f --- /dev/null +++ b/bootstrap @@ -0,0 +1,137 @@ +#!/bin/sh +# PSP Software Development Kit - http://www.pspdev.org +# ----------------------------------------------------------------------- +# Licensed under the BSD license, see LICENSE in PSPSDK root for details. +# +# bootstrap - Script to bootstrap GNU autoconf and GNU automake. +# Inspired by libtool's autogen script. +# +# Copyright (c) 2005 Marcus R. Brown +# Copyright (c) 2005 James Forshaw +# Copyright (c) 2005 John Kelley +#$Id: bootstrap 444 2005-07-03 20:34:12Z mrbrown $ + +progname=`basename $0` +top_srcdir=`dirname $0` + +verbose=""; +quiet="false" +mode="generate" + +usage() +{ + echo + echo "usage: ${progname} [-h|-q|-v|-c]" + echo + echo "options:" + echo " -h .. display this message and exit"; + echo " -q .. quiet, don't display directories"; + echo " -v .. verbose, pass -v to automake when invoking automake" + echo " -c .. clean, remove all aclocal/autoconf/automake generated files" + echo + exit 1; +} + +if test ! -f $top_srcdir/VERSION; then + echo "${progname}:" + echo " Installation problem: Can't find file VERSION" + exit 1; +fi + +while test $# -gt 0; do +case $1 in +-h|--he|--hel|--help) + usage ;; +-q|--qu|--qui|--quie|--quiet) + quiet="true"; + shift;; +-v|--ve|--ver|--verb|--verbo|--verbos|--verbose) + verbose="-v"; + shift;; +-c|--cl|--cle|--clea|--clean) + mode="clean"; + shift;; +-*) echo "unknown option $1" ; + usage ;; +*) echo "invalid parameter $1" ; + usage ;; +esac +done + +case $mode in +generate) + + case $top_srcdir in + /* ) aclocal_dir=$top_srcdir + ;; + *) aclocal_dir=`pwd`/$top_srcdir + ;; + esac + + confs=`find . \( -name 'configure.in' -o -name 'configure.ac' \) -print` + for i in $confs; do + dir=`dirname $i`; + configure=`basename $i`; + ( test "$quiet" = "true" || echo "$dir"; + cd $dir; + pat="s,\$(TOPdir),${aclocal_dir},g" + aclocal_args=`grep '^[ ]*ACLOCAL_AMFLAGS' Makefile.am | \ + sed -e 's%.*ACLOCAL_AMFLAGS.*\=[ ]*%%g' -e $pat ` ; + test "$verbose" = "-v" && echo "aclocal $aclocal_args" + aclocal $aclocal_args; + test -n "`grep CONFIG_HEADER ${configure}`" && autoheader \ + && test "$verbose" = "-v" && echo "autoheader"; + test -f Makefile.am && automake -a -c --foreign $verbose ; + test "$verbose" = "-v" && echo "autoconf"; + autoconf; + test -f Makefile.am && test -n "`grep 'stamp-h\.in' Makefile.in`" \ + && echo timestamp > stamp-h.in + ) + done + + # HACK: Fixup the version in the generated configure script. This would be less of + # hack if it wasn't pspsdk-specific. I'm doing this because I don't want to look + # into how to do it the autoconf way. + version=`cat "$top_srcdir/VERSION"` + cat configure | sed "s/PSPSDK_VERSION/$version/g" > configure.out + cp configure.out configure + rm -f configure.out + ;; + +clean) + test "$quiet" = "true" || echo "removing automake generated Makefile.in files" + files=`find . -name 'Makefile.am' -print | sed -e 's%\.am%\.in%g'` ; + for i in $files; do if test -f $i; then + rm -f $i + test "$verbose" = "-v" && echo "$i" + fi; done + + test "$quiet" = "true" || echo "removing configure files" + files=`find . -name 'configure' -print` ; + test "$verbose" = "-v" && test -n "$files" && echo "$files" ; + for i in $files; do if test -f $i; then + rm -f $i config.guess config.sub depcomp install-sh mdate-sh missing \ + mkinstalldirs texinfo.tex + test "$verbose" = "-v" && echo "$i" + fi; done + + test "$quiet" = "true" || echo "removing aclocal.m4 files" + files=`find . -name 'aclocal.m4' -print` ; + test "$verbose" = "-v" && test -n "$files" && echo "$files" ; + for i in $files; do if test -f $i; then + rm -f $i + test "$verbose" = "-v" && echo "$i" + fi; done + + find . -name '*~' -print | xargs rm -f + find . -name '*.orig' -print | xargs rm -f + find . -name '*.rej' -print | xargs rm -f + find . -name 'config.status' -print | xargs rm -f + find . -name 'config.log' -print | xargs rm -f + find . -name 'config.cache' -print | xargs rm -f + find . -name 'Makefile' -print | xargs rm -f + find . -name '.deps' -print | xargs rm -rf + find . -name '.libs' -print | xargs rm -rf + find . -name 'stamp-h.in' | xargs rm -rf + ;; +esac diff --git a/config.h.in b/config.h.in new file mode 100644 index 00000000..e0b21e82 --- /dev/null +++ b/config.h.in @@ -0,0 +1,81 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the `getcwd' function. */ +#undef HAVE_GETCWD + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if your system has a GNU libc compatible `malloc' function, and + to 0 otherwise. */ +#undef HAVE_MALLOC + +/* Define to 1 if you have the header file. */ +#undef HAVE_MALLOC_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strchr' function. */ +#undef HAVE_STRCHR + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Toplevel directory where PSPSDK will be installed, relative to $prefix */ +#undef PSPSDK_TOPDIR + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION + +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +#undef WORDS_BIGENDIAN + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to rpl_malloc if the replacement function should be used. */ +#undef malloc diff --git a/configure.ac b/configure.ac new file mode 100644 index 00000000..4952d86b --- /dev/null +++ b/configure.ac @@ -0,0 +1,118 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ(2.59) +AC_INIT([pspsdk], [PSPSDK_VERSION], []) +AC_CONFIG_SRCDIR([tools/bin2c.c]) +AC_CONFIG_HEADER([config.h]) +AC_PSPSDK_VERSION +AC_PSPDEV_PATH + +AM_INIT_AUTOMAKE([pspsdk], [PSPSDK_VERSION]) + +# Checks for programs. +AC_PSPDEV_TOOLCHAIN +AC_PROG_CC +# These will actually be overridden by the psp-specific counterparts. They are +# here mainly to shut automake up. +AC_PROG_CXX +AM_PROG_AS +AC_PROG_RANLIB + +# Checks for libraries. + +# Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS([fcntl.h malloc.h stdlib.h string.h unistd.h]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_C_BIGENDIAN + +# Checks for library functions. +AC_FUNC_MALLOC +AC_FUNC_MEMCMP +AC_CHECK_FUNCS([getcwd strchr]) + +# Doxygen. +DX_HTML_FEATURE(ON) +DX_CHM_FEATURE(OFF) +DX_CHI_FEATURE(OFF) +DX_MAN_FEATURE(OFF) +DX_RTF_FEATURE(OFF) +DX_XML_FEATURE(OFF) +DX_PDF_FEATURE(OFF) +DX_PS_FEATURE(OFF) +DX_INIT_DOXYGEN(pspsdk, doxygen.cfg, doc) + +# Override the default prefix to point to where the pspdev tools should be installed. +# The binaries will end up in $prefix/bin, but pspsdk itself will end up in $prefix/$target/sdk. +# TODO: We should see if the user will ever want to override this. +prefix="$pspdev" +psp_targetdir="psp" + +# Create the pspsdk installation paths. +pspsdk_topdir="$psp_targetdir/sdk" +pspsdk="$prefix/$pspsdk_topdir" +pspsdk_includedir="$pspsdk/include" +pspsdk_libdir="$pspsdk/lib" +PSPSDK="$pspsdk" +PSPSDK_INCLUDEDIR="$pspsdk_includedir" +PSPSDK_LIBDIR="$pspsdk_libdir" +AC_DEFINE_UNQUOTED(PSPSDK_TOPDIR, ["$pspsdk_topdir"], + [Toplevel directory where PSPSDK will be installed, relative to $prefix]) +AC_SUBST(PSPSDK) +AC_SUBST(PSPSDK_INCLUDEDIR) +AC_SUBST(PSPSDK_LIBDIR) + +# CFLAGS and CXXFLAGS used to build pspsdk libraries. +PSPSDK_CFLAGS="$CFLAGS -G0 -Wall" +PSPSDK_CXXFLAGS="$PSPSDK_CFLAGS -fno-exceptions -fno-rtti" +AC_SUBST(PSPSDK_CFLAGS) +AC_SUBST(PSPSDK_CXXFLAGS) + +# Turn on all warnings (for host programs). +if test x$ac_compiler_gnu = xyes; then + CFLAGS="$CFLAGS -Wall" +fi + +AC_CONFIG_FILES([Makefile + src/Makefile + src/atrac3/Makefile + src/audio/Makefile + src/base/Makefile + src/base/linkfile.prx + src/ctrl/Makefile + src/debug/Makefile + src/display/Makefile + src/fpu/Makefile + src/ge/Makefile + src/gu/Makefile + src/gum/Makefile + src/hprm/Makefile + src/kernel/Makefile + src/libc/Makefile + src/mp3/Makefile + src/mpeg/Makefile + src/nand/Makefile + src/net/Makefile + src/openpsid/Makefile + src/power/Makefile + src/prof/Makefile + src/registry/Makefile + src/rtc/Makefile + src/sircs/Makefile + src/sdk/Makefile + src/startup/Makefile + src/umd/Makefile + src/usb/Makefile + src/usbstor/Makefile + src/user/Makefile + src/utility/Makefile + src/vfpu/Makefile + src/video/Makefile + src/vsh/Makefile + src/wlan/Makefile + src/samples/Makefile + tools/Makefile]) +AC_OUTPUT diff --git a/doxygen.cfg b/doxygen.cfg new file mode 100644 index 00000000..27cbcd89 --- /dev/null +++ b/doxygen.cfg @@ -0,0 +1,1226 @@ +# Doxyfile 1.4.3-20050530 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = $(PROJECT)-$(VERSION) + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = $(DOCDIR) + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, +# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, +# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, +# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, +# Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# This tag can be used to specify the encoding used in the generated output. +# The encoding is not always determined by the language that is chosen, +# but also whether or not the output is meant for Windows or non-Windows users. +# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES +# forces the Windows encoding (this is the default for the Windows binary), +# whereas setting the tag to NO uses a Unix-style encoding (the default for +# all platforms other than Windows). + +USE_WINDOWS_ENCODING = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = $(SRCDIR) + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = $(SRCDIR) + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = YES + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = YES + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources +# only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. + +SHOW_DIRECTORIES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from the +# version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the progam writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = YES + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = $(SRCDIR) + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. + +EXCLUDE_PATTERNS = */samples/* + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = $(SRCDIR) + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = $(GENERATE_HTML) + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = $(GENERATE_CHM) + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = ../$(PROJECT).chm + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = $(HHC_PATH) + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = $(GENERATE_CHI) + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = YES + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = $(GENERATE_LATEX) + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = $(PAPER_SIZE) + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = $(GENERATE_RTF) + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = $(GENERATE_MAN) + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = $(GENERATE_XML) + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_PREDEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = $(DOCDIR)/$(PROJECT).tag + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = $(PERL_PATH) + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = $(HAVE_DOT) + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = $(DOT_PATH) + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that a graph may be further truncated if the graph's +# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH +# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), +# the graph is not depth-constrained. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, which results in a white background. +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 00000000..a9ddecbd --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,36 @@ +SUBDIRS = \ + atrac3 \ + audio \ + base \ + ctrl \ + debug \ + display \ + fpu \ + ge \ + gu \ + gum \ + hprm \ + kernel \ + libc \ + mp3 \ + mpeg \ + nand \ + net \ + openpsid \ + power \ + prof \ + registry \ + rtc \ + sircs \ + sdk \ + startup \ + umd \ + usb \ + usbstor \ + user \ + utility \ + vfpu \ + video \ + vsh \ + wlan \ + samples diff --git a/src/atrac3/Makefile.am b/src/atrac3/Makefile.am new file mode 100644 index 00000000..40c8f41e --- /dev/null +++ b/src/atrac3/Makefile.am @@ -0,0 +1,23 @@ + +libdir = @PSPSDK_LIBDIR@ + +CC = @PSP_CC@ +CCAS = $(CC) +AR = @PSP_AR@ +RANLIB = @PSP_RANLIB@ + +INCLUDES = -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel +CFLAGS = @PSPSDK_CFLAGS@ +CCASFLAGS = $(CFLAGS) -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel + +ATRAC3_OBJS = sceAtrac3plus_0000.o sceAtrac3plus_0001.o sceAtrac3plus_0002.o sceAtrac3plus_0003.o sceAtrac3plus_0004.o sceAtrac3plus_0005.o sceAtrac3plus_0006.o sceAtrac3plus_0007.o sceAtrac3plus_0008.o sceAtrac3plus_0009.o sceAtrac3plus_0010.o sceAtrac3plus_0011.o sceAtrac3plus_0012.o sceAtrac3plus_0013.o sceAtrac3plus_0014.o sceAtrac3plus_0015.o sceAtrac3plus_0016.o sceAtrac3plus_0017.o sceAtrac3plus_0018.o sceAtrac3plus_0019.o sceAtrac3plus_0020.o sceAtrac3plus_0021.o sceAtrac3plus_0022.o sceAtrac3plus_0023.o sceAtrac3plus_0024.o sceAtrac3plus_0025.o + +libpspatrac3includedir = @PSPSDK_INCLUDEDIR@ +libpspatrac3include_HEADERS = pspatrac3.h + +lib_LIBRARIES = libpspatrac3.a +libpspatrac3_a_SOURCES = sceAtrac3plus.S +libpspatrac3_a_LIBADD = $(ATRAC3_OBJS) + +$(ATRAC3_OBJS): sceAtrac3plus.S + $(COMPILE) -DF_$* $< -c -o $@ diff --git a/src/atrac3/pspatrac3.h b/src/atrac3/pspatrac3.h new file mode 100644 index 00000000..dd381cee --- /dev/null +++ b/src/atrac3/pspatrac3.h @@ -0,0 +1,139 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspatrac3.h - Prototypes for the sceAtrac3plus library + * + * Copyright (c) 2006 moonlight + * + * $Id: pspatrac3.h 2433 2008-10-15 10:00:27Z iwn $ + */ +#ifndef __LIBATRAC3_H__ +#define __LIBATRAC3_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Creates a new Atrac ID from the specified data + * + * @param buf - the buffer holding the atrac3 data, including the RIFF/WAVE header. + * @param bufsize - the size of the buffer pointed by buf + * + * @return the new atrac ID, or < 0 on error +*/ +int sceAtracSetDataAndGetID(void *buf, SceSize bufsize); + +/** + * Decode a frame of data. + * + * @param atracID - the atrac ID + * @param outSamples - pointer to a buffer that receives the decoded data of the current frame + * @param outN - pointer to a integer that receives the number of audio samples of the decoded frame + * @param outEnd - pointer to a integer that receives a boolean value indicating if the decoded frame is the last one + * @param outRemainFrame - pointer to a integer that receives either -1 if all at3 data is already on memory, + * or the remaining (not decoded yet) frames at memory if not all at3 data is on memory + * + * + * @return < 0 on error, otherwise 0 + * +*/ +int sceAtracDecodeData(int atracID, u16 *outSamples, int *outN, int *outEnd, int *outRemainFrame); + +/** + * Gets the remaining (not decoded) number of frames + * + * @param atracID - the atrac ID + * @param outRemainFrame - pointer to a integer that receives either -1 if all at3 data is already on memory, + * or the remaining (not decoded yet) frames at memory if not all at3 data is on memory + * + * @return < 0 on error, otherwise 0 + * +*/ +int sceAtracGetRemainFrame(int atracID, int *outRemainFrame); + +/** + * + * @param atracID - the atrac ID + * @param writePointer - Pointer to where to read the atrac data + * @param availableBytes - Number of bytes available at the writePointer location + * @param readOffset - Offset where to seek into the atrac file before reading + * + * @return < 0 on error, otherwise 0 + * +*/ + +int sceAtracGetStreamDataInfo(int atracID, u8** writePointer, u32* availableBytes, u32* readOffset); + +/** + * + * @param atracID - the atrac ID + * @param bytesToAdd - Number of bytes read into location given by sceAtracGetStreamDataInfo(). + * + * @return < 0 on error, otherwise 0 +*/ +int sceAtracAddStreamData(int atracID, unsigned int bytesToAdd); + +/** + * Gets the bitrate. + * + * @param atracID - the atracID + * @param outBitrate - pointer to a integer that receives the bitrate in kbps + * + * @return < 0 on error, otherwise 0 + * +*/ +int sceAtracGetBitrate(int atracID, int *outBitrate); + +/** + * Sets the number of loops for this atrac ID + * + * @param atracID - the atracID + * @param nloops - the number of loops to set + * + * @return < 0 on error, otherwise 0 + * +*/ +int sceAtracSetLoopNum(int atracID, int nloops); + +/** + * It releases an atrac ID + * + * @param atracID - the atrac ID to release + * + * @return < 0 on error + * +*/ +int sceAtracReleaseAtracID(int atracID); + +/** + * Gets the number of samples of the next frame to be decoded. + * + * @param atracID - the atrac ID + * @param outN - pointer to receives the number of samples of the next frame. + * + * @return < 0 on error, otherwise 0 + * + */ +int sceAtracGetNextSample(int atracID, int *outN); + +/** + * Gets the maximum number of samples of the atrac3 stream. + * + * @param atracID - the atrac ID + * @param outMax - pointer to a integer that receives the maximum number of samples. + * + * @return < 0 on error, otherwise 0 + * + */ +int sceAtracGetMaxSample(int atracID, int *outMax); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/atrac3/sceAtrac3plus.S b/src/atrac3/sceAtrac3plus.S new file mode 100644 index 00000000..ac87b494 --- /dev/null +++ b/src/atrac3/sceAtrac3plus.S @@ -0,0 +1,82 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceAtrac3plus_0000 + IMPORT_START "sceAtrac3plus",0x00090000 +#endif +#ifdef F_sceAtrac3plus_0001 + IMPORT_FUNC "sceAtrac3plus",0xD1F59FDB,sceAtracStartEntry +#endif +#ifdef F_sceAtrac3plus_0002 + IMPORT_FUNC "sceAtrac3plus",0xD5C28CC0,sceAtracEndEntry +#endif +#ifdef F_sceAtrac3plus_0003 + IMPORT_FUNC "sceAtrac3plus",0x780F88D1,sceAtracGetAtracID +#endif +#ifdef F_sceAtrac3plus_0004 + IMPORT_FUNC "sceAtrac3plus",0x61EB33F5,sceAtracReleaseAtracID +#endif +#ifdef F_sceAtrac3plus_0005 + IMPORT_FUNC "sceAtrac3plus",0x0E2A73AB,sceAtracSetData +#endif +#ifdef F_sceAtrac3plus_0006 + IMPORT_FUNC "sceAtrac3plus",0x3F6E26B5,sceAtracSetHalfwayBuffer +#endif +#ifdef F_sceAtrac3plus_0007 + IMPORT_FUNC "sceAtrac3plus",0x7A20E7AF,sceAtracSetDataAndGetID +#endif +#ifdef F_sceAtrac3plus_0008 + IMPORT_FUNC "sceAtrac3plus",0x0FAE370E,sceAtracSetHalfwayBufferAndGetID +#endif +#ifdef F_sceAtrac3plus_0009 + IMPORT_FUNC "sceAtrac3plus",0x6A8C3CD5,sceAtracDecodeData +#endif +#ifdef F_sceAtrac3plus_0010 + IMPORT_FUNC "sceAtrac3plus",0x9AE849A7,sceAtracGetRemainFrame +#endif +#ifdef F_sceAtrac3plus_0011 + IMPORT_FUNC "sceAtrac3plus",0x5D268707,sceAtracGetStreamDataInfo +#endif +#ifdef F_sceAtrac3plus_0012 + IMPORT_FUNC "sceAtrac3plus",0x7DB31251,sceAtracAddStreamData +#endif +#ifdef F_sceAtrac3plus_0013 + IMPORT_FUNC "sceAtrac3plus",0x83E85EA0,sceAtracGetSecondBufferInfo +#endif +#ifdef F_sceAtrac3plus_0014 + IMPORT_FUNC "sceAtrac3plus",0x83BF7AFD,sceAtracSetSecondBuffer +#endif +#ifdef F_sceAtrac3plus_0015 + IMPORT_FUNC "sceAtrac3plus",0xE23E3A35,sceAtracGetNextDecodePosition +#endif +#ifdef F_sceAtrac3plus_0016 + IMPORT_FUNC "sceAtrac3plus",0xA2BBA8BE,sceAtracGetSoundSample +#endif +#ifdef F_sceAtrac3plus_0017 + IMPORT_FUNC "sceAtrac3plus",0x31668BAA,sceAtracGetChannel +#endif +#ifdef F_sceAtrac3plus_0018 + IMPORT_FUNC "sceAtrac3plus",0xD6A5F2F7,sceAtracGetMaxSample +#endif +#ifdef F_sceAtrac3plus_0019 + IMPORT_FUNC "sceAtrac3plus",0x36FAABFB,sceAtracGetNextSample +#endif +#ifdef F_sceAtrac3plus_0020 + IMPORT_FUNC "sceAtrac3plus",0xA554A158,sceAtracGetBitrate +#endif +#ifdef F_sceAtrac3plus_0021 + IMPORT_FUNC "sceAtrac3plus",0xFAA4F89B,sceAtracGetLoopStatus +#endif +#ifdef F_sceAtrac3plus_0022 + IMPORT_FUNC "sceAtrac3plus",0x868120B5,sceAtracSetLoopNum +#endif +#ifdef F_sceAtrac3plus_0023 + IMPORT_FUNC "sceAtrac3plus",0xCA3CA3D2,sceAtracGetBufferInfoForReseting +#endif +#ifdef F_sceAtrac3plus_0024 + IMPORT_FUNC "sceAtrac3plus",0x644E5607,sceAtracResetPlayPosition +#endif +#ifdef F_sceAtrac3plus_0025 + IMPORT_FUNC "sceAtrac3plus",0xE88F759B,sceAtracGetInternalErrorInfo +#endif diff --git a/src/audio/Makefile.am b/src/audio/Makefile.am new file mode 100644 index 00000000..847d8dc7 --- /dev/null +++ b/src/audio/Makefile.am @@ -0,0 +1,51 @@ + +libdir = @PSPSDK_LIBDIR@ + +CC = @PSP_CC@ +CCAS = $(CC) +AR = @PSP_AR@ +RANLIB = @PSP_RANLIB@ + +INCLUDES = -I$(top_srcdir)/src/base -I$(top_srcdir)/src/user -I$(top_srcdir)/src/debug +CFLAGS = @PSPSDK_CFLAGS@ +CCASFLAGS = $(CFLAGS) $(INCLUDES) + +AUDIO_OBJS = sceAudio_0000.o sceAudio_0001.o sceAudio_0002.o sceAudio_0003.o sceAudio_0004.o sceAudio_0005.o sceAudio_0006.o sceAudio_0007.o sceAudio_0008.o sceAudio_0009.o sceAudio_0010.o sceAudio_0011.o sceAudio_0012.o sceAudio_0013.o sceAudio_0014.o sceAudio_0015.o sceAudio_0016.o sceAudio_0017.o sceAudio_0018.o sceAudio_0019.o sceAudio_0020.o sceAudio_0021.o sceAudio_0022.o sceAudio_0023.o sceAudio_0024.o sceAudio_0025.o sceAudio_0026.o sceAudio_0027.o + +AUDIO_DRIVER_OBJS = sceAudio_driver_0000.o sceAudio_driver_0001.o sceAudio_driver_0002.o sceAudio_driver_0003.o sceAudio_driver_0004.o sceAudio_driver_0005.o sceAudio_driver_0006.o sceAudio_driver_0007.o sceAudio_driver_0008.o sceAudio_driver_0009.o sceAudio_driver_0010.o sceAudio_driver_0011.o sceAudio_driver_0012.o sceAudio_driver_0013.o sceAudio_driver_0014.o sceAudio_driver_0015.o sceAudio_driver_0016.o sceAudio_driver_0017.o sceAudio_driver_0018.o sceAudio_driver_0019.o sceAudio_driver_0020.o sceAudio_driver_0021.o sceAudio_driver_0022.o sceAudio_driver_0023.o sceAudio_driver_0024.o sceAudio_driver_0025.o sceAudio_driver_0026.o sceAudio_driver_0027.o + +CODEC_OBJS = sceAudiocodec_0000.o sceAudiocodec_0001.o sceAudiocodec_0002.o sceAudiocodec_0003.o sceAudiocodec_0004.o sceAudiocodec_0005.o sceAudiocodec_0006.o sceAudiocodec_0007.o sceAudiocodec_0008.o + +libpspaudioincludedir = @PSPSDK_INCLUDEDIR@ +libpspaudioinclude_HEADERS = pspaudio.h + +libpspaudio_driverincludedir = @PSPSDK_INCLUDEDIR@ +libpspaudio_driverinclude_HEADERS = pspaudio_kernel.h + +libpspaudiolibincludedir = @PSPSDK_INCLUDEDIR@ +libpspaudiolibinclude_HEADERS = pspaudiolib.h + +libpspaudiocodecincludedir = @PSPSDK_INCLUDEDIR@ +libpspaudiocodecinclude_HEADERS = pspaudiocodec.h + +lib_LIBRARIES = libpspaudio.a libpspaudio_driver.a libpspaudiolib.a libpspaudiocodec.a + +libpspaudio_a_SOURCES = sceAudio.S +libpspaudio_a_LIBADD = $(AUDIO_OBJS) + +libpspaudio_driver_a_SOURCES = sceAudio_driver.S +libpspaudio_driver_a_LIBADD = $(AUDIO_DRIVER_OBJS) + +libpspaudiolib_a_SOURCES = pspaudiolib.c + +libpspaudiocodec_a_SOURCES = sceAudiocodec.S +libpspaudiocodec_a_LIBADD = $(CODEC_OBJS) + +$(AUDIO_OBJS): sceAudio.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(AUDIO_DRIVER_OBJS): sceAudio_driver.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(CODEC_OBJS): sceAudiocodec.S + $(COMPILE) -DF_$* $< -c -o $@ diff --git a/src/audio/pspaudio.h b/src/audio/pspaudio.h new file mode 100644 index 00000000..f666a62f --- /dev/null +++ b/src/audio/pspaudio.h @@ -0,0 +1,354 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspaudio.h - Prototypes for the sceAudio library. + * + * Copyright (c) 2005 Adresd + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2007 cooleyes + * Copyright (c) 2007 Alexander Berl + * Copyright (c) 2008 David Perry + * + * $Id: pspaudio.h 2433 2008-10-15 10:00:27Z iwn $ + */ +#ifndef PSPAUDIO_H +#define PSPAUDIO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup Audio User Audio Library */ + +/** @addtogroup Audio */ + +/*@{*/ + +/** The maximum output volume. */ +#define PSP_AUDIO_VOLUME_MAX 0x8000 + +/** The maximum number of hardware channels. */ +#define PSP_AUDIO_CHANNEL_MAX 8 + +/** Used to request the next available hardware channel. */ +#define PSP_AUDIO_NEXT_CHANNEL (-1) + +enum PspAudioFormats +{ + /** Channel is set to stereo output. */ + PSP_AUDIO_FORMAT_STEREO = 0, + /** Channel is set to mono output. */ + PSP_AUDIO_FORMAT_MONO = 0x10 +}; + +typedef struct +{ + /** Unknown. Pass 0 */ + int unknown1; + int gain; + /** Unknown. Pass 0 */ + int unknown2; + /** Unknown. Pass 0 */ + int unknown3; + /** Unknown. Pass 0 */ + int unknown4; + /** Unknown. Pass 0 */ + int unknown5; + +} pspAudioInputParams; + +/** The minimum number of samples that can be allocated to a channel. */ +#define PSP_AUDIO_SAMPLE_MIN 64 + +/** The maximum number of samples that can be allocated to a channel. */ +#define PSP_AUDIO_SAMPLE_MAX 65472 + +/** Make the given sample count a multiple of 64. */ +#define PSP_AUDIO_SAMPLE_ALIGN(s) (((s) + 63) & ~63) + +/** + * Allocate and initialize a hardware output channel. + * + * @param channel - Use a value between 0 - 7 to reserve a specific channel. + * Pass PSP_AUDIO_NEXT_CHANNEL to get the first available channel. + * @param samplecount - The number of samples that can be output on the channel per + * output call. It must be a value between ::PSP_AUDIO_SAMPLE_MIN + * and ::PSP_AUDIO_SAMPLE_MAX, and it must be aligned to 64 bytes + * (use the ::PSP_AUDIO_SAMPLE_ALIGN macro to align it). + * @param format - The output format to use for the channel. One of ::PspAudioFormats. + * + * @return The channel number on success, an error code if less than 0. + */ +int sceAudioChReserve(int channel, int samplecount, int format); + +/** + * Release a hardware output channel. + * + * @param channel - The channel to release. + * + * @return 0 on success, an error if less than 0. + */ +int sceAudioChRelease(int channel); + +/** + * Output audio of the specified channel + * + * @param channel - The channel number. + * + * @param vol - The volume. + * + * @param buf - Pointer to the PCM data to output. + * + * @return 0 on success, an error if less than 0. + */ +int sceAudioOutput(int channel, int vol, void *buf); + +/** + * Output audio of the specified channel (blocking) + * + * @param channel - The channel number. + * + * @param vol - The volume. + * + * @param buf - Pointer to the PCM data to output. + * + * @return 0 on success, an error if less than 0. + */ +int sceAudioOutputBlocking(int channel, int vol, void *buf); + +/** + * Output panned audio of the specified channel + * + * @param channel - The channel number. + * + * @param leftvol - The left volume. + * + * @param rightvol - The right volume. + * + * @param buf - Pointer to the PCM data to output. + * + * @return 0 on success, an error if less than 0. + */ +int sceAudioOutputPanned(int channel, int leftvol, int rightvol, void *buf); + +/** + * Output panned audio of the specified channel (blocking) + * + * @param channel - The channel number. + * + * @param leftvol - The left volume. + * + * @param rightvol - The right volume. + * + * @param buf - Pointer to the PCM data to output. + * + * @return 0 on success, an error if less than 0. + */ +int sceAudioOutputPannedBlocking(int channel, int leftvol, int rightvol, void *buf); + +/** + * Get count of unplayed samples remaining + * + * @param channel - The channel number. + * + * @return Number of samples to be played, an error if less than 0. + */ +int sceAudioGetChannelRestLen(int channel); + +/** + * Get count of unplayed samples remaining + * + * @param channel - The channel number. + * + * @return Number of samples to be played, an error if less than 0. + */ +int sceAudioGetChannelRestLength(int channel); + +/** + * Change the output sample count, after it's already been reserved + * + * @param channel - The channel number. + * @param samplecount - The number of samples to output in one output call. + * + * @return 0 on success, an error if less than 0. + */ +int sceAudioSetChannelDataLen(int channel, int samplecount); + +/** + * Change the format of a channel + * + * @param channel - The channel number. + * + * @param format - One of ::PspAudioFormats + * + * @return 0 on success, an error if less than 0. + */ +int sceAudioChangeChannelConfig(int channel, int format); + +/** + * Change the volume of a channel + * + * @param channel - The channel number. + * + * @param leftvol - The left volume. + * + * @param rightvol - The right volume. + * + * @return 0 on success, an error if less than 0. + */ +int sceAudioChangeChannelVolume(int channel, int leftvol, int rightvol); + +//sceAudioOneshotOutput ??? + +/** + * Reserve the audio output and set the output sample count + * + * @param samplecount - The number of samples to output in one output call (min 17, max 4111). + * + * @return 0 on success, an error if less than 0. + */ +int sceAudioOutput2Reserve(int samplecount); + +/** + * Release the audio output + * + * @return 0 on success, an error if less than 0. + */ +int sceAudioOutput2Release(void); + +/** + * Change the output sample count, after it's already been reserved + * + * @param samplecount - The number of samples to output in one output call (min 17, max 4111). + * + * @return 0 on success, an error if less than 0. + */ +int sceAudioOutput2ChangeLength(int samplecount); + +/** + * Output audio (blocking) + * + * @param vol - The volume. + * + * @param buf - Pointer to the PCM data. + * + * @return 0 on success, an error if less than 0. + */ +int sceAudioOutput2OutputBlocking(int vol, void *buf); + +/** + * Get count of unplayed samples remaining + * + * @return Number of samples to be played, an error if less than 0. + */ +int sceAudioOutput2GetRestSample(void); + +/** + * Reserve the audio output + * + * @param samplecount - The number of samples to output in one output call (min 17, max 4111). + * + * @param freq - The frequency. One of 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11050, 8000. + * + * @param channels - Number of channels. Pass 2 (stereo). + * + * @return 0 on success, an error if less than 0. + */ +int sceAudioSRCChReserve(int samplecount, int freq, int channels); + +/** + * Release the audio output + * + * @return 0 on success, an error if less than 0. + */ +int sceAudioSRCChRelease(void); + +/** + * Output audio + * + * @param vol - The volume. + * + * @param buf - Pointer to the PCM data to output. + * + * @return 0 on success, an error if less than 0. + */ +int sceAudioSRCOutputBlocking(int vol, void *buf); + +/** + * Init audio input + * + * @param unknown1 - Unknown. Pass 0. + * + * @param gain - Gain. + * + * @param unknown2 - Unknown. Pass 0. + * + * @return 0 on success, an error if less than 0. + */ +int sceAudioInputInit(int unknown1, int gain, int unknown2); + +/** + * Init audio input (with extra arguments) + * + * @param params - A pointer to a ::pspAudioInputParams struct. + * + * @return 0 on success, an error if less than 0. + */ +int sceAudioInputInitEx(pspAudioInputParams *params); + +/** + * Perform audio input (blocking) + * + * @param samplecount - Number of samples. + * + * @param freq - Either 44100, 22050 or 11025. + * + * @param buf - Pointer to where the audio data will be stored. + * + * @return 0 on success, an error if less than 0. + */ +int sceAudioInputBlocking(int samplecount, int freq, void *buf); + +/** + * Perform audio input + * + * @param samplecount - Number of samples. + * + * @param freq - Either 44100, 22050 or 11025. + * + * @param buf - Pointer to where the audio data will be stored. + * + * @return 0 on success, an error if less than 0. + */ +int sceAudioInput(int samplecount, int freq, void *buf); + +/** + * Get the number of samples that were acquired + * + * @return Number of samples acquired, an error if less than 0. + */ +int sceAudioGetInputLength(void); + +/** + * Wait for non-blocking audio input to complete + * + * @return 0 on success, an error if less than 0. + */ +int sceAudioWaitInputEnd(void); + +/** + * Poll for non-blocking audio input status + * + * @return 0 if input has completed, 1 if not completed or an error if less than 0. + */ +int sceAudioPollInputEnd(void); + +/*@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* PSPAUDIO_H */ diff --git a/src/audio/pspaudio_kernel.h b/src/audio/pspaudio_kernel.h new file mode 100755 index 00000000..8007ba93 --- /dev/null +++ b/src/audio/pspaudio_kernel.h @@ -0,0 +1,49 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspaudio.h - Prototypes for the sceAudio library. + * + * Copyright (c) 2005 Adresd + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2007 cooleyes + * Copyright (c) 2007 Alexander Berl + * + * $Id: pspaudio_kernel.h 2433 2008-10-15 10:00:27Z iwn $ + */ +#ifndef PSPAUDIO_KERNEL_H +#define PSPAUDIO_KERNEL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup Audio User Audio Library */ + +/** @addtogroup Audio */ + +/*@{*/ + +enum PspAudioFrequencies { + /** Sampling frequency set to 44100Hz. */ + PSP_AUDIO_FREQ_44K = 44100, + /** Sampling frequency set to 48000Hz. */ + PSP_AUDIO_FREQ_48K = 48000 +}; + +/** + * Set audio sampling frequency + * + * @param frequency - Sampling frequency to set audio output to - either 44100 or 48000. + * + * @return 0 on success, an error if less than 0. + */ +int sceAudioSetFrequency(int frequency); +/*@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* PSPAUDIO_KERNEL_H */ diff --git a/src/audio/pspaudiocodec.h b/src/audio/pspaudiocodec.h new file mode 100644 index 00000000..7f155cc1 --- /dev/null +++ b/src/audio/pspaudiocodec.h @@ -0,0 +1,31 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspaudiocodec.h - Prototypes for the sceAudiocodec library. + * + * Copyright (c) 2006 hitchhikr + * + * $Id: pspaudiocodec.h 2430 2008-08-28 12:04:04Z Raphael $ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#define PSP_CODEC_AT3PLUS (0x00001000) +#define PSP_CODEC_AT3 (0x00001001) +#define PSP_CODEC_MP3 (0x00001002) +#define PSP_CODEC_AAC (0x00001003) + + +int sceAudiocodecCheckNeedMem(unsigned long *Buffer, int Type); +int sceAudiocodecInit(unsigned long *Buffer, int Type); +int sceAudiocodecDecode(unsigned long *Buffer, int Type); +int sceAudiocodecGetEDRAM(unsigned long *Buffer, int Type); +int sceAudiocodecReleaseEDRAM(unsigned long *Buffer); + +#ifdef __cplusplus +} +#endif diff --git a/src/audio/pspaudiolib.c b/src/audio/pspaudiolib.c new file mode 100644 index 00000000..fb3dd2e3 --- /dev/null +++ b/src/audio/pspaudiolib.c @@ -0,0 +1,177 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspaudiolib.c - Audio library build on top of sceAudio, but to provide + * multiple thread usage and callbacks. + * + * Copyright (c) 2005 Adresd + * Copyright (c) 2005 Marcus R. Brown + * + * $Id: pspaudiolib.c 1145 2005-10-12 15:32:44Z mrbrown $ + */ +#include +#include +#include +#include + +#include "pspaudiolib.h" + +static int audio_ready=0; +static short audio_sndbuf[PSP_NUM_AUDIO_CHANNELS][2][PSP_NUM_AUDIO_SAMPLES][2]; + +static psp_audio_channelinfo AudioStatus[PSP_NUM_AUDIO_CHANNELS]; + +static volatile int audio_terminate=0; + +void pspAudioSetVolume(int channel, int left, int right) +{ + AudioStatus[channel].volumeright = right; + AudioStatus[channel].volumeleft = left; +} + +void pspAudioChannelThreadCallback(int channel, void *buf, unsigned int reqn) +{ + pspAudioCallback_t callback; + callback=AudioStatus[channel].callback; +} + + +void pspAudioSetChannelCallback(int channel, pspAudioCallback_t callback, void *pdata) +{ + volatile psp_audio_channelinfo *pci = &AudioStatus[channel]; + pci->callback=0; + pci->pdata=pdata; + pci->callback=callback; +} + +int pspAudioOutBlocking(unsigned int channel, unsigned int vol1, unsigned int vol2, void *buf) +{ + if (!audio_ready) return -1; + if (channel>=PSP_NUM_AUDIO_CHANNELS) return -1; + if (vol1>PSP_VOLUME_MAX) vol1=PSP_VOLUME_MAX; + if (vol2>PSP_VOLUME_MAX) vol2=PSP_VOLUME_MAX; + return sceAudioOutputPannedBlocking(AudioStatus[channel].handle,vol1,vol2,buf); +} + +static int AudioChannelThread(int args, void *argp) +{ + volatile int bufidx=0; + int channel=*(int *)argp; + + while (audio_terminate==0) { + void *bufptr=&audio_sndbuf[channel][bufidx]; + pspAudioCallback_t callback; + callback=AudioStatus[channel].callback; + if (callback) { + callback(bufptr, PSP_NUM_AUDIO_SAMPLES, AudioStatus[channel].pdata); + } else { + unsigned int *ptr=bufptr; + int i; + for (i=0; i + * + * $Id: pspaudiolib.h 1874 2006-04-18 13:20:58Z tyranid $ + */ +#ifndef __AUDIOLIB_H__ +#define __AUDIOLIB_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define PSP_NUM_AUDIO_CHANNELS 4 +/** This is the number of frames you can update per callback, a frame being + * 1 sample for mono, 2 samples for stereo etc. */ +#define PSP_NUM_AUDIO_SAMPLES 1024 +#define PSP_VOLUME_MAX 0x8000 + +typedef void (* pspAudioCallback_t)(void *buf, unsigned int reqn, void *pdata); + +typedef struct { + int threadhandle; + int handle; + int volumeleft; + int volumeright; + pspAudioCallback_t callback; + void *pdata; +} psp_audio_channelinfo; + +typedef int (* pspAudioThreadfunc_t)(int args, void *argp); + +int pspAudioInit(); +void pspAudioEndPre(); +void pspAudioEnd(); + +void pspAudioSetVolume(int channel, int left, int right); +void pspAudioChannelThreadCallback(int channel, void *buf, unsigned int reqn); +void pspAudioSetChannelCallback(int channel, pspAudioCallback_t callback, void *pdata); +int pspAudioOutBlocking(unsigned int channel, unsigned int vol1, unsigned int vol2, void *buf); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/audio/sceAudio.S b/src/audio/sceAudio.S new file mode 100644 index 00000000..20c8a604 --- /dev/null +++ b/src/audio/sceAudio.S @@ -0,0 +1,89 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceAudio_0000 + IMPORT_START "sceAudio",0x40010000 +#endif +#ifdef F_sceAudio_0001 + IMPORT_FUNC "sceAudio",0x8C1009B2,sceAudioOutput +#endif +#ifdef F_sceAudio_0002 + IMPORT_FUNC "sceAudio",0x136CAF51,sceAudioOutputBlocking +#endif +#ifdef F_sceAudio_0003 + IMPORT_FUNC "sceAudio",0xE2D56B2D,sceAudioOutputPanned +#endif +#ifdef F_sceAudio_0004 + IMPORT_FUNC "sceAudio",0x13F592BC,sceAudioOutputPannedBlocking +#endif +#ifdef F_sceAudio_0005 + IMPORT_FUNC "sceAudio",0x5EC81C55,sceAudioChReserve +#endif +#ifdef F_sceAudio_0006 + IMPORT_FUNC "sceAudio",0x41EFADE7,sceAudioOneshotOutput +#endif +#ifdef F_sceAudio_0007 + IMPORT_FUNC "sceAudio",0x6FC46853,sceAudioChRelease +#endif +#ifdef F_sceAudio_0008 + IMPORT_FUNC "sceAudio",0xE9D97901,sceAudioGetChannelRestLen +#endif +#ifdef F_sceAudio_0009 + IMPORT_FUNC "sceAudio",0xCB2E439E,sceAudioSetChannelDataLen +#endif +#ifdef F_sceAudio_0010 + IMPORT_FUNC "sceAudio",0x95FD0C2D,sceAudioChangeChannelConfig +#endif +#ifdef F_sceAudio_0011 + IMPORT_FUNC "sceAudio",0xB7E1D8E7,sceAudioChangeChannelVolume +#endif +#ifdef F_sceAudio_0012 + IMPORT_FUNC "sceAudio",0x38553111,sceAudioSRCChReserve +#endif +#ifdef F_sceAudio_0013 + IMPORT_FUNC "sceAudio",0x5C37C0AE,sceAudioSRCChRelease +#endif +#ifdef F_sceAudio_0014 + IMPORT_FUNC "sceAudio",0xE0727056,sceAudioSRCOutputBlocking +#endif +#ifdef F_sceAudio_0015 + IMPORT_FUNC "sceAudio",0x086E5895,sceAudioInputBlocking +#endif +#ifdef F_sceAudio_0016 + IMPORT_FUNC "sceAudio",0x6D4BEC68,sceAudioInput +#endif +#ifdef F_sceAudio_0017 + IMPORT_FUNC "sceAudio",0xA708C6A6,sceAudioGetInputLength +#endif +#ifdef F_sceAudio_0018 + IMPORT_FUNC "sceAudio",0x87B2E651,sceAudioWaitInputEnd +#endif +#ifdef F_sceAudio_0019 + IMPORT_FUNC "sceAudio",0x7DE61688,sceAudioInputInit +#endif +#ifdef F_sceAudio_0020 + IMPORT_FUNC "sceAudio",0xA633048E,sceAudioPollInputEnd +#endif +#ifdef F_sceAudio_0021 + IMPORT_FUNC "sceAudio",0xB011922F,sceAudioGetChannelRestLength +#endif +#ifdef F_sceAudio_0022 + IMPORT_FUNC "sceAudio",0xE926D3FB,sceAudioInputInitEx +#endif +#ifdef F_sceAudio_0023 + IMPORT_FUNC "sceAudio",0x01562BA3,sceAudioOutput2Reserve +#endif +#ifdef F_sceAudio_0024 + IMPORT_FUNC "sceAudio",0x2D53F36E,sceAudioOutput2OutputBlocking +#endif +#ifdef F_sceAudio_0025 + IMPORT_FUNC "sceAudio",0x43196845,sceAudioOutput2Release +#endif +#ifdef F_sceAudio_0026 + IMPORT_FUNC "sceAudio",0x63F2889C,sceAudioOutput2ChangeLength +#endif +#ifdef F_sceAudio_0027 + IMPORT_FUNC "sceAudio",0x647CEF33,sceAudioOutput2GetRestSample +#endif + diff --git a/src/audio/sceAudio_driver.S b/src/audio/sceAudio_driver.S new file mode 100755 index 00000000..7013d275 --- /dev/null +++ b/src/audio/sceAudio_driver.S @@ -0,0 +1,116 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceAudio_driver_0000 + IMPORT_START "sceAudio_driver",0x00010000 +#endif + +#ifdef F_sceAudio_driver_0001 + IMPORT_FUNC "sceAudio_driver",0x80F1F7E0,sceAudioInit +#endif + +#ifdef F_sceAudio_driver_0002 + IMPORT_FUNC "sceAudio_driver",0x210567F7,sceAudioEnd +#endif + +#ifdef F_sceAudio_driver_0003 + IMPORT_FUNC "sceAudio_driver",0xA2BEAA6C,sceAudioSetFrequency +#endif + +#ifdef F_sceAudio_driver_0004 + IMPORT_FUNC "sceAudio_driver",0xB61595C0,sceAudioLoopbackTest +#endif + +#ifdef F_sceAudio_driver_0005 + IMPORT_FUNC "sceAudio_driver",0x927AC32B,sceAudioSetVolumeOffset +#endif + +#ifdef F_sceAudio_driver_0006 + IMPORT_FUNC "sceAudio_driver",0x8C1009B2,sceAudioOutput +#endif + +#ifdef F_sceAudio_driver_0007 + IMPORT_FUNC "sceAudio_driver",0x136CAF51,sceAudioOutputBlocking +#endif + +#ifdef F_sceAudio_driver_0008 + IMPORT_FUNC "sceAudio_driver",0xE2D56B2D,sceAudioOutputPanned +#endif + +#ifdef F_sceAudio_driver_0009 + IMPORT_FUNC "sceAudio_driver",0x13F592BC,sceAudioOutputPannedBlocking +#endif + +#ifdef F_sceAudio_driver_0010 + IMPORT_FUNC "sceAudio_driver",0x5EC81C55,sceAudioChReserve +#endif + +#ifdef F_sceAudio_driver_0011 + IMPORT_FUNC "sceAudio_driver",0x41EFADE7,sceAudioOneshotOutput +#endif + +#ifdef F_sceAudio_driver_0012 + IMPORT_FUNC "sceAudio_driver",0x6FC46853,sceAudioChRelease +#endif + +#ifdef F_sceAudio_driver_0013 + IMPORT_FUNC "sceAudio_driver",0xB011922F,sceAudio_driver_B011922F +#endif + +#ifdef F_sceAudio_driver_0014 + IMPORT_FUNC "sceAudio_driver",0xCB2E439E,sceAudioSetChannelDataLen +#endif + +#ifdef F_sceAudio_driver_0015 + IMPORT_FUNC "sceAudio_driver",0x95FD0C2D,sceAudioChangeChannelConfig +#endif + +#ifdef F_sceAudio_driver_0016 + IMPORT_FUNC "sceAudio_driver",0xB7E1D8E7,sceAudioChangeChannelVolume +#endif + +#ifdef F_sceAudio_driver_0017 + IMPORT_FUNC "sceAudio_driver",0x38553111,sceAudio_driver_38553111 +#endif + +#ifdef F_sceAudio_driver_0018 + IMPORT_FUNC "sceAudio_driver",0x5C37C0AE,sceAudio_driver_5C37C0AE +#endif + +#ifdef F_sceAudio_driver_0019 + IMPORT_FUNC "sceAudio_driver",0xE0727056,sceAudio_driver_E0727056 +#endif + +#ifdef F_sceAudio_driver_0020 + IMPORT_FUNC "sceAudio_driver",0x086E5895,sceAudioInputBlocking +#endif + +#ifdef F_sceAudio_driver_0021 + IMPORT_FUNC "sceAudio_driver",0x6D4BEC68,sceAudioInput +#endif + +#ifdef F_sceAudio_driver_0022 + IMPORT_FUNC "sceAudio_driver",0xA708C6A6,sceAudioGetInputLength +#endif + +#ifdef F_sceAudio_driver_0023 + IMPORT_FUNC "sceAudio_driver",0x87B2E651,sceAudioWaitInputEnd +#endif + +#ifdef F_sceAudio_driver_0024 + IMPORT_FUNC "sceAudio_driver",0x7DE61688,sceAudioInputInit +#endif + +#ifdef F_sceAudio_driver_0025 + IMPORT_FUNC "sceAudio_driver",0xE926D3FB,sceAudioInputInitEx +#endif + +#ifdef F_sceAudio_driver_0026 + IMPORT_FUNC "sceAudio_driver",0xA633048E,sceAudioPollInputEnd +#endif + +#ifdef F_sceAudio_driver_0027 + IMPORT_FUNC "sceAudio_driver",0xE9D97901,sceAudioGetChannelRestLen +#endif + diff --git a/src/audio/sceAudiocodec.S b/src/audio/sceAudiocodec.S new file mode 100644 index 00000000..790df90f --- /dev/null +++ b/src/audio/sceAudiocodec.S @@ -0,0 +1,31 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceAudiocodec_0000 + IMPORT_START "sceAudiocodec",0x40090000 +#endif +#ifdef F_sceAudiocodec_0001 + IMPORT_FUNC "sceAudiocodec",0x9D3F790C,sceAudiocodecCheckNeedMem +#endif +#ifdef F_sceAudiocodec_0002 + IMPORT_FUNC "sceAudiocodec",0x5B37EB1D,sceAudiocodecInit +#endif +#ifdef F_sceAudiocodec_0003 + IMPORT_FUNC "sceAudiocodec",0x70A703F8,sceAudiocodecDecode +#endif +#ifdef F_sceAudiocodec_0004 + IMPORT_FUNC "sceAudiocodec",0x8ACA11D5,sceAudiocodecGetInfo +#endif +#ifdef F_sceAudiocodec_0005 + IMPORT_FUNC "sceAudiocodec",0x6CD2A861,sceAudiocodec_6CD2A861 +#endif +#ifdef F_sceAudiocodec_0006 + IMPORT_FUNC "sceAudiocodec",0x59176A0F,sceAudiocodec_59176A0F +#endif +#ifdef F_sceAudiocodec_0007 + IMPORT_FUNC "sceAudiocodec",0x3A20A200,sceAudiocodecGetEDRAM +#endif +#ifdef F_sceAudiocodec_0008 + IMPORT_FUNC "sceAudiocodec",0x29681260,sceAudiocodecReleaseEDRAM +#endif diff --git a/src/base/Makefile.am b/src/base/Makefile.am new file mode 100644 index 00000000..c3e6c8a8 --- /dev/null +++ b/src/base/Makefile.am @@ -0,0 +1,17 @@ + +pspsdkincludedir = @PSPSDK_INCLUDEDIR@ + +pspsdkinclude_HEADERS = \ + as_reg_compat.h \ + psptypes.h \ + pspstub.s \ + pspimport.s + +## Install the build.mak fragment to $PSPSDK/lib. +buildmakdir = @PSPSDK_LIBDIR@ +buildmak_DATA = build.mak prxspecs + +buildmakprxdir = @PSPSDK_LIBDIR@ +buildmakprx_DATA = build_prx.mak linkfile.prx + +EXTRA_DIST = build.mak prxspecs build_prx.mak linkfile.prx diff --git a/src/base/as_reg_compat.h b/src/base/as_reg_compat.h new file mode 100644 index 00000000..305fad0d --- /dev/null +++ b/src/base/as_reg_compat.h @@ -0,0 +1,52 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * as_reg_compat.h - Register name mapping. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: as_reg_compat.h 540 2005-07-08 19:35:10Z warren $ + */ +#ifndef __AS_REG_COMPAT_H__ +#define __AS_REG_COMPAT_H__ + +/* register defines for the GNU assembler */ + +#define zero 0 +#define at 1 +#define v0 2 +#define v1 3 +#define a0 4 +#define a1 5 +#define a2 6 +#define a3 7 +#define t0 8 +#define t1 9 +#define t2 10 +#define t3 11 +#define t4 12 +#define t5 13 +#define t6 14 +#define t7 15 +#define s0 16 +#define s1 17 +#define s2 18 +#define s3 19 +#define s4 20 +#define s5 21 +#define s6 22 +#define s7 23 +#define t8 24 +#define t9 25 +#define k0 26 +#define k1 27 +#define gp 28 +#define sp 29 +#define fp 30 +#define ra 31 + +#endif diff --git a/src/base/build.mak b/src/base/build.mak new file mode 100644 index 00000000..7f880079 --- /dev/null +++ b/src/base/build.mak @@ -0,0 +1,204 @@ +# PSP Software Development Kit - http://www.pspdev.org +# ----------------------------------------------------------------------- +# Licensed under the BSD license, see LICENSE in PSPSDK root for details. +# +# build.mak - Base makefile for projects using PSPSDK. +# +# Copyright (c) 2005 Marcus R. Brown +# Copyright (c) 2005 James Forshaw +# Copyright (c) 2005 John Kelley +# +# $Id: build.mak 2333 2007-10-31 19:37:40Z tyranid $ + +# Note: The PSPSDK make variable must be defined before this file is included. +ifeq ($(PSPSDK),) +$(error $$(PSPSDK) is undefined. Use "PSPSDK := $$(shell psp-config --pspsdk-path)" in your Makefile) +endif + +CC = psp-gcc +CXX = psp-g++ +AS = psp-gcc +LD = psp-gcc +AR = psp-ar +RANLIB = psp-ranlib +STRIP = psp-strip +MKSFO = mksfo +PACK_PBP = pack-pbp +FIXUP = psp-fixup-imports + +# Add in PSPSDK includes and libraries. +INCDIR := $(INCDIR) . $(PSPSDK)/include +LIBDIR := $(LIBDIR) . $(PSPSDK)/lib + +CFLAGS := $(addprefix -I,$(INCDIR)) $(CFLAGS) +CXXFLAGS := $(CFLAGS) $(CXXFLAGS) +ASFLAGS := $(CFLAGS) $(ASFLAGS) + +ifeq ($(PSP_LARGE_MEMORY),1) +MKSFO = mksfoex -d MEMSIZE=1 +endif + +ifeq ($(PSP_FW_VERSION),) +PSP_FW_VERSION=150 +endif + +CFLAGS += -D_PSP_FW_VERSION=$(PSP_FW_VERSION) +CXXFLAGS += -D_PSP_FW_VERSION=$(PSP_FW_VERSION) + +ifeq ($(BUILD_PRX),1) +LDFLAGS := $(addprefix -L,$(LIBDIR)) -specs=$(PSPSDK)/lib/prxspecs -Wl,-q,-T$(PSPSDK)/lib/linkfile.prx $(LDFLAGS) +EXTRA_CLEAN += $(TARGET).elf +# Setup default exports if needed +ifdef PRX_EXPORTS +EXPORT_OBJ=$(patsubst %.exp,%.o,$(PRX_EXPORTS)) +EXTRA_CLEAN += $(EXPORT_OBJ) +else +EXPORT_OBJ=$(PSPSDK)/lib/prxexports.o +endif +else +LDFLAGS := $(addprefix -L,$(LIBDIR)) $(LDFLAGS) +endif + +# Library selection. By default we link with Newlib's libc. Allow the +# user to link with PSPSDK's libc if USE_PSPSDK_LIBC is set to 1. + +ifeq ($(USE_KERNEL_LIBC),1) +# Use the PSP's kernel libc +PSPSDK_LIBC_LIB = +CFLAGS := -I$(PSPSDK)/include/libc $(CFLAGS) +else +ifeq ($(USE_PSPSDK_LIBC),1) +# Use the pspsdk libc +PSPSDK_LIBC_LIB = -lpsplibc +CFLAGS := -I$(PSPSDK)/include/libc $(CFLAGS) +else +# Use newlib (urgh) +PSPSDK_LIBC_LIB = -lc +endif +endif + + +# Link with following default libraries. Other libraries should be specified in the $(LIBS) variable. +# TODO: This library list needs to be generated at configure time. +# +ifeq ($(USE_KERNEL_LIBS),1) +PSPSDK_LIBS = -lpspdebug -lpspdisplay_driver -lpspctrl_driver -lpspsdk +LIBS := $(LIBS) $(PSPSDK_LIBS) $(PSPSDK_LIBC_LIB) -lpspkernel +else +ifeq ($(USE_USER_LIBS),1) +PSPSDK_LIBS = -lpspdebug -lpspdisplay -lpspge -lpspctrl -lpspsdk +LIBS := $(LIBS) $(PSPSDK_LIBS) $(PSPSDK_LIBC_LIB) -lpspnet \ + -lpspnet_inet -lpspnet_apctl -lpspnet_resolver -lpsputility \ + -lpspuser +else +PSPSDK_LIBS = -lpspdebug -lpspdisplay -lpspge -lpspctrl -lpspsdk +LIBS := $(LIBS) $(PSPSDK_LIBS) $(PSPSDK_LIBC_LIB) -lpspnet \ + -lpspnet_inet -lpspnet_apctl -lpspnet_resolver -lpsputility \ + -lpspuser -lpspkernel +endif +endif + +# Define the overridable parameters for EBOOT.PBP +ifndef PSP_EBOOT_TITLE +PSP_EBOOT_TITLE = $(TARGET) +endif + +ifndef PSP_EBOOT_SFO +PSP_EBOOT_SFO = PARAM.SFO +endif + +ifndef PSP_EBOOT_ICON +PSP_EBOOT_ICON = NULL +endif + +ifndef PSP_EBOOT_ICON1 +PSP_EBOOT_ICON1 = NULL +endif + +ifndef PSP_EBOOT_UNKPNG +PSP_EBOOT_UNKPNG = NULL +endif + +ifndef PSP_EBOOT_PIC1 +PSP_EBOOT_PIC1 = NULL +endif + +ifndef PSP_EBOOT_SND0 +PSP_EBOOT_SND0 = NULL +endif + +ifndef PSP_EBOOT_PSAR +PSP_EBOOT_PSAR = NULL +endif + +ifndef PSP_EBOOT +PSP_EBOOT = EBOOT.PBP +endif + +ifeq ($(BUILD_PRX),1) +ifneq ($(TARGET_LIB),) +$(error TARGET_LIB should not be defined when building a prx) +else +FINAL_TARGET = $(TARGET).prx +endif +else +ifneq ($(TARGET_LIB),) +FINAL_TARGET = $(TARGET_LIB) +else +FINAL_TARGET = $(TARGET).elf +endif +endif + +all: $(EXTRA_TARGETS) $(FINAL_TARGET) + +kxploit: $(TARGET).elf $(PSP_EBOOT_SFO) + mkdir -p "$(TARGET)" + $(STRIP) $(TARGET).elf -o $(TARGET)/$(PSP_EBOOT) + mkdir -p "$(TARGET)%" + $(PACK_PBP) "$(TARGET)%/$(PSP_EBOOT)" $(PSP_EBOOT_SFO) $(PSP_EBOOT_ICON) \ + $(PSP_EBOOT_ICON1) $(PSP_EBOOT_UNKPNG) $(PSP_EBOOT_PIC1) \ + $(PSP_EBOOT_SND0) NULL $(PSP_EBOOT_PSAR) + +SCEkxploit: $(TARGET).elf $(PSP_EBOOT_SFO) + mkdir -p "__SCE__$(TARGET)" + $(STRIP) $(TARGET).elf -o __SCE__$(TARGET)/$(PSP_EBOOT) + mkdir -p "%__SCE__$(TARGET)" + $(PACK_PBP) "%__SCE__$(TARGET)/$(PSP_EBOOT)" $(PSP_EBOOT_SFO) $(PSP_EBOOT_ICON) \ + $(PSP_EBOOT_ICON1) $(PSP_EBOOT_UNKPNG) $(PSP_EBOOT_PIC1) \ + $(PSP_EBOOT_SND0) NULL $(PSP_EBOOT_PSAR) + +$(TARGET).elf: $(OBJS) $(EXPORT_OBJ) + $(LINK.c) $^ $(LIBS) -o $@ + $(FIXUP) $@ + +$(TARGET_LIB): $(OBJS) + $(AR) cru $@ $(OBJS) + $(RANLIB) $@ + +$(PSP_EBOOT_SFO): + $(MKSFO) '$(PSP_EBOOT_TITLE)' $@ + +ifeq ($(BUILD_PRX),1) +$(PSP_EBOOT): $(TARGET).prx $(PSP_EBOOT_SFO) + $(PACK_PBP) $(PSP_EBOOT) $(PSP_EBOOT_SFO) $(PSP_EBOOT_ICON) \ + $(PSP_EBOOT_ICON1) $(PSP_EBOOT_UNKPNG) $(PSP_EBOOT_PIC1) \ + $(PSP_EBOOT_SND0) $(TARGET).prx $(PSP_EBOOT_PSAR) +else +$(PSP_EBOOT): $(TARGET).elf $(PSP_EBOOT_SFO) + $(STRIP) $(TARGET).elf -o $(TARGET)_strip.elf + $(PACK_PBP) $(PSP_EBOOT) $(PSP_EBOOT_SFO) $(PSP_EBOOT_ICON) \ + $(PSP_EBOOT_ICON1) $(PSP_EBOOT_UNKPNG) $(PSP_EBOOT_PIC1) \ + $(PSP_EBOOT_SND0) $(TARGET)_strip.elf $(PSP_EBOOT_PSAR) + -rm -f $(TARGET)_strip.elf +endif + +%.prx: %.elf + psp-prxgen $< $@ + +%.c: %.exp + psp-build-exports -b $< > $@ + +clean: + -rm -f $(FINAL_TARGET) $(EXTRA_CLEAN) $(OBJS) $(PSP_EBOOT_SFO) $(PSP_EBOOT) $(EXTRA_TARGETS) + +rebuild: clean all diff --git a/src/base/build_prx.mak b/src/base/build_prx.mak new file mode 100644 index 00000000..94f5a284 --- /dev/null +++ b/src/base/build_prx.mak @@ -0,0 +1,86 @@ +# PSP Software Development Kit - http://www.pspdev.org +# ----------------------------------------------------------------------- +# Licensed under the BSD license, see LICENSE in PSPSDK root for details. +# +# build.mak - Base makefile for projects using PSPSDK. +# +# Copyright (c) 2005 Marcus R. Brown +# Copyright (c) 2005 James Forshaw +# Copyright (c) 2005 John Kelley +# +# $Id: build.mak 771 2005-07-24 10:43:54Z tyranid $ + +# Note: The PSPSDK make variable must be defined before this file is included. +ifeq ($(PSPSDK),) +$(error $$(PSPSDK) is undefined. Use "PSPSDK := $$(shell psp-config --pspsdk-path)" in your Makefile) +endif + +CC = psp-gcc +CXX = psp-g++ +AS = psp-gcc +LD = psp-gcc +FIXUP = psp-fixup-imports + +# Add in PSPSDK includes and libraries. +INCDIR := $(INCDIR) . $(PSPSDK)/include +LIBDIR := $(LIBDIR) . $(PSPSDK)/lib + +CFLAGS := $(addprefix -I,$(INCDIR)) $(CFLAGS) +CXXFLAGS := $(CFLAGS) $(CXXFLAGS) +ASFLAGS := $(CFLAGS) $(ASFLAGS) + +LDFLAGS := $(addprefix -L,$(LIBDIR)) -Wl,-q,-T$(PSPSDK)/lib/linkfile.prx -mno-crt0 -nostartfiles $(LDFLAGS) + +ifeq ($(PSP_FW_VERSION),) +PSP_FW_VERSION=150 +endif + +CFLAGS += -D_PSP_FW_VERSION=$(PSP_FW_VERSION) + +# Library selection. By default we link with Newlib's libc. Allow the +# user to link with PSPSDK's libc if USE_PSPSDK_LIBC is set to 1. + +ifeq ($(USE_KERNEL_LIBC),1) +# Use the PSP's kernel libc +PSPSDK_LIBC_LIB = +CFLAGS := -I$(PSPSDK)/include/libc $(CFLAGS) +else +ifeq ($(USE_PSPSDK_LIBC),1) +# Use the pspsdk libc +PSPSDK_LIBC_LIB = -lpsplibc +CFLAGS := -I$(PSPSDK)/include/libc $(CFLAGS) +else +# Use newlib (urgh) +PSPSDK_LIBC_LIB = -lc +endif +endif + +# Link with following default libraries. Other libraries should be specified in the $(LIBS) variable. +# TODO: This library list needs to be generated at configure time. + +ifeq ($(USE_KERNEL_LIBS),1) +PSPSDK_LIBS = -lpspdebug -lpspdisplay_driver -lpspctrl_driver -lpspsdk +LIBS := $(LIBS) $(PSPSDK_LIBS) $(PSPSDK_LIBC_LIB) -lpspkernel +else +PSPSDK_LIBS = -lpspdebug -lpspdisplay -lpspge -lpspctrl -lpspsdk +LIBS := $(LIBS) $(PSPSDK_LIBS) $(PSPSDK_LIBC_LIB) -lpsputility -lpspuser -lpspkernel +endif + +FINAL_TARGET = $(TARGET).prx + +all: $(FINAL_TARGET) + +$(TARGET).elf: $(OBJS) + $(LINK.c) $^ $(LIBS) -o $@ + $(FIXUP) $@ + +%.prx: %.elf + psp-prxgen $< $@ + +%.c: %.exp + psp-build-exports -b $< > $@ + +clean: $(EXTRA_CLEAN) + -rm -f $(FINAL_TARGET) $(TARGET).elf $(OBJS) + +rebuild: clean all diff --git a/src/base/linkfile.prx.in b/src/base/linkfile.prx.in new file mode 100644 index 00000000..18c5946e --- /dev/null +++ b/src/base/linkfile.prx.in @@ -0,0 +1,246 @@ +/* Default linker script, for normal executables */ +OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips", + "elf32-littlemips") +OUTPUT_ARCH(mips:allegrex) +ENTRY(module_start) +SEARCH_DIR("@PSPDEV_LIBDIR@"); +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + PROVIDE (__executable_start = 0x0); . = 0x0; + .interp : { *(.interp) } + .dynamic : { *(.dynamic) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } + .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } + .rel.init : { *(.rel.init) } + .rela.init : { *(.rela.init) } + .rel.fini : { *(.rel.fini) } + .rela.fini : { *(.rela.fini) } + /* PSP-specific relocations. */ + .rel.sceStub.text : { *(.rel.sceStub.text) *(SORT(.rel.sceStub.text.*)) } + .rel.lib.ent.top : { *(.rel.lib.ent.top) } + .rel.lib.ent : { *(.rel.lib.ent) } + .rel.lib.ent.btm : { *(.rel.lib.ent.btm) } + .rel.lib.stub.top : { *(.rel.lib.stub.top) } + .rel.lib.stub : { *(.rel.lib.stub) } + .rel.lib.stub.btm : { *(.rel.lib.stub.btm) } + .rel.rodata.sceModuleInfo : { *(.rel.rodata.sceModuleInfo) } + .rel.rodata.sceResident : { *(.rel.rodata.sceResident) } + .rel.rodata.sceNid : { *(.rel.rodata.sceNid) } + .rel.rodata.sceVstub : { *(.rel.rodata.sceVstub) *(SORT(.rel.rodata.sceVstub.*)) } + .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } + .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } + .rel.data.rel.ro : { *(.rel.data.rel.ro*) } + .rela.data.rel.ro : { *(.rel.data.rel.ro*) } + .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } + .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } + .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } + .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } + .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } + .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) } + .rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) } + .rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) } + .rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) } + .rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) } + .rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) } + .rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) } + .rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) } + .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } + .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .text : + { + _ftext = . ; + *(.text .stub .text.* .gnu.linkonce.t.*) + KEEP (*(.text.*personality*)) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.mips16.fn.*) *(.mips16.call.*) + } =0 + .init : + { + KEEP (*(.init)) + } =0 + .plt : { *(.plt) } + .fini : + { + KEEP (*(.fini)) + } =0 + /* PSP library stub functions. */ + .sceStub.text : { *(.sceStub.text) *(SORT(.sceStub.text.*)) } + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + /* PSP library entry table and library stub table. */ + .lib.ent.top : { *(.lib.ent.top) } + .lib.ent : { *(.lib.ent) } + .lib.ent.btm : { *(.lib.ent.btm) } + .lib.stub.top : { *(.lib.stub.top) } + .lib.stub : { *(.lib.stub) } + .lib.stub.btm : { *(.lib.stub.btm) } + /* PSP read-only data for module info, NIDs, and Vstubs. The + .rodata.sceModuleInfo section must appear before the .rodata section + otherwise it would get absorbed into .rodata and the PSP bootloader + would be unable to locate the module info structure. */ + .rodata.sceModuleInfo : { *(.rodata.sceModuleInfo) } + .rodata.sceResident : { *(.rodata.sceResident) } + .rodata.sceNid : { KEEP (*(.rodata.sceNid)) } + .rodata.sceVstub : { *(.rodata.sceVstub) *(SORT(.rodata.sceVstub.*)) } + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) } + .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } + .eh_frame_hdr : { *(.eh_frame_hdr) } + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } + .gcc_except_table : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ + . = ALIGN(256) + (. & (256 - 1)); + /* Exception handling */ + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } + .gcc_except_table : ONLY_IF_RW { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } + /* Thread Local Storage sections */ + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + /* Ensure the __preinit_array_start label is properly aligned. We + could instead move the label definition inside the section, but + the linker would then create the section even if it turns out to + be empty, which isn't pretty. */ + . = ALIGN(32 / 8); + PROVIDE (__preinit_array_start = .); + .preinit_array : { KEEP (*(.preinit_array)) } + PROVIDE (__preinit_array_end = .); + PROVIDE (__init_array_start = .); + .init_array : { KEEP (*(.init_array)) } + PROVIDE (__init_array_end = .); + PROVIDE (__fini_array_start = .); + .fini_array : { KEEP (*(.fini_array)) } + PROVIDE (__fini_array_end = .); + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin*.o(.ctors)) + /* We don't want to include the .ctor section from + from the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } + .dtors : + { + KEEP (*crtbegin*.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } + .jcr : { KEEP (*(.jcr)) } + .data.rel.ro : { *(.data.rel.ro.local) *(.data.rel.ro*) } + .data : + { + _fdata = . ; + *(.data .data.* .gnu.linkonce.d.*) + KEEP (*(.gnu.linkonce.d.*personality*)) + SORT(CONSTRUCTORS) + } + .data1 : { *(.data1) } + . = .; + _gp = ALIGN(16) + 0x7ff0; + .got : { *(.got.plt) *(.got) } + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata : + { + *(.sdata .sdata.* .gnu.linkonce.s.*) + } + .lit8 : { *(.lit8) } + .lit4 : { *(.lit4) } + _edata = .; + PROVIDE (edata = .); + __bss_start = .; + _fbss = .; + .sbss : + { + PROVIDE (__sbss_start = .); + PROVIDE (___sbss_start = .); + *(.dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + PROVIDE (__sbss_end = .); + PROVIDE (___sbss_end = .); + } + .bss : + { + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. */ + . = ALIGN(32 / 8); + } + . = ALIGN(32 / 8); + _end = .; + PROVIDE (end = .); + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /DISCARD/ : { *(.comment) *(.pdr) } + /DISCARD/ : { *(.note.GNU-stack) } +} diff --git a/src/base/prxspecs b/src/base/prxspecs new file mode 100644 index 00000000..ed314149 --- /dev/null +++ b/src/base/prxspecs @@ -0,0 +1,2 @@ +*startfile: +crt0_prx%O%s crti%O%s crtbegin%O%s diff --git a/src/base/pspimport.s b/src/base/pspimport.s new file mode 100644 index 00000000..6dffc4b8 --- /dev/null +++ b/src/base/pspimport.s @@ -0,0 +1,68 @@ + +.macro IMPORT_START module, flags_ver + + .set push + .section .rodata.sceResident, "a" + .word 0 +__stub_modulestr_\module: + .asciz "\module" + .align 2 + + .section .lib.stub, "a", @progbits + .global __stub_module_\module +__stub_module_\module: + .word __stub_modulestr_\module + .word \flags_ver + .word 0x5 + .word __executable_start + .word __executable_start + + .set pop +.endm + +.macro IMPORT_FUNC module, funcid, funcname + + .set push + .set noreorder + + .extern __stub_module_\module + .section .sceStub.text, "ax", @progbits + .globl \funcname + .type \funcname, @function + .ent \funcname, 0 +\funcname: + .word __stub_module_\module + .word \funcid + .end \funcname + .size \funcname, .-\funcname + + .section .rodata.sceNid, "a" + .word \funcid + + .set pop +.endm + +.macro IMPORT_FUNC_WITH_ALIAS module, funcid, funcname, alias + + .set push + .set noreorder + + .extern __stub_module_\module + .section .sceStub.text, "ax", @progbits + .globl \alias + .type \alias, @function +\alias: + .globl \funcname + .type \funcname, @function + .ent \funcname, 0 +\funcname: + .word __stub_module_\module + .word \funcid + .end \funcname + .size \funcname, .-\funcname + + .section .rodata.sceNid, "a" + .word \funcid + + .set pop +.endm diff --git a/src/base/pspstub.s b/src/base/pspstub.s new file mode 100644 index 00000000..ca04503a --- /dev/null +++ b/src/base/pspstub.s @@ -0,0 +1,83 @@ +# common.s - GAS macros for creating import libraries. +# +# Use STUB_START to declare the start of an import library. The module parameter +# is the name of the library to import, flags_ver is both the import flags and library +# version, and stub_len is both the number of stubs to import and the size of the +# stub itself (in 32-bit words). +# Use the STUB_FUNC macro for each stub you want to import. The funcid parameter is +# the 32-bit SHA1-derived NID value, and the funcname is the name you want to call +# the imported function. +# Use STUB_END to declare the end of your import library. + +.macro STUB_START module, flags_ver, stub_len + + .set push + .section .rodata.sceResident, "a" + .word 0 +__stub_modulestr_\module: + .asciz "\module" + .align 2 + + .section .lib.stub, "a", @progbits + .word __stub_modulestr_\module + .word \flags_ver + .word \stub_len + .word __stub_idtable_\module + .word __stub_text_\module + + .section .rodata.sceNid, "a" +__stub_idtable_\module: + + .section .sceStub.text, "ax", @progbits +__stub_text_\module: + + .set pop +.endm + +.macro STUB_FUNC funcid, funcname + + .set push + .set noreorder + + .section .sceStub.text, "ax", @progbits + .globl \funcname + .type \funcname, @function + .ent \funcname, 0 +\funcname: + jr $ra + nop + .end \funcname + .size \funcname, .-\funcname + + .section .rodata.sceNid + .word \funcid + + .set pop +.endm + +.macro STUB_FUNC_WITH_ALIAS funcid, funcname, alias + + .set push + .set noreorder + + .section .sceStub.text, "ax", @progbits + .globl \alias + .type \alias, @function +\alias: + .globl \funcname + .type \funcname, @function + .ent \funcname, 0 +\funcname: + jr $ra + nop + .end \funcname + .size \funcname, .-\funcname + + .section .rodata.sceNid + .word \funcid + + .set pop +.endm + +.macro STUB_END +.endm diff --git a/src/base/psptypes.h b/src/base/psptypes.h new file mode 100644 index 00000000..acd88dcb --- /dev/null +++ b/src/base/psptypes.h @@ -0,0 +1,434 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * psptypes.h - Commonly used typedefs. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: psptypes.h 2312 2007-09-09 15:02:23Z chip $ + */ + +/* Note: Some of the structures, types, and definitions in this file were + extrapolated from symbolic debugging information found in the Japanese + version of Puzzle Bobble. */ + +#ifndef _PSPTYPES_H_ +#define _PSPTYPES_H_ 1 + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef NULL +#ifdef __cplusplus +#define NULL 0 +#else +#define NULL ((void *) 0) +#endif /* __cplusplus */ +#endif + +/* Legacy ps2dev types. */ +#ifndef PSP_LEGACY_TYPES_DEFINED +#define PSP_LEGACY_TYPES_DEFINED +typedef uint8_t u8; +typedef uint16_t u16; + +typedef uint32_t u32; +typedef uint64_t u64; + +typedef int8_t s8; +typedef int16_t s16; + +typedef int32_t s32; +typedef int64_t s64; +#endif + +#ifndef PSP_LEGACY_VOLATILE_TYPES_DEFINED +#define PSP_LEGACY_VOLATILE_TYPES_DEFINED +typedef volatile uint8_t vu8; +typedef volatile uint16_t vu16; + +typedef volatile uint32_t vu32; +typedef volatile uint64_t vu64; + +typedef volatile int8_t vs8; +typedef volatile int16_t vs16; + +typedef volatile int32_t vs32; +typedef volatile int64_t vs64; +#endif + +/* MIPS-like accessor macros. */ +static __inline__ u8 _lb(u32 addr) { return *(vu8 *)addr; } +static __inline__ u16 _lh(u32 addr) { return *(vu16 *)addr; } +static __inline__ u32 _lw(u32 addr) { return *(vu32 *)addr; } +static __inline__ u64 _ld(u32 addr) { return *(vu64 *)addr; } + +static __inline__ void _sb(u8 val, u32 addr) { *(vu8 *)addr = val; } +static __inline__ void _sh(u16 val, u32 addr) { *(vu16 *)addr = val; } +static __inline__ void _sw(u32 val, u32 addr) { *(vu32 *)addr = val; } +static __inline__ void _sd(u64 val, u32 addr) { *(vu64 *)addr = val; } + +/* SCE types. */ +typedef unsigned char SceUChar8; +typedef uint16_t SceUShort16; +typedef uint32_t SceUInt32; +typedef uint64_t SceUInt64; +typedef uint64_t SceULong64; +/*typedef unsigned int SceULong128 __attribute__((mode(TI)));*/ + +typedef char SceChar8; +typedef int16_t SceShort16; +typedef int32_t SceInt32; +typedef int64_t SceInt64; +typedef int64_t SceLong64; +/*typedef int SceLong128 __attribute__((mode(TI)));*/ + +typedef float SceFloat; +typedef float SceFloat32; + +typedef short unsigned int SceWChar16; +typedef unsigned int SceWChar32; + +typedef int SceBool; + +typedef void SceVoid; +typedef void * ScePVoid; + + +/* PSP types. */ + +/* Rectangles. */ +typedef struct ScePspSRect { + short int x; + short int y; + short int w; + short int h; +} ScePspSRect; + +typedef struct ScePspIRect { + int x; + int y; + int w; + int h; +} ScePspIRect; + +typedef struct ScePspL64Rect { + SceLong64 x; + SceLong64 y; + SceLong64 w; + SceLong64 h; +} ScePspL64Rect; + +typedef struct ScePspFRect { + float x; + float y; + float w; + float h; +} ScePspFRect; + +/* 2D vectors. */ +typedef struct ScePspSVector2 { + short int x; + short int y; +} ScePspSVector2; + +typedef struct ScePspIVector2 { + int x; + int y; +} ScePspIVector2; + +typedef struct ScePspL64Vector2 { + SceLong64 x; + SceLong64 y; +} ScePspL64Vector2; + +typedef struct ScePspFVector2 { + float x; + float y; +} ScePspFVector2; + +typedef union ScePspVector2 { + ScePspFVector2 fv; + ScePspIVector2 iv; + float f[2]; + int i[2]; +} ScePspVector2; + +/* 3D vectors. */ +typedef struct ScePspSVector3 { + short int x; + short int y; + short int z; +} ScePspSVector3; + +typedef struct ScePspIVector3 { + int x; + int y; + int z; +} ScePspIVector3; + +typedef struct ScePspL64Vector3 { + SceLong64 x; + SceLong64 y; + SceLong64 z; +} ScePspL64Vector3; + +typedef struct ScePspFVector3 { + float x; + float y; + float z; +} ScePspFVector3; + +typedef union ScePspVector3 { + ScePspFVector3 fv; + ScePspIVector3 iv; + float f[3]; + int i[3]; +} ScePspVector3; + +/* 4D vectors. */ +typedef struct ScePspSVector4 { + short int x; + short int y; + short int z; + short int w; +} ScePspSVector4; + +typedef struct ScePspIVector4 { + int x; + int y; + int z; + int w; +} ScePspIVector4; + +typedef struct ScePspL64Vector4 { + SceLong64 x; + SceLong64 y; + SceLong64 z; + SceLong64 w; +} ScePspL64Vector4; + +typedef struct ScePspFVector4 { + float x; + float y; + float z; + float w; +} ScePspFVector4 __attribute__((aligned(16))); + +typedef struct ScePspFVector4Unaligned { + float x; + float y; + float z; + float w; +} ScePspFVector4Unaligned; + +typedef union ScePspVector4 { + ScePspFVector4 fv; + ScePspIVector4 iv; +/* SceULong128 qw;*/ /* Missing compiler support. */ + float f[4]; + int i[4]; +} ScePspVector4 __attribute__((aligned(16))); + +/* 2D matrix types. */ +typedef struct ScePspIMatrix2 { + ScePspIVector2 x; + ScePspIVector2 y; +} ScePspIMatrix2; + +typedef struct ScePspFMatrix2 { + ScePspFVector2 x; + ScePspFVector2 y; +} ScePspFMatrix2; + +typedef union ScePspMatrix2 { + ScePspFMatrix2 fm; + ScePspIMatrix2 im; + ScePspFVector2 fv[2]; + ScePspIVector2 iv[2]; + ScePspVector2 v[2]; +/* SceULong128 qw[2];*/ /* Missing compiler support. */ + float f[2][2]; + int i[2][2]; +} ScePspMatrix2; + +/* 3D matrix types. */ +typedef struct ScePspIMatrix3 { + ScePspIVector3 x; + ScePspIVector3 y; + ScePspIVector3 z; +} ScePspIMatrix3; + +typedef struct ScePspFMatrix3 { + ScePspFVector3 x; + ScePspFVector3 y; + ScePspFVector3 z; +} ScePspFMatrix3; + +typedef union ScePspMatrix3 { + ScePspFMatrix3 fm; + ScePspIMatrix3 im; + ScePspFVector3 fv[3]; + ScePspIVector3 iv[3]; + ScePspVector3 v[3]; +/* SceULong128 qw[3];*/ /* Missing compiler support. */ + float f[3][3]; + int i[3][3]; +} ScePspMatrix3; + +/* 4D matrix types. */ +typedef struct ScePspIMatrix4 { + ScePspIVector4 x; + ScePspIVector4 y; + ScePspIVector4 z; + ScePspIVector4 w; +} ScePspIMatrix4 __attribute__((aligned(16))); + +typedef struct ScePspIMatrix4Unaligned { + ScePspIVector4 x; + ScePspIVector4 y; + ScePspIVector4 z; + ScePspIVector4 w; +} ScePspIMatrix4Unaligned; + +typedef struct ScePspFMatrix4 { + ScePspFVector4 x; + ScePspFVector4 y; + ScePspFVector4 z; + ScePspFVector4 w; +} ScePspFMatrix4 __attribute__((aligned(16))); + +typedef struct ScePspFMatrix4Unaligned { + ScePspFVector4 x; + ScePspFVector4 y; + ScePspFVector4 z; + ScePspFVector4 w; +} ScePspFMatrix4Unaligned; + +typedef union ScePspMatrix4 { + ScePspFMatrix4 fm; + ScePspIMatrix4 im; + ScePspFVector4 fv[4]; + ScePspIVector4 iv[4]; + ScePspVector4 v[4]; +/* SceULong128 qw[4];*/ /* Missing compiler support. */ + float f[4][4]; + int i[4][4]; +} ScePspMatrix4; + +/* Quaternions. */ +typedef struct ScePspFQuaternion { + float x; + float y; + float z; + float w; +} ScePspFQuaternion __attribute__((aligned(16))); + +typedef struct ScePspFQuaternionUnaligned { + float x; + float y; + float z; + float w; +} ScePspFQuaternionUnaligned; + +/* Colors and pixel formats. */ +typedef struct ScePspFColor { + float r; + float g; + float b; + float a; +} ScePspFColor __attribute__((aligned(16))); + +typedef struct ScePspFColorUnaligned { + float r; + float g; + float b; + float a; +} ScePspFColorUnaligned; + +typedef unsigned int ScePspRGBA8888; +typedef unsigned short ScePspRGBA4444; +typedef unsigned short ScePspRGBA5551; +typedef unsigned short ScePspRGB565; + +/* Unions for converting between types. */ +typedef union ScePspUnion32 { + unsigned int ui; + int i; + unsigned short us[2]; + short int s[2]; + unsigned char uc[4]; + char c[4]; + float f; + ScePspRGBA8888 rgba8888; + ScePspRGBA4444 rgba4444[2]; + ScePspRGBA5551 rgba5551[2]; + ScePspRGB565 rgb565[2]; +} ScePspUnion32; + +typedef union ScePspUnion64 { + SceULong64 ul; + SceLong64 l; + unsigned int ui[2]; + int i[2]; + unsigned short us[4]; + short int s[4]; + unsigned char uc[8]; + char c[8]; + float f[2]; + ScePspSRect sr; + ScePspSVector4 sv; + ScePspRGBA8888 rgba8888[2]; + ScePspRGBA4444 rgba4444[4]; + ScePspRGBA5551 rgba5551[4]; + ScePspRGB565 rgb565[4]; +} ScePspUnion64; + +typedef union ScePspUnion128 { +/* SceULong128 qw;*/ /* Missing compiler support. */ +/* SceULong128 uq;*/ +/* SceLong128 q;*/ + SceULong64 ul[2]; + SceLong64 l[2]; + unsigned int ui[4]; + int i[4]; + unsigned short us[8]; + short int s[8]; + unsigned char uc[16]; + char c[16]; + float f[4]; + ScePspFRect fr; + ScePspIRect ir; + ScePspFVector4 fv; + ScePspIVector4 iv; + ScePspFQuaternion fq; + ScePspFColor fc; + ScePspRGBA8888 rgba8888[4]; + ScePspRGBA4444 rgba4444[8]; + ScePspRGBA5551 rgba5551[8]; + ScePspRGB565 rgb565[8]; +} ScePspUnion128 __attribute__((aligned(16))); + +/* Date and time. */ +typedef struct ScePspDateTime { + unsigned short year; + unsigned short month; + unsigned short day; + unsigned short hour; + unsigned short minute; + unsigned short second; + unsigned int microsecond; +} ScePspDateTime; + +#ifdef __cplusplus +} +#endif + +#endif /* _PSPTYPES_H_ */ diff --git a/src/ctrl/Makefile.am b/src/ctrl/Makefile.am new file mode 100644 index 00000000..b88090f8 --- /dev/null +++ b/src/ctrl/Makefile.am @@ -0,0 +1,32 @@ + +libdir = @PSPSDK_LIBDIR@ + +CC = @PSP_CC@ +CCAS = $(CC) +AR = @PSP_AR@ +RANLIB = @PSP_RANLIB@ + +INCLUDES = -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel +CFLAGS = @PSPSDK_CFLAGS@ +CCASFLAGS = $(CFLAGS) -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel + +CTRL_OBJS = sceCtrl_0000.o sceCtrl_0001.o sceCtrl_0002.o sceCtrl_0003.o sceCtrl_0004.o sceCtrl_0005.o sceCtrl_0006.o sceCtrl_0007.o sceCtrl_0008.o sceCtrl_0009.o sceCtrl_0010.o sceCtrl_0011.o sceCtrl_0012.o sceCtrl_0013.o sceCtrl_0014.o sceCtrl_0015.o sceCtrl_0016.o + +CTRLDRIVER_OBJS = sceCtrl_driver_0000.o sceCtrl_driver_0001.o sceCtrl_driver_0002.o sceCtrl_driver_0003.o sceCtrl_driver_0004.o sceCtrl_driver_0005.o sceCtrl_driver_0006.o sceCtrl_driver_0007.o sceCtrl_driver_0008.o sceCtrl_driver_0009.o sceCtrl_driver_0010.o sceCtrl_driver_0011.o sceCtrl_driver_0012.o sceCtrl_driver_0013.o sceCtrl_driver_0014.o sceCtrl_driver_0015.o sceCtrl_driver_0016.o sceCtrl_driver_0017.o sceCtrl_driver_0018.o sceCtrl_driver_0019.o sceCtrl_driver_0020.o sceCtrl_driver_0021.o sceCtrl_driver_0022.o sceCtrl_driver_0023.o sceCtrl_driver_0024.o sceCtrl_driver_0025.o + +libpspctrlincludedir = @PSPSDK_INCLUDEDIR@ +libpspctrlinclude_HEADERS = pspctrl.h pspctrl_kernel.h + +lib_LIBRARIES = libpspctrl.a libpspctrl_driver.a +libpspctrl_a_SOURCES = sceCtrl.S +libpspctrl_a_LIBADD = $(CTRL_OBJS) + +libpspctrl_driver_a_SOURCES = sceCtrl_driver.S +libpspctrl_driver_a_LIBADD = $(CTRLDRIVER_OBJS) + +$(CTRL_OBJS): sceCtrl.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(CTRLDRIVER_OBJS): sceCtrl_driver.S + $(COMPILE) -DF_$* $< -c -o $@ + diff --git a/src/ctrl/pspctrl.h b/src/ctrl/pspctrl.h new file mode 100644 index 00000000..781f298b --- /dev/null +++ b/src/ctrl/pspctrl.h @@ -0,0 +1,206 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspctrl.h - Prototypes for the sceCtrl library. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: pspctrl.h 2433 2008-10-15 10:00:27Z iwn $ + */ + +/* Note: Some of the structures, types, and definitions in this file were + extrapolated from symbolic debugging information found in the Japanese + version of Puzzle Bobble. */ + +#ifndef __CTRL_H__ +#define __CTRL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup Ctrl Controller Kernel Library */ +/*@{*/ + +/** + * Enumeration for the digital controller buttons. + * + * @note PSP_CTRL_HOME, PSP_CTRL_NOTE, PSP_CTRL_SCREEN, PSP_CTRL_VOLUP, PSP_CTRL_VOLDOWN, PSP_CTRL_DISC, PSP_CTRL_WLAN_UP, PSP_CTRL_REMOTE, PSP_CTRL_MS can only be read in kernel mode + */ +enum PspCtrlButtons +{ + /** Select button. */ + PSP_CTRL_SELECT = 0x000001, + /** Start button. */ + PSP_CTRL_START = 0x000008, + /** Up D-Pad button. */ + PSP_CTRL_UP = 0x000010, + /** Right D-Pad button. */ + PSP_CTRL_RIGHT = 0x000020, + /** Down D-Pad button. */ + PSP_CTRL_DOWN = 0x000040, + /** Left D-Pad button. */ + PSP_CTRL_LEFT = 0x000080, + /** Left trigger. */ + PSP_CTRL_LTRIGGER = 0x000100, + /** Right trigger. */ + PSP_CTRL_RTRIGGER = 0x000200, + /** Triangle button. */ + PSP_CTRL_TRIANGLE = 0x001000, + /** Circle button. */ + PSP_CTRL_CIRCLE = 0x002000, + /** Cross button. */ + PSP_CTRL_CROSS = 0x004000, + /** Square button. */ + PSP_CTRL_SQUARE = 0x008000, + /** Home button. In user mode this bit is set if the exit dialog is visible. */ + PSP_CTRL_HOME = 0x010000, + /** Hold button. */ + PSP_CTRL_HOLD = 0x020000, + /** Music Note button. */ + PSP_CTRL_NOTE = 0x800000, + /** Screen button. */ + PSP_CTRL_SCREEN = 0x400000, + /** Volume up button. */ + PSP_CTRL_VOLUP = 0x100000, + /** Volume down button. */ + PSP_CTRL_VOLDOWN = 0x200000, + /** Wlan switch up. */ + PSP_CTRL_WLAN_UP = 0x040000, + /** Remote hold position. */ + PSP_CTRL_REMOTE = 0x080000, + /** Disc present. */ + PSP_CTRL_DISC = 0x1000000, + /** Memory stick present. */ + PSP_CTRL_MS = 0x2000000, +}; + +/** Controller mode. */ +enum PspCtrlMode +{ + /* Digitial. */ + PSP_CTRL_MODE_DIGITAL = 0, + /* Analog. */ + PSP_CTRL_MODE_ANALOG +}; + +/** Returned controller data */ +typedef struct SceCtrlData { + /** The current read frame. */ + unsigned int TimeStamp; + /** Bit mask containing zero or more of ::PspCtrlButtons. */ + unsigned int Buttons; + /** Analogue stick, X axis. */ + unsigned char Lx; + /** Analogue stick, Y axis. */ + unsigned char Ly; + /** Reserved. */ + unsigned char Rsrv[6]; +} SceCtrlData; + +typedef struct SceCtrlLatch { + unsigned int uiMake; + unsigned int uiBreak; + unsigned int uiPress; + unsigned int uiRelease; +} SceCtrlLatch; + +/** + * Set the controller cycle setting. + * + * @param cycle - Cycle. Normally set to 0. + * + * @return The previous cycle setting. + */ +int sceCtrlSetSamplingCycle(int cycle); + +/** + * Get the controller current cycle setting. + * + * @param pcycle - Return value. + * + * @return 0. + */ +int sceCtrlGetSamplingCycle(int *pcycle); + +/** + * Set the controller mode. + * + * @param mode - One of ::PspCtrlMode. + * + * @return The previous mode. + */ +int sceCtrlSetSamplingMode(int mode); + +/** + * Get the current controller mode. + * + * @param pmode - Return value. + * + * @return 0. + */ +int sceCtrlGetSamplingMode(int *pmode); + +int sceCtrlPeekBufferPositive(SceCtrlData *pad_data, int count); + +int sceCtrlPeekBufferNegative(SceCtrlData *pad_data, int count); + +/** + * Read buffer positive + * + * @par Example: + * @code + * SceCtrlData pad; + + * sceCtrlSetSamplingCycle(0); + * sceCtrlSetSamplingMode(1); + * sceCtrlReadBufferPositive(&pad, 1); + * // Do something with the read controller data + * @endcode + * + * @param pad_data - Pointer to a ::SceCtrlData structure used hold the returned pad data. + * @param count - Number of ::SceCtrlData buffers to read. + */ +int sceCtrlReadBufferPositive(SceCtrlData *pad_data, int count); + +int sceCtrlReadBufferNegative(SceCtrlData *pad_data, int count); + +int sceCtrlPeekLatch(SceCtrlLatch *latch_data); + +int sceCtrlReadLatch(SceCtrlLatch *latch_data); + +/** + * Set analog threshold relating to the idle timer. + * + * @param idlereset - Movement needed by the analog to reset the idle timer. + * @param idleback - Movement needed by the analog to bring the PSP back from an idle state. + * + * Set to -1 for analog to not cancel idle timer. + * Set to 0 for idle timer to be cancelled even if the analog is not moved. + * Set between 1 - 128 to specify the movement on either axis needed by the analog to fire the event. + * + * @return < 0 on error. + */ +int sceCtrlSetIdleCancelThreshold(int idlereset, int idleback); + +/** + * Get the idle threshold values. + * + * @param idlerest - Movement needed by the analog to reset the idle timer. + * @param idleback - Movement needed by the analog to bring the PSP back from an idle state. + * + * @return < 0 on error. + */ +int sceCtrlGetIdleCancelThreshold(int *idlerest, int *idleback); + +/*@}*/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/ctrl/pspctrl_kernel.h b/src/ctrl/pspctrl_kernel.h new file mode 100644 index 00000000..c6540633 --- /dev/null +++ b/src/ctrl/pspctrl_kernel.h @@ -0,0 +1,70 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspctrl_kernel.h - Prototypes for the sceCtrl_driver library. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: pspctrl_kernel.h 2433 2008-10-15 10:00:27Z iwn $ + */ + +#ifndef __CTRL_KERNEL_H__ +#define __CTRL_KERNEL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Set the controller button masks + * + * @param mask - The bits to setup + * @param type - The type of operation (0 clear, 1 set mask, 2 set button) + * + * @par Example: + * @code + * sceCtrl_driver_7CA723DC(0xFFFF, 1); // Mask lower 16bits + * sceCtrl_driver_7CA723DC(0x10000, 2); // Always return HOME key + * // Do something + * sceCtrl_driver_7CA723DC(0x10000, 0); // Unset HOME key + * sceCtrl_driver_7CA723DC(0xFFFF, 0); // Unset mask + * @endcode + */ +void sceCtrl_driver_7CA723DC(unsigned int mask, unsigned type); + +/** + * Get button mask mode + * + * @param mask - The bitmask to check + * + * @return 0 no setting, 1 set in button mask, 2 set in button set + */ +int sceCtrl_driver_5E77BC8A(unsigned int mask); + +/** + * Setup a controller callback + * + * @param no - The number of the callback (0-3) + * @param mask - The bits to check for + * @param cb - The callback function (int curr_but, int last_but, void *arg) + * @param arg - User defined argument passed + * + * @return 0 on success, < 0 on error + */ +int sceCtrl_driver_5C56C779(int no, unsigned int mask, void (*cb)(int, int, void*), void *arg); + +/* Just define some random names for the functions to make them easier to use */ +#define sceCtrlSetButtonMasks sceCtrl_driver_7CA723DC +#define sceCtrlGetButtonMask sceCtrl_driver_5E77BC8A +#define sceCtrlRegisterButtonCallback sceCtrl_driver_5C56C779 + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/ctrl/sceCtrl.S b/src/ctrl/sceCtrl.S new file mode 100644 index 00000000..de35a0d9 --- /dev/null +++ b/src/ctrl/sceCtrl.S @@ -0,0 +1,55 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceCtrl_0000 + IMPORT_START "sceCtrl",0x40010000 +#endif +#ifdef F_sceCtrl_0001 + IMPORT_FUNC "sceCtrl",0x6A2774F3,sceCtrlSetSamplingCycle +#endif +#ifdef F_sceCtrl_0002 + IMPORT_FUNC "sceCtrl",0x02BAAD91,sceCtrlGetSamplingCycle +#endif +#ifdef F_sceCtrl_0003 + IMPORT_FUNC "sceCtrl",0x1F4011E6,sceCtrlSetSamplingMode +#endif +#ifdef F_sceCtrl_0004 + IMPORT_FUNC "sceCtrl",0xDA6B76A1,sceCtrlGetSamplingMode +#endif +#ifdef F_sceCtrl_0005 + IMPORT_FUNC "sceCtrl",0x3A622550,sceCtrlPeekBufferPositive +#endif +#ifdef F_sceCtrl_0006 + IMPORT_FUNC "sceCtrl",0xC152080A,sceCtrlPeekBufferNegative +#endif +#ifdef F_sceCtrl_0007 + IMPORT_FUNC "sceCtrl",0x1F803938,sceCtrlReadBufferPositive +#endif +#ifdef F_sceCtrl_0008 + IMPORT_FUNC "sceCtrl",0x60B81F86,sceCtrlReadBufferNegative +#endif +#ifdef F_sceCtrl_0009 + IMPORT_FUNC "sceCtrl",0xB1D0E5CD,sceCtrlPeekLatch +#endif +#ifdef F_sceCtrl_0010 + IMPORT_FUNC "sceCtrl",0x0B588501,sceCtrlReadLatch +#endif +#ifdef F_sceCtrl_0011 + IMPORT_FUNC "sceCtrl",0x348D99D4,sceCtrl_348D99D4 +#endif +#ifdef F_sceCtrl_0012 + IMPORT_FUNC "sceCtrl",0xAF5960F3,sceCtrl_AF5960F3 +#endif +#ifdef F_sceCtrl_0013 + IMPORT_FUNC "sceCtrl",0xA68FD260,sceCtrlClearRapidFire +#endif +#ifdef F_sceCtrl_0014 + IMPORT_FUNC "sceCtrl",0x6841BE1A,sceCtrlSetRapidFire +#endif +#ifdef F_sceCtrl_0015 + IMPORT_FUNC "sceCtrl",0xA7144800,sceCtrlSetIdleCancelThreshold +#endif +#ifdef F_sceCtrl_0016 + IMPORT_FUNC "sceCtrl",0x687660FA,sceCtrlGetIdleCancelThreshold +#endif diff --git a/src/ctrl/sceCtrl_driver.S b/src/ctrl/sceCtrl_driver.S new file mode 100644 index 00000000..050fa32c --- /dev/null +++ b/src/ctrl/sceCtrl_driver.S @@ -0,0 +1,85 @@ + .set noreorder + +#include "pspimport.s" + +// Build List +// sceCtrl_driver_0000.o sceCtrl_driver_0001.o sceCtrl_driver_0002.o sceCtrl_driver_0003.o sceCtrl_driver_0004.o sceCtrl_driver_0005.o sceCtrl_driver_0006.o sceCtrl_driver_0007.o sceCtrl_driver_0008.o sceCtrl_driver_0009.o sceCtrl_driver_0010.o sceCtrl_driver_0011.o sceCtrl_driver_0012.o sceCtrl_driver_0013.o sceCtrl_driver_0014.o sceCtrl_driver_0015.o sceCtrl_driver_0016.o sceCtrl_driver_0017.o sceCtrl_driver_0018.o sceCtrl_driver_0019.o sceCtrl_driver_0020.o sceCtrl_driver_0021.o sceCtrl_driver_0022.o sceCtrl_driver_0023.o + +#ifdef F_sceCtrl_driver_0000 + IMPORT_START "sceCtrl_driver",0x00010000 +#endif +#ifdef F_sceCtrl_driver_0001 + IMPORT_FUNC "sceCtrl_driver",0x3E65A0EA,sceCtrlInit +#endif +#ifdef F_sceCtrl_driver_0002 + IMPORT_FUNC "sceCtrl_driver",0xE03956E9,sceCtrlEnd +#endif +#ifdef F_sceCtrl_driver_0003 + IMPORT_FUNC "sceCtrl_driver",0xC3F607F3,sceCtrlSuspend +#endif +#ifdef F_sceCtrl_driver_0004 + IMPORT_FUNC "sceCtrl_driver",0xC245B57B,sceCtrlResume +#endif +#ifdef F_sceCtrl_driver_0005 + IMPORT_FUNC "sceCtrl_driver",0x6A2774F3,sceCtrlSetSamplingCycle +#endif +#ifdef F_sceCtrl_driver_0006 + IMPORT_FUNC "sceCtrl_driver",0x02BAAD91,sceCtrlGetSamplingCycle +#endif +#ifdef F_sceCtrl_driver_0007 + IMPORT_FUNC "sceCtrl_driver",0x1F4011E6,sceCtrlSetSamplingMode +#endif +#ifdef F_sceCtrl_driver_0008 + IMPORT_FUNC "sceCtrl_driver",0xDA6B76A1,sceCtrlGetSamplingMode +#endif +#ifdef F_sceCtrl_driver_0009 + IMPORT_FUNC "sceCtrl_driver",0x3A622550,sceCtrlPeekBufferPositive +#endif +#ifdef F_sceCtrl_driver_0010 + IMPORT_FUNC "sceCtrl_driver",0xC152080A,sceCtrlPeekBufferNegative +#endif +#ifdef F_sceCtrl_driver_0011 + IMPORT_FUNC "sceCtrl_driver",0x1F803938,sceCtrlReadBufferPositive +#endif +#ifdef F_sceCtrl_driver_0012 + IMPORT_FUNC "sceCtrl_driver",0x60B81F86,sceCtrlReadBufferNegative +#endif +#ifdef F_sceCtrl_driver_0013 + IMPORT_FUNC "sceCtrl_driver",0xB1D0E5CD,sceCtrlPeekLatch +#endif +#ifdef F_sceCtrl_driver_0014 + IMPORT_FUNC "sceCtrl_driver",0x0B588501,sceCtrlReadLatch +#endif +#ifdef F_sceCtrl_driver_0015 + IMPORT_FUNC "sceCtrl_driver",0xA88E8D22,sceCtrlSetIdleCancelKey +#endif +#ifdef F_sceCtrl_driver_0016 + IMPORT_FUNC "sceCtrl_driver",0xB7CEAED4,sceCtrlGetIdleCancelKey +#endif +#ifdef F_sceCtrl_driver_0017 + IMPORT_FUNC "sceCtrl_driver",0x348D99D4,sceCtrl_driver_348D99D4 +#endif +#ifdef F_sceCtrl_driver_0018 + IMPORT_FUNC "sceCtrl_driver",0xAF5960F3,sceCtrl_driver_AF5960F3 +#endif +#ifdef F_sceCtrl_driver_0019 + IMPORT_FUNC "sceCtrl_driver",0xA68FD260,sceCtrlClearRapidFire +#endif +#ifdef F_sceCtrl_driver_0020 + IMPORT_FUNC "sceCtrl_driver",0x6841BE1A,sceCtrlSetRapidFire +#endif +#ifdef F_sceCtrl_driver_0021 + IMPORT_FUNC "sceCtrl_driver",0x7CA723DC,sceCtrl_driver_7CA723DC +#endif +#ifdef F_sceCtrl_driver_0022 + IMPORT_FUNC "sceCtrl_driver",0x5E77BC8A,sceCtrl_driver_5E77BC8A +#endif +#ifdef F_sceCtrl_driver_0023 + IMPORT_FUNC "sceCtrl_driver",0x5C56C779,sceCtrl_driver_5C56C779 +#endif +#ifdef F_sceCtrl_driver_0024 + IMPORT_FUNC "sceCtrl_driver",0xA7144800,sceCtrlSetIdleCancelThreshold +#endif +#ifdef F_sceCtrl_driver_0025 + IMPORT_FUNC "sceCtrl_driver",0x687660FA,sceCtrlGetIdleCancelThreshold +#endif diff --git a/src/debug/Makefile.am b/src/debug/Makefile.am new file mode 100644 index 00000000..5b4249ff --- /dev/null +++ b/src/debug/Makefile.am @@ -0,0 +1,50 @@ + +libdir = @PSPSDK_LIBDIR@ + +CC = @PSP_CC@ +CCAS = $(CC) +AR = @PSP_AR@ +RANLIB = @PSP_RANLIB@ + +INCLUDES = -I$(top_srcdir)/src/base \ + -I$(top_srcdir)/src/kernel \ + -I$(top_srcdir)/src/display \ + -I$(top_srcdir)/src/ge \ + -I$(top_srcdir)/src/user \ + -I$(top_srcdir)/src/ctrl +CFLAGS = @PSPSDK_CFLAGS@ +CCASFLAGS = $(CFLAGS) $(INCLUDES) + +SCRPRINT_OBJS = pspDebugScreenInit.o pspDebugScreenPrintf.o pspDebugScreenKprintf.o + +libpspdebugincludedir = @PSPSDK_INCLUDEDIR@ +libpspdebuginclude_HEADERS = \ + pspdebug.h pspdebugkb.h + +lib_LIBRARIES = libpspdebug.a libpspgdb.a libpspgdb_user.a libpspgdb_kernel.a libpspdebugkb.a + +libpspdebug_a_SOURCES = \ + callstack.c \ + callstackget.S \ + font.c \ + scr_printf.c \ + exception.c \ + exception_asm.S \ + kprintf.c \ + stacktrace.c \ + profiler.c \ + stdio.c \ + sio.c + +libpspdebug_a_LIBADD = $(SCRPRINT_OBJS) + +libpspgdb_a_SOURCES = gdb-stub.c + +libpspgdb_user_a_SOURCES = gdb-userlib.c + +libpspgdb_kernel_a_SOURCES = gdb-kernellib.c + +libpspdebugkb_a_SOURCES = pspdebugkb.c + +$(SCRPRINT_OBJS): scr_printf.c + $(COMPILE) -DF_$* $< -c -o $@ diff --git a/src/debug/callstack.c b/src/debug/callstack.c new file mode 100644 index 00000000..33f58053 --- /dev/null +++ b/src/debug/callstack.c @@ -0,0 +1,256 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * callstack.c - Return stack generation for MIPS processors. + * + * Copyright (c) 1992, 1998 The Open Group + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: callstack.c 1492 2005-11-26 23:19:30Z mrbrown $ + */ + +#include "pspdebug.h" + +/* + * $Xorg: getretmips.c,v 1.4 2001/02/09 02:06:19 xorgcvs Exp$ + * +Copyright 1992, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + * Author: Keith Packard, MIT X Consortium + * cleaned up slighly by emoon and added ee related opcodes and checking. + */ + +/* Return stack generation for MIPS processors + * This is tricky as MIPS stack frames aren't + * easily unrolled -- we look for pc restoration + * and stack adjustment instructions beyond the return + * address to discover the correct values + */ + +/* lw $31,const($sp) is : 100 011 11101 11111 const */ +/* 1000 1111 1011 1111 */ + +#define RESTORE_RETURNVAL 0x8fbf0000 +#define RESTORE_RETURNVAL_MASK 0xffff0000 + +/* ld $31,const($sp) is : 110 111 11101 11111 const */ +/* 1101 1111 1011 1111 */ + +#define RESTORE_RETURNVAL2 0xdfbf0000 + +/* lq $31,const($sp) is : 011110 11101 11111 const */ +/* ee Related 0111 1011 1011 1111 */ + +#define RESTORE_RETURNVAL3 0x7bbf0000 + +/* addiu $sp, $sp, const is 001 001 11101 11101 const */ +/* 0010 0111 1011 1101 const */ + +#define ADJUST_STACKP_C 0x27bd0000 +#define ADJUST_STACKP_C_MASK 0xffff0000 + +/* addu $sp, $sp, $at is 000 000 11101 00001 11101 00000 100 001 */ +/* 0000 0011 1010 0001 1110 1000 0010 0001 */ + +#define ADJUST_STACKP_V 0x03a1e821 +#define ADJUST_STACKP_V_MASK 0xffffffff + +/* lui $at, const is 001 111 00000 00001 const */ +/* 0011 1100 0000 0001 const */ + +#define SET_UPPER_C 0x3c010000 +#define SET_UPPER_C_MASK 0xffff0000 + +/* ori $at, $at, const is 001 101 00001 00001 const */ +/* 0011 0100 0010 0001 const */ + +#define OR_LOWER_C 0x34210000 +#define OR_LOWER_C_MASK 0xffff0000 + +/* ori $at, $zero, const is 001 101 00000 00001 const */ +/* 0011 0100 0000 0001 const */ + +#define SET_LOWER_C 0x34010000 +#define SET_LOWER_C_MASK 0xffff0000 + +/* jr $ra */ +#define RETURN 0x03e00008 + +#define CALL(f) (0x0c000000 | (((int) (f)) >> 2)) + +/* + * This computation is expensive, so we cache the results; + * a simple hash function and straight-forward replacement. + */ + +#define HASH_SIZE 256 + +typedef struct _returnCache +{ + unsigned int *returnAddress; + int raOffset; + int spAdjust; +} ReturnCacheRec, *ReturnCachePtr; + +static ReturnCacheRec returnCache[HASH_SIZE]; + +#define HASH(ra) ((((int) (ra)) >> 2) & (HASH_SIZE - 1)) + +typedef int Bool; + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +extern unsigned int *pspGetReturnAddress(); +extern unsigned int *pspGetStackPointer(); +extern int main(); + +int pspDebugGetStackTrace(unsigned int *results, int max) +{ + unsigned int *ra; + unsigned int *ra_limit; + unsigned int *sp; + unsigned int inst; + unsigned int mainCall; + unsigned short const_upper; + unsigned short const_lower; + int ra_offset; + int sp_adjust; + Bool found_ra_offset, found_sp_adjust; + Bool found_const_upper, found_const_lower; + ReturnCachePtr rc; + int total = max; + + ra = pspGetReturnAddress(); + sp = pspGetStackPointer(); + mainCall = CALL(main); + + while (ra && max) + { + rc = &returnCache[HASH(ra)]; + if (rc->returnAddress != ra) + { + found_ra_offset = FALSE; + found_sp_adjust = FALSE; + found_const_upper = FALSE; + found_const_lower = FALSE; + const_upper = 0; + const_lower = 0; + rc->returnAddress = ra; + ra_limit = (unsigned int *) 0x200000; + ra_offset = 0; + sp_adjust = -1; + + while ((!found_ra_offset || !found_sp_adjust) && ra < ra_limit) + { + inst = *ra; + /* look for the offset of the PC in the stack frame */ + if ((inst & RESTORE_RETURNVAL_MASK) == RESTORE_RETURNVAL) + { + ra_offset = inst & ~RESTORE_RETURNVAL_MASK; + found_ra_offset = TRUE; + } + else if ((inst & RESTORE_RETURNVAL_MASK) == RESTORE_RETURNVAL2) + { + ra_offset = inst & ~RESTORE_RETURNVAL_MASK; + found_ra_offset = TRUE; + } + else if ((inst & RESTORE_RETURNVAL_MASK) == RESTORE_RETURNVAL3) + { + ra_offset = inst & ~RESTORE_RETURNVAL_MASK; + found_ra_offset = TRUE; + } + else if ((inst & ADJUST_STACKP_C_MASK) == ADJUST_STACKP_C) + { + sp_adjust = inst & ~ADJUST_STACKP_C_MASK; + found_sp_adjust = TRUE; + } + else if ((inst & ADJUST_STACKP_V_MASK) == ADJUST_STACKP_V) + { + sp_adjust = 0; + found_sp_adjust = TRUE; + } + else if ((inst & SET_UPPER_C_MASK) == SET_UPPER_C) + { + const_upper = inst & ~SET_UPPER_C_MASK; + const_lower = 0; + found_const_upper = TRUE; + } + else if ((inst & OR_LOWER_C_MASK) == OR_LOWER_C) + { + const_lower = inst & ~OR_LOWER_C_MASK; + found_const_lower = TRUE; + } + else if ((inst & SET_LOWER_C_MASK) == SET_LOWER_C) + { + const_lower = inst & ~SET_LOWER_C_MASK; + const_upper = 0; + found_const_lower = TRUE; + } + else if (inst == RETURN) + ra_limit = ra + 2; + + ra++; + } + + if (sp_adjust == 0 && (found_const_upper || found_const_lower)) + sp_adjust = (const_upper << 16) | const_lower; + rc->raOffset = ra_offset; + rc->spAdjust = sp_adjust; + } + /* if something went wrong, punt */ + if (rc->spAdjust <= 0) + { + *results++ = 0; + break; + } + + ra = (unsigned int *) sp[rc->raOffset >> 2]; + sp += rc->spAdjust >> 2; + + if (ra == 0) + { + *results++ = 0; + break; + } + + *results++ = ((unsigned int) ra) - 8; + max--; + + if (ra[-2] == mainCall) + { + *results++ = 0; + break; + } + } + + return total - max; +} diff --git a/src/debug/callstackget.S b/src/debug/callstackget.S new file mode 100644 index 00000000..78d6d9af --- /dev/null +++ b/src/debug/callstackget.S @@ -0,0 +1,46 @@ +/* + * $XConsortium: mipsstack.s,v 1.3 94/04/17 20:59:45 keith Exp $ + * +Copyright (c) 1992 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), +to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + * + * Author: Keith Packard, MIT X Consortium + */ + + .globl pspGetReturnAddress + .ent pspGetReturnAddress +pspGetReturnAddress: + .frame $sp, 0, $31 + move $2,$31 + j $31 + .end pspGetReturnAddress + + .globl pspGetStackPointer + .ent pspGetStackPointer +pspGetStackPointer: + .frame $sp, 0, $31 + move $2,$29 + j $31 + .end pspGetStackPointer diff --git a/src/debug/exception.c b/src/debug/exception.c new file mode 100644 index 00000000..867bcd55 --- /dev/null +++ b/src/debug/exception.c @@ -0,0 +1,103 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspexception.c - Basic exception handler for applications. + * + * Copyright (c) 2005 James Forshaw + * + * $Id: exception.c 1777 2006-02-01 22:23:22Z tyranid $ + */ + +#include +#include +#include + +static PspDebugErrorHandler curr_handler = NULL; + +void _pspDebugExceptionHandler(void); +PspDebugRegBlock _pspDebugExceptRegs; + +int sceKernelRegisterDefaultExceptionHandler(void *func); + +/* Install an error handler */ +int pspDebugInstallErrorHandler(PspDebugErrorHandler handler) +{ + u32 addr; + + curr_handler = handler; + + addr = (u32) _pspDebugExceptionHandler; + addr |= 0x80000000; + + return sceKernelRegisterDefaultExceptionHandler((void *) addr); +} + +/* Mnemonic register names */ +static const unsigned char regName[32][5] = +{ + "zr", "at", "v0", "v1", "a0", "a1", "a2", "a3", + "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", + "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", + "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra" +}; + +/* Taken from the ps2, might not be 100% correct */ +static const char *codeTxt[32] = +{ + "Interrupt", "TLB modification", "TLB load/inst fetch", "TLB store", + "Address load/inst fetch", "Address store", "Bus error (instr)", + "Bus error (data)", "Syscall", "Breakpoint", "Reserved instruction", + "Coprocessor unusable", "Arithmetic overflow", "Unknown 13", "Unknown 14", + "FPU Exception", "Unknown 16", "Unknown 17", "Unknown 18", + "Unknown 20", "Unknown 21", "Unknown 22", "Unknown 23", + "Unknown 24", "Unknown 25", "Unknown 26", "Unknown 27", + "Unknown 28", "Unknown 29", "Unknown 30", "Unknown 31" +}; + +/* Dump an exception to screen */ +void pspDebugDumpException(PspDebugRegBlock *regs) +{ + int i; + + pspDebugScreenPrintf("Exception - %s\n", codeTxt[(regs->cause >> 2) & 31]); + pspDebugScreenPrintf("EPC - %08X\n", regs->epc); + pspDebugScreenPrintf("Cause - %08X\n", regs->cause); + pspDebugScreenPrintf("Status - %08X\n", regs->status); + pspDebugScreenPrintf("BadVAddr - %08X\n", regs->badvaddr); + for(i = 0; i < 32; i+=4) + { + pspDebugScreenPrintf("%s:%08X %s:%08X %s:%08X %s:%08X\n", regName[i], regs->r[i], + regName[i+1], regs->r[i+1], regName[i+2], regs->r[i+2], regName[i+3], regs->r[i+3]); + } + + sceDisplayWaitVblankStart(); +} + +/* Our default handler in case nothing else is installed */ +static void _pspDebugDefaultHandler(PspDebugRegBlock *regs) +{ + pspDebugScreenInit(); + pspDebugDumpException(regs); +} + +/** + * The entry point for our exception "trap" + */ +void _pspDebugTrapEntry(void) +{ + /* No special stack is used here, if the thread's stack is trashed we might be in trouble */ + if(curr_handler != NULL) + { + curr_handler(&_pspDebugExceptRegs); + } + else + { + _pspDebugDefaultHandler(&_pspDebugExceptRegs); + } + + /* Kill this thread as we cannot necessarily continue */ + /* Technically you might be able to "restart" after something like a break */ + sceKernelExitDeleteThread(0); +} diff --git a/src/debug/exception_asm.S b/src/debug/exception_asm.S new file mode 100644 index 00000000..4bcd1e06 --- /dev/null +++ b/src/debug/exception_asm.S @@ -0,0 +1,334 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspexception_asm.S - Basic exception handler for applications. + * + * Copyright (c) 2005 James Forshaw + * + * $Id$ + */ + +#include "as_reg_compat.h" + + .set noreorder + .set noat + +#define BadVAddr $8 // Address for the most recent address-related exception +#define Status $12 // Processor status and control +#define Cause $13 // Cause of last general exception +#define EPC $14 // Program counter at last exception +#define PRId $15 // Processor identification and revision + +#define FSR $31 +#define FIR $0 + +#define REG_GPR_0 (6*4) +#define REG_GPR_1 (REG_GPR_0 + 4) +#define REG_GPR_2 (REG_GPR_1 + 4) +#define REG_GPR_3 (REG_GPR_2 + 4) +#define REG_GPR_4 (REG_GPR_3 + 4) +#define REG_GPR_5 (REG_GPR_4 + 4) +#define REG_GPR_6 (REG_GPR_5 + 4) +#define REG_GPR_7 (REG_GPR_6 + 4) +#define REG_GPR_8 (REG_GPR_7 + 4) +#define REG_GPR_9 (REG_GPR_8 + 4) +#define REG_GPR_10 (REG_GPR_9 + 4) +#define REG_GPR_11 (REG_GPR_10 + 4) +#define REG_GPR_12 (REG_GPR_11 + 4) +#define REG_GPR_13 (REG_GPR_12 + 4) +#define REG_GPR_14 (REG_GPR_13 + 4) +#define REG_GPR_15 (REG_GPR_14 + 4) +#define REG_GPR_16 (REG_GPR_15 + 4) +#define REG_GPR_17 (REG_GPR_16 + 4) +#define REG_GPR_18 (REG_GPR_17 + 4) +#define REG_GPR_19 (REG_GPR_18 + 4) +#define REG_GPR_20 (REG_GPR_19 + 4) +#define REG_GPR_21 (REG_GPR_20 + 4) +#define REG_GPR_22 (REG_GPR_21 + 4) +#define REG_GPR_23 (REG_GPR_22 + 4) +#define REG_GPR_24 (REG_GPR_23 + 4) +#define REG_GPR_25 (REG_GPR_24 + 4) +#define REG_GPR_26 (REG_GPR_25 + 4) +#define REG_GPR_27 (REG_GPR_26 + 4) +#define REG_GPR_28 (REG_GPR_27 + 4) +#define REG_GPR_29 (REG_GPR_28 + 4) +#define REG_GPR_30 (REG_GPR_29 + 4) +#define REG_GPR_31 (REG_GPR_30 + 4) + +#define REG_STATUS (REG_GPR_31 + 4) +#define REG_LO (REG_STATUS + 4) +#define REG_HI (REG_LO + 4) +#define REG_BADVADDR (REG_HI + 4) +#define REG_CAUSE (REG_BADVADDR + 4) +#define REG_EPC (REG_CAUSE + 4) + +#define REG_FPR_0 (REG_EPC + 4) +#define REG_FPR_1 (REG_FPR_0 + 4) +#define REG_FPR_2 (REG_FPR_1 + 4) +#define REG_FPR_3 (REG_FPR_2 + 4) +#define REG_FPR_4 (REG_FPR_3 + 4) +#define REG_FPR_5 (REG_FPR_4 + 4) +#define REG_FPR_6 (REG_FPR_5 + 4) +#define REG_FPR_7 (REG_FPR_6 + 4) +#define REG_FPR_8 (REG_FPR_7 + 4) +#define REG_FPR_9 (REG_FPR_8 + 4) +#define REG_FPR_10 (REG_FPR_9 + 4) +#define REG_FPR_11 (REG_FPR_10 + 4) +#define REG_FPR_12 (REG_FPR_11 + 4) +#define REG_FPR_13 (REG_FPR_12 + 4) +#define REG_FPR_14 (REG_FPR_13 + 4) +#define REG_FPR_15 (REG_FPR_14 + 4) +#define REG_FPR_16 (REG_FPR_15 + 4) +#define REG_FPR_17 (REG_FPR_16 + 4) +#define REG_FPR_18 (REG_FPR_17 + 4) +#define REG_FPR_19 (REG_FPR_18 + 4) +#define REG_FPR_20 (REG_FPR_19 + 4) +#define REG_FPR_21 (REG_FPR_20 + 4) +#define REG_FPR_22 (REG_FPR_21 + 4) +#define REG_FPR_23 (REG_FPR_22 + 4) +#define REG_FPR_24 (REG_FPR_23 + 4) +#define REG_FPR_25 (REG_FPR_24 + 4) +#define REG_FPR_26 (REG_FPR_25 + 4) +#define REG_FPR_27 (REG_FPR_26 + 4) +#define REG_FPR_28 (REG_FPR_27 + 4) +#define REG_FPR_29 (REG_FPR_28 + 4) +#define REG_FPR_30 (REG_FPR_29 + 4) +#define REG_FPR_31 (REG_FPR_30 + 4) + +#define REG_FSR (REG_FPR_31 + 4) +#define REG_FIR (REG_FSR + 4) +#define REG_FP (REG_FIR + 4) + + .extern _pspDebugExceptRegs + .extern _pspDebugTrapEntry + + .global pspDebugResumeFromException + .ent pspDebugResumeFromException +pspDebugResumeFromException: + + break + + .end pspDebugResumeFromException + + .global _pspDebugExceptionHandler + .ent _pspDebugExceptionHandler +_pspDebugExceptionHandler: + nop + nop + la $v1, pspDebugResumeFromException + mfc0 $v0, EPC + beq $v0, $v1, _pspDebugExceptionResume + nop + + la $v0, _pspDebugExceptRegs + sw $0, REG_GPR_0($v0) + sw $1, REG_GPR_1($v0) + + cfc0 $1, $4 # Get original v0 + sw $1, REG_GPR_2($v0) + cfc0 $1, $5 # Get original v1 + sw $1, REG_GPR_3($v0) + sw $4, REG_GPR_4($v0) + sw $5, REG_GPR_5($v0) + sw $6, REG_GPR_6($v0) + sw $7, REG_GPR_7($v0) + sw $8, REG_GPR_8($v0) + sw $9, REG_GPR_9($v0) + sw $10, REG_GPR_10($v0) + sw $11, REG_GPR_11($v0) + sw $12, REG_GPR_12($v0) + sw $13, REG_GPR_13($v0) + sw $14, REG_GPR_14($v0) + sw $15, REG_GPR_15($v0) + sw $16, REG_GPR_16($v0) + sw $17, REG_GPR_17($v0) + sw $18, REG_GPR_18($v0) + sw $19, REG_GPR_19($v0) + sw $20, REG_GPR_20($v0) + sw $21, REG_GPR_21($v0) + sw $22, REG_GPR_22($v0) + sw $23, REG_GPR_23($v0) + sw $24, REG_GPR_24($v0) + sw $25, REG_GPR_25($v0) + sw $26, REG_GPR_26($v0) + sw $27, REG_GPR_27($v0) + sw $28, REG_GPR_28($v0) + sw $29, REG_GPR_29($v0) + sw $30, REG_GPR_30($v0) + sw $31, REG_GPR_31($v0) + + mflo $v1 + sw $v1, REG_LO($v0) + mfhi $v1 + sw $v1, REG_HI($v0) + mfc0 $v1, BadVAddr + sw $v1, REG_BADVADDR($v0) + mfc0 $v1, Cause + sw $v1, REG_CAUSE($v0) + mfc0 $v1, EPC + sw $v1, REG_EPC($v0) + mfc0 $v1, Status + sw $v1, REG_STATUS($v0) + +# Check if cop1 is enable and skip if not + lui $a0, 0x2000 + and $a0, $a0, $v1 + beq $a0, $0, 1f + nop + + swc1 $0, REG_FPR_0($v0) + swc1 $1, REG_FPR_1($v0) + swc1 $2, REG_FPR_2($v0) + swc1 $3, REG_FPR_3($v0) + swc1 $4, REG_FPR_4($v0) + swc1 $5, REG_FPR_5($v0) + swc1 $6, REG_FPR_6($v0) + swc1 $7, REG_FPR_7($v0) + swc1 $8, REG_FPR_8($v0) + swc1 $9, REG_FPR_9($v0) + swc1 $10, REG_FPR_10($v0) + swc1 $11, REG_FPR_11($v0) + swc1 $12, REG_FPR_12($v0) + swc1 $13, REG_FPR_13($v0) + swc1 $14, REG_FPR_14($v0) + swc1 $15, REG_FPR_15($v0) + swc1 $16, REG_FPR_16($v0) + swc1 $17, REG_FPR_17($v0) + swc1 $18, REG_FPR_18($v0) + swc1 $19, REG_FPR_19($v0) + swc1 $20, REG_FPR_20($v0) + swc1 $21, REG_FPR_21($v0) + swc1 $22, REG_FPR_22($v0) + swc1 $23, REG_FPR_23($v0) + swc1 $24, REG_FPR_24($v0) + swc1 $25, REG_FPR_25($v0) + swc1 $26, REG_FPR_26($v0) + swc1 $27, REG_FPR_27($v0) + swc1 $28, REG_FPR_28($v0) + swc1 $29, REG_FPR_29($v0) + swc1 $30, REG_FPR_30($v0) + swc1 $31, REG_FPR_31($v0) + + cfc1 $t0, FSR + sw $t0, REG_FSR($v0) + cfc1 $t0, FIR + sw $t0, REG_FIR($v0) + ctc1 $0, FSR # Clear any cause flags + +# Jump target for ignore cop1 +1: + + sw $sp, REG_FP($v0) + + la $2, _pspDebugTrapEntry + mtc0 $2, $14 + nop + nop + eret + nop + nop + + .end _pspDebugExceptionHandler + + .ent _pspDebugExceptionResume + +_pspDebugExceptionResume: + +# Resume from the exception in user mode (possibly, could be kernel but we don't really know that) + + la $v0, _pspDebugExceptRegs + + lw $v1, REG_STATUS($v0) + +# Check if cop1 is enable and skip if not + lui $a0, 0x2000 + and $a0, $a0, $v1 + beq $a0, $0, 1f + nop + + lwc1 $0, REG_FPR_0($v0) + lwc1 $1, REG_FPR_1($v0) + lwc1 $2, REG_FPR_2($v0) + lwc1 $3, REG_FPR_3($v0) + lwc1 $4, REG_FPR_4($v0) + lwc1 $5, REG_FPR_5($v0) + lwc1 $6, REG_FPR_6($v0) + lwc1 $7, REG_FPR_7($v0) + lwc1 $8, REG_FPR_8($v0) + lwc1 $9, REG_FPR_9($v0) + lwc1 $10, REG_FPR_10($v0) + lwc1 $11, REG_FPR_11($v0) + lwc1 $12, REG_FPR_12($v0) + lwc1 $13, REG_FPR_13($v0) + lwc1 $14, REG_FPR_14($v0) + lwc1 $15, REG_FPR_15($v0) + lwc1 $16, REG_FPR_16($v0) + lwc1 $17, REG_FPR_17($v0) + lwc1 $18, REG_FPR_18($v0) + lwc1 $19, REG_FPR_19($v0) + lwc1 $20, REG_FPR_20($v0) + lwc1 $21, REG_FPR_21($v0) + lwc1 $22, REG_FPR_22($v0) + lwc1 $23, REG_FPR_23($v0) + lwc1 $24, REG_FPR_24($v0) + lwc1 $25, REG_FPR_25($v0) + lwc1 $26, REG_FPR_26($v0) + lwc1 $27, REG_FPR_27($v0) + lwc1 $28, REG_FPR_28($v0) + lwc1 $29, REG_FPR_29($v0) + lwc1 $30, REG_FPR_30($v0) + lwc1 $31, REG_FPR_31($v0) + + lw $t0, REG_FSR($v0) + li $t1, 0xFFFC0F83 + and $t0, $t0, $t1 # Clear the cause and flags before ret + ctc1 $t0, FSR +1: + +# lw $0, REG_GPR_0($v0) +# lw $1, REG_GPR_1($v0) +# Don't do 2 yet + lw $3, REG_GPR_3($v0) + lw $4, REG_GPR_4($v0) + lw $5, REG_GPR_5($v0) + lw $6, REG_GPR_6($v0) + lw $7, REG_GPR_7($v0) + lw $8, REG_GPR_8($v0) + lw $9, REG_GPR_9($v0) + lw $10, REG_GPR_10($v0) + lw $11, REG_GPR_11($v0) + lw $12, REG_GPR_12($v0) + lw $13, REG_GPR_13($v0) + lw $14, REG_GPR_14($v0) + lw $15, REG_GPR_15($v0) + lw $16, REG_GPR_16($v0) + lw $17, REG_GPR_17($v0) + lw $18, REG_GPR_18($v0) + lw $19, REG_GPR_19($v0) + lw $20, REG_GPR_20($v0) + lw $21, REG_GPR_21($v0) + lw $22, REG_GPR_22($v0) + lw $23, REG_GPR_23($v0) + lw $24, REG_GPR_24($v0) + lw $25, REG_GPR_25($v0) + lw $26, REG_GPR_26($v0) + lw $27, REG_GPR_27($v0) + lw $28, REG_GPR_28($v0) + lw $29, REG_GPR_29($v0) + lw $30, REG_GPR_30($v0) + lw $31, REG_GPR_31($v0) + + lw $1, REG_EPC($v0) + mtc0 $1, EPC + +# Restore 1 + 2 now + lw $1, REG_GPR_1($v0) + lw $2, REG_GPR_2($v0) + + nop + nop + eret + + .end _pspDebugExceptionResume diff --git a/src/debug/font.c b/src/debug/font.c new file mode 100644 index 00000000..e6e20984 --- /dev/null +++ b/src/debug/font.c @@ -0,0 +1,147 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * font.c - Debug Font. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: font.c 540 2005-07-08 19:35:10Z warren $ + */ +#include + +u8 msx[]= +"\x00\x00\x00\x00\x00\x00\x00\x00\x3c\x42\xa5\x81\xa5\x99\x42\x3c" +"\x3c\x7e\xdb\xff\xff\xdb\x66\x3c\x6c\xfe\xfe\xfe\x7c\x38\x10\x00" +"\x10\x38\x7c\xfe\x7c\x38\x10\x00\x10\x38\x54\xfe\x54\x10\x38\x00" +"\x10\x38\x7c\xfe\xfe\x10\x38\x00\x00\x00\x00\x30\x30\x00\x00\x00" +"\xff\xff\xff\xe7\xe7\xff\xff\xff\x38\x44\x82\x82\x82\x44\x38\x00" +"\xc7\xbb\x7d\x7d\x7d\xbb\xc7\xff\x0f\x03\x05\x79\x88\x88\x88\x70" +"\x38\x44\x44\x44\x38\x10\x7c\x10\x30\x28\x24\x24\x28\x20\xe0\xc0" +"\x3c\x24\x3c\x24\x24\xe4\xdc\x18\x10\x54\x38\xee\x38\x54\x10\x00" +"\x10\x10\x10\x7c\x10\x10\x10\x10\x10\x10\x10\xff\x00\x00\x00\x00" +"\x00\x00\x00\xff\x10\x10\x10\x10\x10\x10\x10\xf0\x10\x10\x10\x10" +"\x10\x10\x10\x1f\x10\x10\x10\x10\x10\x10\x10\xff\x10\x10\x10\x10" +"\x10\x10\x10\x10\x10\x10\x10\x10\x00\x00\x00\xff\x00\x00\x00\x00" +"\x00\x00\x00\x1f\x10\x10\x10\x10\x00\x00\x00\xf0\x10\x10\x10\x10" +"\x10\x10\x10\x1f\x00\x00\x00\x00\x10\x10\x10\xf0\x00\x00\x00\x00" +"\x81\x42\x24\x18\x18\x24\x42\x81\x01\x02\x04\x08\x10\x20\x40\x80" +"\x80\x40\x20\x10\x08\x04\x02\x01\x00\x10\x10\xff\x10\x10\x00\x00" +"\x00\x00\x00\x00\x00\x00\x00\x00\x20\x20\x20\x20\x00\x00\x20\x00" +"\x50\x50\x50\x00\x00\x00\x00\x00\x50\x50\xf8\x50\xf8\x50\x50\x00" +"\x20\x78\xa0\x70\x28\xf0\x20\x00\xc0\xc8\x10\x20\x40\x98\x18\x00" +"\x40\xa0\x40\xa8\x90\x98\x60\x00\x10\x20\x40\x00\x00\x00\x00\x00" +"\x10\x20\x40\x40\x40\x20\x10\x00\x40\x20\x10\x10\x10\x20\x40\x00" +"\x20\xa8\x70\x20\x70\xa8\x20\x00\x00\x20\x20\xf8\x20\x20\x00\x00" +"\x00\x00\x00\x00\x00\x20\x20\x40\x00\x00\x00\x78\x00\x00\x00\x00" +"\x00\x00\x00\x00\x00\x60\x60\x00\x00\x00\x08\x10\x20\x40\x80\x00" +"\x70\x88\x98\xa8\xc8\x88\x70\x00\x20\x60\xa0\x20\x20\x20\xf8\x00" +"\x70\x88\x08\x10\x60\x80\xf8\x00\x70\x88\x08\x30\x08\x88\x70\x00" +"\x10\x30\x50\x90\xf8\x10\x10\x00\xf8\x80\xe0\x10\x08\x10\xe0\x00" +"\x30\x40\x80\xf0\x88\x88\x70\x00\xf8\x88\x10\x20\x20\x20\x20\x00" +"\x70\x88\x88\x70\x88\x88\x70\x00\x70\x88\x88\x78\x08\x10\x60\x00" +"\x00\x00\x20\x00\x00\x20\x00\x00\x00\x00\x20\x00\x00\x20\x20\x40" +"\x18\x30\x60\xc0\x60\x30\x18\x00\x00\x00\xf8\x00\xf8\x00\x00\x00" +"\xc0\x60\x30\x18\x30\x60\xc0\x00\x70\x88\x08\x10\x20\x00\x20\x00" +"\x70\x88\x08\x68\xa8\xa8\x70\x00\x20\x50\x88\x88\xf8\x88\x88\x00" +"\xf0\x48\x48\x70\x48\x48\xf0\x00\x30\x48\x80\x80\x80\x48\x30\x00" +"\xe0\x50\x48\x48\x48\x50\xe0\x00\xf8\x80\x80\xf0\x80\x80\xf8\x00" +"\xf8\x80\x80\xf0\x80\x80\x80\x00\x70\x88\x80\xb8\x88\x88\x70\x00" +"\x88\x88\x88\xf8\x88\x88\x88\x00\x70\x20\x20\x20\x20\x20\x70\x00" +"\x38\x10\x10\x10\x90\x90\x60\x00\x88\x90\xa0\xc0\xa0\x90\x88\x00" +"\x80\x80\x80\x80\x80\x80\xf8\x00\x88\xd8\xa8\xa8\x88\x88\x88\x00" +"\x88\xc8\xc8\xa8\x98\x98\x88\x00\x70\x88\x88\x88\x88\x88\x70\x00" +"\xf0\x88\x88\xf0\x80\x80\x80\x00\x70\x88\x88\x88\xa8\x90\x68\x00" +"\xf0\x88\x88\xf0\xa0\x90\x88\x00\x70\x88\x80\x70\x08\x88\x70\x00" +"\xf8\x20\x20\x20\x20\x20\x20\x00\x88\x88\x88\x88\x88\x88\x70\x00" +"\x88\x88\x88\x88\x50\x50\x20\x00\x88\x88\x88\xa8\xa8\xd8\x88\x00" +"\x88\x88\x50\x20\x50\x88\x88\x00\x88\x88\x88\x70\x20\x20\x20\x00" +"\xf8\x08\x10\x20\x40\x80\xf8\x00\x70\x40\x40\x40\x40\x40\x70\x00" +"\x00\x00\x80\x40\x20\x10\x08\x00\x70\x10\x10\x10\x10\x10\x70\x00" +"\x20\x50\x88\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8\x00" +"\x40\x20\x10\x00\x00\x00\x00\x00\x00\x00\x70\x08\x78\x88\x78\x00" +"\x80\x80\xb0\xc8\x88\xc8\xb0\x00\x00\x00\x70\x88\x80\x88\x70\x00" +"\x08\x08\x68\x98\x88\x98\x68\x00\x00\x00\x70\x88\xf8\x80\x70\x00" +"\x10\x28\x20\xf8\x20\x20\x20\x00\x00\x00\x68\x98\x98\x68\x08\x70" +"\x80\x80\xf0\x88\x88\x88\x88\x00\x20\x00\x60\x20\x20\x20\x70\x00" +"\x10\x00\x30\x10\x10\x10\x90\x60\x40\x40\x48\x50\x60\x50\x48\x00" +"\x60\x20\x20\x20\x20\x20\x70\x00\x00\x00\xd0\xa8\xa8\xa8\xa8\x00" +"\x00\x00\xb0\xc8\x88\x88\x88\x00\x00\x00\x70\x88\x88\x88\x70\x00" +"\x00\x00\xb0\xc8\xc8\xb0\x80\x80\x00\x00\x68\x98\x98\x68\x08\x08" +"\x00\x00\xb0\xc8\x80\x80\x80\x00\x00\x00\x78\x80\xf0\x08\xf0\x00" +"\x40\x40\xf0\x40\x40\x48\x30\x00\x00\x00\x90\x90\x90\x90\x68\x00" +"\x00\x00\x88\x88\x88\x50\x20\x00\x00\x00\x88\xa8\xa8\xa8\x50\x00" +"\x00\x00\x88\x50\x20\x50\x88\x00\x00\x00\x88\x88\x98\x68\x08\x70" +"\x00\x00\xf8\x10\x20\x40\xf8\x00\x18\x20\x20\x40\x20\x20\x18\x00" +"\x20\x20\x20\x00\x20\x20\x20\x00\xc0\x20\x20\x10\x20\x20\xc0\x00" +"\x40\xa8\x10\x00\x00\x00\x00\x00\x00\x00\x20\x50\xf8\x00\x00\x00" +"\x70\x88\x80\x80\x88\x70\x20\x60\x90\x00\x00\x90\x90\x90\x68\x00" +"\x10\x20\x70\x88\xf8\x80\x70\x00\x20\x50\x70\x08\x78\x88\x78\x00" +"\x48\x00\x70\x08\x78\x88\x78\x00\x20\x10\x70\x08\x78\x88\x78\x00" +"\x20\x00\x70\x08\x78\x88\x78\x00\x00\x70\x80\x80\x80\x70\x10\x60" +"\x20\x50\x70\x88\xf8\x80\x70\x00\x50\x00\x70\x88\xf8\x80\x70\x00" +"\x20\x10\x70\x88\xf8\x80\x70\x00\x50\x00\x00\x60\x20\x20\x70\x00" +"\x20\x50\x00\x60\x20\x20\x70\x00\x40\x20\x00\x60\x20\x20\x70\x00" +"\x50\x00\x20\x50\x88\xf8\x88\x00\x20\x00\x20\x50\x88\xf8\x88\x00" +"\x10\x20\xf8\x80\xf0\x80\xf8\x00\x00\x00\x6c\x12\x7e\x90\x6e\x00" +"\x3e\x50\x90\x9c\xf0\x90\x9e\x00\x60\x90\x00\x60\x90\x90\x60\x00" +"\x90\x00\x00\x60\x90\x90\x60\x00\x40\x20\x00\x60\x90\x90\x60\x00" +"\x40\xa0\x00\xa0\xa0\xa0\x50\x00\x40\x20\x00\xa0\xa0\xa0\x50\x00" +"\x90\x00\x90\x90\xb0\x50\x10\xe0\x50\x00\x70\x88\x88\x88\x70\x00" +"\x50\x00\x88\x88\x88\x88\x70\x00\x20\x20\x78\x80\x80\x78\x20\x20" +"\x18\x24\x20\xf8\x20\xe2\x5c\x00\x88\x50\x20\xf8\x20\xf8\x20\x00" +"\xc0\xa0\xa0\xc8\x9c\x88\x88\x8c\x18\x20\x20\xf8\x20\x20\x20\x40" +"\x10\x20\x70\x08\x78\x88\x78\x00\x10\x20\x00\x60\x20\x20\x70\x00" +"\x20\x40\x00\x60\x90\x90\x60\x00\x20\x40\x00\x90\x90\x90\x68\x00" +"\x50\xa0\x00\xa0\xd0\x90\x90\x00\x28\x50\x00\xc8\xa8\x98\x88\x00" +"\x00\x70\x08\x78\x88\x78\x00\xf8\x00\x60\x90\x90\x90\x60\x00\xf0" +"\x20\x00\x20\x40\x80\x88\x70\x00\x00\x00\x00\xf8\x80\x80\x00\x00" +"\x00\x00\x00\xf8\x08\x08\x00\x00\x84\x88\x90\xa8\x54\x84\x08\x1c" +"\x84\x88\x90\xa8\x58\xa8\x3c\x08\x20\x00\x00\x20\x20\x20\x20\x00" +"\x00\x00\x24\x48\x90\x48\x24\x00\x00\x00\x90\x48\x24\x48\x90\x00" +"\x28\x50\x20\x50\x88\xf8\x88\x00\x28\x50\x70\x08\x78\x88\x78\x00" +"\x28\x50\x00\x70\x20\x20\x70\x00\x28\x50\x00\x20\x20\x20\x70\x00" +"\x28\x50\x00\x70\x88\x88\x70\x00\x50\xa0\x00\x60\x90\x90\x60\x00" +"\x28\x50\x00\x88\x88\x88\x70\x00\x50\xa0\x00\xa0\xa0\xa0\x50\x00" +"\xfc\x48\x48\x48\xe8\x08\x50\x20\x00\x50\x00\x50\x50\x50\x10\x20" +"\xc0\x44\xc8\x54\xec\x54\x9e\x04\x10\xa8\x40\x00\x00\x00\x00\x00" +"\x00\x20\x50\x88\x50\x20\x00\x00\x88\x10\x20\x40\x80\x28\x00\x00" +"\x7c\xa8\xa8\x68\x28\x28\x28\x00\x38\x40\x30\x48\x48\x30\x08\x70" +"\x00\x00\x00\x00\x00\x00\xff\xff\xf0\xf0\xf0\xf0\x0f\x0f\x0f\x0f" +"\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00" +"\x00\x00\x00\x3c\x3c\x00\x00\x00\xff\xff\xff\xff\xff\xff\x00\x00" +"\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\x0f\x0f\x0f\x0f\xf0\xf0\xf0\xf0" +"\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\x03\x03\x03\x03\x03\x03\x03\x03" +"\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x11\x22\x44\x88\x11\x22\x44\x88" +"\x88\x44\x22\x11\x88\x44\x22\x11\xfe\x7c\x38\x10\x00\x00\x00\x00" +"\x00\x00\x00\x00\x10\x38\x7c\xfe\x80\xc0\xe0\xf0\xe0\xc0\x80\x00" +"\x01\x03\x07\x0f\x07\x03\x01\x00\xff\x7e\x3c\x18\x18\x3c\x7e\xff" +"\x81\xc3\xe7\xff\xff\xe7\xc3\x81\xf0\xf0\xf0\xf0\x00\x00\x00\x00" +"\x00\x00\x00\x00\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x00\x00\x00\x00" +"\x00\x00\x00\x00\xf0\xf0\xf0\xf0\x33\x33\xcc\xcc\x33\x33\xcc\xcc" +"\x00\x20\x20\x50\x50\x88\xf8\x00\x20\x20\x70\x20\x70\x20\x20\x00" +"\x00\x00\x00\x50\x88\xa8\x50\x00\xff\xff\xff\xff\xff\xff\xff\xff" +"\x00\x00\x00\x00\xff\xff\xff\xff\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0" +"\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\xff\xff\xff\xff\x00\x00\x00\x00" +"\x00\x00\x68\x90\x90\x90\x68\x00\x30\x48\x48\x70\x48\x48\x70\xc0" +"\xf8\x88\x80\x80\x80\x80\x80\x00\xf8\x50\x50\x50\x50\x50\x98\x00" +"\xf8\x88\x40\x20\x40\x88\xf8\x00\x00\x00\x78\x90\x90\x90\x60\x00" +"\x00\x50\x50\x50\x50\x68\x80\x80\x00\x50\xa0\x20\x20\x20\x20\x00" +"\xf8\x20\x70\xa8\xa8\x70\x20\xf8\x20\x50\x88\xf8\x88\x50\x20\x00" +"\x70\x88\x88\x88\x50\x50\xd8\x00\x30\x40\x40\x20\x50\x50\x50\x20" +"\x00\x00\x00\x50\xa8\xa8\x50\x00\x08\x70\xa8\xa8\xa8\x70\x80\x00" +"\x38\x40\x80\xf8\x80\x40\x38\x00\x70\x88\x88\x88\x88\x88\x88\x00" +"\x00\xf8\x00\xf8\x00\xf8\x00\x00\x20\x20\xf8\x20\x20\x00\xf8\x00" +"\xc0\x30\x08\x30\xc0\x00\xf8\x00\x18\x60\x80\x60\x18\x00\xf8\x00" +"\x10\x28\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\xa0\x40" +"\x00\x20\x00\xf8\x00\x20\x00\x00\x00\x50\xa0\x00\x50\xa0\x00\x00" +"\x00\x18\x24\x24\x18\x00\x00\x00\x00\x30\x78\x78\x30\x00\x00\x00" +"\x00\x00\x00\x00\x30\x00\x00\x00\x3e\x20\x20\x20\xa0\x60\x20\x00" +"\xa0\x50\x50\x50\x00\x00\x00\x00\x40\xa0\x20\x40\xe0\x00\x00\x00" +"\x00\x38\x38\x38\x38\x38\x38\x00\x00\x00\x00\x00\x00\x00\x00"; + + + diff --git a/src/debug/gdb-kernellib.c b/src/debug/gdb-kernellib.c new file mode 100644 index 00000000..0ed94b28 --- /dev/null +++ b/src/debug/gdb-kernellib.c @@ -0,0 +1,91 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * gdb-kernellib.c - GDB support functions for kernel mode. + * + * Copyright (c) 2005 James Forshaw + * + * $Id: gdb-kernellib.c 1492 2005-11-26 23:19:30Z mrbrown $ + */ +#include +#include + +/* GDB Debug putchar */ +void putDebugChar(char ch) +{ + pspDebugSioPutchar(ch); +} + +/* GDB Debug getchar */ +char getDebugChar(void) +{ + int ch = 0; + + while(1) + { + ch = pspDebugSioGetchar(); + if(ch != -1) + { + break; + } + } + + return ch; +} + +void sceKernelDcacheWBinvAll(void); +void sceKernelIcacheClearAll(void); + +void _gdbSupportLibFlushCaches(void) +{ + pspKernelSetKernelPC(); + sceKernelDcacheWBinvAll(); + sceKernelIcacheClearAll(); +} + +int _gdbSupportLibReadByte(unsigned char *address, unsigned char *dest) +{ + u32 addr; + + addr = (u32) address; + if((addr >= 0x08400000) && (addr < 0x0a000000)) + { + *dest = *address; + return 1; + } + else if((addr >= 0x88000000) && (addr < 0x8a000000)) + { + *dest = *address; + return 1; + } + + return 0; +} + +int _gdbSupportLibWriteByte(char val, unsigned char *dest) +{ + u32 addr; + + addr = (u32) dest; + if((addr >= 0x08400000) && (addr < 0x0a000000)) + { + *dest = val; + return 1; + } + else if((addr >= 0x88000000) && (addr < 0x8a000000)) + { + *dest = val; + return 1; + } + + return 0; +} + +int _gdbSupportLibInit(void) +{ + /* Do nothing */ + + return 0; +} diff --git a/src/debug/gdb-stub.c b/src/debug/gdb-stub.c new file mode 100644 index 00000000..b6b50fe5 --- /dev/null +++ b/src/debug/gdb-stub.c @@ -0,0 +1,822 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * gdb-stub.c - Simple remote GDB stub for the psp. + * + * Copyright (c) 2005 James Forshaw + * + * $Id: gdb-stub.c 1152 2005-10-16 20:37:00Z tyranid $ + */ + +/* Note: there is the odd small bit which comes from the gdb stubs/linux mips stub */ +/* As far as I am aware they didn't have an explicit license on them so... */ + +#include +#include +#include +#include + +//#define DEBUG + +#ifdef DEBUG +#define DEBUG_PRINTF(fmt, ...) pspDebugScreenPrintf(fmt, ## __VA_ARGS__) +#else +#define DEBUG_PRINTF(fmt, ...) +#endif + +/* + * breakpoint and test functions + */ +void pspDebugBreakpoint(void); +void putDebugChar(char ch); +char getDebugChar(void); +int _gdbSupportLibWriteByte(char val, unsigned char *dest); +int _gdbSupportLibReadByte(unsigned char *address, unsigned char *dest); +//void _pspDebugExceptionResume(void); +void pspDebugResumeFromException(void); +void _gdbSupportLibFlushCaches(void); +extern u32 _pspDebugResumePatch; + +extern int sceKernelSuspendIntr(void); +extern void sceKernelResumeIntr(int intr); + +static void handle_exception(PspDebugRegBlock *regs); + +#define MAX_BUF 2048 + +void _GdbExceptionHandler(void); +static PspDebugRegBlock *_GdbExceptRegs; +static int initialised = 0; +static char input[MAX_BUF]; +static char output[MAX_BUF]; +static const char hexchars[]="0123456789abcdef"; +static char last_cmd = 0; +static int attached = 0; + +/* Define a software breakpoint structure */ +struct sw_breakpoint +{ + unsigned int addr; + unsigned int oldinst; + unsigned int active; +}; + +static struct sw_breakpoint g_stepbp[2]; + +/* + * send the packet in buffer. + */ +static void putpacket(unsigned char *buffer) +{ + unsigned char checksum; + int count; + unsigned char ch; + + /* + * $#. + */ + + do { + putDebugChar('$'); + checksum = 0; + count = 0; + + while ((ch = buffer[count]) != 0) { + checksum += ch; + count += 1; + putDebugChar(ch); + } + + putDebugChar('#'); + putDebugChar(hexchars[(checksum >> 4) & 0xf]); + putDebugChar(hexchars[checksum & 0xf]); + + DEBUG_PRINTF("calculated checksum = %02X\n", checksum); + } + while ((getDebugChar() & 0x7f) != '+'); +} + +static char get_char(void) +{ + int ch; + + while((ch = pspDebugSioGetchar()) == -1); + + return ch; +} + +/* + * send the packet in buffer. + */ +static int stdout_handler(const char *data, int len) +{ + unsigned char checksum; + int count; + unsigned char ch; + + if(!attached) + { + return 0; + } + + /* + * $#. + */ + + do { + pspDebugSioPutchar('$'); + pspDebugSioPutchar('O'); + + checksum = 'O'; + count = 0; + + while(1) + { + if(count == len) + { + break; + } + + ch = hexchars[(data[count] >> 4) & 0xF]; + pspDebugSioPutchar(ch); + checksum += ch; + ch = hexchars[data[count] & 0xF]; + pspDebugSioPutchar(ch); + checksum += ch; + count += 1; + } + + pspDebugSioPutchar('#'); + pspDebugSioPutchar(hexchars[(checksum >> 4) & 0xf]); + pspDebugSioPutchar(hexchars[checksum & 0xf]); + } + while ((get_char() & 0x7f) != '+'); + + return count; +} + +/* + * Convert ch from a hex digit to an int + */ +static int hex(unsigned char ch) +{ + if (ch >= 'a' && ch <= 'f') + return ch-'a'+10; + if (ch >= '0' && ch <= '9') + return ch-'0'; + if (ch >= 'A' && ch <= 'F') + return ch-'A'+10; + return -1; +} + +/* + * scan for the sequence $# + */ +static void getpacket(char *buffer) +{ + unsigned char checksum; + unsigned char xmitcsum; + int i; + int count; + unsigned char ch; + + do { + /* + * wait around for the start character, + * ignore all other characters + */ + while ((ch = (getDebugChar() & 0x7f)) != '$') ; + + checksum = 0; + xmitcsum = -1; + count = 0; + + /* + * now, read until a # or end of buffer is found + */ + while (count < MAX_BUF) { + ch = getDebugChar(); + if (ch == '#') + break; + checksum = checksum + ch; + buffer[count] = ch; + count = count + 1; + } + + if (count >= MAX_BUF) + continue; + + buffer[count] = 0; + + if (ch == '#') { + xmitcsum = hex(getDebugChar() & 0x7f) << 4; + xmitcsum |= hex(getDebugChar() & 0x7f); + + if (checksum != xmitcsum) + putDebugChar('-'); /* failed checksum */ + else { + putDebugChar('+'); /* successful transfer */ + + /* + * if a sequence char is present, + * reply the sequence ID + */ + if (buffer[2] == ':') { + putDebugChar(buffer[0]); + putDebugChar(buffer[1]); + + /* + * remove sequence chars from buffer + */ + count = strlen(buffer); + for (i=3; i <= count; i++) + buffer[i-3] = buffer[i]; + } + } + } + } + while (checksum != xmitcsum); +} + +static struct hard_trap_info { + unsigned char tt; /* Trap type code for MIPS R3xxx and R4xxx */ + unsigned char signo; /* Signal that we map this trap into */ +} hard_trap_info[] = { + { 6, SIGBUS }, /* instruction bus error */ + { 7, SIGBUS }, /* data bus error */ + { 9, SIGTRAP }, /* break */ + { 10, SIGILL }, /* reserved instruction */ + { 12, SIGFPE }, /* overflow */ + { 13, SIGTRAP }, /* trap */ + { 14, SIGSEGV }, /* virtual instruction cache coherency */ + { 15, SIGFPE }, /* floating point exception */ + { 23, SIGSEGV }, /* watch */ + { 31, SIGSEGV }, /* virtual data cache coherency */ + { 0, 0} /* Must be last */ +}; + +static int computeSignal(int tt) +{ + struct hard_trap_info *ht; + + for (ht = hard_trap_info; ht->tt && ht->signo; ht++) + if (ht->tt == tt) + return ht->signo; + + return SIGHUP; /* default for things we don't know about */ +} + + +static void _GdbTrapEntry(PspDebugRegBlock *regs) +{ + /* Get the current priority and increment by one ? */ + _GdbExceptRegs = regs; + handle_exception(regs); + + /* Flush caches */ + _gdbSupportLibFlushCaches(); + + pspDebugResumeFromException(); +} + +int _gdbSupportLibInit(void); + +void pspDebugGdbStubInit(void) +{ + _gdbSupportLibInit(); + /* Read out any pending data */ + memset(g_stepbp, 0, 2 * sizeof(struct sw_breakpoint)); + pspDebugInstallStdoutHandler(stdout_handler); + pspDebugInstallStderrHandler(stdout_handler); + + pspDebugInstallErrorHandler(_GdbTrapEntry); + + initialised = 1; + attached = 1; +} + +static char *mem2hex(unsigned char *mem, char *buf, int count) +{ + unsigned char ch; + + while (count-- > 0) { + if (_gdbSupportLibReadByte(mem++, &ch) == 0) + { + return NULL; + } + + *buf++ = hexchars[(ch >> 4) & 0xf]; + *buf++ = hexchars[ch & 0xf]; + } + + *buf = 0; + + return buf; +} + +static char *hex2mem(char *buf, char *mem, int count, int binary) +{ + int i; + unsigned char ch; + + for (i=0; iepc; + targetpc = epc + 4; + + opcode = _lw(epc); + + switch(opcode >> 26) + { + case BEQ_OPCODE: + case BEQL_OPCODE: + case BGTZ_OPCODE: + case BGTZL_OPCODE: + case BLEZ_OPCODE: + case BLEZL_OPCODE: + case BNE_OPCODE: + case BNEL_OPCODE: + { + short ofs; + + ofs = (short) (opcode & 0xffff); + cond = 1; + branch = 1; + targetpc += ofs * 4; + } + break; + case REGIMM_OPCODE: { + switch((opcode >> 16) & 0x1f) + { + case BGEZ_OPCODE: + case BGEZAL_OPCODE: + case BGEZALL_OPCODE: + case BGEZL_OPCODE: + case BLTZ_OPCODE: + case BLTZAL_OPCODE: + case BLTZALL_OPCODE: + case BLTZL_OPCODE: { + short ofs; + + ofs = (short) (opcode & 0xffff); + cond = 1; + branch = 1; + targetpc += ofs * 4; + } + break; + } + } + break; + case JAL_OPCODE: link = 1; + case J_OPCODE: { + u32 ofs; + + ofs = opcode & 0x3ffffff; + targetpc = (ofs << 2) | (targetpc & 0xf0000000); + branch = 1; + cond = 0; + } + break; + case SPECIAL_OPCODE: + { + switch(opcode & 0x3f) + { + case JALR_OPCODE: link = 1; + case JR_OPCODE: + { + u32 rs; + + rs = (opcode >> 21) & 0x1f; + targetpc = regs->r[rs]; + branch = 1; + cond = 0; + } + break; + }; + } + break; + case COP0_OPCODE: + case COP1_OPCODE: + case COP2_OPCODE: + { + switch((opcode >> 16) & 0x3ff) + { + case BCXF_OPCODE: + case BCXFL_OPCODE: + case BCXT_OPCODE: + case BCXTL_OPCODE: + { + short ofs; + + ofs = (short) (opcode & 0xffff); + cond = 1; + branch = 1; + targetpc += ofs * 4; + } + break; + }; + } + break; + }; + + if(link && skip) + { + g_stepbp[1].addr = epc + 8; + g_stepbp[1].oldinst = _lw(epc + 8); + g_stepbp[1].active = 1; + _sw(SW_BREAK_INST, epc + 8); + } + else if(branch) + { + g_stepbp[0].addr = targetpc; + g_stepbp[0].oldinst = _lw(targetpc); + g_stepbp[0].active = 1; + _sw(SW_BREAK_INST, targetpc); + + if((cond) && (targetpc != (epc + 8))) + { + g_stepbp[1].addr = epc + 8; + g_stepbp[1].oldinst = _lw(epc + 8); + g_stepbp[1].active = 1; + _sw(SW_BREAK_INST, epc + 8); + } + + } + else + { + g_stepbp[0].addr = targetpc; + g_stepbp[0].active = 1; + g_stepbp[0].oldinst = _lw(targetpc); + _sw(SW_BREAK_INST, targetpc); + } +} + +void build_trap_cmd(int sigval, PspDebugRegBlock *regs) +{ + char *ptr; + /* + * reply to host that an exception has occurred + */ + ptr = output; + *ptr++ = 'T'; + *ptr++ = hexchars[(sigval >> 4) & 0xf]; + *ptr++ = hexchars[sigval & 0xf]; + + /* + * Send Error PC + */ + *ptr++ = hexchars[37 >> 4]; + *ptr++ = hexchars[37 & 0xf]; + *ptr++ = ':'; + ptr = mem2hex((unsigned char *) ®s->epc, ptr, sizeof(u32)); + *ptr++ = ';'; + + /* + * Send frame pointer + */ + *ptr++ = hexchars[30 >> 4]; + *ptr++ = hexchars[30 & 0xf]; + *ptr++ = ':'; + ptr = mem2hex((unsigned char *)®s->r[30], ptr, sizeof(u32)); + *ptr++ = ';'; + + /* + * Send stack pointer + */ + *ptr++ = hexchars[29 >> 4]; + *ptr++ = hexchars[29 & 0xf]; + *ptr++ = ':'; + ptr = mem2hex((unsigned char *)®s->r[29], ptr, sizeof(u32)); + *ptr++ = ';'; + + *ptr++ = 0; +} + +static void handle_query(char *str) +{ + static SceUID threads[100]; + static int thread_count = 0; + static int thread_loc = 0; + + switch(str[0]) + { + case 'f': + if(strncmp(str, "fThreadInfo", strlen("fThreadInfo")) == 0) + { + thread_count = sceKernelGetThreadmanIdList(SCE_KERNEL_TMID_Thread, threads, 100, &thread_count); + if(thread_count > 0) + { + thread_loc = 0; + output[0] = 'm'; + mem2hex((unsigned char *) &threads[thread_loc], &output[1], 4); + output[9] = 0; + thread_loc++; + } + } + break; + + case 's': + if(strncmp(str, "sThreadInfo", strlen("sThreadInfo")) == 0) + { + if(thread_loc < thread_count) + { + output[0] = 'm'; + mem2hex((unsigned char *) &threads[thread_loc], &output[1], 4); + output[9] = 0; + thread_loc++; + } + else + { + strcpy(output, "l"); + } + } + break; + case 'P': + break; + }; +} + +static void handle_exception (PspDebugRegBlock *regs) +{ + int trap; + int sigval; + unsigned int addr; + unsigned int length; + char *ptr; + int bflag = 0; + + trap = (regs->cause & 0x7c) >> 2; + sigval = computeSignal(trap); + + if(sigval == SIGHUP) + { + DEBUG_PRINTF("Trap %d\n", trap); + } + + /* We stopped in breakpoint, so set epc to our ra */ + if((regs->epc == (u32) pspDebugBreakpoint) && (trap == 9)) + { + regs->epc = regs->r[31]; + } + + /* If step breakpoints set then put back the old values */ + if(g_stepbp[0].active) + { + _sw(g_stepbp[0].oldinst, g_stepbp[0].addr); + g_stepbp[0].active = 0; + } + + if(g_stepbp[1].active) + { + _sw(g_stepbp[1].oldinst, g_stepbp[1].addr); + g_stepbp[1].active = 0; + } + + if(last_cmd != 0) + { + build_trap_cmd(sigval, regs); + putpacket((unsigned char *) output); + } + + while(1) + { + getpacket(input); + DEBUG_PRINTF("Received packet '%s'\n", input); + + output[0] = 0; + + switch (input[0]) + { + case '?': + if(last_cmd == 0) + { + build_trap_cmd(sigval, regs); + } + else + { + output[0] = 'S'; + output[1] = hexchars[sigval >> 4]; + output[2] = hexchars[sigval & 0xf]; + output[3] = 0; + } + break; + + case 'c': + ptr = &input[1]; + if (hexToInt(&ptr, &addr)) + { + regs->epc = addr; + } + + goto restart; + break; + + case 'D': + putpacket((unsigned char *) output); + attached = 0; + goto restart; + break; + + case 'g': + ptr = output; + ptr = (char*) mem2hex((unsigned char *)®s->r[0], ptr, 32*sizeof(u32)); /* r0...r31 */ + ptr = (char*) mem2hex((unsigned char *)®s->status, ptr, 6*sizeof(u32)); /* cp0 */ + ptr = (char*) mem2hex((unsigned char *)®s->fpr[0], ptr, 32*sizeof(u32)); /* f0...31 */ + ptr = (char*) mem2hex((unsigned char *)®s->fsr, ptr, 2*sizeof(u32)); /* cp1 */ + ptr = (char*) mem2hex((unsigned char *)®s->frame_ptr, ptr, 2*sizeof(u32)); /* frp */ + ptr = (char*) mem2hex((unsigned char *)®s->index, ptr, 16*sizeof(u32)); /* cp0 */ + break; + + case 'G': + ptr = &input[1]; + hex2mem(ptr, (char *)®s->r[0], 32*sizeof(unsigned int), 0); + ptr += 32*(2*sizeof(unsigned int)); + hex2mem(ptr, (char *)®s->status, 6*sizeof(unsigned int), 0); + ptr += 6*(2*sizeof(unsigned int)); + hex2mem(ptr, (char *)®s->fpr[0], 32*sizeof(unsigned int), 0); + ptr += 32*(2*sizeof(unsigned int)); + hex2mem(ptr, (char *)®s->fsr, 2*sizeof(unsigned int), 0); + ptr += 2*(2*sizeof(unsigned int)); + hex2mem(ptr, (char *)®s->frame_ptr, 2*sizeof(unsigned int), 0); + ptr += 2*(2*sizeof(unsigned int)); + hex2mem(ptr, (char *)®s->index, 16*sizeof(unsigned int), 0); + strcpy(output,"OK"); + break; + + /* + * mAA..AA,LLLL Read LLLL bytes at address AA..AA + */ + case 'm': + ptr = &input[1]; + + if (hexToInt(&ptr, &addr) + && *ptr++ == ',' + && hexToInt(&ptr, &length)) { + if (mem2hex((unsigned char *)addr, output, length)) + break; + strcpy (output, "E03"); + } else + strcpy(output,"E01"); + break; + + /* + * XAA..AA,LLLL: Write LLLL escaped binary bytes at address AA.AA + */ + case 'X': + bflag = 1; + /* fall through */ + + /* + * MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK + */ + case 'M': + ptr = &input[1]; + + if (hexToInt(&ptr, &addr) + && *ptr++ == ',' + && hexToInt(&ptr, &length) + && *ptr++ == ':') { + if (hex2mem(ptr, (char *)addr, length, bflag)) + strcpy(output, "OK"); + else + strcpy(output, "E03"); + } + else + strcpy(output, "E02"); + bflag = 0; + break; + + case 's': ptr = &input[1]; + if (hexToInt(&ptr, &addr)) + { + regs->epc = addr; + } + + step_generic(regs, 0); + goto restart; + break; + + case 'q': handle_query(&input[1]); + break; + + /* + * kill the program; let us try to restart the machine + * Reset the whole machine. + */ + case 'k': + case 'r': sceKernelExitGame(); + break; + + default: + break; + } + /* + * reply to the request + */ + + putpacket((unsigned char *) output); + + } /* while */ + +restart: + last_cmd = input[0]; + return ; + +} + +/* Define the breakpoint function */ +asm ( + ".global pspDebugBreakpoint\n" + ".set noreorder\n" + "pspDebugBreakpoint:\tbreak\n" + "jr $31\n" + "nop\n" + ); diff --git a/src/debug/gdb-userlib.c b/src/debug/gdb-userlib.c new file mode 100644 index 00000000..6fdb6114 --- /dev/null +++ b/src/debug/gdb-userlib.c @@ -0,0 +1,195 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * gdb-userlib.c - GDB support functions for user mode. + * + * Copyright (c) 2005 James Forshaw + * + * $Id: gdb-userlib.c 2166 2007-02-04 10:52:49Z tyranid $ + */ +#include +#include + +#include + +static int sio_fd = -1; + +/* GDB Debug putchar */ +void putDebugChar(char ch) +{ + sceIoWrite(sio_fd, &ch, 1); +} + +/* GDB Debug getchar */ +char getDebugChar(void) +{ + char ch = 0; + int count = 0; + + while(count <= 0) + { + count = sceIoRead(sio_fd, &ch, 1); + } + + return ch; +} + +int g_initialised = 0; + +static int io_init(PspIoDrvArg *arg) +{ + return 0; +} + +static int io_exit(PspIoDrvArg *arg) +{ + return 0; +} + +static int io_read(PspIoDrvFileArg *arg, char *data, int len) +{ + int ret = 0; + int ch; + + while(ret < len) + { + ch = pspDebugSioGetchar(); + if(ch != -1) + { + data[ret++] = ch & 0xFF; + } + else + { + break; + } + } + + return ret; +} + +static int io_write(PspIoDrvFileArg *arg, const char *data, int len) +{ + int ret = 0; + + while(ret < len) + { + pspDebugSioPutchar(data[ret++]); + } + + return ret; +} + +void sceKernelDcacheWBinvAll(void); +void sceKernelIcacheClearAll(void); + +static int io_devctl(PspIoDrvFileArg *arg, const char *devname, unsigned int cmd, void *indata, int inlen, void *outdata, int outlen) +{ + pspKernelSetKernelPC(); + sceKernelDcacheWBinvAll(); + sceKernelIcacheClearAll(); + + return 0; +} + +static PspIoDrvFuncs sio_funcs = +{ + io_init, + io_exit, + NULL, + NULL, + io_read, + io_write, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + io_devctl, + NULL, +}; + +static PspIoDrv sio_driver = +{ + "sio", 0x10, 0x800, "SIO", &sio_funcs +}; + +int _gdbSupportLibReadByte(unsigned char *address, unsigned char *dest) +{ + u32 addr; + + addr = (u32) address; + if((addr >= 0x08400000) && (addr < 0x0a000000)) + { + *dest = *address; + return 1; + } + + /* + else if((addr >= 0x88000000) && (addr < 0x8a000000)) + { + *dest = *address; + return 1; + } + */ + + return 0; +} + +int _gdbSupportLibWriteByte(char val, unsigned char *dest) +{ + u32 addr; + + addr = (u32) dest; + if((addr >= 0x08400000) && (addr < 0x0a000000)) + { + *dest = val; + return 1; + } + + /* + else if((addr >= 0x88000000) && (addr < 0x8a000000)) + { + *dest = val; + return 1; + } + */ + + return 0; +} + +void _gdbSupportLibFlushCaches(void) +{ + sceIoDevctl("sio:", 0, NULL, 0, NULL, 0); +} + +int _gdbSupportLibInit(void) +{ + int ret; + + if(!g_initialised) + { + (void) sceIoDelDrv("sio"); /* Ignore error */ + ret = sceIoAddDrv(&sio_driver); + if(ret < 0) + { + return ret; + } + + sio_fd = sceIoOpen("sio:", PSP_O_RDWR, 0); + + g_initialised = 1; + } + + return 0; +} diff --git a/src/debug/kprintf.c b/src/debug/kprintf.c new file mode 100644 index 00000000..1cf7c080 --- /dev/null +++ b/src/debug/kprintf.c @@ -0,0 +1,45 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * kprintf.c - Basic Kprintf handling for applications. + * + * Copyright (c) 2005 James Forshaw + * + * $Id: kprintf.c 1095 2005-09-27 21:02:16Z jim $ + */ + +#include +#include + +/* The current kprintf handler */ +static PspDebugKprintfHandler curr_handler; + +int sceKernelRegisterKprintfHandler(void *func, void *args); + +/* Default kprintf handler */ +static void _pspDebugDefaultKprintfHandler(const char *format, u32 *args) +{ + pspDebugScreenPrintf(format, args[0], args[1], args[2], args[3]); +} + +/* The registered kprintf handler */ +static void _pspDebugKprintfHandler(void *arg, const char *format, u32 *args) +{ + if(curr_handler != NULL) + { + curr_handler(format, args); + } + else + { + _pspDebugDefaultKprintfHandler(format, args); + } +} + +/* Install a kprintf handler */ +int pspDebugInstallKprintfHandler(PspDebugKprintfHandler handler) +{ + curr_handler = handler; + return sceKernelRegisterKprintfHandler(_pspDebugKprintfHandler, NULL); +} diff --git a/src/debug/profiler.c b/src/debug/profiler.c new file mode 100644 index 00000000..ccd4ad37 --- /dev/null +++ b/src/debug/profiler.c @@ -0,0 +1,97 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * profiler.c - Debug profiler functions. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: profiler.c 2190 2007-02-25 21:00:40Z tyranid $ + */ +#include +#include + +#define PROFILER_REG_BASE 0xBC400000 +#define PROFILER_REG_COUNT 21 + +void pspDebugProfilerEnable(void) +{ + _sw(1, PROFILER_REG_BASE); +} + +void pspDebugProfilerDisable(void) +{ + _sw(0, PROFILER_REG_BASE); + asm("sync\r\n"); +} + +void pspDebugProfilerClear(void) +{ + u32 addr; + int i; + + addr = PROFILER_REG_BASE; + /* Don't clear the enable register */ + for(i = 1; i < PROFILER_REG_COUNT; i++) + { + addr += 4; + _sw(0, addr); + } +} + +void pspDebugProfilerGetRegs(PspDebugProfilerRegs *regs) +{ + u32 *p_regs; + u32 addr; + int i; + + if(regs == NULL) + { + return; + } + + p_regs = (u32 *) regs; + + addr = PROFILER_REG_BASE; + for(i = 0; i < PROFILER_REG_COUNT; i++) + { + p_regs[i] = _lw(addr); + addr += 4; + } +} + +void pspDebugProfilerPrint(void) +{ + PspDebugProfilerRegs regs; + + pspDebugProfilerGetRegs(®s); + + pspDebugScreenPrintf("********** Profile ***********\n"); + pspDebugScreenPrintf("enable : %10u\n", regs.enable); + pspDebugScreenPrintf("systemck : %10u [cycles]\n", regs.systemck); + pspDebugScreenPrintf("cpu ck : %10u [cycles]\n", regs.cpuck); + pspDebugScreenPrintf("stall : %10u [cycles]\n", regs.internal + regs.memory + + regs.copz + regs.vfpu); + pspDebugScreenPrintf("+(internal) : %10u [cycles]\n", regs.internal); + pspDebugScreenPrintf("+--(memory) : %10u [cycles]\n", regs.memory); + pspDebugScreenPrintf("+----(COPz) : %10u [cycles]\n", regs.copz); + pspDebugScreenPrintf("+----(VFPU) : %10u [cycles]\n", regs.vfpu); + pspDebugScreenPrintf("sleep : %10u [cycles]\n", regs.sleep); + pspDebugScreenPrintf("bus access : %10u [cycles]\n", regs.bus_access); + pspDebugScreenPrintf("uncached load : %10u [times]\n", regs.uncached_load); + pspDebugScreenPrintf("uncached store : %10u [times]\n", regs.uncached_store); + pspDebugScreenPrintf("cached load : %10u [times]\n", regs.cached_load); + pspDebugScreenPrintf("cached store : %10u [times]\n", regs.cached_store); + pspDebugScreenPrintf("I cache miss : %10u [times]\n", regs.i_miss); + pspDebugScreenPrintf("D cache miss : %10u [times]\n", regs.d_miss); + pspDebugScreenPrintf("D cache wb : %10u [times]\n", regs.d_writeback); + pspDebugScreenPrintf("COP0 inst. : %10u [inst.]\n", regs.cop0_inst); + pspDebugScreenPrintf("FPU inst. : %10u [inst.]\n", regs.fpu_inst); + pspDebugScreenPrintf("VFPU inst. : %10u [inst.]\n", regs.vfpu_inst); + pspDebugScreenPrintf("local bus : %10u [cycles]\n", regs.local_bus); +} + + diff --git a/src/debug/pspdebug.h b/src/debug/pspdebug.h new file mode 100644 index 00000000..880540fc --- /dev/null +++ b/src/debug/pspdebug.h @@ -0,0 +1,443 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspdebug.h - Prototypes for the pspDebug library + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: pspdebug.h 2450 2009-01-04 23:53:02Z oopo $ + */ +#ifndef __DEBUG_H__ +#define __DEBUG_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup Debug Debug Utility Library */ + +/** @addtogroup Debug */ +/*@{*/ + +/** + * Initialise the debug screen + */ +void pspDebugScreenInit(void); + +/** + * Extended debug screen init + * + * @param vram_base - Base address of frame buffer, if NULL then sets a default + * @param mode - Colour mode + * @param setup - Setup the screen if 1 + */ +void pspDebugScreenInitEx(void *vram_base, int mode, int setup); + +/** + * Do a printf to the debug screen. + * + * @param fmt - Format string to print + * @param ... - Arguments + */ +void pspDebugScreenPrintf(const char *fmt, ...) __attribute__((format(printf,1,2))); + +/** + * Do a printf to the debug screen. + * @note This is for kernel mode only as it uses a kernel function + * to perform the printf instead of using vsnprintf, use normal printf for + * user mode. + * + * @param format - Format string to print + * @param ... - Arguments + */ +void pspDebugScreenKprintf(const char *format, ...) __attribute__((format(printf,1,2))); + +/** + * Enable or disable background colour writing (defaults to enabled) + * + * @param enable - Set 1 to to enable background color, 0 for disable + */ +void pspDebugScreenEnableBackColor(int enable); + +/** + * Set the background color for the text + * @note To reset the entire screens bg colour you need to call pspDebugScreenClear + * + * @param color - A 32bit RGB colour + */ +void pspDebugScreenSetBackColor(u32 color); + +/** + * Set the text color + * + * @param color - A 32 bit RGB color + */ +void pspDebugScreenSetTextColor(u32 color); + +/** + * Set the color mode (you must have switched the frame buffer appropriately) + * + * @param mode - Color mode + */ +void pspDebugScreenSetColorMode(int mode); + +/** + * Draw a single character to the screen. + * + * @param x - The x co-ordinate to draw to (pixel units) + * @param y - The y co-ordinate to draw to (pixel units) + * @param color - The text color to draw + * @param ch - The character to draw + */ +void pspDebugScreenPutChar(int x, int y, u32 color, u8 ch); + +/** + * Set the current X and Y co-ordinate for the screen (in character units) + */ +void pspDebugScreenSetXY(int x, int y); + +/** + * Set the video ram offset used for the screen + * + * @param offset - Offset in bytes + */ +void pspDebugScreenSetOffset(int offset); + +/** + * Set the video ram base used for the screen + * + * @param base - Base address in bytes + */ +void pspDebugScreenSetBase(u32* base); + +/** + * Get the current X co-ordinate (in character units) + * + * @return The X co-ordinate + */ +int pspDebugScreenGetX(void); + +/** + * Get the current Y co-ordinate (in character units) + * + * @return The Y co-ordinate + */ +int pspDebugScreenGetY(void); + +/** + * Clear the debug screen. + */ +void pspDebugScreenClear(void); + +/** + * Print non-nul terminated strings. + * + * @param buff - Buffer containing the text. + * @param size - Size of the data + * + * @return The number of characters written + */ +int pspDebugScreenPrintData(const char *buff, int size); + +/** + * Print a string + * + * @param str - String + * + * @return The number of characters written + */ +int pspDebugScreenPuts(const char *str); + +/** + * Get a MIPS stack trace (might work :P) + * + * @param results - List of points to store the results of the trace, (up to max) + * @param max - Maximum number of back traces + * + * @return The number of frames stored in results. +*/ +int pspDebugGetStackTrace(unsigned int* results, int max); + +/** + * Enable the clear line function that allows debug to clear the screen +*/ +void pspDebugScreenClearLineEnable(void); + +/** + * Disable the clear line function that causes flicker on constant refreshes +*/ +void pspDebugScreenClearLineDisable(void); + +/** Structure to hold the register data associated with an exception */ +typedef struct _PspDebugRegBlock +{ + u32 frame[6]; + /** Array of the 32 GPRs */ + u32 r[32]; + /** The status register */ + u32 status; + /** lo */ + u32 lo; + u32 hi; + u32 badvaddr; + u32 cause; + u32 epc; + float fpr[32]; + u32 fsr; + u32 fir; + u32 frame_ptr; + u32 unused; + /* Unused on PSP */ + u32 index; + u32 random; + u32 entrylo0; + u32 entrylo1; + u32 context; + u32 pagemask; + u32 wired; + u32 cop0_7; + u32 cop0_8; + u32 cop0_9; + u32 entryhi; + u32 cop0_11; + u32 cop0_12; + u32 cop0_13; + u32 cop0_14; + /* PRId should still be okay */ + u32 prid; + u32 padding[100]; +} PspDebugRegBlock; + +/** Defines a debug error handler */ +typedef void (*PspDebugErrorHandler)(PspDebugRegBlock *regs); + +/** + * Install an error handler to catch unhandled exceptions. + * + * @param handler - Pointer to a handler function. If set to NULL it will default + * to resetting the screen and dumping the error. + * @return < 0 on error + */ +int pspDebugInstallErrorHandler(PspDebugErrorHandler handler); + +/** + * Dump an exception to screen using the pspDebugScreen functions. + * @note This function will not setup the screen for debug output, you should call sceDebugScreenInit + * before using it if it isn't already. + * + * @param regs - Pointer to a register block. + * + */ +void pspDebugDumpException(PspDebugRegBlock *regs); + +/** Type for Kprintf handler */ +typedef int (*PspDebugKprintfHandler)(const char *format, u32 *args); + +/** + * Install a Kprintf handler into the system. + * + * @param handler - Function pointer to the handler. + * @return < 0 on error. + */ +int pspDebugInstallKprintfHandler(PspDebugKprintfHandler handler); + +/** Structure to hold a single stack trace entry */ +typedef struct _PspDebugStackTrace +{ + /** The address which called the function */ + u32 call_addr; + /** The address of the function called */ + u32 func_addr; +} PspDebugStackTrace; + +/** + * Do a stack trace from the current exception. + * @note This function really isn't too general purpose and it is more than likely to generate a few + * false positives but I consider that better then missing out calls entirely. You have to use your + * discretion, your code and a objdump to work out if some calls are completely surprious or not ;) + * + * @param regs - Pointer to a register block from an exception. + * @param trace - Pointer to an array of PspDebugStackTrace structures. + * @param max - The maximum number of traces to make. + * + * @return The number of functions found. + */ +int pspDebugGetStackTrace2(PspDebugRegBlock *regs, PspDebugStackTrace *trace, int max); + +/** Structure to hold the psp profiler register values */ +typedef struct _PspDebugProfilerRegs +{ + volatile u32 enable; + volatile u32 systemck; + volatile u32 cpuck; + volatile u32 internal; + volatile u32 memory; + volatile u32 copz; + volatile u32 vfpu; + volatile u32 sleep; + volatile u32 bus_access; + volatile u32 uncached_load; + volatile u32 uncached_store; + volatile u32 cached_load; + volatile u32 cached_store; + volatile u32 i_miss; + volatile u32 d_miss; + volatile u32 d_writeback; + volatile u32 cop0_inst; + volatile u32 fpu_inst; + volatile u32 vfpu_inst; + volatile u32 local_bus; +} PspDebugProfilerRegs; + +/** Enables the profiler hardware */ +void pspDebugProfilerEnable(void); + +/** Disables the profiler hardware */ +void pspDebugProfilerDisable(void); + +/** Clear the profiler registers */ +void pspDebugProfilerClear(void); + +/** Get the profiler register state + * + * @param regs - A pointer to a PspDebugProfilerRegs structure. + */ +void pspDebugProfilerGetRegs(PspDebugProfilerRegs *regs); + +/** Print the profiler registers to screen */ +void pspDebugProfilerPrint(void); + +/** Type for the debug print handlers */ +typedef int (*PspDebugPrintHandler)(const char *data, int len); + +/** Type for the debug input handler */ +typedef int (*PspDebugInputHandler)(char *data, int len); + +/** + * Install a handler for stdin (so you can use normal stdio functions) + * + * @param handler - A pointer to input handler, NULL to disable. + * + * @return < 0 on error, else 0. + */ +int pspDebugInstallStdinHandler(PspDebugInputHandler handler); + +/** + * Install a print handler for stdout (so you can use normal print functions) + * + * @param handler - A pointer to print handler, NULL to disable. + * + * @return < 0 on error, else 0. + */ +int pspDebugInstallStdoutHandler(PspDebugPrintHandler handler); + +/** + * Install a print handler for stderr (so you can use normal print functions) + * + * @param handler - A pointer to print handler, NULL to disable. + * + * @return < 0 on error, else 0. + */ +int pspDebugInstallStderrHandler(PspDebugPrintHandler handler); + +/** + * Put a character to the remote sio. + * + * @param ch - Character to write. + */ +void pspDebugSioPutchar(int ch); + +/** + * Get a character from the remote sio + * + * @return The character read or -1 if no characters available. + */ +int pspDebugSioGetchar(void); + +/** + * Write a string to the sio port. + * + * @param str - String to write. + */ +void pspDebugSioPuts(const char *str); + +/** + * Write a set of data to the sio port + * + * @param data - Pointer to the data to send. + * @param len - Length of the data. + * + * @return Number of characters written. + */ +int pspDebugSioPutData(const char *data, int len); + +/** + * Write a set of data to the sio port converting single + * line feeds to CRLF and single CR to CRLF + * + * @param data - Pointer to the data to send. + * @param len - Length of the data. + * + * @return Number of characters written. + */ +int pspDebugSioPutText(const char *data, int len); + +/** + * Initialise the remote SIO port (defaults to 4800 8N1). + * @note will delay 2 seconds to wait for the power to come up. + */ +void pspDebugSioInit(void); + +/** + * Set the baud rate of the SIO, e.g. 4800/9600..115200. + * @param baud - The baudrate to set. + */ +void pspDebugSioSetBaud(int baud); + +/** + * Enable debug character output. Needs to be called in order + * for the default Kprintf handler to work. + */ +void pspDebugEnablePutchar(void); + +/** + * Install a kprintf debug putchar handler. Implicitly calls ::pspDebugEnablePutchar + * so you do not need to call it explicitly. Sio must be initialised before calling + * this function however. + */ +void pspDebugSioInstallKprintf(void); + +/** + * Install the gdb stub handler. + */ +void pspDebugGdbStubInit(void); + +/** + * Generate a breakpoint exception. + */ +void pspDebugBreakpoint(void); + +/** + * Enable the kprintf handler (once installed) + */ +void pspDebugSioEnableKprintf(void); + +/** + * Disable the kprintf handler (once installed) + */ +void pspDebugSioDisableKprintf(void); + +/*@}*/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/debug/pspdebugkb.c b/src/debug/pspdebugkb.c new file mode 100644 index 00000000..1d0e750b --- /dev/null +++ b/src/debug/pspdebugkb.c @@ -0,0 +1,292 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspdebugkb.c - Simple screen debug keyboard + * + * Copyright (c) 2006 Mike Mallett + * + * $Id: pspdebugkb.c 2112 2006-12-22 10:53:20Z tyranid $ + */ +#include +#include +#include +#include +#include "pspdebugkb.h" + +static char loCharTable[PSP_DEBUG_KB_NUM_ROWS][PSP_DEBUG_KB_NUM_CHARS] = { + { '`', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=' }, + { 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\\' }, + { '\0', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '\0' }, + { '\0', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', '\0', '\0' } +}; + +static char hiCharTable[PSP_DEBUG_KB_NUM_ROWS][PSP_DEBUG_KB_NUM_CHARS] = { + { '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+' }, + { 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '|' }, + { '\0', 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '\0' }, + { '\0', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', '\0', '\0' } +}; + +static char *commandRow[] = { "Shift", "[ ]", "Back", "Clear", "Done" }; + +char charTable[PSP_DEBUG_KB_NUM_ROWS][PSP_DEBUG_KB_NUM_CHARS]; + +/* Switch charTable when Shift is pressed */ +void pspDebugKbShift(int* shiftState) { + int i, j; + + if (*shiftState != 0) { + for (i=0; i 0 + && (row == PSP_DEBUG_KB_COMMAND_ROW || charTable[row][col - 1]) + && (input.Buttons != lastinput.Buttons || input.TimeStamp >= inputTime + inputDelay)) { + // Unhighlight the old character + pspDebugKbDrawKey(row, col, 0); + + // Print the new character highlighted + pspDebugKbDrawKey(row, --col, 1); + + // Update inputTime + inputTime = input.TimeStamp; + } + if (input.Buttons & PSP_CTRL_RIGHT + && ((row == PSP_DEBUG_KB_COMMAND_ROW && col < PSP_DEBUG_KB_NUM_COMMANDS - 1) + || (row != PSP_DEBUG_KB_COMMAND_ROW && col < PSP_DEBUG_KB_NUM_CHARS - 1 + && charTable[row][col + 1])) + && (input.Buttons != lastinput.Buttons || input.TimeStamp >= inputTime + inputDelay)) { + pspDebugKbDrawKey(row, col, 0); + pspDebugKbDrawKey(row, ++col, 1); + inputTime = input.TimeStamp; + } + if (input.Buttons & PSP_CTRL_UP && row > 0 + && (input.Buttons != lastinput.Buttons || input.TimeStamp >= inputTime + inputDelay)) { + if (row == PSP_DEBUG_KB_COMMAND_ROW) { + pspDebugKbDrawKey(row, col, 0); + if (col == PSP_DEBUG_KB_NUM_COMMANDS - 1) { + col = PSP_DEBUG_KB_NUM_CHARS - 1; + } else { + col = (col * (PSP_DEBUG_KB_NUM_CHARS - 1)) / (PSP_DEBUG_KB_NUM_COMMANDS - 1); + } + do { + row--; + } while (charTable[row][col] == '\0' && row > 0); + pspDebugKbDrawKey(row, col, 1); + } else if (charTable[row - 1][col]) { + pspDebugKbDrawKey(row, col, 0); + pspDebugKbDrawKey(--row, col, 1); + } + inputTime = input.TimeStamp; + } + if (input.Buttons & PSP_CTRL_DOWN && row != PSP_DEBUG_KB_COMMAND_ROW + && (input.Buttons != lastinput.Buttons || input.TimeStamp >= inputTime + inputDelay)) { + pspDebugKbDrawKey(row, col, 0); + do { + row++; + } while (charTable[row][col] == '\0' && + row != PSP_DEBUG_KB_COMMAND_ROW); + if (row == PSP_DEBUG_KB_COMMAND_ROW) { + col = (col * (PSP_DEBUG_KB_NUM_COMMANDS - 1)) / (PSP_DEBUG_KB_NUM_CHARS - 1); + } + pspDebugKbDrawKey(row, col, 1); + inputTime = input.TimeStamp; + } + + if (input.Buttons != lastinput.Buttons && input.Buttons & PSP_CTRL_SELECT) { + pspDebugKbShift(&shifted); + pspDebugKbDrawKey(row, col, 1); + } + + if (input.Buttons != lastinput.Buttons + && (input.Buttons & PSP_CTRL_CROSS || input.Buttons & PSP_CTRL_CIRCLE)) { + if (row == PSP_DEBUG_KB_COMMAND_ROW) { + switch(col) { + case 0: // Shift + pspDebugKbShift(&shifted); + pspDebugKbDrawKey(row, col, 1); + break; + case 1: // Space + if (strlen(str) < PSP_DEBUG_KB_MAXLEN) { + snprintf(str, strlen(str)+2, "%s ", str); + pspDebugKbDrawString(str); + } + break; + case 2: // Back + if (strlen(str) > 0) { + str[strlen(str)-1] = '\0'; + pspDebugKbDrawString(str); + } + break; + case 3: // Clear + bzero(str, PSP_DEBUG_KB_MAXLEN); + pspDebugKbDrawString(str); + break; + case 4: + // Clean up the screen + pspDebugKbClearBox(); + return; + }; + } else { + if (strlen(str) < PSP_DEBUG_KB_MAXLEN) { + snprintf(str, strlen(str)+2, "%s%c", str, charTable[row][col]); + pspDebugKbDrawString(str); + } + } + } + + if (input.Buttons != lastinput.Buttons + && (input.Buttons & PSP_CTRL_TRIANGLE || input.Buttons & PSP_CTRL_SQUARE)) { + if (strlen(str) > 0) { + str[strlen(str)-1] = '\0'; + pspDebugKbDrawString(str); + } + } + + lastinput = input; + } +} diff --git a/src/debug/pspdebugkb.h b/src/debug/pspdebugkb.h new file mode 100644 index 00000000..54592ded --- /dev/null +++ b/src/debug/pspdebugkb.h @@ -0,0 +1,96 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspdebugkb.h - Simple screen debug keyboard + * + * Copyright (c) 2006 Mike Mallett + * + * $Id: pspdebugkb.h 2110 2006-12-19 14:50:27Z tyranid $ + */ + +#ifndef __PSPDEBUGKB_H +#define __PSPDEBUGKB_H + +#ifdef __cplusplus +extern "C" { +#endif + +enum PspDebugKbSettings { + /** Maximum string length */ + PSP_DEBUG_KB_MAXLEN = 40, + /** Place the box' upper-left corner at this location */ + PSP_DEBUG_KB_BOX_X = 6, + PSP_DEBUG_KB_BOX_Y = 8, + /** FG and BG colour of unhighlighted characters */ + PSP_DEBUG_KB_CHAR_COLOUR = 0xffffffff, + PSP_DEBUG_KB_BACK_COLOUR = 0xff000000, + /** FG and BG colour of highlighted character */ + PSP_DEBUG_KB_CHAR_HIGHLIGHT = 0xff00ff00, + PSP_DEBUG_KB_BACK_HIGHLIGHT = 0xff101010, + /** Indent the printed characters by (X_OFFSET,Y_OFFSET) */ + PSP_DEBUG_KB_OFFSET_X = 6, + PSP_DEBUG_KB_OFFSET_Y = 4, + /** Distance from one character to the next */ + PSP_DEBUG_KB_SPACING_X = 3, + PSP_DEBUG_KB_SPACING_Y = 2, + /** Number of columns/rows (respectively) in charTable(s) */ + PSP_DEBUG_KB_NUM_CHARS = 13, + PSP_DEBUG_KB_NUM_ROWS = 4, + /** Box width and height */ + PSP_DEBUG_KB_BOX_WIDTH = (PSP_DEBUG_KB_NUM_CHARS * PSP_DEBUG_KB_SPACING_X) + (2 * PSP_DEBUG_KB_OFFSET_X), + PSP_DEBUG_KB_BOX_HEIGHT = ((PSP_DEBUG_KB_NUM_ROWS + 1) * PSP_DEBUG_KB_SPACING_Y) + PSP_DEBUG_KB_OFFSET_Y, + /** Array index of commandRow */ + PSP_DEBUG_KB_COMMAND_ROW = 4, + /** Number of commands on bottom row */ + PSP_DEBUG_KB_NUM_COMMANDS = 5 +}; + +/** + * Switch charTable when SHIFT is pressed + * + * @param shiftState - Pointer to an int indicating Caps Lock + */ +void pspDebugKbShift(int *shiftState); + +/** + * Draw the specified key on the keyboard. + * + * @param row - The row of the character to print (in charTable) + * @param col - The column of the character to print (in charTable) + * @param highlight - 0 for plain; otherwise highlighted + */ +void pspDebugKbDrawKey(int row, int col, int highlight); + +/** + * Draw the string at the top of the box + * + * @param str - The string to print + */ +void pspDebugKbDrawString(char *str); + +/** + * Clear the area where the box resides. + * Called from pspDebugKbDrawBox and pspDebugKbInit (on exit). + */ +void pspDebugKbClearBox(); + +/** + * Draw the entire box on the desbug screen. + * Called from shift() and doInputBox(char*) + */ +void pspDebugKbDrawBox(); + +/** + * Make the text box happen + * + * @param str - The string to edit + */ +void pspDebugKbInit(char *str); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/debug/scr_printf.c b/src/debug/scr_printf.c new file mode 100644 index 00000000..6db6c96d --- /dev/null +++ b/src/debug/scr_printf.c @@ -0,0 +1,478 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * scr_printf.c - Debug screen functions. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: scr_printf.c 2450 2009-01-04 23:53:02Z oopo $ + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PSP_SCREEN_WIDTH 480 +#define PSP_SCREEN_HEIGHT 272 +#define PSP_LINE_SIZE 512 + +/* baseado nas libs do Duke... */ + +#ifdef F_pspDebugScreenInit +void _pspDebugScreenClearLine( int Y); + +static int X = 0, Y = 0; +static int MX=68, MY=34; +static u32 bg_col = 0, fg_col = 0xFFFFFFFF; +static int bg_enable = 1; +static void* g_vram_base = (u32 *) 0x04000000; +static int g_vram_offset = 0; +static int g_vram_mode = PSP_DISPLAY_PIXEL_FORMAT_8888; +static int init = 0; +static int clearline_en = 1; + +static u16 convert_8888_to_565(u32 color) +{ + int r, g, b; + + b = (color >> 19) & 0x1F; + g = (color >> 10) & 0x3F; + r = (color >> 3) & 0x1F; + + return r | (g << 5) | (b << 11); +} + +static u16 convert_8888_to_5551(u32 color) +{ + int r, g, b, a; + + a = (color >> 24) ? 0x8000 : 0; + b = (color >> 19) & 0x1F; + g = (color >> 11) & 0x1F; + r = (color >> 3) & 0x1F; + + return a | r | (g << 5) | (b << 10); +} + +static u16 convert_8888_to_4444(u32 color) +{ + int r, g, b, a; + + a = (color >> 28) & 0xF; + b = (color >> 20) & 0xF; + g = (color >> 12) & 0xF; + r = (color >> 4) & 0xF; + + return (a << 12) | r | (g << 4) | (b << 8); +} + +static void clear_screen_16(u16 color) +{ + int x; + u16 *vram = g_vram_base; + + vram += (g_vram_offset >> 1); + + for(x = 0; x < (PSP_LINE_SIZE * PSP_SCREEN_HEIGHT); x++) + { + *vram++ = color; + } +} + +static void clear_screen_32(u32 color) +{ + int x; + u32 *vram = g_vram_base; + vram += (g_vram_offset>>2); + + for(x = 0; x < (PSP_LINE_SIZE * PSP_SCREEN_HEIGHT); x++) + { + *vram++ = color; + } +} + +static void clear_screen(u32 color) +{ + if(g_vram_mode == PSP_DISPLAY_PIXEL_FORMAT_8888) + { + clear_screen_32(color); + } + else + { + u16 c = 0; + switch(g_vram_mode) + { + case PSP_DISPLAY_PIXEL_FORMAT_565: c = convert_8888_to_565(color); + break; + case PSP_DISPLAY_PIXEL_FORMAT_5551: c = convert_8888_to_5551(color); + break; + case PSP_DISPLAY_PIXEL_FORMAT_4444: c = convert_8888_to_4444(color); + break; + }; + clear_screen_16(c); + } +} + +void pspDebugScreenInitEx(void *vram_base, int mode, int setup) +{ + switch(mode) + { + case PSP_DISPLAY_PIXEL_FORMAT_565: + case PSP_DISPLAY_PIXEL_FORMAT_5551: + case PSP_DISPLAY_PIXEL_FORMAT_4444: + case PSP_DISPLAY_PIXEL_FORMAT_8888: + break; + default: mode = PSP_DISPLAY_PIXEL_FORMAT_8888; + }; + + X = Y = 0; + /* Place vram in uncached memory */ + if(vram_base == NULL) + { + vram_base = (void*) (0x40000000 | (u32) sceGeEdramGetAddr()); + } + g_vram_base = vram_base; + g_vram_offset = 0; + g_vram_mode = mode; + if(setup) + { + sceDisplaySetMode(0, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT); + sceDisplaySetFrameBuf((void *) g_vram_base, PSP_LINE_SIZE, mode, 1); + } + clear_screen(bg_col); + init = 1; +} + +void pspDebugScreenInit() +{ + X = Y = 0; + pspDebugScreenInitEx(NULL, PSP_DISPLAY_PIXEL_FORMAT_8888, 1); +} + +void pspDebugScreenEnableBackColor(int enable) +{ + bg_enable = enable; +} + +void pspDebugScreenSetBackColor(u32 colour) +{ + bg_col = colour; +} + +void pspDebugScreenSetTextColor(u32 colour) +{ + fg_col = colour; +} + +void pspDebugScreenSetColorMode(int mode) +{ + switch(mode) + { + case PSP_DISPLAY_PIXEL_FORMAT_565: + case PSP_DISPLAY_PIXEL_FORMAT_5551: + case PSP_DISPLAY_PIXEL_FORMAT_4444: + case PSP_DISPLAY_PIXEL_FORMAT_8888: + break; + default: mode = PSP_DISPLAY_PIXEL_FORMAT_8888; + }; + + g_vram_mode = mode; +} + +int pspDebugScreenGetX() +{ + return X; +} + +int pspDebugScreenGetY() +{ + return Y; +} + +void pspDebugScreenClear() +{ + int y; + + if(!init) + { + return; + } + + for(y=0;y=0 ) X=x; + if( y=0 ) Y=y; +} + +void pspDebugScreenSetOffset(int offset) +{ + g_vram_offset = offset; +} + +void pspDebugScreenSetBase(u32* base) +{ + g_vram_base = base; +} + +extern u8 msx[]; + +static void debug_put_char_32(int x, int y, u32 color, u32 bgc, u8 ch) +{ + int i,j, l; + u8 *font; + u32 *vram_ptr; + u32 *vram; + + if(!init) + { + return; + } + + vram = g_vram_base; + vram += (g_vram_offset >> 2) + x; + vram += (y * PSP_LINE_SIZE); + + font = &msx[ (int)ch * 8]; + for (i=l=0; i < 8; i++, l+= 8, font++) + { + vram_ptr = vram; + for (j=0; j < 8; j++) + { + if ((*font & (128 >> j))) + *vram_ptr = color; + else if(bg_enable) + *vram_ptr = bgc; + + vram_ptr++; + } + vram += PSP_LINE_SIZE; + } +} + +static void debug_put_char_16(int x, int y, u16 color, u16 bgc, u8 ch) +{ + int i,j, l; + u8 *font; + u16 *vram_ptr; + u16 *vram; + + if(!init) + { + return; + } + + vram = g_vram_base; + vram += (g_vram_offset >> 1) + x; + vram += (y * PSP_LINE_SIZE); + + font = &msx[ (int)ch * 8]; + for (i=l=0; i < 8; i++, l+= 8, font++) + { + vram_ptr = vram; + for (j=0; j < 8; j++) + { + if ((*font & (128 >> j))) + *vram_ptr = color; + else if(bg_enable) + *vram_ptr = bgc; + + vram_ptr++; + } + vram += PSP_LINE_SIZE; + } +} + +void +pspDebugScreenPutChar( int x, int y, u32 color, u8 ch) +{ + if(g_vram_mode == PSP_DISPLAY_PIXEL_FORMAT_8888) + { + debug_put_char_32(x, y, color, bg_col, ch); + } + else + { + u16 c = 0; + u16 b = 0; + switch(g_vram_mode) + { + case PSP_DISPLAY_PIXEL_FORMAT_565: c = convert_8888_to_565(color); + b = convert_8888_to_565(bg_col); + break; + case PSP_DISPLAY_PIXEL_FORMAT_5551: c = convert_8888_to_5551(color); + b = convert_8888_to_5551(bg_col); + break; + case PSP_DISPLAY_PIXEL_FORMAT_4444: c = convert_8888_to_4444(color); + b = convert_8888_to_4444(bg_col); + break; + }; + debug_put_char_16(x, y, c, b, ch); + } +} + +void _pspDebugScreenClearLine( int Y) +{ + if(clearline_en) + { + int i; + if(bg_enable) + { + for (i=0; i < MX; i++) + { + pspDebugScreenPutChar( i*7 , Y * 8, bg_col, 219); + } + } + } + return; +} + +void pspDebugScreenClearLineEnable(void) +{ + clearline_en = 1; + return; +} + +void pspDebugScreenClearLineDisable(void) +{ + clearline_en = 0; + return; +} + +/* Print non-nul terminated strings */ +int pspDebugScreenPrintData(const char *buff, int size) +{ + int i; + int j; + char c; + + if(!init) + { + return 0; + } + + for (i = 0; i < size; i++) + { + c = buff[i]; + switch (c) + { + case '\r': + X = 0; + break; + case '\n': + X = 0; + Y ++; + if (Y == MY) + Y = 0; + _pspDebugScreenClearLine(Y); + break; + case '\t': + for (j = 0; j < 5; j++) { + pspDebugScreenPutChar( X*7 , Y * 8, fg_col, ' '); + X++; + } + break; + default: + pspDebugScreenPutChar( X*7 , Y * 8, fg_col, c); + X++; + if (X == MX) + { + X = 0; + Y++; + if (Y == MY) + Y = 0; + _pspDebugScreenClearLine(Y); + } + } + } + + return i; +} + +int pspDebugScreenPuts(const char *str) +{ + return pspDebugScreenPrintData(str, strlen(str)); +} +#endif + +#ifdef F_pspDebugScreenPrintf +void pspDebugScreenPrintf(const char *format, ...) +{ + va_list opt; + char buff[2048]; + int bufsz; + + va_start(opt, format); + bufsz = vsnprintf( buff, (size_t) sizeof(buff), format, opt); + (void) pspDebugScreenPrintData(buff, bufsz); +} +#endif + +/* Kernel screen printf, uses the prnt function instead of vsnprintf */ +#ifdef F_pspDebugScreenKprintf + +#define MAX_CLI 4096 +#define CTX_BUF_SIZE 128 + +struct prnt_ctx +{ + unsigned short len; + char buf[CTX_BUF_SIZE]; +}; + +static void cb(struct prnt_ctx *ctx, int type) +{ + if(type == 0x200) + { + ctx->len = 0; + } + else if(type == 0x201) + { + pspDebugScreenPrintData(ctx->buf, ctx->len); + ctx->len = 0; + } + else + { + if(type != '\r') + { + ctx->buf[ctx->len++] = type; + if(ctx->len == CTX_BUF_SIZE) + { + pspDebugScreenPrintData(ctx->buf, ctx->len); + ctx->len = 0; + } + } + } +} + +void pspDebugScreenKprintf(const char *format, ...) +{ + struct prnt_ctx ctx; + va_list opt; + + ctx.len = 0; + + va_start(opt, format); + + prnt((prnt_callback) cb, (void*) &ctx, format, opt); + + va_end(opt); +} +#endif + diff --git a/src/debug/sio.c b/src/debug/sio.c new file mode 100644 index 00000000..f3cffefe --- /dev/null +++ b/src/debug/sio.c @@ -0,0 +1,178 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * sio.c - Some basic SIO (remote port) functions. + * + * Copyright (c) 2005 James Forshaw + * + * $Id: sio.c 2152 2007-01-27 10:09:15Z tyranid $ + */ + +#include +#include +#include + +/* Define some important parameters, not really sure on names. Probably doesn't matter */ +#define PSP_UART4_FIFO 0xBE500000 +#define PSP_UART4_STAT 0xBE500018 +#define PSP_UART4_DIV1 0xBE500024 +#define PSP_UART4_DIV2 0xBE500028 +#define PSP_UART4_CTRL 0xBE50002C +#define PSP_UART_CLK 96000000 +#define PSP_UART_TXFULL 0x20 +#define PSP_UART_RXEMPTY 0x10 + +static int g_enablekprintf = 0; + +/* Some function prototypes we will need */ +int sceHprmEnd(void); +int sceSysregUartIoEnable(int uart); +extern u32 sceKernelRemoveByDebugSection; + +void pspDebugSioPutchar(int ch) +{ + while(_lw(PSP_UART4_STAT) & PSP_UART_TXFULL); + _sw(ch, PSP_UART4_FIFO); +} + +int pspDebugSioGetchar(void) +{ + if(_lw(PSP_UART4_STAT) & PSP_UART_RXEMPTY) + { + return -1; + } + + return _lw(PSP_UART4_FIFO); +} + +void pspDebugSioPuts(const char *str) +{ + while(*str) + { + pspDebugSioPutchar(*str); + str++; + } + + pspDebugSioPutchar('\r'); + pspDebugSioPutchar('\n'); +} + +int pspDebugSioPutData(const char *data, int len) +{ + int i; + + for(i = 0; i < len; i++) + { + pspDebugSioPutchar(data[i]); + } + + return len; +} + +/* Put data to SIO converting any line feeds as necessary */ +int pspDebugSioPutText(const char *data, int len) +{ + int i; + + for(i = 0; i < len; i++) + { + /* If just line feed add a carriage return */ + if(data[i] == '\n') + { + if(((i > 0) && (data[i-1] != '\r')) || (i == 0)) + { + pspDebugSioPutchar('\r'); + } + } + + pspDebugSioPutchar(data[i]); + + if((i < (len - 1)) && (data[i] == '\r') && (data[i+1] != '\n')) + { + pspDebugSioPutchar('\n'); + } + } + + return len; +} + +void pspDebugSioSetBaud(int baud) +{ + int div1, div2; + + /* rate set using the rough formula div1 = (PSP_UART_CLK / baud) >> 6 and + * div2 = (PSP_UART_CLK / baud) & 0x3F + * The uart4 driver actually uses a slightly different formula for div 2 (it + * adds 32 before doing the AND, but it doesn't seem to make a difference + */ + div1 = PSP_UART_CLK / baud; + div2 = div1 & 0x3F; + div1 >>= 6; + + _sw(div1, PSP_UART4_DIV1); + _sw(div2, PSP_UART4_DIV2); + _sw(0x60, PSP_UART4_CTRL); +} + +void pspDebugSioInit(void) +{ + /* Shut down the remote driver */ + sceHprmEnd(); + /* Enable UART 4 */ + sceSysregUartIoEnable(4); + /* Enable remote control power */ + sceSysconCtrlHRPower(1); + /* Delay thread for a but */ + sceKernelDelayThread(2000000); +} + +static u32 *get_debug_register(void) +{ + u32 *pData; + u32 ptr; + + pData = (u32 *) (0x80000000 | ((sceKernelRemoveByDebugSection & 0x03FFFFFF) << 2)); + ptr = ((pData[0] & 0xFFFF) << 16) + (short) (pData[2] & 0xFFFF); + + return (u32 *) ptr; +} + +void pspDebugEnablePutchar(void) +{ + u32 *pData; + + pData = get_debug_register(); + *pData |= 0x1000; +} + +static void PutCharDebug(unsigned short *data, unsigned int type) +{ + if(((type & 0xFF00) == 0) && (g_enablekprintf)) + { + if(type == '\n') + { + pspDebugSioPutchar('\r'); + } + + pspDebugSioPutchar(type); + } +} + +void pspDebugSioInstallKprintf(void) +{ + pspDebugEnablePutchar(); + sceKernelRegisterDebugPutchar(PutCharDebug); + g_enablekprintf = 1; +} + +void pspDebugSioEnableKprintf(void) +{ + g_enablekprintf = 1; +} + +void pspDebugSioDisableKprintf(void) +{ + g_enablekprintf = 0; +} diff --git a/src/debug/stacktrace.c b/src/debug/stacktrace.c new file mode 100644 index 00000000..e1fcc222 --- /dev/null +++ b/src/debug/stacktrace.c @@ -0,0 +1,111 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * callstack.c - Return stack generation for MIPS processors. + * + * Copyright (c) 2005 James Forshaw + * + * $Id: stacktrace.c 1095 2005-09-27 21:02:16Z jim $ + */ + +#include +#include +#include + +#define CALL 0x0C000000 +#define CALL_MASK 0xFC000000 +#define IS_CALL(x) (((x) & CALL_MASK) == CALL) +#define CALL_ADDR(x) (((x) & ~CALL_MASK) << 2) + +extern u32 _ftext; +extern u32 _etext; + +/* Ideally should be something which is automatic */ +#define ELF_START (&_ftext) +#define ELF_END (&_etext) + +/* This is a blatently wrong way of doing a stack trace, but I felt as long as you use some intelligence you + could easily work out if some calls in the trace were invalid :P */ +static int _pspDebugDoStackTrace(u32 *sp, u32 *sp_end, u32 *ra, PspDebugStackTrace *trace, int max) +{ + int count = 0; + int recurse = 0; + + if((ra >= (ELF_START + 2)) && (ra < ELF_END) && (IS_CALL(ra[-2]))) + { + trace[count].func_addr = CALL_ADDR(ra[-2]); + trace[count].call_addr = (u32) (&ra[-2]); + count++; + } + + while((count < max) && (sp < sp_end)) + { + u32 *addr; + /* Try and find all the pointers on the stack, then see if they are within range + and point to a valid return address. There is possible false positives with this + but tbh it is better than nothing */ + addr = (u32*) *sp; + + /* Check that the address could possibly be a valid ra address */ + if((addr >= (ELF_START + 2)) && (addr < ELF_END)) + { + if(IS_CALL(addr[-2])) + { + if((count == 1) && (addr == ra) && (!recurse)) + { + /* Set recurse to 1 so any further calls from ra will be caught */ + /* This is not ideal, but it is to try and prevent the more likely case + of the first ra being found on the stack when first parsing */ + recurse = 1; + } + else + { + trace[count].func_addr = CALL_ADDR(addr[-2]); + trace[count].call_addr = (u32) (&addr[-2]); + count++; + } + } + } + + sp++; + } + + return count; +} + +int pspDebugGetStackTrace2(PspDebugRegBlock *regs, PspDebugStackTrace *trace, int max) +{ + u32 *curr_sp; + u32 *sp_end; + u32 *curr_ra; + int curr_thid; + int count = 0; + SceKernelThreadInfo th_stat; + + /* This is a real simple (and dirty way) of getting a stack trace, none of this code following shitz */ + /* Relies on the system not being totally vaporised on an exception */ + + if((trace == NULL) || (max < 1)) + { + return 0; + } + + curr_thid = sceKernelGetThreadId(); + if(curr_thid >= 0) + { + memset(&th_stat, 0, sizeof(th_stat)); + th_stat.size = sizeof(th_stat); + if(sceKernelReferThreadStatus(curr_thid, &th_stat) >= 0) + { + sp_end = (u32*) ((u8*) th_stat.stack + th_stat.stackSize); + curr_sp = (u32*) (regs->r[29] & ~3); + curr_ra = (u32*) (regs->r[31]); + + count = _pspDebugDoStackTrace(curr_sp, sp_end, curr_ra, trace, max); + } + } + + return count; +} diff --git a/src/debug/stdio.c b/src/debug/stdio.c new file mode 100644 index 00000000..1a5b9cf1 --- /dev/null +++ b/src/debug/stdio.c @@ -0,0 +1,291 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * stdio.c - Debug functions to enable stdout and stderr handlers + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: stdio.c 1925 2006-05-29 14:22:53Z tyranid $ + */ +#include +#include +#include + +#define dbgprintf pspDebugScreenPrintf + +static int g_initialised = 0; +static PspDebugInputHandler g_stdin_handler = NULL; +static PspDebugPrintHandler g_stdout_handler = NULL; +static PspDebugPrintHandler g_stderr_handler = NULL; +static SceUID g_in_sema = 0; +/* Probably stdout and stderr should not be guarded by the same mutex */ +static SceUID g_out_sema = 0; + +static int io_init(PspIoDrvArg *arg) +{ + return 0; +} + +static int io_exit(PspIoDrvArg *arg) +{ + return 0; +} + +static int io_open(PspIoDrvFileArg *arg, char *file, int mode, SceMode mask) +{ + if((arg->fs_num != STDIN_FILENO) && (arg->fs_num != STDOUT_FILENO) && (arg->fs_num != STDERR_FILENO)) + { + return SCE_KERNEL_ERROR_NOFILE; + } + + return 0; +} + +static int io_close(PspIoDrvFileArg *arg) +{ + return 0; +} + +static int io_read(PspIoDrvFileArg *arg, char *data, int len) +{ + int ret = 0; + + (void) sceKernelWaitSema(g_in_sema, 1, 0); + if((arg->fs_num == STDIN_FILENO) && (g_stdin_handler != NULL)) + { + ret = g_stdin_handler(data, len); + } + (void) sceKernelSignalSema(g_in_sema, 1); + + return ret; +} + +static int io_write(PspIoDrvFileArg *arg, const char *data, int len) +{ + int ret = 0; + + (void) sceKernelWaitSema(g_out_sema, 1, 0); + if((arg->fs_num == STDOUT_FILENO) && (g_stdout_handler != NULL)) + { + ret = g_stdout_handler(data, len); + } + else if((arg->fs_num == STDERR_FILENO) && (g_stderr_handler != NULL)) + { + ret = g_stderr_handler(data, len); + } + (void) sceKernelSignalSema(g_out_sema, 1); + + return ret; +} + +static SceOff io_lseek(PspIoDrvFileArg *arg, SceOff ofs, int whence) +{ + return 0; +} + +static int io_ioctl(PspIoDrvFileArg *arg, unsigned int cmd, void *indata, int inlen, void *outdata, int outlen) +{ + return 0; +} + +static int io_remove(PspIoDrvFileArg *arg, const char *name) +{ + return 0; +} + +static int io_mkdir(PspIoDrvFileArg *arg, const char *name, SceMode mode) +{ + return 0; +} + +static int io_rmdir(PspIoDrvFileArg *arg, const char *name) +{ + return 0; +} + +static int io_dopen(PspIoDrvFileArg *arg, const char *dir) +{ + return 0; +} + +static int io_dclose(PspIoDrvFileArg *arg) +{ + return 0; +} + +static int io_dread(PspIoDrvFileArg *arg, SceIoDirent *dir) +{ + return 0; +} + +static int io_getstat(PspIoDrvFileArg *arg, const char *file, SceIoStat *stat) +{ + return 0; +} + +static int io_chstat(PspIoDrvFileArg *arg, const char *file, SceIoStat *stat, int bits) +{ + return 0; +} + +static int io_rename(PspIoDrvFileArg *arg, const char *oldname, const char *newname) +{ + return 0; +} + +static int io_chdir(PspIoDrvFileArg *arg, const char *dir) +{ + return 0; +} + +static int io_mount(PspIoDrvFileArg *arg) +{ + return 0; +} + +static int io_umount(PspIoDrvFileArg *arg) +{ + return 0; +} + +static int io_devctl(PspIoDrvFileArg *arg, const char *devname, unsigned int cmd, void *indata, int inlen, void *outdata, int outlen) +{ + return 0; +} + +static int io_unknown(PspIoDrvFileArg *arg) +{ + return 0; +} + +static PspIoDrvFuncs tty_funcs = +{ + io_init, + io_exit, + io_open, + io_close, + io_read, + io_write, + io_lseek, + io_ioctl, + io_remove, + io_mkdir, + io_rmdir, + io_dopen, + io_dclose, + io_dread, + io_getstat, + io_chstat, + io_rename, + io_chdir, + io_mount, + io_umount, + io_devctl, + io_unknown, +}; + +static PspIoDrv tty_driver = +{ + "tty", 0x10, 0x800, "TTY", &tty_funcs +}; + +static int tty_init(void) +{ + int ret; + (void) sceIoDelDrv("tty"); /* Ignore error */ + ret = sceIoAddDrv(&tty_driver); + if(ret < 0) + { + return ret; + } + + g_in_sema = sceKernelCreateSema("TtyInMutex", 0, 1, 1, NULL); + if(g_in_sema < 0) + { + return g_in_sema; + } + + g_out_sema = sceKernelCreateSema("TtyOutMutex", 0, 1, 1, NULL); + if(g_out_sema < 0) + { + return g_out_sema; + } + + ret = sceIoReopen("tty0:", PSP_O_RDONLY, 0777, sceKernelStdin()); + if(ret < 0) + { + return ret; + } + + ret = sceKernelStdoutReopen("tty1:", PSP_O_WRONLY, 0777); + if(ret < 0) + { + return ret; + } + + ret = sceKernelStderrReopen("tty2:", PSP_O_WRONLY, 0777); + if(ret < 0) + { + return ret; + } + + g_initialised = 1; + + return 0; +} + +int pspDebugInstallStdinHandler(PspDebugInputHandler handler) +{ + if(g_initialised == 0) + { + int ret; + ret = tty_init(); + if(ret < 0) + { + return ret; + } + } + + g_stdin_handler = handler; + + return 0; +} + +int pspDebugInstallStdoutHandler(PspDebugPrintHandler handler) +{ + if(g_initialised == 0) + { + int ret; + ret = tty_init(); + if(ret < 0) + { + return ret; + } + } + + g_stdout_handler = handler; + + return 0; +} + +int pspDebugInstallStderrHandler(PspDebugPrintHandler handler) +{ + if(g_initialised == 0) + { + int ret; + ret = tty_init(); + if(ret < 0) + { + return ret; + } + } + + g_stderr_handler = handler; + + return 0; +} + diff --git a/src/display/Makefile.am b/src/display/Makefile.am new file mode 100644 index 00000000..ef0cea87 --- /dev/null +++ b/src/display/Makefile.am @@ -0,0 +1,30 @@ + +libdir = @PSPSDK_LIBDIR@ + +CC = @PSP_CC@ +CCAS = $(CC) +AR = @PSP_AR@ +RANLIB = @PSP_RANLIB@ + +INCLUDES = -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel +CFLAGS = @PSPSDK_CFLAGS@ +CCASFLAGS = $(CFLAGS) -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel + +DISPLAY_OBJS = sceDisplay_0000.o sceDisplay_0001.o sceDisplay_0002.o sceDisplay_0003.o sceDisplay_0004.o sceDisplay_0005.o sceDisplay_0006.o sceDisplay_0007.o sceDisplay_0008.o sceDisplay_0009.o sceDisplay_0010.o sceDisplay_0011.o sceDisplay_0012.o sceDisplay_0013.o sceDisplay_0014.o sceDisplay_0015.o sceDisplay_0016.o sceDisplay_0017.o + +DISPLAYDRIVER_OBJS = sceDisplay_driver_0000.o sceDisplay_driver_0001.o sceDisplay_driver_0002.o sceDisplay_driver_0003.o sceDisplay_driver_0004.o sceDisplay_driver_0005.o sceDisplay_driver_0006.o sceDisplay_driver_0007.o sceDisplay_driver_0008.o sceDisplay_driver_0009.o sceDisplay_driver_0010.o sceDisplay_driver_0011.o sceDisplay_driver_0012.o sceDisplay_driver_0013.o sceDisplay_driver_0014.o sceDisplay_driver_0015.o sceDisplay_driver_0016.o sceDisplay_driver_0017.o sceDisplay_driver_0018.o sceDisplay_driver_0019.o sceDisplay_driver_0020.o sceDisplay_driver_0021.o sceDisplay_driver_0022.o sceDisplay_driver_0023.o sceDisplay_driver_0024.o sceDisplay_driver_0025.o sceDisplay_driver_0026.o + +libpspdisplayincludedir = @PSPSDK_INCLUDEDIR@ +libpspdisplayinclude_HEADERS = pspdisplay.h pspdisplay_kernel.h + +lib_LIBRARIES = libpspdisplay.a libpspdisplay_driver.a +libpspdisplay_a_SOURCES = sceDisplay.S +libpspdisplay_a_LIBADD = $(DISPLAY_OBJS) +libpspdisplay_driver_a_SOURCES = sceDisplay_driver.S +libpspdisplay_driver_a_LIBADD = $(DISPLAYDRIVER_OBJS) + +$(DISPLAY_OBJS): sceDisplay.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(DISPLAYDRIVER_OBJS): sceDisplay_driver.S + $(COMPILE) -DF_$* $< -c -o $@ diff --git a/src/display/pspdisplay.h b/src/display/pspdisplay.h new file mode 100644 index 00000000..cb2e2dd3 --- /dev/null +++ b/src/display/pspdisplay.h @@ -0,0 +1,129 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspdisplay.h - Prototypes for the sceDisplay library. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * Copyright (c) 2007 Alexander Berl + * + * $Id: pspdisplay.h 2433 2008-10-15 10:00:27Z iwn $ + */ +#ifndef __DISPLAY_H__ +#define __DISPLAY_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** Framebuffer pixel formats. */ +enum PspDisplayPixelFormats { + /** 16-bit RGB 5:6:5. */ + PSP_DISPLAY_PIXEL_FORMAT_565 = 0, + /** 16-bit RGBA 5:5:5:1. */ + PSP_DISPLAY_PIXEL_FORMAT_5551, + /* 16-bit RGBA 4:4:4:4. */ + PSP_DISPLAY_PIXEL_FORMAT_4444, + /* 32-bit RGBA 8:8:8:8. */ + PSP_DISPLAY_PIXEL_FORMAT_8888 +}; + +enum PspDisplaySetBufSync { + /** Buffer change effective immediately */ + PSP_DISPLAY_SETBUF_IMMEDIATE = 0, + /** Buffer change effective next frame */ + PSP_DISPLAY_SETBUF_NEXTFRAME = 1 +}; + + +enum PspDisplayErrorCodes +{ + SCE_DISPLAY_ERROR_OK = 0, + SCE_DISPLAY_ERROR_POINTER = 0x80000103, + SCE_DISPLAY_ERROR_ARGUMENT = 0x80000107 +}; + + +/** + * Set display mode + * + * @par Example1: + * @code + * @endcode + * + * @param mode - Display mode, normally 0. + * @param width - Width of screen in pixels. + * @param height - Height of screen in pixels. + * + * @return ??? + */ +int sceDisplaySetMode(int mode, int width, int height); + +/** + * Get display mode + * + * @param pmode - Pointer to an integer to receive the current mode. + * @param pwidth - Pointer to an integer to receive the current width. + * @param pheight - Pointer to an integer to receive the current height, + * + * @return 0 on success + */ +int sceDisplayGetMode(int *pmode, int *pwidth, int *pheight); + +/** + * Display set framebuf + * + * @param topaddr - address of start of framebuffer + * @param bufferwidth - buffer width (must be power of 2) + * @param pixelformat - One of ::PspDisplayPixelFormats. + * @param sync - One of ::PspDisplaySetBufSync + * + * @return 0 on success + */ +int sceDisplaySetFrameBuf(void *topaddr, int bufferwidth, int pixelformat, int sync); + +/** + * Get Display Framebuffer information + * + * @param topaddr - pointer to void* to receive address of start of framebuffer + * @param bufferwidth - pointer to int to receive buffer width (must be power of 2) + * @param pixelformat - pointer to int to receive one of ::PspDisplayPixelFormats. + * @param sync - One of ::PspDisplaySetBufSync + * + * @return 0 on success + */ +int sceDisplayGetFrameBuf(void **topaddr, int *bufferwidth, int *pixelformat, int sync); + +/** + * Number of vertical blank pulses up to now + */ +unsigned int sceDisplayGetVcount(void); + +/** + * Wait for vertical blank start + */ +int sceDisplayWaitVblankStart(void); + +/** + * Wait for vertical blank start with callback + */ +int sceDisplayWaitVblankStartCB(void); + +/** + * Wait for vertical blank + */ +int sceDisplayWaitVblank(void); + +/** + * Wait for vertical blank with callback + */ +int sceDisplayWaitVblankCB(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/display/pspdisplay_kernel.h b/src/display/pspdisplay_kernel.h new file mode 100644 index 00000000..694d5ea5 --- /dev/null +++ b/src/display/pspdisplay_kernel.h @@ -0,0 +1,72 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspdisplay_kernel.h - Prototypes for the sceDisplay_driver library. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * Copyright (c) 2007 Alexander Berl + * + * $Id: pspdisplay_kernel.h 2271 2007-07-20 13:08:41Z oopo $ + */ +#ifndef __DISPLAYKERNEL_H__ +#define __DISPLAYKERNEL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Display set framebuf + * + * @param pri - Priority + * @param topaddr - address of start of framebuffer + * @param bufferwidth - buffer width (must be power of 2) + * @param pixelformat - One of ::PspDisplayPixelFormats. + * @param sync - One of ::PspDisplaySetBufSync + * + * @return 0 on success + */ +int sceDisplay_driver_63E22A26(int pri, void *topaddr, int bufferwidth, int pixelformat, int sync); + +/** + * Get Display Framebuffer information + * + * @param pri - Priority + * @param topaddr - pointer to void* to receive address of start of framebuffer + * @param bufferwidth - pointer to int to receive buffer width (must be power of 2) + * @param pixelformat - pointer to int to receive one of ::PspDisplayPixelFormats. + * @param sync - One of ::PspDisplaySetBufSync + * + * @return 0 on success + */ +int sceDisplay_driver_5B5AEFAD(int pri, void **topaddr, int *bufferwidth, int *pixelformat, int sync); + +/* Define some names to make it nicer */ +#define sceDisplaySetFrameBufferInternal sceDisplay_driver_63E22A26 +#define sceDisplayGetFrameBufferInternal sceDisplay_driver_5B5AEFAD + +/** + * Set Display brightness to a particular level + * + * @param level - Level of the brightness. it goes from 0 (black screen) to 100 (max brightness) + * @param unk1 - Unknown can be 0 or 1 (pass 0) + */ +void sceDisplaySetBrightness(int level,int unk1); + +/** + * Get current display brightness + * + * @param level - Pointer to int to receive the current brightness level (0-100) + * @param unk1 - Pointer to int, receives unknown, it's 1 or 0 + */ +void sceDisplayGetBrightness(int *level,int *unk1); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/display/sceDisplay.S b/src/display/sceDisplay.S new file mode 100644 index 00000000..558a7193 --- /dev/null +++ b/src/display/sceDisplay.S @@ -0,0 +1,58 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceDisplay_0000 + IMPORT_START "sceDisplay",0x40010000 +#endif +#ifdef F_sceDisplay_0001 + IMPORT_FUNC "sceDisplay",0x0E20F177,sceDisplaySetMode +#endif +#ifdef F_sceDisplay_0002 + IMPORT_FUNC "sceDisplay",0xDEA197D4,sceDisplayGetMode +#endif +#ifdef F_sceDisplay_0003 + IMPORT_FUNC "sceDisplay",0xDBA6C4C4,sceDisplayGetFramePerSec +#endif +#ifdef F_sceDisplay_0004 + IMPORT_FUNC "sceDisplay",0x7ED59BC4,sceDisplaySetHoldMode +#endif +#ifdef F_sceDisplay_0005 + IMPORT_FUNC "sceDisplay",0xA544C486,sceDisplaySetResumeMode +#endif +#ifdef F_sceDisplay_0006 + IMPORT_FUNC "sceDisplay",0x289D82FE,sceDisplaySetFrameBuf +#endif +#ifdef F_sceDisplay_0007 + IMPORT_FUNC "sceDisplay",0xEEDA2E54,sceDisplayGetFrameBuf +#endif +#ifdef F_sceDisplay_0008 + IMPORT_FUNC "sceDisplay",0xB4F378FA,sceDisplayIsForeground +#endif +#ifdef F_sceDisplay_0009 + IMPORT_FUNC "sceDisplay",0x31C4BAA8,sceDisplay_31C4BAA8 +#endif +#ifdef F_sceDisplay_0010 + IMPORT_FUNC "sceDisplay",0x9C6EAAD7,sceDisplayGetVcount +#endif +#ifdef F_sceDisplay_0011 + IMPORT_FUNC "sceDisplay",0x4D4E10EC,sceDisplayIsVblank +#endif +#ifdef F_sceDisplay_0012 + IMPORT_FUNC "sceDisplay",0x36CDFADE,sceDisplayWaitVblank +#endif +#ifdef F_sceDisplay_0013 + IMPORT_FUNC "sceDisplay",0x8EB9EC49,sceDisplayWaitVblankCB +#endif +#ifdef F_sceDisplay_0014 + IMPORT_FUNC "sceDisplay",0x984C27E7,sceDisplayWaitVblankStart +#endif +#ifdef F_sceDisplay_0015 + IMPORT_FUNC "sceDisplay",0x46F186C3,sceDisplayWaitVblankStartCB +#endif +#ifdef F_sceDisplay_0016 + IMPORT_FUNC "sceDisplay",0x773DD3A3,sceDisplayGetCurrentHcount +#endif +#ifdef F_sceDisplay_0017 + IMPORT_FUNC "sceDisplay",0x210EAB3A,sceDisplayGetAccumulatedHcount +#endif diff --git a/src/display/sceDisplay_driver.S b/src/display/sceDisplay_driver.S new file mode 100644 index 00000000..0b2c1ecc --- /dev/null +++ b/src/display/sceDisplay_driver.S @@ -0,0 +1,85 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceDisplay_driver_0000 + IMPORT_START "sceDisplay_driver",0x00010000 +#endif +#ifdef F_sceDisplay_driver_0001 + IMPORT_FUNC "sceDisplay_driver",0x206276C2,sceDisplayInit +#endif +#ifdef F_sceDisplay_driver_0002 + IMPORT_FUNC "sceDisplay_driver",0x7A10289D,sceDisplayEnd +#endif +#ifdef F_sceDisplay_driver_0003 + IMPORT_FUNC "sceDisplay_driver",0x0E20F177,sceDisplaySetMode +#endif +#ifdef F_sceDisplay_driver_0004 + IMPORT_FUNC "sceDisplay_driver",0xDEA197D4,sceDisplayGetMode +#endif +#ifdef F_sceDisplay_driver_0005 + IMPORT_FUNC "sceDisplay_driver",0xDBA6C4C4,sceDisplayGetFramePerSec +#endif +#ifdef F_sceDisplay_driver_0006 + IMPORT_FUNC "sceDisplay_driver",0x432D133F,sceDisplayEnable +#endif +#ifdef F_sceDisplay_driver_0007 + IMPORT_FUNC "sceDisplay_driver",0x681EE6A7,sceDisplayDisable +#endif +#ifdef F_sceDisplay_driver_0008 + IMPORT_FUNC "sceDisplay_driver",0x7ED59BC4,sceDisplaySetHoldMode +#endif +#ifdef F_sceDisplay_driver_0009 + IMPORT_FUNC "sceDisplay_driver",0xA544C486,sceDisplaySetResumeMode +#endif +#ifdef F_sceDisplay_driver_0010 + IMPORT_FUNC "sceDisplay_driver",0x63E22A26,sceDisplay_driver_63E22A26 +#endif +#ifdef F_sceDisplay_driver_0011 + IMPORT_FUNC "sceDisplay_driver",0x5B5AEFAD,sceDisplay_driver_5B5AEFAD +#endif +#ifdef F_sceDisplay_driver_0012 + IMPORT_FUNC "sceDisplay_driver",0x289D82FE,sceDisplaySetFrameBuf +#endif +#ifdef F_sceDisplay_driver_0013 + IMPORT_FUNC "sceDisplay_driver",0xEEDA2E54,sceDisplayGetFrameBuf +#endif +#ifdef F_sceDisplay_driver_0014 + IMPORT_FUNC "sceDisplay_driver",0xB4F378FA,sceDisplayIsForeground +#endif +#ifdef F_sceDisplay_driver_0015 + IMPORT_FUNC "sceDisplay_driver",0xAC14F1FF,sceDisplayGetForegroundLevel +#endif +#ifdef F_sceDisplay_driver_0016 + IMPORT_FUNC "sceDisplay_driver",0x9E3C6DC6,sceDisplaySetBrightness +#endif +#ifdef F_sceDisplay_driver_0017 + IMPORT_FUNC "sceDisplay_driver",0x31C4BAA8,sceDisplayGetBrightness +#endif +#ifdef F_sceDisplay_driver_0018 + IMPORT_FUNC "sceDisplay_driver",0x9C6EAAD7,sceDisplayGetVcount +#endif +#ifdef F_sceDisplay_driver_0019 + IMPORT_FUNC "sceDisplay_driver",0x4D4E10EC,sceDisplayIsVblank +#endif +#ifdef F_sceDisplay_driver_0020 + IMPORT_FUNC "sceDisplay_driver",0x69B53541,sceDisplayGetVblankRest +#endif +#ifdef F_sceDisplay_driver_0021 + IMPORT_FUNC "sceDisplay_driver",0x36CDFADE,sceDisplayWaitVblank +#endif +#ifdef F_sceDisplay_driver_0022 + IMPORT_FUNC "sceDisplay_driver",0x8EB9EC49,sceDisplayWaitVblankCB +#endif +#ifdef F_sceDisplay_driver_0023 + IMPORT_FUNC "sceDisplay_driver",0x984C27E7,sceDisplayWaitVblankStart +#endif +#ifdef F_sceDisplay_driver_0024 + IMPORT_FUNC "sceDisplay_driver",0x46F186C3,sceDisplayWaitVblankStartCB +#endif +#ifdef F_sceDisplay_driver_0025 + IMPORT_FUNC "sceDisplay_driver",0x773DD3A3,sceDisplayGetCurrentHcount +#endif +#ifdef F_sceDisplay_driver_0026 + IMPORT_FUNC "sceDisplay_driver",0x210EAB3A,sceDisplayGetAccumulatedHcount +#endif diff --git a/src/fpu/Makefile.am b/src/fpu/Makefile.am new file mode 100644 index 00000000..a44fbc68 --- /dev/null +++ b/src/fpu/Makefile.am @@ -0,0 +1,18 @@ + +libdir = @PSPSDK_LIBDIR@ + +CC = @PSP_CC@ +CCAS = $(CC) +AR = @PSP_AR@ +RANLIB = @PSP_RANLIB@ + +INCLUDES = -I$(top_srcdir)/src/base -I$(top_srcdir)/src/debug -I$(top_srcdir)/src/user +CFLAGS = @PSPSDK_CFLAGS@ -std=gnu99 -Wall -Wmissing-prototypes +CCASFLAGS = $(CFLAGS) -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel + +libpspfpuincludedir = @PSPSDK_INCLUDEDIR@ +libpspfpuinclude_HEADERS = pspfpu.h + +lib_LIBRARIES = libpspfpu.a +libpspfpu_a_SOURCES = pspfpu.c +libpspfpu_a_LIBADD = diff --git a/src/fpu/pspfpu.c b/src/fpu/pspfpu.c new file mode 100644 index 00000000..d5dcff4f --- /dev/null +++ b/src/fpu/pspfpu.c @@ -0,0 +1,151 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspfpu.h - PSP FPU library + * + * Copyright (c) 2006 TyRaNiD (James F.) + * + * $Id: pspfpu.c 1781 2006-02-04 12:53:40Z tyranid $ + */ +#include "pspfpu.h" + +uint32_t pspfpu_get_fcr31(void) +{ + uint32_t ret; + + asm( + "cfc1 %0, $31\n" + : "=r"(ret) + ); + + return ret; +} + +void pspfpu_set_fcr31(uint32_t var) +{ + asm ( + "ctc1 %0, $31\n" + : + : "r"(var) + ); +} + +void pspfpu_set_roundmode(enum FpuRoundMode mode) +{ + uint32_t fcr; + + fcr = pspfpu_get_fcr31(); + fcr &= ~FPU_RM_MASK; + fcr |= (mode & FPU_RM_MASK); + pspfpu_set_fcr31(fcr); +} + +enum FpuRoundMode pspfpu_get_roundmode(void) +{ + return pspfpu_get_fcr31() & FPU_RM_MASK; +} + +uint32_t pspfpu_get_flags(void) +{ + uint32_t fcr; + + fcr = pspfpu_get_fcr31(); + + return (fcr & FPU_FLAGS_MASK) >> FPU_FLAGS_POS; +} + +void pspfpu_clear_flags(uint32_t clear) +{ + uint32_t fcr; + + clear &= 0x1F; + fcr = pspfpu_get_fcr31(); + fcr &= ~(clear << FPU_FLAGS_POS); + pspfpu_set_fcr31(fcr); +} + +uint32_t pspfpu_get_enable(void) +{ + uint32_t fcr; + + fcr = pspfpu_get_fcr31(); + + return (fcr & FPU_ENABLE_MASK) >> FPU_ENABLE_POS; +} + +void pspfpu_set_enable(uint32_t enable) +{ + uint32_t fcr; + + enable &= 0x1F; + fcr = pspfpu_get_fcr31() & ~FPU_ENABLE_MASK; + fcr |= enable << FPU_ENABLE_POS; + pspfpu_set_fcr31(fcr); +} + +uint32_t pspfpu_get_cause(void) +{ + uint32_t fcr; + + fcr = pspfpu_get_fcr31(); + + return (fcr & FPU_CAUSE_MASK) >> FPU_CAUSE_POS; +} + +void pspfpu_clear_cause(uint32_t clear) +{ + uint32_t fcr; + + clear &= 0x3F; + fcr = pspfpu_get_fcr31(); + fcr &= ~(clear << FPU_CAUSE_POS); + pspfpu_set_fcr31(fcr); +} + +uint32_t pspfpu_get_fs(void) +{ + uint32_t fcr; + + fcr = pspfpu_get_fcr31(); + + return (fcr & FPU_FS_MASK) >> FPU_FS_POS; +} + +void pspfpu_set_fs(uint32_t fs) +{ + uint32_t fcr; + + fcr = pspfpu_get_fcr31(); + fcr &= ~FPU_FS_MASK; + + fcr |= ((fs & 1) << FPU_FS_POS); + + pspfpu_set_fcr31(fcr); +} + +uint32_t pspfpu_get_condbits(void) +{ + uint32_t fcr; + uint32_t cond; + + fcr = pspfpu_get_fcr31(); + cond = (fcr & FPU_CC0_MASK) >> FPU_CC0_POS; + cond |= (fcr & FPU_CC17_MASK) >> (FPU_CC17_POS-1); + + return cond; +} + +void pspfpu_clear_condbits(uint32_t clear) +{ + uint32_t fcr; + + clear &= 0xFF; + + fcr = pspfpu_get_fcr31(); + fcr &= ~((clear & 1) << FPU_CC0_POS); + fcr &= ~((clear & 0xFE) << (FPU_CC17_POS-1)); + + pspfpu_set_fcr31(fcr); +} diff --git a/src/fpu/pspfpu.h b/src/fpu/pspfpu.h new file mode 100644 index 00000000..8bc0c888 --- /dev/null +++ b/src/fpu/pspfpu.h @@ -0,0 +1,185 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspfpu.h - Prototypes for the FPU library + * + * Copyright (c) 2006 TyRaNiD (James F.) + * + * $Id: pspfpu.h 1782 2006-02-04 12:57:05Z tyranid $ + */ +#ifndef __PSPFPU_H__ +#define __PSPFPU_H__ + +#include + +/* Note the bit settings in here come from an NEC MIPSv4 document, + * they seem sensible. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** Enumeration for FPU rounding modes */ +enum FpuRoundMode +{ + /** Round to nearest representable value */ + FPU_RN = 0, + /** Round towards zero */ + FPU_RZ = 1, + /** Round towards plus infinity */ + FPU_RP = 2, + /** Round towards minus infinity */ + FPU_RM = 3, +}; + +/** Mask value for rounding mode */ +#define FPU_RM_MASK 0x03 + +/** Enumeration for FPU exceptions */ +enum FpuExceptions +{ + /** Inexact operation exception */ + FPU_EXCEPTION_INEXACT = 0x01, + /** Underflow exception */ + FPU_EXCEPTION_UNDERFLOW = 0x02, + /** Overflow exception */ + FPU_EXCEPTION_OVERFLOW = 0x04, + /** Division by zero exception */ + FPU_EXCEPTION_DIVBYZERO = 0x08, + /** Invalid operation exception */ + FPU_EXCEPTION_INVALIDOP = 0x10, + /** Unimplemented operation exception (only supported in the cause bits) */ + FPU_EXCEPTION_UNIMPOP = 0x20, + /** All exceptions */ + FPU_EXCEPTION_ALL = 0x3F +}; + +/** Bit position of the flag bits */ +#define FPU_FLAGS_POS 2 +/** Bit position of the enable bits */ +#define FPU_ENABLE_POS 7 +/** Bit position of the cause bits */ +#define FPU_CAUSE_POS 12 +/** Bit position of the cc0 bit */ +#define FPU_CC0_POS 23 +/** Bit position of the fs bit */ +#define FPU_FS_POS 24 +/** Bit position of the cc1->7 bits */ +#define FPU_CC17_POS 25 + +#define FPU_FLAGS_MASK (0x1F << FPU_FLAGS_POS) +#define FPU_ENABLE_MASK (0x1F << FPU_ENABLE_POS) +#define FPU_CAUSE_MASK (0x3F << FPU_CAUSE_POS) +#define FPU_CC0_MASK (1 << FPU_CC0_POS) +#define FPU_FS_MASK (1 << FPU_FS_POS) +#define FPU_CC17_MASK (0x7F << FPU_CC17_POS) + +/** + * Get the current value of the control/status register + * + * @return The value of the control/status register + */ +uint32_t pspfpu_get_fcr31(void); + +/** + * Set the current value of the control/status register + * + * @param var - The value to set. + */ +void pspfpu_set_fcr31(uint32_t var); + +/** + * Set the current round mode + * + * @param mode - The rounding mode to set, one of ::FpuRoundMode + */ +void pspfpu_set_roundmode(enum FpuRoundMode mode); + +/** + * Get the current round mode + * + * @return The round mode, one of ::FpuRoundMode + */ +enum FpuRoundMode pspfpu_get_roundmode(void); + +/** + * Get the exception flags (set when an exception occurs but + * the actual exception bit is not enabled) + * + * @return Bitmask of the flags, zero or more of ::FpuExceptions + */ +uint32_t pspfpu_get_flags(void); + +/** + * Clear the flags bits + * + * @param clear - Bitmask of the bits to clear, one or more of ::FpuExceptions + */ +void pspfpu_clear_flags(uint32_t clear); + +/** + * Get the exception enable flags + * + * @return Bitmask of the flags, zero or more of ::FpuExceptions + */ +uint32_t pspfpu_get_enable(void); + +/** + * Set the enable flags bits + * + * @param enable - Bitmask of exceptions to enable, zero or more of ::FpuExceptions + */ +void pspfpu_set_enable(uint32_t enable); + +/** + * Get the cause bits (only useful if you installed your own exception handler) + * + * @return Bitmask of flags, zero or more of ::FpuExceptions + */ +uint32_t pspfpu_get_cause(void); + +/** + * Clear the cause bits + * + * @param clear - Bitmask of the bits to clear, one or more of ::FpuExceptions + * + */ +void pspfpu_clear_cause(uint32_t clear); + +/** + * Get the current value of the FS bit (if FS is 0 then an exception occurs with + * denormalized values, if 1 then they are rewritten as 0. + * + * @return The current state of the FS bit (0 or 1) + */ +uint32_t pspfpu_get_fs(void); + +/** + * Set the FS bit + * + * @param fs - 0 or 1 to unset or set fs + */ +void pspfpu_set_fs(uint32_t fs); + +/** + * Get the condition flags (8 bits) + * + * @return The current condition flags + */ +uint32_t pspfpu_get_condbits(void); + +/** + * Clear the condition bits + * + * @param clear - Bitmask of the bits to clear + */ +void pspfpu_clear_condbits(uint32_t clear); + +#ifdef __cplusplus +} +#endif + +#endif /* __PSPFPU_H__ */ diff --git a/src/ge/Makefile.am b/src/ge/Makefile.am new file mode 100644 index 00000000..3910965d --- /dev/null +++ b/src/ge/Makefile.am @@ -0,0 +1,30 @@ + +libdir = @PSPSDK_LIBDIR@ + +CC = @PSP_CC@ +CCAS = $(CC) +AR = @PSP_AR@ +RANLIB = @PSP_RANLIB@ + +INCLUDES = -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel +CFLAGS = @PSPSDK_CFLAGS@ +CCASFLAGS = $(CFLAGS) -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel + +GE_OBJS = sceGe_user_0000.o sceGe_user_0001.o sceGe_user_0002.o sceGe_user_0003.o sceGe_user_0004.o sceGe_user_0005.o sceGe_user_0006.o sceGe_user_0007.o sceGe_user_0008.o sceGe_user_0009.o sceGe_user_0010.o sceGe_user_0011.o sceGe_user_0012.o sceGe_user_0013.o sceGe_user_0014.o sceGe_user_0015.o sceGe_user_0016.o sceGe_user_0017.o + +GEDRIVER_OBJS = sceGe_driver_0000.o sceGe_driver_0001.o sceGe_driver_0002.o sceGe_driver_0003.o sceGe_driver_0004.o sceGe_driver_0005.o sceGe_driver_0006.o sceGe_driver_0007.o sceGe_driver_0008.o sceGe_driver_0009.o sceGe_driver_0010.o sceGe_driver_0011.o sceGe_driver_0012.o sceGe_driver_0013.o sceGe_driver_0014.o sceGe_driver_0015.o sceGe_driver_0016.o sceGe_driver_0017.o sceGe_driver_0018.o sceGe_driver_0019.o sceGe_driver_0020.o sceGe_driver_0021.o sceGe_driver_0022.o sceGe_driver_0023.o + +libpspgeincludedir = @PSPSDK_INCLUDEDIR@ +libpspgeinclude_HEADERS = pspge.h + +lib_LIBRARIES = libpspge.a libpspge_driver.a +libpspge_a_SOURCES = sceGe_user.S +libpspge_a_LIBADD = $(GE_OBJS) +libpspge_driver_a_SOURCES = sceGe_driver.S +libpspge_driver_a_LIBADD = $(GEDRIVER_OBJS) + +$(GE_OBJS): sceGe_user.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(GEDRIVER_OBJS): sceGe_driver.S + $(COMPILE) -DF_$* $< -c -o $@ diff --git a/src/ge/pspge.h b/src/ge/pspge.h new file mode 100644 index 00000000..ce0101a0 --- /dev/null +++ b/src/ge/pspge.h @@ -0,0 +1,213 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspge.h - Prototypes for the sceGe library. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: pspge.h 2433 2008-10-15 10:00:27Z iwn $ + */ +#ifndef __GE_H__ +#define __GE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** Stores the state of the GE. */ +typedef struct PspGeContext { + unsigned int context[512]; +} PspGeContext; + +/** Typedef for a GE callback */ +typedef void (*PspGeCallback)(int id, void *arg); + +/** Structure to hold the callback data */ +typedef struct PspGeCallbackData +{ + /** GE callback for the signal interrupt */ + PspGeCallback signal_func; + /** GE callback argument for signal interrupt */ + void *signal_arg; + /** GE callback for the finish interrupt */ + PspGeCallback finish_func; + /** GE callback argument for finish interrupt */ + void *finish_arg; +} PspGeCallbackData; + +typedef struct PspGeListArgs +{ + unsigned int size; + PspGeContext* context; +} PspGeListArgs; + +/** + * Get the size of VRAM. + * + * @return The size of VRAM (in bytes). + */ +unsigned int sceGeEdramGetSize(void); + +/** + * Get the address of VRAM. + * + * @return A pointer to the base of VRAM. + */ +void * sceGeEdramGetAddr(void); + +/** + * Retrive the current value of a GE command. + * + * @param cmd - The GE command register to retrieve. + * + * @return The value of the GE command. + */ +unsigned int sceGeGetCmd(int cmd); + +/** GE matrix types. */ +typedef enum PspGeMatrixTypes { + /** Bone matrices. */ + PSP_GE_MATRIX_BONE0 = 0, + PSP_GE_MATRIX_BONE1, + PSP_GE_MATRIX_BONE2, + PSP_GE_MATRIX_BONE3, + PSP_GE_MATRIX_BONE4, + PSP_GE_MATRIX_BONE5, + PSP_GE_MATRIX_BONE6, + PSP_GE_MATRIX_BONE7, + /** World matrix. */ + PSP_GE_MATRIX_WORLD, + /** View matrix. */ + PSP_GE_MATRIX_VIEW, + /** Projection matrix. */ + PSP_GE_MATRIX_PROJECTION, + PSP_GE_MATRIX_TEXGEN +} PspGeMatrixTypes; + +/** + * Retrieve a matrix of the given type. + * + * @param type - One of ::PspGeMatrixTypes. + * @param matrix - Pointer to a variable to store the matrix. + * + * @return ??? + */ +int sceGeGetMtx(int type, void *matrix); + +/** + * Save the GE's current state. + * + * @param context - Pointer to a ::PspGeContext. + * + * @return ??? + */ +int sceGeSaveContext(PspGeContext *context); + +/** + * Restore a previously saved GE context. + * + * @param context - Pointer to a ::PspGeContext. + * + * @return ??? + */ +int sceGeRestoreContext(const PspGeContext *context); + +/** + * Enqueue a display list at the tail of the GE display list queue. + * + * @param list - The head of the list to queue. + * @param stall - The stall address. + * If NULL then no stall address set and the list is transferred immediately. + * @param cbid - ID of the callback set by calling sceGeSetCallback + * @param arg - Structure containing GE context buffer address + * + * @return The ID of the queue. + */ +int sceGeListEnQueue(const void *list, void *stall, int cbid, PspGeListArgs *arg); + +/** + * Enqueue a display list at the head of the GE display list queue. + * + * @param list - The head of the list to queue. + * @param stall - The stall address. + * If NULL then no stall address set and the list is transferred immediately. + * @param cbid - ID of the callback set by calling sceGeSetCallback + * @param arg - Structure containing GE context buffer address + * + * @return The ID of the queue. + */ +int sceGeListEnQueueHead(const void *list, void *stall, int cbid, PspGeListArgs *arg); + +/** + * Cancel a queued or running list. + * + * @param qid - The ID of the queue. + * + * @return ??? + */ +int sceGeListDeQueue(int qid); + +/** + * Update the stall address for the specified queue. + * + * @param qid - The ID of the queue. + * @param stall - The stall address to update + * + * @return Unknown. Probably 0 if successful. + */ +int sceGeListUpdateStallAddr(int qid, void *stall); + + +/** Wait condition for ::sceGeListSync() and ::sceGeDrawSync(). */ +typedef enum PspGeSyncType { + PSP_GE_LIST_DONE = 0, + PSP_GE_LIST_QUEUED, + PSP_GE_LIST_DRAWING_DONE, + PSP_GE_LIST_STALL_REACHED, + PSP_GE_LIST_CANCEL_DONE +} PspGeSyncType; + +/** + * Wait for syncronisation of a list. + * + * @param qid - The queue ID of the list to sync. + * @param syncType - Specifies the condition to wait on. One of ::PspGeSyncType. + * + * @return ??? + */ +int sceGeListSync(int qid, int syncType); + +/** + * Wait for drawing to complete. + * + * @param syncType - Specifies the condition to wait on. One of ::PspGeSyncType. + * + * @return ??? + */ +int sceGeDrawSync(int syncType); + +/** + * Register callback handlers for the the Ge + * + * @param cb - Configured callback data structure + * @return The callback ID, < 0 on error + */ +int sceGeSetCallback(PspGeCallbackData *cb); + +/** + * Unregister the callback handlers + * + * @param cbid - The ID of the callbacks from sceGeSetCallback + * @return < 0 on error + */ +int sceGeUnsetCallback(int cbid); + +#ifdef __cplusplus +} +#endif + +#endif /* __GE_H__ */ diff --git a/src/ge/sceGe_driver.S b/src/ge/sceGe_driver.S new file mode 100644 index 00000000..f7ee3fca --- /dev/null +++ b/src/ge/sceGe_driver.S @@ -0,0 +1,76 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceGe_driver_0000 + IMPORT_START "sceGe_driver",0x00010000 +#endif +#ifdef F_sceGe_driver_0001 + IMPORT_FUNC "sceGe_driver",0x71FCD1D6,sceGeInit +#endif +#ifdef F_sceGe_driver_0002 + IMPORT_FUNC "sceGe_driver",0x9F2C2948,sceGeEnd +#endif +#ifdef F_sceGe_driver_0003 + IMPORT_FUNC "sceGe_driver",0x8F185DF7,sceGeEdramInit +#endif +#ifdef F_sceGe_driver_0004 + IMPORT_FUNC "sceGe_driver",0x1F6752AD,sceGeEdramGetSize +#endif +#ifdef F_sceGe_driver_0005 + IMPORT_FUNC "sceGe_driver",0xE47E40E4,sceGeEdramGetAddr +#endif +#ifdef F_sceGe_driver_0006 + IMPORT_FUNC "sceGe_driver",0xB77905EA,sceGeEdramSetAddrTranslation +#endif +#ifdef F_sceGe_driver_0007 + IMPORT_FUNC "sceGe_driver",0xB415364D,sceGeGetReg +#endif +#ifdef F_sceGe_driver_0008 + IMPORT_FUNC "sceGe_driver",0xDC93CFEF,sceGeGetCmd +#endif +#ifdef F_sceGe_driver_0009 + IMPORT_FUNC "sceGe_driver",0x57C8945B,sceGeGetMtx +#endif +#ifdef F_sceGe_driver_0010 + IMPORT_FUNC "sceGe_driver",0x438A385A,sceGeSaveContext +#endif +#ifdef F_sceGe_driver_0011 + IMPORT_FUNC "sceGe_driver",0x0BF608FB,sceGeRestoreContext +#endif +#ifdef F_sceGe_driver_0012 + IMPORT_FUNC "sceGe_driver",0xAB49E76A,sceGeListEnQueue +#endif +#ifdef F_sceGe_driver_0013 + IMPORT_FUNC "sceGe_driver",0x1C0D95A6,sceGeListEnQueueHead +#endif +#ifdef F_sceGe_driver_0014 + IMPORT_FUNC "sceGe_driver",0x5FB86AB0,sceGeListDeQueue +#endif +#ifdef F_sceGe_driver_0015 + IMPORT_FUNC "sceGe_driver",0xE0D68148,sceGeListUpdateStallAddr +#endif +#ifdef F_sceGe_driver_0016 + IMPORT_FUNC "sceGe_driver",0x03444EB4,sceGeListSync +#endif +#ifdef F_sceGe_driver_0017 + IMPORT_FUNC "sceGe_driver",0xB287BD61,sceGeDrawSync +#endif +#ifdef F_sceGe_driver_0018 + IMPORT_FUNC "sceGe_driver",0xB448EC0D,sceGeBreak +#endif +#ifdef F_sceGe_driver_0019 + IMPORT_FUNC "sceGe_driver",0x4C06E472,sceGeContinue +#endif +#ifdef F_sceGe_driver_0020 + IMPORT_FUNC "sceGe_driver",0xA4FC06A4,sceGeSetCallback +#endif +#ifdef F_sceGe_driver_0021 + IMPORT_FUNC "sceGe_driver",0x05DB22CE,sceGeUnsetCallback +#endif +#ifdef F_sceGe_driver_0022 + IMPORT_FUNC "sceGe_driver",0x9DA4A75F,sceGe_driver_9DA4A75F +#endif +#ifdef F_sceGe_driver_0023 + IMPORT_FUNC "sceGe_driver",0x114E1745,sceGe_driver_114E1745 +#endif diff --git a/src/ge/sceGe_user.S b/src/ge/sceGe_user.S new file mode 100644 index 00000000..8487a460 --- /dev/null +++ b/src/ge/sceGe_user.S @@ -0,0 +1,58 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceGe_user_0000 + IMPORT_START "sceGe_user",0x40010000 +#endif +#ifdef F_sceGe_user_0001 + IMPORT_FUNC "sceGe_user",0x1F6752AD,sceGeEdramGetSize +#endif +#ifdef F_sceGe_user_0002 + IMPORT_FUNC "sceGe_user",0xE47E40E4,sceGeEdramGetAddr +#endif +#ifdef F_sceGe_user_0003 + IMPORT_FUNC "sceGe_user",0xB77905EA,sceGeEdramSetAddrTranslation +#endif +#ifdef F_sceGe_user_0004 + IMPORT_FUNC "sceGe_user",0xDC93CFEF,sceGeGetCmd +#endif +#ifdef F_sceGe_user_0005 + IMPORT_FUNC "sceGe_user",0x57C8945B,sceGeGetMtx +#endif +#ifdef F_sceGe_user_0006 + IMPORT_FUNC "sceGe_user",0x438A385A,sceGeSaveContext +#endif +#ifdef F_sceGe_user_0007 + IMPORT_FUNC "sceGe_user",0x0BF608FB,sceGeRestoreContext +#endif +#ifdef F_sceGe_user_0008 + IMPORT_FUNC "sceGe_user",0xAB49E76A,sceGeListEnQueue +#endif +#ifdef F_sceGe_user_0009 + IMPORT_FUNC "sceGe_user",0x1C0D95A6,sceGeListEnQueueHead +#endif +#ifdef F_sceGe_user_0010 + IMPORT_FUNC "sceGe_user",0x5FB86AB0,sceGeListDeQueue +#endif +#ifdef F_sceGe_user_0011 + IMPORT_FUNC "sceGe_user",0xE0D68148,sceGeListUpdateStallAddr +#endif +#ifdef F_sceGe_user_0012 + IMPORT_FUNC "sceGe_user",0x03444EB4,sceGeListSync +#endif +#ifdef F_sceGe_user_0013 + IMPORT_FUNC "sceGe_user",0xB287BD61,sceGeDrawSync +#endif +#ifdef F_sceGe_user_0014 + IMPORT_FUNC "sceGe_user",0xB448EC0D,sceGeBreak +#endif +#ifdef F_sceGe_user_0015 + IMPORT_FUNC "sceGe_user",0x4C06E472,sceGeContinue +#endif +#ifdef F_sceGe_user_0016 + IMPORT_FUNC "sceGe_user",0xA4FC06A4,sceGeSetCallback +#endif +#ifdef F_sceGe_user_0017 + IMPORT_FUNC "sceGe_user",0x05DB22CE,sceGeUnsetCallback +#endif diff --git a/src/gu/Makefile.am b/src/gu/Makefile.am new file mode 100644 index 00000000..af0f7c8e --- /dev/null +++ b/src/gu/Makefile.am @@ -0,0 +1,36 @@ + +libdir = @PSPSDK_LIBDIR@ + +CC = @PSP_CC@ +CCAS = $(CC) +AR = @PSP_AR@ +RANLIB = @PSP_RANLIB@ + +INCLUDES = -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel -I$(top_srcdir)/src/display -I$(top_srcdir)/src/ge -I$(top_srcdir)/src/user -I$(top_srcdir)/src/debug +CFLAGS = @PSPSDK_CFLAGS@ +CCASFLAGS = $(CFLAGS) $(INCLUDES) + +libpspguincludedir = @PSPSDK_INCLUDEDIR@ +libpspguinclude_HEADERS = pspgu.h + +lib_LIBRARIES = libpspgu.a + +noinst_HEADERS = guInternal.h + +libpspgu_a_SOURCES = callbackFin.c callbackSig.c guInternal.c resetValues.c sceGuAlphaFunc.c sceGuAmbient.c \ + sceGuAmbientColor.c sceGuBeginObject.c sceGuBlendFunc.c sceGuBoneMatrix.c sceGuBreak.c sceGuCallList.c \ + sceGuCallMode.c sceGuCheckList.c sceGuClear.c sceGuClearColor.c sceGuClearDepth.c sceGuClearStencil.c \ + sceGuClutLoad.c sceGuClutMode.c sceGuColor.c sceGuColorFunc.c sceGuColorMaterial.c sceGuContinue.c \ + sceGuCopyImage.c sceGuDepthBuffer.c sceGuDepthFunc.c sceGuDepthMask.c sceGuDepthOffset.c \ + sceGuDepthRange.c sceGuDisable.c sceGuDispBuffer.c sceGuDisplay.c sceGuDrawArray.c sceGuDrawArrayN.c \ + sceGuDrawBezier.c sceGuDrawBuffer.c sceGuDrawBufferList.c sceGuDrawSpline.c sceGuEnable.c sceGuEndObject.c \ + sceGuFinish.c sceGuFog.c sceGuFrontFace.c sceGuGetAllStatus.c sceGuGetMemory.c sceGuGetStatus.c sceGuInit.c \ + sceGuLight.c sceGuLightAtt.c sceGuLightColor.c sceGuLightMode.c sceGuLightSpot.c sceGuLogicalOp.c \ + sceGuMaterial.c sceGuModelColor.c sceGuMorphWeight.c sceGuOffset.c sceGuPatchDivide.c sceGuPatchFrontFace.c \ + sceGuPatchPrim.c sceGuPixelMask.c sceGuScissor.c sceGuSendCommandf.c sceGuSendCommandi.c sceGuSendList.c \ + sceGuSetAllStatus.c sceGuSetCallback.c sceGuSetDither.c sceGuSetMatrix.c sceGuSetStatus.c sceGuShadeModel.c \ + sceGuSignal.c sceGuSpecular.c sceGuStart.c sceGuStencilFunc.c sceGuStencilOp.c \ + sceGuSwapBuffers.c sceGuSync.c sceGuTerm.c sceGuTexEnvColor.c sceGuTexFilter.c sceGuTexFlush.c sceGuTexFunc.c \ + sceGuTexImage.c sceGuTexLevelMode.c sceGuTexMapMode.c sceGuTexMode.c sceGuTexOffset.c sceGuTexProjMapMode.c \ + sceGuTexScale.c sceGuTexSlope.c sceGuTexSync.c sceGuTexWrap.c sceGuViewport.c sendCommand.c + diff --git a/src/gu/callbackFin.c b/src/gu/callbackFin.c new file mode 100644 index 00000000..6a270588 --- /dev/null +++ b/src/gu/callbackFin.c @@ -0,0 +1,16 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void callbackFin(int id, void* arg) +{ + GuSettings* settings = (GuSettings*)arg; + if (settings->fin) + settings->fin(id & 0xffff); +} diff --git a/src/gu/callbackSig.c b/src/gu/callbackSig.c new file mode 100644 index 00000000..a461bfa6 --- /dev/null +++ b/src/gu/callbackSig.c @@ -0,0 +1,23 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +#include + +void callbackSig(int id, void* arg) +{ + GuSettings* settings = (GuSettings*)arg; + + settings->signal_history[(settings->signal_offset++) & 15] = id & 0xffff; + + if (settings->sig) + settings->sig(id & 0xffff); + + sceKernelSetEventFlag(settings->kernel_event_flag,1); +} diff --git a/src/gu/doc/commands.txt b/src/gu/doc/commands.txt new file mode 100644 index 00000000..bd2b8a30 --- /dev/null +++ b/src/gu/doc/commands.txt @@ -0,0 +1,999 @@ +GE Command Format: + +Each command word is divided into two parts, a 8-bit command and a 24-bit +argument. The command is in the upper part of the word, and the argument +in the lower. The argument can be either integer of a special kind of float +that the GE supports (described below). + +GE Floats: + +Floats processed in the command-stream are 24 bits instead of 32 that are +used by the CPU. Conversion from 32 to 24 bits is done by shifting the +value down 8 bits, losing the least significant bits of the mantissa. + +Pointers: + +Some pointers use a shared register when loading addresses called BASE. This +register must be written BEFORE you write to the designated register. All +these registers are marked with (BASE) after the summary. + +Other pointers only use 28 bits of information, and their top bits are +referred to as the '4 most significant bits' in pointer, which reflects +bits 24-27, not 28-31 which could perhaps be believed from common +terminology. + +Enabling Registers: + +Any command or bit that has 'Enable' in the name implies that setting the +first bit (or the bit itself) enables the feature, and no ON/OFF-states +are documented. + +DISCLAIMER: Names and bitsets are all derived from reverse engineering, +available PS2 documentation and educated guesses. Nothing has been derived +using illegal methods. + +Dec Hex Name Description +--- --- ---- ----------- + +0 00 NOP No Operation + +1 01 VADDR Vertex Address (BASE) + 0-23: 24 least significant bits of pointer + +2 02 IADDR Index Address (BASE) + 0-23: 24 least significant bits of pointer + +4 04 PRIM Primitive Kick + 0-15: Number of vertices to kick (0-65535) + 16-18: Primitive Type + 000: Points + 001: Lines + 010: Line Strips + 011: Triangles + 100: Triangle Strips + 101: Triangle Fans + 110: Sprites (2D Rectangles) + +5 05 BEZIER Bezier Patch Kick + 0-7: U Count + 8-15: V Count + +6 06 SPLINE Spline Surface Kick + 0-7: U Count + 8-15: V Count + 16-17: U Edges + 00: Close/Close + 01: Open/Close + 10: Close/Open + 11: Open/Open + 18-19: V Edges + 00: Close/Close + 01: Open/Close + 10: Close/Open + 11: Open/Open + +7 07 BBOX Bounding Box + 0-15: Number of vertices to test for conditional rendering (0-65535) + +8 08 JUMP Jump To New Address (BASE) + 0-23: 24 least significant bits of pointer + +9 09 BJUMP Conditional Jump (BASE) + 0-23: 24 least significant bits of pointer + +10 0A CALL Call Address (BASE) + 0-23: 24 least significant bits of pointer + +11 0B RET Return From Call + +12 0C END Stop execution + +14 0E SIGNAL Raise Signal Interrupt + 0-15: Argument to pass to signal handler + 16-23: Signal index to trigger + +15 0F FINISH Complete rendering + 0-15: Finish signal argument + +16 10 BASE Base Address Register + 16-20: 4 most significant bits for address (28 bits total) + +18 12 VTYPE Vertex Type + 0-1: Texture Format (2 values ST/UV) + 00: Not present in vertex + 01: 8-bit fixed + 10: 16-bit fixed + 11: 32-bit floats + 2-4: Color Format (1 value) + 000: Not present in vertex + 100: 16-bit BGR-5650 + 101: 16-bit ABGR-5551 + 110: 16-bit ABGR-4444 + 111: 32-bit ABGR-8888 + 5-6: Normal Format (3 values XYZ) + 00: Not present in vertex + 01: 8-bit fixed + 10: 16-bit fixed + 11: 32-bit floats + 7-8: Position Format (3 values XYZ) + 00: Not present in vertex + 01: 8-bit fixed + 10: 16-bit fixed + 11: 32-bit floats + 9-10: Weight Format + 00: Not present in vertex + 01: 8-bit fixed + 10: 16-bit fixed + 11: 32-bit floats + 11-12: Index Format + 00: Not using indices + 01: 8-bit + 10: 16-bit + 14-16: Number of weights (Skinning) + 000-111: 1-8 weights + 18-20: Number of vertices (Morphing) + 000-111: 1-8 vertices + 23: Bypass Transform Pipeline + 0: Transformed Coordinates + 1: Raw Coordinates + +19 13 ??? Offset Address (BASE) + +20 14 ??? Origin Address (BASE) + +21 15 REGION1 Draw Region Start + 0-9: X Start + 10-19: Y Start + +22 16 REGION2 Draw Region End + 0-9: X End ((X + Width)-1) + 10-19: Y End ((Y+Height)-1) + +23 17 LTE Lighting Enable + +24 18 LTE0 Light Enable 0 + +25 19 LTE1 Light Enable 1 + +26 1A LTE2 Light Enable 2 + +27 1B LTE3 Light Enable 3 + +28 1C CPE Clip Plane Enable + +29 1D BCE Backface Culling Enable + +30 1E TME Texture Mapping Enable + +31 1F FGE Fog Enable + +32 20 DTE Dither Enable + +33 21 ABE Alpha Blend Enable + +34 22 ATE Alpha Test Enable + +35 23 ZTE Depth Test Enable + +36 24 STE Stencil Test Enable + +37 25 AAE Anti Aliasing Enable + +38 26 PCE Patch Cull Enable + +39 27 CTE Color Test Enable + +40 28 LOE Logical Operation Enable + +42 2A BOFS Bone Matrix Offset + 0-23: Bone Matrix Offset + Offset is in values, so each matrix is offset by 3*4 values + +43 2B BONE Bone Matrix Upload + 0-23: Matrix Value (GE Float) + Write 3x4 times to upload full bone matrix + +44 2C MW0 Morph Weight 0 + 0-23: Morph Value (GE Float) + +45 2D MW1 Morph Weight 1 + 0-23: Morph Value (GE Float) + +46 2E MW2 Morph Weight 2 + 0-23: Morph Value (GE Float) + +47 2F MW3 Morph Weight 3 + 0-23: Morph Value (GE Float) + +48 30 MW4 Morph Weight 4 + 0-23: Morph Value (GE Float) + +49 31 MW5 Morph Weight 5 + 0-23: Morph Value (GE Float) + +50 32 MW6 Morph Weight 6 + 0-23: Morph Value (GE Float) + +51 33 MW7 Morph Weight 7 + 0-23: Morph Value (GE Float) + +54 36 PSUB Patch Subdivision + 0-7: S Subdivision + 8-15: T Subdivision + +55 37 PPRIM Patch Primitive + 0-1: + 00: Triangles + 01: Lines + 10: Points + +56 38 PFACE Patch Front Face + 0: + 0: Clockwise + 1: Counter-Clockwise + +58 3A WMS World Matrix Select + +59 3B WORLD World Matrix Upload + 0-23: Matrix Value (GE Float) + Write 3*4 values for complete matrix + +60 3C VMS View Matrix Select + +61 3D VIEW View Matrix Upload + 0-23: Matrix Value (GE Float) + Write 3*4 values for complete matrix + +62 3E PMS Projection Matrix Select + +63 3F PROJ Projection Matrix Upload + 0-23: Matrix Value (GE Float) + Write 4*4 values for complete matrix + +64 40 TMS Texture Matrix Select + +65 41 TMATRIX Texture Matrix Upload + 0-23: Matrix Value + Write 3*4 values for complete matrix + +66 42 XSCALE Viewport Width Scale + 0-23: Scale Value (GE Float) + +67 43 YSCALE Viewport Height Scale + 0-23: Scale Value (GE Float) + +68 44 ZSCALE Depth Scale + 0-23: Scale Value (GE Float) + +69 45 XPOS Viewport X Position + 0-23: Offset Value (GE Float) + +70 46 YPOS Viewport Y Position + 0-23: Offset Value (GE Float) + +71 47 ZPOS Depth Position + 0-23: Offset Value (GE Float) + +72 48 USCALE Texture U Scale + 0-23: Scale Value (GE Float) + +73 49 USCALE Texture V Scale + 0-23: Scale Value (GE Float) + +74 4A OFFSET Texture U Offset + 0-23: Offset Value (GE Float) + +75 4B OFFSET Texture V Offset + 0-23: Offset Value (GE Float) + +76 4C OFFSETX Viewport X Offset + 0-23: X Offset (12.4 fixed) + +77 4D OFFSETY Viewport Y Offset + 0-23: Y Offset (12.4 fixed) + +80 50 SHADE Shade Model + 0: Shading type + 0: Flat + 1: Smooth + +81 51 RNORM Reverse Face Normals Enable + +83 53 CMAT Color Material + 0-2: Material flags (OR together) + 001: Ambient + 010: Diffuse + 100: Specular + +84 54 EMC Emissive Model Color + 0-7: Red Component + 8-15: Green Component + 16-23: Blue Component + +85 55 AMC Ambient Model Color + 0-7: Red Component + 8-15: Green Component + 16-23: Blue Component + +86 56 DMC Diffuse Model Color + 0-7: Red Component + 8-15: Green Component + 16-23: Blue Component + +87 57 SMC Specular Model Color + 0-7: Red Component + 8-15: Green Component + 16-23: Blue Component + +88 58 AMA Ambient Model Alpha + 0-7: Alpha Component + +91 5B SPOW Specular Power + 0-23: Power (GE Float) + +92 5C ALC Ambient Light Color + 0-7: Red Component + 8-15: Green Component + 16-23: Blue Component + +93 5D ALA Amibient Light Alpha + 0-7: Alpha Component + +94 5E LMODE Light Model + 0: Lighting model + 0: Single color + 1: Separate specular color + +95 5F LT0 Light Type 0 + 0-1: Light Components + 00: Ambient & Diffuse + 01: Diffuse & Specular + 10: Unknown (diffuse color, affected by specular power) + 8-9: Light Type + 00: Directional Light + 01: Point Light + 10: Spot Light + +96 60 LT1 Light Type 1 + 0-1: Light Components + 00: Ambient & Diffuse + 01: Diffuse & Specular + 10: Unknown (diffuse color, affected by specular power) + 8-9: Light Type + 00: Directional Light + 01: Point Light + 10: Spot Light + +97 61 LT2 Light Type 2 + 0-1: Light Components + 00: Ambient & Diffuse + 01: Diffuse & Specular + 10: Unknown (diffuse color, affected by specular power) + 8-9: Light Type + 00: Directional Light + 01: Point Light + 10: Spot Light + +98 62 LT3 Light Type 3 + 0-1: Light Components + 00: Ambient & Diffuse + 01: Diffuse & Specular + 10: Unknown (diffuse color, affected by specular power) + 8-9: Light Type + 00: Directional Light + 01: Point Light + 10: Spot Light + +99 63 LXP0 Light X Position 0 + 0-23: Vector Component (GE Float) + +100 64 LYP0 Light Y Position 0 + 0-23: Vector Component (GE Float) + +101 65 LZP0 Light Z Position 0 + 0-23: Vector Component (GE Float) + +102 66 LXP1 Light X Position 1 + 0-23: Vector Component (GE Float) + +103 67 LYP1 Light Y Position 1 + 0-23: Vector Component (GE Float) + +104 68 LZP1 Light Z Position 1 + 0-23: Vector Component (GE Float) + +105 69 LXP2 Light X Position 2 + 0-23: Vector Component (GE Float) + +106 6A LYP2 Light Y Position 2 + 0-23: Vector Component (GE Float) + +107 6B LZP2 Light Z Position 2 + 0-23: Vector Component (GE Float) + +108 6C LXP3 Light X Position 3 + 0-23: Vector Component (GE Float) + +109 6D LYP3 Light Y Position 3 + 0-23: Vector Component (GE Float) + +110 6E LZP3 Light Z Position 3 + 0-23: Vector Component (GE Float) + +111 6F LXD0 Light X Direction 0 + 0-23: Vector Component (GE Float) + +112 70 LYD0 Light Y Direction 0 + 0-23: Vector Component (GE Float) + +113 71 LZD0 Light Z Direction 0 + 0-23: Vector Component (GE Float) + +114 72 LXD0 Light X Direction 1 + 0-23: Vector Component (GE Float) + +115 73 LYD0 Light Y Direction 1 + 0-23: Vector Component (GE Float) + +116 74 LZD0 Light Z Direction 1 + 0-23: Vector Component (GE Float) + +117 75 LXD0 Light X Direction 2 + 0-23: Vector Component (GE Float) + +118 76 LYD0 Light Y Direction 2 + 0-23: Vector Component (GE Float) + +119 77 LZD0 Light Z Direction 2 + 0-23: Vector Component (GE Float) + +120 78 LXD0 Light X Direction 3 + 0-23: Vector Component (GE Float) + +121 79 LYD0 Light Y Direction 3 + 0-23: Vector Component (GE Float) + +122 7A LZD0 Light Z Direction 3 + 0-23: Vector Component (GE Float) + +123 7B LCA0 Light Constant Attenuation 0 + 0-23: Attenuation Factor (GE Float) + +124 7C LLA0 Light Linear Attenuation 0 + 0-23: Attenuation Factor (GE Float) + +125 7D LQA0 Light Quadratic Attenuation 0 + 0-23: Attenuation Factor (GE Float) + +126 7E LCA1 Light Constant Attenuation 1 + 0-23: Attenuation Factor (GE Float) + +127 7F LLA1 Light Linear Attenuation 1 + 0-23: Attenuation Factor (GE Float) + +128 80 LQA1 Light Quadratic Attenuation 1 + 0-23: Attenuation Factor (GE Float) + +129 81 LCA2 Light Constant Attenuation 2 + 0-23: Attenuation Factor (GE Float) + +130 82 LLA2 Light Linear Attenuation 2 + 0-23: Attenuation Factor (GE Float) + +131 83 LQA2 Light Quadratic Attenuation 2 + 0-23: Attenuation Factor (GE Float) + +132 84 LCA3 Light Constant Attenuation 3 + 0-23: Attenuation Factor (GE Float) + +133 85 LLA3 Light Linear Attenuation 3 + 0-23: Attenuation Factor (GE Float) + +134 86 LQA3 Light Quadratic Attenuation 3 + 0-23: Attenuation Factor (GE Float) + +135 87 ??? Spot light 0 exponent + 0-23: Spotlight exponent + +136 88 ??? Spot light 1 exponent + 0-23: Spotlight exponent + +137 89 ??? Spot light 2 exponent + 0-23: Spotlight exponent + +139 8A ??? Spot light 3 exponent + 0-23: Spotlight exponent + +139 8B ??? Spot light 0 cutoff + 0-23: Spotlight cutoff angle (cosine of angle) + +140 8C ??? Spot light 1 cutoff + 0-23: Spotlight cutoff angle (cosine of angle) + +141 8D ??? Spot light 2 cutoff + 0-23: Spotlight cutoff angle (cosine of angle) + +142 8E ??? Spot light 3 cutoff + 0-23: Spotlight cutoff angle (cosine of angle) + +143 8F ALC0 Ambient Light Color 0 + 0-7: Red Component + 8-15: Green Component + 16-23: Blue Component + +144 90 DLC0 Diffuse Light Color 0 + 0-7: Red Component + 8-15: Green Component + 16-23: Blue Component + +145 91 SLC0 Specular Light Color 0 + 0-7: Red Component + 8-15: Green Component + 16-23: Blue Component + +146 92 ALC1 Ambient Light Color 1 + 0-7: Red Component + 8-15: Green Component + 16-23: Blue Component + +147 93 DLC1 Diffuse Light Color 1 + 0-7: Red Component + 8-15: Green Component + 16-23: Blue Component + +148 94 SLC1 Specular Light Color 1 + 0-7: Red Component + 8-15: Green Component + 16-23: Blue Component + +149 95 ALC2 Ambient Light Color 2 + 0-7: Red Component + 8-15: Green Component + 16-23: Blue Component + +150 96 DLC2 Diffuse Light Color 2 + 0-7: Red Component + 8-15: Green Component + 16-23: Blue Component + +151 97 SLC2 Specular Light Color 2 + 0-7: Red Component + 8-15: Green Component + 16-23: Blue Component + +152 98 ALC3 Ambient Light Color 3 + 0-7: Red Component + 8-15: Green Component + 16-23: Blue Component + +153 99 DLC3 Diffuse Light Color 3 + 0-7: Red Component + 8-15: Green Component + 16-23: Blue Component + +154 9A SLC3 Specular Light Color 3 + 0-7: Red Component + 8-15: Green Component + 16-23: Blue Component + +155 9B FFACE Front Face Culling Order + 0: Culling Order + 0: Clockwise primitives are visible + 1: Counter-clockwise primitives are visible + +156 9C FBP Frame Buffer Pointer + 0-23: 24 least significant bits of pointer (see FBW) + +157 9D FBW Frame Buffer Width + 0-15: Buffer width in pixels + 16-23: 8 most significant bits of pointer (see FBP) + +158 9E ZBP Depth Buffer Pointer + 0-23: 24 least significant bits of pointer (see ZBW) + +159 9F ZBW Depth Buffer Width + 0-15: Buffer width in pixels + 16-23: 8 most significant bits of pointer (see ZBP) + +160 A0 TBP0 Texture Buffer Pointer 0 + 0-23: 24 least significant bits of pointer (see TBW0) + +161 A1 TBP1 Texture Buffer Pointer 1 + 0-23: 24 least significant bits of pointer (see TBW1) + +162 A2 TBP2 Texture Buffer Pointer 2 + 0-23: 24 least significant bits of pointer (see TBW2) + +163 A3 TBP3 Texture Buffer Pointer 3 + 0-23: 24 least significant bits of pointer (see TBW3) + +164 A4 TBP4 Texture Buffer Pointer 4 + 0-23: 24 least significant bits of pointer (see TBW4) + +165 A5 TBP5 Texture Buffer Pointer 5 + 0-23: 24 least significant bits of pointer (see TBW5) + +166 A6 TBP6 Texture Buffer Pointer 6 + 0-23: 24 least significant bits of pointer (see TBW6) + +167 A7 TBP7 Texture Buffer Pointer 7 + 0-23: 24 least significant bits of pointer (see TBW7) + +168 A8 TBW0 Texture Buffer Width 0 + 0-15: Buffer width in pixels + 16-20: 4 most significant bits of pointer (see TBP0) + +169 A9 TBW1 Texture Buffer Width 1 + 0-15: Buffer width in pixels + 16-20: 4 most significant bits of pointer (see TBP1) + +170 AA TBW2 Texture Buffer Width 2 + 0-15: Buffer width in pixels + 16-20: 4 most significant bits of pointer (see TBP2) + +171 AB TBW3 Texture Buffer Width 3 + 0-15: Buffer width in pixels + 16-20: 4 most significant bits of pointer (see TBP3) + +172 AC TBW4 Texture Buffer Width 4 + 0-15: Buffer width in pixels + 16-20: 4 most significant bits of pointer (see TBP4) + +173 AD TBW5 Texture Buffer Width 5 + 0-15: Buffer width in pixels + 16-20: 4 most significant bits of pointer (see TBP5) + +174 AE TBW6 Texture Buffer Width 6 + 0-15: Buffer width in pixels + 16-20: 4 most significant bits of pointer (see TBP6) + +175 AF TBW7 Texture Buffer Width 7 + 0-15: Buffer width in pixels + 16-20: 4 most significant bits of pointer (see TBP7) + +176 B0 CBP CLUT Buffer Pointer + 0-23: 24 least significant bits of pointer (see CBPH) + +177 B1 CBPH CLUT Buffer Pointer H + 16-20: 4 most significant bits of pointer (see CBP) + +178 B2 TRXSBP Transmission Source Buffer Pointer + 0-23: 24 least significant bits of pointer (see TRXSBW) + +179 B3 TRXSBW Transmission Source Buffer Width + 0-15: Source Buffer Width + 16-23: 8 most significant bits of pointer (see TRXSBP) + +180 B4 TRXDBP Transmission Destination Buffer Pointer + 0-23: 24 least significant bits of pointer (see TRXDBW) + +181 B5 TRXDBW Transmission Destination Buffer Width + 0-15: Destination Buffer Width + 16-23: 8 most significant bits of pointer (see TRXDBP) + +184 B8 TSIZE0 Texture Size Level 0 + 0-7: Width = 2^TW + 8-15: Height = 2^TH + +185 B9 TSIZE1 Texture Size Level 1 + 0-7: Width = 2^TW + 8-15: Height = 2^TH + +186 BA TSIZE2 Texture Size Level 2 + 0-7: Width = 2^TW + 8-15: Height = 2^TH + +187 BB TSIZE3 Texture Size Level 3 + 0-7: Width = 2^TW + 8-15: Height = 2^TH + +188 BC TSIZE4 Texture Size Level 4 + 0-7: Width = 2^TW + 8-15: Height = 2^TH + +189 BD TSIZE5 Texture Size Level 5 + 0-7: Width = 2^TW + 8-15: Height = 2^TH + +190 BE TSIZE6 Texture Size Level 6 + 0-7: Width = 2^TW + 8-15: Height = 2^TH + +191 BF TSIZE7 Texture Size Level 7 + 0-7: Width = 2^TW + 8-15: Height = 2^TH + +192 C0 TMAP Texture Projection Map Mode + Texture Map Mode + 0-1: Texture Map Mode + 00: Texture Coordinates (UV) + 01: Texture Matrix + 10: Environment Map + 8-9: Texture Projection Map Mode + 00: Position + 01: Texture Coordinates + 10: Normalized Normal + 11: Normal + +193 C1 Texture Environment Map Matrix + 0-1: 1st Column for matrix + 8-9: 2nd column for matrix + +194 C2 TMODE Texture Mode + 0: Swizzle Enable + 8-15: ??? + 16-20: Maximum mipmap level + +195 C3 TPSM Texture Pixel Storage Mode + 0-23: Pixel Storage Mode + 0: 16-bit BGR 5650 + 1: 16-bit ABGR 5551 + 2: 16-bit ABGR 4444 + 3: 32-bit ABGR 8888 + 4: 4-bit indexed + 5: 8-bit indexed + 6: 16-bit indexed + 7: 32-bit indexed + 8: DXT1 + 9: DXT3 + 10: DXT5 + +196 C4 CLOAD CLUT Load + 0-23: Number of colors divided by 8 + +197 C5 CMODE CLUT Mode + 0-1: CLUT Pixel Format + 00: 16-bit BGR 5650 + 01: 16-bit ABGR 5551 + 10: 16-bit ABGR 4444 + 11: 32-bit ABGR 8888 + 2-7: ??? + 8-15: mask + 16-23: ??? + +198 C6 TFLT Texture Filter + 0-2: Minifying filter + 8-10: Magnifying filter + 000: Nearest + 001: Linear + 100: Nearest; Mipmap Nearest + 101: Linear; Mipmap Nearest + 110: Nearest; Mipmap Linear + 111: Linear; Mipmap Linear + +199 C7 TWRAP Texture Wrapping + 0: U Wrap Mode + 8: V Wrap Mode + 0: Repeat + 1: Clamp + +200 C8 TBIAS Texture Level Bias (???) + 0-15: ??? + 16-23: Mipmap bias (signed) + +201 C9 TFUNC Texture Function + 0-2: Texture Effect + 000: Modulate + 001: Decal + 010: Blend + 011: Replace + 100: Add + 8: Texture Color Component + 0: Texture alpha is ignored + 1: Texture alpha is read + 16: Fragment Double Enable + 0: Fragment color is untouched + 1: Fragment color is doubled + +202 CA TEC Texture Environment Color + 0-7: Red Component + 8-15: Green Component + 16-23: Blue Component + +203 CB TFLUSH Texture Flush + Invalidate texture cache on texture change + +204 CC TSYNC Texture Sync + Sync with texture transfer (see TRXKICK) + +205 CD FFAR Fog Far (???) + +206 CE FDIST Fog Range + 0-23: Range (GE Float) + +207 CF FCOL Fog Color + 0-7: Red Component + 8-15: Green Component + 16-23: Blue Component + +208 D0 TSLOPE Texture Slope + 0-23: Slope (GE Float) + +210 D2 PSM Frame Buffer Pixel Storage Mode + 0-1: Pixel Storage Mode + 00: 16-bit BGR 5650 + 01: 16-bit ABGR 5551 + 10: 16-bit ABGR 4444 + 11: 32-bit ABGR 8888 + +211 D3 CLEAR Clear Flags + 0: Clear enable + 8-11: Clear flags (OR together) + 001: Clear Color Buffer + 010: Clear Stencil/Alpha Buffer + 100: Clear Depth Buffer + +212 D4 SCISSOR1 Scissor Region Start + 0-9: X Start + 10-19: Y Start + +213 D5 SCISSOR2 Scissor Region End + 0-9: X End + 10-19: Y End + +214 D6 NEARZ Near Depth Range + 0-15: Depth Value + +215 D7 FARZ Far Depth Range + 0-15: Depth Value + +216 D8 CTST Color Test Function + 0-1: Color Function + 00: Never pass pixel + 01: Always pass pixel + 10: Pass pixel if color matches + 11: Pass pixel if color differs + +217 D9 CREF Color Reference + 0-23: Color Reference Value + +218 DA CMSK Color Mask + 0-23: Color Mask + +219 DB ATST Alpha Test + 0-2: Alpha Test Function + 000: Never pass pixel + 001: Always pass pixel + 010: Pass pixel if match + 011: Pass pixel if difference + 100: Pass pixel if less + 101: Pass pixel if less or equal + 110: Pass pixel if greater + 111: Pass pixel if greater or equal + 8-15: Alpha Reference Value + 16-23: Alpha Mask + +220 DC STST Stencil Test + 0-2: Stencil Function + 000: Never pass stencil test + 001: Always pass stencil test + 010: Pass test if match + 011: Pass test if difference + 100: Pass test if less + 101: Pass test if less or equal + 110: Pass test if greater + 111: Pass test if greater or equal + 8-15: Stencil Reference Value + 16-23: Stencil Mask + +221 DD SOP Stencil Operations + 0-3: Pass Op + 8-11: Fail Op + 16-18: Zfail Op + 000: Keep stencil value + 001: Zero stencil value + 010: Replace stencil value + 011: Invert stencil value + 100: Increment stencil value + 101: Decrement stencil value + +222 DE ZTST Depth Test Function + 0-2: Function + 000: Never pass pixel + 001: Always pass pixel + 010: Pass pixel when depth is equal + 011: Pass pixel when depth is not equal + 100: Pass pixel when depth is less + 101: Pass pixel when depth is less or equal + 110: Pass pixel when depth is greater + 111: Pass pixel when depth is greater or equal + +223 DF ALPHA Alpha Blend + 0-3: Blend Operation + 000: Add + 001: Subtract + 010: Reverse Subtract + 011: Minimum Value + 100: Maximum Value + 101: Absolute Value + 4-7: Source Function + 8-11: Destination Function + 0000: Source Color + 0001: One Minus Source Color + 0010: Source Alpha + 0011: One Minus Source Alpha + 0100: Destination Color + 0101: One Minus Destination Color + 0110: Destination Alpha + 0111: One Minus Destination Alpha + 1010: Fix + +224 E0 SFIX Source Fix Color + 0-7: Red Component + 8-15: Green Component + 16-23: Blue Component + +225 E1 DFIX Destination Fix Color + 0-7: Red Component + 8-15: Green Component + 16-23: Blue Component + +226 E2 DTH0 Dither Matrix Row 0 + 0-3: Column 0 + 4-7: Column 1 + 8-11: Column 2 + 12-15: Column 3 + +227 E3 DTH1 Dither Matrix Row 1 + 0-3: Column 0 + 4-7: Column 1 + 8-11: Column 2 + 12-15: Column 3 + +228 E4 DTH2 Dither Matrix Row 2 + 0-3: Column 0 + 4-7: Column 1 + 8-11: Column 2 + 12-15: Column 3 + +229 E5 DTH3 Dither Matrix Row 3 + 0-3: Column 0 + 4-7: Column 1 + 8-11: Column 2 + 12-15: Column 3 + +230 E6 LOP Logical Operation + 0-3: Logic Op + 0000: Clear + 0001: And + 0010: Reverse And + 0011: Copy + 0100: Inverted And + 0101: No Operation + 0110: Exclusive Or + 0111: Or + 1000: Negated Or + 1001: Equivalence + 1010: Inverted + 1011: Reverse Or + 1100: Inverted Copy + 1101: Inverted Or + 1110: Negated And + 1111: Set + +231 E7 ZMSK Depth Mask + 0-15: Depth Write Mask + +232 E8 PMSKC Pixel Mask Color + 0-7: Red Write Mask + 8-15: Green Write Mask + 16-23: Blue Write Mask + +233 E9 PMSKA Pixel Mask Alpha + 0-7: Alpha Write Mask + +234 EA TRXKICK Transmission Kick + 0: + 0: 16-bit texel size + 1: 32-bit texel size + +235 EB TRXSPOS Transfer Source Position + 0-9: X Position + 10-19: Y Position + +236 EC TRXDPOS Transfer Destination Position + 0-9: X Position + 10-19: Y Position + +237 EE TRXSIZE Transfer Size + 0-9: Width = Transfer Width-1 + 10-19: Height = Transfer Height-1 diff --git a/src/gu/guInternal.c b/src/gu/guInternal.c new file mode 100644 index 00000000..fc3bb813 --- /dev/null +++ b/src/gu/guInternal.c @@ -0,0 +1,55 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +unsigned int gu_current_frame; +GuContext gu_contexts[3]; +int ge_list_executed[2]; +void* ge_edram_address; +GuSettings gu_settings; +GuDisplayList* gu_list; +int gu_curr_context; +int gu_init; +int gu_display_on; +int gu_call_mode; +int gu_states; +GuDrawBuffer gu_draw_buffer; +unsigned int* gu_object_stack[32]; +int gu_object_stack_depth; + +GuLightSettings light_settings[4] = +{ + { + 0x18, 0x5f, 0x63, 0x64, + 0x65, 0x6f, 0x70, 0x71, + 0x8f, 0x90, 0x91, 0x7b, + 0x7c, 0x7d, 0x87, 0x8b + }, + + { + 0x19, 0x60, 0x66, 0x67, + 0x68, 0x72, 0x73, 0x74, + 0x92, 0x93, 0x94, 0x7e, + 0x7f, 0x80, 0x88, 0x8c + }, + + { + 0x1a, 0x61, 0x69, 0x6a, + 0x6b, 0x75, 0x76, 0x77, + 0x95, 0x96, 0x97, 0x81, + 0x82, 0x83, 0x89, 0x8d + }, + + { + 0x1b, 0x62, 0x6c, 0x6d, + 0x6e, 0x78, 0x79, 0x7a, + 0x98, 0x99, 0x9a, 0x84, + 0x85, 0x86, 0x8a, 0x8e + } +}; diff --git a/src/gu/guInternal.h b/src/gu/guInternal.h new file mode 100644 index 00000000..6b3f422a --- /dev/null +++ b/src/gu/guInternal.h @@ -0,0 +1,125 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#ifndef __guInternal_h__ +#define __guInternal_h__ + +#include "pspgu.h" + +typedef void (*GuCallback)(int); + +typedef struct +{ + GuCallback sig; + GuCallback fin; + short signal_history[16]; + int signal_offset; + int kernel_event_flag; + int ge_callback_id; + + GuSwapBuffersCallback swapBuffersCallback; + int swapBuffersBehaviour; +} GuSettings; + +typedef struct +{ + unsigned int* start; + unsigned int* current; + int parent_context; +} GuDisplayList; + +typedef struct +{ + GuDisplayList list; + int scissor_enable; + int scissor_start[2]; + int scissor_end[2]; + int near_plane; + int far_plane; + int depth_offset; + int fragment_2x; + int texture_function; + int texture_proj_map_mode; + int texture_map_mode; + int sprite_mode[4]; + unsigned int clear_color; + unsigned int clear_stencil; + unsigned int clear_depth; + int texture_mode; +} GuContext; + +typedef struct +{ + int pixel_size; + int frame_width; + void* frame_buffer; + void* disp_buffer; + void* depth_buffer; + int depth_width; + int width; + int height; +} GuDrawBuffer; + +typedef struct +{ + /* row 0 */ + + unsigned char enable; // Light enable + unsigned char type; // Light type + unsigned char xpos; // X position + unsigned char ypos; // Y position + + /* row 1 */ + + unsigned char zpos; // Z position + unsigned char xdir; // X direction + unsigned char ydir; // Y direction + unsigned char zdir; // Z direction + + /* row 2 */ + + unsigned char ambient; // Ambient color + unsigned char diffuse; // Diffuse color + unsigned char specular; // Specular color + unsigned char constant; // Constant attenuation + + /* row 3 */ + + unsigned char linear; // Linear attenuation + unsigned char quadratic;// Quadratic attenuation + unsigned char exponent; // Light exponent + unsigned char cutoff; // Light cutoff +} GuLightSettings; + +extern unsigned int gu_current_frame; +extern GuContext gu_contexts[3]; +extern int ge_list_executed[2]; +extern void* ge_edram_address; +extern GuSettings gu_settings; +extern GuDisplayList* gu_list; +extern int gu_curr_context; +extern int gu_init; +extern int gu_display_on; +extern int gu_call_mode; +extern int gu_states; +extern GuDrawBuffer gu_draw_buffer; + +extern unsigned int* gu_object_stack[]; +extern int gu_object_stack_depth; + +extern GuLightSettings light_settings[4]; + +void sendCommandi(int cmd, int argument); +void sendCommandiStall(int cmd, int argument); +void sendCommandf(int cmd, float argument); + +void callbackSig(int id, void* arg); +void callbackFin(int id, void* arg); +void resetValues(); + +#endif diff --git a/src/gu/pspgu.h b/src/gu/pspgu.h new file mode 100644 index 00000000..5fffd208 --- /dev/null +++ b/src/gu/pspgu.h @@ -0,0 +1,1487 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#ifndef __pspgu_h__ +#define __pspgu_h__ + +#include +#include + +/** @defgroup GU Graphics Utility Library + * + */ + +#if defined(__cplusplus) +extern "C" { +#endif + +/* PI, float-sized */ +#define GU_PI (3.141593f) + +/* Boolean values for convenience */ +#define GU_FALSE (0) +#define GU_TRUE (1) + +/* Primitive types */ +#define GU_POINTS (0) +#define GU_LINES (1) +#define GU_LINE_STRIP (2) +#define GU_TRIANGLES (3) +#define GU_TRIANGLE_STRIP (4) +#define GU_TRIANGLE_FAN (5) +#define GU_SPRITES (6) + +/* States */ +#define GU_ALPHA_TEST (0) +#define GU_DEPTH_TEST (1) +#define GU_SCISSOR_TEST (2) +#define GU_STENCIL_TEST (3) +#define GU_BLEND (4) +#define GU_CULL_FACE (5) +#define GU_DITHER (6) +#define GU_FOG (7) +#define GU_CLIP_PLANES (8) +#define GU_TEXTURE_2D (9) +#define GU_LIGHTING (10) +#define GU_LIGHT0 (11) +#define GU_LIGHT1 (12) +#define GU_LIGHT2 (13) +#define GU_LIGHT3 (14) +#define GU_LINE_SMOOTH (15) +#define GU_PATCH_CULL_FACE (16) +#define GU_COLOR_TEST (17) +#define GU_COLOR_LOGIC_OP (18) +#define GU_FACE_NORMAL_REVERSE (19) +#define GU_PATCH_FACE (20) +#define GU_FRAGMENT_2X (21) + +/* Matrix modes */ +#define GU_PROJECTION (0) +#define GU_VIEW (1) +#define GU_MODEL (2) +#define GU_TEXTURE (3) + +/* Vertex Declarations Begin */ +#define GU_TEXTURE_SHIFT(n) ((n)<<0) +#define GU_TEXTURE_8BIT GU_TEXTURE_SHIFT(1) +#define GU_TEXTURE_16BIT GU_TEXTURE_SHIFT(2) +#define GU_TEXTURE_32BITF GU_TEXTURE_SHIFT(3) +#define GU_TEXTURE_BITS GU_TEXTURE_SHIFT(3) + +#define GU_COLOR_SHIFT(n) ((n)<<2) +#define GU_COLOR_5650 GU_COLOR_SHIFT(4) +#define GU_COLOR_5551 GU_COLOR_SHIFT(5) +#define GU_COLOR_4444 GU_COLOR_SHIFT(6) +#define GU_COLOR_8888 GU_COLOR_SHIFT(7) +#define GU_COLOR_BITS GU_COLOR_SHIFT(7) + +#define GU_NORMAL_SHIFT(n) ((n)<<5) +#define GU_NORMAL_8BIT GU_NORMAL_SHIFT(1) +#define GU_NORMAL_16BIT GU_NORMAL_SHIFT(2) +#define GU_NORMAL_32BITF GU_NORMAL_SHIFT(3) +#define GU_NORMAL_BITS GU_NORMAL_SHIFT(3) + +#define GU_VERTEX_SHIFT(n) ((n)<<7) +#define GU_VERTEX_8BIT GU_VERTEX_SHIFT(1) +#define GU_VERTEX_16BIT GU_VERTEX_SHIFT(2) +#define GU_VERTEX_32BITF GU_VERTEX_SHIFT(3) +#define GU_VERTEX_BITS GU_VERTEX_SHIFT(3) + +#define GU_WEIGHT_SHIFT(n) ((n)<<9) +#define GU_WEIGHT_8BIT GU_WEIGHT_SHIFT(1) +#define GU_WEIGHT_16BIT GU_WEIGHT_SHIFT(2) +#define GU_WEIGHT_32BITF GU_WEIGHT_SHIFT(3) +#define GU_WEIGHT_BITS GU_WEIGHT_SHIFT(3) + +#define GU_INDEX_SHIFT(n) ((n)<<11) +#define GU_INDEX_8BIT GU_INDEX_SHIFT(1) +#define GU_INDEX_16BIT GU_INDEX_SHIFT(2) +#define GU_INDEX_BITS GU_INDEX_SHIFT(3) + +#define GU_WEIGHTS(n) ((((n)-1)&7)<<14) +#define GU_WEIGHTS_BITS GU_WEIGHTS(8) +#define GU_VERTICES(n) ((((n)-1)&7)<<18) +#define GU_VERTICES_BITS GU_VERTICES(8) + +#define GU_TRANSFORM_SHIFT(n) ((n)<<23) +#define GU_TRANSFORM_3D GU_TRANSFORM_SHIFT(0) +#define GU_TRANSFORM_2D GU_TRANSFORM_SHIFT(1) +#define GU_TRANSFORM_BITS GU_TRANSFORM_SHIFT(1) +/* Vertex Declarations End */ + +/* Pixel Formats */ +#define GU_PSM_5650 (0) /* Display, Texture, Palette */ +#define GU_PSM_5551 (1) /* Display, Texture, Palette */ +#define GU_PSM_4444 (2) /* Display, Texture, Palette */ +#define GU_PSM_8888 (3) /* Display, Texture, Palette */ +#define GU_PSM_T4 (4) /* Texture */ +#define GU_PSM_T8 (5) /* Texture */ +#define GU_PSM_T16 (6) /* Texture */ +#define GU_PSM_T32 (7) /* Texture */ +#define GU_PSM_DXT1 (8) /* Texture */ +#define GU_PSM_DXT3 (9) /* Texture */ +#define GU_PSM_DXT5 (10) /* Texture */ + +/* Spline Mode */ +#define GU_FILL_FILL (0) +#define GU_OPEN_FILL (1) +#define GU_FILL_OPEN (2) +#define GU_OPEN_OPEN (3) + +/* Shading Model */ +#define GU_FLAT (0) +#define GU_SMOOTH (1) + +/* Logical operation */ +#define GU_CLEAR (0) +#define GU_AND (1) +#define GU_AND_REVERSE (2) +#define GU_COPY (3) +#define GU_AND_INVERTED (4) +#define GU_NOOP (5) +#define GU_XOR (6) +#define GU_OR (7) +#define GU_NOR (8) +#define GU_EQUIV (9) +#define GU_INVERTED (10) +#define GU_OR_REVERSE (11) +#define GU_COPY_INVERTED (12) +#define GU_OR_INVERTED (13) +#define GU_NAND (14) +#define GU_SET (15) + +/* Texture Filter */ +#define GU_NEAREST (0) +#define GU_LINEAR (1) +#define GU_NEAREST_MIPMAP_NEAREST (4) +#define GU_LINEAR_MIPMAP_NEAREST (5) +#define GU_NEAREST_MIPMAP_LINEAR (6) +#define GU_LINEAR_MIPMAP_LINEAR (7) + +/* Texture Map Mode */ +#define GU_TEXTURE_COORDS (0) +#define GU_TEXTURE_MATRIX (1) +#define GU_ENVIRONMENT_MAP (2) + +/* Texture Level Mode */ +#define GU_TEXTURE_AUTO (0) +#define GU_TEXTURE_CONST (1) +#define GU_TEXTURE_SLOPE (2) + +/* Texture Projection Map Mode */ +#define GU_POSITION (0) +#define GU_UV (1) +#define GU_NORMALIZED_NORMAL (2) +#define GU_NORMAL (3) + +/* Wrap Mode */ +#define GU_REPEAT (0) +#define GU_CLAMP (1) + +/* Front Face Direction */ +#define GU_CW (0) +#define GU_CCW (1) + +/* Test Function */ +#define GU_NEVER (0) +#define GU_ALWAYS (1) +#define GU_EQUAL (2) +#define GU_NOTEQUAL (3) +#define GU_LESS (4) +#define GU_LEQUAL (5) +#define GU_GREATER (6) +#define GU_GEQUAL (7) + +/* Clear Buffer Mask */ +#define GU_COLOR_BUFFER_BIT (1) +#define GU_STENCIL_BUFFER_BIT (2) +#define GU_DEPTH_BUFFER_BIT (4) +#define GU_FAST_CLEAR_BIT (16) + +/* Texture Effect */ +#define GU_TFX_MODULATE (0) +#define GU_TFX_DECAL (1) +#define GU_TFX_BLEND (2) +#define GU_TFX_REPLACE (3) +#define GU_TFX_ADD (4) + +/* Texture Color Component */ +#define GU_TCC_RGB (0) +#define GU_TCC_RGBA (1) + +/* Blending Op */ +#define GU_ADD (0) +#define GU_SUBTRACT (1) +#define GU_REVERSE_SUBTRACT (2) +#define GU_MIN (3) +#define GU_MAX (4) +#define GU_ABS (5) + +/* Blending Factor */ +#define GU_SRC_COLOR (0) +#define GU_ONE_MINUS_SRC_COLOR (1) +#define GU_SRC_ALPHA (2) +#define GU_ONE_MINUS_SRC_ALPHA (3) +#define GU_DST_COLOR (0) +#define GU_ONE_MINUS_DST_COLOR (1) +#define GU_DST_ALPHA (4) +#define GU_ONE_MINUS_DST_ALPHA (5) +#define GU_FIX (10) + +/* Stencil Operations */ +#define GU_KEEP (0) +#define GU_ZERO (1) +#define GU_REPLACE (2) +#define GU_INVERT (3) +#define GU_INCR (4) +#define GU_DECR (5) + +/* Light Components */ +#define GU_AMBIENT (1) +#define GU_DIFFUSE (2) +#define GU_SPECULAR (4) +#define GU_AMBIENT_AND_DIFFUSE (GU_AMBIENT|GU_DIFFUSE) +#define GU_DIFFUSE_AND_SPECULAR (GU_DIFFUSE|GU_SPECULAR) +#define GU_UNKNOWN_LIGHT_COMPONENT (8) + +/* Light modes */ +#define GU_SINGLE_COLOR (0) +#define GU_SEPARATE_SPECULAR_COLOR (1) + +/* Light Type */ +#define GU_DIRECTIONAL (0) +#define GU_POINTLIGHT (1) +#define GU_SPOTLIGHT (2) + +/* Contexts */ +#define GU_DIRECT (0) +#define GU_CALL (1) +#define GU_SEND (2) + +/* List Queue */ +#define GU_TAIL (0) +#define GU_HEAD (1) + +/* Sync behavior (mode) */ +#define GU_SYNC_FINISH (0) +#define GU_SYNC_SIGNAL (1) +#define GU_SYNC_DONE (2) +#define GU_SYNC_LIST (3) +#define GU_SYNC_SEND (4) + +/* behavior (what) */ +#define GU_SYNC_WAIT (0) +#define GU_SYNC_NOWAIT (1) + +/* Sync behavior (what) [see pspge.h] */ +#define GU_SYNC_WHAT_DONE (0) +#define GU_SYNC_WHAT_QUEUED (1) +#define GU_SYNC_WHAT_DRAW (2) +#define GU_SYNC_WHAT_STALL (3) +#define GU_SYNC_WHAT_CANCEL (4) + +/* Signals */ +#define GU_CALLBACK_SIGNAL (1) +#define GU_CALLBACK_FINISH (4) + +/* Signal behavior */ +#define GU_BEHAVIOR_SUSPEND (1) +#define GU_BEHAVIOR_CONTINUE (2) + +/* Color Macros, maps 8 bit unsigned channels into one 32-bit value */ +#define GU_ABGR(a,b,g,r) (((a) << 24)|((b) << 16)|((g) << 8)|(r)) +#define GU_ARGB(a,r,g,b) GU_ABGR((a),(b),(g),(r)) +#define GU_RGBA(r,g,b,a) GU_ARGB((a),(r),(g),(b)) + +/* Color Macro, maps floating point channels (0..1) into one 32-bit value */ +#define GU_COLOR(r,g,b,a) GU_RGBA((u32)((r) * 255.0f),(u32)((g) * 255.0f),(u32)((b) * 255.0f),(u32)((a) * 255.0f)) + +typedef void (*GuSwapBuffersCallback)(void** display,void** render); + +/** @addtogroup GU */ +/*@{*/ + +/** + * Set depth buffer parameters + * + * @param zbp - VRAM pointer where the depthbuffer should start + * @param zbw - The width of the depth-buffer (block-aligned) + * +**/ +void sceGuDepthBuffer(void* zbp, int zbw); + +/** + * Set display buffer parameters + * + * @par Example: Setup a standard 16-bit display buffer + * @code + * sceGuDispBuffer(480,272,(void*)512*272*2,512); // 480*272, skipping the draw buffer located at address 0 + * @endcode + * + * @param width - Width of the display buffer in pixels + * @param height - Width of the display buffer in pixels + * @param dispbp - VRAM pointer to where the display-buffer starts + * @param dispbw - Display buffer width (block aligned) + * +**/ +void sceGuDispBuffer(int width, int height, void* dispbp, int dispbw); + +/** + * Set draw buffer parameters (and store in context for buffer-swap) + * + * Available pixel formats are: + * - GU_PSM_5650 + * - GU_PSM_5551 + * - GU_PSM_4444 + * - GU_PSM_8888 + * + * @par Example: Setup a standard 16-bit draw buffer + * @code + * sceGuDrawBuffer(GU_PSM_5551,(void*)0,512); + * @endcode + * + * @param psm - Pixel format to use for rendering (and display) + * @param fbp - VRAM pointer to where the draw buffer starts + * @param fbw - Frame buffer width (block aligned) +**/ +void sceGuDrawBuffer(int psm, void* fbp, int fbw); + +/** + * Set draw buffer directly, not storing parameters in the context + * + * @param psm - Pixel format to use for rendering + * @param fbp - VRAM pointer to where the draw buffer starts + * @param fbw - Frame buffer width (block aligned) +**/ +void sceGuDrawBufferList(int psm, void* fbp, int fbw); + +/** + * Turn display on or off + * + * Available states are: + * - GU_TRUE (1) - Turns display on + * - GU_FALSE (0) - Turns display off + * + * @param state - Turn display on or off + * @return State of the display prior to this call +**/ +int sceGuDisplay(int state); + +/** + * Select which depth-test function to use + * + * Valid choices for the depth-test are: + * - GU_NEVER - No pixels pass the depth-test + * - GU_ALWAYS - All pixels pass the depth-test + * - GU_EQUAL - Pixels that match the depth-test pass + * - GU_NOTEQUAL - Pixels that doesn't match the depth-test pass + * - GU_LESS - Pixels that are less in depth passes + * - GU_LEQUAL - Pixels that are less or equal in depth passes + * - GU_GREATER - Pixels that are greater in depth passes + * - GU_GEQUAL - Pixels that are greater or equal passes + * + * @param function - Depth test function to use +**/ +void sceGuDepthFunc(int function); + +/** + * Mask depth buffer writes + * + * @param mask - GU_TRUE(1) to disable Z writes, GU_FALSE(0) to enable +**/ +void sceGuDepthMask(int mask); + +void sceGuDepthOffset(unsigned int offset); + +/** + * Set which range to use for depth calculations. + * + * @note The depth buffer is inversed, and takes values from 65535 to 0. + * + * Example: Use the entire depth-range for calculations: + * @code + * sceGuDepthRange(65535,0); + * @endcode + * + * @param near - Value to use for the near plane + * @param far - Value to use for the far plane +**/ +void sceGuDepthRange(int near, int far); + +void sceGuFog(float near, float far, unsigned int color); + +/** + * Initalize the GU system + * + * This function MUST be called as the first function, otherwise state is undetermined. +**/ +void sceGuInit(void); + +/** + * Shutdown the GU system + * + * Called when GU is no longer needed +**/ +void sceGuTerm(void); + +void sceGuBreak(int a0); +void sceGuContinue(void); + +/** + * Setup signal handler + * + * Available signals are: + * - GU_CALLBACK_SIGNAL - Called when sceGuSignal is used + * - GU_CALLBACK_FINISH - Called when display list is finished + * + * @param signal - Signal index to install a handler for + * @param callback - Callback to call when signal index is triggered + * @return The old callback handler +**/ +void* sceGuSetCallback(int signal, void (*callback)(int)); + +/** + * Trigger signal to call code from the command stream + * + * Available behaviors are: + * - GU_BEHAVIOR_SUSPEND - Stops display list execution until callback function finished + * - GU_BEHAVIOR_CONTINUE - Do not stop display list execution during callback + * + * @param signal - Signal to trigger + * @param behavior - Behavior type +**/ +void sceGuSignal(int signal, int behavior); + +/** + * Send raw float-command to the GE + * + * The argument is converted into a 24-bit float before transfer. + * + * @param cmd - Which command to send + * @param argument - Argument to pass along +**/ +void sceGuSendCommandf(int cmd, float argument); + +/** + * Send raw command to the GE + * + * Only the 24 lower bits of the argument is passed along. + * + * @param cmd - Which command to send + * @param argument - Argument to pass along +**/ +void sceGuSendCommandi(int cmd, int argument); + +/** + * Allocate memory on the current display list for temporary storage + * + * @note This function is NOT for permanent memory allocation, the + * memory will be invalid as soon as you start filling the same display + * list again. + * + * @param size - How much memory to allocate + * @return Memory-block ready for use +**/ +void* sceGuGetMemory(int size); + +/** + * Start filling a new display-context + * + * Contexts available are: + * - GU_DIRECT - Rendering is performed as list is filled + * - GU_CALL - List is setup to be called from the main list + * - GU_SEND - List is buffered for a later call to sceGuSendList() + * + * The previous context-type is stored so that it can be restored at sceGuFinish(). + * + * @param cid - Context Type + * @param list - Pointer to display-list (16 byte aligned) +**/ +void sceGuStart(int cid, void* list); + +/** + * Finish current display list and go back to the parent context + * + * If the context is GU_DIRECT, the stall-address is updated so that the entire list will + * execute. Otherwise, only the terminating action is written to the list, depending on + * context-type. + * + * The finish-callback will get a zero as argument when using this function. + * + * This also restores control back to whatever context that was active prior to this call. + * + * @return Size of finished display list +**/ +int sceGuFinish(void); + +/** + * Finish current display list and go back to the parent context, sending argument id for + * the finish callback. + * + * If the context is GU_DIRECT, the stall-address is updated so that the entire list will + * execute. Otherwise, only the terminating action is written to the list, depending on + * context-type. + * + * @param id - Finish callback id (16-bit) + * @return Size of finished display list +**/ +int sceGuFinishId(unsigned int id); + +/** + * Call previously generated display-list + * + * @param list - Display list to call +**/ +void sceGuCallList(const void* list); + +/** + * Set wether to use stack-based calls or signals to handle execution of called lists. + * + * @param mode - GU_TRUE(1) to enable signals, GU_FALSE(0) to disable signals and use + * normal calls instead. +**/ +void sceGuCallMode(int mode); + +/** + * Check how large the current display-list is + * + * @return The size of the current display list +**/ +int sceGuCheckList(void); + +/** + * Send a list to the GE directly + * + * Available modes are: + * - GU_TAIL - Place list last in the queue, so it executes in-order + * - GU_HEAD - Place list first in queue so that it executes as soon as possible + * + * @param mode - Whether to place the list first or last in queue + * @param list - List to send + * @param context - Temporary storage for the GE context +**/ +void sceGuSendList(int mode, const void* list, PspGeContext* context); + +/** + * Swap display and draw buffer + * + * @return Pointer to the new drawbuffer +**/ +void* sceGuSwapBuffers(void); + +/** + * Wait until display list has finished executing + * + * @par Example: Wait for the currently executing display list + * @code + * sceGuSync(0,0); + * @endcode + * + * Available what are: + * - GU_SYNC_WHAT_DONE + * - GU_SYNC_WHAT_QUEUED + * - GU_SYNC_WHAT_DRAW + * - GU_SYNC_WHAT_STALL + * - GU_SYNC_WHAT_CANCEL + * + * Available mode are: + * - GU_SYNC_FINISH - Wait until the last sceGuFinish command is reached + * - GU_SYNC_SIGNAL - Wait until the last (?) signal is executed + * - GU_SYNC_DONE - Wait until all commands currently in list are executed + * - GU_SYNC_LIST - Wait for the currently executed display list (GU_DIRECT) + * - GU_SYNC_SEND - Wait for the last send list + * + * @param mode - What to wait for + * @param what - What to sync to + * @return Unknown at this time +**/ +int sceGuSync(int mode, int what); + +/** + * Draw array of vertices forming primitives + * + * Available primitive-types are: + * - GU_POINTS - Single pixel points (1 vertex per primitive) + * - GU_LINES - Single pixel lines (2 vertices per primitive) + * - GU_LINE_STRIP - Single pixel line-strip (2 vertices for the first primitive, 1 for every following) + * - GU_TRIANGLES - Filled triangles (3 vertices per primitive) + * - GU_TRIANGLE_STRIP - Filled triangles-strip (3 vertices for the first primitive, 1 for every following) + * - GU_TRIANGLE_FAN - Filled triangle-fan (3 vertices for the first primitive, 1 for every following) + * - GU_SPRITES - Filled blocks (2 vertices per primitive) + * + * The vertex-type decides how the vertices align and what kind of information they contain. + * The following flags are ORed together to compose the final vertex format: + * - GU_TEXTURE_8BIT - 8-bit texture coordinates + * - GU_TEXTURE_16BIT - 16-bit texture coordinates + * - GU_TEXTURE_32BITF - 32-bit texture coordinates (float) + * + * - GU_COLOR_5650 - 16-bit color (R5G6B5A0) + * - GU_COLOR_5551 - 16-bit color (R5G5B5A1) + * - GU_COLOR_4444 - 16-bit color (R4G4B4A4) + * - GU_COLOR_8888 - 32-bit color (R8G8B8A8) + * + * - GU_NORMAL_8BIT - 8-bit normals + * - GU_NORMAL_16BIT - 16-bit normals + * - GU_NORMAL_32BITF - 32-bit normals (float) + * + * - GU_VERTEX_8BIT - 8-bit vertex position + * - GU_VERTEX_16BIT - 16-bit vertex position + * - GU_VERTEX_32BITF - 32-bit vertex position (float) + * + * - GU_WEIGHT_8BIT - 8-bit weights + * - GU_WEIGHT_16BIT - 16-bit weights + * - GU_WEIGHT_32BITF - 32-bit weights (float) + * + * - GU_INDEX_8BIT - 8-bit vertex index + * - GU_INDEX_16BIT - 16-bit vertex index + * + * - GU_WEIGHTS(n) - Number of weights (1-8) + * - GU_VERTICES(n) - Number of vertices (1-8) + * + * - GU_TRANSFORM_2D - Coordinate is passed directly to the rasterizer + * - GU_TRANSFORM_3D - Coordinate is transformed before passed to rasterizer + * + * @note Every vertex must align to 32 bits, which means that you HAVE to pad if it does not add up! + * + * Vertex order: + * [for vertices(1-8)] + * [weights (0-8)] + * [texture uv] + * [color] + * [normal] + * [vertex] + * [/for] + * + * @par Example: Render 400 triangles, with floating-point texture coordinates, and floating-point position, no indices + * @code + * sceGuDrawArray(GU_TRIANGLES,GU_TEXTURE_32BITF|GU_VERTEX_32BITF,400*3,0,vertices); + * @endcode + * + * @param prim - What kind of primitives to render + * @param vtype - Vertex type to process + * @param count - How many vertices to process + * @param indices - Optional pointer to an index-list + * @param vertices - Pointer to a vertex-list +**/ +void sceGuDrawArray(int prim, int vtype, int count, const void* indices, const void* vertices); + +/** + * Begin conditional rendering of object + * + * If no vertices passed into this function are inside the scissor region, it will skip rendering + * the object. There can be up to 32 levels of conditional testing, and all levels HAVE to + * be terminated by sceGuEndObject(). + * + * @par Example: test a boundingbox against the frustum, and if visible, render object + * @code + * sceGuBeginObject(GU_VERTEX_32BITF,8,0,boundingBox); + * sceGuDrawArray(GU_TRIANGLES,GU_TEXTURE_32BITF|GU_VERTEX_32BITF,vertexCount,0,vertices); + * sceGuEndObject(); + * @endcode + * + * @param vtype - Vertex type to process + * @param count - Number of vertices to test + * @param indices - Optional list to an index-list + * @param vertices - Pointer to a vertex-list +**/ +void sceGuBeginObject(int vtype, int count, const void* indices, const void* vertices); + +/** + * End conditional rendering of object +**/ +void sceGuEndObject(void); + +/** + * Enable or disable GE state + * + * Look at sceGuEnable() for a list of states + * + * @param state - Which state to change + * @param status - Wether to enable or disable the state +**/ +void sceGuSetStatus(int state, int status); + +/** + * Get if state is currently enabled or disabled + * + * Look at sceGuEnable() for a list of states + * + * @param state - Which state to query about + * @return Wether state is enabled or not +**/ +int sceGuGetStatus(int state); + +/** + * Set the status on all 22 available states + * + * Look at sceGuEnable() for a list of states + * + * @param status - Bit-mask (0-21) containing the status of all 22 states +**/ +void sceGuSetAllStatus(int status); + +/** + * Query status on all 22 available states + * + * Look at sceGuEnable() for a list of states + * + * @return Status of all 22 states as a bitmask (0-21) +**/ +int sceGuGetAllStatus(void); + +/** + * Enable GE state + * + * The currently available states are: + * - GU_ALPHA_TEST + * - GU_DEPTH_TEST + * - GU_SCISSOR_TEST + * - GU_BLEND + * - GU_CULL_FACE + * - GU_DITHER + * - GU_CLIP_PLANES + * - GU_TEXTURE_2D + * - GU_LIGHTING + * - GU_LIGHT0 + * - GU_LIGHT1 + * - GU_LIGHT2 + * - GU_LIGHT3 + * - GU_COLOR_LOGIC_OP + * + * @param state - Which state to enable +**/ +void sceGuEnable(int state); + +/** + * Disable GE state + * + * Look at sceGuEnable() for a list of states + * + * @param state - Which state to disable +**/ +void sceGuDisable(int state); + +/** + * Set light parameters + * + * Available light types are: + * - GU_DIRECTIONAL - Directional light + * - GU_POINTLIGHT - Single point of light + * - GU_SPOTLIGHT - Point-light with a cone + * + * Available light components are: + * - GU_AMBIENT_AND_DIFFUSE + * - GU_DIFFUSE_AND_SPECULAR + * - GU_UNKNOWN_LIGHT_COMPONENT + * + * @param light - Light index + * @param type - Light type + * @param components - Light components + * @param position - Light position +**/ +void sceGuLight(int light, int type, int components, const ScePspFVector3* position); + +/** + * Set light attenuation + * + * @param light - Light index + * @param atten0 - Constant attenuation factor + * @param atten1 - Linear attenuation factor + * @param atten2 - Quadratic attenuation factor +**/ +void sceGuLightAtt(int light, float atten0, float atten1, float atten2); + +/** + * Set light color + * + * Available light components are: + * - GU_AMBIENT + * - GU_DIFFUSE + * - GU_SPECULAR + * - GU_AMBIENT_AND_DIFFUSE + * - GU_DIFFUSE_AND_SPECULAR + * + * @param light - Light index + * @param component - Which component to set + * @param color - Which color to use +**/ +void sceGuLightColor(int light, int component, unsigned int color); + +/** + * Set light mode + * + * Available light modes are: + * - GU_SINGLE_COLOR + * - GU_SEPARATE_SPECULAR_COLOR + * + * Separate specular colors are used to interpolate the specular component + * independently, so that it can be added to the fragment after the texture color. + * + * @param mode - Light mode to use +**/ +void sceGuLightMode(int mode); + +/** + * Set spotlight parameters + * + * @param light - Light index + * @param direction - Spotlight direction + * @param exponent - Spotlight exponent + * @param cutoff - Spotlight cutoff angle (in radians) +**/ +void sceGuLightSpot(int light, const ScePspFVector3* direction, float exponent, float cutoff); + +/** + * Clear current drawbuffer + * + * Available clear-flags are (OR them together to get final clear-mode): + * - GU_COLOR_BUFFER_BIT - Clears the color-buffer + * - GU_STENCIL_BUFFER_BIT - Clears the stencil-buffer + * - GU_DEPTH_BUFFER_BIT - Clears the depth-buffer + * + * @param flags - Which part of the buffer to clear +**/ +void sceGuClear(int flags); + +/** + * Set the current clear-color + * + * @param color - Color to clear with +**/ +void sceGuClearColor(unsigned int color); + +/** + * Set the current clear-depth + * + * @param depth - Set which depth to clear with (0x0000-0xffff) +**/ +void sceGuClearDepth(unsigned int depth); + +/** + * Set the current stencil clear value + * + * @param stencil - Set which stencil value to clear with (0-255) + * +**/ +void sceGuClearStencil(unsigned int stencil); + +/** + * Set mask for which bits of the pixels to write + * + * @param mask - Which bits to filter against writes + * +**/ +void sceGuPixelMask(unsigned int mask); + +/** + * Set current primitive color + * + * @param color - Which color to use (overriden by vertex-colors) +**/ +void sceGuColor(unsigned int color); + +/** + * Set the color test function + * + * The color test is only performed while GU_COLOR_TEST is enabled. + * + * Available functions are: + * - GU_NEVER + * - GU_ALWAYS + * - GU_EQUAL + * - GU_NOTEQUAL + * + * @par Example: Reject any pixel that does not have 0 as the blue channel + * @code + * sceGuColorFunc(GU_EQUAL,0,0xff0000); + * @endcode + * + * @param func - Color test function + * @param color - Color to test against + * @param mask - Mask ANDed against both source and destination when testing +**/ +void sceGuColorFunc(int func, unsigned int color, unsigned int mask); + +/** + * Set which color components that the material will receive + * + * The components are ORed together from the following values: + * - GU_AMBIENT + * - GU_DIFFUSE + * - GU_SPECULAR + * + * @param components - Which components to receive +**/ +void sceGuColorMaterial(int components); + +/** + * Set the alpha test parameters + * + * Available comparison functions are: + * - GU_NEVER + * - GU_ALWAYS + * - GU_EQUAL + * - GU_NOTEQUAL + * - GU_LESS + * - GU_LEQUAL + * - GU_GREATER + * - GU_GEQUAL + * + * @param func - Specifies the alpha comparison function. + * @param value - Specifies the reference value that incoming alpha values are compared to. + * @param mask - Specifies the mask that both values are ANDed with before comparison. +**/ +void sceGuAlphaFunc(int func, int value, int mask); + +void sceGuAmbient(unsigned int color); +void sceGuAmbientColor(unsigned int color); + +/** + * Set the blending-mode + * + * Keys for the blending operations: + * - Cs - Source color + * - Cd - Destination color + * - Bs - Blend function for source fragment + * - Bd - Blend function for destination fragment + * + * Available blending-operations are: + * - GU_ADD - (Cs*Bs) + (Cd*Bd) + * - GU_SUBTRACT - (Cs*Bs) - (Cd*Bd) + * - GU_REVERSE_SUBTRACT - (Cd*Bd) - (Cs*Bs) + * - GU_MIN - Cs < Cd ? Cs : Cd + * - GU_MAX - Cs < Cd ? Cd : Cs + * - GU_ABS - |Cs-Cd| + * + * Available blending-functions are: + * - GU_SRC_COLOR + * - GU_ONE_MINUS_SRC_COLOR + * - GU_SRC_ALPHA + * - GU_ONE_MINUS_SRC_ALPHA + * - GU_DST_ALPHA + * - GU_ONE_MINUS_DST_ALPHA + * - GU_DST_COLOR + * - GU_ONE_MINUS_DST_COLOR + * - GU_FIX + * + * @param op - Blending Operation + * @param src - Blending function for source operand + * @param dest - Blending function for dest operand + * @param srcfix - Fix value for GU_FIX (source operand) + * @param destfix - Fix value for GU_FIX (dest operand) +**/ +void sceGuBlendFunc(int op, int src, int dest, unsigned int srcfix, unsigned int destfix); + +void sceGuMaterial(int mode, int color); + +/** + * +**/ +void sceGuModelColor(unsigned int emissive, unsigned int ambient, unsigned int diffuse, unsigned int specular); + +/** + * Set stencil function and reference value for stencil testing + * + * Available functions are: + * - GU_NEVER + * - GU_ALWAYS + * - GU_EQUAL + * - GU_NOTEQUAL + * - GU_LESS + * - GU_LEQUAL + * - GU_GREATER + * - GU_GEQUAL + * + * @param func - Test function + * @param ref - The reference value for the stencil test + * @param mask - Mask that is ANDed with both the reference value and stored stencil value when the test is done +**/ +void sceGuStencilFunc(int func, int ref, int mask); + +/** + * Set the stencil test actions + * + * Available actions are: + * - GU_KEEP - Keeps the current value + * - GU_ZERO - Sets the stencil buffer value to zero + * - GU_REPLACE - Sets the stencil buffer value to ref, as specified by sceGuStencilFunc() + * - GU_INCR - Increments the current stencil buffer value + * - GU_DECR - Decrease the current stencil buffer value + * - GU_INVERT - Bitwise invert the current stencil buffer value + * + * As stencil buffer shares memory with framebuffer alpha, resolution of the buffer + * is directly in relation. + * + * @param fail - The action to take when the stencil test fails + * @param zfail - The action to take when stencil test passes, but the depth test fails + * @param zpass - The action to take when both stencil test and depth test passes +**/ +void sceGuStencilOp(int fail, int zfail, int zpass); + +/** + * Set the specular power for the material + * + * @param power - Specular power + * +**/ +void sceGuSpecular(float power); + +/** + * Set the current face-order (for culling) + * + * This only has effect when culling is enabled (GU_CULL_FACE) + * + * Culling order can be: + * - GU_CW - Clockwise primitives are not culled + * - GU_CCW - Counter-clockwise are not culled + * + * @param order - Which order to use +**/ +void sceGuFrontFace(int order); + +/** + * Set color logical operation + * + * Available operations are: + * - GU_CLEAR + * - GU_AND + * - GU_AND_REVERSE + * - GU_COPY + * - GU_AND_INVERTED + * - GU_NOOP + * - GU_XOR + * - GU_OR + * - GU_NOR + * - GU_EQUIV + * - GU_INVERTED + * - GU_OR_REVERSE + * - GU_COPY_INVERTED + * - GU_OR_INVERTED + * - GU_NAND + * - GU_SET + * + * This operation only has effect if GU_COLOR_LOGIC_OP is enabled. + * + * @param op - Operation to execute +**/ +void sceGuLogicalOp(int op); + +/** + * Set ordered pixel dither matrix + * + * This dither matrix is only applied if GU_DITHER is enabled. + * + * @param matrix - Dither matrix +**/ +void sceGuSetDither(const ScePspIMatrix4* matrix); + +/** + * Set how primitives are shaded + * + * The available shading-methods are: + * - GU_FLAT - Primitives are flatshaded, the last vertex-color takes effet + * - GU_SMOOTH - Primtives are gouraud-shaded, all vertex-colors take effect + * + * @param mode - Which mode to use +**/ +void sceGuShadeModel(int mode); + +/** + * Image transfer using the GE + * + * @note Data must be aligned to 1 quad word (16 bytes) + * + * @par Example: Copy a fullscreen 32-bit image from RAM to VRAM + * @code + * sceGuCopyImage(GU_PSM_8888,0,0,480,272,512,pixels,0,0,512,(void*)(((unsigned int)framebuffer)+0x4000000)); + * @endcode + * + * @param psm - Pixel format for buffer + * @param sx - Source X + * @param sy - Source Y + * @param width - Image width + * @param height - Image height + * @param srcw - Source buffer width (block aligned) + * @param src - Source pointer + * @param dx - Destination X + * @param dy - Destination Y + * @param destw - Destination buffer width (block aligned) + * @param dest - Destination pointer +**/ +void sceGuCopyImage(int psm, int sx, int sy, int width, int height, int srcw, void* src, int dx, int dy, int destw, void* dest); + +/** + * Specify the texture environment color + * + * This is used in the texture function when a constant color is needed. + * + * See sceGuTexFunc() for more information. + * + * @param color - Constant color (0x00BBGGRR) +**/ +void sceGuTexEnvColor(unsigned int color); + +/** + * Set how the texture is filtered + * + * Available filters are: + * - GU_NEAREST + * - GU_LINEAR + * - GU_NEAREST_MIPMAP_NEAREST + * - GU_LINEAR_MIPMAP_NEAREST + * - GU_NEAREST_MIPMAP_LINEAR + * - GU_LINEAR_MIPMAP_LINEAR + * + * @param min - Minimizing filter + * @param mag - Magnifying filter +**/ +void sceGuTexFilter(int min, int mag); + +/** + * Flush texture page-cache + * + * Do this if you have copied/rendered into an area currently in the texture-cache + * +**/ +void sceGuTexFlush(void); + +/** + * Set how textures are applied + * + * Key for the apply-modes: + * - Cv - Color value result + * - Ct - Texture color + * - Cf - Fragment color + * - Cc - Constant color (specified by sceGuTexEnvColor()) + * + * Available apply-modes are: (TFX) + * - GU_TFX_MODULATE - Cv=Ct*Cf TCC_RGB: Av=Af TCC_RGBA: Av=At*Af + * - GU_TFX_DECAL - TCC_RGB: Cv=Ct,Av=Af TCC_RGBA: Cv=Cf*(1-At)+Ct*At Av=Af + * - GU_TFX_BLEND - Cv=(Cf*(1-Ct))+(Cc*Ct) TCC_RGB: Av=Af TCC_RGBA: Av=At*Af + * - GU_TFX_REPLACE - Cv=Ct TCC_RGB: Av=Af TCC_RGBA: Av=At + * - GU_TFX_ADD - Cv=Cf+Ct TCC_RGB: Av=Af TCC_RGBA: Av=At*Af + * + * The fields TCC_RGB and TCC_RGBA specify components that differ between + * the two different component modes. + * + * - GU_TFX_MODULATE - The texture is multiplied with the current diffuse fragment + * - GU_TFX_REPLACE - The texture replaces the fragment + * - GU_TFX_ADD - The texture is added on-top of the diffuse fragment + * + * Available component-modes are: (TCC) + * - GU_TCC_RGB - The texture alpha does not have any effect + * - GU_TCC_RGBA - The texture alpha is taken into account + * + * @param tfx - Which apply-mode to use + * @param tcc - Which component-mode to use +**/ +void sceGuTexFunc(int tfx, int tcc); + +/** + * Set current texturemap + * + * Textures may reside in main RAM, but it has a huge speed-penalty. Swizzle textures + * to get maximum speed. + * + * @note Data must be aligned to 1 quad word (16 bytes) + * + * @param mipmap - Mipmap level + * @param width - Width of texture (must be a power of 2) + * @param height - Height of texture (must be a power of 2) + * @param tbw - Texture Buffer Width (block-aligned) + * @param tbp - Texture buffer pointer (16 byte aligned) +**/ +void sceGuTexImage(int mipmap, int width, int height, int tbw, const void* tbp); + +/** + * Set texture-level mode (mipmapping) + * + * Available modes are: + * - GU_TEXTURE_AUTO + * - GU_TEXTURE_CONST + * - GU_TEXTURE_SLOPE + * + * @param mode - Which mode to use + * @param bias - Which mipmap bias to use +**/ +void sceGuTexLevelMode(unsigned int mode, float bias); + +/** + * Set the texture-mapping mode + * + * Available modes are: + * - GU_TEXTURE_COORDS + * - GU_TEXTURE_MATRIX + * - GU_ENVIRONMENT_MAP + * + * @param mode - Which mode to use + * @param a1 - Unknown + * @param a2 - Unknown +**/ +void sceGuTexMapMode(int mode, unsigned int a1, unsigned int a2); + +/** + * Set texture-mode parameters + * + * Available texture-formats are: + * - GU_PSM_5650 - Hicolor, 16-bit + * - GU_PSM_5551 - Hicolor, 16-bit + * - GU_PSM_4444 - Hicolor, 16-bit + * - GU_PSM_8888 - Truecolor, 32-bit + * - GU_PSM_T4 - Indexed, 4-bit (2 pixels per byte) + * - GU_PSM_T8 - Indexed, 8-bit + * + * @param tpsm - Which texture format to use + * @param maxmips - Number of mipmaps to use (0-8) + * @param a2 - Unknown, set to 0 + * @param swizzle - GU_TRUE(1) to swizzle texture-reads +**/ +void sceGuTexMode(int tpsm, int maxmips, int a2, int swizzle); + +/** + * Set texture offset + * + * @note Only used by the 3D T&L pipe, renders done with GU_TRANSFORM_2D are + * not affected by this. + * + * @param u - Offset to add to the U coordinate + * @param v - Offset to add to the V coordinate +**/ +void sceGuTexOffset(float u, float v); + +/** + * Set texture projection-map mode + * + * Available modes are: + * - GU_POSITION + * - GU_UV + * - GU_NORMALIZED_NORMAL + * - GU_NORMAL + * + * @param mode - Which mode to use +**/ +void sceGuTexProjMapMode(int mode); + +/** + * Set texture scale + * + * @note Only used by the 3D T&L pipe, renders ton with GU_TRANSFORM_2D are + * not affected by this. + * + * @param u - Scalar to multiply U coordinate with + * @param v - Scalar to multiply V coordinate with +**/ +void sceGuTexScale(float u, float v); +void sceGuTexSlope(float slope); + +/** + * Synchronize rendering pipeline with image upload. + * + * This will stall the rendering pipeline until the current image upload initiated by + * sceGuCopyImage() has completed. +**/ +void sceGuTexSync(); + +/** + * Set if the texture should repeat or clamp + * + * Available modes are: + * - GU_REPEAT - The texture repeats after crossing the border + * - GU_CLAMP - Texture clamps at the border + * + * @param u - Wrap-mode for the U direction + * @param v - Wrap-mode for the V direction +**/ +void sceGuTexWrap(int u, int v); + +/** + * Upload CLUT (Color Lookup Table) + * + * @note Data must be aligned to 1 quad word (16 bytes) + * + * @param num_blocks - How many blocks of 8 entries to upload (32*8 is 256 colors) + * @param cbp - Pointer to palette (16 byte aligned) +**/ +void sceGuClutLoad(int num_blocks, const void* cbp); + +/** + * Set current CLUT mode + * + * Available pixel formats for palettes are: + * - GU_PSM_5650 + * - GU_PSM_5551 + * - GU_PSM_4444 + * - GU_PSM_8888 + * + * @param cpsm - Which pixel format to use for the palette + * @param shift - Shifts color index by that many bits to the right + * @param mask - Masks the color index with this bitmask after the shift (0-0xFF) + * @param a3 - Unknown, set to 0 +**/ +void sceGuClutMode(unsigned int cpsm, unsigned int shift, unsigned int mask, unsigned int a3); + +/** + * Set virtual coordinate offset + * + * The PSP has a virtual coordinate-space of 4096x4096, this controls where rendering is performed + * + * @par Example: Center the virtual coordinate range + * @code + * sceGuOffset(2048-(480/2),2048-(480/2)); + * @endcode + * + * @param x - Offset (0-4095) + * @param y - Offset (0-4095) +**/ +void sceGuOffset(unsigned int x, unsigned int y); + +/** + * Set what to scissor within the current viewport + * + * Note that scissoring is only performed if the custom scissoring is enabled (GU_SCISSOR_TEST) + * + * @param x - Left of scissor region + * @param y - Top of scissor region + * @param w - Width of scissor region + * @param h - Height of scissor region +**/ +void sceGuScissor(int x, int y, int w, int h); + +/** + * Set current viewport + * + * @par Example: Setup a viewport of size (480,272) with origo at (2048,2048) + * @code + * sceGuViewport(2048,2048,480,272); + * @endcode + * + * @param cx - Center for horizontal viewport + * @param cy - Center for vertical viewport + * @param width - Width of viewport + * @param height - Height of viewport +**/ +void sceGuViewport(int cx, int cy, int width, int height); + +/** + * Draw bezier surface + * + * @param vtype - Vertex type, look at sceGuDrawArray() for vertex definition + * @param ucount - Number of vertices used in the U direction + * @param vcount - Number of vertices used in the V direction + * @param indices - Pointer to index buffer + * @param vertices - Pointer to vertex buffer +**/ +void sceGuDrawBezier(int vtype, int ucount, int vcount, const void* indices, const void* vertices); + +/** + * Set dividing for patches (beziers and splines) + * + * @param ulevel - Number of division on u direction + * @param vlevel - Number of division on v direction +**/ +void sceGuPatchDivide(unsigned int ulevel, unsigned int vlevel); + +void sceGuPatchFrontFace(unsigned int a0); + +/** + * Set primitive for patches (beziers and splines) + * + * @param prim - Desired primitive type (GU_POINTS | GU_LINE_STRIP | GU_TRIANGLE_STRIP) +**/ +void sceGuPatchPrim(int prim); + +void sceGuDrawSpline(int vtype, int ucount, int vcount, int uedge, int vedge, const void* indices, const void* vertices); + +/** + * Set transform matrices + * + * Available matrices are: + * - GU_PROJECTION - View->Projection matrix + * - GU_VIEW - World->View matrix + * - GU_MODEL - Model->World matrix + * - GU_TEXTURE - Texture matrix + * + * @param type - Which matrix-type to set + * @param matrix - Matrix to load +**/ +void sceGuSetMatrix(int type, const ScePspFMatrix4* matrix); + +/** + * Specify skinning matrix entry + * + * To enable vertex skinning, pass GU_WEIGHTS(n), where n is between + * 1-8, and pass available GU_WEIGHT_??? declaration. This will change + * the amount of weights passed in the vertex araay, and by setting the skinning, + * matrices, you will multiply each vertex every weight and vertex passed. + * + * Please see sceGuDrawArray() for vertex format information. + * + * @param index - Skinning matrix index (0-7) + * @param matrix - Matrix to set +**/ +void sceGuBoneMatrix(unsigned int index, const ScePspFMatrix4* matrix); + +/** + * Specify morph weight entry + * + * To enable vertex morphing, pass GU_VERTICES(n), where n is between + * 1-8. This will change the amount of vertices passed in the vertex array, + * and by setting the morph weights for every vertex entry in the array, + * you can blend between them. + * + * Please see sceGuDrawArray() for vertex format information. + * + * @param index - Morph weight index (0-7) + * @param weight - Weight to set +**/ +void sceGuMorphWeight(int index, float weight); + +void sceGuDrawArrayN(int primitive_type, int vertex_type, int count, int a3, const void* indices, const void* vertices); + +/** + * Set how the display should be set + * + * Available behaviours are: + * - PSP_DISPLAY_SETBUF_IMMEDIATE - Display is swapped immediately + * - PSP_DISPLAY_SETBUF_NEXTFRAME - Display is swapped on the next frame + * + * Do remember that this swaps the pointers internally, regardless of setting, so be careful to wait until the next + * vertical blank or use another buffering algorithm (see guSwapBuffersCallback()). +**/ +void guSwapBuffersBehaviour(int behaviour); + +/** + * Set a buffer swap callback to allow for more advanced buffer methods without hacking the library. + * + * The GuSwapBuffersCallback is defined like this: + * @code + * void swapBuffersCallback(void** display, void** render); + * @endcode + * and on entry they contain the variables that are to be set. To change the pointers that will be used, just + * write the new pointers. Example of a triple-buffering algorithm: + * @code + * void* doneBuffer; + * void swapBuffersCallback(void** display, void** render) + * { + * void* active = doneBuffer; + * doneBuffer = *display; + *display = active; + * } + * @endcode + * + * @param callback - Callback to access when buffers are swapped. Pass 0 to disable. +**/ +void guSwapBuffersCallback(GuSwapBuffersCallback callback); + +/*@}*/ + +#if defined(__cplusplus) +}; +#endif + +#endif diff --git a/src/gu/resetValues.c b/src/gu/resetValues.c new file mode 100644 index 00000000..fc4d604c --- /dev/null +++ b/src/gu/resetValues.c @@ -0,0 +1,63 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void resetValues() +{ + unsigned int i; + + gu_init = 0; + + gu_states = 0; + gu_current_frame = 0; + gu_object_stack_depth = 0; + + gu_display_on = 0; + gu_call_mode = 0; + + gu_draw_buffer.pixel_size = 1; + gu_draw_buffer.frame_width = 0; + gu_draw_buffer.frame_buffer = 0; + gu_draw_buffer.disp_buffer = 0; + gu_draw_buffer.depth_buffer = 0; + gu_draw_buffer.depth_width = 0; + gu_draw_buffer.width = 480; + gu_draw_buffer.height = 272; + + for (i = 0; i < 3; ++i) + { + GuContext* context = &gu_contexts[i]; + + context->scissor_enable = 0; + context->scissor_start[0] = 0; + context->scissor_start[1] = 0; + context->scissor_end[0] = 0; + context->scissor_end[1] = 0; + + context->near_plane = 0; + context->far_plane = 1; + + context->depth_offset = 0; + context->fragment_2x = 0; + context->texture_function = 0; + context->texture_proj_map_mode = 0; + context->texture_map_mode = 0; + context->sprite_mode[0] = 0; + context->sprite_mode[1] = 0; + context->sprite_mode[2] = 0; + context->sprite_mode[3] = 0; + context->clear_color = 0; + context->clear_stencil = 0; + context->clear_depth = 0xffff; + context->texture_mode = 0; + } + + gu_settings.sig = 0; + gu_settings.fin = 0; +} diff --git a/src/gu/sceGuAlphaFunc.c b/src/gu/sceGuAlphaFunc.c new file mode 100644 index 00000000..2d07b4d7 --- /dev/null +++ b/src/gu/sceGuAlphaFunc.c @@ -0,0 +1,15 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuAlphaFunc(int a0, int a1, int a2) +{ + int arg = a0 | ((a1 & 0xff) << 8) | ((a2 & 0xff) << 16); + sendCommandi(219,arg); +} diff --git a/src/gu/sceGuAmbient.c b/src/gu/sceGuAmbient.c new file mode 100644 index 00000000..f27607f2 --- /dev/null +++ b/src/gu/sceGuAmbient.c @@ -0,0 +1,15 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuAmbient(unsigned int color) +{ + sendCommandi(92,(color & 0xffffff)); + sendCommandi(93,(color >> 24)); +} diff --git a/src/gu/sceGuAmbientColor.c b/src/gu/sceGuAmbientColor.c new file mode 100644 index 00000000..71efaaf9 --- /dev/null +++ b/src/gu/sceGuAmbientColor.c @@ -0,0 +1,15 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuAmbientColor(unsigned int color) +{ + sendCommandi(85,color & 0xffffff); + sendCommandi(88,color >> 24); +} diff --git a/src/gu/sceGuBeginObject.c b/src/gu/sceGuBeginObject.c new file mode 100644 index 00000000..11f35678 --- /dev/null +++ b/src/gu/sceGuBeginObject.c @@ -0,0 +1,37 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuBeginObject(int vertex_type, int a1, const void* indices, const void* vertices) +{ + if (vertex_type) + sendCommandi(18,vertex_type); + + if (indices) + { + sendCommandi(16,(((unsigned int)indices) >> 8) & 0xf0000); + sendCommandi(2,((unsigned int)indices) & 0xffffff); + } + + if (vertices) + { + sendCommandi(16,(((unsigned int)vertices) >> 8) & 0x0f0000); + sendCommandi(1,((unsigned int)vertices) & 0xffffff); + } + + sendCommandi(7,a1); + + // store start to new object + + gu_object_stack[gu_object_stack_depth++] = gu_list->current; + + // dummy commands, overwritten in sceGuEndObject() + sendCommandi(16,0); + sendCommandi(9,0); +} diff --git a/src/gu/sceGuBlendFunc.c b/src/gu/sceGuBlendFunc.c new file mode 100644 index 00000000..424b6104 --- /dev/null +++ b/src/gu/sceGuBlendFunc.c @@ -0,0 +1,16 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuBlendFunc(int op, int src, int dest, unsigned int srcfix, unsigned int destfix) +{ + sendCommandi(223,src | (dest << 4) | (op << 8)); + sendCommandi(224,srcfix & 0xffffff); + sendCommandi(225,destfix & 0xffffff); +} diff --git a/src/gu/sceGuBoneMatrix.c b/src/gu/sceGuBoneMatrix.c new file mode 100644 index 00000000..707d87f8 --- /dev/null +++ b/src/gu/sceGuBoneMatrix.c @@ -0,0 +1,25 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuBoneMatrix(unsigned int index, const ScePspFMatrix4* matrix) +{ + unsigned int offset = ((index << 1)+index) << 2; // 3*4 matrix + unsigned int i,j; + const float* fmatrix = (const float*)matrix; + + sendCommandi(42,offset); + for (i = 0; i < 4; ++i) + { + for (j = 0; j < 3; ++j) + { + sendCommandf(43,fmatrix[j+(i << 2)]); + } + } +} diff --git a/src/gu/sceGuBreak.c b/src/gu/sceGuBreak.c new file mode 100644 index 00000000..64bee925 --- /dev/null +++ b/src/gu/sceGuBreak.c @@ -0,0 +1,15 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuBreak(int a0) +{ + // FIXME + //sceGeBreak(a0,0x527a68); +} diff --git a/src/gu/sceGuCallList.c b/src/gu/sceGuCallList.c new file mode 100644 index 00000000..24093479 --- /dev/null +++ b/src/gu/sceGuCallList.c @@ -0,0 +1,26 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuCallList(const void* list) +{ + unsigned int list_addr = (unsigned int)list; + + if (gu_call_mode == 1) + { + sendCommandi(14,(list_addr >> 16) | 0x110000); + sendCommandi(12,list_addr & 0xffff); + sendCommandiStall(0,0); + } + else + { + sendCommandi(16,(list_addr >> 8) & 0xf0000); + sendCommandiStall(10,list_addr & 0xffffff); + } +} diff --git a/src/gu/sceGuCallMode.c b/src/gu/sceGuCallMode.c new file mode 100644 index 00000000..afd2fadc --- /dev/null +++ b/src/gu/sceGuCallMode.c @@ -0,0 +1,14 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuCallMode(int mode) +{ + gu_call_mode = mode; +} diff --git a/src/gu/sceGuCheckList.c b/src/gu/sceGuCheckList.c new file mode 100644 index 00000000..1e87e5fa --- /dev/null +++ b/src/gu/sceGuCheckList.c @@ -0,0 +1,14 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +int sceGuCheckList(void) +{ + return ((int)gu_list->current)-((int)gu_list->start); +} diff --git a/src/gu/sceGuClear.c b/src/gu/sceGuClear.c new file mode 100644 index 00000000..c9297300 --- /dev/null +++ b/src/gu/sceGuClear.c @@ -0,0 +1,74 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuClear(int flags) +{ + GuContext* context = &gu_contexts[gu_curr_context]; + unsigned int filter; + struct Vertex + { + u32 color; + u16 x,y,z; + u16 pad; + }; + + switch (gu_draw_buffer.pixel_size) + { + case 0: filter = context->clear_color & 0xffffff; break; + case 1: filter = (context->clear_color & 0xffffff) | (context->clear_stencil << 31); break; + case 2: filter = (context->clear_color & 0xffffff) | (context->clear_stencil << 28); break; + case 3: filter = (context->clear_color & 0xffffff) | (context->clear_stencil << 24); break; + default: filter = 0; break; + } + + struct Vertex* vertices; + int count; + + if (!(flags & GU_FAST_CLEAR_BIT)) + { + vertices = (struct Vertex*)sceGuGetMemory(2 * sizeof(struct Vertex)); + count = 2; + + vertices[0].color = 0; + vertices[0].x = 0; + vertices[0].y = 0; + vertices[0].z = context->clear_depth; + + vertices[1].color = filter; + vertices[1].x = gu_draw_buffer.width; + vertices[1].y = gu_draw_buffer.height; + vertices[1].z = context->clear_depth; + } + else + { + struct Vertex* curr; + unsigned int i; + count = ((gu_draw_buffer.width+63)/64)*2; + vertices = (struct Vertex*)sceGuGetMemory(count * sizeof(struct Vertex)); + curr = vertices; + + for (i = 0; i < count; ++i, ++curr) + { + unsigned int j,k; + + j = i >> 1; + k = (i & 1); + + curr->color = filter; + curr->x = (j+k) * 64; + curr->y = k * gu_draw_buffer.height; + curr->z = context->clear_depth; + } + } + + sendCommandi(211,((flags & (GU_COLOR_BUFFER_BIT|GU_STENCIL_BUFFER_BIT|GU_DEPTH_BUFFER_BIT)) << 8) | 0x01); + sceGuDrawArray(GU_SPRITES,GU_COLOR_8888|GU_VERTEX_16BIT|GU_TRANSFORM_2D,count,0,vertices); + sendCommandi(211,0); +} diff --git a/src/gu/sceGuClearColor.c b/src/gu/sceGuClearColor.c new file mode 100644 index 00000000..0f91ce37 --- /dev/null +++ b/src/gu/sceGuClearColor.c @@ -0,0 +1,15 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuClearColor(unsigned int color) +{ + GuContext* context = &gu_contexts[gu_curr_context]; + context->clear_color = color; +} diff --git a/src/gu/sceGuClearDepth.c b/src/gu/sceGuClearDepth.c new file mode 100644 index 00000000..8595ffe3 --- /dev/null +++ b/src/gu/sceGuClearDepth.c @@ -0,0 +1,15 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuClearDepth(unsigned int depth) +{ + GuContext* context = &gu_contexts[gu_curr_context]; + context->clear_depth = depth; +} diff --git a/src/gu/sceGuClearStencil.c b/src/gu/sceGuClearStencil.c new file mode 100644 index 00000000..428b35fb --- /dev/null +++ b/src/gu/sceGuClearStencil.c @@ -0,0 +1,15 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuClearStencil(unsigned int stencil) +{ + GuContext* context = &gu_contexts[gu_curr_context]; + context->clear_stencil = stencil; +} diff --git a/src/gu/sceGuClutLoad.c b/src/gu/sceGuClutLoad.c new file mode 100644 index 00000000..eedb601d --- /dev/null +++ b/src/gu/sceGuClutLoad.c @@ -0,0 +1,16 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuClutLoad(int num_blocks, const void* cbp) +{ + sendCommandi(176,((unsigned int)cbp) & 0xffffff); + sendCommandi(177,(((unsigned int)cbp) >> 8) & 0xf0000); + sendCommandi(196,num_blocks); +} diff --git a/src/gu/sceGuClutMode.c b/src/gu/sceGuClutMode.c new file mode 100644 index 00000000..d88c69a1 --- /dev/null +++ b/src/gu/sceGuClutMode.c @@ -0,0 +1,15 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuClutMode(unsigned int cpsm, unsigned int shift, unsigned int mask, unsigned int a3) +{ + unsigned int argument = (cpsm) | (shift << 2) | (mask << 8) | (a3 << 16); + sendCommandi(197,argument); +} diff --git a/src/gu/sceGuColor.c b/src/gu/sceGuColor.c new file mode 100644 index 00000000..d33f41c5 --- /dev/null +++ b/src/gu/sceGuColor.c @@ -0,0 +1,14 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuColor(unsigned int color) +{ + sceGuMaterial(7,color); +} diff --git a/src/gu/sceGuColorFunc.c b/src/gu/sceGuColorFunc.c new file mode 100644 index 00000000..9d09a59b --- /dev/null +++ b/src/gu/sceGuColorFunc.c @@ -0,0 +1,16 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuColorFunc(int func, unsigned int color, unsigned int mask) +{ + sendCommandi(216,func & 0x03); + sendCommandi(217,color & 0xffffff); + sendCommandi(218,mask); +} diff --git a/src/gu/sceGuColorMaterial.c b/src/gu/sceGuColorMaterial.c new file mode 100644 index 00000000..9ff38fc1 --- /dev/null +++ b/src/gu/sceGuColorMaterial.c @@ -0,0 +1,14 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuColorMaterial(int a0) +{ + sendCommandi(83,a0); +} diff --git a/src/gu/sceGuContinue.c b/src/gu/sceGuContinue.c new file mode 100644 index 00000000..e529edb0 --- /dev/null +++ b/src/gu/sceGuContinue.c @@ -0,0 +1,15 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuContinue(void) +{ + // FIXME + //sceGeContinue(); +} diff --git a/src/gu/sceGuCopyImage.c b/src/gu/sceGuCopyImage.c new file mode 100644 index 00000000..4201ffd7 --- /dev/null +++ b/src/gu/sceGuCopyImage.c @@ -0,0 +1,21 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuCopyImage(int psm, int sx, int sy, int width, int height, int srcw, void* src, int dx, int dy, int destw, void* dest) +{ + sendCommandi(178,((unsigned int)src) & 0xffffff); + sendCommandi(179,((((unsigned int)src) & 0xff000000) >> 8)|srcw); + sendCommandi(235,(sy << 10)|sx); + sendCommandi(180,((unsigned int)dest) & 0xffffff); + sendCommandi(181,((((unsigned int)dest) & 0xff000000) >> 8)|destw); + sendCommandi(236,(dy << 10)|dx); + sendCommandi(238,((height-1) << 10)|(width-1)); + sendCommandi(234,(psm ^ 0x03) ? 0 : 1); +} diff --git a/src/gu/sceGuDepthBuffer.c b/src/gu/sceGuDepthBuffer.c new file mode 100644 index 00000000..4c788fc4 --- /dev/null +++ b/src/gu/sceGuDepthBuffer.c @@ -0,0 +1,20 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuDepthBuffer(void* zbp, int zbw) +{ + gu_draw_buffer.depth_buffer = zbp; + + if (!gu_draw_buffer.depth_width || (gu_draw_buffer.depth_width != zbw)) + gu_draw_buffer.depth_width = zbw; + + sendCommandi(158,((unsigned int)zbp) & 0xffffff); + sendCommandi(159,((((unsigned int)zbp) & 0xff000000) >> 8)|zbw); +} diff --git a/src/gu/sceGuDepthFunc.c b/src/gu/sceGuDepthFunc.c new file mode 100644 index 00000000..a92586a7 --- /dev/null +++ b/src/gu/sceGuDepthFunc.c @@ -0,0 +1,14 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuDepthFunc(int function) +{ + sendCommandi(222,function); +} diff --git a/src/gu/sceGuDepthMask.c b/src/gu/sceGuDepthMask.c new file mode 100644 index 00000000..58876451 --- /dev/null +++ b/src/gu/sceGuDepthMask.c @@ -0,0 +1,14 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuDepthMask(int mask) +{ + sendCommandi(231,mask); +} diff --git a/src/gu/sceGuDepthOffset.c b/src/gu/sceGuDepthOffset.c new file mode 100644 index 00000000..fd2997f9 --- /dev/null +++ b/src/gu/sceGuDepthOffset.c @@ -0,0 +1,17 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuDepthOffset(unsigned int offset) +{ + GuContext* context = &gu_contexts[gu_curr_context]; + context->depth_offset = offset; + + sceGuDepthRange(context->near_plane,context->far_plane); +} diff --git a/src/gu/sceGuDepthRange.c b/src/gu/sceGuDepthRange.c new file mode 100644 index 00000000..772ca19a --- /dev/null +++ b/src/gu/sceGuDepthRange.c @@ -0,0 +1,34 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuDepthRange(int near, int far) +{ + GuContext* context = &gu_contexts[gu_curr_context]; + + unsigned int max = (unsigned int)near + (unsigned int)far; + int val = (int)((max >> 31) + max); + float z = (float)(val >> 1); + + context->near_plane = near; + context->far_plane = far; + + sendCommandf(68,z - ((float)near)); + sendCommandf(71,z + ((float)context->depth_offset)); + + if (near > far) + { + int temp = near; + near = far; + far = temp; + } + + sendCommandi(214,near); + sendCommandi(215,far); +} diff --git a/src/gu/sceGuDisable.c b/src/gu/sceGuDisable.c new file mode 100644 index 00000000..e1f2882a --- /dev/null +++ b/src/gu/sceGuDisable.c @@ -0,0 +1,54 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuDisable(int state) +{ + switch(state) + { + case GU_ALPHA_TEST: sendCommandi(34,0); break; + case GU_DEPTH_TEST: sendCommandi(35,0); break; + case GU_SCISSOR_TEST: + { + GuContext* context = &gu_contexts[gu_curr_context]; + context->scissor_enable = 0; + sendCommandi(212,0); + sendCommandi(213,((gu_draw_buffer.height-1) << 10)|(gu_draw_buffer.width-1)); + } + break; + case GU_STENCIL_TEST: sendCommandi(36,0); break; + case GU_BLEND: sendCommandi(33,0); break; + case GU_CULL_FACE: sendCommandi(29,0); break; + case GU_DITHER: sendCommandi(32,0); break; + case GU_FOG: sendCommandi(31,0); break; + case GU_CLIP_PLANES: sendCommandi(28,0); break; + case GU_TEXTURE_2D: sendCommandi(30,0); break; + case GU_LIGHTING: sendCommandi(23,0); break; + case GU_LIGHT0: sendCommandi(24,0); break; + case GU_LIGHT1: sendCommandi(25,0); break; + case GU_LIGHT2: sendCommandi(26,0); break; + case GU_LIGHT3: sendCommandi(27,0); break; + case GU_LINE_SMOOTH: sendCommandi(37,0); break; + case GU_PATCH_CULL_FACE:sendCommandi(38,0); break; + case GU_COLOR_TEST: sendCommandi(39,0); break; + case GU_COLOR_LOGIC_OP: sendCommandi(40,0); break; + case GU_FACE_NORMAL_REVERSE:sendCommandi(81,0); break; + case GU_PATCH_FACE: sendCommandi(56,0); break; + case GU_FRAGMENT_2X: + { + GuContext* context = &gu_contexts[gu_curr_context]; + context->fragment_2x = 0; + sendCommandi(201,context->texture_function); + } + break; + } + + if (state < 22) + gu_states &= ~(1 << state); +} diff --git a/src/gu/sceGuDispBuffer.c b/src/gu/sceGuDispBuffer.c new file mode 100644 index 00000000..b321026d --- /dev/null +++ b/src/gu/sceGuDispBuffer.c @@ -0,0 +1,34 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +#include +#include + +void drawRegion(int x, int y, int width, int height) +{ + sendCommandi(21,(y << 10) | x); + sendCommandi(22,(((y + height)-1) << 10) | ((x + width)-1)); +} + +void sceGuDispBuffer(int width, int height, void* dispbp, int dispbw) +{ + gu_draw_buffer.width = width; + gu_draw_buffer.height = height; + gu_draw_buffer.disp_buffer = dispbp; + + if (!gu_draw_buffer.frame_width || (gu_draw_buffer.frame_width != dispbw)) + gu_draw_buffer.frame_width = dispbw; + + drawRegion(0,0,gu_draw_buffer.width,gu_draw_buffer.height); + sceDisplaySetMode(0,gu_draw_buffer.width,gu_draw_buffer.height); + + if (gu_display_on) + sceDisplaySetFrameBuf((void*)(((unsigned int)ge_edram_address) + ((unsigned int)gu_draw_buffer.disp_buffer)), dispbw, gu_draw_buffer.pixel_size, PSP_DISPLAY_SETBUF_NEXTFRAME); +} diff --git a/src/gu/sceGuDisplay.c b/src/gu/sceGuDisplay.c new file mode 100644 index 00000000..64acad78 --- /dev/null +++ b/src/gu/sceGuDisplay.c @@ -0,0 +1,23 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +#include +#include + +int sceGuDisplay(int state) +{ + if (state) + sceDisplaySetFrameBuf((void*)((unsigned int)ge_edram_address+(unsigned int)gu_draw_buffer.disp_buffer),gu_draw_buffer.frame_width,gu_draw_buffer.pixel_size,PSP_DISPLAY_SETBUF_NEXTFRAME); + else + sceDisplaySetFrameBuf(0,0,0,PSP_DISPLAY_SETBUF_NEXTFRAME); + + gu_display_on = state; + return state; +} diff --git a/src/gu/sceGuDrawArray.c b/src/gu/sceGuDrawArray.c new file mode 100644 index 00000000..d2cad1db --- /dev/null +++ b/src/gu/sceGuDrawArray.c @@ -0,0 +1,29 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuDrawArray(int prim, int vtype, int count, const void* indices, const void* vertices) +{ + if (vtype) + sendCommandi(18,vtype); + + if (indices) + { + sendCommandi(16,(((unsigned int)indices) >> 8) & 0xf0000); + sendCommandi(2,((unsigned int)indices) & 0xffffff); + } + + if (vertices) + { + sendCommandi(16,(((unsigned int)vertices) >> 8) & 0xf0000); + sendCommandi(1,((unsigned int)vertices) & 0xffffff); + } + + sendCommandiStall(4,(prim << 16)|count); +} diff --git a/src/gu/sceGuDrawArrayN.c b/src/gu/sceGuDrawArrayN.c new file mode 100644 index 00000000..53e306ea --- /dev/null +++ b/src/gu/sceGuDrawArrayN.c @@ -0,0 +1,36 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuDrawArrayN(int primitive_type, int vertex_type, int count, int a3, const void* indices, const void* vertices) +{ + if (vertex_type) + sendCommandi(18,vertex_type); + + if (indices) + { + sendCommandi(16,(((unsigned int)indices) >> 8) & 0xf0000); + sendCommandi(2,((unsigned int)indices) & 0xffffff); + } + + if (vertices) + { + sendCommandi(16,(((unsigned int)vertices) >> 8) & 0xf0000); + sendCommandi(1,((unsigned int)vertices) & 0xffffff); + } + + if (a3 > 0) + { + // TODO: not sure about this loop, might be off. review + int i; + for (i = a3-1; i > 0; --i) + sendCommandi(4,(primitive_type << 16)|count); + sendCommandiStall(4,(primitive_type << 16)|count); + } +} diff --git a/src/gu/sceGuDrawBezier.c b/src/gu/sceGuDrawBezier.c new file mode 100644 index 00000000..1e855d9f --- /dev/null +++ b/src/gu/sceGuDrawBezier.c @@ -0,0 +1,29 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuDrawBezier(int vertex_type, int ucount, int vcount, const void* indices, const void* vertices) +{ + if (vertex_type) + sendCommandi(18,vertex_type); + + if (indices) + { + sendCommandi(16,(((unsigned int)indices) >> 8) & 0xf0000); + sendCommandi(2,((unsigned int)indices) & 0xffffff); + } + + if (vertices) + { + sendCommandi(16,(((unsigned int)vertices) >> 8) & 0xf0000); + sendCommandi(1,((unsigned int)vertices) & 0xffffff); + } + + sendCommandi(5,(vcount << 8)|ucount); +} diff --git a/src/gu/sceGuDrawBuffer.c b/src/gu/sceGuDrawBuffer.c new file mode 100644 index 00000000..afa7bef3 --- /dev/null +++ b/src/gu/sceGuDrawBuffer.c @@ -0,0 +1,28 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuDrawBuffer(int psm, void* fbp, int frame_width) +{ + gu_draw_buffer.pixel_size = psm; + gu_draw_buffer.frame_width = frame_width; + gu_draw_buffer.frame_buffer = fbp; + + if (!gu_draw_buffer.depth_buffer && gu_draw_buffer.height) + gu_draw_buffer.depth_buffer = (void*)(((unsigned int)fbp) + (unsigned int)((gu_draw_buffer.height * frame_width) << 2)); + + if (!gu_draw_buffer.depth_width) + gu_draw_buffer.depth_width = frame_width; + + sendCommandi(210,psm); + sendCommandi(156,((unsigned int)gu_draw_buffer.frame_buffer) & 0xffffff); + sendCommandi(157,((((unsigned int)gu_draw_buffer.frame_buffer) & 0xff000000) >> 8)|gu_draw_buffer.frame_width); + sendCommandi(158,((unsigned int)gu_draw_buffer.depth_buffer) & 0xffffff); + sendCommandi(159,((((unsigned int)gu_draw_buffer.depth_buffer) & 0xff000000) >> 8)|gu_draw_buffer.depth_width); +} diff --git a/src/gu/sceGuDrawBufferList.c b/src/gu/sceGuDrawBufferList.c new file mode 100644 index 00000000..04f434a8 --- /dev/null +++ b/src/gu/sceGuDrawBufferList.c @@ -0,0 +1,16 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuDrawBufferList(int psm, void* fbp, int fbw) +{ + sendCommandi(210,psm); + sendCommandi(156,((unsigned int)fbp) & 0xffffff); + sendCommandi(157,((((unsigned int)fbp) & 0xff000000) >> 8) | fbw); +} diff --git a/src/gu/sceGuDrawSpline.c b/src/gu/sceGuDrawSpline.c new file mode 100644 index 00000000..313c6336 --- /dev/null +++ b/src/gu/sceGuDrawSpline.c @@ -0,0 +1,29 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuDrawSpline(int vertex_type, int ucount, int vcount, int uedge, int vedge, const void* indices, const void* vertices) +{ + if (vertex_type) + sendCommandi(18,vertex_type); + + if (indices) + { + sendCommandi(16,(((unsigned int)indices) >> 8) & 0xf0000); + sendCommandi(2,((unsigned int)indices) & 0xffffff); + } + + if (vertices) + { + sendCommandi(16,(((unsigned int)vertices) >> 8) & 0xf0000); + sendCommandi(1,((unsigned int)vertices) & 0xffffff); + } + + sendCommandi(6,(vedge << 18)|(uedge << 16)|(vcount << 8)|ucount); +} diff --git a/src/gu/sceGuEnable.c b/src/gu/sceGuEnable.c new file mode 100644 index 00000000..5225163d --- /dev/null +++ b/src/gu/sceGuEnable.c @@ -0,0 +1,54 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuEnable(int state) +{ + switch(state) + { + case GU_ALPHA_TEST: sendCommandi(34,1); break; + case GU_DEPTH_TEST: sendCommandi(35,1); break; + case GU_SCISSOR_TEST: + { + GuContext* context = &gu_contexts[gu_curr_context]; + context->scissor_enable = 1; + sendCommandi(212,(context->scissor_start[1]<<10)|context->scissor_start[0]); + sendCommandi(213,(context->scissor_end[1]<<10)|context->scissor_end[0]); + } + break; + case GU_STENCIL_TEST: sendCommandi(36,1); break; + case GU_BLEND: sendCommandi(33,1); break; + case GU_CULL_FACE: sendCommandi(29,1); break; + case GU_DITHER: sendCommandi(32,1); break; + case GU_FOG: sendCommandi(31,1); break; + case GU_CLIP_PLANES: sendCommandi(28,1); break; + case GU_TEXTURE_2D: sendCommandi(30,1); break; + case GU_LIGHTING: sendCommandi(23,1); break; + case GU_LIGHT0: sendCommandi(24,1); break; + case GU_LIGHT1: sendCommandi(25,1); break; + case GU_LIGHT2: sendCommandi(26,1); break; + case GU_LIGHT3: sendCommandi(27,1); break; + case GU_LINE_SMOOTH: sendCommandi(37,1); break; + case GU_PATCH_CULL_FACE:sendCommandi(38,1); break; + case GU_COLOR_TEST: sendCommandi(39,1); break; + case GU_COLOR_LOGIC_OP: sendCommandi(40,1); break; + case GU_FACE_NORMAL_REVERSE: sendCommandi(81,1); break; + case GU_PATCH_FACE: sendCommandi(56,1); break; + case GU_FRAGMENT_2X: + { + GuContext* context = &gu_contexts[gu_curr_context]; + context->fragment_2x = 0x10000; + sendCommandi(201,0x10000|context->texture_function); + } + break; + } + + if (state < 22) + gu_states |= (1 << state); +} diff --git a/src/gu/sceGuEndObject.c b/src/gu/sceGuEndObject.c new file mode 100644 index 00000000..03e3823d --- /dev/null +++ b/src/gu/sceGuEndObject.c @@ -0,0 +1,23 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuEndObject(void) +{ + // rewrite commands from sceGuBeginObject() + + unsigned int* current = gu_list->current; + gu_list->current = gu_object_stack[gu_object_stack_depth-1]; + + sendCommandi(16, (((unsigned int)current) >> 8) & 0xf0000); + sendCommandi(9, ((unsigned int)current) & 0xffffff); + gu_list->current = current; + + gu_object_stack_depth--; +} diff --git a/src/gu/sceGuFinish.c b/src/gu/sceGuFinish.c new file mode 100644 index 00000000..1e2ed371 --- /dev/null +++ b/src/gu/sceGuFinish.c @@ -0,0 +1,81 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +int sceGuFinish(void) +{ + switch (gu_curr_context) + { + case GU_DIRECT: + case GU_SEND: + { + sendCommandi(15,0); + sendCommandiStall(12,0); + } + break; + + case GU_CALL: + { + if (gu_call_mode == 1) + { + sendCommandi(14,0x120000); + sendCommandi(12,0); + sendCommandiStall(0,0); + } + else + { + sendCommandi(11,0); + } + } + break; + } + + unsigned int size = ((unsigned int)gu_list->current) - ((unsigned int)gu_list->start); + + // go to parent list + gu_curr_context = gu_list->parent_context; + gu_list = &gu_contexts[gu_curr_context].list; + return size; +} + +int sceGuFinishId(unsigned int id) +{ + switch (gu_curr_context) + { + case GU_DIRECT: + case GU_SEND: + { + sendCommandi(15,id & 0xffff); + sendCommandiStall(12,0); + } + break; + + case GU_CALL: + { + if (gu_call_mode == 1) + { + sendCommandi(14,0x120000); + sendCommandi(12,0); + sendCommandiStall(0,0); + } + else + { + sendCommandi(11,0); + } + } + break; + } + + unsigned int size = ((unsigned int)gu_list->current) - ((unsigned int)gu_list->start); + + // go to parent list + gu_curr_context = gu_list->parent_context; + gu_list = &gu_contexts[gu_curr_context].list; + return size; +} diff --git a/src/gu/sceGuFog.c b/src/gu/sceGuFog.c new file mode 100644 index 00000000..481b0ee2 --- /dev/null +++ b/src/gu/sceGuFog.c @@ -0,0 +1,21 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuFog(float near, float far, unsigned int color) +{ + float distance = far-near; + + if (distance) + distance = 1.0f / distance; + + sendCommandi(207,color & 0xffffff); + sendCommandf(205,far); + sendCommandf(206,distance); +} diff --git a/src/gu/sceGuFrontFace.c b/src/gu/sceGuFrontFace.c new file mode 100644 index 00000000..526dbe2c --- /dev/null +++ b/src/gu/sceGuFrontFace.c @@ -0,0 +1,17 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuFrontFace(int order) +{ + if (order) + sendCommandi(155,0); + else + sendCommandi(155,1); +} diff --git a/src/gu/sceGuGetAllStatus.c b/src/gu/sceGuGetAllStatus.c new file mode 100644 index 00000000..1706cf5b --- /dev/null +++ b/src/gu/sceGuGetAllStatus.c @@ -0,0 +1,14 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +int sceGuGetAllStatus(void) +{ + return gu_states; +} diff --git a/src/gu/sceGuGetMemory.c b/src/gu/sceGuGetMemory.c new file mode 100644 index 00000000..c7817b96 --- /dev/null +++ b/src/gu/sceGuGetMemory.c @@ -0,0 +1,36 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +#include +#include + +void* sceGuGetMemory(int size) +{ + // some kind of 4-byte alignment? + size += 3; + size += ((unsigned int)(size >> 31)) >> 30; + size = (size >> 2) << 2; + + unsigned int* orig_ptr = gu_list->current; + unsigned int* new_ptr = (unsigned int*)(((unsigned int)orig_ptr) + size + 8); + + int lo = (8 << 24) | (((unsigned int)new_ptr) & 0xffffff); + int hi = (16 << 24) | ((((unsigned int)new_ptr) >> 8) & 0xf0000); + + orig_ptr[0] = hi; + orig_ptr[1] = lo; + + gu_list->current = new_ptr; + + if (!gu_curr_context) + sceGeListUpdateStallAddr(ge_list_executed[0],new_ptr); + + return orig_ptr + 2; +} diff --git a/src/gu/sceGuGetStatus.c b/src/gu/sceGuGetStatus.c new file mode 100644 index 00000000..a35f537c --- /dev/null +++ b/src/gu/sceGuGetStatus.c @@ -0,0 +1,16 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +int sceGuGetStatus(int state) +{ + if (state < 22) + return (gu_states >> state) & 1; + return 0; +} diff --git a/src/gu/sceGuInit.c b/src/gu/sceGuInit.c new file mode 100644 index 00000000..8a5f06fb --- /dev/null +++ b/src/gu/sceGuInit.c @@ -0,0 +1,72 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +#include +#include +#include + +unsigned int __attribute__((aligned(16))) ge_init_list[] = +{ + 0x01000000, 0x02000000, 0x10000000, 0x12000000, 0x13000000, 0x15000000, 0x16000000, 0x17000000, + 0x18000000, 0x19000000, 0x1a000000, 0x1b000000, 0x1c000000, 0x1d000000, 0x1e000000, 0x1f000000, + 0x20000000, 0x21000000, 0x22000000, 0x23000000, 0x24000000, 0x25000000, 0x26000000, 0x27000000, + 0x28000000, 0x2a000000, 0x2b000000, 0x2c000000, 0x2d000000, 0x2e000000, 0x2f000000, 0x30000000, + 0x31000000, 0x32000000, 0x33000000, 0x36000000, 0x37000000, 0x38000000, 0x3a000000, 0x3b000000, + 0x3c000000, 0x3d000000, 0x3e000000, 0x3f000000, 0x40000000, 0x41000000, 0x42000000, 0x43000000, + 0x44000000, 0x45000000, 0x46000000, 0x47000000, 0x48000000, 0x49000000, 0x4a000000, 0x4b000000, + 0x4c000000, 0x4d000000, 0x50000000, 0x51000000, 0x53000000, 0x54000000, 0x55000000, 0x56000000, + 0x57000000, 0x58000000, 0x5b000000, 0x5c000000, 0x5d000000, 0x5e000000, 0x5f000000, 0x60000000, + 0x61000000, 0x62000000, 0x63000000, 0x64000000, 0x65000000, 0x66000000, 0x67000000, 0x68000000, + 0x69000000, 0x6a000000, 0x6b000000, 0x6c000000, 0x6d000000, 0x6e000000, 0x6f000000, 0x70000000, + 0x71000000, 0x72000000, 0x73000000, 0x74000000, 0x75000000, 0x76000000, 0x77000000, 0x78000000, + 0x79000000, 0x7a000000, 0x7b000000, 0x7c000000, 0x7d000000, 0x7e000000, 0x7f000000, 0x80000000, + 0x81000000, 0x82000000, 0x83000000, 0x84000000, 0x85000000, 0x86000000, 0x87000000, 0x88000000, + 0x89000000, 0x8a000000, 0x8b000000, 0x8c000000, 0x8d000000, 0x8e000000, 0x8f000000, 0x90000000, + 0x91000000, 0x92000000, 0x93000000, 0x94000000, 0x95000000, 0x96000000, 0x97000000, 0x98000000, + 0x99000000, 0x9a000000, 0x9b000000, 0x9c000000, 0x9d000000, 0x9e000000, 0x9f000000, 0xa0000000, + 0xa1000000, 0xa2000000, 0xa3000000, 0xa4000000, 0xa5000000, 0xa6000000, 0xa7000000, 0xa8040004, + 0xa9000000, 0xaa000000, 0xab000000, 0xac000000, 0xad000000, 0xae000000, 0xaf000000, 0xb0000000, + 0xb1000000, 0xb2000000, 0xb3000000, 0xb4000000, 0xb5000000, 0xb8000101, 0xb9000000, 0xba000000, + 0xbb000000, 0xbc000000, 0xbd000000, 0xbe000000, 0xbf000000, 0xc0000000, 0xc1000000, 0xc2000000, + 0xc3000000, 0xc4000000, 0xc5000000, 0xc6000000, 0xc7000000, 0xc8000000, 0xc9000000, 0xca000000, + 0xcb000000, 0xcc000000, 0xcd000000, 0xce000000, 0xcf000000, 0xd0000000, 0xd2000000, 0xd3000000, + 0xd4000000, 0xd5000000, 0xd6000000, 0xd7000000, 0xd8000000, 0xd9000000, 0xda000000, 0xdb000000, + 0xdc000000, 0xdd000000, 0xde000000, 0xdf000000, 0xe0000000, 0xe1000000, 0xe2000000, 0xe3000000, + 0xe4000000, 0xe5000000, 0xe6000000, 0xe7000000, 0xe8000000, 0xe9000000, 0xeb000000, 0xec000000, + 0xee000000, 0xf0000000, 0xf1000000, 0xf2000000, 0xf3000000, 0xf4000000, 0xf5000000, 0xf6000000, + 0xf7000000, 0xf8000000, 0xf9000000, + 0x0f000000, 0x0c000000, 0, 0 +}; + + +void sceGuInit(void) +{ + PspGeCallbackData callback; + callback.signal_func = callbackSig; + callback.signal_arg = &gu_settings; + callback.finish_func = callbackFin; + callback.finish_arg = &gu_settings; + gu_settings.ge_callback_id = sceGeSetCallback(&callback); + + gu_settings.swapBuffersCallback = 0; + gu_settings.swapBuffersBehaviour = PSP_DISPLAY_SETBUF_IMMEDIATE; + + ge_edram_address = sceGeEdramGetAddr(); + + // initialize graphics hardware + ge_list_executed[0] = sceGeListEnQueue((void*)((unsigned int)ge_init_list & 0x1fffffff),0,gu_settings.ge_callback_id,0); + + resetValues(); + + gu_settings.kernel_event_flag = sceKernelCreateEventFlag("SceGuSignal",512,3,0); + + // wait for init to complete + sceGeListSync(ge_list_executed[0],0); +} diff --git a/src/gu/sceGuLight.c b/src/gu/sceGuLight.c new file mode 100644 index 00000000..1e6683f3 --- /dev/null +++ b/src/gu/sceGuLight.c @@ -0,0 +1,24 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuLight(int light, int type, int components, const ScePspFVector3* position) +{ + GuLightSettings* settings = &light_settings[light]; + + sendCommandf(settings->xpos,position->x); + sendCommandf(settings->ypos,position->y); + sendCommandf(settings->zpos,position->z); + + int kind = 2; + if (components != 8) + kind = (components^6) < 1 ? 1 : 0; + + sendCommandi(settings->type,((type & 0x03) << 8)|kind); +} diff --git a/src/gu/sceGuLightAtt.c b/src/gu/sceGuLightAtt.c new file mode 100644 index 00000000..2bb2199c --- /dev/null +++ b/src/gu/sceGuLightAtt.c @@ -0,0 +1,18 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuLightAtt(int light, float atten0, float atten1, float atten2) +{ + GuLightSettings* settings = &light_settings[light]; + + sendCommandf(settings->constant,atten0); + sendCommandf(settings->linear,atten1); + sendCommandf(settings->quadratic,atten2); +} diff --git a/src/gu/sceGuLightColor.c b/src/gu/sceGuLightColor.c new file mode 100644 index 00000000..bd1a3e70 --- /dev/null +++ b/src/gu/sceGuLightColor.c @@ -0,0 +1,34 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuLightColor(int light, int component, unsigned int color) +{ + GuLightSettings* settings = &light_settings[light]; + + switch (component) + { + case GU_AMBIENT: sendCommandi(settings->ambient, color & 0xffffff); break; + case GU_DIFFUSE: sendCommandi(settings->diffuse, color & 0xffffff); break; + case GU_AMBIENT_AND_DIFFUSE: + { + sendCommandi(settings->ambient, color & 0xffffff); break; + sendCommandi(settings->diffuse, color & 0xffffff); break; + } + break; + + case GU_SPECULAR: sendCommandi(settings->specular, color & 0xffffff); break; + case GU_DIFFUSE_AND_SPECULAR: + { + sendCommandi(settings->diffuse, color & 0xffffff); break; + sendCommandi(settings->specular, color & 0xffffff); break; + } + break; + } +} diff --git a/src/gu/sceGuLightMode.c b/src/gu/sceGuLightMode.c new file mode 100644 index 00000000..a04924ee --- /dev/null +++ b/src/gu/sceGuLightMode.c @@ -0,0 +1,14 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuLightMode(int mode) +{ + sendCommandi(94,mode); +} diff --git a/src/gu/sceGuLightSpot.c b/src/gu/sceGuLightSpot.c new file mode 100644 index 00000000..3b8de9ed --- /dev/null +++ b/src/gu/sceGuLightSpot.c @@ -0,0 +1,21 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuLightSpot(int light, const ScePspFVector3* direction, float exponent, float cutoff) +{ + GuLightSettings* settings = &light_settings[light]; + + sendCommandf(settings->exponent,exponent); + sendCommandf(settings->cutoff,cutoff); + + sendCommandf(settings->xdir,direction->x); + sendCommandf(settings->ydir,direction->y); + sendCommandf(settings->zdir,direction->z); +} diff --git a/src/gu/sceGuLogicalOp.c b/src/gu/sceGuLogicalOp.c new file mode 100644 index 00000000..1b29726a --- /dev/null +++ b/src/gu/sceGuLogicalOp.c @@ -0,0 +1,14 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuLogicalOp(int op) +{ + sendCommandi(230,op & 0x0f); +} diff --git a/src/gu/sceGuMaterial.c b/src/gu/sceGuMaterial.c new file mode 100644 index 00000000..1c5ada20 --- /dev/null +++ b/src/gu/sceGuMaterial.c @@ -0,0 +1,24 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuMaterial(int mode, int color) +{ + if (mode & 0x01) + { + sendCommandi(85, color & 0xffffff); + sendCommandi(88, color >> 24); + } + + if (mode & 0x02) + sendCommandi(86, color & 0xffffff); + + if (mode & 0x04) + sendCommandi(87, color & 0xffffff); +} diff --git a/src/gu/sceGuModelColor.c b/src/gu/sceGuModelColor.c new file mode 100644 index 00000000..f3c24613 --- /dev/null +++ b/src/gu/sceGuModelColor.c @@ -0,0 +1,17 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuModelColor(unsigned int emissive, unsigned int ambient, unsigned int diffuse, unsigned int specular) +{ + sendCommandi(84, emissive & 0xffffff); + sendCommandi(86, diffuse & 0xffffff); + sendCommandi(85, ambient & 0xffffff); + sendCommandi(87, specular & 0xffffff); +} diff --git a/src/gu/sceGuMorphWeight.c b/src/gu/sceGuMorphWeight.c new file mode 100644 index 00000000..01eabf09 --- /dev/null +++ b/src/gu/sceGuMorphWeight.c @@ -0,0 +1,14 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuMorphWeight(int index,float weight) +{ + sendCommandf(44 + index,weight); +} diff --git a/src/gu/sceGuOffset.c b/src/gu/sceGuOffset.c new file mode 100644 index 00000000..ab20d99f --- /dev/null +++ b/src/gu/sceGuOffset.c @@ -0,0 +1,15 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuOffset(unsigned int x, unsigned int y) +{ + sendCommandi(76,x << 4); + sendCommandi(77,y << 4); +} diff --git a/src/gu/sceGuPatchDivide.c b/src/gu/sceGuPatchDivide.c new file mode 100644 index 00000000..5c4b7acb --- /dev/null +++ b/src/gu/sceGuPatchDivide.c @@ -0,0 +1,14 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuPatchDivide(unsigned int a0, unsigned int a1) +{ + sendCommandi(54,(a1 << 8)|a0); +} diff --git a/src/gu/sceGuPatchFrontFace.c b/src/gu/sceGuPatchFrontFace.c new file mode 100644 index 00000000..d400b58f --- /dev/null +++ b/src/gu/sceGuPatchFrontFace.c @@ -0,0 +1,14 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuPatchFrontFace(unsigned int a0) +{ + sendCommandi(56,a0); +} diff --git a/src/gu/sceGuPatchPrim.c b/src/gu/sceGuPatchPrim.c new file mode 100644 index 00000000..4b7e8ba4 --- /dev/null +++ b/src/gu/sceGuPatchPrim.c @@ -0,0 +1,19 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuPatchPrim(int prim) +{ + switch(prim) + { + case GU_POINTS: sendCommandi(55,2); break; + case GU_LINE_STRIP: sendCommandi(55,1); break; + case GU_TRIANGLE_STRIP: sendCommandi(55,0); break; + } +} diff --git a/src/gu/sceGuPixelMask.c b/src/gu/sceGuPixelMask.c new file mode 100644 index 00000000..9fbfb4ff --- /dev/null +++ b/src/gu/sceGuPixelMask.c @@ -0,0 +1,15 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuPixelMask(unsigned int mask) +{ + sendCommandi(232,mask & 0xffffff); + sendCommandi(233,mask >> 24); +} diff --git a/src/gu/sceGuScissor.c b/src/gu/sceGuScissor.c new file mode 100644 index 00000000..5180567c --- /dev/null +++ b/src/gu/sceGuScissor.c @@ -0,0 +1,25 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuScissor(int x, int y, int w, int h) +{ + GuContext* context = &gu_contexts[gu_curr_context]; + + context->scissor_start[0] = x; + context->scissor_start[1] = y; + context->scissor_end[0] = w-1; + context->scissor_end[1] = h-1; + + if (context->scissor_enable) + { + sendCommandi(212,(context->scissor_start[1] << 10)|context->scissor_start[0]); + sendCommandi(213,(context->scissor_end[1] << 10)|context->scissor_end[0]); + } +} diff --git a/src/gu/sceGuSendCommandf.c b/src/gu/sceGuSendCommandf.c new file mode 100644 index 00000000..18c05e0d --- /dev/null +++ b/src/gu/sceGuSendCommandf.c @@ -0,0 +1,14 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuSendCommandf(int cmd, float argument) +{ + sendCommandf(cmd,argument); +} diff --git a/src/gu/sceGuSendCommandi.c b/src/gu/sceGuSendCommandi.c new file mode 100644 index 00000000..d2aeb0a8 --- /dev/null +++ b/src/gu/sceGuSendCommandi.c @@ -0,0 +1,14 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuSendCommandi(int cmd, int argument) +{ + sendCommandi(cmd,argument); +} diff --git a/src/gu/sceGuSendList.c b/src/gu/sceGuSendList.c new file mode 100644 index 00000000..459d0dd8 --- /dev/null +++ b/src/gu/sceGuSendList.c @@ -0,0 +1,33 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +#include +#include + +void sceGuSendList(int mode, const void* list, PspGeContext* context) +{ + gu_settings.signal_offset = 0; + + // TODO: figure out this structure + PspGeListArgs args; + args.size = 8; // Size of structure? + args.context = context; + + int list_id = 0; + int callback = gu_settings.ge_callback_id; + + switch (mode) + { + case GU_HEAD: list_id = sceGeListEnQueueHead(list,0,callback,&args); break; + case GU_TAIL: list_id = sceGeListEnQueue(list,0,callback,&args); break; + } + + ge_list_executed[1] = list_id; +} diff --git a/src/gu/sceGuSetAllStatus.c b/src/gu/sceGuSetAllStatus.c new file mode 100644 index 00000000..5f82fed0 --- /dev/null +++ b/src/gu/sceGuSetAllStatus.c @@ -0,0 +1,21 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuSetAllStatus(int status) +{ + unsigned int i; + for (i = 0; i < 22; ++i) + { + if ((status >> i)&1) + sceGuEnable(i); + else + sceGuDisable(i); + } +} diff --git a/src/gu/sceGuSetCallback.c b/src/gu/sceGuSetCallback.c new file mode 100644 index 00000000..6431bd15 --- /dev/null +++ b/src/gu/sceGuSetCallback.c @@ -0,0 +1,33 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void* sceGuSetCallback(int signal, GuCallback callback) +{ + GuCallback old_callback = 0; + + switch (signal) + { + case GU_CALLBACK_SIGNAL: + { + old_callback = gu_settings.sig; + gu_settings.sig = callback; + } + break; + + case GU_CALLBACK_FINISH: + { + old_callback = gu_settings.fin; + gu_settings.fin = callback; + } + break; + } + + return old_callback; +} diff --git a/src/gu/sceGuSetDither.c b/src/gu/sceGuSetDither.c new file mode 100644 index 00000000..2dc03be7 --- /dev/null +++ b/src/gu/sceGuSetDither.c @@ -0,0 +1,17 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuSetDither(const ScePspIMatrix4* matrix) +{ + sendCommandi(226,(matrix->x.x & 0x0f)|((matrix->x.y & 0x0f) << 4)|((matrix->x.z & 0x0f) << 8)|((matrix->x.w & 0x0f) << 12)); + sendCommandi(227,(matrix->y.x & 0x0f)|((matrix->y.y & 0x0f) << 4)|((matrix->y.z & 0x0f) << 8)|((matrix->y.w & 0x0f) << 12)); + sendCommandi(228,(matrix->z.x & 0x0f)|((matrix->z.y & 0x0f) << 4)|((matrix->z.z & 0x0f) << 8)|((matrix->z.w & 0x0f) << 12)); + sendCommandi(229,(matrix->w.x & 0x0f)|((matrix->w.y & 0x0f) << 4)|((matrix->w.z & 0x0f) << 8)|((matrix->w.w & 0x0f) << 12)); +} diff --git a/src/gu/sceGuSetMatrix.c b/src/gu/sceGuSetMatrix.c new file mode 100644 index 00000000..ac0eea6e --- /dev/null +++ b/src/gu/sceGuSetMatrix.c @@ -0,0 +1,67 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuSetMatrix(int type, const ScePspFMatrix4* matrix) +{ + unsigned int i,j; + const float* fmatrix = (const float*)matrix; + + switch (type) + { + case 0: + { + sendCommandf(62,0); + + // 4*4 - most probably projection + for (i = 0; i < 16; ++i) + sendCommandf(63,fmatrix[i]); + } + break; + + case 1: + { + sendCommandf(60,0); + + // 4*4 -> 3*4 - view matrix? + for (i = 0; i < 4; ++i) + { + for (j = 0; j < 3; ++j) + sendCommandf(61,fmatrix[j+i*4]); + } + } + break; + + case 2: + { + sendCommandf(58,0); + + // 4*4 -> 3*4 - ??? + for (i = 0; i < 4; ++i) + { + for (j = 0; j < 3; ++j) + sendCommandf(59,fmatrix[j+i*4]); + } + } + break; + + case 3: + { + sendCommandf(64,0); + + // 4*4 -> 3*4 - ??? + for (i = 0; i < 4; ++i) + { + for (j = 0; j < 3; ++j) + sendCommandf(65,fmatrix[j+i*4]); + } + } + break; + } +} diff --git a/src/gu/sceGuSetStatus.c b/src/gu/sceGuSetStatus.c new file mode 100644 index 00000000..777d4cde --- /dev/null +++ b/src/gu/sceGuSetStatus.c @@ -0,0 +1,17 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuSetStatus(int state, int status) +{ + if (status) + sceGuEnable(state); + else + sceGuDisable(state); +} diff --git a/src/gu/sceGuShadeModel.c b/src/gu/sceGuShadeModel.c new file mode 100644 index 00000000..4e4fc97f --- /dev/null +++ b/src/gu/sceGuShadeModel.c @@ -0,0 +1,18 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuShadeModel(int mode) +{ + switch (mode) + { + case 1: sendCommandi(80,1); break; + default: sendCommandi(80,0); break; + } +} diff --git a/src/gu/sceGuSignal.c b/src/gu/sceGuSignal.c new file mode 100644 index 00000000..610368a8 --- /dev/null +++ b/src/gu/sceGuSignal.c @@ -0,0 +1,23 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuSignal(int signal, int argument) +{ + sendCommandi(14,((signal & 0xff) << 16) | (argument & 0xffff)); + sendCommandi(12,0); + + if (signal == 3) + { + sendCommandi(15,0); + sendCommandi(12,0); + } + + sendCommandiStall(0,0); +} diff --git a/src/gu/sceGuSpecular.c b/src/gu/sceGuSpecular.c new file mode 100644 index 00000000..9f860d4d --- /dev/null +++ b/src/gu/sceGuSpecular.c @@ -0,0 +1,14 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuSpecular(float power) // specular power +{ + sendCommandf(91,power); +} diff --git a/src/gu/sceGuStart.c b/src/gu/sceGuStart.c new file mode 100644 index 00000000..e8a2bceb --- /dev/null +++ b/src/gu/sceGuStart.c @@ -0,0 +1,64 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +#include +#include + +void sceGuStart(int cid, void* list) +{ + GuContext* context = &gu_contexts[cid]; + unsigned int* local_list = (unsigned int*)(((unsigned int)list) | 0x40000000); + + // setup display list + + context->list.start = local_list; + context->list.current = local_list; + context->list.parent_context = gu_curr_context; + gu_list = &context->list; + + // store current context + + gu_curr_context = cid; + + if (!cid) + { + ge_list_executed[0] = sceGeListEnQueue(local_list,local_list,gu_settings.ge_callback_id,0); + gu_settings.signal_offset = 0; + } + + if (!gu_init) + { + static int dither_matrix[16] = + { + -4, 0,-3, 1, + 2,-2, 3,-1, + -3, 1,-4, 0, + 3,-1, 2,-2 + }; + + sceGuSetDither((ScePspIMatrix4*)dither_matrix); + sceGuPatchDivide(16,16); + sceGuColorMaterial(GU_AMBIENT|GU_DIFFUSE|GU_SPECULAR); + + sceGuSpecular(1.0f); + sceGuTexScale(1.0f,1.0f); + + gu_init = 1; + } + + if (!gu_curr_context) + { + if (gu_draw_buffer.frame_width) + { + sendCommandi(156, ((unsigned int)gu_draw_buffer.frame_buffer) & 0xffffff); + sendCommandi(157, ((((unsigned int)gu_draw_buffer.frame_buffer) & 0xff000000) >> 8) | gu_draw_buffer.frame_width); + } + } +} diff --git a/src/gu/sceGuStencilFunc.c b/src/gu/sceGuStencilFunc.c new file mode 100644 index 00000000..57f19a50 --- /dev/null +++ b/src/gu/sceGuStencilFunc.c @@ -0,0 +1,14 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuStencilFunc(int func, int ref, int mask) +{ + sendCommandi(220,func | ((ref & 0xff) << 8) | ((mask & 0xff) << 16)); +} diff --git a/src/gu/sceGuStencilOp.c b/src/gu/sceGuStencilOp.c new file mode 100644 index 00000000..143aeb91 --- /dev/null +++ b/src/gu/sceGuStencilOp.c @@ -0,0 +1,14 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuStencilOp(int fail, int zfail, int zpass) +{ + sendCommandi(221,fail | (zfail << 8) | (zpass << 16)); +} diff --git a/src/gu/sceGuSwapBuffers.c b/src/gu/sceGuSwapBuffers.c new file mode 100644 index 00000000..bedce660 --- /dev/null +++ b/src/gu/sceGuSwapBuffers.c @@ -0,0 +1,43 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +#include +#include + +void* sceGuSwapBuffers(void) +{ + if (gu_settings.swapBuffersCallback) + { + gu_settings.swapBuffersCallback(&gu_draw_buffer.disp_buffer,&gu_draw_buffer.frame_buffer); + } else { + void* temp = gu_draw_buffer.disp_buffer; + gu_draw_buffer.disp_buffer = gu_draw_buffer.frame_buffer; + gu_draw_buffer.frame_buffer = temp; + } + + if (gu_display_on) + sceDisplaySetFrameBuf((void*)((unsigned int)ge_edram_address + (unsigned int)gu_draw_buffer.disp_buffer), gu_draw_buffer.frame_width, gu_draw_buffer.pixel_size, gu_settings.swapBuffersBehaviour); + + // TODO: remove this? it serves no real purpose + gu_current_frame ^= 1; + +// return (void*)gu_settings.swapBuffersBehaviour; + return gu_draw_buffer.frame_buffer; +} + +void guSwapBuffersBehaviour(int behaviour) +{ + gu_settings.swapBuffersBehaviour = behaviour; +} + +void guSwapBuffersCallback(GuSwapBuffersCallback callback) +{ + gu_settings.swapBuffersCallback = callback; +} diff --git a/src/gu/sceGuSync.c b/src/gu/sceGuSync.c new file mode 100644 index 00000000..5632d0ba --- /dev/null +++ b/src/gu/sceGuSync.c @@ -0,0 +1,23 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +#include +#include + +int sceGuSync(int mode, int what) +{ + switch (mode) + { + case 0: return sceGeDrawSync(what); + case 3: return sceGeListSync(ge_list_executed[0],what); + case 4: return sceGeListSync(ge_list_executed[1],what); + default: case 1: case 2: return 0; + } +} diff --git a/src/gu/sceGuTerm.c b/src/gu/sceGuTerm.c new file mode 100644 index 00000000..f763f5c6 --- /dev/null +++ b/src/gu/sceGuTerm.c @@ -0,0 +1,18 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +#include +#include + +void sceGuTerm(void) +{ + sceKernelDeleteEventFlag(gu_settings.kernel_event_flag); + sceGeUnsetCallback(gu_settings.ge_callback_id); +} diff --git a/src/gu/sceGuTexEnvColor.c b/src/gu/sceGuTexEnvColor.c new file mode 100644 index 00000000..ea107f5b --- /dev/null +++ b/src/gu/sceGuTexEnvColor.c @@ -0,0 +1,14 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuTexEnvColor(unsigned int color) +{ + sendCommandi(202,color & 0xffffff); +} diff --git a/src/gu/sceGuTexFilter.c b/src/gu/sceGuTexFilter.c new file mode 100644 index 00000000..e5e93897 --- /dev/null +++ b/src/gu/sceGuTexFilter.c @@ -0,0 +1,14 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuTexFilter(int min, int mag) +{ + sendCommandi(198,(mag << 8)|min); +} diff --git a/src/gu/sceGuTexFlush.c b/src/gu/sceGuTexFlush.c new file mode 100644 index 00000000..83b9802d --- /dev/null +++ b/src/gu/sceGuTexFlush.c @@ -0,0 +1,14 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuTexFlush(void) +{ + sendCommandf(203,0.0f); +} diff --git a/src/gu/sceGuTexFunc.c b/src/gu/sceGuTexFunc.c new file mode 100644 index 00000000..d79d9c7b --- /dev/null +++ b/src/gu/sceGuTexFunc.c @@ -0,0 +1,17 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuTexFunc(int tfx, int tcc) +{ + GuContext* context = &gu_contexts[gu_curr_context]; + context->texture_function = (tcc << 8) | tfx; + + sendCommandi(201,((tcc << 8)|tfx)|context->fragment_2x); +} diff --git a/src/gu/sceGuTexImage.c b/src/gu/sceGuTexImage.c new file mode 100644 index 00000000..17e6e87d --- /dev/null +++ b/src/gu/sceGuTexImage.c @@ -0,0 +1,33 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +static int tbpcmd_tbl[8] = { 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7 }; // 0x30A18 +static int tbwcmd_tbl[8] = { 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf }; // 0x30A38 +static int tsizecmd_tbl[8] = { 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf }; // 0x30A58 + +int getExp(int val) +{ + unsigned int i; + asm("clz %0, %1\n":"=r"(i):"r"(val&0x3FF)); + return 31-i; +/* + unsigned int i; + for (i = 9; (i > 0) && !((val >> i) & 1); --i); + return i; +*/ +} + +void sceGuTexImage(int mipmap, int width, int height, int tbw, const void* tbp) +{ + sendCommandi(tbpcmd_tbl[mipmap],((unsigned int)tbp) & 0xffffff); + sendCommandi(tbwcmd_tbl[mipmap],((((unsigned int)tbp) >> 8) & 0x0f0000)|tbw); + sendCommandi(tsizecmd_tbl[mipmap],(getExp(height) << 8)|(getExp(width))); + sceGuTexFlush(); +} diff --git a/src/gu/sceGuTexLevelMode.c b/src/gu/sceGuTexLevelMode.c new file mode 100644 index 00000000..ec09c295 --- /dev/null +++ b/src/gu/sceGuTexLevelMode.c @@ -0,0 +1,24 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +#include + +void sceGuTexLevelMode(unsigned int mode, float bias) +{ + int offset = (int)truncf(bias * 16.0f); + + // mip map bias? + if (offset >= 128) + offset = 128; + else if (offset < -128) + offset = -128; + + sendCommandi(200,(((unsigned int)(offset)) << 16) | mode); +} diff --git a/src/gu/sceGuTexMapMode.c b/src/gu/sceGuTexMapMode.c new file mode 100644 index 00000000..781e8ae5 --- /dev/null +++ b/src/gu/sceGuTexMapMode.c @@ -0,0 +1,19 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuTexMapMode(int mode, unsigned int a1, unsigned int a2) +{ + GuContext* context = &gu_contexts[gu_curr_context]; + + context->texture_map_mode = mode & 0x03; + + sendCommandi(192,context->texture_proj_map_mode | (mode & 0x03)); + sendCommandi(193,(a2 << 8)|(a1 & 0x03)); +} diff --git a/src/gu/sceGuTexMode.c b/src/gu/sceGuTexMode.c new file mode 100644 index 00000000..f5e70482 --- /dev/null +++ b/src/gu/sceGuTexMode.c @@ -0,0 +1,20 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuTexMode(int tpsm, int maxmips, int a2, int swizzle) +{ + GuContext* context = &gu_contexts[gu_curr_context]; + context->texture_mode = tpsm; + + sendCommandi(194,(maxmips << 16) | (a2 << 8) | (swizzle)); + sendCommandi(195,tpsm); + + sceGuTexFlush(); +} diff --git a/src/gu/sceGuTexOffset.c b/src/gu/sceGuTexOffset.c new file mode 100644 index 00000000..5717ed3d --- /dev/null +++ b/src/gu/sceGuTexOffset.c @@ -0,0 +1,15 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuTexOffset(float u, float v) +{ + sendCommandf(74,u); + sendCommandf(75,v); +} diff --git a/src/gu/sceGuTexProjMapMode.c b/src/gu/sceGuTexProjMapMode.c new file mode 100644 index 00000000..35934625 --- /dev/null +++ b/src/gu/sceGuTexProjMapMode.c @@ -0,0 +1,17 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuTexProjMapMode(int mode) +{ + GuContext* context = &gu_contexts[gu_curr_context]; + + context->texture_proj_map_mode = ((mode & 0x03) << 8); + sendCommandi(192,((mode & 0x03) << 8) | context->texture_map_mode); +} diff --git a/src/gu/sceGuTexScale.c b/src/gu/sceGuTexScale.c new file mode 100644 index 00000000..fac5fad8 --- /dev/null +++ b/src/gu/sceGuTexScale.c @@ -0,0 +1,15 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuTexScale(float u, float v) +{ + sendCommandf(72,u); + sendCommandf(73,v); +} diff --git a/src/gu/sceGuTexSlope.c b/src/gu/sceGuTexSlope.c new file mode 100644 index 00000000..181d0bdd --- /dev/null +++ b/src/gu/sceGuTexSlope.c @@ -0,0 +1,14 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuTexSlope(float slope) +{ + sendCommandf(208,slope); +} diff --git a/src/gu/sceGuTexSync.c b/src/gu/sceGuTexSync.c new file mode 100644 index 00000000..84aa0e54 --- /dev/null +++ b/src/gu/sceGuTexSync.c @@ -0,0 +1,14 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuTexSync() +{ + sendCommandi(204,0); +} diff --git a/src/gu/sceGuTexWrap.c b/src/gu/sceGuTexWrap.c new file mode 100644 index 00000000..e72cdbe1 --- /dev/null +++ b/src/gu/sceGuTexWrap.c @@ -0,0 +1,14 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuTexWrap(int u, int v) +{ + sendCommandi(199,(v << 8)|(u)); +} diff --git a/src/gu/sceGuViewport.c b/src/gu/sceGuViewport.c new file mode 100644 index 00000000..74fa2dd9 --- /dev/null +++ b/src/gu/sceGuViewport.c @@ -0,0 +1,17 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +void sceGuViewport(int cx, int cy, int width, int height) +{ + sendCommandf(66,(float)(width>>1)); + sendCommandf(67,(float)((-height)>>1)); + sendCommandf(69,(float)cx); + sendCommandf(70,(float)cy); +} diff --git a/src/gu/sendCommand.c b/src/gu/sendCommand.c new file mode 100644 index 00000000..ceb24303 --- /dev/null +++ b/src/gu/sendCommand.c @@ -0,0 +1,37 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +#include +#include + +void sendCommandi(int cmd, int argument) +{ + *(gu_list->current++) = (cmd << 24) | (argument & 0xffffff); +} + +void sendCommandf(int cmd, float argument) +{ + union + { + float f; + unsigned int i; + } t; + t.f = argument; + + sendCommandi(cmd,t.i >> 8); +} + +void sendCommandiStall(int cmd, int argument) +{ + sendCommandi(cmd,argument); + + if (!gu_object_stack_depth && !gu_curr_context) + sceGeListUpdateStallAddr(ge_list_executed[0],gu_list->current); +} diff --git a/src/gum/Makefile.am b/src/gum/Makefile.am new file mode 100644 index 00000000..4b6e48da --- /dev/null +++ b/src/gum/Makefile.am @@ -0,0 +1,59 @@ + +libdir = @PSPSDK_LIBDIR@ + +CC = @PSP_CC@ +CCAS = $(CC) +AR = @PSP_AR@ +RANLIB = @PSP_RANLIB@ + +INCLUDES = -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel -I$(top_srcdir)/src/display \ + -I$(top_srcdir)/src/ge -I$(top_srcdir)/src/user -I$(top_srcdir)/src/vfpu +CFLAGS = @PSPSDK_CFLAGS@ +CCASFLAGS = $(CFLAGS) $(INCLUDES) + +libpspgumincludedir = @PSPSDK_INCLUDEDIR@ +libpspguminclude_HEADERS = pspgum.h + +lib_LIBRARIES = libpspgum.a libpspgum_vfpu.a + +noinst_HEADERS = gumInternal.h + +PSPGUM_SHARED_OBJS = gumLoadMatrix.o gumOrtho.o gumPerspective.o \ + gumLookAt.o gumRotateXYZ.o gumRotateZYX.o gumFullInverse.o \ + gumCrossProduct.o gumDotProduct.o gumNormalize.o \ + sceGumDrawArray.o sceGumDrawArrayN.o sceGumDrawBezier.o sceGumDrawSpline.o \ + sceGumRotateXYZ.o sceGumRotateZYX.o + +PSPGUM_FPU_OBJS = sceGumLoadIdentity.o sceGumLoadMatrix.o sceGumMatrixMode.o \ + sceGumMultMatrix.o sceGumOrtho.o sceGumPerspective.o sceGumPopMatrix.o \ + sceGumPushMatrix.o sceGumScale.o sceGumTranslate.o sceGumUpdateMatrix.o \ + sceGumStoreMatrix.o sceGumLookAt.o sceGumRotateX.o sceGumRotateY.o \ + sceGumRotateZ.o sceGumFullInverse.o sceGumFastInverse.o sceGumBeginObject.o \ + sceGumEndObject.o gumScale.o gumTranslate.o gumLoadIdentity.o gumFastInverse.o \ + gumMultMatrix.o gumRotateX.o gumRotateY.o gumRotateZ.o gumInit.o + +PSPGUM_VFPU_OBJS = sceGumLoadIdentity_vfpu.o sceGumLoadMatrix_vfpu.o sceGumMatrixMode_vfpu.o \ + sceGumMultMatrix_vfpu.o sceGumOrtho_vfpu.o sceGumPerspective_vfpu.o \ + sceGumPopMatrix_vfpu.o sceGumPushMatrix_vfpu.o sceGumScale_vfpu.o \ + sceGumTranslate_vfpu.o sceGumUpdateMatrix_vfpu.o sceGumStoreMatrix_vfpu.o \ + sceGumLookAt_vfpu.o sceGumRotateX_vfpu.o sceGumRotateY_vfpu.o \ + sceGumRotateZ_vfpu.o sceGumFullInverse_vfpu.o sceGumFastInverse_vfpu.o \ + sceGumBeginObject_vfpu.o sceGumEndObject_vfpu.o gumScale_vfpu.o \ + gumTranslate_vfpu.o gumLoadIdentity_vfpu.o gumFastInverse_vfpu.o \ + gumMultMatrix_vfpu.o gumRotateX_vfpu.o gumRotateY_vfpu.o gumRotateZ_vfpu.o \ + gumInit_vfpu.o + +libpspgum_a_SOURCES = gumInternal.c pspgum.c +libpspgum_a_LIBADD = $(PSPGUM_FPU_OBJS) $(PSPGUM_SHARED_OBJS) + +libpspgum_vfpu_a_SOURCES = gumInternal.c pspgum.c pspgum_vfpu.c +libpspgum_vfpu_a_LIBADD = $(PSPGUM_VFPU_OBJS) $(PSPGUM_SHARED_OBJS) + +$(PSPGUM_SHARED_OBJS): pspgum.c + $(COMPILE) -DF_$* $< -c -o $@ + +$(PSPGUM_FPU_OBJS): pspgum.c + $(COMPILE) -DF_$* $< -c -o $@ + +$(PSPGUM_VFPU_OBJS): pspgum_vfpu.c + $(COMPILE) -DF_$* $< -c -o $@ diff --git a/src/gum/gumInternal.c b/src/gum/gumInternal.c new file mode 100644 index 00000000..75050361 --- /dev/null +++ b/src/gum/gumInternal.c @@ -0,0 +1,30 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "gumInternal.h" +#include +#include + +int gum_current_mode = GU_PROJECTION; + +int gum_matrix_update[4] = { 0 }; +int gum_current_matrix_update = 0; + +ScePspFMatrix4* gum_current_matrix = gum_matrix_stack[GU_PROJECTION]; + +ScePspFMatrix4* gum_stack_depth[4] = +{ + gum_matrix_stack[GU_PROJECTION], + gum_matrix_stack[GU_VIEW], + gum_matrix_stack[GU_MODEL], + gum_matrix_stack[GU_TEXTURE] +}; + +ScePspFMatrix4 gum_matrix_stack[4][32]; + +struct pspvfpu_context *gum_vfpucontext; diff --git a/src/gum/gumInternal.h b/src/gum/gumInternal.h new file mode 100644 index 00000000..e1403cab --- /dev/null +++ b/src/gum/gumInternal.h @@ -0,0 +1,34 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#ifndef __gumInternal_h__ +#define __gumInternal_h__ + +#include + +#include "pspgum.h" +#include "../gu/pspgu.h" + +#define GUM_EPSILON 0.00001f + +//#define GUM_USE_VFPU + +// these macros are because GCC cannot handle aligned matrices declared on the stack +#define GUM_ALIGNED_MATRIX() (ScePspFMatrix4*)((((unsigned int)alloca(sizeof(ScePspFMatrix4)+64)) + 63) & ~63) +#define GUM_ALIGNED_VECTOR() (ScePspFVector4*)((((unsigned int)alloca(sizeof(ScePspFVector4)+64)) + 63) & ~63) + +extern int gum_current_mode; +extern int gum_matrix_update[4]; +extern int gum_current_matrix_update; +extern ScePspFMatrix4* gum_current_matrix; +extern ScePspFMatrix4* gum_stack_depth[4]; +extern ScePspFMatrix4 gum_matrix_stack[4][32]; + +extern struct pspvfpu_context *gum_vfpucontext; + +#endif diff --git a/src/gum/pspgum.c b/src/gum/pspgum.c new file mode 100644 index 00000000..99239b7c --- /dev/null +++ b/src/gum/pspgum.c @@ -0,0 +1,577 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "gumInternal.h" + +#include +#include + +#ifdef F_gumInit +void gumInit(void) +{ +} +#endif + +#ifdef F_gumCrossProduct +void gumCrossProduct(ScePspFVector3* r, const ScePspFVector3* a, const ScePspFVector3* b) +{ + r->x = (a->y * b->z) - (a->z * b->y); + r->y = (a->z * b->x) - (a->x * b->z); + r->z = (a->x * b->y) - (a->y * b->x); +} +#endif + +#ifdef F_gumDotProduct +float gumDotProduct(const ScePspFVector3* a, const ScePspFVector3* b) +{ + return (a->x * b->x) + (a->y * b->y) + (a->z * b->z); +} +#endif + +#ifdef F_gumFastInverse +void gumFastInverse(ScePspFMatrix4* m, const ScePspFMatrix4* a) +{ + ScePspFMatrix4 t; + ScePspFVector3 negPos = {-a->w.x,-a->w.y,-a->w.z}; + + // transpose rotation + + t.x.x = a->x.x; + t.x.y = a->y.x; + t.x.z = a->z.x; + t.x.w = 0; + + t.y.x = a->x.y; + t.y.y = a->y.y; + t.y.z = a->z.y; + t.y.w = 0; + + t.z.x = a->x.z; + t.z.y = a->y.z; + t.z.z = a->z.z; + t.z.w = 0; + + // compute inverse position + + t.w.x = gumDotProduct(&negPos,(const ScePspFVector3*)&a->x); + t.w.y = gumDotProduct(&negPos,(const ScePspFVector3*)&a->y); + t.w.z = gumDotProduct(&negPos,(const ScePspFVector3*)&a->z); + t.w.w = 1; + + gumLoadMatrix(m,&t); +} +#endif + +#ifdef F_gumFullInverse +void gumFullInverse(ScePspFMatrix4* m, const ScePspFMatrix4* a) +{ + ScePspFMatrix4 t; + float d0,d1,d2,d3; + float d; + + d0 = a->y.y*a->z.z*a->w.w + a->y.z*a->z.w*a->w.y + a->y.w*a->z.y*a->w.z - a->w.y*a->z.z*a->y.w - a->w.z*a->z.w*a->y.y - a->w.w*a->z.y*a->y.z; + d1 = a->y.x*a->z.z*a->w.w + a->y.z*a->z.w*a->w.x + a->y.w*a->z.x*a->w.z - a->w.x*a->z.z*a->y.w - a->w.z*a->z.w*a->y.x - a->w.w*a->z.x*a->y.z; + d2 = a->y.x*a->z.y*a->w.w + a->y.y*a->z.w*a->w.x + a->y.w*a->z.x*a->w.y - a->w.x*a->z.y*a->y.w - a->w.y*a->z.w*a->y.x - a->w.w*a->z.x*a->y.y; + d3 = a->y.x*a->z.y*a->w.z + a->y.y*a->z.z*a->w.x + a->y.z*a->z.x*a->w.y - a->w.x*a->z.y*a->y.z - a->w.y*a->z.z*a->y.x - a->w.z*a->z.x*a->y.y; + d = a->x.x*d0 - a->x.y * d1 + a->x.z * d2 - a->x.w * d3; + + if (fabsf(d) < GUM_EPSILON) + { + gumLoadIdentity(m); + return; + } + + d = 1.0f / d; + + t.x.x = d * d0; + t.x.y = -d * (a->x.y*a->z.z*a->w.w + a->x.z*a->z.w*a->w.y + a->x.w*a->z.y*a->w.z - a->w.y*a->z.z*a->x.w - a->w.z*a->z.w*a->x.y - a->w.w*a->z.y*a->x.z); + t.x.z = d * (a->x.y*a->y.z*a->w.w + a->x.z*a->y.w*a->w.y + a->x.w*a->y.y*a->w.z - a->w.y*a->y.z*a->x.w - a->w.z*a->y.w*a->x.y - a->w.w*a->y.y*a->x.z); + t.x.w = -d * (a->x.y*a->y.z*a->z.w + a->x.z*a->y.w*a->z.y + a->x.w*a->y.y*a->z.z - a->z.y*a->y.z*a->x.w - a->z.z*a->y.w*a->x.y - a->z.w*a->y.y*a->x.z); + + t.y.x = -d * d1; + t.y.y = d * (a->x.x*a->z.z*a->w.w + a->x.z*a->z.w*a->w.x + a->x.w*a->z.x*a->w.z - a->w.x*a->z.z*a->x.w - a->w.z*a->z.w*a->x.x - a->w.w*a->z.x*a->x.z); + t.y.z = -d * (a->x.x*a->y.z*a->w.w + a->x.z*a->y.w*a->w.x + a->x.w*a->y.x*a->w.z - a->w.x*a->y.z*a->x.w - a->w.z*a->y.w*a->x.x - a->w.w*a->y.x*a->x.z); + t.y.w = d * (a->x.x*a->y.z*a->z.w + a->x.z*a->y.w*a->z.x + a->x.w*a->y.x*a->z.z - a->z.x*a->y.z*a->x.w - a->z.z*a->y.w*a->x.x - a->z.w*a->y.x*a->x.z); + + t.z.x = d * d2; + t.z.y = -d * (a->x.x*a->z.y*a->w.w + a->x.y*a->z.w*a->w.x + a->x.w*a->z.x*a->w.y - a->w.x*a->z.y*a->x.w - a->w.y*a->z.w*a->x.x - a->w.w*a->z.x*a->x.y); + t.z.z = d * (a->x.x*a->y.y*a->w.w + a->x.y*a->y.w*a->w.x + a->x.w*a->y.x*a->w.y - a->w.x*a->y.y*a->x.w - a->w.y*a->y.w*a->x.x - a->w.w*a->y.x*a->x.y); + t.z.w = -d * (a->x.x*a->y.y*a->z.w + a->x.y*a->y.w*a->z.x + a->x.w*a->y.x*a->z.y - a->z.x*a->y.y*a->x.w - a->z.y*a->y.w*a->x.x - a->z.w*a->y.x*a->x.y); + + t.w.x = -d * d3; + t.w.y = d * (a->x.x*a->z.y*a->w.z + a->x.y*a->z.z*a->w.x + a->x.z*a->z.x*a->w.y - a->w.x*a->z.y*a->x.z - a->w.y*a->z.z*a->x.x - a->w.z*a->z.x*a->x.y); + t.w.z = -d * (a->x.x*a->y.y*a->w.z + a->x.y*a->y.z*a->w.x + a->x.z*a->y.x*a->w.y - a->w.x*a->y.y*a->x.z - a->w.y*a->y.z*a->x.x - a->w.z*a->y.x*a->x.y); + t.w.w = d * (a->x.x*a->y.y*a->z.z + a->x.y*a->y.z*a->z.x + a->x.z*a->y.x*a->z.y - a->z.x*a->y.y*a->x.z - a->z.y*a->y.z*a->x.x - a->z.z*a->y.x*a->x.y); + + gumLoadMatrix(m,&t); +} +#endif + +#ifdef F_gumLoadIdentity +void gumLoadIdentity(ScePspFMatrix4* m) +{ + unsigned int i; + + memset(m,0,sizeof(ScePspFMatrix4)); + + for (i = 0; i < 4; ++i) + ((float*)m)[(i << 2)+i] = 1.0f; +} +#endif + +#ifdef F_gumLoadMatrix +void gumLoadMatrix(ScePspFMatrix4* r, const ScePspFMatrix4* a) +{ + memcpy(r,a,sizeof(ScePspFMatrix4)); +} +#endif + +#ifdef F_gumLookAt +void gumLookAt(ScePspFMatrix4* m, ScePspFVector3* eye, ScePspFVector3* center, ScePspFVector3* up) +{ + ScePspFVector3 forward, side, lup,ieye; + ScePspFMatrix4 t; + + forward.x = center->x - eye->x; + forward.y = center->y - eye->y; + forward.z = center->z - eye->z; + + gumNormalize(&forward); + + gumCrossProduct(&side,&forward,up); + gumNormalize(&side); + + gumCrossProduct(&lup,&side,&forward); + gumLoadIdentity(&t); + + t.x.x = side.x; + t.y.x = side.y; + t.z.x = side.z; + + t.x.y = lup.x; + t.y.y = lup.y; + t.z.y = lup.z; + + t.x.z = -forward.x; + t.y.z = -forward.y; + t.z.z = -forward.z; + + ieye.x = -eye->x; ieye.y = -eye->y; ieye.z = -eye->z; + gumMultMatrix(m,m,&t); + gumTranslate(m,&ieye); +} +#endif + +#ifdef F_gumMultMatrix +void gumMultMatrix(ScePspFMatrix4* result, const ScePspFMatrix4* a, const ScePspFMatrix4* b) +{ + ScePspFMatrix4 t; + unsigned int i,j,k; + const float* ma = (const float*)a; + const float* mb = (const float*)b; + float* mr = (float*)&t; + + for (i = 0; i < 4; ++i) + { + for (j = 0; j < 4; ++j) + { + float v = 0.0f; + for (k = 0; k < 4; ++k) + v += ma[(k << 2)+j] * mb[(i << 2)+k]; + mr[(i << 2)+j] = v; + } + } + + memcpy(result,&t,sizeof(ScePspFMatrix4)); +} +#endif + +#ifdef F_gumNormalize +void gumNormalize(ScePspFVector3* v) +{ + float l = sqrtf((v->x*v->x) + (v->y*v->y) + (v->z*v->z)); + if (l > GUM_EPSILON) + { + float il = 1.0f / l; + v->x *= il; v->y *= il; v->z *= il; + } +} +#endif + +#ifdef F_gumOrtho +void gumOrtho(ScePspFMatrix4* m, float left, float right, float bottom, float top, float near, float far) +{ + ScePspFMatrix4 t; + float dx = right-left, dy = top-bottom, dz = far-near; + + gumLoadIdentity(&t); + + t.x.x = 2.0f / dx; + t.w.x = -(right + left) / dx; + t.y.y = 2.0f / dy; + t.w.y = -(top + bottom) / dy; + t.z.z = -2.0f / dz; + t.w.z = -(far + near) / dz; + + gumMultMatrix(m,m,&t); +} +#endif + +#ifdef F_gumPerspective +void gumPerspective(ScePspFMatrix4* m, float fovy, float aspect, float near, float far) +{ + ScePspFMatrix4 t; + float angle = (fovy / 2) * (GU_PI/180.0f); + float cotangent = cosf(angle) / sinf(angle); + float delta_z = near-far; + + gumLoadIdentity(&t); + + t.x.x = cotangent / aspect; + t.y.y = cotangent; + t.z.z = (far + near) / delta_z; // -(far + near) / delta_z + t.w.z = 2.0f * (far * near) / delta_z; // -2 * (far * near) / delta_z + t.z.w = -1.0f; + t.w.w = 0.0f; + + gumMultMatrix(m,m,&t); +} +#endif + +#ifdef F_gumRotateX +void gumRotateX(ScePspFMatrix4* m, float angle) +{ + ScePspFMatrix4 t; + + float c = cosf(angle); + float s = sinf(angle); + + gumLoadIdentity(&t); + + t.y.y = c; + t.y.z = s; + t.z.y = -s; + t.z.z = c; + + gumMultMatrix(m,m,&t); +} +#endif + +#ifdef F_gumRotateY +void gumRotateY(ScePspFMatrix4* m, float angle) +{ + ScePspFMatrix4 t; + + float c = cosf(angle); + float s = sinf(angle); + + gumLoadIdentity(&t); + + t.x.x = c; + t.x.z = -s; + t.z.x = s; + t.z.z = c; + + gumMultMatrix(m,m,&t); +} +#endif + +#ifdef F_gumRotateZ +void gumRotateZ(ScePspFMatrix4* m, float angle) +{ + ScePspFMatrix4 t; + + float c = cosf(angle); + float s = sinf(angle); + + gumLoadIdentity(&t); + + t.x.x = c; + t.x.y = s; + t.y.x = -s; + t.y.y = c; + + gumMultMatrix(m,m,&t); +} +#endif + +#ifdef F_gumRotateXYZ +void gumRotateXYZ(ScePspFMatrix4* m, const ScePspFVector3* v) +{ + gumRotateX(m,v->x); + gumRotateY(m,v->y); + gumRotateZ(m,v->z); +} +#endif + +#ifdef F_gumRotateZYX +void gumRotateZYX(ScePspFMatrix4* m, const ScePspFVector3* v) +{ + gumRotateZ(m,v->z); + gumRotateY(m,v->y); + gumRotateX(m,v->x); +} +#endif + +#ifdef F_gumScale +void gumScale(ScePspFMatrix4* m, const ScePspFVector3* v) +{ + float x,y,z; + + x = v->x; y = v->y; z = v->z; + m->x.x *= x; m->x.y *= x; m->x.z *= x; + m->y.x *= y; m->y.y *= y; m->y.z *= y; + m->z.x *= z; m->z.y *= z; m->z.z *= z; +} +#endif + +#ifdef F_gumTranslate +void gumTranslate(ScePspFMatrix4* m, const ScePspFVector3* v) +{ + ScePspFMatrix4 t; + + gumLoadIdentity(&t); + t.w.x = v->x; + t.w.y = v->y; + t.w.z = v->z; + + gumMultMatrix(m,m,&t); +} +#endif + +#ifdef F_sceGumDrawArray +void sceGumDrawArray(int prim, int vtype, int count, const void* indices, const void* vertices) +{ + sceGumUpdateMatrix(); + sceGuDrawArray(prim,vtype,count,indices,vertices); +} +#endif + +#ifdef F_sceGumDrawArrayN +void sceGumDrawArrayN(int prim, int vtype, int count, int a3, const void* indices, const void* vertices) +{ + sceGumUpdateMatrix(); + sceGuDrawArrayN(prim,vtype,count,a3,indices,vertices); +} +#endif + +#ifdef F_sceGumDrawBezier +void sceGumDrawBezier(int vtype, int ucount, int vcount, const void* indices, const void* vertices) +{ + sceGumUpdateMatrix(); + sceGuDrawBezier(vtype,ucount,vcount,indices,vertices); +} +#endif + +#ifdef F_sceGumDrawSpline +void sceGumDrawSpline(int vtype, int ucount, int vcount, int uedge, int vedge, const void* indices, const void* vertices) +{ + sceGumUpdateMatrix(); + sceGuDrawSpline(vtype,ucount,vcount,uedge,vedge,indices,vertices); +} +#endif + +#ifdef F_sceGumFastInverse +void sceGumFastInverse() +{ + gumFastInverse(gum_current_matrix,gum_current_matrix); + gum_current_matrix_update = 1; +} +#endif + +#ifdef F_sceGumFullInverse +void sceGumFullInverse() +{ + gumFullInverse(gum_current_matrix,gum_current_matrix); + gum_current_matrix_update = 1; +} +#endif + +#ifdef F_sceGumLoadIdentity +void sceGumLoadIdentity(void) +{ + gumLoadIdentity(gum_current_matrix); + gum_current_matrix_update = 1; +} +#endif + +#ifdef F_sceGumLoadMatrix +void sceGumLoadMatrix(const ScePspFMatrix4* m) +{ + memcpy(gum_current_matrix,m,sizeof(ScePspFMatrix4)); + gum_current_matrix_update = 1; +} +#endif + +#ifdef F_sceGumLookAt +void sceGumLookAt(ScePspFVector3* eye, ScePspFVector3* center, ScePspFVector3* up) +{ + gumLookAt(gum_current_matrix,eye,center,up); + gum_current_matrix_update = 1; +} +#endif + +#ifdef F_sceGumMatrixMode +void sceGumMatrixMode(int mode) +{ + // switch stack + gum_matrix_update[gum_current_mode] = gum_current_matrix_update; + gum_stack_depth[gum_current_mode] = gum_current_matrix; + gum_current_matrix = gum_stack_depth[mode]; + gum_current_mode = mode; + gum_current_matrix_update = gum_matrix_update[gum_current_mode]; +} +#endif + +#ifdef F_sceGumMultMatrix +void sceGumMultMatrix(const ScePspFMatrix4* m) +{ + gumMultMatrix(gum_current_matrix,gum_current_matrix,m); + gum_current_matrix_update = 1; +} +#endif + +#ifdef F_sceGumOrtho +void sceGumOrtho(float left, float right, float bottom, float top, float near, float far) +{ + register ScePspFMatrix4* t __asm("a0") = GUM_ALIGNED_MATRIX(); + float dx = right-left, dy = top-bottom, dz = far-near; + + memset(t,0,sizeof(ScePspFMatrix4)); + + t->x.x = 2.0f / dx; + t->w.x = -(right + left) / dx; + t->y.y = 2.0f / dy; + t->w.y = -(top + bottom) / dy; + t->z.z = -2.0f / dz; + t->w.z = -(far + near) / dz; + t->w.w = 1.0f; + + sceGumMultMatrix(t); +} +#endif + +#ifdef F_sceGumPerspective +void sceGumPerspective(float fovy, float aspect, float near, float far) +{ + float angle = (fovy / 2) * (GU_PI/180.0f); + float cotangent = cosf(angle) / sinf(angle); + float delta_z = near-far; + register ScePspFMatrix4* t __asm("a0") = GUM_ALIGNED_MATRIX(); + + memset(t,0,sizeof(ScePspFMatrix4)); + t->x.x = cotangent / aspect; + t->y.y = cotangent; + t->z.z = (far + near) / delta_z; // -(far + near) / delta_z + t->w.z = 2.0f * (far * near) / delta_z; // -2 * (far * near) / delta_z + t->z.w = -1.0f; + t->w.w = 0.0f; + + sceGumMultMatrix(t); +} +#endif + +#ifdef F_sceGumPopMatrix +void sceGumPopMatrix(void) +{ + gum_current_matrix--; + gum_current_matrix_update = 1; +} +#endif + +#ifdef F_sceGumPushMatrix +void sceGumPushMatrix(void) +{ + memcpy(gum_current_matrix+1,gum_current_matrix,sizeof(ScePspFMatrix4)); + gum_current_matrix++; +} +#endif + +#ifdef F_sceGumRotateX +void sceGumRotateX(float angle) +{ + gumRotateX(gum_current_matrix,angle); + gum_current_matrix_update = 1; +} +#endif + +#ifdef F_sceGumRotateXYZ +void sceGumRotateXYZ(const ScePspFVector3* v) +{ + sceGumRotateX(v->x); + sceGumRotateY(v->y); + sceGumRotateZ(v->z); +} +#endif + +#ifdef F_sceGumRotateY +void sceGumRotateY(float angle) +{ + gumRotateY(gum_current_matrix,angle); + gum_current_matrix_update = 1; +} +#endif + +#ifdef F_sceGumRotateZ +void sceGumRotateZ(float angle) +{ + gumRotateZ(gum_current_matrix,angle); + gum_current_matrix_update = 1; +} +#endif + +#ifdef F_sceGumRotateZYX +void sceGumRotateZYX(const ScePspFVector3* v) +{ + sceGumRotateZ(v->z); + sceGumRotateY(v->y); + sceGumRotateX(v->x); +} +#endif + +#ifdef F_sceGumScale +void sceGumScale(const ScePspFVector3* v) +{ + gumScale(gum_current_matrix,v); + gum_current_matrix_update = 1; +} +#endif + +#ifdef F_sceGumStoreMatrix +void sceGumStoreMatrix(ScePspFMatrix4* m) +{ + memcpy(m,gum_current_matrix,sizeof(ScePspFMatrix4)); +} +#endif + +#ifdef F_sceGumTranslate +void sceGumTranslate(const ScePspFVector3* v) +{ + gumTranslate(gum_current_matrix,v); + gum_current_matrix_update = 1; +} +#endif + +#ifdef F_sceGumUpdateMatrix +void sceGumUpdateMatrix(void) +{ + gum_stack_depth[gum_current_mode] = gum_current_matrix; + gum_matrix_update[gum_current_mode] = gum_current_matrix_update; + gum_current_matrix_update = 0; + + unsigned int i; + for (i = 0; i < 4; ++i) + { + if (gum_matrix_update[i]) + { + sceGuSetMatrix(i,gum_stack_depth[i]); + gum_matrix_update[i] = 0; + } + } +} +#endif diff --git a/src/gum/pspgum.h b/src/gum/pspgum.h new file mode 100644 index 00000000..57f8fcf6 --- /dev/null +++ b/src/gum/pspgum.h @@ -0,0 +1,236 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#ifndef __pspgum_h__ +#define __pspgum_h__ + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +// stack functions + +void sceGumDrawArray(int prim, int vtype, int count, const void* indices, const void* vertices); +void sceGumDrawArrayN(int prim, int vtype, int count, int a3, const void* indices, const void* vertices); +void sceGumDrawBezier(int vtype, int ucount, int vcount, const void* indices, const void* vertices); +void sceGumDrawSpline(int vtype, int ucount, int vcount, int uedge, int vedge, const void* indices, const void* vertices); + +/** + * Load identity matrix + * + * [1 0 0 0] + * [0 1 0 0] + * [0 0 1 0] + * [0 0 0 1] +**/ +void sceGumLoadIdentity(void); + +/** + * Load matrix + * + * @param m - Matrix to load into stack +**/ +void sceGumLoadMatrix(const ScePspFMatrix4* m); + +void sceGumLookAt(ScePspFVector3* eye, ScePspFVector3* center, ScePspFVector3* up); + +/** + * Select which matrix stack to operate on + * + * Available matrix modes are: + * - GU_PROJECTION + * - GU_VIEW + * - GU_MODEL + * - GU_TEXTURE + * + * @param mode - Matrix mode to use +**/ +void sceGumMatrixMode(int mode); + +/** + * Multiply current matrix with input + * + * @param m - Matrix to multiply stack with +**/ +void sceGumMultMatrix(const ScePspFMatrix4* m); + +/** + * Apply ortho projection matrix + * + * @note The matrix loses its orthonogal status after executing this function. +**/ +void sceGumOrtho(float left, float right, float bottom, float top, float near, float far); + +/** + * Apply perspective projection matrix + * + * @note The matrix loses its orthonogal status after executing this function. +**/ +void sceGumPerspective(float fovy, float aspect, float near, float far); + +/** + * Pop matrix from stack +**/ +void sceGumPopMatrix(void); + +/** + * Push current matrix onto stack +**/ +void sceGumPushMatrix(void); + +/** + * Rotate around the X axis + * + * @param angle - Angle in radians +**/ +void sceGumRotateX(float angle); + +/** + * Rotate around the Y axis + * + * @param angle - Angle in radians +**/ +void sceGumRotateY(float angle); + +/** + * Rotate around the Z axis + * + * @param angle - Angle in radians +**/ +void sceGumRotateZ(float angle); + +/** + * Rotate around all 3 axis in order X, Y, Z + * + * @param v - Pointer to vector containing angles +**/ +void sceGumRotateXYZ(const ScePspFVector3* v); + +/** + * Rotate around all 3 axis in order Z, Y, X + * + * @param v - Pointer to vector containing angles +**/ +void sceGumRotateZYX(const ScePspFVector3* v); + +/** + * Scale matrix + * + * @note The matrix loses its orthonogal status after executing this function. +**/ +void sceGumScale(const ScePspFVector3* v); + +/** + * Store current matrix in the stack + * + * @param m - Matrix to write result to +**/ +void sceGumStoreMatrix(ScePspFMatrix4* m); + +/** + * Translate coordinate system + * + * @param v - Translation coordinates +**/ +void sceGumTranslate(const ScePspFVector3* v); + +/** + * Explicitly flush dirty matrices to the hardware +**/ +void sceGumUpdateMatrix(void); + +/** + * Invert 4x4 matrix + * + * This invert algorithm can operate on matrices that are not orthongal (See sceGumFastInverse()) +**/ +void sceGumFullInverse(); + +/** + * Invert orthonogal 4x4 matrix + * + * Note that the matrix in the stack has to be orthonogal (that is, all rotational axises must be unit length & orthonogal against the others), + * otherwise the result of the function cannot be depended on. If you need to invert a matrix that is not orthonogal, use sceGumFullInverse(). +**/ +void sceGumFastInverse(); + +/** + * Stack-aware version of sceGuBeginObject() (look in pspgu.h for description) + * + * @note NOT YET IMPLEMENTED + * + * @param vtype - Vertex type to process + * @param count - Number of vertices to test + * @param indices - Optional index-list + * @param vertices - Vertex-list +**/ +void sceGumBeginObject(int vtype, int count, const void* indices, const void* vertices); + +/** + * Stack-aware version of sceGuEndObject() + * + * @note NOT YET IMPLEMENTED +**/ +void sceGumEndObject(); + +// unimplemented functions + +//sceGumLoadContext +//sceGumSetCurMatrix +//sceGumSetMatrixStack +//sceGumStoreContext + +// standalone functions + +void gumInit(void); + +/** + * Load matrix with identity + * + * @param m - Matrix to load with identity +**/ +void gumLoadIdentity(ScePspFMatrix4* m); + +void gumLoadMatrix(ScePspFMatrix4* r, const ScePspFMatrix4* a); +void gumLookAt(ScePspFMatrix4* m, ScePspFVector3* eye, ScePspFVector3* center, ScePspFVector3* up); +void gumMultMatrix(ScePspFMatrix4* result, const ScePspFMatrix4* a, const ScePspFMatrix4* b); +void gumOrtho(ScePspFMatrix4* m, float left, float right, float bottom, float top, float near, float far); +void gumPerspective(ScePspFMatrix4* m, float fovy, float aspect, float near, float far); +void gumRotateX(ScePspFMatrix4* m, float angle); +void gumRotateXYZ(ScePspFMatrix4* m, const ScePspFVector3* v); +void gumRotateY(ScePspFMatrix4* m, float angle); +void gumRotateZ(ScePspFMatrix4* m, float angle); +void gumRotateZYX(ScePspFMatrix4* m, const ScePspFVector3* v); +void gumScale(ScePspFMatrix4* m, const ScePspFVector3* v); +void gumTranslate(ScePspFMatrix4* m, const ScePspFVector3* v); +void gumFullInverse(ScePspFMatrix4* r, const ScePspFMatrix4* a); + +/** + * Invert orthonogal 4x4 matrix + * + * Note that the matrix in the stack has to be orthonogal (that is, all rotational axises must be unit length & orthonogal against the others), + * otherwise the result of the function cannot be depended on. If you need to invert a matrix that is not orthonogal, use gumFullInverse(). + * + * @param r - Matrix receiving result + * @param a - Orthonogal matrix that is to be inverted +**/ +void gumFastInverse(ScePspFMatrix4* r, const ScePspFMatrix4* a); + +// vector functions + +void gumCrossProduct(ScePspFVector3* r, const ScePspFVector3* a, const ScePspFVector3* b); +float gumDotProduct(const ScePspFVector3* a, const ScePspFVector3* b); +void gumNormalize(ScePspFVector3* v); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/src/gum/pspgum_vfpu.c b/src/gum/pspgum_vfpu.c new file mode 100644 index 00000000..ecfc6f1d --- /dev/null +++ b/src/gum/pspgum_vfpu.c @@ -0,0 +1,627 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "gumInternal.h" + +#include +#include + +#include "pspvfpu.h" + +#ifdef F_gumInit_vfpu +void gumInit(void) +{ + if (gum_vfpucontext == NULL) + gum_vfpucontext = pspvfpu_initcontext(); +} +#endif + +#ifdef F_gumScale_vfpu +void gumScale(ScePspFMatrix4* m, const ScePspFVector3* v) +{ + pspvfpu_use_matrices(gum_vfpucontext, 0, VMAT0 | VMAT1); + + __asm__ volatile ( + "ulv.q C100, 0 + %0\n" + "ulv.q C110, 16 + %0\n" + "ulv.q C120, 32 + %0\n" + "ulv.q C130, 48 + %0\n" + + "ulv.q C000, %1\n" + + "vscl.t C100, C100, S000\n" + "vscl.t C110, C110, S001\n" + "vscl.t C120, C120, S002\n" + + "usv.q C100, 0 + %0\n" + "usv.q C110, 16 + %0\n" + "usv.q C120, 32 + %0\n" + "usv.q C130, 48 + %0\n" + : "+m"(*m) : "m"(*v)); +} +#endif + +#ifdef F_gumTranslate_vfpu +void gumTranslate(ScePspFMatrix4* m, const ScePspFVector3* v) +{ +#if 0 + pspvfpu_use_matrices(gum_vfpucontext, 0, VMAT0 | VMAT1 | VMAT2); + + __asm__ volatile ( + "ulv.q C100, 0 + %0\n" + "ulv.q C110, 16 + %0\n" + "ulv.q C120, 32 + %0\n" + "ulv.q C130, 48 + %0\n" + + "vmidt.q M000\n" + "ulv.q C200, %1\n" + "vmov.t C030, C200\n" + "vmmul.q M200, M100, M000\n" + + "usv.q C200, 0 + %0\n" + "usv.q C210, 16 + %0\n" + "usv.q C220, 32 + %0\n" + "usv.q C230, 48 + %0\n" + : "+m"(*m) : "m"(*v)); +#else + pspvfpu_use_matrices(gum_vfpucontext, 0, VMAT0 | VMAT1); + + /* This might be a little faster, since the vmmul is a + pretty long-latency instruction, compared to simple + scales and adds. Also uses fewer registers (M000 & + M100) */ + __asm__ volatile ( + "ulv.q C030, %1\n" + + "ulv.q C100, 0 + %0\n" + "ulv.q C110, 16 + %0\n" + "ulv.q C120, 32 + %0\n" + "ulv.q C130, 48 + %0\n" + + "vscl.q C000, C100, S030\n" + "vscl.q C010, C110, S031\n" + "vscl.q C020, C120, S032\n" + + "vadd.q C130, C130, C000\n" + "vadd.q C130, C130, C010\n" + "vadd.q C130, C130, C020\n" + + "usv.q C130, 48 + %0\n" // only C130 has changed + : "+m"(*m) : "m"(*v)); +#endif +} +#endif + +#ifdef F_gumRotateX_vfpu +void gumRotateX(ScePspFMatrix4* m, float angle) +{ + pspvfpu_use_matrices(gum_vfpucontext, 0, VMAT0 | VMAT1 | VMAT2); + + __asm__ volatile ( + "ulv.q C200, 0 + %0\n" + "ulv.q C210, 16 + %0\n" + "ulv.q C220, 32 + %0\n" + "ulv.q C230, 48 + %0\n" + + "vmidt.q M000\n" + "mtv %1, S100\n" + "vcst.s S101, VFPU_2_PI\n" + "vmul.s S100, S101, S100\n" + "vrot.q C010, S100, [ 0, c, s, 0]\n" + "vrot.q C020, S100, [ 0,-s, c, 0]\n" + "vmmul.q M100, M200, M000\n" + + "usv.q C100, 0 + %0\n" + "usv.q C110, 16 + %0\n" + "usv.q C120, 32 + %0\n" + "usv.q C130, 48 + %0\n" + : "+m"(*m) : "r"(angle)); +} +#endif + +#ifdef F_gumRotateY_vfpu +void gumRotateY(ScePspFMatrix4* m, float angle) +{ + pspvfpu_use_matrices(gum_vfpucontext, 0, VMAT0 | VMAT1 | VMAT2); + + __asm__ volatile ( + "ulv.q C200, 0 + %0\n" + "ulv.q C210, 16 + %0\n" + "ulv.q C220, 32 + %0\n" + "ulv.q C230, 48 + %0\n" + + "vmidt.q M000\n" + "mtv %1, S100\n" + "vcst.s S101, VFPU_2_PI\n" + "vmul.s S100, S101, S100\n" + "vrot.q C000, S100, [ c, 0,-s, 0]\n" + "vrot.q C020, S100, [ s, 0, c, 0]\n" + "vmmul.q M100, M200, M000\n" + + "usv.q C100, 0 + %0\n" + "usv.q C110, 16 + %0\n" + "usv.q C120, 32 + %0\n" + "usv.q C130, 48 + %0\n" + : "+m"(*m) : "r"(angle)); +} +#endif + +#ifdef F_gumRotateZ_vfpu +void gumRotateZ(ScePspFMatrix4* m, float angle) +{ + pspvfpu_use_matrices(gum_vfpucontext, 0, VMAT0 | VMAT1 | VMAT2); + + __asm__ volatile ( + "ulv.q C200, 0 + %0\n" + "ulv.q C210, 16 + %0\n" + "ulv.q C220, 32 + %0\n" + "ulv.q C230, 48 + %0\n" + + "vmidt.q M000\n" + "mtv %1, S100\n" + "vcst.s S101, VFPU_2_PI\n" + "vmul.s S100, S101, S100\n" + "vrot.q C000, S100, [ c, s, 0, 0]\n" + "vrot.q C010, S100, [-s, c, 0, 0]\n" + "vmmul.q M100, M200, M000\n" + + "usv.q C100, 0 + %0\n" + "usv.q C110, 16 + %0\n" + "usv.q C120, 32 + %0\n" + "usv.q C130, 48 + %0\n" + : "+m"(*m) : "r"(angle)); +} +#endif + +#ifdef F_gumLoadIdentity_vfpu +void gumLoadIdentity(ScePspFMatrix4* m) +{ + pspvfpu_use_matrices(gum_vfpucontext, 0, VMAT0); + + __asm__ volatile ( + "vmidt.q M000\n" + "usv.q C000, 0 + %0\n" + "usv.q C010, 16 + %0\n" + "usv.q C020, 32 + %0\n" + "usv.q C030, 48 + %0\n" + : "=m"(*m) : : "memory" ); +} +#endif + +#ifdef F_gumFastInverse_vfpu +void gumFastInverse(ScePspFMatrix4* m, const ScePspFMatrix4* a) +{ + pspvfpu_use_matrices(gum_vfpucontext, 0, VMAT0 | VMAT1 | VMAT2); + + __asm__ volatile ( + "ulv.q C200, 0 + %1\n" + "ulv.q C210, 16 + %1\n" + "ulv.q C220, 32 + %1\n" + "ulv.q C230, 48 + %1\n" + + "vmidt.q M000\n" + "vmmov.t M000, E200\n" + "vneg.t C100, C230\n" + "vtfm3.t C030, M200, C100\n" + + "usv.q C000, 0 + %0\n" + "usv.q C010, 16 + %0\n" + "usv.q C020, 32 + %0\n" + "usv.q C030, 48 + %0\n" + : "=m"(*m) : "m"(*a) : "memory" ); +} +#endif + +#ifdef F_gumMultMatrix_vfpu +void gumMultMatrix(ScePspFMatrix4* result, const ScePspFMatrix4* a, const ScePspFMatrix4* b) +{ + pspvfpu_use_matrices(gum_vfpucontext, 0, VMAT0 | VMAT1 | VMAT2); + + __asm__ volatile + ( + "ulv.q C000, 0 + %1\n" + "ulv.q C010, 16 + %1\n" + "ulv.q C020, 32 + %1\n" + "ulv.q C030, 48 + %1\n" + + "ulv.q C100, 0 + %2\n" + "ulv.q C110, 16 + %2\n" + "ulv.q C120, 32 + %2\n" + "ulv.q C130, 48 + %2\n" + + "vmmul.q M200, M000, M100\n" + + "usv.q C200, 0 + %0\n" + "usv.q C210, 16 + %0\n" + "usv.q C220, 32 + %0\n" + "usv.q C230, 48 + %0\n" + : "=m"(*result) : "m"(*a), "m"(*b) : "memory"); +} +#endif + +#ifdef F_sceGumFastInverse_vfpu +void sceGumFastInverse() +{ + pspvfpu_use_matrices(gum_vfpucontext, VMAT3, VMAT0 | VMAT1); + + __asm__ volatile ( + "vmidt.q M000\n" + "vmmov.t M000, E300\n" + "vneg.t C100, C330\n" + "vtfm3.t C030, M300, C100\n" + "vmmov.q M300, M000\n" + ); + + gum_current_matrix_update = 1; +} +#endif + +#ifdef F_sceGumFullInverse_vfpu +void sceGumFullInverse() +{ + ScePspFMatrix4* t = GUM_ALIGNED_MATRIX(); + + pspvfpu_use_matrices(gum_vfpucontext, VMAT3, VMAT0 | VMAT1); + + __asm__ volatile ( + "sv.q C300, 0 + %0\n" + "sv.q C310, 16 + %0\n" + "sv.q C320, 32 + %0\n" + "sv.q C330, 48 + %0\n" + : "=m"(*t) : : "memory"); + + gumFastInverse(t,t); + + __asm__ volatile ( + "lv.q C300.q, 0 + %0\n" + "lv.q C310.q, 16 + %0\n" + "lv.q C320.q, 32 + %0\n" + "lv.q C330.q, 48 + %0\n" + : : "m"(*t) : "memory"); + + gum_current_matrix_update = 1; +} +#endif + +#ifdef F_sceGumLoadIdentity_vfpu +void sceGumLoadIdentity(void) +{ + if (gum_vfpucontext == NULL) + gum_vfpucontext = pspvfpu_initcontext(); + pspvfpu_use_matrices(gum_vfpucontext, VMAT3, 0); + + __asm__ volatile ( + "vmidt.q M300\n" + ); + gum_current_matrix_update = 1; +} +#endif + +#ifdef F_sceGumLoadMatrix_vfpu +void sceGumLoadMatrix(const ScePspFMatrix4* m) +{ + if (gum_vfpucontext == NULL) + gum_vfpucontext = pspvfpu_initcontext(); + pspvfpu_use_matrices(gum_vfpucontext, VMAT3, 0); + + __asm__ volatile ( + "ulv.q C300.q, 0 + %0\n" + "ulv.q C310.q, 16 + %0\n" + "ulv.q C320.q, 32 + %0\n" + "ulv.q C330.q, 48 + %0\n" + : : "m"(*m) : "memory"); + + gum_current_matrix_update = 1; +} +#endif + +#ifdef F_sceGumLookAt_vfpu +void sceGumLookAt(ScePspFVector3* eye, ScePspFVector3* center, ScePspFVector3* up) +{ + ScePspFMatrix4* t = GUM_ALIGNED_MATRIX(); + gumLoadIdentity(t); + gumLookAt(t,eye,center,up); + + pspvfpu_use_matrices(gum_vfpucontext, VMAT3, VMAT0 | VMAT1); + + __asm__ volatile ( + "lv.q C000.q, 0 + %0\n" + "lv.q C010.q, 16 + %0\n" + "lv.q C020.q, 32 + %0\n" + "lv.q C030.q, 48 + %0\n" + "vmmul.q M100, M300, M000\n" + "vmmov.q M300, M100\n" + : : "m"(*t) ); + + gum_current_matrix_update = 1; +} +#endif + +#ifdef F_sceGumMatrixMode_vfpu +void sceGumMatrixMode(int mode) +{ + pspvfpu_use_matrices(gum_vfpucontext, VMAT3, 0); + + __asm__ volatile ( + "sv.q C300, 0 + %0\n" + "sv.q C310, 16 + %0\n" + "sv.q C320, 32 + %0\n" + "sv.q C330, 48 + %0\n" + : "=m"(*gum_current_matrix) : : "memory"); + + // switch stack + gum_matrix_update[gum_current_mode] = gum_current_matrix_update; + gum_stack_depth[gum_current_mode] = gum_current_matrix; + gum_current_matrix = gum_stack_depth[mode]; + gum_current_mode = mode; + gum_current_matrix_update = gum_matrix_update[gum_current_mode]; + + __asm__ volatile ( + "lv.q C300, 0 + %0\n" + "lv.q C310, 16 + %0\n" + "lv.q C320, 32 + %0\n" + "lv.q C330, 48 + %0\n" + : : "m"(*gum_current_matrix) : "memory"); +} +#endif + +#ifdef F_sceGumMultMatrix_vfpu +void sceGumMultMatrix(const ScePspFMatrix4* m) +{ + pspvfpu_use_matrices(gum_vfpucontext, VMAT3, VMAT0 | VMAT1); + + __asm__ volatile ( + "ulv.q C000, 0 + %0\n" + "ulv.q C010, 16 + %0\n" + "ulv.q C020, 32 + %0\n" + "ulv.q C030, 48 + %0\n" + "vmmul.q M100, M300, M000\n" + "vmmov.q M300, M100\n" + : : "m"(*m)); + + gum_current_matrix_update = 1; +} +#endif + +#ifdef F_sceGumOrtho_vfpu +void sceGumOrtho(float left, float right, float bottom, float top, float near, float far) +{ + pspvfpu_use_matrices(gum_vfpucontext, VMAT3, VMAT0 | VMAT1); + + __asm__ volatile ( + "vmidt.q M100\n" // set M100 to identity + "mtv %1, S000\n" // C000 = [right, ?, ?, ] + "mtv %3, S001\n" // C000 = [right, top, ?, ] + "mtv %5, S002\n" // C000 = [right, top, far ] + "mtv %0, S010\n" // C010 = [left, ?, ?, ] + "mtv %2, S011\n" // C010 = [left, bottom, ?, ] + "mtv %4, S012\n" // C010 = [left, bottom, near] + "vsub.t C020, C000, C010\n" // C020 = [ dx, dy, dz] + "vrcp.t C020, C020\n" // C020 = [1/dx, 1/dy, 1/dz] + "vmul.s S100, S100[2], S020\n" // S100 = m->x.x = 2.0 / dx + "vmul.s S111, S111[2], S021\n" // S110 = m->y.y = 2.0 / dy + "vmul.s S122, S122[2], S022[-x]\n" // S122 = m->z.z = -2.0 / dz + "vsub.t C130, C000[-x,-y,-z], C010\n" // C130 = m->w[x, y, z] = [-(right+left), -(top+bottom), -(far+near)] + // we do vsub here since -(a+b) => (-1*a) + (-1*b) => -a - b + "vmul.t C130, C130, C020\n" // C130 = [-(right+left)/dx, -(top+bottom)/dy, -(far+near)/dz] + "vmmul.q M000, M300, M100\n" + "vmmov.q M300, M000\n" + : : "r"(left), "r"(right), "r"(bottom), "r"(top), "r"(near), "r"(far)); + + gum_current_matrix_update = 1; +} +#endif + +#ifdef F_sceGumPerspective_vfpu +void sceGumPerspective(float fovy, float aspect, float near, float far) +{ + pspvfpu_use_matrices(gum_vfpucontext, VMAT3, VMAT0 | VMAT1); + + __asm__ volatile ( + "vmzero.q M100\n" // set M100 to all zeros + "mtv %0, S000\n" // S000 = fovy + "viim.s S001, 90\n" // S002 = 90.0f + "vrcp.s S001, S001\n" // S002 = 1/90 + "vmul.s S000, S000, S000[1/2]\n" // S000 = fovy * 0.5 = fovy/2 + "vmul.s S000, S000, S001\n" // S000 = (fovy/2)/90 + "vrot.p C002, S000, [c, s]\n" // S002 = cos(angle), S003 = sin(angle) + "vdiv.s S100, S002, S003\n" // S100 = m->x.x = cotangent = cos(angle)/sin(angle) + "mtv %2, S001\n" // S001 = near + "mtv %3, S002\n" // S002 = far + "vsub.s S003, S001, S002\n" // S003 = deltaz = near-far + "vrcp.s S003, S003\n" // S003 = 1/deltaz + "mtv %1, S000\n" // S000 = aspect + "vmov.s S111, S100\n" // S111 = m->y.y = cotangent + "vdiv.s S100, S100, S000\n" // S100 = m->x.x = cotangent / aspect + "vadd.s S122, S001, S002\n" // S122 = m->z.z = far + near + "vmul.s S122, S122, S003\n" // S122 = m->z.z = (far+near)/deltaz + "vmul.s S132, S001, S002\n" // S132 = m->w.z = far * near + "vmul.s S132, S132, S132[2]\n" // S132 = m->w.z = 2 * (far*near) + "vmul.s S132, S132, S003\n" // S132 = m->w.z = 2 * (far*near) / deltaz + "vsub.s S123, S123, S123[1]\n" // S123 = m->z.w = -1.0 + "vmmul.q M000, M300, M100\n" + "vmmov.q M300, M000\n" + : : "r"(fovy),"r"(aspect),"r"(near),"r"(far)); + + gum_current_matrix_update = 1; +} +#endif + +#ifdef F_sceGumPopMatrix_vfpu +void sceGumPopMatrix(void) +{ + ScePspFMatrix4* m = --gum_current_matrix; + + pspvfpu_use_matrices(gum_vfpucontext, VMAT3, 0); + + __asm__ volatile ( + "lv.q C300.q, 0 + %0\n" + "lv.q C310.q, 16 + %0\n" + "lv.q C320.q, 32 + %0\n" + "lv.q C330.q, 48 + %0\n" + : : "m"(*m)); + + gum_current_matrix_update = 1; +} +#endif + +#ifdef F_sceGumPushMatrix_vfpu +void sceGumPushMatrix(void) +{ + ScePspFMatrix4* m = gum_current_matrix++; + + pspvfpu_use_matrices(gum_vfpucontext, VMAT3, 0); + + __asm__ volatile ( + "sv.q C300, 0 + %0\n" + "sv.q C310, 16 + %0\n" + "sv.q C320, 32 + %0\n" + "sv.q C330, 48 + %0\n" + : "=m"(*m) : : "memory"); +} +#endif + +#ifdef F_sceGumRotateX_vfpu +void sceGumRotateX(float angle) +{ + pspvfpu_use_matrices(gum_vfpucontext, VMAT3, VMAT0 | VMAT1); + + __asm__ volatile ( + "vmidt.q M000\n" + "mtv %0, S100\n" + "vcst.s S101, VFPU_2_PI\n" + "vmul.s S100, S101, S100\n" + "vrot.q C010, S100, [ 0, c, s, 0]\n" + "vrot.q C020, S100, [ 0,-s, c, 0]\n" + "vmmul.q M100, M300, M000\n" + "vmmov.q M300, M100\n" + : : "r"(angle)); + + gum_current_matrix_update = 1; +} +#endif + +#ifdef F_sceGumRotateY_vfpu +void sceGumRotateY(float angle) +{ + pspvfpu_use_matrices(gum_vfpucontext, VMAT3, VMAT0 | VMAT1); + + __asm__ volatile ( + "vmidt.q M000\n" + "mtv %0, S100\n" + "vcst.s S101, VFPU_2_PI\n" + "vmul.s S100, S101, S100\n" + "vrot.q C000, S100, [ c, 0,-s, 0]\n" + "vrot.q C020, S100, [ s, 0, c, 0]\n" + "vmmul.q M100, M300, M000\n" + "vmmov.q M300, M100\n" + : : "r"(angle)); + + gum_current_matrix_update = 1; +} +#endif + +#ifdef F_sceGumRotateZ_vfpu +void sceGumRotateZ(float angle) +{ + pspvfpu_use_matrices(gum_vfpucontext, VMAT3, VMAT0 | VMAT1); + + __asm volatile ( + "vmidt.q M000\n" + "mtv %0, S100\n" + "vcst.s S101, VFPU_2_PI\n" + "vmul.s S100, S101, S100\n" + "vrot.q C000, S100, [ c, s, 0, 0]\n" + "vrot.q C010, S100, [-s, c, 0, 0]\n" + "vmmul.q M100, M300, M000\n" + "vmmov.q M300, M100\n" + : : "r"(angle)); + + gum_current_matrix_update = 1; +} +#endif + +#ifdef F_sceGumScale_vfpu +void sceGumScale(const ScePspFVector3* v) +{ + pspvfpu_use_matrices(gum_vfpucontext, VMAT3, VMAT0); + + __asm__ volatile ( + "ulv.q C000, %0\n" + "vscl.t C300, C300, S000\n" + "vscl.t C310, C310, S001\n" + "vscl.t C320, C320, S002\n" + : : "m"(*v)); + + gum_current_matrix_update = 1; +} +#endif + +#ifdef F_sceGumStoreMatrix_vfpu +void sceGumStoreMatrix(ScePspFMatrix4* m) +{ + pspvfpu_use_matrices(gum_vfpucontext, VMAT3, 0); + + __asm__ volatile ( + "usv.q C300, 0 + %0\n" + "usv.q C310, 16 + %0\n" + "usv.q C320, 32 + %0\n" + "usv.q C330, 48 + %0\n" + : "=m"(*m) : : "memory"); +} +#endif + +#ifdef F_sceGumTranslate_vfpu +void sceGumTranslate(const ScePspFVector3* v) +{ + pspvfpu_use_matrices(gum_vfpucontext, VMAT3, VMAT0 | VMAT1); + + __asm__ volatile ( + "vmidt.q M000\n" + "ulv.q C100, %0\n" + "vmov.t C030, C100\n" + "vmmul.q M100, M300, M000\n" + "vmmov.q M300, M100\n" + : : "m"(*v)); + + gum_current_matrix_update = 1; +} +#endif + +#ifdef F_sceGumUpdateMatrix_vfpu +void sceGumUpdateMatrix(void) +{ + gum_stack_depth[gum_current_mode] = gum_current_matrix; + + // flush dirty matrix from vfpu + if (gum_current_matrix_update) + { + pspvfpu_use_matrices(gum_vfpucontext, VMAT3, 0); + + __asm__ volatile ( + "sv.q C300, 0 + %0\n" + "sv.q C310, 16 + %0\n" + "sv.q C320, 32 + %0\n" + "sv.q C330, 48 + %0\n" + : "=m"(*gum_current_matrix) : : "memory"); + gum_matrix_update[gum_current_mode] = gum_current_matrix_update; + gum_current_matrix_update = 0; + } + + + unsigned int i; + for (i = 0; i < 4; ++i) + { + if (gum_matrix_update[i]) + { + sceGuSetMatrix(i,gum_stack_depth[i]); + gum_matrix_update[i] = 0; + } + } +} +#endif diff --git a/src/hprm/Makefile.am b/src/hprm/Makefile.am new file mode 100644 index 00000000..e96b37aa --- /dev/null +++ b/src/hprm/Makefile.am @@ -0,0 +1,30 @@ + +libdir = @PSPSDK_LIBDIR@ + +CC = @PSP_CC@ +CCAS = $(CC) +AR = @PSP_AR@ +RANLIB = @PSP_RANLIB@ + +INCLUDES = -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel +CFLAGS = @PSPSDK_CFLAGS@ +CCASFLAGS = $(CFLAGS) -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel + +HPRM_OBJS = sceHprm_0000.o sceHprm_0001.o sceHprm_0002.o sceHprm_0003.o sceHprm_0004.o sceHprm_0005.o sceHprm_0006.o sceHprm_0007.o sceHprm_0008.o + +HPRM_DRIVER_OBJS = sceHprm_driver_0000.o sceHprm_driver_0001.o sceHprm_driver_0002.o sceHprm_driver_0003.o sceHprm_driver_0004.o sceHprm_driver_0005.o sceHprm_driver_0006.o sceHprm_driver_0007.o sceHprm_driver_0008.o sceHprm_driver_0009.o sceHprm_driver_0010.o sceHprm_driver_0011.o sceHprm_driver_0012.o sceHprm_driver_0013.o sceHprm_driver_0014.o sceHprm_driver_0015.o sceHprm_driver_0016.o sceHprm_driver_0017.o sceHprm_driver_0018.o + +libpsphprmincludedir = @PSPSDK_INCLUDEDIR@ +libpsphprminclude_HEADERS = psphprm.h + +lib_LIBRARIES = libpsphprm.a libpsphprm_driver.a +libpsphprm_a_SOURCES = sceHprm.S +libpsphprm_a_LIBADD = $(HPRM_OBJS) +libpsphprm_driver_a_SOURCES = sceHprm_driver.S +libpsphprm_driver_a_LIBADD = $(HPRM_DRIVER_OBJS) + +$(HPRM_OBJS): sceHprm.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(HPRM_DRIVER_OBJS): sceHprm_driver.S + $(COMPILE) -DF_$* $< -c -o $@ diff --git a/src/hprm/psphprm.h b/src/hprm/psphprm.h new file mode 100644 index 00000000..cca6c11a --- /dev/null +++ b/src/hprm/psphprm.h @@ -0,0 +1,95 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspaudio.h - Prototypes for the sceHprm library. + * + * Copyright (c) 2005 Adresd + * + * $Id: psphprm.h 1480 2005-11-25 16:10:18Z mrbrown $ + */ +#ifndef __HPRM_H__ +#define __HPRM_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup Hprm Hprm Remote */ + +/** @addtogroup Hprm */ + +/*@{*/ + +/** Enumeration of the remote keys */ +enum PspHprmKeys +{ + PSP_HPRM_PLAYPAUSE = 0x1, + PSP_HPRM_FORWARD = 0x4, + PSP_HPRM_BACK = 0x8, + PSP_HPRM_VOL_UP = 0x10, + PSP_HPRM_VOL_DOWN = 0x20, + PSP_HPRM_HOLD = 0x80 +}; + +/** + * Peek at the current being pressed on the remote. + * + * @param key - Pointer to the u32 to receive the key bitmap, should be one or + * more of ::PspHprmKeys + * + * @return < 0 on error + */ +int sceHprmPeekCurrentKey(u32 *key); + +/** + * Peek at the current latch data. + * + * @param latch - Pointer a to a 4 dword array to contain the latch data. + * + * @return < 0 on error. + */ +int sceHprmPeekLatch(u32 *latch); + +/** + * Read the current latch data. + * + * @param latch - Pointer a to a 4 dword array to contain the latch data. + * + * @return < 0 on error. + */ +int sceHprmReadLatch(u32 *latch); + +/** + * Determines whether the headphones are plugged in. + * + * @return 1 if the headphones are plugged in, else 0. + */ +int sceHprmIsHeadphoneExist(void); + +/** + * Determines whether the remote is plugged in. + * + * @return 1 if the remote is plugged in, else 0. + */ +int sceHprmIsRemoteExist(void); + +/** + * Determines whether the microphone is plugged in. + * + * @return 1 if the microphone is plugged in, else 0. + */ +int sceHprmIsMicrophoneExist(void); + + + +/*@}*/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/hprm/sceHprm.S b/src/hprm/sceHprm.S new file mode 100644 index 00000000..f2731aac --- /dev/null +++ b/src/hprm/sceHprm.S @@ -0,0 +1,31 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceHprm_0000 + IMPORT_START "sceHprm",0x40010000 +#endif +#ifdef F_sceHprm_0001 + IMPORT_FUNC "sceHprm",0xC7154136,sceHprmRegisterCallback +#endif +#ifdef F_sceHprm_0002 + IMPORT_FUNC "sceHprm",0x444ED0B7,sceHprmUnregisterCallback +#endif +#ifdef F_sceHprm_0003 + IMPORT_FUNC "sceHprm",0x208DB1BD,sceHprmIsRemoteExist +#endif +#ifdef F_sceHprm_0004 + IMPORT_FUNC "sceHprm",0x7E69EDA4,sceHprmIsHeadphoneExist +#endif +#ifdef F_sceHprm_0005 + IMPORT_FUNC "sceHprm",0x219C58F1,sceHprmIsMicrophoneExist +#endif +#ifdef F_sceHprm_0006 + IMPORT_FUNC "sceHprm",0x1910B327,sceHprmPeekCurrentKey +#endif +#ifdef F_sceHprm_0007 + IMPORT_FUNC "sceHprm",0x2BCEC83E,sceHprmPeekLatch +#endif +#ifdef F_sceHprm_0008 + IMPORT_FUNC "sceHprm",0x40D2F9F0,sceHprmReadLatch +#endif diff --git a/src/hprm/sceHprm_driver.S b/src/hprm/sceHprm_driver.S new file mode 100644 index 00000000..e16cd3cd --- /dev/null +++ b/src/hprm/sceHprm_driver.S @@ -0,0 +1,61 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceHprm_driver_0000 + IMPORT_START "sceHprm_driver",0x00010000 +#endif +#ifdef F_sceHprm_driver_0001 + IMPORT_FUNC "sceHprm_driver",0x1C5BC5A0,sceHprmInit +#endif +#ifdef F_sceHprm_driver_0002 + IMPORT_FUNC "sceHprm_driver",0x588845DA,sceHprmEnd +#endif +#ifdef F_sceHprm_driver_0003 + IMPORT_FUNC "sceHprm_driver",0x526BB7F4,sceHprmSuspend +#endif +#ifdef F_sceHprm_driver_0004 + IMPORT_FUNC "sceHprm_driver",0x2C7B8B05,sceHprmResume +#endif +#ifdef F_sceHprm_driver_0005 + IMPORT_FUNC "sceHprm_driver",0xD22913DB,sceHprmSetConnectCallback +#endif +#ifdef F_sceHprm_driver_0006 + IMPORT_FUNC "sceHprm_driver",0xC7154136,sceHprmRegisterCallback +#endif +#ifdef F_sceHprm_driver_0007 + IMPORT_FUNC "sceHprm_driver",0x444ED0B7,sceHprmUnregisterCallback +#endif +#ifdef F_sceHprm_driver_0008 + IMPORT_FUNC "sceHprm_driver",0x208DB1BD,sceHprmIsRemoteExist +#endif +#ifdef F_sceHprm_driver_0009 + IMPORT_FUNC "sceHprm_driver",0x7E69EDA4,sceHprmIsHeadphoneExist +#endif +#ifdef F_sceHprm_driver_0010 + IMPORT_FUNC "sceHprm_driver",0x219C58F1,sceHprmIsMicrophoneExist +#endif +#ifdef F_sceHprm_driver_0011 + IMPORT_FUNC "sceHprm_driver",0x4D1E622C,sceHprmReset +#endif +#ifdef F_sceHprm_driver_0012 + IMPORT_FUNC "sceHprm_driver",0x7B038374,sceHprmGetInternalState +#endif +#ifdef F_sceHprm_driver_0013 + IMPORT_FUNC "sceHprm_driver",0xF04591FA,sceHprm_driver_F04591FA +#endif +#ifdef F_sceHprm_driver_0014 + IMPORT_FUNC "sceHprm_driver",0x971AE8FB,sceHprm_driver_971AE8FB +#endif +#ifdef F_sceHprm_driver_0015 + IMPORT_FUNC "sceHprm_driver",0xBAD0828E,sceHprmGetModel +#endif +#ifdef F_sceHprm_driver_0016 + IMPORT_FUNC "sceHprm_driver",0x1910B327,sceHprmPeekCurrentKey +#endif +#ifdef F_sceHprm_driver_0017 + IMPORT_FUNC "sceHprm_driver",0x2BCEC83E,sceHprmPeekLatch +#endif +#ifdef F_sceHprm_driver_0018 + IMPORT_FUNC "sceHprm_driver",0x40D2F9F0,sceHprmReadLatch +#endif diff --git a/src/kernel/ExceptionManagerForKernel.S b/src/kernel/ExceptionManagerForKernel.S new file mode 100644 index 00000000..3680a0ea --- /dev/null +++ b/src/kernel/ExceptionManagerForKernel.S @@ -0,0 +1,31 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_ExceptionManagerForKernel_0000 + IMPORT_START "ExceptionManagerForKernel",0x00010000 +#endif +#ifdef F_ExceptionManagerForKernel_0001 + IMPORT_FUNC "ExceptionManagerForKernel",0x3FB264FC,sceKernelRegisterExceptionHandler +#endif +#ifdef F_ExceptionManagerForKernel_0002 + IMPORT_FUNC "ExceptionManagerForKernel",0x5A837AD4,sceKernelRegisterPriorityExceptionHandler +#endif +#ifdef F_ExceptionManagerForKernel_0003 + IMPORT_FUNC "ExceptionManagerForKernel",0x565C0B0E,sceKernelRegisterDefaultExceptionHandler +#endif +#ifdef F_ExceptionManagerForKernel_0004 + IMPORT_FUNC "ExceptionManagerForKernel",0x1AA6CFFA,sceKernelReleaseExceptionHandler +#endif +#ifdef F_ExceptionManagerForKernel_0005 + IMPORT_FUNC "ExceptionManagerForKernel",0xDF83875E,sceKernelGetActiveDefaultExceptionHandler +#endif +#ifdef F_ExceptionManagerForKernel_0006 + IMPORT_FUNC "ExceptionManagerForKernel",0x291FF031,sceKernelReleaseDefaultExceptionHandler +#endif +#ifdef F_ExceptionManagerForKernel_0007 + IMPORT_FUNC "ExceptionManagerForKernel",0x15ADC862,sceKernelRegisterNmiHandler +#endif +#ifdef F_ExceptionManagerForKernel_0008 + IMPORT_FUNC "ExceptionManagerForKernel",0xB15357C9,sceKernelReleaseNmiHandler +#endif diff --git a/src/kernel/InitForKernel.S b/src/kernel/InitForKernel.S new file mode 100755 index 00000000..8eee6bdb --- /dev/null +++ b/src/kernel/InitForKernel.S @@ -0,0 +1,40 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_InitForKernel_0000 + IMPORT_START "InitForKernel",0x00090000 +#endif +#ifdef F_InitForKernel_0001 + IMPORT_FUNC "InitForKernel",0x1D3256BA,sceKernelRegisterChunk +#endif +#ifdef F_InitForKernel_0002 + IMPORT_FUNC "InitForKernel",0x27932388,sceKernelBootFrom +#endif +#ifdef F_InitForKernel_0003 + IMPORT_FUNC "InitForKernel",0x2C6E9FE9,sceKernelGetChunk +#endif +#ifdef F_InitForKernel_0004 + IMPORT_FUNC "InitForKernel",0x33D30F49,InitForKernel_33D30F49 +#endif +#ifdef F_InitForKernel_0005 + IMPORT_FUNC "InitForKernel",0x7233B5BC,InitForKernel_7233B5BC +#endif +#ifdef F_InitForKernel_0006 + IMPORT_FUNC "InitForKernel",0x7A2333AD,sceKernelInitApitype +#endif +#ifdef F_InitForKernel_0007 + IMPORT_FUNC "InitForKernel",0x9F9AE99C,InitForKernel_9F9AE99C +#endif +#ifdef F_InitForKernel_0008 + IMPORT_FUNC "InitForKernel",0xA6E71B93,sceKernelInitFileName +#endif +#ifdef F_InitForKernel_0009 + IMPORT_FUNC "InitForKernel",0xC4F1BA33,InitForKernel_C4F1BA33 +#endif +#ifdef F_InitForKernel_0010 + IMPORT_FUNC "InitForKernel",0xCE88E870,sceKernelReleaseChunk +#endif +#ifdef F_InitForKernel_0011 + IMPORT_FUNC "InitForKernel",0xFD0F25AD,InitForKernel_FD0F25AD +#endif diff --git a/src/kernel/InterruptManagerForKernel.S b/src/kernel/InterruptManagerForKernel.S new file mode 100644 index 00000000..0091ce7e --- /dev/null +++ b/src/kernel/InterruptManagerForKernel.S @@ -0,0 +1,139 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_InterruptManagerForKernel_0000 + IMPORT_START "InterruptManagerForKernel",0x00010000 +#endif +#ifdef F_InterruptManagerForKernel_0001 + IMPORT_FUNC "InterruptManagerForKernel",0x092968F4,sceKernelCpuSuspendIntr +#endif +#ifdef F_InterruptManagerForKernel_0002 + IMPORT_FUNC "InterruptManagerForKernel",0x5F10D406,sceKernelCpuResumeIntr +#endif +#ifdef F_InterruptManagerForKernel_0003 + IMPORT_FUNC "InterruptManagerForKernel",0x3B84732D,sceKernelCpuResumeIntrWithSync +#endif +#ifdef F_InterruptManagerForKernel_0004 + IMPORT_FUNC "InterruptManagerForKernel",0xFE28C6D9,sceKernelIsIntrContext +#endif +#ifdef F_InterruptManagerForKernel_0005 + IMPORT_FUNC "InterruptManagerForKernel",0x53991063,InterruptManagerForKernel_53991063 +#endif +#ifdef F_InterruptManagerForKernel_0006 + IMPORT_FUNC "InterruptManagerForKernel",0x468BC716,sceKernelGetInterruptExitCount +#endif +#ifdef F_InterruptManagerForKernel_0007 + IMPORT_FUNC "InterruptManagerForKernel",0x43CD40EF,ReturnToThread +#endif +#ifdef F_InterruptManagerForKernel_0008 + IMPORT_FUNC "InterruptManagerForKernel",0x85F7766D,SaveThreadContext +#endif +#ifdef F_InterruptManagerForKernel_0009 + IMPORT_FUNC "InterruptManagerForKernel",0x02314986,sceKernelCpuEnableIntr +#endif +#ifdef F_InterruptManagerForKernel_0010 + IMPORT_FUNC "InterruptManagerForKernel",0x00B6B0F3,QueryInterruptManCB +#endif +#ifdef F_InterruptManagerForKernel_0011 + IMPORT_FUNC "InterruptManagerForKernel",0x58DD8978,sceKernelRegisterIntrHandler +#endif +#ifdef F_InterruptManagerForKernel_0012 + IMPORT_FUNC "InterruptManagerForKernel",0x15894D0B,InterruptManagerForKernel_15894D0B +#endif +#ifdef F_InterruptManagerForKernel_0013 + IMPORT_FUNC "InterruptManagerForKernel",0xF987B1F0,sceKernelReleaseIntrHandler +#endif +#ifdef F_InterruptManagerForKernel_0014 + IMPORT_FUNC "InterruptManagerForKernel",0xB5A15B30,sceKernelSetIntrLevel +#endif +#ifdef F_InterruptManagerForKernel_0015 + IMPORT_FUNC "InterruptManagerForKernel",0x43A7BBDC,InterruptManagerForKernel_43A7BBDC +#endif +#ifdef F_InterruptManagerForKernel_0016 + IMPORT_FUNC "InterruptManagerForKernel",0x02475AAF,sceKernelIsInterruptOccurred +#endif +#ifdef F_InterruptManagerForKernel_0017 + IMPORT_FUNC "InterruptManagerForKernel",0x4D6E7305,sceKernelEnableIntr +#endif +#ifdef F_InterruptManagerForKernel_0018 + IMPORT_FUNC "InterruptManagerForKernel",0x750E2507,sceKernelSuspendIntr +#endif +#ifdef F_InterruptManagerForKernel_0019 + IMPORT_FUNC "InterruptManagerForKernel",0xD774BA45,sceKernelDisableIntr +#endif +#ifdef F_InterruptManagerForKernel_0020 + IMPORT_FUNC "InterruptManagerForKernel",0x494D6D2B,sceKernelResumeIntr +#endif +#ifdef F_InterruptManagerForKernel_0021 + IMPORT_FUNC "InterruptManagerForKernel",0x2CD783A1,RegisterContextHooks +#endif +#ifdef F_InterruptManagerForKernel_0022 + IMPORT_FUNC "InterruptManagerForKernel",0x55242A8B,ReleaseContextHooks +#endif +#ifdef F_InterruptManagerForKernel_0023 + IMPORT_FUNC "InterruptManagerForKernel",0x27BC9A45,UnSupportIntr +#endif +#ifdef F_InterruptManagerForKernel_0024 + IMPORT_FUNC "InterruptManagerForKernel",0x0E224D66,SupportIntr +#endif +#ifdef F_InterruptManagerForKernel_0025 + IMPORT_FUNC "InterruptManagerForKernel",0x272766F8,sceKernelRegisterDebuggerIntrHandler +#endif +#ifdef F_InterruptManagerForKernel_0026 + IMPORT_FUNC "InterruptManagerForKernel",0xB386A459,sceKernelReleaseDebuggerIntrHandler +#endif +#ifdef F_InterruptManagerForKernel_0027 + IMPORT_FUNC "InterruptManagerForKernel",0xCDC86B64,sceKernelCallSubIntrHandler +#endif +#ifdef F_InterruptManagerForKernel_0028 + IMPORT_FUNC "InterruptManagerForKernel",0xD6878EB6,sceKernelGetUserIntrStack +#endif +#ifdef F_InterruptManagerForKernel_0029 + IMPORT_FUNC "InterruptManagerForKernel",0xF4454E44,sceKernelCallUserIntrHandler +#endif +#ifdef F_InterruptManagerForKernel_0030 + IMPORT_FUNC "InterruptManagerForKernel",0xCA04A2B9,sceKernelRegisterSubIntrHandler +#endif +#ifdef F_InterruptManagerForKernel_0031 + IMPORT_FUNC "InterruptManagerForKernel",0xD61E6961,sceKernelReleaseSubIntrHandler +#endif +#ifdef F_InterruptManagerForKernel_0032 + IMPORT_FUNC "InterruptManagerForKernel",0xFB8E22EC,sceKernelEnableSubIntr +#endif +#ifdef F_InterruptManagerForKernel_0033 + IMPORT_FUNC "InterruptManagerForKernel",0x8A389411,sceKernelDisableSubIntr +#endif +#ifdef F_InterruptManagerForKernel_0034 + IMPORT_FUNC "InterruptManagerForKernel",0x5CB5A78B,sceKernelSuspendSubIntr +#endif +#ifdef F_InterruptManagerForKernel_0035 + IMPORT_FUNC "InterruptManagerForKernel",0x7860E0DC,sceKernelResumeSubIntr +#endif +#ifdef F_InterruptManagerForKernel_0036 + IMPORT_FUNC "InterruptManagerForKernel",0xFC4374B8,sceKernelIsSubInterruptOccurred +#endif +#ifdef F_InterruptManagerForKernel_0037 + IMPORT_FUNC "InterruptManagerForKernel",0xD2E8363F,QueryIntrHandlerInfo +#endif +#ifdef F_InterruptManagerForKernel_0038 + IMPORT_FUNC "InterruptManagerForKernel",0x30C08374,sceKernelGetCpuClockCounter +#endif +#ifdef F_InterruptManagerForKernel_0039 + IMPORT_FUNC "InterruptManagerForKernel",0x35634A64,sceKernelGetCpuClockCounterWide +#endif +#ifdef F_InterruptManagerForKernel_0040 + IMPORT_FUNC "InterruptManagerForKernel",0x2DC9709B,_sceKernelGetCpuClockCounterLow +#endif +#ifdef F_InterruptManagerForKernel_0041 + IMPORT_FUNC "InterruptManagerForKernel",0xE9E652A9,_sceKernelGetCpuClockCounterHigh +#endif +#ifdef F_InterruptManagerForKernel_0042 + IMPORT_FUNC "InterruptManagerForKernel",0x0FC68A56,sceKernelSetPrimarySyscallHandler +#endif +#ifdef F_InterruptManagerForKernel_0043 + IMPORT_FUNC "InterruptManagerForKernel",0xF4D443F3,sceKernelRegisterSystemCallTable +#endif +#ifdef F_InterruptManagerForKernel_0044 + IMPORT_FUNC "InterruptManagerForKernel",0x8B61808B,sceKernelQuerySystemCall +#endif diff --git a/src/kernel/IoFileMgrForKernel.S b/src/kernel/IoFileMgrForKernel.S new file mode 100644 index 00000000..e03793c3 --- /dev/null +++ b/src/kernel/IoFileMgrForKernel.S @@ -0,0 +1,133 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_IoFileMgrForKernel_0000 + IMPORT_START "IoFileMgrForKernel",0x00010000 +#endif +#ifdef F_IoFileMgrForKernel_0001 + IMPORT_FUNC "IoFileMgrForKernel",0x3251EA56,sceIoPollAsync +#endif +#ifdef F_IoFileMgrForKernel_0002 + IMPORT_FUNC "IoFileMgrForKernel",0xE23EEC33,sceIoWaitAsync +#endif +#ifdef F_IoFileMgrForKernel_0003 + IMPORT_FUNC "IoFileMgrForKernel",0x35DBD746,sceIoWaitAsyncCB +#endif +#ifdef F_IoFileMgrForKernel_0004 + IMPORT_FUNC "IoFileMgrForKernel",0xCB05F8D6,sceIoGetAsyncStat +#endif +#ifdef F_IoFileMgrForKernel_0005 + IMPORT_FUNC "IoFileMgrForKernel",0xB293727F,sceIoChangeAsyncPriority +#endif +#ifdef F_IoFileMgrForKernel_0006 + IMPORT_FUNC "IoFileMgrForKernel",0xA12A0514,sceIoSetAsyncCallback +#endif +#ifdef F_IoFileMgrForKernel_0007 + IMPORT_FUNC "IoFileMgrForKernel",0x810C4BC3,sceIoClose +#endif +#ifdef F_IoFileMgrForKernel_0008 + IMPORT_FUNC "IoFileMgrForKernel",0xFF5940B6,sceIoCloseAsync +#endif +#ifdef F_IoFileMgrForKernel_0009 + IMPORT_FUNC "IoFileMgrForKernel",0xA905B705,sceIoCloseAll +#endif +#ifdef F_IoFileMgrForKernel_0010 + IMPORT_FUNC "IoFileMgrForKernel",0x109F50BC,sceIoOpen +#endif +#ifdef F_IoFileMgrForKernel_0011 + IMPORT_FUNC "IoFileMgrForKernel",0x89AA9906,sceIoOpenAsync +#endif +#ifdef F_IoFileMgrForKernel_0012 + IMPORT_FUNC "IoFileMgrForKernel",0x3C54E908,sceIoReopen +#endif +#ifdef F_IoFileMgrForKernel_0013 + IMPORT_FUNC "IoFileMgrForKernel",0x6A638D83,sceIoRead +#endif +#ifdef F_IoFileMgrForKernel_0014 + IMPORT_FUNC "IoFileMgrForKernel",0xA0B5A7C2,sceIoReadAsync +#endif +#ifdef F_IoFileMgrForKernel_0015 + IMPORT_FUNC "IoFileMgrForKernel",0x42EC03AC,sceIoWrite +#endif +#ifdef F_IoFileMgrForKernel_0016 + IMPORT_FUNC "IoFileMgrForKernel",0x0FACAB19,sceIoWriteAsync +#endif +#ifdef F_IoFileMgrForKernel_0017 + IMPORT_FUNC "IoFileMgrForKernel",0x27EB27B8,sceIoLseek +#endif +#ifdef F_IoFileMgrForKernel_0018 + IMPORT_FUNC "IoFileMgrForKernel",0x71B19E77,sceIoLseekAsync +#endif +#ifdef F_IoFileMgrForKernel_0019 + IMPORT_FUNC "IoFileMgrForKernel",0x68963324,sceIoLseek32 +#endif +#ifdef F_IoFileMgrForKernel_0020 + IMPORT_FUNC "IoFileMgrForKernel",0x1B385D8F,sceIoLseek32Async +#endif +#ifdef F_IoFileMgrForKernel_0021 + IMPORT_FUNC "IoFileMgrForKernel",0x63632449,sceIoIoctl +#endif +#ifdef F_IoFileMgrForKernel_0022 + IMPORT_FUNC "IoFileMgrForKernel",0xE95A012B,sceIoIoctlAsync +#endif +#ifdef F_IoFileMgrForKernel_0023 + IMPORT_FUNC "IoFileMgrForKernel",0xB29DDF9C,sceIoDopen +#endif +#ifdef F_IoFileMgrForKernel_0024 + IMPORT_FUNC "IoFileMgrForKernel",0xE3EB004C,sceIoDread +#endif +#ifdef F_IoFileMgrForKernel_0025 + IMPORT_FUNC "IoFileMgrForKernel",0xEB092469,sceIoDclose +#endif +#ifdef F_IoFileMgrForKernel_0026 + IMPORT_FUNC "IoFileMgrForKernel",0xF27A9C51,sceIoRemove +#endif +#ifdef F_IoFileMgrForKernel_0027 + IMPORT_FUNC "IoFileMgrForKernel",0x06A70004,sceIoMkdir +#endif +#ifdef F_IoFileMgrForKernel_0028 + IMPORT_FUNC "IoFileMgrForKernel",0x1117C65F,sceIoRmdir +#endif +#ifdef F_IoFileMgrForKernel_0029 + IMPORT_FUNC "IoFileMgrForKernel",0x55F4717D,sceIoChdir +#endif +#ifdef F_IoFileMgrForKernel_0030 + IMPORT_FUNC "IoFileMgrForKernel",0xAB96437F,sceIoSync +#endif +#ifdef F_IoFileMgrForKernel_0031 + IMPORT_FUNC "IoFileMgrForKernel",0xACE946E8,sceIoGetstat +#endif +#ifdef F_IoFileMgrForKernel_0032 + IMPORT_FUNC "IoFileMgrForKernel",0xB8A740F4,sceIoChstat +#endif +#ifdef F_IoFileMgrForKernel_0033 + IMPORT_FUNC "IoFileMgrForKernel",0x779103A0,sceIoRename +#endif +#ifdef F_IoFileMgrForKernel_0034 + IMPORT_FUNC "IoFileMgrForKernel",0x54F5FB11,sceIoDevctl +#endif +#ifdef F_IoFileMgrForKernel_0035 + IMPORT_FUNC "IoFileMgrForKernel",0x08BD7374,sceIoGetDevType +#endif +#ifdef F_IoFileMgrForKernel_0036 + IMPORT_FUNC "IoFileMgrForKernel",0xB2A628C1,sceIoAssign +#endif +#ifdef F_IoFileMgrForKernel_0037 + IMPORT_FUNC "IoFileMgrForKernel",0x6D08A871,sceIoUnassign +#endif +#ifdef F_IoFileMgrForKernel_0038 + IMPORT_FUNC "IoFileMgrForKernel",0x411106BA,sceIoGetThreadCwd +#endif +#ifdef F_IoFileMgrForKernel_0039 + IMPORT_FUNC "IoFileMgrForKernel",0xCB0A151F,sceIoChangeThreadCwd +#endif +#ifdef F_IoFileMgrForKernel_0040 + IMPORT_FUNC "IoFileMgrForKernel",0xE8BC6571,sceIoCancel +#endif +#ifdef F_IoFileMgrForKernel_0041 + IMPORT_FUNC "IoFileMgrForKernel",0x8E982A74,sceIoAddDrv +#endif +#ifdef F_IoFileMgrForKernel_0042 + IMPORT_FUNC "IoFileMgrForKernel",0xC7F35804,sceIoDelDrv +#endif diff --git a/src/kernel/KDebugForKernel.S b/src/kernel/KDebugForKernel.S new file mode 100644 index 00000000..41716c7d --- /dev/null +++ b/src/kernel/KDebugForKernel.S @@ -0,0 +1,67 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_KDebugForKernel_0000 + IMPORT_START "KDebugForKernel",0x00010000 +#endif +#ifdef F_KDebugForKernel_0001 + IMPORT_FUNC "KDebugForKernel",0xE7A3874D,sceKernelRegisterAssertHandler +#endif +#ifdef F_KDebugForKernel_0002 + IMPORT_FUNC "KDebugForKernel",0x2FF4E9F9,sceKernelAssert +#endif +#ifdef F_KDebugForKernel_0003 + IMPORT_FUNC "KDebugForKernel",0x9B868276,sceKernelGetDebugPutchar +#endif +#ifdef F_KDebugForKernel_0004 + IMPORT_FUNC "KDebugForKernel",0xE146606D,sceKernelRegisterDebugPutchar +#endif +#ifdef F_KDebugForKernel_0005 + IMPORT_FUNC "KDebugForKernel",0x7CEB2C09,sceKernelRegisterKprintfHandler +#endif +#ifdef F_KDebugForKernel_0006 + IMPORT_FUNC "KDebugForKernel",0x84F370BC,Kprintf +#endif +#ifdef F_KDebugForKernel_0007 + IMPORT_FUNC "KDebugForKernel",0x5CE9838B,sceKernelDebugWrite +#endif +#ifdef F_KDebugForKernel_0008 + IMPORT_FUNC "KDebugForKernel",0x66253C4E,sceKernelRegisterDebugWrite +#endif +#ifdef F_KDebugForKernel_0009 + IMPORT_FUNC "KDebugForKernel",0xDBB5597F,sceKernelDebugRead +#endif +#ifdef F_KDebugForKernel_0010 + IMPORT_FUNC "KDebugForKernel",0xE6554FDA,sceKernelRegisterDebugRead +#endif +#ifdef F_KDebugForKernel_0011 + IMPORT_FUNC "KDebugForKernel",0xB9C643C9,sceKernelDebugEcho +#endif +#ifdef F_KDebugForKernel_0012 + IMPORT_FUNC "KDebugForKernel",0x7D1C74F0,sceKernelDebugEchoSet +#endif +#ifdef F_KDebugForKernel_0013 + IMPORT_FUNC "KDebugForKernel",0x24C32559,KDebugForKernel_24C32559 +#endif +#ifdef F_KDebugForKernel_0014 + IMPORT_FUNC "KDebugForKernel",0xD636B827,sceKernelRemoveByDebugSection +#endif +#ifdef F_KDebugForKernel_0015 + IMPORT_FUNC "KDebugForKernel",0x5282DD5E,KDebugForKernel_5282DD5E +#endif +#ifdef F_KDebugForKernel_0016 + IMPORT_FUNC "KDebugForKernel",0x9F8703E4,KDebugForKernel_9F8703E4 +#endif +#ifdef F_KDebugForKernel_0017 + IMPORT_FUNC "KDebugForKernel",0x333DCEC7,KDebugForKernel_333DCEC7 +#endif +#ifdef F_KDebugForKernel_0018 + IMPORT_FUNC "KDebugForKernel",0xE892D9A1,KDebugForKernel_E892D9A1 +#endif +#ifdef F_KDebugForKernel_0019 + IMPORT_FUNC "KDebugForKernel",0xA126F497,KDebugForKernel_A126F497 +#endif +#ifdef F_KDebugForKernel_0020 + IMPORT_FUNC "KDebugForKernel",0xB7251823,KDebugForKernel_B7251823 +#endif diff --git a/src/kernel/LoadCoreForKernel.S b/src/kernel/LoadCoreForKernel.S new file mode 100644 index 00000000..a645482d --- /dev/null +++ b/src/kernel/LoadCoreForKernel.S @@ -0,0 +1,97 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_LoadCoreForKernel_0000 + IMPORT_START "LoadCoreForKernel",0x00010000 +#endif +#ifdef F_LoadCoreForKernel_0001 + IMPORT_FUNC "LoadCoreForKernel",0xACE23476,sceKernelCheckPspConfig +#endif +#ifdef F_LoadCoreForKernel_0002 + IMPORT_FUNC "LoadCoreForKernel",0x7BE1421C,sceKernelCheckExecFile +#endif +#ifdef F_LoadCoreForKernel_0003 + IMPORT_FUNC "LoadCoreForKernel",0xBF983EF2,sceKernelProbeExecutableObject +#endif +#ifdef F_LoadCoreForKernel_0004 + IMPORT_FUNC "LoadCoreForKernel",0x7068E6BA,sceKernelLoadExecutableObject +#endif +#ifdef F_LoadCoreForKernel_0005 + IMPORT_FUNC "LoadCoreForKernel",0xB4D6FECC,sceKernelApplyElfRelSection +#endif +#ifdef F_LoadCoreForKernel_0006 + IMPORT_FUNC "LoadCoreForKernel",0x54AB2675,sceKernelApplyPspRelSection +#endif +#ifdef F_LoadCoreForKernel_0007 + IMPORT_FUNC "LoadCoreForKernel",0x2952F5AC,sceKernelDcacheWBinvAll +#endif +#ifdef F_LoadCoreForKernel_0008 + IMPORT_FUNC "LoadCoreForKernel",0xD8779AC6,sceKernelIcacheClearAll +#endif +#ifdef F_LoadCoreForKernel_0009 + IMPORT_FUNC "LoadCoreForKernel",0x99A695F0,sceKernelRegisterLibrary +#endif +#ifdef F_LoadCoreForKernel_0010 + IMPORT_FUNC "LoadCoreForKernel",0x5873A31F,sceKernelRegisterLibraryForUser +#endif +#ifdef F_LoadCoreForKernel_0011 + IMPORT_FUNC "LoadCoreForKernel",0x0B464512,sceKernelReleaseLibrary +#endif +#ifdef F_LoadCoreForKernel_0012 + IMPORT_FUNC "LoadCoreForKernel",0x9BAF90F6,sceKernelCanReleaseLibrary +#endif +#ifdef F_LoadCoreForKernel_0013 + IMPORT_FUNC "LoadCoreForKernel",0x0E760DBA,sceKernelLinkLibraryEntries +#endif +#ifdef F_LoadCoreForKernel_0014 + IMPORT_FUNC "LoadCoreForKernel",0x0DE1F600,sceKernelLinkLibraryEntriesForUser +#endif +#ifdef F_LoadCoreForKernel_0015 + IMPORT_FUNC "LoadCoreForKernel",0xDA1B09AA,sceKernelUnLinkLibraryEntries +#endif +#ifdef F_LoadCoreForKernel_0016 + IMPORT_FUNC "LoadCoreForKernel",0xC99DD47A,sceKernelQueryLoadCoreCB +#endif +#ifdef F_LoadCoreForKernel_0017 + IMPORT_FUNC "LoadCoreForKernel",0x616FCCCD,LoadCoreForKernel_616FCCCD +#endif +#ifdef F_LoadCoreForKernel_0018 + IMPORT_FUNC "LoadCoreForKernel",0xF32A2940,sceKernelModuleFromUID +#endif +#ifdef F_LoadCoreForKernel_0019 + IMPORT_FUNC "LoadCoreForKernel",0xCD0F3BAC,sceKernelCreateModule +#endif +#ifdef F_LoadCoreForKernel_0020 + IMPORT_FUNC "LoadCoreForKernel",0x6B2371C2,sceKernelDeleteModule +#endif +#ifdef F_LoadCoreForKernel_0021 + IMPORT_FUNC "LoadCoreForKernel",0x7320D964,sceKernelModuleAssign +#endif +#ifdef F_LoadCoreForKernel_0022 + IMPORT_FUNC "LoadCoreForKernel",0x44B292AB,sceKernelAllocModule +#endif +#ifdef F_LoadCoreForKernel_0023 + IMPORT_FUNC "LoadCoreForKernel",0xBD61D4D5,sceKernelFreeModule +#endif +#ifdef F_LoadCoreForKernel_0024 + IMPORT_FUNC "LoadCoreForKernel",0xAE7C6E76,sceKernelRegisterModule +#endif +#ifdef F_LoadCoreForKernel_0025 + IMPORT_FUNC "LoadCoreForKernel",0x74CF001A,sceKernelReleaseModule +#endif +#ifdef F_LoadCoreForKernel_0026 + IMPORT_FUNC "LoadCoreForKernel",0xCF8A41B1,sceKernelFindModuleByName +#endif +#ifdef F_LoadCoreForKernel_0027 + IMPORT_FUNC "LoadCoreForKernel",0xFB8AE27D,sceKernelFindModuleByAddress +#endif +#ifdef F_LoadCoreForKernel_0028 + IMPORT_FUNC "LoadCoreForKernel",0xCCE4A157,sceKernelFindModuleByUID +#endif +#ifdef F_LoadCoreForKernel_0029 + IMPORT_FUNC "LoadCoreForKernel",0x82CE54ED,sceKernelModuleCount +#endif +#ifdef F_LoadCoreForKernel_0030 + IMPORT_FUNC "LoadCoreForKernel",0xC0584F0C,sceKernelGetModuleList +#endif diff --git a/src/kernel/LoadExecForKernel.S b/src/kernel/LoadExecForKernel.S new file mode 100644 index 00000000..5a372673 --- /dev/null +++ b/src/kernel/LoadExecForKernel.S @@ -0,0 +1,85 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_LoadExecForKernel_0000 + IMPORT_START "LoadExecForKernel",0x00010000 +#endif +#ifdef F_LoadExecForKernel_0001 + IMPORT_FUNC "LoadExecForKernel",0xBD2F1094,sceKernelLoadExec +#endif +#ifdef F_LoadExecForKernel_0002 + IMPORT_FUNC "LoadExecForKernel",0x2AC9954B,sceKernelExitGameWithStatus +#endif +#ifdef F_LoadExecForKernel_0003 + IMPORT_FUNC "LoadExecForKernel",0x05572A5F,sceKernelExitGame +#endif +#ifdef F_LoadExecForKernel_0004 + IMPORT_FUNC "LoadExecForKernel",0xAC085B9E,sceKernelLoadExecVSHFromHost +#endif +#ifdef F_LoadExecForKernel_0005 + IMPORT_FUNC "LoadExecForKernel",0x1B97BDB3,sceKernelLoadExecVSHDisc +#endif +#ifdef F_LoadExecForKernel_0006 + IMPORT_FUNC "LoadExecForKernel",0x821BE114,sceKernelLoadExecVSHDiscUpdater +#endif +#ifdef F_LoadExecForKernel_0007 + IMPORT_FUNC "LoadExecForKernel",0x015DA036,sceKernelLoadExecBufferVSHUsbWlan +#endif +#ifdef F_LoadExecForKernel_0008 + IMPORT_FUNC "LoadExecForKernel",0x4F41E75E,sceKernelLoadExecBufferVSHUsbWlanDebug +#endif +#ifdef F_LoadExecForKernel_0009 + IMPORT_FUNC "LoadExecForKernel",0x31DF42BF,sceKernelLoadExecVSHMs1 +#endif +#ifdef F_LoadExecForKernel_0010 + IMPORT_FUNC "LoadExecForKernel",0x28D0D249,sceKernelLoadExecVSHMs2 +#endif +#ifdef F_LoadExecForKernel_0011 + IMPORT_FUNC "LoadExecForKernel",0x70901231,sceKernelLoadExecVSHMs3 +#endif +#ifdef F_LoadExecForKernel_0012 + IMPORT_FUNC "LoadExecForKernel",0xA3D5E142,sceKernelExitVSHVSH +#endif +#ifdef F_LoadExecForKernel_0013 + IMPORT_FUNC "LoadExecForKernel",0x62C459E1,sceKernelLoadExecBufferVSHPlain +#endif +#ifdef F_LoadExecForKernel_0014 + IMPORT_FUNC "LoadExecForKernel",0x918782E8,sceKernelLoadExecBufferVSHFromHost +#endif +#ifdef F_LoadExecForKernel_0015 + IMPORT_FUNC "LoadExecForKernel",0xBB28E9B7,sceKernelLoadExecBufferPlain0 +#endif +#ifdef F_LoadExecForKernel_0016 + IMPORT_FUNC "LoadExecForKernel",0x71A1D738,sceKernelLoadExecBufferPlain +#endif +#ifdef F_LoadExecForKernel_0017 + IMPORT_FUNC "LoadExecForKernel",0x4D5C75BE,sceKernelLoadExecFromHost +#endif +#ifdef F_LoadExecForKernel_0018 + IMPORT_FUNC "LoadExecForKernel",0x4AC57943,sceKernelRegisterExitCallback +#endif +#ifdef F_LoadExecForKernel_0019 + IMPORT_FUNC "LoadExecForKernel",0xD9739B89,sceKernelUnregisterExitCallback +#endif +#ifdef F_LoadExecForKernel_0020 + IMPORT_FUNC "LoadExecForKernel",0x659188E1,sceKernelCheckExitCallback +#endif +#ifdef F_LoadExecForKernel_0021 + IMPORT_FUNC "LoadExecForKernel",0x62A27008,sceKernelInvokeExitCallback +#endif +#ifdef F_LoadExecForKernel_0022 + IMPORT_FUNC "LoadExecForKernel",0x7B7C47EF,sceKernelLoadExecVSHDiscDebug +#endif +#ifdef F_LoadExecForKernel_0023 + IMPORT_FUNC "LoadExecForKernel",0x061D9514,sceKernelLoadExecVSHMs4 +#endif +#ifdef F_LoadExecForKernel_0024 + IMPORT_FUNC "LoadExecForKernel",0xB7AB08DA,sceKernelLoadExecVSHMs5 +#endif +#ifdef F_LoadExecForKernel_0025 + IMPORT_FUNC "LoadExecForKernel",0x6D302D3D,sceKernelExitVSHKernel +#endif +#ifdef F_LoadExecForKernel_0026 + IMPORT_FUNC "LoadExecForKernel",0x11412288,LoadExecForKernel_11412288 +#endif diff --git a/src/kernel/Makefile.am b/src/kernel/Makefile.am new file mode 100644 index 00000000..5d2baf78 --- /dev/null +++ b/src/kernel/Makefile.am @@ -0,0 +1,166 @@ + +libdir = @PSPSDK_LIBDIR@ + +CC = @PSP_CC@ +CCAS = $(CC) +AR = @PSP_AR@ +RANLIB = @PSP_RANLIB@ + +INCLUDES = -I$(top_srcdir)/src/base -I$(top_srcdir)/src/user +CFLAGS = @PSPSDK_CFLAGS@ +CCASFLAGS = $(CFLAGS) $(INCLUDES) + +EXCEPTION_OBJS = ExceptionManagerForKernel_0000.o ExceptionManagerForKernel_0001.o ExceptionManagerForKernel_0002.o ExceptionManagerForKernel_0003.o ExceptionManagerForKernel_0004.o ExceptionManagerForKernel_0005.o ExceptionManagerForKernel_0006.o ExceptionManagerForKernel_0007.o ExceptionManagerForKernel_0008.o + +KDEBUG_OBJS = KDebugForKernel_0000.o KDebugForKernel_0001.o KDebugForKernel_0002.o KDebugForKernel_0003.o KDebugForKernel_0004.o KDebugForKernel_0005.o KDebugForKernel_0006.o KDebugForKernel_0007.o KDebugForKernel_0008.o KDebugForKernel_0009.o KDebugForKernel_0010.o KDebugForKernel_0011.o KDebugForKernel_0012.o KDebugForKernel_0013.o KDebugForKernel_0014.o KDebugForKernel_0015.o KDebugForKernel_0016.o KDebugForKernel_0017.o KDebugForKernel_0018.o KDebugForKernel_0019.o KDebugForKernel_0020.o + +LOADCORE_OBJS = LoadCoreForKernel_0000.o LoadCoreForKernel_0001.o LoadCoreForKernel_0002.o LoadCoreForKernel_0003.o LoadCoreForKernel_0004.o LoadCoreForKernel_0005.o LoadCoreForKernel_0006.o LoadCoreForKernel_0007.o LoadCoreForKernel_0008.o LoadCoreForKernel_0009.o LoadCoreForKernel_0010.o LoadCoreForKernel_0011.o LoadCoreForKernel_0012.o LoadCoreForKernel_0013.o LoadCoreForKernel_0014.o LoadCoreForKernel_0015.o LoadCoreForKernel_0016.o LoadCoreForKernel_0017.o LoadCoreForKernel_0018.o LoadCoreForKernel_0019.o LoadCoreForKernel_0020.o LoadCoreForKernel_0021.o LoadCoreForKernel_0022.o LoadCoreForKernel_0023.o LoadCoreForKernel_0024.o LoadCoreForKernel_0025.o LoadCoreForKernel_0026.o LoadCoreForKernel_0027.o LoadCoreForKernel_0028.o LoadCoreForKernel_0029.o LoadCoreForKernel_0030.o + +IO_OBJS = IoFileMgrForKernel_0000.o IoFileMgrForKernel_0001.o IoFileMgrForKernel_0002.o IoFileMgrForKernel_0003.o IoFileMgrForKernel_0004.o IoFileMgrForKernel_0005.o IoFileMgrForKernel_0006.o IoFileMgrForKernel_0007.o IoFileMgrForKernel_0008.o IoFileMgrForKernel_0009.o IoFileMgrForKernel_0010.o IoFileMgrForKernel_0011.o IoFileMgrForKernel_0012.o IoFileMgrForKernel_0013.o IoFileMgrForKernel_0014.o IoFileMgrForKernel_0015.o IoFileMgrForKernel_0016.o IoFileMgrForKernel_0017.o IoFileMgrForKernel_0018.o IoFileMgrForKernel_0019.o IoFileMgrForKernel_0020.o IoFileMgrForKernel_0021.o IoFileMgrForKernel_0022.o IoFileMgrForKernel_0023.o IoFileMgrForKernel_0024.o IoFileMgrForKernel_0025.o IoFileMgrForKernel_0026.o IoFileMgrForKernel_0027.o IoFileMgrForKernel_0028.o IoFileMgrForKernel_0029.o IoFileMgrForKernel_0030.o IoFileMgrForKernel_0031.o IoFileMgrForKernel_0032.o IoFileMgrForKernel_0033.o IoFileMgrForKernel_0034.o IoFileMgrForKernel_0035.o IoFileMgrForKernel_0036.o IoFileMgrForKernel_0037.o IoFileMgrForKernel_0038.o IoFileMgrForKernel_0039.o IoFileMgrForKernel_0040.o IoFileMgrForKernel_0041.o IoFileMgrForKernel_0042.o + +STDIO_OBJS = StdioForKernel_0000.o StdioForKernel_0001.o StdioForKernel_0002.o StdioForKernel_0003.o StdioForKernel_0004.o StdioForKernel_0005.o StdioForKernel_0006.o StdioForKernel_0007.o StdioForKernel_0008.o StdioForKernel_0009.o StdioForKernel_0010.o StdioForKernel_0011.o StdioForKernel_0012.o StdioForKernel_0013.o StdioForKernel_0014.o StdioForKernel_0015.o + +SYSREG_OBJS = sceSysreg_driver_0000.o sceSysreg_driver_0001.o sceSysreg_driver_0002.o sceSysreg_driver_0003.o sceSysreg_driver_0004.o sceSysreg_driver_0005.o sceSysreg_driver_0006.o sceSysreg_driver_0007.o sceSysreg_driver_0008.o sceSysreg_driver_0009.o sceSysreg_driver_0010.o sceSysreg_driver_0011.o sceSysreg_driver_0012.o sceSysreg_driver_0013.o sceSysreg_driver_0014.o sceSysreg_driver_0015.o sceSysreg_driver_0016.o sceSysreg_driver_0017.o sceSysreg_driver_0018.o sceSysreg_driver_0019.o sceSysreg_driver_0020.o sceSysreg_driver_0021.o sceSysreg_driver_0022.o sceSysreg_driver_0023.o sceSysreg_driver_0024.o sceSysreg_driver_0025.o sceSysreg_driver_0026.o sceSysreg_driver_0027.o sceSysreg_driver_0028.o sceSysreg_driver_0029.o sceSysreg_driver_0030.o sceSysreg_driver_0031.o sceSysreg_driver_0032.o sceSysreg_driver_0033.o sceSysreg_driver_0034.o sceSysreg_driver_0035.o sceSysreg_driver_0036.o sceSysreg_driver_0037.o sceSysreg_driver_0038.o sceSysreg_driver_0039.o sceSysreg_driver_0040.o sceSysreg_driver_0041.o sceSysreg_driver_0042.o sceSysreg_driver_0043.o sceSysreg_driver_0044.o sceSysreg_driver_0045.o sceSysreg_driver_0046.o sceSysreg_driver_0047.o sceSysreg_driver_0048.o sceSysreg_driver_0049.o sceSysreg_driver_0050.o sceSysreg_driver_0051.o sceSysreg_driver_0052.o sceSysreg_driver_0053.o sceSysreg_driver_0054.o sceSysreg_driver_0055.o sceSysreg_driver_0056.o sceSysreg_driver_0057.o sceSysreg_driver_0058.o sceSysreg_driver_0059.o sceSysreg_driver_0060.o sceSysreg_driver_0061.o sceSysreg_driver_0062.o sceSysreg_driver_0063.o sceSysreg_driver_0064.o sceSysreg_driver_0065.o sceSysreg_driver_0066.o sceSysreg_driver_0067.o sceSysreg_driver_0068.o sceSysreg_driver_0069.o sceSysreg_driver_0070.o sceSysreg_driver_0071.o sceSysreg_driver_0072.o sceSysreg_driver_0073.o sceSysreg_driver_0074.o sceSysreg_driver_0075.o sceSysreg_driver_0076.o sceSysreg_driver_0077.o sceSysreg_driver_0078.o sceSysreg_driver_0079.o sceSysreg_driver_0080.o sceSysreg_driver_0081.o sceSysreg_driver_0082.o sceSysreg_driver_0083.o sceSysreg_driver_0084.o sceSysreg_driver_0085.o sceSysreg_driver_0086.o sceSysreg_driver_0087.o sceSysreg_driver_0088.o sceSysreg_driver_0089.o sceSysreg_driver_0090.o sceSysreg_driver_0091.o sceSysreg_driver_0092.o sceSysreg_driver_0093.o sceSysreg_driver_0094.o sceSysreg_driver_0095.o sceSysreg_driver_0096.o sceSysreg_driver_0097.o sceSysreg_driver_0098.o sceSysreg_driver_0099.o sceSysreg_driver_0100.o sceSysreg_driver_0101.o sceSysreg_driver_0102.o sceSysreg_driver_0103.o sceSysreg_driver_0104.o sceSysreg_driver_0105.o sceSysreg_driver_0106.o sceSysreg_driver_0107.o sceSysreg_driver_0108.o sceSysreg_driver_0109.o sceSysreg_driver_0110.o sceSysreg_driver_0111.o sceSysreg_driver_0112.o sceSysreg_driver_0113.o sceSysreg_driver_0114.o sceSysreg_driver_0115.o sceSysreg_driver_0116.o sceSysreg_driver_0117.o sceSysreg_driver_0118.o sceSysreg_driver_0119.o sceSysreg_driver_0120.o sceSysreg_driver_0121.o sceSysreg_driver_0122.o sceSysreg_driver_0123.o sceSysreg_driver_0124.o sceSysreg_driver_0125.o sceSysreg_driver_0126.o sceSysreg_driver_0127.o sceSysreg_driver_0128.o sceSysreg_driver_0129.o sceSysreg_driver_0130.o sceSysreg_driver_0131.o sceSysreg_driver_0132.o sceSysreg_driver_0133.o sceSysreg_driver_0134.o sceSysreg_driver_0135.o sceSysreg_driver_0136.o sceSysreg_driver_0137.o sceSysreg_driver_0138.o sceSysreg_driver_0139.o sceSysreg_driver_0140.o sceSysreg_driver_0141.o sceSysreg_driver_0142.o sceSysreg_driver_0143.o sceSysreg_driver_0144.o sceSysreg_driver_0145.o sceSysreg_driver_0146.o sceSysreg_driver_0147.o sceSysreg_driver_0148.o sceSysreg_driver_0149.o sceSysreg_driver_0150.o sceSysreg_driver_0151.o + +UTILS_OBJS = UtilsForKernel_0000.o UtilsForKernel_0001.o UtilsForKernel_0002.o UtilsForKernel_0003.o UtilsForKernel_0004.o UtilsForKernel_0005.o UtilsForKernel_0006.o UtilsForKernel_0007.o UtilsForKernel_0008.o UtilsForKernel_0009.o UtilsForKernel_0010.o UtilsForKernel_0011.o UtilsForKernel_0012.o UtilsForKernel_0013.o UtilsForKernel_0014.o UtilsForKernel_0015.o UtilsForKernel_0016.o UtilsForKernel_0017.o UtilsForKernel_0018.o UtilsForKernel_0019.o UtilsForKernel_0020.o UtilsForKernel_0021.o UtilsForKernel_0022.o UtilsForKernel_0023.o UtilsForKernel_0024.o UtilsForKernel_0025.o UtilsForKernel_0026.o UtilsForKernel_0027.o UtilsForKernel_0028.o UtilsForKernel_0029.o UtilsForKernel_0030.o UtilsForKernel_0031.o UtilsForKernel_0032.o UtilsForKernel_0033.o UtilsForKernel_0034.o UtilsForKernel_0035.o UtilsForKernel_0036.o UtilsForKernel_0037.o UtilsForKernel_0038.o UtilsForKernel_0039.o + +SYSCON_OBJS = sceSyscon_driver_0000.o sceSyscon_driver_0001.o sceSyscon_driver_0002.o sceSyscon_driver_0003.o sceSyscon_driver_0004.o sceSyscon_driver_0005.o sceSyscon_driver_0006.o sceSyscon_driver_0007.o sceSyscon_driver_0008.o sceSyscon_driver_0009.o sceSyscon_driver_0010.o sceSyscon_driver_0011.o sceSyscon_driver_0012.o sceSyscon_driver_0013.o sceSyscon_driver_0014.o sceSyscon_driver_0015.o sceSyscon_driver_0016.o sceSyscon_driver_0017.o sceSyscon_driver_0018.o sceSyscon_driver_0019.o sceSyscon_driver_0020.o sceSyscon_driver_0021.o sceSyscon_driver_0022.o sceSyscon_driver_0023.o sceSyscon_driver_0024.o sceSyscon_driver_0025.o sceSyscon_driver_0026.o sceSyscon_driver_0027.o sceSyscon_driver_0028.o sceSyscon_driver_0029.o sceSyscon_driver_0030.o sceSyscon_driver_0031.o sceSyscon_driver_0032.o sceSyscon_driver_0033.o sceSyscon_driver_0034.o sceSyscon_driver_0035.o sceSyscon_driver_0036.o sceSyscon_driver_0037.o sceSyscon_driver_0038.o sceSyscon_driver_0039.o sceSyscon_driver_0040.o sceSyscon_driver_0041.o sceSyscon_driver_0042.o sceSyscon_driver_0043.o sceSyscon_driver_0044.o sceSyscon_driver_0045.o sceSyscon_driver_0046.o sceSyscon_driver_0047.o sceSyscon_driver_0048.o sceSyscon_driver_0049.o sceSyscon_driver_0050.o sceSyscon_driver_0051.o sceSyscon_driver_0052.o sceSyscon_driver_0053.o sceSyscon_driver_0054.o sceSyscon_driver_0055.o sceSyscon_driver_0056.o sceSyscon_driver_0057.o sceSyscon_driver_0058.o sceSyscon_driver_0059.o sceSyscon_driver_0060.o sceSyscon_driver_0061.o sceSyscon_driver_0062.o sceSyscon_driver_0063.o sceSyscon_driver_0064.o sceSyscon_driver_0065.o sceSyscon_driver_0066.o sceSyscon_driver_0067.o sceSyscon_driver_0068.o sceSyscon_driver_0069.o sceSyscon_driver_0070.o sceSyscon_driver_0071.o sceSyscon_driver_0072.o sceSyscon_driver_0073.o sceSyscon_driver_0074.o sceSyscon_driver_0075.o sceSyscon_driver_0076.o sceSyscon_driver_0077.o sceSyscon_driver_0078.o sceSyscon_driver_0079.o sceSyscon_driver_0080.o sceSyscon_driver_0081.o sceSyscon_driver_0082.o sceSyscon_driver_0083.o sceSyscon_driver_0084.o sceSyscon_driver_0085.o sceSyscon_driver_0086.o sceSyscon_driver_0087.o sceSyscon_driver_0088.o sceSyscon_driver_0089.o sceSyscon_driver_0090.o sceSyscon_driver_0091.o sceSyscon_driver_0092.o sceSyscon_driver_0093.o sceSyscon_driver_0094.o sceSyscon_driver_0095.o sceSyscon_driver_0096.o sceSyscon_driver_0097.o sceSyscon_driver_0098.o sceSyscon_driver_0099.o sceSyscon_driver_0100.o sceSyscon_driver_0101.o sceSyscon_driver_0102.o sceSyscon_driver_0103.o sceSyscon_driver_0104.o sceSyscon_driver_0105.o sceSyscon_driver_0106.o sceSyscon_driver_0107.o sceSyscon_driver_0108.o sceSyscon_driver_0109.o sceSyscon_driver_0110.o sceSyscon_driver_0111.o sceSyscon_driver_0112.o sceSyscon_driver_0113.o + +INTR_OBJS = InterruptManagerForKernel_0000.o InterruptManagerForKernel_0001.o InterruptManagerForKernel_0002.o InterruptManagerForKernel_0003.o InterruptManagerForKernel_0004.o InterruptManagerForKernel_0005.o InterruptManagerForKernel_0006.o InterruptManagerForKernel_0007.o InterruptManagerForKernel_0008.o InterruptManagerForKernel_0009.o InterruptManagerForKernel_0010.o InterruptManagerForKernel_0011.o InterruptManagerForKernel_0012.o InterruptManagerForKernel_0013.o InterruptManagerForKernel_0014.o InterruptManagerForKernel_0015.o InterruptManagerForKernel_0016.o InterruptManagerForKernel_0017.o InterruptManagerForKernel_0018.o InterruptManagerForKernel_0019.o InterruptManagerForKernel_0020.o InterruptManagerForKernel_0021.o InterruptManagerForKernel_0022.o InterruptManagerForKernel_0023.o InterruptManagerForKernel_0024.o InterruptManagerForKernel_0025.o InterruptManagerForKernel_0026.o InterruptManagerForKernel_0027.o InterruptManagerForKernel_0028.o InterruptManagerForKernel_0029.o InterruptManagerForKernel_0030.o InterruptManagerForKernel_0031.o InterruptManagerForKernel_0032.o InterruptManagerForKernel_0033.o InterruptManagerForKernel_0034.o InterruptManagerForKernel_0035.o InterruptManagerForKernel_0036.o InterruptManagerForKernel_0037.o InterruptManagerForKernel_0038.o InterruptManagerForKernel_0039.o InterruptManagerForKernel_0040.o InterruptManagerForKernel_0041.o InterruptManagerForKernel_0042.o InterruptManagerForKernel_0043.o InterruptManagerForKernel_0044.o + +THREAD_OBJS = ThreadManForKernel_0000.o ThreadManForKernel_0001.o ThreadManForKernel_0002.o ThreadManForKernel_0003.o ThreadManForKernel_0004.o ThreadManForKernel_0005.o ThreadManForKernel_0006.o ThreadManForKernel_0007.o ThreadManForKernel_0008.o ThreadManForKernel_0009.o ThreadManForKernel_0010.o ThreadManForKernel_0011.o ThreadManForKernel_0012.o ThreadManForKernel_0013.o ThreadManForKernel_0014.o ThreadManForKernel_0015.o ThreadManForKernel_0016.o ThreadManForKernel_0017.o ThreadManForKernel_0018.o ThreadManForKernel_0019.o ThreadManForKernel_0020.o ThreadManForKernel_0021.o ThreadManForKernel_0022.o ThreadManForKernel_0023.o ThreadManForKernel_0024.o ThreadManForKernel_0025.o ThreadManForKernel_0026.o ThreadManForKernel_0027.o ThreadManForKernel_0028.o ThreadManForKernel_0029.o ThreadManForKernel_0030.o ThreadManForKernel_0031.o ThreadManForKernel_0032.o ThreadManForKernel_0033.o ThreadManForKernel_0034.o ThreadManForKernel_0035.o ThreadManForKernel_0036.o ThreadManForKernel_0037.o ThreadManForKernel_0038.o ThreadManForKernel_0039.o ThreadManForKernel_0040.o ThreadManForKernel_0041.o ThreadManForKernel_0042.o ThreadManForKernel_0043.o ThreadManForKernel_0044.o ThreadManForKernel_0045.o ThreadManForKernel_0046.o ThreadManForKernel_0047.o ThreadManForKernel_0048.o ThreadManForKernel_0049.o ThreadManForKernel_0050.o ThreadManForKernel_0051.o ThreadManForKernel_0052.o ThreadManForKernel_0053.o ThreadManForKernel_0054.o ThreadManForKernel_0055.o ThreadManForKernel_0056.o ThreadManForKernel_0057.o ThreadManForKernel_0058.o ThreadManForKernel_0059.o ThreadManForKernel_0060.o ThreadManForKernel_0061.o ThreadManForKernel_0062.o ThreadManForKernel_0063.o ThreadManForKernel_0064.o ThreadManForKernel_0065.o ThreadManForKernel_0066.o ThreadManForKernel_0067.o ThreadManForKernel_0068.o ThreadManForKernel_0069.o ThreadManForKernel_0070.o ThreadManForKernel_0071.o ThreadManForKernel_0072.o ThreadManForKernel_0073.o ThreadManForKernel_0074.o ThreadManForKernel_0075.o ThreadManForKernel_0076.o ThreadManForKernel_0077.o ThreadManForKernel_0078.o ThreadManForKernel_0079.o ThreadManForKernel_0080.o ThreadManForKernel_0081.o ThreadManForKernel_0082.o ThreadManForKernel_0083.o ThreadManForKernel_0084.o ThreadManForKernel_0085.o ThreadManForKernel_0086.o ThreadManForKernel_0087.o ThreadManForKernel_0088.o ThreadManForKernel_0089.o ThreadManForKernel_0090.o ThreadManForKernel_0091.o ThreadManForKernel_0092.o ThreadManForKernel_0093.o ThreadManForKernel_0094.o ThreadManForKernel_0095.o ThreadManForKernel_0096.o ThreadManForKernel_0097.o ThreadManForKernel_0098.o ThreadManForKernel_0099.o ThreadManForKernel_0100.o ThreadManForKernel_0101.o ThreadManForKernel_0102.o ThreadManForKernel_0103.o ThreadManForKernel_0104.o ThreadManForKernel_0105.o ThreadManForKernel_0106.o ThreadManForKernel_0107.o ThreadManForKernel_0108.o ThreadManForKernel_0109.o ThreadManForKernel_0110.o ThreadManForKernel_0111.o ThreadManForKernel_0112.o ThreadManForKernel_0113.o ThreadManForKernel_0114.o ThreadManForKernel_0115.o ThreadManForKernel_0116.o ThreadManForKernel_0117.o ThreadManForKernel_0118.o ThreadManForKernel_0119.o ThreadManForKernel_0120.o ThreadManForKernel_0121.o ThreadManForKernel_0122.o ThreadManForKernel_0123.o ThreadManForKernel_0124.o ThreadManForKernel_0125.o ThreadManForKernel_0126.o ThreadManForKernel_0127.o ThreadManForKernel_0128.o ThreadManForKernel_0129.o ThreadManForKernel_0130.o ThreadManForKernel_0131.o ThreadManForKernel_0132.o ThreadManForKernel_0133.o ThreadManForKernel_0134.o ThreadManForKernel_0135.o + +SYSCLIB_OBJS = SysclibForKernel_0000.o SysclibForKernel_0001.o SysclibForKernel_0002.o SysclibForKernel_0003.o SysclibForKernel_0004.o SysclibForKernel_0005.o SysclibForKernel_0006.o SysclibForKernel_0007.o SysclibForKernel_0008.o SysclibForKernel_0009.o SysclibForKernel_0010.o SysclibForKernel_0011.o SysclibForKernel_0012.o SysclibForKernel_0013.o SysclibForKernel_0014.o SysclibForKernel_0015.o SysclibForKernel_0016.o SysclibForKernel_0017.o SysclibForKernel_0018.o SysclibForKernel_0019.o SysclibForKernel_0020.o SysclibForKernel_0021.o SysclibForKernel_0022.o SysclibForKernel_0023.o SysclibForKernel_0024.o SysclibForKernel_0025.o SysclibForKernel_0026.o SysclibForKernel_0027.o SysclibForKernel_0028.o SysclibForKernel_0029.o SysclibForKernel_0030.o SysclibForKernel_0031.o SysclibForKernel_0032.o SysclibForKernel_0033.o SysclibForKernel_0034.o SysclibForKernel_0035.o SysclibForKernel_0036.o SysclibForKernel_0037.o SysclibForKernel_0038.o SysclibForKernel_0039.o SysclibForKernel_0040.o SysclibForKernel_0041.o SysclibForKernel_0042.o + +LOADEXEC_OBJS = LoadExecForKernel_0000.o LoadExecForKernel_0001.o LoadExecForKernel_0002.o LoadExecForKernel_0003.o LoadExecForKernel_0004.o LoadExecForKernel_0005.o LoadExecForKernel_0006.o LoadExecForKernel_0007.o LoadExecForKernel_0008.o LoadExecForKernel_0009.o LoadExecForKernel_0010.o LoadExecForKernel_0011.o LoadExecForKernel_0012.o LoadExecForKernel_0013.o LoadExecForKernel_0014.o LoadExecForKernel_0015.o LoadExecForKernel_0016.o LoadExecForKernel_0017.o LoadExecForKernel_0018.o LoadExecForKernel_0019.o LoadExecForKernel_0020.o LoadExecForKernel_0021.o LoadExecForKernel_0022.o LoadExecForKernel_0023.o LoadExecForKernel_0024.o LoadExecForKernel_0025.o LoadExecForKernel_0026.o + +SYSMEM_OBJS = SysMemForKernel_0000.o SysMemForKernel_0001.o SysMemForKernel_0002.o SysMemForKernel_0003.o SysMemForKernel_0004.o SysMemForKernel_0005.o SysMemForKernel_0006.o SysMemForKernel_0007.o SysMemForKernel_0008.o SysMemForKernel_0009.o SysMemForKernel_0010.o SysMemForKernel_0011.o SysMemForKernel_0012.o SysMemForKernel_0013.o SysMemForKernel_0014.o SysMemForKernel_0015.o SysMemForKernel_0016.o SysMemForKernel_0017.o SysMemForKernel_0018.o SysMemForKernel_0019.o SysMemForKernel_0020.o SysMemForKernel_0021.o SysMemForKernel_0022.o SysMemForKernel_0023.o SysMemForKernel_0024.o SysMemForKernel_0025.o SysMemForKernel_0026.o SysMemForKernel_0027.o SysMemForKernel_0028.o SysMemForKernel_0029.o SysMemForKernel_0030.o SysMemForKernel_0031.o SysMemForKernel_0032.o SysMemForKernel_0033.o SysMemForKernel_0034.o SysMemForKernel_0035.o SysMemForKernel_0036.o SysMemForKernel_0037.o SysMemForKernel_0038.o SysMemForKernel_0039.o SysMemForKernel_0040.o SysMemForKernel_0041.o SysMemForKernel_0042.o SysMemForKernel_0043.o SysMemForKernel_0044.o SysMemForKernel_0045.o SysMemForKernel_0046.o SysMemForKernel_0047.o SysMemForKernel_0048.o SysMemForKernel_0049.o SysMemForKernel_0050.o SysMemForKernel_0051.o SysMemForKernel_0052.o SysMemForKernel_0053.o SysMemForKernel_0054.o SysMemForKernel_0055.o SysMemForKernel_0056.o SysMemForKernel_0057.o SysMemForKernel_0058.o SysMemForKernel_0059.o SysMemForKernel_0060.o SysMemForKernel_0061.o SysMemForKernel_0062.o SysMemForKernel_0063.o SysMemForKernel_0064.o SysMemForKernel_0065.o SysMemForKernel_0066.o SysMemForKernel_0067.o SysMemForKernel_0068.o + +MODULE_OBJS = ModuleMgrForKernel_0000.o ModuleMgrForKernel_0001.o ModuleMgrForKernel_0002.o ModuleMgrForKernel_0003.o ModuleMgrForKernel_0004.o ModuleMgrForKernel_0005.o ModuleMgrForKernel_0006.o ModuleMgrForKernel_0007.o ModuleMgrForKernel_0008.o ModuleMgrForKernel_0009.o ModuleMgrForKernel_0010.o ModuleMgrForKernel_0011.o ModuleMgrForKernel_0012.o ModuleMgrForKernel_0013.o ModuleMgrForKernel_0014.o ModuleMgrForKernel_0015.o ModuleMgrForKernel_0016.o ModuleMgrForKernel_0017.o ModuleMgrForKernel_0018.o ModuleMgrForKernel_0019.o ModuleMgrForKernel_0020.o ModuleMgrForKernel_0021.o ModuleMgrForKernel_0022.o + +IDSTORAGE_OBJS = sceIdStorage_driver_0000.o sceIdStorage_driver_0001.o sceIdStorage_driver_0002.o sceIdStorage_driver_0003.o sceIdStorage_driver_0004.o sceIdStorage_driver_0005.o sceIdStorage_driver_0006.o sceIdStorage_driver_0007.o sceIdStorage_driver_0008.o sceIdStorage_driver_0009.o sceIdStorage_driver_0010.o sceIdStorage_driver_0011.o sceIdStorage_driver_0012.o sceIdStorage_driver_0013.o sceIdStorage_driver_0014.o sceIdStorage_driver_0015.o sceIdStorage_driver_0016.o sceIdStorage_driver_0017.o sceIdStorage_driver_0018.o sceIdStorage_driver_0019.o sceIdStorage_driver_0020.o + +SYSTIMER_OBJS = SysTimerForKernel_0000.o SysTimerForKernel_0001.o SysTimerForKernel_0002.o SysTimerForKernel_0003.o SysTimerForKernel_0004.o SysTimerForKernel_0005.o SysTimerForKernel_0006.o SysTimerForKernel_0007.o SysTimerForKernel_0008.o SysTimerForKernel_0009.o + +SYSEVENT_OBJS = sceSysEventForKernel_0000.o sceSysEventForKernel_0001.o sceSysEventForKernel_0002.o sceSysEventForKernel_0003.o sceSysEventForKernel_0004.o sceSysEventForKernel_0005.o + +IMPOSE_OBJS = sceImpose_driver_0000.o sceImpose_driver_0001.o sceImpose_driver_0002.o sceImpose_driver_0003.o sceImpose_driver_0004.o sceImpose_driver_0005.o sceImpose_driver_0006.o sceImpose_driver_0007.o sceImpose_driver_0008.o sceImpose_driver_0009.o sceImpose_driver_0010.o sceImpose_driver_0011.o sceImpose_driver_0012.o sceImpose_driver_0013.o sceImpose_driver_0014.o sceImpose_driver_0015.o sceImpose_driver_0016.o sceImpose_driver_0017.o sceImpose_driver_0018.o sceImpose_driver_0019.o sceImpose_driver_0020.o sceImpose_driver_0021.o sceImpose_driver_0022.o sceImpose_driver_0023.o + +INIT_OBJS = InitForKernel_0000.o InitForKernel_0001.o InitForKernel_0002.o InitForKernel_0003.o InitForKernel_0004.o InitForKernel_0005.o InitForKernel_0006.o InitForKernel_0007.o InitForKernel_0008.o InitForKernel_0009.o InitForKernel_0010.o InitForKernel_0011.o + +AUDIOROUTING_OBJS = sceAudioRouting_driver_0000.o sceAudioRouting_driver_0001.o sceAudioRouting_driver_0002.o sceAudioRouting_driver_0003.o sceAudioRouting_driver_0004.o + +libpspkernelincludedir = @PSPSDK_INCLUDEDIR@ + +libpspkernelinclude_HEADERS = \ + pspiofilemgr_kernel.h \ + pspkernel.h \ + psploadcore.h \ + psploadexec_kernel.h \ + pspstdio_kernel.h \ + pspsysreg.h \ + psputilsforkernel.h \ + pspkdebug.h \ + pspintrman_kernel.h \ + pspmodulemgr_kernel.h \ + pspsystimer.h \ + pspsysmem_kernel.h \ + pspthreadman_kernel.h \ + pspsyscon.h \ + pspsysevent.h \ + pspidstorage.h \ + pspexception.h \ + pspsysclib.h \ + pspimpose_driver.h \ + pspinit.h \ + pspaudiorouting.h + +lib_LIBRARIES = libpspkernel.a + +libpspkernel_a_SOURCES = \ + ExceptionManagerForKernel.S \ + KDebugForKernel.S \ + LoadCoreForKernel.S \ + IoFileMgrForKernel.S \ + StdioForKernel.S \ + sceSyscon_driver.S \ + sceSysreg_driver.S \ + UtilsForKernel.S \ + InterruptManagerForKernel.S \ + ThreadManForKernel.S \ + SysclibForKernel.S \ + LoadExecForKernel.S \ + SysMemForKernel.S \ + SysTimerForKernel.S \ + sceSysEventForKernel.S \ + ModuleMgrForKernel.S \ + sceIdStorage_driver.S \ + sceImpose_driver.S \ + InitForKernel.S \ + sceAudioRouting_driver.S + +libpspkernel_a_LIBADD = $(EXCEPTION_OBJS) $(KDEBUG_OBJS) $(LOADCORE_OBJS) $(IO_OBJS) \ + $(STDIO_OBJS) $(SYSREG_OBJS) $(UTILS_OBJS) $(SYSCON_OBJS) $(INTR_OBJS) \ + $(THREAD_OBJS) $(SYSCLIB_OBJS) $(LOADEXEC_OBJS) $(SYSMEM_OBJS) $(MODULE_OBJS) \ + $(IDSTORAGE_OBJS) $(SYSTIMER_OBJS) $(SYSEVENT_OBJS) $(IMPOSE_OBJS) $(INIT_OBJS) \ + $(AUDIOROUTING_OBJS) + +$(EXCEPTION_OBJS): ExceptionManagerForKernel.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(KDEBUG_OBJS): KDebugForKernel.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(LOADCORE_OBJS): LoadCoreForKernel.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(IO_OBJS): IoFileMgrForKernel.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(STDIO_OBJS): StdioForKernel.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(SYSREG_OBJS): sceSysreg_driver.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(UTILS_OBJS): UtilsForKernel.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(SYSCON_OBJS): sceSyscon_driver.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(INTR_OBJS): InterruptManagerForKernel.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(THREAD_OBJS): ThreadManForKernel.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(SYSCLIB_OBJS): SysclibForKernel.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(LOADEXEC_OBJS): LoadExecForKernel.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(SYSMEM_OBJS): SysMemForKernel.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(MODULE_OBJS): ModuleMgrForKernel.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(IDSTORAGE_OBJS): sceIdStorage_driver.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(SYSTIMER_OBJS): SysTimerForKernel.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(SYSEVENT_OBJS): sceSysEventForKernel.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(IMPOSE_OBJS): sceImpose_driver.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(INIT_OBJS): InitForKernel.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(AUDIOROUTING_OBJS): sceAudioRouting_driver.S + $(COMPILE) -DF_$* $< -c -o $@ diff --git a/src/kernel/ModuleMgrForKernel.S b/src/kernel/ModuleMgrForKernel.S new file mode 100644 index 00000000..b186dd7a --- /dev/null +++ b/src/kernel/ModuleMgrForKernel.S @@ -0,0 +1,73 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_ModuleMgrForKernel_0000 + IMPORT_START "ModuleMgrForKernel",0x00010000 +#endif +#ifdef F_ModuleMgrForKernel_0001 + IMPORT_FUNC "ModuleMgrForKernel",0xABE84F8A,sceKernelLoadModuleBufferWithApitype +#endif +#ifdef F_ModuleMgrForKernel_0002 + IMPORT_FUNC "ModuleMgrForKernel",0xBA889C07,sceKernelLoadModuleBuffer +#endif +#ifdef F_ModuleMgrForKernel_0003 + IMPORT_FUNC "ModuleMgrForKernel",0xB7F46618,sceKernelLoadModuleByID +#endif +#ifdef F_ModuleMgrForKernel_0004 + IMPORT_FUNC "ModuleMgrForKernel",0x437214AE,sceKernelLoadModuleWithApitype +#endif +#ifdef F_ModuleMgrForKernel_0005 + IMPORT_FUNC "ModuleMgrForKernel",0x977DE386,sceKernelLoadModule +#endif +#ifdef F_ModuleMgrForKernel_0006 + IMPORT_FUNC "ModuleMgrForKernel",0x710F61B5,sceKernelLoadModuleMs +#endif +#ifdef F_ModuleMgrForKernel_0007 + IMPORT_FUNC "ModuleMgrForKernel",0x91B87FAE,sceKernelLoadModuleVSHByID +#endif +#ifdef F_ModuleMgrForKernel_0008 + IMPORT_FUNC "ModuleMgrForKernel",0xA4370E7C,sceKernelLoadModuleVSH +#endif +#ifdef F_ModuleMgrForKernel_0009 + IMPORT_FUNC "ModuleMgrForKernel",0x23425E93,sceKernelLoadModuleVSHPlain +#endif +#ifdef F_ModuleMgrForKernel_0010 + IMPORT_FUNC "ModuleMgrForKernel",0xF9275D98,sceKernelLoadModuleBufferUsbWlan +#endif +#ifdef F_ModuleMgrForKernel_0011 + IMPORT_FUNC "ModuleMgrForKernel",0xF0CAC59E,sceKernelLoadModuleBufferVSH +#endif +#ifdef F_ModuleMgrForKernel_0012 + IMPORT_FUNC "ModuleMgrForKernel",0x50F0C1EC,sceKernelStartModule +#endif +#ifdef F_ModuleMgrForKernel_0013 + IMPORT_FUNC "ModuleMgrForKernel",0xD1FF982A,sceKernelStopModule +#endif +#ifdef F_ModuleMgrForKernel_0014 + IMPORT_FUNC "ModuleMgrForKernel",0x2E0911AA,sceKernelUnloadModule +#endif +#ifdef F_ModuleMgrForKernel_0015 + IMPORT_FUNC "ModuleMgrForKernel",0xD675EBB8,sceKernelSelfStopUnloadModule +#endif +#ifdef F_ModuleMgrForKernel_0016 + IMPORT_FUNC "ModuleMgrForKernel",0xCC1D3699,sceKernelStopUnloadSelfModule +#endif +#ifdef F_ModuleMgrForKernel_0017 + IMPORT_FUNC "ModuleMgrForKernel",0x04B7BD22,sceKernelSearchModuleByName +#endif +#ifdef F_ModuleMgrForKernel_0018 + IMPORT_FUNC "ModuleMgrForKernel",0x54D9E02E,sceKernelSearchModuleByAddress +#endif +#ifdef F_ModuleMgrForKernel_0019 + IMPORT_FUNC "ModuleMgrForKernel",0x748CBED9,sceKernelQueryModuleInfo +#endif +#ifdef F_ModuleMgrForKernel_0020 + IMPORT_FUNC "ModuleMgrForKernel",0x5F0CC575,sceKernelRebootBeforeForUser +#endif +#ifdef F_ModuleMgrForKernel_0021 + IMPORT_FUNC "ModuleMgrForKernel",0xB49FFB9E,sceKernelRebootBeforeForKernel +#endif +#ifdef F_ModuleMgrForKernel_0022 + IMPORT_FUNC "ModuleMgrForKernel",0x644395E2,sceKernelGetModuleIdList +#endif diff --git a/src/kernel/StdioForKernel.S b/src/kernel/StdioForKernel.S new file mode 100644 index 00000000..dcf49e1d --- /dev/null +++ b/src/kernel/StdioForKernel.S @@ -0,0 +1,52 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_StdioForKernel_0000 + IMPORT_START "StdioForKernel",0x00010000 +#endif +#ifdef F_StdioForKernel_0001 + IMPORT_FUNC "StdioForKernel",0x2CCF071A,fdprintf +#endif +#ifdef F_StdioForKernel_0002 + IMPORT_FUNC "StdioForKernel",0xCAB439DF,printf +#endif +#ifdef F_StdioForKernel_0003 + IMPORT_FUNC "StdioForKernel",0x4F78930A,fdputc +#endif +#ifdef F_StdioForKernel_0004 + IMPORT_FUNC "StdioForKernel",0xD768752A,putchar +#endif +#ifdef F_StdioForKernel_0005 + IMPORT_FUNC "StdioForKernel",0x36B23B8B,fdputs +#endif +#ifdef F_StdioForKernel_0006 + IMPORT_FUNC "StdioForKernel",0xD97C8CB9,puts +#endif +#ifdef F_StdioForKernel_0007 + IMPORT_FUNC "StdioForKernel",0xD2B2A2A7,fdgetc +#endif +#ifdef F_StdioForKernel_0008 + IMPORT_FUNC "StdioForKernel",0x7E338487,getchar +#endif +#ifdef F_StdioForKernel_0009 + IMPORT_FUNC "StdioForKernel",0x11A5127A,fdgets +#endif +#ifdef F_StdioForKernel_0010 + IMPORT_FUNC "StdioForKernel",0xBFF7E760,gets +#endif +#ifdef F_StdioForKernel_0011 + IMPORT_FUNC "StdioForKernel",0x172D316E,sceKernelStdin +#endif +#ifdef F_StdioForKernel_0012 + IMPORT_FUNC "StdioForKernel",0xA6BAB2E9,sceKernelStdout +#endif +#ifdef F_StdioForKernel_0013 + IMPORT_FUNC "StdioForKernel",0xF78BA90A,sceKernelStderr +#endif +#ifdef F_StdioForKernel_0014 + IMPORT_FUNC "StdioForKernel",0x98220F3E,sceKernelStdoutReopen +#endif +#ifdef F_StdioForKernel_0015 + IMPORT_FUNC "StdioForKernel",0xFB5380C5,sceKernelStderrReopen +#endif diff --git a/src/kernel/SysMemForKernel.S b/src/kernel/SysMemForKernel.S new file mode 100644 index 00000000..bd61768d --- /dev/null +++ b/src/kernel/SysMemForKernel.S @@ -0,0 +1,213 @@ + .set noreorder + +#include "pspimport.s" + +// Build List + +#ifdef F_SysMemForKernel_0000 + IMPORT_START "SysMemForKernel",0x00010011 +#endif +#ifdef F_SysMemForKernel_0001 + IMPORT_FUNC "SysMemForKernel",0x1C1FBFE7,sceKernelCreateHeap +#endif +#ifdef F_SysMemForKernel_0002 + IMPORT_FUNC "SysMemForKernel",0xC9805775,sceKernelDeleteHeap +#endif +#ifdef F_SysMemForKernel_0003 + IMPORT_FUNC "SysMemForKernel",0xEB7A74DB,sceKernelAllocHeapMemoryWithOption +#endif +#ifdef F_SysMemForKernel_0004 + IMPORT_FUNC "SysMemForKernel",0x636C953B,sceKernelAllocHeapMemory +#endif +#ifdef F_SysMemForKernel_0005 + IMPORT_FUNC "SysMemForKernel",0x7B749390,sceKernelFreeHeapMemory +#endif +#ifdef F_SysMemForKernel_0006 + IMPORT_FUNC "SysMemForKernel",0xA823047E,sceKernelHeapTotalFreeSize +#endif +#ifdef F_SysMemForKernel_0007 + IMPORT_FUNC "SysMemForKernel",0xB2163AA1,sceKernelGetHeapTypeCB +#endif +#ifdef F_SysMemForKernel_0008 + IMPORT_FUNC "SysMemForKernel",0xEFF0C6DD,SysMemForKernel_EFF0C6DD +#endif +#ifdef F_SysMemForKernel_0009 + IMPORT_FUNC "SysMemForKernel",0xEFEEBAC7,SysMemForKernel_EFEEBAC7 +#endif +#ifdef F_SysMemForKernel_0010 + IMPORT_FUNC "SysMemForKernel",0x2DB687E9,sceKernelIsValidHeap +#endif +#ifdef F_SysMemForKernel_0011 + IMPORT_FUNC "SysMemForKernel",0x55A40B2C,sceKernelQueryMemoryPartitionInfo +#endif +#ifdef F_SysMemForKernel_0012 + IMPORT_FUNC "SysMemForKernel",0xE6581468,sceKernelPartitionMaxFreeMemSize +#endif +#ifdef F_SysMemForKernel_0013 + IMPORT_FUNC "SysMemForKernel",0x9697CD32,sceKernelPartitionTotalFreeMemSize +#endif +#ifdef F_SysMemForKernel_0014 + IMPORT_FUNC "SysMemForKernel",0xA2A65F0E,sceKernelFillFreeBlock +#endif +#ifdef F_SysMemForKernel_0015 + IMPORT_FUNC "SysMemForKernel",0x237DBD4F,sceKernelAllocPartitionMemory +#endif +#ifdef F_SysMemForKernel_0016 + IMPORT_FUNC "SysMemForKernel",0xEE867074,sceKernelSizeLockMemoryBlock +#endif +#ifdef F_SysMemForKernel_0017 + IMPORT_FUNC "SysMemForKernel",0xCE5544F4,sceKernelResizeMemoryBlock +#endif +#ifdef F_SysMemForKernel_0018 + IMPORT_FUNC "SysMemForKernel",0x5EBE73DE,sceKernelJointMemoryBlock +#endif +#ifdef F_SysMemForKernel_0019 + IMPORT_FUNC "SysMemForKernel",0x915EF4AC,SysMemForKernel_915EF4AC +#endif +#ifdef F_SysMemForKernel_0020 + IMPORT_FUNC "SysMemForKernel",0xB6D61D02,sceKernelFreePartitionMemory +#endif +#ifdef F_SysMemForKernel_0021 + IMPORT_FUNC "SysMemForKernel",0x2A3E5280,sceKernelQueryMemoryInfo +#endif +#ifdef F_SysMemForKernel_0022 + IMPORT_FUNC "SysMemForKernel",0xEB4C0E1B,sceKernelQueryBlockSize +#endif +#ifdef F_SysMemForKernel_0023 + IMPORT_FUNC "SysMemForKernel",0x82CCA14F,sceKernelQueryMemoryBlockInfo +#endif +#ifdef F_SysMemForKernel_0024 + IMPORT_FUNC "SysMemForKernel",0x9D9A5BA1,sceKernelGetBlockHeadAddr +#endif +#ifdef F_SysMemForKernel_0025 + IMPORT_FUNC "SysMemForKernel",0x2F3B7611,SysMemForKernel_2F3B7611 +#endif +#ifdef F_SysMemForKernel_0026 + IMPORT_FUNC "SysMemForKernel",0x7B3E7441,SysMemForKernel_7B3E7441 +#endif +#ifdef F_SysMemForKernel_0027 + IMPORT_FUNC "SysMemForKernel",0xB2C7AA36,sceKernelSetDdrMemoryProtection +#endif +#ifdef F_SysMemForKernel_0028 + IMPORT_FUNC "SysMemForKernel",0x6C1DCD41,sceKernelCallUIDFunction +#endif +#ifdef F_SysMemForKernel_0029 + IMPORT_FUNC "SysMemForKernel",0x5367923C,sceKernelCallUIDObjFunction +#endif +#ifdef F_SysMemForKernel_0030 + IMPORT_FUNC "SysMemForKernel",0xCE05CCB7,SysMemForKernel_CE05CCB7 +#endif +#ifdef F_SysMemForKernel_0031 + IMPORT_FUNC "SysMemForKernel",0x6CD838EC,sceKernelLookupUIDFunction +#endif +#ifdef F_SysMemForKernel_0032 + IMPORT_FUNC "SysMemForKernel",0xAD09C397,sceKernelCreateUIDtypeInherit +#endif +#ifdef F_SysMemForKernel_0033 + IMPORT_FUNC "SysMemForKernel",0xFEFC8666,sceKernelCreateUIDtype +#endif +#ifdef F_SysMemForKernel_0034 + IMPORT_FUNC "SysMemForKernel",0xD1BAB054,sceKernelDeleteUIDtype +#endif +#ifdef F_SysMemForKernel_0035 + IMPORT_FUNC "SysMemForKernel",0x1C221A08,sceKernelGetUIDname +#endif +#ifdef F_SysMemForKernel_0036 + IMPORT_FUNC "SysMemForKernel",0x2E3402CC,sceKernelRenameUID +#endif +#ifdef F_SysMemForKernel_0037 + IMPORT_FUNC "SysMemForKernel",0x39357F07,sceKernelGetUIDtype +#endif +#ifdef F_SysMemForKernel_0038 + IMPORT_FUNC "SysMemForKernel",0x89A74008,sceKernelCreateUID +#endif +#ifdef F_SysMemForKernel_0039 + IMPORT_FUNC "SysMemForKernel",0x8F20C4C0,sceKernelDeleteUID +#endif +#ifdef F_SysMemForKernel_0040 + IMPORT_FUNC "SysMemForKernel",0x55BFD686,sceKernelSearchUIDbyName +#endif +#ifdef F_SysMemForKernel_0041 + IMPORT_FUNC "SysMemForKernel",0xCF4DE78C,sceKernelGetUIDcontrolBlock +#endif +#ifdef F_SysMemForKernel_0042 + IMPORT_FUNC "SysMemForKernel",0x41FFC7F9,sceKernelGetUIDcontrolBlockWithType +#endif +#ifdef F_SysMemForKernel_0043 + IMPORT_FUNC "SysMemForKernel",0x82D3CEE3,SysMemForKernel_82D3CEE3 +#endif +#ifdef F_SysMemForKernel_0044 + IMPORT_FUNC "SysMemForKernel",0xFC207849,SysMemForKernel_FC207849 +#endif +#ifdef F_SysMemForKernel_0045 + IMPORT_FUNC "SysMemForKernel",0x536AD5E1,SysMemForKernel_536AD5E1 +#endif +#ifdef F_SysMemForKernel_0046 + IMPORT_FUNC "SysMemForKernel",0xDFAEBD5B,sceKernelIsHold +#endif +#ifdef F_SysMemForKernel_0047 + IMPORT_FUNC "SysMemForKernel",0x7BE95FA0,sceKernelHoldUID +#endif +#ifdef F_SysMemForKernel_0048 + IMPORT_FUNC "SysMemForKernel",0xFE8DEBE0,sceKernelReleaseUID +#endif +#ifdef F_SysMemForKernel_0049 + IMPORT_FUNC "SysMemForKernel",0xBD5941B4,sceKernelSysmemIsValidAccess +#endif +#ifdef F_SysMemForKernel_0050 + IMPORT_FUNC "SysMemForKernel",0x80F25772,sceKernelIsValidUserAccess +#endif +#ifdef F_SysMemForKernel_0051 + IMPORT_FUNC "SysMemForKernel",0x3905D956,sceKernelSysMemCheckCtlBlk +#endif +#ifdef F_SysMemForKernel_0052 + IMPORT_FUNC "SysMemForKernel",0x26F96157,sceKernelSysMemDump +#endif +#ifdef F_SysMemForKernel_0053 + IMPORT_FUNC "SysMemForKernel",0x6D6200DD,sceKernelSysMemDumpBlock +#endif +#ifdef F_SysMemForKernel_0054 + IMPORT_FUNC "SysMemForKernel",0x621037F5,sceKernelSysMemDumpTail +#endif +#ifdef F_SysMemForKernel_0055 + IMPORT_FUNC "SysMemForKernel",0xA089ECA4,sceKernelMemset +#endif +#ifdef F_SysMemForKernel_0056 + IMPORT_FUNC "SysMemForKernel",0x2F808748,SysMemForKernel_2F808748 +#endif +#ifdef F_SysMemForKernel_0057 + IMPORT_FUNC "SysMemForKernel",0x1C4B1713,SysMemForKernel_1C4B1713 +#endif +#ifdef F_SysMemForKernel_0058 + IMPORT_FUNC "SysMemForKernel",0xE400FDB0,sceKernelSysMemInit +#endif +#ifdef F_SysMemForKernel_0059 + IMPORT_FUNC "SysMemForKernel",0x1890BE9C,sceKernelSysMemMemSize +#endif +#ifdef F_SysMemForKernel_0060 + IMPORT_FUNC "SysMemForKernel",0x03072750,sceKernelSysMemMaxFreeMemSize +#endif +#ifdef F_SysMemForKernel_0061 + IMPORT_FUNC "SysMemForKernel",0x811BED79,sceKernelSysMemTotalFreeMemSize +#endif +#ifdef F_SysMemForKernel_0062 + IMPORT_FUNC "SysMemForKernel",0xF6C10E27,sceKernelGetSysMemoryInfo +#endif +#ifdef F_SysMemForKernel_0063 + IMPORT_FUNC "SysMemForKernel",0xCDA3A2F7,SysMemForKernel_CDA3A2F7 +#endif +#ifdef F_SysMemForKernel_0064 + IMPORT_FUNC "SysMemForKernel",0x960B888C,SysMemForKernel_960B888C +#endif +#ifdef F_SysMemForKernel_0065 + IMPORT_FUNC "SysMemForKernel",0x3FC9AE6A,sceKernelDevkitVersion +#endif +#ifdef F_SysMemForKernel_0066 + IMPORT_FUNC "SysMemForKernel",0x452E3696,SysMemForKernel_452E3696 +#endif +#ifdef F_SysMemForKernel_0067 + IMPORT_FUNC "SysMemForKernel",0x95F5E8DA,SysMemForKernel_95F5E8DA +#endif +#ifdef F_SysMemForKernel_0068 + IMPORT_FUNC "SysMemForKernel",0x6373995D,sceKernelGetModel +#endif diff --git a/src/kernel/SysTimerForKernel.S b/src/kernel/SysTimerForKernel.S new file mode 100644 index 00000000..0c3628d1 --- /dev/null +++ b/src/kernel/SysTimerForKernel.S @@ -0,0 +1,34 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_SysTimerForKernel_0000 + IMPORT_START "SysTimerForKernel",0x00010000 +#endif +#ifdef F_SysTimerForKernel_0001 + IMPORT_FUNC "SysTimerForKernel",0xC99073E3,sceSTimerAlloc +#endif +#ifdef F_SysTimerForKernel_0002 + IMPORT_FUNC "SysTimerForKernel",0xC105CF38,sceSTimerFree +#endif +#ifdef F_SysTimerForKernel_0003 + IMPORT_FUNC "SysTimerForKernel",0xB53534B4,SysTimerForKernel_B53534B4 +#endif +#ifdef F_SysTimerForKernel_0004 + IMPORT_FUNC "SysTimerForKernel",0x975D8E84,sceSTimerSetHandler +#endif +#ifdef F_SysTimerForKernel_0005 + IMPORT_FUNC "SysTimerForKernel",0xA95143E2,sceSTimerStartCount +#endif +#ifdef F_SysTimerForKernel_0006 + IMPORT_FUNC "SysTimerForKernel",0x4A01F9D3,sceSTimerStopCount +#endif +#ifdef F_SysTimerForKernel_0007 + IMPORT_FUNC "SysTimerForKernel",0x54BB5DB4,sceSTimerResetCount +#endif +#ifdef F_SysTimerForKernel_0008 + IMPORT_FUNC "SysTimerForKernel",0x228EDAE4,sceSTimerGetCount +#endif +#ifdef F_SysTimerForKernel_0009 + IMPORT_FUNC "SysTimerForKernel",0x53231A15,SysTimerForKernel_53231A15 +#endif diff --git a/src/kernel/SysclibForKernel.S b/src/kernel/SysclibForKernel.S new file mode 100644 index 00000000..e7075812 --- /dev/null +++ b/src/kernel/SysclibForKernel.S @@ -0,0 +1,133 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_SysclibForKernel_0000 + IMPORT_START "SysclibForKernel",0x00010000 +#endif +#ifdef F_SysclibForKernel_0001 + IMPORT_FUNC "SysclibForKernel",0x476FD94A,strcat +#endif +#ifdef F_SysclibForKernel_0002 + IMPORT_FUNC "SysclibForKernel",0x89B79CB1,strcspn +#endif +#ifdef F_SysclibForKernel_0003 + IMPORT_FUNC "SysclibForKernel",0xD1CD40E5,index +#endif +#ifdef F_SysclibForKernel_0004 + IMPORT_FUNC "SysclibForKernel",0x243665ED,rindex +#endif +#ifdef F_SysclibForKernel_0005 + IMPORT_FUNC "SysclibForKernel",0x90C5573D,strnlen +#endif +#ifdef F_SysclibForKernel_0006 + IMPORT_FUNC "SysclibForKernel",0x0DFB7B6C,strpbrk +#endif +#ifdef F_SysclibForKernel_0007 + IMPORT_FUNC "SysclibForKernel",0x62AE052F,strspn +#endif +#ifdef F_SysclibForKernel_0008 + IMPORT_FUNC "SysclibForKernel",0x0D188658,strstr +#endif +#ifdef F_SysclibForKernel_0009 + IMPORT_FUNC "SysclibForKernel",0x87F8D2DA,strtok +#endif +#ifdef F_SysclibForKernel_0010 + IMPORT_FUNC "SysclibForKernel",0x1AB53A58,strtok_r +#endif +#ifdef F_SysclibForKernel_0011 + IMPORT_FUNC "SysclibForKernel",0x47DD934D,strtol +#endif +#ifdef F_SysclibForKernel_0012 + IMPORT_FUNC "SysclibForKernel",0x1D83F344,atob +#endif +#ifdef F_SysclibForKernel_0013 + IMPORT_FUNC "SysclibForKernel",0x6A7900E1,strtoul +#endif +#ifdef F_SysclibForKernel_0014 + IMPORT_FUNC "SysclibForKernel",0x8AF6B8F8,SysclibForKernel_8AF6B8F8 +#endif +#ifdef F_SysclibForKernel_0015 + IMPORT_FUNC "SysclibForKernel",0xDF17F4A2,SysclibForKernel_DF17F4A2 +#endif +#ifdef F_SysclibForKernel_0016 + IMPORT_FUNC "SysclibForKernel",0x7DEE14DE,SysclibForKernel_7DEE14DE +#endif +#ifdef F_SysclibForKernel_0017 + IMPORT_FUNC "SysclibForKernel",0x5E8E5F42,SysclibForKernel_5E8E5F42 +#endif +#ifdef F_SysclibForKernel_0018 + IMPORT_FUNC "SysclibForKernel",0xC0AB8932,strcmp +#endif +#ifdef F_SysclibForKernel_0019 + IMPORT_FUNC "SysclibForKernel",0xEC6F1CF2,strcpy +#endif +#ifdef F_SysclibForKernel_0020 + IMPORT_FUNC "SysclibForKernel",0xB1DC2AE8,strchr +#endif +#ifdef F_SysclibForKernel_0021 + IMPORT_FUNC "SysclibForKernel",0x4C0E0274,strrchr +#endif +#ifdef F_SysclibForKernel_0022 + IMPORT_FUNC "SysclibForKernel",0x7AB35214,strncmp +#endif +#ifdef F_SysclibForKernel_0023 + IMPORT_FUNC "SysclibForKernel",0xB49A7697,strncpy +#endif +#ifdef F_SysclibForKernel_0024 + IMPORT_FUNC "SysclibForKernel",0x52DF196C,strlen +#endif +#ifdef F_SysclibForKernel_0025 + IMPORT_FUNC "SysclibForKernel",0xD3D1A3B9,strncat +#endif +#ifdef F_SysclibForKernel_0026 + IMPORT_FUNC "SysclibForKernel",0x68A78817,memchr +#endif +#ifdef F_SysclibForKernel_0027 + IMPORT_FUNC "SysclibForKernel",0xAB7592FF,memcpy +#endif +#ifdef F_SysclibForKernel_0028 + IMPORT_FUNC "SysclibForKernel",0x10F3BB61,memset +#endif +#ifdef F_SysclibForKernel_0029 + IMPORT_FUNC "SysclibForKernel",0x81D0D1F7,memcmp +#endif +#ifdef F_SysclibForKernel_0030 + IMPORT_FUNC "SysclibForKernel",0xA48D2592,memmove +#endif +#ifdef F_SysclibForKernel_0031 + IMPORT_FUNC "SysclibForKernel",0x097049BD,bcopy +#endif +#ifdef F_SysclibForKernel_0032 + IMPORT_FUNC "SysclibForKernel",0x7F8A6F23,bcmp +#endif +#ifdef F_SysclibForKernel_0033 + IMPORT_FUNC "SysclibForKernel",0x86FEFCE9,bzero +#endif +#ifdef F_SysclibForKernel_0034 + IMPORT_FUNC "SysclibForKernel",0xCE2F7487,toupper +#endif +#ifdef F_SysclibForKernel_0035 + IMPORT_FUNC "SysclibForKernel",0x3EC5BBF6,tolower +#endif +#ifdef F_SysclibForKernel_0036 + IMPORT_FUNC "SysclibForKernel",0x32C767F2,look_ctype_table +#endif +#ifdef F_SysclibForKernel_0037 + IMPORT_FUNC "SysclibForKernel",0xD887CACD,get_ctype_table +#endif +#ifdef F_SysclibForKernel_0038 + IMPORT_FUNC "SysclibForKernel",0x87C78FB6,prnt +#endif +#ifdef F_SysclibForKernel_0039 + IMPORT_FUNC "SysclibForKernel",0x7661E728,sprintf +#endif +#ifdef F_SysclibForKernel_0040 + IMPORT_FUNC "SysclibForKernel",0x909C228B,setjmp +#endif +#ifdef F_SysclibForKernel_0041 + IMPORT_FUNC "SysclibForKernel",0x18FE80DB,longjmp +#endif +#ifdef F_SysclibForKernel_0042 + IMPORT_FUNC "SysclibForKernel",0x1493EBD9,wmemset +#endif diff --git a/src/kernel/ThreadManForKernel.S b/src/kernel/ThreadManForKernel.S new file mode 100644 index 00000000..b2225eba --- /dev/null +++ b/src/kernel/ThreadManForKernel.S @@ -0,0 +1,412 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_ThreadManForKernel_0000 + IMPORT_START "ThreadManForKernel",0x00010000 +#endif +#ifdef F_ThreadManForKernel_0001 + IMPORT_FUNC "ThreadManForKernel",0x0C106E53,sceKernelRegisterThreadEventHandler +#endif +#ifdef F_ThreadManForKernel_0002 + IMPORT_FUNC "ThreadManForKernel",0x72F3C145,sceKernelReleaseThreadEventHandler +#endif +#ifdef F_ThreadManForKernel_0003 + IMPORT_FUNC "ThreadManForKernel",0x369EEB6B,sceKernelReferThreadEventHandlerStatus +#endif +#ifdef F_ThreadManForKernel_0004 + IMPORT_FUNC "ThreadManForKernel",0xE81CAF8F,sceKernelCreateCallback +#endif +#ifdef F_ThreadManForKernel_0005 + IMPORT_FUNC "ThreadManForKernel",0xEDBA5844,sceKernelDeleteCallback +#endif +#ifdef F_ThreadManForKernel_0006 + IMPORT_FUNC "ThreadManForKernel",0xC11BA8C4,sceKernelNotifyCallback +#endif +#ifdef F_ThreadManForKernel_0007 + IMPORT_FUNC "ThreadManForKernel",0xBA4051D6,sceKernelCancelCallback +#endif +#ifdef F_ThreadManForKernel_0008 + IMPORT_FUNC "ThreadManForKernel",0x2A3D44FF,sceKernelGetCallbackCount +#endif +#ifdef F_ThreadManForKernel_0009 + IMPORT_FUNC "ThreadManForKernel",0x349D6D6C,sceKernelCheckCallback +#endif +#ifdef F_ThreadManForKernel_0010 + IMPORT_FUNC "ThreadManForKernel",0x730ED8BC,sceKernelReferCallbackStatus +#endif +#ifdef F_ThreadManForKernel_0011 + IMPORT_FUNC "ThreadManForKernel",0x9ACE131E,sceKernelSleepThread +#endif +#ifdef F_ThreadManForKernel_0012 + IMPORT_FUNC "ThreadManForKernel",0x82826F70,sceKernelSleepThreadCB +#endif +#ifdef F_ThreadManForKernel_0013 + IMPORT_FUNC "ThreadManForKernel",0xD59EAD2F,sceKernelWakeupThread +#endif +#ifdef F_ThreadManForKernel_0014 + IMPORT_FUNC "ThreadManForKernel",0xFCCFAD26,sceKernelCancelWakeupThread +#endif +#ifdef F_ThreadManForKernel_0015 + IMPORT_FUNC "ThreadManForKernel",0x9944F31F,sceKernelSuspendThread +#endif +#ifdef F_ThreadManForKernel_0016 + IMPORT_FUNC "ThreadManForKernel",0x75156E8F,sceKernelResumeThread +#endif +#ifdef F_ThreadManForKernel_0017 + IMPORT_FUNC "ThreadManForKernel",0x8FD9F70C,sceKernelSuspendAllUserThreads +#endif +#ifdef F_ThreadManForKernel_0018 + IMPORT_FUNC "ThreadManForKernel",0x278C0DF5,sceKernelWaitThreadEnd +#endif +#ifdef F_ThreadManForKernel_0019 + IMPORT_FUNC "ThreadManForKernel",0x840E8133,sceKernelWaitThreadEndCB +#endif +#ifdef F_ThreadManForKernel_0020 + IMPORT_FUNC "ThreadManForKernel",0xCEADEB47,sceKernelDelayThread +#endif +#ifdef F_ThreadManForKernel_0021 + IMPORT_FUNC "ThreadManForKernel",0x68DA9E36,sceKernelDelayThreadCB +#endif +#ifdef F_ThreadManForKernel_0022 + IMPORT_FUNC "ThreadManForKernel",0xBD123D9E,sceKernelDelaySysClockThread +#endif +#ifdef F_ThreadManForKernel_0023 + IMPORT_FUNC "ThreadManForKernel",0x1181E963,sceKernelDelaySysClockThreadCB +#endif +#ifdef F_ThreadManForKernel_0024 + IMPORT_FUNC "ThreadManForKernel",0xD6DA4BA1,sceKernelCreateSema +#endif +#ifdef F_ThreadManForKernel_0025 + IMPORT_FUNC "ThreadManForKernel",0x28B6489C,sceKernelDeleteSema +#endif +#ifdef F_ThreadManForKernel_0026 + IMPORT_FUNC "ThreadManForKernel",0x3F53E640,sceKernelSignalSema +#endif +#ifdef F_ThreadManForKernel_0027 + IMPORT_FUNC "ThreadManForKernel",0x4E3A1105,sceKernelWaitSema +#endif +#ifdef F_ThreadManForKernel_0028 + IMPORT_FUNC "ThreadManForKernel",0x6D212BAC,sceKernelWaitSemaCB +#endif +#ifdef F_ThreadManForKernel_0029 + IMPORT_FUNC "ThreadManForKernel",0x58B1F937,sceKernelPollSema +#endif +#ifdef F_ThreadManForKernel_0030 + IMPORT_FUNC "ThreadManForKernel",0x8FFDF9A2,sceKernelCancelSema +#endif +#ifdef F_ThreadManForKernel_0031 + IMPORT_FUNC "ThreadManForKernel",0xBC6FEBC5,sceKernelReferSemaStatus +#endif +#ifdef F_ThreadManForKernel_0032 + IMPORT_FUNC "ThreadManForKernel",0x55C20A00,sceKernelCreateEventFlag +#endif +#ifdef F_ThreadManForKernel_0033 + IMPORT_FUNC "ThreadManForKernel",0xEF9E4C70,sceKernelDeleteEventFlag +#endif +#ifdef F_ThreadManForKernel_0034 + IMPORT_FUNC "ThreadManForKernel",0x1FB15A32,sceKernelSetEventFlag +#endif +#ifdef F_ThreadManForKernel_0035 + IMPORT_FUNC "ThreadManForKernel",0x812346E4,sceKernelClearEventFlag +#endif +#ifdef F_ThreadManForKernel_0036 + IMPORT_FUNC "ThreadManForKernel",0x402FCF22,sceKernelWaitEventFlag +#endif +#ifdef F_ThreadManForKernel_0037 + IMPORT_FUNC "ThreadManForKernel",0x328C546A,sceKernelWaitEventFlagCB +#endif +#ifdef F_ThreadManForKernel_0038 + IMPORT_FUNC "ThreadManForKernel",0x30FD48F0,sceKernelPollEventFlag +#endif +#ifdef F_ThreadManForKernel_0039 + IMPORT_FUNC "ThreadManForKernel",0xCD203292,sceKernelCancelEventFlag +#endif +#ifdef F_ThreadManForKernel_0040 + IMPORT_FUNC "ThreadManForKernel",0xA66B0120,sceKernelReferEventFlagStatus +#endif +#ifdef F_ThreadManForKernel_0041 + IMPORT_FUNC "ThreadManForKernel",0x8125221D,sceKernelCreateMbx +#endif +#ifdef F_ThreadManForKernel_0042 + IMPORT_FUNC "ThreadManForKernel",0x86255ADA,sceKernelDeleteMbx +#endif +#ifdef F_ThreadManForKernel_0043 + IMPORT_FUNC "ThreadManForKernel",0xE9B3061E,sceKernelSendMbx +#endif +#ifdef F_ThreadManForKernel_0044 + IMPORT_FUNC "ThreadManForKernel",0x18260574,sceKernelReceiveMbx +#endif +#ifdef F_ThreadManForKernel_0045 + IMPORT_FUNC "ThreadManForKernel",0xF3986382,sceKernelReceiveMbxCB +#endif +#ifdef F_ThreadManForKernel_0046 + IMPORT_FUNC "ThreadManForKernel",0x0D81716A,sceKernelPollMbx +#endif +#ifdef F_ThreadManForKernel_0047 + IMPORT_FUNC "ThreadManForKernel",0x87D4DD36,sceKernelCancelReceiveMbx +#endif +#ifdef F_ThreadManForKernel_0048 + IMPORT_FUNC "ThreadManForKernel",0xA8E8C846,sceKernelReferMbxStatus +#endif +#ifdef F_ThreadManForKernel_0049 + IMPORT_FUNC "ThreadManForKernel",0x7C0DC2A0,sceKernelCreateMsgPipe +#endif +#ifdef F_ThreadManForKernel_0050 + IMPORT_FUNC "ThreadManForKernel",0xF0B7DA1C,sceKernelDeleteMsgPipe +#endif +#ifdef F_ThreadManForKernel_0051 + IMPORT_FUNC "ThreadManForKernel",0x876DBFAD,sceKernelSendMsgPipe +#endif +#ifdef F_ThreadManForKernel_0052 + IMPORT_FUNC "ThreadManForKernel",0x7C41F2C2,sceKernelSendMsgPipeCB +#endif +#ifdef F_ThreadManForKernel_0053 + IMPORT_FUNC "ThreadManForKernel",0x884C9F90,sceKernelTrySendMsgPipe +#endif +#ifdef F_ThreadManForKernel_0054 + IMPORT_FUNC "ThreadManForKernel",0x74829B76,sceKernelReceiveMsgPipe +#endif +#ifdef F_ThreadManForKernel_0055 + IMPORT_FUNC "ThreadManForKernel",0xFBFA697D,sceKernelReceiveMsgPipeCB +#endif +#ifdef F_ThreadManForKernel_0056 + IMPORT_FUNC "ThreadManForKernel",0xDF52098F,sceKernelTryReceiveMsgPipe +#endif +#ifdef F_ThreadManForKernel_0057 + IMPORT_FUNC "ThreadManForKernel",0x349B864D,sceKernelCancelMsgPipe +#endif +#ifdef F_ThreadManForKernel_0058 + IMPORT_FUNC "ThreadManForKernel",0x33BE4024,sceKernelReferMsgPipeStatus +#endif +#ifdef F_ThreadManForKernel_0059 + IMPORT_FUNC "ThreadManForKernel",0x56C039B5,sceKernelCreateVpl +#endif +#ifdef F_ThreadManForKernel_0060 + IMPORT_FUNC "ThreadManForKernel",0x89B3D48C,sceKernelDeleteVpl +#endif +#ifdef F_ThreadManForKernel_0061 + IMPORT_FUNC "ThreadManForKernel",0xBED27435,sceKernelAllocateVpl +#endif +#ifdef F_ThreadManForKernel_0062 + IMPORT_FUNC "ThreadManForKernel",0xEC0A693F,sceKernelAllocateVplCB +#endif +#ifdef F_ThreadManForKernel_0063 + IMPORT_FUNC "ThreadManForKernel",0xAF36D708,sceKernelTryAllocateVpl +#endif +#ifdef F_ThreadManForKernel_0064 + IMPORT_FUNC "ThreadManForKernel",0xB736E9FF,sceKernelFreeVpl +#endif +#ifdef F_ThreadManForKernel_0065 + IMPORT_FUNC "ThreadManForKernel",0x1D371B8A,sceKernelCancelVpl +#endif +#ifdef F_ThreadManForKernel_0066 + IMPORT_FUNC "ThreadManForKernel",0x39810265,sceKernelReferVplStatus +#endif +#ifdef F_ThreadManForKernel_0067 + IMPORT_FUNC "ThreadManForKernel",0xC07BB470,sceKernelCreateFpl +#endif +#ifdef F_ThreadManForKernel_0068 + IMPORT_FUNC "ThreadManForKernel",0xED1410E0,sceKernelDeleteFpl +#endif +#ifdef F_ThreadManForKernel_0069 + IMPORT_FUNC "ThreadManForKernel",0xD979E9BF,sceKernelAllocateFpl +#endif +#ifdef F_ThreadManForKernel_0070 + IMPORT_FUNC "ThreadManForKernel",0xE7282CB6,sceKernelAllocateFplCB +#endif +#ifdef F_ThreadManForKernel_0071 + IMPORT_FUNC "ThreadManForKernel",0x623AE665,sceKernelTryAllocateFpl +#endif +#ifdef F_ThreadManForKernel_0072 + IMPORT_FUNC "ThreadManForKernel",0xF6414A71,sceKernelFreeFpl +#endif +#ifdef F_ThreadManForKernel_0073 + IMPORT_FUNC "ThreadManForKernel",0xA8AA591F,sceKernelCancelFpl +#endif +#ifdef F_ThreadManForKernel_0074 + IMPORT_FUNC "ThreadManForKernel",0xD8199E4C,sceKernelReferFplStatus +#endif +#ifdef F_ThreadManForKernel_0075 + IMPORT_FUNC "ThreadManForKernel",0x110DEC9A,sceKernelUSec2SysClock +#endif +#ifdef F_ThreadManForKernel_0076 + IMPORT_FUNC "ThreadManForKernel",0xC8CD158C,sceKernelUSec2SysClockWide +#endif +#ifdef F_ThreadManForKernel_0077 + IMPORT_FUNC "ThreadManForKernel",0xBA6B92E2,sceKernelSysClock2USec +#endif +#ifdef F_ThreadManForKernel_0078 + IMPORT_FUNC "ThreadManForKernel",0xE1619D7C,sceKernelSysClock2USecWide +#endif +#ifdef F_ThreadManForKernel_0079 + IMPORT_FUNC "ThreadManForKernel",0xDB738F35,sceKernelGetSystemTime +#endif +#ifdef F_ThreadManForKernel_0080 + IMPORT_FUNC "ThreadManForKernel",0x82BC5777,sceKernelGetSystemTimeWide +#endif +#ifdef F_ThreadManForKernel_0081 + IMPORT_FUNC "ThreadManForKernel",0x369ED59D,sceKernelGetSystemTimeLow +#endif +#ifdef F_ThreadManForKernel_0082 + IMPORT_FUNC "ThreadManForKernel",0x6652B8CA,sceKernelSetAlarm +#endif +#ifdef F_ThreadManForKernel_0083 + IMPORT_FUNC "ThreadManForKernel",0xB2C25152,sceKernelSetSysClockAlarm +#endif +#ifdef F_ThreadManForKernel_0084 + IMPORT_FUNC "ThreadManForKernel",0x7E65B999,sceKernelCancelAlarm +#endif +#ifdef F_ThreadManForKernel_0085 + IMPORT_FUNC "ThreadManForKernel",0xDAA3F564,sceKernelReferAlarmStatus +#endif +#ifdef F_ThreadManForKernel_0086 + IMPORT_FUNC "ThreadManForKernel",0x20FFF560,sceKernelCreateVTimer +#endif +#ifdef F_ThreadManForKernel_0087 + IMPORT_FUNC "ThreadManForKernel",0x328F9E52,sceKernelDeleteVTimer +#endif +#ifdef F_ThreadManForKernel_0088 + IMPORT_FUNC "ThreadManForKernel",0xB3A59970,sceKernelGetVTimerBase +#endif +#ifdef F_ThreadManForKernel_0089 + IMPORT_FUNC "ThreadManForKernel",0xB7C18B77,sceKernelGetVTimerBaseWide +#endif +#ifdef F_ThreadManForKernel_0090 + IMPORT_FUNC "ThreadManForKernel",0x034A921F,sceKernelGetVTimerTime +#endif +#ifdef F_ThreadManForKernel_0091 + IMPORT_FUNC "ThreadManForKernel",0xC0B3FFD2,sceKernelGetVTimerTimeWide +#endif +#ifdef F_ThreadManForKernel_0092 + IMPORT_FUNC "ThreadManForKernel",0x542AD630,sceKernelSetVTimerTime +#endif +#ifdef F_ThreadManForKernel_0093 + IMPORT_FUNC "ThreadManForKernel",0xFB6425C3,sceKernelSetVTimerTimeWide +#endif +#ifdef F_ThreadManForKernel_0094 + IMPORT_FUNC "ThreadManForKernel",0xC68D9437,sceKernelStartVTimer +#endif +#ifdef F_ThreadManForKernel_0095 + IMPORT_FUNC "ThreadManForKernel",0xD0AEEE87,sceKernelStopVTimer +#endif +#ifdef F_ThreadManForKernel_0096 + IMPORT_FUNC "ThreadManForKernel",0xD8B299AE,sceKernelSetVTimerHandler +#endif +#ifdef F_ThreadManForKernel_0097 + IMPORT_FUNC "ThreadManForKernel",0x53B00E9A,sceKernelSetVTimerHandlerWide +#endif +#ifdef F_ThreadManForKernel_0098 + IMPORT_FUNC "ThreadManForKernel",0xD2D615EF,sceKernelCancelVTimerHandler +#endif +#ifdef F_ThreadManForKernel_0099 + IMPORT_FUNC "ThreadManForKernel",0x5F32BEAA,sceKernelReferVTimerStatus +#endif +#ifdef F_ThreadManForKernel_0100 + IMPORT_FUNC "ThreadManForKernel",0x04E72261,sceKernelAllocateKTLS +#endif +#ifdef F_ThreadManForKernel_0101 + IMPORT_FUNC "ThreadManForKernel",0xD198B811,sceKernelFreeKTLS +#endif +#ifdef F_ThreadManForKernel_0102 + IMPORT_FUNC "ThreadManForKernel",0x3AD875C3,sceKernelGetThreadKTLS +#endif +#ifdef F_ThreadManForKernel_0103 + IMPORT_FUNC "ThreadManForKernel",0xA249EAAE,sceKernelGetKTLS +#endif +#ifdef F_ThreadManForKernel_0104 + IMPORT_FUNC "ThreadManForKernel",0xB50F4E46,ThreadManForKernel_B50F4E46 +#endif +#ifdef F_ThreadManForKernel_0105 + IMPORT_FUNC "ThreadManForKernel",0x446D8DE6,sceKernelCreateThread +#endif +#ifdef F_ThreadManForKernel_0106 + IMPORT_FUNC "ThreadManForKernel",0x9FA03CD3,sceKernelDeleteThread +#endif +#ifdef F_ThreadManForKernel_0107 + IMPORT_FUNC "ThreadManForKernel",0xF475845D,sceKernelStartThread +#endif +#ifdef F_ThreadManForKernel_0108 + IMPORT_FUNC "ThreadManForKernel",0xAA73C935,sceKernelExitThread +#endif +#ifdef F_ThreadManForKernel_0109 + IMPORT_FUNC "ThreadManForKernel",0x809CE29B,sceKernelExitDeleteThread +#endif +#ifdef F_ThreadManForKernel_0110 + IMPORT_FUNC "ThreadManForKernel",0x616403BA,sceKernelTerminateThread +#endif +#ifdef F_ThreadManForKernel_0111 + IMPORT_FUNC "ThreadManForKernel",0x383F7BCC,sceKernelTerminateDeleteThread +#endif +#ifdef F_ThreadManForKernel_0112 + IMPORT_FUNC "ThreadManForKernel",0x3AD58B8C,sceKernelSuspendDispatchThread +#endif +#ifdef F_ThreadManForKernel_0113 + IMPORT_FUNC "ThreadManForKernel",0x27E22EC2,sceKernelResumeDispatchThread +#endif +#ifdef F_ThreadManForKernel_0114 + IMPORT_FUNC "ThreadManForKernel",0xEA748E31,sceKernelChangeCurrentThreadAttr +#endif +#ifdef F_ThreadManForKernel_0115 + IMPORT_FUNC "ThreadManForKernel",0x71BC9871,sceKernelChangeThreadPriority +#endif +#ifdef F_ThreadManForKernel_0116 + IMPORT_FUNC "ThreadManForKernel",0x912354A7,sceKernelRotateThreadReadyQueue +#endif +#ifdef F_ThreadManForKernel_0117 + IMPORT_FUNC "ThreadManForKernel",0x2C34E053,sceKernelReleaseWaitThread +#endif +#ifdef F_ThreadManForKernel_0118 + IMPORT_FUNC "ThreadManForKernel",0x293B45B8,sceKernelGetThreadId +#endif +#ifdef F_ThreadManForKernel_0119 + IMPORT_FUNC "ThreadManForKernel",0x94AA61EE,sceKernelGetThreadCurrentPriority +#endif +#ifdef F_ThreadManForKernel_0120 + IMPORT_FUNC "ThreadManForKernel",0x3B183E26,sceKernelGetThreadExitStatus +#endif +#ifdef F_ThreadManForKernel_0121 + IMPORT_FUNC "ThreadManForKernel",0xF6427665,sceKernelGetUserLevel +#endif +#ifdef F_ThreadManForKernel_0122 + IMPORT_FUNC "ThreadManForKernel",0x85A2A5BF,sceKernelIsUserModeThread +#endif +#ifdef F_ThreadManForKernel_0123 + IMPORT_FUNC "ThreadManForKernel",0xDD55A192,sceKernelGetSyscallRA +#endif +#ifdef F_ThreadManForKernel_0124 + IMPORT_FUNC "ThreadManForKernel",0xBC31C1B9,sceKernelExtendKernelStack +#endif +#ifdef F_ThreadManForKernel_0125 + IMPORT_FUNC "ThreadManForKernel",0x4FE44D5E,sceKernelCheckThreadKernelStack +#endif +#ifdef F_ThreadManForKernel_0126 + IMPORT_FUNC "ThreadManForKernel",0xD13BDE95,sceKernelCheckThreadStack +#endif +#ifdef F_ThreadManForKernel_0127 + IMPORT_FUNC "ThreadManForKernel",0x52089CA1,sceKernelGetThreadStackFreeSize +#endif +#ifdef F_ThreadManForKernel_0128 + IMPORT_FUNC "ThreadManForKernel",0xD890B370,sceKernelGetThreadKernelStackFreeSize +#endif +#ifdef F_ThreadManForKernel_0129 + IMPORT_FUNC "ThreadManForKernel",0x17C1684E,sceKernelReferThreadStatus +#endif +#ifdef F_ThreadManForKernel_0130 + IMPORT_FUNC "ThreadManForKernel",0xFFC36A14,sceKernelReferThreadRunStatus +#endif +#ifdef F_ThreadManForKernel_0131 + IMPORT_FUNC "ThreadManForKernel",0x2D69D086,ThreadManForKernel_2D69D086 +#endif +#ifdef F_ThreadManForKernel_0132 + IMPORT_FUNC "ThreadManForKernel",0xFCB5EB49,sceKernelGetSystemStatusFlag +#endif +#ifdef F_ThreadManForKernel_0133 + IMPORT_FUNC "ThreadManForKernel",0x627E6F3A,sceKernelReferSystemStatus +#endif +#ifdef F_ThreadManForKernel_0134 + IMPORT_FUNC "ThreadManForKernel",0x94416130,sceKernelGetThreadmanIdList +#endif +#ifdef F_ThreadManForKernel_0135 + IMPORT_FUNC "ThreadManForKernel",0x57CF62DD,sceKernelGetThreadmanIdType +#endif diff --git a/src/kernel/UtilsForKernel.S b/src/kernel/UtilsForKernel.S new file mode 100644 index 00000000..e9254005 --- /dev/null +++ b/src/kernel/UtilsForKernel.S @@ -0,0 +1,124 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_UtilsForKernel_0000 + IMPORT_START "UtilsForKernel",0x00090000 +#endif +#ifdef F_UtilsForKernel_0001 + IMPORT_FUNC "UtilsForKernel",0x80FE032E,sceUtilsKernelDcacheWBinvRange +#endif +#ifdef F_UtilsForKernel_0002 + IMPORT_FUNC "UtilsForKernel",0xC8186A58,sceKernelUtilsMd5Digest +#endif +#ifdef F_UtilsForKernel_0003 + IMPORT_FUNC "UtilsForKernel",0x9E5C5086,sceKernelUtilsMd5BlockInit +#endif +#ifdef F_UtilsForKernel_0004 + IMPORT_FUNC "UtilsForKernel",0x61E1E525,sceKernelUtilsMd5BlockUpdate +#endif +#ifdef F_UtilsForKernel_0005 + IMPORT_FUNC "UtilsForKernel",0xB8D24E78,sceKernelUtilsMd5BlockResult +#endif +#ifdef F_UtilsForKernel_0006 + IMPORT_FUNC "UtilsForKernel",0x840259F1,sceKernelUtilsSha1Digest +#endif +#ifdef F_UtilsForKernel_0007 + IMPORT_FUNC "UtilsForKernel",0xF8FCD5BA,sceKernelUtilsSha1BlockInit +#endif +#ifdef F_UtilsForKernel_0008 + IMPORT_FUNC "UtilsForKernel",0x346F6DA8,sceKernelUtilsSha1BlockUpdate +#endif +#ifdef F_UtilsForKernel_0009 + IMPORT_FUNC "UtilsForKernel",0x585F1C09,sceKernelUtilsSha1BlockResult +#endif +#ifdef F_UtilsForKernel_0010 + IMPORT_FUNC "UtilsForKernel",0xE860E75E,sceKernelUtilsMt19937Init +#endif +#ifdef F_UtilsForKernel_0011 + IMPORT_FUNC "UtilsForKernel",0x06FB8A63,sceKernelUtilsMt19937UInt +#endif +#ifdef F_UtilsForKernel_0012 + IMPORT_FUNC "UtilsForKernel",0x193D4036,sceKernelSetGPIMask +#endif +#ifdef F_UtilsForKernel_0013 + IMPORT_FUNC "UtilsForKernel",0x95035FEF,sceKernelSetGPOMask +#endif +#ifdef F_UtilsForKernel_0014 + IMPORT_FUNC "UtilsForKernel",0x37FB5C42,sceKernelGetGPI +#endif +#ifdef F_UtilsForKernel_0015 + IMPORT_FUNC "UtilsForKernel",0x6AD345D7,sceKernelSetGPO +#endif +#ifdef F_UtilsForKernel_0016 + IMPORT_FUNC "UtilsForKernel",0x7B7ED3FD,sceKernelRegisterLibcRtcFunc +#endif +#ifdef F_UtilsForKernel_0017 + IMPORT_FUNC "UtilsForKernel",0x6151A7C3,sceKernelReleaseLibcRtcFunc +#endif +#ifdef F_UtilsForKernel_0018 + IMPORT_FUNC "UtilsForKernel",0x91E4F6A7,sceKernelLibcClock +#endif +#ifdef F_UtilsForKernel_0019 + IMPORT_FUNC "UtilsForKernel",0x27CC57F0,sceKernelLibcTime +#endif +#ifdef F_UtilsForKernel_0020 + IMPORT_FUNC "UtilsForKernel",0x71EC4271,sceKernelLibcGettimeofday +#endif +#ifdef F_UtilsForKernel_0021 + IMPORT_FUNC "UtilsForKernel",0x79D1C3FA,sceKernelDcacheWritebackAll +#endif +#ifdef F_UtilsForKernel_0022 + IMPORT_FUNC "UtilsForKernel",0xB435DEC5,sceKernelDcacheWritebackInvalidateAll +#endif +#ifdef F_UtilsForKernel_0023 + IMPORT_FUNC "UtilsForKernel",0x864A9D72,sceKernelDcacheInvalidateAll +#endif +#ifdef F_UtilsForKernel_0024 + IMPORT_FUNC "UtilsForKernel",0x3EE30821,sceKernelDcacheWritebackRange +#endif +#ifdef F_UtilsForKernel_0025 + IMPORT_FUNC "UtilsForKernel",0x34B9FA9E,sceKernelDcacheWritebackInvalidateRange +#endif +#ifdef F_UtilsForKernel_0026 + IMPORT_FUNC "UtilsForKernel",0xBFA98062,sceKernelDcacheInvalidateRange +#endif +#ifdef F_UtilsForKernel_0027 + IMPORT_FUNC "UtilsForKernel",0x80001C4C,sceKernelDcacheProbe +#endif +#ifdef F_UtilsForKernel_0028 + IMPORT_FUNC "UtilsForKernel",0x16641D70,sceKernelDcacheReadTag +#endif +#ifdef F_UtilsForKernel_0029 + IMPORT_FUNC "UtilsForKernel",0x920F104A,sceKernelIcacheInvalidateAll +#endif +#ifdef F_UtilsForKernel_0030 + IMPORT_FUNC "UtilsForKernel",0xC2DF770E,sceKernelIcacheInvalidateRange +#endif +#ifdef F_UtilsForKernel_0031 + IMPORT_FUNC "UtilsForKernel",0x4FD31C9D,sceKernelIcacheProbe +#endif +#ifdef F_UtilsForKernel_0032 + IMPORT_FUNC "UtilsForKernel",0xFB05FAD0,sceKernelIcacheReadTag +#endif +#ifdef F_UtilsForKernel_0033 + IMPORT_FUNC "UtilsForKernel",0x78934841,sceKernelGzipDecompress +#endif +#ifdef F_UtilsForKernel_0034 + IMPORT_FUNC "UtilsForKernel",0xE0CE3E29,sceKernelGzipIsValid +#endif +#ifdef F_UtilsForKernel_0035 + IMPORT_FUNC "UtilsForKernel",0xB0E9C31F,sceKernelGzipGetInfo +#endif +#ifdef F_UtilsForKernel_0036 + IMPORT_FUNC "UtilsForKernel",0xE0E6BA96,sceKernelGzipGetName +#endif +#ifdef F_UtilsForKernel_0037 + IMPORT_FUNC "UtilsForKernel",0x8C1FBE04,sceKernelGzipGetComment +#endif +#ifdef F_UtilsForKernel_0038 + IMPORT_FUNC "UtilsForKernel",0x23FFC828,sceKernelGzipGetCompressedData +#endif +#ifdef F_UtilsForKernel_0039 + IMPORT_FUNC "UtilsForKernel",0xE8DB3CE6,sceKernelDeflateDecompress +#endif diff --git a/src/kernel/pspaudiorouting.h b/src/kernel/pspaudiorouting.h new file mode 100755 index 00000000..58a3d193 --- /dev/null +++ b/src/kernel/pspaudiorouting.h @@ -0,0 +1,32 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspaudiorouting.h - Interface to sceAudioRouting. + * + * Copyright (c) 2007 Alexander Berl + * + * $Id: pspinit.h 2345 2007-12-08 02:34:59Z raphael $ + */ +#ifndef __PSPAUDIOROUTING_H__ +#define __PSPAUDIOROUTING_H__ + +/** + * Set routing mode. + * + * @param mode The routing mode to set (0 or 1) + * + * @return the previous routing mode, or < 0 on error +*/ +int sceAudioRoutingSetMode( int mode ); + +/** + * Get routing mode. + * + * @return the current routing mode. +*/ +int sceAudioRoutingGetMode(); + +#endif + diff --git a/src/kernel/pspexception.h b/src/kernel/pspexception.h new file mode 100644 index 00000000..423275dc --- /dev/null +++ b/src/kernel/pspexception.h @@ -0,0 +1,57 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspexception.h - Interface to the kernel side of ExceptionMan + * + * Copyright (c) 2006 James F. + * + * $Id: pspexception.h 1906 2006-05-09 18:42:57Z tyranid $ + */ + +#ifndef PSPEXCEPTION_H +#define PSPEXCEPTION_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Register a default exception handler. + * + * @param func - Pointer to the exception handler function + * @note The exception handler function must start with a NOP + * + * @return 0 on success, < 0 on error + */ +int sceKernelRegisterDefaultExceptionHandler(void *func); + +/** + * Register a exception handler + * + * @param exno - The exception number + * @param func - Pointer to the exception handler function + * + * @return 0 on success, < 0 on error + */ +int sceKernelRegisterExceptionHandler(int exno, void *func); + +/** + * Register a exception handler with a priority + * + * @param exno - The exception number + * @param priority - The priority of the exception + * @param func - Pointer to the exception handler function + * + * @return 0 on success, < 0 on error + */ +int sceKernelRegisterPriorityExceptionHandler(int exno, int priority, void *func); + +#ifdef __cplusplus +} +#endif + +#endif /* PSPEXCEPTION_H */ diff --git a/src/kernel/pspidstorage.h b/src/kernel/pspidstorage.h new file mode 100644 index 00000000..fed52f03 --- /dev/null +++ b/src/kernel/pspidstorage.h @@ -0,0 +1,60 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspidstorage.h - Interface to sceIdstorage_driver. + * + * Copyright (c) 2006 Harley G. + * + * $Id: pspidstorage.h 2120 2006-12-30 23:19:33Z tyranid $ + */ + +#ifndef PSPIDSTORAGE_H +#define PSPIDSTORAGE_H + +#include + +/** @defgroup IdStorage Interface to the sceIdStorage_driver library. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup IdStorage Interface to the sceIdStorage_driver library.*/ +/*@{*/ + +/**Retrieves the value associated with a key + * @param key - idstorage key + * @param offset - offset within the 512 byte leaf + * @param buf - buffer with enough storage + * @param len - amount of data to retrieve (offset + len must be <= 512 bytes) + */ +int sceIdStorageLookup(u16 key, u32 offset, void *buf, u32 len); + +/** Retrieves the whole 512 byte container for the key + * @param key - idstorage key + * @param buf - buffer with at last 512 bytes of storage + */ +int sceIdStorageReadLeaf(u16 key, void *buf); + +/** sceIdStorageWriteLeaf() - Writes 512-bytes to idstorage key + * @param key - idstorage key + * @param buf - buffer with 512-btes of data + */ +int sceIdStorageWriteLeaf(u16 key, void *buf); + +/** sceIdStorageIsReadOnly() - Checks idstorage for readonly status */ +int sceIdStorageIsReadOnly(void); + +/** sceIdStorageFlush() - Finalizes a write */ +int sceIdStorageFlush(void); + +/*@}*/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/kernel/pspimpose_driver.h b/src/kernel/pspimpose_driver.h new file mode 100644 index 00000000..ff64cf13 --- /dev/null +++ b/src/kernel/pspimpose_driver.h @@ -0,0 +1,142 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspimpose_driver.h - Prototypes for the sceImpose_driver library. + * + * Copyright (c) 2007 Iaroslav Gaponenko + * + * $Id: pspimpose_driver.h$ + */ + +#ifndef __IMPOSE_DRIVER_H__ +#define __IMPOSE_DRIVER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int SceImposeParam; + +/** + * These values have been found in the 3.52 kernel. + * Therefore, they might not be supported by previous ones. + */ + +#define PSP_IMPOSE_MAIN_VOLUME 0x1 +#define PSP_IMPOSE_BACKLIGHT_BRIGHTNESS 0x2 +#define PSP_IMPOSE_EQUALIZER_MODE 0x4 +#define PSP_IMPOSE_MUTE 0x8 +#define PSP_IMPOSE_AVLS 0x10 +#define PSP_IMPOSE_TIME_FORMAT 0x20 +#define PSP_IMPOSE_DATE_FORMAT 0x40 +#define PSP_IMPOSE_LANGUAGE 0x80 +#define PSP_IMPOSE_BACKLIGHT_OFF_INTERVAL 0x200 +#define PSP_IMPOSE_SOUND_REDUCTION 0x400 + +#define PSP_IMPOSE_UMD_POPUP_ENABLED 1 +#define PSP_IMPOSE_UMD_POPUP_DISABLED 0 + +/** + * Fetch the value of an Impose parameter. + * + * @return value of the parameter on success, < 0 on error + */ +int sceImposeGetParam(SceImposeParam param); + +/** + * Change the value of an Impose parameter. + * + * @param param - The parameter to change. + * @param value - The value to set the parameter to. + * @return < 0 on error + * + */ +int sceImposeSetParam(SceImposeParam param, int value); + +/** + * Get the value of the backlight timer. + * + * @return backlight timer in seconds or < 0 on error + * + */ +int sceImposeGetBacklightOffTime(void); + +/** + * Set the value of the backlight timer. + * + * @param value - The backlight timer. (30 to a lot of seconds) + * @return < 0 on error + * + */ +int sceImposeSetBacklightOffTime(int value); + +/** + * Get the language and button assignment parameters + * + * @return < 0 on error + * + */ +int sceImposeGetLanguageMode(int* lang, int* button); + +/** + * Set the language and button assignment parameters + * + * /!\ parameter values not known. + * + * @param lang - Language + * @param button - Button assignment + * @return < 0 on error + * + */ +int sceImposeSetLanguageMode(int lang, int button); + +/** + * Get the value of the UMD popup. + * + * @return umd popup state or < 0 on error + * + */ +int sceImposeGetUMDPopup(void); + +/** + * Set the value of the UMD popup. + * + * @param value - The popup mode. + * @return < 0 on error + * + */ +int sceImposeSetUMDPopup(int value); + +/** + * Get the value of the Home popup. + * + * @return home popup state or < 0 on error + * + */ +int sceImposeGetHomePopup(void); + +/** + * Set the value of the Home popup. + * + * @param value - The popup mode. + * @return < 0 on error + * + */ +int sceImposeSetHomePopup(int value); + +/** + * Check the video out. (for psp slim?) + * + * @param value - video out mode/status(?) + * @return < 0 on error + * + */ +int sceImposeCheckVideoOut(int* value); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/kernel/pspinit.h b/src/kernel/pspinit.h new file mode 100755 index 00000000..9fbb4e93 --- /dev/null +++ b/src/kernel/pspinit.h @@ -0,0 +1,74 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspinit.h - Interface to InitForKernel. + * + * Copyright (c) 2007 moonlight + * + * $Id: pspinit.h 2433 2008-10-15 10:00:27Z iwn $ + */ +#ifndef __PSPINIT_H__ +#define __PSPINIT_H__ + +enum PSPBootFrom +{ + PSP_BOOT_FLASH = 0, /* ? */ + PSP_BOOT_DISC = 0x20, + PSP_BOOT_MS = 0x40, +}; + +enum PSPInitApitype +{ + PSP_INIT_APITYPE_DISC = 0x120, + PSP_INIT_APITYPE_DISC_UPDATER = 0x121, + PSP_INIT_APITYPE_MS1 = 0x140, + PSP_INIT_APITYPE_MS2 = 0x141, + PSP_INIT_APITYPE_MS3 = 0x142, + PSP_INIT_APITYPE_MS4 = 0x143, + PSP_INIT_APITYPE_MS5 = 0x144, + PSP_INIT_APITYPE_VSH1 = 0x210, /* ExitGame */ + PSP_INIT_APITYPE_VSH2 = 0x220, /* ExitVSH */ +}; + +enum PSPKeyConfig +{ + PSP_INIT_KEYCONFIG_VSH = 0x100, + PSP_INIT_KEYCONFIG_GAME = 0x200, + PSP_INIT_KEYCONFIG_POPS = 0x300, +}; + +/** + * Gets the api type + * + * @return the api type in which the system has booted +*/ +int sceKernelInitApitype(); + +/** + * Gets the filename of the executable to be launched after all modules of the api. + * + * @return filename of executable or NULL if no executable found. +*/ +char *sceKernelInitFileName(); + +/** + * + * Gets the device in which the application was launched. + * + * @return the device code, one of PSPBootFrom values. +*/ +int sceKernelBootFrom(); + +/** + * Get the key configuration in which the system has booted. + * + * @return the key configuration code, one of PSPKeyConfig values +*/ +int InitForKernel_7233B5BC(); + +#define sceKernelInitKeyConfig InitForKernel_7233B5BC + +#endif + diff --git a/src/kernel/pspintrman_kernel.h b/src/kernel/pspintrman_kernel.h new file mode 100644 index 00000000..144f1034 --- /dev/null +++ b/src/kernel/pspintrman_kernel.h @@ -0,0 +1,82 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspintrman_kernel.h - Interface to the system interrupt manager. + * + * Copyright (c) 2005 James F. (tyranid@gmail.com) + * + * $Id: pspintrman_kernel.h 2100 2006-12-12 19:04:19Z tyranid $ + */ + +#ifndef PSPINTRMAN_KERNEL_H +#define PSPINTRMAN_KERNEL_H + +#include + +/** @defgroup IntrManKern Interrupt Manager Kernel + * This module contains routines to manage interrupts. + */ + +/** @addtogroup IntrManKern Interrupt Manager Kernel */ +/*@{*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Register an interrupt handler. + * + * @param intno - The interrupt number to register. + * @param no - The queue number. + * @param handler - Pointer to the handler. + * @param arg1 - Unknown (probably a set of flags) + * @param arg2 - Unknown (probably a common pointer) + * + * @return 0 on success. + */ +int sceKernelRegisterIntrHandler(int intno, int no, void *handler, void *arg1, void *arg2); + +/** + * Release an interrupt handler + * + * @param intno - The interrupt number to release + * + * @return 0 on success + */ +int sceKernelReleaseIntrHandler(int intno); + +/** + * Enable an interrupt. + * + * @param intno - Interrupt to enable. + * + * @return 0 on success. + */ +int sceKernelEnableIntr(int intno); + +/** + * Disable an interrupt. + * + * @param intno - Interrupt to disable. + * + * @return 0 on success. + */ +int sceKernelDisableIntr(int intno); + +/** + * Check if we are in an interrupt context or not + * + * @return 1 if we are in an interrupt context, else 0 + */ +int sceKernelIsIntrContext(void); + +#ifdef __cplusplus +} +#endif + +/*@}*/ + +#endif /* PSPINTRMAN_KERNEL_H */ diff --git a/src/kernel/pspiofilemgr_kernel.h b/src/kernel/pspiofilemgr_kernel.h new file mode 100644 index 00000000..6211e3e6 --- /dev/null +++ b/src/kernel/pspiofilemgr_kernel.h @@ -0,0 +1,166 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspiofilemgr_kernel.h - Interface to the kernel mode library for IoFileMgr. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: pspiofilemgr_kernel.h 1939 2006-06-04 22:03:42Z tyranid $ + */ + +#ifndef PSPIOFILEMGR_KERNEL_H +#define PSPIOFILEMGR_KERNEL_H + +#include +#include +#include + +/** @defgroup IoFileMgr_Kernel Driver interface to IoFileMgr + * This module contains the imports for the kernel's IO routines. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup IoFileMgr_Kernel Driver interface to IoFileMgr */ +/*@{*/ + +struct PspIoDrv; + +/** Structure passed to the init and exit functions of the io driver system */ +typedef struct PspIoDrvArg +{ + /** Pointer to the original driver which was added */ + struct PspIoDrv *drv; + /** Pointer to a user defined argument (if written by the driver will preseve across calls */ + void *arg; +} PspIoDrvArg; + +/** Structure passed to the file functions of the io driver system */ +typedef struct PspIoDrvFileArg +{ + /** Unknown */ + u32 unk1; + /** The file system number, e.g. if a file is opened as host5:/myfile.txt this field will be 5 */ + u32 fs_num; + /** Pointer to the driver structure */ + PspIoDrvArg *drv; + /** Unknown, again */ + u32 unk2; + /** Pointer to a user defined argument, this is preserved on a per file basis */ + void *arg; +} PspIoDrvFileArg; + +/** Structure to maintain the file driver pointers */ +typedef struct PspIoDrvFuncs +{ + int (*IoInit)(PspIoDrvArg* arg); + int (*IoExit)(PspIoDrvArg* arg); + int (*IoOpen)(PspIoDrvFileArg *arg, char *file, int flags, SceMode mode); + int (*IoClose)(PspIoDrvFileArg *arg); + int (*IoRead)(PspIoDrvFileArg *arg, char *data, int len); + int (*IoWrite)(PspIoDrvFileArg *arg, const char *data, int len); + SceOff (*IoLseek)(PspIoDrvFileArg *arg, SceOff ofs, int whence); + int (*IoIoctl)(PspIoDrvFileArg *arg, unsigned int cmd, void *indata, int inlen, void *outdata, int outlen); + int (*IoRemove)(PspIoDrvFileArg *arg, const char *name); + int (*IoMkdir)(PspIoDrvFileArg *arg, const char *name, SceMode mode); + int (*IoRmdir)(PspIoDrvFileArg *arg, const char *name); + int (*IoDopen)(PspIoDrvFileArg *arg, const char *dirname); + int (*IoDclose)(PspIoDrvFileArg *arg); + int (*IoDread)(PspIoDrvFileArg *arg, SceIoDirent *dir); + int (*IoGetstat)(PspIoDrvFileArg *arg, const char *file, SceIoStat *stat); + int (*IoChstat)(PspIoDrvFileArg *arg, const char *file, SceIoStat *stat, int bits); + int (*IoRename)(PspIoDrvFileArg *arg, const char *oldname, const char *newname); + int (*IoChdir)(PspIoDrvFileArg *arg, const char *dir); + int (*IoMount)(PspIoDrvFileArg *arg); + int (*IoUmount)(PspIoDrvFileArg *arg); + int (*IoDevctl)(PspIoDrvFileArg *arg, const char *devname, unsigned int cmd, void *indata, int inlen, void *outdata, int outlen); + int (*IoUnk21)(PspIoDrvFileArg *arg); +} PspIoDrvFuncs; + +typedef struct PspIoDrv +{ + /** The name of the device to add */ + const char *name; + /** Device type, this 0x10 is for a filesystem driver */ + u32 dev_type; + /** Unknown, set to 0x800 */ + u32 unk2; + /** This seems to be the same as name but capitalised :/ */ + const char *name2; + /** Pointer to a filled out functions table */ + PspIoDrvFuncs *funcs; +} PspIoDrv; + +/** + * Adds a new IO driver to the system. + * @note This is only exported in the kernel version of IoFileMgr + * + * @param drv - Pointer to a filled out driver structure + * @return < 0 on error. + * + * @par Example: + * @code + * PspIoDrvFuncs host_funcs = { ... }; + * PspIoDrv host_driver = { "host", 0x10, 0x800, "HOST", &host_funcs }; + * sceIoDelDrv("host"); + * sceIoAddDrv(&host_driver); + * @endcode + */ +int sceIoAddDrv(PspIoDrv *drv); + +/** + * Deletes a IO driver from the system. + * @note This is only exported in the kernel version of IoFileMgr + * + * @param drv_name - Name of the driver to delete. + * @return < 0 on error + */ +int sceIoDelDrv(const char *drv_name); + +/** + * Reopens an existing file descriptor. + * + * @param file - The new file to open. + * @param flags - The open flags. + * @param mode - The open mode. + * @param fd - The old filedescriptor to reopen + * + * @return < 0 on error, otherwise the reopened fd. + */ +int sceIoReopen(const char *file, int flags, SceMode mode, SceUID fd); + +/** + * Get the current working directory for a thread. + * + * @param uid - The UID of the thread + * @param dir - A character buffer in which to store the cwd + * @param len - The length of the buffer + * + * @return Number of characters written to buf, if no cwd then 0 is + * returned. + */ +int sceIoGetThreadCwd(SceUID uid, char *dir, int len); + +/** + * Set the current working directory for a thread + * + * @param uid - The UID of the thread + * @param dir - The directory to set + * + * @return 0 on success, < 0 on error + */ +int sceIoChangeThreadCwd(SceUID uid, char *dir); + +/*@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* PSPIOFILEMGR_KERNEL_H */ diff --git a/src/kernel/pspkdebug.h b/src/kernel/pspkdebug.h new file mode 100644 index 00000000..1abe82d4 --- /dev/null +++ b/src/kernel/pspkdebug.h @@ -0,0 +1,59 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspkdebug.h - Interface to KDebugForKernel. + * + * Copyright (c) 2005 James Forshaw + * + * $Id: pspkdebug.h 1971 2006-07-17 19:43:52Z tyranid $ + */ + +#ifndef PSPKDEBUG_H +#define PSPKDEBUG_H + +#include + +/** @defgroup Kdebug Interface to the KDebugForKernel library. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup Kdebug Interface to the KDebugForKernel library. */ +/*@{*/ + +/** Typedef for the debug putcharacter handler */ +typedef void (*PspDebugPutChar)(unsigned short* args, unsigned int ch); + +/** + * Register a debug put character handler + * + * @param func - The put character function to register. + */ +void sceKernelRegisterDebugPutchar(PspDebugPutChar func); + +/** + * Get the debug put character handler + * + * @return The current debug putchar handler + */ +PspDebugPutChar sceKernelGetDebugPutchar(void); + +/** + * Kernel printf function. + * + * @param format - The format string. + * @param ... - Arguments for the format string. + */ +void Kprintf(const char *format, ...) __attribute__((format(printf, 1, 2))); + +/*@}*/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/kernel/pspkernel.h b/src/kernel/pspkernel.h new file mode 100644 index 00000000..b8a9f30d --- /dev/null +++ b/src/kernel/pspkernel.h @@ -0,0 +1,72 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspkernel.h - Main include file that includes all major kernel headers. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: pspkernel.h 1207 2005-10-23 05:50:29Z mrbrown $ + */ + +#ifndef PSPKERNEL_H +#define PSPKERNEL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Set the $pc register to a kernel memory address. + * + * When the PSP's kernel library stubs are called, they expect to be accessed + * from the kernel's address space. Use this function to set $pc to the kernel + * address space, before calling a kernel library stub. + */ +#define pspKernelSetKernelPC() \ +{ \ + __asm__ volatile ( \ + "la $8, 1f\n\t" \ + "lui $9, 0x8000\n\t" \ + "or $8, $9\n\t" \ + "jr $8\n\t" \ + " nop\n\t" \ + "1:\n\t" \ + : : : "$8", "$9"); \ + sceKernelIcacheClearAll(); \ +} + +/** + * Set the $pc register to a user memory address. + * + */ +#define pspKernelSetUserPC() \ +{ \ + __asm__ volatile ( \ + "la $8, 1f\n\t" \ + "li $9, 0x7FFFFFFF\n\t" \ + "and $8, $9\n\t" \ + "jr $8\n\t" \ + " nop\n\t" \ + "1:\n\t" \ + : : : "$8", "$9"); \ + sceKernelIcacheClearAll(); \ +} + +#ifdef __cplusplus +} +#endif + +#endif /* PSPKERNEL_H */ diff --git a/src/kernel/psploadcore.h b/src/kernel/psploadcore.h new file mode 100644 index 00000000..1c106972 --- /dev/null +++ b/src/kernel/psploadcore.h @@ -0,0 +1,146 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * psploadcore.h - Interface to LoadCoreForKernel. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: psploadcore.h 2433 2008-10-15 10:00:27Z iwn $ + */ + +#ifndef PSPLOADCORE_H +#define PSPLOADCORE_H + +#include + +/** @defgroup LoadCore Interface to the LoadCoreForKernel library. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup LoadCore Interface to the LoadCoreForKernel library. */ +/*@{*/ + +/** Describes a module. This structure could change in future firmware revisions. */ +typedef struct SceModule { + struct SceModule *next; + unsigned short attribute; + unsigned char version[2]; + char modname[27]; + char terminal; + unsigned int unknown1; + unsigned int unknown2; + SceUID modid; + unsigned int unknown3[4]; + void * ent_top; + unsigned int ent_size; + void * stub_top; + unsigned int stub_size; + unsigned int unknown4[4]; + unsigned int entry_addr; + unsigned int gp_value; + unsigned int text_addr; + unsigned int text_size; + unsigned int data_size; + unsigned int bss_size; + unsigned int nsegment; + unsigned int segmentaddr[4]; + unsigned int segmentsize[4]; +} SceModule; + +/** Defines a library and its exported functions and variables. Use the len + member to determine the real size of the table (size = len * 4). */ +typedef struct SceLibraryEntryTable { + /**The library's name. */ + const char * libname; + /** Library version. */ + unsigned char version[2]; + /** Library attributes. */ + unsigned short attribute; + /** Length of this entry table in 32-bit WORDs. */ + unsigned char len; + /** The number of variables exported by the library. */ + unsigned char vstubcount; + /** The number of functions exported by the library. */ + unsigned short stubcount; + /** Pointer to the entry table; an array of NIDs followed by + pointers to functions and variables. */ + void * entrytable; +} SceLibraryEntryTable; + +/** Specifies a library and a set of imports from that library. Use the len + member to determine the real size of the table (size = len * 4). */ +typedef struct SceLibraryStubTable { + /* The name of the library we're importing from. */ + const char * libname; + /** Minimum required version of the library we want to import. */ + unsigned char version[2]; + /* Import attributes. */ + unsigned short attribute; + /** Length of this stub table in 32-bit WORDs. */ + unsigned char len; + /** The number of variables imported from the library. */ + unsigned char vstubcount; + /** The number of functions imported from the library. */ + unsigned short stubcount; + /** Pointer to an array of NIDs. */ + unsigned int * nidtable; + /** Pointer to the imported function stubs. */ + void * stubtable; + /** Pointer to the imported variable stubs. */ + void * vstubtable; +} SceLibraryStubTable; + + +/** + * Find a module by it's name. + * + * @param modname - The name of the module. + * + * @return Pointer to the ::SceModule structure if found, otherwise NULL. + */ +SceModule * sceKernelFindModuleByName(const char *modname); + +/** + * Find a module from an address. + * + * @param addr - Address somewhere within the module. + * + * @return Pointer to the ::SceModule structure if found, otherwise NULL. + */ +SceModule * sceKernelFindModuleByAddress(unsigned int addr); + +/** + * Find a module by it's UID. + * + * @param modid - The UID of the module. + * + * @return Pointer to the ::SceModule structure if found, otherwise NULL. + */ +SceModule * sceKernelFindModuleByUID(SceUID modid); + +/** + * Return the count of loaded modules. + * + * @return The count of loaded modules. + */ +int sceKernelModuleCount(void); + +/** + * Invalidate the CPU's instruction cache. + */ +void sceKernelIcacheClearAll(void); + +/*@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* PSPLOADCORE_H */ diff --git a/src/kernel/psploadexec_kernel.h b/src/kernel/psploadexec_kernel.h new file mode 100644 index 00000000..4b1c4f4d --- /dev/null +++ b/src/kernel/psploadexec_kernel.h @@ -0,0 +1,165 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * psploadexec_kernel.h - Interface to LoadExecForKernel. + * + * Copyright (c) 2007 - DA (Taken from the 303oe SDK) + * + * $Id$ + */ + +#ifndef PSPLOADEXEC_KERNEL_H +#define PSPLOADEXEC_KERNEL_H + +#include +#include + +/** @defgroup LoadExecKernel Interface to the LoadExecForKernel library. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup LoadExecKernel Interface to the LoadExecForKernel library. */ +/*@{*/ + +/** Structure for LoadExecVSH* functions */ +struct SceKernelLoadExecVSHParam { +/** Size of the structure in bytes */ + SceSize size; +/** Size of the arguments string */ + SceSize args; +/** Pointer to the arguments strings */ + void * argp; +/** The key, usually "game", "updater" or "vsh" */ + const char * key; +/** The size of the vshmain arguments */ + u32 vshmain_args_size; +/** vshmain arguments that will be passed to vshmain after the program has exited */ + void *vshmain_args; +/** "/kd/pspbtcnf_game.txt" or "/kd/pspbtcnf.txt" if not supplied (max. 256 chars) */ + char *configfile; +/** An unknown string (max. 256 chars) probably used in 2nd stage of loadexec */ + u32 unk4; +/** unknown flag default value = 0x10000 */ + u32 unk5; +}; + +#if _PSP_FW_VERSION < 200 +/** + * Executes a new executable from a buffer. + * + * @param bufsize - Size in bytes of the buffer pointed by buf. + * @param buf - Pointer to a buffer containing the module to execute. + * @param param - Pointer to a ::SceKernelLoadExecParam structure, or NULL. + * + * @return < 0 on some errors. +*/ +int sceKernelLoadExecBufferPlain(SceSize bufsize, void *buf, struct SceKernelLoadExecParam *param); +#endif + +/** + * Restart the vsh. + * + * @param param - Pointer to a ::SceKernelLoadExecVSHParam structure, or NULL + * + * @return < 0 on some errors. + * + * @note - when called in game mode it will have the same effect that sceKernelExitGame + * +*/ +int sceKernelExitVSHVSH(struct SceKernelLoadExecVSHParam *param); + +#if _PSP_FW_VERSION >= 200 +/** + * Restart the vsh (to be used by a kernel module) + * + * @param param - Pointer to a ::SceKernelLoadExecVSHParam structure, or NULL + * + * @return < 0 on some errors. + * + * @note - when called in game mode it will have the same effect that sceKernelExitGame + * @note2: available since firmware 2.00. +*/ +int sceKernelExitVSHKernel(struct SceKernelLoadExecVSHParam *param); +#endif + +/** + * Executes a new executable from a disc. + * It is the function used by the firmware to execute the EBOOT.BIN from a disc. + * + * @param file - The file to execute. + * @param param - Pointer to a ::SceKernelLoadExecVSHParam structure, or NULL. + * + * @return < 0 on some errors. +*/ +int sceKernelLoadExecVSHDisc(const char *file, struct SceKernelLoadExecVSHParam *param); + +/** + * Executes a new executable from a disc. + * It is the function used by the firmware to execute an updater from a disc. + * + * @param file - The file to execute. + * @param param - Pointer to a ::SceKernelLoadExecVSHParam structure, or NULL. + * + * @return < 0 on some errors. +*/ +int sceKernelLoadExecVSHDiscUpdater(const char *file, struct SceKernelLoadExecVSHParam *param); + +/** + * Executes a new executable from a memory stick. + * It is the function used by the firmware to execute an updater from a memory stick. + * + * @param file - The file to execute. + * @param param - Pointer to a ::SceKernelLoadExecVSHParam structure, or NULL. + * + * @return < 0 on some errors. +*/ +int sceKernelLoadExecVSHMs1(const char *file, struct SceKernelLoadExecVSHParam *param); + +/** + * Executes a new executable from a memory stick. + * It is the function used by the firmware to execute games (and homebrew :P) from a memory stick. + * + * @param file - The file to execute. + * @param param - Pointer to a ::SceKernelLoadExecVSHParam structure, or NULL. + * + * @return < 0 on some errors. +*/ +int sceKernelLoadExecVSHMs2(const char *file, struct SceKernelLoadExecVSHParam *param); + +/** + * Executes a new executable from a memory stick. + * It is the function used by the firmware to execute ... ? + * + * @param file - The file to execute. + * @param param - Pointer to a ::SceKernelLoadExecVSHParam structure, or NULL. + * + * @return < 0 on some errors. +*/ +int sceKernelLoadExecVSHMs3(const char *file, struct SceKernelLoadExecVSHParam *param); + +#if _PSP_FW_VERSION >= 300 +/*** + * Executes a new executable from a memory stick. + * It is the function used by the firmware to execute psx games + * + * @param file - The file to execute. + * @param param - Pointer to a ::SceKernelLoadExecVSHParam structure, or NULL. + * + * @return < 0 on some errors. + * @note - Available since firmware 3.00 +*/ +int sceKernelLoadExecVSHMs4(const char *file, struct SceKernelLoadExecVSHParam *param); +#endif + +/*@}*/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/kernel/pspmodulemgr_kernel.h b/src/kernel/pspmodulemgr_kernel.h new file mode 100644 index 00000000..9b93ae3e --- /dev/null +++ b/src/kernel/pspmodulemgr_kernel.h @@ -0,0 +1,68 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspmodulemgr_kernel.h - Prototypes to manage modules. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: pspmodulemgr.h 792 2005-07-27 09:03:36Z warren $ + */ + +#ifndef __MODMGRKERNEL_H__ +#define __MODMGRKERNEL_H__ + +#include +#include + +/** @defgroup ModuleMgrKern Kernel Module Manager Library + * This module contains the imports for the kernel's module management routines. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup ModuleMgrKern Kernel Module Manager Library */ +/*@{*/ + +/** + * Gets the current module list. + * + * @param readbufsize - The size of the read buffer. + * @param readbuf - Pointer to a buffer to store the IDs + * + * @return < 0 on error. + */ +int sceKernelGetModuleList(int readbufsize, SceUID *readbuf); + +/** + * Get the number of loaded modules. + * + * @return The number of loaded modules. + */ +int sceKernelModuleCount(void); + +/** + * Load a module from a buffer + * + * @param buf - Pointer to a buffer containing the module to load. The buffer must reside at an + * address that is a multiple to 64 bytes. + * @param bufsize - Size (in bytes) of the buffer pointed to by buf. + * @param flags - Unused, always 0. + * @param option - Pointer to an optional ::SceKernelLMOption structure. + * + * @return The UID of the loaded module on success, otherwise one of ::PspKernelErrorCodes. + */ +SceUID sceKernelLoadModuleBuffer(void *buf, SceSize bufsize, int flags, SceKernelLMOption *option); + +/*@}*/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/kernel/pspstdio_kernel.h b/src/kernel/pspstdio_kernel.h new file mode 100644 index 00000000..38ef6cb0 --- /dev/null +++ b/src/kernel/pspstdio_kernel.h @@ -0,0 +1,72 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspstdio_kernel.h - Interface to the kernel mode library for Stdio. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: pspstdio_kernel.h 1095 2005-09-27 21:02:16Z jim $ + */ + +#ifndef PSPSTDIO_KERNEL_H +#define PSPSTDIO_KERNEL_H + +#include +#include +#include + +/** @defgroup Stdio_Kernel Driver interface to Stdio + * This module contains the imports for the kernel's stdio routines. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup Stdio_Kernel Driver interface to Stdio */ +/*@{*/ + +/** + * Function reopen the stdout file handle to a new file + * + * @param file - The file to open. + * @param flags - The open flags + * @param mode - The file mode + * + * @return < 0 on error. + */ +int sceKernelStdoutReopen(const char *file, int flags, SceMode mode); + +/** + * Function reopen the stderr file handle to a new file + * + * @param file - The file to open. + * @param flags - The open flags + * @param mode - The file mode + * + * @return < 0 on error. + */ +int sceKernelStderrReopen(const char *file, int flags, SceMode mode); + + +/** + * fprintf but for file descriptors + * + * @param fd - file descriptor from sceIoOpen + * @param format - format string + * @param ... - variables + * + * @return number of characters printed, <0 on error + */ +int fdprintf(int fd, const char *format, ...); +/*@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* PSPSTDIO_KERNEL_H */ diff --git a/src/kernel/pspsysclib.h b/src/kernel/pspsysclib.h new file mode 100644 index 00000000..e49ca71f --- /dev/null +++ b/src/kernel/pspsysclib.h @@ -0,0 +1,43 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspsysclib.h - Interface to sysclib library. + * + * Copyright (c) 2007 James F + * + * $Id$ + */ + +#ifndef PSPSYSCLIB_H +#define PSPSYSCLIB_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Callback type, ch is 0x200 on start of string, 0x201 on end */ +typedef void (*prnt_callback)(void *ctx, int ch); + +/** + * Generic print routine + * + * @param cb - Callback, called for every character printed + * @param ctx - Context parameter passed to the callback + * @param fmt - Format data + * @param args - Arguments for format + * + */ +void prnt(prnt_callback cb, void *ctx, const char *fmt, va_list args); + +/*@}*/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/kernel/pspsyscon.h b/src/kernel/pspsyscon.h new file mode 100644 index 00000000..e4052532 --- /dev/null +++ b/src/kernel/pspsyscon.h @@ -0,0 +1,74 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspsyscon.h - Interface to sceSyscon_driver. + * + * Copyright (c) 2006 James F + * + * $Id: pspsyscon.h 2413 2008-07-23 22:04:04Z raphael $ + */ + +#ifndef PSPSYSCON_H +#define PSPSYSCON_H + +#include + +/** @defgroup Syscon Interface to the sceSyscon_driver library. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup Syscon Interface to the sceSyscon_driver library. */ +/*@{*/ + +/** + * Force the PSP to go into standby + */ +void sceSysconPowerStandby(void); + +/** + * Reset the PSP + * + * @param unk1 - Unknown, pass 1 + * @param unk2 - Unknown, pass 1 + */ +void sceSysconResetDevice(int unk1, int unk2); + +#define SCE_LED_POWER 1 +#define LED_ON 1 +#define LED_OFF 0 +/** + * Control an LED + * + * @param SceLED - The led to toggle (only SCE_LED_POWER) + * @param state - Whether to turn on or off + */ +int sceSysconCtrlLED(int SceLED, int state); + +/** + * Control the remote control power + * + * @param power - 1 is on, 0 is off + * + * @return < 0 on error + */ +int sceSysconCtrlHRPower(int power); + + +int sceSysconGetHPConnect(void); + +int sceSysconSetHPConnectCallback( void (*)(int), int unk0 ); + +int sceSysconSetHRPowerCallback( void (*)(int), int unk0 ); + +/*@}*/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/kernel/pspsysevent.h b/src/kernel/pspsysevent.h new file mode 100644 index 00000000..0698208b --- /dev/null +++ b/src/kernel/pspsysevent.h @@ -0,0 +1,88 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspsysevent.h - Prototypes for the sceSysEventForKernel library + * + * Copyright (c) 2007 Iaroslav Gaponenko + * + */ +#ifndef __PSPSYSEVENT_H__ +#define __PSPSYSEVENT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct PspSysEventHandler _PspSysEventHandler; + +typedef int (*PspSysEventHandlerFunc)(int ev_id, char* ev_name, void* param, int* result); + +typedef struct PspSysEventHandler{ + int size; + char* name; + int type_mask; + int (*handler)(int ev_id, char* ev_name, void* param, int* result); + int r28; + int busy; + _PspSysEventHandler *next; + int reserved[9]; +}PspSysEventHandler; + + +/** + * Dispatch a SysEvent event. + * + * @param ev_type_mask - the event type mask + * @param ev_id - the event id + * @param ev_name - the event name + * @param param - the pointer to the custom parameters + * @param result - the pointer to the result + * @param break_nonzero - set to 1 to interrupt the calling chain after the first non-zero return + * @param break_handler - the pointer to the event handler having interrupted + * @return 0 on success, < 0 on error + */ +int sceKernelSysEventDispatch(int ev_type_mask, int ev_id, char* ev_name, void* param, int* result, int break_nonzero, PspSysEventHandler* break_handler); + + +/** + * Get the first SysEvent handler (the rest can be found with the linked list). + * + * @return 0 on error, handler on success + */ +PspSysEventHandler* sceKernelReferSysEventHandler(void); + + +/** + * Check if a SysEvent handler is registered. + * + * @param handler - the handler to check + * @return 0 if the handler is not registered + */ +int sceKernelIsRegisterSysEventHandler(PspSysEventHandler* handler); + + +/** + * Register a SysEvent handler. + * + * @param handler - the handler to register + * @return 0 on success, < 0 on error + */ +int sceKernelRegisterSysEventHandler(PspSysEventHandler* handler); + + +/** + * Unregister a SysEvent handler. + * + * @param handler - the handler to unregister + * @return 0 on success, < 0 on error + */ +int sceKernelUnregisterSysEventHandler(PspSysEventHandler* handler); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/src/kernel/pspsysmem_kernel.h b/src/kernel/pspsysmem_kernel.h new file mode 100644 index 00000000..3654bb3f --- /dev/null +++ b/src/kernel/pspsysmem_kernel.h @@ -0,0 +1,210 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspsysmem_kernel.h - Interface to the system memory manager (kernel). + * + * Copyright (c) 2005 James F. + * + * $Id: pspsysmem.h 1095 2005-09-27 21:02:16Z jim $ + */ + +/* Note: Some of the structures, types, and definitions in this file were + extrapolated from symbolic debugging information found in the Japanese + version of Puzzle Bobble. */ + +#ifndef PSPSYSMEMKERNEL_H +#define PSPSYSMEMKERNEL_H + +#include +#include + +/** @defgroup SysMemKern System Memory Manager Kernel + * This module contains routines to manage heaps of memory. + */ + +/** @addtogroup SysMemKern System Memory Manager Kernel */ +/*@{*/ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _PspSysmemPartitionInfo +{ + SceSize size; + unsigned int startaddr; + unsigned int memsize; + unsigned int attr; +} PspSysmemPartitionInfo; + +/** + * Query the parition information + * + * @param pid - The partition id + * @param info - Pointer to the ::PspSysmemPartitionInfo structure + * + * @return 0 on success. + */ +int sceKernelQueryMemoryPartitionInfo(int pid, PspSysmemPartitionInfo *info); + +/** + * Get the total amount of free memory. + * + * @param pid - The partition id + * + * @return The total amount of free memory, in bytes. + */ +SceSize sceKernelPartitionTotalFreeMemSize(int pid); + +/** + * Get the size of the largest free memory block. + * + * @param pid - The partition id + * + * @return The size of the largest free memory block, in bytes. + */ +SceSize sceKernelPartitionMaxFreeMemSize(int pid); + +/** + * Get the kernel to dump the internal memory table to Kprintf + */ +void sceKernelSysMemDump(void); + +/** + * Dump the list of memory blocks + */ +void sceKernelSysMemDumpBlock(void); + +/** + * Dump the tail blocks + */ +void sceKernelSysMemDumpTail(void); + +/** + * Set the protection of a block of ddr memory + * + * @param addr - Address to set protection on + * @param size - Size of block + * @param prot - Protection bitmask + * + * @return < 0 on error + */ +int sceKernelSetDdrMemoryProtection(void *addr, int size, int prot); + +/** + * Create a heap. + * + * @param partitionid - The UID of the partition where allocate the heap. + * @param size - The size in bytes of the heap. + * @param unk - Unknown, probably some flag or type, pass 1. + * @param name - Name assigned to the new heap. + * + * @return The UID of the new heap, or if less than 0 an error. +*/ +SceUID sceKernelCreateHeap(SceUID partitionid, SceSize size, int unk, const char *name); + +/** + * Allocate a memory block from a heap. + * + * @param heapid - The UID of the heap to allocate from. + * @param size - The number of bytes to allocate. + * + * @return The address of the allocated memory block, or NULL on error. +*/ +void *sceKernelAllocHeapMemory(SceUID heapid, SceSize size); + +/** + * Free a memory block allocated from a heap. + * + * @param heapid - The UID of the heap where block belongs. + * @param block - The block of memory to free from the heap. + * + * @return 0 on success, < 0 on error. + */ +int sceKernelFreeHeapMemory(SceUID heapid, void *block); + +/** + * Delete a heap. + * + * @param heapid - The UID of the heap to delete. + * + * @return 0 on success, < 0 on error. +*/ +int sceKernelDeleteHeap(SceUID heapid); + +/** + * Get the amount of free size of a heap, in bytes. + * + * @param heapid - The UID of the heap + * + * @return the free size of the heap, in bytes. < 0 on error. +*/ +SceSize sceKernelHeapTotalFreeSize(SceUID heapid); + +/** Structure of a UID control block */ +struct _uidControlBlock { + struct _uidControlBlock *parent; + struct _uidControlBlock *nextChild; + struct _uidControlBlock *type; //(0x8) + u32 UID; //(0xC) + char *name; //(0x10) + unsigned char unk; + unsigned char size; // Size in words + short attribute; + struct _uidControlBlock *nextEntry; +} __attribute__((packed)); +typedef struct _uidControlBlock uidControlBlock; + +/** + * Get a UID control block + * + * @param uid - The UID to find + * @param block - Pointer to hold the pointer to the block + * + * @return 0 on success + */ +int sceKernelGetUIDcontrolBlock(SceUID uid, uidControlBlock** block); + +/** + * Get a UID control block on a particular type + * + * @param uid - The UID to find + * @param type - Pointer to the type UID block + * @param block - Pointer to hold the pointer to the block + * + * @return 0 on success + */ +int sceKernelGetUIDcontrolBlockWithType(SceUID uid, uidControlBlock* type, uidControlBlock** block); + +/** + * Get the root of the UID tree (1.5+ only) + * + * @return Pointer to the UID tree root + */ +uidControlBlock* SysMemForKernel_536AD5E1(void); + +/** + * Delete a UID + * + * @param uid - The UID to delete + * + * @return 0 on success + */ +int sceKernelDeleteUID(SceUID uid); + +/** + * Get the model of PSP + * + * @return <= 0 original, 1 slim + */ +int sceKernelGetModel(void); + +#ifdef __cplusplus +} +#endif + +/*@}*/ + +#endif /* PSPSYSMEMKERNEL_H */ diff --git a/src/kernel/pspsysreg.h b/src/kernel/pspsysreg.h new file mode 100644 index 00000000..3ef06edb --- /dev/null +++ b/src/kernel/pspsysreg.h @@ -0,0 +1,78 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspsysreg.h - Interface to sceSysreg_driver. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: pspsysreg.h 1095 2005-09-27 21:02:16Z jim $ + */ + +#ifndef PSPSYSREG_H +#define PSPSYSREG_H + +#include + +/** @defgroup Sysreg Interface to the sceSysreg_driver library. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup Sysreg Interface to the sceSysreg_driver library. */ +/*@{*/ + +/** + * Enable the ME reset. + * + * @return < 0 on error. + */ +int sceSysregMeResetEnable(void); + +/** + * Disable the ME reset. + * + * @return < 0 on error. + */ +int sceSysregMeResetDisable(void); + +/** + * Enable the VME reset. + * + * @return < 0 on error. + */ +int sceSysregVmeResetEnable(void); + +/** + * Disable the VME reset. + * + * @return < 0 on error. + */ +int sceSysregVmeResetDisable(void); + +/** + * Enable the ME bus clock. + * + * @return < 0 on error. + */ +int sceSysregMeBusClockEnable(void); + +/** + * Disable the ME bus clock. + * + * @return < 0 on error. + */ +int sceSysregMeBusClockDisable(void); + +/*@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* PSPLOADCORE_H */ diff --git a/src/kernel/pspsystimer.h b/src/kernel/pspsystimer.h new file mode 100644 index 00000000..537a6b38 --- /dev/null +++ b/src/kernel/pspsystimer.h @@ -0,0 +1,93 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspsystimer.h - Prototypes for the sceSystimer library. + * + * Copyright (c) 2007 Iaroslav Gaponenko + * + * $Id: pspsystimer.h 2149 2007-01-25 20:46:21Z tyranid $ + */ + +#ifndef __SYSTIMER_H__ +#define __SYSTIMER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int SceSysTimerId; + +/** + * Allocate a new SysTimer timer instance. + * + * @return SysTimerId on success, < 0 on error + */ +SceSysTimerId sceSTimerAlloc(void); + +/** + * Free an instance of a SysTimer timer. + * + * @param timer - The timer id. + * + */ +void sceSTimerFree(SceSysTimerId timer); + +/** + * Start the SysTimer timer count. + * + * @param timer - The timer id. + * + */ +void sceSTimerStartCount(SceSysTimerId timer); + +/** + * Stop the current SysTimer timer count. + * + * @param timer - The timer id. + * + */ +void sceSTimerStopCount(SceSysTimerId timer); + +/** + * Reset the current SysTimer timer count. + * + * @param timer - The timer id. + * + */ +void sceSTimerResetCount(SceSysTimerId timer); + +/** + * Get the current SysTimer timer count. + * + * @param timer - The timer id. + * @param count - The pointer to an integer into which the count will be written. + * + */ +void sceSTimerGetCount(SceSysTimerId timer, int* count); + +/** + * Setup a SysTimer handler + * + * @param timer - The timer id. + * @param cycle - The timer cycle in microseconds (???). Maximum: 4194303 which represents ~1/10 seconds. + * @param handler - The handler function. Has to return -1. + * @param unk1 - Unknown. Pass 0. + * + */ +void sceSTimerSetHandler(SceSysTimerId timer, int cycle, int (*handler)(void), int unk1); + +/* Unknown functions. */ +//probably something to set the cycle of an active timer. +void SysTimerForKernel_53231A15(SceSysTimerId timer, int unk1); +//more complex. computes some ratio (unk2/unk1) and saves both parameters into the hardware registers. Might be some sort of scaling factor? +void SysTimerForKernel_B53534B4(SceSysTimerId timer, int unk1, int unk2); + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/kernel/pspthreadman_kernel.h b/src/kernel/pspthreadman_kernel.h new file mode 100644 index 00000000..13e227ba --- /dev/null +++ b/src/kernel/pspthreadman_kernel.h @@ -0,0 +1,234 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspthreadman_kernel.h - Interface to the kernel side of threadman + * + * Copyright (c) 2005 James F. + * + * $Id: pspthreadman_kernel.h 2131 2007-01-15 21:42:22Z tyranid $ + */ + +#ifndef PSPTHREADMANKERNEL_H +#define PSPTHREADMANKERNEL_H + +#include +#include + +/** @defgroup ThreadmanKern Thread Manager kernel functions + * This module contains routines to threads in the kernel + */ + +/** @addtogroup ThreadmanKern Thread Manager kernel functions */ +/*@{*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Suspend all user mode threads in the system + * + * @return 0 on success, < 0 on error + */ +int sceKernelSuspendAllUserThreads(void); + +/** + * Checks if the current thread is a usermode thread + * + * @return 0 if kernel, 1 if user, < 0 on error + */ +int sceKernelIsUserModeThread(void); + +/** + * Get the user level of the current thread + * + * @return The user level, < 0 on error + */ +int sceKernelGetUserLevel(void); + +/** + * Get the return address of the current thread's syscall + * + * @return The RA, 0 on error + */ +unsigned int sceKernelGetSyscallRA(void); + +/** + * Get the free stack space on the kernel thread + * + * @param thid - The UID of the thread + * + * @return The free stack space, < 0 on error + */ +int sceKernelGetThreadKernelStackFreeSize(SceUID thid); + +/** + * Check the thread kernel stack + * + * @return Unknown + */ +int sceKernelCheckThreadKernelStack(void); + +/** + * Extend the kernel thread stack + * + * @param type - The type of block allocation. One of ::PspSysMemBlockTypes + * @param cb - A pointer to a callback function + * @param arg - A pointer to a user specified argument + * + * @return < 0 on error + */ +int sceKernelExtendKernelStack(int type, void (*cb)(void*), void *arg); + +/** + * Get the system status flag + * + * @return The system status flag + */ +unsigned int sceKernelGetSystemStatusFlag(void); + +/** + * Setup the KTLS allocator + * + * @param id - The ID of the allocator + * @param cb - The allocator callback + * @param arg - User specified arg passed to the callback + * + * @return < 0 on error, allocation id on success + */ +int sceKernelAllocateKTLS(int id, int (*cb)(unsigned int *size, void *arg), void *arg); + +/** + * Free the KTLS allocator + * + * @param id - The allocation id returned from AllocateKTLS + * + * @return < 0 on error + */ +int sceKernelFreeKTLS(int id); + +/** + * Get the KTLS of the current thread + * + * @param id - The allocation id returned from AllocateKTLS + * + * @return The current KTLS, NULL on error + */ +void *sceKernelGetKTLS(int id); + +/** + * Get the KTLS of a thread + * + * @param id - The allocation id returned from AllocateKTLS + * @param thid - The thread is, 0 for current thread + * @param mode - Perhaps? Sees to be set to 0 or 1 + * + * @return The current KTLS, NULL on error + */ +void *sceKernelGetThreadKTLS(int id, SceUID thid, int mode); + +/** Thread context + * Structues for the thread context taken from florinsasu's post on the forums */ +struct SceThreadContext { + unsigned int type; + unsigned int gpr[31]; + unsigned int fpr[32]; + unsigned int fc31; + unsigned int hi; + unsigned int lo; + unsigned int SR; + unsigned int EPC; + unsigned int field_114; + unsigned int field_118; +}; + +struct SceSCContext +{ + unsigned int status; + unsigned int epc; + unsigned int sp; + unsigned int ra; + unsigned int k1; + unsigned int unk[3]; +}; + +/** Structure to hold the status information for a thread (kernel form) + * 1.5 form + */ +typedef struct SceKernelThreadKInfo { + /** Size of the structure */ + SceSize size; + /** Nul terminated name of the thread */ + char name[32]; + /** Thread attributes */ + SceUInt attr; + /** Thread status */ + int status; + /** Thread entry point */ + SceKernelThreadEntry entry; + /** Thread stack pointer */ + void * stack; + /** Thread stack size */ + int stackSize; + /** Kernel stack pointer */ + void * kstack; + /** Kernel stack size */ + void * kstackSize; + /** Pointer to the gp */ + void * gpReg; + /** Size of args */ + SceSize args; + /** Pointer to args */ + void * argp; + /** Initial priority */ + int initPriority; + /** Current priority */ + int currentPriority; + /** Wait type */ + int waitType; + /** Wait id */ + SceUID waitId; + /** Wakeup count */ + int wakeupCount; + /** Number of clock cycles run */ + SceKernelSysClock runClocks; +#if _PSP_FW_VERSION >= 200 + SceUInt unk3; /* Unknown extra field on later firmwares */ +#endif + /** Interrupt preemption count */ + SceUInt intrPreemptCount; + /** Thread preemption count */ + SceUInt threadPreemptCount; + /** Release count */ + SceUInt releaseCount; + /** Thread Context */ + struct SceThreadContext *thContext; + /** VFPU Context */ + float * vfpuContext; + /** Return address from syscall */ + void * retAddr; + /** Unknown, possibly size of SC context */ + SceUInt unknown1; + /** Syscall Context */ + struct SceSCContext *scContext; +} SceKernelThreadKInfo; + +/** + * Refer kernel version of thread information + * + * @param uid - UID to find + * @param info - Pointer to info structure, ensure size is set before calling + * + * @return 0 on success + */ +int ThreadManForKernel_2D69D086(SceUID uid, SceKernelThreadKInfo *info); + +#ifdef __cplusplus +} +#endif + +/*@}*/ + +#endif /* PSPTHREADMANKERNEL_H */ diff --git a/src/kernel/psputilsforkernel.h b/src/kernel/psputilsforkernel.h new file mode 100644 index 00000000..83a543e6 --- /dev/null +++ b/src/kernel/psputilsforkernel.h @@ -0,0 +1,80 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * psputilsforkernel.h - Include file for UtilsForKernel + * + * Copyright (c) 2005 John Kelley + * Copyright (c) 2005 adresd + * + * $Id: psputilsforkernel.h 2339 2007-12-06 19:41:18Z raphael $ + */ + +#ifndef __PSPUTILSFORKERNEL_H__ +#define __PSPUTILSFORKERNEL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Decompress gzip'd data (requires kernel mode) + * + * @param dest - pointer to destination buffer + * @param destSize - size of destination buffer + * @param src - pointer to source (compressed) data + * @param unknown - unknown, pass NULL + * @return size decompressed on success, < 0 on error + */ +int sceKernelGzipDecompress(u8 *dest, u32 destSize, const u8 *src, u32 unknown); + +/** + * Decompress deflate'd data (requires kernel mode) + * + * @param dest - pointer to destination buffer + * @param destSize - size of destination buffer + * @param src - pointer to source (compressed) data + * @param unknown - unknown, pass NULL + * @return size decompressed on success, < 0 on error + */ +int sceKernelDeflateDecompress(u8 *dest, u32 destSize, const u8 *src, u32 unknown); + +/** + * Invalidate the entire data cache + */ +void sceKernelDcacheInvalidateAll(void); + +/** + * Check whether the specified address is in the data cache + * @param addr - The address to check + * + * @return 0 = not cached, 1 = cache + */ +int sceKernelDcacheProbe(void *addr); + +/** + * Invalidate the entire instruction cache + */ +void sceKernelIcacheInvalidateAll(void); + +/** + * Invalidate a instruction cache range. + * @param addr - The start address of the range. + * @param size - The size in bytes + */ +void sceKernelIcacheInvalidateRange(const void *addr, unsigned int size); + +/** + * Check whether the specified address is in the instruction cache + * @param addr - The address to check + * + * @return 0 = not cached, 1 = cache + */ +int sceKernelIcacheProbe(const void *addr); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/kernel/sceAudioRouting_driver.S b/src/kernel/sceAudioRouting_driver.S new file mode 100755 index 00000000..26e95971 --- /dev/null +++ b/src/kernel/sceAudioRouting_driver.S @@ -0,0 +1,19 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceAudioRouting_driver_0000 + IMPORT_START "sceAudioRouting_driver",0x00010000 +#endif +#ifdef F_sceAudioRouting_driver_0001 + IMPORT_FUNC "sceAudioRouting_driver",0x28235C56,sceAudioRoutingGetVolumeMode +#endif +#ifdef F_sceAudioRouting_driver_0002 + IMPORT_FUNC "sceAudioRouting_driver",0x36FD8AA9,sceAudioRoutingSetMode +#endif +#ifdef F_sceAudioRouting_driver_0003 + IMPORT_FUNC "sceAudioRouting_driver",0x39240E7D,sceAudioRoutingGetMode +#endif +#ifdef F_sceAudioRouting_driver_0004 + IMPORT_FUNC "sceAudioRouting_driver",0xBB548475,sceAudioRoutingSetVolumeMode +#endif diff --git a/src/kernel/sceIdStorage_driver.S b/src/kernel/sceIdStorage_driver.S new file mode 100644 index 00000000..17547464 --- /dev/null +++ b/src/kernel/sceIdStorage_driver.S @@ -0,0 +1,67 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceIdStorage_driver_0000 + IMPORT_START "sceIdStorage_driver",0x00010000 +#endif +#ifdef F_sceIdStorage_driver_0001 + IMPORT_FUNC "sceIdStorage_driver",0xAB129D20,sceIdStorageInit +#endif +#ifdef F_sceIdStorage_driver_0002 + IMPORT_FUNC "sceIdStorage_driver",0x2CE0BE69,sceIdStorageEnd +#endif +#ifdef F_sceIdStorage_driver_0003 + IMPORT_FUNC "sceIdStorage_driver",0xF77565B6,sceIdStorageSuspend +#endif +#ifdef F_sceIdStorage_driver_0004 + IMPORT_FUNC "sceIdStorage_driver",0xFE51173D,sceIdStorageResume +#endif +#ifdef F_sceIdStorage_driver_0005 + IMPORT_FUNC "sceIdStorage_driver",0xEB830733,sceIdStorageGetLeafSize +#endif +#ifdef F_sceIdStorage_driver_0006 + IMPORT_FUNC "sceIdStorage_driver",0xFEFA40C2,sceIdStorageIsFormatted +#endif +#ifdef F_sceIdStorage_driver_0007 + IMPORT_FUNC "sceIdStorage_driver",0x2D633688,sceIdStorageIsReadOnly +#endif +#ifdef F_sceIdStorage_driver_0008 + IMPORT_FUNC "sceIdStorage_driver",0xB9069BAD,sceIdStorageIsDirty +#endif +#ifdef F_sceIdStorage_driver_0009 + IMPORT_FUNC "sceIdStorage_driver",0x958089DB,sceIdStorageFormat +#endif +#ifdef F_sceIdStorage_driver_0010 + IMPORT_FUNC "sceIdStorage_driver",0xF4BCB3EE,sceIdStorageUnformat +#endif +#ifdef F_sceIdStorage_driver_0011 + IMPORT_FUNC "sceIdStorage_driver",0xEB00C509,sceIdStorageReadLeaf +#endif +#ifdef F_sceIdStorage_driver_0012 + IMPORT_FUNC "sceIdStorage_driver",0x1FA4D135,sceIdStorageWriteLeaf +#endif +#ifdef F_sceIdStorage_driver_0013 + IMPORT_FUNC "sceIdStorage_driver",0x08A471A6,sceIdStorageCreateLeaf +#endif +#ifdef F_sceIdStorage_driver_0014 + IMPORT_FUNC "sceIdStorage_driver",0x2C97AB36,sceIdStorageDeleteLeaf +#endif +#ifdef F_sceIdStorage_driver_0015 + IMPORT_FUNC "sceIdStorage_driver",0x99ACCB71,sceIdStorage_driver_99ACCB71 +#endif +#ifdef F_sceIdStorage_driver_0016 + IMPORT_FUNC "sceIdStorage_driver",0x37833CB8,sceIdStorage_driver_37833CB8 +#endif +#ifdef F_sceIdStorage_driver_0017 + IMPORT_FUNC "sceIdStorage_driver",0x31E08AFB,sceIdStorageEnumId +#endif +#ifdef F_sceIdStorage_driver_0018 + IMPORT_FUNC "sceIdStorage_driver",0x6FE062D1,sceIdStorageLookup +#endif +#ifdef F_sceIdStorage_driver_0019 + IMPORT_FUNC "sceIdStorage_driver",0x683AAC10,sceIdStorageUpdate +#endif +#ifdef F_sceIdStorage_driver_0020 + IMPORT_FUNC "sceIdStorage_driver",0x3AD32523,sceIdStorageFlush +#endif diff --git a/src/kernel/sceImpose_driver.S b/src/kernel/sceImpose_driver.S new file mode 100644 index 00000000..634ea6e8 --- /dev/null +++ b/src/kernel/sceImpose_driver.S @@ -0,0 +1,76 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceImpose_driver_0000 + IMPORT_START "sceImpose_driver",0x00010011 +#endif +#ifdef F_sceImpose_driver_0001 + IMPORT_FUNC "sceImpose_driver",0x0F341BE4,sceImposeGetHomePopup +#endif +#ifdef F_sceImpose_driver_0002 + IMPORT_FUNC "sceImpose_driver",0x116CFF64,sceImposeCheckVideoOut +#endif +#ifdef F_sceImpose_driver_0003 + IMPORT_FUNC "sceImpose_driver",0x116DDED6,sceImposeSetVideoOutMode +#endif +#ifdef F_sceImpose_driver_0004 + IMPORT_FUNC "sceImpose_driver",0x1AEED8FE,sceImposeSuspend +#endif +#ifdef F_sceImpose_driver_0005 + IMPORT_FUNC "sceImpose_driver",0x1B6E3400,sceImposeGetStatus +#endif +#ifdef F_sceImpose_driver_0006 + IMPORT_FUNC "sceImpose_driver",0x24FD7BCF,sceImposeGetLanguageMode +#endif +#ifdef F_sceImpose_driver_0007 + IMPORT_FUNC "sceImpose_driver",0x36AA6E91,sceImposeSetLanguageMode +#endif +#ifdef F_sceImpose_driver_0008 + IMPORT_FUNC "sceImpose_driver",0x381BD9E7,sceImposeHomeButton +#endif +#ifdef F_sceImpose_driver_0009 + IMPORT_FUNC "sceImpose_driver",0x531C9778,sceImposeGetParam +#endif +#ifdef F_sceImpose_driver_0010 + IMPORT_FUNC "sceImpose_driver",0x5595A71A,sceImposeSetHomePopup +#endif +#ifdef F_sceImpose_driver_0011 + IMPORT_FUNC "sceImpose_driver",0x7084E72C,sceImpose_driver_7084E72C +#endif +#ifdef F_sceImpose_driver_0012 + IMPORT_FUNC "sceImpose_driver",0x72189C48,sceImposeSetUMDPopup +#endif +#ifdef F_sceImpose_driver_0013 + IMPORT_FUNC "sceImpose_driver",0x810FB7FB,sceImposeSetParam +#endif +#ifdef F_sceImpose_driver_0014 + IMPORT_FUNC "sceImpose_driver",0x86924032,sceImposeResume +#endif +#ifdef F_sceImpose_driver_0015 + IMPORT_FUNC "sceImpose_driver",0x8C943191,sceImposeGetBatteryIconStatus +#endif +#ifdef F_sceImpose_driver_0016 + IMPORT_FUNC "sceImpose_driver",0x8F6E3518,sceImposeGetBacklightOffTime +#endif +#ifdef F_sceImpose_driver_0017 + IMPORT_FUNC "sceImpose_driver",0x967F6D4A,sceImposeSetBacklightOffTime +#endif +#ifdef F_sceImpose_driver_0018 + IMPORT_FUNC "sceImpose_driver",0x9C8C6C81,sceImposeSetStatus +#endif +#ifdef F_sceImpose_driver_0019 + IMPORT_FUNC "sceImpose_driver",0x9DBCE0C4,sceImpose_driver_9DBCE0C4 +#endif +#ifdef F_sceImpose_driver_0020 + IMPORT_FUNC "sceImpose_driver",0xB415FC59,sceImposeChanges +#endif +#ifdef F_sceImpose_driver_0021 + IMPORT_FUNC "sceImpose_driver",0xBDBC42A6,sceImposeInit +#endif +#ifdef F_sceImpose_driver_0022 + IMPORT_FUNC "sceImpose_driver",0xC7E36CC7,sceImposeEnd +#endif +#ifdef F_sceImpose_driver_0023 + IMPORT_FUNC "sceImpose_driver",0xE0887BC8,sceImposeGetUMDPopup +#endif diff --git a/src/kernel/sceSysEventForKernel.S b/src/kernel/sceSysEventForKernel.S new file mode 100644 index 00000000..80222432 --- /dev/null +++ b/src/kernel/sceSysEventForKernel.S @@ -0,0 +1,22 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceSysEventForKernel_0000 + IMPORT_START "sceSysEventForKernel",0x00010000 +#endif +#ifdef F_sceSysEventForKernel_0001 + IMPORT_FUNC "sceSysEventForKernel",0xAEB300AE,sceKernelIsRegisterSysEventHandler +#endif +#ifdef F_sceSysEventForKernel_0002 + IMPORT_FUNC "sceSysEventForKernel",0xCD9E4BB5,sceKernelRegisterSysEventHandler +#endif +#ifdef F_sceSysEventForKernel_0003 + IMPORT_FUNC "sceSysEventForKernel",0xD7D3FDCD,sceKernelUnregisterSysEventHandler +#endif +#ifdef F_sceSysEventForKernel_0004 + IMPORT_FUNC "sceSysEventForKernel",0x36331294,sceKernelSysEventDispatch +#endif +#ifdef F_sceSysEventForKernel_0005 + IMPORT_FUNC "sceSysEventForKernel",0x68D55505,sceKernelReferSysEventHandler +#endif diff --git a/src/kernel/sceSyscon_driver.S b/src/kernel/sceSyscon_driver.S new file mode 100644 index 00000000..836f3c69 --- /dev/null +++ b/src/kernel/sceSyscon_driver.S @@ -0,0 +1,346 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceSyscon_driver_0000 + IMPORT_START "sceSyscon_driver",0x00010000 +#endif +#ifdef F_sceSyscon_driver_0001 + IMPORT_FUNC "sceSyscon_driver",0x0A771482,sceSysconInit +#endif +#ifdef F_sceSyscon_driver_0002 + IMPORT_FUNC "sceSyscon_driver",0x92D16FC7,sceSysconEnd +#endif +#ifdef F_sceSyscon_driver_0003 + IMPORT_FUNC "sceSyscon_driver",0x081826B4,sceSysconSuspend +#endif +#ifdef F_sceSyscon_driver_0004 + IMPORT_FUNC "sceSyscon_driver",0x56931095,sceSysconResume +#endif +#ifdef F_sceSyscon_driver_0005 + IMPORT_FUNC "sceSyscon_driver",0x5EE92F3C,sceSyscon_driver_5EE92F3C +#endif +#ifdef F_sceSyscon_driver_0006 + IMPORT_FUNC "sceSyscon_driver",0x5FF1D610,sceSyscon_driver_5FF1D610 +#endif +#ifdef F_sceSyscon_driver_0007 + IMPORT_FUNC "sceSyscon_driver",0xAD555CE5,sceSyscon_driver_AD555CE5 +#endif +#ifdef F_sceSyscon_driver_0008 + IMPORT_FUNC "sceSyscon_driver",0xF281805D,sceSyscon_driver_F281805D +#endif +#ifdef F_sceSyscon_driver_0009 + IMPORT_FUNC "sceSyscon_driver",0xA068B3D0,sceSysconSetAlarmCallback +#endif +#ifdef F_sceSyscon_driver_0010 + IMPORT_FUNC "sceSyscon_driver",0xE540E532,sceSyscon_driver_E540E532 +#endif +#ifdef F_sceSyscon_driver_0011 + IMPORT_FUNC "sceSyscon_driver",0xBBFB70C0,sceSyscon_driver_BBFB70C0 +#endif +#ifdef F_sceSyscon_driver_0012 + IMPORT_FUNC "sceSyscon_driver",0x805180D1,sceSyscon_driver_805180D1 +#endif +#ifdef F_sceSyscon_driver_0013 + IMPORT_FUNC "sceSyscon_driver",0x53072985,sceSyscon_driver_53072985 +#endif +#ifdef F_sceSyscon_driver_0014 + IMPORT_FUNC "sceSyscon_driver",0xF9193EC3,sceSyscon_driver_F9193EC3 +#endif +#ifdef F_sceSyscon_driver_0015 + IMPORT_FUNC "sceSyscon_driver",0x7479DB05,sceSyscon_driver_7479DB05 +#endif +#ifdef F_sceSyscon_driver_0016 + IMPORT_FUNC "sceSyscon_driver",0x6848D817,sceSyscon_driver_6848D817 +#endif +#ifdef F_sceSyscon_driver_0017 + IMPORT_FUNC "sceSyscon_driver",0x5B9ACC97,sceSysconCmdExec +#endif +#ifdef F_sceSyscon_driver_0018 + IMPORT_FUNC "sceSyscon_driver",0x3AC3D2A4,sceSysconCmdExecAsync +#endif +#ifdef F_sceSyscon_driver_0019 + IMPORT_FUNC "sceSyscon_driver",0x1602ED0D,sceSysconCmdCancel +#endif +#ifdef F_sceSyscon_driver_0020 + IMPORT_FUNC "sceSyscon_driver",0xF350F666,sceSysconCmdSync +#endif +#ifdef F_sceSyscon_driver_0021 + IMPORT_FUNC "sceSyscon_driver",0x86D4CAD8,sceSyscon_driver_86D4CAD8 +#endif +#ifdef F_sceSyscon_driver_0022 + IMPORT_FUNC "sceSyscon_driver",0x32CFD20F,sceSysconIsLowBattery +#endif +#ifdef F_sceSyscon_driver_0023 + IMPORT_FUNC "sceSyscon_driver",0xEC0DE439,sceSysconGetPowerSwitch +#endif +#ifdef F_sceSyscon_driver_0024 + IMPORT_FUNC "sceSyscon_driver",0xEA5B9823,sceSyscon_driver_EA5B9823 +#endif +#ifdef F_sceSyscon_driver_0025 + IMPORT_FUNC "sceSyscon_driver",0xE20D08FE,sceSyscon_driver_E20D08FE +#endif +#ifdef F_sceSyscon_driver_0026 + IMPORT_FUNC "sceSyscon_driver",0xE0DDFE18,sceSysconGetHPConnect +#endif +#ifdef F_sceSyscon_driver_0027 + IMPORT_FUNC "sceSyscon_driver",0xBDA16E46,sceSysconGetWlanSwitch +#endif +#ifdef F_sceSyscon_driver_0028 + IMPORT_FUNC "sceSyscon_driver",0xF6BB4649,sceSysconGetHoldSwitch +#endif +#ifdef F_sceSyscon_driver_0029 + IMPORT_FUNC "sceSyscon_driver",0x138747DE,sceSysconGetUmdSwitch +#endif +#ifdef F_sceSyscon_driver_0030 + IMPORT_FUNC "sceSyscon_driver",0x71AE1BCE,sceSyscon_driver_71AE1BCE +#endif +#ifdef F_sceSyscon_driver_0031 + IMPORT_FUNC "sceSyscon_driver",0x7016161C,sceSysconGetWlanPowerStatus +#endif +#ifdef F_sceSyscon_driver_0032 + IMPORT_FUNC "sceSyscon_driver",0x48AB0E44,sceSysconGetLeptonPowerCtrl +#endif +#ifdef F_sceSyscon_driver_0033 + IMPORT_FUNC "sceSyscon_driver",0x628F2351,sceSysconGetMsPowerCtrl +#endif +#ifdef F_sceSyscon_driver_0034 + IMPORT_FUNC "sceSyscon_driver",0x3C739F57,sceSyscon_driver_3C739F57 +#endif +#ifdef F_sceSyscon_driver_0035 + IMPORT_FUNC "sceSyscon_driver",0xEC37C549,sceSysconGetWlanPowerCtrl +#endif +#ifdef F_sceSyscon_driver_0036 + IMPORT_FUNC "sceSyscon_driver",0x8DDA4CA6,sceSyscon_driver_8DDA4CA6 +#endif +#ifdef F_sceSyscon_driver_0037 + IMPORT_FUNC "sceSyscon_driver",0x52B74B6C,sceSyscon_driver_52B74B6C +#endif +#ifdef F_sceSyscon_driver_0038 + IMPORT_FUNC "sceSyscon_driver",0x1B17D3E3,sceSyscon_driver_1B17D3E3 +#endif +#ifdef F_sceSyscon_driver_0039 + IMPORT_FUNC "sceSyscon_driver",0x5F19C00F,sceSyscon_driver_5F19C00F +#endif +#ifdef F_sceSyscon_driver_0040 + IMPORT_FUNC "sceSyscon_driver",0xCC04A978,sceSysconGetWlanLedCtrl +#endif +#ifdef F_sceSyscon_driver_0041 + IMPORT_FUNC "sceSyscon_driver",0xE6B74CB9,sceSysconNop +#endif +#ifdef F_sceSyscon_driver_0042 + IMPORT_FUNC "sceSyscon_driver",0x7EC5A957,sceSyscon_driver_7EC5A957 +#endif +#ifdef F_sceSyscon_driver_0043 + IMPORT_FUNC "sceSyscon_driver",0x7BCC5EAE,sceSyscon_driver_7BCC5EAE +#endif +#ifdef F_sceSyscon_driver_0044 + IMPORT_FUNC "sceSyscon_driver",0x3B657A27,sceSyscon_driver_3B657A27 +#endif +#ifdef F_sceSyscon_driver_0045 + IMPORT_FUNC "sceSyscon_driver",0xFC32141A,sceSyscon_driver_FC32141A +#endif +#ifdef F_sceSyscon_driver_0046 + IMPORT_FUNC "sceSyscon_driver",0xF775BC34,sceSyscon_driver_F775BC34 +#endif +#ifdef F_sceSyscon_driver_0047 + IMPORT_FUNC "sceSyscon_driver",0xA9AEF39F,sceSyscon_driver_A9AEF39F +#endif +#ifdef F_sceSyscon_driver_0048 + IMPORT_FUNC "sceSyscon_driver",0xC4D66C1D,sceSysconReadClock +#endif +#ifdef F_sceSyscon_driver_0049 + IMPORT_FUNC "sceSyscon_driver",0xC7634A7A,sceSysconWriteClock +#endif +#ifdef F_sceSyscon_driver_0050 + IMPORT_FUNC "sceSyscon_driver",0x7A805EE4,sceSysconReadAlarm +#endif +#ifdef F_sceSyscon_driver_0051 + IMPORT_FUNC "sceSyscon_driver",0x6C911742,sceSysconWriteAlarm +#endif +#ifdef F_sceSyscon_driver_0052 + IMPORT_FUNC "sceSyscon_driver",0x65EB6096,sceSyscon_driver_65EB6096 +#endif +#ifdef F_sceSyscon_driver_0053 + IMPORT_FUNC "sceSyscon_driver",0xEB277C88,sceSyscon_driver_EB277C88 +#endif +#ifdef F_sceSyscon_driver_0054 + IMPORT_FUNC "sceSyscon_driver",0x992C22C2,sceSysconSendSetParam +#endif +#ifdef F_sceSyscon_driver_0055 + IMPORT_FUNC "sceSyscon_driver",0x08234E6D,sceSysconReceiveSetParam +#endif +#ifdef F_sceSyscon_driver_0056 + IMPORT_FUNC "sceSyscon_driver",0x882F0AAB,sceSyscon_driver_882F0AAB +#endif +#ifdef F_sceSyscon_driver_0057 + IMPORT_FUNC "sceSyscon_driver",0x2EE82492,sceSyscon_driver_2EE82492 +#endif +#ifdef F_sceSyscon_driver_0058 + IMPORT_FUNC "sceSyscon_driver",0x8CBC7987,sceSysconResetDevice +#endif +#ifdef F_sceSyscon_driver_0059 + IMPORT_FUNC "sceSyscon_driver",0x00E7B6C2,sceSyscon_driver_00E7B6C2 +#endif +#ifdef F_sceSyscon_driver_0060 + IMPORT_FUNC "sceSyscon_driver",0x44439604,sceSysconCtrlHRPower +#endif +#ifdef F_sceSyscon_driver_0061 + IMPORT_FUNC "sceSyscon_driver",0xC8439C57,sceSysconPowerStandby +#endif +#ifdef F_sceSyscon_driver_0062 + IMPORT_FUNC "sceSyscon_driver",0x91E183CB,sceSysconPowerSuspend +#endif +#ifdef F_sceSyscon_driver_0063 + IMPORT_FUNC "sceSyscon_driver",0xE7E87741,sceSyscon_driver_E7E87741 +#endif +#ifdef F_sceSyscon_driver_0064 + IMPORT_FUNC "sceSyscon_driver",0xFB148FB6,sceSyscon_driver_FB148FB6 +#endif +#ifdef F_sceSyscon_driver_0065 + IMPORT_FUNC "sceSyscon_driver",0x01677F91,sceSyscon_driver_01677F91 +#endif +#ifdef F_sceSyscon_driver_0066 + IMPORT_FUNC "sceSyscon_driver",0xBE27FE66,sceSysconCtrlPower +#endif +#ifdef F_sceSyscon_driver_0067 + IMPORT_FUNC "sceSyscon_driver",0x09721F7F,sceSysconGetPowerStatus +#endif +#ifdef F_sceSyscon_driver_0068 + IMPORT_FUNC "sceSyscon_driver",0x18BFBE65,sceSysconCtrlLED +#endif +#ifdef F_sceSyscon_driver_0069 + IMPORT_FUNC "sceSyscon_driver",0xD1B501E8,sceSyscon_driver_D1B501E8 +#endif +#ifdef F_sceSyscon_driver_0070 + IMPORT_FUNC "sceSyscon_driver",0x3DE38336,sceSyscon_driver_3DE38336 +#endif +#ifdef F_sceSyscon_driver_0071 + IMPORT_FUNC "sceSyscon_driver",0x2B9E6A06,sceSysconGetPowerError +#endif +#ifdef F_sceSyscon_driver_0072 + IMPORT_FUNC "sceSyscon_driver",0x8A4519F5,sceSysconCtrlLeptonPower +#endif +#ifdef F_sceSyscon_driver_0073 + IMPORT_FUNC "sceSyscon_driver",0x99BBB24C,sceSysconCtrlMsPower +#endif +#ifdef F_sceSyscon_driver_0074 + IMPORT_FUNC "sceSyscon_driver",0xF0ED3255,sceSysconCtrlWlanPower +#endif +#ifdef F_sceSyscon_driver_0075 + IMPORT_FUNC "sceSyscon_driver",0x3C6DB1C5,sceSyscon_driver_3C6DB1C5 +#endif +#ifdef F_sceSyscon_driver_0076 + IMPORT_FUNC "sceSyscon_driver",0xB2558E37,sceSyscon_driver_B2558E37 +#endif +#ifdef F_sceSyscon_driver_0077 + IMPORT_FUNC "sceSyscon_driver",0xE5E35721,sceSyscon_driver_E5E35721 +#endif +#ifdef F_sceSyscon_driver_0078 + IMPORT_FUNC "sceSyscon_driver",0x9478F399,sceSyscon_driver_9478F399 +#endif +#ifdef F_sceSyscon_driver_0079 + IMPORT_FUNC "sceSyscon_driver",0x806D4D6C,sceSyscon_driver_806D4D6C +#endif +#ifdef F_sceSyscon_driver_0080 + IMPORT_FUNC "sceSyscon_driver",0xD8471760,sceSyscon_driver_D8471760 +#endif +#ifdef F_sceSyscon_driver_0081 + IMPORT_FUNC "sceSyscon_driver",0xEAB13FBE,sceSyscon_driver_EAB13FBE +#endif +#ifdef F_sceSyscon_driver_0082 + IMPORT_FUNC "sceSyscon_driver",0xC5075828,sceSyscon_driver_C5075828 +#endif +#ifdef F_sceSyscon_driver_0083 + IMPORT_FUNC "sceSyscon_driver",0xE448FD3F,sceSysconBatteryNop +#endif +#ifdef F_sceSyscon_driver_0084 + IMPORT_FUNC "sceSyscon_driver",0x6A53F3F8,sceSysconBatteryGetStatusCap +#endif +#ifdef F_sceSyscon_driver_0085 + IMPORT_FUNC "sceSyscon_driver",0x70C10E61,sceSysconBatteryGetTemp +#endif +#ifdef F_sceSyscon_driver_0086 + IMPORT_FUNC "sceSyscon_driver",0x8BDEBB1E,sceSysconBatteryGetVolt +#endif +#ifdef F_sceSyscon_driver_0087 + IMPORT_FUNC "sceSyscon_driver",0x373EC933,sceSysconBatteryGetElec +#endif +#ifdef F_sceSyscon_driver_0088 + IMPORT_FUNC "sceSyscon_driver",0x82861DE2,sceSyscon_driver_82861DE2 +#endif +#ifdef F_sceSyscon_driver_0089 + IMPORT_FUNC "sceSyscon_driver",0x876CA580,sceSysconBatteryGetCap +#endif +#ifdef F_sceSyscon_driver_0090 + IMPORT_FUNC "sceSyscon_driver",0x71135D7D,sceSyscon_driver_71135D7D +#endif +#ifdef F_sceSyscon_driver_0091 + IMPORT_FUNC "sceSyscon_driver",0x7CBD4522,sceSyscon_driver_7CBD4522 +#endif +#ifdef F_sceSyscon_driver_0092 + IMPORT_FUNC "sceSyscon_driver",0x284FE366,sceSyscon_driver_284FE366 +#endif +#ifdef F_sceSyscon_driver_0093 + IMPORT_FUNC "sceSyscon_driver",0x75025299,sceSysconBatteryGetStatus +#endif +#ifdef F_sceSyscon_driver_0094 + IMPORT_FUNC "sceSyscon_driver",0xB5105D51,sceSysconBatteryGetCycle +#endif +#ifdef F_sceSyscon_driver_0095 + IMPORT_FUNC "sceSyscon_driver",0xD5340103,sceSysconBatteryGetSerial +#endif +#ifdef F_sceSyscon_driver_0096 + IMPORT_FUNC "sceSyscon_driver",0xFA4C4518,sceSysconBatteryGetInfo +#endif +#ifdef F_sceSyscon_driver_0097 + IMPORT_FUNC "sceSyscon_driver",0xB71B98A8,sceSyscon_driver_B71B98A8 +#endif +#ifdef F_sceSyscon_driver_0098 + IMPORT_FUNC "sceSyscon_driver",0x87671B18,sceSyscon_driver_87671B18 +#endif +#ifdef F_sceSyscon_driver_0099 + IMPORT_FUNC "sceSyscon_driver",0x75D22BF8,sceSyscon_driver_75D22BF8 +#endif +#ifdef F_sceSyscon_driver_0100 + IMPORT_FUNC "sceSyscon_driver",0x4C539345,sceSyscon_driver_4C539345 +#endif +#ifdef F_sceSyscon_driver_0101 + IMPORT_FUNC "sceSyscon_driver",0x4C0EE2FA,sceSyscon_driver_4C0EE2FA +#endif +#ifdef F_sceSyscon_driver_0102 + IMPORT_FUNC "sceSyscon_driver",0x1165C864,sceSyscon_driver_1165C864 +#endif +#ifdef F_sceSyscon_driver_0103 + IMPORT_FUNC "sceSyscon_driver",0x68EF0BEF,sceSyscon_driver_68EF0BEF +#endif +#ifdef F_sceSyscon_driver_0104 + IMPORT_FUNC "sceSyscon_driver",0x36E28C5F,sceSysconBatteryAuth +#endif +#ifdef F_sceSyscon_driver_0105 + IMPORT_FUNC "sceSyscon_driver",0x08DA3752,sceSyscon_driver_08DA3752 +#endif +#ifdef F_sceSyscon_driver_0106 + IMPORT_FUNC "sceSyscon_driver",0x9C4E3CA9,sceSyscon_driver_9C4E3CA9 +#endif +#ifdef F_sceSyscon_driver_0107 + IMPORT_FUNC "sceSyscon_driver",0x34C36FF9,sceSyscon_driver_34C36FF9 +#endif +#ifdef F_sceSyscon_driver_0108 + IMPORT_FUNC "sceSyscon_driver",0xB8919D79,sceSysconMsOn +#endif +#ifdef F_sceSyscon_driver_0109 + IMPORT_FUNC "sceSyscon_driver",0x7BE86143,sceSysconMsOff +#endif +#ifdef F_sceSyscon_driver_0110 + IMPORT_FUNC "sceSyscon_driver",0x0E8560F9,sceSysconWlanOn +#endif +#ifdef F_sceSyscon_driver_0111 + IMPORT_FUNC "sceSyscon_driver",0x1B60C8AD,sceSysconWlanOff +#endif +#ifdef F_sceSyscon_driver_0112 + IMPORT_FUNC "sceSyscon_driver",0xE00BFC9E,sceSyscon_driver_E00BFC9E +#endif +#ifdef F_sceSyscon_driver_0113 + IMPORT_FUNC "sceSyscon_driver",0xC8D97773,sceSyscon_driver_C8D97773 +#endif diff --git a/src/kernel/sceSysreg_driver.S b/src/kernel/sceSysreg_driver.S new file mode 100644 index 00000000..dc08e06f --- /dev/null +++ b/src/kernel/sceSysreg_driver.S @@ -0,0 +1,460 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceSysreg_driver_0000 + IMPORT_START "sceSysreg_driver",0x00010000 +#endif +#ifdef F_sceSysreg_driver_0001 + IMPORT_FUNC "sceSysreg_driver",0x9C863542,sceSysregInit +#endif +#ifdef F_sceSysreg_driver_0002 + IMPORT_FUNC "sceSysreg_driver",0xF2DEAA14,sceSysregEnd +#endif +#ifdef F_sceSysreg_driver_0003 + IMPORT_FUNC "sceSysreg_driver",0xE88B77ED,sceSysreg_driver_E88B77ED +#endif +#ifdef F_sceSysreg_driver_0004 + IMPORT_FUNC "sceSysreg_driver",0xCD0F6715,sceSysreg_driver_CD0F6715 +#endif +#ifdef F_sceSysreg_driver_0005 + IMPORT_FUNC "sceSysreg_driver",0x844AF6BD,sceSysreg_driver_844AF6BD +#endif +#ifdef F_sceSysreg_driver_0006 + IMPORT_FUNC "sceSysreg_driver",0xE2A5D1EE,sceSysreg_driver_E2A5D1EE +#endif +#ifdef F_sceSysreg_driver_0007 + IMPORT_FUNC "sceSysreg_driver",0x4F46EEDE,sceSysreg_driver_4F46EEDE +#endif +#ifdef F_sceSysreg_driver_0008 + IMPORT_FUNC "sceSysreg_driver",0x8F4F4E96,sceSysreg_driver_8F4F4E96 +#endif +#ifdef F_sceSysreg_driver_0009 + IMPORT_FUNC "sceSysreg_driver",0xC29D614E,sceSysregTopResetEnable +#endif +#ifdef F_sceSysreg_driver_0010 + IMPORT_FUNC "sceSysreg_driver",0xDC6139A4,sceSysregScResetEnable +#endif +#ifdef F_sceSysreg_driver_0011 + IMPORT_FUNC "sceSysreg_driver",0xDE59DACB,sceSysregMeResetEnable +#endif +#ifdef F_sceSysreg_driver_0012 + IMPORT_FUNC "sceSysreg_driver",0x2DB0EB28,sceSysregMeResetDisable +#endif +#ifdef F_sceSysreg_driver_0013 + IMPORT_FUNC "sceSysreg_driver",0x26283A6F,sceSysregAwResetEnable +#endif +#ifdef F_sceSysreg_driver_0014 + IMPORT_FUNC "sceSysreg_driver",0xA374195E,sceSysregAwResetDisable +#endif +#ifdef F_sceSysreg_driver_0015 + IMPORT_FUNC "sceSysreg_driver",0xD20581EA,sceSysregVmeResetEnable +#endif +#ifdef F_sceSysreg_driver_0016 + IMPORT_FUNC "sceSysreg_driver",0x7558064A,sceSysregVmeResetDisable +#endif +#ifdef F_sceSysreg_driver_0017 + IMPORT_FUNC "sceSysreg_driver",0x9BB70D34,sceSysregAvcResetEnable +#endif +#ifdef F_sceSysreg_driver_0018 + IMPORT_FUNC "sceSysreg_driver",0xFD6C562B,sceSysregAvcResetDisable +#endif +#ifdef F_sceSysreg_driver_0019 + IMPORT_FUNC "sceSysreg_driver",0xCD4FB614,sceSysregUsbResetEnable +#endif +#ifdef F_sceSysreg_driver_0020 + IMPORT_FUNC "sceSysreg_driver",0x69EECBE5,sceSysregUsbResetDisable +#endif +#ifdef F_sceSysreg_driver_0021 + IMPORT_FUNC "sceSysreg_driver",0xF5B80837,sceSysregAtaResetEnable +#endif +#ifdef F_sceSysreg_driver_0022 + IMPORT_FUNC "sceSysreg_driver",0x8075303F,sceSysregAtaResetDisable +#endif +#ifdef F_sceSysreg_driver_0023 + IMPORT_FUNC "sceSysreg_driver",0x00C2628E,sceSysregMsifResetEnable +#endif +#ifdef F_sceSysreg_driver_0024 + IMPORT_FUNC "sceSysreg_driver",0xEC4BF81F,sceSysregMsifResetDisable +#endif +#ifdef F_sceSysreg_driver_0025 + IMPORT_FUNC "sceSysreg_driver",0x8A7F9EB4,sceSysregKirkResetEnable +#endif +#ifdef F_sceSysreg_driver_0026 + IMPORT_FUNC "sceSysreg_driver",0xC32F2491,sceSysregKirkResetDisable +#endif +#ifdef F_sceSysreg_driver_0027 + IMPORT_FUNC "sceSysreg_driver",0xB21B6CBF,sceSysreg_driver_B21B6CBF +#endif +#ifdef F_sceSysreg_driver_0028 + IMPORT_FUNC "sceSysreg_driver",0xBB3623DF,sceSysreg_driver_BB3623DF +#endif +#ifdef F_sceSysreg_driver_0029 + IMPORT_FUNC "sceSysreg_driver",0x53A6838B,sceSysreg_driver_53A6838B +#endif +#ifdef F_sceSysreg_driver_0030 + IMPORT_FUNC "sceSysreg_driver",0xB4560C45,sceSysreg_driver_B4560C45 +#endif +#ifdef F_sceSysreg_driver_0031 + IMPORT_FUNC "sceSysreg_driver",0xDCA57573,sceSysreg_driver_DCA57573 +#endif +#ifdef F_sceSysreg_driver_0032 + IMPORT_FUNC "sceSysreg_driver",0x44F6CDA7,sceSysregMeBusClockEnable +#endif +#ifdef F_sceSysreg_driver_0033 + IMPORT_FUNC "sceSysreg_driver",0x158AD4FC,sceSysregMeBusClockDisable +#endif +#ifdef F_sceSysreg_driver_0034 + IMPORT_FUNC "sceSysreg_driver",0x4D4CE2B8,sceSysreg_driver_4D4CE2B8 +#endif +#ifdef F_sceSysreg_driver_0035 + IMPORT_FUNC "sceSysreg_driver",0x789BD609,sceSysreg_driver_789BD609 +#endif +#ifdef F_sceSysreg_driver_0036 + IMPORT_FUNC "sceSysreg_driver",0x391CE1C0,sceSysreg_driver_391CE1C0 +#endif +#ifdef F_sceSysreg_driver_0037 + IMPORT_FUNC "sceSysreg_driver",0x82D35024,sceSysreg_driver_82D35024 +#endif +#ifdef F_sceSysreg_driver_0038 + IMPORT_FUNC "sceSysreg_driver",0xAF904657,sceSysreg_driver_AF904657 +#endif +#ifdef F_sceSysreg_driver_0039 + IMPORT_FUNC "sceSysreg_driver",0x438AECE9,sceSysreg_driver_438AECE9 +#endif +#ifdef F_sceSysreg_driver_0040 + IMPORT_FUNC "sceSysreg_driver",0x678AD3ED,sceSysregDmacplusBusClockEnable +#endif +#ifdef F_sceSysreg_driver_0041 + IMPORT_FUNC "sceSysreg_driver",0x168C09B8,sceSysregDmacplusBusClockDisable +#endif +#ifdef F_sceSysreg_driver_0042 + IMPORT_FUNC "sceSysreg_driver",0x7E7EBC20,sceSysregDmacBusClockEnable +#endif +#ifdef F_sceSysreg_driver_0043 + IMPORT_FUNC "sceSysreg_driver",0xA265C719,sceSysregDmacBusClockDisable +#endif +#ifdef F_sceSysreg_driver_0044 + IMPORT_FUNC "sceSysreg_driver",0x4F5AFBBE,sceSysregKirkBusClockEnable +#endif +#ifdef F_sceSysreg_driver_0045 + IMPORT_FUNC "sceSysreg_driver",0x845DD1A6,sceSysregKirkBusClockDisable +#endif +#ifdef F_sceSysreg_driver_0046 + IMPORT_FUNC "sceSysreg_driver",0x16909002,sceSysregAtaBusClockEnable +#endif +#ifdef F_sceSysreg_driver_0047 + IMPORT_FUNC "sceSysreg_driver",0xB6C10DF0,sceSysregAtaBusClockDisable +#endif +#ifdef F_sceSysreg_driver_0048 + IMPORT_FUNC "sceSysreg_driver",0x3E216017,sceSysregUsbBusClockEnable +#endif +#ifdef F_sceSysreg_driver_0049 + IMPORT_FUNC "sceSysreg_driver",0xBFBABB63,sceSysregUsbBusClockDisable +#endif +#ifdef F_sceSysreg_driver_0050 + IMPORT_FUNC "sceSysreg_driver",0x4716E71E,sceSysregMsifBusClockEnable +#endif +#ifdef F_sceSysreg_driver_0051 + IMPORT_FUNC "sceSysreg_driver",0x826430C0,sceSysregMsifBusClockDisable +#endif +#ifdef F_sceSysreg_driver_0052 + IMPORT_FUNC "sceSysreg_driver",0x7CC6CBFD,sceSysreg_driver_7CC6CBFD +#endif +#ifdef F_sceSysreg_driver_0053 + IMPORT_FUNC "sceSysreg_driver",0xEE6B9411,sceSysreg_driver_EE6B9411 +#endif +#ifdef F_sceSysreg_driver_0054 + IMPORT_FUNC "sceSysreg_driver",0xF97D9D73,sceSysregEmcsmBusClockEnable +#endif +#ifdef F_sceSysreg_driver_0055 + IMPORT_FUNC "sceSysreg_driver",0x2D0F7755,sceSysregEmcsmBusClockDisable +#endif +#ifdef F_sceSysreg_driver_0056 + IMPORT_FUNC "sceSysreg_driver",0x63B9EB65,sceSysreg_driver_63B9EB65 +#endif +#ifdef F_sceSysreg_driver_0057 + IMPORT_FUNC "sceSysreg_driver",0xE1AA9788,sceSysreg_driver_E1AA9788 +#endif +#ifdef F_sceSysreg_driver_0058 + IMPORT_FUNC "sceSysreg_driver",0xAA63C8BD,sceSysregAudioBusClockEnable +#endif +#ifdef F_sceSysreg_driver_0059 + IMPORT_FUNC "sceSysreg_driver",0x054AC8C6,sceSysregAudioBusClockDisable +#endif +#ifdef F_sceSysreg_driver_0060 + IMPORT_FUNC "sceSysreg_driver",0x6B01D71B,sceSysreg_driver_6B01D71B +#endif +#ifdef F_sceSysreg_driver_0061 + IMPORT_FUNC "sceSysreg_driver",0xFC186A83,sceSysreg_driver_FC186A83 +#endif +#ifdef F_sceSysreg_driver_0062 + IMPORT_FUNC "sceSysreg_driver",0x7234EA80,sceSysreg_driver_7234EA80 +#endif +#ifdef F_sceSysreg_driver_0063 + IMPORT_FUNC "sceSysreg_driver",0x38EC3281,sceSysreg_driver_38EC3281 +#endif +#ifdef F_sceSysreg_driver_0064 + IMPORT_FUNC "sceSysreg_driver",0x31154490,sceSysreg_driver_31154490 +#endif +#ifdef F_sceSysreg_driver_0065 + IMPORT_FUNC "sceSysreg_driver",0x8E2D835D,sceSysreg_driver_8E2D835D +#endif +#ifdef F_sceSysreg_driver_0066 + IMPORT_FUNC "sceSysreg_driver",0x8835D1E1,sceSysreg_driver_8835D1E1 +#endif +#ifdef F_sceSysreg_driver_0067 + IMPORT_FUNC "sceSysreg_driver",0x8B90B8B5,sceSysreg_driver_8B90B8B5 +#endif +#ifdef F_sceSysreg_driver_0068 + IMPORT_FUNC "sceSysreg_driver",0x7725CA08,sceSysreg_driver_7725CA08 +#endif +#ifdef F_sceSysreg_driver_0069 + IMPORT_FUNC "sceSysreg_driver",0xA3E4154C,sceSysreg_driver_A3E4154C +#endif +#ifdef F_sceSysreg_driver_0070 + IMPORT_FUNC "sceSysreg_driver",0xE8533DCA,sceSysreg_driver_E8533DCA +#endif +#ifdef F_sceSysreg_driver_0071 + IMPORT_FUNC "sceSysreg_driver",0xF6D83AD0,sceSysreg_driver_F6D83AD0 +#endif +#ifdef F_sceSysreg_driver_0072 + IMPORT_FUNC "sceSysreg_driver",0xA9CD1C1F,sceSysreg_driver_A9CD1C1F +#endif +#ifdef F_sceSysreg_driver_0073 + IMPORT_FUNC "sceSysreg_driver",0x2F216F38,sceSysreg_driver_2F216F38 +#endif +#ifdef F_sceSysreg_driver_0074 + IMPORT_FUNC "sceSysreg_driver",0xA24C242A,sceSysreg_driver_A24C242A +#endif +#ifdef F_sceSysreg_driver_0075 + IMPORT_FUNC "sceSysreg_driver",0xE89243BE,sceSysreg_driver_E89243BE +#endif +#ifdef F_sceSysreg_driver_0076 + IMPORT_FUNC "sceSysreg_driver",0x7DCA8302,sceSysreg_driver_7DCA8302 +#endif +#ifdef F_sceSysreg_driver_0077 + IMPORT_FUNC "sceSysreg_driver",0x45225F8F,sceSysreg_driver_45225F8F +#endif +#ifdef F_sceSysreg_driver_0078 + IMPORT_FUNC "sceSysreg_driver",0xD74D3AB6,sceSysreg_driver_D74D3AB6 +#endif +#ifdef F_sceSysreg_driver_0079 + IMPORT_FUNC "sceSysreg_driver",0xAD7C4ACB,sceSysreg_driver_AD7C4ACB +#endif +#ifdef F_sceSysreg_driver_0080 + IMPORT_FUNC "sceSysreg_driver",0xDC68A93F,sceSysreg_driver_DC68A93F +#endif +#ifdef F_sceSysreg_driver_0081 + IMPORT_FUNC "sceSysreg_driver",0x94B0323C,sceSysreg_driver_94B0323C +#endif +#ifdef F_sceSysreg_driver_0082 + IMPORT_FUNC "sceSysreg_driver",0x6417CDD6,sceSysreg_driver_6417CDD6 +#endif +#ifdef F_sceSysreg_driver_0083 + IMPORT_FUNC "sceSysreg_driver",0x20388C9E,sceSysreg_driver_20388C9E +#endif +#ifdef F_sceSysreg_driver_0084 + IMPORT_FUNC "sceSysreg_driver",0xE3AECFFA,sceSysreg_driver_E3AECFFA +#endif +#ifdef F_sceSysreg_driver_0085 + IMPORT_FUNC "sceSysreg_driver",0x3BBD0C0C,sceSysreg_driver_3BBD0C0C +#endif +#ifdef F_sceSysreg_driver_0086 + IMPORT_FUNC "sceSysreg_driver",0xC1DA05D2,sceSysreg_driver_C1DA05D2 +#endif +#ifdef F_sceSysreg_driver_0087 + IMPORT_FUNC "sceSysreg_driver",0xDE170397,sceSysreg_driver_DE170397 +#endif +#ifdef F_sceSysreg_driver_0088 + IMPORT_FUNC "sceSysreg_driver",0x1969E840,sceSysreg_driver_1969E840 +#endif +#ifdef F_sceSysreg_driver_0089 + IMPORT_FUNC "sceSysreg_driver",0x1D382514,sceSysreg_driver_1D382514 +#endif +#ifdef F_sceSysreg_driver_0090 + IMPORT_FUNC "sceSysreg_driver",0x833E6FB1,sceSysreg_driver_833E6FB1 +#endif +#ifdef F_sceSysreg_driver_0091 + IMPORT_FUNC "sceSysreg_driver",0x03340297,sceSysreg_driver_03340297 +#endif +#ifdef F_sceSysreg_driver_0092 + IMPORT_FUNC "sceSysreg_driver",0x9100B4E5,sceSysreg_driver_9100B4E5 +#endif +#ifdef F_sceSysreg_driver_0093 + IMPORT_FUNC "sceSysreg_driver",0x0A83FC7B,sceSysreg_driver_0A83FC7B +#endif +#ifdef F_sceSysreg_driver_0094 + IMPORT_FUNC "sceSysreg_driver",0xD6628A48,sceSysreg_driver_D6628A48 +#endif +#ifdef F_sceSysreg_driver_0095 + IMPORT_FUNC "sceSysreg_driver",0x1E18EA43,sceSysreg_driver_1E18EA43 +#endif +#ifdef F_sceSysreg_driver_0096 + IMPORT_FUNC "sceSysreg_driver",0x9DD1F821,sceSysregEmcsmIoEnable +#endif +#ifdef F_sceSysreg_driver_0097 + IMPORT_FUNC "sceSysreg_driver",0x1C4C4C7A,sceSysregEmcsmIoDisable +#endif +#ifdef F_sceSysreg_driver_0098 + IMPORT_FUNC "sceSysreg_driver",0xBC68D9B6,sceSysregUsbIoEnable +#endif +#ifdef F_sceSysreg_driver_0099 + IMPORT_FUNC "sceSysreg_driver",0xA3C8E075,sceSysregUsbIoDisable +#endif +#ifdef F_sceSysreg_driver_0100 + IMPORT_FUNC "sceSysreg_driver",0x79338EA3,sceSysregAtaIoEnable +#endif +#ifdef F_sceSysreg_driver_0101 + IMPORT_FUNC "sceSysreg_driver",0xCADB92AA,sceSysregAtaIoDisable +#endif +#ifdef F_sceSysreg_driver_0102 + IMPORT_FUNC "sceSysreg_driver",0xD74F1D48,sceSysregMsifIoEnable +#endif +#ifdef F_sceSysreg_driver_0103 + IMPORT_FUNC "sceSysreg_driver",0x18172C6A,sceSysregMsifIoDisable +#endif +#ifdef F_sceSysreg_driver_0104 + IMPORT_FUNC "sceSysreg_driver",0x63B1AADF,sceSysregLcdcIoEnable +#endif +#ifdef F_sceSysreg_driver_0105 + IMPORT_FUNC "sceSysreg_driver",0xF74F14E9,sceSysregLcdcIoDisable +#endif +#ifdef F_sceSysreg_driver_0106 + IMPORT_FUNC "sceSysreg_driver",0xBB26CF1F,sceSysregAudioIoEnable +#endif +#ifdef F_sceSysreg_driver_0107 + IMPORT_FUNC "sceSysreg_driver",0x8E2FB536,sceSysregAudioIoDisable +#endif +#ifdef F_sceSysreg_driver_0108 + IMPORT_FUNC "sceSysreg_driver",0x0436B60F,sceSysregIicIoEnable +#endif +#ifdef F_sceSysreg_driver_0109 + IMPORT_FUNC "sceSysreg_driver",0x58F47EFD,sceSysregIicIoDisable +#endif +#ifdef F_sceSysreg_driver_0110 + IMPORT_FUNC "sceSysreg_driver",0x4C49A8BC,sceSysregSircsIoEnable +#endif +#ifdef F_sceSysreg_driver_0111 + IMPORT_FUNC "sceSysreg_driver",0x26FA0928,sceSysregSircsIoDisable +#endif +#ifdef F_sceSysreg_driver_0112 + IMPORT_FUNC "sceSysreg_driver",0xF844DDF3,sceSysreg_driver_F844DDF3 +#endif +#ifdef F_sceSysreg_driver_0113 + IMPORT_FUNC "sceSysreg_driver",0x29A119A1,sceSysreg_driver_29A119A1 +#endif +#ifdef F_sceSysreg_driver_0114 + IMPORT_FUNC "sceSysreg_driver",0x77DED992,sceSysregKeyIoEnable +#endif +#ifdef F_sceSysreg_driver_0115 + IMPORT_FUNC "sceSysreg_driver",0x6879790B,sceSysregKeyIoDisable +#endif +#ifdef F_sceSysreg_driver_0116 + IMPORT_FUNC "sceSysreg_driver",0x7A5D2D15,sceSysregPwmIoEnable +#endif +#ifdef F_sceSysreg_driver_0117 + IMPORT_FUNC "sceSysreg_driver",0x25B0AC52,sceSysregPwmIoDisable +#endif +#ifdef F_sceSysreg_driver_0118 + IMPORT_FUNC "sceSysreg_driver",0x7FD7A631,sceSysregUartIoEnable +#endif +#ifdef F_sceSysreg_driver_0119 + IMPORT_FUNC "sceSysreg_driver",0xBB823481,sceSysregUartIoDisable +#endif +#ifdef F_sceSysreg_driver_0120 + IMPORT_FUNC "sceSysreg_driver",0x8C5C53DE,sceSysregSpiIoEnable +#endif +#ifdef F_sceSysreg_driver_0121 + IMPORT_FUNC "sceSysreg_driver",0xA16E55F4,sceSysregSpiIoDisable +#endif +#ifdef F_sceSysreg_driver_0122 + IMPORT_FUNC "sceSysreg_driver",0xB627582E,sceSysregGpioIoEnable +#endif +#ifdef F_sceSysreg_driver_0123 + IMPORT_FUNC "sceSysreg_driver",0x1E9C3607,sceSysregGpioIoDisable +#endif +#ifdef F_sceSysreg_driver_0124 + IMPORT_FUNC "sceSysreg_driver",0x55B18B84,sceSysreg_driver_55B18B84 +#endif +#ifdef F_sceSysreg_driver_0125 + IMPORT_FUNC "sceSysreg_driver",0x2112E686,sceSysreg_driver_2112E686 +#endif +#ifdef F_sceSysreg_driver_0126 + IMPORT_FUNC "sceSysreg_driver",0x7B9E9A53,sceSysreg_driver_7B9E9A53 +#endif +#ifdef F_sceSysreg_driver_0127 + IMPORT_FUNC "sceSysreg_driver",0x7BDF0556,sceSysreg_driver_7BDF0556 +#endif +#ifdef F_sceSysreg_driver_0128 + IMPORT_FUNC "sceSysreg_driver",0x8D0FED1E,sceSysreg_driver_8D0FED1E +#endif +#ifdef F_sceSysreg_driver_0129 + IMPORT_FUNC "sceSysreg_driver",0xA46E9CA8,sceSysreg_driver_A46E9CA8 +#endif +#ifdef F_sceSysreg_driver_0130 + IMPORT_FUNC "sceSysreg_driver",0x633595F2,sceSysreg_driver_633595F2 +#endif +#ifdef F_sceSysreg_driver_0131 + IMPORT_FUNC "sceSysreg_driver",0x32471457,sceSysregUsbQueryIntr +#endif +#ifdef F_sceSysreg_driver_0132 + IMPORT_FUNC "sceSysreg_driver",0x692F31FF,sceSysregUsbAcquireIntr +#endif +#ifdef F_sceSysreg_driver_0133 + IMPORT_FUNC "sceSysreg_driver",0xD43E98F6,sceSysreg_driver_D43E98F6 +#endif +#ifdef F_sceSysreg_driver_0134 + IMPORT_FUNC "sceSysreg_driver",0xBF91FBDA,sceSysreg_driver_BF91FBDA +#endif +#ifdef F_sceSysreg_driver_0135 + IMPORT_FUNC "sceSysreg_driver",0x36A75390,sceSysreg_driver_36A75390 +#endif +#ifdef F_sceSysreg_driver_0136 + IMPORT_FUNC "sceSysreg_driver",0x25673620,sceSysregIntrInit +#endif +#ifdef F_sceSysreg_driver_0137 + IMPORT_FUNC "sceSysreg_driver",0x4EE8E2C8,sceSysregIntrEnd +#endif +#ifdef F_sceSysreg_driver_0138 + IMPORT_FUNC "sceSysreg_driver",0x61BFF85F,sceSysregInterruptToOther +#endif +#ifdef F_sceSysreg_driver_0139 + IMPORT_FUNC "sceSysreg_driver",0x9FC87ED4,sceSysregSemaTryLock +#endif +#ifdef F_sceSysreg_driver_0140 + IMPORT_FUNC "sceSysreg_driver",0x8BE2D520,sceSysregSemaUnlock +#endif +#ifdef F_sceSysreg_driver_0141 + IMPORT_FUNC "sceSysreg_driver",0x083F56E2,sceSysregEnableIntr +#endif +#ifdef F_sceSysreg_driver_0142 + IMPORT_FUNC "sceSysreg_driver",0x7C5B543C,sceSysregDisableIntr +#endif +#ifdef F_sceSysreg_driver_0143 + IMPORT_FUNC "sceSysreg_driver",0x3EA188AD,sceSysregRequestIntr +#endif +#ifdef F_sceSysreg_driver_0144 + IMPORT_FUNC "sceSysreg_driver",0x5664F8B5,sceSysreg_driver_5664F8B5 +#endif +#ifdef F_sceSysreg_driver_0145 + IMPORT_FUNC "sceSysreg_driver",0x44704E1D,sceSysreg_driver_44704E1D +#endif +#ifdef F_sceSysreg_driver_0146 + IMPORT_FUNC "sceSysreg_driver",0x584AD989,sceSysreg_driver_584AD989 +#endif +#ifdef F_sceSysreg_driver_0147 + IMPORT_FUNC "sceSysreg_driver",0x377F035F,sceSysreg_driver_377F035F +#endif +#ifdef F_sceSysreg_driver_0148 + IMPORT_FUNC "sceSysreg_driver",0xAB3185FD,sceSysreg_driver_AB3185FD +#endif +#ifdef F_sceSysreg_driver_0149 + IMPORT_FUNC "sceSysreg_driver",0x0EA487FA,sceSysreg_driver_0EA487FA +#endif +#ifdef F_sceSysreg_driver_0150 + IMPORT_FUNC "sceSysreg_driver",0x136E8F5A,sceSysreg_driver_136E8F5A +#endif +#ifdef F_sceSysreg_driver_0151 + IMPORT_FUNC "sceSysreg_driver",0xF4811E00,sceSysreg_driver_F4811E00 +#endif diff --git a/src/libc/LIB.status b/src/libc/LIB.status new file mode 100644 index 00000000..dad9b052 --- /dev/null +++ b/src/libc/LIB.status @@ -0,0 +1,180 @@ +Stdlib: +------ + +What should stdlib contain, and current status. + +atof - ok +atoi - ok +atol - ok +strtod - ok +strtof - ok +strtold - missing (do we want to support long double anyway?) +strtol - ok +strtoul - ok +strtoq - missing +strtouq - missing +strtoll - missing (same as strtoq, different "standard") +strtoull - missing (same as strtouq, different "standard") + + +no locale function at all (__strtol_l, etc...) + + +random - missing +srandom - missing +initstate - missing +setstate - missing +rand - ok (should be...) +srand - ok +drand48 - missing + +all *rand48 missing + +malloc, calloc, realloc, free, are defined in alloc.c. + +abort - clean ? should call atexit functions ? +atexit - ok +exit - ok + +getenv - ok +setenv - ok + +system - missing, and won't be here anyway I think... + +bsearch - ok +qsort - ok +abs - ok +labs - ok +llabs - ok +div - ok, but shouldn't it use some asm ? +ldiv - ok, same +lldiv - ok, same +frexp - missing +ldexp - missing + +ecvt - missing +fcvt - missing +gcvt - won't compile + +Multibyte function disabled... I don't trust them. Somebody please advice. +mblen, mbtowc, wctomb, mbstowcs, wcstombs + + +Stdio: +----- + +stdin, stdout, stderr, ok. Maybe some specific ps2 function to switch stderr +to SIO could be an idea. + +Also, should have buffering... + +remove - missing +rename - missing +tmp* - missing +fclose - ok +fflush - ok (memory card) +fcloseall - ok +fopen - ok +freopen - missing +fdopen - ok +setbuf - missing +setvbuf - missing + +*printf - ok (f, s, vf, v, vs, sn, vsn, vas, as) +*dprintf - missing +*scanf - missing +*getc - ok +getchar - ok +*putc - ok +putchar - ok +{get,put}w - missing +*gets - ok +getdelim - missing, gnu replacement to gets +getline - missing, gnu replacement to gets +*puts - ok +ungetc - missing, buffering needed +fread - ok, buffering needed +fwrite - ok, buffering needed +fseek - ok +ftell - ok +rewind - ok +fgetpos - ok +fsetpos - ok +clearerr - ok +feof - ok +ferror - ok + +perror - ok +fileno - ok +pipe funcs - missing, can we make them ? +lock funcs - missing, can we make them ? + + +String: +------ + +memcpy - ok, asm version +memmove - ok, asm +memset - ok, asm +memcmp - ok, asm +memchr - ok, asm + +strcpy - ok, asm +strncpy - ok, asm +strcat - ok, asm +strncat - ok, asm +strcmp - ok, asm +strncmp - ok, asm + +strcoll - ok, binded to strcmp (will we ever support locales ?) +strxfrm - ok, binded to strncpy (will we ever support locales ?) + +strdup - ok + +strchr - ok, asm +strrchr - ok + +strcspn - ok +strspn - ok +strpbrk - ok +strstr - ok +strcasestr - missing +strtok - ok + +strlen - ok +strerror - ok (but in stdio) + +bzero - ok (macro, in string.h) +bcopy - ok (macro, in string.h) +bcmp - ok (macro, in string.h) +index - ok (macro, in string.h) +rindex - ok (macro, in string.h) + +stricmp - ok (macro) +strcasecmp - ok +strnicmp - ok (macro) +strncasecmp - ok + +isalnum - ok +iscntrl - ok +isdigit - ok +isgraph - ok +islower - ok +isprint - ok +ispunct - ok +isspace - ok +isupper - ok +isxdigit - ok + +asctime - missing +clock - missing +ctime - missing +difftime - missing +gmtime - missing +localtime - missing +mktime - missing + +longjmp - ok +setjmp - ok + +raise - missing, can we build signals ? diff --git a/src/libc/Makefile.am b/src/libc/Makefile.am new file mode 100644 index 00000000..fa346c56 --- /dev/null +++ b/src/libc/Makefile.am @@ -0,0 +1,73 @@ + +libdir = @PSPSDK_LIBDIR@ + +CC = @PSP_CC@ +CXX = @PSP_CXX@ +CCAS = $(CC) +AR = @PSP_AR@ +RANLIB = @PSP_RANLIB@ + +INCLUDES = -I$(top_srcdir)/src/libc/include -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel -I$(top_srcdir)/src/user -I$(top_srcdir)/src/debug +CFLAGS = @PSPSDK_CFLAGS@ +CXXFLAGS = @PSPSDK_CXXFLAGS@ +CCASFLAGS = $(CFLAGS) $(INCLUDES) + +EXTRA_DIST = LIB.status + +lib_LIBRARIES = libpsplibc.a + +## libpsplibc.a sources. +CORE_SOURCES = terminate.c setjmp.S qsort.c init.c cxx.cpp +MULT_SOURCES = xprintf.c alloc.c string.c stdio.c stdlib.c libcglue.c + +ALLOC_OBJS = malloc.o realloc.o calloc.o memalign.o free.o __builtin_alloc.o __alloc_internals.o __mem_walk.o + +STRING_C_OBJS = strdup.o strcasecmp.o strncasecmp.o strtok.o strrchr.o strstr.o \ + strupr.o strlwr.o _sjis_internals.o strcpy_ascii.o strcpy_sjis.o \ + strpbrk.o strspn.o strcspn.o memchr.o memcmp.o memcpy.o memmove.o \ + memset.o strcat.o strchr.o strcmp.o strcpy.o strlen.o strncat.o strncmp.o strncpy.o \ + tolower.o toupper.o isupper.o islower.o isalpha.o isdigit.o isalnum.o iscntrl.o \ + isgraph.o isprint.o ispunct.o isspace.o isxdigit.o + +XPRINTF_OBJS = vxprintf.o _xprintf.o __sout.o vsnprintf.o snprintf.o vsprintf.o sprintf.o \ + __mout.o mprintf.o vmprintf.o __fout.o fprintf.o vfprintf.o printf.o vprintf.o putchar.o \ + asprintf.o vasprintf.o + +STDIO_OBJS = clearerr.o fclose.o fcloseall.o feof.o ferror.o fflush.o fflushall.o fgetc.o \ + fgetpos.o fgets.o fopen.o fputc.o fputs.o fread.o fseek.o fsetpos.o ftell.o fwrite.o fileno.o \ + getc.o getchar.o getfdtype.o gets.o perror.o putc.o puts.o remove.o rename.o fdopen.o \ + rewind.o skipatoi.o sscanf.o _stdio.o tmpfile.o tmpnam.o ungetc.o updatestdoutxy.o strerror.o \ + __stdio_internals.o + +STDLIB_OBJS = abs.o atexit.o atof.o bsearch.o div.o exit.o getenv.o _itoa.o labs.o \ + ldiv.o llabs.o lldiv.o _lltoa.o _ltoa.o rand.o setenv.o srand.o \ + strtod.o strtol.o strtoul.o __assert_fail.o \ + __stdlib_internals.o + +## Use a few functions from libpspglue.a. +GLUE_OBJS = glue__exit.o glue__sbrk.o glue_clock.o glue_gettimeofday.o glue_time.o glue___errno.o + +MULT_OBJS = $(XPRINTF_OBJS) $(ALLOC_OBJS) $(STRING_C_OBJS) $(STDIO_OBJS) $(STDLIB_OBJS) $(GLUE_OBJS) + +libpsplibcincludedir = @PSPSDK_INCLUDEDIR@/libc +libpsplibcinclude_HEADERS = assert.h ctype.h malloc.h stdio.h stdlib.h string.h time.h unistd.h +libpsplibc_a_SOURCES = $(CORE_SOURCES) $(MULT_SOURCES) +libpsplibc_a_LIBADD = $(MULT_OBJS) + +$(XPRINTF_OBJS): xprintf.c + $(COMPILE) -DF_$* $< -c -o $@ + +$(ALLOC_OBJS): alloc.c + $(COMPILE) -DF_$* $< -c -o $@ + +$(STRING_C_OBJS): string.c + $(COMPILE) -DF_$* $< -c -o $@ + +$(STDIO_OBJS): stdio.c + $(COMPILE) -DF_$* $< -c -o $@ + +$(STDLIB_OBJS): stdlib.c + $(COMPILE) -DF_$* $< -c -o $@ + +$(GLUE_OBJS): libcglue.c + $(COMPILE) -DF_$* $< -c -o $@ diff --git a/src/libc/alloc.c b/src/libc/alloc.c new file mode 100644 index 00000000..113927dd --- /dev/null +++ b/src/libc/alloc.c @@ -0,0 +1,490 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * alloc.c - Standard C library heap allocation routines. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: alloc.c 540 2005-07-08 19:35:10Z warren $ + */ +/* This code is based on code contributed by Philip Joaqiun (jenova0). */ +#include +#include +#include +#include +#ifdef DEBUG_ALLOC +#include +#endif + +/* Use this to set the default malloc() alignment. */ +#define DEFAULT_ALIGNMENT 16 + +#ifndef ALIGN +#define ALIGN(x, align) (((x)+((align)-1))&~((align)-1)) +#endif + +#ifdef DEBUG_ALLOC +#define ALLOC_MAGIC 0xa110ca73 +#endif + +extern void * _sbrk(ptrdiff_t incr); + +void _pspsdk_alloc_init(); +void _pspsdk_alloc_deinit(); +void _pspsdk_alloc_lock(); +void _pspsdk_alloc_unlock(); + +#ifdef F___alloc_internals +/*static vs32 alloc_sema = -1;*/ +void _pspsdk_alloc_init() +{ +/* ee_sema_t alloc_sema_struct;*/ +/* alloc_sema_struct.init_count = 1;*/ +/* alloc_sema_struct.max_count = 1;*/ +/* alloc_sema = CreateSema(&alloc_sema_struct);*/ +} + +void _pspsdk_alloc_deinit() +{ +/* if (alloc_sema >= 0) {*/ +/* DeleteSema(alloc_sema);*/ +/* }*/ +} + +void _pspsdk_alloc_lock() +{ +/* if (alloc_sema >= 0) {*/ +/* WaitSema(alloc_sema);*/ +/* }*/ +} + +void _pspsdk_alloc_unlock() +{ +/* if (alloc_sema >= 0) {*/ +/* SignalSema(alloc_sema);*/ +/* }*/ +} +#endif + +/* _heap_mem_block_header structure. */ +typedef struct _heap_mem_header { +#ifdef DEBUG_ALLOC + u32 magic; +#endif + void * ptr; + size_t size; + struct _heap_mem_header * prev; + struct _heap_mem_header * next; +} heap_mem_header_t; + +extern void * __alloc_heap_base; +extern heap_mem_header_t *__alloc_heap_head; +extern heap_mem_header_t *__alloc_heap_tail; + +heap_mem_header_t * _heap_mem_fit(heap_mem_header_t *head, size_t size); + +#ifdef F_malloc + +void * __alloc_heap_base = NULL; +heap_mem_header_t *__alloc_heap_head = NULL; +heap_mem_header_t *__alloc_heap_tail = NULL; + +/* Find a the lowest block that we can allocate AFTER, returning NULL if there + are none. */ +heap_mem_header_t * _heap_mem_fit(heap_mem_header_t *head, size_t size) +{ + heap_mem_header_t *prev_mem = head; + u32 prev_top, next_bot; + + while (prev_mem != NULL) { + if (prev_mem->next != NULL) { + prev_top = (u32)prev_mem->ptr + prev_mem->size; + next_bot = (u32)prev_mem->next - prev_top; + if (next_bot >= size) + return prev_mem; + } + + prev_mem = prev_mem->next; + } + + return prev_mem; +} + +__attribute__((weak)) +void * malloc(size_t size) +{ + void *ptr = NULL, *mem_ptr; + heap_mem_header_t *new_mem, *prev_mem; + size_t mem_sz, heap_align_bytes; + + mem_sz = size + sizeof(heap_mem_header_t); + + if ((mem_sz & (DEFAULT_ALIGNMENT - 1)) != 0) + mem_sz = ALIGN(mem_sz, DEFAULT_ALIGNMENT); + + _pspsdk_alloc_lock(); + + /* If we don't have any allocated blocks, reserve the first block from + the OS and initialize __alloc_heap_tail. */ + if (__alloc_heap_head == NULL) { + /* Align the bottom of the heap to our default alignment. */ + if (__alloc_heap_base == NULL) { + heap_align_bytes = (u32) _sbrk(0) & (DEFAULT_ALIGNMENT - 1); + _sbrk(heap_align_bytes); + __alloc_heap_base = _sbrk(0); + } + + /* Allocate the physical heap and setup the head block. */ + if ((mem_ptr = _sbrk(mem_sz)) == (void *)-1) + return ptr; /* NULL */ + + ptr = (void *)((u32)mem_ptr + sizeof(heap_mem_header_t)); + + __alloc_heap_head = (heap_mem_header_t *)mem_ptr; +#ifdef DEBUG_ALLOC + __alloc_heap_head->magic = ALLOC_MAGIC; +#endif + __alloc_heap_head->ptr = ptr; + __alloc_heap_head->size = mem_sz - sizeof(heap_mem_header_t); + __alloc_heap_head->prev = NULL; + __alloc_heap_head->next = NULL; + + __alloc_heap_tail = __alloc_heap_head; + + _pspsdk_alloc_unlock(); + return ptr; + } + + /* Check to see if there's free space at the bottom of the heap. */ + if ((__alloc_heap_base + mem_sz) < (void *)__alloc_heap_head) { + new_mem = (heap_mem_header_t *)__alloc_heap_base; + ptr = (void *)((u32)new_mem + sizeof(heap_mem_header_t)); + +#ifdef DEBUG_ALLOC + new_mem->magic = ALLOC_MAGIC; +#endif + new_mem->ptr = ptr; + new_mem->size = mem_sz - sizeof(heap_mem_header_t); + new_mem->prev = NULL; + new_mem->next = __alloc_heap_head; + new_mem->next->prev = new_mem; + __alloc_heap_head = new_mem; + + _pspsdk_alloc_unlock(); + return ptr; + } + + /* See if we can allocate the block without extending the heap. */ + prev_mem = _heap_mem_fit(__alloc_heap_head, mem_sz); + if (prev_mem != NULL) { + new_mem = (heap_mem_header_t *)((u32)prev_mem->ptr + prev_mem->size); + ptr = (void *)((u32)new_mem + sizeof(heap_mem_header_t)); + +#ifdef DEBUG_ALLOC + new_mem->magic = ALLOC_MAGIC; +#endif + new_mem->ptr = ptr; + new_mem->size = mem_sz - sizeof(heap_mem_header_t); + new_mem->prev = prev_mem; + new_mem->next = prev_mem->next; + new_mem->next->prev = new_mem; + prev_mem->next = new_mem; + + _pspsdk_alloc_unlock(); + return ptr; + } + + /* Extend the heap, but make certain the block is inserted in + order. */ + if ((mem_ptr = _sbrk(mem_sz)) == (void *)-1) { + _pspsdk_alloc_unlock(); + return ptr; /* NULL */ + } + + ptr = (void *)((u32)mem_ptr + sizeof(heap_mem_header_t)); + + new_mem = (heap_mem_header_t *)mem_ptr; +#ifdef DEBUG_ALLOC + new_mem->magic = ALLOC_MAGIC; +#endif + new_mem->ptr = ptr; + new_mem->size = mem_sz - sizeof(heap_mem_header_t); + new_mem->prev = __alloc_heap_tail; + new_mem->next = NULL; + + __alloc_heap_tail->next = new_mem; + __alloc_heap_tail = new_mem; + + _pspsdk_alloc_unlock(); + return ptr; +} +#endif + +#ifdef F_realloc +__attribute__((weak)) +void * realloc(void *ptr, size_t size) +{ + heap_mem_header_t *prev_mem; + void *new_ptr = NULL; + + if (!size && ptr != NULL) { + free(ptr); + return new_ptr; + } + + if (ptr == NULL) + return malloc(size); + + if ((size & (DEFAULT_ALIGNMENT - 1)) != 0) + size = ALIGN(size, DEFAULT_ALIGNMENT); + + _pspsdk_alloc_lock(); + prev_mem = (heap_mem_header_t *)((u32)ptr - sizeof(heap_mem_header_t)); + +#ifdef DEBUG_ALLOC + if (prev_mem->magic != ALLOC_MAGIC) { + fprintf(stderr, "realloc: Pointer at %p was not malloc()ed before, or got overwritten.\n", ptr); + + _pspsdk_alloc_unlock(); + return NULL; + } +#endif + + /* Don't do anything if asked for same sized block. */ + /* If the new size is shorter, let's just shorten the block. */ + if (prev_mem->size >= size) { + /* However, if this is the last block, we have to shrink the heap. */ + if (!prev_mem->next) + _sbrk(ptr + size - _sbrk(0)); + prev_mem->size = size; + + _pspsdk_alloc_unlock(); + return ptr; + } + + + /* We are asked for a larger block of memory. */ + + /* Are we the last memory block ? */ + if (!prev_mem->next) { + /* Yes, let's just extend the heap then. */ + if (_sbrk(size - prev_mem->size) == (void*) -1) + return NULL; + prev_mem->size = size; + + _pspsdk_alloc_unlock(); + return ptr; + } + + /* Is the next block far enough so we can extend the current block ? */ + if ((prev_mem->next->ptr - ptr) > size) { + prev_mem->size = size; + + _pspsdk_alloc_unlock(); + return ptr; + } + + _pspsdk_alloc_unlock(); + + /* We got out of luck, let's allocate a new block of memory. */ + if ((new_ptr = malloc(size)) == NULL) + return new_ptr; + + /* New block is larger, we only copy the old data. */ + memcpy(new_ptr, ptr, prev_mem->size); + + free(ptr); + return new_ptr; +} +#endif + +#ifdef F_calloc +__attribute__((weak)) +void * calloc(size_t n, size_t size) +{ + void *ptr = NULL; + size_t sz = n * size; + + if ((ptr = malloc(sz)) == NULL) + return ptr; + + memset(ptr, 0, sz); + return ptr; +} +#endif + +#ifdef F_memalign +__attribute__((weak)) +void * memalign(size_t align, size_t size) +{ + heap_mem_header_t new_mem; + heap_mem_header_t *cur_mem; + heap_mem_header_t *old_mem; + void *ptr = NULL; + + if (align <= DEFAULT_ALIGNMENT) + return malloc(size); + + /* Allocate with extra alignment bytes just in case it isn't aligned + properly by malloc. */ + if ((ptr = malloc(size + align)) == NULL) + return ptr; /* NULL */ + + /* If malloc returned it aligned for us we're fine. */ + if (((u32)ptr & (align - 1)) == 0) + return ptr; + + _pspsdk_alloc_lock(); + cur_mem = (heap_mem_header_t *)((u32)ptr - sizeof(heap_mem_header_t)); + cur_mem->size -= align; + + /* Otherwise, align the pointer and fixup our hearder accordingly. */ + ptr = (void *)ALIGN((u32)ptr, align); + + old_mem = cur_mem; + + /* Copy the heap_mem_header_t locally, before repositioning (to make + sure we don't overwrite ourselves. */ + memcpy(&new_mem, cur_mem, sizeof(heap_mem_header_t)); + cur_mem = (heap_mem_header_t *)((u32)ptr - sizeof(heap_mem_header_t)); + memcpy(cur_mem, &new_mem, sizeof(heap_mem_header_t)); + + if (cur_mem->prev) + cur_mem->prev->next = cur_mem; + if (cur_mem->next) + cur_mem->next->prev = cur_mem; + + if (__alloc_heap_head == old_mem) + __alloc_heap_head = cur_mem; + + if (__alloc_heap_tail == old_mem) + __alloc_heap_tail = cur_mem; + + cur_mem->ptr = ptr; + + _pspsdk_alloc_unlock(); + return ptr; +} +#endif + +#ifdef F_free +__attribute__((weak)) +void free(void *ptr) +{ + heap_mem_header_t *cur; + void *heap_top; + size_t size; + + if (!ptr) + return; + + _pspsdk_alloc_lock(); + + if (!__alloc_heap_head) { + _pspsdk_alloc_unlock(); + return; + } + +#ifdef DEBUG_ALLOC + cur = (heap_mem_header_t *)((u32)ptr - sizeof(heap_mem_header_t)); + if (cur->magic != ALLOC_MAGIC) { + fprintf(stderr, "free: Pointer at %p was not malloc()ed before, or got overwritten.\n", ptr); + + _pspsdk_alloc_unlock(); + return; + } +#endif + + /* Freeing the head pointer is a special case. */ + if (ptr == __alloc_heap_head->ptr) { + size = __alloc_heap_head->size + + (size_t)(__alloc_heap_head->ptr - (void *)__alloc_heap_head); + + __alloc_heap_head = __alloc_heap_head->next; + + if (__alloc_heap_head != NULL) { + __alloc_heap_head->prev = NULL; + } else { + __alloc_heap_tail = NULL; + + _sbrk(-size); + } + + _pspsdk_alloc_unlock(); + return; + } + + cur = __alloc_heap_head; + while (ptr != cur->ptr) { + /* ptr isn't in our list */ + if (cur->next == NULL) { + _pspsdk_alloc_unlock(); + return; + } + + cur = cur->next; + } + + /* Deallocate the block. */ + if (cur->next != NULL) { + cur->next->prev = cur->prev; + } else { + /* If this block was the last one in the list, shrink the heap. */ + __alloc_heap_tail = cur->prev; + + /* We need to free (heap top) - (prev->ptr + prev->size), or else + we'll end up with an unallocatable block of heap. */ + heap_top = _sbrk(0); + size = (u32)heap_top - (u32)(cur->prev->ptr + cur->prev->size); + _sbrk(-size); + } + + cur->prev->next = cur->next; + + _pspsdk_alloc_unlock(); +} +#endif + +/* These are here in case C++ needs them. */ +#ifdef F___builtin_alloc +__attribute__((weak)) +void * __builtin_new(size_t size) { return malloc(size); } + +__attribute__((weak)) +void __builtin_delete(void *ptr) { free(ptr); } +#endif + +#ifdef F___mem_walk +void * __mem_walk_begin() { + return __alloc_heap_head; +} + +void __mem_walk_read(void * token, u32 * size, void ** ptr, int * valid) { + heap_mem_header_t * cur = (heap_mem_header_t *) token; + +#ifdef DEBUG_ALLOC + if (cur->magic != ALLOC_MAGIC) { + *valid = 0; + return; + } +#endif + *valid = 1; + + *size = cur->size; + *ptr = cur->ptr; +} + +void * __mem_walk_inc(void * token) { + heap_mem_header_t * cur = (heap_mem_header_t *) token; + + return cur->next; +} + +int __mem_walk_end(void * token) { + return token == NULL; +} +#endif diff --git a/src/libc/assert.h b/src/libc/assert.h new file mode 100644 index 00000000..55ae58c0 --- /dev/null +++ b/src/libc/assert.h @@ -0,0 +1,34 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * assert.h + * + * Copyright (c) 2002-2004 PS2DEV + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: assert.h 1095 2005-09-27 21:02:16Z jim $ + */ +#ifndef __ASSERT_H__ +#define __ASSERT_H__ + +#include +#include + +#ifdef NDEBUG +#define assert(cond) +#else +#ifdef __cplusplus +extern "C" { +#endif + int __assert_fail (const char *assertion, const char *file, unsigned int line) __attribute__((noreturn)); +#ifdef __cplusplus +} +#endif +#define assert(cond) (void)((cond)?0:__assert_fail(#cond, __FILE__, __LINE__)) +#endif + +#endif diff --git a/src/libc/ctype.h b/src/libc/ctype.h new file mode 100644 index 00000000..8e30b9f8 --- /dev/null +++ b/src/libc/ctype.h @@ -0,0 +1,57 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * ctype.h + * + * Copyright (c) 2002-2004 PS2DEV + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: ctype.h 1095 2005-09-27 21:02:16Z jim $ + */ + +#ifndef __CTYPE_H__ +#define __CTYPE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +int isalnum(int); +int isalpha(int); +int iscntrl(int); +int isdigit(int); +int isgraph(int); +int islower(int); +int isprint(int); +int ispunct(int); +int isspace(int); +int isupper(int); +int isxdigit(int); +int tolower(int); +int toupper(int); + +#ifdef __cplusplus +} + + +/* To be compatible with C++'s ctype_base.h */ + +namespace std { + enum { + _U = 01, + _L = 02, + _N = 04, + _S = 010, + _P = 020, + _C = 040, + _X = 0100, + _B = 0200 + }; +}; +#endif + +#endif diff --git a/src/libc/cxx.cpp b/src/libc/cxx.cpp new file mode 100644 index 00000000..99b58e41 --- /dev/null +++ b/src/libc/cxx.cpp @@ -0,0 +1,50 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * cxx.cpp - Simple C++ memory allocation operators. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: cxx.cpp 339 2005-06-27 02:24:25Z warren $ + */ +#include +#include + +__attribute__((weak)) +void operator delete(void *ptr) +{ + if (ptr) + { + free(ptr); + } +} + +__attribute__((weak)) +void* operator new(size_t len) +{ + return malloc(len); +} + +__attribute__((weak)) +void operator delete[](void *ptr) +{ + ::operator delete(ptr); +} + +__attribute__((weak)) +void* operator new[](size_t len) +{ + return ::operator new(len); +} + +extern "C" +__attribute__((weak)) +void __cxa_pure_virtual() +{ + /* perror("Pure virtual method called"); */ + abort(); +} diff --git a/src/libc/init.c b/src/libc/init.c new file mode 100644 index 00000000..55915e07 --- /dev/null +++ b/src/libc/init.c @@ -0,0 +1,35 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * init.c - The global init/deinit code for our crt0. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: init.c 540 2005-07-08 19:35:10Z warren $ + */ +void _pspsdk_alloc_init(); +void _pspsdk_alloc_deinit(); +void _pspsdk_stdio_init(); +void _pspsdk_stdio_deinit(); +void _pspsdk_stdlib_init(); +void _pspsdk_stdlib_deinit(); + +__attribute__((weak, constructor)) +void _pspsdk_libc_init() +{ + _pspsdk_alloc_init(); + _pspsdk_stdio_init(); + _pspsdk_stdlib_init(); +} + +__attribute__((weak, destructor)) +void _pspsdk_libc_deinit() +{ + _pspsdk_stdlib_deinit(); + _pspsdk_stdio_deinit(); + _pspsdk_alloc_deinit(); +} diff --git a/src/libc/libcglue.c b/src/libc/libcglue.c new file mode 100644 index 00000000..a3aa2436 --- /dev/null +++ b/src/libc/libcglue.c @@ -0,0 +1,168 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * libcglue.c - Newlib-compatible system calls. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * Copyright (c) 2005 Jim Paris + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/* These functions aren't exposed in any public headers, and they probably don't need to be. */ +int sceKernelStdin(void); +int sceKernelStdout(void); +int sceKernelStderr(void); + +extern char * __psp_argv_0; +extern int __psp_cwd_initialized; +extern char __psp_cwd[MAXPATHLEN + 1]; +extern void __psp_init_cwd(void); +extern int __psp_path_absolute(const char *in, char *out, int len); + +/* If we're being built for PSPSDK's libc this function isn't defined. */ +#ifdef F_glue_gettimeofday +int gettimeofday(struct timeval *tp, void *tzp) +{ + return sceKernelLibcGettimeofday(tp, tzp); +} +#endif + +#if defined(F_clock) || defined(F_glue_clock) +clock_t clock(void) +{ + return sceKernelLibcClock(); +} +#endif + +#if defined(F_time) || defined(F_glue_time) +time_t time(time_t *t) +{ + return sceKernelLibcTime(t); +} +#endif + +/* PSP-compatible sbrk(). */ +#if defined(F__sbrk) || defined(F_glue__sbrk) + +#define DEFAULT_PRX_HEAP_SIZE_KB 64 + +/* If defined it specifies the desired size of the heap, in KB. */ +extern unsigned int sce_newlib_heap_kb_size __attribute__((weak)); +extern int __pspsdk_is_prx __attribute__((weak)); + +/* UID of the memory block that represents the heap. */ +static SceUID __psp_heap_blockid; + +void * _sbrk(ptrdiff_t incr) +{ + static void * heap_bottom = NULL; + static void * heap_top = NULL; + static void * heap_ptr = NULL; + + /* Has our heap been initialized? */ + if (heap_bottom == NULL) { + /* No, initialize the heap. */ + SceSize heap_size = (SceSize) -1; + + if (&sce_newlib_heap_kb_size != NULL) { + heap_size = sce_newlib_heap_kb_size; + } else if(&__pspsdk_is_prx != NULL) { + heap_size = DEFAULT_PRX_HEAP_SIZE_KB; + } + + if (heap_size == (unsigned int) -1) { + heap_size = sceKernelMaxFreeMemSize(); + } else { + heap_size *= 1024; + } + + if (heap_size != 0) { + __psp_heap_blockid = sceKernelAllocPartitionMemory(2, "block", PSP_SMEM_Low, heap_size, NULL); + if (__psp_heap_blockid > 0) { + heap_bottom = sceKernelGetBlockHeadAddr(__psp_heap_blockid); + heap_ptr = heap_bottom; + heap_top = (unsigned char *) heap_bottom + heap_size; + } + } + } + + void * heap_addr = (void *) -1; + void * next_heap_ptr = (void *) ((ptrdiff_t) heap_ptr + incr); + if ((heap_bottom != NULL) && (next_heap_ptr >= heap_bottom) && (next_heap_ptr < heap_top)) { + heap_addr = heap_ptr; + heap_ptr = next_heap_ptr; + } + + return heap_addr; +} + +/* Free the heap. */ +int __psp_free_heap(void) +{ + if (__psp_heap_blockid > 0) { + return sceKernelFreePartitionMemory(__psp_heap_blockid); + } + + return __psp_heap_blockid; +} +#endif + +#if defined(F__exit) || defined(F_glue__exit) +extern int sce_newlib_nocreate_thread_in_start __attribute__((weak)); + +extern int __psp_free_heap(void); + +void _exit(int status) +{ + if (&sce_newlib_nocreate_thread_in_start != NULL) { + /* Free the heap created by _sbrk(). */ + __psp_free_heap(); + + sceKernelSelfStopUnloadModule(1, 0, NULL); + } else { + if (status == 0) { + /* Free the heap created by _sbrk(). */ + __psp_free_heap(); + } + + sceKernelExitThread(status); + } + + while (1) ; +} +#endif + +/* newlib's errno.h wants a function that returns a pointer to errno. */ +#ifdef F_glue___errno +#undef errno + +int errno; + +/* TODO: Should this be made reentrant (wrapping interrupt disable/enable + around it should do it)? */ +int * __errno(void) +{ + return &errno; +} +#endif diff --git a/src/libc/malloc.h b/src/libc/malloc.h new file mode 100644 index 00000000..7cfb1353 --- /dev/null +++ b/src/libc/malloc.h @@ -0,0 +1,66 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * malloc.h + * + * Copyright (c) 2002-2004 PS2DEV + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: malloc.h 1095 2005-09-27 21:02:16Z jim $ + */ + +#ifndef _MALLOC_H +#define _MALLOC_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* stdlib/malloc */ +void * malloc(size_t size); +void * realloc(void *ptr, size_t size); +void * calloc(size_t n, size_t size); +void * memalign(size_t align, size_t size); +void free(void * ptr); + +/* Memory walkers. Used for debugging/profiling purposes. */ +void * __mem_walk_begin(void); +void __mem_walk_read(void * token, u32 * size, void ** ptr, int * valid); +void * __mem_walk_inc(void * token); +int __mem_walk_end(void * token); + +/* Example of use: + + void * i; + + for (i = __mem_walk_begin(); !__mem_walk_end(i); i = __mem_walk_inc(i)) { + u32 block_size; + void * block_ptr; + int valid; + + __mem_walk_read(i, &block_size, &block_ptr, &valid); + if (!valid) { + fprintf(stderr, "Block at token %p is invalid.\n", i); + break; + } + printf("Block at token %p points at a memory block of %i bytes at %p.\n", i, block_size, block_ptr); + } + + note that 'valid' will be always true if DEBUG_ALLOC was not defined when alloc.c got compiled. + +*/ + +#ifdef __cplusplus +} +#endif + +#endif // _MALLOC_H + diff --git a/src/libc/qsort.c b/src/libc/qsort.c new file mode 100644 index 00000000..120d76df --- /dev/null +++ b/src/libc/qsort.c @@ -0,0 +1,177 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * qsort.c - QSort algorithm implementation. + * + * Copyright (c) 1992, 1993 The Regents of the University of California. + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: qsort.c 540 2005-07-08 19:35:10Z warren $ + */ + + /*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +typedef int cmp_t(const void *, const void *); +static __inline char *med3(char *, char *, char *, cmp_t *, void *); +static __inline void swapfunc(char *, char *, int, int); + +#define min(a, b) (a) < (b) ? (a) : (b) + +/* + * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function". + */ +#define swapcode(TYPE, parmi, parmj, n) { \ + long i = (n) / sizeof (TYPE); \ + register TYPE *pi = (TYPE *) (parmi); \ + register TYPE *pj = (TYPE *) (parmj); \ + do { \ + register TYPE t = *pi; \ + *pi++ = *pj; \ + *pj++ = t; \ + } while (--i > 0); \ +} + +#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \ + es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1; + +static __inline void +swapfunc(char *a, char *b, int n, int swaptype) +{ + if(swaptype <= 1) + swapcode(long, a, b, n) + else + swapcode(char, a, b, n) +} + +#define swap(a, b) \ + if (swaptype == 0) { \ + long t = *(long *)(a); \ + *(long *)(a) = *(long *)(b); \ + *(long *)(b) = t; \ + } else \ + swapfunc(a, b, es, swaptype) + +#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype) + +#define CMP(t, x, y) (cmp((x), (y))) + +static __inline char * +med3(char *a, char *b, char *c, cmp_t *cmp, void *thunk +) +{ + return CMP(thunk, a, b) < 0 ? + (CMP(thunk, b, c) < 0 ? b : (CMP(thunk, a, c) < 0 ? c : a )) + :(CMP(thunk, b, c) > 0 ? b : (CMP(thunk, a, c) < 0 ? a : c )); +} + +#define thunk NULL +void +qsort(void *a, size_t n, size_t es, cmp_t *cmp) +{ + char *pa, *pb, *pc, *pd, *pl, *pm, *pn; + int d, r, swaptype, swap_cnt; + +loop: SWAPINIT(a, es); + swap_cnt = 0; + if (n < 7) { + for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es) + for (pl = pm; pl > (char *)a && CMP(thunk, pl - es, pl) > 0; + pl -= es) + swap(pl, pl - es); + return; + } + pm = (char *)a + (n / 2) * es; + if (n > 7) { + pl = a; + pn = (char *)a + (n - 1) * es; + if (n > 40) { + d = (n / 8) * es; + pl = med3(pl, pl + d, pl + 2 * d, cmp, thunk); + pm = med3(pm - d, pm, pm + d, cmp, thunk); + pn = med3(pn - 2 * d, pn - d, pn, cmp, thunk); + } + pm = med3(pl, pm, pn, cmp, thunk); + } + swap(a, pm); + pa = pb = (char *)a + es; + + pc = pd = (char *)a + (n - 1) * es; + for (;;) { + while (pb <= pc && (r = CMP(thunk, pb, a)) <= 0) { + if (r == 0) { + swap_cnt = 1; + swap(pa, pb); + pa += es; + } + pb += es; + } + while (pb <= pc && (r = CMP(thunk, pc, a)) >= 0) { + if (r == 0) { + swap_cnt = 1; + swap(pc, pd); + pd -= es; + } + pc -= es; + } + if (pb > pc) + break; + swap(pb, pc); + swap_cnt = 1; + pb += es; + pc -= es; + } + if (swap_cnt == 0) { /* Switch to insertion sort */ + for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es) + for (pl = pm; pl > (char *)a && CMP(thunk, pl - es, pl) > 0; + pl -= es) + swap(pl, pl - es); + return; + } + + pn = (char *)a + n * es; + r = min(pa - (char *)a, pb - pa); + vecswap(a, pb - r, r); + r = min(pd - pc, pn - pd - es); + vecswap(pb, pn - r, r); + if ((r = pb - pa) > es) + qsort(a, r / es, es, cmp); + if ((r = pd - pc) > es) { + /* Iterate rather than recurse to save stack space */ + a = pn - r; + n = r / es; + goto loop; + } +} diff --git a/src/libc/setjmp.S b/src/libc/setjmp.S new file mode 100644 index 00000000..5410c81f --- /dev/null +++ b/src/libc/setjmp.S @@ -0,0 +1,117 @@ +/* +# _____ ___ ____ ___ ____ +# ____| | ____| | | |____| +# | ___| |____ ___| ____| | \ PS2DEV Open Source Project. +#----------------------------------------------------------------------- +# Copyright 2001-2004, ps2dev - http://www.ps2dev.org +# Licenced under Academic Free License version 2.0 +# Review ps2sdk README & LICENSE files for further details. +# +# $Id: setjmp.S 486 2005-07-05 05:05:45Z mrbrown $ +# This is a simple version of setjmp and longjmp. +# Floating point support in. +*/ + +#include + +#define O_S0 0x00 +#define O_S1 0x04 +#define O_S2 0x08 +#define O_S3 0x0c +#define O_S4 0x10 +#define O_S5 0x14 +#define O_S6 0x18 +#define O_S7 0x1c +#define O_FP 0x20 +#define O_SP 0x24 +#define O_RA 0x28 +#define O_F20 0x2c +#define O_F21 0x30 +#define O_F22 0x34 +#define O_F23 0x38 +#define O_F24 0x3c +#define O_F25 0x40 +#define O_F26 0x44 +#define O_F27 0x48 +#define O_F28 0x4c +#define O_F29 0x50 +#define O_F30 0x54 +#define O_F31 0x58 + +/* int setjmp (jmp_buf); */ + .globl setjmp + .ent setjmp +setjmp: + .frame $sp,0,$31 + + sw $s0, O_S0($a0) + sw $s1, O_S1($a0) + sw $s2, O_S2($a0) + sw $s3, O_S3($a0) + sw $s4, O_S4($a0) + sw $s5, O_S5($a0) + sw $s6, O_S6($a0) + sw $s7, O_S7($a0) + sw $fp, O_FP($a0) + sw $sp, O_SP($a0) + sw $ra, O_RA($a0) + + swc1 $f20, O_F20($a0) + swc1 $f21, O_F21($a0) + swc1 $f22, O_F22($a0) + swc1 $f23, O_F23($a0) + swc1 $f24, O_F24($a0) + swc1 $f25, O_F25($a0) + swc1 $f26, O_F26($a0) + swc1 $f27, O_F27($a0) + swc1 $f28, O_F28($a0) + swc1 $f29, O_F29($a0) + swc1 $f30, O_F30($a0) + swc1 $f31, O_F31($a0) + + + move $v0, $0 + + jr $ra + + .end setjmp + +/* volatile void longjmp (jmp_buf, int); */ + .globl longjmp + .ent longjmp +longjmp: + .frame $sp,0,$31 + + lw $s0, O_S0($a0) + lw $s1, O_S1($a0) + lw $s2, O_S2($a0) + lw $s3, O_S3($a0) + lw $s4, O_S4($a0) + lw $s5, O_S5($a0) + lw $s6, O_S6($a0) + lw $s7, O_S7($a0) + lw $fp, O_FP($a0) + lw $sp, O_SP($a0) + lw $ra, O_RA($a0) + + lwc1 $f20, O_F20($a0) + lwc1 $f21, O_F21($a0) + lwc1 $f22, O_F22($a0) + lwc1 $f23, O_F23($a0) + lwc1 $f24, O_F24($a0) + lwc1 $f25, O_F25($a0) + lwc1 $f26, O_F26($a0) + lwc1 $f27, O_F27($a0) + lwc1 $f28, O_F28($a0) + lwc1 $f29, O_F29($a0) + lwc1 $f30, O_F30($a0) + lwc1 $f31, O_F31($a0) + + bne $a0, $0, 1f + li $a0, 1 +1: + move $v0, $a0 + + jr $ra + + .end longjmp diff --git a/src/libc/stdio.c b/src/libc/stdio.c new file mode 100644 index 00000000..92e5b7aa --- /dev/null +++ b/src/libc/stdio.c @@ -0,0 +1,1444 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * stdio.c - Simple standard C library implementation. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: stdio.c 2335 2007-11-06 07:47:36Z warren $ + */ +#include +#include +#include +#include +#include +#include +#include + +/* std I/O buffer type constants. */ +#define STD_IOBUF_TYPE_NONE 0 +#define STD_IOBUF_TYPE_GE 1 +#define STD_IOBUF_TYPE_MS 2 +#define STD_IOBUF_TYPE_UMD 4 +#define STD_IOBUF_TYPE_HOST 8 +#define STD_IOBUF_TYPE_STDOUTHOST 16 + +#define _NFILE 16 + +#define _IOEOF 0x0020 +#define _IOERR 0x0040 + +#define _IOREAD 0x0001 +#define _IOWRT 0x0002 +#define _IORW 0x0200 +#define _IOMYBUF 0x0010 + +/* ensure FILE is defined. */ +/* This is specific to psplibc, so we have to make sure it doesn't conflict with + newlib's FILE definition. */; +/* +#ifndef __FILE_DEFINED +#define __FILE_DEFINED +*/ +typedef struct { + int type; + int fd; + int cnt; + int flag; + int has_putback; + u8 putback; +} __psplibc_FILE; +//#endif // __FILE_DEFINED + +/* Override newlib's definition of a FILE. */ +#define LOCAL_FILE(f) ((__psplibc_FILE *) (f)) + +extern FILE __iob[_NFILE]; + +/* Don't pull in macros from newlib's ctype.h that we don't support. */ +int isdigit(int); + +#ifdef F_clearerr +/* Get rid of the newlib macro definition. */ +#ifdef clearerr +#undef clearerr +#endif +/* +** +** [func] - clearerr. +** [desc] - clears the stream file stream error condition. +** [entr] - FILE *stream; the pointer to the FILE stream. +** [exit] - none. +** [prec] - stream is a valid FILE pointer. +** [post] - the stream file stream error condition is cleared. +** +*/ +void clearerr(FILE *stream) +{ + LOCAL_FILE(stream)->flag &= (~_IOERR); +} +#endif + + +#ifdef F_fclose +/* +** +** [func] - fclose. +** [desc] - if stream is a valid FILE stream and able to close the stream file +** then returns 0. else returns EOF. +** [entr] - FILE *stream; the pointer to the FILE stream. +** [exit] - int; 0 if able to close the stream file. else EOF. +** [prec] - stream is a valid FILE pointer. +** [post] - the stream file is closed. +** +*/ +int fclose(FILE *stream) +{ + int ret; + + /* test the file stream type. */ + switch(LOCAL_FILE(stream)->type) { + case STD_IOBUF_TYPE_NONE: + case STD_IOBUF_TYPE_GE: + case STD_IOBUF_TYPE_STDOUTHOST: + /* cannot close stdin, stdout, or stderr. */ + // duh.. this is wrong. One SHOULD be able to close + // std*. That's a common unix doing. However, I doubt + // allowing this madness could be a good idea. + ret = EOF; + break; + default: + if ((LOCAL_FILE(stream)->fd >= 0) && (sceIoClose(LOCAL_FILE(stream)->fd) >= 0)) { + LOCAL_FILE(stream)->type = STD_IOBUF_TYPE_NONE; + LOCAL_FILE(stream)->fd = -1; + LOCAL_FILE(stream)->cnt = 0; + LOCAL_FILE(stream)->flag = 0; + ret = 0; + } + else ret = EOF; + } + return (ret); +} +#endif + + +#ifdef F_fcloseall +/* +** +** [func] - fcloseall. +** [desc] - attempts to close all the open files. if able to close all the open +** files then returns the number of files closed. else returns -1. +** [entr] - none. +** [exit] - int; the number of files closed if successful. else -1. +** [prec] - none. +** [post] - all open non-system files are closed. +** +*/ +int fcloseall(void) +{ + int i, ret = 0; + FILE *iob; + + /* process all open files except for stdout, stdin and stderr. */ + for (i = 3, iob = &__iob[3]; i < _NFILE; ++i, ++iob) { + if (LOCAL_FILE(iob)->fd >= 0) { + /* attempt to close the current file. */ + if ((fclose(iob) == 0) && (ret >= 0)) ++ret; + else ret = EOF; + } + } + return (ret); +} +#endif + + +#ifdef F_feof +/* Get rid of the newlib macro definition. */ +#ifdef feof +#undef feof +#endif +/* +** +** [func] - feof. +** [desc] - if the stream file stream has reached the end of the file then +** returns non-zero. else returns 0. +** [entr] - FILE *stream; the pointer to the FILE stream. +** [exit] - int; non-zero if the stream file has reached EOF. else 0. +** [prec] - stream is a valid FILE pointer. +** [post] - none. +** +*/ +int feof(FILE *stream) +{ + return ((LOCAL_FILE(stream)->flag & _IOEOF) != 0); +} +#endif + + +#ifdef F_ferror +/* Get rid of the newlib macro definition. */ +#ifdef ferror +#undef ferror +#endif +/* +** +** [func] - ferror. +** [desc] - if an error has occured for the stream file stream then returns +** non-zero. else returns 0. +** [entr] - FILE *stream; the pointer to the FILE stream. +** [exit] - int; non-zero if error has occured for the stream file. else 0. +** [prec] - stream is a valid FILE pointer. +** [post] - none. +** +*/ +int ferror(FILE *stream) +{ + return ((LOCAL_FILE(stream)->flag & _IOERR) != 0); +} +#endif + + +#ifdef F_fflush +int mcFlush(int fd); +int mcSync(int mode, int *cmd, int *result); + +/* +** +** [func] - fflush. +** [desc] - if the stream file is opened as read-only then returns 0. else +** if stream is a valid FILE stream and able to flush the stream +** file write buffer then returns 0. else returns EOF. +** [entr] - FILE *stream; the pointer to the FILE stream. +** [exit] - int; 0 if able to flush the write buffer or file is read-only. else EOF. +** [prec] - stream is a valid FILE pointer. +** [post] - the stream FILE stream write buffer is flushed. +** +*/ +int fflush(FILE *stream) +{ + int ret = EOF; // Same as default case below. + + switch(LOCAL_FILE(stream)->type) { + case STD_IOBUF_TYPE_GE: + case STD_IOBUF_TYPE_STDOUTHOST: + /* stdout & stderr are never buffered. */ + case STD_IOBUF_TYPE_UMD: + /* cd-rom files are read-only so no write buffer to flush. */ + ret = 0; + break; + case STD_IOBUF_TYPE_MS: + if (LOCAL_FILE(stream)->flag & (_IOWRT | _IORW)) { + //if (ret != 0) ret = EOF; + /* Need to implement sync or something */ + } + else ret = 0; + break; + case STD_IOBUF_TYPE_HOST: + /* flush host file write buffer. */ + if (LOCAL_FILE(stream)->flag & (_IOWRT | _IORW)) ret = 0; + else ret = 0; + break; + default: + /* unknown/invalid I/O buffer type. */ + ret = EOF; + } + return (ret); +} +#endif + + +#ifdef F_fflushall +/* +** +** [func] - _fcloseall. +** [desc] - attempts to flush all the open files with write-access. if able +** to flush all the open files with write-access then returns the +** number of files flushed. else returns -1. +** [entr] - none. +** [exit] - int; the number of files flushed if successful. else -1. +** [prec] - none. +** [post] - all open non-system files with write-access are flushed. +** +*/ +int _fflushall(void) +{ + int i, ret = 0; + FILE *iob; + + /* process all open files except for stdout, stdin and stderr. */ + for (i = 3, iob = &__iob[3]; i < _NFILE; ++i, ++iob) { + if (LOCAL_FILE(iob)->fd >= 0) { + /* attempt to flush the current file. */ + if ((fflush(iob) == 0) && (ret >= 0)) ++ret; + else ret = EOF; + } + } + return (ret); +} +#endif + + +#ifdef F_fgetc +/* +** +** [func] - fgetc. +** [desc] - attempts to read one character from the stream file. if able to +** read one character from the file then returns the chaaracter +** read. else EOF. +** [entr] - FILE *stream; the pointer to the FILE stream. +** [exit] - int; the character read from the stream file. else -1. +** [prec] - stream is a valid FILE pointer. +** [post] - the stream file is modified. +** +*/ +int fgetc(FILE *stream) +{ + char c; + int ret; + + if (LOCAL_FILE(stream)->has_putback) { + LOCAL_FILE(stream)->has_putback = 0; + return LOCAL_FILE(stream)->putback; + } + + switch(LOCAL_FILE(stream)->type) { + case STD_IOBUF_TYPE_GE: + case STD_IOBUF_TYPE_STDOUTHOST: + /* cannot read from stdout or stderr. */ + ret = EOF; + break; + default: + ret = ((fread(&c, 1, 1, stream) == 1) ? (int)c : EOF); + } + return (ret); +} +#endif + + +#ifdef F_fgetpos +/* +** +** [func] - fgetpos. +** [desc] - attempts to retrieve the stream file stream pointer position. +** if able to retrieve the stream file stream pointer position +** then stores the position to pos and returns 0. else returns -1. +** [entr] - FILE *stream; the pointer to the file stream. +** fpos_t *pos; the pointer to the destination file position buffer. +** [exit] - int; 0 if able to retrieve the stream file pointer position. else -1. +** [prec] - stream is a valid FILE pointer and pos is a valid fpos_t pointer. +** [post] - the memory pointed to by pos is modified. +** +*/ +int fgetpos(FILE *stream, fpos_t *pos) +{ + long n; + + if ((n = ftell(stream)) >= 0) *pos = (fpos_t)n; + return ((n >= 0) ? 0 : -1); +} + +int fgetpos64(FILE *stream, int64_t *pos) +{ + int64_t n; + + if ((n = ftello64(stream)) >= 0) *pos = n; + return ((n >= 0) ? 0 : -1); +} +#endif + + +#ifdef F_fgets +/* +** +** [func] - fgets. +** [desc] - attempts to read a string from the stream file. if able to read +** a string from the stream file stdin then stores the string up to +** n characters to the memory pointed by buf and returns buf. else +** returns NULL. +** [entr] - char *buf; the pointer to the destination string buffer. +** int n; the maximum number of characters to write to buf. +** FILE *stream; the pointer to the FILE stream. +** [exit] - char *; buf if the string is read successfully. else NULL. +** [prec] - buf is a valid memory pointer of n size in bytes and stream is a +** valid FILE pointer. +** [post] - the memory pointed to by buf is modified and the stream file +** pointer is modified. +** +*/ +char *fgets(char *buf, int n, FILE *stream) +{ + char *ret = buf; + int c, done; + + switch(LOCAL_FILE(stream)->type) { + case STD_IOBUF_TYPE_GE: + case STD_IOBUF_TYPE_STDOUTHOST: + /* cannot read from stdout or stderr. */ + ret = NULL; + break; + default: + for (done = 0; (!done); ) { + switch(c = fgetc(stream)) { + case '\r': + case '\n': + if (n > 0) { + /* newline terminates fgets. */ + *buf++ = '\0'; + --n; + done = 1; + break; + } + break; + case EOF: + /* end of file or error. */ + ret = NULL; + done = 1; + break; + default: + if (n > 0) { + /* store the current character to buf. */ + *buf++ = (char)c; + --n; + } + } + } + } + return (ret); +} +#endif + + +#ifdef F_fopen +/* std I/O internal function. */ +int __stdio_get_fd_type(const char *); + +/* +** +** [func] - fopen. +** [desc] - attempts to open the fname file using the mode file mode. if able +** open the fname then returns the pointer to the FILE stream. else +** returns NULL. +** [entr] - const char *fname; the filename string pointer. +** const char *mode; the file mode string pointer. +** [exit] - FILE *; the pointer the fname FILE stream. else NULL. +** [prec] - fname and mode are valid string pointers. +** [post] - the fname file is opened. +** +*/ +FILE *fopen(const char *fname, const char *mode) +{ + FILE *ret = NULL; + int fd, flag = 0, i, iomode = 0; + + /* ensure file name and mode are not NULL strings. */ + if ((fname != NULL) && (*fname != '\0')) { + if ((mode != NULL) && (*mode != '\0')) { + /* test the file mode. */ + switch(*mode++) { + case 'r': + flag = _IOREAD; + iomode = PSP_O_RDONLY; + break; + case 'w': + flag = _IOWRT; + iomode = (PSP_O_WRONLY | PSP_O_CREAT); + break; + case 'a': + flag = _IORW; + iomode = PSP_O_APPEND; + break; + } + /* test the extended file mode. */ + for (; (*mode++ != '\0'); ) { + switch(*mode) { + case 'b': + continue; + case '+': + flag |= (_IOREAD | _IOWRT); + iomode |= (PSP_O_RDWR | PSP_O_CREAT | PSP_O_TRUNC); + continue; + default: + break; + } + } + /* search for an available fd slot. */ + for (i = 2; i < _NFILE; ++i) if (LOCAL_FILE(&__iob[i])->fd < 0) break; + if (i < _NFILE) { + /* attempt to open the fname file. */ + if ((fd = sceIoOpen((char *)fname, iomode, 0777)) >= 0) { + LOCAL_FILE(&__iob[i])->type = __stdio_get_fd_type(fname); + LOCAL_FILE(&__iob[i])->fd = fd; + LOCAL_FILE(&__iob[i])->cnt = 0; + LOCAL_FILE(&__iob[i])->flag = flag; + LOCAL_FILE(&__iob[i])->has_putback = 0; + ret = (__iob + i); + } + } + } + } + return (ret); +} + +FILE *fopen64(const char *fname, const char *mode) { + return fopen(fname, mode); +} + +#endif + +#ifdef F_fdopen +/* +** +** [func] - fdopen. +** [desc] - produces a file descriptor of type `FILE *', from a +** descriptor for an already-open file (returned, for +** example, by the system subroutine `open' rather than by `fopen'). +** The MODE argument has the same meanings as in `fopen'. +** [entr] - int fd; file descriptor returned by 'open'. +** const char *mode; the file mode string pointer. +** [exit] - file pointer or `NULL', as for `fopen'. +** +*/ +FILE *fdopen(int fd, const char *mode) +{ + FILE *ret = NULL; + int flag = 0, i, iomode = 0; + + /* ensure valid descriptor, and that mode is not a NULL string. */ + if (fd >= 0) { + if ((mode != NULL) && (*mode != '\0')) { + /* test the file mode. */ + switch(*mode++) { + case 'r': + flag = _IOREAD; + iomode = PSP_O_RDONLY; + break; + case 'w': + flag = _IOWRT; + iomode = (PSP_O_WRONLY | PSP_O_CREAT); + break; + case 'a': + flag = _IORW; + iomode = PSP_O_APPEND; + break; + } + /* test the extended file mode. */ + for (; (*mode++ != '\0'); ) { + switch(*mode) { + case 'b': + continue; + case '+': + flag |= (_IOREAD | _IOWRT); + iomode |= (PSP_O_RDWR | PSP_O_CREAT | PSP_O_TRUNC); + continue; + default: + break; + } + } + /* search for an available fd slot. */ + for (i = 2; i < _NFILE; ++i) if (LOCAL_FILE(&__iob[i])->fd < 0) break; + if (i < _NFILE) { + /* attempt to open the fname file. */ + LOCAL_FILE(&__iob[i])->type = STD_IOBUF_TYPE_NONE; + LOCAL_FILE(&__iob[i])->fd = fd; + LOCAL_FILE(&__iob[i])->cnt = 0; + LOCAL_FILE(&__iob[i])->flag = flag; + LOCAL_FILE(&__iob[i])->has_putback = 0; + ret = (__iob + i); + } + } + } + return (ret); +} +#endif + +#ifdef F_fileno +int fileno(FILE * f) { + return LOCAL_FILE(f)->fd; +} +#endif + +#ifdef F_fputc +/* +** +** [func] - fputc. +** [desc] - attempts to write the c character to the stream file. if able to +** write the character to the stream file then returns the character +** written. else returns -1. +** [entr] - int c; the character to write to the file. +** FILE *stream; the pointer to the FILE stream. +** [exit] - int; the character written to the file if successful. else -1. +** [prec] - stream is a valid FILE pointer. +** [post] - the stream file is modified. +** +*/ +int fputc(int c, FILE *stream) +{ + char ch; + + ch = (char)c; + return ((fwrite(&ch, 1, 1, stream) == 1) ? 0 : EOF); +} +#endif + + +#ifdef F_fputs +/* +** +** [func] - fputs. +** [desc] - attempts to write the s string to the stream file. if able to +** successfully write the string to the stream file then returns +** the number of characters written to the file. else returns -1. +** [entr] - const char *s; the source string pointer. +** [exit] - int; the number of chars. written to file if successful. else -1. +** [prec] - stream is a valid FILE pointer and s is a valid string pointer. +** [post] - the stream file is modified. +** +*/ +int fputs(const char *s, FILE *stream) +{ + size_t len; + + int temp = strlen(s); + + len = ((fwrite(s, 1, temp, stream) == temp) ? temp : EOF); + + if (len != EOF) { + fputc('\n', stream); + } + return len + 1; +} +#endif + + +#ifdef F_fread +/* +** +** [func] - fread. +** [desc] - attempts to read n number of records of r size to the stream file +** and returns the number of records successfully read from the file. +** [entr] - void *buf; the pointer to the destination data buffer. +** size_t r; the size of the records to read. +** size_t n; the number of records to read. +** FILE *stream; the pointer to the FILE stream. +** [exit] - size_t; the number of records successfully read from the stream file. +** [prec] - buf is a valid memory pointer of (r * n) size in bytes and stream +** is a valid FILE pointer. +** [post] - the stream file is modified. +** +*/ +size_t fread(void *buf, size_t r, size_t n, FILE *stream) +{ + size_t ret; + + switch(LOCAL_FILE(stream)->type) { + case STD_IOBUF_TYPE_NONE: + case STD_IOBUF_TYPE_GE: + case STD_IOBUF_TYPE_STDOUTHOST: + /* cannot read from stdout or stderr. */ + ret = 0; + break; + default: + /* attempt to read from the stream file. */ + ret = (sceIoRead(LOCAL_FILE(stream)->fd, buf, (int)(r * n)) / (int)r); + } + return (ret); +} +#endif + + +#ifdef F_fseek + +/* +** +** [func] - fseek. +** [desc] - attempts to seek the stream file pointer to offset from origin. +** if able to seek the stream file pointer to offset from origin +** returns 0. else returns -1. +** [entr] - FILE *stream; the pointer to the FILE stream. +** long offset; the seek offset. +** int origin; the seek origin. +** [exit] - int; 0 if able to seek to offset from origin successfully. else -1. +** [prec] - stream is a valid FILE pointer and origin is a valid seek origin +** type. +** [post] - the stream file pointer position is modified. +** +*/ +int fseeko64(FILE *stream, int64_t offset, int origin) +{ + int ret; + + switch(LOCAL_FILE(stream)->type) { + case STD_IOBUF_TYPE_NONE: + case STD_IOBUF_TYPE_GE: + case STD_IOBUF_TYPE_STDOUTHOST: + /* cannot seek stdout or stderr. */ + ret = -1; + break; + default: + /* attempt to seek to offset from origin. */ + ret = ((sceIoLseek(LOCAL_FILE(stream)->fd, offset, origin) >= 0) ? 0 : -1); + } + return (ret); +} + +int fseek(FILE *stream, long offset, int origin) +{ + return fseeko64(stream, (int64_t)offset, origin); +} +#endif + + +#ifdef F_fsetpos +/* +** +** [func] - fsetpos. +** [desc] - attempts to set the stream file pointer position to the pos offset. +** if able to set the stream file pointer position to pos then returns +** 0. else returns -1. +** [entr] - FILE *stream; the pointer to the FILE stream. +** const fpos_t *pos; the pointer to the source file position buffer. +** [exit] - 0 if able to set the stream file pointer position. else -1. +** [prec] - stream is a valid FILE pointer and pos is a valid fpos_t pointer. +** [post] - the stream file pointer position is modified. +** +*/ +int fsetpos(FILE *stream, const fpos_t *pos) +{ + return (fseek(stream, (long)*pos, SEEK_SET)); +} +#endif + + +#ifdef F_ftell +/* +** +** [func] - ftell. +** [desc] - attempts to retrieve the stream file stream pointer position. +** if able to retrieve the stream file stream pointer position +** then returns the position. else sets error code and returns -1. +** [entr] - FILE *stream; the pointer to the FILE stream. +** [exit] - long; the stream file pointer position if successful. else -1. +** [prec] - stream is a valid FILE pointer. +** [post] - none. +** +*/ +long ftell(FILE *stream) +{ + long n, ret; + + switch(LOCAL_FILE(stream)->type) { + case STD_IOBUF_TYPE_NONE: + case STD_IOBUF_TYPE_GE: + case STD_IOBUF_TYPE_STDOUTHOST: + /* stdout or stderr is an invalid seek stream argument. */ + errno = EINVAL; + ret = -1L; + break; + default: + if (LOCAL_FILE(stream)->fd < 0) { + /* file is not open. */ + errno = EBADF; + ret = -1L; + } + else ret = (((n = sceIoLseek(LOCAL_FILE(stream)->fd, 0, SEEK_CUR)) >= 0) ? (long)n : -1L); + } + return (ret); +} + +int64_t ftello64(FILE *stream) +{ + int64_t n, ret; + + switch(LOCAL_FILE(stream)->type) { + case STD_IOBUF_TYPE_NONE: + case STD_IOBUF_TYPE_GE: + case STD_IOBUF_TYPE_STDOUTHOST: + /* stdout or stderr is an invalid seek stream argument. */ + errno = EINVAL; + ret = -1L; + break; + default: + if (LOCAL_FILE(stream)->fd < 0) { + /* file is not open. */ + errno = EBADF; + ret = -1L; + } + else ret = (((n = sceIoLseek(LOCAL_FILE(stream)->fd, 0, SEEK_CUR)) >= 0) ? (int64_t)n : -1); + } + return (ret); +} +#endif + + +#ifdef F_fwrite +/* +** +** [func] - fwrite. +** [desc] - attempts to write n number of records of r size to the stream file +** and returns the number of records successfully written to the file. +** [entr] - const void *buf; the pointer to the source data buffer. +** size_t r; the size of the records to write. +** size_t n the number of records to write. +** FILE *stream; the pointer to the FILE stream. +** [exit] - size_t; the number of records successfully written to the stream file. +** [prec] - buf is a valid memory pointer of (r * n) size in bytes and stream +** is a valid FILE pointer. +** [post] - the stream file is modified. +** +*/ +size_t fwrite(const void *buf, size_t r, size_t n, FILE *stream) +{ + size_t ret; + + /* attempt to write the stream file. */ + //ret = (sceIoWrite(stream->fd, (void *)buf, (int)(r * n)) / (int)r); + ret = (sceIoWrite(LOCAL_FILE(stream)->fd, (void *)buf, (int)(r * n)) / (int) r); + + return (ret); +} +#endif + + +#ifdef F_getc +/* Get rid of the newlib macro definition. */ +#ifdef getc +#undef getc +#endif +/* +** +** [func] - getc. +** [desc] - attempts to read one character from the stream file. if able to +** read one character from the file then returns the chaaracter +** read. else EOF. +** [entr] - FILE *stream; the pointer to the FILE stream. +** [exit] - int; the character read from the stream file. else -1. +** [prec] - stream is a valid FILE pointer. +** [post] - the stream file is modified. +** +*/ +int getc(FILE *stream) +{ + char c; + int ret; + + switch(LOCAL_FILE(stream)->type) { + case STD_IOBUF_TYPE_NONE: + case STD_IOBUF_TYPE_GE: + case STD_IOBUF_TYPE_STDOUTHOST: + /* cannot read from stdout or stderr. */ + ret = EOF; + break; + default: + ret = ((fread(&c, 1, 1, stream) == 1) ? (int)c : EOF); + } + return (ret); +} +#endif + + +#ifdef F_getchar +/* Get rid of the newlib macro definition. */ +#ifdef getchar +#undef getchar +#endif +/* We can't use the macro version of getc provided in newlib's stdio.h. */ +#ifdef getc +#undef getc +#endif +/* +** +** [func] - getchar. +** [desc] - attempts to read one character from the stdin file stream. if able +** to read one character from the stdin file stream then returns the +** character read. else returns -1. +** [entr] - none. +** [exit] - int; the character read from stdin if successful. else -1. +** [prec] - none. +** [post] - the stdin file stream is modified. +** +*/ +int getchar(void) +{ + return (getc(stdin)); +} +#endif + + +#ifdef F_getfdtype +/* the present working directory variable. */ +#if 0 +char __direct_pwd[256]; +#endif + +/* +** +** [func] - __stdio_get_fd_type. +** [desc] - if s or the present working directory begins with a valid file +** device name then returns the corresponding file descriptor type. +** else returns -1. +** [entr] - const char *s; the source string pointer. +** [exit] - int; the device name file descriptor type if determined. else -1. +** [prec] - s is a valid string pointer. +** [post] - none. +** +*/ +int __stdio_get_fd_type(const char *s) +{ + return (-1); +} +#endif + + +#ifdef F_gets +/* +** +** [func] - gets. +** [desc] - attempts to read a string from stdin. if able to read a string +** from stdin then stores the string to the memory pointed by buf +** and returns buf. else returns NULL. +** [entr] - char *buf; the pointer to the destination string buffer. +** [exit] - char *; buf if string is read successfully. else NULL. +** [prec] - buf is a valid memory pointer. +** [post] - the memory pointed to by buf is modified. +** +*/ +char *gets(char *buf) +{ + return (fgets(buf, INT_MAX, stdin)); +} +#endif + + +#ifdef F_strerror +static const char * file_errors[] = { +"", // 0 +"Not super-user", // 1 +"No such file or directory", // 2 +"No such process", // 3 +"Interrupted system call", // 4 +"I/O error", // 5 +"No such device or address", // 6 +"Arg list too long", // 7 +"Exec format error", // 8 +"Bad file number", // 9 +"No children", // 10 +"No more processes", // 11 +"Not enough core", // 12 +"Permission denied", // 13 +"Bad address", // 14 +"Block device required", // 15 +"Mount device busy", // 16 +"File exists", // 17 +"Cross-device link", // 18 +"No such device", // 19 +"Not a directory", // 20 +"Is a directory", // 21 +"Invalid argument", // 22 +"Too many open files in system", // 23 +"Too many open files", // 24 +"Not a typewriter", // 25 +"Text file busy", // 26 +"File too large", // 27 +"No space left on device", // 28 +"Illegal seek", // 29 +"Read only file system", // 30 +"Too many links", // 31 +"Broken pipe", // 32 +"Math arg out of domain of func", // 33 +"Math result not representable", // 34 +"No message of desired type", // 35 +"Identifier removed", // 36 +"Channel number out of range", // 37 +"Level 2 not synchronized", // 38 +"Level 3 halted", // 39 +"Level 3 reset", // 40 +"Link number out of range", // 41 +"Protocol driver not attached", // 42 +"No CSI structure available", // 43 +"Level 2 halted", // 44 +"Deadlock condition", // 45 +"No record locks available", // 46 +"", // 47 +"", // 48 +"", // 49 +"Invalid exchange", // 50 +"Invalid request descriptor", // 51 +"Exchange full", // 52 +"No anode", // 53 +"Invalid request code", // 54 +"Invalid slot", // 55 +"File locking deadlock error", // 56 +"Bad font file fmt", // 57 +"", // 58 +"", // 59 +"Device not a stream", // 60 +"No data (for no delay io)", // 61 +"Timer expired", // 62 +"Out of streams resources", // 63 +"Machine is not on the network", // 64 +"Package not installed", // 65 +"The object is remote", // 66 +"The link has been severed", // 67 +"Advertise error", // 68 +"Srmount error", // 69 +"Communication error on send", // 70 +"Protocol error", // 71 +"", // 72 +"", // 73 +"Multihop attempted", // 74 +"Inode is remote (not really error)", // 75 + + +"Cross mount point (not really error)", // 76 +"Trying to read unreadable message", // 77 +"", // 78 +"Inappropriate file type or format", // 79 +"Given log. name not unique", // 80 +"f.d. invalid for this operation", // 81 +"Remote address changed", // 82 +"Can't access a needed shared lib", // 83 +"Accessing a corrupted shared lib", // 84 +".lib section in a.out corrupted", // 85 +"Attempting to link in too many libs", // 86 +"Attempting to exec a shared library", // 87 +"Function not implemented", // 88 +"No more files", // 89 +"Directory not empty", // 90 +"File or path name too long", // 91 +"Too many symbolic links", // 92 +"", // 93 +"", // 94 +"Operation not supported on transport endpoint", // 95 +"Protocol family not supported", // 96 +"", // 97 +"", // 98 +"", // 99 +"", // 100 +"", // 101 +"", // 102 +"", // 103 +"Connection reset by peer", // 104 +"No buffer space available", // 105 +"Address family not supported by protocol family", // 106 +"Protocol wrong type for socket", // 107 +"Socket operation on non-socket", // 108 +"Protocol not available", // 109 +"Can't send after socket shutdown", // 110 +"Connection refused", // 111 +"Address already in use", // 112 +"Connection aborted", // 113 +"Network is unreachable", // 114 +"Network interface is not configured", // 115 +"Connection timed out", // 116 +"Host is down", // 117 +"Host is unreachable", // 118 +"Connection already in progress", // 119 +"Socket already connected", // 120 +"Destination address required", // 121 +"Message too long", // 122 +"Unknown protocol", // 123 +"Socket type not supported", // 124 +"Address not available", // 125 +"", // 126 +"Socket is already connected", // 127 +"Socket is not connected", // 128 +"", // 129 +"EPROCLIM", // 130 +"EUSERS", // 131 +"EDQUOT", // 132 +"ESTALE", // 133 +"Not supported", // 134 +"No medium (in tape drive)", // 135 +"No such host or network path", // 136 +"Filename exists with different case", // 137 +"EILSEQ", // 138 +"Value too large for defined data type", // 139 +""}; +#define error_to_string(errnum) (file_errors[errnum*-1]) + +char * strerror(int err) { + return (char *) error_to_string(err); +} +#endif + + +#ifdef F_perror +/* +** +** [func] - perror. +** [desc] - if there is a current error then prints the corresponding error +** and then prints s to stderr. else prints s to stderr. +** [entr] - const char *s; the error string pointer. +** [exit] - none. +** [prec] - s is a valid string pointer. +** [post] - none. +** +*/ +void perror(const char *s) +{ + char *err; + + /* print to stderr output. */ + if ((err = strerror(errno)) != NULL) fprintf(stderr, "%s : ", err); + fputs(s, stderr); +} +#endif + + +#ifdef F_putc +/* Get rid of the newlib macro definition. */ +#ifdef putc +#undef putc +#endif +/* std I/O data variable. */ +#ifdef USE_GS +extern int __stdio_stdout_xy[2]; + + +/* stdio internal function. */ +void __stdio_update_stdout_xy(int, int); +#endif + +/* +** +** [func] - putc. +** [desc] - attempts to write the c character to the stream file. if able to +** write the character to the stream file then returns the character +** written. else returns -1. +** [entr] - int c; the character to write to the file. +** FILE *stream; the pointer to the FILE stream. +** [exit] - int; the character written to the file if successful. else -1. +** [prec] - stream is a valid FILE pointer. +** [post] - the stream file is modified. +** +*/ +int putc(int c, FILE *stream) +{ + char ch; + int ret = 0; + + switch(LOCAL_FILE(stream)->type) { + break; + default: + /* write one character to the stream file. */ + ch = (char)c; + ret = ((fwrite(&ch, 1, 1, stream) == 1) ? c : EOF); + } + return (ret); +} +#endif + + +#ifdef F_putchar +/* We can't use the macro version of putc provided in newlib's stdio.h. */ +#ifdef putc +#undef putc +#endif +/* +** +** [func] - putchar. +** [desc] - attempts to write the c character to stdout. if able to write +** the character to stdout then returns the character written. +** else returns -1. +** [entr] - int c; the character to write to stdout. +** [exit] - int; the character written to stdout. else -1. +** [prec] - none. +** [post] - the stdout file stream is modified. +** +*/ +int putchar(int c) +{ + return (putc(c, stdout)); +} +#endif + + +#ifdef F_puts +/* We can't use the macro version of putc provided in newlib's stdio.h. */ +#ifdef putc +#undef putc +#undef putchar +#endif +/* +** +** [func] - puts. +** [desc] - attempts to write the s string to stdout. if able to write the s +** string to stdout then returns the number of characters written. +** else returns -1. +** [entr] - const char *s; the source string pointer. +** [exit] - int; the number of characters written to stdout. else -1. +** [prec] - s is a valid string pointer. +** [post] - the stdout file stream is modified. +** +*/ +int puts(const char *s) +{ + int ret; + + for (ret = 0; (*s != '\0'); ++s) { + /* attempt to print the current character to stdout. */ + if ((putchar(*s) == (int)*s) && (ret >= 0)) ++ret; + else ret = EOF; + } + if ((putchar('\n') == '\n') && (ret >= 0)) ++ret; + else ret = EOF; + return (ret); +} +#endif + + +#ifdef F_remove +/* +** +** [func] - remove. +** [desc] - if the s named file exists then deletes the s named file and +** returns 0. else returns -1. +** [entr] - const char *s; the filename string pointer. +** [exit] - int; 0 if able to delete the s file. else -1. +** [prec] - s is a valid string pointer. +** [post] - the s file is deleted. +** +*/ +int remove(const char *s) +{ + int ret = sceIoRemove(s); + + return (ret); +} +#endif + + +#ifdef F_rename +/* +** +** [func] - rename. +** [desc] - +** [entr] - const char *name; the filename string pointer. +** const char *newname; the new filename string pointer. +** [exit] - int; +** [prec] - name and newname are valid string pointers. +** [post] - the name filen name is modified. +** +*/ +int rename(const char *name, const char *newname) +{ + int ret = sceIoRename(name, newname); + + return (ret); +} +#endif + + +#ifdef F_rewind +/* +** +** [func] - rewind. +** [desc] - resets the stream file pointer to 0. +** [entr] - FILE *stream; the pointer to the FILE stream. +** [exit] - none. +** [prec] - stream is a valid FILE pointer. +** [post] - the stream file pointer is modified. +** +*/ +void rewind(FILE *stream) +{ + fseek(stream, 0, SEEK_SET); +} +#endif + + +#ifdef F_skipatoi +/* +** +** [func] - __stdio_skip_atoi. +** [desc] - +** [entr] - const char **s; the pointer to the source string pointer. +** [exit] - int; +** [prec] - s is a valid pointer to string pointer. +** [post] - the memory pointed to by s is modified. +** +*/ +int __stdio_skip_atoi(const char **s) +{ + int ret = 0; + + for (; (isdigit(**s) != 0); ) ret = ((ret * 10) + (*((*s)++) - '0')); + return (ret); +} +#endif + +//Do not uncomment until vsscanf is implemented - Warren +//#ifdef F_sscanf +/* +** +** [func] - sscanf. +** [desc] - +** [entr] - const char *buf; +** const char *format; the format string pointer. +** ...; +** [exit] - int; +** [prec] - buf and format are valid string pointers. +** [post] - the memory pointed to by format string arguments are +** +*/ +/* +int sscanf(const char *buf, const char *format, ...) +{ + int ret; + va_list va; + + va_start(va, format); + ret = vsscanf(buf, format, va); + va_end(va); + return (ret); +}*/ +//#endif + + +#ifdef F__stdio +/* stdio data variables. */ +FILE __iob[_NFILE] = { + { -1, 0, 0, 0 }, // stdin + { STD_IOBUF_TYPE_STDOUTHOST, 1, 0, 0 }, // stdout + { STD_IOBUF_TYPE_STDOUTHOST, 2, 0, 0 }, // stdout + { 0, -1, 0, 0 }, + { 0, -1, 0, 0 }, + { 0, -1, 0, 0 }, + { 0, -1, 0, 0 }, + { 0, -1, 0, 0 }, + { 0, -1, 0, 0 }, + { 0, -1, 0, 0 }, + { 0, -1, 0, 0 }, + { 0, -1, 0, 0 }, + { 0, -1, 0, 0 }, + { 0, -1, 0, 0 }, + { 0, -1, 0, 0 }, + { 0, -1, 0, 0 } +}; +char __stdio_tmpnam[256]; +#ifdef USE_GS +int __stdio_stdout_xy[2]; +#endif +#endif + + +#ifdef F_tmpfile +/* stdio temp name variable. */ +extern char __stdio_tmpnam[256]; + + +/* +** +** [func] - tmpfile. +** [desc] - attempts to create a temporary file. if able to create a temporary +** file then returns the pointer to the FILE stream. else returns NULL. +** [entr] - none. +** [exit] - FILE *; the ptr. to the opened temp. file if successful. else NULL. +** [prec] - none. +** [post] - a temporary is opened. +** +*/ +FILE *tmpfile(void) +{ + return ((tmpnam(NULL) != NULL) ? fopen(__stdio_tmpnam, "rw+") : NULL); +} +#endif + + +#ifdef F_tmpnam +/* stdio temp name variable. */ +extern char __stdio_tmpnam[256]; + + +/* +** +** [func] - tmpnam. +** [desc] - creates a temporary filename string, +** [entr] - char *name; the pointer to the destination string pointer. +** [exit] - char *; +** [prec] - +** [post] - +** +*/ +char *tmpnam(char *name) +{ + char *ret = NULL; + + return (ret); +} +#endif + + +#ifdef F_ungetc +/* +** +** [func] - ungetc. +** [desc] - +** [entr] - int c; +** FILE *stream; the pointer to the FILE stream. +** [exit] - int; +** [prec] - stream is a valid FILE pointer. +** [post] - the stream FILE stream is modified. +** +*/ +int ungetc(int c, FILE *stream) +{ + // int ret = EOF; + + if (c == EOF || LOCAL_FILE(stream)->has_putback) { + /* invalid input, or putback queue full */ + return EOF; + } + + LOCAL_FILE(stream)->putback = (u8)c; + LOCAL_FILE(stream)->has_putback = 1; + return c; +} +#endif + + +#ifdef F_updatestdoutxy +/* std I/O data variable. */ +#ifdef USE_GS +extern int __stdio_stdout_xy[2]; +#endif + +/* +** +** [func] - __stdio_update_stdout_xy. +** [desc] - updates the stdout (x, y) screen coordinates. +** [entr] - int x; the x screen coordinate. +** int y; the y screen coordinate. +** [exit] - none. +** [prec] - none. +** [post] - the stdout screen coordinates are modified. +** +*/ +void __stdio_update_stdout_xy(int x, int y) +{ +#ifdef USE_GS + if ((x * 16) >= gsGetDisplayWidth()) { + x = 0; + ++y; + } + if ((y * 16) >= gsGetDisplayHeight()) y = 0; + __stdio_stdout_xy[0] = x; + __stdio_stdout_xy[1] = y; +#endif +} +#endif + + +#ifdef F___stdio_internals +void _pspsdk_stdio_init() +{ +} + +void _pspsdk_stdio_deinit() +{ +} +#endif diff --git a/src/libc/stdio.h b/src/libc/stdio.h new file mode 100644 index 00000000..f8feb62b --- /dev/null +++ b/src/libc/stdio.h @@ -0,0 +1,211 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * stdio.h + * + * Copyright (c) 2002-2004 PS2DEV + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: stdio.h 2335 2007-11-06 07:47:36Z warren $ + */ + +#ifndef __STDIO_H__ +#define __STDIO_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Some aliases for the unix 'unistd' functions */ +static __inline__ int open(const char *fname, int flags, ...) { return sceIoOpen(fname, flags, 0777); } +static __inline__ int close(int handle) { return sceIoClose(handle); } +static __inline__ ssize_t read(int handle, void * buffer, size_t size) { return sceIoRead(handle, buffer, size); } +static __inline__ ssize_t write(int handle, const void * buffer, size_t size) { return sceIoWrite(handle, buffer, size); } +static __inline__ off_t lseek(int handle, off_t position, int wheel) { return sceIoLseek(handle, position, wheel); } +static __inline__ off_t tell(int handle) { return sceIoLseek(handle, 0, 1); } + +/* Some win32 equivalents... baaah */ +#define _open open +#define _close close +#define _read read +#define _write write +#define _lseek lseek + +#define _O_APPEND O_APPEND +#define _O_BINARY O_BINARY +#define _O_CREAT O_CREAT +#define _O_RDONKY O_RDONKY +#define _O_RDWR O_RDWR +#define _O_TEXT O_TEXT +#define _O_TRUNC O_TRUNC +#define _O_WRONLY O_WRONLY + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +#ifndef O_TEXT +#define O_TEXT 0 +#endif + + +#define BUFSIZ 1024 + +#define _NFILE 16 + + +#define _IOFBF 0x0000 +#define _IOLBF 0x0100 +#define _IONBF 0x0004 +#define _IOEOF 0x0020 +#define _IOERR 0x0040 + +#define _IOREAD 0x0001 +#define _IOWRT 0x0002 +#define _IORW 0x0200 +#define _IOMYBUF 0x0010 + + +/* ensure EOF is defined. */ +#ifndef EOF +#define EOF (-1) +#endif + + +#define FOPEN_MAX _NFILE +#define FILENAME_MAX 1024 + + +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 + + +/* ensure fpos_t is defined. */ +#ifndef __FPOS_T_DEFINED +#define __FPOS_T_DEFINED +typedef long fpos_t; +#endif // __FPOS_T_DEFINED + + +/* ensure FILE is defined. */ +#ifndef __FILE_DEFINED +#define __FILE_DEFINED +typedef struct { + int type; + int fd; + int cnt; + int flag; + int has_putback; + u8 putback; +} FILE; +#endif // __FILE_DEFINED + + +extern FILE __iob[_NFILE]; + + +#define stdin (&__iob[0]) +#define stdout (&__iob[1]) +#define stderr (&__iob[2]) + + +/* function declarations. */ +void clearerr(FILE *); +int feof(FILE *); +int ferror(FILE *); +FILE *fopen(const char *, const char *); +FILE *fopen64(const char *, const char *); +FILE *fdopen(int, const char *); +int fclose(FILE *); +int fflush(FILE *); +int fgetc(FILE *); +int fgetpos(FILE *, fpos_t *); +int fgetpos64(FILE *, int64_t *); +char *fgets(char *, int, FILE *); +int fileno(FILE *); +int fputc(int, FILE *); +int fputs(const char *, FILE *); +size_t fread(void *, size_t, size_t, FILE *); +FILE *freopen(const char *, const char *, FILE *); +int fscanf(FILE *, const char *, ...); +int fseek(FILE *, long, int); +int fseeko64(FILE *, int64_t, int); +int fsetpos(FILE *, const fpos_t *); +long ftell(FILE *); +int64_t ftello64(FILE *); +size_t fwrite(const void *, size_t, size_t, FILE *); +int getc(FILE *); +int getchar(void); +char *gets(char *); +void perror(const char *); +int putc(int, FILE *); +int puts(const char *); +int remove(const char *); +int rename(const char *, const char *); +void rewind(FILE *); +int scanf(const char *, ...); +int setbuf(FILE *, char *); +int setvbuf(FILE *, char *, int, size_t); +int sscanf(const char *, const char *, ...); +FILE *tmpfile(void); +char *tmpnam(char *); +int vfscanf(FILE *, const char *, va_list); +int vscanf(const char *, va_list); +int vsscanf(const char *, const char *, va_list); +int vxscanf(int (*xgetc)(void **), void (*xungetc)(int, void **), void *stream, const char *, va_list); +int xscanf(int (*xgetc)(void **), void (*xungetc)(int, void **), void *stream, const char *, ...); + +int ungetc(int, FILE *); + +int _fcloseall(void); +int _fflushall(void); + +int chdir(const char *path); + + +/* from xprintf */ +int vxprintf(void (*func)(char*, int, void *), void * arg, const char * format, va_list ap); +int vsnprintf(char *buf, size_t n, const char *fmt, va_list ap); +int vsprintf(char *buf, const char *fmt, va_list ap); +char *vmprintf(const char *zFormat, va_list ap); +int vfprintf(FILE *pOut, const char *zFormat, va_list ap); +int vprintf(const char *format, va_list ap); +int vasprintf(char **strp, const char *format, va_list ap); + +int xprintf(void (*func)(char*, int, void *), void * arg, const char * format, ...) + __attribute__((format(printf,3,4))); +int snprintf(char *str, size_t sz, const char *format, ...) + __attribute__((format(printf,3,4))); +int sprintf(char *buf, const char *fmt, ...) + __attribute__((format(printf,2,3))); +char *mprintf(const char *zFormat, ...) + __attribute__((format(printf,1,2))); +int fprintf(FILE *pOut, const char *zFormat, ...) + __attribute__((format(printf,2,3))); +int printf(const char *format, ...) + __attribute__((format(printf,1,2))); +int asprintf(char **strp, const char *format, ...) + __attribute__((format(printf,2,3))); + +int putchar(int); + +int npmPuts(const char *buf); +int nprintf(const char *format, ...); +int vnprintf(const char *format, va_list args); +int sio_printf(const char *format, ...); + +#ifdef __cplusplus +} +#endif + + +#endif // __STDIO_H__ diff --git a/src/libc/stdlib.c b/src/libc/stdlib.c new file mode 100644 index 00000000..3c030636 --- /dev/null +++ b/src/libc/stdlib.c @@ -0,0 +1,1239 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * stdlib.c - Stdlib's functions, without allocs (see alloc.c) + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: stdlib.c 2414 2008-07-29 03:52:23Z jim $ + */ +#include +#include +#include +#include +#include + +extern void (* __stdlib_exit_func[32])(void); +extern int __stdlib_exit_index; + +// This function is missing... +char *__stdlib_ecvt(double, size_t, int *, int *); + +#ifndef __ENVIRONVARIABLE_T_DEFINED +#define __ENVIRONVARIABLE_T_DEFINED +typedef struct { + char name[256]; + char value[256]; +} environvariable_t; +#endif // __ENVIRONVARIABLE_T_DEFINED + +extern environvariable_t __stdlib_env[32]; +extern int __stdlib_mb_shift; +extern unsigned int __stdlib_rand_seed; + +int isspace(int); +int isdigit(int); +int isalpha(int); +int isupper(int); + +#ifdef F_abs +/* +** +** [func] - abs. +** [desc] - returns the absolute value of the integer c. +** [entr] - int c; the integer value. +** [exit] - int; the absolute value of the integer c. +** [prec] - none. +** [post] - none. +** +*/ + +// shouldn't we rather put that as a macro... ? +int abs(int c) +{ + return ((c >= 0) ? c : -c); +} +#endif + + +#ifdef F_atexit +/* +** +** [func] - atexit. +** [desc] - if the current amount of registered exit() functions has not +** been reached then registers the func parameter function to the +** list and returns 0. else returns non-zero. +** [entr] - void (*func)(void); the pointer to the exit function. +** [exit] - int; 0 if albe to register the func exit() function. else non-zero. +** [prec] - func is a valid function pointer. +** [post] - the atexit() function list is modified. +** +*/ +int atexit(void (*func)(void)) +{ + int ret; + + if (__stdlib_exit_index < 32) { + /* register func to the exit() function list. */ + __stdlib_exit_func[__stdlib_exit_index++] = func; + ret = 0; + } + else ret = -1; + return (ret); +} +#endif + + +#ifdef F_atof +/* +** +** [func] - atof. +** [desc] - if the string s begins with a valid floating point string then +** returns the floating point value of the string s. else returns 0.** +** [entr] - const char *s; the source string pointer. +** [exit] - double; the floating point value of the string s. else 0. +** [prec] - s is a valid string pointer. +** [post] - none. +* +*/ + +// macro... maybe ? :) +double atof(const char *s) +{ + return (strtod(s, NULL)); +} +#endif + +#ifdef F_bsearch +/* +** +** [func] - bsearch. +** [desc] - +** [entr] - const void *key; the pointer to the search key object. +** const void *base; the pointer to the base of the search data. +** size_t count; the number of elements in the search data. +** size_t size; the size of the search elements. +** int (* compare)(const void *, const void *); the pointer to the compare function. +** [exit] - void *; +** [prec] - +** [post] - +** +*/ +void *bsearch(const void *key, const void *base, size_t count, size_t size, int (* compare)(const void *, const void *)) +{ + int comparison; + size_t l, u, idx; + void *ret = NULL; + const void *p; + + /* perform a binary search of a sorted array. */ + for (l = 0, u = count; l < u; ) { + idx = ((l + u) / 2); + /* calculate the pointer index. */ + p = (const void *)((const char *)base + (idx * size)); + comparison = (*compare)(key, p); + if (comparison < 0) u = idx; + else if (comparison > 0) l = (idx + 1); + else { + /* return the pointer. */ + ret = (void *)p; + break; + } + } + return (ret); +} +#endif + + +#ifdef F_div +/* +** +** [func] - div. +** [desc] - +** [entr] - int n; the integer numerator. +** int d; the integer divisor. +** [exit] - div_t; +** [prec] - none. +** [post] - none. +** +*/ +div_t div(int n, int d) +{ + div_t ret; + + /* calculate the quotient and remainder. */ + // duh... can't this be written with some asm "mfhi/mflo" ? + ret.quot = (n / d); + ret.rem = (n % d); + return (ret); +} +#endif + + +#if F_exit +/* +** +** [func] - exit. +** [desc] - calls all the register exit() functions and returns to PlayStation2 +** OSD. +** [entr] - int status; the exit status code. +** [exit] - this function deos not return. +** [prec] - none. +** [post] - none. +** +*/ +void exit(int status) +{ + int i; + + for (i=(__stdlib_exit_index-1); i>=0; i--) + __stdlib_exit_func[i](); + + _Exit(status); +} +#endif + + +#if 0 +/* +** +** [func] - _gcvt.c +** [desc] - +** [entr] - double x; +** size_t n; +** char *buf; +** [exit] - char *; +** [prec] - +** [post] - +** +*/ + +// why the underscore ? win32 or what ? +// won't link anyway. +char *_gcvt(double x, size_t n, char *buf) +{ + int decpt, i, sign; + char *p1, *p2; + + p1 = __stdlib_ecvt(x, n, &decpt, &sign); + p2 = buf; + if (sign) *p2++ = '-'; + for (i = (n - 1); ((i > 0) && (p1[i] == '0')); --i) --n; + i = (int)n; + if (((decpt >= 0) && (decpt - i > 4)) || ((decpt < 0) && (decpt < -3))) { + --decpt; + *p2++ = *p1++; + *p2++ = '.'; + for (i = 1; i < n; ++i) *p2++ = *p1++; + *p2++ = 'e'; + if (decpt < 0) { + decpt = -decpt; + *p2++ = '-'; + } + else *p2++ = '+'; + if ((decpt / 100) > 0) *p2++ = ((decpt / 100) + '0'); + if ((decpt / 10) > 0) *p2++ = (((decpt % 100) / 10) + '0'); + *p2++ = decpt%10 + '0'; + } + else { + if (decpt <= 0) { + if (*p1!='0') *p2++ = '.'; + while (decpt < 0) { + ++decpt; + *p2++ = '0'; + } + } + for (i = 1; i <= n; ++i) { + *p2++ = *p1++; + if (i == decpt) *p2++ = '.'; + } + if (n < decpt) { + while (n++ < decpt) *p2++ = '0'; + *p2++ = '.'; + } + } + if (p2[-1]=='.') p2--; + *p2 = '\0'; + return(buf); +} +#endif + + +#ifdef F_getenv +/* +** +** [func] - getenv. +** [desc] - if name is an existing environment variable name then returns the +** poiinter to the corresponding environment variable string value. +** else returns NULL. +** [entr] - const char *name; the environment name string pointer. +** [exit] - char *; the ptr. to the corres. environment variable string. else NULL. +** [prec] - name is a valid string pointer. +** [post] - none. +** +*/ +char *getenv(const char *name) +{ + int i; + char *ret = NULL; + + /* search for matching environment variable name. */ + for (i = 0; i < 32; ++i) { + if (strcmp(name, __stdlib_env[i].name) == 0) { + /* return the environment variable value. */ + ret = (char *)__stdlib_env[i].value; + break; + } + } + return (ret); +} +#endif + + +#ifdef F__itoa +/* +** +** [func] - _itoa. +** [desc] - +** [entr] - int n; the integer value to convert. +** char *buf; the pointer to the destination memory buffer. +** int radix; the conversion number base. +** [exit] - char *; buf. +** [prec] - buf is a valid memory pointer. +** [post] - the memory pointed to by buf is modified. +** +*/ +char *_itoa(int n, char *buf, int radix) +{ + char *ret = buf; + char tmp[33]; + int i = 0, j, r; + + /* validate the conversion number base. */ + if ((radix >= 2) && (radix <= 36)) { + if ((radix == 10) && (n < 0)) { + /* negative integer value. */ + *buf++ = '-'; + n = -n; + } + do { + /* calculate the current digit. */ + r = (int)((unsigned int)n % radix); + tmp[i++] = ((r < 10) ? (r + '0') : (r - 10 + 'a')); + } while ((n /= radix) != 0); + /* reverse the buffer string. */ + for (--i, j = 0; (i >= 0); --i, ++j) buf[j] = tmp[i]; + buf[j] = 0; + } + return (ret); +} +#endif + + +#ifdef F_labs +/* +** +** [func] - labs. +** [desc] - returns the absolute value of the long integer n. +** [entr] - long n; the long integer value. +** [exit] - long; the absolute value of the long integer n. +** [prec] - none. +** [post] - none. +** +*/ +long labs(long n) +{ + return ((n >= 0) ? n : -n); +} +#endif + + +#ifdef F_ldiv +/* +** +** [func] - ldiv. +** [desc] - +** [entr] - long n; the long integer numerator. +** long d; the long integer denominator. +** [exit] - ldiv_t; +** [prec] - +** [post] - +** +*/ +ldiv_t ldiv(long n, long d) +{ + ldiv_t ret; + + ret.quot = (n / d); + ret.rem = (n % d); + return (ret); +} +#endif + + +#ifdef F_llabs +/* +** +** [func] - llabs. +** [desc] - returns the absolute value of the long long integer n. +** [entr] - long n; the long long integer value. +** [exit] - long; the absolute value of the long long integer n. +** [prec] - none. +** [post] - none. +** +*/ +long long llabs(long long n) +{ + return ((n >= 0) ? n : -n); +} +#endif + + +#ifdef F_lldiv +/* +** +** [func] - lldiv. +** [desc] - +** [entr] - long long n; the long long integer numerator. +** long long d; the long long integer denominator. +** [exit] - ldiv_t; +** [prec] - +** [post] - +** +*/ +lldiv_t lldiv(long long n, long long d) +{ + lldiv_t ret; + + ret.quot = (n / d); + ret.rem = (n % d); + return (ret); +} +#endif + + +#ifdef F__lltoa +/* +** +** [func] - _lltoa. +** [desc] - +** [entr] - long long n; the long long integer value to convert. +** char *buf; the pointer to the destination memory buffer. +** int radix; the conversion number base. +** [exit] - char *; buf. +** [prec] - buf is a valid memory pointer. +** [post] - the memory pointed to by buf is modified. +** +*/ +char *_lltoa(long long n, char *buf, int radix) +{ + char *ret = buf; + char tmp[65]; + int i = 0, j; + long long r; + + /* validate the conversion number base. */ + if ((radix >= 2) && (radix <= 36)) { + if ((radix == 10) && (n < 0)) { + /* negative integer value. */ + *buf++ = '-'; + n = -n; + } + do { + /* calculate the current digit. */ + r = (long long)((unsigned long long)n % radix); + tmp[i++] = ((r < 10) ? (r + '0') : (r - 10 + 'a')); + } while ((n /= radix) != 0); + /* reverse the buffer string. */ + for (--i, j = 0; (i >= 0); --i, ++j) buf[j] = tmp[i]; + buf[j] = 0; + } + return (ret); +} +#endif + + +#ifdef F__ltoa +/* +** +** [func] - _ltoa. +** [desc] - +** [entr] - long n; the long integer value to convert. +** char *buf; the pointer to the destination memory buffer. +** int radix; the conversion number base. +** [exit] - char *; buf. +** [prec] - buf is a valid memory pointer. +** [post] - the memory pointed to by buf is modified. +** +*/ +char *_ltoa(long n, char *buf, int radix) +{ + char *ret = buf; + char tmp[33]; + int i = 0, j; + long r; + + /* validate the conversion number base. */ + if ((radix >= 2) && (radix <= 36)) { + if ((radix == 10) && (n < 0)) { + /* negative integer value. */ + *buf++ = '-'; + n = -n; + } + do { + /* calculate the current digit. */ + r = (long)((unsigned long)n % radix); + tmp[i++] = ((r < 10) ? (r + '0') : (r - 10 + 'a')); + } while ((n /= radix) != 0); + /* reverse the buffer string. */ + for (--i, j = 0; (i >= 0); --i, ++j) buf[j] = tmp[i]; + buf[j] = 0; + } + return (ret); +} +#endif + + +#ifdef F_mblen +/* +** +** [func] - mblen. +** [desc] - if s is a valid multibyte character then returns the length +** of the multibyte character s. else returns 0. +** [entr] - const char *s; +** size_t n; the length of the multibyte character s. else 0. +** [exit] - int; +** [prec] - s is a valid string pointer. +** [post] - none. +** +*/ +int mblen(const char *s, size_t n) +{ + return (mbtowc((wchar_t *)NULL, s, n)); +} +#endif + + +#ifdef F_mbstowcs +/* +** +** [func] - mbstowcs. +** [desc] - if s is a valid multibyte string then converts the multibyte +** string to a wide-character string and returns the length of +** the wide-character string. else returns -1. +** [entr] - wchar_t *ws; the destination wide-character string pointer. +** const char *s; the source multibyte string pointer. +** size_t n; the maximum number of characters to convert. +** [exit] - size_t; the length of the wide-character string. else -1. +** [prec] - ws is a valid wide-character string pointer and s is a valid +** string pointer. +** [post] - the memory pointed to by ws is modified. +** +*/ +size_t mbstowcs(wchar_t *ws, const char *s, size_t n) +{ + int len, shift; + size_t ret = -1; + + /* convert the multibyte string to wide-character string. */ + for (shift = __stdlib_mb_shift; *s != '\0'; ) { + if (__isascii(*s) != 0) { + /* multibyte character is ascii. */ + *ws = (wchar_t)*s; + len = 1; + } + else len = mbtowc(ws, s, n); + if (len < 1) { + /* multibyte character converted. */ + ++ws; + ++ret; + s += len; + n -= len; + } + else { + /* error occured. */ + ret = -1; + break; + } + } + /* append NULL terminator. */ + if (n > 0) *ws = (wchar_t)'\0'; + __stdlib_mb_shift = shift; + return (ret); +} +#endif + + +#ifdef F_mbtowc +/* +** +** [func] - mbtowc. +** [desc] - attempts to convert the s multi-byte character to the corresponding +** wide-character. if able to convert the s multi-byte character to the +** corresponding wide-character then stores the resulitng wide-character +** to the memory pointed to by wc and returns the number of bytes for +** the multi-byte character. else if the multi-byte character is '\0' +** then returns 1. else returns -1. +** [entr] - wchar_t *wc; the source wide-character string pointer. +** const char *s; the pointer to the destination multi-byte string buffer. +** size_t n; the number of bytes to check. +** [exit] - int; the number of bytes for mb char. else 1 if mb char is '\0'. else -1. +** [prec] - wc is a valid wchar_t pointer and s is a valid string pointer. +** [post] - the memory pointed to by wc is modified. +** +*/ +int mbtowc(wchar_t *wc, const char *s, size_t n) +{ + int ret = -1; + const mbchar_t *mb; + wchar_t i; + + /* test for NULL source string pointer. */ + if (s != NULL) { + if (*s != '\0') { + /* test if the multi-byte conversion table has initialized. */ + if ((_ctype_info->mbchar == NULL) || (_ctype_info->mbchar->chars == NULL)) { + if (wc != NULL) { + *wc = (wchar_t)*s; + ret = 1; + } + } + else { + /* search only up to maximum current multi-byte bytes. */ + if (n > MB_CUR_MAX) n = MB_CUR_MAX; + for (i = 0; i < WCHAR_MAX; ++i) { + /* process the curent multi-byte character. */ + mb = &_ctype_info->mbchar->chars[i]; + if ((i == (wchar_t)EOF) || (i == (wchar_t)'\0')) continue; + else if (__isascii(i)) continue; + else if ((mb->string == NULL) || (mb->len == 0)) continue; + else if (mb->len > n) continue; + else if (strncmp(mb->string, s, mb->len) == 0) { + if (wc != NULL) *wc = i; + __stdlib_mb_shift += mb->shift; + ret = mb->len; + break; + } + } + } + } + else ret = 0; + } + else ret = (__stdlib_mb_shift != 0); + return (ret); +} +#endif + + +#ifdef F_rand +/* +** +** [func] - rand. +** [desc] - returns the random number generated from the current stdlib random +** seed. +** [entr] - none. +** [exit] - int; the random number generated from the current stdlib random seed. +** [prec] - none. +** [post] - the stdlib random seed is modified. +** +*/ +int rand(void) +{ +// I don't agree with it... +// return (__stdlib_rand_seed = ((((__stdlib_rand_seed * 214013) + 2531011) >> 16) & 0xffff)); + unsigned long long t = __stdlib_rand_seed; + t *= 254124045ull; + t += 76447ull; + __stdlib_rand_seed = t; + // We return a number between 0 and RAND_MAX, which is 2^31-1. + return (t >> 16) & 0x7FFFFFFF; +} +#endif + + +#ifdef F_setenv +/* +** +** [func] - setenv. +** [desc] - if name is an existing environment variable and rewrite is non-zero +** then overwrites the name environment variable value with value and +** returns 0. else if name is not an existring environment variable and +** there is a free environment variable slot available then sets the +** name environment variable and returns 0. else returns -1. +** [entr] - const char *name; the environment variable name string pointer. +** const char *value; the environment variable value string pointer. +** int rewrite; the overwrite flag. +** [exit] - int; 0 if able to set the environment variable successfully. else -1. +** [prec] - name and value are valid string pointers. +** [post] - the name environment variable is set. +** +*/ +int setenv(const char *name, const char *value, int rewrite) +{ + int done, i, ret = -1; + + /* search for matching environment variable name. */ + for (i = 0, done = 0; i < 32; ++i) { + if (strcmp(name, __stdlib_env[i].name) == 0) { + if (rewrite) { + /* overwrite the current environment variable value. */ + strncpy(__stdlib_env[i].value, value, 255); + __stdlib_env[i].value[255] = 0; + ret = 0; + } + done = 1; + break; + } + } + if (!done) { + /* search for a free environment variable slot. */ + for (i = 0; i < 32; ++i) { + if (__stdlib_env[i].name[0] == '\0') { + /* set the name environment variable. */ + strncpy(__stdlib_env[i].name, name, 255); + __stdlib_env[i].name[255] = 0; + strncpy(__stdlib_env[i].value, value, 255); + __stdlib_env[i].value[255] = 0; + ret = 0; + break; + } + } + } + return (ret); +} +#endif + + +#ifdef F_srand +/* +** +** [func] - srand. +** [desc] - sets the current stdlib random seed to seed. +** [entr] - unsigned int seed; the stdlib random seed. +** [exit] - none. +** [prec] - none. +** [post] - none. +** +*/ +void srand(unsigned int seed) +{ + __stdlib_rand_seed = seed; +} +#endif + + +#ifdef F___stdlib_internals +/* stdlib data variables. */ +environvariable_t __stdlib_env[32]; +void (* __stdlib_exit_func[32])(void); +int __stdlib_exit_index = 0; +int __stdlib_mb_shift = 0; +unsigned int __stdlib_rand_seed = 92384729; +#endif + + +#ifdef F_strtod +/* +** +** [func] - strtod. +** [desc] - if s is a valid floating point number string then converts the +** string to it's corresponding float point value and returns the +** value. else returns 0.0. if eptr is not NULL then stores the +** pointer to the last processed character in the string. +** [entr] - const char *s; the source string pointer. +** char **endptr; the pointer to the store string end pointer. +** [exit] - double; the converted 64-bit float value. else 0.0. +** [prec] - s is a valid string pointer and eptr is a valid string pointer +** pointer. +** [post] - the memory pointed to by eptr is modified. +** +*/ +double strtod(const char *s, char **eptr) +{ + double d, ret = 0.0, sign = 1.0; + int e = 0, esign = 1, flags = 0, i; + + /* remove leading white spaces. */ + for (; (isspace(*s) != 0); ) ++s; + if (*s == '-') { + /* negative value. */ + sign = -1.0; + ++s; + } + else if (*s == '+') ++s; + for (; (isdigit(*s) != 0); ++s) { + /* process digits before decimal point. */ + flags |= 1; + ret *= 10.0; + ret += (double)(int)(*s - '0'); + } + if (*s == '.') { + for (d = 0.1, ++s; (isdigit(*s) != 0); ++s) { + /* process digits after decimal point. */ + flags |= 2; + ret += (d * (double)(int)(*s - '0')); + d *= 0.1; + } + } + if (flags != 0) { + /* test for exponent token. */ + if ((*s == 'e') || (*s == 'E')) { + ++s; + if (*s == '-') { + /* negative exponent. */ + esign = -1; + ++s; + } + else if (*s == '+') ++s; + if (isdigit(*s) != 0) { + for (; (isdigit(*s) != 0); ++s) { + /* process exponent digits. */ + e *= 10; + e += (int)(*s - '0'); + } + if (esign >= 0) for (i = 0; i < e; ++i) ret *= 1.0; + else for (i = 0; i < e; ++i) ret *= 0.1; + } + } + } + if (eptr != NULL) *eptr = (char *)s; + return (ret * sign); +} +#endif + + +#ifdef F_strtol +/* +** +** [func] - strtol. +** [desc] - if s is a valid long integer string then converts the string to +** it's corresponding long integer value and returns the value. else +** returns the long integer huge value. if eptr is not NULL then +** stores the pointer to the last processed character in the string. +** [entr] - const char *s; the source string pointer. +** char **eptr; the pointer to store the string end pointer. +** int b; the long integer base. +** [exit] - long; the converted long integer value. else the long integer huge value. +** [prec] - s is a valid string pointer and eptr is a valid string pointer +** pointer. +** [post] - the memory pointed to by eptr is modified. +** +*/ +#if 0 +long strtol(const char *s, char **eptr, int b) +{ + const char *start; + int any, c, cutlim, neg = 0; + long ret = 0; + unsigned long acc, cutoff; + + for (start = s; (isspace(*s) != 0); ) ++s; + if (*s == '-') { + neg = 1; + ++s; + } + else if (*s == '+') ++s; + if (((b == 0) || (b == 16)) && (*s == '0') && ((*(s + 1) == 'x') || (*(s + 1) == 'X'))) { + b = 16; + s += 2; + } + if (b == 0) b = ((*s == '0') ? 8 : 10); + /* calculate cutoff values. */ + cutoff = ((neg != 0) ? (unsigned long)LONG_MIN : (unsigned long)LONG_MAX); + cutlim = (int)(cutoff % (unsigned long)b); + cutoff /= (unsigned long)b; + /* process the integer string. */ + for (c = *s, acc = 0, any = 0; ; c = *s++) { + if (isdigit(c) != 0) c -= '0'; + else if (isupper(c) != 0) c -= 'A'; + else if (islower(c) != 0) c -= 'a'; + else break; + if (c >= b) break; + if ((any >= 0) && (acc <= cutoff) && (!((acc == cutoff) && (c > cutlim)))) { + acc *= b; + acc += c; + any = 1; + } + else any = -1; + } + if (any < 0) { + acc = ((neg != 0) ? (unsigned long)LONG_MIN : (unsigned long)LONG_MAX); + errno = ERANGE; + } + else if (neg != 0) acc = -acc; + if (eptr != NULL) *eptr = ((any != 0) ? (char *)(s - 1) : (char *)start); + return (ret); +} +#else + long strtol(const char *nptr, char **endptr, int base) + { + register const char *s = nptr; + register unsigned long acc; + register int c; + register unsigned long cutoff; + register int neg = 0, any, cutlim; + + /* + * Skip white space and pick up leading +/- sign if any. + * If base is 0, allow 0x for hex and 0 for octal, else + * assume decimal; if base is already 16, allow 0x. + */ + do + { + c = *s++; + } while (isspace(c)); + + if (c == '-') + { + neg = 1; + c = *s++; + } else if (c == '+') + c = *s++; + + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) + { + c = s[1]; + s += 2; + base = 16; + } + + if (base == 0) + base = c == '0' ? 8 : 10; + + /* + * Compute the cutoff value between legal numbers and illegal + * numbers. That is the largest legal value, divided by the + * base. An input number that is greater than this value, if + * followed by a legal input character, is too big. One that + * is equal to this value may be valid or not; the limit + * between valid and invalid numbers is then based on the last + * digit. For instance, if the range for longs is + * [-2147483648..2147483647] and the input base is 10, + * cutoff will be set to 214748364 and cutlim to either + * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated + * a value > 214748364, or equal but the next digit is > 7 (or 8), + * the number is too big, and we will return a range error. + * + * Set any if any `digits' consumed; make it negative to indicate + * overflow. + */ + cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX; + cutlim = cutoff % (unsigned long)base; + cutoff /= (unsigned long)base; + + for (acc = 0, any = 0;; c = *s++) + { + if (isdigit(c)) + c -= '0'; + else if (isalpha(c)) + c -= isupper(c) ? 'A' - 10 : 'a' - 10; + else + break; + + if (c >= base) + break; + + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else + { + any = 1; + acc *= base; + acc += c; + } + } + + if (any < 0) + { + acc = neg ? LONG_MIN : LONG_MAX; + /*errno = E_LIB_MATH_RANGE; */ + /* TODO */ + errno = 30; + } else if (neg) + acc = -acc; + + if (endptr != 0) + *endptr = (char *) (any ? s - 1 : nptr); + + return (acc); + } +#endif +#endif + + +#ifdef F_strtoul +/* +** +** [func] - strtoul. +** [desc] - if s is a valid long integer string then converts the string to +** it's corresponding long integer value and returns the value. else +** returns the long integer huge value. if eptr is not NULL then +** stores the pointer to the last processed character in the string. +** [entr] - const char *s; the source string pointer. +** char **eptr; the pointer to store the string end pointer. +** int b; the long integer base. +** [exit] - long; the converted long integer value. else the long integer huge value. +** [prec] - s is a valid string pointer and eptr is a valid string pointer +** pointer. +** [post] - the memory pointed to by eptr is modified. +** +*/ +#if 0 +unsigned long strtoul(const char *s, char **eptr, int b) +{ + const char *start; + int any, c, cutlim, neg = 0; + unsigned long ret = 0; + unsigned long acc, cutoff; + + for (start = s; (isspace(*s) != 0); ) ++s; + if (*s == '-') { + neg = 1; + ++s; + } + else if (*s == '+') ++s; + if (((b == 0) || (b == 16)) && (*s == '0') && ((*(s + 1) == 'x') || (*(s + 1) == 'X'))) { + b = 16; + s += 2; + } + if (b == 0) b = ((*s == '0') ? 8 : 10); + /* calculate cutoff values. */ + cutoff = ((neg != 0) ? (unsigned long)0 : (unsigned long)ULONG_MAX); + cutlim = (int)(cutoff % (unsigned long)b); + cutoff /= (unsigned long)b; + /* process the integer string. */ + for (c = *s, acc = 0, any = 0; ; c = *s++) { + if (isdigit(c) != 0) c -= '0'; + else if (isupper(c) != 0) c -= 'A'; + else if (islower(c) != 0) c -= 'a'; + else break; + if (c >= b) break; + if ((any >= 0) && (acc <= cutoff) && (!((acc == cutoff) && (c > cutlim)))) { + acc *= b; + acc += c; + any = 1; + } + else any = -1; + } + if (any < 0) { + acc = ((neg != 0) ? (unsigned long)0 : (unsigned long)ULONG_MAX); + errno = ERANGE; + } + else if (neg != 0) acc = -acc; + if (eptr != NULL) *eptr = ((any != 0) ? (char *)(s - 1) : (char *)start); + return (ret); +} +#else +unsigned long strtoul(const char *nptr, char **endptr, int base) + { + register const char *s = nptr; + register unsigned long acc; + register int c; + register unsigned long cutoff; + register int any, cutlim; + + /* + * Skip white space and pick up leading +/- sign if any. + * If base is 0, allow 0x for hex and 0 for octal, else + * assume decimal; if base is already 16, allow 0x. + */ + do + { + c = *s++; + } while (isspace(c)); + + if (c == '-') + { + c = *s++; + } else if (c == '+') + c = *s++; + + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) + { + c = s[1]; + s += 2; + base = 16; + } + + if (base == 0) + base = c == '0' ? 8 : 10; + + cutoff = ULONG_MAX; + cutlim = cutoff % (unsigned long)base; + cutoff /= (unsigned long)base; + + for (acc = 0, any = 0;; c = *s++) + { + if (isdigit(c)) + c -= '0'; + else if (isalpha(c)) + c -= isupper(c) ? 'A' - 10 : 'a' - 10; + else + break; + + if (c >= base) + break; + + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else + { + any = 1; + acc *= base; + acc += c; + } + } + + if (any < 0) + { + acc = ULONG_MAX; +/* errno = E_LIB_MATH_RANGE; */ + /* TODO */ + errno = 30; + } + + if (endptr != 0) + *endptr = (char *) (any ? s - 1 : nptr); + + return (acc); + } +#endif +#endif + + +#ifdef F_wcstombs +/* +** +** [func] - wcstombs. +** [desc] - +** [entr] - char *s; the pointer to the destination string buffer. +** const wchar_t *ws; the source wide-character string pointer. +** size_t n; the maximum number of characters to store to s. +** [exit] - size_t; the length of the multibyte string. else -1. +** [prec] - s is a valid memory pointer and ws is a valid wide-character string. +** [post] - the memory pointed to s is modified. +** +*/ +size_t wcstombs(char *s, const wchar_t *ws, size_t n) +{ + int shift = 0; + size_t ret = 0; + wchar_t wc; + const mbchar_t *mb; + + for (; ((wc = *ws++) != (wchar_t)'\0'); ) { + if (__isascii(wc)) { + *s++ = (char)(unsigned char)wc; + --n; + ++ret; + } + else { + mb = &_ctype_info->mbchar->chars[wc + shift]; + if ((mb->string == NULL) || (mb->len == 0)) { + ret = (size_t)-1; + break; + } + else if (mb->len > n) break; + else { + memcpy (s, mb->string, mb->len); + shift += mb->shift; + s += mb->len; + n -= mb->len; + ret += mb->len; + } + } + } + if (n > 0) *s = '\0'; + return (ret); +} +#endif + + +#ifdef F_wctomb +/* +** +** [func] - wctomb. +** [desc] - converts the wc wide-character to the corresponding multibyte +** character and stores the multi-byte character to the memory +** pointed to by s and returns the number of bytes used by the +** multi-byte character. +** [entr] - char *s; the pointer to the destination multi-byte character buffer. +** wchar_t wc; the wide-character to convert. +** [exit] - int; the number of bytes used by the multi-byte character. +** [prec] - s is a valid memory pointer. +** [post] - the memory pointed to by s is modified. +** +*/ +int wctomb(char *s, wchar_t wc) +{ + int ret; + const mbchar_t *mb; + + /* test if the multi-byte conversion table has initialized. */ + if (_ctype_info->mbchar == NULL) mb = NULL; + else mb = _ctype_info->mbchar->chars; + /* test for NULL string pointer. */ + if (s != NULL) { + if (wc != (wchar_t)'\0') { + /* ensure multi-byte character is not NULL. */ + if (mb == NULL) { + if ((unsigned char) wc == wc) { + /* copy wide-character. */ + *s = wc; + ret = 1; + } + else ret = -1; + } + else { + /* retrieve the corresponding multi-byte character. */ + mb += (wc + __stdlib_mb_shift); + if ((mb->string != NULL) || (mb->len == 0)) { + /* copy the multi-byte string. */ + memcpy(s, mb->string, mb->len + 1); + __stdlib_mb_shift += mb->shift; + ret = mb->len; + } + else ret = -1; + } + } + else { + /* NULL string terminator. */ + __stdlib_mb_shift = 0; + if (s != NULL) *s = '\0'; + ret = 1; + } + } + else ret = (__stdlib_mb_shift != 0); + return (ret); +} +#endif + +#ifdef F___assert_fail +int __assert_fail (const char *assertion, const char *file, unsigned int line) +{ + fprintf(stderr, "Error: assertion `%s' failed in %s:%i\n", assertion, file, line); + return 0; +} +#endif + +#ifdef F___stdlib_internals +void _pspsdk_stdlib_init() +{ +} + +void _pspsdk_stdlib_deinit() +{ + int i; + + for (i = (__stdlib_exit_index - 1); i >= 0; --i) + { + (__stdlib_exit_func[i])(); + } +} +#endif diff --git a/src/libc/stdlib.h b/src/libc/stdlib.h new file mode 100644 index 00000000..35b81b34 --- /dev/null +++ b/src/libc/stdlib.h @@ -0,0 +1,133 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * stdlib.h + * + * Copyright (c) 2002-2004 PS2DEV + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: stdlib.h 1095 2005-09-27 21:02:16Z jim $ + */ + +#ifndef __STDLIB_H__ +#define __STDLIB_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* ensure NULL is defined. */ +#ifndef NULL +#define NULL (void *)0 +#endif + + +/* exit status constants. */ +#define EXIT_SUCCESS 0 +#define EXIT_FAILURE 1 + + +/* multibyte maximum character constant. */ +#define MB_CUR_MAX 1 + +/* ensure div_t is defined. */ +#ifndef __DIV_T_DEFINED +#define __DIV_T_DEFINED +typedef struct { + int quot; + int rem; +} div_t; +#endif // __DIV_T_DEFINED + + +/* ensure ldiv_t is defined. */ +#ifndef __LDIV_T_DEFINED +#define __LDIV_T_DEFINED +typedef struct { + long quot; + long rem; +} ldiv_t; +#endif // __LDIV_T_DEFINED + + +#ifndef __STRICT_ANSI__ +#ifndef __LLDIV_T_DEFINED +#define __LLDIV_T_DEFINED +typedef struct { + long long quot; + long long rem; +} lldiv_t; +#endif // __LLDIV_T_DEFINED +#endif // __STRICT_ANSI__ + +/* we don't check for any previously defined value. This HAS to be that. */ +#define RAND_MAX 2147483647 + + +/* function declarations. */ +void abort(void) __attribute__ ((noreturn)); +int abs(int); +int atexit(void (*)(void)); +double atof(const char *); +void exit(int); +//int atoi(const char *); +//long atol(const char *); +//#define atoi(x) strtol(x, NULL, 10) +//#define atol atoi +void *bsearch(const void *, const void *, size_t, size_t, int (*)(const void *, const void *)); +div_t div(int, int); +char *getenv(const char *); +long labs(long); +ldiv_t ldiv(long, long); +#ifndef __STRICT_ANSI__ +long long llabs(long long); +lldiv_t lldiv(long long, long long); +#endif +int rand(void); +int setenv(const char *, const char *, int); +void srand(unsigned int); +double strtod(const char *, char **); +long strtol(const char *, char **, int); +unsigned long strtoul(const char *, char **, int); +static __inline__ int atoi(const char * x) { return strtol(x, NULL, 10); } +static __inline__ long atol(const char * x) { return strtol(x, NULL, 10); } + + +void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)); + + +/* Multibyte disabled, but prototyped for C++... */ +int mblen(const char *, size_t); +size_t mbstowcs(wchar_t *, const char *, size_t); +int mbtowc(wchar_t *, const char *, size_t); +size_t wcstombs(char *, const wchar_t *, size_t); +int wctomb(char *, wchar_t); + +//char *_gcvt(double, size_t, char *); +char *_itoa(int, char *, int); +char *_ltoa(long, char *, int); +#ifndef __STRICT_ANSI__ +char *_lltoa(long long, char *, int); +#endif + +// blah! C++ is evil. +int system (const char * string); + +#ifdef __cplusplus +} + +/* C++ is evil, let's defeat it... */ +#define _CPP_CSTDLIB 1 + +#endif + + +#endif // __STDLIB_H__ diff --git a/src/libc/string.c b/src/libc/string.c new file mode 100644 index 00000000..d10b8f89 --- /dev/null +++ b/src/libc/string.c @@ -0,0 +1,840 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * string.c - Standard ANSI string functions to complement the ASM funcs + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: string.c 1710 2006-01-17 01:24:53Z jim $ + */ +#include +#include +#include +#include + +/* Until a _ctype_ array exists in psplibc, don't include ctype.h and declare ctype.h + function prototypes. */ +int isalnum(int); +int isalpha(int); +int iscntrl(int); +int isdigit(int); +int isgraph(int); +int islower(int); +int isprint(int); +int ispunct(int); +int isspace(int); +int isupper(int); +int isxdigit(int); +int tolower(int); +int toupper(int); + +#ifdef F_strlen +unsigned int strlen(const char *s) +{ + int len = 0; + while(*s) + { + s++; + len++; + } + + return len; +} +#endif + +#ifdef F_strcat +char *strcat(char *s, const char *append) +{ + char *pRet = s; + while(*s) + { + s++; + } + + while(*append) + { + *s++ = *append++; + } + + *s = 0; + + return pRet; +} +#endif + +#ifdef F_strncat +char *strncat(char *s, const char *append, size_t count) +{ + char *pRet = s; + + while(*s) + { + s++; + } + + while((*append) && (count > 0)) + { + *s++ = *append++; + count--; + } + + *s = 0; + + return pRet; +} +#endif + +#ifdef F_strcmp +int strcmp(const char *s1, const char *s2) +{ + int val = 0; + const unsigned char *u1, *u2; + + u1 = (unsigned char *) s1; + u2 = (unsigned char *) s2; + + while(1) + { + if(*u1 != *u2) + { + val = (int) *u1 - (int) *u2; + break; + } + + if((*u1 == 0) && (*u2 == 0)) + { + break; + } + + u1++; + u2++; + } + + return val; +} +#endif + +#ifdef F_strncmp +int strncmp(const char *s1, const char *s2, size_t count) +{ + int val = 0; + const unsigned char *u1, *u2; + + u1 = (unsigned char *) s1; + u2 = (unsigned char *) s2; + + while(count > 0) + { + if(*u1 != *u2) + { + val = (int) *u1 - (int) *u2; + break; + } + + if((*u1 == 0) && (*u2 == 0)) + { + break; + } + + u1++; + u2++; + count--; + } + + return val; +} +#endif + +#ifdef F_strcpy +char *strcpy(char *dst, const char *src) +{ + char *pRet = dst; + + while(*src) + { + *dst++ = *src++; + } + + *dst = 0; + + return pRet; +} +#endif + +#ifdef F_strncpy +char *strncpy(char *dst, const char *src, size_t count) +{ + char *pRet = dst; + + while(count > 0) + { + if(*src) + { + *dst++ = *src++; + } + else + { + *dst++ = 0; + } + + count--; + } + + return pRet; +} +#endif + +#ifdef F_memcmp +int memcmp(const void *b1, const void *b2, size_t len) +{ + int val = 0; + const unsigned char *u1, *u2; + + u1 = (const unsigned char *) b1; + u2 = (const unsigned char *) b2; + + while(len > 0) + { + if(*u1 != *u2) + { + val = (int) *u1 - (int) *u2; + break; + } + u1++; + u2++; + len--; + } + + return val; +} +#endif + +#ifdef F_memcpy +void *memcpy(void *dst, const void *src, size_t len) +{ + void *pRet = dst; + const char *usrc = (const char *) src; + char *udst = (char *) dst; + + while(len > 0) + { + *udst++ = *usrc++; + len--; + } + + return pRet; +} +#endif + +#ifdef F_memmove +void *memmove(void *dst, const void* src, size_t len) +{ + void *pRet = dst; + char *udst; + const char *usrc; + + if(dst < src) + { + /* Copy forwards */ + udst = (char *) dst; + usrc = (const char *) src; + while(len > 0) + { + *udst++ = *usrc++; + len--; + } + } + else + { + /* Copy backwards */ + udst = ((char *) dst) + len; + usrc = ((const char *) src) + len; + while(len > 0) + { + *--udst = *--usrc; + len--; + } + } + + return pRet; +} +#endif + +#ifdef F_memset +void *memset(void *b, int c, size_t len) +{ + void *pRet = b; + unsigned char *ub = (unsigned char *) b; + + while(len > 0) + { + *ub++ = (unsigned char) c; + len--; + } + + return pRet; +} +#endif + +#ifdef F_memchr +void *memchr(const void *b, int c, size_t len) +{ + void *pRet = NULL; + const unsigned char *ub; + + ub = (void *) b; + while(len > 0) + { + if(*ub == (unsigned char) c) + { + pRet = (void *) &ub[0]; + break; + } + + ub++; + len--; + } + + return pRet; +} +#endif + +#ifdef F_strchr +char *strchr(const char *s, int c) +{ + char *pRet = NULL; + + do + { + if(*s == (char) c) + { + pRet = (char *) &s[0]; + break; + } + } + while(*s++); + + return pRet; +} +#endif + +#ifdef F_strdup +char *strdup(const char *s) { + size_t str_size = strlen(s); + char * r = (char *)malloc(str_size + 1); + + return strcpy(r, s); +} +#endif + +#ifdef F_strcasecmp +int strcasecmp(const char * string1, const char * string2) +{ + while (*string1 != '\0' && tolower(*string1) == tolower(*string2)) + { + string1++; + string2++; + } + + return tolower(*(unsigned char *) string1) - tolower(*(unsigned char *) string2); +} +#endif + + +#ifdef F_strncasecmp +int strncasecmp(const char * string1, const char * string2, size_t n) +{ + if (n == 0) + return 0; + + while ((n-- != 0) && (tolower(*string1) == tolower(*string2))) + { + if ((n == 0) || (*string1 == '\0') || (*string2 == '\0')) + break; + + string1++; + string2++; + } + + return tolower(*(unsigned char *) string1) - tolower(*(unsigned char *) string2); +} +#endif + +#ifdef F_strtok +char* strtok(char * strToken, const char * strDelimit) +{ + static char* start; + static char* end; + + if (strToken != NULL) + start = strToken; + else + { + if (*end == 0) + return 0; + + start=end; + } + + if(*start == 0) + { + return 0; + } + + // Strip out any leading delimiters + while (strchr(strDelimit, *start)) + { + // If a character from the delimiting string + // then skip past it + + start++; + + if (*start == 0) + return 0; + } + + if (*start == 0) + return 0; + + end=start; + + + while (*end != 0) + { + if (strchr(strDelimit, *end)) + { + // if we find a delimiting character + // before the end of the string, then + // terminate the token and move the end + // pointer to the next character + *end = 0; + end++; + return start; + } + + end++; + } + + + // reached the end of the string before finding a delimiter + // so dont move on to the next character + return start; +} +#endif + +#ifdef F_strrchr +char* strrchr(const char * string, int c) +{ + /* use the asm strchr to do strrchr */ + char* lastmatch; + char* result; + + /* if char is never found then this will return 0 */ + /* if char is found then this will return the last matched location + before strchr returned 0 */ + + lastmatch = 0; + result = strchr(string,c); + + while ((int)result != 0) + { + lastmatch=result; + result = strchr(lastmatch+1,c); + } + + return lastmatch; +} +#endif + +#ifdef F_strstr +char * strstr(const char * string, const char * substring) +{ + char* strpos; + + if (string == 0) + return 0; + + if (strlen(substring)==0) + return (char*)string; + + strpos = (char*)string; + + while (*strpos != 0) + { + if (strncmp(strpos, substring, strlen(substring)) == 0) + { + return strpos; + } + + strpos++; + } + + return 0; +} +#endif + + +#ifdef F_strupr +char * strupr(char *str) +{ + char * strptr = str; + + // loop thru each char in string + while (*strptr != '\0') + { + // if char is lowercase, convert to uppercase + if(islower(*strptr)) + *strptr = toupper(*strptr); + strptr++; + } + + return str; +} +#endif + +#ifdef F_strlwr +char * strlwr(char *str) +{ + char * strptr = str; + + // loop thru each char in string + while (*strptr != '\0') + { + // if char is uppercase, convert to lowercase + if(isupper(*strptr)) + *strptr = tolower(*strptr); + strptr++; + } + + return str; +} +#endif + + +#ifdef F_tolower +int tolower(int c) +{ + if (isupper(c)) + c+=32; + + return c; +} +#endif + +#ifdef F_toupper +int toupper(int c) +{ + if (islower(c)) + c-=32; + + return c; +} +#endif + +#ifdef F_isupper +int isupper(int c) +{ + if (c < 'A') + return 0; + + if (c > 'Z') + return 0; + + // passed both criteria, so it + // is an upper case alpha char + return 1; +} +#endif + +#ifdef F_islower +int islower(int c) +{ + if (c < 'a') + return 0; + + if (c > 'z') + return 0; + + // passed both criteria, so it + // is a lower case alpha char + return 1; +} +#endif + +#ifdef F_isalpha +int isalpha(int c) +{ + if (islower(c) || isupper(c)) + return 1; + + return 0; +} +#endif + +#ifdef F_isdigit +int isdigit(int c) +{ + if (c < '0') + return 0; + + if (c > '9') + return 0; + + // passed both criteria, so it + // is a numerical char + return 1; +} +#endif + +#ifdef F_isalnum +int isalnum(int c) +{ + if (isalpha(c) || isdigit(c)) + return 1; + + return 0; +} +#endif + +#ifdef F_iscntrl +int iscntrl(int c) +{ + if (c < 0x20) + return 1; + + if (c == 0x7F) + return 1; + + return 0; +} +#endif + +#ifdef F_isgraph +int isgraph(int c) +{ + if (iscntrl(c)) + return 0; + + if (isspace(c)) + return 0; + + return 1; +} +#endif + +#ifdef F_isprint +int isprint(int c) +{ + if (iscntrl(c)) + return 0; + + return 1; +} +#endif + +#ifdef F_ispunct +int ispunct(int c) +{ + if (iscntrl(c)) + return 0; + + if (isalnum(c)) + return 0; + + if (isspace(c)) + return 0; + + // It's a printable character + // thats not alpha-numeric, or a space + // so its a punctuation character + return 1; +} +#endif + +#ifdef F_isspace +int isspace(int c) +{ + if ((c>=0x09) && (c<=0x0D)) + return 1; + + if (c==0x20) + return 1; + + return 0; +} +#endif + +#ifdef F_isxdigit +int isxdigit(int c) +{ + if (isdigit(c)) + return 1; + + if ((c>='a') && (c<='f')) + return 1; + + if ((c>='A') && (c<='F')) + return 1; + + return 0; +} +#endif + + +// sjis<->ascii conversion routines by Peter Sandström + +struct charmap_t { + unsigned short sjis; + unsigned char ascii; +}; + +#ifdef F__sjis_internals +struct charmap_t sjis_conversion[] = { + { 0x4081, ' ' }, + { 0x6d81, '[' }, + { 0x6e81, ']' }, + { 0x7c81, '-' }, + { 0x5b81, '°' }, + { 0x4581, '¥' }, + { 0x4481, '.' }, + { 0x7B81, '+' }, + { 0x9681, '*' }, + { 0x5E81, '/' }, + { 0x4981, '!' }, + { 0x6881, '"' }, + { 0x9481, '#' }, + { 0x9081, '$' }, + { 0x9381, '%' }, + { 0x9581, '&' }, + { 0x6681, '\'' }, + { 0x6981, '(' }, + { 0x6a81, ')' }, + { 0x8181, '=' }, + { 0x6281, '|' }, + { 0x8f81, '\\' }, + { 0x4881, '?' }, + { 0x5181, '_' }, + { 0x6f81, '{' }, + { 0x7081, '}' }, + { 0x9781, '@' }, + { 0x4781, ';' }, + { 0x4681, ':' }, + { 0x8381, '<' }, + { 0x8481, '>' }, + { 0x4d81, '`' }, + { 0, 0 } +}; + +unsigned char isSpecialSJIS(short sjis) +{ + struct charmap_t *s = &sjis_conversion[0]; + do { + if (s->sjis == sjis) return s->ascii; + s++; + } while (s->sjis != 0); + return 0; +} + +short isSpecialASCII(unsigned char ascii) +{ + struct charmap_t *s = &sjis_conversion[0]; + do { + if (s->ascii == ascii) return s->sjis; + s++; + } while (s->ascii != 0); + return 0; +} +#else +extern struct charmap_t * sjis_conversion; +unsigned char isSpecialSJIS(short sjis); +short isSpecialASCII(unsigned char ascii); +#endif + +#ifdef F_strcpy_ascii +int strcpy_ascii(char* ascii_buff, const short* sjis_buff) +{ + int i; + short ascii, sjis; + + int len = strlen((const char *)sjis_buff)/2; + + for (i=0;i> 8) - 0x1f; + if (ascii>96) ascii--; + } + ascii_buff[i] = ascii; + } + ascii_buff[i+1]=0; + return len; +} +#endif + +#ifdef F_strcpy_sjis +int strcpy_sjis(short* sjis_buff, const char* ascii_buff) +{ + int i; + short ascii, sjis; + + int len = strlen(ascii_buff); + + for (i=0;i96) ascii++; + sjis = ((ascii + 0x1f) << 8) | 0x82; + } + sjis_buff[i] = sjis; + } + sjis_buff[i+1]=0; + return len; +} +#endif + +#ifdef F_strpbrk +char *strpbrk(const char *s, const char *accept) +{ + const char *needle; + for (; *s; s++) { + for (needle = accept; *needle; needle++) { + if (*s == *needle) + return (char *) s; + } + } + + return NULL; +} +#endif + +#ifdef F_strspn +size_t strspn(const char *s, const char *accept) { + const char *c; + + for (c = s; *c; c++) { + if (!strchr(accept, *c)) + return c - s; + } + + return c - s; +} +#endif + +#ifdef F_strcspn +size_t strcspn(const char *s, const char *reject) { + const char *c; + + for (c = s; *c; c++) { + if (strchr(reject, *c)) + return c - s; + } + + return c - s; +} +#endif diff --git a/src/libc/string.h b/src/libc/string.h new file mode 100644 index 00000000..5d3025d0 --- /dev/null +++ b/src/libc/string.h @@ -0,0 +1,100 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * string.h + * + * Copyright (c) 2002-2004 PS2DEV + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: string.h 1095 2005-09-27 21:02:16Z jim $ + */ + +#ifndef _STRING_H +#define _STRING_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* ASM String functions by Jeff Johnston of Cygnus Solutions */ +void * memchr(const void *, int, size_t); +void * memcpy(void *, const void *, size_t); +void * memmove(void *, const void *, size_t); +void * memset(void *, int, size_t); + +int memcmp(const void *, const void *, size_t); + +int strcmp(const char *, const char *); +int strncmp(const char *, const char *, size_t); + +unsigned int strlen(const char *); + +char * strdup(const char *s); + +char * strcat(char *, const char *); +char * strchr(const char *, int); +char * strcpy(char *, const char *); +char * strncat(char *, const char *, size_t); +char * strncpy(char *, const char *, size_t); + +char * strpbrk(const char *s, const char *accept); +size_t strspn(const char *s, const char *accept); +size_t strcspn(const char *s, const char *reject); + +static __inline__ int strcoll(const char *s1, const char *s2) { return strcmp(s1, s2); } +static __inline__ size_t strxfrm(char *dest, const char *src, size_t n) { strncpy(dest, src, n); return n; } + +char * strerror(int); + +// copies ascii string to sjis string +// +// args: dest sjis string buffer +// source ascii string buffer +// returns: length of ascii string copied +int strcpy_sjis(short* sjis_buff, const char* ascii_buff); + +// copies sjis string to ascii string +// +// args: dest ascii string buffer +// source sjis string buffer +// returns: length of sjis string copied +int strcpy_ascii(char* ascii_buff, const short* sjis_buff); + + +/* C String functions by Hiryu (A.Lee) */ +#define stricmp strcasecmp +#define strnicmp strncasecmp + +int strcasecmp(const char *, const char *); +int strncasecmp(const char *, const char *, size_t); + +char * strtok(char *, const char *); +char * strrchr(const char *, int); + +char * strstr(const char *, const char *); + +char * strupr(char *); +char * strlwr(char *); + +static __inline__ void bzero(void * p, size_t n) { memset(p, 0, n); } +static __inline__ void bcopy(const void * s, void * d, size_t n) { memcpy(d, s, n); } +static __inline__ int bcmp(const void * s1, const void * s2, size_t n) { return memcmp(s1, s2, n); } +static __inline__ char * index(const char * s, int c) { return strchr(s, c); } +static __inline__ char * rindex(const char * s, int c) { return strrchr(s, c); } + +/* Backward compatibility... */ +#include + +#ifdef __cplusplus +} +#endif + +#endif // _STRING_H diff --git a/src/libc/terminate.c b/src/libc/terminate.c new file mode 100644 index 00000000..a1a1ff8c --- /dev/null +++ b/src/libc/terminate.c @@ -0,0 +1,34 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * terminate.c - Process exit functions. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: terminate.c 802 2005-07-30 19:38:02Z stefan $ + */ +#include +#include +#include + +extern void _exit(int code); + +__attribute__((weak)) +void abort() +{ + printf("Program aborted.\n"); + + while (1) + _exit(1); +} + +__attribute__((weak)) +void _Exit(int retval) +{ + while (1) + _exit(retval); +} diff --git a/src/libc/time.h b/src/libc/time.h new file mode 100644 index 00000000..0c13dc30 --- /dev/null +++ b/src/libc/time.h @@ -0,0 +1,64 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * time.h + * + * Copyright (c) 2002-2004 PS2DEV + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: time.h 1095 2005-09-27 21:02:16Z jim $ + */ + +#ifndef _TIME_H +#define _TIME_H + +#include + +#ifndef __clock_t_defined +typedef unsigned long clock_t; +#define __clock_t_defined +#endif + +#ifndef __time_t_defined +typedef unsigned long time_t; +#define __time_t_defined +#endif + +struct tm +{ + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +clock_t clock(); +time_t time(time_t *t); + +// to be implemented... +double difftime(time_t time1, time_t time0); +time_t mktime(struct tm *timeptr); +char *asctime(const struct tm *timeptr); +char *ctime(const time_t *timep); +struct tm *gmtime(const time_t *timep); +struct tm *localtime(const time_t *timep); +size_t strftime(char *s, size_t max, const char *format, const struct tm *tm); + +#ifdef __cplusplus +} +#endif + +#endif // TIME_H diff --git a/src/libc/unistd.h b/src/libc/unistd.h new file mode 100644 index 00000000..4b2018c8 --- /dev/null +++ b/src/libc/unistd.h @@ -0,0 +1,21 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * unistd.h + * + * Copyright (c) 2002-2004 PS2DEV + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: unistd.h 1095 2005-09-27 21:02:16Z jim $ + */ + +#ifndef __UNISTD_H__ +#define __UNISTD_H__ + +#include + +#endif diff --git a/src/libc/xprintf.c b/src/libc/xprintf.c new file mode 100644 index 00000000..d46ecf22 --- /dev/null +++ b/src/libc/xprintf.c @@ -0,0 +1,988 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * xprintf.c - Various *printf functions. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: xprintf.c 540 2005-07-08 19:35:10Z warren $ + */ +/* Code borrowed from mysql's xprintf.c, by Richard Hipp */ +/* This xprintf.c file on which this one is based is in public domain. */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +/* +** The maximum number of digits of accuracy in a floating-point conversion. +*/ +#define MAXDIG 20 + +/* The maximum string length. */ +#define PS2LIB_STR_MAX 4096 + +/* Instead of including ctype.h, use the isdigit() prototype because psplibc doesn't + know about newlib, and newlib defines isdigit as a macro that uses _ctype_. */ +int isdigit(int __c); + +int vxprintf(void (*func)(char *, int, void *), void *arg, const char *format, va_list ap); + +#ifdef F_vxprintf +/* +** Conversion types fall into various categories as defined by the +** following enumeration. +*/ + +enum e_type { /* The type of the format field */ + RADIX, /* Integer types. %d, %x, %o, and so forth */ + FLOAT, /* Floating point. %f */ + EXP, /* Exponentional notation. %e and %E */ + GENERIC, /* Floating or exponential, depending on exponent. %g */ + SIZE, /* Return number of characters processed so far. %n */ + STRING, /* Strings. %s */ + PERCENT, /* Percent symbol. %% */ + CHAR, /* Characters. %c */ + ERROR, /* Used to indicate no such conversion type */ +/* The rest are extensions, not normally found in printf() */ + CHARLIT, /* Literal characters. %' */ + SEEIT, /* Strings with visible control characters. %S */ + MEM_STRING, /* A string which should be deleted after use. %z */ + ORDINAL, /* 1st, 2nd, 3rd and so forth */ +}; + +/* +** Each builtin conversion character (ex: the 'd' in "%d") is described +** by an instance of the following structure +*/ +typedef struct s_info { /* Information about each format field */ + int fmttype; /* The format field code letter */ + int base; /* The base for radix conversion */ + char *charset; /* The character set for conversion */ + int flag_signed; /* Is the quantity signed? */ + char *prefix; /* Prefix on non-zero values in alt format */ + enum e_type type; /* Conversion paradigm */ +} info; + +/* +** The following table is searched linearly, so it is good to put the +** most frequently used conversion types first. +*/ +static info fmtinfo[] = { + { 'd', 10, "0123456789", 1, 0, RADIX, }, + { 's', 0, 0, 0, 0, STRING, }, + { 'S', 0, 0, 0, 0, SEEIT, }, + { 'z', 0, 0, 0, 0, MEM_STRING, }, + { 'c', 0, 0, 0, 0, CHAR, }, + { 'o', 8, "01234567", 0, "0", RADIX, }, + { 'u', 10, "0123456789", 0, 0, RADIX, }, + { 'x', 16, "0123456789abcdef", 0, "x0", RADIX, }, + { 'X', 16, "0123456789ABCDEF", 0, "X0", RADIX, }, + { 'r', 10, "0123456789", 0, 0, ORDINAL, }, + { 'f', 0, 0, 1, 0, FLOAT, }, + { 'e', 0, "e", 1, 0, EXP, }, + { 'E', 0, "E", 1, 0, EXP, }, + { 'g', 0, "e", 1, 0, GENERIC, }, + { 'G', 0, "E", 1, 0, GENERIC, }, + { 'i', 10, "0123456789", 1, 0, RADIX, }, + { 'n', 0, 0, 0, 0, SIZE, }, + { 'S', 0, 0, 0, 0, SEEIT, }, + { '%', 0, 0, 0, 0, PERCENT, }, + { 'b', 2, "01", 0, "b0", RADIX, }, /* Binary notation */ + { 'p', 16, "0123456789ABCDEF", 0, "x0", RADIX, }, /* Pointers */ + { '\'', 0, 0, 0, 0, CHARLIT, }, /* Literal char */ +}; +#define NINFO (sizeof(fmtinfo)/sizeof(info)) /* Size of the fmtinfo table */ + +/* +** If NOFLOATINGPOINT is defined, then none of the floating point +** conversions will work. +*/ +#ifndef NOFLOATINGPOINT +/* +** "*val" is a double such that 0.1 <= *val < 10.0 +** Return the ascii code for the leading digit of *val, then +** multiply "*val" by 10.0 to renormalize. +** +** Example: +** input: *val = 3.14159 +** output: *val = 1.4159 function return = '3' +** +** The counter *cnt is incremented each time. After counter exceeds +** 16 (the number of significant digits in a 64-bit float) '0' is +** always returned. +*/ +static int getdigit(long double *val, int *cnt){ + int digit; + long double d; + if( (*cnt)++ >= MAXDIG ) return '0'; + digit = (int)*val; + d = digit; + digit += '0'; + *val = (*val - d)*10.0; + return digit; +} +#endif + +/* +** Setting the size of the BUFFER involves trade-offs. No %d or %f +** conversion can have more than BUFSIZE characters. If the field +** width is larger than BUFSIZE, it is silently shortened. On the +** other hand, this routine consumes more stack space with larger +** BUFSIZEs. If you have some threads for which you want to minimize +** stack space, you should keep BUFSIZE small. +*/ +#define BUFSIZE 100 /* Size of the output buffer */ + +/* +** The root program. All variations call this core. +** +** INPUTS: +** func This is a pointer to a function taking three arguments +** 1. A pointer to the list of characters to be output +** (Note, this list is NOT null terminated.) +** 2. An integer number of characters to be output. +** (Note: This number might be zero.) +** 3. A pointer to anything. Same as the "arg" parameter. +** +** arg This is the pointer to anything which will be passed as the +** third argument to "func". Use it for whatever you like. +** +** fmt This is the format string, as in the usual print. +** +** ap This is a pointer to a list of arguments. Same as in +** vfprint. +** +** OUTPUTS: +** The return value is the total number of characters sent to +** the function "func". Returns -1 on a error. +** +** Note that the order in which automatic variables are declared below +** seems to make a big difference in determining how fast this beast +** will run. +*/ + +int vxprintf(func,arg,format,ap) + void (*func)(char*,int,void*); + void *arg; + const char *format; + va_list ap; +{ + register const char *fmt; /* The format string. */ + register int c; /* Next character in the format string */ + register char *bufpt; /* Pointer to the conversion buffer */ + register int precision; /* Precision of the current field */ + register int length; /* Length of the field */ + register int idx; /* A general purpose loop counter */ + int count; /* Total number of characters output */ + int width; /* Width of the current field */ + int flag_leftjustify; /* True if "-" flag is present */ + int flag_plussign; /* True if "+" flag is present */ + int flag_blanksign; /* True if " " flag is present */ + int flag_alternateform; /* True if "#" flag is present */ + int flag_zeropad; /* True if field width constant starts with zero */ + int flag_long; /* True if "l" flag is present */ + int flag_center; /* True if "=" flag is present */ + unsigned long long longvalue; /* Value for integer types */ + + long double realvalue; /* Value for real types */ + info *infop; /* Pointer to the appropriate info structure */ + char buf[BUFSIZE]; /* Conversion buffer */ + char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */ + int errorflag = 0; /* True if an error is encountered */ + enum e_type xtype; /* Conversion paradigm */ + char *zMem = 0; /* String to be freed */ + static char spaces[] = + " "; +#define SPACESIZE (sizeof(spaces)-1) +#ifndef NOFLOATINGPOINT + int exp; /* exponent of real numbers */ + long double rounder; /* Used for rounding floating point values */ + int flag_dp; /* True if decimal point should be shown */ + int flag_rtz; /* True if trailing zeros should be removed */ + int flag_exp; /* True to force display of the exponent */ + int nsd; /* Number of significant digits returned */ +#endif + + fmt = format; /* Put in a register for speed */ + count = length = 0; + bufpt = 0; + for(; (c=(*fmt))!=0; ++fmt){ + if( c!='%' ){ + register int amt; + bufpt = (char *)fmt; + amt = 1; + while( (c=(*++fmt))!='%' && c!=0 ) amt++; + (*func)(bufpt,amt,arg); + count += amt; + if( c==0 ) break; + } + if( (c=(*++fmt))==0 ){ + errorflag = 1; + (*func)("%",1,arg); + count++; + break; + } + /* Find out what flags are present */ + flag_leftjustify = flag_plussign = flag_blanksign = + flag_alternateform = flag_zeropad = flag_center = 0; + do{ + switch( c ){ + case '-': flag_leftjustify = 1; c = 0; break; + case '+': flag_plussign = 1; c = 0; break; + case ' ': flag_blanksign = 1; c = 0; break; + case '#': flag_alternateform = 1; c = 0; break; + case '0': flag_zeropad = 1; c = 0; break; + case '=': flag_center = 1; c = 0; break; + default: break; + } + }while( c==0 && (c=(*++fmt))!=0 ); + if( flag_center ) flag_leftjustify = 0; + /* Get the field width */ + width = 0; + if( c=='*' ){ + width = va_arg(ap,int); + if( width<0 ){ + flag_leftjustify = 1; + width = -width; + } + c = *++fmt; + }else{ + while( isdigit(c) ){ + width = width*10 + c - '0'; + c = *++fmt; + } + } + if( width > BUFSIZE-10 ){ + width = BUFSIZE-10; + } + /* Get the precision */ + if( c=='.' ){ + precision = 0; + c = *++fmt; + if( c=='*' ){ + precision = va_arg(ap,int); +#ifndef COMPATIBILITY + /* This is sensible, but SUN OS 4.1 doesn't do it. */ + if( precision<0 ) precision = -precision; +#endif + c = *++fmt; + }else{ + while( isdigit(c) ){ + precision = precision*10 + c - '0'; + c = *++fmt; + } + } + /* Limit the precision to prevent overflowing buf[] during conversion */ + if( precision>BUFSIZE-40 ) precision = BUFSIZE-40; + }else{ + precision = -1; + } + /* Get the conversion type modifier */ + if( c=='l' ){ + flag_long = 1; + c = *++fmt; + if( c == 'l' ){ + flag_long = 2; + c = *++fmt; + } + }else{ + flag_long = 0; + } + /* Fetch the info entry for the field */ + infop = 0; + for(idx=0; idxtype; + } + + /* + ** At this point, variables are initialized as follows: + ** + ** flag_alternateform TRUE if a '#' is present. + ** flag_plussign TRUE if a '+' is present. + ** flag_leftjustify TRUE if a '-' is present or if the + ** field width was negative. + ** flag_zeropad TRUE if the width began with 0. + ** flag_long TRUE if the letter 'l' (ell) prefixed + ** the conversion character. + ** flag_blanksign TRUE if a ' ' is present. + ** width The specified field width. This is + ** always non-negative. Zero is the default. + ** precision The specified precision. The default + ** is -1. + ** xtype The class of the conversion. + ** infop Pointer to the appropriate info struct. + */ + switch( xtype ){ + case ORDINAL: + case RADIX: + if(( flag_long>1 )&&( infop->flag_signed )){ + signed long long t = va_arg(ap,signed long long); + longvalue = t; + }else if(( flag_long>1 )&&( !infop->flag_signed )){ + unsigned long long t = va_arg(ap,unsigned long long); + longvalue = t; + }else if(( flag_long )&&( infop->flag_signed )){ + signed long t = va_arg(ap,signed long); + longvalue = t; + }else if(( flag_long )&&( !infop->flag_signed )){ + unsigned long t = va_arg(ap,unsigned long); + longvalue = t; + }else if(( !flag_long )&&( infop->flag_signed )){ + signed int t = va_arg(ap,signed int) & ((unsigned long) 0xffffffff); + longvalue = t; + }else{ + unsigned int t = va_arg(ap,unsigned int) & ((unsigned long) 0xffffffff); + longvalue = t; + } +#ifdef COMPATIBILITY + /* For the format %#x, the value zero is printed "0" not "0x0". + ** I think this is stupid. */ + if( longvalue==0 ) flag_alternateform = 0; +#else + /* More sensible: turn off the prefix for octal (to prevent "00"), + ** but leave the prefix for hex. */ + if( longvalue==0 && infop->base==8 ) flag_alternateform = 0; +#endif + if( infop->flag_signed ){ + if( *(long long*)&longvalue<0 ){ + longvalue = -*(long long*)&longvalue; + prefix = '-'; + }else if( flag_plussign ) prefix = '+'; + else if( flag_blanksign ) prefix = ' '; + else prefix = 0; + }else prefix = 0; + if( flag_zeropad && precision3 || (b>10 && b<14) ){ + bufpt[0] = 't'; + bufpt[1] = 'h'; + }else if( a==1 ){ + bufpt[0] = 's'; + bufpt[1] = 't'; + }else if( a==2 ){ + bufpt[0] = 'n'; + bufpt[1] = 'd'; + }else if( a==3 ){ + bufpt[0] = 'r'; + bufpt[1] = 'd'; + } + } + { + register char *cset; /* Use registers for speed */ + register int base; + cset = infop->charset; + base = infop->base; + do{ /* Convert to ascii */ + *(--bufpt) = cset[longvalue%base]; + longvalue = longvalue/base; + }while( longvalue>0 ); + } + length = (int)(&buf[BUFSIZE]-bufpt); + if(infop->fmttype == 'p') + { + precision = 8; + flag_alternateform = 1; + } + + for(idx=precision-length; idx>0; idx--){ + *(--bufpt) = '0'; /* Zero pad */ + } + if( prefix ) *(--bufpt) = prefix; /* Add sign */ + if( flag_alternateform && infop->prefix ){ /* Add "0" or "0x" */ + char *pre, x; + pre = infop->prefix; + if( *bufpt!=pre[0] ){ + for(pre=infop->prefix; (x=(*pre))!=0; pre++) *(--bufpt) = x; + } + } + + length = (int)(&buf[BUFSIZE]-bufpt); + break; + case FLOAT: + case EXP: + case GENERIC: + realvalue = va_arg(ap,double); +#ifndef NOFLOATINGPOINT + if( precision<0 ) precision = 6; /* Set default precision */ + if( precision>BUFSIZE-10 ) precision = BUFSIZE-10; + if( realvalue<0.0 ){ + realvalue = -realvalue; + prefix = '-'; + }else{ + if( flag_plussign ) prefix = '+'; + else if( flag_blanksign ) prefix = ' '; + else prefix = 0; + } + if( infop->type==GENERIC && precision>0 ) precision--; + rounder = 0.0; +#ifdef COMPATIBILITY + /* Rounding works like BSD when the constant 0.4999 is used. Wierd! */ + for(idx=precision, rounder=0.4999; idx>0; idx--, rounder*=0.1); +#else + /* It makes more sense to use 0.5 */ + if( precision>MAXDIG-1 ) idx = MAXDIG-1; + else idx = precision; + for(rounder=0.5; idx>0; idx--, rounder*=0.1); +#endif + if( infop->type==FLOAT ) realvalue += rounder; + /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */ + exp = 0; + if( realvalue>0.0 ){ + int k = 0; + while( realvalue>=1e8 && k++<100 ){ realvalue *= 1e-8; exp+=8; } + while( realvalue>=10.0 && k++<100 ){ realvalue *= 0.1; exp++; } + while( realvalue<1e-8 && k++<100 ){ realvalue *= 1e8; exp-=8; } + while( realvalue<1.0 && k++<100 ){ realvalue *= 10.0; exp--; } + if( k>=100 ){ + bufpt = "NaN"; + length = 3; + break; + } + } + bufpt = buf; + /* + ** If the field type is GENERIC, then convert to either EXP + ** or FLOAT, as appropriate. + */ + flag_exp = xtype==EXP; + if( xtype!=FLOAT ){ + realvalue += rounder; + if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; } + } + if( xtype==GENERIC ){ + flag_rtz = !flag_alternateform; + if( exp<-4 || exp>precision ){ + xtype = EXP; + }else{ + precision = precision - exp; + xtype = FLOAT; + } + }else{ + flag_rtz = 0; + } + /* + ** The "exp+precision" test causes output to be of type EXP if + ** the precision is too large to fit in buf[]. + */ + nsd = 0; + if( xtype==FLOAT && exp+precision0 || flag_alternateform); + if( prefix ) *(bufpt++) = prefix; /* Sign */ + if( exp<0 ) *(bufpt++) = '0'; /* Digits before "." */ + else for(; exp>=0; exp--) *(bufpt++) = getdigit(&realvalue,&nsd); + if( flag_dp ) *(bufpt++) = '.'; /* The decimal point */ + for(exp++; exp<0 && precision>0; precision--, exp++){ + *(bufpt++) = '0'; + } + while( (precision--)>0 ) *(bufpt++) = getdigit(&realvalue,&nsd); + *(bufpt--) = 0; /* Null terminate */ + if( flag_rtz && flag_dp ){ /* Remove trailing zeros and "." */ + while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0; + if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0; + } + bufpt++; /* point to next free slot */ + }else{ /* EXP or GENERIC */ + flag_dp = (precision>0 || flag_alternateform); + if( prefix ) *(bufpt++) = prefix; /* Sign */ + *(bufpt++) = getdigit(&realvalue,&nsd); /* First digit */ + if( flag_dp ) *(bufpt++) = '.'; /* Decimal point */ + while( (precision--)>0 ) *(bufpt++) = getdigit(&realvalue,&nsd); + bufpt--; /* point to last digit */ + if( flag_rtz && flag_dp ){ /* Remove tail zeros */ + while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0; + if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0; + } + bufpt++; /* point to next free slot */ + if( exp || flag_exp ){ + *(bufpt++) = infop->charset[0]; + if( exp<0 ){ *(bufpt++) = '-'; exp = -exp; } /* sign of exp */ + else { *(bufpt++) = '+'; } + if( exp>=100 ){ + *(bufpt++) = (exp/100)+'0'; /* 100's digit */ + exp %= 100; + } + *(bufpt++) = exp/10+'0'; /* 10's digit */ + *(bufpt++) = exp%10+'0'; /* 1's digit */ + } + } + /* The converted number is in buf[] and zero terminated. Output it. + ** Note that the number is in the usual order, not reversed as with + ** integer conversions. */ + length = (int)(bufpt-buf); + bufpt = buf; + + /* Special case: Add leading zeros if the flag_zeropad flag is + ** set and we are not left justified */ + if( flag_zeropad && !flag_leftjustify && length < width){ + int i; + int nPad = width - length; + for(i=width; i>=nPad; i--){ + bufpt[i] = bufpt[i-nPad]; + } + i = prefix!=0; + while( nPad-- ) bufpt[i++] = '0'; + length = width; + } +#endif + break; + case SIZE: + *(va_arg(ap,int*)) = count; + length = width = 0; + break; + case PERCENT: + buf[0] = '%'; + bufpt = buf; + length = 1; + break; + case CHARLIT: + case CHAR: + c = buf[0] = (xtype==CHAR ? va_arg(ap,int) : *++fmt); + if( precision>=0 ){ + for(idx=1; idx=0 && precision=0x7f ){ + buf[i++] = '^'; + buf[i] = (c&0x1f)+0x40; + }else{ + buf[i] = c; + } + } + bufpt = buf; + length = i; + if( precision>=0 && precision0 ){ + if( flag_center ){ + nspace = nspace/2; + width -= nspace; + flag_leftjustify = 1; + } + count += nspace; + while( nspace>=SPACESIZE ){ + (*func)(spaces,SPACESIZE,arg); + nspace -= SPACESIZE; + } + if( nspace>0 ) (*func)(spaces,nspace,arg); + } + } + if( length>0 ){ + (*func)(bufpt,length,arg); + count += length; + } + if( xtype==MEM_STRING && zMem ){ + free(zMem); + } + if( flag_leftjustify ){ + register int nspace; + nspace = width-length; + if( nspace>0 ){ + count += nspace; + while( nspace>=SPACESIZE ){ + (*func)(spaces,SPACESIZE,arg); + nspace -= SPACESIZE; + } + if( nspace>0 ) (*func)(spaces,nspace,arg); + } + } + }/* End for loop over the format string */ + return errorflag ? -1 : count; +} /* End of function */ +#endif + +#ifdef F__xprintf +/* +** This non-standard function is still occasionally useful.... +*/ +int xprintf( + void (*func)(char*,int,void*), + void *arg, + const char *format, + ... +){ + va_list ap; + va_start(ap,format); + return vxprintf(func,arg,format,ap); +} +#endif + +/* +** Now for string-print, also as found in any standard library. +** Add to this the snprint function which stops added characters +** to the string at a given length. +** +** Note that snprint returns the length of the string as it would +** be if there were no limit on the output. +*/ +struct s_strargument { /* Describes the string being written to */ + char *next; /* Next free slot in the string */ + char *last; /* Last available slot in the string */ +}; + +void __sout(char *, int, void *); +#ifdef F___sout +void __sout(txt,amt,arg) + char *txt; + int amt; + void *arg; +{ + register char *head; + register const char *t; + register int a; + register char *tail; + a = amt; + t = txt; + head = ((struct s_strargument*)arg)->next; + tail = ((struct s_strargument*)arg)->last; + if( tail ){ + while( a-- >0 && head0 ) *(head++) = *(t++); + } + *head = 0; + ((struct s_strargument*)arg)->next = head; +} +#endif + +#ifdef F_vsnprintf +int vsnprintf(char *buf, size_t n, const char *fmt, va_list ap){ + struct s_strargument arg; + arg.next = buf; + arg.last = &buf[n-1]; + *buf = 0; + return vxprintf(__sout,&arg,fmt,ap); +} +#endif + +#ifdef F_snprintf +int snprintf(char *str, size_t sz, const char *format, ...) +{ + va_list args; + struct s_strargument arg; + int ret; + + arg.next = str; + arg.last = &str[sz-1]; + + va_start(args, format); + ret = vxprintf(__sout, &arg, format, args); + va_end(args); + + return ret; +} +#endif + +#ifdef F_vsprintf +int vsprintf(char *buf, const char *fmt, va_list ap){ + struct s_strargument arg; + arg.next = buf; + arg.last = NULL; + *buf = 0; + return vxprintf(__sout,&arg,fmt,ap); +} +#endif + +#ifdef F_sprintf +__attribute__((weak)) +int sprintf (char *str, const char *format, ...) +{ + va_list args; + struct s_strargument arg; + int ret; + + arg.next = str; + arg.last = NULL; + + va_start(args, format); + ret = vxprintf(__sout, &arg, format, args); + va_end(args); + + return ret; +} +#endif + +/* +** The following section of code handles the mprintf routine, that +** writes to memory obtained from malloc(). +*/ + +/* This structure is used to store state information about the +** write in progress +*/ +__attribute__((weak)) +struct sgMprintf { + char *zBase; /* A base allocation */ + char *zText; /* The string collected so far */ + int nChar; /* Length of the string so far */ + int nAlloc; /* Amount of space allocated in zText */ +}; + +void __mout(char *, int, void*); + +#ifdef F___mout +/* The xprintf callback function. */ +void __mout(zNewText,nNewChar,arg) + char *zNewText; + int nNewChar; + void *arg; +{ + struct sgMprintf *pM = (struct sgMprintf*)arg; + if( pM->nChar + nNewChar + 1 > pM->nAlloc ){ + pM->nAlloc = pM->nChar + nNewChar*2 + 1; + if( pM->zText==pM->zBase ){ + pM->zText = malloc(pM->nAlloc); + if( pM->zText && pM->nChar ) memcpy(pM->zText,pM->zBase,pM->nChar); + }else{ + pM->zText = realloc(pM->zText, pM->nAlloc); + } + } + if( pM->zText ){ + memcpy(&pM->zText[pM->nChar], zNewText, nNewChar); + pM->nChar += nNewChar; + pM->zText[pM->nChar] = 0; + } +} +#endif + +/* +** mprintf() works like printf(), but allocations memory to hold the +** resulting string and returns a pointer to the allocated memory. +** +** We changed the name to TclMPrint() to conform with the Tcl private +** routine naming conventions. +*/ + +#ifdef F_mprintf +char *mprintf(const char *zFormat, ...){ + va_list ap; + struct sgMprintf sMprintf; + char *zNew; + char zBuf[200]; + + va_start(ap,zFormat); + sMprintf.nChar = 0; + sMprintf.nAlloc = sizeof(zBuf); + sMprintf.zText = zBuf; + sMprintf.zBase = zBuf; + vxprintf(__mout,&sMprintf,zFormat,ap); + va_end(ap); + if( sMprintf.zText==sMprintf.zBase ){ + zNew = malloc( sMprintf.nChar+1 ); + if( zNew ) strcpy(zNew,zBuf); + }else{ + zNew = realloc(sMprintf.zText,sMprintf.nChar+1); + } + + return zNew; +} +#endif + +/* This is the varargs version of mprintf. +** +** The name is changed to TclVMPrintf() to conform with Tcl naming +** conventions. +*/ +#ifdef F_vmprintf +char *vmprintf(const char *zFormat,va_list ap){ + struct sgMprintf sMprintf; + char zBuf[200]; + sMprintf.nChar = 0; + sMprintf.zText = zBuf; + sMprintf.nAlloc = sizeof(zBuf); + sMprintf.zBase = zBuf; + vxprintf(__mout,&sMprintf,zFormat,ap); + if( sMprintf.zText==sMprintf.zBase ){ + sMprintf.zText = malloc( strlen(zBuf)+1 ); + if( sMprintf.zText ) strcpy(sMprintf.zText,zBuf); + }else{ + sMprintf.zText = realloc(sMprintf.zText,sMprintf.nChar+1); + } + return sMprintf.zText; +} +#endif + +#ifdef F_asprintf +int asprintf(char ** strp, const char *zFormat, ...){ + va_list ap; + struct sgMprintf sMprintf; + char *zNew; + char zBuf[200]; + + va_start(ap,zFormat); + sMprintf.nChar = 0; + sMprintf.nAlloc = sizeof(zBuf); + sMprintf.zText = zBuf; + sMprintf.zBase = zBuf; + vxprintf(__mout,&sMprintf,zFormat,ap); + va_end(ap); + if( sMprintf.zText==sMprintf.zBase ){ + zNew = malloc( sMprintf.nChar+1 ); + if( zNew ) strcpy(zNew,zBuf); + }else{ + zNew = realloc(sMprintf.zText,sMprintf.nChar+1); + } + + *strp = zNew; + + return sMprintf.nChar+1; +} +#endif + +#ifdef F_vasprintf +int vasprintf(char **strp, const char *format, va_list ap) { + struct sgMprintf sMprintf; + char zBuf[200]; + sMprintf.nChar = 0; + sMprintf.zText = zBuf; + sMprintf.nAlloc = sizeof(zBuf); + sMprintf.zBase = zBuf; + vxprintf(__mout,&sMprintf,format,ap); + if( sMprintf.zText==sMprintf.zBase ){ + sMprintf.zText = malloc( strlen(zBuf)+1 ); + if( sMprintf.zText ) strcpy(sMprintf.zText,zBuf); + }else{ + sMprintf.zText = realloc(sMprintf.zText,sMprintf.nChar+1); + } + *strp = sMprintf.zText; + return sMprintf.nChar; +} +#endif + +/* +** The following section of code handles the standard fprintf routines +** for pthreads. +*/ + +void __fout(char *, int, void *); + +#ifdef F___fout +void __fout(zNewText,nNewChar,arg) + char *zNewText; + int nNewChar; + void *arg; +{ + fwrite(zNewText,1,nNewChar,(FILE*)arg); +} +#endif + +#ifdef F_fprintf +/* The public interface routines */ +int fprintf(FILE *pOut, const char *zFormat, ...){ + va_list ap; + int retc; + + va_start(ap,zFormat); + retc = vxprintf(__fout,pOut,zFormat,ap); + va_end(ap); + return retc; +} +#endif + +#ifdef F_vfprintf +int vfprintf(FILE *pOut, const char *zFormat, va_list ap){ + return vxprintf(__fout,pOut,zFormat,ap); +} +#endif + + +#ifdef F_printf +int printf(const char *format, ...) +{ + va_list args; + int ret; + + va_start(args, format); + ret = vprintf(format, args); + va_end(args); + + return ret; +} +#endif + +#ifdef F_vprintf +int vprintf(const char *format, va_list args) +{ + static char buf[PS2LIB_STR_MAX]; + int ret; + + ret = vsnprintf(buf, PS2LIB_STR_MAX, format, args); + + sceIoWrite(1, buf, ret); + return ret; +} +#endif + +#ifdef F_putchar +/* Get rid of the newlib macro definition. */ +#ifdef putchar +#undef putchar +#endif +int putchar( int chr ) +{ + sceIoWrite(1, &chr, 1); + return chr; +} +#endif diff --git a/src/mp3/Makefile.am b/src/mp3/Makefile.am new file mode 100755 index 00000000..ac8069c6 --- /dev/null +++ b/src/mp3/Makefile.am @@ -0,0 +1,25 @@ + +libdir = @PSPSDK_LIBDIR@ + +CC = @PSP_CC@ +CCAS = $(CC) +AR = @PSP_AR@ +RANLIB = @PSP_RANLIB@ + +INCLUDES = -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel +CFLAGS = @PSPSDK_CFLAGS@ +CCASFLAGS = $(CFLAGS) -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel + +MP3_OBJS = sceMp3_0000.o sceMp3_0001.o sceMp3_0002.o sceMp3_0003.o sceMp3_0004.o sceMp3_0005.o sceMp3_0006.o sceMp3_0007.o sceMp3_0008.o sceMp3_0009.o sceMp3_0010.o sceMp3_0011.o sceMp3_0012.o sceMp3_0013.o sceMp3_0014.o sceMp3_0015.o sceMp3_0016.o sceMp3_0017.o sceMp3_0018.o sceMp3_0019.o + +libpspmp3includedir = @PSPSDK_INCLUDEDIR@ +libpspmp3include_HEADERS = pspmp3.h + +lib_LIBRARIES = libpspmp3.a + + +libpspmp3_a_SOURCES = sceMp3.S +libpspmp3_a_LIBADD = $(MP3_OBJS) + +$(MP3_OBJS): sceMp3.S + $(COMPILE) -DF_$* $< -c -o $@ diff --git a/src/mp3/pspmp3.h b/src/mp3/pspmp3.h new file mode 100755 index 00000000..1240bfab --- /dev/null +++ b/src/mp3/pspmp3.h @@ -0,0 +1,202 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspmp3.h - Prototypes for the sceMp3 library + * + * Copyright (c) 2008 David Perry + * Copyright (c) 2008 Alexander Berl + * + * $Id: $ + */ + +#ifndef __SCELIBMP3_H__ +#define __SCELIBMP3_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct SceMp3InitArg { + /** Stream start position */ + SceUInt32 mp3StreamStart; + /** Unknown - set to 0 */ + SceUInt32 unk1; + /** Stream end position */ + SceUInt32 mp3StreamEnd; + /** Unknown - set to 0 */ + SceUInt32 unk2; + /** Pointer to a buffer to contain raw mp3 stream data (+1472 bytes workspace) */ + SceVoid* mp3Buf; + /** Size of mp3Buf buffer (must be >= 8192) */ + SceInt32 mp3BufSize; + /** Pointer to decoded pcm samples buffer */ + SceVoid* pcmBuf; + /** Size of pcmBuf buffer (must be >= 9216) */ + SceInt32 pcmBufSize; +} SceMp3InitArg; + +/** + * sceMp3ReserveMp3Handle + * + * @param args - Pointer to SceMp3InitArg structure + * + * @return sceMp3 handle on success, < 0 on error. + */ +SceInt32 sceMp3ReserveMp3Handle(SceMp3InitArg* args); + +/** + * sceMp3ReleaseMp3Handle + * + * @param handle - sceMp3 handle + * + * @return 0 if success, < 0 on error. + */ +SceInt32 sceMp3ReleaseMp3Handle(SceInt32 handle); + +/** + * sceMp3InitResource + * + * @return 0 if success, < 0 on error. + */ +SceInt32 sceMp3InitResource(); + +/** + * sceMp3TermResource + * + * @return 0 if success, < 0 on error. + */ +SceInt32 sceMp3TermResource(); + +/** + * sceMp3Init + * + * @param handle - sceMp3 handle + * + * @return 0 if success, < 0 on error. + */ +SceInt32 sceMp3Init(SceInt32 handle); + +/** + * sceMp3Decode + * + * @param handle - sceMp3 handle + * @param dst - Pointer to destination pcm samples buffer + * + * @return number of bytes in decoded pcm buffer, < 0 on error. + */ +SceInt32 sceMp3Decode(SceInt32 handle, SceShort16** dst); + +/** + * sceMp3GetInfoToAddStreamData + * + * @param handle - sceMp3 handle + * @param dst - Pointer to stream data buffer + * @param towrite - Space remaining in stream data buffer + * @param srcpos - Position in source stream to start reading from + * + * @return 0 if success, < 0 on error. + */ +SceInt32 sceMp3GetInfoToAddStreamData(SceInt32 handle, SceUChar8** dst, SceInt32* towrite, SceInt32* srcpos); + +/** + * sceMp3NotifyAddStreamData + * + * @param handle - sceMp3 handle + * @param size - number of bytes added to the stream data buffer + * + * @return 0 if success, < 0 on error. + */ +SceInt32 sceMp3NotifyAddStreamData(SceInt32 handle, SceInt32 size); + +/** + * sceMp3CheckStreamDataNeeded + * + * @param handle - sceMp3 handle + * + * @return 1 if more stream data is needed, < 0 on error. + */ +SceInt32 sceMp3CheckStreamDataNeeded(SceInt32 handle); + +/** + * sceMp3SetLoopNum + * + * @param handle - sceMp3 handle + * @param loop - Number of loops + * + * @return 0 if success, < 0 on error. + */ +SceInt32 sceMp3SetLoopNum(SceInt32 handle, SceInt32 loop); + +/** + * sceMp3GetLoopNum + * + * @param handle - sceMp3 handle + * + * @return Number of loops + */ +SceInt32 sceMp3GetLoopNum(SceInt32 handle); + +/** + * sceMp3GetSumDecodedSample + * + * @param handle - sceMp3 handle + * + * @return Number of decoded samples + */ +SceInt32 sceMp3GetSumDecodedSample(SceInt32 handle); + +/** + * sceMp3GetMaxOutputSample + * + * @param handle - sceMp3 handle + * + * @return Number of max samples to output + */ +SceInt32 sceMp3GetMaxOutputSample(SceInt32 handle); + +/** + * sceMp3GetSamplingRate + * + * @param handle - sceMp3 handle + * + * @return Sampling rate of the mp3 + */ +SceInt32 sceMp3GetSamplingRate(SceInt32 handle); + +/** + * sceMp3GetBitRate + * + * @param handle - sceMp3 handle + * + * @return Bitrate of the mp3 + */ +SceInt32 sceMp3GetBitRate(SceInt32 handle); + +/** + * sceMp3GetMp3ChannelNum + * + * @param handle - sceMp3 handle + * + * @return Number of channels of the mp3 + */ +SceInt32 sceMp3GetMp3ChannelNum(SceInt32 handle); + +/** + * sceMp3ResetPlayPosition + * + * @param handle - sceMp3 handle + * + * @return < 0 on error + */ +SceInt32 sceMp3ResetPlayPosition(SceInt32 handle); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/mp3/sceMp3.S b/src/mp3/sceMp3.S new file mode 100755 index 00000000..72419781 --- /dev/null +++ b/src/mp3/sceMp3.S @@ -0,0 +1,67 @@ + .set noreorder + +#include "pspimport.s" + +// Build List +// sceMp3_0000.o sceMp3_0001.o sceMp3_0002.o sceMp3_0003.o sceMp3_0004.o sceMp3_0005.o sceMp3_0006.o sceMp3_0007.o sceMp3_0008.o sceMp3_0009.o sceMp3_0010.o sceMp3_0011.o sceMp3_0012.o sceMp3_0013.o sceMp3_0014.o sceMp3_0015.o sceMp3_0016.o sceMp3_0017.o sceMp3_0018.o sceMp3_0019.o + +#ifdef F_sceMp3_0000 + IMPORT_START "sceMp3",0x00090011 +#endif +#ifdef F_sceMp3_0001 + IMPORT_FUNC "sceMp3",0x07EC321A,sceMp3ReserveMp3Handle +#endif +#ifdef F_sceMp3_0002 + IMPORT_FUNC "sceMp3",0x0DB149F4,sceMp3NotifyAddStreamData +#endif +#ifdef F_sceMp3_0003 + IMPORT_FUNC "sceMp3",0x2A368661,sceMp3ResetPlayPosition +#endif +#ifdef F_sceMp3_0004 + IMPORT_FUNC "sceMp3",0x354D27EA,sceMp3GetSumDecodedSample +#endif +#ifdef F_sceMp3_0005 + IMPORT_FUNC "sceMp3",0x35750070,sceMp3InitResource +#endif +#ifdef F_sceMp3_0006 + IMPORT_FUNC "sceMp3",0x3C2FA058,sceMp3TermResource +#endif +#ifdef F_sceMp3_0007 + IMPORT_FUNC "sceMp3",0x3CEF484F,sceMp3SetLoopNum +#endif +#ifdef F_sceMp3_0008 + IMPORT_FUNC "sceMp3",0x44E07129,sceMp3Init +#endif +#ifdef F_sceMp3_0009 + IMPORT_FUNC "sceMp3",0x732B042A,sceMp3_732B042A +#endif +#ifdef F_sceMp3_0010 + IMPORT_FUNC "sceMp3",0x7F696782,sceMp3GetMp3ChannelNum +#endif +#ifdef F_sceMp3_0011 + IMPORT_FUNC "sceMp3",0x87677E40,sceMp3GetBitRate +#endif +#ifdef F_sceMp3_0012 + IMPORT_FUNC "sceMp3",0x87C263D1,sceMp3GetMaxOutputSample +#endif +#ifdef F_sceMp3_0013 + IMPORT_FUNC "sceMp3",0x8AB81558,sceMp3_8AB81558 +#endif +#ifdef F_sceMp3_0014 + IMPORT_FUNC "sceMp3",0x8F450998,sceMp3GetSamplingRate +#endif +#ifdef F_sceMp3_0015 + IMPORT_FUNC "sceMp3",0xA703FE0F,sceMp3GetInfoToAddStreamData +#endif +#ifdef F_sceMp3_0016 + IMPORT_FUNC "sceMp3",0xD021C0FB,sceMp3Decode +#endif +#ifdef F_sceMp3_0017 + IMPORT_FUNC "sceMp3",0xD0A56296,sceMp3CheckStreamDataNeeded +#endif +#ifdef F_sceMp3_0018 + IMPORT_FUNC "sceMp3",0xD8F54A51,sceMp3GetLoopNum +#endif +#ifdef F_sceMp3_0019 + IMPORT_FUNC "sceMp3",0xF5478233,sceMp3ReleaseMp3Handle +#endif diff --git a/src/mpeg/Makefile.am b/src/mpeg/Makefile.am new file mode 100644 index 00000000..e507eb55 --- /dev/null +++ b/src/mpeg/Makefile.am @@ -0,0 +1,62 @@ + +libdir = @PSPSDK_LIBDIR@ + +CC = @PSP_CC@ +CCAS = $(CC) +AR = @PSP_AR@ +RANLIB = @PSP_RANLIB@ + +INCLUDES = -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel +CFLAGS = @PSPSDK_CFLAGS@ +CCASFLAGS = $(CFLAGS) -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel + +MPEG_OBJS = sceMpeg_0000.o sceMpeg_0001.o sceMpeg_0002.o sceMpeg_0003.o sceMpeg_0004.o sceMpeg_0005.o sceMpeg_0006.o sceMpeg_0007.o sceMpeg_0008.o sceMpeg_0009.o sceMpeg_0010.o sceMpeg_0011.o sceMpeg_0012.o sceMpeg_0013.o sceMpeg_0014.o sceMpeg_0015.o sceMpeg_0016.o sceMpeg_0017.o sceMpeg_0018.o sceMpeg_0019.o sceMpeg_0020.o sceMpeg_0021.o sceMpeg_0022.o sceMpeg_0023.o sceMpeg_0024.o sceMpeg_0025.o sceMpeg_0026.o sceMpeg_0027.o sceMpeg_0028.o sceMpeg_0029.o sceMpeg_0030.o sceMpeg_0031.o sceMpeg_0032.o sceMpeg_0033.o sceMpeg_0034.o sceMpeg_0035.o sceMpeg_0036.o sceMpeg_0037.o sceMpeg_0038.o + +MPEGBASE_OBJS = sceMpegbase_0000.o sceMpegbase_0001.o sceMpegbase_0002.o sceMpegbase_0003.o sceMpegbase_0004.o sceMpegbase_0005.o sceMpegbase_0006.o sceMpegbase_0007.o sceMpegbase_0008.o sceMpegbase_0009.o + +MPEGBASE_DRIVER_OBJS = sceMpegbase_driver_0000.o sceMpegbase_driver_0001.o sceMpegbase_driver_0002.o sceMpegbase_driver_0003.o sceMpegbase_driver_0004.o sceMpegbase_driver_0005.o sceMpegbase_driver_0006.o sceMpegbase_driver_0007.o sceMpegbase_driver_0008.o sceMpegbase_driver_0009.o sceMpegbase_driver_0010.o + +JPEG_OBJS = sceJpeg_0000.o sceJpeg_0001.o sceJpeg_0002.o sceJpeg_0003.o sceJpeg_0004.o sceJpeg_0005.o sceJpeg_0006.o sceJpeg_0007.o sceJpeg_0008.o sceJpeg_0009.o sceJpeg_0010.o sceJpeg_0011.o sceJpeg_0012.o sceJpeg_0013.o + + +libpspmpegincludedir = @PSPSDK_INCLUDEDIR@ +libpspmpeginclude_HEADERS = pspmpeg.h + +libpspmpegbaseincludedir = @PSPSDK_INCLUDEDIR@ +libpspmpegbaseinclude_HEADERS = pspmpegbase.h + +libpspmpegbase_driverincludedir = @PSPSDK_INCLUDEDIR@ +libpspmpegbase_driverinclude_HEADERS = pspmpegbase.h + +libpspjpegincludedir = @PSPSDK_INCLUDEDIR@ +libpspjpeginclude_HEADERS = pspjpeg.h + + +lib_LIBRARIES = libpspmpeg.a libpspmpegbase.a libpspmpegbase_driver.a libpspjpeg.a + + +libpspmpeg_a_SOURCES = sceMpeg.S +libpspmpeg_a_LIBADD = $(MPEG_OBJS) + +libpspmpegbase_a_SOURCES = sceMpegbase.S +libpspmpegbase_a_LIBADD = $(MPEGBASE_OBJS) + +libpspmpegbase_driver_a_SOURCES = sceMpegbase_driver.S +libpspmpegbase_driver_a_LIBADD = $(MPEGBASE_DRIVER_OBJS) + +libpspjpeg_a_SOURCES = sceJpeg.S +libpspjpeg_a_LIBADD = $(JPEG_OBJS) + + +$(MPEG_OBJS): sceMpeg.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(MPEGBASE_OBJS): sceMpegbase.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(MPEGBASE_DRIVER_OBJS): sceMpegbase_driver.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(JPEG_OBJS): sceJpeg.S + $(COMPILE) -DF_$* $< -c -o $@ + diff --git a/src/mpeg/pspjpeg.h b/src/mpeg/pspjpeg.h new file mode 100755 index 00000000..feb2a96e --- /dev/null +++ b/src/mpeg/pspjpeg.h @@ -0,0 +1,69 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspjpeg.h - Prototypes for the sceJpeg library + * + * Copyright (c) 2007 dot_blank + * + * $Id: pspjpeg.h 2433 2008-10-15 10:00:27Z iwn $ + */ +#ifndef __PSPJPEG_H__ +#define __PSPJPEG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** + * Inits the MJpeg library + * + * @return 0 on success, < 0 on error +*/ +int sceJpegInitMJpeg(void); + +/** + * Finishes the MJpeg library + * + * @return 0 on success, < 0 on error +*/ +int sceJpegFinishMJpeg(void); + +/** + * Creates the decoder context. + * + * @param width - The width of the frame + * @param height - The height of the frame + * + * @return 0 on success, < 0 on error +*/ +int sceJpegCreateMJpeg(int width, int height); + +/** + * Deletes the current decoder context. + * + * @return 0 on success, < 0 on error +*/ +int sceJpegDeleteMJpeg(void); + +/** + * Decodes a mjpeg frame. + * + * @param jpegbuf - the buffer with the mjpeg frame + * @param size - size of the buffer pointed by jpegbuf + * @param rgba - buffer where the decoded data in RGBA format will be stored. + * It should have a size of (width * height * 4). + * @param unk - Unknown, pass 0 + * + * @return (width * 65536) + height on success, < 0 on error +*/ +int sceJpegDecodeMJpeg(u8 *jpegbuf, SceSize size, void *rgba, u32 unk); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/mpeg/pspmpeg.h b/src/mpeg/pspmpeg.h new file mode 100644 index 00000000..d4ac5ae1 --- /dev/null +++ b/src/mpeg/pspmpeg.h @@ -0,0 +1,344 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspmpeg.h - Prototypes for the sceMpeg library + * + * Copyright (c) 2006 Sorin P. C. + * Copyright (c) 2007 Alexander Berl + * + * $Id: pspmpeg.h 2433 2008-10-15 10:00:27Z iwn $ + */ + +#ifndef __SCELIBMPEG_H__ +#define __SCELIBMPEG_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** points to "LIBMPEG" */ +typedef ScePVoid SceMpeg; + +/** some structure */ +typedef SceVoid SceMpegStream; + +/** Ringbuffer callback */ +typedef SceInt32 (*sceMpegRingbufferCB)(ScePVoid pData, SceInt32 iNumPackets, ScePVoid pParam); + +typedef struct SceMpegRingbuffer +{ + /** packets */ + SceInt32 iPackets; + + /** unknown */ + SceUInt32 iUnk0; + /** unknown */ + SceUInt32 iUnk1; + /** unknown */ + SceUInt32 iUnk2; + /** unknown */ + SceUInt32 iUnk3; + + /** pointer to data */ + ScePVoid pData; + + /** ringbuffer callback */ + sceMpegRingbufferCB Callback; + /** callback param */ + ScePVoid pCBparam; + + /** unknown */ + SceUInt32 iUnk4; + /** unknown */ + SceUInt32 iUnk5; + /** mpeg id */ + SceMpeg pSceMpeg; + +} SceMpegRingbuffer; + +typedef struct SceMpegAu +{ + /** presentation timestamp MSB */ + SceUInt32 iPtsMSB; + /** presentation timestamp LSB */ + SceUInt32 iPts; + /** decode timestamp MSB */ + SceUInt32 iDtsMSB; + /** decode timestamp LSB */ + SceUInt32 iDts; + /** Es buffer handle */ + SceUInt32 iEsBuffer; + /** Au size */ + SceUInt32 iAuSize; + +} SceMpegAu; + +#define SCE_MPEG_AVC_FORMAT_DEFAULT -1 +#define SCE_MPEG_AVC_FORMAT_5650 0 +#define SCE_MPEG_AVC_FORMAT_5551 1 +#define SCE_MPEG_AVC_FORMAT_4444 2 +#define SCE_MPEG_AVC_FORMAT_8888 3 + +typedef struct SceMpegAvcMode +{ + /** unknown, set to -1 */ + SceInt32 iUnk0; + /** Decode pixelformat */ + SceInt32 iPixelFormat; + +} SceMpegAvcMode; + +/** + * sceMpegInit + * + * @return 0 if success. + */ +SceInt32 sceMpegInit(); + +/** + * sceMpegFinish + */ +SceVoid sceMpegFinish(); + +/** + * sceMpegRingbufferQueryMemSize + * + * @param iPackets - number of packets in the ringbuffer + * + * @return < 0 if error else ringbuffer data size. + */ +SceInt32 sceMpegRingbufferQueryMemSize(SceInt32 iPackets); + +/** + * sceMpegRingbufferConstruct + * + * @param Ringbuffer - pointer to a sceMpegRingbuffer struct + * @param iPackets - number of packets in the ringbuffer + * @param pData - pointer to allocated memory + * @param iSize - size of allocated memory, shoud be sceMpegRingbufferQueryMemSize(iPackets) + * @param Callback - ringbuffer callback + * @param pCBparam - param passed to callback + * + * @return 0 if success. + */ +SceInt32 sceMpegRingbufferConstruct(SceMpegRingbuffer* Ringbuffer, SceInt32 iPackets, ScePVoid pData, SceInt32 iSize, sceMpegRingbufferCB Callback, ScePVoid pCBparam); + +/** + * sceMpegRingbufferDestruct + * + * @param Ringbuffer - pointer to a sceMpegRingbuffer struct + */ +SceVoid sceMpegRingbufferDestruct(SceMpegRingbuffer* Ringbuffer); + +/** + * sceMpegQueryMemSize + * + * @param Ringbuffer - pointer to a sceMpegRingbuffer struct + * + * @return < 0 if error else number of free packets in the ringbuffer. + */ +SceInt32 sceMpegRingbufferAvailableSize(SceMpegRingbuffer* Ringbuffer); + +/** + * sceMpegRingbufferPut + * + * @param Ringbuffer - pointer to a sceMpegRingbuffer struct + * @param iNumPackets - num packets to put into the ringbuffer + * @param iAvailable - free packets in the ringbuffer, should be sceMpegRingbufferAvailableSize() + * + * @return < 0 if error else number of packets. + */ +SceInt32 sceMpegRingbufferPut(SceMpegRingbuffer* Ringbuffer, SceInt32 iNumPackets, SceInt32 iAvailable); + +/** + * sceMpegQueryMemSize + * + * @param iUnk - Unknown, set to 0 + * + * @return < 0 if error else decoder data size. + */ +SceInt32 sceMpegQueryMemSize(int iUnk); + +/** + * sceMpegCreate + * + * @param Mpeg - will be filled + * @param pData - pointer to allocated memory of size = sceMpegQueryMemSize() + * @param iSize - size of data, should be = sceMpegQueryMemSize() + * @param Ringbuffer - a ringbuffer + * @param iFrameWidth - display buffer width, set to 512 if writing to framebuffer + * @param iUnk1 - unknown, set to 0 + * @param iUnk2 - unknown, set to 0 + * + * @return 0 if success. + */ +SceInt32 sceMpegCreate(SceMpeg* Mpeg, ScePVoid pData, SceInt32 iSize, SceMpegRingbuffer* Ringbuffer, SceInt32 iFrameWidth, SceInt32 iUnk1, SceInt32 iUnk2); + +/** + * sceMpegDelete + * + * @param Mpeg - SceMpeg handle + */ +SceVoid sceMpegDelete(SceMpeg* Mpeg); + +/** + * sceMpegQueryStreamOffset + * + * @param Mpeg - SceMpeg handle + * @param pBuffer - pointer to file header + * @param iOffset - will contain stream offset in bytes, usually 2048 + * + * @return 0 if success. + */ +SceInt32 sceMpegQueryStreamOffset(SceMpeg* Mpeg, ScePVoid pBuffer, SceInt32* iOffset); + +/** + * sceMpegQueryStreamSize + * + * @param pBuffer - pointer to file header + * @param iSize - will contain stream size in bytes + * + * @return 0 if success. + */ +SceInt32 sceMpegQueryStreamSize(ScePVoid pBuffer, SceInt32* iSize); + +/** + * sceMpegRegistStream + * + * @param Mpeg - SceMpeg handle + * @param iStreamID - stream id, 0 for video, 1 for audio + * @param iUnk - unknown, set to 0 + * + * @return 0 if error. + */ +SceMpegStream* sceMpegRegistStream(SceMpeg* Mpeg, SceInt32 iStreamID, SceInt32 iUnk); + +/** + * sceMpegUnRegistStream + * + * @param Mpeg - SceMpeg handle + * @param pStream - pointer to stream + */ +SceVoid sceMpegUnRegistStream(SceMpeg Mpeg, SceMpegStream* pStream); + +/** + * sceMpegFlushAllStreams + * + * @return 0 if success. + */ +SceInt32 sceMpegFlushAllStream(SceMpeg* Mpeg); + +/** + * sceMpegMallocAvcEsBuf + * + * @return 0 if error else pointer to buffer. + */ +ScePVoid sceMpegMallocAvcEsBuf(SceMpeg* Mpeg); + +/** + * sceMpegFreeAvcEsBuf + * + */ +SceVoid sceMpegFreeAvcEsBuf(SceMpeg* Mpeg, ScePVoid pBuf); + +/** + * sceMpegQueryAtracEsSize + * + * @param Mpeg - SceMpeg handle + * @param iEsSize - will contain size of Es + * @param iOutSize - will contain size of decoded data + * + * @return 0 if success. + */ +SceInt32 sceMpegQueryAtracEsSize(SceMpeg* Mpeg, SceInt32* iEsSize, SceInt32* iOutSize); + +/** + * sceMpegInitAu + * + * @param Mpeg - SceMpeg handle + * @param pEsBuffer - prevously allocated Es buffer + * @param pAu - will contain pointer to Au + * + * @return 0 if success. + */ +SceInt32 sceMpegInitAu(SceMpeg* Mpeg, ScePVoid pEsBuffer, SceMpegAu* pAu); + +/** + * sceMpegGetAvcAu + * + * @param Mpeg - SceMpeg handle + * @param pStream - associated stream + * @param pAu - will contain pointer to Au + * @param iUnk - unknown + * + * @return 0 if success. + */ +SceInt32 sceMpegGetAvcAu(SceMpeg* Mpeg, SceMpegStream* pStream, SceMpegAu* pAu, SceInt32* iUnk); + +/** + * sceMpegAvcDecodeMode + * + * @param Mpeg - SceMpeg handle + * @param pMode - pointer to SceMpegAvcMode struct defining the decode mode (pixelformat) + * @return 0 if success. + */ +SceInt32 sceMpegAvcDecodeMode(SceMpeg* Mpeg, SceMpegAvcMode* pMode); + +/** + * sceMpegAvcDecode + * + * @param Mpeg - SceMpeg handle + * @param pAu - video Au + * @param iFrameWidth - output buffer width, set to 512 if writing to framebuffer + * @param pBuffer - buffer that will contain the decoded frame + * @param iInit - will be set to 0 on first call, then 1 + * + * @return 0 if success. + */ +SceInt32 sceMpegAvcDecode(SceMpeg* Mpeg, SceMpegAu* pAu, SceInt32 iFrameWidth, ScePVoid pBuffer, SceInt32* iInit); + +/** + * sceMpegAvcDecodeStop + * + * @param Mpeg - SceMpeg handle + * @param iFrameWidth - output buffer width, set to 512 if writing to framebuffer + * @param pBuffer - buffer that will contain the decoded frame + * @param iStatus - frame number + * + * @return 0 if success. + */ +SceInt32 sceMpegAvcDecodeStop(SceMpeg* Mpeg, SceInt32 iFrameWidth, ScePVoid pBuffer, SceInt32* iStatus); + +/** + * sceMpegGetAtracAu + * + * @param Mpeg - SceMpeg handle + * @param pStream - associated stream + * @param pAu - will contain pointer to Au + * @param pUnk - unknown + * + * @return 0 if success. + */ +SceInt32 sceMpegGetAtracAu(SceMpeg* Mpeg, SceMpegStream* pStream, SceMpegAu* pAu, ScePVoid pUnk); + +/** + * sceMpegAtracDecode + * + * @param Mpeg - SceMpeg handle + * @param pAu - video Au + * @param pBuffer - buffer that will contain the decoded frame + * @param iInit - set this to 1 on first call + * + * @return 0 if success. + */ +SceInt32 sceMpegAtracDecode(SceMpeg* Mpeg, SceMpegAu* pAu, ScePVoid pBuffer, SceInt32 iInit); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/mpeg/pspmpegbase.h b/src/mpeg/pspmpegbase.h new file mode 100755 index 00000000..e4ed2993 --- /dev/null +++ b/src/mpeg/pspmpegbase.h @@ -0,0 +1,66 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspmpegbase.h - Prototypes for the sceMpegbase library + * + * Copyright (c) 2006 Sorin P. C. + * Copyright (c) 2007 cooleyes + * Copyright (c) 2007 Alexander Berl + * + * $Id: pspmpegbase.h 2341 2007-12-06 20:05:52Z raphael $ + */ + +#ifndef __SCELIBMPEGBASE_H__ +#define __SCELIBMPEGBASE_H__ + + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct SceMpegLLI +{ + ScePVoid pSrc; + ScePVoid pDst; + ScePVoid Next; + SceInt32 iSize; +} __attribute__((aligned(64))) SceMpegLLI; + + + +typedef struct SceMpegYCrCbBuffer +{ + SceInt32 iFrameBufferHeight16; + SceInt32 iFrameBufferWidth16; + SceInt32 iUnknown; // Set to 0 + SceInt32 iUnknown2; // Set to 1 + ScePVoid pYBuffer; // pointer to YBuffer (in VME EDRAM?) + ScePVoid pYBuffer2; // pointer to YBuffer + framebufferwidth*(frameheight/32) + ScePVoid pCrBuffer; // pointer to CrBuffer (in VME EDRAM?) + ScePVoid pCbBuffer; // pointer to CbBuffer (in VME EDRAM?) + ScePVoid pCrBuffer2; // pointer to CrBuffer + (framebufferwidth/2)*(frameheight/64) + ScePVoid pCbBuffer2; // pointer to CbBuffer + (framebufferwidth/2)*(frameheight/64) + SceInt32 iFrameHeight; + SceInt32 iFrameWidth; + SceInt32 iFrameBufferWidth; + SceInt32 iUnknown3[11]; +} __attribute__((aligned(64))) SceMpegYCrCbBuffer; + + +SceInt32 sceMpegBaseYCrCbCopyVme(ScePVoid YUVBuffer, SceInt32 *Buffer, SceInt32 Type); +SceInt32 sceMpegBaseCscInit(SceInt32 width); +SceInt32 sceMpegBaseCscVme(ScePVoid pRGBbuffer, ScePVoid pRGBbuffer2, SceInt32 width, SceMpegYCrCbBuffer* pYCrCbBuffer); + +SceInt32 sceMpegbase_BEA18F91(SceMpegLLI *pLLI); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/mpeg/sceJpeg.S b/src/mpeg/sceJpeg.S new file mode 100755 index 00000000..775fd3c5 --- /dev/null +++ b/src/mpeg/sceJpeg.S @@ -0,0 +1,46 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceJpeg_0000 + IMPORT_START "sceJpeg",0x00090000 +#endif +#ifdef F_sceJpeg_0001 + IMPORT_FUNC "sceJpeg",0x0425B986,sceJpeg_0425B986 +#endif +#ifdef F_sceJpeg_0002 + IMPORT_FUNC "sceJpeg",0x04B5AE02,sceJpegMJpegCsc +#endif +#ifdef F_sceJpeg_0003 + IMPORT_FUNC "sceJpeg",0x04B93CEF,sceJpegDecodeMJpeg +#endif +#ifdef F_sceJpeg_0004 + IMPORT_FUNC "sceJpeg",0x227662D7,sceJpeg_227662D7 +#endif +#ifdef F_sceJpeg_0005 + IMPORT_FUNC "sceJpeg",0x48B602B7,sceJpegDeleteMJpeg +#endif +#ifdef F_sceJpeg_0006 + IMPORT_FUNC "sceJpeg",0x64B6F978,sceJpeg_64B6F978 +#endif +#ifdef F_sceJpeg_0007 + IMPORT_FUNC "sceJpeg",0x67F0ED84,sceJpeg_67F0ED84 +#endif +#ifdef F_sceJpeg_0008 + IMPORT_FUNC "sceJpeg",0x7D2F3D7F,sceJpegFinishMJpeg +#endif +#ifdef F_sceJpeg_0009 + IMPORT_FUNC "sceJpeg",0x8F2BB012,sceJpegGetOutputInfo +#endif +#ifdef F_sceJpeg_0010 + IMPORT_FUNC "sceJpeg",0x91EED83C,sceJpegDecodeMJpegYCbCr +#endif +#ifdef F_sceJpeg_0011 + IMPORT_FUNC "sceJpeg",0x9B36444C,sceJpeg_9B36444C +#endif +#ifdef F_sceJpeg_0012 + IMPORT_FUNC "sceJpeg",0x9D47469C,sceJpegCreateMJpeg +#endif +#ifdef F_sceJpeg_0013 + IMPORT_FUNC "sceJpeg",0xAC9E70E6,sceJpegInitMJpeg +#endif diff --git a/src/mpeg/sceMpeg.S b/src/mpeg/sceMpeg.S new file mode 100644 index 00000000..1d1ed7a5 --- /dev/null +++ b/src/mpeg/sceMpeg.S @@ -0,0 +1,121 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceMpeg_0000 + IMPORT_START "sceMpeg",0x00090000 +#endif +#ifdef F_sceMpeg_0001 + IMPORT_FUNC "sceMpeg",0x21FF80E4,sceMpegQueryStreamOffset +#endif +#ifdef F_sceMpeg_0002 + IMPORT_FUNC "sceMpeg",0x611E9E11,sceMpegQueryStreamSize +#endif +#ifdef F_sceMpeg_0003 + IMPORT_FUNC "sceMpeg",0x682A619B,sceMpegInit +#endif +#ifdef F_sceMpeg_0004 + IMPORT_FUNC "sceMpeg",0x874624D6,sceMpegFinish +#endif +#ifdef F_sceMpeg_0005 + IMPORT_FUNC "sceMpeg",0xC132E22F,sceMpegQueryMemSize +#endif +#ifdef F_sceMpeg_0006 + IMPORT_FUNC "sceMpeg",0xD8C5F121,sceMpegCreate +#endif +#ifdef F_sceMpeg_0007 + IMPORT_FUNC "sceMpeg",0x606A4649,sceMpegDelete +#endif +#ifdef F_sceMpeg_0008 + IMPORT_FUNC "sceMpeg",0x42560F23,sceMpegRegistStream +#endif +#ifdef F_sceMpeg_0009 + IMPORT_FUNC "sceMpeg",0x591A4AA2,sceMpegUnRegistStream +#endif +#ifdef F_sceMpeg_0010 + IMPORT_FUNC "sceMpeg",0xA780CF7E,sceMpegMallocAvcEsBuf +#endif +#ifdef F_sceMpeg_0011 + IMPORT_FUNC "sceMpeg",0xCEB870B1,sceMpegFreeAvcEsBuf +#endif +#ifdef F_sceMpeg_0012 + IMPORT_FUNC "sceMpeg",0xF8DCB679,sceMpegQueryAtracEsSize +#endif +#ifdef F_sceMpeg_0013 + IMPORT_FUNC "sceMpeg",0xC02CF6B5,sceMpegQueryPcmEsSize +#endif +#ifdef F_sceMpeg_0014 + IMPORT_FUNC "sceMpeg",0x167AFD9E,sceMpegInitAu +#endif +#ifdef F_sceMpeg_0015 + IMPORT_FUNC "sceMpeg",0x234586AE,sceMpegChangeGetAvcAuMode +#endif +#ifdef F_sceMpeg_0016 + IMPORT_FUNC "sceMpeg",0x9DCFB7EA,sceMpegChangeGetAuMode +#endif +#ifdef F_sceMpeg_0017 + IMPORT_FUNC "sceMpeg",0xFE246728,sceMpegGetAvcAu +#endif +#ifdef F_sceMpeg_0018 + IMPORT_FUNC "sceMpeg",0x8C1E027D,sceMpegGetPcmAu +#endif +#ifdef F_sceMpeg_0019 + IMPORT_FUNC "sceMpeg",0xE1CE83A7,sceMpegGetAtracAu +#endif +#ifdef F_sceMpeg_0020 + IMPORT_FUNC "sceMpeg",0x500F0429,sceMpegFlushStream +#endif +#ifdef F_sceMpeg_0021 + IMPORT_FUNC "sceMpeg",0x707B7629,sceMpegFlushAllStream +#endif +#ifdef F_sceMpeg_0022 + IMPORT_FUNC "sceMpeg",0x0E3C2E9D,sceMpegAvcDecode +#endif +#ifdef F_sceMpeg_0023 + IMPORT_FUNC "sceMpeg",0x0F6C18D7,sceMpegAvcDecodeDetail +#endif +#ifdef F_sceMpeg_0024 + IMPORT_FUNC "sceMpeg",0xA11C7026,sceMpegAvcDecodeMode +#endif +#ifdef F_sceMpeg_0025 + IMPORT_FUNC "sceMpeg",0x740FCCD1,sceMpegAvcDecodeStop +#endif +#ifdef F_sceMpeg_0026 + IMPORT_FUNC "sceMpeg",0x800C44DF,sceMpegAtracDecode +#endif +#ifdef F_sceMpeg_0027 + IMPORT_FUNC "sceMpeg",0xD7A29F46,sceMpegRingbufferQueryMemSize +#endif +#ifdef F_sceMpeg_0028 + IMPORT_FUNC "sceMpeg",0x37295ED8,sceMpegRingbufferConstruct +#endif +#ifdef F_sceMpeg_0029 + IMPORT_FUNC "sceMpeg",0x13407F13,sceMpegRingbufferDestruct +#endif +#ifdef F_sceMpeg_0030 + IMPORT_FUNC "sceMpeg",0xB240A59E,sceMpegRingbufferPut +#endif +#ifdef F_sceMpeg_0031 + IMPORT_FUNC "sceMpeg",0xB5F6DC87,sceMpegRingbufferAvailableSize +#endif +#ifdef F_sceMpeg_0032 + IMPORT_FUNC "sceMpeg",0x11CAB459,sceMpeg_11CAB459 +#endif +#ifdef F_sceMpeg_0033 + IMPORT_FUNC "sceMpeg",0x3C37A7A6,sceMpeg_3C37A7A6 +#endif +#ifdef F_sceMpeg_0034 + IMPORT_FUNC "sceMpeg",0xB27711A8,sceMpeg_B27711A8 +#endif +#ifdef F_sceMpeg_0035 + IMPORT_FUNC "sceMpeg",0xD4DD6E75,sceMpeg_D4DD6E75 +#endif +#ifdef F_sceMpeg_0036 + IMPORT_FUNC "sceMpeg",0xC345DED2,sceMpeg_C345DED2 +#endif +#ifdef F_sceMpeg_0037 + IMPORT_FUNC "sceMpeg",0xCF3547A2,sceMpegAvcDecodeDetail2 +#endif +#ifdef F_sceMpeg_0038 + IMPORT_FUNC "sceMpeg",0x988E9E12,sceMpeg_988E9E12 +#endif diff --git a/src/mpeg/sceMpegbase.S b/src/mpeg/sceMpegbase.S new file mode 100755 index 00000000..22843d34 --- /dev/null +++ b/src/mpeg/sceMpegbase.S @@ -0,0 +1,34 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceMpegbase_0000 + IMPORT_START "sceMpegbase",0x00090000 +#endif +#ifdef F_sceMpegbase_0001 + IMPORT_FUNC "sceMpegbase",0xBE45C284,sceMpegBaseYCrCbCopyVme +#endif +#ifdef F_sceMpegbase_0002 + IMPORT_FUNC "sceMpegbase",0x492B5E4B,sceMpegBaseCscInit +#endif +#ifdef F_sceMpegbase_0003 + IMPORT_FUNC "sceMpegbase",0xCE8EB837,sceMpegBaseCscVme +#endif +#ifdef F_sceMpegbase_0004 + IMPORT_FUNC "sceMpegbase",0x0530BE4E,sceMpegbase_0530BE4E +#endif +#ifdef F_sceMpegbase_0005 + IMPORT_FUNC "sceMpegbase",0x304882E1,sceMpegbase_304882E1 +#endif +#ifdef F_sceMpegbase_0006 + IMPORT_FUNC "sceMpegbase",0x7AC0321A,sceMpegBaseYCrCbCopy +#endif +#ifdef F_sceMpegbase_0007 + IMPORT_FUNC "sceMpegbase",0x91929A21,sceMpegBaseCscAvc +#endif +#ifdef F_sceMpegbase_0008 + IMPORT_FUNC "sceMpegbase",0xAC9E717E,sceMpegbase_AC9E717E +#endif +#ifdef F_sceMpegbase_0009 + IMPORT_FUNC "sceMpegbase",0xBEA18F91,sceMpegbase_BEA18F91 +#endif diff --git a/src/mpeg/sceMpegbase_driver.S b/src/mpeg/sceMpegbase_driver.S new file mode 100755 index 00000000..45e57e38 --- /dev/null +++ b/src/mpeg/sceMpegbase_driver.S @@ -0,0 +1,37 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceMpegbase_driver_0000 + IMPORT_START "sceMpegbase_driver",0x00010000 +#endif +#ifdef F_sceMpegbase_driver_0001 + IMPORT_FUNC "sceMpegbase_driver",0xBE45C284,sceMpegBaseYCrCbCopyVme +#endif +#ifdef F_sceMpegbase_driver_0002 + IMPORT_FUNC "sceMpegbase_driver",0x492B5E4B,sceMpegBaseCscInit +#endif +#ifdef F_sceMpegbase_driver_0003 + IMPORT_FUNC "sceMpegbase_driver",0xCE8EB837,sceMpegBaseCscVme +#endif +#ifdef F_sceMpegbase_driver_0004 + IMPORT_FUNC "sceMpegbase_driver",0x0530BE4E,sceMpegbase_driver_0530BE4E +#endif +#ifdef F_sceMpegbase_driver_0005 + IMPORT_FUNC "sceMpegbase_driver",0x304882E1,sceMpegbase_driver_304882E1 +#endif +#ifdef F_sceMpegbase_driver_0006 + IMPORT_FUNC "sceMpegbase_driver",0x7AC0321A,sceMpegBaseYCrCbCopy +#endif +#ifdef F_sceMpegbase_driver_0007 + IMPORT_FUNC "sceMpegbase_driver",0x91929A21,sceMpegBaseCscAvc +#endif +#ifdef F_sceMpegbase_driver_0008 + IMPORT_FUNC "sceMpegbase_driver",0xAC9E717E,sceMpegbase_driver_AC9E717E +#endif +#ifdef F_sceMpegbase_driver_0009 + IMPORT_FUNC "sceMpegbase_driver",0xBEA18F91,sceMpegbase_BEA18F91 +#endif +#ifdef F_sceMpegbase_driver_0010 + IMPORT_FUNC "sceMpegbase_driver",0x27A2982F,sceMpegBaseInit +#endif diff --git a/src/nand/Makefile.am b/src/nand/Makefile.am new file mode 100644 index 00000000..dc3f999b --- /dev/null +++ b/src/nand/Makefile.am @@ -0,0 +1,23 @@ + +libdir = @PSPSDK_LIBDIR@ + +CC = @PSP_CC@ +CCAS = $(CC) +AR = @PSP_AR@ +RANLIB = @PSP_RANLIB@ + +INCLUDES = -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel +CFLAGS = @PSPSDK_CFLAGS@ +CCASFLAGS = $(CFLAGS) -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel + +NAND_DRIVER_OBJS = sceNand_driver_0000.o sceNand_driver_0001.o sceNand_driver_0002.o sceNand_driver_0003.o sceNand_driver_0004.o sceNand_driver_0005.o sceNand_driver_0006.o sceNand_driver_0007.o sceNand_driver_0008.o sceNand_driver_0009.o sceNand_driver_0010.o sceNand_driver_0011.o sceNand_driver_0012.o sceNand_driver_0013.o sceNand_driver_0014.o sceNand_driver_0015.o sceNand_driver_0016.o sceNand_driver_0017.o sceNand_driver_0018.o sceNand_driver_0019.o sceNand_driver_0020.o sceNand_driver_0021.o sceNand_driver_0022.o sceNand_driver_0023.o sceNand_driver_0024.o sceNand_driver_0025.o sceNand_driver_0026.o sceNand_driver_0027.o sceNand_driver_0028.o sceNand_driver_0029.o sceNand_driver_0030.o sceNand_driver_0031.o sceNand_driver_0032.o sceNand_driver_0033.o sceNand_driver_0034.o sceNand_driver_0035.o sceNand_driver_0036.o sceNand_driver_0037.o sceNand_driver_0038.o sceNand_driver_0039.o + +libpspnandincludedir = @PSPSDK_INCLUDEDIR@ +libpspnandinclude_HEADERS = pspnand_driver.h + +lib_LIBRARIES = libpspnand_driver.a +libpspnand_driver_a_SOURCES = sceNand_driver.S +libpspnand_driver_a_LIBADD = $(NAND_DRIVER_OBJS) + +$(NAND_DRIVER_OBJS): sceNand_driver.S + $(COMPILE) -DF_$* $< -c -o $@ diff --git a/src/nand/pspnand_driver.h b/src/nand/pspnand_driver.h new file mode 100644 index 00000000..f1923874 --- /dev/null +++ b/src/nand/pspnand_driver.h @@ -0,0 +1,76 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspnand_driver.h - Definitions and interfaces to the NAND (flash) driver. + * + * Copyright (c) 2005 Marcus R. Brown + * + * $Id: pspnand_driver.h 1211 2005-10-24 06:36:00Z mrbrown $ + */ + +#ifndef PSPNAND_DRIVER_H +#define PSPNAND_DRIVER_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int sceNandSetWriteProtect(int protectFlag); + +int sceNandLock(int writeFlag); + +void sceNandUnlock(void); + +int sceNandReadStatus(void); + +int sceNandReset(int flag); + +int sceNandReadId(void *buf, SceSize size); + +int sceNandReadPages(u32 ppn, void *buf, void *buf2, u32 count); + +/* +// sceNandWritePages +// sceNandReadAccess +// sceNandWriteAccess +// sceNandEraseBlock +// sceNandReadExtraOnly +// sceNandCalcEcc +// sceNandVerifyEcc +// sceNandCollectEcc +*/ + +int sceNandGetPageSize(void); + +int sceNandGetPagesPerBlock(void); + +int sceNandGetTotalBlocks(void); + +/* +// sceNandWriteBlock +// sceNandWriteBlockWithVerify +*/ + +int sceNandReadBlockWithRetry(u32 ppn, void *buf, void *buf2); + +/* +// sceNandVerifyBlockWithRetry +// sceNandEraseBlockWithRetry +*/ + +int sceNandIsBadBlock(u32 ppn); + +/* +// sceNandEraseAllBlock +// sceNandTestBlock +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* PSPNAND_DRIVER_H */ diff --git a/src/nand/sceNand_driver.S b/src/nand/sceNand_driver.S new file mode 100644 index 00000000..70d07d53 --- /dev/null +++ b/src/nand/sceNand_driver.S @@ -0,0 +1,124 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceNand_driver_0000 + IMPORT_START "sceNand_driver",0x00010000 +#endif +#ifdef F_sceNand_driver_0001 + IMPORT_FUNC "sceNand_driver",0xA513BB12,sceNandInit +#endif +#ifdef F_sceNand_driver_0002 + IMPORT_FUNC "sceNand_driver",0xD305870E,sceNandEnd +#endif +#ifdef F_sceNand_driver_0003 + IMPORT_FUNC "sceNand_driver",0x73A68408,sceNandSuspend +#endif +#ifdef F_sceNand_driver_0004 + IMPORT_FUNC "sceNand_driver",0x0F9BBBBD,sceNandResume +#endif +#ifdef F_sceNand_driver_0005 + IMPORT_FUNC "sceNand_driver",0x84EE5D76,sceNandSetWriteProtect +#endif +#ifdef F_sceNand_driver_0006 + IMPORT_FUNC "sceNand_driver",0xAE4438C7,sceNandLock +#endif +#ifdef F_sceNand_driver_0007 + IMPORT_FUNC "sceNand_driver",0x41FFA822,sceNandUnlock +#endif +#ifdef F_sceNand_driver_0008 + IMPORT_FUNC "sceNand_driver",0xE41A11DE,sceNandReadStatus +#endif +#ifdef F_sceNand_driver_0009 + IMPORT_FUNC "sceNand_driver",0x7AF7B77A,sceNandReset +#endif +#ifdef F_sceNand_driver_0010 + IMPORT_FUNC "sceNand_driver",0xFCDF7610,sceNandReadId +#endif +#ifdef F_sceNand_driver_0011 + IMPORT_FUNC "sceNand_driver",0x89BDCA08,sceNandReadPages +#endif +#ifdef F_sceNand_driver_0012 + IMPORT_FUNC "sceNand_driver",0x8AF0AB9F,sceNandWritePages +#endif +#ifdef F_sceNand_driver_0013 + IMPORT_FUNC "sceNand_driver",0xE05AE88D,sceNand_driver_E05AE88D +#endif +#ifdef F_sceNand_driver_0014 + IMPORT_FUNC "sceNand_driver",0x8932166A,sceNand_driver_8932166A +#endif +#ifdef F_sceNand_driver_0015 + IMPORT_FUNC "sceNand_driver",0xC478C1DE,sceNand_driver_C478C1DE +#endif +#ifdef F_sceNand_driver_0016 + IMPORT_FUNC "sceNand_driver",0xBADD5D46,sceNand_driver_BADD5D46 +#endif +#ifdef F_sceNand_driver_0017 + IMPORT_FUNC "sceNand_driver",0x766756EF,sceNandReadAccess +#endif +#ifdef F_sceNand_driver_0018 + IMPORT_FUNC "sceNand_driver",0x0ADC8686,sceNandWriteAccess +#endif +#ifdef F_sceNand_driver_0019 + IMPORT_FUNC "sceNand_driver",0xEB0A0022,sceNandEraseBlock +#endif +#ifdef F_sceNand_driver_0020 + IMPORT_FUNC "sceNand_driver",0x5182C394,sceNandReadExtraOnly +#endif +#ifdef F_sceNand_driver_0021 + IMPORT_FUNC "sceNand_driver",0xEF55F193,sceNandCalcEcc +#endif +#ifdef F_sceNand_driver_0022 + IMPORT_FUNC "sceNand_driver",0x18B78661,sceNandVerifyEcc +#endif +#ifdef F_sceNand_driver_0023 + IMPORT_FUNC "sceNand_driver",0xB795D2ED,sceNandCollectEcc +#endif +#ifdef F_sceNand_driver_0024 + IMPORT_FUNC "sceNand_driver",0xD897C343,sceNand_driver_D897C343 +#endif +#ifdef F_sceNand_driver_0025 + IMPORT_FUNC "sceNand_driver",0xCE9843E6,sceNandGetPageSize +#endif +#ifdef F_sceNand_driver_0026 + IMPORT_FUNC "sceNand_driver",0xB07C41D4,sceNandGetPagesPerBlock +#endif +#ifdef F_sceNand_driver_0027 + IMPORT_FUNC "sceNand_driver",0xC1376222,sceNandGetTotalBlocks +#endif +#ifdef F_sceNand_driver_0028 + IMPORT_FUNC "sceNand_driver",0x716CD2B2,sceNandWriteBlock +#endif +#ifdef F_sceNand_driver_0029 + IMPORT_FUNC "sceNand_driver",0xB2B021E5,sceNandWriteBlockWithVerify +#endif +#ifdef F_sceNand_driver_0030 + IMPORT_FUNC "sceNand_driver",0xC32EA051,sceNandReadBlockWithRetry +#endif +#ifdef F_sceNand_driver_0031 + IMPORT_FUNC "sceNand_driver",0x5AC02755,sceNandVerifyBlockWithRetry +#endif +#ifdef F_sceNand_driver_0032 + IMPORT_FUNC "sceNand_driver",0x8933B2E0,sceNandEraseBlockWithRetry +#endif +#ifdef F_sceNand_driver_0033 + IMPORT_FUNC "sceNand_driver",0x01F09203,sceNandIsBadBlock +#endif +#ifdef F_sceNand_driver_0034 + IMPORT_FUNC "sceNand_driver",0xC29DA136,sceNand_driver_C29DA136 +#endif +#ifdef F_sceNand_driver_0035 + IMPORT_FUNC "sceNand_driver",0x3F76BC21,sceNand_driver_3F76BC21 +#endif +#ifdef F_sceNand_driver_0036 + IMPORT_FUNC "sceNand_driver",0xEBA0E6C6,sceNand_driver_EBA0E6C6 +#endif +#ifdef F_sceNand_driver_0037 + IMPORT_FUNC "sceNand_driver",0x2FF6081B,sceNand_driver_2FF6081B +#endif +#ifdef F_sceNand_driver_0038 + IMPORT_FUNC "sceNand_driver",0x2674CFFE,sceNandEraseAllBlock +#endif +#ifdef F_sceNand_driver_0039 + IMPORT_FUNC "sceNand_driver",0x9B2AC433,sceNandTestBlock +#endif diff --git a/src/net/Makefile.am b/src/net/Makefile.am new file mode 100644 index 00000000..7383a512 --- /dev/null +++ b/src/net/Makefile.am @@ -0,0 +1,101 @@ + +libdir = @PSPSDK_LIBDIR@ + +CC = @PSP_CC@ +CCAS = $(CC) +AR = @PSP_AR@ +RANLIB = @PSP_RANLIB@ + +INCLUDES = -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel +CFLAGS = @PSPSDK_CFLAGS@ +CCASFLAGS = $(CFLAGS) $(INCLUDES) + +NET_OBJS = sceNet_0000.o sceNet_0001.o sceNet_0002.o sceNet_0003.o sceNet_0004.o sceNet_0005.o sceNet_0006.o sceNet_0007.o sceNet_0008.o + +NETLIB_OBJS = sceNet_lib_0000.o sceNet_lib_0001.o sceNet_lib_0002.o sceNet_lib_0003.o sceNet_lib_0004.o sceNet_lib_0005.o sceNet_lib_0006.o sceNet_lib_0007.o sceNet_lib_0008.o sceNet_lib_0009.o sceNet_lib_0010.o sceNet_lib_0011.o sceNet_lib_0012.o sceNet_lib_0013.o sceNet_lib_0014.o sceNet_lib_0015.o sceNet_lib_0016.o sceNet_lib_0017.o sceNet_lib_0018.o sceNet_lib_0019.o sceNet_lib_0020.o sceNet_lib_0021.o sceNet_lib_0022.o sceNet_lib_0023.o sceNet_lib_0024.o sceNet_lib_0025.o sceNet_lib_0026.o sceNet_lib_0027.o sceNet_lib_0028.o sceNet_lib_0029.o sceNet_lib_0030.o sceNet_lib_0031.o sceNet_lib_0032.o sceNet_lib_0033.o sceNet_lib_0034.o sceNet_lib_0035.o sceNet_lib_0036.o sceNet_lib_0037.o sceNet_lib_0038.o sceNet_lib_0039.o sceNet_lib_0040.o sceNet_lib_0041.o sceNet_lib_0042.o sceNet_lib_0043.o sceNet_lib_0044.o sceNet_lib_0045.o sceNet_lib_0046.o sceNet_lib_0047.o sceNet_lib_0048.o sceNet_lib_0049.o sceNet_lib_0050.o sceNet_lib_0051.o sceNet_lib_0052.o sceNet_lib_0053.o sceNet_lib_0054.o sceNet_lib_0055.o sceNet_lib_0056.o sceNet_lib_0057.o sceNet_lib_0058.o sceNet_lib_0059.o sceNet_lib_0060.o sceNet_lib_0061.o sceNet_lib_0062.o sceNet_lib_0063.o sceNet_lib_0064.o sceNet_lib_0065.o sceNet_lib_0066.o sceNet_lib_0067.o sceNet_lib_0068.o sceNet_lib_0069.o sceNet_lib_0070.o sceNet_lib_0071.o sceNet_lib_0072.o sceNet_lib_0073.o sceNet_lib_0074.o sceNet_lib_0075.o sceNet_lib_0076.o sceNet_lib_0077.o sceNet_lib_0078.o sceNet_lib_0079.o sceNet_lib_0080.o sceNet_lib_0081.o sceNet_lib_0082.o sceNet_lib_0083.o sceNet_lib_0084.o sceNet_lib_0085.o sceNet_lib_0086.o sceNet_lib_0087.o sceNet_lib_0088.o sceNet_lib_0089.o sceNet_lib_0090.o sceNet_lib_0091.o sceNet_lib_0092.o sceNet_lib_0093.o sceNet_lib_0094.o sceNet_lib_0095.o sceNet_lib_0096.o + +NET_APCTL_OBJS = sceNetApctl_0000.o sceNetApctl_0001.o sceNetApctl_0002.o sceNetApctl_0003.o sceNetApctl_0004.o sceNetApctl_0005.o sceNetApctl_0006.o sceNetApctl_0007.o sceNetApctl_0008.o + +NET_INET_OBJS = sceNetInet_0000.o sceNetInet_0001.o sceNetInet_0002.o sceNetInet_0003.o sceNetInet_0004.o sceNetInet_0005.o sceNetInet_0006.o sceNetInet_0007.o sceNetInet_0008.o sceNetInet_0009.o sceNetInet_0010.o sceNetInet_0011.o sceNetInet_0012.o sceNetInet_0013.o sceNetInet_0014.o sceNetInet_0015.o sceNetInet_0016.o sceNetInet_0017.o sceNetInet_0018.o sceNetInet_0019.o sceNetInet_0020.o sceNetInet_0021.o sceNetInet_0022.o sceNetInet_0023.o sceNetInet_0024.o sceNetInet_0025.o sceNetInet_0026.o sceNetInet_0027.o sceNetInet_0028.o sceNetInet_0029.o sceNetInet_0030.o + +NET_RESOLVER_OBJS = sceNetResolver_0000.o sceNetResolver_0001.o sceNetResolver_0002.o sceNetResolver_0003.o sceNetResolver_0004.o sceNetResolver_0005.o sceNetResolver_0006.o sceNetResolver_0007.o + +NET_ADHOC_OBJS = sceNetAdhoc_0000.o sceNetAdhoc_0001.o sceNetAdhoc_0002.o sceNetAdhoc_0003.o sceNetAdhoc_0004.o sceNetAdhoc_0005.o sceNetAdhoc_0006.o sceNetAdhoc_0007.o sceNetAdhoc_0008.o sceNetAdhoc_0009.o sceNetAdhoc_0010.o sceNetAdhoc_0011.o sceNetAdhoc_0012.o sceNetAdhoc_0013.o sceNetAdhoc_0014.o sceNetAdhoc_0015.o sceNetAdhoc_0016.o sceNetAdhoc_0017.o sceNetAdhoc_0018.o sceNetAdhoc_0019.o sceNetAdhoc_0020.o sceNetAdhoc_0021.o sceNetAdhoc_0022.o sceNetAdhoc_0023.o sceNetAdhoc_0024.o sceNetAdhoc_0025.o + +NET_ADHOCCTL_OBJS = sceNetAdhocctl_0000.o sceNetAdhocctl_0001.o sceNetAdhocctl_0002.o sceNetAdhocctl_0003.o sceNetAdhocctl_0004.o sceNetAdhocctl_0005.o sceNetAdhocctl_0006.o sceNetAdhocctl_0007.o sceNetAdhocctl_0008.o sceNetAdhocctl_0009.o sceNetAdhocctl_0010.o sceNetAdhocctl_0011.o sceNetAdhocctl_0012.o sceNetAdhocctl_0013.o sceNetAdhocctl_0014.o sceNetAdhocctl_0015.o sceNetAdhocctl_0016.o sceNetAdhocctl_0017.o sceNetAdhocctl_0018.o sceNetAdhocctl_0019.o sceNetAdhocctl_0020.o sceNetAdhocctl_0021.o + +NET_ADHOCMATCHING_OBJS = sceNetAdhocMatching_0000.o sceNetAdhocMatching_0001.o sceNetAdhocMatching_0002.o sceNetAdhocMatching_0003.o sceNetAdhocMatching_0004.o sceNetAdhocMatching_0005.o sceNetAdhocMatching_0006.o sceNetAdhocMatching_0007.o sceNetAdhocMatching_0008.o sceNetAdhocMatching_0009.o sceNetAdhocMatching_0010.o sceNetAdhocMatching_0011.o sceNetAdhocMatching_0012.o sceNetAdhocMatching_0013.o sceNetAdhocMatching_0014.o sceNetAdhocMatching_0015.o sceNetAdhocMatching_0016.o + +HTTP_OBJS = sceHttp_0000.o sceHttp_0001.o sceHttp_0002.o sceHttp_0003.o sceHttp_0004.o sceHttp_0005.o sceHttp_0006.o sceHttp_0007.o sceHttp_0008.o sceHttp_0009.o sceHttp_0010.o sceHttp_0011.o sceHttp_0012.o sceHttp_0013.o sceHttp_0014.o sceHttp_0015.o sceHttp_0016.o sceHttp_0017.o sceHttp_0018.o sceHttp_0019.o sceHttp_0020.o sceHttp_0021.o sceHttp_0022.o sceHttp_0023.o sceHttp_0024.o sceHttp_0025.o sceHttp_0026.o sceHttp_0027.o sceHttp_0028.o sceHttp_0029.o sceHttp_0030.o sceHttp_0031.o sceHttp_0032.o sceHttp_0033.o sceHttp_0034.o sceHttp_0035.o sceHttp_0036.o sceHttp_0037.o sceHttp_0038.o sceHttp_0039.o sceHttp_0040.o sceHttp_0041.o sceHttp_0042.o sceHttp_0043.o sceHttp_0044.o sceHttp_0045.o sceHttp_0046.o sceHttp_0047.o sceHttp_0048.o sceHttp_0049.o sceHttp_0050.o sceHttp_0051.o sceHttp_0052.o sceHttp_0053.o sceHttp_0054.o sceHttp_0055.o sceHttp_0056.o sceHttp_0057.o sceHttp_0058.o sceHttp_0059.o sceHttp_0060.o sceHttp_0061.o sceHttp_0062.o sceHttp_0063.o sceHttp_0064.o sceHttp_0065.o sceHttp_0066.o sceHttp_0067.o sceHttp_0068.o sceHttp_0069.o sceHttp_0070.o sceHttp_0071.o sceHttp_0072.o sceHttp_0073.o sceHttp_0074.o sceHttp_0075.o sceHttp_0076.o sceHttp_0077.o sceHttp_0078.o sceHttp_0079.o sceHttp_0080.o sceHttp_0081.o sceHttp_0082.o sceHttp_0083.o + +SSL_OBJS = sceSsl_0000.o sceSsl_0001.o sceSsl_0002.o sceSsl_0003.o sceSsl_0004.o sceSsl_0005.o sceSsl_0006.o sceSsl_0007.o sceSsl_0008.o sceSsl_0009.o sceSsl_0010.o sceSsl_0011.o + +libpspnetincludedir = @PSPSDK_INCLUDEDIR@ +libpspnetinclude_HEADERS = pspnet.h \ + pspnet_apctl.h \ + pspnet_inet.h \ + pspnet_resolver.h \ + pspnet_adhoc.h \ + pspnet_adhocctl.h \ + pspnet_adhocmatching.h \ + psphttp.h \ + pspssl.h + +lib_LIBRARIES = libpspnet.a \ + libpspnet_apctl.a \ + libpspnet_inet.a \ + libpspnet_resolver.a \ + libpspnet_adhoc.a \ + libpspnet_adhocctl.a \ + libpspnet_adhocmatching.a \ + libpsphttp.a \ + libpspssl.a + +libpspnet_a_SOURCES = sceNet.S sceNet_lib.S +libpspnet_a_LIBADD = $(NET_OBJS) $(NETLIB_OBJS) +libpspnet_apctl_a_SOURCES = sceNetApctl.S +libpspnet_apctl_a_LIBADD = $(NET_APCTL_OBJS) +libpspnet_inet_a_SOURCES = sceNetInet.S +libpspnet_inet_a_LIBADD = $(NET_INET_OBJS) +libpspnet_resolver_a_SOURCES = sceNetResolver.S +libpspnet_resolver_a_LIBADD = $(NET_RESOLVER_OBJS) +libpspnet_adhoc_a_SOURCES = sceNetAdhoc.S +libpspnet_adhoc_a_LIBADD = $(NET_ADHOC_OBJS) +libpspnet_adhocctl_a_SOURCES = sceNetAdhocctl.S +libpspnet_adhocctl_a_LIBADD = $(NET_ADHOCCTL_OBJS) +libpspnet_adhocmatching_a_SOURCES = sceNetAdhocMatching.S +libpspnet_adhocmatching_a_LIBADD = $(NET_ADHOCMATCHING_OBJS) +libpsphttp_a_SOURCES = sceHttp.S +libpsphttp_a_LIBADD = $(HTTP_OBJS) +libpspssl_a_SOURCES = sceSsl.S +libpspssl_a_LIBADD = $(SSL_OBJS) + +$(NET_OBJS): sceNet.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(NETLIB_OBJS): sceNet_lib.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(NET_APCTL_OBJS): sceNetApctl.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(NET_INET_OBJS): sceNetInet.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(NET_RESOLVER_OBJS): sceNetResolver.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(NET_ADHOC_OBJS): sceNetAdhoc.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(NET_ADHOCCTL_OBJS): sceNetAdhocctl.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(NET_ADHOCMATCHING_OBJS): sceNetAdhocMatching.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(HTTP_OBJS): sceHttp.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(SSL_OBJS): sceSsl.S + $(COMPILE) -DF_$* $< -c -o $@ diff --git a/src/net/psphttp.h b/src/net/psphttp.h new file mode 100644 index 00000000..5c550172 --- /dev/null +++ b/src/net/psphttp.h @@ -0,0 +1,326 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * psphttp.h - Interface to the http library. + * + * Copyright (c) 2008 David Perry (InsertWittyName) + * Copyright (c) 2008 moonlight + * + */ + +#ifndef __PSPHTTP_H__ +#define __PSPHTTP_H__ + +#if defined(__cplusplus) +extern "C" { +#endif + +typedef enum +{ + PSP_HTTP_METHOD_GET, + PSP_HTTP_METHOD_POST, + PSP_HTTP_METHOD_HEAD + +} PspHttpMethod; + +/** + * Init the http library. + * + * @param unknown1 - Memory pool size? Pass 20000 + * @return 0 on success, < 0 on error. + */ +int sceHttpInit(unsigned int unknown1); + +/** + * Terminate the http library. + * + * @return 0 on success, < 0 on error. + */ +int sceHttpEnd(void); + +/** + * Create a http template. + * + * @param agent - User agent + * @param unknown1 - Pass 1 + * @param unknown2 - Pass 0 + * @return A template ID on success, < 0 on error. + */ +int sceHttpCreateTemplate(char *agent, int unknown1, int unknown2); + +/** + * Delete a http template. + * + * @param templateid - ID of the template created by sceHttpCreateTemplate + * @return 0 on success, < 0 on error. + */ +int sceHttpDeleteTemplate(int templateid); + +/** + * Create a http connection. + * + * @param templateid - ID of the template created by sceHttpCreateTemplate + * @param host - Host to connect to + * @param unknown1 - Pass "http" + * @param port - Port to connect on + * @param unknown2 - Pass 0 + * @return A connection ID on success, < 0 on error. + */ +int sceHttpCreateConnection(int templateid, char *host, char *unknown1, unsigned short port, int unknown2); + +/** + * Create a http connection to a url. + * + * @param templateid - ID of the template created by sceHttpCreateTemplate + * @param url - url to connect to + * @param unknown1 - Pass 0 + * @return A connection ID on success, < 0 on error. + */ +int sceHttpCreateConnectionWithURL(int templateid, const char *url, int unknown1); + +/** + * Delete a http connection. + * + * @param connectionid - ID of the connection created by sceHttpCreateConnection or sceHttpCreateConnectionWithURL + * @return 0 on success, < 0 on error. + */ +int sceHttpDeleteConnection(int connectionid); + +/** + * Create a http request. + * + * @param connectionid - ID of the connection created by sceHttpCreateConnection or sceHttpCreateConnectionWithURL + * @param method - One of ::PspHttpMethod + * @param path - Path to access + * @param contentlength - Length of the content (POST method only) + * @return A request ID on success, < 0 on error. + */ +int sceHttpCreateRequest(int connectionid, PspHttpMethod method, char *path, SceULong64 contentlength); + +/** + * Create a http request with url. + * + * @param connectionid - ID of the connection created by sceHttpCreateConnection or sceHttpCreateConnectionWithURL + * @param method - One of ::PspHttpMethod + * @param url - url to access + * @param contentlength - Length of the content (POST method only) + * @return A request ID on success, < 0 on error. + */ +int sceHttpCreateRequestWithURL(int connectionid, PspHttpMethod method, char *url, SceULong64 contentlength); + +/** + * Delete a http request. + * + * @param requestid - ID of the request created by sceHttpCreateRequest or sceHttpCreateRequestWithURL + * @return 0 on success, < 0 on error. + */ +int sceHttpDeleteRequest(int requestid); + +/** + * Send a http request. + * + * @param requestid - ID of the request created by sceHttpCreateRequest or sceHttpCreateRequestWithURL + * @param data - For POST methods specify a pointer to the post data, otherwise pass NULL + * @param datasize - For POST methods specify the size of the post data, otherwise pass 0 + * @return 0 on success, < 0 on error. + */ +int sceHttpSendRequest(int requestid, void *data, unsigned int datasize); + +/** + * Abort a http request. + * + * @param requestid - ID of the request created by sceHttpCreateRequest or sceHttpCreateRequestWithURL + * @return 0 on success, < 0 on error. + */ +int sceHttpAbortRequest(int requestid); + +/** + * Read a http request response. + * + * @param requestid - ID of the request created by sceHttpCreateRequest or sceHttpCreateRequestWithURL + * @param data - Buffer for the response data to be stored + * @param datasize - Size of the buffer + * @return The size read into the data buffer, 0 if there is no more data, < 0 on error. + */ +int sceHttpReadData(int requestid, void *data, unsigned int datasize); + +/** + * Get http request response length. + * + * @param requestid - ID of the request created by sceHttpCreateRequest or sceHttpCreateRequestWithURL + * @param contentlength - The size of the content + * @return 0 on success, < 0 on error. + */ +int sceHttpGetContentLength(int requestid, SceULong64 *contentlength); + +/** + * Get http request status code. + * + * @param requestid - ID of the request created by sceHttpCreateRequest or sceHttpCreateRequestWithURL + * @param statuscode - The status code from the host (200 is ok, 404 is not found etc) + * @return 0 on success, < 0 on error. + */ +int sceHttpGetStatusCode(int requestid, int *statuscode); + +/** + * Set resolver timeout + * + * @param id - ID of the template or connection + * @param timeout - Timeout value in microseconds + * @return 0 on success, < 0 on error. + */ +int sceHttpSetResolveTimeOut(int id, unsigned int timeout); + +/** + * Set resolver retry + * + * @param id - ID of the template or connection + * @param count - Number of retries + * @return 0 on success, < 0 on error. + */ +int sceHttpSetResolveRetry(int id, int count); + +/** + * Set connect timeout + * + * @param id - ID of the template, connection or request + * @param timeout - Timeout value in microseconds + * @return 0 on success, < 0 on error. + */ +int sceHttpSetConnectTimeOut(int id, unsigned int timeout); + +/** + * Set send timeout + * + * @param id - ID of the template, connection or request + * @param timeout - Timeout value in microseconds + * @return 0 on success, < 0 on error. + */ +int sceHttpSetSendTimeOut(int id, unsigned int timeout); + +/** + * Set receive timeout + * + * @param id - ID of the template or connection + * @param timeout - Timeout value in microseconds + * @return 0 on success, < 0 on error. + */ +int sceHttpSetRecvTimeOut(int id, unsigned int timeout); + +/** + * Enable keep alive + * + * @param id - ID of the template or connection + * @return 0 on success, < 0 on error. + */ +int sceHttpEnableKeepAlive(int id); + +/** + * Disable keep alive + * + * @param id - ID of the template or connection + * @return 0 on success, < 0 on error. + */ +int sceHttpDisableKeepAlive(int id); + +/** + * Enable redirect + * + * @param id - ID of the template or connection + * @return 0 on success, < 0 on error. + */ +int sceHttpEnableRedirect(int id); + +/** + * Disable redirect + * + * @param id - ID of the template or connection + * @return 0 on success, < 0 on error. + */ +int sceHttpDisableRedirect(int id); + +/** + * Enable cookie + * + * @param id - ID of the template or connection + * @return 0 on success, < 0 on error. + */ +int sceHttpEnableCookie(int id); + +/** + * Disable cookie + * + * @param id - ID of the template or connection + * @return 0 on success, < 0 on error. + */ +int sceHttpDisableCookie(int id); + +/** + * Save cookie + * + * @return 0 on success, < 0 on error. + */ +int sceHttpSaveSystemCookie(void); + +/** + * Load cookie + * + * @return 0 on success, < 0 on error. + */ +int sceHttpLoadSystemCookie(void); + +/** + * Add content header + * + * @param id - ID of the template, connection or request + * @param name - Name of the content + * @param value - Value of the content + * @param unknown1 - Pass 0 + * @return 0 on success, < 0 on error. + */ +int sceHttpAddExtraHeader(int id, char *name, char *value, int unknown1); + +/** + * Delete content header + * + * @param id - ID of the template, connection or request + * @param name - Name of the content + * @return 0 on success, < 0 on error. + */ +int sceHttpDeleteHeader(int id, const char *name); + +/** + * Init the https library. + * + * @param unknown1 - Pass 0 + * @param unknown2 - Pass 0 + * @param unknown3 - Pass 0 + * @param unknown4 - Pass 0 + * + * @return 0 on success, < 0 on error. +*/ +int sceHttpsInit(int unknown1, int unknown2, int unknown3, int unknown4); + +/** + * Terminate the https library + * + * @return 0 on success, < 0 on error. +*/ +int sceHttpsEnd(void); + +/** + * Load default certificate + * + * @param unknown1 - Pass 0 + * @param unknown2 - Pass 0 + * @return 0 on success, < 0 on error. +*/ +int sceHttpsLoadDefaultCert(int unknown1, int unknown2); + +#if defined(__cplusplus) +}; +#endif + +#endif diff --git a/src/net/pspnet.h b/src/net/pspnet.h new file mode 100644 index 00000000..fba6947d --- /dev/null +++ b/src/net/pspnet.h @@ -0,0 +1,107 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspnet.h - PSP networking libraries. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2008 David Perry + * + * Portions based on PspPet's wifi_03 sample code. + * + * $Id: pspnet.h 2439 2008-10-23 18:58:06Z iwn $ + */ + +#ifndef PSPNET_H +#define PSPNET_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct SceNetMallocStat +{ + int pool; + int maximum; + int free; + +} SceNetMallocStat; + +/** + * Initialise the networking library + * + * @param poolsize - Memory pool size (appears to be for the whole of the networking library). + * @param calloutprio - Priority of the SceNetCallout thread. + * @param calloutstack - Stack size of the SceNetCallout thread (defaults to 4096 on non 1.5 firmware regardless of what value is passed). + * @param netintrprio - Priority of the SceNetNetintr thread. + * @param netintrstack - Stack size of the SceNetNetintr thread (defaults to 4096 on non 1.5 firmware regardless of what value is passed). + * + * @return 0 on success, < 0 on error + */ +int sceNetInit(int poolsize, int calloutprio, int calloutstack, int netintrprio, int netintrstack); + +/** + * Terminate the networking library + * + * @return 0 on success, < 0 on error + */ +int sceNetTerm(void); + +/** + * Free (delete) thread info/data + * + * @param thid - The thread id. + * + * @return 0 on success, < 0 on error + */ +int sceNetFreeThreadinfo(int thid); + +/** + * Abort a thread + * + * @param thid - The thread id. + * + * @return 0 on success, < 0 on error + */ +int sceNetThreadAbort(int thid); + +/** + * Convert string to a Mac address + * + * @param name - The string to convert. + * @param mac - Pointer to a buffer to store the result. + */ +void sceNetEtherStrton(char *name, unsigned char *mac); + +/** + * Convert Mac address to a string + * + * @param mac - The Mac address to convert. + * @param name - Pointer to a buffer to store the result. + */ +void sceNetEtherNtostr(unsigned char *mac, char *name); + +/** + * Retrieve the local Mac address + * + * @param mac - Pointer to a buffer to store the result. + * + * @return 0 on success, < 0 on error + */ +int sceNetGetLocalEtherAddr(unsigned char *mac); + +/** + * Retrieve the networking library memory usage + * + * @param stat - Pointer to a ::SceNetMallocStat type to store the result. + * + * @return 0 on success, < 0 on error + */ +int sceNetGetMallocStat(SceNetMallocStat *stat); + +#ifdef __cplusplus +} +#endif + +#endif /* PSPNET_H */ diff --git a/src/net/pspnet_adhoc.h b/src/net/pspnet_adhoc.h new file mode 100644 index 00000000..6a88efc4 --- /dev/null +++ b/src/net/pspnet_adhoc.h @@ -0,0 +1,310 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspnet_adhoc.h - PSP Adhoc networking libraries. + * + * Copyright (c) 2006 James F. + * Copyright (c) 2008 InsertWittyName + * + * Based on the adhoc code in SMS Plus + * + * $Id: pspnet_adhoc.h 2400 2008-07-06 22:46:56Z iwn $ + */ +#ifndef __PSPNET_ADHOC_H__ +#define __PSPNET_ADHOC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Initialise the adhoc library. + * + * @return 0 on success, < 0 on error + */ +int sceNetAdhocInit(void); + +/** + * Terminate the adhoc library + * + * @return 0 on success, < 0 on error + */ +int sceNetAdhocTerm(void); + +/** + * Create a PDP object. + * + * @param mac - Your MAC address (from sceWlanGetEtherAddr) + * @param port - Port to use, lumines uses 0x309 + * @param bufsize - Socket buffer size, lumines sets to 0x400 + * @param unk1 - Unknown, lumines sets to 0 + * + * @return The ID of the PDP object (< 0 on error) + */ +int sceNetAdhocPdpCreate(unsigned char *mac, unsigned short port, unsigned int bufsize, int unk1); + +/** + * Delete a PDP object. + * + * @param id - The ID returned from ::sceNetAdhocPdpCreate + * @param unk1 - Unknown, set to 0 + * + * @return 0 on success, < 0 on error + */ +int sceNetAdhocPdpDelete(int id, int unk1); + +/** + * Set a PDP packet to a destination + * + * @param id - The ID as returned by ::sceNetAdhocPdpCreate + * @param destMacAddr - The destination MAC address, can be set to all 0xFF for broadcast + * @param port - The port to send to + * @param data - The data to send + * @param len - The length of the data. + * @param timeout - Timeout in microseconds. + * @param nonblock - Set to 0 to block, 1 for non-blocking. + * + * @return Bytes sent, < 0 on error + */ +int sceNetAdhocPdpSend(int id, unsigned char *destMacAddr, unsigned short port, void *data, unsigned int len, unsigned int timeout, int nonblock); + +/** + * Receive a PDP packet + * + * @param id - The ID of the PDP object, as returned by ::sceNetAdhocPdpCreate + * @param srcMacAddr - Buffer to hold the source mac address of the sender + * @param port - Buffer to hold the port number of he received data + * @param data - Data buffer + * @param dataLength - The length of the data buffer + * @param timeout - Timeout in microseconds. + * @param nonblock - Set to 0 to block, 1 for non-blocking. + * + * @return Number of bytes received, < 0 on error. + */ +int sceNetAdhocPdpRecv(int id, unsigned char *srcMacAddr, unsigned short *port, void *data, void *dataLength, unsigned int timeout, int nonblock); + +/** + * PDP status structure + */ +typedef struct pdpStatStruct +{ + /** Pointer to next PDP structure in list */ + struct pdpStatStruct *next; + /** pdp ID */ + int pdpId; + /** MAC address */ + unsigned char mac[6]; + /** Port */ + unsigned short port; + /** Bytes received */ + unsigned int rcvdData; +} pdpStatStruct; + +/** + * Get the status of all PDP objects + * + * @param size - Pointer to the size of the stat array (e.g 20 for one structure) + * @param stat - Pointer to a list of ::pspStatStruct structures. + * + * @return 0 on success, < 0 on error + */ +int sceNetAdhocGetPdpStat(int *size, pdpStatStruct *stat); + +/** + * Create own game object type data. + * + * @param data - A pointer to the game object data. + * @param size - Size of the game data. + * + * @return 0 on success, < 0 on error. + */ +int sceNetAdhocGameModeCreateMaster(void *data, int size); + +/** + * Create peer game object type data. + * + * @param mac - The mac address of the peer. + * @param data - A pointer to the game object data. + * @param size - Size of the game data. + * + * @return The id of the replica on success, < 0 on error. + */ +int sceNetAdhocGameModeCreateReplica(unsigned char *mac, void *data, int size); + +/** + * Update own game object type data. + * + * @return 0 on success, < 0 on error. + */ +int sceNetAdhocGameModeUpdateMaster(void); + +/** + * Update peer game object type data. + * + * @param id - The id of the replica returned by sceNetAdhocGameModeCreateReplica. + * @param unk1 - Pass 0. + * + * @return 0 on success, < 0 on error. + */ +int sceNetAdhocGameModeUpdateReplica(int id, int unk1); + +/** + * Delete own game object type data. + * + * @return 0 on success, < 0 on error. + */ +int sceNetAdhocGameModeDeleteMaster(void); + +/** + * Delete peer game object type data. + * + * @param id - The id of the replica. + * + * @return 0 on success, < 0 on error. + */ +int sceNetAdhocGameModeDeleteReplica(int id); + +/** + * Open a PTP connection + * + * @param srcmac - Local mac address. + * @param srcport - Local port. + * @param destmac - Destination mac. + * @param destport - Destination port + * @param bufsize - Socket buffer size + * @param delay - Interval between retrying (microseconds). + * @param count - Number of retries. + * @param unk1 - Pass 0. + * + * @return A socket ID on success, < 0 on error. + */ +int sceNetAdhocPtpOpen(unsigned char *srcmac, unsigned short srcport, unsigned char *destmac, unsigned short destport, unsigned int bufsize, unsigned int delay, int count, int unk1); + +/** + * Wait for connection created by sceNetAdhocPtpOpen() + * + * @param id - A socket ID. + * @param timeout - Timeout in microseconds. + * @param nonblock - Set to 0 to block, 1 for non-blocking. + * + * @return 0 on success, < 0 on error. + */ +int sceNetAdhocPtpConnect(int id, unsigned int timeout, int nonblock); + +/** + * Wait for an incoming PTP connection + * + * @param srcmac - Local mac address. + * @param srcport - Local port. + * @param bufsize - Socket buffer size + * @param delay - Interval between retrying (microseconds). + * @param count - Number of retries. + * @param queue - Connection queue length. + * @param unk1 - Pass 0. + * + * @return A socket ID on success, < 0 on error. + */ +int sceNetAdhocPtpListen(unsigned char *srcmac, unsigned short srcport, unsigned int bufsize, unsigned int delay, int count, int queue, int unk1); + +/** + * Accept an incoming PTP connection + * + * @param id - A socket ID. + * @param mac - Connecting peers mac. + * @param port - Connecting peers port. + * @param timeout - Timeout in microseconds. + * @param nonblock - Set to 0 to block, 1 for non-blocking. + * + * @return 0 on success, < 0 on error. + */ +int sceNetAdhocPtpAccept(int id, unsigned char *mac, unsigned short *port, unsigned int timeout, int nonblock); + +/** + * Send data + * + * @param id - A socket ID. + * @param data - Data to send. + * @param datasize - Size of the data. + * @param timeout - Timeout in microseconds. + * @param nonblock - Set to 0 to block, 1 for non-blocking. + * + * @return 0 success, < 0 on error. + */ +int sceNetAdhocPtpSend(int id, void *data, int *datasize, unsigned int timeout, int nonblock); + +/** + * Receive data + * + * @param id - A socket ID. + * @param data - Buffer for the received data. + * @param datasize - Size of the data received. + * @param timeout - Timeout in microseconds. + * @param nonblock - Set to 0 to block, 1 for non-blocking. + * + * @return 0 on success, < 0 on error. + */ +int sceNetAdhocPtpRecv(int id, void *data, int *datasize, unsigned int timeout, int nonblock); + +/** + * Wait for data in the buffer to be sent + * + * @param id - A socket ID. + * @param timeout - Timeout in microseconds. + * @param nonblock - Set to 0 to block, 1 for non-blocking. + * + * @return A socket ID on success, < 0 on error. + */ +int sceNetAdhocPtpFlush(int id, unsigned int timeout, int nonblock); + +/** + * Close a socket + * + * @param id - A socket ID. + * @param unk1 - Pass 0. + * + * @return A socket ID on success, < 0 on error. + */ +int sceNetAdhocPtpClose(int id, int unk1); + +/** + * PTP status structure + */ +typedef struct ptpStatStruct +{ + /** Pointer to next PTP structure in list */ + struct ptpStatStruct *next; + /** ptp ID */ + int ptpId; + /** MAC address */ + unsigned char mac[6]; + /** Peer MAC address */ + unsigned char peermac[6]; + /** Port */ + unsigned short port; + /** Peer Port */ + unsigned short peerport; + /** Bytes sent */ + unsigned int sentData; + /** Bytes received */ + unsigned int rcvdData; + /** Unknown */ + int unk1; +} ptpStatStruct; + +/** + * Get the status of all PTP objects + * + * @param size - Pointer to the size of the stat array (e.g 20 for one structure) + * @param stat - Pointer to a list of ::ptpStatStruct structures. + * + * @return 0 on success, < 0 on error + */ +int sceNetAdhocGetPtpStat(int *size, ptpStatStruct *stat); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/net/pspnet_adhocctl.h b/src/net/pspnet_adhocctl.h new file mode 100644 index 00000000..565f8a4e --- /dev/null +++ b/src/net/pspnet_adhocctl.h @@ -0,0 +1,287 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspnet_adhocctl.h - PSP Adhoc control networking libraries. + * + * Copyright (c) 2006 James F. + * Copyright (c) 2008 InsertWittyName + * + * Based on the adhoc code in SMS Plus + * + * $Id: pspnet_adhocctl.h 2433 2008-10-15 10:00:27Z iwn $ + */ +#ifndef __PSPNETCTL_ADHOC_H__ +#define __PSPNETCTL_ADHOC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** Product structure */ +struct productStruct +{ + /** Unknown, set to 0 */ + int unknown; + /** The product ID string */ + char product[9]; +} productStruct; + +/** Peer info structure */ +struct SceNetAdhocctlPeerInfo +{ + struct SceNetAdhocctlPeerInfo *next; + /** Nickname */ + char nickname[128]; + /** Mac address */ + unsigned char mac[6]; + /** Unknown */ + unsigned char unknown[6]; + /** Time stamp */ + unsigned long timestamp; +}; + +/** Scan info structure */ +struct SceNetAdhocctlScanInfo +{ + struct SceNetAdhocctlScanInfo *next; + /** Channel number */ + int channel; + /** Name of the connection (alphanumeric characters only) */ + char name[8]; + /** The BSSID */ + unsigned char bssid[6]; + /** Unknown */ + unsigned char unknown[2]; + /** Unknown */ + int unknown2; +}; + +struct SceNetAdhocctlGameModeInfo +{ + /** Number of peers (including self) */ + int count; + /** MAC addresses of peers (including self) */ + unsigned char macs[16][6]; +}; + +/** Params structure */ +struct SceNetAdhocctlParams +{ + /** Channel number */ + int channel; + /** Name of the connection */ + char name[8]; + /** The BSSID */ + unsigned char bssid[6]; + /** Nickname */ + char nickname[128]; +}; + +/** + * Initialise the Adhoc control library + * + * @param stacksize - Stack size of the adhocctl thread. Set to 0x2000 + * @param priority - Priority of the adhocctl thread. Set to 0x30 + * @param product - Pass a filled in ::productStruct + * + * @return 0 on success, < 0 on error + */ +int sceNetAdhocctlInit(int stacksize, int priority, struct productStruct *product); + +/** + * Terminate the Adhoc control library + * + * @return 0 on success, < on error. + */ +int sceNetAdhocctlTerm(void); + +/** + * Connect to the Adhoc control + * + * @param name - The name of the connection (maximum 8 alphanumeric characters). + * + * @return 0 on success, < 0 on error. + */ +int sceNetAdhocctlConnect(const char *name); + +/** + * Disconnect from the Adhoc control + * + * @return 0 on success, < 0 on error + */ +int sceNetAdhocctlDisconnect(void); + +/** + * Get the state of the Adhoc control + * + * @param event - Pointer to an integer to receive the status. Can continue when it becomes 1. + * + * @return 0 on success, < 0 on error + */ +int sceNetAdhocctlGetState(int *event); + +/** + * Connect to the Adhoc control (as a host) + * + * @param name - The name of the connection (maximum 8 alphanumeric characters). + * + * @return 0 on success, < 0 on error. + */ +int sceNetAdhocctlCreate(const char *name); + +/** + * Connect to the Adhoc control (as a client) + * + * @param scaninfo - A valid ::SceNetAdhocctlScanInfo struct that has been filled by sceNetAchocctlGetScanInfo + * + * @return 0 on success, < 0 on error. + */ +int sceNetAdhocctlJoin(struct SceNetAdhocctlScanInfo *scaninfo); + +/** + * Get the adhoc ID + * + * @param product - A pointer to a ::productStruct + * + * @return 0 on success, < 0 on error. + */ +int sceNetAdhocctlGetAdhocId(struct productStruct *product); + +/** + * Connect to the Adhoc control game mode (as a host) + * + * @param name - The name of the connection (maximum 8 alphanumeric characters). + * @param unknown - Pass 1. + * @param num - The total number of players (including the host). + * @param macs - A pointer to a list of the participating mac addresses, host first, then clients. + * @param timeout - Timeout in microseconds. + * @param unknown2 - pass 0. + * + * @return 0 on success, < 0 on error. + */ +int sceNetAdhocctlCreateEnterGameMode(const char *name, int unknown, int num, unsigned char *macs, unsigned int timeout, int unknown2); + +/** + * Connect to the Adhoc control game mode (as a client) + * + * @param name - The name of the connection (maximum 8 alphanumeric characters). + * @param hostmac - The mac address of the host. + * @param timeout - Timeout in microseconds. + * @param unknown - pass 0. + * + * @return 0 on success, < 0 on error. + */ +int sceNetAdhocctlJoinEnterGameMode(const char *name, unsigned char *hostmac, unsigned int timeout, int unknown); + +/** + * Get game mode information + * + * @param gamemodeinfo - Pointer to store the info. + * + * @return 0 on success, < 0 on error. + */ +int sceNetAdhocctlGetGameModeInfo(struct SceNetAdhocctlGameModeInfo *gamemodeinfo); + +/** + * Exit game mode. + * + * @return 0 on success, < 0 on error. + */ +int sceNetAdhocctlExitGameMode(void); + +/** + * Get a list of peers + * + * @param length - The length of the list. + * @param buf - An allocated area of size length. + * + * @return 0 on success, < 0 on error. + */ +int sceNetAdhocctlGetPeerList(int *length, void *buf); + +/** + * Get peer information + * + * @param mac - The mac address of the peer. + * @param size - Size of peerinfo. + * @param peerinfo - Pointer to store the information. + * + * @return 0 on success, < 0 on error. + */ +int sceNetAdhocctlGetPeerInfo(unsigned char *mac, int size, struct SceNetAdhocctlPeerInfo *peerinfo); + +/** + * Scan the adhoc channels + * + * @return 0 on success, < 0 on error. + */ +int sceNetAdhocctlScan(void); + +/** + * Get the results of a scan + * + * @param length - The length of the list. + * @param buf - An allocated area of size length. + * + * @return 0 on success, < 0 on error. + */ +int sceNetAdhocctlGetScanInfo(int *length, void *buf); + +typedef void (*sceNetAdhocctlHandler)(int flag, int error, void *unknown); + +/** + * Register an adhoc event handler + * + * @param handler - The event handler. + * @param unknown - Pass NULL. + * + * @return Handler id on success, < 0 on error. + */ +int sceNetAdhocctlAddHandler(sceNetAdhocctlHandler handler, void *unknown); + +/** + * Delete an adhoc event handler + * + * @param id - The handler id as returned by sceNetAdhocctlAddHandler. + * + * @return 0 on success, < 0 on error. + */ +int sceNetAdhocctlDelHandler(int id); + +/** + * Get nickname from a mac address + * + * @param mac - The mac address. + * @param nickname - Pointer to a char buffer where the nickname will be stored. + * + * @return 0 on success, < 0 on error. + */ +int sceNetAdhocctlGetNameByAddr(unsigned char *mac, char *nickname); + +/** + * Get mac address from nickname + * + * @param nickname - The nickname. + * @param length - The length of the list. + * @param buf - An allocated area of size length. + * + * @return 0 on success, < 0 on error. + */ +int sceNetAdhocctlGetAddrByName(char *nickname, int *length, void *buf); + +/** + * Get Adhocctl parameter + * + * @param params - Pointer to a ::SceNetAdhocctlParams + * + * @return 0 on success, < 0 on error. + */ +int sceNetAdhocctlGetParameter(struct SceNetAdhocctlParams *params); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/net/pspnet_adhocmatching.h b/src/net/pspnet_adhocmatching.h new file mode 100644 index 00000000..5704771b --- /dev/null +++ b/src/net/pspnet_adhocmatching.h @@ -0,0 +1,269 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspnet_adhocmatching.h - PSP Adhoc matching networking libraries. + * + * Copyright (c) 2006 James F. + * Copyright (c) 2008 InsertWittyName + * + * Based on the adhoc code in SMS Plus + * + * $Id: pspnet_adhocmatching.h 2433 2008-10-15 10:00:27Z iwn $ + */ +#ifndef __PSPNETMATCHING_ADHOC_H__ +#define __PSPNETMATCHING_ADHOC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Matching events used in pspAdhocMatchingCallback + */ +enum pspAdhocMatchingEvents +{ + /** Hello event. optdata contains data if optlen > 0. */ + PSP_ADHOC_MATCHING_EVENT_HELLO = 1, + /** Join request. optdata contains data if optlen > 0. */ + PSP_ADHOC_MATCHING_EVENT_JOIN = 2, + /** Target left matching. */ + PSP_ADHOC_MATCHING_EVENT_LEFT = 3, + /** Join request rejected. */ + PSP_ADHOC_MATCHING_EVENT_REJECT = 4, + /** Join request cancelled. */ + PSP_ADHOC_MATCHING_EVENT_CANCEL = 5, + /** Join request accepted. optdata contains data if optlen > 0. */ + PSP_ADHOC_MATCHING_EVENT_ACCEPT = 6, + /** Matching is complete. */ + PSP_ADHOC_MATCHING_EVENT_COMPLETE = 7, + /** Ping timeout event. */ + PSP_ADHOC_MATCHING_EVENT_TIMEOUT = 8, + /** Error event. */ + PSP_ADHOC_MATCHING_EVENT_ERROR = 9, + /** Peer disconnect event. */ + PSP_ADHOC_MATCHING_EVENT_DISCONNECT = 10, + /** Data received event. optdata contains data if optlen > 0. */ + PSP_ADHOC_MATCHING_EVENT_DATA = 11, + /** Data acknowledged event. */ + PSP_ADHOC_MATCHING_EVENT_DATA_CONFIRM = 12, + /** Data timeout event. */ + PSP_ADHOC_MATCHING_EVENT_DATA_TIMEOUT = 13 +}; + +/** + * Matching modes used in sceNetAdhocMatchingCreate + */ +enum pspAdhocMatchingModes +{ + /** Host */ + PSP_ADHOC_MATCHING_MODE_HOST = 1, + /** Client */ + PSP_ADHOC_MATCHING_MODE_CLIENT = 2, + /** Peer to peer */ + PSP_ADHOC_MATCHING_MODE_PTP = 3 +}; + +/** + * Linked list for sceNetAdhocMatchingGetMembers + */ +struct pspAdhocMatchingMember +{ + struct pspAdhocMatchingMember *next; + unsigned char mac[6]; + char unknown[2]; +}; + +/** + * Linked list for sceNetAdhocMatchingGetMembers + */ +struct pspAdhocPoolStat +{ + /** Size of the pool */ + int size; + /** Maximum size of the pool */ + int maxsize; + /** Unused memory in the pool */ + int freesize; +}; + +/** + * Initialise the Adhoc matching library + * + * @param memsize - Internal memory pool size. Lumines uses 0x20000 + * + * @return 0 on success, < 0 on error + */ +int sceNetAdhocMatchingInit(int memsize); + +/** + * Terminate the Adhoc matching library + * + * @return 0 on success, < 0 on error + */ +int sceNetAdhocMatchingTerm(void); + +/** Matching callback */ +typedef void (*pspAdhocMatchingCallback)(int matchingid, int event, unsigned char *mac, int optlen, void *optdata); + +/** + * Create an Adhoc matching object + * + * @param mode - One of ::pspAdhocMatchingModes + * @param maxpeers - Maximum number of peers to match (only used when mode is PSP_ADHOC_MATCHING_MODE_HOST) + * @param port - Port. Lumines uses 0x22B + * @param bufsize - Receiving buffer size + * @param hellodelay - Hello message send delay in microseconds (only used when mode is PSP_ADHOC_MATCHING_MODE_HOST or PSP_ADHOC_MATCHING_MODE_PTP) + * @param pingdelay - Ping send delay in microseconds. Lumines uses 0x5B8D80 (only used when mode is PSP_ADHOC_MATCHING_MODE_HOST or PSP_ADHOC_MATCHING_MODE_PTP) + * @param initcount - Initial count of the of the resend counter. Lumines uses 3 + * @param msgdelay - Message send delay in microseconds + * @param callback - Callback to be called for matching + * + * @return ID of object on success, < 0 on error. + */ +int sceNetAdhocMatchingCreate(int mode, int maxpeers, unsigned short port, int bufsize, unsigned int hellodelay, unsigned int pingdelay, int initcount, unsigned int msgdelay, pspAdhocMatchingCallback callback); + +/** + * Delete an Adhoc matching object + * + * @param matchingid - The ID returned from ::sceNetAdhocMatchingCreate + * + * @return 0 on success, < 0 on error. + */ +int sceNetAdhocMatchingDelete(int matchingid); + +/** + * Start a matching object + * + * @param matchingid - The ID returned from ::sceNetAdhocMatchingCreate + * @param evthpri - Priority of the event handler thread. Lumines uses 0x10 + * @param evthstack - Stack size of the event handler thread. Lumines uses 0x2000 + * @param inthpri - Priority of the input handler thread. Lumines uses 0x10 + * @param inthstack - Stack size of the input handler thread. Lumines uses 0x2000 + * @param optlen - Size of hellodata + * @param optdata - Pointer to block of data passed to callback + * + * @return 0 on success, < 0 on error + */ +int sceNetAdhocMatchingStart(int matchingid, int evthpri, int evthstack, int inthpri, int inthstack, int optlen, void *optdata); + +/** + * Stop a matching object + * + * @param matchingid - The ID returned from ::sceNetAdhocMatchingCreate + * + * @return 0 on success, < 0 on error. + */ +int sceNetAdhocMatchingStop(int matchingid); + +/** + * Select a matching target + * + * @param matchingid - The ID returned from ::sceNetAdhocMatchingCreate + * @param mac - MAC address to select + * @param optlen - Optional data length + * @param optdata - Pointer to the optional data + * + * @return 0 on success, < 0 on error. + */ +int sceNetAdhocMatchingSelectTarget(int matchingid, unsigned char *mac, int optlen, void *optdata); + +/** + * Cancel a matching target + * + * @param matchingid - The ID returned from ::sceNetAdhocMatchingCreate + * @param mac - The MAC address to cancel + * + * @return 0 on success, < 0 on error. + */ +int sceNetAdhocMatchingCancelTarget(int matchingid, unsigned char *mac); + +/** + * Cancel a matching target (with optional data) + * + * @param matchingid - The ID returned from ::sceNetAdhocMatchingCreate + * @param mac - The MAC address to cancel + * @param optlen - Optional data length + * @param optdata - Pointer to the optional data + * + * @return 0 on success, < 0 on error. + */ +int sceNetAdhocMatchingCancelTargetWithOpt(int matchingid, unsigned char *mac, int optlen, void *optdata); + +/** + * Send data to a matching target + * + * @param matchingid - The ID returned from ::sceNetAdhocMatchingCreate + * @param mac - The MAC address to send the data to + * @param datalen - Length of the data + * @param data - Pointer to the data + * + * @return 0 on success, < 0 on error. + */ +int sceNetAdhocMatchingSendData(int matchingid, unsigned char *mac, int datalen, void *data); + +/** + * Abort a data send to a matching target + * + * @param matchingid - The ID returned from ::sceNetAdhocMatchingCreate + * @param mac - The MAC address to send the data to + * + * @return 0 on success, < 0 on error. + */ +int sceNetAdhocMatchingAbortSendData(int matchingid, unsigned char *mac); + +/** + * Set the optional hello message + * + * @param matchingid - The ID returned from ::sceNetAdhocMatchingCreate + * @param optlen - Length of the hello data + * @param optdata - Pointer to the hello data + * + * @return 0 on success, < 0 on error. + */ +int sceNetAdhocMatchingSetHelloOpt(int matchingid, int optlen, void *optdata); + +/** + * Get the optional hello message + * + * @param matchingid - The ID returned from ::sceNetAdhocMatchingCreate + * @param optlen - Length of the hello data + * @param optdata - Pointer to the hello data + * + * @return 0 on success, < 0 on error. + */ +int sceNetAdhocMatchingGetHelloOpt(int matchingid, int *optlen, void *optdata); + +/** + * Get a list of matching members + * + * @param matchingid - The ID returned from ::sceNetAdhocMatchingCreate + * @param length - The length of the list. + * @param buf - An allocated area of size length. + * + * @return 0 on success, < 0 on error. + */ +int sceNetAdhocMatchingGetMembers(int matchingid, int *length, void *buf); + +/** + * Get the maximum memory usage by the matching library + * + * @return The memory usage on success, < 0 on error. + */ +int sceNetAdhocMatchingGetPoolMaxAlloc(void); + +/** + * Get the status of the memory pool used by the matching library + * + * @param poolstat - A ::pspAdhocPoolStat. + * + * @return 0 on success, < 0 on error. + */ +int sceNetAdhocMatchingGetPoolStat(struct pspAdhocPoolStat *poolstat); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/net/pspnet_apctl.h b/src/net/pspnet_apctl.h new file mode 100644 index 00000000..c60e496d --- /dev/null +++ b/src/net/pspnet_apctl.h @@ -0,0 +1,171 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspnet_apctl.h - PSP networking libraries. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2008 David Perry + * + * Portions based on PspPet's wifi_03 sample code. + * + * $Id: pspnet_apctl.h 2434 2008-10-15 17:37:25Z iwn $ + */ + +#ifndef PSPNET_APCTL_H +#define PSPNET_APCTL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define PSP_NET_APCTL_STATE_DISCONNECTED 0 +#define PSP_NET_APCTL_STATE_SCANNING 1 +#define PSP_NET_APCTL_STATE_JOINING 2 +#define PSP_NET_APCTL_STATE_GETTING_IP 3 +#define PSP_NET_APCTL_STATE_GOT_IP 4 +#define PSP_NET_APCTL_STATE_EAP_AUTH 5 +#define PSP_NET_APCTL_STATE_KEY_EXCHANGE 6 + +#define PSP_NET_APCTL_EVENT_CONNECT_REQUEST 0 +#define PSP_NET_APCTL_EVENT_SCAN_REQUEST 1 +#define PSP_NET_APCTL_EVENT_SCAN_COMPLETE 2 +#define PSP_NET_APCTL_EVENT_ESTABLISHED 3 +#define PSP_NET_APCTL_EVENT_GET_IP 4 +#define PSP_NET_APCTL_EVENT_DISCONNECT_REQUEST 5 +#define PSP_NET_APCTL_EVENT_ERROR 6 +#define PSP_NET_APCTL_EVENT_INFO 7 +#define PSP_NET_APCTL_EVENT_EAP_AUTH 8 +#define PSP_NET_APCTL_EVENT_KEY_EXCHANGE 9 +#define PSP_NET_APCTL_EVENT_RECONNECT 10 + +#define PSP_NET_APCTL_INFO_PROFILE_NAME 0 +#define PSP_NET_APCTL_INFO_BSSID 1 +#define PSP_NET_APCTL_INFO_SSID 2 +#define PSP_NET_APCTL_INFO_SSID_LENGTH 3 +#define PSP_NET_APCTL_INFO_SECURITY_TYPE 4 +#define PSP_NET_APCTL_INFO_STRENGTH 5 +#define PSP_NET_APCTL_INFO_CHANNEL 6 +#define PSP_NET_APCTL_INFO_POWER_SAVE 7 +#define PSP_NET_APCTL_INFO_IP 8 +#define PSP_NET_APCTL_INFO_SUBNETMASK 9 +#define PSP_NET_APCTL_INFO_GATEWAY 10 +#define PSP_NET_APCTL_INFO_PRIMDNS 11 +#define PSP_NET_APCTL_INFO_SECDNS 12 +#define PSP_NET_APCTL_INFO_USE_PROXY 13 +#define PSP_NET_APCTL_INFO_PROXY_URL 14 +#define PSP_NET_APCTL_INFO_PROXY_PORT 15 +#define PSP_NET_APCTL_INFO_8021_EAP_TYPE 16 +#define PSP_NET_APCTL_INFO_START_BROWSER 17 +#define PSP_NET_APCTL_INFO_WIFISP 18 + +#define PSP_NET_APCTL_INFO_SECURITY_TYPE_NONE 0 +#define PSP_NET_APCTL_INFO_SECURITY_TYPE_WEP 1 +#define PSP_NET_APCTL_INFO_SECURITY_TYPE_WPA 2 + +union SceNetApctlInfo +{ + char name[64]; /* Name of the config used */ + unsigned char bssid[6]; /* MAC address of the access point */ + unsigned char ssid[32]; /* ssid */ + unsigned int ssidLength; /* ssid string length*/ + unsigned int securityType; /* 0 for none, 1 for WEP, 2 for WPA) */ + unsigned char strength; /* Signal strength in % */ + unsigned char channel; /* Channel */ + unsigned char powerSave; /* 1 on, 0 off */ + char ip[16]; /* PSP's ip */ + char subNetMask[16]; /* Subnet mask */ + char gateway[16]; /* Gateway */ + char primaryDns[16]; /* Primary DNS */ + char secondaryDns[16]; /* Secondary DNS */ + unsigned int useProxy; /* 1 for proxy, 0 for no proxy */ + char proxyUrl[128]; /* Proxy url */ + unsigned short proxyPort; /* Proxy port */ + unsigned int eapType; /* 0 is none, 1 is EAP-MD5 */ + unsigned int startBrowser; /* Should browser be started */ + unsigned int wifisp; /* 1 if connection is for Wifi service providers (WISP) */ + +}; + +typedef void (*sceNetApctlHandler)(int oldState, int newState, int event, int error, void *pArg); + +/** + * Init the apctl. + * + * @param stackSize - The stack size of the internal thread. + * + * @param initPriority - The priority of the internal thread. + * + * @return < 0 on error. + */ +int sceNetApctlInit(int stackSize, int initPriority); + +/** + * Terminate the apctl. + * + * @return < 0 on error. + */ +int sceNetApctlTerm(void); + +/** + * Get the apctl information. + * + * @param code - One of the PSP_NET_APCTL_INFO_* defines. + * + * @param pInfo - Pointer to a ::SceNetApctlInfo. + * + * @return < 0 on error. + */ +int sceNetApctlGetInfo(int code, union SceNetApctlInfo *pInfo); + +/** + * Add an apctl event handler. + * + * @param handler - Pointer to the event handler function. + * + * @param pArg - Value to be passed to the pArg parameter of the handler function. + * + * @return A handler id or < 0 on error. + */ +int sceNetApctlAddHandler(sceNetApctlHandler handler, void *pArg); + +/** + * Delete an apctl event handler. + * + * @param handlerid - A handler as created returned from sceNetApctlAddHandler. + * + * @return < 0 on error. + */ +int sceNetApctlDelHandler(int handlerId); + +/** + * Connect to an access point. + * + * @param connIndex - The index of the connection. + * + * @return < 0 on error. + */ +int sceNetApctlConnect(int connIndex); + +/** + * Disconnect from an access point. + * + * @return < 0 on error. + */ +int sceNetApctlDisconnect(void); + +/** + * Get the state of the access point connection. + * + * @param pState - Pointer to receive the current state (one of the PSP_NET_APCTL_STATE_* defines). + * + * @return < 0 on error. + */ +int sceNetApctlGetState(int *pState); + +#ifdef __cplusplus +} +#endif + +#endif /* PSPNET_APCTL_H */ diff --git a/src/net/pspnet_inet.h b/src/net/pspnet_inet.h new file mode 100644 index 00000000..61a0177f --- /dev/null +++ b/src/net/pspnet_inet.h @@ -0,0 +1,47 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspnet_inet.h - PSP networking libraries. + * + * Copyright (c) 2005 Marcus R. Brown + * + * Portions based on PspPet's wifi_03 sample code. + * + * $Id: pspnet_inet.h 1541 2005-12-08 05:49:20Z mrbrown $ + */ + +#ifndef PSPNET_INET_H +#define PSPNET_INET_H + +#ifdef __cplusplus +extern "C" { +#endif + +int sceNetInetInit(void); +int sceNetInetTerm(void); + +/* The real sceNetInet socket prototypes are in . */ +#ifdef DOXYGEN +int sceNetInetAccept(int s, struct sockaddr *addr, socklen_t *addrlen); +int sceNetInetBind(int s, const struct sockaddr *my_addr, socklen_t addrlen); +int sceNetInetConnect(int s, const struct sockaddr *serv_addr, socklen_t addrlen); +int sceNetInetGetsockopt(int s, int level, int optname, void *optval, socklen_t *optlen); +int sceNetInetListen(int s, int backlog); +size_t sceNetInetRecv(int s, void *buf, size_t len, int flags); +size_t sceNetInetRecvfrom(int s, void *buf, size_t flags, int, struct sockaddr *from, socklen_t *fromlen); +size_t sceNetInetSend(int s, const void *buf, size_t len, int flags); +size_t sceNetInetSendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen); +int sceNetInetSetsockopt(int s, int level, int optname, const void *optval, socklen_t optlen); +int sceNetInetShutdown(int s, int how); +int sceNetInetSocket(int domain, int type, int protocol); +int sceNetInetClose(int s); +int sceNetInetGetErrno(void); +#endif /* DOXYGEN */ + +#ifdef __cplusplus +} +#endif + +#endif /* PSPNET_INET_H */ diff --git a/src/net/pspnet_resolver.h b/src/net/pspnet_resolver.h new file mode 100644 index 00000000..beeb678c --- /dev/null +++ b/src/net/pspnet_resolver.h @@ -0,0 +1,98 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspnet_resolver.h - PSP networking libraries. + * + * Copyright (c) 2005 Marcus R. Brown + * + * Portions based on PspPet's wifi_03 sample code. + * + * $Id: pspnet_resolver.h 1661 2006-01-08 13:36:35Z tyranid $ + */ + +#ifndef PSPNET_RESOLVER_H +#define PSPNET_RESOLVER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** + * Inititalise the resolver library + * + * @return 0 on sucess, < 0 on error. + */ +int sceNetResolverInit(void); + +/** + * Create a resolver object + * + * @param rid - Pointer to receive the resolver id + * @param buf - Temporary buffer + * @param buflen - Length of the temporary buffer + * + * @return 0 on success, < 0 on error + */ +int sceNetResolverCreate(int *rid, void *buf, SceSize buflen); + +/** + * Delete a resolver + * + * @param rid - The resolver to delete + * + * @return 0 on success, < 0 on error + */ +int sceNetResolverDelete(int rid); + +/** + * Begin a name to address lookup + * + * @param rid - Resolver id + * @param hostname - Name to resolve + * @param addr - Pointer to in_addr structure to receive the address + * @param timeout - Number of seconds before timeout + * @param retry - Number of retires + * + * @return 0 on success, < 0 on error + */ +int sceNetResolverStartNtoA(int rid, const char *hostname, struct in_addr* addr, unsigned int timeout, int retry); + +/** + * Begin a address to name lookup + * + * @param rid -Resolver id + * @param addr - Pointer to the address to resolve + * @param hostname - Buffer to receive the name + * @param hostname_len - Length of the buffer + * @param timeout - Number of seconds before timeout + * @param retry - Number of retries + * + * @return 0 on success, < 0 on error + */ +int sceNetResolverStartAtoN(int rid, const struct in_addr* addr, char *hostname, SceSize hostname_len, unsigned int timeout, int retry); + +/** + * Stop a resolver operation + * + * @param rid - Resolver id + * + * @return 0 on success, < 0 on error + */ +int sceNetResolverStop(int rid); + +/** + * Terminate the resolver library + * + * @return 0 on success, < 0 on error + */ +int sceNetResolverTerm(void); + +#ifdef __cplusplus +} +#endif + +#endif /* PSPNET_RESOLVER_H */ diff --git a/src/net/pspssl.h b/src/net/pspssl.h new file mode 100644 index 00000000..71ec9477 --- /dev/null +++ b/src/net/pspssl.h @@ -0,0 +1,58 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspssl.h - Interface to the ssl library. + * + * Copyright (c) 2008 David Perry (InsertWittyName) + * Copyright (c) 2008 moonlight + * + */ + +#ifndef __PSPSSL_H__ +#define __PSPSSL_H__ + +#if defined(__cplusplus) +extern "C" { +#endif + +/** + * Init the ssl library. + * + * @param unknown1 - Memory size? Pass 0x28000 + * + * @return 0 on success +*/ +int sceSslInit(int unknown1); + +/** + * Terminate the ssl library. + * + * @return 0 on success +*/ +int sceSslEnd(void); + +/** + * Get the maximum memory size used by ssl. + * + * @param memory - Pointer where the maximum memory used value will be stored. + * + * @return 0 on success +*/ +int sceSslGetUsedMemoryMax(unsigned int *memory); + +/** + * Get the current memory size used by ssl. + * + * @param memory - Pointer where the current memory used value will be stored. + * + * @return 0 on success +*/ +int sceSslGetUsedMemoryCurrent(unsigned int *memory); + +#if defined(__cplusplus) +}; +#endif + +#endif diff --git a/src/net/sceHttp.S b/src/net/sceHttp.S new file mode 100644 index 00000000..49de4f72 --- /dev/null +++ b/src/net/sceHttp.S @@ -0,0 +1,259 @@ + .set noreorder + +#include "pspimport.s" + +// Build List +// sceHttp_0000.o sceHttp_0001.o sceHttp_0002.o sceHttp_0003.o sceHttp_0004.o sceHttp_0005.o sceHttp_0006.o sceHttp_0007.o sceHttp_0008.o sceHttp_0009.o sceHttp_0010.o sceHttp_0011.o sceHttp_0012.o sceHttp_0013.o sceHttp_0014.o sceHttp_0015.o sceHttp_0016.o sceHttp_0017.o sceHttp_0018.o sceHttp_0019.o sceHttp_0020.o sceHttp_0021.o sceHttp_0022.o sceHttp_0023.o sceHttp_0024.o sceHttp_0025.o sceHttp_0026.o sceHttp_0027.o sceHttp_0028.o sceHttp_0029.o sceHttp_0030.o sceHttp_0031.o sceHttp_0032.o sceHttp_0033.o sceHttp_0034.o sceHttp_0035.o sceHttp_0036.o sceHttp_0037.o sceHttp_0038.o sceHttp_0039.o sceHttp_0040.o sceHttp_0041.o sceHttp_0042.o sceHttp_0043.o sceHttp_0044.o sceHttp_0045.o sceHttp_0046.o sceHttp_0047.o sceHttp_0048.o sceHttp_0049.o sceHttp_0050.o sceHttp_0051.o sceHttp_0052.o sceHttp_0053.o sceHttp_0054.o sceHttp_0055.o sceHttp_0056.o sceHttp_0057.o sceHttp_0058.o sceHttp_0059.o sceHttp_0060.o sceHttp_0061.o sceHttp_0062.o sceHttp_0063.o sceHttp_0064.o sceHttp_0065.o sceHttp_0066.o sceHttp_0067.o sceHttp_0068.o sceHttp_0069.o sceHttp_0070.o sceHttp_0071.o sceHttp_0072.o sceHttp_0073.o sceHttp_0074.o sceHttp_0075.o sceHttp_0076.o sceHttp_0077.o sceHttp_0078.o sceHttp_0079.o sceHttp_0080.o sceHttp_0081.o sceHttp_0082.o sceHttp_0083.o + +#ifdef F_sceHttp_0000 + IMPORT_START "sceHttp",0x00090011 +#endif +#ifdef F_sceHttp_0001 + IMPORT_FUNC "sceHttp",0x0282A3BD,sceHttpGetContentLength +#endif +#ifdef F_sceHttp_0002 + IMPORT_FUNC "sceHttp",0x03D9526F,sceHttpSetResolveRetry +#endif +#ifdef F_sceHttp_0003 + IMPORT_FUNC "sceHttp",0x06488A1C,sceHttpSetCookieSendCallback +#endif +#ifdef F_sceHttp_0004 + IMPORT_FUNC "sceHttp",0x0809C831,sceHttpEnableRedirect +#endif +#ifdef F_sceHttp_0005 + IMPORT_FUNC "sceHttp",0x0B12ABFB,sceHttpDisableCookie +#endif +#ifdef F_sceHttp_0006 + IMPORT_FUNC "sceHttp",0x0DAFA58F,sceHttpEnableCookie +#endif +#ifdef F_sceHttp_0007 + IMPORT_FUNC "sceHttp",0x15540184,sceHttpDeleteHeader +#endif +#ifdef F_sceHttp_0008 + IMPORT_FUNC "sceHttp",0x1A0EBB69,sceHttpDisableRedirect +#endif +#ifdef F_sceHttp_0009 + IMPORT_FUNC "sceHttp",0x1CEDB9D4,sceHttpFlushCache +#endif +#ifdef F_sceHttp_0010 + IMPORT_FUNC "sceHttp",0x1F0FC3E3,sceHttpSetRecvTimeOut +#endif +#ifdef F_sceHttp_0011 + IMPORT_FUNC "sceHttp",0x2255551E,sceHttpGetNetworkPspError +#endif +#ifdef F_sceHttp_0012 + IMPORT_FUNC "sceHttp",0x267618F4,sceHttpSetAuthInfoCallback +#endif +#ifdef F_sceHttp_0013 + IMPORT_FUNC "sceHttp",0x2A6C3296,sceHttpSetAuthInfoCB +#endif +#ifdef F_sceHttp_0014 + IMPORT_FUNC "sceHttp",0x2C3C82CF,sceHttpFlushAuthList +#endif +#ifdef F_sceHttp_0015 + IMPORT_FUNC "sceHttp",0x3A67F306,sceHttpSetCookieRecvCallback +#endif +#ifdef F_sceHttp_0016 + IMPORT_FUNC "sceHttp",0x3C478044,sceHttp_3C478044 +#endif +#ifdef F_sceHttp_0017 + IMPORT_FUNC "sceHttp",0x3EABA285,sceHttpAddExtraHeader +#endif +#ifdef F_sceHttp_0018 + IMPORT_FUNC "sceHttp",0x457D221D,sceHttp_457D221D +#endif +#ifdef F_sceHttp_0019 + IMPORT_FUNC "sceHttp",0x47347B50,sceHttpCreateRequest +#endif +#ifdef F_sceHttp_0020 + IMPORT_FUNC "sceHttp",0x47940436,sceHttpSetResolveTimeOut +#endif +#ifdef F_sceHttp_0021 + IMPORT_FUNC "sceHttp",0x4CC7D78F,sceHttpGetStatusCode +#endif +#ifdef F_sceHttp_0022 + IMPORT_FUNC "sceHttp",0x4E4A284A,sceHttp_4E4A284A +#endif +#ifdef F_sceHttp_0023 + IMPORT_FUNC "sceHttp",0x5152773B,sceHttpDeleteConnection +#endif +#ifdef F_sceHttp_0024 + IMPORT_FUNC "sceHttp",0x54E7DF75,sceHttpIsRequestInCache +#endif +#ifdef F_sceHttp_0025 + IMPORT_FUNC "sceHttp",0x569A1481,sceHttpsSetSslCallback +#endif +#ifdef F_sceHttp_0026 + IMPORT_FUNC "sceHttp",0x59E6D16F,sceHttpEnableCache +#endif +#ifdef F_sceHttp_0027 + IMPORT_FUNC "sceHttp",0x68AB0F86,sceHttpsInitWithPath +#endif +#ifdef F_sceHttp_0028 + IMPORT_FUNC "sceHttp",0x739C2D79,sceHttp_739C2D79 +#endif +#ifdef F_sceHttp_0029 + IMPORT_FUNC "sceHttp",0x76D1363B,sceHttpSaveSystemCookie +#endif +#ifdef F_sceHttp_0030 + IMPORT_FUNC "sceHttp",0x7774BF4C,sceHttpAddCookie +#endif +#ifdef F_sceHttp_0031 + IMPORT_FUNC "sceHttp",0x77EE5319,sceHttp_77EE5319 +#endif +#ifdef F_sceHttp_0032 + IMPORT_FUNC "sceHttp",0x78A0D3EC,sceHttpEnableKeepAlive +#endif +#ifdef F_sceHttp_0033 + IMPORT_FUNC "sceHttp",0x78B54C09,sceHttpEndCache +#endif +#ifdef F_sceHttp_0034 + IMPORT_FUNC "sceHttp",0x8046E250,sceHttp_8046E250 +#endif +#ifdef F_sceHttp_0035 + IMPORT_FUNC "sceHttp",0x87797BDD,sceHttpsLoadDefaultCert +#endif +#ifdef F_sceHttp_0036 + IMPORT_FUNC "sceHttp",0x87F1E666,sceHttp_87F1E666 +#endif +#ifdef F_sceHttp_0037 + IMPORT_FUNC "sceHttp",0x8ACD1F73,sceHttpSetConnectTimeOut +#endif +#ifdef F_sceHttp_0038 + IMPORT_FUNC "sceHttp",0x8EEFD953,sceHttpCreateConnection +#endif +#ifdef F_sceHttp_0039 + IMPORT_FUNC "sceHttp",0x951D310E,sceHttp_951D310E +#endif +#ifdef F_sceHttp_0040 + IMPORT_FUNC "sceHttp",0x9668864C,sceHttpSetRecvBlockSize +#endif +#ifdef F_sceHttp_0041 + IMPORT_FUNC "sceHttp",0x96F16D3E,sceHttpGetCookie +#endif +#ifdef F_sceHttp_0042 + IMPORT_FUNC "sceHttp",0x9988172D,sceHttpSetSendTimeOut +#endif +#ifdef F_sceHttp_0043 + IMPORT_FUNC "sceHttp",0x9AFC98B2,sceHttpSendRequestInCacheFirstMode +#endif +#ifdef F_sceHttp_0044 + IMPORT_FUNC "sceHttp",0x9B1F1F36,sceHttpCreateTemplate +#endif +#ifdef F_sceHttp_0045 + IMPORT_FUNC "sceHttp",0x9FC5F10D,sceHttpEnableAuth +#endif +#ifdef F_sceHttp_0046 + IMPORT_FUNC "sceHttp",0xA4496DE5,sceHttpSetRedirectCallback +#endif +#ifdef F_sceHttp_0047 + IMPORT_FUNC "sceHttp",0xA461A167,sceHttp_A461A167 +#endif +#ifdef F_sceHttp_0048 + IMPORT_FUNC "sceHttp",0xA5512E01,sceHttpDeleteRequest +#endif +#ifdef F_sceHttp_0049 + IMPORT_FUNC "sceHttp",0xA6800C34,sceHttpInitCache +#endif +#ifdef F_sceHttp_0050 + IMPORT_FUNC "sceHttp",0xA909F2AE,sceHttp_A909F2AE +#endif +#ifdef F_sceHttp_0051 + IMPORT_FUNC "sceHttp",0xAB1540D5,sceHttpsGetSslError +#endif +#ifdef F_sceHttp_0052 + IMPORT_FUNC "sceHttp",0xAB1ABE07,sceHttpInit +#endif +#ifdef F_sceHttp_0053 + IMPORT_FUNC "sceHttp",0xAE948FEE,sceHttpDisableAuth +#endif +#ifdef F_sceHttp_0054 + IMPORT_FUNC "sceHttp",0xB0257723,sceHttp_B0257723 +#endif +#ifdef F_sceHttp_0055 + IMPORT_FUNC "sceHttp",0xB0C34B1D,sceHttpSetCacheContentLengthMaxSize +#endif +#ifdef F_sceHttp_0056 + IMPORT_FUNC "sceHttp",0xB3FAF831,sceHttpsDisableOption +#endif +#ifdef F_sceHttp_0057 + IMPORT_FUNC "sceHttp",0xB509B09E,sceHttpCreateRequestWithURL +#endif +#ifdef F_sceHttp_0058 + IMPORT_FUNC "sceHttp",0xBAC31BF1,sceHttpsEnableOption +#endif +#ifdef F_sceHttp_0059 + IMPORT_FUNC "sceHttp",0xBB70706F,sceHttpSendRequest +#endif +#ifdef F_sceHttp_0060 + IMPORT_FUNC "sceHttp",0xC0E69162,sceHttp_C0E69162 +#endif +#ifdef F_sceHttp_0061 + IMPORT_FUNC "sceHttp",0xC10B6BD9,sceHttpAbortRequest +#endif +#ifdef F_sceHttp_0062 + IMPORT_FUNC "sceHttp",0xC6330B0D,sceHttp_C6330B0D +#endif +#ifdef F_sceHttp_0063 + IMPORT_FUNC "sceHttp",0xC7EF2559,sceHttpDisableKeepAlive +#endif +#ifdef F_sceHttp_0064 + IMPORT_FUNC "sceHttp",0xC98CBBA7,sceHttpSetResHeaderMaxSize +#endif +#ifdef F_sceHttp_0065 + IMPORT_FUNC "sceHttp",0xCC920C12,sceHttp_CC920C12 +#endif +#ifdef F_sceHttp_0066 + IMPORT_FUNC "sceHttp",0xCCBD167A,sceHttpDisableCache +#endif +#ifdef F_sceHttp_0067 + IMPORT_FUNC "sceHttp",0xCDB0DC58,sceHttp_CDB0DC58 +#endif +#ifdef F_sceHttp_0068 + IMPORT_FUNC "sceHttp",0xCDF8ECB9,sceHttpCreateConnectionWithURL +#endif +#ifdef F_sceHttp_0069 + IMPORT_FUNC "sceHttp",0xD081EC8F,sceHttpGetNetworkErrno +#endif +#ifdef F_sceHttp_0070 + IMPORT_FUNC "sceHttp",0xD11DAB01,sceHttpsGetCaList +#endif +#ifdef F_sceHttp_0071 + IMPORT_FUNC "sceHttp",0xD1C8945E,sceHttpEnd +#endif +#ifdef F_sceHttp_0072 + IMPORT_FUNC "sceHttp",0xD29163DA,sceHttp_D29163DA +#endif +#ifdef F_sceHttp_0073 + IMPORT_FUNC "sceHttp",0xD70D4847,sceHttpGetProxy +#endif +#ifdef F_sceHttp_0074 + IMPORT_FUNC "sceHttp",0xD80BE761,sceHttp_D80BE761 +#endif +#ifdef F_sceHttp_0075 + IMPORT_FUNC "sceHttp",0xDB266CCF,sceHttpGetAllHeader +#endif +#ifdef F_sceHttp_0076 + IMPORT_FUNC "sceHttp",0xDD6E7857,sceHttp_DD6E7857 +#endif +#ifdef F_sceHttp_0077 + IMPORT_FUNC "sceHttp",0xE4D21302,sceHttpsInit +#endif +#ifdef F_sceHttp_0078 + IMPORT_FUNC "sceHttp",0xEDEEB999,sceHttpReadData +#endif +#ifdef F_sceHttp_0079 + IMPORT_FUNC "sceHttp",0xF0F46C62,sceHttpSetProxy +#endif +#ifdef F_sceHttp_0080 + IMPORT_FUNC "sceHttp",0xF1657B22,sceHttpLoadSystemCookie +#endif +#ifdef F_sceHttp_0081 + IMPORT_FUNC "sceHttp",0xF49934F6,sceHttpSetMallocFunction +#endif +#ifdef F_sceHttp_0082 + IMPORT_FUNC "sceHttp",0xF9D8EB63,sceHttpsEnd +#endif +#ifdef F_sceHttp_0083 + IMPORT_FUNC "sceHttp",0xFCF8C055,sceHttpDeleteTemplate +#endif diff --git a/src/net/sceNet.S b/src/net/sceNet.S new file mode 100644 index 00000000..c67f1958 --- /dev/null +++ b/src/net/sceNet.S @@ -0,0 +1,31 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceNet_0000 + IMPORT_START "sceNet",0x00090000 +#endif +#ifdef F_sceNet_0001 + IMPORT_FUNC "sceNet",0x39AF39A6,sceNetInit +#endif +#ifdef F_sceNet_0002 + IMPORT_FUNC "sceNet",0x281928A9,sceNetTerm +#endif +#ifdef F_sceNet_0003 + IMPORT_FUNC "sceNet",0x50647530,sceNetFreeThreadinfo +#endif +#ifdef F_sceNet_0004 + IMPORT_FUNC "sceNet",0xAD6844C6,sceNetThreadAbort +#endif +#ifdef F_sceNet_0005 + IMPORT_FUNC "sceNet",0x89360950,sceNetEtherNtostr +#endif +#ifdef F_sceNet_0006 + IMPORT_FUNC "sceNet",0xD27961C9,sceNetEtherStrton +#endif +#ifdef F_sceNet_0007 + IMPORT_FUNC "sceNet",0x0BF0A3AE,sceNetGetLocalEtherAddr +#endif +#ifdef F_sceNet_0008 + IMPORT_FUNC "sceNet",0xCC393E48,sceNetGetMallocStat +#endif diff --git a/src/net/sceNetAdhoc.S b/src/net/sceNetAdhoc.S new file mode 100644 index 00000000..cd51d416 --- /dev/null +++ b/src/net/sceNetAdhoc.S @@ -0,0 +1,82 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceNetAdhoc_0000 + IMPORT_START "sceNetAdhoc",0x00090000 +#endif +#ifdef F_sceNetAdhoc_0001 + IMPORT_FUNC "sceNetAdhoc",0xE1D621D7,sceNetAdhocInit +#endif +#ifdef F_sceNetAdhoc_0002 + IMPORT_FUNC "sceNetAdhoc",0xA62C6F57,sceNetAdhocTerm +#endif +#ifdef F_sceNetAdhoc_0003 + IMPORT_FUNC "sceNetAdhoc",0x7A662D6B,sceNetAdhocPollSocket +#endif +#ifdef F_sceNetAdhoc_0004 + IMPORT_FUNC "sceNetAdhoc",0x73BFD52D,sceNetAdhocSetSocketAlert +#endif +#ifdef F_sceNetAdhoc_0005 + IMPORT_FUNC "sceNetAdhoc",0x4D2CE199,sceNetAdhocGetSocketAlert +#endif +#ifdef F_sceNetAdhoc_0006 + IMPORT_FUNC "sceNetAdhoc",0x6F92741B,sceNetAdhocPdpCreate +#endif +#ifdef F_sceNetAdhoc_0007 + IMPORT_FUNC "sceNetAdhoc",0xABED3790,sceNetAdhocPdpSend +#endif +#ifdef F_sceNetAdhoc_0008 + IMPORT_FUNC "sceNetAdhoc",0xDFE53E03,sceNetAdhocPdpRecv +#endif +#ifdef F_sceNetAdhoc_0009 + IMPORT_FUNC "sceNetAdhoc",0x7F27BB5E,sceNetAdhocPdpDelete +#endif +#ifdef F_sceNetAdhoc_0010 + IMPORT_FUNC "sceNetAdhoc",0xC7C1FC57,sceNetAdhocGetPdpStat +#endif +#ifdef F_sceNetAdhoc_0011 + IMPORT_FUNC "sceNetAdhoc",0x877F6D66,sceNetAdhocPtpOpen +#endif +#ifdef F_sceNetAdhoc_0012 + IMPORT_FUNC "sceNetAdhoc",0xFC6FC07B,sceNetAdhocPtpConnect +#endif +#ifdef F_sceNetAdhoc_0013 + IMPORT_FUNC "sceNetAdhoc",0xE08BDAC1,sceNetAdhocPtpListen +#endif +#ifdef F_sceNetAdhoc_0014 + IMPORT_FUNC "sceNetAdhoc",0x9DF81198,sceNetAdhocPtpAccept +#endif +#ifdef F_sceNetAdhoc_0015 + IMPORT_FUNC "sceNetAdhoc",0x4DA4C788,sceNetAdhocPtpSend +#endif +#ifdef F_sceNetAdhoc_0016 + IMPORT_FUNC "sceNetAdhoc",0x8BEA2B3E,sceNetAdhocPtpRecv +#endif +#ifdef F_sceNetAdhoc_0017 + IMPORT_FUNC "sceNetAdhoc",0x9AC2EEAC,sceNetAdhocPtpFlush +#endif +#ifdef F_sceNetAdhoc_0018 + IMPORT_FUNC "sceNetAdhoc",0x157E6225,sceNetAdhocPtpClose +#endif +#ifdef F_sceNetAdhoc_0019 + IMPORT_FUNC "sceNetAdhoc",0xB9685118,sceNetAdhocGetPtpStat +#endif +#ifdef F_sceNetAdhoc_0020 + IMPORT_FUNC "sceNetAdhoc",0x7F75C338,sceNetAdhocGameModeCreateMaster +#endif +#ifdef F_sceNetAdhoc_0021 + IMPORT_FUNC "sceNetAdhoc",0x3278AB0C,sceNetAdhocGameModeCreateReplica +#endif +#ifdef F_sceNetAdhoc_0022 + IMPORT_FUNC "sceNetAdhoc",0x98C204C8,sceNetAdhocGameModeUpdateMaster +#endif +#ifdef F_sceNetAdhoc_0023 + IMPORT_FUNC "sceNetAdhoc",0xFA324B4E,sceNetAdhocGameModeUpdateReplica +#endif +#ifdef F_sceNetAdhoc_0024 + IMPORT_FUNC "sceNetAdhoc",0xA0229362,sceNetAdhocGameModeDeleteMaster +#endif +#ifdef F_sceNetAdhoc_0025 + IMPORT_FUNC "sceNetAdhoc",0x0B2228E9,sceNetAdhocGameModeDeleteReplica +#endif diff --git a/src/net/sceNetAdhocMatching.S b/src/net/sceNetAdhocMatching.S new file mode 100644 index 00000000..c652e85a --- /dev/null +++ b/src/net/sceNetAdhocMatching.S @@ -0,0 +1,55 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceNetAdhocMatching_0000 + IMPORT_START "sceNetAdhocMatching",0x00090000 +#endif +#ifdef F_sceNetAdhocMatching_0001 + IMPORT_FUNC "sceNetAdhocMatching",0x2A2A1E07,sceNetAdhocMatchingInit +#endif +#ifdef F_sceNetAdhocMatching_0002 + IMPORT_FUNC "sceNetAdhocMatching",0x7945ECDA,sceNetAdhocMatchingTerm +#endif +#ifdef F_sceNetAdhocMatching_0003 + IMPORT_FUNC "sceNetAdhocMatching",0xCA5EDA6F,sceNetAdhocMatchingCreate +#endif +#ifdef F_sceNetAdhocMatching_0004 + IMPORT_FUNC "sceNetAdhocMatching",0x93EF3843,sceNetAdhocMatchingStart +#endif +#ifdef F_sceNetAdhocMatching_0005 + IMPORT_FUNC "sceNetAdhocMatching",0x32B156B3,sceNetAdhocMatchingStop +#endif +#ifdef F_sceNetAdhocMatching_0006 + IMPORT_FUNC "sceNetAdhocMatching",0xF16EAF4F,sceNetAdhocMatchingDelete +#endif +#ifdef F_sceNetAdhocMatching_0007 + IMPORT_FUNC "sceNetAdhocMatching",0x5E3D4B79,sceNetAdhocMatchingSelectTarget +#endif +#ifdef F_sceNetAdhocMatching_0008 + IMPORT_FUNC "sceNetAdhocMatching",0xEA3C6108,sceNetAdhocMatchingCancelTarget +#endif +#ifdef F_sceNetAdhocMatching_0009 + IMPORT_FUNC "sceNetAdhocMatching",0xB58E61B7,sceNetAdhocMatchingSetHelloOpt +#endif +#ifdef F_sceNetAdhocMatching_0010 + IMPORT_FUNC "sceNetAdhocMatching",0xB5D96C2A,sceNetAdhocMatchingGetHelloOpt +#endif +#ifdef F_sceNetAdhocMatching_0011 + IMPORT_FUNC "sceNetAdhocMatching",0xC58BCD9E,sceNetAdhocMatchingGetMembers +#endif +#ifdef F_sceNetAdhocMatching_0012 + IMPORT_FUNC "sceNetAdhocMatching",0x40F8F435,sceNetAdhocMatchingGetPoolMaxAlloc +#endif +#ifdef F_sceNetAdhocMatching_0013 + IMPORT_FUNC "sceNetAdhocMatching",0x8F58BEDF,sceNetAdhocMatchingCancelTargetWithOpt +#endif +#ifdef F_sceNetAdhocMatching_0014 + IMPORT_FUNC "sceNetAdhocMatching",0x9C5CFB7D,sceNetAdhocMatchingGetPoolStat +#endif +#ifdef F_sceNetAdhocMatching_0015 + IMPORT_FUNC "sceNetAdhocMatching",0xF79472D7,sceNetAdhocMatchingSendData +#endif +#ifdef F_sceNetAdhocMatching_0016 + IMPORT_FUNC "sceNetAdhocMatching",0xEC19337D,sceNetAdhocMatchingAbortSendData +#endif diff --git a/src/net/sceNetAdhocctl.S b/src/net/sceNetAdhocctl.S new file mode 100644 index 00000000..a7fd9a53 --- /dev/null +++ b/src/net/sceNetAdhocctl.S @@ -0,0 +1,70 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceNetAdhocctl_0000 + IMPORT_START "sceNetAdhocctl",0x00090000 +#endif +#ifdef F_sceNetAdhocctl_0001 + IMPORT_FUNC "sceNetAdhocctl",0xE26F226E,sceNetAdhocctlInit +#endif +#ifdef F_sceNetAdhocctl_0002 + IMPORT_FUNC "sceNetAdhocctl",0x9D689E13,sceNetAdhocctlTerm +#endif +#ifdef F_sceNetAdhocctl_0003 + IMPORT_FUNC "sceNetAdhocctl",0x0AD043ED,sceNetAdhocctlConnect +#endif +#ifdef F_sceNetAdhocctl_0004 + IMPORT_FUNC "sceNetAdhocctl",0xEC0635C1,sceNetAdhocctlCreate +#endif +#ifdef F_sceNetAdhocctl_0005 + IMPORT_FUNC "sceNetAdhocctl",0x5E7F79C9,sceNetAdhocctlJoin +#endif +#ifdef F_sceNetAdhocctl_0006 + IMPORT_FUNC "sceNetAdhocctl",0x08FFF7A0,sceNetAdhocctlScan +#endif +#ifdef F_sceNetAdhocctl_0007 + IMPORT_FUNC "sceNetAdhocctl",0x34401D65,sceNetAdhocctlDisconnect +#endif +#ifdef F_sceNetAdhocctl_0008 + IMPORT_FUNC "sceNetAdhocctl",0x20B317A0,sceNetAdhocctlAddHandler +#endif +#ifdef F_sceNetAdhocctl_0009 + IMPORT_FUNC "sceNetAdhocctl",0x6402490B,sceNetAdhocctlDelHandler +#endif +#ifdef F_sceNetAdhocctl_0010 + IMPORT_FUNC "sceNetAdhocctl",0x75ECD386,sceNetAdhocctlGetState +#endif +#ifdef F_sceNetAdhocctl_0011 + IMPORT_FUNC "sceNetAdhocctl",0x362CBE8F,sceNetAdhocctlGetAdhocId +#endif +#ifdef F_sceNetAdhocctl_0012 + IMPORT_FUNC "sceNetAdhocctl",0xE162CB14,sceNetAdhocctlGetPeerList +#endif +#ifdef F_sceNetAdhocctl_0013 + IMPORT_FUNC "sceNetAdhocctl",0x99560ABE,sceNetAdhocctlGetAddrByName +#endif +#ifdef F_sceNetAdhocctl_0014 + IMPORT_FUNC "sceNetAdhocctl",0x8916C003,sceNetAdhocctlGetNameByAddr +#endif +#ifdef F_sceNetAdhocctl_0015 + IMPORT_FUNC "sceNetAdhocctl",0xDED9D28E,sceNetAdhocctlGetParameter +#endif +#ifdef F_sceNetAdhocctl_0016 + IMPORT_FUNC "sceNetAdhocctl",0x81AEE1BE,sceNetAdhocctlGetScanInfo +#endif +#ifdef F_sceNetAdhocctl_0017 + IMPORT_FUNC "sceNetAdhocctl",0xA5C055CE,sceNetAdhocctlCreateEnterGameMode +#endif +#ifdef F_sceNetAdhocctl_0018 + IMPORT_FUNC "sceNetAdhocctl",0x1FF89745,sceNetAdhocctlJoinEnterGameMode +#endif +#ifdef F_sceNetAdhocctl_0019 + IMPORT_FUNC "sceNetAdhocctl",0xCF8E084D,sceNetAdhocctlExitGameMode +#endif +#ifdef F_sceNetAdhocctl_0020 + IMPORT_FUNC "sceNetAdhocctl",0x5A014CE0,sceNetAdhocctlGetGameModeInfo +#endif +#ifdef F_sceNetAdhocctl_0021 + IMPORT_FUNC "sceNetAdhocctl",0x8DB83FDC,sceNetAdhocctlGetPeerInfo +#endif diff --git a/src/net/sceNetApctl.S b/src/net/sceNetApctl.S new file mode 100644 index 00000000..bd0f11eb --- /dev/null +++ b/src/net/sceNetApctl.S @@ -0,0 +1,31 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceNetApctl_0000 + IMPORT_START "sceNetApctl",0x00090000 +#endif +#ifdef F_sceNetApctl_0001 + IMPORT_FUNC "sceNetApctl",0xE2F91F9B,sceNetApctlInit +#endif +#ifdef F_sceNetApctl_0002 + IMPORT_FUNC "sceNetApctl",0xB3EDD0EC,sceNetApctlTerm +#endif +#ifdef F_sceNetApctl_0003 + IMPORT_FUNC "sceNetApctl",0x2BEFDF23,sceNetApctlGetInfo +#endif +#ifdef F_sceNetApctl_0004 + IMPORT_FUNC "sceNetApctl",0x8ABADD51,sceNetApctlAddHandler +#endif +#ifdef F_sceNetApctl_0005 + IMPORT_FUNC "sceNetApctl",0x5963991B,sceNetApctlDelHandler +#endif +#ifdef F_sceNetApctl_0006 + IMPORT_FUNC "sceNetApctl",0xCFB957C6,sceNetApctlConnect +#endif +#ifdef F_sceNetApctl_0007 + IMPORT_FUNC "sceNetApctl",0x24FE91A1,sceNetApctlDisconnect +#endif +#ifdef F_sceNetApctl_0008 + IMPORT_FUNC "sceNetApctl",0x5DEAC81B,sceNetApctlGetState +#endif diff --git a/src/net/sceNetInet.S b/src/net/sceNetInet.S new file mode 100644 index 00000000..7505c58d --- /dev/null +++ b/src/net/sceNetInet.S @@ -0,0 +1,97 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceNetInet_0000 + IMPORT_START "sceNetInet",0x00090000 +#endif +#ifdef F_sceNetInet_0001 + IMPORT_FUNC "sceNetInet",0x17943399,sceNetInetInit +#endif +#ifdef F_sceNetInet_0002 + IMPORT_FUNC "sceNetInet",0xA9ED66B9,sceNetInetTerm +#endif +#ifdef F_sceNetInet_0003 + IMPORT_FUNC "sceNetInet",0xDB094E1B,sceNetInetAccept +#endif +#ifdef F_sceNetInet_0004 + IMPORT_FUNC "sceNetInet",0x1A33F9AE,sceNetInetBind +#endif +#ifdef F_sceNetInet_0005 + IMPORT_FUNC "sceNetInet",0x8D7284EA,sceNetInetClose +#endif +#ifdef F_sceNetInet_0006 + IMPORT_FUNC "sceNetInet",0x805502DD,sceNetInetCloseWithRST +#endif +#ifdef F_sceNetInet_0007 + IMPORT_FUNC "sceNetInet",0x410B34AA,sceNetInetConnect +#endif +#ifdef F_sceNetInet_0008 + IMPORT_FUNC "sceNetInet",0xE247B6D6,sceNetInetGetpeername +#endif +#ifdef F_sceNetInet_0009 + IMPORT_FUNC "sceNetInet",0x162E6FD5,sceNetInetGetsockname +#endif +#ifdef F_sceNetInet_0010 + IMPORT_FUNC "sceNetInet",0x4A114C7C,sceNetInetGetsockopt +#endif +#ifdef F_sceNetInet_0011 + IMPORT_FUNC "sceNetInet",0xD10A1A7A,sceNetInetListen +#endif +#ifdef F_sceNetInet_0012 + IMPORT_FUNC "sceNetInet",0xFAABB1DD,sceNetInetPoll +#endif +#ifdef F_sceNetInet_0013 + IMPORT_FUNC "sceNetInet",0xCDA85C99,sceNetInetRecv +#endif +#ifdef F_sceNetInet_0014 + IMPORT_FUNC "sceNetInet",0xC91142E4,sceNetInetRecvfrom +#endif +#ifdef F_sceNetInet_0015 + IMPORT_FUNC "sceNetInet",0xEECE61D2,sceNetInetRecvmsg +#endif +#ifdef F_sceNetInet_0016 + IMPORT_FUNC "sceNetInet",0x5BE8D595,sceNetInetSelect +#endif +#ifdef F_sceNetInet_0017 + IMPORT_FUNC "sceNetInet",0x7AA671BC,sceNetInetSend +#endif +#ifdef F_sceNetInet_0018 + IMPORT_FUNC "sceNetInet",0x05038FC7,sceNetInetSendto +#endif +#ifdef F_sceNetInet_0019 + IMPORT_FUNC "sceNetInet",0x774E36F4,sceNetInetSendmsg +#endif +#ifdef F_sceNetInet_0020 + IMPORT_FUNC "sceNetInet",0x2FE71FE7,sceNetInetSetsockopt +#endif +#ifdef F_sceNetInet_0021 + IMPORT_FUNC "sceNetInet",0x4CFE4E56,sceNetInetShutdown +#endif +#ifdef F_sceNetInet_0022 + IMPORT_FUNC "sceNetInet",0x8B7B220F,sceNetInetSocket +#endif +#ifdef F_sceNetInet_0023 + IMPORT_FUNC "sceNetInet",0x80A21ABD,sceNetInetSocketAbort +#endif +#ifdef F_sceNetInet_0024 + IMPORT_FUNC "sceNetInet",0xFBABE411,sceNetInetGetErrno +#endif +#ifdef F_sceNetInet_0025 + IMPORT_FUNC "sceNetInet",0xB3888AD4,sceNetInetGetTcpcbstat +#endif +#ifdef F_sceNetInet_0026 + IMPORT_FUNC "sceNetInet",0x39B0C7D3,sceNetInetGetUdpcbstat +#endif +#ifdef F_sceNetInet_0027 + IMPORT_FUNC "sceNetInet",0xB75D5B0A,sceNetInetInetAddr +#endif +#ifdef F_sceNetInet_0028 + IMPORT_FUNC "sceNetInet",0x1BDF5D13,sceNetInetInetAton +#endif +#ifdef F_sceNetInet_0029 + IMPORT_FUNC "sceNetInet",0xD0792666,sceNetInetInetNtop +#endif +#ifdef F_sceNetInet_0030 + IMPORT_FUNC "sceNetInet",0xE30B8C19,sceNetInetInetPton +#endif diff --git a/src/net/sceNetResolver.S b/src/net/sceNetResolver.S new file mode 100644 index 00000000..4af3a465 --- /dev/null +++ b/src/net/sceNetResolver.S @@ -0,0 +1,28 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceNetResolver_0000 + IMPORT_START "sceNetResolver",0x00090000 +#endif +#ifdef F_sceNetResolver_0001 + IMPORT_FUNC "sceNetResolver",0xF3370E61,sceNetResolverInit +#endif +#ifdef F_sceNetResolver_0002 + IMPORT_FUNC "sceNetResolver",0x6138194A,sceNetResolverTerm +#endif +#ifdef F_sceNetResolver_0003 + IMPORT_FUNC "sceNetResolver",0x244172AF,sceNetResolverCreate +#endif +#ifdef F_sceNetResolver_0004 + IMPORT_FUNC "sceNetResolver",0x94523E09,sceNetResolverDelete +#endif +#ifdef F_sceNetResolver_0005 + IMPORT_FUNC "sceNetResolver",0x224C5F44,sceNetResolverStartNtoA +#endif +#ifdef F_sceNetResolver_0006 + IMPORT_FUNC "sceNetResolver",0x629E2FB7,sceNetResolverStartAtoN +#endif +#ifdef F_sceNetResolver_0007 + IMPORT_FUNC "sceNetResolver",0x808F6063,sceNetResolverStop +#endif diff --git a/src/net/sceNet_lib.S b/src/net/sceNet_lib.S new file mode 100644 index 00000000..c115ae54 --- /dev/null +++ b/src/net/sceNet_lib.S @@ -0,0 +1,295 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceNet_lib_0000 + IMPORT_START "sceNet_lib",0x00090000 +#endif +#ifdef F_sceNet_lib_0001 + IMPORT_FUNC "sceNet_lib",0x3B617AA0,sceNet_lib_3B617AA0 +#endif +#ifdef F_sceNet_lib_0002 + IMPORT_FUNC "sceNet_lib",0xDB88F458,sceNet_lib_DB88F458 +#endif +#ifdef F_sceNet_lib_0003 + IMPORT_FUNC "sceNet_lib",0xB6FC0A5B,sceNet_lib_B6FC0A5B +#endif +#ifdef F_sceNet_lib_0004 + IMPORT_FUNC "sceNet_lib",0xC431A214,sceNet_lib_C431A214 +#endif +#ifdef F_sceNet_lib_0005 + IMPORT_FUNC "sceNet_lib",0xBFCFEFF6,sceNet_lib_BFCFEFF6 +#endif +#ifdef F_sceNet_lib_0006 + IMPORT_FUNC "sceNet_lib",0xE1F4696F,sceNet_lib_E1F4696F +#endif +#ifdef F_sceNet_lib_0007 + IMPORT_FUNC "sceNet_lib",0x5216CBF5,sceNet_lib_5216CBF5 +#endif +#ifdef F_sceNet_lib_0008 + IMPORT_FUNC "sceNet_lib",0xD2422E4D,sceNet_lib_D2422E4D +#endif +#ifdef F_sceNet_lib_0009 + IMPORT_FUNC "sceNet_lib",0xD1BE2CE9,sceNet_lib_D1BE2CE9 +#endif +#ifdef F_sceNet_lib_0010 + IMPORT_FUNC "sceNet_lib",0xAB7DD9A5,sceNet_lib_AB7DD9A5 +#endif +#ifdef F_sceNet_lib_0011 + IMPORT_FUNC "sceNet_lib",0x80E1933E,sceNet_lib_80E1933E +#endif +#ifdef F_sceNet_lib_0012 + IMPORT_FUNC "sceNet_lib",0x7BA3ED91,sceNet_lib_7BA3ED91 +#endif +#ifdef F_sceNet_lib_0013 + IMPORT_FUNC "sceNet_lib",0x03164B12,sceNet_lib_03164B12 +#endif +#ifdef F_sceNet_lib_0014 + IMPORT_FUNC "sceNet_lib",0x389728AB,sceNet_lib_389728AB +#endif +#ifdef F_sceNet_lib_0015 + IMPORT_FUNC "sceNet_lib",0x4BF9E1DE,sceNet_lib_4BF9E1DE +#endif +#ifdef F_sceNet_lib_0016 + IMPORT_FUNC "sceNet_lib",0xD5B64E37,sceNet_lib_D5B64E37 +#endif +#ifdef F_sceNet_lib_0017 + IMPORT_FUNC "sceNet_lib",0xDA02F383,sceNet_lib_DA02F383 +#endif +#ifdef F_sceNet_lib_0018 + IMPORT_FUNC "sceNet_lib",0xAFA11338,sceNet_lib_AFA11338 +#endif +#ifdef F_sceNet_lib_0019 + IMPORT_FUNC "sceNet_lib",0xB20F84F8,sceNet_lib_B20F84F8 +#endif +#ifdef F_sceNet_lib_0020 + IMPORT_FUNC "sceNet_lib",0x83FE280A,sceNet_lib_83FE280A +#endif +#ifdef F_sceNet_lib_0021 + IMPORT_FUNC "sceNet_lib",0x4F8F3808,sceNet_lib_4F8F3808 +#endif +#ifdef F_sceNet_lib_0022 + IMPORT_FUNC "sceNet_lib",0x891723D5,sceNet_lib_891723D5 +#endif +#ifdef F_sceNet_lib_0023 + IMPORT_FUNC "sceNet_lib",0x0DFF67F9,sceNet_lib_0DFF67F9 +#endif +#ifdef F_sceNet_lib_0024 + IMPORT_FUNC "sceNet_lib",0xF355C73B,sceNet_lib_F355C73B +#endif +#ifdef F_sceNet_lib_0025 + IMPORT_FUNC "sceNet_lib",0xA55C914F,sceNet_lib_A55C914F +#endif +#ifdef F_sceNet_lib_0026 + IMPORT_FUNC "sceNet_lib",0x0D633F53,sceNet_lib_0D633F53 +#endif +#ifdef F_sceNet_lib_0027 + IMPORT_FUNC "sceNet_lib",0x8D33C11D,sceNetConfigGetEtherAddr +#endif +#ifdef F_sceNet_lib_0028 + IMPORT_FUNC "sceNet_lib",0x522A971B,sceNet_lib_522A971B +#endif +#ifdef F_sceNet_lib_0029 + IMPORT_FUNC "sceNet_lib",0x1858883D,sceNetRand +#endif +#ifdef F_sceNet_lib_0030 + IMPORT_FUNC "sceNet_lib",0x75D9985C,sceNet_lib_75D9985C +#endif +#ifdef F_sceNet_lib_0031 + IMPORT_FUNC "sceNet_lib",0x25CC373A,sceNet_lib_25CC373A +#endif +#ifdef F_sceNet_lib_0032 + IMPORT_FUNC "sceNet_lib",0xDCBC596E,sceNet_lib_DCBC596E +#endif +#ifdef F_sceNet_lib_0033 + IMPORT_FUNC "sceNet_lib",0x7C86FBA4,sceNet_lib_7C86FBA4 +#endif +#ifdef F_sceNet_lib_0034 + IMPORT_FUNC "sceNet_lib",0xA8B6205A,sceNet_lib_A8B6205A +#endif +#ifdef F_sceNet_lib_0035 + IMPORT_FUNC "sceNet_lib",0xA93A93E9,sceNet_lib_A93A93E9 +#endif +#ifdef F_sceNet_lib_0036 + IMPORT_FUNC "sceNet_lib",0x6B294EE4,sceNet_lib_6B294EE4 +#endif +#ifdef F_sceNet_lib_0037 + IMPORT_FUNC "sceNet_lib",0x51C209B2,sceNet_lib_51C209B2 +#endif +#ifdef F_sceNet_lib_0038 + IMPORT_FUNC "sceNet_lib",0xC9C97945,sceNet_lib_C9C97945 +#endif +#ifdef F_sceNet_lib_0039 + IMPORT_FUNC "sceNet_lib",0xB8C4A858,sceNet_lib_B8C4A858 +#endif +#ifdef F_sceNet_lib_0040 + IMPORT_FUNC "sceNet_lib",0x205E8D17,sceNet_lib_205E8D17 +#endif +#ifdef F_sceNet_lib_0041 + IMPORT_FUNC "sceNet_lib",0xF6DB0A0B,sceNet_lib_F6DB0A0B +#endif +#ifdef F_sceNet_lib_0042 + IMPORT_FUNC "sceNet_lib",0x7574FDA1,sceNet_lib_7574FDA1 +#endif +#ifdef F_sceNet_lib_0043 + IMPORT_FUNC "sceNet_lib",0xCA3CF5EB,sceNet_lib_CA3CF5EB +#endif +#ifdef F_sceNet_lib_0044 + IMPORT_FUNC "sceNet_lib",0x757085B0,sceNet_lib_757085B0 +#endif +#ifdef F_sceNet_lib_0045 + IMPORT_FUNC "sceNet_lib",0x435843CB,sceNet_lib_435843CB +#endif +#ifdef F_sceNet_lib_0046 + IMPORT_FUNC "sceNet_lib",0xD861EF33,sceNet_lib_D861EF33 +#endif +#ifdef F_sceNet_lib_0047 + IMPORT_FUNC "sceNet_lib",0xBB2B3DDB,sceNet_lib_BB2B3DDB +#endif +#ifdef F_sceNet_lib_0048 + IMPORT_FUNC "sceNet_lib",0x6D5D42D7,sceNet_lib_6D5D42D7 +#endif +#ifdef F_sceNet_lib_0049 + IMPORT_FUNC "sceNet_lib",0xC21E18B2,sceNet_lib_C21E18B2 +#endif +#ifdef F_sceNet_lib_0050 + IMPORT_FUNC "sceNet_lib",0x45452B7B,sceNet_lib_45452B7B +#endif +#ifdef F_sceNet_lib_0051 + IMPORT_FUNC "sceNet_lib",0x94B44F26,sceNet_lib_94B44F26 +#endif +#ifdef F_sceNet_lib_0052 + IMPORT_FUNC "sceNet_lib",0x515B2F33,sceNet_lib_515B2F33 +#endif +#ifdef F_sceNet_lib_0053 + IMPORT_FUNC "sceNet_lib",0x6DC71518,sceNet_lib_6DC71518 +#endif +#ifdef F_sceNet_lib_0054 + IMPORT_FUNC "sceNet_lib",0x7C3B86C5,sceNet_lib_7C3B86C5 +#endif +#ifdef F_sceNet_lib_0055 + IMPORT_FUNC "sceNet_lib",0x05D525E4,sceNet_lib_05D525E4 +#endif +#ifdef F_sceNet_lib_0056 + IMPORT_FUNC "sceNet_lib",0x1D10419C,sceNet_lib_1D10419C +#endif +#ifdef F_sceNet_lib_0057 + IMPORT_FUNC "sceNet_lib",0xC2EC2EEA,sceNet_lib_C2EC2EEA +#endif +#ifdef F_sceNet_lib_0058 + IMPORT_FUNC "sceNet_lib",0x710BD467,sceNet_lib_710BD467 +#endif +#ifdef F_sceNet_lib_0059 + IMPORT_FUNC "sceNet_lib",0x701DDDC3,sceNet_lib_701DDDC3 +#endif +#ifdef F_sceNet_lib_0060 + IMPORT_FUNC "sceNet_lib",0xD5A03BC0,sceNet_lib_D5A03BC0 +#endif +#ifdef F_sceNet_lib_0061 + IMPORT_FUNC "sceNet_lib",0xFA6DE6A6,sceNet_lib_FA6DE6A6 +#endif +#ifdef F_sceNet_lib_0062 + IMPORT_FUNC "sceNet_lib",0xEDB11CB4,sceNet_lib_EDB11CB4 +#endif +#ifdef F_sceNet_lib_0063 + IMPORT_FUNC "sceNet_lib",0x8C55B410,sceNet_lib_8C55B410 +#endif +#ifdef F_sceNet_lib_0064 + IMPORT_FUNC "sceNet_lib",0x13A8B98A,sceNet_lib_13A8B98A +#endif +#ifdef F_sceNet_lib_0065 + IMPORT_FUNC "sceNet_lib",0xEA42B353,sceNet_lib_EA42B353 +#endif +#ifdef F_sceNet_lib_0066 + IMPORT_FUNC "sceNet_lib",0x45945E8D,sceNet_lib_45945E8D +#endif +#ifdef F_sceNet_lib_0067 + IMPORT_FUNC "sceNet_lib",0xD60225A3,sceNet_lib_D60225A3 +#endif +#ifdef F_sceNet_lib_0068 + IMPORT_FUNC "sceNet_lib",0xEB6DE71A,sceNet_lib_EB6DE71A +#endif +#ifdef F_sceNet_lib_0069 + IMPORT_FUNC "sceNet_lib",0xEDCC871E,sceNet_lib_EDCC871E +#endif +#ifdef F_sceNet_lib_0070 + IMPORT_FUNC "sceNet_lib",0x4B2B3416,sceNet_lib_4B2B3416 +#endif +#ifdef F_sceNet_lib_0071 + IMPORT_FUNC "sceNet_lib",0x2B42872F,sceNet_lib_2B42872F +#endif +#ifdef F_sceNet_lib_0072 + IMPORT_FUNC "sceNet_lib",0xC4261339,sceNet_lib_C4261339 +#endif +#ifdef F_sceNet_lib_0073 + IMPORT_FUNC "sceNet_lib",0x41FD8B5C,sceNet_lib_41FD8B5C +#endif +#ifdef F_sceNet_lib_0074 + IMPORT_FUNC "sceNet_lib",0x92633D8D,sceNet_lib_92633D8D +#endif +#ifdef F_sceNet_lib_0075 + IMPORT_FUNC "sceNet_lib",0xB9C780C7,sceNet_lib_B9C780C7 +#endif +#ifdef F_sceNet_lib_0076 + IMPORT_FUNC "sceNet_lib",0xB68E1EEA,sceNet_lib_B68E1EEA +#endif +#ifdef F_sceNet_lib_0077 + IMPORT_FUNC "sceNet_lib",0xE155112D,sceNet_lib_E155112D +#endif +#ifdef F_sceNet_lib_0078 + IMPORT_FUNC "sceNet_lib",0x41621EB0,sceNet_lib_41621EB0 +#endif +#ifdef F_sceNet_lib_0079 + IMPORT_FUNC "sceNet_lib",0x2E005032,sceNet_lib_2E005032 +#endif +#ifdef F_sceNet_lib_0080 + IMPORT_FUNC "sceNet_lib",0x33B230BD,sceNet_lib_33B230BD +#endif +#ifdef F_sceNet_lib_0081 + IMPORT_FUNC "sceNet_lib",0x976AB1E9,sceNet_lib_976AB1E9 +#endif +#ifdef F_sceNet_lib_0082 + IMPORT_FUNC "sceNet_lib",0x4C8FD452,sceNet_lib_4C8FD452 +#endif +#ifdef F_sceNet_lib_0083 + IMPORT_FUNC "sceNet_lib",0x5ED457BE,sceNet_lib_5ED457BE +#endif +#ifdef F_sceNet_lib_0084 + IMPORT_FUNC "sceNet_lib",0x31F3CDA1,sceNet_lib_31F3CDA1 +#endif +#ifdef F_sceNet_lib_0085 + IMPORT_FUNC "sceNet_lib",0x1F94AFD9,sceNet_lib_1F94AFD9 +#endif +#ifdef F_sceNet_lib_0086 + IMPORT_FUNC "sceNet_lib",0x0A5A8751,sceNet_lib_0A5A8751 +#endif +#ifdef F_sceNet_lib_0087 + IMPORT_FUNC "sceNet_lib",0xB3A48B7F,sceNet_lib_B3A48B7F +#endif +#ifdef F_sceNet_lib_0088 + IMPORT_FUNC "sceNet_lib",0x949F1FBB,sceNet_lib_949F1FBB +#endif +#ifdef F_sceNet_lib_0089 + IMPORT_FUNC "sceNet_lib",0x13672F83,sceNet_lib_13672F83 +#endif +#ifdef F_sceNet_lib_0090 + IMPORT_FUNC "sceNet_lib",0x5C7C7381,sceNet_lib_5C7C7381 +#endif +#ifdef F_sceNet_lib_0091 + IMPORT_FUNC "sceNet_lib",0x86B6DCD9,sceNet_lib_86B6DCD9 +#endif +#ifdef F_sceNet_lib_0092 + IMPORT_FUNC "sceNet_lib",0x7AE91FB4,sceNet_lib_7AE91FB4 +#endif +#ifdef F_sceNet_lib_0093 + IMPORT_FUNC "sceNet_lib",0x572AD6ED,sceNet_lib_572AD6ED +#endif +#ifdef F_sceNet_lib_0094 + IMPORT_FUNC "sceNet_lib",0x87DC7A7E,sceNet_lib_87DC7A7E +#endif +#ifdef F_sceNet_lib_0095 + IMPORT_FUNC "sceNet_lib",0x991FF86D,sceNet_lib_991FF86D +#endif +#ifdef F_sceNet_lib_0096 + IMPORT_FUNC "sceNet_lib",0x5505D820,sceNet_lib_5505D820 +#endif diff --git a/src/net/sceSsl.S b/src/net/sceSsl.S new file mode 100644 index 00000000..2d3b8b40 --- /dev/null +++ b/src/net/sceSsl.S @@ -0,0 +1,43 @@ + .set noreorder + +#include "pspimport.s" + +// Build List +// sceSsl_0000.o sceSsl_0001.o sceSsl_0002.o sceSsl_0003.o sceSsl_0004.o sceSsl_0005.o sceSsl_0006.o sceSsl_0007.o sceSsl_0008.o sceSsl_0009.o sceSsl_0010.o sceSsl_0011.o + +#ifdef F_sceSsl_0000 + IMPORT_START "sceSsl",0x00090011 +#endif +#ifdef F_sceSsl_0001 + IMPORT_FUNC "sceSsl",0x058D21C0,sceSslGetNameEntryCount +#endif +#ifdef F_sceSsl_0002 + IMPORT_FUNC "sceSsl",0x0EB43B06,sceSslGetUsedMemoryCurrent +#endif +#ifdef F_sceSsl_0003 + IMPORT_FUNC "sceSsl",0x17A10DCC,sceSslGetNotBefore +#endif +#ifdef F_sceSsl_0004 + IMPORT_FUNC "sceSsl",0x191CDEFF,sceSslEnd +#endif +#ifdef F_sceSsl_0005 + IMPORT_FUNC "sceSsl",0x1B7C8191,sceSslGetIssuerName +#endif +#ifdef F_sceSsl_0006 + IMPORT_FUNC "sceSsl",0x3DD5E023,sceSslGetSubjectName +#endif +#ifdef F_sceSsl_0007 + IMPORT_FUNC "sceSsl",0x5BFB6B61,sceSslGetNotAfter +#endif +#ifdef F_sceSsl_0008 + IMPORT_FUNC "sceSsl",0x957ECBE2,sceSslInit +#endif +#ifdef F_sceSsl_0009 + IMPORT_FUNC "sceSsl",0xB99EDE6A,sceSslGetUsedMemoryMax +#endif +#ifdef F_sceSsl_0010 + IMPORT_FUNC "sceSsl",0xCC0919B0,sceSslGetSerialNumber +#endif +#ifdef F_sceSsl_0011 + IMPORT_FUNC "sceSsl",0xD6D097B4,sceSslGetNameEntryInfo +#endif diff --git a/src/openpsid/Makefile.am b/src/openpsid/Makefile.am new file mode 100644 index 00000000..1d04b34e --- /dev/null +++ b/src/openpsid/Makefile.am @@ -0,0 +1,23 @@ + +libdir = @PSPSDK_LIBDIR@ + +CC = @PSP_CC@ +CCAS = $(CC) +AR = @PSP_AR@ +RANLIB = @PSP_RANLIB@ + +INCLUDES = -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel +CFLAGS = @PSPSDK_CFLAGS@ +CCASFLAGS = $(CFLAGS) -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel + +OPENPSID_OBJS = sceOpenPSID_0000.o sceOpenPSID_0001.o + +libpspopenspidincludedir = @PSPSDK_INCLUDEDIR@ +libpspopenspidinclude_HEADERS = pspopenpsid.h + +lib_LIBRARIES = libpspopenpsid.a +libpspopenpsid_a_SOURCES = sceOpenPSID.S +libpspopenpsid_a_LIBADD = $(OPENPSID_OBJS) + +$(OPENPSID_OBJS): sceOpenPSID.S + $(COMPILE) -DF_$* $< -c -o $@ diff --git a/src/openpsid/pspopenpsid.h b/src/openpsid/pspopenpsid.h new file mode 100755 index 00000000..13ee1097 --- /dev/null +++ b/src/openpsid/pspopenpsid.h @@ -0,0 +1,30 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspopenpsid.h - Prototypes for the OpenPSID library + * + * Copyright (c) 2008 InsertWittyName (David Perry) + * + */ + +#ifndef __PSPOPENPSID_H__ +#define __PSPOPENPSID_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct PspOpenPSID +{ + unsigned char data[16]; +} PspOpenPSID; + +int sceOpenPSIDGetOpenPSID(PspOpenPSID *openpsid); + +#ifdef __cplusplus +} +#endif + +#endif /* __PSPOPENPSID_H__ */ diff --git a/src/openpsid/sceOpenPSID.S b/src/openpsid/sceOpenPSID.S new file mode 100644 index 00000000..cad008f0 --- /dev/null +++ b/src/openpsid/sceOpenPSID.S @@ -0,0 +1,13 @@ + .set noreorder + +#include "pspimport.s" + +// Build List +// sceOpenPSID_0000.o sceOpenPSID_0001.o + +#ifdef F_sceOpenPSID_0000 + IMPORT_START "sceOpenPSID",0x40010011 +#endif +#ifdef F_sceOpenPSID_0001 + IMPORT_FUNC "sceOpenPSID",0xC69BEBCE,sceOpenPSIDGetOpenPSID +#endif diff --git a/src/power/Makefile.am b/src/power/Makefile.am new file mode 100644 index 00000000..3ae6d579 --- /dev/null +++ b/src/power/Makefile.am @@ -0,0 +1,31 @@ + +libdir = @PSPSDK_LIBDIR@ + +CC = @PSP_CC@ +CCAS = $(CC) +AR = @PSP_AR@ +RANLIB = @PSP_RANLIB@ + +INCLUDES = -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel +CFLAGS = @PSPSDK_CFLAGS@ +CCASFLAGS = $(CFLAGS) -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel + +POWER_OBJS = scePower_0000.o scePower_0001.o scePower_0002.o scePower_0003.o scePower_0004.o scePower_0005.o scePower_0006.o scePower_0007.o scePower_0008.o scePower_0009.o scePower_0010.o scePower_0011.o scePower_0012.o scePower_0013.o scePower_0014.o scePower_0015.o scePower_0016.o scePower_0017.o scePower_0018.o scePower_0019.o scePower_0020.o scePower_0021.o scePower_0022.o scePower_0023.o scePower_0024.o scePower_0025.o scePower_0026.o scePower_0027.o scePower_0028.o scePower_0029.o scePower_0030.o scePower_0031.o scePower_0032.o scePower_0033.o scePower_0034.o scePower_0035.o scePower_0036.o scePower_0037.o scePower_0038.o scePower_0039.o scePower_0040.o scePower_0041.o scePower_0042.o scePower_0043.o scePower_0044.o scePower_0045.o scePower_0046.o + +POWERDRIVER_OBJS= scePower_driver_0000.o scePower_driver_0001.o scePower_driver_0002.o scePower_driver_0003.o scePower_driver_0004.o scePower_driver_0005.o scePower_driver_0006.o scePower_driver_0007.o scePower_driver_0008.o scePower_driver_0009.o scePower_driver_0010.o scePower_driver_0011.o scePower_driver_0012.o scePower_driver_0013.o scePower_driver_0014.o scePower_driver_0015.o scePower_driver_0016.o scePower_driver_0017.o scePower_driver_0018.o scePower_driver_0019.o scePower_driver_0020.o scePower_driver_0021.o scePower_driver_0022.o scePower_driver_0023.o scePower_driver_0024.o scePower_driver_0025.o scePower_driver_0026.o scePower_driver_0027.o scePower_driver_0028.o scePower_driver_0029.o scePower_driver_0030.o scePower_driver_0031.o scePower_driver_0032.o scePower_driver_0033.o scePower_driver_0034.o scePower_driver_0035.o scePower_driver_0036.o scePower_driver_0037.o scePower_driver_0038.o scePower_driver_0039.o scePower_driver_0040.o scePower_driver_0041.o scePower_driver_0042.o scePower_driver_0043.o scePower_driver_0044.o scePower_driver_0045.o scePower_driver_0046.o scePower_driver_0047.o scePower_driver_0048.o scePower_driver_0049.o scePower_driver_0050.o scePower_driver_0051.o scePower_driver_0052.o scePower_driver_0053.o scePower_driver_0054.o scePower_driver_0055.o scePower_driver_0056.o scePower_driver_0057.o scePower_driver_0058.o scePower_driver_0059.o scePower_driver_0060.o scePower_driver_0061.o scePower_driver_0062.o scePower_driver_0063.o scePower_driver_0064.o + +libpsppowerincludedir = @PSPSDK_INCLUDEDIR@ +libpsppowerinclude_HEADERS = psppower.h + +lib_LIBRARIES = libpsppower.a libpsppower_driver.a +libpsppower_a_SOURCES = scePower.S +libpsppower_a_LIBADD = $(POWER_OBJS) + +libpsppower_driver_a_SOURCES = scePower_driver.S +libpsppower_driver_a_LIBADD = $(POWERDRIVER_OBJS) + +$(POWER_OBJS): scePower.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(POWERDRIVER_OBJS): scePower_driver.S + $(COMPILE) -DF_$* $< -c -o $@ diff --git a/src/power/psppower.h b/src/power/psppower.h new file mode 100644 index 00000000..5fc8238a --- /dev/null +++ b/src/power/psppower.h @@ -0,0 +1,280 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * psppower.h - Prototypes for the scePower library. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * Copyright (c) 2005 David Perry + * + * $Id: psppower.h 2433 2008-10-15 10:00:27Z iwn $ + */ +#ifndef __POWER_H__ +#define __POWER_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Power callback flags + */ + /*indicates the power switch it pushed, putting the unit into suspend mode*/ +#define PSP_POWER_CB_POWER_SWITCH 0x80000000 +/*indicates the hold switch is on*/ +#define PSP_POWER_CB_HOLD_SWITCH 0x40000000 +/*what is standby mode?*/ +#define PSP_POWER_CB_STANDBY 0x00080000 +/*indicates the resume process has been completed (only seems to be triggered when another event happens)*/ +#define PSP_POWER_CB_RESUME_COMPLETE 0x00040000 +/*indicates the unit is resuming from suspend mode*/ +#define PSP_POWER_CB_RESUMING 0x00020000 +/*indicates the unit is suspending, seems to occur due to inactivity*/ +#define PSP_POWER_CB_SUSPENDING 0x00010000 +/*indicates the unit is plugged into an AC outlet*/ +#define PSP_POWER_CB_AC_POWER 0x00001000 +/*indicates the battery charge level is low*/ +#define PSP_POWER_CB_BATTERY_LOW 0x00000100 +/*indicates there is a battery present in the unit*/ +#define PSP_POWER_CB_BATTERY_EXIST 0x00000080 +/*unknown*/ +#define PSP_POWER_CB_BATTPOWER 0x0000007F + +/** + * Power tick flags + */ +/* All */ +#define PSP_POWER_TICK_ALL 0 +/* Suspend */ +#define PSP_POWER_TICK_SUSPEND 1 +/* Display */ +#define PSP_POWER_TICK_DISPLAY 6 + +/** + * Power Callback Function Definition + * + * @param unknown - unknown function, appears to cycle between 1,2 and 3 + * @param powerInfo - combination of PSP_POWER_CB_ flags + */ +typedef void (*powerCallback_t)(int unknown, int powerInfo); + +/** + * Register Power Callback Function + * + * @param slot - slot of the callback in the list, 0 to 15, pass -1 to get an auto assignment. + * @param cbid - callback id from calling sceKernelCreateCallback + * + * @return 0 on success, the slot number if -1 is passed, < 0 on error. + */ +int scePowerRegisterCallback(int slot, SceUID cbid); + +/** + * Unregister Power Callback Function + * + * @param slot - slot of the callback + * + * @return 0 on success, < 0 on error. + */ +int scePowerUnregisterCallback(int slot); + +/** + * Check if unit is plugged in + * + * @return 1 if plugged in, 0 if not plugged in, < 0 on error. + */ +int scePowerIsPowerOnline(void); + +/** + * Check if a battery is present + * + * @return 1 if battery present, 0 if battery not present, < 0 on error. + */ +int scePowerIsBatteryExist(void); + +/** + * Check if the battery is charging + * + * @return 1 if battery charging, 0 if battery not charging, < 0 on error. + */ +int scePowerIsBatteryCharging(void); + +/** + * Get the status of the battery charging + */ +int scePowerGetBatteryChargingStatus(void); + +/** + * Check if the battery is low + * + * @return 1 if the battery is low, 0 if the battery is not low, < 0 on error. + */ +int scePowerIsLowBattery(void); + +/** + * Get battery life as integer percent + * + * @return Battery charge percentage (0-100), < 0 on error. + */ +int scePowerGetBatteryLifePercent(void); + +/** + * Get battery life as time + * + * @return Battery life in minutes, < 0 on error. + */ +int scePowerGetBatteryLifeTime(void); + +/** + * Get temperature of the battery + */ +int scePowerGetBatteryTemp(void); + +/** + * unknown? - crashes PSP in usermode + */ +int scePowerGetBatteryElec(void); + +/** + * Get battery volt level + */ +int scePowerGetBatteryVolt(void); + +/** + * Set CPU Frequency + * @param cpufreq - new CPU frequency, valid values are 1 - 333 + */ +int scePowerSetCpuClockFrequency(int cpufreq); + +/** + * Set Bus Frequency + * @param busfreq - new BUS frequency, valid values are 1 - 167 + */ +int scePowerSetBusClockFrequency(int busfreq); + +/** + * Alias for scePowerGetCpuClockFrequencyInt + * @return frequency as int + */ +int scePowerGetCpuClockFrequency(void); + +/** + * Get CPU Frequency as Integer + * @return frequency as int + */ +int scePowerGetCpuClockFrequencyInt(void); + +/** + * Get CPU Frequency as Float + * @return frequency as float + */ +float scePowerGetCpuClockFrequencyFloat(void); + +/** + * Alias for scePowerGetBusClockFrequencyInt + * @return frequency as int + */ +int scePowerGetBusClockFrequency(void); + +/** + * Get Bus fequency as Integer + * @return frequency as int + */ +int scePowerGetBusClockFrequencyInt(void); + +/** + * Get Bus frequency as Float + * @return frequency as float + */ +float scePowerGetBusClockFrequencyFloat(void); + +/** + * Set Clock Frequencies + * + * @param pllfreq - pll frequency, valid from 19-333 + * @param cpufreq - cpu frequency, valid from 1-333 + * @param busfreq - bus frequency, valid from 1-167 + * + * and: + * + * cpufreq <= pllfreq + * busfreq*2 <= pllfreq + * + */ +int scePowerSetClockFrequency(int pllfreq, int cpufreq, int busfreq); + +/** + * Lock power switch + * + * Note: if the power switch is toggled while locked + * it will fire immediately after being unlocked. + * + * @param unknown - pass 0 + * + * @return 0 on success, < 0 on error. + */ +int scePowerLock(int unknown); + +/** + * Unlock power switch + * + * @param unknown - pass 0 + * + * @return 0 on success, < 0 on error. + */ +int scePowerUnlock(int unknown); + +/** + * Generate a power tick, preventing unit from + * powering off and turning off display. + * + * @param type - Either PSP_POWER_TICK_ALL, PSP_POWER_TICK_SUSPEND or PSP_POWER_TICK_DISPLAY + * + * @return 0 on success, < 0 on error. + */ +int scePowerTick(int type); + +/** + * Get Idle timer + * + */ +int scePowerGetIdleTimer(void); + +/** + * Enable Idle timer + * + * @param unknown - pass 0 + */ +int scePowerIdleTimerEnable(int unknown); + +/** + * Disable Idle timer + * + * @param unknown - pass 0 + */ +int scePowerIdleTimerDisable(int unknown); + +/** + * Request the PSP to go into standby + * + * @return 0 always + */ +int scePowerRequestStandby(void); + +/** + * Request the PSP to go into suspend + * + * @return 0 always + */ +int scePowerRequestSuspend(void); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/power/scePower.S b/src/power/scePower.S new file mode 100644 index 00000000..8f44acfb --- /dev/null +++ b/src/power/scePower.S @@ -0,0 +1,145 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_scePower_0000 + IMPORT_START "scePower",0x40010000 +#endif +#ifdef F_scePower_0001 + IMPORT_FUNC "scePower",0x2B51FE2F,scePower_2B51FE2F +#endif +#ifdef F_scePower_0002 + IMPORT_FUNC "scePower",0x442BFBAC,scePower_442BFBAC +#endif +#ifdef F_scePower_0003 + IMPORT_FUNC "scePower",0xEFD3C963,scePowerTick +#endif +#ifdef F_scePower_0004 + IMPORT_FUNC "scePower",0xEDC13FE5,scePowerGetIdleTimer +#endif +#ifdef F_scePower_0005 + IMPORT_FUNC "scePower",0x7F30B3B1,scePowerIdleTimerEnable +#endif +#ifdef F_scePower_0006 + IMPORT_FUNC "scePower",0x972CE941,scePowerIdleTimerDisable +#endif +#ifdef F_scePower_0007 + IMPORT_FUNC "scePower",0x27F3292C,scePowerBatteryUpdateInfo +#endif +#ifdef F_scePower_0008 + IMPORT_FUNC "scePower",0xE8E4E204,scePower_E8E4E204 +#endif +#ifdef F_scePower_0009 + IMPORT_FUNC "scePower",0xB999184C,scePowerGetLowBatteryCapacity +#endif +#ifdef F_scePower_0010 + IMPORT_FUNC "scePower",0x87440F5E,scePowerIsPowerOnline +#endif +#ifdef F_scePower_0011 + IMPORT_FUNC "scePower",0x0AFD0D8B,scePowerIsBatteryExist +#endif +#ifdef F_scePower_0012 + IMPORT_FUNC "scePower",0x1E490401,scePowerIsBatteryCharging +#endif +#ifdef F_scePower_0013 + IMPORT_FUNC "scePower",0xB4432BC8,scePowerGetBatteryChargingStatus +#endif +#ifdef F_scePower_0014 + IMPORT_FUNC "scePower",0xD3075926,scePowerIsLowBattery +#endif +#ifdef F_scePower_0015 + IMPORT_FUNC "scePower",0x78A1A796,scePower_78A1A796 +#endif +#ifdef F_scePower_0016 + IMPORT_FUNC "scePower",0x94F5A53F,scePowerGetBatteryRemainCapacity +#endif +#ifdef F_scePower_0017 + IMPORT_FUNC "scePower",0xFD18A0FF,scePower_FD18A0FF +#endif +#ifdef F_scePower_0018 + IMPORT_FUNC "scePower",0x2085D15D,scePowerGetBatteryLifePercent +#endif +#ifdef F_scePower_0019 + IMPORT_FUNC "scePower",0x8EFB3FA2,scePowerGetBatteryLifeTime +#endif +#ifdef F_scePower_0020 + IMPORT_FUNC "scePower",0x28E12023,scePowerGetBatteryTemp +#endif +#ifdef F_scePower_0021 + IMPORT_FUNC "scePower",0x862AE1A6,scePowerGetBatteryElec +#endif +#ifdef F_scePower_0022 + IMPORT_FUNC "scePower",0x483CE86B,scePowerGetBatteryVolt +#endif +#ifdef F_scePower_0023 + IMPORT_FUNC "scePower",0x23436A4A,scePower_23436A4A +#endif +#ifdef F_scePower_0024 + IMPORT_FUNC "scePower",0x0CD21B1F,scePower_0CD21B1F +#endif +#ifdef F_scePower_0025 + IMPORT_FUNC "scePower",0x165CE085,scePower_165CE085 +#endif +#ifdef F_scePower_0026 + IMPORT_FUNC "scePower",0xD6D016EF,scePowerLock +#endif +#ifdef F_scePower_0027 + IMPORT_FUNC "scePower",0xCA3D34C1,scePowerUnlock +#endif +#ifdef F_scePower_0028 + IMPORT_FUNC "scePower",0xDB62C9CF,scePowerCancelRequest +#endif +#ifdef F_scePower_0029 + IMPORT_FUNC "scePower",0x7FA406DD,scePowerIsRequest +#endif +#ifdef F_scePower_0030 + IMPORT_FUNC "scePower",0x2B7C7CF4,scePowerRequestStandby +#endif +#ifdef F_scePower_0031 + IMPORT_FUNC "scePower",0xAC32C9CC,scePowerRequestSuspend +#endif +#ifdef F_scePower_0032 + IMPORT_FUNC "scePower",0x2875994B,scePower_2875994B +#endif +#ifdef F_scePower_0033 + IMPORT_FUNC "scePower",0x3951AF53,scePowerEncodeUBattery +#endif +#ifdef F_scePower_0034 + IMPORT_FUNC "scePower",0x0074EF9B,scePowerGetResumeCount +#endif +#ifdef F_scePower_0035 + IMPORT_FUNC "scePower",0x04B7766E,scePowerRegisterCallback +#endif +#ifdef F_scePower_0036 + IMPORT_FUNC "scePower",0xDFA8BAF8,scePowerUnregisterCallback +#endif +#ifdef F_scePower_0037 + IMPORT_FUNC "scePower",0xDB9D28DD,scePowerUnregitserCallback +#endif +#ifdef F_scePower_0038 + IMPORT_FUNC "scePower",0x843FBF43,scePowerSetCpuClockFrequency +#endif +#ifdef F_scePower_0039 + IMPORT_FUNC "scePower",0xB8D7B3FB,scePowerSetBusClockFrequency +#endif +#ifdef F_scePower_0040 + IMPORT_FUNC "scePower",0xFEE03A2F,scePowerGetCpuClockFrequency +#endif +#ifdef F_scePower_0041 + IMPORT_FUNC "scePower",0x478FE6F5,scePowerGetBusClockFrequency +#endif +#ifdef F_scePower_0042 + IMPORT_FUNC "scePower",0xFDB5BFE9,scePowerGetCpuClockFrequencyInt +#endif +#ifdef F_scePower_0043 + IMPORT_FUNC "scePower",0xBD681969,scePowerGetBusClockFrequencyInt +#endif +#ifdef F_scePower_0044 + IMPORT_FUNC "scePower",0xB1A52C83,scePowerGetCpuClockFrequencyFloat +#endif +#ifdef F_scePower_0045 + IMPORT_FUNC "scePower",0x9BADB3EB,scePowerGetBusClockFrequencyFloat +#endif +#ifdef F_scePower_0046 + IMPORT_FUNC "scePower",0x737486F2,scePowerSetClockFrequency +#endif diff --git a/src/power/scePower_driver.S b/src/power/scePower_driver.S new file mode 100644 index 00000000..c37784a8 --- /dev/null +++ b/src/power/scePower_driver.S @@ -0,0 +1,199 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_scePower_driver_0000 + IMPORT_START "scePower_driver",0x00010000 +#endif +#ifdef F_scePower_driver_0001 + IMPORT_FUNC "scePower_driver",0x9CE06934,scePowerInit +#endif +#ifdef F_scePower_driver_0002 + IMPORT_FUNC "scePower_driver",0xAD5BB433,scePowerEnd +#endif +#ifdef F_scePower_driver_0003 + IMPORT_FUNC "scePower_driver",0x6D2CA84B,scePowerWlanActivate +#endif +#ifdef F_scePower_driver_0004 + IMPORT_FUNC "scePower_driver",0x23BB0A60,scePowerWlanDeactivate +#endif +#ifdef F_scePower_driver_0005 + IMPORT_FUNC "scePower_driver",0x2B51FE2F,scePower_driver_2B51FE2F +#endif +#ifdef F_scePower_driver_0006 + IMPORT_FUNC "scePower_driver",0x442BFBAC,scePower_driver_442BFBAC +#endif +#ifdef F_scePower_driver_0007 + IMPORT_FUNC "scePower_driver",0xE8685403,scePower_driver_E8685403 +#endif +#ifdef F_scePower_driver_0008 + IMPORT_FUNC "scePower_driver",0xEFD3C963,scePowerTick +#endif +#ifdef F_scePower_driver_0009 + IMPORT_FUNC "scePower_driver",0xEDC13FE5,scePowerGetIdleTimer +#endif +#ifdef F_scePower_driver_0010 + IMPORT_FUNC "scePower_driver",0x1BA2FCAE,scePowerSetIdleCallback +#endif +#ifdef F_scePower_driver_0011 + IMPORT_FUNC "scePower_driver",0x7F30B3B1,scePowerIdleTimerEnable +#endif +#ifdef F_scePower_driver_0012 + IMPORT_FUNC "scePower_driver",0x972CE941,scePowerIdleTimerDisable +#endif +#ifdef F_scePower_driver_0013 + IMPORT_FUNC "scePower_driver",0x27F3292C,scePowerBatteryUpdateInfo +#endif +#ifdef F_scePower_driver_0014 + IMPORT_FUNC "scePower_driver",0xE8E4E204,scePower_driver_E8E4E204 +#endif +#ifdef F_scePower_driver_0015 + IMPORT_FUNC "scePower_driver",0xB999184C,scePowerGetLowBatteryCapacity +#endif +#ifdef F_scePower_driver_0016 + IMPORT_FUNC "scePower_driver",0x166922EC,scePower_driver_166922EC +#endif +#ifdef F_scePower_driver_0017 + IMPORT_FUNC "scePower_driver",0xDD3D4DAC,scePower_driver_DD3D4DAC +#endif +#ifdef F_scePower_driver_0018 + IMPORT_FUNC "scePower_driver",0x87440F5E,scePowerIsPowerOnline +#endif +#ifdef F_scePower_driver_0019 + IMPORT_FUNC "scePower_driver",0x0AFD0D8B,scePowerIsBatteryExist +#endif +#ifdef F_scePower_driver_0020 + IMPORT_FUNC "scePower_driver",0x1E490401,scePowerIsBatteryCharging +#endif +#ifdef F_scePower_driver_0021 + IMPORT_FUNC "scePower_driver",0xB4432BC8,scePowerGetBatteryChargingStatus +#endif +#ifdef F_scePower_driver_0022 + IMPORT_FUNC "scePower_driver",0xD3075926,scePowerIsLowBattery +#endif +#ifdef F_scePower_driver_0023 + IMPORT_FUNC "scePower_driver",0x78A1A796,scePower_driver_78A1A796 +#endif +#ifdef F_scePower_driver_0024 + IMPORT_FUNC "scePower_driver",0x94F5A53F,scePowerGetBatteryRemainCapacity +#endif +#ifdef F_scePower_driver_0025 + IMPORT_FUNC "scePower_driver",0xFD18A0FF,scePower_driver_FD18A0FF +#endif +#ifdef F_scePower_driver_0026 + IMPORT_FUNC "scePower_driver",0x2085D15D,scePowerGetBatteryLifePercent +#endif +#ifdef F_scePower_driver_0027 + IMPORT_FUNC "scePower_driver",0x8EFB3FA2,scePowerGetBatteryLifeTime +#endif +#ifdef F_scePower_driver_0028 + IMPORT_FUNC "scePower_driver",0x28E12023,scePowerGetBatteryTemp +#endif +#ifdef F_scePower_driver_0029 + IMPORT_FUNC "scePower_driver",0x862AE1A6,scePowerGetBatteryElec +#endif +#ifdef F_scePower_driver_0030 + IMPORT_FUNC "scePower_driver",0x483CE86B,scePowerGetBatteryVolt +#endif +#ifdef F_scePower_driver_0031 + IMPORT_FUNC "scePower_driver",0x23436A4A,scePower_driver_23436A4A +#endif +#ifdef F_scePower_driver_0032 + IMPORT_FUNC "scePower_driver",0x0CD21B1F,scePower_driver_0CD21B1F +#endif +#ifdef F_scePower_driver_0033 + IMPORT_FUNC "scePower_driver",0x165CE085,scePower_driver_165CE085 +#endif +#ifdef F_scePower_driver_0034 + IMPORT_FUNC "scePower_driver",0xD6D016EF,scePowerLock +#endif +#ifdef F_scePower_driver_0035 + IMPORT_FUNC "scePower_driver",0xCA3D34C1,scePowerUnlock +#endif +#ifdef F_scePower_driver_0036 + IMPORT_FUNC "scePower_driver",0x79DB9421,scePowerRebootStart +#endif +#ifdef F_scePower_driver_0037 + IMPORT_FUNC "scePower_driver",0xDB62C9CF,scePowerCancelRequest +#endif +#ifdef F_scePower_driver_0038 + IMPORT_FUNC "scePower_driver",0x7FA406DD,scePowerIsRequest +#endif +#ifdef F_scePower_driver_0039 + IMPORT_FUNC "scePower_driver",0x2B7C7CF4,scePowerRequestStandby +#endif +#ifdef F_scePower_driver_0040 + IMPORT_FUNC "scePower_driver",0xAC32C9CC,scePowerRequestSuspend +#endif +#ifdef F_scePower_driver_0041 + IMPORT_FUNC "scePower_driver",0x2875994B,scePower_driver_2875994B +#endif +#ifdef F_scePower_driver_0042 + IMPORT_FUNC "scePower_driver",0x3951AF53,scePowerEncodeUBattery +#endif +#ifdef F_scePower_driver_0043 + IMPORT_FUNC "scePower_driver",0x0074EF9B,scePowerGetResumeCount +#endif +#ifdef F_scePower_driver_0044 + IMPORT_FUNC "scePower_driver",0xF535D928,scePower_driver_F535D928 +#endif +#ifdef F_scePower_driver_0045 + IMPORT_FUNC "scePower_driver",0x04B7766E,scePowerRegisterCallback +#endif +#ifdef F_scePower_driver_0046 + IMPORT_FUNC "scePower_driver",0xDFA8BAF8,scePowerUnregisterCallback +#endif +#ifdef F_scePower_driver_0047 + IMPORT_FUNC "scePower_driver",0xDB9D28DD,scePowerUnregitserCallback +#endif +#ifdef F_scePower_driver_0048 + IMPORT_FUNC "scePower_driver",0xD24E6BEB,scePower_driver_D24E6BEB +#endif +#ifdef F_scePower_driver_0049 + IMPORT_FUNC "scePower_driver",0x35B7662E,scePowerGetSectionDescriptionEntry +#endif +#ifdef F_scePower_driver_0050 + IMPORT_FUNC "scePower_driver",0xF9B4DEA1,scePowerLimitPllClock +#endif +#ifdef F_scePower_driver_0051 + IMPORT_FUNC "scePower_driver",0x843FBF43,scePowerSetCpuClockFrequency +#endif +#ifdef F_scePower_driver_0052 + IMPORT_FUNC "scePower_driver",0xB8D7B3FB,scePowerSetBusClockFrequency +#endif +#ifdef F_scePower_driver_0053 + IMPORT_FUNC "scePower_driver",0xFEE03A2F,scePowerGetCpuClockFrequency +#endif +#ifdef F_scePower_driver_0054 + IMPORT_FUNC "scePower_driver",0x478FE6F5,scePowerGetBusClockFrequency +#endif +#ifdef F_scePower_driver_0055 + IMPORT_FUNC "scePower_driver",0xFDB5BFE9,scePowerGetCpuClockFrequencyInt +#endif +#ifdef F_scePower_driver_0056 + IMPORT_FUNC "scePower_driver",0xBD681969,scePowerGetBusClockFrequencyInt +#endif +#ifdef F_scePower_driver_0057 + IMPORT_FUNC "scePower_driver",0xB1A52C83,scePowerGetCpuClockFrequencyFloat +#endif +#ifdef F_scePower_driver_0058 + IMPORT_FUNC "scePower_driver",0x9BADB3EB,scePowerGetBusClockFrequencyFloat +#endif +#ifdef F_scePower_driver_0059 + IMPORT_FUNC "scePower_driver",0x737486F2,scePowerSetClockFrequency +#endif +#ifdef F_scePower_driver_0060 + IMPORT_FUNC "scePower_driver",0xE0B7A95D,scePower_driver_E0B7A95D +#endif +#ifdef F_scePower_driver_0061 + IMPORT_FUNC "scePower_driver",0xC23AC778,scePower_driver_C23AC778 +#endif +#ifdef F_scePower_driver_0062 + IMPORT_FUNC "scePower_driver",0x23C31FFE,scePowerVolatileMemLock +#endif +#ifdef F_scePower_driver_0063 + IMPORT_FUNC "scePower_driver",0xFA97A599,scePowerVolatileMemTryLock +#endif +#ifdef F_scePower_driver_0064 + IMPORT_FUNC "scePower_driver",0xB3EDD801,scePowerVolatileMemUnlock +#endif diff --git a/src/prof/Makefile.am b/src/prof/Makefile.am new file mode 100644 index 00000000..8594fb76 --- /dev/null +++ b/src/prof/Makefile.am @@ -0,0 +1,18 @@ + +libdir = @PSPSDK_LIBDIR@ + +CC = @PSP_CC@ +CCAS = $(CC) +AR = @PSP_AR@ +RANLIB = @PSP_RANLIB@ + +INCLUDES = -I$(top_srcdir)/src/base -I$(top_srcdir)/src/debug -I$(top_srcdir)/src/user +CFLAGS = @PSPSDK_CFLAGS@ -std=gnu99 -Wall -Wmissing-prototypes +CCASFLAGS = $(CFLAGS) -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel + +libpspprofincludedir = @PSPSDK_INCLUDEDIR@ +libpspprofinclude_HEADERS = pspprof.h + +lib_LIBRARIES = libpspprof.a +libpspprof_a_SOURCES = prof.c mcount.s +libpspprof_a_LIBADD = diff --git a/src/prof/mcount.s b/src/prof/mcount.s new file mode 100644 index 00000000..3cb207d3 --- /dev/null +++ b/src/prof/mcount.s @@ -0,0 +1,61 @@ + .set noreorder + .set noat + + .global _mcount + .ent _mcount + +_mcount: + + +# Generated code already substracts 8 bytes +# We store our ra, at and a0-a3 + addu $29, $29, -40 + sd $31, 0($29) # store ra + sd $1, 8($29) # at = ra of caller + sd $4, 16($29) + sd $5, 24($29) + sd $6, 32($29) + sd $7, 40($29) + +# Make sure we're not recursively called when compiling __mcount() +# With -pg + la $4, _busy + lw $5, 0($4) + bnez $5, done + nop + +# Mark busy + li $5, 1 + sw $5, 0($4) + +# Call internal C handler + move $4, $1 + move $5, $31 + jal __mcount + nop + +# Unmark busy + la $4, _busy + li $5, 0 + sw $5, 0($4) + + done: + +# Restore registers + ld $31, 0($29) + ld $1, 8($29) + ld $4, 16($29) + ld $5, 24($29) + ld $6, 32($29) + ld $7, 40($29) + addu $29, $29, 48 # generated code substracts 8 bytes + j $31 + move $31, $1 # restore caller's ra + +_busy: + .space 4 + + .end _mcount + + .set reorder + .set at diff --git a/src/prof/prof.c b/src/prof/prof.c new file mode 100644 index 00000000..7aafaebb --- /dev/null +++ b/src/prof/prof.c @@ -0,0 +1,256 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * prof.c - Main profiler code + * + * Copyright (c) 2005 urchin + * + * $Id$ + */ +#include +#include +#include +#include + +#define GMON_PROF_ON 0 +#define GMON_PROF_BUSY 1 +#define GMON_PROF_ERROR 2 +#define GMON_PROF_OFF 3 + +#define GMONVERSION 0x00051879 + +#include + +/** gmon.out file header */ +struct gmonhdr +{ + int lpc; /* lowest pc address */ + int hpc; /* highest pc address */ + int ncnt; /* size of samples + size of header */ + int version; /* version number */ + int profrate; /* profiling clock rate */ + int resv[3]; /* reserved */ +}; + +/** frompc -> selfpc graph */ +struct rawarc +{ + unsigned int frompc; + unsigned int selfpc; + unsigned int count; +}; + +/** context */ +struct gmonparam +{ + int state; + unsigned int lowpc; + unsigned int highpc; + unsigned int textsize; + unsigned int hashfraction; + + int narcs; + struct rawarc *arcs; + + int nsamples; + unsigned int *samples; + + int timer; + + unsigned int pc; +}; + +/// holds context statistics +static struct gmonparam gp; + +/// one histogram per four bytes of text space +#define HISTFRACTION 4 + +/// define sample frequency - 1000 hz = 1ms +#define SAMPLE_FREQ 1000 + +/// have we allocated memory and registered already +static int initialized = 0; + +/// defined by linker +extern int _ftext; +extern int _etext; + +/* forward declarations */ +void gprof_cleanup(void); +void __mcount(unsigned int, unsigned int); +static SceUInt timer_handler(SceUID uid, SceKernelSysClock *c1, SceKernelSysClock *c2, void *common); + +/** Initializes pg library + + After calculating the text size, initialize() allocates enough + memory to allow fastest access to arc structures, and some more + for sampling statistics. Note that this also installs a timer that + runs at 1000 hert. +*/ +static void initialize() +{ + initialized = 1; + + memset(&gp, '\0', sizeof(gp)); + gp.state = GMON_PROF_ON; + gp.lowpc = (unsigned int)&_ftext; + gp.highpc = (unsigned int)&_etext; + gp.textsize = gp.highpc - gp.lowpc; + gp.hashfraction = HISTFRACTION; + + gp.narcs = (gp.textsize + gp.hashfraction - 1) / gp.hashfraction; + gp.arcs = (struct rawarc *)malloc(sizeof(struct rawarc) * gp.narcs); + if (gp.arcs == NULL) + { + gp.state = GMON_PROF_ERROR; + return; + } + + gp.nsamples = (gp.textsize + gp.hashfraction - 1) / gp.hashfraction; + gp.samples = (unsigned int *)malloc(sizeof(unsigned int) * gp.nsamples); + if (gp.samples == NULL) + { + free(gp.arcs); + gp.arcs = 0; + gp.state = GMON_PROF_ERROR; + return; + } + + memset((void *)gp.arcs, '\0', gp.narcs * (sizeof(struct rawarc))); + memset((void *)gp.samples, '\0', gp.nsamples * (sizeof(unsigned int ))); + + gp.timer = sceKernelCreateVTimer("gprof timer", NULL); + + SceKernelSysClock sc; + sc.hi = 0; + sc.low = SAMPLE_FREQ; + + int thid = sceKernelGetThreadId(); + + SceKernelThreadInfo info; + info.size = sizeof(info); + int ret = sceKernelReferThreadStatus(thid, &info); + + if(ret == 0) + { + void* timer_addr = timer_handler; + if((info.attr & PSP_THREAD_ATTR_USER) == 0) + { + timer_addr += 0x80000000; + } + + ret = sceKernelSetVTimerHandler(gp.timer, &sc, timer_addr, NULL); + } + + if(ret == 0) + { + sceKernelStartVTimer(gp.timer); + } +} + +/** Writes gmon.out dump file and stops profiling + + Called from atexit() handler; will dump out a host:gmon.out file + with all collected information. +*/ +void gprof_cleanup() +{ + FILE *fp; + int i; + struct gmonhdr hdr; + + if (gp.state != GMON_PROF_ON) + { + /* profiling was disabled anyway */ + return; + } + + /* disable profiling before we make plenty of libc calls */ + gp.state = GMON_PROF_OFF; + + sceKernelStopVTimer(gp.timer); + + fp = fopen("gmon.out", "wb"); + hdr.lpc = gp.lowpc; + hdr.hpc = gp.highpc; + hdr.ncnt = sizeof(hdr) + (sizeof(unsigned int) * gp.nsamples); + hdr.version = GMONVERSION; + hdr.profrate = SAMPLE_FREQ; + hdr.resv[0] = 0; + hdr.resv[1] = 0; + hdr.resv[2] = 0; + fwrite(&hdr, 1, sizeof(hdr), fp); + fwrite(gp.samples, gp.nsamples, sizeof(unsigned int), fp); + + for (i=0; i 0) + { + fwrite(gp.arcs + i, sizeof(struct rawarc), 1, fp); + } + } + + fclose(fp); +} + +/** Internal C handler for _mcount() + @param frompc pc address of caller + @param selfpc pc address of current function + + Called from mcount.S to make life a bit easier. __mcount is called + right before a function starts. GCC generates a tiny stub at the very + beginning of each compiled routine, which eventually brings the + control to here. +*/ +void __mcount(unsigned int frompc, unsigned int selfpc) +{ + int e; + struct rawarc *arc; + + if (initialized == 0) + { + initialize(); + } + + if (gp.state != GMON_PROF_ON) + { + /* returned off for some reason */ + return; + } + + frompc = frompc & 0x0FFFFFFF; + selfpc = selfpc & 0x0FFFFFFF; + + /* call might come from stack */ + if (frompc >= gp.lowpc && frompc <= gp.highpc) + { + gp.pc = selfpc; + e = (frompc - gp.lowpc) / gp.hashfraction; + arc = gp.arcs + e; + arc->frompc = frompc; + arc->selfpc = selfpc; + arc->count++; + } +} + +/** Internal timer handler +*/ +static SceUInt timer_handler(SceUID uid, SceKernelSysClock *requested, SceKernelSysClock *actual, void *common) +{ + unsigned int frompc = gp.pc; + + if (gp.state == GMON_PROF_ON) + { + /* call might come from stack */ + if (frompc >= gp.lowpc && frompc <= gp.highpc) + { + int e = (frompc - gp.lowpc) / gp.hashfraction; + gp.samples[e]++; + } + } + + return SAMPLE_FREQ; +} diff --git a/src/prof/pspprof.h b/src/prof/pspprof.h new file mode 100644 index 00000000..e065627a --- /dev/null +++ b/src/prof/pspprof.h @@ -0,0 +1,25 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspprof.h - Prototypes for the profiler library + * + * Copyright (c) 2006 Urchin + * + * $Id$ + */ +#ifndef __PSPPROF_H__ +#define __PSPPROF_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +void gprof_cleanup(); + +#ifdef __cplusplus +} +#endif + +#endif /* __PSPPROF_H__ */ diff --git a/src/registry/Makefile.am b/src/registry/Makefile.am new file mode 100644 index 00000000..b79e4048 --- /dev/null +++ b/src/registry/Makefile.am @@ -0,0 +1,32 @@ + +libdir = @PSPSDK_LIBDIR@ + +CC = @PSP_CC@ +CCAS = $(CC) +AR = @PSP_AR@ +RANLIB = @PSP_RANLIB@ + +INCLUDES = -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel +CFLAGS = @PSPSDK_CFLAGS@ +CCASFLAGS = $(CFLAGS) -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel + +REG_OBJS = sceReg_0000.o sceReg_0001.o sceReg_0002.o sceReg_0003.o sceReg_0004.o sceReg_0005.o sceReg_0006.o sceReg_0007.o sceReg_0008.o sceReg_0009.o sceReg_0010.o sceReg_0011.o sceReg_0012.o sceReg_0013.o sceReg_0014.o sceReg_0015.o sceReg_0016.o sceReg_0017.o sceReg_0018.o + +REGDRIVER_OBJS = sceReg_driver_0000.o sceReg_driver_0001.o sceReg_driver_0002.o sceReg_driver_0003.o sceReg_driver_0004.o sceReg_driver_0005.o sceReg_driver_0006.o sceReg_driver_0007.o sceReg_driver_0008.o sceReg_driver_0009.o sceReg_driver_0010.o sceReg_driver_0011.o sceReg_driver_0012.o sceReg_driver_0013.o sceReg_driver_0014.o sceReg_driver_0015.o sceReg_driver_0016.o sceReg_driver_0017.o sceReg_driver_0018.o sceReg_driver_0019.o + +libpspregincludedir = @PSPSDK_INCLUDEDIR@ +libpspreginclude_HEADERS = pspreg.h + +lib_LIBRARIES = libpspreg.a libpspreg_driver.a +libpspreg_a_SOURCES = sceReg.S +libpspreg_a_LIBADD = $(REG_OBJS) + +libpspreg_driver_a_SOURCES = sceReg_driver.S +libpspreg_driver_a_LIBADD = $(REGDRIVER_OBJS) + +$(REG_OBJS): sceReg.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(REGDRIVER_OBJS): sceReg_driver.S + $(COMPILE) -DF_$* $< -c -o $@ + diff --git a/src/registry/pspreg.h b/src/registry/pspreg.h new file mode 100644 index 00000000..71758692 --- /dev/null +++ b/src/registry/pspreg.h @@ -0,0 +1,237 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspreg.h - Prototypes for the sceReg library. + * + * Copyright (c) 2005 James F + * + * $Id: pspreg.h 2433 2008-10-15 10:00:27Z iwn $ + */ + +#ifndef __REG_H__ +#define __REG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup Reg Registry Kernel Library */ +/*@{*/ + +/** System registry path */ +#define SYSTEM_REGISTRY "/system" + +/** Size of a keyname, used in ::sceRegGetKeys */ +#define REG_KEYNAME_SIZE 27 + +/** Key types */ +enum RegKeyTypes +{ + /** Key is a directory */ + REG_TYPE_DIR = 1, + /** Key is an integer (4 bytes) */ + REG_TYPE_INT = 2, + /** Key is a string */ + REG_TYPE_STR = 3, + /** Key is a binary string */ + REG_TYPE_BIN = 4, +}; + +/** Typedef for a registry handle */ +typedef unsigned int REGHANDLE; + +/** Struct used to open a registry */ +struct RegParam +{ + unsigned int regtype; /* 0x0, set to 1 only for system */ + /** Seemingly never used, set to ::SYSTEM_REGISTRY */ + char name[256]; /* 0x4-0x104 */ + /** Length of the name */ + unsigned int namelen; /* 0x104 */ + /** Unknown, set to 1 */ + unsigned int unk2; /* 0x108 */ + /** Unknown, set to 1 */ + unsigned int unk3; /* 0x10C */ +}; + +/** + * Open the registry + * + * @param reg - A filled in ::RegParam structure + * @param mode - Open mode (set to 1) + * @param h - Pointer to a REGHANDLE to receive the registry handle + * + * @return 0 on success, < 0 on error + */ +int sceRegOpenRegistry(struct RegParam *reg, int mode, REGHANDLE *h); + +/** + * Flush the registry to disk + * + * @param h - The open registry handle + * + * @return 0 on success, < 0 on error + */ +int sceRegFlushRegistry(REGHANDLE h); + +/** + * Close the registry + * + * @param h - The open registry handle + * + * @return 0 on success, < 0 on error + */ +int sceRegCloseRegistry(REGHANDLE h); + +/** + * Open a registry directory + * + * @param h - The open registry handle + * @param name - The path to the dir to open (e.g. /CONFIG/SYSTEM) + * @param mode - Open mode (can be 1 or 2, probably read or read/write + * @param hd - Pointer to a REGHANDLE to receive the registry dir handle + * + * @return 0 on success, < 0 on error + */ +int sceRegOpenCategory(REGHANDLE h, const char *name, int mode, REGHANDLE *hd); + +/** + * Remove a registry dir + * + * @param h - The open registry dir handle + * @param name - The name of the key + * + * @return 0 on success, < 0 on error + */ +int sceRegRemoveCategory(REGHANDLE h, const char *name); + +/** + * Close the registry directory + * + * @param hd - The open registry dir handle + * + * @return 0 on success, < 0 on error + */ +int sceRegCloseCategory(REGHANDLE hd); + +/** + * Flush the registry directory to disk + * + * @param hd - The open registry dir handle + * + * @return 0 on success, < 0 on error + */ +int sceRegFlushCategory(REGHANDLE hd); + +/** + * Get a key's information + * + * @param hd - The open registry dir handle + * @param name - Name of the key + * @param hk - Pointer to a REGHANDLE to get registry key handle + * @param type - Type of the key, on of ::RegKeyTypes + * @param size - The size of the key's value in bytes + * + * @return 0 on success, < 0 on error + */ +int sceRegGetKeyInfo(REGHANDLE hd, const char *name, REGHANDLE *hk, unsigned int *type, SceSize *size); + +/** + * Get a key's information by name + * + * @param hd - The open registry dir handle + * @param name - Name of the key + * @param type - Type of the key, on of ::RegKeyTypes + * @param size - The size of the key's value in bytes + * + * @return 0 on success, < 0 on error + */ +int sceRegGetKeyInfoByName(REGHANDLE hd, const char *name, unsigned int *type, SceSize *size); + +/** + * Get a key's value + * + * @param hd - The open registry dir handle + * @param hk - The open registry key handler (from ::sceRegGetKeyInfo) + * @param buf - Buffer to hold the value + * @param size - The size of the buffer + * + * @return 0 on success, < 0 on error + */ +int sceRegGetKeyValue(REGHANDLE hd, REGHANDLE hk, void *buf, SceSize size); + +/** + * Get a key's value by name + * + * @param hd - The open registry dir handle + * @param name - The key name + * @param buf - Buffer to hold the value + * @param size - The size of the buffer + * + * @return 0 on success, < 0 on error + */ +int sceRegGetKeyValueByName(REGHANDLE hd, const char *name, void *buf, SceSize size); + +/** + * Set a key's value + * + * @param hd - The open registry dir handle + * @param name - The key name + * @param buf - Buffer to hold the value + * @param size - The size of the buffer + * + * @return 0 on success, < 0 on error + */ +int sceRegSetKeyValue(REGHANDLE hd, const char *name, const void *buf, SceSize size); + +/** + * Get number of subkeys in the current dir + * + * @param hd - The open registry dir handle + * @param num - Pointer to an integer to receive the number + * + * @return 0 on success, < 0 on error + */ +int sceRegGetKeysNum(REGHANDLE hd, int *num); + +/** + * Get the key names in the current directory + * + * @param hd - The open registry dir handle + * @param buf - Buffer to hold the NUL terminated strings, should be num*REG_KEYNAME_SIZE + * @param num - Number of elements in buf + * + * @return 0 on success, < 0 on error + */ +int sceRegGetKeys(REGHANDLE hd, char *buf, int num); + +/** + * Create a key + * + * @param hd - The open registry dir handle + * @param name - Name of the key to create + * @param type - Type of key (note cannot be a directory type) + * @param size - Size of the allocated value space + * + * @return 0 on success, < 0 on error + */ +int sceRegCreateKey(REGHANDLE hd, const char *name, int type, SceSize size); + +/** + * Remove a registry (HONESTLY, DO NOT USE) + * + * @param reg - Filled out registry parameter + * + * @return 0 on success, < 0 on error + */ +int sceRegRemoveRegistry(struct RegParam *reg); + +/*@}*/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/registry/sceReg.S b/src/registry/sceReg.S new file mode 100644 index 00000000..bcff1ff7 --- /dev/null +++ b/src/registry/sceReg.S @@ -0,0 +1,61 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceReg_0000 + IMPORT_START "sceReg",0x40010000 +#endif +#ifdef F_sceReg_0001 + IMPORT_FUNC "sceReg",0x9B25EDF1,sceRegExit +#endif +#ifdef F_sceReg_0002 + IMPORT_FUNC "sceReg",0x92E41280,sceRegOpenRegistry +#endif +#ifdef F_sceReg_0003 + IMPORT_FUNC "sceReg",0xFA8A5739,sceRegCloseRegistry +#endif +#ifdef F_sceReg_0004 + IMPORT_FUNC "sceReg",0xDEDA92BF,sceRegRemoveRegistry +#endif +#ifdef F_sceReg_0005 + IMPORT_FUNC "sceReg",0x1D8A762E,sceRegOpenCategory +#endif +#ifdef F_sceReg_0006 + IMPORT_FUNC "sceReg",0x0CAE832B,sceRegCloseCategory +#endif +#ifdef F_sceReg_0007 + IMPORT_FUNC "sceReg",0x39461B4D,sceRegFlushRegistry +#endif +#ifdef F_sceReg_0008 + IMPORT_FUNC "sceReg",0x0D69BF40,sceRegFlushCategory +#endif +#ifdef F_sceReg_0009 + IMPORT_FUNC "sceReg",0x57641A81,sceRegCreateKey +#endif +#ifdef F_sceReg_0010 + IMPORT_FUNC "sceReg",0x17768E14,sceRegSetKeyValue +#endif +#ifdef F_sceReg_0011 + IMPORT_FUNC "sceReg",0xD4475AA8,sceRegGetKeyInfo +#endif +#ifdef F_sceReg_0012 + IMPORT_FUNC "sceReg",0x28A8E98A,sceRegGetKeyValue +#endif +#ifdef F_sceReg_0013 + IMPORT_FUNC "sceReg",0x2C0DB9DD,sceRegGetKeysNum +#endif +#ifdef F_sceReg_0014 + IMPORT_FUNC "sceReg",0x2D211135,sceRegGetKeys +#endif +#ifdef F_sceReg_0015 + IMPORT_FUNC "sceReg",0x4CA16893,sceRegRemoveCategory +#endif +#ifdef F_sceReg_0016 + IMPORT_FUNC "sceReg",0x3615BC87,sceRegRemoveKey +#endif +#ifdef F_sceReg_0017 + IMPORT_FUNC "sceReg",0xC5768D02,sceRegGetKeyInfoByName +#endif +#ifdef F_sceReg_0018 + IMPORT_FUNC "sceReg",0x30BE0259,sceRegGetKeyValueByName +#endif diff --git a/src/registry/sceReg_driver.S b/src/registry/sceReg_driver.S new file mode 100644 index 00000000..d8dc3ecd --- /dev/null +++ b/src/registry/sceReg_driver.S @@ -0,0 +1,64 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceReg_driver_0000 + IMPORT_START "sceReg_driver",0x00010000 +#endif +#ifdef F_sceReg_driver_0001 + IMPORT_FUNC "sceReg_driver",0x98279CF1,sceRegInit +#endif +#ifdef F_sceReg_driver_0002 + IMPORT_FUNC "sceReg_driver",0x9B25EDF1,sceRegExit +#endif +#ifdef F_sceReg_driver_0003 + IMPORT_FUNC "sceReg_driver",0x92E41280,sceRegOpenRegistry +#endif +#ifdef F_sceReg_driver_0004 + IMPORT_FUNC "sceReg_driver",0xFA8A5739,sceRegCloseRegistry +#endif +#ifdef F_sceReg_driver_0005 + IMPORT_FUNC "sceReg_driver",0xDEDA92BF,sceRegRemoveRegistry +#endif +#ifdef F_sceReg_driver_0006 + IMPORT_FUNC "sceReg_driver",0x1D8A762E,sceRegOpenCategory +#endif +#ifdef F_sceReg_driver_0007 + IMPORT_FUNC "sceReg_driver",0x0CAE832B,sceRegCloseCategory +#endif +#ifdef F_sceReg_driver_0008 + IMPORT_FUNC "sceReg_driver",0x39461B4D,sceRegFlushRegistry +#endif +#ifdef F_sceReg_driver_0009 + IMPORT_FUNC "sceReg_driver",0x0D69BF40,sceRegFlushCategory +#endif +#ifdef F_sceReg_driver_0010 + IMPORT_FUNC "sceReg_driver",0x57641A81,sceRegCreateKey +#endif +#ifdef F_sceReg_driver_0011 + IMPORT_FUNC "sceReg_driver",0x17768E14,sceRegSetKeyValue +#endif +#ifdef F_sceReg_driver_0012 + IMPORT_FUNC "sceReg_driver",0xD4475AA8,sceRegGetKeyInfo +#endif +#ifdef F_sceReg_driver_0013 + IMPORT_FUNC "sceReg_driver",0x28A8E98A,sceRegGetKeyValue +#endif +#ifdef F_sceReg_driver_0014 + IMPORT_FUNC "sceReg_driver",0x2C0DB9DD,sceRegGetKeysNum +#endif +#ifdef F_sceReg_driver_0015 + IMPORT_FUNC "sceReg_driver",0x2D211135,sceRegGetKeys +#endif +#ifdef F_sceReg_driver_0016 + IMPORT_FUNC "sceReg_driver",0x4CA16893,sceRegRemoveCategory +#endif +#ifdef F_sceReg_driver_0017 + IMPORT_FUNC "sceReg_driver",0x3615BC87,sceRegRemoveKey +#endif +#ifdef F_sceReg_driver_0018 + IMPORT_FUNC "sceReg_driver",0xC5768D02,sceRegGetKeyInfoByName +#endif +#ifdef F_sceReg_driver_0019 + IMPORT_FUNC "sceReg_driver",0x30BE0259,sceRegGetKeyValueByName +#endif diff --git a/src/rtc/Makefile.am b/src/rtc/Makefile.am new file mode 100644 index 00000000..9b313a8a --- /dev/null +++ b/src/rtc/Makefile.am @@ -0,0 +1,31 @@ + +libdir = @PSPSDK_LIBDIR@ + +CC = @PSP_CC@ +CCAS = $(CC) +AR = @PSP_AR@ +RANLIB = @PSP_RANLIB@ + +INCLUDES = -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel +CFLAGS = @PSPSDK_CFLAGS@ +CCASFLAGS = $(CFLAGS) -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel + +RTC_OBJS = sceRtc_0000.o sceRtc_0001.o sceRtc_0002.o sceRtc_0003.o sceRtc_0004.o sceRtc_0005.o sceRtc_0006.o sceRtc_0007.o sceRtc_0008.o sceRtc_0009.o sceRtc_0010.o sceRtc_0011.o sceRtc_0012.o sceRtc_0013.o sceRtc_0014.o sceRtc_0015.o sceRtc_0016.o sceRtc_0017.o sceRtc_0018.o sceRtc_0019.o sceRtc_0020.o sceRtc_0021.o sceRtc_0022.o sceRtc_0023.o sceRtc_0024.o sceRtc_0025.o sceRtc_0026.o sceRtc_0027.o sceRtc_0028.o sceRtc_0029.o sceRtc_0030.o sceRtc_0031.o sceRtc_0032.o sceRtc_0033.o sceRtc_0034.o sceRtc_0035.o sceRtc_0036.o sceRtc_0037.o sceRtc_0038.o sceRtc_0039.o sceRtc_0040.o sceRtc_0041.o + +RTCDRIVER_OBJS = sceRtc_driver_0000.o sceRtc_driver_0001.o sceRtc_driver_0002.o sceRtc_driver_0003.o sceRtc_driver_0004.o sceRtc_driver_0005.o sceRtc_driver_0006.o sceRtc_driver_0007.o sceRtc_driver_0008.o sceRtc_driver_0009.o sceRtc_driver_0010.o sceRtc_driver_0011.o sceRtc_driver_0012.o sceRtc_driver_0013.o sceRtc_driver_0014.o sceRtc_driver_0015.o sceRtc_driver_0016.o sceRtc_driver_0017.o sceRtc_driver_0018.o sceRtc_driver_0019.o sceRtc_driver_0020.o sceRtc_driver_0021.o sceRtc_driver_0022.o sceRtc_driver_0023.o sceRtc_driver_0024.o sceRtc_driver_0025.o sceRtc_driver_0026.o sceRtc_driver_0027.o sceRtc_driver_0028.o sceRtc_driver_0029.o sceRtc_driver_0030.o sceRtc_driver_0031.o sceRtc_driver_0032.o sceRtc_driver_0033.o sceRtc_driver_0034.o sceRtc_driver_0035.o sceRtc_driver_0036.o sceRtc_driver_0037.o sceRtc_driver_0038.o sceRtc_driver_0039.o sceRtc_driver_0040.o sceRtc_driver_0041.o sceRtc_driver_0042.o sceRtc_driver_0043.o sceRtc_driver_0044.o sceRtc_driver_0045.o sceRtc_driver_0046.o sceRtc_driver_0047.o sceRtc_driver_0048.o sceRtc_driver_0049.o sceRtc_driver_0050.o sceRtc_driver_0051.o sceRtc_driver_0052.o sceRtc_driver_0053.o sceRtc_driver_0054.o sceRtc_driver_0055.o sceRtc_driver_0056.o + +libpsprtcincludedir = @PSPSDK_INCLUDEDIR@ +libpsprtcinclude_HEADERS = psprtc.h + +lib_LIBRARIES = libpsprtc.a libpsprtc_driver.a +libpsprtc_a_SOURCES = sceRtc.S +libpsprtc_a_LIBADD = $(RTC_OBJS) + +libpsprtc_driver_a_SOURCES = sceRtc_driver.S +libpsprtc_driver_a_LIBADD = $(RTCDRIVER_OBJS) + +$(RTC_OBJS): sceRtc.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(RTCDRIVER_OBJS): sceRtc_driver.S + $(COMPILE) -DF_$* $< -c -o $@ diff --git a/src/rtc/psprtc.h b/src/rtc/psprtc.h new file mode 100644 index 00000000..e36a5cd9 --- /dev/null +++ b/src/rtc/psprtc.h @@ -0,0 +1,265 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * psprtc.h - Prototypes for the sceRtc library + * + * Function returns marked with (?) have not been tested. + * + * Copyright (c) 2005 John Kelley + * + * $Id: psprtc.h 2091 2006-12-06 18:11:29Z tyranid $ + */ +#ifndef __PSPRTC_H__ +#define __PSPRTC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + u16 year; + u16 month; + u16 day; + u16 hour; + u16 minutes; + u16 seconds; + u32 microseconds; +} pspTime; + +enum pspRtcCheckValidErrors { + PSP_TIME_INVALID_YEAR = -1, + PSP_TIME_INVALID_MONTH = -2, + PSP_TIME_INVALID_DAY = -3, + PSP_TIME_INVALID_HOUR = -4, + PSP_TIME_INVALID_MINUTES = -5, + PSP_TIME_INVALID_SECONDS = -6, + PSP_TIME_INVALID_MICROSECONDS = -7 +}; + +/** + * Get the resolution of the tick counter + * + * @return # of ticks per second + */ +u32 sceRtcGetTickResolution(); + +/** + * Get current tick count + * + * @param tick - pointer to u64 to receive tick count + * @return 0 on success, < 0 on error + */ +int sceRtcGetCurrentTick(u64 *tick); + +/** + * Get current tick count, adjusted for local time zone + * + * @param time - pointer to pspTime struct to receive time + * @param tz - time zone to adjust to (minutes from UTC) + * @return 0 on success, < 0 on error + */ +int sceRtcGetCurrentClock(pspTime *time, int tz); + +/** + * Get current local time into a pspTime struct + * + * @param time - pointer to pspTime struct to receive time + * @return 0 on success, < 0 on error + */ +int sceRtcGetCurrentClockLocalTime(pspTime *time); + +/** + * Convert a UTC-based tickcount into a local time tick count + * + * @param tickUTC - pointer to u64 tick in UTC time + * @param tickLocal - pointer to u64 to receive tick in local time + * @return 0 on success, < 0 on error + */ +int sceRtcConvertUtcToLocalTime(const u64* tickUTC, u64* tickLocal); + +/** + * Convert a local time based tickcount into a UTC-based tick count + * + * @param tickLocal - pointer to u64 tick in local time + * @param tickUTC - pointer to u64 to receive tick in UTC based time + * @return 0 on success, < 0 on error + */ +int sceRtcConvertLocalTimeToUTC(const u64* tickLocal, u64* tickUTC); + +/** + * Check if a year is a leap year + * + * @param year - year to check if is a leap year + * @return 1 on leapyear, 0 if not + */ +int sceRtcIsLeapYear(int year); + +/** + * Get number of days in a specific month + * + * @param year - year in which to check (accounts for leap year) + * @param month - month to get number of days for + * @return # of days in month, <0 on error (?) + */ +int sceRtcGetDaysInMonth(int year, int month); + +/** + * Get day of the week for a date + * + * @param year - year in which to check (accounts for leap year) + * @param month - month that day is in + * @param day - day to get day of week for + * @return day of week with 0 representing Monday + */ +int sceRtcGetDayOfWeek(int year, int month, int day); + +/** + * Validate pspDate component ranges + * + * @param date - pointer to pspDate struct to be checked + * @return 0 on success, one of ::CheckValidErrors on error + */ +int sceRtcCheckValid(const pspTime* date); + +/** + * Set a pspTime struct based on ticks + * + * @param date - pointer to pspTime struct to set + * @param tick - pointer to ticks to convert + * @return 0 on success, < 0 on error + */ +int sceRtcSetTick(pspTime* date, const u64* tick); + +/** + * Set ticks based on a pspTime struct + * + * @param date - pointer to pspTime to convert + * @param tick - pointer to tick to set + * @return 0 on success, < 0 on error + */ +int sceRtcGetTick(const pspTime* date, u64 *tick); + +/** + * Compare two ticks + * + * @param tick1 - pointer to first tick + * @param tick2 - poiinter to second tick + * @return 0 on equal, <0 when tick1 < tick2, >0 when tick1 > tick2 + */ +int sceRtcCompareTick(const u64* tick1, const u64* tick2); + +/** + * Add two ticks + * + * @param destTick - pointer to tick to hold result + * @param srcTick - pointer to source tick + * @param numTicks - number of ticks to add + * @return 0 on success, <0 on error + */ +int sceRtcTickAddTicks(u64* destTick, const u64* srcTick, u64 numTicks); + +/** + * Add an amount of ms to a tick + * + * @param destTick - pointer to tick to hold result + * @param srcTick - pointer to source tick + * @param numMS - number of ms to add + * @return 0 on success, <0 on error + */ +int sceRtcTickAddMicroseconds(u64* destTick, const u64* srcTick, u64 numMS); + +/** + * Add an amount of seconds to a tick + * + * @param destTick - pointer to tick to hold result + * @param srcTick - pointer to source tick + * @param numSecs - number of seconds to add + * @return 0 on success, <0 on error + */ +int sceRtcTickAddSeconds(u64* destTick, const u64* srcTick, u64 numSecs); + +/** + * Add an amount of minutes to a tick + * + * @param destTick - pointer to tick to hold result + * @param srcTick - pointer to source tick + * @param numMins - number of minutes to add + * @return 0 on success, <0 on error + */ +int sceRtcTickAddMinutes(u64* destTick, const u64* srcTick, u64 numMins); + +/** + * Add an amount of hours to a tick + * + * @param destTick - pointer to tick to hold result + * @param srcTick - pointer to source tick + * @param numHours - number of hours to add + * @return 0 on success, <0 on error + */ +int sceRtcTickAddHours(u64* destTick, const u64* srcTick, int numHours); + +/** + * Add an amount of days to a tick + * + * @param destTick - pointer to tick to hold result + * @param srcTick - pointer to source tick + * @param numDays - number of days to add + * @return 0 on success, <0 on error + */ +int sceRtcTickAddDays(u64* destTick, const u64* srcTick, int numDays); + +/** + * Add an amount of weeks to a tick + * + * @param destTick - pointer to tick to hold result + * @param srcTick - pointer to source tick + * @param numWeeks - number of weeks to add + * @return 0 on success, <0 on error + */ +int sceRtcTickAddWeeks(u64* destTick, const u64* srcTick, int numWeeks); + + +/** + * Add an amount of months to a tick + * + * @param destTick - pointer to tick to hold result + * @param srcTick - pointer to source tick + * @param numMonths - number of months to add + * @return 0 on success, <0 on error + */ +int sceRtcTickAddMonths(u64* destTick, const u64* srcTick, int numMonths); + +/** + * Add an amount of years to a tick + * + * @param destTick - pointer to tick to hold result + * @param srcTick - pointer to source tick + * @param numYears - number of years to add + * @return 0 on success, <0 on error + */ +int sceRtcTickAddYears(u64* destTick, const u64* srcTick, int numYears); + +int sceRtcSetTime_t(pspTime* date, const time_t time); +int sceRtcGetTime_t(const pspTime* date, time_t *time); +int sceRtcSetDosTime(pspTime* date, u32 dosTime); +int sceRtcGetDosTime(pspTime* date, u32 dosTime); +int sceRtcSetWin32FileTime(pspTime* date, u64* win32Time); +int sceRtcGetWin32FileTime(pspTime* date, u64* win32Time); + +int sceRtcParseDateTime(u64 *destTick, const char *dateString); +/* +sceRtcFormatRFC2822 +sceRtcFormatRFC2822LocalTime +sceRtcFormatRFC3339 +sceRtcFormatRFC3339LocalTime + +sceRtcParseRFC3339 +*/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/rtc/sceRtc.S b/src/rtc/sceRtc.S new file mode 100644 index 00000000..59ce3c9e --- /dev/null +++ b/src/rtc/sceRtc.S @@ -0,0 +1,131 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceRtc_0000 + IMPORT_START "sceRtc",0x40010000 +#endif +#ifdef F_sceRtc_0001 + IMPORT_FUNC "sceRtc",0xC41C2853,sceRtcGetTickResolution +#endif +#ifdef F_sceRtc_0002 + IMPORT_FUNC "sceRtc",0x3F7AD767,sceRtcGetCurrentTick +#endif +#ifdef F_sceRtc_0003 + IMPORT_FUNC "sceRtc",0x029CA3B3,sceRtc_029CA3B3 +#endif +#ifdef F_sceRtc_0004 + IMPORT_FUNC "sceRtc",0x4CFA57B0,sceRtcGetCurrentClock +#endif +#ifdef F_sceRtc_0005 + IMPORT_FUNC "sceRtc",0xE7C27D1B,sceRtcGetCurrentClockLocalTime +#endif +#ifdef F_sceRtc_0006 + IMPORT_FUNC "sceRtc",0x34885E0D,sceRtcConvertUtcToLocalTime +#endif +#ifdef F_sceRtc_0007 + IMPORT_FUNC "sceRtc",0x779242A2,sceRtcConvertLocalTimeToUTC +#endif +#ifdef F_sceRtc_0008 + IMPORT_FUNC "sceRtc",0x42307A17,sceRtcIsLeapYear +#endif +#ifdef F_sceRtc_0009 + IMPORT_FUNC "sceRtc",0x05EF322C,sceRtcGetDaysInMonth +#endif +#ifdef F_sceRtc_0010 + IMPORT_FUNC "sceRtc",0x57726BC1,sceRtcGetDayOfWeek +#endif +#ifdef F_sceRtc_0011 + IMPORT_FUNC "sceRtc",0x4B1B5E82,sceRtcCheckValid +#endif +#ifdef F_sceRtc_0012 + IMPORT_FUNC "sceRtc",0x3A807CC8,sceRtcSetTime_t +#endif +#ifdef F_sceRtc_0013 + IMPORT_FUNC "sceRtc",0x27C4594C,sceRtcGetTime_t +#endif +#ifdef F_sceRtc_0014 + IMPORT_FUNC "sceRtc",0xF006F264,sceRtcSetDosTime +#endif +#ifdef F_sceRtc_0015 + IMPORT_FUNC "sceRtc",0x36075567,sceRtcGetDosTime +#endif +#ifdef F_sceRtc_0016 + IMPORT_FUNC "sceRtc",0x7ACE4C04,sceRtcSetWin32FileTime +#endif +#ifdef F_sceRtc_0017 + IMPORT_FUNC "sceRtc",0xCF561893,sceRtcGetWin32FileTime +#endif +#ifdef F_sceRtc_0018 + IMPORT_FUNC "sceRtc",0x7ED29E40,sceRtcSetTick +#endif +#ifdef F_sceRtc_0019 + IMPORT_FUNC "sceRtc",0x6FF40ACC,sceRtcGetTick +#endif +#ifdef F_sceRtc_0020 + IMPORT_FUNC "sceRtc",0x9ED0AE87,sceRtcCompareTick +#endif +#ifdef F_sceRtc_0021 + IMPORT_FUNC "sceRtc",0x44F45E05,sceRtcTickAddTicks +#endif +#ifdef F_sceRtc_0022 + IMPORT_FUNC "sceRtc",0x26D25A5D,sceRtcTickAddMicroseconds +#endif +#ifdef F_sceRtc_0023 + IMPORT_FUNC "sceRtc",0xF2A4AFE5,sceRtcTickAddSeconds +#endif +#ifdef F_sceRtc_0024 + IMPORT_FUNC "sceRtc",0xE6605BCA,sceRtcTickAddMinutes +#endif +#ifdef F_sceRtc_0025 + IMPORT_FUNC "sceRtc",0x26D7A24A,sceRtcTickAddHours +#endif +#ifdef F_sceRtc_0026 + IMPORT_FUNC "sceRtc",0xE51B4B7A,sceRtcTickAddDays +#endif +#ifdef F_sceRtc_0027 + IMPORT_FUNC "sceRtc",0xCF3A2CA8,sceRtcTickAddWeeks +#endif +#ifdef F_sceRtc_0028 + IMPORT_FUNC "sceRtc",0xDBF74F1B,sceRtcTickAddMonths +#endif +#ifdef F_sceRtc_0029 + IMPORT_FUNC "sceRtc",0x42842C77,sceRtcTickAddYears +#endif +#ifdef F_sceRtc_0030 + IMPORT_FUNC "sceRtc",0xC663B3B9,sceRtcFormatRFC2822 +#endif +#ifdef F_sceRtc_0031 + IMPORT_FUNC "sceRtc",0x7DE6711B,sceRtcFormatRFC2822LocalTime +#endif +#ifdef F_sceRtc_0032 + IMPORT_FUNC "sceRtc",0x0498FB3C,sceRtcFormatRFC3339 +#endif +#ifdef F_sceRtc_0033 + IMPORT_FUNC "sceRtc",0x27F98543,sceRtcFormatRFC3339LocalTime +#endif +#ifdef F_sceRtc_0034 + IMPORT_FUNC "sceRtc",0xDFBC5F16,sceRtcParseDateTime +#endif +#ifdef F_sceRtc_0035 + IMPORT_FUNC "sceRtc",0x28E1E988,sceRtcParseRFC3339 +#endif +#ifdef F_sceRtc_0036 + IMPORT_FUNC "sceRtc",0x011F03C1,sceRtcGetAccumulativeTime +#endif +#ifdef F_sceRtc_0037 + IMPORT_FUNC "sceRtc",0x1909C99B,sceRtcSetTime64_t +#endif +#ifdef F_sceRtc_0038 + IMPORT_FUNC "sceRtc",0x203CEB0D,sceRtcGetLastReincarnatedTime +#endif +#ifdef F_sceRtc_0039 + IMPORT_FUNC "sceRtc",0x62685E98,sceRtcGetLastAdjustedTime +#endif +#ifdef F_sceRtc_0040 + IMPORT_FUNC "sceRtc",0xDFBC5F16,sceRtcParseDateTime +#endif +#ifdef F_sceRtc_0041 + IMPORT_FUNC "sceRtc",0xE1C93E47,sceRtcGetTime64_t +#endif + diff --git a/src/rtc/sceRtc_driver.S b/src/rtc/sceRtc_driver.S new file mode 100644 index 00000000..ef94bdb8 --- /dev/null +++ b/src/rtc/sceRtc_driver.S @@ -0,0 +1,176 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceRtc_driver_0000 + IMPORT_START "sceRtc_driver",0x00010000 +#endif +#ifdef F_sceRtc_driver_0001 + IMPORT_FUNC "sceRtc_driver",0xC41C2853,sceRtcGetTickResolution +#endif +#ifdef F_sceRtc_driver_0002 + IMPORT_FUNC "sceRtc_driver",0x3F7AD767,sceRtcGetCurrentTick +#endif +#ifdef F_sceRtc_driver_0003 + IMPORT_FUNC "sceRtc_driver",0x029CA3B3,sceRtc_029CA3B3 +#endif +#ifdef F_sceRtc_driver_0004 + IMPORT_FUNC "sceRtc_driver",0x4CFA57B0,sceRtcGetCurrentClock +#endif +#ifdef F_sceRtc_driver_0005 + IMPORT_FUNC "sceRtc_driver",0xE7C27D1B,sceRtcGetCurrentClockLocalTime +#endif +#ifdef F_sceRtc_driver_0006 + IMPORT_FUNC "sceRtc_driver",0x34885E0D,sceRtcConvertUtcToLocalTime +#endif +#ifdef F_sceRtc_driver_0007 + IMPORT_FUNC "sceRtc_driver",0x779242A2,sceRtcConvertLocalTimeToUTC +#endif +#ifdef F_sceRtc_driver_0008 + IMPORT_FUNC "sceRtc_driver",0x42307A17,sceRtcIsLeapYear +#endif +#ifdef F_sceRtc_driver_0009 + IMPORT_FUNC "sceRtc_driver",0x05EF322C,sceRtcGetDaysInMonth +#endif +#ifdef F_sceRtc_driver_0010 + IMPORT_FUNC "sceRtc_driver",0x57726BC1,sceRtcGetDayOfWeek +#endif +#ifdef F_sceRtc_driver_0011 + IMPORT_FUNC "sceRtc_driver",0x4B1B5E82,sceRtcCheckValid +#endif +#ifdef F_sceRtc_driver_0012 + IMPORT_FUNC "sceRtc_driver",0x3A807CC8,sceRtcSetTime_t +#endif +#ifdef F_sceRtc_driver_0013 + IMPORT_FUNC "sceRtc_driver",0x27C4594C,sceRtcGetTime_t +#endif +#ifdef F_sceRtc_driver_0014 + IMPORT_FUNC "sceRtc_driver",0xF006F264,sceRtcSetDosTime +#endif +#ifdef F_sceRtc_driver_0015 + IMPORT_FUNC "sceRtc_driver",0x36075567,sceRtcGetDosTime +#endif +#ifdef F_sceRtc_driver_0016 + IMPORT_FUNC "sceRtc_driver",0x7ACE4C04,sceRtcSetWin32FileTime +#endif +#ifdef F_sceRtc_driver_0017 + IMPORT_FUNC "sceRtc_driver",0xCF561893,sceRtcGetWin32FileTime +#endif +#ifdef F_sceRtc_driver_0018 + IMPORT_FUNC "sceRtc_driver",0x7ED29E40,sceRtcSetTick +#endif +#ifdef F_sceRtc_driver_0019 + IMPORT_FUNC "sceRtc_driver",0x6FF40ACC,sceRtcGetTick +#endif +#ifdef F_sceRtc_driver_0020 + IMPORT_FUNC "sceRtc_driver",0x9ED0AE87,sceRtcCompareTick +#endif +#ifdef F_sceRtc_driver_0021 + IMPORT_FUNC "sceRtc_driver",0x44F45E05,sceRtcTickAddTicks +#endif +#ifdef F_sceRtc_driver_0022 + IMPORT_FUNC "sceRtc_driver",0x26D25A5D,sceRtcTickAddMicroseconds +#endif +#ifdef F_sceRtc_driver_0023 + IMPORT_FUNC "sceRtc_driver",0xF2A4AFE5,sceRtcTickAddSeconds +#endif +#ifdef F_sceRtc_driver_0024 + IMPORT_FUNC "sceRtc_driver",0xE6605BCA,sceRtcTickAddMinutes +#endif +#ifdef F_sceRtc_driver_0025 + IMPORT_FUNC "sceRtc_driver",0x26D7A24A,sceRtcTickAddHours +#endif +#ifdef F_sceRtc_driver_0026 + IMPORT_FUNC "sceRtc_driver",0xE51B4B7A,sceRtcTickAddDays +#endif +#ifdef F_sceRtc_driver_0027 + IMPORT_FUNC "sceRtc_driver",0xCF3A2CA8,sceRtcTickAddWeeks +#endif +#ifdef F_sceRtc_driver_0028 + IMPORT_FUNC "sceRtc_driver",0xDBF74F1B,sceRtcTickAddMonths +#endif +#ifdef F_sceRtc_driver_0029 + IMPORT_FUNC "sceRtc_driver",0x42842C77,sceRtcTickAddYears +#endif +#ifdef F_sceRtc_driver_0030 + IMPORT_FUNC "sceRtc_driver",0xC663B3B9,sceRtcFormatRFC2822 +#endif +#ifdef F_sceRtc_driver_0031 + IMPORT_FUNC "sceRtc_driver",0x7DE6711B,sceRtcFormatRFC2822LocalTime +#endif +#ifdef F_sceRtc_driver_0032 + IMPORT_FUNC "sceRtc_driver",0x0498FB3C,sceRtcFormatRFC3339 +#endif +#ifdef F_sceRtc_driver_0033 + IMPORT_FUNC "sceRtc_driver",0x27F98543,sceRtcFormatRFC3339LocalTime +#endif +#ifdef F_sceRtc_driver_0034 + IMPORT_FUNC "sceRtc_driver",0xDFBC5F16,sceRtcParseDateTime +#endif +#ifdef F_sceRtc_driver_0035 + IMPORT_FUNC "sceRtc_driver",0x28E1E988,sceRtcParseRFC3339 +#endif +#ifdef F_sceRtc_driver_0036 + IMPORT_FUNC "sceRtc_driver",0x011F03C1,sceRtcGetAccumulativeTime +#endif +#ifdef F_sceRtc_driver_0037 + IMPORT_FUNC "sceRtc_driver",0x17C26C00,sceRtc_driver_17C26C00 +#endif +#ifdef F_sceRtc_driver_0038 + IMPORT_FUNC "sceRtc_driver",0x1909C99B,sceRtcSetTime64_t +#endif +#ifdef F_sceRtc_driver_0039 + IMPORT_FUNC "sceRtc_driver",0x203CEB0D,sceRtcGetLastReincarnatedTime +#endif +#ifdef F_sceRtc_driver_0040 + IMPORT_FUNC "sceRtc_driver",0x48D07D70,sceRtcResume +#endif +#ifdef F_sceRtc_driver_0041 + IMPORT_FUNC "sceRtc_driver",0x62685E98,sceRtcGetLastAdjustedTime +#endif +#ifdef F_sceRtc_driver_0042 + IMPORT_FUNC "sceRtc_driver",0x6A676D2D,sceRtc_driver_6A676D2D +#endif +#ifdef F_sceRtc_driver_0043 + IMPORT_FUNC "sceRtc_driver",0x759937C5,sceRtcSetConf +#endif +#ifdef F_sceRtc_driver_0044 + IMPORT_FUNC "sceRtc_driver",0x7D1FBED3,sceRtcSetAlarmTick +#endif +#ifdef F_sceRtc_driver_0045 + IMPORT_FUNC "sceRtc_driver",0x81FCDA34,sceRtc_driver_81FCDA34 +#endif +#ifdef F_sceRtc_driver_0046 + IMPORT_FUNC "sceRtc_driver",0x912BEE56,sceRtcInit +#endif +#ifdef F_sceRtc_driver_0047 + IMPORT_FUNC "sceRtc_driver",0x9763C138,sceRtcSetCurrentTick +#endif +#ifdef F_sceRtc_driver_0048 + IMPORT_FUNC "sceRtc_driver",0x9CC2797E,sceRtcSuspend +#endif +#ifdef F_sceRtc_driver_0049 + IMPORT_FUNC "sceRtc_driver",0xB44BDAED,sceRtc_driver_B44BDAED +#endif +#ifdef F_sceRtc_driver_0050 + IMPORT_FUNC "sceRtc_driver",0xC2DDBEB5,sceRtcGetAlarmTick +#endif +#ifdef F_sceRtc_driver_0051 + IMPORT_FUNC "sceRtc_driver",0xC499AF2F,sceRtc_driver_C499AF2F +#endif +#ifdef F_sceRtc_driver_0052 + IMPORT_FUNC "sceRtc_driver",0xCE27DE2F,sceRtcEnd +#endif +#ifdef F_sceRtc_driver_0053 + IMPORT_FUNC "sceRtc_driver",0xDFBC5F16,sceRtcParseDateTime +#endif +#ifdef F_sceRtc_driver_0054 + IMPORT_FUNC "sceRtc_driver",0xE1C93E47,sceRtcGetTime64_t +#endif +#ifdef F_sceRtc_driver_0055 + IMPORT_FUNC "sceRtc_driver",0xF0B5571C,sceRtcSynchronize +#endif +#ifdef F_sceRtc_driver_0056 + IMPORT_FUNC "sceRtc_driver",0xFB3B18CD,sceRtc_driver_FB3B18CD +#endif + diff --git a/src/samples/Makefile.am b/src/samples/Makefile.am new file mode 100644 index 00000000..9b64793f --- /dev/null +++ b/src/samples/Makefile.am @@ -0,0 +1,122 @@ + +samplesdir = @PSPSDK@/samples + +SAMPLES = \ + audio/polyphonic \ + audio/wavegen \ + controller/basic \ + debug/exception \ + debug/kprintf \ + debug/prxdecrypt \ + debug/profiler \ + debug/debugkb \ + debug/sio \ + debug/gdb \ + gu/beginobject \ + gu/blend \ + gu/blit \ + gu/celshading \ + gu/clut \ + gu/common \ + gu/copy \ + gu/cube \ + gu/envmap \ + gu/integerdrawing \ + gu/lights \ + gu/lines \ + gu/logic \ + gu/morph \ + gu/morphskin \ + gu/ortho \ + gu/reflection \ + gu/rendertarget \ + gu/shadowprojection \ + gu/signals \ + gu/skinning \ + gu/speed \ + gu/spharm \ + gu/splinesurface \ + gu/sprite \ + gu/text \ + gu/timing \ + gu/vertex \ + gu/zbufferfog \ + ir/sircs \ + ir/irda \ + kernel/kdumper \ + kernel/loadmodule \ + kernel/threadstatus \ + kernel/cwd \ + kernel/fileio \ + kernel/idstorage \ + kernel/messagebox \ + kernel/registry \ + kernel/regenum \ + kernel/systimer \ + kernel/sysevent \ + mp3 \ + ms/callback \ + nand/dumpipl \ + net/simple \ + net/simple_prx \ + net/resolver \ + net/wlanscan \ + net/wlanscan_elf \ + power \ + prx/prx_loader \ + prx/testprx \ + savedata/utility \ + savedata/decrypt \ + savedata/encrypt \ + template/elf_template \ + template/prx_template \ + template/lib_template \ + template/kprx_template \ + usb/storage \ + utility/gamesharing \ + utility/htmlviewer \ + utility/netconf \ + utility/netdialog \ + utility/msgdialog \ + utility/systemparam \ + utility/osk \ + me/basic \ + wlan + +all: + +dist-hook: + rm -rf `find $(distdir) -name .svn -o -name CVS` + +# Install all of the samples. Rename any files that end in a .sample extension. +SAMPLES_INSTALL = $(INSTALL_DATA) +install-data-hook: + $(mkinstalldirs) $(DESTDIR)$(samplesdir) + @list='$(SAMPLES)'; for s in $$list; do \ + $(mkinstalldirs) $(DESTDIR)$(samplesdir)/$$s; \ + for p in $(srcdir)/$$s/*; do \ + if test -f $$p; then \ + f="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " $(SAMPLES_INSTALL) $$p $(DESTDIR)$(samplesdir)/$$s/$$f"; \ + $(SAMPLES_INSTALL) $$p $(DESTDIR)$(samplesdir)/$$s/$$f; \ + else :; fi; \ + done; \ + done + @for p in `find $(DESTDIR)$(samplesdir) -name *.sample -print `; do \ + f="`echo $$p | sed -e 's/\.sample$$//'`"; \ + echo " mv $$p $$f"; \ + mv $$p $$f; \ + done + +uninstall-hook: + @list='$(SAMPLES)'; for s in $$list; do \ + for p in $(DESTDIR)$(samplesdir)/$$s/*; do \ + if test -f $$p; then \ + p="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " rm -f $(DESTDIR)$(samplesdir)/$$s/$$p"; \ + rm -f $(DESTDIR)$(samplesdir)/$$s/$$p; \ + else :; fi; \ + done; \ + done + +EXTRA_DIST = $(SAMPLES) diff --git a/src/samples/audio/polyphonic/Makefile.sample b/src/samples/audio/polyphonic/Makefile.sample new file mode 100644 index 00000000..0ed9c44d --- /dev/null +++ b/src/samples/audio/polyphonic/Makefile.sample @@ -0,0 +1,17 @@ +TARGET = polyphonic +OBJS = main.o + +INCDIR = +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = +LIBS = -lpspaudiolib -lpspaudio + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Polyphonic sample by Shine + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/audio/polyphonic/main.c b/src/samples/audio/polyphonic/main.c new file mode 100644 index 00000000..0a9d072b --- /dev/null +++ b/src/samples/audio/polyphonic/main.c @@ -0,0 +1,474 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Basic audio sample. + * + * Copyright (c) 2005 Frank Buss (aka Shine) + * + * $Id: main.c 1147 2005-10-12 15:52:52Z mrbrown $ + */ +#include +#include +#include +#include +#include +#include + +/* Define the module info section */ +PSP_MODULE_INFO("POLYPHONIC", 0, 1, 1); + +/* Define the main thread's attribute value (optional) */ +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU); + +/* Define printf, just to make typing easier */ +#define printf pspDebugScreenPrintf + +void dump_threadstatus(void); + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + sceKernelExitGame(); + + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", (void *) exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0); + if(thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} + +int pspAudioInit(); +void pspAudioEndPre(); +void pspAudioEnd(); + +#define SAMPLE_COUNT 0x10000 +float sample[SAMPLE_COUNT]; + +#define SAMPLE_RATE 44100 + +#define OCTAVE_COUNT 6 + +float octaves[OCTAVE_COUNT][12]; + +typedef struct { + int note; + int octave; + int duration; +} Note_t; + +typedef struct { + Note_t currentNote; + int noteIndex; + int currentTime; + float currentsampleIndex; + float currentsampleIncrement; +} ChannelState_t; + +ChannelState_t channelStates[3]; + +// "S" means "#" +#define NOTE_END -2 +#define NOTE_PAUSE -1 +#define NOTE_C 0 +#define NOTE_CS 1 +#define NOTE_D 2 +#define NOTE_DS 3 +#define NOTE_E 4 +#define NOTE_F 5 +#define NOTE_FS 6 +#define NOTE_G 7 +#define NOTE_GS 8 +#define NOTE_A 9 +#define NOTE_AS 10 +#define NOTE_B 11 + +#define EIGHT_NOTE(note, octave, duration) { note, octave, SAMPLE_RATE * duration / 8} + +Note_t channel0[] = { + EIGHT_NOTE(NOTE_D, 4, 7), + EIGHT_NOTE(NOTE_E, 4, 1), + EIGHT_NOTE(NOTE_F, 4, 1), + EIGHT_NOTE(NOTE_E, 4, 1), + EIGHT_NOTE(NOTE_F, 4, 1), + EIGHT_NOTE(NOTE_E, 4, 1), + EIGHT_NOTE(NOTE_A, 3, 9), + EIGHT_NOTE(NOTE_B, 3, 2), + EIGHT_NOTE(NOTE_C, 4, 1), + EIGHT_NOTE(NOTE_D, 4, 7), + EIGHT_NOTE(NOTE_E, 4, 1), + EIGHT_NOTE(NOTE_F, 4, 1), + EIGHT_NOTE(NOTE_E, 4, 1), + EIGHT_NOTE(NOTE_F, 4, 1), + EIGHT_NOTE(NOTE_E, 4, 1), + EIGHT_NOTE(NOTE_A, 3, 9), + EIGHT_NOTE(NOTE_G, 3, 3), + EIGHT_NOTE(NOTE_A, 3, 7), + EIGHT_NOTE(NOTE_B, 3, 1), + EIGHT_NOTE(NOTE_C, 4, 1), + EIGHT_NOTE(NOTE_B, 3, 1), + EIGHT_NOTE(NOTE_C, 4, 1), + EIGHT_NOTE(NOTE_B, 3, 1), + EIGHT_NOTE(NOTE_E, 3, 9), + EIGHT_NOTE(NOTE_F, 3, 2), + EIGHT_NOTE(NOTE_G, 3, 1), + EIGHT_NOTE(NOTE_A, 3, 7), + EIGHT_NOTE(NOTE_B, 3, 1), + EIGHT_NOTE(NOTE_C, 4, 1), + EIGHT_NOTE(NOTE_B, 3, 1), + EIGHT_NOTE(NOTE_C, 4, 1), + EIGHT_NOTE(NOTE_B, 3, 1), + EIGHT_NOTE(NOTE_E, 3, 12), + EIGHT_NOTE(NOTE_D, 4, 9), + EIGHT_NOTE(NOTE_C, 4, 3), + EIGHT_NOTE(NOTE_B, 3, 6), + EIGHT_NOTE(NOTE_A, 3, 6), + EIGHT_NOTE(NOTE_D, 4, 7), + EIGHT_NOTE(NOTE_E, 4, 1), + EIGHT_NOTE(NOTE_E, 4, 1), + EIGHT_NOTE(NOTE_C, 4, 1), + EIGHT_NOTE(NOTE_B, 3, 1), + EIGHT_NOTE(NOTE_C, 4, 1), + EIGHT_NOTE(NOTE_B, 3, 6), + EIGHT_NOTE(NOTE_A, 3, 6), + EIGHT_NOTE(NOTE_C, 4, 9), + EIGHT_NOTE(NOTE_B, 3, 3), + EIGHT_NOTE(NOTE_E, 3, 12), + EIGHT_NOTE(NOTE_C, 4, 7), + EIGHT_NOTE(NOTE_D, 4, 1), + EIGHT_NOTE(NOTE_C, 4, 1), + EIGHT_NOTE(NOTE_B, 3, 1), + EIGHT_NOTE(NOTE_C, 4, 1), + EIGHT_NOTE(NOTE_B, 3, 1), + EIGHT_NOTE(NOTE_E, 3, 12), + { NOTE_END, 0, 0 } +}; + +Note_t channel1[] = { + EIGHT_NOTE(NOTE_D, 1, 1), + EIGHT_NOTE(NOTE_A, 1, 1), + EIGHT_NOTE(NOTE_D, 2, 1), + EIGHT_NOTE(NOTE_E, 2, 1), + EIGHT_NOTE(NOTE_F, 2, 1), + EIGHT_NOTE(NOTE_A, 2, 1), + EIGHT_NOTE(NOTE_F, 2, 1), + EIGHT_NOTE(NOTE_E, 2, 1), + EIGHT_NOTE(NOTE_D, 2, 1), + EIGHT_NOTE(NOTE_A, 1, 1), + EIGHT_NOTE(NOTE_D, 1, 1), + EIGHT_NOTE(NOTE_A, 1, 1), + EIGHT_NOTE(NOTE_A, 0, 1), + EIGHT_NOTE(NOTE_E, 1, 1), + EIGHT_NOTE(NOTE_A, 1, 1), + EIGHT_NOTE(NOTE_B, 1, 1), + EIGHT_NOTE(NOTE_C, 2, 1), + EIGHT_NOTE(NOTE_E, 2, 1), + EIGHT_NOTE(NOTE_C, 2, 1), + EIGHT_NOTE(NOTE_B, 1, 1), + EIGHT_NOTE(NOTE_A, 1, 1), + EIGHT_NOTE(NOTE_E, 1, 1), + EIGHT_NOTE(NOTE_A, 0, 1), + EIGHT_NOTE(NOTE_E, 1, 1), + EIGHT_NOTE(NOTE_D, 1, 1), + EIGHT_NOTE(NOTE_A, 1, 1), + EIGHT_NOTE(NOTE_D, 2, 1), + EIGHT_NOTE(NOTE_E, 2, 1), + EIGHT_NOTE(NOTE_F, 2, 1), + EIGHT_NOTE(NOTE_A, 2, 1), + EIGHT_NOTE(NOTE_F, 2, 1), + EIGHT_NOTE(NOTE_E, 2, 1), + EIGHT_NOTE(NOTE_D, 2, 1), + EIGHT_NOTE(NOTE_A, 1, 1), + EIGHT_NOTE(NOTE_D, 1, 1), + EIGHT_NOTE(NOTE_A, 1, 1), + EIGHT_NOTE(NOTE_A, 0, 1), + EIGHT_NOTE(NOTE_E, 1, 1), + EIGHT_NOTE(NOTE_A, 1, 1), + EIGHT_NOTE(NOTE_B, 1, 1), + EIGHT_NOTE(NOTE_C, 2, 1), + EIGHT_NOTE(NOTE_E, 2, 1), + EIGHT_NOTE(NOTE_C, 2, 1), + EIGHT_NOTE(NOTE_B, 1, 1), + EIGHT_NOTE(NOTE_A, 1, 1), + EIGHT_NOTE(NOTE_E, 1, 1), + EIGHT_NOTE(NOTE_A, 0, 1), + EIGHT_NOTE(NOTE_E, 1, 1), + EIGHT_NOTE(NOTE_F, 1, 1), + EIGHT_NOTE(NOTE_C, 2, 1), + EIGHT_NOTE(NOTE_F, 2, 1), + EIGHT_NOTE(NOTE_G, 2, 1), + EIGHT_NOTE(NOTE_A, 2, 1), + EIGHT_NOTE(NOTE_C, 3, 1), + EIGHT_NOTE(NOTE_A, 2, 1), + EIGHT_NOTE(NOTE_G, 2, 1), + EIGHT_NOTE(NOTE_F, 2, 1), + EIGHT_NOTE(NOTE_C, 2, 1), + EIGHT_NOTE(NOTE_F, 1, 1), + EIGHT_NOTE(NOTE_C, 2, 1), + EIGHT_NOTE(NOTE_C, 1, 1), + EIGHT_NOTE(NOTE_G, 1, 1), + EIGHT_NOTE(NOTE_C, 2, 1), + EIGHT_NOTE(NOTE_D, 2, 1), + EIGHT_NOTE(NOTE_E, 2, 1), + EIGHT_NOTE(NOTE_G, 2, 1), + EIGHT_NOTE(NOTE_E, 2, 1), + EIGHT_NOTE(NOTE_D, 2, 1), + EIGHT_NOTE(NOTE_C, 2, 1), + EIGHT_NOTE(NOTE_G, 1, 1), + EIGHT_NOTE(NOTE_C, 1, 1), + EIGHT_NOTE(NOTE_G, 1, 1), + EIGHT_NOTE(NOTE_F, 1, 1), + EIGHT_NOTE(NOTE_C, 2, 1), + EIGHT_NOTE(NOTE_F, 2, 1), + EIGHT_NOTE(NOTE_G, 2, 1), + EIGHT_NOTE(NOTE_A, 2, 1), + EIGHT_NOTE(NOTE_C, 3, 1), + EIGHT_NOTE(NOTE_A, 2, 1), + EIGHT_NOTE(NOTE_G, 2, 1), + EIGHT_NOTE(NOTE_F, 2, 1), + EIGHT_NOTE(NOTE_C, 2, 1), + EIGHT_NOTE(NOTE_F, 1, 1), + EIGHT_NOTE(NOTE_C, 2, 1), + EIGHT_NOTE(NOTE_C, 1, 1), + EIGHT_NOTE(NOTE_G, 1, 1), + EIGHT_NOTE(NOTE_C, 2, 1), + EIGHT_NOTE(NOTE_D, 2, 1), + EIGHT_NOTE(NOTE_E, 2, 1), + EIGHT_NOTE(NOTE_G, 2, 1), + EIGHT_NOTE(NOTE_E, 2, 1), + EIGHT_NOTE(NOTE_D, 2, 1), + EIGHT_NOTE(NOTE_C, 2, 1), + EIGHT_NOTE(NOTE_G, 1, 1), + EIGHT_NOTE(NOTE_C, 1, 1), + EIGHT_NOTE(NOTE_G, 1, 1), + EIGHT_NOTE(NOTE_D, 1, 1), + EIGHT_NOTE(NOTE_A, 1, 1), + EIGHT_NOTE(NOTE_D, 2, 1), + EIGHT_NOTE(NOTE_E, 2, 1), + EIGHT_NOTE(NOTE_F, 2, 1), + EIGHT_NOTE(NOTE_A, 2, 1), + EIGHT_NOTE(NOTE_F, 2, 1), + EIGHT_NOTE(NOTE_E, 2, 1), + EIGHT_NOTE(NOTE_D, 2, 1), + EIGHT_NOTE(NOTE_A, 1, 1), + EIGHT_NOTE(NOTE_D, 1, 1), + EIGHT_NOTE(NOTE_A, 1, 1), + EIGHT_NOTE(NOTE_A, 0, 1), + EIGHT_NOTE(NOTE_E, 1, 1), + EIGHT_NOTE(NOTE_A, 1, 1), + EIGHT_NOTE(NOTE_B, 1, 1), + EIGHT_NOTE(NOTE_C, 2, 1), + EIGHT_NOTE(NOTE_E, 2, 1), + EIGHT_NOTE(NOTE_C, 2, 1), + EIGHT_NOTE(NOTE_B, 1, 1), + EIGHT_NOTE(NOTE_A, 1, 1), + EIGHT_NOTE(NOTE_E, 1, 1), + EIGHT_NOTE(NOTE_A, 0, 1), + EIGHT_NOTE(NOTE_E, 1, 1), + EIGHT_NOTE(NOTE_D, 1, 1), + EIGHT_NOTE(NOTE_A, 1, 1), + EIGHT_NOTE(NOTE_D, 2, 1), + EIGHT_NOTE(NOTE_E, 2, 1), + EIGHT_NOTE(NOTE_F, 2, 1), + EIGHT_NOTE(NOTE_A, 2, 1), + EIGHT_NOTE(NOTE_F, 2, 1), + EIGHT_NOTE(NOTE_E, 2, 1), + EIGHT_NOTE(NOTE_D, 2, 1), + EIGHT_NOTE(NOTE_A, 1, 1), + EIGHT_NOTE(NOTE_D, 1, 1), + EIGHT_NOTE(NOTE_A, 1, 1), + EIGHT_NOTE(NOTE_A, 0, 1), + EIGHT_NOTE(NOTE_E, 1, 1), + EIGHT_NOTE(NOTE_A, 1, 1), + EIGHT_NOTE(NOTE_B, 1, 1), + EIGHT_NOTE(NOTE_C, 2, 1), + EIGHT_NOTE(NOTE_E, 2, 1), + EIGHT_NOTE(NOTE_C, 2, 1), + EIGHT_NOTE(NOTE_B, 1, 1), + EIGHT_NOTE(NOTE_A, 1, 1), + EIGHT_NOTE(NOTE_E, 1, 1), + EIGHT_NOTE(NOTE_A, 0, 1), + EIGHT_NOTE(NOTE_E, 1, 1), + EIGHT_NOTE(NOTE_F, 1, 1), + EIGHT_NOTE(NOTE_C, 2, 1), + EIGHT_NOTE(NOTE_F, 2, 1), + EIGHT_NOTE(NOTE_G, 2, 1), + EIGHT_NOTE(NOTE_A, 2, 1), + EIGHT_NOTE(NOTE_C, 3, 1), + EIGHT_NOTE(NOTE_A, 2, 1), + EIGHT_NOTE(NOTE_G, 2, 1), + EIGHT_NOTE(NOTE_F, 2, 1), + EIGHT_NOTE(NOTE_C, 2, 1), + EIGHT_NOTE(NOTE_F, 1, 1), + EIGHT_NOTE(NOTE_C, 2, 1), + EIGHT_NOTE(NOTE_C, 1, 1), + EIGHT_NOTE(NOTE_G, 1, 1), + EIGHT_NOTE(NOTE_C, 2, 1), + EIGHT_NOTE(NOTE_D, 2, 1), + EIGHT_NOTE(NOTE_E, 2, 1), + EIGHT_NOTE(NOTE_G, 2, 1), + EIGHT_NOTE(NOTE_E, 2, 1), + EIGHT_NOTE(NOTE_D, 2, 1), + EIGHT_NOTE(NOTE_C, 2, 1), + EIGHT_NOTE(NOTE_G, 1, 1), + EIGHT_NOTE(NOTE_C, 1, 1), + EIGHT_NOTE(NOTE_G, 1, 1), + EIGHT_NOTE(NOTE_F, 1, 1), + EIGHT_NOTE(NOTE_C, 2, 1), + EIGHT_NOTE(NOTE_F, 2, 1), + EIGHT_NOTE(NOTE_G, 2, 1), + EIGHT_NOTE(NOTE_A, 2, 1), + EIGHT_NOTE(NOTE_C, 3, 1), + EIGHT_NOTE(NOTE_A, 2, 1), + EIGHT_NOTE(NOTE_G, 2, 1), + EIGHT_NOTE(NOTE_F, 2, 1), + EIGHT_NOTE(NOTE_C, 2, 1), + EIGHT_NOTE(NOTE_F, 1, 1), + EIGHT_NOTE(NOTE_C, 2, 1), + EIGHT_NOTE(NOTE_C, 1, 1), + EIGHT_NOTE(NOTE_G, 1, 1), + EIGHT_NOTE(NOTE_C, 2, 1), + EIGHT_NOTE(NOTE_D, 2, 1), + EIGHT_NOTE(NOTE_E, 2, 1), + EIGHT_NOTE(NOTE_G, 2, 1), + EIGHT_NOTE(NOTE_E, 2, 1), + EIGHT_NOTE(NOTE_D, 2, 1), + EIGHT_NOTE(NOTE_C, 2, 1), + EIGHT_NOTE(NOTE_G, 1, 1), + EIGHT_NOTE(NOTE_C, 1, 1), + EIGHT_NOTE(NOTE_G, 1, 1), + { NOTE_END, 0, 0 } +}; + +Note_t* channels[] = { channel0, channel1 }; + +void nextNote(int channel) +{ + ChannelState_t* state = &channelStates[channel]; + state->currentNote = channels[channel][state->noteIndex]; + state->currentTime = 0; + state->currentsampleIndex = 0; + int note = state->currentNote.note; + if (note == NOTE_PAUSE) { + state->currentsampleIncrement = 0; + } else { + state->currentsampleIncrement = octaves[state->currentNote.octave][note] * ((float) SAMPLE_COUNT) / ((float) SAMPLE_RATE); + } + + state->noteIndex++; + if (channels[channel][state->noteIndex].note == NOTE_END) state->noteIndex = 0; +} + +// calculate current value of attack/delay/sustain/release envelope +float adsr(float time, float duration) { + if (time < 0.0) return 0.0; + const float attack = 0.004; + const float decay = 0.02; + const float sustain = 0.5; + const float release = 0.08; + duration -= attack + decay + release; + if (time < attack) return time / attack; + time -= attack; + if (time < decay) return (decay - time) / decay * (1.0 - sustain) + sustain; + time -= decay; + if (time < duration) return sustain; + time -= duration; + if (time < release) return (release - time) / release * sustain; + return 0.0; +} + +void audioOutCallback(int channel, unsigned short* buf, unsigned int reqn) +{ + ChannelState_t* state = &channelStates[channel]; + unsigned int i; + for (i = 0; i < reqn; i++) { + float time = ((float) state->currentTime) / ((float) SAMPLE_RATE); + if (state->currentTime++ == state->currentNote.duration) nextNote(channel); + float value; + if (state->currentsampleIncrement == 0.0) { + value = 0.0; + } else { + value = sample[(int)state->currentsampleIndex] * adsr(time, ((float) state->currentNote.duration) / ((float) SAMPLE_RATE)); + value *= (float) 0x7000; + state->currentsampleIndex += state->currentsampleIncrement; + if (state->currentsampleIndex >= SAMPLE_COUNT) state->currentsampleIndex -= (float) SAMPLE_COUNT; + } + buf[0] = value; + buf[1] = value; + buf += 2; + } +} + +void audioOutCallback0(void *buf, unsigned int reqn, void *userdata) { audioOutCallback(0, buf, reqn); } +void audioOutCallback1(void *buf, unsigned int reqn, void *userdata) { audioOutCallback(1, buf, reqn); } + +void createPitches(float base, float* target) +{ + int i; + for (i = 0; i < 12; i++) { + target[i] = base; + base *= 1.0594630943592952645618252949463; // 2^(1/12) + } +} + +int main(void) +{ + pspDebugScreenInit(); + SetupCallbacks(); + printf("Polyphonic sample by Shine\n\n"); + printf("Soundtrack of the movie\n"); + printf("\"Le fabuleux destin d'Amelie Poulain\"\n"); + printf("by Yann Tiersen\n"); + + int i; + int maxAt = SAMPLE_COUNT / 16; + for (i = 0; i < SAMPLE_COUNT; i++) { + float value; + if (i < maxAt) { + value = ((float) i) / ((float) maxAt) * 2.0 - 1.0; + } else { + value = 1.0 - ((float) (i - maxAt)) / ((float) (SAMPLE_COUNT - maxAt)) * 2.0; + } + sample[i] = value; + } + float base = 40.0; + for (i = 0; i < OCTAVE_COUNT; i++) { + createPitches(base, octaves[i]); + base *= 2; + } + channelStates[0].noteIndex = 0; nextNote(0); + channelStates[1].noteIndex = 0; nextNote(1); + + pspAudioInit(); + pspAudioSetVolume(0, 0x4000, 0x4000); + pspAudioSetVolume(1, 0x4000, 0x4000); + pspAudioSetChannelCallback(0, audioOutCallback0, NULL); + pspAudioSetChannelCallback(1, audioOutCallback1, NULL); + sceKernelSleepThread(); + + return 0; +} diff --git a/src/samples/audio/wavegen/Makefile.sample b/src/samples/audio/wavegen/Makefile.sample new file mode 100644 index 00000000..90e6c6b0 --- /dev/null +++ b/src/samples/audio/wavegen/Makefile.sample @@ -0,0 +1,17 @@ +TARGET = alsample +OBJS = main.o + +INCDIR = +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = +LIBS = -lpspaudiolib -lpspaudio -lm + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Audiolib Wave Generator + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/audio/wavegen/main.c b/src/samples/audio/wavegen/main.c new file mode 100644 index 00000000..0ee5fe01 --- /dev/null +++ b/src/samples/audio/wavegen/main.c @@ -0,0 +1,200 @@ +/* + AudioLib Sample + + Demonstrates how to get sound working with minimal effort. + + Based on sdktest sample from pspsdk +*/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* + This part of the code is more or less identical to the sdktest sample +*/ + +/* Define the module info section */ +PSP_MODULE_INFO("AUDIOLIBDEMO", 0, 1, 1); +/* Define the main thread's attribute value (optional) */ +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU); +/* Define printf, just to make typing easier */ +#define printf pspDebugScreenPrintf + +/* Exit callback */ +int exitCallback(int arg1, int arg2, void *common) { + sceKernelExitGame(); + return 0; +} + +/* Callback thread */ +int callbackThread(SceSize args, void *argp) { + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", (void*) exitCallback, NULL); + sceKernelRegisterExitCallback(cbid); + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int setupCallbacks(void) { + int thid = 0; + + thid = sceKernelCreateThread("update_thread", callbackThread, 0x11, 0xFA0, 0, 0); + if (thid >= 0) { + sceKernelStartThread(thid, 0, 0); + } + return thid; +} + +/* + Below this point is the interesting code in this sample +*/ + +const float PI = 3.1415926535897932f; +const int sampleRate = 44100; +float frequency = 440.0f; +float time = 0; +int function = 0; + +typedef struct { + short l, r; +} sample_t; + +float currentFunction(const float time) { + double x; + float t = modf(time / (2 * PI), &x); + + switch(function) { + case 0: // SINE + return sinf(time); + case 1: // SQUARE + if (t < 0.5f) { + return -0.2f; + } else { + return 0.2f; + } + case 2: // TRIANGLE + if (t < 0.5f) { + return t * 2.0f - 0.5f; + } else { + return 0.5f - (t - 0.5f) * 2.0f; + } + default: + return 0.0f; + } +} + + +/* This function gets called by pspaudiolib every time the + audio buffer needs to be filled. The sample format is + 16-bit, stereo. */ +void audioCallback(void* buf, unsigned int length, void *userdata) { + const float sampleLength = 1.0f / sampleRate; + const float scaleFactor = SHRT_MAX - 1.0f; + static float freq0 = 440.0f; + sample_t* ubuf = (sample_t*) buf; + int i; + + if (frequency != freq0) { + time *= (freq0 / frequency); + } + for (i = 0; i < length; i++) { + short s = (short) (scaleFactor * currentFunction(2.0f * PI * frequency * time)); + ubuf[i].l = s; + ubuf[i].r = s; + time += sampleLength; + } + if (time * frequency > 1.0f) { + double d; + time = modf(time * frequency, &d) / frequency; + } + freq0 = frequency; +} + +/* Read the analog stick and adjust the frequency */ +void controlFrequency() { + static int oldButtons = 0; + const int zones[6] = {30, 70, 100, 112, 125, 130}; + const float response[6] = {0.0f, 0.1f, 0.5f, 1.0f, 4.0f, 8.0f}; + const float minFreq = 32.0f; + const float maxFreq = 7040.0f; + SceCtrlData pad; + float direction; + int changedButtons; + int i, v; + + sceCtrlReadBufferPositive(&pad, 1); + + v = pad.Ly - 128; + if (v < 0) { + direction = 1.0f; + v = -v; + } else { + direction = -1.0f; + } + + for (i = 0; i < 6; i++) { + if (v < zones[i]) { + frequency += response[i] * direction; + break; + } + } + + if (frequency < minFreq) { + frequency = minFreq; + } else if (frequency > maxFreq) { + frequency = maxFreq; + } + + changedButtons = pad.Buttons & (~oldButtons); + if (changedButtons & PSP_CTRL_CROSS) { + function++; + if (function > 2) { + function = 0; + } + } + oldButtons = pad.Buttons; +} + +int main(void) { + pspDebugScreenInit(); + setupCallbacks(); + + pspAudioInit(); + pspAudioSetChannelCallback(0, audioCallback, NULL); + + sceCtrlSetSamplingCycle(0); + sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG); + + printf("Press up and down to select frequency\nPress X to change function\n"); + + while(1) { + sceDisplayWaitVblankStart(); + pspDebugScreenSetXY(0,2); + printf("freq = %.2f \n", frequency); + switch(function) { + case 0: + printf("sine wave\n"); + break; + case 1: + printf("square wave\n"); + break; + case 2: + printf("triangle wave\n"); + break; + } + controlFrequency(); + } + return 0; +} diff --git a/src/samples/controller/basic/Makefile.sample b/src/samples/controller/basic/Makefile.sample new file mode 100644 index 00000000..2981b5c3 --- /dev/null +++ b/src/samples/controller/basic/Makefile.sample @@ -0,0 +1,16 @@ +TARGET = controller_basic +OBJS = main.o + +INCDIR = +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Basic controller sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/controller/basic/main.c b/src/samples/controller/basic/main.c new file mode 100644 index 00000000..6d2c298d --- /dev/null +++ b/src/samples/controller/basic/main.c @@ -0,0 +1,131 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Basic Input demo -- reads from control pad and indicates button + * presses. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * Copyright (c) 2005 Donour Sizemore + * + * $Id: main.c 1095 2005-09-27 21:02:16Z jim $ + */ +#include +#include +#include +#include +#include + +/* Define the module info section */ +PSP_MODULE_INFO("CONTROLTEST", 0, 1, 1); + +/* Define the main thread's attribute value (optional) */ +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU); + +/* Define printf, just to make typing easier */ +#define printf pspDebugScreenPrintf + +void dump_threadstatus(void); + +int done = 0; + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + done = 1; + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + + thid = sceKernelCreateThread("update_thread", CallbackThread, + 0x11, 0xFA0, 0, 0); + if(thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} + +int main(void) +{ + SceCtrlData pad; + + pspDebugScreenInit(); + SetupCallbacks(); + + sceCtrlSetSamplingCycle(0); + sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG); + + while(!done){ + pspDebugScreenSetXY(0, 2); + + sceCtrlReadBufferPositive(&pad, 1); + + printf("Analog X = %d ", pad.Lx); + printf("Analog Y = %d \n", pad.Ly); + + if (pad.Buttons != 0){ + if (pad.Buttons & PSP_CTRL_SQUARE){ + printf("Square pressed \n"); + } + if (pad.Buttons & PSP_CTRL_TRIANGLE){ + printf("Triangle pressed \n"); + } + if (pad.Buttons & PSP_CTRL_CIRCLE){ + printf("Cicle pressed \n"); + } + if (pad.Buttons & PSP_CTRL_CROSS){ + printf("Cross pressed \n"); + } + + if (pad.Buttons & PSP_CTRL_UP){ + printf("Up pressed \n"); + } + if (pad.Buttons & PSP_CTRL_DOWN){ + printf("Down pressed \n"); + } + if (pad.Buttons & PSP_CTRL_LEFT){ + printf("Left pressed \n"); + } + if (pad.Buttons & PSP_CTRL_RIGHT){ + printf("Right pressed \n"); + } + + if (pad.Buttons & PSP_CTRL_START){ + printf("Start pressed \n"); + } + if (pad.Buttons & PSP_CTRL_SELECT){ + printf("Select pressed \n"); + } + if (pad.Buttons & PSP_CTRL_LTRIGGER){ + printf("L-trigger pressed \n"); + } + if (pad.Buttons & PSP_CTRL_RTRIGGER){ + printf("R-trigger pressed \n"); + } + } + } + + sceKernelExitGame(); + return 0; +} diff --git a/src/samples/debug/debugkb/Makefile.sample b/src/samples/debug/debugkb/Makefile.sample new file mode 100644 index 00000000..1c9a382d --- /dev/null +++ b/src/samples/debug/debugkb/Makefile.sample @@ -0,0 +1,17 @@ +TARGET = debugkb +OBJS = main.o +LIBS = -lpspdebugkb + +INCDIR = +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Debug Screen Keyboard Example + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/debug/debugkb/main.c b/src/samples/debug/debugkb/main.c new file mode 100644 index 00000000..66bca7d4 --- /dev/null +++ b/src/samples/debug/debugkb/main.c @@ -0,0 +1,105 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * debugkb.c - Example of a simple screen debug keyboard + * + * Copyright (c) 2006 Mike Mallett + * + * $Id: main.c 2110 2006-12-19 14:50:27Z tyranid $ + */ + +#include +#include +#include +#include +#include +#include +#include + +/* Define the module info section */ +PSP_MODULE_INFO("Debug Screen Text Input", 0, 1, 1); + +/* Define the main thread's attribute value (optional) */ +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU); + +#define printf pspDebugScreenPrintf +#define setXY pspDebugScreenSetXY +#define setTextColor pspDebugScreenSetTextColor +#define setBackColor pspDebugScreenSetBackColor + +/* Exit callback */ +int exit_callback() +{ + sceKernelExitGame(); + + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + + thid = sceKernelCreateThread("update_thread", CallbackThread, + 0x11, 0xFA0, 0, 0); + if(thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} + + +int main(void) +{ + SetupCallbacks(); + + pspDebugScreenInit(); + + printf ("Debug Screen Text Input Box\n"); + printf("Press Left Trigger and Right Trigger to bring up the keyboard.\n"); + + char str[PSP_DEBUG_KB_MAXLEN]; + bzero(str, PSP_DEBUG_KB_MAXLEN); + + sceCtrlSetSamplingCycle(0); + sceCtrlSetSamplingMode(PSP_CTRL_MODE_DIGITAL); + + SceCtrlData input; + + while (1) { + sceCtrlReadBufferPositive(&input, 1); + + if (input.Buttons & PSP_CTRL_LTRIGGER && input.Buttons & PSP_CTRL_RTRIGGER) { + pspDebugKbInit(str); + + setTextColor(0xffffffff); + setBackColor(0x00000000); + setXY(0, 3); + printf("str = \"%s\"", str); + setXY(0, 4); + printf("str is %d characters long", strlen(str)); + } + } + + sceKernelSleepThread(); + + sceKernelExitGame(); + return 0; +} diff --git a/src/samples/debug/exception/Makefile.sample b/src/samples/debug/exception/Makefile.sample new file mode 100644 index 00000000..bea90d3d --- /dev/null +++ b/src/samples/debug/exception/Makefile.sample @@ -0,0 +1,16 @@ +TARGET = exception +OBJS = main.o + +INCDIR = +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Exception Example + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/debug/exception/main.c b/src/samples/debug/exception/main.c new file mode 100644 index 00000000..de12f7e3 --- /dev/null +++ b/src/samples/debug/exception/main.c @@ -0,0 +1,120 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Basic sample to demonstrate installing an exception handler. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: main.c 1095 2005-09-27 21:02:16Z jim $ + */ +#include +#include +#include +#include + +PSP_MODULE_INFO("EXTEST", 0x1000, 1, 1); +/* Define the main thread's attribute value (optional) */ +PSP_MAIN_THREAD_ATTR(0); + +/* Define printf, just to make typing easier */ +#define printf pspDebugScreenPrintf + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + sceKernelExitGame(); + + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, THREAD_ATTR_USER, 0); + if(thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} + +/* Example custom exception handler */ +void MyExceptionHandler(PspDebugRegBlock *regs) +{ + /* Do normal initial dump, setup screen etc */ + pspDebugScreenInit(); + + /* I always felt BSODs were more interesting that white on black */ + pspDebugScreenSetBackColor(0x00FF0000); + pspDebugScreenSetTextColor(0xFFFFFFFF); + pspDebugScreenClear(); + + pspDebugScreenPrintf("I regret to inform you your psp has just crashed\n"); + pspDebugScreenPrintf("Please contact Sony technical support for further information\n\n"); + pspDebugScreenPrintf("Exception Details:\n"); + pspDebugDumpException(regs); + pspDebugScreenPrintf("\nBlame the 3rd party software, it cannot possibly be our fault!\n"); +} + +int main(void) +{ + SceCtrlData pad; + pspDebugScreenInit(); + SetupCallbacks(); + + /* Install our custom exception handler. If this was NULL then the default would be used */ + pspDebugInstallErrorHandler(MyExceptionHandler); + sceCtrlSetSamplingCycle(0); + sceCtrlSetSamplingMode(PSP_CTRL_MODE_DIGITAL); + + pspDebugScreenPrintf("Exception Sample\n\n"); + pspDebugScreenPrintf("You have two choices, press O for a bus error or X for a breakpoint\n\n"); + + while(1) + { + sceCtrlReadBufferPositive(&pad, 1); + if(pad.Buttons & PSP_CTRL_CIRCLE) + { + /* Cause a bus error */ + _sw(0, 0); + } + + if(pad.Buttons & PSP_CTRL_CROSS) + { + /* Cause a break exception */ + asm( + "break\r\n" + ); + } + + sceDisplayWaitVblankStart(); + } + + + /* We will never end up here, hopefully */ + printf("End\n"); + + sceKernelExitDeleteThread(0); + + return 0; +} diff --git a/src/samples/debug/gdb/Makefile.sample b/src/samples/debug/gdb/Makefile.sample new file mode 100644 index 00000000..7ef87a55 --- /dev/null +++ b/src/samples/debug/gdb/Makefile.sample @@ -0,0 +1,21 @@ +TARGET = gdb +OBJS = main.o + +USE_PSPSDK_LIBC = 1 + +INCDIR = +CFLAGS = -O0 -G0 -Wall -ggdb +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBS = -lpspgdb -lpspgdb_user +LIBDIR = +LDFLAGS = + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = GDB + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak + +LIBS += -lpsphprm_driver diff --git a/src/samples/debug/gdb/main.c b/src/samples/debug/gdb/main.c new file mode 100644 index 00000000..cf9aef0d --- /dev/null +++ b/src/samples/debug/gdb/main.c @@ -0,0 +1,114 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Basic sample to demonstrate installing an exception handler. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: main.c 1095 2005-09-27 21:02:16Z jim $ + */ +#include +#include +#include +#include +#include + +PSP_MODULE_INFO("EXTEST", 0x1000, 1, 1); +/* Define the main thread's attribute value (optional) */ +PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER); + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + sceKernelExitGame(); + + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, THREAD_ATTR_USER, 0); + if(thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} + +/* Initialise SIO and GDB */ +__attribute__((constructor)) +void loaderInit() +{ + pspDebugScreenInit(); + pspDebugScreenPrintf("Initialising serial port\n"); + pspKernelSetKernelPC(); + pspDebugSioSetBaud(38400); + pspDebugSioInit(); + pspDebugGdbStubInit(); +} + +int main(void) +{ + SceCtrlData pad; + + pspDebugScreenPrintf("App Started\n"); + SetupCallbacks(); + + /* Generate a breakpoint to trap into GDB */ + pspDebugBreakpoint(); + + sceCtrlSetSamplingCycle(0); + sceCtrlSetSamplingMode(PSP_CTRL_MODE_DIGITAL); + + printf("Exception Sample\n\n"); + printf("You have two choices, press O for a bus error or X for a breakpoint\n\n"); + + while(1) + { + sceCtrlReadBufferPositive(&pad, 1); + if(pad.Buttons & PSP_CTRL_CIRCLE) + { + /* Cause a bus error */ + _sw(0, 0); + } + + if(pad.Buttons & PSP_CTRL_CROSS) + { + /* Cause a break exception */ + asm( + "break\r\n" + ); + } + + sceDisplayWaitVblankStart(); + } + + + /* We will never end up here, hopefully */ + printf("End\n"); + + sceKernelSleepThread(); + + return 0; +} diff --git a/src/samples/debug/kprintf/Makefile.sample b/src/samples/debug/kprintf/Makefile.sample new file mode 100644 index 00000000..55a31897 --- /dev/null +++ b/src/samples/debug/kprintf/Makefile.sample @@ -0,0 +1,16 @@ +TARGET = kptest +OBJS = main.o + +INCDIR = +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Kprintf Test + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/debug/kprintf/main.c b/src/samples/debug/kprintf/main.c new file mode 100644 index 00000000..28176ed3 --- /dev/null +++ b/src/samples/debug/kprintf/main.c @@ -0,0 +1,81 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Basic sample to demonstrate the kprintf handler. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: main.c 1095 2005-09-27 21:02:16Z jim $ + */ +#include +#include + +PSP_MODULE_INFO("KPTEST", 0x1000, 1, 1); +/* Define the main thread's attribute value (optional) */ +PSP_MAIN_THREAD_ATTR(0); + +/* Define printf, just to make typing easier */ +#define printf pspDebugScreenPrintf + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + sceKernelExitGame(); + + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, THREAD_ATTR_USER, 0); + if(thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} + +int main(void) +{ + pspDebugScreenInit(); + SetupCallbacks(); + + printf("Kprintf Example:\n\n"); + + pspDebugInstallKprintfHandler(NULL); + + printf("Lets test a kernel function error report\n"); + pspDebugScreenSetTextColor(0xFF); + /* Try and load a module, this should print an error to the screen */ + sceKernelLoadModule("test:/this/is/not/a/file.prx", 0, NULL); + pspDebugScreenSetTextColor(0xFFFFFFFF); + printf("\nLets call Kprintf directly\n"); + pspDebugScreenSetTextColor(0xFF); + Kprintf("Hello from Kprintf\n"); + + /* Let's bug out */ + sceKernelExitDeleteThread(0); + + return 0; +} diff --git a/src/samples/debug/profiler/Makefile.sample b/src/samples/debug/profiler/Makefile.sample new file mode 100644 index 00000000..15d52d81 --- /dev/null +++ b/src/samples/debug/profiler/Makefile.sample @@ -0,0 +1,16 @@ +TARGET = profiler +OBJS = main.o + +INCDIR = +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Profiler Test + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/debug/profiler/main.c b/src/samples/debug/profiler/main.c new file mode 100644 index 00000000..d1740378 --- /dev/null +++ b/src/samples/debug/profiler/main.c @@ -0,0 +1,85 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Basic sample to demonstrate the profiler + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: main.c 1095 2005-09-27 21:02:16Z jim $ + */ +#include +#include +#include +#include + +PSP_MODULE_INFO("PROFILER", 0x1000, 1, 1); +/* Define the main thread's attribute value (optional) */ +PSP_MAIN_THREAD_ATTR(0); + +/* Define printf, just to make typing easier */ +#define printf pspDebugScreenPrintf + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + sceKernelExitGame(); + + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, THREAD_ATTR_USER, 0); + if(thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} + +int main(void) +{ + int i; + + pspDebugScreenInit(); + SetupCallbacks(); + + /* Clear the existing profile regs */ + pspDebugProfilerClear(); + /* Enable profiling */ + pspDebugProfilerEnable(); + + for(i = 0; i < 600; i++) + { + pspDebugScreenSetXY(0, 0); + /* Print profile information to the screen */ + pspDebugProfilerPrint(); + sceDisplayWaitVblankStart(); + } + + /* Let's bug out */ + sceKernelExitDeleteThread(0); + + return 0; +} diff --git a/src/samples/debug/prxdecrypt/Makefile.sample b/src/samples/debug/prxdecrypt/Makefile.sample new file mode 100644 index 00000000..9cae73a9 --- /dev/null +++ b/src/samples/debug/prxdecrypt/Makefile.sample @@ -0,0 +1,16 @@ +TARGET = prxdecrypt +OBJS = main.o + +INCDIR = +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = PRX Decrypter + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/debug/prxdecrypt/main.c b/src/samples/debug/prxdecrypt/main.c new file mode 100644 index 00000000..00c78c7d --- /dev/null +++ b/src/samples/debug/prxdecrypt/main.c @@ -0,0 +1,179 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Basic sample to erm do something. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: main.c 1095 2005-09-27 21:02:16Z jim $ + */ +#include +#include +#include +#include + +/* Define the module info section */ +PSP_MODULE_INFO("PRXDecryptor", 0x1000, 1, 0); + +/* Define the main thread's attribute value (optional) */ +PSP_MAIN_THREAD_ATTR(0); + +/* Define printf, just to make typing easier */ +#define printf pspDebugScreenPrintf + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + sceKernelExitGame(); + + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, THREAD_ATTR_USER, 0); + if(thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} + +/* ptr is a pointer to the file to decrypt, check is undocumented, look at decrypt_file to see how to use */ +int sceKernelCheckExecFile(void *ptr, void *check); + +char g_data[0x400000] __attribute__((aligned(64))); +char g_decrypt_buf[0x400000] __attribute__((aligned(64))); + +/* Decrypt a single PRX file */ +int extract_file(const char* name, const char* dstname) +{ + int fd; + int ret = 0; + + fd = sceIoOpen(name, PSP_O_RDONLY, 0777); + if(fd >= 0) + { + int bytes_read; + bytes_read = sceIoRead(fd, g_data, 4*1024*1024); + sceIoClose(fd); + if(bytes_read > 0) + { + u8 check[0x100]; + u32 size; + char *output; + + memset(check, 0, sizeof(check)); + sceKernelCheckExecFile(g_data, check); + /* Get size of data block */ + size = *(unsigned int *) (check+0x5C); + + /* Check if we managed to decrypt the file */ + if(*(unsigned short *)(check+0x5a) & 1) + { + /* Set decrypt buffer pointer */ + *(unsigned int*)(check+0x24) = (unsigned int) g_decrypt_buf; + sceKernelCheckExecFile(g_data, check); + output = g_decrypt_buf; + } + else + { + output = g_data; + } + + if(size >= 0) + { + printf("Extracted file - size %d\n", size); + fd = sceIoOpen(dstname, PSP_O_WRONLY | PSP_O_CREAT | PSP_O_TRUNC, 0777); + if(fd >= 0) + { + sceIoWrite(fd, output, size); + sceIoClose(fd); + ret = 1; + } + } + else + { + printf("Extract failed %s\n", name); + } + } + else + { + printf("Couldn't read file\n"); + } + } + else + { + printf("Couldn't open file\n"); + } + + return ret; +} + +SceIoDirent g_dir; +char g_infile[256]; +char g_outfile[256]; + +void decrypt_files(const char *basedir, const char *destdir) +{ + int fd; + + printf("%s\n", basedir); + fd = sceIoDopen(basedir); + if(fd >= 0) + { + while(sceIoDread(fd, &g_dir) > 0) + { + if((g_dir.d_stat.st_attr & FIO_SO_IFDIR) == 0) + { + strcpy(g_infile, basedir); + strcat(g_infile, g_dir.d_name); + strcpy(g_outfile, destdir); + strcat(g_outfile, g_dir.d_name); + printf("Decrypting %s to %s\n", g_infile, g_outfile); + extract_file(g_infile, g_outfile); + } + } + + sceIoDclose(fd); + } +} + +int main(void) +{ + pspDebugScreenInit(); + SetupCallbacks(); + + /* Decrypt kernel modules */ + sceIoMkdir("ms0:/kd", 0777); + decrypt_files("flash0:/kd/", "ms0:/kd/"); + /* Decrypt VShell modules */ + sceIoMkdir("ms0:/vsh", 0777); + decrypt_files("flash0:/vsh/module/", "ms0:/vsh/"); + + printf("Done\n"); + sceKernelExitDeleteThread(0); + + return 0; +} diff --git a/src/samples/debug/sio/Makefile.sample b/src/samples/debug/sio/Makefile.sample new file mode 100644 index 00000000..4902a6af --- /dev/null +++ b/src/samples/debug/sio/Makefile.sample @@ -0,0 +1,21 @@ +TARGET = sio +OBJS = main.o + +USE_PSPSDK_LIBC = 1 + +INCDIR = +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = + + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = SIO Test + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak + +LIBS += -lpsphprm_driver diff --git a/src/samples/debug/sio/main.c b/src/samples/debug/sio/main.c new file mode 100644 index 00000000..d1fcb7db --- /dev/null +++ b/src/samples/debug/sio/main.c @@ -0,0 +1,76 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Basic sample to demonstrate the remote port sio. + * + * Copyright (c) 2005 James Forshaw + * + * $Id: main.c 1095 2005-09-27 21:02:16Z jim $ + */ +#include +#include +#include +#include +#include +#include +#include + +PSP_MODULE_INFO("REMOTE", 0x1000, 1, 1); +/* Define the main thread's attribute value (optional) */ +PSP_MAIN_THREAD_ATTR(0); + +int main(void) +{ + pspDebugScreenInit(); + + sceCtrlSetSamplingCycle(0); + sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG); + + /* Initialise SIO and install a kprintf handler */ + pspDebugSioInit(); + pspDebugSioInstallKprintf(); + + /* Install a stdout handler */ + pspDebugInstallStdoutHandler(pspDebugSioPutData); + + Kprintf("Hi from %s!\n", "Kprintf"); + printf("Also hi from stdio\r\n"); + + pspDebugScreenPrintf("Press X to exit, tap away on your terminal to echo\n"); + sceDisplayWaitVblankStart(); + + while(1) + { + SceCtrlData pad; + int ch; + + sceCtrlReadBufferPositive(&pad, 1); + if(pad.Buttons & PSP_CTRL_CROSS) + { + break; + } + + ch = pspDebugSioGetchar(); + if(ch >= 0) + { + pspDebugScreenPrintf("Received %d\n", ch); + if(ch == '\r') + { + pspDebugSioPutchar('\r'); + pspDebugSioPutchar('\n'); + } + else + { + pspDebugSioPutchar(ch); + } + } + + sceDisplayWaitVblankStart(); + } + + sceKernelExitGame(); + + return 0; +} diff --git a/src/samples/debug/sio/readme.txt b/src/samples/debug/sio/readme.txt new file mode 100644 index 00000000..e398636d --- /dev/null +++ b/src/samples/debug/sio/readme.txt @@ -0,0 +1,7 @@ +This is a simple demo of the SIO code. + +The serial interface used is the remote control port, see http://nil.rpc1.org/psp/remote.html +for how to build the interface. You should setup your local terminal software to 4800 baud +8N1 to communicate. + +Note this comes with no warranty, if it blows up your psp it is not my resposibility. diff --git a/src/samples/gu/beginobject/Makefile.sample b/src/samples/gu/beginobject/Makefile.sample new file mode 100644 index 00000000..99ff5e13 --- /dev/null +++ b/src/samples/gu/beginobject/Makefile.sample @@ -0,0 +1,18 @@ +TARGET = beginobject +OBJS = beginobject.o ../common/callbacks.o + +INCDIR = +CFLAGS = -G0 -Wall -O2 +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = +LIBS= -lpspgum -lpspgu -lm + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = BeginObject Sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak + diff --git a/src/samples/gu/beginobject/beginobject.c b/src/samples/gu/beginobject/beginobject.c new file mode 100644 index 00000000..52dd5327 --- /dev/null +++ b/src/samples/gu/beginobject/beginobject.c @@ -0,0 +1,244 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * beginobject.c Shows the usage of sceGuBeginObject/sceGuEndObject + * + * Copyright (c) 2007 McZonk + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "../common/callbacks.h" + +PSP_MODULE_INFO("BeginObject", 0, 1, 1); +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER); + +static unsigned int __attribute__((aligned(16))) list[262144]; + +typedef struct VERT { + float vertex[3]; +} VERT; + +#define BUF_WIDTH (512) +#define SCR_WIDTH (480) +#define SCR_HEIGHT (272) +#define PIXEL_SIZE (4) /* change this if you change to another screenmode */ +#define FRAME_SIZE (BUF_WIDTH * SCR_HEIGHT * PIXEL_SIZE) +#define ZBUF_SIZE (BUF_WIDTH SCR_HEIGHT * 2) /* zbuffer seems to be 16-bit? */ + +#define TORUS_SLICES 24 // numc +#define TORUS_ROWS 24 // numt +#define TORUS_RADIUS 1.0f +#define TORUS_THICKNESS 0.5f + +#define LIGHT_DISTANCE 3.0f + +static VERT __attribute__((aligned(16))) torus_v0[TORUS_SLICES * TORUS_ROWS]; +static unsigned short __attribute__((aligned(16))) torus_in[TORUS_SLICES * TORUS_ROWS * 6]; + +static unsigned int colors[6] = { + 0xffff0000, + 0xffffff00, + 0xff00ff00, + 0xff00ffff, + 0xff0000ff, + 0xffff00ff +}; + +static float __attribute__((aligned(16))) bbox[8][3] = { + { -1.0f, -1.0f, -1.0f }, + { -1.0f, -1.0f, 1.0f }, + { -1.0f, 1.0f, -1.0f }, + { -1.0f, 1.0f, 1.0f }, + { 1.0f, -1.0f, -1.0f }, + { 1.0f, -1.0f, 1.0f }, + { 1.0f, 1.0f, -1.0f }, + { 1.0f, 1.0f, 1.0f } +}; + +unsigned int objects = 0; + +void gucallback(int id) { + objects++; +} + +int main(int argc, char* argv[]) { + /* Setup Homebutton Callbacks */ + setupCallbacks(); + + /* Generate Torus */ + unsigned int i,j; + for (j = 0; j < TORUS_SLICES; ++j) { + for (i = 0; i < TORUS_ROWS; ++i) { + VERT* v0 = &torus_v0[i + j*TORUS_ROWS]; + + float s = i + 0.5f; + float t = j; + float cs,ct,ss,st; + + cs = cosf(s * (2*GU_PI)/TORUS_SLICES); + ct = cosf(t * (2*GU_PI)/TORUS_ROWS); + ss = sinf(s * (2*GU_PI)/TORUS_SLICES); + st = sinf(t * (2*GU_PI)/TORUS_ROWS); + + v0->vertex[0] = (TORUS_RADIUS + TORUS_THICKNESS * cs) * ct; + v0->vertex[1] = (TORUS_RADIUS + TORUS_THICKNESS * cs) * st; + v0->vertex[2] = TORUS_THICKNESS * ss; + } + } + for (j = 0; j < TORUS_SLICES; ++j) { + for (i = 0; i < TORUS_ROWS; ++i) { + unsigned short* in = &torus_in[(i+(j*TORUS_ROWS))*6]; + unsigned int i1 = (i+1)%TORUS_ROWS, j1 = (j+1)%TORUS_SLICES; + + *in++ = i + j * TORUS_ROWS; + *in++ = i1 + j * TORUS_ROWS; + *in++ = i + j1 * TORUS_ROWS; + + *in++ = i1 + j * TORUS_ROWS; + *in++ = i1 + j1 * TORUS_ROWS; + *in++ = i + j1 * TORUS_ROWS; + } + } + + sceKernelDcacheWritebackAll(); + + // setup GU + + SceCtrlData pad; + sceCtrlSetSamplingCycle(0); + sceCtrlSetSamplingMode(PSP_CTRL_MODE_DIGITAL); + + sceGuInit(); + + sceGuStart(GU_DIRECT,list); + sceGuDrawBuffer(GU_PSM_8888,(void*)0,BUF_WIDTH); + sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,(void*)0x88000,BUF_WIDTH); + sceGuDepthBuffer((void*)0x110000,BUF_WIDTH); + sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); + sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); + sceGuDepthRange(0xc350,0x2710); + sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + sceGuDepthFunc(GU_GEQUAL); + sceGuEnable(GU_DEPTH_TEST); + sceGuFrontFace(GU_CW); + sceGuShadeModel(GU_SMOOTH); + sceGuEnable(GU_CULL_FACE); + sceGuEnable(GU_CLIP_PLANES); + sceGuSetCallback(GU_CALLBACK_SIGNAL, gucallback); + sceGuFinish(); + sceGuSync(0,0); + sceDisplayWaitVblankStart(); + sceGuDisplay(GU_TRUE); + + float time = 0.0f; + + void* buffer = 0; + + pspDebugScreenInit(); + + unsigned int old = 0; + unsigned int flags = PSP_CTRL_CIRCLE | PSP_CTRL_CROSS; + + while(running()) { + objects = 0; + time += 0.01f; + + sceGuStart(GU_DIRECT,list); + + sceGuClearColor(0); + sceGuClearDepth(0); + sceGuClear(GU_COLOR_BUFFER_BIT | GU_DEPTH_BUFFER_BIT); + + sceGumMatrixMode(GU_PROJECTION); + sceGumLoadIdentity(); + sceGumPerspective(90.0f,16.0/9.0f, 0.1f,100.0f); + + sceGumMatrixMode(GU_VIEW); + sceGumLoadIdentity(); + + sceGumMatrixMode(GU_MODEL); + sceGumLoadIdentity(); + + unsigned int i; + for(i = 0; i < 12; i++) { + sceGumPushMatrix(); + + float r = (((float)i / (float)12) * M_PI * 2.0f) + time; + sceGumRotateY(r); + ScePspFVector3 t = { 0.0f, 0.0f, 8.0f }; + sceGumTranslate(&t); + + // Draw Bounding Box + if(flags & PSP_CTRL_CIRCLE || 1) { + sceGuColor(0xffffffff); + sceGumDrawArray(GU_POINTS, GU_VERTEX_32BITF | GU_TRANSFORM_3D, 8, 0, bbox); + } + + // Begin Object + if(flags & PSP_CTRL_CROSS) { + sceGuBeginObject(GU_VERTEX_32BITF, 8, 0, bbox); + } + + sceGuSignal(1, GU_BEHAVIOR_SUSPEND); + + sceGumPushMatrix(); + sceGumRotateX(time * 0.5324f); + sceGumRotateY(time * 1.2211f); + + sceGuColor(colors[i%6]); + sceGumDrawArray(GU_TRIANGLES, + GU_VERTEX_32BITF | GU_INDEX_16BIT | GU_TRANSFORM_3D, + sizeof(torus_in)/sizeof(unsigned short), torus_in, torus_v0 + ); + + sceGumPopMatrix(); + + // End Object + if(flags & PSP_CTRL_CROSS) { + sceGuEndObject(); + } + + sceGumPopMatrix(); + } + + sceGuFinish(); + sceGuSync(0,0); + + pspDebugScreenSetOffset((int)buffer); + pspDebugScreenSetXY(0,0); + if(flags & PSP_CTRL_CROSS) { + pspDebugScreenPrintf("Use culling. X to toogle. %d objects", objects); + } else { + pspDebugScreenPrintf("Don't use culling. X to toogle. %d objects", objects); + } + + sceDisplayWaitVblankStart(); + buffer = sceGuSwapBuffers(); + + sceCtrlReadBufferPositive(&pad, 1); + if(old != pad.Buttons) { + flags ^= pad.Buttons; + } + old = pad.Buttons; + } + + sceGuTerm(); + + sceKernelExitGame(); + return 0; +} diff --git a/src/samples/gu/blend/Makefile.sample b/src/samples/gu/blend/Makefile.sample new file mode 100644 index 00000000..74bfe8bd --- /dev/null +++ b/src/samples/gu/blend/Makefile.sample @@ -0,0 +1,17 @@ +TARGET = blend +OBJS = blend.o ../common/callbacks.o ../common/vram.o + +INCDIR = +CFLAGS = -G0 -Wall -O2 +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = +LIBS= -lpspgu + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Blend Sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/gu/blend/blend.c b/src/samples/gu/blend/blend.c new file mode 100644 index 00000000..ca120d39 --- /dev/null +++ b/src/samples/gu/blend/blend.c @@ -0,0 +1,198 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "../common/callbacks.h" +#include "../common/vram.h" + +PSP_MODULE_INFO("Blend Sample", 0, 1, 1); +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER); + +static unsigned int __attribute__((aligned(16))) list[262144]; + +struct Vertex +{ + float u,v; + unsigned int color; + float x,y,z; +}; + +struct BlendState +{ + char* name; + int op; + int src; + int dest; + unsigned int srcfix; + unsigned int destfix; +}; + +#define BUF_WIDTH (512) +#define SCR_WIDTH (480) +#define SCR_HEIGHT (272) + +#define NUM_SLICES 128 +#define NUM_ROWS 128 +#define RING_SIZE 2.0f +#define RING_RADIUS 1.0f +#define SPRITE_SIZE 0.025f + +unsigned int __attribute__((aligned(16))) clut256[256]; +unsigned char __attribute__((aligned(16))) tex256[256*256]; + +struct BlendState states[] = +{ + {"GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA", GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0}, + {"GU_SUBTRACT, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA", GU_SUBTRACT, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0}, + {"GU_ALPHA_ADD, GU_SRC_COLOR, GU_DST_COLOR", GU_ADD, GU_SRC_COLOR, GU_DST_COLOR, 0, 0}, + {"GU_ADD, GU_FIX(0x700f7f7f), GU_FIX(0x3f3f3f00)", GU_ADD, GU_FIX, GU_FIX, 0x7f007f7f, 0x3f3f3f00}, + {"GU_ADD, GU_FIX(0x7f7f7f7f), GU_FIX(0x7f7f7f7f)", GU_ADD, GU_FIX, GU_FIX, 0x7f7f7f7f, 0x7f7f7f7f} +}; +int curr_state = 0; +float blend_time = 0; + +#define BLEND_LENGTH 5.0f + +int main(int argc, char* argv[]) +{ + unsigned int i,j; + float start, curr; + struct timeval tval; + + setupCallbacks(); + + // initialize texture + + for (j = 0; j < 256; ++j) + { + for (i = 0; i < 256; ++i) + { + tex256[i + j * 256] = j & i; + } + } + + sceKernelDcacheWritebackAll(); + + pspDebugScreenInit(); + + // setup GU + + void* fbp0 = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_8888); + void* fbp1 = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_8888); + void* zbp = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_4444); + + sceGuInit(); + sceGuStart(GU_DIRECT,list); + + sceGuDrawBuffer(GU_PSM_8888,fbp0,BUF_WIDTH); + sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,fbp1,BUF_WIDTH); + sceGuDepthBuffer(zbp,BUF_WIDTH); + sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); + sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); + sceGuDepthRange(0xc350,0x2710); + sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + sceGuFrontFace(GU_CW); + sceGuEnable(GU_TEXTURE_2D); + sceGuEnable(GU_BLEND); + sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuDisplay(GU_TRUE); + + // run sample + + int offset = 0; + + gettimeofday(&tval,0); + curr = start = tval.tv_sec + (((float)tval.tv_usec) / 1000000); + + while(running()) + { + sceGuStart(GU_DIRECT,list); + + // animate palette + + unsigned int* clut = (unsigned int*)(((unsigned int)clut256)|0x40000000); + for (i = 0; i < 256; ++i) + { + unsigned int j = (i + offset)&0xff; + *(clut++) = (j << 24)|(j << 16)|(j << 8)|(j); + } + + // clear screen + + sceGuClearColor(0xff00ff); + sceGuClear(GU_COLOR_BUFFER_BIT); + + // setup blend-mode + + sceGuBlendFunc(states[curr_state].op,states[curr_state].src,states[curr_state].dest,states[curr_state].srcfix,states[curr_state].destfix); + + // setup CLUT texture + + sceGuClutMode(GU_PSM_8888,0,0xff,0); // 32-bit palette + sceGuClutLoad((256/8),clut256); // upload 32*8 entries (256) + sceGuTexMode(GU_PSM_T8,0,0,0); // 8-bit image + sceGuTexImage(0,256,256,256,tex256); + sceGuTexFunc(GU_TFX_REPLACE,GU_TCC_RGBA); + sceGuTexFilter(GU_LINEAR,GU_LINEAR); + sceGuTexScale(1.0f,1.0f); + sceGuTexOffset(0.0f,0.0f); + sceGuAmbientColor(0xffffffff); + + // render sprite + + sceGuColor(0xffffffff); + struct Vertex* vertices = (struct Vertex*)sceGuGetMemory(2 * sizeof(struct Vertex)); + vertices[0].u = 0; vertices[0].v = 0; + vertices[0].x = 0; vertices[0].y = 0; vertices[0].z = 0; + vertices[1].u = 256; vertices[1].v = 256; + vertices[1].x = 480; vertices[1].y = 272; vertices[1].z = 0; + sceGuDrawArray(GU_SPRITES,GU_TEXTURE_32BITF|GU_COLOR_8888|GU_VERTEX_32BITF|GU_TRANSFORM_2D,2,0,vertices); + + // switch blend-modes if time has expired + + gettimeofday(&tval,0); + curr = tval.tv_sec + (((float)tval.tv_usec) / 1000000); + if ((curr-start) >= BLEND_LENGTH) + { + curr_state = (curr_state + 1) % (sizeof(states)/sizeof(struct BlendState)); + start = curr; + } + + // wait for next frame + + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuSwapBuffers(); + pspDebugScreenSetXY(0,0); + pspDebugScreenPrintf("%s",states[curr_state].name); + + offset++; + } + + sceGuTerm(); + + sceKernelExitGame(); + return 0; +} diff --git a/src/samples/gu/blit/Makefile.sample b/src/samples/gu/blit/Makefile.sample new file mode 100644 index 00000000..33d6e7af --- /dev/null +++ b/src/samples/gu/blit/Makefile.sample @@ -0,0 +1,17 @@ +TARGET = blit +OBJS = blit.o ../common/callbacks.o ../common/vram.o + +INCDIR = +CFLAGS = -G0 -Wall -O2 +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = +LIBS= -lpspgum -lpspgu -lpsprtc + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Blit Sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/gu/blit/blit.c b/src/samples/gu/blit/blit.c new file mode 100644 index 00000000..bf6842c1 --- /dev/null +++ b/src/samples/gu/blit/blit.c @@ -0,0 +1,248 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "../common/callbacks.h" +#include "../common/vram.h" + +PSP_MODULE_INFO("Blit Sample", 0, 1, 1); +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER); + +static unsigned int __attribute__((aligned(16))) list[262144]; + +#define BUF_WIDTH (512) +#define SCR_WIDTH (480) +#define SCR_HEIGHT (272) + +static unsigned short __attribute__((aligned(16))) pixels[BUF_WIDTH*SCR_HEIGHT]; +static unsigned short __attribute__((aligned(16))) swizzled_pixels[BUF_WIDTH*SCR_HEIGHT]; + +struct Vertex +{ + unsigned short u, v; + unsigned short color; + short x, y, z; +}; + +void simpleBlit(int sx, int sy, int sw, int sh, int dx, int dy) +{ + // simple blit, this just copies A->B, with all the cache-misses that apply + + struct Vertex* vertices = (struct Vertex*)sceGuGetMemory(2 * sizeof(struct Vertex)); + + vertices[0].u = sx; vertices[0].v = sy; + vertices[0].color = 0; + vertices[0].x = dx; vertices[0].y = dy; vertices[0].z = 0; + + vertices[1].u = sx+sw; vertices[1].v = sy+sh; + vertices[1].color = 0; + vertices[1].x = dx+sw; vertices[1].y = dy+sh; vertices[1].z = 0; + + sceGuDrawArray(GU_SPRITES,GU_TEXTURE_16BIT|GU_COLOR_4444|GU_VERTEX_16BIT|GU_TRANSFORM_2D,2,0,vertices); +} + +void advancedBlit(int sx, int sy, int sw, int sh, int dx, int dy, int slice) +{ + int start, end; + + // blit maximizing the use of the texture-cache + + for (start = sx, end = sx+sw; start < end; start += slice, dx += slice) + { + struct Vertex* vertices = (struct Vertex*)sceGuGetMemory(2 * sizeof(struct Vertex)); + int width = (start + slice) < end ? slice : end-start; + + vertices[0].u = start; vertices[0].v = sy; + vertices[0].color = 0; + vertices[0].x = dx; vertices[0].y = dy; vertices[0].z = 0; + + vertices[1].u = start + width; vertices[1].v = sy + sh; + vertices[1].color = 0; + vertices[1].x = dx + width; vertices[1].y = dy + sh; vertices[1].z = 0; + + sceGuDrawArray(GU_SPRITES,GU_TEXTURE_16BIT|GU_COLOR_4444|GU_VERTEX_16BIT|GU_TRANSFORM_2D,2,0,vertices); + } +} + +void swizzle_fast(u8* out, const u8* in, unsigned int width, unsigned int height) +{ + unsigned int blockx, blocky; + unsigned int j; + + unsigned int width_blocks = (width / 16); + unsigned int height_blocks = (height / 8); + + unsigned int src_pitch = (width-16)/4; + unsigned int src_row = width * 8; + + const u8* ysrc = in; + u32* dst = (u32*)out; + + for (blocky = 0; blocky < height_blocks; ++blocky) + { + const u8* xsrc = ysrc; + for (blockx = 0; blockx < width_blocks; ++blockx) + { + const u32* src = (u32*)xsrc; + for (j = 0; j < 8; ++j) + { + *(dst++) = *(src++); + *(dst++) = *(src++); + *(dst++) = *(src++); + *(dst++) = *(src++); + src += src_pitch; + } + xsrc += 16; + } + ysrc += src_row; + } +} + +const char* modes[] = +{ + "normal, linear", + "optimized, linear", + "normal, swizzled", + "optimized, swizzled" +}; + +int main(int argc, char* argv[]) +{ + unsigned int x,y; + + pspDebugScreenInit(); + setupCallbacks(); + + // Setup GU + + void* fbp0 = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_8888); + void* fbp1 = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_8888); + void* zbp = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_4444); + + sceGuInit(); + + sceGuStart(GU_DIRECT,list); + sceGuDrawBuffer(GU_PSM_8888,fbp0,BUF_WIDTH); + sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,fbp1,BUF_WIDTH); + sceGuDepthBuffer(zbp,BUF_WIDTH); + sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); + sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); + sceGuDepthRange(65535,0); + sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + sceGuFrontFace(GU_CW); + sceGuEnable(GU_TEXTURE_2D); + sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuDisplay(1); + + // generate dummy image to blit + + for (y = 0; y < SCR_HEIGHT; ++y) + { + unsigned short* row = &pixels[y * BUF_WIDTH]; + for (x = 0; x < SCR_WIDTH; ++x) + { + row[x] = x * y; + } + } + + swizzle_fast((u8*)swizzled_pixels,(const u8*)pixels,BUF_WIDTH*2,SCR_HEIGHT); // 512*2 because swizzle operates in bytes, and each pixel in a 16-bit texture is 2 bytes + + sceKernelDcacheWritebackAll(); + + float curr_ms = 1.0f; + int blit_method = 0; + int swizzle = 0; + SceCtrlData oldPad; + oldPad.Buttons = 0; + + sceCtrlSetSamplingCycle(0); + sceCtrlSetSamplingMode(0); + + u64 last_tick; + sceRtcGetCurrentTick(&last_tick); + u32 tick_frequency = sceRtcGetTickResolution(); + int frame_count = 0; + + while(running()) + { + SceCtrlData pad; + + sceGuStart(GU_DIRECT,list); + + // switch methods if requested + + if(sceCtrlPeekBufferPositive(&pad, 1)) + { + if (pad.Buttons != oldPad.Buttons) + { + if(pad.Buttons & PSP_CTRL_CROSS) + blit_method ^= 1; + if(pad.Buttons & PSP_CTRL_CIRCLE) + swizzle ^= 1; + } + oldPad = pad; + } + + sceGuTexMode(GU_PSM_4444,0,0,swizzle); // 16-bit RGBA + sceGuTexImage(0,512,512,512,swizzle ? swizzled_pixels : pixels); // setup texture as a 512x512 texture, even though the buffer is only 512x272 (480 visible) + sceGuTexFunc(GU_TFX_REPLACE,GU_TCC_RGBA); // don't get influenced by any vertex colors + sceGuTexFilter(GU_NEAREST,GU_NEAREST); // point-filtered sampling + + if (blit_method) + advancedBlit(0,0,SCR_WIDTH,SCR_HEIGHT,0,0,32); + else + simpleBlit(0,0,SCR_WIDTH,SCR_HEIGHT,0,0); + + sceGuFinish(); + sceGuSync(0,0); + + float curr_fps = 1.0f / curr_ms; + + pspDebugScreenSetOffset((int)fbp0); + pspDebugScreenSetXY(0,0); + pspDebugScreenPrintf("fps: %d.%03d (%dMB/s) (X = mode, O = swizzle) %s",(int)curr_fps,(int)((curr_fps-(int)curr_fps) * 1000.0f),(((int)curr_fps * SCR_WIDTH * SCR_HEIGHT * 2)/(1024*1024)),modes[blit_method + swizzle * 2]); + +// sceDisplayWaitVblankStart(); + fbp0 = sceGuSwapBuffers(); + + // simple frame rate counter + + ++frame_count; + u64 curr_tick; + sceRtcGetCurrentTick(&curr_tick); + if ((curr_tick-last_tick) >= tick_frequency) + { + float time_span = ((int)(curr_tick-last_tick)) / (float)tick_frequency; + curr_ms = time_span / frame_count; + + frame_count = 0; + sceRtcGetCurrentTick(&last_tick); + } + } + + sceGuTerm(); + + sceKernelExitGame(); + return 0; +} diff --git a/src/samples/gu/celshading/Makefile.sample b/src/samples/gu/celshading/Makefile.sample new file mode 100644 index 00000000..f9a03c79 --- /dev/null +++ b/src/samples/gu/celshading/Makefile.sample @@ -0,0 +1,20 @@ +TARGET = celshading +OBJS = lightmap.o celshading.o ../common/callbacks.o + +INCDIR = +CFLAGS = -G0 -Wall -O2 +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = +LIBS= -lpspgum -lpspgu -lm + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Celshading Sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak + +lightmap.o : lightmap.raw + bin2o -i lightmap.raw lightmap.o lightmap diff --git a/src/samples/gu/celshading/celshading.c b/src/samples/gu/celshading/celshading.c new file mode 100644 index 00000000..42e510f9 --- /dev/null +++ b/src/samples/gu/celshading/celshading.c @@ -0,0 +1,251 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * celshading.c Simple cel shading example + * written as xmas present for psp community + * + * Copyright (c) 2005 McZonk + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "../common/callbacks.h" + +PSP_MODULE_INFO("Celshading", 0, 1, 1); +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER); + +static unsigned int __attribute__((aligned(16))) list[262144]; + +extern unsigned char lightmap_start[]; + +typedef struct Vx_v32f_n32f { + float normal[3]; + float vertex[3]; +} Vx_v32f_n32f; + +typedef struct Vx_v32f { + float vertex[3]; +} Vx_v32f; + +#define BUF_WIDTH (512) +#define SCR_WIDTH (480) +#define SCR_HEIGHT (272) +#define PIXEL_SIZE (4) /* change this if you change to another screenmode */ +#define FRAME_SIZE (BUF_WIDTH * SCR_HEIGHT * PIXEL_SIZE) +#define ZBUF_SIZE (BUF_WIDTH SCR_HEIGHT * 2) /* zbuffer seems to be 16-bit? */ + +#define TORUS_SLICES 48 // numc +#define TORUS_ROWS 48 // numt +#define TORUS_RADIUS 1.0f +#define TORUS_THICKNESS 0.5f + +#define LIGHT_DISTANCE 3.0f + +Vx_v32f_n32f __attribute__((aligned(16))) torus_v0[TORUS_SLICES * TORUS_ROWS]; +Vx_v32f __attribute__((aligned(16))) torus_v1[TORUS_SLICES * TORUS_ROWS]; +unsigned short __attribute__((aligned(16))) torus_in[TORUS_SLICES * TORUS_ROWS * 6]; + +int main(int argc, char* argv[]) { + /* Setup Homebutton Callbacks */ + setupCallbacks(); + + /* Generate Torus */ + unsigned int i,j; + for (j = 0; j < TORUS_SLICES; ++j) { + for (i = 0; i < TORUS_ROWS; ++i) { + struct Vx_v32f_n32f* v0 = &torus_v0[i + j*TORUS_ROWS]; + struct Vx_v32f* v1 = &torus_v1[i + j*TORUS_ROWS]; + + float s = i + 0.5f; + float t = j; + float cs,ct,ss,st; + + cs = cosf(s * (2*GU_PI)/TORUS_SLICES); + ct = cosf(t * (2*GU_PI)/TORUS_ROWS); + ss = sinf(s * (2*GU_PI)/TORUS_SLICES); + st = sinf(t * (2*GU_PI)/TORUS_ROWS); + + v0->normal[0] = cs * ct; + v0->normal[1] = cs * st; + v0->normal[2] = ss; + + v0->vertex[0] = (TORUS_RADIUS + TORUS_THICKNESS * cs) * ct; + v0->vertex[1] = (TORUS_RADIUS + TORUS_THICKNESS * cs) * st; + v0->vertex[2] = TORUS_THICKNESS * ss; + + v1->vertex[0] = v0->vertex[0] + v0->normal[0] * 0.1f; + v1->vertex[1] = v0->vertex[1] + v0->normal[1] * 0.1f; + v1->vertex[2] = v0->vertex[2] + v0->normal[2] * 0.1f; + } + } + for (j = 0; j < TORUS_SLICES; ++j) { + for (i = 0; i < TORUS_ROWS; ++i) { + unsigned short* in = &torus_in[(i+(j*TORUS_ROWS))*6]; + unsigned int i1 = (i+1)%TORUS_ROWS, j1 = (j+1)%TORUS_SLICES; + + *in++ = i + j * TORUS_ROWS; + *in++ = i1 + j * TORUS_ROWS; + *in++ = i + j1 * TORUS_ROWS; + + *in++ = i1 + j * TORUS_ROWS; + *in++ = i1 + j1 * TORUS_ROWS; + *in++ = i + j1 * TORUS_ROWS; + } + } + + sceKernelDcacheWritebackAll(); + + SceCtrlData pad; + sceCtrlSetSamplingCycle(0); + sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG); + + // setup GU + + sceGuInit(); + + sceGuStart(GU_DIRECT,list); + sceGuDrawBuffer(GU_PSM_8888,(void*)0,BUF_WIDTH); + sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,(void*)0x88000,BUF_WIDTH); + sceGuDepthBuffer((void*)0x110000,BUF_WIDTH); + sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); + sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); + sceGuDepthRange(0xc350,0x2710); + sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + sceGuDepthFunc(GU_GEQUAL); + sceGuEnable(GU_DEPTH_TEST); + sceGuFrontFace(GU_CW); + sceGuShadeModel(GU_SMOOTH); + sceGuEnable(GU_CULL_FACE); + sceGuEnable(GU_CLIP_PLANES); + sceGuFinish(); + sceGuSync(0,0); + sceDisplayWaitVblankStart(); + sceGuDisplay(GU_TRUE); + + unsigned int old = 0; + unsigned int flags = PSP_CTRL_CIRCLE | PSP_CTRL_CROSS | PSP_CTRL_SQUARE; + + float rx = 0.0f, ry = 0.0f; + + while(running()) + { + sceGuStart(GU_DIRECT,list); + + sceGuClearColor(0xFFFFFF); + sceGuClearDepth(0); + sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); + + sceGumMatrixMode(GU_PROJECTION); + sceGumLoadIdentity(); + sceGumPerspective(75.0f,16.0/9.0f,1.0f,1000.0f); + + sceGumMatrixMode(GU_VIEW); + sceGumLoadIdentity(); + + sceGumMatrixMode(GU_MODEL); + sceGumLoadIdentity(); + ScePspFVector3 pos = { 0.0f, 0.0f, -3.0f }; + ScePspFVector3 rot = { ry * (GU_PI/180.0f), rx * (GU_PI/180.0f), 0.0f }; + sceGumTranslate(&pos); + sceGumRotateXYZ(&rot); + + sceGuTexMode(GU_PSM_8888,0,0,0); + sceGuTexImage(0,64,64,64, lightmap_start); + sceGuTexFunc(GU_TFX_MODULATE,GU_TCC_RGB); + sceGuTexFilter(GU_LINEAR,GU_LINEAR); + sceGuColor(0xff9966); + + ScePspFVector3 envmapMatrixColumns[2] = { + { 1.0f, 0.0f, 0.0f }, + { 0.0f, 1.0f, 0.0f } + }; + sceGuLight( 0, GU_DIRECTIONAL, GU_DIFFUSE, &envmapMatrixColumns[0] ); + sceGuLight( 1, GU_DIRECTIONAL, GU_DIFFUSE, &envmapMatrixColumns[1] ); + + sceGuTexMapMode(GU_ENVIRONMENT_MAP, 0, 1); + + /* + First pass: draw the torus + */ + if(flags & PSP_CTRL_CROSS) { + sceGuEnable(GU_TEXTURE_2D); + } + sceGumDrawArray(GU_TRIANGLES, + GU_NORMAL_32BITF|GU_VERTEX_32BITF|GU_INDEX_16BIT|GU_TRANSFORM_3D, + sizeof(torus_in)/sizeof(unsigned short), torus_in, torus_v0 + ); + if(flags & PSP_CTRL_CROSS) { + sceGuDisable(GU_TEXTURE_2D); + } + + + /* + Seconds pass: draw the outline + */ + if(flags & PSP_CTRL_CIRCLE) { + sceGuFrontFace(GU_CCW); + sceGuColor(0x0); + sceGumDrawArray(GU_TRIANGLES, + GU_VERTEX_32BITF|GU_INDEX_16BIT|GU_TRANSFORM_3D, + sizeof(torus_in)/sizeof(unsigned short), torus_in, torus_v1 + ); + sceGuFrontFace(GU_CW); + } + + sceGuFinish(); + sceGuSync(0,0); + + sceCtrlReadBufferPositive(&pad, 1); + + float tx = (pad.Lx - 128) / 127.0f; + float ty = (pad.Ly - 128) / 127.0f; + if(fabs(tx) <= 0.2f) { + tx = 0.0f; + } else { + if(tx > 0.0f) { + tx -= 0.2f; + } else { + tx += 0.2f; + } + } + if(fabs(ty) <= 0.2f) { + ty = 0.0f; + } else { + if(ty > 0.0f) { + ty -= 0.2f; + } else { + ty += 0.2f; + } + } + + rx += tx; + ry += ty; + + if(old != pad.Buttons) { + flags ^= pad.Buttons; + } + old = pad.Buttons; + + sceDisplayWaitVblankStart(); + sceGuSwapBuffers(); + } + + sceGuTerm(); + + sceKernelExitGame(); + return 0; +} diff --git a/src/samples/gu/celshading/lightmap.raw b/src/samples/gu/celshading/lightmap.raw new file mode 100644 index 00000000..afe88c47 --- /dev/null +++ b/src/samples/gu/celshading/lightmap.raw @@ -0,0 +1 @@ +333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ343ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ433ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ334ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿKKKÿcbbÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿbccÿKKKÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ433ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿNNNÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿNNNÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ999ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ9:9ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ343ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ:::ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ;:;ÿ333ÿ333ÿ343ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ334ÿ333ÿ333ÿ333ÿ333ÿ333ÿNNOÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿNNNÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ433ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿNNNÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿpppÿ€€ÿˆˆˆÿŒŒŒÿˆˆˆÿÿppqÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿNNNÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ‚‚ƒÿšš™ÿ›œ›ÿœœœÿÿžžÿžžÿžÿÿœœÿ››œÿš™šÿƒ‚‚ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿŒŒŒÿ›››ÿÿŸžŸÿ ¡ ÿ¢¢¡ÿ£¢£ÿ¤£¤ÿ£¤¤ÿ££¤ÿ£¢£ÿ¢¢¢ÿ  ¡ÿŸŸŸÿÿ›››ÿŒŒŒÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ:::ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿvvvÿšš›ÿžÿŸ  ÿ¢¢¢ÿ¤¤¤ÿ¦¦¦ÿ§§§ÿ¨©¨ÿ©©©ÿ©©©ÿ©©©ÿ¨¨©ÿ¨§§ÿ¦¦¦ÿ¤¤¤ÿ£¢¢ÿ Ÿ ÿÿšššÿvvvÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ:;;ÿ333ÿ334ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿˆ‰ˆÿ›œœÿŸžŸÿ¢¢¢ÿ¥¥¥ÿ§§¨ÿªªªÿ¬««ÿ­¬­ÿ®®­ÿ¯¯®ÿ¯®®ÿ®®®ÿ®®®ÿ­¬¬ÿ«¬«ÿ©©ªÿ§§§ÿ¥¥¥ÿ¢¢¢ÿŸŸŸÿœœœÿˆˆˆÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ999ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿŽÿœœÿ   ÿ£¤£ÿ§§§ÿªª©ÿ¬¬­ÿ®®¯ÿ°°°ÿ²²²ÿ´³³ÿ´´´ÿ´µ´ÿ´´´ÿ´³³ÿ³²²ÿ±±±ÿ¯¯¯ÿ¬¬¬ÿªªªÿ§¦§ÿ££¤ÿ   ÿœœÿÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ999ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿˆˆˆÿœœœÿ   ÿ¤¤¤ÿ¨¨¨ÿ¬¬«ÿ®®¯ÿ±±±ÿ´´´ÿ¶¶¶ÿ¸¸¸ÿ¹¹¹ÿºº¹ÿºººÿº¹ºÿ¸¹¸ÿ¸·¸ÿµ¶¶ÿ´´´ÿ±²±ÿ®¯®ÿ««¬ÿ¨¨¨ÿ¤¤¥ÿ ¡ ÿœœœÿˆˆˆÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿvvvÿ››œÿ   ÿ¤¤¤ÿ¨¨©ÿ¬¬¬ÿ°°¯ÿ³³³ÿ¶¶¶ÿ¹¸¸ÿ»»»ÿ½½½ÿ¾¿¿ÿÀ¿¿ÿ¿ÀÀÿÀ¿¿ÿ¿¾¿ÿ½½½ÿ¼»»ÿ¹¹¹ÿ¶¶¶ÿ³³³ÿ¯°°ÿ¬¬¬ÿ¨¨¨ÿ¤¤¤ÿ   ÿ››œÿvvvÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿNNNÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿš››ÿŸŸŸÿ¤£¤ÿ¨¨§ÿ¬­¬ÿ°°°ÿ´´´ÿ··¸ÿ»»»ÿ¾¾¾ÿÀÀÁÿÂÂÃÿÄÄÄÿÅÅÄÿÅÅÅÿÄÅÅÿÄÄÄÿÂÂÂÿÀÀÀÿ½½½ÿ»»»ÿ¸¸¸ÿ´´´ÿ°°°ÿ­¬¬ÿ¨¨¨ÿ£££ÿŸŸžÿš››ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿNNNÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿŒŒŒÿÿ¢¢¢ÿ¦§§ÿ«««ÿ°°¯ÿ´´´ÿ¸¸¸ÿ¼¼¼ÿÀÀ¿ÿÃÂÃÿÅÅÅÿÇÇÇÿÉÊÉÿÊÊÊÿËËÊÿËËÊÿÊÉÉÿÈÈÈÿÅÅÆÿÂÃÃÿÀ¿¿ÿ¼¼¼ÿ¸¸¸ÿ´´´ÿ°°°ÿ«««ÿ¦¦¦ÿ¢¢¢ÿÿŒŒŒÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ›š›ÿ   ÿ¤¤¥ÿªªªÿ¯®¯ÿ³³³ÿ·¸·ÿ¼¼¼ÿÁÀÁÿÄÄÄÿÈÈÇÿËÊÊÿããäÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿãäãÿÊËÊÿÈÇÇÿÄÄÄÿÀÀÀÿ¼¼¼ÿ·¸¸ÿ³³³ÿ®®¯ÿªª©ÿ¥¥¥ÿ Ÿ ÿ›››ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ‚‚‚ÿÿ£¢¢ÿ§§§ÿ¬¬¬ÿ±±²ÿ¶¶¶ÿ»»»ÿÀ¿ÀÿÄÄÃÿÈÈÈÿËÌÌÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿËÌËÿÈÈÈÿÄÄÄÿÀ¿¿ÿ»»»ÿ·¶¶ÿ±±±ÿ¬¬¬ÿ¨§¨ÿ££¢ÿÿƒ‚‚ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿKKKÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ™™šÿŸŸžÿ¤¤¥ÿªª©ÿ¯¯¯ÿ³³³ÿ¹¹¹ÿ¾¾¾ÿÃÃÃÿÈÇÈÿÌÌÌÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÌÌÌÿÇÇÈÿÃÃÃÿ¾¾½ÿ¹¸¹ÿ´´´ÿ¯®¯ÿª©©ÿ¤¤¥ÿŸŸŸÿš™šÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿKKKÿ333ÿ333ÿ333ÿ333ÿ333ÿbccÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ›››ÿ¡¡ ÿ¦¦¦ÿ««¬ÿ°±°ÿ¶¶¶ÿ¼»»ÿÀÀÀÿÅÆÆÿËËÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÊËËÿÆÅÅÿÀÀÀÿ¼»¼ÿ¶µ¶ÿ°°°ÿ«¬«ÿ¦¦¦ÿ  ¡ÿ›››ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿbbcÿ333ÿ333ÿ333ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿpppÿœœœÿ¢¢¢ÿ§§§ÿ­­­ÿ²²²ÿ¸¸¸ÿ½½½ÿÃÃÂÿÈÈÈÿãããÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿäãäÿÈÈÈÿÃÃÂÿ½½½ÿ··¸ÿ²²²ÿ­­­ÿ§§§ÿ¢¢¢ÿœœœÿppqÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿÿÿ¢££ÿ©©¨ÿ®­®ÿ³³³ÿ¸¸¹ÿ¾¾¾ÿÄÄÄÿÊÉÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿþÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÉÊÉÿÄÄÄÿ¿¾¾ÿ¹¹¹ÿ´³´ÿ®®­ÿ¨¨¨ÿ£¢£ÿžÿ€ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿˆˆˆÿžÿ£££ÿ©©©ÿ®®®ÿ´´´ÿºº¹ÿ¿¿¿ÿÄÄÅÿÊËÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿþÿýýýÿýýüÿýýýÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÊËÊÿÅÄÅÿ¿¿¿ÿºººÿ´´´ÿ®®¯ÿ©¨©ÿ¤¤£ÿžžÿ‰ˆˆÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿŒŒŒÿžžÿ¤¤¤ÿ©©©ÿ¯¯®ÿµµµÿº¹ºÿ¿ÀÀÿÅÅÅÿÊËËÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿüýýÿüüüÿýýüÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÊËÊÿÅÅÅÿÀ¿¿ÿºººÿ´´´ÿ®®¯ÿ©ª©ÿ££¤ÿžžÿŒŒÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ433ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿˆˆˆÿžžžÿ££¤ÿ©©©ÿ®¯¯ÿ´´´ÿ¹ººÿ¿¿ÀÿÅÅÅÿÊËÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿýýýÿüýýÿþýýÿÿþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÊÊÊÿÅÅÅÿ¿¿¿ÿºººÿ´´´ÿ¯¯¯ÿ©©©ÿ¤££ÿžžžÿˆˆˆÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ€€ÿÿ£¢£ÿ¨¨¨ÿ®®®ÿ´³³ÿ¸¹¹ÿ¾¿¾ÿÄÄÄÿÊÉÉÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþÿþþþÿþÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÉÉÊÿÄÄÄÿ¿¾¿ÿ¸¹¹ÿ³³³ÿ®®®ÿ©¨©ÿ£££ÿÿ€ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿpqqÿœÿ¡¢¢ÿ§§§ÿ¬­¬ÿ³²²ÿ·¸·ÿ½½½ÿÃÂÂÿÈÈÈÿäãäÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿããäÿÈÈÈÿÃÂÃÿ½½½ÿ¸¸·ÿ²²²ÿ­­­ÿ§§§ÿ¢¢¢ÿœÿqqpÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ333ÿ333ÿbccÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ›››ÿ ¡ ÿ¦¦¦ÿ¬««ÿ°±°ÿ¶¶¶ÿ»»»ÿÁÀÀÿÆÅÆÿÊÊÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÊËÊÿÆÆÅÿÀÁÁÿ¼»»ÿ¶¶¶ÿ°±°ÿ«««ÿ¦¦¦ÿ¡  ÿ›››ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿccbÿ333ÿ333ÿ333ÿ333ÿ333ÿKKKÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿšššÿŸžŸÿ¤¤¤ÿ©©ªÿ¯¯®ÿ³´´ÿ¹¹¸ÿ¾¾¾ÿÂÃÂÿÇÇÇÿÌÌÌÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿËÌÌÿÇÈÇÿÃÃÂÿ½¾¾ÿ¹¹¹ÿ´´´ÿ®¯¯ÿ©ªªÿ¤¤¤ÿŸŸŸÿšššÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿKKKÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ‚ƒ‚ÿÿ¢£¢ÿ§§§ÿ¬¬¬ÿ±²±ÿ·¶¶ÿ»»»ÿ¿¿¿ÿÄÄÃÿÈÈÈÿÌÌÌÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿËÌÌÿÈÈÈÿÄÄÄÿ¿¿¿ÿ»»ºÿ¶¶¶ÿ²²±ÿ¬¬¬ÿ§¨§ÿ¢£¢ÿÿ‚‚‚ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿš››ÿ Ÿ ÿ¥¥¥ÿ©©ªÿ¯®¯ÿ³³³ÿ·¸·ÿ¼¼¼ÿÀÀÀÿÄÄÃÿÈÈÈÿÊÊÊÿãääÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿäããÿËÊËÿÇÇÇÿÄÄÄÿÀÀÀÿ¼¼¼ÿ·¸·ÿ³³³ÿ¯®®ÿªªªÿ¤¥¥ÿ   ÿ›››ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿŒŒŒÿžžÿ¢¢¢ÿ§§¦ÿ««¬ÿ°°°ÿ´´´ÿ¸¸¹ÿ¼¼¼ÿ¿¿ÀÿÃÃÃÿÅÅÆÿÈÈÈÿÊÉÉÿËÊÊÿÊÊËÿÊÊÊÿÊÊÉÿÇÇÇÿÆÆÅÿÃÂÃÿ¿À¿ÿ¼¼¼ÿ¸¸¸ÿ´´´ÿ°°°ÿ«««ÿ¦§¦ÿ¢¢¢ÿÿŒŒŒÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿNNNÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿšš›ÿŸŸŸÿ£¤£ÿ§§¨ÿ­¬¬ÿ°°°ÿ´´´ÿ¸·¸ÿ»»»ÿ¾½½ÿÀÀÀÿÃÃÂÿÄÃÃÿÅÅÅÿÆÅÅÿÅÅÅÿÄÄÃÿÃÂÃÿÀÀÀÿ¾¾¾ÿ»»»ÿ¸·¸ÿ´´´ÿ°°°ÿ­¬¬ÿ¨§¨ÿ£££ÿŸŸŸÿš››ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿNNNÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿvvvÿ›œœÿ   ÿ¤¤¥ÿ¨©¨ÿ­¬¬ÿ°°°ÿ³³´ÿ¶¶¶ÿ¹¹¹ÿ»»»ÿ½½½ÿ¾¾¾ÿÀ¿¿ÿÀÀÀÿ¿¿¿ÿ¿¿¾ÿ½½½ÿ»»»ÿ¹¹¹ÿ¶¶¶ÿ³³³ÿ¯°°ÿ­¬¬ÿ©¨©ÿ¥¤¤ÿ   ÿœ››ÿvvvÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ333ÿ343ÿ333ÿ333ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿˆˆˆÿœÿ¡  ÿ¤¤¤ÿ¨§¨ÿ«¬«ÿ¯®®ÿ²²±ÿ´´´ÿ¶¶¶ÿ¸·¸ÿ¸¹¹ÿº¹ºÿºººÿºººÿ¹¹¸ÿ·¸·ÿ¶¶¶ÿ³´´ÿ²±±ÿ®¯¯ÿ«««ÿ¨¨¨ÿ¤¤¤ÿ¡¡ ÿœœœÿˆˆˆÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ999ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿŽÿœœÿ   ÿ¤££ÿ§§§ÿª©ªÿ¬­¬ÿ®®®ÿ±±±ÿ³²²ÿ³³³ÿ´´´ÿ´´´ÿ´´´ÿ´´´ÿ²²²ÿ°±°ÿ¯¯¯ÿ¬¬¬ÿ©©ªÿ¦§§ÿ¤¤¤ÿ   ÿœœœÿÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ999ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ343ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿˆˆˆÿœœœÿžŸŸÿ¢¢¢ÿ¤¥¥ÿ§¨§ÿªª©ÿ¬««ÿ­­­ÿ®®®ÿ®¯®ÿ¯¯¯ÿ®®®ÿ®®®ÿ­¬­ÿ«««ÿª©©ÿ¨§¨ÿ¥¥¥ÿ¢¢¢ÿŸŸŸÿœ›œÿˆˆˆÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ::;ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿvvvÿšš›ÿÿ   ÿ¢£¢ÿ¤¥¤ÿ¦¦¦ÿ¨§§ÿ©©¨ÿ¨©©ÿ©©©ÿ©¨©ÿ¨©¨ÿ§§§ÿ¦¦¦ÿ¤¤¤ÿ£¢£ÿ  Ÿÿÿšššÿvvvÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ;::ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿŒŒŒÿšš›ÿÿŸŸŸÿ¡ ¡ÿ¢¢¢ÿ£££ÿ£¤£ÿ£¤¤ÿ££¤ÿ£££ÿ¢¢¢ÿ¡¡ ÿŸŸŸÿÿš››ÿŒŒŒÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿƒ‚‚ÿ™š™ÿ›››ÿœœÿÿžžÿžÿžžÿžÿœœÿ›››ÿšššÿ‚‚‚ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿNNNÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿqppÿÿˆˆˆÿŒŒÿˆˆˆÿÿpqpÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿNNNÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ433ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿNNNÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿNONÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ433ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ:::ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ::;ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ999ÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿ999ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿNONÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿNNNÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ343ÿ333ÿ333ÿ333ÿ334ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ334ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿKKKÿccbÿfffÿfffÿfffÿfffÿfffÿfffÿfffÿbccÿKKKÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ433ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ334ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ433ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ343ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ433ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ \ No newline at end of file diff --git a/src/samples/gu/clut/Makefile.sample b/src/samples/gu/clut/Makefile.sample new file mode 100644 index 00000000..b6264686 --- /dev/null +++ b/src/samples/gu/clut/Makefile.sample @@ -0,0 +1,17 @@ +TARGET = clut +OBJS = clut.o ../common/callbacks.o ../common/vram.o + +INCDIR = +CFLAGS = -G0 -Wall -O2 +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = +LIBS= -lpspgu + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Clut Sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/gu/clut/clut.c b/src/samples/gu/clut/clut.c new file mode 100644 index 00000000..74e6cb4b --- /dev/null +++ b/src/samples/gu/clut/clut.c @@ -0,0 +1,194 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +PSP_MODULE_INFO("Clut Sample", 0, 1, 1); +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER); + +static unsigned int __attribute__((aligned(16))) list[262144]; + +struct Vertex +{ + float u,v; + float x,y,z; +}; + +int SetupCallbacks(); + +#define BUF_WIDTH (512) +#define SCR_WIDTH (480) +#define SCR_HEIGHT (272) +#define PIXEL_SIZE (4) /* change this if you change to another screenmode */ +#define FRAME_SIZE (BUF_WIDTH * SCR_HEIGHT * PIXEL_SIZE) +#define ZBUF_SIZE (BUF_WIDTH SCR_HEIGHT * 2) /* zbuffer seems to be 16-bit? */ + +#define NUM_SLICES 128 +#define NUM_ROWS 128 +#define RING_SIZE 2.0f +#define RING_RADIUS 1.0f +#define SPRITE_SIZE 0.025f + +unsigned int colors[8] = +{ + 0xffff0000, + 0xffff00ff, + 0xff0000ff, + 0xff00ffff, + 0xff00ff00, + 0xffffff00, + 0xffffffff, + 0xff00ffff +}; + +unsigned int __attribute__((aligned(16))) clut256[256]; +unsigned char __attribute__((aligned(16))) tex256[256*256]; + +int main(int argc, char* argv[]) +{ + unsigned int i,j; + + SetupCallbacks(); + + // initialize texture + + for (j = 0; j < 256; ++j) + { + for (i = 0; i < 256; ++i) + { + tex256[i + j * 256] = j ^ i; + } + } + + sceKernelDcacheWritebackAll(); + + // setup GU + + sceGuInit(); + sceGuStart(GU_DIRECT,list); + + sceGuDrawBuffer(GU_PSM_8888,(void*)0,BUF_WIDTH); + sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,(void*)FRAME_SIZE,BUF_WIDTH); + sceGuDepthBuffer((void*)(FRAME_SIZE*2),BUF_WIDTH); + sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); + sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); + sceGuDepthRange(0xc350,0x2710); + sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + sceGuFrontFace(GU_CW); + sceGuEnable(GU_TEXTURE_2D); + sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuDisplay(GU_TRUE); + + // run sample + + int offset = 0; + + for(;;) + { + sceGuStart(GU_DIRECT,list); + + // animate palette + + unsigned int* clut = (unsigned int*)(((unsigned int)clut256)|0x40000000); + for (i = 0; i < 256; ++i) + { + unsigned int j = (i + offset)&0xff; + *(clut++) = (j << 24)|(j << 16)|(j << 8)|(j); + } + + // clear screen + + sceGuClearColor(0xff00ff); + sceGuClear(GU_COLOR_BUFFER_BIT); + + // setup CLUT texture + + sceGuClutMode(GU_PSM_8888,0,0xff,0); // 32-bit palette + sceGuClutLoad((256/8),clut256); // upload 32*8 entries (256) + sceGuTexMode(GU_PSM_T8,0,0,0); // 8-bit image + sceGuTexImage(0,256,256,256,tex256); + sceGuTexFunc(GU_TFX_REPLACE,GU_TCC_RGB); + sceGuTexFilter(GU_LINEAR,GU_LINEAR); + sceGuTexScale(1.0f,1.0f); + sceGuTexOffset(0.0f,0.0f); + sceGuAmbientColor(0xffffffff); + + // render sprite + + sceGuColor(0xffffffff); + struct Vertex* vertices = (struct Vertex*)sceGuGetMemory(2 * sizeof(struct Vertex)); + vertices[0].u = 0; vertices[0].v = 0; + vertices[0].x = 0; vertices[0].y = 0; vertices[0].z = 0; + vertices[1].u = 256; vertices[1].v = 256; + vertices[1].x = 480; vertices[1].y = 272; vertices[1].z = 0; + sceGuDrawArray(GU_SPRITES,GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D,2,0,vertices); + + // wait for next frame + + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuSwapBuffers(); + + offset++; + } + + sceGuTerm(); + + sceKernelExitGame(); + return 0; +} + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + sceKernelExitGame(); + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0); + if(thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} diff --git a/src/samples/gu/common/callbacks.c b/src/samples/gu/common/callbacks.c new file mode 100644 index 00000000..22e2e104 --- /dev/null +++ b/src/samples/gu/common/callbacks.c @@ -0,0 +1,54 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static int exitRequest = 0; + +int running() +{ + return !exitRequest; +} + +int exitCallback(int arg1, int arg2, void *common) +{ + exitRequest = 1; + return 0; +} + +int callbackThread(SceSize args, void *argp) +{ + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", exitCallback, NULL); + sceKernelRegisterExitCallback(cbid); + + sceKernelSleepThreadCB(); + + return 0; +} + +int setupCallbacks(void) +{ + int thid = 0; + + thid = sceKernelCreateThread("update_thread", callbackThread, 0x11, 0xFA0, 0, 0); + if(thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} diff --git a/src/samples/gu/common/callbacks.h b/src/samples/gu/common/callbacks.h new file mode 100644 index 00000000..a6ecd7a6 --- /dev/null +++ b/src/samples/gu/common/callbacks.h @@ -0,0 +1,15 @@ +#ifndef common_callbacks_h +#define common_callbacks_h + +#ifdef __cplusplus +extern "C" { +#endif + +int running(); +int setupCallbacks(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/samples/gu/common/geometry.c b/src/samples/gu/common/geometry.c new file mode 100644 index 00000000..c04727c7 --- /dev/null +++ b/src/samples/gu/common/geometry.c @@ -0,0 +1,174 @@ +#include "geometry.h" + +#include +#include + +static void generateTorus(unsigned int slices, unsigned int rows, float radius, float thickness, void* vertices, unsigned short* indices, unsigned int size, int texture, int color, int normal, int position) +{ + unsigned int i,j; + + for (j = 0; j < slices; ++j) + { + for (i = 0; i < rows; ++i) + { + float s = i + 0.5f; + float t = j; + float cs,ct,ss,st; + int offset = 0; + + cs = cosf(s * (2*GU_PI) / slices); + ct = cosf(t * (2*GU_PI) / rows); + ss = sinf(s * (2*GU_PI) / slices); + st = sinf(t * (2*GU_PI) / rows); + + if (texture >= 0) + { + float* texcoords = (float*)(((unsigned char*)vertices) + offset); + texcoords[0] = cs * ct; + texcoords[1] = cs * st; + offset += texture; + } + + if (color >= 0) + { + u32* col = (u32*)(((unsigned char*)vertices) + offset); + unsigned int r = 128 + (cs * ct) * 127; + unsigned int g = 128 + (cs * st) * 127; + unsigned int b = 128 + ss * 127; + + *col = (0xff << 24)|(b << 16)|(g << 8)|r; + offset += color; + } + + if (normal >= 0) + { + float* normals = (float*)(((unsigned char*)vertices) + offset); + normals[0] = cs * ct; + normals[1] = cs * st; + normals[2] = ss; + + offset += normal; + } + + if (position >= 0) + { + float* pos = (float*)(((unsigned char*)vertices) + offset); + pos[0] = (radius + thickness * cs) * ct; + pos[1] = (radius + thickness * cs) * st; + pos[2] = thickness * ss; + + offset += position; + } + + vertices = (void*)(((unsigned char*)vertices) + size); + } + } + + // TODO: generate degenerates instead, so we can tristrip the torus + + for (j = 0; j < slices; ++j) + { + for (i = 0; i < rows; ++i) + { + unsigned int i1 = (i+1) % rows; + unsigned int j1 = (j+1) % slices; + + *indices++ = i + j * rows; + *indices++ = i1 + j * rows; + *indices++ = i + j1 * rows; + + *indices++ = i1 + j * rows; + *indices++ = i1 + j1 * rows; + *indices++ = i + j1 * rows; + } + } +} + +void generateTorusTCNP(unsigned int slices, unsigned int rows, float radius, float thickness, TCNPVertex* vertices, unsigned short* indices) +{ + generateTorus(slices,rows,radius,thickness,vertices,indices,sizeof(TCNPVertex), 2 * sizeof(float), sizeof(u32), 3 * sizeof(float), 3 * sizeof(float)); +} + +void generateTorusTCP(unsigned int slices, unsigned int rows, float radius, float thickness, TCPVertex* vertices, unsigned short* indices) +{ + generateTorus(slices,rows,radius,thickness,vertices,indices,sizeof(TCPVertex), 2 * sizeof(float), sizeof(u32), -1, 3 * sizeof(float)); +} + +void generateTorusNP(unsigned int slices, unsigned int rows, float radius, float thickness, NPVertex* vertices, unsigned short* indices) +{ + generateTorus(slices,rows,radius,thickness,vertices,indices,sizeof(NPVertex),-1,-1,3 * sizeof(float), 3 * sizeof(float)); +} + +static void generateGrid(unsigned int columns, unsigned int rows, float width, float depth, void* vertices, unsigned short* indices, unsigned int size, int texture, int color, int normal, int position) +{ + unsigned int i,j; + float ic = 1.0f / columns; + float ir = 1.0f / rows; + + for (j = 0; j < rows; ++j) + { + for (i = 0; i < columns; ++i) + { + int offset = 0; + + if (texture >= 0) + { + float* texcoords = (float*)(((unsigned char*)vertices) + offset); + texcoords[0] = ic * i; + texcoords[1] = ir * j; + offset += texture; + } + + if (color >= 0) + { + u32* col = (u32*)(((unsigned char*)vertices) + offset); + *col = 0xffffffff; + offset += color; + } + + if (normal >= 0) + { + float* normals = (float*)(((unsigned char*)vertices) + offset); + normals[0] = 0.0f; + normals[1] = 1.0f; + normals[2] = 0.0f; + offset += normal; + } + + if (position >= 0) + { + float* pos = (float*)(((unsigned char*)vertices) + offset); + pos[0] = ((ic * i)-0.5f) * width; + pos[1] = 0.0f; + pos[2] = ((ir * j)-0.5f) * depth; + offset += position; + } + + vertices = (void*)(((unsigned char*)vertices) + size); + } + } + + for (j = 0; j < rows-1; ++j) + { + for (i = 0; i < columns-1; ++i) + { + *indices++ = i + j * columns; + *indices++ = (i+1) + j * columns; + *indices++ = i + (j+1) * columns; + + *indices++ = (i+1) + j * columns; + *indices++ = (i+1) + (j+1) * columns; + *indices++ = i + (j+1) * columns; + } + } +} + +void generateGridTCNP(unsigned int columns, unsigned int rows, float width, float depth, TCNPVertex* vertices, unsigned short* indices) +{ + generateGrid(columns,rows,width,depth,vertices,indices,sizeof(TCNPVertex),2 * sizeof(float), sizeof(u32), 3 * sizeof(float), 3 * sizeof(float)); +} + +void generateGridNP(unsigned int columns, unsigned int rows, float width, float depth, NPVertex* vertices, unsigned short* indices) +{ + generateGrid(columns,rows,width,depth,vertices,indices,sizeof(NPVertex),-1,-1,3 * sizeof(float), 3 * sizeof(float)); +} diff --git a/src/samples/gu/common/geometry.h b/src/samples/gu/common/geometry.h new file mode 100644 index 00000000..39b62edc --- /dev/null +++ b/src/samples/gu/common/geometry.h @@ -0,0 +1,65 @@ +#ifndef common_geometry_h +#define common_geometry_h + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct +{ + ScePspFVector2 texture; + u32 color; + ScePspFVector3 normal; + ScePspFVector3 position; +} TCNPVertex; // Texture, Color, Normal, Position +#define TCNP_VERTEX_FORMAT (GU_TEXTURE_32BITF|GU_COLOR_8888|GU_NORMAL_32BITF|GU_VERTEX_32BITF) + +typedef struct +{ + ScePspFVector2 texture; + u32 color; + ScePspFVector3 position; +} TCPVertex; // Texture, Color, Position +#define TCP_VERTEX_FORMAT (GU_TEXTURE_32BITF|GU_COLOR_8888|GU_VERTEX_32BITF) + +typedef struct +{ + ScePspFVector2 texture; + ScePspFVector3 position; +} TPVertex; // Texture, Position +#define TP_VERTEX_FORMAT (GU_TEXTURE_32BITF|GU_VERTEX_32BITF) + +typedef struct +{ + ScePspFVector3 normal; + ScePspFVector3 position; +} NPVertex; // Normal, Position +#define NP_VERTEX_FORMAT (GU_NORMAL_32BITF|GU_VERTEX_32BITF) + +/* + torus memory usage + + vertices: slices * rows + indices: slices * rows +*/ +void generateTorusTCNP(unsigned int slices, unsigned int rows, float radius, float thickness, TCNPVertex* vertices, unsigned short* indices); +void generateTorusTCP(unsigned int slices, unsigned int rows, float radius, float thickness, TCPVertex* vertices, unsigned short* indices); +void generateTorusNP(unsigned int slices, unsigned int rows, float radius, float thickness, NPVertex* vertices, unsigned short* indices); + +/* + grid memory usage + + vertices: slices * rows + indices (slices-1) * (rows-1) +*/ +void generateGridTCNP(unsigned int columns, unsigned int rows, float width, float depth, TCNPVertex* vertices, unsigned short* indices); +void generateGridTCP(unsigned int columns, unsigned int rows, float width, float depth, TCPVertex* vertices, unsigned short* indices); +void generateGridNP(unsigned int columns, unsigned int rows, float width, float depth, NPVertex* vertices, unsigned short* indices); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/samples/gu/common/menu.c b/src/samples/gu/common/menu.c new file mode 100644 index 00000000..1afb6219 --- /dev/null +++ b/src/samples/gu/common/menu.c @@ -0,0 +1,316 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "menu.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +MenuContext* initMenu() +{ + MenuContext* context = (MenuContext*)malloc(sizeof(MenuContext)); + memset(context,0,sizeof(MenuContext)); + + return context; +} + +void destroyMenu(MenuContext* context) +{ + // delete items + + MenuItem* curr = context->root; + while (curr) + { + if (curr->children) + curr = curr->children; + else + { + MenuItem* last = curr; + curr = curr->next; + + if (!curr && last->parent) + { + MenuItem* lastParent = last->parent; + curr = lastParent->next; + + free(lastParent); + } + + free(last); + } + } + + free(context); +} + +MenuItem* addMenuItem(MenuContext* context, MenuItem* parent, MenuItem* item, int id, int data) +{ + // setup item + + item->id = id; + item->data = data; + + item->parent = parent; + + // attach to active parent + + if (parent) + { + MenuItem* sibling = parent->children; + MenuItem* last = sibling; + while (sibling) + { + last = sibling; + sibling = sibling->next; + } + + if (last) + last->next = item; + else + parent->children = item; + } + else + { + MenuItem* sibling = context->root; + MenuItem* last = sibling; + while (sibling) + { + last = sibling; + sibling = sibling->next; + } + + if (last) + last->next = item; + else + { + context->root = item; + context->active = item; + } + } + + switch (item->type) + { + case RadioButton: + { + if (item->state && item->parent) + item->parent->selected = item; + item->state = 0; + } + break; + + default: + break; + } + + return item; +} + +MenuItem* createMenuContainer(const char* name) +{ + MenuItem* item = (MenuItem*)malloc(sizeof(MenuItem)); + memset(item,0,sizeof(MenuItem)); + + item->name = name; + item->type = MenuContainer; + + return item; +} + +MenuItem* createRadioButton(const char* name, int state) +{ + MenuItem* item = (MenuItem*)malloc(sizeof(MenuItem)); + memset(item,0,sizeof(MenuItem)); + + item->name = name; + item->type = RadioButton; + + item->state = state; + + return item; +} + +MenuItem* createTriggerButton(const char* name) +{ + MenuItem* item = (MenuItem*)malloc(sizeof(MenuItem)); + memset(item,0,sizeof(MenuItem)); + + item->name = name; + item->type = TriggerButton; + + return item; +} + +MenuItem* handleMenu(MenuContext* context, SceCtrlData* input) +{ + int wasOpen = context->open; + MenuItem* result = 0; + + if (context->lastState.Buttons != input->Buttons) + { + if (context->open && context->root) + { + MenuItem* active = context->active; + + if ((context->lastState.Buttons & PSP_CTRL_UP) && !(input->Buttons & PSP_CTRL_UP)) + { + MenuItem* sibling = active->parent ? active->parent->children : context->root; + MenuItem* last = sibling; + while (sibling && (sibling != active)) + { + last = sibling; + sibling = sibling->next; + } + + context->active = last; + } + + if ((context->lastState.Buttons & PSP_CTRL_DOWN) && !(input->Buttons & PSP_CTRL_DOWN)) + { + if (active->next) + context->active = active->next; + } + + if ((context->lastState.Buttons & PSP_CTRL_CROSS) && !(input->Buttons & PSP_CTRL_CROSS)) + { + switch (active->type) + { + case MenuContainer: + { + if (active->children) + { + active->state = 1; + context->active = active->children; + } + } + break; + + case RadioButton: + { + if (active->parent) + { + active->parent->selected = active; + result = active; + } + } + break; + + case ToggleButton: + case TriggerButton: + { + result = active; + } + break; + } + } + + if ((context->lastState.Buttons & PSP_CTRL_CIRCLE) && !(input->Buttons & PSP_CTRL_CIRCLE)) + { + if (active->parent) + { + context->active = active->parent; + context->active->state = 0; + } + else + context->open = 0; + } + } + else + { + if ((context->lastState.Buttons & PSP_CTRL_CIRCLE) && !(input->Buttons & PSP_CTRL_CIRCLE)) + context->open = 1; + } + } + + // eat all input if menu is open + + context->lastState = *input; + if (context->open || wasOpen) + memset(input,0,sizeof(SceCtrlData)); + + return result; +} + +void renderMenu(MenuContext* context,int startx, int starty) +{ + if (context->open && context->root) + { + int depth = 0; + int row = starty; + + MenuItem* curr = context->root; + while (curr) + { + pspDebugScreenSetXY(startx + depth * 4, row); + pspDebugScreenSetTextColor(curr == context->active ? 0x00ffff : 0xffffff); + + switch (curr->type) + { + case RadioButton: + { + int selected = curr->parent && (curr->parent->selected == curr); + pspDebugScreenPrintf("[%s] %s",selected ? "*" : " ", curr->name); + } + break; + + case MenuContainer: + { + pspDebugScreenPrintf("%s%s",curr->state ? "-" : "+", curr->name); + if (curr->selected && !curr->state) + pspDebugScreenPrintf(": %s",curr->selected->name); + } + break; + + default: + { + pspDebugScreenPrintf(curr->name); + } + break; + } + + // traverse + + if (curr->state && curr->children && (curr->type == MenuContainer)) + { + curr = curr->children; + ++depth; + } + else + { + MenuItem* last = curr; + curr = curr->next; + + if (!curr && last->parent) + { + curr = last->parent->next; + --depth; + } + } + + ++row; + } + + pspDebugScreenSetXY(0,33); + pspDebugScreenSetTextColor(0xffffff); + pspDebugScreenPrintf("O = %s, Arrows = Move Up/Down, X = Select", context->active->parent ? "Back" : "Close Menu"); + } + else + { + + pspDebugScreenSetXY(0,33); + pspDebugScreenPrintf("O = Open Debug Menu"); + } +} diff --git a/src/samples/gu/common/menu.h b/src/samples/gu/common/menu.h new file mode 100644 index 00000000..47fc5299 --- /dev/null +++ b/src/samples/gu/common/menu.h @@ -0,0 +1,65 @@ +#ifndef common_menu_h +#define common_menu_h + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum +{ + MenuContainer, + RadioButton, + ToggleButton, + TriggerButton +} MenuItemType; + +typedef struct MenuItem +{ + const char* name; + MenuItemType type; + int id; + int data; + + int state; + + struct MenuItem* parent; + struct MenuItem* next; + struct MenuItem* children; + + // for radio-button parents + + struct MenuItem* selected; +} MenuItem; + +typedef struct MenuContext +{ + int open; + SceCtrlData lastState; + + MenuItem* root; + MenuItem* active; +} MenuContext; + +// initialize menu for use +MenuContext* initMenu(); +// destroy menu +void destroyMenu(MenuContext* context); +// add menu-item into tree +MenuItem* addMenuItem(MenuContext* context, MenuItem* parent, MenuItem* item, int id, int data); +// process menu input +// - kills input while menu is open, pass the input-structure you intend to use with the rest of input +// - returns triggered MenuItem +MenuItem* handleMenu(MenuContext* context, SceCtrlData* input); +void renderMenu(MenuContext* context,int startx, int starty); + +MenuItem* createMenuContainer(const char* name); +MenuItem* createRadioButton(const char* name, int state); +MenuItem* createTriggerButton(const char* name); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/samples/gu/common/vram.c b/src/samples/gu/common/vram.c new file mode 100644 index 00000000..90ae58bc --- /dev/null +++ b/src/samples/gu/common/vram.c @@ -0,0 +1,46 @@ +#include "vram.h" + +#include +#include + +static unsigned int staticOffset = 0; + +static unsigned int getMemorySize(unsigned int width, unsigned int height, unsigned int psm) +{ + switch (psm) + { + case GU_PSM_T4: + return (width * height) >> 1; + + case GU_PSM_T8: + return width * height; + + case GU_PSM_5650: + case GU_PSM_5551: + case GU_PSM_4444: + case GU_PSM_T16: + return 2 * width * height; + + case GU_PSM_8888: + case GU_PSM_T32: + return 4 * width * height; + + default: + return 0; + } +} + +void* getStaticVramBuffer(unsigned int width, unsigned int height, unsigned int psm) +{ + unsigned int memSize = getMemorySize(width,height,psm); + void* result = (void*)staticOffset; + staticOffset += memSize; + + return result; +} + +void* getStaticVramTexture(unsigned int width, unsigned int height, unsigned int psm) +{ + void* result = getStaticVramBuffer(width,height,psm); + return (void*)(((unsigned int)result) + ((unsigned int)sceGeEdramGetAddr())); +} diff --git a/src/samples/gu/common/vram.h b/src/samples/gu/common/vram.h new file mode 100644 index 00000000..e59f1009 --- /dev/null +++ b/src/samples/gu/common/vram.h @@ -0,0 +1,31 @@ +#ifndef common_vram_h +#define common_vram_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + The following are a few helperfunctions to help manage vram in gu-examples. + Do not use for your own code, it's better you manage it in your own way. +*/ + +/* make a static allocation of vram memory and return pointer relative to vram start */ +void* getStaticVramBuffer(unsigned int width, unsigned int height, unsigned int psm); +/* make a static allocation of vram memory and return absolute pointer */ +void* getStaticVramTexture(unsigned int width, unsigned int height, unsigned int psm); + +// the following is not yet implemented +/* +void beginDynamicVramFrame(); +void endDynamicVramFrame(); + +void* getDynamicVramBuffer(unsigned int width, unsigned int height, unsigned int psm); +void* getDynamicVramTexture(unsigned int width, unsigned int height, unsigned int psm); +*/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/samples/gu/copy/Makefile.sample b/src/samples/gu/copy/Makefile.sample new file mode 100644 index 00000000..9b18b72c --- /dev/null +++ b/src/samples/gu/copy/Makefile.sample @@ -0,0 +1,17 @@ +TARGET = copy +OBJS = copy.o ../common/callbacks.o ../common/vram.o + +INCDIR = +CFLAGS = -G0 -Wall -O2 +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = +LIBS= -lpspgu + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = CopyImage Sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/gu/copy/copy.c b/src/samples/gu/copy/copy.c new file mode 100644 index 00000000..b76669fa --- /dev/null +++ b/src/samples/gu/copy/copy.c @@ -0,0 +1,146 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "../common/callbacks.h" +#include "../common/vram.h" + +PSP_MODULE_INFO("CopyImage Sample", 0, 1, 1); +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER); + +#define BUF_WIDTH (512) +#define SCR_WIDTH (480) +#define SCR_HEIGHT (272) + +static unsigned int __attribute__((aligned(16))) list[262144]; +static unsigned int __attribute__((aligned(16))) pixels[512*272]; + +struct Vertex +{ + unsigned short u, v; + unsigned short color; + short x, y, z; +}; + +int main(int argc, char* argv[]) +{ + unsigned int x,y; + + setupCallbacks(); + + // setup + + void* fbp0 = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_8888); + void* fbp1 = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_8888); + void* zbp = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_4444); + + pspDebugScreenInit(); + sceGuInit(); + + sceGuStart(GU_DIRECT,list); + sceGuDrawBuffer(GU_PSM_8888,fbp0,BUF_WIDTH); + sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,fbp1,BUF_WIDTH); + sceGuDepthBuffer(zbp,BUF_WIDTH); + sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); + sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); + sceGuDepthRange(65535,0); + sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + sceGuFrontFace(GU_CW); + sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuDisplay(1); + + int val = 0; + + // generate dummy image to blit + + for (y = 0; y < 272; ++y) + { + unsigned int* row = &pixels[y * 512]; + for (x = 0; x < 480; ++x) + { + row[x] = x * y; + } + } + + sceKernelDcacheWritebackAll(); + + float curr_ms = 1.0f; + struct timeval time_slices[16]; + + void* framebuffer = 0; + + while (running()) + { + sceGuStart(GU_DIRECT,list); + + // copy image from ram to vram + + sceGuCopyImage(GU_PSM_8888,0,0,480,272,512,pixels,0,0,512,(void*)(0x04000000+(u32)framebuffer)); + sceGuTexSync(); + + sceGuFinish(); + sceGuSync(0,0); + + float curr_fps = 1.0f / curr_ms; + +// sceDisplayWaitVblankStart(); + framebuffer = sceGuSwapBuffers(); + + pspDebugScreenSetXY(0,0); + pspDebugScreenPrintf("%d.%03d",(int)curr_fps,(int)((curr_fps-(int)curr_fps) * 1000.0f)); + + // simple frame rate counter + + gettimeofday(&time_slices[val & 15],0); + + val++; + + if (!(val & 15)) + { + struct timeval last_time = time_slices[0]; + unsigned int i; + + curr_ms = 0; + for (i = 1; i < 16; ++i) + { + struct timeval curr_time = time_slices[i]; + + if (last_time.tv_usec > curr_time.tv_usec) + { + curr_time.tv_sec++; + curr_time.tv_usec-=1000000; + } + + curr_ms += ((curr_time.tv_usec-last_time.tv_usec) + (curr_time.tv_sec-last_time.tv_sec) * 1000000) * (1.0f/1000000.0f); + + last_time = time_slices[i]; + } + curr_ms /= 15.0f; + } + } + + sceGuTerm(); + + sceKernelExitGame(); + return 0; +} diff --git a/src/samples/gu/cube/Makefile.sample b/src/samples/gu/cube/Makefile.sample new file mode 100644 index 00000000..f133de7c --- /dev/null +++ b/src/samples/gu/cube/Makefile.sample @@ -0,0 +1,20 @@ +TARGET = cube +OBJS = cube.o logo.o ../common/callbacks.o ../common/vram.o + +INCDIR = +CFLAGS = -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = +LIBS= -lpspgum -lpspgu -lm + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Cube Sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak + +logo.o: logo.raw + bin2o -i logo.raw logo.o logo diff --git a/src/samples/gu/cube/cube.c b/src/samples/gu/cube/cube.c new file mode 100644 index 00000000..155e23c8 --- /dev/null +++ b/src/samples/gu/cube/cube.c @@ -0,0 +1,185 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "../common/callbacks.h" +#include "../common/vram.h" + +PSP_MODULE_INFO("Cube Sample", 0, 1, 1); +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER); + +static unsigned int __attribute__((aligned(16))) list[262144]; +extern unsigned char logo_start[]; + +struct Vertex +{ + float u, v; + unsigned int color; + float x,y,z; +}; + +struct Vertex __attribute__((aligned(16))) vertices[12*3] = +{ + {0, 0, 0xff7f0000,-1,-1, 1}, // 0 + {1, 0, 0xff7f0000,-1, 1, 1}, // 4 + {1, 1, 0xff7f0000, 1, 1, 1}, // 5 + + {0, 0, 0xff7f0000,-1,-1, 1}, // 0 + {1, 1, 0xff7f0000, 1, 1, 1}, // 5 + {0, 1, 0xff7f0000, 1,-1, 1}, // 1 + + {0, 0, 0xff7f0000,-1,-1,-1}, // 3 + {1, 0, 0xff7f0000, 1,-1,-1}, // 2 + {1, 1, 0xff7f0000, 1, 1,-1}, // 6 + + {0, 0, 0xff7f0000,-1,-1,-1}, // 3 + {1, 1, 0xff7f0000, 1, 1,-1}, // 6 + {0, 1, 0xff7f0000,-1, 1,-1}, // 7 + + {0, 0, 0xff007f00, 1,-1,-1}, // 0 + {1, 0, 0xff007f00, 1,-1, 1}, // 3 + {1, 1, 0xff007f00, 1, 1, 1}, // 7 + + {0, 0, 0xff007f00, 1,-1,-1}, // 0 + {1, 1, 0xff007f00, 1, 1, 1}, // 7 + {0, 1, 0xff007f00, 1, 1,-1}, // 4 + + {0, 0, 0xff007f00,-1,-1,-1}, // 0 + {1, 0, 0xff007f00,-1, 1,-1}, // 3 + {1, 1, 0xff007f00,-1, 1, 1}, // 7 + + {0, 0, 0xff007f00,-1,-1,-1}, // 0 + {1, 1, 0xff007f00,-1, 1, 1}, // 7 + {0, 1, 0xff007f00,-1,-1, 1}, // 4 + + {0, 0, 0xff00007f,-1, 1,-1}, // 0 + {1, 0, 0xff00007f, 1, 1,-1}, // 1 + {1, 1, 0xff00007f, 1, 1, 1}, // 2 + + {0, 0, 0xff00007f,-1, 1,-1}, // 0 + {1, 1, 0xff00007f, 1, 1, 1}, // 2 + {0, 1, 0xff00007f,-1, 1, 1}, // 3 + + {0, 0, 0xff00007f,-1,-1,-1}, // 4 + {1, 0, 0xff00007f,-1,-1, 1}, // 7 + {1, 1, 0xff00007f, 1,-1, 1}, // 6 + + {0, 0, 0xff00007f,-1,-1,-1}, // 4 + {1, 1, 0xff00007f, 1,-1, 1}, // 6 + {0, 1, 0xff00007f, 1,-1,-1}, // 5 +}; + +#define BUF_WIDTH (512) +#define SCR_WIDTH (480) +#define SCR_HEIGHT (272) + +int main(int argc, char* argv[]) +{ + setupCallbacks(); + + // setup GU + + void* fbp0 = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_8888); + void* fbp1 = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_8888); + void* zbp = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_4444); + + sceGuInit(); + + sceGuStart(GU_DIRECT,list); + sceGuDrawBuffer(GU_PSM_8888,fbp0,BUF_WIDTH); + sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,fbp1,BUF_WIDTH); + sceGuDepthBuffer(zbp,BUF_WIDTH); + sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); + sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); + sceGuDepthRange(65535,0); + sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + sceGuDepthFunc(GU_GEQUAL); + sceGuEnable(GU_DEPTH_TEST); + sceGuFrontFace(GU_CW); + sceGuShadeModel(GU_SMOOTH); + sceGuEnable(GU_CULL_FACE); + sceGuEnable(GU_TEXTURE_2D); + sceGuEnable(GU_CLIP_PLANES); + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuDisplay(GU_TRUE); + + // run sample + + int val = 0; + + while(running()) + { + sceGuStart(GU_DIRECT,list); + + // clear screen + + sceGuClearColor(0xff554433); + sceGuClearDepth(0); + sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); + + // setup matrices for cube + + sceGumMatrixMode(GU_PROJECTION); + sceGumLoadIdentity(); + sceGumPerspective(75.0f,16.0f/9.0f,0.5f,1000.0f); + + sceGumMatrixMode(GU_VIEW); + sceGumLoadIdentity(); + + sceGumMatrixMode(GU_MODEL); + sceGumLoadIdentity(); + { + ScePspFVector3 pos = { 0, 0, -2.5f }; + ScePspFVector3 rot = { val * 0.79f * (GU_PI/180.0f), val * 0.98f * (GU_PI/180.0f), val * 1.32f * (GU_PI/180.0f) }; + sceGumTranslate(&pos); + sceGumRotateXYZ(&rot); + } + + // setup texture + + sceGuTexMode(GU_PSM_4444,0,0,0); + sceGuTexImage(0,64,64,64,logo_start); + sceGuTexFunc(GU_TFX_ADD,GU_TCC_RGB); + sceGuTexEnvColor(0xffff00); + sceGuTexFilter(GU_LINEAR,GU_LINEAR); + sceGuTexScale(1.0f,1.0f); + sceGuTexOffset(0.0f,0.0f); + sceGuAmbientColor(0xffffffff); + + // draw cube + + sceGumDrawArray(GU_TRIANGLES,GU_TEXTURE_32BITF|GU_COLOR_8888|GU_VERTEX_32BITF|GU_TRANSFORM_3D,12*3,0,vertices); + + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuSwapBuffers(); + + val++; + } + + sceGuTerm(); + + sceKernelExitGame(); + return 0; +} diff --git a/src/samples/gu/cube/logo.raw b/src/samples/gu/cube/logo.raw new file mode 100644 index 00000000..fbac33e1 --- /dev/null +++ b/src/samples/gu/cube/logo.raw @@ -0,0 +1 @@ +ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆDDDDDDUUˆˆˆˆffDDDDffˆˆffDDDDDDwwˆˆUUDDDDUUwwˆˆffDDDDDDDDffDDwwˆˆwwDDwwˆˆˆˆˆˆffDDDDffˆˆˆˆDDDDDDUUwwˆˆˆˆffDDDDffˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆªª™™ˆˆ™™DD33™™ffªªˆˆffÌÌww™™wwˆˆªªww™™UUˆˆÌÌww™™™™DDÌÌDDDDˆˆÌÌ""wwˆˆˆˆˆˆUU™™™™""UUÌÌww™™™™ff""ˆˆˆˆUU™™™™UUˆˆˆˆˆˆˆˆˆˆˆˆˆˆªª™™UUªªÌÌ""ÝÝDDUUÌÌÌÌffÝÝ33ªªîîDDwwÌÌ33ªªîîDDUUÝÝ33ˆˆˆˆˆˆªªªª""ˆˆÌÌ33ˆˆˆˆˆˆÌÌUU™™»»ÌÌÌ̈ˆffªªÝÝ""™™»»ff™™ÌÌÝÝffˆˆˆˆˆˆˆˆˆˆˆˆˆˆªª™™33ˆˆ33»»ÝÝff""wwÝÝ""""wwDDˆˆÌÌ""ˆˆÌÌwwDDÝÝUUUUUU""ˆˆîî""ªªwwUUˆˆˆˆªªªª33ˆˆˆˆÝÝ""Ì̈ˆ""""™™UU»»ˆˆDD™™""""33ˆˆˆˆˆˆˆˆˆˆˆˆˆˆªªªªªªÝÝÌÌwwffffÌÌîîffDDÝÝwwÝÝÌÌ™™™™ÌÌ""ˆˆÌÌwwUUÝÝUUÌÌÌÌ™™ˆˆÌÌff™™33wwˆˆˆˆªªªª""ˆˆˆˆÝÝ""Ì̈ˆ»»ÌÌ33ff»»™™33»»î""ˆˆˆˆˆˆˆˆˆˆˆˆˆˆªª™™DDˆˆˆˆˆˆÝÝ3333ffwwDDÝÝ""ˆˆˆˆˆˆ™™ÌÌDDˆˆ33wwÝÝ""DDDDDDwwªªÌÌff33ˆˆˆˆ""wwîî""33DD™™33Ì̈ˆDDÝÝ™™™™îî33DD™™""ˆˆˆˆˆˆˆˆˆˆˆˆˆˆªªÌÌUUˆˆˆˆˆˆªªîªªªªwwîîffˆˆˆˆˆˆ™™îªªÌ̈ˆˆˆîªªªªwwffˆˆîUUˆˆÌÌ™™ff»»î»»»»wwÌÌ»»UUˆˆîff»»î»»Ì̈ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ™™ˆˆˆˆˆˆˆˆˆˆˆˆªª™™ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ™™™™™™ˆˆˆˆˆˆ™™™™™™™™ˆˆˆˆˆˆˆˆ™™ˆˆˆˆˆˆ™™ˆˆˆˆˆˆªª™™ˆˆˆˆˆˆ™™ˆˆˆˆˆˆ™™ˆˆˆˆˆˆªª™™ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ \ No newline at end of file diff --git a/src/samples/gu/envmap/Makefile.sample b/src/samples/gu/envmap/Makefile.sample new file mode 100644 index 00000000..8d638a74 --- /dev/null +++ b/src/samples/gu/envmap/Makefile.sample @@ -0,0 +1,20 @@ +TARGET = envmap +OBJS = envmap.o env0.o ../common/callbacks.o ../common/geometry.o ../common/vram.o + +INCDIR = +CFLAGS = -G0 -Wall -O2 +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = +LIBS= -lpspgum -lpspgu -lm + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Environment Mapping Sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak + +env0.o: env0.raw + bin2o -i env0.raw env0.o env0 diff --git a/src/samples/gu/envmap/env0.raw b/src/samples/gu/envmap/env0.raw new file mode 100644 index 00000000..fbac33e1 --- /dev/null +++ b/src/samples/gu/envmap/env0.raw @@ -0,0 +1 @@ +ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆDDDDDDUUˆˆˆˆffDDDDffˆˆffDDDDDDwwˆˆUUDDDDUUwwˆˆffDDDDDDDDffDDwwˆˆwwDDwwˆˆˆˆˆˆffDDDDffˆˆˆˆDDDDDDUUwwˆˆˆˆffDDDDffˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆªª™™ˆˆ™™DD33™™ffªªˆˆffÌÌww™™wwˆˆªªww™™UUˆˆÌÌww™™™™DDÌÌDDDDˆˆÌÌ""wwˆˆˆˆˆˆUU™™™™""UUÌÌww™™™™ff""ˆˆˆˆUU™™™™UUˆˆˆˆˆˆˆˆˆˆˆˆˆˆªª™™UUªªÌÌ""ÝÝDDUUÌÌÌÌffÝÝ33ªªîîDDwwÌÌ33ªªîîDDUUÝÝ33ˆˆˆˆˆˆªªªª""ˆˆÌÌ33ˆˆˆˆˆˆÌÌUU™™»»ÌÌÌ̈ˆffªªÝÝ""™™»»ff™™ÌÌÝÝffˆˆˆˆˆˆˆˆˆˆˆˆˆˆªª™™33ˆˆ33»»ÝÝff""wwÝÝ""""wwDDˆˆÌÌ""ˆˆÌÌwwDDÝÝUUUUUU""ˆˆîî""ªªwwUUˆˆˆˆªªªª33ˆˆˆˆÝÝ""Ì̈ˆ""""™™UU»»ˆˆDD™™""""33ˆˆˆˆˆˆˆˆˆˆˆˆˆˆªªªªªªÝÝÌÌwwffffÌÌîîffDDÝÝwwÝÝÌÌ™™™™ÌÌ""ˆˆÌÌwwUUÝÝUUÌÌÌÌ™™ˆˆÌÌff™™33wwˆˆˆˆªªªª""ˆˆˆˆÝÝ""Ì̈ˆ»»ÌÌ33ff»»™™33»»î""ˆˆˆˆˆˆˆˆˆˆˆˆˆˆªª™™DDˆˆˆˆˆˆÝÝ3333ffwwDDÝÝ""ˆˆˆˆˆˆ™™ÌÌDDˆˆ33wwÝÝ""DDDDDDwwªªÌÌff33ˆˆˆˆ""wwîî""33DD™™33Ì̈ˆDDÝÝ™™™™îî33DD™™""ˆˆˆˆˆˆˆˆˆˆˆˆˆˆªªÌÌUUˆˆˆˆˆˆªªîªªªªwwîîffˆˆˆˆˆˆ™™îªªÌ̈ˆˆˆîªªªªwwffˆˆîUUˆˆÌÌ™™ff»»î»»»»wwÌÌ»»UUˆˆîff»»î»»Ì̈ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ™™ˆˆˆˆˆˆˆˆˆˆˆˆªª™™ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ™™™™™™ˆˆˆˆˆˆ™™™™™™™™ˆˆˆˆˆˆˆˆ™™ˆˆˆˆˆˆ™™ˆˆˆˆˆˆªª™™ˆˆˆˆˆˆ™™ˆˆˆˆˆˆ™™ˆˆˆˆˆˆªª™™ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ \ No newline at end of file diff --git a/src/samples/gu/envmap/envmap.c b/src/samples/gu/envmap/envmap.c new file mode 100644 index 00000000..e1c8bf8e --- /dev/null +++ b/src/samples/gu/envmap/envmap.c @@ -0,0 +1,213 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * envmap.c - Sample to demonstrate environment mapping functionality + * + * Copyright (c) 2005 Jesper Svennevid + * Copyright (c) 2005 Renaldas Zioma + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "../common/callbacks.h" +#include "../common/geometry.h" +#include "../common/vram.h" + +PSP_MODULE_INFO("EnvMap Sample", 0, 1, 1); +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER); + +static unsigned int __attribute__((aligned(16))) list[262144]; +extern unsigned char env0_start[]; + +#define BUF_WIDTH (512) +#define SCR_WIDTH (480) +#define SCR_HEIGHT (272) +#define PIXEL_SIZE (4) /* change this if you change to another screenmode */ +#define FRAME_SIZE (BUF_WIDTH * SCR_HEIGHT * PIXEL_SIZE) +#define ZBUF_SIZE (BUF_WIDTH SCR_HEIGHT * 2) /* zbuffer seems to be 16-bit? */ + +#define TORUS_SLICES 48 // numc +#define TORUS_ROWS 48 // numt +#define TORUS_RADIUS 1.0f +#define TORUS_THICKNESS 0.5f + +#define LIGHT_DISTANCE 3.0f + +NPVertex __attribute__((aligned(16))) torus_vertices[TORUS_SLICES*TORUS_ROWS]; +unsigned short __attribute__((aligned(16))) torus_indices[TORUS_SLICES*TORUS_ROWS*6]; + +int main(int argc, char* argv[]) +{ + setupCallbacks(); + + // generate geometry + + generateTorusNP(TORUS_ROWS,TORUS_SLICES,TORUS_RADIUS,TORUS_THICKNESS,torus_vertices,torus_indices); + + // flush cache so that no stray data remains + + sceKernelDcacheWritebackAll(); + + //setup Pad + + SceCtrlData pad; + u32 oldButtons = 0; + sceCtrlSetSamplingCycle(0); + sceCtrlSetSamplingMode(0); + + // setup GU + + void* fbp0 = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_8888); + void* fbp1 = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_8888); + void* zbp = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_4444); + + pspDebugScreenInit(); + sceGuInit(); + + sceGuStart(GU_DIRECT,list); + sceGuDrawBuffer(GU_PSM_8888,fbp0,BUF_WIDTH); + sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,fbp1,BUF_WIDTH); + sceGuDepthBuffer(zbp,BUF_WIDTH); + sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); + sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); + sceGuDepthRange(65535,0); + sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + sceGuDepthFunc(GU_GEQUAL); + sceGuEnable(GU_DEPTH_TEST); + sceGuFrontFace(GU_CW); + sceGuShadeModel(GU_SMOOTH); + sceGuEnable(GU_CULL_FACE); + sceGuEnable(GU_CLIP_PLANES); + sceGuEnable(GU_TEXTURE_2D); + sceGuEnable(GU_LIGHTING); + sceGuEnable(GU_LIGHT0); + sceGuFinish(); + sceGuSync(0,0); + sceDisplayWaitVblankStart(); + sceGuDisplay(GU_TRUE); + + // run sample + + int valTorus = 0; + int valEnvMap = 0; + int rotateTorus = 1; + int rotateEnvMap = 1; + + while(running()) + { + sceGuStart(GU_DIRECT,list); + + // clear screen + + sceGuClearColor(0x554433); + sceGuClearDepth(0); + sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); + + // setup a light + + ScePspFVector3 dir = { 0, 0, 1 }; + sceGuLight(0,GU_DIRECTIONAL,GU_DIFFUSE,&dir); + sceGuLightColor(0,GU_DIFFUSE,0x00ff4040 ); + sceGuLightAtt(0,1.0f,0.0f,0.0f); + sceGuAmbient(0x00202020); + + // setup proj/view matrices + + sceGumMatrixMode(GU_PROJECTION); + sceGumLoadIdentity(); + sceGumPerspective(75.0f,16.0/9.0f,1.0f,1000.0f); + + sceGumMatrixMode(GU_VIEW); + sceGumLoadIdentity(); + + // setup envmap texture + + sceGuTexMode(GU_PSM_4444,0,0,0); + sceGuTexImage(0,64,64,64,env0_start); + sceGuTexFunc(GU_TFX_MODULATE,GU_TCC_RGB); + sceGuTexFilter(GU_LINEAR,GU_LINEAR); + sceGuAmbientColor(0xffffffff); + + // setup envmap matrix (2x3) + // 2d rotation/translation matrix + // [ cosa -sina ] + // [ sina cosa ] + // [ tx ty ] + + // envmap matrix is transposed + // since it is passed to GU as columns + float angle = -2.0f * valEnvMap * (GU_PI/180.0f); + float cs = cosf(angle); + float sn = sinf(angle); + ScePspFVector3 envmapMatrixColumns[2] = { + { cs, sn, 0.0f }, + { -sn, cs, 0.0f } + }; + sceGuLight( 2, GU_DIRECTIONAL, GU_DIFFUSE, &envmapMatrixColumns[0] ); + sceGuLight( 3, GU_DIRECTIONAL, GU_DIFFUSE, &envmapMatrixColumns[1] ); + + // setup envmap texture coord generation + sceGuTexMapMode( + GU_ENVIRONMENT_MAP, // envmap mode on + 2, // use 2nd light position as an envmap matrix 1st column + 3 // use 3rd light position as an envmap matrix 2nd column + ); + + // draw torus + + sceGumMatrixMode(GU_MODEL); + { + ScePspFVector3 pos = {0,0,-2.5f}; + ScePspFVector3 rot = {valTorus * 0.79f * (GU_PI/180.0f), valTorus * 0.98f * (GU_PI/180.0f), valTorus * 1.32f * (GU_PI/180.0f)}; + sceGumLoadIdentity(); + sceGumTranslate(&pos); + sceGumRotateXYZ(&rot); + } + + sceGuColor(0xffffff); + sceGumDrawArray(GU_TRIANGLES,GU_NORMAL_32BITF|GU_VERTEX_32BITF|GU_INDEX_16BIT|GU_TRANSFORM_3D,sizeof(torus_indices)/sizeof(unsigned short),torus_indices,torus_vertices); + + pspDebugScreenSetXY(0,0); + pspDebugScreenPrintf( "Press X to toggle environment map rotation" ); + pspDebugScreenSetXY(0,1); + pspDebugScreenPrintf( "Press O to toggle torus rotation" ); + + sceCtrlReadBufferPositive(&pad, 1); + if(oldButtons != pad.Buttons) + { + if(pad.Buttons & PSP_CTRL_CROSS) + rotateTorus ^= 0x01; + if(pad.Buttons & PSP_CTRL_CIRCLE) + rotateEnvMap ^= 0x01; + } + oldButtons = pad.Buttons; + + sceGuFinish(); + sceGuSync(0,0); + +// sceDisplayWaitVblankStart(); + sceGuSwapBuffers(); + + if(rotateTorus) valTorus++; + if(rotateEnvMap) valEnvMap++; + } + + sceGuTerm(); + + sceKernelExitGame(); + return 0; +} diff --git a/src/samples/gu/integerdrawing/Makefile.sample b/src/samples/gu/integerdrawing/Makefile.sample new file mode 100644 index 00000000..ef7a979f --- /dev/null +++ b/src/samples/gu/integerdrawing/Makefile.sample @@ -0,0 +1,18 @@ +TARGET = integerdrawing +OBJS = integerdrawing.o ../common/callbacks.o + +INCDIR = +CFLAGS = -G0 -Wall -O2 +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = +LIBS= -lpspgum -lpspgu -lm + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Integer Drawing Sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak + diff --git a/src/samples/gu/integerdrawing/integerdrawing.c b/src/samples/gu/integerdrawing/integerdrawing.c new file mode 100644 index 00000000..640418f7 --- /dev/null +++ b/src/samples/gu/integerdrawing/integerdrawing.c @@ -0,0 +1,286 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * beginobject.c Shows the usage of sceGuBeginObject/sceGuEndObject + * + * Copyright (c) 2007 McZonk + * + */ + +/* + This sample shows the usage of integers for 3d drawing. + 3d mode is always used when GU_TRANSFORM_2D is not specified as flag. + Instead of spending an 32bit float for weight, normal, texcoord or postion + a smaller integer value can be used. The behavior is equal for each type. + The range of the int is normalized to the interval [-1, 1]. + The maximum value is +( ( 2 ^ (number of bits) ) / 2 ) - 1. + The minimum value is -( ( 2 ^ (number of bits) ) / 2 ) - 1. + For 8 bit it is: -127 to 127, for 16 bit is it is -32767 tp 32767. + The values -128 and -32767 are greater than one. + The texcoord values can be extended by using sceGuTexScale() while the + values for positions can be scaled with sceGumScale(). + For sure there are visual differences when less bits are used. + + The behavior of 2d drawing is different. The values are directly passed + and not normalized. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "../common/callbacks.h" + +PSP_MODULE_INFO("IntDrawingModes", 0, 1, 1); +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER); + +static unsigned int __attribute__((aligned(16))) list[262144]; + +#define B 0xff444444 +#define W 0xffffffff + +/* checkerboard pattern */ +static const unsigned int __attribute__((aligned(16))) texture[256] = { +#if 1 + W, W, B, B, W, W, B, B, W, W, B, B, W, W, B, B, + W, W, B, B, W, W, B, B, W, W, B, B, W, W, B, B, + B, B, W, W, B, B, W, W, B, B, W, W, B, B, W, W, + B, B, W, W, B, B, W, W, B, B, W, W, B, B, W, W, + W, W, B, B, W, W, B, B, W, W, B, B, W, W, B, B, + W, W, B, B, W, W, B, B, W, W, B, B, W, W, B, B, + B, B, W, W, B, B, W, W, B, B, W, W, B, B, W, W, + B, B, W, W, B, B, W, W, B, B, W, W, B, B, W, W, + W, W, B, B, W, W, B, B, W, W, B, B, W, W, B, B, + W, W, B, B, W, W, B, B, W, W, B, B, W, W, B, B, + B, B, W, W, B, B, W, W, B, B, W, W, B, B, W, W, + B, B, W, W, B, B, W, W, B, B, W, W, B, B, W, W, + W, W, B, B, W, W, B, B, W, W, B, B, W, W, B, B, + W, W, B, B, W, W, B, B, W, W, B, B, W, W, B, B, + B, B, W, W, B, B, W, W, B, B, W, W, B, B, W, W, + B, B, W, W, B, B, W, W, B, B, W, W, B, B, W, W, +#else + B, W, B, W, B, W, B, W, B, W, B, W, B, W, B, W, + W, B, W, B, W, B, W, B, W, B, W, B, W, B, W, B, + B, W, B, W, B, W, B, W, B, W, B, W, B, W, B, W, + W, B, W, B, W, B, W, B, W, B, W, B, W, B, W, B, + B, W, B, W, B, W, B, W, B, W, B, W, B, W, B, W, + W, B, W, B, W, B, W, B, W, B, W, B, W, B, W, B, + B, W, B, W, B, W, B, W, B, W, B, W, B, W, B, W, + W, B, W, B, W, B, W, B, W, B, W, B, W, B, W, B, + B, W, B, W, B, W, B, W, B, W, B, W, B, W, B, W, + W, B, W, B, W, B, W, B, W, B, W, B, W, B, W, B, + B, W, B, W, B, W, B, W, B, W, B, W, B, W, B, W, + W, B, W, B, W, B, W, B, W, B, W, B, W, B, W, B, + B, W, B, W, B, W, B, W, B, W, B, W, B, W, B, W, + W, B, W, B, W, B, W, B, W, B, W, B, W, B, W, B, + B, W, B, W, B, W, B, W, B, W, B, W, B, W, B, W, + W, B, W, B, W, B, W, B, W, B, W, B, W, B, W, B, +#endif +}; + +#undef B +#undef W + +#define BUF_WIDTH (512) +#define SCR_WIDTH (480) +#define SCR_HEIGHT (272) +#define PIXEL_SIZE (4) /* change this if you change to another screenmode */ +#define FRAME_SIZE (BUF_WIDTH * SCR_HEIGHT * PIXEL_SIZE) +#define ZBUF_SIZE (BUF_WIDTH SCR_HEIGHT * 2) /* zbuffer seems to be 16-bit? */ + +typedef struct { + float s, t; + float x, y, z; +} VertT32V32; + +typedef struct { + signed short s, t; + signed short x, y, z; +} VertT16V16; + +typedef struct { + signed char s, t; + signed char x, y, z; +} VertT8V8; + +typedef struct { + signed short s, t; + float x, y, z; +} VertT16V32; + +typedef struct { + signed char s, t; + float x, y, z; +} VertT8V32; + +static VertT32V32 __attribute__((aligned(16))) vertsT32V32[3] = { + { 0.0f, 0.0f, -1.0f, -1.0f, 0.25f }, + { 1.0f, 0.0f, 1.0f, -1.0f, -0.25f }, + { 0.5f, 1.0f, 0.0f, 1.0f, 0.00f } +}; + +static VertT16V16 __attribute__((aligned(16))) vertsT16V16[3] = { + { 0, 0, -32767, -32767, 8191 }, + { 32767, 0, 32767, -32767, -8191 }, + { 16383, 32767, 0, 32767, 0 } +}; + +static VertT8V8 __attribute__((aligned(16))) vertsT8V8[3] = { + { 0, 0, -127, -127, 31 }, + { 127, 0, 127, -127, -31 }, + { 63, 127, 0, 127, 0 } +}; + +static VertT16V32 __attribute__((aligned(16))) vertsT16V32[3] = { + { 0, 0, -1.0f, -1.0f, 0.25f }, + { 32767, 0, 1.0f, -1.0f, -0.25f }, + { 16383, 32767, 0.0f, 1.0f, 0.00f } +}; + +static VertT8V32 __attribute__((aligned(16))) vertsT8V32[3] = { + { 0, 0, -1.0f, -1.0f, 0.25f }, + { 127, 0, 1.0f, -1.0f, -0.25f }, + { 63, 127, 0.0f, 1.0f, 0.00f } +}; + + + +typedef struct { + int prim; + int flags; + int count; + void* data; + char text[64]; +} Object; + +static Object objects[] = { + { GU_TRIANGLES, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_TRANSFORM_3D, 3, vertsT32V32, "tex 32 | pos 32" }, + { GU_TRIANGLES, GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_3D, 3, vertsT16V16, "tex 16 | pos 16" }, + { GU_TRIANGLES, GU_TEXTURE_8BIT | GU_VERTEX_8BIT | GU_TRANSFORM_3D, 3, vertsT8V8, "tex 8 | pos 8" }, + { GU_TRIANGLES, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_TRANSFORM_3D, 3, vertsT32V32, "tex 32 | pos 32" }, + { GU_TRIANGLES, GU_TEXTURE_16BIT | GU_VERTEX_32BITF | GU_TRANSFORM_3D, 3, vertsT16V32, "tex 16 | pos 32" }, + { GU_TRIANGLES, GU_TEXTURE_8BIT | GU_VERTEX_32BITF | GU_TRANSFORM_3D, 3, vertsT8V32, "tex 8 | pos 32" }, +}; +static unsigned int o = 0; + +int main(int argc, char* argv[]) { + /* Setup Homebutton Callbacks */ + setupCallbacks(); + + sceKernelDcacheWritebackAll(); + + // setup GU + + SceCtrlData pad; + sceCtrlSetSamplingCycle(0); + sceCtrlSetSamplingMode(PSP_CTRL_MODE_DIGITAL); + + sceGuInit(); + + sceGuStart(GU_DIRECT,list); + sceGuDrawBuffer(GU_PSM_8888,(void*)0,BUF_WIDTH); + sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,(void*)0x88000,BUF_WIDTH); + sceGuDepthBuffer((void*)0x110000,BUF_WIDTH); + sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); + sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); + sceGuDepthRange(0xc350,0x2710); + sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + sceGuDepthFunc(GU_GEQUAL); + sceGuEnable(GU_DEPTH_TEST); + sceGuFrontFace(GU_CCW); + sceGuColor(0xffffffff); + sceGuShadeModel(GU_SMOOTH); +// sceGuEnable(GU_CULL_FACE); + sceGuEnable(GU_CLIP_PLANES); + sceGuEnable(GU_TEXTURE_2D); + sceGuTexMode(GU_PSM_8888, 0, 0, 0); + sceGuTexImage(0, 16, 16, 16, texture); + sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGB); + sceGuTexEnvColor(0xffffff); + sceGuTexFilter(GU_LINEAR, GU_LINEAR); + sceGuTexWrap(GU_REPEAT, GU_REPEAT); + sceGuTexScale(1.0f, 1.0f); + sceGuTexOffset(0.0f, 0.0f); + sceGuAmbientColor(0xffffffff); + + sceGuFinish(); + sceGuSync(0,0); + sceDisplayWaitVblankStart(); + sceGuDisplay(GU_TRUE); + + void* buffer = 0; + + pspDebugScreenInit(); + + unsigned int old = 0; + unsigned int flags = PSP_CTRL_CIRCLE | PSP_CTRL_CROSS; + + int tex = 1; + + while(running()) { + sceGuStart(GU_DIRECT,list); + + sceGuClearColor(0); + sceGuClearDepth(0); + sceGuClear(GU_COLOR_BUFFER_BIT | GU_DEPTH_BUFFER_BIT); + + sceGumMatrixMode(GU_PROJECTION); + sceGumLoadIdentity(); + sceGumPerspective(90.0f, 480.0/272.0f, 0.1f, 10.0f); + + sceGumMatrixMode(GU_VIEW); + sceGumLoadIdentity(); + ScePspFVector3 trans = { 0.0f, 0.0f, -1.8f }; + sceGumTranslate(&trans); + + sceGumMatrixMode(GU_MODEL); + sceGumLoadIdentity(); + + sceGumDrawArray(objects[o].prim, objects[o].flags, objects[o].count, 0, objects[o].data); + + sceCtrlReadBufferPositive(&pad, 1); + if(old != pad.Buttons) { + if(pad.Buttons & PSP_CTRL_CROSS) { + o++; + if(o >= sizeof(objects) / sizeof(Object)) { + o = 0; + } + } + if(pad.Buttons & PSP_CTRL_CIRCLE) { + tex = !tex; + if(tex) { + sceGuEnable(GU_TEXTURE_2D); + } else { + sceGuDisable(GU_TEXTURE_2D); + } + } + } + old = pad.Buttons; + + sceGuFinish(); + sceGuSync(0,0); + + pspDebugScreenSetOffset((int)buffer); + pspDebugScreenSetXY(0, 0); + pspDebugScreenPrintf("Mode: %s (X to change) Texture: %s (O to change)", objects[o].text, tex ? "on " : "off"); + + sceDisplayWaitVblankStart(); + buffer = sceGuSwapBuffers(); + } + + sceGuTerm(); + + sceKernelExitGame(); + return 0; +} diff --git a/src/samples/gu/lights/Makefile.sample b/src/samples/gu/lights/Makefile.sample new file mode 100644 index 00000000..f63a4349 --- /dev/null +++ b/src/samples/gu/lights/Makefile.sample @@ -0,0 +1,17 @@ +TARGET = lights +OBJS = lights.o ../common/callbacks.o ../common/geometry.o ../common/vram.o + +INCDIR = +CFLAGS = -G0 -Wall -O2 +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = +LIBS= -lpspgum -lpspgu -lm + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Lights Sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/gu/lights/lights.c b/src/samples/gu/lights/lights.c new file mode 100644 index 00000000..c30165d8 --- /dev/null +++ b/src/samples/gu/lights/lights.c @@ -0,0 +1,187 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "../common/callbacks.h" +#include "../common/geometry.h" +#include "../common/vram.h" + +PSP_MODULE_INFO("Lights Sample", 0, 1, 1); +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER); + +static unsigned int __attribute__((aligned(16))) list[262144]; + +#define BUF_WIDTH (512) +#define SCR_WIDTH (480) +#define SCR_HEIGHT (272) + +#define GRID_COLUMNS 32 +#define GRID_ROWS 32 +#define GRID_SIZE 10.0f + +NPVertex __attribute__((aligned(16))) grid_vertices[GRID_COLUMNS*GRID_ROWS]; +unsigned short __attribute__((aligned(16))) grid_indices[(GRID_COLUMNS-1)*(GRID_ROWS-1)*6]; + +#define TORUS_SLICES 48 // numc +#define TORUS_ROWS 48 // numt +#define TORUS_RADIUS 1.0f +#define TORUS_THICKNESS 0.5f + +#define LIGHT_DISTANCE 3.0f + +NPVertex __attribute__((aligned(16))) torus_vertices[TORUS_SLICES*TORUS_ROWS]; +unsigned short __attribute__((aligned(16))) torus_indices[TORUS_SLICES*TORUS_ROWS*6]; + +unsigned int colors[4] = +{ + 0xffff0000, + 0xff00ff00, + 0xff0000ff, + 0xffff00ff +}; + +int main(int argc, char* argv[]) +{ + unsigned int i; + + setupCallbacks(); + + // generate geometry + + generateGridNP(GRID_COLUMNS,GRID_ROWS,GRID_SIZE,GRID_SIZE,grid_vertices,grid_indices); + generateTorusNP(TORUS_SLICES,TORUS_ROWS,TORUS_RADIUS,TORUS_THICKNESS,torus_vertices,torus_indices); + + // flush cache so that no stray data remains + + sceKernelDcacheWritebackAll(); + + // setup GU + + void* fbp0 = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_8888); + void* fbp1 = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_8888); + void* zbp = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_4444); + + sceGuInit(); + + sceGuStart(GU_DIRECT,list); + sceGuDrawBuffer(GU_PSM_8888,fbp0,BUF_WIDTH); + sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,fbp1,BUF_WIDTH); + sceGuDepthBuffer(zbp,BUF_WIDTH); + sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); + sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); + sceGuDepthRange(0xc350,0x2710); + sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + sceGuDepthFunc(GU_GEQUAL); + sceGuEnable(GU_DEPTH_TEST); + sceGuFrontFace(GU_CW); + sceGuShadeModel(GU_SMOOTH); + sceGuEnable(GU_CULL_FACE); + sceGuEnable(GU_CLIP_PLANES); + sceGuEnable(GU_LIGHTING); + sceGuEnable(GU_LIGHT0); + sceGuEnable(GU_LIGHT1); + sceGuEnable(GU_LIGHT2); + sceGuEnable(GU_LIGHT3); + sceGuFinish(); + sceGuSync(0,0); + sceDisplayWaitVblankStart(); + sceGuDisplay(GU_TRUE); + + // run sample + + int val = 0; + + while(running()) + { + sceGuStart(GU_DIRECT,list); + + // clear screen + + sceGuClearColor(0x554433); + sceGuClearDepth(0); + sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); + + // setup a light + + for (i = 0; i < 4; ++i) + { + ScePspFVector3 pos = { cosf(i*(GU_PI/2) + val * (GU_PI/180)) * LIGHT_DISTANCE, 0, sinf(i*(GU_PI/2) + val * (GU_PI/180)) * LIGHT_DISTANCE }; + sceGuLight(i,GU_POINTLIGHT,GU_DIFFUSE_AND_SPECULAR,&pos); + sceGuLightColor(i,GU_DIFFUSE,colors[i]); + sceGuLightColor(i,GU_SPECULAR,0xffffffff); + sceGuLightAtt(i,0.0f,1.0f,0.0f); + } + + sceGuSpecular(12.0f); + sceGuAmbient(0x00222222); + + // setup matrices for cube + + sceGumMatrixMode(GU_PROJECTION); + sceGumLoadIdentity(); + sceGumPerspective(75.0f,16.0f/9.0f,1.0f,1000.0f); + + sceGumMatrixMode(GU_VIEW); + { + ScePspFVector3 pos = {0,0,-3.5f}; + + sceGumLoadIdentity(); + sceGumTranslate(&pos); + } + + // draw grid + + sceGumMatrixMode(GU_MODEL); + { + ScePspFVector3 pos = {0,-1.5f,0}; + + sceGumLoadIdentity(); + sceGumTranslate(&pos); + } + + sceGuColor(0xff7777); + sceGumDrawArray(GU_TRIANGLES,NP_VERTEX_FORMAT|GU_INDEX_16BIT|GU_TRANSFORM_3D,sizeof(grid_indices)/sizeof(unsigned short),grid_indices,grid_vertices); + + // draw torus + + sceGumMatrixMode(GU_MODEL); + { + ScePspFVector3 rot = {val * 0.79f * (GU_PI/180.0f), val * 0.98f * (GU_PI/180.0f), val * 1.32f * (GU_PI/180.0f)}; + + sceGumLoadIdentity(); + sceGumRotateXYZ(&rot); + } + + sceGuColor(0xffffff); + sceGumDrawArray(GU_TRIANGLES,NP_VERTEX_FORMAT|GU_INDEX_16BIT|GU_TRANSFORM_3D,sizeof(torus_indices)/sizeof(unsigned short),torus_indices,torus_vertices); + + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuSwapBuffers(); + + val++; + } + + sceGuTerm(); + + sceKernelExitGame(); + return 0; +} diff --git a/src/samples/gu/lines/Makefile.sample b/src/samples/gu/lines/Makefile.sample new file mode 100644 index 00000000..88ebb84f --- /dev/null +++ b/src/samples/gu/lines/Makefile.sample @@ -0,0 +1,17 @@ +TARGET = lines +OBJS = lines.o ../common/callbacks.o ../common/vram.o + +INCDIR = +CFLAGS = -G0 -Wall -O2 +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = +LIBS= -lpspgu + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Lines Sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/gu/lines/lines.c b/src/samples/gu/lines/lines.c new file mode 100644 index 00000000..508e1637 --- /dev/null +++ b/src/samples/gu/lines/lines.c @@ -0,0 +1,211 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "../common/callbacks.h" +#include "../common/vram.h" + +PSP_MODULE_INFO("Lines Sample", 0, 1, 1); +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER); + +static unsigned int __attribute__((aligned(16))) list[262144]; + +struct Vertex +{ + float x,y,z; +}; + +#define BUF_WIDTH (512) +#define SCR_WIDTH (480) +#define SCR_HEIGHT (272) + +#define NUM_SLICES 128 +#define NUM_ROWS 128 +#define RING_SIZE 2.0f +#define RING_RADIUS 1.0f +#define SPRITE_SIZE 0.025f + +unsigned int colors[8] = +{ + 0xffff0000, + 0xffff00ff, + 0xff0000ff, + 0xff00ffff, + 0xff00ff00, + 0xffffff00, + 0xffffffff, + 0xff00ffff +}; + +#define NUM_LINES 12 +#define NUM_VERTICES 8 +#define SPEED 4.0f +#define FADE_SPEED 0.015f; + +struct Vertex lines[NUM_LINES][NUM_VERTICES]; +unsigned int curr_line = 0; +struct Vertex position[8]; +struct Vertex direction[8]; + +float fade = 0; +unsigned int color_index = 0; + +int main(int argc, char* argv[]) +{ + unsigned int i; + + setupCallbacks(); + + // initialize lines + + memset(lines,0,sizeof(lines)); + + srand(time(0)); + + for (i = 0; i < NUM_VERTICES; ++i) + { + position[i].x = (((float)rand())/RAND_MAX) * (SCR_WIDTH-1); + position[i].y = (((float)rand())/RAND_MAX) * (SCR_HEIGHT-1); + + direction[i].x = (((float)rand())/(RAND_MAX/2)-1.0f) * SPEED; + direction[i].y = (((float)rand())/(RAND_MAX/2)-1.0f) * SPEED; + } + + // setup GU + + void* fbp0 = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_8888); + void* fbp1 = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_8888); + void* zbp = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_4444); + + sceGuInit(); + + sceGuStart(GU_DIRECT,list); + sceGuDrawBuffer(GU_PSM_8888,fbp0,BUF_WIDTH); + sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,fbp1,BUF_WIDTH); + sceGuDepthBuffer(zbp,BUF_WIDTH); + sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); + sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); + sceGuDepthRange(65535,0); + sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuDisplay(GU_TRUE); + + // run sample + + while(running()) + { + unsigned int i,j; + unsigned int result; + + // update lines + + for (i = 0; i < NUM_VERTICES; ++i) + { + position[i].x += direction[i].x; + position[i].y += direction[i].y; + + if (position[i].x < 0) + { + position[i].x = 0; + direction[i].x = (((float)rand())/RAND_MAX) * SPEED; + direction[i].y += 0.1f * (direction[i].y / fabsf(direction[i].y)); + } + else if (position[i].x >= SCR_WIDTH) + { + position[i].x = (SCR_WIDTH-1); + direction[i].x = -(((float)rand())/RAND_MAX) * SPEED; + direction[i].y += 0.1f * (direction[i].y / fabsf(direction[i].y)); + } + + if (position[i].y < 0) + { + position[i].y = 0; + direction[i].x += 0.1f * (direction[i].x / fabsf(direction[i].x)); + direction[i].y = (0.1f+((float)rand())/RAND_MAX) * SPEED; + } + else if (position[i].y >= SCR_HEIGHT) + { + position[i].y = (SCR_HEIGHT-1); + direction[i].x += 0.1f * (direction[i].x / fabsf(direction[i].x)); + direction[i].y = -(0.1f+((float)rand())/RAND_MAX) * SPEED; + } + + lines[curr_line][i].x = position[i].x; + lines[curr_line][i].y = position[i].y; + } + curr_line = (curr_line+1) % NUM_LINES; + + fade += FADE_SPEED; + if (fade >= 1.0f) + { + fade -= 1.0f; + color_index = (color_index+1) & 7; + } + + sceGuStart(GU_DIRECT,list); + + // clear screen + + sceGuClearColor(0); + sceGuClear(GU_COLOR_BUFFER_BIT); + + // render lines + + result = 0; + for (i = 0; i < 4; ++i) + { + int ca = (colors[color_index] >> (i*8)) & 0xff; + int cb = (colors[(color_index+1)&7] >> (i*8)) & 0xff; + result |= ((unsigned char)(ca + (cb-ca) * fade)) << (i*8); + } + + sceGuColor(result); + + for (i = 0; i < NUM_LINES; ++i) + { + // we make local copies of the line into the main buffer here, so we don't have to flush the cache + + struct Vertex* vertices = sceGuGetMemory((NUM_VERTICES+1) * sizeof(struct Vertex)); + + // create a lineloop + + for (j = 0; j < NUM_VERTICES; ++j) + vertices[j] = lines[i][j]; + vertices[NUM_VERTICES] = lines[i][0]; + + sceGuDrawArray(GU_LINE_STRIP,GU_VERTEX_32BITF|GU_TRANSFORM_2D,(NUM_VERTICES+1),0,vertices); + } + + // wait for next frame + + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuSwapBuffers(); + } + + sceGuTerm(); + + sceKernelExitGame(); + return 0; +} diff --git a/src/samples/gu/logic/Makefile.sample b/src/samples/gu/logic/Makefile.sample new file mode 100644 index 00000000..e1509de8 --- /dev/null +++ b/src/samples/gu/logic/Makefile.sample @@ -0,0 +1,17 @@ +TARGET = logic +OBJS = logic.o ../common/callbacks.o ../common/vram.o + +INCDIR = +CFLAGS = -G0 -Wall -O2 +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = +LIBS= -lpspgu -lm + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Logic Sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/gu/logic/logic.c b/src/samples/gu/logic/logic.c new file mode 100644 index 00000000..41ab15aa --- /dev/null +++ b/src/samples/gu/logic/logic.c @@ -0,0 +1,165 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "../common/callbacks.h" +#include "../common/vram.h" + +PSP_MODULE_INFO("Logic Sample", 0, 1, 1); +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER); + +static unsigned int __attribute__((aligned(16))) list[262144]; + +struct Vertex +{ + float x,y,z; +}; + +#define BUF_WIDTH (512) +#define SCR_WIDTH (480) +#define SCR_HEIGHT (272) + +const char* names[16] = +{ + "GU_CLEAR", + "GU_AND", + "GU_AND_REVERSE", + "GU_COPY", + "GU_AND_INVERTED", + "GU_NOOP", + "GU_XOR", + "GU_OR", + "GU_NOR", + "GU_EQUIV", + "GU_INVERTED", + "GU_OR_REVERSE", + "GU_COPY_INVERTED", + "GU_OR_INVERTED", + "GU_NAND", + "GU_SET" +}; + +#define TIME_SLICE 5 + +int curr_state = 0; +struct timeval base_time; + +int main(int argc, char* argv[]) +{ + pspDebugScreenInit(); + + setupCallbacks(); + + // setup GU + + void* fbp0 = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_8888); + void* fbp1 = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_8888); + void* zbp = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_4444); + + sceGuInit(); + + sceGuStart(GU_DIRECT,list); + sceGuDrawBuffer(GU_PSM_8888,fbp0,BUF_WIDTH); + sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,fbp1,BUF_WIDTH); + sceGuDepthBuffer(zbp,BUF_WIDTH); + sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); + sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); + sceGuDepthRange(65535,0); + sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + sceGuFinish(); + sceGuSync(0,0); + sceDisplayWaitVblankStart(); + sceGuDisplay(GU_TRUE); + + int val = 0; + + gettimeofday(&base_time,0); + + while(running()) + { + struct Vertex* vertices; + struct timeval tv; + + sceGuStart(GU_DIRECT,list); + + // clear screen + + sceGuClearColor(0); + sceGuClearDepth(0); + sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); + + // draw triangle 1 (normal) + + sceGuColor(0xffffffff); + + vertices = (struct Vertex*)sceGuGetMemory(3*sizeof(struct Vertex)); + vertices[0].x = (SCR_WIDTH/2) + cosf(val * (GU_PI/180)) * (SCR_HEIGHT/2); + vertices[0].y = (SCR_HEIGHT/2) + sinf(val * (GU_PI/180)) * (SCR_HEIGHT/2); + vertices[0].z = 0; + vertices[1].x = (SCR_WIDTH/2) + cosf((val+120) * (GU_PI/180)) * (SCR_HEIGHT/2); + vertices[1].y = (SCR_HEIGHT/2) + sinf((val+120) * (GU_PI/180)) * (SCR_HEIGHT/2); + vertices[1].z = 0; + vertices[2].x = (SCR_WIDTH/2) + cosf((val+240) * (GU_PI/180)) * (SCR_HEIGHT/2); + vertices[2].y = (SCR_HEIGHT/2) + sinf((val+240) * (GU_PI/180)) * (SCR_HEIGHT/2); + vertices[2].z = 0; + sceGuDrawArray(GU_TRIANGLES,GU_VERTEX_32BITF|GU_TRANSFORM_2D,3,0,vertices); + + // draw triangle 2 (affected by logic op) + + sceGuEnable(GU_COLOR_LOGIC_OP); + sceGuLogicalOp(curr_state); + + sceGuColor(0xffff00ff); + + vertices = (struct Vertex*)sceGuGetMemory(3*sizeof(struct Vertex)); + vertices[0].x = (SCR_WIDTH/2) + cosf((val*1.1f) * (GU_PI/180)) * (SCR_HEIGHT/2); + vertices[0].y = (SCR_HEIGHT/2) + sinf((val*1.1f) * (GU_PI/180)) * (SCR_HEIGHT/2); + vertices[0].z = 0; + vertices[1].x = (SCR_WIDTH/2) + cosf((val*1.1f+120) * (GU_PI/180)) * (SCR_HEIGHT/2); + vertices[1].y = (SCR_HEIGHT/2) + sinf((val*1.1f+120) * (GU_PI/180)) * (SCR_HEIGHT/2); + vertices[1].z = 0; + vertices[2].x = (SCR_WIDTH/2) + cosf((val*1.1f+240) * (GU_PI/180)) * (SCR_HEIGHT/2); + vertices[2].y = (SCR_HEIGHT/2) + sinf((val*1.1f+240) * (GU_PI/180)) * (SCR_HEIGHT/2); + vertices[2].z = 0; + sceGuDrawArray(GU_TRIANGLES,GU_VERTEX_32BITF|GU_TRANSFORM_2D,3,0,vertices); + + sceGuDisable(GU_COLOR_LOGIC_OP); + + sceGuFinish(); + sceGuSync(0,0); + + gettimeofday(&tv,0); + if ((tv.tv_sec-base_time.tv_sec) > TIME_SLICE) + { + curr_state = (curr_state + 1) & 15; + base_time = tv; + } + + sceDisplayWaitVblankStart(); + sceGuSwapBuffers(); + pspDebugScreenSetXY(0,0); + pspDebugScreenPrintf("%s",names[curr_state]); + + val++; + } + + sceGuTerm(); + + sceKernelExitGame(); + return 0; +} diff --git a/src/samples/gu/morph/Makefile.sample b/src/samples/gu/morph/Makefile.sample new file mode 100644 index 00000000..e731b91a --- /dev/null +++ b/src/samples/gu/morph/Makefile.sample @@ -0,0 +1,17 @@ +TARGET = morph +OBJS = morph.o + +INCDIR = +CFLAGS = -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = +LIBS= -lpspgum -lpspgu -lm + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Morph Sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/gu/morph/morph.c b/src/samples/gu/morph/morph.c new file mode 100644 index 00000000..3fcf08e3 --- /dev/null +++ b/src/samples/gu/morph/morph.c @@ -0,0 +1,230 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +PSP_MODULE_INFO("Morph Sample", 0, 1, 1); +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER); + +#define printf pspDebugScreenPrintf + +static unsigned int __attribute__((aligned(16))) list[262144]; + +#define max(a,b) ((a)<(b)) ? (b) : (a) +#define min(a,b) ((a)<(b)) ? (a) : (b) + +struct Vertex +{ + unsigned int color; + ScePspFVector3 normal; + ScePspFVector3 pos; +}; + +struct MorphVertex +{ + struct Vertex v0; + struct Vertex v1; +}; + +int SetupCallbacks(); + +#define BUF_WIDTH (512) +#define SCR_WIDTH (480) +#define SCR_HEIGHT (272) +#define PIXEL_SIZE (4) /* change this if you change to another screenmode */ +#define FRAME_SIZE (BUF_WIDTH * SCR_HEIGHT * PIXEL_SIZE) +#define ZBUF_SIZE (BUF_WIDTH SCR_HEIGHT * 2) /* zbuffer seems to be 16-bit? */ + +#define ROWS (64) +#define COLS (64) + +unsigned short __attribute__((aligned(16))) indices[(ROWS+1)*(COLS+1)*6]; +struct MorphVertex __attribute__((aligned(16))) vertices[ROWS*COLS]; + +int main(int argc, char* argv[]) +{ + unsigned int i,j; + SetupCallbacks(); + + // generate sphere & cube that can blend between each other (a bit messy right now) + + for (i = 0; i < ROWS; ++i) + { + float di = (((float)i)/ROWS); + float s = di * GU_PI * 2; + ScePspFVector3 v = { cosf(s), cosf(s), sinf(s) }; + + for(j = 0; j < COLS; ++j) + { + unsigned short* curr = &indices[(j+(i*COLS))*6]; + unsigned int i1 = (i+1)%ROWS, j1 = (j+1)%COLS; + + float t = (((float)j)/COLS) * GU_PI * 2; + + ScePspFVector3 v2 = { v.x * cosf(t), v.y * sinf(t), v.z }; + ScePspFVector3 v3; + + // cheap mans sphere -> cube algo :D + v3.x = v2.x > 0 ? min(v2.x * 10.0f,1.0f) : max(v2.x * 10.0f,-1.0f); + v3.y = v2.y > 0 ? min(v2.y * 10.0f,1.0f) : max(v2.y * 10.0f,-1.0f); + v3.z = v2.z > 0 ? min(v2.z * 10.0f,1.0f) : max(v2.z * 10.0f,-1.0f); + + vertices[j+i*COLS].v0.color = (0xff<<24)|((int)(fabsf(v2.x) * 255.0f) << 16)|((int)(fabsf(v2.y) * 255.0f) << 8)|((int)(fabsf(v2.z) * 255.0f)); + vertices[j+i*COLS].v0.normal = v2; + vertices[j+i*COLS].v0.pos = v2; + + vertices[j+i*COLS].v1.color = vertices[j+i*COLS].v0.color; + vertices[j+i*COLS].v1.normal = v3; + gumNormalize(&vertices[j+i*COLS].v1.normal); + vertices[j+i*COLS].v1.pos = v3; + + // indices + *curr++ = j + i * COLS; + *curr++ = j1 + i * COLS; + *curr++ = j + i1 * COLS; + + *curr++ = j1 + i * COLS; + *curr++ = j1 + i1 * COLS; + *curr++ = j + i1 * COLS; + } + } + + sceKernelDcacheWritebackAll(); + + // setup GU + + sceGuInit(); + + sceGuStart(GU_DIRECT,list); + sceGuDrawBuffer(GU_PSM_8888,(void*)0,BUF_WIDTH); + sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,(void*)0x88000,BUF_WIDTH); + sceGuDepthBuffer((void*)0x110000,BUF_WIDTH); + sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); + sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); + sceGuDepthRange(0xc350,0x2710); + sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + sceGuDepthFunc(GU_GEQUAL); + sceGuEnable(GU_DEPTH_TEST); + sceGuFrontFace(GU_CW); + sceGuShadeModel(GU_SMOOTH); + sceGuEnable(GU_CULL_FACE); + sceGuEnable(GU_LIGHTING); + sceGuEnable(GU_LIGHT0); + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuDisplay(GU_TRUE); + + sceGumMatrixMode(GU_PROJECTION); + sceGumLoadIdentity(); + sceGumPerspective(75.0f,16.0f/9.0f,0.5f,1000.0f); + + sceGumMatrixMode(GU_VIEW); + { + ScePspFVector3 pos = {0.0f,0.0f,-2.5f}; + + sceGumLoadIdentity(); + sceGumTranslate(&pos); + } + + // run sample + + int val = 0; + + for(;;) + { + ScePspFVector3 lpos = { 1, 0, 1 }; + sceGuStart(GU_DIRECT,list); + + // clear screen + + sceGuClearColor(0xff554433); + sceGuClearDepth(0); + sceGuLight(0,GU_DIRECTIONAL,GU_DIFFUSE_AND_SPECULAR,&lpos); + sceGuLightColor(0,GU_DIFFUSE_AND_SPECULAR,0xffffffff); + sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); + sceGuSpecular(12.0f); + + + // rotate morphing mesh + + sceGumMatrixMode(GU_MODEL); + { + ScePspFVector3 rot = {val * 0.79f * (GU_PI/180.0f), val * 0.98f * (GU_PI/180.0f), val * 1.32f * (GU_PI/180.0f)}; + + sceGumLoadIdentity(); + sceGumRotateXYZ(&rot); + } + + sceGuAmbientColor(0xffffffff); + + // draw cube + + sceGuMorphWeight(0,0.5f * sinf(val * (GU_PI/180.0f)) + 0.5f); + sceGuMorphWeight(1,-0.5f * sinf(val * (GU_PI/180.0f)) + 0.5f); + sceGumDrawArray(GU_TRIANGLES,GU_COLOR_8888|GU_NORMAL_32BITF|GU_VERTEX_32BITF|GU_VERTICES(2)|GU_INDEX_16BIT|GU_TRANSFORM_3D,sizeof(indices)/sizeof(unsigned short),indices,vertices); + + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuSwapBuffers(); + + val++; + } + + sceGuTerm(); + + sceKernelExitGame(); + return 0; +} + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + sceKernelExitGame(); + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0); + if(thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} diff --git a/src/samples/gu/morphskin/Makefile.sample b/src/samples/gu/morphskin/Makefile.sample new file mode 100644 index 00000000..c902d1e7 --- /dev/null +++ b/src/samples/gu/morphskin/Makefile.sample @@ -0,0 +1,17 @@ +TARGET = morphskin +OBJS = morphskin.o + +INCDIR = +CFLAGS = -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = +LIBS = -lpspgum -lpspgu -lm + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Simultaneous Morphing and Skinning Sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/gu/morphskin/morphskin.c b/src/samples/gu/morphskin/morphskin.c new file mode 100644 index 00000000..350c3d29 --- /dev/null +++ b/src/samples/gu/morphskin/morphskin.c @@ -0,0 +1,352 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * skinning.c - Sample to demonstrate simultaneous + * keyframed morphing and matrix skinning on GPU + * + * Copyright (c) 2005 Jesper Svennevid + * Copyright (c) 2005 Renaldas Zioma + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +PSP_MODULE_INFO("MorphingSkinning Sample", 0, 1, 1); +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER); + +static unsigned int __attribute__((aligned(16))) list[262144]; + +#define WEIGHTS_PER_VERTEX 8 +typedef struct Vertex +{ + float skinWeight[WEIGHTS_PER_VERTEX]; + float u,v; + unsigned int color; + float nx,ny,nz; + float x,y,z; +} Vertex; + +#define MORPH_TARGETS 2 +typedef struct MorphVertex +{ + Vertex v[MORPH_TARGETS]; +} MorphVertex; + +/* cylinder */ + +#define CYLINDER_SLICES 48 // numc +#define CYLINDER_ROWS 48 // numt +#define CYLINDER_RADIUS 0.35f +#define CYLINDER_LENGTH 1.25f + +MorphVertex __attribute__((aligned(16))) cylinder_vertices[CYLINDER_SLICES*CYLINDER_ROWS]; +unsigned short __attribute__((aligned(16))) cylinder_indices[CYLINDER_SLICES*(CYLINDER_ROWS-1)*6]; + +#define min( a, b ) ( ((a)<(b))?(a):(b) ) +#define max( a, b ) ( ((a)>(b))?(a):(b) ) + +int SetupCallbacks(); + +void genSkinnedMonsterCylinder( unsigned slices, unsigned rows, float length, float radius, unsigned bones, + MorphVertex* dstVertices, unsigned short* dstIndices ); + +#define BUF_WIDTH (512) +#define SCR_WIDTH (480) +#define SCR_HEIGHT (272) +#define PIXEL_SIZE (4) /* change this if you change to another screenmode */ +#define FRAME_SIZE (BUF_WIDTH * SCR_HEIGHT * PIXEL_SIZE) +#define ZBUF_SIZE (BUF_WIDTH SCR_HEIGHT * 2) /* zbuffer seems to be 16-bit? */ + +#define HIERARCHY_SIZE (WEIGHTS_PER_VERTEX) + +int main(int argc, char* argv[]) +{ + SetupCallbacks(); + + // generate geometry + + genSkinnedMonsterCylinder( CYLINDER_ROWS, CYLINDER_SLICES, CYLINDER_LENGTH, CYLINDER_RADIUS, HIERARCHY_SIZE, cylinder_vertices, cylinder_indices ); + + // flush cache so that no stray data remains + + sceKernelDcacheWritebackAll(); + + // setup GU + + sceGuInit(); + + sceGuStart(GU_DIRECT,list); + sceGuDrawBuffer(GU_PSM_8888,(void*)0,BUF_WIDTH); + sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,(void*)0x88000,BUF_WIDTH); + sceGuDepthBuffer((void*)0x110000,BUF_WIDTH); + sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); + sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); + sceGuDepthRange(0xc350,0x2710); + sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + sceGuDepthFunc(GU_GEQUAL); + sceGuEnable(GU_DEPTH_TEST); + sceGuFrontFace(GU_CW); + sceGuShadeModel(GU_SMOOTH); + sceGuEnable(GU_CULL_FACE); + sceGuEnable(GU_DITHER); + + // setup a light + + ScePspFVector3 lightDir = { 0, 0, 1 }; + sceGuLight(0,GU_DIRECTIONAL,GU_DIFFUSE,&lightDir); + sceGuLightColor(0,GU_DIFFUSE,0x00ffffff); + sceGuLightAtt(0,1.0f,0.0f,0.0f); + sceGuAmbient(0x00202020); + sceGuEnable(GU_LIGHTING); + sceGuEnable(GU_LIGHT0); + + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuDisplay(GU_TRUE); + + // setup matrices + + sceGumMatrixMode(GU_PROJECTION); + sceGumLoadIdentity(); + sceGumPerspective(75.0f,16.0f/9.0f,0.5f,1000.0f); + + sceGumMatrixMode(GU_VIEW); + { + ScePspFVector3 pos = {0,0,-5.0f}; + + sceGumLoadIdentity(); + sceGumTranslate(&pos); + } + + // setup bones hierarchy + + ScePspFMatrix4 bones[HIERARCHY_SIZE]; + float boneLength = CYLINDER_LENGTH; + + // run sample + + int val = 0; + int q; + + for(;;) + { + sceGuStart(GU_DIRECT,list); + + // clear screen + + sceGuClearColor(0xff554433); + sceGuClearDepth(0); + sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); + + // update matrices + + for( q = 0; q < HIERARCHY_SIZE; ++q ) + { + ScePspFVector3 rot = {0,0,cosf( val * 1.0f * (GU_PI/180.0f))}; + gumLoadIdentity(&bones[q]); + gumRotateXYZ(&bones[q],&rot); + if( q > 0 ) + { + ScePspFVector3 pos = {boneLength, 0, 0}; + + gumTranslate(&bones[q],&pos); + gumMultMatrix(&bones[q], &bones[q-1], &bones[q]); + } + + // set matrices for skinning + + sceGuBoneMatrix(q, &bones[q]); + sceGuMorphWeight(q, 1.0f); + } + + sceGumMatrixMode(GU_MODEL); + { + ScePspFVector3 rot = { GU_PI/7.0f, GU_PI/9.0f, 0 }; + + sceGumLoadIdentity(); + sceGumRotateXYZ(&rot); + } + + for( q = 0 ; q < 4; ++q ) + { + ScePspFVector3 rot = {0,0,GU_PI/2.0f}; + sceGumRotateXYZ(&rot); + + // set weights for morphing + + sceGuMorphWeight(0, 0.5f * sinf(val * (GU_PI/180.0f)) + 0.5f); + sceGuMorphWeight(1, -0.5f * sinf(val * (GU_PI/180.0f)) + 0.5f); + + // submit geometry to GPU, where each vertex is + // a) first morphed (interpolated) between keyframe targets + // b) then skinned using position and bone (matrix) weights which were calculated in the 1st step + + sceGumDrawArray(GU_TRIANGLES, + GU_VERTICES( MORPH_TARGETS )| + GU_WEIGHTS( WEIGHTS_PER_VERTEX )| + GU_NORMAL_32BITF|GU_TEXTURE_32BITF|GU_COLOR_8888|GU_VERTEX_32BITF|GU_WEIGHT_32BITF|GU_INDEX_16BIT|GU_TRANSFORM_3D, + sizeof(cylinder_indices)/sizeof(unsigned short),cylinder_indices,cylinder_vertices); + } + + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuSwapBuffers(); + + val++; + } + + sceGuTerm(); + + sceKernelExitGame(); + return 0; +} + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + sceKernelExitGame(); + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0); + if(thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} + +void genSkinnedMonsterCylinder( unsigned slices, unsigned rows, float length, float radius, unsigned bones, + MorphVertex* dstMorphVertices, unsigned short* dstIndices ) +{ + unsigned int i,j; + + float lengthStep = length / (float)rows; + float boneStep = ((float)bones-1)/((float)rows); + + // generate keyframed geom + + for (j = 0; j < slices; ++j) + { + for (i = 0; i < rows; ++i) + { + struct MorphVertex* curr = &dstMorphVertices[i+j*rows]; + float s = i + 0.5f; + float t = j; + float cs,ct,ss,st; + float d0, d1, combinedDeform; + + cs = cosf(s * (2*GU_PI)/slices); + ct = cosf(t * (2*GU_PI)/rows); + ss = sinf(s * (2*GU_PI)/slices); + st = sinf(t * (2*GU_PI)/rows); + + curr->v[0].nx = 0; + curr->v[0].ny = ct; + curr->v[0].nz = st; + + curr->v[1].nx = 0; + curr->v[1].ny = ct; + curr->v[1].nz = st; + + // keyframed pair for vertex positions + + curr->v[0].x = lengthStep * (float)i; + curr->v[0].y = radius * ct; + curr->v[0].z = radius * st; + + d0 = 0.5f * cosf( s ) * cosf( t ); + d1 = sinf( 0.5f*GU_PI * ((float)i / (float)rows) ); + combinedDeform = d0 + d1 * d1; + + curr->v[1].x = lengthStep * (float) + combinedDeform * curr->v[1].nx; + curr->v[1].y = radius * ct + combinedDeform * curr->v[1].ny; + curr->v[1].z = radius * st + combinedDeform * curr->v[1].nz; + + // keyframed pair for colors + + curr->v[0].color = 0x0000ff; + + d0 *= 3.0f; + d0 = min( d0, 1.0f ); d0 = max( d0, 0.0f ); + curr->v[1].color = + (((int)(d0 * 255.0f) & 0xff)<<16) + + (((int)(d0 * 255.0f) & 0xff)<<8) + + 0xff; + + int q = 0; + for( ; q < bones; q++ ) + { + float b = min( ((float)bones-1), boneStep * (float)i ); + float t = b - (float)q; + + // calculate cubic blending functions for skinning weights + // each vertex is influenced by 4 bones (matrices) at most + + float t2 = t*t; + float t3 = t*t*t; + + float f = 0; + if( t >= 0.0f && t < 1.0f ) f = t3/6.0f; + if( t >= 1.0f && t < 2.0f ) f = -0.5f*t3 + 2.0f*t2 - 2.0f*t + 2.0f/3.0f; + if( t >= 2.0f && t < 3.0f ) f = 0.5f*t3 - 4.0f*t2 + 10.0f*t - 22.0f/3.0f; + if( t >= 3.0f && t < 4.0f ) f = -t3/6.0f + 2.0f*t2 - 8.0f*t + 32.0f/3.0f; + + curr->v[0].skinWeight[q] = f; + curr->v[1].skinWeight[q] = f; + } + } + } + + for (j = 0; j < slices; ++j) + { + for (i = 0; i < rows-1; ++i) + { + unsigned short* curr = &dstIndices[(i+(j*(rows-1)))*6]; + + *curr++ = i + j * rows; + *curr++ = (i+1) + j * rows; + *curr++ = i + ((j+1)%slices) * rows; + + *curr++ = (i+1) + j * rows; + *curr++ = (i+1) + ((j+1)%slices) * rows; + *curr++ = i + ((j+1)%slices) * rows; + } + } +} + diff --git a/src/samples/gu/ortho/Makefile.sample b/src/samples/gu/ortho/Makefile.sample new file mode 100644 index 00000000..db58974c --- /dev/null +++ b/src/samples/gu/ortho/Makefile.sample @@ -0,0 +1,19 @@ +PSPSDK=$(shell psp-config --pspsdk-path) +PSPDIR=$(shell psp-config --psp-prefix) + +TARGET = ortho +OBJS = ortho.o ../common/callbacks.o ../common/vram.o + +CFLAGS = -O2 -G0 -Wall -g +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LIBS = -lpspgum -lpspgu -lm +LDFLAGS = + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Ortho Sample + +include $(PSPSDK)/lib/build.mak + diff --git a/src/samples/gu/ortho/ortho.c b/src/samples/gu/ortho/ortho.c new file mode 100644 index 00000000..5c6d4bdb --- /dev/null +++ b/src/samples/gu/ortho/ortho.c @@ -0,0 +1,140 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2006 David Perry (Insert_witty_name) + * Simple pixel perfect ortho projection sample + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "../common/callbacks.h" +#include "../common/vram.h" + +PSP_MODULE_INFO("Orthographic Projection", 0, 1, 1); + +static unsigned int __attribute__((aligned(16))) list[262144]; + +#define BUF_WIDTH (512) +#define SCR_WIDTH (480) +#define SCR_HEIGHT (272) + +struct Vertex +{ + unsigned int color; + float x, y, z; +}; + +struct Vertex __attribute__((aligned(16))) vertices[1*3] = +{ + {0xFF0000FF, 0.0f, -50.0f, 0.0f}, // Top, red + {0xFF00FF00, 50.0f, 50.0f, 0.0f}, // Right, green + {0xFFFF0000, -50.0f, 50.0f, 0.0f}, // Left, blue +}; + + +int main(int argc, char* argv[]) +{ + pspDebugScreenInit(); + setupCallbacks(); + + // Setup GU + + void* fbp0 = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_8888); + void* fbp1 = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_8888); + void* zbp = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_4444); + + sceGuInit(); + + sceGuStart(GU_DIRECT,list); + sceGuDrawBuffer(GU_PSM_8888,fbp0,BUF_WIDTH); + sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,fbp1,BUF_WIDTH); + sceGuDepthBuffer(zbp,BUF_WIDTH); + sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); + sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); + sceGuDepthRange(65535,0); + sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + sceGuFrontFace(GU_CW); + sceGuShadeModel(GU_SMOOTH); + sceGuDisable(GU_TEXTURE_2D); + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuDisplay(1); + + sceCtrlSetSamplingCycle(0); + sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG); + + ScePspFVector3 pos = {240.0f, 136.0f, 0.0f}; + + int val = 0; + + while(running()) + { + SceCtrlData pad; + + sceGuStart(GU_DIRECT,list); + + sceGuClearColor(0); + sceGuClearDepth(0); + sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); + + sceCtrlPeekBufferPositive(&pad, 1); + + if(pad.Buttons & PSP_CTRL_UP) + pos.z += 1.0f / 100.0f; + if(pad.Buttons & PSP_CTRL_DOWN) + pos.z -= 1.0f / 100.0f; + + if(abs(pad.Lx-128) > 32) + pos.x += ((pad.Lx-128)/128.0f); + if(abs(pad.Ly-128) > 32) + pos.y += ((pad.Ly-128)/128.0f); + + sceGumMatrixMode(GU_PROJECTION); + sceGumLoadIdentity(); + sceGumOrtho(0, 480, 272, 0, -1, 1); + + sceGumMatrixMode(GU_VIEW); + sceGumLoadIdentity(); + + sceGumMatrixMode(GU_MODEL); + sceGumLoadIdentity(); + + // Draw triangle + + sceGumTranslate(&pos); + sceGumRotateZ(val*0.03f); + + sceGumDrawArray(GU_TRIANGLES,GU_COLOR_8888|GU_VERTEX_32BITF|GU_TRANSFORM_3D,1*3,0,vertices); + + sceGuFinish(); + sceGuSync(0,0); + + pspDebugScreenSetOffset((int)fbp0); + pspDebugScreenSetXY(0,0); + + pspDebugScreenPrintf("x: %.2f y: %.2f z: %.2f",pos.x,pos.y,pos.z); + + sceDisplayWaitVblankStart(); + fbp0 = sceGuSwapBuffers(); + + val++; + + } + + sceGuTerm(); + + sceKernelExitGame(); + return 0; +} diff --git a/src/samples/gu/reflection/Makefile.sample b/src/samples/gu/reflection/Makefile.sample new file mode 100644 index 00000000..beeb0f31 --- /dev/null +++ b/src/samples/gu/reflection/Makefile.sample @@ -0,0 +1,20 @@ +TARGET = reflection +OBJS = reflection.o logo.o + +INCDIR = +CFLAGS = -G0 -Wall -O2 +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = +LIBS= -lpspgum -lpspgu -lm + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Reflection Sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak + +logo.o: ../cube/logo.raw + bin2o -i $< logo.o logo diff --git a/src/samples/gu/reflection/reflection.c b/src/samples/gu/reflection/reflection.c new file mode 100644 index 00000000..b0c7ef08 --- /dev/null +++ b/src/samples/gu/reflection/reflection.c @@ -0,0 +1,304 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + * Copyright (c) 2005 McZonk + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +PSP_MODULE_INFO("Reflection Sample", 0, 1, 1); +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER); + +#define printf pspDebugScreenPrintf + +static unsigned int __attribute__((aligned(16))) list[262144]; +extern unsigned char logo_start[]; + +struct Vertex +{ + float u, v; + unsigned int color; + float x,y,z; +}; + +struct Vertex __attribute__((aligned(16))) obj[36] = { + {0, 0, 0xff6666ff,-1,-1, 1}, + {1, 0, 0xff6666ff, 1,-1, 1}, + {1, 1, 0xff6666ff, 1, 1, 1}, + {0, 0, 0xff6666ff,-1,-1, 1}, + {1, 1, 0xff6666ff, 1, 1, 1}, + {0, 1, 0xff6666ff,-1, 1, 1}, + + {1, 1, 0xff66ff66, 1, 1, 1}, + {0, 1, 0xff66ff66, 1,-1, 1}, + {0, 0, 0xff66ff66, 1,-1,-1}, + {1, 1, 0xff66ff66, 1, 1, 1}, + {0, 0, 0xff66ff66, 1,-1,-1}, + {1, 0, 0xff66ff66, 1, 1,-1}, + + {0, 1, 0xffff6666,-1, 1, 1}, + {0, 0, 0xffff6666, 1, 1, 1}, + {1, 0, 0xffff6666, 1, 1,-1}, + {0, 1, 0xffff6666,-1, 1, 1}, + {1, 0, 0xffff6666, 1, 1,-1}, + {1, 1, 0xffff6666,-1, 1,-1}, + + + {1, 1, 0xff6666ff, 1,-1,-1}, + {0, 1, 0xff6666ff,-1,-1,-1}, + {0, 0, 0xff6666ff,-1, 1,-1}, + {1, 1, 0xff6666ff, 1,-1,-1}, + {0, 0, 0xff6666ff,-1, 1,-1}, + {1, 0, 0xff6666ff, 1, 1,-1}, + + {1, 0, 0xff66ff66,-1,-1,-1}, + {1, 1, 0xff66ff66,-1,-1, 1}, + {0, 1, 0xff66ff66,-1, 1, 1}, + {1, 0, 0xff66ff66,-1,-1,-1}, + {0, 1, 0xff66ff66,-1, 1, 1}, + {0, 0, 0xff66ff66,-1, 1,-1}, + + {0, 1, 0xffff6666,-1,-1,-1}, + {0, 0, 0xffff6666, 1,-1,-1}, + {1, 0, 0xffff6666, 1,-1, 1}, + {0, 1, 0xffff6666,-1,-1,-1}, + {1, 0, 0xffff6666, 1,-1, 1}, + {1, 1, 0xffff6666,-1,-1, 1}, +}; + +struct Vertex __attribute__((aligned(16))) mirror[6] = { + {0, 0, 0xaa000000, -2.0f, 0, -2.0f}, + {2, 2, 0xaa000000, 2.0f, 0, 2.0f}, + {2, 0, 0xaa000000, 2.0f, 0, -2.0f}, + + {0, 0, 0xaa000000, -2.0f, 0, -2.0f}, + {0, 2, 0xaa000000, -2.0f, 0, 2.0f}, + {2, 2, 0xaa000000, 2.0f, 0, 2.0f} +}; + +struct Vertex __attribute__((aligned(16))) border[6] = { + {0, 0, 0xff0055aa, -2.125f, -0.01, -2.125f}, + {2, 2, 0xff0055aa, 2.125f, -0.01, 2.125f}, + {2, 0, 0xff0055aa, 2.125f, -0.01, -2.125f}, + + {0, 0, 0xff0055aa, -2.125f, -0.01, -2.125f}, + {0, 2, 0xff0055aa, -2.125f, -0.01, 2.125f}, + {2, 2, 0xff0055aa, 2.125f, -0.01, 2.125f} +}; + +int SetupCallbacks(); + +#define BUF_WIDTH (512) +#define SCR_WIDTH (480) +#define SCR_HEIGHT (272) +#define PIXEL_SIZE (4) /* change this if you change to another screenmode */ +#define FRAME_SIZE (BUF_WIDTH * SCR_HEIGHT * PIXEL_SIZE) +#define ZBUF_SIZE (BUF_WIDTH SCR_HEIGHT * 2) /* zbuffer seems to be 16-bit? */ + +int main(int argc, char* argv[]) +{ + SetupCallbacks(); + + // setup GU + + sceGuInit(); + + sceGuStart(GU_DIRECT,list); + sceGuDrawBuffer(GU_PSM_8888,(void*)0,BUF_WIDTH); + sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,(void*)0x88000,BUF_WIDTH); + sceGuDepthBuffer((void*)0x110000,BUF_WIDTH); + sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); + sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); + sceGuDepthRange(0xc350,0x2710); + sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + sceGuDepthFunc(GU_GEQUAL); + sceGuEnable(GU_DEPTH_TEST); + sceGuFrontFace(GU_CCW); + sceGuShadeModel(GU_SMOOTH); + sceGuEnable(GU_CULL_FACE); + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuDisplay(GU_TRUE); + + // run sample + + int val = 0; + + for(;;) + { + float move = sinf(((float)val / 180.0f) * GU_PI); + if(move < 0) { + move *= -1; + } + move += 1; + + float rot = ((float)val / 180.0f) * GU_PI; + + sceGuStart(GU_DIRECT,list); + + // clear screen + + sceGuClearColor(0xff554433); + sceGuClearDepth(0); + sceGuClearStencil(0); + sceGuClear(GU_COLOR_BUFFER_BIT | GU_STENCIL_BUFFER_BIT | GU_DEPTH_BUFFER_BIT); + + // setup matrices for cube + + sceGumMatrixMode(GU_PROJECTION); + sceGumLoadIdentity(); + sceGumPerspective(60.0f,16.0f/9.0f,0.5f,1000.0f); + + sceGumMatrixMode(GU_VIEW); + { + ScePspFVector3 pos = {0,-0.5f,-5.5f}; + ScePspFVector3 rot = {(30.0f * GU_PI) / 180.0f, (val * 0.2f * GU_PI) / 180.0f, 0.0f}; + + sceGumLoadIdentity(); + sceGumTranslate(&pos); + sceGumRotateXYZ(&rot); + } + + sceGumMatrixMode(GU_MODEL); + sceGumLoadIdentity(); + + // draw mirrored view + + sceGumPushMatrix(); + { + ScePspFVector3 scale = {1,-1,1}; + sceGumScale(&scale); + } + + sceGuFrontFace(GU_CCW); + sceGuEnable(GU_STENCIL_TEST); // Stencil test + sceGuDepthMask(GU_TRUE); + sceGuStencilFunc(GU_ALWAYS, 1, 1); // always set 1 bit in 1 bit mask + sceGuStencilOp(GU_KEEP, GU_KEEP, GU_REPLACE); // keep value on failed test (fail and zfail) and replace on pass + sceGumDrawArray(GU_TRIANGLES, GU_TEXTURE_32BITF | GU_COLOR_8888 | GU_VERTEX_32BITF | GU_TRANSFORM_3D, 6, 0, mirror); + sceGuDepthMask(GU_FALSE); + + sceGuTexMode(GU_PSM_4444,0,0,0); + sceGuTexImage(0,64,64,64,logo_start); + sceGuTexFunc(GU_TFX_ADD,GU_TCC_RGB); + sceGuTexFilter(GU_LINEAR,GU_LINEAR); + sceGuTexScale(1.0f,1.0f); + sceGuTexOffset(0.0f,0.0f); + sceGuEnable(GU_TEXTURE_2D); + sceGuFrontFace(GU_CW); + sceGuStencilFunc(GU_EQUAL, 1, 1); // allow drawing where stencil is 1 + sceGuStencilOp(GU_KEEP, GU_KEEP, GU_KEEP); // keep the stencil buffer unchanged + + { + ScePspFVector3 pos = {0,move,0}; + ScePspFVector3 rvec = {0,rot * -0.83f, 0}; + + sceGumTranslate(&pos); + sceGumRotateXYZ(&rvec); + } + + sceGumDrawArray(GU_TRIANGLES, GU_TEXTURE_32BITF | GU_COLOR_8888 | GU_VERTEX_32BITF | GU_TRANSFORM_3D, 36, 0, obj); + sceGuDisable(GU_TEXTURE_2D); + sceGuDisable(GU_STENCIL_TEST); + + sceGumPopMatrix(); + + // draw normal view + sceGuEnable(GU_TEXTURE_2D); + sceGuTexMode(GU_PSM_4444,0,0,0); + sceGuTexImage(0,64,64,64,logo_start); + sceGuTexFunc(GU_TFX_REPLACE,GU_TCC_RGBA); + sceGuTexFilter(GU_LINEAR,GU_LINEAR); + sceGuTexScale(1.0f,1.0f); + sceGuTexOffset(0.0f,0.0f); + sceGuFrontFace(GU_CCW); + sceGuEnable(GU_BLEND); + sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0); + sceGumDrawArray(GU_TRIANGLES, GU_TEXTURE_32BITF | GU_COLOR_8888 | GU_VERTEX_32BITF | GU_TRANSFORM_3D, 6, 0, mirror); + sceGuDisable(GU_BLEND); + sceGuDisable(GU_TEXTURE_2D); + + sceGumDrawArray(GU_TRIANGLES, GU_TEXTURE_32BITF | GU_COLOR_8888 | GU_VERTEX_32BITF | GU_TRANSFORM_3D, 6, 0, border); + + sceGuEnable(GU_TEXTURE_2D); + sceGuTexMode(GU_PSM_4444,0,0,0); + sceGuTexImage(0,64,64,64,logo_start); + sceGuTexFunc(GU_TFX_ADD,GU_TCC_RGB); + sceGuTexFilter(GU_LINEAR,GU_LINEAR); + sceGuTexScale(1.0f,1.0f); + sceGuTexOffset(0.0f,0.0f); + + { + ScePspFVector3 pos = {0,move,0}; + ScePspFVector3 rvec = {0,rot * -0.83f, 0}; + + sceGumTranslate(&pos); + sceGumRotateXYZ(&rvec); + } + + sceGumDrawArray(GU_TRIANGLES, GU_TEXTURE_32BITF | GU_COLOR_8888 | GU_VERTEX_32BITF | GU_TRANSFORM_3D, 36, 0, obj); + sceGuDisable(GU_TEXTURE_2D); + + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuSwapBuffers(); + + val++; + } + + sceGuTerm(); + + sceKernelExitGame(); + return 0; +} + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + sceKernelExitGame(); + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0); + if(thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} diff --git a/src/samples/gu/rendertarget/Makefile.sample b/src/samples/gu/rendertarget/Makefile.sample new file mode 100644 index 00000000..abfd9113 --- /dev/null +++ b/src/samples/gu/rendertarget/Makefile.sample @@ -0,0 +1,17 @@ +TARGET = rendertarget +OBJS = rendertarget.o + +INCDIR = +CFLAGS = -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = +LIBS = -lpspgum -lpspgu -lm + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Render-To-Texture Sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/gu/rendertarget/rendertarget.c b/src/samples/gu/rendertarget/rendertarget.c new file mode 100644 index 00000000..21d8229f --- /dev/null +++ b/src/samples/gu/rendertarget/rendertarget.c @@ -0,0 +1,417 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * rendertarget.c - Sample to demonstrate usage of ofscreen + * texture as a render target + * + * Copyright (c) 2005 Jesper Svennevid + * Copyright (c) 2005 Renaldas Zioma + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +PSP_MODULE_INFO("RenderTarget Sample", 0, 1, 1); +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER); + +#define printf pspDebugScreenPrintf + +static unsigned int __attribute__((aligned(16))) list[262144]; + +typedef struct Vertex_ColorUV +{ + float u, v; + unsigned int color; + float x,y,z; +} Vertex_ColorUV; + +typedef struct Vertex_Normal +{ + float nx,ny,nz; + float x,y,z; +} Vertex_Normal; + + +typedef struct Texture +{ + int format; + int mipmap; + int width, height, stride; + const void* data; +} Texture; + +/* cube */ + +Vertex_ColorUV __attribute__((aligned(16))) cube_vertices[12*3] = +{ + {0, 0, 0xff7f0000,-1,-1, 1}, // 0 + {1, 0, 0xff7f0000,-1, 1, 1}, // 4 + {1, 1, 0xff7f0000, 1, 1, 1}, // 5 + + {0, 0, 0xff7f0000,-1,-1, 1}, // 0 + {1, 1, 0xff7f0000, 1, 1, 1}, // 5 + {0, 1, 0xff7f0000, 1,-1, 1}, // 1 + + {0, 0, 0xff7f0000,-1,-1,-1}, // 3 + {1, 0, 0xff7f0000, 1,-1,-1}, // 2 + {1, 1, 0xff7f0000, 1, 1,-1}, // 6 + + {0, 0, 0xff7f0000,-1,-1,-1}, // 3 + {1, 1, 0xff7f0000, 1, 1,-1}, // 6 + {0, 1, 0xff7f0000,-1, 1,-1}, // 7 + + {0, 0, 0xff007f00, 1,-1,-1}, // 0 + {1, 0, 0xff007f00, 1,-1, 1}, // 3 + {1, 1, 0xff007f00, 1, 1, 1}, // 7 + + {0, 0, 0xff007f00, 1,-1,-1}, // 0 + {1, 1, 0xff007f00, 1, 1, 1}, // 7 + {0, 1, 0xff007f00, 1, 1,-1}, // 4 + + {0, 0, 0xff007f00,-1,-1,-1}, // 0 + {1, 0, 0xff007f00,-1, 1,-1}, // 3 + {1, 1, 0xff007f00,-1, 1, 1}, // 7 + + {0, 0, 0xff007f00,-1,-1,-1}, // 0 + {1, 1, 0xff007f00,-1, 1, 1}, // 7 + {0, 1, 0xff007f00,-1,-1, 1}, // 4 + + {0, 0, 0xff00007f,-1, 1,-1}, // 0 + {1, 0, 0xff00007f, 1, 1,-1}, // 1 + {1, 1, 0xff00007f, 1, 1, 1}, // 2 + + {0, 0, 0xff00007f,-1, 1,-1}, // 0 + {1, 1, 0xff00007f, 1, 1, 1}, // 2 + {0, 1, 0xff00007f,-1, 1, 1}, // 3 + + {0, 0, 0xff00007f,-1,-1,-1}, // 4 + {1, 0, 0xff00007f,-1,-1, 1}, // 7 + {1, 1, 0xff00007f, 1,-1, 1}, // 6 + + {0, 0, 0xff00007f,-1,-1,-1}, // 4 + {1, 1, 0xff00007f, 1,-1, 1}, // 6 + {0, 1, 0xff00007f, 1,-1,-1}, // 5 +}; + +/* torus */ + +#define TORUS_SLICES 48 // numc +#define TORUS_ROWS 48 // numt +#define TORUS_RADIUS 1.0f +#define TORUS_THICKNESS 0.5f + +Vertex_Normal __attribute__((aligned(16))) torus_vertices[TORUS_SLICES*TORUS_ROWS]; +unsigned short __attribute__((aligned(16))) torus_indices[TORUS_SLICES*TORUS_ROWS*6]; + + +int SetupCallbacks(); + +void genTorus( unsigned slices, unsigned rows, float radius, float thickness, + Vertex_Normal* dstVertices, unsigned short* dstIndices ); + +#define BUF_WIDTH (512) +#define SCR_WIDTH (480) +#define SCR_HEIGHT (272) +#define PIXEL_SIZE (4) /* change this if you change to another screenmode */ +#define FRAME_SIZE (BUF_WIDTH * SCR_HEIGHT * PIXEL_SIZE) +#define ZBUF_SIZE (BUF_WIDTH SCR_HEIGHT * 2) /* zbuffer seems to be 16-bit? */ + +void drawCube( Texture* texture, int val ) +{ + // setup matrices for cube + + sceGumMatrixMode(GU_PROJECTION); + sceGumLoadIdentity(); + sceGumPerspective(75.0f,16.0f/9.0f,0.5f,1000.0f); + + sceGumMatrixMode(GU_VIEW); + { + ScePspFVector3 pos = {0.0f,0.0f,-2.5f}; + + sceGumLoadIdentity(); + sceGumTranslate(&pos); + } + + sceGumMatrixMode(GU_MODEL); + { + ScePspFVector3 rot = {val * 0.263f * (GU_PI/180.0f), val * 0.32f * (GU_PI/180.0f), val * 0.44f * (GU_PI/180.0f)}; + + sceGumLoadIdentity(); + sceGumRotateXYZ(&rot); + } + + // setup texture + + sceGuTexMode(texture->format,0,0,0); + sceGuTexImage(texture->mipmap,texture->width,texture->height,texture->stride,texture->data); + sceGuTexFunc(GU_TFX_ADD,GU_TCC_RGB); + sceGuTexFilter(GU_LINEAR,GU_LINEAR); + sceGuTexScale(1.0f,1.0f); + sceGuTexOffset(0.0f,0.0f); + sceGuAmbientColor(0xffffffff); + + sceGuEnable(GU_TEXTURE_2D); + + // draw cube + + sceGumDrawArray(GU_TRIANGLES,GU_TEXTURE_32BITF|GU_COLOR_8888|GU_VERTEX_32BITF|GU_TRANSFORM_3D,12*3,0,cube_vertices); + + sceGuDisable(GU_TEXTURE_2D); +} + +void drawTorus( int val ) +{ + // setup a light + + ScePspFVector3 dir = { 0, 0, 1 }; + sceGuLight(0,GU_DIRECTIONAL,GU_DIFFUSE,&dir); + sceGuLightColor(0,GU_DIFFUSE,0x00ff4040 ); + sceGuLightAtt(0,1.0f,0.0f,0.0f); + sceGuAmbient(0x00202020); + + // setup texture + sceGuDisable(GU_TEXTURE_2D); + sceGuEnable(GU_LIGHTING); + sceGuEnable(GU_LIGHT0); + + // setup matrices for torus + + sceGumMatrixMode(GU_PROJECTION); + sceGumLoadIdentity(); + sceGumPerspective(75.0f,16.0f/9.0f,0.5f,1000.0f); + + sceGumMatrixMode(GU_VIEW); + { + ScePspFVector3 pos = {0.0f,0.0f,-2.5f}; + + sceGumLoadIdentity(); + sceGumTranslate(&pos); + } + + sceGumMatrixMode(GU_MODEL); + { + ScePspFVector3 rot = {val * 0.79f * (GU_PI/180.0f), val * 0.98f * (GU_PI/180.0f), val * 1.32f * (GU_PI/180.0f)}; + + sceGumLoadIdentity(); + sceGumRotateXYZ(&rot); + } + + // draw torus + + sceGuColor(0xffffff); + sceGumDrawArray(GU_TRIANGLES,GU_NORMAL_32BITF|GU_VERTEX_32BITF|GU_INDEX_16BIT|GU_TRANSFORM_3D,sizeof(torus_indices)/sizeof(unsigned short),torus_indices,torus_vertices); + + + // restore state + + sceGuDisable(GU_LIGHTING); + sceGuDisable(GU_LIGHT0); + sceGuEnable(GU_TEXTURE_2D); +} + + + +int main(int argc, char* argv[]) +{ + SetupCallbacks(); + + // generate geometry + + genTorus( TORUS_ROWS, TORUS_SLICES, TORUS_RADIUS, TORUS_THICKNESS, torus_vertices, torus_indices ); + + // flush cache so that no stray data remains + + sceKernelDcacheWritebackAll(); + + // setup Edram buffers + + void* frameBuffer = (void*)0; + const void* doubleBuffer = (void*)0x44000; + const void* renderTarget = (void*)0x88000; + const void* depthBuffer = (void*)0x110000; + + // setup GU + + sceGuInit(); + + sceGuStart(GU_DIRECT,list); + sceGuDrawBuffer(GU_PSM_4444,frameBuffer,BUF_WIDTH); + sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,(void*)doubleBuffer,BUF_WIDTH); + sceGuDepthBuffer((void*)depthBuffer,BUF_WIDTH); + sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); + sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); + sceGuDepthRange(0xc350,0x2710); + sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + sceGuDepthFunc(GU_GEQUAL); + sceGuEnable(GU_DEPTH_TEST); + sceGuFrontFace(GU_CW); + sceGuShadeModel(GU_SMOOTH); + sceGuEnable(GU_CULL_FACE); + sceGuEnable(GU_TEXTURE_2D); + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuDisplay(GU_TRUE); + + // run sample + int val = 0; + Texture offscreenTexture = { + GU_PSM_4444, + 0, 128, 128, 128, + sceGeEdramGetAddr() + (int)renderTarget + }; + + for(;;) + { + sceGuStart(GU_DIRECT,list); + + { + sceGuDrawBufferList(GU_PSM_4444,(void*)renderTarget,offscreenTexture.stride); + + // setup viewport + + sceGuOffset(2048 - (offscreenTexture.width/2),2048 - (offscreenTexture.height/2)); + sceGuViewport(2048,2048,offscreenTexture.width,offscreenTexture.height); + + // clear screen + + sceGuClearColor(0xffffffff); + sceGuClearDepth(0); + sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); + + // draw torus to offscreen texture + + drawTorus( val ); + } + + { + // set frame buffer + + sceGuDrawBufferList(GU_PSM_4444,(void*)frameBuffer,BUF_WIDTH); + + // setup viewport + + sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); + sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); + + // clear screen + + sceGuClearColor(0xff554433); + sceGuClearDepth(0); + sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); + + // draw cube using offscreen texture + + drawCube( &offscreenTexture, val ); + + } + + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + frameBuffer = sceGuSwapBuffers(); + + val++; + } + + sceGuTerm(); + + sceKernelExitGame(); + return 0; +} + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + sceKernelExitGame(); + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0); + if(thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} + +/* usefull geometry functions */ +void genTorus( unsigned slices, unsigned rows, float radius, float thickness, Vertex_Normal* dstVertices, unsigned short* dstIndices ) +{ + unsigned int i,j; + + // generate torus (TODO: tri-strips) + for (j = 0; j < slices; ++j) + { + for (i = 0; i < rows; ++i) + { + struct Vertex_Normal* curr = &dstVertices[i+j*rows]; + float s = i + 0.5f; + float t = j; + float cs,ct,ss,st; + + cs = cosf(s * (2*GU_PI)/slices); + ct = cosf(t * (2*GU_PI)/rows); + ss = sinf(s * (2*GU_PI)/slices); + st = sinf(t * (2*GU_PI)/rows); + + curr->nx = cs * ct; + curr->ny = cs * st; + curr->nz = ss; + + curr->x = (radius + thickness * cs) * ct; + curr->y = (radius + thickness * cs) * st; + curr->z = thickness * ss; + } + } + + for (j = 0; j < slices; ++j) + { + for (i = 0; i < rows; ++i) + { + unsigned short* curr = &dstIndices[(i+(j*rows))*6]; + unsigned int i1 = (i+1)%rows, j1 = (j+1)%slices; + + *curr++ = i + j * rows; + *curr++ = i1 + j * rows; + *curr++ = i + j1 * rows; + + *curr++ = i1 + j * rows; + *curr++ = i1 + j1 * rows; + *curr++ = i + j1 * rows; + } + } +} diff --git a/src/samples/gu/shadowprojection/Makefile.sample b/src/samples/gu/shadowprojection/Makefile.sample new file mode 100644 index 00000000..143e1575 --- /dev/null +++ b/src/samples/gu/shadowprojection/Makefile.sample @@ -0,0 +1,17 @@ +TARGET = shadowprojection +OBJS = shadowprojection.o + +INCDIR = +CFLAGS = -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = +LIBS = -lpspgum -lpspgu -lm + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Shadow Projection Sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/gu/shadowprojection/shadowprojection.c b/src/samples/gu/shadowprojection/shadowprojection.c new file mode 100644 index 00000000..7197e52b --- /dev/null +++ b/src/samples/gu/shadowprojection/shadowprojection.c @@ -0,0 +1,512 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * shadowmap.c - Sample to demonstrate projective texture mapping + * used for shadowmap implementation + * + * Copyright (c) 2005 Jesper Svennevid + * Copyright (c) 2005 Renaldas Zioma + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +PSP_MODULE_INFO("Shadow Projection Sample", 0, 1, 1); +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER); + +#define printf pspDebugScreenPrintf + +static unsigned int __attribute__((aligned(16))) list[262144]; + +typedef struct Vertex_Normal +{ + float nx,ny,nz; + float x,y,z; +} Vertex_Normal; + +typedef struct Texture +{ + int format; + int mipmap; + int width, height, stride; + const void* data; +} Texture; + +/* grid */ +#define GRID_COLUMNS 32 +#define GRID_ROWS 32 +#define GRID_SIZE 10.0f + +Vertex_Normal __attribute__((aligned(16))) grid_vertices[GRID_COLUMNS*GRID_ROWS]; +unsigned short __attribute__((aligned(16))) grid_indices[(GRID_COLUMNS-1)*(GRID_ROWS-1)*6]; + +/* torus */ + +#define TORUS_SLICES 48 // numc +#define TORUS_ROWS 48 // numt +#define TORUS_RADIUS 1.0f +#define TORUS_THICKNESS 0.5f + +Vertex_Normal __attribute__((aligned(16))) torus_vertices[TORUS_SLICES*TORUS_ROWS]; +unsigned short __attribute__((aligned(16))) torus_indices[TORUS_SLICES*TORUS_ROWS*6]; + +#define LIGHT_DISTANCE 3.0f + + +int SetupCallbacks(); + +void genGrid( unsigned rows, unsigned columns, float size, + Vertex_Normal* dstVertices, unsigned short* dstIndices ); +void genTorus( unsigned slices, unsigned rows, float radius, float thickness, + Vertex_Normal* dstVertices, unsigned short* dstIndices ); + +#define BUF_WIDTH (512) +#define SCR_WIDTH (480) +#define SCR_HEIGHT (272) +#define PIXEL_SIZE (4) /* change this if you change to another screenmode */ +#define FRAME_SIZE (BUF_WIDTH * SCR_HEIGHT * PIXEL_SIZE) +#define ZBUF_SIZE (BUF_WIDTH SCR_HEIGHT * 2) /* zbuffer seems to be 16-bit? */ + +typedef struct Geometry +{ + ScePspFMatrix4 world; + unsigned int count; + unsigned short* indices; + Vertex_Normal* vertices; + unsigned int color; +} Geometry; + +void drawGeometry( Geometry* geom ) +{ + sceGuSetMatrix(GU_MODEL,&geom->world); + + sceGuColor(geom->color); + sceGuDrawArray(GU_TRIANGLES,GU_NORMAL_32BITF|GU_VERTEX_32BITF|GU_INDEX_16BIT|GU_TRANSFORM_3D,geom->count,geom->indices,geom->vertices); +} + +void drawShadowCaster( Geometry* geom ) +{ + sceGuSetMatrix(GU_MODEL,&geom->world); + + sceGuColor(0x00000000); + sceGuDrawArray(GU_TRIANGLES,GU_NORMAL_32BITF|GU_VERTEX_32BITF|GU_INDEX_16BIT|GU_TRANSFORM_3D,geom->count,geom->indices,geom->vertices); +} + +void drawShadowReceiver( Geometry* geom, ScePspFMatrix4 shadowProjMatrix ) +{ + sceGuSetMatrix(GU_MODEL,&geom->world); + + // multiply shadowmap projection texture by geometry world matrix + // since geometry coords are in object space + + gumMultMatrix(&shadowProjMatrix, &shadowProjMatrix, &geom->world ); + sceGuSetMatrix(GU_TEXTURE,&shadowProjMatrix); + + sceGuColor(geom->color); + sceGuDrawArray(GU_TRIANGLES,GU_NORMAL_32BITF|GU_VERTEX_32BITF|GU_INDEX_16BIT|GU_TRANSFORM_3D,geom->count,geom->indices,geom->vertices); +} + +int main(int argc, char* argv[]) +{ + SetupCallbacks(); + + // generate geometry + + genGrid( GRID_ROWS, GRID_COLUMNS, GRID_SIZE, grid_vertices, grid_indices ); + genTorus( TORUS_ROWS, TORUS_SLICES, TORUS_RADIUS, TORUS_THICKNESS, torus_vertices, torus_indices ); + + // flush cache so that no stray data remains + + sceKernelDcacheWritebackAll(); + + // setup VRAM buffers + + void* frameBuffer = (void*)0; + const void* doubleBuffer = (void*)0x44000; + const void* renderTarget = (void*)0x88000; + const void* depthBuffer = (void*)0x110000; + + // setup GU + + sceGuInit(); + + sceGuStart(GU_DIRECT,list); + sceGuDrawBuffer(GU_PSM_4444,frameBuffer,BUF_WIDTH); + sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,(void*)doubleBuffer,BUF_WIDTH); + sceGuDepthBuffer((void*)depthBuffer,BUF_WIDTH); + sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); + sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); + sceGuDepthRange(0xc350,0x2710); + sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + sceGuDepthFunc(GU_GEQUAL); + sceGuEnable(GU_DEPTH_TEST); + sceGuFrontFace(GU_CW); + sceGuShadeModel(GU_SMOOTH); + sceGuEnable(GU_CULL_FACE); + sceGuEnable(GU_TEXTURE_2D); + sceGuEnable(GU_DITHER); + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuDisplay(GU_TRUE); + + + // setup matrices + + ScePspFMatrix4 identity; + ScePspFMatrix4 projection; + ScePspFMatrix4 view; + + gumLoadIdentity(&identity); + + gumLoadIdentity(&projection); + gumPerspective(&projection,75.0f,16.0f/9.0f,0.5f,1000.0f); + + { + ScePspFVector3 pos = {0,0,-5.0f}; + + gumLoadIdentity(&view); + gumTranslate(&view,&pos); + } + + ScePspFMatrix4 textureProjScaleTrans; + gumLoadIdentity(&textureProjScaleTrans); + textureProjScaleTrans.x.x = 0.5; + textureProjScaleTrans.y.y = -0.5; + textureProjScaleTrans.w.x = 0.5; + textureProjScaleTrans.w.y = 0.5; + + ScePspFMatrix4 lightProjection; + ScePspFMatrix4 lightProjectionInf; + ScePspFMatrix4 lightView; + ScePspFMatrix4 lightMatrix; + + gumLoadIdentity(&lightProjection); + gumPerspective(&lightProjection,75.0f,1.0f,0.1f,1000.0f); + gumLoadIdentity(&lightProjectionInf); + gumPerspective(&lightProjectionInf,75.0f,1.0f,0.0f,1000.0f); + + gumLoadIdentity(&lightView); + gumLoadIdentity(&lightMatrix); + + // define shadowmap + + Texture shadowmap = { + GU_PSM_4444, + 0, 128, 128, 128, + sceGeEdramGetAddr() + (int)renderTarget + }; + + // define geometry + + Geometry torus = { + identity, + sizeof(torus_indices)/sizeof(unsigned short), + torus_indices, + torus_vertices, + 0xffffff + }; + Geometry grid = { + identity, + sizeof(grid_indices)/sizeof(unsigned short), + grid_indices, + grid_vertices, + 0xff7777 + }; + + // run sample + + int val = 0; + + for(;;) + { + // update matrices + + // grid + { + ScePspFVector3 pos = {0,-1.5f,0}; + + gumLoadIdentity(&grid.world); + gumTranslate(&grid.world,&pos); + } + + // torus + { + ScePspFVector3 pos = {0,0.5f,0.0f}; + ScePspFVector3 rot = {val * 0.79f * (GU_PI/180.0f), val * 0.98f * (GU_PI/180.0f), val * 1.32f * (GU_PI/180.0f)}; + + gumLoadIdentity(&torus.world); + gumTranslate(&torus.world,&pos); + gumRotateXYZ(&torus.world,&rot); + } + + // orbiting light + { + ScePspFVector3 lightLookAt = { torus.world.w.x, torus.world.w.y, torus.world.w.z }; + ScePspFVector3 rot1 = {0,val * 0.79f * (GU_PI/180.0f),0}; + ScePspFVector3 rot2 = {-(GU_PI/180.0f)*60.0f,0,0}; + ScePspFVector3 pos = {0,0,LIGHT_DISTANCE}; + + gumLoadIdentity(&lightMatrix); + gumTranslate(&lightMatrix,&lightLookAt); + gumRotateXYZ(&lightMatrix,&rot1); + gumRotateXYZ(&lightMatrix,&rot2); + gumTranslate(&lightMatrix,&pos); + } + + gumFastInverse(&lightView,&lightMatrix); + + // render to shadow map + + { + sceGuStart(GU_DIRECT,list); + + // set offscreen texture as a render target + + sceGuDrawBufferList(GU_PSM_4444,(void*)renderTarget,shadowmap.stride); + + // setup viewport + + sceGuOffset(2048 - (shadowmap.width/2),2048 - (shadowmap.height/2)); + sceGuViewport(2048,2048,shadowmap.width,shadowmap.height); + + // clear screen + + sceGuClearColor(0xffffffff); + sceGuClearDepth(0); + sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); + + // setup view/projection from light + + sceGuSetMatrix(GU_PROJECTION,&lightProjection); + sceGuSetMatrix(GU_VIEW,&lightView); + + // shadow casters are drawn in black + // disable lighting and texturing + + sceGuDisable(GU_LIGHTING); + sceGuDisable(GU_TEXTURE_2D); + + // draw torus to shadow map + + drawShadowCaster( &torus ); + + sceGuFinish(); + sceGuSync(0,0); + } + + // render to frame buffer + + { + sceGuStart(GU_DIRECT,list); + + // set frame buffer + + sceGuDrawBufferList(GU_PSM_4444,(void*)frameBuffer,BUF_WIDTH); + + // setup viewport + + sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); + sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); + + // clear screen + + sceGuClearColor(0xff554433); + sceGuClearDepth(0); + sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); + + // setup view/projection from camera + + sceGuSetMatrix(GU_PROJECTION,&projection); + sceGuSetMatrix(GU_VIEW,&view); + sceGuSetMatrix(GU_MODEL,&identity); + + // setup a light + ScePspFVector3 lightPos = { lightMatrix.w.x, lightMatrix.w.y, lightMatrix.w.z }; + ScePspFVector3 lightDir = { lightMatrix.z.x, lightMatrix.z.y, lightMatrix.z.z }; + + sceGuLight(0,GU_SPOTLIGHT,GU_DIFFUSE,&lightPos); + sceGuLightSpot(0,&lightDir, 5.0, 0.6); + sceGuLightColor(0,GU_DIFFUSE,0x00ff4040); + sceGuLightAtt(0,1.0f,0.0f,0.0f); + sceGuAmbient(0x00202020); + sceGuEnable(GU_LIGHTING); + sceGuEnable(GU_LIGHT0); + + // draw torus + + drawGeometry( &torus ); + + // setup texture projection + + sceGuTexMapMode( GU_TEXTURE_MATRIX, 0, 0 ); + sceGuTexProjMapMode( GU_POSITION ); + + // set shadowmap as a texture + + sceGuTexMode(shadowmap.format,0,0,0); + sceGuTexImage(shadowmap.mipmap,shadowmap.width,shadowmap.height,shadowmap.stride,shadowmap.data); + sceGuTexFunc(GU_TFX_MODULATE,GU_TCC_RGB); + sceGuTexFilter(GU_LINEAR,GU_LINEAR); + sceGuTexWrap(GU_CLAMP,GU_CLAMP); + sceGuEnable(GU_TEXTURE_2D); + + // calculate texture projection matrix for shadowmap + + ScePspFMatrix4 shadowProj; + gumMultMatrix(&shadowProj, &lightProjectionInf, &lightView); + gumMultMatrix(&shadowProj, &textureProjScaleTrans, &shadowProj); + + // draw grid receiving shadow + + drawShadowReceiver( &grid, shadowProj ); + + sceGuFinish(); + sceGuSync(0,0); + } + + sceDisplayWaitVblankStart(); + frameBuffer = sceGuSwapBuffers(); + + val++; + } + + sceGuTerm(); + + sceKernelExitGame(); + return 0; +} + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + sceKernelExitGame(); + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0); + if(thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} + +/* usefull geometry functions */ +void genGrid( unsigned rows, unsigned columns, float size, Vertex_Normal* dstVertices, unsigned short* dstIndices ) +{ + unsigned int i,j; + + // generate grid (TODO: tri-strips) + for (j = 0; j < rows; ++j) + { + for (i = 0; i < columns; ++i) + { + Vertex_Normal* curr = &dstVertices[i+j*columns]; + + curr->nx = 0.0f; + curr->ny = 1.0f; + curr->nz = 0.0f; + + curr->x = ((i * (1.0f/((float)columns)))-0.5f) * size; + curr->y = 0; + curr->z = ((j * (1.0f/((float)columns)))-0.5f) * size; + } + } + + for (j = 0; j < rows-1; ++j) + { + for (i = 0; i < columns-1; ++i) + { + unsigned short* curr = &dstIndices[(i+(j*(columns-1)))*6]; + + *curr++ = i + j * columns; + *curr++ = (i+1) + j * columns; + *curr++ = i + (j+1) * columns; + + *curr++ = (i+1) + j * columns; + *curr++ = (i+1) + (j+1) * columns; + *curr++ = i + (j + 1) * columns; + } + } +} + +void genTorus( unsigned slices, unsigned rows, float radius, float thickness, Vertex_Normal* dstVertices, unsigned short* dstIndices ) +{ + unsigned int i,j; + + // generate torus (TODO: tri-strips) + for (j = 0; j < slices; ++j) + { + for (i = 0; i < rows; ++i) + { + struct Vertex_Normal* curr = &dstVertices[i+j*rows]; + float s = i + 0.5f; + float t = j; + float cs,ct,ss,st; + + cs = cosf(s * (2*GU_PI)/slices); + ct = cosf(t * (2*GU_PI)/rows); + ss = sinf(s * (2*GU_PI)/slices); + st = sinf(t * (2*GU_PI)/rows); + + curr->nx = cs * ct; + curr->ny = cs * st; + curr->nz = ss; + + curr->x = (radius + thickness * cs) * ct; + curr->y = (radius + thickness * cs) * st; + curr->z = thickness * ss; + } + } + + for (j = 0; j < slices; ++j) + { + for (i = 0; i < rows; ++i) + { + unsigned short* curr = &dstIndices[(i+(j*rows))*6]; + unsigned int i1 = (i+1)%rows, j1 = (j+1)%slices; + + *curr++ = i + j * rows; + *curr++ = i1 + j * rows; + *curr++ = i + j1 * rows; + + *curr++ = i1 + j * rows; + *curr++ = i1 + j1 * rows; + *curr++ = i + j1 * rows; + } + } +} diff --git a/src/samples/gu/signals/Makefile.sample b/src/samples/gu/signals/Makefile.sample new file mode 100644 index 00000000..74cb7aa7 --- /dev/null +++ b/src/samples/gu/signals/Makefile.sample @@ -0,0 +1,20 @@ +TARGET = signals +OBJS = signals.o ball.o + +INCDIR = +CFLAGS = -G0 -Wall -O2 +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = +LIBS= -lpspgum -lpspgu -lm + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Signals Sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak + +ball.o: ball.raw + bin2o -i ball.raw ball.o ball diff --git a/src/samples/gu/signals/ball.raw b/src/samples/gu/signals/ball.raw new file mode 100644 index 00000000..0ff2eea6 --- /dev/null +++ b/src/samples/gu/signals/ball.raw @@ -0,0 +1 @@ +|||||||||||ï½k­J©)¥)¥¡¡)¥J©Î¹||||||||||||||||||||RÊ1ÆÎ¹Œ±k­k­J©)¥¡)¥)¥Œ±ï½Â|||||||||||||||||Âï½Âï½Î¹Î¹Î¹­µŒ±k­)¥)¥J©k­Œ±Î¹||||||||||||||µÖµÖµÖsÎ1Æ1Æ1Æ1Æ1Æ1ÆÂl±J©)¥J©Œ±ÂRʵÖ|||||||||||ÖÚ÷ÞZë{ïãµÖ”Ò”ÒµÖµÖµÖ”ÒsÎ1Æï½Œ±Œ±­µÂsΔÒÖÚ|||||||||ÖÚãœó½÷½÷{ï9çã÷Þ÷Þ÷Þ÷Þ÷ÞÖÚµÖsÎ1Æï½Î¹Î¹1ƔҵÖÖÚ|||||||µÖ÷Þ{ï½÷œó{ï9ç9ç9çããã9ç9çã÷ÞÖÚµÖsÎÂιι1ƔҔҵÖ||||||µÖZëœó{ïZë9ç9ç9ç9ç9ç9ç9ç9ç9ç9çã÷Þ÷Þ÷Þ”ÒÂιι1ÆsÎsÎ|||||RÊ÷ÞZë{ïZë9ç9çZë9ç9ç9çZë9ç9ç9ç9ç9ç9çã9ç÷Þ”ÒÂιιÂ1ÆÂ|||sΔÒãZë9ç9ç9ç9ç9ç9ç9çZë{ïZë9ç9çZëZëZë9ç9çãÖÚsÎÂιιÂ1ÆsÎ||”Ò÷Þ9ç9ç9ç9ç9ç9ç9ç9ç{ï{ï{ïœóœóœóœó{ï{ï{ï9çããÖÚsÎï½Î¹ï½RÊRÊ|ï½sÎã9ç9çZë9ç9çZëZë{ï½÷½÷œó½÷ÞûÞû½÷œó½÷œó{ïZë9çãµÖ1Æï½ï½1ÆÂι­µsÎã9çZë{ïZëZëœó½÷½÷ÞûÞûÞûÞûÿÿÿÿÞû½÷½÷½÷½÷½÷œóZë÷ÞsÎ1ÆÂ1Æï½Œ±Œ±1ƵÖãZëœóœóœóÞûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞûÞû½÷ÞûÿÿÞû{ïã”ÒRÊ1ÆÂιk­çœk­ï½RÊÖÚ9ç{ïœóÞûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞûÞûÿÿÿÿÞûœóãsÎÂι­µJ©çœBˆ¥”çœJ©­µ1ƵÖã{ïÞûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞû{ïã”Òï½k­)¥çœ„Bˆ!„!„Bˆ„¥”¡Œ±1ƵÖ9ç½÷ÞûÞûÿÿÿÿÿÿÿÿÿÿÿÿÞûÞû½÷9çµÖ1ÆŒ±çœ„cŒBˆ!„!„cŒ!„!„BˆBˆBˆ¥”¡k­µÖãZë{ïœó½÷½÷œó{ïZëãµÖÂk­¡¥”BˆBˆBˆ!„!„cŒÆ˜„cŒ¥”„BˆBˆBˆ„çœk­ï½RʔҵÖ÷Þ÷ÞµÖ”ÒRÊï½k­çœ„BˆBˆBˆ„¥”cŒ„Ƙ¡çœÆ˜çœÆ˜„BˆBˆ„„„Ƙ¡)¥J©k­k­J©)¥¡Æ˜„„„BˆBˆ„Æ˜çœÆ˜çœ¡­µJ©)¥¡¡çœ¥”„¥”„BˆBˆcŒBˆcŒ„„cŒBˆcŒBˆBˆ„¥”„¥”眡¡)¥J©­µ|ï½k­)¥J©J©¡çœçœ„cŒ„„Bˆ„ƘƘ„Bˆ„„cŒ„çœçœ¡J©J©)¥k­ï½||Âk­J©J©J©J©)¥¡Æ˜¥”ƘƘ¥”Ƙ¡¡Æ˜¥”ƘƘ¥”Ƙ¡)¥J©J©J©J©k­Â|||­µŒ±k­J©k­k­)¥)¥¡¡¡¡¡¡¡¡¡¡¡¡)¥)¥k­k­J©k­Œ±­µ|||||ÂιŒ±Œ±Œ±k­k­J©J©J©J©J©)¥)¥J©J©J©J©J©k­k­Œ±Œ±Œ±Î¹Â||||||”ÒÂï½Î¹Î¹­µŒ±Œ±Œ±Œ±Œ±Œ±Œ±Œ±Œ±Œ±Œ±Œ±Œ±Œ±­µÎ¹Î¹ï½”Ò|||||||”Ò1Æ1ÆÂï½Î¹Î¹ï½ï½ï½ï½ÂÂï½ï½ï½ï½Î¹Î¹ï½Â1Æ1Æ”Ò|||||||||”ÒRÊRÊRÊRÊRÊRÊRÊRÊsÎsÎsÎsÎRÊRÊRÊRÊRÊRÊRÊRÊ”Ò|||||||||||”ÒRÊRʔҵֵÖÖÚÖÚÖÚÖÚÖÚÖÚÖÚÖÚµÖµÖ”ÒRÊRÊ”Ò||||||||||||||ÂRʵÖ÷Þ9çZë{ï{ï{ï{ïZë9ç÷ÞµÖRÊÂ|||||||||||||||||RÊ”ÒÖÚã{ïœó½÷½÷œó{ïãÖÚ”ÒRÊ||||||||||||||||||||”Ò÷ÞZëœóœóœóœóZë÷Þ”Ò||||||||||| \ No newline at end of file diff --git a/src/samples/gu/signals/signals.c b/src/samples/gu/signals/signals.c new file mode 100644 index 00000000..af084533 --- /dev/null +++ b/src/samples/gu/signals/signals.c @@ -0,0 +1,534 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * signals.c - Sample to demonstrate usage of GE signals under libgu API. + * + * At the start of each frame 2 vertex buffers are allocated, filled with + * data and submitted to the command-list. As soon as GPU finishes rendering + * from one of the buffers, signal is raised and interrupt handler is called + * allowing application to reuse the same buffer by filling it with data and + * submitting it back to the command-list. + * + * Sample renders 64K dynamic billboards at ~25fps using 2 vertex buffers + * pushing 3MB of vertex data to GE each frame. + * + * + * Copyright (c) 2005 Jesper Svennevid + * Copyright (c) 2005 Renaldas Zioma + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +//#define ENABLE_PROFILER +//#define ENABLE_FRAMERATE +#define USING_SIGNALS + +PSP_MODULE_INFO("GE Signals Sample", 0, 1, 1); +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER); + + +#define printf pspDebugScreenPrintf + +static unsigned int __attribute__((aligned(16))) list[262144]; +static unsigned int __attribute__((aligned(16))) smallList1[1024]; +static unsigned int __attribute__((aligned(16))) smallList2[1024]; +extern unsigned char ball_start[]; + +typedef struct InputVertex +{ + float x,y,z; +} InputVertex; + +typedef struct Vertex +{ + float u, v; // 8 + unsigned int color; // 4 + float x,y,z; // 12 +} Vertex; + +Vertex __attribute__((aligned(16))) cubeVertices[12*3] = +{ + {0, 0, 0xff7f0000,-1,-1, 1}, // 0 + {1, 0, 0xff7f0000,-1, 1, 1}, // 4 + {1, 1, 0xff7f0000, 1, 1, 1}, // 5 + + {0, 0, 0xff7f0000,-1,-1, 1}, // 0 + {1, 1, 0xff7f0000, 1, 1, 1}, // 5 + {0, 1, 0xff7f0000, 1,-1, 1}, // 1 + + {0, 0, 0xff7f0000,-1,-1,-1}, // 3 + {1, 0, 0xff7f0000, 1,-1,-1}, // 2 + {1, 1, 0xff7f0000, 1, 1,-1}, // 6 + + {0, 0, 0xff7f0000,-1,-1,-1}, // 3 + {1, 1, 0xff7f0000, 1, 1,-1}, // 6 + {0, 1, 0xff7f0000,-1, 1,-1}, // 7 + + {0, 0, 0xff007f00, 1,-1,-1}, // 0 + {1, 0, 0xff007f00, 1,-1, 1}, // 3 + {1, 1, 0xff007f00, 1, 1, 1}, // 7 + + {0, 0, 0xff007f00, 1,-1,-1}, // 0 + {1, 1, 0xff007f00, 1, 1, 1}, // 7 + {0, 1, 0xff007f00, 1, 1,-1}, // 4 + + {0, 0, 0xff007f00,-1,-1,-1}, // 0 + {1, 0, 0xff007f00,-1, 1,-1}, // 3 + {1, 1, 0xff007f00,-1, 1, 1}, // 7 + + {0, 0, 0xff007f00,-1,-1,-1}, // 0 + {1, 1, 0xff007f00,-1, 1, 1}, // 7 + {0, 1, 0xff007f00,-1,-1, 1}, // 4 + + {0, 0, 0xff00007f,-1, 1,-1}, // 0 + {1, 0, 0xff00007f, 1, 1,-1}, // 1 + {1, 1, 0xff00007f, 1, 1, 1}, // 2 + + {0, 0, 0xff00007f,-1, 1,-1}, // 0 + {1, 1, 0xff00007f, 1, 1, 1}, // 2 + {0, 1, 0xff00007f,-1, 1, 1}, // 3 + + {0, 0, 0xff00007f,-1,-1,-1}, // 4 + {1, 0, 0xff00007f,-1,-1, 1}, // 7 + {1, 1, 0xff00007f, 1,-1, 1}, // 6 + + {0, 0, 0xff00007f,-1,-1,-1}, // 4 + {1, 1, 0xff00007f, 1,-1, 1}, // 6 + {0, 1, 0xff00007f, 1,-1,-1}, // 5 +}; + + +int SetupCallbacks(); + +void create_modified_torus_billboards(Vertex* vertices, float* world, float t, int startSlice, int sliceCount ); +void render_billboards(unsigned int i); +void mySignalHandler(int id); +void myFinishHandler(int id); + +#define BUF_WIDTH (512) +#define SCR_WIDTH (480) +#define SCR_HEIGHT (272) +#define PIXEL_SIZE (4) /* change this if you change to another screenmode */ +#define FRAME_SIZE (BUF_WIDTH * SCR_HEIGHT * PIXEL_SIZE) +#define ZBUF_SIZE (BUF_WIDTH SCR_HEIGHT * 2) /* zbuffer seems to be 16-bit? */ + +#define NUM_SLICES (128) +#define NUM_ROWS (128*4) +#define RING_SIZE (2.0f) +#define RING_RADIUS (1.0f) +#define SPRITE_SIZE (0.025f*0.5f) + +#define NUM_VERTEX_BUFFERS 2 +#define NUM_ITERATIONS 16 + + +#define printf pspDebugScreenPrintf + +unsigned int colors[8] = +{ + 0xffff0000, + 0xffff00ff, + 0xff0000ff, + 0xff00ffff, + 0xff00ff00, + 0xffffff00, + 0xffffffff, + 0xff101010 +}; + +InputVertex __attribute__((aligned(64))) torus_vertices[NUM_SLICES * NUM_ROWS]; +InputVertex __attribute__((aligned(16))) torus_modifiers[NUM_ROWS]; + +// Global data +typedef struct GlobalContext +{ + Vertex* vbuffer[NUM_VERTEX_BUFFERS]; + int vertsRendered; + + ScePspFMatrix4 world; + int iterationCount; + float t; + float sint; +} GlobalContext; + +GlobalContext g_context; + +int main(int argc, char* argv[]) +{ + unsigned int i,j; + + pspDebugScreenInit(); + SetupCallbacks(); + +#ifdef ENABLE_PROFILER + // Enable profiling + pspDebugProfilerClear(); + pspDebugProfilerEnable(); +#endif + + // initialize global context + g_context.iterationCount = NUM_VERTEX_BUFFERS * NUM_ITERATIONS; + g_context.t = 0; + g_context.sint = 0; + + // initialize torus + for (i = 0; i < NUM_SLICES; ++i) + { + for (j = 0; j < NUM_ROWS; ++j) + { + float s = i + 0.5f, t = j; + float x,y,z; + + x = (RING_SIZE + RING_RADIUS * cosf(s * ((GU_PI*2)/NUM_SLICES))) * cosf(t * ((GU_PI*2)/NUM_ROWS)); + y = (RING_SIZE + RING_RADIUS * cosf(s * ((GU_PI*2)/NUM_SLICES))) * sinf(t * ((GU_PI*2)/NUM_ROWS)); + z = RING_RADIUS * sinf(s * ((GU_PI*2)/NUM_SLICES)); + + torus_vertices[j + i * NUM_ROWS].x = x; + torus_vertices[j + i * NUM_ROWS].y = y; + torus_vertices[j + i * NUM_ROWS].z = z; + } + } + + // initialize torus modifiers + + for (j = 0; j < NUM_ROWS; ++j) + { + float t = j; + torus_modifiers[j].x = 0; + torus_modifiers[j].y = 0; + torus_modifiers[j].z = 0.3*cosf( t * 8.0f *((GU_PI*2)/NUM_ROWS) ); + } + + // init GU and set callbacks + sceGuInit(); + + // 0x01 - user callback + // 0x04 - 'rendering finished' callback + sceGuSetCallback(1, &mySignalHandler); + sceGuSetCallback(4, &myFinishHandler); + + // setup GU + sceGuStart(GU_DIRECT,list); + sceGuDrawBuffer(GU_PSM_8888,(void*)0,BUF_WIDTH); + sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,(void*)0x88000,BUF_WIDTH); + sceGuDepthBuffer((void*)0x110000,BUF_WIDTH); + sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); + sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); + sceGuDepthRange(0xc350,0x2710); + sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + sceGuAlphaFunc(GU_GREATER,0,0xff); + sceGuEnable(GU_ALPHA_TEST); + sceGuDepthFunc(GU_GEQUAL); + sceGuEnable(GU_DEPTH_TEST); + sceGuFrontFace(GU_CW); + sceGuShadeModel(GU_SMOOTH); + sceGuEnable(GU_CULL_FACE); + sceGuEnable(GU_TEXTURE_2D); + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuDisplay(GU_TRUE); + + // run sample + +#ifdef USING_SIGNALS + sceGuCallMode(1); +#endif + + // generate callable command-list with texture setup + { + sceGuStart(GU_CALL, smallList1); + + // setup texture + sceGuTexMode(GU_PSM_5551,0,0,0); + sceGuTexImage(0,32,32,32,ball_start); // width, height, buffer width, tbp + sceGuTexFunc(GU_TFX_MODULATE,GU_TCC_RGBA); // NOTE: this enables reads of the alpha-component from the texture, otherwise blend/test won't work + sceGuTexFilter(GU_NEAREST,GU_NEAREST); + sceGuTexWrap(GU_CLAMP,GU_CLAMP); + sceGuTexScale(1,1); + sceGuTexOffset(0,0); + sceGuAmbientColor(0xffffffff); + + sceGuFinish(); + sceGuSync(0,0); + } + + // generate callable command-list for cube rendering + { + sceGuStart(GU_CALL, smallList2); + + // draw cube + sceGuDrawArray(GU_TRIANGLES,GU_TEXTURE_32BITF|GU_COLOR_8888|GU_VERTEX_32BITF|GU_TRANSFORM_3D,12*3,0,cubeVertices); + + sceGuFinish(); + sceGuSync(0,0); + } + + for(;;) + { + sceGuStart(GU_DIRECT,list); + + unsigned int i = 0; + for( ; i < NUM_VERTEX_BUFFERS; i++ ) + g_context.vbuffer[i] = sceGuGetMemory((NUM_SLICES/g_context.iterationCount) * 2 * NUM_ROWS * sizeof(Vertex)); + g_context.vertsRendered = 0; + + // clear screen + sceGuClearColor(0x00334455); + sceGuClearDepth(0); + sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); + + // setup matrices + sceGumMatrixMode(GU_PROJECTION); + sceGumLoadIdentity(); + sceGumPerspective(75.0f,16.0f/9.0f,0.5f,1000.0f); + + sceGumMatrixMode(GU_VIEW); + sceGumLoadIdentity(); + + sceGumMatrixMode(GU_MODEL); + { + ScePspFVector3 pos = {0.0f,0.0f,-3.5f}; + ScePspFVector3 rot = {g_context.t * 0.3f * (GU_PI/180.0f), g_context.t * 0.7f * (GU_PI/180.0f), g_context.t * 1.3f * (GU_PI/180.0f)}; + + sceGumLoadIdentity(); + sceGumTranslate(&pos); + sceGumRotateXYZ(&rot); + } + + sceGumStoreMatrix(&g_context.world); + + // call pregenerated command-list to setup texture + sceGuCallList(smallList1); + + // start billboard rendering + render_billboards(0); + + // call pregenerated command-list to render cube + { + ScePspFVector3 scale = {0.3f, 0.3f, 0.3f}; + sceGumScale(&scale); + } + + sceGumUpdateMatrix(); + sceGuCallList(smallList2); + +#ifndef USING_SIGNALS + // HACK: sceGuFinish() is called inside the signal interupt handler when all rendering job is done + // this is done in order to stall GPU if it is ahead of CPU + sceGuFinish(); +#endif + sceGuSync(0,0); + +#ifndef ENABLE_FRAMERATE + // wait for next frame + sceDisplayWaitVblankStart(); +#endif + sceGuSwapBuffers(); + + pspDebugScreenSetXY(0,0); + +#ifdef ENABLE_PROFILER + // Print profile information to the screen + pspDebugProfilerPrint(); +#endif + +#ifdef ENABLE_FRAMERATE + // simple frame rate counter + static float curr_ms = 1.0f; + static struct timeval time_slices[16]; + static int t = 0; + + float curr_fps = 1.0f / curr_ms; + + t++; + + float vertsPerSec = g_context.vertsRendered*curr_fps; + float kbPerSec = vertsPerSec * sizeof(Vertex) / 1024.0f; + gettimeofday(&time_slices[t & 15],0); + pspDebugScreenPrintf("fps: %d.%03d ms: %d vert/s: %dK MB/s: %d.%03d",(int)curr_fps, ((int)(curr_fps*1000.0f)%1000), (int)(curr_ms*1000.0f), + (int)(vertsPerSec/1000.0f), + (int)(kbPerSec/1024.0f), (int)((1000.0f/1024.0f)*((int)kbPerSec%1024)) ); + + if (!(t & 15)) + { + struct timeval last_time = time_slices[0]; + unsigned int i; + + curr_ms = 0; + for (i = 1; i < 16; ++i) + { + struct timeval curr_time = time_slices[i]; + + int curr_time_usec = curr_time.tv_usec + curr_time.tv_sec * 1000000; + int last_time_usec = last_time.tv_usec + last_time.tv_sec * 1000000; + + if( last_time_usec < curr_time_usec ) + curr_ms += (( curr_time_usec - last_time_usec ) * (1.0f/1000000.0f)); + + last_time = time_slices[i]; + } + curr_ms /= 15.0f; + } +#endif + } + + sceGuTerm(); + + sceKernelExitGame(); + return 0; +} + +/* user signal handler */ +void mySignalHandler(int id) +{ + render_billboards(id); +} + +/* 'rendering finished' signal handler */ +void myFinishHandler(int id) +{ + // do some animations + g_context.t += 0.6f; + g_context.sint = sinf(g_context.t / 2.0f); +} + +/* renders subset of billboards array */ +void render_billboards(unsigned int i) +{ + if (i >= g_context.iterationCount) return; + + + Vertex* vbuffer = g_context.vbuffer[i%NUM_VERTEX_BUFFERS]; + int sliceCount = NUM_SLICES / g_context.iterationCount; + + // fill current vertex buffer if we just started + if (i == 0) + { + create_modified_torus_billboards(vbuffer,(float*)&g_context.world, g_context.sint, sliceCount*i, sliceCount); + } + + // render previously generated vertex buffer + sceGumMatrixMode(GU_MODEL); + sceGumLoadMatrix(&g_context.world); + sceGumDrawArray(GU_SPRITES,GU_TEXTURE_32BITF|GU_COLOR_8888|GU_VERTEX_32BITF|GU_TRANSFORM_3D,sliceCount*NUM_ROWS*2,0,vbuffer); + g_context.vertsRendered += sliceCount*NUM_ROWS*2; + + // fill next vertex buffer for future rendering + int nextI = i + 1; + if (nextI < g_context.iterationCount ) + { + Vertex* vbufferNext; + vbufferNext = g_context.vbuffer[nextI%NUM_VERTEX_BUFFERS]; + create_modified_torus_billboards(vbufferNext,(float*)&g_context.world, g_context.sint, sliceCount*nextI, sliceCount); + } + +#ifdef USING_SIGNALS + // send a signal when rendering was completed + // signals 0x01..0x03 - seems to be available for custom usage + sceGuSignal( 1, nextI ); + + // HACK: keeps CPU waiting until all jobs were submitted for GPU + if (nextI == g_context.iterationCount) + sceGuFinish(); +#endif +} + +/* this function generates the billboards rendered by sceGumDrawArray() */ +void create_modified_torus_billboards( Vertex* vertices, float* world, float t, int startSlice, int sliceCount ) +{ + unsigned int i,j; + float sx, sy, sz; + + // calculate billboard world offsets + + sx = SPRITE_SIZE * world[(0 << 2)+0] + SPRITE_SIZE * world[(0 << 2)+1]; + sy = SPRITE_SIZE * world[(1 << 2)+0] + SPRITE_SIZE * world[(1 << 2)+1]; + sz = SPRITE_SIZE * world[(2 << 2)+0] + SPRITE_SIZE * world[(2 << 2)+1]; + + Vertex* curr = vertices; + for (i = startSlice; i < startSlice + sliceCount; ++i) + { + InputVertex* inrow = &torus_vertices[i * NUM_ROWS]; + + for (j = 0; j < NUM_ROWS; ++j) + { + InputVertex* incurr = &inrow[j]; + + float x, y, z; + + x = incurr->x; + y = incurr->y; + z = incurr->z; + + x += torus_modifiers[j].x * t; + y += torus_modifiers[j].y * t; + z += torus_modifiers[j].z * t; + + curr->u = 0.0f; + curr->v = 0.0f; + curr->color = colors[(i+j)&7]; + curr->x = x - sx; + curr->y = y - sy; + curr->z = z - sz; + ++curr; + + curr->u = 1.0f; + curr->v = 1.0f; + curr->color = colors[(i+j)&7]; + curr->x = x + sx; + curr->y = y + sy; + curr->z = z + sz; + ++curr; + } + } +} + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + sceKernelExitGame(); + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0); + if(thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} + diff --git a/src/samples/gu/skinning/Makefile.sample b/src/samples/gu/skinning/Makefile.sample new file mode 100644 index 00000000..d8f536cf --- /dev/null +++ b/src/samples/gu/skinning/Makefile.sample @@ -0,0 +1,18 @@ +TARGET = skinning +OBJS = skinning.o + +INCDIR = +CFLAGS = -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = +LIBS = -lpspgum -lpspgu -lm + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Matrix Skinning Sample + +PSPSDK=$(shell psp-config --pspsdk-path) +USE_PSPSDK_LIBC=1 +include $(PSPSDK)/lib/build.mak \ No newline at end of file diff --git a/src/samples/gu/skinning/skinning.c b/src/samples/gu/skinning/skinning.c new file mode 100644 index 00000000..308dfb4d --- /dev/null +++ b/src/samples/gu/skinning/skinning.c @@ -0,0 +1,309 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * skinning.c - Sample to demonstrate matrix skinning using 8 weights per vertex + * + * Copyright (c) 2005 Jesper Svennevid + * Copyright (c) 2005 Renaldas Zioma + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +PSP_MODULE_INFO("Matrix Skinning Sample", 0, 1, 1); +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER); + +static unsigned int __attribute__((aligned(16))) list[262144]; + +#define WEIGHTS_PER_VERTEX 8 +typedef struct Vertex +{ + float skinWeight[WEIGHTS_PER_VERTEX]; + float u,v; + unsigned int color; + float nx,ny,nz; + float x,y,z; +} Vertex; + +/* cylinder */ + +#define CYLINDER_SLICES 48 // numc +#define CYLINDER_ROWS 48 // numt +#define CYLINDER_RADIUS 0.35f +#define CYLINDER_LENGTH 1.25f + +Vertex __attribute__((aligned(16))) cylinder_vertices[CYLINDER_SLICES*CYLINDER_ROWS]; +unsigned short __attribute__((aligned(16))) cylinder_indices[CYLINDER_SLICES*(CYLINDER_ROWS-1)*6]; + +#define min( a, b ) ( ((a)<(b))?(a):(b) ) +#define max( a, b ) ( ((a)>(b))?(a):(b) ) + +int SetupCallbacks(); + +void genSkinnedCylinder( unsigned slices, unsigned rows, float length, float radius, unsigned bones, + Vertex* dstVertices, unsigned short* dstIndices ); + +#define BUF_WIDTH (512) +#define SCR_WIDTH (480) +#define SCR_HEIGHT (272) +#define PIXEL_SIZE (4) /* change this if you change to another screenmode */ +#define FRAME_SIZE (BUF_WIDTH * SCR_HEIGHT * PIXEL_SIZE) +#define ZBUF_SIZE (BUF_WIDTH SCR_HEIGHT * 2) /* zbuffer seems to be 16-bit? */ + +#define HIERARCHY_SIZE (WEIGHTS_PER_VERTEX) + +int main(int argc, char* argv[]) +{ + SetupCallbacks(); + + // generate geometry + + genSkinnedCylinder( CYLINDER_ROWS, CYLINDER_SLICES, CYLINDER_LENGTH, CYLINDER_RADIUS, HIERARCHY_SIZE, cylinder_vertices, cylinder_indices ); + + // flush cache so that no stray data remains + + sceKernelDcacheWritebackAll(); + + // setup GU + + sceGuInit(); + + sceGuStart(GU_DIRECT,list); + sceGuDrawBuffer(GU_PSM_8888,(void*)0,BUF_WIDTH); + sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,(void*)0x88000,BUF_WIDTH); + sceGuDepthBuffer((void*)0x110000,BUF_WIDTH); + sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); + sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); + sceGuDepthRange(0xc350,0x2710); + sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + sceGuDepthFunc(GU_GEQUAL); + sceGuEnable(GU_DEPTH_TEST); + sceGuFrontFace(GU_CW); + sceGuShadeModel(GU_SMOOTH); + sceGuEnable(GU_CULL_FACE); + sceGuEnable(GU_DITHER); + + // setup a light + ScePspFVector3 lightDir = { 0, 0, 1 }; + sceGuLight(0,GU_DIRECTIONAL,GU_DIFFUSE,&lightDir); + sceGuLightColor(0,GU_DIFFUSE,0x00ff4040); + sceGuLightAtt(0,1.0f,0.0f,0.0f); + sceGuAmbient(0x00202020); + sceGuEnable(GU_LIGHTING); + sceGuEnable(GU_LIGHT0); + + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuDisplay(GU_TRUE); + + // setup matrices + + sceGumMatrixMode(GU_PROJECTION); + sceGumLoadIdentity(); + sceGumPerspective(75.0f,16.0f/9.0f,0.5f,1000.0f); + + sceGumMatrixMode(GU_VIEW); + { + ScePspFVector3 pos = {0,0,-5.0f}; + + sceGumLoadIdentity(); + sceGumTranslate(&pos); + } + + // setup bones hierarchy + + ScePspFMatrix4 bones[HIERARCHY_SIZE]; + float boneLength = CYLINDER_LENGTH; + + // run sample + + int val = 0; + int q; + + for(;;) + { + sceGuStart(GU_DIRECT,list); + + // clear screen + + sceGuClearColor(0xff554433); + sceGuClearDepth(0); + sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); + + // update matrices + + for( q = 0; q < HIERARCHY_SIZE; ++q ) + { + ScePspFVector3 rot = {0,0,cosf( val * 1.0f * (GU_PI/180.0f))}; + + gumLoadIdentity(&bones[q]); + gumRotateXYZ(&bones[q],&rot); + + if( q > 0 ) + { + ScePspFVector3 pos = {boneLength, 0, 0}; + + gumTranslate(&bones[q], &pos); + gumMultMatrix(&bones[q], &bones[q-1], &bones[q]); + } + + // set matrices for skinning + + sceGuBoneMatrix( q, &bones[q] ); + sceGuMorphWeight( q, 1.0f ); + } + + sceGumMatrixMode(GU_MODEL); + { + ScePspFVector3 rot = {GU_PI/7.0f, GU_PI/9.0f, 0}; + + sceGumLoadIdentity(); + sceGumRotateXYZ(&rot); + } + + for( q = 0 ; q < 4; ++q ) + { + ScePspFVector3 rot = {0,0,GU_PI/2.0f}; + sceGumRotateXYZ(&rot); + + sceGumDrawArray(GU_TRIANGLES, + GU_WEIGHTS( WEIGHTS_PER_VERTEX )|GU_NORMAL_32BITF|GU_TEXTURE_32BITF|GU_COLOR_8888|GU_VERTEX_32BITF|GU_WEIGHT_32BITF|GU_INDEX_16BIT|GU_TRANSFORM_3D, + sizeof(cylinder_indices)/sizeof(unsigned short),cylinder_indices,cylinder_vertices); + } + + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuSwapBuffers(); + + val++; + } + + sceGuTerm(); + + sceKernelExitGame(); + return 0; +} + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + sceKernelExitGame(); + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0); + if(thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} + +/* usefull geometry functions */ +void genSkinnedCylinder( unsigned slices, unsigned rows, float length, float radius, unsigned bones, + Vertex* dstVertices, unsigned short* dstIndices ) +{ + unsigned int i,j; + + float lengthStep = length / (float)rows; + float boneStep = ((float)bones-1)/((float)rows); + + // generate torus (TODO: tri-strips) + for (j = 0; j < slices; ++j) + { + for (i = 0; i < rows; ++i) + { + struct Vertex* curr = &dstVertices[i+j*rows]; + float s = i + 0.5f; + float t = j; + float cs,ct,ss,st; + + cs = cosf(s * (2*GU_PI)/slices); + ct = cosf(t * (2*GU_PI)/rows); + ss = sinf(s * (2*GU_PI)/slices); + st = sinf(t * (2*GU_PI)/rows); + + curr->nx = 0; + curr->ny = ct; + curr->nz = st; + + curr->x = lengthStep * (float)i; + curr->y = radius * ct; + curr->z = radius * st; + + curr->color = 0xffffff; + + int q = 0; + for( ; q < bones; q++ ) + { + float b = min( ((float)bones-1), boneStep * (float)i ); + float t = b - (float)q; + + // calculate cubic blending functions for skinning weights + // each vertex is influenced by 4 bones (matrices) at most + + float t2 = t*t; + float t3 = t*t*t; + + float f = 0; + if( t >= 0.0f && t < 1.0f ) f = t3/6.0f; + if( t >= 1.0f && t < 2.0f ) f = -0.5f*t3 + 2.0f*t2 - 2.0f*t + 2.0f/3.0f; + if( t >= 2.0f && t < 3.0f ) f = 0.5f*t3 - 4.0f*t2 + 10.0f*t - 22.0f/3.0f; + if( t >= 3.0f && t < 4.0f ) f = -t3/6.0f + 2.0f*t2 - 8.0f*t + 32.0f/3.0f; + + curr->skinWeight[q] = f; + } + } + } + + for (j = 0; j < slices; ++j) + { + for (i = 0; i < rows-1; ++i) + { + unsigned short* curr = &dstIndices[(i+(j*(rows-1)))*6]; + + *curr++ = i + j * rows; + *curr++ = (i+1) + j * rows; + *curr++ = i + ((j+1)%slices) * rows; + + *curr++ = (i+1) + j * rows; + *curr++ = (i+1) + ((j+1)%slices) * rows; + *curr++ = i + ((j+1)%slices) * rows; + } + } +} diff --git a/src/samples/gu/speed/Makefile.sample b/src/samples/gu/speed/Makefile.sample new file mode 100644 index 00000000..54a2685e --- /dev/null +++ b/src/samples/gu/speed/Makefile.sample @@ -0,0 +1,17 @@ +TARGET = speed +OBJS = speed.o ../common/callbacks.o ../common/vram.o + +INCDIR = +CFLAGS = -G0 -Wall -O2 +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = +LIBS= -lpspgum -lpspgu -lpsprtc + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Memory Speed Sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/gu/speed/speed.c b/src/samples/gu/speed/speed.c new file mode 100644 index 00000000..3e088a62 --- /dev/null +++ b/src/samples/gu/speed/speed.c @@ -0,0 +1,347 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "../common/callbacks.h" +#include "../common/vram.h" + +PSP_MODULE_INFO("Memory Speed Sample", 0, 1, 1); +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER); + +#define SLICE_SIZE 32 // change this to experiment with different page-cache sizes + +#define BUF_WIDTH (512) +#define SCR_WIDTH (480) +#define SCR_HEIGHT (272) + +static unsigned int __attribute__((aligned(16))) list[262144]; + +static u32 __attribute__((aligned(16))) pixels[BUF_WIDTH*SCR_HEIGHT]; +static u32 __attribute__((aligned(16))) swizzled_pixels[BUF_WIDTH*SCR_HEIGHT]; + +struct Vertex +{ + unsigned short u, v; + unsigned short color; + short x, y, z; +}; + +void simpleBlit(int sx, int sy, int sw, int sh, int dx, int dy) +{ + // simple blit, this just copies A->B, with all the cache-misses that apply + + struct Vertex* vertices = (struct Vertex*)sceGuGetMemory(2 * sizeof(struct Vertex)); + + vertices[0].u = sx; vertices[0].v = sy; + vertices[0].color = 0; + vertices[0].x = dx; vertices[0].y = dy; vertices[0].z = 0; + + vertices[1].u = sx+sw; vertices[1].v = sy+sh; + vertices[1].color = 0; + vertices[1].x = dx+sw; vertices[1].y = dy+sh; vertices[1].z = 0; + + sceGuDrawArray(GU_SPRITES,GU_TEXTURE_16BIT|GU_COLOR_4444|GU_VERTEX_16BIT|GU_TRANSFORM_2D,2,0,vertices); +} + +void advancedBlit(int sx, int sy, int sw, int sh, int dx, int dy, int slice) +{ + int start, end; + + // blit maximizing the use of the texture-cache + + for (start = sx, end = sx+sw; start < end; start += slice, dx += slice) + { + struct Vertex* vertices = (struct Vertex*)sceGuGetMemory(2 * sizeof(struct Vertex)); + int width = (start + slice) < end ? slice : end-start; + + vertices[0].u = start; vertices[0].v = sy; + vertices[0].color = 0; + vertices[0].x = dx; vertices[0].y = dy; vertices[0].z = 0; + + vertices[1].u = start + width; vertices[1].v = sy + sh; + vertices[1].color = 0; + vertices[1].x = dx + width; vertices[1].y = dy + sh; vertices[1].z = 0; + + sceGuDrawArray(GU_SPRITES,GU_TEXTURE_16BIT|GU_COLOR_4444|GU_VERTEX_16BIT|GU_TRANSFORM_2D,2,0,vertices); + } +} + +void swizzle_fast(u8* out, const u8* in, unsigned int width, unsigned int height) +{ + unsigned int blockx, blocky; + unsigned int j; + + unsigned int width_blocks = (width / 16); + unsigned int height_blocks = (height / 8); + + unsigned int src_pitch = (width-16)/4; + unsigned int src_row = width * 8; + + const u8* ysrc = in; + u32* dst = (u32*)out; + + for (blocky = 0; blocky < height_blocks; ++blocky) + { + const u8* xsrc = ysrc; + for (blockx = 0; blockx < width_blocks; ++blockx) + { + const u32* src = (u32*)xsrc; + for (j = 0; j < 8; ++j) + { + *(dst++) = *(src++); + *(dst++) = *(src++); + *(dst++) = *(src++); + *(dst++) = *(src++); + src += src_pitch; + } + xsrc += 16; + } + ysrc += src_row; + } +} + +struct StripWidthDeclaration +{ + int width; + const char* name; +} strip_widths[] = +{ + {16,"16"}, + {32,"32"}, + {64,"64"}, + {128,"128"} +}; + +struct PixelFormatDeclaration +{ + int psm; + int size; + int row_pitch; + const char* name; +} pixel_formats[] = +{ + {GU_PSM_4444,SCR_WIDTH*SCR_HEIGHT*2,1024,"16-bit RGBA"}, + {GU_PSM_T4,(SCR_WIDTH*SCR_HEIGHT)>>1,256,"4-bit CLUT"}, + {GU_PSM_T8,SCR_WIDTH*SCR_HEIGHT,512,"8-bit CLUT"}, + {GU_PSM_8888,SCR_WIDTH*SCR_HEIGHT*4,2048,"32-bit RGBA"} +}; + +u16 __attribute__((aligned(16))) palette[256]; + +int main(int argc, char* argv[]) +{ + unsigned int i; + + setupCallbacks(); + + for (i = 0; i < 256; ++i) + palette[i] = i; + + sceKernelDcacheWritebackAll(); + + // setup GU + + void* fbp0 = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_8888); + void* fbp1 = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_8888); + void* zbp = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_4444); + + pspDebugScreenInit(); + sceGuInit(); + + sceGuStart(GU_DIRECT,list); + sceGuDrawBuffer(GU_PSM_5650,fbp0,BUF_WIDTH); + sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,fbp1,BUF_WIDTH); + sceGuDepthBuffer(zbp,BUF_WIDTH); + sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); + sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); + sceGuDepthRange(65535,0); + sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + sceGuFrontFace(GU_CW); + sceGuEnable(GU_TEXTURE_2D); + sceGuDepthMask(0xffff); + sceGuDisable(GU_DEPTH_TEST); + sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); + + sceGuClutMode(GU_PSM_4444,0,255,0); + sceGuClutLoad(256/8,palette); + + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuDisplay(1); + + // get vram buffer for vram -> vram blit + + void* vram_buffer; + vram_buffer = getStaticVramTexture(BUF_WIDTH,SCR_HEIGHT,GU_PSM_8888); + + // flush caches to make sure no stray data remains + + sceKernelDcacheWritebackAll(); + + float curr_ms = 1.0f; + int blit_method = 0; + int swizzle = 0; + int vram_select = 0; + int strip_width = 0; + int pixel_format = 0; + int initialized = 0; + + SceCtrlData oldPad; + oldPad.Buttons = 0; + sceCtrlSetSamplingCycle(0); + sceCtrlSetSamplingMode(0); + + u64 last_tick; + sceRtcGetCurrentTick(&last_tick); + u32 tick_res = sceRtcGetTickResolution(); + int frame_count = 0; + + while (running()) + { + int texture_change = 0; + + // deal with input + + SceCtrlData pad; + if(sceCtrlPeekBufferPositive(&pad, 1)) + { + if (pad.Buttons != oldPad.Buttons) + { + if (pad.Buttons & PSP_CTRL_CROSS) + blit_method ^= 1; + + if (pad.Buttons & PSP_CTRL_CIRCLE) + { + swizzle ^= 1; + texture_change = 1; + } + + if (pad.Buttons & PSP_CTRL_SQUARE) + { + vram_select ^= 1; + texture_change = 1; + } + + if (pad.Buttons & PSP_CTRL_TRIANGLE) + strip_width = (strip_width+1) % (sizeof(strip_widths)/sizeof(struct StripWidthDeclaration)); + + if (pad.Buttons & (PSP_CTRL_RTRIGGER|PSP_CTRL_LTRIGGER)) + { + if (pad.Buttons & PSP_CTRL_RTRIGGER) + ++pixel_format; + else + --pixel_format; + pixel_format %= sizeof(pixel_formats) / sizeof(struct PixelFormatDeclaration); + texture_change = 1; + } + } + oldPad = pad; + } + + // generate new texture if settings have changed + + if (texture_change || !initialized) + { + u8* output = (u8*)pixels; + unsigned int x,y; + + for (y = 0; y < 512; ++y) + for (x = 0; x < pixel_formats[pixel_format].row_pitch; ++x) + *output++ = x*y; + + if (swizzle) + { + if (vram_select) + swizzle_fast((u8*)vram_buffer,(const u8*)pixels,pixel_formats[pixel_format].row_pitch,SCR_HEIGHT); + else + swizzle_fast((u8*)swizzled_pixels,(const u8*)pixels,pixel_formats[pixel_format].row_pitch,SCR_HEIGHT); + } + else + { + if (vram_select) + memcpy(vram_buffer,pixels,pixel_formats[pixel_format].row_pitch * SCR_HEIGHT); + } + + sceKernelDcacheWritebackAll(); + initialized = 1; + } + + // begin rendering + + sceGuStart(GU_DIRECT,list); + + sceGuTexMode(pixel_formats[pixel_format].psm,0,0,swizzle); // 16-bit RGBA + sceGuTexImage(0,512,512,512,vram_select ? vram_buffer : swizzle ? swizzled_pixels : pixels); // setup texture as a 512x512 texture, even though the buffer is only 512x272 (480 visible) + sceGuTexFunc(GU_TFX_REPLACE,GU_TCC_RGBA); // don't get influenced by any vertex colors + sceGuTexFilter(GU_NEAREST,GU_NEAREST); // point-filtered sampling + + if (blit_method) + advancedBlit(0,0,SCR_WIDTH,SCR_HEIGHT,0,0, strip_widths[strip_width].width); + else + simpleBlit(0,0,SCR_WIDTH,SCR_HEIGHT,0,0); + + sceGuFinish(); + sceGuSync(0,0); + + // sum results and update report if more than one second has passed since last time + + ++frame_count; + + u64 curr_tick; + sceRtcGetCurrentTick(&curr_tick); + if ((curr_tick-last_tick) >= tick_res) + { + float curr_fps = 1.0f / curr_ms; + int transfer_rate = (curr_fps * pixel_formats[pixel_format].size) / (1024*1024); + + pspDebugScreenSetOffset((int)fbp0); + pspDebugScreenSetXY(0,0); + pspDebugScreenPrintf("fps: %d.%03d (%dMB/s)",(int)curr_fps,(int)((curr_fps-(int)curr_fps) * 1000.0f),transfer_rate); + pspDebugScreenSetXY(0,1); + pspDebugScreenPrintf("%s %s %s %s",blit_method ? "optimized" : "normal", swizzle ? "swizzled" : "linear",vram_select ? "video ram" : "system ram", strip_widths[strip_width].name); + pspDebugScreenSetXY(0,2); + pspDebugScreenPrintf("%s",pixel_formats[pixel_format].name); + + pspDebugScreenSetXY(0,32); + pspDebugScreenPrintf("L/R = pixel format"); + pspDebugScreenSetXY(0,33); + pspDebugScreenPrintf("X = blit method, O = swizzling, [] = memory, /\\ = strip width"); + + fbp0 = sceGuSwapBuffers(); + + // update timing for next pass + + double time_span = ((curr_tick-last_tick)) / (float)tick_res; + curr_ms = time_span / frame_count; + + frame_count = 0; + + sceRtcGetCurrentTick(&last_tick); + } + + } + + sceGuTerm(); + + sceKernelExitGame(); + return 0; +} diff --git a/src/samples/gu/spharm/Image1.raw b/src/samples/gu/spharm/Image1.raw new file mode 100644 index 00000000..09457582 --- /dev/null +++ b/src/samples/gu/spharm/Image1.raw @@ -0,0 +1 @@ +y|ö후é€ïmpôy\óƒUñ{_ðlyòoó‡óžŒò‘ïh‘ëfï~‡ô˜ƒó—‚îm„ì]‚ôp~÷ˆ{óŸ~ñò|†ðnŽíz”ðtóezògqôyrô’tò’xðuðg‡õr‹öЉó‘ð~jï{WñˆTó‡cõ‚ôuŒñosòu_õƒ_òdïyñ~õm…ômeò}Zó‹^ô“_ò~_ëh]ìr[ô…\õ\î‘fê_xìT€ðn{ô€|õ‘ƒí›…胀ïooôv]ò‚Uð~^ðnxñoó‡óžŒò‘ïh‘ëfï~‡ô˜ƒó—‚îm„ì]‚ôp~÷ˆ{óŸ~ñò|†ðnŽíz”ðtóezògqôyrô’tò’xðuðg‡õr‹öЉó‘ð~jï{WñˆTó‡cõ‚ôuŒñosòu_õƒ_òdïyñ~õm…ômeò}Zó‹^ô“_ò~_ëh]ìsZô†\õ›^ïŒhê[zìU€ñu}ô’ø˜ó—‡îl~î_sõukøˆi÷Žnö€õrô€‘ó›†ó‘}îe}ê]|ïxuó‘pð“pêo{åZ‹ìkõ„”ñ”—쑇í~jîx`í|gîqpïf|òj†ö}ˆ÷—‡ö›ƒó~€ñi‡ót”ö‡˜÷‚Œôpvóujõˆj÷—o÷‘yôn€ñcyõvqúŠqùŸsñŸ{ëyƒíX€ïbuò|pøŒsúwöxuðioótnùˆpù¤mó¡mðkzîPñg–ö‚“÷™ò–ˆíp}îbrõslø†j÷‘mö‚~ôrô€‘ó›†ó‘}îe}ê]|ïxuó‘pð“pêo{åZ‹ìkõ„”ñ”—쑇í~jîx`í|gîqpïf|òj†ö}ˆ÷—‡ö›ƒó~€ñi‡ót”ö‡˜÷‚Œôpvóujõˆj÷—o÷‘yôn€ñcyõvqúŠqùŸsñŸ{ëyƒíX€ïbuò|pøŒsúwöxvðhpótnù‰où¦ló£lðpwî]‰ñv“ö{“ô†ò‡vîasîY}÷o„ú†„÷™ƒ÷’‚ôsïsvðiõ‹bòdjî^sðypó“lõœmó‚rëbzëj„ñ†ŒóŒŽïx|ìndïw\óƒ`óƒiïuíl™ñ} ô‘™õ„óiïyhî„}îhŒï]†ón…÷…†öŸƒó–~ðg|îY‚ón‰úˆŒü¥‡ö¥zì{oéXvî[†õt‹ûû”÷vôdŒöqŠû‹ˆú¥õ¢nñ{iîaði–ó~•ô‡ò‡wíerî\|öl…ù……÷œ‚÷“‚ôsïsvðiõ‹bòdjî^sðypó“lõœmó‚rëbzëj„ñ†ŒóŒŽïx|ìndïw\óƒ`óƒiïuíl™ñ} ô‘™õ„óiïyhî„}îhŒï]†ón…÷…†öŸƒó–~ðg|îY‚ón‰úˆŒü¥‡ö¥zì{oéXvî[†õt‹ûû”÷u‘ôcöqŠûŒ‡ú§~õ¤nñgîm{ðw”ógtïxkñaòtiòhƒõs–ùˆ™ø—’÷‡…òivíoló‹dúŒcúpp÷h}÷{€ø‘€ú~øŒoómcðpfñŒiô‹jôhpó`sõutúŒuúšt÷‰{òs‰ð|Žñƒ‡îwtîx_ó‡]ó—gë‹læeqé^óq÷ˆ˜ôš’ï‰~íhnïdvót‰ø…”ú‘÷qñ~\îogòj„øw™ù’›ô˜“ðxîd—ðn¡ô…›ô”ƒòiñ‹]ñ†dðxtïqvïylñ€bòwhòj‚õp˜ù‡šø™‘÷ˆ„òivíoló‹dúŒcúpp÷h}÷{€ø‘€ú~øŒoómcðpfñŒiô‹jôhpó`sõutúŒuúšt÷‰{òs‰ð|Žñƒ‡îwtîx_ó‡]ó—gë‹læeqé^óq÷ˆ˜ôš’ï‰~íhnïdvót‰ø…”ú‘÷qñ~\îogòj„øw™ù’›ô˜“ðxîd—ðo ô†šô‘„óŠmò†`ñ…fð}vïZmónjöˆhø‘nôñwõ„øŒ…õr}ñ\~ól~ùˆ{û“|ù‚‡÷m—ötœ÷‰˜÷‹ó|vòniöxi÷“gõ”jõlz÷`ˆúv‹úŒŒùš„ù‹söwgó}dñxhëinìoqøtû”róeîv]òth÷„}øŽõ‰‹ïstïneõ|i÷‹vø‰‚÷t€õolözb÷„høˆy÷„ð†Œë‰ué}kçt~éqšío™ïs€òzoöjö›fó‚hðikòok÷‡iø“mô‚€ñt’õ‚‘øŽ„õt|ñ\~ól~ùˆ{û“|ù‚‡÷m—ötœ÷‰˜÷‹ó|vòniöxi÷“gõ”jõlz÷`ˆúv‹úŒŒùš„ù‹söwgó}dñxhëinìoqøtû”róeîv]òth÷„}øŽõ‰‹ïstïneõ|i÷‹vø‰‚÷t€õolözb÷„høˆy÷„ð†Œë‰ué~kçt~ér™ío™ïpòtsö‡mö˜hóŒiðY€ùr}ú}øôŽ~ðquðvmô…hôunòc„õp‘ø‰‘õœŠð“‹ìt˜ìmï‘ò€}ðnuðkyø{ú”€ô™€òw‚ói‰ôz‘òˆ™ò†’ôtxóqeö€a÷€hòozôkˆûzýˆ‡øvöviùjù”sõ}ðoíbyórsú‡tùšxùŽ|÷i}ôdxöxxùŽzù›|ô…|éopéx^ðˆZïŽeì{wî\‚ð]‚óqøˆø”ó}òh€÷sûŒùŸô}ðmvðsnõ†gõvmòc„õp‘ø‰‘õœŠð“‹ìt˜ìmï‘ò€}ðnuðkyø{ú”€ô™€òw‚ói‰ôz‘òˆ™ò†’ôtxóqeö€a÷€hòozôkˆûzýˆ‡øvöviùjù”sõ}ðoíbyórsú‡tùšxùŽ|÷i}ôdxöxxùŽzù›|ô…|éopéx^ðˆZïeì{wî]‚ð]óqø‹ùœ~ô’}ïZˆöu‰÷Š‘õ“•ó†ðknòrgö…jõŠqó~‚ów“ô‘ó•í—pê€rêjyìlsðuiòsnót÷~ø–ô‘ˆñzsîumî‡xðŒ‡ñsŒð^„ñj}÷„zû|ú‹ùvø~¡÷~˜ônŠõo€úƒù—ò’{ëmxì]‚õm‹ù„Œø™Šø†õh†ñc‹ózö“’ö—‹ôv}ïcoòwhù‘hùžgõ†gòamòczõzˆ÷Œ“õ–òw‘ïh‰ôvŠø‰“ö””ó‚„ñgpóoh÷†iö‹pó~‚ów“ô‘ó•í—pê€rêjyìlsðuiòsnót÷~ø–ô‘ˆñzsîumî‡xðŒ‡ñsŒð^„ñj}÷„zû|ú‹ùvø~¡÷~˜ônŠõo€úƒù—ò’{ëmxì]‚õm‹ù„Œø™Šø†õh†ñc‹ózö“’ö—‹ôv}ïcoòwhù‘hùhõ†gòclòczöy‰÷“ö˜“óŠì]wñy}óŠõ‹’ôlŒôe÷u}ø†‚óœ‚ñ—ôrƒôh|õ}nö‘cöŒbòlkîapòsp÷‚tø‡‚÷‡˜ô†ò|„ñpkñyeõ”i÷—pôrzï]„ñnˆ÷†‹ø—‘÷—ô~›ï~“íxŠîi‰ópŽù…‘ú’Šõuð{fðizól—ô}žõö‡zôpwòp‡ô„™õ‘›ó†ˆõew÷`xøx~ø’~ûœyù„nñofñwkø‰|÷–òŽïs}îjuñz}ôŒŒõ‹’ôlŒôaøs~øˆóžò—ôrƒôh|õ}nö‘cöŒbòlkîapòsp÷‚tø‡‚÷‡˜ô†ò|„ñpkñyeõ”i÷—pôrzï]„ñnˆ÷†‹ø—‘÷—ô~›ï~“íxŠîi‰ópŽù…‘ú’Šõuð{fðizól—ô}žõö‡zôpwòp‡ô„™õ‘›ó†ˆõew÷`xøx~ø’~úœyø…nðpfñtlø„ø‘’óŒ‘ð{}ìhkõ„lôrô‘zôfƒô]ˆöpŠõˆ‹ñ¢ˆï”„ñaðYyôvsúŽrývøu~ñe†ôv‡øŽ…÷šŠõ–ï{‰ëbïdzöyxù™vøœtózpîfrôt{ùЇö›ðŒìtxëriïxfòvsóxŠô|•ô|†ô|mõ‚aö†nô€ˆñw‘òw|óygõeö‹rõŒ‡ò}‰ïnrógg÷juö|…õŽùŒ‹ùv|õtpö†oú•y÷•ñzzïglñrgõ†lõ˜tó{ógƒôZŠöoŠö‹‰ñ¤‡ï”„ñaðYyôvsúŽrývøu~ñe†ôv‡øŽ…÷šŠõ–ï{‰ëbïdzöyxù™vøœtózpîfrôt{ùЇö›ðŒìtxëriïxfòvsóxŠô|•ô|†ô|mõ‚aö†nô€ˆñw‘òw|óygõeö‹rõŒ‡ò}‰ïnrógg÷juö|…õù‹÷w|óvpõƒpú“zø“ƒñx|ïklñpxôŒuõ¤wñ—zîgzîX{òm}õŒ{ó¡zñˆìXŠëYŒóvŠùŠŒú’÷€’ók›ôxžõ™ò™Œñ“sîxfé`xîd‹ô~Žõ˜ö”†óuuðlj÷~mü–s÷ yïƒuëbjîddöxeø‰mó‡|ïr†ïfòovõ…søŸrø–xöqzõerörn÷†o÷šsõzñfzì\qñom÷zwó‰ƒñ’ôw™öe÷s†÷Š„ö™‰ò‘‡îi{ð[wötwøvõ¡xðšyímxíX{òk~õŒ{ô¢yñˆìXŠëYŒóvŠùŠŒú’÷€’ók›ôxžõ™ò™Œñ“sîxfé`xîd‹ô~Žõ˜ö”†óuuðlj÷~mü–s÷ yïƒuëbjîddöxeø‰mó‡|ïr†ïfòovõ…søŸrø–xöqzõerörn÷†o÷šsõzñfzì\qñom÷zwó‰ƒñŽ“ót›ófôu…öˆ…öšŠó’‡ïj}ð`w÷pó‰Žó£ð”…ëcxëWrôrrùrø röwïf‚ë`ðv™õŠ ó•–ò†ˆðsîvšð|—ð{ñ|dô~\óxoðvŽð„Ÿôö€ógòj{÷€zúœy÷£xó{{îX~ð`}ø{{ú—{ö˜~ót„òd‡õsˆøˆŠø ˆõ–€ôkyõ`|ösƒ÷‰…ø„ù‘|õfvï^{ós‚ø„†öš‰ò™‹ðsòa—óqžðˆžðœ—ëh{ï\…öq÷Š‘ô£ŽðœëlsëYqômtùŠsùŸr÷wïf‚ë`ðv™õŠ ó•–ò†ˆðsîvšð|—ð{ñ|dô~\óxoðvŽð„Ÿôö€ógòj{÷€zúœy÷£xó{{îX~ð`}ø{{ú—{ö˜~ót„òd‡õsˆøˆŠø ˆõ–€ôkyõ`|ösƒ÷‰…ø„ù‘|õfvï^{ós‚ø„†öš‰ò˜Œïq’ïb—ñsð‡Ÿñœ—ð’†ìi}î`ƒ÷r›÷‡žó—‘ï„yí^pï^v÷v}ûŠø€õ”sóshîoqî‡îˆ’ë†ëfë€bëzpîgzðesôslù†kù”pô„ñ„—ó~òo{îc|ðl‰ô}“õ–‘ô†óxî[…ífö~ù›Žöœ‡ôxƒóhˆów–ö‡Ÿô‘–ð†}ðknòf}òu‘ò‰—õ“Œö…vóniónvözŒø‰—øžöyñmðoìwšè ì‹‰ï†jëqfìk}òy–÷‰¡ô–’ïˆwìdlî^uørûˆ‚ø€ö”sóshîoqî‡îˆ’ë†ëfë€bëzpîgzðesôslù†kù”pô„ñ„—ó~òo{îc|ðl‰ô}“õ–‘ô†óxî[…ífö~ù›Žöœ‡ôxƒóhˆów–ö‡Ÿô‘–ð†}ðknòf}òu‘ò‰—õ“Œö…vóniónvözŒø‰—øžöœzð}oîp€êyšç¡í‹‰ð‡jìrhìswð~Žõ‚‘ð{}îofðjeñrt÷}‰ø†™òŽ‘îuñtaô„_ôiî}oémgìs^ñˆ[óŒ_ómmôd|øuúŠ‚ø¡ƒöž‚ñ{zìkjìmbðskò~ò†”ó‹”òŠ{ðzgínrësŒò›÷Ž•ò‹~ïwkïrqñ{Šð|™ìvŠìvlóxbözpó€‰ñƒ•ð}„ïtnðugöoúˆ…ø…–õ…ˆð†gîƒYñ†cì†xåt€êiròqaô|`ó†nòŒ…ô†’ñx€înfðjdñpt÷|‰ù‰—óïuñtaô„_ôiî}oémgìs^ñˆ[óŒ_ómmôd|øuúŠ‚ø¡ƒöž‚ñ{zìkjìmbðskò~ò†”ó‹”òŠ{ðzgínrësŒò›÷Ž•ò‹~ïwkïrqñ{Šð|™ìvŠìvlóxbözpó€‰ñƒ•ð}„ïtnðugöoúˆ…ø…–õ…ˆð…hîZð‡cëˆwårëiróraõ}bó’iï•}ñx{îdpñkhö~jôqõŽˆõžîq•ëj{ðvn÷kú•køvnõcqöprúŠrú›pø…{ôhõn’÷ˆŽöžŒñ•‚élpçahðshù…kù“v÷Œ‚ôx}òskô|_ô†eñŠyó…‰õx‚ðsmïzaó‡dö‰qòs|êcxínn÷‚lú‘qù•zöƒðk|îmuôwyúzû™€÷~‡ðfzêljîeõ˜eö–jñopñYs÷hsûqûšsöŸxò|{î_tñgjö|jôŠsöއö†›ït”ìj{ðvn÷kú•køvnõcqöprúŠrú›pø…{ôhõn’÷ˆŽöžŒñ•‚élpçahðshù…kù“v÷Œ‚ôx}òskô|_ô†eñŠyó…‰õx‚ðsmïzaó‡dö‰qòs|êcxínn÷‚lú‘qù•zöƒðk|îmuôwyúzû™€÷~‡ðfzêlkí€fô™eõ—iñnqñZs÷isû‚túŸsö €ïqyï[zõiù‚€÷›õŸ‚ò„î_‚î`‚òu„÷Œ„ù’†úyŠ÷g‹÷tŠúŠŠúž‰÷’‡ïk‰ìh†ò…|ö›uñ‹rébví^}÷w~û}ú›€ø…‚ógyñgr÷}qú“qøšuôyðcvògrö}rù–qøšpô{qïbxók€÷‚„øœƒù¢õ}„ìa‡ík‰ø|Žû–öžŠðyë^zîe{õ|ùžzú|õr‚ó[‰÷j‹úƒ‰û ˆ÷¡€ðszîX|õj~ù„}÷šõœƒó€„ï`î`‚òu„÷Œ„ù’†úyŠ÷g‹÷tŠúŠŠúž‰÷’‡ïk‰ìh†ò…|ö›uñ‹rébví^}÷w~û}ú›€ø…‚ógyñgr÷}qú“qøšuôyðcvògrö}rù–qøšpô{qïbxók€÷‚„øœƒù¢õ}„ìa‡ík‰ø|Žû–öžŠðyë^zîe{õ~}ùŸzúŸ{õqƒó\‰÷l‹ù„‹ù Š÷‹{ïlpì]|ðg÷}—ø“‘ó–|îfîiiïg€ôu•÷Šö•›ó—ín—íy™óˆ—ö•‹ôˆ|îgsëhpôƒmú›iø’oók‚ôdø{”ö”•ò›”ò€Œñb†ðg‡ô}Š÷’‰÷—‚òxyì]wñg€ø~‡ú•‡ø›òqñhtól‡ô”ô—˜õšðy~çb€ën‹õ„–ö•›ïŽérvêctôlƒûûœ÷›‹ït…ëa‰òp”øˆ›ùš–ô‘ïlrî]|ól÷‚”÷”‘ó“~ï}gïhiïg€ôu•÷Šö•›ó—ín—íy™óˆ—ö•‹ôˆ|îgsëhpôƒmú›iø’oók‚ôdø{”ö”•ò›”ò€Œñb†ðg‡ô}Š÷’‰÷—‚òxyì]wñg€ø~‡ú•‡ø›òqñhtól‡ô”ô—˜õšðy~çb€ën‹õ„–ö•›ïŽérvêctôlƒûú÷œŠðs†ìc‰òs”øˆœ÷Ÿòkgôoaïrnîz…ô€–÷}’ñxwî}bñcò‚uõ„÷‰œðë€|és~êqŒîy…ò…qó}fñhkñiw÷~|ù˜|ú}øƒôqŒô{›ï‹ŸèŽë~xñh}ñk’ï|Ÿñ‹›ôŒƒòwlðgmòp÷‚ùŒ•÷‡„òzkñthõ{yôŠò•ò‚íqgìpdñ|sóƒð‹Šís|êihïoiø|zù‹ö”•óŠ‚îvjìqkï|ñ†’òƒ‰òwoóoaórmó}„ô‚—ô}’ðwwîycòdñ‚uõ„÷‰œðë€|és~êqŒîy…ò…qó}fñhkñiw÷~|ù˜|ú}øƒôqŒô{›ï‹ŸèŽë~xñh}ñk’ï|Ÿñ‹›ôŒƒòwlðgmòp÷‚ùŒ•÷‡„òzkñthõ{yôŠò•ò‚íqgìpdñ|sóƒð‹Šís|êihïoiø}yùŽŒö•“ó‰ƒïtjísjð€ñˆ‘ñ‰•ð`iùviø‰nö–xõ‰„õh…óbzôwsøqùœvø•~õ}{ïukì\í}_ïhmñgpôyi÷‚høwu÷nŠøx•ù‘÷•ôŒlò‚kò~}íw‚çtoìx]ó{eð€‚ì›îy–òtzósiôwlõ…v÷Œˆö~“òm„òtpö‚múuù˜}ô†îhsìfgôwfùkö›pò€uñ_uòeq÷|pûvö”ƒð‚…îqrñu_õ„_óŽmìƒwêjtîfk÷vhú‡mø–wö‡†ói†ïdyòusùqùœvø•~õ}{ïukì\í}_ïhmñgpôyi÷‚høwu÷nŠøx•ù‘÷•ôŒlò‚kò~}íw‚çtoìx]ó{eð€‚ì›îy–òtzósiôwlõ…v÷Œˆö~“òm„òtpö‚múuù˜}ô†îhsìfgôwfùkö›pò€uñ_uòeq÷|pû‘uø™ó„„ðnsñsaô†_ñ“jë‡vìj{ð`öx~ùùŸ€÷Ž|õcõ]†øuŠúŽŠ÷žŒôŽƒñkoðicò…aóŠcôrk÷ev÷v{øyúú|Œøw’÷}Šô€vñ…bóŽ_òˆeðmhðcgôvdöŽfóšpíˆ{êe|î\{ôn{öƒ{ù—}÷˜‚òu…î_…ôr‚ùŠú›ùž{ôqë_sîc{ø||û™zù¡z÷}€ó[…ôf†ùƒ„ú˜…÷“Šñs„ífvótoûŠpú˜sô‰xîe|íb~õw€ùŒùŸù}ôdða…öv‰ûŠ÷žŒôŽƒñkoðicò…aóŠcôrk÷ev÷v{øyúú|Œøw’÷}Šô€vñ…bóŽ_òˆeðmhðcgôvdöŽfóšpíˆ{êe|î\{ôn{öƒ{ù—}÷˜‚òu…î_…ôr‚ùŠú›ùž{ôqë_sîc{ø||û™zù¡z÷}€ó[…ôf†ùƒ„úš„ù–‡öu‚ñdwórqù‹p÷œrñwñc~ò]’ñv•öŒ–÷—ŠõŠtñjpïc‡óvšôžï’šêy‹è_|íhyö‚zøzù‚€ùlŽöw’ö’Žù–‰ø‚ôstòpoôumön÷“pôpôosôfx÷|yù“yø›ró‰cìjcë^{òmŒ÷†ø—ö’ƒñurïbyór‰öŠ’õ”õŽ{ðwhêfpïj‡÷‘ø™øŸ„õ€îbˆîj”ô„šøš—ø‘óp…îc‚ôn‡ù‡ˆøž†÷’ƒôl†ðcôv˜öŠ—÷—‰÷Štïnpëi„óx˜öŒžð’šêy‹è_|íhyö‚zøzù‚€ùlŽöw’ö’Žù–‰ø‚ôstòpoôumön÷“pôpôosôfx÷|yù“yø›ró‰cìjcë^{òmŒ÷†ø—ö’ƒñurïbyór‰öŠ’õ”õŽ{ðwhêfpïj‡÷‘ø™øŸ„õ€îbˆîj”ô„šø›—ø”õqƒðbƒômˆùˆ‰ø¡†ö—ƒõn‚ók‰ñy˜ô}œô~„ò|gïxbízvóŠó†íqrèczîi‹÷{“ù‘“÷‘ôu“óz“ôŠ”õ€òrvðpgôsiùwuúƒø–‡÷—‡ötŒójö€úŒŒúˆ{ùƒdõ€að{uð{ó… ò‡™óz|óofòqió|ó‡Žò|ïsuîudðykô~‚õ‚–õ‰ôuñ‚eëwnëxŠñ~œó‹‘ñŠxîtmíh}òp•ó†›ð™ñvôynótƒózšö}œöƒò|gì|aìrð„‰ôŠó†íqrèczîi‹÷{“ù‘“÷‘ôu“óz“ôŠ”õ€òrvðpgôsiùwuúƒø–‡÷—‡ötŒójö€úŒŒúˆ{ùƒdõ€að{uð{ó… ò‡™óz|óofòqió|ó‡Žò|ïsuîudðykô~‚õ‚–õ‰ôuñ‚eëwnëxŠñ~œó‹‘ð‹xìulìi|ôp“÷†šóšŒñ•uòfò‰mô„òi‰ð`{ôplø„j÷•nõ’nöh÷x`õ{]óznôtõy¥õŒ£ð‹ìwxî~rñ{îh€ìdyñrvøyúƒ…ø…–õ”œò””ðwðl™ñy¤óyœôq…÷ytù‹rø–yõ“‡ï‚’ëlˆîbuôlm÷„kø–q÷†€ñg‚îfwô|púrû–{÷†…ôq~òrló…`ó•còvñsƒïkwíudñ{_ó}oòŠñ}”ñyñ|gô†^ó‘jñ†€ôiˆôbzópmõˆiø›k÷”möhöx`õ{]óznôtõy¥õŒ£ð‹ìwxî~rñ{îh€ìdyñrvøyúƒ…ø…–õ”œò””ðwðl™ñy¤óyœôq…÷ytù‹rø–yõ“‡ï‚’ëlˆîbuôlm÷„kø–q÷†€ñg‚îfwô|púrû–{÷†…ôq~òrló…`ó•còvñsƒïkwëteì{_ñnö€‡÷|’õy€ñgð\ñ”löŽjóipï\{õoû‡€ü˜}útôriòrg÷‡hú’o÷‰€ñ€ð|îqwìodò`õ…gïqtîf„õqŽú†ö‘–òñŠ•ì…}êynìv}ëu•êgšía”ôrùŒ‰úœ‡ö•|îylé_kî^wõq~ù}ù ~ùЇôcŠñdˆø†ü•ˆùšˆõ€òczôeyø‚vù¢söšwôpwñ^pômlù€mú‘s÷Ž|ón€ò^xönq÷ˆmóœkò’kòloñ_yöpûŠü{úsõqjórg÷‡hú’o÷‰€ñ€ð|îqwìodò`õ…gïqtîf„õqŽú†ö‘–òñŠ•ì…}êynìv}ëu•êgšía”ôrùŒ‰úœ‡ö•|îylé_kî^wõq~ù}ù ~ùЇôcŠñdˆø†ü•ˆùšˆõ€òczôeyø‚vù¢söšwôpwñ]qókm÷€mù”qùzõl€ò]xõrpönò‰uõŒfô~dòn~ór”ô†šõ—öxñd…ðr÷Œ}û˜yø•kñˆbîsfñ`lõepù~pú’q÷zõvöp™ö…™ò•“ð‰ˆðvtïvað[ïaïŒlíj}í]Žòr–ö‹—öô~uïu\ño`ôoxõwö‰”õœõˆòkˆðc•öxù˜ôŒívía‚õcû{ùŸ‹õœ†òpñ\÷o€û…û›„ø”‡ïi‡í\„÷n…ûƒƒö“xôgò~eñn}ôr”ôˆ™ô–öuòb†ðr÷Œ}û˜yø•kñˆbîsfñ`lõepù~pú’q÷zõvöp™ö…™ò•“ð‰ˆðvtïvað[ïaïŒlíj}í]Žòr–ö‹—öô~uïu\ño`ôoxõwö‰”õœõˆòkˆðc•öxù˜ôŒívía‚õcû{ùŸ‹õœ†òpñ\€øn€ý…üƒ÷—†íiˆëY†õs„ú‚÷zuô†m÷kø†õzœîƒ¢ê†–ïlŽñ^‘ñq•÷†’ù‰‚ù‡i÷‡\ô{dôguøg…û{Šú–ˆùœ‰÷‚‰ñoˆï~ðŒrñxjòdgõnhöƒkõœiõœbówbïgoñ|~ó‰‡ôs†ógvóviù„kù‰yõ‚’óšñŽ…ï‹lïyjðn‚ór“ó€†ð„pî{hðqyôn”øzŸö’”ò‘ípyì^†òm•÷‡™÷›—ó‘êl‰èbóo•ø{Žõƒ|õ‰m÷Žk÷„ôyí„¡ê…–ïið]’ñq•÷†’ù‰‚ù‡i÷‡\ô{dôguøg…û{Šú–ˆùœ‰÷‚‰ñoˆï~ðŒrñxjòdgõnhöƒkõœiõœbówbïgoñ|~ó‰‡ôs†ógvóviù„kù‰yõ‚’óšñŽ…ï‹lïyjðn‚ór“ó€†ð„pî{hðqyôn”øzŸö’”ò‘ípyì_…óo”÷‡™ö›—ñ“èkŠç_‘òs•ø‰öoô€ùš~ú™…õ~ít…èzqìslïq~òy–õwœóm‹ôrzö„vôxò‚÷u“ú}ø”šö•òsídpðxgöˆböygóevónö€‚÷‘€øtõufñsdôŒhöŽmõkxó]÷süŽûœ„öðs‡ítpïƒ^õ]÷‰iõsrðmmðvfõ‚föŽpô‰…ó{ó{~ògð}aîwuñw”òŸïŒï‹rî{hën~ïk“ónòwƒõˆ}øŸ|ù„öŽív„ç|pëukïq~òy–õwœóm‹ôrzö„vôxò‚÷u“ú}ø”šö•òsídpðxgöˆböygóevónö€‚÷‘€øtõufñsdôŒhöŽmõkxó]÷süŽûœ„öðs‡ítpïƒ^õ]÷‰iõsrðmmðvfõ‚föŽpô‰…ó{ó{~ògð}aîwuðw•ëìŠsìxiël~ðp‘õx‘ôg—ô‚•÷¢’õžŒïpéakíu_ó‡^ñ“iòŠ€ðk“ï_“òmó†óœŠô”‰õzõ|ð‘Šë‡€é_xì\söxpûŽqøwôy†óu“ö™øƒ˜øzˆõowõwrùqû˜q÷{òd“ôq•øŒùž…ö~ñexï`rõyqú•où™o÷wqõbuömz÷…{ô{ô•~óozïfnówe÷‹cöœkô’|îtƒéoqî€\óXñˆgòp€õd’÷p–øˆ”õ¤’ó Œòs}ëejëw_ð‡^ò“hóŠ€ðk“ï_“òmó†óœŠô”‰õzõ|ð‘Šë‡€é_xì\söxpûŽqøwôy†óu“ö™øƒ˜øzˆõowõwrùqû˜q÷{òd“ôq•øŒùž…ö~ñexï`rõyqú•où™o÷wqõbuömz÷…{ô{ô•~óozïfnówe÷‹cöškôŽ~ïtƒéqpî€\ó‹Yð‡gñtõg”÷c–÷„‘õ£‹ð”ƒéayçZqñtoùŽo÷¤oô–xíi‚ì`‡ôu÷Œ’ö˜’õƒˆñjtñwjî’dé‰fécwð\ˆùtŠúˆö™Šö†ôw’õ€“ø€‘ön‹òiˆôwŠø‹Š÷›„ôŒ‚ìn‹ìmò„€õ”róˆlðfvò_…øpùŒŒ÷•‰øx‹÷bøn’øˆô¡ŽõŠòbí\|ós|úyø¨xôœuîiqë[móskõlñšnóƒ{ôc‘õg—ø…“ôê`yéZqñqqø‰q÷£pô–xíi‚ì`‡ôu÷Œ’ö˜’õƒˆñjtñwjî’dé‰fécwð\ˆùtŠúˆö™Šö†ôw’õ€“ø€‘ön‹òiˆôwŠø‹Š÷›„ôŒ‚ìn‹ìmò„€õ”róˆlðfvò_…øpùŒŒ÷•‰øx‹÷bøn’øˆô¡ŽõŠòbí\|ós|úyø¥yõ–xðhrí^kôtköŒmñœmò†{ôb•ócqùoôškí‹jédvì]„óp‰ø‰‡ù¡†õ”ëiréckõ}rù”{ôŽƒðh~î[pórg÷cö”gôy}ód•õqœö™ö–•ó|ˆîlvïjö‡iõrzïk“ñwœò†“ð‘îŽjërhîeqöxoøŽjôŽmñ{{ônör˜õ‡“ö’‹ô~ïl–òt™÷Š“÷ˆöŠ€ñc„ì_òtø‰ˆøö‘uñdvñY~øp‚úŠƒöŸ„ò“‚îk{íftõƒo÷˜kïˆlèaxêZ†õm‹ú†‰ø ‡ô”ëiréckõ}rù”{ôŽƒðh~î[pórg÷cö”gôy}ód•õqœö™ö–•ó|ˆîlvïjö‡iõrzïk“ñwœò†“ð‘îŽjërhîeqöxoøŽjôŽmñ{{ônör˜õ‡“ö’‹ô~ïl–òt™÷Š“÷ˆöŠ€ñc„ì_òtø‰ˆø™õŠyïevï_|øoƒú‡…÷¢‚õ—óiîddùzhõ‘hò‘kòs{ðbðo˜õŠ—ø˜–ôƒ‰ìeríif÷…hùŸlô‘sñe{ñ]~öqûŒ|ü|úóp†ísŠð‹Šõ‡…ðixêfhî~_ö`öˆpòw‹ðs’ñxònóˆaõxc÷brûnzü…|ù–ø‘‚öwˆñp†ð„zó”oïŒpçw}êpƒò~yôŽkôdðxrìj‹ñn‘õ~„÷’r÷‘hôtvõeùs—ú”øŸóƒîmnïkdöeù“fõ’jïv{ífŽòr–÷‹—÷˜—óƒ‰ìeríif÷…hùŸlô‘sñe{ñ]~öqûŒ|ü|úóp†ísŠð‹Šõ‡…ðixêfhî~_ö`öˆpòw‹ðs’ñxònóˆaõxc÷brûnzü…|ù–ø‘‚öwˆñp†ð„zó”oïŒpçw}êpƒò~yôŽkôdðxrìj‹ñn‘õ~„÷s÷jótvõhŒùr—û‹•ù ô”ðnpïexøx{÷“}ø|÷…|ñj€ìs…ð’ˆó‘‹ðm‡ï]~ôl{ú†{ø¡zò˜}ñm„ôbŒ÷r”÷‹•øœøŠ~ðrjéxeïŠgô}kñasðhuôuø’uøpö…qðgtñdt÷rtú†sú…xùo‡÷m“ø—÷——÷’‘òkêdsî|kö‘hõ—fð}iìfkîpfô„dõ–cò’kñk~óZ„õn{öŠp÷›löwötŒôs“ñŠŒð–ïvî`wóhxù~zù‘|ø|öŠzðp|ìwƒð‘ˆô‹ñm‡ï]~ôl{ú†{ø¡zò˜}ñm„ôbŒ÷r”÷‹•øœøŠ~ðrjéxeïŠgô}kñasðhuôuø’uøpö…qðgtñdt÷rtú†sú…xùo‡÷m“ø—÷——÷’‘òkêdsî|kö‘hõ—fð}iìfkîpfô„dõ–cò’kñk~óZ„õn{ö‹oøœjøŽw÷sŒõu‘ò‰Œð“‚î‚xícwñd’õy“õ“”öš‹õƒvñoeñzeô”hó“mïm|ñ\Žõi–÷€—ó”똋ìq€òdƒôwñ–ðŒ“ðoëikî{eõŒgöƒnôe€õjŠù€‰ûŽƒûšnøŠ_òlhñe|õs‰ø‰Œö’‹ô„òy‘ò‡“ôš”ò†“ì[‡ê^zõwyûŠ|ù—xõsñfròms÷‚xöœyôšzólòV…ôj…÷„ƒ÷›ƒô™‚óz{ðqqì‚kíŽeï}iñ_€õc‘ø{”ö‘”ö˜Œö‚vðnfíxfò’iô’mðm|ñ\Žõi–÷€—ó”똋ìq€òdƒôwñ–ðŒ“ðoëikî{eõŒgöƒnôe€õjŠù€‰ûŽƒûšnøŠ_òlhñe|õs‰ø‰Œö’‹ô„òy‘ò‡“ôš”ò†“ì[‡ê^zõwyûŠ|ù—xõsñfròms÷‚xöœyôšzólòV…ôj…÷†ƒö‚ó™‚òy{ðqpî€kíŠhïkòf|õf˜îyšíŒ›ï…ðkyñkhö~fû“høŸjô†vòd‹ðg–ñƒ—ñ—“퇄ìinðlhô…oñ—vî‚ë_‚ëc~õy~úŽ€÷’‚óy‹õn˜øu™÷|ˆø†qù‹g÷‚qôwˆôzô‰£óŽ—òƒð~oñnòœqïzéWˆë\öt’û‹”÷—ð~ˆîe‡óm‹÷…÷Žóš†ðt}ï_ƒòl‘õ„˜ô—–ð†ðmrðhhò{iõjõoôz‚ón•ò{›î‹œï‚‘ðg{ïgkô{hù‘jùžjõ†vòd‹ðg–ñƒ—ñ—“퇄ìinðlhô…oñ—vî‚ë_‚ëc~õy~úŽ€÷’‚óy‹õn˜øu™÷|ˆø†qù‹g÷‚qôwˆôzô‰£óŽ—òƒð~oñnòœqïzéWˆë\öt’û‹”÷—ð~ˆîe‡óm‹÷…÷Žóš†ðt}ï_ƒòl‘õ„˜ô—–ïmrðhhóxiõŠkõ”qõˆ}ôeyè}yì‹yðu{ð\€ñg€ö€~ø’‚ö¢ñ“uíjmíkpòrôrôppñdkñwgöŽi÷Ÿmò‹vîd‡ñc’ù{“úö™‚ñ{ïwˆïb•ìeŒïu€öˆ}ø“ƒ÷‰Žô€—ïtŒñmròycó‹eñ™fîŠhéfvçdˆðz•øšö‘îtêd€ðqŽõ‡˜ö““ô‹zðudòjkõu„ôƒ•ó‰ðyvîclðgtöz}úúžöŽîw{ë€yíŒzït}ïY‚ðdõ~€ø‘ƒö¢ñ“uíjmíkpòrôrôppñdkñwgöŽi÷Ÿmò‹vîd‡ñc’ù{“úö™‚ñ{ïwˆïb•ìeŒïu€öˆ}ø“ƒ÷‰Žô€—ïtŒñmròycó‹eñ™fîŠhéfvçdˆðz•øšö‘îtêd€ðqŽõ‡˜ö““ô‹zðudòjkõu„ô‚–ò‡Žðzvîekðeuöu~úŽ€ú¢€õ¡í]cí}_ò‘_ôkñc†ói—õ€™ô’œñ–—ì}|ìffòta÷“aøgöjsóf|ñzó‰‚÷šƒõ“|ïp|ðgŠöv’÷‚†õpò—aíˆiìhê_”ìo˜öˆ•ùš‘ö‘ƒð€pëwiîdoóas÷uuù‡yö“xó‹lïw`í|eñŠvô‡ƒñvzílhïueó†vñŒ…ñ{‚ômoõqb÷búm÷„zònvðjjðpiôuxøƒ‰ø—“÷™õ~|ïmgî€^ô“^õkòa†òg˜ôšô’ò•—í}|ìffòta÷“aøgöjsóf|ñzó‰‚÷šƒõ“|ïp|ðgŠöv’÷‚†õpò—aíˆiìhê_”ìo˜öˆ•ùš‘ö‘ƒð€pëwiîdoóas÷uuù‡yö“xó‹lïw`í|eñŠvô‡ƒñvzílhïueó†vñŒ…ñ{‚ômoõqb÷búm÷„zòmwðjjðpiôuwø‰ø”“÷›ôƒî[n÷xl÷˜jõ˜qò{ƒòo’ó~–ó‘—ò„‘ïaƒð`x÷ytùuø’{ôx‡ñh”òu™ó…šö’õtì{`êqhñhxôkxö{mö’fô›gó„wïkítœó‰œô‰’ï}tí|[ðVóseõi}ùs‹ú†ø‰ö}vöyc÷Š`ö”iñpîhnòof÷ˆdø›kô“sñnwó`vöqvø‹súžqù‡wóaxñevô|vùˆ}ù“Œó˜—î„ðf{õaoø{jù˜g÷—pôy„óm“ó}–ô‘—ó„‘ðaƒð`x÷ytùuø’{ôx‡ñh”òu™ó…šö’õtì{`êqhñhxôkxö{mö’fô›gó„wïkítœó‰œô‰’ï}tí|[ðVóseõi}ùs‹ú†ø‰ö}vöyc÷Š`ö”iñpîhnòof÷ˆdø›kô“sñnwó`vöqvø‹súžqù‡wóayðevô}uù‰|ù‘Œó•˜í†‘ïp~ôaúw„÷—ƒó¢òˆ{ïrqí}mñmó~rî[‚ð_‹÷yŒúŽŽ÷šŽò‹ŠïsŒóx’ô‡”õƒ†òwlë{^ë~aónnögzöt€ø‹€ú {ø•sñypí~xìlídròxiö‰jöŠrõ{ˆôuó‚Ÿó‚’ôoøtwü‰wú”yô‚|ôj}øq|û‡|úœ}ù”zõoxñd}ôt†÷‹ŠúžŠù†ñaðgŒø€‹ú“Žô›ŒîŽ€ëqtì^vôe~ú{ƒ÷˜‚ñ¢€ò‡{ñrpñ~mômó~rî[‚ð_‹÷yŒúŽŽ÷šŽò‹ŠïsŒóx’ô‡”õƒ†òwlë{^ë~aónnögzöt€ø‹€ú {ø•sñypí~xìlídròxiö‰jöŠrõ{ˆôuó‚Ÿó‚’ôoøtwü‰wú”yô‚|ôj}øq|û‡|úœ}ù”zõoxñd}ôt†÷‹ŠúžŠù…ñ`ïi‹÷ƒŠú“õ™îŽêutëauñl‹ô{—ò‘žð“”ðxzíocï‚]õ–]ödîn~ée”ïyŸõŒ£ô‘—î…xíyeò‚iô†qòotñcuòsuóŠs÷‡yùt‹÷u˜õ‹—ö–Šô‡pï}\ñˆ\òƒgðgrób|ùu€ù‰‚ö˜ƒôމò{ñ|Šïu„îhˆórøŠŽù˜‹ø„ˆõj‰ôn‘ö€—÷”’÷€óoqðlsó|ƒôŽ’õ™–ó‘ìcím‘õ„›õðŒ‡ïgñs^ðlnïr…ò€—ñ“î””ïxzíocð‚]÷–]÷dïn~ée”ïyŸõŒ£ô‘—î…xíyeò‚iô†qòotñcuòsuóŠs÷‡yùt‹÷u˜õ‹—ö–Šô‡pï}\ñˆ\òƒgðgrób|ùu€ù‰‚ö˜ƒôމò{ñ|Šïu„îhˆórøŠŽù˜‹ø„ˆõj‰ôn‘ö€—÷”’÷€óoqðlsó|ƒôŽ’õ™–ó€‘ëcìnô‡™öœñ‹‡ïhñw^ðshì~ˆî„˜ïŠœï~îeyïhröqù˜qø pñˆsèu}逌ð†—ït‹ëknït_õˆ`öŒeónuò`‡õr÷ŽŠ÷”Šø’õ|œð„Ÿíx‘íjxðyhõŒg÷möy{õh‘ösœôŠò™–óŒówlôybñyhìqítšð„ñŠôxñrwîy‹ð‚Ÿñ‚—ñt}òlnõ{möŒvô•„ð‚ìzoêmiíyy퇎ë}“íl~ñoh÷|e÷†mðˆ‚튘îœïŒífyìhrò€qù™pú¡pòˆsèu}逌ð†—ït‹ëknït_õˆ`öŒeónuò`‡õr÷ŽŠ÷”Šø’õ|œð„Ÿíx‘íjxðyhõŒg÷möy{õh‘ösœôŠò™–óŒówlôybñyhìqítšð„ñŠôxñrwîy‹ð‚Ÿñ‚—ñt}òlnõ{möŒvô•„ð‚ì{oêniìzyì‰ë€‘îm}òni÷€e÷“gò•„퇅îyxîqiðhmôiùy‰ú‰÷—ó†jï€]ïañƒlðavî^vôsvù‹vø™tø…€õn•òuŸô‰™÷މ÷ˆzò‰zíz‡êZëW‡òv÷}÷œõ†ór‘ðv™ìœë‰•ðr}òjgöxb÷ˆfóŒvð~Žïrïsyòxgô„eó”ròŒ‚ðn„ï[óh~÷…zù™{ø”}ò}oís]ò|[ôŒfîrçn{ê[}óhzú€yú–zö›ò‹…ð{yîsiíhnðh÷y‰ú‘ˆ÷—ó†jï€]ïañƒlðavî^vôsvù‹vø™tø…€õn•òuŸô‰™÷މ÷ˆzò‰zíz‡êZëW‡òv÷}÷œõ†ór‘ðv™ìœë‰•ðr}òjgöxb÷ˆfóŒvð~Žïrïsyòxgô„eó”ròŒ‚ðn„ï[óh~÷…zù™{ø”}ò}oís]ñ}[ôfíqçqzêZ}ôhzù„yùžxù•‹ïzwìkdðq^ö{f÷|ø~˜ø‡œõ‡ôwló‚^ö”]øŠfôgyïa‰òvŽ÷‹÷›†ø“ô|…ëvëxŠñxtô„aô”]òƒkí[ƒíX–ðu™ô–÷¡’ô–€ñymñ}lï‹uìx{ì^|ób{ùx|ú“zö¢zõ‡€ò`}ò_uöuqùŽpø¢m÷’iñkjð]|õlŒö‡øù‹ôjzòhnønû•pö—sïx~í]õg‘ú‚ûšŽù™Šôyyðjeòs]óygôw€ù}™ø‡œò€ˆòwló‚^ö”]øŠfôgyïa‰òvŽ÷‹÷›†ø“ô|…ëvëxŠñxtô„aô”]òƒkí[ƒíX–ðu™ô–÷¡’ô–€ñymñ}lï‹uìx{ì^|ób{ùx|ú“zö¢zõ‡€ò`}ò_uöuqùŽpø¢m÷’iñkjð]|õlŒö‡øù‹ôjzòhn÷nù”qõ˜sï{|î]Œõe’ú„ú¡û†õgvñdpösrú‡s÷“}ôŒòw•ñdˆókzô‚t÷–uú˜yø~ƒïi•îs¢ôƒŸõ‰‹ö„pñcìxgìioïinõ|iú•h÷›jðzwëh‹êz—óˆ–ïzwít^ò€\õ‹cðznì`ƒðg÷ù™Œö¡„òƒyï^vñ`€÷y†ú„ú˜zù‡hõx`ôvo÷y‰ö†–õ˜ò‰‡îc…ðbˆö{‰ø’‰ùŸ‰öŠˆñcŒðdõ€‹ù•‹øˆ‡òezðcp÷woú†sùŽ}úŒôx•îdˆñkzô‚t÷–uú˜yø~ƒïi•îs¢ôƒŸõ‰‹ö„pñcìxgìioïinõ|iú•h÷›jðzwëh‹êz—óˆ–ïzwít^ò€\õ‹cðznì`ƒðg÷ù™Œö¡„òƒyï^vñ`€÷y†ú„ú˜zù‡hõx`ôvo÷y‰ö†–õ˜ò‰‡îc…ðbˆõ{‰÷‘Š÷ž‰ö‹‡ñdŠï`Žô€Œø ‰úzqùa~ôaˆ÷v‰û…øœñuìpqíZ~ñd‹ô€ô—Šõ¡€övñsîq”ðs”ñq}ôviõ…_óƒaõkq÷i~ú}ú”‚ö¤uó‘dï{dé‡pë…ƒìg‡é\xínmô„n÷“põŽxïs‰êm—ì~šð‹“òŠî{hëoiînõx–ù‚˜ù~‡÷yr÷ƒhømú‰|÷€„ñ…uê€iélwîiò}•ô’öˆôˆzìdnçemï~o÷pøƒsôa€ô`ˆùz†ýŽ„ü˜øtðqqë[~ðd‹ô€ô—Šõ¡€övñsîq”ðs”ñq}ôviõ…_óƒaõkq÷i~ú}ú”‚ö¤uó‘dï{dé‡pë…ƒìg‡é\xínmô„n÷“põŽxïs‰êm—ì~šð‹“òŠî{hëoiînõx–ù‚˜ù~‡÷yr÷ƒhømú‰|÷€„ñ…uê€iélwîjñ}•ò’ôœ‰ó‹xìençanî~oõ™pùŒrñn…íe–ñyš÷Š’ö‰ð‚hî~^òvpòró{ óˆ˜ï|î‰aï‰]ïlìgxêdvówsùŒu÷Žz÷wˆùp•úšõ‘—ð’€ô…c÷‚Zô”_ñiífzêY„ñm„÷ƒƒøš„ù¡€ö†{íq}étƒësîroñzdñ„eóˆwõ’ôoœóeópƒõ„~ø“úŽ}÷vsðsfð„^ó†góz|òz‚ôwô˜kñ~eì`gíhkõmù•nù‘r÷n…õf•õ˜ö‹”õ†‚ñ‚hï€^ñvpñró{ óˆ˜ï|î‰aï‰]ïlìgxêdvówsùŒu÷Žz÷wˆùp•úšõ‘—ð’€ô…c÷‚Zô”_ñiífzêY„ñm„÷ƒƒøš„ù¡€ö†{íq}étƒësîroñzdñ„eóˆwõ’ôoœóeópƒõ„~ø“úŽ}÷vsðsfð„^ó†gó{|ò{‚óŒyô—lñ‚cëagídlôlø˜nù˜}ë~{ësƒí{ŽîxŽïp}ðynõ‹iø–oö„óx˜òjïpsïbð˜^ñ•eîoxë`‡ðsŒ÷‹Œø˜õ‰•ôwšò~žî€œìp‡ðkvø{rú—qöŸqð~zîc‰ñk“ô™õ”š÷–†ô~jðs^òwaóljóip÷ztøu÷›vöxòqzîc‚ðmó™ô‹›õŽôlzópqøŠoü“oø~rõroô…hõ•bõ‚hõexøl€û…‚úšƒö~ò{ñtð‚ìzêmïzmõiö–oõ„óx˜òjïpsïbð˜^ñ•eîoxë`‡ðsŒ÷‹Œø˜õ‰•ôwšò~žî€œìp‡ðkvø{rú—qöŸqð~zîc‰ñk“ô™õ”š÷–†ô~jðs^òwaóljóip÷ztøu÷›vöxòqzîc‚ðmó™ô‹›õŽôlzópqøŠoü“oørôroôƒiõ”cô„gôgx÷i‚û„‚úƒø„zò{iñcò‚kïoyïg€ôuù‡ƒøŸ~ô£vðwwíXzñdx÷zw÷‘yôœ{ò‚ƒðeîn›ò‹Ÿó™›ñ‹‹ðv|íxzëqí^„ñcŠô{Šø–‰õŸ„ñ†vðlrñs€ò‰ô‰•ós†îhmñtcù€dûyp÷oùz‹ùŒö”ƒö‰jõ|\ñxjñ{‡ó‡œð…Ÿìo“ídŠòr‰÷‡Š÷‰‰ôtƒôl{õ~xö’xøŒ{ús„ùsŽù„—ø‘—óŽƒî{kðbó‡iðpxïc€öu€ú‰‚õ ~ó£vðwwíXzñdx÷zw÷‘yôœ{ò‚ƒðeîn›ò‹Ÿó™›ñ‹‹ðv|íxzëqí^„ñcŠô{Šø–‰õŸ„ñ†vðlrñs€ò‰ô‰•ós†îhmñtcù€dûyp÷oùz‹ùŒö”ƒö‰jõ|\ñxjñ{‡ó‡œð…Ÿìo“ídŠòr‰÷‡Š÷‰‰ôtƒôl{ô{yõy÷Žzøt„÷pø…—ø™›öbs÷sh÷†cøgö{xñj‘óqœ÷‚–÷”„ô™ið}`íbsòf‡ùvù‹‘õ›ŠóŒzðqwîxƒî‰î€Œîrrït_ò\ñ}cój~óišò~¢õ‘Ÿõ‹òwpòr`õeö™k÷‰vó_€ï\~ôt{úˆ{ûù~‘÷|›ö…™ö~‰öuo÷|cø‰jö“vò”ëzæhyêdŠðrò†£ò‡ ðo˜ñi“ö}‘ù‹ùŽö~{ó|†ô€šôyšðp€ñqkö„cùdõyxòe’öq›øƒ–ö”…ó™ið}`íbsòf‡ùvù‹‘õ›ŠóŒzðqwîxƒî‰î€Œîrrït_ò\ñ}cój~óišò~¢õ‘Ÿõ‹òwpòr`õeö™k÷‰vó_€ï\~ôt{úˆ{ûù~‘÷|›ö…™ö~‰öuo÷|cø‰jö“vò”ëzæhyêdŠðrò†£ò‡ ðp˜ñi“öy’øŽŒø’€õ~|ñyˆóšõ†¤òS}óozô‰zõ›|õ“„ïx“êožív“ó{{÷ƒhö‰côsóu’óz¦óˆ¤òŠï~lîz^ðŠdð‹lîioï`jóvcø‡eø’jõˆ|òx“ñšñ†—ñpŠïcvñnnö‡kø£fù•qôeˆï]•ñu–õ‹”÷—“ø‡ô{Œñy…ól~õh{÷x|ú~ù˜xógî}Zîw^ñyxî}•í‡ñˆ’ïq‹ëk“ðv˜÷ƒ‹ø†uó…hòlóˆðe‹î\ƒôn{ù‡z÷œ{ñ‘…êt•énžîw“ò|{öƒhö‰côsóu’óz¦óˆ¤òŠï~lîz^ðŠdð‹lîioï`jóvcø‡eø’jõˆ|òx“ñšñ†—ñpŠïcvñnnö‡kø£fù•qôeˆï]•ñu–õ‹”÷—“ø‡ô{Œñy…ól~õh{÷x|ú~ù˜xógî}Zîw^ñyxî}•í‡ñˆ’ïr‹ìk“ñu™÷ƒŒø‰tò‡gðŽlòˆñníX‰òj’ð†“óž}ñ„tél{è`€ïh{÷xyùwø™|õˆ‹ð~–ð{‘ïlíknñzhõ‘hõ”hòpqð^|õr~ùˆùôyòƒpòjñ~lîeví]ñm†õ‰ƒö¦€öœƒòsˆêgëy™î‰Ÿð‰–ò|{ðwgíveñno÷l„øx”÷‰”÷‰…÷yk÷y_ù‰dø”oð‰xìytïxfðzcëvuën„ôløwtö†möžlô˜pîkzìZ†òk’ó…”ðžŒñœ~îƒuçm{èbîi{öxyùwø™|õˆ‹ð~–ð{‘ïlíknñzhõ‘hõ”hòpqð^|õr~ùˆùôyòƒpòjñ~lîeví]ñm†õ‰ƒö¦€öœƒòsˆêgëy™î‰Ÿð‰–ò|{ðwgíveñno÷l„øx”÷‰”÷‰…÷yk÷y_ù‰dø”oð‰xìytïxfðzcìwtío„ôo~÷ysõ‰mö kõ™qînyèlwõt튉ó‰mô†\ïx`ïeuôdŠ÷wù‘úœ†÷uòƒbñwaòdpóhzøz~û’~ú~ö}‰òb–òn˜õˆ–÷˜õŒ|òucñzXó†YñxkíiŠïq›ö‰œõ˜ò“†íxlêthì…ví……ëmƒídpòseòfó‡oøƒˆø¢ó€¢ñuôm{ùzwû{ùœ{ô†sïheñn\ö…\õ‰eótsõf€öm†öƒ‡õ‚ô›tðygìmrðvŒï—툉ó‡nô…\ïz_ïgtôe‰÷wù‘úœ†÷uòƒbñwaòdpóhzøz~û’~ú~ö}‰òb–òn˜õˆ–÷˜õŒ|òucñzXó†YñxkíiŠïq›ö‰œõ˜ò“†íxlêthì…ví……ëmƒídpòseòfó‡oøƒˆø¢ó€¢ñuôm{ùzwû{ùœ{ô†sïheñn\ö†[öŠdôurôhôn‡ö„‡÷ €õžuð~gå|eõ…rò}ñnzôqmö„hôŒiôy÷p’øz÷˜÷‰‡ô~iò‚Uô€Yõrpõnˆ÷z”ù“‘ú ‹÷„ŒðfŽîpòˆŒõ†‰ón}ñhpñ|kõ”i÷tðw‡ìs“ò†“ôŒŒîyvéo`î}Zõ”_óŽhïftð[|öq÷‰~ö›€ø˜Œö‚–íoŒèc‚îg†ô}Ž÷”’ö˜Šò}yígqôrqúˆsú•t÷†õk‘õn˜ô…–òô…võxbòbóŠpó|ñlzôooö‚hôŒjôx÷p’øz÷˜÷‰‡ô~iò‚Uô€Yõrpõnˆ÷z”ù“‘ú ‹÷„ŒðfŽîpòˆŒõ†‰ón}ñhpñ|kõ”i÷tðw‡ìs“ò†“ôŒŒîyvéo`î}Zõ”_óŽhïftð[|öq÷‰~ö›€ø˜Œö‚–íoŒèc‚îg†ô}Ž÷”’ö˜Šò}yígqôrqúŠrú˜sø†~ôk’ók›ô‚˜ô‘Œö‹vôbîysñqõvöe|÷jù‚ø—õ•€ó}„ñzˆñ‡ñl~ïhsò|nö‹pö†yóu‹ðw’ñŽŠó›{ð‚oédjéohñ‡hõmókvôl~ö€€ù˜ûš}ö~tñslñ‚iñ}hîdlîeoõ}pù–nø˜oótzðc†ôt‹øŽø¡’øšóyyédhèblïo}ò…ô‘“óŠƒírnêjqôu€û„‹÷˜ñ’îpñrŠòƒ†ðzókuønqø‚qö”p÷‚töd|÷g€ù€€ø•õ”ó}„ñzˆñ‡ñl~ïhsò|nö‹pö†yóu‹ðw’ñŽŠó›{ð‚oédjéohñ‡hõmókvôl~ö€€ù˜ûš}ö~tñslñ‚iñ}hîdlîeoõ}pù–nø˜oótzðc†ôt‹øŽø¡’øšóyyédhèblïo}ò…ô‘“óŠƒírnêjqôu€û†‰ø›Žò’în‘ðmò~ˆò|õst÷{pù~‡ó’ˆõ‰‹ókôi”ù•û•’÷ƒî|lê|cïxiñawïa„ó|…ö’„÷‘…÷y~ôqtòƒmò‘dð_ìedîmhô‡g÷Œmôy~ôs‘÷™ù‘™÷Šõvpõpbõ‚`õ‚dõjt÷fƒú|†ù–†ö›„ñ{€ìd}ït~õ„öŸ‰ó‹ƒíeqê`gñriø†qùŽ}÷‚‚óqtïjhòqn÷úŒ’÷™›ïŠ‘éjwëohð~hñumòhxöo„ø‡‡øš†ö‹‰òjóf•ù~—û““÷Ž„î|lê|cïxiñawïa„ó|…ö’„÷‘…÷y~ôqtòƒmò‘dð_ìedîmhô‡g÷Œmôy~ôs‘÷™ù‘™÷Šõvpõpbõ‚`õ‚dõjt÷fƒú|†ù–†ö›„ñ{€ìd}ït~õ„öŸ‰ó‹ƒíeqê`gñriø†qùŽ}÷‚‚óqtïjhòqn÷úŽ‘ø™ð‹‘éixêjjðziòwlôowõyƒ÷†›ò–›òŒïr‡òq÷—÷ƒ•óu€ðsjñ…aöŠe÷tzôk“ô}œó’ô‹•÷q}ùlnø|løjø„m÷jy÷l€ù†€ù–‚õ‹Šðy”ñ|œóžîs‘êg}òrvú‰tû”uù÷rù’÷——ô“’óo}ñ_oôsnö‘oó oï‚tëY}î\ö{|û”{û“€ùwöcwökuùw÷–}õž‡ô–…îuxéXnîehöi÷„qô{‚óy•ôŒœôœ˜òŽîp†ðnö~˜÷–ótðsjñ…aöŠe÷tzôk“ô}œó’ô‹•÷q}ùlnø|løjø„m÷jy÷l€ù†€ù–‚õ‹Šðy”ñ|œóžîs‘êg}òrvú‰tû”uù÷rù’÷——ô“’óo}ñ_oôsnö‘oó oï‚tëY}î\ö{|û”{û“€ùwöcwökuùw÷–}õ †õ™„ïvwéYníbjö|jø†oõ€ò–ñ†–퇑ïzyíseñ~iö…xòt€ïcômzù…xù—zù’÷}ô|—òŠ–ð}ðe†õhƒùz„úŽƒû‹†ûp‘øo–÷‡•÷™’õ‘„ðzvî|uñyîiéa‰ïrøŽ‰ùš†ö‰óz~ò…„ò”ñ‚Œò`~õ`uøvuú‘tù¤qô‰uï^‚ð^ôz”ö”÷‘Œõw}ófzøn„úˆ‹õŸ‰ò›}ñ„hîj`ïYqóe~øù„öˆõ‡ôŠ”ñ‹Žï{wíqeñ|iõƒxòrïcômyù…xù—zù’÷}ô|—òŠ–ð}ðe†õhƒùz„úŽƒû‹†ûp‘øo–÷‡•÷™’õ‘„ðzvî|uñyîiéa‰ïrøŽ‰ùš†ö‰óz~ò…„ò”ñ‚Œò`~õ`uøvuú‘tù¤qô‰uï^‚ð^ôz”ö”÷‘Œõw}ófzøn„úˆ‹õŸ‰ò|ò†gïk_î[oòe~ø€€ú‘‚ö‘ˆóˆó…lðqnðehðr`óˆaö‘gó|uñe‰ök’ù€“÷•’÷˜‰öxñylòƒiñyoëf„íi—õ|›ö”–÷“‘÷t‘ôqóˆó†ðƒpîx_ó‚^÷`ö~pðjïožóƒœôˆözxõukó…mñ—pîƒvìaƒîeŠôx‹úŒŒú„õŠuðmoðr~ó‚”ôˆ™ôƒ„ñtlñpm÷y€ø†”ö‹“ô{óvdõy_øwoötˆõ}—÷‹”ö‘€önö‡jôtkñfgðq`ó‡böhó|uñe‰ök’ù€“÷•’÷˜‰öxñylòƒiñyoëf„íi—õ|›ö”–÷“‘÷t‘ôqóˆó†ðƒpîx_ó‚^÷`ö~pðjïožóƒœôˆözxõukó…mñ—pîƒvìaƒîeŠôx‹úŒŒú„õŠuðmoðr~ó‚”ôˆ™ôƒ„ñtlñpm÷y€ø†”ö‹“ô€{ówcöy_øwoöu‡õ€•øŽ’÷‘‚õŒpõ‚_óreõfqöqw÷Šw÷œwôñmŽój—ó‚–ó‘“ô„…ñqjït\õ„]÷Œcïxëmòx”ö•ˆó|ònróllõƒkò‚lîriòshøƒnø˜nö™ró|ïr‰îy‹ðp‚ófw÷prùŠpõ lð’mìl{êiŽï{›ö‡õ†‹ñznòyaô‰höyó{ƒðgyñllô~l÷ŽvöŠˆõuõh}õpsøƒrú“v÷‰ó{žôw“ó~sô…`÷…^÷wdöhpöqv÷ˆw÷›xôñmŽój—ó‚–ó‘“ô„…ñqjït\õ„]÷Œcïxëmòx”ö•ˆó|ònróllõƒkò‚lîriòshøƒnø˜nö™ró|ïr‰îy‹ðp‚ófw÷prùŠpõ lð’mìl{êiŽï{›ö‡õ†‹ñznòyaô‰höyó{ƒðgyñllô~l÷ŽvöŠˆõuõi}õqsø‚súx÷‰ô€›õy“ó~tò‰aö„røƒv÷q„ôqŽöˆŽø ó—‰ñp|ñhvñvñ‰vðquïcrôpqú‡rû pö–qòntômo÷‡fö…bóidôhgøi÷nõoxùlƒù}ˆñ›…ïyò~jðtbðxeðlpïd€õt†ùƒ÷{õmòxeïwtï„ð{—ïk†ñmq÷{mùpö—tíu{ê\€ïhô‚€ôš€ô•„ôp…ò`ƒólˆõ€Œö›Šó‰íz‡îb}òlrõ}púŠqû‰vøt„õrŽ÷‡øŸó—‰ñp|ñhvñvñ‰vðquïcrôpqú‡rû pö–qòntômo÷‡fö…bóidôhgøi÷nõoxùlƒù}ˆñ›…ïyò~jðtbðxeðlpïd€õt†ùƒ÷{õmòxeïwtï„ð{—ïk†ñmq÷{mùpö—tíu{ê\€ïhô‚€ôš€ô•„ôp…ò_„òkˆô€Œõ›‹óŸˆî}†î^ñktòŠlù‰‰õŽ‹ð{îr“õ‡’÷šŽò‹€ñjkòicôfõˆiórsñ`ƒ÷mŠûŠˆú¢„÷‘~ôgsógi÷fùjõmtôl}ùûŒ€ú†úp‘õ|™î’–óonõua÷‚d÷}róo‹òvšõŠ•øŒƒø~m÷{cöfô‘qïsyí_}òl~ù‚û”…ôœƒè}éf‚ïnŒóƒ’ô™“õ•‡òsvîdxòrˆõƒ–ô’–óíshêaiñgyøx…û‰ù”‹ò}ïs“ö†’÷™òŠñikòicôfõˆiórsñ`ƒ÷mŠûŠˆú¢„÷‘~ôgsógi÷fùjõmtôl}ùûŒ€ú†úp‘õ|™î’–óonõua÷‚d÷}róo‹òvšõŠ•øŒƒø~m÷{cöfô‘qïsyí_}òl~ù‚û”…ôœƒè}éf‚ïnŒóƒ’ô™“õ•‡òsvîbyòoŠô„–ó••ó“îuhëZmïe}õ…‚û¢îŽœèz‰ëm|ô€wôŽqðvnð`pómqø†rú•tø‡õl–÷nžø‡˜õ•ñ‡ïcñm}÷ƒ}û‡ùzŠöv’ö†“ø‘ŒøŠ€ö}€ò†‰ñŠŽòm‰óa€öyxùŽxú“ø†ñzžïwšòt…õqwø{vû’vø•nõydógoón…ö€”ø“™ò—‰ípïnoñ{|óŒôŽ‘ô~ïpgïqfö‚t÷‚ö…†öqtôncñufòvz÷~÷Ÿñ“œé{ˆëm|õwõqðvnð`pómqø†rú•tø‡õl–÷nžø‡˜õ•ñ‡ïcñm}÷ƒ}û‡ùzŠöv’ö†“ø‘ŒøŠ€ö}€ò†‰ñŠŽòm‰óa€öyxùŽxú“ø†ñzžïwšòt…õqwø{vû’vø•nõydógoón…ö€”ø“™ò—‰ípïnoñ{|óŒôŽ‘ô~ïpgïpgõ€uö‚ö‡…÷trõpbñpjñt}õ‡‹÷˜í~éjuígiõ~gö‘dõ{môb‚ól‰ø‡„úŸøœƒõ}òq’ò~‰ð†{îysïl€ñsõ…’ù‘ù†’óy™í{›ï€Šò}tó~môoóŒvòf…ó]‘õwö‘÷Ÿ‹ö—„î}éj}êaƒîj‰ôŠø‰÷‰z÷zgøxgö€zó‰’ñŠšï|ómh÷qfõŠmï˜vï€~ñcyðgoô|møq÷™tö|wõ^yôjuö…røyö•‰ò“•î‚ékuígiö}gödõ{nôa‚ól‰ø‡„úŸøœƒõ}òq’ò~‰ð†{îysïl€ñsõ…’ù‘ù†’óy™í{›ï€Šò}tó~môoóŒvòf…ó]‘õwö‘÷Ÿ‹ö—„î}éj}êaƒîj‰ôŠø‰÷‰z÷zgøxgö€zó‰’ñŠšï|ómh÷qfõŠmï˜vï€~ñcyðgoô|m÷’pö˜töxyõ^xôosö†s÷|öž†ñ~kímií_nógt÷€uø˜sö{ôm‹ôh÷†øš{÷Ÿsòpêipéqlï‚fõˆfó~zïv”ñ–ö†õ‰|íy€èk‡ëeñlwö|tø•r÷—rôw{òi‰ów–òŠœïð†sî}\íu_ïixïl•ï ñ‡˜ôv„÷pvør÷™vóœî€…îc{ôcsùwt÷‘vòœxñ|~ðZƒñe„öƒ÷•…ö˜…õw‡ðYŽïgø‡†ûšƒöš|ò‰oïqhî`nófuøvø—tö|ôm‹ôh÷†øš{÷Ÿsòpêipéqlï‚fõˆfó~zïv”ñ–ö†õ‰|íy€èk‡ëeñlwö|tø•r÷—rôw{òi‰ów–òŠœïð†sî}\íu_ïixïl•ï ñ‡˜ôv„÷pvør÷™vóœî€…îc{ôcsùwt÷‘vòœxñ|~ðZƒñe„ö‚ƒ÷˜„õ–†õqŠñXðmиІúš…õ§ó}Xôu_ódwòiŠö÷™Šñ—†ðsƒôc~÷vwùrù˜nö„lîfnêipòpù—qõ“|ñuˆòn~ö}löˆeñ‰gðurð^ƒófŠù~‰û–ˆùš|ö…jïyhî‚zêp‚ìilóx`÷ˆaõ‰pò€Šð–ït‘ñc‹õiŠö„ˆö…õŸzñ}pð]yóe‡÷}Œ÷’÷›…õ…zðgïjô™ø’˜ö•ò{†íbîlœöƒšù‹‹õ„rô‚]õy^ófvòiŠöŽ÷˜‹ñ—‡ðsƒôc~÷vwùrù˜nö„lîfnêipòpù—qõ“|ñuˆòn~ö}löˆeñ‰gðurð^ƒófŠù~‰û–ˆùš|ö…jïyhî‚zêp‚ìilóx`÷ˆaõ‰pò€Šð–ït‘ñc‹õiŠö„ˆö…õŸzñ}pð]yóe‡÷}Œ÷’÷›…õ…zðgïjô~™ø“˜ö•òxˆîc‘ïq›÷œ÷‰ówó‚gú‡pó{ƒît”ô€•÷‘‹ñŽ}ïqtòbyöp~ù„ú•€ùŠ‚ôi‡ïh‰ôˆùš‡öš‡òq„ñ_xöop÷…pò˜póŒyôkñhžô øŒ™ø…ƒõxiò}aòŽgñ…oîcuï]xösyùŽxóžwð“uñ|lðllïaƒñl–ó…˜õ‘‹õŽrñ~bðjròmöøŒ™øŽ€õ†fðygðx€õ|–÷…ŽôŒsðfívvíx’ïw˜óq…ôsqõ„hø‹oó{ƒís”ô~–÷ŒñŽ}ïqsòbyöp~ù„ú•€ùŠ‚ôi‡ïh‰ôˆùš‡öš‡òq„ñ_xöop÷…pò˜póŒyôkñhžô øŒ™ø…ƒõxiò}aòŽgñ…oîcuï]xösyùŽxóžwð“uñ|lðllïaƒñl–ó…˜õ‘‹õŽrñ~bðjròmöøŒ™øŽ€õ†fðygðx€õ{–÷„ôsð„dî{uîy“ðpœòn‡ò|rô}€ù’…ñ–Ší|Œòrƒö€sõ‡gôziôk€õp’ø†•øœ“ö‘’ñi”íe‘ò}Œ÷˜Šö–‡îlˆë[ˆôm‡ø„‡ó›ˆò˜‰óxŠïnî|–ñz’ôlõlvø|uø“tõvòo€òaøq’ùŒõ˜…ò‡pñy\ó{[ô{pôz‹ò{“ñzò|jô„cõ†móƒ‡ò›ôu‘ótsòaô‰c÷Œnø~xôsrñ|côƒ`ôhï‹xìl†ï]‡ôløƒø”…ñ’Œízòrƒö~tõ†gô|hôlõp’ø†•øœ“ö‘’ñi”íe‘ò}Œ÷˜Šö–‡îlˆë[ˆôm‡ø„‡ó›ˆò˜‰óxŠïnî|–ñz’ôlõlvø|uø“tõvòo€òaøq’ùŒõ˜…ò‡pñy\ó{[ô{pôz‹ò{“ñzò|jô„cõ†móƒ‡ò›ôu‘ótsòaô‰c÷Œnø}yôqró|bõˆ]õ–eð‹xìdŠî\ˆów÷|˜÷˜“ò™Šîm€ï]wõroø†l÷p÷‚€öt’ö‚’õ‡ô”€ïg€ë_}ðzvö•rõ—qîr|è^Œñp“ùˆ—ö—šò’Šð|mîvcí|jñrsñfói‰ø{Œù”‹÷˜‡óñpˆóx—ö…ö‘ôpyóxk÷‰jø—o÷{òn‚ìd{ótuúŒsú¡vóŸ~ìy‡íY‚îevò€qøuû“xö~vðnpôwmûˆrú¡qô¡nðtxïWŽòf™÷˜ø˜”ó”Œîmï_võppø…l÷‘o÷„€öt’ö‚’õ‡ô”€ïg€ë_}ðzvö•rõ—qîr|è^Œñp“ùˆ—ö—šò’Šð|mîvcí|jñrsñfói‰ø{Œù”‹÷˜‡óñpˆóx—ö…ö‘ôpyóxk÷‰jø—o÷{òn‚ìd{ótuúŒsú¡vóŸ~ìy‡íY‚îevò€qøuû“xö|wñirõspüŠqû§nõ£nðpzî[ñt—öx•ô‡òŠvîbtîW~ök…ø……õšƒö“õt~ïstðgöbõfjð_ròzpö”løŸlô…qífzëoƒðŠ‹òï{|ìocïw\ô‚aô‚jñsðk™ó{Ÿõ™õ„óiî|gí†}ì‚ìfŒí]†óp…÷ˆ…õ¢‚ò˜}îi{ì\òo‰ú‹‹û§…ö¥yîxoëWvî`„õyŠú÷”ñzïh‹õtˆû‹†ú¢€õ¡nñ‚fïf~ðf—òy—ôމò†xíerî[|ök…ø‚†õšƒö“õt~ïstðgöbõfjð_ròzpö”løŸlô…qífzëoƒðŠ‹òï{|ìocïw\ô‚aô‚jñsðk™ó{Ÿõ™õ„óiî|gí†}ì‚ìfŒí]†óp…÷ˆ…õ¢‚ò˜}îi{ì\òo‰ú‹‹û§…ö¥yîxoëWvî`„õyŠú÷”ñyïdöoŠü‹†û§}ö¤nòhîj|ïr–ógvñzkò…`òviòf„õp—øˆ™ö˜’ô‡…ðiwênlðŠdúeûqq÷h~÷z‚ùƒø›õ‹rñmfìphëjíŒkîjpî`sõuuúŒvøštöŠzótˆò|ñƒˆîwuîvbó€aó’jëŠlæfpé\€ón‘ö‡™òž’îŒ}íjlïhtówˆøˆ“ø’ŒõŒpò{]ðmgòlƒøy˜ø‘›ò˜“ìxëb™ðm¡õƒšõŒ…óˆlòŠ]ò†eñrvïlwðxló‚aòzfòm€õq—ø…šö–’ô‡…ðiwênlðŠdúeûqq÷h~÷z‚ùƒø›õ‹rñmfìphëjíŒkîjpî`sõuuúŒvøštöŠzótˆò|ñƒˆîwuîvbó€aó’jëŠlæfpé\€ón‘ö‡™òž’îŒ}íjlïhtówˆøˆ“ø’ŒõŒpò{]ðmgòlƒøy˜ø‘›ò˜“ìzëd—ño¡ö…™ö‘ƒôŠló„_ò‚fðywðYnõpiøŒfù“mô€‚ñu‘õ…÷Ž„ôt|ï^~ðn~÷Š{û•|úƒ‡÷o–ötœ÷†™÷‹Žôyxòkkõvjõ’hô”jõl{ö`ˆùv‹ø‹øš„øŒtôygï}dîyhêioínrøuû’rôŽeïu]óshøƒ~÷Žô‰Œïttïndö|høŒvø‰‚öt€óomõ|aõ‡gö‰yö…ðŠŠìsê|kép€ëq™îp˜ðm‚ósr÷Œj÷šfõjòemôokø‰gù˜jô†~ñv‘õ‚‘÷Œ…ôt|ï^~ðn~÷Š{û•|úƒ‡÷o–ötœ÷†™÷‹Žôyxòkkõvjõ’hô”jõl{ö`ˆùv‹ø‹øš„øŒtôygï}dîyhêioínrøuû’rôŽeïu]óshøƒ~÷Žô‰Œïttïndö|høŒvø‰‚öt€óomõ|aõ‡gö‰yö…ðŠŠìsê~jét~ër™îp™ðpótr÷…l÷•hõŠkòX€ús}û{ùŸõ~ðovðumô†gõumôaƒ÷n‘úˆ‘ú›Šõ‘Šðr—ðló~õ|ómtókxù|~ü•øš~÷yöjˆô{‘ðˆ™ð…“òsyñqfòaóhðqyóp†ûŠý„ùƒu÷wiú„hù™qô‘|ðm€íbyòptù…tø™xøŒ}÷g~óbzôyxõzö˜}ó‚~êqnëz]ó…[ò‹fî€tïd~ð^ôp‚ø‹€ø˜~ô€óh€øsü~ù¡}ô’{ðovðsoô†gõumôaƒ÷n‘úˆ‘ú›Šõ‘Šðr—ðló~õ|ómtókxù|~ü•øš~÷yöjˆô{‘ðˆ™ð…“òsyñqfòaóhðqyóp†ûŠý„ùƒu÷wiú„hù™qô‘|ðm€íbyòptù…tø™xøŒ}÷g~óbzôyxõzö˜}ó‚~êqnëz]ó†Zò‹fí{wî^ð^órøŠ€ù›~öñW‰õu‰÷Œõ”•ó†ñhpóqg÷…iöˆqô{ƒõt”÷’÷’€ò”qî|síhyîoqñygówlôx|÷‚Žø“”ö”†ò|rïtmð‡yîtŒî_„ñk|÷ƒzúŽ}÷ƒŠ÷yœ÷‚ ÷‚–õq‰õsú‡~øšñ’{ìlxí_ôlŒö„ŒõšŠ÷†öh†óbŒôy‘õ‘’õ•Œós~ïapòtiùjùœiõŒdñkhñeyõx‰öŽ’õ””òzïjˆôwŠø‰“ö“”ó€…ðfpópg÷‡hö‰qô{ƒõt”÷’÷’€ò”qî|síhyîoqñygówlôx|÷‚Žø“”ö”†ò|rïtmð‡yîtŒî_„ñk|÷ƒzúŽ}÷ƒŠ÷yœ÷‚ ÷‚–õq‰õsú‡~øšñ’{ìlxí_ôlŒö„ŒõšŠ÷†öh†óbŒôy‘õ‘’õ•Œós~ïapòtiùŽiøœió‡gðdlñdyõzˆ÷“÷–”ôˆŽíZyðy}òŠõ‹’õjôb€øt}ù†‚ó‚ð˜òrƒói{ô~nõ‘böŒbòlkíbpñtpöƒt÷ˆ‚ö‡˜ô†òz…ðolñwfõ“i÷–pôqzð]„òmˆ÷…‹ø—‘ö‘˜ò}œî{•íu‹îfŠóoù†’ù“Šõuñzfñlyòn—ñ€žñŽõ‡zõqvôs†ö…˜õ’šô‰‡õhuö`x÷w~ö’ùšzø†nðseñvlø„÷“‘ñŽïs}íkuð{~óŒôŠ“ôkŒô`øs~ù‰€óŸð˜òrƒói{ô~nõ‘böŒbòlkíbpñtpöƒt÷ˆ‚ö‡˜ô†òz…ðolñwfõ“i÷–pôqzð]„òmˆ÷…‹ø—‘ö‘˜ò}œî{•íu‹îfŠóoù†’ù“Šõuñzfñlyòn—ñ€žñŽõ‡zõqvôs†ö…˜õ’šô‰‡õhuö`x÷w~ö”~øyö†nîpfïul÷…ø’“ò‹’ðy}íglô„lôrô‘zôfƒô\ˆöpŠöˆŠñ¤ˆî•„ïbïZyówrùqü‘u÷v~ðd‡óu‡ø†÷™‹õ”ïyŠë`€îczöyxù™vøœsóyqïerôs{ùІöœðŒìtyêojïthòruóvŒô}•ô}…õ|möböˆmô‚‡ðyðx{óxg÷d÷qöކò~ˆïpqójf÷jtõ|…ôŽø‹Œøu|ôupö…oú’z÷”‚ðz{ïfmñphõ†mõ™tó‘zóh‚ô[‰ön‹öŠŠñ¥‡î•„ïbïZyówrùqü‘u÷v~ðd‡óu‡ø†÷™‹õ”ïyŠë`€îczöyxù™vøœsóyqïerôs{ùІöœðŒìtyêojïthòruóvŒô}•ô}…õ|möböˆmô‚‡ðyðx{óxg÷d÷qöކò~ˆïpqójf÷jtõ|…ô‘ŽøŒŒ÷w|òvpõ„pú“zø“ƒñx}ïjlñpxôŒuõ¤wñ—zîgzîX{òm}õŒ{ó¡zñˆìXŠëYŒóvŠùŠŒú’÷€’ók›ôxžõ™ò™Œñ“sîxfé`xîd‹ô~Žõ˜ö”†óuuðlj÷~mü–s÷Ÿyï‚vêakîddözeøŠmó‡|ïq†ïfôpuø†rùžsø”{õn|ódsõsmùˆmù›röŽ{ñfzì]pñnn÷ywóŠƒñ’ôvšöe÷s†÷Š„ö™‰ò‘‡îi{ð\wöuvøŽvõ¡yð˜yíkxíW|òl~õ{ô¢yñˆìXŠëYŒóvŠùŠŒú’÷€’ók›ôxžõ™ò™Œñ“sîxfé`xîd‹ô~Žõ˜ö”†óuuðlj÷~mü–s÷Ÿyï‚vêakîddözeøŠmó‡|ïq†ïfôpuø†rùžsø”{õn|ódsõsmùˆmù›röŽ{ñfzì]pñnn÷ywóŠƒñŽ“ót›ófôu…öˆ…öšŠó’‡ïj}ð`w÷pó‰Žó£ð”…ëcxëWrôrrùrø röwïf‚ë`ðv™õŠ ó•–ò†ˆðsîvšð|—ð{ñ|dô~\óxoðvŽð„Ÿôö€ógòj{÷€zúœy÷¢yóx}îVðb|ø€yúœyöš}óq…òaˆõt‡øŠ‰øŸˆö“õhzõ_}ötƒ÷‹ƒøžƒù}õfvï_{órƒøƒ†ö›ˆò™‹ðròa—óqžðˆžðœ—ëh{ï]„öu÷Œô¡ð–„ëfvëWrôpsùŽqù¡q÷wïf‚ë`ðv™õŠ ó•–ò†ˆðsîvšð|—ð{ñ|dô~\óxoðvŽð„Ÿôö€ógòj{÷€zúœy÷¢yóx}îVðb|ø€yúœyöš}óq…òaˆõt‡øŠ‰øŸˆö“õhzõ_}ötƒ÷‹ƒøžƒù}õfvï_{órƒøƒ†ö›ˆò˜Œïp’ïb—ñsð‡Ÿñœ—ð’†ìi}î`ƒ÷r›÷‡žó—‘ï„yí^pï^v÷v}ûŠø€õ”sóshîoqî‡îˆ’ë†ëfëbëzqîgzñesôslù†kù”pô„ñ„—ó~òo{îc|ðl‰ô}“õ–‘ôœ†ówî[†ígŒöŽùžö‡ôwƒóeŠòt—ó† ó’•ñ‰{òolôg|òs’ñ†™ô’ö†uóniómvö{‹ø‰—øœöžyñmðoìwšè ì‹‰ï†jëqfìl}ò{•÷Š ô•“ï†xìanî]vøt~û‹øžö”sóshîoqî‡îˆ’ë†ëfëbëzqîgzñesôslù†kù”pô„ñ„—ó~òo{îc|ðl‰ô}“õ–‘ôœ†ówî[†ígŒöŽùžö‡ôwƒóeŠòt—ó† ó’•ñ‰{òolôg|òs’ñ†™ô’ö†uóniómvö{‹ø‰—øœözñ}oîp€êyšç¡í‹‰ð‡jìrhìswð~Žõ‚‘ð{}îofðjeñrt÷}‰ø†™òŽ‘îuñtaô„_ôiî}oémgìs^ñˆ[óŒ_ônnõd|÷uúŠ‚ø¡ƒöž‚ñ{zìkjìmbðskò~ò†”ó‹”ò‹{ð}fípqërò}÷‹—òŠïyjïtpñzŠð{šìw‰ëykò{aô{pò~‰ò€–ó|…ðumðtgö€oú‰„ø…–õƒ‰ð†gï„Xñ†cì†xåt€êiròqaô|`ó†oòЇô…“ñyîqeðmcñrt÷{Šù‡˜óïuñtaô„_ôiî}oémgìs^ñˆ[óŒ_ônnõd|÷uúŠ‚ø¡ƒöž‚ñ{zìkjìmbðskò~ò†”ó‹”ò‹{ð}fípqërò}÷‹—òŠïyjïtpñzŠð{šìw‰ëykò{aô{pò~‰ò€–ó|…ðumðtgö€oú‰„ø…–õƒ‰ð…hî‚Zð‡cëˆwårëiróraõ}bó’iï•}ñx{îdpñkhö~jôqõŽˆõžîq•ëj{ðvn÷kú•køvnõcqöprúŠrúœqø†|õiŽõn’÷ˆŽöžŒñ•‚élpçahðshù…kù“v÷Œ‚ôx}òtjô€]ô‰dñˆ{óŒõr…ðqoï|`óŒaõoñt{êbyëloönúrù—zöðl{ïlvôxyúyû˜€÷}‡ðgzêljîeõ˜eö–jñopñYs÷hsûqû™tö›zòz|îbrñmgö‚gôqöˆö‚ïr”ìj{ðvn÷kú•køvnõcqöprúŠrúœqø†|õiŽõn’÷ˆŽöžŒñ•‚élpçahðshù…kù“v÷Œ‚ôx}òtjô€]ô‰dñˆ{óŒõr…ðqoï|`óŒaõoñt{êbyëloönúrù—zöðl{ïlvôxyúyû˜€÷}‡ðgzêkkí€fô™eõ—iñnqñZs÷isû‚túŸsö €ïqyï[zõiù‚€÷›õŸ‚ò„î_‚î`‚òu„÷Œ„ù’†úyŠ÷g‹÷tŠúŠŠúŸ‰÷’ˆðlŠíh†ò…|ö›uñ‹rébví^}÷w~û}ú›€ø…‚ógyñhr÷~qú”qø™uô~zðbvògrö}qù—pøœoò|qîaxòh÷…ù›„ú£õ€ƒêb†ìjŠø|Žû˜Žö‹ðyë_zîf{õ|ùžzú|õr‚ó[‰÷j‹úƒ‰û ˆ÷¡€ðszîY{õk}ù†}÷›~õƒó€„ï`î`‚òu„÷Œ„ù’†úyŠ÷g‹÷tŠúŠŠúŸ‰÷’ˆðlŠíh†ò…|ö›uñ‹rébví^}÷w~û}ú›€ø…‚ógyñhr÷~qú”qø™uô~zðbvògrö}qù—pøœoò|qîaxòh÷…ù›„ú£õ€ƒêb†ìjŠø|Žû˜Žö‹ðyë_zîe|õ}}øŸzúŸ{õqƒó\‰÷l‹ù„‹ù Š÷‹{ïlpì]|ðg÷}—ø“‘ó–|îfîiiïg€ôu•÷Šö•›ó—ín˜íy™óˆ–õ•‹ôˆ|îhtìhqôƒmú›iø’oók‚ôdø{”ö”•ò›”ò€Œñb†ðfˆô{‹÷‘‰÷™ò{wìauñiø|ˆú’ˆø™€ó€qñitòn‡òƒ”ó˜˜õ™ðwçaëoŠõ„–ö–›ïéruéctól‚úúœ÷›‹ït…ëa‰òp”øˆ›ù›–ô“€ïnpî\}óiŽ÷•÷’‘ó”}ï€fïiiïg€ôu•÷Šö•›ó—ín˜íy™óˆ–õ•‹ôˆ|îhtìhqôƒmú›iø’oók‚ôdø{”ö”•ò›”ò€Œñb†ðfˆô{‹÷‘‰÷™ò{wìauñiø|ˆú’ˆø™€ó€qñitòn‡òƒ”ó˜˜õ™ðwçaëoŠõ„–ö–›ïéruéctól‚úú÷œŠðs†ìc‰òs”øˆœ÷Ÿòkgôoaïrnîz…ô€–÷}’ñxwî}bñcò‚uõ„÷‰œðë|ésêrŒîy…ò…qó}fñhkòjw÷~|ù˜|ú}øƒôqŒô{›ï‹ŸèŽë~xñh}ñk’ï|Ÿñ‹›ôŽòzjðjlòr~÷‚ù‹–÷†„óykòthô}yó‹ñ•ò€‚îogìocñ}róŽ‚ñ‹Šíu{êjgïph÷|yù‹ö”•óŠ‚îvjìqkï|ñ†’ò„‰òxnóp`óqmó{…ô€˜ô}’ðxvî{bò€dñ‚uõ„÷‰œðë|ésêrŒîy…ò…qó}fñhkòjw÷~|ù˜|ú}øƒôqŒô{›ï‹ŸèŽë~xñh}ñk’ï|Ÿñ‹›ôŽòzjðjlòr~÷‚ù‹–÷†„óykòthô}yó‹ñ•ò€‚îogìocñ}róŽ‚ñ‹Šíu{êjgïph÷~xù‹ö•“ó‰ƒïtjísjð€ñˆ‘ñ‰•ð`iùviø‰nö–xõ‰„õh…óbzôwsøqùœvø•~õ|{îukë‚\í~_ïhmñgoôyi÷‚høwu÷nŠøx•ù‘÷•ôŒlò‚kò~}íw‚çtoìx]ó{eð€‚삚îz–òuyótiôxlõ‡v÷ˆö~“òn„òtpö‚múuù˜}ô†îhsìfgôxfùŽköœpóuñ`tòep÷|pûvö•ƒð‚…îqrñu_õ„_óŽmìƒwêjtîfk÷vhú‡mø–wö‡†ói†ïdyòusùqùœvø•~õ|{îukë‚\í~_ïhmñgoôyi÷‚høwu÷nŠøx•ù‘÷•ôŒlò‚kò~}íw‚çtoìx]ó{eð€‚삚îz–òuyótiôxlõ‡v÷ˆö~“òn„òtpö‚múuù˜}ô†îhsìfgôxfùŽköœpóuñ`tòep÷|pû‘uø™ó„„ðnsñsaô†_ñ“jë‡vìj{ð`öx~ùùŸ€÷Ž|õcõ]†øuŠúŽŠ÷žŒôŽƒñkoïicò„aòŠcôrk÷ev÷v{øyúú|Œøw’÷}Šô€vñ…bóŽ_òˆeðmhðcgôvdöŽfó›pí‰{êf|î]zôozö…zù˜|÷™‚òv…î_…ôr‚ùŠú›ùž{ôqë_sîc{ø|}û˜{ù¡{÷}€ó[†ôf†ù‚„ú—†÷“Šñs„ífvótoûŠpú˜sô‰xîe|íb~õw€ùŒùŸù}ôdða…öv‰ûŠ÷žŒôŽƒñkoïicò„aòŠcôrk÷ev÷v{øyúú|Œøw’÷}Šô€vñ…bóŽ_òˆeðmhðcgôvdöŽfó›pí‰{êf|î]zôozö…zù˜|÷™‚òv…î_…ôr‚ùŠú›ùž{ôqë_sîc{ø|}û˜{ù¡{÷}€ó[†ôf†ù‚„ú™„ù–‡öu‚ñdwórqù‹p÷œrñwñc~ò]’ñv•öŒ–÷—ŠõŠtñjpïc‡óvšôžï’šêy‹è_|ígxõyøzù‚€ùlŽöw’ö’Žù–‰ø‚ôstòpoôumön÷“pôpôosôfx÷|yù“yøœróŠcìkcë^zònŒ÷‡ø˜ö“ƒñurïbyór‰öŠ’õ”õŽ{ðwhêfpïj‡÷~’ù—Žù„õ}€îa‰íi•ôƒšø™˜ø‘óp…îc‚ôn‡ù‡ˆøž†÷’ƒôl†ðcôv˜öŠ—÷—ŠöŠtïnpëi„óx˜öŒžð’šêy‹è_|ígxõyøzù‚€ùlŽöw’ö’Žù–‰ø‚ôstòpoôumön÷“pôpôosôfx÷|yù“yøœróŠcìkcë^zònŒ÷‡ø˜ö“ƒñurïbyór‰öŠ’õ”õŽ{ðwhêfpïj‡÷~’ù—Žù„õ}€îa‰íi•ôƒšøš—ø“õqƒðbƒômˆùˆ‰ø¡†ö—ƒõn‚ók‰ñy˜ô}œô~„ò|gïxbízvóŠó†íqrèczîi‹÷z“ù‘’÷‘ôt’óz“ôŠ”õ€òrvðpgôsiùwuúƒø–‡÷—‡ötŒójö€úŒŒúˆ{ùƒcõað|uð{ó†Ÿòˆ˜ò{|ópfòqió|ó‡Žò|ïsuîudðykô}‚õ–õˆôŒvñeëvoëw‹ñ}óŠ’ñ‰xîtmíh}òp•ó†›ð™ñvôynótƒóz›ö}œöƒò|gì|aìrð„‰ôŠó†íqrèczîi‹÷z“ù‘’÷‘ôt’óz“ôŠ”õ€òrvðpgôsiùwuúƒø–‡÷—‡ötŒójö€úŒŒúˆ{ùƒcõað|uð{ó†Ÿòˆ˜ò{|ópfòqió|ó‡Žò|ïsuîudðykô}‚õ–õˆôŒvñeëvoëw‹ñ}óŠ’ðŠxìulìi|ôp“÷†šóšŒñ•uòfò‰mô„òi‰ð`{ôplø„j÷•nõ’nöh÷x`õ{]óznôtõy¥õŒ£ð‹ìwxî~rñ{îh€ìdyñrvøyúƒ…ø…–õ”œò””ðwðl™ñy¤óyœôq…÷ztùŒrø—xõ”‡ïƒ’ën‡îduõmm÷„kø–q÷†€ñg‚îfwô|púrû–{÷†…ôp~òrmó…`ó•dòŒwñrƒïkwíudñ{_ó}oòŠñ}”ñyñ|gô†^ô‘jò†€ôiˆôbzópmöˆiø›k÷”möhöx`õ{]óznôtõy¥õŒ£ð‹ìwxî~rñ{îh€ìdyñrvøyúƒ…ø…–õ”œò””ðwðl™ñy¤óyœôq…÷ztùŒrø—xõ”‡ïƒ’ën‡îduõmm÷„kø–q÷†€ñg‚îfwô|púrû–{÷†…ôp~òrmó…`ó•dòŒwñrƒïkxëteì{_ñnö€‡÷|’õy€ñgð\ñ”löŽjóipï\{õoû‡€ü˜}útôriòrg÷‡hú’o÷‰€ñ€ð|îqwìodò`õ…gïqtîf„õqŽú†ö‘–òñŠ•ì…}êynìv}ëu•êgšía”ôsŒùˆú‡ö—|î{lé`kî`wör~ù}ù ~ùЇôcŠñdˆø†ü•ˆùšˆõ€òczôeyøƒvù£sö›wôpwñ_pômlù€mú‘s÷Ž|ón€ò^xönq÷ˆnólò’kòkoð_yöpûŠü{úsõqjórg÷‡hú’o÷‰€ñ€ð|îqwìodò`õ…gïqtîf„õqŽú†ö‘–òñŠ•ì…}êynìv}ëu•êgšía”ôsŒùˆú‡ö—|î{lé`kî`wör~ù}ù ~ùЇôcŠñdˆø†ü•ˆùšˆõ€òczôeyøƒvù£sö›wôpwñ^qókm÷€mù”qùzõl€ò]xõrpönòŠuõŒfô}eòm~ós”ô‡™õ—öwñd†ðr÷Œ}û˜yø•kñˆbîsfñ`lõepù~pú’q÷zõvöp™ö…™ò•“ð‰ˆðvtïvað[ïaïŒlíj}í]Žòr–öŒ—öôuïv\ñp`ôpxõxö‰”õœõˆòkˆðc•öxù˜ôŒíw~íbõdû|ù Šõ…òqñ]€÷o€û…û›„ø”‡ïi‡í\„÷n…û„ƒö“yôgò}eñn}ôr”ôˆ™ô–öuòb†ðr÷Œ}û˜yø•kñˆbîsfñ`lõepù~pú’q÷zõvöp™ö…™ò•“ð‰ˆðvtïvað[ïaïŒlíj}í]Žòr–öŒ—öôuïv\ñp`ôpxõxö‰”õœõˆòkˆðc•öxù˜ôŒíw~íbõdû|ù Šõ…òqñ]€øn€ý…üƒ÷—†íiˆëY†õs„ú‚÷zvô†m÷kø…õzꆖïlŽñ^‘ñq•÷†’ù‰‚ù‡i÷‡\ô{dôguøg…û{Šú–ˆùœ‰÷‚‰ñoˆï~ðŒrñxjòdgõnhöƒkõœiõœbówbïgoñ}~ó‰‡ôt†ógvóviù…kù‰yõ‚’óšñŽ…ï‹lïyjðn‚ór“ó€†ð„pî{hðqyôo”ø{Ÿö“”ò’ípxì^†òm•÷‡™÷›—ó‘êl‰èbóo•ø{Žõ‚}ô‰n÷Žl÷ƒ‚óx탢ꅖïið]’ñq•÷†’ù‰‚ù‡i÷‡\ô{dôguøg…û{Šú–ˆùœ‰÷‚‰ñoˆï~ðŒrñxjòdgõnhöƒkõœiõœbówbïgoñ}~ó‰‡ôt†ógvóviù…kù‰yõ‚’óšñŽ…ï‹lïyjðn‚ór“ó€†ð„pî{hðqyôo”ø{Ÿö“”ò’ípxì_…óo”÷‡™ö›—ñ“èkŠç_‘òs•ø‰ömô‚€ù}úš…õ|ír†èzrìtlïq~òy–õwœóm‹ôrzö„vôxò‚÷u“ú}ø”šö•òsídpðxgöˆböygóevónö€‚÷‘€øtõufñsdôŒhöŽmõkxó]÷süŽûœ„öðs‡ítpïƒ^õ]÷‰iõsrðmmðvfõ‚föŽpô‰…ó{ó{~ògð}aîwuñw”òŸïŒï‹rî{hën~ïk“ónòvƒõˆ~øž}ù›…õ~Žíu…ç{qëtlïq~òy–õwœóm‹ôrzö„vôxò‚÷u“ú}ø”šö•òsídpðxgöˆböygóevónö€‚÷‘€øtõufñsdôŒhöŽmõkxó]÷süŽûœ„öðs‡ítpïƒ^õ]÷‰iõsrðmmðvfõ‚föŽpô‰…ó{ó{~ògð}aîwuðw•ëìŠsìxiël~ðp‘õx‘ôg—ô–÷¢’õžïpéakíu_ó†^ñ“iòŠ€ðk“ï_“òmó†óœŠô”‰õzõ|ð‘Šë‡€é_xì\söxpûŽqøwôy†óu“ö™øƒ˜øzˆõowõwrùqû˜q÷{òd“ôq•øŒùž…ö~ñexï`rõyqú•où™o÷wqõbuömz÷…{ô{ô•~óozïfnówe÷‹cöœkô’|îtƒéoqî€\óXñˆgòp€õd’÷o–ø‡•õ£“óŸòr}ëdjëv_ð†^ò“ióŠ€ðk“ï_“òmó†óœŠô”‰õzõ|ð‘Šë‡€é_xì\söxpûŽqøwôy†óu“ö™øƒ˜øzˆõowõwrùqû˜q÷{òd“ôq•øŒùž…ö~ñexï`rõyqú•où™o÷wqõbuömz÷…{ô{ô•~óozïfnówe÷‹cöškôŽ~ïtƒéqpî€\ó‹Yð‡gñtõg”÷d•÷ƒ‘õ ð’„écxç\pñtoùp÷¤pô–xíi‚ì`‡ôu÷Œ’ö˜’õƒˆñjtñwjî’dé‰fécwð\ˆùtŠúˆö™Šö†ôw’õ€“ø€‘ön‹òiˆôwŠø‹Š÷›„ôŒ‚ìn‹ìmò„€õ”róˆlðfvò_…øpùŒŒ÷•‰øx‹÷bøn‘÷ˆô¡ŽõŠòbí\|ós|úyø¨xôœuîiqë[móskõlñšnóƒ{ôb‘õf—ø„“ôî†ê_zéYrñprøˆr÷¢pô–xíi‚ì`‡ôu÷Œ’ö˜’õƒˆñjtñwjî’dé‰fécwð\ˆùtŠúˆö™Šö†ôw’õ€“ø€‘ön‹òiˆôwŠø‹Š÷›„ôŒ‚ìn‹ìmò„€õ”róˆlðfvò_…øpùŒŒ÷•‰øx‹÷bøn‘÷ˆô¡ŽõŠòbí\|ós|úyø¥yõ–xðhrí^kôtköŒmñœmò†{ôb•óbrù‚nô›jíŒjécvì[…óp‰ø‰‡ù¡†õ”ëiréckõ}rù”{ôŽƒðh~î[pórg÷cö”gôy}ód•õqœö™ö–•ó|ˆîlvïjö‡iõrzïk“ñwœò†“ð‘îŽjërhîeqöxoøŽjôŽmñ{{ônör˜õ‡“ö’‹ó~îl–òt™÷Š“÷ˆöŠ€ñc„ì_òtø‰ˆøö‘uñdvñY~øp‚úŠƒöŸ„ò“‚îk{íeuõ‚o÷—lï‡lè`yêY†õl‹ú…‰ø ‡ô”ëiréckõ}rù”{ôŽƒðh~î[pórg÷cö”gôy}ód•õqœö™ö–•ó|ˆîlvïjö‡iõrzïk“ñwœò†“ð‘îŽjërhîeqöxoøŽjôŽmñ{{ônör˜õ‡“ö’‹ó~îl–òt™÷Š“÷ˆöŠ€ñc„ì_òtø‰ˆø™õŠyïevï_|øoƒú‡…÷¢‚õ—óiîdeùzhõ’hò‘kòs{ðb‘ðo˜õŠ—ø˜–ôƒ‰ìeríif÷…hùŸlô‘sñe{ñ]~öqûŒ|ü|úóp†ísŠð‹Šõ‡…ðixêfhî~_ö`öˆpòw‹ðs’ñxònóˆaõxc÷brûnzü…|ù–ø‘‚öwˆñp†ð„zó“oïŒpçw}êpƒò~yôŽkôdðxrìj‹ñn‘õ~„÷’r÷‘hôtvõeùs—ú”øŸóƒîmnïjeö€fù’fõ‘kïu{íeŽòq—÷Š—÷˜—óƒ‰ìeríif÷…hùŸlô‘sñe{ñ]~öqûŒ|ü|úóp†ísŠð‹Šõ‡…ðixêfhî~_ö`öˆpòw‹ðs’ñxònóˆaõxc÷brûnzü…|ù–ø‘‚öwˆñp†ð„zó“oïŒpçw}êpƒò~yôŽkôdðxrìj‹ñn‘õ~„÷s÷jótvõhŒùr—û‹•ù ô”ðnpïgwøx|÷~øœ}÷†|ñlìt…ðˆó‹ðm‡ï]~ôl{ú†{ø¡zò˜}ñm„ôbŒ÷r”÷‹•øœøŠ~ðrjéxeïŠgô}kñasðhuôuø’uøpö…qðgtñdt÷rtú†sú…xùo‡÷m“ø—÷——÷’‘òkêdsî|kö‘hõ—fï}iëfkîpfô„dõ–cò’kñk~óZ„õn{öŠp÷›löwötŒôs“ñŠŒð–ïvî`wóhxù}zù‘}øœ|öˆ{ðp}ìvƒðˆôŒñm‡ï]~ôl{ú†{ø¡zò˜}ñm„ôbŒ÷r”÷‹•øœøŠ~ðrjéxeïŠgô}kñasðhuôuø’uøpö…qðgtñdt÷rtú†sú…xùo‡÷m“ø—÷——÷’‘òkêdsî|kö‘hõ—fï}iëfkîpfô„dõ–cò’kñk~óZ„õn{ö‹oøœjøŽw÷sŒõu‘ò‰Œð“‚î‚xícwñd’õx”õ“”ö›‹õƒvñoeñzeô”hó“mïn|ñ\Žõi–÷€—ó”똋ìq€òdƒôwñ–ðŒ“ðoëikî{eõŒgöƒnôe€õjŠù€‰ûŽƒûšnøŠ_òlhñe|õs‰ø‰Œö’‹ô„òy‘ò‡“ôš”ò†“ì[‡ê^zõwyû‹|ù—yõ‚tñgròmt÷‚xöœyôšzólòV…ôj…÷„ƒ÷›ƒô™‚óz{ðqqì‚kíŽeï}iñ_€õc‘ø{”ö‘•ö˜Œöwðnfíxfò’iô’mðn|ñ\Žõi–÷€—ó”똋ìq€òdƒôwñ–ðŒ“ðoëikî{eõŒgöƒnôe€õjŠù€‰ûŽƒûšnøŠ_òlhñe|õs‰ø‰Œö’‹ô„òy‘ò‡“ôš”ò†“ì[‡ê^zõwyû‹|ù—yõ‚tñgròmt÷‚xöœyôšzólòV…ôj…÷†ƒö‚ó™‚òy{ðqpî€kíŠhïkòf|õe˜îyší›ï…ðkyñjiö~fû“høŸjô‡vñdŠðg–ñƒ—ð—“퇄ìinðlhô…oñ—vî‚ë_‚ëc~õy~úŽ€÷’‚óy‹õn˜øu™÷|ˆø†qù‹g÷‚qôwˆôzô‰£óŽ—òƒð~oñnòœqïzéWˆë\öt’û‹”÷—ð~ˆîe‡ón‹ø…÷Žóš†ðt}ï_ƒòl‘õ„˜ô—–ð†ðmrðhhò{iõjõoôz‚ón•ò{›î‹œï‚‘ðg{ïgkô{hù‘jùžjõ‡vñdŠðg–ñƒ—ð—“퇄ìinðlhô…oñ—vî‚ë_‚ëc~õy~úŽ€÷’‚óy‹õn˜øu™÷|ˆø†qù‹g÷‚qôwˆôzô‰£óŽ—òƒð~oñnòœqïzéWˆë\öt’û‹”÷—ð~ˆîe‡ón‹ø…÷Žóš†ðt}ï_ƒòl‘õ„˜ô—–ïmrðhhóxiõŠkõ”qõˆ}ôeyè}yì‹yðu{ð\€ñg€ö€~ø’‚ö¢€ñ“uíjmíkpòrôrôppñdkñwgöŽi÷Ÿmò‹vîd‡ñc’ù{“úö™‚ñ{ïwˆïb•ìeŒïu€öˆ}ø“ƒ÷‰Žô€—ïtŒñmròycó‹eñ™fîŠhéfvçdˆðz•øšö‘îtêd€ðqŽõ‡˜ö““ô‹zðudòjkõu„ôƒ•ó‰ðyvîclðgtöz}úúžöŽîw{ë€yíŒzït}ïY‚ðdõ~€ø‘ƒö¢ñ“uíjmíkpòrôrôppñdkñwgöŽi÷Ÿmò‹vîd‡ñc’ù{“úö™‚ñ{ïwˆïb•ìeŒïu€öˆ}ø“ƒ÷‰Žô€—ïtŒñmròycó‹eñ™fîŠhéfvçdˆðz•øšö‘îtêd€ðqŽõ‡˜ö““ô‹zðudòjkõu„ô‚–ò‡Žðzvîekðeuöu~úŽ€ú¢€õ¡í]cí}_ò‘_ôkñc†ói—õ€™ô’œñ•–ì}|ëffñta÷“aøgöjsóf|ñzó‰‚÷šƒõ“|ïp|ðgŠöv’÷‚†õpò—aíˆiìhê_”ìo˜öˆ•ùš‘ö‘ƒð€pëwiîdoóas÷uuù‡yö“xó‹lïw`í|eñŠvô‡ƒñvzílhïueó†vñŒ…ñ{‚ômoõqb÷búm÷„zònvðjjðpiôuxøƒ‰ø—“÷™õ~|ïmgî€^ô“^õkòa†òg˜ôšô’œò•—í}|ëffñta÷“aøgöjsóf|ñzó‰‚÷šƒõ“|ïp|ðgŠöv’÷‚†õpò—aíˆiìhê_”ìo˜öˆ•ùš‘ö‘ƒð€pëwiîdoóas÷uuù‡yö“xó‹lïw`í|eñŠvô‡ƒñvzílhïueó†vñŒ…ñ{‚ômoõqb÷búm÷„zòmwðjjðpiôuwø‰ø”“÷›ôƒî[n÷xl÷˜jõ˜qò{ƒòo’ó~–ó‘—ò„’ïaƒð`x÷ytùuø’{ôx‡ñh”òu™ó…šö’õtì|`êqhñhxôkxö{mö’fô›gó„wïkítœó‰œô‰’ï}tí|[ðVóseõi}ùs‹ú†ø‰ö}vöyc÷Š`ö”iñpîhnòof÷ˆdø›kô“sñnwó`vöqvø‹súžqù‡wóaxñevô|vùˆ}ù“Œó˜—î„ðf{õaoø{jù˜g÷—pôy„óm“ó}–ô‘—ó„‘ðaƒð`x÷ytùuø’{ôx‡ñh”òu™ó…šö’õtì|`êqhñhxôkxö{mö’fô›gó„wïkítœó‰œô‰’ï}tí|[ðVóseõi}ùs‹ú†ø‰ö}vöyc÷Š`ö”iñpîhnòof÷ˆdø›kô“sñnwó`vöqvø‹súžqù‡wóayðevô}uù‰|ù‘Œó•˜í†‘ïp~ôaúw„÷—ƒó¢òˆ{ïrqí}mñmó~rî[‚ð_‹÷yŒùŽŽ÷šŽò‹ŠïsŒóx“ô‡•õƒ‡óxmë{^ë~aónnögzöt€ø‹€ú {ø•sñypí~xìlídròxiö‰jöŠrõ{ˆôuó‚Ÿó‚’ôoøtwü‰wú”yô‚|ôj}øq|û‡|úœ}ù”zõoxñd}ôt†÷‹ŠúžŠù†ñaðgŒø€‹ú“Žô›ŒîŽ€ëqtì^vôe~ú{ƒ÷˜‚ñ¢€ò‡{ñrpñ~mômó~rî[‚ð_‹÷yŒùŽŽ÷šŽò‹ŠïsŒóx“ô‡•õƒ‡óxmë{^ë~aónnögzöt€ø‹€ú {ø•sñypí~xìlídròxiö‰jöŠrõ{ˆôuó‚Ÿó‚’ôoøtwü‰wú”yô‚|ôj}øq|û‡|úœ}ù”zõoxñd}ôt†÷‹ŠúžŠù…ñ`ïi‹÷ƒŠú“õ™îŽêutëauñl‹ô{—ò‘žð“”ðxzíocï‚]õ–]ödîn~ée”ïyŸõŒ£ô‘—î…xíyeò‚jô‡ròouñcuòtuóŠs÷‡yùt‹÷u˜õ‹—ö–Šô‡pï}\ñˆ\òƒgðgrób|ùu€ù‰‚ö˜ƒôމò{ñ|Šïu„îhˆórøŠŽù˜‹ø„ˆõj‰ôn‘ö€—÷”’÷€óoqðlsó|ƒôŽ’õ™–ó‘ìcím‘õ„›õðŒ‡ïgñs^ðlnïr…ò€—ñ“î””ïxzíocð‚]÷–]÷dïn~ée”ïyŸõŒ£ô‘—î…xíyeò‚jô‡ròouñcuòtuóŠs÷‡yùt‹÷u˜õ‹—ö–Šô‡pï}\ñˆ\òƒgðgrób|ùu€ù‰‚ö˜ƒôމò{ñ|Šïu„îhˆórøŠŽù˜‹ø„ˆõj‰ôn‘ö€—÷”’÷€óoqðlsó|ƒôŽ’õ™–ó€‘ëcìnô‡™öœñ‹‡ïhñw^ðshì~ˆî„˜ïŠœï~îeyïhröqù˜qø pñˆsèu}逌ð†—ït‹ëknït_öˆaöŒfóouóaˆör÷ŽŠ÷”Šø’õ|œð„Ÿíx‘íjxðyhõŒg÷möy{õh‘ösœôŠò™–óŒówlôybñyhìqítšð„ñŠôxñrwîy‹ð‚Ÿñ‚—ñt}òlnõ{möŒvô•„ð‚ìzoêmiíyy퇎ë}“íl~ñoh÷|e÷†mðˆ‚튘îœïŒífyìhrò€qù™pú¡pòˆsèu}逌ð†—ït‹ëknït_öˆaöŒfóouóaˆör÷ŽŠ÷”Šø’õ|œð„Ÿíx‘íjxðyhõŒg÷möy{õh‘ösœôŠò™–óŒówlôybñyhìqítšð„ñŠôxñrwîy‹ð‚Ÿñ‚—ñt}òlnõ{möŒvô•„ð‚ì{oêniìzyì‰ë€‘îm}òni÷€e÷“gò•…톆îyxîqiðhmôiùy‰ú‰÷—ó†jï€]ïañƒlðavî^vôsvù‹vø™tø†õo–òuŸô‰™÷މ÷ˆzò‰zíz‡êZëW‡òv÷}÷œõ†ór‘ðv™ìœë‰•ðr}òjgöxb÷ˆfóŒvð~Žïrïsyòxgô„eó”ròŒ‚ðn„ï[óh~÷…zù™{ø”}ò}oís]ò|[ôŒfîrçn{ê[}óhzú€yú–zö›ò‹…ð{yîsiíhnðh÷y‰ú‘ˆ÷—ó†jï€]ïañƒlðavî^vôsvù‹vø™tø†õo–òuŸô‰™÷މ÷ˆzò‰zíz‡êZëW‡òv÷}÷œõ†ór‘ðv™ìœë‰•ðr}òjgöxb÷ˆfóŒvð~Žïrïsyòxgô„eó”ròŒ‚ðn„ï[óh~÷…zù™{ø”}ò}oís]ñ}[ôfíqçqzêZ}ôhzù„yùžxù”Œïyxìkdðq^özf÷{ø~˜ø†œõ‡ôwló‚^ö”]øŠfôgyïa‰òvŽ÷‹÷›†ù”ô|…ëvëxŠñxtô„aô”]òƒkí[ƒíX–ðu™ô–÷¡’ô–€ñymñ}lï‹uìx{ì^|ób{ùx|ú“zö¢zõ‡€ò`}ò_uöuqùŽpø¢m÷’iñkjð]|õlŒö‡øù‹ôjzòhnønû•pö—sïx~í]õg‘ú‚ûšŽù™Šôyyðjeòs]óygôw€ù}™ø‡œò€ˆòwló‚^ö”]øŠfôgyïa‰òvŽ÷‹÷›†ù”ô|…ëvëxŠñxtô„aô”]òƒkí[ƒíX–ðu™ô–÷¡’ô–€ñymñ}lï‹uìx{ì^|ób{ùx|ú“zö¢zõ‡€ò`}ò_uöuqùŽpø¢m÷’iñkjð]|õlŒö‡øù‹ôjzòhn÷nù”qõ˜sï{|î]Œõe’ú„ú¡û~†öfxñcqõrsú†s÷’}ôŒòw•ñcˆókzô‚t÷–uú˜yø~ƒïi•îs¢ôƒŸõ‰‹ö„pñcìxgìioïinõ|iú•h÷›jðzwëh‹êz—óˆ–ïzwít^ò€\õ‹cðznì`ƒðg÷ù™Œö¡„òƒyï^vñ`€÷y†ú„ú˜zù‡hõx`ôvo÷y‰ö†–õ˜ò‰‡îc…ðbˆö{‰ø’‰ùŸ‰öŠˆñcŒðdõ€‹ù•‹øˆ‡òezðcp÷woú†sùŽ}úŒôx•îdˆñkzô‚t÷–uú˜yø~ƒïi•îs¢ôƒŸõ‰‹ö„pñcìxgìioïinõ|iú•h÷›jðzwëh‹êz—óˆ–ïzwít^ò€\õ‹cðznì`ƒðg÷ù™Œö¡„òƒyï^vñ`€÷y†ú„ú˜zù‡hõx`ôvo÷y‰ö†–õ˜ò‰‡îc…ðbˆõ{‰÷‘Š÷ž‰ö‹‡ñdŠï`Žô€Œø ‰úyrù`ô`ˆöu‰úŒ†ø›€ñuìoríZñd‹ô€ô—Šõ¡€övñsîq”ðs”ñq}ôviõ…_óƒaõkq÷i~ú}ú”‚ö¤uó‘dï{dé‡pë…ƒìg‡é\xínmô„n÷“põŽxïs‰êm—ì~šð‹“òŠî{hëoiînõx–ù‚˜ù~‡÷yr÷ƒhømú‰|÷€„ñ…uê€iélwîiò}•ô’öˆôˆzìdnçemï~o÷pøƒsôa€ô`ˆùz†ýŽ„ü˜øtðqqë[~ðd‹ô€ô—Šõ¡€övñsîq”ðs”ñq}ôviõ…_óƒaõkq÷i~ú}ú”‚ö¤uó‘dï{dé‡pë…ƒìg‡é\xínmô„n÷“põŽxïs‰êm—ì~šð‹“òŠî{hëoiînõx–ù‚˜ù~‡÷yr÷ƒhømú‰|÷€„ñ…uê€iélwîjñ}•ò’ôœ‰ó‹xìençanî~oõ™pù‹sñm†íd—ñx™÷‰“öˆðiî}^òupòró{ óˆ˜ï|î‰aï‰]ïlìgxêdvówsùŒu÷Žz÷wˆùp•úšõ‘—ð’€ô…c÷‚Zô”_ñiífzêY„ñm„÷ƒƒøš„ù¡€ö†{íq}étƒësîroñzdñ„eóˆwõ’ôoœóeópƒõ„~ø“úŽ}÷vsðsfð„^ó†góz|òz‚ôwô˜kñ~eì`gíhkõmù•nù‘r÷n…õf•õ˜ö‹”õ†‚ñ‚hï€^ñvpñró{ óˆ˜ï|î‰aï‰]ïlìgxêdvówsùŒu÷Žz÷wˆùp•úšõ‘—ð’€ô…c÷‚Zô”_ñiífzêY„ñm„÷ƒƒøš„ù¡€ö†{íq}étƒësîroñzdñ„eóˆwõ’ôoœóeópƒõ„~ø“úŽ}÷vsðsfð„^ó†gó{|ò{‚óŒyô—lñ‚cëagídlôlø˜nù—}ë~{ësƒízîxŽïo~ðxnõŠjø•oö„óx˜òjïpsïbð˜^ñ•eîoxë`‡ðsŒ÷‹Œø˜õ‰•ôwšò~žî€œìp‡ðkvø{rú—qöŸqð~zîc‰ñk“ô™õ”š÷–†ô~jðs^òwaóljóip÷ztøu÷›vöxòqzîc‚ðmó™ô‹›õŽôlzópqøŠoü“oø~rõroô…hõ•bõ‚hõexøl€û…‚úšƒö~ò{ñtð‚ìzêmïzmõiö–oõ„óx˜òjïpsïbð˜^ñ•eîoxë`‡ðsŒ÷‹Œø˜õ‰•ôwšò~žî€œìp‡ðkvø{rú—qöŸqð~zîc‰ñk“ô™õ”š÷–†ô~jðs^òwaóljóip÷ztøu÷›vöxòqzîc‚ðmó™ô‹›õŽôlzópqøŠoü“oørôroôƒiõ”cô„gôgx÷i‚û„‚úƒøƒ{òziñcòlïnyïf€ôuù†ƒøŸ~ô£vðwwíXzñdx÷zw÷‘yôœ{ò‚ƒðeîn›ò‹Ÿó™›ñ‹‹ðv|íxzëqí^„ñcŠô{Šø–‰õŸ„ñ†vðlrñs€ò‰ô‰•ós†îhmñtcù€dûyp÷oùz‹ùŒö”ƒö‰jõ|\ñxjñ{‡ó‡œð…Ÿìo“ídŠòr‰÷‡Š÷‰‰ôtƒôl{õ~xö’xøŒ{ús„ùsŽù„—ø‘—óŽƒî{kðbó‡iðpxïc€öu€ú‰‚õ ~ó£vðwwíXzñdx÷zw÷‘yôœ{ò‚ƒðeîn›ò‹Ÿó™›ñ‹‹ðv|íxzëqí^„ñcŠô{Šø–‰õŸ„ñ†vðlrñs€ò‰ô‰•ós†îhmñtcù€dûyp÷oùz‹ùŒö”ƒö‰jõ|\ñxjñ{‡ó‡œð…Ÿìo“ídŠòr‰÷‡Š÷‰‰ôtƒôl{ô{yõy÷Žzøt„÷pø…—ø™›öat÷qh÷„døŒhözxñi‘óqœ÷‚–÷”„ô™ið}`íbsòf‡ùvù‹‘õ›ŠóŒzðqwîxƒî‰î€Œîrrït_ò\ñ}cój~óišò~¢õ‘Ÿõ‹òwpòr`õeö™k÷‰vó_€ï\~ôt{úˆ{ûù~‘÷|›ö…™ö~‰öuo÷|cø‰jö“vò”ëzæhyêdŠðrò†£ò‡ ðo˜ñi“ö}‘ù‹ùŽö~{ó|†ô€šôyšðp€ñqkö„cùdõyxòe’öq›øƒ–ö”…ó™ið}`íbsòf‡ùvù‹‘õ›ŠóŒzðqwîxƒî‰î€Œîrrït_ò\ñ}cój~óišò~¢õ‘Ÿõ‹òwpòr`õeö™k÷‰vó_€ï\~ôt{úˆ{ûù~‘÷|›ö…™ö~‰öuo÷|cø‰jö“vò”ëzæhyêdŠðrò†£ò‡ ðp˜ñi“öy’øŽŒø’€õ~|ñyˆóšõ†¤òS~òn{ôˆzöš{ö’ƒðx“êpžív”ò|{ö„höŠbôƒrówó{¥ó‰¤òŠð~lðz^òŠdñŠkðioð`iôucø‡eø’jô‡|òx“ðšñ†—òpŠïduònnö†lø£gù”qôdˆï\–òs—õŠ•÷–“ø†ôzŒñ{…ól~õg{÷w|úŒ~ø™wóŽgî}Zîw^ñyxî}•í‡ñˆ’ïs‹ìl’ñw˜ø‚Œ÷„vòƒiñlóˆ~ðgŠî]ƒôn{ùˆzø{ò‘…êt•éožîw“ò|{ö„höŠbôƒrówó{¥ó‰¤òŠð~lðz^òŠdñŠkðioð`iôucø‡eø’jô‡|òx“ðšñ†—òpŠïduònnö†lø£gù”qôdˆï\–òs—õŠ•÷–“ø†ôzŒñ{…ól~õg{÷w|úŒ~ø™wóŽgî}Zîw^ñyxî}•í‡ñˆ’ïs‹ìl’òu™ø‚Œ÷ˆuñ…hïmò‰òpïX‰îk‘ñ Šöž|ó…sém{çaíg|õyxù‘vøœzõ‹‰ð€•ðz’ïkîjnózh÷‘i÷”góopñ^|õq~ø‡~÷œóœyñ‚pñiñ}lîeuí^ñm‡öˆ„ö¥€ö‚ñtˆêf‘ëwšîˆŸð‰–ò{{ñvgîxeòoo÷k„øw“÷‰”öŠ„ö{köz_øŠc÷•nïŠxëzuîyfî{dëxuìnƒôl÷vtõ…nöœlõ™pïn|í]‡ñnóˆ“ó ‹ó~íƒuåm{èbïh{öyxù‘vøœzõ‹‰ð€•ðz’ïkîjnózh÷‘i÷”góopñ^|õq~ø‡~÷œóœyñ‚pñiñ}lîeuí^ñm‡öˆ„ö¥€ö‚ñtˆêf‘ëwšîˆŸð‰–ò{{ñvgîxeòoo÷k„øw“÷‰”öŠ„ö{köz_øŠc÷•nïŠxëzuîyfî{cìwuím„ôn~öxsô‡löžkõ™rðq}ëmvñuŒîƒ—ôŠlõ‡[ïy`îduóa‹öu‘øŽùš†÷vòcñsdò`rôf|ùz€û‘€øœô}‹ðc™ðnšñ†—ó—ó{ñtcðyXò‡Xñxkìi‹ïrœöŠœõŸ–ñ—ƒì{jétfë„v쇅ìr‚îfoòreò}hô†où„†ø ò ðtôm|ù{wû’zù{ó‡sïjeño[õ…]ôˆgñtsôg~÷q„÷†„öõšvñ{lìptîy‹ð„–ñŠˆõˆmó†\ìz_îftôbŠ÷u‘øŽùš†÷vòcñsdò`rôf|ùz€û‘€øœô}‹ðc™ðnšñ†—ó—ó{ñtcðyXò‡Xñxkìi‹ïrœöŠœõŸ–ñ—ƒì{jétfë„v쇅ìr‚îfoòreò}hô†où„†ø ò ðtôm|ù{wû’zù{ó‡sïjeño[õ†]õ‡gòrsôh~öq„÷‡„ø ÷œwñ}nå}dõ†qó}ñnzôrmö„góiôxøp’øyö‹™ö…‰ôzlòXô~\õpqõlŠ÷z•ù““ø õ…Žïg‘ìpï‡ò…‰ñn|ðgpñ{kõ”h÷‘tïvˆìs“ò…”ôŒŒîzuèo_îzZôaójïhuñ\|öp÷„€ö™€ø™Šö„”ìq‹èb‚îg†õø•‘÷™‰òxîhpôsqûˆtú”u÷…~ôl‘ôq˜ó‡•ñô„wõwdñ€bòŒoó‚{ómxöpnõƒhñŒió‚xøp’ùyö‹™ö…‰ôzlòXô~\õpqõlŠ÷z•ù““ø õ…Žïg‘ìpï‡ò…‰ñn|ðgpñ{kõ”h÷‘tïvˆìs“ò…”ôŒŒîzuèo_îzZôaójïhuñ\|öp÷„€ö™€ø™Šö„”ìq‹èb‚îg†õø•‘÷™‰òxîhpôsqû‰sú”u÷ƒôk‘ôn™ô†–ô“Œöˆwô}eìzrõŽq÷võe}õiø‚ø—÷—~ö‚ò†ð€‡ðkïgtò}nöŽnõŠwôuŠóu’õŠö›{ó‚oídkíoiô‡hö€mòiwôl}öø–€úš}ötñrmñkñ|jîelîdoôyqù’pø•qót{ðaˆôt‹øŽŒø¡÷˜Žòwzéchèdjïq{ó†ö’“õŠ‚îsnëjpõuû…ŠøšŽó‘‘îp‘ðqŒñ€ˆïy‚óluøop÷ƒpõ–oö…s÷e{øgù€€ö–€ô—ô‚ò†ð€‡ðkïgtò}nöŽnõŠwôuŠóu’õŠö›{ó‚oídkíoiô‡hö€mòiwôl}öø–€úš}ötñrmñkñ|jîelîdoôyqù’pø•qót{ðaˆôt‹øŽŒø¡÷˜Žòwzéchèdjïq{ó†ö’“õŠ‚îsnëjpõuû‡‰ùšó‘îm“ðkò}‹ò{€õst÷{n÷~†÷“ˆö‰‹òkði•ö–û•’ù‘ò‚ië‚aïzhñ`xï`…ó}„ö•‚÷”ƒ÷z}öptômôdô~_ñddòlhø‡gùŒlõx~ós‘÷€™ù™÷Šõxoõpcöaö…cönr÷iú}†ù•‡ö„ò}ìd~ïtö’‚õ ˆò‰„ídrê_fñshøˆoùŽ}ø‚‚õpsðjhóqnøû’÷œšíŒèjwìmió{iósnóiyõp„õ‡‡õš†öŒˆõjŽôg•ø—ù”“÷‘‚ð‚jë‚aïzhñ`xï`…ó}„ö•‚÷”ƒ÷z}öptômôdô~_ñddòlhø‡gùŒlõx~ós‘÷€™ù™÷Šõxoõpcöaö…cönr÷iú}†ù•‡ö„ò}ìd~ïtö’‚õ ˆò‰„ídrê_fñshøˆoùŽ}ø‚‚õpsðjhóqnøûŽ‘÷™îŠçgyëglówkõvmõpwô{ƒô†›ó–šò‹ïq‡ðpö—÷‚•ôu€ñsjñ„aö‡g÷q|ôg•ôzóžôŠ–÷p~ökoõ|nöŒl÷ƒn÷hzökø…‚ù•ƒõŒ‰ðx”ñzó‚žîs‘êf~òqvú‰tû•tù‚€÷sŒù€“÷•˜ô“’óq|ñanôsnöŽpóŸoï„së\|î^~öz|û’|û’€úvöcx÷juú€w÷•~ö‡õ•†îuxéZlîif÷‚h÷„qóyƒóv—òŠóœ˜óñp…ònö~˜õ‚•óu€ñsiñ„aö‡g÷q|ôg•ôzóžôŠ–÷p~ökoõ|nöŒl÷ƒn÷hzökø…‚ù•ƒõŒ‰ðx”ñzó‚žîs‘êf~òqvú‰tû•tù‚€÷sŒù€“÷•˜ô“’óq|ñanôsnöŽpóŸoï„së\|î^~öz|û’|û’€úvöcx÷juú€w÷•~öž‡õ•†ïsyèYmífh÷€hù‡oõ}‚òy˜ð†—솑ïyyîreó}iøƒxòrîa€ók{ù‚zù•{ù‘‚÷|ôz˜ò†˜ðy’ðcˆóg„÷z…÷„ùЇùo’öm—õ…—ö˜’õ’ƒðzvî{uñ€xîjé_‹ïpŽøŒŠù™†ö‰óyò†òŽñò`~õauøuuúvù£rô‹tïaðaôy•ö•ö‘Œôv~óe{øn„ù‡‹ôž‰ñš~òƒhðj_ð[póh~÷‚€÷„ô‰õ…óˆ–ðŠŽðzwïqeó|jõƒyït€îdõlzú‚zù•{ù‘‚÷|ôz˜ò†˜ðy’ðcˆóg„÷z…÷„ùЇùo’öm—õ…—ö˜’õ’ƒðzvî{uñ€xîjé_‹ïpŽøŒŠù™†ö‰óyò†òŽñò`~õauøuuúvù£rô‹tïaðaôy•ö•ö‘Œôv~óe{øn„ù‡‹ôž‰ñš~ò‚hñh`ð\oòh~÷ƒù’‚öމô„‘ô†lðpoðciñp`õˆaø‘gô{vðcŠôk“ø€“ö—’õ‡õ†uòzkóiðuqêb†îg—÷|šù’—ø“÷r’öpõ‡ô†ñƒpïx_ó‚^÷Œaõ}qðjðmŸóžô‡ö|wõwjó†mò•qïwì_„íbŒòvŒùŒŒú›…öˆuòlpñqóƒ”ó‰˜ó„„ðvmïpmõxõ…•ò‰”ò~|òxcô{]øxnøtˆö}˜öŒ•ô“€ômö‡jóslñdgño`ô‡bô’gñ}tñe‰öl’ù€“ö—’õ‡õ†uòzkóiðuqêb†îg—÷|šù’—ø“÷r’öpõ‡ô†ñƒpïx_ó‚^÷Œaõ}qðjðmŸóžô‡ö|wõwjó†mò•qïwì_„íbŒòvŒùŒŒú›…öˆuòlpñqóƒ”ó‰˜ó„„ðvmïpmõxõ…•ò‰”ò~|òwcõz^ùynøv‡÷€–÷“ô“ónô†]õseôcröpvøŒuö uõ~ómók–ôƒ–ñ““ðˆ„ðthñt[÷‚^ö‰eíx{ìlõ{‘ø’‰õŠóksônk÷„jólîpjòriù‚nù–oö–sóz€îo‹ívŒïp‚òhu÷toùn÷¢jò’míj}éfìzœô†õ…‹ôymõxaö‰iõ’yñ}‚îjxðokõ€k÷vóЉðsògóps÷„qû”uú‰ö{Ÿòx”ï€sñ‡_øˆ]øwdõfpöqv÷Œuõ uô‘~ónŽôl–ôƒ–ñ““ðˆ„ðthñt[÷‚^ö‰eíx{ìlõ{‘ø’‰õŠóksônk÷„jólîpjòriù‚nù–oö–sóz€îo‹ívŒïp‚òhu÷toùn÷¢jò’míj}éfìzœô†õ…‹ôymõxaö‰iõ’yñ}‚îjxðokõ€k÷vóЉðsògóqsöƒrú’vùŽˆöœòx”îtï‹_öˆpøƒvöm†óoöŠŽö£ó˜ˆño}ñivò„uòŒuðquðcqöqpü‡qûžqõ–qòsrôsl÷‰eõ„còjdókgø€iõnñox÷kƒú}‡÷™„õ›zô|kîtdëzeìooìfóu…ù‘ùŸzö“kñ{cîxsî‚ð{—ïl…ðmqö}lú”n÷˜sïr|ëZñhùƒ~úœ}÷–ƒôp…ñ_„òj‰õ}ø˜‹öšŠïw‰í_ïitô|púpü‰v÷q…ôpŽöŠö£ó˜ˆño}ñivò„uòŒuðquðcqöqpü‡qûžqõ–qòsrôsl÷‰eõ„còjdókgø€iõnñox÷kƒú}‡÷™„õ›zô|kîtdëzeìooìfóu…ù‘ùŸzö“kñ{cîxsî‚ð{—ïl…ðmqö}lú”n÷˜sïr|ëZñhùƒ~úœ}÷–ƒôp…ñ_„òj‰ó}Žõ”Žõš‹ï{‡ì^îhvñ„oúˆŠóŠïu”ín–ó†“ö™ðˆ‚îenðhdó…d÷föqsó_„õp‰ø†ø¢„÷•|òppðmfõf÷‚kósrón|ø~ù‹÷…ør÷~—ô“•õ‡…õonôwaõ‡bó€qðnŒðrô†—ø‹ƒ÷‚kõ€`öŽdörðszì_~îk€ô‚û–„øš‚ðx€î_…ójŽ÷“ø™“ø–†ótuïdwôr‡ø‚—ö‘˜ó‚írií`iófzùw‡ûŒ‹øòx“îo–ô…“ö™ðˆƒîfmðhdó…d÷föqsó_„õp‰ø†ø¢„÷•|òppðmfõf÷‚kósrón|ø~ù‹÷…ør÷~—ô“•õ‡…õonôwaõ‡bó€qðnŒðrô†—ø‹ƒ÷‚kõ€`öŽdörðszì_~îk€ô‚û–„øš‚ðx€î_…ójŽ÷“ø™“ø–†ótuïdwôrˆö˜ôšò‚îwgí_jóe}÷~†û¢ëŽœêyŠël}ó€vöŽpïvnì_qðmrô‰qø—rú‡õl˜ðq îŠ™ð•ñ€†îeïjö{ú…ƒù€‡÷w‘ø~–úŽù÷~òˆˆðŒñnˆób÷zwûŽxû€÷‚‘ñt¡ïqœòo†õox÷{vú“uú—lözdògpñp„õ“ú“˜ø—ˆò|rñjqñxñ‹Žô“òìqhírföƒrú÷‡†órtòpaôvd÷wyø‘ô ï’œëz‰ëm}ó€wöpïunì_qðmrô‰qø—rú‡õl˜ðq îŠ™ð•ñ€†îeïjö{ú…ƒù€‡÷w‘ø~–úŽù÷~òˆˆðŒñnˆób÷zwûŽxû€÷‚‘ñt¡ïqœòo†õox÷{vú“uú—lözdògpñp„õ“ú“˜ø—ˆò|rñjqñxñ‹Žô“òìqhírföƒrùƒöƒ‰órtót_õue÷v|ø…Žõ—ì‹ìmtïihödùaõ|kòdónŠö†…ùûž÷ðp•ì~‹î‡zðxsïg‚ñk’ö}–ú‘úŽõ|—ñxœó€Šõ€rôló“oðŽuïg…ñ]÷wùŽùœŒ÷—„ï€|êk|ë`‚ïgŠö~ŒøŠõ‹yözfùxfø‚x÷‰‘õ‰šð}ñogõsfó‹mï™vñ€òbzîeqð{nõqù™t÷|yð^yñju÷„qúyõ”‹î“•섊ìmsïhh÷~eúaõ{kòdónŠö†…ùûž÷ðp•ì~‹î‡zðxsïg‚ñk’ö}–ú‘úŽõ|—ñxœó€Šõ€rôló“oðŽuïg…ñ]÷wùŽùœŒ÷—„ï€|êk|ë`‚ïgŠö~ŒøŠõ‹yözfùxfø‚x÷‰‘õ‰šð}ñogõsfó‹mï™vñ€òbzîeqð{nõ‘qø˜uöx{ñ]yònrø„qû{õŸ‡ì{kíngðalôgsø~tù•sö{ôo‰ögŽùz‡ú•{úžpö‚nîdpëmkñdö†eó}yït”ò{–÷Ž„ö’vïzêm…ëdîkwô|tø•rö—sôu|ñeŠòu—ñˆœðñ‹oï„Wî}Zðnuñl“ò€ ò†šðt‡ôpwùrù•vö™‚ð~†êa{ïeqøzqø’tõ›wô{~óX„òb„õ‚÷–…÷š…ôx‡íZŽìg÷‡…úšƒó™}î‡oîqfðbkôgsø|uù“söŽ{ônŠögŽùz‡ú•{úžpö‚nîdpëmkñdö†eó}yït”ò{–÷Ž„ö’vïzêm…ëdîkwô|tø•rö—sôu|ñeŠòu—ñˆœðñ‹oï„Wî}Zðnuñl“ò€ ò†šðt‡ôpwùrù•vö™‚ð~†êa{ïeqøzqø’tõ›wô{~óX„òb„õ‚ö—…õ˜†ótŠíZíl‹ø‡…úš„ò©~î{\ôxbóiwòj‹õ~ô–Žï—ˆðt„ôaùr{ú‰wø•qõ‚mðcnígqô}tù“tô—{ð{…ñl€õypõŒfðfîvtî]†ïeö}Œù”Šø™€õƒnîvlë~ëƒér„íknózcö‹dö‹sóŒñ˜ðv“ðdŽólõ…‹ô›ˆóž~ð~sí]|ñe‡ø}‹ø÷™ˆõƒ~ðf‚îiô~™÷“˜ô—Žñ|‡íd’îmŸô„ôŒñ„uóaõzaóiwòj‹õ|‘ô“ðs„ôaùr{ú‰wø•qõ‚mðcnígqô}tù“tô—{ð{…ñl€õypõŒfðfîvtî]†ïeö}Œù”Šø™€õƒnîvlë~ëƒér„íknózcö‹dö‹sóŒñ˜ðv“ðdŽólõ…‹ô›ˆóž~ð~sí]|ñe‡ø}‹ø÷™ˆõƒ~ðf‚îiô™ö”˜ò–Žðx‰îd’ïsõ„ôŠŽðxò†oúŠwñuŠínŸô€©ó“¥í‘ín€ña÷u„ø‡†õ’ˆöˆ…öo…ônŠøŽù™÷¢†ô}óczõjxõ{ð˜wò‹~õj•ôj£ø‚£ú“ öñ|qîfòjõˆqòc{ñ[öq…ø‰…ó‚ð›|ó‚qòfuðZ’ïm£ðŒ¡ô™ó™€î}jïa|òhšô¦õ‘¥õ˜Žó‹míunëq‘ï|­ñޤð“~îiïl€îr¨ì|®ìv’ñszø„qùŒvñvŠíl ô}ªó‘¦í’ílñ`‚÷u„ø‡†õ’ˆöˆ…öo…ônŠøŽù™÷¢†ô}óczõjxõ{ð˜wò‹~õj•ôj£ø‚£ú“ öñ|qîfòjõˆqòc{ñ[öq…ø‰…ó‚ð›|ó‚qòfuðZ’ïm£ðŒ¡ô™ó™€î}jïa|òhšô¦õ‘¥õ˜Žó‹míunëq‘ï}­ñ¤ï’î{jïlïv¦í|®íu’ñx{ø \ No newline at end of file diff --git a/src/samples/gu/spharm/Image2.raw b/src/samples/gu/spharm/Image2.raw new file mode 100644 index 0000000000000000000000000000000000000000..a794d237c9bc0592e14cc838033b0847fb9b39e1 GIT binary patch literal 196608 zcmb^4g|{6=);Ine5+KBgyPUYYySsacyC+16yAd}+gai^|1a}`8V1^l<;g5Ph-TU6+ z5S}%^wSMp0>*Swj(LK6%@7cU*p`@fu(yZXLx&EXJ#)sQ zsgs&lso3V(lIkVd(Y8&S%9Se3ojz^tie(EXjqB93QT_V$w{F__#-(!;Mh-u7^w7n_ zd-pD1@Y=Bhi-r$qT2gX!_s)NQ_vJ@-Z>^p_QRQ_@O6Csf_vF@V7Y^*|R_z5>I#qdo z*7&h|UU}up+0$o_9GpIFTK1Zfl4naw7S5izX~X)yef!20-;GO3Iyb6cxm?M(LH+Ms zJahKI?n-6%I&|ouC6y{wYSOszpn(IoY~FPJ$|bGZxnXV3jvdNMmHuC^PVMz;*F1Un z;9o!g{fDo=c;mGzYnLw@K4eJUI(42Z>1V?V5Zd-oB;htHogd&{~tuO2#Z<j94KK}|vw8ixom)0<+qgmDX%ojcuKT}qP@4}OJowWO-~awU|Nh|J zcNWfnsmgQ6UwS-KQlfYL`t~)-NB8fWJ7rRXN)_F%S+i#ILZMEbI+dP(e$3#3kKVZc z-n}=6_3u~qT&W%b2bnZBF>Xhfom#7$2lojBmZo9ABz?5%UBEgLnYTjgf~6}f);>QlThzEc~>SN`-XTMXi|38TDPPrEm$ zy?FM_1N-*A^75ut3+FeiUoV>4uWRQ+dv`Bgyr^Z17IDSn!`d_-(ZBDkDU)^l)r0#w zw<^8Wu|o#{z`sU((M$7?;`rf1C-&`LJAZDg7c0l(>077Xd-BeI{{8DefByT;Yp+e2 zII&av_LV9=p9;hY0uJlh9q)J%z#reg2jCS3ctk*I6a#oCevTbIYU7$!Fqz>z2Q8G| zIDgu+NA|pe3t$gB%$PcL;`nhRhYwSU4@7Bmm(HEj$4?)4_HkF4VMB+i9LPPZhE+=! zgT2OFIDW*ta7XY3s9+iG+_-v`!oZIUbObwSXYk{~mtNYj<>kGv?A*3#0~&T{h5Uay z6dpEY$XjpRA`|}h^_NEu>@PHIP+X!-n>Hw%G4;WHi>FR(P@&|-=PIB)E{J0D#*X~q z!^a=oyWO^l;r-Jweqg_^-hJ@f_g}t#^2pR)T?+Z=`}Wzhdg%|Jy!Z9H_jfLy*RMe> zSAsj7Ke%@B)UIuShuwTvDJj{%ZUy{I>)E*^KQ0_OaP`pcj#Zw+Tp(1tMh%$RvtwJ& z#`U8BW`V0Qqenkip*#UTwq1)(jT$s8SF*5c>r0C!`&MAb#&s=Pv_Os#%^NM4Jqw$! zTC$k%cQmM9pGfT5q#@QAKT7Y1FI}_n9K6O4RXquSWGqcyL`ZYsT2Vy`sTJ!9ZgiBMx0I z>bR1FyLHj9z1z3x=BQyqqj0-6t$}Cs=+RoWcl%bK4Qp1iA@d-9j8%R5%!Z>%)U1gNVU)n=2 z1V>;BO~NLsRhYg;2ZYsrEuj=p^5EV*7-8Ck@$CxD5|!eFK%g}~e)sYBUw(Gt@WED1 zn-mvN;jEc6Df;WDk7K05GbPn4KCh37o(I+~|MyoPy>{wYG5wC2B# zY}*I`g)(VBv0Deg_~+N3V&o(n-K8upAKv@+m9vAI)bkUxU}@jFm5QwxKSG_3E5{D_ z*{4m*Q-}6%SiZDDxsnBQX2E@cod$Cp4N3sN8&?J+_GS{M($d^P^;q8v3iwlYgegZe4ie!#6jA# zTXw#@8AvpMZuQ1`l`3{>)soop0U-#a=(P|m@%7OI`(8VH3SnnWo!q5m^B%Qd%y_2g zShj50ci(*d`+t7>=BqDX-n^O6F1neW0!FuXZI>@vpeovP<V8Gspy8_!R znFRO~`}YRgiD-q1K^O=?!m~=W76S1FSY~>m%$^Ao$akrxU<>6c!xfUP_!A|=Od{}^ zQiQ*n)sH^jiv{RD&5O6gb~FI&v4fYY4KJwSz|L)y7u}6?x{L_gjLU)%e2*SFW=;JLgXR z{P_nt@GJwJZ@;I|*YB`rs_Y62d?2%ruvF!RfoA79-6N}&uVP7ZBcts~57 z`0rbzQul^+_ibMP`NOw%Et>OOUa9h*z4L%9WtmJEGO&BKiVLSr9$SX1hLxUQx$vb? z9a`(apgL6#%pBLVeraz) zQ2dk;N0zTY{@~;LcUDgtUC5zMu=}tLh)VBbDzHpI#YNwoNAh#!h;zGgM8=YGC4c|!H7Rr~hr zfwstw2)Svob@GT|%6DkofZ0P7FIl{p>qIKDf1>?b4k|A0+PT9c@NjU)*7Es1z`lNT z@28L6zI5*FsyQ>%1CTHe`CQ#%Ww&zNaDCCdsMB|a3Kb?zn#6`#G-zx?va#~-g;xw7oeAOCl3 z)nf5Wb6LXr^3t3+>hwkrf;})WC&+f9BspEhLjmr3T?g|0R$U)Dr zlyWx8)Q8Hc5>Rmj+M_Bs_i?!BmNE`x_aMb*P}uMRq}25AZ6TZ<)GB-z>=|A_a0E95 z+v-KITht%C0Qr=NuAx7U074D+I!eK}GN{2EMH!(C{$ufhs@~0Pr5jWB8Ca4+rKwF?VJ3ynBGcjovpHL6y@2$RN*h1j+gN*cZJT)Wn- zg-7O1pE`TWB+4S%%t$~Sc7ku<&%EGSGvd~Sj;)_uzx3{#H)%|kyuN65*gU?2i(S;t z%lmfVh$hvzGNlLV@kzCI;@|;I>(&ufh#Tx8{hc|w)XW16fgq9)#qM1>H>_)?vIXj>mAPm!l@#EoHsQb3 z*x09G9U@d~v44~}xpl)ozW8AO_N`@4WG=17lWeb@IrZMH*A|Q&!4HAeF!Dih@#vx0 zZQZOXi3LWqZU#I;D1}^Qu%_*-f7*(fr86oTRIjEOnaLW5 ze?BJez+B4f#i~hT5L_s7K$njEZf#Qu{(Z{k;s1Vk`x<$kDBxt=sF8+SFo8u>zU+n* zwGr=ep?1w0D9PY?{leLg-@fx#lXCdbA++IxyKg;w@L<=jU0A!Urqch}IffX(^b0Z# zG5q-GK5Q^lv>)s_P=FCu5RQN-PcdxV3d{p@v5my)Rt(z3%J`BV#}~KGo$|SP`uMp6 zyAE&N#4QrU6aDDlzD<{=jWB+l=PJCIN9T0YN0_Ecxsn>sKZnRI8aCjKg2ceyy+#fm zBuYb`Xajk!eqjwC$`?4XCt2;)P_4f>0vCj`@a-o&>l$`o6+n>=hAxW^>bR%ybudDh zRp>x#gkS^`HLKy!p52(YXWLRe8w7=xE9XvA!2)p&Ui`zK@@gs@v_v&|m)#oH!v(#1 z^{SW$qZ(IymR0lFlLrPp>Y-vdjE-eYW#z9Ajiql>~!FX0`uT|Rj%PKkKF zHtVJqMx-~|$$le|sKUJB?2Dhyc4AVF>)aL}rGt_Jwkd=9#udo-@lvKf-T|Ie(g`pd zwR^X2yms~K;>C*@pT&2pJ@>4LH{^uCH=yha1;7KgVZ)1jNP7bv!1gXyH=ILD*f!*( zw-B%(;UGf6hCoIoX4tLsr$r~;I(z)m?yZ|3goAz3?d1mtTZc8CUGbB%Y43mm+VcX=NULInL)Sl=@_aA;pfkegR2EPX^J zhXQJ*x!8oPXz)%4E_m(Yc@~J+NcCp}GNm^?h->a$cy-OVVfCLaZ(In9xCd+>Jh;nc zz~-)~5JDVHYE~ER{OJChb0<&e*{E)>s?P&0fc2|a1DuFc#R~byb-^P3HGo0ROGEmB zmbspxy?VeTe%ZBRu?KPefwjvaoB>1r2Me%#hPG+pZr$g~qucE9W4gWg0%ukOx-@Ap zf6{o;CTmST&xOd4BO=tgeumHyLk5%8p;I(ZdtN`fPuqIds^;94Lhf8(hv30zuy6AV zS~a?JyR6>4%fhfo%~~tQD{*QxDb|n)z=mju%&Fll^G&jc%MR**-h6QL+R5X`1`ZrZ zcbDDC{x>UO)P%Fb!YA%xZU_=|5DYYutQIx|7#F=LgZ=7K*ed`7bUjUBC>ihyfDpa_ z0}sA-^2pIG8@OY=>(@k@|4+1sbrkvn8=7J1)3c{f&+gs$J3fLfx)8yc;*R{6^YSGn zoCNMP9YHUcF7bgnG{hRlPMlNkv|JaW9DzC-_wa21_Q=C) z7tASmFhMcuaYeLtWRI?W>(z8FhRMz8)}qUf4h2n$31qe1>m=>6mTFU^9jB*2OdCCZe6{QJ(*cVJ8ph z6YuhE(w2Qo(u&0TNhSauCFLR+YZ8iIkP34UjPHAQZeT{rn$9ggNJt2W{AB95O9le7 z;X@GeO}~ISatoW#%fg;6f+a!Fyj+HSHJG#- z+NoX5DwR$19oV~f?UF??SE||CykYTt9%!q|&zpKUxN|!}tAw}v!JXIFE|?oV zB>;i{?4E7(7b8D`KOA<=a2JDw>ck_g&8F4?+RVsjlMpQ269SFkQeIWUG7-2S)(Ctzfn^`bixnSCqmes2itN!S?aVOI-DYSDg%=ZGkwq1Jl1ZKguYZot=KW(z< z!tU+bv~AkBPL)b*7*<*BDwXS2e-YW)0KK|(9Wi9c$YH~v5#wy!u;G=RJ5L-x&V_&X z$&)WW|NQSi{)j1l{^_T0zxf7JoH})C!-fsiA`ubI_%Gj;o+-y=V+3LcjstCu7w82# zhzVxfqD?~11q z42{}cH$%F1>`=ZBr=Ypv$)kL{nD^d(lLHvNhzTZ)VBW#(yopZrgLl6gl>wMN!;k=V z7z-9)X}H4VRtEMki0K0paBQAyCyz)xST=strk7?d9@x`VZ)gFAirNY}FZ3=nHu2%r zbEZsIXB@maQv*N?joaoG@H=>X#p)?^ff)_;^sHJc zFL$qB1sLf;Cn$rM^c{DvP0bfgb-5VeC%7h$9n-d2C0%nEEQ(^kz(B#*$FXZjl zqdSd&gD8Dc&d9oMq|_W1ua`P!(-Q2yofCI-fx9ec!-`FOV#KkJ(1*9ft-*TgfO*(6 zPhmhs{3H%Z|Jby8C1E98@K+vr>hb^IKZU9=n)gyGQWQA*Z`^pD?FVv{6nlgA5xx2E z^;3>Wib}YZ_T>77jThZV2b75*SjY-`2gSlDLMx1b3s5Pz0O>MQ@YsPNEt(`Qz)cKh zazH?@m>OQeqIh`w#`!(l+E=ZJG3jwE;JWcTcjB15h-f@W#0gHkedBsK%c_DRQdES; zz!9xU%tD$gzz-*5+P5Tx*+MHOj~mjhvt%tw;ncS48i3F5{l1v;EU)aqduOI{e#4-7=?5ky!ir&b=FXXB!zNspTNt1A# zHfQBZN_M}z2~OfXzG*<>$bfQrIO)M8Xlq+<#T5Q5SGuJS}40g1QAW=P9CEW(?w3=o44O!3`{Fa z4OLvskeU{qW9>t};cyY%2qmMIkgr0A0x_VdM5-7y+Qe{p3U}Z^F9n8T+cjE*alD0; zQz1QjYTs^3;rY1t=kKS)FNA}iSt0g}xk8*pp|B;`2K0+?7L&^0Vx62^mFasW5ZvYLqHiW1#@(Y zc~To^WkySoC0KxIqyWKdu+~kRKsf8yz1Oe&{`YUe(k&_g7kFgz(4IF|%yd4qUiF#n zno=l~MFRiQS<^qd{aOfa`J&!CXWVFXkVKJ1g7U*0G*qmcJ|VTid$AsM<4Pg_P+NsY zjra~|Rr*-|A7Vbbdq>{R{IMgGZO^2aHH2LJ@lZg@qScq5e|GccO)yS1v@JAc@PIU% z*>zwhxC|ocge)QRBcMTpXBKRpV559gqP)B0dDz1&z^5SHv~eSo{xQpJMw=UA$~e6} zofzU!6e@%bjnOJPf|eH>r-k3We(~1v17~+`7Lmi|@+OI}LR5Kz+X=wH?X z>FRN64kKJReTrmYMffHFF$g9V_SB4qFD8PehCF@3sF2`oLXgR{f8RbVz=QbxKmYT$ z@4lrS!0hP<^5154vjErOgPK7(;(hQ2SIiZ@u%Ss@5SkRh2@ouxq(?*v#5|Wz7@3%q zP9g9qP3p4vrBW-IVaksgIyh(;ca00`J$~)nQwWZViloY3ML_yU*dBiYDO@+Kc zF&k?M039a{-o?;NCUj`4*?qgk+g)5RVvtJKOrM0yhIpOb_f zd^Y*u&K)pF9P8Gu6-hp}dxsgixPmOSIloT~q^wjnVFc%-4eAj)2Ab&Lrg2id-2jEP z1LsB!@^##Y)C~ne+p_;nsuBxo;4-J0ooGzg&YiS2QXgTDOI}$b@s1y{`CsxqEkW+le&6s?)#`X z{J!1CckkS`YMBI*PL2PRpR5wtfW1J-Q+49dqeqU2EJ+3Y{kJR$R{I4cpK6uIF{#W1 zF@I=BE-auKPN+`AOk9BeAzSDOEks)?!z0q*FYMpht3l~FY6iJ#a6w2~duo+x>1AL* zaC3j@I#G7<)stU7yfbscxZ<{n0g8B=*iF5wUA~+_|0@fGFA$FE;3jqD%UPI!HGca1 z!`-Ww@gr9B>cA~!`J9|J8W*sImX01OD4`9b`t{ZwcS#v7ab@M)nKw=!a{}s&dGKB{ zds=3yHOV}P&^}m?=1SmK%tSC!+`Ds|=1N`D9V{>FiJA^q*DV80M97_xq?c)${4g%E zcfSAbyYb`4mt8B7ypajXjT`9tz%!f^&WONY^E#v8x^V$`GGCX;{3vMzam4BsE698% zQ%t_3nw^+Xh~+TfeEB(H`&8YrwCGg5vgsRUIdKOA zT4mCc{KO_~iROiZ?zj~|B2tPaUU3`Z9F>a4-9_c`g2&lZatzo5j2vwsS4C6lTyy0j z=N2rG;ii&J?uZ+h*=boe!TQu&0Ma4|;Z{M{cOTy8Jy904SaC7>oryvTq9F;RUudXD zi3>!A(ZnqV8@@0Q%D{|K0BORO)=PR^ujw^J+p~FndW&wNmDnr=$J9^PwS<8B>hWD@ z5i(8Jom@PA`11Z8$p~Sh+`W1}EbwAOC?Z0v8gCrdywS9NJ*DE)7yMaJXZceBDq;Kt z{@c}jQTT#GC-fn!zrb#(lkx9{Me|LxIl&Gw!zCG&1IQ3k26=sRz;V|0#q)w46zf}P zjHC#gv>tQLAet`M9)eeeaUiKk7d1*#lwB)9A0Hwy3>#>N zd1Ha{xFD<`!$IPC+=zID)lJm!L7vKH$9+unAODsueIgRY2Gbkkge9+@hy>DEraYLM za>aEPO(gvqbZ9q@Y=E$1i)%2%(#Wv@MhN`tvZnG7%^Z=y90BYGFkr_2+PZ4FWjk^_ z1fP2~Zz3jUu@&*ip7FR!uobNO#tY=9{(2BfZ(hD2_lCQ7?#KasS7GL5tXm@&o#`d} zBFUEG=IJkI!D<&X5e9-2q~_uRl>Yj~3!o0{xdXbX{l0?>B5o{3gcpcS!@|b~1dTq;EQ!f@Y?sD^9FvfL?=z)P5Qx4pf->kZCwvNpXG(nzB}mb>sxQd6vu< z{VT2$^1X#6@Y}EdID6(y)LdM^xIigmiF#sj31zgZT?0chX2^4I^vF{o$M%gI$}k}! zZohiuy_;7E=Z_z~E#2K*r`bs-Pu{$x%gjrz!3Q_5_$X$8P{t(D`w#AMi#S2-e=h}K zAz#*rB(%Sx7iS?Xroez2bb4JJqDYcw0e#G0iviu(loh1Dh_c6{zBZ(J! z?UN^uWGpkWJdQr8B!e&b2F3 zU9K~(j2&rKtOv;i#v~)ZSo3BP@2eN@-@cVnhN4OPH?0#ylGqnY``{5IizKidq-=U`>*fUuOIdDz(&B%9C7Odr{pv63Y`0Dw z#Wul7e<4j|(y-DycP^dNYhq36h1DM>$|06D0ye2JYNf4$F}0J`%gIC&0%9nL4#RRDxGzjoQsr26EF zkc3z+U7^{3`tb*VBwNx&bRfD3F(7vlc|+_oI8haOiFe!)PA=ELpkol%jSg>-r|^{A zP(Uz{aV0Q_-_wiY1dwPzDYf@+zHZ3=x)Q`_ssW)`Yh)?&`){ATFF?d?x5R_S{4WPF zLKazq(XnY`gU*JbM2Zc(|MG0{t-8;Y4C~feio5JVNF#FbI3Afcc63AtqcEsQf-=io z{H$}tVQ-t{B7F2ze>o;kX)(pLRy>3Vr4AV9LI0>qFBllI{)lnlM-T@&&#Iw$MS;A6 zcjPNhU1HsEz)ny&@I7p)~36GNGo)HO~lh}vV7$BskdAS~jMzP{q zc$G+v2Kx^`_&``bS`yzX$0jIDz!GI<0E_PypBpj+r;Zsj7f+v*5Ln!=;*!PZ3>BaM z%Y#zmLh2wfB2rQ7xeC%|1P@V3dV@U~*cfK~b%A_dJ$t&T87#n|ZC;~V*V@$$21pkl zDl``ifu^ucL$I3Qwpd0*VOAfrhi!KFzyXRW)c^w!CEtLf0X!@*LqIwiBh2UuUkqas zO@)`=4Ghkbe%8uNlbf8+AONkhf|AsKg|RUB`; zdQ{vmDvT@JRxSg6s*pRTP94X3=k{y|elgENSqMlnB;R&Yo=V-LK`HN`j|WSu&i~`% zFh^4tTr;Qt`)~iccJ)falJRA^C}*JK3va`((`)mn=SS z*|5HVMm8a}bB9Sf{Ae^U9nYpdDPzIfkSE@O&bUV>%n=!W4m`M zMP5-`QQHKB?rVmU=xKBkm7?Il9^E(vkKej&rw(iq7vW8G5x~62#F^{Z6F!N3SHeId zg^UrY#Z3!EV2q^6acWW%dUorE4nKYWEn_cTRGV?J;=@yM(bTGx0C6F8GEn29^|LZ_ zsEpJqQB!P4XEB6=1@4?Z&U%4=rVB@2OvXe^rvA3A7W`rSkpGBAKI~q;fMiZ@^a|-) zV)eo%{aQDV+FTR>5yJ$2b%x}(;R!ix_}rCT=i5JYV7fR@2N)xAYO3qzK>z30U+AnP zAx-hH_5~`#5F$n*BZYAUkL#Y+b#g?}6$B!Qu*g-c*6w#9E z2CijO0`u18^Ky6?#>GZglu@TC31-`ukMF&I^YYROql+<*Rw$O*%yh>T20|PXwtxKi zT@#KrI`Cm2@pkReVT+q%TQ+Q8xpdWnd25y|vHDDSWeZPsZfBIbp3yvyh#C7Liy|nrW|Q6OMrK+dqFMx>I`$E`v%?ONDV!rrF4TeVKfW+jLR5k~c)M>3$Rw z#ezMN%n?1h5!dqbO+9RyH=|(OyLGvG_B1m|+oU&~UomIj_(A4>A$exsZkU3-ks83H zL@^pRB)`WUQh;EucwuI?p7;KnVX#FR3W5m@pUNAB>@lvvie)yrDh{*gveaLqBMSKD zd;zK+Fc3Bf&qLHWSg!~wJ% zB7rHyAtFGFM9uGHUo=9;#@V{j@G?Go`_{4Tn+s)g^cBmOmn%+&=v^EgTD4NoXYajZ zH-rED{agMosB^o7f>GO=An|9Bw?eLbQP_!(u)OSXYM1C>OMB^4M`EkE&L4+r!!7d9 z`tn9*;fiHT&FzXOu-*|NO+5e@MzB!2xK2ZWTvBK0V*E~^8EBCfV)L(-KRjEverW4P zOM55_BJFN<-Whk+OyV^s=8*8zJ zs8*VR8F}*&CMHtjpD+Imy(33DO#^kTQAK3l7~#|K1xQ-?6&a*AZ!&!u&x+b{;mJb_ z$`ILdcv94Gw5#-N#1aV~Z2tMZo3C$O#Sthl`!Adl-Ab>vOjr~SD|KyHm(8z$!?G{% zD+a$T3)$=zv}%SIIRvXU*hsN3^)$bhfuB?_7PG+r_iw+FW)KB@6Ws_xz8Mq`;&JcN zNU%pz?my!k>!G9qxWjc~3Pk^`cwArQ`An0Lw1%(h3xCWFb!pi`v`tpY=kMIlBAj<`%7FxU3)y7p z5IBIX!uZ5b-|6FSeBuh)nuxTm2lW~R^wR%+fGAnbBC?>5kU?s;A_;(EBF~U8Z}LQ$ z?KtjFM9C}FCB~sL0!m*$dP|-L*o4^+%!Vvp?G?O+6ECkta8PHEKh-2^T5!xDrkEbK zm6jtsMcNx0BS`oY;L@=$1^y-W!$B|v?xH^)5uP1ZG|BD}%OC7lljM>v@bn?d+(Cq7 zTi2?t7uKF*jq-W3XbQ+Dfk}omrw?ze6o#b*Xyl%-B$koPKd@aZ6f=P+;D2PtmT#Zj zySi_i;p6OE*%1d8GY5^fB)`EjQVvUUEUQf5FO-zLJa2}*jN~{8i3h3KrBakx;G~c) z0GJk{w*0rGo>avn{_fL{h~=!_{GfR?9^GIYn;;a8sR0B96Nt+56AL?6T+M7nBaW?7 zl*x5Nz&3ya;G_Y=HHhoJ<(3QDa2yPTP>(D2Q52A2+A)tMw!#yZh8(T?X&T z#J9vAfS33*vU$U>2@5&eQ3B2^Q#WDHf=5dFm77!*vYAgYI&2DcSmMvaBWxQx! zamnIy-SjTA*y4C(0@Aq)naFGS$PHRV2hVI;WsFg#d7+>{v1?#?6oo?6@Xe!Uk3^O` zc}3UzM1T(2Nq(cr@JO~0+}d%@xEIG9T>SLok0dN5&JyB0v}21GQCOjIER^;-9?k1# zPQ-h)S>?nUXz^BDG=zjFuZ;{x0?88ksKE??zO7qmhK2mbl*wwz0PEdoMpeGeSW>=VnZbx0DoNW?!Kmy-acvBSKyTg1)E9HNzS=@&9y% zS&Lh>pZrmhc@Mp$1i_mNjckK2EPygPr2zgFb`SthH8>$*_U+qu_l=t#r%8)LNyLRo zOv=|=JWkwcp`}s=iyWgwuo8x{Eb%GZL$y3L>sdsq#eBqwY#qb94^$U&QY5td={o1a z2exTj6JeG`eDd}kvm|B-ecS6&q6netqf@?#9jS?m;VFxzO}p?Y@18mK=GhYhFWyMD z>n|E|D!GK0PaU_V>av;BC@c{_^RpWH)PYUF80kcSJt7qWRE)(_N3j#Jdd6hxlF(zW zkjzNrfL>C|CWm&EI<;;o+_IoT`KGEk1@ahylfRHIP8isiqd__u6fL3C4XE~~=%}Bh znGsi;ZyhuW#qqj3w{M#UO&PzY9c9CEVc5nRh6fwgtLJrAl;5}}*`KNbLH zA46%FRjd2N1>;0oY-+HQkT1f+)Mwol534eB$Bh#2;>nU8L|ky0>tq5~R7M%()9=M% zEov6zr{Cr8k#C%fQT_T@mkkLh5JV{CV&A!`b_B5*;GwlkWvAE*hO7|#I=E>KDM7Zc zpEjPZ6gSwrdZ{ad#%2stCAj9P4>|{n2{_XQrb_@1NGMkMr3Tc8fZ}qRSMtHXddCL% z>v{zH3@jZr*z$bs0Xb17Q@|Yd=%a50v4L&;G>akM;L%%muv;v}ay_^}9u9Upxqg`_ zYdDF;%19W^JP30A;Sp3QC;CL}hb@HiY$32GqKy|uAddVr&{)8g6-$?rPQ{xsX0!AE z`7Q0>M5>rwqJ~&gnuH6&Y+E{IypXK6kiSF_~XO&cgv@JO<9%aR4yD$|CYJEtK_?X=4-!E5ZS zrIoiy|3V{b_=I^whcaeN13kEQkv!KaD=chyVt{1N+J-SzMS2v<=;kDSkP$J1p3c+t zzn-}3LlE_>RmHwK+%b`Vd2TimBnJ@C;wf5Q2p7EJ5Wg$-CkHsU3=L(=>Q%-K8OTjw z(u=#Y1|=7jekdHvu{n!?X0AK$Ew z``0eX$}@cFx=A!r5g;LxNnobN5F1%!S1iIrq#PGJ3AbdxtHeSc`2Z;a7(}gxz$R=e zu_gi^7bv!6=>n#y6S)(rqWV=1Ey2}RyR*RYX8S@@WlYZE#O+JwtIdE~l_`yxg8+@q zs#X&2LmX?z+zO76!epi+z;C>SVbAW}@$YXx!%Aw4gDdglC+`ZL_^E4z3yCLlgE?BR ztPC5Q#uu)M3(62*cp3Qh-3eoWRTh*XfBZx!x5x(?gxF^$)hkMrMSqK8Olk4p67qv# z>sNYS=!SnvHH(uNyA%?U$D$c&!D(6RGT*^S%c8{W7EPxu?*J*VTF4C>E-K`UC)=`^ z-DuH=jaYF<@u7?>XeG$w1G)+7Dsjuli4S7Z9jr>m5;b9ElT6z9ICq6waaS3Y#3Kf! zR-P|Wk{_b7?d#PhxB0?=aroc?+6q(HY0BD}w)w^#QPL16>(0C|)V+S?GV|3I$|;Z9 zD-z>We*QT!jlm{EX+W!HQ3(UXcv-%^enPg1fmjp}CPiSZZQtQKnHJ@J_wUk4c!Y3+ zf1~NWM%MU-l*5cM?rs4yc+h6W`46V)&DYz?GAh*l;axkC&un`hF|>rwE+@nW^%$6; z9+7GjtcnHvq-&ZyqA~4cjt(Qcbik?90-LM|0^bmu0i4;d2brAY^HXTg z@ZYE&AIi4#QeTF5Y{Tra-KB{D1}DW~+>2cR7o`aL@B)0CxWYByAVkS*i;q12N8H0S zADWn*vBwlhXajjAtZEd*=p+o-r$P>xMND2n6v+5eOc_1W9T@Nd6&ge&grK0%&0l2Q z&Tqv@e9L7rzM2smHIS~TYX8jMwW{1cwvVX{qG5_ed35$t_)HgtQ&?`$h#;wFUN=feUsWua?!>Pu~4FbE1s*$Su=FVbSEdpeq<2XX;&b|Bl{o-kq>@vMnU z_FkM@!y+oeeh@xF3S*&>L>VYDO_2uX!@4{X~Uiw+C{ zS;PgF?`_ac#F&FN2dZJ|E#OgL={2c`EO4m(008r3ati4y5URo3P0g?v87E>3&~DFO zl;nurx$(MrUbeBsGhpV9Et)n-0`1t&?NpA=DhZ8X2#oAg9~VPec#+`hxK3^74C&9X zq`y#=^TNVp{o3NghTc(?Z|zY&ss(sSUmEY@M6uLnB2EK1HH;jJ4|8cGbH(gfAgZM3 zkaEf6JH2;DTtiy}L5Z&!I|T3WD~n^K)>IOJ+EzTJE)>ay$s}ZMpRhj-w4tF;j6TuC zEKw(673#h?C?pZr_7`?J3!Va61H>(o8W${}RaCrDwna~mwyg_gEjMYBBqw{%M3r&r zQoXVQlH$a!(F&m^b#1TjW(EZ}!t$XG$T|@@cY~f8_&@)^CUs?XXa5VGNq%+$QH+pL zg$AHfZ1$Ls#t!Bq;wkA{G!bh@d2Rv=P{(!Oxo-{;u|Ny3;sk0SpU?=CCLZ6pb0?q3 zK8NwsH-y+qNT;wigUVDXln>nOJV4?C@U?dl$cUJ{I39UKaW6bHkJS(UiP zTjE?*?&=ZiPMyJ7I)V$5ab+(x2{7M(`oTw!A4-W&1c?(qok+qzK6_7`Kdz8?0ul6% zu$2ilzFvrEcg0@B9He;^hv^Ix&r}dwF+&h8u!xO8A^L(N)ah{oki{!>887mU1vq;0 zWc<+wKk0f0@g-9T3&c~td2PnRT6L1d!KPZZa;3>E=Q!)~tH=3DQgcJ{Tsyj7E-3mK zWid}fi6B1s3zbCV3OV?F8xa;SyFxwbh-?-=$x>X*(J-eh{+y%-M-s=e&*Krk3f&EL z3d6t2bbyCLKjEAf;2*iJ&BOwc5@D-&me3aA0si8QW#JK1_3%cpcm(61q{hS}oIxTb zOYNRMbzrMPqx>rMolPjLUWL4bLmIDmgu#r#8HAF$ArL77JW%AkP=+Pvmca0F(Cxi9 zZ|EaM>5m}rm1JfLofWV6#)-;T#?Cx2M}4JOj3N`efuq`R{mm+*aAn) zCQE>g4U6p`uRtaJm6XD`(maFZqjHO$5-&(dz;}reQsc1_c@Ucpyl zsANm$E}pR{iOLA5V+12aHP8ZhGxV2cM;DB*kFF_TZo=EOfm36A!>Cg%3SbjG<^2Bs z!&f-2c)xC4Lrm@!)D7;PE&FX=D472$FT19D7p*d;i3Jokl=ip-$i(~HTNk0-vkc&f z0@41EK!{Na#tw`FJMuJ7X8>>`#P>48wLAiF5X??3-dkf*c}`J!O9Q0ztvbsU_t zTh`)h1>!B-5V-^?or$$3GQiZ=eqGi)ZQ$4V854rK&rwAIgi=r1RhUtSr~KU_TcD)3 zJ7KC(WVWsI2sz`h(S&d3LSe$53@wLTg&Jjl)jhd+?J@xF98&_CU2R5zckb)UzA>sg) z8d9eM%q^hBVtRpVREsI_k?Z7}Ua;b#Q_;KN0`9!IIcz9%i8ZA_bYCU<4hFW6;`D7^ zwkYTvz4lEq3m^GLSZWu{Tx{8(K3CWF;6^!>gyDbx@)IGPSRfL;ggC&J#N#XzfGhz3 zX8fA~Vhkh}Fl20oL|bKSi~wD1r1T1ZCJYPUDXd2eFr3U1dPJZYmw_nrSW~0Ca44@| zwLSBxOeE6lkacqTg!LGTTJMVM{<4PrE&;3bu95xv{PxYKT^nW-aFmM)FZ&*FY5h#I zNUTB2+2Rr4H_Oa0({g0d*$n)X{s2ElKtqk>BALnw)6TOjJyU*iqKegugk)J&3`?{8 z5nm!;CH5$9sz_W*06gA{xeN-KuW|`go7S(l@kreAO%aehI1!T~ucdR=5b1IuS9t+@ za3v&}f2Z}%F$$-{UAQ%U zCbDWLv@kw-XXerTp&zMS>anVh3YM=Tcm3U~XM}?^@9>6Ii-!*+y|s-UE`v9uy15Bm z@Cuw|5R>t*e%D=bE4V>w9~M) z3(2pTK5Cd}-Q}eguYm5~rw=deyDvZYXGy&)4t>#U-GuG90#4?#5mR0_`_oE8*I~Xn zPAe2tOD#fvu{S4G2JA^ZbDe||??C7#`imMQ9^*M+A8L^x4fzn8P$g1ytXtE*?k0Ip z?Ak^_0AwbmMNw{F6EwblWG`p7boMB3tGK<@re+U?C}lfKuidbGDOtzeKvI9fidMF_ z9+57rD%4}|%H!KMiAyj(4a)kLW{>XDVP@x67H&vfzqDb=XK&w@g7U9#KZjd;gG?JU zG7Aij8076%`MGG>>6W?E!!*(bHHYy}j|3O!wNHViQL~D8l(`Ijr!Vk(@JP(}sX=3C z3QhqqATlC^T_;w+hIbLQ^In#IQR@u#k;8|ji=a-A+t;*Q*(IZf{;tykSO7MPS-^B2 zEf6d~7X%AramoCE8QVWH=7BJ-P(K6$Jq{#sMUG$pcCDN%;~?b-()e4S;>Jto&8C?A z{kxz5Yab+-{U~3^$-+S}BOt(AJYCM}qh!?yU>I#;$5uoxG$u!qk1umJEI=e;XA0@y zQw>HF;HT!4kFaNeUmr~eFl(dPzLhcmXrs&G?HYs^MAei`#lV$ll{$iSL`QHO@^XQ3 z4WC-3F2&cbNoE>3lxMMnoM}q*6t^*(>0-hL`U3#t*+rZcvRY(DoWXh)ng!q)=V8n! zEJVQg^arOZ#0zq(qfmD4@s3rVGwm27Zq|tkHfmIZ7zM5*)2wab1q%VGpGFoOyME#z z00W^vtU0W49kpeaOyy^n^y##IaCZy0ZQo(nf>DiX$z9YzYEh+U5V{`p5D zx)CE)AP#?u1u$s6vJ2V&w)V1|qaex$wLh!Wi)zEV}Nxuk((tsp}NL^3^Bv?MSE#fBz zr+WoT5_C>9m3AW!1&#GO*>#d~fjHQ*itFwgsp6HPtnsfu zd_pp$_j;oR=@PW?MfB9Skd8HR6b+oK1U2GT_Z9_u4ZJZs1)a*90ih#ADQRZ`v1S!3 z#IRb#6oJ984Up2H7c7YA*Tcj&dG7CPJh^{2%XYSb%*E3tu*3-oOmJddBz2%K?OV69 z7f|V7tewSH8Sh?h0F9u$H@X`q)_q&f!`L?CT$0l&5+~5p zU%}I<1O|6?)~GRloW}thzy0f16Zd5oN;s-UB(wlrF%^K;Kr?cv52iAi$uOith0wHGMh}n44OZ9?ge{}h@#ZytaZ$UqCJWz})w7+#XToS5HOn`vG0=Oo? zuWJE*89v4+RYH;rD-}=wDJF=--?2ABDkjBUZi9?vbVHoDu1Eg*D)4g+Pyof^KsP!X z#)u1PGcFnc=tU{n0@A`NI>uEd`TC2i2(;t^B-nZb7P48vo|@BzUZV&=4!nq{-7M39PQ=x={_ zs8Mx7pYHw$piMSROBo0+D&)G@xo3Sql;qbEw`^jJK`@2uR(7zR1fz@~RgO=YOk4vG zn%uFWfzjkv#Ol0gt#4VuTr(3iW{$G3ZNAn6bLogfB9jpJXZLPlv1m+iK|zdk`UJ`F zqF8ysEVVLDWK&x`Q9Kvs&wLnqos9y%0b5GL|H1-u=I~VwcVxfA473Cb-~ynHsWFxV zKQS3XSy1%$4fIU)AKbdx5=*FvNVwJO{vc!A&DPG$nvpUSjHY?9jT z+bj&{w%CyH#)(6q0_~C$3A!PuEM$AaR@X#hNv+w=l~ zpTH0e(|2;uZU)9z8w5AJT9>^&xWF<5t|fbnkSyfdv+Ma zgao$$#>|nyl~a_L%~E;I;1?T0bYf@$EI=BB@ee03!%mqRtHeEtRUqhAVdDh(ur4hZ(QH#v&7=3^3wc_dnQBjj*~)is{M5X1rWg@&(jW0 z7KW%zowf(}*Ue1UgdS0VfF)^$mst{~j`+FQrqLwiv4hll6S6R1$0UN3h2VsZWLSm$cWzt{!@$p<66&G# zrVQxq4<&diwTGb4P7+o8*~J#kn%U1yLYlC%O&d}%E->C96I4hwn?nIs(DG_K9?;8e zDrJ+r41SpRu~?Poix*DM9fuLP1J>>Zr?89gLdGxkY8>0J5^JNUy>zH`sSEMO7xLsi zd}mC8%Z@io8X^SO{ZM zl2*0)AW3O5pDzH_X~82r$l&4*m%Sm|g#!x+ih`NDy5K|pI~Op~W=b4#9QcCWn9}6% zi|imm5@yt9l+Cj76FCmyhuXNz%$kk(+$E2M+Pui0or+iYXwfV}1axbk`n61(YJAia z62R&+VCL=ed1b)bR+quaj|j9YDbt%S2=|jbxq0HCV2);s33xBv%3cC{_CFTTej34a zvwhb?IFcLL_I+2*+q*KF;v|NfJ4~ueud=7B zNTXc{cosyZw#7;@Q*2^TIvxjJZuw%ySt^unCsvPB3@cC2sviaq;MuE3ZU#DV8Gsym zVLqtAmG)N%IYcaW=BrASk6l|K9}7UfZy(ziV+zZ+p%I3a#PYV_;6(5QC1GkICNi4| zNc4V}IyJmS;W_<#2ETK4wK-nlq}KD#ojJHqYBc>t5io}o#vp~f4Xh~}d|C3zNi2;E zReqL=ZkO+20J&!~VFdq{RnNnB@ESo%2Vp5*jp8`J6!b1#Q0KR63$OJ#(oP^hY!7HOr z3y`|7A==~mzI7`D>m&w((@>_&ywrhlOxS6j>BYF>ySzQPPM`ert?NmV#Vr&txYl>T zTRN<8&rr8~nN2V(|1addliNwZ2oD-l9mE$VL2OoRG+pthY6P-m0LlWz{vsstloPH8 z`K&h5&t3TUr;1I$F;`4Yf*ER1a11#vAz#mWF)v~pXThA)$0?T(BhfrFGI&So8Y2po zbk^hrj4^xgm*}Y6HuadKt6gSn6rRcK96NQKnmZ2caRJ!-$s@LdE7kyht#*dfra02MFrmDZ^V4+1=dv(wlukjZ$%zfOd< zfS*dDr#OQF3G-73;?Jq1tsB(Lv>eZl}LeLc%-p&*L)M> zjpVd=R=;3_eJeQ6`eoZ-6TqMx#YOoMqJ@_J5iGxb|D|se-!_UT_Bp(;VeW}xBjKF+ zWYZXpCr{K+C~ibawjrBQLxkpq0@)%oB>foW9sahs1_WdGQQsOQG=hNt@IMEgjJu|91LtUMHB8L*gLurWp)P2_8tobBH%1DM04ygzeRoXrc>8W~|vHNZTv@24ob zX)-_Yg$I3;sA(-B;moHNUWOKjML?)3Hb}sN2aO<@Lj{;1%kO8v;FXYmexe)YsPT3` z2rR|7T$!T_Uxpcj6(q>5fwomKApIezfDYi z*cdJTMg!OgtrxGy^j_IkY(KeSzU^$rwx`y`kwy<5gb4L&*VeDb)hd%Ypo{E~Y0oPU zIt-udBrWw#Q%KCtFK0Uy`;#SDfbqX);t+r6kb%Tr1xw}ayG!gl2Q%zO1ELQ-A_Q8n zd)}aI{s^u}46g$c`)Zg)d@`6Q$#CXN0Re{EWXoh1@sqtN^VSB0@CS3cSH*ry-Dn|qKQ`R zG=iW49-@CBojgHnkmbgQZwnH99N}?~c#EOz+_W(|GcDjVYZ(nVppV6>ZlM_Nuwyxc z!F4V44LLa4Nw^g>0$nC&(v>(UcYne%&c#X03TZQ$r@!=pf2}8CW02eS9??iu`BrAvn&lqR-_yqgTkwW{8-EpxszHkCo?e01Z&jjgK=&Y3u{X?>|U{&ayqbJ}0} z7}cZetnp*<8VDIF11ErE)`R>p)|5U|O3t}I0U(qu-#J0HLGn^KGB)@k_OVp~ zRGKwyp6}=5PnLUyEJ1SKm1d0^G9(CPAYt1q8k5C`?YqLCmFRBYxdSuCxGwlf_~V6) zhPmo#S-Yke33@=gzheka4z?32fjTj+?@Uc?_A_iwE}pfhdBGA)3Wba!`(B#H6+Nr^ zTvp1(44p#CtqY7mw3QfE$iZJsUXhbXv`7lY4*#a%@<+2T00u~S=C1MuC_zIHAtIvE zgH`B2C1jM|4>0+K5|p%c9=8_;Vp0IRMMN~hL1Luv;4b?UgTzz5c@v*~`l(yaVSu6$ zLJ7bN5gQumNeq%y-kiJD6C59*Jb9t6vr>FhrVJY=k=G>VLv)i!ni|iVOER?q)qWxr zhY=^jxdY%SEPcTO7=Z@S0IVS>6fEx%Y0_So5=v1CNX&aO9=O;BMc1H6&>*rn*gPmkOd$e}5WAxVK0dmkN}HHIN=Mis8iB>|Q1 zRsFj#wmqd|3gd|Qe!-P0FIYd~F4>~vOiczA)7o?c)j+h;kA@y4byob%6#~Zqadmas zQP7xYvTeJF5qF71;7rHd8PiB+9)!GZOG|WLwL+#Q>+vJER|r(VN7(1Y>V@!ZW_jlL zF=VN6q2KYBzb7?&=zwT2%CG_0c*IWFI#!osSh@*8UOTkQ^cLpQ7k$)UEfEctykVV` zz-e%b&Z^d}ZcQ41iY>uS3o7gpeeuawnfWtVv!*D<6N$dy7glKM7iFivBq2LoIwA^a zA|R>UHAXRlru$i>hP!daEJYbN8Ee!w*JIwQP&O_G1==mDMOzmY&_@#94hBL!Hi75k zV-TPcJTb(5YF1V(KIE8jjB}OuX;jB~9BMPl3dG(5E(+#YIL^p7rY0BM)lLb4R09zw zpy!+TLQ)6Ihiy-lFcJ_%NPz)a$OS$XU=aO@Omlq1BfQDH;tq`N(ZyhRmZ+qaBJ+U> zL`m^*pI*sgP73;iI>zaFPP{U+^HRx-+G7e z^`d~tn2AdpBT$sFW4RV)fXI&plg1&e1Q?Vll<8TH0P;$WFdPPj{$iAxabw4Zb?Q+V zFlvHJ<@0*PQeX+Z1*lyJwjtBZWF_m`bqL2JBlE=qsF$Vg=iwCRu0vo*^3X3-MqYP` zX-8AcfmMz1Cq)D><0rzxsxTBQC<^=51};e~H;Vv~On}e@QAXM%A>*a-ldbF3q)Pl0 zZDZaWal?f2nADuFhMBN1m+d0?uh~{vMtPHiawLj(x*#0*r`C=I_!Z0e>+u6NgL8s6 z$SASdM#NMYmk`oI1ew#sSuC7F8GtpOC666+);Ify*`qL5S2~9TC%gY`S~SnJshOid zzJY@l0+WEH5$5NAD_M3it{3fLX4}-7mX|5*3cFf(nZaXcDpnu-6V$rdyh_D{6WGQP zwh-}Ggq+I~1OQ~Ae5qrqf%>q7RvCs07l2tsQ^-h<8o>MT{49%}5ydtm>M=gECz5|C z0=5LB)XHK8uwtYrrJ%nKir=iXIXF)-kTgv5NFh-j1*B&%ML;4c;_*WU@!*unpUzNS zBR}JS%lsFYv*RUHr$Y^9*-)5xaXm(X9&}MmwSCph@NgJ1<8}7nUPBX#+eIcBn>oLq zX*UAa0!D$^xZ<0RAg;sd^AlgNEm@xU+D{k*JT91!--&`L>X;{=cuiccuW4r zF-d-W%G#m&af(KAY^f^exPSx>9(P5+hwqtQM>=_GYL_-Z5`M?`b~#Sv>p^b>nwG{(#(hbyam!YGQ#1dS1A z+`<6qfic7R-8D6{vV@ZK*I+UGv7tJlYf$&DmPUG`rs65v9iX8;N+>lVnAe|@fgBBH zRt2aO5NB3i{0gq940B;rutgd;(*r$G{L* zESHBv^_R&M^#G?73)WQpr1d_$_l91_PdSq$AvqR5eW&Kx=7=3a+NWET6qTA-5)Dm$ zMProV1>ifw2j|J`H_&1B<4so6wUdWKG;t-c5_XQt89AUr!f-rE{?ISt41$pHSLqeQ z(bNrgyMN`JAr^%r`3pHyaL)}5%KGU;&fo>=AnwAv=;c4Z`;xNm(YT%*594KN!^OjU zp@rqcmdJon^*MkiT74K8G=hja-ibQBophBcWDm(05wElDZApH(%T*`CX*3WOU?kf~ z61tV$o}4>Ea{0`uzy?&h$x4A1Tg~XZS(|Bt`r+PW_txp-ESW@h8lM&r_QAqxU^$#PetcN}e$hOYbBE1ww|TL$2#L@)R^nE~ zA%~d>VWbK*Uc|Pv4+UXpuAVwNut7~_h&#)^^bre1v`3DI>+r9^xTo6WQ)cyfp91RsF9#+0wrn_-Z3d3=QtgO-JRF3 zyVS2xH=OQYzxv4X#=?fH2RE)ES24Imbkd#|5M~cv06bT0yoPi_Mq)}Bha`t~5hsZp zgd~3oq#0n^%$9g~{`j5=LtfvxPND+x+TqsBib__G$fkpXV#1zK9jew9fI}IkCglQt zT1A$oIa9ZoG20i+f^aUj2!luDyg?LWo~Dr1X0clkoTigFp}Yx1@!l+DG?x+~^TQTW z5@e@zX^RDLZZyd^%_0uZNzwfXr&z@nb59~yHl~(5!-GrZF$FB~VF{nOXqQ*~E}e|2 z16NE71&~omvttnsB?|0*fUv0^f9zFQHT^V+pX?kdJ-E#LVEJ^L02wtx-_xf3lmeHW z7>Od}u)vGg#ZQvN{Hd|l9vl(TenVz)7I(m~Iu|cpGIc_fr+p}$VxN~Mer(NRS@EGw zL@?|#WA~oaBJAdmgYa0xN(TdzJFFT842MhXqL2?kfS)?>QyF^}N%vK`{ojOZOyZc8 zb4y;9G@kW?vJ`qhsQ~!{44#C1C?Z`=Gntt!$rm?)v>}r$t?;zrgAW}%C`d&}BBS{l zjt^6rc~4vr>@oVRI2r-oh-Dk^m<=($P$BGNH1!k+F$Ld2vIpKlKsFCcnEEqzl(_hh zG;&E1kWcPWp!}d6)5nTd9h*H47s$S5W{XtAKZA-i#xiVpv(ijQk8InzRT~IuyS3Y< zOby^oyY?1Y3=}V zO!e|9(r%FEi>aYR6X&M0V}9A=V89py53~h-KT%j8okKo(=$zF-*En3UABX|Xe`Q~` z+<9>Rgg?)n91W9D{?<$?U=NuezW7A?mUXg7im*N=TwGzvgw8D(!OG7{@HS)XE|E_2 zLOx)|5Z9E80E*F3mkcYQ!B7A^caDYS#{p%H8jTuGw?JpfhkG?~uzMzaIaoDLL z;!*u%1-g*~*0j`Q!R1;7BjQMSRi@!8JrH zOWqY8ZcMnKvk$|DEu;WoGalHepia)S;e`;%G1jJ5tr$7TFqvSA(FqnP7LynWIL zl0TeZ7SYkgGjWZ~G0}Bm+^CUzifNdfC{ax`k4AD92n1aKFr*`4;E)kW$Y>HL*Ho|J zCg(AxToDg4mYDaFrWjWM@1sIxyhZek3V?RP#EFklrf?C5&z0>@b>}*(RRQ=X=VeU` zSDG9Qc}{i4@Y%)1EQVdJRErp|aX+Zk+$hzEFu|Kt_*T04HivsWau-(dai{Rd1wVQ1;|5F6rJVYQ{i2J!80zx+bPKBiyI zh0%;UV%(9DCW<@gOJ)#7z>0G0sPv$U~r#x%a>A2TGFm{Yr>7p$7{4LmypNwYnChN6{HRO&|d@8Huk?ULQk$% z^2>NA@XyA^u&Q;438)8IoHNgCT$VL#|DG@^G()Rc>HKl3GulI_iexTZR%#eeq9s6$iXJ?SF!pf4J6+aPN9MWbf zy06(T`un+7f2S2~uK2s#zkK$-1=p;7eL!k6EGl7V`so9uF8b>vRDV?Ko4}`nZJ`iX z#IA*-S-&)_{7uuZ@ z7hdOzaWt$<#}NK*m4YAs%RaO%ehKdI6#41fggf?8x%Yyu(P3#bHf&I-*Yp%K-YAE{ z4Nu%GhE{0+II-xM^yP9=AP8*dr`eYzYBHHHHwU3A@U}~mO;@M@Ke-;vR7>Ltt6%|E zkXQt}sK62ElhL2@!U$2JC{v0!}{ThbjC$YwI(~S7(jkX#i+ii~tlMZ4}2nbE0 z0K?|@fBzF>#!oQ;ZwFlz#(F$)^bhU>dl%^ielckrhx|-`_b|@YY;=fanSVygMLP&t zwOYI+M0{8X$S#)w{z4wX&@Zzvq&mAD&BfIjioCESvQ))ivtT*8z$Rxb(a2bUU=(aL zd{zXg4f~K|cImA0!V7F*=#^+n#n128Jyuu2xw#~kwk@)0QfZ&$7z*>(7^qw}SFk(` z6QmLtG?+{SEd%WYdeL82KR4VW2#{7-$j*zr#pEx@A(4RtTEsVwd^a@oQPN%Cfo;-^ zFifyV1n0g*SMUpJD^^@yRfIY2_AUbiC`n4_ z1)!1)tZ^W8O938zJWkvCOLMK87vd)d)P*?rjW_LDDc~Gez#FR5-A_OIfDINFg^Q|X z+f(SIjj=#dBc5ivyq8ioMH`PBVjZtjrBeL-KaAap-{oz6gealTTq+}q5HQ44p3Nn~8t3-!!%nb+H^<+vzN!8jCyry( z+4x#sB}afS?0fm-v7l(1Bf?g{2s$YT6UL4u83@GeQbxhR(7=iF#upw@r5a z!uj*yTumpT4y|ZavI2vs1HJAOUI>^2d*76)yXhnAI&jWt-R4M|J3(2Z@1eWZq!4 zoJk;pJ+(Bp%iFpt$!^mV+rY24iK_aGdNMpu+L$_#cPe*nSHLPx{0qsg>9Wk!~ zY`IqRG;%?G5f7S|2;r=m0!juYA5gUQB~5A=svI(l{Q;P;_}a&96-&+KF@&Aj+r@m|f)N0t!)`!Y`_|EhM8w(4KewNph!))o3@Eu z*?3c6*5ZY`Z<$36nO3$O085Ig$`3ad1|n0C?k4z#Bk-EBvjq(nz)BVZAO(?SfI>Hq z$SQJOlh)-|XAsSV9mI;CYpsti{PN4c+ucj3Ge$lpB1MBh*i#2FArpn&q+sC6Lnb{s zd*5Otm*TP&#FxO~y$zMZ$4+t9Sd~^46gGSinR$|u43Wqa>0+6Wz_U?CxNy^uxm<#Y(Tnz18zhZIm7z&6qyuV z_ZnqsHq?Q4#;urqrXwh?&cY63F;UC{JAr>UgLS+n**;u8s?VqxRx zZsJ{Hym*9k`rU~qa+C}WAX&ms@}QvyA*_2!bCnJ;{k${8qU{sH+Mxw@zw`oLBe;Zs zu$X5dzOBzZ&W-_Y#SDYzjSsA(g3Dp$2t+`iq+6H*=3o0sFaZ>W9XMIs=j>tSyglFk z{qsL@sIm`fOfI<`_6Qbzheq@?9Po(@` zK!~4n0gRMHcgtW6BBgA7rLm5`DQ(Z5d)!-)GYX>Ue$r+5PojcV&zTptQHcs@C2!4U z4#ZtPUX9vy;}pY9*&!pb42KyA9mfK?=5iIVNv@R&ZbO?a*>;JsBis((xa=87_*<5q zUOO*|w9O#0p#fHcd>6*!@I->8#NuR?oOBZUgI|K2V$PN;zVX^2;m_k{Gq=x5YfXn0 z`BE)>wui8`*k)7xQ*;wgL(jyk1AZPW+0N|DRRB+h)0l}!^I_4JhK;YGX1#ZZU;=3- z&`Pu8eea$yA~Z55B`;Pp7rg5F$uiBjR2%`eF)_&Kq5__rdz}n4a z7-?TnTFvi6h_#d0O|vi&DHJ1zB2Y(70ZeoQDkhDgi7$XnRHFou(RpKmr`*{kfL*Xu zw}v*&#I?-C^kZ|T;{`uy68pzDUGKK8N*grKgA#G#iKyeySQr{%2Py8<5G~+As5*-H13 z#dB3)wOX@di%5J#caVM(p9Gb}RM~H>Wll;MEKa&Ha(|qwQxagB9w!%*(JVY*@7-<3 zl6q9$^2s1?^Z5lip-u;Z%5XpTQZ4DjYJQWsXE z3lv-ect*i}0Lc(|E?^gI&nOE*9U>iUJ5)^_vn`R~EqaZhJG;L#)@JVCw(0r%@3Q1% z`~6GpEJO=n2l7A4*F*iKF}mpwlR9)yH^ETG*C8(tzZ)sKfS5un0s#^bR_3;{Gq&y_ z-mU(i9Yl>l(YU~jvcNm52K;2)vG$Lx^DJ_K43;}Ibq_AF0tI_(2*CjuBi0s?)(-H1 z(A-pul@~h8Qe|Y@GR5qPE}%de6^_`?DjyMNqIkyKg3n&8E0T zO~t>c0`QyI;-Cfm^7iQt3Zm=2IJt3gH+h(+*X^MB*95+2&}eK( zOKjBiVTMWn^R^DD?`HgQgvkOSQ;b6|0F}WqEg0Ab|Gu?~)!`=t7sRRwu?|rN-as80 z;m{}q^SDDzX!nP79xY-_@4!8{qIKw;sY|l%(9$SM4tyW_S5d2ZCua>e!nu(-w1Z<7srQRL&Q&?bjsg@5f-h~8O&OoDFAe}n=d&f6leqlfS z)+mBKz1A<(z*#7%U+6;=7!lyK3m=2QM+c2#n|_ZzWUpYLI-2Cw47FAVpSKOS0uT5R z{z#%4%6p1YWBnRvq(eYNmfe?YJ^kmO{@N}$;%sVsSVINIC!nTgzKyIcWZ66sDFSHb zd2KP|5Um7!=t_G~cYWiYr{iL;wRKfft9|j-YgRL9syQaC%7!6NIQW9k;@G&uq*ePO z0O?_-dxl+jAzxT)Wxqi6nMZZVB?D=_gJfhxs22RN=kMk9Why5ThS>8ey98NKQklI0 z(#T>sP@XL$G5~UbM=y~7j8*t?iE4B-A?8}o0!}A=YflkMRkH||(m|e!L|VdZ5DR+m zxhJ`VE{AsfgIVx4|D%>L`H7_4ktG z17qssP`aRAK!qL=FZ@a-2i=FTD1#sX+@n*3)~8f%hV1%W54QG~WghO-A0 zu0%JJZq}F!(^)%!+OqeVwZ@taVCun)t(gMEcZOmL@Zb<^05A9lKUN3$ZCNzO)`-p% z&fo{A5a<$QQ~)q%fY7%QM0pKBRZ~t*CZx%Vz-TD!SCoWLR8`*-4VjzZAjouc-yRem z{7*~XeFM4jAkXy&(ojMB;70{A-<`u6#vR8Io0`Y$^sD=O5YdWC{9KR5BNzASC6bm^ z$xH$}MTm?UGHR6N>{(_`jRNwr*xiH*eahk5po0^7#PJBAJBQaQ78Rhb>L zna0XHZV?4-s-&W_AF3;|?NE*5XeE=98CkJbUj3$pe{mD>{Iy_B)B?F-0Ki&W5$kjxdRD^2kWpHz^8*@c-cb_w!H~b7xY* zAqnO}cgARuf!NJJ>qRU4e>Gp==4L%|E8isZr+Z&kaG`H0VX$qo%$j$kgMXo8S)k(o zes*Z?iJafIW|hh@%*J>26BXaKdPO9X^R~QzF$Et=itCZGWHXFlJ_rn$Ay%L>Yi-`; zw)3V;R7YonPt2=RNEG)I8ud<3y>$ZcNMPe=r{A6HS6lnwkn~V99u@>b6v~q}5F22F znL9W+?7Z^oURk@!goa1BIoS(l(C)ct>%9671ABLa-e4Pa!+`nL7*?5|)K@2#l5d+N zIHLh>?h!m+>`4(AcX#ubT@yj|_7Zz@X@E(hrs5gqWzR|@=b_6FL|f+xE;&^9P8`h&k}ToS@{NZV->x!h z=nE;Q8uejHMUF9yoebWFl@c$)|IzY@ zR`{#)E8#CZwR=}VxDUZ=gNW7(wz~_hzY7tFUoXQDdvXfu>9Q9SkHY{<%Mt5fPf`RW5OnIPvQ~&J zm&@&REeTm5x1_9MGqU*xSGI@X5@|2k$Paz{*~hq_#*Y1i1r*pe>IbX7kqBH35c(5A z5D09DMn~g5&yC?Nv|?^iSsVtN3v^IMW;t=UMtVAMdU`;vVF2%m{ydRb^9WGSuQalP zI!46c=1@np!A(3p_wnr{@MjQX7-M{q>R4qUltZ)C_)%m4WxxqN$vuWpNZPZCARS>h zl4JG|qc=&dl0AEP0Ug4I3uKZQGK;)^{_aa*J=HL8_REqcB*E);qlM`s- zRWAGL%s-?`gjluNhtvAW!9TT@zu7A~n(iPyV)+{ygu+}#M|}gWg1AAwx`XgKIvU z!obFGY&o98z9*lEHB5P%$jF`^VtTA2P`B;Bh5T3m4s8j7N|c57%?Tedo^c1XkQ>0D zz#QTlXg{-G$Whb<{trC=6#E|(pS=Bs&tHGpTs9&gFCZx(ug(&fJX|Na()RPjp?+mr z+ognQ!N9NwHTxM!=_84GoFG0C*+Pui6j8>4q-C5dxRxJ@jAm1=M z5lyXogm!waHsfeo*cg%Lz@ux%#aL4W9tzvQqmP)>CD=ieR0b0D@e%O&Qw@X2E-uRx z@Xmty0+j-Ew1zj=ub(~^+S!)Yvxovo)FFyFU(2p8`%!yC2NB_qh`NuAKBu3Pt#%CqY5t88`w2G6^(x z1^LjfxR(_}_@inr2M;@Grz}sN%(1g*rrw-{eAg-fc4ORPxsMxBE4SPL6i~2B56hhqmf`<$ACUqUIVOd zCeUC50SRGLf(M{d)*e{m`NrUZc~7*m21gWYWd9xrR1-A+%t5g4N!ux2UjvAIq4$j%yr5F zbRpU3$k*XHY6Ac}qdmIJd({jlAs^HYJ%R66y(7Uq9mf%9&ge4USBUaL4bgHPp^2yi zNrSdxu&t%{q__!Zio`zYH@{)1XxIbO#$^L)$dB+>u!e{Ugw$-I#_FW!w*Kqe&m|SG z^t@UWRZZ>~bY3vmKm|2@+uXnln*@I%@r-8Icb#~>+WuWTGjkL|G14Li9qKY9lWfYg zh-(oC49I`xItuHxp@djHHN9(=v(#jqzp>Xs1Lb^R()PKQDz}G35K^NdhXR06*a*6n zC#s`tI8OO(Q9V8u8n=d%YU`6?PP-}h#Md&Qpl$T66Hq1=d+t- z`1my+vsx-3j&_^>qB2;CF@*Gj$`S15aRl?(+iYov2HJ4r1;Kyr5>mi9yA(=I zuNY-~4FHgUcNhc8{s5cz%4Sf(szYesv-wf5_h$1Fz^@n6a);A$#8MK2(N8`5YdJ}fym4Q=wvOPa)v_)w+= zy|ToZO0G7h-ZyIBX?J!;7#zD2UJJeI-t0Njr zm83h)iwu)3sG))`I4}N>RwANeL{@P~i85|Nd80cRg~w6_N6yA4|; z8H#^;yJb^HnHP}tO%90#5|8$Gp+ScYqB!gH1^*4b&HC87e)1u!Wou|gIKr>e^;?N& zdq5pQ8Tcfqak`oqgfxH$O0az!g1zy11i7d05;xekjkr+m9^rpeneatY?MF$KML?JBb zCV0KF%}?Gmq!|Wo%a*c(5VS zgoYLgYO}m*KDI{(;Ta>9*v&V0aJ%v4OhNd9SkaB+$vEp z7Ryxu9!Wy2)pu_kC_%`Y&*{7g4uID??JRm{@+5<(Krk|);}Ge-1}nRRC%U<^9_hP3 z$Z?gK6lSpK8L>%Pf|-4HEfuHz_8cid#pL z@EZQ`$ZGCD+%&$12m|@AromN5%8(l>`)CptP#}JNthp9Buf_5u;LmN>=A1FhU|bj^ z4y`bP5dG3qQ3%Wnx4tnr7#L_-@dTg`QNy{&_OleOJ>uG}=Y)gM&8VqHRzQfdQBDZR zNoB%6X$B5=?AY<~!Gj7uER1ZUs?0``cHw3330Kl()0s};&6u4L3M+Q7v(*DT^LR(j{7Q}D8hKVsx;Io2= zBeELbd9EJWVnrLs3UNh;$uR&egUg;FjTtaDj7bCx#bpOJUDG!2}AVzJ&;bjdV^pW#z3lVazeVWvi; zi{)=q8v9RvdGJH4n5_;|fg>Ef-_#ZK$SYF<6A_^zc(yp^M(Lxz__h>+X{V46eClk( zwKJT@Sk%h4v(OPz2uF(y=n;a`1we}?*xyS}auZV8=qNjBnuD}gh6<7g2JnmeT7_H+ z#3LBMmN^%)>sQ-Dp)DFx8L3RC>xhBYN0m{4se=@Tk0{WK z=tRj06bHk`VqU+RE-{T>L~GwZ?nAg4P58-E5JyM%H{r?hX;m)uBo70U{I%`P%kXN9O7{KrY=<=h0L2+yTRnMdeq%C zZ|V3^ruaoT^%{8any~=s!M{7%uqrz*PXpty)1-?dg%1P6LT~J8&d6RXvW|fkx){{_k!+@_830yw|=tFx2>ZHOR-8|p%HVv2F%a^uUkEH{!PamGM3b7ugc zS@4lNc$~YDHZX=ktb0m*vdcz8X%*0#hR9+`JL}r-j6~%RrlxNpOXZ*Jf6?(>^X)?h$?sIlq( z7NNSo6e7sX~Kj zf>;&`V$)XS7p@UdMOsSE9f7zRjw`kmr4`i9_@ZCiv~R8v75lDlC> ztX@~XC_5A&77P%}2kfE3$YKQNRUj)+Oe89o2pO3*P}U^%!13qmkmSU>I55`pvBd$~i~;5;CUi6yRt+W0 zI4L(TU4V9j#far;uAOle>zaefiuM%DVtJI6#R{M+Gt&lNR;*aAh0cr(Q@UQTNDfQ6 z??R5$m1ag>p#)a+^zSa^Qe|6(S3X;Yp z_DiCWLCs3BtVVXd$b&<`j<=%YICs(&W6XTHl@z%0uHoa4Vz|DwZ;uW(|D^&1`uKw- z(BW-deR~RodecgZM&^bQzd+ z*5&A6^MuqCqto(sS{b?sa0rJbl0n~Hf`DkH4A`IoHt>+kVf&*GKa4JDbZ5eN6!uUc zR6(S|g{cY5@=K*9|qM_$FKCc)y(EM?E|yYD9C zMf-F4@N>`RQ)3DPjT8BUOgE%3tVWZ0z@oGBkJcJ@jWOuPn$2t#j0Il^g1edbXhKAw zra(g}Z%&N(nEleaKjw zyXWR84iMY1!+`!e=>z}9$Y2p`tRipX76C}4g;6a*mvB&x zj1_1yd}>0wPN9PWkyyrk+Egoa3P9`n0*OY*Qjf}JM+jnE;9vL@q2l>+1Kk7@8brfk zHYD|}BC$!A#yF((b&C4%(BR+YAmJzNv0IubN3QaX)Dt@UHnm@n5C6*k>{V`pgNLGd zguF$sRFx2DA#&X(*3`T#0&UHQ^N0V3uM2BmQDRvWT@M`1T8y^HqVsPm#v(35K5fr*u z0>n6jNAHMz`y|*k*9%+_hpf|JDnQxnvuz1&P(~E6%*_a63Ta>>KVk(IjOdQ7r@8RJ z=1(}q4M9sAmW&#z402)}1_-%Cjo<;<4K5wc)by+Fv!&Tx9tW1JchiMzZ~Ut-6UL1d z8&@tifAw^f;n^Lq04>kEd12Wd)>^jUcTyU*gec_emT*;pn6Eooun1 z#-=Em#950|Nt$tFxI(sF!t&Cv1%DvHu_pD)_s`AF2r2ST92c5 zfKzlxYA%roLXbS@wc&iiu`C))DSRk^2$)Er_uvh}?`KF3{3Muat16hvT#+V)@pdjcQYb=G+WoplDz z?c$h$fT&_U8=&9!fNf|8Y@-kJE_W5dh%8jO;e(clIQ5Gr-Tew7pzIC;+UP^P5IfG8 z;3$5bd8z? zwyx*8t;_oyd4%1Qs64G@Y0m>JwGU;>phczqNT?SWwX?)`j0}9UQKJF;Z)$+sssay*Lr)1>Byb+L=I+H$K3dkgI<%%HuQ@OxgesFehM6vSQz3I# zSVr%}fl-*_Z^XqaZSN_s{@#B^c6L%S(XEMT6MFD&!N`|`k#0V#n;+cXUKS=~S+vP{H1?ie>3FtiH$;}I!I zIs&4a0oXK}tLQ9?N<f{XtIPs4$NJKP_t3wrktgTh^z>~rOnexK z2!G&*9F!pd)fb}>@LznxG)uY`Pa3Ni9wCHI;(FzRW!!MGHE7jR#C46$v z)uHPpf4VRq0#|u#|{FFksSXNgO5fVz`NX26zf96k|#;Y%q9qmJ96*4gZb(&?XF*NFdCJ1xz-% zmEb4g=|Ymzp)iY~#KmlHPti{NB@_UhkuwI45l*vXSOUtV%nj$9-bb733qYByy6h_7 z{-Bz;qkL_yBHx>8^UxRO->`MwOu=5#*q_)h`4DA6r0}+wtip7lCGd+Gh5IaY6?rr1 z;{^&v+(`M;46;tY7`@tK=#7!{&bVjy&_dMl_FJA=y#gcvp5!P0B~C;IV0nSlAO8F) z7bDfpmHc?{U1e-8E9tR?@ef z9ZhsI!e3-V2L%B(uUrPGG7QBQYoLM)NNN2NuX7Ok28ia2A46t> z8<^d{sS=+3`mAvf2d2H zVv49NE<`uE1A$4J1^<9S#1)*sQT{Al+_!G|6LY4~0%fLe(VTr-pD@-WMufks7&$Jd z1g)(j983fVZlkS7AS2OH+>_J#^*;VL6USZ=I+&iO_mP70;@u*8`og1YA6QsYS$z0D z1R#gkc|DaFAa^v5aD%GjFZ=oXuXF!ey}-i`Hp)7}S&fH{M|WKyM?Eio~>QBJIn z0RzJnnKO9AY*dC-Wrir@hlQ*R^O#-bV*J#-{hd@_1KOMi(=JpAjO9UIUSLl}jnNEZ z&D^~`uKV=tNfV(Pw@x)yirb1?8n~t!JcPfIBK#8puuBZa@y=zsk3k4XE)-9o0rM2O z!D1cMeXJ}eiGAIF;F>YaB&_EVazq8>A%uj~Yw%Xk1_g|-K=|vLVJaAyF~bxsd!BeF zy$vh%#MqE&;8v2UEP8@iwu&D4kkXIZCqr# zf|_RbIYdZ=q+0UC-3zR2!kGSWG<^p!-T){j=7u~AI*}FRI~+mHu_&k**E*ArjGCmZ z01P?9$f$OnSRtN}V$7L6Bx0YOLx*uw(;BpZMJ)*dNObb&Ni zmiFGw8@v*W&;Wb&8UHSq?n|x$wtW%hiZc|k11hCqc21y`lnEI^$s?380!n5cpL^c0 zgfF>(tW%)WSVTtL3m{mqh~}hxX>WEwRqeMKEcX2R;QQ{AkEBYfO4%TqLbRhYd=gpC z2+r^bAY2(XOgTXdlO`sRY6=?c44iuavPBr2;A+EWKxHka2s z=33u;B^5x(<>+IWOjtW_T!ikk%L?V97l_uXKgd_ftOrZ%;{JU!8~u62BFtBxahmKw z8`J5&KMX)Z8Zz!r!x`+~SGdUyaXJT_NnluYll&J^A>Xj7NG5h;?Px8;`gKCxlgc1c zf6izyULe!3gY;B}G!sH>#E`MISW~=665E}Tf_~@4I0Q};ug036iz$)=BL^NYXa=Ig zr-+}>x2uG02|ZgD1Bv+>E%%8ZhffiT7N(jFz19kJ=sSY2`KJynm9YR*#1n~vvBNHs z`=l3QzFI5RkF!|#1U}ORAK5Mmkgx#PMr=^~y{)f|L3P{+Hz8Rj3N`@=??(4@kaphX z0so=G{yl~X_~`;BO0kQ!ZZ@D1{)7nvx)6m0oE1nULJ#FBf*9Tm08;}Xt*2;iB3>Je zpqnUA0lY{Upr_zpY$|}a``P|ic4jsc8S%bW#RO`+xAewqfBE5S_LV#MxYiE&$RZ|b zyylG^W!fS?`Igm?tOIReN?}zaj>3i;!WHxyFc9BNajrr%hwerNz&y!`vml(Zz*giu z@S8$SWp>W%uaq?P9Nso=Zw8t8jbkj-kd7-w|_ms^)DFwaL zew_kxy&$!K+({lECzr-2hXX$+5r>`NLB8>?Z!PTXagy_BODVg*j~6BQW_KAK=Nr4P zRIHNN40V5ucB;yGBHj80=CK!WK&B?qN3InJ1qp)^F=E`s04)~qCSUL2a^boq^GK3e zqc4$KEb?P_DUh}r2y1w0sUap3X$p}F_wh0#_k?p7T4uQ7wlekOgH}*C_|#scU#3UB zo1WnEVQ3uXSe{$Q&=mMh_B)|rmTyxP7SJ`x0{x;S?3bKy60YYjt8ed|S z^bvQ11a>lJ^tNJG>=6Wh`N?dc{Y+AR_^w6JVpuhsJcJF6j|qfI zJGVY*IDFJ$s4MuD!LMJ%_^G*qPJ#`VX`BNcBAU9H=bAIyt>n4I zWTBw5_njSPJRQ;SEFGuuSis=&dQ7Co-uv{ey}TZb4@;4yO$~imC|zE~#jHKDo7>uI z)vLJV^9TWXsAX%mZZ?#Hmdp$q7GpxYkplj7mW)*}VV`7VbktHk9NSxWSI0Te;%89d43`2-$(j+^6Fwv6|1F=R*x`Hm4zXp3@ZTOMB zpmHTud4-lP^K>v31*g6q!3O*jhJ-EQ^Wx?w-1GW#8q&#*YNj5HzO@^I9!xv8Wu9@A zSc&c_YOOD4b~X!Tsm+`zI)T@wTzH;)Qjugby(Xq=^Gu^7tW@@S!gJVjBEM9 zuI;2fw8sjv%!mB{^o>_U2AB$l%zPQ-7vrZ&ek4V9-%KpB!sF;}3m$JDc8=hxfP=gg zp;}siS7KL57B51{2G^Lges{8rXakz8C+*Lh@8DlqZlr8sP@x?h(!!#qR2b2Ol}ru% zaPUBIRGgzm{ ze=JX6;wdTsL2v>2k1Nrk-n+1y)h>BIug36z%ug|^Ku873g$j=GBj9gJG%pq;;{LE@ zv+$ID3gvlqg`sEGk}a6sCJ!bDEqxMTkuz-3Q&VLEN$YKNcmXkm+2@TJ#w8Tc#?GE4 z&nhyXJkcG>m#;@R5$`w`3&XrW4Tf_kaXmWt5JVhm86z-m1dSuhAAQ&%dhMhNOl4tz z-KY17GLnG(pjn>mUVi{UDZl_ypcuLl{;lVW0_2=$qC3I4HwJ&L^{ z(V*836`|o(5mX?UndVz_^9(b&F3ATbvjU5FCr^kzZPOhvh6kcpkDPHRI3{ka7x+cX z4T_)GEd)LkImwPCDr0-Nxi_ose|;a!C~G#78U>woXaa8gri}_Q_+iqm9HP9r>G((4 zs)FCac;H|P0*jnTjy3L1PCsh^go{_Oe}opXhHalc2{<)X8|1W*uKvn8_Z2Ic>(nLM z`W0?Hj{Ror@HI{+uZ)!b8g#BM-oyy{2s6aKf~hgc9DLkSnAFIY!09PHcn~PVa*#h} zy4FsKURcoRM%7#r2^3J(h`3e@F|09izG2s0QqoPA&$*Gj;>8$imAS)W9SBRHspC_G zU5#A%_O@#;pW^#S_Gs#a__#A06Q+EDSGGKX^27V~S~6{-pM2b$e|^p1fd(2?E%`xY zdkff9*}NeEtB%Nn45+k?&q8xyJ#Ubt+G3aDT**;j|IEUho?mtc&INKyR*7_i4h{W9 z;-M-|$r-=WfXIlRW{T0)VOWU`X5lb*$uM~e0gHwVMdu9=Hq+@Fuit2hoT`2mmlg!o>&}MO&Zhtq>uLR<$>lWuP19w zpeNTnpcjygujvBVR^ZVaWqiRl;FzhhXH-+x4JlDEX2|%tU@SyQx2~HxdF!py6+6|RmQV+cjU#8sFDnI@gyidd=#N*!L|JN7k9C9G8HBZ+{2{^S+g1_Cy7cgwCL$cKW6qu?ct>YXT7VSjfCx zSVAJxk#hgc*|}|PY4Lxvy$O-K>eg9=#woTen|?KWyL)N~^*{codrFN9{=JXV97OPs zyw=hD`^Rq$P^yzxnPvq)yu^@eH|^9@sX?iB>$FL-yo@-sw}t^tXY^gjK;=tfSe11d ze*r%hzzEpEN!`)w+=@N??Kj^XlJ>m6sZ;pW(3M$W7Hq&zy1Ij~c9E5MeDx}>J@3zm z)8JBP$$>~1&JnZc<<)ob_@w)ir6dERno)rl8uGALk20w=^a66;EEV>FdF!LWgZjcxUYN!p$*)c7nHFP}zv@3^0>mI06qgJx*3rXQPNAv%tPtzv4F9Y&5x(bUo~mw_cK{ekDWE7e0b?1f72I zVSNlVB+zI^nOHClN-c_7+xgZIK-%}8eMCW618%Gtu1?CHvb)IQX;-5ayV_02Va+39 zm=H~k^Rp72*CQebZdvJS>JB=y*6^vw(yHm@T~6Yt1ezHuRATt)uZ}~D&IbQ*9HNs)>}@9W-!`|L3m`Do+B;IQ(!tR!R8*JB|hUuj*vK^;7#IC$63&2+-Geg zfmy3`NUt(OWL=wEp@|O)sMAz_zw`QO@UOG=mkxr9%Z!Yy5ysf&6-x|L(rg%kycoz- zlg&V30Rx;MpuXr4M!*h+Uh|3zQ(xRb=98JorKjku012SNK*|$&z7n2O7LfE4*wA#{ zq|$YCWFrftb0IRu-`5_qCwPJHW1!{8*#glNDi9(jcKB%LHo7?AZ>s-jfSiFP0YC|d zUKMSJE1Jc07>Q~pPojoY(MT`PC1i9*FANs68=8!oLR7YqGO_~Hm;x`vodIJbKd6~OtYtYyGKo-XN@_S(BTV+%y?6n=?{Hp@R&3G%SZ2;c08}g z34%W?dGWW_p~GDKO~Y+NfG^&A%gC~R&HXWTEQR3YVh|+i?AF0OG5Q`v;2V7zWit6a z+Q&BjUe}HVtTSD^;5KLMuz`#k%>H5c8D(-m6B@SfBhsAb_nbHfm>!G z8Z7aJ(UWav5i!6-@}rdjBK8p((I{2|0bx;91;UMpgCEjQpa3OlVE{u(xJ6YFPJ`l! z=MU)5lj1#5PuGncX3KH=&MAvN(L^dhuLUwBo3f8LAu@psE)@_jn5jnW;}qSYEBQp; zZ=TA&ZRyX!m)*eykTc+Y4Z5FSNn?g?%J8qvq#uOqwSi^`X}r8x#TX)e#j@9d?&6b#}Y~JzWr8$(R{9LPt38JaHJUv+OIE*)}y1L z9czaX!UD$5N!@XX3#c|6hYrqLDUb3r3)$XSsC#M;_%UR_ufDRI%Pu1`W2Kn$1qKEN zM@g&|ailb0YBLu)C1!$jUS8%~R91tnP*4s8J)(%E+hgi;R8_rRhBo1bkkhO9St&XQj#dDhQz*xotorO5M83GzLgz}Rx0_v3&H&q=N>q6V= zDQK;}P=y1kCPg=591dwc6b=q)YB35)Bb+IlSFrBzulYFLPf84gY+O43)fcy?Qw~MF zBzdx#b(sk#TF98>m!Tvs5Iy4~tDO333OQ<(k2jj}7uqP$)(vahD5aSiPgF-AONi#8 zlEx1YhFb^4Pe2`m8v>jjsF0Z&gZEiS3O=~(mw)|?ZpvhoaI|*=S#+7b^dUKmv-mZ0 zXWbx0p?kebZomuAYymT(d)9~xWh)sD5<}?20HL8l&yKsC4B;Lcj{JoSl*z6LuHausoYXt#33(uAof^$JXjCV443OOO>}AK( zVGp1cqt37Q-8P$abqNKO`4`;bhT^wkR?Kn|$@WB+QLt(Ch!JAPC&}B;8yRjMA7KeG z18Pw}tg4njU2f{I8d(MM&5Ps+O#3{D3n7jRu?7Zl^W!SnD^U-9!GJo8CQop!c?2G` zrrOgU*o5Gmv}vu0IaX!pNw6R$m(#412{oxo4B(~XMo3@=38^~<3mHM0x&#;q;U^k# z{f);&+_4a78L&ZQ-xPtr11djxAbi zbxa$7B^YQ1JhOaYK=0T>y6?k^>sDW`oyb3~4Na_=^U^O`} zy2V7%HC=XSjUg*NQ}b+HVMdvO0@qF51lv%efC!e}?7g9WtV-=nSjHXRJWlLrqZ-c8b(nT1s; zz6?Ko@h3cJro*2?G`RcgEK)dB_U+H1`#AKc+`S7&(3MOhmK8I}&I!=Yph{H1B`QmU zAs$79I`|+HuM|z<3;QNX{L0kH{?K!5CJPXDwVq4x4Huix3LSQ{Q9@F>cw8 z$RWINB#F-d2#Hh5m4kq2~w#{DfsWk z@xNm(p{L*@E6mhhJX3j$ZV2i|ysHa9+Pe_Lg1U4F7}iL4fPaNchLp4jJ~6qID-RlToMlwduFpmNpz&T(c6N?|E`l=et?6eh}GHFy-ylQPPlZ z8a`CyP}htFz!O#mi?a5ofCA3=$#;w*vQ*r_6Ac7IjmYSD4wg5V!77!=%L zG))vh?e~;&iT!et}AiY- z6BDyM!|hssVG|V?T}IqHR-DX-vGo3~7eLxfBIHXQ$8G>Gj6ks>pfc%!7nobJn+SP^ zv5*47T2SmJwwgyDTgmAiCqgoI(RVi#8SYn7j_MRMhnz?lfH%GvL^S@)lTQ#nVuI|<{fiv%@sl*e7ewx2mJ2Fm}jdP;*a+4TQGBmMyepF`1Zcn zKnnpG*qXHYp;eHNV(t(zf`G!yV4*%)Eyl&3xdL+tHT^>GoPJO{>Yd88uN^+qRGy;|ms02_BW_)To15TB zO>?-UM9Rz_!zyR8VF*pRibymBq*DqUdEL}Cw30l7T#!##aq*zbo*O-DeE8n0M*4F; zL%DhGb@aGHQ{L8S81DAZ!aa%3W#Ps<`<%2;LY&PwYL7qoM*+eQKeFE><{^R?ka54u&6!pU;R!hE9J%mu()+^3iK%bDmI@Ua$~SZ?vpI|lXq#10|EFfSQMyu&%PV{HZxRMS)FhE)}u^b?Ob7GN%4 z^Uy=B@h`9=quzynYWVMKA3}uKLe6Yi_h8oSE6Y>8bJlh0=$FxF$HIwkGybA&FFd>D z`-AV1fjX6(2hJL)g>(Xd@kWu3C=*6lF>mgw*)#5$I7XI;_cK0w$MquQ6r5%U|8#*r zX|ZC$&U;(X3(M!zoBHAp7x*jFk)uYMh%`+j8B(5-+giD)sZ3cIP%!-JE6Dj|3}~=> zvQ^4}b#zQR|7;CrpmG)<)~Bg|%sIwC@oQ(lb`TjeHlr4W07z+UIiLE5GJo(46~Fov z9;*pFc1s{G%#Wj9>NJNHitJe(_c$%gO9Sm_EjQ_ZzWz)z%u4W^%*`QbxWLmn#qiII zmr4YL7?5R>+e-6e^HbvZ0t|=(Qb<4pI{+}su!Ivlgdc+f{B$MQ1HUuHZtUM*@TaqB z^jgDYT)-Gsa^8w{h6I)YavyHulDuSAEcE`Si{$!-RW$F(sE)|9tMh)pqLI3{+ZRV|vGsE5YpFot!R84T?r zW6)w3DZ)8#J$6Z|sRI?SKD)U%wlj)IM9+|v!|S;WepsRlP}t2Mzi-)}UfSvv#>#d` zNc2E`6NtWb!AC*jit&ALbqQ{(sn>{1T$@|9)hBom{**p5*uHc0g()oncAiBPcbJ$3 z63C$roF`g=Uk;20lmE~~EUVz8Ct4XQVqjBBWu^i>C5RymZZcFeZ0<^!2p8x5&g%FW z+1BQ#DG&kK;h*vL+RHm>SasZ=^f1b;S0$;SolP+4pa1Ct+2CrLe#OH06rB+b&Y>OV z$vXJgHKWWsb_vj;133T>S)+;wKmGLw<6fGj&G)TnBdeO>O)e5?@{^$y;WQli7&0A3 zUVpj+drjT##|#lAPAck@@$z~F{qmDPT2f#fs0b(%tk&MzI>SvE2Es~SibQC0xL9cR zVP+w?tv_~@AiVFL3ulUW*sMk$!yQf%T;!FmY5DkZ;|z_-S*y!=h}j!QYrXdngUC1F zXnPQ+o>dz6pOGwuQl0Kd{nnn=A#z3_%Yy{9V#(;HE|6vxCOB_ta2!lE^Ra~m$Ck4o zn^D8i!7gW9TDfid%ifl?CH^V<=*qJE|N=VWGWDqhEj!m?BT<;Z)yw47HSvs7W1!9FTv{VPj6DqgM5GW_8xYZf{#15KxNJR z{kv}nF6T`UyNYUnZ9+-gpgpEO&J{4>_KNPdP63Az{_8Ev_GQ2P^C!Mc4tG4W#e7!E z0?y_m;?X<93u`sCx95HGIb%&}NRg%e_q- z7hq~pi#~+p;PQ%diohs95!k6CYSFh_**4RJmqUB@lJ(a3W5aaZw+&wY{Ly>TY0^i% z^G7C29+u;Z6m3ntkgRT5v<>&@sc%2|(DDs06w}$H#HdLJ#l0d?1zmMb!A;!UZBfQI z8-TL#8IYJq<4Pj}!|bo0eJCg)+Hdy^VqAB`Nl1GhBa4WG z57LI%PY}X0@>6GBL@zVbYuaE2jKPC1fM`JC5Am5v;Rv?9m>5DCDZ8B*DgE`66>v_v z?Rh604YYEeIl><8h0cgL z&8A5nhdwq6-u~>?l$p){{M(N$ZsD1qu3_wdIM)lE!UC9x&yI!lR0x!U(@oL

iLO z`{{@8NWXmel|zRNNf{l;|MuM$EALt&)!9!XB+?-9Y=$qRrq?E^CA5fNnQ|o|{VH?= zb)cwg;u|vC34Hk*lH@5DSzCU(eDr8mDCvQ=s4d(?T9QIqO9eptj&-ZxAJnBwZJagP zru|kEgf%=Ru7MPKuW4omNHTE;X`kXwb zq_CoMPMlL0*ovGEG9-T}#wyUMdv2T_Y&2BrGf$$n)KFTL%#kMpx}sRJ>)~I@y*98I zDSek5R~O0Z-Gj^SWVo9CFejo5rUO8cY#~cY9yJG?csyx|9mw`LPyv6+AVfQ`h0sS5 zudNs9f}%2}O+`{1>((pDEKp|M=_oketKvl!;eyY=Kr32--cGE>NH= z^&NL$1ZXFI9mXGYt;x*~-hC%GDeB|!X6%eERBde`6-z%CiO%u!3*pw7K?Z&V?Wh*CVbjolmcs7!n!DkFKwedjCK_mao z(b(aT1!9Gi3^7>~tVgeCA@)V!QNTxrGg%az7$ajNc1MF;FleB54m#mjBn|#)1b?Q$ zqGKLPeXu7AM(wC%qAjGv+iUVRb%owtLrf_R{mcyHD)VbuSWQwUxFW<^_WgTnse zbfBtOIWAu4+f5{&?sM1KK>F z0Acy-nkhUlm=GQ@vZC>PMi*L4p&23`b~(uAOVJ(DUtI`44&gx~sltSVSUX4|5@Js< zXz>w+HlWmyX)hEb+~5sd{lw|!fDn2_Hzg~(xTyjbg@g94n0L~hLwua#LvG-1Or-1% z_74~RuwS|}{VWmf*O%DmO3x+f4>`c2GAuO30 zOHY&FhvC-}+iJYiprL3fgZ=v z?51mNh(V-JA3s*6MA`}enOxvWJ@Rm2DDJRH6Ai;G_>{sbK35It$H}6Lbpc;{sHEsG z-`)!|y2iT09aiwEOn_?!!=b1 zf>JAXRRDhLGW>*7dzuZW^ug+11D2iN0iAKnKLVAmq{gF zFpR;!WuE=JmtX>C$NEG!5v__OBpb!~!~VYAsx1fb4pV6P0%q7eY#Sn!Q6cSzYNq}g z+0J#!K#!~*!uz&@q?nLSn|PN#{S;B@1{(sQZ%@poDb|Zp8caTb)XB3YKMi3 zy(wek2K?y5_WtIRkG#7c&wVal0(6Yk4%(?|pq@X^}F+JqXW(+ev5 zqc@9FM#SNCvwln(Ml!&Iv@O1Mmch^ObCr!UN^r9G@5Mryk^Cl!0itTem&(}IA7Env z#D`BOiF$3o4(jNR@p9;!kg?^I*pYdqHFIaJoq7f2v#*SZskbnK1-#}-aff#DqfMBy zoOze*B{EGCJ}W}2G7t*7rlv$VJr#iu_yJw$`_lt&>S@Q}kKhuaL7Nl83B!rWb%ua`BV)ow*3lA~BVxsl~Czf;ty7Z|R$1q1>8;mu8g}?!!$eJ2*WL|39 z%n=tlM028EwpHE$&LA<}ym0!YY}o|TsMG?xYq>qywT=q@$d)2@YT6YDA-jl~7zK>! z4iwSU3KAh0iU4GTM;-C2gm%V1x#1+!7v{~6c+00>XN|hpN-nq3X838@&><9IBHi?n z0d7yoTI?Wgm?+s?)EPSuxI8~u`26Gd-=$3VX&z?OFt_5oU{AiV_5%-L4nGcAHTaq( zpR3^K;5%=o>{=m$*hS8mB|q@uvkLm?`@sHvR%sDFfYCME!J%Fl6b1GSp(JfaeQjXr z@mR4T{i1ExoIjZ0g&avW_OLP|gV$EfpXOT-Rxm2q{F*wUCg>^?`&htmIEkAe zpNiM1jFDdz0MFzO=a&o@b>WCfT3dh9G=NWr7t`LkTzWDPFU!F+_H^%US8Qe=`dePGFVERb?sqvHGp+Bqhc z-dXM{#B^q7<5%X8Zyysb%xSbrwk?ar{QDDYN`}0r`(`t+6NsST#DX;(5mDxH=K)ng zWZRlSwt5S1RQmrct7$-eQ)ljgJ}d{!3m%LLW1%A;!57%L@K$t|5EaYTYdZ*Ga|Df0 z;YC9XicB`6PoENTB4g>rlMk;kZ)HWZYF(`e;RPFQg+8|TI0$} zvlct72>Zw1|CX}w7hi(|>%-0=9!tRI(T7EW$WLOQjAAP21sC4QTm@8n|M+6cRJou> zCIy^fO|fAVq{>sWAHDM?31bwR>V;{!g2V6vNy~kkaKU*Hg%?~U#3yrrS$pPy{sN4s z!MZR&@W~@eLWRgGrLUdB6bMd7qp*oE1P5|$b213WrxEzhIFGxX#~nnFt#9l*%5cIO zy3n&`l@mTuWb*BojT=q{06*dHPg5liNJjFK5z$(rMn}TJ3i?HsDi|yQI>8nNioh93 z`)2ew!sS&*9pz(pCPQPPopMBCJzc)|g9-I`Pd(nWWLx5NaNey}5)rinw(#1nCpUmi zgbd@suLdiwR_=zsM9AA_XqD`v{DhaS3&^W)y&st>F~xumsAOnb>FUs*OCsd+YuF*> zR0!--_ACBn|6>7zf?*94FdN5*?!AY>Z!*!erVVX0K8@kp7+E2DcIK#4e#=@`+0+{& z(1z{yFk!6$0QW&wn~Z1*j_0UrO{KPkE7`xfl|97lB%Cra&Rnr>j&$-73nj+$ll>4R z?Wb%tH=|1@3)Q-FV164=jGPKt=8%trE{aG5iluf+O{2=VmEfw$N# z1b9Q54eU?dXGCH!0F|yqqp9G7>1=C;dgOyM0>x*Y+RJ{PqN&J&lIn;~qY`-qhFdQrj;?%Fe6a1L10DispV!mx_SN;8)KWC>P4fe6X)>v39X%7JN+*q(riWl>gjq%Ee#3@Dx7M)v_ zXRvLC4u(wcSZOLJBDL%w>+FDEBi)UFB`|B_FQwv`do?wTvQ#f?hi(aJrU&G6>KyfoasyF+D3_WR}E|H?FhaFfR&9VKf} zARp#ohDE9i+Nl6b>>r0#In|pLDJ@ozGJ6}Rbk9NEXv-$sIbyCb+XQxiTr)^Q+A8=b zEn!Akcl?q64S*d{-ed<4zHRL6Cb)^l)FfpgIDuSBg1n;fz32+Y7(X^DwD6oHqzJU1 zFvkLrjA6k;^Bn4tpA1b*BmBjnlBBAGrr_ll8PFbbt%qLVDuS06Cg7>rUNFH0&^8`1 za|lOBG_pL0ID){0R-`)cK=s9@DBk!W@=O{y^kI_#VH*u_hF8lcsy~)5Z4*~ys}poq zMR9ToLvqp*Q4&A}S>mia`*_G(@CH3-DVJfcQ-2S`GBx$fJSL_vxa6v~`L(Hki0tV^ zO%CmR!VK$qXsuX*x?h82-^wmj2#l3eXyKhg*YCDM3cm9PFw6$uFvF2IE}DJ9F~=Ah z13~1{5jrkOOg78;r}gttaS{T-LyfO_Myi=#W{ZFg_uPrdqP0VN{Z=|3*b_L;v@WnM zB3TPA^f66FsTDJ#Mi@MumXR{;ka%G}*)&+0{3QP~vFH%N{i?t~!mU9LgHT@*{AbZc zqh+HNj3buLKXnOq(oGOja6?SQF6!C6>`CQA$-0kJPr|3EMzX|3El?&ijeDt7gXi|f zX=(`F-QXW=lB8+^h0ViYz$3!HLN0tdz;L+XmKkJ)7Gm?_1$z!!yyW&6X%4mg(xzY^(QmzGJk7|vacGI3Z}C0ZefSQF93mQE$8^zKNNn`e>Jaey{w)?L3 zh;`gCV~XIIkK8tD!t%gt&mH7N@J%%@wV$^o<;kIbvF;SKlSdHe#f8$A_ zK{r#PxFEmc2=0<-p@50E9&`O@1ifR!YpOUK22mM#HBuK6xPyQ9fpcey&2wjQ=LrOt z2$8wmgC<^nnM2PaXM~cH&m(?i=J$pvleM}16ZWyB%dR8P`|&$(2<(`rustxB6IXq zH}Q*?e&SXfp{ITo@6%a9_0;sxV8BpusVG^m-SJcUf+nq;cd{)z@6VZhr_gr4Yk?AU znEDFPo^lHLF2Jj6A)|JAju`@q%q)pX{4)Q0VS%6ZgOLviVsK5FksWSJ`I>D337IfW zjfzNyF@F~()is3#5-r@5_7l9JITDGVxU&zlguqEgG+OaeWx6`A+TZ{7xA>9{QICXI zFdR%ELJ~U|N1O{(B&sv)1hyQjOf{Hcu0+BElAsWSpSR1bQqvH_Gx_X8G)Yr$s{P6M z$G_qv4*lJF`Ec`G>iEb}iC+x=Q=tkMlT9oklYM~ z1~-~?c=FVR!7!=@LOE>9!EnA+RzPrnZCN4M?s~F4)Ae#?)HVdbuZ;f0DUNW+tYwf( zA0lLs(LGsoBEvl5)2ui<;b?ZCcqnV+V) zEvj-iQi2|7H-Yzl4SB*We8wbwBm`uRNi~whjy>9->_aLt2~r^Tac*D_Q5XUK0UrAp ztW#=znZQogVwuMgppcO+=H?^l`u5(}{1krllSp_|2ZGH;7uy>lhn&Z_E%<2MnGHB8 z2)=2gAh0`ts0fM54wZ2hTKPs#eK})br>Ep+W4A`BIAhMg*-k=@~&FFtE00dsA>sa-u%#t}9Xkj12o>;l@dBcwe9MZQ~*x0rA5)Be-~ zICUJh1?3j=DYupXUj_J&z&9ew@M8#29$Ex6SZLmn_sFf+izjz>E9T|O8>ZNvw7iv| zbAUjuY*=IJkJ^PFrm$ITTPXLdi)2~Ox{WU&s;N7Il9`w&okCK2+*@BAN@(!{5fn!# zk`Rhy+&RxxGzDyRTQ1Q^%2ZiXiGAo|r$M+Oz`4$_;xGmKf#d08WU)ytmQ4uRrE&)1 zq6!}Fe(422c|5+8)w5{QxTfM?FN94j%FdyfmEegR>ZWae;ontkIkWkcKDz=+^~=_* zW;xl_Xb7?HNr1@Mv>?j>iQ!0wF}LUq%giCli`%8m3_>;lS&HmD8uq`Fbew`A!>Vp2 zg~L>Zm3`)$tne}lHs!N`MKk1V7zmRB-gBg1)-`B`6*NK(qkErhrv9sgAILN#^93UG z!nM2-(%zrVSlodei%QiI%Y+$$vJMzXLBE*`W{lxD#0<2_{x|-(bEgY^cxU8Q%DxSp z%H-ZxUwp=<3tupqw93*j6A(tjTY+xf}2PwM-QNJpjA=~_tHch^D= z+pBWuo9)q-0ZiFgkev3YWb0lr=(L&VpJ4@@#S5~{MSWq9azs+|n^0;PP*t=|z~S+g z%Vev{?c_s=1tn(&*%g}lLSaq>3!!wQs$H5TVPR&uwLeZ8ZW5kUv>~KJ0Qm6z_ske7 z`xN|F`L7LNPxzCBDHM*V@5pviSR+y$iwO$lTKE^?5yK~Mosr2v4(BJ~ZVr34sch;B zFIE!+17SI^w#3=}^yB(S(jH&cnX61j7>!~=AA1DAu*VYQoHAjYx7*v^!LW`=hG z$f>i#BxV$f(LtgT3@|StkJNm5jmHS^PkD*f;$M)HTjGg!j-mok$%VdM%c8Jnl>ARa zU?8Ybo~BW-O_NM2^D-t$wUBEDiWaG1RgD+UjTBOTZq0q|8aERSc)@MmUw#X&R5t04 zTxcuVgC!6u<(qtifv#tiqX!k}2&u?SW%(W)_Ef_QLP@q|VE)gXL)l zZ!$$jmW&z61kAnfmMvLWThAofH*nGe&0g*59?DsrcWvz5fd`Wm5v z|K~QYvjJm$NC(&38*0eOrt-38(^&*Q77*+3@-oR|Y#xW|d#>*^+XlZqlto=`D=#o| zo>?VC?~IRp5>|@fFx>isdAx~|tQ|^9gWW`#zR;xB>~Y>1A6acsN{W*FrP+f^?lj^< zra2e&NfL3n`lt?b3W7^WDsU|qS3@6NI?qI^L@d{`|24a*IPuLQ%^EklPnw@-Uc|eY zYJ$>kPAUrA3HZ3YeFP@r59W~81ABt8JoK(R+gbJeYM-%p-+n7)O|qzsFCSP2z<$b| zbEurZ7V{3A25he`1g~oCJR#Qx^Dul z7R!94_tA^nOC51Wp1FOl@)LIc<*$EZo}Mjst@-j|kyDO8&Pf<%TEH`pn{+k$08i`>A2y7BB;f^o96~s26C;O<8D@Gx zHPC$|6064CF`r9>md9ZYxHpGV#O5OD7jsntt(Z=}q9=M*F&*n-919AD)Y%Q9;K^0@ z_|yJ|tR8=v=#~OUz$MfTBTB(XOZX9@aDLD*QYhyQibZ4s(KtH&Re^Y?i%CwSfSvhV z%7kRHpv}<9&vCi>Ivx-z|N)-bR4w6sh!RcLLo(|46@fl?V!jK z0Anm5Vxv_&;-<&R>>^^5b!XCq_ry1W87)L=-`a2D&mAO_ld^W2FL&_m4u{J7_t<%3%hKEBipU414sZcW z5@8{Pg-@g~Q{l>Vn7y9tZD`uXMkwYY?fV4(kdLr7y|G~5)PQLhTbr8Ev#t%D=TE-M zx?mN!YAc{EkzkWU=L`PVt}&GyYLG$_7c=P2lxgCdW-%cs4*2)2 zKK$b&@ZeN3Cx9g8iu$0~;slB;#OQn6F|mK-)!SY;Pw_eiyI-31hLDC79e-H@{t#lO z+e2F?8p1745JXaq(4_ipKiFNvmM%8mC+H;MN1I6x1`p^OdfTrFr-%ScFwj%-oYe;# z#HQ9_VJr}7<0lChh58lN>kmTYvB-F>&f8XcgqNQR<3n7h5WUT zYcKy*K@65bh(vhbA6!|}XOt~EkaO-0M5}MP;h{O#t-5K(qAN$R^JSH=dDcw5QvR){ zOFPVa6Rh&EZH0|qF%dIT<{q6$ahpFvB7&DLkig!?((Pb_fCz#wOyU@Hy3$yS(m!$k z3g>+w+y+gtksJ!mk^f*2`QPH7@c{o^U5H{N%UUU8Q06k*wJ6P$cpb!OlW3yTP=O=bxJNzWpMQrI-$8w`b3mfx`%yGPsissbQMx4~CgE z6s2?*7-Ke%9W_z|{6tzpJ|(O1>O+wpG14I4q3&Y`kXEg;Y5a*PaXDdFRtXl?LE$6U z5*=7i0G!+4S1^@T`zwn>I3!(|B4?q8u`Du`;aQ!aKk+(28oY!Oh zsbEf355xeKpF(_7`;5gWr*BhY1lV&4$uy(+IYcp3s0_ryxyTrY)Vi3$-t|OlIe9Vo z9k69n+kjlHvG2@eO@9q~ z&rjt3|Mgdo|NEb3UtPKIeDKR-A?gRO?mxd+Am`yS^1+)`j2-^vS4^R=sQ^DYmBxZT zVh!2NkYqwIbsVvzQ9L;Fz1vCE@lQ6VgrP1zFH$3^K0W&Kfkytb!I;E#_7?2JWloR$ zJN{ecf2;gIACpZwT=Vb9&;4Y((B*%t{ZB-++W&|^O%VQ3DF32C{;w?H=KlcupUX-9 zx5j^3<3GS37HAUTg66y70+Ro1`ofR@Fqm88|D+$AlN-_+|A+R*%Q#;b{5uz50j}-^ z9sf7~0seKpC5_(}RgAOCHg|I<4ECkQ9%;{u$Y z2-^QUE#O!3KQZSEcm9v@7jYqh&%UCSF)C^Z03(=AV|dpTyVmu;t?Pf||3=iaf*SCj&kHPn$cg1Idd!fBI=Fz= z{|ftSBeO@seB&~3|M;V=`#-eq{{R)B-oQSLkeE->ej+Um9=YT>(go~iE&y9XMA7U8 z9AVnw|Ihb-Fzt=Q!t9YS3Sjz;%hvsWTKE46_!|~DKN0-<1{jkMeZ!2oOeT++!F6Hn z|I@nvTV)|+>;7-&R*(hT44y=OnuPle3ncBEoQHg3pU-%K?*Ar!rRMY(M#c+Kge$w0T=ww*#F;zACXTo9~T<}0DdfBg<$LXFRkal zoNxTc9f;*0E`S*ZkHtQOCllH_qYLr;7nKKlhVN9HnzQZa#A&woUO*7F}5$sa~w z_GiuDg?|1c7H0ozOQKkomeXj|0ToajfZ7FaJ^$C@cTQjH`M>c3us|8@{U34uFKKV& zLcmkgG)gRpBhM(}0tEl9=fAg}{|+9a;sj$Xf7U)b8BVO|w_ymg-wJeFgL974z=b!At7k03TO7yMwj#F&lwg#-;P@ap zir0~yw#KzHgDskEmW5C45@TZ%#riV^{p2;2ABx-I7g2#9_2;i-=8%6<;{ zIIrA`Y}03Gz;J+;R`rI@HaT?vkwy3Q>)YpC-tzy>f&J}xETCj_KXpb2d&mp5nQNiF zw&Ar0g*^)Fbm8b~`9nG-r*K;b+h4-2P*wetoAyStIgGd4JYn}^tDMjcgeMQZ^k0AY zmQCv zUa;k+jWU9E*1k9i50Tj*8~+!07!T}!dpD`DQ)~U?>~#cZMNgYnb^rr|e%D@QnoxOZ zm(Dhovb9vdu3b1*PDiqVm<%>@*IzQ^b8P=^TU%Fk4IKgIkU{&>*ipxZT6TeO5P)o6 zaqqMR1A5#0QJ%_KHkY+UL(Q~@n-gm%|4n~t-ahx=I7p-5h*kE*%}c3GJ} zZ8Bc7(+g7PhynRE%GMv@k$h|NxZy(xjfEoz!<7RI9JK>KiuI|^ft-}E2RmV63uQOa zGbD8$rT5w-AFJ4N4}}#=o_zM^!50=zk#>%fvuy0TBfp(yeQSb`#PSF3)4xw|+2SA- zIkg&*VZ)ZzjwBEXu~iO86MeVz?Tf!`W)A1>Gmp^|U~mVJNEiZepB2%wsvMP~QA7%E zvOkXuZhE7Aoa`HOYaefJu^XWs-JND-_b8kBsK%m+V{oW#Gwt&xLq7Vn*<{RygouFb zJqt?c=e5_I}EpZ&)95iSSz=|!617j#B6IEQwa$Dwvm zRDU;VGzp+}(}q7#t#v8t*=L^l>tFtyw7pE7PK%XXR?el``iv$tTWr1b+|$k8$eUI# zU%POQJZNHjw`}L@o22S}bvs)tn`4QuHOhIrvN?Oso_Lz+1h_fVi`>uz5^3;&{u`Dp z*>wNx$M3ld0v*fs%ENQd96gjh#}LY&J!kxhSlYeZ{nIb+d1L)@yYy>|zqo9GjiVvo zhJ;{Gl_=JEE?$Ia@%Q0Des_d_$tZwPrbF4H)TR!+S%vL`XQwP(R-|sFxqBnkjtS6-ukU zP7NJWLz~=wT|0Y#|JM&+tA>r#Am4U^Na{u2;_dc{vahmJGaO7q-8h0ITe&Kk*m2sd z{h8@~Ft86E?zSx+Id9W2lmQ-UG@@RoaDItR@XO3kxRTRxmOZOVt5wV{{g8&I-0yzl zjbw{w+tzKc&EwJ;Q_yq4$RT74f;%19FZSO6@;Xb)$bL7y_v(x4jA2y9S!RyLkOq~z z2HyJ3Cugp|IEA&0y}9@Kd+s?XFvwJnjc5H7*09YQ`KiJf6T;zK0_KT&JE7rpY5lIw zQ3`e^lL4?(9~taLmSaaqJ&a>#AwMC${fNklW{c6)^JXGWp0X>cP4H|1T@g6bC*fk) z)}cw*$6l{d=t$uZYTaaWB!`fqJUM9#(+;98vnD?==?;JHXB)8tOXh5yKGx+g5AFNv zygkRz+%A+Pznes*OXn(@$PM`=Qc)ikPq5ki&0djCA+&oQ3AX*Y=k&PRUVp`9=@5hq|UeZ&w6AJssjhzOSsOtA#7s;LS&4p~M4&4GVgQ_}VF z_nb!#!zqhkk>8E73x>s_{&L^>wD7U2TlTh}b}3McSNSLejFv;(2OI-_#C zu_r%5!>JOT%Y1S^AVFcnXD5uXCmBx8+$6L;4iZ6y5^N@E8#;2#DM%~k&sIqphW6@l z=JY$+o{{8NCHv7)nkc4(2n|HDyFN_H50gv?TP`yTxHd?E*X)pw8hFrN@#MebLNtLt z!rB26NDv!`b_o!YM$%8-Iqu+t2WL%JA9t{gKU-m=JQEJSRe0Et!Af(K6=K?dUPEkq z>u3Wt_dx_^VT7tv?;YSCE77T51S9zXEtP$4*DOP;W_Qgemo26#JU*yf7vEq&IOl8~ zui&jT_;)5tj#iWn4oN>ax8W+Lkf#atXcuV@Gp6ui2Tg-0@(TyQq>1(u@n42rb#@zVzFalPQG%$p1`)h z(^!7lOZQI&a_~;aN$5m({N&qBlHb0X^ny2Pf+2Xjpfj`cZKF~27tVrq38G0qVtM+G zypqPJdJu;Wxc)j^w)*Z7?XPU7rC`q(D0=+*jSX1f$Yc+PZ4g-9c|Y-4d;DC9eb8dMdDEh4tkh9Yybu{VV?1T zzwQ}2h?|Uh0f5KD0y1!x-#YpR6uFrXC-IXLZ`h3Sxz!IpJbe;(fQCgS-aRfrKxz1Y zbj%Qknh~CMnUx53+dEF|RvsJN^vUMn(<&OQgF(Zv5t$UckFfWbf zFFe0ZL-a3UrGK#u@dzZI)sQwUjb&v!aS9H@stn@?Q_w8g|5hOmC23p$_5=JY(0yvI z{m(DKJ0X`=i=V{nzm&4Oe*qzrGp02pCmINw9C~&Wkl5+nVJl>*t$tnb~UyDi!AHTU12 z)fr9)fPcC#o8JPqwM$F|1oimSYggJYR5N{?F6#6#0@JH`b514G=?;r@W~D7Co!QC- zIC1F3VrSN9heMLep9BEQtV1=ns_`uCW`Lca-0@S}`eyD^`kY)IlTK&wknPxN?Crx; z#v?MbABajD4!a{K{1-QQ`Xs{NuP`qfhLZj;0=uzlM|YK-OHEO8EXAB#dlD=N#lTy2 z|9t#K06J)fFA(n!>8Q>)yy6~m5;cgauR)8`1bEniPC-NRPy*)lh5NupUm%w>(@4qE zXxQ(D4!t{fBEE=gtpL=AXH2%WvWlrQta7h(0b3M@`eWT`wV%*O{!dOG9XF~RpX7sK zNdrzg=4!*ve0T{wNch}R^(aS|)`zMvw-iXE>v3GnDgXuz0dfy&HE)*|2<)|& zF#puEF0be*Cpg4z?AfNcy$?P3Af*}pwJUXY5yuVA#c*U#+xjum#*uAKn$QqY4$)EA zKy${e=IBs|I1^KB9!-mp6XXNDE_;2+EZ@5yoJC)A&LLcFiIF+u#{i)iiw?>k!26RX ztil&aA-{&Wsder<8ArnjH~mOT=oejP7igA`;8;9vp`jAt>C_47{QBfW_iuV+ZIOqQ z#_=4rNhd1MVFzUX=EV!xUHhNeY>0f*;)Pm7TsR64r;}G~fQs+1cp<{lSvZTWmCd!} zOmE82Z~?JN5r}^}J;4Ulh~q&#MQA9TEJpV8KaeBOs`}W$j+b1-Dppk(==QVX>MGe` zRs3I4B_f3|LCo#z*YO$04IAR{Vt80Lek7ZUJRH>F8l8oP^n>sS41)n7smHY!uoL{p z3;Ujbj+{hf-{hx1fdzy`QnO`{+C(4>5?(;+v#e3|ASB_I0_ASF59&yy)tYI~{4|X@ z{ln*&bd4i)D{=dPewz$ z+8wSU0V2`U8TXSWa>Rs*T#^P1Me{@SK7{KpGELx%mYg(n5U%<9t;2*rcq;||fnPWI zj;Zt1oD#=#45)44?c49jIl(3NIqga8P`k0}3;63C_&ok%h>Lm{PbyXT(K|l~bPssJq3EjPh6+hd7QRWr{fCQlkt#Ae|Es zd^_w+g@xs{R6x(K+C@R^SijaC!b&;V4gC#sFi6<{;0@%SmErT#CzQ;jan>*nQa1=u zLd-3I5gbUBh(4l&1M3n`L6oyLmX5!RaONHJyH$gy%w_O6n|b{`cOoh6gSL}<+@QM| z*vLZNJ8+68g*dEvAQiGzFS9nCkWS|}@ixNf;9O&aBrQN(X`MusNym-}4OhJq8CKuLn) z+1wtFVKgaJ>hSh#BD0*6U*R zpu$bi5jb?ktSQ}FT6B}jkXN4`JETX*e`2bt&%wkF?$F%=7pxt|l>=^w-#L>f5(st| z$8;D7et>Azh632{c`X{WVhpIRI7jcc23Ry%lBVW z+|G!BI?vvG)#Y4f9`3K-fA`y8e+WMxy!krAhF{EdAr`_cguL)?bO#pTD2Wz2#V>D% zpTS*jczOG?++>HOxallEWK?0MJISnWvu8}7an~J6Q%Sz03OjF0&dqbD3ML?|@23{c zM>O6UM*}^b;28sAvA^cxwx7IzO6LkSglLaFxPa<} ze9fULXxsCTzx?9kGrS3w3BGgIv(sV1cS;sI!PFB+Xa)RhraLIW_S3V_Qq@vRV*y?zF|y-qKvZl5S#-BDX*7&X zM~H~BzI46LHCjsOIjza?G$M$!`(8S%A3sH%>0GkZlrTfgB%z}`&>z6NOtQy^jM)>jTPo3cN!HHuIWuvm)1pbxt?lm6|t!OBPfU)Ya z864G7)dq$W8Qj+*&VueH;^fpEbS7Rn{*>&dSrgHUj$rQzkDwBfrM((Xh(+L&B#?|~ zAu^GLVuh-n!vDEsELn5&V-dD7@XqLqRN_#y9orC zsk5}qm^eWIAGazBO?*fRd8(Ece{1K?bl$PXmLFPLdfeE>SPwE1Uxs%NY*?e4a@2)` zIJwM_DI1pu{((Ug&Nu$?udY`;>;~jyIH({m=xQBKVFh^{60|6X)4BZBnKQ^GaV5|F z>MQqcdlnejQSLmpWDzMH762i>b38S=?Bwf*;zt88?CEH>w4pk15=H-y&p&1c2++X~ z0uu5xwNcBeZZ&2>TW202IHmc(l!?#HpLTHZEC&hU1(HXBAdQ=dDInK7VDFMH^X(^e z2!r@${t;`jW)VbAWHcp!Y9^z-QL#O%DzPkx#WH+(Qk04m#BeANUqF<8(AAeSU}P}H z+T+s=xKZjQ)N2yb5QYIYyj~q}9gF84q~yo?H8X zBJOtNoVWq0yKeFQyZ{>3w}XD5O900sVBp&yNJI-r7sGPxYV~mkAGw2u>ggL_5Mtn= zuc3<)aYDU;MOZ?ja_m&sF7&2i>zbB@ghI8_4yxnM;Cd=e9FN3kn;eXv7j`O>@P~gN zR_-qkzl2R(A}>V%|2inyonS>KNQ0kP&~Hv0ZsPM=>hQH>6XIsS>2ZM9`wX4}gX2f^ zz6Wt4^M+Zg6>y?yS_&07U1m46nwv?yq_hniHhl2jX&mQL4;n@X{qL>0o?QsLIV*H+9DXOk9otEI~e)d6Rmg zygJ}zV!@xYm7mzKf!jqdptfJJq1VAbwq*w3WgVw?G!x^HU<^O3t&P+o4JBdP5~?}~ z*jd{;9X;8ZR3Xfp55r`2UK{V;=}48T*S08ET>`YyBWlQO)0OU5kxQrrEVw4}zrDG0Omf0f? z*%9p_tWeb)8$^C}-|kzxc6Qt|`$rz3TA@qrQa48gI$`RDi+}di+$oSxA9)2~!l;1% zmsj5Bq!n=ng5rg(&%~-nLx0iEL3{4_6@a4%h*Pw6Nfg5p>Fso80VUn!Eu;_{CcIDv z+=mZUE5oCP-Bn52V2#R)lSp&McddO`!iQR9{MpK`hH*{4(zl1V~l4{S^D>-92@;F8}|^&sJ4Sim!4 zUx6eBA%@3eFe61u_7fFw|GYUaHHPWq)JrfEMRcb)7yWM)e2}JzjC6pO^r9&fjp;ZT zQP(e9FxNCK9c0u=i_k<4%3O@6# zwmkl*h!7YUsB-+)`0?ZQX2a$huEJpNCep#Y4=vBY7MR5{L_J;>pw@RJuvWV%111$f z(0sk$_u_IiHtC8-*!1z0{n6 zDR+-8w$`1a?(BRWD~nNt9rOb5YmQdqacM-*`x1s(b%#3R3yJ^>VBYI4xu|oS7UGMb zU^bK>;QjX*&AE(f4StIaa`k9c5gRn z$1sXwh1cee8!fn`K*x${OW&T=%H_+9;To!D>Q5isUzsc-8i9Lg^6Cq_ck3M{<(;?n z*PDD^EG%BcA7?f=)*NGcHFgurVmW{H{>f8EUSlomGFyUxK@1_6NQ&&f$ql3{!IQ3? zDLx($lfG(yHGX8H5?OtE_B33=Ca-EgMP z*!1{g(X)P~YZ3*LHf6%$#io5$?1X6(9UH2C>;4hmCdg=tr`Ju_<4a%^8U?Yrg zXlcp91>&o*!B7f|sgFowGwDK1GP(dfv{c*GU!$O1D|D9jx~c5|Nv7d$eX7ZBh6TJ! zZ;}bV)v#y#tK28eObk;SOGh~39Jdx$|&(3)mcH{M&Sv|s_jhS?0&yL3y+^aN5AOYygSGE_2 zG#?`L@g)yR>*(Q~ulvY=&V~=V%iJdYODT!)n0WY#{fGm61<`Zv4*oI$w@k$y$ahT4_q;5jqoZN zDa-|BOS@#@T-y-@PtE96G7JBT(s(1~VYq5|&u&^_lv!;J)tQAiE@C=unlRH}$?>O)UB6Pd{Y*Q6ZlF&u>3N77|;3EgLtAaBx4L zmtNQv!Ke=6&j#c4I11}-2$#@mz(9N&Hjh}6;3nbk(nKK0fr?@R)x6*)lTVY8H~ASh zln7~%O9Ajh`(D6_NMX)AVDQ2^cj$m1_=2e{8+EBz+Hl&4p;b$ZIgMt2=^$Ld#MMle zl0mV(Pd-AkgM`+3P>dzgKnX&Qs6DPWd-7iFOv;%iCkoW=^2@vet{4gAt)8OA&|E?t zB=oohB4`@?t1WMi<6}+1qifelP!#uk{kY-67d&?@@?rLv%j#LRQURDJ z{F%_}CXCc&1Q+h+pK^GCbM%lwx>7<;h8bfUiI7xH_B^`c`Ats%tv||Q(S$Li`lPD! z#GYLg2=ICz_AdufZu;Yt&kMkBmy_i7tG};+crvjD6 zS`CV|Nl3#hiEpTzAWURFuz9IhxOvaGu_(zp#jp;ytxP5vejEHtU|T@dC!r}^L5w0{Ny_LWT?2q{UJ!nVQJXF?1Tnc1g^SU zHVGAW2hQU@%h|R*8lFT2U_?d`uu-@?+yNp~TQpxc$()Z-E!~&2(UvdIyw5HILhPTz ze~tf|mB->jcE$P_UKia(H;oeaLvVTx3m5}Bu<pK8(4vdYXkdpZkiyeWGdyMYqgjbRY9lZ}}N!rAu?t;@+R&xKNMkM&#IohY1T<>=u)#9J{KTPylu&qoPMI0&k2R$KZt$9@pJDQfwo?Oj65ee!Gq#C zU>`adiK7aUV$I5xBde}jDkk>S%CnIlbHza}OP{nf{-8Mz$gXv!M*QQ)A5y+o_<%DFYX4p4?(z#0gmnLvVN zq-EAFP1aL9tmGFo4wiCBQ(&JAYVUsPNpl*hIQ`f)yDm)08)+$ z(0m(=U<%WN$wOm#hxhK{EN~E1jL2e>=tp1}Kk5$R1(88Y1j%{abUj7jTig9q!k9yc zn2188bH}iizSAxrP4i6!xI+|EdAvL=HL@nN`lAnoGna&< zU_z|O4+jUwi9+Kz_95enePR-k*%W$QPx(`gu><;P*UT}a)JNCrBlq1=X4}w$Yp`^Y zumDH^KbwcqA`%kg2QPEdfBNn#QOaaD$@4!x|416$gqU`(T%_1@CAEMk$hp)D2IA={ z(wmWqT*#uO8qOR7s#l-iLZ~($UKKnLp;$>azK?VuMu&$Xrm9Ek|5?g~dK@ z9zL)aJQy})9XUy|O&u~2i3l{W5d1+y*oJ4i9-|p>p*^)xogo2npjv0)IDD-wS`7~} zAO#~C9sFSgKQUAFFJI3kJm_eMr6oCu)9)H-4Kn6pmiw6FXZ8-!M>re#g;k4uX%Hi! zqi^nQl^<`5j8!)kqx%M4f9;sthr=he_3-#Rpp=$H>jpN`!q|kO0;~f~zR&zqq3<08y zmL$ipdGN0X)mEC8|N6ZXZ$ACFbyaLplK;hrW|w6|zy2lZ=Z|zEHc=)jfJPSWBn?QX z)lsr+(tL!?Q;7WTTPL}nE|p*v;V%vy1SIr# zhq;RyKIqSA5eLq|bXCv%0RTtQ_T@io z!%kl?uB^E$RH$uHG^cK!SoVP&2Fo6hmvS{x3v0{~|!TvdL|5PjVMS-Xr zgz8sy7gWS1=s#`J1O)GX>BVN~p>|b@FM%mZ45;BecMTlewKL{2TtXnY3GM5bJfL03 zr2-@XY(%8f?C4x@E*8Z3HBWEv^BH{rgWz9+x|hGuWd3{#W zh&0v_K+fobC}I=GiDXh?CWp(Tv8FT|lF(#-COr?$Pi;0j4n5AoSXvj&=P$;2IYb6M#m=x1f}hWVmO=bKC<&!E4+}%L=MFczwS!1U4=!$ zwHF!v3G(ARCcXRq+z}Qda6FYVP58_uJR6sB?l7fxcCt#BPS)ZDW~dF}Bqugu$!M(m z5*q6coF9JvsdNNHp_TG|*t!%V7=SuzU>0PjFCc_P1n`Kd*J9SnziQPgDu4)*<`oFe z#Dj=)>TwYDlNX_hXtQ)aoCUFtszwDjM=V#`ALIYzn@0!)eT|_^2|$Wx)~*mpr1w2* z`UG!O9q^aBUEA)80;->tT~mbP*ta;eEx({&nTG%nWVj40A9!ZGVNa%@ig5&dm;`2q z(Ej?A=)e(zV_NDyn!pBxXufBSF8~igJ+V*sw{|^E{==tPJ%-7wIc0}~zQOJ&M>|Cb zHg>wWt%W3rLvg4u4@jCK6G1YP$cQ4$Z#2tGpz_wf5Nq_a|Mew|15Trc4#r>ps2Htg zMXSS_QN^W#G^o=-$TeZ?Sn>+l0T>!tS$@@gUe$toXL%i_Sh;)|No#sW+A?wcIOAE; z)Il034IWA$+XMSI9(x$-0{gJQS0DY7YT!bejyt%+)rN5mB~bnCF1c9SL6LF(=$vV) zBr+C<7e`y8A($o_EC^;38$yjK;ecwE? zSF4rmbI;vl4G>#Rk7#1NcDFFeC-T;>=GZWP>WqbtShM6C#A0fUK*vewRv(ODqPU#m zGe(UWCwYo-D^`Ot5%t;*2?{|XX)hu_K?R|bA5WPMZS25h#Y~+zK}SPT@V|C(*>xc~ zHOKl^ou11XWA6Ou=ppS5kHf!KqnNeB)R}o5#!uz6%-jqR7KlNFbxRi;*URH<3~^L| zPQ3(!Jm=yW*E7W>(q3iYUmuBnkVu>nm>~ob6M(D2L7h6e>CdJ1Y6Waa z`z8=9gVhj!T>dQ!XTG^{&8ap5W@kA<{;}mk0vPf;?_+oOB0&AEPN#l#JbO=?7zmPOl#-K_22=ZOLRKK5Rv0 z(z!ZUOSwYkO8J$v&mKp5R@dtt?9T&Y4XVG^=}isyO(@}gfpmRsEYd6;iTnYfEtT*i z)nIf6ztBN~{OVss)9^AQ1?;V@v$&qD(5?Oqf-rRLuCAq#P4LIZX#PqhJYD&Xg<{CkrO9Q zn2sWiul0`3mA{SVbi9tO&Zv$)l0k?}Fjn325$81Ny*k%$bf(!glW!%kU}Xma`eb@1 zr~`?=EHU#gn_w7c*J~LukrU5qFSLt7prpp)dW7=F%rO*+E5u=XHPOAoR%@6!dvug*Gn(9 zTvwv3Mp?dGB%cw5>ChRc2n$^C^GinGK8%A&EGXanJ*x(ECEn2%b;C+t>J>Z!H6ato zw=}tFbrS3ZY(g9A7vP6jHPP_5cReGqY3?+W*kimw`+#e%VBd1Ui!Ils1ID)=N5lCt zrie3c6}5Q6=)F%o!r&p&KRkU(1FJgjr+lWY%(~u4sC7f)fvBMzfr~HRe+O9*#J6A| z{A-u~6x=hOC@Px)Zoit%^~<+UNcfoZz+WS9FgvE!B25NnjrBM>n3|iMoCP(f7Z{eg zWB*vWco z;76|?5a1OW@`oCGH?LQwFd(A&kcUh`k{`wpiXFm9Q86X!5%*PFl~59r3HHo{xwS{P z38O~N>fc8gpFzvPnSM)8?BEZI+!O*eYEac}7WrSjYL#K=RTJ+r1f~QN59k7&D^?~X zg5_QMHvGZ9l~4z5!NOXtIf#jg5QH!!&HNNL_nm}RBP`<36!P1PX3x@j8vfk$F#@v` z!E+1BE*Y#oT7a6ia~ED#y;)=KG(}A(@`K1jV%G8&@on)OVN6Tf#lhefy#1ud1wc^4 zgCc$nFL-?79V6|GmzCEMdg38;8Kf~<2*8~i9~U}Es0UTxoOZ6sQ&x~s*~FU0!T|8& zak5VD>jFZUQ7xwoM_zl?;1O#<@QO%uvrRoHLpJ(V=c`epgSLBwOUOenqe45k%ODhBnW1SamN^LBC{6X&O&G=Ky`e(~tv0w!^@r&| zv`_bL((ZGpfro+s`zS;)?QPq((HbJU%w{8H>}v8>Ak>n7rbVwVo$bSRXmJ?=M*sA? zr3cijkIMLlXDp!k=s2Rm9IwstL3U&(mix9K#ee{n=2l6Fw*yUCukDA-bTX+w>KKjDKE zz^^SD%LF395JY!FU1(1Jm?_~AGuh~l45qs@ctj>3mozCsaY$n#h9#%iO=&&b%!N2| zfDToSSX-I7w4(?ui9VK! zyR@^JoQ6k*cl?qIt&sSBLPZdbLl)gIW8w}dmJ2(4He z0H)tz5`$x8fI%EIAs_Hg%pO1KeR7Y3!0{Ib5BOCke+*-Wfv2!G7>lopfe?Dexv=(_ zZr3BM_iB{6-0Hwo7NvJ-G)-lQTw^r&7xsAQJ=oEKB6I+6 zUcZF)7Qom0S;>>M*7?)X-p*g6bB)eCJ#)O#G2vNrKX3sKHKA_I&ArOx=UV27W$8X? zCfWRfeFX8Wakg&7mX&1w_n-gPE*8dpWH{gQkMK831djkGLGkwSU$CsSQCoZyn}oka zKJclrT9HeVlZBi#Riz==f8zLYl!AUoa1sn?(S)cMT}e*PvffD=H@$l3Pzr2YPp~wg zLnA=G-bW%tMlJv#zR+Bsy3DgE_K*Mi8}hnTc~MX$$15Smu^5dY2$sz3D;cC|2!vwq zHL+hbp$%Qq1+;^Y0J5;#*lsuY$rh2SQ5>{-xrE1E8dA~qHxe4XdRYu&RlB~{b^>2) z91i)0xZWLg=H}md{nhvjt&qhXG68pEPxx=-o;0DMr5~O+Y68E>FpNNd?lj-%AK9pU zgcW+y9m)i@yo=#sy&=8>W;EpVX^yEuUX2YG-ZQ~)iJ$xl1B#4^MX(fkGIE5mHk*QCgy$YzjUPp&fFCpRP;Aig%d;=ed~eOt72eZ?=;0Rv{pf8G#P6j;pJq<J9ei0LM$y0z3?IQfiC_)TweUrLipraX4-tJ>&yV#L2ullM*e|>c3 z!z>wa$0Z>N>MEc>j}x#62rY;sgEYx-!!>1Ei;opC@4r{Hl@DV;04GIZ2UC?S_cmoQ zzxv*`=#|~lWET9Cfov>pQJ-E6KjVEQkPK`9cw;8P5~P{K z5A$UhbmmN#a7X~^vQfA6;W*%Z{DR{&pDzrqsG++lHRK}drTsw{aC3lqTVh#<_{~`9TFa+U4H4$ zElRcHuAAD+4Dd$ftD&ZmrI1gjr~ZV$OD)yEx>bc?KFx7|!q_o(AVdurG{JpND_U7W zV5Cp9-z06mFh-!Kv;r@fwm~}}vb4c*Gk8s7(00pk#DeVSDJ-Ll{TUvOtt%~90l>Uq z54Las8RWZmWRW8&s_TtS6J>t#q3(%O)zB!Heib9q%k__CMWKeE41ALLxL8gqPw*2S zNQ39sKa!lgc5JtFH)&-m%}WJya>qAmK)6Z3i6$Td2q|2#%ExX*8RstfO$f9*D5lG$ z#dL4J`byGvCqQ1q7KTJ~2XjSRfpk?5i~O-)@1PWH zgd)v-)JGz{n(6I68s1QY#^h}=4k=}#h6yoZ*f4Yu^-=-r?0^7BhR0Er<%2$|Y9bte-;{oD6k7nuo`UeTJFH^b=+cLC zI%~o>^d!WD!8L@y=hcoJHq;_G<|tJqz_o4pB1_?*YxAmQ>?Hz+kwYj!HAd4r%qN?+ zsRO2SM}0Ke0HSKRiQE)A{FCi|)jC|}?NEX1-O*$?m!SPUiy90b4Kb#PeKxFFNq38- zOuVhcz0I`2n^#?S89!IW>`rNCtsox@Bsv8DOe3V`9aQEXzjp9{{oxza73NK!W(OEl zWzFjJ^Oe4AAH4C(s(G^@xuD;swL71;zd@ZWU;CcfWbJ>@?h>JBJ@rWj)dp{h&m};3 zHkQ9J4z@Z9YqhR~SS_`Nh$1UFuf3K`rqNPJxm9nz`sL@JS?H9T6rX^h640<%{yWMF zdN70kSU&hdhGt#-?|=9GFOD6{v*La*EORc|Bv2$okjr*$TKL_#fG|fZEiuN;gd+i} z8s1iXcuT0^SJiuU*S2gfl!hD7F_%F6(};i!q@_!8@7C+DGely`W$_d5Vs9fCxym~; z*#?#91!fXhT03L6WYH2hK^aJZPeM|HA!JUk`a`>+_V*6HK&E~C`u>+zJ!pC)Uijv{ z;}{$fZ~*{IkenLJA7M1Q$#4|_95H;DUyaQPx)u|?S1*wnV>d`j&a=|_v!=^JBQ3_= zGh0K%&m3>lhbUhWp6#19ytZc1kxgrCk7G~(mobXy9j{PN?^S19KxpeD{jQ@mO}~Hv z*UwAw1uh7adIZ!}NoImVe%N3I`IC(huu|1BUKzYgxXBDs`hv5D2aR|dI5s<%C1&oc zNr0R?QD3mP_JQ#ChZl%_%#Qa>3)H99^dY0&!1R&%%)9^z@(m-z>66(ekl8jT*svTJ z5t8<8PMRs%iLSU5bvHa3OWUP*h;W3OC%>^sJ&3`P1%C9So<#=@2OD&=#_DX&RjY7K z(u{n}Lj@p|NPc6+__a|1`beD>h&X8IS#MFMj?12DGFyB{1-PGL^`LbVNh{eJZM{>( zcl|M5bK=dT=9Tenu>i>_6vhZd5SPA57{O9@LRFgz9ug6a*#qP_0=no#kRa>iVFkso zEbHPQSqDYRA+L-MxI_ow*UQji1lAl9OhJ&UEoA`)=;o5>Lo4~={Mg3T#(F+Dd{EDN zvCciXZV75TT!8$S6Z|~oFTOxTD1!(5C>`toX5L876F&H^m^~Mj+37?y?-fWexRE33 z#;f%yscWtUA)^8cm&f!%nzzhJK7A6+b+oFgp>Hgp4$uzjygWZCA>Z&^FkD;mIx8{H zJWE>A#ngceOg@FHze=htfzKu%Hh8e=QI4WIzMtN*MLbgs)&V87Ck0`wfhDgyaD*XC zfX4znl&Ao+m2{17%OUO1LRT{QZRADqk#Ff)Zf|0qdPnb5tj*p^_m3J1Bnr<5yqV}E z8~o(Mc@fUdYzKFazII4}LVKmHv);dRJAz+Amnq& zcE!j-*}3%X)EM)`1a??`RlOOw5Sg7|!vgM@LCW$$B^f})pFuHUWEl|Ir%$h*0E3C_ zj)g;s^!j#*9$*S{4tw?J!A|22khkE6VOLF?NHu%h`4pZdC_n-RKrYDlt!aSAJNx+f z8|DMsQ~Jy+*3d5|IH_# zqyiv^CJ8g1uLAf)=&UBX8-p}8B#@~9(kzcNVvTep?Hk>`dbe;#nlQLmk1s#|Q2fwp zDI`J=@*fKTMpe_tQAe6@YY2}ZzKF=v2zf9+PW{lOMOSGD>D*a$ZRe}mA+$%~PZ|`n6*Xc_0CxdRn0?6)lUL+`o8unpx$)T`gvlu(`46Vdz z6M3VsNcc&&_LYbE!QiwMPBdEuXx^&U%ftvfC;RIL`R)_)^u-hR-1)=D?-}q@4xy2^9Hop zREH?gQm#GAA4w5}W`sr`BBGJKW;-0({d|h0e@)C_t3X0k-_nVH`_I2LUVtg(dWv`< zzTyQSNTUKs{(n&c-+uMQskh%s;VdiG8h0$0Y+X?-n;*Jl`uetn%6womXX9pI>Z(+_l$Q zqr}=2Gh}?;+NTeZizYp*iji;KG&#n#bcX>DbioYF!&|V&3+4zgLfHQ_g8Kjld&nDU zjJy)8Aa~H&w_d;q;V)akyUED$Erw%Nc-VwLMFOL${NAX)6ru;i2)?~YHPqq%sfn%s zj=Yu^sj5F*K$+(Zd9S)D3YbYkOr(08N58u1MKFU(rY?9j9^rkn#5gJHj4_Qn zi0$Yy&O7nzT?R(=0`l5Q*Mv0wi&0YY%J8o69huKEETPx>X0`%z=h&vzDsL>$CNL&5 zS2e#F2;=!u-v%@Vfk{pi|CH>*i`S1;o%V$enU-U?C-=w-eneyWytIGs@4x+;o7wzI z$Y>7bOHs!12UqoXlUQK<#7a>zl4d~Jvlz-8F7oUV26MF_0RSs$>XMH@ZEl%i`v{}1)aMp|Dns)tY|_q!#o!W3z$gk z5|K3@_x=8}Uki*kPkB4Nz;E(YRcEs;zv;NDYI-d#BWi8r9RbbEDZ9{L(#H8Lb`4Dl zn>KC~9;e4CKD8C)14Xdpv_h2D0V)~>dtm_x^mlywW~NAVAH2b>%pO4&=#oZTy?`uw z0omC|>{ZrIEDdPn9g{O2k&QG1QO|l8Si0$3eH1GVt86gp#(R-SH87wPoqqk=KAX3A zJRpaE?}d3nNwtZ6Wdf2v74TlIkilCZL1qt1(?M=h2Q)kKn#Ku@Bmnc?Op;MIT*K_q zafWPkoM>mXt<|io8lh&B%(a35cWJ3knW$!{>z3|#!EP`TN7pa6h;rNJCq?G%`)72F zgjFK~5rQ@#G15&eN*nX+!4o9 zF=mf*FndN;*0i?tpfY!H&K!{+@qbi>TM;TZBY%wla)AwXSqn3J^c^AwEFToM6BJ#8 zs&bnACdgy4m<}~Lgs?T582I|M@6VLJy`fv)YRrC|-#8xq-s?OMQ;J|_As0(+5 zg{c5gmrX}_5rQKr=UNZyYs0~2nB-YT_@DpqyT&oWjHW<17SOMW;=cQfqw&P)P&d`# z#J(K_epUbFC^rK=ehLeWxT!a;Dd(E?>E)&m8}+?c_Z#4m#`V6D%Sf37f@fj|aj$`@ z=cZ3V!u|I{yOm13yqsBJmGSCPx0wyayOGmd_`%Hk&(FM1_QD?IhY`>Xo=FvdkQV&A z<0)y6kia0P9H@pg_i=>3@PbRE(<3frlLsrgR2pI`0fuptl5_>ep$RBZdZi8+R za^_ttmn|z{pAOeqqDTf(2jmYtkn>jV$Rko`DzBNM)>xJ0v_l86oi^S-$N7>5UWFsT z-fSOD*33e#8tO1C;ST5qz0x|A9BK zv0}P1ygLoY)O7V%HztrE)#z?F2r_e&FgUuIg02hlsm}EXd?KbDx)}e<@16d?fBHeS z?N;~v>LoH8`Eo>&Mm6XPE&{_NoedG?cqfx?QRr{-pzN~|j zLZBG1zA6iT1z5#-+GFV7;r&DgUuRf*@; z?=n=^SW05Q|NO__8;?W8%rq5HN7aa+hSA6tBn1z7QaJnncc1^p2wE;x8wD61E)iU2 z)1=vHE+H9dLFLD9KDPrB@S~n@vkfWzoP_I+KePJZdh?B(4@>_02>GJ968s6TAq4?0 zmJ1b8M$93?kk_VSvp`acGVe?6tH-b)9%SjyDr`IB&M;6X;h+E;= z_udh^&{I~In9QRSF^FXX`Z{}Hl2KH@m0vLfteEhVCX>>pH0w}SP}a`jK!Tks zzC|F2FPux;j8FlX3tIG}SHKLi>v3KlI%6mqOz2I1J&tpe_ByVXG1Cqgwc!yEL^6N& zt6y5joeXMavMbe@b)aZSKp8+pRUij%^tTbT&id}tUz;6-AQ?ZRRgH_GT~)8X(TTvo zTQL;q5jXV|`NKi$ZNlw{p?qGR9o-?yF|2ck>c$%_2jf22TNSO0iENm5H{oxV`+NJJ zxAqo^obiOP{*(+e$m>snq}6xGg%spGvEb58^dV#22St40qrD*K5@=!4AEL>OEZ78A zN$k8L-(ajawH@01?OHgED0p}O4r>x^QF8dPW$=#_GAlDxDs@}C+Di#QfLErz5b^8W zp@TaxPx1q#g(|E~{x7GG1mJa&kor++6ra^Jgd~k=K|xGYjADyXS`B(tF+ z0He!t$?C)MgKjBC6lQEZaiLv0qM57qFY$bD1TfDc3l$SbTN6mCNI5Xzx#Sf(-Bgyw z^92b46I@{rg;kFyrAlp+TgdB{oB!jxFRgtR|3^kFz|>@l(4?|>N-qcpX~Gw0-hX_- ztg2=T-$o4#lMyulZ;mc=Q6>GEPSCM!*&`a2q*Dk*Z*CZFw{#TusfIS1n#Bf#8H3JT zIg-}jv8_+6nl;5jSGZDwU^P}ERm^m92likFc%TA)bbz zrV;AtEFP{q3Zd~mg$1ycVik^1j3px-mK=)tU;*o({YfzS*bi)*rVa=z9k${*DuGD! zt;s}$o>dun0NdX)PdpBs1iR1yRR~KcKo+SU#Ih3Iv7n3tg_vTJ`kEi7GdO9<3FVfe=dw19mxOgopSs`V*A>O@w7 zeIfKCdifK=J+yU`40_G-Nn%!1-%M8`9UaJgQ@LU?5k6Rw%a7gs>YLebk)?C#Pk>iH>NgKM3BXO^Fz=t~H$1r`qxZtraEqIaG+3651Gw zBZe9#Ht1htWY&Q?wh!9%osyMEDbQAgl1?1btMZhQ(D~y==UrOoMFKl2$qjMS8Y0t* zBv4Y9p$Qxs83%xTe*EJfn%QOU@M=ZZC{XaDE>RNrJ%wEAjKV4pt9jN+`7eL-F>cBw zg0NXc26Aaw>hLQEO|=R_3>cYEs+aRCo$}AW|20b*-Jvp6jILLRkQ4y3i1evC=tMVl zsA(8PcRu#8dVTNCq?ODOd*|i7T_Cv*%a|u=BRg|z&t)(B2inyAzOkch`G|BCNY{r0 zS}ciH;H{gip)*TLJgo?eb05J6o86@ef|(gavjc`{W<9RFoai>xQq}%7k;t1C2ok4a z-te7;j27Kd=IgSwX&I&w`Cm>IU%8UHhbYi;PM^?$X-n>a2g%Q5WjCrYyfL9sTS9jr zzE!#p&z@|Pc0E8*dfhRJRoqg6*H*Y-Nk$olskeIs7)xrznn}FtpHS7ReT-@{UifVFpnE4 z_^&_z)VF7qOB!DjlJ?D_(0$G&w1O`;bqz_C)nx7%0sQfY@0+nUy(5FS=svL5UnD<~ z#bjmuBB`!1_K~98(RLx|Tq3?XOLi*-R4sMW{@6c${%fb6C4+B+!hiYdH_N9@3Jaho z-&P?O%i{=t$l|6Y%ns3Lo?_CNVYPGJvfL5U*9CUkLD^ZM6guvRGf$& zT|#49`k2Q8|G2<7&W71jv{5$E0Cl#aK}RzTG}%y^<}ghS9b#u-LwpmBM%>uZXfo94 z6jR9j#3s>veL)rhs2>aqBshp*M`Xg*PsTMG7Dz%b`zbu) zDU9Qr0HlT#?!D|Ty+g1Q?`An@wctDhUN5VRsEA7HCf2N4sQ_7LKoF<2scDBG6hz4A z+x$jhe;h#zE6S7x4!EsOR!y7el3M)JH(#(?P3$47t9qP^M@DK%13&sxWR2ks)!>)H zOotcbE#?cCtlL zIs)uf1DF}K8iKIOB%qk$d0aUvme8m>+|N%xIKA@jG9f39&nsIu3$`b7zL_p|x6b+q zL`Eo6AdCx(k(xtN)m-4)FqsKd1PE)E#xZ>YH7prUD=3=N$Bxjv0MFJ%9~;pq&7YvO zP=*qO{_wBKqE>T&y`Rio5&5~h+x1#^Z7t0>Vm9ou@K&r?Um(5+HaFk82HU}*JPLE! zFvy(IBMCQym6UiHA*$_IzcLpwf)&b;k2}zZMDkwQe25EVlmOrW(s$tPTln-W3w&^j zYbIS{&h-ojrY28KX(&w1vFj+Hn>$@kI4mAB!YpD|kXM*$k_Znr!Ccf9E}+mw^Y9Cm zp#(-?qfD8p6agj@t5l$OnJX(nZ}LyKtX(0eSKtwclGv{g&Bdz&ev^1HNanHAn_$m@ zrO48)>|5m^i%SBKBUUQ*{MNI3!`8K;@=VK*Wh)!eLGl}hNC{?W6F3+a$hC#5>v7nN z1>!}VS)}F~G&39wzy9qn|3P-81hi_{&7Id?+W*#zMHi@v_!XZt*#-?5V6Ki%$t5e- zkQPOmOOY!WKsRk^Mub&WeJ~^8!v@1mXB~BR{^8dS?l|j-D}nk$G~?_MNA9?^vM+`E zMq#^2+XQmm+!;s>mPO!idb}JKzkipYWmU5PUBKq#aLE9Edc;~Yt5kT+)WNJlw>W;n zEMDN{rQ!@pl$>af}jr@318STK;bk3VMiA*+f)^7xLp}-;m;EO4%l+EB@e~YPS3); zzR)|Nu=8c84EVP|)$Cj^HFilB5t}0F_QvPOVO}av^?(_c_@p35*MzpdS!jGu+X6`E zgGzuo9_pOi*(fJY^1_qB=D%0NnfZ8TVhe{%`XUcs-=rOq?mEnE{;l|dhYI{f240E;xExTV#{i=-KK5ykEp@M2D+WZ$AR4y@_ju5fW~ zn)zw__a+1WrC3GS=8r6UkE5zTlb_vzhiHMSCc9nYxm|uOA)sDm>74MO-S$L3gdiZ< zPng1_3mLFUz`tlvUvt+@U-W02O+GK<$2@OJPj}mHk%Y9TlUTRdpt{ir)}q1& z;0mLa%;>H`532dgCi=x=)S>0IR)Pde~gz@!l zi(P~l-~mFU-Di{QZhru8CFb4-W~keq6%W|`5B`NNWfLZ11bT(8WcjdxVSr=kkTS&S z(Xnu!pb(6KT>o|@2rMon^vCyM(5k9J%zzR=V^*0B;=Dyw zmPK|BG%&}C*tKyzI|uklB*v%6l9zggZ|mim{npDAsUeuz{u+jmwxEnEnXYMhBMGT| z$`Re@KJFE_uFhV*#@uCUoe0`?e#6K1owSY(9J6HUvZV^zf;l-Zsn4jm&&a5`{;zgZa&!pznM)N6rF zy&;?a)u$AP*}U|iCHd}~V5#f1l)R$8%|LdjH`$AT`jo!_hpZi718ftzgc*s8$YCQC zPH)_^VDg@YQ$IYk*M@=puDp~yCmzk&!_kaz@)_i87vK>S{M3PgVWUMJ5N`Eel`LNH z)mMmBMqfbqZM}PWqYV?RA>}PLvX0&qPhjO*4^>7_x_0sw`RPH#7kS_;;3H&olV1jY z&#ZXJCGcyk(3}Ad1CCh3hx8{d$V2>&T%s{;?4J_kWQSADxkMIdhp}Ad+Y~s# zAGFG)6|$z`0dp>8HU}Qsb7^$d^f@?}fx)lIRDZF8PLz3Z_(JEBDs1fJXNff%&53=f zuwN}KLXc*qPNi7Kr>&S6gimQ1(%@c1eCl zDb;MTlEXec%gzUN1=^g1wG+wTaDnNIwy$UKJEMW#H(aiNIR&g8r#1_&+U+ydBi_v- zgJC8O35Hn=Ec%hZ!c9cS>lFJXjX~WVsut;NtrOFo^}>V$X3<4! ze-PG=G`K*WZRiB~Tc?k;`y5vYd0E%+uaGqp$_5dsl7Jx%qGI`wy@Z4K4}N6is1@$Y zx^fx(#GZHV81Kn}@;RoHF#r`WZ{5Vy5$hA-48hI$u^3-|GuhZS7Mxakr{1pvsM!C= zE~oE%Z@XE9YQlMw743vTVVNOJm?Wq|&S#vLx+EV&V{!^!s*PJ=$=1pwM(&7_Qi8l% zrY2m8I?8~IauUe!#*pS%QG5uSM||6s&9)59CC`H3%B5}6*-Lzrw)OSd9<{pp(w{r* z#zcbVDN!$Kky({H@W2-J-dxiDD(3BYO@X2ikf09O6EA2lE_-wTuE+sx7k4E;^DG4< zGkDA!+MoPXg8LLVKeu6FsH1nVi6zpckU9Ke1m-<~Pwb<4RdM@hh{3&GXma zf6HsIUXLY4Mj57mZP#=3IC;+OAqb2MV*z%BKPbW)OnQ%}OmEi(j2}DM*4}XGVk-zz zf4|z`i-2PP@Se;&%`5`Gtpy`|J%#vygi$}8#o5^1&Wqv&g|Q6DnaRbAd(WNWpci-szRd=E0>%Rx3NcPTvxav@Xyx*x`6+s zQ}|+@Vkuz|-GLX(ofdcXBI9c`xFcv8|6E!u06b9vzT*OCvV={Tb+kPvskzyshBFHZ zb0^AC0ir+@y4W45Xe|lTjz(5DK+@gXD5yeA8K=-0b^$^?ekHImS8Vx(k-5eis}t8w zxMRhnF}jk7)`Qe{DSY}QYRIfScYs#c(`b;dhCCFT?buGlc8=PsvuF+IS0+QniDL$; zyirvdHkmzD*!;S7dW7sE)yX9l=A5ckP1+XG4EafEXf!o}woY8mubPjBcBC=kA(`Rd zd({U=SjJn`vO+T@TLgceM1hTec+x*H5X7KANJuZSl8L1dckA{MLHxV4apjh&g zmL@e(%DMC{;ARoD)8B~4Q2w4VqsY9S~c9%k0KCE1Nfh+<=X{=3gBa2CZbc9Z)85u(Ibg-&u z*kFA}0voeV33id%wP-fggO5y15`htWr=fT*)D|sZA{oigJ%?M_xRb{0qGa`-^^Er8 z@)XpmnCdZEiFX;y{}H%zl&U7Dsun@;9fB@*s@m<9VC)$~p`DF95;e_737lmVj?I%^ zAaL9?;KDIUPF<$I?6;t6&c2DKuyB6kZ+auI2igUQn!=g%7I`(s2APTXX{E3#i~$}- z_AF3|)zB0uiMEE!D8%MP@18oJyBluXecN(M4kdgx{M~A z?+aU;!tQc}eOQ2LWCp3_pJH(yp@NHvU`w&JEA5F|)Xk-3hdrGLsFVxqFjDKaHCq%`6vzF$sn$hJB$^*>T2CtTzy& zn*detmU4HZ4UX_EYl?XW{5%m_0E3u*;M8C{t3V6Wdhy8HSXN%gSS5uhDfJ|>ZT3RL zHp}ryLSZ7o98j@hPFTr_y4foxEfP=_+kA8XZsAsQ_}x^)hOZaTER$ZClqloAZ@pl2 z5_!1{y2B-v4g4qfZ8s?;f=eMVpx1;<+q$T&N?2lAbH-i9HZbB~`f;-fr~5Q!0%Guh zdi-316!N9rhd^RhHaZtmvj(MotfpypBUBm8Zg0;(7hz!)_?xw3@~gvjKflC!w8(r_ zb(1S?)dU^wrVq>C_71pD8ZlXPszi_bG>(9dh$El}=`7P?8?giMUYA8N zrG$$v5?cA>#2ePaXIzXyh0V)86-yV%z&i_f+u%zW3awoFBebDz`??jZ8U_#gr&F4s zggd&=Og0^7a|yq$o;lfyDqD()sF3#Atb-Q-TE0cjafGKdOlAy~Z)(VP`T|OR#g7^; z6in`Mc-cY>e#+OxNR|moYAhk|4yjIVSbeVvK9$PUD{ZMfznVS~pfeb)Xqc%qsI<8A9T0s59cF=_X zrE>wmTUacV4*Q1+)`J`eh7hqvQyB1l`}LPUJO1kNjjMOuH-n8qJ8;8wE73~Q!ka>z zXD1rtAWK4<7Di`=idYToQI3SXE)Y_tqnSg_SSNx6b69Ag%XAUk&?wokHd_utD#+>4 zy{ChEhYT@C&MU0VC;Z*v5g48WR3gjfIR*u^-SIIXD%fZ($@Y1Z-RH9~gs^I%p>V{p9!>)0NB%uGOkpL~CE>Ns@+|M8>AH>Q50p{Q>-XFaAU8|4Wa zi+Fn-e$0pfBzVN1o75JLKK8;kJ>r87dv@&-%W9@ZU=!9gy=nc03|bLW5DS>znMcyU z)-cKmlhLq*n9pt9I_st!G7+xmOZM+4nocxTy`Q$WK6&iZzlm~njN{J6m8 zsoIB@V`4IrHp=f*O@Sb3xFrn)LjO-|cmDU+boCAVA}vbps+wx5bD3+nsl1|wRud^= zj@vwhgpv|ekWw*6sj(u87%E82LkManJZ)+HQO|py&-Go7D;}@shx@#~`Q}{byU#v* zuf68A_B!B$BKG)kb5t5L;$=u;svbwm@YaH1R#_W7kZOT8^Q?U9%Dc#=Tie6VF9)6A ziQatT5lSs4e|oM1JyPw$mir6si>8O=D$YaL<#D(xnT3rQwg%>lt8i4R5S6=lXz4R} zDQrhR&>QmW7SljD#uOO`*RR%nAeu~|Q>b`Q zuR7x-Wtorq^zTI+Q|> z$}((WDadI&6#mN=E@UGZHuIBQu(FJOh1b+V7npRGvHB4(}Tn3nqQ=Q{C)4YDikdy@8_1qKt&7Hs*DohR~3xnn-ub+(Y)DQ-cI; zSM&h+`PKc&sAT;5lSuWGZ#HkK0fdOHVMrUcIOu+$D(=9Q1kUtB8V+I+g71HCh{5$_ zv$;PTb$H{<7Mt?*u?_Jz7n1?YQwrf3Yy1ozp@b9%BVb0vXeO2A>Bk;5FXskt;~T!} zPgF)`2OY*T<$#3HSi+38mSh`BC*QF<%7BU}X$FTs{NRIYul?Fs zz)1|1)}eu4VLLGTlhi0d;3uHdzfV0;CkmJ+Kc^cT!$t@ZTu5Vf2k|VQM-arH4hVnS z)xS>+&Yv`7FeH!2Q_3L(aFGPb!ZDv=3*^V&7^jN!2!Yv&gEP0j6rfmqwRuHH(z9X? zQs1pC=}*0}JCfvzMq~-l1&Lsz{T1gqH?4zx(`C zi!Ql1DOG9goAr$;m5&;{$!<&X?R%knA&9w8sLGgby? z_<>Qh4v7PTz(U)SDRf9A!B2Pv|EYX%*x0g}bl)Af^O`La&w<8O<42D=6zge}Xe0cb zlVtr#BjhrohHbOi4;aPZV5fjohgk7J5-^oYWG5{3h7{9@_K;j+c7k*aVN~Fg^2;Ix z(BAB{WUw56#IJdz5jes$LRoy0X0ZrvMk+3h)%f&7rtwvR7_G*b^9U#0AY3%q5!K6X zYly8e4Db3ecwyoPuRaI)aSXKJCs0*51-icW!fN$QGJW5WAE%YA>LQ&#*C9X03w~J9 zF*y9$x^*=6x)B{w6fM0TAUvL_Jt%1jf2;^Wfbr5sjF1IUv22k^dz$N}=xw++&DbHo`gn|oGzfHP7fuuWmmTw!z|Ud9VO zDp&H2DS0Q_U;cbYX??jq@5E!I4N$i7C(4BkTw5rMCQN}*dl^Lw7)fg(iM+d9Y&6OY z4jFv#(n&fJg^Dc$6!L}ed~a=YB8dY05$WQ~+Wtzq1gz%aq(z^2=yYn5yK0=uWf&*r zFm!5n02-ue(0hlQeVAhuX0l#~Y=qr6pK57fvPa{YP#0-HKdKIf?*r$lK&U_z3>9z$ zaR*s707pS&ghga8vw$ExcuN14E?5=s@qBwrr7>6qy0ONdrGMXIUeYSqL8{gtH|q#I zKgiIHrX&$pC4bNe=g&hGGa>6K4CG51CT{hIg$uAym|O@3`ML7=aJpVz!F}E}EScunOJg@6Xz|`c)(+Q=!YY@GHrcIVvR#%|3N8EqSLOee^H(g{5 za_O@WojbfFSA_uy8{zf_Zl^&8J?}9<*ln0x~NB6bz z3!IryohxR~?x$Fs!*hu$nal(Vg^J&vB4i1IU=5$Q*o@^1=Q%&KLk%GaUc*~U<5y8U zVQas77oH##rCk{f0-dhHjmhifDY${SGYiPuU_yzDJufnu_#S z|3So-u;4@PMv9hUAGTZPB9;Xi9Eu2qyUH`Ph=mD$f-p2~i|h52ecKk%P+e;Es#W>Z zw+%0Fl06HD;dAqLKDr#9z?nFFgj1a-N{*dUlj>fn4qgowRmYgQ!tx$=?U9mZwChrv z(X7>vjqE4wxjsw{qW}kT&BQyZ!jUt~g2^y3;;}ITMeekCG(@G(Knzu3slGJ~oDfA| z?71S0;<%=+y9SyDf1-j-XH8 zdQG_uLYCi#IZQM_j6lQcLp+*{NUOIpaShb~#y1$-{in@VqKFE_s62)uz=6qs{>(%5 z@8B$o_&)RKSvrwnV#Or^lDzh*%{}dZPyug=h47%Rm%`57>qF(>0yPppdCd^g5Xg3& zbB``(E20(Tt-`3q1Zga8l%FpeWi`dhDSrJBCcd_svVp8i9v(U>X+`0I`6w%xFBgtO z4^c}U%wRm%cziB7`PjEt|Ba24j#5a$`Lp-mA%-QypX41FR)Qi-VLPUi_P9w%{Epc!>! zFk=*_EU`p#ZP$T(nRIGA9pI!90U1`ZpKKyz~G)5$5YtDn5K z(8wgn&kBId8}xh(=FqEaw=6W~8z)&t-M0d;=8OBq5N1Hx9+F?#0+h@P=g*7YZgsrZ z#=Z2+PW)?^9kB@MF|+sG)1Pp|`bs?J|Ky;n{!`<~pX2?DbdTF-H*OP?Dt8d!js&82 zfeQtLp3idyJq+GlOig=K90BJ#j}UE5iH3TLHgCQByzLLXYIRZ8gpwdy))k8)mkB^f z4U`oF9H0=s{T=8+MkT*uYJ9m%dv$M+By|XZaCY&_xoCZ{{X`02ID^+kE9>J#DkkfR zS48-OgI94skv^DXndlpe_cAt{lFJySMLMzLR0Pa_b}z%XElB!^GmdR=Ok z%t@1SF^AF(5M!7y4FELjbP|Dwdu~gDnujnIMgkjYDoy z8eM@EvQX4s78d-P%l&9`+ttrKYNjWmBbi<2{&G51*%*R;uET9?Ie)rQ5hO%y7Nk5x zMFPy3kbqT-E#Ox!BZ_pvO3KRX&#zYF8Yb68I$l#J9%>Yqix!CQ1sL&mD!sH`*U19p z>Ci2g7ffTnR42;N!41T&78&4!0NluY;Q&c_D=W0zY!=^)$e*sh4-9cjNGI+W*B2XZ$kHEinZQNYxq@i=@M#MCqEi zkO~0ytl{mlH7v@dXPu_-vNwvd1z5okEIgk)QZejb@4rQGv;DnV7sKb^^>iCWT~s3V z$}>)mbFXOJAo;aOI#xyQJlReg0{MnEhh2i7jUK%2D!5i%a%6F9czPOQ!?1rk|DeK(^3RU(9?x84FWJfAWHp?BA>JM@s*0-hlR_yCK*ra$R-{~NHr_8ZyAm{)HGc8E2o6w6?8CfNJM%h3uVS`cQH6`;?U1~ufD(} zQCj(}$Ctgd{BGoCcwVYS$>)_dHp$p5Ujs&r;z;d z=RjRoAV0qxqTsB6{IFt({MZ7-2=Y@Ng8T(%s*zf7IH8}aLq%etV2{{w%nN()S@kKku)fKHJ4Pid-s0Nw7PRtz|@C1Ig_T?+)&kdY2 zHQ#hO{sG?r%hQrPN$+EoU<2ES;sBfd;`4PxZJ7qrP^~goC$)!G0Qq4%r5A@RwI?Ak z7;echsDiCFUQ`XcLLC{;o!4H)B;jnK=TOD@`h=L>BHGBI1VyRAkWtI*!T`B$(q;>{ zEV-7(W&8#i5@6#)U{O@l_Y+V!1b_L-%cbCUyjlqh6~H_wz4;cPm;6A{;_zhJfMm2j zKd~ZdS*j{=tq4vj{Tj%V1-inS@spIo(>PeFtgGRvY;)b*_Kx7-2~dDZ*V6)AA_X8= zXh9%=g~*!Va*-hh-@f&*1kn@x>J=N1(@REh51teK;CK*^gGIQ6CJ&_*8bXgu42xn5 z|MbV=O3*%P_HHH#R0104sjJrD*T`GQIc*cy5pgqK9!eHsB#||Fo8>ipVQhE@}nK-Q4fazkF8iCNKxg0{KN!<{1jcN z1r2lpyZDs6U_$%_VZtb!Bm-cB;JpT5w?)_EcAz96tIS>S9~dKoHE_i@t&)7?#r3#4 zILGi7f3i0TJ8zVr`buoxVAMi_AA6*Tf>@%Wqh*al0`xaj?@zWWONaU6I%#DJMktCg z>Zv7=OOdjj+4iWqC{I|ZMLr2yb_?KOMDcoQBalrs6$Pf@a~3u6&}STBDQFE9$Ym|F zz5j7cWx z+Y1Lg4r#D_?NGLvk>6M?5g|p@eHB4n_s$wcnGmB?6G8`~S|bV%Z<|MelKJ9hA`!v) zh!5-<)wo4tYCP5*qVU`-qQ(%LnXiHMh4V#RH9;qr%xRfFRDBqZ9u0MPoHOS{nDD?Y z6Pf&S{OB7TRu`OdlEsCDh5XQf0d7X3y48a<#rbE=oB{F>-U7jP$PWilgeVo{j8=mL zAirrA18J_#RjZg4%8=?X*ExKQlOARD_318)i`)puh-vx{(IX?#EeHh4Nxa8u;te2? z0ga28okgiQaJ#K>KRm?hu(^`p2YSFFB0%SX9yJ#y00o{-%o-E6hYM`^SBnJX19LAc zwUoQ4C0rbar#)On`LLM2u7Xx-I&!5nBTZs%22(R4Tw=Xz*C1TQ_`YIEUcUM6gu$?O}qL46c0dMV}% zX({0zXR_9t)Q4}r z%JVSv7>xA?bRzZs&)Sy>rd%O##WL6(_usIX#m7Nc{KS3@`TWeZipaagGC@V?t(hgj z>a93=VNvMkFdzO$h|_H_C~8a|WE^bc}NNxR;q}EmSf@+77(b zh9K^4=Zw>3f4-eEslWozb$$IbzG83yjm77kDf`O^l^OS|_KNjkYha}%FamfZfweDR ze(srm&7r&=qOf1ppPugJ;3x058-#~f<&dYxLL?NLTekiFhK%KqJn}2rS{K7zMW>w2Z0{qyiR?_Stvp#+*o8_bQ9pHiaTU zlEEeWk++a^#$G5qR3`7>n5`J&etYRWtDvhafhC*t36>g(2k|~}3aO0h1%h(qKvfbQ z6vB#Su-llUSw>|%+NWD8lM?*~@8d+X8Z)#v0D(4@vLvDqE(S?~iEk4ShKD2yR$suzk{6>r*qPqE#kL?ZxPFTfend3?hGV4wKZ@g~L+=b}kPC zSOFA9gd_3xuU`2#WsqG29CxXu!~zdPz5bSu5h8? z37)Qk5Iv28O6x-ftTP~m^Rys9mXMbAzRgfR1kOC?;As?cxt(%EAxxWjk3Y`ir~wds zfT~O;G8nN1v>-snQ3*0W!6oSAMB{v9(NIzB(nS&8qD~52eEgBZX9$XDh*skpW+Dw2 z$r>L#+{cM4uKRVU|FEN}8B#331PSotp%DWxPJGxZaIVhSe_sjMZD-aK4*|O}M2GLW zt7h7mQP(36{IP!@GOz@N_TVs9(9gS}*6?6%TVKP-_E_pPsM@^DT7P2c67dBd^`K?$ z0%s3p($+=p5k@gl4!tb|J%_Gqm8~@vM+#eRngC{q>7fWy8zunolYGAJQyD%HE?7i! z^PYYxE*j*IvLQjy-aw8Q5;-Fg1(Pb1bJ0)x+9(O~@qofw7$oV5lp}Jr%`8aol(&ATbkX3FmPjQ6ick2%) zsv62_7L6q+`Sds(*m`n(rQ0!QMhzQQhpt@_iKG5K{NOSU9Ht-_L7H`=QUm^!t0Nr4 z1jYdEEJy;O6{S}(G`hl5|B<APv-i;|Mh>-X2Omqbbnv>y_u9L;l)=q}$Tds#|6|-a?b) zL*PKztVdeV@JT#~Du@dB*s*cqz@+$L?!EEa-<^HN2}jIGJ<0TDMY^6Ag8a_&@n`sn zlSw~Sn`)^6{3mPd>7Zia!`yljnQ(6al&eptC2$3dnEb*YnoUsq*u(+zE#43Z~ZyZd;cG= zGNck%w|sS7ULS=DODE;wKg->kT3KM%ES?_}!Q6xYG-O=P)9dy{ixz$LpMT$UQ%gm5 zKv5Y}$ehB!kB9V-jO+YAoZe3O^mIi+=^VB+C0=Iiwm;_ZWSt4b`_o<_ik9N`db6N% zJoub#3GdssFB>8VHBJl*1ngGORxCt)-2QvH#l^0Vr_csJc=I(;jJnZGh2Vw5%*A{g z37m2g1jfCq4Q-#-wD#<{4mk}KK=65hqN0d>L@fjvSn4xt=8O$Ye*_}yKHP7Je3VG# z9g^yd3Mvephr$O|8(WO?pM~N<;TTgGx#yfog{EK8T`O`|Lsb(4(0FEWR341q9DEQ} zS$rgT+l?^UpZGIIz3|i%1+dh{w53kmil!tqjLBf*q#+^8P!&jWh45ui2a@`UL>PX9 zvp@aB!6m3i(FG#PGcDq-+inqT^})>uP(t5FyvghkcqPWvEVkQV%!`uk4>BGELLd0W zv;&6;EdWv#U&#?Mab-8~=PD$Hn?Zhs(Nxd4RI|^Wv52RZkum*&F?O9*FpR5rwyfr;(g79=L7yeTTC^VKVEQdqk?Cim^D7J zA5Am9P~fGzX02TzR;(#mY+bT&)=}`C09ENmgB;dn`8{_rEfG6B#NlcFfEjmg+F)64 zzx++aHa358Zly$_mnJ$?p0 z#lQi_GWobdr4d~sfb3SlE5w+5Qzys^65q$9d`J1$Ou(1g&ygY}b>-bl*&dC5Gi8yP~^A+MOW&)$?wK{|VHtAAPq^`2tiL`Gi*(}Eg5w6~^K)}M$m zOwYFoT7@bssh=mGcmnd*zFNE#8cPO9yx0Kp`dT4Nv&(Z0n|j8Z#O*MB@4Z~)gW_<2 zlX0YrD6!Mo2+i%b{kAt>bEV?>a;Vr@{G1kILeyE=t+xaUS`a6yCAOLl9fAY)CgI+B0oG_6~M(Yu#T=L1mB)w?dwbg^KcO|1 znZu6jxOVTqll!RetbK8r-hbDf?xk?X_;QhN0oN)Lu(&N&^3rMsjz`4S5^}X)5=B!p z05cszRJ<2r=TF~crT38y6(JrTk{pXb0&b+HdX_053bX^B{Gu49Ifezfj%k1-ev;zk z)j8&GQ7|;WmQi4M(u6by2c2LSK;)npchYaBA8`E@3q{pcz>rT)#ZrUCub8BjQir59 z?GHH>%10ovmJ$8jN0tY_X#_n!YwxCm!|f z|Ka2U@lws%yjTQKlM%Q9h}oo!+t?hTIo;D2 zkY@}GI=683c*!Yz&Vx)rCJ&5a?S}k0aLhs)KR?)%z7dk4`w4Uo%?J2~Y&l)kZe{Z- zM@;kaUgN{|+6}~by*O=T{>!IYzT_&fl8&M3;3}>zTl_D;~Bq&e* zv;*PcGok=S#O^Lu29E(<$m&zktB6E8Bt31)W)xuQL3MCI{&vR`kr*02S#Wj>P;+6y z4gFIH*FMuchg}~x^y?;5rr5ZuqBs_pLm^!KtbO?f`GL~!xrJYPY`H8NZc^mH{HFp{ zupok!au-9n7MS_w|BAt1X--TICDp&*RsEd-O~|K;uq;2&rP- z$B-n{6t$7HcDz10?;TER5o^pI7K zD0nu$*7p0ilOPqSj#*j0tes3nYiCp#4!zV;k^+7;9)1t(uC_y}Q%7r+>u4MAXe?tJ zPuUQXL;fncLuqe&Sk62hGKaGv0nv6>5Hc#rz2dEs1~ED^6p)WUbUNk1a@ZxrLWC`7 z5NlNf?cqfi*+U93utC{_61EMm2EfA%Tw>6agdzcU9Lf@-w5Ar(_x#@+4q;@|xiLG8 zjEV+QuM$Xygbthsjp`qlmKLZyR4qEjf^vnuA}lC8Mo#ktSU|%@0!cK8zG4voxQjYB zUqYmD?a`tA?YG~qEC5h@18gqS&+Xe{=0CRVKKNh@+fXp2jXrTxRx^k2D=U`GJNC%$ zjr#OISby4!hcSfuKMd=Br|{Y>HG2rd_H>P6+~gf2)F;zD;G*hVstM!zr6_C z637%4Y@)(ZO=U#OCbAplk=t4ku)o}X3x9$QGKf@Ao1~*ixQl$Gs0>y2j0@TuGfJsp z!dn_3W&$`?obrsD(M&}7J+zwD37J9*g;x;6IM| z8P^-k`;;Clf}cZp62S^a=h1*5FdkvYdbGWh5aY{#d{zmQezLg42ak#l(^8O8z9MCq zq^paH9*8*5`b*;J?|YjaV*OAXn$U3s1MDS^)v* znnU;-pa64pVaz*Oq;Oyzkpeoz07ZZ76hH#qhy<9!IJ4pdZe$_mc0LC;R##5ANqOFC z@a@XNOTYT^U*g(f(XQC)i#d?#7`}`6o6+`c|3(W+g7~ISx`LlLcZ;nIqhR3BmXH4VzF&t=M&ku- zv2W8i3@yRa>J*gHibjnO^9m9^#lDcgt#hn(4^EQrvO|odT}|nLy*;|fp(*+v6u+dv)xfL;`pM zcN~2c2@v0QOd|oVylzAS3r?HEN2FA;vGEsWgwH>8FO#Hj+r>*SIG>cMVqdP1q+k5w zbND%Q+R(cQdiogLb~|{|g+S8uF+ju))Zk3+@G6J)!3xP(MEIuJ(4U|a^vhTSuT`i6lt5N~|r3-aDHuMHZ`tC~$ZfhQ#?CjIpP|0m6yjcI~( zbr{Rw6$MaA0+i+)cZ_X)#2Ig%DLj7f9T%T=ve*Zn#%N*k(Bv%!nKe9g$SXn|5DK`i z4GT~xhQP3yGI!ii%5K}{KTNrV1EQk%8|4%7ph`;+^*(H$;KuN=eT45POw7{YTI5Sn zE9lWiyyEBiXP;3eub#`?kk#YHx}q9}y{xScFRB!;l%(8d5cE2@9i(7I1Pmen&$cD0dUiKs?FNvuZ}|^HY{7 ztB|5X8GvRMow25-P_=~o{LC%uNHg*tx@$X-FbQ$D?;i#38=DJ|Px-~D}aL&op zep{+F!~a{7@Y!cuUvSgdEgaE`{W=GVSbXw*-^sP6UYevAJ@WZ~K2?IEw(Nu`K8flDHh$lB76~ zrJ+xPEkQs!a1&|f<0lQ^2GwGy4(Zd1NGAE}-(MoPVK#Lh%HAYiZMTar>Le4gF~yNW|tE%r%*8> zOjeBxY!-E!ujQr^z-@TKU1Qd`4F`)@KaE%TgB*miQX3y}-%vN}$f63yD0 zcV5Y(JPV$;2;-Muct7Snci)|!^HaW|khDXd1d6c?YMOvDO57!a9awkJY!c^`gQ^a# zu-6j`O|QT_SFU;PnKjR^Qay~yRFfuVHoES2hCHOm>W6lKvP!ly( zG!w(8>bpJ8#x%fT+ZMJvm-3LKN>B7?%V!m!I`oF*ke@I@2*`n|1A4BI3u38sv$B|6 zCpa)GtSLMsk3cLo%<@Xrz9iR8UltjKbCMjFjLMSQe$xr20(*F*F$$YlgZ$aMiY-H0 zCc56o(2Peu&P~HS^{;O1Nt3Yz_B1@FJ6Cl)+C3nTx(bqiteZem{+( zE^>BJQCO@)^}qsw7?c3&aCqxW=7K)~0pI{g=Oi8U7Na06&Put3@q!9CvW5jEJkcs+ z^>&tdR}?o9602e41V_~mD)V%FSj3R~%jOr81rzx&kb%5FgLvH}vr!MQRM{~igMtTF z&DUY5D2s!I(8cj^En2kYlON?}4Wj%ULF&bEI7oDqq9de2lDb_d@SN@xY{z@e*Nqr* zD^W`G`=-qcd{`*=B!E>VLAq2#ih0d9cxH=AF zn#S)tOddH282vDZ zS#vP~nzsXtuC-}`6?=qFTNWewDP@NPBL|?+y<&S|ze^dJ+2k~Js1-w+Hnp$WsWwo{#lBxW! zrA4>RS$)(>|8o(6VEeQYLIj@EaIjoUK)8FlMWL5MJO`G7W0MXM5TOF<3XOLk8*PRb&Hi-v<0K`ma8jHU5cyk z^$${vZt0bv)Js|)VQ2gZbJD2XPUE7YaMWNaz!kD}Qkd_$-oPJ(@fi%$2*K7+{iLKe z<58{P8Uu2(xKK!vMqSh``2`sOoPewAxUSrrcUC{ilQ|rl8qR9G$P%g9Nola?-i$fq z!;s%j4ahG<>sKCHRli<-`fsk&Qm(srekuv$@WSpmfAAlru-c3>!%#HL)(MiuAu#8g zGH;csJwgZ`z#)YCl|FJgDN()AzXSC)YaN-Va%Mh7TSbmdKXUr#Y87)AAk!zcan z;NlzB=$*ILu2``GN{{XyQ#=#U@Fi-h>(~XL!H{S^i~>{uMg7Dy&KeoK_US}>zlt`J z1z5dzt$u^W^rb8%W?+5N1Gsl^w&4b}8U_>%C)Xi-Fc_nfpDBH!-T2Jol>EnTzmeww zC!~aMJ43A_fAvdcSUi-$rJRT&QQYqw7frNXzEJQ2pQQhzK6<-viUIa$oC4g2vHj)+ zuo}qZ6KsLLgr$oS->_uKD=)t+orYuKqYvI^@(exC!#l|i3Owm%7_=8`gc<`&aS|W} zKuZ(MhwWN|whvGv(kMLG_0#wNSvU+4p&xIQp=DKwOJwEe# zD^RYph?xen4s2n&;J*Ym{Cs`n7cqhSz9FYV<-1PZBn--H9f%~DN%O({Y3VRu0d0S> ze_fZmLjNohxaPO#3y?v5IIKg5J(c>TQ1yScFHUA)iS!|AJDN}bDt38{(!gBtap3v# z-{{``UlU&}8YySi7h-gyAK)j>Ecx92l)C86P>P?}>QdQ&nkz#J;f0ncGuTKeIn5Eb zV!3gK3Uuhu0P?$z31DIjHyB%GvA>V&uz-9yHsJuEWb zg}_pJ%Q6*e)lhL=C`u=6;kK)<)CrXyd*|czf&5&)TxzJbZmE+g7IC*-%@G6y9EGvq zHk~bUhr(~}mYAJen2%1OJzxSgwAYd#Adzhay78j(j4+4C@yyGOL^Z=|00;_C)1e7w zPrCN8n-C@~`o>ExaHTRUB)S6^Ejr#^sE9X8G=lt>oqB@DMdy#&6XeH-EtbqQ$ZuXU zwS?pCq;oH9=ks@qqQPFK(%w7oWc;AC@O%)L6UH-{`wLuPD_yYZP9reVJRHImKAuP zbl_t~g|}m6%zrPe!O*x1*3Y+}bfZ6Y1{pZ_Jjmdg3BDb!xb9g0mhZlz2cSc+$OI~y z4xT#@l2||X%X;v438io@GTsMe1iAR_QP-r9nzZsQ#Hbm2N?qU=We^xVp zLMK1l8E4A)@Fe7q+9MhT_v~Z!iVfnGL*S#=Ua&h!W7xjqaLq)9m0d0ms)7qZmLSCx$6N$&QQk!Lge+?2*5E#ku9EPGFa%B(gc2iBzl}Q}Qbq z>N)7a)^JXP<*D%P98)3-{ECSY5EKR<-7+QcXHGCr$Lc3Xk9thDh;lZpi`*f>Q$&HT zsWcpDLw&VI_`h<3CsSrT7iUlwb=AtJ9)I*<1px6O9WiY7Rq zeWni%Ad_q>{sc%)djv5c4c|ZxE`k!+QdEGBbddXMKi~w9>%9a54Kz0z-4Gfc!F52l zQC9S4|FsE^E7KCca@~5_!lvq7#tbELLQ;FnVLYF@f<<_#?J5?Ix?af7+v7?hKWud+j5KC+6Sv{lI*sv-N1-0$o*HAZu#Htso#{ zYnYqCkni#18A%wR#r3P+=n_^z#Tz>ZhpU-KW8H8DT2f|U6pFC!#%8|^iX-2J0woZl zBLZ~KpYFKz)J;iqwlG(l$SfBVH zcYXi`5cq_#cUwNuAiNzy;9Jk3nOzSOBq*O$(AYbCo|rkT!%}?AI=)JlEDSea>QE#m zFgELH#d1)B`6e68M<&d0Z%Cn-73Nzq#0Us%?ae6-tEW`1G-aBIsr0N(AhLmt1I>kND{-o;UQ&JaS7oq_$-6> z*=2Wgh8rH_gx)T~?MZ@(50>Z=ASN2jLOlOG$8% z5!w{R!4@-o1Gg7DrmMhY;2j=V9E*UDlx78ogCtfN+S9AiW65-E)6!#ZbSL5f6-cCeCAN z$HaSUUitX#H+bFEM&oqlhxFl)gz6IDd1;`!>K1%o^XE4{j3mEXQvwI+-!`?`vn<~m z!ox#wAjp7%kI_sS>9ABwstC}bI4}Vaa|Z!%Fn2J4u1Fv@FA)jb!}HzlI$m+#tv4t` zSD0^LB5oXg65ED0RF(!W71~>V?G-SVGgIeQ7N4QQd3i4Qq^yKmn$f!LN#P#U8<7fU zx?aO~FQpoK!zfpR{GzT@9al7?`D68;z4x})V#0I5R*ctAN*O2)Bg4VPF#PciT8gqB zn5cG1h#<$;?Hzxu66UDZ92_7haSY-tBb4q1<j05TXbiqU@1ytH1-CI&L#o3QaT^5$!tF6Ai;mHOs>tIBN6e^}PPprN!(>U(0ce}x zIs8@Xi{6z3s|{QeJJ&BL3DVhv8tH6GQqjLH*#pHd=Zsgb&l+TX=lDj@c9pa?*|8@#hqt z*v&SD?bJd@&OY)XM!^t&uy**o*?FQzryq|%(LHXrxNXqhr0{voz(IR|5|n;I?_h!n zxIGksSfnw`nfa^Xd`0ot9i*O|t{N?U%()I#S`#HXaqnG8c7JlWy1va8TNtF6xY6bo zX)`$y#jrP)K3scmyMD_?s=*8uY={l_!dFi_vt+Y#>^6|nW}>ELf1>kmBKo7c#FuyyRY(~igg>JV->3?!uR{cFDbzpy zpDClOPV^?GnG3RmtOABF8=N8`H(=Co;(tZ~RgFogE}|r7!g^8zrUAB3MK7f&sxP_F z*8Qd>#&6vzIj|^%V7;J+yX;`{6U4yw(M5jkQDcIiLpdG;*ywg`I5&KF1C&F#WzprL z?H8PKl5n961T{t!l10LFVEoWDeZ*Y(as_Px*|t^%5Fm!S;v51Tad^8iG)<=8u z<8cGnORjk|qKjzkKLSJ=p`|Ky=h5()S^dPlcX~sj+FVq9q3}2}ciiOrFnR5Zt16iX z5F+d4g>wEVt!cX!)tWjDXCNM43ZH2*U5`}0@mS6l+;!JJA;EhnBna^y!#&8~w&C=# zU>nu1pMRDfkQ>wr^4l&dJIh51n2kl4hNl~?Hh?T46F#F9bzt_|eRmj6qTwmXCvztP zn*KBQ9N!SBZB07$fASNHSkVtT4A#qL4daCNT(W4;w{xR)(f6_?*Px4GJz;~PFmo4p zsV+S~5og`9zAXy#JdfZ2p<0W9Qm5&Ga$q@;V2s<$b+s0*wQd566 zcv*Zie>T}zZiXDB`>wf60V0@hwCE_es~fL~oT^;a8_sD8h@BoQIrE&OkB~nPQK2zB zfr>nw@JDJ*u~6gyd8qwek4|1XBZZradCNdpax9ZfZ?xOx#CTjRZV+|JnH_(6;`KzC$JiUAZ=6A7}}%F=sD~T57mZD zL49bDVvIQt4^T~d?cF#1QKYzjvUWI_NFQ(T%a1(ZePjYvnPb{edOu(LiU`G|kgjYl zSr)jNEPdG9jqF@V0wLiH&Oh8{9@CPKMN4gLvl20+eW^X`PcKcl;i9=LO3BhTN5EJd zm5KuKeE2OPKh@ep6?UKn8KD)&SWY?Ss4f0$s+4BPVB%!KHs7COMn2nawH3R5;RW-s zEErf*7RRSDVG#t1>eFCOS@J8%a`icZm+-WQ2=@xG5Ep#xZmaMEN*KujQ&QB14I%HIg0zN2lDEN!$4Jg8Q!^4}F z;Kp!F1D+O>3PPHN+Z*2Zm~SB*Ar03ZhyqC(3`@klm@}!TD+7q40^5Cp?MM&fG7Az% z|8CTS-gF+EH((@eY})(i1QloolHh>Kv~(|S1`hgJf7g#x5OPFhma$fEXATTKh|iNU z@6C5to_HkVimGq?kxll|%cg$!rDtsp8ZArv---jvyK7#R38^4zH_{EDv5aL3gJ;o{ zByC1>@XdZivm6c@BNn+gX06%PXP-)$ccZryfjL)+DR>K*4euE2wCyHdYsGRQ3v52( zyF*8cIH_MM6&!2<9}raQlGDp!!rOy7%woLjByir{Dp$y&$71PI0) zw2xWD4L)?*gAbP!ZI&PY@2|at)p)7v5NMtS^XVQ^C9gZ{K&gO{ItMg1o9FKr`H+NnYm0_ztFw z704u!q2!YAD!V5yIjN#}lrnL6=-&u-KkBzNe|k#iS= z?b>tX8V^E4GLa63g!=TaG5%(P06U@NoYCIF4ei;~45DGl!N7qEO1LKpRyy3I9TPgF z=TkwYlPUSgqsTF3js;KQr!W5gI{7|?e+Ga}sfnRx8k06?4>zn7JsD!yNQKEuZ*ax+ zZlpZ$unEHY6Kc7>So&` zY*YuHh3;(&-hT&S=t8#X>HokTx8t3r7x8H@OPLAEj;Wf9;lo4I#6z0pd*m(Jj~ z*;)dC{ladP_=W@1fc=UeI#QQ8bOXX(erbf4MPx2Xw|P zQIO9OO)5FHCByHa)o%D9Wm6QNt+;$o_l2g;eO{lqF(F; z@$g&Uf&|<<@Mq4n{nD-C)oRP^Gj$^|RwzVcfit{h{E%tTcD|f@Ha%gZ?@gf|3p`2M T+G;ot}6p5R*p+v5H&`~cHe literal 0 HcmV?d00001 diff --git a/src/samples/gu/spharm/Makefile.sample b/src/samples/gu/spharm/Makefile.sample new file mode 100644 index 00000000..72a613de --- /dev/null +++ b/src/samples/gu/spharm/Makefile.sample @@ -0,0 +1,25 @@ +TARGET = spharm +OBJS = cube.o spharm.o disablefpu.o mt19937.o logo.o logo2.o logo3.o + +INCDIR = +CFLAGS = -G0 -Wall -fno-exceptions +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = +LIBS= -lpspgum -lpspgu -lm + +EXTRA_TARGETS = convlogo EBOOT.PBP +PSP_EBOOT_TITLE = adresd - spharm v1.0 + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak + +convlogo: + bin2o -i logo.raw logo.o logo + bin2o -i Image1.raw logo2.o logo2 + bin2o -i Image2.raw logo3.o logo3 + +copyms: + cp -f EBOOT.PBP /cygdrive/I/PSP/GAME/SPHARM diff --git a/src/samples/gu/spharm/cube.c b/src/samples/gu/spharm/cube.c new file mode 100644 index 00000000..4915fe35 --- /dev/null +++ b/src/samples/gu/spharm/cube.c @@ -0,0 +1,267 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +PSP_MODULE_INFO("SceGu Cube", 0, 1, 1); +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER); + +#define printf pspDebugScreenPrintf + +static unsigned int __attribute__((aligned(16))) list[262144]; + +struct Vertex +{ + float u, v; + unsigned int color; + float x,y,z; +}; + +struct Vertex __attribute__((aligned(16))) vertices[12*3] = +{ + {0, 0, 0xff7f0000,-1,-1, 1}, // 0 + {1, 0, 0xff7f0000,-1, 1, 1}, // 4 + {1, 1, 0xff7f0000, 1, 1, 1}, // 5 + + {0, 0, 0xff7f0000,-1,-1, 1}, // 0 + {1, 1, 0xff7f0000, 1, 1, 1}, // 5 + {0, 1, 0xff7f0000, 1,-1, 1}, // 1 + + {0, 0, 0xff7f0000,-1,-1,-1}, // 3 + {1, 0, 0xff7f0000, 1,-1,-1}, // 2 + {1, 1, 0xff7f0000, 1, 1,-1}, // 6 + + {0, 0, 0xff7f0000,-1,-1,-1}, // 3 + {1, 1, 0xff7f0000, 1, 1,-1}, // 6 + {0, 1, 0xff7f0000,-1, 1,-1}, // 7 + + {0, 0, 0xff007f00, 1,-1,-1}, // 0 + {1, 0, 0xff007f00, 1,-1, 1}, // 3 + {1, 1, 0xff007f00, 1, 1, 1}, // 7 + + {0, 0, 0xff007f00, 1,-1,-1}, // 0 + {1, 1, 0xff007f00, 1, 1, 1}, // 7 + {0, 1, 0xff007f00, 1, 1,-1}, // 4 + + {0, 0, 0xff007f00,-1,-1,-1}, // 0 + {1, 0, 0xff007f00,-1, 1,-1}, // 3 + {1, 1, 0xff007f00,-1, 1, 1}, // 7 + + {0, 0, 0xff007f00,-1,-1,-1}, // 0 + {1, 1, 0xff007f00,-1, 1, 1}, // 7 + {0, 1, 0xff007f00,-1,-1, 1}, // 4 + + {0, 0, 0xff00007f,-1, 1,-1}, // 0 + {1, 0, 0xff00007f, 1, 1,-1}, // 1 + {1, 1, 0xff00007f, 1, 1, 1}, // 2 + + {0, 0, 0xff00007f,-1, 1,-1}, // 0 + {1, 1, 0xff00007f, 1, 1, 1}, // 2 + {0, 1, 0xff00007f,-1, 1, 1}, // 3 + + {0, 0, 0xff00007f,-1,-1,-1}, // 4 + {1, 0, 0xff00007f,-1,-1, 1}, // 7 + {1, 1, 0xff00007f, 1,-1, 1}, // 6 + + {0, 0, 0xff00007f,-1,-1,-1}, // 4 + {1, 1, 0xff00007f, 1,-1, 1}, // 6 + {0, 1, 0xff00007f, 1,-1,-1}, // 5 +}; + +int done = 0; +/* Exit callback */ +int exit_callback(void) +{ + done = 1; + return 0; +} + +/* Callback thread */ +void CallbackThread(void *arg) +{ + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + + sceKernelSleepThreadCB(); +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0); + if(thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} + +extern void SpharmGenTest(int rendermode); +unsigned char *convertimage(unsigned char *inptr,int size); + +extern unsigned char logo_start[]; + +#define BUF_WIDTH (512) +#define SCR_WIDTH (480) +#define SCR_HEIGHT (272) +#define PIXEL_SIZE (4) /* change this if you change to another screenmode */ +#define FRAME_SIZE (BUF_WIDTH * SCR_HEIGHT * PIXEL_SIZE) +#define ZBUF_SIZE (BUF_WIDTH SCR_HEIGHT * 2) /* zbuffer seems to be 16-bit? */ + +unsigned char *logo_temp2; + +// from disablefpu.S +extern void _DisableFPUExceptions(void); + +int main(int argc, char* argv[]) +{ + SceCtrlData pad; + unsigned int buttonsold = 0; + int rendermode = 0; + int i = 0; + int val = 0; + + _DisableFPUExceptions(); + + pspDebugScreenInit(); + //printf("Bootpath: %s\n", g_elf_name); + SetupCallbacks(); + + // Setup Pad + sceCtrlSetSamplingCycle(0); + sceCtrlSetSamplingMode(0); + + sceGuInit(); + + printf("INIT OK\n"); + + logo_temp2 = convertimage(logo_start,64); + + // setup + sceGuStart(0,list); + sceGuDrawBuffer(GU_PSM_8888,(void*)0,BUF_WIDTH); + sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,(void*)0x88000,BUF_WIDTH); + sceGuDepthBuffer((void*)0x110000,BUF_WIDTH); + sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); + sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); + sceGuDepthRange(0xc350,0x2710);//0xc350=50000 0x2710=10000 + sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + sceGuBlendFunc(0,2,3,0,0); + sceGuEnable(GU_BLEND); + sceGuDepthFunc(GU_GEQUAL); + sceGuEnable(GU_DEPTH_TEST); + sceGuShadeModel(GU_SMOOTH); + sceGuFrontFace(GU_CW); // NOTE: not CCW + sceGuEnable(GU_CULL_FACE); + //sceGuEnable(GU_STATE_TEXTURE); + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuDisplay(1); + + sceCtrlReadBufferPositive(&pad, 1); + buttonsold = pad.Buttons; + + + while (!done) + { + unsigned int x,y; + + sceGuStart(0,list); + + sceGuClearColor(0); + sceGuClearDepth(0); + sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); + + val++; + + sceGumMatrixMode(GU_PROJECTION); + sceGumLoadIdentity(); + sceGumPerspective(75.0f,16.0/9.0f,1.0f,1000.0f); + + sceGumMatrixMode(GU_VIEW); + sceGumLoadIdentity(); + + sceGumMatrixMode(GU_TEXTURE); + sceGumLoadIdentity(); + + sceGumMatrixMode(GU_MODEL); + { + ScePspFVector3 pos = {-6.5f,-3.5f,-7.0f}; + ScePspFVector3 rot = {val * 0.79f * (GU_PI/180.0f), val * 0.98f * (GU_PI/180.0f), val * 1.32f * (GU_PI/180.0f)}; + + sceGumLoadIdentity(); + sceGumTranslate(&pos); + sceGumRotateXYZ(&rot); + } + + sceGuTexMode(GU_PSM_8888,0,0,0); + sceGuTexImage(0,64,64,64,logo_temp2); + sceGuTexFunc(GU_TFX_ADD,GU_TCC_RGB); + sceGuTexFilter(GU_LINEAR,GU_LINEAR); + sceGuTexScale(1.0f,1.0f); + sceGuTexOffset(0.0f,0.0f); + sceGuAmbientColor(0xff101010); + + sceGuTexMapMode(0,0,0); + sceGuDisable(GU_LIGHTING); + sceGuEnable(GU_TEXTURE_2D); + + sceGumDrawArray(GU_TRIANGLES,GU_TEXTURE_32BITF|GU_COLOR_8888|GU_VERTEX_32BITF|GU_TRANSFORM_3D,12*3,0,vertices); + + // now for the spherical harmonics + sceGumMatrixMode(GU_MODEL); + { + ScePspFVector3 pos = {0,0,-130.0f}; + ScePspFVector3 rot = {val * 0.79f * (GU_PI/180.0f), val * 0.98f * (GU_PI/180.0f), val * 1.32f * (GU_PI/180.0f)}; + + sceGumLoadIdentity(); + sceGumTranslate(&pos); + sceGumRotateXYZ(&rot); + } + sceGuFinish(); + //sceGuSync(0,0); + + SpharmGenTest(rendermode); + + sceCtrlReadBufferPositive(&pad, 1); + if (buttonsold != pad.Buttons) { + if (pad.Buttons & PSP_CTRL_LEFT) { + if (rendermode > 0) rendermode--; + } + if (pad.Buttons & PSP_CTRL_RIGHT) { + if (rendermode < 9) rendermode++; + } + if (pad.Buttons & PSP_CTRL_UP) { + rendermode = 0; + } + if (pad.Buttons & PSP_CTRL_DOWN) { + rendermode = 9; + } + } + buttonsold = pad.Buttons; + + sceGuSync(0,0); + sceDisplayWaitVblankStart(); + sceGuSwapBuffers(); + } + + sceGuTerm(); + + sceKernelExitGame(); + return 0; +} diff --git a/src/samples/gu/spharm/disablefpu.S b/src/samples/gu/spharm/disablefpu.S new file mode 100644 index 00000000..daaf14f2 --- /dev/null +++ b/src/samples/gu/spharm/disablefpu.S @@ -0,0 +1,22 @@ +/* +# +# This disables FPU exceptions +# +# extern void _DisableFPUExceptions(void); +*/ + +#include + + .set push + .set noreorder + .globl _DisableFPUExceptions + .ent _DisableFPUExceptions +_DisableFPUExceptions: + cfc1 $2, $31 + lui $8, 0x80 + and $8, $2, $8 # Mask off all bits except for 23 of FCR + ctc1 $8, $31 + jr $31 + nop + .end _DisableFPUExceptions + .set pop diff --git a/src/samples/gu/spharm/logo.raw b/src/samples/gu/spharm/logo.raw new file mode 100644 index 0000000000000000000000000000000000000000..6a4ce72356990e54ed49ca3d12aac320c1aaa40d GIT binary patch literal 12288 zcmeI22V7IhzQ?bwbx{#Ta22E}MF`D6C;6 zMT!(DK?J0RPC}?51VRf_3qvG?tbpueUJI@IZWovne#jUGiPT0 z-}(RPPb=wnVF6)bVKmxMPtQ(K(Q3;Uv0v7NLZKWSy!G{oDk{iduKCfkGBPU0#;(@Z zULqn&AFc3@3gN!T-X_Q_ujA?I+0`}H(lT98FcKZz7!gq&92~QH_3GtymghY^j~5m) zlad&Ce9-dpUzyj{B_<}e*47RpksE)3j>S@)_cA0>NK?~fZS91UQ}BDIe$7u!O_%uib{dVNsrld5|LkpAuHW9? zyTAWAoBcdI{M%KlR%>Wz1qTN^Ir$zqps%c~VQ=q`!FWhZYa$RPl9C#Hd6t$QH8m^> zg@wn5=;@hhY8tFrvwlgrsHl{joUyL1`OclY`Gty#NH;fs4GkwW+D2dB#MG301HZziO*guNM-|x%Gp;0KkQBie7;^%PIz<@}ljy-uYnwr}7@FA_Fr2E{t z+_h^rz^Raski5K>#6)Ua+aQB6tfj?!i53=K)z$2%s7B~E3E6BZhYn@v=$ysj9*&MK z3=gwSOiVtiA9RX~t3*bY*VhlcdGq66|N2)hcd@#9P(WZS26MEhXL51zd1`9v{rmSP zCZ2V74;va<;c%W@?gBi}#fwQ%QE?p|Tq<=Ei}l6fp#B7vIu#t86CYnQKK?8=woyyV z%-1(?a&o?+V#voQ3T~&N;oR0X(cH{IARG(~Y~$mbnwmIzdSSxCN+KfGTeg@B2|0<0 z`CC~f69^^N)`gEBkB*Mc`1<<(BmK}O^n5cjVopw5Qxo$qfBBE5rg3$3Lv3xBk&&6j z#l^E{&&I{YF_|-+onsajNAY;yiHR2s#)7?lAbi4IT{AsBvu0-Ac6NbXUEG3#p$iw9 zN=gR%`nX9+G-#Gc421VsQ8D7+z#Ff$wVfLpMk_0aq5l{dxaH+B%F72774dM2pVq9| zrluB`mPQK+p^!+Wxw%8Vz1+aS;E(FZVr`(@!NFHTLiW>7H$_Di(&|mgS z&a<%aJTC6eci&~O*$WvNT__Y5hRwmj#g-PXm6Z<$a>`pj1_|?>m)z@=~!~jru;DAee`#21D>gsq^RcuU5V|De2w)SyB z!F}7dS!~;8xoekqL`2QQheKHG7xwm1MMcB#3OqalKB}KYB8`oWu~^)!tS12hXEHK+ zySuqDF}1sQOJgu@V8ik8g_;_ASy>l{^D;cVSzKJs#U)^DY_6kY;_zV)0|Nqx9~$Bk ziC_V#q@?=E$!9PKKX_2v+&p~jSc#^lvA1_XZ7r+4eGJAr(2qvD_Vmoa>(J353JXg( zIc2xDPMVvisHt5K45Y})-WCyY3=Ax9X_@fz%LomvV6hfqgt4*l_V*9^aQs=fZe3|< zX>adPdOAHemX@5{m6b&e2{{Qjva#_R8JU}&e%jc`rclOXW4pb)u0lDP4E=e!u8wJK z?QU!9!D5YfcCv{?GMpljPR7Smb8`Cf^7^Bro5cHfi zolU!OqfJML1V7c)3GVLsuC9f0a`F25$x2GWt5*wHTW3Ojm`qQddYqZrd--yUmKF&H zVJ??9fx(M_3zrhyLQZbKs;VU#?Pg|%+q-uk|CEyxd3t&QhMlmmSW{Ck6v~`m&Y#B* z9Xcv0iBMKP;O`%d!}-d}zFSL(h)9{45$x=|BqdeXtXT_}$jTl-A_-Wm4+6oPL8PQq zq1&sgyNHP?^BWWvmfy3-dfPUm_3K6XB|<`yT3Q4Y%1%Ya42>qCP$Ur%#J+uMzP>>q z{=M}B|B?@npdb4Dz`zSjOP+22aOubq@BIAH?CcS9bB{lqco4j2kE*7om!YADyuA7! zQU8kO6$`9bV8sF}7WhAGfh8z`MDn17galGmm1u44sj2y27{$NY0&Caq6&1x=Sh)Yw zrA}}#4@z)2bDo}|Akx&-GbyPnKYzf*#qZy&dHL-={nXsmwLCME9uV+P5Qn#S(ER-K ziHYys+>S#FHZ~sMvw$0AWyM>o|8FJGPau?Cxza))`2Mm6JU)QUe!*hBaB$!)GF@HC zi;K@jN9XPB->o@?gm%iw9aK^>-mya(+)St=E31ydkhHZ4Xf#e++gMxM$k334L^>f5 zdMK2Us;a?;4Vwi71dWZYm6WvjT!OD*{rXSQXyXG1j06SWt&_#Y5ztBC+Rr{y78gf~ ziXvC9UI&#yzpCopLx&0u9eTHP+`W6Zxw*NOl@(<8t?`c*7XDP~TwB{zc=#<4pOKLX zJ`R`r6r5bBaQSk2Y-~qzayz&QGCB2=Pk3GcK%|I>s?JVUMn>DolO>9Z+E94#pzFPR zv|G1YPMxB-x;}7q%~w#kx@y(BO`9zI{VT)5>NGTnPz{H}0omYiIN&O>+3f4ruR|d} zp->)$g(G!!aNpjMkx{4s`se4L+1dFkD;s|I9SCcTkG})ulaq_JwS9($#tsf%gM-s- z_H1!+Yh7KFmsc=g2L@xRx|%_w(Ez9P^h}qQcGc9hF`2X1uUDf`#zI2dFJG<(moPuS zGc2s4zJBcP-G+@DH|yyU!1<+6hC@Tkot@L)I+7V1HzK!gwM!SJvTQ8VwS#Z9Ua%IDt1G|L}X+NnH-drl?@L2)YMBmyC5XeIw0U0h0+L* z{Pw};1_q{`oOnJX@SoAqxl^ZNzz8^;UuP#Eh`CFblCNHkZ*QNjtsM^uxpC^$*R8D+ zm6c2q$;-mxaAsyZV3UxL>uzq}_V&(ZX12=6pfMO?ef>yT*^s5>SzX=F)6;vx!)rHh zHU}>r@&yHh^742krNdO}5U{DFq$FKkUGTpk+1S|d?eF5^J2p1o(J^gi<^?6r&VEeh zBH&PP3Abz!NlvbvpI-p}0{X#c@9Ue!Vm)kay~oF&4-GB4xbWR%Um9(;y`5`qO@?Qw zub-%{=GfZ$dUymwv(3#D1VSJV=U-C7Y-r$+NXH0-bG5Z2`S}cGWqU0xmx>BzY3YE9 zii4b-Q$j)~_{Bm(mfN>mWo7l2l?|(^Ix8s=;C;=`J`D>C<7-}igz*zP4EX7`w!9A( zhYM(LpKocIf=^OQ%dx(GcxLA5)vGsRV-tslW*QpCO-#J(>;m8!J33~~&3R*#si`ZS zK1riZ0%rrXMWv2*bd0;Y`T@40QaLp>qxSZ`NTkKxyIm~SLP$uolT!?XF>~imqqH;{ z5N=V?KtVyjqN2T&lucY*JLm`TqN3Khx&4)uENyL~qN2^6J6%BG;^X6yNF?9>j*gD} zr+}ZJA3j(Dfj8hgI|ny6Pc=4<0vkc0tcr>lT<)`+oJSN2oy&byRW)g0L3VZyfB~wf zXUfvj9WJr7Jj!HpVbt~X^oLKQql44eH$@u_vr+qd8H^zYt{Ei4?Yssb)V+_p`^)3bDN zaK5>j*4Ea>@BfB|hD-Wk{+gWR;_*EFmX_X+9`!RAqX7Xyn>P#Q=C*Sc0CnE*e5OWfW4`uaF6Ei4xoGEgiqW=Y8~bfiOvynw#}dh+rLfof

K?k$6^ifjM*t-|V=gz~B*}h!?_=%pLtE8j~zov-D zemy-GM@N#hv^2kD<+x&j6$`9bV8sF}7Fe;siUt0ET7bV8g9RI(|NOQ_P*gksD@@o{ zgDtS%q~#^G{N*LI`5yoIP42SPh^?(>e0*D8UXO=I;8Nkgk^wvOHXxU6LB7X-{*}f* zycT@Ax;i#&5W{^xJo`T=fp);#g0$4&68~{=2?Bbfpuk(wV=(5xf50P?mE~=5iisf% z3_SJqz2xQ5@7;9Aj?aMqAP@#ZLVNghh+jcYP6LCnaBv6&|D~g2%H2IcQc@Xc18fuP z>)Xo9>uue-18TzlHEheu$mj_O@P6{s#*IoFHfV3&tn|qz{~4A8o;&cL(9qEL^e^$B z)YOLhdU{{qU_?X&k?298^aF+a@=KnlbN+l9xU{!#!zQxz-*3YEf9zN+@E<@T2?-51 zZq(eonFCQSP>#ok78kce)Jk@CCxi(>I=j1RJ7k^Ah=m20vrw{)0(@$k(^zGY4c)H&v9UTmX0>G#5%9Yz$ zSuGGY)7(4&Q7)2_`@Z?+@xsFQR4OAOp|PoH3|xD#zmd_=Cr`!(2j@DLqkg;1cgAz78kdKo%b6zTBW4EJ$Uf$wQH?*b|pyUp`IR|FwhSW1VGC2 z{=?@#5JM6XaWgF~=lkzp0XM^9o$lOe9Up&@lG1qQ%ta=X`NI!C+`CutckR6Y78bbE zr*9S(wq|AZ+_^&s{sU1cB$BU@5#ioF`oO^a*|WDk|2&1soQL2UaG4=&pr&S|yL-yP z;Y+w2gK@lhv$3UR?8J#QclXq~y0M_3hjMZOCr?)O_Rg7`r<BCYF?xyng+9xqd$X0e)y@6>#E2G?O_;qs`Dk|bC5<-x=FOiwI{Fn9RF}j< z2FPkf1&c}@Cy~yDg?$4E2d#55Zigr%f( z1AB>yiOJ5+e)a0ra{c@f31Yn}D(ID!jHgfEeDh7qXP?PH=*9KxbuVB3*wr=q`t^@x zWu42#L*Bpu```hsw|6=!Dz~_}ZE^7x^b_DeGBSwV+?JV{=lAc|pE(0zFk=%Fb5>SI zjf{xEg&=BHgRDg-V+#G-KARd9h!2AM(r> 11) +#define TEMPERING_SHIFT_S(y) (y << 7) +#define TEMPERING_SHIFT_T(y) (y << 15) +#define TEMPERING_SHIFT_L(y) (y >> 18) + +static unsigned long mt[N]; /* the array for the state vector */ +static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */ + +/* initializing the array with a NONZERO seed */ +void sgenrand(unsigned long seed) +{ + /* setting initial seeds to mt[N] using */ + /* the generator Line 25 of Table 1 in */ + /* [KNUTH 1981, The Art of Computer Programming */ + /* Vol. 2 (2nd Ed.), pp102] */ + mt[0]= seed & 0xffffffff; + for (mti=1; mti= N) { + int kk; + if (mti == N+1) /* if sgenrand() has not been called, */ + sgenrand(4357); /* a default initial seed is used */ + for (kk=0;kk> 1) ^ mag01[y & 0x1]; + } + for (;kk> 1) ^ mag01[y & 0x1]; + } + y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); + mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1]; + mti = 0; + } + y = mt[mti++]; + y ^= TEMPERING_SHIFT_U(y); + y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B; + y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C; + y ^= TEMPERING_SHIFT_L(y); + return (float)(((float)y)*(1.0f/4294967295.0f)); +} + diff --git a/src/samples/gu/spharm/mt19937.h b/src/samples/gu/spharm/mt19937.h new file mode 100644 index 00000000..d8cf3cf0 --- /dev/null +++ b/src/samples/gu/spharm/mt19937.h @@ -0,0 +1,16 @@ +#ifndef __MT19937_H +#define __MT19937_H + +#ifdef __cplusplus +extern "C" { +#endif + +void sgenrand(unsigned long seed); +float genrand(); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/samples/gu/spharm/readme b/src/samples/gu/spharm/readme new file mode 100644 index 00000000..7c74204d --- /dev/null +++ b/src/samples/gu/spharm/readme @@ -0,0 +1,19 @@ +Info file for : Spherical Harmonics +----------------------------------- + +coding & gfx: adresd + +Just a little demo to wet your appetites! + +LEFT/RIGHT change rendermode +Up = first mode +down = last mode + +Goes through a few pre-defined shapes, then onto random ones.. just interpolating +so it might get messy at times. + +Greets and thank you's go to: +----------------------------- +Everyone involved with pspsdk and the forums/sites under ps2dev.org + +Chip for his excellent work reversing sceGu :) diff --git a/src/samples/gu/spharm/spharm.c b/src/samples/gu/spharm/spharm.c new file mode 100644 index 00000000..3651a8e8 --- /dev/null +++ b/src/samples/gu/spharm/spharm.c @@ -0,0 +1,654 @@ +//////////////////////////////////////////////////////////////////////////////////////// +// Spherical Harmonic Surface +// Copyright (c) 2004,5 adresd +// +// calculated with each point, as done. +// as drawn re-uses previous strip for making the tri strips, so +// first strip may not be correct first run. +// +// Note that this code is highly unoptimized, but might be useful to learn from or so. +// +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "mt19937.h" + +/* +*/ + +#define PSP_GEVERT_SET(TEX,COL,NORM,VERT,INDEX,TRAN) ((TEX)|(COL<<2)|(NORM<<5)|(VERT<<7)|(INDEX<<11)|(TRAN<<23)) + + +#define PI (3.14159265358979323846f) +#define TWOPI (PI+PI) + +float shift23=(float)(1<<23); +float OOshift23=1.0f/(float)(1<<23); +static inline float floorf(float i) +{ // return largest integer that is less than or equal to i + float k = (float)((int) i); + if (k <= i) + return k; + else // if k greater than i + return k-1.0f; +} +static inline float myLog2(float i) +{ + float LogBodge=0.346607f; + float x; + float y; + x=*(int *)&i; + x*= OOshift23; //1/pow(2,23); + x=x-127; + + y=x-floorf(x); + y=(y-y*y)*LogBodge; + return x+y; +} +static inline float myPow2(float i) +{ + float PowBodge=0.33971f; + float x; + float y=i-floorf(i); + y=(y-y*y)*PowBodge; + + x=i+127-y; + x*= shift23; //pow(2,23); + *(int*)&x=(int)x; + return x; +} + +static inline float mypowf(float a, float b) +{ + return myPow2(b*myLog2(a)); +} + +static inline float invsqrtf (float x) +{ + float xhalf = 0.5f*x; + int i = *(int*)&x; + i = 0x5f3759df - (i >> 1); + x = *(float*)&i; + x = x*(1.5f - xhalf*x*x); + return x; +} + +static inline float mysqrtf(float val) +{ + float val2 = invsqrtf(val); + if (val2 == 0.0f) return 0.0f; // check for div by 0 + return (1.0f / val2); +} + +static int mi[8]; +static float mf[8]; +static float mft[8]; + +// Float Vector +typedef struct +{ + float x, y, z; +} FVec; +// Short Vector +typedef struct +{ + short x, y, z; +} SVec; +// Integer Vector +typedef struct +{ + int x, y, z; +} IVec; + +static inline void FVecMult(FVec *v0, const FVec *v1, const FVec *v2) +{ + v0->x = v1->x * v2->x; + v0->y = v1->y * v2->y; + v0->z = v1->z * v2->z; +} +static inline void FVecSub(FVec *v0, const FVec *v1, const FVec *v2) +{ + v0->x = v1->x - v2->x; + v0->y = v1->y - v2->y; + v0->z = v1->z - v2->z; +} +static inline void FVecAdd(FVec *v0, const FVec *v1, const FVec *v2) +{ + v0->x = v1->x + v2->x; + v0->y = v1->y + v2->y; + v0->z = v1->z + v2->z; +} +static inline void FVecCrossProduct(FVec *v0, const FVec *v1, const FVec *v2) +{ + v0->x = (v1->y * v2->z) - (v2->y * v1->z); + v0->y = (v1->z * v2->x) - (v2->z * v1->x); + v0->z = (v1->x * v2->y) - (v2->x * v1->y); +} +static inline void FVecNormalize(FVec *v0, const FVec *v1) +{ + float dist; + dist = (v1->x * v1->x) + (v1->y * v1->y) + (v1->z * v1->z); + dist = mysqrtf(dist); + v0->x = v1->x / dist; + v0->y = v1->y / dist; + v0->z = v1->z / dist; +} + + +static inline void objgen_spharm_calcnormal(FVec *point1,FVec *point2,FVec *point3,FVec *output) +{ + FVec temp1,temp2,temp3; + FVecSub(&temp1,point1,point2); + FVecSub(&temp2,point1,point3); + + FVecCrossProduct(&temp3,&temp1,&temp2); + FVecNormalize(output,&temp3); +} +static inline void objgen_spharm_Evaln(float theta, float phi, FVec *output,float dx,float dy, FVec *normal) +{ + float r,rp,rt,rtemp; + float sinphi,cosphi,sintheta,costheta; + float phix, thex; + FVec t1,t2; + phix = phi + dx; + thex = theta + dy; + + sinphi = sinf(phi); + cosphi = cosf(phi); + sintheta = sinf(theta); + costheta = cosf(theta); + + // eval posy,posx + rt = mypowf(sinf(mf[4]*theta),mf[5]); + rt += mypowf(cosf(mf[6]*theta),mf[7]); + rp = mypowf(sinf(mf[0]*phi),mf[1]); + rp += mypowf(cosf(mf[2]*phi),mf[3]); + r = rt + rp; + output->x = r * sinphi * costheta; + output->y = r * cosphi; + output->z = r * sinphi * sintheta; + + // eval posy+dy,posx + rtemp = mypowf(sinf(mf[4]*thex),mf[5]); + rtemp += mypowf(cosf(mf[6]*thex),mf[7]); + r = rtemp + rp; + t1.x = r * sinphi * cosf(thex); + t1.y = r * cosphi; + t1.z = r * sinphi * sinf(thex); + + // eval posy,posx+dx + rtemp = mypowf(sinf(mf[0]*phix),mf[1]); + rtemp += mypowf(cosf(mf[2]*phix),mf[3]); + r = rt + rtemp; + sinphi = sinf(phix); + t2.x = r * sinphi * costheta; + t2.y = r * cosf(phix); + t2.z = r * sinphi * sintheta; + // Calculate normal + objgen_spharm_calcnormal(output,&t1,&t2,normal); +} +void objgen_spharm_setparam(float v1,float v2,float v3, float v4, float v5, float v6, float v7, float v8) +{ + mf[0] = v1; + mf[1] = v2; + mf[2] = v3; + mf[3] = v4; + mf[4] = v5; + mf[5] = v6; + mf[6] = v7; + mf[7] = v8; +} +void objgen_spharm_setparamg(float v1,float v2,float v3, float v4, float v5, float v6, float v7, float v8) +{ + mft[0] = v1; + mft[1] = v2; + mft[2] = v3; + mft[3] = v4; + mft[4] = v5; + mft[5] = v6; + mft[6] = v7; + mft[7] = v8; +} + +void objgen_spharm_setparamt(int time,float v1,float v2,float v3, float v4, float v5, float v6, float v7, float v8) +{ + float ftime = (float)time; + mft[0] = (v1 - mf[0]) / ftime; + mft[1] = (v2 - mf[1]) / ftime; + mft[2] = (v3 - mf[2]) / ftime; + mft[3] = (v4 - mf[3]) / ftime; + mft[4] = (v5 - mf[4]) / ftime; + mft[5] = (v6 - mf[5]) / ftime; + mft[6] = (v7 - mf[6]) / ftime; + mft[7] = (v8 - mf[7]) / ftime; +} + +void objgen_spharm_tick() +{ + mf[0] += mft[0]; + mf[1] += mft[1]; + mf[2] += mft[2]; + mf[3] += mft[3]; + mf[4] += mft[4]; + mf[5] += mft[5]; + mf[6] += mft[6]; + mf[7] += mft[7]; +} + +void objgen_spharm_setparamc(char *ptr) +{ + int count; + for (count=0;count<8;count++) + { + mi[count] = (int)*(ptr+count); + mf[count] = (float)mi[count]; + } +} + + +// This is for the GU display list +static unsigned int __attribute__((aligned(16))) spharmlist[20*1024]; + +struct Vertex +{ + float u, v; + unsigned int color; + float nx,ny,nz; + float x,y,z; +}; +// current and previous list +static struct Vertex __attribute__((aligned(16))) vertices[20*1024]; +static struct Vertex __attribute__((aligned(16))) vertices2[20*1024]; +static struct Vertex __attribute__((aligned(16))) preverts[1024]; + + +#define ENABLE_GU +static FVec q; +static FVec n; +void SparmGenList(struct Vertex *vertptr,int xpoints,int ypoints,int color) +{ + int x,y; + float dx,dy; + float dx10,dy10; + float dtx,dty; + float texx,texy; + float posx,posy; + float dcolx,dcoly; + float colx,coly; + struct Vertex *verts; + struct Vertex *prevptr; + float ypoints2 = ypoints-2; + + dx = PI / (float)(xpoints - 1); + dy = TWOPI / (float)ypoints2; + + dx10 = dx / 50.0f; + dy10 = dy / 50.0f; + + dtx = 1.0f / (float)xpoints; + dty = 1.0f / (float)ypoints2; + + dcolx = 96.0f/(float)xpoints; + dcoly = 96.0f/(float)ypoints2; + + coly = 0.0f; + verts = vertptr; + + for (y=0;yu = texy; + verts->v = texx; + if (color) + verts->color = 0xff000020 | (((int)coly)<< 16) | (((int)colx)<<8); + else + verts->color = 0xff555555; + verts->x = q.x; + verts->y = q.y; + verts->z = q.z; + verts->nx = n.x; + verts->ny = n.y; + verts->nz = n.z; + verts++; +#if 0 // slower + memcpy(verts,prevptr,sizeof(struct Vertex)); + memcpy(prevptr,verts-1,sizeof(struct Vertex)); + verts++; +#else + // Add previous point to our list + verts->u = prevptr->u; + verts->v = prevptr->v; + verts->color = prevptr->color; + verts->x = prevptr->x; + verts->y = prevptr->y; + verts->z = prevptr->z; + verts->nx = prevptr->nx; + verts->ny = prevptr->ny; + verts->nz = prevptr->nz; + verts++; + // Save this point as previous + prevptr->u = texy; + prevptr->v = texx; + if (color) + prevptr->color = 0xff000020 | (((int)coly)<< 16) | (((int)colx)<<8); + else + prevptr->color = 0xff555555; + prevptr->x = q.x; + prevptr->y = q.y; + prevptr->z = q.z; + prevptr->nx = n.x; + prevptr->ny = n.y; + prevptr->nz = n.z; +#endif + // Move previous pointer on + prevptr++; + colx += dcolx; + } + coly += dcoly; + } +} + + +extern unsigned char logo2_start[]; +extern unsigned char logo3_start[]; + +unsigned char *logo2_temp; +unsigned char *logo3_temp; + +static int rendertype; + +ScePspFVector3 columns[4] = { + { 0.707f, 0.707f, 0.0f }, // cos(a), sin(a), tx + { -0.707f, 0.707f, 0.0f }, // -sin(a), cos(a), ty + { 0.86f, 0.5f, 0.0f }, + { -0.5f, 0.86f, 0.0f } + }; +static ScePspFVector3 lpos = {0.0f,0.0f,1.0f}; +static ScePspFVector3 lpos1 = {0.0f,1.0f,0.0f}; +static ScePspFVector3 lpos2 = {1.0f,0.0f,0.0f}; + +// converts the image and uploads it to vram in one go +#define VRAM_OFFSET ((512*280*4)*3) +// 0x198000 +static unsigned int vramaddr = 0; +unsigned char *convertimage(unsigned char *inptr,int size) +{ + // convert our raw image + // saved as raw. no header .. interleaved and order RGB + int x; + unsigned char *input = inptr; + unsigned char *output,*outptr; + int tsize = size*size; + if (vramaddr == 0) + vramaddr = (0x40000000 | (u32) sceGeEdramGetAddr()) + VRAM_OFFSET; + outptr = output = (unsigned char *)vramaddr; + for (x=0;x (TIME_LEN+TIME_PAUSE)) { + inited = 0; + } + if (count <= TIME_LEN ) objgen_spharm_tick(); + count++; + + if (inited == 0) { + inited = 1; + objtype++; + // default + switch(objtype) + { + case 0: + break; + case 1: + objgen_spharm_setparamt(TIME_LEN,40.0f,1.0f,40.0f,1.0f,1.0f,1.0f,1.0f,1.0f); + break; + case 2: + objgen_spharm_setparamt(TIME_LEN,20.0f,2.0f,20.0f,1.0f,1.0f,1.0f,1.0f,1.0f); + break; + case 3: + objgen_spharm_setparamt(TIME_LEN,10.0f,2.0f,1.0f,2.0f,3.0f,2.0f,3.0f,2.0f); + break; + case 4: + objgen_spharm_setparamt(TIME_LEN,4.0f,2.0f,2.0f,2.0f,3.0f,2.0f,3.0f,2.0f); + break; + case 5: + objgen_spharm_setparamt(TIME_LEN,2.0f,4.0f,1.0f,2.0f,1.0f,2.0f,1.0f,4.0f); + break; + case 6: + objgen_spharm_setparamt(TIME_LEN,1.0f,6.0f,1.0f,3.0f,1.0f,3.0f,1.0f,6.0f); + break; + case 7: + objgen_spharm_setparamt(TIME_LEN,6.0f,3.0f,6.0f,3.0f,2.0f,3.0f,2.0f,3.0f); + break; + +#define RAND_MULT 30.0f + case 8: { + // random object + static float t1,t2,t3,t4,t5,t6,t7,t8; + t1 = genrand() * 6.0f; t1 = floorf(t1); + t2 = genrand() * 6.0f; if (t2 == 0.0f) t2 += 0.02f; + t3 = genrand() * 6.0f; t3 = floorf(t3); + t4 = genrand() * 6.0f; if (t4 == 0.0f) t4 += 0.02f; + t5 = genrand() * 6.0f; t5 = floorf(t5); + t6 = genrand() * 6.0f; if (t6 == 0.0f) t6 += 0.02f; + t7 = genrand() * 6.0f; t7 = floorf(t7); + t8 = genrand() * 6.0f; if (t8 == 0.0f) t8 += 0.02f; + + objgen_spharm_setparamt(TIME_LEN,t1,t2,t3,t4,t5,t6,t7,t8); + objtype--;// make sure we end up back in same spot + //objtype = 6; // make sure we end up back in same spot + } break; + default: // none found, so move to next one, and trigger re-gen + objtype == 0; + inited = 0; + break; + } + count = 0; + } + + if (odd) { + SparmGenList(vertices2,resx,resy,color); + odd = 0; + } else { + SparmGenList(vertices,resx,resy,color); + odd = 1; + } +} + diff --git a/src/samples/gu/splinesurface/Makefile.sample b/src/samples/gu/splinesurface/Makefile.sample new file mode 100644 index 00000000..06908520 --- /dev/null +++ b/src/samples/gu/splinesurface/Makefile.sample @@ -0,0 +1,17 @@ +TARGET = splinesurface +OBJS = splinesurface.o ../common/callbacks.o ../common/vram.o + +INCDIR = +CFLAGS = -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = +LIBS= -lpspgum -lpspgu -lm + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Spline Surface Sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/gu/splinesurface/splinesurface.c b/src/samples/gu/splinesurface/splinesurface.c new file mode 100644 index 00000000..8de764e2 --- /dev/null +++ b/src/samples/gu/splinesurface/splinesurface.c @@ -0,0 +1,326 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "../common/callbacks.h" +#include "../common/vram.h" + +PSP_MODULE_INFO("Spline Surface Sample", 0, 1, 1); +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER); + +static unsigned int __attribute__((aligned(16))) list[262144]; + +struct Vertex +{ + unsigned int color; + ScePspFVector3 normal; + ScePspFVector3 position; +}; + +#define BUF_WIDTH (512) +#define SCR_WIDTH (480) +#define SCR_HEIGHT (272) + +#define GRID_WIDTH 18 +#define GRID_HEIGHT 18 + +int parametersSH[8] = {0,2,2,2,2,2,2,2}; + +float hue2rgb(float m1, float m2, float h) +{ + h += h < 0.0f ? 1.0f : h > 1.0f ? -1.0f : 0.0f; + + if ((h*6.0f) < 1.0f) + return m1 + (m2-m1) * h * 6.0f; + + if ((h*2.0f) < 1.0f) + return m2; + + if ((h*3.0f) < 2.0f) + return m1 + (m2-m1) * ((2.0f/3.0f)-h) * 6.0f; + + return m1; +} + +unsigned int hsl2rgb(float h, float s, float l) +{ + float m1,m2; + int r,g,b; + + m2 = l < 0.5f ? l * (s+1.0f) : (l+s) - (l*s); + m1 = l*2.0f-m2; + + r = (int)(255.0f * hue2rgb(m1,m2,h+(1.0f/3.0f))); + g = (int)(255.0f * hue2rgb(m1,m2,h)); + b = (int)(255.0f * hue2rgb(m1,m2,h-(1.0f/3.0f))); + + return (0xff << 24) | (b << 16) | (g << 8) | r; +} + +void evalSH(float theta, float phi, const int* m, ScePspFVector3* p) +{ + float r = 0; + + r += powf(sinf(m[0]*phi),(float)m[1]); + r += powf(cosf(m[2]*phi),(float)m[3]); + r += powf(sinf(m[4]*theta),(float)m[5]); + r += powf(cosf(m[6]*theta),(float)m[7]); + + p->x = r * sinf(phi) * cosf(theta); + p->y = r * cosf(phi); + p->z = r * sinf(phi) * sinf(theta); +} + +struct Vertex vertices[GRID_WIDTH * GRID_HEIGHT]; +unsigned short indices[GRID_WIDTH * GRID_HEIGHT * 6]; + +void indicesSH() +{ + unsigned short i,j; + + for (i = 0; i < GRID_WIDTH; ++i) + { + for (j = 0; j < GRID_HEIGHT; ++j) + { + unsigned short* curr = &indices[(j + (i * (GRID_HEIGHT))) * 6]; + unsigned short i1 = (i+1) % GRID_WIDTH; + unsigned short j1 = (j+1) % GRID_HEIGHT; + + *curr++ = j + i * GRID_HEIGHT; + *curr++ = j1 + i * GRID_HEIGHT; + *curr++ = j + i1 * GRID_HEIGHT; + + *curr++ = j1 + i * GRID_HEIGHT; + *curr++ = j1 + i1 * GRID_HEIGHT; + *curr++ = j + i1 * GRID_HEIGHT; + } + } + + sceKernelDcacheWritebackAll(); +} + +void setupSH() +{ + struct Vertex* vtx = vertices; + struct Vertex* currvtx = vtx; + + float du = (GU_PI*2) / GRID_WIDTH; + float dh = 1.0f / GRID_WIDTH; + + unsigned int i,j; + + for (i = 0; i < GRID_WIDTH; ++i) + { + float u = i * du; + + for (j = 0; j < GRID_HEIGHT; ++j) + { + currvtx->color = hsl2rgb(i * dh, 1.0f, 0.5f); + currvtx++; + } + } + +} + +void renderSH(const int* m) +{ + struct Vertex* vtx = vertices; + struct Vertex* currvtx = vtx; + + float du = (GU_PI*2) / (GRID_WIDTH-1); + float dv = GU_PI / (GRID_HEIGHT-1); + + unsigned int i,j; + + // position + + for (i = 0; i < GRID_WIDTH; ++i) + { + float u = fmod(i * du,GU_PI*2); + + for (j = 0; j < GRID_HEIGHT; ++j) + { + float v = (j * dv); + + evalSH(u,v,m,&(currvtx->position)); + currvtx++; + } + } + + // normal + + for (i = 0; i < GRID_WIDTH; ++i) + { + for (j = 0; j < GRID_HEIGHT; ++j) + { + ScePspFVector3 l1,l2; + unsigned short* curr = &indices[(j + (i * (GRID_HEIGHT))) * 6]; + ScePspFVector3* normal = &vtx[curr[0]].normal; + + l1.x = vtx[curr[1]].position.x - vtx[curr[0]].position.x; + l1.y = vtx[curr[1]].position.y - vtx[curr[0]].position.y; + l1.z = vtx[curr[1]].position.z - vtx[curr[0]].position.z; + + l2.x = vtx[curr[2]].position.x - vtx[curr[0]].position.x; + l2.y = vtx[curr[2]].position.y - vtx[curr[0]].position.y; + l2.z = vtx[curr[2]].position.z - vtx[curr[0]].position.z; + + gumCrossProduct(normal,&l1,&l2); + gumNormalize(normal); + } + } + + sceKernelDcacheWritebackAll(); + + sceGumDrawSpline(GU_NORMAL_32BITF|GU_COLOR_8888|GU_VERTEX_32BITF, + GRID_HEIGHT,GRID_WIDTH,3,3,indices,vertices); +} + +struct LightSettings +{ + ScePspFVector3 position; + unsigned int diffuse; + unsigned int specular; +} lsettings[3] = +{ + {{-1,-1,-1}, 0xffffffff, 0xffffffff}, // key + {{1,0,-1}, 0xff202020, 0xff000000}, // fill + {{0,-1,1}, 0xff808080, 0xff000000} // back +}; + +int main(int argc, char* argv[]) +{ + setupCallbacks(); + + // setup GU + + void* fbp0 = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_8888); + void* fbp1 = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_8888); + void* zbp = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_4444); + + sceGuInit(); + + sceGuStart(GU_DIRECT,list); + sceGuDrawBuffer(GU_PSM_8888,fbp0,BUF_WIDTH); + sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,fbp1,BUF_WIDTH); + sceGuDepthBuffer(zbp,BUF_WIDTH); + sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); + sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); + sceGuDepthRange(0xc350,0x2710); + sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + sceGuDepthFunc(GU_GEQUAL); + sceGuEnable(GU_DEPTH_TEST); + sceGuFrontFace(GU_CW); + sceGuShadeModel(GU_SMOOTH); +// sceGuEnable(GU_CULL_FACE); + sceGuEnable(GU_CLIP_PLANES); + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuDisplay(GU_TRUE); + + setupSH(); + indicesSH(); + + // run sample + + int val = 0; + + while(running()) + { + sceGuStart(GU_DIRECT,list); + + // clear screen + + sceGuClearColor(0x000000); + sceGuClearDepth(0); + sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); + + // light settings + + sceGuEnable(GU_LIGHTING); + sceGuEnable(GU_LIGHT0); + sceGuEnable(GU_LIGHT1); + sceGuEnable(GU_LIGHT2); + sceGuLightMode(1); + { + unsigned int i; + + for (i = 0; i < 3; ++i) + { + sceGuLight(i,GU_DIRECTIONAL,GU_DIFFUSE_AND_SPECULAR,&lsettings[i].position); + sceGuLightColor(i,GU_DIFFUSE,lsettings[i].diffuse); + sceGuLightColor(i,GU_SPECULAR,lsettings[i].specular); + sceGuLightAtt(i,0.0f,1.0f,0.0f); + } + sceGuSpecular(12.0f); + sceGuAmbient(0x000000); + } + + // setup matrices + + sceGumMatrixMode(GU_PROJECTION); + sceGumLoadIdentity(); + sceGumPerspective(75.0f,16.0f/9.0f,0.5f,1000.0f); + + sceGumMatrixMode(GU_VIEW); + { + ScePspFVector3 pos = { 0, 0, -5.0f }; + + sceGumLoadIdentity(); + sceGumTranslate(&pos); + } + + sceGumMatrixMode(GU_MODEL); + sceGumLoadIdentity(); + { + ScePspFVector3 rot = { val * 0.79f * (GU_PI/180.0f), val * 0.98f * (GU_PI/180.0f), val * 1.32f * (GU_PI/180.0f) }; + sceGumRotateXYZ(&rot); + } + + // setup texture + + sceGuAmbientColor(0xffffffff); + + // draw + + renderSH(parametersSH); + + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuSwapBuffers(); + + val++; + + if ((val%600) == 0) + { + unsigned int i; + for (i = 0; i < 8; ++i) + parametersSH[i] = (int)((rand() / ((float)RAND_MAX)) * 6.0f); + } + } + + sceGuTerm(); + + sceKernelExitGame(); + return 0; +} diff --git a/src/samples/gu/sprite/Makefile.sample b/src/samples/gu/sprite/Makefile.sample new file mode 100644 index 00000000..e2021f43 --- /dev/null +++ b/src/samples/gu/sprite/Makefile.sample @@ -0,0 +1,20 @@ +TARGET = sprite +OBJS = sprite.o ball.o ../common/callbacks.o ../common/vram.o + +INCDIR = +CFLAGS = -G0 -Wall -O2 +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = +LIBS= -lpspgum -lpspgu -lm + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Sprite Sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak + +ball.o: ball.raw + bin2o -i ball.raw ball.o ball diff --git a/src/samples/gu/sprite/ball.raw b/src/samples/gu/sprite/ball.raw new file mode 100644 index 00000000..0ff2eea6 --- /dev/null +++ b/src/samples/gu/sprite/ball.raw @@ -0,0 +1 @@ +|||||||||||ï½k­J©)¥)¥¡¡)¥J©Î¹||||||||||||||||||||RÊ1ÆÎ¹Œ±k­k­J©)¥¡)¥)¥Œ±ï½Â|||||||||||||||||Âï½Âï½Î¹Î¹Î¹­µŒ±k­)¥)¥J©k­Œ±Î¹||||||||||||||µÖµÖµÖsÎ1Æ1Æ1Æ1Æ1Æ1ÆÂl±J©)¥J©Œ±ÂRʵÖ|||||||||||ÖÚ÷ÞZë{ïãµÖ”Ò”ÒµÖµÖµÖ”ÒsÎ1Æï½Œ±Œ±­µÂsΔÒÖÚ|||||||||ÖÚãœó½÷½÷{ï9çã÷Þ÷Þ÷Þ÷Þ÷ÞÖÚµÖsÎ1Æï½Î¹Î¹1ƔҵÖÖÚ|||||||µÖ÷Þ{ï½÷œó{ï9ç9ç9çããã9ç9çã÷ÞÖÚµÖsÎÂιι1ƔҔҵÖ||||||µÖZëœó{ïZë9ç9ç9ç9ç9ç9ç9ç9ç9ç9çã÷Þ÷Þ÷Þ”ÒÂιι1ÆsÎsÎ|||||RÊ÷ÞZë{ïZë9ç9çZë9ç9ç9çZë9ç9ç9ç9ç9ç9çã9ç÷Þ”ÒÂιιÂ1ÆÂ|||sΔÒãZë9ç9ç9ç9ç9ç9ç9çZë{ïZë9ç9çZëZëZë9ç9çãÖÚsÎÂιιÂ1ÆsÎ||”Ò÷Þ9ç9ç9ç9ç9ç9ç9ç9ç{ï{ï{ïœóœóœóœó{ï{ï{ï9çããÖÚsÎï½Î¹ï½RÊRÊ|ï½sÎã9ç9çZë9ç9çZëZë{ï½÷½÷œó½÷ÞûÞû½÷œó½÷œó{ïZë9çãµÖ1Æï½ï½1ÆÂι­µsÎã9çZë{ïZëZëœó½÷½÷ÞûÞûÞûÞûÿÿÿÿÞû½÷½÷½÷½÷½÷œóZë÷ÞsÎ1ÆÂ1Æï½Œ±Œ±1ƵÖãZëœóœóœóÞûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞûÞû½÷ÞûÿÿÞû{ïã”ÒRÊ1ÆÂιk­çœk­ï½RÊÖÚ9ç{ïœóÞûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞûÞûÿÿÿÿÞûœóãsÎÂι­µJ©çœBˆ¥”çœJ©­µ1ƵÖã{ïÞûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞû{ïã”Òï½k­)¥çœ„Bˆ!„!„Bˆ„¥”¡Œ±1ƵÖ9ç½÷ÞûÞûÿÿÿÿÿÿÿÿÿÿÿÿÞûÞû½÷9çµÖ1ÆŒ±çœ„cŒBˆ!„!„cŒ!„!„BˆBˆBˆ¥”¡k­µÖãZë{ïœó½÷½÷œó{ïZëãµÖÂk­¡¥”BˆBˆBˆ!„!„cŒÆ˜„cŒ¥”„BˆBˆBˆ„çœk­ï½RʔҵÖ÷Þ÷ÞµÖ”ÒRÊï½k­çœ„BˆBˆBˆ„¥”cŒ„Ƙ¡çœÆ˜çœÆ˜„BˆBˆ„„„Ƙ¡)¥J©k­k­J©)¥¡Æ˜„„„BˆBˆ„Æ˜çœÆ˜çœ¡­µJ©)¥¡¡çœ¥”„¥”„BˆBˆcŒBˆcŒ„„cŒBˆcŒBˆBˆ„¥”„¥”眡¡)¥J©­µ|ï½k­)¥J©J©¡çœçœ„cŒ„„Bˆ„ƘƘ„Bˆ„„cŒ„çœçœ¡J©J©)¥k­ï½||Âk­J©J©J©J©)¥¡Æ˜¥”ƘƘ¥”Ƙ¡¡Æ˜¥”ƘƘ¥”Ƙ¡)¥J©J©J©J©k­Â|||­µŒ±k­J©k­k­)¥)¥¡¡¡¡¡¡¡¡¡¡¡¡)¥)¥k­k­J©k­Œ±­µ|||||ÂιŒ±Œ±Œ±k­k­J©J©J©J©J©)¥)¥J©J©J©J©J©k­k­Œ±Œ±Œ±Î¹Â||||||”ÒÂï½Î¹Î¹­µŒ±Œ±Œ±Œ±Œ±Œ±Œ±Œ±Œ±Œ±Œ±Œ±Œ±Œ±­µÎ¹Î¹ï½”Ò|||||||”Ò1Æ1ÆÂï½Î¹Î¹ï½ï½ï½ï½ÂÂï½ï½ï½ï½Î¹Î¹ï½Â1Æ1Æ”Ò|||||||||”ÒRÊRÊRÊRÊRÊRÊRÊRÊsÎsÎsÎsÎRÊRÊRÊRÊRÊRÊRÊRÊ”Ò|||||||||||”ÒRÊRʔҵֵÖÖÚÖÚÖÚÖÚÖÚÖÚÖÚÖÚµÖµÖ”ÒRÊRÊ”Ò||||||||||||||ÂRʵÖ÷Þ9çZë{ï{ï{ï{ïZë9ç÷ÞµÖRÊÂ|||||||||||||||||RÊ”ÒÖÚã{ïœó½÷½÷œó{ïãÖÚ”ÒRÊ||||||||||||||||||||”Ò÷ÞZëœóœóœóœóZë÷Þ”Ò||||||||||| \ No newline at end of file diff --git a/src/samples/gu/sprite/sprite.c b/src/samples/gu/sprite/sprite.c new file mode 100644 index 00000000..665e0a2e --- /dev/null +++ b/src/samples/gu/sprite/sprite.c @@ -0,0 +1,241 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "../common/callbacks.h" +#include "../common/vram.h" + +PSP_MODULE_INFO("Sprite Sample", 0, 1, 1); +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER); + +static unsigned int __attribute__((aligned(16))) list[262144]; +extern unsigned char ball_start[]; + +struct InputVertex +{ + float x,y,z; +}; + +struct Vertex +{ + float u, v; + unsigned int color; + float x,y,z; +}; + +void create_torus_billboards(struct Vertex* vertices, float* world); + +#define BUF_WIDTH (512) +#define SCR_WIDTH (480) +#define SCR_HEIGHT (272) + +#define NUM_SLICES 128 +#define NUM_ROWS 128 +#define RING_SIZE 2.0f +#define RING_RADIUS 1.0f +#define SPRITE_SIZE 0.025f + +unsigned int colors[8] = +{ + 0xffff0000, + 0xffff00ff, + 0xff0000ff, + 0xff00ffff, + 0xff00ff00, + 0xffffff00, + 0xffffffff, + 0xff101010 +}; + +struct InputVertex torus_vertices[NUM_SLICES * NUM_ROWS]; + +int main(int argc, char* argv[]) +{ + unsigned int i,j; + + setupCallbacks(); + + // initialize torus + + for (i = 0; i < NUM_SLICES; ++i) + { + for (j = 0; j < NUM_ROWS; ++j) + { + float s = i + 0.5f, t = j; + float x,y,z; + + x = (RING_SIZE + RING_RADIUS * cosf(s * ((GU_PI*2)/NUM_SLICES))) * cosf(t * ((GU_PI*2)/NUM_ROWS)); + y = (RING_SIZE + RING_RADIUS * cosf(s * ((GU_PI*2)/NUM_SLICES))) * sinf(t * ((GU_PI*2)/NUM_ROWS)); + z = RING_RADIUS * sinf(s * ((GU_PI*2)/NUM_SLICES)); + + torus_vertices[j + i * NUM_ROWS].x = x; + torus_vertices[j + i * NUM_ROWS].y = y; + torus_vertices[j + i * NUM_ROWS].z = z; + } + } + + // setup GU + + sceGuInit(); + + void* fbp0 = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_8888); + void* fbp1 = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_8888); + void* zbp = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_4444); + + sceGuStart(GU_DIRECT,list); + sceGuDrawBuffer(GU_PSM_8888,fbp0,BUF_WIDTH); + sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,fbp1,BUF_WIDTH); + sceGuDepthBuffer(zbp,BUF_WIDTH); + sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); + sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); + sceGuDepthRange(0xc350,0x2710); + sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + sceGuAlphaFunc(GU_GREATER,0,0xff); + sceGuEnable(GU_ALPHA_TEST); + sceGuDepthFunc(GU_GEQUAL); + sceGuEnable(GU_DEPTH_TEST); + sceGuFrontFace(GU_CW); + sceGuShadeModel(GU_SMOOTH); + sceGuEnable(GU_CULL_FACE); + sceGuEnable(GU_TEXTURE_2D); + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuDisplay(GU_TRUE); + + // run sample + + ScePspFMatrix4 world; + + float val = 0; + + while(running()) + { + struct Vertex* vertices; + + sceGuStart(GU_DIRECT,list); + + // clear screen + + sceGuClearColor(0xff554433); + sceGuClearDepth(0); + sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); + + // setup texture + + sceGuTexMode(GU_PSM_5551,0,0,0); + sceGuTexImage(0,32,32,32,ball_start); // width, height, buffer width, tbp + sceGuTexFunc(GU_TFX_MODULATE,GU_TCC_RGBA); // NOTE: this enables reads of the alpha-component from the texture, otherwise blend/test won't work + sceGuTexFilter(GU_NEAREST,GU_NEAREST); + sceGuTexWrap(GU_CLAMP,GU_CLAMP); + sceGuTexScale(1,1); + sceGuTexOffset(0,0); + sceGuAmbientColor(0xffffffff); + + // setup transforms + + sceGumMatrixMode(GU_PROJECTION); + sceGumLoadIdentity(); + sceGumPerspective(75.0f,16.0f/9.0f,0.5f,1000.0f); + + sceGumMatrixMode(GU_VIEW); + { + ScePspFVector3 pos = {0.0f,0.0f,-3.5f}; + + sceGumLoadIdentity(); + sceGumTranslate(&pos); + } + + sceGumMatrixMode(GU_MODEL); + { + ScePspFVector3 rot = {val * 0.3f * (GU_PI/180.0f), val * 0.7f * (GU_PI/180.0f), val * 1.3f * (GU_PI/180.0f)}; + + sceGumLoadIdentity(); + sceGumRotateXYZ(&rot); + } + sceGumStoreMatrix(&world); + + // render torus + + vertices = sceGuGetMemory(NUM_SLICES * NUM_ROWS * 2 * sizeof(struct Vertex)); + create_torus_billboards(vertices,(float*)&world); + + sceGumDrawArray(GU_SPRITES,GU_TEXTURE_32BITF|GU_COLOR_8888|GU_VERTEX_32BITF|GU_TRANSFORM_3D,NUM_SLICES*NUM_ROWS*2,0,vertices); + + // wait for next frame + + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuSwapBuffers(); + + val += 0.6f; + } + + sceGuTerm(); + + sceKernelExitGame(); + return 0; +} + +/* this function generates the billboards rendered by sceGuDrawArray() */ +void create_torus_billboards(struct Vertex* vertices, float* world) +{ + unsigned int i,j; + float sx, sy, sz; + + // calculate billboard world offsets + + sx = SPRITE_SIZE * world[(0 << 2)+0] + SPRITE_SIZE * world[(0 << 2)+1]; + sy = SPRITE_SIZE * world[(1 << 2)+0] + SPRITE_SIZE * world[(1 << 2)+1]; + sz = SPRITE_SIZE * world[(2 << 2)+0] + SPRITE_SIZE * world[(2 << 2)+1]; + + for (i = 0; i < NUM_SLICES; ++i) + { + struct Vertex* row = &vertices[i * NUM_ROWS * 2]; + struct InputVertex* inrow = &torus_vertices[i * NUM_ROWS]; + + for (j = 0; j < NUM_ROWS; ++j) + { + struct Vertex* curr = &row[j << 1]; + struct InputVertex* incurr = &inrow[j]; + float x, y, z; + + x = incurr->x; + y = incurr->y; + z = incurr->z; + + curr[0].u = 0; + curr[0].v = 0; + curr[0].color = colors[(i+j)&7]; + curr[0].x = x - sx; + curr[0].y = y - sy; + curr[0].z = z - sz; + + curr[1].u = 1; + curr[1].v = 1; + curr[1].color = colors[(i+j)&7]; + curr[1].x = x + sx; + curr[1].y = y + sy; + curr[1].z = z + sz; + } + } +} diff --git a/src/samples/gu/text/Makefile.sample b/src/samples/gu/text/Makefile.sample new file mode 100644 index 00000000..be7c4555 --- /dev/null +++ b/src/samples/gu/text/Makefile.sample @@ -0,0 +1,20 @@ +TARGET = gufont +OBJS = font.c main.o + +INCDIR = +CFLAGS = -G0 -Wall -O2 +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = +LIBS= -lpspgum -lpspgu -lm + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = GUFont Sample by McZonk + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak + +font.c : font.raw + bin2c font.raw font.c font diff --git a/src/samples/gu/text/font.raw b/src/samples/gu/text/font.raw new file mode 100644 index 0000000000000000000000000000000000000000..c24d4fed26d4999b5cff00fe7cca6ac6d0192a97 GIT binary patch literal 131072 zcmeI5J&!F(Qil1^8hjam0j#qYXdJ{300$6a3|#mPxa;7JW_(;+D3c$sI6D$P-U7m1 z)e{zs#KG5VLI|NH1a96h&OFZn(gu=v0iKEFA7#?AHhoQ$-dYBTrObN}9Q z$Qga)`IrCmq2s%w|J&&QGkR_@@A+PJz2^f?xY6+W=x_P?HRPRYG5$H9&jM<|^Y_J= ze>wWS-~aM|Hn_ht`u9iwuhD-rdTg;?^NL&qwDyLOuQ6=-(YZ#{A`2pXt#DKJg6)T%V5)HyY4_CbUJ&+Wect zhR-2ijE<&zfBxrZmT!&D=WX==<>!Z*Av;X|`i29!A z|Lr`>p8fl)N1y*^|NeBI|F?4%AF&tD{`;#(pMUm@X8@lA_*sCTr=IEer;n()k)l)W z5nA6nr|0Lhu_NCZo$r+RUin9(#}@MtuXpBKKH!2AZZv#0I^XG`En?Q@>i=TcemVNR zzyDj)G_URN+t{X4ZRT}9uV?b(`T2b82;a#++uyIM|BIo0p8wm|$C;Ws!i=pt)sFnm z`_Hlex7??B{-1BpPaXaNx@Fx=Uo)Sx24)S+8kjXOYhc#Etbthrvj%1jJYx;~;`rI< z7e;4{y&6lzL|SFf`|8?M$he^$AwA^aQ;gMk98Ff#~MG^DmA!=ujt>3 z{~rf`1%H))3*X5fwz-kNihlNQ4SzL$@Q>U-Vyf_O?SHlYw(y<(TdV&Lerx}#@sCuk zwrc&Xg2%-Q9-FOJ(Z7eU@WZjyD)_7Xd-zKHuc^Pnzo);FzdijG{yqFX_^-zQmhrqB zjy^-YrvA$Qza~GvUpszsyw&c(|LpnO)BouDy}Ext3H86Xf0g`Qeg0qNf6Mqv{p{th zg5Qh3a{l)CEBpWK&(GJ?e|7(^;w$^NS3g(r75!K1?=|(`BmTFnzY_o6`Kj#xUi_8k z*B-v2|26Sf$?;aZ$LGI2{%6SF)%t&Q{CoV| zyYl_-Rs22nAB}6jf2{ug6OC*5>hE9o@Rj)Y^jGlMto{D<>hE94$rb)i{;%p^+rNA2 z-{P-6f7jx_n!j7%uk8OV{{EuE&-0BlM8}?-J3o5%c^{k@=63HNjS&lf7auWTjp2yb z`w=5IqxX+SG3qd$Bb@ie=h6E|W5&5Y!g*hN^}F`|(Wt%nZv5Ii;*a?eulMB_=ji>T zG2+EC9^t$nF~-o90nR?(BUiuokN&{&oeST8#p`oE^YN2Z183i#;Nsai<0oR` zyqf<{h6dYjjY$=UEzb;oU&PqKMh?HTMSHy7nV*R}`#TItL^4^{nOmeFn0pY3nPK@=j{{so_Fx&Eduuvxc`fpz zflduAqu+zySl}XVTBrWRUmfKq{(Hua?oSB%V~g*RZXU2_@49Cg9C3q#pZKdez|MxB z#l^>Y)z6jviyE%*o%I7Q?i(pEkCnKhfJx%w#hkokU#`@m;>^Y6Gy6@<;cCS3UZxJh+@0~YwM{YE9by)ucdb)l+ z$J7yf(%BC+`~911<9qE9KI`br`89vkZa4R@9b47E&+W6%z$(v{oqKK#Y}v)@?%Sg@ zM=j4hCy$=nEA`8BC_amxDJPs^>S!6glLO)f!`VOc?05?~B3?dw5ku#>{Z_Ph_UkQZ zev2BO_1xYvm(&q?==ucr>@|2c_HM4GeZRhD&SuVL4a^#tH85*n*1)WRSp%~MW)0l7 z2K*V$@l1Zt{tPYW*`LA0`!^h2?c%#Q?2Xy+tS|A59Ub!J@rsWQ7TYV_U9Q)*HTH}TiwZtsnHyJUgcJQV&hJ@2=ymV#SLcd;3?3evc-EEtWvp6^?Pvt=nT3=6KU0G-clh939&vLYz3|Z({qGntujC)R z4f~jnss?m`LpQC;9plUR%HD~$=HX@T^~y+$%jjU~>?LvVPVB@Fmpbs#(Lt=l59Un$ z#680Y-NwC294$iC&? z-2?r(7t8S3jl(*u)}Ea3*w{<(wyuUVICI!NJ5fJ6>1rnz746vg{w4S9o2{BhxzF;; z$Fl?xTF}%N;-D$-NuXm)60nNR(0s$jF;ypF!N=3vlHJCnZ;$PabnbA)RZ{c6IN=LfC(`vZNj7x?McuXwQ?-D0nt zJ@|4z``Mp;WDnHU8Nm@p2ZJrzsaG0%NDa|EQ&oTXu`#dUu(NjIW^M1{iQV&u_G%r; zhrReQE$@SPu;h_=m{;|id-5)S_4xq@x@~Bw@M?p-{BX-p3>{zK^g|r_ua0n82VHJB z;?H57y^s3PO$?p=i}LQq{MalX?bYAS8+E64^WV{r265f@4mr*F!&m1FQ*X=YG_aMt<-G($ z4rph5n1c@<&S@|g)Z;SxnRArmI$EO}u5Qk=U;OagJNxXzA3kEw9F?{Bimf(a{MlDL zqxUPLIQFcI&Hll6_Fits?60yG>sY}=o3l85hCJ z&Kj6CFl%7ez^s8;1G5HZ4a^#Ny&CZ6raX3Ye)fAzdHw#l^WD1|_2KCC%BXI~3MSgf zna60eH_tfNdzgGrj5*Br_trUXeeGfLJ$;boZa{O8I>Wzw>0I^SemK&iAPCcgUUJ9TPizGddCzXPpmhaWzgu~)I| zcf`YQ49l43nuzt`JjWmL?4@>lqw%YsvHCX%aF8>2(V`xFRP>_@%rd%d856GUY2LaA z4sLqI2l}y%`dwG@2ZuSY@MYcP$eJ@>9iL!wyx{Y-%p2F77440sQp50|orXPHxW=5u zJ=T$HZEpR6p@FOL;|u>bFw`y0{aoXV*T7>-15c-s5BDS5=XvDk_s8b(jDGe3fA-9^ zwvPPb-G?>%e9ih9wEr)Dd}sT-j{NGz7p;;%{h4=g)!d1VW7JdO&-Us#v;X*tS}OC% zZ`|yo?a1dEK3=Qf*XqA=cGq}#W_kvR;VeJ-Kf;n<_SlB~nx?&d$oBXnc5+gA{%3yc zr;q+>3bTXZ2)1N4#72yZn)ty<^{Kp2aO5uSYy{ zuUE&2Uk09c2>sXMgk`{V{L{3nAK4V^O(@#yvpj_FG~(iHK`b3N?kA!5<&XQ#8zAGAmP zN7~VrHJCg6bf5pkuFnd$wgdLkz(+k5AJHD|tSdP8Wesl}+U$)PzYKmF`K#!Nc51xH?ue*Mty>-hwq^dpQs~BTujCgXljNZv%#4`u$IULg;=OuE+dB&4_ z8~37Zo@XrF)Q!(k#*Pp0o!HTnHRN^HoY&c&HM%R>@s;zXe)3SMX_?nQp}$7@GE*Z4bo zn7Q(LO|#eFHeWpZ!TJtBLnViqFR$g=8lydY@YB%6y)B&Av7vrwYG&TSV^8D#0ghgY z9SvDOYr7iv#)xOWXS;R}40>rXe%2L#nLn@BIM=ShZL8)EKk&JKeDACuuKAf@jn8XQ zFZC>*cPRI?+ZrPtENlA~CSH$t__?=srXwcKBc3_;)~-cNoMXGT|6J2ww9j*5#+L4L zn344|`jHRri(}57#dYS(Yw-j2g7ar!bY3%bJ-O&SP8Qr#w3D+{$)|zL&8q7s?58&bRzIs{f zqoN`2pL@6rKNUPSaLZ4OT+`2y4{g!xeyIr`M|k+imHBh5=1;wF!j=2hp2h28yq4Eq z-x{@NRL7R>)^%}?TXt*LGyj^+-ZeR+ALe_Qcu#!1)}70(uMWRhIpfdcUOO7~;do@9 z?~8NH_xIKrlh=D#?!}ymWjw-ppL}I|{b;i{!cUJj;PbV3KhNcJ%=hQ|>-nAenE9AB zFl%7ez^s8;1G5HZ4a^#tH85*n*1)WRN7cam*?rdDqiXNjc|ALfo$t+V6?f!k-u3Hu z_Fr2*n$(wSjA_4G@RiV2bNl>^1FB7Z1`G6uhfwGiJ3Va zU-;U}|Il$KZkpr>ud2)o8A1r*fBX0eI zGj{6_A051$_|k7>#6HGf!ED*!%hu6>ZM0`zjeSc?^?KYdb#!6?W5ZWmGe6Q1?ZIa~ z6+F)h8nuHxJ}cbOchu3rX589&j68Xs@p+x?^E%s~*#q*%86c1RyUS&Co}-y-ZJqh^ zdJVI8&F66S`H!#2N&I{M*X~8mGkASQ9X^Y__g2TKnL6aUv$o-*N?`SgG$Y2e>sMHzq*b(y0KR|ZfzGedxqG%Y7Im@^SnON z8|~q@Rr&SL`%3*?EIy(R=K4JvMvfJz!0*azwn?0e@)~KM~JoPrpm3 ze*TO)V-0odFY2i1mN(<#x>85co;es>6>rWy9l&LDMjFooe5!S8Bv;Gm<{w-)|M;+V zbB{gej^4!*Q_kU5oO{>tLEN-%?D~y5DtjmHkz>@%ysIVS^ZLkNw&&STtJW_5@j+*9 z9a2kPJJO(!0eNYiz03OZ`iL8Qw9?S7{!aX2@Wa{ndBF7wzjaUC`s(oK{B`p#e?{+F zJl&kH`QTcN{mjqr@w=Z+4z~2%$WPVMvDmcM)czez1g^zfxJ#x^gVX!e@d0o*ZhFGd~ll|%=U$3mq;T0dZ!m6dB z8=K6V*Hu4VUj51^p3h=j^ZwBY&PLsJu-P|Q&VKj&quFQ2m|oJ5HSMj@Yu=dWzK4B{ zdp-k}JLcdu;+Q_`=kL+EqUQO$LStM;=h|6ao}nrpdpOn5eRfoNvYotq?xOqI2_3h{ zL*}clyZNj7op$GI`n~7QnsdB&yz)BUi+}IkkCuDsm^?Grvj(2G27GSKXU6mH;XHqH z@6OZ!XWswMGJbZc{NC*h&&0g%`t%)gWuNiEXWA=1CbpkHzqcEyZ+&-vi(KELZf>DN zAO1|``d*`XxHrGNSK`D6-#PLAID3Ba0iN%&m{;{&)i2($%KP5zcm|OBW%RRq*v$z! zw{Dns@wc`|139?Ycev{J`Frp0Zi$yzuf|KgsQqm1n0x$GYvHPX@XP4LPrI52_w!jt z_O6=y7$X>aXaB+2;@^Ko-<3Ij)Xuzui8g9SgRSF7JY)CgC+vCV(0C5$E9yI%gCTx% zP}Km=b~gXU44!_Zb?v?}6F+^;X6;(k&m0@ZP7PuUr>%pPk9@=HsFpR&`5LylXPcw- zRs50vz58%4qx&9btnMMXw)y_x8C=Dq3tO<9A$o^jJe>A1eQCtC7q|D|7t7e?hsRds zlw1Agj*-S#spH6P3?2R8m(jt}z;_6oQ7Ta3g(_x(v6m3I&r8=C1f@Z3An#=e<9@vN88D|l?+qM==W z)?K{(V9`*)6CeL>!G;fTm9qf_xv{Z!(>*2X;U2kRpr5g-5k5kA$k=L5XIdjZ3~(X0Rcx5&>tulKmQm+kZV z2=D!~IPq&*;=QeTNVme=fuuvtMF(2aozp=P~polMLzIx%{<%Zb+q^F5aX~U_Gg}d<~RHC zdS^W2BVzpg&1Zl1;w(2ltJt`AaCXl>XWVus|1o~%QBURhQH^uU4o-enp%FjbR>@=3 zAMw@qCoz(98hCyV1zY|6Oun}Cb8jnducJTmyNBMdj4=n5oJF75Z#{pj`iF~`hOell zf=3IOxbMul7IjwU@hnvFQE$}2o^*UrH#X)StT^KS>(OH_j{I=nM!xB`Bdob!+yCnM zsqD*<4e^q1&XH%Kntx(cKX^K8d>-+7Uw&|OxX<9hMJ?6(mtXuc{8X{TU=HA}?749} z!f)<*_t`4Guu(U2*Z8Z%fXy;GK5WdF(JTDMz=$tf6{}u2!PBjQiVtj-(a-9a-@Ri^ zw~m>|81r1b`d#ZU+pn#8UV*oR?bQF8&+avJ$Id=feMFq|Dposiyg%$-ua5HShp~#q zF5Yb+Gz0?_KTU=lJ#gd!~F?FN~i5&imuhv8w+WwLdy{lmB_o?Jf3>v$KruXFo?i z6W+rAYy04Rg?^q_boAf*v+HZeIQ>6IEk5f$@eJ^DpYvym#rMDCGije%=h>b$Fl%7e zz^s8;1G5HZ4LoNJ%+H?Bxo`QrUD?M+VdKwkF&^~9_0}9ae+OXz`{ulb-%mB-oF(9@BjB0*O$?c>XA5!IX8SAVa*SA z@fp<39e(g(*O&f}M)|d4&GXE4Wz>fn7%Mnz$hD2RzN&aRwa;s>Z;hF+i}%?d{dat1 z+cW!z5Ba-z?8V?`EgpSujo_$x8hf~9w{;!7Eyl8CpRfD(gPn6n%%1&E#~ds@&X2T2 z-2?iyc7!DcY|I;4{QXfUhuDhqS%fd*%X!Lc_~m7eFY{2*k3aeGLkGW%UcqC7tqm+b zmeDKtxQEs)e}hLJDtIt(VvjF+Cw@4@GY8KYbDDD=*Vw|159S>#ey|4%AKb*l+;!wy zn`6Ixv{%Pi{#ef%X6+g}Y|Phe_O9I$PagKTya(qpdVJ@T1M^ThgHiW@eyvsV5b^NQ zX=td#fep5_h-cm9=ef549L;((S6d?-k)O4F3zM(=?1q;ZI(Xu@fy?X6mDgZw^2T+x z&+CXsJOA#%J;V?9GbXOL_OFwFcxY$zqeUDeH9)KK8;dbl>sFj2+&1Q3ua02QOhZct z7j5ywo>Vnpx7F|yeXq?Uo_SucVdAxHpV!fLZ658dU9QpB?DIA3V%|Hs(^u3`?tIpNY$zRp?mR;06WPhzy@*nZc^LmTd>)AfngLYeE#8+!B`{MHx zIj4sG?A@uKsDXL*zqiiVxUSSuv}c~zd)(ZM_SPSxjr&JFxbJ%x9PdxO@|opr@LR&$npur`m&m|yX;=6mg0)IBJ_)++oF&pfZ!IODZ^-n;m& zedLaFwOjkt64#>5*8GZwh$RgQS3#Z!CB=+`G5;e4Uu)gZpRxX`wX;>f2&vR> zetyK*s&nFmi|+ZU>W3r8;5n}FXRQ3gZ7F^@z{K;{tsl-0jhH$6`l_5I^n;_J0}QR2 zzl=Bjv(GR5*(>?iMqXkE@Ac{k##Vi9Mc?4fJ6hts*PO@mqkhLq9%9_+XWtn+F<=XZ zJvRqqTG|KmR;`zuOYqC+@cP*wUmgAU#9saQT1Kzr4=iT}3>_ad=2g7>V90-0d(5G6 zRL?KZPPOBQ4wg8o=fI!8@MEjSARjn*I z?b>(o;K0QH?yXw%xi`w^nDy*oy$9B3Z}r(DmNEX^g0Fb5GKZ5^J$DtKRhyhQ*A+ar zwli^Oj_9vb1KH19_iOMGIkVQNf8XC{&fhJx!^` +#include +#include +#include + +#include +#include + +#include "font.c" + +PSP_MODULE_INFO("GuText Sample", 0, 1, 1); +PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER); + +static unsigned int __attribute__((aligned(16))) list[262144]; + +static int fontwidthtab[128] = { + 10, 10, 10, 10, + 10, 10, 10, 10, + 10, 10, 10, 10, + 10, 10, 10, 10, + + 10, 10, 10, 10, + 10, 10, 10, 10, + 10, 10, 10, 10, + 10, 10, 10, 10, + + 10, 6, 8, 10, // ! " # + 10, 10, 10, 6, // $ % & ' + 10, 10, 10, 10, // ( ) * + + 6, 10, 6, 10, // , - . / + + 10, 10, 10, 10, // 0 1 2 3 + 10, 10, 10, 10, // 6 5 8 7 + 10, 10, 6, 6, // 10 9 : ; + 10, 10, 10, 10, // < = > ? + + 16, 10, 10, 10, // @ A B C + 10, 10, 10, 10, // D E F G + 10, 6, 8, 10, // H I J K + 8, 10, 10, 10, // L M N O + + 10, 10, 10, 10, // P Q R S + 10, 10, 10, 12, // T U V W + 10, 10, 10, 10, // X Y Z [ + 10, 10, 8, 10, // \ ] ^ _ + + 6, 8, 8, 8, // ` a b c + 8, 8, 6, 8, // d e f g + 8, 6, 6, 8, // h i j k + 6, 10, 8, 8, // l m n o + + 8, 8, 8, 8, // p q r s + 8, 8, 8, 12, // t u v w + 8, 8, 8, 10, // x y z { + 8, 10, 8, 12 // | } ~ +}; + +#define BUF_WIDTH (512) +#define SCR_WIDTH (480) +#define SCR_HEIGHT (272) +#define PIXEL_SIZE (4) +#define FRAME_SIZE (BUF_WIDTH * SCR_HEIGHT * PIXEL_SIZE) +#define ZBUF_SIZE (BUF_WIDTH SCR_HEIGHT * 2) + +int exit_callback(int arg1, int arg2, void *common) { + sceKernelExitGame(); + return 0; +} + +int CallbackThread(SceSize args, void *argp) { + int cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + sceKernelSleepThreadCB(); + return 0; +} + +/* + This function draws a string on the screen + The chars are handled as sprites. + It supportes colors and blending. + The fontwidth can be selected with the parameter fw, if it is 0 the best width for each char is selected. +*/ +void drawString(const char* text, int x, int y, unsigned int color, int fw) { + int len = (int)strlen(text); + if(!len) { + return; + } + + typedef struct { + float s, t; + unsigned int c; + float x, y, z; + } VERT; + + VERT* v = sceGuGetMemory(sizeof(VERT) * 2 * len); + + int i; + for(i = 0; i < len; i++) { + unsigned char c = (unsigned char)text[i]; + if(c < 32) { + c = 0; + } else if(c >= 128) { + c = 0; + } + + int tx = (c & 0x0F) << 4; + int ty = (c & 0xF0); + + VERT* v0 = &v[i*2+0]; + VERT* v1 = &v[i*2+1]; + + v0->s = (float)(tx + (fw ? ((16 - fw) >> 1) : ((16 - fontwidthtab[c]) >> 1))); + v0->t = (float)(ty); + v0->c = color; + v0->x = (float)(x); + v0->y = (float)(y); + v0->z = 0.0f; + + v1->s = (float)(tx + 16 - (fw ? ((16 - fw) >> 1) : ((16 - fontwidthtab[c]) >> 1))); + v1->t = (float)(ty + 16); + v1->c = color; + v1->x = (float)(x + (fw ? fw : fontwidthtab[c])); + v1->y = (float)(y + 16); + v1->z = 0.0f; + + x += (fw ? fw : fontwidthtab[c]); + } + + sceGumDrawArray(GU_SPRITES, + GU_TEXTURE_32BITF | GU_COLOR_8888 | GU_VERTEX_32BITF | GU_TRANSFORM_2D, + len * 2, 0, v + ); +} + +int main(int argc, char** argv) { + int thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0); + if(thid >= 0) { + sceKernelStartThread(thid, 0, 0); + } + + sceGuInit(); + sceGuStart(GU_DIRECT, list); + sceGuDrawBuffer(GU_PSM_8888,(void*)0,BUF_WIDTH); + sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,(void*)0x88000,BUF_WIDTH); + sceGuDepthBuffer((void*)0x110000,BUF_WIDTH); + sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); + sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); + sceGuDepthRange(0xc350,0x2710); + sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + sceGuDisable(GU_DEPTH_TEST); + sceGuShadeModel(GU_SMOOTH); + sceGuEnable(GU_BLEND); + sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0); + sceGuEnable(GU_TEXTURE_2D); + sceGuTexMode(GU_PSM_8888, 0, 0, 0); + sceGuTexImage(0, 256, 128, 256, font); + sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA); + sceGuTexEnvColor(0x0); + sceGuTexOffset(0.0f, 0.0f); + sceGuTexScale(1.0f / 256.0f, 1.0f / 128.0f); + sceGuTexWrap(GU_REPEAT, GU_REPEAT); + sceGuTexFilter(GU_NEAREST, GU_NEAREST); + sceGuFinish(); + sceGuSync(0,0); + sceGuDisplay(GU_TRUE); + + while(1) { + sceGuStart(GU_DIRECT, list); + sceGuClear(GU_COLOR_BUFFER_BIT); + + /* + No matrixes are needed because the font is drawn with GU_TRANSFORM_2D + */ + + drawString("Hello World in red", 0, 0, 0xFF0000FF, 0); + drawString("Hello World in green", 0, 16, 0xFF00FF00, 0); + drawString("Hello World in blue", 0, 32, 0xFFFF0000, 0); + + drawString("Hello World with free char width", 0, 64, 0xFFFFFFFF, 0); + drawString("Hello World with block char width 10", 0, 80, 0xFFFFFFFF, 10); + drawString("Hello World with block char width 12", 0, 96, 0xFFFFFFFF, 12); + + drawString("Hello World with opacity 100%", 0, 128, 0xFFFFFFFF, 0); + drawString("Hello World with opacity 50%", 0, 144, 0x7FFFFFFF, 0); + drawString("Hello World with opacity 10%", 0, 160, 0x18FFFFFF, 0); + + drawString("Hello World with shadow", 2, 194, 0x40FFFFFF, 0); + drawString("Hello World with shadow", 0, 192, 0xFFFFFFFF, 0); + + static float t = 0.0f; + t += 0.1f; + + unsigned int c = 0xFF000000 | + (unsigned int)((sinf(t * 0.393f + 0.086f) / 2.0f + 0.5f) * 255.0f) << 16 | + (unsigned int)((sinf(t * 0.444f + 0.854f) / 2.0f + 0.5f) * 255.0f) << 8 | + (unsigned int)((sinf(t * 0.117f + 1.337f) / 2.0f + 0.5f) * 255.0f) << 0; + + drawString("Hello World from pspdev", 0, 224, c, 0); + + sceGuFinish(); + sceGuSync(0, 0); + + sceDisplayWaitVblankStart(); + sceGuSwapBuffers(); + } + + sceGuDisplay(GU_FALSE); + sceGuTerm(); + + return 0; +} diff --git a/src/samples/gu/timing/Makefile.sample b/src/samples/gu/timing/Makefile.sample new file mode 100644 index 00000000..1414f729 --- /dev/null +++ b/src/samples/gu/timing/Makefile.sample @@ -0,0 +1,18 @@ +TARGET = timing +OBJS = timing.o + +INCDIR = +CFLAGS = -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = +LIBS = -lpspgum -lpspgu -lm + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Timing Sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak + diff --git a/src/samples/gu/timing/timing.c b/src/samples/gu/timing/timing.c new file mode 100644 index 00000000..2fbe0117 --- /dev/null +++ b/src/samples/gu/timing/timing.c @@ -0,0 +1,338 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * timing.c - Shows gu time messuaring + * + * Copyright (c) 2007 McZonk + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +PSP_MODULE_INFO("Timing Sample", 0, 1, 1); +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER); + +static unsigned int __attribute__((aligned(16))) list[262144]; + +typedef struct { + float x, y, z; +} VERT3D; + +#define TORUS_SEGMENTS 8 +#define TORUS_SLICES 8 +#define TORUS_IRADIUS 0.5f +#define TORUS_ORADIUS 1.0f + +#define BLUR_RADIUS 4 + +static VERT3D __attribute__((aligned(16))) indexedTorus[TORUS_SEGMENTS][TORUS_SLICES]; + +static VERT3D __attribute__((aligned(16))) triangleTorus[TORUS_SEGMENTS][TORUS_SLICES*6]; + +static VERT3D __attribute__((aligned(16))) tristripTorus[TORUS_SEGMENTS][TORUS_SLICES*2+2]; + +static VERT3D __attribute__((aligned(16))) splineTorus[TORUS_SEGMENTS+3][TORUS_SLICES+3]; + + +int SetupCallbacks(); + +#define BUF_WIDTH (512) +#define SCR_WIDTH (480) +#define SCR_HEIGHT (272) +#define PIXEL_SIZE (4) /* change this if you change to another screenmode */ +#define FRAME_SIZE (BUF_WIDTH * SCR_HEIGHT * PIXEL_SIZE) +#define ZBUF_SIZE (BUF_WIDTH SCR_HEIGHT * 2) /* zbuffer seems to be 16-bit? */ + +void buildIndexedTorus() { + const float thickness = TORUS_ORADIUS - TORUS_IRADIUS; + + unsigned int i, j; + for(i = 0; i < TORUS_SEGMENTS; i++) { + float x = cosf((float)i / (float)TORUS_SEGMENTS * (2.0f*GU_PI)); + float z = sinf((float)i / (float)TORUS_SEGMENTS * (2.0f*GU_PI)); + + for(j = 0; j < TORUS_SLICES; j++) { + float t = cosf((float)j / (float)TORUS_SLICES * (2.0f*GU_PI)) * (thickness / 2.0f) + TORUS_IRADIUS; + float y = sinf((float)j / (float)TORUS_SLICES * (2.0f*GU_PI)) * (thickness / 2.0f); + + indexedTorus[i][j].x = x * t; + indexedTorus[i][j].y = y; + indexedTorus[i][j].z = z * t; + } + } +} + +void buildTriangleTorus() { + unsigned int i, j; + for(i = 0; i < TORUS_SEGMENTS; i++) { + unsigned int x0 = i % TORUS_SEGMENTS; + unsigned int x1 = (i+1) % TORUS_SEGMENTS; + for(j = 0; j < TORUS_SLICES; j++) { + unsigned int y0 = j % TORUS_SLICES; + unsigned int y1 = (j+1) % TORUS_SLICES; + + triangleTorus[i][j*6+0].x = indexedTorus[x0][y0].x; + triangleTorus[i][j*6+0].y = indexedTorus[x0][y0].y; + triangleTorus[i][j*6+0].z = indexedTorus[x0][y0].z; + + triangleTorus[i][j*6+1].x = indexedTorus[x1][y0].x; + triangleTorus[i][j*6+1].y = indexedTorus[x1][y0].y; + triangleTorus[i][j*6+1].z = indexedTorus[x1][y0].z; + + triangleTorus[i][j*6+2].x = indexedTorus[x0][y1].x; + triangleTorus[i][j*6+2].y = indexedTorus[x0][y1].y; + triangleTorus[i][j*6+2].z = indexedTorus[x0][y1].z; + + triangleTorus[i][j*6+3].x = indexedTorus[x1][y0].x; + triangleTorus[i][j*6+3].y = indexedTorus[x1][y0].y; + triangleTorus[i][j*6+3].z = indexedTorus[x1][y0].z; + + triangleTorus[i][j*6+4].x = indexedTorus[x1][y1].x; + triangleTorus[i][j*6+4].y = indexedTorus[x1][y1].y; + triangleTorus[i][j*6+4].z = indexedTorus[x1][y1].z; + + triangleTorus[i][j*6+5].x = indexedTorus[x0][y1].x; + triangleTorus[i][j*6+5].y = indexedTorus[x0][y1].y; + triangleTorus[i][j*6+5].z = indexedTorus[x0][y1].z; + } + } +} + +void buildTristripTorus() { + unsigned int i, j; + for(i = 0; i < TORUS_SEGMENTS; i++) { + unsigned int x0 = i % TORUS_SEGMENTS; + unsigned int x1 = (i+1) % TORUS_SEGMENTS; + for(j = 0; j < TORUS_SLICES + 1; j++) { + unsigned int y = j % TORUS_SLICES; + + tristripTorus[i][j*2+0].x = indexedTorus[x0][y].x; + tristripTorus[i][j*2+0].y = indexedTorus[x0][y].y; + tristripTorus[i][j*2+0].z = indexedTorus[x0][y].z; + + tristripTorus[i][j*2+1].x = indexedTorus[x1][y].x; + tristripTorus[i][j*2+1].y = indexedTorus[x1][y].y; + tristripTorus[i][j*2+1].z = indexedTorus[x1][y].z; + } + } +} + +void buildSplineTorus() { + unsigned int i, j; + for(i = 0; i <= TORUS_SEGMENTS + 2; i++) { + unsigned int x = i % TORUS_SEGMENTS; + for(j = 0; j <= TORUS_SLICES + 2; j++) { + unsigned int y = j % TORUS_SLICES; + + splineTorus[i][j].x = indexedTorus[x][y].x; + splineTorus[i][j].y = indexedTorus[x][y].y; + splineTorus[i][j].z = indexedTorus[x][y].z; + } + } +} + +static unsigned int start = 0; +static unsigned int end = 0; + +static const char* modenames[] = { + "Triangles ", + "Tristrips ", + "Spline(1,1)", + "Spline(2,2)", + "Spline(4,4)", + "Spline(8,8)" +}; + +static void gucallback(int id) { + if(id == 1) { + start = clock(); + } else if(id == 2) { + end = clock(); + } +} + +int main(int argc, char** argv) { + SetupCallbacks(); + + buildIndexedTorus(); + buildTriangleTorus(); + buildTristripTorus(); + buildSplineTorus(); + + pspDebugScreenInit(); + + sceKernelDcacheWritebackAll(); + + void* frameBuffer = (void*)0; + void* doubleBuffer = (void*)0x88000; + void* depthBuffer = (void*)0x110000; + + sceGuInit(); + + sceGuStart(GU_DIRECT,list); + sceGuDrawBuffer(GU_PSM_8888,frameBuffer,BUF_WIDTH); + sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,doubleBuffer,BUF_WIDTH); + sceGuDepthBuffer(depthBuffer,BUF_WIDTH); + sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); + sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); + sceGuDepthRange(0xc350,0x2710); + sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + sceGuDepthFunc(GU_GEQUAL); + sceGuEnable(GU_DEPTH_TEST); + sceGuFrontFace(GU_CW); + //sceGuEnable(GU_CULL_FACE); + sceGuDisable(GU_TEXTURE_2D); + sceGuSetCallback(GU_CALLBACK_SIGNAL, gucallback); + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuDisplay(GU_TRUE); + + int mode = 0; + int val = 0; + + SceCtrlData pad; + sceCtrlSetSamplingCycle(0); + sceCtrlSetSamplingMode(PSP_CTRL_MODE_DIGITAL); + unsigned int old = 0; + + while(1) { + sceGuStart(GU_DIRECT, list); + + sceGuClearDepth(0); + sceGuClearColor(0xff000000); + sceGuClear(GU_COLOR_BUFFER_BIT | GU_DEPTH_BUFFER_BIT); + + sceGuColor(0xff66ccff); + + sceGumMatrixMode(GU_PROJECTION); + sceGumLoadIdentity(); + sceGumPerspective(75.0f, 16.0f/9.0f, 0.5f, 10.0f); + + sceGumMatrixMode(GU_VIEW); + ScePspFVector3 pos = {0.0f,0.0f,-1.5f}; + sceGumLoadIdentity(); + sceGumTranslate(&pos); + + sceGumMatrixMode(GU_MODEL); + ScePspFVector3 rot = {val * 0.263f * (GU_PI/180.0f), val * 0.32f * (GU_PI/180.0f), val * 0.44f * (GU_PI/180.0f)}; + sceGumLoadIdentity(); + sceGumRotateXYZ(&rot); + + switch(mode) { + case 0 : + sceGuSignal(GU_BEHAVIOR_SUSPEND, 1); + sceGumDrawArray(GU_TRIANGLES, GU_VERTEX_32BITF, TORUS_SEGMENTS * TORUS_SLICES * 6, 0, triangleTorus); + sceGuSignal(GU_BEHAVIOR_SUSPEND, 2); + break; + + case 1 : + sceGuSignal(GU_BEHAVIOR_SUSPEND, 1); + sceGumDrawArrayN(GU_TRIANGLE_STRIP, GU_VERTEX_32BITF, TORUS_SLICES*2+2, TORUS_SEGMENTS, 0, tristripTorus); + sceGuSignal(GU_BEHAVIOR_SUSPEND, 2); + break; + + case 2 : + sceGuPatchDivide(1, 1); + sceGuSignal(GU_BEHAVIOR_SUSPEND, 1); + sceGumDrawSpline(GU_VERTEX_32BITF, TORUS_SEGMENTS + 3, TORUS_SLICES + 3, GU_FILL_FILL, GU_FILL_FILL, 0, splineTorus); + sceGuSignal(GU_BEHAVIOR_SUSPEND, 2); + break; + + case 3 : + sceGuPatchDivide(2, 2); + sceGuSignal(GU_BEHAVIOR_SUSPEND, 1); + sceGumDrawSpline(GU_VERTEX_32BITF, TORUS_SEGMENTS + 3, TORUS_SLICES + 3, GU_FILL_FILL, GU_FILL_FILL, 0, splineTorus); + sceGuSignal(GU_BEHAVIOR_SUSPEND, 2); + break; + + case 4 : + sceGuPatchDivide(4, 4); + sceGuSignal(GU_BEHAVIOR_SUSPEND, 1); + sceGumDrawSpline(GU_VERTEX_32BITF, TORUS_SEGMENTS + 3, TORUS_SLICES + 3, GU_FILL_FILL, GU_FILL_FILL, 0, splineTorus); + sceGuSignal(GU_BEHAVIOR_SUSPEND, 2); + break; + + default : + sceGuPatchDivide(8, 8); + sceGuSignal(GU_BEHAVIOR_SUSPEND, 1); + sceGumDrawSpline(GU_VERTEX_32BITF, TORUS_SEGMENTS + 3, TORUS_SLICES + 3, GU_FILL_FILL, GU_FILL_FILL, 0, splineTorus); + sceGuSignal(GU_BEHAVIOR_SUSPEND, 2); + break; + } + sceGuFinish(); + sceGuSync(0, 0); + + pspDebugScreenSetOffset((int)frameBuffer); + pspDebugScreenSetXY(0,0); + pspDebugScreenPrintf("%s: %1d.%03d ms", modenames[mode], (end - start)/1000, (end - start)%1000); + + frameBuffer = (void*)sceDisplayWaitVblankStart(); + sceGuSwapBuffers(); + + val++; + + sceCtrlReadBufferPositive(&pad, 1); + if(old != pad.Buttons) { + if(pad.Buttons & (PSP_CTRL_CROSS | PSP_CTRL_CIRCLE)) { + mode+=1; + mode%=6; + } + } + old = pad.Buttons; + } + + sceGuTerm(); + + sceKernelExitGame(); + return 0; +} + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + sceKernelExitGame(); + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0); + if(thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} diff --git a/src/samples/gu/vertex/Makefile.sample b/src/samples/gu/vertex/Makefile.sample new file mode 100644 index 00000000..46fc1ee9 --- /dev/null +++ b/src/samples/gu/vertex/Makefile.sample @@ -0,0 +1,17 @@ +TARGET = vertex +OBJS = vertex.o ../common/callbacks.o ../common/vram.o ../common/menu.o + +INCDIR = +CFLAGS = -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = +LIBS= -lpspgum -lpspgu -lm -lpsprtc + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Vertex Speed Sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/gu/vertex/vertex.c b/src/samples/gu/vertex/vertex.c new file mode 100644 index 00000000..548e35cf --- /dev/null +++ b/src/samples/gu/vertex/vertex.c @@ -0,0 +1,624 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "../common/callbacks.h" +#include "../common/vram.h" +#include "../common/menu.h" + +PSP_MODULE_INFO("Vertex Speed Sample", 0, 1, 1); +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER); + +static unsigned int __attribute__((aligned(16))) list[262144]; + +#define BUF_WIDTH (512) +#define SCR_WIDTH (480) +#define SCR_HEIGHT (272) + +// TODO: fix alignments + +int getVertexSize(int vertexFormat) +{ + enum + { + SIZE, + WEIGHTS, + VERTEX, + }; + + static int vertexValues[] = + { + 4, 0, GU_TEXTURE_BITS, SIZE, 2, 0, 1, 2, 4, + 4, 9, GU_WEIGHT_BITS, WEIGHTS, 1, 0, 1, 2, 4, + 8, 2, GU_COLOR_BITS, SIZE, 1, 0, 0, 0, 0, 2, 2, 2, 4, + 4, 5, GU_NORMAL_BITS, SIZE, 3, 0, 1, 2, 4, + 4, 7, GU_VERTEX_BITS, SIZE, 3, 0, 1, 2, 4, + 0, 11, GU_VERTICES_BITS, VERTEX, 0, + 0, 0, 0, + }; + + int* current = vertexValues; + int size = 0; + + while (current[0] || current[1] || current[2]) + { + int currentCount = current[0]; + int currentShift = current[1]; + int currentBits = current[2]; + int mode = current[3]; + int numElements = current[4]; + + current += 5; + + switch (mode) + { + case SIZE: + { + int elementSize = current[(vertexFormat & currentBits) >> currentShift]; + + // align + if (elementSize > 0) + size = (size + (elementSize-1)) & ~(elementSize-1); + + size += elementSize * numElements; + } + break; + + case WEIGHTS: + { + int elementSize = current[(vertexFormat & currentBits) >> currentShift]; + int numWeights = ((vertexFormat & GU_WEIGHTS_BITS) >> 14)+1; + + if (elementSize > 0) + size = (size + (elementSize-1)) & ~(elementSize-1); + + if (numWeights > 1) + size += numWeights * elementSize; + } + break; + + case VERTEX: + { + int numVertices = ((vertexFormat & GU_VERTICES_BITS) >> 18); + if (size > 0) + size = (size + (4-1)) & ~(4-1); + size += size * numVertices; + } + break; + } + + + current += currentCount; + } + + // align to size of first element? + if (size > 0) + size = (size + (4-1)) & ~(4-1); + + return size; +} + +void generateVertexBuffer(int vertexFormat, void* vertices, int batchSize) +{ + int vertexSize = getVertexSize(vertexFormat); +// int textureOffset = 0; + int colorOffset = getVertexSize(vertexFormat & (GU_TEXTURE_BITS)); +// int normalOffset = getVertexSize(vertexFormat & (GU_TEXTURE_BITS|GU_COLOR_BITS)); + int vertexOffset = getVertexSize(vertexFormat & (GU_TEXTURE_BITS|GU_COLOR_BITS|GU_NORMAL_BITS)); + float batchScale = 1.0f / batchSize; + int i; + + char* current = vertices; + + for (i = 0; i < batchSize; ++i) + { + memset(current,0,vertexSize); + + // TODO: render something nice +/* + float x = cosf((i * batchScale) * (GU_PI*2)); + float y = sinf((i * batchScale) * (GU_PI*2)); + + switch (vertexFormat & GU_COLOR_BITS) + { + case GU_COLOR_5650: + case GU_COLOR_5551: + case GU_COLOR_4444: + { + unsigned short* color = (unsigned short*)(current + colorOffset); + *color = i; + } + break; + + case GU_COLOR_8888: + { + unsigned int* color = (unsigned int*)(current + colorOffset); + *color = i; + } + break; + } + + switch (vertexFormat & GU_VERTEX_BITS) + { + case GU_VERTEX_8BIT: + { + char* vertex = (char*)(current + vertexOffset); + vertex[0] = x * 127.5f; + vertex[1] = y * 127.5f; + } + break; + + case GU_VERTEX_16BIT: + { + short* vertex = (short*)(current + vertexOffset); + vertex[0] = x * 32767.5f; + vertex[1] = y * 32767.5f; + } + break; + + case GU_VERTEX_32BITF: + { + float* vertex = (float*)(current + vertexOffset); + vertex[0] = x; + vertex[1] = y; + } + break; + } +*/ + current = current + vertexSize; + } +} + +typedef enum +{ + NoAction, + TextureMenu, + ColorMenu, + NormalMenu, + VertexMenu, + WeightMenu, + NumWeightsMenu, + NumVerticesMenu, + IndexBufferMenu, + IndexFormatMenu, + IndexMemoryMenu, + IndexCacheMenu, + MemoryMenu, + QuitTrigger +} MenuAction; + +int main(int argc, char* argv[]) +{ + setupCallbacks(); + + // setup GU + + void* fbp0 = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_8888); + void* fbp1 = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_8888); + void* zbp = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_4444); + + pspDebugScreenInit(); + sceGuInit(); + + sceGuStart(GU_DIRECT,list); + sceGuDrawBuffer(GU_PSM_8888,fbp0,BUF_WIDTH); + sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,fbp1,BUF_WIDTH); + sceGuDepthBuffer(zbp,BUF_WIDTH); + sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); + sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); + sceGuDepthRange(65535,0); + sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + sceGuDepthFunc(GU_GEQUAL); + sceGuEnable(GU_DEPTH_TEST); + sceGuFrontFace(GU_CW); + sceGuShadeModel(GU_SMOOTH); + sceGuEnable(GU_CULL_FACE); + sceGuEnable(GU_TEXTURE_2D); + sceGuEnable(GU_CLIP_PLANES); + + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuDisplay(GU_TRUE); + + // allocate vertex buffers + + int maxVertexSize = getVertexSize(GU_TEXTURE_32BITF|GU_COLOR_8888|GU_NORMAL_32BITF|GU_VERTEX_32BITF|GU_WEIGHT_32BITF|GU_WEIGHTS(8)|GU_VERTICES(8)); + int batchSize = 1536; // max size = 608, 608 * 1536 = ~1MB, make sure you don't overrun vram limits if you change this + void* ramVertexBuffer = malloc(batchSize * maxVertexSize); + void* vramVertexBuffer = getStaticVramTexture(batchSize,maxVertexSize,GU_PSM_T8); + + // allocate index buffers + + void* ramIndexBuffer = malloc(batchSize * sizeof(unsigned short)); + void* vramIndexBuffer = getStaticVramTexture(batchSize,sizeof(unsigned short),GU_PSM_T8); + + // run sample + + int val = 0; + SceCtrlData oldPad; + memset(&oldPad,0,sizeof(SceCtrlData)); + + sceCtrlSetSamplingCycle(0); + sceCtrlSetSamplingMode(0); + + // create debug menu + + MenuContext* context = initMenu(); + + MenuItem* vertexFormatMenu = addMenuItem(context,0,createMenuContainer("Vertex Buffer"),NoAction,0); + { + MenuItem* textureMenu = addMenuItem(context,vertexFormatMenu,createMenuContainer("Texture"),NoAction,0); + { + addMenuItem(context,textureMenu,createRadioButton("Off",1),TextureMenu,0); + addMenuItem(context,textureMenu,createRadioButton("8-bit",0),TextureMenu,GU_TEXTURE_8BIT); + addMenuItem(context,textureMenu,createRadioButton("16-bit",0),TextureMenu,GU_TEXTURE_16BIT); + addMenuItem(context,textureMenu,createRadioButton("32-bit",0),TextureMenu,GU_TEXTURE_32BITF); + } + + MenuItem* colorMenu = addMenuItem(context,vertexFormatMenu,createMenuContainer("Color"),NoAction,0); + { + addMenuItem(context,colorMenu,createRadioButton("Off",0),ColorMenu,0); + addMenuItem(context,colorMenu,createRadioButton("5650 (16-bit)",0),ColorMenu,GU_COLOR_5650); + addMenuItem(context,colorMenu,createRadioButton("5551 (16-bit)",0),ColorMenu,GU_COLOR_5551); + addMenuItem(context,colorMenu,createRadioButton("4444 (16-bit)",0),ColorMenu,GU_COLOR_4444); + addMenuItem(context,colorMenu,createRadioButton("8888 (32-bit)",1),ColorMenu,GU_COLOR_8888); + } + + MenuItem* normalMenu = addMenuItem(context,vertexFormatMenu,createMenuContainer("Normal"),NoAction,0); + { + addMenuItem(context,normalMenu,createRadioButton("Off",1),NormalMenu,0); + addMenuItem(context,normalMenu,createRadioButton("8-bit",0),NormalMenu,GU_NORMAL_8BIT); + addMenuItem(context,normalMenu,createRadioButton("16-bit",0),NormalMenu,GU_NORMAL_16BIT); + addMenuItem(context,normalMenu,createRadioButton("32-bit",0),NormalMenu,GU_NORMAL_32BITF); + } + + MenuItem* vertexMenu = addMenuItem(context,vertexFormatMenu,createMenuContainer("Vertex"),NoAction,0); + { + addMenuItem(context,vertexMenu,createRadioButton("Off",0),VertexMenu,0); + addMenuItem(context,vertexMenu,createRadioButton("8-bit",0),VertexMenu,GU_VERTEX_8BIT); + addMenuItem(context,vertexMenu,createRadioButton("16-bit",0),VertexMenu,GU_VERTEX_16BIT); + addMenuItem(context,vertexMenu,createRadioButton("32-bit",1),VertexMenu,GU_VERTEX_32BITF); + } + + MenuItem* weightMenu = addMenuItem(context,vertexFormatMenu,createMenuContainer("Weight"),NoAction,0); + { + addMenuItem(context,weightMenu,createRadioButton("Off",1),WeightMenu,0); + addMenuItem(context,weightMenu,createRadioButton("8-bit",0),WeightMenu,GU_WEIGHT_8BIT); + addMenuItem(context,weightMenu,createRadioButton("16-bit",0),WeightMenu,GU_WEIGHT_16BIT); + addMenuItem(context,weightMenu,createRadioButton("32-bit",0),WeightMenu,GU_WEIGHT_32BITF); + } + + MenuItem* numWeightsMenu = addMenuItem(context,vertexFormatMenu,createMenuContainer("Num. Weights"),NoAction,0); + { + addMenuItem(context,numWeightsMenu,createRadioButton("0",1),NumWeightsMenu,0); + addMenuItem(context,numWeightsMenu,createRadioButton("2",0),NumWeightsMenu,GU_WEIGHTS(2)); + addMenuItem(context,numWeightsMenu,createRadioButton("3",0),NumWeightsMenu,GU_WEIGHTS(3)); + addMenuItem(context,numWeightsMenu,createRadioButton("4",0),NumWeightsMenu,GU_WEIGHTS(4)); + addMenuItem(context,numWeightsMenu,createRadioButton("5",0),NumWeightsMenu,GU_WEIGHTS(5)); + addMenuItem(context,numWeightsMenu,createRadioButton("6",0),NumWeightsMenu,GU_WEIGHTS(6)); + addMenuItem(context,numWeightsMenu,createRadioButton("7",0),NumWeightsMenu,GU_WEIGHTS(7)); + addMenuItem(context,numWeightsMenu,createRadioButton("8",0),NumWeightsMenu,GU_WEIGHTS(8)); + } + + MenuItem* numVerticesMenu = addMenuItem(context,vertexFormatMenu,createMenuContainer("Num. Vertices"),NoAction,0); + { + addMenuItem(context,numVerticesMenu,createRadioButton("1",1),NumVerticesMenu,GU_VERTICES(1)); + addMenuItem(context,numVerticesMenu,createRadioButton("2",0),NumVerticesMenu,GU_VERTICES(2)); + addMenuItem(context,numVerticesMenu,createRadioButton("3",0),NumVerticesMenu,GU_VERTICES(3)); + addMenuItem(context,numVerticesMenu,createRadioButton("4",0),NumVerticesMenu,GU_VERTICES(4)); + addMenuItem(context,numVerticesMenu,createRadioButton("5",0),NumVerticesMenu,GU_VERTICES(5)); + addMenuItem(context,numVerticesMenu,createRadioButton("6",0),NumVerticesMenu,GU_VERTICES(6)); + addMenuItem(context,numVerticesMenu,createRadioButton("7",0),NumVerticesMenu,GU_VERTICES(7)); + addMenuItem(context,numVerticesMenu,createRadioButton("8",0),NumVerticesMenu,GU_VERTICES(8)); + } + + MenuItem* memoryMenu = addMenuItem(context,vertexFormatMenu,createMenuContainer("Memory Location"),NoAction,0); + { + addMenuItem(context,memoryMenu,createRadioButton("System RAM",1),MemoryMenu,0); + addMenuItem(context,memoryMenu,createRadioButton("Video RAM",0),MemoryMenu,1); + } + } + + + MenuItem* indexBufferMenu = addMenuItem(context,0,createMenuContainer("Index Buffer"),NoAction,0); + { + addMenuItem(context,indexBufferMenu,createRadioButton("Disabled",1),IndexBufferMenu,0); + addMenuItem(context,indexBufferMenu,createRadioButton("Enabled",0),IndexBufferMenu,1); + + MenuItem* indexFormatMenu = addMenuItem(context,indexBufferMenu,createMenuContainer("Format"),NoAction,0); + { + addMenuItem(context,indexFormatMenu,createRadioButton("8-bit",0),IndexFormatMenu,GU_INDEX_8BIT); + addMenuItem(context,indexFormatMenu,createRadioButton("16-bit",1),IndexFormatMenu,GU_INDEX_16BIT); + } + + MenuItem* indexMemoryMenu = addMenuItem(context,indexBufferMenu,createMenuContainer("Memory Location"),NoAction,0); + { + addMenuItem(context,indexMemoryMenu,createRadioButton("System RAM",1),IndexMemoryMenu,0); + addMenuItem(context,indexMemoryMenu,createRadioButton("Video RAM",0),IndexMemoryMenu,1); + } + + MenuItem* indexCacheMenu = addMenuItem(context,indexBufferMenu,createMenuContainer("Cache Test Size"),NoAction,0); + { + addMenuItem(context,indexCacheMenu,createRadioButton("Disabled",1),IndexCacheMenu,batchSize); + addMenuItem(context,indexCacheMenu,createRadioButton("4",0),IndexCacheMenu,4); + addMenuItem(context,indexCacheMenu,createRadioButton("8",0),IndexCacheMenu,8); + addMenuItem(context,indexCacheMenu,createRadioButton("16",0),IndexCacheMenu,16); + addMenuItem(context,indexCacheMenu,createRadioButton("32",0),IndexCacheMenu,32); + } + } + + addMenuItem(context,0,createTriggerButton("Quit"),QuitTrigger,0); + + unsigned int vertexMask = GU_COLOR_8888|GU_VERTEX_32BITF; + unsigned int vertexSize = getVertexSize(vertexMask); + int exitRequested = 0; + int changed = 1; + int memorySelection = 0; + int indexEnabled = 0; + int indexFormat = GU_INDEX_16BIT; + int indexCacheSize = batchSize; + int indexMemory = 0; + u64 tickCount = 0; + u32 tickResolution = sceRtcGetTickResolution(); + u32 vertexCount = 0; + float avgVertexSpeed = 0; + int batchCount = 1; + + while(running() && !exitRequested) + { + SceCtrlData pad; + if (!sceCtrlPeekBufferPositive(&pad,1)) + pad = oldPad; + + MenuItem* action = handleMenu(context, &pad); + if (action) + { + switch (action->id) + { + case TextureMenu: + { + vertexMask = (vertexMask & ~GU_TEXTURE_BITS) | action->data; + changed = 1; + } + break; + + case ColorMenu: + { + vertexMask = (vertexMask & ~GU_COLOR_BITS) | action->data; + changed = 1; + } + break; + + case NormalMenu: + { + vertexMask = (vertexMask & ~GU_NORMAL_BITS) | action->data; + changed = 1; + } + break; + + case VertexMenu: + { + vertexMask = (vertexMask & ~GU_VERTEX_BITS) | action->data; + changed = 1; + } + break; + + case WeightMenu: + { + vertexMask = (vertexMask & ~GU_WEIGHT_BITS) | action->data; + changed = 1; + } + break; + + case NumWeightsMenu: + { + vertexMask = (vertexMask & ~GU_WEIGHTS_BITS) | action->data; + changed = 1; + } + break; + + case NumVerticesMenu: + { + vertexMask = (vertexMask & ~GU_VERTICES_BITS) | action->data; + changed = 1; + } + break; + + case IndexBufferMenu: + { + indexEnabled = action->data; + vertexMask = (vertexMask & ~GU_INDEX_BITS) | (indexEnabled ? indexFormat : 0); + changed = 1; + } + break; + + case IndexFormatMenu: + { + indexFormat = action->data; + vertexMask = (vertexMask & ~GU_INDEX_BITS) | (indexEnabled ? indexFormat : 0); + changed = 1; + } + break; + + case IndexCacheMenu: + { + indexCacheSize = action->data; + changed = 1; + } + break; + + case IndexMemoryMenu: + { + indexMemory = action->data; + changed = 1; + } + break; + + case MemoryMenu: + { + memorySelection = action->data; + changed = 1; + } + break; + + case QuitTrigger: + exitRequested = 1; + break; + + case NoAction: + default: + break; + } + } + + if (changed) + { + pspDebugScreenSetOffset((int)fbp1); + pspDebugScreenSetXY((60/2)-(31/2),33/2); // TODO: center? + pspDebugScreenPrintf("--- Rebuilding buffers ---"); + + // re-generate buffers + + generateVertexBuffer(vertexMask,memorySelection ? vramVertexBuffer : ramVertexBuffer,batchSize); + if (indexEnabled) + { + switch (vertexMask & GU_INDEX_BITS) + { + case GU_INDEX_8BIT: + { + unsigned char* indexBuffer = indexMemory ? vramIndexBuffer : ramIndexBuffer; + int i; + for (i = 0; i < batchSize; ++i) + *indexBuffer++ = (i % indexCacheSize); + } + break; + + case GU_INDEX_16BIT: + { + unsigned short* indexBuffer = indexMemory ? vramIndexBuffer : ramIndexBuffer; + int i; + for (i = 0; i < batchSize; ++i) + *indexBuffer++ = (i % indexCacheSize); + } + break; + } + } + + + + vertexSize = getVertexSize(vertexMask); + sceKernelDcacheWritebackAll(); + changed = 0; + + vertexCount = 0; + tickCount = 0; + avgVertexSpeed = 0; + batchCount = 1; + } + + // TODO: additional input processing here + + oldPad = pad; + + sceGuStart(GU_SEND,list); + + // run gu stuff not to be measured + + sceGuStart(GU_DIRECT,list); + + sceGuClearColor(0xff554433); + sceGuClearDepth(0); + sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); + + sceGumMatrixMode(GU_PROJECTION); + sceGumLoadIdentity(); + sceGumPerspective(75.0f,16.0f/9.0f,0.5f,1000.0f); + + sceGumMatrixMode(GU_VIEW); + sceGumLoadIdentity(); + + sceGumMatrixMode(GU_MODEL); + sceGumLoadIdentity(); + + sceGuFinish(); + sceGuSync(0,0); + + // draw cube + + sceGuStart(GU_SEND,list); + int i; + for (i = 0; i < batchCount; ++i) + sceGumDrawArray(GU_POINTS,vertexMask,batchSize,indexMemory ? vramIndexBuffer : ramIndexBuffer,memorySelection ? vramVertexBuffer : ramVertexBuffer); + sceGuFinish(); + vertexCount += batchSize * batchCount; + + PspGeContext tempGeContext; + u64 tick1,tick2; + sceRtcGetCurrentTick(&tick1); + sceGuSendList(GU_TAIL,list,&tempGeContext); + sceGuSync(0,0); + sceRtcGetCurrentTick(&tick2); + + // rescale number of batches if they rendered faster/slower than threshold + + if (((tick2-tick1) < (tickResolution * (1.0f/60.0f) * 0.8f)) || ((tick2-tick1) > (tickResolution * (1.0f/60.0f) * 1.0f))) + { + batchCount = (int)((tickResolution * (1.0f/60.0f) * 0.8f) / (((tick2-tick1) / (float)batchCount))); + batchCount = batchCount > 130 ? 130 : batchCount < 1 ? 1 : batchCount; + } + + tickCount += (tick2-tick1); + if (tickCount > tickResolution) + { + float timeSpan = tickCount / (float)tickResolution; + avgVertexSpeed = (vertexCount / timeSpan) / 1000000; + + tickCount = 0; + vertexCount = 0; + } + + pspDebugScreenSetOffset((int)fbp0); + pspDebugScreenSetXY(0,0); + pspDebugScreenPrintf("Mask: 0x%08x, Size: %u", vertexMask, vertexSize,val); + if (avgVertexSpeed) + pspDebugScreenPrintf(", %.2f million vertices / sec.",avgVertexSpeed); + else + pspDebugScreenPrintf(", accumulating (%.2f%%)...",100.0f * (tickCount / (float)tickResolution)); + + pspDebugScreenSetXY(0,32); + pspDebugScreenPrintf("This is performance numbers, not real world numbers!"); + + renderMenu(context,0,2); + + sceDisplayWaitVblankStart(); + fbp1 = fbp0; + fbp0 = sceGuSwapBuffers(); + + val++; + } + + sceGuTerm(); + + sceKernelExitGame(); + return 0; +} diff --git a/src/samples/gu/zbufferfog/Makefile.sample b/src/samples/gu/zbufferfog/Makefile.sample new file mode 100644 index 00000000..acd19a17 --- /dev/null +++ b/src/samples/gu/zbufferfog/Makefile.sample @@ -0,0 +1,17 @@ +TARGET = zbufferfog +OBJS = zbufferfog.o ../common/callbacks.o ../common/geometry.o ../common/vram.o + +INCDIR = +CFLAGS = -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = +LIBS= -lpspgum -lpspgu -lm + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Depth Buffer Fog Sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/gu/zbufferfog/zbufferfog.c b/src/samples/gu/zbufferfog/zbufferfog.c new file mode 100644 index 00000000..aef564d5 --- /dev/null +++ b/src/samples/gu/zbufferfog/zbufferfog.c @@ -0,0 +1,256 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * This implements unswizzled depth-fog using the hardware unswizzling + * figured out by Jeremy Fitzhardinge. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "../common/callbacks.h" +#include "../common/geometry.h" +#include "../common/vram.h" + +PSP_MODULE_INFO("Depth Buffer Fog Sample", 0, 1, 1); +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER); + +static unsigned int __attribute__((aligned(16))) list[262144]; + +#define BUFFER_WIDTH 512 // actual screen width +#define SCREEN_WIDTH 480 // visible screen width +#define SCREEN_HEIGHT 272 // visible screen height +#define SCREEN_PSM GU_PSM_8888 // screen pixel format + +#define TORUS_SLICES 48 // numc +#define TORUS_ROWS 48 // numt +#define TORUS_RADIUS 1.0f +#define TORUS_THICKNESS 0.5f + +TCPVertex __attribute__((aligned(16))) torus_vertices[TORUS_SLICES*TORUS_ROWS]; +unsigned short __attribute__((aligned(16))) torus_indices[TORUS_SLICES*TORUS_ROWS*6]; + +#define ZBUFFER_LINEAR(x) (0x600000 + x) +#define ZBUFFER_SLICE 64 +#define VRAM_OFFSET(x) (0x4000000 + x) +#define ZFAR_LIMIT 64 +#define ZNEAR_LIMIT 256 +#define FOG_COLOR 0x554433 + +unsigned int __attribute__((aligned(16))) fogPalette[256]; +unsigned int __attribute__((aligned(16))) rawPalette[256]; + +void RenderFog(void* zbuffer) +{ + int i; + + // split in two passes since the depth buffer won't fit in a 512x512 texture when using 8-bit textures + + for (i = 0; i < 2; ++i) + { + int j; + + sceGuTexMode(GU_PSM_T8,0,0,0); + sceGuTexImage(0,512,512,1024,(void*)VRAM_OFFSET(ZBUFFER_LINEAR(((unsigned int)zbuffer) + i * (256*2)))); + sceGuTexFunc(GU_TFX_REPLACE,GU_TCC_RGBA); + sceGuTexFilter(GU_NEAREST,GU_NEAREST); + sceGuColor(0); + + for (j = 0; j < (256/ZBUFFER_SLICE); ++j) + { + TPVertex* vertices = (TPVertex*)sceGuGetMemory(sizeof(TPVertex)*2); + + // shift texture 1 pixel to avoid the 8 LSB, since they change very rapidly + + vertices[0].texture.x = 1 + j*(ZBUFFER_SLICE * 2); + vertices[0].texture.y = 0; + vertices[0].position.x = j*ZBUFFER_SLICE + i * 256; + vertices[0].position.y = 0; + vertices[0].position.z = 0; + + vertices[1].texture.x = 1 + (j+1)*(ZBUFFER_SLICE * 2); + vertices[1].texture.y = SCREEN_HEIGHT; + vertices[1].position.x = (j+1)*ZBUFFER_SLICE + i * 256; + vertices[1].position.y = SCREEN_HEIGHT; + vertices[1].position.z = 0; + + sceGuDrawArray(GU_SPRITES,TP_VERTEX_FORMAT|GU_TRANSFORM_2D,2,0,vertices); + } + } +} + +int main(int argc, char* argv[]) +{ + setupCallbacks(); + + // generate geometry & palettes + + int i; + + generateTorusTCP(TORUS_SLICES,TORUS_ROWS,TORUS_RADIUS,TORUS_THICKNESS,torus_vertices,torus_indices); + + for (i = 0; i < 256; ++i) + { + unsigned int far = (i - ZFAR_LIMIT) < 0 ? 0 : (i - ZFAR_LIMIT); + unsigned int near = (far * 256) / (ZNEAR_LIMIT-ZFAR_LIMIT); + unsigned int k = near > 255 ? 255 : near; + fogPalette[i] = (k << 24)|FOG_COLOR; + + rawPalette[i] = (i << 24)|(i << 16)|(i << 8)|i; + } + + sceKernelDcacheWritebackAll(); + + // setup GU + + sceGuInit(); + + void* fbp0 = getStaticVramBuffer(BUFFER_WIDTH,SCREEN_HEIGHT,SCREEN_PSM); // drawbuffer 1, 512x272 (480x272 visible) + void* fbp1 = getStaticVramBuffer(BUFFER_WIDTH,SCREEN_HEIGHT,SCREEN_PSM); // drawbuffer 2 + void* zbp = getStaticVramBuffer(BUFFER_WIDTH,SCREEN_HEIGHT,GU_PSM_4444); // zbuffer, always 16bit + + sceGuStart(GU_DIRECT,list); + sceGuDrawBuffer(SCREEN_PSM,fbp0,BUFFER_WIDTH); + sceGuDispBuffer(SCREEN_WIDTH,SCREEN_HEIGHT,fbp1,BUFFER_WIDTH); + sceGuDepthBuffer(zbp,BUFFER_WIDTH); + sceGuOffset(2048 - (SCREEN_WIDTH/2),2048 - (SCREEN_HEIGHT/2)); + sceGuViewport(2048,2048,SCREEN_WIDTH,SCREEN_HEIGHT); + sceGuDepthRange(65535,0); + sceGuDisable(GU_SCISSOR_TEST); + sceGuDepthFunc(GU_GEQUAL); + sceGuEnable(GU_DEPTH_TEST); + sceGuFrontFace(GU_CW); + sceGuShadeModel(GU_SMOOTH); + sceGuEnable(GU_CULL_FACE); + sceGuEnable(GU_CLIP_PLANES); + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuDisplay(GU_TRUE); + + pspDebugScreenInit(); + + // run sample + + int val = 0; + int split = 0; + SceCtrlData oldPad; + oldPad.Buttons = 0; + + sceCtrlSetSamplingCycle(0); + sceCtrlSetSamplingMode(0); + + while(running()) + { + sceGuStart(GU_DIRECT,list); + + // switch mode if requested + + SceCtrlData pad; + if (sceCtrlPeekBufferPositive(&pad,1)) + { + if (pad.Buttons != oldPad.Buttons) + { + if (pad.Buttons & PSP_CTRL_CROSS) + split ^= 1; + } + oldPad = pad; + } + + // clear screen + + sceGuClearColor(0); + sceGuClearDepth(0); + sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); + + // setup matrices for cube + + sceGumMatrixMode(GU_PROJECTION); + sceGumLoadIdentity(); + sceGumPerspective(75.0f,16.0f/9.0f,1.0f,100.0f); + + sceGumMatrixMode(GU_VIEW); + sceGumLoadIdentity(); + + sceGumMatrixMode(GU_MODEL); + sceGumLoadIdentity(); + { + ScePspFVector3 pos = { 0, 0, -5.0f + sinf(val * (GU_PI/180.0f)) * 2.5f }; + ScePspFVector3 rot = { val * 0.79f * (GU_PI/180.0f), val * 0.98f * (GU_PI/180.0f), val * 1.32f * (GU_PI/180.0f) }; + sceGumTranslate(&pos); + sceGumRotateXYZ(&rot); + } + + // draw cube + + sceGumDrawArray(GU_TRIANGLES,GU_TEXTURE_32BITF|GU_COLOR_8888|GU_VERTEX_32BITF|GU_INDEX_16BIT|GU_TRANSFORM_3D,sizeof(torus_indices)/sizeof(unsigned short),torus_indices,torus_vertices); + + // fog using the zbuffer + + sceGuEnable(GU_TEXTURE_2D); + sceGuDisable(GU_DEPTH_TEST); + sceGuDepthMask(0xffff); + sceGuColor(0); + + sceGuClutMode(GU_PSM_8888,0,255,0); + sceGuClutLoad(256/8,fogPalette); + + sceGuEnable(GU_BLEND); + sceGuBlendFunc(GU_ADD,GU_ONE_MINUS_SRC_ALPHA,GU_SRC_ALPHA,0,0); + + RenderFog(zbp); + + sceGuDisable(GU_BLEND); + + // render raw fog if enabled + + if (split) + { + sceGuEnable(GU_SCISSOR_TEST); + sceGuScissor(SCREEN_WIDTH/2,0,SCREEN_WIDTH,SCREEN_HEIGHT); + + sceGuClutMode(GU_PSM_8888,0,255,0); + sceGuClutLoad(256/8,rawPalette); + + RenderFog(zbp); + + sceGuDisable(GU_SCISSOR_TEST); + } + + sceGuDisable(GU_TEXTURE_2D); + sceGuEnable(GU_DEPTH_TEST); + sceGuDepthMask(0); + + sceGuFinish(); + sceGuSync(0,0); + + pspDebugScreenSetOffset((int)fbp0); + pspDebugScreenSetXY(0,0); + pspDebugScreenPrintf("X = normal/split screen"); + + sceDisplayWaitVblankStart(); + fbp0 = sceGuSwapBuffers(); + + + val++; + } + + sceGuTerm(); + + sceKernelExitGame(); + return 0; +} diff --git a/src/samples/ir/irda/Makefile.sample b/src/samples/ir/irda/Makefile.sample new file mode 100644 index 00000000..bb2ef5c8 --- /dev/null +++ b/src/samples/ir/irda/Makefile.sample @@ -0,0 +1,17 @@ +TARGET = irda +OBJS = main.o + +INCDIR = +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LIBS = +LDFLAGS = + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = IrDA Test v1.0 + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/ir/irda/main.c b/src/samples/ir/irda/main.c new file mode 100644 index 00000000..1e05ff20 --- /dev/null +++ b/src/samples/ir/irda/main.c @@ -0,0 +1,107 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - IrDA example + * + * Copyright (c) 2005 Frank Buss (aka Shine) + * + * $Id: main.c 705 2005-07-20 18:09:56Z tyranid $ + */ +#include +#include +#include +#include +#include +#include +#include + +/* Define the module info section */ +PSP_MODULE_INFO("IRDA", 0, 1, 1); + +/* Define the main thread's attribute value (optional) */ +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU); + +/* Define printf, just to make typing easier */ +#define printf pspDebugScreenPrintf + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + sceKernelExitGame(); + + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0); + if(thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} + +int main(void) +{ + SceCtrlData pad; + u32 buttonsold = 0; + + SetupCallbacks(); + pspDebugScreenInit(); + + sceCtrlSetSamplingCycle(0); + sceCtrlSetSamplingMode(PSP_CTRL_MODE_DIGITAL); + + printf ("IrDA PSP-2-PSP Example by Shine\n"); + printf ("-------------------------------\n"); + printf ("This example can be used with two PSPs\n\n"); + printf ("Press CROSS, SQUARE, CIRCLE or TRIANGLE\n"); + printf ("and it will be displayed at the other PSP\n\n"); + + int fd = sceIoOpen("irda0:", PSP_O_RDWR, 0); + + while (1) { + // read pad and send it + sceCtrlReadBufferPositive(&pad, 1); + if (pad.Buttons != buttonsold) { + unsigned char padHighbyte = pad.Buttons >> 8; + sceIoWrite(fd, &padHighbyte, 1); + buttonsold = pad.Buttons; + } + + // check for pad info from other PSP + unsigned char data; + int len = sceIoRead(fd, &data, 1); + int otherPad = data << 8; + if (len == 1) { + if (otherPad & PSP_CTRL_CIRCLE) printf ("CIRCLE pressed\n"); + if (otherPad & PSP_CTRL_CROSS) printf ("CROSS pressed\n"); + if (otherPad & PSP_CTRL_SQUARE) printf ("SQUARE pressed\n"); + if (otherPad & PSP_CTRL_TRIANGLE) printf ("TRIANGLE pressed\n"); + } + + sceDisplayWaitVblankStart(); + } + + return 0; +} diff --git a/src/samples/ir/sircs/Makefile.sample b/src/samples/ir/sircs/Makefile.sample new file mode 100644 index 00000000..dce8d4f1 --- /dev/null +++ b/src/samples/ir/sircs/Makefile.sample @@ -0,0 +1,17 @@ +TARGET = sircs +OBJS = main.o + +INCDIR = +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LIBS = -lpspsircs +LDFLAGS = + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Sircs Test v1.0 + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/ir/sircs/main.c b/src/samples/ir/sircs/main.c new file mode 100644 index 00000000..ffbf8cdb --- /dev/null +++ b/src/samples/ir/sircs/main.c @@ -0,0 +1,143 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Infrared Remote example + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * Copyright (c) 2005 Matthew H + * + * $$ + */ +#include +#include +#include +#include +#include +#include +#include + +/* Define the module info section */ +PSP_MODULE_INFO("SIRCS", 0, 1, 1); + +/* Define the main thread's attribute value (optional) */ +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU); + +/* Define printf, just to make typing easier */ +#define printf pspDebugScreenPrintf + +// sircs commands are easily found in lirc +// - interpret as described at +// http://sourceforge.net/mailarchive/message.php?msg_id=8833252 + +#define SIRCS_ADDR_DVD 0x1b5a +#define SIRCS_CMD_RESET 0x15 +#define SIRCS_CMD_PLAY 0x32 +#define SIRCS_CMD_PAUSE 0x39 + +void send_code(int type, int dev, int cmd) +{ + struct sircs_data sd; + int ret; + int count = 20; // this seems like a good number + + sd.type = type; + sd.cmd = cmd & 0x7f; + sd.dev = dev & 0x1fff; + + ret = sceSircsSend(&sd, count); + if (ret < 0) + { + printf ("sceSircsSend returned %d\n", ret); + } +} + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + sceKernelExitGame(); + + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0); + if(thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} + +int main(void) +{ + SceCtrlData pad; + u32 buttonsold = 0; + int sirc_bits = 20; // # of bits in code, choose from 12, 15 or 20 + + SetupCallbacks(); + pspDebugScreenInit(); + + sceCtrlSetSamplingCycle(0); + sceCtrlSetSamplingMode(PSP_CTRL_MODE_DIGITAL); + + printf ("Sircs Example\n"); + printf ("-------\n"); + printf ("This example can be used with a PS2\n\n"); + printf ("Press CROSS to send PLAY\n"); + printf ("Press SQUARE to send PAUSE\n"); + printf ("Press CIRCLE to send RESET\n"); + + do { + sceCtrlReadBufferPositive(&pad, 1); + + if (pad.Buttons != buttonsold) + { + + if (pad.Buttons & PSP_CTRL_CIRCLE) + { + printf ("Sending SIRCS_CMD_RESET\n"); + send_code(sirc_bits, SIRCS_ADDR_DVD, SIRCS_CMD_RESET); + } + + if (pad.Buttons & PSP_CTRL_CROSS) + { + printf ("Sending SIRCS_CMD_PLAY\n"); + send_code(sirc_bits, SIRCS_ADDR_DVD, SIRCS_CMD_PLAY); + } + + if (pad.Buttons & PSP_CTRL_SQUARE) + { + printf ("Sending SIRCS_CMD_PAUSE\n"); + send_code(sirc_bits, SIRCS_ADDR_DVD, SIRCS_CMD_PAUSE); + } + + buttonsold = pad.Buttons; + } + + sceDisplayWaitVblankStart(); + } while (1); + + return 0; +} diff --git a/src/samples/kernel/cwd/Makefile.sample b/src/samples/kernel/cwd/Makefile.sample new file mode 100644 index 00000000..8034da8a --- /dev/null +++ b/src/samples/kernel/cwd/Makefile.sample @@ -0,0 +1,17 @@ +TARGET = cwd +OBJS = main.o + +INCDIR = +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LIBS = +LDFLAGS = + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Working Directory example + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/kernel/cwd/main.c b/src/samples/kernel/cwd/main.c new file mode 100644 index 00000000..1e28861c --- /dev/null +++ b/src/samples/kernel/cwd/main.c @@ -0,0 +1,105 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Basic sample to demonstrate some fileio functionality. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * Copyright (c) 2005 Jim Paris + * + * $Id: main.c 1175 2005-10-20 15:41:33Z chip $ + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +PSP_MODULE_INFO("CwdTest", 0, 1, 1); + +#define printf pspDebugScreenPrintf + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + sceKernelExitGame(); + + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0); + if(thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} + +void try(const char *dest) +{ + char buf[MAXPATHLEN]; + + printf("%16s --> ", dest); + if(chdir(dest) < 0) { + printf("(chdir error)\n"); + } else { + printf("%s\n", getcwd(buf, MAXPATHLEN) ?: "(getcwd error)"); + } +} + +int main(void) +{ + char buf[MAXPATHLEN]; + pspDebugScreenInit(); + SetupCallbacks(); + + printf("Working Directory Examples\n"); + printf("Initial dir: %s\n\n", getcwd(buf, MAXPATHLEN) ?: "(error)"); + + printf("%16s --> %s\n", "chdir() attempt", "resulting getcwd()"); + printf("%16s --> %s\n", "---------------", "------------------"); + try(""); /* empty string */ + try("hello"); /* nonexistent path */ + try(".."); /* parent dir */ + try("../SAVEDATA"); /* parent dir and subdir */ + try("../.."); /* multiple parents */ + try("."); /* current dir */ + try("./././//PSP"); /* current dirs, extra slashes */ + try("/PSP/./GAME"); /* absolute with no drive */ + try("/"); /* root with no drive */ + try("ms0:/PSP/GAME"); /* absolute with drive */ + try("flash0:/"); /* different drive */ + try("ms0:/PSP/../PSP/"); /* mixed */ + + printf("\nAll done!\n"); + + return 0; +} diff --git a/src/samples/kernel/fileio/Makefile.sample b/src/samples/kernel/fileio/Makefile.sample new file mode 100644 index 00000000..898ba9bc --- /dev/null +++ b/src/samples/kernel/fileio/Makefile.sample @@ -0,0 +1,17 @@ +TARGET = dumper +OBJS = main.o + +INCDIR = +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LIBS = -lpspumd +LDFLAGS = + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = File IO example + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/kernel/fileio/main.c b/src/samples/kernel/fileio/main.c new file mode 100644 index 00000000..545713ad --- /dev/null +++ b/src/samples/kernel/fileio/main.c @@ -0,0 +1,347 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Basic sample to demonstrate some fileio functionality. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: main.c 2389 2008-05-24 17:42:11Z iwn $ + */ +#include +#include +#include +#include +#include + +#include + +PSP_MODULE_INFO("Dumper", 0, 1, 1); + +#define printf pspDebugScreenPrintf + + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + sceKernelExitGame(); + + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0); + if(thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} + +/* Build a path, append a directory slash if requested */ +void build_path(char *output, const char *root, const char *path, int append) +{ + while(*root != 0) + { + *output++ = *root++; + } + + if(*(root-1) != '/') + { + *output++ = '/'; + } + + while(*path != 0) + { + *output++ = *path++; + } + if(append) + *output++ = '/'; + + *output++ = 0; +} + +/* Define a write buffer */ +char write_buffer[128*1024]; + +void write_file(const char *read_loc, const char *write_loc, const char *name) +{ + int fdin; + int fdout; + char readpath[256]; + char writepath[256]; + + build_path(readpath, read_loc, name, 0); + build_path(writepath, write_loc, name, 0); + printf("Writing %s\n", writepath); + + fdin = sceIoOpen(readpath, PSP_O_RDONLY, 0777); + if(fdin >= 0) + { + int bytesRead = 1; + fdout = sceIoOpen(writepath, PSP_O_WRONLY | PSP_O_CREAT | PSP_O_TRUNC, 0777); + if(fdout < 0) + { + printf("Couldn't open %s\n", writepath); + } + + bytesRead = sceIoRead(fdin, write_buffer, sizeof(write_buffer)); + while((bytesRead > 0) && (fdout >= 0)) + { + sceIoWrite(fdout, write_buffer, bytesRead); + bytesRead = sceIoRead(fdin, write_buffer, sizeof(write_buffer)); + } + + if(fdout >= 0) + { + sceIoClose(fdout); + } + + if(fdin >= 0) + { + sceIoClose(fdin); + } + } + else + { + printf("Couldn't open %s\n", readpath); + } +} + +void DumpBootBin(void) +{ + int i; + int fd; + + i = sceUmdCheckMedium(); + if(i == 0) + { + printf("Insert UMD\n"); + i = sceUmdWaitDriveStat(PSP_UMD_PRESENT); + } + + i = sceUmdActivate(1, "disc0:"); + printf("Mounted disc\n"); + + i = sceUmdWaitDriveStat(PSP_UMD_READY); + + /* Open the UMD_DATA.BIN */ + fd = sceIoOpen("disc0:/UMD_DATA.BIN", PSP_O_RDONLY, 0777); + if(fd >= 0) + { + char game_id[11]; + char path[256]; + + sceIoRead(fd, game_id, 10); + sceIoClose(fd); + game_id[10] = 0; + build_path(path, "ms0:/", game_id, 0); + sceIoMkdir(path, 0777); + + printf("Found game %s\n", game_id); + + write_file("disc0:/PSP_GAME/SYSDIR", path, "BOOT.BIN"); + } +} + +/* Dump a filing system */ +void dump_filesystem(const char *root, const char *write_loc) +{ + int dfd; + char next_root[256]; + char next_write[256]; + + sceIoMkdir(write_loc, 0777); + + dfd = sceIoDopen(root); + if(dfd > 0) + { + SceIoDirent dir; + + while(sceIoDread(dfd, &dir) > 0) + { + if(dir.d_stat.st_attr & FIO_SO_IFDIR) + { + if(dir.d_name[0] != '.') + { + build_path(next_write, write_loc, dir.d_name, 0); + build_path(next_root, root, dir.d_name, 1); + dump_filesystem(next_root, next_write); + } + } + else + { + write_file(root, write_loc, dir.d_name); + } + } + sceIoDclose(dfd); + } +} + +/* Dump memory */ +void dump_memory(void) +{ + int fd; + + printf("Dumping 28Megs from 0x8400000\n"); + fd = sceIoOpen("ms0:/MEMORY.BIN", PSP_O_CREAT | PSP_O_TRUNC | PSP_O_WRONLY, 0777); + if(fd >= 0) + { + sceIoWrite(fd, (void *) 0x8400000, 28*1024*1024); + sceIoClose(fd); + } +} + +/* Dumps flash rom in bits */ +void dump_flashrom(int lower) +{ + int fdin; + int fdout; + + fdin = sceIoOpen("lflash:", PSP_O_RDONLY, 0777); + if(fdin > 0) + { + int i; + int bytes_read; + + if(lower) + { + fdout = sceIoOpen("ms0:/flash_lower.bin", PSP_O_WRONLY | PSP_O_CREAT | PSP_O_TRUNC, 0777); + } + else + { + fdout = sceIoOpen("ms0:/flash_upper.bin", PSP_O_WRONLY | PSP_O_CREAT | PSP_O_TRUNC, 0777); + } + + if(fdout > 0) + { + for(i = 0; i < ((16 * 1024 * 1024) / sizeof(write_buffer)); i++) + { + bytes_read = sceIoRead(fdin, write_buffer, sizeof(write_buffer)); + if(lower) + { + sceIoWrite(fdout, write_buffer, bytes_read); + } + } + + if(!lower) + { + for(i = 0; i < ((16 * 1024 * 1024) / sizeof(write_buffer)); i++) + { + bytes_read = sceIoRead(fdin, write_buffer, sizeof(write_buffer)); + sceIoWrite(fdout, write_buffer, bytes_read); + } + } + + sceIoClose(fdout); + } + + sceIoClose(fdin); + } + else + { + printf("Cannot open lflash: device\n"); + sceKernelSleepThread(); + } +} + +void show_menu(void) +{ + printf("PSP Dumping Tool - TyRaNiD 2k5. (www.pspdev.org)\n"); + printf("Press triangle to dump umd boot.bin\n"); + printf("Press circle to dump flash0\n"); + printf("Press square to dump flash1\n"); + printf("Press cross to dump memory\n"); + printf("Press L trigger to dump lower 16Mb of flash rom\n"); + printf("Press R trigger to dump lower 16Mb of flash rom\n"); +} + +int main(void) +{ + SceCtrlData pad_data; + + pspDebugScreenSetBackColor(0xFFFFFFFF); + pspDebugScreenSetTextColor(0); + pspDebugScreenInit(); + SetupCallbacks(); + sceCtrlSetSamplingCycle(0); + sceCtrlSetSamplingMode(1); + show_menu(); + + for(;;) + { + sceCtrlReadBufferPositive(&pad_data, 1); + if(pad_data.Buttons & PSP_CTRL_TRIANGLE) + { + DumpBootBin(); + pspDebugScreenClear(); + printf("!!!!!!!! DONE !!!!!!!!!!\n"); + show_menu(); + } + + if(pad_data.Buttons & PSP_CTRL_CIRCLE) + { + dump_filesystem("flash0:/", "ms0:/flash0"); + pspDebugScreenClear(); + printf("!!!!!!!! DONE !!!!!!!!!!\n"); + show_menu(); + } + + if(pad_data.Buttons & PSP_CTRL_SQUARE) + { + dump_filesystem("flash1:/", "ms0:/flash1"); + pspDebugScreenClear(); + printf("!!!!!!!! DONE !!!!!!!!!!\n"); + show_menu(); + } + + if(pad_data.Buttons & PSP_CTRL_CROSS) + { + dump_memory(); + pspDebugScreenClear(); + printf("!!!!!!!! DONE !!!!!!!!!!\n"); + show_menu(); + } + + if(pad_data.Buttons & PSP_CTRL_LTRIGGER) + { + dump_flashrom(1); + pspDebugScreenClear(); + printf("!!!!!!!! DONE !!!!!!!!!!\n"); + show_menu(); + } + + if(pad_data.Buttons & PSP_CTRL_RTRIGGER) + { + dump_flashrom(0); + pspDebugScreenClear(); + printf("!!!!!!!! DONE !!!!!!!!!!\n"); + show_menu(); + } + + sceDisplayWaitVblankStart(); + } + + return 0; +} diff --git a/src/samples/kernel/idstorage/Makefile.sample b/src/samples/kernel/idstorage/Makefile.sample new file mode 100644 index 00000000..e9fbfa64 --- /dev/null +++ b/src/samples/kernel/idstorage/Makefile.sample @@ -0,0 +1,14 @@ +TARGET = idstorage +OBJS = main.o + +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBS = + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Idstorage Sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/kernel/idstorage/main.c b/src/samples/kernel/idstorage/main.c new file mode 100644 index 00000000..7de08e2a --- /dev/null +++ b/src/samples/kernel/idstorage/main.c @@ -0,0 +1,63 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - idstorage sample, demonstrates the use of sceIdStorageLookup. + * + * Copyright (c) 2006 Harley G. + * + */ +#include +#include +#include + +/* Start in kernel mode */ +PSP_MODULE_INFO("idstorage sample", 0x1000, 1, 0); +PSP_MAIN_THREAD_ATTR(0); +PSP_MAIN_THREAD_STACK_SIZE_KB(32); + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) { + sceKernelExitGame(); + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) { + int cbid; + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + sceKernelSleepThreadCB(); + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) { + int thid = 0; + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, THREAD_ATTR_USER, 0); + if(thid >= 0) sceKernelStartThread(thid, 0, 0); + return thid; +} + +int main(void) { + unsigned char buffer[0x1e]; /* Buffer */ + + pspDebugScreenInit(); + SetupCallbacks(); + + pspDebugScreenPrintf("Idstorage sample by harleyg\nThanks to Dark_AleX and Mathieulh\n\n"); + /* Read idstorage key 0x050 (serial) */ + sceIdStorageLookup(0x050, 0x0, buffer, 0x1e); /* key, offset, buffer, length */ + + /* Print the serial */ + pspDebugScreenPrintf("Serial: %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c", + buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], + buffer[6], buffer[7], buffer[8], buffer[9], buffer[10], buffer[11], + buffer[12], buffer[13], buffer[14], buffer[15], buffer[16], buffer[17], + buffer[18], buffer[19], buffer[20], buffer[21], buffer[22], buffer[23], + buffer[24], buffer[25], buffer[26], buffer[27], buffer[28], buffer[29]); + + sceKernelSleepThread(); + return 0; +} diff --git a/src/samples/kernel/kdumper/Makefile.sample b/src/samples/kernel/kdumper/Makefile.sample new file mode 100644 index 00000000..447bc4f2 --- /dev/null +++ b/src/samples/kernel/kdumper/Makefile.sample @@ -0,0 +1,16 @@ +TARGET = kdumper +OBJS = main.o + +INCDIR = +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Kernel Dumper Sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/kernel/kdumper/main.c b/src/samples/kernel/kdumper/main.c new file mode 100644 index 00000000..8447ce9f --- /dev/null +++ b/src/samples/kernel/kdumper/main.c @@ -0,0 +1,214 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - KDumper sample, demonstrates use of kernel mode. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: main.c 1095 2005-09-27 21:02:16Z jim $ + */ +#include +#include +#include +#include + +/* Define the module info section, note the 0x1000 flag to enable start in kernel mode */ +PSP_MODULE_INFO("SDKTEST", 0x1000, 1, 1); + +/* Define the thread attribute as 0 so that the main thread does not get converted to user mode */ +PSP_MAIN_THREAD_ATTR(0); + +/* Define printf, just to make typing easier */ +#define printf pspDebugScreenPrintf + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + sceKernelExitGame(); + + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + + /* Note the use of THREAD_ATTR_USER to ensure the callback thread is in user mode */ + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, THREAD_ATTR_USER, 0); + if(thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} + +/* Dump the cop0 regs, good proof we are in kernel mode */ +void dump_cop0_regs(void) +{ + u32 regs[32]; + int i; + + asm __volatile__ ( + "mfc0 $3, $0\n" + "sw $3, 0(%0)\n" + "addi %0, %0, 4\n" + "mfc0 $3, $1\n" + "sw $3, 0(%0)\n" + "addi %0, %0, 4\n" + "mfc0 $3, $2\n" + "sw $3, 0(%0)\n" + "addi %0, %0, 4\n" + "mfc0 $3, $3\n" + "sw $3, 0(%0)\n" + "addi %0, %0, 4\n" + "mfc0 $3, $4\n" + "sw $3, 0(%0)\n" + "addi %0, %0, 4\n" + "mfc0 $3, $5\n" + "sw $3, 0(%0)\n" + "addi %0, %0, 4\n" + "mfc0 $3, $6\n" + "sw $3, 0(%0)\n" + "addi %0, %0, 4\n" + "mfc0 $3, $7\n" + "sw $3, 0(%0)\n" + "addi %0, %0, 4\n" + "mfc0 $3, $8\n" + "sw $3, 0(%0)\n" + "addi %0, %0, 4\n" + "mfc0 $3, $9\n" + "sw $3, 0(%0)\n" + "addi %0, %0, 4\n" + "mfc0 $3, $10\n" + "sw $3, 0(%0)\n" + "addi %0, %0, 4\n" + "mfc0 $3, $11\n" + "sw $3, 0(%0)\n" + "addi %0, %0, 4\n" + "mfc0 $3, $12\n" + "sw $3, 0(%0)\n" + "addi %0, %0, 4\n" + "mfc0 $3, $13\n" + "sw $3, 0(%0)\n" + "addi %0, %0, 4\n" + "mfc0 $3, $14\n" + "sw $3, 0(%0)\n" + "addi %0, %0, 4\n" + "mfc0 $3, $15\n" + "sw $3, 0(%0)\n" + "addi %0, %0, 4\n" + "mfc0 $3, $16\n" + "sw $3, 0(%0)\n" + "addi %0, %0, 4\n" + "mfc0 $3, $17\n" + "sw $3, 0(%0)\n" + "addi %0, %0, 4\n" + "mfc0 $3, $18\n" + "sw $3, 0(%0)\n" + "addi %0, %0, 4\n" + "mfc0 $3, $19\n" + "sw $3, 0(%0)\n" + "addi %0, %0, 4\n" + "mfc0 $3, $20\n" + "sw $3, 0(%0)\n" + "addi %0, %0, 4\n" + "mfc0 $3, $21\n" + "sw $3, 0(%0)\n" + "addi %0, %0, 4\n" + "mfc0 $3, $22\n" + "sw $3, 0(%0)\n" + "addi %0, %0, 4\n" + "mfc0 $3, $23\n" + "sw $3, 0(%0)\n" + "addi %0, %0, 4\n" + "mfc0 $3, $24\n" + "sw $3, 0(%0)\n" + "addi %0, %0, 4\n" + "mfc0 $3, $25\n" + "sw $3, 0(%0)\n" + "addi %0, %0, 4\n" + "mfc0 $3, $26\n" + "sw $3, 0(%0)\n" + "addi %0, %0, 4\n" + "mfc0 $3, $27\n" + "sw $3, 0(%0)\n" + "addi %0, %0, 4\n" + "mfc0 $3, $28\n" + "sw $3, 0(%0)\n" + "addi %0, %0, 4\n" + "mfc0 $3, $29\n" + "sw $3, 0(%0)\n" + "addi %0, %0, 4\n" + "mfc0 $3, $30\n" + "sw $3, 0(%0)\n" + "addi %0, %0, 4\n" + "mfc0 $3, $31\n" + "sw $3, 0(%0)\n" + "addi %0, %0, 4\n" + : + : "r"(®s[0]) + ); + + printf("Cop0 regs\n"); + for(i = 0; i < 32; i+=4) + { + printf("$%02d: %08X, $%02d: %08X, $%02d: %08X $%02d: %08X\n", + i, regs[i], i+1, regs[i+1], i+2, regs[i+2], i+3, regs[i+3]); + } +} + +char g_data[0x400000] __attribute__((aligned(64))); + +/* Well what would you expect ? :) */ +void dump_memregion(const char* file, void *addr, int len) +{ + int fd; + + fd = sceIoOpen(file, PSP_O_CREAT | PSP_O_TRUNC | PSP_O_WRONLY, 0777); + if(fd >= 0) + { + printf("Writing %s\n", file); + memcpy(g_data, addr, len); + sceIoWrite(fd, g_data, len); + sceIoClose(fd); + } +} + +int main(void) +{ + pspDebugScreenInit(); + SetupCallbacks(); + + printf("Kernel mem dumper. TyRaNiD 2k5.\n"); + printf("Props to nem, mrbrown, adresd et al\n\n"); + dump_cop0_regs(); + printf("Dumping Boot Mem 0xBFC00000 -> 0xBFD00000\n"); + dump_memregion("ms0:/boot.bin", (void*) 0xBFC00000, 0x100000); + printf("Dumping Kernel Mem 0x88000000 -> 0x883FFFFF\n"); + dump_memregion("ms0:/kmem.bin", (void*) 0x88000000, 0x400000); + printf("Done\n"); + + /* Exit the thread, this will allow the exit callback to work */ + sceKernelExitDeleteThread(0); + + return 0; +} diff --git a/src/samples/kernel/loadmodule/Makefile.sample b/src/samples/kernel/loadmodule/Makefile.sample new file mode 100644 index 00000000..87a5b2f0 --- /dev/null +++ b/src/samples/kernel/loadmodule/Makefile.sample @@ -0,0 +1,16 @@ +TARGET = loadmodule +OBJS = main.o + +INCDIR = +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Loadmodule PSPSDK Sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/kernel/loadmodule/main.c b/src/samples/kernel/loadmodule/main.c new file mode 100644 index 00000000..336f6bb3 --- /dev/null +++ b/src/samples/kernel/loadmodule/main.c @@ -0,0 +1,152 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - sceKernelLoadModule() sample. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: main.c 1095 2005-09-27 21:02:16Z jim $ + */ + +/* WARNING: This sample currently crashes, due to a bug in the PSP's kernel. We're working on a fix. */ + +#include +#include +#include +#include + +/* Define the module info section, note the 0x1000 flag to enable start in kernel mode */ +PSP_MODULE_INFO("SDKTEST", 0x1000, 1, 1); + +PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER); + +/* Define printf, just to make typing easier */ +#define printf pspDebugScreenPrintf + +/* List of modules to load - type is 0 if the module belongs to the kernel, 1 if it's a user module. */ +struct module_list { + int type; + const char *path; +} module_list[] = { + { 0, "flash0:/kd/ifhandle.prx" }, + { 1, "flash0:/kd/pspnet.prx" } +}; +const int module_count = sizeof(module_list) / sizeof(module_list[0]); + +SceUID load_module(const char *path, int flags, int type); + + +void MyExceptionHandler(PspDebugRegBlock *regs) +{ + printf("\n\n"); + pspDebugDumpException(regs); +} + +/* This function is called by the startup code before main() is called. Since + it runs in kernel mode we can access kernel-only features. */ +__attribute__((constructor)) +void KernelSetup(void) +{ + pspDebugScreenInit(); + pspDebugInstallKprintfHandler(NULL); + pspDebugInstallErrorHandler(MyExceptionHandler); + + /* Very important - patch the module manager so that we can load modules from user mode. */ + pspSdkInstallNoDeviceCheckPatch(); +} + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + sceKernelExitGame(); + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + + /* Note the use of THREAD_ATTR_USER to ensure the callback thread is in user mode */ + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, PSP_THREAD_ATTR_USER, NULL); + if(thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} + +SceUID load_module(const char *path, int flags, int type) +{ + SceKernelLMOption option; + SceUID mpid; + + /* If the type is 0, then load the module in the kernel partition, otherwise load it + in the user partition. */ + if (type == 0) { + mpid = 1; + } else { + mpid = 2; + } + + memset(&option, 0, sizeof(option)); + option.size = sizeof(option); + option.mpidtext = mpid; + option.mpiddata = mpid; + option.position = 0; + option.access = 1; + + return sceKernelLoadModule(path, flags, &option); +} + +int main(void) +{ + int i; + + SetupCallbacks(); + + printf("Loadmodule sample program.\n\n"); + + /* Try loading and starting the network modules. */ + for (i = 0; i < module_count; i++) { + SceUID modid; + int res, status; + + modid = load_module(module_list[i].path, 0, module_list[i].type); + if (modid < 0) { + printf("sceKernelLoadModule('%s') failed with %x\n", module_list[i].path, modid); + break; + } + + res = sceKernelStartModule(modid, 0, NULL, &status, NULL); + if (res < 0) { + printf("sceKernelStartModule('%s') failed with %x\n", module_list[i].path, res); + break; + } + + printf("Load and start '%s' - Success\n", module_list[i].path); + } + + printf("\nAll done!\n"); + + sceKernelSleepThread(); + return 0; +} diff --git a/src/samples/kernel/messagebox/Makefile.sample b/src/samples/kernel/messagebox/Makefile.sample new file mode 100644 index 00000000..b97fbece --- /dev/null +++ b/src/samples/kernel/messagebox/Makefile.sample @@ -0,0 +1,16 @@ +TARGET = messagebox +OBJS = main.o + +INCDIR = +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = messagebox sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/kernel/messagebox/main.c b/src/samples/kernel/messagebox/main.c new file mode 100644 index 00000000..e9b63dbe --- /dev/null +++ b/src/samples/kernel/messagebox/main.c @@ -0,0 +1,209 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Demonstrate use of kernel messageboxes. + * + * Copyright (c) 2005 Marcus Comstedt + * + * $Id: main.c 2166 2007-02-04 10:52:49Z tyranid $ + */ +#include +#include +#include +#include +#include + +/* Define the module info section */ +PSP_MODULE_INFO("messagebox", 0, 1, 1); + +/* Define the main thread's attribute value (optional) */ +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU); + +/* Define printf, just to make typing easier */ +#define printf pspDebugScreenPrintf + + +/* The messagebox */ +static SceUID myMessagebox; + +/* Structure for the messages */ +typedef struct _MyMessage { + SceKernelMsgPacket header; /* For internal use by the kernel */ + char text[8]; /* Anything we would like to have */ +} MyMessage; + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + sceKernelExitGame(); + + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0); + if(thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} + +static int SubThread(SceSize args, void *argp) +{ + int error, numWaitThreads; + SceKernelMbxInfo info; + + /* For simplicily, we statically allocate some messages */ + static MyMessage one = { {0}, "One" }; + static MyMessage two = { {0}, "Two" }; + static MyMessage three = { {0}, "Three" }; + + sceKernelDelayThread(100000); + printf("SUB: started\n"); + + sceKernelDelayThread(1000000); + + /* Send a message */ + printf("SUB: Posting 1\n"); + sceKernelSendMbx(myMessagebox, &one.header); + + /* Send another message after some delay, + to demonstrate the timeout feature */ + sceKernelDelayThread(1000000); + printf("SUB: Posting 2\n"); + sceKernelSendMbx(myMessagebox, &two.header); + + /* Again, send another message after some delay, + this time to demonstrate the polling feature */ + sceKernelDelayThread(1000000); + printf("SUB: Posting 3\n"); + sceKernelSendMbx(myMessagebox, &three.header); + + /* Wait for the main task to start blocking again, + and then check the messagebox status */ + sceKernelDelayThread(1000000); + printf("SUB: Checking messagebox status\n"); + info.size = sizeof(info); + error = sceKernelReferMbxStatus(myMessagebox, &info); + if(error < 0) + printf("SUB: ERROR %08x\n", error); + else + printf("SUB: status ok, name=\"%s\", attr=%d, numWaitThreads=%d, " + "numMessages=%d, firstMessage=%p\n", info.name, info.attr, + info.numWaitThreads, info.numMessages, info.firstMessage); + + /* Finally, cancel the main tasks receive operation */ + printf("SUB: Cancelling receive\n"); + error = sceKernelCancelReceiveMbx(myMessagebox, &numWaitThreads); + sceKernelDelayThread(100000); + if(error < 0) + printf("SUB: ERROR %08x\n", error); + else + printf("SUB: cancellation ok, %d threads were waiting\n", numWaitThreads); + + printf("SUB: Exiting\n"); + return 0; +} + +int main(int argc, char *argv[]) +{ + SceUID thid; + int error; + void *data; + + pspDebugScreenInit(); + if (argc > 0) { + printf("Bootpath: %s\n", argv[0]); + } + SetupCallbacks(); + + /* Create a messagebox */ + myMessagebox = sceKernelCreateMbx("pspSDK-testMBX", 0, 0); + printf("MAIN: created messagebox %08x\n", myMessagebox); + + /* Create a task that will post in the messagebox */ + thid = sceKernelCreateThread("subthread", SubThread, 17, 8192, THREAD_ATTR_USER, 0); + sceKernelStartThread(thid, 0, NULL); + printf("MAIN: started task %08x\n", thid); + + /* Wait for a message */ + printf("MAIN: waiting for message\n"); + error = sceKernelReceiveMbx(myMessagebox, &data, NULL); + if(error < 0) + printf("MAIN: ERROR %08x\n", error); + else + printf("MAIN: got message: \"%s\"\n", ((MyMessage *)data)->text); + + /* Wait for a message with timeout */ + printf("MAIN: waiting with timeout (will fail the first couple of times)\n"); + for(;;) { + SceUInt timeout = 300000; /* microseconds */ + error = sceKernelReceiveMbx(myMessagebox, &data, &timeout); + if(error < 0) + printf("MAIN: ERROR %08x\n", error); + else { + printf("MAIN: got message: \"%s\" (timeout remaining %d us)\n", + ((MyMessage *)data)->text, timeout); + break; + } + } + + /* Poll for messages */ + printf("MAIN: polling for message (non-blocking)\n"); + for(;;) { + error = sceKernelPollMbx(myMessagebox, &data); + if(error < 0) { + printf("MAIN: ERROR %08x\n", error); + /* Sleep for a little while to give the message + a chance to arrive */ + sceKernelDelayThread(300000); + } else { + printf("MAIN: got message: \"%s\"\n", ((MyMessage *)data)->text); + break; + } + } + + /* This call to sceKernelReceiveMbx() will be interrupted + by the sub task without a message being sent */ + printf("MAIN: waiting for a message that will not arrive\n"); + error = sceKernelReceiveMbx(myMessagebox, &data, NULL); + if(error < 0) + printf("MAIN: ERROR %08x\n", error); + else + printf("MAIN: got message: \"%s\"\n", ((MyMessage *)data)->text); + + /* Prepare to shutdown */ + printf("MAIN: waiting for sub task to exit\n"); + sceKernelWaitThreadEnd(thid, NULL); + printf("MAIN: sub task exited, deleting messagebox\n"); + error = sceKernelDeleteMbx(myMessagebox); + if(error < 0) + printf("MAIN: ERROR %08x\n", error); + else + printf("MAIN: all done\n"); + + sceKernelSleepThread(); + + return 0; +} diff --git a/src/samples/kernel/regenum/Makefile.sample b/src/samples/kernel/regenum/Makefile.sample new file mode 100644 index 00000000..594f1e67 --- /dev/null +++ b/src/samples/kernel/regenum/Makefile.sample @@ -0,0 +1,17 @@ +TARGET = regsh +OBJS = main.o + +INCDIR = +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = +LIBS = -lpspreg + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Registry Shell + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/kernel/regenum/main.c b/src/samples/kernel/regenum/main.c new file mode 100644 index 00000000..850908a6 --- /dev/null +++ b/src/samples/kernel/regenum/main.c @@ -0,0 +1,322 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Simple shell to look at the registry + * + * Copyright (c) 2006 James F + * + * $Id$ + * $HeadURL$ + */ +#include +#include +#include +#include +#include +#include +#include +#include + +/* Define the module info section */ +PSP_MODULE_INFO("regsh", 0, 1, 1); + +/* Define the main thread's attribute value (optional) */ +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER); + +#define ROOT_DIR "/root" + +/* Cant seem to work out how to enumerate the roots */ +const char *root_dirs[] = { + "SYSPROFILE", + "DATA", + "SYSTEM", + "CONFIG", + "REGISTRY" +}; + +void print_key_root(void) +{ + int i; + for(i = 0; i < (sizeof(root_dirs)/sizeof(char *)); i++) + { + printf("DIR - %-27s\n", root_dirs[i]); + } +} + +/* Print info about a specific key */ +void print_key_info(REGHANDLE hd, const char *name) +{ + unsigned int type; + SceSize size; + unsigned char data[1024]; + REGHANDLE hk; + + if(!sceRegGetKeyInfo(hd, name, &hk, &type, &size)) + { + if(type == REG_TYPE_DIR) + { + printf("DIR - %-27s\n", name); + } + else + { + if(!sceRegGetKeyValue(hd, hk, data, size)) + { + switch(type) + { + case REG_TYPE_INT: printf("INT - %-27s - %4d : %d\n", name, size, *((int*) data)); + break; + case REG_TYPE_STR: printf("STR - %-27s - %4d : %s\n", name, size, (char *)data); + break; + case REG_TYPE_BIN: { + int i; + printf("BIN - %-27s - %4d : ", name, size); + for(i = 0; i < size-1; i++) + { + printf("%02X-", data[i]); + } + printf("%02X\n", data[i]); + } + break; + }; + } + } + } + else + { + printf("Could not get info for key %s\n", name); + } +} + +/* Print out a directory key */ +void print_key(const char *dir) +{ + struct RegParam reg; + REGHANDLE h; + + if(strcmp(dir, ROOT_DIR) == 0) + { + print_key_root(); + return; + } + + dir = strchr(&dir[1], '/'); + if(dir == NULL) + { + return; + } + + memset(®, 0, sizeof(reg)); + reg.regtype = 1; + reg.namelen = strlen("/system"); + reg.unk2 = 1; + reg.unk3 = 1; + strcpy(reg.name, "/system"); + if(sceRegOpenRegistry(®, 2, &h) == 0) + { + REGHANDLE hd; + if(!sceRegOpenCategory(h, dir, 2, &hd)) + { + int num; + + if(!sceRegGetKeysNum(hd, &num)) + { + char *data; + printf("Key Entries: %d\n", num); + data = malloc(num*27); + if(data) + { + if(!sceRegGetKeys(hd, data, num)) + { + int i; + for(i = 0; i < num; i++) + { + print_key_info(hd, &data[i*27]); + } + free(data); + } + else + { + printf("Could not get key values\n"); + } + } + else + { + printf("Could not allocate key data\n"); + } + } + else + { + printf("Could not get number of keys\n"); + } + sceRegCloseCategory(hd); + } + else + { + printf("Could not open directory\n"); + } + + sceRegCloseRegistry(h); + } + else + { + printf("Could not open registry\n"); + } +} + +int check_dir(const char *dir) +{ + struct RegParam reg; + REGHANDLE h; + int ret = 0; + + dir = strchr(&dir[1], '/'); + if(dir == NULL) + { + return 0; + } + + memset(®, 0, sizeof(reg)); + reg.regtype = 1; + reg.namelen = strlen("/system"); + reg.unk2 = 1; + reg.unk3 = 1; + strcpy(reg.name, "/system"); + if(sceRegOpenRegistry(®, 2, &h) == 0) + { + REGHANDLE hd; + if(!sceRegOpenCategory(h, dir, 2, &hd)) + { + sceRegCloseCategory(hd); + ret = 1; + } + sceRegCloseRegistry(h); + } + else + { + printf("ERROR: Could not open registry\n"); + } + + return ret; +} + +int exitCallback(int arg1, int arg2, void *common) +{ + sceKernelExitGame(); + return 0; +} + +int callbackThread(SceSize args, void *argp) +{ + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", exitCallback, NULL); + sceKernelRegisterExitCallback(cbid); + + sceKernelSleepThreadCB(); + + return 0; +} + +int setupCallbacks(void) +{ + int thid = 0; + + thid = sceKernelCreateThread("update_thread", callbackThread, 0x11, 0xFA0, 0, 0); + if(thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} + +void up_dir(char *currdir) +{ + char *lastsl; + + lastsl = strrchr(currdir, '/'); + + if((lastsl) && (&lastsl[0] != currdir)) + { + *lastsl = 0; + } +} + +void change_dir(char *currdir, const char *dir) +{ + char tempdir[1024]; + + if(dir == NULL) + { + printf("ERROR: Must supply a directory argument\n"); + return; + } + + if(strcmp(dir, "..") == 0) + { + up_dir(currdir); + return; + } + + (void) snprintf(tempdir, sizeof(tempdir), "%s/%s", currdir, dir); + if(check_dir(tempdir)) + { + strcpy(currdir, tempdir); + } + else + { + printf("ERROR: Invalid directory '%s'\n", tempdir); + } +} + +int main(int argc, char *argv[]) +{ + char buf[1024]; + char currdir[1024]; + + setupCallbacks(); + pspDebugScreenInit(); + pspDebugScreenPrintf("Registry Shell (c) 2k6 TyRaNiD\n"); + pspDebugScreenPrintf("You must access it through a stdin app such as psplink\n"); + + strcpy(currdir, ROOT_DIR); + + printf("\n"); + printf("%s> ", currdir); + while(fgets(buf, sizeof(buf), stdin)) + { + char *cmd; + char *arg; + + cmd = strtok(buf, " \t\n\r"); + arg = strtok(NULL, "\t\n\r"); + + if(cmd) + { + if(strcasecmp(cmd, "ls") == 0) + { + print_key(currdir); + } + else if(strcasecmp(cmd, "cd") == 0) + { + change_dir(currdir, arg); + } + else if(strcasecmp(cmd, "exit") == 0) + { + break; + } + else + { + printf("ERROR: Unknown command '%s'\n", cmd); + } + } + + printf("%s> ", currdir); + } + + sceKernelExitGame(); + + return 0; +} diff --git a/src/samples/kernel/registry/Makefile.sample b/src/samples/kernel/registry/Makefile.sample new file mode 100644 index 00000000..9b4cf337 --- /dev/null +++ b/src/samples/kernel/registry/Makefile.sample @@ -0,0 +1,17 @@ +TARGET = regsample +OBJS = main.o + +INCDIR = +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = +LIBS = -lpspreg + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Registry Sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/kernel/registry/main.c b/src/samples/kernel/registry/main.c new file mode 100644 index 00000000..c1715c53 --- /dev/null +++ b/src/samples/kernel/registry/main.c @@ -0,0 +1,168 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Sample to show registry usage + * + * Copyright (c) 2006 James F + * + * $Id: main.c 2096 2006-12-10 14:19:25Z tyranid $ + * $HeadURL: svn://svn.ps2dev.org/psp/trunk/pspsdk/src/samples/kernel/registry/main.c $ + */ +#include +#include +#include +#include +#include +#include +#include + +#define printf pspDebugScreenPrintf + +/* Define the module info section */ +PSP_MODULE_INFO("regsample", 0, 1, 1); + +/* Define the main thread's attribute value (optional) */ +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER); + +int get_registry_value(const char *dir, const char *name, unsigned int *val) +{ + int ret = 0; + struct RegParam reg; + REGHANDLE h; + + memset(®, 0, sizeof(reg)); + reg.regtype = 1; + reg.namelen = strlen("/system"); + reg.unk2 = 1; + reg.unk3 = 1; + strcpy(reg.name, "/system"); + if(sceRegOpenRegistry(®, 2, &h) == 0) + { + REGHANDLE hd; + if(!sceRegOpenCategory(h, dir, 2, &hd)) + { + REGHANDLE hk; + unsigned int type, size; + + if(!sceRegGetKeyInfo(hd, name, &hk, &type, &size)) + { + if(!sceRegGetKeyValue(hd, hk, val, 4)) + { + ret = 1; + sceRegFlushCategory(hd); + } + } + sceRegCloseCategory(hd); + } + sceRegFlushRegistry(h); + sceRegCloseRegistry(h); + } + + return ret; +} + +int set_registry_value(const char *dir, const char *name, unsigned int val) +{ + int ret = 0; + struct RegParam reg; + REGHANDLE h; + + memset(®, 0, sizeof(reg)); + reg.regtype = 1; + reg.namelen = strlen("/system"); + reg.unk2 = 1; + reg.unk3 = 1; + strcpy(reg.name, "/system"); + if(sceRegOpenRegistry(®, 2, &h) == 0) + { + REGHANDLE hd; + if(!sceRegOpenCategory(h, dir, 2, &hd)) + { + if(!sceRegSetKeyValue(hd, name, &val, 4)) + { + printf("Set registry value\n"); + ret = 1; + sceRegFlushCategory(hd); + } + sceRegCloseCategory(hd); + } + sceRegFlushRegistry(h); + sceRegCloseRegistry(h); + } + + return ret; +} + +int main(int argc, char *argv[]) +{ + unsigned int vol; + unsigned int but; + unsigned int lang; + + pspDebugScreenInit(); + printf("Simple Registry Sample (c) 2k6 TyRaNiD\n"); + if(get_registry_value("/CONFIG/SYSTEM/SOUND", "main_volume", &vol)) + { + printf("Main Volume: %d\n", vol); + } + if(get_registry_value("/CONFIG/SYSTEM/XMB", "language", &lang)) + { + printf("Language : %d\n", lang); + } + if(get_registry_value("/CONFIG/SYSTEM/XMB", "button_assign", &but)) + { + if(but == 0) + { + printf("Jap button assignment (Circle is enter)\n"); + } + else + { + printf("NA/EU button assignment (Cross is enter)\n"); + } + } + else + { + printf("Could not get button_assign (v1.0?). Exiting in 5 seconds\n"); + sceKernelDelayThread(5000000); + sceKernelExitGame(); + } + + printf("* To swap buttons press Circle *\n"); + printf("* To exit press start *\n"); + while(1) + { + SceCtrlData pad; + sceCtrlPeekBufferPositive(&pad, 1); + if(pad.Buttons & PSP_CTRL_START) + { + sceKernelExitGame(); + } + if(pad.Buttons & PSP_CTRL_CIRCLE) + { + but ^= 1; + if(set_registry_value("/CONFIG/SYSTEM/XMB", "button_assign", but)) + { + if(but) + { + printf("Set to NA/EU mode\n"); + } + else + { + printf("Set to Jap mode\n"); + } + } + else + { + printf("Error setting button assignment\n"); + } + printf("Exiting in 5 seconds\n"); + sceKernelDelayThread(5000000); + sceKernelExitGame(); + } + sceDisplayWaitVblankStart(); + } + + return 0; +} diff --git a/src/samples/kernel/sysevent/Makefile.sample b/src/samples/kernel/sysevent/Makefile.sample new file mode 100644 index 00000000..6bd2a415 --- /dev/null +++ b/src/samples/kernel/sysevent/Makefile.sample @@ -0,0 +1,16 @@ +TARGET = sysevent +OBJS = main.o + +INCDIR = +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = SysEvent example + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/kernel/sysevent/main.c b/src/samples/kernel/sysevent/main.c new file mode 100644 index 00000000..90274653 --- /dev/null +++ b/src/samples/kernel/sysevent/main.c @@ -0,0 +1,70 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Basic SysEvent handler example + * + * Copyright (c) 2007 Iaroslav Gaponenko + * + */ +#include +#include +#include +#define printf pspDebugScreenPrintf + +/* Define the module info section */ +PSP_MODULE_INFO("template", 0x1000, 1, 1); + +/* Define the main thread's attribute value (optional) */ +PSP_MAIN_THREAD_ATTR(0); + +//This is the handler for the event. +int my_handler(int ev_id, char* ev_name, void* param, int* result){ + //we won't do anything special, just print the event number and name. + pspDebugScreenPrintf("Event number 0x%x (%s)\n", ev_id, ev_name); + + //return 0 if the event should not be stopped (it has to be configured as breakable before in order to do so: set break_nonzero to 1. + return 0; +} + +int main(int argc, char *argv[]) +{ + int ret; + + //This is the initialisation part for the event handler. + PspSysEventHandler events; + //structure size. mandatory 0x40. + events.size = 0x40; + //name which can be used for debugging purposes. + events.name = "MyEventGrabber"; + //mask + events.type_mask = 0x0000000F; + //pointer to the handler function. + events.handler = my_handler; + + pspDebugScreenInit(); + pspDebugScreenPrintf("Loaded app...\n"); + + //register the system event handler. + ret = sceKernelRegisterSysEventHandler(&events); + pspDebugScreenPrintf("Registered handler. Return: %i\n", ret); + sceKernelDelayThreadCB(1000000); + + //Dispatch a few test events to see if it works. + + ret = sceKernelSysEventDispatch(0x0000000F, 0x123, "pspsdk", NULL, NULL, 0, NULL); + pspDebugScreenPrintf("Sending event 1. Return: %i\n", ret); + sceKernelDelayThreadCB(1000000); + ret = sceKernelSysEventDispatch(0x0000000F, 0x456, "rules", NULL, NULL, 0, NULL); + pspDebugScreenPrintf("Sending event 2. Return: %i\n", ret); + sceKernelDelayThreadCB(1000000); + ret = sceKernelSysEventDispatch(0x0000000F, 0x789, "the world", NULL, NULL, 0, NULL); + pspDebugScreenPrintf("Sending event 3. Return: %i\n", ret); + + //wait till the end of time. + while(1){ + sceKernelDelayThreadCB(1000000); + } + return 0; +} diff --git a/src/samples/kernel/systimer/Makefile.sample b/src/samples/kernel/systimer/Makefile.sample new file mode 100644 index 00000000..7575de95 --- /dev/null +++ b/src/samples/kernel/systimer/Makefile.sample @@ -0,0 +1,16 @@ +TARGET = systimer +OBJS = main.o + +INCDIR = +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = SysTimer example + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/kernel/systimer/main.c b/src/samples/kernel/systimer/main.c new file mode 100644 index 00000000..8173ffd3 --- /dev/null +++ b/src/samples/kernel/systimer/main.c @@ -0,0 +1,58 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Simple Systimer example + * + * Copyright (c) 2007 Iaroslav Gaponenko + * + * $Id: main.c 2149 2007-01-25 20:46:21Z tyranid $ + * $HeadURL: svn://svn.ps2dev.org/psp/trunk/pspsdk/src/samples/kernel/systimer/main.c $ + */ +#include +#include +#include +#include +#include "pspsystimer.h" + +#define printf pspDebugScreenPrintf + +/* Define the module info section */ +PSP_MODULE_INFO("systimer", 0x1000, 1, 1); + +/* Define the main thread's attribute value (optional) */ +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_VFPU); + +SceSysTimerId timer; +int tic = 0; + +int my_tick_handler(void){ + static int div; + div++; + //arrange to get more or less seconds... + if(div > 12){ + div = 0; + if(tic){ + pspDebugScreenPrintf("Tac!\n"); + }else{ + pspDebugScreenPrintf("Tic!\n"); + } + tic = ~tic; + } + return -1; +} + +int main(int argc, char *argv[]) { + + pspDebugScreenInit(); + pspDebugScreenPrintf("SysTimer sample by Adrahil.\n"); + + timer = sceSTimerAlloc(); + sceSTimerStartCount(timer); + sceSTimerSetHandler(timer, 4194303, my_tick_handler, 0); + + sceKernelSleepThreadCB(); + return 0; + +} diff --git a/src/samples/kernel/threadstatus/Makefile.sample b/src/samples/kernel/threadstatus/Makefile.sample new file mode 100644 index 00000000..833420f4 --- /dev/null +++ b/src/samples/kernel/threadstatus/Makefile.sample @@ -0,0 +1,16 @@ +TARGET = threadstatus +OBJS = main.o + +INCDIR = +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = threadstatus sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/kernel/threadstatus/main.c b/src/samples/kernel/threadstatus/main.c new file mode 100644 index 00000000..b3fbb9a3 --- /dev/null +++ b/src/samples/kernel/threadstatus/main.c @@ -0,0 +1,104 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Display information about active program threads. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: main.c 705 2005-07-20 18:09:56Z tyranid $ + */ +#include +#include +#include +#include + +/* Define the module info section */ +PSP_MODULE_INFO("threadstatus", 0, 1, 1); + +/* Define the main thread's attribute value (optional) */ +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU); + +/* Define printf, just to make typing easier */ +#define printf pspDebugScreenPrintf + +void dump_threadstatus(void); + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + sceKernelExitGame(); + + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + + printf("\nCallback Thread Status:\n"); + dump_threadstatus(); + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + + sceKernelSleepThreadCB(); + + return 0; +} + +/* Dump the current thread's status */ +void dump_threadstatus(void) +{ + int thid; + SceKernelThreadInfo status; + int ret; + + thid = sceKernelGetThreadId(); + memset(&status, 0, sizeof(SceKernelThreadInfo)); + printf("Thread ID: %08X\n", thid); + status.size = sizeof(SceKernelThreadInfo); + ret = sceKernelReferThreadStatus(thid, &status); + printf("Get Thread Status: %08X\n", ret); + if(ret == 0) + { + printf("Name: %s\n", status.name); + printf("Thread Addr: %p\n", status.entry); + printf("Stack Addr: %p\n", status.stack); + printf("Stack Size: %08X\n", status.stackSize); + printf("gp: %p\n", status.gpReg); + printf("Initial Pri: %x\n", status.initPriority); + printf("Current Pri: %x\n", status.currentPriority); + } +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0); + if(thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} + +int main(int argc, char *argv[]) +{ + pspDebugScreenInit(); + if (argc > 0) { + printf("Bootpath: %s\n", argv[0]); + } + SetupCallbacks(); + printf("\nMain Thread Status:\n"); + dump_threadstatus(); + sceKernelSleepThread(); + + return 0; +} diff --git a/src/samples/me/basic/Makefile.sample b/src/samples/me/basic/Makefile.sample new file mode 100644 index 00000000..7f00e2a1 --- /dev/null +++ b/src/samples/me/basic/Makefile.sample @@ -0,0 +1,16 @@ +TARGET = mebasic +OBJS = main.o me.o + +INCDIR = +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = ME Basic Example + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/me/basic/main.c b/src/samples/me/basic/main.c new file mode 100644 index 00000000..24f1791e --- /dev/null +++ b/src/samples/me/basic/main.c @@ -0,0 +1,68 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - A basic example of getting code onto the ME. This was based on + * the sample code written by crazyc on the pspdev forums. + * + * Copyright (c) 2005 James Forshaw + * + * $Id: main.c 1095 2005-09-27 21:02:16Z jim $ + */ +#include +#include +#include +#include +#include +#include + +/* Define the module info section */ +PSP_MODULE_INFO("mebasic", 0x1000, 1, 1); + +/* Define the main thread's attribute value (optional) */ +PSP_MAIN_THREAD_ATTR(0); + +/* Define printf, just to make typing easier */ +#define printf pspDebugScreenPrintf + +void me_run(void); +void me_end(void); + +int main(int argc, char *argv[]) +{ + SceCtrlData ctl; + + pspDebugScreenInit(); + + sceCtrlSetSamplingCycle(0); + sceCtrlSetSamplingMode(PSP_CTRL_MODE_DIGITAL); + + /* Copy our small program into the ME reset vector */ + memcpy((void *)0xbfc00040, me_run, (int)(me_end - me_run)); + sceKernelDcacheWritebackInvalidateAll(); + + sceSysregMeResetEnable(); + sceSysregMeBusClockEnable(); + sceSysregMeResetDisable(); + sceSysregVmeResetDisable(); + + while(1) + { + volatile u32 *count = (u32*) 0xBFC00060; + + pspDebugScreenSetXY(0, 0); + pspDebugScreenPrintf("ME Basic Example, press Home to exit\n"); + sceKernelDcacheWritebackInvalidateAll(); + pspDebugScreenPrintf("ME Counter: %08x\n", *count); + sceCtrlReadBufferPositive(&ctl, 1); + if(ctl.Buttons & PSP_CTRL_HOME) + { + sceKernelExitGame(); + } + + sceDisplayWaitVblankStart(); + } + + return 0; +} diff --git a/src/samples/me/basic/me.S b/src/samples/me/basic/me.S new file mode 100644 index 00000000..5cd581a4 --- /dev/null +++ b/src/samples/me/basic/me.S @@ -0,0 +1,18 @@ + .set noreorder + + .global me_run + .global me_end + + .ent me_run + +me_run: + li $2, 0xbfc00060 + li $3, 0 +loop: + addiu $3, $3, 1 + sw $3, 0($2) + b loop + nop +me_end: + + .end me_run diff --git a/src/samples/mp3/Makefile.sample b/src/samples/mp3/Makefile.sample new file mode 100755 index 00000000..724ad16c --- /dev/null +++ b/src/samples/mp3/Makefile.sample @@ -0,0 +1,16 @@ +PSPSDK = $(shell psp-config --pspsdk-path) +PSPLIBSDIR = $(PSPSDK)/.. +TARGET = mp3sample +OBJS = main.o +LIBS = -lpspaudio -lpspmp3 + +BUILD_PRX = 1 + +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Mp3 Sample + +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/mp3/main.c b/src/samples/mp3/main.c new file mode 100755 index 00000000..269668a1 --- /dev/null +++ b/src/samples/mp3/main.c @@ -0,0 +1,335 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Sample to demonstrate proper use of the mp3 library + * + * Copyright (c) 2008 Alexander Berl + * + * $Id: $ + */ +#include +#include +#include +#include +#include +#include +#include +#include + + +/* Define the module info section */ +PSP_MODULE_INFO("Mp3Test", 0, 0, 1); +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER); +PSP_HEAP_SIZE_KB(-1024); + +#define MP3FILE "ms0:/MUSIC/Test.mp3" + +/* Define printf, just to make typing easier */ +#define printf pspDebugScreenPrintf + +static int isrunning = 1; +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + isrunning = 0; + + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0); + if (thid >= 0) + sceKernelStartThread(thid, 0, 0); + return thid; +} + + +// Input and Output buffers +char mp3Buf[16*1024] __attribute__((aligned(64))); +short pcmBuf[16*(1152/2)] __attribute__((aligned(64))); + + +// Macro to allow formatted input without having to use stdargs.h +#define ERRORMSG(...) { char msg[128]; sprintf(msg,__VA_ARGS__); error(msg); } + +// Print out an error message and quit after user input +void error( char* msg ) +{ + SceCtrlData pad; + pspDebugScreenClear(); + pspDebugScreenSetXY(0, 0); + printf(msg); + printf("Press X to quit.\n"); + while (isrunning) + { + sceCtrlReadBufferPositive(&pad, 1); + if (pad.Buttons & PSP_CTRL_CROSS) + break; + sceDisplayWaitVblankStart(); + } + sceKernelExitGame(); +} + +int fillStreamBuffer( int fd, int handle ) +{ + char* dst; + int write; + int pos; + // Get Info on the stream (where to fill to, how much to fill, where to fill from) + int status = sceMp3GetInfoToAddStreamData( handle, &dst, &write, &pos); + if (status<0) + { + ERRORMSG("ERROR: sceMp3GetInfoToAddStreamData returned 0x%08X\n", status); + } + + // Seek file to position requested + status = sceIoLseek32( fd, pos, SEEK_SET ); + if (status<0) + { + ERRORMSG("ERROR: sceIoLseek32 returned 0x%08X\n", status); + } + + // Read the amount of data + int read = sceIoRead( fd, dst, write ); + if (read < 0) + { + ERRORMSG("ERROR: Could not read from file - 0x%08X\n", read); + } + + if (read==0) + { + // End of file? + return 0; + } + + // Notify mp3 library about how much we really wrote to the stream buffer + status = sceMp3NotifyAddStreamData( handle, read ); + if (status<0) + { + ERRORMSG("ERROR: sceMp3NotifyAddStreamData returned 0x%08X\n", status); + } + + return (pos>0); +} + +/* main routine */ +int main(int argc, char *argv[]) +{ + SceCtrlData pad; + + //init screen and callbacks + pspDebugScreenInit(); + pspDebugScreenClear(); + SetupCallbacks(); + + // Setup Pad + sceCtrlSetSamplingCycle(0); + sceCtrlSetSamplingMode(0); + + // Load modules + int status = sceUtilityLoadModule(PSP_MODULE_AV_AVCODEC); + if (status<0) + { + ERRORMSG("ERROR: sceUtilityLoadModule(PSP_MODULE_AV_AVCODEC) returned 0x%08X\n", status); + } + + status = sceUtilityLoadModule(PSP_MODULE_AV_MP3); + if (status<0) + { + ERRORMSG("ERROR: sceUtilityLoadModule(PSP_MODULE_AV_MP3) returned 0x%08X\n", status); + } + + // Open the input file + int fd = sceIoOpen( MP3FILE, PSP_O_RDONLY, 0777 ); + if (fd<0) + { + ERRORMSG("ERROR: Could not open file '%s' - 0x%08X\n", MP3FILE, fd); + } + + // Init mp3 resources + status = sceMp3InitResource(); + if (status<0) + { + ERRORMSG("ERROR: sceMp3InitResource returned 0x%08X\n", status); + } + + // Reserve a mp3 handle for our playback + SceMp3InitArg mp3Init; + mp3Init.mp3StreamStart = 0; + mp3Init.mp3StreamEnd = sceIoLseek32( fd, 0, SEEK_END ); + mp3Init.unk1 = 0; + mp3Init.unk2 = 0; + mp3Init.mp3Buf = mp3Buf; + mp3Init.mp3BufSize = sizeof(mp3Buf); + mp3Init.pcmBuf = pcmBuf; + mp3Init.pcmBufSize = sizeof(pcmBuf); + + int handle = sceMp3ReserveMp3Handle( &mp3Init ); + if (handle<0) + { + ERRORMSG("ERROR: sceMp3ReserveMp3Handle returned 0x%08X\n", handle); + } + + // Fill the stream buffer with some data so that sceMp3Init has something to work with + fillStreamBuffer( fd, handle ); + + status = sceMp3Init( handle ); + if (status<0) + { + ERRORMSG("ERROR: sceMp3Init returned 0x%08X\n", status); + } + + int channel = -1; + int samplingRate = sceMp3GetSamplingRate( handle ); + int numChannels = sceMp3GetMp3ChannelNum( handle ); + int lastDecoded = 0; + int volume = PSP_AUDIO_VOLUME_MAX; + int numPlayed = 0; + int paused = 0; + int lastButtons = 0; + int loop = 0; + while (isrunning) + { + sceDisplayWaitVblankStart(); + pspDebugScreenSetXY(0, 0); + printf("PSP Mp3 Sample v1.0 by Raphael\n\n"); + printf("Playing '%s'...\n", MP3FILE); + printf(" %i Hz\n", samplingRate); + printf(" %i kbit/s\n", sceMp3GetBitRate( handle )); + printf(" %s\n", numChannels==2?"Stereo":"Mono"); + printf(" %s\n\n", loop==0?"No loop":"Loop"); + int playTime = samplingRate>0?numPlayed / samplingRate:0; + printf(" Playtime: %02i:%02i\n", playTime/60, playTime%60 ); + printf("\n\n\nPress CIRCLE to Pause/Resume playback\nPress TRIANGLE to reset playback\nPress CROSS to switch loop mode\nPress SQUARE to stop playback and quit\n"); + + if (!paused) + { + // Check if we need to fill our stream buffer + if (sceMp3CheckStreamDataNeeded( handle )>0) + { + fillStreamBuffer( fd, handle ); + } + + // Decode some samples + short* buf; + int bytesDecoded; + int retries = 0; + // We retry in case it's just that we reached the end of the stream and need to loop + for (;retries<1;retries++) + { + bytesDecoded = sceMp3Decode( handle, &buf ); + if (bytesDecoded>0) + break; + + if (sceMp3CheckStreamDataNeeded( handle )<=0) + break; + + if (!fillStreamBuffer( fd, handle )) + { + numPlayed = 0; + } + } + if (bytesDecoded<0 && bytesDecoded!=0x80671402) + { + ERRORMSG("ERROR: sceMp3Decode returned 0x%08X\n", bytesDecoded); + } + + // Nothing more to decode? Must have reached end of input buffer + if (bytesDecoded==0 || bytesDecoded==0x80671402) + { + paused = 1; + sceMp3ResetPlayPosition( handle ); + numPlayed = 0; + } + else + { + // Reserve the Audio channel for our output if not yet done + if (channel<0 || lastDecoded!=bytesDecoded) + { + if (channel>=0) + sceAudioSRCChRelease(); + + channel = sceAudioSRCChReserve( bytesDecoded/(2*numChannels), samplingRate, numChannels ); + } + // Output the decoded samples and accumulate the number of played samples to get the playtime + numPlayed += sceAudioSRCOutputBlocking( volume, buf ); + } + } + + sceCtrlPeekBufferPositive(&pad, 1); + + if (pad.Buttons!=lastButtons) + { + if (pad.Buttons & PSP_CTRL_CIRCLE) + { + paused ^= 1; + } + + if (pad.Buttons & PSP_CTRL_TRIANGLE) + { + // Reset the stream and playback status + sceMp3ResetPlayPosition( handle ); + numPlayed = 0; + } + + if (pad.Buttons & PSP_CTRL_CROSS) + { + loop = (loop==0?-1:0); + status = sceMp3SetLoopNum( handle, loop ); + if (status<0) + { + ERRORMSG("ERROR: sceMp3SetLoopNum returned 0x%08X\n", status); + } + } + + if (pad.Buttons & PSP_CTRL_SQUARE) + { + break; + } + + lastButtons = pad.Buttons; + } + } + + // Cleanup time... + if (channel>=0) + sceAudioSRCChRelease(); + + status = sceMp3ReleaseMp3Handle( handle ); + if (status<0) + { + ERRORMSG("ERROR: sceMp3ReleaseMp3Handle returned 0x%08X\n", status); + } + + status = sceMp3TermResource(); + if (status<0) + { + ERRORMSG("ERROR: sceMp3TermResource returned 0x%08X\n", status); + } + + status = sceIoClose( fd ); + if (status<0) + { + ERRORMSG("ERROR: sceIoClose returned 0x%08X\n", status); + } + + sceKernelExitGame(); + + return 0; +} diff --git a/src/samples/ms/callback/Makefile.sample b/src/samples/ms/callback/Makefile.sample new file mode 100644 index 00000000..880b3275 --- /dev/null +++ b/src/samples/ms/callback/Makefile.sample @@ -0,0 +1,15 @@ +TARGET = mscm +OBJS = main.o + +BUILD_PRX=1 + +INCDIR = +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/ms/callback/main.c b/src/samples/ms/callback/main.c new file mode 100644 index 00000000..1edfe55e --- /dev/null +++ b/src/samples/ms/callback/main.c @@ -0,0 +1,56 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - PRX MS insert/eject callback usage sample + * + * Copyright (c) 2006 Iaroslav Gaponenko + * + * $Id: main.c 2006 2006-09-17 21:48:56Z tyranid $ + * $HeadURL: svn://svn.ps2dev.org/psp/trunk/pspsdk/src/samples/ms/callback/main.c $ + */ +#include +#include +#include + +/* Define the module info section */ +PSP_MODULE_INFO("MS CB Sample", 0, 1, 1); + +/* Define the main thread's attribute value (optional) */ +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU); + +int ms_callback(int arg1, int arg2, void *arg) +{ + if (arg2 == MS_CB_EVENT_INSERTED){ + printf("Memory Stick (c) has been inserted.\n"); + } else if (arg2 == MS_CB_EVENT_EJECTED){ + printf("Memory Stick (c) has been ejected.\n"); + } + return 0; +} + +int main(int argc, char *argv[]) +{ + SceUID cb_id; + + cb_id = sceKernelCreateCallback("MSCB", ms_callback, NULL); + printf("================================================\n"); + printf("Memory Stick (c) insert/eject callback sample.\n"); + printf("Adrahil (c) 2006, thanks to TyRaNiD, dot_blank\n"); + printf("\n"); + printf("\n"); + printf("================================================\n"); + printf("Created callback %08X\n", cb_id); + printf("Registering callback %08X\n", MScmRegisterMSInsertEjectCallback(cb_id)); + printf("================================================\n"); + printf("Please remove your Memory Stick (c) now!\n"); + printf("\n"); + + sceKernelSleepThreadCB(); + + //This will not be reached, as the instruction above sleeps the thread, and since this is a one-thread application. + // Nevertheless, this shows how to unregister the callback in case one needs it. + MScmUnregisterMSInsertEjectCallback(cb_id); + return 0; +} diff --git a/src/samples/nand/dumpipl/Makefile.sample b/src/samples/nand/dumpipl/Makefile.sample new file mode 100644 index 00000000..7baa63ed --- /dev/null +++ b/src/samples/nand/dumpipl/Makefile.sample @@ -0,0 +1,16 @@ +TARGET = dumpipl +OBJS = main.o + +INCDIR = +CFLAGS = -O2 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LIBS = -lpspnand_driver +LDFLAGS = + +EXTRA_TARGETS = EBOOT.PBP + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/nand/dumpipl/README b/src/samples/nand/dumpipl/README new file mode 100644 index 00000000..6dd279de --- /dev/null +++ b/src/samples/nand/dumpipl/README @@ -0,0 +1,4 @@ +Sample program to dump the Initial Program Loader (IPL) from flash. + +See http://forums.ps2dev.org/viewtopic.php?t=3573 for more information on the +IPL. diff --git a/src/samples/nand/dumpipl/main.c b/src/samples/nand/dumpipl/main.c new file mode 100644 index 00000000..b280526e --- /dev/null +++ b/src/samples/nand/dumpipl/main.c @@ -0,0 +1,212 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Dump the Initial Program Loader (IPL). + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * Sample program to write the contents of the Initial Program Loader (IPL) + * from flash to a file. The IPL is written to ms0:/ipl.bin. + * + * A table describing the location of the IPL is located at block offset 4 + * (physical page 128) in flash. The table contains a list of 16-bit values + * that point to the block offsets of the IPL itself. The table is terminated + * with an entry of zero. + * + * $Id: main.c 1212 2005-10-24 06:36:57Z mrbrown $ + */ + +#include +#include +#include + +#include +#include +#include + +/* Define the module info section */ +PSP_MODULE_INFO("dumpipl", 0x1000, 1, 1); +PSP_MAIN_THREAD_ATTR(0); + +/* Define printf, just to make typing easier */ +#define printf pspDebugScreenPrintf + +int g_iPageSize, g_iPagesPerBlock, g_iBlockSize; +int g_bFlashLocked = 0; + +void LockFlash(); +void UnlockFlash(); +void die(const char *msg); +int ReadIPLBlockTable(void *pBlockBuf); + +/* Exit callback */ +int exit_callback(void) +{ + UnlockFlash(); + sceKernelExitGame(); + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", (SceKernelCallbackFunction) exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + + sceKernelSleepThreadCB(); + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, PSP_THREAD_ATTR_USER, 0); + if(thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} + +void LockFlash() +{ + if (!g_bFlashLocked) + sceNandLock(0); + + g_bFlashLocked = 1; +} + +void UnlockFlash() +{ + if (g_bFlashLocked) + sceNandUnlock(); + + g_bFlashLocked = 0; +} + +void die(const char *msg) +{ + UnlockFlash(); + + printf("Fatal error: %s\n", msg); + + while (1) + sceKernelSleepThread(); +} + +int ReadIPLBlockTable(void *pBlockBuf) +{ + u16 *pBlockTable; + u32 uiBlockNum = 4; + u32 uiSearchCount = 8; + int iBlockCount; + + /* You must always get exclusive access to the flash device before reading + from it or writing to it. */ + LockFlash(); + memset(pBlockBuf, 0, g_iBlockSize); + + while (uiSearchCount > 0) + { + u32 uiPPN = uiBlockNum * g_iPagesPerBlock; + + if (!sceNandIsBadBlock(uiPPN)) + { + if (sceNandReadBlockWithRetry(uiPPN, pBlockBuf, NULL) < 0) + { + die("can't read IPL block table!"); + } + + printf("Found IPL block table at block %d\n", uiBlockNum); + break; + } + + uiBlockNum++; + uiSearchCount--; + } + + /* Count the number of blocks used by the IPL. */ + pBlockTable = (u16 *) pBlockBuf; + iBlockCount = 0; + + while (*pBlockTable != 0) + { + iBlockCount++; + pBlockTable++; + } + + if (iBlockCount) + printf("IPL spans a total of %d blocks.\n", iBlockCount); + + UnlockFlash(); + return iBlockCount; +} + +int main(int argc, char *argv[]) +{ + void *pBlockBuf; + u16 *pBlockTable; + int iBlockCount, iBlock; + int fd; + + pspDebugScreenInit(); + SetupCallbacks(); + + g_iPageSize = sceNandGetPageSize(); + g_iPagesPerBlock = sceNandGetPagesPerBlock(); + g_iBlockSize = g_iPageSize * g_iPagesPerBlock; + + /* Read buffer for blocks. */ + pBlockBuf = malloc(g_iBlockSize); + assert(pBlockBuf); + + iBlockCount = ReadIPLBlockTable(pBlockBuf); + if (!iBlockCount) + die("IPL block count is 0!"); + + pBlockTable = (u16 *) malloc(iBlockCount * sizeof(u16)); + memcpy(pBlockTable, pBlockBuf, iBlockCount * sizeof(u16)); + + fd = sceIoOpen("ms0:/ipl.bin", PSP_O_WRONLY | PSP_O_CREAT, 0777); + if (fd < 0) + die("can't open ms0:/ipl.bin for writing!"); + + /* Write out each block of the IPL. */ + for (iBlock = 0; iBlock < iBlockCount; iBlock++) + { + u32 uiPPN = pBlockTable[iBlock] * g_iPagesPerBlock; + + LockFlash(); + + if (sceNandReadBlockWithRetry(uiPPN, pBlockBuf, NULL) < 0) + { + sceIoClose(fd); + die("can't read block from IPL!\n"); + } + + UnlockFlash(); + + if (sceIoWrite(fd, pBlockBuf, g_iBlockSize) < 0) + { + sceIoClose(fd); + die("can't write data to file!\n"); + } + } + + sceIoClose(fd); + free(pBlockTable); + free(pBlockBuf); + + printf("\nFinished writing IPL to ms0:/ipl.bin. Use [HOME] to exit.\n"); + sceKernelSleepThread(); + return 0; +} diff --git a/src/samples/net/resolver/Makefile.sample b/src/samples/net/resolver/Makefile.sample new file mode 100644 index 00000000..dc6979cd --- /dev/null +++ b/src/samples/net/resolver/Makefile.sample @@ -0,0 +1,14 @@ +TARGET = resolver +OBJS = main.o + +INCDIR = +CFLAGS = -O0 -G0 -Wall -g +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = + +EXTRA_TARGETS = EBOOT.PBP + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/net/resolver/main.c b/src/samples/net/resolver/main.c new file mode 100644 index 00000000..475f8319 --- /dev/null +++ b/src/samples/net/resolver/main.c @@ -0,0 +1,216 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Simple DNS resolver example + * + * Copyright (c) 2006 James F + * Some small parts (c) 2005 PSPPet + * + * $Id: main.c 2435 2008-10-15 18:05:02Z iwn $ + * $HeadURL: svn://svn.ps2dev.org/psp/trunk/pspsdk/src/samples/net/resolver/main.c $ + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define printf pspDebugScreenPrintf + +#define MODULE_NAME "Resolver" + +#define RESOLVE_NAME "badgers.com" + +PSP_MODULE_INFO(MODULE_NAME, 0x1000, 1, 1); +PSP_MAIN_THREAD_ATTR(0); + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + + thid = sceKernelCreateThread("update_thread", CallbackThread, + 0x11, 0xFA0, PSP_THREAD_ATTR_USER, 0); + if(thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} + +void do_resolver(void) +{ + int rid = -1; + char buf[1024]; + struct in_addr addr; + char name[1024]; + + do + { + /* Create a resolver */ + if(sceNetResolverCreate(&rid, buf, sizeof(buf)) < 0) + { + printf("Error creating resolver\n"); + break; + } + + printf("Created resolver %08x\n", rid); + + /* Resolve a name to an ip address */ + if(sceNetResolverStartNtoA(rid, RESOLVE_NAME, &addr, 2, 3) < 0) + { + printf("Error resolving %s\n", RESOLVE_NAME); + break; + } + + printf("Resolved %s to %s\n", RESOLVE_NAME, inet_ntoa(addr)); + + /* Resolve the ip address to a name */ + if(sceNetResolverStartAtoN(rid, &addr, name, sizeof(name), 2, 3) < 0) + { + printf("Error resolving ip to name\n"); + break; + } + + printf("Resolved ip to %s\n", name); + } + while(0); + + if(rid >= 0) + { + sceNetResolverDelete(rid); + } +} + +/* Connect to an access point */ +int connect_to_apctl(int config) +{ + int err; + int stateLast = -1; + + /* Connect using the first profile */ + err = sceNetApctlConnect(config); + if (err != 0) + { + printf(MODULE_NAME ": sceNetApctlConnect returns %08X\n", err); + return 0; + } + + printf(MODULE_NAME ": Connecting...\n"); + while (1) + { + int state; + err = sceNetApctlGetState(&state); + if (err != 0) + { + printf(MODULE_NAME ": sceNetApctlGetState returns $%x\n", err); + break; + } + if (state > stateLast) + { + printf(" connection state %d of 4\n", state); + stateLast = state; + } + if (state == 4) + break; // connected with static IP + + // wait a little before polling again + sceKernelDelayThread(50*1000); // 50ms + } + printf(MODULE_NAME ": Connected!\n"); + + if(err != 0) + { + return 0; + } + + return 1; +} + +int net_thread(SceSize args, void *argp) +{ + int err; + + do + { + if((err = pspSdkInetInit())) + { + printf(MODULE_NAME ": Error, could not initialise the network %08X\n", err); + break; + } + + if(connect_to_apctl(1)) + { + // connected, get my IPADDR and run test + union SceNetApctlInfo info; + + if (sceNetApctlGetInfo(8, &info) != 0) + strcpy(info.ip, "unknown IP"); + + do_resolver(); + } + } + while(0); + + return 0; +} + +/* Simple thread */ +int main(int argc, char **argv) +{ + SceUID thid; + + SetupCallbacks(); + + pspDebugScreenInit(); + + if(pspSdkLoadInetModules() < 0) + { + printf("Error, could not load inet modules\n"); + sceKernelSleepThread(); + } + + /* Create a user thread to do the real work */ + thid = sceKernelCreateThread("net_thread", net_thread, 0x18, 0x10000, PSP_THREAD_ATTR_USER, NULL); + if(thid < 0) + { + printf("Error, could not create thread\n"); + sceKernelSleepThread(); + } + + sceKernelStartThread(thid, 0, NULL); + + sceKernelExitDeleteThread(0); + + return 0; +} diff --git a/src/samples/net/simple/Makefile.sample b/src/samples/net/simple/Makefile.sample new file mode 100644 index 00000000..eaeed2ef --- /dev/null +++ b/src/samples/net/simple/Makefile.sample @@ -0,0 +1,14 @@ +TARGET = netsample +OBJS = main.o + +INCDIR = +CFLAGS = -O0 -G0 -Wall -g +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = + +EXTRA_TARGETS = EBOOT.PBP + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/net/simple/main.c b/src/samples/net/simple/main.c new file mode 100644 index 00000000..a94d7c92 --- /dev/null +++ b/src/samples/net/simple/main.c @@ -0,0 +1,288 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Simple elf based network example. + * + * Copyright (c) 2005 James F + * Some small parts (c) 2005 PSPPet + * + * $Id: main.c 2435 2008-10-15 18:05:02Z iwn $ + * $HeadURL: svn://svn.ps2dev.org/psp/trunk/pspsdk/src/samples/net/simple/main.c $ + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define printf pspDebugScreenPrintf + +#define MODULE_NAME "NetSample" +#define HELLO_MSG "Hello there. Type away.\r\n" + +PSP_MODULE_INFO(MODULE_NAME, 0x1000, 1, 1); +PSP_MAIN_THREAD_ATTR(0); + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + sceKernelExitGame(); + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + + thid = sceKernelCreateThread("update_thread", CallbackThread, + 0x11, 0xFA0, PSP_THREAD_ATTR_USER, 0); + if(thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} + +#define SERVER_PORT 23 + +int make_socket(uint16_t port) +{ + int sock; + int ret; + struct sockaddr_in name; + + sock = socket(PF_INET, SOCK_STREAM, 0); + if(sock < 0) + { + return -1; + } + + name.sin_family = AF_INET; + name.sin_port = htons(port); + name.sin_addr.s_addr = htonl(INADDR_ANY); + ret = bind(sock, (struct sockaddr *) &name, sizeof(name)); + if(ret < 0) + { + return -1; + } + + return sock; +} + +/* Start a simple tcp echo server */ +void start_server(const char *szIpAddr) +{ + int ret; + int sock; + int new = -1; + struct sockaddr_in client; + size_t size; + int readbytes; + char data[1024]; + fd_set set; + fd_set setsave; + + /* Create a socket for listening */ + sock = make_socket(SERVER_PORT); + if(sock < 0) + { + printf("Error creating server socket\n"); + return; + } + + ret = listen(sock, 1); + if(ret < 0) + { + printf("Error calling listen\n"); + return; + } + + printf("Listening for connections ip %s port %d\n", szIpAddr, SERVER_PORT); + + FD_ZERO(&set); + FD_SET(sock, &set); + setsave = set; + + while(1) + { + int i; + set = setsave; + if(select(FD_SETSIZE, &set, NULL, NULL, NULL) < 0) + { + printf("select error\n"); + return; + } + + for(i = 0; i < FD_SETSIZE; i++) + { + if(FD_ISSET(i, &set)) + { + int val = i; + + if(val == sock) + { + new = accept(sock, (struct sockaddr *) &client, &size); + if(new < 0) + { + printf("Error in accept %s\n", strerror(errno)); + close(sock); + return; + } + + printf("New connection %d from %s:%d\n", val, + inet_ntoa(client.sin_addr), + ntohs(client.sin_port)); + + write(new, HELLO_MSG, strlen(HELLO_MSG)); + + FD_SET(new, &setsave); + } + else + { + readbytes = read(val, data, sizeof(data)); + if(readbytes <= 0) + { + printf("Socket %d closed\n", val); + FD_CLR(val, &setsave); + close(val); + } + else + { + write(val, data, readbytes); + printf("%.*s", readbytes, data); + } + } + } + } + } + + close(sock); +} + +/* Connect to an access point */ +int connect_to_apctl(int config) +{ + int err; + int stateLast = -1; + + /* Connect using the first profile */ + err = sceNetApctlConnect(config); + if (err != 0) + { + printf(MODULE_NAME ": sceNetApctlConnect returns %08X\n", err); + return 0; + } + + printf(MODULE_NAME ": Connecting...\n"); + while (1) + { + int state; + err = sceNetApctlGetState(&state); + if (err != 0) + { + printf(MODULE_NAME ": sceNetApctlGetState returns $%x\n", err); + break; + } + if (state > stateLast) + { + printf(" connection state %d of 4\n", state); + stateLast = state; + } + if (state == 4) + break; // connected with static IP + + // wait a little before polling again + sceKernelDelayThread(50*1000); // 50ms + } + printf(MODULE_NAME ": Connected!\n"); + + if(err != 0) + { + return 0; + } + + return 1; +} + +int net_thread(SceSize args, void *argp) +{ + int err; + + do + { + if((err = pspSdkInetInit())) + { + printf(MODULE_NAME ": Error, could not initialise the network %08X\n", err); + break; + } + + if(connect_to_apctl(1)) + { + // connected, get my IPADDR and run test + union SceNetApctlInfo info; + + if (sceNetApctlGetInfo(8, &info) != 0) + strcpy(info.ip, "unknown IP"); + + start_server(info.ip); + } + } + while(0); + + return 0; +} + +/* Simple thread */ +int main(int argc, char **argv) +{ + SceUID thid; + + SetupCallbacks(); + + pspDebugScreenInit(); + + if(pspSdkLoadInetModules() < 0) + { + printf("Error, could not load inet modules\n"); + sceKernelSleepThread(); + } + + /* Create a user thread to do the real work */ + thid = sceKernelCreateThread("net_thread", net_thread, 0x18, 0x10000, PSP_THREAD_ATTR_USER, NULL); + if(thid < 0) + { + printf("Error, could not create thread\n"); + sceKernelSleepThread(); + } + + sceKernelStartThread(thid, 0, NULL); + + sceKernelExitDeleteThread(0); + + return 0; +} diff --git a/src/samples/net/simple_prx/Makefile.sample b/src/samples/net/simple_prx/Makefile.sample new file mode 100644 index 00000000..e2757024 --- /dev/null +++ b/src/samples/net/simple_prx/Makefile.sample @@ -0,0 +1,15 @@ +TARGET = netsample +OBJS = main.o + +PRX_EXPORTS=exports.exp +BUILD_PRX=1 + +INCDIR = +CFLAGS = -O0 -G0 -Wall -g +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/net/simple_prx/exports.exp b/src/samples/net/simple_prx/exports.exp new file mode 100644 index 00000000..b7940e81 --- /dev/null +++ b/src/samples/net/simple_prx/exports.exp @@ -0,0 +1,12 @@ +# Define the exports for the prx +PSP_BEGIN_EXPORTS + +# These four lines are mandatory (although you can add other functions like module_stop) +# syslib is a psynonym for the single mandatory export. +PSP_EXPORT_START(syslib, 0, 0x8000) +PSP_EXPORT_FUNC(module_start) +PSP_EXPORT_FUNC(module_stop) +PSP_EXPORT_VAR(module_info) +PSP_EXPORT_END + +PSP_END_EXPORTS diff --git a/src/samples/net/simple_prx/main.c b/src/samples/net/simple_prx/main.c new file mode 100644 index 00000000..79428d17 --- /dev/null +++ b/src/samples/net/simple_prx/main.c @@ -0,0 +1,234 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Simple prx based network example. Must load the net modules + * before running. + * + * Copyright (c) 2005 James F + * Some small parts (c) 2005 PSPPet + * + * $Id: main.c 2435 2008-10-15 18:05:02Z iwn $ + * $HeadURL: svn://svn.ps2dev.org/psp/trunk/pspsdk/src/samples/net/simple_prx/main.c $ + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MODULE_NAME "NetSample" +#define HELLO_MSG "Hello there. Type away.\r\n" + +PSP_MODULE_INFO(MODULE_NAME, 0, 1, 1); +PSP_MAIN_THREAD_NAME("NetSample"); + +#define SERVER_PORT 23 + +int make_socket(uint16_t port) +{ + int sock; + int ret; + struct sockaddr_in name; + + sock = socket(PF_INET, SOCK_STREAM, 0); + if(sock < 0) + { + return -1; + } + + name.sin_family = AF_INET; + name.sin_port = htons(port); + name.sin_addr.s_addr = htonl(INADDR_ANY); + ret = bind(sock, (struct sockaddr *) &name, sizeof(name)); + if(ret < 0) + { + return -1; + } + + return sock; +} + +/* Start a simple tcp echo server */ +void start_server(const char *szIpAddr) +{ + int ret; + int sock; + int new = -1; + struct sockaddr_in client; + size_t size; + int readbytes; + char data[1024]; + fd_set set; + fd_set setsave; + + /* Create a socket for listening */ + sock = make_socket(SERVER_PORT); + if(sock < 0) + { + printf("Error creating server socket\n"); + return; + } + + ret = listen(sock, 1); + if(ret < 0) + { + printf("Error calling listen\n"); + return; + } + + printf("Listening for connections ip %s port %d\n", szIpAddr, SERVER_PORT); + + FD_ZERO(&set); + FD_SET(sock, &set); + setsave = set; + + while(1) + { + int i; + set = setsave; + if(select(FD_SETSIZE, &set, NULL, NULL, NULL) < 0) + { + printf("select error\n"); + return; + } + + for(i = 0; i < FD_SETSIZE; i++) + { + if(FD_ISSET(i, &set)) + { + int val = i; + + if(val == sock) + { + new = accept(sock, (struct sockaddr *) &client, &size); + if(new < 0) + { + printf("Error in accept %s\n", strerror(errno)); + close(sock); + return; + } + + printf("New connection %d from %s:%d\n", val, + inet_ntoa(client.sin_addr), + ntohs(client.sin_port)); + + write(new, HELLO_MSG, strlen(HELLO_MSG)); + + FD_SET(new, &setsave); + } + else + { + readbytes = read(val, data, sizeof(data)); + if(readbytes <= 0) + { + printf("Socket %d closed\n", val); + FD_CLR(val, &setsave); + close(val); + } + else + { + write(val, data, readbytes); + printf("%.*s", readbytes, data); + } + } + } + } + } + + close(sock); +} + +/* Connect to an access point */ +int connect_to_apctl(int config) +{ + int err; + int stateLast = -1; + + /* Connect using the first profile */ + err = sceNetApctlConnect(config); + if (err != 0) + { + printf(MODULE_NAME ": sceNetApctlConnect returns %08X\n", err); + return 0; + } + + printf(MODULE_NAME ": Connecting...\n"); + while (1) + { + int state; + err = sceNetApctlGetState(&state); + if (err != 0) + { + printf(MODULE_NAME ": sceNetApctlGetState returns $%x\n", err); + break; + } + if (state > stateLast) + { + printf(" connection state %d of 4\n", state); + stateLast = state; + } + if (state == 4) + break; // connected with static IP + + // wait a little before polling again + sceKernelDelayThread(50*1000); // 50ms + } + printf(MODULE_NAME ": Connected!\n"); + + if(err != 0) + { + return 0; + } + + return 1; +} + +/* Simple thread */ +int main(int argc, char **argv) +{ + int err; + + do + { + if((err = pspSdkInetInit())) + { + printf(MODULE_NAME ": Error, could not initialise the network %08X\n", err); + break; + } + + if(connect_to_apctl(1)) + { + // connected, get my IPADDR and run test + union SceNetApctlInfo info; + + if (sceNetApctlGetInfo(8, &info) != 0) + strcpy(info.ip, "unknown IP"); + + start_server(info.ip); + } + } + while(0); + + sceKernelSleepThread(); + + return 0; +} + +int module_stop(SceSize args, void *argp) +{ + (void) pspSdkInetTerm(); + + return 0; +} diff --git a/src/samples/net/wlanscan/Makefile.sample b/src/samples/net/wlanscan/Makefile.sample new file mode 100644 index 00000000..2e5a41d8 --- /dev/null +++ b/src/samples/net/wlanscan/Makefile.sample @@ -0,0 +1,17 @@ +TARGET = wlanscan +OBJS = main.o + +BUILD_PRX=1 + +INCDIR = +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBS=-lpspwlan -lpspnet + +LIBDIR = +LDFLAGS = + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/net/wlanscan/main.c b/src/samples/net/wlanscan/main.c new file mode 100644 index 00000000..88b466f8 --- /dev/null +++ b/src/samples/net/wlanscan/main.c @@ -0,0 +1,228 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Example of using the WLAN scanner + * The info here was reversed from scan.prx which Sony/Namco so + * helpfully left in plain sight on the japanese ridge racer UMD + * Thx boys :) + * + * Copyright (c) 2006 James F + * + * $Id: main.c 1699 2006-01-15 23:46:00Z tyranid $ + * $HeadURL: svn://svn.ps2dev.org/psp/trunk/pspsdk/src/samples/net/wlanscan/main.c $ + */ +#include +#include +#include +#include +#include + +/* Define the module info section */ +PSP_MODULE_INFO("wlanscan", 0, 1, 1); + +/* Define the main thread's attribute value (optional) */ +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU); + +/* Init the scan */ +int sceNet_lib_5216CBF5(const char *name); +/* Do the scan */ +int sceNet_lib_7BA3ED91(const char *name, void *type, u32 *size, void *buf, u32 *unk); +/* Terminate the scan */ +int sceNet_lib_D2422E4D(const char *name); + +#define InitScan sceNet_lib_5216CBF5 +#define ScanAPs sceNet_lib_7BA3ED91 +#define TermScan sceNet_lib_D2422E4D + +/* Global buffer to store the scan data */ +unsigned char scan_data[0xA80]; + +/* Returned data */ +struct ScanData +{ + struct ScanHead *pNext; + unsigned char bssid[6]; + char channel; + unsigned char namesize; + char name[32]; + unsigned int bsstype; + unsigned int beaconperiod; + unsigned int dtimperiod; + unsigned int timestamp; + unsigned int localtime; + unsigned short atim; + unsigned short capabilities; + unsigned char rate[8]; + unsigned short rssi; + unsigned char sizepad[6]; +} __attribute__((packed)); + +/* Capability flags */ +const char *caps[8] = { + "ESS, ", + "IBSS, ", + "CF Pollable, ", + "CF Pollreq, ", + "Privacy, ", + "Short Preamble, ", + "PBCC, ", + "Channel Agility, " +}; + +/* Print the scan data to stdout */ +void print_scan(unsigned char *data, int size) +{ + int i = 1; + + while(size >= sizeof(struct ScanData)) + { + char name[33]; + char bssid[30]; + int loop; + struct ScanData *pData; + + pData = (struct ScanData *) data; + printf("==================\n"); + printf(" BSS: %d\n", i); + printf("==================\n"); + strncpy(name, pData->name, 32); + name[32] = 0; + sceNetEtherNtostr(pData->bssid, bssid); + printf("BSSID: %s\n", bssid); + printf("SSID: %s\n", name); + printf("bsstype: "); + if(pData->bsstype == 1) + { + printf("Infrastructure\n"); + } + else if(pData->bsstype == 2) + { + printf("Independent\n"); + } + else + { + printf("Unknown\n"); + } + printf("Beacon Period: %d\n", pData->beaconperiod); + printf("DTIM period: %d\n", pData->dtimperiod); + printf("Timestamp: %d\n", pData->timestamp); + printf("Local Time: %d\n", pData->localtime); + printf("Channel: %d\n", pData->channel); + printf("ATIM: %d\n", pData->atim); + printf("Capability Information: "); + for(loop = 0; loop < 8; loop++) + { + if(pData->capabilities & (1 << loop)) + { + printf("%s", caps[loop]); + } + } + printf("\n"); + + printf("Rate: "); + for(loop = 0; loop < 8; loop++) + { + const char *type; + + if(pData->rate[loop] & 0x80) + { + type = "Basic"; + } + else + { + type = "Operational"; + } + + if(pData->rate[loop] & 0x7F) + { + printf("%s %d kbps, ", type, (pData->rate[loop] & 0x7F) * 500); + } + } + printf("\n"); + + printf("RSSI: %d\n", pData->rssi); + + printf("\n"); + i++; + data += sizeof(struct ScanData); + size -= sizeof(struct ScanData); + } +} + +/* Do a scan */ +void do_scan(void) +{ + unsigned char type[0x4C]; + u32 size, unk; + int i; + int ret; + + if(InitScan("wlan") >= 0) + { + /* No real idea what this is doing ;) */ + memset(type, 0, sizeof(type)); + for(i = 1; i < 0xF; i++) + { + type[0x9+i] = i; + } + type[0x3C] = 1; + *((u32*) (type + 0x44)) = 6; /* Minimum strength */ + *((u32*) (type + 0x48)) = 100; /* Maximum strength */ + size = sizeof(scan_data); + unk = 0; + memset(scan_data, 0, sizeof(scan_data)); + ret = ScanAPs("wlan", type, &size, scan_data, &unk); + if(ret < 0) + { + printf("Error, could not perform scan err = %08X\n", ret); + } + else + { + print_scan(scan_data, size); + } + } + else + { + printf("Error, cannot initialise scan\n"); + } + + TermScan("wlan"); +} + +int main(int argc, char *argv[]) +{ + int ret; + + ret = sceNetInit(0x20000, 0x20, 0x1000, 0x20, 0x1000); + if(ret < 0) + { + printf("Error initialising network lib %08X\n", ret); + goto error; + } + + ret = -1; + while(ret < 0) + { + ret = sceWlanDevAttach(); + + /* If returns a error which indicates it isn't ready */ + if(ret == 0x80410D0E) + { + sceKernelDelayThread(1000000); + } + else if(ret < 0) + { + printf("Error attaching to wlan device %08X\n", ret); + goto error; + } + } + + do_scan(); +error: + sceWlanDevDetach(); + sceNetTerm(); + + return 0; +} diff --git a/src/samples/net/wlanscan_elf/Makefile.sample b/src/samples/net/wlanscan_elf/Makefile.sample new file mode 100644 index 00000000..f220a0f6 --- /dev/null +++ b/src/samples/net/wlanscan_elf/Makefile.sample @@ -0,0 +1,17 @@ +TARGET = wlanscan +OBJS = main.o + +INCDIR = +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBS=-lpspwlan -lpspnet + +LIBDIR = +LDFLAGS = + +EXTRA_TARGETS = EBOOT.PBP + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/net/wlanscan_elf/main.c b/src/samples/net/wlanscan_elf/main.c new file mode 100644 index 00000000..253401b3 --- /dev/null +++ b/src/samples/net/wlanscan_elf/main.c @@ -0,0 +1,374 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - ELF Based WLAN Scanner + * + * Copyright (c) 2005 James F + * adresd + * + * $Id: main.c 1888 2006-05-01 08:47:04Z tyranid $ + * $HeadURL$ + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define printf pspDebugScreenPrintf + +#define MODULE_NAME "WlanScanner" + +PSP_MODULE_INFO(MODULE_NAME, 0x1000, 1, 1); +PSP_MAIN_THREAD_ATTR(0); + +/* Init the scan */ +int sceNet_lib_5216CBF5(const char *name); +/* Do the scan */ +int sceNet_lib_7BA3ED91(const char *name, void *type, u32 *size, void *buf, u32 *unk); +/* Terminate the scan */ +int sceNet_lib_D2422E4D(const char *name); + +#define InitScan sceNet_lib_5216CBF5 +#define ScanAPs sceNet_lib_7BA3ED91 +#define TermScan sceNet_lib_D2422E4D + +/* Global buffer to store the scan data */ +unsigned char scan_data[0xA80]; + +/* Returned data */ +struct ScanData +{ + struct ScanHead *pNext; + unsigned char bssid[6]; + char channel; + unsigned char namesize; + char name[32]; + unsigned int bsstype; + unsigned int beaconperiod; + unsigned int dtimperiod; + unsigned int timestamp; + unsigned int localtime; + unsigned short atim; + unsigned short capabilities; + unsigned char rate[8]; + unsigned short rssi; + unsigned char sizepad[6]; +} __attribute__((packed)); + +/* Capability flags */ +const char *caps[8] = { + "ESS, ", + "IBSS, ", + "CF Pollable, ", + "CF Pollreq, ", + "Privacy (WEP), ", + "Short Preamble, ", + "PBCC, ", + "Channel Agility, " +}; + +/* Print the scan summary data to stdout */ +void print_apsum(struct ScanData *pData) +{ + char name[33]; + int loop; + strncpy(name, pData->name, 32); + name[32] = 0; + printf("RSSI:%02d ", pData->rssi); + if (pData->capabilities & (1 << 4)) + printf(" WEP! "); + else + printf("NO WEP"); + printf(" SSID: %s\n", name); +} + +/* Print the scan data to stdout */ +void print_ap(struct ScanData *pData) +{ + char name[33]; + char bssid[30]; + int loop; + + strncpy(name, pData->name, 32); + name[32] = 0; + sceNetEtherNtostr(pData->bssid, bssid); + printf("BSSID: %s\n", bssid); + printf("SSID: %s\n", name); + printf("bsstype: "); + if(pData->bsstype == 1) + { + printf("Infrastructure\n"); + } + else if(pData->bsstype == 2) + { + printf("Independent\n"); + } + else + { + printf("Unknown\n"); + } + printf("Beacon Period: %d\n", pData->beaconperiod); + printf("DTIM period: %d\n", pData->dtimperiod); + printf("Timestamp: %d\n", pData->timestamp); + printf("Local Time: %d\n", pData->localtime); + printf("Channel: %d\n", pData->channel); + printf("ATIM: %d\n", pData->atim); + printf("Capability Information: "); + for(loop = 0; loop < 8; loop++) + { + if(pData->capabilities & (1 << loop)) + { + printf("%s", caps[loop]); + } + } + printf("\n"); + + printf("Rate: "); + for(loop = 0; loop < 8; loop++) + { + const char *type; + + if(pData->rate[loop] & 0x80) + { + type = "Basic"; + } + else + { + type = "Operational"; + } + + if(pData->rate[loop] & 0x7F) + { + printf("%s %d kbps, ", type, (pData->rate[loop] & 0x7F) * 500); + } + } + printf("\n"); + + printf("RSSI: %d\n", pData->rssi); + + printf("\n"); +} + +/* Do a scan */ +struct ScanData *do_scan(int *count) +{ + unsigned char type[0x4C]; + u32 size, unk; + int i; + int ret; + + if((ret = InitScan("wlan")) >= 0) + { + memset(type, 0, sizeof(type)); + /* Set the channels we want to scan */ + for(i = 1; i < 0xF; i++) + { + type[0x9+i] = i; + } + type[0x3C] = 1; + *((u32*) (type + 0x44)) = 1; //6/* Minimum strength */ + *((u32*) (type + 0x48)) = 100; /* Maximum strength */ + size = sizeof(scan_data); + unk = 0; + memset(scan_data, 0, sizeof(scan_data)); + ret = ScanAPs("wlan", type, &size, scan_data, &unk); + if(ret < 0) + { + printf("Error, could not perform scan err = %08X\n", ret); + } + else + { + *count = size / sizeof(struct ScanData); + return (struct ScanData *) scan_data; + } + } + else + { + printf("Error, cannot initialise scan %08X\n", ret); + } + + TermScan("wlan"); + + return NULL; +} + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + sceWlanDevDetach(); + sceNetTerm(); + sceKernelExitGame(); + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + + thid = sceKernelCreateThread("update_thread", CallbackThread, + 0x11, 0xFA0, PSP_THREAD_ATTR_USER, 0); + if(thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} + +void start_ui(struct ScanData *pScan, int count) +{ + unsigned int last = 0; + SceCtrlData pad; + int ap = 0; + int loop = 1; + int vcount = 0; + + sceCtrlSetSamplingCycle(0); + sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG); + while(loop) + { + pspDebugScreenClear(); + printf("Scan found %d access point(s)\n\n", count); + + printf("Press X to rescan, SQUARE to quit\n"); + + if (count == 0) printf("\nAuto re-scan in 30 seconds\n"); + else printf("Press O to view/cycle through the access points\n\n"); + + + if (ap == 0) + { + int x; + for (x=0;x (30*60)) loop = 0; // auto-rescan + } + } + } +} + +int net_thread(SceSize args, void *argp) +{ + int ret; + struct ScanData *pScan = NULL; + int count; + + printf("Please wait, performing WLAN AP scan...\n"); + ret = sceNetInit(0x20000, 0x20, 0x1000, 0x20, 0x1000); + if(ret < 0) + { + printf("Error initialising network lib %08X\n", ret); + goto error; + } + + ret = -1; + while(ret < 0) + { + ret = sceWlanDevAttach(); + + /* If returns a error which indicates it isn't ready */ + if(ret == 0x80410D0E) + { + sceKernelDelayThread(1000000); + } + else if(ret < 0) + { + printf("Error attaching to wlan device %08X\n", ret); + goto error; + } + } + + pScan = do_scan(&count); + while (pScan != NULL) + { + start_ui(pScan, count); + + printf("\n\nPlease wait, performing WLAN AP scan...\n"); + pScan = do_scan(&count); + } + +error: + sceWlanDevDetach(); + sceNetTerm(); + + return 0; +} + +/* Simple thread */ +int main(int argc, char **argv) +{ + SceUID thid; + + SetupCallbacks(); + + pspDebugScreenInit(); + + if(pspSdkLoadInetModules() < 0) + { + printf("Error, could not load inet modules\n"); + sceKernelSleepThread(); + } + + /* Create a user thread to do the real work */ + thid = sceKernelCreateThread("net_thread", net_thread, 0x18, 0x10000, PSP_THREAD_ATTR_USER, NULL); + if(thid < 0) + { + printf("Error, could not create thread\n"); + sceKernelSleepThread(); + } + + sceKernelStartThread(thid, 0, NULL); + + sceKernelExitDeleteThread(0); + + return 0; +} diff --git a/src/samples/power/Makefile.sample b/src/samples/power/Makefile.sample new file mode 100644 index 00000000..ac3a69a5 --- /dev/null +++ b/src/samples/power/Makefile.sample @@ -0,0 +1,12 @@ +PSPSDK = $(shell psp-config --pspsdk-path) +PSPLIBSDIR = $(PSPSDK)/.. +TARGET = powersample +OBJS = main.o +LIBS = -lpsppower + + +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/power/main.c b/src/samples/power/main.c new file mode 100644 index 00000000..a85ecc43 --- /dev/null +++ b/src/samples/power/main.c @@ -0,0 +1,190 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Sample to demonstrate proper use of the power library + * + * Copyright (c) 2005 John Kelley + * + * $Id: main.c 1869 2006-04-09 14:21:59Z tyranid $ + */ +#include +#include +#include +#include +#include +#include +#include + +/* Define the module info section */ +PSP_MODULE_INFO("PowerTest", 0, 0, 71); + +char powerCBMessage[256]; + +/* Define printf, just to make typing easier */ +#define printf pspDebugScreenPrintf + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + sceKernelExitGame(); + + return 0; +} + +/* Power Callback */ +int power_callback(int unknown, int pwrflags, void *common) +{ + /* check for power switch and suspending as one is manual and the other automatic */ + if (pwrflags & PSP_POWER_CB_POWER_SWITCH || pwrflags & PSP_POWER_CB_SUSPENDING) { + sprintf(powerCBMessage, + "first arg: 0x%08X, flags: 0x%08X: suspending\n", unknown, pwrflags); + } else if (pwrflags & PSP_POWER_CB_RESUMING) { + sprintf(powerCBMessage, + "first arg: 0x%08X, flags: 0x%08X: resuming from suspend mode\n", + unknown, pwrflags); + } else if (pwrflags & PSP_POWER_CB_RESUME_COMPLETE) { + sprintf(powerCBMessage, + "first arg: 0x%08X, flags: 0x%08X: resume complete\n", unknown, pwrflags); + } else if (pwrflags & PSP_POWER_CB_STANDBY) { + sprintf(powerCBMessage, + "first arg: 0x%08X, flags: 0x%08X: entering standby mode\n", unknown, pwrflags); + } else { + sprintf(powerCBMessage, "first arg: 0x%08X, flags: 0x%08X: Unhandled power event\n", unknown, pwrflags); + } + sceDisplayWaitVblankStart(); + + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + cbid = sceKernelCreateCallback("Power Callback", power_callback, NULL); + scePowerRegisterCallback(0, cbid); + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0); + if (thid >= 0) + sceKernelStartThread(thid, 0, 0); + return thid; +} + +/* main routine */ +int main(int argc, char *argv[]) +{ + SceCtrlData pad; + int i = 0; + int powerLocked = 0; + int powerTicks = 0; + u32 oldButtons = 0; + int batteryLifeTime = 0; + + //init screen and callbacks + pspDebugScreenInit(); + pspDebugScreenClear(); + SetupCallbacks(); + + // Setup Pad + sceCtrlSetSamplingCycle(0); + sceCtrlSetSamplingMode(0); + + //fetch and print out power and battery information + for (;;) { + /* fix so the screen lines up right if the battery disappears */ + if (!scePowerIsBatteryExist()) { + pspDebugScreenClear(); + } + + pspDebugScreenSetXY(0, 0); + printf("PSP Power Sample v1.0 by John_K\n\n"); + sceCtrlReadBufferPositive(&pad, 1); + + printf("External Power: %s\n", scePowerIsPowerOnline()? "yes" : "no "); + printf("%-14s: %s\n", "Battery", scePowerIsBatteryExist()? "present" : "absent "); + + if (scePowerIsBatteryExist()) { + printf("%-14s: %s\n", "Low Charge", scePowerIsLowBattery()? "yes" : "no "); + printf("%-14s: %s\n", "Charging", scePowerIsBatteryCharging()? "yes" : "no "); + batteryLifeTime = scePowerGetBatteryLifeTime(); + printf("%-14s: %d%% (%02dh%02dm) \n", "Charge", + scePowerGetBatteryLifePercent(), batteryLifeTime/60, batteryLifeTime-(batteryLifeTime/60*60)); + printf("%-14s: %0.3fV\n", "Volts", (float) scePowerGetBatteryVolt() / 1000.0); + printf("%-14s: %d deg C\n", "Battery Temp", scePowerGetBatteryTemp()); + } else + printf("Battery stats unavailable\n"); + + printf("%-14s: %d mHz\n", "CPU Speed", scePowerGetCpuClockFrequency()); + printf("%-14s: %d mHz\n", "Bus Speed", scePowerGetBusClockFrequency()); + printf("%-14s: %s \n", "Power Switch", powerLocked == 0 ? "unlocked" : "locked"); + printf("%-14s: %s \n", "Send Ticks", powerTicks == 1 ? "yes" : "no"); + printf("\nPress X to switch CPU between 333 and 222 mHz\n"); + printf("Press O to toggle power switch lock\n"); + printf("Press [] to toggle sending power ticks\n"); + //send powerTicks if enabled + if (powerTicks == 1) + if (scePowerTick(0) != 0) + printf("Error calling scePowerTick(0)\n"); + + //only check buttons if they've changed since last frame + if (oldButtons != pad.Buttons) { + //check to see if the user pressed X to toggle CPU speed + if (pad.Buttons & PSP_CTRL_CROSS) { + if (i == 0) { + i = scePowerSetClockFrequency(333, 333, 166); + if (i == 0) { + i = 1; + } else { + printf("\nCould not set CPU to 333mHz (0x%08X)\n", i); + i = 0; + } + } else { + i = scePowerSetClockFrequency(222, 222, 111); + if (i != 0) { + printf("\nCould not set CPU to 222mHz (0x%08X)\n", i); + i = 1; + } + } + } + //check to see if the user pressed O to toggle power locking + if (pad.Buttons & PSP_CTRL_CIRCLE) { + if (powerLocked == 0) { + if (scePowerLock(0) == 0) + powerLocked = 1; + else + printf("Error locking power switch\n"); + } else { + if (scePowerUnlock(0) == 0) + powerLocked = 0; + else + printf("Error unlocking power switch\n"); + } + } + //check to see if the user pressed [] to toggle PowerTicks + if (pad.Buttons & PSP_CTRL_SQUARE) + powerTicks = powerTicks == 1 ? 0 : 1; + } + + pspDebugScreenSetXY(0, 30); + printf("Power callback messages appear below:\n%s\n", powerCBMessage); + oldButtons = pad.Buttons; + + sceDisplayWaitVblankStart(); + } + + sceKernelSleepThread(); + sceKernelExitGame(); + + return 0; +} diff --git a/src/samples/prx/prx_loader/Makefile.sample b/src/samples/prx/prx_loader/Makefile.sample new file mode 100644 index 00000000..f8e5a4b5 --- /dev/null +++ b/src/samples/prx/prx_loader/Makefile.sample @@ -0,0 +1,20 @@ +TARGET = prxloader +OBJS = main.o MyLib.o + +USE_PSPSDK_LIBC = 1 + +INCDIR = +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = + +LIBS = + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Sample PRX Loader + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/prx/prx_loader/MyLib.S b/src/samples/prx/prx_loader/MyLib.S new file mode 100644 index 00000000..e895dc17 --- /dev/null +++ b/src/samples/prx/prx_loader/MyLib.S @@ -0,0 +1,7 @@ + .set noreorder + +#include "pspstub.s" + + STUB_START "MyLib",0x00090000,0x00010005 + STUB_FUNC 0x563FF2B2,getModuleInfo + STUB_END diff --git a/src/samples/prx/prx_loader/main.c b/src/samples/prx/prx_loader/main.c new file mode 100644 index 00000000..6127df65 --- /dev/null +++ b/src/samples/prx/prx_loader/main.c @@ -0,0 +1,131 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Basic harness for loading prxes (for proving a point) + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: main.c 1095 2005-09-27 21:02:16Z jim $ + */ +#include +#include +#include +#include +#include + +PSP_MODULE_INFO("PRXLOADER", 0x1000, 1, 1); +/* Define the main thread's attribute value (optional) */ +PSP_MAIN_THREAD_ATTR(0); + +/* Define printf, just to make typing easier */ +#define printf pspDebugScreenPrintf + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *arg) +{ + sceKernelExitGame(); + + return 0; +} + +/* Callback thread */ +void CallbackThread(void *arg) +{ + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + + sceKernelSleepThreadCB(); +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + + thid = sceKernelCreateThread("update_thread", (void*) CallbackThread, 0x11, 0xFA0, 0xa0000000, 0); + if(thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} + +SceUID load_module(const char *path, int flags, int type) +{ + SceKernelLMOption option; + SceUID mpid; + + /* If the type is 0, then load the module in the kernel partition, otherwise load it + in the user partition. */ + if (type == 0) { + mpid = 1; + } else { + mpid = 2; + } + + memset(&option, 0, sizeof(option)); + option.size = sizeof(option); + option.mpidtext = mpid; + option.mpiddata = mpid; + option.position = 0; + option.access = 1; + + return sceKernelLoadModule(path, flags, type > 0 ? &option : NULL); +} + +/* Imported function */ +void *getModuleInfo(void); + +int main(void) +{ + SceUID modid; + SceModule *mod; + int i; + int ret; + int fd; + + pspDebugScreenInit(); + + /* Install all our funky err thingamybobs */ + pspDebugInstallKprintfHandler(NULL); + pspDebugInstallErrorHandler(NULL); + pspDebugInstallStdoutHandler(pspDebugScreenPrintData); + pspSdkInstallNoPlainModuleCheckPatch(); + SetupCallbacks(); + + /* Start mymodule.prx and dump its information */ + printf("\nStart my module\n"); + modid = load_module("ms0:/mymodule.prx", 0, 0); + printf("Module ID %08X\n", modid); + mod = sceKernelFindModuleByUID(modid); + printf("mod %p\n", mod); + if(mod != NULL) + { + printf("Attr %04X, Version %x.%x\n", mod->attribute, mod->version[0], mod->version[1]); + printf("Name %s\n", mod->modname); + printf("Text %08X, Size %08X, Data Size %08X\n", mod->text_addr, mod->text_size, mod->data_size); + printf("Entry Addr %08X\n", mod->entry_addr); + printf("Stub %p %08X, Ent %p %08X\n", mod->stub_top, mod->stub_size, mod->ent_top, mod->ent_size); + for(i = 0; i < mod->nsegment; i++) + { + printf("Segment[%d] %08X %08X\n", i, mod->segmentaddr[i], mod->segmentsize[i]); + } + + ret = sceKernelStartModule(modid, 0, NULL, &fd, NULL); + + /* Let's test the module's exports */ + printf("Module Info %p\n", getModuleInfo()); + } + + /* Let's bug out */ + sceKernelExitDeleteThread(0); + + return 0; +} diff --git a/src/samples/prx/testprx/Makefile.sample b/src/samples/prx/testprx/Makefile.sample new file mode 100644 index 00000000..6bf81847 --- /dev/null +++ b/src/samples/prx/testprx/Makefile.sample @@ -0,0 +1,19 @@ +TARGET = mymodule +OBJS = main.o + +# Define to build this as a prx (instead of a static elf) +BUILD_PRX=1 +# Define the name of our custom exports (minus the .exp extension) +PRX_EXPORTS=exports.exp + +USE_PSPSDK_LIBC = 1 + +INCDIR = +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/prx/testprx/exports.exp b/src/samples/prx/testprx/exports.exp new file mode 100644 index 00000000..e5a4bc4a --- /dev/null +++ b/src/samples/prx/testprx/exports.exp @@ -0,0 +1,16 @@ +# Define the exports for the prx +PSP_BEGIN_EXPORTS + +# These four lines are mandatory (although you can add other functions like module_stop) +# syslib is a psynonym for the single mandatory export. +PSP_EXPORT_START(syslib, 0, 0x8000) +PSP_EXPORT_FUNC_HASH(module_start) +PSP_EXPORT_VAR_HASH(module_info) +PSP_EXPORT_END + +# Export our function +PSP_EXPORT_START(MyLib, 0, 0x0001) +PSP_EXPORT_FUNC_HASH(getModuleInfo) +PSP_EXPORT_END + +PSP_END_EXPORTS diff --git a/src/samples/prx/testprx/main.c b/src/samples/prx/testprx/main.c new file mode 100644 index 00000000..bc7ebe1d --- /dev/null +++ b/src/samples/prx/testprx/main.c @@ -0,0 +1,39 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Simple PRX example. + * + * Copyright (c) 2005 James Forshaw + * + * $Id: main.c 1531 2005-12-07 18:27:12Z tyranid $ + */ +#include +#include + +PSP_MODULE_INFO("TESTPRX", 0x1000, 1, 1); + +#define WELCOME_MESSAGE "Hello from the PRX\n" + +int main(int argc, char **argv) +{ + int i; + + printf(WELCOME_MESSAGE); + + for(i = 0; i < argc; i++) + { + printf("Arg %d: %s\n", i, argv[i]); + } + + sceKernelSleepThread(); + + return 0; +} + +/* Exported function returns the address of module_info */ +void* getModuleInfo(void) +{ + return (void *) &module_info; +} diff --git a/src/samples/savedata/decrypt/Makefile.sample b/src/samples/savedata/decrypt/Makefile.sample new file mode 100644 index 00000000..c75dd769 --- /dev/null +++ b/src/samples/savedata/decrypt/Makefile.sample @@ -0,0 +1,20 @@ +TARGET = main +OBJS = main.o decrypt.o + +INCDIR = +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LIBS = -lpspchnnlsv +LDFLAGS = + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Save Decrypt Sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak + +main.c : decrypt.h +decrypt.c : decrypt.h diff --git a/src/samples/savedata/decrypt/README.txt b/src/samples/savedata/decrypt/README.txt new file mode 100644 index 00000000..6e82702f --- /dev/null +++ b/src/samples/savedata/decrypt/README.txt @@ -0,0 +1,5 @@ +This sample uses the sceChnnlsv module directly to do savegame +decryption. It currently works only in VSH mode (e.g., via the TIFF +exploit). It can handle both old and new format saves (SaveParam +structure sizes 0x5c8, 0x5dc, 0x600). New format saves require a +game-specific encryption key. diff --git a/src/samples/savedata/decrypt/decrypt.c b/src/samples/savedata/decrypt/decrypt.c new file mode 100644 index 00000000..013152eb --- /dev/null +++ b/src/samples/savedata/decrypt/decrypt.c @@ -0,0 +1,162 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * decrypt.c - Decryption routines using sceChnnlsv + * + * Copyright (c) 2005 Jim Paris + * Coypright (c) 2005 psp123 + * + * $Id: decrypt.c 1562 2005-12-10 20:52:45Z jim $ + */ + +#include "decrypt.h" +#include +#include +#include +#include +#include + +unsigned int align16(unsigned int v) +{ + return ((v + 0xF) >> 4) << 4; +} + +/* Read, decrypt, and write a savedata file. See main.c for example usage. */ +int decrypt_file(const char *decrypted_filename, + const char *encrypted_filename, + const unsigned char *gamekey) +{ + FILE *in, *out; + int len, aligned_len; + unsigned char *data, *cryptkey; + int retval; + + /* Open file and get size */ + + if ((in = fopen(encrypted_filename, "r")) == NULL) { + retval = -1; + goto out; + } + + fseek(in, 0, SEEK_END); + len = ftell(in); + fseek(in, 0, SEEK_SET); + + if (len <= 0) { + retval = -2; + goto out1; + } + + /* Allocate buffers */ + + aligned_len = align16(len); + + if ((data = (unsigned char *) memalign(0x10, aligned_len)) == NULL) { + retval = -3; + goto out1; + } + + if ((cryptkey = (unsigned char *) memalign(0x10, 0x10)) == NULL) { + retval = -4; + goto out2; + } + + /* Fill buffers */ + + if (gamekey != NULL) + memcpy(cryptkey, gamekey, 0x10); + + memset(data + len, 0, aligned_len - len); + if (fread(data, 1, len, in) != len) { + retval = -5; + goto out3; + } + + /* Do the decryption */ + + if ((retval = decrypt_data( gamekey ? 3 : 1, + data, &len, &aligned_len, + gamekey ? cryptkey : NULL)) < 0) { + retval -= 100; + goto out3; + } + + /* Write the data out. decrypt_data has set len correctly. */ + + if ((out = fopen(decrypted_filename, "w")) == NULL) { + retval = -6; + goto out3; + } + + if (fwrite(data, 1, len, out) != len) { + retval = -7; + goto out4; + } + + /* All done. Return file length. */ + retval = len; + out4: + fclose(out); + out3: + free(cryptkey); + out2: + free(data); + out1: + fclose(in); + out: + return retval; +} + +/* Do the actual hardware decryption. + mode is 3 for saves with a cryptkey, or 1 otherwise + data, dataLen, and cryptkey must be multiples of 0x10. + cryptkey is NULL if mode == 1. +*/ +int decrypt_data(unsigned int mode, + unsigned char *data, + int *dataLen, + int *alignedLen, + unsigned char *cryptkey) +{ + pspChnnlsvContext1 ctx1; + pspChnnlsvContext2 ctx2; + + /* Need a 16-byte IV plus some data */ + if (*alignedLen <= 0x10) + return -1; + *dataLen -= 0x10; + *alignedLen -= 0x10; + + /* Set up buffers */ + memset(&ctx1, 0, sizeof(pspChnnlsvContext1)); + memset(&ctx2, 0, sizeof(pspChnnlsvContext2)); + + /* Perform the magic */ + if (sceChnnlsv_E7833020(&ctx1, mode) < 0) + return -2; + if (sceChnnlsv_ABFDFC8B(&ctx2, mode, 2, data, cryptkey) < 0) + return -3; + if (sceChnnlsv_F21A1FCA(&ctx1, data, 0x10) < 0) + return -4; + if (sceChnnlsv_F21A1FCA(&ctx1, data + 0x10, *alignedLen) < 0) + return -5; + if (sceChnnlsv_850A7FA1(&ctx2, data + 0x10, *alignedLen) < 0) + return -6; + + /* Verify that it decrypted correctly */ + if (sceChnnlsv_21BE78B4(&ctx2) < 0) + return -7; + + /* If desired, a new file hash from this PSP can be computed now: + if (sceChnnlsv_C4C494F8(ctx1, newhash, cryptkey) < 0) + return -8; + */ + + /* The decrypted data starts at data + 0x10, so shift it back. */ + memmove(data, data + 0x10, *dataLen); + + /* All done */ + return 0; +} diff --git a/src/samples/savedata/decrypt/decrypt.h b/src/samples/savedata/decrypt/decrypt.h new file mode 100644 index 00000000..5bb48c40 --- /dev/null +++ b/src/samples/savedata/decrypt/decrypt.h @@ -0,0 +1,30 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * decrypt.h - Declarations for functions in decrypt.c + * + * Copyright (c) 2005 Jim Paris + * Coypright (c) 2005 psp123 + * + * $Id: decrypt.h 1562 2005-12-10 20:52:45Z jim $ + */ + +#include + +/* Detect the samegame format and decrypt it. See main.c for an example. */ +int decrypt_file(const char *decrypted_filename, + const char *encrypted_filename, + const unsigned char *gamekey); + +/* Do the actual hardware decryption. + mode is 3 for saves with a cryptkey, or 1 otherwise. + data, alignedLen, and cryptkey must be multiples of 0x10. + cryptkey is NULL if mode == 1. +*/ +int decrypt_data(unsigned int mode, + unsigned char *data, + int *dataLen, + int *alignedLen, + unsigned char *cryptkey); diff --git a/src/samples/savedata/decrypt/main.c b/src/samples/savedata/decrypt/main.c new file mode 100644 index 00000000..0a97ff32 --- /dev/null +++ b/src/samples/savedata/decrypt/main.c @@ -0,0 +1,100 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Sample to demonstrate savedata decryption using sceChnnlsv + * + * Copyright (c) 2005 Jim Paris + * Coypright (c) 2005 psp123 + * + * $Id: main.c 1996 2006-09-05 01:31:55Z jim $ + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "decrypt.h" + +PSP_MODULE_INFO("SaveDecrypt", 0, 1, 1); + +#define printf pspDebugScreenPrintf + +#if 0 + /* Old format save with no key, supported by 1.0+ firmware */ + const char *decrypted = "ms0:/PLAIN.BIN"; + const char *encrypted = "ms0:/PSP/SAVEDATA/DATA111110000/DATA.BIN"; + const unsigned char *gamekey = NULL; +#else + /* New format save with a key, supported by 2.0+ firmware */ + const char *decrypted = "ms0:/PLAIN.BIN"; + const char *encrypted = "ms0:/PSP/SAVEDATA/DATA222220000/DATA.BIN"; + const unsigned char gamekey[] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0xFA, 0xCA, 0xDE, 0x00, 0xDE, 0xAD, 0xBE, 0xEF + }; +#endif + +int waitbutton(int mask) { + SceCtrlData paddata; + do { + sceDisplayWaitVblankStart(); + sceCtrlReadBufferPositive(&paddata, 1); + } while((paddata.Buttons & mask)); + do { + sceDisplayWaitVblankStart(); + sceCtrlReadBufferPositive(&paddata, 1); + } while(!(paddata.Buttons & mask)); + return paddata.Buttons; +} + +int main(int argc, char *argv[]) +{ + int i, ret; + + pspDebugScreenInit(); + sceCtrlSetSamplingCycle(0); + sceCtrlSetSamplingMode(PSP_CTRL_MODE_DIGITAL); + + printf("Save Decrypt Sample\n"); + printf("by Jim Paris and psp123\n\n"); + + printf("Will decrypt: %s\n", encrypted); + printf(" Using key:"); + if(gamekey) { + for (i = 0; i < 0x10; i++) + printf(" %02x", gamekey[i]); + } else { + printf(" none"); + } + printf("\n\n"); + printf(" Output file: %s\n\n", decrypted); + printf("Press X to continue, or O to quit.\n\n"); + + if (waitbutton(PSP_CTRL_CROSS | PSP_CTRL_CIRCLE) & PSP_CTRL_CIRCLE) + goto out; + + printf("Working...\n\n"); + + ret = decrypt_file(decrypted, encrypted, gamekey); + if(ret < 0) { + printf("Error: decrypt_file() returned %d\n\n", ret); + } else { + printf("Successfully wrote %d bytes to\n", ret); + printf(" %s\n\n", decrypted); + } + + printf("Press any button to quit\n"); + waitbutton(-1); + + out: + sceKernelExitGame(); + return 0; +} diff --git a/src/samples/savedata/encrypt/Makefile.sample b/src/samples/savedata/encrypt/Makefile.sample new file mode 100644 index 00000000..8a4b43a8 --- /dev/null +++ b/src/samples/savedata/encrypt/Makefile.sample @@ -0,0 +1,23 @@ +TARGET = main +OBJS = main.o encrypt.o hash.o psf.o + +INCDIR = +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LIBS = -lpspchnnlsv +LDFLAGS = + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Save Encrypt Sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak + +main.c : encrypt.h +encrypt.c : encrypt.h hash.h +hash.c : hash.h psf.h +psf.c : psf.h + diff --git a/src/samples/savedata/encrypt/README.txt b/src/samples/savedata/encrypt/README.txt new file mode 100644 index 00000000..1516b6a5 --- /dev/null +++ b/src/samples/savedata/encrypt/README.txt @@ -0,0 +1,5 @@ +This sample uses the sceChnnlsv module directly to do savegame +encryption. It currently works only in VSH mode (e.g., via the TIFF +exploit). It can handle both old and new format saves (SaveParam +structure sizes 0x5c8, 0x5dc, 0x600). New format saves require a +game-specific encryption key. diff --git a/src/samples/savedata/encrypt/encrypt.c b/src/samples/savedata/encrypt/encrypt.c new file mode 100644 index 00000000..13afd87f --- /dev/null +++ b/src/samples/savedata/encrypt/encrypt.c @@ -0,0 +1,230 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * encrypt.c - Encryption routines using sceChnnlsv + * + * Copyright (c) 2005 Jim Paris + * Coypright (c) 2005 psp123 + * + * $Id: encrypt.c 1560 2005-12-10 01:16:32Z jim $ + */ + +#include "encrypt.h" +#include "hash.h" +#include +#include +#include +#include +#include + +static inline int align16(unsigned int v) +{ + return ((v + 0xF) >> 4) << 4; +} + +int fopen_getsize(const char *filename, FILE **fd, int *size) +{ + if ((*fd = fopen(filename, "r")) == NULL) + return -1; + + fseek(*fd, 0, SEEK_END); + *size = ftell(*fd); + fseek(*fd, 0, SEEK_SET); + + if (*size <= 0) { + fclose(*fd); + return -2; + } + + return 0; +} + +/* Encrypt the given plaintext file, and update the message + authentication hashes in the param.sfo. The data_filename is + usually the final component of encrypted_filename, e.g. "DATA.BIN". + See main.c for an example of usage. */ +int encrypt_file(const char *plaintext_filename, + const char *encrypted_filename, + const char *data_filename, + const char *paramsfo_filename, + const unsigned char *gamekey) +{ + FILE *in = NULL, *out = NULL, *sfo = NULL; + unsigned char *data = NULL, *cryptkey = NULL, *hash = NULL; + unsigned char paramsfo[0x1330]; + int len, aligned_len, tmp; + int retval; + + /* Open plaintext and param.sfo files and get size */ + + if (fopen_getsize(plaintext_filename, &in, &len) < 0) { + retval = -1; + goto out; + } + + if (fopen_getsize(paramsfo_filename, &sfo, &tmp) < 0) { + retval = -2; + goto out; + } + + /* Verify size of param.sfo; all known saves use this size */ + + if (tmp != 0x1330) { + retval = -3; + goto out; + } + + /* Allocate buffers. data has 0x10 bytes extra for the IV. */ + + aligned_len = align16(len); + + if ((data = + (unsigned char *) memalign(0x10, aligned_len + 0x10)) == NULL) { + retval = -4; + goto out; + } + + if ((cryptkey = (unsigned char *) memalign(0x10, 0x10)) == NULL) { + retval = -5; + goto out; + } + + if ((hash = (unsigned char *) memalign(0x10, 0x10)) == NULL) { + retval = -6; + goto out; + } + + /* Fill buffers. */ + + memset(data + len, 0, aligned_len - len); + if (fread(data, 1, len, in) != len) { + retval = -7; + goto out; + } + + if (fread(paramsfo, 1, 0x1330, sfo) != 0x1330) { + retval = -8; + goto out; + } + + if (gamekey != NULL) + memcpy(cryptkey, gamekey, 0x10); + + /* Do the encryption */ + + if ((retval = encrypt_data( gamekey ? 3 : 1, + data, + &len, &aligned_len, + hash, + gamekey ? cryptkey : NULL)) < 0) { + retval -= 1000; + goto out; + } + + /* Update the param.sfo hashes */ + + if ((retval = update_hashes(paramsfo, 0x1330, + data_filename, hash, + gamekey ? 3 : 1)) < 0) { + retval -= 2000; + goto out; + } + + /* Write the data to the file. encrypt_data has already set len. */ + + if ((out = fopen(encrypted_filename, "w")) == NULL) { + retval = -9; + goto out; + } + + if (fwrite(data, 1, len, out) != len) { + retval = -10; + goto out; + } + + /* Reopen param.sfo, and write the updated copy out. */ + + fclose(sfo); + if ((sfo = fopen(paramsfo_filename, "w")) == NULL) { + retval = -11; + goto out; + } + + if (fwrite(paramsfo, 1, 0x1330, sfo) != 0x1330) { + retval = -12; + goto out; + } + + /* All done. Return file length. */ + + retval = len; + + out: + if(out) fclose(out); + if(hash) free(hash); + if(cryptkey) free(cryptkey); + if(data) free(data); + if(sfo) fclose(sfo); + if(in) fclose(in); + + return retval; +} + +/* Do the actual hardware encryption. + mode is 3 for saves with a cryptkey, or 1 otherwise + data, dataLen, and cryptkey must be multiples of 0x10. + cryptkey is NULL if mode == 1. +*/ +int encrypt_data(unsigned int mode, + unsigned char *data, + int *dataLen, + int *alignedLen, + unsigned char *hash, + unsigned char *cryptkey) +{ + pspChnnlsvContext1 ctx1; + pspChnnlsvContext2 ctx2; + + /* Make room for the IV in front of the data. */ + memmove(data + 0x10, data, *alignedLen); + + /* Set up buffers */ + memset(&ctx1, 0, sizeof(pspChnnlsvContext1)); + memset(&ctx2, 0, sizeof(pspChnnlsvContext2)); + memset(hash, 0, 0x10); + memset(data, 0, 0x10); + + /* Build the 0x10-byte IV and setup encryption */ + if (sceChnnlsv_ABFDFC8B(&ctx2, mode, 1, data, cryptkey) < 0) + return -1; + if (sceChnnlsv_E7833020(&ctx1, mode) < 0) + return -2; + if (sceChnnlsv_F21A1FCA(&ctx1, data, 0x10) < 0) + return -3; + if (sceChnnlsv_850A7FA1(&ctx2, data + 0x10, *alignedLen) < 0) + return -4; + + /* Clear any extra bytes left from the previous steps */ + memset(data + 0x10 + *dataLen, 0, *alignedLen - *dataLen); + + /* Encrypt the data */ + if (sceChnnlsv_F21A1FCA(&ctx1, data + 0x10, *alignedLen) < 0) + return -5; + + /* Verify encryption */ + if (sceChnnlsv_21BE78B4(&ctx2) < 0) + return -6; + + /* Build the file hash from this PSP */ + if (sceChnnlsv_C4C494F8(&ctx1, hash, cryptkey) < 0) + return -7; + + /* Adjust sizes to account for IV */ + *alignedLen += 0x10; + *dataLen += 0x10; + + /* All done */ + return 0; +} diff --git a/src/samples/savedata/encrypt/encrypt.h b/src/samples/savedata/encrypt/encrypt.h new file mode 100644 index 00000000..63780af8 --- /dev/null +++ b/src/samples/savedata/encrypt/encrypt.h @@ -0,0 +1,36 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * encrypt.h - Declarations for functions in encrypt.c + * + * Copyright (c) 2005 Jim Paris + * Coypright (c) 2005 psp123 + * + * $Id: encrypt.h 1559 2005-12-10 01:10:11Z jim $ + */ + +#include + +/* Encrypt the given plaintext file, and update the message + authentication hashes in the param.sfo. The data_filename is + usually the final component of encrypted_filename, e.g. "DATA.BIN". + See main.c for an example of usage. */ +int encrypt_file(const char *plaintext_filename, + const char *encrypted_filename, + const char *data_filename, + const char *paramsfo_filename, + const unsigned char *gamekey); + +/* Do the actual hardware encryption. + mode is 3 for saves with a cryptkey, or 1 otherwise. + data, alignedLen, cryptkey, and hash must be multiples of 0x10. + cryptkey is NULL if mode == 1. +*/ +int encrypt_data(unsigned int mode, + unsigned char *data, + int *dataLen, + int *alignedLen, + unsigned char *hash, + unsigned char *cryptkey); diff --git a/src/samples/savedata/encrypt/hash.c b/src/samples/savedata/encrypt/hash.c new file mode 100644 index 00000000..52afa43d --- /dev/null +++ b/src/samples/savedata/encrypt/hash.c @@ -0,0 +1,128 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * hash.c - Hashing routines using sceChnnlsv + * + * Copyright (c) 2005 Jim Paris + * Coypright (c) 2005 psp123 + * + * $Id: hash.c 1560 2005-12-10 01:16:32Z jim $ + */ + +#include "hash.h" +#include "psf.h" +#include +#include +#include +#include +#include + +static inline int align16(unsigned int v) +{ + return ((v + 0xF) >> 4) << 4; +} + +/* Update the hashes in the param.sfo data, using + the given file hash, and by computing the param.sfo hashes. + filehash must be a multiple of 16 bytes, and is reused to + store other hashes. The filename is e.g. "DATA.BIN". */ +int update_hashes(unsigned char *data, + int len, + const char *filename, + unsigned char *filehash, + int encryptmode) +{ + int alignedLen = align16(len); + unsigned char *datafile, *savedata_params; + int listLen, paramsLen; + int ret; + + /* Locate SAVEDATA_PARAM section in the param.sfo. */ + if ((ret = find_psf_section("SAVEDATA_PARAMS", data, 0x1330, + &savedata_params, ¶msLen)) < 0) { + return ret - 100; + } + + /* Locate the pointer for this DATA.BIN equivalent */ + if ((ret = find_psf_section("SAVEDATA_FILE_LIST", data, 0x1330, + &datafile, &listLen)) < 0) { + return ret - 200; + } + + if ((ret = find_psf_datafile(filename, datafile, + listLen, &datafile)) < 0) { + return ret - 300; + } + + /* Check minimum sizes based on where we want to write */ + if ((listLen < 0x20) || (paramsLen < 0x80)) { + return -1; + } + + /* Clear params and insert file hash */ + memset(savedata_params, 0, paramsLen); + memcpy(datafile + 0x0D, filehash, 0x10); + + /* Compute 11D0 hash over entire file */ + if ((ret = build_hash(filehash, data, len, alignedLen, + (encryptmode & 2) ? 4 : 2, NULL)) < 0) { + return ret - 400; + } + + /* Copy 11D0 hash to param.sfo and set flag indicating it's there */ + memcpy(savedata_params + 0x20, filehash, 0x10); + *savedata_params |= 0x01; + + /* If new encryption mode, compute and insert the 1220 hash. */ + if (encryptmode & 2) { + + /* Enable the hash bit first */ + *savedata_params |= 0x20; + + if ((ret = build_hash(filehash, data, len, alignedLen, + 3, 0)) < 0) { + return ret - 500; + } + memcpy(savedata_params + 0x70, filehash, 0x10); + } + + /* Compute and insert the 11C0 hash. */ + if ((ret = build_hash(filehash, data, len, alignedLen, 1, 0)) < 0) { + return ret - 600; + } + memcpy(savedata_params + 0x10, filehash, 0x10); + + /* All done. */ + return 0; +} + +/* Build a single hash using the given data and mode. + data and alignedLen must be multiples of 0x10. + cryptkey is NULL for savedata. */ +int build_hash(unsigned char *output, + unsigned char *data, + unsigned int len, + unsigned int alignedLen, + int mode, + unsigned char *cryptkey) +{ + pspChnnlsvContext1 ctx1; + + /* Set up buffers */ + memset(&ctx1, 0, sizeof(pspChnnlsvContext1)); + memset(output, 0, 0x10); + memset(data + len, 0, alignedLen - len); + + /* Perform the magic */ + if (sceChnnlsv_E7833020(&ctx1, mode & 0xFF) < 0) + return -1; + if (sceChnnlsv_F21A1FCA(&ctx1, data, alignedLen) < 0) + return -2; + if (sceChnnlsv_C4C494F8(&ctx1, output, cryptkey) < 0) + return -3; + + /* All done. */ + return 0; +} diff --git a/src/samples/savedata/encrypt/hash.h b/src/samples/savedata/encrypt/hash.h new file mode 100644 index 00000000..978627a6 --- /dev/null +++ b/src/samples/savedata/encrypt/hash.h @@ -0,0 +1,34 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * hash.h - Declarations for functions in hash.c + * + * Copyright (c) 2005 Jim Paris + * Coypright (c) 2005 psp123 + * + * $Id: hash.h 1559 2005-12-10 01:10:11Z jim $ + */ + +#include + +/* Update the hashes in the param.sfo data, using + the given file hash, and by computing the param.sfo hashes. + filehash must be a multiple of 16 bytes, and is reused to + store other hashes. The filename is e.g. "DATA.BIN". */ +int update_hashes(unsigned char *data, + int len, + const char *filename, + unsigned char *filehash, + int encryptmode); + +/* Build a single hash using the given data and mode. + data, and alignedLen must be multiples of 0x10. + cryptkey is NULL for savedata.*/ +int build_hash(unsigned char *output, + unsigned char *data, + unsigned int len, + unsigned int alignedLen, + int mode, + unsigned char *cryptkey); diff --git a/src/samples/savedata/encrypt/main.c b/src/samples/savedata/encrypt/main.c new file mode 100644 index 00000000..273bb353 --- /dev/null +++ b/src/samples/savedata/encrypt/main.c @@ -0,0 +1,107 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Sample to demonstrate savedata encryption using sceChnnlsv + * + * Copyright (c) 2005 Jim Paris + * Coypright (c) 2005 psp123 + * + * $Id: main.c 1559 2005-12-10 01:10:11Z jim $ + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "encrypt.h" + +PSP_MODULE_INFO("SaveEncrypt", 0, 1, 1); + +#define printf pspDebugScreenPrintf + +#if 0 + /* Old format save with no key, supported by 1.0+ firmware */ + const char *plaintext = "ms0:/PLAIN.BIN"; + const char *encrypted = "ms0:/PSP/SAVEDATA/DATA111110000/DATA.BIN"; + const char *datafile = "DATA.BIN"; + const char *paramsfo = "ms0:/PSP/SAVEDATA/DATA111110000/PARAM.SFO"; + const unsigned char *gamekey = NULL; +#else + /* New format save with a key (GTA:LCS) */ + const char *plaintext = "ms0:/PLAIN.BIN"; + const char *encrypted = "ms0:/PSP/SAVEDATA/DATA222220000/DATA.BIN"; + const char *datafile = "DATA.BIN"; + const char *paramsfo = "ms0:/PSP/SAVEDATA/DATA222220000/PARAM.SFO"; + const unsigned char gamekey[] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0xFA, 0xCA, 0xDE, 0x00, 0xDE, 0xAD, 0xBE, 0xEF + }; +#endif + +int waitbutton(int mask) { + SceCtrlData paddata; + do { + sceDisplayWaitVblankStart(); + sceCtrlReadBufferPositive(&paddata, 1); + } while((paddata.Buttons & mask)); + do { + sceDisplayWaitVblankStart(); + sceCtrlReadBufferPositive(&paddata, 1); + } while(!(paddata.Buttons & mask)); + return paddata.Buttons; +} + +int main(int argc, char *argv[]) +{ + int i, ret; + + pspDebugScreenInit(); + sceCtrlSetSamplingCycle(0); + sceCtrlSetSamplingMode(PSP_CTRL_MODE_DIGITAL); + + printf("Save Encrypt Sample\n"); + printf("by Jim Paris and psp123\n\n"); + + printf(" Will encrypt: %s\n", plaintext); + printf(" Using key:"); + if(gamekey) { + for (i = 0; i < 0x10; i++) + printf(" %02x", gamekey[i]); + } else { + printf(" none"); + } + printf("\n\n"); + printf(" Output file: %s\n", encrypted); + printf("Update hashes: %s\n\n", paramsfo); + printf("Press X to continue, or O to quit.\n\n"); + + if (waitbutton(PSP_CTRL_CROSS | PSP_CTRL_CIRCLE) & PSP_CTRL_CIRCLE) + goto out; + + printf("Working...\n\n"); + + ret = encrypt_file(plaintext, encrypted, datafile, paramsfo, gamekey); + if(ret < 0) { + printf("Error: encrypt_file() returned %d\n\n", ret); + } else { + printf("Successfully wrote %d bytes to\n", ret); + printf(" %s\n", encrypted); + printf("and updated hashes in\n"); + printf(" %s\n\n", paramsfo); + } + + printf("Press any button to quit\n"); + waitbutton(-1); + + out: + sceKernelExitGame(); + return 0; +} diff --git a/src/samples/savedata/encrypt/psf.c b/src/samples/savedata/encrypt/psf.c new file mode 100644 index 00000000..5f68b1cc --- /dev/null +++ b/src/samples/savedata/encrypt/psf.c @@ -0,0 +1,114 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * psf.c - PSF parsing routines + * + * Copyright (c) 2005 Jim Paris + * Coypright (c) 2005 psp123 + * + * $Id: psf.c 1560 2005-12-10 01:16:32Z jim $ + */ + +#include "psf.h" +#include +#include +#include +#include +#include + +/* Find to the named section in the PSF file, and return an + absolute pointer to it and the section size. */ +int find_psf_section(const char *name, + unsigned char *data, + int dataLen, + unsigned char **location, + int *size) +{ + unsigned short int nameLoc; + int i, magicHead, strLoc, headLen, numSects; + int sectCurLen, sectBufLen, sectBufLoc, curPos; + + if (dataLen < 0x14) + return -1; + + /* Get the basics from the header */ + magicHead = *(unsigned int *)&data[0x00]; + strLoc = *(unsigned int *)&data[0x08]; + headLen = *(unsigned int *)&data[0x0C]; + numSects = *(unsigned int *)&data[0x10]; + + /* Do some error checking */ + if (magicHead != 0x46535000) + return -2; + + /* Verify strLoc is proper */ + if ((strLoc > headLen) || (strLoc >= dataLen)) + return -3; + + /* Verify headLen is proper */ + if (headLen >= dataLen) + return -4; + + /* Verify numSects is proper */ + if (numSects != ((strLoc - 0x14) / 0x10)) + return -5; + + /* Process all sections */ + for (i = 0; i < numSects; i++) + { + /* Get the curPos */ + curPos = 0x14 + (i * 0x10); + + /* Verify curPos is proper */ + if (curPos >= strLoc) + return -6; + + /* Get some basic info about this section */ + nameLoc = *(unsigned short *)&data[curPos]; + sectCurLen = *(unsigned short *)&data[curPos + 0x04]; + sectBufLen = *(unsigned short *)&data[curPos + 0x08]; + sectBufLoc = *(unsigned short *)&data[curPos + 0x0C]; + + /* Do some error checking */ + if ((nameLoc < dataLen) && (sectCurLen < dataLen) + && (sectBufLen < dataLen) && (sectBufLoc < dataLen)) + { + /* Check if this is the section we want */ + if (!stricmp((char *)&data[strLoc + nameLoc], name)) + { + /* Update the location and size */ + *location = &data[headLen + sectBufLoc]; + *size = sectBufLen; + return 0; + } + } + } + + /* Section was not found if it makes it here */ + return -7; +} + +/* Find the named file inside the FILE_LIST, and return + an absolute pointer to it. */ +int find_psf_datafile(const char *name, + unsigned char *filelist, + int size, + unsigned char **location) +{ + int i; + + /* Process all files */ + for (i = 0; (i + 0x0d) <= size; i += 0x20) + { + /* Check if this is the filename we want */ + if (!strncasecmp((char *)&filelist[i], name, 0x0d)) { + *location = &filelist[i]; + return 0; + } + } + + /* File was not found if it makes it here */ + return -1; +} diff --git a/src/samples/savedata/encrypt/psf.h b/src/samples/savedata/encrypt/psf.h new file mode 100644 index 00000000..261e241e --- /dev/null +++ b/src/samples/savedata/encrypt/psf.h @@ -0,0 +1,29 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * psf.h - Declarations for functions in psf.c + * + * Copyright (c) 2005 Jim Paris + * Coypright (c) 2005 psp123 + * + * $Id: psf.h 1559 2005-12-10 01:10:11Z jim $ + */ + +#include + +/* Find the named section in the PSF file, and return an + absolute pointer to it and the section size. */ +int find_psf_section(const char *name, + unsigned char *data, + int dataLen, + unsigned char **location, + int *size); + +/* Find the named file inside the FILE_LIST, and return + an absolute pointer to it. */ +int find_psf_datafile(const char *name, + unsigned char *filelist, + int size, + unsigned char **location); diff --git a/src/samples/savedata/utility/Makefile.sample b/src/samples/savedata/utility/Makefile.sample new file mode 100644 index 00000000..637743d0 --- /dev/null +++ b/src/samples/savedata/utility/Makefile.sample @@ -0,0 +1,18 @@ +TARGET = savedata +OBJS = main.o + +# For custom firmware uncomment the following lines: +#PSP_FW_VERSION = 200 +#BUILD_PRX = 1 + +LIBS = -lpsputility -lpspgum -lpspgu -lm + +CFLAGS = -O2 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = PSPSDK Savedata Sample + +PSPSDK = $(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/savedata/utility/data.h b/src/samples/savedata/utility/data.h new file mode 100644 index 00000000..1e627adc --- /dev/null +++ b/src/samples/savedata/utility/data.h @@ -0,0 +1,314 @@ +#ifndef __data__ +#define __data__ + +unsigned int size_icon0 = 1666; +unsigned char icon0[] __attribute__((aligned(16))) = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, + 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x50, 0x08, 0x02, 0x00, 0x00, 0x00, 0x79, 0xcc, 0x6b, + 0x5b, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xd6, 0xd8, 0xd4, 0x4f, 0x58, + 0x32, 0x00, 0x00, 0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, + 0x65, 0x00, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x61, + 0x64, 0x79, 0x71, 0xc9, 0x65, 0x3c, 0x00, 0x00, 0x06, 0x14, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, + 0xec, 0x5c, 0x2d, 0x6c, 0x1c, 0x47, 0x14, 0x7e, 0xae, 0x1c, 0x10, 0x70, 0x07, 0x02, 0x12, 0x70, + 0x91, 0x5c, 0x60, 0x10, 0x9f, 0x64, 0x90, 0x00, 0x3b, 0x0a, 0x09, 0x72, 0x55, 0x95, 0x26, 0x20, + 0x85, 0x0d, 0x28, 0x4d, 0x81, 0x4d, 0x0d, 0x52, 0xe8, 0x80, 0x1a, 0xd6, 0x20, 0x86, 0x09, 0x88, + 0x61, 0x0b, 0x62, 0xd8, 0xb4, 0xb2, 0x0d, 0x5a, 0x10, 0x29, 0x17, 0x10, 0xa9, 0x89, 0x94, 0x03, + 0x31, 0x08, 0xb0, 0x41, 0x40, 0x0d, 0xfa, 0x79, 0x47, 0xfb, 0xf4, 0xee, 0x76, 0x77, 0x76, 0x76, + 0xf6, 0x7e, 0xf6, 0x92, 0xef, 0xd3, 0x01, 0xeb, 0x6e, 0x67, 0x76, 0xe6, 0x7d, 0xef, 0x7d, 0xf3, + 0xde, 0xcc, 0xc8, 0x73, 0xff, 0xca, 0xb7, 0x42, 0xcc, 0x0e, 0xbe, 0xa2, 0x09, 0x48, 0x18, 0x41, + 0xc2, 0x08, 0x12, 0x46, 0xc2, 0x08, 0x12, 0x46, 0x90, 0x30, 0x12, 0x46, 0x90, 0x30, 0x82, 0x84, + 0x91, 0x30, 0x82, 0x84, 0x11, 0x24, 0x8c, 0x84, 0x11, 0x24, 0x8c, 0x20, 0x61, 0x24, 0x8c, 0x20, + 0x61, 0x04, 0x09, 0x23, 0x61, 0x04, 0x09, 0x23, 0x48, 0xd8, 0x17, 0x85, 0xf9, 0x69, 0xbd, 0xf8, + 0x95, 0x9c, 0xbc, 0x97, 0x4f, 0xaf, 0xe4, 0x54, 0xbf, 0xb9, 0x29, 0x97, 0xae, 0xca, 0x45, 0x7c, + 0x02, 0x9b, 0xa3, 0x2d, 0x7a, 0x88, 0x68, 0x3b, 0xd3, 0x98, 0xab, 0x79, 0x2f, 0xf1, 0x40, 0x3e, + 0x7e, 0x2f, 0x47, 0xee, 0xef, 0x27, 0xb2, 0x02, 0xc3, 0x95, 0x3e, 0xff, 0x4c, 0xfa, 0xcf, 0xe5, + 0xc3, 0xa9, 0x9c, 0xe5, 0x3e, 0xd0, 0x91, 0x8b, 0x77, 0xa5, 0xf3, 0x93, 0x2c, 0xe6, 0xfe, 0x0a, + 0x86, 0x1e, 0xcb, 0x5b, 0xf4, 0x90, 0xdb, 0x7c, 0x49, 0x5a, 0xf7, 0xe5, 0x6b, 0x34, 0xf7, 0x8f, + 0xe1, 0x9e, 0x1c, 0x1d, 0xca, 0x47, 0xf7, 0xf7, 0xaf, 0x72, 0xfd, 0x1b, 0xb9, 0x52, 0x3a, 0x4d, + 0x6d, 0xf2, 0x40, 0x16, 0x8b, 0xc6, 0xe6, 0x70, 0x22, 0xff, 0x61, 0x8e, 0xce, 0x11, 0xe1, 0x40, + 0xce, 0x93, 0x66, 0x32, 0xc2, 0x10, 0x13, 0x0f, 0xe5, 0xb5, 0x5a, 0xaa, 0x08, 0x7d, 0xf9, 0x04, + 0x3a, 0x73, 0x8d, 0x02, 0xaa, 0x7e, 0x91, 0x37, 0x45, 0x4c, 0x03, 0x3d, 0x39, 0xdd, 0x90, 0x97, + 0x78, 0xe6, 0x91, 0x2c, 0x97, 0xba, 0x8e, 0xc3, 0xba, 0xbc, 0x7c, 0x21, 0x97, 0xda, 0x72, 0xa1, + 0xfe, 0x04, 0xe1, 0x4c, 0x78, 0xf5, 0x1e, 0x66, 0x30, 0x88, 0x3b, 0xd2, 0xd9, 0x94, 0x6b, 0x23, + 0x79, 0xc5, 0xe4, 0x08, 0x43, 0x4c, 0xc0, 0x94, 0x43, 0xd1, 0xd0, 0x95, 0xb6, 0xf5, 0xbe, 0xc4, + 0x31, 0x4f, 0xc0, 0x47, 0x6e, 0x88, 0xc0, 0xb2, 0xd6, 0x16, 0xb0, 0x82, 0x3a, 0xaf, 0x73, 0x6a, + 0x0d, 0x3b, 0x50, 0x8e, 0xa0, 0xdf, 0x92, 0xe5, 0xd2, 0x50, 0x03, 0xd0, 0x04, 0x6e, 0x04, 0x82, + 0xeb, 0xbb, 0x23, 0xa2, 0x30, 0xd7, 0x99, 0xf6, 0x12, 0x45, 0x79, 0x2a, 0x2b, 0x98, 0xef, 0x6c, + 0x10, 0x86, 0xc8, 0xf8, 0x59, 0x5e, 0x5b, 0x5b, 0x23, 0x80, 0x8a, 0x84, 0x02, 0xa6, 0xcf, 0xfe, + 0x64, 0xd9, 0x5a, 0x93, 0xcb, 0x9b, 0xb2, 0x34, 0xf4, 0x0c, 0x64, 0x0d, 0x5f, 0xc2, 0xc1, 0xb7, + 0xe5, 0x8d, 0xfb, 0xc6, 0xf9, 0x47, 0x08, 0x67, 0xe8, 0xf9, 0x6e, 0x42, 0xff, 0x48, 0xd8, 0x6a, + 0xc9, 0xbc, 0x0e, 0x0f, 0x3e, 0xe4, 0x86, 0x8d, 0x9f, 0x7e, 0x94, 0x7f, 0x7e, 0x97, 0x5b, 0xf5, + 0xe3, 0x6c, 0xec, 0x59, 0x22, 0x9c, 0x4b, 0xd9, 0xc2, 0x64, 0x7e, 0x93, 0x5b, 0x70, 0x67, 0x8f, + 0xac, 0x67, 0x45, 0x1f, 0x7c, 0x2b, 0x5b, 0x20, 0x7b, 0x47, 0x6e, 0x14, 0x35, 0x87, 0x1f, 0x6c, + 0x99, 0x58, 0x79, 0x28, 0x3d, 0xcd, 0x4a, 0x72, 0xb1, 0x9a, 0x92, 0x04, 0x87, 0x40, 0x98, 0x46, + 0xcf, 0x11, 0x31, 0xea, 0xd8, 0xc2, 0x02, 0xfc, 0x42, 0x6e, 0x3b, 0xfa, 0xf1, 0xc1, 0x4c, 0x75, + 0x3c, 0xfd, 0x44, 0x30, 0x9b, 0x9e, 0xd6, 0xc3, 0x5e, 0xeb, 0xa9, 0x12, 0x82, 0x2d, 0x4c, 0xa6, + 0xaa, 0x2c, 0xc0, 0x8e, 0x3a, 0x4f, 0xa8, 0x68, 0xa9, 0x76, 0xc1, 0x58, 0x3f, 0xc8, 0x82, 0xca, + 0xdd, 0xfa, 0xa0, 0x0e, 0x0f, 0xe1, 0xbe, 0x2c, 0xb4, 0x12, 0x8d, 0xe9, 0x9f, 0xe7, 0x32, 0xef, + 0xa2, 0xd5, 0x5e, 0x17, 0x66, 0x0c, 0x6f, 0x28, 0x86, 0xec, 0x78, 0x76, 0xe5, 0x9d, 0xdf, 0x81, + 0xa6, 0x4f, 0x98, 0xcd, 0x11, 0x20, 0xe2, 0x11, 0x82, 0x00, 0x3b, 0x6a, 0x0f, 0x90, 0x9a, 0x90, + 0x26, 0x88, 0xb3, 0x4e, 0x1a, 0x82, 0x87, 0xc9, 0xba, 0x58, 0xf4, 0x24, 0xc6, 0x83, 0xac, 0xd2, + 0xfd, 0x0d, 0x2d, 0xf5, 0x3c, 0xe9, 0x27, 0x4c, 0xe3, 0x35, 0x57, 0x57, 0xf5, 0x15, 0x4e, 0x6f, + 0x9a, 0x4b, 0x18, 0x82, 0xc3, 0x4a, 0x59, 0xdc, 0x92, 0x0b, 0x3d, 0xd4, 0xa5, 0x2b, 0x70, 0x99, + 0x01, 0x0d, 0x36, 0xc9, 0x7c, 0x96, 0x49, 0xdb, 0xec, 0xda, 0xa3, 0x41, 0xe6, 0x94, 0x2d, 0x42, + 0x42, 0x34, 0xbc, 0x8a, 0xd6, 0x4b, 0x08, 0xb8, 0x6a, 0xef, 0x73, 0x39, 0x6e, 0x2e, 0x61, 0xd6, + 0x52, 0xfe, 0xda, 0xc5, 0xb3, 0xfe, 0x69, 0x78, 0x85, 0xa4, 0x0f, 0x26, 0x07, 0xb9, 0x6c, 0x3a, + 0x39, 0x2e, 0x76, 0xa9, 0x33, 0x1b, 0x64, 0x30, 0xbd, 0xfa, 0x47, 0x78, 0x19, 0x9a, 0xfb, 0xd2, + 0xec, 0xc2, 0xac, 0xaf, 0x68, 0x2e, 0x61, 0x6a, 0x29, 0xac, 0x3d, 0x71, 0xc5, 0xa3, 0xdd, 0x07, + 0x09, 0x29, 0x6f, 0x6d, 0x90, 0xa9, 0x53, 0x63, 0x7d, 0xf2, 0xaf, 0x1c, 0x56, 0x42, 0xa1, 0xe1, + 0x95, 0x96, 0x19, 0x55, 0x51, 0xcc, 0xd1, 0x23, 0xf8, 0x56, 0x1b, 0xe2, 0x84, 0x77, 0x12, 0x84, + 0xe9, 0xc8, 0xa2, 0x33, 0x66, 0xf5, 0x5f, 0x98, 0xa3, 0x6a, 0x5b, 0xfb, 0xd2, 0x52, 0x0e, 0x34, + 0x97, 0x49, 0xca, 0xb2, 0x5e, 0x84, 0x4b, 0x85, 0x2f, 0xcf, 0x27, 0xc5, 0x85, 0xff, 0x34, 0x09, + 0xc3, 0x02, 0xa6, 0x6a, 0x16, 0x5d, 0x30, 0x6a, 0xaa, 0x1d, 0xd1, 0x43, 0xd7, 0x70, 0x5c, 0xea, + 0xd4, 0x60, 0x77, 0x2d, 0x15, 0xb4, 0x7d, 0x39, 0x0e, 0x4f, 0x0d, 0xcc, 0x08, 0x5b, 0x81, 0xde, + 0xd3, 0xd0, 0x08, 0xb3, 0x6a, 0x16, 0xbd, 0x99, 0xd6, 0x4b, 0x3b, 0x89, 0xe8, 0xc1, 0xba, 0x7c, + 0x88, 0x53, 0x23, 0x05, 0xb5, 0xd9, 0x47, 0x60, 0x59, 0xd6, 0xfb, 0x6c, 0x22, 0x6c, 0xe6, 0x00, + 0x9f, 0xd0, 0xec, 0x63, 0x54, 0x45, 0xee, 0x38, 0x40, 0xc2, 0x06, 0xb2, 0x0f, 0x5d, 0x2c, 0x51, + 0xe4, 0xd6, 0xd4, 0xae, 0x19, 0x23, 0xac, 0x6d, 0x76, 0x29, 0xa3, 0x77, 0x7d, 0x54, 0xa3, 0x22, + 0x7a, 0xb0, 0x89, 0x46, 0x37, 0x38, 0x67, 0xb1, 0x3b, 0x29, 0xfe, 0x5d, 0x92, 0xcf, 0x8d, 0x30, + 0x9b, 0x26, 0xd8, 0xf5, 0x2c, 0xae, 0x93, 0x88, 0x1e, 0x2c, 0x61, 0xe1, 0x0b, 0x0c, 0xde, 0xa8, + 0x3b, 0x49, 0x58, 0x9f, 0x3c, 0x45, 0x77, 0xa5, 0xf4, 0xd5, 0x3a, 0x5c, 0xb7, 0x7a, 0xc6, 0x3b, + 0x21, 0x49, 0xd4, 0xe2, 0xe6, 0x20, 0xb6, 0x5a, 0xbc, 0x6a, 0x76, 0x98, 0xa2, 0x4b, 0x82, 0xaa, + 0x75, 0x85, 0x2d, 0xcb, 0x90, 0xe2, 0x3b, 0x5b, 0xb7, 0x0b, 0x8e, 0x35, 0xd4, 0x15, 0xfc, 0x73, + 0xb4, 0x0e, 0x57, 0x73, 0xc3, 0x7e, 0x8c, 0x84, 0xd9, 0xf2, 0x3e, 0x4e, 0x15, 0xad, 0xa1, 0x2b, + 0xed, 0xc2, 0xe1, 0x75, 0x87, 0xb1, 0x35, 0x1c, 0x0c, 0xba, 0x29, 0xd7, 0xb4, 0x2c, 0x73, 0x9b, + 0xc2, 0x45, 0x75, 0x85, 0xba, 0x94, 0x7f, 0x82, 0xf6, 0xd7, 0x9a, 0x07, 0xd0, 0x63, 0x24, 0xcc, + 0x6e, 0xd5, 0xc4, 0xed, 0x85, 0x0f, 0x12, 0x56, 0x61, 0x17, 0xce, 0x4a, 0x59, 0xa5, 0x3d, 0x2d, + 0xdd, 0x55, 0xd1, 0xb2, 0x6c, 0xdb, 0xbb, 0xf7, 0xa1, 0x23, 0xec, 0x79, 0x45, 0x5b, 0xe3, 0x0f, + 0xab, 0x72, 0x93, 0x09, 0xbb, 0xa2, 0xda, 0xf2, 0x58, 0xde, 0x46, 0x9c, 0x2c, 0x60, 0x6e, 0x6a, + 0xb8, 0x3d, 0xe9, 0x07, 0xa6, 0x6d, 0x70, 0x67, 0xeb, 0x1f, 0x11, 0x84, 0x0d, 0x95, 0x65, 0x9e, + 0x14, 0x3f, 0x50, 0x03, 0x94, 0xb0, 0x3a, 0xc7, 0xa4, 0x93, 0x48, 0xeb, 0x75, 0xcf, 0x37, 0x39, + 0x72, 0xfd, 0x3b, 0x42, 0x18, 0xed, 0xd9, 0x44, 0x60, 0xda, 0x06, 0xfb, 0xf6, 0x53, 0xe7, 0x78, + 0x20, 0x8b, 0x71, 0x6b, 0x06, 0x7c, 0x45, 0x07, 0x0f, 0x5f, 0x29, 0xf2, 0x36, 0x3c, 0xa6, 0x92, + 0x5b, 0xa4, 0x01, 0x68, 0xab, 0xf1, 0x57, 0x69, 0x47, 0x74, 0x0a, 0x84, 0xc1, 0xbb, 0x57, 0x8d, + 0x68, 0xdc, 0x93, 0xa3, 0xaa, 0x71, 0x06, 0x97, 0xbc, 0x93, 0x86, 0x08, 0x7a, 0x28, 0xe5, 0x0c, + 0x62, 0xb8, 0x9b, 0x86, 0x57, 0xe7, 0xbc, 0x16, 0x5e, 0x88, 0x1e, 0x3c, 0x7c, 0x45, 0xc9, 0xf0, + 0x04, 0xb7, 0xba, 0x54, 0x91, 0x06, 0x68, 0x80, 0x22, 0x64, 0xe3, 0xc2, 0x7d, 0xa2, 0x85, 0xf3, + 0x8e, 0x5c, 0x57, 0x6d, 0x81, 0xc5, 0xbf, 0x93, 0x3f, 0xfd, 0x3b, 0xe2, 0x07, 0x99, 0x23, 0x47, + 0xa4, 0x00, 0x6a, 0x38, 0x18, 0x05, 0x91, 0x9a, 0xdb, 0xdc, 0x9d, 0x4d, 0x6f, 0x98, 0x03, 0x6e, + 0xbc, 0xba, 0x66, 0x4a, 0xa6, 0x65, 0x99, 0x67, 0x89, 0x02, 0x07, 0xaa, 0xfc, 0xd9, 0xab, 0x06, + 0x7a, 0xad, 0x43, 0x62, 0xcf, 0x98, 0x86, 0x30, 0xf6, 0x4b, 0x38, 0x30, 0xd9, 0x53, 0x59, 0xc1, + 0x4c, 0xdc, 0x9c, 0xa1, 0x8d, 0xdb, 0xc9, 0x55, 0x19, 0x70, 0x70, 0x73, 0xf0, 0x7e, 0x99, 0xde, + 0x9a, 0x82, 0x8e, 0xd9, 0xac, 0xcc, 0xf5, 0x80, 0xe8, 0x74, 0x3d, 0xec, 0xcb, 0x31, 0x3e, 0x9e, + 0x5b, 0x53, 0x8e, 0xad, 0x91, 0xdc, 0x52, 0x42, 0x0f, 0x18, 0xcc, 0x76, 0xd9, 0x36, 0x15, 0x78, + 0x75, 0x97, 0x33, 0x13, 0x8f, 0xfc, 0x4b, 0xaf, 0x18, 0x59, 0xb6, 0xa0, 0x34, 0x56, 0xde, 0x9b, + 0x4b, 0x98, 0x9b, 0x36, 0xcc, 0x07, 0xf7, 0xdf, 0x35, 0xb9, 0x00, 0xe6, 0x56, 0xe4, 0xb6, 0xd9, + 0x9a, 0x46, 0x59, 0xdf, 0x4f, 0xd7, 0x89, 0x3d, 0x63, 0x8b, 0x21, 0xac, 0x26, 0xb7, 0x5f, 0x46, + 0x75, 0x7d, 0x13, 0xa2, 0x0a, 0xbb, 0xf7, 0xbd, 0x4a, 0x0e, 0xd7, 0xd9, 0x92, 0x65, 0x17, 0xdc, + 0x78, 0x72, 0x23, 0xa3, 0xdb, 0xf0, 0x4e, 0x84, 0x7b, 0xa3, 0x77, 0x3a, 0xf2, 0x8a, 0x9b, 0xa5, + 0x3f, 0xe4, 0x36, 0x22, 0xa3, 0xe5, 0xf5, 0x12, 0xcc, 0x2d, 0xf7, 0xe8, 0x16, 0x3d, 0xec, 0xc8, + 0x8d, 0x27, 0xb2, 0xb2, 0x56, 0x7c, 0xb0, 0x8b, 0x9f, 0xf0, 0x00, 0xa8, 0x1d, 0xe1, 0x65, 0x5b, + 0xbc, 0x37, 0xe4, 0xd6, 0x22, 0x84, 0x11, 0xaf, 0xce, 0xd6, 0x7c, 0x98, 0x2c, 0x62, 0x34, 0xee, + 0x3e, 0x4b, 0x2e, 0xe6, 0xa6, 0xf2, 0x2f, 0x64, 0xb3, 0x17, 0xeb, 0xdd, 0xcd, 0xf8, 0xae, 0xf7, + 0xdc, 0x36, 0xbb, 0xd4, 0xb9, 0xa3, 0x8a, 0xb6, 0xcc, 0x23, 0x88, 0xc3, 0xdb, 0x8e, 0x7b, 0x6a, + 0x07, 0xe7, 0x1b, 0x05, 0x67, 0x2e, 0xf2, 0xea, 0xe7, 0xf1, 0x8d, 0x20, 0x8c, 0x68, 0xba, 0x24, + 0x12, 0x24, 0x8c, 0x84, 0x11, 0x24, 0x8c, 0x20, 0x61, 0x24, 0x8c, 0x20, 0x61, 0x04, 0x09, 0x23, + 0x48, 0x18, 0x09, 0x23, 0x48, 0x18, 0x41, 0xc2, 0x48, 0x18, 0x41, 0xc2, 0x08, 0x12, 0x46, 0xc2, + 0x08, 0x12, 0x46, 0x90, 0x30, 0x12, 0x46, 0x90, 0x30, 0x82, 0x84, 0x91, 0x30, 0x82, 0x84, 0x11, + 0x24, 0x8c, 0x84, 0x11, 0x24, 0x8c, 0x20, 0x61, 0x5f, 0x12, 0xfe, 0x17, 0x60, 0x00, 0xed, 0xf6, + 0x47, 0x4c, 0x1c, 0x54, 0x4d, 0x28, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, + 0x60, 0x82, +}; + +unsigned int size_pic1 = 3150; +unsigned char pic1[] __attribute__((aligned(16))) = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, + 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0x10, 0x08, 0x02, 0x00, 0x00, 0x00, 0xe7, 0x24, 0x30, + 0xdb, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xd6, 0xd8, 0xd4, 0x4f, 0x58, + 0x32, 0x00, 0x00, 0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, + 0x65, 0x00, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x61, + 0x64, 0x79, 0x71, 0xc9, 0x65, 0x3c, 0x00, 0x00, 0x0b, 0xe0, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, + 0xec, 0xdd, 0x7d, 0x56, 0x5b, 0x65, 0x1e, 0xc0, 0xf1, 0xf2, 0x12, 0x42, 0x43, 0x81, 0x14, 0x8a, + 0x65, 0x68, 0x3d, 0xe4, 0x74, 0xf4, 0x1f, 0xff, 0x81, 0x59, 0x41, 0xe9, 0x0a, 0xca, 0x0e, 0xc4, + 0x15, 0x48, 0x57, 0x50, 0x5c, 0x81, 0xb8, 0x02, 0x71, 0x05, 0xe2, 0x0a, 0x06, 0x56, 0x30, 0xf4, + 0xbf, 0x99, 0xe3, 0x51, 0xe9, 0x54, 0x99, 0x62, 0x0b, 0xe5, 0xa5, 0x8d, 0xbc, 0x33, 0xbf, 0x12, + 0x45, 0xac, 0x36, 0xf7, 0x42, 0x21, 0xb9, 0x09, 0x9f, 0xcf, 0xc9, 0xe9, 0xa9, 0x1a, 0x20, 0x3c, + 0xc4, 0x6f, 0x9e, 0x3c, 0x3c, 0xf7, 0xde, 0x96, 0xe1, 0xc3, 0x8f, 0xae, 0x00, 0x90, 0x3d, 0xad, + 0x86, 0x00, 0x40, 0xa0, 0x01, 0x10, 0x68, 0x00, 0x81, 0x06, 0x40, 0xa0, 0x01, 0x04, 0x1a, 0x00, + 0x81, 0x06, 0x40, 0xa0, 0x01, 0x04, 0x1a, 0x00, 0x81, 0x06, 0x10, 0x68, 0x00, 0x04, 0x1a, 0x00, + 0x81, 0x06, 0x10, 0x68, 0x00, 0x04, 0x1a, 0x40, 0xa0, 0x01, 0x10, 0x68, 0x00, 0x81, 0x06, 0x40, + 0xa0, 0x01, 0x10, 0x68, 0x00, 0x81, 0x06, 0x40, 0xa0, 0x01, 0x04, 0x1a, 0x00, 0x81, 0x06, 0x40, + 0xa0, 0x01, 0x04, 0x1a, 0x00, 0x81, 0x06, 0x10, 0x68, 0x00, 0x04, 0x1a, 0x40, 0xa0, 0x01, 0x10, + 0x68, 0x00, 0x04, 0x1a, 0x40, 0xa0, 0x01, 0x10, 0x68, 0x00, 0x81, 0x06, 0x40, 0xa0, 0x01, 0x10, + 0x68, 0x00, 0x81, 0x06, 0x40, 0xa0, 0x01, 0x04, 0x1a, 0x00, 0x81, 0x06, 0x10, 0x68, 0x00, 0x04, + 0x1a, 0x00, 0x81, 0x06, 0x10, 0x68, 0x00, 0x04, 0x1a, 0x40, 0xa0, 0x01, 0x10, 0x68, 0x00, 0x04, + 0x1a, 0x40, 0xa0, 0x01, 0x10, 0x68, 0x00, 0x81, 0x06, 0x40, 0xa0, 0x01, 0x10, 0x68, 0x00, 0x81, + 0x06, 0x40, 0xa0, 0x01, 0x04, 0x1a, 0x00, 0x81, 0x06, 0x10, 0x68, 0x00, 0x04, 0x1a, 0x00, 0x81, + 0x06, 0x10, 0x68, 0x00, 0x04, 0x1a, 0x40, 0xa0, 0x01, 0x10, 0x68, 0x00, 0x04, 0x1a, 0x40, 0xa0, + 0x01, 0x10, 0x68, 0x00, 0x81, 0x06, 0x40, 0xa0, 0x01, 0x04, 0x1a, 0x00, 0x81, 0x06, 0x40, 0xa0, + 0x01, 0x04, 0x1a, 0x00, 0x81, 0x06, 0x10, 0x68, 0x00, 0x04, 0x1a, 0x00, 0x81, 0x06, 0x10, 0x68, + 0x00, 0x04, 0x1a, 0x40, 0xa0, 0x01, 0x10, 0x68, 0x00, 0x81, 0x06, 0x20, 0x8b, 0xda, 0x0d, 0x01, + 0xa4, 0xb1, 0x35, 0xf7, 0xea, 0xf8, 0xef, 0x9d, 0x63, 0x5d, 0x06, 0x04, 0x81, 0xe6, 0x14, 0x76, + 0x16, 0xb6, 0x0e, 0xd6, 0xf6, 0x4f, 0xfe, 0x9b, 0xbd, 0xc5, 0xdd, 0xb8, 0x9d, 0xc8, 0x4a, 0x41, + 0x62, 0xaa, 0xdb, 0x5b, 0xdc, 0x89, 0x61, 0xdc, 0x59, 0xd8, 0xae, 0x0c, 0x66, 0xfc, 0x79, 0xb8, + 0x7e, 0x50, 0xfd, 0x43, 0x72, 0x23, 0xf9, 0xd6, 0x62, 0x5b, 0xc7, 0x68, 0x67, 0xfc, 0x19, 0x23, + 0x5c, 0xf9, 0x8b, 0x91, 0xe4, 0x5c, 0xb4, 0x0c, 0x1f, 0x7e, 0x64, 0x14, 0x1a, 0xab, 0xc2, 0x47, + 0x11, 0xd9, 0xae, 0xe4, 0xa3, 0xf2, 0x6f, 0x12, 0x23, 0xf2, 0x36, 0xf9, 0xbb, 0x85, 0x4a, 0x5c, + 0xa2, 0x2c, 0x17, 0x9a, 0xec, 0x98, 0x7e, 0x2e, 0xdf, 0x7b, 0x5c, 0xe5, 0x0e, 0xbd, 0x0f, 0x07, + 0x8a, 0x53, 0x03, 0xf5, 0x8a, 0xf2, 0xd6, 0x5c, 0x39, 0x1e, 0x61, 0xfc, 0xb9, 0xff, 0x78, 0xf7, + 0xdd, 0x3f, 0x61, 0xdb, 0x70, 0xae, 0x32, 0x9e, 0x85, 0xf1, 0x6e, 0xb1, 0x46, 0xa0, 0x2f, 0x85, + 0xa5, 0xd1, 0xef, 0x76, 0x1f, 0x6d, 0x5f, 0xe8, 0x97, 0xb8, 0x7a, 0xbf, 0x3b, 0xca, 0x72, 0x6d, + 0xa2, 0x78, 0xee, 0x59, 0xc9, 0x60, 0xa0, 0xe3, 0x15, 0xae, 0x3c, 0xbb, 0xb9, 0x31, 0xbd, 0x72, + 0xa1, 0xa3, 0x1a, 0x43, 0x1a, 0x99, 0x8e, 0x21, 0xf5, 0x04, 0xe6, 0x0c, 0xfc, 0x92, 0xb0, 0x61, + 0x5c, 0x74, 0x9d, 0xc3, 0x2f, 0xdf, 0x6c, 0xbe, 0x78, 0xb0, 0xfc, 0xe4, 0xfa, 0x7f, 0x7e, 0x1e, + 0x7f, 0x72, 0x72, 0xc9, 0xb5, 0xf9, 0xde, 0x85, 0x3c, 0x9f, 0xf8, 0x29, 0xbe, 0xcd, 0x95, 0x4f, + 0x96, 0x2e, 0x7a, 0x54, 0x63, 0x48, 0xe3, 0xab, 0xfc, 0xb7, 0xf8, 0xef, 0xca, 0xdb, 0x1d, 0x38, + 0x15, 0x6b, 0xd0, 0xfc, 0x75, 0x56, 0xe2, 0x96, 0xbf, 0x5b, 0x88, 0x59, 0x6d, 0x33, 0xad, 0x56, + 0xc7, 0xab, 0xce, 0xda, 0xd4, 0xb3, 0xed, 0xf9, 0x72, 0x8d, 0xbf, 0xee, 0xe1, 0xfa, 0x41, 0x7b, + 0x29, 0x77, 0xa1, 0x5f, 0xe2, 0xe5, 0xcc, 0x5a, 0x7c, 0x6b, 0x6f, 0x5b, 0xa2, 0x89, 0x1f, 0xe5, + 0xe0, 0x5c, 0xc9, 0x13, 0xdb, 0x0c, 0x9a, 0xe6, 0x11, 0x21, 0x5b, 0xbe, 0xf7, 0x78, 0x75, 0xf2, + 0xe9, 0x1b, 0xbf, 0x7b, 0x6c, 0x44, 0x7b, 0x8b, 0x3b, 0x31, 0x6b, 0x8e, 0x6f, 0xa7, 0xf6, 0x75, + 0xbe, 0x72, 0xb4, 0xd0, 0x71, 0x71, 0x8b, 0xd1, 0x91, 0xe6, 0x1f, 0x4b, 0xdf, 0xc6, 0x3c, 0xfd, + 0x5c, 0x16, 0xd0, 0x11, 0x68, 0x1a, 0xc9, 0xe6, 0x17, 0xab, 0x4b, 0xa3, 0xdf, 0x37, 0xf4, 0x3b, + 0xf4, 0x8d, 0xe9, 0x95, 0xf8, 0x16, 0x5e, 0x7d, 0xb5, 0x5e, 0xaf, 0x07, 0x50, 0x18, 0xef, 0xbe, + 0xa0, 0x37, 0x04, 0x4f, 0xc7, 0x16, 0xa5, 0xb9, 0x89, 0x59, 0xe2, 0x20, 0x59, 0xfc, 0xff, 0x1f, + 0x21, 0x78, 0x6f, 0xf6, 0xfd, 0x86, 0x5b, 0xee, 0x38, 0x9a, 0x38, 0x2f, 0xd5, 0x65, 0xd6, 0x7c, + 0xd2, 0xc9, 0x0d, 0x8e, 0xe7, 0x95, 0xe6, 0xba, 0xac, 0xd5, 0x20, 0xd0, 0x64, 0xd1, 0xe1, 0xfa, + 0xc1, 0xf2, 0xbd, 0xc7, 0x03, 0x5f, 0xdf, 0x2e, 0x8c, 0xf7, 0x34, 0xca, 0x63, 0x2e, 0xcf, 0x6e, + 0x44, 0x9d, 0xcf, 0xbc, 0x07, 0xf1, 0x0d, 0x95, 0xfd, 0xce, 0xbf, 0x75, 0x7f, 0x37, 0xfd, 0xa4, + 0x35, 0x3e, 0xb0, 0xbd, 0xd4, 0x71, 0x8e, 0x2f, 0x39, 0xab, 0x93, 0xcb, 0xbf, 0x7c, 0xb3, 0xe9, + 0x39, 0x29, 0xd0, 0x34, 0x8c, 0x96, 0xde, 0xd6, 0x8e, 0xd1, 0xce, 0xca, 0x51, 0x12, 0x1d, 0xa3, + 0xbf, 0xa7, 0xe4, 0xe4, 0x9c, 0xb7, 0x72, 0xf0, 0xc5, 0xd1, 0x06, 0xea, 0xed, 0xa3, 0xc3, 0x31, + 0xb6, 0x4e, 0xfb, 0xd6, 0x38, 0x7a, 0x37, 0x38, 0xd7, 0x11, 0x5f, 0x25, 0xfb, 0x03, 0xb2, 0x31, + 0xbd, 0xf2, 0xe2, 0xc1, 0xf2, 0x99, 0x5b, 0x1c, 0xe3, 0xd6, 0x5e, 0xca, 0x1d, 0x0f, 0x69, 0x95, + 0x5c, 0x46, 0xac, 0x8f, 0x36, 0xa7, 0xef, 0xc6, 0xac, 0xf6, 0x2f, 0xf7, 0x84, 0x9c, 0xd7, 0x1e, + 0xbb, 0xf8, 0x5a, 0x31, 0x6b, 0xae, 0xe3, 0x42, 0x0d, 0x02, 0xcd, 0x19, 0xf5, 0x4c, 0xf6, 0x27, + 0xee, 0x23, 0x3e, 0x0e, 0x6b, 0x61, 0xfc, 0xf7, 0x64, 0x97, 0x67, 0x37, 0x5f, 0xce, 0xac, 0xa5, + 0x2c, 0x75, 0xcc, 0x46, 0x7f, 0x1e, 0x7f, 0x32, 0xb4, 0x70, 0x27, 0xe3, 0xc7, 0x5f, 0x3c, 0x9f, + 0xf8, 0xe9, 0x0c, 0x21, 0xab, 0xec, 0x59, 0x3e, 0xd5, 0xd1, 0x25, 0x31, 0x35, 0x8e, 0xdb, 0xf1, + 0xab, 0x60, 0xbc, 0xf8, 0x45, 0xa6, 0x63, 0x48, 0xe3, 0x76, 0x3c, 0x73, 0x7f, 0xf7, 0x05, 0xe8, + 0xf8, 0xb4, 0x1b, 0xd3, 0xab, 0xeb, 0x9f, 0x3d, 0xf3, 0x3c, 0x17, 0x68, 0x2e, 0x91, 0xca, 0x0c, + 0x31, 0xca, 0x5e, 0x7d, 0x93, 0xd6, 0x49, 0x71, 0x9f, 0xb8, 0x67, 0xdf, 0xf4, 0x60, 0xd3, 0xd4, + 0xb9, 0x6d, 0x38, 0xd7, 0x33, 0xd9, 0x77, 0x2e, 0x87, 0xe7, 0xc4, 0x67, 0x28, 0x8c, 0xf7, 0x54, + 0x56, 0x81, 0x62, 0x48, 0xe3, 0x16, 0x33, 0xeb, 0x77, 0x59, 0xdf, 0xa8, 0xa4, 0x39, 0xde, 0x0d, + 0x9c, 0xd7, 0x42, 0x0d, 0x8d, 0xc5, 0x2e, 0x0e, 0x7e, 0x7d, 0x1b, 0x7e, 0x7b, 0xf1, 0xc3, 0xde, + 0x87, 0xa9, 0x8e, 0xe5, 0xdb, 0xfc, 0x62, 0x35, 0xb3, 0x87, 0xb1, 0x9c, 0xaa, 0xce, 0x91, 0xe6, + 0xfe, 0x2f, 0x87, 0xe2, 0x1b, 0x8f, 0xf7, 0x1f, 0xe7, 0xfe, 0x9e, 0x20, 0x86, 0x74, 0x70, 0xae, + 0x34, 0x38, 0x37, 0x7c, 0xe6, 0xcf, 0x10, 0x5d, 0xfe, 0xb1, 0xf4, 0x6d, 0x4c, 0x9c, 0xd5, 0x59, + 0xa0, 0xe1, 0x4a, 0x4c, 0xa5, 0x07, 0xbe, 0xbe, 0xdd, 0xd2, 0x9b, 0xfc, 0xac, 0x88, 0x49, 0x74, + 0x06, 0x1f, 0x7f, 0x14, 0x2d, 0x7d, 0x9d, 0xe3, 0xd5, 0x68, 0x68, 0xe1, 0xce, 0x45, 0x1f, 0x84, + 0x7d, 0xe6, 0xe9, 0x73, 0x8c, 0xf0, 0x8b, 0x07, 0xcb, 0xd2, 0x2c, 0xd0, 0xf0, 0xbb, 0x78, 0x7b, + 0xfe, 0xde, 0xec, 0xfb, 0x89, 0x77, 0xdb, 0x9e, 0x2f, 0x67, 0x6d, 0x67, 0x74, 0x79, 0x76, 0x23, + 0xe5, 0x6f, 0x05, 0x63, 0xe2, 0xfc, 0xb7, 0x7f, 0xdd, 0x89, 0x57, 0xa3, 0x2c, 0xaf, 0xa4, 0x77, + 0x8c, 0xe6, 0x53, 0xde, 0x33, 0x5e, 0x50, 0xe3, 0xc5, 0x26, 0x37, 0x92, 0xf7, 0xec, 0x15, 0x68, + 0x9a, 0x5f, 0xe7, 0x58, 0xd7, 0xf5, 0xcf, 0x6f, 0xa6, 0x99, 0xae, 0x66, 0xe7, 0x31, 0x57, 0xf6, + 0x3b, 0xa7, 0xb9, 0xe7, 0xd5, 0xfb, 0xdd, 0x31, 0x71, 0xce, 0xfe, 0x46, 0x94, 0x94, 0x5b, 0xce, + 0xbb, 0x3e, 0xee, 0x8d, 0x6f, 0x27, 0xe3, 0x2f, 0x36, 0x08, 0x34, 0xe7, 0xa9, 0x67, 0xb2, 0x3f, + 0x7f, 0xb7, 0x90, 0x34, 0x63, 0xcd, 0xd0, 0x56, 0xdc, 0x9f, 0xc7, 0x9f, 0xa4, 0x59, 0x0d, 0x88, + 0x9c, 0xc5, 0xfb, 0x83, 0x86, 0x68, 0x59, 0x3c, 0xc8, 0xea, 0x93, 0xe2, 0x78, 0xa5, 0xb9, 0xf5, + 0xc3, 0x07, 0x37, 0x66, 0x6e, 0x9d, 0xe3, 0x26, 0x6b, 0x04, 0x9a, 0xc6, 0x90, 0xb8, 0x69, 0x2f, + 0x82, 0x98, 0x91, 0x5f, 0x15, 0xae, 0x4d, 0x3d, 0x4b, 0x73, 0x52, 0xba, 0xa8, 0x73, 0xe4, 0xac, + 0x81, 0x7e, 0x04, 0x6f, 0x3b, 0x26, 0x28, 0x5e, 0x3b, 0x6f, 0xfe, 0x73, 0x38, 0x5e, 0x69, 0xa4, + 0x59, 0xa0, 0xb9, 0xa4, 0xe2, 0x2d, 0x76, 0xe2, 0x24, 0x7a, 0x6b, 0xae, 0xfe, 0x87, 0x1a, 0xef, + 0x2d, 0xee, 0xa4, 0xd9, 0x20, 0xdc, 0x70, 0x75, 0xbe, 0xf2, 0x57, 0x07, 0x88, 0xb7, 0x0d, 0xe7, + 0x22, 0xcd, 0x83, 0x73, 0x25, 0x17, 0xc4, 0x11, 0x68, 0x2e, 0xbb, 0xc4, 0x1d, 0x0e, 0x59, 0x98, + 0x41, 0xa7, 0x59, 0x7a, 0xce, 0x8d, 0xe4, 0xb3, 0xbc, 0x71, 0xbb, 0xca, 0x6b, 0xe4, 0xc9, 0x34, + 0x57, 0x76, 0x04, 0x4a, 0xf3, 0xa5, 0xe2, 0x40, 0x15, 0x4e, 0x31, 0x83, 0xfb, 0xd3, 0xec, 0xb5, + 0xce, 0x27, 0x51, 0x8b, 0x57, 0x88, 0xc4, 0x13, 0x06, 0xb5, 0xf4, 0xb6, 0x36, 0xca, 0xba, 0xf3, + 0x9f, 0xc5, 0x9b, 0x98, 0x9d, 0x85, 0xad, 0x9e, 0xc9, 0xfe, 0x9e, 0xc9, 0x3e, 0xbf, 0x06, 0x14, + 0x68, 0x38, 0xf1, 0xe4, 0x28, 0x75, 0x44, 0xdd, 0xaa, 0xfc, 0xf2, 0xad, 0xee, 0x67, 0xb9, 0x4c, + 0xb3, 0x1d, 0xbb, 0x38, 0x35, 0xd0, 0xb8, 0x6b, 0xb5, 0x31, 0xf1, 0x6f, 0x2f, 0xe5, 0xa4, 0xf9, + 0xd2, 0xb2, 0xc4, 0x41, 0x35, 0x59, 0xde, 0x8e, 0x96, 0x66, 0xfa, 0x1c, 0x33, 0xd0, 0x98, 0x7e, + 0x36, 0xf4, 0xf8, 0xab, 0xb3, 0x40, 0x43, 0xe3, 0xd9, 0x98, 0x5e, 0x4d, 0x33, 0x03, 0x35, 0x50, + 0x08, 0x34, 0x66, 0xd0, 0x35, 0xb5, 0xb7, 0xb8, 0x93, 0x78, 0x4e, 0xe4, 0xae, 0x8f, 0x7b, 0x1b, + 0xe2, 0xcc, 0xa8, 0x20, 0xd0, 0x9c, 0x45, 0x66, 0xaf, 0x46, 0x98, 0xe6, 0x30, 0x99, 0xc4, 0xad, + 0xdc, 0x20, 0xd0, 0x34, 0xb0, 0xba, 0xef, 0xd3, 0x78, 0x9b, 0xc4, 0xf5, 0x8d, 0xfc, 0xdd, 0x82, + 0xe3, 0x38, 0x10, 0x68, 0xa8, 0xb5, 0x34, 0xd7, 0x82, 0xb9, 0xe8, 0xd3, 0xd4, 0x81, 0x40, 0x53, + 0xff, 0x14, 0x56, 0xf9, 0xaf, 0x6d, 0xc3, 0xb9, 0xba, 0x3c, 0xaa, 0xc4, 0x03, 0x64, 0x5a, 0x7a, + 0x5b, 0x05, 0x1a, 0x81, 0xa6, 0x99, 0xed, 0x2d, 0xee, 0x54, 0x3f, 0x03, 0x51, 0x7b, 0xa9, 0x3e, + 0x81, 0x4e, 0x5c, 0x80, 0x7e, 0xf7, 0xab, 0x4c, 0x81, 0x40, 0x93, 0x69, 0x89, 0x1d, 0xac, 0xd7, + 0x61, 0xc7, 0x89, 0xdb, 0x9f, 0x1d, 0x0f, 0x8d, 0x40, 0xd3, 0xe4, 0x5e, 0xce, 0xac, 0x55, 0xbf, + 0x43, 0xfa, 0x93, 0xca, 0x9f, 0xa3, 0x34, 0x27, 0x00, 0x49, 0x3c, 0x48, 0x1d, 0x04, 0x9a, 0x06, + 0x16, 0x1d, 0x4c, 0x3c, 0x87, 0x67, 0x5d, 0x26, 0xaa, 0x89, 0x57, 0x72, 0x69, 0x1b, 0xce, 0xd9, + 0xbf, 0x81, 0x40, 0xd3, 0xcc, 0x12, 0x4f, 0x73, 0x91, 0x1b, 0xc9, 0xd7, 0xe5, 0x28, 0xe4, 0xc4, + 0x40, 0x3b, 0x38, 0x05, 0x81, 0xa6, 0x99, 0x95, 0x67, 0x37, 0x12, 0xd7, 0x79, 0xeb, 0x75, 0x8e, + 0x8b, 0xc4, 0xad, 0xd9, 0x02, 0x8d, 0x40, 0xd3, 0xb4, 0x62, 0x8a, 0x9a, 0x78, 0x92, 0xe5, 0x96, + 0xde, 0xd6, 0x7a, 0xed, 0x94, 0x48, 0x31, 0x83, 0x76, 0xf9, 0x54, 0x04, 0x9a, 0x66, 0xb4, 0xb7, + 0xb8, 0x93, 0xe6, 0xfa, 0x7e, 0x31, 0x7d, 0xae, 0xd7, 0x59, 0xd6, 0x12, 0x1f, 0x9b, 0xd3, 0xbf, + 0xd1, 0x34, 0x9c, 0x0f, 0x9a, 0x3f, 0x4c, 0x4e, 0x9f, 0x8e, 0x2d, 0x26, 0x16, 0x30, 0xa6, 0xcf, + 0x3d, 0x93, 0x7d, 0xf5, 0x7a, 0xfd, 0x48, 0xbc, 0x8f, 0x25, 0x0e, 0xcc, 0xa0, 0x69, 0x36, 0x6b, + 0x53, 0xcf, 0xfe, 0xf7, 0x8f, 0xef, 0xd3, 0x5c, 0x1b, 0xbb, 0x6f, 0x7a, 0xb0, 0x5e, 0xb3, 0xd4, + 0x34, 0xe7, 0x06, 0x31, 0x83, 0xc6, 0x0c, 0x9a, 0xe6, 0xf1, 0x72, 0x66, 0x2d, 0xea, 0x9c, 0xf2, + 0xf2, 0x28, 0x57, 0xef, 0x77, 0x3b, 0x8a, 0x1a, 0x04, 0x9a, 0x8b, 0xb5, 0xb3, 0xb0, 0x15, 0x69, + 0x2e, 0xcf, 0x6e, 0xa6, 0xbf, 0x72, 0x55, 0x6e, 0x24, 0x7f, 0x63, 0x66, 0xc8, 0xd0, 0x81, 0x40, + 0x73, 0x0a, 0x1b, 0xd3, 0x2b, 0x5b, 0x73, 0xaf, 0x3a, 0xc7, 0xba, 0x5a, 0x8b, 0xad, 0xc7, 0x8b, + 0xb0, 0xc7, 0x07, 0x92, 0x1c, 0xac, 0xed, 0x57, 0x36, 0x3f, 0xec, 0x2d, 0xee, 0xc6, 0x2d, 0xee, + 0x19, 0xff, 0x98, 0x66, 0x35, 0xe3, 0x8d, 0x3a, 0x0f, 0xce, 0x95, 0x2c, 0x20, 0x80, 0x40, 0x73, + 0x3a, 0x51, 0xdb, 0xed, 0xf9, 0x72, 0xe2, 0xe6, 0xe5, 0x33, 0x3b, 0x9a, 0x3b, 0xdf, 0x52, 0x67, + 0x10, 0x68, 0xb2, 0xc5, 0xdc, 0x19, 0xea, 0xc2, 0x2e, 0x0e, 0x12, 0x74, 0x7f, 0xda, 0x37, 0xb4, + 0xf0, 0x77, 0x75, 0x06, 0x33, 0x68, 0x32, 0xa4, 0x6d, 0x38, 0x77, 0x63, 0x66, 0xc8, 0xa9, 0x3b, + 0x41, 0xa0, 0xc9, 0x90, 0xa3, 0x43, 0x51, 0xfa, 0x5d, 0x74, 0x15, 0x04, 0x9a, 0x6c, 0xcd, 0x9a, + 0x7b, 0x26, 0xfb, 0xae, 0x4d, 0x14, 0xb3, 0xb9, 0xa6, 0x91, 0xe6, 0x51, 0x55, 0x76, 0xb3, 0xf8, + 0x51, 0x22, 0xd0, 0x34, 0x4f, 0x97, 0x0b, 0xe3, 0xaf, 0x8f, 0x40, 0xc9, 0xf8, 0x71, 0xd2, 0x0e, + 0xe3, 0x46, 0xa0, 0xb9, 0x14, 0x72, 0x23, 0xf9, 0xe8, 0x5d, 0xdc, 0x62, 0xbe, 0xd9, 0x4c, 0xe1, + 0xdb, 0x9a, 0x2b, 0x9b, 0x41, 0x23, 0xd0, 0x64, 0x48, 0xef, 0xc3, 0x81, 0x6b, 0x13, 0xbd, 0x95, + 0xe3, 0x50, 0xaa, 0x9c, 0xb0, 0xa2, 0xbd, 0x94, 0x8b, 0x5b, 0x6b, 0xb1, 0xad, 0x71, 0x8b, 0x9c, + 0xbf, 0x5b, 0xa8, 0xbe, 0xdd, 0x3b, 0xcd, 0x09, 0x95, 0x40, 0xa0, 0xa9, 0xed, 0xcf, 0xb2, 0xd4, + 0x71, 0x19, 0x2e, 0xf5, 0x94, 0xb8, 0x0c, 0x1d, 0x33, 0x68, 0x4f, 0x06, 0x9a, 0xe4, 0xd9, 0x6e, + 0x08, 0x68, 0x2c, 0x89, 0x73, 0xff, 0xfd, 0xc7, 0xbb, 0x07, 0x6b, 0xfb, 0x06, 0x0a, 0x81, 0x86, + 0x5a, 0x4b, 0x73, 0xc5, 0xee, 0xf2, 0xec, 0xa6, 0x81, 0x42, 0xa0, 0x21, 0x73, 0x33, 0xe8, 0x2b, + 0x47, 0x3b, 0xed, 0x0c, 0x14, 0x02, 0x0d, 0x35, 0x7f, 0xca, 0x16, 0xdb, 0x72, 0x23, 0x79, 0x33, + 0x68, 0x04, 0x1a, 0xb2, 0x28, 0x71, 0x17, 0xdd, 0xe1, 0xfa, 0x41, 0x79, 0x76, 0xc3, 0x40, 0x21, + 0xd0, 0x50, 0xfb, 0x40, 0x27, 0x2f, 0x43, 0x6f, 0x4c, 0xaf, 0x1a, 0x28, 0x04, 0x1a, 0x6a, 0xad, + 0x30, 0xde, 0xd3, 0xd2, 0x9b, 0xf0, 0xd4, 0xdd, 0x9e, 0x2f, 0xdb, 0x10, 0x8d, 0x40, 0x43, 0x5d, + 0x1a, 0xdd, 0x9d, 0x78, 0x9f, 0xb5, 0xa9, 0x67, 0x06, 0x0a, 0x81, 0x86, 0x5a, 0x4b, 0x73, 0xe1, + 0xda, 0x57, 0x5f, 0xad, 0x57, 0x2e, 0xf4, 0x05, 0x02, 0x0d, 0xb5, 0xd3, 0x39, 0xd6, 0xd5, 0x36, + 0x9c, 0x4b, 0xbc, 0xdb, 0xea, 0xe4, 0x53, 0x63, 0x85, 0x40, 0x43, 0xad, 0xa5, 0x39, 0x5d, 0xf5, + 0xf6, 0x7c, 0x79, 0x63, 0x7a, 0xc5, 0x58, 0x21, 0xd0, 0x50, 0x53, 0xd7, 0x26, 0x8a, 0x69, 0x26, + 0xd1, 0x6b, 0x53, 0xcf, 0x2c, 0x74, 0x20, 0xd0, 0x90, 0xc5, 0x49, 0xf4, 0xe1, 0xfa, 0xc1, 0xf3, + 0x89, 0x9f, 0x9c, 0x9d, 0x03, 0x81, 0x86, 0x2c, 0x4e, 0xa2, 0x77, 0x1f, 0x6d, 0x3f, 0x1d, 0x5b, + 0x34, 0x5c, 0x08, 0x34, 0xd4, 0xd4, 0x8d, 0x99, 0xa1, 0x34, 0x77, 0x8b, 0x46, 0xc7, 0x3c, 0xda, + 0x70, 0x21, 0xd0, 0x50, 0x3b, 0x9d, 0x63, 0x5d, 0x57, 0xef, 0x77, 0xa7, 0xb9, 0xe7, 0xab, 0xaf, + 0xd6, 0x97, 0x46, 0xbf, 0xb3, 0xd6, 0x81, 0x40, 0x43, 0x4d, 0x27, 0xd1, 0x69, 0x16, 0x3a, 0xae, + 0xfc, 0xb6, 0xd6, 0xe1, 0x77, 0x86, 0x08, 0x34, 0xd4, 0xea, 0x49, 0x5c, 0x6c, 0x7b, 0x6f, 0xf6, + 0xfd, 0x94, 0x77, 0xae, 0x34, 0xda, 0xde, 0x3b, 0x04, 0x1a, 0x6a, 0xa4, 0x63, 0xb4, 0xb3, 0xff, + 0xcb, 0xa1, 0x94, 0x77, 0x3e, 0x5c, 0x3f, 0x78, 0xf1, 0x60, 0x39, 0x32, 0xed, 0xb4, 0xd1, 0x08, + 0x34, 0xd4, 0xc2, 0xb5, 0x89, 0x62, 0xf7, 0xa7, 0x7d, 0xe9, 0xef, 0xbf, 0x3d, 0x5f, 0x5e, 0xbe, + 0xf7, 0xf8, 0x42, 0x33, 0x1d, 0x9f, 0xd9, 0x0e, 0x3f, 0x04, 0x1a, 0x5e, 0xeb, 0x9b, 0x1e, 0xec, + 0xfa, 0xb8, 0xf7, 0x54, 0x1f, 0x52, 0xc9, 0xf4, 0xd2, 0xe8, 0x77, 0x2f, 0x67, 0xd6, 0xce, 0xab, + 0xa4, 0x3b, 0x0b, 0x5b, 0x1b, 0xd3, 0x2b, 0x3f, 0x96, 0xbe, 0x8d, 0xcf, 0xfc, 0xea, 0xab, 0x75, + 0xf3, 0x74, 0xce, 0xcc, 0x55, 0xbd, 0x69, 0x2a, 0x37, 0x66, 0x6e, 0x5d, 0x39, 0xda, 0xb0, 0x71, + 0xaa, 0x8f, 0xda, 0x7d, 0xb4, 0xbd, 0xf2, 0xc9, 0xd2, 0xca, 0x27, 0x57, 0x72, 0x23, 0xf9, 0xc2, + 0x78, 0x4f, 0xe7, 0x58, 0xa1, 0x63, 0xb4, 0x33, 0xf1, 0xf2, 0xe1, 0x6f, 0x4c, 0x96, 0xa3, 0xcb, + 0x71, 0xdb, 0x9a, 0x2b, 0xef, 0x3f, 0xde, 0xfd, 0xe3, 0x7f, 0x2a, 0xc7, 0xe7, 0xf4, 0xa3, 0x41, + 0xa0, 0xe1, 0x75, 0xa3, 0x23, 0xaf, 0x2f, 0x1e, 0x2c, 0x9f, 0xe1, 0x63, 0xa3, 0xd4, 0xeb, 0x8f, + 0x9e, 0xad, 0x7f, 0xf6, 0xfa, 0xef, 0x2d, 0xbd, 0xad, 0xf1, 0x79, 0xda, 0x4b, 0xb9, 0xf6, 0x52, + 0xc7, 0xdb, 0xa2, 0x5c, 0x99, 0x2f, 0x1f, 0xae, 0x1f, 0x54, 0x6f, 0xb7, 0x1f, 0x0a, 0x02, 0x0d, + 0xbf, 0xea, 0x99, 0xec, 0x8f, 0xb0, 0x3e, 0x9f, 0x58, 0xaa, 0x9e, 0xce, 0xea, 0xe2, 0x63, 0xb7, + 0xe7, 0xcb, 0xdb, 0xf3, 0xef, 0xfa, 0x60, 0x22, 0xfa, 0x07, 0x6b, 0xfb, 0xa7, 0x9a, 0x8f, 0x43, + 0x85, 0x35, 0x68, 0x9a, 0x53, 0x61, 0xbc, 0x67, 0x68, 0xe1, 0x4e, 0xfe, 0x6e, 0x21, 0x0b, 0x0f, + 0xc6, 0x24, 0x1a, 0x81, 0x86, 0x3f, 0xbe, 0x3d, 0x2c, 0x75, 0x0c, 0xce, 0x95, 0xae, 0x7f, 0x7e, + 0x33, 0xf1, 0xfa, 0x58, 0x17, 0x1f, 0xe8, 0xb2, 0x1f, 0x07, 0x02, 0x0d, 0x6f, 0xea, 0x99, 0xec, + 0xbf, 0xbd, 0xf8, 0xe1, 0x69, 0x77, 0x77, 0x98, 0x41, 0x23, 0xd0, 0x50, 0x93, 0x67, 0x79, 0xb1, + 0xed, 0xc6, 0xcc, 0xad, 0x5b, 0x3f, 0x7c, 0x50, 0xaf, 0x4c, 0xef, 0x2d, 0xee, 0xfa, 0x29, 0x20, + 0xd0, 0xf0, 0x56, 0xed, 0xa5, 0x8e, 0x4a, 0xa6, 0x7b, 0x1f, 0x0e, 0xa4, 0x3c, 0x77, 0xc7, 0xbb, + 0x8b, 0x2f, 0x74, 0xfd, 0xf3, 0x9b, 0x31, 0x85, 0x37, 0xfe, 0x9c, 0xe5, 0x49, 0x6b, 0x08, 0xb8, + 0x6c, 0x99, 0x2e, 0x4e, 0x0d, 0xc4, 0x6d, 0x67, 0x61, 0xeb, 0xe5, 0xcc, 0x5a, 0x79, 0x76, 0xf3, + 0x8d, 0x6d, 0xcb, 0xe7, 0x22, 0x7f, 0xb7, 0x50, 0x18, 0xef, 0xee, 0x1c, 0xeb, 0xea, 0x18, 0xed, + 0x34, 0xe6, 0x9c, 0x59, 0xcb, 0xf0, 0xe1, 0x47, 0x46, 0xa1, 0x21, 0x54, 0x5f, 0xc7, 0xac, 0xb2, + 0x5d, 0x37, 0x0b, 0x0e, 0xd6, 0xf6, 0xab, 0x9f, 0x43, 0xae, 0x8e, 0x8f, 0x7f, 0x6f, 0x71, 0x67, + 0x6b, 0xae, 0x5c, 0x39, 0xcc, 0x64, 0x7b, 0xfe, 0x2c, 0xbf, 0xcd, 0xab, 0xec, 0x98, 0xae, 0x6c, + 0x9a, 0xae, 0x57, 0x94, 0xe3, 0xc1, 0x57, 0x39, 0x12, 0xb2, 0xb5, 0xd8, 0xe6, 0xa5, 0x42, 0xa0, + 0xa1, 0xe1, 0x1d, 0xbf, 0x96, 0x54, 0xd9, 0x7a, 0xd1, 0x5a, 0x6c, 0xad, 0xf4, 0x4e, 0xf8, 0x10, + 0x68, 0x80, 0xcb, 0xc8, 0x2f, 0x09, 0x01, 0x04, 0x1a, 0x00, 0x81, 0x06, 0x10, 0x68, 0x00, 0x04, + 0x1a, 0x40, 0xa0, 0x01, 0x10, 0x68, 0x00, 0x04, 0x1a, 0x40, 0xa0, 0x01, 0x10, 0x68, 0x00, 0x81, + 0x06, 0x40, 0xa0, 0x01, 0x10, 0x68, 0x00, 0x81, 0x06, 0x40, 0xa0, 0x01, 0x04, 0x1a, 0x00, 0x81, + 0x06, 0x10, 0x68, 0x00, 0x04, 0x1a, 0x00, 0x81, 0x06, 0x10, 0x68, 0x00, 0x04, 0x1a, 0x40, 0xa0, + 0x01, 0x10, 0x68, 0x00, 0x04, 0x1a, 0x40, 0xa0, 0x01, 0x10, 0x68, 0x00, 0x81, 0x06, 0x40, 0xa0, + 0x01, 0x04, 0x1a, 0x00, 0x81, 0x06, 0x40, 0xa0, 0x01, 0x04, 0x1a, 0x00, 0x81, 0x06, 0x10, 0x68, + 0x00, 0x04, 0x1a, 0x00, 0x81, 0x06, 0x10, 0x68, 0x00, 0x04, 0x1a, 0x40, 0xa0, 0x01, 0x10, 0x68, + 0x00, 0x81, 0x36, 0x04, 0x00, 0x02, 0x0d, 0x80, 0x40, 0x03, 0x08, 0x34, 0x00, 0x02, 0x0d, 0x20, + 0xd0, 0x00, 0x08, 0x34, 0x00, 0x02, 0x0d, 0x20, 0xd0, 0x00, 0x08, 0x34, 0x80, 0x40, 0x03, 0x20, + 0xd0, 0x00, 0x08, 0x34, 0x80, 0x40, 0x03, 0x20, 0xd0, 0x00, 0x02, 0x0d, 0x80, 0x40, 0x03, 0x08, + 0x34, 0x00, 0x02, 0x0d, 0x80, 0x40, 0x03, 0x08, 0x34, 0x00, 0x02, 0x0d, 0x20, 0xd0, 0x00, 0x08, + 0x34, 0x00, 0x02, 0x0d, 0x20, 0xd0, 0x00, 0x08, 0x34, 0x80, 0x40, 0x03, 0x20, 0xd0, 0x00, 0x02, + 0x0d, 0x80, 0x40, 0x03, 0x20, 0xd0, 0x00, 0x02, 0x0d, 0x80, 0x40, 0x03, 0x08, 0x34, 0x00, 0x02, + 0x0d, 0x80, 0x40, 0x03, 0x08, 0x34, 0x00, 0x02, 0x0d, 0x20, 0xd0, 0x00, 0x08, 0x34, 0x80, 0x40, + 0x03, 0x20, 0xd0, 0x00, 0x08, 0x34, 0x80, 0x40, 0x03, 0x20, 0xd0, 0x00, 0x02, 0x0d, 0x80, 0x40, + 0x03, 0x20, 0xd0, 0x00, 0x02, 0x0d, 0x80, 0x40, 0x03, 0x08, 0x34, 0x00, 0x02, 0x0d, 0x80, 0x40, + 0x03, 0x08, 0x34, 0x00, 0x02, 0x0d, 0x20, 0xd0, 0x00, 0x08, 0x34, 0x80, 0x40, 0x03, 0x20, 0xd0, + 0x00, 0x08, 0x34, 0x40, 0x23, 0xfa, 0xbf, 0x00, 0x03, 0x00, 0x60, 0x2f, 0x3c, 0xc6, 0xbd, 0xc0, + 0x07, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#endif diff --git a/src/samples/savedata/utility/main.c b/src/samples/savedata/utility/main.c new file mode 100644 index 00000000..f16408af --- /dev/null +++ b/src/samples/savedata/utility/main.c @@ -0,0 +1,369 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Sample to demonstrate how to use savedata utility + * + * Copyright (c) 2005 weltall (weltall@consoleworld.org) + * (c) 2007 InsertWittyName (tias_dp@hotmail.com) + * Based on work by Shine + * + * $Id: main.c 2364 2008-02-16 22:07:09Z iwn $ + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "data.h" + +PSP_MODULE_INFO("Savedata Sample", 0, 1, 1); + +#if _PSP_FW_VERSION >= 200 +PSP_HEAP_SIZE_KB(20480); +#endif + +#define BUF_WIDTH (512) +#define SCR_WIDTH (480) +#define SCR_HEIGHT (272) +#define PIXEL_SIZE (4) /* change this if you change to another screenmode */ +#define FRAME_SIZE (BUF_WIDTH * SCR_HEIGHT * PIXEL_SIZE) +#define ZBUF_SIZE (BUF_WIDTH SCR_HEIGHT * 2) /* zbuffer seems to be 16-bit? */ + +#define DATABUFFLEN 0x20 + +static int running = 1; + +char string[128]; + +// Exit callback +int exit_callback(int arg1, int arg2, void *common) +{ + running = 0; + + return 0; +} + +// Callback thread +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + sceKernelSleepThreadCB(); + + return 0; +} + +// Sets up the callback thread and returns its thread id +int SetupCallbacks(void) +{ + int thid = 0; + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0); + if (thid >= 0) + sceKernelStartThread(thid, 0, 0); + return thid; +} + + +// Graphics stuff, based on cube sample +static unsigned int __attribute__((aligned(16))) list[262144]; + +struct Vertex +{ + float u, v; + unsigned int color; + float x, y, z; +}; + +struct Vertex __attribute__((aligned(16))) vertices[12*3] = +{ + {0, 0, 0xff7f0000,-1,-1, 1}, // 0 + {1, 0, 0xff7f0000,-1, 1, 1}, // 4 + {1, 1, 0xff7f0000, 1, 1, 1}, // 5 + + {0, 0, 0xff7f0000,-1,-1, 1}, // 0 + {1, 1, 0xff7f0000, 1, 1, 1}, // 5 + {0, 1, 0xff7f0000, 1,-1, 1}, // 1 + + {0, 0, 0xff7f0000,-1,-1,-1}, // 3 + {1, 0, 0xff7f0000, 1,-1,-1}, // 2 + {1, 1, 0xff7f0000, 1, 1,-1}, // 6 + + {0, 0, 0xff7f0000,-1,-1,-1}, // 3 + {1, 1, 0xff7f0000, 1, 1,-1}, // 6 + {0, 1, 0xff7f0000,-1, 1,-1}, // 7 + + {0, 0, 0xff007f00, 1,-1,-1}, // 0 + {1, 0, 0xff007f00, 1,-1, 1}, // 3 + {1, 1, 0xff007f00, 1, 1, 1}, // 7 + + {0, 0, 0xff007f00, 1,-1,-1}, // 0 + {1, 1, 0xff007f00, 1, 1, 1}, // 7 + {0, 1, 0xff007f00, 1, 1,-1}, // 4 + + {0, 0, 0xff007f00,-1,-1,-1}, // 0 + {1, 0, 0xff007f00,-1, 1,-1}, // 3 + {1, 1, 0xff007f00,-1, 1, 1}, // 7 + + {0, 0, 0xff007f00,-1,-1,-1}, // 0 + {1, 1, 0xff007f00,-1, 1, 1}, // 7 + {0, 1, 0xff007f00,-1,-1, 1}, // 4 + + {0, 0, 0xff00007f,-1, 1,-1}, // 0 + {1, 0, 0xff00007f, 1, 1,-1}, // 1 + {1, 1, 0xff00007f, 1, 1, 1}, // 2 + + {0, 0, 0xff00007f,-1, 1,-1}, // 0 + {1, 1, 0xff00007f, 1, 1, 1}, // 2 + {0, 1, 0xff00007f,-1, 1, 1}, // 3 + + {0, 0, 0xff00007f,-1,-1,-1}, // 4 + {1, 0, 0xff00007f,-1,-1, 1}, // 7 + {1, 1, 0xff00007f, 1,-1, 1}, // 6 + + {0, 0, 0xff00007f,-1,-1,-1}, // 4 + {1, 1, 0xff00007f, 1,-1, 1}, // 6 + {0, 1, 0xff00007f, 1,-1,-1}, // 5 +}; + +static void SetupGu() +{ + sceGuInit(); + + sceGuStart(GU_DIRECT,list); + sceGuDrawBuffer(GU_PSM_8888,(void*)0,BUF_WIDTH); + sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,(void*)0x88000,BUF_WIDTH); + sceGuDepthBuffer((void*)0x110000,BUF_WIDTH); + sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); + sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); + sceGuDepthRange(0xc350,0x2710); + sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + sceGuDepthFunc(GU_GEQUAL); + sceGuEnable(GU_DEPTH_TEST); + sceGuFrontFace(GU_CW); + sceGuShadeModel(GU_SMOOTH); + sceGuEnable(GU_CULL_FACE); + sceGuEnable(GU_CLIP_PLANES); + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuDisplay(GU_TRUE); +} + +static void DrawStuff(void) +{ + static int val = 0; + + sceGuStart(GU_DIRECT,list); + + // Clear screen + sceGuClearColor(0xff554433); + sceGuClearDepth(0); + sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); + + // Setup matrices for cube + sceGumMatrixMode(GU_PROJECTION); + sceGumLoadIdentity(); + sceGumPerspective(75.0f,16.0f/9.0f,0.5f,1000.0f); + + sceGumMatrixMode(GU_VIEW); + sceGumLoadIdentity(); + + sceGumMatrixMode(GU_MODEL); + sceGumLoadIdentity(); + { + ScePspFVector3 pos = { 0, 0, -2.5f }; + ScePspFVector3 rot = { val * 0.79f * (M_PI/180.0f), val * 0.98f * (M_PI/180.0f), val * 1.32f * (M_PI/180.0f) }; + sceGumRotateXYZ(&rot); + sceGumTranslate(&pos); + } + + // Draw cube + sceGuAmbientColor(0xffffffff); + sceGumDrawArray(GU_TRIANGLES,GU_TEXTURE_32BITF|GU_COLOR_8888|GU_VERTEX_32BITF|GU_TRANSFORM_3D,12*3,0,vertices); + + sceGuFinish(); + sceGuSync(0,0); + + val ++; +} + +PspUtilitySavedataListSaveNewData newData; + +char *titleShow = "New Save"; + +char nameMultiple[][20] = // End list with "" +{ + "0000", + "0001", + "0002", + "0003", + "0004", + "" +}; + +char key[] = "QTAK319JQKJ952HA"; // Key to encrypt or decrypt savedata + +void initSavedata(SceUtilitySavedataParam * savedata, int mode) +{ + memset(savedata, 0, sizeof(SceUtilitySavedataParam)); + savedata->base.size = sizeof(SceUtilitySavedataParam); + + savedata->base.language = PSP_SYSTEMPARAM_LANGUAGE_ENGLISH; + savedata->base.buttonSwap = PSP_UTILITY_ACCEPT_CROSS; + savedata->base.graphicsThread = 0x11; + savedata->base.accessThread = 0x13; + savedata->base.fontThread = 0x12; + savedata->base.soundThread = 0x10; + + savedata->mode = mode; + savedata->overwrite = 1; + savedata->focus = PSP_UTILITY_SAVEDATA_FOCUS_LATEST; // Set initial focus to the newest file (for loading) + +#if _PSP_FW_VERSION >= 200 + strncpy(savedata->key, key, 16); +#endif + + strcpy(savedata->gameName, "DEMO11111"); // First part of the save name, game identifier name + strcpy(savedata->saveName, "0000"); // Second part of the save name, save identifier name + + // List of multiple names + savedata->saveNameList = nameMultiple; + + strcpy(savedata->fileName, "DATA.BIN"); // name of the data file + + // Allocate buffers used to store various parts of the save data + savedata->dataBuf = malloc(DATABUFFLEN); + savedata->dataBufSize = DATABUFFLEN; + savedata->dataSize = DATABUFFLEN; + + // Set some data + if (mode == PSP_UTILITY_SAVEDATA_LISTSAVE) + { + memset(savedata->dataBuf, 0, DATABUFFLEN); + strcpy(savedata->dataBuf,"score: 10"); + + strcpy(savedata->sfoParam.title,"Title"); + strcpy(savedata->sfoParam.savedataTitle,"Title 2"); + strcpy(savedata->sfoParam.detail,"Details"); + savedata->sfoParam.parentalLevel = 1; + + // No icon1 + savedata->icon1FileData.buf = NULL; + savedata->icon1FileData.bufSize = 0; + savedata->icon1FileData.size = 0; + + savedata->pic1FileData.buf = pic1; + savedata->pic1FileData.bufSize = size_pic1; + savedata->pic1FileData.size = size_pic1; + + savedata->icon0FileData.buf = icon0; + savedata->icon0FileData.bufSize = size_icon0; + savedata->icon0FileData.size = size_icon0; + + // No snd0 + savedata->snd0FileData.buf = NULL; + savedata->snd0FileData.bufSize = 0; + savedata->snd0FileData.size = 0; + + // Set title + newData.title = titleShow; + + // Set new data + savedata->newData = &newData; + + savedata->focus = PSP_UTILITY_SAVEDATA_FOCUS_FIRSTEMPTY; // If saving, set inital focus to the first empty slot + } +} + +static void ShowSaveDialog (int mode) +{ + SceUtilitySavedataParam dialog; + + initSavedata(&dialog, mode); + + sceUtilitySavedataInitStart(&dialog); + + while(running) { + + DrawStuff(); + + switch(sceUtilitySavedataGetStatus()) { + + case PSP_UTILITY_DIALOG_VISIBLE : + + sceUtilitySavedataUpdate(1); + break; + + case PSP_UTILITY_DIALOG_QUIT : + + sceUtilitySavedataShutdownStart(); + break; + + case PSP_UTILITY_DIALOG_FINISHED : + if(mode == PSP_UTILITY_SAVEDATA_LISTSAVE) + sprintf(string, "Saved: score = 10"); + else + sprintf(string, "Loaded: %s\n", (char*)dialog.dataBuf); // The actual data in the savedata file that was saved previously + + case PSP_UTILITY_DIALOG_NONE : + return; + } + + sceDisplayWaitVblankStart(); + sceGuSwapBuffers(); + } +} + +int main(int argc, char *argv[]) +{ + SceCtrlData pad; + + SetupCallbacks(); + SetupGu(); + + pspDebugScreenInit(); + + int mode = 0; + + memset(string, 0, sizeof(string)); + + while(running) + { + pspDebugScreenSetXY(0, 0); + + pspDebugScreenPrintf("Press X to Save, O to Load\n"); + pspDebugScreenPrintf(string); + + sceCtrlReadBufferPositive(&pad, 1); + + if(pad.Buttons & PSP_CTRL_CROSS) + mode = PSP_UTILITY_SAVEDATA_LISTSAVE; + + else if(pad.Buttons & PSP_CTRL_CIRCLE) + mode = PSP_UTILITY_SAVEDATA_LISTLOAD; + + if(mode) + { + ShowSaveDialog(mode); + pspDebugScreenInit(); + mode = 0; + } + } + + sceKernelExitGame(); + + return 0; +} diff --git a/src/samples/template/elf_template/Makefile.sample b/src/samples/template/elf_template/Makefile.sample new file mode 100644 index 00000000..9bd56434 --- /dev/null +++ b/src/samples/template/elf_template/Makefile.sample @@ -0,0 +1,16 @@ +TARGET = template +OBJS = main.o + +INCDIR = +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Template + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/template/elf_template/main.c b/src/samples/template/elf_template/main.c new file mode 100644 index 00000000..29283185 --- /dev/null +++ b/src/samples/template/elf_template/main.c @@ -0,0 +1,33 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Basic ELF template + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: main.c 1888 2006-05-01 08:47:04Z tyranid $ + * $HeadURL$ + */ +#include +#include + +#define printf pspDebugScreenPrintf + +/* Define the module info section */ +PSP_MODULE_INFO("template", 0, 1, 1); + +/* Define the main thread's attribute value (optional) */ +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU); + +int main(int argc, char *argv[]) +{ + pspDebugScreenInit(); + + pspDebugScreenPrintf("Hello World\n"); + + return 0; +} diff --git a/src/samples/template/kprx_template/Makefile.sample b/src/samples/template/kprx_template/Makefile.sample new file mode 100644 index 00000000..eb3e1035 --- /dev/null +++ b/src/samples/template/kprx_template/Makefile.sample @@ -0,0 +1,19 @@ +TARGET = ktemplate +OBJS = main.o + +# Use the kernel's small inbuilt libc +USE_KERNEL_LIBC = 1 +# Use only kernel libraries +USE_KERNEL_LIBS = 1 + +INCDIR = +CFLAGS = -O2 -G0 -Wall -fno-builtin-printf +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = + +LIBS = + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build_prx.mak diff --git a/src/samples/template/kprx_template/exports.exp b/src/samples/template/kprx_template/exports.exp new file mode 100644 index 00000000..b7940e81 --- /dev/null +++ b/src/samples/template/kprx_template/exports.exp @@ -0,0 +1,12 @@ +# Define the exports for the prx +PSP_BEGIN_EXPORTS + +# These four lines are mandatory (although you can add other functions like module_stop) +# syslib is a psynonym for the single mandatory export. +PSP_EXPORT_START(syslib, 0, 0x8000) +PSP_EXPORT_FUNC(module_start) +PSP_EXPORT_FUNC(module_stop) +PSP_EXPORT_VAR(module_info) +PSP_EXPORT_END + +PSP_END_EXPORTS diff --git a/src/samples/template/kprx_template/main.c b/src/samples/template/kprx_template/main.c new file mode 100644 index 00000000..9eb228c5 --- /dev/null +++ b/src/samples/template/kprx_template/main.c @@ -0,0 +1,44 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Basic Kernel PRX template + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id$ + * $HeadURL$ + */ +#include +#include + +PSP_MODULE_INFO("template", PSP_MODULE_KERNEL, 1, 1); + +int main_thread(SceSize args, void *argp) +{ + printf("Hello World\n"); + + return 0; +} + +/* Entry point */ +int module_start(SceSize args, void *argp) +{ + int thid; + + thid = sceKernelCreateThread("template", main_thread, 7, 0x800, 0, NULL); + if(thid >= 0) + { + sceKernelStartThread(thid, args, argp); + } + return 0; +} + +/* Module stop entry */ +int module_stop(SceSize args, void *argp) +{ + return 0; +} diff --git a/src/samples/template/lib_template/Makefile.sample b/src/samples/template/lib_template/Makefile.sample new file mode 100644 index 00000000..81a901a3 --- /dev/null +++ b/src/samples/template/lib_template/Makefile.sample @@ -0,0 +1,13 @@ +TARGET_LIB = libtemplate.a +OBJS = template.o + +INCDIR = +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/template/lib_template/template.c b/src/samples/template/lib_template/template.c new file mode 100644 index 00000000..a25616ca --- /dev/null +++ b/src/samples/template/lib_template/template.c @@ -0,0 +1,18 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * template.c - Template source file for a library + * + * Copyright (c) 2005 James F + * + * $Id: template.c 1888 2006-05-01 08:47:04Z tyranid $ + */ + +#include "template.h" + +int template_call(void) +{ + return 0; +} diff --git a/src/samples/template/lib_template/template.h b/src/samples/template/lib_template/template.h new file mode 100644 index 00000000..967226be --- /dev/null +++ b/src/samples/template/lib_template/template.h @@ -0,0 +1,26 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * template.c - Template source file for a library + * + * Copyright (c) 2005 James F + * + * $Id: template.h 1888 2006-05-01 08:47:04Z tyranid $ + */ + +#ifndef __TEMPLATE_H +#define __TEMPLATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +int template_call(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/samples/template/prx_template/Makefile.sample b/src/samples/template/prx_template/Makefile.sample new file mode 100644 index 00000000..add22c49 --- /dev/null +++ b/src/samples/template/prx_template/Makefile.sample @@ -0,0 +1,15 @@ +TARGET = template +OBJS = main.o + +BUILD_PRX=1 + +INCDIR = +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +LIBDIR = +LDFLAGS = + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/template/prx_template/main.c b/src/samples/template/prx_template/main.c new file mode 100644 index 00000000..73fb7afb --- /dev/null +++ b/src/samples/template/prx_template/main.c @@ -0,0 +1,29 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Basic PRX template + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: main.c 1888 2006-05-01 08:47:04Z tyranid $ + * $HeadURL$ + */ +#include +#include + +/* Define the module info section */ +PSP_MODULE_INFO("template", 0, 1, 1); + +/* Define the main thread's attribute value (optional) */ +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU); + +int main(int argc, char *argv[]) +{ + printf("Hello World\n"); + + return 0; +} diff --git a/src/samples/usb/storage/Makefile.sample b/src/samples/usb/storage/Makefile.sample new file mode 100644 index 00000000..d7fcb8ba --- /dev/null +++ b/src/samples/usb/storage/Makefile.sample @@ -0,0 +1,10 @@ +PSPSDK = $(shell psp-config --pspsdk-path) +PSPLIBSDIR = $(PSPSDK)/.. +TARGET = usbstorage +OBJS = main.o +LIBS = -lpspusb -lpspusbstor +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/usb/storage/main.c b/src/samples/usb/storage/main.c new file mode 100644 index 00000000..b58337ff --- /dev/null +++ b/src/samples/usb/storage/main.c @@ -0,0 +1,211 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Sample to demonstrate USB Mass Storage functionality + * + * Copyright (c) 2005 John Kelley + * + * Derived from code written by PspPet + * Code flow and API usage from VSH module "sysconf_plugin.prx" + * + * $Id: main.c 1882 2006-04-24 00:25:11Z jim $ + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * Define the module info section + * + * 2nd arg must 0x1000 so __init is executed in + * kernelmode for our loaderInit function + */ +PSP_MODULE_INFO("USBSample", 0x1000, 1, 0); + +/** + * THREAD_ATTR_USER causes the thread that the startup + * code (ctr0.c) starts this program in to be in usermode + * even though the module was started in kernelmode + */ +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER); + +/* Define printf, just to make typing easier */ +#define printf pspDebugScreenPrintf + +//make this global so we can check it in the exit_callback +u32 state; + +/** + * Function that is called from _init in kernelmode before the + * main thread is started in usermode. + */ +__attribute__ ((constructor)) +void loaderInit() +{ + pspKernelSetKernelPC(); + pspSdkInstallNoDeviceCheckPatch(); + pspDebugInstallKprintfHandler(NULL); +} + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + int retVal; + + //cleanup drivers + if (state & PSP_USB_ACTIVATED) { + retVal = sceUsbDeactivate(0); + if (retVal != 0) + printf("Error calling sceUsbDeactivate (0x%08X)\n", retVal); + } + retVal = sceUsbStop(PSP_USBSTOR_DRIVERNAME, 0, 0); + if (retVal != 0) + printf("Error stopping USB Mass Storage driver (0x%08X)\n", + retVal); + + retVal = sceUsbStop(PSP_USBBUS_DRIVERNAME, 0, 0); + if (retVal != 0) + printf("Error stopping USB BUS driver (0x%08X)\n", retVal); + + sceKernelExitGame(); + + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + + thid = sceKernelCreateThread("update_thread", CallbackThread, + 0x11, 0xFA0, 0, 0); + if (thid >= 0) { + sceKernelStartThread(thid, 0, 0); + } + + return thid; +} + +//helper function to make things easier +int LoadStartModule(char *path) +{ + u32 loadResult; + u32 startResult; + int status; + + loadResult = sceKernelLoadModule(path, 0, NULL); + if (loadResult & 0x80000000) + return -1; + else + startResult = + sceKernelStartModule(loadResult, 0, NULL, &status, NULL); + + if (loadResult != startResult) + return -2; + + return 0; +} + +int main(void) +{ + SceCtrlData pad; + u32 oldButtons = 0; + u32 retVal; + + state = 0; + pspDebugScreenInit(); + pspDebugScreenClear(); + SetupCallbacks(); + + //setup Pad + sceCtrlSetSamplingCycle(0); + sceCtrlSetSamplingMode(0); + + //print header now in case we have any errors + printf("USB Sample v1.0 by John_K - Based off work by PSPPet\n"); + + //start necessary drivers + LoadStartModule("flash0:/kd/semawm.prx"); + LoadStartModule("flash0:/kd/usbstor.prx"); + LoadStartModule("flash0:/kd/usbstormgr.prx"); + LoadStartModule("flash0:/kd/usbstorms.prx"); + LoadStartModule("flash0:/kd/usbstorboot.prx"); + + //setup USB drivers + retVal = sceUsbStart(PSP_USBBUS_DRIVERNAME, 0, 0); + if (retVal != 0) { + printf("Error starting USB Bus driver (0x%08X)\n", retVal); + sceKernelSleepThread(); + } + retVal = sceUsbStart(PSP_USBSTOR_DRIVERNAME, 0, 0); + if (retVal != 0) { + printf("Error starting USB Mass Storage driver (0x%08X)\n", + retVal); + sceKernelSleepThread(); + } + retVal = sceUsbstorBootSetCapacity(0x800000); + if (retVal != 0) { + printf + ("Error setting capacity with USB Mass Storage driver (0x%08X)\n", + retVal); + sceKernelSleepThread(); + } + retVal = 0; + + //if everything worked we now enter our main loop + for (;;) { + + sceCtrlReadBufferPositive(&pad, 1); + state = sceUsbGetState(); + pspDebugScreenSetXY(0, 0); + printf("USB Sample v1.0 by John_K - Based off work by PSPPet\n\n"); + printf("%-14s: %s\n", "USB Driver", + state & PSP_USB_ACTIVATED ? "activated " : + "deactivated"); + printf("%-14s: %s\n", "USB Cable", + state & PSP_USB_CABLE_CONNECTED ? "connected " : + "disconnected"); + printf("%-14s: %s\n", "USB Connection", + state & PSP_USB_CONNECTION_ESTABLISHED ? "established" : + "not present"); + printf("\nPress X to establish or destroy the USB connection\n"); + + if (oldButtons != pad.Buttons) { + if (pad.Buttons & PSP_CTRL_CROSS) { + if (state & PSP_USB_ACTIVATED) + retVal = sceUsbDeactivate(0x1c8); + else + retVal = sceUsbActivate(0x1c8); + } + } + oldButtons = pad.Buttons; + sceDisplayWaitVblankStart(); + } + + + //Exit program + sceKernelExitGame(); + + return 0; +} diff --git a/src/samples/utility/gamesharing/Makefile.sample b/src/samples/utility/gamesharing/Makefile.sample new file mode 100644 index 00000000..530b924d --- /dev/null +++ b/src/samples/utility/gamesharing/Makefile.sample @@ -0,0 +1,20 @@ +TARGET = gamesharing +OBJS = main.o + +PSP_FW_VERSION = 200 +BUILD_PRX = 1 + +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + + +LIBDIR = +LDFLAGS = +LIBS = -lpsputility -lpspgum -lpspgu -lm -lpspnet_adhoc -lpspnet_adhocctl -lpspnet_adhocmatching + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Game Sharing Sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/utility/gamesharing/main.c b/src/samples/utility/gamesharing/main.c new file mode 100644 index 00000000..bbcc9bb9 --- /dev/null +++ b/src/samples/utility/gamesharing/main.c @@ -0,0 +1,398 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Game Sharing sample + * + * Copyright (c) 2007 David Perry (Insert_Witty_Name) + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PSP_MODULE_INFO("Game Sharing Sample", 0, 1, 1); +PSP_HEAP_SIZE_KB(1024); + +static int running = 1; + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + running = 0; + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, PSP_THREAD_ATTR_USER, 0); + + if (thid >= 0) + sceKernelStartThread(thid, 0, 0); + + return thid; +} + +/* Graphics stuff, based on cube sample */ +static unsigned int __attribute__((aligned(16))) list[262144]; + +struct Vertex +{ + unsigned int color; + float x,y,z; +}; + +struct Vertex __attribute__((aligned(16))) vertices[12*3] = +{ + {0xff7f0000,-1,-1, 1}, // 0 + {0xff7f0000,-1, 1, 1}, // 4 + {0xff7f0000, 1, 1, 1}, // 5 + + {0xff7f0000,-1,-1, 1}, // 0 + {0xff7f0000, 1, 1, 1}, // 5 + {0xff7f0000, 1,-1, 1}, // 1 + + {0xff7f0000,-1,-1,-1}, // 3 + {0xff7f0000, 1,-1,-1}, // 2 + {0xff7f0000, 1, 1,-1}, // 6 + + {0xff7f0000,-1,-1,-1}, // 3 + {0xff7f0000, 1, 1,-1}, // 6 + {0xff7f0000,-1, 1,-1}, // 7 + + {0xff007f00, 1,-1,-1}, // 0 + {0xff007f00, 1,-1, 1}, // 3 + {0xff007f00, 1, 1, 1}, // 7 + + {0xff007f00, 1,-1,-1}, // 0 + {0xff007f00, 1, 1, 1}, // 7 + {0xff007f00, 1, 1,-1}, // 4 + + {0xff007f00,-1,-1,-1}, // 0 + {0xff007f00,-1, 1,-1}, // 3 + {0xff007f00,-1, 1, 1}, // 7 + + {0xff007f00,-1,-1,-1}, // 0 + {0xff007f00,-1, 1, 1}, // 7 + {0xff007f00,-1,-1, 1}, // 4 + + {0xff00007f,-1, 1,-1}, // 0 + {0xff00007f, 1, 1,-1}, // 1 + {0xff00007f, 1, 1, 1}, // 2 + + {0xff00007f,-1, 1,-1}, // 0 + {0xff00007f, 1, 1, 1}, // 2 + {0xff00007f,-1, 1, 1}, // 3 + + {0xff00007f,-1,-1,-1}, // 4 + {0xff00007f,-1,-1, 1}, // 7 + {0xff00007f, 1,-1, 1}, // 6 + + {0xff00007f,-1,-1,-1}, // 4 + {0xff00007f, 1,-1, 1}, // 6 + {0xff00007f, 1,-1,-1}, // 5 +}; + +#define BUF_WIDTH (512) +#define SCR_WIDTH (480) +#define SCR_HEIGHT (272) +#define PIXEL_SIZE (4) +#define FRAME_SIZE (BUF_WIDTH * SCR_HEIGHT * PIXEL_SIZE) +#define ZBUF_SIZE (BUF_WIDTH SCR_HEIGHT * 2) + +static void setupGu() +{ + sceGuInit(); + + sceGuStart(GU_DIRECT,list); + sceGuDrawBuffer(GU_PSM_8888,(void*)0,BUF_WIDTH); + sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,(void*)0x88000,BUF_WIDTH); + sceGuDepthBuffer((void*)0x110000,BUF_WIDTH); + sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); + sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); + sceGuDepthRange(0xc350,0x2710); + sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + sceGuDepthFunc(GU_GEQUAL); + sceGuEnable(GU_DEPTH_TEST); + sceGuFrontFace(GU_CW); + sceGuShadeModel(GU_SMOOTH); + sceGuEnable(GU_CULL_FACE); + sceGuEnable(GU_CLIP_PLANES); + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuDisplay(GU_TRUE); +} + +static void drawStuff(void) +{ + static int val = 0; + + sceGuStart(GU_DIRECT, list); + + sceGuClearColor(0xff554433); + sceGuClearDepth(0); + sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); + + sceGumMatrixMode(GU_PROJECTION); + sceGumLoadIdentity(); + sceGumPerspective(75.0f,16.0f/9.0f,0.5f,1000.0f); + + sceGumMatrixMode(GU_VIEW); + sceGumLoadIdentity(); + + sceGumMatrixMode(GU_MODEL); + sceGumLoadIdentity(); + + ScePspFVector3 pos = { 0, 0, -5.0f }; + ScePspFVector3 rot = { val * 0.79f * (M_PI/180.0f), val * 0.98f * (M_PI/180.0f), val * 1.32f * (M_PI/180.0f) }; + sceGumTranslate(&pos); + sceGumRotateXYZ(&rot); + + sceGumDrawArray(GU_TRIANGLES, GU_COLOR_8888|GU_VERTEX_32BITF|GU_TRANSFORM_3D, 12*3, 0, vertices); + + sceGuFinish(); + sceGuSync(0,0); + + val++; +} + +int adhocDialog() +{ + int done = 0; + + pspUtilityNetconfData data; + + memset(&data, 0, sizeof(data)); + data.base.size = sizeof(data); + data.base.language = PSP_SYSTEMPARAM_LANGUAGE_ENGLISH; + data.base.buttonSwap = PSP_UTILITY_ACCEPT_CROSS; + data.base.graphicsThread = 17; + data.base.accessThread = 19; + data.base.fontThread = 18; + data.base.soundThread = 16; + data.action = PSP_NETCONF_ACTION_CONNECT_ADHOC; + + struct pspUtilityNetconfAdhoc adhocparam; + memset(&adhocparam, 0, sizeof(adhocparam)); + memcpy(&adhocparam.name, "GameShar", 8); + adhocparam.timeout = 60; + data.adhocparam = &adhocparam; + + sceUtilityNetconfInitStart(&data); + + while(running) + { + drawStuff(); + + switch(sceUtilityNetconfGetStatus()) + { + case PSP_UTILITY_DIALOG_NONE: + done = 1; + break; + + case PSP_UTILITY_DIALOG_VISIBLE: + sceUtilityNetconfUpdate(1); + break; + + case PSP_UTILITY_DIALOG_QUIT: + sceUtilityNetconfShutdownStart(); + break; + + case PSP_UTILITY_DIALOG_FINISHED: + break; + + default: + break; + } + + sceDisplayWaitVblankStart(); + sceGuSwapBuffers(); + + if(done) + break; + } + + return 1; +} + +int gsDialog() +{ + int done = 0; + + sceNetAdhocMatchingInit(32*1024); + + pspUtilityGameSharingParams params; + + memset(¶ms, 0, sizeof(params)); + params.base.size = sizeof(params); + params.base.language = PSP_SYSTEMPARAM_LANGUAGE_ENGLISH; + params.base.buttonSwap = PSP_UTILITY_ACCEPT_CROSS; + params.base.graphicsThread = 17; + params.base.accessThread = 19; + params.base.fontThread = 18; + params.base.soundThread = 16; + + int fd = sceIoOpen("EBOOT.PBP", PSP_O_RDONLY, 0777); + + params.datasize = sceIoLseek32(fd, 0, PSP_SEEK_END); + + unsigned char *fileBuffer = memalign(64, params.datasize); + + sceIoLseek32(fd, 0, PSP_SEEK_SET); + + sceIoRead(fd, fileBuffer, params.datasize); + + sceIoClose(fd); + + // Manually patch the PARAM.SFO in the EBOOT + fileBuffer[276] = 0x57; + // And add a custom filename + strncpy((char *) &fileBuffer[320], "PSPSDK GameShare", 127); + + memcpy(¶ms.name, "GameShar", 8); + + params.mode = PSP_UTILITY_GAMESHARING_MODE_MULTIPLE; + params.datatype = PSP_UTILITY_GAMESHARING_DATA_TYPE_MEMORY; + + params.data = fileBuffer; + + sceUtilityGameSharingInitStart(¶ms); + + while(running) + { + drawStuff(); + + switch(sceUtilityGameSharingGetStatus()) + { + case PSP_UTILITY_DIALOG_NONE: + sceNetAdhocMatchingTerm(); + done = 1; + break; + + case PSP_UTILITY_DIALOG_VISIBLE: + sceUtilityGameSharingUpdate(1); + break; + + case PSP_UTILITY_DIALOG_QUIT: + sceUtilityGameSharingShutdownStart(); + break; + + case PSP_UTILITY_DIALOG_FINISHED: + break; + + default: + break; + } + + sceDisplayWaitVblankStart(); + sceGuSwapBuffers(); + + if(done) + break; + } + + free(fileBuffer); + + return 1; +} + +void adhocInit(void) +{ + sceUtilityLoadNetModule(PSP_NET_MODULE_COMMON); + + sceUtilityLoadNetModule(PSP_NET_MODULE_ADHOC); + + sceNetInit(128*1024, 42, 4*1024, 42, 4*1024); + + sceNetAdhocInit(); + + struct productStruct gameProduct; + + gameProduct.unknown = 2; + + memcpy(gameProduct.product, "000000001", 9); + + sceNetAdhocctlInit(32*1024, 0x20, &gameProduct); +} + +void adhocTerm(void) +{ + sceNetAdhocctlDisconnect(); + + sceNetAdhocctlTerm(); + + sceNetAdhocTerm(); + + sceNetTerm(); + + sceUtilityUnloadNetModule(PSP_NET_MODULE_ADHOC); + + sceUtilityUnloadNetModule(PSP_NET_MODULE_COMMON); +} + + +/* main routine */ +int main(int argc, char *argv[]) +{ + SetupCallbacks(); + + if(argc > 1) + { + if(strcmp(argv[2], "GameShar") == 0) + { + pspDebugScreenInit(); + pspDebugScreenPrintf("This is a game shared EBOOT.\n\n"); + pspDebugScreenPrintf("Arguments passed are:\n"); + + pspDebugScreenPrintf("MAC address of sender: %s\n", argv[1]); + pspDebugScreenPrintf("Name: %s\n", argv[2]); + + while(running) + sceKernelDelayThread(1000); + + sceKernelExitGame(); + } + } + + setupGu(); + + adhocInit(); + + adhocDialog(); + + gsDialog(); + + adhocTerm(); + + sceKernelExitGame(); + + return 0; +} diff --git a/src/samples/utility/htmlviewer/Makefile.sample b/src/samples/utility/htmlviewer/Makefile.sample new file mode 100644 index 00000000..4750f53f --- /dev/null +++ b/src/samples/utility/htmlviewer/Makefile.sample @@ -0,0 +1,17 @@ +TARGET = htmlsample +OBJS = main.o + +INCDIR = +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +BUILD_PRX = 1 +EXTRA_TARGETS = EBOOT.PBP + +LIBDIR = +LDFLAGS = +LIBS = -lpsputility -lpsphttp -lpspssl -lpspgum -lpspgu -lm + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/utility/htmlviewer/main.c b/src/samples/utility/htmlviewer/main.c new file mode 100644 index 00000000..2ea09476 --- /dev/null +++ b/src/samples/utility/htmlviewer/main.c @@ -0,0 +1,293 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +PSP_MODULE_INFO("HtmlViewer", PSP_MODULE_USER, 1, 1); +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER); + +void throwError(int milisecs, char *fmt, ...) +{ + va_list list; + char msg[256]; + + va_start(list, fmt); + vsprintf(msg, fmt, list); + va_end(list); + + pspDebugScreenInit(); + pspDebugScreenClear(); + pspDebugScreenPrintf(msg); + + sceKernelDelayThread(milisecs * 1000); + sceKernelExitGame(); +} + +#define BUF_WIDTH (512) +#define SCR_WIDTH (480) +#define SCR_HEIGHT (272) + +static char list[0x10000] __attribute__((aligned(64))); + +void setupGu(void) +{ + sceGuInit(); + + sceGuStart(GU_DIRECT, list); + sceGuDrawBuffer(GU_PSM_8888, 0, BUF_WIDTH); + sceGuDispBuffer(SCR_WIDTH, SCR_HEIGHT, (void*)0x88000, BUF_WIDTH); + sceGuDepthBuffer((void*)0x110000, BUF_WIDTH); + + sceGuOffset(0, 0); + + sceGuScissor(0, 0, SCR_WIDTH, SCR_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + + sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0); + sceGuEnable(GU_BLEND); + + //sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA); + //sceGuTexFilter(GU_LINEAR_MIPMAP_LINEAR, GU_NEAREST); + //sceGuTexWrap(GU_REPEAT, GU_REPEAT); + + sceGuClearColor(0); + sceGuClearDepth(0); + sceGuClearStencil(0); + + sceGuFinish(); + sceGuSync(0, 0); + + sceDisplayWaitVblankStart(); + sceGuDisplay(GU_TRUE); +} + +void draw() +{ + sceGuStart(GU_DIRECT, list); + sceGuClear(GU_COLOR_BUFFER_BIT|GU_STENCIL_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); + sceGuFinish(); + sceGuSync(0, 0); +} + +void loadNetModules() +{ + sceUtilityLoadNetModule(PSP_NET_MODULE_COMMON); + sceUtilityLoadNetModule(PSP_NET_MODULE_INET); + sceUtilityLoadNetModule(PSP_NET_MODULE_PARSEURI); + sceUtilityLoadNetModule(PSP_NET_MODULE_PARSEHTTP); + sceUtilityLoadNetModule(PSP_NET_MODULE_HTTP); + sceUtilityLoadNetModule(PSP_NET_MODULE_SSL); +} + +void unloadNetModules() +{ + sceUtilityUnloadNetModule(PSP_NET_MODULE_SSL); + sceUtilityUnloadNetModule(PSP_NET_MODULE_HTTP); + sceUtilityUnloadNetModule(PSP_NET_MODULE_PARSEHTTP); + sceUtilityUnloadNetModule(PSP_NET_MODULE_PARSEURI); + sceUtilityUnloadNetModule(PSP_NET_MODULE_INET); + sceUtilityUnloadNetModule(PSP_NET_MODULE_COMMON); +} + +void netTerm() +{ + sceHttpSaveSystemCookie(); + sceHttpsEnd(); + sceHttpEnd(); + sceSslEnd(); + sceNetApctlTerm(); + sceNetInetTerm(); + sceNetTerm(); + + unloadNetModules(); +} + +void netInit() +{ + int res; + + loadNetModules(); + + res = sceNetInit(0x20000, 0x2A, 0, 0x2A, 0); + + if (res < 0) + { + throwError(6000, "Error 0x%08X in sceNetInit\n", res); + } + + res = sceNetInetInit(); + + if (res < 0) + { + netTerm(); + throwError(6000, "Error 0x%08X in sceNetInetInit\n", res); + } + + res = sceNetResolverInit(); + + if (res < 0) + { + netTerm(); + throwError(6000, "Error 0x%08X in sceNetResolverInit\n", res); + } + + res = sceNetApctlInit(0x1800, 0x30); + + if (res < 0) + { + netTerm(); + throwError(6000, "Error 0x%08X in sceNetApctlInit\n", res); + } + + res = sceSslInit(0x28000); + + if (res < 0) + { + netTerm(); + throwError(6000, "Error 0x%08X in sceSslInit\n", res); + } + + res = sceHttpInit(0x25800); + + if (res < 0) + { + netTerm(); + throwError(6000, "Error 0x%08X in sceHttpInit\n", res); + } + + res = sceHttpsInit(0, 0, 0, 0); + if (res < 0) + { + netTerm(); + throwError(6000, "Error 0x%08X in sceHttpsInit\n", res); + } + + res = sceHttpsLoadDefaultCert(0, 0); + + if (res < 0) + { + netTerm(); + throwError(6000, "Error 0x%08X in sceHttpsLoadDefaultCert\n", res); + } + + res = sceHttpLoadSystemCookie(); + + if (res < 0) + { + netTerm(); + throwError(6000, "Error 0x%08X in sceHttpsLoadDefaultCert\n", res); + } +} + +#define BROWSER_MEMORY (10*1024*1024) + +SceUID vpl; +pspUtilityHtmlViewerParam params; + +void htmlViewerInit(char *url) +{ + int res; + + vpl = sceKernelCreateVpl("BrowserVpl", PSP_MEMORY_PARTITION_USER, 0, BROWSER_MEMORY + 256, NULL); + + if (vpl < 0) + throwError(6000, "Error 0x%08X creating vpl.\n", vpl); + + memset(¶ms, 0, sizeof(pspUtilityHtmlViewerParam)); + + params.base.size = sizeof(pspUtilityHtmlViewerParam); + + sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_LANGUAGE, ¶ms.base.language); + sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_UNKNOWN, ¶ms.base.buttonSwap); + + params.base.graphicsThread = 17; + params.base.accessThread = 19; + params.base.fontThread = 18; + params.base.soundThread = 16; + params.memsize = BROWSER_MEMORY; + params.initialurl = url; + params.numtabs = 1; + params.cookiemode = PSP_UTILITY_HTMLVIEWER_COOKIEMODE_DEFAULT; + params.homeurl = url; + params.textsize = PSP_UTILITY_HTMLVIEWER_TEXTSIZE_NORMAL; + params.displaymode = PSP_UTILITY_HTMLVIEWER_DISPLAYMODE_SMART_FIT; + params.options = PSP_UTILITY_HTMLVIEWER_DISABLE_STARTUP_LIMITS|PSP_UTILITY_HTMLVIEWER_ENABLE_FLASH; + params.interfacemode = PSP_UTILITY_HTMLVIEWER_INTERFACEMODE_FULL; + params.connectmode = PSP_UTILITY_HTMLVIEWER_CONNECTMODE_MANUAL_ALL; + + // Note the lack of 'ms0:' on the paths + params.dldirname = "/PSP/PHOTO"; + + res = sceKernelAllocateVpl(vpl, params.memsize, ¶ms.memaddr, NULL); + + if (res < 0) + throwError(6000, "Error 0x%08X allocating browser memory.\n", res); + + res = sceUtilityHtmlViewerInitStart(¶ms); + + if (res < 0) + throwError(6000, "Error 0x%08X initing browser.\n", res); +} + +int updateHtmlViewer() +{ + draw(); + + switch (sceUtilityHtmlViewerGetStatus()) + { + case PSP_UTILITY_DIALOG_VISIBLE: + sceUtilityHtmlViewerUpdate(1); + break; + + case PSP_UTILITY_DIALOG_QUIT: + sceUtilityHtmlViewerShutdownStart(); + break; + + case PSP_UTILITY_DIALOG_NONE: + return 0; + break; + + default: + break; + } + + return 1; +} + +int main(int argc, char *argv[]) +{ + char url[] = "http://www.ps2dev.org/"; + + setupGu(); + netInit(); + htmlViewerInit(url); + + while(updateHtmlViewer()) + { + sceDisplayWaitVblankStart(); + sceGuSwapBuffers(); + } + + netTerm(); + sceKernelFreeVpl(vpl, params.memaddr); + sceKernelDeleteVpl(vpl); + sceKernelExitGame(); + + return 0; +} diff --git a/src/samples/utility/msgdialog/Makefile.sample b/src/samples/utility/msgdialog/Makefile.sample new file mode 100644 index 00000000..6fa68b17 --- /dev/null +++ b/src/samples/utility/msgdialog/Makefile.sample @@ -0,0 +1,14 @@ +PSPSDK = $(shell psp-config --pspsdk-path) +PSPLIBSDIR = $(PSPSDK)/.. +TARGET = msgdialogsample +OBJS = main.o +LIBS = -lpsputility -lpspgum -lpspgu -lm + +# Uncomment the following line to comple for custom firmware 3.xx +#BUILD_PRX = 1 + +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/utility/msgdialog/main.c b/src/samples/utility/msgdialog/main.c new file mode 100644 index 00000000..a7977a77 --- /dev/null +++ b/src/samples/utility/msgdialog/main.c @@ -0,0 +1,312 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Sample to demonstrate how to use the message dialog utility + * + * Copyright (c) 2005 Marcus Comstedt + * (c) 2008 InsertWittyName + * + * $Id: main.c 2364 2008-02-16 22:07:09Z iwn $ + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Define the module info section */ +PSP_MODULE_INFO("MsgDialog Sample", 0, 1, 0); + + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + sceKernelExitGame(); + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0); + if (thid >= 0) + sceKernelStartThread(thid, 0, 0); + return thid; +} + + +/* Graphics stuff, based on cube sample */ + +static unsigned int __attribute__((aligned(16))) list[262144]; + +struct Vertex +{ + float u, v; + unsigned int color; + float x,y,z; +}; + +struct Vertex __attribute__((aligned(16))) vertices[12*3] = +{ + {0, 0, 0xff7f0000,-1,-1, 1}, // 0 + {1, 0, 0xff7f0000,-1, 1, 1}, // 4 + {1, 1, 0xff7f0000, 1, 1, 1}, // 5 + + {0, 0, 0xff7f0000,-1,-1, 1}, // 0 + {1, 1, 0xff7f0000, 1, 1, 1}, // 5 + {0, 1, 0xff7f0000, 1,-1, 1}, // 1 + + {0, 0, 0xff7f0000,-1,-1,-1}, // 3 + {1, 0, 0xff7f0000, 1,-1,-1}, // 2 + {1, 1, 0xff7f0000, 1, 1,-1}, // 6 + + {0, 0, 0xff7f0000,-1,-1,-1}, // 3 + {1, 1, 0xff7f0000, 1, 1,-1}, // 6 + {0, 1, 0xff7f0000,-1, 1,-1}, // 7 + + {0, 0, 0xff007f00, 1,-1,-1}, // 0 + {1, 0, 0xff007f00, 1,-1, 1}, // 3 + {1, 1, 0xff007f00, 1, 1, 1}, // 7 + + {0, 0, 0xff007f00, 1,-1,-1}, // 0 + {1, 1, 0xff007f00, 1, 1, 1}, // 7 + {0, 1, 0xff007f00, 1, 1,-1}, // 4 + + {0, 0, 0xff007f00,-1,-1,-1}, // 0 + {1, 0, 0xff007f00,-1, 1,-1}, // 3 + {1, 1, 0xff007f00,-1, 1, 1}, // 7 + + {0, 0, 0xff007f00,-1,-1,-1}, // 0 + {1, 1, 0xff007f00,-1, 1, 1}, // 7 + {0, 1, 0xff007f00,-1,-1, 1}, // 4 + + {0, 0, 0xff00007f,-1, 1,-1}, // 0 + {1, 0, 0xff00007f, 1, 1,-1}, // 1 + {1, 1, 0xff00007f, 1, 1, 1}, // 2 + + {0, 0, 0xff00007f,-1, 1,-1}, // 0 + {1, 1, 0xff00007f, 1, 1, 1}, // 2 + {0, 1, 0xff00007f,-1, 1, 1}, // 3 + + {0, 0, 0xff00007f,-1,-1,-1}, // 4 + {1, 0, 0xff00007f,-1,-1, 1}, // 7 + {1, 1, 0xff00007f, 1,-1, 1}, // 6 + + {0, 0, 0xff00007f,-1,-1,-1}, // 4 + {1, 1, 0xff00007f, 1,-1, 1}, // 6 + {0, 1, 0xff00007f, 1,-1,-1}, // 5 +}; + +#define BUF_WIDTH (512) +#define SCR_WIDTH (480) +#define SCR_HEIGHT (272) +#define PIXEL_SIZE (4) /* change this if you change to another screenmode */ +#define FRAME_SIZE (BUF_WIDTH * SCR_HEIGHT * PIXEL_SIZE) +#define ZBUF_SIZE (BUF_WIDTH SCR_HEIGHT * 2) /* zbuffer seems to be 16-bit? */ + +static void SetupGu() +{ + sceGuInit(); + + sceGuStart(GU_DIRECT,list); + sceGuDrawBuffer(GU_PSM_8888,(void*)0,BUF_WIDTH); + sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,(void*)0x88000,BUF_WIDTH); + sceGuDepthBuffer((void*)0x110000,BUF_WIDTH); + sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); + sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); + sceGuDepthRange(0xc350,0x2710); + sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + sceGuDepthFunc(GU_GEQUAL); + sceGuEnable(GU_DEPTH_TEST); + sceGuFrontFace(GU_CW); + sceGuShadeModel(GU_SMOOTH); + sceGuEnable(GU_CULL_FACE); + sceGuEnable(GU_CLIP_PLANES); + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuDisplay(GU_TRUE); +} + +static void DrawStuff(void) +{ + static int val = 0; + + sceGuStart(GU_DIRECT,list); + + // clear screen + + sceGuClearColor(0xff554433); + sceGuClearDepth(0); + sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); + + // setup matrices for cube + + sceGumMatrixMode(GU_PROJECTION); + sceGumLoadIdentity(); + sceGumPerspective(75.0f,16.0f/9.0f,0.5f,1000.0f); + + sceGumMatrixMode(GU_VIEW); + sceGumLoadIdentity(); + + sceGumMatrixMode(GU_MODEL); + sceGumLoadIdentity(); + { + ScePspFVector3 pos = { 0, 0, -2.5f }; + ScePspFVector3 rot = { val * 0.79f * (M_PI/180.0f), val * 0.98f * (M_PI/180.0f), val * 1.32f * (M_PI/180.0f) }; + sceGumRotateXYZ(&rot); + sceGumTranslate(&pos); + } + + // draw cube + + sceGuAmbientColor(0xffffffff); + sceGumDrawArray(GU_TRIANGLES,GU_TEXTURE_32BITF|GU_COLOR_8888|GU_VERTEX_32BITF|GU_TRANSFORM_3D,12*3,0,vertices); + + sceGuFinish(); + sceGuSync(0,0); + + val ++; +} + + +/* Utility dialog functions */ + +pspUtilityMsgDialogParams dialog; + +static void ConfigureDialog(pspUtilityMsgDialogParams *dialog, size_t dialog_size) +{ + memset(dialog, 0, dialog_size); + + dialog->base.size = dialog_size; + sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_LANGUAGE, + &dialog->base.language); // Prompt language + sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_UNKNOWN, + &dialog->base.buttonSwap); // X/O button swap + + dialog->base.graphicsThread = 0x11; + dialog->base.accessThread = 0x13; + dialog->base.fontThread = 0x12; + dialog->base.soundThread = 0x10; +} + +static void ShowErrorDialog(const unsigned int error) +{ + ConfigureDialog(&dialog, sizeof(dialog)); + dialog.mode = PSP_UTILITY_MSGDIALOG_MODE_ERROR; + dialog.options = PSP_UTILITY_MSGDIALOG_OPTION_ERROR; + dialog.errorValue = error; + + sceUtilityMsgDialogInitStart(&dialog); + + for(;;) { + + DrawStuff(); + + switch(sceUtilityMsgDialogGetStatus()) { + + case PSP_UTILITY_DIALOG_VISIBLE: + sceUtilityMsgDialogUpdate(1); + break; + + case PSP_UTILITY_DIALOG_QUIT: + sceUtilityMsgDialogShutdownStart(); + break; + + case PSP_UTILITY_DIALOG_NONE: + return; + + } + + sceDisplayWaitVblankStart(); + sceGuSwapBuffers(); + } +} + +static void ShowMessageDialog(const char *message, int enableYesno) +{ + ConfigureDialog(&dialog, sizeof(dialog)); + dialog.mode = PSP_UTILITY_MSGDIALOG_MODE_TEXT; + dialog.options = PSP_UTILITY_MSGDIALOG_OPTION_TEXT; + + if(enableYesno) + dialog.options |= PSP_UTILITY_MSGDIALOG_OPTION_YESNO_BUTTONS|PSP_UTILITY_MSGDIALOG_OPTION_DEFAULT_NO; + + strcpy(dialog.message, message); + + sceUtilityMsgDialogInitStart(&dialog); + + for(;;) { + + DrawStuff(); + + switch(sceUtilityMsgDialogGetStatus()) { + + case 2: + sceUtilityMsgDialogUpdate(1); + break; + + case 3: + sceUtilityMsgDialogShutdownStart(); + break; + + case 0: + return; + + } + + sceDisplayWaitVblankStart(); + sceGuSwapBuffers(); + } +} + +/* main routine */ +int main(int argc, char *argv[]) +{ + SetupCallbacks(); + SetupGu(); + + char string[256]; + char button[12]; + + ShowMessageDialog("This is a utility message dialog.\n" + "After you acknowledge it, this program will\n" + "show an error message dialog.", 1); + + if(dialog.buttonPressed == PSP_UTILITY_MSGDIALOG_RESULT_YES) + sprintf(button, "Yes"); + else if(dialog.buttonPressed == PSP_UTILITY_MSGDIALOG_RESULT_NO) + sprintf(button, "No"); + else + sprintf(button, "Back"); + + ShowErrorDialog(0x80020001); + + sprintf(string, "This is a utility message dialog.\nAfter you acknowledge it, this program will\nautomatically exit to the shell.\n\nBy the way, you selected '%s' on the first dialog.", button); + + ShowMessageDialog(string, 0); + + sceKernelExitGame(); + return 0; +} diff --git a/src/samples/utility/netconf/Makefile.sample b/src/samples/utility/netconf/Makefile.sample new file mode 100644 index 00000000..b6c25a2e --- /dev/null +++ b/src/samples/utility/netconf/Makefile.sample @@ -0,0 +1,12 @@ +PSPSDK = $(shell psp-config --pspsdk-path) +PSPLIBSDIR = $(PSPSDK)/.. +TARGET = netconfsample +OBJS = main.o +LIBS = -lpsputility + + +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/utility/netconf/main.c b/src/samples/utility/netconf/main.c new file mode 100644 index 00000000..c578efd4 --- /dev/null +++ b/src/samples/utility/netconf/main.c @@ -0,0 +1,117 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Sample to demonstrate proper use of the systemparam functions + * + * Copyright (c) 2005 John Kelley + * + * $Id: main.c 1869 2006-04-09 14:21:59Z tyranid $ + */ +#include +#include +#include +#include +#include +#include +#include +#include + +/* Define the module info section */ +PSP_MODULE_INFO("NetParam Sample", 0, 1, 00); + +//Just to leave room for expansion +#define NUM_NETPARAMS 17 + +/* Define printf, just to make typing easier */ +#define printf pspDebugScreenPrintf + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + sceKernelExitGame(); + + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0); + if (thid >= 0) + sceKernelStartThread(thid, 0, 0); + return thid; +} + +/* main routine */ +int main(int argc, char *argv[]) +{ + int i; + int netConfIndex = 1; + int numNetConfigs = 1; + netData data; + SceCtrlData pad; + u32 oldButtons; + + //init screen and callbacks + pspDebugScreenInit(); + pspDebugScreenClear(); + + SetupCallbacks(); + + // Setup Pad + sceCtrlSetSamplingCycle(0); + sceCtrlSetSamplingMode(0); + sceCtrlReadBufferPositive(&pad, 1); + oldButtons = pad.Buttons; + + // Determine # of net configs + while (sceUtilityCheckNetParam(numNetConfigs) == 0) { + numNetConfigs++; + } + numNetConfigs--; + + for (;;) { + pspDebugScreenSetXY(0, 0); + printf("NetParam Sample v1.0 by John_K\n\n"); + + printf("Net Configuration #%d:\n", netConfIndex); + for (i = 0; i <= NUM_NETPARAMS; i++) { + //clear netData + data.asUint = 0xBADF00D; + memset(&data.asString[4], 0, 124); + printf("param %03d: ret(0x%08X) uint(%d) string(%s)\n", i, sceUtilityGetNetParam(netConfIndex, i, &data), data.asUint, data.asString); + } + printf("\nPress X to show details for next net configuration.\n"); + sceDisplayWaitVblankStart(); + while (oldButtons == pad.Buttons) { + sceCtrlReadBufferPositive(&pad, 1); + if(pad.Buttons & PSP_CTRL_SELECT) + sceKernelExitGame(); + } + if (pad.Buttons & PSP_CTRL_CROSS) { + netConfIndex++; + if(netConfIndex > numNetConfigs) + netConfIndex = 1; + } + oldButtons = pad.Buttons; + } + + sceKernelSleepThread(); + sceKernelExitGame(); + + return 0; +} diff --git a/src/samples/utility/netdialog/Makefile.sample b/src/samples/utility/netdialog/Makefile.sample new file mode 100644 index 00000000..7ec76b2f --- /dev/null +++ b/src/samples/utility/netdialog/Makefile.sample @@ -0,0 +1,22 @@ +TARGET = netdialog +OBJS = main.o + +# For OE firmware: +PSP_FW_VERSION = 200 +BUILD_PRX = 1 + + +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + + +LIBDIR = +LDFLAGS = +LIBS = -lpsputility -lpspgum -lpspgu -lm + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Net Dialog Sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/utility/netdialog/main.c b/src/samples/utility/netdialog/main.c new file mode 100644 index 00000000..f7d9d80a --- /dev/null +++ b/src/samples/utility/netdialog/main.c @@ -0,0 +1,313 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Net dialog sample for connecting to an access point + * + * For OE firmwares, this sample must be run under the 3.xx kernel. + * + * Copyright (c) 2007 David Perry (Insert_Witty_Name) + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if _PSP_FW_VERSION >= 200 +PSP_MODULE_INFO("Net Dialog Sample", 0, 1, 1); +#else +PSP_MODULE_INFO("Net Dialog Sample", 0x1000, 1, 1); +PSP_MAIN_THREAD_ATTR(0); +#endif + +static int running = 1; + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + running = 0; + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, PSP_THREAD_ATTR_USER, 0); + + if (thid >= 0) + sceKernelStartThread(thid, 0, 0); + + return thid; +} + +/* Graphics stuff, based on cube sample */ +static unsigned int __attribute__((aligned(16))) list[262144]; + +struct Vertex +{ + unsigned int color; + float x,y,z; +}; + +struct Vertex __attribute__((aligned(16))) vertices[12*3] = +{ + {0xff7f0000,-1,-1, 1}, // 0 + {0xff7f0000,-1, 1, 1}, // 4 + {0xff7f0000, 1, 1, 1}, // 5 + + {0xff7f0000,-1,-1, 1}, // 0 + {0xff7f0000, 1, 1, 1}, // 5 + {0xff7f0000, 1,-1, 1}, // 1 + + {0xff7f0000,-1,-1,-1}, // 3 + {0xff7f0000, 1,-1,-1}, // 2 + {0xff7f0000, 1, 1,-1}, // 6 + + {0xff7f0000,-1,-1,-1}, // 3 + {0xff7f0000, 1, 1,-1}, // 6 + {0xff7f0000,-1, 1,-1}, // 7 + + {0xff007f00, 1,-1,-1}, // 0 + {0xff007f00, 1,-1, 1}, // 3 + {0xff007f00, 1, 1, 1}, // 7 + + {0xff007f00, 1,-1,-1}, // 0 + {0xff007f00, 1, 1, 1}, // 7 + {0xff007f00, 1, 1,-1}, // 4 + + {0xff007f00,-1,-1,-1}, // 0 + {0xff007f00,-1, 1,-1}, // 3 + {0xff007f00,-1, 1, 1}, // 7 + + {0xff007f00,-1,-1,-1}, // 0 + {0xff007f00,-1, 1, 1}, // 7 + {0xff007f00,-1,-1, 1}, // 4 + + {0xff00007f,-1, 1,-1}, // 0 + {0xff00007f, 1, 1,-1}, // 1 + {0xff00007f, 1, 1, 1}, // 2 + + {0xff00007f,-1, 1,-1}, // 0 + {0xff00007f, 1, 1, 1}, // 2 + {0xff00007f,-1, 1, 1}, // 3 + + {0xff00007f,-1,-1,-1}, // 4 + {0xff00007f,-1,-1, 1}, // 7 + {0xff00007f, 1,-1, 1}, // 6 + + {0xff00007f,-1,-1,-1}, // 4 + {0xff00007f, 1,-1, 1}, // 6 + {0xff00007f, 1,-1,-1}, // 5 +}; + +#define BUF_WIDTH (512) +#define SCR_WIDTH (480) +#define SCR_HEIGHT (272) +#define PIXEL_SIZE (4) +#define FRAME_SIZE (BUF_WIDTH * SCR_HEIGHT * PIXEL_SIZE) +#define ZBUF_SIZE (BUF_WIDTH SCR_HEIGHT * 2) + +static void setupGu() +{ + sceGuInit(); + + sceGuStart(GU_DIRECT,list); + sceGuDrawBuffer(GU_PSM_8888,(void*)0,BUF_WIDTH); + sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,(void*)0x88000,BUF_WIDTH); + sceGuDepthBuffer((void*)0x110000,BUF_WIDTH); + sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); + sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); + sceGuDepthRange(0xc350,0x2710); + sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + sceGuDepthFunc(GU_GEQUAL); + sceGuEnable(GU_DEPTH_TEST); + sceGuFrontFace(GU_CW); + sceGuShadeModel(GU_SMOOTH); + sceGuEnable(GU_CULL_FACE); + sceGuEnable(GU_CLIP_PLANES); + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuDisplay(GU_TRUE); +} + +static void drawStuff(void) +{ + static int val = 0; + + sceGuStart(GU_DIRECT, list); + + sceGuClearColor(0xff554433); + sceGuClearDepth(0); + sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); + + sceGumMatrixMode(GU_PROJECTION); + sceGumLoadIdentity(); + sceGumPerspective(75.0f,16.0f/9.0f,0.5f,1000.0f); + + sceGumMatrixMode(GU_VIEW); + sceGumLoadIdentity(); + + sceGumMatrixMode(GU_MODEL); + sceGumLoadIdentity(); + + ScePspFVector3 pos = { 0, 0, -5.0f }; + ScePspFVector3 rot = { val * 0.79f * (M_PI/180.0f), val * 0.98f * (M_PI/180.0f), val * 1.32f * (M_PI/180.0f) }; + sceGumTranslate(&pos); + sceGumRotateXYZ(&rot); + + sceGumDrawArray(GU_TRIANGLES, GU_COLOR_8888|GU_VERTEX_32BITF|GU_TRANSFORM_3D, 12*3, 0, vertices); + + sceGuFinish(); + sceGuSync(0,0); + + val++; +} + +int netDialog() +{ + int done = 0; + + pspUtilityNetconfData data; + + memset(&data, 0, sizeof(data)); + data.base.size = sizeof(data); + data.base.language = PSP_SYSTEMPARAM_LANGUAGE_ENGLISH; + data.base.buttonSwap = PSP_UTILITY_ACCEPT_CROSS; + data.base.graphicsThread = 17; + data.base.accessThread = 19; + data.base.fontThread = 18; + data.base.soundThread = 16; + data.action = PSP_NETCONF_ACTION_CONNECTAP; + + struct pspUtilityNetconfAdhoc adhocparam; + memset(&adhocparam, 0, sizeof(adhocparam)); + data.adhocparam = &adhocparam; + + sceUtilityNetconfInitStart(&data); + + while(running) + { + drawStuff(); + + switch(sceUtilityNetconfGetStatus()) + { + case PSP_UTILITY_DIALOG_NONE: + break; + + case PSP_UTILITY_DIALOG_VISIBLE: + sceUtilityNetconfUpdate(1); + break; + + case PSP_UTILITY_DIALOG_QUIT: + sceUtilityNetconfShutdownStart(); + break; + + case PSP_UTILITY_DIALOG_FINISHED: + done = 1; + break; + + default: + break; + } + + sceDisplayWaitVblankStart(); + sceGuSwapBuffers(); + + if(done) + break; + } + + return 1; +} + +void netInit(void) +{ + sceNetInit(128*1024, 42, 4*1024, 42, 4*1024); + + sceNetInetInit(); + + sceNetApctlInit(0x8000, 48); +} + +void netTerm(void) +{ + sceNetApctlTerm(); + + sceNetInetTerm(); + + sceNetTerm(); +} + +int user_thread(SceSize args, void *argp) +{ + netInit(); + + SetupCallbacks(); + + setupGu(); + + netDialog(); + + netTerm(); + + return 0; +} + +/* main routine */ +int main(int argc, char *argv[]) +{ + #if _PSP_FW_VERSION >= 200 + sceUtilityLoadNetModule(PSP_NET_MODULE_COMMON); + + sceUtilityLoadNetModule(PSP_NET_MODULE_INET); + + netInit(); + + SetupCallbacks(); + + setupGu(); + + netDialog(); + + netTerm(); + + #else + + pspSdkLoadInetModules(); + + SceUID thid = sceKernelCreateThread("user_thread", user_thread, 0x18, 0x10000, PSP_THREAD_ATTR_USER, NULL); + + sceKernelStartThread(thid, 0, NULL); + + sceKernelWaitThreadEnd(thid, 0); + #endif + + sceKernelExitGame(); + + return 0; +} diff --git a/src/samples/utility/osk/Makefile.sample b/src/samples/utility/osk/Makefile.sample new file mode 100755 index 00000000..26a37d3d --- /dev/null +++ b/src/samples/utility/osk/Makefile.sample @@ -0,0 +1,19 @@ +TARGET = osk +OBJS = main.o + +INCDIR = +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +BUILD_PRX = 1 + +LIBDIR = +LDFLAGS = +LIBS = -lpspgu -lpsputility + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = PSP OSK Sample + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/utility/osk/main.c b/src/samples/utility/osk/main.c new file mode 100755 index 00000000..c7b961a6 --- /dev/null +++ b/src/samples/utility/osk/main.c @@ -0,0 +1,223 @@ +#include +#include +#include +#include +#include +#include + +PSP_MODULE_INFO("OSK Sample", 0, 1, 1); +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER); + +static int done = 0; + +int exit_callback(int arg1, int arg2, void *common) +{ + done = 1; + + return 0; +} + +int CallbackThread(SceSize args, void *argp) +{ + int cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + sceKernelSleepThreadCB(); + + return 0; +} + +int SetupCallbacks(void) +{ + int thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, PSP_THREAD_ATTR_USER, 0); + + if(thid >= 0) + sceKernelStartThread(thid, 0, 0); + + return thid; +} + +static unsigned int __attribute__((aligned(16))) list[262144]; + +#define BUF_WIDTH (512) +#define SCR_WIDTH (480) +#define SCR_HEIGHT (272) +#define PIXEL_SIZE (4) +#define FRAME_SIZE (BUF_WIDTH * SCR_HEIGHT * PIXEL_SIZE) +#define ZBUF_SIZE (BUF_WIDTH SCR_HEIGHT * 2) + +#define NUM_INPUT_FIELDS (3) +#define TEXT_LENGTH (128) + +int main(int argc, char* argv[]) +{ + SetupCallbacks(); + + sceGuInit(); + sceGuStart(GU_DIRECT,list); + sceGuDrawBuffer(GU_PSM_8888,(void*)0,BUF_WIDTH); + sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,(void*)0x88000,BUF_WIDTH); + sceGuDepthBuffer((void*)0x110000,BUF_WIDTH); + sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); + sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); + sceGuDepthRange(0xc350,0x2710); + sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + sceGuDepthFunc(GU_GEQUAL); + sceGuEnable(GU_DEPTH_TEST); + sceGuFrontFace(GU_CW); + sceGuShadeModel(GU_FLAT); + sceGuEnable(GU_CULL_FACE); + sceGuEnable(GU_TEXTURE_2D); + sceGuEnable(GU_CLIP_PLANES); + sceGuFinish(); + sceGuSync(0,0); + sceDisplayWaitVblankStart(); + sceGuDisplay(GU_TRUE); + + unsigned short intext[NUM_INPUT_FIELDS][TEXT_LENGTH]; + unsigned short outtext[NUM_INPUT_FIELDS][TEXT_LENGTH]; + unsigned short desc[NUM_INPUT_FIELDS][TEXT_LENGTH]; + + memset(&intext, 0, NUM_INPUT_FIELDS * TEXT_LENGTH * sizeof(unsigned short)); + memset(&outtext, 0, NUM_INPUT_FIELDS * TEXT_LENGTH * sizeof(unsigned short)); + memset(&desc, 0, NUM_INPUT_FIELDS * TEXT_LENGTH * sizeof(unsigned short)); + + int i; + + for(i = 0;i < NUM_INPUT_FIELDS;i++) + { + desc[i][0] = 'F'; + desc[i][1] = 'i'; + desc[i][2] = 'e'; + desc[i][3] = 'l'; + desc[i][4] = 'd'; + desc[i][5] = ' '; + desc[i][6] = i + 48 + 1; // Convert i to ASCII value. + desc[i][7] = 0; + + intext[i][0] = 'T'; + intext[i][1] = 'e'; + intext[i][2] = 'x'; + intext[i][3] = 't'; + intext[i][4] = ' '; + intext[i][5] = i + 48 + 1; // Convert i to ASCII value. + intext[i][6] = 0; + + } + + SceUtilityOskData data[NUM_INPUT_FIELDS]; + + for(i = 0; i < NUM_INPUT_FIELDS;i++) + { + memset(&data[i], 0, sizeof(SceUtilityOskData)); + data[i].language = PSP_UTILITY_OSK_LANGUAGE_DEFAULT; // Use system default for text input + data[i].lines = 1; + data[i].unk_24 = 1; + data[i].inputtype = PSP_UTILITY_OSK_INPUTTYPE_ALL; // Allow all input types + data[i].desc = desc[i]; + data[i].intext = intext[i]; + data[i].outtextlength = TEXT_LENGTH; + data[i].outtextlimit = 32; // Limit input to 32 characters + data[i].outtext = outtext[i]; + } + + SceUtilityOskParams params; + memset(¶ms, 0, sizeof(params)); + params.base.size = sizeof(params); + sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_LANGUAGE, ¶ms.base.language); + sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_UNKNOWN, ¶ms.base.buttonSwap); + params.base.graphicsThread = 17; + params.base.accessThread = 19; + params.base.fontThread = 18; + params.base.soundThread = 16; + params.datacount = NUM_INPUT_FIELDS; + params.data = data; + + sceUtilityOskInitStart(¶ms); + + while(!done) + { + sceGuStart(GU_DIRECT,list); + sceGuClearColor(0); + sceGuClearDepth(0); + sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); + + sceGuFinish(); + sceGuSync(0,0); + + switch(sceUtilityOskGetStatus()) + { + case PSP_UTILITY_DIALOG_INIT: + break; + + case PSP_UTILITY_DIALOG_VISIBLE: + sceUtilityOskUpdate(1); + break; + + case PSP_UTILITY_DIALOG_QUIT: + sceUtilityOskShutdownStart(); + break; + + case PSP_UTILITY_DIALOG_FINISHED: + break; + + case PSP_UTILITY_DIALOG_NONE: + done = 1; + + default : + break; + } + + sceDisplayWaitVblankStart(); + sceGuSwapBuffers(); + } + + pspDebugScreenInit(); + pspDebugScreenSetXY(0, 0); + + int j; + + for(i = 0; i < NUM_INPUT_FIELDS;i++) + { + pspDebugScreenPrintf("Field %d: ", i+1); + + switch(data[i].result) + { + case PSP_UTILITY_OSK_RESULT_UNCHANGED: + pspDebugScreenPrintf("UNCHANGED: "); + break; + + case PSP_UTILITY_OSK_RESULT_CANCELLED: + pspDebugScreenPrintf("CANCELLED: "); + break; + + case PSP_UTILITY_OSK_RESULT_CHANGED: + pspDebugScreenPrintf("CHANGED: "); + break; + + default: + break; + } + + for(j = 0; data[i].outtext[j]; j++) + { + unsigned c = data[i].outtext[j]; + + if(32 <= c && c <= 127) // print ascii only + pspDebugScreenPrintf("%c", data[i].outtext[j]); + } + + pspDebugScreenPrintf("\n"); + } + + done = 0; + + while(!done) + sceKernelDelayThread(1000); + + sceGuTerm(); + + sceKernelExitGame(); + + return 0; +} diff --git a/src/samples/utility/systemparam/Makefile.sample b/src/samples/utility/systemparam/Makefile.sample new file mode 100644 index 00000000..fb34d5f5 --- /dev/null +++ b/src/samples/utility/systemparam/Makefile.sample @@ -0,0 +1,12 @@ +PSPSDK = $(shell psp-config --pspsdk-path) +PSPLIBSDIR = $(PSPSDK)/.. +TARGET = sysparamsample +OBJS = main.o +LIBS = -lpsputility + + +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/utility/systemparam/main.c b/src/samples/utility/systemparam/main.c new file mode 100644 index 00000000..68d824ea --- /dev/null +++ b/src/samples/utility/systemparam/main.c @@ -0,0 +1,182 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Sample to demonstrate proper use of the systemparam functions + * + * Copyright (c) 2005 John Kelley + * + * $Id: main.c 1869 2006-04-09 14:21:59Z tyranid $ + */ +#include +#include +#include +#include +#include +#include +#include + +/* Define the module info section */ +PSP_MODULE_INFO("SystemParam Sample", 0, 1, 0); + +//Just to leave room for expansion +#define NUM_SYSTEMPARAMS 15 + +/* Define printf, just to make typing easier */ +#define printf pspDebugScreenPrintf + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + sceKernelExitGame(); + + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, THREAD_ATTR_USER, 0); + if (thid >= 0) + sceKernelStartThread(thid, 0, 0); + return thid; +} + +void printSystemParam(int id, int iVal, char *sVal) { + switch(id) { + case(PSP_SYSTEMPARAM_ID_STRING_NICKNAME): + printf("%-17s: %s\n", "Nickname", sVal); + break; + case(PSP_SYSTEMPARAM_ID_INT_ADHOC_CHANNEL): + printf("%-17s: %d\n", "AdHoc Channel", iVal); + break; + case(PSP_SYSTEMPARAM_ID_INT_WLAN_POWERSAVE): + printf("%-17s: %s\n", "WLAN Powersave", iVal == 0 ? "enabled " : "disabled"); + break; + case(PSP_SYSTEMPARAM_ID_INT_DATE_FORMAT): + switch(iVal) { + case(PSP_SYSTEMPARAM_DATE_FORMAT_YYYYMMDD): + printf("%-17s: YYYYMMDD\n", "Date Format"); + break; + case(PSP_SYSTEMPARAM_DATE_FORMAT_MMDDYYYY): + printf("%-17s: MMDDYYYY\n", "Date Format"); + break; + case(PSP_SYSTEMPARAM_DATE_FORMAT_DDMMYYYY): + printf("%-17s: DDMMYYYY\n", "Date Format"); + break; + default: + printf("%-17s: INVALID\n", "Date Format"); + } + break; + case(PSP_SYSTEMPARAM_ID_INT_TIME_FORMAT): + switch(iVal) { + case(PSP_SYSTEMPARAM_TIME_FORMAT_24HR): + printf("%-17s: 24HR\n", "Time Format"); + break; + case(PSP_SYSTEMPARAM_TIME_FORMAT_12HR): + printf("%-17s: 12HR\n", "Time Format"); + break; + default: + printf("%-17s: INVALID\n", "Time Format"); + } + break; + case(PSP_SYSTEMPARAM_ID_INT_TIMEZONE): + printf("%-17s: %d\n", "Timezone", iVal); + break; + case(PSP_SYSTEMPARAM_ID_INT_DAYLIGHTSAVINGS): + switch(iVal) { + case(PSP_SYSTEMPARAM_DAYLIGHTSAVINGS_STD): + printf("%-17s: standard\n", "Daylight Savings"); + break; + case(PSP_SYSTEMPARAM_DAYLIGHTSAVINGS_SAVING): + printf("%-17s: saving\n", "Daylight Savings"); + break; + default: + printf("%-17s: INVALID\n", "Daylight Savings"); + } + break; + case(PSP_SYSTEMPARAM_ID_INT_LANGUAGE): + switch(iVal) { + case(PSP_SYSTEMPARAM_LANGUAGE_JAPANESE): + printf("%-17s: Japanese\n", "Language"); + break; + case(PSP_SYSTEMPARAM_LANGUAGE_ENGLISH): + printf("%-17s: English\n", "Language"); + break; + case(PSP_SYSTEMPARAM_LANGUAGE_FRENCH): + printf("%-17s: French\n", "Language"); + break; + case(PSP_SYSTEMPARAM_LANGUAGE_SPANISH): + printf("%-17s: Spanish\n", "Language"); + break; + case(PSP_SYSTEMPARAM_LANGUAGE_GERMAN): + printf("%-17s: German\n", "Language"); + break; + case(PSP_SYSTEMPARAM_LANGUAGE_ITALIAN): + printf("%-17s: Italian\n", "Language"); + break; + case(PSP_SYSTEMPARAM_LANGUAGE_DUTCH): + printf("%-17s: Dutch\n", "Language"); + break; + case(PSP_SYSTEMPARAM_LANGUAGE_PORTUGUESE): + printf("%-17s: Portuguese\n", "Language"); + break; + case(PSP_SYSTEMPARAM_LANGUAGE_KOREAN): + printf("%-17s: Korean\n", "Language"); + break; + default: + printf("%-17s: INVALID\n", "Language"); + } + break; + case(PSP_SYSTEMPARAM_ID_INT_UNKNOWN): + printf("%-17s: %d (1 on NA PSPs and 0 on JAP PSPs, v1.5+ only)\n", "Unknown:", iVal); + break; + default: + printf("%-17s: int 0x%08X, string '%s'\n", "Unknown", iVal, sVal); + } +} + +/* main routine */ +int main(int argc, char *argv[]) +{ + char sVal[256]; + int iVal; + int i; + + //init screen and callbacks + pspDebugScreenInit(); + pspDebugScreenClear(); + + SetupCallbacks(); + + //fetch and print out power and battery information + pspDebugScreenSetXY(0, 0); + printf("SystemParam Sample v1.0 by John_K\n\n"); + + for (i = 0; i <= NUM_SYSTEMPARAMS; i++) { + iVal = 0xDEADBEEF; + memset(sVal, 0, 256); + if(sceUtilityGetSystemParamInt(i, &iVal) != PSP_SYSTEMPARAM_RETVAL_FAIL) + printSystemParam(i, iVal, sVal); + if(sceUtilityGetSystemParamString(i, sVal, 256) != PSP_SYSTEMPARAM_RETVAL_FAIL) + printSystemParam(i, iVal, sVal); + } + + sceKernelSleepThread(); + sceKernelExitGame(); + + return 0; +} diff --git a/src/samples/wlan/Makefile.sample b/src/samples/wlan/Makefile.sample new file mode 100644 index 00000000..21ddac85 --- /dev/null +++ b/src/samples/wlan/Makefile.sample @@ -0,0 +1,12 @@ +PSPSDK = $(shell psp-config --pspsdk-path) +PSPLIBSDIR = $(PSPSDK)/.. +TARGET = wlansample +OBJS = main.o +LIBS = -lpspwlan + + +CFLAGS = -O2 -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +include $(PSPSDK)/lib/build.mak diff --git a/src/samples/wlan/main.c b/src/samples/wlan/main.c new file mode 100644 index 00000000..d5c83687 --- /dev/null +++ b/src/samples/wlan/main.c @@ -0,0 +1,86 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Sample to demonstrate proper use of the systemparam functions + * + * Copyright (c) 2005 John Kelley + * + * $Id: main.c 2207 2007-03-16 16:42:08Z tyranid $ + */ +#include +#include +#include +#include +#include +//#include +#include + +/* Define the module info section */ +PSP_MODULE_INFO("Wlan Sample", 0, 1, 0); + +/* Define printf, just to make typing easier */ +#define printf pspDebugScreenPrintf + +/* Exit callback */ +int exit_callback(int arg1, int arg2, void *common) +{ + sceKernelExitGame(); + + return 0; +} + +/* Callback thread */ +int CallbackThread(SceSize args, void *argp) +{ + int cbid; + cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + sceKernelSleepThreadCB(); + + return 0; +} + +/* Sets up the callback thread and returns its thread id */ +int SetupCallbacks(void) +{ + int thid = 0; + thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, THREAD_ATTR_USER, 0); + if (thid >= 0) + sceKernelStartThread(thid, 0, 0); + return thid; +} + +/* main routine */ +int main(int argc, char *argv[]) +{ + u8 sVal[8]; + int retVal; + + //init screen and callbacks + pspDebugScreenInit(); + pspDebugScreenClear(); + + SetupCallbacks(); + + memset(sVal, 0, 7); + + for(;;) { + sceDisplayWaitVblankStart(); + pspDebugScreenSetXY(0, 0); + printf("Wlan Sample v1.0 by John_K\n\n"); + + printf("Wlan switch is %s\n", sceWlanGetSwitchState() == 0 ? "off":"on"); + printf("Wlan power is %s\n", sceWlanDevIsPowerOn() == 0 ? "off":"on"); + retVal = sceWlanGetEtherAddr(sVal); + if (retVal == 0) + printf("Wlan Ethernet Addr: %02X:%02X:%02X:%02X:%02X:%02X\n", sVal[0], sVal[1], sVal[2], sVal[3], sVal[4], sVal[5]); + else + printf("Error getting Wlan Ethernet Address (0x%08X)\n", retVal); + } + sceKernelSleepThread(); + sceKernelExitGame(); + + return 0; +} diff --git a/src/sdk/Makefile.am b/src/sdk/Makefile.am new file mode 100644 index 00000000..5eb96be6 --- /dev/null +++ b/src/sdk/Makefile.am @@ -0,0 +1,40 @@ + +libdir = @PSPSDK_LIBDIR@ + +CC = @PSP_CC@ +CCAS = $(CC) +AR = @PSP_AR@ +RANLIB = @PSP_RANLIB@ + +INCLUDES = -I$(top_srcdir)/src/base \ + -I$(top_srcdir)/src/kernel \ + -I$(top_srcdir)/src/user \ + -I$(top_srcdir)/src/net \ + -I$(top_srcdir)/src/utility \ + -I$(top_srcdir)/src/debug +CFLAGS = @PSPSDK_CFLAGS@ +CCASFLAGS = $(CFLAGS) $(INCLUDES) + +libpspsdkincludedir = @PSPSDK_INCLUDEDIR@ +libpspsdkinclude_HEADERS = pspsdk.h + +lib_LIBRARIES = libpspsdk.a + +MODULEMGR_PATCHES_OBJS = \ + InstallNoDeviceCheckPatch.o \ + InstallNoPlainModuleCheckPatch.o \ + InstallKernelLoadModulePatch.o + +INETHELPER_OBJS = pspSdkLoadInetModules.o pspSdkInetInit.o pspSdkInetTerm.o + +MULT_SRCS = modulemgr_patches.c inethelper.c +MULT_OBJS = $(MODULEMGR_PATCHES_OBJS) $(INETHELPER_OBJS) + +libpspsdk_a_SOURCES = query_mod.c loadmodule.c fixup.c threadutils.c interrupt.S k1set.S fpu.S $(MULT_SRCS) +libpspsdk_a_LIBADD = $(MULT_OBJS) + +$(MODULEMGR_PATCHES_OBJS): modulemgr_patches.c + $(COMPILE) -DF_$* $< -c -o $@ + +$(INETHELPER_OBJS): inethelper.c + $(COMPILE) -DF_$* $< -c -o $@ diff --git a/src/sdk/fixup.c b/src/sdk/fixup.c new file mode 100644 index 00000000..700364a4 --- /dev/null +++ b/src/sdk/fixup.c @@ -0,0 +1,113 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * fixup.c - Code to manually fixup late binding modules + * + * Copyright (c) 2005 John Kelley + * Copyright (c) 2005 Marcus R. Brown + * + * $Id: fixup.c 1888 2006-05-01 08:47:04Z tyranid $ + */ + +#include +#include + +struct SceLibStubEntry{ + char *moduleName; + unsigned short version; + unsigned short attr; + unsigned char structsz; // 0x5 + unsigned char numVars; + unsigned short numFuncs; + u32* nidList; + u32* stubs; +} __attribute__((packed)); + +struct PspModuleExport +{ + const char* name; + u32 flags; + u8 unk; + u8 v_count; + u16 f_count; + u32 *exports; +} __attribute__((packed)); + +extern SceModuleInfo module_info; + +static void *pspSdkFindExport(SceModule *modInfo, const char *exportName, u32 nid) { + void *pRet = NULL; + struct PspModuleExport *export; + if (modInfo == NULL) + return NULL; + + export = modInfo->ent_top; + + while(export < (struct PspModuleExport *)(modInfo->ent_top+modInfo->ent_size)) { + if (export->name != NULL && strcmp(exportName, export->name) == 0) { + u32 *nidlist; + int i; + int t_count; + + t_count = export->f_count + export->v_count; + nidlist = export->exports; + + for(i = 0; i < t_count; i++) { + if(nidlist[i] == nid) { + pRet = (void *) nidlist[i+t_count]; + break; + } + } + break; + } + export++; + } + + return pRet; +} + +void pspSdkFixupImports(int modId) +{ + struct SceLibStubEntry* stubEntry = module_info.stub_top; + int i; + u32 *nid, *stub; + void* addr; + SceModule *modInfo; + + modInfo = sceKernelFindModuleByUID(modId); + if (modInfo == NULL) { + Kprintf("Could not find module with id 0x%08X\n", modId); + return; + } + + while (stubEntry < (struct SceLibStubEntry*)module_info.stub_end) { + if (stubEntry->attr == 9) { //check to ensure this is a delayed import library + /*Kprintf("Fixing up imports for '%s'...\n", stubEntry->moduleName);*/ + for (i = 0; i < stubEntry->numVars+stubEntry->numFuncs; i++) { + stub = stubEntry->stubs; + stub += i * 2; // since each stub is 8 bytes + nid = stubEntry->nidList; + nid += i; + + //get addr of NID from library + addr = pspSdkFindExport(modInfo, stubEntry->moduleName, *nid); + if (addr != NULL) { + //fixup stub + //Kprintf("addr is 0x%08X\n", addr); + *stub = ((u32)addr & 0x03FFFFFF) >> 2 | 0x0A000000; //j addr + stub += 1; + *stub = 0; // nop + /* Okay if we fix up at least one function set attribute to 1 */ + stubEntry->attr = 1; + } + } + } + + stubEntry += 1; + } + //clear caches + sceKernelDcacheWritebackAll(); + sceKernelIcacheClearAll(); +} diff --git a/src/sdk/fpu.S b/src/sdk/fpu.S new file mode 100644 index 00000000..ffe11b1f --- /dev/null +++ b/src/sdk/fpu.S @@ -0,0 +1,15 @@ + + .set noreorder + .set noat + + .global pspSdkDisableFPUExceptions + .ent pspSdkDisableFPUExceptions + +pspSdkDisableFPUExceptions: + cfc1 $2, $31 + lui $8, 0x80 + and $8, $2, $8 # Mask off all bits except for 23 of FCR + ctc1 $8, $31 + jr $31 + nop + .end pspSdkDisableFPUExceptions diff --git a/src/sdk/inethelper.c b/src/sdk/inethelper.c new file mode 100644 index 00000000..75bba7e8 --- /dev/null +++ b/src/sdk/inethelper.c @@ -0,0 +1,104 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * inethelper.c - Helper functions for internet related modules. + * + * Copyright (c) 2005 John Kelley + * Copyright (c) 2005 Marcus R. Brown + * + * $Id: inethelper.c 2432 2008-09-17 19:44:47Z jim $ + */ + +#include +#include +#include +#include +#include +#include +//#include + +#ifdef F_pspSdkLoadInetModules +int pspSdkLoadInetModules() +{ + int modID; + + modID = pspSdkLoadStartModule("flash0:/kd/ifhandle.prx", PSP_MEMORY_PARTITION_KERNEL); + if (modID < 0) + return modID; + + modID = pspSdkLoadStartModule("flash0:/kd/pspnet.prx", PSP_MEMORY_PARTITION_USER); + if (modID < 0) + return modID; + else + pspSdkFixupImports(modID); + + modID = pspSdkLoadStartModule("flash0:/kd/pspnet_inet.prx", PSP_MEMORY_PARTITION_USER); + if (modID < 0) + return modID; + else + pspSdkFixupImports(modID); + + modID = pspSdkLoadStartModule("flash0:/kd/pspnet_apctl.prx", PSP_MEMORY_PARTITION_USER); + if (modID < 0) + return modID; + else + pspSdkFixupImports(modID); +/* + modID = loadModule("flash0:/kd/pspnet_ap_dialog_dummy.prx", PSP_MEMORY_PARTITION_USER); + if (modID < 0) + return modID; + else + fixupImports(modID); +*/ + modID = pspSdkLoadStartModule("flash0:/kd/pspnet_resolver.prx", PSP_MEMORY_PARTITION_USER); + if (modID < 0) + return modID; + else + pspSdkFixupImports(modID); + + return 0; +} +#endif + +#ifdef F_pspSdkInetInit +int pspSdkInetInit() +{ + u32 retVal; + + retVal = sceNetInit(0x20000, 0x20, 0x1000, 0x20, 0x1000); + if (retVal != 0) + return retVal; + + retVal = sceNetInetInit(); + if (retVal != 0) + return retVal; + + retVal = sceNetResolverInit(); + if (retVal != 0) + return retVal; + + retVal = sceNetApctlInit(0x1600, 0x42); + if (retVal != 0) + return retVal; + +/* + retVal = sceNetApDialogDummyInit(); + if(retVal != 0) + return retVal; +*/ + return 0; +} +#endif + +#ifdef F_pspSdkInetTerm +void pspSdkInetTerm() +{ + //sceNetApDialogDummyTerm(); + sceNetApctlTerm(); + sceNetResolverTerm(); + sceNetInetTerm(); + sceNetTerm(); +} +#endif diff --git a/src/sdk/interrupt.S b/src/sdk/interrupt.S new file mode 100644 index 00000000..92b2dd40 --- /dev/null +++ b/src/sdk/interrupt.S @@ -0,0 +1,66 @@ + + .set noreorder + .set noat + + .global pspSdkDisableInterrupts + .ent pspSdkDisableInterrupts + +pspSdkDisableInterrupts: + mfic $v0, $0 + mtic $0, $0 + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + jr $ra + nop + + .end pspSdkDisableInterrupts + + .global pspSdkEnableInterrupts + .ent pspSdkEnableInterrupts + +pspSdkEnableInterrupts: + mtic $a0, $0 + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + jr $ra + nop + + .end pspSdkEnableInterrupts diff --git a/src/sdk/k1set.S b/src/sdk/k1set.S new file mode 100644 index 00000000..e530fdef --- /dev/null +++ b/src/sdk/k1set.S @@ -0,0 +1,22 @@ + + .set noreorder + .set noat + + .global pspSdkSetK1 + .ent pspSdkSetK1 + +pspSdkSetK1: + move $v0, $k1 + jr $ra + move $k1, $a0 + + .end pspSdkSetK1 + + .global pspSdkGetK1 + .ent pspSdkGetK1 + +pspSdkGetK1: + jr $ra + move $v0, $k1 + + .end pspSdkGetK1 diff --git a/src/sdk/loadmodule.c b/src/sdk/loadmodule.c new file mode 100644 index 00000000..af400cbc --- /dev/null +++ b/src/sdk/loadmodule.c @@ -0,0 +1,66 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * loadmodule.c - Routines to simplify module loading and unloading. + * + * Copyright (c) 2005 John Kelley + * Copyright (c) 2005 Marcus R. Brown + * + * $Id: loadmodule.c 1737 2006-01-22 12:54:08Z tyranid $ + */ + +#include +#include +#include + +#define MAX_ARGS 2048 + +SceUID pspSdkLoadStartModuleWithArgs(const char *filename, int mpid, int argc, char * const argv[]) +{ + SceKernelLMOption option; + SceUID modid = 0; + int retVal = 0, mresult; + char args[MAX_ARGS]; + int argpos = 0; + int i; + + memset(args, 0, MAX_ARGS); + strcpy(args, filename); + argpos += strlen(args) + 1; + for(i = 0; (i < argc) && (argpos < MAX_ARGS); i++) + { + int len; + + snprintf(&args[argpos], MAX_ARGS-argpos, "%s", argv[i]); + len = strlen(&args[argpos]); + argpos += len + 1; + } + + memset(&option, 0, sizeof(option)); + option.size = sizeof(option); + option.mpidtext = mpid; + option.mpiddata = mpid; + option.position = 0; + option.access = 1; + + retVal = sceKernelLoadModule(filename, 0, &option); + if(retVal < 0){ + return retVal; + } + + modid = retVal; + + retVal = sceKernelStartModule(modid, argpos, args, &mresult, NULL); + if(retVal < 0){ + return retVal; + } + + return modid; +} + +SceUID pspSdkLoadStartModule(const char *filename, int mpid) +{ + return pspSdkLoadStartModuleWithArgs(filename, mpid, 0, NULL); +} diff --git a/src/sdk/modulemgr_patches.c b/src/sdk/modulemgr_patches.c new file mode 100644 index 00000000..69619dc2 --- /dev/null +++ b/src/sdk/modulemgr_patches.c @@ -0,0 +1,145 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * modulemgr_patches.c - Patches for sceModuleManager libraries. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: modulemgr_patches.c 2166 2007-02-04 10:52:49Z tyranid $ + */ + +#include +#include +#include +#include +#include +#include + +#define MM_MODNAME "sceModuleManager" + +#ifdef F_InstallNoDeviceCheckPatch + +#define IOFILEMGR_LIBNAME "IoFileMgrForKernel" +#define IOCTL_NID 0x63632449 +#define JR_RA_INSN 0x03e00008 +#define MOVE_V0_0_INSN 0x00001021 + +/* Nullify sceModuleMangager's LoadDeviceCheck() (and related calls). */ +int pspSdkInstallNoDeviceCheckPatch(void) +{ + SceModule *mm_module; + SceLibraryStubTable *libstubtable; + int found, i; + + mm_module = sceKernelFindModuleByName(MM_MODNAME); + if (mm_module == NULL) { + return SCE_KERNEL_ERROR_UNKNOWN_MODULE; + } + + libstubtable = (SceLibraryStubTable *) mm_module->stub_top; + found = 0; + /* Find the stub entry table for IoFileMgrForKernel. */ + while ((u32) libstubtable < ((u32) mm_module->stub_top + mm_module->stub_size)) { + if (strcmp(libstubtable->libname, IOFILEMGR_LIBNAME) == 0) { + found = 1; + break; + } + + libstubtable = (SceLibraryStubTable *) ((u32) libstubtable + (libstubtable->len * 4)); + } + + if (!found) { + return SCE_KERNEL_ERROR_LIBRARY_NOTFOUND; + } + + /* Find the NID for sceIoIoctl, and it's offset within the function stub table. */ + for (i = 0; i < libstubtable->stubcount; i++) { + if (libstubtable->nidtable[i] == IOCTL_NID) { + /* Found it, so patch the stub to return 0 so that all device checks pass. */ + u32 *ioctl_stub = (u32 *) ((u32) libstubtable->stubtable + (i * 8)); + + ioctl_stub[0] = JR_RA_INSN; + ioctl_stub[1] = MOVE_V0_0_INSN; + return 0; + } + } + + /* We couldn't find the stub entry. */ + return SCE_KERNEL_ERROR_ERROR; +} +#endif /* F_InstallNoDeviceCheckPatch */ + +#ifdef F_InstallNoPlainModuleCheckPatch + +#define LOAD_EXEC_PLAIN_CHECK 0x4000B000 /* mfc0 *, $22 */ +#define LOAD_EXEC_PLAIN_PATCH 0x34000001 /* li *, 1 */ + + +extern u32 sceKernelProbeExecutableObject; +extern u32 sceKernelCheckPspConfig; + +int pspSdkInstallNoPlainModuleCheckPatch(void) +{ + u32 *addr; + int i; + + addr = (u32*) (0x80000000 | ((sceKernelProbeExecutableObject & 0x03FFFFFF) << 2)); + //printf("sceKernelProbeExecutableObject %p\n", addr); + for(i = 0; i < 100; i++) + { + if((addr[i] & 0xFFE0FFFF) == LOAD_EXEC_PLAIN_CHECK) + { + //printf("Found instruction %p\n", &addr[i]); + addr[i] = (LOAD_EXEC_PLAIN_PATCH | (addr[i] & ~0xFFE0FFFF)); + } + } + + addr = (u32*) (0x80000000 | ((sceKernelCheckPspConfig & 0x03FFFFFF) << 2)); + //printf("sceCheckPspConfig %p\n", addr); + for(i = 0; i < 100; i++) + { + if((addr[i] & 0xFFE0FFFF) == LOAD_EXEC_PLAIN_CHECK) + { + //printf("Found instruction %p\n", &addr[i]); + addr[i] = (LOAD_EXEC_PLAIN_PATCH | (addr[i] & ~0xFFE0FFFF)); + } + } + + sceKernelDcacheWritebackAll(); + + return 0; +} +#endif /* F_InstallNoPlainModuleCheckPatch */ + +#ifdef F_InstallKernelLoadModulePatch + +#define LOAD_MODULE_KERN_CHECK 0x001BDC02 /* srl $k1, 16 */ +#define LOAD_MODULE_KERN_PATCH 0x0000d821 /* move $k1, $0 */ + +extern u32 sceKernelLoadModuleWithApitype; +void sceKernelIcacheInvalidateAll(); + +int pspSdkInstallKernelLoadModulePatch(void) +{ + u32 *addr; + int i; + + addr = (u32*) (0x80000000 | ((sceKernelLoadModuleWithApitype & 0x03FFFFFF) << 2)); + for(i = 0; i < 100; i++) + { + if(addr[i] == LOAD_MODULE_KERN_CHECK) + { + addr[i] = LOAD_MODULE_KERN_PATCH; + } + } + + sceKernelDcacheWritebackInvalidateAll(); + sceKernelIcacheInvalidateAll(); + + return 0; +} +#endif diff --git a/src/sdk/pspsdk.h b/src/sdk/pspsdk.h new file mode 100644 index 00000000..b6c5a24b --- /dev/null +++ b/src/sdk/pspsdk.h @@ -0,0 +1,296 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspsdk.h - Interface to the PSPSDK utility library. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: pspsdk.h 2433 2008-10-15 10:00:27Z iwn $ + */ + +#ifndef PSPSDK_H +#define PSPSDK_H + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup PSPSDK PSPSDK Utility Library */ + +/** @addtogroup PSPSDK */ +/*@{*/ + +/** + * Query a modules information from its uid. + * @note this is a replacement function for the broken kernel sceKernelQueryModuleInfo in v1.0 firmware + * DO NOT use on a anything above that version. This also needs kernel mode access where + * the normal one has a user mode stub. + * + * @param uid - The UID of the module to query. + * @param modinfo - Pointer a module SceKernelModuleInfo structure. + * + * @return < 0 on error. + */ +int pspSdkQueryModuleInfoV1(SceUID uid, SceKernelModuleInfo *modinfo); + +/** + * Get the list of module IDs. + * @note This is a replacement function for the missing v1.5 sceKernelGetModuleIdList + * on v1.0 firmware. DO NOT use on anything above that version. + * + * @param readbuf - Buffer to store the module list. + * @param readbufsize - Number of elements in the readbuffer. + * @param idcount - Returns the number of module ids + * + * @return >= 0 on success + */ +int pspSdkGetModuleIdList(SceUID *readbuf, int readbufsize, int *idcount); + +/** + * Patch the sceModuleManager module to nullify LoadDeviceCheck() calls. + * + * @return 0 on success, otherwise one of ::PspKernelErrorCodes. + * + * @note This function must be called while running in kernel mode. The program + * must also be linked against the pspkernel library. + */ +int pspSdkInstallNoDeviceCheckPatch(void); + +/** + * Patch sceLoadCore module to remove loading plain module checks + * + * @note This function must be called while running in kernel mode. + * + * @return 0 on success, otherwise one of ::PspKernelErrorCodes. + */ +int pspSdkInstallNoPlainModuleCheckPatch(void); + +/** + * Patch sceLoadModuleWithApiType to remove the kernel check in loadmodule allowing all modules to load + * + * @note This function must be called while running in kernel mode + * + * @return 0 on success + */ +int pspSdkInstallKernelLoadModulePatch(void); + +/** + * Load a module and start it. + * + * @param filename - Path to the module. + * @param mpid - Memory parition ID to use to load the module int. + * + * @return - The UID of the module on success, otherwise one of ::PspKernelErrorCodes. + */ +SceUID pspSdkLoadStartModule(const char *filename, int mpid); + +/** + * Load a module and start it with arguments + * + * @param filename - Path to the module. + * @param mpid - Memory parition ID to use to load the module int. + * @param argc - Number of arguments to pass to start module + * @param argv - Array of arguments + * + * @return - The UID of the module on success, otherwise one of ::PspKernelErrorCodes. + */ +SceUID pspSdkLoadStartModuleWithArgs(const char *filename, int mpid, int argc, char * const argv[]); + +/** + * Manually fixup library imports for late binding modules. + * + * @param moduleId - Id of the module to fixup + */ +void pspSdkFixupImports(int moduleId); + +/** + * Load Inet related modules. + * @note You must be in kernel mode to execute this function. + * + * @return - 0 on success, otherwise one of ::PspKernelErrorCodes. + */ +int pspSdkLoadInetModules(); + +/** + * Initialize Inet related modules. + * + * @return - 0 on success, otherwise one of ::PspKernelErrorCodes. + */ +int pspSdkInetInit(); + +/** + * Terminate Inet related modules. + */ +void pspSdkInetTerm(); + +/** + * Search for a thread with the given name and retrieve it's ::SceKernelThreadInfo struct. + * + * @param name - The name of the thread to search for. + * @param pUID - If the thread with the given name is found, it's ::SceUID is stored here. + * @param pInfo - If the thread with the given name is found, it's ::SceKernelThreadInfo data is stored here. + * + * @return 0 if successful, otherwise one of ::PspKernelErrorCodes. + */ +int pspSdkReferThreadStatusByName(const char *name, SceUID *pUID, SceKernelThreadInfo *pInfo); + +/** + * Search for a semaphore with the given name and retrieve it's ::SceKernelSemaInfo struct. + * + * @param name - The name of the sema to search for. + * @param pUID - If the sema with the given name is found, it's ::SceUID is stored here. + * @param pInfo - If the sema with the given name is found, it's ::SceKernelSemaInfo data is stored here. + * + * @return 0 if successful, otherwise one of ::PspKernelErrorCodes. + */ +int pspSdkReferSemaStatusByName(const char *name, SceUID *pUID, SceKernelSemaInfo *pInfo); + +/** + * Search for an event flag with the given name and retrieve it's ::SceKernelEventFlagInfo struct. + * + * @param name - The name of the event flag to search for. + * @param pUID - If the event flag with the given name is found, it's ::SceUID is stored here. + * @param pInfo - If the event flag with the given name is found, it's ::SceKernelEventFlagInfo data is stored here. + * + * @return 0 if successful, otherwise one of ::PspKernelErrorCodes. + */ +int pspSdkReferEventFlagStatusByName(const char *name, SceUID *pUID, SceKernelEventFlagInfo *pInfo); + +/** + * Search for a message box with the given name and retrieve it's ::SceKernelMbxInfo struct. + * + * @param name - The name of the message box to search for. + * @param pUID - If the message box with the given name is found, it's ::SceUID is stored here. + * @param pInfo - If the message box with the given name is found, it's ::SceKernelMbxInfo data is stored here. + * + * @return 0 if successful, otherwise one of ::PspKernelErrorCodes. + */ +int pspSdkReferMboxStatusByName(const char *name, SceUID *pUID, SceKernelMbxInfo *pInfo); + +/** + * Search for a VPL with the given name and retrieve it's ::SceKernelVplInfo struct. + * + * @param name - The name of to search for. + * @param pUID - If the given name is found, it's ::SceUID is stored here. + * @param pInfo - If the given name is found, it's ::SceKernelVplInfo data is stored here. + * + * @return 0 if successful, otherwise one of ::PspKernelErrorCodes. + */ +int pspSdkReferVplStatusByName(const char *name, SceUID *pUID, SceKernelVplInfo *pInfo); + +/** + * Search for a FPL with the given name and retrieve it's ::SceKernelFplInfo struct. + * + * @param name - The name of to search for. + * @param pUID - If the given name is found, it's ::SceUID is stored here. + * @param pInfo - If the given name is found, it's ::SceKernelFplInfo data is stored here. + * + * @return 0 if successful, otherwise one of ::PspKernelErrorCodes. + */ +int pspSdkReferFplStatusByName(const char *name, SceUID *pUID, SceKernelFplInfo *pInfo); + +/** + * Search for a message pipe with the given name and retrieve it's ::SceKernelMppInfo struct. + * + * @param name - The name of to search for. + * @param pUID - If the given name is found, it's ::SceUID is stored here. + * @param pInfo - If the given name is found, it's ::SceKernelMppInfo data is stored here. + * + * @return 0 if successful, otherwise one of ::PspKernelErrorCodes. + */ +int pspSdkReferMppStatusByName(const char *name, SceUID *pUID, SceKernelMppInfo *pInfo); + +/** + * Search for a callback with the given name and retrieve it's ::SceKernelCallbackInfo struct. + * + * @param name - The name of to search for. + * @param pUID - If the given name is found, it's ::SceUID is stored here. + * @param pInfo - If the given name is found, it's ::SceKernelMppInfo data is stored here. + * + * @return 0 if successful, otherwise one of ::PspKernelErrorCodes. + */ +int pspSdkReferCallbackStatusByName(const char *name, SceUID *pUID, SceKernelCallbackInfo *pInfo); + +/** + * Search for a vtimer with the given name and retrieve it's ::SceKernelVTimerInfo struct. + * + * @param name - The name of to search for. + * @param pUID - If the given name is found, it's ::SceUID is stored here. + * @param pInfo - If the given name is found, it's ::SceKernelVTimerInfo data is stored here. + * + * @return 0 if successful, otherwise one of ::PspKernelErrorCodes. + */ +int pspSdkReferVTimerStatusByName(const char *name, SceUID *pUID, SceKernelVTimerInfo *pInfo); + +/** + * Search for a thread event handler with the given name and retrieve it's ::SceKernelThreadEventHandlerInfo struct. + * + * @param name - The name of to search for. + * @param pUID - If the given name is found, it's ::SceUID is stored here. + * @param pInfo - If the given name is found, it's ::SceKernelThreadEventHandlerInfo data is stored here. + * + * @return 0 if successful, otherwise one of ::PspKernelErrorCodes. + */ +int pspSdkReferThreadEventHandlerStatusByName(const char *name, SceUID *pUID, SceKernelThreadEventHandlerInfo *pInfo); + +/** + * Disable interrupts + * + * @note Do not disable interrupts for too long otherwise the watchdog will get you. + * + * @return The previous state of the interrupt enable bit (should be passed back to ::pspSdkEnableInterrupts) + */ +unsigned int pspSdkDisableInterrupts(void); + +/** + * Enable interrupts + * + * @param istate - The interrupt state as returned from ::pspSdkDisableInterrupts + */ +void pspSdkEnableInterrupts(unsigned int istate); + +/** + * Set the processors K1 register to a known value + * + * @note This function is for use in kernel mode syscall exports. The kernel + * sets the k1 register to indicate what mode called the function, i.e. + * whether it was directly called, was called via a syscall from a kernel + * thread or called via a syscall from a user thread. By setting k1 to 0 + * before doing anything in your code you can make the other functions think + * you are calling from a kernel thread and therefore disable numerous + * protections. + * + * @param k1 - The k1 value to set + * + * @return The previous value of k1 + */ +unsigned int pspSdkSetK1(unsigned int k1); + +/** + * Get the current value of the processors K1 register + * + * @return The current value of K1 + */ +unsigned int pspSdkGetK1(void); + +/** + * Disable the CPUs FPU exceptions + */ +void pspSdkDisableFPUExceptions(void); + +/*@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* PSPSDK_H */ diff --git a/src/sdk/query_mod.c b/src/sdk/query_mod.c new file mode 100644 index 00000000..d6c7c244 --- /dev/null +++ b/src/sdk/query_mod.c @@ -0,0 +1,57 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * query_mod.c - Replacement for some missing modulemgr functions for v1.0 units. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: query_mod.c 1148 2005-10-12 19:08:27Z tyranid $ + */ + +#include +#include +#include +#include +#include +#include + +int pspSdkGetModuleIdList(SceUID *readbuf, int readbufsize, int *idcount) +{ + sceKernelGetModuleList(readbufsize / sizeof(SceUID), readbuf); + *idcount = sceKernelModuleCount(); + + return *idcount; +} + +int pspSdkQueryModuleInfoV1(SceUID uid, SceKernelModuleInfo *modinfo) +{ + SceModule *mod; + + mod = sceKernelFindModuleByUID(uid); + if(mod != NULL) + { + memcpy(modinfo->name, mod->modname, sizeof(mod->modname) + 1); + modinfo->attribute = mod->attribute; + modinfo->version[0] = mod->version[0]; + modinfo->version[1] = mod->version[1]; + modinfo->nsegment = (unsigned char )mod->nsegment; + modinfo->entry_addr = mod->entry_addr; + modinfo->gp_value = mod->gp_value; + modinfo->text_addr = mod->text_addr; + modinfo->text_size = mod->text_size; + modinfo->data_size = mod->data_size; + modinfo->bss_size = mod->bss_size; + memcpy(modinfo->segmentaddr, mod->segmentaddr, sizeof(unsigned int) * 4); + memcpy(modinfo->segmentsize, mod->segmentsize, sizeof(unsigned int) * 4); + } + else + { + return -1; + } + + return 0; +} diff --git a/src/sdk/threadutils.c b/src/sdk/threadutils.c new file mode 100644 index 00000000..30a32762 --- /dev/null +++ b/src/sdk/threadutils.c @@ -0,0 +1,343 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * threadutils.c - Thread manager extensions. + * + * Copyright (c) 2005 Marcus R. Brown + * + * $Id: threadutils.c 1658 2006-01-07 15:27:56Z tyranid $ + */ + +#include + +#include "pspthreadman.h" +#include "pspsdk.h" + +#define MAX_UIDS 256 + +/* TODO: Generalize this for all thread primatives that have names. */ + +struct _ThreadInfoSkel +{ + SceSize size; + char name[32]; +}; + +typedef int (*ReferFunc)(SceUID, struct _ThreadInfoSkel*); + +static int _pspSdkReferInternal(const char *name, enum SceKernelIdListType type, + struct _ThreadInfoSkel *pInfo, int size, ReferFunc pRefer) +{ + int uid_count = 0; + + /* First determine the number of threads we have. */ + int res = sceKernelGetThreadmanIdList(type, NULL, 0, &uid_count); + if (res < 0) { + return res; + } + if (uid_count == 0) { + return -1; /* XXX: Should we return a kernel errorcode here? */ + } + + /* Grab UIDs for all of the threads. */ + SceUID uid_buf[uid_count]; + res = sceKernelGetThreadmanIdList(type, uid_buf, uid_count, NULL); + if (res < 0) { + return res; + } + + int i; + for (i = 0; i < uid_count; i++) { + memset(pInfo, 0, size); + pInfo->size = size; + + res = pRefer(uid_buf[i], pInfo); + if (res < 0) { + /* If we got an error than we probably don't have enough privileges + to access the thread's info. */ + continue; + } + + if (pInfo->name[0] != '\0' && strcmp(pInfo->name, name) == 0) { + /* Found it. */ + return uid_buf[i]; + } + } + + /* Unable to find the thread (or insufficient access to retrieve it's info). */ + return -1; /* XXX: Should we return a kernel errorcode here? */ +} + +int pspSdkReferSemaStatusByName(const char *name, SceUID *pUID, SceKernelSemaInfo *pInfo) +{ + SceKernelSemaInfo intSema; + SceUID uid; + + uid = _pspSdkReferInternal(name, SCE_KERNEL_TMID_Semaphore, (struct _ThreadInfoSkel *) &intSema, + sizeof(intSema), (ReferFunc) sceKernelReferSemaStatus); + if(uid > 0) + { + if(pUID != NULL) + { + *pUID = uid; + } + + if(pInfo != NULL) + { + memcpy(pInfo, &intSema, sizeof(intSema)); + } + } + else + { + return -1; + } + + return 0; +} + +int pspSdkReferEventFlagStatusByName(const char *name, SceUID *pUID, SceKernelEventFlagInfo *pInfo) +{ + SceKernelEventFlagInfo intEvent; + SceUID uid; + + uid = _pspSdkReferInternal(name, SCE_KERNEL_TMID_EventFlag, (struct _ThreadInfoSkel *) &intEvent, + sizeof(intEvent), (ReferFunc) sceKernelReferEventFlagStatus); + if(uid > 0) + { + if(pUID != NULL) + { + *pUID = uid; + } + + if(pInfo != NULL) + { + memcpy(pInfo, &intEvent, sizeof(intEvent)); + } + } + else + { + return -1; + } + + return 0; +} + +int pspSdkReferThreadStatusByName(const char *name, SceUID *pUID, SceKernelThreadInfo *pInfo) +{ + SceKernelThreadInfo intThread; + SceUID uid; + + uid = _pspSdkReferInternal(name, SCE_KERNEL_TMID_Thread, (struct _ThreadInfoSkel *) &intThread, + sizeof(intThread), (ReferFunc) sceKernelReferThreadStatus); + if(uid > 0) + { + if(pUID != NULL) + { + *pUID = uid; + } + + if(pInfo != NULL) + { + memcpy(pInfo, &intThread, sizeof(intThread)); + } + } + else + { + return -1; + } + + return 0; +} + +int pspSdkReferMboxStatusByName(const char *name, SceUID *pUID, SceKernelMbxInfo *pInfo) +{ + SceKernelMbxInfo intMbx; + SceUID uid; + + uid = _pspSdkReferInternal(name, SCE_KERNEL_TMID_Mbox, (struct _ThreadInfoSkel *) &intMbx, + sizeof(intMbx), (ReferFunc) sceKernelReferMbxStatus); + if(uid > 0) + { + if(pUID != NULL) + { + *pUID = uid; + } + + if(pInfo != NULL) + { + memcpy(pInfo, &intMbx, sizeof(intMbx)); + } + } + else + { + return -1; + } + + return 0; +} + + +int pspSdkReferVplStatusByName(const char *name, SceUID *pUID, SceKernelVplInfo *pInfo) +{ + SceKernelVplInfo intVpl; + SceUID uid; + + uid = _pspSdkReferInternal(name, SCE_KERNEL_TMID_Vpl, (struct _ThreadInfoSkel *) &intVpl, + sizeof(intVpl), (ReferFunc) sceKernelReferVplStatus); + if(uid > 0) + { + if(pUID != NULL) + { + *pUID = uid; + } + + if(pInfo != NULL) + { + memcpy(pInfo, &intVpl, sizeof(intVpl)); + } + } + else + { + return -1; + } + + return 0; +} + +int pspSdkReferFplStatusByName(const char *name, SceUID *pUID, SceKernelFplInfo *pInfo) +{ + SceKernelVplInfo intFpl; + SceUID uid; + + uid = _pspSdkReferInternal(name, SCE_KERNEL_TMID_Fpl, (struct _ThreadInfoSkel *) &intFpl, + sizeof(intFpl), (ReferFunc) sceKernelReferFplStatus); + if(uid > 0) + { + if(pUID != NULL) + { + *pUID = uid; + } + + if(pInfo != NULL) + { + memcpy(pInfo, &intFpl, sizeof(intFpl)); + } + } + else + { + return -1; + } + + return 0; +} + + +int pspSdkReferMppStatusByName(const char *name, SceUID *pUID, SceKernelMppInfo *pInfo) +{ + SceKernelMppInfo intMpp; + SceUID uid; + + uid = _pspSdkReferInternal(name, SCE_KERNEL_TMID_Mpipe, (struct _ThreadInfoSkel *) &intMpp, + sizeof(intMpp), (ReferFunc) sceKernelReferMsgPipeStatus); + if(uid > 0) + { + if(pUID != NULL) + { + *pUID = uid; + } + + if(pInfo != NULL) + { + memcpy(pInfo, &intMpp, sizeof(intMpp)); + } + } + else + { + return -1; + } + + return 0; +} + +int pspSdkReferCallbackStatusByName(const char *name, SceUID *pUID, SceKernelCallbackInfo *pInfo) +{ + SceKernelCallbackInfo intCB; + SceUID uid; + + uid = _pspSdkReferInternal(name, SCE_KERNEL_TMID_Callback, (struct _ThreadInfoSkel *) &intCB, + sizeof(intCB), (ReferFunc) sceKernelReferCallbackStatus); + if(uid > 0) + { + if(pUID != NULL) + { + *pUID = uid; + } + + if(pInfo != NULL) + { + memcpy(pInfo, &intCB, sizeof(intCB)); + } + } + else + { + return -1; + } + + return 0; +} + +int pspSdkReferVTimerStatusByName(const char *name, SceUID *pUID, SceKernelVTimerInfo *pInfo) +{ + SceKernelVTimerInfo intVT; + SceUID uid; + + uid = _pspSdkReferInternal(name, SCE_KERNEL_TMID_VTimer, (struct _ThreadInfoSkel *) &intVT, + sizeof(intVT), (ReferFunc) sceKernelReferVTimerStatus); + if(uid > 0) + { + if(pUID != NULL) + { + *pUID = uid; + } + + if(pInfo != NULL) + { + memcpy(pInfo, &intVT, sizeof(intVT)); + } + } + else + { + return -1; + } + + return 0; +} + +int pspSdkReferThreadEventHandlerStatusByName(const char *name, SceUID *pUID, SceKernelThreadEventHandlerInfo *pInfo) +{ + SceKernelThreadEventHandlerInfo intEH; + SceUID uid; + + uid = _pspSdkReferInternal(name, SCE_KERNEL_TMID_ThreadEventHandler, (struct _ThreadInfoSkel *) &intEH, + sizeof(intEH), (ReferFunc) sceKernelReferThreadEventHandlerStatus); + if(uid > 0) + { + if(pUID != NULL) + { + *pUID = uid; + } + + if(pInfo != NULL) + { + memcpy(pInfo, &intEH, sizeof(intEH)); + } + } + else + { + return -1; + } + + return 0; +} diff --git a/src/sircs/Makefile.am b/src/sircs/Makefile.am new file mode 100644 index 00000000..cb228db9 --- /dev/null +++ b/src/sircs/Makefile.am @@ -0,0 +1,23 @@ + +libdir = @PSPSDK_LIBDIR@ + +CC = @PSP_CC@ +CCAS = $(CC) +AR = @PSP_AR@ +RANLIB = @PSP_RANLIB@ + +INCLUDES = -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel +CFLAGS = @PSPSDK_CFLAGS@ +CCASFLAGS = $(CFLAGS) -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel + +SIRCS_OBJS = sceSircs_0000.o sceSircs_0001.o + +libpspsircsincludedir = @PSPSDK_INCLUDEDIR@ +libpspsircsinclude_HEADERS = pspsircs.h + +lib_LIBRARIES = libpspsircs.a +libpspsircs_a_SOURCES = sceSircs.S +libpspsircs_a_LIBADD = $(SIRCS_OBJS) + +$(SIRCS_OBJS): sceSircs.S + $(COMPILE) -DF_$* $< -c -o $@ diff --git a/src/sircs/pspsircs.h b/src/sircs/pspsircs.h new file mode 100644 index 00000000..1b3ea2f9 --- /dev/null +++ b/src/sircs/pspsircs.h @@ -0,0 +1,45 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspmodulemgr.h - Prototypes to manage manage modules. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * Copyright (c) 2005 Matthew H + * + * $$ + */ +#ifndef __SIRCS_H__ +#define __SIRCS_H__ + +/** @defgroup Sony Integrated Remote Control System Library + * This module contains the imports for the kernel's remote control routines. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup Sony Integrated Remote Control System Library */ +/*@{*/ + +struct sircs_data { + u8 type; // 12, 15 or 20 bits + u8 cmd; // 7 bit cmd + u16 dev; // 5, 8 or 13 bit device address +} __packed__; + +/** + */ +int sceSircsSend(struct sircs_data* sd, int count); + +/*@}*/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/sircs/sceSircs.S b/src/sircs/sceSircs.S new file mode 100644 index 00000000..e016fe10 --- /dev/null +++ b/src/sircs/sceSircs.S @@ -0,0 +1,10 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceSircs_0000 + IMPORT_START "sceSircs",0x40010000 +#endif +#ifdef F_sceSircs_0001 + IMPORT_FUNC "sceSircs",0x71EEF62D,sceSircsSend +#endif diff --git a/src/startup/Makefile.am b/src/startup/Makefile.am new file mode 100644 index 00000000..e37dad7b --- /dev/null +++ b/src/startup/Makefile.am @@ -0,0 +1,36 @@ + +CC = @PSP_CC@ +CCAS = $(CC) +AR = @PSP_AR@ +RANLIB = @PSP_RANLIB@ + +INCLUDES = -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel -I$(top_srcdir)/src/user -I$(top_srcdir)/src/debug +CFLAGS = @PSPSDK_CFLAGS@ +CCASFLAGS = $(CFLAGS) $(INCLUDES) + +## Borrow this trick from newlib - create a dummy library to generate build rules. +noinst_LIBRARIES = lib.a +lib_a_SOURCES = dummy.c + +all: crt0.o crt0_prx.o prxexports.o + +startupdir = @PSPDEV_LIBDIR@ +pspsdkdir = @PSPSDK_LIBDIR@ + +# Install the prx specific stuff in the pspsdk libdir +install-exec-hook: + $(mkinstalldirs) $(DESTDIR)$(startupdir) + $(INSTALL_DATA) crt0.o $(DESTDIR)$(startupdir)/crt0.o + $(INSTALL_DATA) crt0_prx.o $(DESTDIR)$(startupdir)/crt0_prx.o + $(INSTALL_DATA) prxexports.o $(DESTDIR)$(pspsdkdir)/prxexports.o + + +uninstall-hook: + rm -f $(DESTDIR)$(startupdir)/crt0.o + rm -f $(DESTDIR)$(startupdir)/crt0_prx.o + rm -f $(DESTDIR)$(pspsdkdir)/prxexports.o + +CLEANFILES = crt0.o crt0_prx.o prxexports.o + +## How else do I add a dependency for this? +EXTRA_DIST = crt0.c crt0_prx.c prxexports.c diff --git a/src/startup/crt0.c b/src/startup/crt0.c new file mode 100644 index 00000000..6dbfe0ac --- /dev/null +++ b/src/startup/crt0.c @@ -0,0 +1,173 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * crt0.c - Startup code. + * + * Copyright (c) 2005 Marcus R. Brown + * + * $Id: crt0.c 1531 2005-12-07 18:27:12Z tyranid $ + */ + +#include +#include +#include +#include +#include + +/* The maximum number of arguments that can be passed to main(). */ +#define ARG_MAX 19 + +/* Default thread parameters for the main program thread. */ +#define DEFAULT_THREAD_PRIORITY 32 +#define DEFAULT_THREAD_ATTRIBUTE PSP_THREAD_ATTR_USER +#define DEFAULT_THREAD_STACK_KB_SIZE 256 +#define DEFAULT_MAIN_THREAD_NAME "user_main" + +/* If these variables are defined by the program, then they override the + defaults given above. */ +extern int sce_newlib_nocreate_thread_in_start __attribute__((weak)); +extern unsigned int sce_newlib_priority __attribute__((weak)); +extern unsigned int sce_newlib_attribute __attribute__((weak)); +extern unsigned int sce_newlib_stack_kb_size __attribute__((weak)); +extern const char* sce_newlib_main_thread_name __attribute__((weak)); + +/* This is declared weak in case someone compiles an empty program. That + program won't work on the PSP, but it could be useful for testing the + toolchain. */ +extern SceModuleInfo module_info __attribute__((weak)); + +/* Allow newlib/psplibc to provide an init hook to be called before main */ +extern void __psp_libc_init(int argc, char *argv[]) __attribute__((weak)); + +extern void _init(void); +extern void _fini(void); + +extern int main(int argc, char *argv[]); + +/** + * Main program thread + * + * Initializes runtime parameters and calls the program's main(). + * + * @param args - Size (in bytes) of the argp parameter. + * @param argp - Pointer to program arguments. Each argument is a NUL-terminated string. + */ +void _main(SceSize args, void *argp) +{ + char *argv[ARG_MAX + 1]; + int argc = 0; + int loc = 0; + char *ptr = argp; + + /* Turn our thread arguments into main()'s argc and argv[]. */ + while(loc < args) + { + argv[argc] = &ptr[loc]; + loc += strlen(&ptr[loc]) + 1; + argc++; + if(argc == ARG_MAX) + { + break; + } + } + + argv[argc] = NULL; + + /* Call libc initialization hook */ + if(__psp_libc_init != NULL) + __psp_libc_init(argc, argv); + + /* Make sure _fini() is called when the program ends. */ + atexit((void *) _fini); + + /* Call main(). */ + int res = main(argc, argv); + + /* Return control to the operating system. */ + exit(res); +} + +/** + * Startup thread + * + * Creates the main program thread based on variables defined by the program. + * + * @param args - Size (in bytes) of arguments passed to the program by the kernel. + * @param argp - Pointer to arguments passed by the kernel. + */ +int _start(SceSize args, void *argp) +{ + void (*_main_func)(SceSize args, void *argp) = _main; + void (*_init_func)(void) = _init; + + if ((&module_info != NULL) && (module_info.modattribute & 0x1000)) { + /* If we're running in kernel mode, the addresses of our _main() thread + and _init() function must also reside in kernel mode. */ + _main_func = (void *) ((u32) _main_func | 0x80000000); + _init_func = (void *) ((u32) _init_func | 0x80000000); + } + + /* Call _init() here, because an app may have code that needs to run in + kernel mode, but want their main() thread to run in user mode. If they + define "constructors" they can do any kernel mode initialization here + before their app is switched. */ + _init_func(); + + if (&sce_newlib_nocreate_thread_in_start != NULL) { + /* The program does not want main() to be run in a seperate thread. */ + _main_func(args, argp); + return 1; + } + + int priority = DEFAULT_THREAD_PRIORITY; + unsigned int attribute = DEFAULT_THREAD_ATTRIBUTE; + unsigned int stackSize = DEFAULT_THREAD_STACK_KB_SIZE * 1024; + const char *threadName = DEFAULT_MAIN_THREAD_NAME; + + if (&sce_newlib_priority != NULL) { + priority = sce_newlib_priority; + } + if (&sce_newlib_attribute != NULL) { + attribute = sce_newlib_attribute; + } + if (&sce_newlib_stack_kb_size != NULL) { + stackSize = sce_newlib_stack_kb_size * 1024; + } + if (&sce_newlib_main_thread_name != NULL) { + threadName = sce_newlib_main_thread_name; + } + + /* Does the _main() thread belong to the User, VSH, or USB/WLAN APIs? */ + if (attribute & (PSP_THREAD_ATTR_USER | PSP_THREAD_ATTR_USBWLAN | PSP_THREAD_ATTR_VSH)) { + /* Remove the kernel mode addressing from the pointer to _main(). */ + _main_func = (void *) ((u32) _main_func & 0x7fffffff); + } + + SceUID thid; + thid = sceKernelCreateThread(threadName, (void *) _main_func, priority, stackSize, attribute, 0); + sceKernelStartThread(thid, args, argp); + + return 0; +} + +/* The entry table provides pointers to the executable's _start() and + module_info structure. */ +static const unsigned int __entrytable[4] __attribute__((section(".rodata.sceResident"))) = { + 0xD632ACDB, 0xF01D73A7, (unsigned int) &_start, (unsigned int) &module_info +}; + +/* Create the empty library entry used to describe the program's _start() and + module_info. */ +static const struct _library_entry { + const char * name; + unsigned short version; + unsigned short attribute; + unsigned char entLen; + unsigned char varCount; + unsigned short funcCount; + void * entrytable; +} _library_entry __attribute__((section(".lib.ent"), used)) = { + NULL, 0, 0x8000, 4, 1, 1, &__entrytable +}; diff --git a/src/startup/crt0_prx.c b/src/startup/crt0_prx.c new file mode 100644 index 00000000..b2d8ba74 --- /dev/null +++ b/src/startup/crt0_prx.c @@ -0,0 +1,138 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * crt0_prx.c - Pure PRX startup code. + * + * Copyright (c) 2005 Marcus R. Brown + * + * $Id: crt0.c 1526 2005-12-06 21:56:06Z tyranid $ + */ + +#include +#include +#include +#include +#include + +/* The maximum number of arguments that can be passed to main(). */ +#define ARG_MAX 19 + +/* Default thread parameters for the main program thread. */ +#define DEFAULT_THREAD_PRIORITY 32 +#define DEFAULT_THREAD_ATTRIBUTE 0 +#define DEFAULT_THREAD_STACK_KB_SIZE 256 +#define DEFAULT_MAIN_THREAD_NAME "user_main" + +/* Define us as a prx */ +int __pspsdk_is_prx = 1; + +/* If these variables are defined by the program, then they override the + defaults given above. */ +extern int sce_newlib_nocreate_thread_in_start __attribute__((weak)); +extern unsigned int sce_newlib_priority __attribute__((weak)); +extern unsigned int sce_newlib_attribute __attribute__((weak)); +extern unsigned int sce_newlib_stack_kb_size __attribute__((weak)); +extern const char* sce_newlib_main_thread_name __attribute__((weak)); + +/* This is declared weak in case someone compiles an empty program. That + program won't work on the PSP, but it could be useful for testing the + toolchain. */ +extern SceModuleInfo module_info __attribute__((weak)); + +/* Allow newlib/psplibc to provide an init hook to be called before main */ +extern void __psp_libc_init(int argc, char *argv[]) __attribute__((weak)); + +extern void _init(void); +extern void _fini(void); + +extern int main(int argc, char *argv[]); + +/** + * Main program thread + * + * Initializes runtime parameters and calls the program's main(). + * + * @param args - Size (in bytes) of the argp parameter. + * @param argp - Pointer to program arguments. Each argument is a NUL-terminated string. + */ +void _main(SceSize args, void *argp) +{ + char *argv[ARG_MAX + 1]; + int argc = 0; + int loc = 0; + char *ptr = argp; + + _init(); + + /* Turn our thread arguments into main()'s argc and argv[]. */ + while(loc < args) + { + argv[argc] = &ptr[loc]; + loc += strlen(&ptr[loc]) + 1; + argc++; + if(argc == ARG_MAX) + { + break; + } + } + + argv[argc] = NULL; + + /* Call libc initialization hook */ + if(__psp_libc_init != NULL) + __psp_libc_init(argc, argv); + + /* Make sure _fini() is called when the program ends. */ + atexit((void *) _fini); + + /* Call main(). */ + int res = main(argc, argv); + + /* Return control to the operating system. */ + exit(res); +} + +int module_start(SceSize args, void *argp) __attribute__((alias("_start"))); + +/** + * Startup thread + * + * Creates the main program thread based on variables defined by the program. + * + * @param args - Size (in bytes) of arguments passed to the program by the kernel. + * @param argp - Pointer to arguments passed by the kernel. + */ +int _start(SceSize args, void *argp) +{ + if (&sce_newlib_nocreate_thread_in_start != NULL) { + /* The program does not want main() to be run in a seperate thread. */ + _main(args, argp); + return 1; + } + + int priority = DEFAULT_THREAD_PRIORITY; + unsigned int attribute = DEFAULT_THREAD_ATTRIBUTE; + unsigned int stackSize = DEFAULT_THREAD_STACK_KB_SIZE * 1024; + const char *threadName = DEFAULT_MAIN_THREAD_NAME; + + if (&sce_newlib_priority != NULL) { + priority = sce_newlib_priority; + } + if (&sce_newlib_attribute != NULL) { + attribute = sce_newlib_attribute; + } + if (&sce_newlib_stack_kb_size != NULL) { + stackSize = sce_newlib_stack_kb_size * 1024; + } + if (&sce_newlib_main_thread_name != NULL) { + threadName = sce_newlib_main_thread_name; + } + + SceUID thid; + thid = sceKernelCreateThread(threadName, (void *) _main, priority, stackSize, attribute, 0); + sceKernelStartThread(thid, args, argp); + + return 0; +} diff --git a/src/startup/dummy.c b/src/startup/dummy.c new file mode 100644 index 00000000..e69de29b diff --git a/src/startup/prxexports.c b/src/startup/prxexports.c new file mode 100644 index 00000000..8529adf5 --- /dev/null +++ b/src/startup/prxexports.c @@ -0,0 +1,27 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspexports.c - Define the default set of exports for an executable + * + * Copyright (c) 2005 James F. + * + * $Id: pspexports.c 1521 2005-12-04 20:32:16Z tyranid $ + * $HeadURL: svn://tyranid@svn.pspdev.org/psp/trunk/pspsdk/src/startup/pspexports.c $ + */ +#include +#define NULL ((void *) 0) + +void extern module_start; +void extern module_info; +static const unsigned int __syslib_exports[4] __attribute__((section(".rodata.sceResident"))) = { + 0xD632ACDB, + 0xF01D73A7, + (unsigned int) &module_start, + (unsigned int) &module_info, +}; + +const struct _PspLibraryEntry __library_exports[1] __attribute__((section(".lib.ent"), used)) = { + { NULL, 0x0000, 0x8000, 4, 1, 1, &__syslib_exports }, +}; diff --git a/src/umd/Makefile.am b/src/umd/Makefile.am new file mode 100644 index 00000000..cad017fd --- /dev/null +++ b/src/umd/Makefile.am @@ -0,0 +1,32 @@ + +libdir = @PSPSDK_LIBDIR@ + +CC = @PSP_CC@ +CCAS = $(CC) +AR = @PSP_AR@ +RANLIB = @PSP_RANLIB@ + +INCLUDES = -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel +CFLAGS = @PSPSDK_CFLAGS@ +CCASFLAGS = $(CFLAGS) -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel + +UMDUSER_OBJS = sceUmdUser_0000.o sceUmdUser_0001.o sceUmdUser_0002.o sceUmdUser_0003.o sceUmdUser_0004.o sceUmdUser_0005.o sceUmdUser_0006.o sceUmdUser_0007.o sceUmdUser_0008.o sceUmdUser_0009.o sceUmdUser_0010.o sceUmdUser_0011.o sceUmdUser_0012.o sceUmdUser_0013.o sceUmdUser_0014.o + +UMD_OBJS = sceUmd_0000.o sceUmd_0001.o sceUmd_0002.o sceUmd_0003.o sceUmd_0004.o sceUmd_0005.o sceUmd_0006.o sceUmd_0007.o sceUmd_0008.o sceUmd_0009.o sceUmd_0010.o sceUmd_0011.o sceUmd_0012.o sceUmd_0013.o sceUmd_0014.o sceUmd_0015.o sceUmd_0016.o sceUmd_0017.o sceUmd_0018.o sceUmd_0019.o sceUmd_0020.o sceUmd_0021.o sceUmd_0022.o sceUmd_0023.o sceUmd_0024.o sceUmd_0025.o sceUmd_0026.o sceUmd_0027.o sceUmd_0028.o sceUmd_0029.o sceUmd_0030.o sceUmd_0031.o sceUmd_0032.o sceUmd_0033.o sceUmd_0034.o sceUmd_0035.o + +libpspumdlincludedir = @PSPSDK_INCLUDEDIR@ +libpspumdlinclude_HEADERS = pspumd.h + +lib_LIBRARIES = libpspumd.a libpspumd_driver.a + +libpspumd_a_SOURCES = sceUmdUser.S +libpspumd_a_LIBADD = $(UMDUSER_OBJS) + +libpspumd_driver_a_SOURCES = sceUmd.S +libpspumd_driver_a_LIBADD = $(UMD_OBJS) + +$(UMDUSER_OBJS): sceUmdUser.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(UMD_OBJS): sceUmd.S + $(COMPILE) -DF_$* $< -c -o $@ diff --git a/src/umd/pspumd.h b/src/umd/pspumd.h new file mode 100644 index 00000000..e21a6b52 --- /dev/null +++ b/src/umd/pspumd.h @@ -0,0 +1,216 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspumd.h - Prototypes for the sceUmd library. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: pspumd.h 2448 2008-12-11 21:45:37Z jim $ + */ +#ifndef __UMD_H__ +#define __UMD_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup UMD UMD Kernel Library */ +/*@{*/ + +/** UMD Info struct */ +typedef struct pspUmdInfo +{ + /** Set to sizeof(pspUmdInfo) */ + unsigned int size; + /** One or more of ::pspUmdTypes */ + unsigned int type; + +} pspUmdInfo; + +/** Enumeration for UMD types */ +enum pspUmdTypes +{ + PSP_UMD_TYPE_GAME = 0x10, + PSP_UMD_TYPE_VIDEO = 0x20, + PSP_UMD_TYPE_AUDIO = 0x40 +}; + +/** Enumeration for UMD drive state */ +enum pspUmdState +{ + PSP_UMD_NOT_PRESENT = 0x01, + PSP_UMD_PRESENT = 0x02, + PSP_UMD_CHANGED = 0x04, + PSP_UMD_INITING = 0x08, + PSP_UMD_INITED = 0x10, + PSP_UMD_READY = 0x20 +}; + +/** Enumeration for UMD stats (legacy) */ +enum UmdDriveStat +{ + /** Wait for disc to be inserted */ + UMD_WAITFORDISC = PSP_UMD_PRESENT, + /** Wait for the UMD to be initialised so it can be accessed from the mapped drive */ + UMD_WAITFORINIT = PSP_UMD_READY +}; + +/** UMD Callback function */ +typedef int (*UmdCallback)(int unknown, int event); + +/** + * Check whether there is a disc in the UMD drive + * + * @return 0 if no disc present, anything else indicates a disc is inserted. + */ +int sceUmdCheckMedium(void); + +/** + * Get the disc info + * + * @param info - A pointer to a ::pspUmdInfo struct + * + * @return < 0 on error + */ +int sceUmdGetDiscInfo(pspUmdInfo *info); + +/** + * Activates the UMD drive + * + * @param unit - The unit to initialise (probably). Should be set to 1. + * + * @param drive - A prefix string for the fs device to mount the UMD on (e.g. "disc0:") + * + * @return < 0 on error + * + * @par Example: + * @code + * // Wait for disc and mount to filesystem + * int i; + * i = sceUmdCheckMedium(); + * if(i == 0) + * { + * sceUmdWaitDriveStat(PSP_UMD_PRESENT); + * } + * sceUmdActivate(1, "disc0:"); // Mount UMD to disc0: file system + * sceUmdWaitDriveStat(PSP_UMD_READY); + * // Now you can access the UMD using standard sceIo functions + * @endcode + */ +int sceUmdActivate(int unit, const char *drive); + +/** + * Deativates the UMD drive + * + * @param unit - The unit to initialise (probably). Should be set to 1. + * + * @param drive - A prefix string for the fs device to mount the UMD on (e.g. "disc0:") + * + * @return < 0 on error + */ +int sceUmdDeactivate(int unit, const char *drive); + +/** + * Wait for the UMD drive to reach a certain state + * + * @param stat - One or more of ::pspUmdState + * + * @return < 0 on error + */ +int sceUmdWaitDriveStat(int stat); + +/** + * Wait for the UMD drive to reach a certain state + * + * @param stat - One or more of ::pspUmdState + * + * @param timeout - Timeout value in microseconds + * + * @return < 0 on error + */ +int sceUmdWaitDriveStatWithTimer(int stat, unsigned int timeout); + +/** + * Wait for the UMD drive to reach a certain state (plus callback) + * + * @param stat - One or more of ::pspUmdState + * + * @param timeout - Timeout value in microseconds + * + * @return < 0 on error + */ +int sceUmdWaitDriveStatCB(int stat, unsigned int timeout); + +/** + * Cancel a sceUmdWait* call + * + * @return < 0 on error + */ +int sceUmdCancelWaitDriveStat(void); + +/** + * Get (poll) the current state of the UMD drive + * + * @return < 0 on error, one or more of ::pspUmdState on success + */ +int sceUmdGetDriveStat(void); + +/** + * Get the error code associated with a failed event + * + * @return < 0 on error, the error code on success + */ +int sceUmdGetErrorStat(void); + +/** + * Register a callback for the UMD drive + * @note Callback is of type UmdCallback + * + * @param cbid - A callback ID created from sceKernelCreateCallback + * @return < 0 on error + * @par Example: + * @code + * int umd_callback(int unknown, int event) + * { + * //do something + * } + * int cbid = sceKernelCreateCallback("UMD Callback", umd_callback, NULL); + * sceUmdRegisterUMDCallBack(cbid); + * @endcode + */ +int sceUmdRegisterUMDCallBack(int cbid); + +/** + * Un-register a callback for the UMD drive + * + * @param cbid - A callback ID created from sceKernelCreateCallback + * + * @return < 0 on error + */ +int sceUmdUnRegisterUMDCallBack(int cbid); + +/** + * Permit UMD disc being replaced + * + * @return < 0 on error + */ +int sceUmdReplacePermit(void); + +/** + * Prohibit UMD disc being replaced + * + * @return < 0 on error + */ +int sceUmdReplaceProhibit(void); + +/*@}*/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/umd/sceUmd.S b/src/umd/sceUmd.S new file mode 100755 index 00000000..150e906c --- /dev/null +++ b/src/umd/sceUmd.S @@ -0,0 +1,112 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceUmd_0000 + IMPORT_START "sceUmd",0x00090000 +#endif +#ifdef F_sceUmd_0001 + IMPORT_FUNC "sceUmd",0x075F1E0B,sceUmd_075F1E0B +#endif +#ifdef F_sceUmd_0002 + IMPORT_FUNC "sceUmd",0x086DDC0D,sceUmd_086DDC0D +#endif +#ifdef F_sceUmd_0003 + IMPORT_FUNC "sceUmd",0x230666E3,sceUmdSetDriveStatus +#endif +#ifdef F_sceUmd_0004 + IMPORT_FUNC "sceUmd",0x27A764A1,sceUmd_27A764A1 +#endif +#ifdef F_sceUmd_0005 + IMPORT_FUNC "sceUmd",0x2D81508D,sceUmd_2D81508D +#endif +#ifdef F_sceUmd_0006 + IMPORT_FUNC "sceUmd",0x319ED97C,sceUmd_319ED97C +#endif +#ifdef F_sceUmd_0007 + IMPORT_FUNC "sceUmd",0x340B7686,sceUmdGetDiscInfo +#endif +#ifdef F_sceUmd_0008 + IMPORT_FUNC "sceUmd",0x3925CBD8,sceUmd_3925CBD8 +#endif +#ifdef F_sceUmd_0009 + IMPORT_FUNC "sceUmd",0x3D0DECD5,sceUmd_3D0DECD5 +#endif +#ifdef F_sceUmd_0010 + IMPORT_FUNC "sceUmd",0x46EBB729,sceUmdCheckMedium +#endif +#ifdef F_sceUmd_0011 + IMPORT_FUNC "sceUmd",0x4832ABF3,sceUmd_4832ABF3 +#endif +#ifdef F_sceUmd_0012 + IMPORT_FUNC "sceUmd",0x4A9E5E29,sceUmdWaitDriveStatCB +#endif +#ifdef F_sceUmd_0013 + IMPORT_FUNC "sceUmd",0x4BA25F4A,sceUmd_4BA25F4A +#endif +#ifdef F_sceUmd_0014 + IMPORT_FUNC "sceUmd",0x4C952ACF,sceUmdSetSuspendResumeMode +#endif +#ifdef F_sceUmd_0015 + IMPORT_FUNC "sceUmd",0x5469DC37,sceUmd_5469DC37 +#endif +#ifdef F_sceUmd_0016 + IMPORT_FUNC "sceUmd",0x56202973,sceUmdWaitDriveStatWithTimer +#endif +#ifdef F_sceUmd_0017 + IMPORT_FUNC "sceUmd",0x659587F7,sceUmd_659587F7 +#endif +#ifdef F_sceUmd_0018 + IMPORT_FUNC "sceUmd",0x6A41ED25,sceUmdGetSuspendResumeMode +#endif +#ifdef F_sceUmd_0019 + IMPORT_FUNC "sceUmd",0x6AF9B50A,sceUmd_6AF9B50A +#endif +#ifdef F_sceUmd_0020 + IMPORT_FUNC "sceUmd",0x71F81482,sceUmd_71F81482 +#endif +#ifdef F_sceUmd_0021 + IMPORT_FUNC "sceUmd",0x7850F057,sceUmd_7850F057 +#endif +#ifdef F_sceUmd_0022 + IMPORT_FUNC "sceUmd",0x87533940,sceUmdReplaceProhibit +#endif +#ifdef F_sceUmd_0023 + IMPORT_FUNC "sceUmd",0x8EF08FCE,sceUmdWaitDriveStat +#endif +#ifdef F_sceUmd_0024 + IMPORT_FUNC "sceUmd",0x9B22AED7,sceUmd_9B22AED7 +#endif +#ifdef F_sceUmd_0025 + IMPORT_FUNC "sceUmd",0xAE53DC2D,sceUmdClearDriveStatus +#endif +#ifdef F_sceUmd_0026 + IMPORT_FUNC "sceUmd",0xAEE7404D,sceUmdRegisterUMDCallBack +#endif +#ifdef F_sceUmd_0027 + IMPORT_FUNC "sceUmd",0xBBB5F05C,sceUmd_BBB5F05C +#endif +#ifdef F_sceUmd_0028 + IMPORT_FUNC "sceUmd",0xBD2BDE07,sceUmdUnRegisterUMDCallBack +#endif +#ifdef F_sceUmd_0029 + IMPORT_FUNC "sceUmd",0xC6183D47,sceUmdActivate +#endif +#ifdef F_sceUmd_0030 + IMPORT_FUNC "sceUmd",0xCBE9F02A,sceUmdReplacePermit +#endif +#ifdef F_sceUmd_0031 + IMPORT_FUNC "sceUmd",0xD01B2DC6,sceUmd_D01B2DC6 +#endif +#ifdef F_sceUmd_0032 + IMPORT_FUNC "sceUmd",0xD45D1FE6,sceUmdGetDriveStatus +#endif +#ifdef F_sceUmd_0033 + IMPORT_FUNC "sceUmd",0xE83742BA,sceUmdDeactivate +#endif +#ifdef F_sceUmd_0034 + IMPORT_FUNC "sceUmd",0xEB56097E,sceUmd_EB56097E +#endif +#ifdef F_sceUmd_0035 + IMPORT_FUNC "sceUmd",0xF8352373,sceUmd_F8352373 +#endif diff --git a/src/umd/sceUmdUser.S b/src/umd/sceUmdUser.S new file mode 100644 index 00000000..5b5cfc70 --- /dev/null +++ b/src/umd/sceUmdUser.S @@ -0,0 +1,52 @@ + .set noreorder + +#include "pspimport.s" + +// Build List +// sceUmdUser_0000.o sceUmdUser_0001.o sceUmdUser_0002.o sceUmdUser_0003.o sceUmdUser_0004.o sceUmdUser_0005.o sceUmdUser_0006.o sceUmdUser_0007.o sceUmdUser_0008.o sceUmdUser_0009.o sceUmdUser_0010.o sceUmdUser_0011.o sceUmdUser_0012.o sceUmdUser_0013.o sceUmdUser_0014.o + +#ifdef F_sceUmdUser_0000 + IMPORT_START "sceUmdUser",0x40010011 +#endif +#ifdef F_sceUmdUser_0001 + IMPORT_FUNC "sceUmdUser",0x20628E6F,sceUmdGetErrorStat +#endif +#ifdef F_sceUmdUser_0002 + IMPORT_FUNC "sceUmdUser",0x340B7686,sceUmdGetDiscInfo +#endif +#ifdef F_sceUmdUser_0003 + IMPORT_FUNC "sceUmdUser",0x46EBB729,sceUmdCheckMedium +#endif +#ifdef F_sceUmdUser_0004 + IMPORT_FUNC "sceUmdUser",0x4A9E5E29,sceUmdWaitDriveStatCB +#endif +#ifdef F_sceUmdUser_0005 + IMPORT_FUNC "sceUmdUser",0x56202973,sceUmdWaitDriveStatWithTimer +#endif +#ifdef F_sceUmdUser_0006 + IMPORT_FUNC "sceUmdUser",0x6AF9B50A,sceUmdCancelWaitDriveStat +#endif +#ifdef F_sceUmdUser_0007 + IMPORT_FUNC "sceUmdUser",0x6B4A146C,sceUmdGetDriveStat +#endif +#ifdef F_sceUmdUser_0008 + IMPORT_FUNC "sceUmdUser",0x87533940,sceUmdReplaceProhibit +#endif +#ifdef F_sceUmdUser_0009 + IMPORT_FUNC "sceUmdUser",0x8EF08FCE,sceUmdWaitDriveStat +#endif +#ifdef F_sceUmdUser_0010 + IMPORT_FUNC "sceUmdUser",0xAEE7404D,sceUmdRegisterUMDCallBack +#endif +#ifdef F_sceUmdUser_0011 + IMPORT_FUNC "sceUmdUser",0xBD2BDE07,sceUmdUnRegisterUMDCallBack +#endif +#ifdef F_sceUmdUser_0012 + IMPORT_FUNC "sceUmdUser",0xC6183D47,sceUmdActivate +#endif +#ifdef F_sceUmdUser_0013 + IMPORT_FUNC "sceUmdUser",0xCBE9F02A,sceUmdReplacePermit +#endif +#ifdef F_sceUmdUser_0014 + IMPORT_FUNC "sceUmdUser",0xE83742BA,sceUmdDeactivate +#endif diff --git a/src/usb/Makefile.am b/src/usb/Makefile.am new file mode 100644 index 00000000..96a6d882 --- /dev/null +++ b/src/usb/Makefile.am @@ -0,0 +1,51 @@ + +libdir = @PSPSDK_LIBDIR@ + +CC = @PSP_CC@ +CCAS = $(CC) +AR = @PSP_AR@ +RANLIB = @PSP_RANLIB@ + +INCLUDES = -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel +CFLAGS = @PSPSDK_CFLAGS@ +CCASFLAGS = $(CFLAGS) $(INCLUDES) + +USB_OBJS = sceUsb_0000.o sceUsb_0001.o sceUsb_0002.o sceUsb_0003.o sceUsb_0004.o sceUsb_0005.o sceUsb_0006.o sceUsb_0007.o sceUsb_0008.o sceUsb_0009.o + +USBDRIVER_OBJS= sceUsb_driver_0000.o sceUsb_driver_0001.o sceUsb_driver_0002.o sceUsb_driver_0003.o sceUsb_driver_0004.o sceUsb_driver_0005.o sceUsb_driver_0006.o sceUsb_driver_0007.o sceUsb_driver_0008.o sceUsb_driver_0009.o sceUsb_driver_0010.o + +USBBUSDRIVER_OBJS=sceUsbBus_driver_0000.o sceUsbBus_driver_0001.o sceUsbBus_driver_0002.o sceUsbBus_driver_0003.o sceUsbBus_driver_0004.o sceUsbBus_driver_0005.o sceUsbBus_driver_0006.o sceUsbBus_driver_0007.o sceUsbBus_driver_0008.o sceUsbBus_driver_0009.o + +USBCAM_OBJS = sceUsbCam_0000.o sceUsbCam_0001.o sceUsbCam_0002.o sceUsbCam_0003.o sceUsbCam_0004.o sceUsbCam_0005.o sceUsbCam_0006.o sceUsbCam_0007.o sceUsbCam_0008.o sceUsbCam_0009.o sceUsbCam_0010.o sceUsbCam_0011.o sceUsbCam_0012.o sceUsbCam_0013.o sceUsbCam_0014.o sceUsbCam_0015.o sceUsbCam_0016.o sceUsbCam_0017.o sceUsbCam_0018.o sceUsbCam_0019.o sceUsbCam_0020.o sceUsbCam_0021.o sceUsbCam_0022.o sceUsbCam_0023.o sceUsbCam_0024.o sceUsbCam_0025.o sceUsbCam_0026.o sceUsbCam_0027.o sceUsbCam_0028.o sceUsbCam_0029.o sceUsbCam_0030.o sceUsbCam_0031.o sceUsbCam_0032.o sceUsbCam_0033.o sceUsbCam_0034.o sceUsbCam_0035.o sceUsbCam_0036.o sceUsbCam_0037.o sceUsbCam_0038.o sceUsbCam_0039.o sceUsbCam_0040.o sceUsbCam_0041.o sceUsbCam_0042.o sceUsbCam_0043.o sceUsbCam_0044.o sceUsbCam_0045.o sceUsbCam_0046.o sceUsbCam_0047.o sceUsbCam_0048.o sceUsbCam_0049.o sceUsbCam_0050.o sceUsbCam_0051.o sceUsbCam_0052.o sceUsbCam_0053.o sceUsbCam_0054.o + + +libpspusbincludedir = @PSPSDK_INCLUDEDIR@ + +libpspusbinclude_HEADERS = \ + pspusb.h pspusbbus.h pspusbcam.h pspusbacc.h + +lib_LIBRARIES = libpspusb.a libpspusb_driver.a libpspusbbus_driver.a libpspusbcam.a + +libpspusb_a_SOURCES = sceUsb.S +libpspusb_a_LIBADD = $(USB_OBJS) + +libpspusb_driver_a_SOURCES = sceUsb_driver.S +libpspusb_driver_a_LIBADD = $(USBDRIVER_OBJS) + +libpspusbbus_driver_a_SOURCES = sceUsbBus_driver.S +libpspusbbus_driver_a_LIBADD = $(USBBUSDRIVER_OBJS) + +libpspusbcam_a_SOURCES = sceUsbCam.S +libpspusbcam_a_LIBADD = $(USBCAM_OBJS) + +$(USB_OBJS): sceUsb.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(USBDRIVER_OBJS): sceUsb_driver.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(USBBUSDRIVER_OBJS): sceUsbBus_driver.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(USBCAM_OBJS): sceUsbCam.S + $(COMPILE) -DF_$* $< -c -o $@ diff --git a/src/usb/pspusb.h b/src/usb/pspusb.h new file mode 100644 index 00000000..bd8ca3c2 --- /dev/null +++ b/src/usb/pspusb.h @@ -0,0 +1,92 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspusb.h - Prototypes for the sceUsb library + * + * Copyright (c) 2005 John Kelley + * + * $Id: pspusb.h 2087 2006-12-04 07:08:01Z loser $ + */ +#ifndef __PSPUSB_H__ +#define __PSPUSB_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define PSP_USBBUS_DRIVERNAME "USBBusDriver" + +//Defines for use with status function return values +#define PSP_USB_ACTIVATED 0x200 +#define PSP_USB_CABLE_CONNECTED 0x020 +#define PSP_USB_CONNECTION_ESTABLISHED 0x002 + +/** + * Start a USB driver. + * + * @param driverName - name of the USB driver to start + * @param size - Size of arguments to pass to USB driver start + * @param args - Arguments to pass to USB driver start + * + * @return 0 on success + */ +int sceUsbStart(const char* driverName, int size, void *args); + +/** + * Stop a USB driver. + * + * @param driverName - name of the USB driver to stop + * @param size - Size of arguments to pass to USB driver start + * @param args - Arguments to pass to USB driver start + * + * @return 0 on success + */ +int sceUsbStop(const char* driverName, int size, void *args); + +/** + * Activate a USB driver. + * + * @param pid - Product ID for the default USB Driver + * + * @return 0 on success + */ +int sceUsbActivate(u32 pid); + +/** + * Deactivate USB driver. + * + * @param pid - Product ID for the default USB driver + * + * @return 0 on success + */ +int sceUsbDeactivate(u32 pid); + +/** + * Get USB state + * + * @return OR'd PSP_USB_* constants + */ +int sceUsbGetState(void); + +/** + * Get state of a specific USB driver + * + * @param driverName - name of USB driver to get status from + * + * @return 1 if the driver has been started, 2 if it is stopped + */ +int sceUsbGetDrvState(const char* driverName); + +#if 0 +int sceUsbGetDrvList(u32 r4one, u32* r5ret, u32 r6one); +int sceUsbWaitState(u32 state, s32 waitmode, u32 *timeout); +int sceUsbWaitCancel(void); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/usb/pspusbacc.h b/src/usb/pspusbacc.h new file mode 100755 index 00000000..e6ce9ce1 --- /dev/null +++ b/src/usb/pspusbacc.h @@ -0,0 +1,26 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspusbacc.h - Prototypes for the sceUsbAcc library + * + * Copyright (c) 2007 dot_blank + * + * $Id: pspusbacc.h 2342 2007-12-06 21:49:26Z raphael $ + */ +#ifndef __PSPUSBACC_H__ +#define __PSPUSBACC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define PSP_USBACC_DRIVERNAME "USBAccBaseDriver" + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/src/usb/pspusbbus.h b/src/usb/pspusbbus.h new file mode 100644 index 00000000..2c6ad6e3 --- /dev/null +++ b/src/usb/pspusbbus.h @@ -0,0 +1,308 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspusbbus.h - Prototypes for the sceUsbBus_driver library + * + * Copyright (c) 2006 James F + * + * $Id: pspusbbus.h 2219 2007-04-18 19:08:48Z chip $ + */ +#ifndef __PSPUSBBUS_H__ +#define __PSPUSBBUS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** USB driver interface */ +struct UsbInterface +{ + /** Expectant interface (0 or -1) */ + int expect_interface; + /** Unknown */ + int unk8; + /** Number of interfaces */ + int num_interface; +}; + +/** USB driver endpoint */ +struct UsbEndpoint +{ + /** Endpoint number (must be filled in sequentially) */ + int endpnum; + /** Filled in by the bus driver */ + int unk2; + /** Filled in by the bus driver */ + int unk3; +}; + +/** USB string descriptor */ +struct StringDescriptor +{ + unsigned char bLength; + unsigned char bDescriptorType; + short bString[32]; +} __attribute__((packed)); + +/** USB device descriptor */ +struct DeviceDescriptor +{ + unsigned char bLength; + unsigned char bDescriptorType; + unsigned short bcdUSB; + unsigned char bDeviceClass; + unsigned char bDeviceSubClass; + unsigned char bDeviceProtocol; + unsigned char bMaxPacketSize; + unsigned short idVendor; + unsigned short idProduct; + unsigned short bcdDevice; + unsigned char iManufacturer; + unsigned char iProduct; + unsigned char iSerialNumber; + unsigned char bNumConfigurations; +} __attribute__((packed)); + +/** USB configuration descriptor */ +struct ConfigDescriptor +{ + unsigned char bLength; + unsigned char bDescriptorType; + unsigned short wTotalLength; + unsigned char bNumInterfaces; + unsigned char bConfigurationValue; + unsigned char iConfiguration; + unsigned char bmAttributes; + unsigned char bMaxPower; +} __attribute__((packed)); + +/** USB Interface descriptor */ +struct InterfaceDescriptor +{ + unsigned char bLength; + unsigned char bDescriptorType; + unsigned char bInterfaceNumber; + unsigned char bAlternateSetting; + unsigned char bNumEndpoints; + unsigned char bInterfaceClass; + unsigned char bInterfaceSubClass; + unsigned char bInterfaceProtocol; + unsigned char iInterface; +} __attribute__((packed)); + +/** USB endpoint descriptor */ +struct EndpointDescriptor +{ + unsigned char bLength; + unsigned char bDescriptorType; + unsigned char bEndpointAddress; + unsigned char bmAttributes; + unsigned short wMaxPacketSize; + unsigned char bInterval; +} __attribute__((packed)); + +/** USB driver interfaces structure */ +struct UsbInterfaces +{ + /** Pointers to the individual interface descriptors */ + struct InterfaceDescriptor *infp[2]; + /** Number of interface descriptors */ + unsigned int num; +}; + +/** USB driver configuration */ +struct UsbConfiguration +{ + /** Pointer to the configuration descriptors */ + struct ConfigDescriptor *confp; + /** USB driver interfaces pointer */ + struct UsbInterfaces *infs; + /** Pointer to the first interface descriptor */ + struct InterfaceDescriptor *infp; + /** Pointer to the first endpoint descriptor (each should be 16byte aligned) */ + struct EndpointDescriptor *endp; +}; + +/** Padded data structure, padding is required otherwise the USB hardware crashes */ +struct UsbData +{ + unsigned char devdesc[20]; + + struct Config + { + void *pconfdesc; + void *pinterfaces; + void *pinterdesc; + void *pendp; + } config; + + struct ConfDesc + { + unsigned char desc[12]; + void *pinterfaces; + } confdesc; + + unsigned char pad1[8]; + struct Interfaces + { + void *pinterdesc[2]; + unsigned int intcount; + } interfaces; + + struct InterDesc + { + unsigned char desc[12]; + void *pendp; + unsigned char pad[32]; + } interdesc; + + struct Endp + { + unsigned char desc[16]; + } endp[4]; +} __attribute__((packed)); + +/** USB EP0 Device Request */ +struct DeviceRequest +{ + unsigned char bmRequestType; + unsigned char bRequest; + unsigned short wValue; + unsigned short wIndex; + unsigned short wLength; +} __attribute__((packed)); + +/** USB driver structure used by ::sceUsbbdRegisterDriver and ::sceUsbbdUnregisterDriver */ +struct UsbDriver +{ + /** Name of the USB driver */ + const char *name; + /** Number of endpoints in this driver (including default control) */ + int endpoints; + /** List of endpoint structures (used when calling other functions) */ + struct UsbEndpoint *endp; + /** Interface list */ + struct UsbInterface *intp; + /** Pointer to hi-speed device descriptor */ + void *devp_hi; + /** Pointer to hi-speed device configuration */ + void *confp_hi; + /** Pointer to full-speed device descriptor */ + void *devp; + /** Pointer to full-speed device configuration */ + void *confp; + /** Default String descriptor */ + struct StringDescriptor *str; + /** Received a control request arg0 is endpoint, arg1 is possibly data arg2 is data buffer */ + int (*recvctl)(int arg1, int arg2, struct DeviceRequest *req); + /** Unknown */ + int (*func28)(int arg1, int arg2, int arg3); + /** Configuration set (attach) function */ + int (*attach)(int speed, void *arg2, void *arg3); + /** Configuration unset (detach) function */ + int (*detach)(int arg1, int arg2, int arg3); + /** Unknown set to 0 */ + int unk34; + /** Function called when the driver is started */ + int (*start_func)(int size, void *args); + /** Function called when the driver is stopped */ + int (*stop_func)(int size, void *args); + /** Link to next USB driver in the chain, set to NULL */ + struct UsbDriver *link; +}; + +/** USB device request, used by ::sceUsbbdReqSend and ::sceUsbbdReqRecv. */ +struct UsbdDeviceReq +{ + /** Pointer to the endpoint to queue request on */ + struct UsbEndpoint *endp; + /** Pointer to the data buffer to use in the request */ + void *data; + /** Size of the data buffer (send == size of data, recv == size of max receive) */ + int size; + /** Unknown */ + int unkc; + /** Pointer to the function to call on completion */ + void *func; + /** Resultant size (send == size of data sent, recv == size of data received) */ + int recvsize; + /** Return code of the request, 0 == success, -3 == cancelled */ + int retcode; + /** Unknown */ + int unk1c; + /** A user specified pointer for the device request */ + void *arg; + /** Link pointer to next request used by the driver, set it to NULL */ + void *link; +}; + +/** + * Register a USB driver. + * + * @param drv - Pointer to a filled out USB driver + * + * @return 0 on success, < 0 on error + */ +int sceUsbbdRegister(struct UsbDriver *drv); + +/** + * Unregister a USB driver + * + * @param drv - Pointer to a filled out USB driver + * + * @return 0 on success, < 0 on error + */ +int sceUsbbdUnregister(struct UsbDriver *drv); + +/** + * Clear the FIFO on an endpoint + * + * @param endp - The endpoint to clear + * + * @return 0 on success, < 0 on error + */ +int sceUsbbdClearFIFO(struct UsbEndpoint *endp); + +/** + * Cancel any pending requests on an endpoint. + * + * @param endp - The endpoint to cancel + * + * @return 0 on success, < 0 on error + */ +int sceUsbbdReqCancelAll(struct UsbEndpoint *endp); + +/** + * Stall an endpoint + * + * @param endp - The endpoint to stall + * + * @return 0 on success, < 0 on error + */ +int sceUsbbdStall(struct UsbEndpoint *endp); + +/** + * Queue a send request (IN from host pov) + * + * @param req - Pointer to a filled out UsbdDeviceReq structure. + * + * @return 0 on success, < 0 on error + */ +int sceUsbbdReqSend(struct UsbdDeviceReq *req); + +/** + * Queue a receive request (OUT from host pov) + * + * @param req - Pointer to a filled out UsbdDeviceReq structure + * + * @return 0 on success, < 0 on error + */ +int sceUsbbdReqRecv(struct UsbdDeviceReq *req); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/usb/pspusbcam.h b/src/usb/pspusbcam.h new file mode 100755 index 00000000..86c5fc90 --- /dev/null +++ b/src/usb/pspusbcam.h @@ -0,0 +1,576 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspusbcam.h - Prototypes for the sceUsbCam library + * + * Copyright (c) 2007 dot_blank + * + * $Id: pspusbcam.h 2433 2008-10-15 10:00:27Z iwn $ + */ +#ifndef __PSPUSBCAM_H__ +#define __PSPUSBCAM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define PSP_USBCAM_PID (0x282) +#define PSP_USBCAM_DRIVERNAME "USBCamDriver" +#define PSP_USBCAMMIC_DRIVERNAME "USBCamMicDriver" + +/** Resolutions for sceUsbCamSetupStill & + sceUsbCamSetupVideo + ** DO NOT use on sceUsbCamSetupStillEx & sceUsbCamSetupVideoEx */ +enum PspUsbCamResolution +{ + PSP_USBCAM_RESOLUTION_160_120 = 0, + PSP_USBCAM_RESOLUTION_176_144 = 1, + PSP_USBCAM_RESOLUTION_320_240 = 2, + PSP_USBCAM_RESOLUTION_352_288 = 3, + PSP_USBCAM_RESOLUTION_640_480 = 4, + PSP_USBCAM_RESOLUTION_1024_768 = 5, + PSP_USBCAM_RESOLUTION_1280_960 = 6, + PSP_USBCAM_RESOLUTION_480_272 = 7, + PSP_USBCAM_RESOLUTION_360_272 = 8, +}; + +/** Resolutions for sceUsbCamSetupStillEx & + sceUsbCamSetupVideoEx + ** DO NOT use on sceUsbCamSetupStill & sceUsbCamSetupVideo */ +enum PspUsbCamResolutionEx +{ + PSP_USBCAM_RESOLUTION_EX_160_120 = 0, + PSP_USBCAM_RESOLUTION_EX_176_144 = 1, + PSP_USBCAM_RESOLUTION_EX_320_240 = 2, + PSP_USBCAM_RESOLUTION_EX_352_288 = 3, + PSP_USBCAM_RESOLUTION_EX_360_272 = 4, + PSP_USBCAM_RESOLUTION_EX_480_272 = 5, + PSP_USBCAM_RESOLUTION_EX_640_480 = 6, + PSP_USBCAM_RESOLUTION_EX_1024_768 = 7, + PSP_USBCAM_RESOLUTION_EX_1280_960 = 8, +}; + +/** Flags for reverse effects. */ +enum PspUsbCamReverseFlags +{ + PSP_USBCAM_FLIP = 1, + PSP_USBCAM_MIRROR = 0x100, +}; + +/** Delay to take pictures */ +enum PspUsbCamDelay +{ + PSP_USBCAM_NODELAY = 0, + PSP_USBCAM_DELAY_10SEC = 1, + PSP_USBCAM_DELAY_20SEC = 2, + PSP_USBCAM_DELAY_30SEC = 3, +}; + +/** Usbcam framerates */ +enum PspUsbCamFrameRate +{ + PSP_USBCAM_FRAMERATE_3_75_FPS = 0, /* 3.75 fps */ + PSP_USBCAM_FRAMERATE_5_FPS = 1, + PSP_USBCAM_FRAMERATE_7_5_FPS = 2, /* 7.5 fps */ + PSP_USBCAM_FRAMERATE_10_FPS = 3, + PSP_USBCAM_FRAMERATE_15_FPS = 4, + PSP_USBCAM_FRAMERATE_20_FPS = 5, + PSP_USBCAM_FRAMERATE_30_FPS = 6, + PSP_USBCAM_FRAMERATE_60_FPS = 7, +}; + +/** White balance values */ +enum PspUsbCamWB +{ + PSP_USBCAM_WB_AUTO = 0, + PSP_USBCAM_WB_DAYLIGHT = 1, + PSP_USBCAM_WB_FLUORESCENT = 2, + PSP_USBCAM_WB_INCADESCENT = 3, +}; + +/** Effect modes */ +enum PspUsbCamEffectMode +{ + PSP_USBCAM_EFFECTMODE_NORMAL = 0, + PSP_USBCAM_EFFECTMODE_NEGATIVE = 1, + PSP_USBCAM_EFFECTMODE_BLACKWHITE = 2, + PSP_USBCAM_EFFECTMODE_SEPIA = 3, + PSP_USBCAM_EFFECTMODE_BLUE = 4, + PSP_USBCAM_EFFECTMODE_RED = 5, + PSP_USBCAM_EFFECTMODE_GREEN = 6, +}; + +/** Exposure levels */ +enum PspUsbCamEVLevel +{ + PSP_USBCAM_EVLEVEL_2_0_POSITIVE = 0, // +2.0 + PSP_USBCAM_EVLEVEL_1_7_POSITIVE = 1, // +1.7 + PSP_USBCAM_EVLEVEL_1_5_POSITIVE = 2, // +1.5 + PSP_USBCAM_EVLEVEL_1_3_POSITIVE = 3, // +1.3 + PSP_USBCAM_EVLEVEL_1_0_POSITIVE = 4, // +1.0 + PSP_USBCAM_EVLEVEL_0_7_POSITIVE = 5, // +0.7 + PSP_USBCAM_EVLEVEL_0_5_POSITIVE = 6, // +0.5 + PSP_USBCAM_EVLEVEL_0_3_POSITIVE = 7, // +0.3 + PSP_USBCAM_EVLEVEL_0_0 = 8, // 0.0 + PSP_USBCAM_EVLEVEL_0_3_NEGATIVE = 9, // -0.3 + PSP_USBCAM_EVLEVEL_0_5_NEGATIVE = 10, // -0.5 + PSP_USBCAM_EVLEVEL_0_7_NEGATIVE = 11, // -0.7 + PSP_USBCAM_EVLEVEL_1_0_NEGATIVE = 12, // -1.0 + PSP_USBCAM_EVLEVEL_1_3_NEGATIVE = 13, // -1.3 + PSP_USBCAM_EVLEVEL_1_5_NEGATIVE = 14, // -1.5 + PSP_USBCAM_EVLEVEL_1_7_NEGATIVE = 15, // -1.7 + PSP_USBCAM_EVLEVEL_2_0_NEGATIVE = 16, // -2.0 +}; + + + +/** Structure for sceUsbCamSetupStill */ +typedef struct PspUsbCamSetupStillParam { +/** Size of the ::PspUsbCamSetupStillParam structure */ + int size; +/** Resolution. One of ::PspUsbCamResolution */ + int resolution; +/** Size of the jpeg image */ + int jpegsize; +/** Reverse effect to apply. Zero or more of ::PspUsbCamReverseFlags */ + int reverseflags; +/** Delay to apply to take the picture. One of ::PspUsbCamDelay */ + int delay; +/** JPEG compression level, a value from 1-63. + 1 -> less compression, better quality; 63 -> max compression, worse quality */ + int complevel; +} PspUsbCamSetupStillParam; + +/** Structure for sceUsbCamSetupStillEx */ +typedef struct PspUsbCamSetupStillExParam { +/** Size of the ::PspUsbCamSetupStillExParam structure */ + int size; +/** Unknown, set it to 9 at the moment. */ + u32 unk; +/** Resolution. One of ::PspUsbCamResolutionEx */ + int resolution; +/** Size of the jpeg image */ + int jpegsize; +/** JPEG compression level, a value from 1-63. + 1 -> less compression, better quality; 63 -> max compression, worse quality */ + int complevel; +/** Unknown, set it to 0 at the moment */ + u32 unk2; +/** Unknown, set it to 1 at the moment */ + u32 unk3; +/** Flag that indicates whether to flip the image */ + int flip; +/** Flag that indicates whether to mirror the image */ + int mirror; +/** Delay to apply to take the picture. One of ::PspUsbCamDelay */ + int delay; +/** Unknown, set it to 0 at the moment */ + u32 unk4[5]; +} PspUsbCamSetupStillExParam; + +typedef struct PspUsbCamSetupVideoParam { +/** Size of the ::PspUsbCamSetupVideoParam structure */ + int size; +/** Resolution. One of ::PspUsbCamResolution */ + int resolution; +/** Framerate. One of ::PspUsbCamFrameRate */ + int framerate; +/** White balance. One of ::PspUsbCamWB */ + int wb; +/** Saturarion (0-255) */ + int saturation; +/** Brightness (0-255) */ + int brightness; +/** Contrast (0-255) */ + int contrast; +/** Sharpness (0-255) */ + int sharpness; +/** Effect mode. One of ::PspUsbCamEffectMode */ + int effectmode; +/** Size of jpeg video frame */ + int framesize; +/** Unknown. Set it to 0 at the moment. */ + u32 unk; +/** Exposure value. One of ::PspUsbCamEVLevel */ + int evlevel; +} PspUsbCamSetupVideoParam; + +typedef struct PspUsbCamSetupVideoExParam { +/** Size of the ::PspUsbCamSetupVideoParam structure */ + int size; +/* Unknown. Set it to 9 at the moment. */ + u32 unk; +/** Resolution. One of ::PspUsbCamResolutionEx */ + int resolution; +/** Framerate. One of ::PspUsbCamFrameRate */ + int framerate; +/** Unknown. Set it to 2 at the moment */ + u32 unk2; +/** Unknown. Set it to 3 at the moment */ + u32 unk3; +/** White balance. One of ::PspUsbCamWB */ + int wb; +/** Saturarion (0-255) */ + int saturation; +/** Brightness (0-255) */ + int brightness; +/** Contrast (0-255) */ + int contrast; +/** Sharpness (0-255) */ + int sharpness; +/** Unknown. Set it to 0 at the moment */ + u32 unk4; +/** Unknown. Set it to 1 at the moment */ + u32 unk5; +/** Unknown. Set it to 0 at the moment */ + u32 unk6[3]; +/** Effect mode. One of ::PspUsbCamEffectMode */ + int effectmode; +/** Unknown. Set it to 1 at the moment */ + u32 unk7; +/** Unknown. Set it to 10 at the moment */ + u32 unk8; +/** Unknown. Set it to 2 at the moment */ + u32 unk9; +/** Unknown. Set it to 500 at the moment */ + u32 unk10; +/** Unknown. Set it to 1000 at the moment */ + u32 unk11; +/** Size of jpeg video frame */ + int framesize; +/** Unknown. Set it to 0 at the moment */ + u32 unk12; +/** Exposure value. One of ::PspUsbCamEVLevel */ + int evlevel; +} PspUsbCamSetupVideoExParam; + +/** + * Setups the parameters to take a still image. + * + * @param param - pointer to a ::PspUsbCamSetupStillParam + * + * @return 0 on success, < 0 on error +*/ +int sceUsbCamSetupStill(PspUsbCamSetupStillParam *param); + +/** + * Setups the parameters to take a still image (with more options) + * + * @param param - pointer to a ::PspUsbCamSetupStillParamEx + * + * @return 0 on success, < 0 on error +*/ +int sceUsbCamSetupStillEx(PspUsbCamSetupStillExParam *param); + +/** + * Gets a still image. The function doesn't return until the image + * has been acquired. + * + * @param buf - The buffer that receives the image jpeg data + * @param size - The size of the buffer. + * + * @return size of acquired image on success, < 0 on error +*/ +int sceUsbCamStillInputBlocking(u8 *buf, SceSize size); + +/** + * Gets a still image. The function returns inmediately, and + * the completion has to be handled by calling ::sceUsbCamStillWaitInputEnd + * or ::sceUsbCamStillPollInputEnd. + * + * @param buf - The buffer that receives the image jpeg data + * @param size - The size of the buffer. + * + * @return 0 on success, < 0 on error +*/ +int sceUsbCamStillInput(u8 *buf, SceSize size); + +/** + * Waits untils still input has been finished. + * + * @return the size of the acquired image on sucess, < 0 on error +*/ +int sceUsbCamStillWaitInputEnd(void); + +/** + * Polls the status of still input completion. + * + * @return the size of the acquired image if still input has ended, + * 0 if the input has not ended, < 0 on error. +*/ +int sceUsbCamStillPollInputEnd(void); + +/** + * Cancels the still input. + * + * @return 0 on success, < 0 on error +*/ +int sceUsbCamStillCancelInput(void); + +/** + * Gets the size of the acquired still image. + * + * @return the size of the acquired image on success, < 0 on error +*/ +int sceUsbCamStillGetInputLength(void); + +/** + * Set ups the parameters for video capture. + * + * @param param - Pointer to a ::PspUsbCamSetupVideoParam structure. + * @param workarea - Pointer to a buffer used as work area by the driver. + * @param wasize - Size of the work area. + * + * @return 0 on success, < 0 on error +*/ +int sceUsbCamSetupVideo(PspUsbCamSetupVideoParam *param, void *workarea, int wasize); + +/** + * Set ups the parameters for video capture (with more options) + * + * @param param - Pointer to a ::PspUsbCamSetupVideoExParam structure. + * @param workarea - Pointer to a buffer used as work area by the driver. + * @param wasize - Size of the work area. + * + * @return 0 on success, < 0 on error +*/ +int sceUsbCamSetupVideoEx(PspUsbCamSetupVideoExParam *param, void *workarea, int wasize); + +/** + * Starts video input from the camera. + * + * @return 0 on success, < 0 on error +*/ +int sceUsbCamStartVideo(void); + +/** + * Stops video input from the camera. + * + * @return 0 on success, < 0 on error +*/ +int sceUsbCamStopVideo(void); + +/** + * Reads a video frame. The function doesn't return until the frame + * has been acquired. + * + * @param buf - The buffer that receives the frame jpeg data + * @param size - The size of the buffer. + * + * @return size of acquired frame on success, < 0 on error +*/ +int sceUsbCamReadVideoFrameBlocking(u8 *buf, SceSize size); + +/** + * Reads a video frame. The function returns inmediately, and + * the completion has to be handled by calling ::sceUsbCamWaitReadVideoFrameEnd + * or ::sceUsbCamPollReadVideoFrameEnd. + * + * @param buf - The buffer that receives the frame jpeg data + * @param size - The size of the buffer. + * + * @return 0 on success, < 0 on error +*/ +int sceUsbCamReadVideoFrame(u8 *buf, SceSize size); + +/** + * Waits untils the current frame has been read. + * + * @return the size of the acquired frame on sucess, < 0 on error +*/ +int sceUsbCamWaitReadVideoFrameEnd(void); + +/** + * Polls the status of video frame read completion. + * + * @return the size of the acquired frame if it has been read, + * 0 if the frame has not yet been read, < 0 on error. +*/ +int sceUsbCamPollReadVideoFrameEnd(void); + +/** + * Gets the size of the acquired frame. + * + * @return the size of the acquired frame on success, < 0 on error +*/ +int sceUsbCamGetReadVideoFrameSize(void); + +/** + * Sets the saturation + * + * @param saturation - The saturation (0-255) + * + * @return 0 on success, < 0 on error +*/ +int sceUsbCamSetSaturation(int saturation); + +/** + * Sets the brightness + * + * @param brightness - The brightness (0-255) + * + * @return 0 on success, < 0 on error +*/ +int sceUsbCamSetBrightness(int brightness); + +/** + * Sets the contrast + * + * @param contrast - The contrast (0-255) + * + * @return 0 on success, < 0 on error +*/ +int sceUsbCamSetContrast(int contrast); + +/** + * Sets the sharpness + * + * @param sharpness - The sharpness (0-255) + * + * @return 0 on success, < 0 on error +*/ +int sceUsbCamSetSharpness(int sharpness); + +/** + * Sets the image effect mode + * + * @param effectmode - The effect mode, one of ::PspUsbCamEffectMode + * + * @return 0 on success, < 0 on error +*/ +int sceUsbCamSetImageEffectMode(int effectmode); + +/** + * Sets the exposure level + * + * @param ev - The exposure level, one of ::PspUsbCamEVLevel + * + * @return 0 on success, < 0 on error +*/ +int sceUsbCamSetEvLevel(int ev); + +/** + * Sets the reverse mode + * + * @param reverseflags - The reverse flags, zero or more of ::PspUsbCamReverseFlags + * + * @return 0 on success, < 0 on error +*/ +int sceUsbCamSetReverseMode(int reverseflags); + +/** + * Sets the zoom. + * + * @param zoom - The zoom level starting by 10. (10 = 1X, 11 = 1.1X, etc) + * + * @returns 0 on success, < 0 on error +*/ +int sceUsbCamSetZoom(int zoom); + +/** + * Gets the current saturation + * + * @param saturation - pointer to a variable that receives the current saturation + * + * @return 0 on success, < 0 on error +*/ +int sceUsbCamGetSaturation(int *saturation); + +/** + * Gets the current brightness + * + * @param brightness - pointer to a variable that receives the current brightness + * + * @return 0 on success, < 0 on error +*/ +int sceUsbCamGetBrightness(int *brightness); + +/** + * Gets the current contrast + * + * @param contrast - pointer to a variable that receives the current contrast + * + * @return 0 on success, < 0 on error +*/ +int sceUsbCamGetContrast(int *contrast); + +/** + * Gets the current sharpness + * + * @param brightness - pointer to a variable that receives the current sharpness + * + * @return 0 on success, < 0 on error +*/ +int sceUsbCamGetSharpness(int *sharpness); + +/** + * Gets the current image efect mode + * + * @param effectmode - pointer to a variable that receives the current effect mode + * + * @return 0 on success, < 0 on error +*/ +int sceUsbCamGetImageEffectMode(int *effectmode); + +/** + * Gets the current exposure level. + * + * @param ev - pointer to a variable that receives the current exposure level + * + * @return 0 on success, < 0 on error +*/ +int sceUsbCamGetEvLevel(int *ev); + +/** + * Gets the current reverse mode. + * + * @param reverseflags - pointer to a variable that receives the current reverse mode flags + * + * @return 0 on success, < 0 on error +*/ +int sceUsbCamGetReverseMode(int *reverseflags); + +/** + * Gets the current zoom. + * + * @param zoom - pointer to a variable that receives the current zoom + * + * @return 0 on success, < 0 on error +*/ +int sceUsbCamGetZoom(int *zoom); + +/** + * Sets if the image should be automatically reversed, depending of the position + * of the camera. + * + * @param on - 1 to set the automatical reversal of the image, 0 to set it off + * + * @return 0 on success, < 0 on error +*/ +int sceUsbCamAutoImageReverseSW(int on); + +/** + * Gets the state of the autoreversal of the image. + * + * @return 1 if it is set to automatic, 0 otherwise +*/ +int sceUsbCamGetAutoImageReverseState(void); + +/** + * Gets the direction of the camera lens + * + * @return 1 if the camera is "looking to you", 0 if the camera + * is "looking to the other side". +*/ +int sceUsbCamGetLensDirection(void); + +#ifdef __cplusplus +} +#endif + +#endif + + + diff --git a/src/usb/sceUsb.S b/src/usb/sceUsb.S new file mode 100644 index 00000000..215dd48d --- /dev/null +++ b/src/usb/sceUsb.S @@ -0,0 +1,34 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceUsb_0000 + IMPORT_START "sceUsb",0x40010000 +#endif +#ifdef F_sceUsb_0001 + IMPORT_FUNC "sceUsb",0xAE5DE6AF,sceUsbStart +#endif +#ifdef F_sceUsb_0002 + IMPORT_FUNC "sceUsb",0xC2464FA0,sceUsbStop +#endif +#ifdef F_sceUsb_0003 + IMPORT_FUNC "sceUsb",0xC21645A4,sceUsbGetState +#endif +#ifdef F_sceUsb_0004 + IMPORT_FUNC "sceUsb",0x4E537366,sceUsbGetDrvList +#endif +#ifdef F_sceUsb_0005 + IMPORT_FUNC "sceUsb",0x112CC951,sceUsbGetDrvState +#endif +#ifdef F_sceUsb_0006 + IMPORT_FUNC "sceUsb",0x586DB82C,sceUsbActivate +#endif +#ifdef F_sceUsb_0007 + IMPORT_FUNC "sceUsb",0xC572A9C8,sceUsbDeactivate +#endif +#ifdef F_sceUsb_0008 + IMPORT_FUNC "sceUsb",0x5BE0E002,sceUsbWaitState +#endif +#ifdef F_sceUsb_0009 + IMPORT_FUNC "sceUsb",0x1C360735,sceUsbWaitCancel +#endif diff --git a/src/usb/sceUsbBus_driver.S b/src/usb/sceUsbBus_driver.S new file mode 100644 index 00000000..3288bfb6 --- /dev/null +++ b/src/usb/sceUsbBus_driver.S @@ -0,0 +1,34 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceUsbBus_driver_0000 + IMPORT_START "sceUsbBus_driver",0x00010000 +#endif +#ifdef F_sceUsbBus_driver_0001 + IMPORT_FUNC "sceUsbBus_driver",0xC21645A4,sceUsbGetState +#endif +#ifdef F_sceUsbBus_driver_0002 + IMPORT_FUNC "sceUsbBus_driver",0xB1644BE7,sceUsbbdRegister +#endif +#ifdef F_sceUsbBus_driver_0003 + IMPORT_FUNC "sceUsbBus_driver",0xC1E2A540,sceUsbbdUnregister +#endif +#ifdef F_sceUsbBus_driver_0004 + IMPORT_FUNC "sceUsbBus_driver",0x951A24CC,sceUsbbdClearFIFO +#endif +#ifdef F_sceUsbBus_driver_0005 + IMPORT_FUNC "sceUsbBus_driver",0xE65441C1,sceUsbbdStall +#endif +#ifdef F_sceUsbBus_driver_0006 + IMPORT_FUNC "sceUsbBus_driver",0x23E51D8F,sceUsbbdReqSend +#endif +#ifdef F_sceUsbBus_driver_0007 + IMPORT_FUNC "sceUsbBus_driver",0x913EC15D,sceUsbbdReqRecv +#endif +#ifdef F_sceUsbBus_driver_0008 + IMPORT_FUNC "sceUsbBus_driver",0xCC57EC9D,sceUsbbdReqCancel +#endif +#ifdef F_sceUsbBus_driver_0009 + IMPORT_FUNC "sceUsbBus_driver",0xC5E53685,sceUsbbdReqCancelAll +#endif diff --git a/src/usb/sceUsbCam.S b/src/usb/sceUsbCam.S new file mode 100755 index 00000000..1a975abe --- /dev/null +++ b/src/usb/sceUsbCam.S @@ -0,0 +1,169 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceUsbCam_0000 + IMPORT_START "sceUsbCam",0x40090000 +#endif +#ifdef F_sceUsbCam_0001 + IMPORT_FUNC "sceUsbCam",0x03ED7A82,sceUsbCamSetupMic +#endif +#ifdef F_sceUsbCam_0002 + IMPORT_FUNC "sceUsbCam",0x08AEE98A,sceUsbCamSetMicGain +#endif +#ifdef F_sceUsbCam_0003 + IMPORT_FUNC "sceUsbCam",0x09C26C7E,sceUsbCamSetContrast +#endif +#ifdef F_sceUsbCam_0004 + IMPORT_FUNC "sceUsbCam",0x0A41A298,sceUsbCamSetupStillEx +#endif +#ifdef F_sceUsbCam_0005 + IMPORT_FUNC "sceUsbCam",0x11A1F128,sceUsbCamGetAutoImageReverseState +#endif +#ifdef F_sceUsbCam_0006 + IMPORT_FUNC "sceUsbCam",0x17F7B2FB,sceUsbCamSetupVideo +#endif +#ifdef F_sceUsbCam_0007 + IMPORT_FUNC "sceUsbCam",0x1A46CFE7,sceUsbCamStillPollInputEnd +#endif +#ifdef F_sceUsbCam_0008 + IMPORT_FUNC "sceUsbCam",0x1D686870,sceUsbCamSetEvLevel +#endif +#ifdef F_sceUsbCam_0009 + IMPORT_FUNC "sceUsbCam",0x1E958148,sceUsbCam_1E958148 +#endif +#ifdef F_sceUsbCam_0010 + IMPORT_FUNC "sceUsbCam",0x2BCD50C0,sceUsbCamGetEvLevel +#endif +#ifdef F_sceUsbCam_0011 + IMPORT_FUNC "sceUsbCam",0x2E930264,sceUsbCamSetupMicEx +#endif +#ifdef F_sceUsbCam_0012 + IMPORT_FUNC "sceUsbCam",0x36636925,sceUsbCamReadMicBlocking +#endif +#ifdef F_sceUsbCam_0013 + IMPORT_FUNC "sceUsbCam",0x383E9FA8,sceUsbCamGetSaturation +#endif +#ifdef F_sceUsbCam_0014 + IMPORT_FUNC "sceUsbCam",0x3DC0088E,sceUsbCamReadMic +#endif +#ifdef F_sceUsbCam_0015 + IMPORT_FUNC "sceUsbCam",0x3F0CF289,sceUsbCamSetupStill +#endif +#ifdef F_sceUsbCam_0016 + IMPORT_FUNC "sceUsbCam",0x41E73E95,sceUsbCamPollReadVideoFrameEnd +#endif +#ifdef F_sceUsbCam_0017 + IMPORT_FUNC "sceUsbCam",0x41EE8797,sceUsbCamUnregisterLensRotationCallback +#endif +#ifdef F_sceUsbCam_0018 + IMPORT_FUNC "sceUsbCam",0x4C34F553,sceUsbCamGetLensDirection +#endif +#ifdef F_sceUsbCam_0019 + IMPORT_FUNC "sceUsbCam",0x4F3D84D5,sceUsbCamSetBrightness +#endif +#ifdef F_sceUsbCam_0020 + IMPORT_FUNC "sceUsbCam",0x5145868A,sceUsbCamStopMic +#endif +#ifdef F_sceUsbCam_0021 + IMPORT_FUNC "sceUsbCam",0x574A8C3F,sceUsbCamStartVideo +#endif +#ifdef F_sceUsbCam_0022 + IMPORT_FUNC "sceUsbCam",0x5778B452,sceUsbCamGetMicDataLength +#endif +#ifdef F_sceUsbCam_0023 + IMPORT_FUNC "sceUsbCam",0x61BE5CAC,sceUsbCamStillInputBlocking +#endif +#ifdef F_sceUsbCam_0024 + IMPORT_FUNC "sceUsbCam",0x622F83CC,sceUsbCamSetSharpness +#endif +#ifdef F_sceUsbCam_0025 + IMPORT_FUNC "sceUsbCam",0x6784E6A8,sceUsbCamSetAntiFlicker +#endif +#ifdef F_sceUsbCam_0026 + IMPORT_FUNC "sceUsbCam",0x6CF32CB9,sceUsbCamStopVideo +#endif +#ifdef F_sceUsbCam_0027 + IMPORT_FUNC "sceUsbCam",0x6E205974,sceUsbCamSetSaturation +#endif +#ifdef F_sceUsbCam_0028 + IMPORT_FUNC "sceUsbCam",0x70F522C5,sceUsbCamGetBrightness +#endif +#ifdef F_sceUsbCam_0029 + IMPORT_FUNC "sceUsbCam",0x7563AFA1,sceUsbCamStillWaitInputEnd +#endif +#ifdef F_sceUsbCam_0030 + IMPORT_FUNC "sceUsbCam",0x7DAC0C71,sceUsbCamReadVideoFrameBlocking +#endif +#ifdef F_sceUsbCam_0031 + IMPORT_FUNC "sceUsbCam",0x82A64030,sceUsbCamStartMic +#endif +#ifdef F_sceUsbCam_0032 + IMPORT_FUNC "sceUsbCam",0x951BEDF5,sceUsbCamSetReverseMode +#endif +#ifdef F_sceUsbCam_0033 + IMPORT_FUNC "sceUsbCam",0x95F8901E,sceUsbCam_95F8901E +#endif +#ifdef F_sceUsbCam_0034 + IMPORT_FUNC "sceUsbCam",0x994471E0,sceUsbCamGetImageEffectMode +#endif +#ifdef F_sceUsbCam_0035 + IMPORT_FUNC "sceUsbCam",0x99D86281,sceUsbCamReadVideoFrame +#endif +#ifdef F_sceUsbCam_0036 + IMPORT_FUNC "sceUsbCam",0x9E8AAF8D,sceUsbCamGetZoom +#endif +#ifdef F_sceUsbCam_0037 + IMPORT_FUNC "sceUsbCam",0xA063A957,sceUsbCamGetContrast +#endif +#ifdef F_sceUsbCam_0038 + IMPORT_FUNC "sceUsbCam",0xA720937C,sceUsbCamStillCancelInput +#endif +#ifdef F_sceUsbCam_0039 + IMPORT_FUNC "sceUsbCam",0xAA7D94BA,sceUsbCamGetAntiFlicker +#endif +#ifdef F_sceUsbCam_0040 + IMPORT_FUNC "sceUsbCam",0xB048A67D,sceUsbCamWaitReadMicEnd +#endif +#ifdef F_sceUsbCam_0041 + IMPORT_FUNC "sceUsbCam",0xC484901F,sceUsbCamSetZoom +#endif +#ifdef F_sceUsbCam_0042 + IMPORT_FUNC "sceUsbCam",0xC72ED6D3,sceUsbCam_C72ED6D3 +#endif +#ifdef F_sceUsbCam_0043 + IMPORT_FUNC "sceUsbCam",0xCFE9E999,sceUsbCamSetupVideoEx +#endif +#ifdef F_sceUsbCam_0044 + IMPORT_FUNC "sceUsbCam",0xD293A100,sceUsbCamRegisterLensRotationCallback +#endif +#ifdef F_sceUsbCam_0045 + IMPORT_FUNC "sceUsbCam",0xD4876173,sceUsbCamSetImageEffectMode +#endif +#ifdef F_sceUsbCam_0046 + IMPORT_FUNC "sceUsbCam",0xD5279339,sceUsbCamGetReverseMode +#endif +#ifdef F_sceUsbCam_0047 + IMPORT_FUNC "sceUsbCam",0xD865997B,sceUsbCam_D865997B +#endif +#ifdef F_sceUsbCam_0048 + IMPORT_FUNC "sceUsbCam",0xDF9D0C92,sceUsbCamGetReadVideoFrameSize +#endif +#ifdef F_sceUsbCam_0049 + IMPORT_FUNC "sceUsbCam",0xE5959C36,sceUsbCamStillGetInputLength +#endif +#ifdef F_sceUsbCam_0050 + IMPORT_FUNC "sceUsbCam",0xF8847F60,sceUsbCamPollReadMicEnd +#endif +#ifdef F_sceUsbCam_0051 + IMPORT_FUNC "sceUsbCam",0xF90B2293,sceUsbCamWaitReadVideoFrameEnd +#endif +#ifdef F_sceUsbCam_0052 + IMPORT_FUNC "sceUsbCam",0xF93C4669,sceUsbCamAutoImageReverseSW +#endif +#ifdef F_sceUsbCam_0053 + IMPORT_FUNC "sceUsbCam",0xFB0A6C5D,sceUsbCamStillInput +#endif +#ifdef F_sceUsbCam_0054 + IMPORT_FUNC "sceUsbCam",0xFDB68C23,sceUsbCamGetSharpness +#endif diff --git a/src/usb/sceUsb_driver.S b/src/usb/sceUsb_driver.S new file mode 100644 index 00000000..61b7f7e9 --- /dev/null +++ b/src/usb/sceUsb_driver.S @@ -0,0 +1,37 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceUsb_driver_0000 + IMPORT_START "sceUsb_driver",0x00010000 +#endif +#ifdef F_sceUsb_driver_0001 + IMPORT_FUNC "sceUsb_driver",0xAE5DE6AF,sceUsbStart +#endif +#ifdef F_sceUsb_driver_0002 + IMPORT_FUNC "sceUsb_driver",0xC2464FA0,sceUsbStop +#endif +#ifdef F_sceUsb_driver_0003 + IMPORT_FUNC "sceUsb_driver",0xC21645A4,sceUsbGetState +#endif +#ifdef F_sceUsb_driver_0004 + IMPORT_FUNC "sceUsb_driver",0x4E537366,sceUsbGetDrvList +#endif +#ifdef F_sceUsb_driver_0005 + IMPORT_FUNC "sceUsb_driver",0x112CC951,sceUsbGetDrvState +#endif +#ifdef F_sceUsb_driver_0006 + IMPORT_FUNC "sceUsb_driver",0x586DB82C,sceUsbActivate +#endif +#ifdef F_sceUsb_driver_0007 + IMPORT_FUNC "sceUsb_driver",0xC572A9C8,sceUsbDeactivate +#endif +#ifdef F_sceUsb_driver_0008 + IMPORT_FUNC "sceUsb_driver",0x5BE0E002,sceUsbWaitState +#endif +#ifdef F_sceUsb_driver_0009 + IMPORT_FUNC "sceUsb_driver",0x1C360735,sceUsbWaitCancel +#endif +#ifdef F_sceUsb_driver_0010 + IMPORT_FUNC "sceUsb_driver",0xE20B23A6,sceUsb_E20B23A6 +#endif diff --git a/src/usbstor/Makefile.am b/src/usbstor/Makefile.am new file mode 100644 index 00000000..072e5ff3 --- /dev/null +++ b/src/usbstor/Makefile.am @@ -0,0 +1,30 @@ + +libdir = @PSPSDK_LIBDIR@ + +CC = @PSP_CC@ +CCAS = $(CC) +AR = @PSP_AR@ +RANLIB = @PSP_RANLIB@ + +INCLUDES = -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel +CFLAGS = @PSPSDK_CFLAGS@ +CCASFLAGS = $(CFLAGS) $(INCLUDES) + +USBSTOR_OBJS = sceUsbstor_0000.o sceUsbstor_0001.o +USBSTORBOOT_OBJS = sceUsbstorBoot_0000.o sceUsbstorBoot_0001.o sceUsbstorBoot_0002.o sceUsbstorBoot_0003.o sceUsbstorBoot_0004.o sceUsbstorBoot_0005.o sceUsbstorBoot_0006.o + +libpspusbstorincludedir = @PSPSDK_INCLUDEDIR@ + +libpspusbstorinclude_HEADERS = \ + pspusbstor.h + +lib_LIBRARIES = libpspusbstor.a + +libpspusbstor_a_SOURCES = sceUsbstor.S sceUsbstorBoot.S +libpspusbstor_a_LIBADD = $(USBSTOR_OBJS) $(USBSTORBOOT_OBJS) + +$(USBSTOR_OBJS): sceUsbstor.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(USBSTORBOOT_OBJS): sceUsbstorBoot.S + $(COMPILE) -DF_$* $< -c -o $@ diff --git a/src/usbstor/pspusbstor.h b/src/usbstor/pspusbstor.h new file mode 100644 index 00000000..f71fd914 --- /dev/null +++ b/src/usbstor/pspusbstor.h @@ -0,0 +1,64 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspusbstor.h - Prototypes for the sceUsbStor and sceUsbStorBoot libraries + * + * Copyright (c) 2005 John Kelley + * + * $Id: pspusbstor.h 1095 2005-09-27 21:02:16Z jim $ + */ +#ifndef __PSPUSBSTOR_H__ +#define __PSPUSBSTOR_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define PSP_USBSTOR_DRIVERNAME "USBStor_Driver" + +/** + * Register an eventFlag to send notifications to. + * + * @param eventFlag - eventFlag created with sceKernelCreateEventFlag + * + * @return 0 on success + */ +int sceUsbstorBootRegisterNotify(u32 eventFlag); + +/** + * Unregister a previously registered eventFlag. + * + * @param eventFlag - eventFlag created with sceKernelCreateEventFlag + * + * @return 0 on success + */ +int sceUsbstorBootUnregisterNotify(u32 eventFlag); + +/** + * Tell the USBstorBoot driver the size of MS + * + * @note I'm not sure if this is the actual size of the media or not + * as it seems to have no bearing on what size windows detects. + * PSPPET passes 0x800000 + * + * @param size - capacity of memory stick + * + * @return 0 on success + */ +int sceUsbstorBootSetCapacity(u32 size); + +// the following are disabled until more testing is done +#if 0 +int sceUsbstorBootGetDataSize(void); // what for ? +int sceUsbstorBootSetLoadAddr(u32 addr); // ? +int sceUsbstorBootSetStatus(u32 status); // 1=? +int sceUsbstorGetStatus(?) +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/usbstor/sceUsbstor.S b/src/usbstor/sceUsbstor.S new file mode 100644 index 00000000..edb524b6 --- /dev/null +++ b/src/usbstor/sceUsbstor.S @@ -0,0 +1,10 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceUsbstor_0000 + IMPORT_START "sceUsbstor",0x40090000 +#endif +#ifdef F_sceUsbstor_0001 + IMPORT_FUNC "sceUsbstor",0x60066CFE,sceUsbstorGetStatus +#endif diff --git a/src/usbstor/sceUsbstorBoot.S b/src/usbstor/sceUsbstorBoot.S new file mode 100644 index 00000000..4e5661f3 --- /dev/null +++ b/src/usbstor/sceUsbstorBoot.S @@ -0,0 +1,25 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceUsbstorBoot_0000 + IMPORT_START "sceUsbstorBoot",0x40090000 +#endif +#ifdef F_sceUsbstorBoot_0001 + IMPORT_FUNC "sceUsbstorBoot",0xE58818A8,sceUsbstorBootSetCapacity +#endif +#ifdef F_sceUsbstorBoot_0002 + IMPORT_FUNC "sceUsbstorBoot",0x594BBF95,sceUsbstorBootSetLoadAddr +#endif +#ifdef F_sceUsbstorBoot_0003 + IMPORT_FUNC "sceUsbstorBoot",0x6D865ECD,sceUsbstorBootGetDataSize +#endif +#ifdef F_sceUsbstorBoot_0004 + IMPORT_FUNC "sceUsbstorBoot",0xA1119F0D,sceUsbstorBootSetStatus +#endif +#ifdef F_sceUsbstorBoot_0005 + IMPORT_FUNC "sceUsbstorBoot",0x1F080078,sceUsbstorBootRegisterNotify +#endif +#ifdef F_sceUsbstorBoot_0006 + IMPORT_FUNC "sceUsbstorBoot",0xA55C9E16,sceUsbstorBootUnregisterNotify +#endif diff --git a/src/user/InterruptManager.S b/src/user/InterruptManager.S new file mode 100644 index 00000000..95464ef5 --- /dev/null +++ b/src/user/InterruptManager.S @@ -0,0 +1,34 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_InterruptManager_0000 + IMPORT_START "InterruptManager",0x40000000 +#endif +#ifdef F_InterruptManager_0001 + IMPORT_FUNC "InterruptManager",0xCA04A2B9,sceKernelRegisterSubIntrHandler +#endif +#ifdef F_InterruptManager_0002 + IMPORT_FUNC "InterruptManager",0xD61E6961,sceKernelReleaseSubIntrHandler +#endif +#ifdef F_InterruptManager_0003 + IMPORT_FUNC "InterruptManager",0xFB8E22EC,sceKernelEnableSubIntr +#endif +#ifdef F_InterruptManager_0004 + IMPORT_FUNC "InterruptManager",0x8A389411,sceKernelDisableSubIntr +#endif +#ifdef F_InterruptManager_0005 + IMPORT_FUNC "InterruptManager",0x5CB5A78B,sceKernelSuspendSubIntr +#endif +#ifdef F_InterruptManager_0006 + IMPORT_FUNC "InterruptManager",0x7860E0DC,sceKernelResumeSubIntr +#endif +#ifdef F_InterruptManager_0007 + IMPORT_FUNC "InterruptManager",0xFC4374B8,sceKernelIsSubInterruptOccurred +#endif +#ifdef F_InterruptManager_0008 + IMPORT_FUNC "InterruptManager",0xD2E8363F,QueryIntrHandlerInfo +#endif +#ifdef F_InterruptManager_0009 + IMPORT_FUNC "InterruptManager",0xEEE43F47,sceKernelRegisterUserSpaceIntrStack +#endif diff --git a/src/user/IoFileMgrForUser.S b/src/user/IoFileMgrForUser.S new file mode 100644 index 00000000..67993ed0 --- /dev/null +++ b/src/user/IoFileMgrForUser.S @@ -0,0 +1,115 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_IoFileMgrForUser_0000 + IMPORT_START "IoFileMgrForUser",0x40010000 +#endif +#ifdef F_IoFileMgrForUser_0001 + IMPORT_FUNC "IoFileMgrForUser",0x3251EA56,sceIoPollAsync +#endif +#ifdef F_IoFileMgrForUser_0002 + IMPORT_FUNC "IoFileMgrForUser",0xE23EEC33,sceIoWaitAsync +#endif +#ifdef F_IoFileMgrForUser_0003 + IMPORT_FUNC "IoFileMgrForUser",0x35DBD746,sceIoWaitAsyncCB +#endif +#ifdef F_IoFileMgrForUser_0004 + IMPORT_FUNC "IoFileMgrForUser",0xCB05F8D6,sceIoGetAsyncStat +#endif +#ifdef F_IoFileMgrForUser_0005 + IMPORT_FUNC "IoFileMgrForUser",0xB293727F,sceIoChangeAsyncPriority +#endif +#ifdef F_IoFileMgrForUser_0006 + IMPORT_FUNC "IoFileMgrForUser",0xA12A0514,sceIoSetAsyncCallback +#endif +#ifdef F_IoFileMgrForUser_0007 + IMPORT_FUNC "IoFileMgrForUser",0x810C4BC3,sceIoClose +#endif +#ifdef F_IoFileMgrForUser_0008 + IMPORT_FUNC "IoFileMgrForUser",0xFF5940B6,sceIoCloseAsync +#endif +#ifdef F_IoFileMgrForUser_0009 + IMPORT_FUNC "IoFileMgrForUser",0x109F50BC,sceIoOpen +#endif +#ifdef F_IoFileMgrForUser_0010 + IMPORT_FUNC "IoFileMgrForUser",0x89AA9906,sceIoOpenAsync +#endif +#ifdef F_IoFileMgrForUser_0011 + IMPORT_FUNC "IoFileMgrForUser",0x6A638D83,sceIoRead +#endif +#ifdef F_IoFileMgrForUser_0012 + IMPORT_FUNC "IoFileMgrForUser",0xA0B5A7C2,sceIoReadAsync +#endif +#ifdef F_IoFileMgrForUser_0013 + IMPORT_FUNC "IoFileMgrForUser",0x42EC03AC,sceIoWrite +#endif +#ifdef F_IoFileMgrForUser_0014 + IMPORT_FUNC "IoFileMgrForUser",0x0FACAB19,sceIoWriteAsync +#endif +#ifdef F_IoFileMgrForUser_0015 + IMPORT_FUNC "IoFileMgrForUser",0x27EB27B8,sceIoLseek +#endif +#ifdef F_IoFileMgrForUser_0016 + IMPORT_FUNC "IoFileMgrForUser",0x71B19E77,sceIoLseekAsync +#endif +#ifdef F_IoFileMgrForUser_0017 + IMPORT_FUNC "IoFileMgrForUser",0x68963324,sceIoLseek32 +#endif +#ifdef F_IoFileMgrForUser_0018 + IMPORT_FUNC "IoFileMgrForUser",0x1B385D8F,sceIoLseek32Async +#endif +#ifdef F_IoFileMgrForUser_0019 + IMPORT_FUNC "IoFileMgrForUser",0x63632449,sceIoIoctl +#endif +#ifdef F_IoFileMgrForUser_0020 + IMPORT_FUNC "IoFileMgrForUser",0xE95A012B,sceIoIoctlAsync +#endif +#ifdef F_IoFileMgrForUser_0021 + IMPORT_FUNC "IoFileMgrForUser",0xB29DDF9C,sceIoDopen +#endif +#ifdef F_IoFileMgrForUser_0022 + IMPORT_FUNC "IoFileMgrForUser",0xE3EB004C,sceIoDread +#endif +#ifdef F_IoFileMgrForUser_0023 + IMPORT_FUNC "IoFileMgrForUser",0xEB092469,sceIoDclose +#endif +#ifdef F_IoFileMgrForUser_0024 + IMPORT_FUNC "IoFileMgrForUser",0xF27A9C51,sceIoRemove +#endif +#ifdef F_IoFileMgrForUser_0025 + IMPORT_FUNC "IoFileMgrForUser",0x06A70004,sceIoMkdir +#endif +#ifdef F_IoFileMgrForUser_0026 + IMPORT_FUNC "IoFileMgrForUser",0x1117C65F,sceIoRmdir +#endif +#ifdef F_IoFileMgrForUser_0027 + IMPORT_FUNC "IoFileMgrForUser",0x55F4717D,sceIoChdir +#endif +#ifdef F_IoFileMgrForUser_0028 + IMPORT_FUNC "IoFileMgrForUser",0xAB96437F,sceIoSync +#endif +#ifdef F_IoFileMgrForUser_0029 + IMPORT_FUNC "IoFileMgrForUser",0xACE946E8,sceIoGetstat +#endif +#ifdef F_IoFileMgrForUser_0030 + IMPORT_FUNC "IoFileMgrForUser",0xB8A740F4,sceIoChstat +#endif +#ifdef F_IoFileMgrForUser_0031 + IMPORT_FUNC "IoFileMgrForUser",0x779103A0,sceIoRename +#endif +#ifdef F_IoFileMgrForUser_0032 + IMPORT_FUNC "IoFileMgrForUser",0x54F5FB11,sceIoDevctl +#endif +#ifdef F_IoFileMgrForUser_0033 + IMPORT_FUNC "IoFileMgrForUser",0x08BD7374,sceIoGetDevType +#endif +#ifdef F_IoFileMgrForUser_0034 + IMPORT_FUNC "IoFileMgrForUser",0xB2A628C1,sceIoAssign +#endif +#ifdef F_IoFileMgrForUser_0035 + IMPORT_FUNC "IoFileMgrForUser",0x6D08A871,sceIoUnassign +#endif +#ifdef F_IoFileMgrForUser_0036 + IMPORT_FUNC "IoFileMgrForUser",0xE8BC6571,sceIoCancel +#endif diff --git a/src/user/Kernel_Library.S b/src/user/Kernel_Library.S new file mode 100644 index 00000000..a5b05816 --- /dev/null +++ b/src/user/Kernel_Library.S @@ -0,0 +1,22 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_Kernel_Library_0000 + IMPORT_START "Kernel_Library",0x00010000 +#endif +#ifdef F_Kernel_Library_0001 + IMPORT_FUNC "Kernel_Library",0x092968F4,sceKernelCpuSuspendIntr +#endif +#ifdef F_Kernel_Library_0002 + IMPORT_FUNC "Kernel_Library",0x5F10D406,sceKernelCpuResumeIntr +#endif +#ifdef F_Kernel_Library_0003 + IMPORT_FUNC "Kernel_Library",0x3B84732D,sceKernelCpuResumeIntrWithSync +#endif +#ifdef F_Kernel_Library_0004 + IMPORT_FUNC "Kernel_Library",0x47A0B729,sceKernelIsCpuIntrSuspended +#endif +#ifdef F_Kernel_Library_0005 + IMPORT_FUNC "Kernel_Library",0xB55249D2,sceKernelIsCpuIntrEnable +#endif diff --git a/src/user/LoadExecForUser.S b/src/user/LoadExecForUser.S new file mode 100644 index 00000000..1ac1572e --- /dev/null +++ b/src/user/LoadExecForUser.S @@ -0,0 +1,19 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_LoadExecForUser_0000 + IMPORT_START "LoadExecForUser",0x40010000 +#endif +#ifdef F_LoadExecForUser_0001 + IMPORT_FUNC "LoadExecForUser",0xBD2F1094,sceKernelLoadExec +#endif +#ifdef F_LoadExecForUser_0002 + IMPORT_FUNC "LoadExecForUser",0x2AC9954B,sceKernelExitGameWithStatus +#endif +#ifdef F_LoadExecForUser_0003 + IMPORT_FUNC "LoadExecForUser",0x05572A5F,sceKernelExitGame +#endif +#ifdef F_LoadExecForUser_0004 + IMPORT_FUNC "LoadExecForUser",0x4AC57943,sceKernelRegisterExitCallback +#endif diff --git a/src/user/Makefile.am b/src/user/Makefile.am new file mode 100644 index 00000000..9372f371 --- /dev/null +++ b/src/user/Makefile.am @@ -0,0 +1,116 @@ + +libdir = @PSPSDK_LIBDIR@ + +CC = @PSP_CC@ +CCAS = $(CC) +AR = @PSP_AR@ +RANLIB = @PSP_RANLIB@ + +INCLUDES = -I$(top_srcdir)/src/base +CFLAGS = @PSPSDK_CFLAGS@ +CCASFLAGS = $(CFLAGS) $(INCLUDES) + +IO_OBJS = IoFileMgrForUser_0000.o IoFileMgrForUser_0001.o IoFileMgrForUser_0002.o IoFileMgrForUser_0003.o IoFileMgrForUser_0004.o IoFileMgrForUser_0005.o IoFileMgrForUser_0006.o IoFileMgrForUser_0007.o IoFileMgrForUser_0008.o IoFileMgrForUser_0009.o IoFileMgrForUser_0010.o IoFileMgrForUser_0011.o IoFileMgrForUser_0012.o IoFileMgrForUser_0013.o IoFileMgrForUser_0014.o IoFileMgrForUser_0015.o IoFileMgrForUser_0016.o IoFileMgrForUser_0017.o IoFileMgrForUser_0018.o IoFileMgrForUser_0019.o IoFileMgrForUser_0020.o IoFileMgrForUser_0021.o IoFileMgrForUser_0022.o IoFileMgrForUser_0023.o IoFileMgrForUser_0024.o IoFileMgrForUser_0025.o IoFileMgrForUser_0026.o IoFileMgrForUser_0027.o IoFileMgrForUser_0028.o IoFileMgrForUser_0029.o IoFileMgrForUser_0030.o IoFileMgrForUser_0031.o IoFileMgrForUser_0032.o IoFileMgrForUser_0033.o IoFileMgrForUser_0034.o IoFileMgrForUser_0035.o IoFileMgrForUser_0036.o + +KERNEL_OBJS = Kernel_Library_0000.o Kernel_Library_0001.o Kernel_Library_0002.o Kernel_Library_0003.o Kernel_Library_0004.o Kernel_Library_0005.o + +MODMGR_OBJS = ModuleMgrForUser_0000.o ModuleMgrForUser_0001.o ModuleMgrForUser_0002.o ModuleMgrForUser_0003.o ModuleMgrForUser_0004.o ModuleMgrForUser_0005.o ModuleMgrForUser_0006.o ModuleMgrForUser_0007.o ModuleMgrForUser_0008.o ModuleMgrForUser_0009.o ModuleMgrForUser_0010.o ModuleMgrForUser_0011.o + +STDIO_OBJS = StdioForUser_0000.o StdioForUser_0001.o StdioForUser_0002.o StdioForUser_0003.o StdioForUser_0004.o StdioForUser_0005.o StdioForUser_0006.o StdioForUser_0007.o StdioForUser_0008.o StdioForUser_0009.o + +SUSPEND_OBJS = sceSuspendForUser_0000.o sceSuspendForUser_0001.o sceSuspendForUser_0002.o sceSuspendForUser_0003.o sceSuspendForUser_0004.o sceSuspendForUser_005.o sceSuspendForUser_0006.o + +SYSMEM_OBJS = SysMemUserForUser_0000.o SysMemUserForUser_0001.o SysMemUserForUser_0002.o SysMemUserForUser_0003.o SysMemUserForUser_0004.o SysMemUserForUser_0005.o SysMemUserForUser_0006.o SysMemUserForUser_0007.o + +THREADMAN_OBJS = ThreadManForUser_0000.o ThreadManForUser_0001.o ThreadManForUser_0002.o ThreadManForUser_0003.o ThreadManForUser_0004.o ThreadManForUser_0005.o ThreadManForUser_0006.o ThreadManForUser_0007.o ThreadManForUser_0008.o ThreadManForUser_0009.o ThreadManForUser_0010.o ThreadManForUser_0011.o ThreadManForUser_0012.o ThreadManForUser_0013.o ThreadManForUser_0014.o ThreadManForUser_0015.o ThreadManForUser_0016.o ThreadManForUser_0017.o ThreadManForUser_0018.o ThreadManForUser_0019.o ThreadManForUser_0020.o ThreadManForUser_0021.o ThreadManForUser_0022.o ThreadManForUser_0023.o ThreadManForUser_0024.o ThreadManForUser_0025.o ThreadManForUser_0026.o ThreadManForUser_0027.o ThreadManForUser_0028.o ThreadManForUser_0029.o ThreadManForUser_0030.o ThreadManForUser_0031.o ThreadManForUser_0032.o ThreadManForUser_0033.o ThreadManForUser_0034.o ThreadManForUser_0035.o ThreadManForUser_0036.o ThreadManForUser_0037.o ThreadManForUser_0038.o ThreadManForUser_0039.o ThreadManForUser_0040.o ThreadManForUser_0041.o ThreadManForUser_0042.o ThreadManForUser_0043.o ThreadManForUser_0044.o ThreadManForUser_0045.o ThreadManForUser_0046.o ThreadManForUser_0047.o ThreadManForUser_0048.o ThreadManForUser_0049.o ThreadManForUser_0050.o ThreadManForUser_0051.o ThreadManForUser_0052.o ThreadManForUser_0053.o ThreadManForUser_0054.o ThreadManForUser_0055.o ThreadManForUser_0056.o ThreadManForUser_0057.o ThreadManForUser_0058.o ThreadManForUser_0059.o ThreadManForUser_0060.o ThreadManForUser_0061.o ThreadManForUser_0062.o ThreadManForUser_0063.o ThreadManForUser_0064.o ThreadManForUser_0065.o ThreadManForUser_0066.o ThreadManForUser_0067.o ThreadManForUser_0068.o ThreadManForUser_0069.o ThreadManForUser_0070.o ThreadManForUser_0071.o ThreadManForUser_0072.o ThreadManForUser_0073.o ThreadManForUser_0074.o ThreadManForUser_0075.o ThreadManForUser_0076.o ThreadManForUser_0077.o ThreadManForUser_0078.o ThreadManForUser_0079.o ThreadManForUser_0080.o ThreadManForUser_0081.o ThreadManForUser_0082.o ThreadManForUser_0083.o ThreadManForUser_0084.o ThreadManForUser_0085.o ThreadManForUser_0086.o ThreadManForUser_0087.o ThreadManForUser_0088.o ThreadManForUser_0089.o ThreadManForUser_0090.o ThreadManForUser_0091.o ThreadManForUser_0092.o ThreadManForUser_0093.o ThreadManForUser_0094.o ThreadManForUser_0095.o ThreadManForUser_0096.o ThreadManForUser_0097.o ThreadManForUser_0098.o ThreadManForUser_0099.o ThreadManForUser_0100.o ThreadManForUser_0101.o ThreadManForUser_0102.o ThreadManForUser_0103.o ThreadManForUser_0104.o ThreadManForUser_0105.o ThreadManForUser_0106.o ThreadManForUser_0107.o ThreadManForUser_0108.o ThreadManForUser_0109.o ThreadManForUser_0110.o ThreadManForUser_0111.o ThreadManForUser_0112.o ThreadManForUser_0113.o ThreadManForUser_0114.o ThreadManForUser_0115.o ThreadManForUser_0116.o ThreadManForUser_0117.o ThreadManForUser_0118.o ThreadManForUser_0119.o ThreadManForUser_0120.o ThreadManForUser_0121.o ThreadManForUser_0122.o ThreadManForUser_0123.o ThreadManForUser_0124.o ThreadManForUser_0125.o ThreadManForUser_0126.o + +UTILS_OBJS = UtilsForUser_0000.o UtilsForUser_0001.o UtilsForUser_0002.o UtilsForUser_0003.o UtilsForUser_0004.o UtilsForUser_0005.o UtilsForUser_0006.o UtilsForUser_0007.o UtilsForUser_0008.o UtilsForUser_0009.o UtilsForUser_0010.o UtilsForUser_0011.o UtilsForUser_0012.o UtilsForUser_0013.o UtilsForUser_0014.o UtilsForUser_0015.o UtilsForUser_0016.o UtilsForUser_0017.o UtilsForUser_0018.o UtilsForUser_0019.o UtilsForUser_0020.o UtilsForUser_0021.o UtilsForUser_0022.o UtilsForUser_0023.o UtilsForUser_0024.o + +INTERRUPT_OBJS = InterruptManager_0000.o InterruptManager_0001.o InterruptManager_0002.o InterruptManager_0003.o InterruptManager_0004.o InterruptManager_0005.o InterruptManager_0006.o InterruptManager_0007.o InterruptManager_0008.o InterruptManager_0009.o + +LOADEXEC_OBJS = LoadExecForUser_0000.o LoadExecForUser_0001.o LoadExecForUser_0002.o LoadExecForUser_0003.o LoadExecForUser_0004.o + +IMPOSE_OBJS = sceImpose_0000.o sceImpose_0001.o sceImpose_0002.o sceImpose_0003.o sceImpose_0004.o sceImpose_0005.o sceImpose_0006.o sceImpose_0007.o sceImpose_0008.o sceImpose_0009.o sceImpose_0010.o sceImpose_0011.o sceImpose_0012.o sceImpose_0013.o sceImpose_0014.o sceImpose_0015.o + +libpspuserincludedir = @PSPSDK_INCLUDEDIR@ +libpspuserinclude_HEADERS = \ + pspiofilemgr.h \ + pspiofilemgr_dirent.h \ + pspiofilemgr_fcntl.h \ + pspiofilemgr_stat.h \ + pspkerneltypes.h \ + pspkerror.h \ + psploadexec.h \ + pspmscm.h \ + pspmoduleinfo.h \ + pspmodulemgr.h \ + pspsuspend.h \ + pspsysmem.h \ + pspthreadman.h \ + pspstdio.h \ + pspuser.h \ + psputils.h \ + pspintrman.h \ + pspmoduleexport.h + +lib_LIBRARIES = libpspuser.a + +libpspuser_a_SOURCES = \ + IoFileMgrForUser.S \ + InterruptManager.S \ + Kernel_Library.S \ + LoadExecForUser.S \ + ModuleMgrForUser.S \ + StdioForUser.S \ + SysMemUserForUser.S \ + ThreadManForUser.S \ + UtilsForUser.S \ + sceSuspendForUser.S \ + pspintrman.c \ + sceImpose.S + +libpspuser_a_LIBADD = \ +$(IO_OBJS) \ +$(KERNEL_OBJS) \ +$(MODMGR_OBJS) \ +$(STDIO_OBJS) \ +$(SUSPEND_OBJS) \ +$(SYSMEM_OBJS) \ +$(THREADMAN_OBJS) \ +$(UTILS_OBJS) \ +$(INTERRUPT_OBJS) \ +$(LOADEXEC_OBJS) \ +$(IMPOSE_OBJS) + +$(IO_OBJS): IoFileMgrForUser.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(KERNEL_OBJS): Kernel_Library.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(MODMGR_OBJS): ModuleMgrForUser.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(STDIO_OBJS): StdioForUser.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(SUSPEND_OBJS): sceSuspendForUser.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(SYSMEM_OBJS): SysMemUserForUser.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(THREADMAN_OBJS): ThreadManForUser.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(UTILS_OBJS): UtilsForUser.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(INTERRUPT_OBJS): InterruptManager.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(LOADEXEC_OBJS): LoadExecForUser.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(IMPOSE_OBJS): sceImpose.S + $(COMPILE) -DF_$* $< -c -o $@ diff --git a/src/user/ModuleMgrForUser.S b/src/user/ModuleMgrForUser.S new file mode 100644 index 00000000..3c9bdd38 --- /dev/null +++ b/src/user/ModuleMgrForUser.S @@ -0,0 +1,40 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_ModuleMgrForUser_0000 + IMPORT_START "ModuleMgrForUser",0x40010000 +#endif +#ifdef F_ModuleMgrForUser_0001 + IMPORT_FUNC "ModuleMgrForUser",0xB7F46618,sceKernelLoadModuleByID +#endif +#ifdef F_ModuleMgrForUser_0002 + IMPORT_FUNC "ModuleMgrForUser",0x977DE386,sceKernelLoadModule +#endif +#ifdef F_ModuleMgrForUser_0003 + IMPORT_FUNC "ModuleMgrForUser",0x710F61B5,sceKernelLoadModuleMs +#endif +#ifdef F_ModuleMgrForUser_0004 + IMPORT_FUNC "ModuleMgrForUser",0xF9275D98,sceKernelLoadModuleBufferUsbWlan +#endif +#ifdef F_ModuleMgrForUser_0005 + IMPORT_FUNC "ModuleMgrForUser",0x50F0C1EC,sceKernelStartModule +#endif +#ifdef F_ModuleMgrForUser_0006 + IMPORT_FUNC "ModuleMgrForUser",0xD1FF982A,sceKernelStopModule +#endif +#ifdef F_ModuleMgrForUser_0007 + IMPORT_FUNC "ModuleMgrForUser",0x2E0911AA,sceKernelUnloadModule +#endif +#ifdef F_ModuleMgrForUser_0008 + IMPORT_FUNC "ModuleMgrForUser",0xD675EBB8,sceKernelSelfStopUnloadModule +#endif +#ifdef F_ModuleMgrForUser_0009 + IMPORT_FUNC "ModuleMgrForUser",0xCC1D3699,sceKernelStopUnloadSelfModule +#endif +#ifdef F_ModuleMgrForUser_0010 + IMPORT_FUNC "ModuleMgrForUser",0x748CBED9,sceKernelQueryModuleInfo +#endif +#ifdef F_ModuleMgrForUser_0011 + IMPORT_FUNC "ModuleMgrForUser", 0x644395E2,sceKernelGetModuleIdList +#endif diff --git a/src/user/StdioForUser.S b/src/user/StdioForUser.S new file mode 100644 index 00000000..879ce66e --- /dev/null +++ b/src/user/StdioForUser.S @@ -0,0 +1,34 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_StdioForUser_0000 + IMPORT_START "StdioForUser",0x40010000 +#endif +#ifdef F_StdioForUser_0001 + IMPORT_FUNC "StdioForUser",0x3054D478,sceKernelStdioRead +#endif +#ifdef F_StdioForUser_0002 + IMPORT_FUNC "StdioForUser",0x0CBB0571,sceKernelStdioLseek +#endif +#ifdef F_StdioForUser_0003 + IMPORT_FUNC "StdioForUser",0xA46785C9,sceKernelStdioSendChar +#endif +#ifdef F_StdioForUser_0004 + IMPORT_FUNC "StdioForUser",0xA3B931DB,sceKernelStdioWrite +#endif +#ifdef F_StdioForUser_0005 + IMPORT_FUNC "StdioForUser",0x9D061C19,sceKernelStdioClose +#endif +#ifdef F_StdioForUser_0006 + IMPORT_FUNC "StdioForUser",0x924ABA61,sceKernelStdioOpen +#endif +#ifdef F_StdioForUser_0007 + IMPORT_FUNC "StdioForUser",0x172D316E,sceKernelStdin +#endif +#ifdef F_StdioForUser_0008 + IMPORT_FUNC "StdioForUser",0xA6BAB2E9,sceKernelStdout +#endif +#ifdef F_StdioForUser_0009 + IMPORT_FUNC "StdioForUser",0xF78BA90A,sceKernelStderr +#endif diff --git a/src/user/SysMemUserForUser.S b/src/user/SysMemUserForUser.S new file mode 100644 index 00000000..dd197730 --- /dev/null +++ b/src/user/SysMemUserForUser.S @@ -0,0 +1,28 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_SysMemUserForUser_0000 + IMPORT_START "SysMemUserForUser",0x40000000 +#endif +#ifdef F_SysMemUserForUser_0001 + IMPORT_FUNC "SysMemUserForUser",0xA291F107,sceKernelMaxFreeMemSize +#endif +#ifdef F_SysMemUserForUser_0002 + IMPORT_FUNC "SysMemUserForUser",0xF919F628,sceKernelTotalFreeMemSize +#endif +#ifdef F_SysMemUserForUser_0003 + IMPORT_FUNC "SysMemUserForUser",0x237DBD4F,sceKernelAllocPartitionMemory +#endif +#ifdef F_SysMemUserForUser_0004 + IMPORT_FUNC "SysMemUserForUser",0xB6D61D02,sceKernelFreePartitionMemory +#endif +#ifdef F_SysMemUserForUser_0005 + IMPORT_FUNC "SysMemUserForUser",0x9D9A5BA1,sceKernelGetBlockHeadAddr +#endif +#ifdef F_SysMemUserForUser_0006 + IMPORT_FUNC "SysMemUserForUser",0x3FC9AE6A,sceKernelDevkitVersion +#endif +#ifdef F_SysMemUserForUser_0007 + IMPORT_FUNC "SysMemUserForUser",0x13A5ABEF,sceKernelPrintf +#endif diff --git a/src/user/ThreadManForUser.S b/src/user/ThreadManForUser.S new file mode 100644 index 00000000..968a2d93 --- /dev/null +++ b/src/user/ThreadManForUser.S @@ -0,0 +1,385 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_ThreadManForUser_0000 + IMPORT_START "ThreadManForUser",0x40010000 +#endif +#ifdef F_ThreadManForUser_0001 + IMPORT_FUNC "ThreadManForUser",0x6E9EA350,_sceKernelReturnFromCallback +#endif +#ifdef F_ThreadManForUser_0002 + IMPORT_FUNC "ThreadManForUser",0x0C106E53,sceKernelRegisterThreadEventHandler +#endif +#ifdef F_ThreadManForUser_0003 + IMPORT_FUNC "ThreadManForUser",0x72F3C145,sceKernelReleaseThreadEventHandler +#endif +#ifdef F_ThreadManForUser_0004 + IMPORT_FUNC "ThreadManForUser",0x369EEB6B,sceKernelReferThreadEventHandlerStatus +#endif +#ifdef F_ThreadManForUser_0005 + IMPORT_FUNC "ThreadManForUser",0xE81CAF8F,sceKernelCreateCallback +#endif +#ifdef F_ThreadManForUser_0006 + IMPORT_FUNC "ThreadManForUser",0xEDBA5844,sceKernelDeleteCallback +#endif +#ifdef F_ThreadManForUser_0007 + IMPORT_FUNC "ThreadManForUser",0xC11BA8C4,sceKernelNotifyCallback +#endif +#ifdef F_ThreadManForUser_0008 + IMPORT_FUNC "ThreadManForUser",0xBA4051D6,sceKernelCancelCallback +#endif +#ifdef F_ThreadManForUser_0009 + IMPORT_FUNC "ThreadManForUser",0x2A3D44FF,sceKernelGetCallbackCount +#endif +#ifdef F_ThreadManForUser_0010 + IMPORT_FUNC "ThreadManForUser",0x349D6D6C,sceKernelCheckCallback +#endif +#ifdef F_ThreadManForUser_0011 + IMPORT_FUNC "ThreadManForUser",0x730ED8BC,sceKernelReferCallbackStatus +#endif +#ifdef F_ThreadManForUser_0012 + IMPORT_FUNC "ThreadManForUser",0x9ACE131E,sceKernelSleepThread +#endif +#ifdef F_ThreadManForUser_0013 + IMPORT_FUNC "ThreadManForUser",0x82826F70,sceKernelSleepThreadCB +#endif +#ifdef F_ThreadManForUser_0014 + IMPORT_FUNC "ThreadManForUser",0xD59EAD2F,sceKernelWakeupThread +#endif +#ifdef F_ThreadManForUser_0015 + IMPORT_FUNC "ThreadManForUser",0xFCCFAD26,sceKernelCancelWakeupThread +#endif +#ifdef F_ThreadManForUser_0016 + IMPORT_FUNC "ThreadManForUser",0x9944F31F,sceKernelSuspendThread +#endif +#ifdef F_ThreadManForUser_0017 + IMPORT_FUNC "ThreadManForUser",0x75156E8F,sceKernelResumeThread +#endif +#ifdef F_ThreadManForUser_0018 + IMPORT_FUNC "ThreadManForUser",0x278C0DF5,sceKernelWaitThreadEnd +#endif +#ifdef F_ThreadManForUser_0019 + IMPORT_FUNC "ThreadManForUser",0x840E8133,sceKernelWaitThreadEndCB +#endif +#ifdef F_ThreadManForUser_0020 + IMPORT_FUNC "ThreadManForUser",0xCEADEB47,sceKernelDelayThread +#endif +#ifdef F_ThreadManForUser_0021 + IMPORT_FUNC "ThreadManForUser",0x68DA9E36,sceKernelDelayThreadCB +#endif +#ifdef F_ThreadManForUser_0022 + IMPORT_FUNC "ThreadManForUser",0xBD123D9E,sceKernelDelaySysClockThread +#endif +#ifdef F_ThreadManForUser_0023 + IMPORT_FUNC "ThreadManForUser",0x1181E963,sceKernelDelaySysClockThreadCB +#endif +#ifdef F_ThreadManForUser_0024 + IMPORT_FUNC "ThreadManForUser",0xD6DA4BA1,sceKernelCreateSema +#endif +#ifdef F_ThreadManForUser_0025 + IMPORT_FUNC "ThreadManForUser",0x28B6489C,sceKernelDeleteSema +#endif +#ifdef F_ThreadManForUser_0026 + IMPORT_FUNC "ThreadManForUser",0x3F53E640,sceKernelSignalSema +#endif +#ifdef F_ThreadManForUser_0027 + IMPORT_FUNC "ThreadManForUser",0x4E3A1105,sceKernelWaitSema +#endif +#ifdef F_ThreadManForUser_0028 + IMPORT_FUNC "ThreadManForUser",0x6D212BAC,sceKernelWaitSemaCB +#endif +#ifdef F_ThreadManForUser_0029 + IMPORT_FUNC "ThreadManForUser",0x58B1F937,sceKernelPollSema +#endif +#ifdef F_ThreadManForUser_0030 + IMPORT_FUNC "ThreadManForUser",0x8FFDF9A2,sceKernelCancelSema +#endif +#ifdef F_ThreadManForUser_0031 + IMPORT_FUNC "ThreadManForUser",0xBC6FEBC5,sceKernelReferSemaStatus +#endif +#ifdef F_ThreadManForUser_0032 + IMPORT_FUNC "ThreadManForUser",0x55C20A00,sceKernelCreateEventFlag +#endif +#ifdef F_ThreadManForUser_0033 + IMPORT_FUNC "ThreadManForUser",0xEF9E4C70,sceKernelDeleteEventFlag +#endif +#ifdef F_ThreadManForUser_0034 + IMPORT_FUNC "ThreadManForUser",0x1FB15A32,sceKernelSetEventFlag +#endif +#ifdef F_ThreadManForUser_0035 + IMPORT_FUNC "ThreadManForUser",0x812346E4,sceKernelClearEventFlag +#endif +#ifdef F_ThreadManForUser_0036 + IMPORT_FUNC "ThreadManForUser",0x402FCF22,sceKernelWaitEventFlag +#endif +#ifdef F_ThreadManForUser_0037 + IMPORT_FUNC "ThreadManForUser",0x328C546A,sceKernelWaitEventFlagCB +#endif +#ifdef F_ThreadManForUser_0038 + IMPORT_FUNC "ThreadManForUser",0x30FD48F0,sceKernelPollEventFlag +#endif +#ifdef F_ThreadManForUser_0039 + IMPORT_FUNC "ThreadManForUser",0xCD203292,sceKernelCancelEventFlag +#endif +#ifdef F_ThreadManForUser_0040 + IMPORT_FUNC "ThreadManForUser",0xA66B0120,sceKernelReferEventFlagStatus +#endif +#ifdef F_ThreadManForUser_0041 + IMPORT_FUNC "ThreadManForUser",0x8125221D,sceKernelCreateMbx +#endif +#ifdef F_ThreadManForUser_0042 + IMPORT_FUNC "ThreadManForUser",0x86255ADA,sceKernelDeleteMbx +#endif +#ifdef F_ThreadManForUser_0043 + IMPORT_FUNC "ThreadManForUser",0xE9B3061E,sceKernelSendMbx +#endif +#ifdef F_ThreadManForUser_0044 + IMPORT_FUNC "ThreadManForUser",0x18260574,sceKernelReceiveMbx +#endif +#ifdef F_ThreadManForUser_0045 + IMPORT_FUNC "ThreadManForUser",0xF3986382,sceKernelReceiveMbxCB +#endif +#ifdef F_ThreadManForUser_0046 + IMPORT_FUNC "ThreadManForUser",0x0D81716A,sceKernelPollMbx +#endif +#ifdef F_ThreadManForUser_0047 + IMPORT_FUNC "ThreadManForUser",0x87D4DD36,sceKernelCancelReceiveMbx +#endif +#ifdef F_ThreadManForUser_0048 + IMPORT_FUNC "ThreadManForUser",0xA8E8C846,sceKernelReferMbxStatus +#endif +#ifdef F_ThreadManForUser_0049 + IMPORT_FUNC "ThreadManForUser",0x7C0DC2A0,sceKernelCreateMsgPipe +#endif +#ifdef F_ThreadManForUser_0050 + IMPORT_FUNC "ThreadManForUser",0xF0B7DA1C,sceKernelDeleteMsgPipe +#endif +#ifdef F_ThreadManForUser_0051 + IMPORT_FUNC "ThreadManForUser",0x876DBFAD,sceKernelSendMsgPipe +#endif +#ifdef F_ThreadManForUser_0052 + IMPORT_FUNC "ThreadManForUser",0x7C41F2C2,sceKernelSendMsgPipeCB +#endif +#ifdef F_ThreadManForUser_0053 + IMPORT_FUNC "ThreadManForUser",0x884C9F90,sceKernelTrySendMsgPipe +#endif +#ifdef F_ThreadManForUser_0054 + IMPORT_FUNC "ThreadManForUser",0x74829B76,sceKernelReceiveMsgPipe +#endif +#ifdef F_ThreadManForUser_0055 + IMPORT_FUNC "ThreadManForUser",0xFBFA697D,sceKernelReceiveMsgPipeCB +#endif +#ifdef F_ThreadManForUser_0056 + IMPORT_FUNC "ThreadManForUser",0xDF52098F,sceKernelTryReceiveMsgPipe +#endif +#ifdef F_ThreadManForUser_0057 + IMPORT_FUNC "ThreadManForUser",0x349B864D,sceKernelCancelMsgPipe +#endif +#ifdef F_ThreadManForUser_0058 + IMPORT_FUNC "ThreadManForUser",0x33BE4024,sceKernelReferMsgPipeStatus +#endif +#ifdef F_ThreadManForUser_0059 + IMPORT_FUNC "ThreadManForUser",0x56C039B5,sceKernelCreateVpl +#endif +#ifdef F_ThreadManForUser_0060 + IMPORT_FUNC "ThreadManForUser",0x89B3D48C,sceKernelDeleteVpl +#endif +#ifdef F_ThreadManForUser_0061 + IMPORT_FUNC "ThreadManForUser",0xBED27435,sceKernelAllocateVpl +#endif +#ifdef F_ThreadManForUser_0062 + IMPORT_FUNC "ThreadManForUser",0xEC0A693F,sceKernelAllocateVplCB +#endif +#ifdef F_ThreadManForUser_0063 + IMPORT_FUNC "ThreadManForUser",0xAF36D708,sceKernelTryAllocateVpl +#endif +#ifdef F_ThreadManForUser_0064 + IMPORT_FUNC "ThreadManForUser",0xB736E9FF,sceKernelFreeVpl +#endif +#ifdef F_ThreadManForUser_0065 + IMPORT_FUNC "ThreadManForUser",0x1D371B8A,sceKernelCancelVpl +#endif +#ifdef F_ThreadManForUser_0066 + IMPORT_FUNC "ThreadManForUser",0x39810265,sceKernelReferVplStatus +#endif +#ifdef F_ThreadManForUser_0067 + IMPORT_FUNC "ThreadManForUser",0xC07BB470,sceKernelCreateFpl +#endif +#ifdef F_ThreadManForUser_0068 + IMPORT_FUNC "ThreadManForUser",0xED1410E0,sceKernelDeleteFpl +#endif +#ifdef F_ThreadManForUser_0069 + IMPORT_FUNC "ThreadManForUser",0xD979E9BF,sceKernelAllocateFpl +#endif +#ifdef F_ThreadManForUser_0070 + IMPORT_FUNC "ThreadManForUser",0xE7282CB6,sceKernelAllocateFplCB +#endif +#ifdef F_ThreadManForUser_0071 + IMPORT_FUNC "ThreadManForUser",0x623AE665,sceKernelTryAllocateFpl +#endif +#ifdef F_ThreadManForUser_0072 + IMPORT_FUNC "ThreadManForUser",0xF6414A71,sceKernelFreeFpl +#endif +#ifdef F_ThreadManForUser_0073 + IMPORT_FUNC "ThreadManForUser",0xA8AA591F,sceKernelCancelFpl +#endif +#ifdef F_ThreadManForUser_0074 + IMPORT_FUNC "ThreadManForUser",0xD8199E4C,sceKernelReferFplStatus +#endif +#ifdef F_ThreadManForUser_0075 + IMPORT_FUNC "ThreadManForUser",0x0E927AED,_sceKernelReturnFromTimerHandler +#endif +#ifdef F_ThreadManForUser_0076 + IMPORT_FUNC "ThreadManForUser",0x110DEC9A,sceKernelUSec2SysClock +#endif +#ifdef F_ThreadManForUser_0077 + IMPORT_FUNC "ThreadManForUser",0xC8CD158C,sceKernelUSec2SysClockWide +#endif +#ifdef F_ThreadManForUser_0078 + IMPORT_FUNC "ThreadManForUser",0xBA6B92E2,sceKernelSysClock2USec +#endif +#ifdef F_ThreadManForUser_0079 + IMPORT_FUNC "ThreadManForUser",0xE1619D7C,sceKernelSysClock2USecWide +#endif +#ifdef F_ThreadManForUser_0080 + IMPORT_FUNC "ThreadManForUser",0xDB738F35,sceKernelGetSystemTime +#endif +#ifdef F_ThreadManForUser_0081 + IMPORT_FUNC "ThreadManForUser",0x82BC5777,sceKernelGetSystemTimeWide +#endif +#ifdef F_ThreadManForUser_0082 + IMPORT_FUNC "ThreadManForUser",0x369ED59D,sceKernelGetSystemTimeLow +#endif +#ifdef F_ThreadManForUser_0083 + IMPORT_FUNC "ThreadManForUser",0x6652B8CA,sceKernelSetAlarm +#endif +#ifdef F_ThreadManForUser_0084 + IMPORT_FUNC "ThreadManForUser",0xB2C25152,sceKernelSetSysClockAlarm +#endif +#ifdef F_ThreadManForUser_0085 + IMPORT_FUNC "ThreadManForUser",0x7E65B999,sceKernelCancelAlarm +#endif +#ifdef F_ThreadManForUser_0086 + IMPORT_FUNC "ThreadManForUser",0xDAA3F564,sceKernelReferAlarmStatus +#endif +#ifdef F_ThreadManForUser_0087 + IMPORT_FUNC "ThreadManForUser",0x20FFF560,sceKernelCreateVTimer +#endif +#ifdef F_ThreadManForUser_0088 + IMPORT_FUNC "ThreadManForUser",0x328F9E52,sceKernelDeleteVTimer +#endif +#ifdef F_ThreadManForUser_0089 + IMPORT_FUNC "ThreadManForUser",0xB3A59970,sceKernelGetVTimerBase +#endif +#ifdef F_ThreadManForUser_0090 + IMPORT_FUNC "ThreadManForUser",0xB7C18B77,sceKernelGetVTimerBaseWide +#endif +#ifdef F_ThreadManForUser_0091 + IMPORT_FUNC "ThreadManForUser",0x034A921F,sceKernelGetVTimerTime +#endif +#ifdef F_ThreadManForUser_0092 + IMPORT_FUNC "ThreadManForUser",0xC0B3FFD2,sceKernelGetVTimerTimeWide +#endif +#ifdef F_ThreadManForUser_0093 + IMPORT_FUNC "ThreadManForUser",0x542AD630,sceKernelSetVTimerTime +#endif +#ifdef F_ThreadManForUser_0094 + IMPORT_FUNC "ThreadManForUser",0xFB6425C3,sceKernelSetVTimerTimeWide +#endif +#ifdef F_ThreadManForUser_0095 + IMPORT_FUNC "ThreadManForUser",0xC68D9437,sceKernelStartVTimer +#endif +#ifdef F_ThreadManForUser_0096 + IMPORT_FUNC "ThreadManForUser",0xD0AEEE87,sceKernelStopVTimer +#endif +#ifdef F_ThreadManForUser_0097 + IMPORT_FUNC "ThreadManForUser",0xD8B299AE,sceKernelSetVTimerHandler +#endif +#ifdef F_ThreadManForUser_0098 + IMPORT_FUNC "ThreadManForUser",0x53B00E9A,sceKernelSetVTimerHandlerWide +#endif +#ifdef F_ThreadManForUser_0099 + IMPORT_FUNC "ThreadManForUser",0xD2D615EF,sceKernelCancelVTimerHandler +#endif +#ifdef F_ThreadManForUser_0100 + IMPORT_FUNC "ThreadManForUser",0x5F32BEAA,sceKernelReferVTimerStatus +#endif +#ifdef F_ThreadManForUser_0101 + IMPORT_FUNC "ThreadManForUser",0x446D8DE6,sceKernelCreateThread +#endif +#ifdef F_ThreadManForUser_0102 + IMPORT_FUNC "ThreadManForUser",0x9FA03CD3,sceKernelDeleteThread +#endif +#ifdef F_ThreadManForUser_0103 + IMPORT_FUNC "ThreadManForUser",0xF475845D,sceKernelStartThread +#endif +#ifdef F_ThreadManForUser_0104 + IMPORT_FUNC "ThreadManForUser",0x532A522E,_sceKernelExitThread +#endif +#ifdef F_ThreadManForUser_0105 + IMPORT_FUNC "ThreadManForUser",0xAA73C935,sceKernelExitThread +#endif +#ifdef F_ThreadManForUser_0106 + IMPORT_FUNC "ThreadManForUser",0x809CE29B,sceKernelExitDeleteThread +#endif +#ifdef F_ThreadManForUser_0107 + IMPORT_FUNC "ThreadManForUser",0x616403BA,sceKernelTerminateThread +#endif +#ifdef F_ThreadManForUser_0108 + IMPORT_FUNC "ThreadManForUser",0x383F7BCC,sceKernelTerminateDeleteThread +#endif +#ifdef F_ThreadManForUser_0109 + IMPORT_FUNC "ThreadManForUser",0x3AD58B8C,sceKernelSuspendDispatchThread +#endif +#ifdef F_ThreadManForUser_0110 + IMPORT_FUNC "ThreadManForUser",0x27E22EC2,sceKernelResumeDispatchThread +#endif +#ifdef F_ThreadManForUser_0111 + IMPORT_FUNC "ThreadManForUser",0xEA748E31,sceKernelChangeCurrentThreadAttr +#endif +#ifdef F_ThreadManForUser_0112 + IMPORT_FUNC "ThreadManForUser",0x71BC9871,sceKernelChangeThreadPriority +#endif +#ifdef F_ThreadManForUser_0113 + IMPORT_FUNC "ThreadManForUser",0x912354A7,sceKernelRotateThreadReadyQueue +#endif +#ifdef F_ThreadManForUser_0114 + IMPORT_FUNC "ThreadManForUser",0x2C34E053,sceKernelReleaseWaitThread +#endif +#ifdef F_ThreadManForUser_0115 + IMPORT_FUNC "ThreadManForUser",0x293B45B8,sceKernelGetThreadId +#endif +#ifdef F_ThreadManForUser_0116 + IMPORT_FUNC "ThreadManForUser",0x94AA61EE,sceKernelGetThreadCurrentPriority +#endif +#ifdef F_ThreadManForUser_0117 + IMPORT_FUNC "ThreadManForUser",0x3B183E26,sceKernelGetThreadExitStatus +#endif +#ifdef F_ThreadManForUser_0118 + IMPORT_FUNC "ThreadManForUser",0xD13BDE95,sceKernelCheckThreadStack +#endif +#ifdef F_ThreadManForUser_0119 + IMPORT_FUNC "ThreadManForUser",0x52089CA1,sceKernelGetThreadStackFreeSize +#endif +#ifdef F_ThreadManForUser_0120 + IMPORT_FUNC "ThreadManForUser",0x17C1684E,sceKernelReferThreadStatus +#endif +#ifdef F_ThreadManForUser_0121 + IMPORT_FUNC "ThreadManForUser",0xFFC36A14,sceKernelReferThreadRunStatus +#endif +#ifdef F_ThreadManForUser_0122 + IMPORT_FUNC "ThreadManForUser",0x627E6F3A,sceKernelReferSystemStatus +#endif +#ifdef F_ThreadManForUser_0123 + IMPORT_FUNC "ThreadManForUser",0x94416130,sceKernelGetThreadmanIdList +#endif +#ifdef F_ThreadManForUser_0124 + IMPORT_FUNC "ThreadManForUser",0x57CF62DD,sceKernelGetThreadmanIdType +#endif +#ifdef F_ThreadManForUser_0125 + IMPORT_FUNC "ThreadManForUser",0x64D4540E,sceKernelReferThreadProfiler +#endif +#ifdef F_ThreadManForUser_0126 + IMPORT_FUNC "ThreadManForUser",0x8218B4DD,sceKernelReferGlobalProfiler +#endif diff --git a/src/user/UtilsForUser.S b/src/user/UtilsForUser.S new file mode 100644 index 00000000..85c88419 --- /dev/null +++ b/src/user/UtilsForUser.S @@ -0,0 +1,79 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_UtilsForUser_0000 + IMPORT_START "UtilsForUser",0x40010000 +#endif +#ifdef F_UtilsForUser_0001 + IMPORT_FUNC "UtilsForUser",0xBFA98062,sceKernelDcacheInvalidateRange +#endif +#ifdef F_UtilsForUser_0002 + IMPORT_FUNC "UtilsForUser",0xC8186A58,sceKernelUtilsMd5Digest +#endif +#ifdef F_UtilsForUser_0003 + IMPORT_FUNC "UtilsForUser",0x9E5C5086,sceKernelUtilsMd5BlockInit +#endif +#ifdef F_UtilsForUser_0004 + IMPORT_FUNC "UtilsForUser",0x61E1E525,sceKernelUtilsMd5BlockUpdate +#endif +#ifdef F_UtilsForUser_0005 + IMPORT_FUNC "UtilsForUser",0xB8D24E78,sceKernelUtilsMd5BlockResult +#endif +#ifdef F_UtilsForUser_0006 + IMPORT_FUNC "UtilsForUser",0x840259F1,sceKernelUtilsSha1Digest +#endif +#ifdef F_UtilsForUser_0007 + IMPORT_FUNC "UtilsForUser",0xF8FCD5BA,sceKernelUtilsSha1BlockInit +#endif +#ifdef F_UtilsForUser_0008 + IMPORT_FUNC "UtilsForUser",0x346F6DA8,sceKernelUtilsSha1BlockUpdate +#endif +#ifdef F_UtilsForUser_0009 + IMPORT_FUNC "UtilsForUser",0x585F1C09,sceKernelUtilsSha1BlockResult +#endif +#ifdef F_UtilsForUser_0010 + IMPORT_FUNC "UtilsForUser",0xE860E75E,sceKernelUtilsMt19937Init +#endif +#ifdef F_UtilsForUser_0011 + IMPORT_FUNC "UtilsForUser",0x06FB8A63,sceKernelUtilsMt19937UInt +#endif +#ifdef F_UtilsForUser_0012 + IMPORT_FUNC "UtilsForUser",0x37FB5C42,sceKernelGetGPI +#endif +#ifdef F_UtilsForUser_0013 + IMPORT_FUNC "UtilsForUser",0x6AD345D7,sceKernelSetGPO +#endif +#ifdef F_UtilsForUser_0014 + IMPORT_FUNC "UtilsForUser",0x91E4F6A7,sceKernelLibcClock +#endif +#ifdef F_UtilsForUser_0015 + IMPORT_FUNC "UtilsForUser",0x27CC57F0,sceKernelLibcTime +#endif +#ifdef F_UtilsForUser_0016 + IMPORT_FUNC "UtilsForUser",0x71EC4271,sceKernelLibcGettimeofday +#endif +#ifdef F_UtilsForUser_0017 + IMPORT_FUNC "UtilsForUser",0x79D1C3FA,sceKernelDcacheWritebackAll +#endif +#ifdef F_UtilsForUser_0018 + IMPORT_FUNC "UtilsForUser",0xB435DEC5,sceKernelDcacheWritebackInvalidateAll +#endif +#ifdef F_UtilsForUser_0019 + IMPORT_FUNC "UtilsForUser",0x3EE30821,sceKernelDcacheWritebackRange +#endif +#ifdef F_UtilsForUser_0020 + IMPORT_FUNC "UtilsForUser",0x34B9FA9E,sceKernelDcacheWritebackInvalidateRange +#endif +#ifdef F_UtilsForUser_0021 + IMPORT_FUNC "UtilsForUser",0x80001C4C,sceKernelDcacheProbe +#endif +#ifdef F_UtilsForUser_0022 + IMPORT_FUNC "UtilsForUser",0x16641D70,sceKernelDcacheReadTag +#endif +#ifdef F_UtilsForUser_0023 + IMPORT_FUNC "UtilsForUser",0x4FD31C9D,sceKernelIcacheProbe +#endif +#ifdef F_UtilsForUser_0024 + IMPORT_FUNC "UtilsForUser",0xFB05FAD0,sceKernelIcacheReadTag +#endif diff --git a/src/user/pspintrman.c b/src/user/pspintrman.c new file mode 100644 index 00000000..d6c7867c --- /dev/null +++ b/src/user/pspintrman.c @@ -0,0 +1,25 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspintrman.c - Interface to the system interupt manager. + * + * Copyright (c) 2005 James F. (tyranid@gmail.com) + * Copyright (c) 2005 Florin Sasu (...) + * + * $Id: pspintrman.c 1207 2005-10-23 05:50:29Z mrbrown $ + */ + +#include + +const char* PspInterruptNames[67] = {//67 interrupts + 0, 0, 0, 0, "GPIO", "ATA_ATAPI", "UmdMan", "MScm0", + "Wlan", 0, "Audio", 0, "I2C", 0, "SIRCS_IrDA", + "Systimer0", "Systimer1", "Systimer2", "Systimer3", + "Thread0", "NAND", "DMACPLUS", "DMA0", "DMA1", + "Memlmd", "GE", 0, 0, 0, 0, "Display", "MeCodec", 0, + 0, 0, 0, "HP_Remote", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "MScm1", "MScm2", + 0, 0, 0, "Thread1", "Interrupt" +}; diff --git a/src/user/pspintrman.h b/src/user/pspintrman.h new file mode 100644 index 00000000..19abdf14 --- /dev/null +++ b/src/user/pspintrman.h @@ -0,0 +1,178 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspintrman.h - Interface to the system interrupt manager. + * + * Copyright (c) 2005 James F. (tyranid@gmail.com) + * Copyright (c) 2005 Florin Sasu (...) + * + * $Id: pspintrman.h 2433 2008-10-15 10:00:27Z iwn $ + */ + +#ifndef PSPINTRMAN_H +#define PSPINTRMAN_H + +#include + +/** @defgroup IntrMan Interrupt Manager + * This module contains routines to manage interrupts. + */ + +/** @addtogroup IntrMan Interrupt Manager */ +/*@{*/ + +#ifdef __cplusplus +extern "C" { +#endif + +extern const char* PspInterruptNames[67]; + +enum PspInterrupts +{ + PSP_GPIO_INT = 4, + PSP_ATA_INT = 5, + PSP_UMD_INT = 6, + PSP_MSCM0_INT = 7, + PSP_WLAN_INT = 8, + PSP_AUDIO_INT = 10, + PSP_I2C_INT = 12, + PSP_SIRCS_INT = 14, + PSP_SYSTIMER0_INT = 15, + PSP_SYSTIMER1_INT = 16, + PSP_SYSTIMER2_INT = 17, + PSP_SYSTIMER3_INT = 18, + PSP_THREAD0_INT = 19, + PSP_NAND_INT = 20, + PSP_DMACPLUS_INT = 21, + PSP_DMA0_INT = 22, + PSP_DMA1_INT = 23, + PSP_MEMLMD_INT = 24, + PSP_GE_INT = 25, + PSP_VBLANK_INT = 30, + PSP_MECODEC_INT = 31, + PSP_HPREMOTE_INT = 36, + PSP_MSCM1_INT = 60, + PSP_MSCM2_INT = 61, + PSP_THREAD1_INT = 65, + PSP_INTERRUPT_INT = 66 +}; + +enum PspSubInterrupts +{ + PSP_GPIO_SUBINT = PSP_GPIO_INT, + PSP_ATA_SUBINT = PSP_ATA_INT, + PSP_UMD_SUBINT = PSP_UMD_INT, + PSP_DMACPLUS_SUBINT = PSP_DMACPLUS_INT, + PSP_GE_SUBINT = PSP_GE_INT, + PSP_DISPLAY_SUBINT = PSP_VBLANK_INT +}; + +/** + * Suspend all interrupts. + * + * @return The current state of the interrupt controller, to be used with ::sceKernelCpuResumeIntr(). + */ +unsigned int sceKernelCpuSuspendIntr(void); + +/** + * Resume all interrupts. + * + * @param flags - The value returned from ::sceKernelCpuSuspendIntr(). + */ +void sceKernelCpuResumeIntr(unsigned int flags); + +/** + * Resume all interrupts (using sync instructions). + * + * @param flags - The value returned from ::sceKernelCpuSuspendIntr() + */ +void sceKernelCpuResumeIntrWithSync(unsigned int flags); + +/** + * Determine if interrupts are suspended or active, based on the given flags. + * + * @param flags - The value returned from ::sceKernelCpuSuspendIntr(). + * + * @return 1 if flags indicate that interrupts were not suspended, 0 otherwise. + */ +int sceKernelIsCpuIntrSuspended(unsigned int flags); + +/** + * Determine if interrupts are enabled or disabled. + * + * @return 1 if interrupts are currently enabled. + */ +int sceKernelIsCpuIntrEnable(void); + +/** + * Register a sub interrupt handler. + * + * @param intno - The interrupt number to register. + * @param no - The sub interrupt handler number (user controlled) + * @param handler - The interrupt handler + * @param arg - An argument passed to the interrupt handler + * + * @return < 0 on error. + */ +int sceKernelRegisterSubIntrHandler(int intno, int no, void *handler, void *arg); + +/** + * Release a sub interrupt handler. + * + * @param intno - The interrupt number to register. + * @param no - The sub interrupt handler number + * + * @return < 0 on error. + */ +int sceKernelReleaseSubIntrHandler(int intno, int no); + +/** + * Enable a sub interrupt. + * + * @param intno - The sub interrupt to enable. + * @param no - The sub interrupt handler number + * + * @return < 0 on error. + */ +int sceKernelEnableSubIntr(int intno, int no); + +/** + * Disable a sub interrupt handler. + * + * @param intno - The sub interrupt to disable. + * @param no - The sub interrupt handler number + * + * @return < 0 on error. + */ +int sceKernelDisableSubIntr(int intno, int no); + +typedef struct tag_IntrHandlerOptionParam{ + int size; //+00 + u32 entry; //+04 + u32 common; //+08 + u32 gp; //+0C + u16 intr_code; //+10 + u16 sub_count; //+12 + u16 intr_level; //+14 + u16 enabled; //+16 + u32 calls; //+18 + u32 field_1C; //+1C + u32 total_clock_lo; //+20 + u32 total_clock_hi; //+24 + u32 min_clock_lo; //+28 + u32 min_clock_hi; //+2C + u32 max_clock_lo; //+30 + u32 max_clock_hi; //+34 +} PspIntrHandlerOptionParam; //=38 + +int QueryIntrHandlerInfo(SceUID intr_code, SceUID sub_intr_code, PspIntrHandlerOptionParam *data); + +#ifdef __cplusplus +} +#endif + +/*@}*/ + +#endif /* PSPINTRMAN_H */ diff --git a/src/user/pspiofilemgr.h b/src/user/pspiofilemgr.h new file mode 100644 index 00000000..3490d84a --- /dev/null +++ b/src/user/pspiofilemgr.h @@ -0,0 +1,477 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspiofilemgr.h - Prototypes for the sceIo library. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: pspiofilemgr.h 1884 2006-04-30 08:55:54Z chip $ + */ +#ifndef __FILEIO_H__ +#define __FILEIO_H__ + +#include +#include +#include +#include + +/** @defgroup FileIO File IO Library + * This module contains the imports for the kernel's IO routines. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup FileIO File IO Library */ +/*@{*/ + +/** Permission value for the sceIoAssign function */ +enum IoAssignPerms +{ + /** Assign the device read/write */ + IOASSIGN_RDWR = 0, + /** Assign the device read only */ + IOASSIGN_RDONLY = 1 +}; + +/** + * Open or create a file for reading or writing + * + * @par Example1: Open a file for reading + * @code + * if(!(fd = sceIoOpen("device:/path/to/file", O_RDONLY, 0777)) { + * // error + * } + * @endcode + * @par Example2: Open a file for writing, creating it if it doesnt exist + * @code + * if(!(fd = sceIoOpen("device:/path/to/file", O_WRONLY|O_CREAT, 0777)) { + * // error + * } + * @endcode + * + * @param file - Pointer to a string holding the name of the file to open + * @param flags - Libc styled flags that are or'ed together + * @param mode - File access mode. + * @return A non-negative integer is a valid fd, anything else an error + */ +SceUID sceIoOpen(const char *file, int flags, SceMode mode); + +/** + * Open or create a file for reading or writing (asynchronous) + * + * @param file - Pointer to a string holding the name of the file to open + * @param flags - Libc styled flags that are or'ed together + * @param mode - File access mode. + * @return A non-negative integer is a valid fd, anything else an error + */ +SceUID sceIoOpenAsync(const char *file, int flags, SceMode mode); + +/** + * Delete a descriptor + * + * @code + * sceIoClose(fd); + * @endcode + * + * @param fd - File descriptor to close + * @return < 0 on error + */ +int sceIoClose(SceUID fd); + +/** + * Delete a descriptor (asynchronous) + * + * @param fd - File descriptor to close + * @return < 0 on error + */ +int sceIoCloseAsync(SceUID fd); + +/** + * Read input + * + * @par Example: + * @code + * bytes_read = sceIoRead(fd, data, 100); + * @endcode + * + * @param fd - Opened file descriptor to read from + * @param data - Pointer to the buffer where the read data will be placed + * @param size - Size of the read in bytes + * + * @return The number of bytes read + */ +int sceIoRead(SceUID fd, void *data, SceSize size); + +/** + * Read input (asynchronous) + * + * @par Example: + * @code + * bytes_read = sceIoRead(fd, data, 100); + * @endcode + * + * @param fd - Opened file descriptor to read from + * @param data - Pointer to the buffer where the read data will be placed + * @param size - Size of the read in bytes + * + * @return < 0 on error. + */ +int sceIoReadAsync(SceUID fd, void *data, SceSize size); + +/** + * Write output + * + * @par Example: + * @code + * bytes_written = sceIoWrite(fd, data, 100); + * @endcode + * + * @param fd - Opened file descriptor to write to + * @param data - Pointer to the data to write + * @param size - Size of data to write + * + * @return The number of bytes written + */ +int sceIoWrite(SceUID fd, const void *data, SceSize size); + +/** + * Write output (asynchronous) + * + * @param fd - Opened file descriptor to write to + * @param data - Pointer to the data to write + * @param size - Size of data to write + * + * @return < 0 on error. + */ +int sceIoWriteAsync(SceUID fd, const void *data, SceSize size); + +/** + * Reposition read/write file descriptor offset + * + * @par Example: + * @code + * pos = sceIoLseek(fd, -10, SEEK_END); + * @endcode + * + * @param fd - Opened file descriptor with which to seek + * @param offset - Relative offset from the start position given by whence + * @param whence - Set to SEEK_SET to seek from the start of the file, SEEK_CUR + * seek from the current position and SEEK_END to seek from the end. + * + * @return The position in the file after the seek. + */ +SceOff sceIoLseek(SceUID fd, SceOff offset, int whence); + +/** + * Reposition read/write file descriptor offset (asynchronous) + * + * @param fd - Opened file descriptor with which to seek + * @param offset - Relative offset from the start position given by whence + * @param whence - Set to SEEK_SET to seek from the start of the file, SEEK_CUR + * seek from the current position and SEEK_END to seek from the end. + * + * @return < 0 on error. Actual value should be passed returned by the ::sceIoWaitAsync call. + */ +int sceIoLseekAsync(SceUID fd, SceOff offset, int whence); + +/** + * Reposition read/write file descriptor offset (32bit mode) + * + * @par Example: + * @code + * pos = sceIoLseek32(fd, -10, SEEK_END); + * @endcode + * + * @param fd - Opened file descriptor with which to seek + * @param offset - Relative offset from the start position given by whence + * @param whence - Set to SEEK_SET to seek from the start of the file, SEEK_CUR + * seek from the current position and SEEK_END to seek from the end. + * + * @return The position in the file after the seek. + */ +int sceIoLseek32(SceUID fd, int offset, int whence); + +/** + * Reposition read/write file descriptor offset (32bit mode, asynchronous) + * + * @param fd - Opened file descriptor with which to seek + * @param offset - Relative offset from the start position given by whence + * @param whence - Set to SEEK_SET to seek from the start of the file, SEEK_CUR + * seek from the current position and SEEK_END to seek from the end. + * + * @return < 0 on error. + */ +int sceIoLseek32Async(SceUID fd, int offset, int whence); + +/** + * Remove directory entry + * + * @param file - Path to the file to remove + * @return < 0 on error + */ +int sceIoRemove(const char *file); + +/** + * Make a directory file + * + * @param dir + * @param mode - Access mode. + * @return Returns the value 0 if its succesful otherwise -1 + */ +int sceIoMkdir(const char *dir, SceMode mode); + +/** + * Remove a directory file + * + * @param path - Removes a directory file pointed by the string path + * @return Returns the value 0 if its succesful otherwise -1 + */ +int sceIoRmdir(const char *path); + +/** + * Change the current directory. + * + * @param path - The path to change to. + * @return < 0 on error. + */ +int sceIoChdir(const char *path); + +/** + * Change the name of a file + * + * @param oldname - The old filename + * @param newname - The new filename + * @return < 0 on error. + */ +int sceIoRename(const char *oldname, const char *newname); + +/** + * Open a directory + * + * @par Example: + * @code + * int dfd; + * dfd = sceIoDopen("device:/"); + * if(dfd >= 0) + * { Do something with the file descriptor } + * @endcode + * @param dirname - The directory to open for reading. + * @return If >= 0 then a valid file descriptor, otherwise a Sony error code. + */ +SceUID sceIoDopen(const char *dirname); + +/** + * Reads an entry from an opened file descriptor. + * + * @param fd - Already opened file descriptor (using sceIoDopen) + * @param dir - Pointer to an io_dirent_t structure to hold the file information + * + * @return Read status + * - 0 - No more directory entries left + * - > 0 - More directory entired to go + * - < 0 - Error + */ +int sceIoDread(SceUID fd, SceIoDirent *dir); + +/** + * Close an opened directory file descriptor + * + * @param fd - Already opened file descriptor (using sceIoDopen) + * @return < 0 on error + */ +int sceIoDclose(SceUID fd); + +/** + * Send a devctl command to a device. + * + * @par Example: Sending a simple command to a device (not a real devctl) + * @code + * sceIoDevctl("ms0:", 0x200000, indata, 4, NULL, NULL); + * @endcode + * + * @param dev - String for the device to send the devctl to (e.g. "ms0:") + * @param cmd - The command to send to the device + * @param indata - A data block to send to the device, if NULL sends no data + * @param inlen - Length of indata, if 0 sends no data + * @param outdata - A data block to receive the result of a command, if NULL receives no data + * @param outlen - Length of outdata, if 0 receives no data + * @return 0 on success, < 0 on error + */ +int sceIoDevctl(const char *dev, unsigned int cmd, void *indata, int inlen, void *outdata, int outlen); + +/** + * Assigns one IO device to another (I guess) + * @param dev1 - The device name to assign. + * @param dev2 - The block device to assign from. + * @param dev3 - The filesystem device to mape the block device to dev1 + * @param mode - Read/Write mode. One of IoAssignPerms. + * @param unk1 - Unknown, set to NULL. + * @param unk2 - Unknown, set to 0. + * @return < 0 on error. + * + * @par Example: Reassign flash0 in read/write mode. + * @code + * sceIoUnassign("flash0"); + * sceIoAssign("flash0", "lflash0:0,0", "flashfat0:", IOASSIGN_RDWR, NULL, 0); + * @endcode + * + */ +int sceIoAssign(const char *dev1, const char *dev2, const char *dev3, int mode, void* unk1, long unk2); + +/** + * Unassign an IO device. + * @param dev - The device to unassign. + * @return < 0 on error + * + * @par Example: See ::sceIoAssign + */ +int sceIoUnassign(const char *dev); + +/** + * Get the status of a file. + * + * @param file - The path to the file. + * @param stat - A pointer to an io_stat_t structure. + * + * @return < 0 on error. + */ +int sceIoGetstat(const char *file, SceIoStat *stat); + +/** + * Change the status of a file. + * + * @param file - The path to the file. + * @param stat - A pointer to an io_stat_t structure. + * @param bits - Bitmask defining which bits to change. + * + * @return < 0 on error. + */ +int sceIoChstat(const char *file, SceIoStat *stat, int bits); + +/** + * Perform an ioctl on a device. + * + * @param fd - Opened file descriptor to ioctl to + * @param cmd - The command to send to the device + * @param indata - A data block to send to the device, if NULL sends no data + * @param inlen - Length of indata, if 0 sends no data + * @param outdata - A data block to receive the result of a command, if NULL receives no data + * @param outlen - Length of outdata, if 0 receives no data + * @return 0 on success, < 0 on error + */ +int sceIoIoctl(SceUID fd, unsigned int cmd, void *indata, int inlen, void *outdata, int outlen); + +/** + * Perform an ioctl on a device. (asynchronous) + * + * @param fd - Opened file descriptor to ioctl to + * @param cmd - The command to send to the device + * @param indata - A data block to send to the device, if NULL sends no data + * @param inlen - Length of indata, if 0 sends no data + * @param outdata - A data block to receive the result of a command, if NULL receives no data + * @param outlen - Length of outdata, if 0 receives no data + * @return 0 on success, < 0 on error + */ +int sceIoIoctlAsync(SceUID fd, unsigned int cmd, void *indata, int inlen, void *outdata, int outlen); + +/** + * Synchronise the file data on the device. + * + * @param device - The device to synchronise (e.g. msfat0:) + * @param unk - Unknown + */ +int sceIoSync(const char *device, unsigned int unk); + +/** + * Wait for asyncronous completion. + * + * @param fd - The file descriptor which is current performing an asynchronous action. + * @param res - The result of the async action. + * + * @return < 0 on error. + */ +int sceIoWaitAsync(SceUID fd, SceInt64 *res); + +/** + * Wait for asyncronous completion (with callbacks). + * + * @param fd - The file descriptor which is current performing an asynchronous action. + * @param res - The result of the async action. + * + * @return < 0 on error. + */ +int sceIoWaitAsyncCB(SceUID fd, SceInt64 *res); + +/** + * Poll for asyncronous completion. + * + * @param fd - The file descriptor which is current performing an asynchronous action. + * @param res - The result of the async action. + * + * @return < 0 on error. + */ +int sceIoPollAsync(SceUID fd, SceInt64 *res); + +/** + * Get the asyncronous completion status. + * + * @param fd - The file descriptor which is current performing an asynchronous action. + * @param poll - If 0 then waits for the status, otherwise it polls the fd. + * @param res - The result of the async action. + * + * @return < 0 on error. + */ +int sceIoGetAsyncStat(SceUID fd, int poll, SceInt64 *res); + +/** + * Cancel an asynchronous operation on a file descriptor. + * + * @param fd - The file descriptor to perform cancel on. + * + * @return < 0 on error. + */ +int sceIoCancel(SceUID fd); + +/** + * Get the device type of the currently opened file descriptor. + * + * @param fd - The opened file descriptor. + * + * @return < 0 on error. Otherwise the device type? + */ +int sceIoGetDevType(SceUID fd); + +/** + * Change the priority of the asynchronous thread. + * + * @param fd - The opened fd on which the priority should be changed. + * @param pri - The priority of the thread. + * + * @return < 0 on error. + */ +int sceIoChangeAsyncPriority(SceUID fd, int pri); + +/** + * Sets a callback for the asynchronous action. + * + * @param fd - The filedescriptor currently performing an asynchronous action. + * @param cb - The UID of the callback created with ::sceKernelCreateCallback + * @param argp - Pointer to an argument to pass to the callback. + * + * @return < 0 on error. + */ +int sceIoSetAsyncCallback(SceUID fd, SceUID cb, void *argp); + +/*@}*/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/user/pspiofilemgr_dirent.h b/src/user/pspiofilemgr_dirent.h new file mode 100644 index 00000000..3b29806e --- /dev/null +++ b/src/user/pspiofilemgr_dirent.h @@ -0,0 +1,35 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspiofilemgr_dirent.h - File attributes and directory entries. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: pspiofilemgr_dirent.h 1172 2005-10-20 09:08:04Z jim $ + */ + +/* Note: Some of the structures, types, and definitions in this file were + extrapolated from symbolic debugging information found in the Japanese + version of Puzzle Bobble. */ + +#ifndef PSPIOFILEMGR_DIRENT_H +#define PSPIOFILEMGR_DIRENT_H + +#include + +/** Describes a single directory entry */ +typedef struct SceIoDirent { + /** File status. */ + SceIoStat d_stat; + /** File name. */ + char d_name[256]; + /** Device-specific data. */ + void * d_private; + int dummy; +} SceIoDirent; + +#endif /* PSPIOFILEMGR_DIRENT_H */ diff --git a/src/user/pspiofilemgr_fcntl.h b/src/user/pspiofilemgr_fcntl.h new file mode 100644 index 00000000..445bf0a8 --- /dev/null +++ b/src/user/pspiofilemgr_fcntl.h @@ -0,0 +1,34 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspiofilemgr_fcntl.h - File control definitions. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: pspiofilemgr_fcntl.h 559 2005-07-09 08:47:52Z mrbrown $ + */ +#ifndef PSPIOFILEMGR_FCNTL_H +#define PSPIOFILEMGR_FCNTL_H + +/* Note: Not all of these sceIoOpen() flags are not compatible with the + open() flags found in sys/unistd.h. */ +#define PSP_O_RDONLY 0x0001 +#define PSP_O_WRONLY 0x0002 +#define PSP_O_RDWR (PSP_O_RDONLY | PSP_O_WRONLY) +#define PSP_O_NBLOCK 0x0004 +#define PSP_O_DIROPEN 0x0008 // Internal use for dopen +#define PSP_O_APPEND 0x0100 +#define PSP_O_CREAT 0x0200 +#define PSP_O_TRUNC 0x0400 +#define PSP_O_EXCL 0x0800 +#define PSP_O_NOWAIT 0x8000 + +#define PSP_SEEK_SET 0 +#define PSP_SEEK_CUR 1 +#define PSP_SEEK_END 2 + +#endif /* PSPIOFILEMGR_FCNTL_H */ diff --git a/src/user/pspiofilemgr_stat.h b/src/user/pspiofilemgr_stat.h new file mode 100644 index 00000000..746dcfbd --- /dev/null +++ b/src/user/pspiofilemgr_stat.h @@ -0,0 +1,118 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspiofilemgr_dirent.h - File attributes and directory entries. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: pspiofilemgr_stat.h 1095 2005-09-27 21:02:16Z jim $ + */ + +/* Note: Some of the structures, types, and definitions in this file were + extrapolated from symbolic debugging information found in the Japanese + version of Puzzle Bobble. */ + +#ifndef PSPIOFILEMGR_STAT_H +#define PSPIOFILEMGR_STAT_H + +#include +#include + +/** Access modes for st_mode in SceIoStat (confirm?). */ +enum IOAccessModes +{ + /** Format bits mask */ + FIO_S_IFMT = 0xF000, + /** Symbolic link */ + FIO_S_IFLNK = 0x4000, + /** Directory */ + FIO_S_IFDIR = 0x1000, + /** Regular file */ + FIO_S_IFREG = 0x2000, + + /** Set UID */ + FIO_S_ISUID = 0x0800, + /** Set GID */ + FIO_S_ISGID = 0x0400, + /** Sticky */ + FIO_S_ISVTX = 0x0200, + + /** User access rights mask */ + FIO_S_IRWXU = 0x01C0, + /** Read user permission */ + FIO_S_IRUSR = 0x0100, + /** Write user permission */ + FIO_S_IWUSR = 0x0080, + /** Execute user permission */ + FIO_S_IXUSR = 0x0040, + + /** Group access rights mask */ + FIO_S_IRWXG = 0x0038, + /** Group read permission */ + FIO_S_IRGRP = 0x0020, + /** Group write permission */ + FIO_S_IWGRP = 0x0010, + /** Group execute permission */ + FIO_S_IXGRP = 0x0008, + + /** Others access rights mask */ + FIO_S_IRWXO = 0x0007, + /** Others read permission */ + FIO_S_IROTH = 0x0004, + /** Others write permission */ + FIO_S_IWOTH = 0x0002, + /** Others execute permission */ + FIO_S_IXOTH = 0x0001, +}; + +// File mode checking macros +#define FIO_S_ISLNK(m) (((m) & FIO_S_IFMT) == FIO_S_IFLNK) +#define FIO_S_ISREG(m) (((m) & FIO_S_IFMT) == FIO_S_IFREG) +#define FIO_S_ISDIR(m) (((m) & FIO_S_IFMT) == FIO_S_IFDIR) + +/** File modes, used for the st_attr parameter in SceIoStat (confirm?). */ +enum IOFileModes +{ + /** Format mask */ + FIO_SO_IFMT = 0x0038, // Format mask + /** Symlink */ + FIO_SO_IFLNK = 0x0008, // Symbolic link + /** Directory */ + FIO_SO_IFDIR = 0x0010, // Directory + /** Regular file */ + FIO_SO_IFREG = 0x0020, // Regular file + + /** Hidden read permission */ + FIO_SO_IROTH = 0x0004, // read + /** Hidden write permission */ + FIO_SO_IWOTH = 0x0002, // write + /** Hidden execute permission */ + FIO_SO_IXOTH = 0x0001, // execute +}; + +// File mode checking macros +#define FIO_SO_ISLNK(m) (((m) & FIO_SO_IFMT) == FIO_SO_IFLNK) +#define FIO_SO_ISREG(m) (((m) & FIO_SO_IFMT) == FIO_SO_IFREG) +#define FIO_SO_ISDIR(m) (((m) & FIO_SO_IFMT) == FIO_SO_IFDIR) + +/** Structure to hold the status information about a file */ +typedef struct SceIoStat { + SceMode st_mode; + unsigned int st_attr; + /** Size of the file in bytes. */ + SceOff st_size; + /** Creation time. */ + ScePspDateTime st_ctime; + /** Access time. */ + ScePspDateTime st_atime; + /** Modification time. */ + ScePspDateTime st_mtime; + /** Device-specific data. */ + unsigned int st_private[6]; +} SceIoStat; + +#endif /* PSPIOFILEMGR_STAT_H */ diff --git a/src/user/pspkerneltypes.h b/src/user/pspkerneltypes.h new file mode 100644 index 00000000..81c77bee --- /dev/null +++ b/src/user/pspkerneltypes.h @@ -0,0 +1,39 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspkerneltypes.h - PSP kernel types and definitions. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: pspkerneltypes.h 1884 2006-04-30 08:55:54Z chip $ + */ + +/* Note: Some of the structures, types, and definitions in this file were + extrapolated from symbolic debugging information found in the Japanese + version of Puzzle Bobble. */ + +#ifndef PSPKERNELTYPES_H +#define PSPKERNELTYPES_H + +#include + +/** UIDs are used to describe many different kernel objects. */ +typedef int SceUID; + +/* Misc. kernel types. */ +typedef unsigned int SceSize; +typedef int SceSSize; + +typedef unsigned char SceUChar; +typedef unsigned int SceUInt; + +/* File I/O types. */ +typedef int SceMode; +typedef SceInt64 SceOff; +typedef SceInt64 SceIores; + +#endif /* PSPKERNELTYPES_H */ diff --git a/src/user/pspkerror.h b/src/user/pspkerror.h new file mode 100644 index 00000000..b4f755e7 --- /dev/null +++ b/src/user/pspkerror.h @@ -0,0 +1,221 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspkerror.h - Definitions for the kernel error codes + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: pspkerror.h 1095 2005-09-27 21:02:16Z jim $ + */ +#ifndef PSPKERROR_H +#define PSPKERROR_H + +/* Note: The error code enumerations in this file were extrapolated from + symbolic debugging information found in the Japanese version of Puzzle Bobble. */ + +enum PspKernelErrorCodes +{ + SCE_KERNEL_ERROR_OK = 0, + SCE_KERNEL_ERROR_ERROR = 0x80020001, + SCE_KERNEL_ERROR_NOTIMP = 0x80020002, + SCE_KERNEL_ERROR_ILLEGAL_EXPCODE = 0x80020032, + SCE_KERNEL_ERROR_EXPHANDLER_NOUSE = 0x80020033, + SCE_KERNEL_ERROR_EXPHANDLER_USED = 0x80020034, + SCE_KERNEL_ERROR_SYCALLTABLE_NOUSED = 0x80020035, + SCE_KERNEL_ERROR_SYCALLTABLE_USED = 0x80020036, + SCE_KERNEL_ERROR_ILLEGAL_SYSCALLTABLE = 0x80020037, + SCE_KERNEL_ERROR_ILLEGAL_PRIMARY_SYSCALL_NUMBER = 0x80020038, + SCE_KERNEL_ERROR_PRIMARY_SYSCALL_NUMBER_INUSE = 0x80020039, + SCE_KERNEL_ERROR_ILLEGAL_CONTEXT = 0x80020064, + SCE_KERNEL_ERROR_ILLEGAL_INTRCODE = 0x80020065, + SCE_KERNEL_ERROR_CPUDI = 0x80020066, + SCE_KERNEL_ERROR_FOUND_HANDLER = 0x80020067, + SCE_KERNEL_ERROR_NOTFOUND_HANDLER = 0x80020068, + SCE_KERNEL_ERROR_ILLEGAL_INTRLEVEL = 0x80020069, + SCE_KERNEL_ERROR_ILLEGAL_ADDRESS = 0x8002006a, + SCE_KERNEL_ERROR_ILLEGAL_INTRPARAM = 0x8002006b, + SCE_KERNEL_ERROR_ILLEGAL_STACK_ADDRESS = 0x8002006c, + SCE_KERNEL_ERROR_ALREADY_STACK_SET = 0x8002006d, + SCE_KERNEL_ERROR_NO_TIMER = 0x80020096, + SCE_KERNEL_ERROR_ILLEGAL_TIMERID = 0x80020097, + SCE_KERNEL_ERROR_ILLEGAL_SOURCE = 0x80020098, + SCE_KERNEL_ERROR_ILLEGAL_PRESCALE = 0x80020099, + SCE_KERNEL_ERROR_TIMER_BUSY = 0x8002009a, + SCE_KERNEL_ERROR_TIMER_NOT_SETUP = 0x8002009b, + SCE_KERNEL_ERROR_TIMER_NOT_INUSE = 0x8002009c, + SCE_KERNEL_ERROR_UNIT_USED = 0x800200a0, + SCE_KERNEL_ERROR_UNIT_NOUSE = 0x800200a1, + SCE_KERNEL_ERROR_NO_ROMDIR = 0x800200a2, + SCE_KERNEL_ERROR_IDTYPE_EXIST = 0x800200c8, + SCE_KERNEL_ERROR_IDTYPE_NOT_EXIST = 0x800200c9, + SCE_KERNEL_ERROR_IDTYPE_NOT_EMPTY = 0x800200ca, + SCE_KERNEL_ERROR_UNKNOWN_UID = 0x800200cb, + SCE_KERNEL_ERROR_UNMATCH_UID_TYPE = 0x800200cc, + SCE_KERNEL_ERROR_ID_NOT_EXIST = 0x800200cd, + SCE_KERNEL_ERROR_NOT_FOUND_UIDFUNC = 0x800200ce, + SCE_KERNEL_ERROR_UID_ALREADY_HOLDER = 0x800200cf, + SCE_KERNEL_ERROR_UID_NOT_HOLDER = 0x800200d0, + SCE_KERNEL_ERROR_ILLEGAL_PERM = 0x800200d1, + SCE_KERNEL_ERROR_ILLEGAL_ARGUMENT = 0x800200d2, + SCE_KERNEL_ERROR_ILLEGAL_ADDR = 0x800200d3, + SCE_KERNEL_ERROR_OUT_OF_RANGE = 0x800200d4, + SCE_KERNEL_ERROR_MEM_RANGE_OVERLAP = 0x800200d5, + SCE_KERNEL_ERROR_ILLEGAL_PARTITION = 0x800200d6, + SCE_KERNEL_ERROR_PARTITION_INUSE = 0x800200d7, + SCE_KERNEL_ERROR_ILLEGAL_MEMBLOCKTYPE = 0x800200d8, + SCE_KERNEL_ERROR_MEMBLOCK_ALLOC_FAILED = 0x800200d9, + SCE_KERNEL_ERROR_MEMBLOCK_RESIZE_LOCKED = 0x800200da, + SCE_KERNEL_ERROR_MEMBLOCK_RESIZE_FAILED = 0x800200db, + SCE_KERNEL_ERROR_HEAPBLOCK_ALLOC_FAILED = 0x800200dc, + SCE_KERNEL_ERROR_HEAP_ALLOC_FAILED = 0x800200dd, + SCE_KERNEL_ERROR_ILLEGAL_CHUNK_ID = 0x800200de, + SCE_KERNEL_ERROR_NOCHUNK = 0x800200df, + SCE_KERNEL_ERROR_NO_FREECHUNK = 0x800200e0, + SCE_KERNEL_ERROR_LINKERR = 0x8002012c, + SCE_KERNEL_ERROR_ILLEGAL_OBJECT = 0x8002012d, + SCE_KERNEL_ERROR_UNKNOWN_MODULE = 0x8002012e, + SCE_KERNEL_ERROR_NOFILE = 0x8002012f, + SCE_KERNEL_ERROR_FILEERR = 0x80020130, + SCE_KERNEL_ERROR_MEMINUSE = 0x80020131, + SCE_KERNEL_ERROR_PARTITION_MISMATCH = 0x80020132, + SCE_KERNEL_ERROR_ALREADY_STARTED = 0x80020133, + SCE_KERNEL_ERROR_NOT_STARTED = 0x80020134, + SCE_KERNEL_ERROR_ALREADY_STOPPED = 0x80020135, + SCE_KERNEL_ERROR_CAN_NOT_STOP = 0x80020136, + SCE_KERNEL_ERROR_NOT_STOPPED = 0x80020137, + SCE_KERNEL_ERROR_NOT_REMOVABLE = 0x80020138, + SCE_KERNEL_ERROR_EXCLUSIVE_LOAD = 0x80020139, + SCE_KERNEL_ERROR_LIBRARY_NOT_YET_LINKED = 0x8002013a, + SCE_KERNEL_ERROR_LIBRARY_FOUND = 0x8002013b, + SCE_KERNEL_ERROR_LIBRARY_NOTFOUND = 0x8002013c, + SCE_KERNEL_ERROR_ILLEGAL_LIBRARY = 0x8002013d, + SCE_KERNEL_ERROR_LIBRARY_INUSE = 0x8002013e, + SCE_KERNEL_ERROR_ALREADY_STOPPING = 0x8002013f, + SCE_KERNEL_ERROR_ILLEGAL_OFFSET = 0x80020140, + SCE_KERNEL_ERROR_ILLEGAL_POSITION = 0x80020141, + SCE_KERNEL_ERROR_ILLEGAL_ACCESS = 0x80020142, + SCE_KERNEL_ERROR_MODULE_MGR_BUSY = 0x80020143, + SCE_KERNEL_ERROR_ILLEGAL_FLAG = 0x80020144, + SCE_KERNEL_ERROR_CANNOT_GET_MODULELIST = 0x80020145, + SCE_KERNEL_ERROR_PROHIBIT_LOADMODULE_DEVICE = 0x80020146, + SCE_KERNEL_ERROR_PROHIBIT_LOADEXEC_DEVICE = 0x80020147, + SCE_KERNEL_ERROR_UNSUPPORTED_PRX_TYPE = 0x80020148, + SCE_KERNEL_ERROR_ILLEGAL_PERM_CALL = 0x80020149, + SCE_KERNEL_ERROR_CANNOT_GET_MODULE_INFORMATION = 0x8002014a, + SCE_KERNEL_ERROR_ILLEGAL_LOADEXEC_BUFFER = 0x8002014b, + SCE_KERNEL_ERROR_ILLEGAL_LOADEXEC_FILENAME = 0x8002014c, + SCE_KERNEL_ERROR_NO_EXIT_CALLBACK = 0x8002014d, + SCE_KERNEL_ERROR_NO_MEMORY = 0x80020190, + SCE_KERNEL_ERROR_ILLEGAL_ATTR = 0x80020191, + SCE_KERNEL_ERROR_ILLEGAL_ENTRY = 0x80020192, + SCE_KERNEL_ERROR_ILLEGAL_PRIORITY = 0x80020193, + SCE_KERNEL_ERROR_ILLEGAL_STACK_SIZE = 0x80020194, + SCE_KERNEL_ERROR_ILLEGAL_MODE = 0x80020195, + SCE_KERNEL_ERROR_ILLEGAL_MASK = 0x80020196, + SCE_KERNEL_ERROR_ILLEGAL_THID = 0x80020197, + SCE_KERNEL_ERROR_UNKNOWN_THID = 0x80020198, + SCE_KERNEL_ERROR_UNKNOWN_SEMID = 0x80020199, + SCE_KERNEL_ERROR_UNKNOWN_EVFID = 0x8002019a, + SCE_KERNEL_ERROR_UNKNOWN_MBXID = 0x8002019b, + SCE_KERNEL_ERROR_UNKNOWN_VPLID = 0x8002019c, + SCE_KERNEL_ERROR_UNKNOWN_FPLID = 0x8002019d, + SCE_KERNEL_ERROR_UNKNOWN_MPPID = 0x8002019e, + SCE_KERNEL_ERROR_UNKNOWN_ALMID = 0x8002019f, + SCE_KERNEL_ERROR_UNKNOWN_TEID = 0x800201a0, + SCE_KERNEL_ERROR_UNKNOWN_CBID = 0x800201a1, + SCE_KERNEL_ERROR_DORMANT = 0x800201a2, + SCE_KERNEL_ERROR_SUSPEND = 0x800201a3, + SCE_KERNEL_ERROR_NOT_DORMANT = 0x800201a4, + SCE_KERNEL_ERROR_NOT_SUSPEND = 0x800201a5, + SCE_KERNEL_ERROR_NOT_WAIT = 0x800201a6, + SCE_KERNEL_ERROR_CAN_NOT_WAIT = 0x800201a7, + SCE_KERNEL_ERROR_WAIT_TIMEOUT = 0x800201a8, + SCE_KERNEL_ERROR_WAIT_CANCEL = 0x800201a9, + SCE_KERNEL_ERROR_RELEASE_WAIT = 0x800201aa, + SCE_KERNEL_ERROR_NOTIFY_CALLBACK = 0x800201ab, + SCE_KERNEL_ERROR_THREAD_TERMINATED = 0x800201ac, + SCE_KERNEL_ERROR_SEMA_ZERO = 0x800201ad, + SCE_KERNEL_ERROR_SEMA_OVF = 0x800201ae, + SCE_KERNEL_ERROR_EVF_COND = 0x800201af, + SCE_KERNEL_ERROR_EVF_MULTI = 0x800201b0, + SCE_KERNEL_ERROR_EVF_ILPAT = 0x800201b1, + SCE_KERNEL_ERROR_MBOX_NOMSG = 0x800201b2, + SCE_KERNEL_ERROR_MPP_FULL = 0x800201b3, + SCE_KERNEL_ERROR_MPP_EMPTY = 0x800201b4, + SCE_KERNEL_ERROR_WAIT_DELETE = 0x800201b5, + SCE_KERNEL_ERROR_ILLEGAL_MEMBLOCK = 0x800201b6, + SCE_KERNEL_ERROR_ILLEGAL_MEMSIZE = 0x800201b7, + SCE_KERNEL_ERROR_ILLEGAL_SPADADDR = 0x800201b8, + SCE_KERNEL_ERROR_SPAD_INUSE = 0x800201b9, + SCE_KERNEL_ERROR_SPAD_NOT_INUSE = 0x800201ba, + SCE_KERNEL_ERROR_ILLEGAL_TYPE = 0x800201bb, + SCE_KERNEL_ERROR_ILLEGAL_SIZE = 0x800201bc, + SCE_KERNEL_ERROR_ILLEGAL_COUNT = 0x800201bd, + SCE_KERNEL_ERROR_UNKNOWN_VTID = 0x800201be, + SCE_KERNEL_ERROR_ILLEGAL_VTID = 0x800201bf, + SCE_KERNEL_ERROR_ILLEGAL_KTLSID = 0x800201c0, + SCE_KERNEL_ERROR_KTLS_FULL = 0x800201c1, + SCE_KERNEL_ERROR_KTLS_BUSY = 0x800201c2, + SCE_KERNEL_ERROR_PM_INVALID_PRIORITY = 0x80020258, + SCE_KERNEL_ERROR_PM_INVALID_DEVNAME = 0x80020259, + SCE_KERNEL_ERROR_PM_UNKNOWN_DEVNAME = 0x8002025a, + SCE_KERNEL_ERROR_PM_PMINFO_REGISTERED = 0x8002025b, + SCE_KERNEL_ERROR_PM_PMINFO_UNREGISTERED = 0x8002025c, + SCE_KERNEL_ERROR_PM_INVALID_MAJOR_STATE = 0x8002025d, + SCE_KERNEL_ERROR_PM_INVALID_REQUEST = 0x8002025e, + SCE_KERNEL_ERROR_PM_UNKNOWN_REQUEST = 0x8002025f, + SCE_KERNEL_ERROR_PM_INVALID_UNIT = 0x80020260, + SCE_KERNEL_ERROR_PM_CANNOT_CANCEL = 0x80020261, + SCE_KERNEL_ERROR_PM_INVALID_PMINFO = 0x80020262, + SCE_KERNEL_ERROR_PM_INVALID_ARGUMENT = 0x80020263, + SCE_KERNEL_ERROR_PM_ALREADY_TARGET_PWRSTATE = 0x80020264, + SCE_KERNEL_ERROR_PM_CHANGE_PWRSTATE_FAILED = 0x80020265, + SCE_KERNEL_ERROR_PM_CANNOT_CHANGE_DEVPWR_STATE = 0x80020266, + SCE_KERNEL_ERROR_PM_NO_SUPPORT_DEVPWR_STATE = 0x80020267, + SCE_KERNEL_ERROR_DMAC_REQUEST_FAILED = 0x800202bc, + SCE_KERNEL_ERROR_DMAC_REQUEST_DENIED = 0x800202bd, + SCE_KERNEL_ERROR_DMAC_OP_QUEUED = 0x800202be, + SCE_KERNEL_ERROR_DMAC_OP_NOT_QUEUED = 0x800202bf, + SCE_KERNEL_ERROR_DMAC_OP_RUNNING = 0x800202c0, + SCE_KERNEL_ERROR_DMAC_OP_NOT_ASSIGNED = 0x800202c1, + SCE_KERNEL_ERROR_DMAC_OP_TIMEOUT = 0x800202c2, + SCE_KERNEL_ERROR_DMAC_OP_FREED = 0x800202c3, + SCE_KERNEL_ERROR_DMAC_OP_USED = 0x800202c4, + SCE_KERNEL_ERROR_DMAC_OP_EMPTY = 0x800202c5, + SCE_KERNEL_ERROR_DMAC_OP_ABORTED = 0x800202c6, + SCE_KERNEL_ERROR_DMAC_OP_ERROR = 0x800202c7, + SCE_KERNEL_ERROR_DMAC_CHANNEL_RESERVED = 0x800202c8, + SCE_KERNEL_ERROR_DMAC_CHANNEL_EXCLUDED = 0x800202c9, + SCE_KERNEL_ERROR_DMAC_PRIVILEGE_ADDRESS = 0x800202ca, + SCE_KERNEL_ERROR_DMAC_NO_ENOUGHSPACE = 0x800202cb, + SCE_KERNEL_ERROR_DMAC_CHANNEL_NOT_ASSIGNED = 0x800202cc, + SCE_KERNEL_ERROR_DMAC_CHILD_OPERATION = 0x800202cd, + SCE_KERNEL_ERROR_DMAC_TOO_MUCH_SIZE = 0x800202ce, + SCE_KERNEL_ERROR_DMAC_INVALID_ARGUMENT = 0x800202cf, + SCE_KERNEL_ERROR_MFILE = 0x80020320, + SCE_KERNEL_ERROR_NODEV = 0x80020321, + SCE_KERNEL_ERROR_XDEV = 0x80020322, + SCE_KERNEL_ERROR_BADF = 0x80020323, + SCE_KERNEL_ERROR_INVAL = 0x80020324, + SCE_KERNEL_ERROR_UNSUP = 0x80020325, + SCE_KERNEL_ERROR_ALIAS_USED = 0x80020326, + SCE_KERNEL_ERROR_CANNOT_MOUNT = 0x80020327, + SCE_KERNEL_ERROR_DRIVER_DELETED = 0x80020328, + SCE_KERNEL_ERROR_ASYNC_BUSY = 0x80020329, + SCE_KERNEL_ERROR_NOASYNC = 0x8002032a, + SCE_KERNEL_ERROR_REGDEV = 0x8002032b, + SCE_KERNEL_ERROR_NOCWD = 0x8002032c, + SCE_KERNEL_ERROR_NAMETOOLONG = 0x8002032d, + SCE_KERNEL_ERROR_NXIO = 0x800203e8, + SCE_KERNEL_ERROR_IO = 0x800203e9, + SCE_KERNEL_ERROR_NOMEM = 0x800203ea, + SCE_KERNEL_ERROR_STDIO_NOT_OPENED = 0x800203eb, + SCE_KERNEL_ERROR_CACHE_ALIGNMENT = 0x8002044c, + SCE_KERNEL_ERROR_ERRORMAX = 0x8002044d, +}; + +#endif /* PSPKERROR_H */ diff --git a/src/user/psploadexec.h b/src/user/psploadexec.h new file mode 100644 index 00000000..1325744b --- /dev/null +++ b/src/user/psploadexec.h @@ -0,0 +1,88 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * psploadexec.h - Process load and exit related functions. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: psploadexec.h 835 2005-08-09 05:41:25Z tyranid $ + */ + +/* Note: Some of the structures, types, and definitions in this file were + extrapolated from symbolic debugging information found in the Japanese + version of Puzzle Bobble. */ + +#ifndef __LOADEXEC_H__ +#define __LOADEXEC_H__ + +/** @defgroup LoadExec LoadExec Library */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup LoadExec */ + +/*@{*/ + +/** + * Register callback + * + * @note By installing the exit callback the home button becomes active. However if sceKernelExitGame + * is not called in the callback it is likely that the psp will just crash. + * + * @par Example: + * @code + * int exit_callback(void) { sceKernelExitGame(); } + * + * cbid = sceKernelCreateCallback("ExitCallback", exit_callback, NULL); + * sceKernelRegisterExitCallback(cbid); + * @endcode + * + * @param cbid Callback id + * @return < 0 on error + */ +int sceKernelRegisterExitCallback(int cbid); + +/** + * Exit game and go back to the PSP browser. + * + * @note You need to be in a thread in order for this function to work + * + */ +void sceKernelExitGame(void); + +/** Structure to pass to loadexec */ +struct SceKernelLoadExecParam { + /** Size of the structure */ + SceSize size; + /** Size of the arg string */ + SceSize args; + /** Pointer to the arg string */ + void * argp; + /** Encryption key ? */ + const char * key; +}; + +/** + * Execute a new game executable, limited when not running in kernel mode. + * + * @param file - The file to execute. + * @param param - Pointer to a ::SceKernelLoadExecParam structure, or NULL. + * + * @return < 0 on error, probably. + * + */ +int sceKernelLoadExec(const char *file, struct SceKernelLoadExecParam *param); + +#ifdef __cplusplus +} +#endif + +/*@}*/ + +#endif diff --git a/src/user/pspmoduleexport.h b/src/user/pspmoduleexport.h new file mode 100644 index 00000000..36a77c26 --- /dev/null +++ b/src/user/pspmoduleexport.h @@ -0,0 +1,29 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspmoduleexport.h - Definitions for the .rodata.sceResident section. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: pspmoduleexport.h 1095 2005-09-27 21:02:16Z jim $ + */ + +#ifndef PSP_MODEXPORT_H_ +#define PSP_MODEXPORT_H_ + +/** Structure to hold a single export entry */ +struct _PspLibraryEntry { + const char * name; + unsigned short version; + unsigned short attribute; + unsigned char entLen; + unsigned char varCount; + unsigned short funcCount; + void * entrytable; +}; + +#endif diff --git a/src/user/pspmoduleinfo.h b/src/user/pspmoduleinfo.h new file mode 100644 index 00000000..2976d9a0 --- /dev/null +++ b/src/user/pspmoduleinfo.h @@ -0,0 +1,148 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspmoduleinfo.h - Definitions for the .rodata.sceModuleInfo ELF section. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: pspmoduleinfo.h 2434 2008-10-15 17:37:25Z iwn $ + */ +#ifndef PSPMODULEINFO_H +#define PSPMODULEINFO_H + +/* Note: Some of the structures and definitions in this file were extrapolated from + symbolic debugging information found in the Japanese version of Puzzle Bobble. */ + +/* Module info structure. Used to declare a module (library or executable). This structure + is required in all PSP executables. */ +typedef struct _scemoduleinfo { + unsigned short modattribute; + unsigned char modversion[2]; + char modname[27]; + char terminal; + void * gp_value; + void * ent_top; + void * ent_end; + void * stub_top; + void * stub_end; +} _sceModuleInfo; + +typedef const _sceModuleInfo SceModuleInfo; + +extern char _gp[]; + +enum PspModuleInfoAttr +{ + PSP_MODULE_USER = 0, + PSP_MODULE_NO_STOP = 0x0001, + PSP_MODULE_SINGLE_LOAD = 0x0002, + PSP_MODULE_SINGLE_START = 0x0004, + PSP_MODULE_KERNEL = 0x1000, +}; + +#ifdef __cplusplus + +/* Declare a module. This must be specified in the source of a library or executable. */ +#define PSP_MODULE_INFO(name, attributes, major_version, minor_version) \ + __asm__ ( \ + " .set push\n" \ + " .section .lib.ent.top, \"a\", @progbits\n" \ + " .align 2\n" \ + " .word 0\n" \ + "__lib_ent_top:\n" \ + " .section .lib.ent.btm, \"a\", @progbits\n" \ + " .align 2\n" \ + "__lib_ent_bottom:\n" \ + " .word 0\n" \ + " .section .lib.stub.top, \"a\", @progbits\n" \ + " .align 2\n" \ + " .word 0\n" \ + "__lib_stub_top:\n" \ + " .section .lib.stub.btm, \"a\", @progbits\n" \ + " .align 2\n" \ + "__lib_stub_bottom:\n" \ + " .word 0\n" \ + " .set pop\n" \ + " .text\n" \ + ); \ + extern char __lib_ent_top[], __lib_ent_bottom[]; \ + extern char __lib_stub_top[], __lib_stub_bottom[]; \ + extern SceModuleInfo module_info \ + __attribute__((section(".rodata.sceModuleInfo"), \ + aligned(16), unused)) = { \ + attributes, { minor_version, major_version }, #name, 0, _gp, \ + __lib_ent_top, __lib_ent_bottom, \ + __lib_stub_top, __lib_stub_bottom \ + } +#else +/* Declare a module. This must be specified in the source of a library or executable. */ +#define PSP_MODULE_INFO(name, attributes, major_version, minor_version) \ + __asm__ ( \ + " .set push\n" \ + " .section .lib.ent.top, \"a\", @progbits\n" \ + " .align 2\n" \ + " .word 0\n" \ + "__lib_ent_top:\n" \ + " .section .lib.ent.btm, \"a\", @progbits\n" \ + " .align 2\n" \ + "__lib_ent_bottom:\n" \ + " .word 0\n" \ + " .section .lib.stub.top, \"a\", @progbits\n" \ + " .align 2\n" \ + " .word 0\n" \ + "__lib_stub_top:\n" \ + " .section .lib.stub.btm, \"a\", @progbits\n" \ + " .align 2\n" \ + "__lib_stub_bottom:\n" \ + " .word 0\n" \ + " .set pop\n" \ + " .text\n" \ + ); \ + extern char __lib_ent_top[], __lib_ent_bottom[]; \ + extern char __lib_stub_top[], __lib_stub_bottom[]; \ + SceModuleInfo module_info \ + __attribute__((section(".rodata.sceModuleInfo"), \ + aligned(16), unused)) = { \ + attributes, { minor_version, major_version }, name, 0, _gp, \ + __lib_ent_top, __lib_ent_bottom, \ + __lib_stub_top, __lib_stub_bottom \ + } +#endif + +/* Define the main thread's initial priority. */ +#define PSP_MAIN_THREAD_PRIORITY(priority) \ + unsigned int sce_newlib_priority = (priority) +/* Define the main thread's stack size (in KB). */ +#define PSP_MAIN_THREAD_STACK_SIZE_KB(size_kb) \ + unsigned int sce_newlib_stack_kb_size = (size_kb) +/* Define the main thread's attributes. */ +#define PSP_MAIN_THREAD_ATTR(attr) \ + unsigned int sce_newlib_attribute = (attr) +#define PSP_MAIN_THREAD_ATTRIBUTE PSP_MAIN_THREAD_ATTR + +/* Define all main thread parameters. */ +#define PSP_MAIN_THREAD_PARAMS(priority, size_kb, attribute) \ + PSP_MAIN_THREAD_PRIORITY(priority); \ + PSP_MAIN_THREAD_STACK_SIZE_KB(size_kb); \ + PSP_MAIN_THREAD_ATTR(attribute) + +/* If declared, the runtime code won't create a main thread for the program. */ +#define PSP_NO_CREATE_MAIN_THREAD() \ + int sce_newlib_nocreate_thread_in_start = 1 + +/* Declare the size of the heap (in KB) that the program wants to allocate from. */ +#define PSP_HEAP_SIZE_KB(size_kb) \ + int sce_newlib_heap_kb_size = (size_kb) + +/* Declare to allocate maximum heap area */ +#define PSP_HEAP_SIZE_MAX() \ + PSP_HEAP_SIZE_KB(-1) + +/* Declare the name of the main thread */ +#define PSP_MAIN_THREAD_NAME(s) const char* sce_newlib_main_thread_name = (s) + +#endif /* PSPMODULEINFO_H */ diff --git a/src/user/pspmodulemgr.h b/src/user/pspmodulemgr.h new file mode 100644 index 00000000..aa24f2da --- /dev/null +++ b/src/user/pspmodulemgr.h @@ -0,0 +1,218 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspmodulemgr.h - Prototypes to manage modules. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: pspmodulemgr.h 2433 2008-10-15 10:00:27Z iwn $ + */ + +/* Note: Some of the structures, types, and definitions in this file were + extrapolated from symbolic debugging information found in the Japanese + version of Puzzle Bobble. */ + +#ifndef __MODLOAD_H__ +#define __MODLOAD_H__ + +#include + +/** @defgroup ModuleMgr Module Manager Library + * This module contains the imports for the kernel's module management routines. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup ModuleMgr Module Manager Library */ +/*@{*/ + +#define PSP_MEMORY_PARTITION_KERNEL 1 +#define PSP_MEMORY_PARTITION_USER 2 + +typedef struct SceKernelLMOption { + SceSize size; + SceUID mpidtext; + SceUID mpiddata; + unsigned int flags; + char position; + char access; + char creserved[2]; +} SceKernelLMOption; + +typedef struct SceKernelSMOption { + SceSize size; + SceUID mpidstack; + SceSize stacksize; + int priority; + unsigned int attribute; +} SceKernelSMOption; + + +/** + * Load a module. + * @note This function restricts where it can load from (such as from flash0) + * unless you call it in kernel mode. It also must be called from a thread. + * + * @param path - The path to the module to load. + * @param flags - Unused, always 0 . + * @param option - Pointer to a mod_param_t structure. Can be NULL. + * + * @return The UID of the loaded module on success, otherwise one of ::PspKernelErrorCodes. + */ +SceUID sceKernelLoadModule(const char *path, int flags, SceKernelLMOption *option); + +/** + * Load a module from MS. + * @note This function restricts what it can load, e.g. it wont load plain executables. + * + * @param path - The path to the module to load. + * @param flags - Unused, set to 0. + * @param option - Pointer to a mod_param_t structure. Can be NULL. + * + * @return The UID of the loaded module on success, otherwise one of ::PspKernelErrorCodes. + */ +SceUID sceKernelLoadModuleMs(const char *path, int flags, SceKernelLMOption *option); + +/** + * Load a module from the given file UID. + * + * @param fid - The module's file UID. + * @param flags - Unused, always 0. + * @param option - Pointer to an optional ::SceKernelLMOption structure. + * + * @return The UID of the loaded module on success, otherwise one of ::PspKernelErrorCodes. + */ +SceUID sceKernelLoadModuleByID(SceUID fid, int flags, SceKernelLMOption *option); + +/** + * Load a module from a buffer using the USB/WLAN API. + * + * Can only be called from kernel mode, or from a thread that has attributes of 0xa0000000. + * + * @param bufsize - Size (in bytes) of the buffer pointed to by buf. + * @param buf - Pointer to a buffer containing the module to load. The buffer must reside at an + * address that is a multiple to 64 bytes. + * @param flags - Unused, always 0. + * @param option - Pointer to an optional ::SceKernelLMOption structure. + * + * @return The UID of the loaded module on success, otherwise one of ::PspKernelErrorCodes. + */ +SceUID sceKernelLoadModuleBufferUsbWlan(SceSize bufsize, void *buf, int flags, SceKernelLMOption *option); + +/** + * Start a loaded module. + * + * @param modid - The ID of the module returned from LoadModule. + * @param argsize - Length of the args. + * @param argp - A pointer to the arguments to the module. + * @param status - Returns the status of the start. + * @param option - Pointer to an optional ::SceKernelSMOption structure. + * + * @return ??? on success, otherwise one of ::PspKernelErrorCodes. + */ +int sceKernelStartModule(SceUID modid, SceSize argsize, void *argp, int *status, SceKernelSMOption *option); + +/** + * Stop a running module. + * + * @param modid - The UID of the module to stop. + * @param argsize - The length of the arguments pointed to by argp. + * @param argp - Pointer to arguments to pass to the module's module_stop() routine. + * @param status - Return value of the module's module_stop() routine. + * @param option - Pointer to an optional ::SceKernelSMOption structure. + * + * @return ??? on success, otherwise one of ::PspKernelErrorCodes. + */ +int sceKernelStopModule(SceUID modid, SceSize argsize, void *argp, int *status, SceKernelSMOption *option); + +/** + * Unload a stopped module. + * + * @param modid - The UID of the module to unload. + * + * @return ??? on success, otherwise one of ::PspKernelErrorCodes. + */ +int sceKernelUnloadModule(SceUID modid); + +/** + * Stop and unload the current module. + * + * @param unknown - Unknown (I've seen 1 passed). + * @param argsize - Size (in bytes) of the arguments that will be passed to module_stop(). + * @param argp - Pointer to arguments that will be passed to module_stop(). + * + * @return ??? on success, otherwise one of ::PspKernelErrorCodes. + */ +int sceKernelSelfStopUnloadModule(int unknown, SceSize argsize, void *argp); + +/** + * Stop and unload the current module. + * + * @param argsize - Size (in bytes) of the arguments that will be passed to module_stop(). + * @param argp - Poitner to arguments that will be passed to module_stop(). + * @param status - Return value from module_stop(). + * @param option - Pointer to an optional ::SceKernelSMOption structure. + * + * @return ??? on success, otherwise one of ::PspKernelErrorCodes. + */ +int sceKernelStopUnloadSelfModule(SceSize argsize, void *argp, int *status, SceKernelSMOption *option); + + +typedef struct SceKernelModuleInfo { + SceSize size; + char nsegment; + char reserved[3]; + int segmentaddr[4]; + int segmentsize[4]; + unsigned int entry_addr; + unsigned int gp_value; + unsigned int text_addr; + unsigned int text_size; + unsigned int data_size; + unsigned int bss_size; + /* The following is only available in the v1.5 firmware and above, + but as sceKernelQueryModuleInfo is broken in v1.0 is doesn't matter ;) */ + unsigned short attribute; + unsigned char version[2]; + char name[28]; +} SceKernelModuleInfo; + +/** + * Query the information about a loaded module from its UID. + * @note This fails on v1.0 firmware (and even it worked has a limited structure) + * so if you want to be compatible with both 1.5 and 1.0 (and you are running in + * kernel mode) then call this function first then ::pspSdkQueryModuleInfoV1 + * if it fails, or make separate v1 and v1.5+ builds. + * + * @param modid - The UID of the loaded module. + * @param info - Pointer to a ::SceKernelModuleInfo structure. + * + * @return 0 on success, otherwise one of ::PspKernelErrorCodes. + */ +int sceKernelQueryModuleInfo(SceUID modid, SceKernelModuleInfo *info); + +/** + * Get a list of module IDs. NOTE: This is only available on 1.5 firmware + * and above. For V1 use ::pspSdkGetModuleIdList. + * + * @param readbuf - Buffer to store the module list. + * @param readbufsize - Number of elements in the readbuffer. + * @param idcount - Returns the number of module ids + * + * @return >= 0 on success + */ +int sceKernelGetModuleIdList(SceUID *readbuf, int readbufsize, int *idcount); + +/*@}*/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/user/pspmscm.h b/src/user/pspmscm.h new file mode 100644 index 00000000..ea3ebde9 --- /dev/null +++ b/src/user/pspmscm.h @@ -0,0 +1,67 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspmscm.h - Memory stick utility functions + * + * Copyright (c) 2006 Adrahil + * + * $Id: pspmscm.h 2005 2006-09-17 21:36:52Z tyranid $ + */ +#ifndef PSPMSCM_H +#define PSPMSCM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Returns whether a memory stick is current inserted + * + * @return 1 if memory stick inserted, 0 if not or if < 0 on error + */ +static __inline__ int MScmIsMediumInserted(void) +{ + int status, ret; + + ret = sceIoDevctl("mscmhc0:", 0x02025806, 0, 0, &status, sizeof(status)); + if(ret < 0) return ret; + if(status != 1) return 0; + + return 1; +} + +/* Event which has occurred in the memory stick ejection callback, passed in arg2 */ +#define MS_CB_EVENT_INSERTED 1 +#define MS_CB_EVENT_EJECTED 2 + +/** + * Registers a memory stick ejection callback + * + * @param cbid - The uid of an allocated callback + * + * @return 0 on success, < 0 on error + */ +static __inline__ int MScmRegisterMSInsertEjectCallback(SceUID cbid) +{ + return sceIoDevctl("fatms0:", 0x02415821, &cbid, sizeof(cbid), 0, 0); +} + +/** + * Unregister a memory stick ejection callback + * + * @param cbid - The uid of an allocated callback + * + * @return 0 on success, < 0 on error + */ +static __inline__ int MScmUnregisterMSInsertEjectCallback(SceUID cbid) +{ + return sceIoDevctl("fatms0:", 0x02415822, &cbid, sizeof(cbid), 0, 0); +} + +#ifdef __cplusplus +} +#endif + +#endif /* PSPMSCM_H */ diff --git a/src/user/pspstdio.h b/src/user/pspstdio.h new file mode 100644 index 00000000..e5486206 --- /dev/null +++ b/src/user/pspstdio.h @@ -0,0 +1,57 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspstdio.h - Prototypes for the sceStdio library. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: pspstdio.h 1095 2005-09-27 21:02:16Z jim $ + */ +#ifndef __PSPSTDIO_H__ +#define __PSPSTDIO_H__ + +#include + +/** @defgroup Stdio Stdio Library + * This module contains the imports for the kernel's stdio routines. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup Stdio Stdio Library */ +/*@{*/ + +/** + * Function to get the current standard in file no + * + * @return The stdin fileno + */ +SceUID sceKernelStdin(void); + +/** + * Function to get the current standard out file no + * + * @return The stdout fileno + */ +SceUID sceKernelStdout(void); + +/** + * Function to get the current standard err file no + * + * @return The stderr fileno + */ +SceUID sceKernelStderr(void); + +/*@}*/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/user/pspsuspend.h b/src/user/pspsuspend.h new file mode 100644 index 00000000..8c438e38 --- /dev/null +++ b/src/user/pspsuspend.h @@ -0,0 +1,57 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspsuspend.h - User interface to the PSP suspend. + * + * Copyright (c) 2006 James F + * + * $Id + */ + +#ifndef __PSPSUSPEND_H__ +#define __PSPSUSPEND_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Allocate the extra 4megs of RAM + * + * @param unk - No idea as it is never used, set to anything + * @param ptr - Pointer to a pointer to hold the address of the memory + * @param size - Pointer to an int which will hold the size of the memory + * + * @return 0 on success + */ +int sceKernelVolatileMemLock(int unk, void **ptr, int *size); + +/** + * Try and allocate the extra 4megs of RAM, will return an error if + * something has already allocated it + * + * @param unk - No idea as it is never used, set to anything + * @param ptr - Pointer to a pointer to hold the address of the memory + * @param size - Pointer to an int which will hold the size of the memory + * + * @return 0 on success + */ +int sceKernelVolatileMemTryLock(int unk, void **ptr, int *size); + +/** + * Deallocate the extra 4 megs of RAM + * + * @param unk - Set to 0, otherwise it fails in 3.52+, possibly earlier + * @return 0 on success + */ +int sceKernelVolatileMemUnlock(int unk); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/user/pspsysmem.h b/src/user/pspsysmem.h new file mode 100644 index 00000000..1dfc986e --- /dev/null +++ b/src/user/pspsysmem.h @@ -0,0 +1,124 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspsysmem.h - Interface to the system memory manager. + * + * Copyright (c) 2005 Marcus R. Brown + * + * $Id: pspsysmem.h 2433 2008-10-15 10:00:27Z iwn $ + */ + +/* Note: Some of the structures, types, and definitions in this file were + extrapolated from symbolic debugging information found in the Japanese + version of Puzzle Bobble. */ + +#ifndef PSPSYSMEM_H +#define PSPSYSMEM_H + +#include + +/** @defgroup SysMem System Memory Manager + * This module contains routines to manage heaps of memory. + */ + +/** @addtogroup SysMem System Memory Manager */ +/*@{*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** Specifies the type of allocation used for memory blocks. */ +enum PspSysMemBlockTypes { + /** Allocate from the lowest available address. */ + PSP_SMEM_Low = 0, + /** Allocate from the highest available address. */ + PSP_SMEM_High, + /** Allocate from the specified address. */ + PSP_SMEM_Addr +}; + +typedef int SceKernelSysMemAlloc_t; + +/** + * Allocate a memory block from a memory partition. + * + * @param partitionid - The UID of the partition to allocate from. + * @param name - Name assigned to the new block. + * @param type - Specifies how the block is allocated within the partition. One of ::PspSysMemBlockTypes. + * @param size - Size of the memory block, in bytes. + * @param addr - If type is PSP_SMEM_Addr, then addr specifies the lowest address allocate the block from. + * + * @return The UID of the new block, or if less than 0 an error. + */ +SceUID sceKernelAllocPartitionMemory(SceUID partitionid, const char *name, int type, SceSize size, void *addr); + +/** + * Free a memory block allocated with ::sceKernelAllocPartitionMemory. + * + * @param blockid - UID of the block to free. + * + * @return ? on success, less than 0 on error. + */ +int sceKernelFreePartitionMemory(SceUID blockid); + +/** + * Get the address of a memory block. + * + * @param blockid - UID of the memory block. + * + * @return The lowest address belonging to the memory block. + */ +void * sceKernelGetBlockHeadAddr(SceUID blockid); + +/** + * Get the total amount of free memory. + * + * @return The total amount of free memory, in bytes. + */ +SceSize sceKernelTotalFreeMemSize(void); + +/** + * Get the size of the largest free memory block. + * + * @return The size of the largest free memory block, in bytes. + */ +SceSize sceKernelMaxFreeMemSize(void); + +/** + * Get the firmware version. + * + * @return The firmware version. + * 0x01000300 on v1.00 unit, + * 0x01050001 on v1.50 unit, + * 0x01050100 on v1.51 unit, + * 0x01050200 on v1.52 unit, + * 0x02000010 on v2.00/v2.01 unit, + * 0x02050010 on v2.50 unit, + * 0x02060010 on v2.60 unit, + * 0x02070010 on v2.70 unit, + * 0x02070110 on v2.71 unit. + */ +int sceKernelDevkitVersion(void); + +#if _PSP_FW_VERSION >= 150 + +/** + * Kernel printf function. + * + * @param format - The format string. + * @param ... - Arguments for the format string. + */ +void sceKernelPrintf(const char *format, ...) __attribute__((format(printf, 1, 2))); + +#endif + +#ifdef __cplusplus +} +#endif + +/*@}*/ + +#endif /* PSPSYSMEM_H */ diff --git a/src/user/pspthreadman.h b/src/user/pspthreadman.h new file mode 100644 index 00000000..7c69d500 --- /dev/null +++ b/src/user/pspthreadman.h @@ -0,0 +1,1768 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspthreadman.h - Library imports for the kernel threading library. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * Copyright (c) 2005 Florin Sasu + * + * $Id: pspthreadman.h 2433 2008-10-15 10:00:27Z iwn $ + */ +#ifndef __THREADMAN_H__ +#define __THREADMAN_H__ + +#include +#include +/* Include for profile register definitions */ +#include + +/* Note: Some of the structures, types, and definitions in this file were + extrapolated from symbolic debugging information found in the Japanese + version of Puzzle Bobble. */ + +/** @defgroup ThreadMan Thread Manager Library + * Library imports for the kernel threading library. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup ThreadMan */ + +/*@{*/ + +/** 64-bit system clock type. */ +typedef struct SceKernelSysClock { + SceUInt32 low; + SceUInt32 hi; +} SceKernelSysClock; + +/** Attribute for threads. */ +enum PspThreadAttributes +{ + /** Enable VFPU access for the thread. */ + PSP_THREAD_ATTR_VFPU = 0x00004000, + /** Start the thread in user mode (done automatically + if the thread creating it is in user mode). */ + PSP_THREAD_ATTR_USER = 0x80000000, + /** Thread is part of the USB/WLAN API. */ + PSP_THREAD_ATTR_USBWLAN = 0xa0000000, + /** Thread is part of the VSH API. */ + PSP_THREAD_ATTR_VSH = 0xc0000000, + /** Allow using scratchpad memory for a thread, NOT USABLE ON V1.0 */ + PSP_THREAD_ATTR_SCRATCH_SRAM = 0x00008000, + /** Disables filling the stack with 0xFF on creation */ + PSP_THREAD_ATTR_NO_FILLSTACK = 0x00100000, + /** Clear the stack when the thread is deleted */ + PSP_THREAD_ATTR_CLEAR_STACK = 0x00200000, +}; + +/* Maintained for compatibility with older versions of PSPSDK. */ +#define THREAD_ATTR_VFPU PSP_THREAD_ATTR_VFPU +#define THREAD_ATTR_USER PSP_THREAD_ATTR_USER + + +/* Threads. */ + +typedef int (*SceKernelThreadEntry)(SceSize args, void *argp); + +/** Additional options used when creating threads. */ +typedef struct SceKernelThreadOptParam { + /** Size of the ::SceKernelThreadOptParam structure. */ + SceSize size; + /** UID of the memory block (?) allocated for the thread's stack. */ + SceUID stackMpid; +} SceKernelThreadOptParam; + +/** Structure to hold the status information for a thread + * @see sceKernelReferThreadStatus + */ +typedef struct SceKernelThreadInfo { + /** Size of the structure */ + SceSize size; + /** Nul terminated name of the thread */ + char name[32]; + /** Thread attributes */ + SceUInt attr; + /** Thread status */ + int status; + /** Thread entry point */ + SceKernelThreadEntry entry; + /** Thread stack pointer */ + void * stack; + /** Thread stack size */ + int stackSize; + /** Pointer to the gp */ + void * gpReg; + /** Initial priority */ + int initPriority; + /** Current priority */ + int currentPriority; + /** Wait type */ + int waitType; + /** Wait id */ + SceUID waitId; + /** Wakeup count */ + int wakeupCount; + /** Exit status of the thread */ + int exitStatus; + /** Number of clock cycles run */ + SceKernelSysClock runClocks; + /** Interrupt preemption count */ + SceUInt intrPreemptCount; + /** Thread preemption count */ + SceUInt threadPreemptCount; + /** Release count */ + SceUInt releaseCount; +} SceKernelThreadInfo; + +/** Statistics about a running thread. + * @see sceKernelReferThreadRunStatus. + */ +typedef struct SceKernelThreadRunStatus { + SceSize size; + int status; + int currentPriority; + int waitType; + int waitId; + int wakeupCount; + SceKernelSysClock runClocks; + SceUInt intrPreemptCount; + SceUInt threadPreemptCount; + SceUInt releaseCount; +} SceKernelThreadRunStatus; + +/* Sure there must be more than this, but haven't seen them */ +enum PspThreadStatus +{ + PSP_THREAD_RUNNING = 1, + PSP_THREAD_READY = 2, + PSP_THREAD_WAITING = 4, + PSP_THREAD_SUSPEND = 8, + PSP_THREAD_STOPPED = 16, + PSP_THREAD_KILLED = 32, /* Thread manager has killed the thread (stack overflow) */ +}; + +/** + * Create a thread + * + * @par Example: + * @code + * SceUID thid; + * thid = sceKernelCreateThread("my_thread", threadFunc, 0x18, 0x10000, 0, NULL); + * @endcode + * + * @param name - An arbitrary thread name. + * @param entry - The thread function to run when started. + * @param initPriority - The initial priority of the thread. Less if higher priority. + * @param stackSize - The size of the initial stack. + * @param attr - The thread attributes, zero or more of ::PspThreadAttributes. + * @param option - Additional options specified by ::SceKernelThreadOptParam. + + * @return UID of the created thread, or an error code. + */ +SceUID sceKernelCreateThread(const char *name, SceKernelThreadEntry entry, int initPriority, + int stackSize, SceUInt attr, SceKernelThreadOptParam *option); + +/** + * Delate a thread + * + * @param thid - UID of the thread to be deleted. + * + * @return < 0 on error. + */ +int sceKernelDeleteThread(SceUID thid); + +/** + * Start a created thread + * + * @param thid - Thread id from sceKernelCreateThread + * @param arglen - Length of the data pointed to by argp, in bytes + * @param argp - Pointer to the arguments. + */ +int sceKernelStartThread(SceUID thid, SceSize arglen, void *argp); + +/** + * Exit a thread + * + * @param status - Exit status. + */ +int sceKernelExitThread(int status); + +/** + * Exit a thread and delete itself. + * + * @param status - Exit status + */ +int sceKernelExitDeleteThread(int status); + +/** + * Terminate a thread. + * + * @param thid - UID of the thread to terminate. + * + * @return Success if >= 0, an error if < 0. + */ +int sceKernelTerminateThread(SceUID thid); + +/** + * Terminate and delete a thread. + * + * @param thid - UID of the thread to terminate and delete. + * + * @return Success if >= 0, an error if < 0. + */ +int sceKernelTerminateDeleteThread(SceUID thid); + +/** + * Suspend the dispatch thread + * + * @return The current state of the dispatch thread, < 0 on error + */ +int sceKernelSuspendDispatchThread(void); + +/** + * Resume the dispatch thread + * + * @param state - The state of the dispatch thread + * (from ::sceKernelSuspendDispatchThread) + * + * @return 0 on success, < 0 on error + */ +int sceKernelResumeDispatchThread(int state); + +/** + * Sleep thread + * + * @return < 0 on error. + */ +int sceKernelSleepThread(void); + +/** + * Sleep thread but service any callbacks as necessary + * + * @par Example: + * @code + * // Once all callbacks have been setup call this function + * sceKernelSleepThreadCB(); + * @endcode + */ +int sceKernelSleepThreadCB(void); + +/** + * Wake a thread previously put into the sleep state. + * + * @param thid - UID of the thread to wake. + * + * @return Success if >= 0, an error if < 0. + */ +int sceKernelWakeupThread(SceUID thid); + +/** + * Cancel a thread that was to be woken with ::sceKernelWakeupThread. + * + * @param thid - UID of the thread to cancel. + * + * @return Success if >= 0, an error if < 0. + */ +int sceKernelCancelWakeupThread(SceUID thid); + +/** + * Suspend a thread. + * + * @param thid - UID of the thread to suspend. + * + * @return Success if >= 0, an error if < 0. + */ +int sceKernelSuspendThread(SceUID thid); + +/** + * Resume a thread previously put into a suspended state with ::sceKernelSuspendThread. + * + * @param thid - UID of the thread to resume. + * + * @return Success if >= 0, an error if < 0. + */ +int sceKernelResumeThread(SceUID thid); + +/** + * Wait until a thread has ended. + * + * @param thid - Id of the thread to wait for. + * @param timeout - Timeout in microseconds (assumed). + * + * @return < 0 on error. + */ +int sceKernelWaitThreadEnd(SceUID thid, SceUInt *timeout); + +/** + * Wait until a thread has ended and handle callbacks if necessary. + * + * @param thid - Id of the thread to wait for. + * @param timeout - Timeout in microseconds (assumed). + * + * @return < 0 on error. + */ +int sceKernelWaitThreadEndCB(SceUID thid, SceUInt *timeout); + +/** + * Delay the current thread by a specified number of microseconds + * + * @param delay - Delay in microseconds. + * + * @par Example: + * @code + * sceKernelDelayThread(1000000); // Delay for a second + * @endcode + */ +int sceKernelDelayThread(SceUInt delay); + +/** + * Delay the current thread by a specified number of microseconds and handle any callbacks. + * + * @param delay - Delay in microseconds. + * + * @par Example: + * @code + * sceKernelDelayThread(1000000); // Delay for a second + * @endcode + */ +int sceKernelDelayThreadCB(SceUInt delay); + +/** + * Delay the current thread by a specified number of sysclocks + * + * @param delay - Delay in sysclocks + * + * @return 0 on success, < 0 on error + */ +int sceKernelDelaySysClockThread(SceKernelSysClock *delay); + +/** + * Delay the current thread by a specified number of sysclocks handling callbacks + * + * @param delay - Delay in sysclocks + * + * @return 0 on success, < 0 on error + * + */ +int sceKernelDelaySysClockThreadCB(SceKernelSysClock *delay); + +/** + * Modify the attributes of the current thread. + * + * @param unknown - Set to 0. + * @param attr - The thread attributes to modify. One of ::PspThreadAttributes. + * + * @return < 0 on error. + */ +int sceKernelChangeCurrentThreadAttr(int unknown, SceUInt attr); + +/** + * Change the threads current priority. + * + * @param thid - The ID of the thread (from sceKernelCreateThread or sceKernelGetThreadId) + * @param priority - The new priority (the lower the number the higher the priority) + * + * @par Example: + * @code + * int thid = sceKernelGetThreadId(); + * // Change priority of current thread to 16 + * sceKernelChangeThreadPriority(thid, 16); + * @endcode + * + * @return 0 if successful, otherwise the error code. + */ +int sceKernelChangeThreadPriority(SceUID thid, int priority); + +/** + * Rotate thread ready queue at a set priority + * + * @param priority - The priority of the queue + * + * @return 0 on success, < 0 on error. + */ +int sceKernelRotateThreadReadyQueue(int priority); + +/** + * Release a thread in the wait state. + * + * @param thid - The UID of the thread. + * + * @return 0 on success, < 0 on error + */ +int sceKernelReleaseWaitThread(SceUID thid); + +/** + * Get the current thread Id + * + * @return The thread id of the calling thread. + */ +int sceKernelGetThreadId(void); + +/** + * Get the current priority of the thread you are in. + * + * @return The current thread priority + */ +int sceKernelGetThreadCurrentPriority(void); + +/** + * Get the exit status of a thread. + * + * @param thid - The UID of the thread to check. + * + * @return The exit status + */ +int sceKernelGetThreadExitStatus(SceUID thid); + +/** + * Check the thread stack? + * + * @return Unknown. + */ +int sceKernelCheckThreadStack(void); + +/** + * Get the free stack size for a thread. + * + * @param thid - The thread ID. Seem to take current thread + * if set to 0. + * + * @return The free size. + */ +int sceKernelGetThreadStackFreeSize(SceUID thid); + +/** + * Get the status information for the specified thread. + * + * @param thid - Id of the thread to get status + * @param info - Pointer to the info structure to receive the data. + * Note: The structures size field should be set to + * sizeof(SceKernelThreadInfo) before calling this function. + * + * @par Example: + * @code + * SceKernelThreadInfo status; + * status.size = sizeof(SceKernelThreadInfo); + * if(sceKernelReferThreadStatus(thid, &status) == 0) + * { Do something... } + * @endcode + * @return 0 if successful, otherwise the error code. + */ +int sceKernelReferThreadStatus(SceUID thid, SceKernelThreadInfo *info); + +/** + * Retrive the runtime status of a thread. + * + * @param thid - UID of the thread to retrive status. + * @param status - Pointer to a ::SceKernelThreadRunStatus struct to receive the runtime status. + * + * @return 0 if successful, otherwise the error code. + */ +int sceKernelReferThreadRunStatus(SceUID thid, SceKernelThreadRunStatus *status); + + +/* Semaphores. */ + +/** Additional options used when creating semaphores. */ +typedef struct SceKernelSemaOptParam { + /** Size of the ::SceKernelSemaOptParam structure. */ + SceSize size; +} SceKernelSemaOptParam; + +/** Current state of a semaphore. + * @see sceKernelReferSemaStatus. + */ +typedef struct SceKernelSemaInfo { + /** Size of the ::SceKernelSemaInfo structure. */ + SceSize size; + /** NUL-terminated name of the semaphore. */ + char name[32]; + /** Attributes. */ + SceUInt attr; + /** The initial count the semaphore was created with. */ + int initCount; + /** The current count. */ + int currentCount; + /** The maximum count. */ + int maxCount; + /** The number of threads waiting on the semaphore. */ + int numWaitThreads; +} SceKernelSemaInfo; + +/** + * Creates a new semaphore + * + * @par Example: + * @code + * int semaid; + * semaid = sceKernelCreateSema("MyMutex", 0, 1, 1, 0); + * @endcode + * + * @param name - Specifies the name of the sema + * @param attr - Sema attribute flags (normally set to 0) + * @param initVal - Sema initial value + * @param maxVal - Sema maximum value + * @param option - Sema options (normally set to 0) + * @return A semaphore id + */ +SceUID sceKernelCreateSema(const char *name, SceUInt attr, int initVal, int maxVal, SceKernelSemaOptParam *option); + +/** + * Destroy a semaphore + * + * @param semaid - The semaid returned from a previous create call. + * @return Returns the value 0 if its succesful otherwise -1 + */ +int sceKernelDeleteSema(SceUID semaid); + +/** + * Send a signal to a semaphore + * + * @par Example: + * @code + * // Signal the sema + * sceKernelSignalSema(semaid, 1); + * @endcode + * + * @param semaid - The sema id returned from sceKernelCreateSema + * @param signal - The amount to signal the sema (i.e. if 2 then increment the sema by 2) + * + * @return < 0 On error. + */ +int sceKernelSignalSema(SceUID semaid, int signal); + +/** + * Lock a semaphore + * + * @par Example: + * @code + * sceKernelWaitSema(semaid, 1, 0); + * @endcode + * + * @param semaid - The sema id returned from sceKernelCreateSema + * @param signal - The value to wait for (i.e. if 1 then wait till reaches a signal state of 1) + * @param timeout - Timeout in microseconds (assumed). + * + * @return < 0 on error. + */ +int sceKernelWaitSema(SceUID semaid, int signal, SceUInt *timeout); + +/** + * Lock a semaphore a handle callbacks if necessary. + * + * @par Example: + * @code + * sceKernelWaitSemaCB(semaid, 1, 0); + * @endcode + * + * @param semaid - The sema id returned from sceKernelCreateSema + * @param signal - The value to wait for (i.e. if 1 then wait till reaches a signal state of 1) + * @param timeout - Timeout in microseconds (assumed). + * + * @return < 0 on error. + */ +int sceKernelWaitSemaCB(SceUID semaid, int signal, SceUInt *timeout); + +/** + * Poll a sempahore. + * + * @param semaid - UID of the semaphore to poll. + * @param signal - The value to test for. + * + * @return < 0 on error. + */ +int sceKernelPollSema(SceUID semaid, int signal); + +/** + * Retrieve information about a semaphore. + * + * @param semaid - UID of the semaphore to retrieve info for. + * @param info - Pointer to a ::SceKernelSemaInfo struct to receive the info. + * + * @return < 0 on error. + */ +int sceKernelReferSemaStatus(SceUID semaid, SceKernelSemaInfo *info); + + +/* Event flags. */ + +/** Structure to hold the event flag information */ +typedef struct SceKernelEventFlagInfo { + SceSize size; + char name[32]; + SceUInt attr; + SceUInt initPattern; + SceUInt currentPattern; + int numWaitThreads; +} SceKernelEventFlagInfo; + +struct SceKernelEventFlagOptParam { + SceSize size; +}; + +typedef struct SceKernelEventFlagOptParam SceKernelEventFlagOptParam; + +/** Event flag creation attributes */ +enum PspEventFlagAttributes +{ + /** Allow the event flag to be waited upon by multiple threads */ + PSP_EVENT_WAITMULTIPLE = 0x200 +}; + +/** Event flag wait types */ +enum PspEventFlagWaitTypes +{ + /** Wait for all bits in the pattern to be set */ + PSP_EVENT_WAITAND = 0, + /** Wait for one or more bits in the pattern to be set */ + PSP_EVENT_WAITOR = 1, + /** Clear the wait pattern when it matches */ + PSP_EVENT_WAITCLEAR = 0x20 +}; + +/** + * Create an event flag. + * + * @param name - The name of the event flag. + * @param attr - Attributes from ::PspEventFlagAttributes + * @param bits - Initial bit pattern. + * @param opt - Options, set to NULL + * @return < 0 on error. >= 0 event flag id. + * + * @par Example: + * @code + * int evid; + * evid = sceKernelCreateEventFlag("wait_event", 0, 0, 0); + * @endcode + */ +SceUID sceKernelCreateEventFlag(const char *name, int attr, int bits, SceKernelEventFlagOptParam *opt); + +/** + * Set an event flag bit pattern. + * + * @param evid - The event id returned by sceKernelCreateEventFlag. + * @param bits - The bit pattern to set. + * + * @return < 0 On error + */ +int sceKernelSetEventFlag(SceUID evid, u32 bits); + +/** + * Clear a event flag bit pattern + * + * @param evid - The event id returned by ::sceKernelCreateEventFlag + * @param bits - The bits to clean + * + * @return < 0 on Error + */ +int sceKernelClearEventFlag(SceUID evid, u32 bits); + +/** + * Poll an event flag for a given bit pattern. + * + * @param evid - The event id returned by sceKernelCreateEventFlag. + * @param bits - The bit pattern to poll for. + * @param wait - Wait type, one or more of ::PspEventFlagWaitTypes or'ed together + * @param outBits - The bit pattern that was matched. + * @return < 0 On error + */ +int sceKernelPollEventFlag(int evid, u32 bits, u32 wait, u32 *outBits); + +/** + * Wait for an event flag for a given bit pattern. + * + * @param evid - The event id returned by sceKernelCreateEventFlag. + * @param bits - The bit pattern to poll for. + * @param wait - Wait type, one or more of ::PspEventFlagWaitTypes or'ed together + * @param outBits - The bit pattern that was matched. + * @param timeout - Timeout in microseconds + * @return < 0 On error + */ +int sceKernelWaitEventFlag(int evid, u32 bits, u32 wait, u32 *outBits, SceUInt *timeout); + +/** + * Wait for an event flag for a given bit pattern with callback. + * + * @param evid - The event id returned by sceKernelCreateEventFlag. + * @param bits - The bit pattern to poll for. + * @param wait - Wait type, one or more of ::PspEventFlagWaitTypes or'ed together + * @param outBits - The bit pattern that was matched. + * @param timeout - Timeout in microseconds + * @return < 0 On error + */ +int sceKernelWaitEventFlagCB(int evid, u32 bits, u32 wait, u32 *outBits, SceUInt *timeout); + +/** + * Delete an event flag + * + * @param evid - The event id returned by sceKernelCreateEventFlag. + * + * @return < 0 On error + */ +int sceKernelDeleteEventFlag(int evid); + +/** + * Get the status of an event flag. + * + * @param event - The UID of the event. + * @param status - A pointer to a ::SceKernelEventFlagInfo structure. + * + * @return < 0 on error. + */ +int sceKernelReferEventFlagStatus(SceUID event, SceKernelEventFlagInfo *status); + + +/* Message boxes. */ + +/** Additional options used when creating messageboxes. */ +typedef struct SceKernelMbxOptParam { + /** Size of the ::SceKernelMbxOptParam structure. */ + SceSize size; +} SceKernelMbxOptParam; + +/** Current state of a messagebox. + * @see sceKernelReferMbxStatus. + */ +typedef struct SceKernelMbxInfo { + /** Size of the ::SceKernelMbxInfo structure. */ + SceSize size; + /** NUL-terminated name of the messagebox. */ + char name[32]; + /** Attributes. */ + SceUInt attr; + /** The number of threads waiting on the messagebox. */ + int numWaitThreads; + /** Number of messages currently in the messagebox. */ + int numMessages; + /** The message currently at the head of the queue. */ + void *firstMessage; +} SceKernelMbxInfo; + +/** + * Header for a message box packet + */ +typedef struct SceKernelMsgPacket { + /** Pointer to next msg (used by the kernel) */ + struct SceKernelMsgPacket *next; + /** Priority ? */ + SceUChar msgPriority; + SceUChar dummy[3]; + /** After this can be any user defined data */ +} SceKernelMsgPacket; + +/** + * Creates a new messagebox + * + * @par Example: + * @code + * int mbxid; + * mbxid = sceKernelCreateMbx("MyMessagebox", 0, NULL); + * @endcode + * + * @param name - Specifies the name of the mbx + * @param attr - Mbx attribute flags (normally set to 0) + * @param option - Mbx options (normally set to NULL) + * @return A messagebox id + */ +SceUID sceKernelCreateMbx(const char *name, SceUInt attr, SceKernelMbxOptParam *option); + +/** + * Destroy a messagebox + * + * @param mbxid - The mbxid returned from a previous create call. + * @return Returns the value 0 if its succesful otherwise an error code + */ +int sceKernelDeleteMbx(SceUID mbxid); + +/** + * Send a message to a messagebox + * + * @par Example: + * @code + * struct MyMessage { + * SceKernelMsgPacket header; + * char text[8]; + * }; + * + * struct MyMessage msg = { {0}, "Hello" }; + * // Send the message + * sceKernelSendMbx(mbxid, (void*) &msg); + * @endcode + * + * @param mbxid - The mbx id returned from sceKernelCreateMbx + * @param message - A message to be forwarded to the receiver. + * The start of the message should be the + * ::SceKernelMsgPacket structure, the rest + * + * @return < 0 On error. + */ +int sceKernelSendMbx(SceUID mbxid, void *message); + +/** + * Wait for a message to arrive in a messagebox + * + * @par Example: + * @code + * void *msg; + * sceKernelReceiveMbx(mbxid, &msg, NULL); + * @endcode + * + * @param mbxid - The mbx id returned from sceKernelCreateMbx + * @param pmessage - A pointer to where a pointer to the + * received message should be stored + * @param timeout - Timeout in microseconds + * + * @return < 0 on error. + */ +int sceKernelReceiveMbx(SceUID mbxid, void **pmessage, SceUInt *timeout); + +/** + * Wait for a message to arrive in a messagebox and handle callbacks if necessary. + * + * @par Example: + * @code + * void *msg; + * sceKernelReceiveMbxCB(mbxid, &msg, NULL); + * @endcode + * + * @param mbxid - The mbx id returned from sceKernelCreateMbx + * @param pmessage - A pointer to where a pointer to the + * received message should be stored + * @param timeout - Timeout in microseconds + * + * @return < 0 on error. + */ +int sceKernelReceiveMbxCB(SceUID mbxid, void **pmessage, SceUInt *timeout); + +/** + * Check if a message has arrived in a messagebox + * + * @par Example: + * @code + * void *msg; + * sceKernelPollMbx(mbxid, &msg); + * @endcode + * + * @param mbxid - The mbx id returned from sceKernelCreateMbx + * @param pmessage - A pointer to where a pointer to the + * received message should be stored + * + * @return < 0 on error (SCE_KERNEL_ERROR_MBOX_NOMSG if the mbx is empty). + */ +int sceKernelPollMbx(SceUID mbxid, void **pmessage); + +/** + * Abort all wait operations on a messagebox + * + * @par Example: + * @code + * sceKernelCancelReceiveMbx(mbxid, NULL); + * @endcode + * + * @param mbxid - The mbx id returned from sceKernelCreateMbx + * @param pnum - A pointer to where the number of threads which + * were waiting on the mbx should be stored (NULL + * if you don't care) + * + * @return < 0 on error + */ +int sceKernelCancelReceiveMbx(SceUID mbxid, int *pnum); + +/** + * Retrieve information about a messagebox. + * + * @param mbxid - UID of the messagebox to retrieve info for. + * @param info - Pointer to a ::SceKernelMbxInfo struct to receive the info. + * + * @return < 0 on error. + */ +int sceKernelReferMbxStatus(SceUID mbxid, SceKernelMbxInfo *info); + + +/* Alarms. */ + +/** Prototype for alarm handlers. */ +typedef SceUInt (*SceKernelAlarmHandler)(void *common); + +/** Struct containing alarm info */ +typedef struct SceKernelAlarmInfo { + /** Size of the structure (should be set before calling + * :: sceKernelReferAlarmStatus */ + SceSize size; + /* The current schedule */ + SceKernelSysClock schedule; + /** Pointer to the alarm handler */ + SceKernelAlarmHandler handler; + /** Common pointer argument */ + void * common; +} SceKernelAlarmInfo; + +/** + * Set an alarm. + * @param clock - The number of micro seconds till the alarm occurrs. + * @param handler - Pointer to a ::SceKernelAlarmHandler + * @param common - Common pointer for the alarm handler + * + * @return A UID representing the created alarm, < 0 on error. + */ +SceUID sceKernelSetAlarm(SceUInt clock, SceKernelAlarmHandler handler, void *common); + +/** + * Set an alarm using a ::SceKernelSysClock structure for the time + * + * @param clock - Pointer to a ::SceKernelSysClock structure + * @param handler - Pointer to a ::SceKernelAlarmHandler + * @param common - Common pointer for the alarm handler. + * + * @return A UID representing the created alarm, < 0 on error. + */ +SceUID sceKernelSetSysClockAlarm(SceKernelSysClock *clock, SceKernelAlarmHandler handler, void *common); + +/** + * Cancel a pending alarm. + * + * @param alarmid - UID of the alarm to cancel. + * + * @return 0 on success, < 0 on error. + */ +int sceKernelCancelAlarm(SceUID alarmid); + +/** + * Refer the status of a created alarm. + * + * @param alarmid - UID of the alarm to get the info of + * @param info - Pointer to a ::SceKernelAlarmInfo structure + * + * @return 0 on success, < 0 on error. + */ +int sceKernelReferAlarmStatus(SceUID alarmid, SceKernelAlarmInfo *info); + +/* Callbacks. */ + +/** Callback function prototype */ +typedef int (*SceKernelCallbackFunction)(int arg1, int arg2, void *arg); + +/** Structure to hold the status information for a callback */ +typedef struct SceKernelCallbackInfo { + /** Size of the structure (i.e. sizeof(SceKernelCallbackInfo)) */ + SceSize size; + /** The name given to the callback */ + char name[32]; + /** The thread id associated with the callback */ + SceUID threadId; + /** Pointer to the callback function */ + SceKernelCallbackFunction callback; + /** User supplied argument for the callback */ + void * common; + /** Unknown */ + int notifyCount; + /** Unknown */ + int notifyArg; +} SceKernelCallbackInfo; + +/** + * Create callback + * + * @par Example: + * @code + * int cbid; + * cbid = sceKernelCreateCallback("Exit Callback", exit_cb, NULL); + * @endcode + * + * @param name - A textual name for the callback + * @param func - A pointer to a function that will be called as the callback + * @param arg - Argument for the callback ? + * + * @return >= 0 A callback id which can be used in subsequent functions, < 0 an error. + */ +int sceKernelCreateCallback(const char *name, SceKernelCallbackFunction func, void *arg); + +/** + * Gets the status of a specified callback. + * + * @param cb - The UID of the callback to refer. + * @param status - Pointer to a status structure. The size parameter should be + * initialised before calling. + * + * @return < 0 on error. + */ +int sceKernelReferCallbackStatus(SceUID cb, SceKernelCallbackInfo *status); + +/** + * Delete a callback + * + * @param cb - The UID of the specified callback + * + * @return 0 on success, < 0 on error + */ +int sceKernelDeleteCallback(SceUID cb); + +/** + * Notify a callback + * + * @param cb - The UID of the specified callback + * @param arg2 - Passed as arg2 into the callback function + * + * @return 0 on success, < 0 on error + */ +int sceKernelNotifyCallback(SceUID cb, int arg2); + +/** + * Cancel a callback ? + * + * @param cb - The UID of the specified callback + * + * @return 0 on succes, < 0 on error + */ +int sceKernelCancelCallback(SceUID cb); + +/** + * Get the callback count + * + * @param cb - The UID of the specified callback + * + * @return The callback count, < 0 on error + */ +int sceKernelGetCallbackCount(SceUID cb); + +/** + * Check callback ? + * + * @return Something or another + */ +int sceKernelCheckCallback(void); + +/* Misc. */ + +/** Threadman types for ::sceKernelGetThreadmanIdList */ +enum SceKernelIdListType +{ + SCE_KERNEL_TMID_Thread = 1, + SCE_KERNEL_TMID_Semaphore = 2, + SCE_KERNEL_TMID_EventFlag = 3, + SCE_KERNEL_TMID_Mbox = 4, + SCE_KERNEL_TMID_Vpl = 5, + SCE_KERNEL_TMID_Fpl = 6, + SCE_KERNEL_TMID_Mpipe = 7, + SCE_KERNEL_TMID_Callback = 8, + SCE_KERNEL_TMID_ThreadEventHandler = 9, + SCE_KERNEL_TMID_Alarm = 10, + SCE_KERNEL_TMID_VTimer = 11, + SCE_KERNEL_TMID_SleepThread = 64, + SCE_KERNEL_TMID_DelayThread = 65, + SCE_KERNEL_TMID_SuspendThread = 66, + SCE_KERNEL_TMID_DormantThread = 67, +}; + +/** + * Get a list of UIDs from threadman. Allows you to enumerate + * resources such as threads or semaphores. + * + * @param type - The type of resource to list, one of ::SceKernelIdListType. + * @param readbuf - A pointer to a buffer to store the list. + * @param readbufsize - The size of the buffer in SceUID units. + * @param idcount - Pointer to an integer in which to return the number of ids in the list. + * + * @return < 0 on error. Either 0 or the same as idcount on success. + */ +int sceKernelGetThreadmanIdList(enum SceKernelIdListType type, SceUID *readbuf, int readbufsize, int *idcount); + +/** Structure to contain the system status returned by ::sceKernelReferSystemStatus */ +typedef struct SceKernelSystemStatus { + /** Size of the structure (should be set prior to the call) */ + SceSize size; + /** The status ? */ + SceUInt status; + /** The number of cpu clocks in the idle thread */ + SceKernelSysClock idleClocks; + /** Number of times we resumed from idle */ + SceUInt comesOutOfIdleCount; + /** Number of thread context switches */ + SceUInt threadSwitchCount; + /** Number of vfpu switches ? */ + SceUInt vfpuSwitchCount; +} SceKernelSystemStatus; + +/** + * Get the current system status. + * + * @param status - Pointer to a ::SceKernelSystemStatus structure. + * + * @return < 0 on error. + */ +int sceKernelReferSystemStatus(SceKernelSystemStatus *status); + + +/** + * Create a message pipe + * + * @param name - Name of the pipe + * @param part - ID of the memory partition + * @param attr - Set to 0? + * @param unk1 - Unknown + * @param opt - Message pipe options (set to NULL) + * + * @return The UID of the created pipe, < 0 on error + */ +SceUID sceKernelCreateMsgPipe(const char *name, int part, int attr, void *unk1, void *opt); + +/** + * Delete a message pipe + * + * @param uid - The UID of the pipe + * + * @return 0 on success, < 0 on error + */ +int sceKernelDeleteMsgPipe(SceUID uid); + +/** + * Send a message to a pipe + * + * @param uid - The UID of the pipe + * @param message - Pointer to the message + * @param size - Size of the message + * @param unk1 - Unknown + * @param unk2 - Unknown + * @param timeout - Timeout for send + * + * @return 0 on success, < 0 on error + */ +int sceKernelSendMsgPipe(SceUID uid, void *message, unsigned int size, int unk1, void *unk2, unsigned int *timeout); + +/** + * Send a message to a pipe (with callback) + * + * @param uid - The UID of the pipe + * @param message - Pointer to the message + * @param size - Size of the message + * @param unk1 - Unknown + * @param unk2 - Unknown + * @param timeout - Timeout for send + * + * @return 0 on success, < 0 on error + */ +int sceKernelSendMsgPipeCB(SceUID uid, void *message, unsigned int size, int unk1, void *unk2, unsigned int *timeout); + +/** + * Try to send a message to a pipe + * + * @param uid - The UID of the pipe + * @param message - Pointer to the message + * @param size - Size of the message + * @param unk1 - Unknown + * @param unk2 - Unknown + * + * @return 0 on success, < 0 on error + */ +int sceKernelTrySendMsgPipe(SceUID uid, void *message, unsigned int size, int unk1, void *unk2); + +/** + * Receive a message from a pipe + * + * @param uid - The UID of the pipe + * @param message - Pointer to the message + * @param size - Size of the message + * @param unk1 - Unknown + * @param unk2 - Unknown + * @param timeout - Timeout for receive + * + * @return 0 on success, < 0 on error + */ +int sceKernelReceiveMsgPipe(SceUID uid, void *message, unsigned int size, int unk1, void *unk2, unsigned int *timeout); + +/** + * Receive a message from a pipe (with callback) + * + * @param uid - The UID of the pipe + * @param message - Pointer to the message + * @param size - Size of the message + * @param unk1 - Unknown + * @param unk2 - Unknown + * @param timeout - Timeout for receive + * + * @return 0 on success, < 0 on error + */ +int sceKernelReceiveMsgPipeCB(SceUID uid, void *message, unsigned int size, int unk1, void *unk2, unsigned int *timeout); + +/** + * Receive a message from a pipe + * + * @param uid - The UID of the pipe + * @param message - Pointer to the message + * @param size - Size of the message + * @param unk1 - Unknown + * @param unk2 - Unknown + * + * @return 0 on success, < 0 on error + */ +int sceKernelTryReceiveMsgPipe(SceUID uid, void *message, unsigned int size, int unk1, void *unk2); + +/** + * Cancel a message pipe + * + * @param uid - UID of the pipe to cancel + * @param psend - Receive number of sending threads? + * @param precv - Receive number of receiving threads? + * + * @return 0 on success, < 0 on error + */ +int sceKernelCancelMsgPipe(SceUID uid, int *psend, int *precv); + +/** Message Pipe status info */ +typedef struct SceKernelMppInfo { + SceSize size; + char name[32]; + SceUInt attr; + int bufSize; + int freeSize; + int numSendWaitThreads; + int numReceiveWaitThreads; +} SceKernelMppInfo; + +/** + * Get the status of a Message Pipe + * + * @param uid - The uid of the Message Pipe + * @param info - Pointer to a ::SceKernelMppInfo structure + * + * @return 0 on success, < 0 on error + */ +int sceKernelReferMsgPipeStatus(SceUID uid, SceKernelMppInfo *info); + +/* VPL Functions */ + +struct SceKernelVplOptParam { + SceSize size; +}; + +/** + * Create a variable pool + * + * @param name - Name of the pool + * @param part - The memory partition ID + * @param attr - Attributes + * @param size - Size of pool + * @param opt - Options (set to NULL) + * + * @return The UID of the created pool, < 0 on error. + */ +SceUID sceKernelCreateVpl(const char *name, int part, int attr, unsigned int size, struct SceKernelVplOptParam *opt); + +/** + * Delete a variable pool + * + * @param uid - The UID of the pool + * + * @return 0 on success, < 0 on error + */ +int sceKernelDeleteVpl(SceUID uid); + +/** + * Allocate from the pool + * + * @param uid - The UID of the pool + * @param size - The size to allocate + * @param data - Receives the address of the allocated data + * @param timeout - Amount of time to wait for allocation? + * + * @return 0 on success, < 0 on error + */ +int sceKernelAllocateVpl(SceUID uid, unsigned int size, void **data, unsigned int *timeout); + +/** + * Allocate from the pool (with callback) + * + * @param uid - The UID of the pool + * @param size - The size to allocate + * @param data - Receives the address of the allocated data + * @param timeout - Amount of time to wait for allocation? + * + * @return 0 on success, < 0 on error + */ +int sceKernelAllocateVplCB(SceUID uid, unsigned int size, void **data, unsigned int *timeout); + +/** + * Try to allocate from the pool + * + * @param uid - The UID of the pool + * @param size - The size to allocate + * @param data - Receives the address of the allocated data + * + * @return 0 on success, < 0 on error + */ +int sceKernelTryAllocateVpl(SceUID uid, unsigned int size, void **data); + +/** + * Free a block + * + * @param uid - The UID of the pool + * @param data - The data block to deallocate + * + * @return 0 on success, < 0 on error + */ +int sceKernelFreeVpl(SceUID uid, void *data); + +/** + * Cancel a pool + * + * @param uid - The UID of the pool + * @param pnum - Receives the number of waiting threads + * + * @return 0 on success, < 0 on error + */ +int sceKernelCancelVpl(SceUID uid, int *pnum); + +/** Variable pool status info */ +typedef struct SceKernelVplInfo { + SceSize size; + char name[32]; + SceUInt attr; + int poolSize; + int freeSize; + int numWaitThreads; +} SceKernelVplInfo; + +/** + * Get the status of an VPL + * + * @param uid - The uid of the VPL + * @param info - Pointer to a ::SceKernelVplInfo structure + * + * @return 0 on success, < 0 on error + */ +int sceKernelReferVplStatus(SceUID uid, SceKernelVplInfo *info); + +/* FPL Functions */ + +struct SceKernelFplOptParam { + SceSize size; +}; + +/** + * Create a fixed pool + * + * @param name - Name of the pool + * @param part - The memory partition ID + * @param attr - Attributes + * @param size - Size of pool block + * @param blocks - Number of blocks to allocate + * @param opt - Options (set to NULL) + * + * @return The UID of the created pool, < 0 on error. + */ +int sceKernelCreateFpl(const char *name, int part, int attr, unsigned int size, unsigned int blocks, struct SceKernelFplOptParam *opt); + +/** + * Delete a fixed pool + * + * @param uid - The UID of the pool + * + * @return 0 on success, < 0 on error + */ +int sceKernelDeleteFpl(SceUID uid); + +/** + * Allocate from the pool + * + * @param uid - The UID of the pool + * @param data - Receives the address of the allocated data + * @param timeout - Amount of time to wait for allocation? + * + * @return 0 on success, < 0 on error + */ +int sceKernelAllocateFpl(SceUID uid, void **data, unsigned int *timeout); + +/** + * Allocate from the pool (with callback) + * + * @param uid - The UID of the pool + * @param data - Receives the address of the allocated data + * @param timeout - Amount of time to wait for allocation? + * + * @return 0 on success, < 0 on error + */ +int sceKernelAllocateFplCB(SceUID uid, void **data, unsigned int *timeout); + +/** + * Try to allocate from the pool + * + * @param uid - The UID of the pool + * @param data - Receives the address of the allocated data + * + * @return 0 on success, < 0 on error + */ +int sceKernelTryAllocateFpl(SceUID uid, void **data); + +/** + * Free a block + * + * @param uid - The UID of the pool + * @param data - The data block to deallocate + * + * @return 0 on success, < 0 on error + */ +int sceKernelFreeFpl(SceUID uid, void *data); + +/** + * Cancel a pool + * + * @param uid - The UID of the pool + * @param pnum - Receives the number of waiting threads + * + * @return 0 on success, < 0 on error + */ +int sceKernelCancelFpl(SceUID uid, int *pnum); + +/** Fixed pool status information */ +typedef struct SceKernelFplInfo { + SceSize size; + char name[32]; + SceUInt attr; + int blockSize; + int numBlocks; + int freeBlocks; + int numWaitThreads; +} SceKernelFplInfo; + +/** + * Get the status of an FPL + * + * @param uid - The uid of the FPL + * @param info - Pointer to a ::SceKernelFplInfo structure + * + * @return 0 on success, < 0 on error + */ +int sceKernelReferFplStatus(SceUID uid, SceKernelFplInfo *info); + +/** + * Return from a timer handler (doesn't seem to do alot) + */ +void _sceKernelReturnFromTimerHandler(void); + +/** + * Return from a callback (used as a syscall for the return + * of the callback function) + */ +void _sceKernelReturnFromCallback(void); + +/** + * Convert a number of microseconds to a ::SceKernelSysClock structure + * + * @param usec - Number of microseconds + * @param clock - Pointer to a ::SceKernelSysClock structure + * + * @return 0 on success, < 0 on error + */ +int sceKernelUSec2SysClock(unsigned int usec, SceKernelSysClock *clock); + +/** + * Convert a number of microseconds to a wide time + * + * @param usec - Number of microseconds. + * + * @return The time + */ +SceInt64 sceKernelUSec2SysClockWide(unsigned int usec); + +/** + * Convert a ::SceKernelSysClock structure to microseconds + * + * @param clock - Pointer to a ::SceKernelSysClock structure + * @param low - Pointer to the low part of the time + * @param high - Pointer to the high part of the time + * + * @return 0 on success, < 0 on error + */ +int sceKernelSysClock2USec(SceKernelSysClock *clock, unsigned int *low, unsigned int *high); + +/** + * Convert a wide time to microseconds + * + * @param clock - Wide time + * @param low - Pointer to the low part of the time + * @param high - Pointer to the high part of the time + * + * @return 0 on success, < 0 on error + */ +int sceKernelSysClock2USecWide(SceInt64 clock, unsigned *low, unsigned int *high); + +/** + * Get the system time + * + * @param time - Pointer to a ::SceKernelSysClock structure + * + * @return 0 on success, < 0 on error + */ +int sceKernelGetSystemTime(SceKernelSysClock *time); + +/** + * Get the system time (wide version) + * + * @return The system time + */ +SceInt64 sceKernelGetSystemTimeWide(void); + +/** + * Get the low 32bits of the current system time + * + * @return The low 32bits of the system time + */ +unsigned int sceKernelGetSystemTimeLow(void); + +struct SceKernelVTimerOptParam { + SceSize size; +}; + +/** + * Create a virtual timer + * + * @param name - Name for the timer. + * @param opt - Pointer to an ::SceKernelVTimerOptParam (pass NULL) + * + * @return The VTimer's UID or < 0 on error. + */ +SceUID sceKernelCreateVTimer(const char *name, struct SceKernelVTimerOptParam *opt); + +/** + * Delete a virtual timer + * + * @param uid - The UID of the timer + * + * @return < 0 on error. + */ +int sceKernelDeleteVTimer(SceUID uid); + +/** + * Get the timer base + * + * @param uid - UID of the vtimer + * @param base - Pointer to a ::SceKernelSysClock structure + * + * @return 0 on success, < 0 on error + */ +int sceKernelGetVTimerBase(SceUID uid, SceKernelSysClock *base); + +/** + * Get the timer base (wide format) + * + * @param uid - UID of the vtimer + * + * @return The 64bit timer base + */ +SceInt64 sceKernelGetVTimerBaseWide(SceUID uid); + +/** + * Get the timer time + * + * @param uid - UID of the vtimer + * @param time - Pointer to a ::SceKernelSysClock structure + * + * @return 0 on success, < 0 on error + */ +int sceKernelGetVTimerTime(SceUID uid, SceKernelSysClock *time); + +/** + * Get the timer time (wide format) + * + * @param uid - UID of the vtimer + * + * @return The 64bit timer time + */ +SceInt64 sceKernelGetVTimerTimeWide(SceUID uid); + +/** + * Set the timer time + * + * @param uid - UID of the vtimer + * @param time - Pointer to a ::SceKernelSysClock structure + * + * @return 0 on success, < 0 on error + */ +int sceKernelSetVTimerTime(SceUID uid, SceKernelSysClock *time); + +/** + * Set the timer time (wide format) + * + * @param uid - UID of the vtimer + * @param time - Pointer to a ::SceKernelSysClock structure + * + * @return Possibly the last time + */ +SceInt64 sceKernelSetVTimerTimeWide(SceUID uid, SceInt64 time); + +/** + * Start a virtual timer + * + * @param uid - The UID of the timer + * + * @return < 0 on error + */ +int sceKernelStartVTimer(SceUID uid); + +/** + * Stop a virtual timer + * + * @param uid - The UID of the timer + * + * @return < 0 on error + */ +int sceKernelStopVTimer(SceUID uid); + +typedef SceUInt (*SceKernelVTimerHandler)(SceUID uid, SceKernelSysClock *, SceKernelSysClock *, void *); +typedef SceUInt (*SceKernelVTimerHandlerWide)(SceUID uid, SceInt64, SceInt64, void *); + +/** + * Set the timer handler + * + * @param uid - UID of the vtimer + * @param time - Time to call the handler? + * @param handler - The timer handler + * @param common - Common pointer + * + * @return 0 on success, < 0 on error + */ +int sceKernelSetVTimerHandler(SceUID uid, SceKernelSysClock *time, SceKernelVTimerHandler handler, void *common); + +/** + * Set the timer handler (wide mode) + * + * @param uid - UID of the vtimer + * @param time - Time to call the handler? + * @param handler - The timer handler + * @param common - Common pointer + * + * @return 0 on success, < 0 on error + */ +int sceKernelSetVTimerHandlerWide(SceUID uid, SceInt64 time, SceKernelVTimerHandlerWide handler, void *common); + +/** + * Cancel the timer handler + * + * @param uid - The UID of the vtimer + * + * @return 0 on success, < 0 on error + */ +int sceKernelCancelVTimerHandler(SceUID uid); + +typedef struct SceKernelVTimerInfo { + SceSize size; + char name[32]; + int active; + SceKernelSysClock base; + SceKernelSysClock current; + SceKernelSysClock schedule; + SceKernelVTimerHandler handler; + void * common; +} SceKernelVTimerInfo; + +/** + * Get the status of a VTimer + * + * @param uid - The uid of the VTimer + * @param info - Pointer to a ::SceKernelVTimerInfo structure + * + * @return 0 on success, < 0 on error + */ +int sceKernelReferVTimerStatus(SceUID uid, SceKernelVTimerInfo *info); + +/** + * Exit the thread (probably used as the syscall when the main thread + * returns + */ +void _sceKernelExitThread(void); + +/** + * Get the type of a threadman uid + * + * @param uid - The uid to get the type from + * + * @return The type, < 0 on error + */ +enum SceKernelIdListType sceKernelGetThreadmanIdType(SceUID uid); + +typedef int (*SceKernelThreadEventHandler)(int mask, SceUID thid, void *common); + +/** Struct for event handler info */ +typedef struct SceKernelThreadEventHandlerInfo { + SceSize size; + char name[32]; + SceUID threadId; + int mask; + SceKernelThreadEventHandler handler; + void * common; +} SceKernelThreadEventHandlerInfo; + +enum ThreadEventIds +{ + THREADEVENT_ALL = 0xFFFFFFFF, + THREADEVENT_KERN = 0xFFFFFFF8, + THREADEVENT_USER = 0xFFFFFFF0, + THREADEVENT_CURRENT = 0 +}; + +enum ThreadEvents +{ + THREAD_CREATE = 1, + THREAD_START = 2, + THREAD_EXIT = 4, + THREAD_DELETE = 8, +}; + +/** + * Register a thread event handler + * + * @param name - Name for the thread event handler + * @param threadID - Thread ID to monitor + * @param mask - Bit mask for what events to handle (only lowest 4 bits valid) + * @param handler - Pointer to a ::SceKernelThreadEventHandler function + * @param common - Common pointer + * + * @return The UID of the create event handler, < 0 on error + */ +SceUID sceKernelRegisterThreadEventHandler(const char *name, SceUID threadID, int mask, SceKernelThreadEventHandler handler, void *common); + +/** + * Release a thread event handler. + * + * @param uid - The UID of the event handler + * + * @return 0 on success, < 0 on error + */ +int sceKernelReleaseThreadEventHandler(SceUID uid); + +/** + * Refer the status of an thread event handler + * + * @param uid - The UID of the event handler + * @param info - Pointer to a ::SceKernelThreadEventHandlerInfo structure + * + * @return 0 on success, < 0 on error + */ +int sceKernelReferThreadEventHandlerStatus(SceUID uid, struct SceKernelThreadEventHandlerInfo *info); + +/** + * Get the thread profiler registers. + * @return Pointer to the registers, NULL on error + */ +PspDebugProfilerRegs *sceKernelReferThreadProfiler(void); + +/** + * Get the globile profiler registers. + * @return Pointer to the registers, NULL on error + */ +PspDebugProfilerRegs *sceKernelReferGlobalProfiler(void); + +/*@}*/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/user/pspuser.h b/src/user/pspuser.h new file mode 100644 index 00000000..a5ebf922 --- /dev/null +++ b/src/user/pspuser.h @@ -0,0 +1,31 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspuser.h - Main include file for the user interface to the PSP kernel. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: pspuser.h 1207 2005-10-23 05:50:29Z mrbrown $ + */ + +#ifndef PSPUSER_H +#define PSPUSER_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif /* PSPUSER_H */ diff --git a/src/user/psputils.h b/src/user/psputils.h new file mode 100644 index 00000000..935d84ab --- /dev/null +++ b/src/user/psputils.h @@ -0,0 +1,230 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * psputils.h - Prototypes for the sceUtils library. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: psputils.h 1884 2006-04-30 08:55:54Z chip $ + */ +#ifndef __UTILS_H__ +#define __UTILS_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Some of the structures and definitions in this file were extracted from the japanese + puzzle bobble main executable */ + +/** @defgroup Utils Utils Library */ + +/** @addtogroup Utils */ + +/*@{*/ + +#include + +/** + * Get the time in seconds since the epoc (1st Jan 1970) + * + */ +time_t sceKernelLibcTime(time_t *t); + +/** + * Get the processor clock used since the start of the process + */ +clock_t sceKernelLibcClock(void); + +/** + * Get the current time of time and time zone information + */ +int sceKernelLibcGettimeofday(struct timeval *tp, struct timezone *tzp); + +/** + * Write back the data cache to memory + */ +void sceKernelDcacheWritebackAll(void); + +/** + * Write back and invalidate the data cache + */ +void sceKernelDcacheWritebackInvalidateAll(void); + +/** + * Write back a range of addresses from data cache to memory + */ +void sceKernelDcacheWritebackRange(const void *p, unsigned int size); + +/** + * Write back and invalidate a range of addresses in data cache + */ +void sceKernelDcacheWritebackInvalidateRange(const void *p, unsigned int size); + +/** + * Invalidate a range of addresses in data cache + */ +void sceKernelDcacheInvalidateRange(const void *p, unsigned int size); + +/** Structure for holding a mersenne twister context */ +typedef struct _SceKernelUtilsMt19937Context { + unsigned int count; + unsigned int state[624]; +} SceKernelUtilsMt19937Context; + +/** + * Function to initialise a mersenne twister context. + * + * @param ctx - Pointer to a context + * @param seed - A seed for the random function. + * + * @par Example: + * @code + * SceKernelUtilsMt19937Context ctx; + * sceKernelUtilsMt19937Init(&ctx, time(NULL)); + * u23 rand_val = sceKernelUtilsMt19937UInt(&ctx); + * @endcode + * + * @return < 0 on error. + */ +int sceKernelUtilsMt19937Init(SceKernelUtilsMt19937Context *ctx, u32 seed); + +/** + * Function to return a new psuedo random number. + * + * @param ctx - Pointer to a pre-initialised context. + * @return A pseudo random number (between 0 and MAX_INT). + */ +u32 sceKernelUtilsMt19937UInt(SceKernelUtilsMt19937Context *ctx); + +/** Structure to hold the MD5 context */ +typedef struct _SceKernelUtilsMd5Context { + unsigned int h[4]; + unsigned int pad; + SceUShort16 usRemains; + SceUShort16 usComputed; + SceULong64 ullTotalLen; + unsigned char buf[64]; +} SceKernelUtilsMd5Context; + +/** + * Function to perform an MD5 digest of a data block. + * + * @param data - Pointer to a data block to make a digest of. + * @param size - Size of the data block. + * @param digest - Pointer to a 16byte buffer to store the resulting digest + * + * @return < 0 on error. + */ +int sceKernelUtilsMd5Digest(u8 *data, u32 size, u8 *digest); + +/** + * Function to initialise a MD5 digest context + * + * @param ctx - A context block to initialise + * + * @return < 0 on error. + * @par Example: + * @code + * SceKernelUtilsMd5Context ctx; + * u8 digest[16]; + * sceKernelUtilsMd5BlockInit(&ctx); + * sceKernelUtilsMd5BlockUpdate(&ctx, (u8*) "Hello", 5); + * sceKernelUtilsMd5BlockResult(&ctx, digest); + * @endcode + */ +int sceKernelUtilsMd5BlockInit(SceKernelUtilsMd5Context *ctx); + +/** + * Function to update the MD5 digest with a block of data. + * + * @param ctx - A filled in context block. + * @param data - The data block to hash. + * @param size - The size of the data to hash + * + * @return < 0 on error. + */ +int sceKernelUtilsMd5BlockUpdate(SceKernelUtilsMd5Context *ctx, u8 *data, u32 size); + +/** + * Function to get the digest result of the MD5 hash. + * + * @param ctx - A filled in context block. + * @param digest - A 16 byte array to hold the digest. + * + * @return < 0 on error. + */ +int sceKernelUtilsMd5BlockResult(SceKernelUtilsMd5Context *ctx, u8 *digest); + +/** Type to hold a sha1 context */ +typedef struct _SceKernelUtilsSha1Context { + unsigned int h[5]; + SceUShort16 usRemains; + SceUShort16 usComputed; + SceULong64 ullTotalLen; + unsigned char buf[64]; +} SceKernelUtilsSha1Context; + +/** + * Function to SHA1 hash a data block. + * + * @param data - The data to hash. + * @param size - The size of the data. + * @param digest - Pointer to a 20 byte array for storing the digest + * + * @return < 0 on error. + */ +int sceKernelUtilsSha1Digest(u8 *data, u32 size, u8 *digest); + +/** + * Function to initialise a context for SHA1 hashing. + * + * @param ctx - Pointer to a context. + * + * @return < 0 on error. + * + * @par Example: + * @code + * SceKernelUtilsSha1Context ctx; + * u8 digest[20]; + * sceKernelUtilsSha1BlockInit(&ctx); + * sceKernelUtilsSha1BlockUpdate(&ctx, (u8*) "Hello", 5); + * sceKernelUtilsSha1BlockResult(&ctx, digest); + * @endcode + */ +int sceKernelUtilsSha1BlockInit(SceKernelUtilsSha1Context *ctx); + +/** + * Function to update the current hash. + * + * @param ctx - Pointer to a prefilled context. + * @param data - The data block to hash. + * @param size - The size of the data block + * + * @return < 0 on error. + */ +int sceKernelUtilsSha1BlockUpdate(SceKernelUtilsSha1Context *ctx, u8 *data, u32 size); + +/** + * Function to get the result of the SHA1 hash. + * + * @param ctx - Pointer to a prefilled context. + * @param digest - A pointer to a 20 byte array to contain the digest. + * + * @return < 0 on error. + */ +int sceKernelUtilsSha1BlockResult(SceKernelUtilsSha1Context *ctx, u8 *digest); + +/*@}*/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/user/sceImpose.S b/src/user/sceImpose.S new file mode 100644 index 00000000..a625bb7b --- /dev/null +++ b/src/user/sceImpose.S @@ -0,0 +1,52 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceImpose_0000 + IMPORT_START "sceImpose",0x40010011 +#endif +#ifdef F_sceImpose_0001 + IMPORT_FUNC "sceImpose",0x0F341BE4,sceImposeGetHomePopup +#endif +#ifdef F_sceImpose_0002 + IMPORT_FUNC "sceImpose",0x24FD7BCF,sceImposeGetLanguageMode +#endif +#ifdef F_sceImpose_0003 + IMPORT_FUNC "sceImpose",0x36AA6E91,sceImposeSetLanguageMode +#endif +#ifdef F_sceImpose_0004 + IMPORT_FUNC "sceImpose",0x381BD9E7,sceImposeHomeButton +#endif +#ifdef F_sceImpose_0005 + IMPORT_FUNC "sceImpose",0x5595A71A,sceImposeSetHomePopup +#endif +#ifdef F_sceImpose_0006 + IMPORT_FUNC "sceImpose",0x72189C48,sceImposeSetUMDPopup +#endif +#ifdef F_sceImpose_0007 + IMPORT_FUNC "sceImpose",0x8C943191,sceImposeBatteryIconStatus +#endif +#ifdef F_sceImpose_0008 + IMPORT_FUNC "sceImpose",0x8F6E3518,sceImposeGetBacklightOffTime +#endif +#ifdef F_sceImpose_0009 + IMPORT_FUNC "sceImpose",0x967F6D4A,sceImposeSetBacklightOffTime +#endif +#ifdef F_sceImpose_0010 + IMPORT_FUNC "sceImpose",0x9BA61B49,sceImpose_9BA61B49 +#endif +#ifdef F_sceImpose_0011 + IMPORT_FUNC "sceImpose",0xA9884B00,sceImpose_A9884B00 +#endif +#ifdef F_sceImpose_0012 + IMPORT_FUNC "sceImpose",0xBB3F5DEC,sceImpose_BB3F5DEC +#endif +#ifdef F_sceImpose_0013 + IMPORT_FUNC "sceImpose",0xE0887BC8,sceImposeGetUMDPopup +#endif +#ifdef F_sceImpose_0014 + IMPORT_FUNC "sceImpose",0xFCD44963,sceImpose_FCD44963 +#endif +#ifdef F_sceImpose_0015 + IMPORT_FUNC "sceImpose",0xFF1A2F07,sceImpose_FF1A2F07 +#endif diff --git a/src/user/sceSuspendForUser.S b/src/user/sceSuspendForUser.S new file mode 100644 index 00000000..cd080c64 --- /dev/null +++ b/src/user/sceSuspendForUser.S @@ -0,0 +1,25 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceSuspendForUser_0000 + IMPORT_START "sceSuspendForUser",0x40000000 +#endif +#ifdef F_sceSuspendForUser_0001 + IMPORT_FUNC "sceSuspendForUser",0xEADB1BD7,sceKernelPowerLock +#endif +#ifdef F_sceSuspendForUser_0002 + IMPORT_FUNC "sceSuspendForUser",0x3AEE7261,sceKernelPowerUnlock +#endif +#ifdef F_sceSuspendForUser_0003 + IMPORT_FUNC "sceSuspendForUser",0x090CCB3F,sceKernelPowerTick +#endif +#ifdef F_sceSuspendForUser_0004 + IMPORT_FUNC "sceSuspendForUser",0x3E0271D3,sceKernelVolatileMemLock +#endif +#ifdef F_sceSuspendForUser_0005 + IMPORT_FUNC "sceSuspendForUser",0xA14F40B2,sceKernelVolatileMemTryLock +#endif +#ifdef F_sceSuspendForUser_0006 + IMPORT_FUNC "sceSuspendForUser",0xA569E425,sceKernelVolatileMemUnlock +#endif diff --git a/src/utility/Makefile.am b/src/utility/Makefile.am new file mode 100644 index 00000000..c18c73ec --- /dev/null +++ b/src/utility/Makefile.am @@ -0,0 +1,40 @@ + +libdir = @PSPSDK_LIBDIR@ + +CC = @PSP_CC@ +CCAS = $(CC) +AR = @PSP_AR@ +RANLIB = @PSP_RANLIB@ + +INCLUDES = -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel +CFLAGS = @PSPSDK_CFLAGS@ +CCASFLAGS = $(CFLAGS) -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel + +UTILITY_OBJS = sceUtility_0000.o sceUtility_0001.o sceUtility_0002.o sceUtility_0003.o sceUtility_0004.o sceUtility_0005.o sceUtility_0006.o sceUtility_0007.o sceUtility_0008.o sceUtility_0009.o sceUtility_0010.o sceUtility_0011.o sceUtility_0012.o sceUtility_0013.o sceUtility_0014.o sceUtility_0015.o sceUtility_0016.o sceUtility_0017.o sceUtility_0018.o sceUtility_0019.o sceUtility_0020.o sceUtility_0021.o sceUtility_0022.o sceUtility_0023.o sceUtility_0024.o sceUtility_0025.o sceUtility_0026.o sceUtility_0027.o sceUtility_0028.o sceUtility_0029.o sceUtility_0030.o sceUtility_0031.o sceUtility_0032.o sceUtility_0033.o sceUtility_0034.o sceUtility_0035.o sceUtility_0036.o sceUtility_0037.o sceUtility_0038.o sceUtility_0039.o sceUtility_0040.o sceUtility_0041.o sceUtility_0042.o sceUtility_0043.o sceUtility_0044.o sceUtility_0045.o sceUtility_0046.o sceUtility_0047.o + +NETPARAM_OBJS = sceUtility_netparam_internal_0000.o sceUtility_netparam_internal_0001.o sceUtility_netparam_internal_0002.o sceUtility_netparam_internal_0003.o sceUtility_netparam_internal_0004.o + +libpsputilityincludedir = @PSPSDK_INCLUDEDIR@ +libpsputilityinclude_HEADERS = psputility.h \ + psputility_msgdialog.h \ + psputility_netconf.h \ + psputility_netparam.h \ + psputility_savedata.h \ + psputility_sysparam.h \ + psputility_osk.h \ + psputility_netmodules.h \ + psputility_avmodules.h \ + psputility_usbmodules.h \ + psputility_gamesharing.h \ + psputility_htmlviewer.h \ + psputility_modules.h + +lib_LIBRARIES = libpsputility.a +libpsputility_a_SOURCES = sceUtility.S sceUtility_netparam_internal.S +libpsputility_a_LIBADD = $(UTILITY_OBJS) $(NETPARAM_OBJS) + +$(UTILITY_OBJS): sceUtility.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(NETPARAM_OBJS): sceUtility_netparam_internal.S + $(COMPILE) -DF_$* $< -c -o $@ diff --git a/src/utility/psputility.h b/src/utility/psputility.h new file mode 100644 index 00000000..bb52f739 --- /dev/null +++ b/src/utility/psputility.h @@ -0,0 +1,58 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * psputility.h - Master include for the pspUtility library + * + * Copyright (c) 2005 John Kelley + * + * $Id: psputility.h 2387 2008-05-04 17:15:32Z iwn $ + */ +#ifndef __PSPUTILITY_H__ +#define __PSPUTILITY_H__ + +typedef struct +{ + unsigned int size; /** Size of the structure */ + int language; /** Language */ + int buttonSwap; /** Set to 1 for X/O button swap */ + int graphicsThread; /** Graphics thread priority */ + int accessThread; /** Access/fileio thread priority (SceJobThread) */ + int fontThread; /** Font thread priority (ScePafThread) */ + int soundThread; /** Sound thread priority */ + int result; /** Result */ + int reserved[4]; /** Set to 0 */ + +} pspUtilityDialogCommon; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PSP_UTILITY_ACCEPT_CIRCLE 0 +#define PSP_UTILITY_ACCEPT_CROSS 1 + +/** + * Return-values for the various sceUtility***GetStatus() functions +**/ +typedef enum +{ + PSP_UTILITY_DIALOG_NONE = 0, /**< No dialog is currently active */ + PSP_UTILITY_DIALOG_INIT, /**< The dialog is currently being initialized */ + PSP_UTILITY_DIALOG_VISIBLE, /**< The dialog is visible and ready for use */ + PSP_UTILITY_DIALOG_QUIT, /**< The dialog has been canceled and should be shut down */ + PSP_UTILITY_DIALOG_FINISHED /**< The dialog has successfully shut down */ + +} pspUtilityDialogState; + +#endif diff --git a/src/utility/psputility_avmodules.h b/src/utility/psputility_avmodules.h new file mode 100755 index 00000000..795a98dc --- /dev/null +++ b/src/utility/psputility_avmodules.h @@ -0,0 +1,52 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * psputility_avmodules.h - Load audio/video modules from user mode on 2.xx+ + * + * Copyright (c) 2007 David Perry + * + */ +#ifndef __PSPUTILITY_AVMODULES_H__ +#define __PSPUTILITY_AVMODULES_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#define PSP_AV_MODULE_AVCODEC 0 +#define PSP_AV_MODULE_SASCORE 1 +#define PSP_AV_MODULE_ATRAC3PLUS 2 // Requires PSP_AV_MODULE_AVCODEC loading first +#define PSP_AV_MODULE_MPEGBASE 3 // Requires PSP_AV_MODULE_AVCODEC loading first +#define PSP_AV_MODULE_MP3 4 +#define PSP_AV_MODULE_VAUDIO 5 +#define PSP_AV_MODULE_AAC 6 +#define PSP_AV_MODULE_G729 7 + +/** + * Load an audio/video module (PRX) from user mode. + * + * Available on firmware 2.00 and higher only. + * + * @param module - module number to load (PSP_AV_MODULE_xxx) + * @return 0 on success, < 0 on error + */ +int sceUtilityLoadAvModule(int module); + +/** + * Unload an audio/video module (PRX) from user mode. + * Available on firmware 2.00 and higher only. + * + * @param module - module number to be unloaded + * @return 0 on success, < 0 on error + */ +int sceUtilityUnloadAvModule(int module); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/utility/psputility_gamesharing.h b/src/utility/psputility_gamesharing.h new file mode 100644 index 00000000..9b46d786 --- /dev/null +++ b/src/utility/psputility_gamesharing.h @@ -0,0 +1,86 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * psputility_gamesharing.h - Game Sharing utility library + * + * Copyright (c) 2008 InsertWittyName + * + */ +#ifndef __PSPUTILITY_GAMESHARING_H__ +#define __PSPUTILITY_GAMESHARING_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum +{ + PSP_UTILITY_GAMESHARING_MODE_SINGLE = 1, /* Single send */ + PSP_UTILITY_GAMESHARING_MODE_MULTIPLE = 2 /* Up to 4 simultaneous sends */ + +} pspUtilityGameSharingMode; + +typedef enum +{ + PSP_UTILITY_GAMESHARING_DATA_TYPE_FILE = 1, /* EBOOT is a file */ + PSP_UTILITY_GAMESHARING_DATA_TYPE_MEMORY = 2, /* EBOOT is in memory */ + +} pspUtilityGameSharingDataType; + +/** + * Structure to hold the parameters for Game Sharing +**/ +typedef struct _pspUtilityGameSharingParams +{ + pspUtilityDialogCommon base; + int unknown1; /* Set to 0 */ + int unknown2; /* Set to 0 */ + char name[8]; + int unknown3; /* Set to 0 */ + int unknown4; /* Set to 0 */ + int unknown5; /* Set to 0 */ + int result; /* Return value */ + char *filepath; /* File path if PSP_UTILITY_GAMESHARING_DATA_TYPE_FILE specified */ + pspUtilityGameSharingMode mode; /* Send mode. One of ::pspUtilityGameSharingMode */ + pspUtilityGameSharingDataType datatype; /* Data type. One of ::pspUtilityGameSharingDataType */ + void *data; /* Pointer to the EBOOT data in memory */ + unsigned int datasize; /* Size of the EBOOT data in memory */ + +} pspUtilityGameSharingParams; + +/** + * Init the game sharing + * + * @param params - game sharing parameters + * @return 0 on success, < 0 on error. + */ +int sceUtilityGameSharingInitStart(pspUtilityGameSharingParams *params); + +/** + * Shutdown game sharing. + */ +void sceUtilityGameSharingShutdownStart(void); + +/** + * Get the current status of game sharing. + * + * @return 2 if the GUI is visible (you need to call sceUtilityGameSharingGetStatus). + * 3 if the user cancelled the dialog, and you need to call sceUtilityGameSharingShutdownStart. + * 4 if the dialog has been successfully shut down. + */ +int sceUtilityGameSharingGetStatus(void); + +/** + * Refresh the GUI for game sharing + * + * @param n - unknown, pass 1 + */ +void sceUtilityGameSharingUpdate(int n); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/utility/psputility_htmlviewer.h b/src/utility/psputility_htmlviewer.h new file mode 100644 index 00000000..0f960a08 --- /dev/null +++ b/src/utility/psputility_htmlviewer.h @@ -0,0 +1,192 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * psputility_htmlviewer.h - html viewer utility library. + * + * Copyright (c) 2008 David Perry (InsertWittyName) + * Copyright (c) 2008 moonlight + * + */ + +#ifndef __PSPUTILITY_HTMLVIEWER_H__ +#define __PSPUTILITY_HTMLVIEWER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +enum pspUtilityHtmlViewerDisconnectModes +{ + /** Enable automatic disconnect */ + PSP_UTILITY_HTMLVIEWER_DISCONNECTMODE_ENABLE = 0, + /** Disable automatic disconnect */ + PSP_UTILITY_HTMLVIEWER_DISCONNECTMODE_DISABLE, + /** Confirm disconnection */ + PSP_UTILITY_HTMLVIEWER_DISCONNECTMODE_CONFIRM +}; + +enum pspUtilityHtmlViewerInterfaceModes +{ + /** Full user interface */ + PSP_UTILITY_HTMLVIEWER_INTERFACEMODE_FULL = 0, + /** Limited user interface */ + PSP_UTILITY_HTMLVIEWER_INTERFACEMODE_LIMITED, + /** No user interface */ + PSP_UTILITY_HTMLVIEWER_INTERFACEMODE_NONE +}; + +enum pspUtilityHtmlViewerCookieModes +{ + /** Disable accepting cookies */ + PSP_UTILITY_HTMLVIEWER_COOKIEMODE_DISABLED = 0, + /** Enable accepting cookies */ + PSP_UTILITY_HTMLVIEWER_COOKIEMODE_ENABLED, + /** Confirm accepting a cookie every time */ + PSP_UTILITY_HTMLVIEWER_COOKIEMODE_CONFIRM, + /** Use the system default for accepting cookies */ + PSP_UTILITY_HTMLVIEWER_COOKIEMODE_DEFAULT +}; + +enum pspUtilityHtmlViewerTextSizes +{ + /** Large text size */ + PSP_UTILITY_HTMLVIEWER_TEXTSIZE_LARGE = 0, + /** Normal text size */ + PSP_UTILITY_HTMLVIEWER_TEXTSIZE_NORMAL, + /** Small text size */ + PSP_UTILITY_HTMLVIEWER_TEXTSIZE_SMALL +}; + +enum pspUtilityHtmlViewerDisplayModes +{ + /** Normal display */ + PSP_UTILITY_HTMLVIEWER_DISPLAYMODE_NORMAL = 0, + /** Fit display */ + PSP_UTILITY_HTMLVIEWER_DISPLAYMODE_FIT, + /** Smart fit display */ + PSP_UTILITY_HTMLVIEWER_DISPLAYMODE_SMART_FIT +}; + +enum pspUtilityHtmlViewerConnectModes +{ + /** Auto connect to last used connection */ + PSP_UTILITY_HTMLVIEWER_CONNECTMODE_LAST = 0, + /** Manually select the connection (once) */ + PSP_UTILITY_HTMLVIEWER_CONNECTMODE_MANUAL_ONCE, + /** Manually select the connection (every time) */ + PSP_UTILITY_HTMLVIEWER_CONNECTMODE_MANUAL_ALL +}; + +enum pspUtilityHtmlViewerOptions +{ + /** Open SCE net start page */ + PSP_UTILITY_HTMLVIEWER_OPEN_SCE_START_PAGE = 0x000001, + /** Disable startup limitations */ + PSP_UTILITY_HTMLVIEWER_DISABLE_STARTUP_LIMITS = 0x000002, + /** Disable exit confirmation dialog */ + PSP_UTILITY_HTMLVIEWER_DISABLE_EXIT_DIALOG = 0x000004, + /** Disable cursor */ + PSP_UTILITY_HTMLVIEWER_DISABLE_CURSOR = 0x000008, + /** Disable download completion confirmation dialog */ + PSP_UTILITY_HTMLVIEWER_DISABLE_DOWNLOAD_COMPLETE_DIALOG = 0x000010, + /** Disable download confirmation dialog */ + PSP_UTILITY_HTMLVIEWER_DISABLE_DOWNLOAD_START_DIALOG = 0x000020, + /** Disable save destination confirmation dialog */ + PSP_UTILITY_HTMLVIEWER_DISABLE_DOWNLOAD_DESTINATION_DIALOG = 0x000040, + /** Disable modification of the download destination */ + PSP_UTILITY_HTMLVIEWER_LOCK_DOWNLOAD_DESTINATION_DIALOG = 0x000080, + /** Disable tab display */ + PSP_UTILITY_HTMLVIEWER_DISABLE_TAB_DISPLAY = 0x000100, + /** Hold analog controller when HOLD button is down */ + PSP_UTILITY_HTMLVIEWER_ENABLE_ANALOG_HOLD = 0x000200, + /** Enable Flash Player */ + PSP_UTILITY_HTMLVIEWER_ENABLE_FLASH = 0x000400, + /** Disable L/R triggers for back/forward */ + PSP_UTILITY_HTMLVIEWER_DISABLE_LRTRIGGER = 0x000800 +}; + +typedef struct pspUtilityHtmlViewerParam +{ + pspUtilityDialogCommon base; + /** Pointer to the memory pool to be used */ + void* memaddr; + /** Size of the memory pool */ + unsigned int memsize; + /** Unknown. Pass 0 */ + int unknown1; + /** Unknown. Pass 0 */ + int unknown2; + /** URL to be opened initially */ + char* initialurl; + /** Number of tabs (maximum of 3) */ + unsigned int numtabs; + /** One of ::pspUtilityHtmlViewerInterfaceModes */ + unsigned int interfacemode; + /** Values from ::pspUtilityHtmlViewerOptions. Bitwise OR together */ + unsigned int options; + /** Directory to be used for downloading */ + char* dldirname; + /** Filename to be used for downloading */ + char* dlfilename; + /** Directory to be used for uploading */ + char* uldirname; + /** Filename to be used for uploading */ + char* ulfilename; + /** One of ::pspUtilityHtmlViewerCookieModes */ + unsigned int cookiemode; + /** Unknown. Pass 0 */ + unsigned int unknown3; + /** URL to set the home page to */ + char* homeurl; + /** One of ::pspUtilityHtmlViewerTextSizes */ + unsigned int textsize; + /** One of ::pspUtilityHtmlViewerDisplayModes */ + unsigned int displaymode; + /** One of ::pspUtilityHtmlViewerConnectModes */ + unsigned int connectmode; + /** One of ::pspUtilityHtmlViewerDisconnectModes */ + unsigned int disconnectmode; + /** The maximum amount of memory the browser used */ + unsigned int memused; + /** Unknown. Pass 0 */ + int unknown4[10]; + +} pspUtilityHtmlViewerParam; + +/** + * Init the html viewer + * + * @param params - html viewer parameters + * + * @return 0 on success, < 0 on error. + */ +int sceUtilityHtmlViewerInitStart(pspUtilityHtmlViewerParam *params); + +/** + * Shutdown html viewer. + */ +int sceUtilityHtmlViewerShutdownStart(void); + +/** + * Refresh the GUI for html viewer + * + * @param n - unknown, pass 1 + */ +int sceUtilityHtmlViewerUpdate(int n); + +/** + * Get the current status of the html viewer. + * + * @return 2 if the GUI is visible (you need to call sceUtilityHtmlViewerGetStatus). + * 3 if the user cancelled the dialog, and you need to call sceUtilityHtmlViewerShutdownStart. + * 4 if the dialog has been successfully shut down. + */ +int sceUtilityHtmlViewerGetStatus(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/utility/psputility_modules.h b/src/utility/psputility_modules.h new file mode 100755 index 00000000..5749c287 --- /dev/null +++ b/src/utility/psputility_modules.h @@ -0,0 +1,78 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * psputility_modules.h - Load modules from user mode + * + * Copyright (c) 2008 David Perry + * + */ +#ifndef __PSPUTILITY_MODULES_H__ +#define __PSPUTILITY_MODULES_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Net Modules */ +#define PSP_MODULE_NET_COMMON 0x0100 +#define PSP_MODULE_NET_ADHOC 0x0101 +#define PSP_MODULE_NET_INET 0x0102 +#define PSP_MODULE_NET_PARSEURI 0x0103 +#define PSP_MODULE_NET_PARSEHTTP 0x0104 +#define PSP_MODULE_NET_HTTP 0x0105 +#define PSP_MODULE_NET_SSL 0x0106 + +/* USB Modules */ +#define PSP_MODULE_USB_PSPCM 0x0200 +#define PSP_MODULE_USB_MIC 0x0201 +#define PSP_MODULE_USB_CAM 0x0202 +#define PSP_MODULE_USB_GPS 0x0203 + +/* Audio/video Modules */ +#define PSP_MODULE_AV_AVCODEC 0x0300 +#define PSP_MODULE_AV_SASCORE 0x0301 +#define PSP_MODULE_AV_ATRAC3PLUS 0x0302 +#define PSP_MODULE_AV_MPEGBASE 0x0303 +#define PSP_MODULE_AV_MP3 0x0304 +#define PSP_MODULE_AV_VAUDIO 0x0305 +#define PSP_MODULE_AV_AAC 0x0306 +#define PSP_MODULE_AV_G729 0x0307 + +/* NP */ +#define PSP_MODULE_NP_COMMON 0x0400 +#define PSP_MODULE_NP_SERVICE 0x0401 +#define PSP_MODULE_NP_MATCHING2 0x0402 + +#define PSP_MODULE_NP_DRM 0x0500 + +/* IrDA */ +#define PSP_MODULE_IRDA 0x0600 + + +/** + * Load a module (PRX) from user mode. + * + * @param module - module to load (PSP_MODULE_xxx) + * + * @return 0 on success, < 0 on error + */ +int sceUtilityLoadModule(int module); + +/** + * Unload a module (PRX) from user mode. + * + * @param module - module to unload (PSP_MODULE_xxx) + * + * @return 0 on success, < 0 on error + */ +int sceUtilityUnloadModule(int module); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/utility/psputility_msgdialog.h b/src/utility/psputility_msgdialog.h new file mode 100644 index 00000000..6b2e342a --- /dev/null +++ b/src/utility/psputility_msgdialog.h @@ -0,0 +1,102 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * psputility_msdialog.h - Definitions and Functions for Dialogs + * section of the pspUtility library + * + * Copyright (c) 2005 Marcus Comstedt + * (c) 2008 InsertWittyName + * + * $Id: psputility_msgdialog.h 2433 2008-10-15 10:00:27Z iwn $ + */ +#ifndef __PSPUTILITY_DIALOGS_H__ +#define __PSPUTILITY_DIALOGS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum +{ + PSP_UTILITY_MSGDIALOG_MODE_ERROR = 0, /* Error message */ + PSP_UTILITY_MSGDIALOG_MODE_TEXT /* String message */ + +} pspUtilityMsgDialogMode; + +typedef enum +{ + PSP_UTILITY_MSGDIALOG_OPTION_ERROR = 0, /* Error message (why two flags?) */ + PSP_UTILITY_MSGDIALOG_OPTION_TEXT = 0x00000001, /* Text message (why two flags?) */ + PSP_UTILITY_MSGDIALOG_OPTION_YESNO_BUTTONS = 0x00000010, /* Yes/No buttons instead of 'Cancel' */ + PSP_UTILITY_MSGDIALOG_OPTION_DEFAULT_NO = 0x00000100 /* Default position 'No', if not set will default to 'Yes' */ + +} pspUtilityMsgDialogOption; + +typedef enum +{ + PSP_UTILITY_MSGDIALOG_RESULT_UNKNOWN1 = 0, + PSP_UTILITY_MSGDIALOG_RESULT_YES, + PSP_UTILITY_MSGDIALOG_RESULT_NO, + PSP_UTILITY_MSGDIALOG_RESULT_BACK + +} pspUtilityMsgDialogPressed; + +/** + * Structure to hold the parameters for a message dialog +**/ +typedef struct _pspUtilityMsgDialogParams +{ + pspUtilityDialogCommon base; + int unknown; + pspUtilityMsgDialogMode mode; + unsigned int errorValue; + /** The message to display (may contain embedded linefeeds) */ + char message[512]; + int options; /* OR ::pspUtilityMsgDialogOption together for multiple options */ + pspUtilityMsgDialogPressed buttonPressed; + +} pspUtilityMsgDialogParams; + +/** + * Create a message dialog + * + * @param params - dialog parameters + * @return 0 on success + */ +int sceUtilityMsgDialogInitStart(pspUtilityMsgDialogParams *params); + +/** + * Remove a message dialog currently active. After calling this + * function you need to keep calling GetStatus and Update until + * you get a status of 4. + */ +void sceUtilityMsgDialogShutdownStart(void); + +/** + * Get the current status of a message dialog currently active. + * + * @return 2 if the GUI is visible (you need to call sceUtilityMsgDialogGetStatus). + * 3 if the user cancelled the dialog, and you need to call sceUtilityMsgDialogShutdownStart. + * 4 if the dialog has been successfully shut down. + */ +int sceUtilityMsgDialogGetStatus(void); + +/** + * Refresh the GUI for a message dialog currently active + * + * @param n - unknown, pass 1 + */ +void sceUtilityMsgDialogUpdate(int n); + +/** + * Abort a message dialog currently active + */ +int sceUtilityMsgDialogAbort(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/utility/psputility_netconf.h b/src/utility/psputility_netconf.h new file mode 100644 index 00000000..280d16f9 --- /dev/null +++ b/src/utility/psputility_netconf.h @@ -0,0 +1,80 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * psputility_netconf.h - Definitions and Functions for Network Configuration + * section of the pspUtility library + * + * Copyright (c) 2005 John Kelley + * + * $Id: psputility_netconf.h 2363 2008-02-16 19:40:17Z iwn $ + */ +#ifndef __PSPUTILITY_NETCONF_H__ +#define __PSPUTILITY_NETCONF_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +enum pspUtilityNetconfActions +{ + PSP_NETCONF_ACTION_CONNECTAP, + PSP_NETCONF_ACTION_DISPLAYSTATUS, + PSP_NETCONF_ACTION_CONNECT_ADHOC +}; + +struct pspUtilityNetconfAdhoc +{ + unsigned char name[8]; + unsigned int timeout; +}; + +typedef struct _pspUtilityNetconfData +{ + pspUtilityDialogCommon base; + int action; /** One of pspUtilityNetconfActions */ + struct pspUtilityNetconfAdhoc *adhocparam; //* Adhoc connection params */ + int hotspot; /** Set to 1 to allow connections with the 'Internet Browser' option set to 'Start' (ie. hotspot connection) */ + int hotspot_connected; /** Will be set to 1 when connected to a hotspot style connection */ + int wifisp; /** Set to 1 to allow connections to Wifi service providers (WISP) */ + +} pspUtilityNetconfData; + +/** + * Init the Network Configuration Dialog Utility + * + * @param data - pointer to pspUtilityNetconfData to be initialized + * @return 0 on success, < 0 on error + */ +int sceUtilityNetconfInitStart (pspUtilityNetconfData *data); + +/** + * Shutdown the Network Configuration Dialog Utility + * + * @return 0 on success, < 0 on error + */ +int sceUtilityNetconfShutdownStart (void); + +/** + * Update the Network Configuration Dialog GUI + * + * @param unknown - unknown; set to 1 + * @return 0 on success, < 0 on error + */ +int sceUtilityNetconfUpdate (int unknown); + +/** + * Get the status of a running Network Configuration Dialog + * + * @return one of pspUtilityDialogState on success, < 0 on error + */ +int sceUtilityNetconfGetStatus (void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/utility/psputility_netmodules.h b/src/utility/psputility_netmodules.h new file mode 100644 index 00000000..a7bc6adb --- /dev/null +++ b/src/utility/psputility_netmodules.h @@ -0,0 +1,53 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * psputility_netmodules.h - Load network modules from user mode on 2.xx+ + * + * Copyright (c) 2005 John Kelley + * + * $Id: psputility_netmodules.h 2002 2006-09-16 16:49:57Z jim $ + */ +#ifndef __PSPUTILITY_NETMODULES_H__ +#define __PSPUTILITY_NETMODULES_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#define PSP_NET_MODULE_COMMON 1 +#define PSP_NET_MODULE_ADHOC 2 +#define PSP_NET_MODULE_INET 3 +#define PSP_NET_MODULE_PARSEURI 4 +#define PSP_NET_MODULE_PARSEHTTP 5 +#define PSP_NET_MODULE_HTTP 6 +#define PSP_NET_MODULE_SSL 7 + +/** + * Load a network module (PRX) from user mode. + * Load PSP_NET_MODULE_COMMON and PSP_NET_MODULE_INET + * to use infrastructure WifI (via an access point). + * Available on firmware 2.00 and higher only. + * + * @param module - module number to load (PSP_NET_MODULE_xxx) + * @return 0 on success, < 0 on error + */ +int sceUtilityLoadNetModule(int module); + +/** + * Unload a network module (PRX) from user mode. + * Available on firmware 2.00 and higher only. + * + * @param module - module number be unloaded + * @return 0 on success, < 0 on error + */ +int sceUtilityUnloadNetModule(int module); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/utility/psputility_netparam.h b/src/utility/psputility_netparam.h new file mode 100644 index 00000000..3ccae917 --- /dev/null +++ b/src/utility/psputility_netparam.h @@ -0,0 +1,117 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * psputility_netparam.h - Definitions and Functions to manage Network + * parameters. + * + * Copyright (c) 2005 John Kelley + * + * $Id: psputility_netparam.h 2433 2008-10-15 10:00:27Z iwn $ + */ +#ifndef __PSPUTILITY_NETPARAM_H__ +#define __PSPUTILITY_NETPARAM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** + * Datatype for sceUtilityGetNetParam + * since it can return a u32 or a string + * we use a union to avoid ugly casting + */ +typedef union { + u32 asUint; + char asString[128]; +} netData; + +#define PSP_NETPARAM_NAME 0 // string +#define PSP_NETPARAM_SSID 1 // string +#define PSP_NETPARAM_SECURE 2 // int +#define PSP_NETPARAM_WEPKEY 3 // string +#define PSP_NETPARAM_IS_STATIC_IP 4 // int +#define PSP_NETPARAM_IP 5 // string +#define PSP_NETPARAM_NETMASK 6 // string +#define PSP_NETPARAM_ROUTE 7 // string +#define PSP_NETPARAM_MANUAL_DNS 8 // int +#define PSP_NETPARAM_PRIMARYDNS 9 // string +#define PSP_NETPARAM_SECONDARYDNS 10 // string +#define PSP_NETPARAM_PROXY_USER 11 // string +#define PSP_NETPARAM_PROXY_PASS 12 // string +#define PSP_NETPARAM_USE_PROXY 13 // int +#define PSP_NETPARAM_PROXY_SERVER 14 // string +#define PSP_NETPARAM_PROXY_PORT 15 // int +#define PSP_NETPARAM_UNKNOWN1 16 // int +#define PSP_NETPARAM_UNKNOWN2 17 // int + +#define PSP_NETPARAM_ERROR_BAD_NETCONF 0x80110601 +#define PSP_NETPARAM_ERROR_BAD_PARAM 0x80110604 + +/** + * Check existance of a Net Configuration + * + * @param id - id of net Configuration (1 to n) + * @return 0 on success, + */ +int sceUtilityCheckNetParam(int id); + +/** + * Get Net Configuration Parameter + * + * @param conf - Net Configuration number (1 to n) + * (0 returns valid but seems to be a copy of the last config requested) + * @param param - which parameter to get + * @param data - parameter data + * @return 0 on success, + */ +int sceUtilityGetNetParam(int conf, int param, netData *data); + +/** + * Create a new Network Configuration + * @note This creates a new configuration at conf and clears 0 + * + * @param conf - Net Configuration number (1 to n) + * + * @return 0 on success + */ +int sceUtilityCreateNetParam(int conf); + +/** + * Sets a network parameter + * @note This sets only to configuration 0 + * + * @param param - Which parameter to set + * @param val - Pointer to the the data to set + * + * @return 0 on success + */ +int sceUtilitySetNetParam(int param, const void *val); + +/** + * Copies a Network Configuration to another + * + * @param src - Source Net Configuration number (0 to n) + * @param dest - Destination Net Configuration number (0 to n) + * + * @return 0 on success + */ +int sceUtilityCopyNetParam(int src, int dest); + +/** + * Deletes a Network Configuration + * + * @param conf - Net Configuration number (1 to n) + * + * @return 0 on success + */ +int sceUtilityDeleteNetParam(int conf); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/utility/psputility_osk.h b/src/utility/psputility_osk.h new file mode 100644 index 00000000..3d62e6f4 --- /dev/null +++ b/src/utility/psputility_osk.h @@ -0,0 +1,181 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * psputility_osk.h - Definitions and Functions for OSK section of + * the pspUtility library + * + * Copyright (c) 2006 McZonk + * Copyright (c) 2008 InsertWittyName + * + * $Id: psputility_osk.h 2433 2008-10-15 10:00:27Z iwn $ + */ +#ifndef PSPOSK_H +#define PSPOSK_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** + * Enumeration for input language + */ +enum SceUtilityOskInputLanguage +{ + PSP_UTILITY_OSK_LANGUAGE_DEFAULT = 0x00, + PSP_UTILITY_OSK_LANGUAGE_JAPANESE = 0x01, + PSP_UTILITY_OSK_LANGUAGE_ENGLISH = 0x02, + PSP_UTILITY_OSK_LANGUAGE_FRENCH = 0x03, + PSP_UTILITY_OSK_LANGUAGE_SPANISH = 0x04, + PSP_UTILITY_OSK_LANGUAGE_GERMAN = 0x05, + PSP_UTILITY_OSK_LANGUAGE_ITALIAN = 0x06, + PSP_UTILITY_OSK_LANGUAGE_DUTCH = 0x07, + PSP_UTILITY_OSK_LANGUAGE_PORTUGESE = 0x08, + PSP_UTILITY_OSK_LANGUAGE_RUSSIAN = 0x09, + PSP_UTILITY_OSK_LANGUAGE_KOREAN = 0x0a +}; + +/** + * Enumeration for OSK internal state + */ +enum SceUtilityOskState +{ + PSP_UTILITY_OSK_DIALOG_NONE = 0, /**< No OSK is currently active */ + PSP_UTILITY_OSK_DIALOG_INITING, /**< The OSK is currently being initialized */ + PSP_UTILITY_OSK_DIALOG_INITED, /**< The OSK is initialised */ + PSP_UTILITY_OSK_DIALOG_VISIBLE, /**< The OSK is visible and ready for use */ + PSP_UTILITY_OSK_DIALOG_QUIT, /**< The OSK has been cancelled and should be shut down */ + PSP_UTILITY_OSK_DIALOG_FINISHED /**< The OSK has successfully shut down */ +}; + +/** + * Enumeration for OSK field results + */ +enum SceUtilityOskResult +{ + PSP_UTILITY_OSK_RESULT_UNCHANGED = 0, + PSP_UTILITY_OSK_RESULT_CANCELLED, + PSP_UTILITY_OSK_RESULT_CHANGED +}; + +/** + * Enumeration for input types (these are limited by initial choice of language) + */ +enum SceUtilityOskInputType +{ + PSP_UTILITY_OSK_INPUTTYPE_ALL = 0x00000000, + PSP_UTILITY_OSK_INPUTTYPE_LATIN_DIGIT = 0x00000001, + PSP_UTILITY_OSK_INPUTTYPE_LATIN_SYMBOL = 0x00000002, + PSP_UTILITY_OSK_INPUTTYPE_LATIN_LOWERCASE = 0x00000004, + PSP_UTILITY_OSK_INPUTTYPE_LATIN_UPPERCASE = 0x00000008, + PSP_UTILITY_OSK_INPUTTYPE_JAPANESE_DIGIT = 0x00000100, + PSP_UTILITY_OSK_INPUTTYPE_JAPANESE_SYMBOL = 0x00000200, + PSP_UTILITY_OSK_INPUTTYPE_JAPANESE_LOWERCASE = 0x00000400, + PSP_UTILITY_OSK_INPUTTYPE_JAPANESE_UPPERCASE = 0x00000800, + // http://en.wikipedia.org/wiki/Hiragana + PSP_UTILITY_OSK_INPUTTYPE_JAPANESE_HIRAGANA = 0x00001000, + // http://en.wikipedia.org/wiki/Katakana + // Half-width Katakana + PSP_UTILITY_OSK_INPUTTYPE_JAPANESE_HALF_KATAKANA = 0x00002000, + PSP_UTILITY_OSK_INPUTTYPE_JAPANESE_KATAKANA = 0x00004000, + // http://en.wikipedia.org/wiki/Kanji + PSP_UTILITY_OSK_INPUTTYPE_JAPANESE_KANJI = 0x00008000, + PSP_UTILITY_OSK_INPUTTYPE_RUSSIAN_LOWERCASE = 0x00010000, + PSP_UTILITY_OSK_INPUTTYPE_RUSSIAN_UPPERCASE = 0x00020000, + PSP_UTILITY_OSK_INPUTTYPE_KOREAN = 0x00040000, + PSP_UTILITY_OSK_INPUTTYPE_URL = 0x00080000 +}; + +/** + * OSK Field data + */ +typedef struct _SceUtilityOskData +{ + /** Unknown. Pass 0. */ + int unk_00; + /** Unknown. Pass 0. */ + int unk_04; + /** One of ::SceUtilityOskInputLanguage */ + int language; + /** Unknown. Pass 0. */ + int unk_12; + /** One or more of ::SceUtilityOskInputType (types that are selectable by pressing SELECT) */ + int inputtype; + /** Number of lines */ + int lines; + /** Unknown. Pass 0. */ + int unk_24; + /** Description text */ + unsigned short* desc; + /** Initial text */ + unsigned short* intext; + /** Length of output text */ + int outtextlength; + /** Pointer to the output text */ + unsigned short* outtext; + /** Result. One of ::SceUtilityOskResult */ + int result; + /** The max text that can be input */ + int outtextlimit; + +} SceUtilityOskData; + +/** + * OSK parameters + */ +typedef struct _SceUtilityOskParams +{ + pspUtilityDialogCommon base; + /** Number of input fields */ + int datacount; + /** Pointer to the start of the data for the input fields */ + SceUtilityOskData* data; + /** The local OSK state, one of ::SceUtilityOskState */ + int state; + /** Unknown. Pass 0 */ + int unk_60; + +} SceUtilityOskParams; + +/** + * Create an on-screen keyboard + * + * @param params - OSK parameters. + * + * @return < 0 on error. + */ +int sceUtilityOskInitStart(SceUtilityOskParams* params); + +/** + * Remove a currently active keyboard. After calling this function you must + * + * poll sceUtilityOskGetStatus() until it returns PSP_UTILITY_DIALOG_NONE. + * + * @return < 0 on error. + */ +int sceUtilityOskShutdownStart(void); + +/** + * Refresh the GUI for a keyboard currently active + * + * @param n - Unknown, pass 1. + * + * @return < 0 on error. + */ +int sceUtilityOskUpdate(int n); + +/** + * Get the status of a on-screen keyboard currently active. + * + * @return the current status of the keyboard. See ::pspUtilityDialogState for details. + */ +int sceUtilityOskGetStatus(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/utility/psputility_savedata.h b/src/utility/psputility_savedata.h new file mode 100644 index 00000000..b1003d61 --- /dev/null +++ b/src/utility/psputility_savedata.h @@ -0,0 +1,183 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * psputility_savedata.h - Definitions and Functions for savedata part of + * pspUtility library + * + * Copyright (c) 2005 Shine + * weltall + * Marcus R. Brown + * InsertWittyName + * + * $Id: psputility_savedata.h 2433 2008-10-15 10:00:27Z iwn $ + */ + +#ifndef __PSPUTILITY_SAVEDATA_H__ +#define __PSPUTILITY_SAVEDATA_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Save data utility modes */ +typedef enum +{ + PSP_UTILITY_SAVEDATA_AUTOLOAD = 0, + PSP_UTILITY_SAVEDATA_AUTOSAVE, + PSP_UTILITY_SAVEDATA_LOAD, + PSP_UTILITY_SAVEDATA_SAVE, + PSP_UTILITY_SAVEDATA_LISTLOAD, + PSP_UTILITY_SAVEDATA_LISTSAVE, + PSP_UTILITY_SAVEDATA_LISTDELETE, + PSP_UTILITY_SAVEDATADELETE, + +} PspUtilitySavedataMode; + +/** Initial focus position for list selection types */ +typedef enum +{ + PSP_UTILITY_SAVEDATA_FOCUS_UNKNOWN = 0, + PSP_UTILITY_SAVEDATA_FOCUS_FIRSTLIST, /* First in list */ + PSP_UTILITY_SAVEDATA_FOCUS_LASTLIST, /* Last in list */ + PSP_UTILITY_SAVEDATA_FOCUS_LATEST, /* Most recent date */ + PSP_UTILITY_SAVEDATA_FOCUS_OLDEST, /* Oldest date */ + PSP_UTILITY_SAVEDATA_FOCUS_UNKNOWN2, + PSP_UTILITY_SAVEDATA_FOCUS_UNKNOWN3, + PSP_UTILITY_SAVEDATA_FOCUS_FIRSTEMPTY, /* First empty slot */ + PSP_UTILITY_SAVEDATA_FOCUS_LASTEMPTY, /*Last empty slot */ + +} PspUtilitySavedataFocus; + + +/** title, savedataTitle, detail: parts of the unencrypted SFO + data, it contains what the VSH and standard load screen shows */ +typedef struct PspUtilitySavedataSFOParam +{ + char title[0x80]; + char savedataTitle[0x80]; + char detail[0x400]; + unsigned char parentalLevel; + unsigned char unknown[3]; + +} PspUtilitySavedataSFOParam; + +typedef struct PspUtilitySavedataFileData { + void *buf; + SceSize bufSize; + SceSize size; /* ??? - why are there two sizes? */ + int unknown; + +} PspUtilitySavedataFileData; + +typedef struct PspUtilitySavedataListSaveNewData +{ + PspUtilitySavedataFileData icon0; + char *title; + +} PspUtilitySavedataListSaveNewData; + +/** Structure to hold the parameters for the ::sceUtilitySavedataInitStart function. */ +typedef struct SceUtilitySavedataParam +{ + pspUtilityDialogCommon base; + + PspUtilitySavedataMode mode; + + int unknown1; + + int overwrite; + + /** gameName: name used from the game for saves, equal for all saves */ + char gameName[13]; + char reserved[3]; + /** saveName: name of the particular save, normally a number */ + char saveName[20]; + + /** saveNameList: used by multiple modes */ + char (*saveNameList)[20]; + + /** fileName: name of the data file of the game for example DATA.BIN */ + char fileName[13]; + char reserved1[3]; + + /** pointer to a buffer that will contain data file unencrypted data */ + void *dataBuf; + /** size of allocated space to dataBuf */ + SceSize dataBufSize; + SceSize dataSize; + + PspUtilitySavedataSFOParam sfoParam; + + PspUtilitySavedataFileData icon0FileData; + PspUtilitySavedataFileData icon1FileData; + PspUtilitySavedataFileData pic1FileData; + PspUtilitySavedataFileData snd0FileData; + + /** Pointer to an PspUtilitySavedataListSaveNewData structure */ + PspUtilitySavedataListSaveNewData *newData; + + /** Initial focus for lists */ + PspUtilitySavedataFocus focus; + + /** unknown2: ? */ + int unknown2[4]; + +#if _PSP_FW_VERSION >= 200 + + /** key: encrypt/decrypt key for save with firmware >= 2.00 */ + char key[16]; + + /** unknown3: ? */ + char unknown3[20]; + +#endif + +} SceUtilitySavedataParam; + + +/** + * Saves or Load savedata to/from the passed structure + * After having called this continue calling sceUtilitySavedataGetStatus to + * check if the operation is completed + * + * @param params - savedata parameters + * @return 0 on success + */ +int sceUtilitySavedataInitStart(SceUtilitySavedataParam * params); + +/** + * Check the current status of the saving/loading/shutdown process + * Continue calling this to check current status of the process + * before calling this call also sceUtilitySavedataUpdate + * @return 2 if the process is still being processed. + * 3 on save/load success, then you can call sceUtilitySavedataShutdownStart. + * 4 on complete shutdown. + */ +int sceUtilitySavedataGetStatus(void); + + +/** + * Shutdown the savedata utility. after calling this continue calling + * ::sceUtilitySavedataGetStatus to check when it has shutdown + * + * @return 0 on success + * + */ +int sceUtilitySavedataShutdownStart(void); + +/** + * Refresh status of the savedata function + * + * @param unknown - unknown, pass 1 + */ +void sceUtilitySavedataUpdate(int unknown); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/utility/psputility_sysparam.h b/src/utility/psputility_sysparam.h new file mode 100644 index 00000000..032f41c5 --- /dev/null +++ b/src/utility/psputility_sysparam.h @@ -0,0 +1,141 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * psputility_sysparam.h - Definitions and Functions for System Paramters + * section of the pspUtility library + * + * Copyright (c) 2005 John Kelley + * + * $Id: psputility_sysparam.h 2433 2008-10-15 10:00:27Z iwn $ + */ +#ifndef __PSPUTILITY_SYSPARAM_H__ +#define __PSPUTILITY_SYSPARAM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** + * IDs for use inSystemParam functions + * PSP_SYSTEMPARAM_ID_INT are for use with SystemParamInt funcs + * PSP_SYSTEMPARAM_ID_STRING are for use with SystemParamString funcs + */ +#define PSP_SYSTEMPARAM_ID_STRING_NICKNAME 1 +#define PSP_SYSTEMPARAM_ID_INT_ADHOC_CHANNEL 2 +#define PSP_SYSTEMPARAM_ID_INT_WLAN_POWERSAVE 3 +#define PSP_SYSTEMPARAM_ID_INT_DATE_FORMAT 4 +#define PSP_SYSTEMPARAM_ID_INT_TIME_FORMAT 5 +//Timezone offset from UTC in minutes, (EST = -300 = -5 * 60) +#define PSP_SYSTEMPARAM_ID_INT_TIMEZONE 6 +#define PSP_SYSTEMPARAM_ID_INT_DAYLIGHTSAVINGS 7 +#define PSP_SYSTEMPARAM_ID_INT_LANGUAGE 8 +/** + * #9 seems to be Region or maybe X/O button swap. + * It doesn't exist on JAP v1.0 + * is 1 on NA v1.5s + * is 0 on JAP v1.5s + * is read-only + */ +#define PSP_SYSTEMPARAM_ID_INT_UNKNOWN 9 + +/** + * Return values for the SystemParam functions + */ +#define PSP_SYSTEMPARAM_RETVAL_OK 0 +#define PSP_SYSTEMPARAM_RETVAL_FAIL 0x80110103 + +/** + * Valid values for PSP_SYSTEMPARAM_ID_INT_ADHOC_CHANNEL + */ +#define PSP_SYSTEMPARAM_ADHOC_CHANNEL_AUTOMATIC 0 +#define PSP_SYSTEMPARAM_ADHOC_CHANNEL_1 1 +#define PSP_SYSTEMPARAM_ADHOC_CHANNEL_6 6 +#define PSP_SYSTEMPARAM_ADHOC_CHANNEL_11 11 + +/** + * Valid values for PSP_SYSTEMPARAM_ID_INT_WLAN_POWERSAVE + */ +#define PSP_SYSTEMPARAM_WLAN_POWERSAVE_OFF 0 +#define PSP_SYSTEMPARAM_WLAN_POWERSAVE_ON 1 + +/** + * Valid values for PSP_SYSTEMPARAM_ID_INT_DATE_FORMAT + */ +#define PSP_SYSTEMPARAM_DATE_FORMAT_YYYYMMDD 0 +#define PSP_SYSTEMPARAM_DATE_FORMAT_MMDDYYYY 1 +#define PSP_SYSTEMPARAM_DATE_FORMAT_DDMMYYYY 2 + +/** + * Valid values for PSP_SYSTEMPARAM_ID_INT_TIME_FORMAT + */ +#define PSP_SYSTEMPARAM_TIME_FORMAT_24HR 0 +#define PSP_SYSTEMPARAM_TIME_FORMAT_12HR 1 + +/** + * Valid values for PSP_SYSTEMPARAM_ID_INT_DAYLIGHTSAVINGS + */ +#define PSP_SYSTEMPARAM_DAYLIGHTSAVINGS_STD 0 +#define PSP_SYSTEMPARAM_DAYLIGHTSAVINGS_SAVING 1 + +/** + * Valid values for PSP_SYSTEMPARAM_ID_INT_LANGUAGE + */ +#define PSP_SYSTEMPARAM_LANGUAGE_JAPANESE 0 +#define PSP_SYSTEMPARAM_LANGUAGE_ENGLISH 1 +#define PSP_SYSTEMPARAM_LANGUAGE_FRENCH 2 +#define PSP_SYSTEMPARAM_LANGUAGE_SPANISH 3 +#define PSP_SYSTEMPARAM_LANGUAGE_GERMAN 4 +#define PSP_SYSTEMPARAM_LANGUAGE_ITALIAN 5 +#define PSP_SYSTEMPARAM_LANGUAGE_DUTCH 6 +#define PSP_SYSTEMPARAM_LANGUAGE_PORTUGUESE 7 +#define PSP_SYSTEMPARAM_LANGUAGE_RUSSIAN 8 +#define PSP_SYSTEMPARAM_LANGUAGE_KOREAN 9 +#define PSP_SYSTEMPARAM_LANGUAGE_CHINESE_TRADITIONAL 10 +#define PSP_SYSTEMPARAM_LANGUAGE_CHINESE_SIMPLIFIED 11 + +/** + * Set Integer System Parameter + * + * @param id - which parameter to set + * @param value - integer value to set + * @return 0 on success, PSP_SYSTEMPARAM_RETVAL_FAIL on failure + */ +int sceUtilitySetSystemParamInt(int id, int value); + +/** + * Set String System Parameter + * + * @param id - which parameter to set + * @param str - char * value to set + * @return 0 on success, PSP_SYSTEMPARAM_RETVAL_FAIL on failure + */ +int sceUtilitySetSystemParamString(int id, const char *str); + +/** + * Get Integer System Parameter + * + * @param id - which parameter to get + * @param value - pointer to integer value to place result in + * @return 0 on success, PSP_SYSTEMPARAM_RETVAL_FAIL on failure + */ +int sceUtilityGetSystemParamInt( int id, int *value ); + +/** + * Get String System Parameter + * + * @param id - which parameter to get + * @param str - char * buffer to place result in + * @param len - length of str buffer + * @return 0 on success, PSP_SYSTEMPARAM_RETVAL_FAIL on failure + */ +int sceUtilityGetSystemParamString(int id, char *str, int len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/utility/psputility_usbmodules.h b/src/utility/psputility_usbmodules.h new file mode 100755 index 00000000..c191697f --- /dev/null +++ b/src/utility/psputility_usbmodules.h @@ -0,0 +1,48 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * psputility_usbmodules.h - Load usb modules from user mode on 2.70 and higher + * + * Copyright (c) 2007 David Perry + * + */ +#ifndef __PSPUTILITY_USBMODULES_H__ +#define __PSPUTILITY_USBMODULES_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#define PSP_USB_MODULE_PSPCM 1 +#define PSP_USB_MODULE_ACC 2 +#define PSP_USB_MODULE_MIC 3 // Requires PSP_USB_MODULE_ACC loading first +#define PSP_USB_MODULE_CAM 4 // Requires PSP_USB_MODULE_ACC loading first +#define PSP_USB_MODULE_GPS 5 // Requires PSP_USB_MODULE_ACC loading first + +/** + * Load a usb module (PRX) from user mode. + * Available on firmware 2.70 and higher only. + * + * @param module - module number to load (PSP_USB_MODULE_xxx) + * @return 0 on success, < 0 on error +*/ +int sceUtilityLoadUsbModule(int module); + +/** + * Unload a usb module (PRX) from user mode. + * Available on firmware 2.70 and higher only. + * + * @param module - module number to be unloaded + * @return 0 on success, < 0 on error +*/ +int sceUtilityUnloadUsbModule(int module); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/utility/sceUtility.S b/src/utility/sceUtility.S new file mode 100644 index 00000000..39865a8f --- /dev/null +++ b/src/utility/sceUtility.S @@ -0,0 +1,175 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceUtility_0000 + IMPORT_START "sceUtility",0x40010000 +#endif +#ifdef F_sceUtility_0001 + IMPORT_FUNC "sceUtility",0xC492F751,sceUtilityGameSharingInitStart +#endif +#ifdef F_sceUtility_0002 + IMPORT_FUNC "sceUtility",0xEFC6F80F,sceUtilityGameSharingShutdownStart +#endif +#ifdef F_sceUtility_0003 + IMPORT_FUNC "sceUtility",0x7853182D,sceUtilityGameSharingUpdate +#endif +#ifdef F_sceUtility_0004 + IMPORT_FUNC "sceUtility",0x946963F3,sceUtilityGameSharingGetStatus +#endif +#ifdef F_sceUtility_0005 + IMPORT_FUNC "sceUtility",0x3AD50AE7,sceNetplayDialogInitStart +#endif +#ifdef F_sceUtility_0006 + IMPORT_FUNC "sceUtility",0xBC6B6296,sceNetplayDialogShutdownStart +#endif +#ifdef F_sceUtility_0007 + IMPORT_FUNC "sceUtility",0x417BED54,sceNetplayDialogUpdate +#endif +#ifdef F_sceUtility_0008 + IMPORT_FUNC "sceUtility",0xB6CEE597,sceNetplayDialogGetStatus +#endif +#ifdef F_sceUtility_0009 + IMPORT_FUNC "sceUtility",0x4DB1E739,sceUtilityNetconfInitStart +#endif +#ifdef F_sceUtility_0010 + IMPORT_FUNC "sceUtility",0xF88155F6,sceUtilityNetconfShutdownStart +#endif +#ifdef F_sceUtility_0011 + IMPORT_FUNC "sceUtility",0x91E70E35,sceUtilityNetconfUpdate +#endif +#ifdef F_sceUtility_0012 + IMPORT_FUNC "sceUtility",0x6332AA39,sceUtilityNetconfGetStatus +#endif +#ifdef F_sceUtility_0013 + IMPORT_FUNC "sceUtility",0x50C4CD57,sceUtilitySavedataInitStart +#endif +#ifdef F_sceUtility_0014 + IMPORT_FUNC "sceUtility",0x9790B33C,sceUtilitySavedataShutdownStart +#endif +#ifdef F_sceUtility_0015 + IMPORT_FUNC "sceUtility",0xD4B95FFB,sceUtilitySavedataUpdate +#endif +#ifdef F_sceUtility_0016 + IMPORT_FUNC "sceUtility",0x8874DBE0,sceUtilitySavedataGetStatus +#endif +#ifdef F_sceUtility_0017 + IMPORT_FUNC "sceUtility",0x2995D020,sceUtility_2995D020 +#endif +#ifdef F_sceUtility_0018 + IMPORT_FUNC "sceUtility",0xB62A4061,sceUtility_B62A4061 +#endif +#ifdef F_sceUtility_0019 + IMPORT_FUNC "sceUtility",0xED0FAD38,sceUtility_ED0FAD38 +#endif +#ifdef F_sceUtility_0020 + IMPORT_FUNC "sceUtility",0x88BC7406,sceUtility_88BC7406 +#endif +#ifdef F_sceUtility_0021 + IMPORT_FUNC "sceUtility",0x2AD8E239,sceUtilityMsgDialogInitStart +#endif +#ifdef F_sceUtility_0022 + IMPORT_FUNC "sceUtility",0x67AF3428,sceUtilityMsgDialogShutdownStart +#endif +#ifdef F_sceUtility_0023 + IMPORT_FUNC "sceUtility",0x95FC253B,sceUtilityMsgDialogUpdate +#endif +#ifdef F_sceUtility_0024 + IMPORT_FUNC "sceUtility",0x9A1C91D7,sceUtilityMsgDialogGetStatus +#endif +#ifdef F_sceUtility_0025 + IMPORT_FUNC "sceUtility",0xF6269B82,sceUtilityOskInitStart +#endif +#ifdef F_sceUtility_0026 + IMPORT_FUNC "sceUtility",0x3DFAEBA9,sceUtilityOskShutdownStart +#endif +#ifdef F_sceUtility_0027 + IMPORT_FUNC "sceUtility",0x4B85C861,sceUtilityOskUpdate +#endif +#ifdef F_sceUtility_0028 + IMPORT_FUNC "sceUtility",0xF3F76017,sceUtilityOskGetStatus +#endif +#ifdef F_sceUtility_0029 + IMPORT_FUNC "sceUtility",0x45C18506,sceUtilitySetSystemParamInt +#endif +#ifdef F_sceUtility_0030 + IMPORT_FUNC "sceUtility",0x41E30674,sceUtilitySetSystemParamString +#endif +#ifdef F_sceUtility_0031 + IMPORT_FUNC "sceUtility",0xA5DA2406,sceUtilityGetSystemParamInt +#endif +#ifdef F_sceUtility_0032 + IMPORT_FUNC "sceUtility",0x34B78343,sceUtilityGetSystemParamString +#endif +#ifdef F_sceUtility_0033 + IMPORT_FUNC "sceUtility",0x5EEE6548,sceUtilityCheckNetParam +#endif +#ifdef F_sceUtility_0034 + IMPORT_FUNC "sceUtility",0x434D4B3A,sceUtilityGetNetParam +#endif +#ifdef F_sceUtility_0035 + IMPORT_FUNC "sceUtility",0x1579a159,sceUtilityLoadNetModule +#endif +#ifdef F_sceUtility_0036 + IMPORT_FUNC "sceUtility",0x64d50c56,sceUtilityUnloadNetModule +#endif +#ifdef F_sceUtility_0037 + IMPORT_FUNC "sceUtility",0xC629AF26,sceUtilityLoadAvModule +#endif +#ifdef F_sceUtility_0038 + IMPORT_FUNC "sceUtility",0xF7D8D092,sceUtilityUnloadAvModule +#endif +#ifdef F_sceUtility_0039 + IMPORT_FUNC "sceUtility",0x0D5BC6D2,sceUtilityLoadUsbModule +#endif +#ifdef F_sceUtility_0040 + IMPORT_FUNC "sceUtility",0xF64910F0,sceUtilityUnloadUsbModule +#endif +#ifdef F_sceUtility_0041 + IMPORT_FUNC "sceUtility",0x4928BD96,sceUtilityMsgDialogAbort +#endif +#ifdef F_sceUtility_0042 + IMPORT_FUNC "sceUtility",0x05AFB9E4,sceUtilityHtmlViewerUpdate +#endif +#ifdef F_sceUtility_0043 + IMPORT_FUNC "sceUtility",0xBDA7D894,sceUtilityHtmlViewerGetStatus +#endif +#ifdef F_sceUtility_0044 + IMPORT_FUNC "sceUtility",0xCDC3AA41,sceUtilityHtmlViewerInitStart +#endif +#ifdef F_sceUtility_0045 + IMPORT_FUNC "sceUtility",0xF5CE1134,sceUtilityHtmlViewerShutdownStart +#endif +#ifdef F_sceUtility_0046 + IMPORT_FUNC "sceUtility",0x2A2B3DE0,sceUtilityLoadModule +#endif +#ifdef F_sceUtility_0047 + IMPORT_FUNC "sceUtility",0xE49BFE92,sceUtilityUnloadModule +#endif +#ifdef F_sceUtility_0048 + IMPORT_FUNC "sceUtility",0x0251B134,sceUtilityScreenshotInitStart +#endif +#ifdef F_sceUtility_0049 + IMPORT_FUNC "sceUtility",0xF9E0008C,sceUtilityScreenshotShutdownStart +#endif +#ifdef F_sceUtility_0050 + IMPORT_FUNC "sceUtility",0xAB083EA9,sceUtilityScreenshotUpdate +#endif +#ifdef F_sceUtility_0051 + IMPORT_FUNC "sceUtility",0xD81957B7,sceUtilityScreenshotGetStatus +#endif +#ifdef F_sceUtility_0052 + IMPORT_FUNC "sceUtility",0x86A03A27,sceUtilityScreenshotContStart +#endif +#ifdef F_sceUtility_0053 + IMPORT_FUNC "sceUtility",0x16D02AF0,sceUtilityNpSigninInitStart +#endif +#ifdef F_sceUtility_0054 + IMPORT_FUNC "sceUtility",0xE19C97D6,sceUtilityNpSigninShutdownStart +#endif +#ifdef F_sceUtility_0055 + IMPORT_FUNC "sceUtility",0xF3FBC572,sceUtilityNpSigninUpdate +#endif +#ifdef F_sceUtility_0056 + IMPORT_FUNC "sceUtility",0x86ABDB1B,sceUtilityNpSigninGetStatus +#endif diff --git a/src/utility/sceUtility_netparam_internal.S b/src/utility/sceUtility_netparam_internal.S new file mode 100644 index 00000000..54579526 --- /dev/null +++ b/src/utility/sceUtility_netparam_internal.S @@ -0,0 +1,19 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceUtility_netparam_internal_0000 + IMPORT_START "sceUtility_netparam_internal",0x40010000 +#endif +#ifdef F_sceUtility_netparam_internal_0001 + IMPORT_FUNC "sceUtility_netparam_internal",0x072DEBF2,sceUtilityCreateNetParam +#endif +#ifdef F_sceUtility_netparam_internal_0002 + IMPORT_FUNC "sceUtility_netparam_internal",0x9CE50172,sceUtilityDeleteNetParam +#endif +#ifdef F_sceUtility_netparam_internal_0003 + IMPORT_FUNC "sceUtility_netparam_internal",0xFB0C4840,sceUtilityCopyNetParam +#endif +#ifdef F_sceUtility_netparam_internal_0004 + IMPORT_FUNC "sceUtility_netparam_internal",0xFC4516F3,sceUtilitySetNetParam +#endif diff --git a/src/vfpu/Makefile.am b/src/vfpu/Makefile.am new file mode 100644 index 00000000..4c4cd80f --- /dev/null +++ b/src/vfpu/Makefile.am @@ -0,0 +1,20 @@ + +libdir = @PSPSDK_LIBDIR@ + +CC = @PSP_CC@ +CCAS = $(CC) +AR = @PSP_AR@ +RANLIB = @PSP_RANLIB@ + +INCLUDES = -I$(top_srcdir)/src/base -I$(top_srcdir)/src/debug -I$(top_srcdir)/src/user +CFLAGS = @PSPSDK_CFLAGS@ -std=gnu99 -Wall -Wmissing-prototypes +CCASFLAGS = $(CFLAGS) -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel + +VFPU_OBJS = + +libpspvfpuincludedir = @PSPSDK_INCLUDEDIR@ +libpspvfpuinclude_HEADERS = pspvfpu.h + +lib_LIBRARIES = libpspvfpu.a +libpspvfpu_a_SOURCES = pspvfpu.c +libpspvfpu_a_LIBADD = $(VFPU_OBJS) diff --git a/src/vfpu/pspvfpu.c b/src/vfpu/pspvfpu.c new file mode 100644 index 00000000..5fde7ce8 --- /dev/null +++ b/src/vfpu/pspvfpu.c @@ -0,0 +1,178 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspvfpu.h - Prototypes for the VFPU library + * + * Copyright (c) 2005 Jeremy Fitzhardinge + * + * $Id: pspvfpu.c 1796 2006-02-08 19:59:58Z jsgf $ + */ +#include +#include + +#include "pspthreadman.h" +#include "pspvfpu.h" + +#define NMAT 8 + +struct pspvfpu_context { + float fpregs[4*4*NMAT] __attribute__((aligned(VFPU_ALIGNMENT))); + + /* + States a matrix can be in: + owned valid + 0 X context has no knowledge of the matrix + 1 1 context is using matrix, and wants it preserved + 1 0 context is using matrix temporarily + */ + vfpumatrixset_t valid; /* which matrices are valid in this context */ + vfpumatrixset_t owned; /* which matrices are in the VFPU at the moment */ +}; + +/* XXX This should be per-thread info */ +static struct pspvfpu_context *users[NMAT]; + +static void save_matrix(struct pspvfpu_context *c, int mat) +{ +#define SV(N) \ + asm("sv.q c"#N"00, 0 + %0, wt\n" \ + "sv.q c"#N"10, 16 + %0, wt\n" \ + "sv.q c"#N"20, 32 + %0, wt\n" \ + "sv.q c"#N"30, 48 + %0, wt\n" \ + : "=m" (c->fpregs[N * 4*4]) \ + : : "memory") + + switch(mat) { + case 0: SV(0); break; + case 1: SV(1); break; + case 2: SV(2); break; + case 3: SV(3); break; + case 4: SV(4); break; + case 5: SV(5); break; + case 6: SV(6); break; + case 7: SV(7); break; + } +#undef SV +} + +static void load_matrix(const struct pspvfpu_context *c, int mat) +{ +#define LV(N) \ + asm("lv.q c"#N"00, 0 + %0\n" \ + "lv.q c"#N"10, 16 + %0\n" \ + "lv.q c"#N"20, 32 + %0\n" \ + "lv.q c"#N"30, 48 + %0\n" \ + : : "m" (c->fpregs[N * 4*4]) \ + : "memory") + switch(mat) { + case 0: LV(0); break; + case 1: LV(1); break; + case 2: LV(2); break; + case 3: LV(3); break; + case 4: LV(4); break; + case 5: LV(5); break; + case 6: LV(6); break; + case 7: LV(7); break; + } +#undef LV +} + +/* + Switch the VFPU's register state for the current context. This means: + + 1. save any other context's matrices in the set (keepset | tempset) + 2. load the current context's valid keepset (keepset & c->valid) + 3. mark the current context as owning (keepset | tempset), and having keepset valid + + Note, a NULL context is a valid special case. It means that the + caller doesn't care about long-term matrix use, but does want to + claim a temporary matrix. + */ +void pspvfpu_use_matrices(struct pspvfpu_context *c, vfpumatrixset_t keepset, vfpumatrixset_t tempset) +{ + vfpumatrixset_t saveset, loadset; + + /* If a matrix is both in the keepset and tempset, drop it + from tempset */ + tempset &= ~keepset; + + if (c != NULL) { + /* If the context already has a matrix owned, we + don't need to handle it */ + keepset &= ~c->owned; + tempset &= ~c->owned; + + saveset = keepset | tempset; /* save everything we use */ + loadset = keepset & c->valid; /* only reload valid matrices */ + + c->owned |= saveset; /* will be true by the time we're done */ + c->valid |= keepset; /* likewise */ + c->valid &= ~tempset; /* temporaries aren't valid */ + } else { + saveset = keepset | tempset; + loadset = 0; /* no context, nothing to reload */ + } + + int m = 0; + while(saveset) { + /* skip to the next member of the matrix set + (ctz -> count trailing zeros; the number of zeros in the LSB) */ + int skip = __builtin_ctz(saveset); + m += skip; + saveset >>= skip; + loadset >>= skip; + + /* we need to save everyone else's use of saveset + matrices */ + if (users[m] != NULL) { + struct pspvfpu_context *other = users[m]; + + if (other->valid & (1 << m)) + save_matrix(other, m); + other->owned &= ~(1 << m); + other->valid &= ~(1 << m); + } + + /* reload matrix values if necessary */ + if (loadset & 1) + load_matrix(c, m); + + /* we own all the matrices we're about to use */ + users[m] = c; + + saveset &= ~1; /* that one's done */ + } +} + +/* + Create a new context, and make sure the matrices in matrixset are + ready for use. + */ +struct pspvfpu_context *pspvfpu_initcontext(void) +{ + struct pspvfpu_context *c; + + /* Make sure the kernel preserves this thread's VFPU state */ + if (sceKernelChangeCurrentThreadAttr(0, PSP_THREAD_ATTR_VFPU) < 0) + return NULL; + + c = memalign(VFPU_ALIGNMENT, sizeof(*c)); + + if (c != NULL) { + c->owned = 0; + c->valid = 0; + } + + return c; +} + +void pspvfpu_deletecontext(struct pspvfpu_context *c) +{ + for(int i = 0; i < NMAT; i++) + if (users[i] == c) + users[i] = NULL; + + free(c); +} diff --git a/src/vfpu/pspvfpu.h b/src/vfpu/pspvfpu.h new file mode 100644 index 00000000..9792eeca --- /dev/null +++ b/src/vfpu/pspvfpu.h @@ -0,0 +1,76 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspvfpu.h - Prototypes for the VFPU library + * + * Copyright (c) 2005 Jeremy Fitzhardinge + * + * $Id: pspvfpu.h 1751 2006-01-26 01:42:38Z jsgf $ + */ +#ifndef __PSPVFPU_H__ +#define __PSPVFPU_H__ + + +#ifdef __cplusplus +extern "C" { +#endif + +struct pspvfpu_context; +typedef unsigned char vfpumatrixset_t; + +#define VMAT0 (1<<0) +#define VMAT1 (1<<1) +#define VMAT2 (1<<2) +#define VMAT3 (1<<3) +#define VMAT4 (1<<4) +#define VMAT5 (1<<5) +#define VMAT6 (1<<6) +#define VMAT7 (1<<7) + +#define VFPU_ALIGNMENT (sizeof(float) * 4) /* alignment required for VFPU matrix loads and stores */ + +/** + Prepare to use the VFPU. This set's the calling thread's VFPU + attribute, and returns a pointer to some VFPU state storage. + The initial value all all VFPU matrix registers is undefined. + + @return A VFPU context + */ +struct pspvfpu_context *pspvfpu_initcontext(void); + +/** + Delete a VFPU context. This frees the resources used by the VFPU + context. + + @param context The VFPU context to be deleted. + */ +void pspvfpu_deletecontext(struct pspvfpu_context *context); + +/** + Use a set of VFPU matrices. This restores the parts of the VFPU + state the caller wants restored (if necessary). If the caller was + the previous user of the the matrix set, then this call is + effectively a no-op. If a matrix has never been used by this + context before, then it will initially have an undefined value. + + @param context The VFPU context the caller wants to restore + from. It is valid to pass NULL as a context. This means the caller + wants to reserve a temporary matrix without affecting other VFPU + users, but doesn't want any long-term matrices itself. + + @param keepset The set of matrices the caller wants to use, and + keep the values persistently. + + @param tempset A set of matrices the callers wants to use + temporarily, but doesn't care about the values in the long-term. + */ +void pspvfpu_use_matrices(struct pspvfpu_context *context, + vfpumatrixset_t keepset, vfpumatrixset_t tempset); + +#ifdef __cplusplus +} +#endif + +#endif /* __PSPVFPU_H__ */ diff --git a/src/video/Makefile.am b/src/video/Makefile.am new file mode 100755 index 00000000..f10914e5 --- /dev/null +++ b/src/video/Makefile.am @@ -0,0 +1,27 @@ + +libdir = @PSPSDK_LIBDIR@ + +CC = @PSP_CC@ +CCAS = $(CC) +AR = @PSP_AR@ +RANLIB = @PSP_RANLIB@ + +INCLUDES = -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel +CFLAGS = @PSPSDK_CFLAGS@ +CCASFLAGS = $(CFLAGS) -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel + +VIDEOCODEC_OBJS = sceVideocodec_0000.o sceVideocodec_0001.o sceVideocodec_0002.o sceVideocodec_0003.o sceVideocodec_0004.o sceVideocodec_0005.o sceVideocodec_0006.o sceVideocodec_0007.o sceVideocodec_0008.o sceVideocodec_0009.o sceVideocodec_0010.o sceVideocodec_0011.o sceVideocodec_0012.o sceVideocodec_0013.o + + +libpspvideocodecincludedir = @PSPSDK_INCLUDEDIR@ +libpspvideocodecinclude_HEADERS = pspvideocodec.h + + +lib_LIBRARIES = libpspvideocodec.a + + +libpspvideocodec_a_SOURCES = sceVideocodec.S +libpspvideocodec_a_LIBADD = $(VIDEOCODEC_OBJS) + +$(VIDEOCODEC_OBJS): sceVideocodec.S + $(COMPILE) -DF_$* $< -c -o $@ diff --git a/src/video/pspvideocodec.h b/src/video/pspvideocodec.h new file mode 100755 index 00000000..50c51100 --- /dev/null +++ b/src/video/pspvideocodec.h @@ -0,0 +1,36 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspvideocodec.h - Prototypes for the sceVideocodec library. + * + * Copyright (c) 2007 cooleyes + * + * $Id: pspvideocodec.h 2418 2008-08-13 23:29:18Z Raphael $ + */ + +#ifndef __SCELIBVIDEOCODEC_H__ +#define __SCELIBVIDEOCODEC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +int sceVideocodecOpen(unsigned long *Buffer, int Type); +int sceVideocodecGetEDRAM(unsigned long *Buffer, int Type); +int sceVideocodecInit(unsigned long *Buffer, int Type); +int sceVideocodecDecode(unsigned long *Buffer, int Type); +int sceVideocodecReleaseEDRAM(unsigned long *Buffer); + +// sceVideocodecGetVersion +// sceVideocodecScanHeader +// sceVideocodecDelete +// sceVideocodecSetMemory +// sceVideocodecStop + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/src/video/sceVideocodec.S b/src/video/sceVideocodec.S new file mode 100755 index 00000000..86cd9f07 --- /dev/null +++ b/src/video/sceVideocodec.S @@ -0,0 +1,43 @@ + .set noreorder + +#include "pspimport.s" + +// Build List +// sceVideocodec_0000.o sceVideocodec_0001.o sceVideocodec_0002.o sceVideocodec_0003.o sceVideocodec_0004.o sceVideocodec_0005.o sceVideocodec_0006.o sceVideocodec_0007.o sceVideocodec_0008.o sceVideocodec_0009.o sceVideocodec_0010.o sceVideocodec_0011.o + +#ifdef F_sceVideocodec_0000 + IMPORT_START "sceVideocodec",0x40010011 +#endif +#ifdef F_sceVideocodec_0001 + IMPORT_FUNC "sceVideocodec",0x17099F0A,sceVideocodecInit +#endif +#ifdef F_sceVideocodec_0002 + IMPORT_FUNC "sceVideocodec",0x26927D19,sceVideocodecGetVersion +#endif +#ifdef F_sceVideocodec_0003 + IMPORT_FUNC "sceVideocodec",0x2D31F5B1,sceVideocodecGetEDRAM +#endif +#ifdef F_sceVideocodec_0004 + IMPORT_FUNC "sceVideocodec",0x2F385E7F,sceVideocodecScanHeader +#endif +#ifdef F_sceVideocodec_0005 + IMPORT_FUNC "sceVideocodec",0x307E6E1C,sceVideocodecDelete +#endif +#ifdef F_sceVideocodec_0006 + IMPORT_FUNC "sceVideocodec",0x4F160BF4,sceVideocodecReleaseEDRAM +#endif +#ifdef F_sceVideocodec_0007 + IMPORT_FUNC "sceVideocodec",0x627B7D42,sceVideocodec_627B7D42 +#endif +#ifdef F_sceVideocodec_0008 + IMPORT_FUNC "sceVideocodec",0x745A7B7A,sceVideocodecSetMemory +#endif +#ifdef F_sceVideocodec_0009 + IMPORT_FUNC "sceVideocodec",0xA2F0564E,sceVideocodecStop +#endif +#ifdef F_sceVideocodec_0010 + IMPORT_FUNC "sceVideocodec",0xC01EC829,sceVideocodecOpen +#endif +#ifdef F_sceVideocodec_0011 + IMPORT_FUNC "sceVideocodec",0xDBA273FA,sceVideocodecDecode +#endif diff --git a/src/vsh/Makefile.am b/src/vsh/Makefile.am new file mode 100644 index 00000000..6cf6d130 --- /dev/null +++ b/src/vsh/Makefile.am @@ -0,0 +1,35 @@ + +libdir = @PSPSDK_LIBDIR@ + +CC = @PSP_CC@ +CCAS = $(CC) +AR = @PSP_AR@ +RANLIB = @PSP_RANLIB@ + +INCLUDES = -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel +CFLAGS = @PSPSDK_CFLAGS@ +CCASFLAGS = $(CFLAGS) -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel + +CHNNLSV_OBJS = sceChnnlsv_0000.o sceChnnlsv_0001.o sceChnnlsv_0002.o sceChnnlsv_0003.o sceChnnlsv_0004.o sceChnnlsv_0005.o sceChnnlsv_0006.o +VSHBRIDGE_OBJS = sceVshBridge_0000.o sceVshBridge_0001.o sceVshBridge_0002.o sceVshBridge_0003.o sceVshBridge_0004.o sceVshBridge_0005.o sceVshBridge_0006.o sceVshBridge_0007.o sceVshBridge_0008.o sceVshBridge_0009.o sceVshBridge_0010.o sceVshBridge_0011.o sceVshBridge_0012.o sceVshBridge_0013.o sceVshBridge_0014.o sceVshBridge_0015.o sceVshBridge_0016.o sceVshBridge_0017.o sceVshBridge_0018.o sceVshBridge_0019.o sceVshBridge_0020.o sceVshBridge_0021.o sceVshBridge_0022.o sceVshBridge_0023.o sceVshBridge_0024.o sceVshBridge_0025.o sceVshBridge_0026.o sceVshBridge_0027.o sceVshBridge_0028.o sceVshBridge_0029.o sceVshBridge_0030.o sceVshBridge_0031.o sceVshBridge_0032.o sceVshBridge_0033.o sceVshBridge_0034.o sceVshBridge_0035.o sceVshBridge_0036.o sceVshBridge_0037.o sceVshBridge_0038.o sceVshBridge_0039.o sceVshBridge_0040.o sceVshBridge_0041.o sceVshBridge_0042.o sceVshBridge_0043.o sceVshBridge_0044.o sceVshBridge_0045.o sceVshBridge_0046.o sceVshBridge_0047.o sceVshBridge_0048.o sceVshBridge_0049.o sceVshBridge_0050.o sceVshBridge_0051.o sceVshBridge_0052.o sceVshBridge_0053.o sceVshBridge_0054.o sceVshBridge_0055.o sceVshBridge_0056.o sceVshBridge_0057.o sceVshBridge_0058.o sceVshBridge_0059.o sceVshBridge_0060.o sceVshBridge_0061.o sceVshBridge_0062.o +PAF_OBJS = scePaf_0000.o scePaf_0001.o scePaf_0002.o scePaf_0003.o scePaf_0004.o scePaf_0005.o scePaf_0006.o scePaf_0007.o scePaf_0008.o scePaf_0009.o scePaf_0010.o scePaf_0011.o scePaf_0012.o scePaf_0013.o scePaf_0014.o scePaf_0015.o scePaf_0016.o scePaf_0017.o scePaf_0018.o scePaf_0019.o scePaf_0020.o scePaf_0021.o scePaf_0022.o scePaf_0023.o scePaf_0024.o scePaf_0025.o scePaf_0026.o scePaf_0027.o scePaf_0028.o scePaf_0029.o scePaf_0030.o scePaf_0031.o scePaf_0032.o scePaf_0033.o scePaf_0034.o scePaf_0035.o scePaf_0036.o scePaf_0037.o scePaf_0038.o scePaf_0039.o scePaf_0040.o scePaf_0041.o scePaf_0042.o scePaf_0043.o scePaf_0044.o scePaf_0045.o scePaf_0046.o scePaf_0047.o scePaf_0048.o scePaf_0049.o scePaf_0050.o scePaf_0051.o scePaf_0052.o scePaf_0053.o scePaf_0054.o scePaf_0055.o scePaf_0056.o scePaf_0057.o scePaf_0058.o scePaf_0059.o scePaf_0060.o scePaf_0061.o scePaf_0062.o scePaf_0063.o scePaf_0064.o scePaf_0065.o scePaf_0066.o scePaf_0067.o scePaf_0068.o scePaf_0069.o scePaf_0070.o scePaf_0071.o scePaf_0072.o scePaf_0073.o scePaf_0074.o scePaf_0075.o scePaf_0076.o scePaf_0077.o scePaf_0078.o scePaf_0079.o scePaf_0080.o scePaf_0081.o scePaf_0082.o scePaf_0083.o scePaf_0084.o scePaf_0085.o scePaf_0086.o scePaf_0087.o scePaf_0088.o scePaf_0089.o scePaf_0090.o scePaf_0091.o scePaf_0092.o scePaf_0093.o scePaf_0094.o scePaf_0095.o scePaf_0096.o scePaf_0097.o scePaf_0098.o scePaf_0099.o scePaf_0100.o scePaf_0101.o scePaf_0102.o scePaf_0103.o scePaf_0104.o scePaf_0105.o scePaf_0106.o scePaf_0107.o scePaf_0108.o scePaf_0109.o scePaf_0110.o scePaf_0111.o scePaf_0112.o scePaf_0113.o scePaf_0114.o scePaf_0115.o scePaf_0116.o scePaf_0117.o scePaf_0118.o scePaf_0119.o scePaf_0120.o scePaf_0121.o scePaf_0122.o scePaf_0123.o scePaf_0124.o scePaf_0125.o scePaf_0126.o scePaf_0127.o scePaf_0128.o scePaf_0129.o scePaf_0130.o scePaf_0131.o scePaf_0132.o scePaf_0133.o scePaf_0134.o scePaf_0135.o scePaf_0136.o scePaf_0137.o scePaf_0138.o scePaf_0139.o scePaf_0140.o scePaf_0141.o scePaf_0142.o scePaf_0143.o scePaf_0144.o scePaf_0145.o scePaf_0146.o scePaf_0147.o scePaf_0148.o scePaf_0149.o scePaf_0150.o scePaf_0151.o scePaf_0152.o scePaf_0153.o scePaf_0154.o scePaf_0155.o scePaf_0156.o scePaf_0157.o scePaf_0158.o scePaf_0159.o scePaf_0160.o scePaf_0161.o scePaf_0162.o scePaf_0163.o scePaf_0164.o scePaf_0165.o scePaf_0166.o scePaf_0167.o scePaf_0168.o scePaf_0169.o scePaf_0170.o scePaf_0171.o scePaf_0172.o scePaf_0173.o scePaf_0174.o scePaf_0175.o scePaf_0176.o scePaf_0177.o scePaf_0178.o scePaf_0179.o scePaf_0180.o scePaf_0181.o scePaf_0182.o scePaf_0183.o scePaf_0184.o scePaf_0185.o scePaf_0186.o scePaf_0187.o scePaf_0188.o scePaf_0189.o scePaf_0190.o scePaf_0191.o scePaf_0192.o scePaf_0193.o scePaf_0194.o scePaf_0195.o scePaf_0196.o scePaf_0197.o scePaf_0198.o scePaf_0199.o scePaf_0200.o scePaf_0201.o scePaf_0202.o scePaf_0203.o scePaf_0204.o scePaf_0205.o scePaf_0206.o scePaf_0207.o scePaf_0208.o scePaf_0209.o scePaf_0210.o scePaf_0211.o scePaf_0212.o scePaf_0213.o scePaf_0214.o scePaf_0215.o scePaf_0216.o scePaf_0217.o scePaf_0218.o scePaf_0219.o scePaf_0220.o scePaf_0221.o scePaf_0222.o scePaf_0223.o scePaf_0224.o scePaf_0225.o scePaf_0226.o scePaf_0227.o scePaf_0228.o scePaf_0229.o scePaf_0230.o scePaf_0231.o scePaf_0232.o scePaf_0233.o scePaf_0234.o scePaf_0235.o scePaf_0236.o scePaf_0237.o scePaf_0238.o scePaf_0239.o scePaf_0240.o scePaf_0241.o scePaf_0242.o scePaf_0243.o scePaf_0244.o scePaf_0245.o scePaf_0246.o scePaf_0247.o scePaf_0248.o scePaf_0249.o scePaf_0250.o scePaf_0251.o scePaf_0252.o scePaf_0253.o scePaf_0254.o scePaf_0255.o scePaf_0256.o scePaf_0257.o scePaf_0258.o scePaf_0259.o scePaf_0260.o scePaf_0261.o scePaf_0262.o scePaf_0263.o scePaf_0264.o scePaf_0265.o scePaf_0266.o scePaf_0267.o scePaf_0268.o scePaf_0269.o scePaf_0270.o scePaf_0271.o scePaf_0272.o scePaf_0273.o scePaf_0274.o scePaf_0275.o scePaf_0276.o scePaf_0277.o scePaf_0278.o scePaf_0279.o scePaf_0280.o scePaf_0281.o scePaf_0282.o scePaf_0283.o scePaf_0284.o scePaf_0285.o scePaf_0286.o scePaf_0287.o scePaf_0288.o scePaf_0289.o scePaf_0290.o scePaf_0291.o scePaf_0292.o scePaf_0293.o scePaf_0294.o scePaf_0295.o scePaf_0296.o scePaf_0297.o scePaf_0298.o scePaf_0299.o scePaf_0300.o scePaf_0301.o scePaf_0302.o scePaf_0303.o scePaf_0304.o scePaf_0305.o scePaf_0306.o scePaf_0307.o scePaf_0308.o scePaf_0309.o scePaf_0310.o scePaf_0311.o scePaf_0312.o scePaf_0313.o scePaf_0314.o scePaf_0315.o scePaf_0316.o scePaf_0317.o scePaf_0318.o scePaf_0319.o scePaf_0320.o scePaf_0321.o scePaf_0322.o scePaf_0323.o scePaf_0324.o scePaf_0325.o scePaf_0326.o scePaf_0327.o scePaf_0328.o scePaf_0329.o scePaf_0330.o scePaf_0331.o scePaf_0332.o scePaf_0333.o scePaf_0334.o scePaf_0335.o scePaf_0336.o scePaf_0337.o scePaf_0338.o scePaf_0339.o scePaf_0340.o scePaf_0341.o scePaf_0342.o scePaf_0343.o scePaf_0344.o scePaf_0345.o scePaf_0346.o scePaf_0347.o scePaf_0348.o scePaf_0349.o scePaf_0350.o scePaf_0351.o scePaf_0352.o scePaf_0353.o scePaf_0354.o scePaf_0355.o scePaf_0356.o scePaf_0357.o scePaf_0358.o scePaf_0359.o scePaf_0360.o scePaf_0361.o scePaf_0362.o scePaf_0363.o scePaf_0364.o scePaf_0365.o scePaf_0366.o scePaf_0367.o scePaf_0368.o scePaf_0369.o scePaf_0370.o scePaf_0371.o scePaf_0372.o scePaf_0373.o scePaf_0374.o scePaf_0375.o scePaf_0376.o scePaf_0377.o scePaf_0378.o scePaf_0379.o scePaf_0380.o scePaf_0381.o scePaf_0382.o scePaf_0383.o scePaf_0384.o scePaf_0385.o scePaf_0386.o scePaf_0387.o scePaf_0388.o scePaf_0389.o scePaf_0390.o scePaf_0391.o scePaf_0392.o scePaf_0393.o scePaf_0394.o scePaf_0395.o scePaf_0396.o scePaf_0397.o scePaf_0398.o scePaf_0399.o scePaf_0400.o scePaf_0401.o scePaf_0402.o scePaf_0403.o scePaf_0404.o scePaf_0405.o scePaf_0406.o scePaf_0407.o scePaf_0408.o scePaf_0409.o scePaf_0410.o scePaf_0411.o scePaf_0412.o scePaf_0413.o scePaf_0414.o scePaf_0415.o scePaf_0416.o scePaf_0417.o scePaf_0418.o scePaf_0419.o scePaf_0420.o scePaf_0421.o scePaf_0422.o scePaf_0423.o scePaf_0424.o scePaf_0425.o scePaf_0426.o scePaf_0427.o scePaf_0428.o scePaf_0429.o scePaf_0430.o scePaf_0431.o scePaf_0432.o scePaf_0433.o scePaf_0434.o scePaf_0435.o scePaf_0436.o scePaf_0437.o scePaf_0438.o scePaf_0439.o scePaf_0440.o scePaf_0441.o scePaf_0442.o scePaf_0443.o scePaf_0444.o scePaf_0445.o scePaf_0446.o scePaf_0447.o scePaf_0448.o scePaf_0449.o scePaf_0450.o scePaf_0451.o scePaf_0452.o scePaf_0453.o scePaf_0454.o scePaf_0455.o scePaf_0456.o scePaf_0457.o scePaf_0458.o scePaf_0459.o scePaf_0460.o scePaf_0461.o scePaf_0462.o scePaf_0463.o scePaf_0464.o scePaf_0465.o scePaf_0466.o scePaf_0467.o scePaf_0468.o scePaf_0469.o scePaf_0470.o scePaf_0471.o scePaf_0472.o scePaf_0473.o scePaf_0474.o scePaf_0475.o scePaf_0476.o scePaf_0477.o scePaf_0478.o scePaf_0479.o scePaf_0480.o scePaf_0481.o scePaf_0482.o scePaf_0483.o scePaf_0484.o scePaf_0485.o scePaf_0486.o scePaf_0487.o scePaf_0488.o scePaf_0489.o scePaf_0490.o scePaf_0491.o scePaf_0492.o scePaf_0493.o scePaf_0494.o scePaf_0495.o scePaf_0496.o scePaf_0497.o scePaf_0498.o scePaf_0499.o scePaf_0500.o scePaf_0501.o scePaf_0502.o scePaf_0503.o scePaf_0504.o scePaf_0505.o scePaf_0506.o scePaf_0507.o scePaf_0508.o scePaf_0509.o scePaf_0510.o scePaf_0511.o scePaf_0512.o scePaf_0513.o scePaf_0514.o scePaf_0515.o scePaf_0516.o scePaf_0517.o scePaf_0518.o scePaf_0519.o scePaf_0520.o scePaf_0521.o scePaf_0522.o scePaf_0523.o scePaf_0524.o scePaf_0525.o scePaf_0526.o scePaf_0527.o scePaf_0528.o scePaf_0529.o scePaf_0530.o scePaf_0531.o scePaf_0532.o scePaf_0533.o scePaf_0534.o scePaf_0535.o scePaf_0536.o scePaf_0537.o scePaf_0538.o scePaf_0539.o scePaf_0540.o scePaf_0541.o scePaf_0542.o scePaf_0543.o scePaf_0544.o scePaf_0545.o scePaf_0546.o scePaf_0547.o scePaf_0548.o scePaf_0549.o scePaf_0550.o scePaf_0551.o scePaf_0552.o scePaf_0553.o scePaf_0554.o scePaf_0555.o scePaf_0556.o scePaf_0557.o scePaf_0558.o scePaf_0559.o scePaf_0560.o scePaf_0561.o scePaf_0562.o scePaf_0563.o scePaf_0564.o scePaf_0565.o scePaf_0566.o scePaf_0567.o scePaf_0568.o scePaf_0569.o scePaf_0570.o scePaf_0571.o scePaf_0572.o scePaf_0573.o scePaf_0574.o scePaf_0575.o scePaf_0576.o scePaf_0577.o scePaf_0578.o scePaf_0579.o scePaf_0580.o scePaf_0581.o scePaf_0582.o scePaf_0583.o scePaf_0584.o scePaf_0585.o scePaf_0586.o scePaf_0587.o scePaf_0588.o scePaf_0589.o scePaf_0590.o scePaf_0591.o scePaf_0592.o scePaf_0593.o scePaf_0594.o scePaf_0595.o scePaf_0596.o scePaf_0597.o scePaf_0598.o scePaf_0599.o scePaf_0600.o scePaf_0601.o scePaf_0602.o scePaf_0603.o scePaf_0604.o scePaf_0605.o scePaf_0606.o scePaf_0607.o scePaf_0608.o scePaf_0609.o scePaf_0610.o scePaf_0611.o scePaf_0612.o scePaf_0613.o scePaf_0614.o scePaf_0615.o scePaf_0616.o scePaf_0617.o scePaf_0618.o scePaf_0619.o scePaf_0620.o scePaf_0621.o scePaf_0622.o scePaf_0623.o scePaf_0624.o scePaf_0625.o scePaf_0626.o scePaf_0627.o scePaf_0628.o scePaf_0629.o scePaf_0630.o scePaf_0631.o scePaf_0632.o scePaf_0633.o scePaf_0634.o scePaf_0635.o scePaf_0636.o scePaf_0637.o scePaf_0638.o scePaf_0639.o scePaf_0640.o scePaf_0641.o scePaf_0642.o scePaf_0643.o scePaf_0644.o scePaf_0645.o scePaf_0646.o scePaf_0647.o scePaf_0648.o scePaf_0649.o scePaf_0650.o scePaf_0651.o scePaf_0652.o scePaf_0653.o scePaf_0654.o scePaf_0655.o scePaf_0656.o scePaf_0657.o scePaf_0658.o scePaf_0659.o scePaf_0660.o scePaf_0661.o scePaf_0662.o scePaf_0663.o scePaf_0664.o scePaf_0665.o scePaf_0666.o scePaf_0667.o scePaf_0668.o scePaf_0669.o scePaf_0670.o scePaf_0671.o scePaf_0672.o scePaf_0673.o scePaf_0674.o scePaf_0675.o scePaf_0676.o scePaf_0677.o + +libpspchnnlsvincludedir = @PSPSDK_INCLUDEDIR@ +libpspchnnlsvinclude_HEADERS = pspchnnlsv.h + +lib_LIBRARIES = libpspchnnlsv.a libpspvshbridge.a libpsppaf.a +libpspchnnlsv_a_SOURCES = sceChnnlsv.S +libpspchnnlsv_a_LIBADD = $(CHNNLSV_OBJS) +libpspvshbridge_a_SOURCES = sceVshBridge.S +libpspvshbridge_a_LIBADD = $(VSHBRIDGE_OBJS) +libpsppaf_a_SOURCES = scePaf.S +libpsppaf_a_LIBADD = $(PAF_OBJS) + +$(CHNNLSV_OBJS): sceChnnlsv.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(VSHBRIDGE_OBJS): sceVshBridge.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(PAF_OBJS): scePaf.S + $(COMPILE) -DF_$* $< -c -o $@ diff --git a/src/vsh/pspchnnlsv.h b/src/vsh/pspchnnlsv.h new file mode 100644 index 00000000..28aab1ad --- /dev/null +++ b/src/vsh/pspchnnlsv.h @@ -0,0 +1,114 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspchnnlsv.h - Include for the pspChnnlsv library. + * + * Copyright (c) 2005 Jim Paris + * Copyright (c) 2005 psp123 + * + * $Id: pspchnnlsv.h 2433 2008-10-15 10:00:27Z iwn $ + */ +#ifndef __PSPCHNNLSV_H__ +#define __PSPCHNNLSV_H__ + +/* The descriptions are mostly speculation. */ + +/** @defgroup Chnnlsv Chnnlsv Library + * Library imports for the vsh chnnlsv library. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** @addtogroup Chnnlsv Chnnlsv Library */ +/*@{*/ + +typedef struct _pspChnnlsvContext1 { + /** Cipher mode */ + int mode; + + /** Context data */ + char buffer1[0x10]; + char buffer2[0x10]; + int unknown; +} pspChnnlsvContext1; + +typedef struct _pspChnnlsvContext2 { + /** Context data */ + char unknown[0x100]; +} pspChnnlsvContext2; + +/** + * Initialize context + * + * @param ctx - Context + * @param mode - Cipher mode + * @return < 0 on error + */ +int sceChnnlsv_E7833020(pspChnnlsvContext1 *ctx, int mode); + +/** + * Process data + * + * @param ctx - Context + * @param data - Data (aligned to 0x10) + * @param len - Length (aligned to 0x10) + * @return < 0 on error + */ +int sceChnnlsv_F21A1FCA(pspChnnlsvContext1 *ctx, unsigned char *data, int len); + +/** + * Finalize hash + * + * @param ctx - Context + * @param hash - Hash output (aligned to 0x10, 0x10 bytes long) + * @param cryptkey - Crypt key or NULL. + * @return < 0 on error + */ +int sceChnnlsv_C4C494F8(pspChnnlsvContext1 *ctx, + unsigned char *hash, unsigned char *cryptkey); + +/** + * Prepare a key, and set up integrity check + * + * @param ctx - Context + * @param mode1 - Cipher mode + * @param mode2 - Encrypt mode (1 = encrypting, 2 = decrypting) + * @param hashkey - Key out + * @param cipherkey - Key in + * @return < 0 on error + */ +int sceChnnlsv_ABFDFC8B(pspChnnlsvContext2 *ctx, int mode1, int mode2, + unsigned char *hashkey, unsigned char *cipherkey); + +/** + * Process data for integrity check + * + * @param ctx - Context + * @param data - Data (aligned to 0x10) + * @param len - Length (aligned to 0x10) + * @return < 0 on error + */ +int sceChnnlsv_850A7FA1(pspChnnlsvContext2 *ctx, unsigned char *data, int len); + +/** + * Check integrity + * + * @param ctx - Context + * @return < 0 on error + */ +int sceChnnlsv_21BE78B4(pspChnnlsvContext2 *ctx); + +/*@}*/ + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/src/vsh/sceChnnlsv.S b/src/vsh/sceChnnlsv.S new file mode 100644 index 00000000..0826e581 --- /dev/null +++ b/src/vsh/sceChnnlsv.S @@ -0,0 +1,25 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceChnnlsv_0000 + IMPORT_START "sceChnnlsv",0x40010000 +#endif +#ifdef F_sceChnnlsv_0001 + IMPORT_FUNC "sceChnnlsv",0xE7833020,sceChnnlsv_E7833020 +#endif +#ifdef F_sceChnnlsv_0002 + IMPORT_FUNC "sceChnnlsv",0xF21A1FCA,sceChnnlsv_F21A1FCA +#endif +#ifdef F_sceChnnlsv_0003 + IMPORT_FUNC "sceChnnlsv",0xC4C494F8,sceChnnlsv_C4C494F8 +#endif +#ifdef F_sceChnnlsv_0004 + IMPORT_FUNC "sceChnnlsv",0xABFDFC8B,sceChnnlsv_ABFDFC8B +#endif +#ifdef F_sceChnnlsv_0005 + IMPORT_FUNC "sceChnnlsv",0x850A7FA1,sceChnnlsv_850A7FA1 +#endif +#ifdef F_sceChnnlsv_0006 + IMPORT_FUNC "sceChnnlsv",0x21BE78B4,sceChnnlsv_21BE78B4 +#endif diff --git a/src/vsh/scePaf.S b/src/vsh/scePaf.S new file mode 100644 index 00000000..19557943 --- /dev/null +++ b/src/vsh/scePaf.S @@ -0,0 +1,2038 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_scePaf_0000 + IMPORT_START "scePaf",0x00010000 +#endif +#ifdef F_scePaf_0001 + IMPORT_FUNC "scePaf",0xC9831AFF,scePaf_C9831AFF +#endif +#ifdef F_scePaf_0002 + IMPORT_FUNC "scePaf",0xBFE9E90B,scePaf_BFE9E90B +#endif +#ifdef F_scePaf_0003 + IMPORT_FUNC "scePaf",0x5FAC9869,scePaf_5FAC9869 +#endif +#ifdef F_scePaf_0004 + IMPORT_FUNC "scePaf",0xFCB4E053,scePaf_FCB4E053 +#endif +#ifdef F_scePaf_0005 + IMPORT_FUNC "scePaf",0x26DE971C,scePaf_26DE971C +#endif +#ifdef F_scePaf_0006 + IMPORT_FUNC "scePaf",0x613E9AA2,scePaf_613E9AA2 +#endif +#ifdef F_scePaf_0007 + IMPORT_FUNC "scePaf",0x40C95283,scePaf_40C95283 +#endif +#ifdef F_scePaf_0008 + IMPORT_FUNC "scePaf",0xB61E88F2,scePaf_B61E88F2 +#endif +#ifdef F_scePaf_0009 + IMPORT_FUNC "scePaf",0x545FE2DA,scePaf_545FE2DA +#endif +#ifdef F_scePaf_0010 + IMPORT_FUNC "scePaf",0x7EC15225,scePaf_7EC15225 +#endif +#ifdef F_scePaf_0011 + IMPORT_FUNC "scePaf",0x60DECA7E,scePaf_60DECA7E +#endif +#ifdef F_scePaf_0012 + IMPORT_FUNC "scePaf",0xFD4C9F47,scePaf_FD4C9F47 +#endif +#ifdef F_scePaf_0013 + IMPORT_FUNC "scePaf",0xF95EA3F1,scePaf_F95EA3F1 +#endif +#ifdef F_scePaf_0014 + IMPORT_FUNC "scePaf",0x6829D7AF,scePaf_6829D7AF +#endif +#ifdef F_scePaf_0015 + IMPORT_FUNC "scePaf",0xCA79D58B,scePaf_CA79D58B +#endif +#ifdef F_scePaf_0016 + IMPORT_FUNC "scePaf",0x66FE90D7,scePaf_66FE90D7 +#endif +#ifdef F_scePaf_0017 + IMPORT_FUNC "scePaf",0x980228BA,scePaf_980228BA +#endif +#ifdef F_scePaf_0018 + IMPORT_FUNC "scePaf",0x296897BC,scePaf_296897BC +#endif +#ifdef F_scePaf_0019 + IMPORT_FUNC "scePaf",0xDEDF238F,scePaf_DEDF238F +#endif +#ifdef F_scePaf_0020 + IMPORT_FUNC "scePaf",0x7BED034E,scePaf_7BED034E +#endif +#ifdef F_scePaf_0021 + IMPORT_FUNC "scePaf",0xB3D58D25,scePaf_B3D58D25 +#endif +#ifdef F_scePaf_0022 + IMPORT_FUNC "scePaf",0x44AAF96C,scePaf_44AAF96C +#endif +#ifdef F_scePaf_0023 + IMPORT_FUNC "scePaf",0x49A81B18,scePaf_49A81B18 +#endif +#ifdef F_scePaf_0024 + IMPORT_FUNC "scePaf",0xFF2F98C6,scePaf_FF2F98C6 +#endif +#ifdef F_scePaf_0025 + IMPORT_FUNC "scePaf",0x77D981F5,scePaf_77D981F5 +#endif +#ifdef F_scePaf_0026 + IMPORT_FUNC "scePaf",0x45D851D1,scePaf_45D851D1 +#endif +#ifdef F_scePaf_0027 + IMPORT_FUNC "scePaf",0x71712601,scePaf_71712601 +#endif +#ifdef F_scePaf_0028 + IMPORT_FUNC "scePaf",0x71460F7C,scePaf_71460F7C +#endif +#ifdef F_scePaf_0029 + IMPORT_FUNC "scePaf",0xABBBB335,scePaf_ABBBB335 +#endif +#ifdef F_scePaf_0030 + IMPORT_FUNC "scePaf",0x07A5F495,scePaf_07A5F495 +#endif +#ifdef F_scePaf_0031 + IMPORT_FUNC "scePaf",0xF1552447,scePaf_F1552447 +#endif +#ifdef F_scePaf_0032 + IMPORT_FUNC "scePaf",0x83944053,scePaf_83944053 +#endif +#ifdef F_scePaf_0033 + IMPORT_FUNC "scePaf",0x2FDC80B3,scePaf_2FDC80B3 +#endif +#ifdef F_scePaf_0034 + IMPORT_FUNC "scePaf",0x993E9FDC,scePaf_993E9FDC +#endif +#ifdef F_scePaf_0035 + IMPORT_FUNC "scePaf",0x3188E7DB,scePaf_3188E7DB +#endif +#ifdef F_scePaf_0036 + IMPORT_FUNC "scePaf",0xDC38941B,scePaf_DC38941B +#endif +#ifdef F_scePaf_0037 + IMPORT_FUNC "scePaf",0xF0B4CAE7,scePaf_F0B4CAE7 +#endif +#ifdef F_scePaf_0038 + IMPORT_FUNC "scePaf",0x6C234A6A,scePaf_6C234A6A +#endif +#ifdef F_scePaf_0039 + IMPORT_FUNC "scePaf",0x37A98AE9,scePaf_37A98AE9 +#endif +#ifdef F_scePaf_0040 + IMPORT_FUNC "scePaf",0x3DD2A27B,scePaf_3DD2A27B +#endif +#ifdef F_scePaf_0041 + IMPORT_FUNC "scePaf",0x9870A25B,scePaf_9870A25B +#endif +#ifdef F_scePaf_0042 + IMPORT_FUNC "scePaf",0x503BA324,scePaf_503BA324 +#endif +#ifdef F_scePaf_0043 + IMPORT_FUNC "scePaf",0x2FA84441,scePaf_2FA84441 +#endif +#ifdef F_scePaf_0044 + IMPORT_FUNC "scePaf",0x84BD418F,scePaf_84BD418F +#endif +#ifdef F_scePaf_0045 + IMPORT_FUNC "scePaf",0x902515FB,scePaf_902515FB +#endif +#ifdef F_scePaf_0046 + IMPORT_FUNC "scePaf",0x3586BE05,scePaf_3586BE05 +#endif +#ifdef F_scePaf_0047 + IMPORT_FUNC "scePaf",0x2FA0EDDC,scePaf_2FA0EDDC +#endif +#ifdef F_scePaf_0048 + IMPORT_FUNC "scePaf",0x3FBD9639,scePaf_3FBD9639 +#endif +#ifdef F_scePaf_0049 + IMPORT_FUNC "scePaf",0x6BA9C299,scePaf_6BA9C299 +#endif +#ifdef F_scePaf_0050 + IMPORT_FUNC "scePaf",0xF1B52E86,scePaf_F1B52E86 +#endif +#ifdef F_scePaf_0051 + IMPORT_FUNC "scePaf",0x10B901E7,scePaf_10B901E7 +#endif +#ifdef F_scePaf_0052 + IMPORT_FUNC "scePaf",0x4370175A,scePaf_4370175A +#endif +#ifdef F_scePaf_0053 + IMPORT_FUNC "scePaf",0x809A4F83,scePaf_809A4F83 +#endif +#ifdef F_scePaf_0054 + IMPORT_FUNC "scePaf",0xA82E3C19,scePaf_A82E3C19 +#endif +#ifdef F_scePaf_0055 + IMPORT_FUNC "scePaf",0xED2B47FA,scePaf_ED2B47FA +#endif +#ifdef F_scePaf_0056 + IMPORT_FUNC "scePaf",0x26168DD3,scePaf_26168DD3 +#endif +#ifdef F_scePaf_0057 + IMPORT_FUNC "scePaf",0x626D68A1,scePaf_626D68A1 +#endif +#ifdef F_scePaf_0058 + IMPORT_FUNC "scePaf",0xFBA47E77,scePaf_FBA47E77 +#endif +#ifdef F_scePaf_0059 + IMPORT_FUNC "scePaf",0x44A0BCE4,scePaf_44A0BCE4 +#endif +#ifdef F_scePaf_0060 + IMPORT_FUNC "scePaf",0x4B1A374C,scePaf_4B1A374C +#endif +#ifdef F_scePaf_0061 + IMPORT_FUNC "scePaf",0x1D5D9A68,scePaf_1D5D9A68 +#endif +#ifdef F_scePaf_0062 + IMPORT_FUNC "scePaf",0x51AAAAF4,scePaf_51AAAAF4 +#endif +#ifdef F_scePaf_0063 + IMPORT_FUNC "scePaf",0x54C0DD23,scePaf_54C0DD23 +#endif +#ifdef F_scePaf_0064 + IMPORT_FUNC "scePaf",0x9F10613F,scePaf_9F10613F +#endif +#ifdef F_scePaf_0065 + IMPORT_FUNC "scePaf",0x8F12B63A,scePaf_8F12B63A +#endif +#ifdef F_scePaf_0066 + IMPORT_FUNC "scePaf",0x9D0192FD,scePaf_9D0192FD +#endif +#ifdef F_scePaf_0067 + IMPORT_FUNC "scePaf",0xFEAFC77A,scePaf_FEAFC77A +#endif +#ifdef F_scePaf_0068 + IMPORT_FUNC "scePaf",0x99A5CD38,scePaf_99A5CD38 +#endif +#ifdef F_scePaf_0069 + IMPORT_FUNC "scePaf",0xCE699963,scePaf_CE699963 +#endif +#ifdef F_scePaf_0070 + IMPORT_FUNC "scePaf",0xCB2198AB,scePaf_CB2198AB +#endif +#ifdef F_scePaf_0071 + IMPORT_FUNC "scePaf",0x11EF5210,scePaf_11EF5210 +#endif +#ifdef F_scePaf_0072 + IMPORT_FUNC "scePaf",0xB7E6052B,scePaf_B7E6052B +#endif +#ifdef F_scePaf_0073 + IMPORT_FUNC "scePaf",0xF13EBB78,scePaf_F13EBB78 +#endif +#ifdef F_scePaf_0074 + IMPORT_FUNC "scePaf",0x4E67BB08,scePaf_4E67BB08 +#endif +#ifdef F_scePaf_0075 + IMPORT_FUNC "scePaf",0xB3D2C3BB,scePaf_B3D2C3BB +#endif +#ifdef F_scePaf_0076 + IMPORT_FUNC "scePaf",0x962FA087,scePaf_962FA087 +#endif +#ifdef F_scePaf_0077 + IMPORT_FUNC "scePaf",0xD4C6CC7A,scePaf_D4C6CC7A +#endif +#ifdef F_scePaf_0078 + IMPORT_FUNC "scePaf",0x927854C5,scePaf_927854C5 +#endif +#ifdef F_scePaf_0079 + IMPORT_FUNC "scePaf",0xD02C0D2E,scePaf_D02C0D2E +#endif +#ifdef F_scePaf_0080 + IMPORT_FUNC "scePaf",0x2FF0A287,scePaf_2FF0A287 +#endif +#ifdef F_scePaf_0081 + IMPORT_FUNC "scePaf",0xF47CA1C2,scePaf_F47CA1C2 +#endif +#ifdef F_scePaf_0082 + IMPORT_FUNC "scePaf",0xEAA5AFF6,scePaf_EAA5AFF6 +#endif +#ifdef F_scePaf_0083 + IMPORT_FUNC "scePaf",0x58BFC2AC,scePaf_58BFC2AC +#endif +#ifdef F_scePaf_0084 + IMPORT_FUNC "scePaf",0x72514A05,scePaf_72514A05 +#endif +#ifdef F_scePaf_0085 + IMPORT_FUNC "scePaf",0xA69BABE3,scePaf_A69BABE3 +#endif +#ifdef F_scePaf_0086 + IMPORT_FUNC "scePaf",0x9430557B,scePaf_9430557B +#endif +#ifdef F_scePaf_0087 + IMPORT_FUNC "scePaf",0x607713A6,scePaf_607713A6 +#endif +#ifdef F_scePaf_0088 + IMPORT_FUNC "scePaf",0x5EFC5387,scePaf_5EFC5387 +#endif +#ifdef F_scePaf_0089 + IMPORT_FUNC "scePaf",0x79C3CBF7,scePaf_79C3CBF7 +#endif +#ifdef F_scePaf_0090 + IMPORT_FUNC "scePaf",0x3A4934E3,scePaf_3A4934E3 +#endif +#ifdef F_scePaf_0091 + IMPORT_FUNC "scePaf",0x4FF65BDC,scePaf_4FF65BDC +#endif +#ifdef F_scePaf_0092 + IMPORT_FUNC "scePaf",0x26DF747F,scePaf_26DF747F +#endif +#ifdef F_scePaf_0093 + IMPORT_FUNC "scePaf",0x41BCFB59,scePaf_41BCFB59 +#endif +#ifdef F_scePaf_0094 + IMPORT_FUNC "scePaf",0xFA05BF7B,scePaf_FA05BF7B +#endif +#ifdef F_scePaf_0095 + IMPORT_FUNC "scePaf",0xAAA8D3DA,scePaf_AAA8D3DA +#endif +#ifdef F_scePaf_0096 + IMPORT_FUNC "scePaf",0xA18DB948,scePaf_A18DB948 +#endif +#ifdef F_scePaf_0097 + IMPORT_FUNC "scePaf",0x2313DDCA,scePaf_2313DDCA +#endif +#ifdef F_scePaf_0098 + IMPORT_FUNC "scePaf",0x4FC2470C,scePaf_4FC2470C +#endif +#ifdef F_scePaf_0099 + IMPORT_FUNC "scePaf",0xB77039E4,scePaf_B77039E4 +#endif +#ifdef F_scePaf_0100 + IMPORT_FUNC "scePaf",0x0C6EEA21,scePaf_0C6EEA21 +#endif +#ifdef F_scePaf_0101 + IMPORT_FUNC "scePaf",0xCB7B666E,scePaf_CB7B666E +#endif +#ifdef F_scePaf_0102 + IMPORT_FUNC "scePaf",0x7B6F0E32,scePaf_7B6F0E32 +#endif +#ifdef F_scePaf_0103 + IMPORT_FUNC "scePaf",0x256218C2,scePaf_256218C2 +#endif +#ifdef F_scePaf_0104 + IMPORT_FUNC "scePaf",0x96C46364,scePaf_96C46364 +#endif +#ifdef F_scePaf_0105 + IMPORT_FUNC "scePaf",0x7C31F453,scePaf_7C31F453 +#endif +#ifdef F_scePaf_0106 + IMPORT_FUNC "scePaf",0x503FA456,scePaf_503FA456 +#endif +#ifdef F_scePaf_0107 + IMPORT_FUNC "scePaf",0xD5F5E68F,scePaf_D5F5E68F +#endif +#ifdef F_scePaf_0108 + IMPORT_FUNC "scePaf",0xCAE6374A,scePaf_CAE6374A +#endif +#ifdef F_scePaf_0109 + IMPORT_FUNC "scePaf",0x84A71447,scePaf_84A71447 +#endif +#ifdef F_scePaf_0110 + IMPORT_FUNC "scePaf",0xD2463C79,scePaf_D2463C79 +#endif +#ifdef F_scePaf_0111 + IMPORT_FUNC "scePaf",0xED3E4EB1,scePaf_ED3E4EB1 +#endif +#ifdef F_scePaf_0112 + IMPORT_FUNC "scePaf",0x8DB4B066,scePaf_8DB4B066 +#endif +#ifdef F_scePaf_0113 + IMPORT_FUNC "scePaf",0xB104EC1B,scePaf_B104EC1B +#endif +#ifdef F_scePaf_0114 + IMPORT_FUNC "scePaf",0xB3659499,scePaf_B3659499 +#endif +#ifdef F_scePaf_0115 + IMPORT_FUNC "scePaf",0x6E94BA7B,scePaf_6E94BA7B +#endif +#ifdef F_scePaf_0116 + IMPORT_FUNC "scePaf",0xFF74C932,scePaf_FF74C932 +#endif +#ifdef F_scePaf_0117 + IMPORT_FUNC "scePaf",0xF6F3E99E,scePaf_F6F3E99E +#endif +#ifdef F_scePaf_0118 + IMPORT_FUNC "scePaf",0xA72594EF,scePaf_A72594EF +#endif +#ifdef F_scePaf_0119 + IMPORT_FUNC "scePaf",0x5075C799,scePaf_5075C799 +#endif +#ifdef F_scePaf_0120 + IMPORT_FUNC "scePaf",0xA76B9604,scePaf_A76B9604 +#endif +#ifdef F_scePaf_0121 + IMPORT_FUNC "scePaf",0xE1C76B22,scePaf_E1C76B22 +#endif +#ifdef F_scePaf_0122 + IMPORT_FUNC "scePaf",0x44EB8C62,scePaf_44EB8C62 +#endif +#ifdef F_scePaf_0123 + IMPORT_FUNC "scePaf",0xC2C25056,scePaf_C2C25056 +#endif +#ifdef F_scePaf_0124 + IMPORT_FUNC "scePaf",0xAEEF2A7C,scePaf_AEEF2A7C +#endif +#ifdef F_scePaf_0125 + IMPORT_FUNC "scePaf",0x55CC4749,scePaf_55CC4749 +#endif +#ifdef F_scePaf_0126 + IMPORT_FUNC "scePaf",0x37DD37B8,scePaf_37DD37B8 +#endif +#ifdef F_scePaf_0127 + IMPORT_FUNC "scePaf",0x16033F84,scePaf_16033F84 +#endif +#ifdef F_scePaf_0128 + IMPORT_FUNC "scePaf",0xA0A25707,scePaf_A0A25707 +#endif +#ifdef F_scePaf_0129 + IMPORT_FUNC "scePaf",0xF6AB6655,scePaf_F6AB6655 +#endif +#ifdef F_scePaf_0130 + IMPORT_FUNC "scePaf",0xC6CF9352,scePaf_C6CF9352 +#endif +#ifdef F_scePaf_0131 + IMPORT_FUNC "scePaf",0x0A189A1A,scePaf_0A189A1A +#endif +#ifdef F_scePaf_0132 + IMPORT_FUNC "scePaf",0xCB7CCB28,scePaf_CB7CCB28 +#endif +#ifdef F_scePaf_0133 + IMPORT_FUNC "scePaf",0x7B099943,scePaf_7B099943 +#endif +#ifdef F_scePaf_0134 + IMPORT_FUNC "scePaf",0xE9BF6BEB,scePaf_E9BF6BEB +#endif +#ifdef F_scePaf_0135 + IMPORT_FUNC "scePaf",0xCEAC29F3,scePaf_CEAC29F3 +#endif +#ifdef F_scePaf_0136 + IMPORT_FUNC "scePaf",0x275BCDC6,scePaf_275BCDC6 +#endif +#ifdef F_scePaf_0137 + IMPORT_FUNC "scePaf",0x65C19AC0,scePaf_65C19AC0 +#endif +#ifdef F_scePaf_0138 + IMPORT_FUNC "scePaf",0x8BA04801,scePaf_8BA04801 +#endif +#ifdef F_scePaf_0139 + IMPORT_FUNC "scePaf",0x93A60B78,scePaf_93A60B78 +#endif +#ifdef F_scePaf_0140 + IMPORT_FUNC "scePaf",0xAEE1CBAD,scePaf_AEE1CBAD +#endif +#ifdef F_scePaf_0141 + IMPORT_FUNC "scePaf",0x19A779E2,scePaf_19A779E2 +#endif +#ifdef F_scePaf_0142 + IMPORT_FUNC "scePaf",0xCDC81771,scePaf_CDC81771 +#endif +#ifdef F_scePaf_0143 + IMPORT_FUNC "scePaf",0xC1FAF826,scePaf_C1FAF826 +#endif +#ifdef F_scePaf_0144 + IMPORT_FUNC "scePaf",0x9C9B6732,scePaf_9C9B6732 +#endif +#ifdef F_scePaf_0145 + IMPORT_FUNC "scePaf",0x78054045,scePaf_78054045 +#endif +#ifdef F_scePaf_0146 + IMPORT_FUNC "scePaf",0xDF9138A8,scePaf_DF9138A8 +#endif +#ifdef F_scePaf_0147 + IMPORT_FUNC "scePaf",0xF7FB133E,scePaf_F7FB133E +#endif +#ifdef F_scePaf_0148 + IMPORT_FUNC "scePaf",0xCFF2B69C,scePaf_CFF2B69C +#endif +#ifdef F_scePaf_0149 + IMPORT_FUNC "scePaf",0xEF52945B,scePaf_EF52945B +#endif +#ifdef F_scePaf_0150 + IMPORT_FUNC "scePaf",0xBAA88CDA,scePaf_BAA88CDA +#endif +#ifdef F_scePaf_0151 + IMPORT_FUNC "scePaf",0xBDC894D8,scePaf_BDC894D8 +#endif +#ifdef F_scePaf_0152 + IMPORT_FUNC "scePaf",0x5045C01F,scePaf_5045C01F +#endif +#ifdef F_scePaf_0153 + IMPORT_FUNC "scePaf",0xA89157EE,scePaf_A89157EE +#endif +#ifdef F_scePaf_0154 + IMPORT_FUNC "scePaf",0x1F0B8678,scePaf_1F0B8678 +#endif +#ifdef F_scePaf_0155 + IMPORT_FUNC "scePaf",0x33096E46,scePaf_33096E46 +#endif +#ifdef F_scePaf_0156 + IMPORT_FUNC "scePaf",0x47E35A50,scePaf_47E35A50 +#endif +#ifdef F_scePaf_0157 + IMPORT_FUNC "scePaf",0x25391E36,scePaf_25391E36 +#endif +#ifdef F_scePaf_0158 + IMPORT_FUNC "scePaf",0x50FFFCD2,scePaf_50FFFCD2 +#endif +#ifdef F_scePaf_0159 + IMPORT_FUNC "scePaf",0x206C1F70,scePaf_206C1F70 +#endif +#ifdef F_scePaf_0160 + IMPORT_FUNC "scePaf",0x0C66B594,scePaf_0C66B594 +#endif +#ifdef F_scePaf_0161 + IMPORT_FUNC "scePaf",0x39F89900,scePaf_39F89900 +#endif +#ifdef F_scePaf_0162 + IMPORT_FUNC "scePaf",0xB6841F37,scePaf_B6841F37 +#endif +#ifdef F_scePaf_0163 + IMPORT_FUNC "scePaf",0x360956CC,scePaf_360956CC +#endif +#ifdef F_scePaf_0164 + IMPORT_FUNC "scePaf",0x0AEDCDA1,scePaf_0AEDCDA1 +#endif +#ifdef F_scePaf_0165 + IMPORT_FUNC "scePaf",0x222526B6,scePaf_222526B6 +#endif +#ifdef F_scePaf_0166 + IMPORT_FUNC "scePaf",0x41A7BDD2,scePaf_41A7BDD2 +#endif +#ifdef F_scePaf_0167 + IMPORT_FUNC "scePaf",0xD07AF3FA,scePaf_D07AF3FA +#endif +#ifdef F_scePaf_0168 + IMPORT_FUNC "scePaf",0x29DC646F,scePaf_29DC646F +#endif +#ifdef F_scePaf_0169 + IMPORT_FUNC "scePaf",0x2A6499A5,scePaf_2A6499A5 +#endif +#ifdef F_scePaf_0170 + IMPORT_FUNC "scePaf",0x4FCA0DE9,scePaf_4FCA0DE9 +#endif +#ifdef F_scePaf_0171 + IMPORT_FUNC "scePaf",0xE796C85B,scePaf_E796C85B +#endif +#ifdef F_scePaf_0172 + IMPORT_FUNC "scePaf",0xBAFF6806,scePaf_BAFF6806 +#endif +#ifdef F_scePaf_0173 + IMPORT_FUNC "scePaf",0xAA978F61,scePaf_AA978F61 +#endif +#ifdef F_scePaf_0174 + IMPORT_FUNC "scePaf",0xFCF42D6D,scePaf_FCF42D6D +#endif +#ifdef F_scePaf_0175 + IMPORT_FUNC "scePaf",0x5DB527D4,scePaf_5DB527D4 +#endif +#ifdef F_scePaf_0176 + IMPORT_FUNC "scePaf",0x2E6CA751,scePaf_2E6CA751 +#endif +#ifdef F_scePaf_0177 + IMPORT_FUNC "scePaf",0x3F52824F,scePaf_3F52824F +#endif +#ifdef F_scePaf_0178 + IMPORT_FUNC "scePaf",0x1C286704,scePaf_1C286704 +#endif +#ifdef F_scePaf_0179 + IMPORT_FUNC "scePaf",0x672036FE,scePaf_672036FE +#endif +#ifdef F_scePaf_0180 + IMPORT_FUNC "scePaf",0x08A02EFF,scePaf_08A02EFF +#endif +#ifdef F_scePaf_0181 + IMPORT_FUNC "scePaf",0x01A35C15,scePaf_01A35C15 +#endif +#ifdef F_scePaf_0182 + IMPORT_FUNC "scePaf",0x470ABD60,scePaf_470ABD60 +#endif +#ifdef F_scePaf_0183 + IMPORT_FUNC "scePaf",0xB42D784E,scePaf_B42D784E +#endif +#ifdef F_scePaf_0184 + IMPORT_FUNC "scePaf",0x84485F54,scePaf_84485F54 +#endif +#ifdef F_scePaf_0185 + IMPORT_FUNC "scePaf",0x87516C3B,scePaf_87516C3B +#endif +#ifdef F_scePaf_0186 + IMPORT_FUNC "scePaf",0x715E8DAB,scePaf_715E8DAB +#endif +#ifdef F_scePaf_0187 + IMPORT_FUNC "scePaf",0xD35B454A,scePaf_D35B454A +#endif +#ifdef F_scePaf_0188 + IMPORT_FUNC "scePaf",0xCFB1A402,scePaf_CFB1A402 +#endif +#ifdef F_scePaf_0189 + IMPORT_FUNC "scePaf",0x5D7F1F27,scePaf_5D7F1F27 +#endif +#ifdef F_scePaf_0190 + IMPORT_FUNC "scePaf",0x3291BDDD,scePaf_3291BDDD +#endif +#ifdef F_scePaf_0191 + IMPORT_FUNC "scePaf",0x515EE222,scePaf_515EE222 +#endif +#ifdef F_scePaf_0192 + IMPORT_FUNC "scePaf",0x3987B5C4,scePaf_3987B5C4 +#endif +#ifdef F_scePaf_0193 + IMPORT_FUNC "scePaf",0xF89ECA28,scePaf_F89ECA28 +#endif +#ifdef F_scePaf_0194 + IMPORT_FUNC "scePaf",0x4AF8E417,scePaf_4AF8E417 +#endif +#ifdef F_scePaf_0195 + IMPORT_FUNC "scePaf",0x76D5A950,scePaf_76D5A950 +#endif +#ifdef F_scePaf_0196 + IMPORT_FUNC "scePaf",0xF577BC82,scePaf_F577BC82 +#endif +#ifdef F_scePaf_0197 + IMPORT_FUNC "scePaf",0x369E597A,scePaf_369E597A +#endif +#ifdef F_scePaf_0198 + IMPORT_FUNC "scePaf",0x293A01D8,scePaf_293A01D8 +#endif +#ifdef F_scePaf_0199 + IMPORT_FUNC "scePaf",0x45386654,scePaf_45386654 +#endif +#ifdef F_scePaf_0200 + IMPORT_FUNC "scePaf",0x73D49419,scePaf_73D49419 +#endif +#ifdef F_scePaf_0201 + IMPORT_FUNC "scePaf",0xAD007AB6,scePaf_AD007AB6 +#endif +#ifdef F_scePaf_0202 + IMPORT_FUNC "scePaf",0xF49F3C59,scePaf_F49F3C59 +#endif +#ifdef F_scePaf_0203 + IMPORT_FUNC "scePaf",0x05EEE8A6,scePaf_05EEE8A6 +#endif +#ifdef F_scePaf_0204 + IMPORT_FUNC "scePaf",0x15EF8E18,scePaf_15EF8E18 +#endif +#ifdef F_scePaf_0205 + IMPORT_FUNC "scePaf",0xFE84212F,scePaf_FE84212F +#endif +#ifdef F_scePaf_0206 + IMPORT_FUNC "scePaf",0x9D92765E,scePaf_9D92765E +#endif +#ifdef F_scePaf_0207 + IMPORT_FUNC "scePaf",0x98A6C193,scePaf_98A6C193 +#endif +#ifdef F_scePaf_0208 + IMPORT_FUNC "scePaf",0x1943B875,scePaf_1943B875 +#endif +#ifdef F_scePaf_0209 + IMPORT_FUNC "scePaf",0xD7074BD1,scePaf_D7074BD1 +#endif +#ifdef F_scePaf_0210 + IMPORT_FUNC "scePaf",0xBD49CAEF,scePaf_BD49CAEF +#endif +#ifdef F_scePaf_0211 + IMPORT_FUNC "scePaf",0x6C4976AF,scePaf_6C4976AF +#endif +#ifdef F_scePaf_0212 + IMPORT_FUNC "scePaf",0x85112756,scePaf_85112756 +#endif +#ifdef F_scePaf_0213 + IMPORT_FUNC "scePaf",0xFDB39519,scePaf_FDB39519 +#endif +#ifdef F_scePaf_0214 + IMPORT_FUNC "scePaf",0xDA3A6D88,scePaf_DA3A6D88 +#endif +#ifdef F_scePaf_0215 + IMPORT_FUNC "scePaf",0x199896A3,scePaf_199896A3 +#endif +#ifdef F_scePaf_0216 + IMPORT_FUNC "scePaf",0x5458E412,scePaf_5458E412 +#endif +#ifdef F_scePaf_0217 + IMPORT_FUNC "scePaf",0x43374E9E,scePaf_43374E9E +#endif +#ifdef F_scePaf_0218 + IMPORT_FUNC "scePaf",0x6797988C,scePaf_6797988C +#endif +#ifdef F_scePaf_0219 + IMPORT_FUNC "scePaf",0x449C8821,scePaf_449C8821 +#endif +#ifdef F_scePaf_0220 + IMPORT_FUNC "scePaf",0x6C386158,scePaf_6C386158 +#endif +#ifdef F_scePaf_0221 + IMPORT_FUNC "scePaf",0x8E751FCC,scePaf_8E751FCC +#endif +#ifdef F_scePaf_0222 + IMPORT_FUNC "scePaf",0xF32223AC,scePaf_F32223AC +#endif +#ifdef F_scePaf_0223 + IMPORT_FUNC "scePaf",0x40B21F4F,scePaf_40B21F4F +#endif +#ifdef F_scePaf_0224 + IMPORT_FUNC "scePaf",0x501E9BC9,scePaf_501E9BC9 +#endif +#ifdef F_scePaf_0225 + IMPORT_FUNC "scePaf",0x4E60E34C,scePaf_4E60E34C +#endif +#ifdef F_scePaf_0226 + IMPORT_FUNC "scePaf",0x39C55C03,scePaf_39C55C03 +#endif +#ifdef F_scePaf_0227 + IMPORT_FUNC "scePaf",0x65920294,scePaf_65920294 +#endif +#ifdef F_scePaf_0228 + IMPORT_FUNC "scePaf",0x37DDBDD8,scePaf_37DDBDD8 +#endif +#ifdef F_scePaf_0229 + IMPORT_FUNC "scePaf",0x92A46B32,scePaf_92A46B32 +#endif +#ifdef F_scePaf_0230 + IMPORT_FUNC "scePaf",0x905347E9,scePaf_905347E9 +#endif +#ifdef F_scePaf_0231 + IMPORT_FUNC "scePaf",0xDF887DED,scePaf_DF887DED +#endif +#ifdef F_scePaf_0232 + IMPORT_FUNC "scePaf",0xDC544921,scePaf_DC544921 +#endif +#ifdef F_scePaf_0233 + IMPORT_FUNC "scePaf",0x585B93BC,scePaf_585B93BC +#endif +#ifdef F_scePaf_0234 + IMPORT_FUNC "scePaf",0x1AD33D73,scePaf_1AD33D73 +#endif +#ifdef F_scePaf_0235 + IMPORT_FUNC "scePaf",0xA4F53FED,scePaf_A4F53FED +#endif +#ifdef F_scePaf_0236 + IMPORT_FUNC "scePaf",0x01CF521E,scePaf_01CF521E +#endif +#ifdef F_scePaf_0237 + IMPORT_FUNC "scePaf",0x3C68DCB7,scePaf_3C68DCB7 +#endif +#ifdef F_scePaf_0238 + IMPORT_FUNC "scePaf",0x3F81333A,scePaf_3F81333A +#endif +#ifdef F_scePaf_0239 + IMPORT_FUNC "scePaf",0x9A8E343E,scePaf_9A8E343E +#endif +#ifdef F_scePaf_0240 + IMPORT_FUNC "scePaf",0x95040C08,scePaf_95040C08 +#endif +#ifdef F_scePaf_0241 + IMPORT_FUNC "scePaf",0x0CFDBE2F,scePaf_0CFDBE2F +#endif +#ifdef F_scePaf_0242 + IMPORT_FUNC "scePaf",0x3829AC24,scePaf_3829AC24 +#endif +#ifdef F_scePaf_0243 + IMPORT_FUNC "scePaf",0x1F0E9712,scePaf_1F0E9712 +#endif +#ifdef F_scePaf_0244 + IMPORT_FUNC "scePaf",0xD24E4016,scePaf_D24E4016 +#endif +#ifdef F_scePaf_0245 + IMPORT_FUNC "scePaf",0x409E25A3,scePaf_409E25A3 +#endif +#ifdef F_scePaf_0246 + IMPORT_FUNC "scePaf",0xDC8B0309,scePaf_DC8B0309 +#endif +#ifdef F_scePaf_0247 + IMPORT_FUNC "scePaf",0xEB553D60,scePaf_EB553D60 +#endif +#ifdef F_scePaf_0248 + IMPORT_FUNC "scePaf",0x4EA868E6,scePaf_4EA868E6 +#endif +#ifdef F_scePaf_0249 + IMPORT_FUNC "scePaf",0x8AB03D91,scePaf_8AB03D91 +#endif +#ifdef F_scePaf_0250 + IMPORT_FUNC "scePaf",0x5CA7F421,scePaf_5CA7F421 +#endif +#ifdef F_scePaf_0251 + IMPORT_FUNC "scePaf",0xB7865607,scePaf_B7865607 +#endif +#ifdef F_scePaf_0252 + IMPORT_FUNC "scePaf",0x95948FB6,scePaf_95948FB6 +#endif +#ifdef F_scePaf_0253 + IMPORT_FUNC "scePaf",0xBA433BEF,scePaf_BA433BEF +#endif +#ifdef F_scePaf_0254 + IMPORT_FUNC "scePaf",0xED89C94B,scePaf_ED89C94B +#endif +#ifdef F_scePaf_0255 + IMPORT_FUNC "scePaf",0x0E8A3B52,scePaf_0E8A3B52 +#endif +#ifdef F_scePaf_0256 + IMPORT_FUNC "scePaf",0xD587826C,scePaf_D587826C +#endif +#ifdef F_scePaf_0257 + IMPORT_FUNC "scePaf",0x61B105C0,scePaf_61B105C0 +#endif +#ifdef F_scePaf_0258 + IMPORT_FUNC "scePaf",0xDAD477C1,scePaf_DAD477C1 +#endif +#ifdef F_scePaf_0259 + IMPORT_FUNC "scePaf",0xD91B2651,scePaf_D91B2651 +#endif +#ifdef F_scePaf_0260 + IMPORT_FUNC "scePaf",0xA02E66FA,scePaf_A02E66FA +#endif +#ifdef F_scePaf_0261 + IMPORT_FUNC "scePaf",0x2D79697E,scePaf_2D79697E +#endif +#ifdef F_scePaf_0262 + IMPORT_FUNC "scePaf",0xEDF1C662,scePaf_EDF1C662 +#endif +#ifdef F_scePaf_0263 + IMPORT_FUNC "scePaf",0xA7818BCE,scePaf_A7818BCE +#endif +#ifdef F_scePaf_0264 + IMPORT_FUNC "scePaf",0x695BCD34,scePaf_695BCD34 +#endif +#ifdef F_scePaf_0265 + IMPORT_FUNC "scePaf",0xC4D819AA,scePaf_C4D819AA +#endif +#ifdef F_scePaf_0266 + IMPORT_FUNC "scePaf",0x70B92642,scePaf_70B92642 +#endif +#ifdef F_scePaf_0267 + IMPORT_FUNC "scePaf",0x447974D1,scePaf_447974D1 +#endif +#ifdef F_scePaf_0268 + IMPORT_FUNC "scePaf",0x63EA1815,scePaf_63EA1815 +#endif +#ifdef F_scePaf_0269 + IMPORT_FUNC "scePaf",0xCB65103E,scePaf_CB65103E +#endif +#ifdef F_scePaf_0270 + IMPORT_FUNC "scePaf",0x32B27ADD,scePaf_32B27ADD +#endif +#ifdef F_scePaf_0271 + IMPORT_FUNC "scePaf",0xADC146F0,scePaf_ADC146F0 +#endif +#ifdef F_scePaf_0272 + IMPORT_FUNC "scePaf",0xD5A254F9,scePaf_D5A254F9 +#endif +#ifdef F_scePaf_0273 + IMPORT_FUNC "scePaf",0x42F43213,scePaf_42F43213 +#endif +#ifdef F_scePaf_0274 + IMPORT_FUNC "scePaf",0x5D242D11,scePaf_5D242D11 +#endif +#ifdef F_scePaf_0275 + IMPORT_FUNC "scePaf",0x11361F12,scePaf_11361F12 +#endif +#ifdef F_scePaf_0276 + IMPORT_FUNC "scePaf",0x51FF9D24,scePaf_51FF9D24 +#endif +#ifdef F_scePaf_0277 + IMPORT_FUNC "scePaf",0xB2ED6CAA,scePaf_B2ED6CAA +#endif +#ifdef F_scePaf_0278 + IMPORT_FUNC "scePaf",0x79F4AE65,scePaf_79F4AE65 +#endif +#ifdef F_scePaf_0279 + IMPORT_FUNC "scePaf",0x905CF2A7,scePaf_905CF2A7 +#endif +#ifdef F_scePaf_0280 + IMPORT_FUNC "scePaf",0xE732CF74,scePaf_E732CF74 +#endif +#ifdef F_scePaf_0281 + IMPORT_FUNC "scePaf",0xB711DC69,scePaf_B711DC69 +#endif +#ifdef F_scePaf_0282 + IMPORT_FUNC "scePaf",0x0ED80B09,scePaf_0ED80B09 +#endif +#ifdef F_scePaf_0283 + IMPORT_FUNC "scePaf",0xBB457D6F,scePaf_BB457D6F +#endif +#ifdef F_scePaf_0284 + IMPORT_FUNC "scePaf",0xB6F52424,scePaf_B6F52424 +#endif +#ifdef F_scePaf_0285 + IMPORT_FUNC "scePaf",0xBA6B8B02,scePaf_BA6B8B02 +#endif +#ifdef F_scePaf_0286 + IMPORT_FUNC "scePaf",0xB9BE69FD,scePaf_B9BE69FD +#endif +#ifdef F_scePaf_0287 + IMPORT_FUNC "scePaf",0xFA758B05,scePaf_FA758B05 +#endif +#ifdef F_scePaf_0288 + IMPORT_FUNC "scePaf",0xFA87D725,scePaf_FA87D725 +#endif +#ifdef F_scePaf_0289 + IMPORT_FUNC "scePaf",0xFC37FABD,scePaf_FC37FABD +#endif +#ifdef F_scePaf_0290 + IMPORT_FUNC "scePaf",0x64775957,scePaf_64775957 +#endif +#ifdef F_scePaf_0291 + IMPORT_FUNC "scePaf",0x7F2442DC,scePaf_7F2442DC +#endif +#ifdef F_scePaf_0292 + IMPORT_FUNC "scePaf",0x86B41BA3,scePaf_86B41BA3 +#endif +#ifdef F_scePaf_0293 + IMPORT_FUNC "scePaf",0x541F36E9,scePaf_541F36E9 +#endif +#ifdef F_scePaf_0294 + IMPORT_FUNC "scePaf",0x86C87E62,scePaf_86C87E62 +#endif +#ifdef F_scePaf_0295 + IMPORT_FUNC "scePaf",0xF1546D14,scePaf_F1546D14 +#endif +#ifdef F_scePaf_0296 + IMPORT_FUNC "scePaf",0x6840D208,scePaf_6840D208 +#endif +#ifdef F_scePaf_0297 + IMPORT_FUNC "scePaf",0xD1EE972C,scePaf_D1EE972C +#endif +#ifdef F_scePaf_0298 + IMPORT_FUNC "scePaf",0x1232B7A3,scePaf_1232B7A3 +#endif +#ifdef F_scePaf_0299 + IMPORT_FUNC "scePaf",0x8D7FC7DB,scePaf_8D7FC7DB +#endif +#ifdef F_scePaf_0300 + IMPORT_FUNC "scePaf",0x5DE0445F,scePaf_5DE0445F +#endif +#ifdef F_scePaf_0301 + IMPORT_FUNC "scePaf",0x09AC6844,scePaf_09AC6844 +#endif +#ifdef F_scePaf_0302 + IMPORT_FUNC "scePaf",0xD2E0D705,scePaf_D2E0D705 +#endif +#ifdef F_scePaf_0303 + IMPORT_FUNC "scePaf",0xAE02F241,scePaf_AE02F241 +#endif +#ifdef F_scePaf_0304 + IMPORT_FUNC "scePaf",0xD1159069,scePaf_D1159069 +#endif +#ifdef F_scePaf_0305 + IMPORT_FUNC "scePaf",0xBFFAEE83,scePaf_BFFAEE83 +#endif +#ifdef F_scePaf_0306 + IMPORT_FUNC "scePaf",0xDDA68BE8,scePaf_DDA68BE8 +#endif +#ifdef F_scePaf_0307 + IMPORT_FUNC "scePaf",0x9AFD4AD4,scePaf_9AFD4AD4 +#endif +#ifdef F_scePaf_0308 + IMPORT_FUNC "scePaf",0x6E1B5B50,scePaf_6E1B5B50 +#endif +#ifdef F_scePaf_0309 + IMPORT_FUNC "scePaf",0x8DEB3DB3,scePaf_8DEB3DB3 +#endif +#ifdef F_scePaf_0310 + IMPORT_FUNC "scePaf",0xBA09CF46,scePaf_BA09CF46 +#endif +#ifdef F_scePaf_0311 + IMPORT_FUNC "scePaf",0x6DD28F44,scePaf_6DD28F44 +#endif +#ifdef F_scePaf_0312 + IMPORT_FUNC "scePaf",0x4ADAEF94,scePaf_4ADAEF94 +#endif +#ifdef F_scePaf_0313 + IMPORT_FUNC "scePaf",0x95708BC0,scePaf_95708BC0 +#endif +#ifdef F_scePaf_0314 + IMPORT_FUNC "scePaf",0xC85155C9,scePaf_C85155C9 +#endif +#ifdef F_scePaf_0315 + IMPORT_FUNC "scePaf",0xDEF9EBE7,scePaf_DEF9EBE7 +#endif +#ifdef F_scePaf_0316 + IMPORT_FUNC "scePaf",0xF23F3226,scePaf_F23F3226 +#endif +#ifdef F_scePaf_0317 + IMPORT_FUNC "scePaf",0xD153385E,scePaf_D153385E +#endif +#ifdef F_scePaf_0318 + IMPORT_FUNC "scePaf",0x86A5AE7D,scePaf_86A5AE7D +#endif +#ifdef F_scePaf_0319 + IMPORT_FUNC "scePaf",0x5A8D4BDB,scePaf_5A8D4BDB +#endif +#ifdef F_scePaf_0320 + IMPORT_FUNC "scePaf",0x2120282A,scePaf_2120282A +#endif +#ifdef F_scePaf_0321 + IMPORT_FUNC "scePaf",0x8159EB28,scePaf_8159EB28 +#endif +#ifdef F_scePaf_0322 + IMPORT_FUNC "scePaf",0x5CE11C03,scePaf_5CE11C03 +#endif +#ifdef F_scePaf_0323 + IMPORT_FUNC "scePaf",0x05073826,scePaf_05073826 +#endif +#ifdef F_scePaf_0324 + IMPORT_FUNC "scePaf",0xA4B48F00,scePaf_A4B48F00 +#endif +#ifdef F_scePaf_0325 + IMPORT_FUNC "scePaf",0x224C33F0,scePaf_224C33F0 +#endif +#ifdef F_scePaf_0326 + IMPORT_FUNC "scePaf",0x3DBE861F,scePaf_3DBE861F +#endif +#ifdef F_scePaf_0327 + IMPORT_FUNC "scePaf",0xFA78AF39,scePaf_FA78AF39 +#endif +#ifdef F_scePaf_0328 + IMPORT_FUNC "scePaf",0xA3761F27,scePaf_A3761F27 +#endif +#ifdef F_scePaf_0329 + IMPORT_FUNC "scePaf",0xDE75C2BA,scePaf_DE75C2BA +#endif +#ifdef F_scePaf_0330 + IMPORT_FUNC "scePaf",0x4129A915,scePaf_4129A915 +#endif +#ifdef F_scePaf_0331 + IMPORT_FUNC "scePaf",0x8A51BA1E,scePaf_8A51BA1E +#endif +#ifdef F_scePaf_0332 + IMPORT_FUNC "scePaf",0x0FFA3ECE,scePaf_0FFA3ECE +#endif +#ifdef F_scePaf_0333 + IMPORT_FUNC "scePaf",0x89582FD0,scePaf_89582FD0 +#endif +#ifdef F_scePaf_0334 + IMPORT_FUNC "scePaf",0x84913A3A,scePaf_84913A3A +#endif +#ifdef F_scePaf_0335 + IMPORT_FUNC "scePaf",0x06EA7CDE,scePaf_06EA7CDE +#endif +#ifdef F_scePaf_0336 + IMPORT_FUNC "scePaf",0x9563887D,scePaf_9563887D +#endif +#ifdef F_scePaf_0337 + IMPORT_FUNC "scePaf",0x21B885B8,scePaf_21B885B8 +#endif +#ifdef F_scePaf_0338 + IMPORT_FUNC "scePaf",0xB0FD305A,scePaf_B0FD305A +#endif +#ifdef F_scePaf_0339 + IMPORT_FUNC "scePaf",0x777635B9,scePaf_777635B9 +#endif +#ifdef F_scePaf_0340 + IMPORT_FUNC "scePaf",0xF8301DBC,scePaf_F8301DBC +#endif +#ifdef F_scePaf_0341 + IMPORT_FUNC "scePaf",0x5A818E41,scePaf_5A818E41 +#endif +#ifdef F_scePaf_0342 + IMPORT_FUNC "scePaf",0xA9970EF5,scePaf_A9970EF5 +#endif +#ifdef F_scePaf_0343 + IMPORT_FUNC "scePaf",0x6741C662,scePaf_6741C662 +#endif +#ifdef F_scePaf_0344 + IMPORT_FUNC "scePaf",0x14CE7F6F,scePaf_14CE7F6F +#endif +#ifdef F_scePaf_0345 + IMPORT_FUNC "scePaf",0xDFC8650C,scePaf_DFC8650C +#endif +#ifdef F_scePaf_0346 + IMPORT_FUNC "scePaf",0xECE59E24,scePaf_ECE59E24 +#endif +#ifdef F_scePaf_0347 + IMPORT_FUNC "scePaf",0x4D810FDC,scePaf_4D810FDC +#endif +#ifdef F_scePaf_0348 + IMPORT_FUNC "scePaf",0xABCBC1C5,scePaf_ABCBC1C5 +#endif +#ifdef F_scePaf_0349 + IMPORT_FUNC "scePaf",0x7C2C2742,scePaf_7C2C2742 +#endif +#ifdef F_scePaf_0350 + IMPORT_FUNC "scePaf",0xD0AD10FF,scePaf_D0AD10FF +#endif +#ifdef F_scePaf_0351 + IMPORT_FUNC "scePaf",0x2A2EB136,scePaf_2A2EB136 +#endif +#ifdef F_scePaf_0352 + IMPORT_FUNC "scePaf",0x20F5234E,scePaf_20F5234E +#endif +#ifdef F_scePaf_0353 + IMPORT_FUNC "scePaf",0x6F74F263,scePaf_6F74F263 +#endif +#ifdef F_scePaf_0354 + IMPORT_FUNC "scePaf",0xD6232F26,scePaf_D6232F26 +#endif +#ifdef F_scePaf_0355 + IMPORT_FUNC "scePaf",0xED83B18F,scePaf_ED83B18F +#endif +#ifdef F_scePaf_0356 + IMPORT_FUNC "scePaf",0xD6C1FF36,scePaf_D6C1FF36 +#endif +#ifdef F_scePaf_0357 + IMPORT_FUNC "scePaf",0x7952AE83,scePaf_7952AE83 +#endif +#ifdef F_scePaf_0358 + IMPORT_FUNC "scePaf",0xFDB98CAC,scePaf_FDB98CAC +#endif +#ifdef F_scePaf_0359 + IMPORT_FUNC "scePaf",0xBA1F20EE,scePaf_BA1F20EE +#endif +#ifdef F_scePaf_0360 + IMPORT_FUNC "scePaf",0xD96449B4,scePaf_D96449B4 +#endif +#ifdef F_scePaf_0361 + IMPORT_FUNC "scePaf",0x71EDAD83,scePaf_71EDAD83 +#endif +#ifdef F_scePaf_0362 + IMPORT_FUNC "scePaf",0x2CB6FBBE,scePaf_2CB6FBBE +#endif +#ifdef F_scePaf_0363 + IMPORT_FUNC "scePaf",0x442F1731,scePaf_442F1731 +#endif +#ifdef F_scePaf_0364 + IMPORT_FUNC "scePaf",0xE418D7E0,scePaf_E418D7E0 +#endif +#ifdef F_scePaf_0365 + IMPORT_FUNC "scePaf",0xC8FD64AA,scePaf_C8FD64AA +#endif +#ifdef F_scePaf_0366 + IMPORT_FUNC "scePaf",0xDB230BE1,scePaf_DB230BE1 +#endif +#ifdef F_scePaf_0367 + IMPORT_FUNC "scePaf",0x0FB7D433,scePaf_0FB7D433 +#endif +#ifdef F_scePaf_0368 + IMPORT_FUNC "scePaf",0xC2E4423A,scePaf_C2E4423A +#endif +#ifdef F_scePaf_0369 + IMPORT_FUNC "scePaf",0xA574DB92,scePaf_A574DB92 +#endif +#ifdef F_scePaf_0370 + IMPORT_FUNC "scePaf",0xC6F44EF9,scePaf_C6F44EF9 +#endif +#ifdef F_scePaf_0371 + IMPORT_FUNC "scePaf",0x6B678D44,scePaf_6B678D44 +#endif +#ifdef F_scePaf_0372 + IMPORT_FUNC "scePaf",0xE15A64EA,scePaf_E15A64EA +#endif +#ifdef F_scePaf_0373 + IMPORT_FUNC "scePaf",0x6A772BF7,scePaf_6A772BF7 +#endif +#ifdef F_scePaf_0374 + IMPORT_FUNC "scePaf",0xD180ACBA,scePaf_D180ACBA +#endif +#ifdef F_scePaf_0375 + IMPORT_FUNC "scePaf",0x4C5F6657,scePaf_4C5F6657 +#endif +#ifdef F_scePaf_0376 + IMPORT_FUNC "scePaf",0xDFB912CB,scePaf_DFB912CB +#endif +#ifdef F_scePaf_0377 + IMPORT_FUNC "scePaf",0xBAA76FDE,scePaf_BAA76FDE +#endif +#ifdef F_scePaf_0378 + IMPORT_FUNC "scePaf",0x6CF44237,scePaf_6CF44237 +#endif +#ifdef F_scePaf_0379 + IMPORT_FUNC "scePaf",0xCFAF88AB,scePaf_CFAF88AB +#endif +#ifdef F_scePaf_0380 + IMPORT_FUNC "scePaf",0xD34D0B82,scePaf_D34D0B82 +#endif +#ifdef F_scePaf_0381 + IMPORT_FUNC "scePaf",0x8CDEDC6F,scePaf_8CDEDC6F +#endif +#ifdef F_scePaf_0382 + IMPORT_FUNC "scePaf",0x22B0D7D8,scePaf_22B0D7D8 +#endif +#ifdef F_scePaf_0383 + IMPORT_FUNC "scePaf",0xCA8CDF32,scePaf_CA8CDF32 +#endif +#ifdef F_scePaf_0384 + IMPORT_FUNC "scePaf",0xFCABD0E7,scePaf_FCABD0E7 +#endif +#ifdef F_scePaf_0385 + IMPORT_FUNC "scePaf",0xEE10AEF1,scePaf_EE10AEF1 +#endif +#ifdef F_scePaf_0386 + IMPORT_FUNC "scePaf",0xD99BEC81,scePaf_D99BEC81 +#endif +#ifdef F_scePaf_0387 + IMPORT_FUNC "scePaf",0x4D4805AF,scePaf_4D4805AF +#endif +#ifdef F_scePaf_0388 + IMPORT_FUNC "scePaf",0x28F8DE83,scePaf_28F8DE83 +#endif +#ifdef F_scePaf_0389 + IMPORT_FUNC "scePaf",0xB1F587EF,scePaf_B1F587EF +#endif +#ifdef F_scePaf_0390 + IMPORT_FUNC "scePaf",0x8C1ED07B,scePaf_8C1ED07B +#endif +#ifdef F_scePaf_0391 + IMPORT_FUNC "scePaf",0x04EF78CD,scePaf_04EF78CD +#endif +#ifdef F_scePaf_0392 + IMPORT_FUNC "scePaf",0x75A553A2,scePaf_75A553A2 +#endif +#ifdef F_scePaf_0393 + IMPORT_FUNC "scePaf",0xF4404EAF,scePaf_F4404EAF +#endif +#ifdef F_scePaf_0394 + IMPORT_FUNC "scePaf",0xD63D4561,scePaf_D63D4561 +#endif +#ifdef F_scePaf_0395 + IMPORT_FUNC "scePaf",0x81667058,scePaf_81667058 +#endif +#ifdef F_scePaf_0396 + IMPORT_FUNC "scePaf",0x149CDEB9,scePaf_149CDEB9 +#endif +#ifdef F_scePaf_0397 + IMPORT_FUNC "scePaf",0x62081F34,scePaf_62081F34 +#endif +#ifdef F_scePaf_0398 + IMPORT_FUNC "scePaf",0xBECD1827,scePaf_BECD1827 +#endif +#ifdef F_scePaf_0399 + IMPORT_FUNC "scePaf",0xA8711520,scePaf_A8711520 +#endif +#ifdef F_scePaf_0400 + IMPORT_FUNC "scePaf",0xFCDD55E3,scePaf_FCDD55E3 +#endif +#ifdef F_scePaf_0401 + IMPORT_FUNC "scePaf",0x2EABF548,scePaf_2EABF548 +#endif +#ifdef F_scePaf_0402 + IMPORT_FUNC "scePaf",0x50F72192,scePaf_50F72192 +#endif +#ifdef F_scePaf_0403 + IMPORT_FUNC "scePaf",0x73712598,scePaf_73712598 +#endif +#ifdef F_scePaf_0404 + IMPORT_FUNC "scePaf",0x8B439A23,scePaf_8B439A23 +#endif +#ifdef F_scePaf_0405 + IMPORT_FUNC "scePaf",0x7435C5D5,scePaf_7435C5D5 +#endif +#ifdef F_scePaf_0406 + IMPORT_FUNC "scePaf",0xCC103AD2,scePaf_CC103AD2 +#endif +#ifdef F_scePaf_0407 + IMPORT_FUNC "scePaf",0x566BC690,scePaf_566BC690 +#endif +#ifdef F_scePaf_0408 + IMPORT_FUNC "scePaf",0x68569AAC,scePaf_68569AAC +#endif +#ifdef F_scePaf_0409 + IMPORT_FUNC "scePaf",0x76491EEA,scePaf_76491EEA +#endif +#ifdef F_scePaf_0410 + IMPORT_FUNC "scePaf",0x7771BC86,scePaf_7771BC86 +#endif +#ifdef F_scePaf_0411 + IMPORT_FUNC "scePaf",0x06BB62B7,scePaf_06BB62B7 +#endif +#ifdef F_scePaf_0412 + IMPORT_FUNC "scePaf",0x30F5E7DF,scePaf_30F5E7DF +#endif +#ifdef F_scePaf_0413 + IMPORT_FUNC "scePaf",0x97B9C21E,scePaf_97B9C21E +#endif +#ifdef F_scePaf_0414 + IMPORT_FUNC "scePaf",0xD16E5935,scePaf_D16E5935 +#endif +#ifdef F_scePaf_0415 + IMPORT_FUNC "scePaf",0x9D496842,scePaf_9D496842 +#endif +#ifdef F_scePaf_0416 + IMPORT_FUNC "scePaf",0x2750CF68,scePaf_2750CF68 +#endif +#ifdef F_scePaf_0417 + IMPORT_FUNC "scePaf",0xFB3A9617,scePaf_FB3A9617 +#endif +#ifdef F_scePaf_0418 + IMPORT_FUNC "scePaf",0x35F003C0,scePaf_35F003C0 +#endif +#ifdef F_scePaf_0419 + IMPORT_FUNC "scePaf",0xEBDC149C,scePaf_EBDC149C +#endif +#ifdef F_scePaf_0420 + IMPORT_FUNC "scePaf",0x08DD2D50,scePaf_08DD2D50 +#endif +#ifdef F_scePaf_0421 + IMPORT_FUNC "scePaf",0x846E1F0A,scePaf_846E1F0A +#endif +#ifdef F_scePaf_0422 + IMPORT_FUNC "scePaf",0x4AB0D3F4,scePaf_4AB0D3F4 +#endif +#ifdef F_scePaf_0423 + IMPORT_FUNC "scePaf",0x9122393C,scePaf_9122393C +#endif +#ifdef F_scePaf_0424 + IMPORT_FUNC "scePaf",0x5C4BF618,scePaf_5C4BF618 +#endif +#ifdef F_scePaf_0425 + IMPORT_FUNC "scePaf",0x93538664,scePaf_93538664 +#endif +#ifdef F_scePaf_0426 + IMPORT_FUNC "scePaf",0x952CE8AF,scePaf_952CE8AF +#endif +#ifdef F_scePaf_0427 + IMPORT_FUNC "scePaf",0x21DBFF5B,scePaf_21DBFF5B +#endif +#ifdef F_scePaf_0428 + IMPORT_FUNC "scePaf",0x359CBCAF,scePaf_359CBCAF +#endif +#ifdef F_scePaf_0429 + IMPORT_FUNC "scePaf",0x3684D457,scePaf_3684D457 +#endif +#ifdef F_scePaf_0430 + IMPORT_FUNC "scePaf",0x0598FFD6,scePaf_0598FFD6 +#endif +#ifdef F_scePaf_0431 + IMPORT_FUNC "scePaf",0xCAF82B9B,scePaf_CAF82B9B +#endif +#ifdef F_scePaf_0432 + IMPORT_FUNC "scePaf",0x5B202AED,scePaf_5B202AED +#endif +#ifdef F_scePaf_0433 + IMPORT_FUNC "scePaf",0x50DC7446,scePaf_50DC7446 +#endif +#ifdef F_scePaf_0434 + IMPORT_FUNC "scePaf",0x36CB5601,scePaf_36CB5601 +#endif +#ifdef F_scePaf_0435 + IMPORT_FUNC "scePaf",0xBA32D6E6,scePaf_BA32D6E6 +#endif +#ifdef F_scePaf_0436 + IMPORT_FUNC "scePaf",0xEAB7BD23,scePaf_EAB7BD23 +#endif +#ifdef F_scePaf_0437 + IMPORT_FUNC "scePaf",0x669DE9B1,scePaf_669DE9B1 +#endif +#ifdef F_scePaf_0438 + IMPORT_FUNC "scePaf",0x940D9797,scePaf_940D9797 +#endif +#ifdef F_scePaf_0439 + IMPORT_FUNC "scePaf",0x4708AED4,scePaf_4708AED4 +#endif +#ifdef F_scePaf_0440 + IMPORT_FUNC "scePaf",0x32A70C80,scePaf_32A70C80 +#endif +#ifdef F_scePaf_0441 + IMPORT_FUNC "scePaf",0xCAF05F1D,scePaf_CAF05F1D +#endif +#ifdef F_scePaf_0442 + IMPORT_FUNC "scePaf",0x49CE42F7,scePaf_49CE42F7 +#endif +#ifdef F_scePaf_0443 + IMPORT_FUNC "scePaf",0xFC6B7234,scePaf_FC6B7234 +#endif +#ifdef F_scePaf_0444 + IMPORT_FUNC "scePaf",0x63B24F4D,scePaf_63B24F4D +#endif +#ifdef F_scePaf_0445 + IMPORT_FUNC "scePaf",0x6F33D1DF,scePaf_6F33D1DF +#endif +#ifdef F_scePaf_0446 + IMPORT_FUNC "scePaf",0x3481F595,scePaf_3481F595 +#endif +#ifdef F_scePaf_0447 + IMPORT_FUNC "scePaf",0x986FEBD1,scePaf_986FEBD1 +#endif +#ifdef F_scePaf_0448 + IMPORT_FUNC "scePaf",0x458A9C95,scePaf_458A9C95 +#endif +#ifdef F_scePaf_0449 + IMPORT_FUNC "scePaf",0xD3D12890,scePaf_D3D12890 +#endif +#ifdef F_scePaf_0450 + IMPORT_FUNC "scePaf",0x9D1633BC,scePaf_9D1633BC +#endif +#ifdef F_scePaf_0451 + IMPORT_FUNC "scePaf",0x98E1BC87,scePaf_98E1BC87 +#endif +#ifdef F_scePaf_0452 + IMPORT_FUNC "scePaf",0x84240C1D,scePaf_84240C1D +#endif +#ifdef F_scePaf_0453 + IMPORT_FUNC "scePaf",0x5D786CDD,scePaf_5D786CDD +#endif +#ifdef F_scePaf_0454 + IMPORT_FUNC "scePaf",0x6E95EFAA,scePaf_6E95EFAA +#endif +#ifdef F_scePaf_0455 + IMPORT_FUNC "scePaf",0x88D73AED,scePaf_88D73AED +#endif +#ifdef F_scePaf_0456 + IMPORT_FUNC "scePaf",0xD4FAE7D0,scePaf_D4FAE7D0 +#endif +#ifdef F_scePaf_0457 + IMPORT_FUNC "scePaf",0x338C3774,scePaf_338C3774 +#endif +#ifdef F_scePaf_0458 + IMPORT_FUNC "scePaf",0xDC2CA0F7,scePaf_DC2CA0F7 +#endif +#ifdef F_scePaf_0459 + IMPORT_FUNC "scePaf",0x7F7791A1,scePaf_7F7791A1 +#endif +#ifdef F_scePaf_0460 + IMPORT_FUNC "scePaf",0xF28A9DB3,scePaf_F28A9DB3 +#endif +#ifdef F_scePaf_0461 + IMPORT_FUNC "scePaf",0xBB3CBD19,scePaf_BB3CBD19 +#endif +#ifdef F_scePaf_0462 + IMPORT_FUNC "scePaf",0x27F64616,scePaf_27F64616 +#endif +#ifdef F_scePaf_0463 + IMPORT_FUNC "scePaf",0x72129CFB,scePaf_72129CFB +#endif +#ifdef F_scePaf_0464 + IMPORT_FUNC "scePaf",0xDAB59652,scePaf_DAB59652 +#endif +#ifdef F_scePaf_0465 + IMPORT_FUNC "scePaf",0x1A45C860,scePaf_1A45C860 +#endif +#ifdef F_scePaf_0466 + IMPORT_FUNC "scePaf",0xD7215544,scePaf_D7215544 +#endif +#ifdef F_scePaf_0467 + IMPORT_FUNC "scePaf",0x5DFB5858,scePaf_5DFB5858 +#endif +#ifdef F_scePaf_0468 + IMPORT_FUNC "scePaf",0x5EBC648F,scePaf_5EBC648F +#endif +#ifdef F_scePaf_0469 + IMPORT_FUNC "scePaf",0xF247A0BD,scePaf_F247A0BD +#endif +#ifdef F_scePaf_0470 + IMPORT_FUNC "scePaf",0x910A6B7B,scePaf_910A6B7B +#endif +#ifdef F_scePaf_0471 + IMPORT_FUNC "scePaf",0x5470B915,scePaf_5470B915 +#endif +#ifdef F_scePaf_0472 + IMPORT_FUNC "scePaf",0xD05C226F,scePaf_D05C226F +#endif +#ifdef F_scePaf_0473 + IMPORT_FUNC "scePaf",0xCE21D21F,scePaf_CE21D21F +#endif +#ifdef F_scePaf_0474 + IMPORT_FUNC "scePaf",0x8860B0FD,scePaf_8860B0FD +#endif +#ifdef F_scePaf_0475 + IMPORT_FUNC "scePaf",0x2AA842B0,scePaf_2AA842B0 +#endif +#ifdef F_scePaf_0476 + IMPORT_FUNC "scePaf",0xD5372E90,scePaf_D5372E90 +#endif +#ifdef F_scePaf_0477 + IMPORT_FUNC "scePaf",0xD7C2E0AD,scePaf_D7C2E0AD +#endif +#ifdef F_scePaf_0478 + IMPORT_FUNC "scePaf",0xF4AB3180,scePaf_F4AB3180 +#endif +#ifdef F_scePaf_0479 + IMPORT_FUNC "scePaf",0xEA026663,scePaf_EA026663 +#endif +#ifdef F_scePaf_0480 + IMPORT_FUNC "scePaf",0xF609FA81,scePaf_F609FA81 +#endif +#ifdef F_scePaf_0481 + IMPORT_FUNC "scePaf",0xBBDE1C17,scePaf_BBDE1C17 +#endif +#ifdef F_scePaf_0482 + IMPORT_FUNC "scePaf",0x8117E6C8,scePaf_8117E6C8 +#endif +#ifdef F_scePaf_0483 + IMPORT_FUNC "scePaf",0x1811AD32,scePaf_1811AD32 +#endif +#ifdef F_scePaf_0484 + IMPORT_FUNC "scePaf",0x6CE39EF8,scePaf_6CE39EF8 +#endif +#ifdef F_scePaf_0485 + IMPORT_FUNC "scePaf",0xB09203B0,scePaf_B09203B0 +#endif +#ifdef F_scePaf_0486 + IMPORT_FUNC "scePaf",0x58C69BDA,scePaf_58C69BDA +#endif +#ifdef F_scePaf_0487 + IMPORT_FUNC "scePaf",0xE32B3558,scePaf_E32B3558 +#endif +#ifdef F_scePaf_0488 + IMPORT_FUNC "scePaf",0x86237EB3,scePaf_86237EB3 +#endif +#ifdef F_scePaf_0489 + IMPORT_FUNC "scePaf",0xBEF9FF15,scePaf_BEF9FF15 +#endif +#ifdef F_scePaf_0490 + IMPORT_FUNC "scePaf",0xFE4D4112,scePaf_FE4D4112 +#endif +#ifdef F_scePaf_0491 + IMPORT_FUNC "scePaf",0xDAA609BB,scePaf_DAA609BB +#endif +#ifdef F_scePaf_0492 + IMPORT_FUNC "scePaf",0x69CA1A2D,scePaf_69CA1A2D +#endif +#ifdef F_scePaf_0493 + IMPORT_FUNC "scePaf",0xD3F5956D,scePaf_D3F5956D +#endif +#ifdef F_scePaf_0494 + IMPORT_FUNC "scePaf",0x602EB0CE,scePaf_602EB0CE +#endif +#ifdef F_scePaf_0495 + IMPORT_FUNC "scePaf",0x6A14BB04,scePaf_6A14BB04 +#endif +#ifdef F_scePaf_0496 + IMPORT_FUNC "scePaf",0x95960A88,scePaf_95960A88 +#endif +#ifdef F_scePaf_0497 + IMPORT_FUNC "scePaf",0xD6CD39AF,scePaf_D6CD39AF +#endif +#ifdef F_scePaf_0498 + IMPORT_FUNC "scePaf",0x79E57CAF,scePaf_79E57CAF +#endif +#ifdef F_scePaf_0499 + IMPORT_FUNC "scePaf",0x9DED6118,scePaf_9DED6118 +#endif +#ifdef F_scePaf_0500 + IMPORT_FUNC "scePaf",0x997D2809,scePaf_997D2809 +#endif +#ifdef F_scePaf_0501 + IMPORT_FUNC "scePaf",0x7D83FB20,scePaf_7D83FB20 +#endif +#ifdef F_scePaf_0502 + IMPORT_FUNC "scePaf",0xE1242646,scePaf_E1242646 +#endif +#ifdef F_scePaf_0503 + IMPORT_FUNC "scePaf",0x0F3527DD,scePaf_0F3527DD +#endif +#ifdef F_scePaf_0504 + IMPORT_FUNC "scePaf",0x10C1DB70,scePaf_10C1DB70 +#endif +#ifdef F_scePaf_0505 + IMPORT_FUNC "scePaf",0x39B36025,scePaf_39B36025 +#endif +#ifdef F_scePaf_0506 + IMPORT_FUNC "scePaf",0x01C2FC36,scePaf_01C2FC36 +#endif +#ifdef F_scePaf_0507 + IMPORT_FUNC "scePaf",0x17308FC9,scePaf_17308FC9 +#endif +#ifdef F_scePaf_0508 + IMPORT_FUNC "scePaf",0xF3967AF5,scePaf_F3967AF5 +#endif +#ifdef F_scePaf_0509 + IMPORT_FUNC "scePaf",0x34C973B6,scePaf_34C973B6 +#endif +#ifdef F_scePaf_0510 + IMPORT_FUNC "scePaf",0x4C8C2E25,scePaf_4C8C2E25 +#endif +#ifdef F_scePaf_0511 + IMPORT_FUNC "scePaf",0x81FD71A9,scePaf_81FD71A9 +#endif +#ifdef F_scePaf_0512 + IMPORT_FUNC "scePaf",0xBBBF145C,scePaf_BBBF145C +#endif +#ifdef F_scePaf_0513 + IMPORT_FUNC "scePaf",0xB52E43FB,scePaf_B52E43FB +#endif +#ifdef F_scePaf_0514 + IMPORT_FUNC "scePaf",0x95C97571,scePaf_95C97571 +#endif +#ifdef F_scePaf_0515 + IMPORT_FUNC "scePaf",0xF273FE50,scePaf_F273FE50 +#endif +#ifdef F_scePaf_0516 + IMPORT_FUNC "scePaf",0xAD7A45F9,scePaf_AD7A45F9 +#endif +#ifdef F_scePaf_0517 + IMPORT_FUNC "scePaf",0x67C7567E,scePaf_67C7567E +#endif +#ifdef F_scePaf_0518 + IMPORT_FUNC "scePaf",0x56F4D69F,scePaf_56F4D69F +#endif +#ifdef F_scePaf_0519 + IMPORT_FUNC "scePaf",0xD7E925A1,scePaf_D7E925A1 +#endif +#ifdef F_scePaf_0520 + IMPORT_FUNC "scePaf",0x296ED0EF,scePaf_296ED0EF +#endif +#ifdef F_scePaf_0521 + IMPORT_FUNC "scePaf",0xDBD69B7B,scePaf_DBD69B7B +#endif +#ifdef F_scePaf_0522 + IMPORT_FUNC "scePaf",0x7DDE0658,scePaf_7DDE0658 +#endif +#ifdef F_scePaf_0523 + IMPORT_FUNC "scePaf",0xCC3CFABF,scePaf_CC3CFABF +#endif +#ifdef F_scePaf_0524 + IMPORT_FUNC "scePaf",0xD2C94856,scePaf_D2C94856 +#endif +#ifdef F_scePaf_0525 + IMPORT_FUNC "scePaf",0xEF346632,scePaf_EF346632 +#endif +#ifdef F_scePaf_0526 + IMPORT_FUNC "scePaf",0x79293604,scePaf_79293604 +#endif +#ifdef F_scePaf_0527 + IMPORT_FUNC "scePaf",0xAECF91A9,scePaf_AECF91A9 +#endif +#ifdef F_scePaf_0528 + IMPORT_FUNC "scePaf",0x3342C5F5,scePaf_3342C5F5 +#endif +#ifdef F_scePaf_0529 + IMPORT_FUNC "scePaf",0x48B5C1C0,scePaf_48B5C1C0 +#endif +#ifdef F_scePaf_0530 + IMPORT_FUNC "scePaf",0xD188831A,scePaf_D188831A +#endif +#ifdef F_scePaf_0531 + IMPORT_FUNC "scePaf",0x2D08CA09,scePaf_2D08CA09 +#endif +#ifdef F_scePaf_0532 + IMPORT_FUNC "scePaf",0x55C7628A,scePaf_55C7628A +#endif +#ifdef F_scePaf_0533 + IMPORT_FUNC "scePaf",0xA9CE8FBB,scePaf_A9CE8FBB +#endif +#ifdef F_scePaf_0534 + IMPORT_FUNC "scePaf",0xD6F088EF,scePaf_D6F088EF +#endif +#ifdef F_scePaf_0535 + IMPORT_FUNC "scePaf",0xF2E5FDEB,scePaf_F2E5FDEB +#endif +#ifdef F_scePaf_0536 + IMPORT_FUNC "scePaf",0x6E3E2085,scePaf_6E3E2085 +#endif +#ifdef F_scePaf_0537 + IMPORT_FUNC "scePaf",0x6676FAA6,scePaf_6676FAA6 +#endif +#ifdef F_scePaf_0538 + IMPORT_FUNC "scePaf",0x7D9A4824,scePaf_7D9A4824 +#endif +#ifdef F_scePaf_0539 + IMPORT_FUNC "scePaf",0xD8739C4C,scePaf_D8739C4C +#endif +#ifdef F_scePaf_0540 + IMPORT_FUNC "scePaf",0x34C7D69A,scePaf_34C7D69A +#endif +#ifdef F_scePaf_0541 + IMPORT_FUNC "scePaf",0xCDB85442,scePaf_CDB85442 +#endif +#ifdef F_scePaf_0542 + IMPORT_FUNC "scePaf",0xDFD3E855,scePaf_DFD3E855 +#endif +#ifdef F_scePaf_0543 + IMPORT_FUNC "scePaf",0x2AA80564,scePaf_2AA80564 +#endif +#ifdef F_scePaf_0544 + IMPORT_FUNC "scePaf",0x6BAC756B,scePaf_6BAC756B +#endif +#ifdef F_scePaf_0545 + IMPORT_FUNC "scePaf",0x3A844B7B,scePaf_3A844B7B +#endif +#ifdef F_scePaf_0546 + IMPORT_FUNC "scePaf",0x9B8CBC5F,scePaf_9B8CBC5F +#endif +#ifdef F_scePaf_0547 + IMPORT_FUNC "scePaf",0xBE5B0791,scePaf_BE5B0791 +#endif +#ifdef F_scePaf_0548 + IMPORT_FUNC "scePaf",0xFCD816FA,scePaf_FCD816FA +#endif +#ifdef F_scePaf_0549 + IMPORT_FUNC "scePaf",0x548AA4E7,scePaf_548AA4E7 +#endif +#ifdef F_scePaf_0550 + IMPORT_FUNC "scePaf",0x21A0C6E0,scePaf_21A0C6E0 +#endif +#ifdef F_scePaf_0551 + IMPORT_FUNC "scePaf",0xC01BF169,scePaf_C01BF169 +#endif +#ifdef F_scePaf_0552 + IMPORT_FUNC "scePaf",0xAD1721B8,scePaf_AD1721B8 +#endif +#ifdef F_scePaf_0553 + IMPORT_FUNC "scePaf",0x910BCFE1,scePaf_910BCFE1 +#endif +#ifdef F_scePaf_0554 + IMPORT_FUNC "scePaf",0x75DBA857,scePaf_75DBA857 +#endif +#ifdef F_scePaf_0555 + IMPORT_FUNC "scePaf",0x849ED670,scePaf_849ED670 +#endif +#ifdef F_scePaf_0556 + IMPORT_FUNC "scePaf",0x5148EFE2,scePaf_5148EFE2 +#endif +#ifdef F_scePaf_0557 + IMPORT_FUNC "scePaf",0xD36F3AAA,scePaf_D36F3AAA +#endif +#ifdef F_scePaf_0558 + IMPORT_FUNC "scePaf",0x1A468B86,scePaf_1A468B86 +#endif +#ifdef F_scePaf_0559 + IMPORT_FUNC "scePaf",0x8E757709,scePaf_8E757709 +#endif +#ifdef F_scePaf_0560 + IMPORT_FUNC "scePaf",0x7BBD70F0,scePaf_7BBD70F0 +#endif +#ifdef F_scePaf_0561 + IMPORT_FUNC "scePaf",0xDFFE9ED6,scePaf_DFFE9ED6 +#endif +#ifdef F_scePaf_0562 + IMPORT_FUNC "scePaf",0x72A0044D,scePaf_72A0044D +#endif +#ifdef F_scePaf_0563 + IMPORT_FUNC "scePaf",0x4612DB4B,scePaf_4612DB4B +#endif +#ifdef F_scePaf_0564 + IMPORT_FUNC "scePaf",0x78219D10,scePaf_78219D10 +#endif +#ifdef F_scePaf_0565 + IMPORT_FUNC "scePaf",0x97FDA760,scePaf_97FDA760 +#endif +#ifdef F_scePaf_0566 + IMPORT_FUNC "scePaf",0x298246CD,scePaf_298246CD +#endif +#ifdef F_scePaf_0567 + IMPORT_FUNC "scePaf",0x12C50A9D,scePaf_12C50A9D +#endif +#ifdef F_scePaf_0568 + IMPORT_FUNC "scePaf",0x3D451DE8,scePaf_3D451DE8 +#endif +#ifdef F_scePaf_0569 + IMPORT_FUNC "scePaf",0x8FE88010,scePaf_8FE88010 +#endif +#ifdef F_scePaf_0570 + IMPORT_FUNC "scePaf",0x21A183A7,scePaf_21A183A7 +#endif +#ifdef F_scePaf_0571 + IMPORT_FUNC "scePaf",0xABEBF18D,scePaf_ABEBF18D +#endif +#ifdef F_scePaf_0572 + IMPORT_FUNC "scePaf",0x94136997,scePaf_94136997 +#endif +#ifdef F_scePaf_0573 + IMPORT_FUNC "scePaf",0xA25BDAA2,scePaf_A25BDAA2 +#endif +#ifdef F_scePaf_0574 + IMPORT_FUNC "scePaf",0x9F60CB01,scePaf_9F60CB01 +#endif +#ifdef F_scePaf_0575 + IMPORT_FUNC "scePaf",0x50B0C0A1,scePaf_50B0C0A1 +#endif +#ifdef F_scePaf_0576 + IMPORT_FUNC "scePaf",0x7E304DCF,scePaf_7E304DCF +#endif +#ifdef F_scePaf_0577 + IMPORT_FUNC "scePaf",0x1F43B8A2,scePaf_1F43B8A2 +#endif +#ifdef F_scePaf_0578 + IMPORT_FUNC "scePaf",0x891B7F7F,scePaf_891B7F7F +#endif +#ifdef F_scePaf_0579 + IMPORT_FUNC "scePaf",0x14D80C40,scePaf_14D80C40 +#endif +#ifdef F_scePaf_0580 + IMPORT_FUNC "scePaf",0x87E5F9C7,scePaf_87E5F9C7 +#endif +#ifdef F_scePaf_0581 + IMPORT_FUNC "scePaf",0xD3AB4076,scePaf_D3AB4076 +#endif +#ifdef F_scePaf_0582 + IMPORT_FUNC "scePaf",0x537D04C6,scePaf_537D04C6 +#endif +#ifdef F_scePaf_0583 + IMPORT_FUNC "scePaf",0x7AFD6B74,png_create_info_struct +#endif +#ifdef F_scePaf_0584 + IMPORT_FUNC "scePaf",0x6528115D,png_create_read_struct +#endif +#ifdef F_scePaf_0585 + IMPORT_FUNC "scePaf",0x211A764A,png_destroy_read_struct +#endif +#ifdef F_scePaf_0586 + IMPORT_FUNC "scePaf",0x7894B61F,png_error +#endif +#ifdef F_scePaf_0587 + IMPORT_FUNC "scePaf",0x38F12307,png_get_IHDR +#endif +#ifdef F_scePaf_0588 + IMPORT_FUNC "scePaf",0xE6432407,png_get_PLTE +#endif +#ifdef F_scePaf_0589 + IMPORT_FUNC "scePaf",0x07216006,png_get_tRNS +#endif +#ifdef F_scePaf_0590 + IMPORT_FUNC "scePaf",0xB2290D1A,png_read_end +#endif +#ifdef F_scePaf_0591 + IMPORT_FUNC "scePaf",0xE327C974,png_read_info +#endif +#ifdef F_scePaf_0592 + IMPORT_FUNC "scePaf",0x1BDFF258,png_set_read_fn +#endif +#ifdef F_scePaf_0593 + IMPORT_FUNC "scePaf",0xDB1549DF,png_start_read_image +#endif +#ifdef F_scePaf_0594 + IMPORT_FUNC "scePaf",0xDDD91620,png_read_image +#endif +#ifdef F_scePaf_0595 + IMPORT_FUNC "scePaf",0xD4F9270D,png_read_update_info +#endif +#ifdef F_scePaf_0596 + IMPORT_FUNC "scePaf",0x7333E75A,png_set_packing +#endif +#ifdef F_scePaf_0597 + IMPORT_FUNC "scePaf",0x1A1F232F,png_set_sig_bytes +#endif +#ifdef F_scePaf_0598 + IMPORT_FUNC "scePaf",0xC6624F24,png_set_packswap +#endif +#ifdef F_scePaf_0599 + IMPORT_FUNC "scePaf",0xFBC76D05,sce_png_read +#endif +#ifdef F_scePaf_0600 + IMPORT_FUNC "scePaf",0xC6A8BEE2,scePaf_C6A8BEE2 +#endif +#ifdef F_scePaf_0601 + IMPORT_FUNC "scePaf",0x8406F469,scePaf_8406F469 +#endif +#ifdef F_scePaf_0602 + IMPORT_FUNC "scePaf",0xB4D1CBBF,scePaf_B4D1CBBF +#endif +#ifdef F_scePaf_0603 + IMPORT_FUNC "scePaf",0x8D3EAEA3,scePaf_8D3EAEA3 +#endif +#ifdef F_scePaf_0604 + IMPORT_FUNC "scePaf",0xC8E7B03F,scePaf_C8E7B03F +#endif +#ifdef F_scePaf_0605 + IMPORT_FUNC "scePaf",0xD4DAB044,scePaf_D4DAB044 +#endif +#ifdef F_scePaf_0606 + IMPORT_FUNC "scePaf",0x15939BB8,scePaf_15939BB8 +#endif +#ifdef F_scePaf_0607 + IMPORT_FUNC "scePaf",0x8D736C8F,scePaf_8D736C8F +#endif +#ifdef F_scePaf_0608 + IMPORT_FUNC "scePaf",0xE0CF8091,scePaf_E0CF8091 +#endif +#ifdef F_scePaf_0609 + IMPORT_FUNC "scePaf",0xBEB47224,scePaf_BEB47224 +#endif +#ifdef F_scePaf_0610 + IMPORT_FUNC "scePaf",0xD9392CCB,scePaf_D9392CCB +#endif +#ifdef F_scePaf_0611 + IMPORT_FUNC "scePaf",0xF1B73D12,scePaf_F1B73D12 +#endif +#ifdef F_scePaf_0612 + IMPORT_FUNC "scePaf",0x00D1378F,scePaf_00D1378F +#endif +#ifdef F_scePaf_0613 + IMPORT_FUNC "scePaf",0xD6CDB3BB,scePaf_D6CDB3BB +#endif +#ifdef F_scePaf_0614 + IMPORT_FUNC "scePaf",0x60CBB63F,scePaf_60CBB63F +#endif +#ifdef F_scePaf_0615 + IMPORT_FUNC "scePaf",0xF93D4E1F,scePaf_F93D4E1F +#endif +#ifdef F_scePaf_0616 + IMPORT_FUNC "scePaf",0xB9383A25,scePaf_B9383A25 +#endif +#ifdef F_scePaf_0617 + IMPORT_FUNC "scePaf",0xB7D3C112,scePaf_B7D3C112 +#endif +#ifdef F_scePaf_0618 + IMPORT_FUNC "scePaf",0x4BDEB2A8,scePaf_4BDEB2A8 +#endif +#ifdef F_scePaf_0619 + IMPORT_FUNC "scePaf",0x41B724A5,scePaf_41B724A5 +#endif +#ifdef F_scePaf_0620 + IMPORT_FUNC "scePaf",0xD5F3BAB1,scePaf_D5F3BAB1 +#endif +#ifdef F_scePaf_0621 + IMPORT_FUNC "scePaf",0xEA39A7C1,scePaf_EA39A7C1 +#endif +#ifdef F_scePaf_0622 + IMPORT_FUNC "scePaf",0x6B1E90C7,scePaf_6B1E90C7 +#endif +#ifdef F_scePaf_0623 + IMPORT_FUNC "scePaf",0x66907719,scePaf_66907719 +#endif +#ifdef F_scePaf_0624 + IMPORT_FUNC "scePaf",0xAAD0EE78,scePaf_AAD0EE78 +#endif +#ifdef F_scePaf_0625 + IMPORT_FUNC "scePaf",0xE69C3B1B,scePaf_E69C3B1B +#endif +#ifdef F_scePaf_0626 + IMPORT_FUNC "scePaf",0xE618F7A8,scePaf_E618F7A8 +#endif +#ifdef F_scePaf_0627 + IMPORT_FUNC "scePaf",0x78F94D84,scePaf_78F94D84 +#endif +#ifdef F_scePaf_0628 + IMPORT_FUNC "scePaf",0x5822F12A,scePaf_5822F12A +#endif +#ifdef F_scePaf_0629 + IMPORT_FUNC "scePaf",0xFD9DE7B9,scePaf_FD9DE7B9 +#endif +#ifdef F_scePaf_0630 + IMPORT_FUNC "scePaf",0xAD43F865,scePaf_AD43F865 +#endif +#ifdef F_scePaf_0631 + IMPORT_FUNC "scePaf",0x872F948B,scePaf_872F948B +#endif +#ifdef F_scePaf_0632 + IMPORT_FUNC "scePaf",0xD726F4A2,scePaf_D726F4A2 +#endif +#ifdef F_scePaf_0633 + IMPORT_FUNC "scePaf",0xA044BFC0,scePaf_A044BFC0 +#endif +#ifdef F_scePaf_0634 + IMPORT_FUNC "scePaf",0xF1CF9579,scePaf_F1CF9579 +#endif +#ifdef F_scePaf_0635 + IMPORT_FUNC "scePaf",0x132148FD,scePaf_132148FD +#endif +#ifdef F_scePaf_0636 + IMPORT_FUNC "scePaf",0x533F3856,scePaf_533F3856 +#endif +#ifdef F_scePaf_0637 + IMPORT_FUNC "scePaf",0x139D9047,scePaf_139D9047 +#endif +#ifdef F_scePaf_0638 + IMPORT_FUNC "scePaf",0x8D3B3587,scePaf_8D3B3587 +#endif +#ifdef F_scePaf_0639 + IMPORT_FUNC "scePaf",0x27760582,scePaf_27760582 +#endif +#ifdef F_scePaf_0640 + IMPORT_FUNC "scePaf",0xFD3FF4AA,scePaf_FD3FF4AA +#endif +#ifdef F_scePaf_0641 + IMPORT_FUNC "scePaf",0xA0ED77C4,scePaf_A0ED77C4 +#endif +#ifdef F_scePaf_0642 + IMPORT_FUNC "scePaf",0x35F25BA1,scePaf_35F25BA1 +#endif +#ifdef F_scePaf_0643 + IMPORT_FUNC "scePaf",0x75062BCF,scePaf_75062BCF +#endif +#ifdef F_scePaf_0644 + IMPORT_FUNC "scePaf",0x79493F8F,scePaf_79493F8F +#endif +#ifdef F_scePaf_0645 + IMPORT_FUNC "scePaf",0x3E203AEB,Heap_Alloc +#endif +#ifdef F_scePaf_0646 + IMPORT_FUNC "scePaf",0x9948CDB3,Heap_Free +#endif +#ifdef F_scePaf_0647 + IMPORT_FUNC "scePaf",0xF84A99C8,scePaf_F84A99C8 +#endif +#ifdef F_scePaf_0648 + IMPORT_FUNC "scePaf",0x6D491648,Heap_Create +#endif +#ifdef F_scePaf_0649 + IMPORT_FUNC "scePaf",0x8A861692,Heap_Destroy +#endif +#ifdef F_scePaf_0650 + IMPORT_FUNC "scePaf",0xC4BAD564,scePaf_C4BAD564 +#endif +#ifdef F_scePaf_0651 + IMPORT_FUNC "scePaf",0xD27DE19A,scePaf_D27DE19A +#endif +#ifdef F_scePaf_0652 + IMPORT_FUNC "scePaf",0xBAE16A39,scePaf_BAE16A39 +#endif +#ifdef F_scePaf_0653 + IMPORT_FUNC "scePaf",0x2CFAE498,scePaf_2CFAE498 +#endif +#ifdef F_scePaf_0654 + IMPORT_FUNC "scePaf",0x58846DF3,scePaf_58846DF3 +#endif +#ifdef F_scePaf_0655 + IMPORT_FUNC "scePaf",0xE357380E,scePaf_E357380E +#endif +#ifdef F_scePaf_0656 + IMPORT_FUNC "scePaf",0x4B4F39FC,scePaf_4B4F39FC +#endif +#ifdef F_scePaf_0657 + IMPORT_FUNC "scePaf",0x5C5F727C,scePaf_5C5F727C +#endif +#ifdef F_scePaf_0658 + IMPORT_FUNC "scePaf",0x0F2615A4,scePaf_0F2615A4 +#endif +#ifdef F_scePaf_0659 + IMPORT_FUNC "scePaf",0xEA4C24B3,scePaf_EA4C24B3 +#endif +#ifdef F_scePaf_0660 + IMPORT_FUNC "scePaf",0x28C54317,scePaf_28C54317 +#endif +#ifdef F_scePaf_0661 + IMPORT_FUNC "scePaf",0xCBA9AAB1,scePaf_CBA9AAB1 +#endif +#ifdef F_scePaf_0662 + IMPORT_FUNC "scePaf",0x2C5D3E63,scePaf_2C5D3E63 +#endif +#ifdef F_scePaf_0663 + IMPORT_FUNC "scePaf",0x38316A7D,scePaf_38316A7D +#endif +#ifdef F_scePaf_0664 + IMPORT_FUNC "scePaf",0x96610AE6,scePaf_96610AE6 +#endif +#ifdef F_scePaf_0665 + IMPORT_FUNC "scePaf",0xA08B0F31,scePaf_A08B0F31 +#endif +#ifdef F_scePaf_0666 + IMPORT_FUNC "scePaf",0xFB3DB2FF,paf_fini +#endif +#ifdef F_scePaf_0667 + IMPORT_FUNC "scePaf",0xE13B6DAE,sinf +#endif +#ifdef F_scePaf_0668 + IMPORT_FUNC "scePaf",0xEB6D20A5,cosf +#endif +#ifdef F_scePaf_0669 + IMPORT_FUNC "scePaf",0x09F5941E,sqrtf +#endif +#ifdef F_scePaf_0670 + IMPORT_FUNC "scePaf",0x481C9ADA,malloc +#endif +#ifdef F_scePaf_0671 + IMPORT_FUNC "scePaf",0xAD8AF84F,free +#endif +#ifdef F_scePaf_0672 + IMPORT_FUNC "scePaf",0xAB7592FF,memcpy +#endif +#ifdef F_scePaf_0673 + IMPORT_FUNC "scePaf",0x10F3BB61,memset +#endif +#ifdef F_scePaf_0674 + IMPORT_FUNC "scePaf",0x81D0D1F7,memcpy +#endif +#ifdef F_scePaf_0675 + IMPORT_FUNC "scePaf",0x7EDCC45E,floorf +#endif +#ifdef F_scePaf_0676 + IMPORT_FUNC "scePaf",0x820C80E6,acosf +#endif +#ifdef F_scePaf_0677 + IMPORT_FUNC "scePaf",0xCAB439DF,printf +#endif diff --git a/src/vsh/sceVshBridge.S b/src/vsh/sceVshBridge.S new file mode 100644 index 00000000..e7e3b132 --- /dev/null +++ b/src/vsh/sceVshBridge.S @@ -0,0 +1,205 @@ + .set noreorder + +#include "pspimport.s" + +// Build List +// sceVshBridge_0000.o sceVshBridge_0001.o sceVshBridge_0002.o sceVshBridge_0003.o sceVshBridge_0004.o sceVshBridge_0005.o sceVshBridge_0006.o sceVshBridge_0007.o sceVshBridge_0008.o sceVshBridge_0009.o sceVshBridge_0010.o sceVshBridge_0011.o sceVshBridge_0012.o sceVshBridge_0013.o sceVshBridge_0014.o sceVshBridge_0015.o sceVshBridge_0016.o sceVshBridge_0017.o sceVshBridge_0018.o sceVshBridge_0019.o sceVshBridge_0020.o sceVshBridge_0021.o sceVshBridge_0022.o sceVshBridge_0023.o sceVshBridge_0024.o sceVshBridge_0025.o sceVshBridge_0026.o sceVshBridge_0027.o sceVshBridge_0028.o sceVshBridge_0029.o sceVshBridge_0030.o sceVshBridge_0031.o sceVshBridge_0032.o sceVshBridge_0033.o sceVshBridge_0034.o sceVshBridge_0035.o sceVshBridge_0036.o sceVshBridge_0037.o sceVshBridge_0038.o sceVshBridge_0039.o sceVshBridge_0040.o sceVshBridge_0041.o sceVshBridge_0042.o sceVshBridge_0043.o sceVshBridge_0044.o sceVshBridge_0045.o sceVshBridge_0046.o sceVshBridge_0047.o sceVshBridge_0048.o sceVshBridge_0049.o sceVshBridge_0050.o sceVshBridge_0051.o sceVshBridge_0052.o sceVshBridge_0053.o sceVshBridge_0054.o sceVshBridge_0055.o sceVshBridge_0056.o sceVshBridge_0057.o sceVshBridge_0058.o sceVshBridge_0059.o sceVshBridge_0060.o sceVshBridge_0061.o sceVshBridge_0062.o sceVshBridge_0063.o sceVshBridge_0064.o sceVshBridge_0065.o + +#ifdef F_sceVshBridge_0000 + IMPORT_START "sceVshBridge",0x40010000 +#endif +#ifdef F_sceVshBridge_0001 + IMPORT_FUNC "sceVshBridge",0xA5628F0D,vshKernelLoadModuleVSH +#endif +#ifdef F_sceVshBridge_0002 + IMPORT_FUNC "sceVshBridge",0x41C54ADF,vshKernelLoadModuleVSHByID +#endif +#ifdef F_sceVshBridge_0003 + IMPORT_FUNC "sceVshBridge",0xC9626587,vshKernelLoadModuleBufferVSH +#endif +#ifdef F_sceVshBridge_0004 + IMPORT_FUNC "sceVshBridge",0x5C2983C2,sceVshBridge_5C2983C2 +#endif +#ifdef F_sceVshBridge_0005 + IMPORT_FUNC "sceVshBridge",0xC949966C,sceVshBridge_C949966C +#endif +#ifdef F_sceVshBridge_0006 + IMPORT_FUNC "sceVshBridge",0xC6395C03,vshCtrlReadBufferPositive +#endif +#ifdef F_sceVshBridge_0007 + IMPORT_FUNC "sceVshBridge",0x0163A8E7,vshUmdManTerm +#endif +#ifdef F_sceVshBridge_0008 + IMPORT_FUNC "sceVshBridge",0x7C1658F2,sceVshBridge_7C1658F2 +#endif +#ifdef F_sceVshBridge_0009 + IMPORT_FUNC "sceVshBridge",0x0E10922A,vshDisplaySetHoldMode +#endif +#ifdef F_sceVshBridge_0010 + IMPORT_FUNC "sceVshBridge",0xCA719C34,vshImposeGetStatus +#endif +#ifdef F_sceVshBridge_0011 + IMPORT_FUNC "sceVshBridge",0x4E4E4DA3,vshImposeSetStatus +#endif +#ifdef F_sceVshBridge_0012 + IMPORT_FUNC "sceVshBridge",0x639C3CB3,vshImposeGetParam +#endif +#ifdef F_sceVshBridge_0013 + IMPORT_FUNC "sceVshBridge",0x4A596D2D,vshImposeSetParam +#endif +#ifdef F_sceVshBridge_0014 + IMPORT_FUNC "sceVshBridge",0x5894C339,vshImposeChanges +#endif +#ifdef F_sceVshBridge_0015 + IMPORT_FUNC "sceVshBridge",0x0FA48729,vshRtcSetConf +#endif +#ifdef F_sceVshBridge_0016 + IMPORT_FUNC "sceVshBridge",0x16415246,vshRtcSetCurrentTick +#endif +#ifdef F_sceVshBridge_0017 + IMPORT_FUNC "sceVshBridge",0x5350C073,vshMSAudioFormatICV +#endif +#ifdef F_sceVshBridge_0018 + IMPORT_FUNC "sceVshBridge",0x2380DC08,vshIoDevctl +#endif +#ifdef F_sceVshBridge_0019 + IMPORT_FUNC "sceVshBridge",0x4DB43867,vshIdStorageLookup +#endif +#ifdef F_sceVshBridge_0020 + IMPORT_FUNC "sceVshBridge",0x7B67394E,vshAudioSetFrequency +#endif +#ifdef F_sceVshBridge_0021 + IMPORT_FUNC "sceVshBridge",0xCE32CBEF,vshMSAudioInit +#endif +#ifdef F_sceVshBridge_0022 + IMPORT_FUNC "sceVshBridge",0xE5DA5E95,vshMSAudioEnd +#endif +#ifdef F_sceVshBridge_0023 + IMPORT_FUNC "sceVshBridge",0x6CAEB765,vshMSAudioAuth +#endif +#ifdef F_sceVshBridge_0024 + IMPORT_FUNC "sceVshBridge",0x53BFD101,vshMSAudioCheckICV +#endif +#ifdef F_sceVshBridge_0025 + IMPORT_FUNC "sceVshBridge",0xE174218C,sceVshBridge_E174218C +#endif +#ifdef F_sceVshBridge_0026 + IMPORT_FUNC "sceVshBridge",0x7EA32357,vshMSAudioDeauth +#endif +#ifdef F_sceVshBridge_0027 + IMPORT_FUNC "sceVshBridge",0x14877197,sceVshBridge_14877197 +#endif +#ifdef F_sceVshBridge_0028 + IMPORT_FUNC "sceVshBridge",0x5BBB35E4,sceVshBridge_5BBB35E4 +#endif +#ifdef F_sceVshBridge_0029 + IMPORT_FUNC "sceVshBridge",0xB27C593F,sceVshBridge_B27C593F +#endif +#ifdef F_sceVshBridge_0030 + IMPORT_FUNC "sceVshBridge",0x0D2CEAD2,sceVshBridge_0D2CEAD2 +#endif +#ifdef F_sceVshBridge_0031 + IMPORT_FUNC "sceVshBridge",0xD120667D,sceVshBridge_D120667D +#endif +#ifdef F_sceVshBridge_0032 + IMPORT_FUNC "sceVshBridge",0xD907B6AA,sceVshBridge_D907B6AA +#endif +#ifdef F_sceVshBridge_0033 + IMPORT_FUNC "sceVshBridge",0xD46D4528,vshMSAudioInvalidateICV +#endif +#ifdef F_sceVshBridge_0034 + IMPORT_FUNC "sceVshBridge",0x7A63BE73,sceVshBridge_7A63BE73 +#endif +#ifdef F_sceVshBridge_0035 + IMPORT_FUNC "sceVshBridge",0x222A18C4,sceVshBridge_222A18C4 +#endif +#ifdef F_sceVshBridge_0036 + IMPORT_FUNC "sceVshBridge",0x04310D7C,sceVshBridge_04310D7C +#endif +#ifdef F_sceVshBridge_0037 + IMPORT_FUNC "sceVshBridge",0x4E61C72E,sceVshBridge_4E61C72E +#endif +#ifdef F_sceVshBridge_0038 + IMPORT_FUNC "sceVshBridge",0xE2DD0A81,vshMSAudioGetInitialEKB +#endif +#ifdef F_sceVshBridge_0039 + IMPORT_FUNC "sceVshBridge",0x6396ACBD,vshMSAudioGetICVInfo +#endif +#ifdef F_sceVshBridge_0040 + IMPORT_FUNC "sceVshBridge",0x274BB6AE,vshVaudioOutputBlocking +#endif +#ifdef F_sceVshBridge_0041 + IMPORT_FUNC "sceVshBridge",0x8C440581,vshVaudioChReserve +#endif +#ifdef F_sceVshBridge_0042 + IMPORT_FUNC "sceVshBridge",0x07EC5661,vshVaudioChRelease +#endif +#ifdef F_sceVshBridge_0043 + IMPORT_FUNC "sceVshBridge",0x3B3D9F5D,sceVshBridge_3B3D9F5D +#endif +#ifdef F_sceVshBridge_0044 + IMPORT_FUNC "sceVshBridge",0xB7F233A2,sceVshBridge_B7F233A2 +#endif +#ifdef F_sceVshBridge_0045 + IMPORT_FUNC "sceVshBridge",0xC58D0939,sceVshBridge_C58D0939 +#endif +#ifdef F_sceVshBridge_0046 + IMPORT_FUNC "sceVshBridge",0xCBDA2613,vshMeRpcLock +#endif +#ifdef F_sceVshBridge_0047 + IMPORT_FUNC "sceVshBridge",0xA7F0E8E0,vshMeRpcUnlock +#endif +#ifdef F_sceVshBridge_0048 + IMPORT_FUNC "sceVshBridge",0x98B4117E,vshKernelLoadExecBufferPlain0 +#endif +#ifdef F_sceVshBridge_0049 + IMPORT_FUNC "sceVshBridge",0x8399A8AA,vshKernelLoadExecBufferPlain +#endif +#ifdef F_sceVshBridge_0050 + IMPORT_FUNC "sceVshBridge",0xE614F45F,vshKernelLoadExecFromHost +#endif +#ifdef F_sceVshBridge_0051 + IMPORT_FUNC "sceVshBridge",0xEEFB02BB,vshKernelLoadExec +#endif +#ifdef F_sceVshBridge_0052 + IMPORT_FUNC "sceVshBridge",0x9929DDA5,vshKernelExitVSH +#endif +#ifdef F_sceVshBridge_0053 + IMPORT_FUNC "sceVshBridge",0xB7C46DCA,vshKernelLoadExecVSHDiscUpdater +#endif +#ifdef F_sceVshBridge_0054 + IMPORT_FUNC "sceVshBridge",0x04AEC74C,vshKernelLoadExecVSHDiscDebug +#endif +#ifdef F_sceVshBridge_0055 + IMPORT_FUNC "sceVshBridge",0xF4873F4D,sceVshBridge_F4873F4D +#endif +#ifdef F_sceVshBridge_0056 + IMPORT_FUNC "sceVshBridge",0x83528906,vshKernelLoadExecBufferVSHUsbWlan +#endif +#ifdef F_sceVshBridge_0057 + IMPORT_FUNC "sceVshBridge",0x68BE3316,vshKernelLoadExecBufferVSHUsbWlanDebug +#endif +#ifdef F_sceVshBridge_0058 + IMPORT_FUNC "sceVshBridge",0xF35BFB7D,vshKernelLoadExecVSHMs1 +#endif +#ifdef F_sceVshBridge_0059 + IMPORT_FUNC "sceVshBridge",0x97FB006F,vshKernelLoadExecVSHMs2 +#endif +#ifdef F_sceVshBridge_0060 + IMPORT_FUNC "sceVshBridge",0x029EF6C9,vshKernelLoadExecVSHMs3 +#endif +#ifdef F_sceVshBridge_0061 + IMPORT_FUNC "sceVshBridge",0x40716012,vshKernelExitVSHVSH +#endif +#ifdef F_sceVshBridge_0062 + IMPORT_FUNC "sceVshBridge",0x88DA81A5,vshKernelLoadExecBufferVSHPlain +#endif +#ifdef F_sceVshBridge_0063 + IMPORT_FUNC "sceVshBridge",0x88BD8364,vshKernelLoadExecBufferVSHFromHost +#endif +#ifdef F_sceVshBridge_0064 + IMPORT_FUNC "sceVshBridge",0x74DA9D25,vshLflashFatfmtStartFatfmt +#endif +#ifdef F_sceVshBridge_0065 + IMPORT_FUNC "sceVshBridge",0x61001D64,vshChkregGetPsCode +#endif diff --git a/src/wlan/Makefile.am b/src/wlan/Makefile.am new file mode 100644 index 00000000..7bacce63 --- /dev/null +++ b/src/wlan/Makefile.am @@ -0,0 +1,27 @@ + +libdir = @PSPSDK_LIBDIR@ + +CC = @PSP_CC@ +CCAS = $(CC) +AR = @PSP_AR@ +RANLIB = @PSP_RANLIB@ + +INCLUDES = -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel +CFLAGS = @PSPSDK_CFLAGS@ +CCASFLAGS = $(CFLAGS) -I$(top_srcdir)/src/base -I$(top_srcdir)/src/kernel + +WLAN_OBJS = sceWlanDrv_0000.o sceWlanDrv_0001.o sceWlanDrv_0002.o sceWlanDrv_0003.o +WLANLIB_OBJS = sceWlanDrv_lib_0000.o sceWlanDrv_lib_0001.o sceWlanDrv_lib_0002.o sceWlanDrv_lib_0003.o sceWlanDrv_lib_0004.o sceWlanDrv_lib_0005.o sceWlanDrv_lib_0006.o sceWlanDrv_lib_0007.o sceWlanDrv_lib_0008.o sceWlanDrv_lib_0009.o sceWlanDrv_lib_0010.o sceWlanDrv_lib_0011.o sceWlanDrv_lib_0012.o sceWlanDrv_lib_0013.o sceWlanDrv_lib_0014.o sceWlanDrv_lib_0015.o sceWlanDrv_lib_0016.o sceWlanDrv_lib_0017.o sceWlanDrv_lib_0018.o + +libpspwlanincludedir = @PSPSDK_INCLUDEDIR@ +libpspwlaninclude_HEADERS = pspwlan.h + +lib_LIBRARIES = libpspwlan.a +libpspwlan_a_SOURCES = sceWlanDrv.S sceWlanDrv_lib.S +libpspwlan_a_LIBADD = $(WLAN_OBJS) $(WLANLIB_OBJS) + +$(WLAN_OBJS): sceWlanDrv.S + $(COMPILE) -DF_$* $< -c -o $@ + +$(WLANLIB_OBJS): sceWlanDrv_lib.S + $(COMPILE) -DF_$* $< -c -o $@ diff --git a/src/wlan/pspwlan.h b/src/wlan/pspwlan.h new file mode 100644 index 00000000..be0ec49f --- /dev/null +++ b/src/wlan/pspwlan.h @@ -0,0 +1,64 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * pspwlan.h - Prototypes for the sceWlan library + * + * Copyright (c) 2005 John Kelley + * + * $Id: pspwlan.h 2207 2007-03-16 16:42:08Z tyranid $ + */ +#ifndef __PSPWLAN_H__ +#define __PSPWLAN_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Determine if the wlan device is currently powered on + * + * @return 0 if off, 1 if on + */ +int sceWlanDevIsPowerOn(void); + +/** + * Determine the state of the Wlan power switch + * + * @return 0 if off, 1 if on + */ +int sceWlanGetSwitchState(void); + +/** + * Get the Ethernet Address of the wlan controller + * + * @param etherAddr - pointer to a buffer of u8 (NOTE: it only writes to 6 bytes, but + * requests 8 so pass it 8 bytes just in case) + * @return 0 on success, < 0 on error + */ +int sceWlanGetEtherAddr(u8 *etherAddr); + +/** + * Attach to the wlan device + * + * @return 0 on success, < 0 on error. + */ +int sceWlanDevAttach(void); + +/** + * Detach from the wlan device + * + * @return 0 on success, < 0 on error/ + */ +int sceWlanDevDetach(void); + +/* +int sceWlanGPBindRegError(); +*/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/wlan/sceWlanDrv.S b/src/wlan/sceWlanDrv.S new file mode 100644 index 00000000..57f597af --- /dev/null +++ b/src/wlan/sceWlanDrv.S @@ -0,0 +1,16 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceWlanDrv_0000 + IMPORT_START "sceWlanDrv",0x40010000 +#endif +#ifdef F_sceWlanDrv_0001 + IMPORT_FUNC "sceWlanDrv",0x93440B11,sceWlanDevIsPowerOn +#endif +#ifdef F_sceWlanDrv_0002 + IMPORT_FUNC "sceWlanDrv",0xD7763699,sceWlanGetSwitchState +#endif +#ifdef F_sceWlanDrv_0003 + IMPORT_FUNC "sceWlanDrv",0x0C622081,sceWlanGetEtherAddr +#endif diff --git a/src/wlan/sceWlanDrv_lib.S b/src/wlan/sceWlanDrv_lib.S new file mode 100644 index 00000000..3e6a75b1 --- /dev/null +++ b/src/wlan/sceWlanDrv_lib.S @@ -0,0 +1,61 @@ + .set noreorder + +#include "pspimport.s" + +#ifdef F_sceWlanDrv_lib_0000 + IMPORT_START "sceWlanDrv_lib",0x40010000 +#endif +#ifdef F_sceWlanDrv_lib_0001 + IMPORT_FUNC "sceWlanDrv_lib",0x482CAE9A,sceWlanDevAttach +#endif +#ifdef F_sceWlanDrv_lib_0002 + IMPORT_FUNC "sceWlanDrv_lib",0xC9A8CAB7,sceWlanDevDetach +#endif +#ifdef F_sceWlanDrv_lib_0003 + IMPORT_FUNC "sceWlanDrv_lib",0x19E51F54,sceWlanDrv_lib_19E51F54 +#endif +#ifdef F_sceWlanDrv_lib_0004 + IMPORT_FUNC "sceWlanDrv_lib",0x5E7C8D94,sceWlanDevIsGameMode +#endif +#ifdef F_sceWlanDrv_lib_0005 + IMPORT_FUNC "sceWlanDrv_lib",0x5ED4049A,sceWlanGPPrevEstablishActive +#endif +#ifdef F_sceWlanDrv_lib_0006 + IMPORT_FUNC "sceWlanDrv_lib",0xB4D7CB74,sceWlanGPSend +#endif +#ifdef F_sceWlanDrv_lib_0007 + IMPORT_FUNC "sceWlanDrv_lib",0xA447103A,sceWlanGPRecv +#endif +#ifdef F_sceWlanDrv_lib_0008 + IMPORT_FUNC "sceWlanDrv_lib",0x9658C9F7,sceWlanGPRegisterCallback +#endif +#ifdef F_sceWlanDrv_lib_0009 + IMPORT_FUNC "sceWlanDrv_lib",0x4C7F62E0,sceWlanGPUnRegisterCallback +#endif +#ifdef F_sceWlanDrv_lib_0010 + IMPORT_FUNC "sceWlanDrv_lib",0x81579D36,sceWlanDrv_lib_81579D36 +#endif +#ifdef F_sceWlanDrv_lib_0011 + IMPORT_FUNC "sceWlanDrv_lib",0x5BAA1FE5,sceWlanDrv_lib_5BAA1FE5 +#endif +#ifdef F_sceWlanDrv_lib_0012 + IMPORT_FUNC "sceWlanDrv_lib",0x4C14BACA,sceWlanDrv_lib_4C14BACA +#endif +#ifdef F_sceWlanDrv_lib_0013 + IMPORT_FUNC "sceWlanDrv_lib",0x2D0FAE4E,sceWlanDrv_lib_2D0FAE4E +#endif +#ifdef F_sceWlanDrv_lib_0014 + IMPORT_FUNC "sceWlanDrv_lib",0x56F467CA,sceWlanDrv_lib_56F467CA +#endif +#ifdef F_sceWlanDrv_lib_0015 + IMPORT_FUNC "sceWlanDrv_lib",0xFE8A0B46,sceWlanDrv_lib_FE8A0B46 +#endif +#ifdef F_sceWlanDrv_lib_0016 + IMPORT_FUNC "sceWlanDrv_lib",0x40B0AA4A,sceWlanDrv_lib_40B0AA4A +#endif +#ifdef F_sceWlanDrv_lib_0017 + IMPORT_FUNC "sceWlanDrv_lib",0x7FF54BD2,sceWlanDevSetGPIO +#endif +#ifdef F_sceWlanDrv_lib_0018 + IMPORT_FUNC "sceWlanDrv_lib",0x05FE320C,sceWlanDevGetStateGPIO +#endif diff --git a/tools/Makefile.am b/tools/Makefile.am new file mode 100644 index 00000000..39279d2d --- /dev/null +++ b/tools/Makefile.am @@ -0,0 +1,23 @@ + +bin_PROGRAMS = bin2s bin2c bin2o pack-pbp unpack-pbp mksfo mksfoex psp-config psp-build-exports psp-prxgen psp-fixup-imports + +bin2s_SOURCES = bin2s.c +bin2c_SOURCES = bin2c.c +bin2o_SOURCES = bin2o.c + +pack_pbp_SOURCES = pack-pbp.c +unpack_pbp_SOURCES = unpack-pbp.c + +mksfo_SOURCES = mksfo.c + +mksfoex_SOURCES = mksfoex.c + +psp_config_SOURCES = psp-config.c getopt_long.c + +psp_build_exports_SOURCES = psp-build-exports.c getopt_long.c sha1.c + +psp_prxgen_SOURCES = psp-prxgen.c getopt_long.c + +psp_fixup_imports_SOURCES = psp-fixup-imports.c getopt_long.c sha1.c + +noinst_HEADERS = elftypes.h getopt.h prxtypes.h sha1.h types.h diff --git a/tools/bin2c.c b/tools/bin2c.c new file mode 100644 index 00000000..c2bfb094 --- /dev/null +++ b/tools/bin2c.c @@ -0,0 +1,73 @@ +/* +# _____ ___ ____ ___ ____ +# ____| | ____| | | |____| +# | ___| | ___| ____| | \ PSPDEV Open Source Project. +#----------------------------------------------------------------------- +# Review pspsdk README & LICENSE files for further details. +# +# $Id: bin2c.c 210 2005-06-18 17:52:59Z mrbrown $ +*/ + +#include +#include +#include +#include +#include +#include + +unsigned char *buffer; + +int main(int argc, char *argv[]) +{ + int fd_size; + FILE *source,*dest; + int i; + + if(argc != 4) { + printf("bin2c - from bin2s By Sjeep\n" + "Usage: bin2c infile outfile label\n\n"); + return 1; + } + + if((source=fopen( argv[1], "rb")) == NULL) { + printf("Error opening %s for reading.\n",argv[1]); + return 1; + } + + fseek(source,0,SEEK_END); + fd_size = ftell(source); + fseek(source,0,SEEK_SET); + + buffer = malloc(fd_size); + if(buffer == NULL) { + printf("Failed to allocate memory.\n"); + return 1; + } + + if(fread(buffer,1,fd_size,source) != fd_size) { + printf("Failed to read file.\n"); + return 1; + } + fclose(source); + + if((dest = fopen(argv[2],"w+")) == NULL) { + printf("Failed to open/create %s.\n",argv[2]); + return 1; + } + + fprintf(dest, "#ifndef __%s__\n", argv[3]); + fprintf(dest, "#define __%s__\n\n", argv[3]); + fprintf(dest, "static unsigned int size_%s = %d;\n", argv[3], fd_size); + fprintf(dest, "static unsigned char %s[] __attribute__((aligned(16))) = {", argv[3]); + + for(i=0;i +#include +#include +#include +#include +#include +#include + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; + +int alignment = 16; +int have_size = 1; +int have_irx = 0; + +u32 LE32(u32 b) { + u32 t = 0x12345678; + if (*((unsigned char*)(&t)) == 0x78) { + return b; + } else { + return ((b & 0xff000000) >> 24) | + ((b & 0x00ff0000) >> 8 ) | + ((b & 0x0000ff00) << 8 ) | + ((b & 0x000000ff) << 24); + } +} + +u16 LE16(u16 b) { + u32 t = 0x12345678; + if (*((unsigned char*)(&t)) == 0x78) { + return b; + } else { + return ((b & 0xff00) >> 8) | + ((b & 0x00ff) << 8); + } +} + +unsigned char elf_header[] = { + 0x7f, 'E', 'L', 'F', 0x01, 0x01, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // e_ident + 0x01, 0x00, // e_type (relocatable) + 0x08, 0x00, // e_machine (mips) + 0x01, 0x00, 0x00, 0x00, // e_version + 0x00, 0x00, 0x00, 0x00, // e_entry + 0x00, 0x00, 0x00, 0x00, // e_phoff + 0x34, 0x00, 0x00, 0x00, // e_shoff + 0x01, 0x40, 0x92, 0x20, // e_flags + 0x34, 0x00, // e_ehsize + 0x00, 0x00, // e_phentsize + 0x00, 0x00, // e_phnum + 0x28, 0x00, // e_shentsize + 0x05, 0x00, // e_shnum + 0x01, 0x00, // e_shstrndx +}; + +// 0 = NULL +// 1 = .shstrtab +// 2 = .symtab +// 3 = .strtab +// 4 = .data + +struct elf_section_t { + u32 sh_name, sh_type, sh_flags, sh_addr, sh_offset, sh_size; + u32 sh_link, sh_info, sh_addralign, sh_entsize; +}; + +struct elf_symbol_t { + u32 st_name, st_value, st_size; + u8 st_info, st_other; + u16 st_shndx; +}; + +// 0 0000000001 11111111 12222222 22233 +// 0 1234567890 12345678 90123456 78901 +char shstrtab[] = "\0.shstrtab\0.symtab\0.strtab\0.data"; + +void create_elf(FILE * dest, const unsigned char * source, u32 size, const char * label) { + int i, l_size; + struct elf_section_t section; + struct elf_symbol_t symbol; + u32 strtab_size; + char strtab[512]; + u32 data_size[4]; + + if (have_irx) { + elf_header[36] = 1; + elf_header[37] = 0; + elf_header[38] = 0; + elf_header[39] = 0; + } + + for (i = 0; i < sizeof(elf_header); i++) { + fputc(elf_header[i], dest); + } + + l_size = strlen(label); + + strtab[0] = 0; + strcpy(strtab + 1, label); + strcat(strtab + 1, "_start"); + strcpy(strtab + 1 + l_size + 7, label); + strcat(strtab + 1 + l_size + 7, "_end"); + if (have_size) { + strtab_size = (l_size * 3 + 1 + 7 + 5 + 6); + strcpy(strtab + 1 + l_size + 7 + l_size + 5, label); + strcat(strtab + 1 + l_size + 7 + l_size + 5, "_size"); + } else { + strtab_size = (l_size * 2 + 1 + 7 + 5); + } + + // section 0 (NULL) + section.sh_name = section.sh_type = section.sh_flags = section.sh_addr = section.sh_offset = section.sh_size = + section.sh_link = section.sh_info = section.sh_addralign = section.sh_entsize = 0; + + fwrite(§ion, 1, sizeof(section), dest); + + + // section 1 (.shstrtab) + section.sh_name = LE32(1); + section.sh_type = LE32(3); // STRTAB + section.sh_flags = 0; + section.sh_addr = 0; + section.sh_offset = LE32(40 * 5 + 0x34); + section.sh_size = LE32(33); + section.sh_link = 0; + section.sh_info = 0; + section.sh_addralign = LE32(1); + section.sh_entsize = 0; + + fwrite(§ion, 1, sizeof(section), dest); + + + // section 2 (.symtab) + section.sh_name = LE32(11); + section.sh_type = LE32(2); // SYMTAB + section.sh_flags = 0; + section.sh_addr = 0; + section.sh_offset = LE32(40 * 5 + 0x34 + 33); + section.sh_size = LE32(have_size ? 0x30 : 0x20); + section.sh_link = LE32(3); + section.sh_info = 0; + section.sh_addralign = LE32(4); + section.sh_entsize = LE32(0x10); + + fwrite(§ion, 1, sizeof(section), dest); + + + // section 3 (.strtab) + section.sh_name = LE32(19); + section.sh_type = LE32(3); // STRTAB + section.sh_flags = 0; + section.sh_addr = 0; + section.sh_offset = LE32(40 * 5 + 0x34 + 33 + (have_size ? 0x30 : 0x20)); + section.sh_size = LE32(strtab_size); + section.sh_link = 0; + section.sh_info = 0; + section.sh_addralign = LE32(1); + section.sh_entsize = 0; + + fwrite(§ion, 1, sizeof(section), dest); + + + // section 4 (.data) + section.sh_name = LE32(27); + section.sh_type = LE32(1); // PROGBITS + section.sh_flags = LE32(3); // Write + Alloc + section.sh_addr = 0; + section.sh_offset = LE32(40 * 5 + 0x34 + 33 + (have_size ? 0x30 : 0x20) + strtab_size); + section.sh_size = LE32(size + have_size * 16); + section.sh_link = 0; + section.sh_addralign = LE32(alignment); + section.sh_entsize = 0; + + fwrite(§ion, 1, sizeof(section), dest); + + + + fwrite(shstrtab, 1, 33, dest); + + symbol.st_name = LE32(1); + symbol.st_value = LE32(have_size * 16); + symbol.st_size = LE32(size); + symbol.st_info = 0x11; + symbol.st_other = 0; + symbol.st_shndx = LE16(4); + fwrite(&symbol, 1, sizeof(symbol), dest); + + symbol.st_name = LE32(l_size + 1 + 7); + symbol.st_value = LE32(size + have_size * 16); + symbol.st_size = 0; + symbol.st_info = 0x11; + symbol.st_other = 0; + symbol.st_shndx = LE16(4); + fwrite(&symbol, 1, sizeof(symbol), dest); + + if (have_size) { + symbol.st_name = LE32(l_size * 2 + 1 + 7 + 5); + symbol.st_value = 0; + symbol.st_size = LE32(4); + symbol.st_info = 0x11; + symbol.st_other = 0; + symbol.st_shndx = LE16(4); + fwrite(&symbol, 1, sizeof(symbol), dest); + } + + fwrite(strtab, 1, strtab_size, dest); + + if (have_size) { + data_size[0] = LE32(size); + data_size[1] = 0; + data_size[2] = 0; + data_size[3] = 0; + fwrite(data_size, 4, 4, dest); + } + fwrite(source, 1, size, dest); +} + +void usage() { + printf("bin2o - Converts a binary file into a .o file.\n" + "Usage: bin2o [-a XX] [-n] [-i] [-b XX] [-e XX] [-s XX] infile outfile label\n" + " -i - create an iop-compatible .o file.\n" + " -n - don't add label_size symbol.\n" + " -a XX - set .data section alignment to XX.\n" + " (has to be a power of two).\n" + " -b XX - start reading file at this offset.\n" + " -e XX - stop reading file at this offset.\n" + " -s XX - force output data to be of this size.\n" + "\n" + ); +} + +int main(int argc, char *argv[]) +{ + u32 fd_size, start = 0, end = 0xffffffff, size = 0xffffffff; + unsigned char * buffer; + FILE * source, * dest; + char * f_source = 0, * f_dest = 0, * f_label = 0; + int i; + + for (i = 1; i < argc; i++) { + if (argv[i][0] == '-') { + switch (argv[i][1]) { + case 'a': + i++; + if (!argv[i]) { + usage(); + printf("-a requires an argument.\n"); + return 1; + } + if (argv[i][0] == '-') { + usage(); + printf("-a requires an argument.\n"); + return 1; + } + alignment = atoi(argv[i]); + if ((alignment - 1) & alignment) { + printf("Error: alignment must be a power of 2.\n"); + return 1; + } + break; + case 'n': + have_size = 0; + break; + case 'i': + have_irx = 1; + break; + case 'b': + i++; + if (!argv[i]) { + usage(); + printf("-b requires an argument.\n"); + return 1; + } + if (argv[i][0] == '-') { + usage(); + printf("-b requires an argument.\n"); + return 1; + } + start = atoi(argv[i]); + break; + case 'e': + i++; + if (!argv[i]) { + usage(); + printf("-e requires an argument.\n"); + return 1; + } + if (argv[i][0] == '-') { + usage(); + printf("-e requires an argument.\n"); + return 1; + } + end = atoi(argv[i]); + break; + case 's': + i++; + if (!argv[i]) { + usage(); + printf("-s requires an argument.\n"); + return 1; + } + if (argv[i][0] == '-') { + usage(); + printf("-s requires an argument.\n"); + return 1; + } + size = atoi(argv[i]); + break; + default: + usage(); + printf("Unknow option: %s.\n", argv[i]); + return 1; + } + } else { + if (!f_source) { + f_source = argv[i]; + } else if (!f_dest) { + f_dest = argv[i]; + } else if (!f_label) { + f_label = argv[i]; + } else { + usage(); + printf("Too many arguments.\n"); + return 1; + } + } + } + + if (!f_source || !f_dest || !f_label) { + usage(); + printf("Not enough arguments.\n"); + return 1; + } + + if (!(source = fopen(f_source, "rb"))) { + printf("Error opening %s for reading.\n", f_source); + return 1; + } + + fseek(source, 0, SEEK_END); + fd_size = ftell(source); + fseek(source, start, SEEK_SET); + + if (fd_size < end) + end = fd_size; + + if (end < (size - start)) + size = end - start; + + buffer = malloc(size); + if (buffer == NULL) { + printf("Failed to allocate memory.\n"); + return 1; + } + + if (fread(buffer, 1, size, source) != size) { + printf("Failed to read file.\n"); + return 1; + } + fclose(source); + + if (!(dest = fopen(f_dest, "wb+"))) { + printf("Failed to open/create %s.\n", f_dest); + return 1; + } + + create_elf(dest, buffer, size, f_label); + + fclose(dest); + free(buffer); + + return 0; +} diff --git a/tools/bin2s.c b/tools/bin2s.c new file mode 100644 index 00000000..95a23f49 --- /dev/null +++ b/tools/bin2s.c @@ -0,0 +1,75 @@ +/* +# _____ ___ ____ ___ ____ +# ____| | ____| | | |____| +# | ___| | ___| ____| | \ PSPDEV Open Source Project. +#----------------------------------------------------------------------- +# Review pspsdk README & LICENSE files for further details. +# +# $Id: bin2s.c 210 2005-06-18 17:52:59Z mrbrown $ +*/ + +#include +#include +#include +#include +#include +#include + +unsigned char *buffer; + +int main(int argc, char *argv[]) +{ + int fd_size; + FILE *source,*dest; + int i; + + if(argc != 4) { + printf("bin2s - By Sjeep\n" + "Usage: bin2s infile outfile label\n\n"); + return 1; + } + + if((source=fopen( argv[1], "rb")) == NULL) { + printf("Error opening %s for reading.\n",argv[1]); + return 1; + } + + fseek(source,0,SEEK_END); + fd_size = ftell(source); + fseek(source,0,SEEK_SET); + + buffer = malloc(fd_size); + if(buffer == NULL) { + printf("Failed to allocate memory.\n"); + return 1; + } + + if(fread(buffer,1,fd_size,source) != fd_size) { + printf("Failed to read file.\n"); + return 1; + } + fclose(source); + + if((dest = fopen(argv[2],"w+")) == NULL) { + printf("Failed to open/create %s.\n",argv[2]); + return 1; + } + + fprintf(dest, ".sdata\n\n"); + fprintf(dest, ".globl size_%s\nsize_%s:\t.word %d\n\n", argv[3], argv[3], fd_size); + fprintf(dest, ".data\n\n"); + fprintf(dest, ".balign 16\n\n"); + fprintf(dest, ".globl %s\n",argv[3]); + fprintf(dest, "%s:\n\n",argv[3]); + + for(i=0;i + * + * $Id: elftypes.h 1520 2005-12-04 20:09:36Z tyranid $ + */ + +#ifndef __ELF_TYPES_H__ +#define __ELF_TYPES_H__ + +#include "types.h" + +#define ELF_MACHINE_MIPS 0x0008 +#define ELF_SH_STRTAB ".shstrtab" + +#define ELF_SECT_MAX_NAME 128 + +/* Structure defining a single elf section */ +struct ElfSection +{ + /* Name index */ + u32 iName; + /* Type of section */ + u32 iType; + /* Section flags */ + u32 iFlags; + /* Addr of section when loaded */ + u32 iAddr; + /* Offset of the section in the elf */ + u32 iOffset; + /* Size of the sections data */ + u32 iSize; + /* Link info */ + u32 iLink; + /* Info */ + u32 iInfo; + /* Address alignment */ + u32 iAddralign; + /* Entry size */ + u32 iEntsize; + + /* Aliased pointer to the data (in the original Elf) */ + u8 *pData; + /* Name of the section */ + char szName[ELF_SECT_MAX_NAME]; + /* Index */ + int iIndex; + /* Section Ref. Used for relocations */ + struct ElfSection *pRef; + /* Indicates if this section is to be outputted */ + int blOutput; +}; + +struct ElfProgram +{ + u32 iType; + u32 iOffset; + u32 iVaddr; + u32 iPaddr; + u32 iFilesz; + u32 iMemsz; + u32 iFlags; + u32 iAlign; + + /* Aliased pointer to the data (in the original Elf)*/ + u8 *pData; +}; + +/* Structure to hold elf header data, in native format */ +struct ElfHeader +{ + u32 iMagic; + u32 iClass; + u32 iData; + u32 iIdver; + u32 iType; + u32 iMachine; + u32 iVersion; + u32 iEntry; + u32 iPhoff; + u32 iShoff; + u32 iFlags; + u32 iEhsize; + u32 iPhentsize; + u32 iPhnum; + u32 iShentsize; + u32 iShnum; + u32 iShstrndx; +}; + +struct ElfReloc +{ + /* Pointer to the section name */ + const char* secname; + /* Base address */ + u32 base; + /* Type */ + u32 type; + /* Symbol (if known) */ + u32 symbol; + /* Offset into the file */ + u32 offset; + /* New Address for the relocation (to do with what you will) */ + u32 addr; +}; + +/* Define ELF types */ +typedef u32 Elf32_Addr; +typedef u16 Elf32_Half; +typedef u32 Elf32_Off; +typedef s32 Elf32_Sword; +typedef u32 Elf32_Word; + +#define ELF_MAGIC 0x464C457F + +#define ELF_EXEC_TYPE 0x0002 +#define ELF_PRX_TYPE 0xFFA0 + +#define SHT_NULL 0 +#define SHT_PROGBITS 1 +#define SHT_SYMTAB 2 +#define SHT_STRTAB 3 +#define SHT_RELA 4 +#define SHT_HASH 5 +#define SHT_DYNAMIC 6 +#define SHT_NOTE 7 +#define SHT_NOBITS 8 +#define SHT_REL 9 +#define SHT_SHLIB 10 +#define SHT_DYNSYM 11 +#define SHT_LOPROC 0x70000000 +#define SHT_HIPROC 0x7fffffff +#define SHT_LOUSER 0x80000000 +#define SHT_HIUSER 0xffffffff + +#define SHT_PRXRELOC (SHT_LOPROC | 0xA0) + +// MIPS Reloc Entry Types +#define R_MIPS_NONE 0 +#define R_MIPS_16 1 +#define R_MIPS_32 2 +#define R_MIPS_REL32 3 +#define R_MIPS_26 4 +#define R_MIPS_HI16 5 +#define R_MIPS_LO16 6 +#define R_MIPS_GPREL16 7 +#define R_MIPS_LITERAL 8 +#define R_MIPS_GOT16 9 +#define R_MIPS_PC16 10 +#define R_MIPS_CALL16 11 +#define R_MIPS_GPREL32 12 + +#define SHF_WRITE 1 +#define SHF_ALLOC 2 +#define SHF_EXECINSTR 4 + +#define PT_NULL 0 +#define PT_LOAD 1 +#define PT_DYNAMIC 2 +#define PT_INTERP 3 +#define PT_NOTE 4 +#define PT_SHLIB 5 +#define PT_PHDR 6 +#define PT_LOPROC 0x70000000 +#define PT_HIPROC 0x7fffffff + +/* ELF file header */ +typedef struct { + Elf32_Word e_magic; + u8 e_class; + u8 e_data; + u8 e_idver; + u8 e_pad[9]; + Elf32_Half e_type; + Elf32_Half e_machine; + Elf32_Word e_version; + Elf32_Addr e_entry; + Elf32_Off e_phoff; + Elf32_Off e_shoff; + Elf32_Word e_flags; + Elf32_Half e_ehsize; + Elf32_Half e_phentsize; + Elf32_Half e_phnum; + Elf32_Half e_shentsize; + Elf32_Half e_shnum; + Elf32_Half e_shstrndx; +} __attribute__((packed)) Elf32_Ehdr; + +/* ELF section header */ +typedef struct { + Elf32_Word sh_name; + Elf32_Word sh_type; + Elf32_Word sh_flags; + Elf32_Addr sh_addr; + Elf32_Off sh_offset; + Elf32_Word sh_size; + Elf32_Word sh_link; + Elf32_Word sh_info; + Elf32_Word sh_addralign; + Elf32_Word sh_entsize; +} __attribute__((packed)) Elf32_Shdr; + +typedef struct { + Elf32_Word p_type; + Elf32_Off p_offset; + Elf32_Addr p_vaddr; + Elf32_Addr p_paddr; + Elf32_Word p_filesz; + Elf32_Word p_memsz; + Elf32_Word p_flags; + Elf32_Word p_align; +} Elf32_Phdr; + +#define ELF32_R_SYM(i) ((i)>>8) +#define ELF32_R_TYPE(i) ((u8)(i&0xFF)) + +typedef struct { + Elf32_Addr r_offset; + Elf32_Word r_info; +} Elf32_Rel; + +typedef struct { + Elf32_Word st_name; + Elf32_Addr st_value; + Elf32_Word st_size; + unsigned char st_info; + unsigned char st_other; + Elf32_Half st_shndx; +} __attribute__((packed)) Elf32_Sym; + +#define STB_LOCAL 0 +#define STB_GLOBAL 1 +#define STB_WEAK 2 +#define STB_LOPROC 13 +#define STB_HIPROC 15 + +#define ELF32_ST_BIND(i) ((i)>>4) +#define ELF32_ST_TYPE(i) ((i)&0xf) +#define ELF32_ST_INFO(b,t) (((b)<<4)+((t)&0xf)) + +#endif diff --git a/tools/getopt.h b/tools/getopt.h new file mode 100644 index 00000000..c27a3d16 --- /dev/null +++ b/tools/getopt.h @@ -0,0 +1,68 @@ +/* $NetBSD: getopt.h,v 1.7 2005/02/03 04:39:32 perry Exp $ */ + +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dieter Baron and Thomas Klausner. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _GETOPT_H_ +#define _GETOPT_H_ + +#include + +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 + +extern char *optarg; +extern int optind, opterr, optopt; + +struct option { + /* name of long option */ + const char *name; + /* + * one of no_argument, required_argument, and optional_argument: + * whether option takes an argument + */ + int has_arg; + /* if not NULL, set *flag to val when option found */ + int *flag; + /* if flag not NULL, value to set *flag to; else return value */ + int val; +}; + +int getopt_long(int, char * const *, const char *, + const struct option *, int *); + +#endif /* !_GETOPT_H_ */ diff --git a/tools/getopt_long.c b/tools/getopt_long.c new file mode 100644 index 00000000..ec7551d3 --- /dev/null +++ b/tools/getopt_long.c @@ -0,0 +1,405 @@ +/* $NetBSD: getopt_long.c,v 1.19 2005/12/02 14:08:51 yamt Exp $ */ + +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dieter Baron and Thomas Klausner. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include + +int opterr = 1; /* if error message should be printed */ +int optind = 1; /* index into parent argv vector */ +int optopt = '?'; /* character checked for validity */ +int optreset; /* reset getopt */ +char *optarg; /* argument associated with option */ + +#define IGNORE_FIRST (*options == '-' || *options == '+') +#define PRINT_ERROR ((opterr) && ((*options != ':') \ + || (IGNORE_FIRST && options[1] != ':'))) +#define IS_POSIXLY_CORRECT (getenv("POSIXLY_CORRECT") != NULL) +#define PERMUTE (!IS_POSIXLY_CORRECT && !IGNORE_FIRST) +/* XXX: GNU ignores PC if *options == '-' */ +#define IN_ORDER (!IS_POSIXLY_CORRECT && *options == '-') + +/* return values */ +#define BADCH (int)'?' +#define BADARG ((IGNORE_FIRST && options[1] == ':') \ + || (*options == ':') ? (int)':' : (int)'?') +#define INORDER (int)1 + +#define EMSG "" + +static int getopt_internal (int, char **, const char *); +static int gcd (int, int); +static void permute_args (int, int, int, char **); + +static const char *place = EMSG; /* option letter processing */ + +/* XXX: set optreset to 1 rather than these two */ +static int nonopt_start = -1; /* first non option argument (for permute) */ +static int nonopt_end = -1; /* first option after non options (for permute) */ + +/* Error messages */ +static const char recargchar[] = "option requires an argument -- %c"; +static const char recargstring[] = "option requires an argument -- %s"; +static const char ambig[] = "ambiguous option -- %.*s"; +static const char noarg[] = "option doesn't take an argument -- %.*s"; +static const char illoptchar[] = "unknown option -- %c"; +static const char illoptstring[] = "unknown option -- %s"; + + +/* + * Compute the greatest common divisor of a and b. + */ +static int +gcd(a, b) + int a; + int b; +{ + int c; + + c = a % b; + while (c != 0) { + a = b; + b = c; + c = a % b; + } + + return b; +} + +/* + * Exchange the block from nonopt_start to nonopt_end with the block + * from nonopt_end to opt_end (keeping the same order of arguments + * in each block). + */ +static void +permute_args(int panonopt_start, int panonopt_end, int opt_end, char **nargv) +{ + int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; + char *swap; + + /* + * compute lengths of blocks and number and size of cycles + */ + nnonopts = panonopt_end - panonopt_start; + nopts = opt_end - panonopt_end; + ncycle = gcd(nnonopts, nopts); + cyclelen = (opt_end - panonopt_start) / ncycle; + + for (i = 0; i < ncycle; i++) { + cstart = panonopt_end+i; + pos = cstart; + for (j = 0; j < cyclelen; j++) { + if (pos >= panonopt_end) + pos -= nnonopts; + else + pos += nopts; + swap = nargv[pos]; + nargv[pos] = nargv[cstart]; + nargv[cstart] = swap; + } + } +} + +/* + * getopt_internal -- + * Parse argc/argv argument vector. Called by user level routines. + * Returns -2 if -- is found (can be long option or end of options marker). + */ +static int +getopt_internal(int nargc, char **nargv, const char *options) +{ + char *oli; /* option letter list index */ + int optchar; + + optarg = NULL; + + /* + * XXX Some programs (like rsyncd) expect to be able to + * XXX re-initialize optind to 0 and have getopt_long(3) + * XXX properly function again. Work around this braindamage. + */ + if (optind == 0) + optind = 1; + + if (optreset) + nonopt_start = nonopt_end = -1; +start: + if (optreset || !*place) { /* update scanning pointer */ + optreset = 0; + if (optind >= nargc) { /* end of argument vector */ + place = EMSG; + if (nonopt_end != -1) { + /* do permutation, if we have to */ + permute_args(nonopt_start, nonopt_end, + optind, nargv); + optind -= nonopt_end - nonopt_start; + } + else if (nonopt_start != -1) { + /* + * If we skipped non-options, set optind + * to the first of them. + */ + optind = nonopt_start; + } + nonopt_start = nonopt_end = -1; + return -1; + } + if ((*(place = nargv[optind]) != '-') + || (place[1] == '\0')) { /* found non-option */ + place = EMSG; + if (IN_ORDER) { + /* + * GNU extension: + * return non-option as argument to option 1 + */ + optarg = nargv[optind++]; + return INORDER; + } + if (!PERMUTE) { + /* + * if no permutation wanted, stop parsing + * at first non-option + */ + return -1; + } + /* do permutation */ + if (nonopt_start == -1) + nonopt_start = optind; + else if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, nargv); + nonopt_start = optind - + (nonopt_end - nonopt_start); + nonopt_end = -1; + } + optind++; + /* process next argument */ + goto start; + } + if (nonopt_start != -1 && nonopt_end == -1) + nonopt_end = optind; + if (place[1] && *++place == '-') { /* found "--" */ + place++; + return -2; + } + } + if ((optchar = (int)*place++) == (int)':' || + (oli = strchr(options + (IGNORE_FIRST ? 1 : 0), optchar)) == NULL) { + /* option letter unknown or ':' */ + if (!*place) + ++optind; + if (PRINT_ERROR) + fprintf(stderr, illoptchar, optchar); + optopt = optchar; + return BADCH; + } + if (optchar == 'W' && oli[1] == ';') { /* -W long-option */ + /* XXX: what if no long options provided (called by getopt)? */ + if (*place) + return -2; + + if (++optind >= nargc) { /* no arg */ + place = EMSG; + if (PRINT_ERROR) + fprintf(stderr, recargchar, optchar); + optopt = optchar; + return BADARG; + } else /* white space */ + place = nargv[optind]; + /* + * Handle -W arg the same as --arg (which causes getopt to + * stop parsing). + */ + return -2; + } + if (*++oli != ':') { /* doesn't take argument */ + if (!*place) + ++optind; + } else { /* takes (optional) argument */ + optarg = NULL; + if (*place) /* no white space */ + optarg = (char *) place; + /* XXX: disable test for :: if PC? (GNU doesn't) */ + else if (oli[1] != ':') { /* arg not optional */ + if (++optind >= nargc) { /* no arg */ + place = EMSG; + if (PRINT_ERROR) + fprintf(stderr, recargchar, optchar); + optopt = optchar; + return BADARG; + } else + optarg = nargv[optind]; + } + place = EMSG; + ++optind; + } + /* dump back option letter */ + return optchar; +} + +/* + * getopt_long -- + * Parse argc/argv argument vector. + */ +int +getopt_long(int nargc, char * const *nargv, const char *options, const struct option *long_options, int *idx) +{ + int retval; + + retval = getopt_internal(nargc, (char **) (nargv), options); + if (retval == -2) { + char *current_argv, *has_equal; + size_t current_argv_len; + int i, match; + + current_argv = (char *) (place); + match = -1; + + optind++; + place = EMSG; + + if (*current_argv == '\0') { /* found "--" */ + /* + * We found an option (--), so if we skipped + * non-options, we have to permute. + */ + if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, (char **) (nargv)); + optind -= nonopt_end - nonopt_start; + } + nonopt_start = nonopt_end = -1; + return -1; + } + if ((has_equal = strchr(current_argv, '=')) != NULL) { + /* argument found (--option=arg) */ + current_argv_len = has_equal - current_argv; + has_equal++; + } else + current_argv_len = strlen(current_argv); + + for (i = 0; long_options[i].name; i++) { + /* find matching long option */ + if (strncmp(current_argv, long_options[i].name, + current_argv_len)) + continue; + + if (strlen(long_options[i].name) == + (unsigned)current_argv_len) { + /* exact match */ + match = i; + break; + } + if (match == -1) /* partial match */ + match = i; + else { + /* ambiguous abbreviation */ + if (PRINT_ERROR) + fprintf(stderr, ambig, (int)current_argv_len, + current_argv); + optopt = 0; + return BADCH; + } + } + if (match != -1) { /* option found */ + if (long_options[match].has_arg == no_argument + && has_equal) { + if (PRINT_ERROR) + fprintf(stderr, noarg, (int)current_argv_len, + current_argv); + /* + * XXX: GNU sets optopt to val regardless of + * flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + return BADARG; + } + if (long_options[match].has_arg == required_argument || + long_options[match].has_arg == optional_argument) { + if (has_equal) + optarg = has_equal; + else if (long_options[match].has_arg == + required_argument) { + /* + * optional argument doesn't use + * next nargv + */ + optarg = nargv[optind++]; + } + } + if ((long_options[match].has_arg == required_argument) + && (optarg == NULL)) { + /* + * Missing argument; leading ':' + * indicates no error should be generated + */ + if (PRINT_ERROR) + fprintf(stderr, recargstring, current_argv); + /* + * XXX: GNU sets optopt to val regardless + * of flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + --optind; + return BADARG; + } + } else { /* unknown option */ + if (PRINT_ERROR) + fprintf(stderr, illoptstring, current_argv); + optopt = 0; + return BADCH; + } + if (long_options[match].flag) { + *long_options[match].flag = long_options[match].val; + retval = 0; + } else + retval = long_options[match].val; + if (idx) + *idx = match; + } + return retval; +} diff --git a/tools/mksfo.c b/tools/mksfo.c new file mode 100644 index 00000000..4b134830 --- /dev/null +++ b/tools/mksfo.c @@ -0,0 +1,78 @@ +/* +# _____ ___ ____ ___ ____ +# ____| | ____| | | |____| +# | ___| | ___| ____| | \ PSPDEV Open Source Project. +#----------------------------------------------------------------------- +# Review ps2sdk README & LICENSE files for further details. +# +# A simple tool to build an SFO file for use in the EBOOT.PBP +# $Id: mksfo.c 1993 2006-08-23 21:40:16Z jim $ +*/ + +#include +#include + +#define SIZE_POS 0x88 +#define TITLE_POS 0x118 +#define TITLE_SIZE 0x7F + +/* A default, simple SFO file */ +unsigned char g_defaultSfo[] = { + 0x00, 0x50, 0x53, 0x46, 0x01, 0x01, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0xe8, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x04, 0x02, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x12, 0x00, 0x04, 0x02, 0x0a, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x04, 0x02, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x27, 0x00, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x36, 0x00, 0x04, 0x02, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x24, 0x00, 0x00, 0x00, 0x45, 0x00, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x2c, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x04, 0x02, 0x24, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x42, 0x4f, 0x4f, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x00, 0x43, 0x41, 0x54, + 0x45, 0x47, 0x4f, 0x52, 0x59, 0x00, 0x44, 0x49, 0x53, 0x43, 0x5f, 0x49, 0x44, 0x00, 0x44, 0x49, + 0x53, 0x43, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x00, 0x50, 0x41, 0x52, 0x45, 0x4e, + 0x54, 0x41, 0x4c, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x00, 0x50, 0x53, 0x50, 0x5f, 0x53, 0x59, + 0x53, 0x54, 0x45, 0x4d, 0x5f, 0x56, 0x45, 0x52, 0x00, 0x52, 0x45, 0x47, 0x49, 0x4f, 0x4e, 0x00, + 0x54, 0x49, 0x54, 0x4c, 0x45, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x4d, 0x47, 0x00, 0x00, + 0x55, 0x43, 0x4a, 0x53, 0x31, 0x30, 0x30, 0x34, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x31, 0x2e, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x31, 0x2e, 0x30, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +int main(int argc, char **argv) +{ + FILE *fp; + int len; + + if(argc < 3) + { + fprintf(stderr, "Usage: mksfo TITLE output.sfo\n"); + return 1; + } + + len = strlen(argv[1]); + if(len > TITLE_SIZE) len = TITLE_SIZE; + g_defaultSfo[SIZE_POS] = (unsigned char) len; + strncpy((char *) &g_defaultSfo[TITLE_POS], argv[1], len); + + fp = fopen(argv[2], "wb"); + if(fp != NULL) + { + fwrite(g_defaultSfo, 1, sizeof(g_defaultSfo), fp); + fclose(fp); + } + else + { + fprintf(stderr, "Could not open %s\n", argv[2]); + return 1; + } + + return 0; +} diff --git a/tools/mksfoex.c b/tools/mksfoex.c new file mode 100644 index 00000000..923d4410 --- /dev/null +++ b/tools/mksfoex.c @@ -0,0 +1,341 @@ +/* +# _____ ___ ____ ___ ____ +# ____| | ____| | | |____| +# | ___| | ___| ____| | \ PSPDEV Open Source Project. +#----------------------------------------------------------------------- +# Review pspsdk README & LICENSE files for further details. +# +# New and improved mksfo +# $Id$ +*/ +#include +#include +#include +#include +#include +#include "types.h" + +#define PSF_MAGIC 0x46535000 +#define PSF_VERSION 0x00000101 + +struct SfoHeader +{ + uint32_t magic; + uint32_t version; + uint32_t keyofs; + uint32_t valofs; + uint32_t count; +} __attribute__((packed)); + +struct SfoEntry +{ + uint16_t nameofs; + uint8_t alignment; + uint8_t type; + uint32_t valsize; + uint32_t totalsize; + uint32_t dataofs; +} __attribute__((packed)); + +#define PSF_TYPE_BIN 0 +#define PSF_TYPE_STR 2 +#define PSF_TYPE_VAL 4 + +struct EntryContainer +{ + const char *name; + int type; + uint32_t value; + const char *data; +}; + +struct EntryContainer g_defaults[] = { + { "BOOTABLE", PSF_TYPE_VAL, 1, NULL }, + { "CATEGORY", PSF_TYPE_STR, 0, "MG" }, + { "DISC_ID", PSF_TYPE_STR, 0, "UCJS10041" }, + { "DISC_VERSION", PSF_TYPE_STR, 0, "1.00" }, + { "PARENTAL_LEVEL", PSF_TYPE_VAL, 1, NULL }, + { "PSP_SYSTEM_VER", PSF_TYPE_STR, 0, "1.00" }, + { "REGION", PSF_TYPE_VAL, 0x8000, NULL }, +}; + +#define MAX_OPTIONS (256) + +static const char *g_title = NULL; +static const char *g_filename = NULL; +static int g_empty = 0; +static struct EntryContainer g_vals[MAX_OPTIONS]; + +static struct option arg_opts[] = +{ + {"dword", required_argument, NULL, 'd'}, + {"string", required_argument, NULL, 's'}, + {"empty", no_argument, NULL, 'e'}, + { NULL, 0, NULL, 0 } +}; + +struct EntryContainer *find_free() +{ + int i; + + for(i = 0; i < MAX_OPTIONS; i++) + { + if(g_vals[i].name == NULL) + { + return &g_vals[i]; + } + } + + return NULL; +} + +struct EntryContainer *find_name(const char *name) +{ + int i; + + for(i = 0; i < MAX_OPTIONS; i++) + { + if((g_vals[i].name != NULL) && (strcmp(g_vals[i].name, name) == 0)) + { + return &g_vals[i]; + } + } + + return NULL; +} + +int add_string(char *str) +{ + char *equals = NULL; + struct EntryContainer *entry; + + equals = strchr(str, '='); + if(equals == NULL) + { + fprintf(stderr, "Invalid option (no =)\n"); + return 0; + } + + *equals++ = 0; + + entry = find_free(); + if(entry == NULL) + { + fprintf(stderr, "Maximum options reached\n"); + return 0; + } + + memset(entry, 0, sizeof(struct EntryContainer)); + entry->name = str; + entry->type = PSF_TYPE_STR; + entry->data = equals; + + return 1; +} + +int add_dword(char *str) +{ + char *equals = NULL; + struct EntryContainer *entry; + + equals = strchr(str, '='); + if(equals == NULL) + { + fprintf(stderr, "Invalid option (no =)\n"); + return 0; + } + + *equals++ = 0; + + entry = find_free(); + if(entry == NULL) + { + fprintf(stderr, "Maximum options reached\n"); + return 0; + } + + memset(entry, 0, sizeof(struct EntryContainer)); + entry->name = str; + entry->type = PSF_TYPE_VAL; + entry->value = strtoul(equals, NULL, 0); + + return 1; +} + +/* Process the arguments */ +int process_args(int argc, char **argv) +{ + int ch; + + g_title = NULL; + g_filename = NULL; + g_empty = 0; + + ch = getopt_long(argc, argv, "ed:s:", arg_opts, NULL); + while(ch != -1) + { + switch(ch) + { + case 'd' : if(!add_dword(optarg)) + { + return 0; + } + break; + case 's' : if(!add_string(optarg)) + { + } + break; + default : break; + }; + + ch = getopt_long(argc, argv, "ed:s:", arg_opts, NULL); + } + + argc -= optind; + argv += optind; + + if(argc < 1) + { + return 0; + } + + if(!g_empty) + { + g_title = argv[0]; + argc--; + argv++; + } + + if(argc < 1) + { + return 0; + } + + g_filename = argv[0]; + + return 1; +} + +int main(int argc, char **argv) +{ + FILE *fp; + int i; + char head[8192]; + char keys[8192]; + char data[8192]; + struct SfoHeader *h; + struct SfoEntry *e; + char *k; + char *d; + unsigned int align; + unsigned int keyofs; + unsigned int count; + + if(!process_args(argc, argv)) + { + fprintf(stderr, "Usage: mksfoex [options] TITLE output.sfo\n"); + fprintf(stderr, "Options:\n"); + fprintf(stderr, "-d NAME=VALUE - Add a new DWORD value\n"); + fprintf(stderr, "-s NAME=STR - Add a new string value\n"); + + return 1; + } + + if(!g_empty) + { + struct EntryContainer *entry; + + for(i = 0; i < (sizeof(g_defaults) / sizeof(struct EntryContainer)); i++) + { + if(!find_name(g_defaults[i].name)) + { + entry = find_free(); + if(entry == NULL) + { + fprintf(stderr, "Maximum options reached\n"); + return 0; + } + *entry = g_defaults[i]; + } + } + + if(!find_name("TITLE")) + { + entry = find_free(); + entry->name = "TITLE"; + entry->type = PSF_TYPE_STR; + entry->value = 0; + entry->data = g_title; + } + } + + memset(head, 0, sizeof(head)); + memset(keys, 0, sizeof(keys)); + memset(data, 0, sizeof(data)); + h = (struct SfoHeader*) head; + e = (struct SfoEntry*) (head+sizeof(struct SfoHeader)); + k = keys; + d = data; + SW(&h->magic, PSF_MAGIC); + SW(&h->version, PSF_VERSION); + count = 0; + + for(i = 0; g_vals[i].name; i++) + { + SW(&h->count, ++count); + SW(&e->nameofs, k-keys); + SW(&e->dataofs, d-data); + SW(&e->alignment, 4); + SW(&e->type, g_vals[i].type); + + strcpy(k, g_vals[i].name); + k += strlen(k)+1; + if(e->type == PSF_TYPE_VAL) + { + SW(&e->valsize, 4); + SW(&e->totalsize, 4); + SW((uint32_t*) d, g_vals[i].value); + d += 4; + } + else + { + int totalsize; + int valsize; + + valsize = strlen(g_vals[i].data)+1; + totalsize = (valsize + 3) & ~3; + SW(&e->valsize, valsize); + SW(&e->totalsize, totalsize); + memset(d, 0, totalsize); + memcpy(d, g_vals[i].data, valsize); + d += totalsize; + } + e++; + } + + + keyofs = (char*)e - head; + SW(&h->keyofs, keyofs); + align = 3 - ((unsigned int) (k-keys) & 3); + while(align < 3) + { + k++; + align--; + } + + SW(&h->valofs, keyofs + (k-keys)); + + fp = fopen(g_filename, "wb"); + if(fp == NULL) + { + fprintf(stderr, "Cannot open filename %s\n", g_filename); + return 0; + } + + fwrite(head, 1, (char*)e-head, fp); + fwrite(keys, 1, k-keys, fp); + fwrite(data, 1, d-data, fp); + fclose(fp); + + return 0; +} diff --git a/tools/pack-pbp.c b/tools/pack-pbp.c new file mode 100644 index 00000000..261f6de1 --- /dev/null +++ b/tools/pack-pbp.c @@ -0,0 +1,189 @@ +/* +# _____ ___ ____ ___ ____ +# ____| | ____| | | |____| +# | ___| | ___| ____| | \ PSPDEV Open Source Project. +#----------------------------------------------------------------------- +# (c) 2005 Dan Peori +# Licenced under Academic Free License version 2.0 +# Review pspsdk README & LICENSE files for further details. +# +# 2006-12-30 - Andrew Whatson +# - rewrote for easier reading +# - gave "correct" names to UNKNOWN.* files +# - improved memory efficiency with large PBPs +# - output name of each file as it's added +# +# $Id: pack-pbp.c 2228 2007-05-01 05:22:03Z oopo $ +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef WORDS_BIGENDIAN + +// Swap the bytes of an int for big-endian machines +static int swap_int(int n) +{ + return ((n>>24)&0xff)|((n>>8)&0xff00)|((n<<8)&0xff0000)|((n<<24)&0xff000000); +} + +#endif + +#include +#include +#include + +#ifdef HAVE_MALLOC_H +#include +#endif + +// Struct to describe the header of a PBP file +struct { + char signature[4]; + char version[4]; + int offset[8]; +} header = { + { 0x00, 0x50, 0x42, 0x50 }, + { 0x00, 0x00, 0x01, 0x00 }, + { 40, 0, 0, 0, 0, 0, 0, 0 } +}; + +// Maximum size of read buffer +int maxbuffer = 16 * 1024 * 1024; + +int main(int argc, char *argv[]) { int loop0, result; + FILE *infile; + FILE *outfile; + int filesize[8]; + + // Check for the correct number of arguments + if (argc != 10) { + printf("USAGE: %s \n", argv[0]); + return -1; + } + + // For each file in the PBP + for (loop0 = 0; loop0 < 8; loop0++) { + + // If the specificed filename is NULL or -, skip the file. + if (strncmp(argv[2 + loop0], "NULL", 4) == 0 || strncmp(argv[2 + loop0], "-", 4) == 0) { + filesize[loop0] = 0; + } else { + + // Open the file + infile = fopen(argv[2 + loop0], "rb"); + if (infile == NULL) { + printf("ERROR: Could not open the file. (%s)\n", argv[2 + loop0]); + return -1; + } + + // Read in the file size + fseek(infile, 0, SEEK_END); + filesize[loop0] = ftell(infile); + fseek(infile, 0, SEEK_SET); + if (filesize[loop0] < 0) { + printf("ERROR: Could not read in the file size. (%s)\n", argv[2 + loop0]); + return -1; + } + + // Close the file + result = fclose(infile); + if (result < 0) { + printf("ERROR: Could not close the file. (%s)\n", argv[2 + loop0]); + return -1; + } + } + } + + // Set the header offset values for each file + for (loop0 = 1; loop0 < 8; loop0++) { + header.offset[loop0] = header.offset[loop0 - 1] + filesize[loop0 - 1]; + } + +#ifdef WORDS_BIGENDIAN + + // Swap the bytes of the offsets for big-endian machines + for (loop0 = 0; loop0 < 8; loop0++) { + header.offset[loop0] = swap_int(header.offset[loop0]); + } + +#endif + + // Open the output file + outfile = fopen(argv[1], "wb"); + if (outfile == NULL) { + printf("ERROR: Could not open the output file. (%s)\n", argv[1]); + return -1; + } + + // Write out the header + result = fwrite(&header, sizeof(header), 1, outfile); + if (result < 0) { + printf("ERROR: Could not write out the file header. (%s)\n", argv[1]); + return -1; + } + + // For each file in the PBP + for (loop0 = 0; loop0 < 8; loop0++) { + void *buffer; + int readsize; + + // Print out the file details + printf("[%d] %10d bytes | %s\n", loop0, filesize[loop0], argv[2 + loop0]); + + // If this file is empty, skip it + if (!filesize[loop0]) continue; + + // Open the file + infile = fopen(argv[2 + loop0], "rb"); + if (infile == NULL) { + printf("ERROR: Could not open the file. (%s)\n", argv[2 + loop0]); + return -1; + } + + do { + // Make sure we don't exceed the maximum buffer size + if (filesize[loop0] > maxbuffer) { + readsize = maxbuffer; + } else { + readsize = filesize[loop0]; + } + filesize[loop0] -= readsize; + + // Create the read buffer + buffer = malloc(readsize); + if (buffer == NULL) { + printf("ERROR: Could not allocate the file data space. (%s)\n", argv[2 + loop0]); + return -1; + } + + // Read in the data from the file + if (fread(buffer, readsize, 1, infile) < 0) { + printf("ERROR: Could not read in the file data. (%s)\n", argv[2 + loop0]); + return -1; + } + + // Write the contents of the buffer to the PBP + if (fwrite(buffer, readsize, 1, outfile) < 0) { + printf("ERROR: Could not write out the file data. (%s)\n", argv[1]); + return -1; + } + + // Clean up the buffer + free(buffer); + + // Repeat if we haven't finished writing the file + } while (filesize[loop0]); + } + + // Close the output file. + result = fclose(outfile); + if (result < 0) { + printf("ERROR: Could not close the output file. (%s)\n", argv[1]); + return -1; + } + + // Exit successful + return 0; +} diff --git a/tools/prxtypes.h b/tools/prxtypes.h new file mode 100644 index 00000000..fd25154b --- /dev/null +++ b/tools/prxtypes.h @@ -0,0 +1,150 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * prxtypes.h - Definition of PRX specific types. + * + * Copyright (c) 2005 James Forshaw + * + * $Id: prxtypes.h 1095 2005-09-27 21:02:16Z jim $ + */ + +#ifndef __PRXTYPES_H__ +#define __PRXTYPES_H__ + +#include "types.h" + +#define PSP_MODULE_MAX_NAME 28 +#define PSP_LIB_MAX_NAME 128 +#define PSP_ENTRY_MAX_NAME 128 +/* Define the maximum number of permitted entries per lib */ +#define PSP_MAX_V_ENTRIES 255 +#define PSP_MAX_F_ENTRIES 65535 + +#define PSP_MODULE_INFO_NAME ".rodata.sceModuleInfo" + +/* Remove the .rel.sceStub.text section as it shouldn't have been there */ +#define PSP_MODULE_REMOVE_REL ".rel.sceStub.text" + +/* Define a name for the unnamed first export */ +#define PSP_SYSTEM_EXPORT "syslib" + +enum PspEntryType +{ + PSP_ENTRY_FUNC = 0, + PSP_ENTRY_VAR = 1 +}; + +/* Define the in-prx structure types */ + +/* Structure to hold the module export information */ +struct PspModuleExport +{ + u32 name; + u32 flags; + u32 counts; + u32 exports; +} __attribute__((packed)); + +/* Structure to hold the module import information */ +struct PspModuleImport +{ + u32 name; + u32 flags; + u8 entry_size; + u8 var_count; + u16 func_count; + u32 nids; + u32 funcs; +}; + +/* Structure to hold the module info */ +struct PspModuleInfo +{ + u32 flags; + char name[PSP_MODULE_MAX_NAME]; + u32 gp; + u32 exports; + u32 exp_end; + u32 imports; + u32 imp_end; +}; + +/* Define the loaded prx types */ +struct PspEntry +{ + /* Name of the entry */ + char name[PSP_ENTRY_MAX_NAME]; + /* Nid of the entry */ + u32 nid; + /* Type of the entry */ + enum PspEntryType type; + /* Virtual address of the entry in the loaded elf */ + u32 addr; + /* Virtual address of the nid dword */ + u32 nid_addr; +}; + +/* Holds a linking entry for an import library */ +struct PspLibImport +{ + /** Previous import */ + struct PspLibImport *prev; + /** Next import */ + struct PspLibImport *next; + /** Name of the library */ + char name[PSP_LIB_MAX_NAME]; + /* Virtual address of the lib import stub */ + u32 addr; + /* Copy of the import stub (in native byte order) */ + struct PspModuleImport stub; + /* List of function entries */ + struct PspEntry funcs[PSP_MAX_F_ENTRIES]; + /* Number of function entries */ + int f_count; + /* List of variable entried */ + struct PspEntry vars[PSP_MAX_V_ENTRIES]; + /* Number of variable entires */ + int v_count; +}; + +/* Holds a linking entry for an export library */ +struct PspLibExport +{ + /** Previous export in the chain */ + struct PspLibExport *prev; + /** Next export in the chain */ + struct PspLibExport *next; + /** Name of the library */ + char name[PSP_LIB_MAX_NAME]; + /** Virtual address of the lib import stub */ + u32 addr; + /** Copy of the import stub (in native byte order) */ + struct PspModuleExport stub; + /** List of function entries */ + struct PspEntry funcs[PSP_MAX_F_ENTRIES]; + /** Number of function entries */ + int f_count; + /** List of variable entried */ + struct PspEntry vars[PSP_MAX_V_ENTRIES]; + /** Number of variable entires */ + int v_count; +}; + +/** Structure to hold the loaded module information */ +struct PspModule +{ + /** Name of the module */ + char name[PSP_MODULE_MAX_NAME+1]; + /** Info structure, in native byte order */ + struct PspModuleInfo info; + /** Virtual address of the module info section */ + u32 addr; + /** Head of the export list */ + struct PspLibExport *exp_head; + /** Head of the import list */ + struct PspLibImport *imp_head; +}; + +#endif diff --git a/tools/psp-build-exports.c b/tools/psp-build-exports.c new file mode 100644 index 00000000..1205d372 --- /dev/null +++ b/tools/psp-build-exports.c @@ -0,0 +1,1058 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * psp-build-exports.c - Simple program to build an export file. + * + * Copyright (c) 2005 James Forshaw + * + * $Id: psp-build-exports.c 2415 2008-08-01 16:56:26Z Raphael $ + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "sha1.h" + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define MAX_LIB_NAME 27 +#define MAX_LIB_FUNCS 65535 +#define MAX_LIB_VARS 255 +#define MAX_LIB_ENTRY_NAME 127 +#define MAX_ERROR 1024 +#define MAX_LINE 1024 +#define SYSTEM_LIB_NAME "syslib" + +enum PspConfigMode +{ + PSP_BUILD_UNKNOWN, + PSP_BUILD_EXPORTS, + PSP_BUILD_STUBS, + PSP_BUILD_STUBS_NEW, +}; + +struct psp_export +{ + struct psp_export *pNext; + unsigned int nid; + char name[MAX_LIB_ENTRY_NAME+1]; +}; + +struct psp_alias +{ + struct psp_alias *pNext; + char name[MAX_LIB_ENTRY_NAME+1]; + char alias[MAX_LIB_ENTRY_NAME+1]; +}; + +struct psp_lib +{ + struct psp_lib *pNext; + char name[MAX_LIB_NAME+1]; + unsigned short ver; + unsigned short attr; + int funcCount; + struct psp_export *pFuncHead; + int varCount; + struct psp_export *pVarHead; + struct psp_alias *pAliasHead; +}; + +struct export_cmd +{ + const char *name; + int params; + int (*handler)(char ** params); +}; + +/* Specifies that the current usage is to the print the pspsdk path */ +static enum PspConfigMode g_outputmode; +static int g_verbose = 0; +static const char *g_infile; +static char g_errstring[MAX_ERROR] = "No Error"; +static struct psp_lib *g_libhead = NULL; +static struct psp_lib *g_currlib = NULL; +static int g_libcount = 0; + +void free_export_chain(struct psp_export *pHead) +{ + struct psp_export *pNext; + + pNext = pHead; + + while(pNext != NULL) + { + struct psp_export *pTemp; + + pTemp = pNext->pNext; + free(pNext); + pNext = pTemp; + } +} + +void free_alias_chain(struct psp_alias *pHead) +{ + struct psp_alias *pNext; + + pNext = pHead; + + while(pNext != NULL) + { + struct psp_alias *pTemp; + + pTemp = pNext->pNext; + free(pNext); + pNext = pTemp; + } +} + +void free_lib_data(void) +{ + struct psp_lib *pNext; + + if(g_currlib != NULL) + { + free_export_chain(g_currlib->pFuncHead); + free_export_chain(g_currlib->pVarHead); + free_alias_chain(g_currlib->pAliasHead); + free(g_currlib); + g_currlib = NULL; + } + + pNext = g_libhead; + + while(pNext != NULL) + { + struct psp_lib *pTemp; + + pTemp = pNext->pNext; + free_export_chain(pNext->pFuncHead); + free_export_chain(pNext->pVarHead); + free_alias_chain(pNext->pAliasHead); + free(pNext); + pNext = pTemp; + } + + g_libhead = NULL; +} + +const char *find_alias(struct psp_alias *pHead, const char *name) +{ + struct psp_alias *pNext; + const char *szAlias = NULL; + + pNext = pHead; + while(pNext) + { + if(strcmp(name, pNext->name) == 0) + { + szAlias = pNext->alias; + break; + } + + pNext = pNext->pNext; + } + + return szAlias; +} + +static struct option arg_opts[] = +{ + {"build-exports", no_argument, NULL, 'b'}, + {"build-stubs", no_argument, NULL, 's'}, + {"build-stubs-new", no_argument, NULL, 'k'}, + {"verbose", no_argument, NULL, 'v'}, + { NULL, 0, NULL, 0 } +}; + +/* Process the arguments */ +int process_args(int argc, char **argv) +{ + int ret = 0; + int ch; + + g_outputmode = PSP_BUILD_UNKNOWN; + + ch = getopt_long(argc, argv, "bsvk", arg_opts, NULL); + while(ch != -1) + { + switch(ch) + { + case 'b' : g_outputmode = PSP_BUILD_EXPORTS; + ret = 1; + break; + case 's' : g_outputmode = PSP_BUILD_STUBS; + ret = 1; + break; + case 'v' : g_verbose = 1; + break; + case 'k' : g_outputmode = PSP_BUILD_STUBS_NEW; + ret = 1; + break; + default : //fprintf(stderr, "Invalid option '%c'\n", ch); + break; + }; + + ch = getopt_long(argc, argv, "bsvk", arg_opts, NULL); + } + + argc -= optind; + argv += optind; + + if(argc < 1) + { + return 0; + } + + g_infile = argv[0]; + + return ret; +} + +void print_help(void) +{ + fprintf(stderr, "Usage: psp-build-exports -b|-s|-k [-v] export.exp\n"); + fprintf(stderr, "Options:\n"); + fprintf(stderr, "-b, --build-exports : Build an export file to stdout\n"); + fprintf(stderr, "-s, --build-stubs : Build a batch of stub files for the exports\n"); + fprintf(stderr, "-k, --build-stubs-new : Build a batch of stub files (in new format)\n"); + fprintf(stderr, "-v, --verbose : Verbose output\n"); +} + +void strip_whitespace(char *dest, const char *src) +{ + assert(dest != NULL); + assert(src != NULL); + + while(*src != 0) + { + if(!isspace(*src)) + { + *dest = *src; + dest++; + } + + src++; + } + + *dest = 0; +} + +/* + Parse a string of the form FUNC(arg1,arg2,...) + Returns the number of parameters or -1 on error. + */ +int parse_string(char *line, char **params, int max_params) +{ + int pos; + int param_start; + char *next_param; + int param_count; + + assert(line != NULL); + assert(params != NULL); + + pos = 0; + + /* Parse off "function" name */ + while((isalnum(line[pos])) || (line[pos] == '_')) + { + pos++; + } + + /* If we don't have any thing else than this is just the function */ + if(line[pos] == 0) + { + return 0; + } + + if(line[pos] != '(') + { + snprintf(g_errstring, MAX_ERROR, "Invalid character %c, expected (", line[pos]); + return -1; + } + + /* Terminate */ + line[pos++] = 0; + param_start = pos; + + /* Scan parameters */ + while((isalnum(line[pos])) || (line[pos] == '_') || (line[pos] == ',')) + { + pos++; + } + + if(line[pos] == 0) + { + snprintf(g_errstring, MAX_ERROR, "Missing closing brace ')'"); + return -1; + } + + if(line[pos] != ')') + { + snprintf(g_errstring, MAX_ERROR, "Invalid character %c, expected ')'", line[pos]); + return -1; + } + + if(line[pos+1] != 0) + { + snprintf(g_errstring, MAX_ERROR, "Trailing characters after bracket close %d", line[pos+1]); + return -1; + } + + line[pos] = 0; + + param_count = 0; + next_param = strtok(&line[param_start], ","); + while(next_param != NULL) + { + if(param_count == max_params) + { + snprintf(g_errstring, MAX_ERROR, "Run out of space for parameters"); + return -1; + } + + params[param_count++] = next_param; + next_param = strtok(NULL, ","); + } + + return param_count; +} + +void build_exports_output_extern(struct psp_export *pHead) +{ + struct psp_export *pExp; + + pExp = pHead; + while(pExp != NULL) + { + fprintf(stdout, "extern void %s;\n", pExp->name); + pExp = pExp->pNext; + } +} + +void build_exports_output_nids(struct psp_export *pHead) +{ + struct psp_export *pExp; + + pExp = pHead; + while(pExp != NULL) + { + fprintf(stdout, "\t0x%08X,\n", pExp->nid); + pExp = pExp->pNext; + } +} + +void build_exports_output_names(struct psp_export *pHead) +{ + struct psp_export *pExp; + + pExp = pHead; + while(pExp != NULL) + { + fprintf(stdout, "\t(unsigned int) &%s,\n", pExp->name); + pExp = pExp->pNext; + } +} + +void build_exports(void) +{ + struct psp_lib *pLib; + + fprintf(stdout, "#include \n"); + fprintf(stdout, "#define NULL ((void *) 0)\n\n"); + + /* Write out the nid tables */ + pLib = g_libhead; + while(pLib != NULL) + { + /* Print extern */ + build_exports_output_extern(pLib->pFuncHead); + build_exports_output_extern(pLib->pVarHead); + + fprintf(stdout, "static const unsigned int __%s_exports[%d] __attribute__((section(\".rodata.sceResident\"))) = {\n", + pLib->name, (pLib->funcCount + pLib->varCount) * 2); + + /* Print nid */ + build_exports_output_nids(pLib->pFuncHead); + build_exports_output_nids(pLib->pVarHead); + /* Print names */ + build_exports_output_names(pLib->pFuncHead); + build_exports_output_names(pLib->pVarHead); + fprintf(stdout, "};\n\n"); + + pLib = pLib->pNext; + } + + fprintf(stdout, "const struct _PspLibraryEntry __library_exports[%d] __attribute__((section(\".lib.ent\"), used)) = {\n", g_libcount); + pLib = g_libhead; + while(pLib != NULL) + { + if(strcmp(pLib->name, SYSTEM_LIB_NAME) == 0) + { + fprintf(stdout, "\t{ NULL, "); + } + else + { + fprintf(stdout, "\t{ \"%s\", ", pLib->name); + } + + fprintf(stdout, "0x%04X, 0x%04X, 4, %d, %d, &__%s_exports },\n", pLib->ver, pLib->attr, + pLib->varCount, pLib->funcCount, pLib->name); + + pLib = pLib->pNext; + } + fprintf(stdout, "};\n"); +} + +void build_stubs_output_lib(struct psp_lib *pLib) +{ + FILE *fp; + char filename[256]; + + snprintf(filename, 256, "%s.S", pLib->name); + if(g_verbose) + { + fprintf(stderr, "Writing output file %s\n", filename); + } + fp = fopen(filename, "w"); + if(fp != NULL) + { + struct psp_export *pExp; + + fprintf(fp, "\t.set noreorder\n\n"); + fprintf(fp, "#include \"pspstub.s\"\n\n"); + fprintf(fp, "\tSTUB_START \"%s\",0x%08X,0x%08X\n", pLib->name, ((pLib->attr | 0x8) << 16) | pLib->ver, + (pLib->funcCount << 16) | 5); + + pExp = pLib->pFuncHead; + while(pExp != NULL) + { + const char *alias; + + alias = find_alias(pLib->pAliasHead, pExp->name); + if(alias) + { + fprintf(fp, "\tSTUB_FUNC_WITH_ALIAS 0x%08X,%s,%s\n", pExp->nid, pExp->name,alias); + } + else + { + fprintf(fp, "\tSTUB_FUNC 0x%08X,%s\n", pExp->nid, pExp->name); + } + pExp = pExp->pNext; + } + + fprintf(fp, "\tSTUB_END\n"); + + fclose(fp); + } + else + { + fprintf(stderr, "Error, couldn't open file %s for writing\n", filename); + } +} + +void build_stubs_output_lib_new(struct psp_lib *pLib) +{ + FILE *fp; + char filename[256]; + int i; + + snprintf(filename, 256, "%s.S", pLib->name); + if(g_verbose) + { + fprintf(stderr, "Writing output file %s\n", filename); + } + fp = fopen(filename, "w"); + if(fp != NULL) + { + struct psp_export *pExp; + + fprintf(fp, "\t.set noreorder\n\n"); + fprintf(fp, "#include \"pspimport.s\"\n\n"); + + fprintf(fp, "// Build files\n"); + fprintf(fp, "// %s_0000.o ", pLib->name); + pExp = pLib->pFuncHead; + i = 1; + while(pExp != NULL) + { + fprintf(fp, "%s_%04d.o ", pLib->name, i++); + pExp = pExp->pNext; + } + fprintf(fp, "\n\n"); + + fprintf(fp, "#ifdef F_%s_0000\n", pLib->name); + fprintf(fp, "\tIMPORT_START \"%s\",0x%08X\n", pLib->name, ((pLib->attr | 0x8) << 16) | pLib->ver); + fprintf(fp, "#endif\n"); + + pExp = pLib->pFuncHead; + i = 1; + while(pExp != NULL) + { + const char *alias; + fprintf(fp, "#ifdef F_%s_%04d\n", pLib->name, i++); + + alias = find_alias(pLib->pAliasHead, pExp->name); + if(alias) + { + fprintf(fp, "\tIMPORT_FUNC_WITH_ALIAS \"%s\",0x%08X,%s,%s\n", pLib->name, pExp->nid, pExp->name, alias); + } + else + { + fprintf(fp, "\tIMPORT_FUNC \"%s\",0x%08X,%s\n", pLib->name, pExp->nid, pExp->name); + } + + fprintf(fp, "#endif\n"); + pExp = pExp->pNext; + } + + fclose(fp); + } + else + { + fprintf(stderr, "Error, couldn't open file %s for writing\n", filename); + } +} + +void build_stubs(void) +{ + struct psp_lib *pLib; + + pLib = g_libhead; + + while(pLib != NULL) + { + if(strcmp(pLib->name, SYSTEM_LIB_NAME)) + { + if(g_outputmode == PSP_BUILD_STUBS) + { + build_stubs_output_lib(pLib); + } + else + { + build_stubs_output_lib_new(pLib); + } + } + + pLib = pLib->pNext; + } +} + +int validate_number(const char *str, unsigned int *num) +{ + char *endp; + + assert(str != NULL); + assert(num != NULL); + + if(!isxdigit(*str)) + { + snprintf(g_errstring, MAX_ERROR, "'%s' is an invalid number", str); + return 0; + } + + *num = strtoul(str, &endp, 0); + if(*endp != 0) + { + snprintf(g_errstring, MAX_ERROR, "'%s' has trailing non-numeric characters", str); + return 0; + } + + return 1; +} + +int psp_begin_exports(char **params) +{ + /* Do nothing */ + return 1; +} + +int psp_end_exports(char **params) +{ + if(g_currlib != NULL) + { + /* Error, missing end of exports */ + } + + return 1; +} + +int psp_export_start(char **params) +{ + unsigned int ver; + unsigned int attr; + + if(g_currlib != NULL) + { + snprintf(g_errstring, MAX_ERROR, "Previous library '%s' not ended", g_currlib->name); + return 0; + } + + if(validate_number(params[1], &ver) == 0) + { + return 0; + } + + if(validate_number(params[2], &attr) == 0) + { + return 0; + } + + g_currlib = (struct psp_lib *) malloc(sizeof(struct psp_lib)); + if(g_currlib == NULL) + { + snprintf(g_errstring, MAX_ERROR, "Could not allocate memory for library"); + return 0; + } + + memset(g_currlib, 0, sizeof(struct psp_lib)); + g_libcount++; + + strncpy(g_currlib->name, params[0], MAX_LIB_NAME); + g_currlib->ver = ver; + g_currlib->attr = attr; + + return 1; +} + +int psp_export_end(char **params) +{ + struct psp_lib *pNext; + + if(g_currlib == NULL) + { + snprintf(g_errstring, MAX_ERROR, "No matching start command for library end"); + return 1; + } + + /* Add to the end of the chain */ + if(g_libhead == NULL) + { + g_libhead = g_currlib; + } + else + { + pNext = g_libhead; + while(pNext->pNext != NULL) + { + pNext = pNext->pNext; + } + + pNext->pNext = g_currlib; + } + + g_currlib = NULL; + + return 1; +} + +int internal_do_export(const char *name, unsigned int nid, struct psp_export **pHead) +{ + struct psp_export *pNew; + + assert(name != NULL); + assert(pHead != NULL); + + pNew = (struct psp_export *) malloc(sizeof(struct psp_export)); + + if(pNew != NULL) + { + struct psp_export *pNext; + + memset(pNew, 0, sizeof(struct psp_export)); + strncpy(pNew->name, name, MAX_LIB_ENTRY_NAME); + pNew->nid = nid; + + if(*pHead == NULL) + { + *pHead = pNew; + } + else + { + pNext = *pHead; + while(pNext->pNext != NULL) + { + pNext = pNext->pNext; + } + + pNext->pNext = pNew; + } + } + else + { + snprintf(g_errstring, MAX_ERROR, "Could not allocate memory for export %s", name); + return 0; + } + + return 1; +} + +int psp_export_func_nid(char **params) +{ + unsigned int nid; + + if(g_currlib == NULL) + { + snprintf(g_errstring, MAX_ERROR, "Cannot export function, not in a library definition"); + return 0; + } + + if(validate_number(params[1], &nid) == 0) + { + return 0; + } + + if(g_currlib->funcCount < MAX_LIB_FUNCS) + { + if(internal_do_export(params[0], nid, &g_currlib->pFuncHead)) + { + g_currlib->funcCount++; + return 1; + } + } + else + { + snprintf(g_errstring, MAX_ERROR, "Too many functions defined, cannot export another"); + } + + return 0; +} + +int psp_export_func_hash(char **params) +{ + unsigned int nid; + unsigned char hash[SHA1_DIGEST_SIZE]; + + if(g_currlib == NULL) + { + snprintf(g_errstring, MAX_ERROR, "Cannot export function, not in a library definition"); + return 0; + } + + sha1(hash, (unsigned char *) params[0], strlen(params[0])); + nid = hash[0] | (hash[1] << 8) | (hash[2] << 16) | (hash[3] << 24); + + if(g_currlib->funcCount < MAX_LIB_FUNCS) + { + if(internal_do_export(params[0], nid, &g_currlib->pFuncHead)) + { + g_currlib->funcCount++; + return 1; + } + } + else + { + snprintf(g_errstring, MAX_ERROR, "Too many functions defined, cannot export another"); + } + + return 0; +} + +int psp_export_var_nid(char **params) +{ + unsigned int nid; + + if(g_currlib == NULL) + { + snprintf(g_errstring, MAX_ERROR, "Cannot export variable, not in a library definition"); + return 0; + } + + if(validate_number(params[1], &nid) == 0) + { + return 0; + } + + if(g_currlib->varCount < MAX_LIB_VARS) + { + if(internal_do_export(params[0], nid, &g_currlib->pVarHead)) + { + g_currlib->varCount++; + return 1; + } + } + else + { + snprintf(g_errstring, MAX_ERROR, "Too many variables defined, cannot export another"); + } + + return 0; +} + +int psp_export_var_hash(char **params) +{ + unsigned int nid; + unsigned char hash[SHA1_DIGEST_SIZE]; + + if(g_currlib == NULL) + { + snprintf(g_errstring, MAX_ERROR, "Cannot export variable, not in a library definition"); + return 0; + } + + sha1(hash, (unsigned char *) params[0], strlen(params[0])); + nid = hash[0] | (hash[1] << 8) | (hash[2] << 16) | (hash[3] << 24); + + if(g_currlib->varCount < MAX_LIB_VARS) + { + if(internal_do_export(params[0], nid, &g_currlib->pVarHead)) + { + g_currlib->varCount++; + return 1; + } + } + else + { + snprintf(g_errstring, MAX_ERROR, "Too many variables defined, cannot export another"); + } + + return 0; +} + +int psp_export_alias(char **params) +{ + struct psp_alias *pAlias; + + if(g_currlib == NULL) + { + snprintf(g_errstring, MAX_ERROR, "Cannot alias name, not in a library definition"); + return 0; + } + + pAlias = (struct psp_alias *) malloc(sizeof(struct psp_alias)); + if(pAlias == NULL) + { + snprintf(g_errstring, MAX_ERROR, "Cannot allocate memory for alias"); + return 0; + } + + memset(pAlias, 0, sizeof(*pAlias)); + strncpy(pAlias->name, params[0], MAX_LIB_ENTRY_NAME); + strncpy(pAlias->alias, params[1], MAX_LIB_ENTRY_NAME); + + if(g_currlib->pAliasHead == NULL) + { + g_currlib->pAliasHead = pAlias; + } + else + { + struct psp_alias *pNext = g_currlib->pAliasHead; + + while(pNext->pNext) + { + pNext = pNext->pNext; + } + + pNext->pNext = pAlias; + } + + fprintf(stderr, "Alias %s->%s\n", params[0], params[1]); + + return 1; +} + +struct export_cmd commands[] = +{ + { "PSP_BEGIN_EXPORTS", 0, psp_begin_exports }, + { "PSP_END_EXPORTS", 0, psp_end_exports }, + { "PSP_EXPORT_START", 3, psp_export_start }, + { "PSP_EXPORT_END", 0, psp_export_end }, + { "PSP_EXPORT_FUNC_NID", 2, psp_export_func_nid }, + { "PSP_EXPORT_FUNC_HASH", 1, psp_export_func_hash }, + { "PSP_EXPORT_FUNC", 1, psp_export_func_hash }, + { "PSP_EXPORT_VAR_NID", 2, psp_export_var_nid }, + { "PSP_EXPORT_VAR", 1, psp_export_var_hash }, + { "PSP_EXPORT_VAR_HASH", 1, psp_export_var_hash }, + { "PSP_EXPORT_ALIAS", 2, psp_export_alias }, + { NULL, 0, NULL } +}; + +int process_command(const char *cmd, char ** params, int param_count) +{ + int i; + + i = 0; + + while(commands[i].name != NULL) + { + if(strcmp(cmd, commands[i].name) == 0) + { + assert(commands[i].handler != NULL); + if(param_count != commands[i].params) + { + snprintf(g_errstring, MAX_ERROR, "Incorrect number of parameters, have %d, expect %d\n", + param_count, commands[i].params); + break; + } + else + { + return commands[i].handler(params); + } + } + + i++; + } + + if(commands[i].name == NULL) + { + snprintf(g_errstring, MAX_ERROR, "Unknown command '%s'", cmd); + } + + return 0; +} + +int load_exports(void) +{ + FILE *fp; + int line_no = 1; + + fp = fopen(g_infile, "r"); + if(fp != NULL) + { + char curr_line[MAX_LINE]; + char strip_line[MAX_LINE]; + + while(fgets(curr_line, MAX_LINE, fp)) + { + strip_whitespace(strip_line, curr_line); + if((strip_line[0] != 0) && (strip_line[0] != '#')) + { + int ret; + char *params[16]; + + ret = parse_string(strip_line, params, 16); + if(ret >= 0) + { + if(g_verbose) + { + int i; + + fprintf(stderr, "Line %d, Name: %s ", line_no, strip_line); + for(i = 0; i < ret; i++) + { + fprintf(stderr, "Arg %d: %s ", i, params[i]); + } + fprintf(stderr, "\n"); + } + + if(process_command(strip_line, params, ret) == 0) + { + fprintf(stderr, "Error, line %d: %s\n", line_no, g_errstring); + return 0; + } + } + else + { + fprintf(stderr, "Error, line %d: %s\n", line_no, g_errstring); + return 0; + } + } + + line_no++; + } + + if(g_currlib) + { + fprintf(stderr, "Error, reached end of file while still exporting a library\n"); + return 0; + } + } + else + { + fprintf(stderr, "Could not open file %s\n", g_infile); + return 0; + } + + return 1; +} + +void dump_exports(void) +{ + struct psp_lib *pLib; + int count; + + pLib = g_libhead; + count = 1; + + while(pLib != NULL) + { + fprintf(stderr, "Export %d '%s', ver %04X, attr %04X\n", count, pLib->name, pLib->ver, pLib->attr); + fprintf(stderr, "Funcs %d-%p, Vars %d-%p\n", pLib->funcCount, pLib->pFuncHead, pLib->varCount, pLib->pVarHead); + + if(pLib->pFuncHead != NULL) + { + int func; + struct psp_export *pFunc; + + func = 0; + pFunc = pLib->pFuncHead; + while(pFunc != NULL) + { + fprintf(stderr, "Function %d - '%s', nid %08X\n", func++, pFunc->name, pFunc->nid); + pFunc = pFunc->pNext; + } + } + + if(pLib->pVarHead != NULL) + { + int var; + struct psp_export *pVar; + + var = 0; + pVar = pLib->pVarHead; + while(pVar != NULL) + { + fprintf(stderr, "Variable %d - '%s', nid %08X\n", var++, pVar->name, pVar->nid); + pVar = pVar->pNext; + } + } + + + + count++; + pLib = pLib->pNext; + } +} + +int main(int argc, char **argv) +{ + if(process_args(argc, argv)) + { + if(load_exports()) + { + if(g_verbose) + { + dump_exports(); + } + switch(g_outputmode) + { + case PSP_BUILD_EXPORTS: build_exports(); + break; + /* Do the same for both */ + case PSP_BUILD_STUBS_NEW: + case PSP_BUILD_STUBS : build_stubs(); + break; + default : /* Argh */ + break; + }; + } + + free_lib_data(); + } + else + { + print_help(); + } + + return 0; +} diff --git a/tools/psp-config.c b/tools/psp-config.c new file mode 100644 index 00000000..8f04abb8 --- /dev/null +++ b/tools/psp-config.c @@ -0,0 +1,290 @@ +#if defined(__MINGW32__) && !defined(__CYGWIN__) +#include +#endif +#include +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define PSPDEV_ENV "PSPDEV" +#define PATH_ENV "PATH" + +#ifndef MAX_PATH +#define MAX_PATH 256 +#endif + +/***** Might need to change these for different platforms */ +#define PATH_SEP ":" +#define DIR_SEP '/' +#define DIR_SEP_STR "/" + +/* The suffix to the path to strip off, if this is not there then we have an error */ +#ifdef __MINGW32__ +#define PSPDEV_PATH_SUFFIX "/bin/psp-config.exe" +#else +#define PSPDEV_PATH_SUFFIX "/bin/psp-config" +#endif +/************************/ + +enum PspConfigMode +{ + PSP_CONFIG_UNKNOWN, + PSP_CONFIG_PSPSDK_PATH, + PSP_CONFIG_PSPDEV_PATH, + PSP_CONFIG_PSP_PREFIX, +}; + +/* Specifies that the current usage is to the print the pspsdk path */ +static enum PspConfigMode g_configmode; + +static struct option arg_opts[] = +{ + {"pspsdk-path", no_argument, NULL, 'p'}, + {"pspdev-path", no_argument, NULL, 'd'}, + {"psp-prefix", no_argument, NULL, 'P'}, + { NULL, 0, NULL, 0 } +}; + +/* Process the arguments */ +int process_args(int argc, char **argv) +{ + int ret = 0; + int ch; + + g_configmode = PSP_CONFIG_UNKNOWN; + + ch = getopt_long(argc, argv, "pdP", arg_opts, NULL); + while(ch != -1) + { + switch(ch) + { + case 'p' : g_configmode = PSP_CONFIG_PSPSDK_PATH; + ret = 1; + break; + case 'd' : g_configmode = PSP_CONFIG_PSPDEV_PATH; + ret = 1; + break; + case 'P' : g_configmode = PSP_CONFIG_PSP_PREFIX; + ret = 1; + break; + default : fprintf(stderr, "Invalid option '%c'\n", ch); + break; + }; + + ch = getopt_long(argc, argv, "p", arg_opts, NULL); + } + + return ret; +} + +void print_help(void) +{ + fprintf(stderr, "Usage: psp-config [opts]\n"); + fprintf(stderr, "Options:\n"); + fprintf(stderr, "-p, --pspsdk-path : Print the base directory of PSPSDK\n"); + fprintf(stderr, "-d, --pspdev-path : Print the base install directory\n"); + fprintf(stderr, "-P, --psp-prefix : Print the prefix of PSP-hosted software\n"); +} + +void normalize_path (char *out) +{ + int i; + int j; + + /* Convert "//" to "/" */ + for (i = 0; out[i + 1]; i++) { + if (out[i] == '/' && out[i + 1] == '/') { + for (j = i + 1; out[j]; j++) { + out[j] = out[j + 1]; + } + i--; + } + } +} + +/* Find the path to the pspdev dir (e.g. /usr/local/pspdev) */ +char *find_pspdev_path(char *name) +{ + static char path[MAX_PATH]; + int found = 0; + + /* Check if name is an absolute path, if so our job is done */ + +#ifdef __MINGW32__ + + char *writableName = malloc(strlen(name) + 2); + char *ptr = writableName; + char temp; + + while (*(name)) { + temp = *(name++); + if (temp == '\\') temp = '/'; + *(ptr++) = temp; + } + + *(ptr) = '\0'; + name = writableName; +#endif + + if(name[0] == DIR_SEP +#ifdef __MINGW32__ + || name[1] == ':' +#endif + ) + { + /* Absolute path */ + strncpy(path, name, MAX_PATH); + /* Ensure NUL termination */ + path[MAX_PATH-1] = 0; + found = 1; + } + else + { + /* relative path */ + if(strchr(name, DIR_SEP) != NULL) + { + if(getcwd(path, MAX_PATH) != NULL) + { + strncat(path, DIR_SEP_STR, MAX_PATH-1); + strncat(path, name, MAX_PATH-1); + found = 1; + } + else + { + fprintf(stderr, "Error getting current working directory\n"); + } + } + else + { + char *path_env; + /* Scan the PATH variable */ + path_env = getenv(PATH_ENV); + if(path_env != NULL) + { + char *curr_tok; + char new_path[MAX_PATH]; + + /* Should really use the path separator from the + environment but who on earth changes it? */ + curr_tok = strtok(path_env, PATH_SEP); + while(curr_tok != NULL) + { + strcpy(new_path, curr_tok); + strcat(new_path, DIR_SEP_STR); + strcat(new_path, name); + + if(access(new_path, X_OK) == 0) + { + found = 1; + strcpy(path, new_path); + break; + } + + curr_tok = strtok(NULL, PATH_SEP); + } + } + else + { + fprintf(stderr, "Error, couldn't get PATH environment variable\n"); + } + } + } + + normalize_path(path); + char *result = NULL; + + if(found) + { + int suffix_len; + int path_len; + + suffix_len = strlen(PSPDEV_PATH_SUFFIX); + path_len = strlen(path); + + if(suffix_len <= path_len) + { + if(strcmp(PSPDEV_PATH_SUFFIX, &path[path_len - suffix_len]) == 0) + { + /* Oki valid path add a NUL */ + path[path_len - suffix_len] = 0; + result = path; + } + else + { + fprintf(stderr, "Error, invalid suffix on the end of the path. Should be %s\n", PSPDEV_PATH_SUFFIX); + } + } + else + { + fprintf(stderr, "Error, path not large enough for creating the PSPSDK path\n"); + } + + } + +#ifdef __MINGW32__ + free(writableName); +#endif + + return result; +} + +void print_path(char *name) +{ + char *pspdev_env; + + pspdev_env = getenv(PSPDEV_ENV); + if(pspdev_env == NULL) + { + /* Could not find the PSPDEV environment variable */ + /* Let's try and find where psp-config is */ + pspdev_env = find_pspdev_path(name); + } + + if (pspdev_env != NULL) { + switch(g_configmode) + { + case PSP_CONFIG_PSPSDK_PATH : printf("%s%c%s\n", pspdev_env, DIR_SEP, PSPSDK_TOPDIR); + break; + case PSP_CONFIG_PSPDEV_PATH : printf("%s\n", pspdev_env); + break; + case PSP_CONFIG_PSP_PREFIX : printf("%s%c%s\n", pspdev_env, DIR_SEP, "psp"); + break; + default : fprintf(stderr, "Error, invalida configuration mode\n"); + break; + }; + } +} + +int main(int argc, char **argv) +{ +#if defined(__MINGW32__) && !defined(__CYGWIN__) + // this will store the fully-qualified path + char psp_config_path[MAX_PATH] = ""; + + // fetch the path of the executable + if(GetModuleFileName(0, psp_config_path, sizeof(psp_config_path) - 1) == 0) + { + // fall back + strcpy(psp_config_path, argv[0]); + } +#endif + if(process_args(argc, argv)) + { + #if defined(__MINGW32__) && !defined(__CYGWIN__) + print_path(psp_config_path); + #else + print_path(argv[0]); + #endif + } + else + { + print_help(); + } + + return 0; +} diff --git a/tools/psp-fixup-imports.c b/tools/psp-fixup-imports.c new file mode 100644 index 00000000..840ed8f7 --- /dev/null +++ b/tools/psp-fixup-imports.c @@ -0,0 +1,851 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * psp-fixup-imports.c - Simple program to fixup an ELF's imports + * + * Copyright (c) 2005 James Forshaw + * + * $Id: psp-fixup-imports.c 2324 2007-10-03 00:51:52Z tyranid $ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "types.h" +#include "elftypes.h" +#include "prxtypes.h" +#include "sha1.h" + +#define PRX_LIBSTUB_SECT ".lib.stub" +#define PRX_STUBTEXT_SECT ".sceStub.text" +#define PRX_NID_SECT ".rodata.sceNid" + +struct NidMap +{ + unsigned int oldnid; + unsigned int newnid; +}; + +#define MAX_MAPNIDS 1024 + +struct ImportMap +{ + struct ImportMap *next; + char name[32]; + int count; + /* Could fail on things like PAF but who is going to want to remap 1000+ nids ? */ + struct NidMap nids[MAX_MAPNIDS]; +}; + +static const char *g_outfile; +static const char *g_infile; +static const char *g_mapfile; +static unsigned char *g_elfdata = NULL; +static unsigned int g_elfsize; +static struct ElfHeader g_elfhead = {0}; +static struct ElfSection *g_elfsections = NULL; +static struct ElfSection *g_modinfo = NULL; +static struct ElfSection *g_libstub = NULL; +static struct ElfSection *g_stubtext = NULL; +static struct ElfSection *g_nid = NULL; +static struct ImportMap *g_map = NULL; +static int g_reversemap = 0; + +/* Specifies that the current usage is to the print the pspsdk path */ +static int g_verbose = 0; + +static struct option arg_opts[] = +{ + {"output", required_argument, NULL, 'o'}, + {"reverse", no_argument, NULL, 'r' }, + {"map", required_argument, NULL, 'm'}, + {"verbose", no_argument, NULL, 'v'}, + { NULL, 0, NULL, 0 } +}; + +/* Process the arguments */ +int process_args(int argc, char **argv) +{ + int ch; + + g_outfile = NULL; + g_infile = NULL; + g_mapfile = NULL; + + ch = getopt_long(argc, argv, "vro:m:", arg_opts, NULL); + while(ch != -1) + { + switch(ch) + { + case 'v' : g_verbose = 1; + break; + case 'o' : g_outfile = optarg; + break; + case 'm' : g_mapfile = optarg; + break; + case 'r' : g_reversemap = 1; + break; + default : break; + }; + + ch = getopt_long(argc, argv, "vro:m:", arg_opts, NULL); + } + + argc -= optind; + argv += optind; + + if(argc < 1) + { + return 0; + } + + g_infile = argv[0]; + + if(g_outfile == NULL) + { + g_outfile = argv[0]; + } + + if(g_verbose) + { + fprintf(stderr, "Loading %s, outputting to %s\n", g_infile, g_outfile); + } + + return 1; +} + +void print_help(void) +{ + fprintf(stderr, "Usage: psp-fixup-imports [-v] [-o outfile.elf] infile.elf\n"); + fprintf(stderr, "Options:\n"); + fprintf(stderr, "-o, --output outfile : Output to a different file\n"); + fprintf(stderr, "-m, --map mapfile : Specify a firmware NID mapfile\n"); + fprintf(stderr, "-r, --reverse : Reverse the mapping\n"); + fprintf(stderr, "-v, --verbose : Verbose output\n"); +} + +/* Scan through the sections trying to find this address */ +const unsigned char *find_data(unsigned int iAddr) +{ + int i; + + for(i = 0; i < g_elfhead.iShnum; i++) + { + if((g_elfsections[i].iAddr <= iAddr) && ((g_elfsections[i].iAddr + g_elfsections[i].iSize) > iAddr)) + { + return g_elfsections[i].pData + (iAddr - g_elfsections[i].iAddr); + } + } + + return NULL; +} + +struct ImportMap *find_map_by_name(const char *name) +{ + struct ImportMap *currmap = g_map; + + while(currmap) + { + if(strcmp(name, currmap->name) == 0) + { + break; + } + currmap = currmap->next; + } + return currmap; +} + +unsigned char *load_file(const char *file, unsigned int *size) +{ + FILE *fp; + unsigned char *data = NULL; + + do + { + fp = fopen(file, "rb"); + if(fp != NULL) + { + (void) fseek(fp, 0, SEEK_END); + *size = ftell(fp); + rewind(fp); + + if(*size < sizeof(Elf32_Ehdr)) + { + fprintf(stderr, "Error, invalid file size\n"); + break; + } + + data = (unsigned char *) malloc(*size); + if(data == NULL) + { + fprintf(stderr, "Error, could not allocate memory for ELF\n"); + break; + } + + (void) fread(data, 1, *size, fp); + fclose(fp); + } + else + { + fprintf(stderr, "Error, could not find file %s\n", file); + } + } + while(0); + + return data; +} + +/* Validate the ELF header */ +int validate_header(unsigned char *data) +{ + Elf32_Ehdr *head; + int ret = 0; + + head = (Elf32_Ehdr*) data; + + do + { + /* Read in the header structure */ + g_elfhead.iMagic = LW(head->e_magic); + g_elfhead.iClass = head->e_class; + g_elfhead.iData = head->e_data; + g_elfhead.iIdver = head->e_idver; + g_elfhead.iType = LH(head->e_type); + g_elfhead.iMachine = LH(head->e_machine); + g_elfhead.iVersion = LW(head->e_version); + g_elfhead.iEntry = LW(head->e_entry); + g_elfhead.iPhoff = LW(head->e_phoff); + g_elfhead.iShoff = LW(head->e_shoff); + g_elfhead.iFlags = LW(head->e_flags); + g_elfhead.iEhsize = LH(head->e_ehsize); + g_elfhead.iPhentsize = LH(head->e_phentsize); + g_elfhead.iPhnum = LH(head->e_phnum); + g_elfhead.iShentsize = LH(head->e_shentsize); + g_elfhead.iShnum = LH(head->e_shnum); + g_elfhead.iShstrndx = LH(head->e_shstrndx); + + if(g_verbose) + { + fprintf(stderr, "Magic %08X, Class %02X, Data %02X, Idver %02X\n", g_elfhead.iMagic, + g_elfhead.iClass, g_elfhead.iData, g_elfhead.iIdver); + fprintf(stderr, "Type %04X, Machine %04X, Version %08X, Entry %08X\n", g_elfhead.iType, + g_elfhead.iMachine, g_elfhead.iVersion, g_elfhead.iEntry); + fprintf(stderr, "Phoff %08X, Shoff %08X, Flags %08X, Ehsize %08X\n", g_elfhead.iPhoff, + g_elfhead.iShoff, g_elfhead.iFlags, g_elfhead.iEhsize); + fprintf(stderr, "Phentsize %04X, Phnum %04X\n", g_elfhead.iPhentsize, g_elfhead.iPhnum); + fprintf(stderr, "Shentsize %04X, Shnum %08X, Shstrndx %04X\n", g_elfhead.iShentsize, + g_elfhead.iShnum, g_elfhead.iShstrndx); + } + + if(g_elfhead.iMagic != ELF_MAGIC) + { + fprintf(stderr, "Error, invalid magic in the header\n"); + break; + } + + if((g_elfhead.iType != ELF_EXEC_TYPE) && (g_elfhead.iType != ELF_PRX_TYPE)) + { + fprintf(stderr, "Error, not EXEC type elf\n"); + break; + } + + if(g_elfhead.iMachine != ELF_MACHINE_MIPS) + { + fprintf(stderr, "Error, not MIPS type ELF\n"); + break; + } + + if(g_elfhead.iShnum < g_elfhead.iShstrndx) + { + fprintf(stderr, "Error, number of headers is less than section string index\n"); + break; + } + + ret = 1; + } + while(0); + + return ret; +} + +/* Load sections into ram */ +int load_sections(unsigned char *data) +{ + int ret = 0; + int found_rel = 0; + unsigned int load_addr = 0xFFFFFFFF; + + if(g_elfhead.iShnum > 0) + { + do + { + Elf32_Shdr *sect; + int i; + + g_elfsections = (struct ElfSection *) malloc(sizeof(struct ElfSection) * g_elfhead.iShnum); + if(g_elfsections == NULL) + { + fprintf(stderr, "Error, could not allocate memory for sections\n"); + break; + } + + memset(g_elfsections, 0, sizeof(struct ElfSection) * g_elfhead.iShnum); + + for(i = 0; i < g_elfhead.iShnum; i++) + { + sect = (Elf32_Shdr *) (g_elfdata + g_elfhead.iShoff + (i * g_elfhead.iShentsize)); + + g_elfsections[i].iName = LW(sect->sh_name); + g_elfsections[i].iType = LW(sect->sh_type); + g_elfsections[i].iAddr = LW(sect->sh_addr); + g_elfsections[i].iFlags = LW(sect->sh_flags); + g_elfsections[i].iOffset = LW(sect->sh_offset); + g_elfsections[i].iSize = LW(sect->sh_size); + g_elfsections[i].iLink = LW(sect->sh_link); + g_elfsections[i].iInfo = LW(sect->sh_info); + g_elfsections[i].iAddralign = LW(sect->sh_addralign); + g_elfsections[i].iEntsize = LW(sect->sh_entsize); + g_elfsections[i].iIndex = i; + + if(g_elfsections[i].iOffset != 0) + { + g_elfsections[i].pData = g_elfdata + g_elfsections[i].iOffset; + } + + if(g_elfsections[i].iFlags & SHF_ALLOC) + { + g_elfsections[i].blOutput = 1; + if(g_elfsections[i].iAddr < load_addr) + { + load_addr = g_elfsections[i].iAddr; + } + } + + if(((g_elfsections[i].iType == SHT_REL) || (g_elfsections[i].iType == SHT_PRXRELOC)) + && (g_elfsections[g_elfsections[i].iInfo].iFlags & SHF_ALLOC)) + { + g_elfsections[i].pRef = &g_elfsections[g_elfsections[i].iInfo]; + found_rel = 1; + } + } + + /* Okay so we have loaded all the sections, lets fix up the names */ + for(i = 0; i < g_elfhead.iShnum; i++) + { + strcpy(g_elfsections[i].szName, (char *) (g_elfsections[g_elfhead.iShstrndx].pData + g_elfsections[i].iName)); + if(strcmp(g_elfsections[i].szName, PSP_MODULE_INFO_NAME) == 0) + { + g_modinfo = &g_elfsections[i]; + } + else if(strcmp(g_elfsections[i].szName, PRX_LIBSTUB_SECT) == 0) + { + g_libstub = &g_elfsections[i]; + } + else if(strcmp(g_elfsections[i].szName, PRX_STUBTEXT_SECT) == 0) + { + g_stubtext = &g_elfsections[i]; + } + else if(strcmp(g_elfsections[i].szName, PRX_NID_SECT) == 0) + { + g_nid = &g_elfsections[i]; + } + } + + if(g_verbose) + { + for(i = 0; i < g_elfhead.iShnum; i++) + { + fprintf(stderr, "\nSection %d: %s\n", i, g_elfsections[i].szName); + fprintf(stderr, "Name %08X, Type %08X, Flags %08X, Addr %08X\n", + g_elfsections[i].iName, g_elfsections[i].iType, + g_elfsections[i].iFlags, g_elfsections[i].iAddr); + fprintf(stderr, "Offset %08X, Size %08X, Link %08X, Info %08X\n", + g_elfsections[i].iOffset, g_elfsections[i].iSize, + g_elfsections[i].iLink, g_elfsections[i].iInfo); + fprintf(stderr, "Addralign %08X, Entsize %08X pData %p\n", + g_elfsections[i].iAddralign, g_elfsections[i].iEntsize, + g_elfsections[i].pData); + } + + fprintf(stderr, "ELF Load Base address %08X\n", load_addr); + } + + if(g_modinfo == NULL) + { + fprintf(stderr, "Error, no sceModuleInfo section found\n"); + break; + } + + if(g_libstub == NULL) + { + fprintf(stderr, "Error, no .lib.stub section found\n"); + break; + } + + if(g_stubtext == NULL) + { + fprintf(stderr, "Error, no stub text section found\n"); + break; + } + + if(g_nid == NULL) + { + fprintf(stderr, "Error, no nid section found\n"); + break; + } + + ret = 1; + } + while(0); + } + else + { + fprintf(stderr, "Error, no sections in the ELF\n"); + } + + return ret; +} + +/* Load an ELF file */ +int load_elf(const char *elf) +{ + int ret = 0; + + do + { + g_elfdata = load_file(elf, &g_elfsize); + if(g_elfdata == NULL) + { + break; + } + + if(!validate_header(g_elfdata)) + { + break; + } + + if(!load_sections(g_elfdata)) + { + break; + } + + ret = 1; + } + while(0); + + return ret; +} + +/* Free allocated memory */ +void free_data(void) +{ + if(g_elfdata != NULL) + { + free(g_elfdata); + g_elfdata = NULL; + } + + if(g_elfsections != NULL) + { + free(g_elfsections); + g_elfsections = NULL; + } +} + +void strip_wsp(char *str) +{ + int len; + char *p; + + len = strlen(str); + while((len > 0) && (isspace(str[len-1]))) + { + str[--len] = 0; + } + + p = str; + while(isspace(*p)) + { + p++; + len--; + } + + memmove(str, p, len); + str[len] = 0; +} + +/* Load map file in + * File format is :- + * @LibraryName followed by 0 or more + * OLDNID=NEWNID [ Comment ] + * + * Read in badly :P + */ +int load_mapfile(const char *mapfile) +{ + int ret = 1; + char buf[1024]; + struct ImportMap *currmap = NULL; + int line = 0; + + if(mapfile != NULL) + { + do + { + FILE *fp; + + fp = fopen(mapfile, "r"); + if(fp != NULL) + { + while(fgets(buf, sizeof(buf), fp)) + { + line++; + strip_wsp(buf); + if((buf[0]) && (buf[0] != '#')) + { + if(buf[0] == '@') + { + struct ImportMap *temp; + + temp = (struct ImportMap *) malloc(sizeof(struct ImportMap)); + if(temp == NULL) + { + printf("Error allocating memory for import map\n"); + ret = 0; + break; + } + + memset(temp, 0, sizeof(struct ImportMap)); + if(currmap == NULL) + { + g_map = temp; + } + else + { + temp->next = currmap; + g_map = temp; + } + + currmap = temp; + if(buf[1]) + { + strncpy(currmap->name, &buf[1], 32); + currmap->name[31] = 0; + } + else + { + printf("Invalid library name at line %d\n", line); + break; + } + + if(g_verbose) + { + printf("Mapping library %s\n", currmap->name); + } + } + else + { + unsigned int oldnid; + unsigned int newnid; + char *endp; + + if(currmap->count == MAX_MAPNIDS) + { + printf("Error, number of defined nids exceed maximum\n"); + break; + } + + /* Hex data should be prefixed with 0 */ + if(buf[0] == '0') + { + errno = 0; + oldnid = strtoul(buf, &endp, 16); + if((errno != 0) || (*endp != ':')) + { + printf("Invalid NID entry on line %d\n", line); + continue; + } + } + else + { + unsigned char hash[SHA1_DIGEST_SIZE]; + + endp = strchr(buf, ':'); + if(endp == NULL) + { + printf("Invalid NID entry on line %d\n", line); + continue; + } + + sha1(hash, (unsigned char *) buf, endp-buf); + oldnid = hash[0] | (hash[1] << 8) | (hash[2] << 16) | (hash[3] << 24); + } + + newnid = strtoul(endp+1, &endp, 16); + if(g_verbose) + { + fprintf(stderr, "NID Mapping 0x%08X to 0x%08X\n", oldnid, newnid); + } + + currmap->nids[currmap->count].oldnid = oldnid; + currmap->nids[currmap->count].newnid = newnid; + currmap->count++; + } + } + } + fclose(fp); + } + } + while(0); + } + + return ret; +} + +#define MIPS_JR_31 0x03e00008 +#define MIPS_NOP 0x0 + +int fixup_imports(void) +{ + unsigned int *pText; + unsigned int *pNid; + struct PspModuleImport *pLastImport = NULL; + int count; + + /* First let's check the sizes are correct */ + if(g_stubtext->iSize != (g_nid->iSize * 2)) + { + fprintf(stderr, "Error, size of text section and nid section do not match\n"); + return 0; + } + + count = g_nid->iSize / 4; + pText = (unsigned int *) g_stubtext->pData; + pNid = (unsigned int *) g_nid->pData; + + if(g_verbose) + { + fprintf(stderr, "Import count %d\n", count); + } + + while(count > 0) + { + unsigned int stub_addr; + unsigned int stub_nid; + unsigned int sect_nid; + + stub_addr = LW(pText[0]); + stub_nid = LW(pText[1]); + sect_nid = LW(pNid[0]); + + /* Check if this is an original format NID */ + if((stub_addr != MIPS_JR_31) || (stub_nid != MIPS_NOP)) + { + struct PspModuleImport *pImport; + u16 func_count; + + if(g_verbose) + { + fprintf(stderr, "Found import to fixup. pStub %08X, Nid %08X, NidInSect %08X\n", stub_addr, stub_nid, sect_nid); + } + + if(stub_nid != sect_nid) + { + fprintf(stderr, "Error, unmatched NIDs\n"); + return 0; + } + + if((stub_addr < g_libstub->iAddr) || (stub_addr > (g_libstub->iAddr + g_libstub->iSize)) || (stub_addr & 3)) + { + fprintf(stderr, "Error, invalid stub address\n"); + return 0; + } + + pImport = (struct PspModuleImport *) (g_libstub->pData + (stub_addr - g_libstub->iAddr)); + if(g_verbose) + { + fprintf(stderr, "Import Stub %p, %08X, %08X, %02X, %02X, %04X, %08X, %08X\n", pImport, + LW(pImport->name), LW(pImport->flags), pImport->entry_size, pImport->var_count, + LH(pImport->func_count), LW(pImport->nids), LW(pImport->funcs)); + } + + func_count = LH(pImport->func_count); + + if(func_count == 0) + { + /* Setup the stub */ + SW(&pImport->nids, ((unsigned char *) pNid - g_nid->pData) + g_nid->iAddr); + SW(&pImport->funcs, ((unsigned char *) pText - g_stubtext->pData) + g_stubtext->iAddr); + } + else + { + if((pLastImport) && (pImport != pLastImport)) + { + fprintf(stderr, "Error, could not fixup imports, stubs out of order.\n"); + fprintf(stderr, "Ensure the SDK libraries are linked in last to correct this error\n"); + return 0; + } + } + + pLastImport = pImport; + func_count++; + SH(&pImport->func_count, func_count); + SW(&pText[0], MIPS_JR_31); + SW(&pText[1], MIPS_NOP); + } + else + { + /* Set last import to some value so we know if we have out of order stubs over a fixed stub table */ + pLastImport = (struct PspModuleImport *) pText; + } + + pText += 2; + pNid++; + count--; + } + + /* Should indicate no error occurred */ + if(count == 0) + { + if(g_verbose) + { + fprintf(stderr, "No libraries to fixup\n"); + } + } + + return 1; +} + +int fixup_nidmap(void) +{ + struct PspModuleImport *pImport; + int size; + + pImport = (struct PspModuleImport *) g_libstub->pData; + size = g_libstub->iSize; + + while(size >= sizeof(struct PspModuleImport)) + { + const char *str; + + str = (const char*) find_data(LW(pImport->name)); + if(str) + { + struct ImportMap *pMap; + + pMap = find_map_by_name(str); + if(pMap) + { + int count; + unsigned int *pNid; + + pNid = (unsigned int*) find_data(LW(pImport->nids)); + count = LH(pImport->func_count) + pImport->var_count; + + if(pNid && (count > 0)) + { + if(g_verbose) + { + fprintf(stderr, "Mapping library %s\n", str); + } + + while(count > 0) + { + int i; + + for(i = 0; i < pMap->count; i++) + { + unsigned oldnid, newnid; + + if(g_reversemap) + { + oldnid = pMap->nids[i].newnid; + newnid = pMap->nids[i].oldnid; + } + else + { + newnid = pMap->nids[i].newnid; + oldnid = pMap->nids[i].oldnid; + } + + if(oldnid == *pNid) + { + if(g_verbose) + { + fprintf(stderr, "Mapping 0x%08X to 0x%08X\n", oldnid, newnid); + } + + *pNid = newnid; + break; + } + } + + pNid++; + count--; + } + } + } + } + + pImport++; + size -= sizeof(struct PspModuleImport); + } + + return 1; +} + +int main(int argc, char **argv) +{ + int ret = 0; + + if(process_args(argc, argv)) + { + if(load_mapfile(g_mapfile) && load_elf(g_infile)) + { + if(fixup_imports() && fixup_nidmap()) + { + FILE *fp; + + fp = fopen(g_outfile, "wb"); + if(fp != NULL) + { + (void) fwrite(g_elfdata, 1, g_elfsize, fp); + fclose(fp); + } + else + { + fprintf(stderr, "Error, couldn't open %s for writing\n", g_outfile); + return 0; + } + } + else + { + ret = 1; + } + free_data(); + } + else + { + ret = 1; + } + } + else + { + print_help(); + ret = 1; + } + + return ret; +} diff --git a/tools/psp-prxgen.c b/tools/psp-prxgen.c new file mode 100644 index 00000000..659dd421 --- /dev/null +++ b/tools/psp-prxgen.c @@ -0,0 +1,941 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * psp-prxgen.c - Simple program to build a PRX file (and strip at the same time) + * + * Copyright (c) 2005 James Forshaw + * + * $Id: psp-prxgen.c 1520 2005-12-04 20:09:36Z tyranid $ + */ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "types.h" +#include "elftypes.h" +#include "prxtypes.h" + +/* Arrangement of ELF file after stripping + * + * ELF Header - 52 bytes + * Program Headers + * .text data + * .data data + * Section Headers + * Relocation data + * Section Header String Table + * + * When stripping the sections remove anything which isn't an allocated section or a relocation section. + * The section string section we will rebuild. + */ + +static const char *g_outfile; +static const char *g_infile; +static unsigned char *g_elfdata = NULL; +static struct ElfHeader g_elfhead = {0}; +static struct ElfSection *g_elfsections = NULL; +static struct ElfSection *g_modinfo = NULL; +static int g_out_sects = 2; +static int g_alloc_size = 0; +static int g_mem_size = 0; +static int g_reloc_size = 0; +static int g_str_size = 1; + +/* Base addresses in the Elf */ +static int g_phbase = 0; +static int g_allocbase = 0; +static int g_shbase = 0; +static int g_relocbase = 0; +static int g_shstrbase = 0; + +/* Specifies that the current usage is to the print the pspsdk path */ +static int g_verbose = 0; + +static struct option arg_opts[] = +{ + {"verbose", no_argument, NULL, 'v'}, + { NULL, 0, NULL, 0 } +}; + +/* Process the arguments */ +int process_args(int argc, char **argv) +{ + int ch; + + g_outfile = NULL; + g_infile = NULL; + + ch = getopt_long(argc, argv, "v", arg_opts, NULL); + while(ch != -1) + { + switch(ch) + { + case 'v' : g_verbose = 1; + break; + default : break; + }; + + ch = getopt_long(argc, argv, "v", arg_opts, NULL); + } + + argc -= optind; + argv += optind; + + if(argc < 2) + { + return 0; + } + + g_infile = argv[0]; + g_outfile = argv[1]; + + if(g_verbose) + { + fprintf(stderr, "Loading %s, outputting to %s\n", g_infile, g_outfile); + } + + return 1; +} + +void print_help(void) +{ + fprintf(stderr, "Usage: psp-prxgen [-v] infile.elf outfile.prx\n"); + fprintf(stderr, "Options:\n"); + fprintf(stderr, "-v, --verbose : Verbose output\n"); +} + +unsigned char *load_file(const char *file) +{ + FILE *fp; + unsigned int size; + unsigned char *data = NULL; + + do + { + fp = fopen(file, "rb"); + if(fp != NULL) + { + (void) fseek(fp, 0, SEEK_END); + size = ftell(fp); + rewind(fp); + + if(size < sizeof(Elf32_Ehdr)) + { + fprintf(stderr, "Error, invalid file size\n"); + break; + } + + data = (unsigned char *) malloc(size); + if(data == NULL) + { + fprintf(stderr, "Error, could not allocate memory for ELF\n"); + break; + } + + (void) fread(data, 1, size, fp); + fclose(fp); + } + else + { + fprintf(stderr, "Error, could not find file %s\n", file); + } + } + while(0); + + return data; +} + +/* Validate the ELF header */ +int validate_header(unsigned char *data) +{ + Elf32_Ehdr *head; + int ret = 0; + + head = (Elf32_Ehdr*) data; + + do + { + /* Read in the header structure */ + g_elfhead.iMagic = LW(head->e_magic); + g_elfhead.iClass = head->e_class; + g_elfhead.iData = head->e_data; + g_elfhead.iIdver = head->e_idver; + g_elfhead.iType = LH(head->e_type); + g_elfhead.iMachine = LH(head->e_machine); + g_elfhead.iVersion = LW(head->e_version); + g_elfhead.iEntry = LW(head->e_entry); + g_elfhead.iPhoff = LW(head->e_phoff); + g_elfhead.iShoff = LW(head->e_shoff); + g_elfhead.iFlags = LW(head->e_flags); + g_elfhead.iEhsize = LH(head->e_ehsize); + g_elfhead.iPhentsize = LH(head->e_phentsize); + g_elfhead.iPhnum = LH(head->e_phnum); + g_elfhead.iShentsize = LH(head->e_shentsize); + g_elfhead.iShnum = LH(head->e_shnum); + g_elfhead.iShstrndx = LH(head->e_shstrndx); + + if(g_verbose) + { + fprintf(stderr, "Magic %08X, Class %02X, Data %02X, Idver %02X\n", g_elfhead.iMagic, + g_elfhead.iClass, g_elfhead.iData, g_elfhead.iIdver); + fprintf(stderr, "Type %04X, Machine %04X, Version %08X, Entry %08X\n", g_elfhead.iType, + g_elfhead.iMachine, g_elfhead.iVersion, g_elfhead.iEntry); + fprintf(stderr, "Phoff %08X, Shoff %08X, Flags %08X, Ehsize %08X\n", g_elfhead.iPhoff, + g_elfhead.iShoff, g_elfhead.iFlags, g_elfhead.iEhsize); + fprintf(stderr, "Phentsize %04X, Phnum %04X\n", g_elfhead.iPhentsize, g_elfhead.iPhnum); + fprintf(stderr, "Shentsize %04X, Shnum %08X, Shstrndx %04X\n", g_elfhead.iShentsize, + g_elfhead.iShnum, g_elfhead.iShstrndx); + } + + if(g_elfhead.iMagic != ELF_MAGIC) + { + fprintf(stderr, "Error, invalid magic in the header\n"); + break; + } + + if((g_elfhead.iType != ELF_EXEC_TYPE) && (g_elfhead.iType != ELF_PRX_TYPE)) + { + fprintf(stderr, "Error, not EXEC type elf\n"); + break; + } + + if(g_elfhead.iMachine != ELF_MACHINE_MIPS) + { + fprintf(stderr, "Error, not MIPS type ELF\n"); + break; + } + + if(g_elfhead.iShnum < g_elfhead.iShstrndx) + { + fprintf(stderr, "Error, number of headers is less than section string index\n"); + break; + } + + ret = 1; + } + while(0); + + return ret; +} + +/* Load sections into ram */ +int load_sections(unsigned char *data) +{ + int ret = 0; + int found_rel = 0; + unsigned int load_addr = 0xFFFFFFFF; + + if(g_elfhead.iShnum > 0) + { + do + { + Elf32_Shdr *sect; + int i; + + g_elfsections = (struct ElfSection *) malloc(sizeof(struct ElfSection) * g_elfhead.iShnum); + if(g_elfsections == NULL) + { + fprintf(stderr, "Error, could not allocate memory for sections\n"); + break; + } + + memset(g_elfsections, 0, sizeof(struct ElfSection) * g_elfhead.iShnum); + + for(i = 0; i < g_elfhead.iShnum; i++) + { + sect = (Elf32_Shdr *) (g_elfdata + g_elfhead.iShoff + (i * g_elfhead.iShentsize)); + + g_elfsections[i].iName = LW(sect->sh_name); + g_elfsections[i].iType = LW(sect->sh_type); + g_elfsections[i].iAddr = LW(sect->sh_addr); + g_elfsections[i].iFlags = LW(sect->sh_flags); + g_elfsections[i].iOffset = LW(sect->sh_offset); + g_elfsections[i].iSize = LW(sect->sh_size); + g_elfsections[i].iLink = LW(sect->sh_link); + g_elfsections[i].iInfo = LW(sect->sh_info); + g_elfsections[i].iAddralign = LW(sect->sh_addralign); + g_elfsections[i].iEntsize = LW(sect->sh_entsize); + g_elfsections[i].iIndex = i; + + if(g_elfsections[i].iOffset != 0) + { + g_elfsections[i].pData = g_elfdata + g_elfsections[i].iOffset; + } + + if(g_elfsections[i].iFlags & SHF_ALLOC) + { + g_elfsections[i].blOutput = 1; + if(g_elfsections[i].iAddr < load_addr) + { + load_addr = g_elfsections[i].iAddr; + } + } + + if(((g_elfsections[i].iType == SHT_REL) || (g_elfsections[i].iType == SHT_PRXRELOC)) + && (g_elfsections[g_elfsections[i].iInfo].iFlags & SHF_ALLOC)) + { + g_elfsections[i].pRef = &g_elfsections[g_elfsections[i].iInfo]; + found_rel = 1; + g_elfsections[i].blOutput = 1; + } + } + + /* Okay so we have loaded all the sections, lets fix up the names */ + for(i = 0; i < g_elfhead.iShnum; i++) + { + strcpy(g_elfsections[i].szName, (char *) (g_elfsections[g_elfhead.iShstrndx].pData + g_elfsections[i].iName)); + if(strcmp(g_elfsections[i].szName, PSP_MODULE_INFO_NAME) == 0) + { + g_modinfo = &g_elfsections[i]; + } + else if(strcmp(g_elfsections[i].szName, PSP_MODULE_REMOVE_REL) == 0) + { + /* Don't output .rel.lib.stub relocations */ + g_elfsections[i].blOutput = 0; + } + } + + if(g_verbose) + { + for(i = 0; i < g_elfhead.iShnum; i++) + { + fprintf(stderr, "\nSection %d: %s\n", i, g_elfsections[i].szName); + fprintf(stderr, "Name %08X, Type %08X, Flags %08X, Addr %08X\n", + g_elfsections[i].iName, g_elfsections[i].iType, + g_elfsections[i].iFlags, g_elfsections[i].iAddr); + fprintf(stderr, "Offset %08X, Size %08X, Link %08X, Info %08X\n", + g_elfsections[i].iOffset, g_elfsections[i].iSize, + g_elfsections[i].iLink, g_elfsections[i].iInfo); + fprintf(stderr, "Addralign %08X, Entsize %08X pData %p\n", + g_elfsections[i].iAddralign, g_elfsections[i].iEntsize, + g_elfsections[i].pData); + } + + fprintf(stderr, "ELF Load Base address %08X\n", load_addr); + } + + if(g_modinfo == NULL) + { + fprintf(stderr, "Error, no sceModuleInfo section found\n"); + break; + } + + if(!found_rel) + { + fprintf(stderr, "Error, found no relocation sections\n"); + break; + } + + if(load_addr != 0) + { + fprintf(stderr, "Error, ELF not loaded to address 0 (%08X)\n", load_addr); + break; + } + + ret = 1; + } + while(0); + } + else + { + fprintf(stderr, "Error, no sections in the ELF\n"); + } + + return ret; +} + +int remove_weak_relocs(struct ElfSection *pReloc, struct ElfSection *pSymbol, struct ElfSection *pString) +{ + int iCount; + int iMaxSymbol; + void *pNewRel = NULL; + Elf32_Rel *pInRel; + Elf32_Rel *pOutRel; + Elf32_Sym *pSymData = (Elf32_Sym *) pSymbol->pData; + char *pStrData = NULL; + int iOutput; + int i; + + if(pString != NULL) + { + pStrData = (char *) pString->pData; + } + + iMaxSymbol = pSymbol->iSize / sizeof(Elf32_Sym); + iCount = pReloc->iSize / sizeof(Elf32_Rel); + + pNewRel = malloc(pReloc->iSize); + if(pNewRel == NULL) + { + return 0; + } + pOutRel = (Elf32_Rel *) pNewRel; + pInRel = (Elf32_Rel *) pReloc->pData; + iOutput = 0; + + if(g_verbose) + { + fprintf(stderr, "[%s] Processing %d relocations, %d symbols\n", pReloc->szName, iCount, iMaxSymbol); + } + + for(i = 0; i < iCount; i++) + { + int iSymbol; + + iSymbol = ELF32_R_SYM(LW(pInRel->r_info)); + if(g_verbose) + { + fprintf(stderr, "Relocation %d - Symbol %x\n", iOutput, iSymbol); + } + + if(iSymbol >= iMaxSymbol) + { + fprintf(stderr, "Warning: Ignoring relocation as cannot find matching symbol\n"); + } + else + { + if(g_verbose) + { + if(pStrData != NULL) + { + fprintf(stderr, "Symbol %d - Name %s info %x ndx %x\n", iSymbol, &pStrData[pSymData[iSymbol].st_name], + pSymData[iSymbol].st_info, pSymData[iSymbol].st_shndx); + } + else + { + fprintf(stderr, "Symbol %d - Name %d info %x ndx %x\n", iSymbol, pSymData[iSymbol].st_name, + pSymData[iSymbol].st_info, pSymData[iSymbol].st_shndx); + } + } + + if(LH(pSymData[iSymbol].st_shndx) == 0) + { + if(g_verbose) + { + fprintf(stderr, "Deleting relocation\n"); + } + } + else + { + /* We are keeping this relocation, copy it across */ + *pOutRel = *pInRel; + pOutRel++; + iOutput++; + } + } + + pInRel++; + } + + /* If we deleted some relocations */ + if(iOutput < iCount) + { + int iSize; + + iSize = iOutput * sizeof(Elf32_Rel); + if(g_verbose) + { + fprintf(stderr, "Old relocation size %d, new %d\n", pReloc->iSize, iSize); + } + pReloc->iSize = iSize; + /* If size is zero then delete this section */ + if(iSize == 0) + { + pReloc->blOutput = 0; + } + else + { + /* Copy across the new relocation data */ + memcpy(pReloc->pData, pNewRel, pReloc->iSize); + } + } + + free(pNewRel); + + return 1; +} + +/* Let's remove the weak relocations from the list */ +int process_relocs(void) +{ + int i; + + for(i = 0; i < g_elfhead.iShnum; i++) + { + if((g_elfsections[i].blOutput) && (g_elfsections[i].iType == SHT_REL)) + { + struct ElfSection *pReloc; + + pReloc = &g_elfsections[i]; + if((pReloc->iLink < g_elfhead.iShnum) && (g_elfsections[pReloc->iLink].iType == SHT_SYMTAB)) + { + struct ElfSection *pStrings = NULL; + struct ElfSection *pSymbols; + + pSymbols = &g_elfsections[pReloc->iLink]; + if((pSymbols->iLink < g_elfhead.iShnum) && (g_elfsections[pSymbols->iLink].iType == SHT_STRTAB)) + { + pStrings = &g_elfsections[pSymbols->iLink]; + } + + if(!remove_weak_relocs(pReloc, pSymbols, pStrings)) + { + return 0; + } + } + else + { + if(g_verbose) + { + fprintf(stderr, "Ignoring relocation section %d, invalid link number\n", i); + } + } + } + } + + return 1; +} + +/* Reindex the sections we are keeping */ +void reindex_sections(void) +{ + int i; + int sect = 1; + + for(i = 0; i < g_elfhead.iShnum; i++) + { + if(g_elfsections[i].blOutput) + { + g_elfsections[i].iIndex = sect++; + } + } +} + +/* Load an ELF file */ +int load_elf(const char *elf) +{ + int ret = 0; + + do + { + g_elfdata = load_file(elf); + if(g_elfdata == NULL) + { + break; + } + + if(!validate_header(g_elfdata)) + { + break; + } + + if(!load_sections(g_elfdata)) + { + break; + } + + if(!process_relocs()) + { + break; + } + + reindex_sections(); + + ret = 1; + } + while(0); + + return ret; +} + +int calculate_outsize(void) +{ + /* out_sects starts at two for the null section and the section string table */ + int out_sects = 2; + int alloc_size = 0; + int reloc_size = 0; + int mem_size = 0; + /* 1 for the NUL for the NULL section */ + int str_size = 1; + int i; + + /* Calculate how big our output file needs to be */ + /* We have elf header + 1 PH + allocated data + section headers + relocation data */ + + /* Note that the ELF should be based from 0, we use this to calculate the alloc and mem sizes */ + + /* Skip null section */ + for(i = 1; i < g_elfhead.iShnum; i++) + { + if(g_elfsections[i].blOutput) + { + if(g_elfsections[i].iType == SHT_PROGBITS) + { + unsigned int top_addr; + + top_addr = g_elfsections[i].iAddr + g_elfsections[i].iSize; + + if(top_addr > alloc_size) + { + alloc_size = top_addr; + } + + if(top_addr > mem_size) + { + mem_size = top_addr; + } + + out_sects++; + str_size += strlen(g_elfsections[i].szName) + 1; + } + else if((g_elfsections[i].iType == SHT_REL) || (g_elfsections[i].iType == SHT_PRXRELOC)) + { + /* Check this is a reloc for an allocated section */ + if(g_elfsections[g_elfsections[i].iInfo].iFlags & SHF_ALLOC) + { + reloc_size += g_elfsections[i].iSize; + out_sects++; + str_size += strlen(g_elfsections[i].szName) + 1; + } + } + else + { + unsigned int top_addr; + + top_addr = g_elfsections[i].iAddr + g_elfsections[i].iSize; + + if(top_addr > mem_size) + { + mem_size = top_addr; + } + + out_sects++; + str_size += strlen(g_elfsections[i].szName) + 1; + } + } + } + + alloc_size = (alloc_size + 3) & ~3; + mem_size = (mem_size + 3) & ~3; + str_size = (str_size + 3) & ~3; + str_size += strlen(ELF_SH_STRTAB) + 1; + + if(g_verbose) + { + fprintf(stderr, "Out_sects %d, alloc_size %d, reloc_size %d, str_size %d, mem_size %d\n", + out_sects, alloc_size, reloc_size, str_size, mem_size); + } + + /* Save them for future use */ + g_out_sects = out_sects; + g_alloc_size = alloc_size; + g_reloc_size = reloc_size; + g_mem_size = mem_size; + g_str_size = str_size; + + /* Lets build the offsets */ + g_phbase = sizeof(Elf32_Ehdr); + /* The allocated data needs to be 16 byte aligned */ + g_allocbase = (g_phbase + sizeof(Elf32_Shdr) + 0xF) & ~0xF; + g_shbase = g_allocbase + g_alloc_size; + g_relocbase = g_shbase + (g_out_sects * sizeof(Elf32_Shdr)); + g_shstrbase = g_relocbase + g_reloc_size; + + if(g_verbose) + { + fprintf(stderr, "PHBase %08X, AllocBase %08X, SHBase %08X\n", g_phbase, g_allocbase, g_shbase); + fprintf(stderr, "Relocbase %08X, Shstrbase %08X\n", g_relocbase, g_shstrbase); + fprintf(stderr, "Total size %d\n", g_shstrbase + g_str_size); + } + + return (g_shstrbase + g_str_size); +} + +/* Output the ELF header */ +void output_header(unsigned char *data) +{ + Elf32_Ehdr *head; + + head = (Elf32_Ehdr*) data; + + SW(&head->e_magic, g_elfhead.iMagic); + head->e_class = g_elfhead.iClass; + head->e_data = g_elfhead.iData; + head->e_idver = g_elfhead.iIdver; + SH(&head->e_type, ELF_PRX_TYPE); + SH(&head->e_machine, g_elfhead.iMachine); + SW(&head->e_version, g_elfhead.iVersion); + SW(&head->e_entry, g_elfhead.iEntry); + SW(&head->e_phoff, g_phbase); + SW(&head->e_shoff, g_shbase); + SW(&head->e_flags, g_elfhead.iFlags); + SH(&head->e_ehsize, sizeof(Elf32_Ehdr)); + SH(&head->e_phentsize, sizeof(Elf32_Phdr)); + SH(&head->e_phnum, 1); + SH(&head->e_shentsize, sizeof(Elf32_Shdr)); + SH(&head->e_shnum, g_out_sects); + SH(&head->e_shstrndx, g_out_sects-1); +} + +/* Output the program header */ +void output_ph(unsigned char *data) +{ + Elf32_Phdr *phdr; + struct PspModuleInfo *pModinfo; + int mod_flags; + + phdr = (Elf32_Phdr*) data; + pModinfo = (struct PspModuleInfo *) (g_modinfo->pData); + mod_flags = LW(pModinfo->flags); + + SW(&phdr->p_type, 1); + /* Starts after the program header */ + SW(&phdr->p_offset, g_allocbase); + SW(&phdr->p_vaddr, 0); + + /* Check if this is a kernel module */ + if(mod_flags & 0x1000) + { + SW(&phdr->p_paddr, 0x80000000 | (g_modinfo->iAddr + g_allocbase)); + } + else + { + SW(&phdr->p_paddr, (g_modinfo->iAddr + g_allocbase)); + } + SW(&phdr->p_filesz, g_alloc_size); + SW(&phdr->p_memsz, g_mem_size); + SW(&phdr->p_flags, 5); + SW(&phdr->p_align, 0x10); +} + +/* Output the allocated sections */ +void output_alloc(unsigned char *data) +{ + int i; + + for(i = 0; i < g_elfhead.iShnum; i++) + { + if((g_elfsections[i].blOutput) && (g_elfsections[i].iType == SHT_PROGBITS)) + { + memcpy(&data[g_elfsections[i].iAddr], g_elfsections[i].pData, g_elfsections[i].iSize); + } + } +} + +/* Output the section headers */ +void output_sh(unsigned char *data) +{ + unsigned int reloc_ofs; + unsigned int str_ofs; + Elf32_Shdr *shdr; + int i; + + shdr = (Elf32_Shdr*) data; + /* For the NULL section */ + shdr++; + memset(data, 0, g_out_sects * sizeof(Elf32_Shdr)); + + reloc_ofs = g_relocbase; + str_ofs = 1; + + for(i = 1; i < g_elfhead.iShnum; i++) + { + if(g_elfsections[i].blOutput) + { + SW(&shdr->sh_name, str_ofs); + str_ofs += strlen(g_elfsections[i].szName) + 1; + SW(&shdr->sh_flags, g_elfsections[i].iFlags); + SW(&shdr->sh_addr, g_elfsections[i].iAddr); + SW(&shdr->sh_size, g_elfsections[i].iSize); + SW(&shdr->sh_link, 0); + SW(&shdr->sh_addralign, g_elfsections[i].iAddralign); + SW(&shdr->sh_entsize, g_elfsections[i].iEntsize); + + if((g_elfsections[i].iType == SHT_REL) || (g_elfsections[i].iType == SHT_PRXRELOC)) + { + SW(&shdr->sh_type, SHT_PRXRELOC); + SW(&shdr->sh_info, g_elfsections[i].pRef->iIndex); + SW(&shdr->sh_offset, reloc_ofs); + reloc_ofs += g_elfsections[i].iSize; + } + else if(g_elfsections[i].iType == SHT_PROGBITS) + { + SW(&shdr->sh_type, g_elfsections[i].iType); + SW(&shdr->sh_info, 0); + SW(&shdr->sh_offset, g_allocbase + g_elfsections[i].iAddr); + } + else + { + SW(&shdr->sh_type, g_elfsections[i].iType); + SW(&shdr->sh_info, 0); + /* Point it to the end of the allocated section */ + SW(&shdr->sh_offset, g_allocbase + g_alloc_size); + } + + shdr++; + } + } + + /* Fill in the shstrtab section */ + SW(&shdr->sh_name, str_ofs); + SW(&shdr->sh_flags, 0); + SW(&shdr->sh_addr, 0); + SW(&shdr->sh_size, g_str_size); + SW(&shdr->sh_link, 0); + SW(&shdr->sh_addralign, 1); + SW(&shdr->sh_entsize, 0); + SW(&shdr->sh_type, SHT_STRTAB); + SW(&shdr->sh_info, 0); + SW(&shdr->sh_offset, g_shstrbase); +} + +/* Output relocations */ +void output_relocs(unsigned char *data) +{ + int i; + unsigned char *pReloc; + + pReloc = data; + + for(i = 0; i < g_elfhead.iShnum; i++) + { + if((g_elfsections[i].blOutput) && + ((g_elfsections[i].iType == SHT_REL) || (g_elfsections[i].iType == SHT_PRXRELOC))) + { + Elf32_Rel *rel; + int j, count; + + memcpy(pReloc, g_elfsections[i].pData, g_elfsections[i].iSize); + rel = (Elf32_Rel*) pReloc; + count = g_elfsections[i].iSize / sizeof(Elf32_Rel); + for(j = 0; j < count; j++) + { + unsigned int sym; + + /* Clear the top 24bits of the info */ + /* Kind of a dirty trick but hey :P */ + sym = LW(rel->r_info); + sym &= 0xFF; + SW(&rel->r_info, sym); + rel++; + } + pReloc += g_elfsections[i].iSize; + } + } +} + +/* Output the section header string table */ +void output_shstrtab(unsigned char *data) +{ + int i; + char *pData; + + /* For the NULL section, memory should be zeroed anyway */ + memset(data, 0, g_str_size); + pData = (char *) (data + 1); + + for(i = 1; i < g_elfhead.iShnum; i++) + { + if(g_elfsections[i].blOutput) + { + if(g_verbose) + { + fprintf(stderr, "String %d: %s\n", i, g_elfsections[i].szName); + } + + strcpy(pData, g_elfsections[i].szName); + pData += strlen(g_elfsections[i].szName) + 1; + } + } + + strcpy(pData, ELF_SH_STRTAB); +} + +/* Output a stripped prx file */ +int output_prx(const char *prxfile) +{ + int size; + unsigned char *data; + FILE *fp; + + do + { + size = calculate_outsize(); + data = (unsigned char *) malloc(size); + if(data == NULL) + { + fprintf(stderr, "Error, couldn't allocate output data\n"); + break; + } + + memset(data, 0, size); + + output_header(data); + output_ph(data + g_phbase); + output_alloc(data + g_allocbase); + output_sh(data + g_shbase); + output_relocs(data + g_relocbase); + output_shstrtab(data + g_shstrbase); + + fp = fopen(prxfile, "wb"); + if(fp != NULL) + { + fwrite(data, 1, size, fp); + fclose(fp); + } + else + { + fprintf(stderr, "Error, could not open output file %s\n", prxfile); + } + + free(data); + } + while(0); + + return 0; +} + +/* Free allocated memory */ +void free_data(void) +{ + if(g_elfdata != NULL) + { + free(g_elfdata); + g_elfdata = NULL; + } + + if(g_elfsections != NULL) + { + free(g_elfsections); + g_elfsections = NULL; + } +} + +int main(int argc, char **argv) +{ + if(process_args(argc, argv)) + { + if(load_elf(g_infile)) + { + (void) output_prx(g_outfile); + free_data(); + } + } + else + { + print_help(); + } + + return 0; +} diff --git a/tools/sha1.c b/tools/sha1.c new file mode 100644 index 00000000..6e2fa21f --- /dev/null +++ b/tools/sha1.c @@ -0,0 +1,282 @@ +/* + --------------------------------------------------------------------------- + Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and binary + form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + ALTERNATIVELY, provided that this notice is retained in full, this product + may be distributed under the terms of the GNU General Public License (GPL), + in which case the provisions of the GPL apply INSTEAD OF those given above. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and/or fitness for purpose. + --------------------------------------------------------------------------- + Issue Date: 18/06/2004 + + This is a byte oriented version of SHA1 that operates on arrays of bytes + stored in memory. +*/ + +#include /* for memcpy() etc. */ +#include /* for _lrotl with VC++ */ + +#include "sha1.h" + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/* + To obtain the highest speed on processors with 32-bit words, this code + needs to determine the order in which bytes are packed into such words. + The following block of code is an attempt to capture the most obvious + ways in which various environemnts specify their endian definitions. + It may well fail, in which case the definitions will need to be set by + editing at the points marked **** EDIT HERE IF NECESSARY **** below. +*/ + +/* PLATFORM SPECIFIC INCLUDES */ + +#define BRG_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */ +#define BRG_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */ + +#ifdef WORDS_BIGENDIAN +#define PLATFORM_BYTE_ORDER BRG_BIG_ENDIAN +#else +#define PLATFORM_BYTE_ORDER BRG_LITTLE_ENDIAN +#endif + +#ifdef _MSC_VER +#pragma intrinsic(memcpy) +#endif + +#if 0 && defined(_MSC_VER) +#define rotl32 _lrotl +#define rotr32 _lrotr +#else +#define rotl32(x,n) (((x) << n) | ((x) >> (32 - n))) +#define rotr32(x,n) (((x) >> n) | ((x) << (32 - n))) +#endif + +#if !defined(bswap_32) +#define bswap_32(x) ((rotr32((x), 24) & 0x00ff00ff) | (rotr32((x), 8) & 0xff00ff00)) +#endif + +#if (PLATFORM_BYTE_ORDER == BRG_LITTLE_ENDIAN) +#define SWAP_BYTES +#else +#undef SWAP_BYTES +#endif + +#if defined(SWAP_BYTES) +#define bsw_32(p,n) \ + { int _i = (n); while(_i--) ((sha1_32t*)p)[_i] = bswap_32(((sha1_32t*)p)[_i]); } +#else +#define bsw_32(p,n) +#endif + +#define SHA1_MASK (SHA1_BLOCK_SIZE - 1) + +#if 0 + +#define ch(x,y,z) (((x) & (y)) ^ (~(x) & (z))) +#define parity(x,y,z) ((x) ^ (y) ^ (z)) +#define maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + +#else /* Discovered by Rich Schroeppel and Colin Plumb */ + +#define ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) +#define parity(x,y,z) ((x) ^ (y) ^ (z)) +#define maj(x,y,z) (((x) & (y)) | ((z) & ((x) ^ (y)))) + +#endif + +/* Compile 64 bytes of hash data into SHA1 context. Note */ +/* that this routine assumes that the byte order in the */ +/* ctx->wbuf[] at this point is in such an order that low */ +/* address bytes in the ORIGINAL byte stream will go in */ +/* this buffer to the high end of 32-bit words on BOTH big */ +/* and little endian systems */ + +#ifdef ARRAY +#define q(v,n) v[n] +#else +#define q(v,n) v##n +#endif + +#define one_cycle(v,a,b,c,d,e,f,k,h) \ + q(v,e) += rotr32(q(v,a),27) + \ + f(q(v,b),q(v,c),q(v,d)) + k + h; \ + q(v,b) = rotr32(q(v,b), 2) + +#define five_cycle(v,f,k,i) \ + one_cycle(v, 0,1,2,3,4, f,k,hf(i )); \ + one_cycle(v, 4,0,1,2,3, f,k,hf(i+1)); \ + one_cycle(v, 3,4,0,1,2, f,k,hf(i+2)); \ + one_cycle(v, 2,3,4,0,1, f,k,hf(i+3)); \ + one_cycle(v, 1,2,3,4,0, f,k,hf(i+4)) + +void sha1_compile(sha1_ctx ctx[1]) +{ sha1_32t *w = ctx->wbuf; + +#ifdef ARRAY + sha1_32t v[5]; + memcpy(v, ctx->hash, 5 * sizeof(sha1_32t)); +#else + sha1_32t v0, v1, v2, v3, v4; + v0 = ctx->hash[0]; v1 = ctx->hash[1]; + v2 = ctx->hash[2]; v3 = ctx->hash[3]; + v4 = ctx->hash[4]; +#endif + +#define hf(i) w[i] + + five_cycle(v, ch, 0x5a827999, 0); + five_cycle(v, ch, 0x5a827999, 5); + five_cycle(v, ch, 0x5a827999, 10); + one_cycle(v,0,1,2,3,4, ch, 0x5a827999, hf(15)); \ + +#undef hf +#define hf(i) (w[(i) & 15] = rotl32( \ + w[((i) + 13) & 15] ^ w[((i) + 8) & 15] \ + ^ w[((i) + 2) & 15] ^ w[(i) & 15], 1)) + + one_cycle(v,4,0,1,2,3, ch, 0x5a827999, hf(16)); + one_cycle(v,3,4,0,1,2, ch, 0x5a827999, hf(17)); + one_cycle(v,2,3,4,0,1, ch, 0x5a827999, hf(18)); + one_cycle(v,1,2,3,4,0, ch, 0x5a827999, hf(19)); + + five_cycle(v, parity, 0x6ed9eba1, 20); + five_cycle(v, parity, 0x6ed9eba1, 25); + five_cycle(v, parity, 0x6ed9eba1, 30); + five_cycle(v, parity, 0x6ed9eba1, 35); + + five_cycle(v, maj, 0x8f1bbcdc, 40); + five_cycle(v, maj, 0x8f1bbcdc, 45); + five_cycle(v, maj, 0x8f1bbcdc, 50); + five_cycle(v, maj, 0x8f1bbcdc, 55); + + five_cycle(v, parity, 0xca62c1d6, 60); + five_cycle(v, parity, 0xca62c1d6, 65); + five_cycle(v, parity, 0xca62c1d6, 70); + five_cycle(v, parity, 0xca62c1d6, 75); + +#ifdef ARRAY + ctx->hash[0] += v[0]; ctx->hash[1] += v[1]; + ctx->hash[2] += v[2]; ctx->hash[3] += v[3]; + ctx->hash[4] += v[4]; +#else + ctx->hash[0] += v0; ctx->hash[1] += v1; + ctx->hash[2] += v2; ctx->hash[3] += v3; + ctx->hash[4] += v4; +#endif +} + +void sha1_begin(sha1_ctx ctx[1]) +{ + ctx->count[0] = ctx->count[1] = 0; + ctx->hash[0] = 0x67452301; + ctx->hash[1] = 0xefcdab89; + ctx->hash[2] = 0x98badcfe; + ctx->hash[3] = 0x10325476; + ctx->hash[4] = 0xc3d2e1f0; +} + +/* SHA1 hash data in an array of bytes into hash buffer and */ +/* call the hash_compile function as required. */ + +void sha1_hash(const unsigned char data[], unsigned long len, sha1_ctx ctx[1]) +{ sha1_32t pos = (sha1_32t)(ctx->count[0] & SHA1_MASK), + space = SHA1_BLOCK_SIZE - pos; + const unsigned char *sp = data; + + if((ctx->count[0] += len) < len) + ++(ctx->count[1]); + + while(len >= space) /* tranfer whole blocks if possible */ + { + memcpy(((unsigned char*)ctx->wbuf) + pos, sp, space); + sp += space; len -= space; space = SHA1_BLOCK_SIZE; pos = 0; + bsw_32(ctx->wbuf, SHA1_BLOCK_SIZE >> 2); + sha1_compile(ctx); + } + + memcpy(((unsigned char*)ctx->wbuf) + pos, sp, len); +} + +/* SHA1 final padding and digest calculation */ + +void sha1_end(unsigned char hval[], sha1_ctx ctx[1]) +{ sha1_32t i = (sha1_32t)(ctx->count[0] & SHA1_MASK); + + /* put bytes in the buffer in an order in which references to */ + /* 32-bit words will put bytes with lower addresses into the */ + /* top of 32 bit words on BOTH big and little endian machines */ + bsw_32(ctx->wbuf, (i + 3) >> 2); + + /* we now need to mask valid bytes and add the padding which is */ + /* a single 1 bit and as many zero bits as necessary. Note that */ + /* we can always add the first padding byte here because the */ + /* buffer always has at least one empty slot */ + ctx->wbuf[i >> 2] &= 0xffffff80 << 8 * (~i & 3); + ctx->wbuf[i >> 2] |= 0x00000080 << 8 * (~i & 3); + + /* we need 9 or more empty positions, one for the padding byte */ + /* (above) and eight for the length count. If there is not */ + /* enough space, pad and empty the buffer */ + if(i > SHA1_BLOCK_SIZE - 9) + { + if(i < 60) ctx->wbuf[15] = 0; + sha1_compile(ctx); + i = 0; + } + else /* compute a word index for the empty buffer positions */ + i = (i >> 2) + 1; + + while(i < 14) /* and zero pad all but last two positions */ + ctx->wbuf[i++] = 0; + + /* the following 32-bit length fields are assembled in the */ + /* wrong byte order on little endian machines but this is */ + /* corrected later since they are only ever used as 32-bit */ + /* word values. */ + ctx->wbuf[14] = (ctx->count[1] << 3) | (ctx->count[0] >> 29); + ctx->wbuf[15] = ctx->count[0] << 3; + sha1_compile(ctx); + + /* extract the hash value as bytes in case the hash buffer is */ + /* misaligned for 32-bit words */ + for(i = 0; i < SHA1_DIGEST_SIZE; ++i) + hval[i] = (unsigned char)(ctx->hash[i >> 2] >> (8 * (~i & 3))); +} + +void sha1(unsigned char hval[], const unsigned char data[], unsigned long len) +{ sha1_ctx cx[1]; + + sha1_begin(cx); sha1_hash(data, len, cx); sha1_end(hval, cx); +} + +#if defined(__cplusplus) +} +#endif diff --git a/tools/sha1.h b/tools/sha1.h new file mode 100644 index 00000000..0333b5c6 --- /dev/null +++ b/tools/sha1.h @@ -0,0 +1,84 @@ +/* + --------------------------------------------------------------------------- + Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and binary + form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + ALTERNATIVELY, provided that this notice is retained in full, this product + may be distributed under the terms of the GNU General Public License (GPL), + in which case the provisions of the GPL apply INSTEAD OF those given above. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and/or fitness for purpose. + --------------------------------------------------------------------------- + Issue Date: 26/08/2003 +*/ + +#ifndef _SHA1_H +#define _SHA1_H + +#include + +#define SHA1_BLOCK_SIZE 64 +#define SHA1_DIGEST_SIZE 20 + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/* define an unsigned 32-bit type */ + +#if defined(_MSC_VER) + typedef unsigned long sha1_32t; +#elif defined(ULONG_MAX) && ULONG_MAX == 0xfffffffful + typedef unsigned long sha1_32t; +#elif defined(UINT_MAX) && UINT_MAX == 0xffffffff + typedef unsigned int sha1_32t; +#else +# error Please define sha1_32t as an unsigned 32 bit type in sha1.h +#endif + +/* type to hold the SHA256 context */ + +typedef struct +{ sha1_32t count[2]; + sha1_32t hash[5]; + sha1_32t wbuf[16]; +} sha1_ctx; + +/* Note that these prototypes are the same for both bit and */ +/* byte oriented implementations. However the length fields */ +/* are in bytes or bits as appropriate for the version used */ +/* and bit sequences are input as arrays of bytes in which */ +/* bit sequences run from the most to the least significant */ +/* end of each byte */ + +void sha1_compile(sha1_ctx ctx[1]); + +void sha1_begin(sha1_ctx ctx[1]); +void sha1_hash(const unsigned char data[], unsigned long len, sha1_ctx ctx[1]); +void sha1_end(unsigned char hval[], sha1_ctx ctx[1]); +void sha1(unsigned char hval[], const unsigned char data[], unsigned long len); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/tools/types.h b/tools/types.h new file mode 100644 index 00000000..68ba4f04 --- /dev/null +++ b/tools/types.h @@ -0,0 +1,162 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * types.h - Definition of basic cross platform types. + * + * Copyright (c) 2005 James Forshaw + * + * $Id: types.h 2333 2007-10-31 19:37:40Z tyranid $ + */ + +#ifndef __TYPES_H__ +#define __TYPES_H__ + +#include "config.h" +#ifdef HAVE_STDINT_H +#include +#else +#ifdef HAVE_INTTYPES_H +#include +#else +#include +#define uint8_t u_int8_t +#define uint16_t u_int16_t +#define uint32_t u_int32_t +#define uint64_t u_int64_t +#endif +#endif + +/* Re-define some system types */ +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; +typedef int8_t s8; +typedef int16_t s16; +typedef int32_t s32; +typedef int64_t s64; + +#ifdef WORDS_BIGENDIAN +inline u32 lw_le(u32 data) +{ + u8 *ptr; + u32 val; + + ptr = (u8*) &data; + + val = ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24); + + return val; +} + +inline u16 lh_le(u16 data) +{ + u8 *ptr; + u16 val; + + ptr = (u8*) &data; + + val = ptr[0] | (ptr[1] << 8); + + return val; +} + +#define LW_LE(x) (lw_le((x))) +#define LW_BE(x) (x) +#define LH_LE(x) (lh_le((x))) +#define LH_BE(x) (x) + +#else + +inline u32 lw_be(u32 data) +{ + u8 *ptr; + u32 val; + + ptr = (u8*) &data; + + val = (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | ptr[3]; + + return val; +} + +inline u16 lh_be(u16 data) +{ + u8 *ptr; + u16 val; + + ptr = (u8*) &data; + + val = (ptr[0] << 16) | ptr[1]; + + return val; +} + +#define LW_LE(x) (x) +#define LW_BE(x) (lw_be((x))) +#define LH_LE(x) (x) +#define LH_BE(x) (lh_be((x))) + +#endif + +#define LW(x) (LW_LE(x)) +#define LH(x) (LH_LE(x)) + + +#ifdef WORDS_BIGENDIAN +inline void sw_le(u32 *data, u32 val) +{ + u8* ptr = (u8*) data; + + ptr[0] = (u8) (val & 0xFF); + ptr[1] = (u8) ((val >> 8) & 0xFF); + ptr[2] = (u8) ((val >> 16) & 0xFF); + ptr[3] = (u8) ((val >> 24) & 0xFF); +} + +inline void sh_le(u16 *data, u16 val) +{ + u8 *ptr = (u8*) data; + + ptr[0] = (u8) (val & 0xFF); + ptr[1] = (u8) ((val >> 8) & 0xFF); +} + +#define SW_LE(x, v) (sw_le((x), (v))) +#define SW_BE(x, v) (*(x) = (v)) +#define SH_LE(x, v) (sh_le((x), (v))) +#define SH_BE(x, v) (*(x) = (v)) + +#else + +inline void sw_be(u32 *data, u32 val) +{ + u8 *ptr = (u8*) data; + + ptr[0] = (u8) ((val >> 24) & 0xFF); + ptr[1] = (u8) ((val >> 16) & 0xFF); + ptr[2] = (u8) ((val >> 8) & 0xFF); + ptr[3] = (u8) (val & 0xFF); +} + +inline void sh_be(u16 *data, u16 val) +{ + u8* ptr = (u8*) data; + + ptr[0] = (u8) ((val >> 8) & 0xFF); + ptr[1] = (u8) (val & 0xFF); +} + +#define SW_LE(x, v) (*(x) = (v)) +#define SW_BE(x, v) (sw_be((x), (v))) +#define SH_LE(x, v) (*(x) = (v)) +#define SH_BE(x, v) (sh_be((x), (v))) + +#endif + +#define SW(x, v) (SW_LE(x, v)) +#define SH(x, v) (SH_LE(x, v)) + +#endif diff --git a/tools/unpack-pbp.c b/tools/unpack-pbp.c new file mode 100644 index 00000000..011a1959 --- /dev/null +++ b/tools/unpack-pbp.c @@ -0,0 +1,205 @@ +/* +# _____ ___ ____ ___ ____ +# ____| | ____| | | |____| +# | ___| | ___| ____| | \ PSPDEV Open Source Project. +#----------------------------------------------------------------------- +# (c) 2005 Dan Peori +# Licenced under Academic Free License version 2.0 +# Review pspsdk README & LICENSE files for further details. +# +# 2006-12-26 - Andrew Whatson +# - rewrote for easier reading +# - gave "correct" names to UNKNOWN.* files +# - improved memory efficiency with large PBPs +# - no longer outputs empty files +# +# $Id: unpack-pbp.c 2379 2008-04-08 21:18:58Z jim $ +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#ifdef HAVE_MALLOC_H +#include +#endif + +#ifdef WORDS_BIGENDIAN + +// Swap the bytes of an int for big-endian machines +static int swap_int(int n) +{ + return ((n >> 24) & 0xff) | ((n >> 8) & 0xff00) | ((n << 8) & 0xff0000) | ((n << 24) & 0xff000000); +} + +#endif + +// Struct to describe the header of a PBP file +typedef struct { + char signature[4]; + int version; + int offset[8]; +} HEADER; + +// Correct PBP signature +char correct_sig[4] = { + 0x00, + 0x50, // P + 0x42, // B + 0x50 // P +}; + +// Names of files included in a PBP +char *filename[8] = { + "PARAM.SFO", + "ICON0.PNG", + "ICON1.PMF", + "PIC0.PNG", + "PIC1.PNG", + "SND0.AT3", + "DATA.PSP", + "DATA.PSAR" +}; + +// Maximum size of read buffer +int maxbuffer = 16 * 1024 * 1024; + +int main(int argc, char *argv[]) { + FILE *infile; + FILE *outfile; + HEADER header; + int loop0; + int total_size; + + // Check for the correct number of arguments + if (argc != 2) { + printf("USAGE: %s \n", argv[0]); + return -1; + } + + // Open the specified PBP + infile = fopen(argv[1], "rb"); + if (infile == NULL) { + printf("ERROR: Could not open the input file. (%s)\n", argv[1]); + return -1; + } + + // Get the size of the PBP + fseek(infile, 0, SEEK_END); + total_size = ftell(infile); + fseek(infile, 0, SEEK_SET); + if (total_size < 0) { + printf("ERROR: Could not get the input file size.\n"); + return -1; + } + + // Read in the header + if (fread(&header, sizeof(HEADER), 1, infile) < 0) { + printf("ERROR: Could not read the input file header.\n"); + return -1; + } + + // Check the signature + for (loop0 = 0; loop0 < sizeof(correct_sig); loop0++) { + if (header.signature[loop0] != correct_sig[loop0]) { + printf("ERROR: Input file is not a PBP file.\n"); + return -1; + } + } + +#ifdef WORDS_BIGENDIAN + + // Swap the bytes of the offsets for big-endian machines + for (loop0 = 0; loop0 < 8; loop0++) { + header.offset[loop0] = swap_int(header.offset[loop0]); + } + +#endif + + // For each file in the PBP + for (loop0 = 0; loop0 < 8; loop0++) { + void *buffer; + int size; + + // Get the size of this file + if (loop0 == 7) { + size = total_size - header.offset[loop0]; + } else { + size = header.offset[loop0 + 1] - header.offset[loop0]; + } + + // Print out the file details + printf("[%d] %10d bytes | %s\n", loop0, size, filename[loop0]); + + // Skip the file if empty + if (!size) continue; + + // Seek to the proper position in the file + if (fseek(infile, header.offset[loop0], SEEK_SET) != 0) { + printf("ERROR: Could not seek in the input file.\n"); + return -1; + } + + // Open the output file + outfile = fopen(filename[loop0], "wb"); + if (outfile == NULL) { + printf("ERROR: Could not open the output file. (%s)\n", filename[loop0]); + return -1; + } + + do { + int readsize; + + // Make sure we don't exceed the maximum buffer size + if (size > maxbuffer) { + readsize = maxbuffer; + } else { + readsize = size; + } + size -= readsize; + + // Create the read buffer + buffer = malloc(readsize); + if (buffer == NULL) { + printf("ERROR: Could not allocate the section data buffer. (%d)\n", readsize); + return -1; + } + + // Read in the data from the PBP + if (fread(buffer, readsize, 1, infile) < 0) { + printf("ERROR: Could not read in the section data.\n"); + return -1; + } + + // Write the contents of the buffer to the output file + if (fwrite(buffer, readsize, 1, outfile) < 0) { + printf("ERROR: Could not write out the section data.\n"); + return -1; + } + + // Clean up the buffer + free(buffer); + + // Repeat if we haven't finished writing the file + } while (size); + + // Close the output file + if (fclose(outfile) < 0) { + printf("ERROR: Could not close the output file.\n"); + return -1; + } + + } + + // Close the PBP + if (fclose(infile) < 0) { + printf("ERROR: Could not close the input file.\n"); + return -1; + } + + // Exit successful + return 0; +}