diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml new file mode 100644 index 0000000..22e6fb1 --- /dev/null +++ b/.github/workflows/pages.yml @@ -0,0 +1,85 @@ +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +# Sample workflow for building and deploying a Jekyll site to GitHub Pages +name: Deploy Jekyll site to Pages + +on: + # Runs on pushes + push: + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: {} + schedule: + - cron: '0 18 * * FRI' + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. +# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + # Test the samples to make sure they build + test: + runs-on: ubuntu-latest + container: pspdev/pspdev:latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Build + run: | + cd _includes/samples + for SAMPLE_DIR in $(ls); do + echo "Building ${SAMPLE_DIR}..." + cd "${SAMPLE_DIR}" + psp-cmake . + make + cd .. + done + + # Build job + build: + runs-on: ubuntu-latest + needs: test + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.3' # Not needed with a .ruby-version file + bundler-cache: true # runs 'bundle install' and caches installed gems automatically + cache-version: 0 # Increment this number if you need to re-download cached gems + - name: Setup Pages + id: pages + uses: actions/configure-pages@v4 + - name: Build with Jekyll + # Outputs to the './_site' directory by default + run: bundle exec jekyll build --baseurl "${{ steps.pages.outputs.base_path }}" + env: + JEKYLL_ENV: production + - name: Upload artifact + # Automatically uploads an artifact from the './_site' directory by default + uses: actions/upload-pages-artifact@v3 + + # Deployment job, only runs for master branch + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + if: github.ref == 'refs/heads/master' + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..83a391e --- /dev/null +++ b/.gitignore @@ -0,0 +1,89 @@ +# Created by https://www.toptal.com/developers/gitignore/api/jekyll,ruby +# Edit at https://www.toptal.com/developers/gitignore?templates=jekyll,ruby + +### Jekyll ### +_site/ +.sass-cache/ +.jekyll-cache/ +.jekyll-metadata +# Ignore folders generated by Bundler +.bundle/ +vendor/ + +### Ruby ### +*.gem +*.rbc +/.config +/coverage/ +/InstalledFiles +/pkg/ +/spec/reports/ +/spec/examples.txt +/test/tmp/ +/test/version_tmp/ +/tmp/ + +# Used by dotenv library to load environment variables. +# .env + +# Ignore Byebug command history file. +.byebug_history + +## Specific to RubyMotion: +.dat* +.repl_history +build/ +*.bridgesupport +build-iPhoneOS/ +build-iPhoneSimulator/ + +## Specific to RubyMotion (use of CocoaPods): +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# vendor/Pods/ + +## Documentation cache and generated files: +/.yardoc/ +/_yardoc/ +/doc/ +/rdoc/ + +## Environment normalization: +/.bundle/ +/vendor/bundle +/lib/bundler/man/ + +# for a library or gem, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +Gemfile.lock +# .ruby-version +# .ruby-gemset + +# unless supporting rvm < 1.11.0 or doing something fancy, ignore this: +.rvmrc + +# Used by RuboCop. Remote config files pulled in from inherit_from directive. +# .rubocop-https?--* + +# End of https://www.toptal.com/developers/gitignore/api/jekyll,ruby + +# Sample build files +_includes/samples/*/CMakeFiles/ +_includes/samples/*/CMakeCache.txt +_includes/samples/*/Makefile +_includes/samples/*/cmake_install.cmake +_includes/samples/*/EBOOT.PBP +_includes/samples/*/PARAM.SFO +_includes/samples/*/*.prx +_includes/samples/audio/audio +_includes/samples/controls/controls +_includes/samples/hello/hello +_includes/samples/sdl2/sdl2 +_includes/samples/sdl2_mixer/sdl2_mixer +_includes/samples/sdl2_ttf/sdl2_ttf +_includes/samples/shape/shape + +# Editor files +.vscode/ \ No newline at end of file diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..a4bc029 --- /dev/null +++ b/Gemfile @@ -0,0 +1,8 @@ +source 'https://rubygems.org' + +gem "jekyll" # static site generator used +gem "just-the-docs" # Jekyll theme used +gem "jekyll-seo-tags" # adds SEO metadata to improve search engine visibility +gem "jekyll-github-metadata" # fetches repo data for use in Jekyll +gem "jekyll-include-cache" # caches included files to speed up site gen or load +gem "jekyll-sitemap" # generate sitemap to help search engines index the site diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..fdddb29 --- /dev/null +++ b/LICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +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 AUTHORS 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. + +For more information, please refer to diff --git a/README.md b/README.md index 8379b84..58fa25d 100644 --- a/README.md +++ b/README.md @@ -1,1225 +1,33 @@ -PSPDEV is an open source toolchain for Playstation Portable development. It allows you to make apps and games for both custom and official firmwares. This is a community project made by enthusiasts, it is in no way affiliated with Sony. +# website -# Getting started +Main repo of the PSPDEV GitHub Organization portal -## Installing +## Build locally -### dependencies - -The PSPDEV toolchain requires a couple of dependencies to be installed before use. - -#### Windows - -On Windows it is advised to use Ubuntu on Microsoft's WSL system. To set it up run the following commands in a Powershell window started as administrator: +First, follow the instructions for your system to install the dependencies for building on [this page](https://jekyllrb.com/docs/installation/). -``` -wsl --install +Clone this repo from the terminal: +```shell +git clone https://github.com/pspdev/pspdev.github.io.git ``` -Now run bash and run the following commands to install the dependencies: +Go to the just created directory in the terminal and enter the following commands to install all required gems: -``` -sudo apt-get update -sudo apt-get install build-essential cmake pkgconf libreadline8 libusb-0.1 libgpgme11 libarchive-tools fakeroot +```shell +bundle config set --local path 'vendor/bundle' +bundle install ``` -Going forwards, all commands will be run within bash. The filesystem of your Ubuntu installation can be accessed by opening the network location `\\wsl$`. - -#### Ubuntu - -On Ubuntu run the following commands to install the dependencies: - +To start the web server run: +```shell +bundle exec jekyll serve ``` -sudo apt-get update -sudo apt-get install build-essential cmake pkgconf libreadline8 libusb-0.1 libgpgme11 libarchive-tools fakeroot -``` - -#### MacOS - - -On MacOS make sure to install [Brew](https://brew.sh/) first, then run the following commands to install the dependencies: - -``` -brew install cmake pkgconf gnu-sed bash openssl libtool libarchive gettext texinfo bison flex gsl gmp mpfr -``` - - -### Toolchain - -To install the PSPDEV toolchain, first [download the latest version](https://github.com/pspdev/pspdev/releases/tag/latest) for your system. Extract it into your user's home directory, which would be `\\wsl$\home\username` on Windows, otherwise `~`. If you're on Windows, pick the Ubuntu build. - -Now set the required environment variables. On Mac edit the ``~/.bash_profile`` on Linux/WSL the ``~/.bashrc`` file. Add the following at the bottom: - -``` -export PSPDEV=~/pspdev -export PATH=$PATH:$PSPDEV/bin -``` - -This can simply be done with `nano ~/.bashrc`. To save press Ctrl+X, then press y, then enter/return twice. After that run `source ~/.bashrc` to apply the changes. - -That's it, now the PSPDEV toolchain can be used to build PSP software. Below are some examples of programs and how to run them. For testing on real hardware, check out [psplink](https://pspdev.github.io/psplinkusb/). - -## Basic programs - -Below are some basic examples of programs for the PSP. More can be found [here](https://github.com/pspdev/pspsdk/tree/master/src/samples). - -### Hello world - -![](images/hello.png?raw=true) - - -This is a simple Hello World program for the PSP. Click on the details below to see the code and how to build it. - -

- -main.c: - -
-#include <pspkernel.h>
-#include <pspdebug.h>
-#include <pspdisplay.h>
-
-// PSP_MODULE_INFO is required
-PSP_MODULE_INFO("Hello World", 0, 1, 0);
-PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER);
-
-int exit_callback(int arg1, int arg2, void *common)
-{
-    sceKernelExitGame();
-    return 0;
-}
-
-int callback_thread(SceSize args, void *argp)
-{
-    int cbid = sceKernelCreateCallback("Exit Callback",
-        exit_callback, NULL);
-    sceKernelRegisterExitCallback(cbid);
-    sceKernelSleepThreadCB();
-    return 0;
-}
-
-int setup_callbacks(void)
-{
-    int thid = sceKernelCreateThread("update_thread",
-        callback_thread, 0x11, 0xFA0, 0, 0);
-
-    if(thid >= 0)
-        sceKernelStartThread(thid, 0, 0);
-    return thid;
-}
-
-int main(void) 
-{
-    // Use above functions to make exiting possible
-    setup_callbacks();
-    
-    // Print Hello World! on a debug screen on a loop
-    pspDebugScreenInit();
-    while(1)
-    {
-        pspDebugScreenSetXY(0, 0);
-        pspDebugScreenPrintf("Hello World!");
-        sceDisplayWaitVblankStart();
-    }
-
-    return 0;
-}
-
- -CMakeLists.txt: - -
-cmake_minimum_required(VERSION 3.0)
-
-project(hello)
-
-add_executable(${PROJECT_NAME} main.c)
-
-target_link_libraries(${PROJECT_NAME} PRIVATE
-    pspdebug
-    pspdisplay
-    pspge
-)
-
-# Create an EBOOT.PBP file
-create_pbp_file(
-    TARGET ${PROJECT_NAME}
-    ICON_PATH NULL
-    BACKGROUND_PATH NULL
-    PREVIEW_PATH NULL
-    TITLE ${PROJECT_NAME}
-)
-
- -Building can be done with: - -
-mkdir build && cd build
-psp-cmake ..
-make
-
- -This will result in an EBOOT.PBP file in the build directory. Put it in a directory in ms0:/PSP/GAME/ and the PSP can run it. -

- -### Drawing shapes - -![](images/shape.png?raw=true) - -This is a simple square drawn on the PSP. It uses the native libgu library. Click on the details below to see the code and how to build it. - -

- -main.c: - -
-#include <pspkernel.h>
-#include <pspgu.h>
-
-PSP_MODULE_INFO("gutest", 0, 1, 0);
-PSP_MAIN_THREAD_ATTR(THREAD_ATTR_VFPU | THREAD_ATTR_USER);
-
-#define BUFFER_WIDTH 512
-#define BUFFER_HEIGHT 272
-#define SCREEN_WIDTH 480
-#define SCREEN_HEIGHT BUFFER_HEIGHT
-
-char list[0x20000] __attribute__((aligned(64)));
-
-void initGu(){
-    sceGuInit();
-
-    //Set up buffers
-    sceGuStart(GU_DIRECT, list);
-    sceGuDrawBuffer(GU_PSM_8888,(void*)0,BUFFER_WIDTH);
-    sceGuDispBuffer(SCREEN_WIDTH,SCREEN_HEIGHT,(void*)0x88000,BUFFER_WIDTH);
-    sceGuDepthBuffer((void*)0x110000,BUFFER_WIDTH);
-
-    //Set up viewport
-    sceGuOffset(2048 - (SCREEN_WIDTH / 2), 2048 - (SCREEN_HEIGHT / 2));
-    sceGuViewport(2048, 2048, SCREEN_WIDTH, SCREEN_HEIGHT);
-    sceGuEnable(GU_SCISSOR_TEST);
-    sceGuScissor(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
-
-    //Set some stuff
-    sceGuDepthRange(65535, 0); //Use the full buffer for depth testing - buffer is reversed order
-
-    sceGuDepthFunc(GU_GEQUAL); //Depth buffer is reversed, so GEQUAL instead of LEQUAL
-    sceGuEnable(GU_DEPTH_TEST); //Enable depth testing
-
-    sceGuFinish();
-    sceGuDisplay(GU_TRUE);
-}
-
-void endGu(){
-    sceGuDisplay(GU_FALSE);
-    sceGuTerm();
-}
-
-void startFrame(){
-    sceGuStart(GU_DIRECT, list);
-    sceGuClearColor(0xFFFFFFFF); // White background
-    sceGuClear(GU_COLOR_BUFFER_BIT);
-}
-
-void endFrame(){
-    sceGuFinish();
-    sceGuSync(0, 0);
-    sceDisplayWaitVblankStart();
-    sceGuSwapBuffers();
-}
-
-typedef struct {
-    unsigned short u, v;
-    short x, y, z;
-} Vertex;
-
-void drawRect(float x, float y, float w, float h) {
-
-    Vertex* vertices = (struct Vertex*)sceGuGetMemory(2 * sizeof(Vertex));
-
-    vertices[0].x = x;
-    vertices[0].y = y;
-
-    vertices[1].x = y + w;
-    vertices[1].y = x + h;
-
-    sceGuColor(0xFF0000FF); // Red, colors are ABGR
-    sceGuDrawArray(GU_SPRITES, GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 2, 0, vertices);
-}
-
-
-int main() {
-    initGu();
-    int running = 1;
-    while(running){
-        startFrame();
-
-        drawRect(32, 32, 64, 64);
-
-        endFrame();
-    }
-
-    return 0;
-}
-
- -CMakeLists.txt: - -
-cmake_minimum_required(VERSION 3.0)
-
-project(shape)
-
-add_executable(${PROJECT_NAME} main.c)
-
-target_link_libraries(${PROJECT_NAME} PRIVATE
-    pspgu
-    pspge
-    pspdisplay
-)
-
-# Create an EBOOT.PBP file
-create_pbp_file(
-    TARGET ${PROJECT_NAME}
-    ICON_PATH NULL
-    BACKGROUND_PATH NULL
-    PREVIEW_PATH NULL
-    TITLE ${PROJECT_NAME}
-)
-
- -Building can be done with: - -
-mkdir build && cd build
-psp-cmake ..
-make
-
- -

This will result in an EBOOT.PBP file in the build directory. Put it in a directory in ms0:/PSP/GAME/ and the PSP can run it.

- -More libgu examples can be found here. - -

- -### Controller - -![](images/controls.png?raw=true) - -This is a simple program to use the PSP controller. Click on details below to see the code and how to build it. - -

- -main.c: - -
-#include <pspkernel.h>
-#include <pspdebug.h>
-#include <pspctrl.h>
-#include <stdlib.h>
-#include <string.h>
-
-PSP_MODULE_INFO("Controller", 0, 1, 1);
-
-PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU);
-
-#define printf pspDebugScreenPrintf
-
-int done = 0;
-
-int exit_callback(int arg1, int arg2, void *common)
-{
-    done = 1;
-    return 0;
-}
-
-int callback_thread(SceSize args, void *argp)
-{
-    int cbid = sceKernelCreateCallback("Exit Callback",
-        exit_callback, NULL);
-    sceKernelRegisterExitCallback(cbid);
-    sceKernelSleepThreadCB();
-    return 0;
-}
-
-int setup_callbacks(void)
-{
-    int thid = sceKernelCreateThread("update_thread",
-        callback_thread, 0x11, 0xFA0, 0, 0);
-
-    if(thid >= 0)
-        sceKernelStartThread(thid, 0, 0);
-    return thid;
-}
-
-int main(void)
-{
-    SceCtrlData pad;
-
-    pspDebugScreenInit();
-    setup_callbacks();
-
-    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("Circle pressed! \n");
-            }
-            if (pad.Buttons & PSP_CTRL_CROSS)
-            {
-                printf("Cross pressed! \n");
-            }
-
-            if (pad.Buttons & PSP_CTRL_UP)
-            {
-                printf("Up direction pad pressed! \n");
-            }
-            if (pad.Buttons & PSP_CTRL_DOWN)
-            {
-                printf("Down direction pad pressed! \n");
-            }
-            if (pad.Buttons & PSP_CTRL_LEFT)
-            {
-                printf("Left direction pad pressed! \n");
-            }
-            if (pad.Buttons & PSP_CTRL_RIGHT)
-            {
-                printf("Right direction pad pressed! \n");
-            }
-        }
-    }
-
-    sceKernelExitGame();
-    return 0;
-}
-
- -CMakeLists.txt: - -
-cmake_minimum_required(VERSION 3.0)
-
-project(controls)
-
-add_executable(${PROJECT_NAME} main.c)
-
-target_link_libraries(${PROJECT_NAME} PRIVATE
-    pspdebug
-    pspdisplay
-    pspge
-    pspctrl
-)
-
-# Create an EBOOT.PBP file
-create_pbp_file(
-    TARGET ${PROJECT_NAME}
-    ICON_PATH NULL
-    BACKGROUND_PATH NULL
-    PREVIEW_PATH NULL
-    TITLE ${PROJECT_NAME}
-)
-
- -Building can be done with: - -
-mkdir build && cd build
-psp-cmake ..
-make
-
- -

This will result in an EBOOT.PBP file in the build directory. Put it in a directory in ms0:/PSP/GAME/ and the PSP can run it.

- -

- -### Audio - -![](images/audio.png?raw=true) - -This is a simple program to use the audio of the PSP with minimal effort. It uses native audio library. Click on the details below to see the code and how to build it. - -

- -main.c: - -
-#include <pspkernel.h>
-#include <pspdebug.h>
-#include <pspaudiolib.h>
-#include <pspaudio.h>
-#include <pspdisplay.h>
-#include <pspctrl.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include <limits.h>
-
-PSP_MODULE_INFO("audio", 0, 1, 1);
-PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU);
-
-#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;
-}
-
-/* Main code */
-
-const float PI = 3.1415926535897932f;
-const int sampleRate = 44100;
-float frequency = 440.0f;
-float currentTime = 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) {
-            currentTime *= (freq0 / frequency);
-    }
-    for (i = 0; i < length; i++) {
-        short s = (short) (scaleFactor * currentFunction(2.0f * PI * frequency * currentTime));
-        ubuf[i].l = s;
-        ubuf[i].r = s;
-        currentTime += sampleLength;
-    }
-    if (currentTime * frequency > 1.0f) {
-        double d;
-        currentTime = modf(currentTime * frequency, &d) / frequency;
-    }
-
-    freq0 = frequency;
-}
-
-/* Read the analog stick and adjust the frequency */
-void controlFrequency(void) {
-    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;
-}
-
- -CMakeLists.txt: - -
-cmake_minimum_required(VERSION 3.0)
-
-project(audio)
-
-add_executable(${PROJECT_NAME} main.c)
-
-target_link_libraries(${PROJECT_NAME} PRIVATE
-    pspdebug
-    pspdisplay
-    pspge
-    pspctrl
-    pspaudio
-    pspaudiolib
-    psputility
-)
-
-# Create an EBOOT.PBP file
-create_pbp_file(
-    TARGET ${PROJECT_NAME}
-    ICON_PATH NULL
-    BACKGROUND_PATH NULL
-    PREVIEW_PATH NULL
-    TITLE ${PROJECT_NAME}
-)
-
- -Building can be done with: - -
-mkdir build && cd build
-psp-cmake ..
-make
-
- -

This will result in an EBOOT.PBP file in the build directory. Put it in a directory in ms0:/PSP/GAME/ and the PSP can run it.

- -More audiolib examples can be found here. - -

- -### Using SDL2 - -![](images/sdl2.png?raw=true) - -SDL2 is a library which handles system specific things like input, audio and window management for you. It can also be used to render shapes and images, just like the native libgu. This will be slower, but will result in code that can be run more easily on multiple platforms. Click on details below for the to see the code and how to build it. - -

- -main.c: - -
-#include <SDL.h>
-
-int main(int argc, char *argv[])
-{
-    SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER);
-
-    SDL_Window * window = SDL_CreateWindow(
-        "window",
-        SDL_WINDOWPOS_UNDEFINED,
-        SDL_WINDOWPOS_UNDEFINED,
-        480,
-        272,
-        0
-    );
-
-    SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
-
-    SDL_Rect square = {216, 96, 34, 64}; 
-
-    int running = 1;
-    SDL_Event event;
-    while (running) { 
-        if (SDL_PollEvent(&event)) {
-            switch (event.type) {
-                case SDL_QUIT:
-                    running = 0;
-                    break;
-                case SDL_CONTROLLERDEVICEADDED:
-                    SDL_GameControllerOpen(event.cdevice.which);
-                    break;
-                case SDL_CONTROLLERBUTTONDOWN:
-                    if(event.cbutton.button == SDL_CONTROLLER_BUTTON_START)
-                        running = 0;
-                    break;
-            }
-        }
-
-        // Clear the screen
-        SDL_RenderClear(renderer);
-
-        // Draw a red square
-        SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
-        SDL_RenderFillRect(renderer, &square);
-
-        // Draw everything on a white background
-        SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
-        SDL_RenderPresent(renderer);
-    }
-
-    return 0;
-}
-
- -CMakeLists.txt: - -
-cmake_minimum_required(VERSION 3.0)
-
-project(square)
-
-add_executable(${PROJECT_NAME} main.c)
-
-find_package(SDL2 REQUIRED)
-
-target_include_directories(${PROJECT_NAME} PRIVATE ${SDL2_INCLUDE_DIRS})
-
-target_link_libraries(${PROJECT_NAME} PRIVATE
-    ${SDL2_LIBRARIES}
-)
-
-if(PSP)
-    create_pbp_file(
-        TARGET ${PROJECT_NAME}
-        ICON_PATH NULL
-        BACKGROUND_PATH NULL
-        PREVIEW_PATH NULL
-        TITLE ${PROJECT_NAME}
-    )
-endif()
-
- -Building can be done with: - -
-mkdir build && cd build
-psp-cmake ..
-make
-
- -

This will result in an EBOOT.PBP` file in the build directory. Put it in a directory in ms0:/PSP/GAME/ and the PSP can run it.

- -If you have sdl2 dev package and a compiler installed this code will also build on Linux for Linux by running: - -
-mkdir build && cd build
-cmake ..
-make
-
- -More documentation on SDL can be found here. - -

- -### Using SDL2 mixer - -![](images/sdl2_mixer.png?raw=true) - -This is a simple program to use the SDL2_mixer library. Click on details below to see the code and how to build it. - -

- -main.c: - -
-#include <SDL2/SDL.h>
-#include <SDL2/SDL_mixer.h>
-
-// Define MIN macro
-#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
-
-// Define screen dimensions
-#define SCREEN_WIDTH    480
-#define SCREEN_HEIGHT   272
-
-// audio file path
-#define MUSIC_PATH "ms0:/MUSIC/test.ogg" // ogg/mp3 file format
-
-int main(int argc, char **argv) {
-    (void)argc;
-    (void)argv;
-
-    // Initialize sdl
-    SDL_Init(SDL_INIT_VIDEO |
-        SDL_INIT_AUDIO |
-        SDL_INIT_GAMECONTROLLER
-    );
-
-    // Initialize sdl2_mixer
-    Mix_OpenAudio(44100, 
-        MIX_DEFAULT_FORMAT, 
-        MIX_DEFAULT_CHANNELS, 
-        2048
-    );
-
-    // create window
-    SDL_Window *win = SDL_CreateWindow(
-        "psp_win",
-        SDL_WINDOWPOS_UNDEFINED,
-        SDL_WINDOWPOS_UNDEFINED,
-        SCREEN_WIDTH,
-        SCREEN_HEIGHT,
-        0
-    );
-
-    // Create Renderer
-    SDL_Renderer *renderer = SDL_CreateRenderer(
-        win, -1, 0
-    );
-
-    // Load ogg file
-    Mix_Music *ogg_file = NULL;
-    ogg_file = Mix_LoadMUS(MUSIC_PATH);
-    if (!ogg_file) {
-        return 0;
-    }
-
-    SDL_Rect rect;
-
-    // Square dimensions: Half of the min(SCREEN_WIDTH, SCREEN_HEIGHT)
-    rect.w = MIN(SCREEN_WIDTH, SCREEN_HEIGHT) / 2;
-    rect.h = MIN(SCREEN_WIDTH, SCREEN_HEIGHT) / 2;
-
-    // Square position: In the middle of the screen
-    rect.x = SCREEN_WIDTH / 2 - rect.w / 2;
-    rect.y = SCREEN_HEIGHT / 2 - rect.h / 2;
-
-
-    // Declare rects of pause symbol
-    SDL_Rect pause_rect1, pause_rect2;
-
-    pause_rect1.h = rect.h / 2;
-    pause_rect1.w = 40;
-    pause_rect1.x = rect.x + (rect.w - pause_rect1.w * 3) / 2;
-    pause_rect1.y = rect.y + rect.h / 4;
-    pause_rect2 = pause_rect1;
-    pause_rect2.x += pause_rect1.w * 2;
-    
-    // play the music 8 times
-    if (Mix_PlayMusic(ogg_file, 8) == -1) {
-        return 0;
-    }
-
-    int running = 1;
-    SDL_Event e;
-    while (running) {
-        if(SDL_PollEvent(&e)) {
-            switch(e.type) {
-                case SDL_QUIT:
-                    running = 0;
-                break;
-                case SDL_CONTROLLERDEVICEADDED:
-                    SDL_GameControllerOpen(e.cdevice.which);
-                break;
-                case SDL_CONTROLLERBUTTONDOWN:
-                    // pause using cross button
-                    if (e.cbutton.button == SDL_CONTROLLER_BUTTON_A) {
-                        Mix_PauseMusic();
-                    // resume using circle button
-                    } else if (e.cbutton.button == SDL_CONTROLLER_BUTTON_B) {
-                        Mix_ResumeMusic();
-                    }	
-                    // press start button to exit
-                    if (e.cbutton.button == SDL_CONTROLLER_BUTTON_START) {
-                        running = 0;
-                    }
-            break;		
-            }
-        }
-
-        // Initialize renderer color black for the background
-        SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
-
-        // Clear screen
-        SDL_RenderClear(renderer);
-
-        // Set renderer color green to draw the square
-        SDL_SetRenderDrawColor(renderer, 0, 0xFF, 0, 0xFF);
-
-        // Draw filled square
-        SDL_RenderFillRect(renderer, &rect);
-
-        // Check pause status
-        if(Mix_PausedMusic()) {
-            // Set renderer color black to draw the pause symbol
-            SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
-
-            // Draw pause symbol
-            SDL_RenderFillRect(renderer, &pause_rect1);
-             SDL_RenderFillRect(renderer, &pause_rect2);
-        }
-
-        // Update screen
-        SDL_RenderPresent(renderer);
-    }
-
-    Mix_FreeMusic(ogg_file);
-    SDL_DestroyRenderer(renderer);
-    SDL_DestroyWindow(win);
-    Mix_CloseAudio();
-    SDL_Quit();
-
-    return 0;
-}
-
- -CMakeLists.txt: - -
-cmake_minimum_required(VERSION 3.0)
-
-project(sdl2_mixer)
-
-add_executable(${PROJECT_NAME} main.c)
-
-find_package(SDL2 REQUIRED)
-
-target_include_directories(${PROJECT_NAME} PRIVATE ${SDL2_INCLUDE_DIRS})
-
-target_link_libraries(${PROJECT_NAME} PRIVATE
-    ${SDL2_LIBRARIES}
-)
-
-if(PSP)
-    target_link_libraries(${PROJECT_NAME} PRIVATE
-        SDL2_mixer
-        SDL2
-        vorbisfile
-        vorbis
-        ogg
-        xmp
-    )
-    create_pbp_file(
-        TARGET ${PROJECT_NAME}
-        ICON_PATH NULL
-        BACKGROUND_PATH NULL
-        PREVIEW_PATH NULL
-        TITLE ${PROJECT_NAME}
-    )
-endif()
-
- -Building can be done with: - -
-mkdir build && cd build
-psp-cmake ..
-make
-
- -

This will result in an EBOOT.PBP file in the build directory. Put it in a directory in ms0:/PSP/GAME/ and you need an audio file to test the program, download it from here. Put it in a directory in ms0:/MUSIC/ and then rename the audio file same as name on your MUSIC_PATH macro in your C code and the PSP can run it.

- -

- -### Using SDL2 ttf - -![](images/sdl2_ttf.jpg?raw=true) - -This is a simple program to use the SDL2_ttf library. Click on details below to see the code and how to build it. - -

- -main.c: - -
-#include <stdio.h>
-
-#include <SDL2/SDL.h>
-#include <SDL2/SDL_ttf.h>
-
-// Define screen dimensions
-#define SCREEN_WIDTH 480
-#define SCREEN_HEIGHT 272
-
-int main(int argc, char **argv)
-{
-    (void)argc;
-    (void)argv;
-
-    // Initialize SDL2
-    if (SDL_Init(SDL_INIT_VIDEO) < 0)
-    {
-        printf("SDL2 could not be initialized!\n"
-               "SDL2 Error: %s\n",
-               SDL_GetError());
-        return 0;
-    }
-
-    // Initialize SDL2_ttf
-    if (TTF_Init() < 0)
-    {
-        printf("SDL2_ttf could not be initialized!\n"
-               "SDL2_ttf Error: %s\n",
-               SDL_GetError());
-        return 0;
-    }
-
-    SDL_Window *win = SDL_CreateWindow(
-        "window",
-        SDL_WINDOWPOS_UNDEFINED,
-        SDL_WINDOWPOS_UNDEFINED,
-        SCREEN_WIDTH,
-        SCREEN_HEIGHT,
-        0);
-
-    if (!win)
-    {
-        printf("Window could not be created!\n"
-               "SDL_Error: %s\n",
-               SDL_GetError());
-    }
-
-    SDL_Renderer *renderer = SDL_CreateRenderer(win, -1, 0);
-    TTF_Font *font = TTF_OpenFont("Pacifico.ttf", 40);
-
-    // Set the text and background color
-    SDL_Color text_color = {0xff, 0xff, 0xff, 0xff};
-    SDL_Color bg_color = {0x00, 0x00, 0x00, 0xff};
-
-    SDL_Rect text_rect;
-    SDL_Surface *surface = TTF_RenderText(font, "Hello World!", text_color, bg_color);
-    SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
-
-    // Get text dimensions
-    text_rect.w = surface->w;
-    text_rect.h = surface->h;
-
-    SDL_FreeSurface(surface);
-
-    text_rect.x = (SCREEN_WIDTH - text_rect.w) / 2;
-    text_rect.y = text_rect.h + 30;
-
-    int running = 1;
-    SDL_Event e;
-    while (running)
-    {
-        if (SDL_PollEvent(&e))
-        {
-            switch (e.type)
-            {
-            case SDL_QUIT:
-                running = 0;
-                break;
-            case SDL_CONTROLLERDEVICEADDED:
-                SDL_GameControllerOpen(e.cdevice.which);
-                break;
-            case SDL_CONTROLLERBUTTONDOWN:
-                if (e.cbutton.button == SDL_CONTROLLER_BUTTON_START)
-                {
-                    running = 0;
-                }
-                break;
-            }
-        }
-
-        SDL_SetRenderDrawColor(renderer, 0xff, 0xff, 0xff, 0xff);
-        SDL_RenderClear(renderer);
-        SDL_SetRenderDrawColor(renderer, 0xff, 0x00, 0x00, 0xff);
-        SDL_RenderCopy(renderer, texture, NULL, &text_rect);
-        SDL_RenderPresent(renderer);
-    }
-
-    SDL_DestroyRenderer(renderer);
-    SDL_DestroyWindow(win);
-    TTF_Quit();
-    SDL_Quit();
-
-    return 0;
-}
-
- -CMakeLists.txt: - -
-cmake_minimum_required(VERSION 3.0)
-
-project(text-ttf)
-
-add_executable(${PROJECT_NAME} main.c)
-
-find_package(SDL2 REQUIRED)
-
-target_include_directories(${PROJECT_NAME} 
-    PRIVATE ${SDL2_INCLUDE_DIRS}
-)
-
-target_link_libraries(${PROJECT_NAME} PRIVATE
-    ${SDL2_LIBRARIES}
-)
-
-if(PSP)
-    target_link_libraries(${PROJECT_NAME} PRIVATE
-        SDL2_ttf
-        freetype
-        m
-        bz2
-        png16
-        z
-    )
-    create_pbp_file(
-        TARGET ${PROJECT_NAME}
-        ICON_PATH NULL
-        BACKGROUND_PATH NULL
-        PREVIEW_PATH NULL
-        TITLE ${PROJECT_NAME}
-    )
-endif()
-
- -Building can be done with: - -
-mkdir build && cd build
-psp-cmake ..
-make
-
- -

This will result in an EBOOT.PBP file in the build directory. Put it in a directory in ms0:/PSP/GAME/ and you need a font file to test the program, download it from here. Put it in a directory same as EBOOT.PBP and the PSP can run it.

- -

- -## Tips and Tricks - -Here some useful tips for developing for the PSP. - -### Making Programs Work on Unmodded PSPs - -The PSPDEV toolchain contains tools for making your program work on unmodded PSPs. This can be done by running psp-cmake with some additional commands when building like so: - -``` -mkdir build && cd build -psp-cmake -DBUILD_PRX=1 -DENC_PRX=1 .. -make -``` - -This does require `create_pbp_file` to be used in your CMakeLists.txt file. After the first build, running `make` is enough to get an `EBOOT.PBP` file which works on official firmware with any new changes made to the code. - -### Add PSP Specific Code to a Multi-Platform Programs - -When porting a game to the PSP, some PSP specific code might be needed. To make this code only apply to PSP, it is possible to use a simple ifdef statements which checks for `__PSP__` like so: - -``` -#ifdef __PSP__ - // Do PSP specific thing -#else - // Do the thing all other systems should do -#endif -``` - -This makes sure that the other systems supported by the program keeps working the same, while still making it possible to add support for the PSP. - -## More Libraries - -There are many C and C++ libraries available within the PSPDEV toolchain which can add functionality to your program. Some examples: - -- Audio formats: mp3, ogg -- Image formats: png, jpeg -- Data formats: json, yaml, sqlite -- Support for compression, physics, fonts and much more - -For the full list take a look at the [psp-packages repository](https://github.com/pspdev/psp-packages) or run `psp-pacman -Syl`. Updating libraries can be done with `psp-pacman -Syu`. +You can access the website at `http://localhost:4000`. -## Contact +> [!Note] +> You can learn how this website deployed in the GitHub pipeline [here](https://jekyllrb.com/docs/continuous-integration/github-actions/). -If you need help or would like to contribute, don't hesitate to join us on [Discord](https://discord.gg/bePrj9W) or open an issue on [GitHub](https://github.com/pspdev/pspdev/issues). See you there! +## Contributing +If you want to contribute your changes feel free to open a pull request [here](https://github.com/pspdev/pspdev.github.io). diff --git a/_config.yml b/_config.yml index c1cff16..0b6cde0 100644 --- a/_config.yml +++ b/_config.yml @@ -1,3 +1,37 @@ -theme: jekyll-theme-hacker title: PSPDEV -description: Development tools for the Playstation Portable +description: "An open source SDK for PlayStation Portable (PSP) development. It allows you to make apps and games for both custom and official firmwares. This is a community project made by enthusiasts, it is in no way affiliated with Sony." +theme: just-the-docs +url: "https://pspdev.github.io" + +# just-the-docs configuration +color_scheme: dark + +exclude: + - README.md + - Gemfile.lock + +nav_external_links: + - title: "PSPSDK's documentation" + url: "https://pspdev.github.io/pspsdk/" + opens_in_new_tab: true + - title: "PSPDEV's package index" + url: "https://pspdev.github.io/psp-packages/" + opens_in_new_tab: true + +back_to_top: true +back_to_top_text: "Back to top" + +footer_content: 'Copyright © 2025, PSPDEV. Distributed by The Unlicense.' + +# Footer "Edit this page on GitHub" link text +gh_edit_link: true # show or hide edit this page link +gh_edit_link_text: "Edit this page on GitHub" +gh_edit_repository: "https://github.com/pspdev/pspdev.github.io" # the github URL for your repo +gh_edit_branch: "master" # the branch that your docs is served from +# gh_edit_source: docs # the source that your files originate from +gh_edit_view_mode: "tree" # "tree" or "edit" if you want the user to jump into the editor immediately + +plugins: + - jekyll-seo-tag + - jekyll-github-metadata + - jekyll-sitemap diff --git a/_includes/head.html b/_includes/head.html new file mode 100644 index 0000000..056a186 --- /dev/null +++ b/_includes/head.html @@ -0,0 +1,30 @@ + + + + + + + + + + {% if site.search_enabled != false %} + + {% endif %} + + + + {{ page.title }} | PSP SDK: Development tools for the Playstation Portable + + + + + {% seo title=false %} + \ No newline at end of file diff --git a/_includes/nav_footer_custom.html b/_includes/nav_footer_custom.html new file mode 100644 index 0000000..81fcec9 --- /dev/null +++ b/_includes/nav_footer_custom.html @@ -0,0 +1,3 @@ + diff --git a/_includes/samples/audio/CMakeLists.txt b/_includes/samples/audio/CMakeLists.txt new file mode 100644 index 0000000..4a2ea85 --- /dev/null +++ b/_includes/samples/audio/CMakeLists.txt @@ -0,0 +1,25 @@ +cmake_minimum_required(VERSION 3.11) + +project(audio) + +add_executable(${PROJECT_NAME} main.c) + +target_link_libraries(${PROJECT_NAME} PRIVATE + pspdebug + pspdisplay + pspge + pspctrl + pspaudio + pspaudiolib + psputility +) + +# Create an EBOOT.PBP file +create_pbp_file( + TARGET ${PROJECT_NAME} + ICON_PATH NULL + BACKGROUND_PATH NULL + PREVIEW_PATH NULL + TITLE ${PROJECT_NAME} + VERSION 01.00 +) \ No newline at end of file diff --git a/_includes/samples/audio/main.c b/_includes/samples/audio/main.c new file mode 100644 index 0000000..ef20cac --- /dev/null +++ b/_includes/samples/audio/main.c @@ -0,0 +1,188 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +PSP_MODULE_INFO("audio", 0, 1, 1); +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU); + +#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; +} + +/* Main code */ + +const float PI = 3.1415926535897932f; +const int sampleRate = 44100; +float frequency = 440.0f; +float currentTime = 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) { + currentTime *= (freq0 / frequency); + } + for (i = 0; i < length; i++) { + short s = (short) (scaleFactor * currentFunction(2.0f * PI * frequency * currentTime)); + ubuf[i].l = s; + ubuf[i].r = s; + currentTime += sampleLength; + } + if (currentTime * frequency > 1.0f) { + double d; + currentTime = modf(currentTime * frequency, &d) / frequency; + } + + freq0 = frequency; +} + +/* Read the analog stick and adjust the frequency */ +void controlFrequency(void) { + 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; +} \ No newline at end of file diff --git a/_includes/samples/controls/CMakeLists.txt b/_includes/samples/controls/CMakeLists.txt new file mode 100644 index 0000000..c34ca41 --- /dev/null +++ b/_includes/samples/controls/CMakeLists.txt @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 3.11) + +project(controls) + +add_executable(${PROJECT_NAME} main.c) + +target_link_libraries(${PROJECT_NAME} PRIVATE + pspdebug + pspdisplay + pspge + pspctrl +) + +# Create an EBOOT.PBP file +create_pbp_file( + TARGET ${PROJECT_NAME} + ICON_PATH NULL + BACKGROUND_PATH NULL + PREVIEW_PATH NULL + TITLE ${PROJECT_NAME} + VERSION 01.00 +) \ No newline at end of file diff --git a/_includes/samples/controls/main.c b/_includes/samples/controls/main.c new file mode 100644 index 0000000..afd8f5a --- /dev/null +++ b/_includes/samples/controls/main.c @@ -0,0 +1,98 @@ +#include +#include +#include +#include +#include + +PSP_MODULE_INFO("Controller", 0, 1, 1); + +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU); + +#define printf pspDebugScreenPrintf + +int done = 0; + +int exit_callback(int arg1, int arg2, void *common) +{ + done = 1; + return 0; +} + +int callback_thread(SceSize args, void *argp) +{ + int cbid = sceKernelCreateCallback("Exit Callback", + exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + sceKernelSleepThreadCB(); + return 0; +} + +int setup_callbacks(void) +{ + int thid = sceKernelCreateThread("update_thread", + callback_thread, 0x11, 0xFA0, 0, 0); + + if(thid >= 0) + sceKernelStartThread(thid, 0, 0); + return thid; +} + +int main(void) +{ + SceCtrlData pad; + + pspDebugScreenInit(); + setup_callbacks(); + + sceCtrlSetSamplingCycle(0); + sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG); + + while (!done) + { + pspDebugScreenSetXY(0, 2); + sceCtrlReadBufferPositive(&pad, 1); + + printf("Analog X = %3d, ", pad.Lx); + printf("Analog Y = %3d \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("Circle pressed! \n"); + } + if (pad.Buttons & PSP_CTRL_CROSS) + { + printf("Cross pressed! \n"); + } + + if (pad.Buttons & PSP_CTRL_UP) + { + printf("Up direction pad pressed! \n"); + } + if (pad.Buttons & PSP_CTRL_DOWN) + { + printf("Down direction pad pressed! \n"); + } + if (pad.Buttons & PSP_CTRL_LEFT) + { + printf("Left direction pad pressed! \n"); + } + if (pad.Buttons & PSP_CTRL_RIGHT) + { + printf("Right direction pad pressed! \n"); + } + } + } + + sceKernelExitGame(); + return 0; +} \ No newline at end of file diff --git a/_includes/samples/hello/CMakeLists.txt b/_includes/samples/hello/CMakeLists.txt new file mode 100644 index 0000000..c2cb8c1 --- /dev/null +++ b/_includes/samples/hello/CMakeLists.txt @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 3.11) + +project(hello) + +add_executable(${PROJECT_NAME} main.c) + +target_link_libraries(${PROJECT_NAME} PRIVATE + pspdebug + pspdisplay + pspge +) + +# Create an EBOOT.PBP file +create_pbp_file( + TARGET ${PROJECT_NAME} + ICON_PATH NULL + BACKGROUND_PATH NULL + PREVIEW_PATH NULL + TITLE ${PROJECT_NAME} + VERSION 01.00 +) \ No newline at end of file diff --git a/_includes/samples/hello/main.c b/_includes/samples/hello/main.c new file mode 100644 index 0000000..1eef433 --- /dev/null +++ b/_includes/samples/hello/main.c @@ -0,0 +1,41 @@ +#include +#include +#include + +// PSP_MODULE_INFO is required +PSP_MODULE_INFO("Hello World", 0, 1, 0); +PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER); + +int exit_callback(int arg1, int arg2, void *common) { + sceKernelExitGame(); + return 0; +} + +int callback_thread(SceSize args, void *argp) { + int cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + sceKernelSleepThreadCB(); + return 0; +} + +int setup_callbacks(void) { + int thid = sceKernelCreateThread("update_thread", callback_thread, 0x11, 0xFA0, 0, 0); + if(thid >= 0) + sceKernelStartThread(thid, 0, 0); + return thid; +} + +int main(void) { + // Use above functions to make exiting possible + setup_callbacks(); + + // Print Hello World! on a debug screen on a loop + pspDebugScreenInit(); + while(1) { + pspDebugScreenSetXY(0, 0); + pspDebugScreenPrintf("Hello World!"); + sceDisplayWaitVblankStart(); + } + + return 0; +} \ No newline at end of file diff --git a/_includes/samples/sdl2/CMakeLists.txt b/_includes/samples/sdl2/CMakeLists.txt new file mode 100644 index 0000000..3383735 --- /dev/null +++ b/_includes/samples/sdl2/CMakeLists.txt @@ -0,0 +1,25 @@ +cmake_minimum_required(VERSION 3.11) + +project(sdl2) + +add_executable(${PROJECT_NAME} main.c) + +include(FindPkgConfig) +pkg_search_module(SDL2 REQUIRED sdl2) + +target_include_directories(${PROJECT_NAME} PRIVATE ${SDL2_INCLUDE_DIRS}) + +target_link_libraries(${PROJECT_NAME} PRIVATE + ${SDL2_LIBRARIES} +) + +if(PSP) + create_pbp_file( + TARGET ${PROJECT_NAME} + ICON_PATH NULL + BACKGROUND_PATH NULL + PREVIEW_PATH NULL + TITLE ${PROJECT_NAME} + VERSION 01.00 + ) +endif() \ No newline at end of file diff --git a/_includes/samples/sdl2/main.c b/_includes/samples/sdl2/main.c new file mode 100644 index 0000000..fc7b6f4 --- /dev/null +++ b/_includes/samples/sdl2/main.c @@ -0,0 +1,59 @@ +#include + +int main(int argc, char *argv[]) +{ + SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER); + + SDL_Window * window = SDL_CreateWindow( + "window", + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + 480, + 272, + 0 + ); + + SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); + + SDL_Rect square = {216, 96, 34, 64}; + + int running = 1; + SDL_Event event; + while (running) { + // Process input + if (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_QUIT: + // End the loop if the programs is being closed + running = 0; + break; + case SDL_CONTROLLERDEVICEADDED: + // Connect a controller when it is connected + SDL_GameControllerOpen(event.cdevice.which); + break; + case SDL_CONTROLLERBUTTONDOWN: + if(event.cbutton.button == SDL_CONTROLLER_BUTTON_START) { + // Close the program if start is pressed + running = 0; + } + break; + } + } + + // Clear the screen + SDL_RenderClear(renderer); + + // Draw a red square + SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); + SDL_RenderFillRect(renderer, &square); + + // Draw everything on a white background + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); + SDL_RenderPresent(renderer); + } + SDL_DestroyRenderer(renderer); + SDL_DestroyWindow(window); + SDL_Quit(); + + return 0; +} \ No newline at end of file diff --git a/_includes/samples/sdl2_image/CMakeLists.txt b/_includes/samples/sdl2_image/CMakeLists.txt new file mode 100644 index 0000000..a2c75b5 --- /dev/null +++ b/_includes/samples/sdl2_image/CMakeLists.txt @@ -0,0 +1,31 @@ +cmake_minimum_required(VERSION 3.11) + +project(sdl2-image) + +add_executable(${PROJECT_NAME} main.c) + +include(FindPkgConfig) +pkg_search_module(SDL2 REQUIRED sdl2) +pkg_search_module(SDL2_IMAGE REQUIRED SDL2_image) + +target_include_directories(${PROJECT_NAME} PRIVATE + ${SDL2_INCLUDE_DIRS} + ${SDL2_IMAGE_INCLUDE_DIRS} +) + +target_link_libraries(${PROJECT_NAME} PRIVATE + ${SDL2_LIBRARIES} + ${SDL2_IMAGE_LIBRARIES} +) + +if(PSP) + # Create an EBOOT.PBP file + create_pbp_file( + TARGET ${PROJECT_NAME} + ICON_PATH NULL + BACKGROUND_PATH NULL + PREVIEW_PATH NULL + TITLE ${PROJECT_NAME} + VERSION 01.00 + ) +endif() \ No newline at end of file diff --git a/_includes/samples/sdl2_image/main.c b/_includes/samples/sdl2_image/main.c new file mode 100644 index 0000000..eafecc9 --- /dev/null +++ b/_includes/samples/sdl2_image/main.c @@ -0,0 +1,73 @@ +#include +#include + +int main(int argc, char *argv[]) +{ + SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER); + + // Enable png support for SDL2_image + IMG_Init(IMG_INIT_PNG); + + SDL_Window * window = SDL_CreateWindow( + "window", + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + 480, + 272, + 0 + ); + + SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); + + // Load the texture + SDL_Surface * pixels = IMG_Load("grass.png"); + SDL_Texture * sprite = SDL_CreateTextureFromSurface(renderer, pixels); + SDL_FreeSurface(pixels); + + // Store the dimensions of the texture + SDL_Rect sprite_rect; + SDL_QueryTexture(sprite, NULL, NULL, &sprite_rect.w, &sprite_rect.h); + + // Set the position to draw to in the middle of the screen + sprite_rect.x = 480/2 - sprite_rect.w/2; + sprite_rect.y = 272/2 - sprite_rect.h/2; + + int running = 1; + SDL_Event event; + while (running) { + // Process input + if (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_QUIT: + // End the loop if the programs is being closed + running = 0; + break; + case SDL_CONTROLLERDEVICEADDED: + // Connect a controller when it is connected + SDL_GameControllerOpen(event.cdevice.which); + break; + case SDL_CONTROLLERBUTTONDOWN: + if(event.cbutton.button == SDL_CONTROLLER_BUTTON_START) { + // Close the program if start is pressed + running = 0; + } + break; + } + } + + // Clear the screen + SDL_RenderClear(renderer); + + // Draw the 'grass' sprite + SDL_RenderCopy(renderer, sprite, NULL, &sprite_rect); + + // Draw everything on a white background + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); + SDL_RenderPresent(renderer); + } + SDL_DestroyRenderer(renderer); + SDL_DestroyWindow(window); + SDL_Quit(); + + return 0; +} \ No newline at end of file diff --git a/_includes/samples/sdl2_mixer/CMakeLists.txt b/_includes/samples/sdl2_mixer/CMakeLists.txt new file mode 100644 index 0000000..6b4651c --- /dev/null +++ b/_includes/samples/sdl2_mixer/CMakeLists.txt @@ -0,0 +1,30 @@ +cmake_minimum_required(VERSION 3.11) + +project(sdl2_mixer) + +add_executable(${PROJECT_NAME} main.c) + +include(FindPkgConfig) +pkg_search_module(SDL2 REQUIRED sdl2) +pkg_search_module(SDL2_MIXER REQUIRED SDL2_mixer) + +target_include_directories(${PROJECT_NAME} PRIVATE + ${SDL2_INCLUDE_DIRS} + ${SDL2_MIXER_INCLUDE_DIRS} +) + +target_link_libraries(${PROJECT_NAME} PRIVATE + ${SDL2_LIBRARIES} + ${SDL2_MIXER_LIBRARIES} +) + +if(PSP) + create_pbp_file( + TARGET ${PROJECT_NAME} + ICON_PATH NULL + BACKGROUND_PATH NULL + PREVIEW_PATH NULL + TITLE ${PROJECT_NAME} + VERSION 01.00 + ) +endif() \ No newline at end of file diff --git a/_includes/samples/sdl2_mixer/main.c b/_includes/samples/sdl2_mixer/main.c new file mode 100644 index 0000000..95ef8a0 --- /dev/null +++ b/_includes/samples/sdl2_mixer/main.c @@ -0,0 +1,139 @@ +#include +#include + +// Define MIN macro +#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) + +// Define screen dimensions +#define SCREEN_WIDTH 480 +#define SCREEN_HEIGHT 272 + +// audio file path +#define MUSIC_PATH "ms0:/MUSIC/test.ogg" // ogg/mp3 file format + +int main(int argc, char **argv) { + (void)argc; + (void)argv; + + // Initialize sdl + SDL_Init(SDL_INIT_VIDEO | + SDL_INIT_AUDIO | + SDL_INIT_GAMECONTROLLER + ); + + // Initialize sdl2_mixer + Mix_OpenAudio(44100, + MIX_DEFAULT_FORMAT, + MIX_DEFAULT_CHANNELS, + 2048 + ); + + // create window + SDL_Window *win = SDL_CreateWindow( + "psp_win", + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + SCREEN_WIDTH, + SCREEN_HEIGHT, + 0 + ); + + // Create Renderer + SDL_Renderer *renderer = SDL_CreateRenderer( + win, -1, 0 + ); + + // Load ogg file + Mix_Music *ogg_file = NULL; + ogg_file = Mix_LoadMUS(MUSIC_PATH); + if (!ogg_file) { + return 0; + } + + SDL_Rect rect; + + // Square dimensions: Half of the min(SCREEN_WIDTH, SCREEN_HEIGHT) + rect.w = MIN(SCREEN_WIDTH, SCREEN_HEIGHT) / 2; + rect.h = MIN(SCREEN_WIDTH, SCREEN_HEIGHT) / 2; + + // Square position: In the middle of the screen + rect.x = SCREEN_WIDTH / 2 - rect.w / 2; + rect.y = SCREEN_HEIGHT / 2 - rect.h / 2; + + + // Declare rects of pause symbol + SDL_Rect pause_rect1, pause_rect2; + + pause_rect1.h = rect.h / 2; + pause_rect1.w = 40; + pause_rect1.x = rect.x + (rect.w - pause_rect1.w * 3) / 2; + pause_rect1.y = rect.y + rect.h / 4; + pause_rect2 = pause_rect1; + pause_rect2.x += pause_rect1.w * 2; + + // play the music 8 times + if (Mix_PlayMusic(ogg_file, 8) == -1) { + return 0; + } + + int running = 1; + SDL_Event e; + while (running) { + if(SDL_PollEvent(&e)) { + switch(e.type) { + case SDL_QUIT: + running = 0; + break; + case SDL_CONTROLLERDEVICEADDED: + SDL_GameControllerOpen(e.cdevice.which); + break; + case SDL_CONTROLLERBUTTONDOWN: + // pause using cross button + if (e.cbutton.button == SDL_CONTROLLER_BUTTON_A) { + Mix_PauseMusic(); + // resume using circle button + } else if (e.cbutton.button == SDL_CONTROLLER_BUTTON_B) { + Mix_ResumeMusic(); + } + // press start button to exit + if (e.cbutton.button == SDL_CONTROLLER_BUTTON_START) { + running = 0; + } + break; + } + } + + // Initialize renderer color black for the background + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); + + // Clear screen + SDL_RenderClear(renderer); + + // Set renderer color green to draw the square + SDL_SetRenderDrawColor(renderer, 0, 0xFF, 0, 0xFF); + + // Draw filled square + SDL_RenderFillRect(renderer, &rect); + + // Check pause status + if(Mix_PausedMusic()) { + // Set renderer color black to draw the pause symbol + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); + + // Draw pause symbol + SDL_RenderFillRect(renderer, &pause_rect1); + SDL_RenderFillRect(renderer, &pause_rect2); + } + + // Update screen + SDL_RenderPresent(renderer); + } + + Mix_FreeMusic(ogg_file); + SDL_DestroyRenderer(renderer); + SDL_DestroyWindow(win); + Mix_CloseAudio(); + SDL_Quit(); + + return 0; +} \ No newline at end of file diff --git a/_includes/samples/sdl2_ttf/CMakeLists.txt b/_includes/samples/sdl2_ttf/CMakeLists.txt new file mode 100644 index 0000000..4dc0986 --- /dev/null +++ b/_includes/samples/sdl2_ttf/CMakeLists.txt @@ -0,0 +1,30 @@ +cmake_minimum_required(VERSION 3.11) + +project(sdl2_ttf) + +add_executable(${PROJECT_NAME} main.c) + +include(FindPkgConfig) +pkg_search_module(SDL2 REQUIRED sdl2) +pkg_search_module(SDL2_TTF REQUIRED SDL2_ttf) + +target_include_directories(${PROJECT_NAME} PRIVATE + ${SDL2_INCLUDE_DIRS} + ${SDL2_TTF_INCLUDE_DIRS} +) + +target_link_libraries(${PROJECT_NAME} PRIVATE + ${SDL2_LIBRARIES} + ${SDL2_TTF_LIBRARIES} +) + +if(PSP) + create_pbp_file( + TARGET ${PROJECT_NAME} + ICON_PATH NULL + BACKGROUND_PATH NULL + PREVIEW_PATH NULL + TITLE ${PROJECT_NAME} + VERSION 01.00 + ) +endif() \ No newline at end of file diff --git a/_includes/samples/sdl2_ttf/main.c b/_includes/samples/sdl2_ttf/main.c new file mode 100644 index 0000000..949c577 --- /dev/null +++ b/_includes/samples/sdl2_ttf/main.c @@ -0,0 +1,104 @@ +#include + +#include +#include + +// Define screen dimensions +#define SCREEN_WIDTH 480 +#define SCREEN_HEIGHT 272 + +int main(int argc, char **argv) +{ + (void)argc; + (void)argv; + + // Initialize SDL2 + if (SDL_Init(SDL_INIT_VIDEO) < 0) + { + printf("SDL2 could not be initialized!\n" + "SDL2 Error: %s\n", + SDL_GetError()); + return 0; + } + + // Initialize SDL2_ttf + if (TTF_Init() < 0) + { + printf("SDL2_ttf could not be initialized!\n" + "SDL2_ttf Error: %s\n", + SDL_GetError()); + return 0; + } + + SDL_Window *win = SDL_CreateWindow( + "window", + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + SCREEN_WIDTH, + SCREEN_HEIGHT, + 0); + + if (!win) + { + printf("Window could not be created!\n" + "SDL_Error: %s\n", + SDL_GetError()); + } + + SDL_Renderer *renderer = SDL_CreateRenderer(win, -1, 0); + TTF_Font *font = TTF_OpenFont("Pacifico.ttf", 40); + + // Set the text and background color + SDL_Color text_color = {0xff, 0xff, 0xff, 0xff}; + SDL_Color bg_color = {0x00, 0x00, 0x00, 0xff}; + + SDL_Rect text_rect; + SDL_Surface *surface = TTF_RenderText(font, "Hello World!", text_color, bg_color); + SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface); + + // Get text dimensions + text_rect.w = surface->w; + text_rect.h = surface->h; + + SDL_FreeSurface(surface); + + text_rect.x = (SCREEN_WIDTH - text_rect.w) / 2; + text_rect.y = text_rect.h + 30; + + int running = 1; + SDL_Event e; + while (running) + { + if (SDL_PollEvent(&e)) + { + switch (e.type) + { + case SDL_QUIT: + running = 0; + break; + case SDL_CONTROLLERDEVICEADDED: + SDL_GameControllerOpen(e.cdevice.which); + break; + case SDL_CONTROLLERBUTTONDOWN: + if (e.cbutton.button == SDL_CONTROLLER_BUTTON_START) + { + running = 0; + } + break; + } + } + + SDL_SetRenderDrawColor(renderer, 0xff, 0xff, 0xff, 0xff); + SDL_RenderClear(renderer); + SDL_SetRenderDrawColor(renderer, 0xff, 0x00, 0x00, 0xff); + SDL_RenderCopy(renderer, texture, NULL, &text_rect); + SDL_RenderPresent(renderer); + } + + SDL_DestroyRenderer(renderer); + SDL_DestroyWindow(win); + TTF_Quit(); + SDL_Quit(); + + return 0; +} \ No newline at end of file diff --git a/_includes/samples/shape/CMakeLists.txt b/_includes/samples/shape/CMakeLists.txt new file mode 100644 index 0000000..56eb684 --- /dev/null +++ b/_includes/samples/shape/CMakeLists.txt @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 3.11) + +project(shape) + +add_executable(${PROJECT_NAME} main.c) + +target_link_libraries(${PROJECT_NAME} PRIVATE + pspgu + pspge + pspdisplay +) + +# Create an EBOOT.PBP file +create_pbp_file( + TARGET ${PROJECT_NAME} + ICON_PATH NULL + BACKGROUND_PATH NULL + PREVIEW_PATH NULL + TITLE ${PROJECT_NAME} + VERSION 01.00 +) \ No newline at end of file diff --git a/_includes/samples/shape/main.c b/_includes/samples/shape/main.c new file mode 100644 index 0000000..dc0bf6b --- /dev/null +++ b/_includes/samples/shape/main.c @@ -0,0 +1,115 @@ +#include +#include +#include + +PSP_MODULE_INFO("shape", 0, 1, 0); +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_VFPU | THREAD_ATTR_USER); + +#define BUFFER_WIDTH 512 +#define BUFFER_HEIGHT 272 +#define SCREEN_WIDTH 480 +#define SCREEN_HEIGHT BUFFER_HEIGHT + +char list[0x20000] __attribute__((aligned(64))); +int running; + +int exit_callback(int arg1, int arg2, void *common) { + running = 0; + return 0; +} + +int callback_thread(SceSize args, void *argp) { + int cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + sceKernelSleepThreadCB(); + return 0; +} + +int setup_callbacks(void) { + int thid = sceKernelCreateThread("update_thread", callback_thread, 0x11, 0xFA0, 0, 0); + if(thid >= 0) + sceKernelStartThread(thid, 0, 0); + return thid; +} + +void initGu(){ + sceGuInit(); + + //Set up buffers + sceGuStart(GU_DIRECT, list); + sceGuDrawBuffer(GU_PSM_8888,(void*)0,BUFFER_WIDTH); + sceGuDispBuffer(SCREEN_WIDTH,SCREEN_HEIGHT,(void*)0x88000,BUFFER_WIDTH); + sceGuDepthBuffer((void*)0x110000,BUFFER_WIDTH); + + //Set up viewport + sceGuOffset(2048 - (SCREEN_WIDTH / 2), 2048 - (SCREEN_HEIGHT / 2)); + sceGuViewport(2048, 2048, SCREEN_WIDTH, SCREEN_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + sceGuScissor(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); + + //Set some stuff + sceGuDepthRange(65535, 0); //Use the full buffer for depth testing - buffer is reversed order + + sceGuDepthFunc(GU_GEQUAL); //Depth buffer is reversed, so GEQUAL instead of LEQUAL + sceGuEnable(GU_DEPTH_TEST); //Enable depth testing + + sceGuFinish(); + sceGuDisplay(GU_TRUE); +} + +void endGu(){ + sceGuDisplay(GU_FALSE); + sceGuTerm(); +} + +void startFrame(){ + sceGuStart(GU_DIRECT, list); + sceGuClearColor(0xFFFFFFFF); // White background + sceGuClear(GU_COLOR_BUFFER_BIT); +} + +void endFrame(){ + sceGuFinish(); + sceGuSync(0, 0); + sceDisplayWaitVblankStart(); + sceGuSwapBuffers(); +} + +typedef struct { + unsigned short u, v; + short x, y, z; +} Vertex; + +void drawRect(float x, float y, float w, float h) { + + Vertex* vertices = (Vertex*)sceGuGetMemory(2 * sizeof(Vertex)); + + vertices[0].x = x; + vertices[0].y = y; + + vertices[1].x = x + w; + vertices[1].y = y + h; + + sceGuColor(0xFF0000FF); // Red, colors are ABGR + sceGuDrawArray(GU_SPRITES, GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 2, 0, vertices); +} + + +int main() { + // Make exiting with the home button possible + setup_callbacks(); + + // Setup the library used for rendering + initGu(); + + running = 1; + while(running){ + startFrame(); + + drawRect(216, 96, 34, 64); + + endFrame(); + } + + return 0; +} \ No newline at end of file diff --git a/_includes/samples/sprite/CMakeLists.txt b/_includes/samples/sprite/CMakeLists.txt new file mode 100644 index 0000000..5f65db0 --- /dev/null +++ b/_includes/samples/sprite/CMakeLists.txt @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 3.11) + +project(texture) + +add_executable(${PROJECT_NAME} main.c) + +target_link_libraries(${PROJECT_NAME} PRIVATE + pspgu + pspge + pspdisplay +) + +# Create an EBOOT.PBP file +create_pbp_file( + TARGET ${PROJECT_NAME} + ICON_PATH NULL + BACKGROUND_PATH NULL + PREVIEW_PATH NULL + TITLE ${PROJECT_NAME} + VERSION 01.00 +) \ No newline at end of file diff --git a/_includes/samples/sprite/main.c b/_includes/samples/sprite/main.c new file mode 100644 index 0000000..e0446d1 --- /dev/null +++ b/_includes/samples/sprite/main.c @@ -0,0 +1,164 @@ +#include +#include +#include +#include +#include + +#define STB_IMAGE_IMPLEMENTATION +#include + +PSP_MODULE_INFO("texture", 0, 1, 0); +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER); + +#define BUFFER_WIDTH 512 +#define BUFFER_HEIGHT 272 +#define SCREEN_WIDTH 480 +#define SCREEN_HEIGHT BUFFER_HEIGHT + +typedef struct +{ + float u, v; + uint32_t colour; + float x, y, z; +} TextureVertex; + +typedef struct +{ + int width, height; + uint32_t * data; +} Texture; + +char list[0x20000] __attribute__((aligned(64))); + +void * fbp0; +void * fbp1; +int running; + +int exit_callback(int arg1, int arg2, void *common) { + running = 0; + return 0; +} + +int callback_thread(SceSize args, void *argp) { + int cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + sceKernelSleepThreadCB(); + return 0; +} + +int setup_callbacks(void) { + int thid = sceKernelCreateThread("update_thread", callback_thread, 0x11, 0xFA0, 0, 0); + if(thid >= 0) + sceKernelStartThread(thid, 0, 0); + return thid; +} + +void initGu(){ + sceGuInit(); + + fbp0 = guGetStaticVramBuffer(BUFFER_WIDTH, BUFFER_HEIGHT, GU_PSM_8888); + fbp1 = guGetStaticVramBuffer(BUFFER_WIDTH, BUFFER_HEIGHT, GU_PSM_8888); + + //Set up buffers + sceGuStart(GU_DIRECT, list); + sceGuDrawBuffer(GU_PSM_8888, fbp0, BUFFER_WIDTH); + sceGuDispBuffer(SCREEN_WIDTH,SCREEN_HEIGHT,fbp1, BUFFER_WIDTH); + + // We do not care about the depth buffer in this example + sceGuDepthBuffer(fbp0, 0); // Set depth buffer to a length of 0 + sceGuDisable(GU_DEPTH_TEST); // Disable depth testing + + //Set up viewport + sceGuOffset(2048 - (SCREEN_WIDTH / 2), 2048 - (SCREEN_HEIGHT / 2)); + sceGuViewport(2048, 2048, SCREEN_WIDTH, SCREEN_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + sceGuScissor(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); + + // Start a new frame and enable the display + sceGuFinish(); + sceGuDisplay(GU_TRUE); +} + +void endGu(){ + sceGuDisplay(GU_FALSE); + sceGuTerm(); +} + +void startFrame(){ + sceGuStart(GU_DIRECT, list); + sceGuClearColor(0xFFFFFFFF); // White background + sceGuClear(GU_COLOR_BUFFER_BIT); +} + +void endFrame(){ + sceGuFinish(); + sceGuSync(0, 0); + sceDisplayWaitVblankStart(); + sceGuSwapBuffers(); +} + +Texture * loadTexture(const char * filename) { + Texture * texture = (Texture *) calloc(1, sizeof(Texture)); + + texture->data = (uint32_t *) stbi_load("grass.png", &(texture->width), &(texture->height), NULL, STBI_rgb_alpha); + + // Make sure the texture cache is reloaded + sceKernelDcacheWritebackInvalidateAll(); + + return texture; +} + +void drawTexture(Texture * texture, float x, float y, float w, float h) { + static TextureVertex vertices[2]; + + vertices[0].u = 0.0f; + vertices[0].v = 0.0f; + vertices[0].colour = 0xFFFFFFFF; + vertices[0].x = x; + vertices[0].y = y; + vertices[0].z = 0.0f; + + vertices[1].u = w; + vertices[1].v = h; + vertices[1].colour = 0xFFFFFFFF; + vertices[1].x = x + w; + vertices[1].y = y + h; + vertices[1].z = 0.0f; + + sceGuTexMode(GU_PSM_8888, 0, 0, GU_FALSE); + sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGB); + sceGuTexImage(0, texture->width, texture->height, texture->width, texture->data); + + sceGuEnable(GU_TEXTURE_2D); + sceGuDrawArray(GU_SPRITES, GU_COLOR_8888 | GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_TRANSFORM_2D, 2, 0, vertices); + sceGuDisable(GU_TEXTURE_2D); +} + + +int main() { + // Make exiting with the home button possible + setup_callbacks(); + + // Create a texture from a file + Texture * texture = loadTexture("grass.png"); + + // Start rendering + initGu(); + + running = 1; + while(running){ + startFrame(); + + drawTexture(texture, SCREEN_WIDTH / 2 - texture->width / 2, SCREEN_HEIGHT / 2 - texture->height / 2, texture->width, texture->height); + + endFrame(); + } + // Stop rendering + endGu(); + + // Clean up + stbi_image_free(texture->data); + free(texture); + + return 0; +} \ No newline at end of file diff --git a/_layouts/default.html b/_layouts/default.html deleted file mode 100644 index 1fe9377..0000000 --- a/_layouts/default.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - {{ page.title | default: site.title | default: site.github.repository_name }} - - - - -
-
- -

{{ page.title | default: site.title | default: site.github.repository_name }}

-
-

{{ page.description | default: site.description | default: site.github.project_tagline }}

- -
- Download - Documentation - Samples - PSPLINK - Discord - GitHub -
-
-
- -
-
- {{ content }} -
-
- - diff --git a/basic_programs.md b/basic_programs.md new file mode 100644 index 0000000..fa2b39c --- /dev/null +++ b/basic_programs.md @@ -0,0 +1,387 @@ +--- +title: Basic Programs +layout: home +nav_order: 4 +--- + +# Basic Programs +{: .fs-8 .fw-700 .text-center } + +## Hello world +{: .fs-6 .fw-700 } + +![](images/hello.png) + +This is a simple Hello World program for the PSP. + +Click on view source below to see the code and how to build it. + +
+ +View source + +**main.c** + +```c +{% include samples/hello/main.c %} +``` + + +**CMakeLists.txt** + +```cmake +{% include samples/hello/CMakeLists.txt %} +``` + +Building can be done with: + +```shell +mkdir build && cd build +psp-cmake .. +make +``` + +This will result in an EBOOT.PBP file in the build directory. Put it in a directory in ms0:/PSP/GAME/ and the PSP can run it. + +
+ +## Drawing shapes +{: .fs-6 .fw-700 } + +![](images/shape.png) + +This is a simple square drawn on the PSP. It uses the native libgu library. + +Click on view source below to see the code and how to build it. + +
+ +View source + +**main.c** + +```c +{% include samples/shape/main.c %} +``` + +**CMakeLists.txt** + +```cmake +{% include samples/shape/CMakeLists.txt %} +``` + +Building can be done with: + +```shell +mkdir build && cd build +psp-cmake .. +make +``` + +

This will result in an EBOOT.PBP file in the build directory. Put it in a directory in ms0:/PSP/GAME/ and the PSP can run it.

+ +More libgu examples can be found here. + +
+ +## Drawing Sprites +{: .fs-6 .fw-700 } + +![](images/sprite.png) + +This is a sprite drawn on the PSP. It uses the native libgu library to draw and the stb_image library to load the image. stb_image supports a lot of image formats. For the Playstation Portable it is important that the width of images used is a power of 2. In this case 16, but 32, 64, 128 and 256 will also work. This limitation does not exist for the example with SDL2 below. + +Click on view source below to see the code and how to build it. + +
+ +View source + +**main.c** + +```c +{% include samples/sprite/main.c %} +``` + +**CMakeLists.txt** + +```cmake +{% include samples/sprite/CMakeLists.txt %} +``` + +Building can be done with: + +```shell +mkdir build && cd build +psp-cmake .. +make +``` + +This will result in an EBOOT.PBP file in the build directory. Put it in a directory in ms0:/PSP/GAME/ and add the grass image file, download it from here, to be able to run it on the PSP. + +More libgu examples can be found here. + +
+ +## Input +{: .fs-6 .fw-700 } + +![](images/controls.png) + +This is a simple program to use the PSP's input functions. + +Click on view source below to see the code and how to build it. + +
+ +View source + +**main.c** + +```c +{% include samples/controls/main.c %} +``` + +**CMakeLists.txt** + +```cmake +{% include samples/controls/CMakeLists.txt %} +``` + +Building can be done with: + +```shell +mkdir build && cd build +psp-cmake .. +make +``` + +

This will result in an EBOOT.PBP file in the build directory. Put it in a directory in ms0:/PSP/GAME/ and the PSP can run it.

+ +
+ +## Audio +{: .fs-6 .fw-700 } + +![](images/audio.png) + +This is a simple program to use the audio of the PSP with minimal effort. It uses native audio library. + +Click on view source below to see the code and how to build it. + +
+ +View source + +**main.c** + +```c +{% include samples/audio/main.c %} +``` + +**CMakeLists.txt** + +```cmake +{% include samples/audio/CMakeLists.txt %} +`````` + +Building can be done with: + +```shell +mkdir build && cd build +psp-cmake .. +make +``` + +

This will result in an EBOOT.PBP file in the build directory. Put it in a directory in ms0:/PSP/GAME/ and the PSP can run it.

+ +More audiolib examples can be found here. + +
+ +## Using SDL2 +{: .fs-6 .fw-700 } + +![](images/shape.png) + +SDL2 is a library which handles system specific things like input, audio and window management for you. It can also be used to render shapes and images, just like the native libgu. This can be slower, but will result in code that is easier to read and can run on multiple platforms. + +Despite this example adding an option to close by pressing the start button, the code is much shorter. It can even be build for Linux without any further modifications. + +Click on view source below for the to see the code and how to build it. + +
+ +View source + +**main.c** + +```c +{% include samples/sdl2/main.c %} +``` + +**CMakeLists.txt** + +```cmake +{% include samples/sdl2/CMakeLists.txt %} +`````` + +Building can be done with: + +```shell +mkdir build && cd build +psp-cmake .. +make +``` + +

This will result in an EBOOT.PBP` file in the build directory. Put it in a directory in ms0:/PSP/GAME/ and the PSP can run it.

+ +If you have sdl2 dev package and a compiler installed this code will also build on Linux for Linux by running: + +```shell +mkdir build && cd build +cmake .. +make +``` + +More documentation on SDL can be found here. + +
+ +## Using SDL2 Image +{: .fs-6 .fw-700 } + +![](images/sprite.png) + +SDL2 image is a library which adds support for multiple image formats to SDL2. This example results in the same image as the sprite example using libgu above. Here the limitation of the image width being a power 2 does not apply. + +Despite this example adding an option to close by pressing the start button, the code is much shorter. It can even be build for Linux without any further modifications. + +Click on view source below to see the code and how to build it. + +
+ +View source + +**main.c** + +```c +{% include samples/sdl2_image/main.c %} +``` + +**CMakeLists.txt** + +```cmake +{% include samples/sdl2_image/CMakeLists.txt %} +``` + +Building can be done with: + +```shell +mkdir build && cd build +psp-cmake .. +make +``` + +This will result in an EBOOT.PBP file in the build directory. Put it in a directory in ms0:/PSP/GAME/ and add the grass image file, download it from here, to be able to run it on the PSP. + +If you have sdl2 sdl2-image dev packages and a compiler installed this code will also build on Linux for Linux by running: + +```shell +mkdir build && cd build +cmake .. +make +``` + +Documentation for SDL2_image can be found here. + +
+ + +## Using SDL2 mixer +{: .fs-6 .fw-700 } + +![](images/sdl2_mixer.png) + +This is a simple program to use the SDL2_mixer library. It handle audio playback in multimedia applications and games. It supports various audio formats(MP3/OGG). + +Click on view source below to see the code and how to build it. + +
+ +View source + +**main.c** + +```c +{% include samples/sdl2_mixer/main.c %} +``` + +**CMakeLists.txt** + +```cmake +{% include samples/sdl2_mixer/CMakeLists.txt %} +`````` + +Building can be done with: + +```shell +mkdir build && cd build +psp-cmake .. +make +``` + +This will result in an EBOOT.PBP file in the build directory. Put it in a directory in ms0:/PSP/GAME/ and you need an audio file to test the program, download it from here. Put it in a directory in ms0:/MUSIC/ and then rename the audio file same as name on your *MUSIC_PATH* macro in your C code and the PSP can run it. + +Documentation for SDL2_mixer can be found here. + +
+ +## Using SDL2 ttf +{: .fs-6 .fw-700 } + +![](images/sdl2_ttf.jpg) + +This is a simple program to use the SDL2_ttf library. It provides functionality for rendering TrueType fonts for your PSP. + +Click on view source below to see the code and how to build it. + +
+ +View source + +**main.c** + +```c +{% include samples/sdl2_ttf/main.c %} +``` + +**CMakeLists.txt** + +```cmake +{% include samples/sdl2_ttf/CMakeLists.txt %} +`````` + +Building can be done with: + +```shell +mkdir build && cd build +psp-cmake .. +make +``` + +This will result in an EBOOT.PBP file in the build directory. Put it in a directory in ms0:/PSP/GAME/ and you need a font file to test the program, download it from here. Put it in a directory same as EBOOT.PBP and the PSP can run it. + +Documentation for SDL2_ttf can be found here. + +
+ +## More Examples +{: .fs-6 .fw-700 } + +More examples on how to use specific functions offered in the PSP SDK can be found [here](https://github.com/pspdev/pspsdk/tree/master/src/samples). Additional documentation on these functions can be found [here](https://pspdev.github.io/pspsdk/). + +## Debugging +{: .fs-6 .fw-700 } + +When making changes to the example programs listed above, you might run into errors or even crashes. To learn how to figure out what went wrong, check out the [debugging](debugging.html) page. diff --git a/contributing.md b/contributing.md new file mode 100644 index 0000000..bcf9c6e --- /dev/null +++ b/contributing.md @@ -0,0 +1,51 @@ +--- +title: Contributing +layout: home +nav_order: 8 +--- + +# Contributing +{: .fs-8 .fw-700 .text-center } + +There are many ways to contribute to our efforts to make developing homebrew for the PlayStation Portable (PSP) easier for everyone. The first step would be to [join our Discord](https://discord.gg/bePrj9W) or use our [GitHub Discussions](https://github.com/pspdev/pspdev/discussions)! + +## Ways to contribute +{: .fs-6 .fw-700 } + +Before making any contribution, it's best to talk about what you want to do on [Discord](https://discord.gg/bePrj9W). After that, here are some places you can look to contribute: + +- Found a bug or are you missing something? [Submit a bug, feature request or pull request](https://github.com/pspdev/pspdev/issues/new)! +- Want to solve a bug? [Check our bug tracker here](https://github.com/issues?q=is%3Aopen+is%3Aissue+archived%3Afalse+user%3Apspdev+)! +- Want to add a library to support with PSP SDK? [Add your library here](https://github.com/pspdev/psp-packages/blob/master/CONTRIBUTING.md)! +- Want to add a PSP SDK function? [Add your function here](https://github.com/pspdev/pspsdk)! + +**Pull requests are always welcome!** + +## Where can I find the code? +{: .fs-6 .fw-700 } + +The PSP SDK is build using quite a few different repositories which each add their own piece to the system. If you just want to build everything at once, the [pspdev repository](https://github.com/pspdev/pspdev) is the place to go. + +There are automated builds, which build each part individually if there are changes. Here is a basic image showing the build order: + +![Image with order of repositories](images/repos.png) + +Lets go over what each repository in this list does and where they get the things they build from: + +- [psptoolchain-allegrex](https://github.com/pspdev/psptoolchain-allegrex) contains scripts to build the following tools: + - [binutils and gdb](https://github.com/pspdev/binutils-gdb) provide supporting tools for debugging, linking and building software. + - [gcc](https://github.com/pspdev/gcc) is the compiler used for building homebrew. + - [newlib](https://github.com/pspdev/newlib) is the C library used in PSPDEV, providing many posix functions. + - [pthread](https://github.com/pspdev/pthread-embedded) is a multithreading library used by `std::thread` in C++ among other things. +- [psptoolchain-extra](https://github.com/pspdev/psptoolchain-extra) contains scripts to build the following tools: + - [psp-pacman](https://github.com/pspdev/psp-pacman) is the package manager for installing and updating libraries. + - [psp-cmake](https://github.com/pspdev/psptoolchain-extra/blob/main/patches/psp-cmake) is a wrapper script for cmake using the psp toolchain file. + - [psp-pkg-config](https://github.com/pspdev/psptoolchain-extra/blob/main/patches/psp-pkg-config) is a wrapper script for pkg-config for libraries in PSPDEV. +- [psptoolchain](https://github.com/pspdev/psptoolchain) builds [psptoolchain-allegrex](https://github.com/pspdev/psptoolchain-allegrex) and [psptoolchain-extra](https://github.com/pspdev/psptoolchain-extra) combines them. +- [pspsdk](https://github.com/pspdev/pspsdk) contains all the PSP specific libraries that we consider to be part of the base system. A lot of functions offered by the official PSP SDK from Sony are also provided here. It also contains [samples](https://github.com/pspdev/pspsdk/tree/master/src/samples) for how to use these functions. +- [psp-packages](https://github.com/pspdev/psp-packages) contains build files for all the 3rd party libraries that are supported by PSPDEV. There are over 50 of them, including SDL2, curl, OpenGL, sqlite, lua and openal to just name a few. +- [pspdev](https://github.com/pspdev/pspdev) combines everything listed above and adds the following tools: + - [psplinkusb](https://github.com/pspdev/psplinkusb) provides the tools for debugging with psplink. I also contains psplink itself. + - [ebootsigner](https://github.com/pspdev/ebootsigner) is a tool for making homebrew able to run on official firmares from Sony. + +Pull requests for any repository are always appreciated! Have fun contributing and don't forget to say hi on [Discord](https://discord.gg/bePrj9W) or on the [GitHub Discussions](https://github.com/pspdev/pspdev/discussions) page! diff --git a/debugging.md b/debugging.md new file mode 100644 index 0000000..e9e3b31 --- /dev/null +++ b/debugging.md @@ -0,0 +1,157 @@ +--- +title: Debugging +layout: home +nav_order: 5 +--- + +# Debugging +{: .fs-8 .fw-700 .text-center } + +When developing for the Playstation Portable (PSP), you may run into crashes or code that does not quite work like expected. Figuring out what is going in is called debugging. This page will cover how to do that. + +## PSPLINK +{: .fs-6 .fw-700 } + +PSPLINK is THE tool to use for testing code on the PSP. It is an application which allows you to run and debug programs for the PSP from your PC through USB without requiring data to be transferred to the PSP. Setting it up for use requires different action for the PSP and the PC. + +### Setting PSPLINK up on the PSP +{: .fs-4 .fw-700 } + +Download the latest version of PSPLINK for the PSP [here](https://github.com/pspdev/psplinkusb/releases/download/latest/psplink.zip) and extract it in ``ms0:/PSP/GAME`` on the PSP memory card. + +### Setting PSPLINK up on the PC +{: .fs-4 .fw-700 } + +Depending on the operating system used the setup on PC is different. Pick the setup guide for your system here: + +- [Windows](psplink/windows.html) +- [Linux](psplink/linux.html) + +MacOS should not require any additional setup. + +### Using PSPLINK +{: .fs-4 .fw-700 } + +To be able to use PSPLINK with Playstation Portable homebrew, the homebrew will need to be build into an unencrypted ``.prx`` file. This can be done by running CMake like `psp-cmake -DBUILD_PRX=1 .` or if you're using a Makefile by adding `BUILD_PRX=1` to it. Then build the homebrew. + +After having done all of the above, PSPLINK can be used using the following steps: + +1. Connect the PSP with a USB cable to the computer. +2. Launch the PSPLINK homebrew on the PSP. The PSP is now waiting for input from the PC. +3. In the build directory of the homebrew you wish to test, open a terminal and run the following: + ```sh + usbhostfs_pc + ``` + Keep this running! +4. Then open another terminal window and run the following there: + ```sh + pspsh + ``` +5. Now you can simply start our homebrew on the PSP by running the following command in the pspsh window: + ```sh + ./myhomebrew.prx + ``` + Replace myhomebrew with the name of the `.prx` file which was generated. Now the PSP should be running your project! + +When you're done with the current build, just run `reset`, rebuild the homebrew and try again. + +Options available can be found when using the `help` command, but here are some notable ones: + +- `scrshot screenshotname.bmp` for taking a screenshot. +- `exit` for closing PSPLINK on the PSP. +- `poweroff` for shutting down the PSP. + +### Getting Basic Crash Information +{: .fs-4 .fw-700 } + +When a crash happens a crash log will be shown with a hint of what might have happened at the top and some additional info. If you wish to figure out where the crash happened, only the address is needed. + +To figure out where the crash happened, open another terminal in the build directory and use the address shown by PSPLINK in the following command: + +```sh +psp-addr2line -e myhomebrew address +``` + +Replace `address` with the actual adress and replace myhomebrew with the name of the elf file. This is **NOT** the `.prx` file and either has no extension or `.elf` depending on the build system used. + +If no result is returned, make sure to build with the `-g` or `-g3` option and without the `-O` option to make sure `psp-addr2line` knowns the function names and locations. + +The information received from `psp-addr2line` will be limited and not always useful, for more information you'll have to use a debugger as described below. + +## Using a Debugger +{: .fs-6 .fw-700 } + +When using `psp-addr2line` is not enough to figure out what is going on, the best way to debug will be by using an actual debugger called GDB, which comes bundled with the PSP SDK as the `psp-gdb` command. PSPLINK allows this debugger to connect directly to the PSP. + +### Preparation +{: .fs-4 .fw-700 } + +Prepare a separate terminal for `usbhostfs_pc`, `pspsh` and `psp-gdb`. Open all of them in the directory in which your compiled `.prx` and the `elf` (PSP binary) files are located. + +#### 1. usbhostfs_pc +{: .fs-2 .fw-700 } + +Run `usbhostfs_pc` on your terminal dedicated for `usbhostfs_pc` and you will see the `waiting for device...` status. + +Now start the PSPLINK app on your PSP and connect the USB cable. You should see the `connected to device` status in the terminal, which means success. + +**Do not close this terminal after that.** + +#### 2. pspsh +{: .fs-2 .fw-700 } + +Run `pspsh` on your terminal dedicated for `pspsh` and you will see the `host0:/>`. Now run `debug file.prx`, and it will display something like this: + +```sh +PSPLink USB GDBServer (c) 2k7 TyRaNiD +host0:/> Loaded host0:/ - UID 0x0408A763, Entry 0x088040AC +``` + +> You need to replace `file.prx` with the file you need to debug. This is a `.prx` file. + +It means the debugger is succesfully loaded. You can type `reset` if there's something wrong with your GDBServer. + +#### 3. psp-gdb +{: .fs-2 .fw-700 } + +In a new terminal run `psp-gdb file -q` and you will see something like this: + +> You need to replace `file` with the elf file of the program you're trying to debug. It has the same name as the file loaded in pspsh, but without the `.prx` ending. + +> Check if your binary has enabled the debug symbols required for debugging by using `objdump --syms` command and should produce an output but if it says `no symbols` then it is disabled(You can enable it by adding `-g` option to gcc). + +```sh +Reading symbols from ... +(gdb) +``` + +> `` is the name of the binary you are debugging. + +then type the `target remote :10001` to connect to your GDBServer and you will see the gdb output something like this: + +```sh +Remote debugging using :10001 +_start (args=0, argp=0x0) at crt0_prx.c:103 +103 if (&sce_newlib_nocreate_thread_in_start != NULL) { +(gdb) +``` +This will display the `_start` routine, it means you succesfully connected and ready to the debug your app! + +Here are a few useful commands for getting around in psp-gdb: +- `b` or `break` - for setting breakpoints +- `c` or `continue` - for resuming program execution until the next breakpoint or program completion +- `s` or `step` - for executing the current line and, if it contains a function call, step into that function +- `n` or `next` - for executing the current line, but if it contains a function call, step over it without diving into the function +- `f` or `finish` - for executing the remaining lines of the current function and return to the caller +- `bt` or `backtrace` - for getting stacktrace +- `p $var` or `print $var` - for displaying the value of specific variable +- `i r` or `info registers` - for displaying the contents of CPU registers +- `d` or `delete` - for deleting all breakpoints +- `q` or `quit` - for exiting from psp-gdb + +You can type `help` for more information about the psp-gdb commands. + +## Done +{: .fs-6 .fw-700 } + +Now you know how to debug your code. Make sure to check out the [Tips and Tricks](tips_tricks.html) section to get most out of your PSP development experience. diff --git a/documentation.md b/documentation.md deleted file mode 100644 index 7982a34..0000000 --- a/documentation.md +++ /dev/null @@ -1,15 +0,0 @@ - -PSPDEV is made out of several components. Here is a (non-exhaustive) list of -links to the documentation available for them: - - - [PSPSDK](https://pspdev.github.io/pspsdk/): The documentation for the - developer kit. - - [PSP Allegrex documentation](https://pspdev.github.io/vfpu-docs/): - Non-official documentation on the PSP CPU and VFPU. - - [PSPLink Manual](https://pspdev.github.io/psplinkusb/psplink_manual.pdf): - User manual for the PSPLink debugging software. - - [Unofficial PSP docs](http://uofw.github.io/upspd/): A collection of docs - from different authors and sources, covering more specific topics. - - [Yet Another PSP Documentation](http://hitmen.c02.at/files/yapspd/): A very - detailed hardware documentation, including software interfaces. - diff --git a/downloads.md b/downloads.md new file mode 100644 index 0000000..4f03ccd --- /dev/null +++ b/downloads.md @@ -0,0 +1,19 @@ +--- +title: Downloads +layout: home +nav_order: 7 +--- + +# Downloads +{: .fs-8 .fw-700 .text-center } + +Download the latest update for the PSP SDK here. If you don't have it setup yet, go to the [installation instructions](installation.html) instead! Otherwise click on the link for your system: + +- [Windows/Ubuntu](https://github.com/pspdev/pspdev/releases/latest/download/pspdev-ubuntu-latest-x86_64.tar.gz) +- [MacOS (arm64)](https://github.com/pspdev/pspdev/releases/latest/download/pspdev-macos-latest-arm64.tar.gz) +- [MacOS (x86_64)](https://github.com/pspdev/pspdev/releases/latest/download/pspdev-macos-13-x86_64.tar.gz) +- [Fedora](https://github.com/pspdev/pspdev/releases/latest/download/pspdev-fedora-latest.tar.gz) +- [Debian](https://github.com/pspdev/pspdev/releases/latest/download/pspdev-debian-latest.tar.gz) +- [Docker](https://hub.docker.com/r/pspdev/pspdev) + +Alternatively, development builds are available [here](https://github.com/pspdev/pspdev/releases/tag/latest). Only get these if you cannot wait a couple of weeks for a specific new feature or you are working on improving the SDK itself. diff --git a/images/pspdev.ico b/favicon.ico similarity index 100% rename from images/pspdev.ico rename to favicon.ico diff --git a/how_to_use.md b/how_to_use.md new file mode 100644 index 0000000..cddd396 --- /dev/null +++ b/how_to_use.md @@ -0,0 +1,94 @@ +--- +title: How to Use +layout: home +nav_order: 3 +--- + +# How to use +{: .fs-8 .fw-700 .text-center } + +This page will describe how to use the PSP SDK to build a basic program for the Playstation Portable (PSP), including screenshots. The screenshots will mainly be for Windows users, but the steps will not be much different for other operating systems, so you should be able to follow along. + +Before going through this guide, make sure to have followed the [installation instructions](installation.html) first. + +# Install a code editor +{: .fs-6 .fw-700 } + +For developing programs for the PSP it is recommended to use [Visual Studio Code](https://code.visualstudio.com/). You can download the installer for it on the official website [here](https://code.visualstudio.com/Download). Please install it before continuing this guide. + +While using Visual Studio Code, you may be asked to install useful plugins, which is a good idea to do. + +# Creating a project +{: .fs-6 .fw-700 } + +When you open Visual Studio Code, you'll be greeted by the welcome screen. Simply click the `Open Folder...` link on it or select this option from the `File` menu to get started: + +![](images/vscode-welcome.png) + +Create a new folder and give it the name of your new project. As an example, lets take `hello world`: + +![](images/vscode-create-folder.png) + +Then click on the folder and click on the `Select Folder` button: + +![](images/vscode-select-folder.png) + +Now you've successfully created a new project. + +# Writing a simple program +{: .fs-6 .fw-700 } + +To start, clicking the `New File` button in Visual Studio Code, type the name `main.c` and press enter: + +![](images/vscode-create-file.png) + +Lets add some very basic code to the file: + +```c +{% include samples/hello/main.c %} +``` + +This code will print "Hello World!" to the screen each frame. This may seem complex at first, but the `exit_callback`, `callback_thread` and `setup_callbacks` are just there to make the home button work and can be reused for any project. They only have to be run once. The `PSP_MODULE_INFO` is required and just contains the name of the software. `PSP_MAIN_THREAD_ATTR` will be set like this for every program. Only the content of the `main` function really matters here. + +Now add an aditional file called `CMakeLists.txt`. Make sure the case matches, `cmakelists.txt` is not valid. + +Add the following lines to `CMakeLists.txt`: + +```cmake +{% include samples/hello/CMakeLists.txt %} +``` + +The `CMakeLists.txt` file is used for CMake, which allows you to build the code. It contains which files to add to the program in the `add_executable` function and which libraries to link to using the `target_link_libraries` function. In this case we just link to the libraries required to write text to the screen. The `create_pbp_file` function is used to create an `EBOOT.PBP` file, so we can run on the program on the PSP. + +# Building the code +{: .fs-6 .fw-700 } + +For building, a terminal is used with a couple of short commands. To open a terminal in Visual Studio Code, select `Terminal` in the top bar and select `New Terminal`: + +![](images/vscode-open-terminal.png) + +This will open a terminal at the bottom of the screen. On Windows, this will be a powershell window, but the PSP SDK is installed in WSL. To open a WSL terminal instead, click on the arrow next to the `+` sign at the right side an select `Ubuntu (WSL)`: + +![](images/vscode-ubuntu-shell.png) + +Now the code can be build with the following set of simple commands: + +```shell +mkdir build +cd build +psp-cmake .. +make +``` + +The first line will create the `build` folder. The `cd` command moves you into the `build` folder. The `psp-cmake` command will create `Makefile` for the `make` command to be able to build the program, which happens in the last line. + +After running these commands, you can go to the build folder in your project to find the `EBOOT.PBP` file. This file can be copied to a new folder in the `GAME` folder of your PSP memory stick. Then you'll be able to launch it. It should look like this: + +![](images/hello.png) + +If you make changes and you want to build the program with the new code, you'll only have to run `make` again. Do make sure you are in the build directory, though. If you are not, you can switch to it with `cd build`. + +# Writing your own code +{: .fs-6 .fw-700 } + +Now you know how to create code files and build them for the PSP, you will be able to create your own. For more examples of what kind of code you can write, take a look at the [Basic Programs page](basic_programs.html). diff --git a/images/ccleste.png b/images/ccleste.png new file mode 100644 index 0000000..89a0156 Binary files /dev/null and b/images/ccleste.png differ diff --git a/images/nzp.png b/images/nzp.png new file mode 100644 index 0000000..cb4829d Binary files /dev/null and b/images/nzp.png differ diff --git a/images/oceanpop.png b/images/oceanpop.png new file mode 100644 index 0000000..913b844 Binary files /dev/null and b/images/oceanpop.png differ diff --git a/images/repos.png b/images/repos.png new file mode 100644 index 0000000..51abf25 Binary files /dev/null and b/images/repos.png differ diff --git a/images/sdl2.png b/images/sdl2.png deleted file mode 100644 index 0ba7b41..0000000 Binary files a/images/sdl2.png and /dev/null differ diff --git a/images/shape.png b/images/shape.png index fd57133..0ba7b41 100644 Binary files a/images/shape.png and b/images/shape.png differ diff --git a/images/sprite.png b/images/sprite.png new file mode 100644 index 0000000..dc24630 Binary files /dev/null and b/images/sprite.png differ diff --git a/images/vscode-create-file.png b/images/vscode-create-file.png new file mode 100644 index 0000000..424a281 Binary files /dev/null and b/images/vscode-create-file.png differ diff --git a/images/vscode-create-folder.png b/images/vscode-create-folder.png new file mode 100644 index 0000000..fa142a3 Binary files /dev/null and b/images/vscode-create-folder.png differ diff --git a/images/vscode-open-terminal.png b/images/vscode-open-terminal.png new file mode 100644 index 0000000..6a72f2e Binary files /dev/null and b/images/vscode-open-terminal.png differ diff --git a/images/vscode-select-folder.png b/images/vscode-select-folder.png new file mode 100644 index 0000000..338ec50 Binary files /dev/null and b/images/vscode-select-folder.png differ diff --git a/images/vscode-ubuntu-shell.png b/images/vscode-ubuntu-shell.png new file mode 100644 index 0000000..a599b9a Binary files /dev/null and b/images/vscode-ubuntu-shell.png differ diff --git a/images/vscode-welcome.png b/images/vscode-welcome.png new file mode 100644 index 0000000..592c32b Binary files /dev/null and b/images/vscode-welcome.png differ diff --git a/images/windows-open-linux-shell.png b/images/windows-open-linux-shell.png new file mode 100644 index 0000000..c34041c Binary files /dev/null and b/images/windows-open-linux-shell.png differ diff --git a/index.md b/index.md new file mode 100644 index 0000000..d603c2a --- /dev/null +++ b/index.md @@ -0,0 +1,59 @@ +--- +title: Home +layout: home +nav_order: 1 +--- + +PSPDEV Logo +{: .text-center } + +# Welcome to PSPDEV +{: .fs-8 .fw-700 .text-center .lh-0 } + +# The PSP SDK for Homebrew +{: .fs-6 .fw-700 .text-center } + +PSPDEV is an open source software development kit (SDK) for PlayStation Portable (PSP) development. It allows you to make apps and games for both custom and official firmwares. **This is a community project made by enthusiasts, it is in no way affiliated with Sony**. +{: .fs-5 .text-center } + +# Getting started +{: .fs-6 .fw-700 } + +Install our open source [PlayStation Portable Software Development Kit](installation.html). +{: .fs-5 } + +Already have the PSP SDK installed? Dive in and [get started with PSP SDK Homebrew development](how_to_use.html). +{: .fs-5 } + +Need some inspiration? Check out our [PSP SDK examples](basic_programs.html). +{: .fs-5 } + +Is your code is not working? [Debug it using PSPLINK](debugging.html). +{: .fs-5 } + +Want to improve your PSP SDK homebrew development experience? Get some [tips and tricks here](tips_tricks.html). +{: .fs-5 } + +# Contact Us +{: .fs-6 .fw-700 } + +If you have ideas, suggestions or questions, please don't hesitate to use our [PSPDEV GitHub Discussions](https://github.com/pspdev/pspdev/discussions). +{: .fs-5 } + +If you need help or would like to contribute, don't hesitate to join us on [Discord](https://discord.gg/bePrj9W) or open an issue on [GitHub](https://github.com/pspdev/pspdev/issues). See you there! +{: .fs-5 } + +# Made with PSP SDK by the PSPDEV community <3 +{: .fs-6 .fw-700 } + +| [![nzportable screenshot](images/nzp.png)](https://github.com/nzp-team/nzportable) | +{: .text-center } + +| [![oceanpop screenshot](images/oceanpop.png)](https://github.com/sharkwouter/oceanpop) | +{: .text-center } + +| [![ccleste screenshot](images/ccleste.png)](https://github.com/fjtrujy/ccleste/tree/psp-fixes) | +{: .text-center } + +And so much more! +{: .text-center } diff --git a/installation.md b/installation.md new file mode 100644 index 0000000..7b9c8cb --- /dev/null +++ b/installation.md @@ -0,0 +1,19 @@ +--- +title: Installation +layout: home +nav_order: 2 +--- + +# Installation +{: .fs-8 .fw-700 .text-center } + +Pick the installation guide for your system: + +- [Windows](installation/windows.html) +- [MacOS](installation/macos.html) +- [Ubuntu](installation/ubuntu.html) +- [Fedora](installation/fedora.html) +- [Debian](installation/debian.html) +- [Arch Linux](installation/arch.html) + +If your operating system is not listed above, use the [Docker installation guide](installation/docker.html). diff --git a/installation/arch.md b/installation/arch.md new file mode 100644 index 0000000..9ff63f1 --- /dev/null +++ b/installation/arch.md @@ -0,0 +1,107 @@ +--- +title: Installation on Arch Linux +layout: home +nav_exclude: true +--- + +# Installation on Arch Linux +{: .fs-8 .fw-700 .text-center } + + +## Prerequisites +{: .fs-6 .fw-700 } + +Arch Linux users can install the PSP SDK using packages available in the Arch +User Repository (AUR). There are two primary options: a pre-compiled binary +package (recommended for faster installation) and a source package (which builds +the SDK locally). + +### AUR Helper (Optional but Recommended) +{: .fs-4 .fw-700 } + +An AUR helper (like `yay`, `paru`, etc.) simplifies installing and updating AUR +packages. If you don't have one, you can find instructions on the +[Arch Wiki's AUR helpers page](https://wiki.archlinux.org/title/AUR_helpers). +Using an AUR helper is assumed for the simplified commands below, but manual +installation steps are also provided. + +## Installation via AUR (Recommended - Binary) +{: .fs-6 .fw-700 } + +The [`psp-sdk-bin`](https://aur.archlinux.org/packages/psp-sdk-bin) package, +provides pre-compiled binaries for the PSP SDK, making installation much faster. + +### Using an AUR helper (e.g., `yay`) +{: .fs-4 .fw-700 } + +```shell +yay -S psp-sdk-bin +``` + +### Manual Installation +{: .fs-4 .fw-700 } + +```shell +# Clone the build files +git clone https://aur.archlinux.org/psp-sdk-bin.git +cd psp-sdk-bin + +# Build and install the package +makepkg -si + +# Clean up (optional) +cd .. +rm -rf psp-sdk-bin +``` + +## Installation via AUR (Alternative - Source) +{: .fs-6 .fw-700 } + +The [`psp-sdk`](https://aur.archlinux.org/packages/psp-sdk) package builds the +entire SDK from source. This takes significantly longer but ensures you are +building against your system's exact libraries. + +**Warning:** Building the full SDK can take a considerable amount of time and +CPU resources. + +### Using an AUR helper (e.g., `yay`) +{: .fs-4 .fw-700 } + +```shell +yay -S psp-sdk +``` + +### Manual Installation +{: .fs-4 .fw-700 } + +```shell +# Clone the build files +git clone https://aur.archlinux.org/psp-sdk.git +cd psp-sdk + +# Build and install the package (this will take a while!) +makepkg -si + +# Clean up (optional) +cd .. +rm -rf psp-sdk +``` + +## Verification +{: .fs-6 .fw-700 } + +From a new terminal, run the following command to confirm the SDK is found and +the environment variable is set: + +```shell +psp-config --pspdev-path +``` + +This command should output the path you set for `PSPDEV` (e.g., `/opt/pspdev`). +If the command itself is not found, ensure `/opt/pspdev/bin` (or the equivalent +`bin` directory for your installation) is in your `PATH`. The profile script +installed by the AUR package should handle this automatically after logging out +and back in or rebooting. + +That's it, now the PSP SDK can be used to build PSP software. Check out the +[How to Use](../how_to_use.html) page for a guide on how to do so. diff --git a/installation/debian.md b/installation/debian.md new file mode 100644 index 0000000..d714a7f --- /dev/null +++ b/installation/debian.md @@ -0,0 +1,46 @@ +--- +title: Installation on Debian +layout: home +nav_exclude: true +--- + +# Installation on Debian +{: .fs-8 .fw-700 .text-center } + +## Dependencies +{: .fs-6 .fw-700 } + +The PSP SDK requires a couple of dependencies to be installed before use. To install them, run the following command from a terminal: + +```shell +sudo apt-get update +``` + +```shell +sudo apt-get install build-essential cmake pkgconf libreadline8 libusb-0.1 libgpgme11 libarchive-tools fakeroot +``` + +## PSP SDK +{: .fs-6 .fw-700 } + +Installing the PSP SDK itself can be done with the following steps: + +1. Download [the latest version of the SDK here](https://github.com/pspdev/pspdev/releases/latest/download/pspdev-debian-latest.tar.gz). +2. Extract the downloaded archive into your home directory, resulting in `/home/YOURUSERNAME/pspdev` being created. +3. To make the SDK usable, some environment variables need to be set. The first step in doing so it to open the `~/.bashrc` file with the `nano` text editor using the following command from a terminal: + ```shell + nano ~/.bashrc + ``` +4. Add the following lines at the bottom of the file in the text editor: + ```shell + export PSPDEV="$HOME/pspdev" + export PATH="$PATH:$PSPDEV/bin" + ``` +5. Now save and exit by pressing `Ctrl`+`X`, then `Y` and then enter/return. +6. Close the current terminal and open a new one. +7. From the new terminal, run the following command to confirm everything is set up correctly: + ```shell + psp-config --pspdev-path + ``` + +That's it, now the PSP SDK can be used to build PSP software. Check out the [How to Use](../how_to_use.html) page for a guide on how to do so. diff --git a/installation/docker.md b/installation/docker.md new file mode 100644 index 0000000..c7780f2 --- /dev/null +++ b/installation/docker.md @@ -0,0 +1,42 @@ +--- +title: Installation on Docker +layout: home +nav_exclude: true +--- + +# Installation on Docker +{: .fs-8 .fw-700 .text-center } + +## Docker +{: .fs-6 .fw-700 } + +Docker can be used on almost every platform and offers and easy way to use the PSP SDK with very little setup. + +To use it, install Docker itself using the instructions [here](https://docs.docker.com/engine/install/). + +## PSP SDK +{: .fs-6 .fw-700 } + +Once docker is installed, the PSPDEV image can be downloaded using the following command from a terminal: + +```shell +docker pull pspdev/pspdev:latest +``` + +To work with it, open a terminal in the directory with the code you'd like to build in it and run the following command: + +```shell +docker run -ti -v $PWD:/source pspdev/pspdev:latest +``` + +This mounts the current directory to a directory called source in the container, so run `cd /source` to navigate to it. + +That's it, now the PSP SDK can be used to build PSP software. Check out the [Basic Programs](../basic_programs.html) page to for examples on what you can do with it. + +### Windows + +Using the container on Windows can be a bit tricky. + +* Replace $PWD with the absolute path in a UNIX format. Example: `/c/Users/John/my_psp_code`. +* Your code *must* be located somewhere under "home folder" (like `C:\Users\John`), or the mounted directory will be empty when viewed from inside the container due to permissions. +* If you get an `Operation not permitted` error from gmake while using psp-cmake, you'll need to add the `--privileged=true` option to your `docker run` command. diff --git a/installation/fedora.md b/installation/fedora.md new file mode 100644 index 0000000..58db144 --- /dev/null +++ b/installation/fedora.md @@ -0,0 +1,42 @@ +--- +title: Installation on Fedora +layout: home +nav_exclude: true +--- + +# Installation on Fedora +{: .fs-8 .fw-700 .text-center } + +## Dependencies +{: .fs-6 .fw-700 } + +The PSP SDK requires a couple of dependencies to be installed before use. To install them, run the following command from a terminal: + +```shell +sudo dnf -y install @development-tools cmake bsdtar libusb-compat-0.1 gpgme fakeroot xz nano +``` + +## PSP SDK +{: .fs-6 .fw-700 } + +Installing the PSP SDK itself can be done with the following steps: + +1. Download [the latest version of the SDK here](https://github.com/pspdev/pspdev/releases/latest/download/pspdev-fedora-latest.tar.gz). +2. Extract the downloaded archive into your home directory, resulting in `/home/YOURUSERNAME/pspdev` being created. +3. To make the SDK usable, some environment variables need to be set. The first step in doing so it to open the `~/.bashrc` file with the `nano` text editor using the following command from a terminal: + ```shell + nano ~/.bashrc + ``` +4. Add the following lines at the bottom of the file in the text editor: + ```shell + export PSPDEV="$HOME/pspdev" + export PATH="$PATH:$PSPDEV/bin" + ``` +5. Now save and exit by pressing `Ctrl`+`X`, then `Y` and then enter/return. +6. Close the current terminal and open a new one. +7. From the new terminal, run the following command to confirm everything is set up correctly: + ```shell + psp-config --pspdev-path + ``` + +That's it, now the PSP SDK can be used to build PSP software. Check out the [How to Use](../how_to_use.html) page for a guide on how to do so. diff --git a/installation/macos.md b/installation/macos.md new file mode 100644 index 0000000..8e9d18a --- /dev/null +++ b/installation/macos.md @@ -0,0 +1,50 @@ +--- +title: Installation on MacOS +layout: home +nav_exclude: true +--- + +# Installation on MacOS +{: .fs-8 .fw-700 .text-center } + +## Dependencies +{: .fs-6 .fw-700 } + +The PSP SDK requires a couple of dependencies to be installed before use. Installing them can be done using [brew](https://brew.sh/). + +Once brew is installed, run the following command from a terminal to install the dependencies: + +```shell +brew install cmake pkgconf gnu-sed bash openssl libtool libmpc libarchive gettext texinfo bison flex isl gsl gmp mpfr libusb-compat zlib +``` + +## PSP SDK +{: .fs-6 .fw-700 } + +Installing the PSP SDK itself can be done with the following steps: + +1. Download the latest version of the SDK for your system here: + - [arm64](https://github.com/pspdev/pspdev/releases/latest/download/pspdev-macos-latest-arm64.tar.gz) for M1 or newer CPUs. + - [x86_64](https://github.com/pspdev/pspdev/releases/latest/download/pspdev-macos-13-x86_64.tar.gz) for Intel CPUs. +2. Extract the downloaded archive into your home directory, resulting in `/home/YOURUSERNAME/pspdev` being created. +3. To make the SDK usable, some environment variables need to be set. The first step in doing so it to open the `~/.zprofile` file with the `pico` text editor using the following command from a terminal: + ```shell + pico ~/.zprofile + ``` +4. Add the following lines at the bottom of the file in the text editor: + ```shell + export PSPDEV="$HOME/pspdev" + export PATH="$PATH:$PSPDEV/bin" + ``` +5. Now save and exit by pressing `Ctrl`+`X`, then `Y` and then enter/return. +6. Run the following command to remove the gatekeeper quarantine, allowing executables to be run: + ```shell + xattr -rd com.apple.quarantine $HOME/pspdev + ``` +7. Close the current terminal and open a new one. +8. From the new terminal, run the following command to confirm everything is set up correctly: + ```shell + psp-config --pspdev-path + ``` + +That's it, now the PSP SDK can be used to build PSP software. Check out the [How to Use](../how_to_use.html) page for a guide on how to do so. diff --git a/installation/ubuntu.md b/installation/ubuntu.md new file mode 100644 index 0000000..d59013a --- /dev/null +++ b/installation/ubuntu.md @@ -0,0 +1,46 @@ +--- +title: Installation on Ubuntu +layout: home +nav_exclude: true +--- + +# Installation on Ubuntu +{: .fs-8 .fw-700 .text-center } + +## Dependencies +{: .fs-6 .fw-700 } + +The PSP SDK requires a couple of dependencies to be installed before use. To install them, run the following command from a terminal: + +```shell +sudo apt-get update +``` + +```shell +sudo apt-get install build-essential cmake pkgconf libreadline8 libusb-0.1 libgpgme11 libarchive-tools fakeroot +``` + +## PSP SDK +{: .fs-6 .fw-700 } + +Installing the PSP SDK itself can be done with the following steps: + +1. Download [the latest version of the SDK here](https://github.com/pspdev/pspdev/releases/latest/download/pspdev-ubuntu-latest-x86_64.tar.gz). +2. Extract the downloaded archive into your home directory, resulting in `/home/YOURUSERNAME/pspdev` being created. +3. To make the SDK usable, some environment variables need to be set. The first step in doing so it to open the `~/.bashrc` file with the `nano` text editor using the following command from a terminal: + ```shell + nano ~/.bashrc + ``` +4. Add the following lines at the bottom of the file in the text editor: + ```shell + export PSPDEV="$HOME/pspdev" + export PATH="$PATH:$PSPDEV/bin" + ``` +5. Now save and exit by pressing `Ctrl`+`X`, then `Y` and then enter/return. +6. Close the current terminal and open a new one. +7. From the new terminal, run the following command to confirm everything is set up correctly: + ```shell + psp-config --pspdev-path + ``` + +That's it, now the PSP SDK can be used to build PSP software. Check out the [How to Use](../how_to_use.html) page for a guide on how to do so. diff --git a/installation/windows.md b/installation/windows.md new file mode 100644 index 0000000..de43482 --- /dev/null +++ b/installation/windows.md @@ -0,0 +1,74 @@ +--- +title: Installation on Windows +layout: home +nav_exclude: true +--- + +# Installation on Windows +{: .fs-8 .fw-700 .text-center } + +## Windows Subsystem for Linux (WSL) +{: .fs-6 .fw-700 } + +On Windows the PSP SDK is run on Ubuntu running on Microsoft's WSL. This is very easy to set up and will offer us the full power of Linux from a Windows machine. + +To set up WSL with Ubuntu in it run the following commands in a Powershell window started as administrator (right click run as administrator on Powershell in the start menu): + +```powershell +wsl --install +``` + +When this is done, restart your computer. Afterwards Ubuntu can be selected from the start menu to open a terminal, do this once to set up your user. + +From now on the Ubuntu shell will be used when running commands going forward. + +**Note:** You can open an Ubuntu terminal in a specific folder by holding shift and clicking the right mouse button on the background in the file explorer and selecting `Open Linux shell here`: + +![](../images/windows-open-linux-shell.png) + +This can be useful when building a specific project. + +## Dependencies +{: .fs-6 .fw-700 } + +The PSP SDK requires a couple of dependencies to be installed before use. To install them, run the following command from an Ubuntu terminal: + +```shell +sudo apt-get update +``` + +```shell +sudo apt-get install build-essential cmake pkgconf libreadline8 libusb-0.1 libgpgme11 libarchive-tools fakeroot wget +``` + +## PSP SDK +{: .fs-6 .fw-700 } + +Installing the PSP SDK itself can be done with the following steps: + +1. In a fresh WSL Session download the SDK using the following command: + ```shell + wget https://github.com/pspdev/pspdev/releases/latest/download/pspdev-ubuntu-latest-x86_64.tar.gz + ``` +2. Extract the archive using: + ```shell + tar -xvf pspdev-ubuntu-latest-x86_64.tar.gz + ``` +3. To make the SDK usable, some environment variables need to be set. The first step in doing so it to open the `~/.bashrc` file with the `nano` text editor using the following command from an Ubuntu terminal: + ```shell + nano ~/.bashrc + ``` +4. Add the following lines at the bottom of the file in the text editor: + ```shell + export PSPDEV="$HOME/pspdev" + export PATH="$PATH:$PSPDEV/bin" + ``` +5. Now save and exit by pressing `Ctrl`+`X`, then `Y` and then enter/return. +6. Close the current Ubuntu terminal and open a new one. +7. From the new Ubuntu terminal, run the following command to confirm everything is set up correctly: + ```shell + psp-config --pspdev-path + ``` + If everything is set up correctly, the path of the PSP SDK installation will be shown. + +That's it, now the PSP SDK can be used to build PSP software. Check out the [How to Use](../how_to_use.html) page for a guide on how to do so. diff --git a/psplink/linux.md b/psplink/linux.md new file mode 100644 index 0000000..26246bf --- /dev/null +++ b/psplink/linux.md @@ -0,0 +1,24 @@ +--- +title: Setting up PSPLINK on Linux +layout: home +nav_exclude: true +--- + +# Setting up PSPLINK on Linux +{: .fs-8 .fw-700 .text-center } + +With Linux PSPLINK will work without making any changes, but it will require using sudo for the `usbhostfs_pc` command. To make it work without sudo, a udev rule can be added. + +To make using PSPLINK without sudo create file called `/etc/udev/rules.d/50-psplink.rules` (for example with `sudo nano /etc/udev/rules.d/50-psplink.rules`) and add the following content: + +``` +SUBSYSTEM=="usb", ATTR{idVendor}=="054c", ATTR{idProduct}=="01c9", SYMLINK+="psp", MODE="0666" +``` + +Save this, in Nano this can be done with Ctrl+O and pressing enter. The run the following command: + +``` +sudo udevadm control --reload +``` + +Now PSPLINK can be used without sudo. Continue with the instructions on the [Debugging](../debugging.html) page. diff --git a/psplink/windows.md b/psplink/windows.md new file mode 100644 index 0000000..7b777d4 --- /dev/null +++ b/psplink/windows.md @@ -0,0 +1,20 @@ +--- +title: Setting up PSPLINK on Windows +layout: home +nav_exclude: true +--- + +# Setting up PSPLINK on Windows +{: .fs-8 .fw-700 .text-center } + +On Windows a driver needs to be installed before PSPLINK can be used. To do this take the following steps: + +1. Make sure the programs `usbhostfs_pc` and `pspsh` are available in cmd. Otherwise download them [here](https://github.com/pspdev/psplinkusb/releases/download/latest/pspsh-windows.zip). +2. Start PSPLINK on the Playstation Portable and connect it to the computer through USB. +3. Download [Zadig](https://zadig.akeo.ie/) and start it. It will ask if you want to run it as administrator, click yes. +4. In Zadig, click on `options` -> `List All Devices`. +5. Select the entry `"PSP" type B` from the dropdown list. +6. Left of driver, select the `libusb-win32` driver. Then click install. +7. Wait for the installation to finish, then disconnect the USB cable from the PSP. + +Now PSPLINK can be used with Windows. Continue with the instructions on the [Debugging](../debugging.html) page. diff --git a/resources/grass.png b/resources/grass.png new file mode 100644 index 0000000..9f8471a Binary files /dev/null and b/resources/grass.png differ diff --git a/tips_tricks.md b/tips_tricks.md new file mode 100644 index 0000000..f2009f7 --- /dev/null +++ b/tips_tricks.md @@ -0,0 +1,96 @@ +--- +title: Tips and Tricks +layout: home +nav_order: 6 +--- + +# Tips and Tricks +{: .fs-8 .fw-700 .text-center } + +Here some useful tips for developing for the PSP. + +## Making Programs Work on Unmodded PSPs +{: .fs-6 .fw-700 } + +The PSP SDK contains tools for making your program work on unmodded PSPs. This can be done by running psp-cmake with some additional commands when building like so: + +```shell +mkdir build && cd build +``` + +```shell +psp-cmake -DBUILD_PRX=1 -DENC_PRX=1 .. && make +``` + + +This does require `create_pbp_file` to be used in your CMakeLists.txt file. After the first build, running `make` is enough to get an `EBOOT.PBP` file which works on official firmware with any new changes made to the code. + +## Add PSP Specific Code to a Multi-Platform Programs +{: .fs-6 .fw-700 } + +When porting a game to the PSP, some PSP specific code might be needed. To make this code only apply to PSP, it is possible to use a simple ifdef statements which checks for `__PSP__` like so: + +```c +#ifdef __PSP__ + // Do PSP specific thing +#else + // Do the thing all other systems should do +#endif +``` + +This makes sure that the other systems supported by the program keeps working the same, while still making it possible to add support for the PSP. + +## Managing Libraries +{: .fs-6 .fw-700 } + +There are many C and C++ libraries available within the PSP SDK and most of them will be installed by default. Libraries are where most of the updates within the SDK happen and they can be updated manually without redownload the SDK using `psp-pacman`. + +Updating the libraries installed can be done with the following command: + +```shell +psp-pacman -Syu +``` + +After updating, you can list all available libraries with the following command: + +```shell +psp-pacman -Sl +``` + +For a full list with information on each library, it's easiest to take a look on the [repository's web pages](https://pspdev.github.io/psp-packages). + +Installing a library can be done with the following command: + +```shell +psp-pacman -S library +``` + +## Managing Licenses +{: .fs-6 .fw-700 } + +Every project made with the PSP SDK will import at least some libraries, each with their own license. Everything bundled is free to use, but some libraries will ask you to share their license with your project or in rare cases give users access to your code to respect their licenses. The `psp-create-license-directory` tool can be used to easily collect the licenses that apply to your project, so you can comply with them and ship them with your project. + +To create a directory with a copy of the licenses that are always used in project made with the PSP SDK use the following command: + +``` +psp-create-license-directory +``` + +For any library you added, for example `sdl2` or `jsoncpp`, you can add the licenses by adding the library names to the command: + +``` +psp-create-license-directory sdl2 jsoncpp +``` + +If you're not sure what the library you used is called exactly, you can use the `-l` option to list the installed libraries: + +``` +psp-create-license-directory -l +``` + +## Updating the PSP SDK +{: .fs-6 .fw-700 } + +A new version of the PSP SDK is released at least once a month, so updating should be done regularly if you want to benefit from new features and bug fixes. + +To update the SDK, simply follow the installation instruction for your system on the [Installation](installation.html) page. Installing the dependencies can be skipped.