Fix up build scripts, add GitHub Actions CI

This commit is contained in:
spicyjpeg 2024-05-29 21:16:24 +02:00
parent e75a7f2e42
commit 7702ef2258
No known key found for this signature in database
GPG Key ID: 5CC87404C01DF393
10 changed files with 438 additions and 116 deletions

51
.github/scripts/buildRelease.sh vendored Executable file
View File

@ -0,0 +1,51 @@
#!/bin/bash
ROOT_DIR="$(pwd)"
PROJECT_DIR="$ROOT_DIR/cart-tool"
OPENBIOS_DIR="$ROOT_DIR/nugget/openbios"
TOOLCHAIN_DIR="$ROOT_DIR/gcc-mipsel-none-elf"
## Build project
cmake --preset release -DTOOLCHAIN_PATH="$TOOLCHAIN_DIR" "$PROJECT_DIR" \
|| exit 1
cmake --build "$PROJECT_DIR/build" \
|| exit 1
RELEASE_NAME="$(
ls "$PROJECT_DIR/build" |
grep -E -o '^cart-tool-[0-9]+\.[0-9]+\.[0-9]+' |
head -n 1
)"
mkdir -p "$ROOT_DIR/$RELEASE_NAME"
cd "$ROOT_DIR/$RELEASE_NAME"
cp \
"$PROJECT_DIR/build/$RELEASE_NAME.chd" \
"$PROJECT_DIR/build/$RELEASE_NAME.iso" \
"$PROJECT_DIR/build/$RELEASE_NAME.psexe" \
"$PROJECT_DIR/build/readme.txt" \
.
## Build BIOS ROM
cd "$OPENBIOS_DIR"
make \
BUILD=Release \
PREFIX="$TOOLCHAIN_DIR/bin/mipsel-none-elf" \
FORMAT=elf32-littlemips \
FASTBOOT=true \
EMBED_PSEXE="$PROJECT_DIR/build/${RELEASE_NAME}-tiny.psexe" \
|| exit 2
cd "$ROOT_DIR/$RELEASE_NAME"
cp "$OPENBIOS_DIR/openbios.bin" "${RELEASE_NAME}-bios.bin"
## Package release
zip -9 -r "$ROOT_DIR/$RELEASE_NAME.zip" . \
|| exit 3
#cd "$ROOT_DIR"
#rm -rf "$RELEASE_NAME"

110
.github/scripts/buildToolchain.sh vendored Executable file
View File

@ -0,0 +1,110 @@
#!/bin/bash
ROOT_DIR="$(pwd)"
BINUTILS_VERSION="2.41"
GCC_VERSION="13.2.0"
NUM_JOBS="4"
if [ $# -eq 2 ]; then
PACKAGE_NAME="$1"
TARGET_NAME="$2"
BUILD_OPTIONS=""
elif [ $# -eq 3 ]; then
PACKAGE_NAME="$1"
TARGET_NAME="$2"
BUILD_OPTIONS="--build=x86_64-linux-gnu --host=$3"
else
echo "Usage: $0 <package name> <target triplet> [host triplet]"
exit 0
fi
## Download binutils and GCC
if [ ! -d binutils-$BINUTILS_VERSION ]; then
wget "https://ftpmirror.gnu.org/gnu/binutils/binutils-$BINUTILS_VERSION.tar.xz" \
|| exit 1
tar Jxf binutils-$BINUTILS_VERSION.tar.xz \
|| exit 1
rm -f binutils-$BINUTILS_VERSION.tar.xz
fi
if [ ! -d gcc-$GCC_VERSION ]; then
wget "https://ftpmirror.gnu.org/gnu/gcc/gcc-$GCC_VERSION/gcc-$GCC_VERSION.tar.xz" \
|| exit 1
tar Jxf gcc-$GCC_VERSION.tar.xz \
|| exit 1
cd gcc-$GCC_VERSION
contrib/download_prerequisites \
|| exit 1
cd ..
rm -f gcc-$GCC_VERSION.tar.xz
fi
## Build binutils
mkdir -p binutils-build
cd binutils-build
../binutils-$BINUTILS_VERSION/configure \
--prefix="$ROOT_DIR/$PACKAGE_NAME" \
$BUILD_OPTIONS \
--target=$TARGET_NAME \
--with-float=soft \
--disable-docs \
--disable-nls \
--disable-werror \
|| exit 2
make -j $NUM_JOBS \
|| exit 2
make install-strip \
|| exit 2
cd ..
rm -rf binutils-build
## Build GCC
mkdir -p gcc-build
cd gcc-build
../gcc-$GCC_VERSION/configure \
--prefix="$ROOT_DIR/$PACKAGE_NAME" \
$BUILD_OPTIONS \
--target=$TARGET_NAME \
--with-float=soft \
--disable-docs \
--disable-nls \
--disable-werror \
--disable-libada \
--disable-libssp \
--disable-libquadmath \
--disable-threads \
--disable-libgomp \
--disable-libstdcxx-pch \
--disable-hosted-libstdcxx \
--enable-languages=c,c++ \
--without-isl \
--without-headers \
--with-gnu-as \
--with-gnu-ld \
|| exit 3
make -j $NUM_JOBS \
|| exit 3
make install-strip \
|| exit 3
cd ..
rm -rf gcc-build
## Package toolchain
#cd $PACKAGE_NAME
#zip -9 -r ../$PACKAGE_NAME-$GCC_VERSION.zip . \
# || exit 4
#cd ..
#rm -rf $PACKAGE_NAME

60
.github/workflows/build.yml vendored Normal file
View File

@ -0,0 +1,60 @@
# The GCC toolchain is stored in the GitHub Actions cache after being built. To
# minimize build times, the toolchain build step is skipped if there is a cached
# copy of the toolchain that has not expired.
name: Build
on: [ push, pull_request ]
jobs:
build:
name: Run build
runs-on: ubuntu-latest
steps:
- name: Initialize toolchain cache
id: cache
uses: actions/cache@v3
with:
key: toolchain
path: gcc-mipsel-none-elf
- name: Fetch repo contents
uses: actions/checkout@v4
with:
path: cart-tool
- name: Fetch OpenBIOS repo contents
uses: actions/checkout@v4
with:
repository: pcsx-redux/nugget
path: nugget
submodules: recursive
- name: Install prerequisites
run: |
sudo apt-get update -y
sudo apt-get install -y --no-install-recommends ninja-build mame-tools
sudo pip3 install -r cart-tool/tools/requirements.txt
- name: Build GCC toolchain
if: ${{ steps.cache.outputs.cache-hit != 'true' }}
run: |
cart-tool/.github/scripts/buildToolchain.sh gcc-mipsel-none-elf mipsel-none-elf
- name: Build project
run: |
cart-tool/.github/scripts/buildRelease.sh
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: build
if-no-files-found: error
path: cart-tool-*/**
- name: Publish release
if: ${{ github.ref_type == 'tag' }}
uses: softprops/action-gh-release@v1
with:
fail_on_unmatched_files: true
files: cart-tool-*.zip

View File

@ -4,12 +4,28 @@ cmake_minimum_required(VERSION 3.25)
set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_LIST_DIR}/cmake/toolchain.cmake") set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_LIST_DIR}/cmake/toolchain.cmake")
project( project(
cart_tool cart-tool
LANGUAGES C CXX ASM LANGUAGES C CXX ASM
VERSION 0.4.3 VERSION 0.4.3
DESCRIPTION "Konami System 573 security cartridge tool" DESCRIPTION "Konami System 573 security cartridge tool"
) )
set(
RELEASE_INFO "${PROJECT_NAME} ${PROJECT_VERSION} - (C) 2022-2024 spicyjpeg"
CACHE STRING "Executable description and version string (optional)"
)
set(
RELEASE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}"
CACHE STRING "CD-ROM image and release package file name"
)
string(TOUPPER "${RELEASE_NAME}" _cdVolumeName)
string(REGEX REPLACE "[^0-9A-Z_]" "_" _cdVolumeName "${_cdVolumeName}")
set(
CD_VOLUME_NAME "${_cdVolumeName}"
CACHE STRING "CD-ROM image volume label"
)
find_package(Python3 REQUIRED COMPONENTS Interpreter) find_package(Python3 REQUIRED COMPONENTS Interpreter)
find_program( find_program(
CHDMAN_PATH chdman CHDMAN_PATH chdman
@ -20,22 +36,6 @@ find_program(
DOC "Path to MAME chdman tool (optional)" DOC "Path to MAME chdman tool (optional)"
) )
string(TOUPPER "${PROJECT_NAME}" _name)
string(REPLACE "." "_" _version "${PROJECT_VERSION}")
set(
RELEASE_INFO "${PROJECT_NAME} ${PROJECT_VERSION} - (C) 2022-2024 spicyjpeg"
CACHE STRING "Executable description and version string (optional)"
)
set(
RELEASE_NAME "${PROJECT_NAME}_${PROJECT_VERSION}"
CACHE STRING "CD-ROM image and release package file name"
)
set(
CD_VOLUME_NAME "${_name}_${_version}"
CACHE STRING "CD-ROM image volume label"
)
## Files common to all executables ## Files common to all executables
add_library( add_library(
@ -171,14 +171,6 @@ target_compile_definitions(
> >
) )
addExecutable(
boot 80010000 0
src/boot/crt0.s
src/boot/main.cpp
src/common/util.cpp
)
target_link_libraries(boot PRIVATE bootFlags)
function(addLauncher address stackTop) function(addLauncher address stackTop)
addExecutable( addExecutable(
launcher${address} ${address} ${stackTop} launcher${address} ${address} ${stackTop}
@ -199,84 +191,60 @@ endfunction()
addLauncher(801fd000 801ffff0) addLauncher(801fd000 801ffff0)
addLauncher(803fd000 803ffff0) addLauncher(803fd000 803ffff0)
## Default resource archive ## Boot stub and resource archive
function(addBinaryFile target name sizeName path) function(addBootStub name resourceName)
set(_file "${PROJECT_BINARY_DIR}/includes/${target}_${name}.s") configure_file(${resourceName}.json ${resourceName}.json ESCAPE_QUOTES)
cmake_path(ABSOLUTE_PATH path OUTPUT_VARIABLE _path)
file( add_custom_command(
CONFIGURE
OUTPUT "${_file}"
CONTENT [[
.section .rodata.${name}, "a"
.balign 8
.global ${name}
.type ${name}, @object
.size ${name}, (${name}_end - ${name})
${name}:
.incbin "${_path}"
${name}_end:
.section .rodata.${sizeName}, "a"
.balign 4
.global ${sizeName}
.type ${sizeName}, @object
.size ${sizeName}, 4
${sizeName}:
.int (${name}_end - ${name})
]]
ESCAPE_QUOTES
NEWLINE_STYLE LF
)
target_sources(${target} PRIVATE "${_file}")
set_source_files_properties("${_file}" PROPERTIES OBJECT_DEPENDS "${_path}")
endfunction()
configure_file(resources.json resources.json ESCAPE_QUOTES)
add_custom_command(
COMMAND COMMAND
"${Python3_EXECUTABLE}" "${Python3_EXECUTABLE}"
"${PROJECT_SOURCE_DIR}/tools/buildResourceArchive.py" "${PROJECT_SOURCE_DIR}/tools/buildResourceArchive.py"
resources.json ${resourceName}.json
resources.zip ${resourceName}.zip
OUTPUT resources.zip OUTPUT ${resourceName}.zip
DEPENDS DEPENDS
resources.json ${resourceName}.json
assets/app.palette.json assets/app.palette.json
assets/app.strings.json assets/app.strings.json
main.psexe main.psexe
launcher801fd000.psexe launcher801fd000.psexe
launcher803fd000.psexe launcher803fd000.psexe
COMMENT "Building resource archive" COMMENT "Building ${name} resource archive"
VERBATIM VERBATIM
) )
addBinaryFile(
boot _resourceArchive _resourceArchiveLength addExecutable(
"${PROJECT_BINARY_DIR}/resources.zip" ${name} 80010000 0
) src/boot/crt0.s
src/boot/main.cpp
src/common/util.cpp
)
addBinaryFile(
${name} _resourceArchive _resourceArchiveLength
"${PROJECT_BINARY_DIR}/${resourceName}.zip"
)
target_link_libraries(${name} PRIVATE bootFlags)
endfunction()
addBootStub("${RELEASE_NAME}" resources)
addBootStub("${RELEASE_NAME}-tiny" resourcestiny)
## CD-ROM image ## CD-ROM image
configure_file(cd.json cd.json ESCAPE_QUOTES) configure_file(cdrom.json cdrom.json ESCAPE_QUOTES)
configure_file(assets/cdreadme.txt readme.txt NEWLINE_STYLE CRLF) configure_file(assets/cdreadme.txt readme.txt NEWLINE_STYLE CRLF)
add_custom_command( add_custom_command(
COMMAND COMMAND
"${Python3_EXECUTABLE}" "${Python3_EXECUTABLE}"
"${PROJECT_SOURCE_DIR}/tools/buildCDImage.py" "${PROJECT_SOURCE_DIR}/tools/buildCDImage.py"
cd.json cdrom.json
"${RELEASE_NAME}.iso" "${RELEASE_NAME}.iso"
OUTPUT "${RELEASE_NAME}.iso" OUTPUT "${RELEASE_NAME}.iso"
DEPENDS DEPENDS
cd.json cdrom.json
boot.psexe "${RELEASE_NAME}"
COMMENT "Building CD-ROM image" COMMENT "Building CD-ROM image"
VERBATIM VERBATIM
) )
@ -293,28 +261,7 @@ if(EXISTS "${CHDMAN_PATH}")
VERBATIM VERBATIM
) )
list(APPEND packageFiles "${RELEASE_NAME}.chd") add_custom_target(cdrom ALL DEPENDS "${RELEASE_NAME}.chd")
else()
add_custom_target(cdrom ALL DEPENDS "${RELEASE_NAME}.iso")
endif() endif()
## Release package
list(
APPEND packageFiles
readme.txt
boot.psexe
"${RELEASE_NAME}.iso"
)
add_custom_command(
COMMAND
"${CMAKE_COMMAND}" -E tar cf
"${RELEASE_NAME}.zip"
--format=zip
${packageFiles}
OUTPUT "${RELEASE_NAME}.zip"
DEPENDS ${packageFiles}
COMMENT "Packaging built files"
VERBATIM
)
add_custom_target(package ALL DEPENDS "${RELEASE_NAME}.zip")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 636 B

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -15,11 +15,15 @@
"name": "README.TXT", "name": "README.TXT",
"source": "${PROJECT_BINARY_DIR}/readme.txt" "source": "${PROJECT_BINARY_DIR}/readme.txt"
}, },
{
"type": "empty",
"name": "NOBOOT.TXT"
},
{ {
"type": "file", "type": "file",
"name": "PSX.EXE", "name": "PSX.EXE",
"source": "${PROJECT_BINARY_DIR}/boot.psexe" "source": "${PROJECT_BINARY_DIR}/${RELEASE_NAME}.psexe"
}, },
{ {
"type": "fileAlias", "type": "fileAlias",
@ -118,7 +122,7 @@
}, },
{ {
"type": "padding", "type": "empty",
"name": "PADDING.BIN", "name": "PADDING.BIN",
"size": 1048576 "size": 1048576
} }

View File

@ -81,3 +81,41 @@ target_link_options(
-G8 -G8
"-T${CMAKE_CURRENT_LIST_DIR}/executable.ld" "-T${CMAKE_CURRENT_LIST_DIR}/executable.ld"
) )
# Define a helper function to embed binary data into executables and libraries.
function(addBinaryFile target name sizeName path)
set(_file "${PROJECT_BINARY_DIR}/includes/${target}_${name}.s")
cmake_path(ABSOLUTE_PATH path OUTPUT_VARIABLE _path)
file(
CONFIGURE
OUTPUT "${_file}"
CONTENT [[
.section .rodata.${name}, "a"
.balign 8
.global ${name}
.type ${name}, @object
.size ${name}, (${name}_end - ${name})
${name}:
.incbin "${_path}"
${name}_end:
.section .rodata.${sizeName}, "a"
.balign 4
.global ${sizeName}
.type ${sizeName}, @object
.size ${sizeName}, 4
${sizeName}:
.int (${name}_end - ${name})
]]
ESCAPE_QUOTES
NEWLINE_STYLE LF
)
target_sources(${target} PRIVATE "${_file}")
set_source_files_properties("${_file}" PROPERTIES OBJECT_DEPENDS "${_path}")
endfunction()

112
resourcestiny.json Normal file
View File

@ -0,0 +1,112 @@
[
{
"type": "binary",
"name": "binaries/main.psexe.lz4",
"source": "${PROJECT_BINARY_DIR}/main.psexe",
"compression": "lz4"
},
{
"type": "binary",
"name": "binaries/launcher801fd000.psexe",
"source": "${PROJECT_BINARY_DIR}/launcher801fd000.psexe"
},
{
"type": "binary",
"name": "binaries/launcher803fd000.psexe",
"source": "${PROJECT_BINARY_DIR}/launcher803fd000.psexe"
},
{
"type": "tim",
"name": "assets/textures/background.tim",
"source": "${PROJECT_SOURCE_DIR}/assets/textures/background.png",
"quantize": 16,
"imagePos": { "x": 960, "y": 0 },
"clutPos": { "x": 1008, "y": 0 }
},
{
"type": "tim",
"name": "assets/textures/font.tim",
"source": "${PROJECT_SOURCE_DIR}/assets/textures/font.png",
"quantize": 16,
"imagePos": { "x": 984, "y": 0 },
"clutPos": { "x": 1008, "y": 1 }
},
{
"type": "metrics",
"name": "assets/textures/font.metrics",
"source": "${PROJECT_SOURCE_DIR}/assets/textures/font.metrics.json"
},
{
"type": "binary",
"name": "assets/sounds/alert.vag",
"source": "${PROJECT_SOURCE_DIR}/assets/sounds/alert.vag",
"compression": "none"
},
{
"type": "binary",
"name": "assets/sounds/move.vag",
"source": "${PROJECT_SOURCE_DIR}/assets/sounds/move.vag",
"compression": "none"
},
{
"type": "binary",
"name": "assets/sounds/enter.vag",
"source": "${PROJECT_SOURCE_DIR}/assets/sounds/enter.vag",
"compression": "none"
},
{
"type": "binary",
"name": "assets/sounds/exit.vag",
"source": "${PROJECT_SOURCE_DIR}/assets/sounds/exit.vag",
"compression": "none"
},
{
"type": "binary",
"name": "assets/sounds/click.vag",
"source": "${PROJECT_SOURCE_DIR}/assets/sounds/click.vag",
"compression": "none"
},
{
"type": "binary",
"name": "assets/sounds/screenshot.vag",
"source": "${PROJECT_SOURCE_DIR}/assets/sounds/screenshot.vag",
"compression": "none"
},
{
"type": "palette",
"name": "assets/app.palette",
"source": "${PROJECT_SOURCE_DIR}/assets/app.palette.json"
},
{
"type": "strings",
"name": "assets/app.strings",
"source": "${PROJECT_SOURCE_DIR}/assets/app.strings.json"
},
{
"type": "text",
"name": "assets/about.txt",
"source": "${PROJECT_SOURCE_DIR}/assets/about.txt"
},
{
"type": "binary",
"name": "data/fpga.bit",
"source": "${PROJECT_SOURCE_DIR}/data/fpga.bit"
},
{
"type": "binary",
"name": "data/x76f041.db",
"source": "${PROJECT_SOURCE_DIR}/data/x76f041.db"
},
{
"type": "binary",
"name": "data/zs01.db",
"source": "${PROJECT_SOURCE_DIR}/data/zs01.db"
},
{
"type": "binary",
"name": "data/flash.db",
"source": "${PROJECT_SOURCE_DIR}/data/flash.db"
}
]

View File

@ -223,12 +223,12 @@ def main():
for entry in entryList: for entry in entryList:
match entry.get("type", "file").strip(): match entry.get("type", "file").strip():
case "padding": case "empty":
name: str = normalizePath(entry["name"]) name: str = normalizePath(entry["name"])
iso.add_fp( iso.add_fp(
fp = paddingFile, fp = paddingFile,
length = int(entry["size"]), length = int(entry.get("size", 0)),
iso_path = name iso_path = name
) )
iso.set_hidden(iso_path = name) iso.set_hidden(iso_path = name)

View File

@ -65,18 +65,18 @@ def convertIndexedImage(imageObj: Image.Image) -> tuple[ndarray, ndarray]:
# Pad the palette to 16 or 256 colors. # Pad the palette to 16 or 256 colors.
padAmount: int = (16 if (numColors <= 16) else 256) - numColors padAmount: int = (16 if (numColors <= 16) else 256) - numColors
if padAmount: if padAmount:
clut = numpy.c_[ clut, numpy.zeros(padAmount, "<H") ] clut = numpy.c_[ clut, numpy.zeros(( 1, padAmount ), "<H") ]
image: ndarray = numpy.asarray(imageObj, "B") image: ndarray = numpy.asarray(imageObj, "B")
if image.shape[1] % 2: if image.shape[1] % 2:
image = numpy.c_[ image, numpy.zeros(image.shape[0], "B") ] image = numpy.c_[ image, numpy.zeros((image.shape[0], 1 ), "B") ]
# Pack two pixels into each byte for 4bpp images. # Pack two pixels into each byte for 4bpp images.
if numColors <= 16: if numColors <= 16:
image = image[:, 0::2] | (image[:, 1::2] << 4) image = image[:, 0::2] | (image[:, 1::2] << 4)
if image.shape[1] % 2: if image.shape[1] % 2:
image = numpy.c_[ image, numpy.zeros(image.shape[0], "B") ] image = numpy.c_[ image, numpy.zeros(( image.shape[0], 1 ), "B") ]
return image, clut return image, clut