diff --git a/.vscode/configurations/linux-docker/c_cpp_properties.json b/.vscode/configurations/linux-docker/c_cpp_properties.json new file mode 100644 index 0000000..a846f7e --- /dev/null +++ b/.vscode/configurations/linux-docker/c_cpp_properties.json @@ -0,0 +1,41 @@ +{ + "configurations": [ + { + "name": "Docker PS2SDK (Linux)", + "includePath": [ + "${workspaceFolder}/**", + "~/ps2dev-intellisense/ps2sdk/common/include/**", + "~/ps2dev-intellisense/ps2sdk/ee/include/**", + "~/ps2dev-intellisense/ps2sdk/iop/include/**", + "~/ps2dev-intellisense/ps2sdk/ports/include/**", + "~/ps2dev-intellisense/ee/include/**", + "~/ps2dev-intellisense/ee/lib/gcc/mips64r5900el-ps2-elf/11.3.0/include/**", + "~/ps2dev-intellisense/ee/lib/gcc/mips64r5900el-ps2-elf/11.3.0/include-fixed/**", + "~/ps2dev-intellisense/ee/lib/gcc/mips64r5900el-ps2-elf/11.3.0/install-tools/include/**", + "~/ps2dev-intellisense/ee/lib/gcc/mips64r5900el-ps2-elf/11.3.0/plugin/include/**", + "~/ps2dev-intellisense/ee/mips64r5900el-ps2-elf/include/**", + "~/ps2dev-intellisense/ee/mips64r5900el-ps2-elf/sys-include/**", + "~/ps2dev-intellisense/gsKit/include/**", + "~/ps2dev-intellisense/iop/lib/gcc/mipsel-ps2-elf/11.3.0/include/**", + "~/ps2dev-intellisense/iop/lib/gcc/mipsel-ps2-elf/11.3.0/install-tools/include/**", + "~/ps2dev-intellisense/iop/lib/gcc/mipsel-ps2-elf/11.3.0/plugin/include/**", + "~/ps2dev-intellisense/iop/lib/gcc/mipsel-ps2-elf/11.3.0/include-fixed/**", + "~/ps2dev-intellisense/iop/lib/gcc/mipsel-ps2-irx/11.3.0/include/**", + "~/ps2dev-intellisense/iop/lib/gcc/mipsel-ps2-irx/11.3.0/install-tools/include/**", + "~/ps2dev-intellisense/iop/lib/gcc/mipsel-ps2-irx/11.3.0/plugin/include/**", + "~/ps2dev-intellisense/iop/lib/gcc/mipsel-ps2-irx/11.3.0/include-fixed/**" + ], + "defines": [ + "_EE", + "_IOP", + "__SPU__", + "INTELLISENSE" + ], + "cppStandard": "c++20", + "compilerPath": "", // Should be empty + "intelliSenseMode": "linux-gcc-x86", + "configurationProvider": "ms-vscode.cpptools" + } + ], + "version": 4 +} diff --git a/.vscode/configurations/linux-docker/settings.json b/.vscode/configurations/linux-docker/settings.json new file mode 100644 index 0000000..b090414 --- /dev/null +++ b/.vscode/configurations/linux-docker/settings.json @@ -0,0 +1,14 @@ +{ + "buildDirectory": "demo", + "C_Cpp.default.intelliSenseMode": "gcc-x86", + "files.associations": { + "*.vcl": "asm-collection", + "*.i": "asm-collection", + "*.vsm": "asm-collection", + "*.vclpp": "asm-collection", + "*.hpp": "cpp", + "*.cpp": "cpp", + "*.h": "c", + "*.c": "c" + } +} diff --git a/.vscode/configurations/linux-docker/tasks.json b/.vscode/configurations/linux-docker/tasks.json new file mode 100644 index 0000000..3242a74 --- /dev/null +++ b/.vscode/configurations/linux-docker/tasks.json @@ -0,0 +1,119 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Build & run", + "dependsOrder": "sequence", + "dependsOn": [ + "1. Copy source code to docker volume", + "2. Compile via docker container", + "3. Copy binaries to host", + "4. Run PCSX2" + ], + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "type": "shell", + "label": "1. Copy source code to docker volume", + "command": "docker exec -t tyra-compiler sh -c 'rsync -ac --delete --exclude \".git\" --exclude \"docs\" --exclude \".vscode\" --exclude \"tools\" --exclude \"obj\" --exclude \"bin\" /host/ /src/'" + }, + { + "type": "shell", + "label": "2. Compile via docker container", + "command": "docker exec -t tyra-compiler sh -c 'cd ${config:buildDirectory} && make build-engine all'", + "problemMatcher": { + "base": "$gcc", + "fileLocation": [ + "autoDetect" + ] + } + }, + { + "type": "shell", + "label": "3. Copy binaries to host", + "command": "docker exec -t tyra-compiler sh -c 'rsync -zac --include=\"*/\" --include=\"bin/**\" --exclude=\"*\" /src/ /host/'" + }, + { + "type": "shell", + "label": "4. Run PCSX2", + "options": { + "cwd": "${config:buildDirectory}" + }, + "command": "./run.sh" + }, + { + "type": "shell", + "label": "Convert WAV to ADPCM", + "dependsOn": [ + "1. Copy source code to docker volume" + ], + "command": "docker exec -t tyra-compiler sh -c 'adpenc ${input:wav2adpcmSource} ${input:wav2adpcmTarget} && rsync -zac /src/${input:wav2adpcmTarget} /host/${input:wav2adpcmTarget}'" + }, + { + "type": "shell", + "label": "Cleanup", + "command": "docker exec -t tyra-compiler sh -c 'rm -rf /src/*'" + }, + { + "type": "shell", + "label": "Send to PS2", + "command": "docker exec -t tyra-compiler sh -c 'cd ${config:buildDirectory}/bin && killall -v ps2client || true && ps2client -h ${input:ps2Ip} reset && ps2client -h ${input:ps2Ip} reset && ps2client -h ${input:ps2Ip} execee host:$(find . -maxdepth 1 -type f -name \"*.elf\")'" + }, + { + "type": "shell", + "label": "Open PS2 output logger", + "command": "docker stop ps2-logs || true && docker run -t --rm --name=ps2-logs -p ${input:local2Ip}:18194:18194/udp h4570/tyra sh -c 'ps2client -h ${input:ps2Ip} listen'", + "runOptions": { + "instanceLimit": 1 + }, + "presentation": { + "reveal": "always", + "panel": "new" + } + }, + { + "type": "shell", + "label": "Start docker container", + "command": "docker compose up -d" + }, + { + "type": "shell", + "label": "Stop docker container", + "command": "docker compose down" + }, + { + "type": "shell", + "label": "[Debug] Copy obj directory to host", + "command": "docker exec -t tyra-compiler sh -c 'rsync -zac --include=\"*/\" --include=\"obj/**\" --exclude=\"*\" /src/ /host/'" + } + ], + "inputs": [ + { + "id": "wav2adpcmSource", + "description": "Source file path (ex. ):", + "default": "demo/res/sound.wav", + "type": "promptString" + }, + { + "id": "wav2adpcmTarget", + "description": "Target file path (ex. ):", + "default": "demo/res/sound.adpcm", + "type": "promptString" + }, + { + "id": "ps2Ip", + "description": "PS2link ip address:", + "default": "192.168.1.200", + "type": "promptString" + }, + { + "id": "local2Ip", + "description": "Local ip address:", + "default": "192.168.1.245", + "type": "promptString" + } + ] +} diff --git a/demo/run.sh b/demo/run.sh new file mode 100755 index 0000000..67836a7 --- /dev/null +++ b/demo/run.sh @@ -0,0 +1,4 @@ +#!/bin/bash +SCRIPT_DIR=$(dirname "$(readlink -f "$0")") +cd "$SCRIPT_DIR" || exit 1 +../linux-pcsx2.sh diff --git a/docker-compose.yml b/docker-compose.yml index ff8ece3..b55a522 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,4 +11,4 @@ services: container_name: tyra-compiler volumes: - tyra-volume:/src - - ./:/host + - ./:/host:z diff --git a/linux-pcsx2.sh b/linux-pcsx2.sh new file mode 100755 index 0000000..3324589 --- /dev/null +++ b/linux-pcsx2.sh @@ -0,0 +1,77 @@ +#!/bin/bash +# ======================= +CUSTOM_PCSX2_PATH="" # e.g. "/usr/bin/pcsx2" or "flatpak run net.pcsx2.PCSX2" +# ======================= + +get_target_elf_name() { + if [ -f "./Makefile" ]; then + grep -oP '\S+\.elf' Makefile | head -n 1 + else + echo "" + fi +} + +find_pcsx2() { + if [ -n "$CUSTOM_PCSX2_PATH" ]; then + echo "$CUSTOM_PCSX2_PATH" + return 0 + fi + + # Check flatpak + if command -v flatpak >/dev/null 2>&1 && flatpak list | grep -q "net.pcsx2.PCSX2"; then + echo "flatpak run net.pcsx2.PCSX2" + return 0 + fi + + # Check if pcsx2-qt is in PATH + if command -v pcsx2-qt >/dev/null 2>&1; then + echo "pcsx2-qt" + return 0 + fi + + # Check if pcsx2 is in PATH + if command -v pcsx2 >/dev/null 2>&1; then + echo "pcsx2" + return 0 + fi + + echo "Error: PCSX2 not found! Please install it, put it in PATH, or specify CUSTOM_PCSX2_PATH in this script." >&2 + exit 1 +} + +run_pcsx2() { + local pcsx2_cmd + pcsx2_cmd=$(find_pcsx2) + + local elf_name + elf_name=$(get_target_elf_name) + if [ -z "$elf_name" ]; then + echo "Error: Could not find target ELF name in Makefile!" >&2 + exit 1 + fi + + local target_file + target_file="$(pwd)/bin/$elf_name" + + if [ ! -f "$target_file" ]; then + echo "Error: ELF file not found at $target_file. Did you build the project?" >&2 + exit 1 + fi + + # Kill existing PCSX2 instances + if [[ "$pcsx2_cmd" == *"flatpak"* ]]; then + pkill -f "net.pcsx2.PCSX2" >/dev/null 2>&1 || true + pkill -f "pcsx2-qt" >/dev/null 2>&1 || true + else + local bin_name + bin_name=$(basename "$pcsx2_cmd") + pkill "$bin_name" >/dev/null 2>&1 || true + fi + + echo "Running PCSX2: $pcsx2_cmd -elf $target_file" + + # Run PCSX2 in the background + $pcsx2_cmd -elf "$target_file" & +} + +run_pcsx2 diff --git a/template/linux-pcsx2.sh b/template/linux-pcsx2.sh new file mode 100755 index 0000000..3324589 --- /dev/null +++ b/template/linux-pcsx2.sh @@ -0,0 +1,77 @@ +#!/bin/bash +# ======================= +CUSTOM_PCSX2_PATH="" # e.g. "/usr/bin/pcsx2" or "flatpak run net.pcsx2.PCSX2" +# ======================= + +get_target_elf_name() { + if [ -f "./Makefile" ]; then + grep -oP '\S+\.elf' Makefile | head -n 1 + else + echo "" + fi +} + +find_pcsx2() { + if [ -n "$CUSTOM_PCSX2_PATH" ]; then + echo "$CUSTOM_PCSX2_PATH" + return 0 + fi + + # Check flatpak + if command -v flatpak >/dev/null 2>&1 && flatpak list | grep -q "net.pcsx2.PCSX2"; then + echo "flatpak run net.pcsx2.PCSX2" + return 0 + fi + + # Check if pcsx2-qt is in PATH + if command -v pcsx2-qt >/dev/null 2>&1; then + echo "pcsx2-qt" + return 0 + fi + + # Check if pcsx2 is in PATH + if command -v pcsx2 >/dev/null 2>&1; then + echo "pcsx2" + return 0 + fi + + echo "Error: PCSX2 not found! Please install it, put it in PATH, or specify CUSTOM_PCSX2_PATH in this script." >&2 + exit 1 +} + +run_pcsx2() { + local pcsx2_cmd + pcsx2_cmd=$(find_pcsx2) + + local elf_name + elf_name=$(get_target_elf_name) + if [ -z "$elf_name" ]; then + echo "Error: Could not find target ELF name in Makefile!" >&2 + exit 1 + fi + + local target_file + target_file="$(pwd)/bin/$elf_name" + + if [ ! -f "$target_file" ]; then + echo "Error: ELF file not found at $target_file. Did you build the project?" >&2 + exit 1 + fi + + # Kill existing PCSX2 instances + if [[ "$pcsx2_cmd" == *"flatpak"* ]]; then + pkill -f "net.pcsx2.PCSX2" >/dev/null 2>&1 || true + pkill -f "pcsx2-qt" >/dev/null 2>&1 || true + else + local bin_name + bin_name=$(basename "$pcsx2_cmd") + pkill "$bin_name" >/dev/null 2>&1 || true + fi + + echo "Running PCSX2: $pcsx2_cmd -elf $target_file" + + # Run PCSX2 in the background + $pcsx2_cmd -elf "$target_file" & +} + +run_pcsx2 diff --git a/template/run.sh b/template/run.sh new file mode 100755 index 0000000..6e8e2db --- /dev/null +++ b/template/run.sh @@ -0,0 +1,4 @@ +#!/bin/bash +SCRIPT_DIR=$(dirname "$(readlink -f "$0")") +cd "$SCRIPT_DIR" || exit 1 +./linux-pcsx2.sh diff --git a/tutorials/01-hello/run.sh b/tutorials/01-hello/run.sh new file mode 100755 index 0000000..60b5ea7 --- /dev/null +++ b/tutorials/01-hello/run.sh @@ -0,0 +1,4 @@ +#!/bin/bash +SCRIPT_DIR=$(dirname "$(readlink -f "$0")") +cd "$SCRIPT_DIR" || exit 1 +../../linux-pcsx2.sh diff --git a/tutorials/02-sprite/run.sh b/tutorials/02-sprite/run.sh new file mode 100755 index 0000000..60b5ea7 --- /dev/null +++ b/tutorials/02-sprite/run.sh @@ -0,0 +1,4 @@ +#!/bin/bash +SCRIPT_DIR=$(dirname "$(readlink -f "$0")") +cd "$SCRIPT_DIR" || exit 1 +../../linux-pcsx2.sh diff --git a/tutorials/03-minecraft/run.sh b/tutorials/03-minecraft/run.sh new file mode 100755 index 0000000..60b5ea7 --- /dev/null +++ b/tutorials/03-minecraft/run.sh @@ -0,0 +1,4 @@ +#!/bin/bash +SCRIPT_DIR=$(dirname "$(readlink -f "$0")") +cd "$SCRIPT_DIR" || exit 1 +../../linux-pcsx2.sh diff --git a/tutorials/04-de_dust2/run.sh b/tutorials/04-de_dust2/run.sh new file mode 100755 index 0000000..60b5ea7 --- /dev/null +++ b/tutorials/04-de_dust2/run.sh @@ -0,0 +1,4 @@ +#!/bin/bash +SCRIPT_DIR=$(dirname "$(readlink -f "$0")") +cd "$SCRIPT_DIR" || exit 1 +../../linux-pcsx2.sh diff --git a/tutorials/05-animation/run.sh b/tutorials/05-animation/run.sh new file mode 100755 index 0000000..60b5ea7 --- /dev/null +++ b/tutorials/05-animation/run.sh @@ -0,0 +1,4 @@ +#!/bin/bash +SCRIPT_DIR=$(dirname "$(readlink -f "$0")") +cd "$SCRIPT_DIR" || exit 1 +../../linux-pcsx2.sh diff --git a/tutorials/06-audio/run.sh b/tutorials/06-audio/run.sh new file mode 100755 index 0000000..60b5ea7 --- /dev/null +++ b/tutorials/06-audio/run.sh @@ -0,0 +1,4 @@ +#!/bin/bash +SCRIPT_DIR=$(dirname "$(readlink -f "$0")") +cd "$SCRIPT_DIR" || exit 1 +../../linux-pcsx2.sh diff --git a/tutorials/07-lighting/run.sh b/tutorials/07-lighting/run.sh new file mode 100755 index 0000000..60b5ea7 --- /dev/null +++ b/tutorials/07-lighting/run.sh @@ -0,0 +1,4 @@ +#!/bin/bash +SCRIPT_DIR=$(dirname "$(readlink -f "$0")") +cd "$SCRIPT_DIR" || exit 1 +../../linux-pcsx2.sh diff --git a/tutorials/08-skybox-debug/run.sh b/tutorials/08-skybox-debug/run.sh new file mode 100755 index 0000000..60b5ea7 --- /dev/null +++ b/tutorials/08-skybox-debug/run.sh @@ -0,0 +1,4 @@ +#!/bin/bash +SCRIPT_DIR=$(dirname "$(readlink -f "$0")") +cd "$SCRIPT_DIR" || exit 1 +../../linux-pcsx2.sh diff --git a/tutorials/09-manual-mode/run.sh b/tutorials/09-manual-mode/run.sh new file mode 100755 index 0000000..60b5ea7 --- /dev/null +++ b/tutorials/09-manual-mode/run.sh @@ -0,0 +1,4 @@ +#!/bin/bash +SCRIPT_DIR=$(dirname "$(readlink -f "$0")") +cd "$SCRIPT_DIR" || exit 1 +../../linux-pcsx2.sh diff --git a/tutorials/10-sprite-sheet/run.sh b/tutorials/10-sprite-sheet/run.sh new file mode 100755 index 0000000..60b5ea7 --- /dev/null +++ b/tutorials/10-sprite-sheet/run.sh @@ -0,0 +1,4 @@ +#!/bin/bash +SCRIPT_DIR=$(dirname "$(readlink -f "$0")") +cd "$SCRIPT_DIR" || exit 1 +../../linux-pcsx2.sh diff --git a/tutorials/11-texture-region-repeat/run.sh b/tutorials/11-texture-region-repeat/run.sh new file mode 100755 index 0000000..60b5ea7 --- /dev/null +++ b/tutorials/11-texture-region-repeat/run.sh @@ -0,0 +1,4 @@ +#!/bin/bash +SCRIPT_DIR=$(dirname "$(readlink -f "$0")") +cd "$SCRIPT_DIR" || exit 1 +../../linux-pcsx2.sh