mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
Compare commits
3 Commits
ca383c91ca
...
v0.6.0-wel
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bffe7eb4de | ||
|
|
cd454d2e9a | ||
|
|
c814a616d6 |
88
.checkpatch.conf
Normal file
88
.checkpatch.conf
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
# Configuration for checkpatch.pl
|
||||||
|
# ===============================
|
||||||
|
|
||||||
|
# Enable more tests
|
||||||
|
--strict
|
||||||
|
|
||||||
|
# Quiet
|
||||||
|
--quiet
|
||||||
|
|
||||||
|
# No per-file summary
|
||||||
|
--no-summary
|
||||||
|
|
||||||
|
# Don't expect the Linux kernel tree
|
||||||
|
--no-tree
|
||||||
|
|
||||||
|
# Show file line, not input line
|
||||||
|
--showfile
|
||||||
|
|
||||||
|
# Don't expect SPDX tag in the first line of a file
|
||||||
|
--ignore SPDX_LICENSE_TAG
|
||||||
|
|
||||||
|
# Don't expect Signed-off-by lines in commit messages
|
||||||
|
--no-signoff
|
||||||
|
|
||||||
|
# List of ignored rules
|
||||||
|
# ---------------------
|
||||||
|
|
||||||
|
# There's no BIT macro
|
||||||
|
--ignore BIT_MACRO
|
||||||
|
|
||||||
|
# Don't complain when bools are used in structs
|
||||||
|
--ignore BOOL_MEMBER
|
||||||
|
|
||||||
|
# Allow CamelCase
|
||||||
|
--ignore CAMELCASE
|
||||||
|
|
||||||
|
# Comparing to NULL explicitly isn't a bad thing
|
||||||
|
--ignore COMPARISON_TO_NULL
|
||||||
|
|
||||||
|
# Causes false positives
|
||||||
|
--ignore COMPLEX_MACRO
|
||||||
|
|
||||||
|
# Don't complain about structs not being const
|
||||||
|
--ignore CONST_STRUCT
|
||||||
|
|
||||||
|
# Don't complain about printing "warning:" without the function name, as warning
|
||||||
|
# printing is relevant to the code being parsed, not RGBDS' code
|
||||||
|
--ignore EMBEDDED_FUNCTION_NAME
|
||||||
|
|
||||||
|
# Do not check the format of commit messages
|
||||||
|
--ignore GIT_COMMIT_ID
|
||||||
|
|
||||||
|
# Do not check for global initializers (this is specific to the kernel)
|
||||||
|
--ignore GLOBAL_INITIALISERS
|
||||||
|
|
||||||
|
# Don't complain about initializing statics (this is specific to the kernel)
|
||||||
|
--ignore INITIALISED_STATIC
|
||||||
|
|
||||||
|
# We don't have a MAINTAINERS file, don't complain about it.
|
||||||
|
--ignore FILE_PATH_CHANGES
|
||||||
|
|
||||||
|
# Writing the continuation on the start of the line can make it clearer
|
||||||
|
--ignore LOGICAL_CONTINUATIONS
|
||||||
|
|
||||||
|
# Don't complain if a line that contains a string is too long. It's better to
|
||||||
|
# have a really long line that can be found with grep.
|
||||||
|
--ignore LONG_LINE_STRING
|
||||||
|
|
||||||
|
# Don't complain when files are modified in 'include/asm'
|
||||||
|
--ignore MODIFIED_INCLUDE_ASM
|
||||||
|
|
||||||
|
# Allow new typedefs
|
||||||
|
--ignore NEW_TYPEDEFS
|
||||||
|
|
||||||
|
# We allow lines ending with parentheses for the usage prints
|
||||||
|
--ignore OPEN_ENDED_LINE
|
||||||
|
|
||||||
|
# Prefer stdint.h types over kernel types
|
||||||
|
--ignore PREFER_KERNEL_TYPES
|
||||||
|
|
||||||
|
# Don't ask to replace sscanf by kstrto
|
||||||
|
--ignore SSCANF_TO_KSTRTO
|
||||||
|
|
||||||
|
# Parentheses can make the code clearer
|
||||||
|
--ignore UNNECESSARY_PARENTHESES
|
||||||
|
|
||||||
|
# We don't have `fallthrough;` */
|
||||||
|
--ignore PREFER_FALLTHROUGH
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
AccessModifierOffset: -4
|
AccessModifierOffset: -4
|
||||||
AlignAfterOpenBracket: BlockIndent
|
AlignAfterOpenBracket: Align
|
||||||
AlignArrayOfStructures: Left
|
AlignArrayOfStructures: Left
|
||||||
AlignConsecutiveAssignments: None
|
AlignConsecutiveAssignments: None
|
||||||
AlignConsecutiveBitFields: Consecutive
|
AlignConsecutiveBitFields: Consecutive
|
||||||
AlignConsecutiveDeclarations: None
|
AlignConsecutiveDeclarations: None
|
||||||
AlignConsecutiveMacros: Consecutive
|
AlignConsecutiveMacros: Consecutive
|
||||||
AlignEscapedNewlines: DontAlign
|
AlignEscapedNewlines: Left
|
||||||
AlignOperands: Align
|
AlignOperands: Align
|
||||||
AlignTrailingComments: true
|
AlignTrailingComments: false
|
||||||
AllowShortBlocksOnASingleLine: Empty
|
AllowShortBlocksOnASingleLine: Empty
|
||||||
AllowShortCaseLabelsOnASingleLine: false
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
AllowShortEnumsOnASingleLine: true
|
AllowShortEnumsOnASingleLine: true
|
||||||
@@ -21,10 +21,9 @@ AlwaysBreakTemplateDeclarations: Yes
|
|||||||
AttributeMacros:
|
AttributeMacros:
|
||||||
- format_
|
- format_
|
||||||
- attr_
|
- attr_
|
||||||
BinPackArguments: false
|
BinPackArguments: true
|
||||||
BinPackParameters: false
|
BinPackParameters: true
|
||||||
BitFieldColonSpacing: Both
|
BitFieldColonSpacing: Both
|
||||||
BreakAfterAttributes: Always
|
|
||||||
BreakBeforeBinaryOperators: NonAssignment
|
BreakBeforeBinaryOperators: NonAssignment
|
||||||
BreakBeforeBraces: Attach
|
BreakBeforeBraces: Attach
|
||||||
BreakBeforeConceptDeclarations: true
|
BreakBeforeConceptDeclarations: true
|
||||||
@@ -55,28 +54,22 @@ IncludeCategories:
|
|||||||
IndentAccessModifiers: false
|
IndentAccessModifiers: false
|
||||||
IndentCaseBlocks: false
|
IndentCaseBlocks: false
|
||||||
IndentCaseLabels: false
|
IndentCaseLabels: false
|
||||||
IndentExternBlock: Indent
|
IndentExternBlock: NoIndent
|
||||||
IndentGotoLabels: false
|
IndentGotoLabels: false
|
||||||
IndentPPDirectives: BeforeHash
|
IndentPPDirectives: BeforeHash
|
||||||
IndentRequires: true
|
IndentRequires: true
|
||||||
IndentWidth: 4
|
IndentWidth: 4
|
||||||
IndentWrappedFunctionNames: true
|
IndentWrappedFunctionNames: true
|
||||||
InsertBraces: true
|
# Only support for Javascript as of clang-format 13...
|
||||||
InsertNewlineAtEOF: true
|
# InsertTrailingCommas: true
|
||||||
# Only support for Javascript as of clang-format 14...
|
|
||||||
# InsertTrailingCommas: Wrapped
|
|
||||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||||
LambdaBodyIndentation: Signature
|
LambdaBodyIndentation: Signature
|
||||||
Language: Cpp
|
Language: Cpp
|
||||||
MaxEmptyLinesToKeep: 1
|
MaxEmptyLinesToKeep: 1
|
||||||
NamespaceIndentation: None
|
NamespaceIndentation: None
|
||||||
PPIndentWidth: -1
|
PPIndentWidth: -1
|
||||||
PenaltyBreakScopeResolution: 1000
|
|
||||||
PointerAlignment: Right
|
PointerAlignment: Right
|
||||||
QualifierAlignment: Right
|
|
||||||
ReflowComments: true
|
ReflowComments: true
|
||||||
RemoveParentheses: ReturnStatement
|
|
||||||
RemoveSemicolon: true
|
|
||||||
SortIncludes: CaseSensitive
|
SortIncludes: CaseSensitive
|
||||||
SortUsingDeclarations: true
|
SortUsingDeclarations: true
|
||||||
SpaceAfterCStyleCast: false
|
SpaceAfterCStyleCast: false
|
||||||
@@ -103,4 +96,4 @@ SpacesInSquareBrackets: false
|
|||||||
Standard: c++20
|
Standard: c++20
|
||||||
TabWidth: 4
|
TabWidth: 4
|
||||||
UseCRLF: false
|
UseCRLF: false
|
||||||
UseTab: ForIndentation
|
UseTab: AlignWithSpaces
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
---
|
|
||||||
Checks: ''
|
|
||||||
WarningsAsErrors: ''
|
|
||||||
HeaderFilterRegex: ''
|
|
||||||
FormatStyle: none
|
|
||||||
SystemHeaders: false
|
|
||||||
@@ -1,2 +1,7 @@
|
|||||||
|
# This file is part of RGBDS.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018-2019, Phil Smith and RGBDS contributors.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
.git
|
.git
|
||||||
docs
|
docs
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
root = true
|
root = true
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
indent_size = tab
|
indent_size = tab
|
||||||
tab_width = 4
|
tab_width = 8
|
||||||
charset = utf-8
|
charset = utf-8
|
||||||
insert_final_newline = true
|
insert_final_newline = true
|
||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
|
|||||||
16
.gitattributes
vendored
16
.gitattributes
vendored
@@ -1,18 +1,2 @@
|
|||||||
# Shell scripts need Unix line endings (see https://github.com/gbdev/rgbds/issues/841)
|
# Shell scripts need Unix line endings (see https://github.com/gbdev/rgbds/issues/841)
|
||||||
*.sh text eol=lf
|
*.sh text eol=lf
|
||||||
*.bash text eol=lf
|
|
||||||
|
|
||||||
# Flags also need Unix line endings (see https://github.com/gbdev/rgbds/issues/955)
|
|
||||||
*.flags text eol=lf
|
|
||||||
|
|
||||||
# Binary files need exact bytes
|
|
||||||
*.bin binary
|
|
||||||
*.gb binary
|
|
||||||
*.1bpp binary
|
|
||||||
*.2bpp binary
|
|
||||||
*.pal binary
|
|
||||||
*.attrmap binary
|
|
||||||
*.tilemap binary
|
|
||||||
*.palmap binary
|
|
||||||
*.patch binary
|
|
||||||
*.png binary
|
|
||||||
|
|||||||
3
.github/FUNDING.yml
vendored
3
.github/FUNDING.yml
vendored
@@ -1,2 +1,3 @@
|
|||||||
|
github: avivace
|
||||||
|
patreon: gbdev01
|
||||||
open_collective: gbdev
|
open_collective: gbdev
|
||||||
github: gbdev
|
|
||||||
|
|||||||
56
.github/actions/doc_postproc.awk
vendored
Executable file
56
.github/actions/doc_postproc.awk
vendored
Executable file
@@ -0,0 +1,56 @@
|
|||||||
|
#!/usr/bin/awk -f
|
||||||
|
|
||||||
|
/^\s+<td><b class="Sy">.+<\/b><\/td>$/ {
|
||||||
|
# Assuming that all cells whose contents are bold are heading cells,
|
||||||
|
# use the HTML tag for those
|
||||||
|
sub(/td><b class="Sy"/, "th");
|
||||||
|
sub(/b><\/td/, "th");
|
||||||
|
}
|
||||||
|
|
||||||
|
# The whole page is being generated, so it's not meant to contain any Liquid
|
||||||
|
BEGIN {
|
||||||
|
print "{% raw %}"
|
||||||
|
}
|
||||||
|
END {
|
||||||
|
print "{% endraw %}"
|
||||||
|
}
|
||||||
|
|
||||||
|
BEGIN {
|
||||||
|
in_synopsis = 0
|
||||||
|
}
|
||||||
|
/<table class="Nm">/ {
|
||||||
|
in_synopsis = 1
|
||||||
|
}
|
||||||
|
/<\/table>/ {
|
||||||
|
# Resets synopsis state even when already reset, but whatever
|
||||||
|
in_synopsis = 0
|
||||||
|
}
|
||||||
|
/<code class="Fl">-[a-zA-Z]/ {
|
||||||
|
# Add links to arg descr in synopsis section
|
||||||
|
if (in_synopsis) {
|
||||||
|
while (match($0, /<code class="Fl">-[a-zA-Z]+/)) {
|
||||||
|
# 123456789012345678 -> 18 chars
|
||||||
|
optchars = substr($0, RSTART + 18, RLENGTH - 18)
|
||||||
|
i = length(optchars)
|
||||||
|
while (i) {
|
||||||
|
end = RSTART + 18 + i
|
||||||
|
i -= 1
|
||||||
|
len = i ? 1 : 2
|
||||||
|
$0 = sprintf("%s<a href=\"#%s\">%s</a>%s",
|
||||||
|
substr($0, 0, end - len - 1),
|
||||||
|
substr($0, end - 1, 1),
|
||||||
|
substr($0, end - len, len),
|
||||||
|
substr($0, end))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
# Make long opts (defined using `Fl Fl`) into a single tag
|
||||||
|
gsub(/<code class="Fl">-<\/code>\s*<code class="Fl">/, "<code class=\"Fl\">-")
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
print
|
||||||
|
}
|
||||||
113
.github/actions/get-pages.sh
vendored
Executable file
113
.github/actions/get-pages.sh
vendored
Executable file
@@ -0,0 +1,113 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<EOF
|
||||||
|
Usage: $0 [-h] [-r] <rgbds-www> <version>
|
||||||
|
Copy renders from RGBDS repository to rgbds-www documentation
|
||||||
|
Execute from the root folder of the RGBDS repo, checked out at the desired tag
|
||||||
|
<rgbds-www> : Path to the rgbds-www repository
|
||||||
|
<version> : Version to be copied, such as 'v0.4.1' or 'master'
|
||||||
|
|
||||||
|
-h Display this help message
|
||||||
|
-r Update "latest stable" redirection pages and add a new entry to the index
|
||||||
|
(use for releases, not master)
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
is_release=0
|
||||||
|
bad_usage=0
|
||||||
|
while getopts ":hr" opt; do
|
||||||
|
case $opt in
|
||||||
|
r)
|
||||||
|
is_release=1
|
||||||
|
;;
|
||||||
|
h)
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
\?)
|
||||||
|
echo "Unknown option '$OPTARG'"
|
||||||
|
bad_usage=1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
if [ $bad_usage -ne 0 ]; then
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
shift $(($OPTIND - 1))
|
||||||
|
|
||||||
|
|
||||||
|
declare -A PAGES
|
||||||
|
PAGES=(
|
||||||
|
[rgbasm.1.html]=src/asm/rgbasm.1
|
||||||
|
[rgbasm.5.html]=src/asm/rgbasm.5
|
||||||
|
[rgblink.1.html]=src/link/rgblink.1
|
||||||
|
[rgblink.5.html]=src/link/rgblink.5
|
||||||
|
[rgbfix.1.html]=src/fix/rgbfix.1
|
||||||
|
[rgbgfx.1.html]=src/gfx/rgbgfx.1
|
||||||
|
[rgbds.5.html]=src/rgbds.5
|
||||||
|
[rgbds.7.html]=src/rgbds.7
|
||||||
|
[gbz80.7.html]=src/gbz80.7
|
||||||
|
)
|
||||||
|
WWWPATH="/docs"
|
||||||
|
mkdir -p "$1/_documentation/$2"
|
||||||
|
|
||||||
|
# `mandoc` uses a different format for referring to man pages present in the **current** directory.
|
||||||
|
# We want that format for RGBDS man pages, and the other one for the rest;
|
||||||
|
# we thus need to copy all pages to a temporary directory, and process them there.
|
||||||
|
|
||||||
|
# Copy all pages to current dir
|
||||||
|
cp "${PAGES[@]}" .
|
||||||
|
|
||||||
|
for page in "${!PAGES[@]}"; do
|
||||||
|
stem="${page%.html}"
|
||||||
|
manpage="${stem%.?}(${stem#*.})"
|
||||||
|
descr="$(awk -v 'FS=.Nd ' '/.Nd/ { print $2; }' "${PAGES[$page]}")"
|
||||||
|
|
||||||
|
cat >"$1/_documentation/$2/$page" <<EOF
|
||||||
|
---
|
||||||
|
layout: doc
|
||||||
|
title: $manpage [$2]
|
||||||
|
description: RGBDS $2 — $descr
|
||||||
|
---
|
||||||
|
EOF
|
||||||
|
options=fragment,man='%N.%S;https://linux.die.net/man/%S/%N'
|
||||||
|
if [ $stem = rgbasm.5 ]; then
|
||||||
|
options+=,toc
|
||||||
|
fi
|
||||||
|
mandoc -Thtml -I os=Linux -O$options "${PAGES[$page]##*/}" | .github/actions/doc_postproc.awk >> "$1/_documentation/$2/$page"
|
||||||
|
groff -Tpdf -mdoc -wall "${PAGES[$page]##*/}" >"$1/_documentation/$2/$stem.pdf"
|
||||||
|
if [ $is_release -ne 0 ]; then
|
||||||
|
cat - >"$1/_documentation/$page" <<EOF
|
||||||
|
---
|
||||||
|
redirect_to: $WWWPATH/$2/${page%.html}
|
||||||
|
permalink: $WWWPATH/${page%.html}/
|
||||||
|
title: $manpage [latest stable]
|
||||||
|
description: RGBDS latest stable — $descr
|
||||||
|
---
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
cat - >"$1/_documentation/$2/index.html" <<EOF
|
||||||
|
---
|
||||||
|
layout: doc_index
|
||||||
|
permalink: /docs/$2/
|
||||||
|
title: RGBDS online manual [$2]
|
||||||
|
description: RGBDS $2 - Online manual
|
||||||
|
---
|
||||||
|
EOF
|
||||||
|
|
||||||
|
|
||||||
|
# If making a release, add a new entry right after `master`
|
||||||
|
if [ $is_release -ne 0 ]; then
|
||||||
|
awk '{ print }
|
||||||
|
/"name": "master"/ { print "\t\t{\"name\": \"'$2'\", \"text\": \"'$2'\" }," }
|
||||||
|
' "$1/_data/doc.json" >"$1/_data/doc.json.tmp"
|
||||||
|
mv "$1/_data/doc.json"{.tmp,}
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Clean up
|
||||||
|
rm "${PAGES[@]##*/}"
|
||||||
21
.github/actions/install_deps.sh
vendored
Executable file
21
.github/actions/install_deps.sh
vendored
Executable file
@@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
case "${1%-*}" in
|
||||||
|
ubuntu)
|
||||||
|
sudo apt-get -qq update
|
||||||
|
sudo apt-get install -yq bison libpng-dev pkg-config
|
||||||
|
;;
|
||||||
|
macos)
|
||||||
|
brew install bison libpng pkg-config md5sha1sum
|
||||||
|
# For the version check below exclusively, re-do this before building
|
||||||
|
export PATH="/usr/local/opt/bison/bin:$PATH"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "WARNING: Cannot install deps for OS '$1'"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
bison --version
|
||||||
|
make --version
|
||||||
|
cmake --version
|
||||||
17
.github/actions/mingw-configure.sh
vendored
Normal file
17
.github/actions/mingw-configure.sh
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
source mingw-env @TRIPLE@
|
||||||
|
echo LAST IS: $last
|
||||||
|
|
||||||
|
# check if last arg is a path to configure, else use parent
|
||||||
|
for last; do true; done
|
||||||
|
if test -x "${last}/configure"; then
|
||||||
|
config_path="$last"
|
||||||
|
else
|
||||||
|
config_path=".."
|
||||||
|
fi
|
||||||
|
|
||||||
|
${config_path}/configure \
|
||||||
|
--host=@TRIPLE@ --target=@TRIPLE@ --build="$CHOST" \
|
||||||
|
--prefix=/usr/@TRIPLE@ --libdir=/usr/@TRIPLE@/lib --includedir=/usr/@TRIPLE@/include \
|
||||||
|
--enable-shared --enable-static "$@"
|
||||||
16
.github/actions/mingw-env.sh
vendored
Normal file
16
.github/actions/mingw-env.sh
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
_arch=$1
|
||||||
|
|
||||||
|
default_mingw_pp_flags="-D_FORTIFY_SOURCE=2"
|
||||||
|
default_mingw_compiler_flags="$default_mingw_pp_flags -O2 -pipe -fno-plt -fexceptions --param=ssp-buffer-size=4"
|
||||||
|
default_mingw_linker_flags="-Wl,-O1,--sort-common,--as-needed -fstack-protector"
|
||||||
|
|
||||||
|
export CPPFLAGS="${MINGW_CPPFLAGS:-$default_mingw_pp_flags $CPPFLAGS}"
|
||||||
|
export CFLAGS="${MINGW_CFLAGS:-$default_mingw_compiler_flags $CFLAGS}"
|
||||||
|
export CXXFLAGS="${MINGW_CXXFLAGS:-$default_mingw_compiler_flags $CXXFLAGS}"
|
||||||
|
export LDFLAGS="${MINGW_LDFLAGS:-$default_mingw_linker_flags $LDFLAGS}"
|
||||||
|
|
||||||
|
mingw_prefix=/usr/${_arch}
|
||||||
|
export PKG_CONFIG_SYSROOT_DIR="${mingw_prefix}"
|
||||||
|
export PKG_CONFIG_LIBDIR="${mingw_prefix}/lib/pkgconfig:${mingw_prefix}/share/pkgconfig"
|
||||||
44
.github/actions/mingw-w64-libpng-dev.sh
vendored
Executable file
44
.github/actions/mingw-w64-libpng-dev.sh
vendored
Executable file
@@ -0,0 +1,44 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# This script was written by ISSOtm while looking at Arch Linux's PKGBUILD for
|
||||||
|
# the corresponding package. (And its dependencies)
|
||||||
|
# https://aur.archlinux.org/packages/mingw-w64-libpng/
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
pngver=1.6.37
|
||||||
|
_apngver=$pngver
|
||||||
|
_arch="$1"
|
||||||
|
|
||||||
|
|
||||||
|
## Install mingw-configure and mingw-env (both build dependencies)
|
||||||
|
|
||||||
|
install -m 755 .github/actions/mingw-env.sh /usr/bin/mingw-env
|
||||||
|
|
||||||
|
sed "s|@TRIPLE@|${_arch}|g" .github/actions/mingw-configure.sh > ${_arch}-configure
|
||||||
|
install -m 755 ${_arch}-configure /usr/bin/
|
||||||
|
|
||||||
|
|
||||||
|
## Grab sources and check them
|
||||||
|
|
||||||
|
wget http://downloads.sourceforge.net/sourceforge/libpng/libpng-$pngver.tar.xz
|
||||||
|
wget http://downloads.sourceforge.net/project/apng/libpng/libpng16/libpng-$_apngver-apng.patch.gz
|
||||||
|
sha256sum -c .github/actions/mingw-w64-libpng-dev.sha256sums
|
||||||
|
|
||||||
|
## Extract sources
|
||||||
|
|
||||||
|
tar -xf libpng-$pngver.tar.xz
|
||||||
|
gunzip libpng-$_apngver-apng.patch.gz
|
||||||
|
|
||||||
|
|
||||||
|
## Start building!
|
||||||
|
|
||||||
|
cd libpng-$pngver
|
||||||
|
# Patch in apng support
|
||||||
|
patch -p0 ../libpng-$_apngver-apng.patch
|
||||||
|
|
||||||
|
mkdir -p build-${_arch}
|
||||||
|
cd build-${_arch}
|
||||||
|
${_arch}-configure LDFLAGS=-static-libgcc
|
||||||
|
make
|
||||||
|
make install
|
||||||
2
.github/actions/mingw-w64-libpng-dev.sha256sums
vendored
Normal file
2
.github/actions/mingw-w64-libpng-dev.sha256sums
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
10d9e0cb60e2b387a79b355eb7527c0bee2ed8cbd12cf04417cabc4d6976683c libpng-1.6.37-apng.patch.gz
|
||||||
|
505e70834d35383537b6491e7ae8641f1a4bed1876dbfe361201fc80868d88ca libpng-1.6.37.tar.xz
|
||||||
27
.github/scripts/build_libpng.sh
vendored
27
.github/scripts/build_libpng.sh
vendored
@@ -1,27 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
pngver=1.6.50
|
|
||||||
|
|
||||||
## Grab sources and check them
|
|
||||||
|
|
||||||
curl -LOJ "http://prdownloads.sourceforge.net/libpng/libpng-$pngver.tar.xz?download"
|
|
||||||
# Brew doesn't provide any sha256sum, so we're making do with `sha2` instead.
|
|
||||||
if [ "$(sha2 -q -256 libpng-$pngver.tar.xz)" != 4df396518620a7aa3651443e87d1b2862e4e88cad135a8b93423e01706232307 ]; then
|
|
||||||
sha2 -256 libpng-$pngver.tar.xz
|
|
||||||
echo Checksum mismatch! Aborting. >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
## Extract sources and patch them
|
|
||||||
|
|
||||||
tar -xvf libpng-$pngver.tar.xz
|
|
||||||
|
|
||||||
## Start building!
|
|
||||||
|
|
||||||
mkdir -p build
|
|
||||||
cd build
|
|
||||||
../libpng-$pngver/configure --disable-shared --enable-static \
|
|
||||||
CFLAGS="-O3 -flto -DNDEBUG -mmacosx-version-min=10.9 -arch x86_64 -arch arm64 -fno-exceptions"
|
|
||||||
make -kj
|
|
||||||
make install prefix="$PWD/../libpng-staging"
|
|
||||||
23
.github/scripts/get_win_deps.ps1
vendored
23
.github/scripts/get_win_deps.ps1
vendored
@@ -1,23 +0,0 @@
|
|||||||
function getlibrary ([string] $URI, [string] $filename, [string] $hash, [string] $destdir) {
|
|
||||||
$wc = New-Object Net.WebClient
|
|
||||||
[string] $downloadhash = $null
|
|
||||||
try {
|
|
||||||
$wc.DownloadFile($URI, $filename)
|
|
||||||
$downloadhash = $(Get-FileHash $filename -Algorithm SHA256).Hash
|
|
||||||
} catch {
|
|
||||||
Write-Host "${filename}: failed to download"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
if ($hash -ne $downloadhash) {
|
|
||||||
Write-Host "${filename}: SHA256 mismatch ($downloadhash)"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
Expand-Archive -DestinationPath $destdir $filename
|
|
||||||
}
|
|
||||||
|
|
||||||
getlibrary 'https://www.zlib.net/zlib131.zip' 'zlib.zip' '72af66d44fcc14c22013b46b814d5d2514673dda3d115e64b690c1ad636e7b17' .
|
|
||||||
getlibrary 'https://github.com/pnggroup/libpng/archive/refs/tags/v1.6.50.zip' 'libpng.zip' 'f6bb2544d2cf5465af3a695dee0b7eacff82f11a50aa4672ef0e19df6e16d455' .
|
|
||||||
getlibrary 'https://github.com/lexxmark/winflexbison/releases/download/v2.5.25/win_flex_bison-2.5.25.zip' 'winflexbison.zip' '8d324b62be33604b2c45ad1dd34ab93d722534448f55a16ca7292de32b6ac135' install_dir
|
|
||||||
|
|
||||||
Move-Item zlib-1.3.1 zlib
|
|
||||||
Move-Item libpng-1.6.50 libpng
|
|
||||||
7
.github/scripts/install.sh
vendored
7
.github/scripts/install.sh
vendored
@@ -1,7 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
install -d /usr/local/bin/ /usr/local/share/man/man1/ /usr/local/share/man/man5/ /usr/local/share/man/man7/
|
|
||||||
install -s -m 755 rgbasm rgblink rgbfix rgbgfx /usr/local/bin/
|
|
||||||
install -m 644 rgbasm.1 rgblink.1 rgbfix.1 rgbgfx.1 /usr/local/share/man/man1/
|
|
||||||
install -m 644 rgbds.5 rgbasm.5 rgblink.5 rgbasm-old.5 /usr/local/share/man/man5/
|
|
||||||
install -m 644 rgbds.7 gbz80.7 /usr/local/share/man/man7/
|
|
||||||
23
.github/scripts/install_deps.sh
vendored
23
.github/scripts/install_deps.sh
vendored
@@ -1,23 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
case "${1%-*}" in
|
|
||||||
ubuntu)
|
|
||||||
sudo apt-get -qq update
|
|
||||||
sudo apt-get install -yq bison libpng-dev pkg-config
|
|
||||||
;;
|
|
||||||
macos)
|
|
||||||
brew install bison sha2 md5sha1sum
|
|
||||||
# Export `bison` to allow using the version we install from Homebrew,
|
|
||||||
# instead of the outdated one preinstalled on macOS (which doesn't even support `-Wall`...)
|
|
||||||
export PATH="/opt/homebrew/opt/bison/bin:$PATH"
|
|
||||||
printf 'PATH=%s\n' "$PATH" >>"$GITHUB_ENV" # Make it available to later CI steps too
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "WARNING: Cannot install deps for OS '$1'"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
bison --version
|
|
||||||
make --version
|
|
||||||
cmake --version
|
|
||||||
28
.github/scripts/mingw-w64-libpng-dev.sh
vendored
28
.github/scripts/mingw-w64-libpng-dev.sh
vendored
@@ -1,28 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
pngver=1.6.50
|
|
||||||
arch="$1"
|
|
||||||
|
|
||||||
## Grab sources and check them
|
|
||||||
|
|
||||||
wget http://downloads.sourceforge.net/project/libpng/libpng16/$pngver/libpng-$pngver.tar.xz
|
|
||||||
echo 4df396518620a7aa3651443e87d1b2862e4e88cad135a8b93423e01706232307 libpng-$pngver.tar.xz | sha256sum -c -
|
|
||||||
|
|
||||||
## Extract sources and patch them
|
|
||||||
|
|
||||||
tar -xf libpng-$pngver.tar.xz
|
|
||||||
|
|
||||||
## Start building!
|
|
||||||
|
|
||||||
mkdir -p build
|
|
||||||
cd build
|
|
||||||
../libpng-$pngver/configure \
|
|
||||||
--host="$arch" --target="$arch" \
|
|
||||||
--prefix="/usr/$arch" \
|
|
||||||
--enable-shared --disable-static \
|
|
||||||
CPPFLAGS="-D_FORTIFY_SOURCE=2" \
|
|
||||||
CFLAGS="-O2 -pipe -fno-plt -fno-exceptions --param=ssp-buffer-size=4" \
|
|
||||||
LDFLAGS="-Wl,-O1,--sort-common,--as-needed -fstack-protector"
|
|
||||||
make -kj
|
|
||||||
sudo make install
|
|
||||||
18
.github/workflows/analysis.yml
vendored
18
.github/workflows/analysis.yml
vendored
@@ -1,18 +0,0 @@
|
|||||||
name: Static analysis
|
|
||||||
on:
|
|
||||||
- push
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
analysis:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout repo
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Install deps
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
./.github/scripts/install_deps.sh ubuntu-latest
|
|
||||||
- name: Static analysis
|
|
||||||
run: | # Silence warnings with too many false positives (https://stackoverflow.com/a/73913076)
|
|
||||||
make -kj CXX=g++-14 CXXFLAGS="-fanalyzer -fanalyzer-verbosity=0 -Wno-analyzer-use-of-uninitialized-value -DNDEBUG" Q=
|
|
||||||
53
.github/workflows/build-container.yml
vendored
53
.github/workflows/build-container.yml
vendored
@@ -1,53 +0,0 @@
|
|||||||
name: Build container image
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
tags:
|
|
||||||
- '*'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
publish-docker-image:
|
|
||||||
if: github.repository_owner == 'gbdev'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
packages: write
|
|
||||||
steps:
|
|
||||||
- name: Checkout repo
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Login to GitHub Container Registry
|
|
||||||
uses: docker/login-action@v3
|
|
||||||
with:
|
|
||||||
registry: ghcr.io
|
|
||||||
username: ${{ github.actor }}
|
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: Build and push the master container image
|
|
||||||
if: github.ref == 'refs/heads/master'
|
|
||||||
run: |
|
|
||||||
COMMIT_HASH=$(git rev-parse --short HEAD)
|
|
||||||
sed -i "2i LABEL org.opencontainers.image.description=\"RGBDS container image, containing the git version master:$COMMIT_HASH\"" Dockerfile
|
|
||||||
docker build . --tag ghcr.io/gbdev/rgbds:master
|
|
||||||
docker push ghcr.io/gbdev/rgbds:master
|
|
||||||
|
|
||||||
- name: Build and push the version-tagged container image
|
|
||||||
if: startsWith(github.ref, 'refs/tags/')
|
|
||||||
run: |
|
|
||||||
TAG_NAME=${GITHUB_REF#refs/tags/}
|
|
||||||
sed -i "2i LABEL org.opencontainers.image.description=\"RGBDS container image for the release version $TAG_NAME\"" Dockerfile
|
|
||||||
docker build . --tag ghcr.io/gbdev/rgbds:$TAG_NAME
|
|
||||||
docker tag ghcr.io/gbdev/rgbds:$TAG_NAME ghcr.io/gbdev/rgbds:latest
|
|
||||||
docker push ghcr.io/gbdev/rgbds:$TAG_NAME
|
|
||||||
docker push ghcr.io/gbdev/rgbds:latest
|
|
||||||
|
|
||||||
- name: Delete untagged container images
|
|
||||||
if: github.repository_owner == 'gbdev'
|
|
||||||
uses: Chizkiyahu/delete-untagged-ghcr-action@v5
|
|
||||||
with:
|
|
||||||
# Requires a personal access token with delete:packages permissions
|
|
||||||
token: ${{ secrets.PAT_TOKEN }}
|
|
||||||
package_name: 'rgbds'
|
|
||||||
untagged_only: true
|
|
||||||
except_untagged_multiplatform: true
|
|
||||||
owner_type: 'org'
|
|
||||||
2
.github/workflows/checkdiff.yml
vendored
2
.github/workflows/checkdiff.yml
vendored
@@ -1,4 +1,4 @@
|
|||||||
name: Diff completeness check
|
name: "Code coverage checking"
|
||||||
on: pull_request
|
on: pull_request
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|||||||
12
.github/workflows/checkformat.yml
vendored
12
.github/workflows/checkformat.yml
vendored
@@ -1,12 +0,0 @@
|
|||||||
name: Code format checking
|
|
||||||
on: pull_request
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
checkformat:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout repo
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Check format
|
|
||||||
run: |
|
|
||||||
contrib/checkformat.bash
|
|
||||||
25
.github/workflows/checkpatch.yml
vendored
Normal file
25
.github/workflows/checkpatch.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
name: "Code style checking"
|
||||||
|
on: pull_request
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
checkpatch:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Set up repo
|
||||||
|
run: |
|
||||||
|
git clone -b "${{ github.event.pull_request.head.ref }}" "${{ github.event.pull_request.head.repo.clone_url }}" rgbds
|
||||||
|
cd rgbds
|
||||||
|
git remote add upstream "${{ github.event.pull_request.base.repo.clone_url }}"
|
||||||
|
git fetch upstream
|
||||||
|
- name: Set up checkpatch
|
||||||
|
working-directory: rgbds
|
||||||
|
run: |
|
||||||
|
wget 'https://raw.githubusercontent.com/torvalds/linux/master/scripts/checkpatch.pl'
|
||||||
|
chmod +x checkpatch.pl
|
||||||
|
wget 'https://raw.githubusercontent.com/torvalds/linux/master/scripts/const_structs.checkpatch'
|
||||||
|
wget 'https://raw.githubusercontent.com/torvalds/linux/master/scripts/spelling.txt'
|
||||||
|
- name: Checkpatch
|
||||||
|
working-directory: rgbds
|
||||||
|
run: |
|
||||||
|
make checkpatch CHECKPATCH=./checkpatch.pl "BASE_REF=${{ github.event.pull_request.base.sha }}" Q= | tee log
|
||||||
|
if grep -q ERROR: log; then exit 1; else exit 0; fi
|
||||||
34
.github/workflows/coverage.yml
vendored
34
.github/workflows/coverage.yml
vendored
@@ -1,34 +0,0 @@
|
|||||||
name: Code coverage report
|
|
||||||
on:
|
|
||||||
- push
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
coverage:
|
|
||||||
runs-on: ubuntu-24.04
|
|
||||||
steps:
|
|
||||||
- name: Checkout repo
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Install deps
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
./.github/scripts/install_deps.sh ubuntu
|
|
||||||
- name: Install LCOV
|
|
||||||
run: |
|
|
||||||
sudo apt-get install lcov
|
|
||||||
- name: Install test dependency dependencies
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
test/fetch-test-deps.sh --get-deps ubuntu
|
|
||||||
- name: Generate coverage report
|
|
||||||
run: |
|
|
||||||
contrib/coverage.bash ubuntu-ci
|
|
||||||
- name: Upload coverage report
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: coverage-report
|
|
||||||
# Workaround for keeping the top-level coverage/ directory
|
|
||||||
# https://github.com/actions/upload-artifact/issues/174
|
|
||||||
path: |
|
|
||||||
coverage
|
|
||||||
dummy-file-to-keep-directory-structure.txt
|
|
||||||
96
.github/workflows/create-release-artifacts.yaml
vendored
Normal file
96
.github/workflows/create-release-artifacts.yaml
vendored
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
name: "Create release artifacts"
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- v[0-9]*
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
windows:
|
||||||
|
runs-on: windows-2019
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Get version from tag
|
||||||
|
shell: bash
|
||||||
|
run: | # Turn "refs/tags/vX.Y.Z" into "X.Y.Z"
|
||||||
|
VERSION="${{ github.ref }}"
|
||||||
|
echo "version=${VERSION##*/v}" >> $GITHUB_ENV
|
||||||
|
- name: Get zlib, libpng and bison
|
||||||
|
run: | # TODO: use an array
|
||||||
|
$wc = New-Object System.Net.WebClient
|
||||||
|
$wc.DownloadFile('https://www.zlib.net/zlib1212.zip', 'zlib.zip')
|
||||||
|
$hash = (Get-FileHash "zlib.zip" -Algorithm SHA256).Hash
|
||||||
|
if ($hash -ne '173e89893dcb8b4a150d7731cd72f0602f1d6b45e60e2a54efdf7f3fc3325fd7') {
|
||||||
|
Write-Host "zlib SHA256 mismatch! ($hash)"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
$wc.DownloadFile('https://download.sourceforge.net/libpng/lpng1637.zip', 'libpng.zip')
|
||||||
|
$hash = (Get-FileHash "libpng.zip" -Algorithm SHA256).Hash
|
||||||
|
if ($hash -ne '3b4b1cbd0bae6822f749d39b1ccadd6297f05e2b85a83dd2ce6ecd7d09eabdf2') {
|
||||||
|
Write-Host "libpng SHA256 mismatch! ($hash)"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
$wc.DownloadFile('https://github.com/lexxmark/winflexbison/releases/download/v2.5.24/win_flex_bison-2.5.24.zip', 'winflexbison.zip')
|
||||||
|
$hash = (Get-FileHash "winflexbison.zip" -Algorithm SHA256).Hash
|
||||||
|
if ($hash -ne '39c6086ce211d5415500acc5ed2d8939861ca1696aee48909c7f6daf5122b505') {
|
||||||
|
Write-Host "bison SHA256 mismatch! ($hash)"
|
||||||
|
}
|
||||||
|
Expand-Archive -DestinationPath . "zlib.zip"
|
||||||
|
Expand-Archive -DestinationPath . "libpng.zip"
|
||||||
|
Expand-Archive -DestinationPath install_dir "winflexbison.zip"
|
||||||
|
Move-Item zlib-1.2.12 zlib
|
||||||
|
Move-Item lpng1637 libpng
|
||||||
|
- name: Build 32-bit zlib
|
||||||
|
run: | # BUILD_SHARED_LIBS causes the output DLL to be correctly called `zlib1.dll`
|
||||||
|
cmake -S zlib -B zbuild32 -A Win32 -DCMAKE_INSTALL_PREFIX=install_dir -DBUILD_SHARED_LIBS=ON
|
||||||
|
cmake --build zbuild32 --config Release
|
||||||
|
cmake --install zbuild32
|
||||||
|
- name: Build 32-bit libpng
|
||||||
|
run: |
|
||||||
|
cmake -S libpng -B pngbuild32 -A Win32 -DCMAKE_INSTALL_PREFIX=install_dir -DPNG_SHARED=ON -DPNG_STATIC=ON -DPNG_TESTS=OFF
|
||||||
|
cmake --build pngbuild32 --config Release
|
||||||
|
cmake --install pngbuild32
|
||||||
|
- name: Build 32-bit Windows binaries
|
||||||
|
run: |
|
||||||
|
cmake -S . -B build32 -A Win32 -DCMAKE_INSTALL_PREFIX=install_dir -DCMAKE_BUILD_TYPE=Release
|
||||||
|
cmake --build build32 --config Release
|
||||||
|
cmake --install build32
|
||||||
|
- name: Package 32-bit binaries
|
||||||
|
run: |
|
||||||
|
Compress-Archive -LiteralPath @("install_dir/bin/rgbasm.exe", "install_dir/bin/rgblink.exe", "install_dir/bin/rgbfix.exe", "install_dir/bin/rgbgfx.exe", "install_dir/bin/zlib1.dll", "install_dir/bin/libpng16.dll") "rgbds-${{ env.version }}-win32.zip"
|
||||||
|
- name: Build 64-bit zlib
|
||||||
|
run: | # BUILD_SHARED_LIBS causes the output DLL to be correctly called `zlib1.dll`
|
||||||
|
cmake -S zlib -B zbuild64 -A x64 -DCMAKE_INSTALL_PREFIX=install_dir -DBUILD_SHARED_LIBS=ON
|
||||||
|
cmake --build zbuild64 --config Release
|
||||||
|
cmake --install zbuild64
|
||||||
|
- name: Build 64-bit libpng
|
||||||
|
run: |
|
||||||
|
cmake -S libpng -B pngbuild64 -A x64 -DCMAKE_INSTALL_PREFIX=install_dir -DPNG_SHARED=ON -DPNG_STATIC=ON -DPNG_TESTS=OFF
|
||||||
|
cmake --build pngbuild64 --config Release
|
||||||
|
cmake --install pngbuild64
|
||||||
|
- name: Build 64-bit Windows binaries
|
||||||
|
run: |
|
||||||
|
cmake -S . -B build64 -A x64 -DCMAKE_INSTALL_PREFIX=install_dir -DCMAKE_BUILD_TYPE=Release
|
||||||
|
cmake --build build64 --config Release
|
||||||
|
cmake --install build64
|
||||||
|
- name: Package 64-bit binaries
|
||||||
|
run: |
|
||||||
|
Compress-Archive -LiteralPath @("install_dir/bin/rgbasm.exe", "install_dir/bin/rgblink.exe", "install_dir/bin/rgbfix.exe", "install_dir/bin/rgbgfx.exe", "install_dir/bin/zlib1.dll", "install_dir/bin/libpng16.dll") "rgbds-${{ env.version }}-win64.zip"
|
||||||
|
- name: Package sources
|
||||||
|
run: |
|
||||||
|
make dist
|
||||||
|
- name: Release
|
||||||
|
uses: softprops/action-gh-release@v1
|
||||||
|
with:
|
||||||
|
body: |
|
||||||
|
Please ensure that the three assets below work properly.
|
||||||
|
Once that's done, replace this text with the changelog, un-draft the release, and update the `release` branch.
|
||||||
|
By the way, if you forgot to update `include/version.h`, RGBASM's version test is gonna fail in the tag's regression testing! (Use `git push --delete origin <tag>` to delete it)
|
||||||
|
draft: true # Don't publish the release quite yet...
|
||||||
|
prerelease: ${{ contains(github.ref, '-rc') }}
|
||||||
|
files: |
|
||||||
|
rgbds-${{ env.version }}-win32.zip
|
||||||
|
rgbds-${{ env.version }}-win64.zip
|
||||||
|
rgbds-${{ env.version }}.tar.gz
|
||||||
|
fail_on_unmatched_files: true
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
165
.github/workflows/create-release-artifacts.yml
vendored
165
.github/workflows/create-release-artifacts.yml
vendored
@@ -1,165 +0,0 @@
|
|||||||
name: Create release artifacts
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
tags:
|
|
||||||
- v[0-9]*
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
windows:
|
|
||||||
runs-on: windows-2022
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
bits: [32, 64]
|
|
||||||
include:
|
|
||||||
- bits: 32
|
|
||||||
arch: x86
|
|
||||||
platform: Win32
|
|
||||||
- bits: 64
|
|
||||||
arch: x86_x64
|
|
||||||
platform: x64
|
|
||||||
fail-fast: false
|
|
||||||
steps:
|
|
||||||
- name: Get version from tag
|
|
||||||
shell: bash
|
|
||||||
run: | # Turn "vX.Y.Z" into "X.Y.Z"
|
|
||||||
VERSION="${{ github.ref_name }}"
|
|
||||||
echo "version=${VERSION#v}" >> $GITHUB_ENV
|
|
||||||
- name: Checkout repo
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Install deps
|
|
||||||
run: .github/scripts/get_win_deps.ps1
|
|
||||||
- name: Check libraries cache
|
|
||||||
id: cache
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
zbuild
|
|
||||||
pngbuild
|
|
||||||
key: ${{ matrix.arch }}-${{ hashFiles('zlib/**', 'libpng/**') }}
|
|
||||||
- name: Build zlib
|
|
||||||
if: steps.cache.outputs.cache-hit != 'true'
|
|
||||||
run: | # BUILD_SHARED_LIBS causes the output DLL to be correctly called `zlib1.dll`
|
|
||||||
cmake -S zlib -B zbuild -A ${{ matrix.platform }} -Wno-dev -DCMAKE_INSTALL_PREFIX=install_dir -DBUILD_SHARED_LIBS=ON
|
|
||||||
cmake --build zbuild --config Release -j
|
|
||||||
- name: Install zlib
|
|
||||||
run: |
|
|
||||||
cmake --install zbuild
|
|
||||||
- name: Build libpng
|
|
||||||
if: steps.cache.outputs.cache-hit != 'true'
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
cmake -S libpng -B pngbuild -A ${{ matrix.platform }} -Wno-dev -DCMAKE_INSTALL_PREFIX=install_dir -DPNG_SHARED=ON -DPNG_STATIC=OFF -DPNG_TESTS=OFF
|
|
||||||
cmake --build pngbuild --config Release -j
|
|
||||||
- name: Install libpng
|
|
||||||
run: |
|
|
||||||
cmake --install pngbuild
|
|
||||||
- name: Build Windows binaries
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
cmake -S . -B build -A ${{ matrix.platform }} -DCMAKE_INSTALL_PREFIX=install_dir -DCMAKE_BUILD_TYPE=Release
|
|
||||||
cmake --build build --config Release -j --verbose
|
|
||||||
cmake --install build --verbose --prefix install_dir --strip
|
|
||||||
- name: Package binaries
|
|
||||||
run: |
|
|
||||||
Compress-Archive -LiteralPath @("install_dir/bin/rgbasm.exe", "install_dir/bin/rgblink.exe", "install_dir/bin/rgbfix.exe", "install_dir/bin/rgbgfx.exe", "install_dir/bin/zlib1.dll", "install_dir/bin/libpng16.dll") "rgbds-win${{ matrix.bits }}.zip"
|
|
||||||
- name: Upload Windows binaries
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: win${{ matrix.bits }}
|
|
||||||
path: rgbds-win${{ matrix.bits }}.zip
|
|
||||||
|
|
||||||
macos:
|
|
||||||
runs-on: macos-14
|
|
||||||
steps:
|
|
||||||
- name: Get version from tag
|
|
||||||
shell: bash
|
|
||||||
run: | # Turn "refs/tags/vX.Y.Z" into "X.Y.Z"
|
|
||||||
VERSION="${{ github.ref_name }}"
|
|
||||||
echo "version=${VERSION#v}" >> $GITHUB_ENV
|
|
||||||
- name: Checkout repo
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Install deps
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
./.github/scripts/install_deps.sh macos
|
|
||||||
- name: Build libpng
|
|
||||||
run: |
|
|
||||||
./.github/scripts/build_libpng.sh
|
|
||||||
# We force linking libpng statically; the other libs are provided by macOS itself
|
|
||||||
- name: Build binaries
|
|
||||||
run: |
|
|
||||||
make -kj CXXFLAGS="-O3 -flto -DNDEBUG -mmacosx-version-min=10.9 -arch x86_64 -arch arm64" PNGCFLAGS="-I libpng-staging/include" PNGLDLIBS="libpng-staging/lib/libpng.a -lz" Q=
|
|
||||||
strip rgb{asm,link,fix,gfx}
|
|
||||||
- name: Package binaries
|
|
||||||
run: |
|
|
||||||
zip --junk-paths rgbds-macos.zip rgb{asm,link,fix,gfx} man/* .github/scripts/install.sh
|
|
||||||
- name: Upload macOS binaries
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: macos
|
|
||||||
path: rgbds-macos.zip
|
|
||||||
|
|
||||||
linux:
|
|
||||||
runs-on: ubuntu-22.04 # Oldest supported, for best glibc compatibility.
|
|
||||||
steps:
|
|
||||||
- name: Get version from tag
|
|
||||||
shell: bash
|
|
||||||
run: | # Turn "refs/tags/vX.Y.Z" into "X.Y.Z"
|
|
||||||
VERSION="${{ github.ref_name }}"
|
|
||||||
echo "version=${VERSION#v}" >> $GITHUB_ENV
|
|
||||||
- name: Checkout repo
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Install deps
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
./.github/scripts/install_deps.sh ubuntu-22.04
|
|
||||||
- name: Build binaries
|
|
||||||
run: |
|
|
||||||
make -kj WARNFLAGS="-Wall -Wextra -pedantic -static" PKG_CONFIG="pkg-config --static" Q=
|
|
||||||
strip rgb{asm,link,fix,gfx}
|
|
||||||
- name: Package binaries
|
|
||||||
run: |
|
|
||||||
tar caf rgbds-linux-x86_64.tar.xz --transform='s#.*/##' rgb{asm,link,fix,gfx} man/* .github/scripts/install.sh
|
|
||||||
- name: Upload Linux binaries
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: linux
|
|
||||||
path: rgbds-linux-x86_64.tar.xz
|
|
||||||
|
|
||||||
release:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: [windows, macos, linux]
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
steps:
|
|
||||||
- name: Get version from tag
|
|
||||||
shell: bash
|
|
||||||
run: | # Turn "refs/tags/vX.Y.Z" into "X.Y.Z"
|
|
||||||
VERSION="${{ github.ref_name }}"
|
|
||||||
echo "version=${VERSION#v}" >> $GITHUB_ENV
|
|
||||||
- name: Checkout repo
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Package sources
|
|
||||||
run: |
|
|
||||||
make dist Q=
|
|
||||||
ls
|
|
||||||
- name: Download Linux binaries
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
- name: Release
|
|
||||||
uses: softprops/action-gh-release@v2
|
|
||||||
with:
|
|
||||||
body: |
|
|
||||||
Please ensure that the packages below work properly.
|
|
||||||
Once that's done, replace this text with the changelog, un-draft the release, and update the `release` branch.
|
|
||||||
By the way, if you forgot to update `include/version.hpp`, RGBASM's version test is going to fail in the tag's regression testing! (Use `git push --delete origin <tag>` to delete it)
|
|
||||||
draft: true # Don't publish the release quite yet...
|
|
||||||
prerelease: ${{ contains(github.ref, '-rc') }}
|
|
||||||
files: |
|
|
||||||
win32/rgbds-win32.zip
|
|
||||||
win64/rgbds-win64.zip
|
|
||||||
macos/rgbds-macos.zip
|
|
||||||
linux/rgbds-linux-x86_64.tar.xz
|
|
||||||
rgbds-source.tar.gz
|
|
||||||
fail_on_unmatched_files: true
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
24
.github/workflows/create-release-docs.yml
vendored
24
.github/workflows/create-release-docs.yml
vendored
@@ -1,4 +1,4 @@
|
|||||||
name: Create release docs
|
name: "Create release docs"
|
||||||
on:
|
on:
|
||||||
release:
|
release:
|
||||||
types:
|
types:
|
||||||
@@ -7,26 +7,32 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
if: github.repository_owner == 'gbdev'
|
if: github.repository_owner == 'gbdev'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-18.04
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout rgbds@release
|
- name: Checkout rgbds@release
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
path: rgbds
|
path: rgbds
|
||||||
- name: Checkout rgbds-www@master
|
- name: Checkout rgbds-www@master
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
repository: ${{ github.repository_owner }}/rgbds-www
|
repository: ${{ github.repository_owner }}/rgbds-www
|
||||||
path: rgbds-www
|
path: rgbds-www
|
||||||
- name: Install groff and mandoc
|
# `-O toc` was added in 1.14.5, but the repos only have 1.14.4
|
||||||
|
- name: Build and install mandoc + install groff
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get -qq update
|
sudo apt-get -qq update
|
||||||
sudo apt-get install -yq groff mandoc
|
sudo apt-get install -yq groff zlib1g-dev
|
||||||
|
wget 'http://mandoc.bsd.lv/snapshots/mandoc-1.14.5.tar.gz'
|
||||||
|
tar xf mandoc-1.14.5.tar.gz
|
||||||
|
cd mandoc-1.14.5
|
||||||
|
./configure
|
||||||
|
make
|
||||||
|
sudo make install
|
||||||
- name: Update pages
|
- name: Update pages
|
||||||
working-directory: rgbds/man
|
working-directory: rgbds
|
||||||
run: | # The ref appears to be in the format "refs/tags/<version>", so strip that
|
run: | # The ref appears to be in the format "refs/tags/<version>", so strip that
|
||||||
../../rgbds-www/maintainer/man_to_html.sh ${GITHUB_REF##*/} *
|
./.github/actions/get-pages.sh -r ../rgbds-www ${GITHUB_REF##*/}
|
||||||
../../rgbds-www/maintainer/new_release.sh ${GITHUB_REF##*/}
|
|
||||||
- name: Push new pages
|
- name: Push new pages
|
||||||
working-directory: rgbds-www
|
working-directory: rgbds-www
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
366
.github/workflows/testing.yml
vendored
366
.github/workflows/testing.yml
vendored
@@ -1,133 +1,64 @@
|
|||||||
name: Regression testing
|
name: "Regression testing"
|
||||||
on:
|
on:
|
||||||
- push
|
- push
|
||||||
- pull_request
|
- pull_request
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
unix:
|
unix-testing:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-22.04, macos-14]
|
os: [ubuntu-20.04, ubuntu-18.04, macos-11.0, macos-10.15]
|
||||||
cxx: [g++, clang++]
|
cc: [gcc, clang]
|
||||||
buildsys: [make, cmake]
|
buildsys: [make, cmake]
|
||||||
exclude:
|
exclude:
|
||||||
# Don't use `g++` on macOS; it's just an alias to `clang++`.
|
# `gcc` is just an alias to `clang` on macOS, don't bother
|
||||||
- os: macos-14
|
- os: macos-10.15
|
||||||
cxx: g++
|
cc: gcc
|
||||||
|
- os: macos-11.0
|
||||||
|
cc: gcc
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- uses: actions/checkout@v2
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Install deps
|
- name: Install deps
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
./.github/scripts/install_deps.sh ${{ matrix.os }}
|
./.github/actions/install_deps.sh ${{ matrix.os }}
|
||||||
|
# The `export` lines are to allow working on macOS...
|
||||||
|
# Apple's base version is severely outdated, not even supporting -Wall,
|
||||||
|
# but it overrides Homebrew's version nonetheless...
|
||||||
- name: Build & install using Make
|
- name: Build & install using Make
|
||||||
if: matrix.buildsys == 'make'
|
|
||||||
run: |
|
run: |
|
||||||
make develop -kj Q= CXX=${{ matrix.cxx }}
|
export PATH="/usr/local/opt/bison/bin:$PATH"
|
||||||
|
make develop -j Q= CC=${{ matrix.cc }}
|
||||||
sudo make install -j Q=
|
sudo make install -j Q=
|
||||||
|
if: matrix.buildsys == 'make'
|
||||||
- name: Build & install using CMake
|
- name: Build & install using CMake
|
||||||
|
run: |
|
||||||
|
export PATH="/usr/local/opt/bison/bin:$PATH"
|
||||||
|
cmake -S . -B build -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=${{ matrix.cc }} -DSANITIZERS=ON -DMORE_WARNINGS=ON
|
||||||
|
cmake --build build -j
|
||||||
|
cp build/src/rgb{asm,link,fix,gfx} .
|
||||||
|
sudo cmake --install build
|
||||||
if: matrix.buildsys == 'cmake'
|
if: matrix.buildsys == 'cmake'
|
||||||
run: |
|
|
||||||
cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_COMPILER=${{ matrix.cxx }} -DSANITIZERS=ON -DMORE_WARNINGS=ON
|
|
||||||
cmake --build build -j --verbose
|
|
||||||
sudo cmake --install build --verbose
|
|
||||||
- name: Package binaries
|
- name: Package binaries
|
||||||
run: |
|
run: |
|
||||||
mkdir bins
|
mkdir bins
|
||||||
cp rgb{asm,link,fix,gfx} bins
|
cp rgb{asm,link,fix,gfx} bins
|
||||||
- name: Upload binaries
|
- name: Upload binaries
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v1
|
||||||
with:
|
with:
|
||||||
name: rgbds-canary-${{ matrix.os }}-${{ matrix.cxx }}-${{ matrix.buildsys }}
|
name: rgbds-canary-${{ matrix.os }}-${{ matrix.cc }}-${{ matrix.buildsys }}
|
||||||
path: bins
|
path: bins
|
||||||
- name: Compute test dependency cache params
|
- name: Test
|
||||||
id: test-deps-cache-params
|
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
paths=$(test/fetch-test-deps.sh --get-paths)
|
test/run-tests.sh
|
||||||
hash=$(test/fetch-test-deps.sh --get-hash)
|
|
||||||
tee -a <<<"paths=\"${paths//,/\\n}\"" $GITHUB_OUTPUT
|
|
||||||
tee -a <<<"hash=${hash%-}" $GITHUB_OUTPUT
|
|
||||||
- name: Check test dependency repositories cache
|
|
||||||
id: test-deps-cache
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: ${{ fromJSON(steps.test-deps-cache-params.outputs.paths) }}
|
|
||||||
key: ${{ matrix.os }}-${{ steps.test-deps-cache-params.outputs.hash }}
|
|
||||||
- name: Fetch test dependency repositories
|
|
||||||
if: steps.test-deps-cache.outputs.cache-hit != 'true'
|
|
||||||
continue-on-error: true
|
|
||||||
run: |
|
|
||||||
test/fetch-test-deps.sh
|
|
||||||
- name: Install test dependency dependencies
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
test/fetch-test-deps.sh --get-deps ${{ matrix.os }}
|
|
||||||
- name: Run tests
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
CXX=${{ matrix.cxx }} test/run-tests.sh --os ${{ matrix.os }}
|
|
||||||
|
|
||||||
macos-static:
|
windows-testing:
|
||||||
runs-on: macos-14
|
|
||||||
steps:
|
|
||||||
- name: Checkout repo
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Install deps
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
./.github/scripts/install_deps.sh macos
|
|
||||||
- name: Build libpng
|
|
||||||
run: |
|
|
||||||
./.github/scripts/build_libpng.sh
|
|
||||||
- name: Build & install
|
|
||||||
run: |
|
|
||||||
make -kj CXXFLAGS="-O3 -flto -DNDEBUG -mmacosx-version-min=10.9 -arch x86_64 -arch arm64" PNGCFLAGS="-I libpng-staging/include" PNGLDLIBS="libpng-staging/lib/libpng.a -lz" Q=
|
|
||||||
- name: Package binaries
|
|
||||||
run: |
|
|
||||||
mkdir bins
|
|
||||||
cp rgb{asm,link,fix,gfx} bins
|
|
||||||
- name: Upload binaries
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: rgbds-canary-macos-static
|
|
||||||
path: bins
|
|
||||||
- name: Compute test dependency cache params
|
|
||||||
id: test-deps-cache-params
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
paths=$(test/fetch-test-deps.sh --get-paths)
|
|
||||||
hash=$(test/fetch-test-deps.sh --get-hash)
|
|
||||||
tee -a <<<"paths=\"${paths//,/\\n}\"" $GITHUB_OUTPUT
|
|
||||||
tee -a <<<"hash=${hash%-}" $GITHUB_OUTPUT
|
|
||||||
- name: Check test dependency repositories cache
|
|
||||||
id: test-deps-cache
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: ${{ fromJSON(steps.test-deps-cache-params.outputs.paths) }}
|
|
||||||
key: ${{ matrix.os }}-${{ steps.test-deps-cache-params.outputs.hash }}
|
|
||||||
- name: Fetch test dependency repositories
|
|
||||||
if: steps.test-deps-cache.outputs.cache-hit != 'true'
|
|
||||||
continue-on-error: true
|
|
||||||
run: |
|
|
||||||
test/fetch-test-deps.sh
|
|
||||||
- name: Install test dependency dependencies
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
test/fetch-test-deps.sh --get-deps macos
|
|
||||||
- name: Run tests
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
test/run-tests.sh --os macos
|
|
||||||
|
|
||||||
windows:
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
bits: [32, 64]
|
bits: [32, 64]
|
||||||
os: [windows-2022, windows-2025]
|
|
||||||
include:
|
include:
|
||||||
- bits: 32
|
- bits: 32
|
||||||
arch: x86
|
arch: x86
|
||||||
@@ -136,89 +67,70 @@ jobs:
|
|||||||
arch: x86_x64
|
arch: x86_x64
|
||||||
platform: x64
|
platform: x64
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: windows-2019
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- uses: actions/checkout@v2
|
||||||
uses: actions/checkout@v4
|
- name: Get zlib, libpng and bison
|
||||||
- name: Install deps
|
run: | # TODO: use an array
|
||||||
run: .github/scripts/get_win_deps.ps1
|
$wc = New-Object System.Net.WebClient
|
||||||
- name: Check libraries cache
|
$wc.DownloadFile('https://www.zlib.net/zlib1212.zip', 'zlib.zip')
|
||||||
id: cache
|
$hash = (Get-FileHash "zlib.zip" -Algorithm SHA256).Hash
|
||||||
uses: actions/cache@v4
|
if ($hash -ne '173e89893dcb8b4a150d7731cd72f0602f1d6b45e60e2a54efdf7f3fc3325fd7') {
|
||||||
with:
|
Write-Host "zlib SHA256 mismatch! ($hash)"
|
||||||
path: |
|
exit 1
|
||||||
zbuild
|
}
|
||||||
pngbuild
|
$wc.DownloadFile('https://download.sourceforge.net/libpng/lpng1637.zip', 'libpng.zip')
|
||||||
key: ${{ matrix.os }}-${{ matrix.arch }}-${{ hashFiles('zlib/**', 'libpng/**') }}
|
$hash = (Get-FileHash "libpng.zip" -Algorithm SHA256).Hash
|
||||||
|
if ($hash -ne '3b4b1cbd0bae6822f749d39b1ccadd6297f05e2b85a83dd2ce6ecd7d09eabdf2') {
|
||||||
|
Write-Host "libpng SHA256 mismatch! ($hash)"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
$wc.DownloadFile('https://github.com/lexxmark/winflexbison/releases/download/v2.5.24/win_flex_bison-2.5.24.zip', 'winflexbison.zip')
|
||||||
|
$hash = (Get-FileHash "winflexbison.zip" -Algorithm SHA256).Hash
|
||||||
|
if ($hash -ne '39c6086ce211d5415500acc5ed2d8939861ca1696aee48909c7f6daf5122b505') {
|
||||||
|
Write-Host "bison SHA256 mismatch! ($hash)"
|
||||||
|
}
|
||||||
|
Expand-Archive -DestinationPath . "zlib.zip"
|
||||||
|
Expand-Archive -DestinationPath . "libpng.zip"
|
||||||
|
Expand-Archive -DestinationPath install_dir "winflexbison.zip"
|
||||||
|
Move-Item zlib-1.2.12 zlib
|
||||||
|
Move-Item lpng1637 libpng
|
||||||
- name: Build zlib
|
- name: Build zlib
|
||||||
if: steps.cache.outputs.cache-hit != 'true'
|
|
||||||
shell: bash
|
|
||||||
run: | # BUILD_SHARED_LIBS causes the output DLL to be correctly called `zlib1.dll`
|
run: | # BUILD_SHARED_LIBS causes the output DLL to be correctly called `zlib1.dll`
|
||||||
cmake -S zlib -B zbuild -A ${{ matrix.platform }} -Wno-dev -DCMAKE_INSTALL_PREFIX=install_dir -DBUILD_SHARED_LIBS=ON
|
cmake -S zlib -B zbuild -A ${{ matrix.platform }} -DCMAKE_INSTALL_PREFIX=install_dir -DBUILD_SHARED_LIBS=ON
|
||||||
cmake --build zbuild --config Release -j
|
cmake --build zbuild --config Release -j
|
||||||
- name: Install zlib
|
|
||||||
run: |
|
|
||||||
cmake --install zbuild
|
cmake --install zbuild
|
||||||
- name: Build libpng
|
- name: Build libpng
|
||||||
if: steps.cache.outputs.cache-hit != 'true'
|
|
||||||
shell: bash
|
|
||||||
run: |
|
run: |
|
||||||
cmake -S libpng -B pngbuild -A ${{ matrix.platform }} -Wno-dev -DCMAKE_INSTALL_PREFIX=install_dir -DPNG_SHARED=ON -DPNG_STATIC=OFF -DPNG_TESTS=OFF
|
cmake -S libpng -B pngbuild -A ${{ matrix.platform }} -DCMAKE_INSTALL_PREFIX=install_dir -DPNG_SHARED=ON -DPNG_STATIC=ON -DPNG_TESTS=OFF
|
||||||
cmake --build pngbuild --config Release -j
|
cmake --build pngbuild --config Release -j
|
||||||
- name: Install libpng
|
|
||||||
run: |
|
|
||||||
cmake --install pngbuild
|
cmake --install pngbuild
|
||||||
- name: Build Windows binaries
|
- name: Build Windows binaries
|
||||||
shell: bash
|
|
||||||
run: |
|
run: |
|
||||||
cmake -S . -B build -A ${{ matrix.platform }} -DCMAKE_INSTALL_PREFIX=install_dir -DCMAKE_BUILD_TYPE=Release
|
cmake -S . -B build -A ${{ matrix.platform }} -DCMAKE_INSTALL_PREFIX=install_dir -DCMAKE_BUILD_TYPE=Release
|
||||||
cmake --build build --config Release -j --verbose
|
cmake --build build --config Release -j
|
||||||
cmake --install build --verbose --prefix install_dir
|
cmake --install build
|
||||||
- name: Package binaries
|
- name: Package binaries
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
mkdir bins
|
mkdir bins
|
||||||
cp install_dir/bin/{rgbasm.exe,rgblink.exe,rgbfix.exe,rgbgfx.exe,zlib1.dll,libpng16.dll} bins
|
cp install_dir/bin/{rgbasm.exe,rgblink.exe,rgbfix.exe,rgbgfx.exe,zlib1.dll,libpng16.dll} bins
|
||||||
- name: Upload Windows binaries
|
- name: Upload Windows binaries
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v1
|
||||||
with:
|
with:
|
||||||
name: rgbds-canary-w${{ matrix.bits }}-${{ matrix.os }}
|
name: rgbds-canary-win${{ matrix.bits }}
|
||||||
path: bins
|
path: bins
|
||||||
- name: Compute test dependency cache params
|
- name: Test
|
||||||
id: test-deps-cache-params
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
paths=$(test/fetch-test-deps.sh --get-paths)
|
|
||||||
hash=$(test/fetch-test-deps.sh --get-hash)
|
|
||||||
tee -a <<<"paths=\"${paths//,/\\n}\"" $GITHUB_OUTPUT
|
|
||||||
tee -a <<<"hash=${hash%-}" $GITHUB_OUTPUT
|
|
||||||
- name: Check test dependency repositories cache
|
|
||||||
id: test-deps-cache
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: ${{ fromJSON(steps.test-deps-cache-params.outputs.paths) }}
|
|
||||||
key: ${{ matrix.os }}-${{ matrix.bits }}-${{ steps.test-deps-cache-params.outputs.hash }}
|
|
||||||
- name: Fetch test dependency repositories
|
|
||||||
if: steps.test-deps-cache.outputs.cache-hit != 'true'
|
|
||||||
shell: bash
|
|
||||||
continue-on-error: true
|
|
||||||
run: |
|
|
||||||
test/fetch-test-deps.sh
|
|
||||||
- name: Install test dependency dependencies
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
test/fetch-test-deps.sh --get-deps ${{ matrix.os }}
|
|
||||||
- name: Run tests
|
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
cp bins/* .
|
cp bins/* .
|
||||||
cp bins/*.dll test/gfx
|
test/run-tests.sh
|
||||||
test/run-tests.sh --os ${{ matrix.os }}
|
|
||||||
|
|
||||||
windows-mingw-build:
|
windows-xbuild:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
bits: [32, 64]
|
bits: [32, 64]
|
||||||
|
os: [ubuntu-18.04]
|
||||||
include:
|
include:
|
||||||
- bits: 32
|
- bits: 32
|
||||||
arch: i686
|
arch: i686
|
||||||
@@ -227,163 +139,59 @@ jobs:
|
|||||||
arch: x86-64
|
arch: x86-64
|
||||||
triplet: x86_64-w64-mingw32
|
triplet: x86_64-w64-mingw32
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ${{ matrix.os }}
|
||||||
env:
|
env:
|
||||||
DIST_DIR: win${{ matrix.bits }}
|
DIST_DIR: win${{ matrix.bits }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- uses: actions/checkout@v2
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Install deps
|
- name: Install deps
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
./.github/scripts/install_deps.sh ubuntu
|
./.github/actions/install_deps.sh ${{ matrix.os }}
|
||||||
- name: Install MinGW
|
- name: Install MinGW
|
||||||
run: | # dpkg-dev is apparently required for pkg-config for cross-building
|
run: |
|
||||||
sudo apt-get install g++-mingw-w64-${{ matrix.arch }}-win32 mingw-w64-tools libz-mingw-w64-dev dpkg-dev
|
sudo apt-get install gcc-mingw-w64-${{ matrix.arch }} mingw-w64-tools libz-mingw-w64-dev
|
||||||
- name: Install libpng dev headers for MinGW
|
- name: Install libpng dev headers for MinGW
|
||||||
run: |
|
run: |
|
||||||
./.github/scripts/mingw-w64-libpng-dev.sh ${{ matrix.triplet }}
|
sudo ./.github/actions/mingw-w64-libpng-dev.sh ${{ matrix.triplet }}
|
||||||
- name: Cross-build Windows binaries
|
- name: Cross-build Windows binaries
|
||||||
run: |
|
run: |
|
||||||
make mingw${{ matrix.bits }} -kj Q=
|
make mingw${{ matrix.bits }} -j Q=
|
||||||
- name: Package binaries
|
- name: Package binaries
|
||||||
run: | # DLL dependencies can be figured out using e.g. Dependency Walker or objdump -p
|
run: |
|
||||||
mkdir bins
|
mkdir bins
|
||||||
mv -v rgb{asm,link,fix,gfx}.exe bins/
|
mv rgbasm bins/rgbasm.exe
|
||||||
cp -v /usr/${{ matrix.triplet }}/lib/zlib1.dll bins
|
mv rgblink bins/rgblink.exe
|
||||||
cp -v /usr/${{ matrix.triplet }}/bin/libpng16-16.dll bins
|
mv rgbfix bins/rgbfix.exe
|
||||||
cp -v /usr/lib/gcc/${{ matrix.triplet }}/10-win32/lib{ssp-0,stdc++-6}.dll bins
|
mv rgbgfx bins/rgbgfx.exe
|
||||||
[ "${{ matrix.bits }}" -ne 32 ] || cp -v /usr/lib/gcc/${{ matrix.triplet }}/10-win32/libgcc_s_dw2-1.dll bins
|
cp /usr/${{ matrix.triplet }}/lib/zlib1.dll bins
|
||||||
|
cp /usr/${{ matrix.triplet }}/bin/libpng16-16.dll bins
|
||||||
|
if [ ${{ matrix.bits }} -eq 32 ]; then cp /usr/lib/gcc/${{ matrix.triplet }}/7.3-win32/libgcc_s_sjlj-1.dll bins; fi
|
||||||
- name: Upload Windows binaries
|
- name: Upload Windows binaries
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v1
|
||||||
with:
|
with:
|
||||||
name: rgbds-canary-mingw-win${{ matrix.bits }}
|
name: rgbds-canary-mingw-win${{ matrix.bits }}
|
||||||
path: bins
|
path: bins
|
||||||
- name: Upload Windows test binaries
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: testing-programs-mingw-win${{ matrix.bits }}
|
|
||||||
path: |
|
|
||||||
test/gfx/randtilegen.exe
|
|
||||||
test/gfx/rgbgfx_test.exe
|
|
||||||
|
|
||||||
windows-mingw-testing:
|
windows-xtesting:
|
||||||
needs: windows-mingw-build
|
needs: windows-xbuild
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [windows-2022, windows-2025]
|
|
||||||
bits: [32, 64]
|
bits: [32, 64]
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: windows-2019
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- uses: actions/checkout@v2
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Retrieve binaries
|
- name: Retrieve binaries
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v1
|
||||||
with:
|
with:
|
||||||
name: rgbds-canary-mingw-win${{ matrix.bits }}
|
name: rgbds-canary-mingw-win${{ matrix.bits }}
|
||||||
path: bins
|
path: bins
|
||||||
- name: Retrieve test binaries
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: testing-programs-mingw-win${{ matrix.bits }}
|
|
||||||
path: test/gfx
|
|
||||||
- name: Extract binaries
|
- name: Extract binaries
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
cp bins/* .
|
cp bins/* .
|
||||||
cp bins/*.dll test/gfx
|
|
||||||
- name: Compute test dependency cache params
|
|
||||||
id: test-deps-cache-params
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
paths=$(test/fetch-test-deps.sh --get-paths)
|
|
||||||
hash=$(test/fetch-test-deps.sh --get-hash)
|
|
||||||
tee -a <<<"paths=\"${paths//,/\\n}\"" $GITHUB_OUTPUT
|
|
||||||
tee -a <<<"hash=${hash%-}" $GITHUB_OUTPUT
|
|
||||||
- name: Check test dependency repositories cache
|
|
||||||
id: test-deps-cache
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: ${{ fromJSON(steps.test-deps-cache-params.outputs.paths) }}
|
|
||||||
key: mingw-${{ matrix.bits }}-${{ steps.test-deps-cache-params.outputs.hash }}
|
|
||||||
- name: Fetch test dependency repositories
|
|
||||||
if: steps.test-deps-cache.outputs.cache-hit != 'true'
|
|
||||||
shell: bash
|
|
||||||
continue-on-error: true
|
|
||||||
run: |
|
|
||||||
test/fetch-test-deps.sh
|
|
||||||
- name: Install test dependency dependencies
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
test/fetch-test-deps.sh --get-deps ${{ matrix.os }}
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
test/run-tests.sh --os ${{ matrix.os }}
|
test/run-tests.sh
|
||||||
|
|
||||||
cygwin:
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
bits: [32, 64]
|
|
||||||
include:
|
|
||||||
- bits: 32
|
|
||||||
arch: x86
|
|
||||||
- bits: 64
|
|
||||||
arch: x86_64
|
|
||||||
fail-fast: false
|
|
||||||
runs-on: windows-2022
|
|
||||||
timeout-minutes: 30
|
|
||||||
steps:
|
|
||||||
- name: Checkout repo
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
fetch-tags: true
|
|
||||||
- name: Setup Cygwin
|
|
||||||
uses: cygwin/cygwin-install-action@v4
|
|
||||||
with:
|
|
||||||
platform: ${{ matrix.arch }}
|
|
||||||
packages: >-
|
|
||||||
bison
|
|
||||||
gcc-g++
|
|
||||||
git
|
|
||||||
libpng-devel
|
|
||||||
make
|
|
||||||
pkg-config
|
|
||||||
- name: Build & install using Make
|
|
||||||
shell: C:\cygwin\bin\env.exe CYGWIN_NOWINPATH=1 CHERE_INVOKING=1 C:\cygwin\bin\bash.exe -o igncr '{0}'
|
|
||||||
run: | # Cygwin does not support `make develop` sanitizers ASan or UBSan
|
|
||||||
make -kj Q=
|
|
||||||
make install -j Q=
|
|
||||||
- name: Run tests
|
|
||||||
shell: C:\cygwin\bin\env.exe CYGWIN_NOWINPATH=1 CHERE_INVOKING=1 C:\cygwin\bin\bash.exe -o igncr '{0}'
|
|
||||||
run: |
|
|
||||||
test/run-tests.sh --only-internal
|
|
||||||
|
|
||||||
freebsd:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
timeout-minutes: 30
|
|
||||||
steps:
|
|
||||||
- name: Checkout repo
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
fetch-tags: true
|
|
||||||
- name: Build & test using CMake on FreeBSD
|
|
||||||
uses: vmactions/freebsd-vm@v1
|
|
||||||
with:
|
|
||||||
release: "14.3"
|
|
||||||
usesh: true
|
|
||||||
prepare: |
|
|
||||||
pkg install -y \
|
|
||||||
bash \
|
|
||||||
bison \
|
|
||||||
cmake \
|
|
||||||
git \
|
|
||||||
png
|
|
||||||
run: | # FreeBSD `c++` compiler does not support `make develop` sanitizers ASan or UBSan
|
|
||||||
cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_COMPILER=c++ -DUSE_EXTERNAL_TESTS=OFF -DOS=bsd
|
|
||||||
cmake --build build -j4 --verbose
|
|
||||||
cmake --install build --verbose
|
|
||||||
cmake --build build --target test
|
|
||||||
|
|||||||
44
.github/workflows/update-master-docs.yml
vendored
44
.github/workflows/update-master-docs.yml
vendored
@@ -1,45 +1,51 @@
|
|||||||
name: Update master docs
|
name: "Update master docs"
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
paths:
|
paths:
|
||||||
- man/gbz80.7
|
- .github/actions/get-pages.sh
|
||||||
- man/rgbds.5
|
- src/gbz80.7
|
||||||
- man/rgbds.7
|
- src/rgbds.5
|
||||||
- man/rgbasm.1
|
- src/rgbds.7
|
||||||
- man/rgbasm.5
|
- src/asm/rgbasm.1
|
||||||
- man/rgbasm-old.5
|
- src/asm/rgbasm.5
|
||||||
- man/rgblink.1
|
- src/link/rgblink.1
|
||||||
- man/rgblink.5
|
- src/link/rgblink.5
|
||||||
- man/rgbfix.1
|
- src/fix/rgbfix.1
|
||||||
- man/rgbgfx.1
|
- src/gfx/rgbgfx.1
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
if: github.repository_owner == 'gbdev'
|
if: github.repository_owner == 'gbdev'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-18.04
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout rgbds@master
|
- name: Checkout rgbds@master
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
repository: gbdev/rgbds
|
repository: gbdev/rgbds
|
||||||
ref: master
|
ref: master
|
||||||
path: rgbds
|
path: rgbds
|
||||||
- name: Checkout rgbds-www@master
|
- name: Checkout rgbds-www@master
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
repository: gbdev/rgbds-www
|
repository: gbdev/rgbds-www
|
||||||
ref: master
|
ref: master
|
||||||
path: rgbds-www
|
path: rgbds-www
|
||||||
- name: Install groff and mandoc
|
- name: Build and install mandoc + install groff
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get -qq update
|
sudo apt-get -qq update
|
||||||
sudo apt-get install -yq groff mandoc
|
sudo apt-get install -yq groff zlib1g-dev
|
||||||
|
wget 'http://mandoc.bsd.lv/snapshots/mandoc-1.14.5.tar.gz'
|
||||||
|
tar xf mandoc-1.14.5.tar.gz
|
||||||
|
cd mandoc-1.14.5
|
||||||
|
./configure
|
||||||
|
make
|
||||||
|
sudo make install
|
||||||
- name: Update pages
|
- name: Update pages
|
||||||
working-directory: rgbds/man
|
working-directory: rgbds
|
||||||
run: |
|
run: |
|
||||||
../../rgbds-www/maintainer/man_to_html.sh master *
|
./.github/actions/get-pages.sh ../rgbds-www master
|
||||||
- name: Push new pages
|
- name: Push new pages
|
||||||
working-directory: rgbds-www
|
working-directory: rgbds-www
|
||||||
run: |
|
run: |
|
||||||
@@ -50,7 +56,7 @@ jobs:
|
|||||||
ssh-add ~/.ssh/id_ed25519
|
ssh-add ~/.ssh/id_ed25519
|
||||||
git config --global user.name "GitHub Action"
|
git config --global user.name "GitHub Action"
|
||||||
git config --global user.email "community@gbdev.io"
|
git config --global user.email "community@gbdev.io"
|
||||||
git add -A
|
git add .
|
||||||
git commit -m "Update RGBDS master documentation"
|
git commit -m "Update RGBDS master documentation"
|
||||||
if git remote | grep -q origin; then
|
if git remote | grep -q origin; then
|
||||||
git remote set-url origin git@github.com:gbdev/rgbds-www.git
|
git remote set-url origin git@github.com:gbdev/rgbds-www.git
|
||||||
|
|||||||
8
.gitignore
vendored
8
.gitignore
vendored
@@ -3,16 +3,10 @@
|
|||||||
/rgbfix
|
/rgbfix
|
||||||
/rgbgfx
|
/rgbgfx
|
||||||
/rgbshim.sh
|
/rgbshim.sh
|
||||||
/coverage/
|
|
||||||
*.o
|
*.o
|
||||||
*.exe
|
*.exe
|
||||||
*.dll
|
*.dll
|
||||||
*.gcno
|
.checkpatch-camelcase.*
|
||||||
*.gcda
|
|
||||||
*.gcov
|
|
||||||
CMakeCache.txt
|
CMakeCache.txt
|
||||||
CMakeFiles/
|
CMakeFiles/
|
||||||
cmake_install.cmake
|
cmake_install.cmake
|
||||||
build/
|
|
||||||
*.dSYM/
|
|
||||||
callgrind.out.*
|
|
||||||
|
|||||||
279
ARCHITECTURE.md
279
ARCHITECTURE.md
@@ -1,279 +0,0 @@
|
|||||||
# RGBDS Architecture
|
|
||||||
|
|
||||||
The RGBDS package consists of four programs: RGBASM, RGBLINK, RGBFIX, and RGBGFX.
|
|
||||||
|
|
||||||
- RGBASM is the assembler. It takes assembly code as input, and produces an RGB object file as output (and optionally a state file, logging the final state of variables and constants).
|
|
||||||
- RGBLINK is the linker. It takes object files as input, and produces a ROM file as output (and optionally a symbol and/or map file, logging where the assembly declarations got placed in the ROM).
|
|
||||||
- RGBFIX is the checksum/header fixer. It takes a ROM file as input, and outputs the same ROM file (or modifies it in-place) with the cartridge header's checksum and other metadata fixed for consistency.
|
|
||||||
- RGBGFX is the graphics converter. It takes a PNG image file as input, and outputs the tile data, palettes, tilemap, attribute map, and/or palette map in formats that the Game Boy can use.
|
|
||||||
|
|
||||||
In the simplest case, a single pipeline can turn an assembly file into a ROM:
|
|
||||||
|
|
||||||
```console
|
|
||||||
(rgbasm -o - - | rgblink -o - - | rgbfix -v -p 0) < game.asm > game.gb
|
|
||||||
```
|
|
||||||
|
|
||||||
This document describes how these four programs are structured. It goes over each source code file, noting which data is *global* (and thus scoped in all files), *owned* by that file (i.e. that is where the data's memory is managed, via [RAII](https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization)) or *referenced* by that file (i.e. there are non-owning pointers to some data, and care must be taken to not dereference those pointers after the data's owner has moved or deleted the data).
|
|
||||||
|
|
||||||
We assume that the programs are single-threaded; data structures and operations may not be thread-safe.
|
|
||||||
|
|
||||||
## Folder Organization
|
|
||||||
|
|
||||||
The RGBDS source code file structure is as follows:
|
|
||||||
|
|
||||||
```
|
|
||||||
rgbds/
|
|
||||||
├── .github/
|
|
||||||
│ ├── scripts/
|
|
||||||
│ │ └── ...
|
|
||||||
│ └── workflows/
|
|
||||||
│ └── ...
|
|
||||||
├── contrib/
|
|
||||||
│ ├── bash_compl/
|
|
||||||
│ ├── zsh_compl/
|
|
||||||
│ │ └── ...
|
|
||||||
│ └── ...
|
|
||||||
├── include/
|
|
||||||
│ └── ...
|
|
||||||
├── man/
|
|
||||||
│ └── ...
|
|
||||||
├── src/
|
|
||||||
│ ├── asm/
|
|
||||||
│ │ └── ...
|
|
||||||
│ ├── extern/
|
|
||||||
│ │ └── ...
|
|
||||||
│ ├── fix/
|
|
||||||
│ │ └── ...
|
|
||||||
│ ├── gfx/
|
|
||||||
│ │ └── ...
|
|
||||||
│ ├── link/
|
|
||||||
│ │ └── ...
|
|
||||||
│ ├── CMakeLists.txt
|
|
||||||
│ ├── bison.sh
|
|
||||||
│ └── ...
|
|
||||||
├── test/
|
|
||||||
│ ├── fetch-test-deps.sh
|
|
||||||
│ ├── run-tests.sh
|
|
||||||
│ └── ...
|
|
||||||
├── .clang-format
|
|
||||||
├── .clang-tidy
|
|
||||||
├── CMakeLists.txt
|
|
||||||
├── compile_flags.txt
|
|
||||||
├── Dockerfile
|
|
||||||
└── Makefile
|
|
||||||
```
|
|
||||||
|
|
||||||
- **`.github/`:**
|
|
||||||
Files related to the integration of the RGBDS codebase with GitHub features.
|
|
||||||
* **`scripts/`:**
|
|
||||||
Scripts used by GitHub Actions workflow files.
|
|
||||||
* **`workflows/`:**
|
|
||||||
GitHub Actions CI workflow description files. Used for automated testing, deployment, etc.
|
|
||||||
- **`contrib/`:**
|
|
||||||
Scripts and other resources which may be useful to RGBDS users and developers.
|
|
||||||
* **`bash_compl/`:**
|
|
||||||
Tab completion scripts for use with `bash`. Run them with `source` somewhere in your `.bashrc`, and they should auto-load when you open a shell.
|
|
||||||
* **`zsh_compl/`:**
|
|
||||||
Tab completion scripts for use with `zsh`. Put them somewhere in your `fpath`, and they should auto-load when you open a shell.
|
|
||||||
- **`include/`:**
|
|
||||||
Header files for the respective source files in `src`.
|
|
||||||
- **`man/`:**
|
|
||||||
Manual pages to be read with `man`, written in the [`mandoc`](https://mandoc.bsd.lv) dialect.
|
|
||||||
- **`src/`:**
|
|
||||||
Source code of RGBDS.
|
|
||||||
* **`asm/`:**
|
|
||||||
Source code of RGBASM.
|
|
||||||
* **`extern/`:**
|
|
||||||
Source code copied from external sources.
|
|
||||||
* **`fix/`:**
|
|
||||||
Source code of RGBFIX.
|
|
||||||
* **`gfx/`:**
|
|
||||||
Source code of RGBGFX.
|
|
||||||
* **`link/`:**
|
|
||||||
Source code of RGBLINK.
|
|
||||||
* **`CMakeLists.txt`:**
|
|
||||||
Defines how to build individual RGBDS programs with CMake, including the source files that each program depends on.
|
|
||||||
* **`bison.sh`:**
|
|
||||||
Script used to run the Bison parser generator with the latest flags that the user's version supports.
|
|
||||||
- **`test/`:**
|
|
||||||
Testing framework used to verify that changes to the code don't break or modify the behavior of RGBDS.
|
|
||||||
* **`fetch-test-deps.sh`:**
|
|
||||||
Script used to fetch dependencies for building external repositories. `fetch-test-deps.sh --help` describes its options.
|
|
||||||
* **`run-tests.sh`:**
|
|
||||||
Script used to run tests, including internal test cases and external repositories. `run-tests.sh --help` describes its options.
|
|
||||||
- **`.clang-format`:**
|
|
||||||
Code style for automated C++ formatting with [`clang-format`](https://clang.llvm.org/docs/ClangFormat.html) (for which we define the shortcut `make format`).
|
|
||||||
- **`.clang-tidy`:**
|
|
||||||
Configuration for C++ static analysis with [`clang-tidy`](https://clang.llvm.org/extra/clang-tidy/) (for which we define the shortcut `make tidy`).
|
|
||||||
- **`CMakeLists.txt`:**
|
|
||||||
Defines how to build RGBDS with CMake.
|
|
||||||
- **`compile_flags.txt`:**
|
|
||||||
Compiler flags for `clang-tidy`.
|
|
||||||
- **`Dockerfile`:**
|
|
||||||
Defines how to build RGBDS with Docker (which we do in CI to provide a [container image](https://github.com/gbdev/rgbds/pkgs/container/rgbds)).
|
|
||||||
- **`Makefile`:**
|
|
||||||
Defines how to build RGBDS with `make`, including the source files that each program depends on.
|
|
||||||
|
|
||||||
## RGBDS
|
|
||||||
|
|
||||||
These files in the `src/` directory are shared across multiple programs: often all four (RGBASM, RGBLINK, RGBFIX, and RGBGFX), sometimes only RGBASM and RGBLINK.
|
|
||||||
|
|
||||||
- **`backtrace.cpp`:**
|
|
||||||
Generic printing of location backtraces for RGBASM and RGBLINK. Allows configuring backtrace styles with a command-line flag (conventionally `-B/--backtrace`). Renders warnings in yellow, errors in red, and locations in cyan.
|
|
||||||
- **`cli.cpp`:**
|
|
||||||
A function for parsing command-line options, including RGBDS-specific "at-files" (a filename containing more options, prepended with an "`@`").
|
|
||||||
This is the only file to use the extern/getopt.cpp variables and functions.
|
|
||||||
- **`diagnostics.cpp`:**
|
|
||||||
Generic warning/error diagnostic support for all programs. Allows command-line flags (conventionally `-W`) to have `no-`, `error=`, or `no-error=` prefixes, and `=` level suffixes; allows "meta" flags to affect groups of individual flags; and counts how many total errors there have been. Every program has its own `warning.cpp` file that uses this.
|
|
||||||
- **`linkdefs.cpp`:**
|
|
||||||
Constants, data, and functions related to RGBDS object files, which are used for RGBASM output and RGBLINK input.
|
|
||||||
This file defines two *global* variables, `sectionTypeInfo` (metadata about each section type) and `sectionModNames` (names of section modifiers, for error reporting). RGBLINK may change some values in `sectionTypeInfo` depending on its command-line options (this only affects RGBLINK; `sectionTypeInfo` is immutable in RGBASM).
|
|
||||||
- **`opmath.cpp`:**
|
|
||||||
Functions for mathematical operations in RGBASM and RGBLINK that aren't trivially equivalent to built-in C++ ones, such as division and modulo with well-defined results for negative values.
|
|
||||||
- **`style.cpp`:**
|
|
||||||
Generic printing of cross-platform colored or bold text. Obeys the [`FORCE_COLOR`](https://force-color.org/) and [`NO_COLOR`](https://no-color.org/) environment variables, and allows configuring with a command-line flag (conventionally `--color`).
|
|
||||||
- **`usage.cpp`:**
|
|
||||||
Generic printing of usage information. Renders headings in green, flags in cyan, and URLs in blue. Every program has its own `main.cpp` file that uses this.
|
|
||||||
- **`util.cpp`:**
|
|
||||||
Utility functions applicable to most programs, mostly dealing with text strings, such as locale-independent character checks.
|
|
||||||
- **`verbosity.cpp`:**
|
|
||||||
Generic printing of messages conditionally at different verbosity levels. Allows configuring with a command-line flag (conventionally `-v/--verbose`).
|
|
||||||
- **`version.cpp`:**
|
|
||||||
RGBDS version number and string for all the programs.
|
|
||||||
|
|
||||||
## External
|
|
||||||
|
|
||||||
These files have been copied ("vendored") from external authors and adapted for use with RGBDS. Both of our vendored dependencies use the same MIT license as RGBDS.
|
|
||||||
|
|
||||||
- **`getopt.cpp`:**
|
|
||||||
Functions for parsing command-line options, including conventional single-dash and double-dash options.
|
|
||||||
This file defines some *global* `musl_opt*` variables, including `musl_optarg` (the argument given after an option flag) and `musl_optind` (the index of the next option in `argv`). Copied from [musl libc](https://musl.libc.org/).
|
|
||||||
- **`utf8decoder.cpp`:**
|
|
||||||
Function for decoding UTF-8 bytes into Unicode code points. Copied from [Björn Höhrmann](https://bjoern.hoehrmann.de/utf-8/decoder/dfa/).
|
|
||||||
|
|
||||||
## RGBASM
|
|
||||||
|
|
||||||
- **`actions.cpp`:**
|
|
||||||
Actions taken by the assembly language parser, to avoid large amounts of code going in the parser.y file.
|
|
||||||
- **`charmap.cpp`:**
|
|
||||||
Functions and data related to charmaps.
|
|
||||||
This file *owns* the `Charmap`s in its `charmaps` collection. It also maintains a static `currentCharmap` pointer, and a `charmapStack` stack of pointers to `Charmap`s within `charmaps` (which is affected by `PUSHC` and `POPC` directives).
|
|
||||||
- **`fixpoint.cpp`:**
|
|
||||||
Functions for fixed-point math, with configurable [Q*m*.*n*](https://en.wikipedia.org/wiki/Q_(number_format)) precision.
|
|
||||||
- **`format.cpp`:**
|
|
||||||
`FormatSpec` methods for parsing and applying format specs, as used by `{interpolations}` and `STRFMT`.
|
|
||||||
- **`fstack.cpp`:**
|
|
||||||
Functions and data related to "fstack" nodes (the contents of top-level or `INCLUDE`d files, macro expansions, or `REPT`/`FOR` loop iterations) and their "contexts" (metadata that is only relevant while a node's content is being lexed and parsed).
|
|
||||||
This file *owns* the `Context`s in its `contextStack` collection. Each of those `Context`s *owns* its `LexerState`, and *refers* to its `FileStackNode`, `uniqueIDStr`, and `macroArgs`. Each `FileStackNode` also *references* its `parent`.
|
|
||||||
- **`lexer.cpp`:**
|
|
||||||
Functions and data related to [lexing](https://en.wikipedia.org/wiki/Lexical_analysis) assembly source code into tokens, which can then be parsed.
|
|
||||||
This file maintains static `lexerState` and `lexerStateEOL` pointers to `LexerState`s from the `Context`s in `fstack.cpp`.
|
|
||||||
Each `LexerState` *owns* its `content` and its `expansions`' content. Each `Expansion` (the contents of an `{interpolation}` or macro argument) in turn *owns* its `contents`.
|
|
||||||
The lexer and parser are interdependent: when the parser reaches certain tokens, it changes the lexer's mode, which affects how characters get lexed into tokens. For example, when the parser reaches a macro name, it changes the lexer to "raw" mode, which lexes the rest of the line as a sequence of string arguments to the macro.
|
|
||||||
- **`macro.cpp`:**
|
|
||||||
`MacroArgs` methods related to macro arguments. Each `MacroArgs` *references* its arguments' contents.
|
|
||||||
- **`main.cpp`:**
|
|
||||||
The `main` function for running RGBASM, including the initial handling of command-line options.
|
|
||||||
This file defines a *global* `options` variable with the parsed CLI options.
|
|
||||||
- **`opt.cpp`:**
|
|
||||||
Functions for parsing options specified by `OPT` or by certain command-line options.
|
|
||||||
This file *owns* the `OptStackEntry`s in its `stack` collection (which is affected by `PUSHO` and `POPO` directives).
|
|
||||||
- **`output.cpp`:**
|
|
||||||
Functions and data related to outputting object files (with `-o/--output`) and state files (with `-s/--state`).
|
|
||||||
This file *owns* its `assertions` (created by `ASSERT` and `STATIC_ASSERT` directives). Every assertion gets output in the object file.
|
|
||||||
This file also *references* some `fileStackNodes`, and maintains static pointers to `Symbol`s in `objectSymbols`. Only the "registered" symbols and fstack nodes get output in the object file. The `fileStackNodes` and `objectSymbols` collections keep track of which nodes and symbols have been registered for output.
|
|
||||||
- **`parser.y`:**
|
|
||||||
Grammar for the RGBASM assembly language, which Bison preprocesses into a [LALR(1) parser](https://en.wikipedia.org/wiki/LALR_parser).
|
|
||||||
The Bison-generated parser calls `yylex` (defined in `lexer.cpp`) to get the next token, and calls `yywrap` (defined in `fstack.cpp`) when the current context is out of tokens and returns `EOF`.
|
|
||||||
- **`rpn.cpp`:**
|
|
||||||
`Expression` methods and data related to "[RPN](https://en.wikipedia.org/wiki/Reverse_Polish_notation)" expressions. When a numeric expression is parsed, if its value cannot be calculated at assembly time, it is built up into a buffer of RPN-encoded operations to do so at link time by RGBLINK. The valid RPN operations are defined in [man/rgbds.5](man/rgbds.5).
|
|
||||||
- **`section.cpp`:**
|
|
||||||
Functions and data related to `SECTION`s.
|
|
||||||
This file *owns* the `Section`s in its `sections` collection. It also maintains various static pointers to those sections, including the `currentSection`, `currentLoadSection`, and `sectionStack` (which is affected by `PUSHS` and `POPS` directives). (Note that sections cannot be deleted.)
|
|
||||||
- **`symbol.cpp`:**
|
|
||||||
Functions and data related to symbols (labels, constants, variables, string constants, macros, etc).
|
|
||||||
This file *owns* the `Symbol`s in its `symbols` collection, and the various built-in ones outside that collection (`PCSymbol` for "`@`", `NARGSymbol` for "`_NARG`", etc). It also maintains a static `purgedSymbols` collection to remember which symbol names have been `PURGE`d from `symbols`, for error reporting purposes.
|
|
||||||
- **`warning.cpp`:**
|
|
||||||
Functions and data for warning and error output.
|
|
||||||
This file defines a *global* `warnings` variable using the `diagnostics.cpp` code for RGBASM-specific warning flags.
|
|
||||||
|
|
||||||
## RGBFIX
|
|
||||||
|
|
||||||
- **`fix.cpp`:**
|
|
||||||
Functions for fixing the ROM header.
|
|
||||||
- **`main.cpp`:**
|
|
||||||
The `main` function for running RGBFIX, including the initial handling of command-line options.
|
|
||||||
This file defines a *global* `options` variable with the parsed CLI options.
|
|
||||||
- **`mbc.cpp`:**
|
|
||||||
Functions and data related to [MBCs](https://gbdev.io/pandocs/MBCs.html), including the names of known MBC values.
|
|
||||||
- **`warning.cpp`:**
|
|
||||||
Functions and data for warning and error output.
|
|
||||||
This file defines a *global* `warnings` variable using the `diagnostics.cpp` code for RGBFIX-specific warning flags.
|
|
||||||
|
|
||||||
## RGBGFX
|
|
||||||
|
|
||||||
- **`color_set.cpp`:**
|
|
||||||
`ColorSet` methods for creating and comparing sets of colors. A color set includes the unique colors used by a single tile, and these sets are then packed into palettes.
|
|
||||||
- **`main.cpp`:**
|
|
||||||
The `main` function for running RGBGFX, including the initial handling of command-line options.
|
|
||||||
This file defines a *global* `options` variable with the parsed CLI options.
|
|
||||||
- **`pal_packing.cpp`:**
|
|
||||||
Functions for packing color sets into palettes. This is done with an ["overload-and-remove" heuristic](https://arxiv.org/abs/1605.00558) for a pagination algorithm.
|
|
||||||
- **`pal_sorting.cpp`:**
|
|
||||||
Functions for sorting colors within palettes, which works differently for grayscale, RGB, or indexed-color palettes.
|
|
||||||
- **`pal_spec.cpp`:**
|
|
||||||
Functions for parsing various formats of palette specifications (from `-c/--colors`).
|
|
||||||
- **`palette.cpp`:**
|
|
||||||
`Palette` methods for working with up to four GBC-native (RGB555) colors.
|
|
||||||
- **`png.cpp`:**
|
|
||||||
`Png` methods for reading PNG image files, standardizing them to 8-bit RGBA pixels while also reading their indexed palette if there is one.
|
|
||||||
- **`process.cpp`:**
|
|
||||||
Functions related to generating and outputting files (tile data, palettes, tilemap, attribute map, and/or palette map).
|
|
||||||
- **`reverse.cpp`:**
|
|
||||||
Functions related to reverse-generating RGBGFX outputs into a PNG file (for `-r/--reverse`).
|
|
||||||
- **`rgba.cpp`:**
|
|
||||||
`Rgba` methods related to RGBA colors and their 8-bit or 5-bit representations.
|
|
||||||
- **`warning.cpp`:**
|
|
||||||
Functions and data for warning and error output.
|
|
||||||
This file defines a *global* `warnings` variable using the `diagnostics.cpp` code for RGBGFX-specific warning flags.
|
|
||||||
|
|
||||||
## RGBLINK
|
|
||||||
|
|
||||||
- **`assign.cpp`:**
|
|
||||||
Functions and data for assigning `SECTION`s to specific banks and addresses.
|
|
||||||
This file *owns* the `memory` table of free space: each section type is associated with a list of each bank's free address ranges, which are allocated to sections using a [first-fit decreasing](https://en.wikipedia.org/wiki/Bin_packing_problem#First-fit_algorithm) bin-packing algorithm.
|
|
||||||
- **`fstack.cpp`:**
|
|
||||||
Functions related to "fstack" nodes (the contents of top-level or `INCLUDE`d files, macro expansions, or `REPT`/`FOR` loop iterations) read from the object files. At link time, these nodes are only needed for printing of location backtraces.
|
|
||||||
- **`layout.cpp`:**
|
|
||||||
Actions taken by the linker script parser, to avoid large amounts of code going in the script.y file.
|
|
||||||
This file maintains some static data about the current bank and address layout, which get checked and updated for consistency as the linker script is parsed.
|
|
||||||
- **`lexer.cpp`:**
|
|
||||||
Functions and data related to [lexing](https://en.wikipedia.org/wiki/Lexical_analysis) linker script files into tokens, which can then be parsed.
|
|
||||||
This file *owns* the `LexerStackEntry`s in its `lexerStack` collection. Each of those `LexerStackEntry`s *owns* its `file`. The stack is updated as linker scripts can `INCLUDE` other linker script pieces.
|
|
||||||
The linker script lexer is simpler than the RGBASM one, and does not have modes.
|
|
||||||
- **`main.cpp`:**
|
|
||||||
The `main` function for running RGBLINK, including the initial handling of command-line options.
|
|
||||||
This file defines a *global* `options` variable with the parsed CLI options.
|
|
||||||
- **`object.cpp`:**
|
|
||||||
Functions and data for reading object files generated by RGBASM.
|
|
||||||
This file *owns* the `Symbol`s in its `symbolLists` collection, and the `FileStackNode`s in its `nodes` collection.
|
|
||||||
- **`output.cpp`:**
|
|
||||||
Functions and data related to outputting ROM files (with `-o/--output`), symbol files (with `-n/--sym`), and map files (with `-m/--map`).
|
|
||||||
This file *references* some `Symbol`s and `Section`s, in collections that keep them sorted by address and name, which allows the symbol and map output to be in order.
|
|
||||||
- **`patch.cpp`:**
|
|
||||||
Functions and data related to "[RPN](https://en.wikipedia.org/wiki/Reverse_Polish_notation)" expression patches read from the object files, including the ones for `ASSERT` conditions. After sections have been assigned specific locations, the RPN patches can have their values calculated and applied to the ROM. The valid RPN operations are defined in [man/rgbds.5](man/rgbds.5).
|
|
||||||
This file *owns* the `Assertion`s in its `assertions` collection, and the `RPNStackEntry`s in its `rpnStack` collection.
|
|
||||||
- **`script.y`:**
|
|
||||||
Grammar for the linker script language, which Bison preprocesses into a [LALR(1) parser](https://en.wikipedia.org/wiki/LALR_parser).
|
|
||||||
The Bison-generated parser calls `yylex` (defined in `lexer.cpp`) to get the next token, and calls `yywrap` (also defined in `lexer.cpp`) when the current context is out of tokens and returns `EOF`.
|
|
||||||
- **`sdas_obj.cpp`:**
|
|
||||||
Functions and data for reading object files generated by [GBDK with SDCC](https://gbdk.org/). RGBLINK support for these object files is incomplete.
|
|
||||||
- **`section.cpp`:**
|
|
||||||
Functions and data related to `SECTION`s read from the object files.
|
|
||||||
This file *owns* the `Section`s in its `sections` collection.
|
|
||||||
- **`symbol.cpp`:**
|
|
||||||
Functions and data related to symbols read from the object files.
|
|
||||||
This file *references* the `Symbol`s in its `symbols` and `localSymbols` collections, which allow accessing symbols by name.
|
|
||||||
- **`warning.cpp`:**
|
|
||||||
Functions and data for warning and error output.
|
|
||||||
This file defines a *global* `warnings` variable using the `diagnostics.cpp` code for RGBLINK-specific warning flags.
|
|
||||||
@@ -1,13 +1,16 @@
|
|||||||
|
#
|
||||||
|
# This file is part of RGBDS.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2020 RGBDS contributors.
|
||||||
|
#
|
||||||
# SPDX-License-Identifier: MIT
|
# SPDX-License-Identifier: MIT
|
||||||
|
#
|
||||||
|
|
||||||
# 3.9 required for LTO checks
|
# 3.9 required for LTO checks
|
||||||
# 3.17 optional for CMAKE_CTEST_ARGUMENTS
|
cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
|
||||||
cmake_minimum_required(VERSION 3.9..3.17 FATAL_ERROR)
|
|
||||||
|
|
||||||
project(rgbds
|
project(rgbds
|
||||||
LANGUAGES CXX)
|
LANGUAGES C)
|
||||||
|
|
||||||
include(CTest)
|
|
||||||
|
|
||||||
# get real path of source and binary directories
|
# get real path of source and binary directories
|
||||||
get_filename_component(srcdir "${CMAKE_SOURCE_DIR}" REALPATH)
|
get_filename_component(srcdir "${CMAKE_SOURCE_DIR}" REALPATH)
|
||||||
@@ -24,45 +27,36 @@ option(SANITIZERS "Build with sanitizers enabled" OFF) # Ignored on MSVC
|
|||||||
option(MORE_WARNINGS "Turn on more warnings" OFF) # Ignored on MSVC
|
option(MORE_WARNINGS "Turn on more warnings" OFF) # Ignored on MSVC
|
||||||
|
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
# MSVC's own standard library triggers warning C5105,
|
# MSVC's standard library triggers warning C5105,
|
||||||
# "macro expansion producing 'defined' has undefined behavior".
|
# "macro expansion producing 'defined' has undefined behavior"
|
||||||
# Warning C5030 is about unknown attributes (`[[gnu::ATTR]]`), none of ours being load-bearing.
|
add_compile_options(/std:c11 /W1 /MP /wd5105)
|
||||||
# Warning C4996 is about using POSIX names, which we want to do for portability.
|
|
||||||
# We also opt into the C++20-conformant preprocessor.
|
|
||||||
add_compile_options(/MP /wd5105 /wd5030 /wd4996 /Zc:preprocessor)
|
|
||||||
add_definitions(/D_CRT_SECURE_NO_WARNINGS)
|
add_definitions(/D_CRT_SECURE_NO_WARNINGS)
|
||||||
|
|
||||||
if(SANITIZERS)
|
|
||||||
set(SAN_FLAGS /fsanitize=address)
|
|
||||||
add_compile_options(${SAN_FLAGS})
|
|
||||||
add_link_options(${SAN_FLAGS})
|
|
||||||
endif()
|
|
||||||
else()
|
else()
|
||||||
add_compile_options(-Wall -pedantic)
|
add_compile_options(-Wall -pedantic)
|
||||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
add_definitions(-D_POSIX_C_SOURCE=200809L -D_ISOC11_SOURCE)
|
||||||
# C++20 allows macros to take zero variadic arguments, but Clang (aka AppleClang on macOS)
|
|
||||||
# does not recognize this yet.
|
|
||||||
add_compile_options(-Wno-gnu-zero-variadic-macro-arguments)
|
|
||||||
endif()
|
|
||||||
if(SANITIZERS)
|
if(SANITIZERS)
|
||||||
set(SAN_FLAGS -fsanitize=address -fsanitize=undefined
|
set(SAN_FLAGS -fsanitize=shift -fsanitize=integer-divide-by-zero
|
||||||
-fsanitize=float-divide-by-zero)
|
-fsanitize=unreachable -fsanitize=vla-bound
|
||||||
|
-fsanitize=signed-integer-overflow -fsanitize=bounds
|
||||||
|
-fsanitize=object-size -fsanitize=bool -fsanitize=enum
|
||||||
|
-fsanitize=alignment -fsanitize=null -fsanitize=address)
|
||||||
add_compile_options(${SAN_FLAGS})
|
add_compile_options(${SAN_FLAGS})
|
||||||
add_link_options(${SAN_FLAGS})
|
link_libraries(${SAN_FLAGS})
|
||||||
add_definitions(-D_GLIBCXX_ASSERTIONS)
|
|
||||||
# A non-zero optimization level is desired in debug mode, but allow overriding it nonetheless
|
# A non-zero optimization level is desired in debug mode, but allow overriding it nonetheless
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "-g -Og -fno-omit-frame-pointer -fno-optimize-sibling-calls ${CMAKE_CXX_FLAGS_DEBUG}"
|
# TODO: this overrides anything previously set... that's a bit sloppy!
|
||||||
CACHE STRING "" FORCE)
|
set(CMAKE_C_FLAGS_DEBUG "-g -Og -fno-omit-frame-pointer -fno-optimize-sibling-calls" CACHE STRING "" FORCE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(MORE_WARNINGS)
|
if(MORE_WARNINGS)
|
||||||
add_compile_options(-Werror -Wextra
|
add_compile_options(-Werror -Wextra
|
||||||
-Walloc-zero -Wcast-align -Wcast-qual -Wduplicated-branches -Wduplicated-cond
|
-Walloc-zero -Wcast-align -Wcast-qual -Wduplicated-branches -Wduplicated-cond
|
||||||
-Wfloat-equal -Wlogical-op -Wnull-dereference -Wold-style-cast -Wshift-overflow=2
|
-Wfloat-equal -Winline -Wlogical-op -Wnested-externs -Wnull-dereference
|
||||||
-Wstringop-overflow=4 -Wtrampolines -Wundef -Wuninitialized -Wunused -Wshadow
|
-Wold-style-definition -Wshift-overflow=2 -Wstrict-overflow=5
|
||||||
|
-Wstrict-prototypes -Wstringop-overflow=4 -Wundef -Wuninitialized -Wunused
|
||||||
|
-Wshadow # TODO: -Wshadow=compatible-local ?
|
||||||
-Wformat=2 -Wformat-overflow=2 -Wformat-truncation=1
|
-Wformat=2 -Wformat-overflow=2 -Wformat-truncation=1
|
||||||
-Wno-format-nonliteral -Wno-strict-overflow
|
-Wno-format-nonliteral # We have a couple of "dynamic" prints
|
||||||
-Wno-unused-but-set-variable # bison's `yynerrs_` is incremented but unused
|
# We do some range checks that are always false on some platforms (GCC, Clang)
|
||||||
-Wno-type-limits -Wno-tautological-constant-out-of-range-compare
|
-Wno-type-limits -Wno-tautological-constant-out-of-range-compare
|
||||||
-Wvla # MSVC does not support VLAs
|
-Wvla # MSVC does not support VLAs
|
||||||
-Wno-unknown-warning-option) # Clang shouldn't diagnose unknown warnings
|
-Wno-unknown-warning-option) # Clang shouldn't diagnose unknown warnings
|
||||||
@@ -74,7 +68,7 @@ endif()
|
|||||||
|
|
||||||
find_program(GIT git)
|
find_program(GIT git)
|
||||||
if(GIT)
|
if(GIT)
|
||||||
execute_process(COMMAND ${GIT} --git-dir=.git -c safe.directory='*' describe --tags --dirty --always
|
execute_process(COMMAND ${GIT} describe --tags --dirty --always
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
OUTPUT_VARIABLE GIT_REV OUTPUT_STRIP_TRAILING_WHITESPACE
|
OUTPUT_VARIABLE GIT_REV OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
ERROR_QUIET)
|
ERROR_QUIET)
|
||||||
@@ -83,24 +77,12 @@ else(GIT)
|
|||||||
message(STATUS "Cannot determine RGBDS version (Git not installed), falling back")
|
message(STATUS "Cannot determine RGBDS version (Git not installed), falling back")
|
||||||
endif(GIT)
|
endif(GIT)
|
||||||
|
|
||||||
find_package(PkgConfig)
|
|
||||||
if(MSVC OR NOT PKG_CONFIG_FOUND)
|
|
||||||
# fallback to find_package
|
|
||||||
# cmake's FindPNG is very fragile; it breaks when multiple versions are installed
|
|
||||||
# this is most evident on macOS but can occur on Linux too
|
|
||||||
find_package(PNG REQUIRED)
|
|
||||||
else()
|
|
||||||
pkg_check_modules(LIBPNG REQUIRED libpng)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include_directories("${PROJECT_SOURCE_DIR}/include")
|
include_directories("${PROJECT_SOURCE_DIR}/include")
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
set(CMAKE_C_STANDARD 11)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
set(CMAKE_C_STANDARD_REQUIRED True)
|
||||||
|
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
set(CMAKE_CTEST_ARGUMENTS "--verbose")
|
|
||||||
add_subdirectory(test)
|
|
||||||
|
|
||||||
# By default, build in Release mode; Debug mode must be explicitly requested
|
# By default, build in Release mode; Debug mode must be explicitly requested
|
||||||
# (You may want to augment it with the options above)
|
# (You may want to augment it with the options above)
|
||||||
@@ -115,20 +97,3 @@ if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
|||||||
message(CHECK_FAIL "no")
|
message(CHECK_FAIL "no")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(MANDIR "share/man")
|
|
||||||
set(man1 "man/rgbasm.1"
|
|
||||||
"man/rgbfix.1"
|
|
||||||
"man/rgbgfx.1"
|
|
||||||
"man/rgblink.1")
|
|
||||||
set(man5 "man/rgbasm.5"
|
|
||||||
"man/rgbasm-old.5"
|
|
||||||
"man/rgblink.5"
|
|
||||||
"man/rgbds.5")
|
|
||||||
set(man7 "man/gbz80.7"
|
|
||||||
"man/rgbds.7")
|
|
||||||
|
|
||||||
foreach(SECTION "man1" "man5" "man7")
|
|
||||||
set(DEST "${MANDIR}/${SECTION}")
|
|
||||||
install(FILES ${${SECTION}} DESTINATION ${DEST})
|
|
||||||
endforeach()
|
|
||||||
|
|||||||
257
CONTRIBUTING.md
257
CONTRIBUTING.md
@@ -1,257 +0,0 @@
|
|||||||
# Contributing
|
|
||||||
|
|
||||||
RGBDS was created in the late '90s and has received contributions from several
|
|
||||||
developers since then. It wouldn't have been possible to get to this point
|
|
||||||
without their work, and it is always open to the contributions of other people.
|
|
||||||
|
|
||||||
## Reporting Bugs
|
|
||||||
|
|
||||||
Bug reports are essential to improve RGBDS and they are always welcome. If you
|
|
||||||
want to report a bug:
|
|
||||||
|
|
||||||
1. Make sure that there isn't a similar issue
|
|
||||||
[already reported](https://github.com/gbdev/rgbds/issues).
|
|
||||||
2. Figure out a way of reproducing it reliably.
|
|
||||||
3. If there is a piece of code that triggers the bug, try to reduce it to the
|
|
||||||
smallest file you can.
|
|
||||||
4. Create a new [issue](https://github.com/gbdev/rgbds/issues).
|
|
||||||
|
|
||||||
Of course, it may not always be possible to give an accurate bug report, but it
|
|
||||||
always helps to fix it.
|
|
||||||
|
|
||||||
## Requesting new features
|
|
||||||
|
|
||||||
If you come up with a good idea that could be implemented, you can propose it to
|
|
||||||
be done.
|
|
||||||
|
|
||||||
1. Create a new [issue](https://github.com/gbdev/rgbds/issues).
|
|
||||||
2. Try to be as accurate as possible. Describe what you need and why you need
|
|
||||||
it, maybe with examples.
|
|
||||||
|
|
||||||
Please understand that the contributors are doing it in their free time, so
|
|
||||||
simple requests are more likely to catch the interest of a contributor than
|
|
||||||
complicated ones. If you really need something to be done, and you think you can
|
|
||||||
implement it yourself, you can always contribute to RGBDS with your own code.
|
|
||||||
|
|
||||||
## Contributing code
|
|
||||||
|
|
||||||
If you want to contribute with your own code, whether it is to fix a current
|
|
||||||
issue or to add something that nobody had requested, you should first consider
|
|
||||||
if your change is going to be small (and likely to be accepted as-is) or big
|
|
||||||
(and will have to go through some rework).
|
|
||||||
|
|
||||||
Big changes will most likely require some discussion, so open an
|
|
||||||
[issue](https://github.com/gbdev/rgbds/issues) and explain what you want to
|
|
||||||
do and how you intend to do it. If you already have a prototype, it's always a
|
|
||||||
good idea to show it. Tests help, too.
|
|
||||||
|
|
||||||
If you are going to work on a specific issue that involves a lot of work, it is
|
|
||||||
always a good idea to leave a message, just in case someone else is interested
|
|
||||||
but doesn't know that there's someone working on it.
|
|
||||||
|
|
||||||
Note that you must contribute all your changes under the MIT License. If you are
|
|
||||||
just modifying a file, you don't need to do anything (maybe update the copyright
|
|
||||||
years). If you are adding new files, you need to use the
|
|
||||||
`SPDX-License-Identifier: MIT` header.
|
|
||||||
|
|
||||||
1. Fork this repository.
|
|
||||||
2. Checkout the `master` branch.
|
|
||||||
3. Create a new branch to work on. You could still work on `master`, but it's
|
|
||||||
easier that way.
|
|
||||||
4. Compile your changes with `make develop` instead of just `make`. This
|
|
||||||
target checks for additional warnings. Your patches shouldn't introduce any
|
|
||||||
new warning (but it may be possible to remove some warning checks if it makes
|
|
||||||
the code much easier).
|
|
||||||
5. Test your changes by running `./run-tests.sh` in the `test` directory.
|
|
||||||
(You must run `./fetch-test-deps.sh` first; if you forget to, the test suite
|
|
||||||
will fail and remind you mid-way.)
|
|
||||||
5. Format your changes according to `clang-format`, which will reformat the
|
|
||||||
coding style according to our standards defined in `.clang-format`.
|
|
||||||
6. Create a pull request against the branch `master`.
|
|
||||||
7. Check the results of the GitHub Actions CI jobs for your pull request. The
|
|
||||||
"Code format checking" and "Regression testing" jobs should all succeed.
|
|
||||||
The "Diff completeness check" and "Static analysis" jobs should be manually
|
|
||||||
checked, as they may output warnings which do not count as failure errors.
|
|
||||||
The "Code coverage report" provides an
|
|
||||||
[LCOV](https://github.com/linux-test-project/lcov)-generated report which
|
|
||||||
can be downloaded and checked to see if your new code has full test coverage.
|
|
||||||
8. Be prepared to get some comments about your code and to modify it. Tip: Use
|
|
||||||
`git rebase -i origin/master` to modify chains of commits.
|
|
||||||
|
|
||||||
## Adding a test
|
|
||||||
|
|
||||||
The test suite is a little ad-hoc, so the way tests work is different for each
|
|
||||||
program being tested.
|
|
||||||
|
|
||||||
Feel free to modify how the test scripts work, if the thing you want to test
|
|
||||||
doesn't fit the existing scheme(s).
|
|
||||||
|
|
||||||
### RGBASM
|
|
||||||
|
|
||||||
There are two kinds of test.
|
|
||||||
|
|
||||||
#### Simple tests
|
|
||||||
|
|
||||||
Each `.asm` file corresponds to one test.
|
|
||||||
RGBASM will be invoked on the `.asm` file with all warnings enabled.
|
|
||||||
|
|
||||||
If a `.flags` file exists, its first line contains flags to pass to RGBASM.
|
|
||||||
(There may be more lines, which will be ignored; they can serve as comments to
|
|
||||||
explain what the test is about.)
|
|
||||||
|
|
||||||
If a `.out` file exists, RGBASM's output (`print`, `println`, etc.) must match
|
|
||||||
its contents.
|
|
||||||
If a `.err` file exists, RGBASM's error output (`warn`, errors, etc.) must match
|
|
||||||
its contents.
|
|
||||||
|
|
||||||
If a `.out.bin` file exists, the object file will be linked, and the generated
|
|
||||||
ROM truncated to the length of the `.out.bin` file.
|
|
||||||
After that, the ROM must match the `.out.bin` file.
|
|
||||||
|
|
||||||
#### CLI tests
|
|
||||||
|
|
||||||
Each `.flags` file in `cli/` corresponds to one test.
|
|
||||||
RGBASM will be invoked, passing it the first line of the `.flags` file.
|
|
||||||
(There may be more lines, which will be ignored; they can serve as comments to
|
|
||||||
explain what the test is about.)
|
|
||||||
|
|
||||||
If a `.out` file exists, RGBASM's output (`print`, `println`, etc.) must match
|
|
||||||
its contents.
|
|
||||||
If a `.err` file exists, RGBASM's error output (`warn`, errors, etc.) must match
|
|
||||||
its contents.
|
|
||||||
|
|
||||||
### RGBLINK
|
|
||||||
|
|
||||||
Each `.asm` file corresponds to one test, or one *set* of tests.
|
|
||||||
|
|
||||||
All tests begin by assembling the `.asm` file into an object file, which will be
|
|
||||||
linked in various ways depending on the test.
|
|
||||||
|
|
||||||
#### Simple tests
|
|
||||||
|
|
||||||
These simply check that RGBLINK's output matches some expected output.
|
|
||||||
|
|
||||||
A `.out` file **must** exist, and RGBLINK's total output must match that file's
|
|
||||||
contents.
|
|
||||||
|
|
||||||
Additionally, if a `.out.bin` file exists, the `.gb` file generated by RGBLINK
|
|
||||||
must match it.
|
|
||||||
|
|
||||||
#### Linker script tests
|
|
||||||
|
|
||||||
These allow applying various linker scripts to the same object file.
|
|
||||||
If one or more `.link` files exist, whose names start the same as the `.asm`
|
|
||||||
file, then each of those files correspond to one test.
|
|
||||||
|
|
||||||
Each `.link` linker script **must** be accompanied by a `.out` file, and
|
|
||||||
RGBLINK's total output must match that file's contents when passed the
|
|
||||||
corresponding linker script.
|
|
||||||
|
|
||||||
#### Variant tests
|
|
||||||
|
|
||||||
These allow testing RGBLINK's `-d`, `-t`, and `-w` flags.
|
|
||||||
If one or more
|
|
||||||
<code>-<var><flag></var>.out</code> or <code>-no-<var><flag></var>.out</code>
|
|
||||||
files exist, then each of them corresponds to one test.
|
|
||||||
|
|
||||||
The object file will be linked with and without said flag, respectively; and in
|
|
||||||
each case, RGBLINK's total output must match the `.out` file's contents.
|
|
||||||
|
|
||||||
### RGBFIX
|
|
||||||
|
|
||||||
Each `.flags` file corresponds to one test.
|
|
||||||
Each one is a text file whose first line contains flags to pass to RGBFIX.
|
|
||||||
(There may be more lines, which will be ignored; they can serve as comments to
|
|
||||||
explain what the test is about.)
|
|
||||||
|
|
||||||
RGBFIX will be invoked on the `.bin` file if it exists, or else on
|
|
||||||
default-input.bin.
|
|
||||||
|
|
||||||
If no `.out` file exist, RGBFIX is not expected to output anything.
|
|
||||||
If one *does* exist, RGBFIX's output **must** match the `.out` file's contents.
|
|
||||||
|
|
||||||
If no `.err` file exists, RGBFIX is simply expected to be able to process the
|
|
||||||
file normally.
|
|
||||||
If one *does* exist, RGBFIX's return status is ignored, but its error output
|
|
||||||
**must** match the `.err` file's contents.
|
|
||||||
|
|
||||||
Additionally, if a `.gb` file exists, the output of RGBFIX must match the `.gb`.
|
|
||||||
|
|
||||||
### RGBGFX
|
|
||||||
|
|
||||||
There are three kinds of test.
|
|
||||||
|
|
||||||
#### Simple tests
|
|
||||||
|
|
||||||
Each `.png` file corresponds to one test.
|
|
||||||
RGBGFX will be invoked on the file.
|
|
||||||
If a `.flags` file exists, it will be used as part of the RGBGFX invocation
|
|
||||||
(<code>@<var><file></var>.flags</code>).
|
|
||||||
|
|
||||||
If `.out.1bpp`, `.out.2bpp`, `.out.pal`, `.out.tilemap`, `.out.attrmap`, or
|
|
||||||
`.out.palmap` files exist, RGBGFX will create the corresponding kind of output,
|
|
||||||
which must match the file's contents.
|
|
||||||
Multiple kinds of output may be tested for the same input.
|
|
||||||
|
|
||||||
If no `.err` file exists, RGBGFX is simply expected to be able to process the
|
|
||||||
file normally.
|
|
||||||
If one *does* exist, RGBGFX's return status is ignored, but its output **must**
|
|
||||||
match the `.err` file's contents.
|
|
||||||
|
|
||||||
#### Reverse tests
|
|
||||||
|
|
||||||
Each `.1bpp` or `.2bpp` file corresponds to one test.
|
|
||||||
RGBGFX will be invoked on the file with `-r 1` for reverse mode, then invoked on
|
|
||||||
the output without `-r 1`.
|
|
||||||
The round-trip output must match the input file's contents.
|
|
||||||
If a `.flags` file exists, it will be used as part of the RGBGFX invocation
|
|
||||||
(<code>@<var><file></var>.flags</code>).
|
|
||||||
|
|
||||||
#### Random seed tests
|
|
||||||
|
|
||||||
Each `seed*.bin` file corresponds to one test.
|
|
||||||
Each one is a binary RNG file which is passed to the `rgbgfx_test` program.
|
|
||||||
|
|
||||||
### Downstream projects
|
|
||||||
|
|
||||||
1. Make sure the downstream project supports
|
|
||||||
<code>make <var><target></var> RGBDS=<var><path/to/RGBDS/></var></code>.
|
|
||||||
While the test suite supports any Make target name, only
|
|
||||||
[Make](//gnu.org/software/make) is currently supported, and the Makefile must
|
|
||||||
support a `RGBDS` variable to use a non-system RGBDS directory.
|
|
||||||
|
|
||||||
Also, only projects hosted on GitHub are currently supported.
|
|
||||||
2. Add the project to `test/fetch-test-deps.sh`: add a new `action` line at the
|
|
||||||
bottom, following the existing pattern:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
action <owner> <repo> <date of last commit> <hash of last commit>
|
|
||||||
```
|
|
||||||
|
|
||||||
(The date is used to avoid fetching too much history when cloning the
|
|
||||||
repositories.)
|
|
||||||
3. Add the project to `test/run-tests.sh`: add a new `test_downstream` line at
|
|
||||||
the bottom, following the existing pattern:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
test_downstream <owner> <repo> <makefile target> <build file> <sha1 hash of build file>
|
|
||||||
```
|
|
||||||
|
|
||||||
## Container images
|
|
||||||
|
|
||||||
The CI will
|
|
||||||
[take care](https://github.com/gbdev/rgbds/blob/master/.github/workflows/build-container.yml)
|
|
||||||
of updating the
|
|
||||||
[rgbds container](https://github.com/gbdev/rgbds/pkgs/container/rgbds) image
|
|
||||||
tagged `master`.
|
|
||||||
|
|
||||||
When a git tag is pushed, the image is also tagged with that tag.
|
|
||||||
|
|
||||||
The image can be built locally and pushed to the GitHub container registry by
|
|
||||||
manually running:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# e.g. to build and tag as 'master'
|
|
||||||
docker build . --tag ghcr.io/gbdev/rgbds:master
|
|
||||||
docker push ghcr.io/gbdev/rgbds:master
|
|
||||||
```
|
|
||||||
95
CONTRIBUTING.rst
Normal file
95
CONTRIBUTING.rst
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
Contributing
|
||||||
|
============
|
||||||
|
|
||||||
|
RGBDS was created in the late '90s and has received contributions from several
|
||||||
|
developers since then. It wouldn't have been possible to get to this point
|
||||||
|
without their work, and it is always open to the contributions of other people.
|
||||||
|
|
||||||
|
Reporting Bugs
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Bug reports are essential to improve RGBDS and they are always welcome. If you
|
||||||
|
want to report a bug:
|
||||||
|
|
||||||
|
1. Make sure that there isn't a similar issue already reported
|
||||||
|
`here <https://github.com/rednex/rgbds/issues>`__.
|
||||||
|
|
||||||
|
2. Figure out a way of reproducing it reliably.
|
||||||
|
|
||||||
|
3. If there is a piece of code that triggers the bug, try to reduce it to the
|
||||||
|
smallest file you can.
|
||||||
|
|
||||||
|
4. Create a new `issue <https://github.com/rednex/rgbds/issues>`__.
|
||||||
|
|
||||||
|
Of course, it may not always be possible to give an accurate bug report, but it
|
||||||
|
always helps to fix it.
|
||||||
|
|
||||||
|
Requesting new features
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
If you come up with a good idea that could be implemented, you can propose it to
|
||||||
|
be done.
|
||||||
|
|
||||||
|
1. Create a new `issue <https://github.com/rednex/rgbds/issues>`__.
|
||||||
|
|
||||||
|
2. Try to be as accurate as possible. Describe what you need and why you need
|
||||||
|
it, maybe with examples.
|
||||||
|
|
||||||
|
Please understand that the contributors are doing it in their free time, so
|
||||||
|
simple requests are more likely to catch the interest of a contributor than
|
||||||
|
complicated ones. If you really need something to be done, and you think you can
|
||||||
|
implement it yourself, you can always contribute to RGBDS with your own code.
|
||||||
|
|
||||||
|
Contributing code
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
If you want to contribute with your own code, whether it is to fix a current
|
||||||
|
issue or to add something that nobody had requested, you should first consider
|
||||||
|
if your change is going to be small (and likely to be accepted as-is) or big
|
||||||
|
(and will have to go through some rework).
|
||||||
|
|
||||||
|
Big changes will most likely require some discussion, so open an
|
||||||
|
`issue <https://github.com/rednex/rgbds/issues>`__ and explain what you want to
|
||||||
|
do and how you intend to do it. If you already have a prototype, it's always a
|
||||||
|
good idea to show it. Tests help, too.
|
||||||
|
|
||||||
|
If you are going to work on a specific issue that involves a lot of work, it is
|
||||||
|
always a good idea to leave a message, just in case someone else is interested
|
||||||
|
but doesn't know that there's someone working on it.
|
||||||
|
|
||||||
|
Note that you must contribute all your changes under the MIT License. If you are
|
||||||
|
just modifying a file, you don't need to do anything (maybe update the copyright
|
||||||
|
years). If you are adding new files, you need to use the correct header with the
|
||||||
|
copyright and the reference to the MIT License.
|
||||||
|
|
||||||
|
1. Fork this repository.
|
||||||
|
|
||||||
|
2. Checkout the ``master`` branch.
|
||||||
|
|
||||||
|
3. Create a new branch to work on. You could still work on ``master``, but it's
|
||||||
|
easier that way.
|
||||||
|
|
||||||
|
4. Compile your changes with ``make develop`` instead of just ``make``. This
|
||||||
|
target checks for additional warnings. Your patches shouldn't introduce any
|
||||||
|
new warning (but it may be possible to remove some warning checks if it makes
|
||||||
|
the code much easier).
|
||||||
|
|
||||||
|
5. Follow the Linux kernel coding style, which can be found in the file
|
||||||
|
``Documentation/process/coding-style.rst`` in the Linux kernel repository.
|
||||||
|
Note that the coding style isn't written in stone, if there is a good reason
|
||||||
|
to deviate from it, it should be fine.
|
||||||
|
|
||||||
|
6. Download the files ``checkpatch.pl``, ``const_structs.checkpatch`` and
|
||||||
|
``spelling.txt`` from the folder ``scripts`` in the Linux kernel repository.
|
||||||
|
|
||||||
|
7. To use ``checkpatch.pl`` you can use ``make checkpatch``, which will check
|
||||||
|
the coding style of all patches between the current one and the upstream
|
||||||
|
code. By default, the Makefile expects the script (and associate files) to be
|
||||||
|
located in ``../linux/scripts/``, but you can place them anywhere you like as
|
||||||
|
long as you specify it when executing the command:
|
||||||
|
``make checkpatch CHECKPATCH=../path/to/folder``.
|
||||||
|
|
||||||
|
8. Create a pull request against the branch ``master``.
|
||||||
|
|
||||||
|
9. Be prepared to get some comments about your code and to modify it. Tip: Use
|
||||||
|
``git rebase -i origin/master`` to modify chains of commits.
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
# Contributors to RGBDS
|
|
||||||
|
|
||||||
## Original author
|
|
||||||
|
|
||||||
- Carsten Elton Sørensen <csoren@gmail.com>
|
|
||||||
|
|
||||||
## Main contributors
|
|
||||||
|
|
||||||
- Justin Lloyd <jlloyd@imf.la>
|
|
||||||
- Vegard Nossum <vegard.nossum@gmail.com>
|
|
||||||
- Anthony J. Bentley <anthony@anjbe.name>
|
|
||||||
- stag019 <stag019@gmail.com>
|
|
||||||
- Antonio Niño Díaz <antonio_nd@outlook.com>
|
|
||||||
- Eldred "ISSOtm" Habert <me@eldred.fr>
|
|
||||||
- Sylvie "Rangi" Oukaour <https://github.com/Rangi42>
|
|
||||||
|
|
||||||
## Other contributors
|
|
||||||
|
|
||||||
- Ben Hetherington <dev@ben-h.uk>
|
|
||||||
- Björn Höhrmann <bjoern@hoehrmann.de>
|
|
||||||
- Christophe Staïesse <chastai@skynet.be>
|
|
||||||
- David Brotz <dbrotz007@gmail.com>
|
|
||||||
- Evie <https://evie.gbdev.io>
|
|
||||||
- James "JL2210" Larrowe <https://github.com/JL2210>
|
|
||||||
- Maja Kądziołka <github@compilercrim.es>
|
|
||||||
- The Musl C library <https://musl.libc.org/>
|
|
||||||
- obskyr <powpowd@gmail.com>
|
|
||||||
- The OpenBSD Project <http://www.openbsd.org>
|
|
||||||
- Quint Guvernator <quint@guvernator.net>
|
|
||||||
- Sanqui <gsanky@gmail.com>
|
|
||||||
- YamaArashi <shadow962@live.com>
|
|
||||||
- yenatch <yenatch@gmail.com>
|
|
||||||
- phs <phil@philhsmith.com>
|
|
||||||
- jidoc01 <jidoc01@naver.com>
|
|
||||||
|
|
||||||
[<img src="https://contrib.rocks/image?repo=gbdev/rgbds">](https://github.com/gbdev/rgbds/graphs/contributors)
|
|
||||||
|
|
||||||
Contributor image made with [contrib.rocks](https://contrib.rocks).
|
|
||||||
|
|
||||||
## Acknowledgements
|
|
||||||
|
|
||||||
RGBGFX generates palettes using algorithms found in the paper
|
|
||||||
["Algorithms for the Pagination Problem, a Bin Packing with Overlapping Items"](https://arxiv.org/abs/1605.00558)
|
|
||||||
([GitHub](https://github.com/pagination-problem/pagination), MIT license),
|
|
||||||
by Aristide Grange, Imed Kacem, and Sébastien Martin.
|
|
||||||
|
|
||||||
RGBGFX's color palette was taken from [SameBoy](https://sameboy.github.io), with
|
|
||||||
permission and help by [LIJI](https://github.com/LIJI32).
|
|
||||||
57
CONTRIBUTORS.rst
Normal file
57
CONTRIBUTORS.rst
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
Contributors to RGBDS
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Original author
|
||||||
|
---------------
|
||||||
|
|
||||||
|
- Carsten Elton Sørensen <csoren@gmail.com>
|
||||||
|
|
||||||
|
Main contributors
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
- Justin Lloyd <jlloyd@imf.la>
|
||||||
|
|
||||||
|
- Vegard Nossum <vegard.nossum@gmail.com>
|
||||||
|
|
||||||
|
- Anthony J. Bentley <anthony@anjbe.name>
|
||||||
|
|
||||||
|
- stag019 <stag019@gmail.com>
|
||||||
|
|
||||||
|
- Antonio Niño Díaz <antonio_nd@outlook.com>
|
||||||
|
|
||||||
|
- Eldred "ISSOtm" Habert <eldredhabert0@gmail.com>
|
||||||
|
|
||||||
|
- Rangi <http://github.com/Rangi42>
|
||||||
|
|
||||||
|
Other contributors
|
||||||
|
------------------
|
||||||
|
|
||||||
|
- Ben Hetherington <dev@ben-h.uk>
|
||||||
|
|
||||||
|
- Björn Höhrmann <bjoern@hoehrmann.de>
|
||||||
|
|
||||||
|
- Christophe Staïesse <chastai@skynet.be>
|
||||||
|
|
||||||
|
- David Brotz <dbrotz007@gmail.com>
|
||||||
|
|
||||||
|
- Jakub Kądziołka <kuba@kadziolka.net>
|
||||||
|
|
||||||
|
- James "JL2210" Larrowe <https://github.com/JL2210>
|
||||||
|
|
||||||
|
- The Musl C library <http://www.musl-libc.org>
|
||||||
|
|
||||||
|
- obskyr <powpowd@gmail.com>
|
||||||
|
|
||||||
|
- The OpenBSD Project <http://www.openbsd.org>
|
||||||
|
|
||||||
|
- Quint Guvernator <quint@guvernator.net>
|
||||||
|
|
||||||
|
- Sanqui <gsanky@gmail.com>
|
||||||
|
|
||||||
|
- YamaArashi <shadow962@live.com>
|
||||||
|
|
||||||
|
- yenatch <yenatch@gmail.com>
|
||||||
|
|
||||||
|
- phs <phil@philhsmith.com>
|
||||||
|
|
||||||
|
- jidoc01 <jidoc01@naver.com>
|
||||||
41
Dockerfile
41
Dockerfile
@@ -1,21 +1,24 @@
|
|||||||
FROM debian:12-slim
|
# This file is part of RGBDS.
|
||||||
LABEL org.opencontainers.image.source=https://github.com/gbdev/rgbds
|
#
|
||||||
ARG version=1.0.0-rc2
|
# Copyright (c) 2018-2019, Phil Smith and RGBDS contributors.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
# docker build -t rgbds:vX.X.X-alpine
|
||||||
|
FROM alpine:latest
|
||||||
|
RUN apk add --update \
|
||||||
|
build-base \
|
||||||
|
bison \
|
||||||
|
libpng-dev
|
||||||
|
COPY . /rgbds
|
||||||
WORKDIR /rgbds
|
WORKDIR /rgbds
|
||||||
|
RUN make Q='' all
|
||||||
|
|
||||||
COPY . .
|
FROM alpine:latest
|
||||||
|
RUN apk add --update \
|
||||||
RUN apt-get update && \
|
libpng
|
||||||
apt-get install sudo make cmake gcc build-essential -y
|
COPY --from=0 \
|
||||||
|
/rgbds/rgbasm \
|
||||||
# Install dependencies and compile RGBDS
|
/rgbds/rgbfix \
|
||||||
RUN ./.github/scripts/install_deps.sh ubuntu-22.04
|
/rgbds/rgblink \
|
||||||
RUN make -j CXXFLAGS="-O3 -flto -DNDEBUG -static" PKG_CONFIG="pkg-config --static" Q=
|
/rgbds/rgbgfx \
|
||||||
|
/bin/
|
||||||
# Create an archive with the compiled executables and all the necessary to install it,
|
|
||||||
# so it can be copied outside of the container and installed/used in another system
|
|
||||||
RUN tar caf rgbds-linux-x86_64.tar.xz --transform='s#.*/##' rgbasm rgblink rgbfix rgbgfx man/* .github/scripts/install.sh
|
|
||||||
|
|
||||||
# Install RGBDS on the container so all the executables will be available in the PATH
|
|
||||||
RUN cp man/* .
|
|
||||||
RUN ./.github/scripts/install.sh
|
|
||||||
|
|||||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
|||||||
The MIT License
|
The MIT License
|
||||||
|
|
||||||
Copyright (c) 1996-2025, Carsten Sørensen and RGBDS contributors.
|
Copyright (c) 1997-2020, Carsten Sorensen and RGBDS contributors.
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to
|
of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
286
Makefile
286
Makefile
@@ -1,9 +1,13 @@
|
|||||||
|
#
|
||||||
|
# This file is part of RGBDS.
|
||||||
|
#
|
||||||
|
# Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
|
||||||
|
#
|
||||||
# SPDX-License-Identifier: MIT
|
# SPDX-License-Identifier: MIT
|
||||||
|
#
|
||||||
|
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
.SUFFIXES: .cpp .y .o
|
.SUFFIXES: .h .y .c .o
|
||||||
|
|
||||||
.PHONY: all clean install checkdiff develop debug profile coverage format tidy iwyu mingw32 mingw64 wine-shim dist
|
|
||||||
|
|
||||||
# User-defined variables
|
# User-defined variables
|
||||||
|
|
||||||
@@ -11,10 +15,10 @@ Q := @
|
|||||||
PREFIX := /usr/local
|
PREFIX := /usr/local
|
||||||
bindir := ${PREFIX}/bin
|
bindir := ${PREFIX}/bin
|
||||||
mandir := ${PREFIX}/share/man
|
mandir := ${PREFIX}/share/man
|
||||||
SUFFIX :=
|
|
||||||
STRIP := -s
|
STRIP := -s
|
||||||
BINMODE := 755
|
BINMODE := 755
|
||||||
MANMODE := 644
|
MANMODE := 644
|
||||||
|
CHECKPATCH := ../linux/scripts/checkpatch.pl
|
||||||
|
|
||||||
# Other variables
|
# Other variables
|
||||||
|
|
||||||
@@ -23,23 +27,26 @@ PNGCFLAGS := `${PKG_CONFIG} --cflags libpng`
|
|||||||
PNGLDFLAGS := `${PKG_CONFIG} --libs-only-L libpng`
|
PNGLDFLAGS := `${PKG_CONFIG} --libs-only-L libpng`
|
||||||
PNGLDLIBS := `${PKG_CONFIG} --libs-only-l libpng`
|
PNGLDLIBS := `${PKG_CONFIG} --libs-only-l libpng`
|
||||||
|
|
||||||
# Note: if this comes up empty, `version.cpp` will automatically fall back to last release number
|
# Note: if this comes up empty, `version.c` will automatically fall back to last release number
|
||||||
VERSION_STRING := `git --git-dir=.git -c safe.directory='*' describe --tags --dirty --always 2>/dev/null`
|
VERSION_STRING := `git describe --tags --dirty --always 2>/dev/null`
|
||||||
|
|
||||||
WARNFLAGS := -Wall -pedantic -Wno-unknown-warning-option -Wno-gnu-zero-variadic-macro-arguments
|
WARNFLAGS := -Wall -pedantic
|
||||||
|
|
||||||
# Overridable CXXFLAGS
|
# Overridable CFLAGS
|
||||||
CXXFLAGS ?= -O3 -flto -DNDEBUG
|
CFLAGS ?= -O3 -flto -DNDEBUG
|
||||||
# Non-overridable CXXFLAGS
|
# Non-overridable CFLAGS
|
||||||
REALCXXFLAGS := ${CXXFLAGS} ${WARNFLAGS} -std=c++2a -I include -fno-exceptions -fno-rtti
|
# _ISOC11_SOURCE is required on certain platforms to get C11 on top of the C99-based POSIX 2008
|
||||||
|
REALCFLAGS := ${CFLAGS} ${WARNFLAGS} -std=gnu11 -I include \
|
||||||
|
-D_POSIX_C_SOURCE=200809L -D_ISOC11_SOURCE
|
||||||
# Overridable LDFLAGS
|
# Overridable LDFLAGS
|
||||||
LDFLAGS ?=
|
LDFLAGS ?=
|
||||||
# Non-overridable LDFLAGS
|
# Non-overridable LDFLAGS
|
||||||
REALLDFLAGS := ${LDFLAGS} ${WARNFLAGS} -DBUILD_VERSION_STRING=\"${VERSION_STRING}\"
|
REALLDFLAGS := ${LDFLAGS} ${WARNFLAGS} \
|
||||||
|
-DBUILD_VERSION_STRING=\"${VERSION_STRING}\"
|
||||||
|
|
||||||
# Wrapper around bison that passes flags depending on what the version supports
|
YFLAGS ?= -Wall
|
||||||
BISON := src/bison.sh
|
|
||||||
|
|
||||||
|
BISON := bison
|
||||||
RM := rm -rf
|
RM := rm -rf
|
||||||
|
|
||||||
# Used for checking pull requests
|
# Used for checking pull requests
|
||||||
@@ -49,17 +56,7 @@ BASE_REF := origin/master
|
|||||||
|
|
||||||
all: rgbasm rgblink rgbfix rgbgfx
|
all: rgbasm rgblink rgbfix rgbgfx
|
||||||
|
|
||||||
common_obj := \
|
|
||||||
src/extern/getopt.o \
|
|
||||||
src/cli.o \
|
|
||||||
src/diagnostics.o \
|
|
||||||
src/style.o \
|
|
||||||
src/usage.o \
|
|
||||||
src/util.o
|
|
||||||
|
|
||||||
rgbasm_obj := \
|
rgbasm_obj := \
|
||||||
${common_obj} \
|
|
||||||
src/asm/actions.o \
|
|
||||||
src/asm/charmap.o \
|
src/asm/charmap.o \
|
||||||
src/asm/fixpoint.o \
|
src/asm/fixpoint.o \
|
||||||
src/asm/format.o \
|
src/asm/format.o \
|
||||||
@@ -73,207 +70,182 @@ rgbasm_obj := \
|
|||||||
src/asm/rpn.o \
|
src/asm/rpn.o \
|
||||||
src/asm/section.o \
|
src/asm/section.o \
|
||||||
src/asm/symbol.o \
|
src/asm/symbol.o \
|
||||||
|
src/asm/util.o \
|
||||||
src/asm/warning.o \
|
src/asm/warning.o \
|
||||||
|
src/extern/getopt.o \
|
||||||
src/extern/utf8decoder.o \
|
src/extern/utf8decoder.o \
|
||||||
src/backtrace.o \
|
src/error.o \
|
||||||
|
src/hashmap.o \
|
||||||
src/linkdefs.o \
|
src/linkdefs.o \
|
||||||
src/opmath.o \
|
src/opmath.o
|
||||||
src/verbosity.o
|
|
||||||
|
|
||||||
src/asm/lexer.o src/asm/main.o: src/asm/parser.hpp
|
src/asm/lexer.o src/asm/main.o: src/asm/parser.h
|
||||||
|
|
||||||
rgblink_obj := \
|
rgblink_obj := \
|
||||||
${common_obj} \
|
|
||||||
src/link/assign.o \
|
src/link/assign.o \
|
||||||
src/link/fstack.o \
|
|
||||||
src/link/lexer.o \
|
|
||||||
src/link/layout.o \
|
|
||||||
src/link/main.o \
|
src/link/main.o \
|
||||||
src/link/object.o \
|
src/link/object.o \
|
||||||
src/link/output.o \
|
src/link/output.o \
|
||||||
src/link/patch.o \
|
src/link/patch.o \
|
||||||
src/link/script.o \
|
src/link/script.o \
|
||||||
src/link/sdas_obj.o \
|
|
||||||
src/link/section.o \
|
src/link/section.o \
|
||||||
src/link/symbol.o \
|
src/link/symbol.o \
|
||||||
src/link/warning.o \
|
src/extern/getopt.o \
|
||||||
src/extern/utf8decoder.o \
|
src/error.o \
|
||||||
src/backtrace.o \
|
src/hashmap.o \
|
||||||
src/linkdefs.o \
|
src/linkdefs.o \
|
||||||
src/opmath.o \
|
src/opmath.o
|
||||||
src/verbosity.o
|
|
||||||
|
|
||||||
src/link/lexer.o src/link/main.o: src/link/script.hpp
|
|
||||||
|
|
||||||
rgbfix_obj := \
|
rgbfix_obj := \
|
||||||
${common_obj} \
|
|
||||||
src/fix/fix.o \
|
|
||||||
src/fix/main.o \
|
src/fix/main.o \
|
||||||
src/fix/mbc.o \
|
src/extern/getopt.o \
|
||||||
src/fix/warning.o
|
src/error.o
|
||||||
|
|
||||||
rgbgfx_obj := \
|
rgbgfx_obj := \
|
||||||
${common_obj} \
|
src/gfx/gb.o \
|
||||||
src/gfx/color_set.o \
|
|
||||||
src/gfx/main.o \
|
src/gfx/main.o \
|
||||||
src/gfx/pal_packing.o \
|
src/gfx/makepng.o \
|
||||||
src/gfx/pal_sorting.o \
|
src/extern/getopt.o \
|
||||||
src/gfx/pal_spec.o \
|
src/error.o
|
||||||
src/gfx/palette.o \
|
|
||||||
src/gfx/png.o \
|
|
||||||
src/gfx/process.o \
|
|
||||||
src/gfx/reverse.o \
|
|
||||||
src/gfx/rgba.o \
|
|
||||||
src/gfx/warning.o \
|
|
||||||
src/verbosity.o
|
|
||||||
|
|
||||||
rgbasm: ${rgbasm_obj}
|
rgbasm: ${rgbasm_obj}
|
||||||
$Q${CXX} ${REALLDFLAGS} -o $@ ${rgbasm_obj} ${REALCXXFLAGS} src/version.cpp
|
$Q${CC} ${REALLDFLAGS} -o $@ ${rgbasm_obj} ${REALCFLAGS} src/version.c -lm
|
||||||
|
|
||||||
rgblink: ${rgblink_obj}
|
rgblink: ${rgblink_obj}
|
||||||
$Q${CXX} ${REALLDFLAGS} -o $@ ${rgblink_obj} ${REALCXXFLAGS} src/version.cpp
|
$Q${CC} ${REALLDFLAGS} -o $@ ${rgblink_obj} ${REALCFLAGS} src/version.c
|
||||||
|
|
||||||
rgbfix: ${rgbfix_obj}
|
rgbfix: ${rgbfix_obj}
|
||||||
$Q${CXX} ${REALLDFLAGS} -o $@ ${rgbfix_obj} ${REALCXXFLAGS} src/version.cpp
|
$Q${CC} ${REALLDFLAGS} -o $@ ${rgbfix_obj} ${REALCFLAGS} src/version.c
|
||||||
|
|
||||||
rgbgfx: ${rgbgfx_obj}
|
rgbgfx: ${rgbgfx_obj}
|
||||||
$Q${CXX} ${REALLDFLAGS} ${PNGLDFLAGS} -o $@ ${rgbgfx_obj} ${REALCXXFLAGS} ${PNGLDLIBS} src/version.cpp
|
$Q${CC} ${REALLDFLAGS} ${PNGLDFLAGS} -o $@ ${rgbgfx_obj} ${REALCFLAGS} src/version.c ${PNGLDLIBS}
|
||||||
|
|
||||||
test/gfx/randtilegen: test/gfx/randtilegen.cpp
|
|
||||||
$Q${CXX} ${REALLDFLAGS} ${PNGLDFLAGS} -o $@ $^ ${REALCXXFLAGS} ${PNGCFLAGS} ${PNGLDLIBS}
|
|
||||||
|
|
||||||
test/gfx/rgbgfx_test: test/gfx/rgbgfx_test.cpp
|
|
||||||
$Q${CXX} ${REALLDFLAGS} ${PNGLDFLAGS} -o $@ $^ ${REALCXXFLAGS} ${PNGCFLAGS} ${PNGLDLIBS}
|
|
||||||
|
|
||||||
# Rules to process files
|
# Rules to process files
|
||||||
|
|
||||||
# We want the Bison invocation to pass through our rules, not default ones
|
# We want the Bison invocation to pass through our rules, not default ones
|
||||||
.y.o:
|
.y.o:
|
||||||
|
|
||||||
.y.cpp:
|
# Bison-generated C files have an accompanying header
|
||||||
$Q${BISON} $@ $<
|
src/asm/parser.h: src/asm/parser.c
|
||||||
|
|
||||||
# Bison-generated C++ files have an accompanying header
|
|
||||||
src/asm/parser.hpp: src/asm/parser.cpp
|
|
||||||
$Qtouch $@
|
|
||||||
src/link/script.hpp: src/link/script.cpp
|
|
||||||
$Qtouch $@
|
$Qtouch $@
|
||||||
|
|
||||||
# Only RGBGFX uses libpng (POSIX make doesn't support pattern rules to cover all these)
|
src/asm/parser.c: src/asm/parser.y
|
||||||
src/gfx/color_set.o: src/gfx/color_set.cpp
|
$QDEFS=; \
|
||||||
$Q${CXX} ${REALCXXFLAGS} ${PNGCFLAGS} -c -o $@ $<
|
add_flag(){ \
|
||||||
src/gfx/main.o: src/gfx/main.cpp
|
if src/check_bison_ver.sh $$1 $$2; then \
|
||||||
$Q${CXX} ${REALCXXFLAGS} ${PNGCFLAGS} -c -o $@ $<
|
DEFS="-D$$3 $$DEFS"; \
|
||||||
src/gfx/pal_packing.o: src/gfx/pal_packing.cpp
|
fi \
|
||||||
$Q${CXX} ${REALCXXFLAGS} ${PNGCFLAGS} -c -o $@ $<
|
}; \
|
||||||
src/gfx/pal_sorting.o: src/gfx/pal_sorting.cpp
|
add_flag 3 5 api.token.raw=true; \
|
||||||
$Q${CXX} ${REALCXXFLAGS} ${PNGCFLAGS} -c -o $@ $<
|
add_flag 3 6 parse.error=detailed; \
|
||||||
src/gfx/pal_spec.o: src/gfx/pal_spec.cpp
|
add_flag 3 0 parse.error=verbose; \
|
||||||
$Q${CXX} ${REALCXXFLAGS} ${PNGCFLAGS} -c -o $@ $<
|
add_flag 3 0 parse.lac=full; \
|
||||||
src/gfx/png.o: src/gfx/png.cpp
|
add_flag 3 0 lr.type=ielr; \
|
||||||
$Q${CXX} ${REALCXXFLAGS} ${PNGCFLAGS} -c -o $@ $<
|
echo "DEFS=$$DEFS"; \
|
||||||
src/gfx/process.o: src/gfx/process.cpp
|
${BISON} $$DEFS -d ${YFLAGS} -o $@ $<
|
||||||
$Q${CXX} ${REALCXXFLAGS} ${PNGCFLAGS} -c -o $@ $<
|
|
||||||
src/gfx/reverse.o: src/gfx/reverse.cpp
|
|
||||||
$Q${CXX} ${REALCXXFLAGS} ${PNGCFLAGS} -c -o $@ $<
|
|
||||||
src/gfx/rgba.o: src/gfx/rgba.cpp
|
|
||||||
$Q${CXX} ${REALCXXFLAGS} ${PNGCFLAGS} -c -o $@ $<
|
|
||||||
|
|
||||||
.cpp.o:
|
.c.o:
|
||||||
$Q${CXX} ${REALCXXFLAGS} -c -o $@ $<
|
$Q${CC} ${REALCFLAGS} ${PNGCFLAGS} -c -o $@ $<
|
||||||
|
|
||||||
# Target used to remove all files generated by other Makefile targets
|
# Target used to remove all files generated by other Makefile targets
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$Q${RM} rgbasm rgbasm.exe
|
$Q${RM} rgbasm rgbasm.exe
|
||||||
$Q${RM} rgblink rgblink.exe
|
$Q${RM} rgblink rgblink.exe
|
||||||
$Q${RM} rgbfix rgbfix.exe
|
$Q${RM} rgbfix rgbfix.exe
|
||||||
$Q${RM} rgbgfx rgbgfx.exe
|
$Q${RM} rgbgfx rgbgfx.exe
|
||||||
$Qfind src/ -name "*.o" -exec rm {} \;
|
$Qfind src/ -name "*.o" -exec rm {} \;
|
||||||
$Qfind . -type f \( -name "*.gcno" -o -name "*.gcda" -o -name "*.gcov" \) -exec rm {} \;
|
|
||||||
$Q${RM} rgbshim.sh
|
$Q${RM} rgbshim.sh
|
||||||
$Q${RM} src/asm/parser.cpp src/asm/parser.hpp src/asm/stack.hh
|
$Q${RM} src/asm/parser.c src/asm/parser.h
|
||||||
$Q${RM} src/link/script.cpp src/link/script.hpp src/link/stack.hh
|
|
||||||
$Q${RM} test/gfx/randtilegen test/gfx/rgbgfx_test
|
|
||||||
|
|
||||||
# Target used to install the binaries and man pages.
|
# Target used to install the binaries and man pages.
|
||||||
|
|
||||||
install: all
|
install: all
|
||||||
$Qinstall -d ${DESTDIR}${bindir}/ ${DESTDIR}${mandir}/man1/ ${DESTDIR}${mandir}/man5/ ${DESTDIR}${mandir}/man7/
|
$Qmkdir -p ${DESTDIR}${bindir}
|
||||||
$Qinstall ${STRIP} -m ${BINMODE} rgbasm ${DESTDIR}${bindir}/rgbasm${SUFFIX}
|
$Qinstall ${STRIP} -m ${BINMODE} rgbasm ${DESTDIR}${bindir}/rgbasm
|
||||||
$Qinstall ${STRIP} -m ${BINMODE} rgblink ${DESTDIR}${bindir}/rgblink${SUFFIX}
|
$Qinstall ${STRIP} -m ${BINMODE} rgbfix ${DESTDIR}${bindir}/rgbfix
|
||||||
$Qinstall ${STRIP} -m ${BINMODE} rgbfix ${DESTDIR}${bindir}/rgbfix${SUFFIX}
|
$Qinstall ${STRIP} -m ${BINMODE} rgblink ${DESTDIR}${bindir}/rgblink
|
||||||
$Qinstall ${STRIP} -m ${BINMODE} rgbgfx ${DESTDIR}${bindir}/rgbgfx${SUFFIX}
|
$Qinstall ${STRIP} -m ${BINMODE} rgbgfx ${DESTDIR}${bindir}/rgbgfx
|
||||||
$Qinstall -m ${MANMODE} man/rgbasm.1 man/rgblink.1 man/rgbfix.1 man/rgbgfx.1 ${DESTDIR}${mandir}/man1/
|
$Qmkdir -p ${DESTDIR}${mandir}/man1 ${DESTDIR}${mandir}/man5 ${DESTDIR}${mandir}/man7
|
||||||
$Qinstall -m ${MANMODE} man/rgbds.5 man/rgbasm.5 man/rgbasm-old.5 man/rgblink.5 ${DESTDIR}${mandir}/man5/
|
$Qinstall -m ${MANMODE} src/rgbds.7 ${DESTDIR}${mandir}/man7/rgbds.7
|
||||||
$Qinstall -m ${MANMODE} man/rgbds.7 man/gbz80.7 ${DESTDIR}${mandir}/man7/
|
$Qinstall -m ${MANMODE} src/gbz80.7 ${DESTDIR}${mandir}/man7/gbz80.7
|
||||||
|
$Qinstall -m ${MANMODE} src/rgbds.5 ${DESTDIR}${mandir}/man5/rgbds.5
|
||||||
|
$Qinstall -m ${MANMODE} src/asm/rgbasm.1 ${DESTDIR}${mandir}/man1/rgbasm.1
|
||||||
|
$Qinstall -m ${MANMODE} src/asm/rgbasm.5 ${DESTDIR}${mandir}/man5/rgbasm.5
|
||||||
|
$Qinstall -m ${MANMODE} src/fix/rgbfix.1 ${DESTDIR}${mandir}/man1/rgbfix.1
|
||||||
|
$Qinstall -m ${MANMODE} src/link/rgblink.1 ${DESTDIR}${mandir}/man1/rgblink.1
|
||||||
|
$Qinstall -m ${MANMODE} src/link/rgblink.5 ${DESTDIR}${mandir}/man5/rgblink.5
|
||||||
|
$Qinstall -m ${MANMODE} src/gfx/rgbgfx.1 ${DESTDIR}${mandir}/man1/rgbgfx.1
|
||||||
|
|
||||||
|
# Target used to check the coding style of the whole codebase.
|
||||||
|
# `extern/` is excluded, as it contains external code that should not be patched
|
||||||
|
# to meet our coding style, so applying upstream patches is easier.
|
||||||
|
# `.y` files aren't checked, unfortunately...
|
||||||
|
|
||||||
|
checkcodebase:
|
||||||
|
$Qfor file in `git ls-files | grep -E '(\.c|\.h)$$' | grep -Ev '(src|include)/extern/'`; do \
|
||||||
|
${CHECKPATCH} -f "$$file"; \
|
||||||
|
done
|
||||||
|
|
||||||
|
# Target used to check the coding style of the patches from the upstream branch
|
||||||
|
# to the HEAD. Runs checkpatch once for each commit between the current HEAD and
|
||||||
|
# the first common commit between the HEAD and origin/master.
|
||||||
|
# `.y` files aren't checked, unfortunately...
|
||||||
|
|
||||||
|
checkpatch:
|
||||||
|
$QCOMMON_COMMIT=`git merge-base HEAD ${BASE_REF}`; \
|
||||||
|
for commit in `git rev-list $$COMMON_COMMIT..HEAD`; do \
|
||||||
|
echo "[*] Analyzing commit '$$commit'"; \
|
||||||
|
git format-patch --stdout "$$commit~..$$commit" \
|
||||||
|
-- src include '!src/extern' '!include/extern' \
|
||||||
|
| ${CHECKPATCH} - || true; \
|
||||||
|
done
|
||||||
|
|
||||||
# Target used to check for suspiciously missing changed files.
|
# Target used to check for suspiciously missing changed files.
|
||||||
|
|
||||||
checkdiff:
|
checkdiff:
|
||||||
$Qcontrib/checkdiff.bash `git merge-base HEAD ${BASE_REF}`
|
$Qcontrib/checkdiff.bash `git merge-base HEAD ${BASE_REF}`
|
||||||
|
|
||||||
# Target used in development to prevent adding new issues to the source code.
|
# This target is used during development in order to prevent adding new issues
|
||||||
# All warnings are treated as errors to block the compilation and make the
|
# to the source code. All warnings are treated as errors in order to block the
|
||||||
# continous integration infrastructure return failure.
|
# compilation and make the continous integration infrastructure return failure.
|
||||||
# The rationale for some of the flags is documented in the CMakeLists.
|
# The rationale for some of the flags is documented in the CMakeLists.
|
||||||
|
|
||||||
develop:
|
develop:
|
||||||
$Q${MAKE} WARNFLAGS="${WARNFLAGS} -Werror -Wextra \
|
$Qenv ${MAKE} WARNFLAGS="-Werror -Wextra \
|
||||||
-Walloc-zero -Wcast-align -Wcast-qual -Wduplicated-branches -Wduplicated-cond \
|
-Walloc-zero -Wcast-align -Wcast-qual -Wduplicated-branches -Wduplicated-cond \
|
||||||
-Wfloat-equal -Wlogical-op -Wnull-dereference -Wold-style-cast -Wshift-overflow=2 \
|
-Wfloat-equal -Winline -Wlogical-op -Wnested-externs -Wold-style-definition \
|
||||||
-Wstringop-overflow=4 -Wtrampolines -Wundef -Wuninitialized -Wunused -Wshadow \
|
-Wshift-overflow=2 \
|
||||||
|
-Wstrict-overflow=5 -Wstrict-prototypes -Wundef -Wuninitialized -Wunused \
|
||||||
|
-Wshadow \
|
||||||
|
-Wnull-dereference -Wstringop-overflow=4 \
|
||||||
-Wformat=2 -Wformat-overflow=2 -Wformat-truncation=1 \
|
-Wformat=2 -Wformat-overflow=2 -Wformat-truncation=1 \
|
||||||
-Wno-format-nonliteral -Wno-strict-overflow -Wno-unused-but-set-variable \
|
-Wno-format-nonliteral \
|
||||||
-Wno-type-limits -Wno-tautological-constant-out-of-range-compare -Wvla \
|
-Wno-type-limits -Wno-tautological-constant-out-of-range-compare \
|
||||||
-D_GLIBCXX_ASSERTIONS -fsanitize=address -fsanitize=undefined \
|
-Wvla \
|
||||||
-fsanitize=float-divide-by-zero" \
|
-Wno-unknown-warning-option \
|
||||||
CXXFLAGS="-ggdb3 -Og -fno-omit-frame-pointer -fno-optimize-sibling-calls"
|
-fsanitize=shift -fsanitize=integer-divide-by-zero \
|
||||||
|
-fsanitize=unreachable -fsanitize=vla-bound \
|
||||||
# Target used in development to debug with gdb.
|
-fsanitize=signed-integer-overflow -fsanitize=bounds \
|
||||||
debug:
|
-fsanitize=object-size -fsanitize=bool -fsanitize=enum \
|
||||||
$Qenv ${MAKE} \
|
-fsanitize=alignment -fsanitize=null -fsanitize=address" \
|
||||||
CXXFLAGS="-ggdb3 -O0 -fno-omit-frame-pointer -fno-optimize-sibling-calls"
|
CFLAGS="-ggdb3 -Og -fno-omit-frame-pointer -fno-optimize-sibling-calls"
|
||||||
|
|
||||||
# Target used in development to profile with callgrind.
|
|
||||||
profile:
|
|
||||||
$Qenv ${MAKE} \
|
|
||||||
CXXFLAGS="-ggdb3 -O3 -fno-omit-frame-pointer -fno-optimize-sibling-calls"
|
|
||||||
|
|
||||||
# Target used in development to inspect code coverage with gcov.
|
|
||||||
coverage:
|
|
||||||
$Qenv ${MAKE} \
|
|
||||||
CXXFLAGS="-ggdb3 -Og --coverage -fno-omit-frame-pointer -fno-optimize-sibling-calls"
|
|
||||||
|
|
||||||
# Target used in development to format source code with clang-format.
|
|
||||||
format:
|
|
||||||
$Qclang-format -i $$(git ls-files '*.hpp' '*.cpp')
|
|
||||||
|
|
||||||
# Target used in development to check code with clang-tidy.
|
|
||||||
# Requires Bison-generated header files to exist.
|
|
||||||
tidy: src/asm/parser.hpp src/link/script.hpp
|
|
||||||
$Qclang-tidy -p . $$(git ls-files '*.hpp' '*.cpp')
|
|
||||||
|
|
||||||
# Target used in development to remove unused `#include` headers.
|
|
||||||
iwyu:
|
|
||||||
$Qenv ${MAKE} \
|
|
||||||
CXX="include-what-you-use" \
|
|
||||||
REALCXXFLAGS="-std=c++2a -I include"
|
|
||||||
|
|
||||||
# Targets for the project maintainer to easily create Windows exes.
|
# Targets for the project maintainer to easily create Windows exes.
|
||||||
# This is not for Windows users!
|
# This is not for Windows users!
|
||||||
# If you're building on Windows with Cygwin or MinGW, just follow the Unix
|
# If you're building on Windows with Cygwin or Mingw, just follow the Unix
|
||||||
# install instructions instead.
|
# install instructions instead.
|
||||||
|
|
||||||
mingw32:
|
mingw32:
|
||||||
$Q${MAKE} all test/gfx/randtilegen test/gfx/rgbgfx_test \
|
$Q${MAKE} CC=i686-w64-mingw32-gcc BISON=bison \
|
||||||
CXX=i686-w64-mingw32-g++ \
|
PKG_CONFIG=i686-w64-mingw32-pkg-config -j
|
||||||
CXXFLAGS="-O3 -flto -DNDEBUG -static-libgcc -static-libstdc++" \
|
|
||||||
PKG_CONFIG="PKG_CONFIG_SYSROOT_DIR=/usr/i686-w64-mingw32 pkg-config"
|
|
||||||
|
|
||||||
mingw64:
|
mingw64:
|
||||||
$Q${MAKE} all test/gfx/randtilegen test/gfx/rgbgfx_test \
|
$Q${MAKE} CC=x86_64-w64-mingw32-gcc BISON=bison \
|
||||||
CXX=x86_64-w64-mingw32-g++ \
|
PKG_CONFIG=x86_64-w64-mingw32-pkg-config -j
|
||||||
PKG_CONFIG="PKG_CONFIG_SYSROOT_DIR=/usr/x86_64-w64-mingw32 pkg-config"
|
|
||||||
|
|
||||||
wine-shim:
|
wine-shim:
|
||||||
$Qecho '#!/usr/bin/env bash' > rgbshim.sh
|
$Qecho '#!/bin/bash' > rgbshim.sh
|
||||||
$Qecho 'WINEDEBUG=-all wine $$0.exe "$${@:1}"' >> rgbshim.sh
|
$Qecho 'WINEDEBUG=-all wine $$0.exe "$${@:1}"' >> rgbshim.sh
|
||||||
$Qchmod +x rgbshim.sh
|
$Qchmod +x rgbshim.sh
|
||||||
$Qln -s rgbshim.sh rgbasm
|
$Qln -s rgbshim.sh rgbasm
|
||||||
@@ -286,4 +258,4 @@ wine-shim:
|
|||||||
|
|
||||||
dist:
|
dist:
|
||||||
$Qgit ls-files | sed s~^~$${PWD##*/}/~ \
|
$Qgit ls-files | sed s~^~$${PWD##*/}/~ \
|
||||||
| tar -czf rgbds-source.tar.gz -C .. -T -
|
| tar -czf rgbds-`git describe --tags | cut -c 2-`.tar.gz -C .. -T -
|
||||||
|
|||||||
57
README.md
57
README.md
@@ -1,57 +0,0 @@
|
|||||||
# RGBDS
|
|
||||||
|
|
||||||
RGBDS (Rednex Game Boy Development System) is a free assembler/linker package
|
|
||||||
for the Game Boy and Game Boy Color. It consists of:
|
|
||||||
|
|
||||||
- RGBASM (assembler)
|
|
||||||
- RGBLINK (linker)
|
|
||||||
- RGBFIX (checksum/header fixer)
|
|
||||||
- RGBGFX (PNG-to-Game Boy graphics converter)
|
|
||||||
|
|
||||||
This is a fork of the original RGBDS which aims to make the programs more like
|
|
||||||
other UNIX tools.
|
|
||||||
|
|
||||||
This toolchain is maintained [on GitHub](https://github.com/gbdev/rgbds).
|
|
||||||
|
|
||||||
The documentation of this toolchain can be [viewed online](https://rgbds.gbdev.io/docs/),
|
|
||||||
including its [basic usage and development history](https://rgbds.gbdev.io/docs/rgbds.7).
|
|
||||||
It is generated from the man pages found in this repository.
|
|
||||||
The source code of the website itself is on GitHub as well under the repository
|
|
||||||
[rgbds-www](https://github.com/gbdev/rgbds-www).
|
|
||||||
|
|
||||||
If you want to contribute or maintain RGBDS, read [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
||||||
If you have questions regarding the code, its organization, etc. you can find the maintainers
|
|
||||||
[on the GBDev community channels](https://gbdev.io/chat) or via mail at `rgbds at gbdev dot io`.
|
|
||||||
|
|
||||||
## Installing RGBDS
|
|
||||||
|
|
||||||
The [installation procedure](https://rgbds.gbdev.io/install) is available
|
|
||||||
online for various platforms. [Building from source](https://rgbds.gbdev.io/install/source)
|
|
||||||
is possible using `make` or `cmake`; follow the link for more detailed instructions.
|
|
||||||
|
|
||||||
```sh
|
|
||||||
make
|
|
||||||
sudo make install
|
|
||||||
```
|
|
||||||
|
|
||||||
```sh
|
|
||||||
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
|
||||||
cmake --build build
|
|
||||||
cmake --install build
|
|
||||||
```
|
|
||||||
|
|
||||||
Two parameters available when building are a prefix (e.g. to put the executables in a directory)
|
|
||||||
and a suffix (e.g. to append the version number or commit ID).
|
|
||||||
|
|
||||||
```sh
|
|
||||||
make
|
|
||||||
sudo make install PREFIX=install_dir/ SUFFIX=-$(git rev-parse --short HEAD)
|
|
||||||
```
|
|
||||||
|
|
||||||
```sh
|
|
||||||
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DSUFFIX=-$(git rev-parse --short HEAD)
|
|
||||||
cmake --build build
|
|
||||||
cmake --install build --prefix install_dir
|
|
||||||
```
|
|
||||||
|
|
||||||
(If you set a `SUFFIX`, it should include the `.exe` extension on Windows.)
|
|
||||||
128
README.rst
Normal file
128
README.rst
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
RGBDS
|
||||||
|
=====
|
||||||
|
|
||||||
|
RGBDS (Rednex Game Boy Development System) is a free assembler/linker package
|
||||||
|
for the Game Boy and Game Boy Color. It consists of:
|
||||||
|
|
||||||
|
- rgbasm (assembler)
|
||||||
|
- rgblink (linker)
|
||||||
|
- rgbfix (checksum/header fixer)
|
||||||
|
- rgbgfx (PNG‐to‐Game Boy graphics converter)
|
||||||
|
|
||||||
|
This is a fork of the original RGBDS which aims to make the programs more like
|
||||||
|
other UNIX tools.
|
||||||
|
|
||||||
|
This toolchain is maintained on `GitHub <https://github.com/rednex/rgbds>`__.
|
||||||
|
|
||||||
|
The documentation of this toolchain can be viewed online
|
||||||
|
`here <https://rgbds.gbdev.io/docs/>`__, it is generated from the man pages
|
||||||
|
found in this repository.
|
||||||
|
|
||||||
|
If you want to contribute or maintain RGBDS, and have questions regarding the code, its organisation, etc. you can find me `on GBDev <https://gbdev.io/chat>`__ or via mail at ``rgbds at eldred dot fr``.
|
||||||
|
|
||||||
|
1. Installing RGBDS
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
The `installation procedure <https://rgbds.gbdev.io/install>`__ is available
|
||||||
|
online for various platforms. `Building from source <https://rgbds.gbdev.io/install/source>`__
|
||||||
|
is possible using ``make`` or ``cmake``; follow the link for more detailed instructions.
|
||||||
|
|
||||||
|
.. code:: sh
|
||||||
|
|
||||||
|
make
|
||||||
|
sudo make install
|
||||||
|
|
||||||
|
.. code:: sh
|
||||||
|
|
||||||
|
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
||||||
|
cmake --build build
|
||||||
|
cmake --install build
|
||||||
|
|
||||||
|
2. RGBDS Folder Organization
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
The RGBDS source code file structure somewhat resembles the following:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
.
|
||||||
|
├── .github/
|
||||||
|
│ ├── actions/
|
||||||
|
│ │ └── ...
|
||||||
|
│ └── workflows/
|
||||||
|
│ └── ...
|
||||||
|
├── contrib/
|
||||||
|
│ ├── zsh_compl/
|
||||||
|
│ │ └── ...
|
||||||
|
│ └── ...
|
||||||
|
├── include/
|
||||||
|
│ └── ...
|
||||||
|
├── src/
|
||||||
|
│ ├── asm/
|
||||||
|
│ │ └── ...
|
||||||
|
│ ├── extern/
|
||||||
|
│ │ └── ...
|
||||||
|
│ ├── fix/
|
||||||
|
│ │ └── ...
|
||||||
|
│ ├── gfx/
|
||||||
|
│ │ └── ...
|
||||||
|
│ ├── link/
|
||||||
|
│ │ └── ...
|
||||||
|
│ ├── CMakeLists.txt
|
||||||
|
│ └── ...
|
||||||
|
├── test/
|
||||||
|
│ ├── ...
|
||||||
|
│ └── run-tests.sh
|
||||||
|
├── .clang-format
|
||||||
|
├── CMakeLists.txt
|
||||||
|
├── Makefile
|
||||||
|
└── README.rst
|
||||||
|
|
||||||
|
.. |clang-format| replace:: ``clang-format``
|
||||||
|
.. _clang-format: https://clang.llvm.org/docs/ClangFormat.html
|
||||||
|
|
||||||
|
- ``.github/`` - files and scripts related to the integration of the RGBDS codebase with
|
||||||
|
GitHub.
|
||||||
|
|
||||||
|
* ``actions/`` - scripts used by workflow files.
|
||||||
|
* ``workflows/`` - CI workflow description files.
|
||||||
|
|
||||||
|
- ``contrib/`` - scripts and other resources which may be useful to users and developers of
|
||||||
|
RGBDS.
|
||||||
|
|
||||||
|
* ``zsh_compl`` contains tab completion scripts for use with zsh. Put them somewhere in your ``fpath``, and they should auto-load.
|
||||||
|
|
||||||
|
* ``bash_compl`` contains tab completion scripts for use with bash. Run them with ``source`` somewhere in your ``.bashrc``, and they should load every time you open a shell.
|
||||||
|
|
||||||
|
- ``include/`` - header files for each respective C files in `src`.
|
||||||
|
|
||||||
|
- ``src/`` - source code and manual pages for RGBDS.
|
||||||
|
|
||||||
|
* Note that the code unique to each RGBDS tool is stored in its respective subdirectory
|
||||||
|
(rgbasm -> ``src/asm/``, for example). ``src/extern/`` contains code imported from external sources.
|
||||||
|
|
||||||
|
- ``test/`` - testing framework used to verify that changes to the code don't break or modify the behavior of RGBDS.
|
||||||
|
|
||||||
|
- ``.clang-format`` - code style for automated formatting with |clang-format|_. The C code does not currently follow this style, but all C++ code should.
|
||||||
|
|
||||||
|
3. History
|
||||||
|
----------
|
||||||
|
|
||||||
|
- Around 1997, Carsten Sørensen (AKA SurfSmurf) writes ASMotor as a
|
||||||
|
general-purpose assembler/linker system for DOS/Win32
|
||||||
|
|
||||||
|
- Around 1999, Justin Lloyd (AKA Otaku no Zoku) adapts ASMotor to read and
|
||||||
|
produce GBZ80 assembly/machine code, and releases this version as RGBDS.
|
||||||
|
|
||||||
|
- 2009, Vegard Nossum adapts the code to be more UNIX-like and releases
|
||||||
|
this version as rgbds-linux on
|
||||||
|
`GitHub <https://github.com/vegard/rgbds-linux>`__.
|
||||||
|
|
||||||
|
- 2010, Anthony J. Bentley forks that repository. The fork becomes the reference
|
||||||
|
implementation of rgbds.
|
||||||
|
|
||||||
|
- 2017, Bentley's repository is moved to a neutral name.
|
||||||
|
|
||||||
|
- 2018, codebase relicensed under the MIT license.
|
||||||
|
|
||||||
|
- 2020, repository is moved to the `gbdev <https://github.com/gbdev>`__ organisation. The `rgbds.gbdev.io <https://rgbds.gbdev.io>`__ website serving documentation and downloads is created.
|
||||||
83
RELEASE.md
83
RELEASE.md
@@ -1,83 +0,0 @@
|
|||||||
# Releasing
|
|
||||||
|
|
||||||
This describes for the maintainers of RGBDS how to publish a new release on
|
|
||||||
GitHub.
|
|
||||||
|
|
||||||
1. Update the following files, then commit and push.
|
|
||||||
You can use <code>git commit -m "Release <i><version></i>"</code> and `git push origin master`.
|
|
||||||
|
|
||||||
- [include/version.hpp](include/version.hpp): set appropriate values for `PACKAGE_VERSION_MAJOR`,
|
|
||||||
`PACKAGE_VERSION_MINOR`, `PACKAGE_VERSION_PATCH`, and `PACKAGE_VERSION_RC`.
|
|
||||||
**Only** define `PACKAGE_VERSION_RC` if you are publishing a release candidate!
|
|
||||||
- [Dockerfile](Dockerfile): update `ARG version`.
|
|
||||||
- [test/fetch-test-deps.sh](test/fetch-test-deps.sh): update test dependency commits
|
|
||||||
(preferably, use the latest available).
|
|
||||||
- [man/\*](man/): update dates and authors.
|
|
||||||
|
|
||||||
2. Create a Git tag formatted as <code>v<i><MAJOR></i>.<i><MINOR></i>.<i><PATCH></i></code>,
|
|
||||||
or <code>v<i><MAJOR></i>.<i><MINOR></i>.<i><PATCH></i>-rc<i><RC></i></code>
|
|
||||||
for a release candidate. <code><i>MAJOR</i></code>, <code><i>MINOR</i></code>,
|
|
||||||
<code><i>PATCH</i></code>, and <code><i>RC</i></code> should match their values from
|
|
||||||
[include/version.hpp](include/version.hpp). You can use <code>git tag <i><tag></i></code>.
|
|
||||||
|
|
||||||
3. Push the tag to GitHub. You can use <code>git push origin <i><tag></i></code>.
|
|
||||||
|
|
||||||
GitHub Actions will run the [create-release-artifacts.yaml](.github/workflows/create-release-artifacts.yaml)
|
|
||||||
workflow to detect the tag starting with "`v[0-9]`" and automatically do the following:
|
|
||||||
|
|
||||||
1. Build 32-bit and 64-bit RGBDS binaries for Windows with `cmake`.
|
|
||||||
|
|
||||||
2. Package the binaries into zip files.
|
|
||||||
|
|
||||||
3. Package the source code into a tar.gz file with `make dist`.
|
|
||||||
|
|
||||||
4. Create a draft GitHub release for the tag, attaching the three
|
|
||||||
packaged files. It will be a prerelease if the tag contains "`-rc`".
|
|
||||||
|
|
||||||
If an error occurred in the above steps, delete the tag and restart the
|
|
||||||
procedure. You can use <code>git push --delete origin <i><tag></i></code> and
|
|
||||||
<code>git tag --delete <i><tag></i></code>.
|
|
||||||
|
|
||||||
4. GitHub Actions will run the [create-release-docs.yml](.github/workflows/create-release-docs.yml)
|
|
||||||
workflow to add the release documentation to [rgbds-www](https://github.com/gbdev/rgbds-www).
|
|
||||||
|
|
||||||
This is not done automatically for prereleases, since we do not normally publish documentation
|
|
||||||
for them. If you want to manually publish prerelease documentation, such as for an April Fools
|
|
||||||
joke prerelease,
|
|
||||||
|
|
||||||
1. Clone [rgbds-www](https://github.com/gbdev/rgbds-www). You can use
|
|
||||||
`git clone https://github.com/gbdev/rgbds-www.git`.
|
|
||||||
|
|
||||||
2. Make sure that you have installed `groff` and `mandoc`. You will
|
|
||||||
need `mandoc` 1.14.5 or later to support `-O toc`.
|
|
||||||
|
|
||||||
3. Inside of the `man` directory, run <code><i><path/to/rgbds-www></i>/maintainer/man_to_html.sh <i><tag></i> *</code> then <code><i><path/to/rgbds-www></i>/maintainer/new_release.sh <i><tag></i></code>.
|
|
||||||
This will render the RGBDS documentation as HTML and PDF and copy it to
|
|
||||||
`rgbds-www`.
|
|
||||||
|
|
||||||
If you do not have `groff` installed, you can change
|
|
||||||
`groff -Tpdf -mdoc -wall` to `mandoc -Tpdf -I os=Linux` in
|
|
||||||
[maintainer/man_to_html.sh](https://github.com/gbdev/rgbds-www/blob/master/maintainer/man_to_html.sh)
|
|
||||||
and it will suffice.
|
|
||||||
|
|
||||||
4. Commit and push the documentation. You can use <code>git commit -m
|
|
||||||
"Create RGBDS <i><tag></i> documentation"</code> and `git push origin master`
|
|
||||||
(within the `rgbds-www` directory, not RGBDS).
|
|
||||||
|
|
||||||
5. Write a changelog in the GitHub draft release.
|
|
||||||
|
|
||||||
6. Click the "Publish release" button to publish it!
|
|
||||||
|
|
||||||
7. Update the `release` branch. You can use `git push origin master:release`.
|
|
||||||
|
|
||||||
8. Update the following related projects.
|
|
||||||
|
|
||||||
1. [rgbds-www](https://github.com/gbdev/rgbds-www): update
|
|
||||||
[src/pages/versions.mdx](https://github.com/gbdev/rgbds-www/blob/master/src/pages/versions.mdx)
|
|
||||||
to list the new release.
|
|
||||||
2. [rgbds-live](https://github.com/gbdev/rgbds-live): update the `rgbds` submodule (and
|
|
||||||
[patches/rgbds.patch](https://github.com/gbdev/rgbds-live/blob/master/patches/rgbds.patch)
|
|
||||||
if necessary) to use the new release.
|
|
||||||
3. [rgbobj](https://github.com/gbdev/rgbobj) and [rgbds-obj](https://github.com/gbdev/rgbds-obj):
|
|
||||||
make sure that object files created by the latest RGBASM can be parsed and displayed.
|
|
||||||
If the object file revision has been updated, `rgbobj` will need a corresponding release.
|
|
||||||
67
RELEASE.rst
Normal file
67
RELEASE.rst
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
Releasing
|
||||||
|
=========
|
||||||
|
|
||||||
|
This describes for the maintainers of RGBDS how to publish a new release on
|
||||||
|
GitHub.
|
||||||
|
|
||||||
|
1. Update, commit, and push `include/version.h <include/version.h>`__ with
|
||||||
|
values for ``PACKAGE_VERSION_MAJOR``, ``PACKAGE_VERSION_MINOR``,
|
||||||
|
``PACKAGE_VERSION_PATCH``, and ``PACKAGE_VERSION_RC``. Only define
|
||||||
|
``PACKAGE_VERSION_RC`` if you are publishing a release candidate! You can
|
||||||
|
use ``git commit -m "Release <version>"`` and ``git push origin master``.
|
||||||
|
|
||||||
|
2. Create a Git tag formatted as ``v<MAJOR>.<MINOR>.<PATCH>``, or
|
||||||
|
``v<MAJOR>.<MINOR>.<PATCH>-rc<RC>`` for a release candidate. ``MAJOR``,
|
||||||
|
``MINOR``, ``PATCH``, and ``RC`` should match their values from
|
||||||
|
`include/version.h <include/version.h>`__. You can use ``git tag <tag>``.
|
||||||
|
|
||||||
|
3. Push the tag to GitHub. You can use ``git push origin <tag>``.
|
||||||
|
|
||||||
|
GitHub Actions will run the `create-release-artifacts.yaml
|
||||||
|
<.github/workflows/create-release-artifacts.yaml>`__ workflow to detect the
|
||||||
|
tag starting with "``v[0-9]``" and automatically do the following:
|
||||||
|
|
||||||
|
1. Build 32-bit and 64-bit RGBDS binaries for Windows with ``cmake``.
|
||||||
|
|
||||||
|
2. Package the binaries into zip files.
|
||||||
|
|
||||||
|
3. Package the source code into a tar.gz file with ``make dist``.
|
||||||
|
|
||||||
|
4. Create a draft GitHub release for the tag, attaching the three
|
||||||
|
packaged files. It will be a prerelease if the tag contains "``-rc``".
|
||||||
|
|
||||||
|
If an error occurred in the above steps, delete the tag and restart the
|
||||||
|
procedure. You can use ``git push --delete origin <tag>`` and
|
||||||
|
``git tag --delete <tag>``.
|
||||||
|
|
||||||
|
4. GitHub Actions will run the `create-release-docs.yml
|
||||||
|
<.github/workflows/create-release-docs.yml>`__ workflow to add the release
|
||||||
|
documentation to `rgbds-www <https://github.com/gbdev/rgbds-www>`__.
|
||||||
|
|
||||||
|
For a release candidate, which creates a prerelease, you will have to
|
||||||
|
take these steps yourself.
|
||||||
|
|
||||||
|
1. Clone `rgbds-www <https://github.com/gbdev/rgbds-www>`__. You can use
|
||||||
|
``git clone https://github.com/gbdev/rgbds-www.git``.
|
||||||
|
|
||||||
|
2. Make sure that you have installed ``groff`` and ``mandoc``. You will
|
||||||
|
need ``mandoc`` 1.14.5 or later to support ``-O toc``.
|
||||||
|
|
||||||
|
3. Run ``.github/actions/get-pages.sh -r <path/to/rgbds-www> <tag>``. This
|
||||||
|
will render the RGBDS documentation as HTML and PDF and copy it to
|
||||||
|
``rgbds-www``.
|
||||||
|
|
||||||
|
If you do not have ``groff`` installed, you can change
|
||||||
|
``groff -Tpdf -mdoc -wall`` to ``mandoc -Tpdf -I os=Linux`` in
|
||||||
|
`.github/actions/get-pages.sh <.github/actions/get-pages.sh>`__ and it
|
||||||
|
will suffice.
|
||||||
|
|
||||||
|
4. Commit and push the documentation. You can use ``git commit -m
|
||||||
|
"Create RGBDS <tag> documentation"`` and ``git push origin master``
|
||||||
|
(within the ``rgbds-www`` directory, not RGBDS).
|
||||||
|
|
||||||
|
5. Write a changelog in the GitHub draft release.
|
||||||
|
|
||||||
|
6. Click the "Publish release" button to publish it!
|
||||||
|
|
||||||
|
7. Update the `release` branch. You can use ``git push origin release``.
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
-std=c++2a
|
|
||||||
-I
|
|
||||||
include
|
|
||||||
-fno-exceptions
|
|
||||||
-fno-rtti
|
|
||||||
-fno-caret-diagnostics
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/env bash
|
#/usr/bin/env bash
|
||||||
|
|
||||||
# Known bugs:
|
# Known bugs:
|
||||||
# - Newlines in file/directory names break this script
|
# - Newlines in file/directory names break this script
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
# - Directories are not completed as such in "coalesced" short-opt arguments. For example,
|
# - Directories are not completed as such in "coalesced" short-opt arguments. For example,
|
||||||
# `rgbasm -M d<tab>` can autocomplete to `rgbasm -M dir/` (no space), but
|
# `rgbasm -M d<tab>` can autocomplete to `rgbasm -M dir/` (no space), but
|
||||||
# `rgbasm -Md<tab>` would autocomplete to `rgbasm -Mdir ` (trailing space) instead.
|
# `rgbasm -Md<tab>` would autocomplete to `rgbasm -Mdir ` (trailing space) instead.
|
||||||
# This is because directory handling is performed by Readline, whom we can't tell about the short
|
# This is because dircetory handling is performed by Readline, whom we can't tell about the short
|
||||||
# opt kerfuffle. The user can work around by separating the argument, as shown above.
|
# opt kerfuffle. The user can work around by separating the argument, as shown above.
|
||||||
# (Also, there might be more possible bugs if `-Mdir` is actually a directory. Ugh.)
|
# (Also, there might be more possible bugs if `-Mdir` is actually a directory. Ugh.)
|
||||||
|
|
||||||
@@ -20,29 +20,27 @@
|
|||||||
# Thus, we don't need to do much to handle that form of argument passing: skip '=' after long opts.
|
# Thus, we don't need to do much to handle that form of argument passing: skip '=' after long opts.
|
||||||
|
|
||||||
_rgbasm_completions() {
|
_rgbasm_completions() {
|
||||||
|
COMPREPLY=()
|
||||||
|
|
||||||
# Format: "long_opt:state_after"
|
# Format: "long_opt:state_after"
|
||||||
# Empty long opt = it doesn't exit
|
# Empty long opt = it doesn't exit
|
||||||
# See the `state` variable below for info about `state_after`
|
# See the `state` variable below for info about `state_after`
|
||||||
declare -A opts=(
|
declare -A opts=(
|
||||||
[h]="help:normal"
|
|
||||||
[V]="version:normal"
|
[V]="version:normal"
|
||||||
[W]="warning:warning"
|
[E]="export-all:normal"
|
||||||
|
[h]="halt-without-nop:normal"
|
||||||
|
[L]="preserve-ld:normal"
|
||||||
|
[v]="verbose:normal"
|
||||||
[w]=":normal"
|
[w]=":normal"
|
||||||
[B]="backtrace:unk"
|
|
||||||
[b]="binary-digits:unk"
|
[b]="binary-digits:unk"
|
||||||
[D]="define:unk"
|
[D]="define:unk"
|
||||||
[E]="export-all:normal"
|
|
||||||
[g]="gfx-chars:unk"
|
[g]="gfx-chars:unk"
|
||||||
[I]="include:dir"
|
[i]="include:dir"
|
||||||
[M]="dependfile:glob-*.mk *.d"
|
[M]="dependfile:glob-*.mk *.d"
|
||||||
[o]="output:glob-*.o"
|
[o]="output:glob-*.o"
|
||||||
[P]="preinclude:glob-*.asm *.inc"
|
|
||||||
[p]="pad-value:unk"
|
[p]="pad-value:unk"
|
||||||
[Q]="q-precision:unk"
|
|
||||||
[r]="recursion-depth:unk"
|
[r]="recursion-depth:unk"
|
||||||
[s]="state:unk"
|
[W]="warning:warning"
|
||||||
[v]="verbose:normal"
|
|
||||||
[X]="max-errors:unk"
|
|
||||||
)
|
)
|
||||||
# Parse command-line up to current word
|
# Parse command-line up to current word
|
||||||
local opt_ena=true
|
local opt_ena=true
|
||||||
@@ -60,18 +58,6 @@ _rgbasm_completions() {
|
|||||||
# "normal" is not returned, `optlen` will be set to the length (dash included) of the "option"
|
# "normal" is not returned, `optlen` will be set to the length (dash included) of the "option"
|
||||||
# part of the argument.
|
# part of the argument.
|
||||||
parse_short_opt() {
|
parse_short_opt() {
|
||||||
# These options act like a long option (= takes up the entire word), but only use a single dash
|
|
||||||
# So, they need some special handling
|
|
||||||
if [[ "$1" = "-M"[CGP] ]]; then
|
|
||||||
state=normal
|
|
||||||
optlen=${#1}
|
|
||||||
return;
|
|
||||||
elif [[ "$1" = "-M"[QT] ]]; then
|
|
||||||
state='glob-*.d *.mk *.o'
|
|
||||||
optlen=${#1}
|
|
||||||
return;
|
|
||||||
fi
|
|
||||||
|
|
||||||
for (( i = 1; i < "${#1}"; i++ )); do
|
for (( i = 1; i < "${#1}"; i++ )); do
|
||||||
# If the option is not known, assume it doesn't take an argument
|
# If the option is not known, assume it doesn't take an argument
|
||||||
local opt="${opts["${1:$i:1}"]:-":normal"}"
|
local opt="${opts["${1:$i:1}"]:-":normal"}"
|
||||||
@@ -85,7 +71,7 @@ _rgbasm_completions() {
|
|||||||
optlen=0
|
optlen=0
|
||||||
}
|
}
|
||||||
|
|
||||||
for (( i = 1; i < COMP_CWORD; i++ )); do
|
for (( i = 1; i < $COMP_CWORD; i++ )); do
|
||||||
local word="${COMP_WORDS[$i]}"
|
local word="${COMP_WORDS[$i]}"
|
||||||
|
|
||||||
# If currently processing an argument, skip this word
|
# If currently processing an argument, skip this word
|
||||||
@@ -101,7 +87,7 @@ _rgbasm_completions() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Check if it's a long option
|
# Check if it's a long option
|
||||||
if [[ "$word" = '--'* ]]; then
|
if [[ "${word:0:2}" = '--' ]]; then
|
||||||
# If the option is unknown, assume it takes no arguments: keep the state at "normal"
|
# If the option is unknown, assume it takes no arguments: keep the state at "normal"
|
||||||
for long_opt in "${opts[@]}"; do
|
for long_opt in "${opts[@]}"; do
|
||||||
if [[ "$word" = "--${long_opt%%:*}" ]]; then
|
if [[ "$word" = "--${long_opt%%:*}" ]]; then
|
||||||
@@ -117,7 +103,15 @@ _rgbasm_completions() {
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
# Check if it's a short option
|
# Check if it's a short option
|
||||||
elif [[ "$word" = '-'* ]]; then
|
elif [[ "${word:0:1}" = '-' ]]; then
|
||||||
|
# The `-M?` ones are a mix of short and long, augh
|
||||||
|
# They must match the *full* word, but only take a single dash
|
||||||
|
# So, handle them here
|
||||||
|
if [[ "$1" = "-M"[GP] ]]; then
|
||||||
|
state=normal
|
||||||
|
elif [[ "$1" = "-M"[TQ] ]]; then
|
||||||
|
state='glob-*.d *.mk *.o'
|
||||||
|
else
|
||||||
parse_short_opt "$word"
|
parse_short_opt "$word"
|
||||||
# The last option takes an argument...
|
# The last option takes an argument...
|
||||||
if [[ "$state" != 'normal' ]]; then
|
if [[ "$state" != 'normal' ]]; then
|
||||||
@@ -130,33 +124,34 @@ _rgbasm_completions() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# Parse current word
|
# Parse current word
|
||||||
# Careful that it might look like an option, so use `--` aggressively!
|
# Careful that it might look like an option, so use `--` aggressively!
|
||||||
local cur_word="${COMP_WORDS[$i]}"
|
local cur_word="${COMP_WORDS[$COMP_CWORD]}"
|
||||||
|
|
||||||
# Process options, as short ones may change the state
|
# Process options, as short ones may change the state
|
||||||
if $opt_ena && [[ "$state" = 'normal' && "$cur_word" = '-'* ]]; then
|
if $opt_ena && [[ "$state" = 'normal' && "${cur_word:0:1}" = '-' ]]; then
|
||||||
# We might want to complete to an option or an arg to that option
|
# We might want to complete to an option or an arg to that option
|
||||||
# Parse the option word to check
|
# Parse the option word to check
|
||||||
# There's no whitespace in the option names, so we can ride a little dirty...
|
# There's no whitespace in the option names, so we can ride a little dirty...
|
||||||
|
|
||||||
# Is this a long option?
|
# Is this a long option?
|
||||||
if [[ "$cur_word" = '--'* ]]; then
|
if [[ "${cur_word:1:1}" = '-' ]]; then
|
||||||
# It is, try to complete one
|
# It is, try to complete one
|
||||||
mapfile -t COMPREPLY < <(compgen -W "${opts[*]%%:*}" -P '--' -- "${cur_word#--}")
|
COMPREPLY+=( $(compgen -W "${opts[*]%%:*}" -P '--' -- "${cur_word#--}") )
|
||||||
return 0
|
|
||||||
elif [[ "$cur_word" = '-M'[CGPQT] ]]; then
|
|
||||||
# These options act like long opts with no arguments, so return them and exactly them
|
|
||||||
COMPREPLY=( "$cur_word" )
|
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
# Short options may be grouped, parse them to determine what to complete
|
# Short options may be grouped, parse them to determine what to complete
|
||||||
|
# The `-M?` ones may not be followed by anything
|
||||||
|
if [[ "$1" != "-M"[GPTQ] ]]; then
|
||||||
parse_short_opt "$cur_word"
|
parse_short_opt "$cur_word"
|
||||||
|
# We got some short options that behave like long ones
|
||||||
|
COMPREPLY+=( $(compgen -W '-MG -MP -MT -MQ' -- "$cur_word") )
|
||||||
|
|
||||||
if [[ "$state" = 'normal' ]]; then
|
if [[ "$state" = 'normal' ]]; then
|
||||||
mapfile -t COMPREPLY < <(compgen -W "${!opts[*]}" -P "$cur_word" ''; compgen -W '-MC -MG -MP -MQ -MT' "$cur_word")
|
COMPREPLY+=( $(compgen -W "${!opts[*]}" -P "$cur_word" '') )
|
||||||
return 0
|
return 0
|
||||||
elif [[ "$optlen" = "${#cur_word}" && "$state" != "warning" ]]; then
|
elif [[ "$optlen" = "${#cur_word}" && "$state" != "warning" ]]; then
|
||||||
# This short option group only awaits its argument!
|
# This short option group only awaits its argument!
|
||||||
@@ -164,18 +159,18 @@ _rgbasm_completions() {
|
|||||||
# so that the next completion request switches to the argument
|
# so that the next completion request switches to the argument
|
||||||
# An exception is made for warnings, since it's idiomatic to stick them to the
|
# An exception is made for warnings, since it's idiomatic to stick them to the
|
||||||
# `-W`, and it doesn't break anything.
|
# `-W`, and it doesn't break anything.
|
||||||
COMPREPLY=( "$cur_word" )
|
COMPREPLY+=( "$cur_word" )
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
COMPREPLY=()
|
|
||||||
case "$state" in
|
case "$state" in
|
||||||
unk) # Return with no replies: no idea what to complete!
|
unk) # Return with no replies: no idea what to complete!
|
||||||
;;
|
;;
|
||||||
warning)
|
warning)
|
||||||
mapfile -t COMPREPLY < <(compgen -W "
|
COMPREPLY+=( $(compgen -W "
|
||||||
assert
|
assert
|
||||||
backwards-for
|
backwards-for
|
||||||
builtin-args
|
builtin-args
|
||||||
@@ -184,24 +179,20 @@ _rgbasm_completions() {
|
|||||||
empty-data-directive
|
empty-data-directive
|
||||||
empty-macro-arg
|
empty-macro-arg
|
||||||
empty-strrpl
|
empty-strrpl
|
||||||
export-undefined
|
|
||||||
large-constant
|
large-constant
|
||||||
|
long-string
|
||||||
macro-shift
|
macro-shift
|
||||||
nested-comment
|
nested-comment
|
||||||
numeric-string
|
numeric-string
|
||||||
obsolete
|
obsolete
|
||||||
purge
|
|
||||||
shift
|
shift
|
||||||
shift-amount
|
shift-amount
|
||||||
truncation
|
truncation
|
||||||
unmapped-char
|
|
||||||
unmatched-directive
|
|
||||||
unterminated-load
|
|
||||||
user
|
user
|
||||||
all
|
all
|
||||||
extra
|
extra
|
||||||
everything
|
everything
|
||||||
error" -P "${cur_word:0:$optlen}" -- "${cur_word:$optlen}")
|
error" -P "${cur_word:0:$optlen}" -- "${cur_word:$optlen}") )
|
||||||
;;
|
;;
|
||||||
normal) # Acts like a glob...
|
normal) # Acts like a glob...
|
||||||
state="glob-*.asm *.inc *.sm83"
|
state="glob-*.asm *.inc *.sm83"
|
||||||
@@ -218,10 +209,6 @@ _rgbasm_completions() {
|
|||||||
done < <(compgen -A directory -- "${cur_word:$optlen}")
|
done < <(compgen -A directory -- "${cur_word:$optlen}")
|
||||||
compopt -o filenames
|
compopt -o filenames
|
||||||
;;
|
;;
|
||||||
*)
|
|
||||||
echo >&2 "Internal completion error: invalid state \"$state\", please report this bug"
|
|
||||||
return 1
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,32 +1,29 @@
|
|||||||
#!/usr/bin/env bash
|
#/usr/bin/env bash
|
||||||
|
|
||||||
# Same notes as RGBASM
|
# Same notes as RGBASM
|
||||||
|
|
||||||
_rgbfix_completions() {
|
_rgbfix_completions() {
|
||||||
|
COMPREPLY=()
|
||||||
|
|
||||||
# Format: "long_opt:state_after"
|
# Format: "long_opt:state_after"
|
||||||
# Empty long opt = it doesn't exit
|
# Empty long opt = it doesn't exit
|
||||||
# See the `state` variable below for info about `state_after`
|
# See the `state` variable below for info about `state_after`
|
||||||
declare -A opts=(
|
declare -A opts=(
|
||||||
[h]="help:normal"
|
|
||||||
[V]="version:normal"
|
[V]="version:normal"
|
||||||
[W]="warning:warning"
|
[j]="non-japanese:normal"
|
||||||
[w]=":normal"
|
[s]="sgb-compatible:normal"
|
||||||
|
[v]="validate:normal"
|
||||||
[C]="color-only:normal"
|
[C]="color-only:normal"
|
||||||
[c]="color-compatible:normal"
|
[c]="color-compatible:normal"
|
||||||
[f]="fix-spec:fix-spec"
|
[f]="fix-spec:fix-spec"
|
||||||
[i]="game-id:unk"
|
[i]="game-id:unk"
|
||||||
[j]="non-japanese:normal"
|
|
||||||
[k]="new-licensee:unk"
|
[k]="new-licensee:unk"
|
||||||
[L]="custom-logo:glob-*.1bpp"
|
|
||||||
[l]="old-licensee:unk"
|
[l]="old-licensee:unk"
|
||||||
[m]="mbc-type:mbc"
|
[m]="mbc-type:mbc"
|
||||||
[n]="rom-version:unk"
|
[n]="rom-version:unk"
|
||||||
[o]="output:glob-*.gb *.gbc *.sgb"
|
|
||||||
[p]="pad-value:unk"
|
[p]="pad-value:unk"
|
||||||
[r]="ram-size:unk"
|
[r]="ram-size:unk"
|
||||||
[s]="sgb-compatible:normal"
|
|
||||||
[t]="title:unk"
|
[t]="title:unk"
|
||||||
[v]="validate:normal"
|
|
||||||
)
|
)
|
||||||
# Parse command-line up to current word
|
# Parse command-line up to current word
|
||||||
local opt_ena=true
|
local opt_ena=true
|
||||||
@@ -57,7 +54,7 @@ _rgbfix_completions() {
|
|||||||
optlen=0
|
optlen=0
|
||||||
}
|
}
|
||||||
|
|
||||||
for (( i = 1; i < COMP_CWORD; i++ )); do
|
for (( i = 1; i < $COMP_CWORD; i++ )); do
|
||||||
local word="${COMP_WORDS[$i]}"
|
local word="${COMP_WORDS[$i]}"
|
||||||
|
|
||||||
# If currently processing an argument, skip this word
|
# If currently processing an argument, skip this word
|
||||||
@@ -73,7 +70,7 @@ _rgbfix_completions() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Check if it's a long option
|
# Check if it's a long option
|
||||||
if [[ "$word" = '--'* ]]; then
|
if [[ "${word:0:2}" = '--' ]]; then
|
||||||
# If the option is unknown, assume it takes no arguments: keep the state at "normal"
|
# If the option is unknown, assume it takes no arguments: keep the state at "normal"
|
||||||
for long_opt in "${opts[@]}"; do
|
for long_opt in "${opts[@]}"; do
|
||||||
if [[ "$word" = "--${long_opt%%:*}" ]]; then
|
if [[ "$word" = "--${long_opt%%:*}" ]]; then
|
||||||
@@ -89,7 +86,7 @@ _rgbfix_completions() {
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
# Check if it's a short option
|
# Check if it's a short option
|
||||||
elif [[ "$word" = '-'* ]]; then
|
elif [[ "${word:0:1}" = '-' ]]; then
|
||||||
parse_short_opt "$word"
|
parse_short_opt "$word"
|
||||||
# The last option takes an argument...
|
# The last option takes an argument...
|
||||||
if [[ "$state" != 'normal' ]]; then
|
if [[ "$state" != 'normal' ]]; then
|
||||||
@@ -106,25 +103,25 @@ _rgbfix_completions() {
|
|||||||
|
|
||||||
# Parse current word
|
# Parse current word
|
||||||
# Careful that it might look like an option, so use `--` aggressively!
|
# Careful that it might look like an option, so use `--` aggressively!
|
||||||
local cur_word="${COMP_WORDS[$i]}"
|
local cur_word="${COMP_WORDS[$COMP_CWORD]}"
|
||||||
|
|
||||||
# Process options, as short ones may change the state
|
# Process options, as short ones may change the state
|
||||||
if $opt_ena && [[ "$state" = 'normal' && "$cur_word" = '-'* ]]; then
|
if $opt_ena && [[ "$state" = 'normal' && "${cur_word:0:1}" = '-' ]]; then
|
||||||
# We might want to complete to an option or an arg to that option
|
# We might want to complete to an option or an arg to that option
|
||||||
# Parse the option word to check
|
# Parse the option word to check
|
||||||
# There's no whitespace in the option names, so we can ride a little dirty...
|
# There's no whitespace in the option names, so we can ride a little dirty...
|
||||||
|
|
||||||
# Is this a long option?
|
# Is this a long option?
|
||||||
if [[ "$cur_word" = '--'* ]]; then
|
if [[ "${cur_word:1:1}" = '-' ]]; then
|
||||||
# It is, try to complete one
|
# It is, try to complete one
|
||||||
mapfile -t COMPREPLY < <(compgen -W "${opts[*]%%:*}" -P '--' -- "${cur_word#--}")
|
COMPREPLY+=( $(compgen -W "${opts[*]%%:*}" -P '--' -- "${cur_word#--}") )
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
# Short options may be grouped, parse them to determine what to complete
|
# Short options may be grouped, parse them to determine what to complete
|
||||||
parse_short_opt "$cur_word"
|
parse_short_opt "$cur_word"
|
||||||
|
|
||||||
if [[ "$state" = 'normal' ]]; then
|
if [[ "$state" = 'normal' ]]; then
|
||||||
mapfile -t COMPREPLY < <(compgen -W "${!opts[*]}" -P "$cur_word" '')
|
COMPREPLY+=( $(compgen -W "${!opts[*]}" -P "$cur_word" '') )
|
||||||
return 0
|
return 0
|
||||||
elif [[ "$optlen" = "${#cur_word}" && "$state" != "warning" ]]; then
|
elif [[ "$optlen" = "${#cur_word}" && "$state" != "warning" ]]; then
|
||||||
# This short option group only awaits its argument!
|
# This short option group only awaits its argument!
|
||||||
@@ -132,36 +129,22 @@ _rgbfix_completions() {
|
|||||||
# so that the next completion request switches to the argument
|
# so that the next completion request switches to the argument
|
||||||
# An exception is made for warnings, since it's idiomatic to stick them to the
|
# An exception is made for warnings, since it's idiomatic to stick them to the
|
||||||
# `-W`, and it doesn't break anything.
|
# `-W`, and it doesn't break anything.
|
||||||
COMPREPLY=( "$cur_word" )
|
COMPREPLY+=( "$cur_word" )
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
COMPREPLY=()
|
|
||||||
case "$state" in
|
case "$state" in
|
||||||
unk) # Return with no replies: no idea what to complete!
|
unk) # Return with no replies: no idea what to complete!
|
||||||
;;
|
;;
|
||||||
warning)
|
|
||||||
mapfile -t COMPREPLY < <(compgen -W "
|
|
||||||
mbc
|
|
||||||
obsolete
|
|
||||||
overwrite
|
|
||||||
sgb
|
|
||||||
truncation
|
|
||||||
all
|
|
||||||
everything
|
|
||||||
error" -P "${cur_word:0:$optlen}" -- "${cur_word:$optlen}")
|
|
||||||
;;
|
|
||||||
fix-spec)
|
fix-spec)
|
||||||
COMPREPLY=( "${cur_word}"{l,h,g,L,H,G} )
|
COMPREPLY+=( "${cur_word}"{l,h,g,L,H,G} )
|
||||||
;;
|
;;
|
||||||
mbc)
|
mbc)
|
||||||
local cur_arg="${cur_word:$optlen}"
|
local cur_arg="${cur_word:$optlen}"
|
||||||
cur_arg="${cur_arg@U}"
|
cur_arg="${cur_arg@U}"
|
||||||
compopt -o nosort # Keep `help` first in the list, mainly
|
COMPREPLY=( $(compgen -W "
|
||||||
mapfile -t COMPREPLY < <(compgen -W "help" -P "${cur_word:0:$optlen}" -- "${cur_word:$optlen}")
|
|
||||||
mapfile -t COMPREPLY -O ${#COMPREPLY} < <(compgen -W "
|
|
||||||
ROM_ONLY
|
ROM_ONLY
|
||||||
MBC1{,+RAM,+RAM+BATTERY}
|
MBC1{,+RAM,+RAM+BATTERY}
|
||||||
MBC2{,+BATTERY}
|
MBC2{,+BATTERY}
|
||||||
@@ -174,7 +157,8 @@ _rgbfix_completions() {
|
|||||||
BANDAI_TAMA5
|
BANDAI_TAMA5
|
||||||
HUC3
|
HUC3
|
||||||
HUC1+RAM+BATTERY
|
HUC1+RAM+BATTERY
|
||||||
TPP1_1.0{,+BATTERY}{,+RTC}{,+RUMBLE,+MULTIRUMBLE}" -P "${cur_word:0:$optlen}" -- "${cur_word/ /_}")
|
TPP1_1.0{,+BATTERY}{,+RTC}{,+RUMBLE,+MULTIRUMBLE}" -P "${cur_word:0:$optlen}" -- "`tr 'a-z ' 'A-Z_' <<<"${cur_word/ /_}"`") )
|
||||||
|
COMPREPLY+=( $(compgen -W "help" -P "${cur_word:0:$optlen}" -- "${cur_word:$optlen}") )
|
||||||
;;
|
;;
|
||||||
normal) # Acts like a glob...
|
normal) # Acts like a glob...
|
||||||
state="glob-*.gb *.gbc *.sgb"
|
state="glob-*.gb *.gbc *.sgb"
|
||||||
@@ -191,10 +175,6 @@ _rgbfix_completions() {
|
|||||||
done < <(compgen -A directory -- "${cur_word:$optlen}")
|
done < <(compgen -A directory -- "${cur_word:$optlen}")
|
||||||
compopt -o filenames
|
compopt -o filenames
|
||||||
;;
|
;;
|
||||||
*)
|
|
||||||
echo >&2 "Internal completion error: invalid state \"$state\", please report this bug"
|
|
||||||
return 1
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,44 +1,32 @@
|
|||||||
#!/usr/bin/env bash
|
#/usr/bin/env bash
|
||||||
|
|
||||||
# Same notes as RGBASM
|
# Same notes as RGBASM
|
||||||
|
|
||||||
_rgbgfx_completions() {
|
_rgbgfx_completions() {
|
||||||
|
COMPREPLY=()
|
||||||
|
|
||||||
# Format: "long_opt:state_after"
|
# Format: "long_opt:state_after"
|
||||||
# Empty long opt = it doesn't exit
|
# Empty long opt = it doesn't exit
|
||||||
# See the `state` variable below for info about `state_after`
|
# See the `state` variable below for info about `state_after`
|
||||||
declare -A opts=(
|
declare -A opts=(
|
||||||
[h]="help:normal"
|
|
||||||
[V]="version:normal"
|
[V]="version:normal"
|
||||||
[W]="warning:warning"
|
|
||||||
[w]=":normal"
|
|
||||||
[A]="auto-attr-map:normal"
|
|
||||||
[a]="attr-map:glob-*.attrmap"
|
|
||||||
[B]="background-color:unk"
|
|
||||||
[b]="base-tiles:unk"
|
|
||||||
[C]="color-curve:normal"
|
[C]="color-curve:normal"
|
||||||
[c]="colors:unk"
|
[D]="debug:normal"
|
||||||
[d]="depth:unk"
|
[h]="horizontal:normal"
|
||||||
[i]="input-tileset:glob-*.2bpp"
|
|
||||||
[L]="slice:unk"
|
|
||||||
[m]="mirror-tiles:normal"
|
[m]="mirror-tiles:normal"
|
||||||
[N]="nb-tiles:unk"
|
|
||||||
[n]="nb-palettes:unk"
|
|
||||||
[O]="group-outputs:normal"
|
|
||||||
[o]="output:glob-*.2bpp"
|
|
||||||
[P]="auto-palette:normal"
|
|
||||||
[p]="palette:glob-*.pal"
|
|
||||||
[Q]="auto-palette-map:normal"
|
|
||||||
[q]="palette-map:glob-*.palmap"
|
|
||||||
[r]="reverse:unk"
|
|
||||||
[s]="palette-size:unk"
|
|
||||||
[T]="auto-tilemap:normal"
|
|
||||||
[t]="tilemap:glob-*.tilemap"
|
|
||||||
[u]="unique-tiles:normal"
|
[u]="unique-tiles:normal"
|
||||||
[v]="verbose:normal"
|
[v]="verbose:normal"
|
||||||
[X]="mirror-x:normal"
|
[f]="fix:normal"
|
||||||
|
[F]="fix-and-save:normal"
|
||||||
|
[a]="attr-map:*.attrmap"
|
||||||
|
[A]="output-attr-map:normal"
|
||||||
|
[d]="depth:unk"
|
||||||
|
[o]="output:glob *.2bpp"
|
||||||
|
[p]="palette:glob *.pal"
|
||||||
|
[P]="output-palette:normal"
|
||||||
|
[t]="tilemap:glob *.tilemap"
|
||||||
|
[T]="output-tilemap:normal"
|
||||||
[x]="trim-end:unk"
|
[x]="trim-end:unk"
|
||||||
[Y]="mirror-y:normal"
|
|
||||||
[Z]="columns:normal"
|
|
||||||
)
|
)
|
||||||
# Parse command-line up to current word
|
# Parse command-line up to current word
|
||||||
local opt_ena=true
|
local opt_ena=true
|
||||||
@@ -69,7 +57,7 @@ _rgbgfx_completions() {
|
|||||||
optlen=0
|
optlen=0
|
||||||
}
|
}
|
||||||
|
|
||||||
for (( i = 1; i < COMP_CWORD; i++ )); do
|
for (( i = 1; i < $COMP_CWORD; i++ )); do
|
||||||
local word="${COMP_WORDS[$i]}"
|
local word="${COMP_WORDS[$i]}"
|
||||||
|
|
||||||
# If currently processing an argument, skip this word
|
# If currently processing an argument, skip this word
|
||||||
@@ -85,7 +73,7 @@ _rgbgfx_completions() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Check if it's a long option
|
# Check if it's a long option
|
||||||
if [[ "$word" = '--'* ]]; then
|
if [[ "${word:0:2}" = '--' ]]; then
|
||||||
# If the option is unknown, assume it takes no arguments: keep the state at "normal"
|
# If the option is unknown, assume it takes no arguments: keep the state at "normal"
|
||||||
for long_opt in "${opts[@]}"; do
|
for long_opt in "${opts[@]}"; do
|
||||||
if [[ "$word" = "--${long_opt%%:*}" ]]; then
|
if [[ "$word" = "--${long_opt%%:*}" ]]; then
|
||||||
@@ -101,7 +89,7 @@ _rgbgfx_completions() {
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
# Check if it's a short option
|
# Check if it's a short option
|
||||||
elif [[ "$word" = '-'* ]]; then
|
elif [[ "${word:0:1}" = '-' ]]; then
|
||||||
parse_short_opt "$word"
|
parse_short_opt "$word"
|
||||||
# The last option takes an argument...
|
# The last option takes an argument...
|
||||||
if [[ "$state" != 'normal' ]]; then
|
if [[ "$state" != 'normal' ]]; then
|
||||||
@@ -118,25 +106,25 @@ _rgbgfx_completions() {
|
|||||||
|
|
||||||
# Parse current word
|
# Parse current word
|
||||||
# Careful that it might look like an option, so use `--` aggressively!
|
# Careful that it might look like an option, so use `--` aggressively!
|
||||||
local cur_word="${COMP_WORDS[$i]}"
|
local cur_word="${COMP_WORDS[$COMP_CWORD]}"
|
||||||
|
|
||||||
# Process options, as short ones may change the state
|
# Process options, as short ones may change the state
|
||||||
if $opt_ena && [[ "$state" = 'normal' && "$cur_word" = '-'* ]]; then
|
if $opt_ena && [[ "$state" = 'normal' && "${cur_word:0:1}" = '-' ]]; then
|
||||||
# We might want to complete to an option or an arg to that option
|
# We might want to complete to an option or an arg to that option
|
||||||
# Parse the option word to check
|
# Parse the option word to check
|
||||||
# There's no whitespace in the option names, so we can ride a little dirty...
|
# There's no whitespace in the option names, so we can ride a little dirty...
|
||||||
|
|
||||||
# Is this a long option?
|
# Is this a long option?
|
||||||
if [[ "$cur_word" = '--'* ]]; then
|
if [[ "${cur_word:1:1}" = '-' ]]; then
|
||||||
# It is, try to complete one
|
# It is, try to complete one
|
||||||
mapfile -t COMPREPLY < <(compgen -W "${opts[*]%%:*}" -P '--' -- "${cur_word#--}")
|
COMPREPLY+=( $(compgen -W "${opts[*]%%:*}" -P '--' -- "${cur_word#--}") )
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
# Short options may be grouped, parse them to determine what to complete
|
# Short options may be grouped, parse them to determine what to complete
|
||||||
parse_short_opt "$cur_word"
|
parse_short_opt "$cur_word"
|
||||||
|
|
||||||
if [[ "$state" = 'normal' ]]; then
|
if [[ "$state" = 'normal' ]]; then
|
||||||
mapfile -t COMPREPLY < <(compgen -W "${!opts[*]}" -P "$cur_word" '')
|
COMPREPLY+=( $(compgen -W "${!opts[*]}" -P "$cur_word" '') )
|
||||||
return 0
|
return 0
|
||||||
elif [[ "$optlen" = "${#cur_word}" && "$state" != "warning" ]]; then
|
elif [[ "$optlen" = "${#cur_word}" && "$state" != "warning" ]]; then
|
||||||
# This short option group only awaits its argument!
|
# This short option group only awaits its argument!
|
||||||
@@ -144,25 +132,15 @@ _rgbgfx_completions() {
|
|||||||
# so that the next completion request switches to the argument
|
# so that the next completion request switches to the argument
|
||||||
# An exception is made for warnings, since it's idiomatic to stick them to the
|
# An exception is made for warnings, since it's idiomatic to stick them to the
|
||||||
# `-W`, and it doesn't break anything.
|
# `-W`, and it doesn't break anything.
|
||||||
COMPREPLY=( "$cur_word" )
|
COMPREPLY+=( "$cur_word" )
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
COMPREPLY=()
|
|
||||||
case "$state" in
|
case "$state" in
|
||||||
unk) # Return with no replies: no idea what to complete!
|
unk) # Return with no replies: no idea what to complete!
|
||||||
;;
|
;;
|
||||||
warning)
|
|
||||||
mapfile -t COMPREPLY < <(compgen -W "
|
|
||||||
embedded
|
|
||||||
obsolete
|
|
||||||
trim-nonempty
|
|
||||||
all
|
|
||||||
everything
|
|
||||||
error" -P "${cur_word:0:$optlen}" -- "${cur_word:$optlen}")
|
|
||||||
;;
|
|
||||||
normal) # Acts like a glob...
|
normal) # Acts like a glob...
|
||||||
state="glob-*.png"
|
state="glob-*.png"
|
||||||
;&
|
;&
|
||||||
@@ -178,10 +156,6 @@ _rgbgfx_completions() {
|
|||||||
done < <(compgen -A directory -- "${cur_word:$optlen}")
|
done < <(compgen -A directory -- "${cur_word:$optlen}")
|
||||||
compopt -o filenames
|
compopt -o filenames
|
||||||
;;
|
;;
|
||||||
*)
|
|
||||||
echo >&2 "Internal completion error: invalid state \"$state\", please report this bug"
|
|
||||||
return 1
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,28 +1,27 @@
|
|||||||
#!/usr/bin/env bash
|
#/usr/bin/env bash
|
||||||
|
|
||||||
# Same notes as RGBASM
|
# Same notes as RGBASM
|
||||||
|
|
||||||
_rgblink_completions() {
|
_rgblink_completions() {
|
||||||
|
COMPREPLY=()
|
||||||
|
|
||||||
# Format: "long_opt:state_after"
|
# Format: "long_opt:state_after"
|
||||||
# Empty long opt = it doesn't exit
|
# Empty long opt = it doesn't exit
|
||||||
# See the `state` variable below for info about `state_after`
|
# See the `state` variable below for info about `state_after`
|
||||||
declare -A opts=(
|
declare -A opts=(
|
||||||
[h]="help:normal"
|
|
||||||
[V]="version:normal"
|
[V]="version:normal"
|
||||||
[W]="warning:warning"
|
|
||||||
[M]="no-sym-in-map:normal"
|
|
||||||
[d]="dmg:normal"
|
[d]="dmg:normal"
|
||||||
[B]="backtrace:unk"
|
[t]="tiny:normal"
|
||||||
|
[v]="verbose:normal"
|
||||||
|
[w]="wramx:normal"
|
||||||
|
[x]="nopad:normal"
|
||||||
[l]="linkerscript:glob-*"
|
[l]="linkerscript:glob-*"
|
||||||
[m]="map:glob-*.map"
|
[m]="map:glob-*.map"
|
||||||
[n]="sym:glob-*.sym"
|
[n]="sym:glob-*.sym"
|
||||||
[O]="overlay:glob-*.gb *.gbc *.sgb"
|
[O]="overlay:glob-*.gb *.gbc *.sgb"
|
||||||
[o]="output:glob-*.gb *.gbc *.sgb"
|
[o]="output:glob-*.gb *.gbc *.sgb"
|
||||||
[p]="pad:unk"
|
[p]="pad:unk"
|
||||||
[t]="tiny:normal"
|
[s]="smart:unk"
|
||||||
[v]="verbose:normal"
|
|
||||||
[w]="wramx:normal"
|
|
||||||
[x]="nopad:normal"
|
|
||||||
)
|
)
|
||||||
# Parse command-line up to current word
|
# Parse command-line up to current word
|
||||||
local opt_ena=true
|
local opt_ena=true
|
||||||
@@ -53,7 +52,7 @@ _rgblink_completions() {
|
|||||||
optlen=0
|
optlen=0
|
||||||
}
|
}
|
||||||
|
|
||||||
for (( i = 1; i < COMP_CWORD; i++ )); do
|
for (( i = 1; i < $COMP_CWORD; i++ )); do
|
||||||
local word="${COMP_WORDS[$i]}"
|
local word="${COMP_WORDS[$i]}"
|
||||||
|
|
||||||
# If currently processing an argument, skip this word
|
# If currently processing an argument, skip this word
|
||||||
@@ -69,7 +68,7 @@ _rgblink_completions() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Check if it's a long option
|
# Check if it's a long option
|
||||||
if [[ "$word" = '--'* ]]; then
|
if [[ "${word:0:2}" = '--' ]]; then
|
||||||
# If the option is unknown, assume it takes no arguments: keep the state at "normal"
|
# If the option is unknown, assume it takes no arguments: keep the state at "normal"
|
||||||
for long_opt in "${opts[@]}"; do
|
for long_opt in "${opts[@]}"; do
|
||||||
if [[ "$word" = "--${long_opt%%:*}" ]]; then
|
if [[ "$word" = "--${long_opt%%:*}" ]]; then
|
||||||
@@ -85,7 +84,7 @@ _rgblink_completions() {
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
# Check if it's a short option
|
# Check if it's a short option
|
||||||
elif [[ "$word" = '-'* ]]; then
|
elif [[ "${word:0:1}" = '-' ]]; then
|
||||||
parse_short_opt "$word"
|
parse_short_opt "$word"
|
||||||
# The last option takes an argument...
|
# The last option takes an argument...
|
||||||
if [[ "$state" != 'normal' ]]; then
|
if [[ "$state" != 'normal' ]]; then
|
||||||
@@ -102,25 +101,25 @@ _rgblink_completions() {
|
|||||||
|
|
||||||
# Parse current word
|
# Parse current word
|
||||||
# Careful that it might look like an option, so use `--` aggressively!
|
# Careful that it might look like an option, so use `--` aggressively!
|
||||||
local cur_word="${COMP_WORDS[$i]}"
|
local cur_word="${COMP_WORDS[$COMP_CWORD]}"
|
||||||
|
|
||||||
# Process options, as short ones may change the state
|
# Process options, as short ones may change the state
|
||||||
if $opt_ena && [[ "$state" = 'normal' && "$cur_word" = '-'* ]]; then
|
if $opt_ena && [[ "$state" = 'normal' && "${cur_word:0:1}" = '-' ]]; then
|
||||||
# We might want to complete to an option or an arg to that option
|
# We might want to complete to an option or an arg to that option
|
||||||
# Parse the option word to check
|
# Parse the option word to check
|
||||||
# There's no whitespace in the option names, so we can ride a little dirty...
|
# There's no whitespace in the option names, so we can ride a little dirty...
|
||||||
|
|
||||||
# Is this a long option?
|
# Is this a long option?
|
||||||
if [[ "$cur_word" = '--'* ]]; then
|
if [[ "${cur_word:1:1}" = '-' ]]; then
|
||||||
# It is, try to complete one
|
# It is, try to complete one
|
||||||
mapfile -t COMPREPLY < <(compgen -W "${opts[*]%%:*}" -P '--' -- "${cur_word#--}")
|
COMPREPLY+=( $(compgen -W "${opts[*]%%:*}" -P '--' -- "${cur_word#--}") )
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
# Short options may be grouped, parse them to determine what to complete
|
# Short options may be grouped, parse them to determine what to complete
|
||||||
parse_short_opt "$cur_word"
|
parse_short_opt "$cur_word"
|
||||||
|
|
||||||
if [[ "$state" = 'normal' ]]; then
|
if [[ "$state" = 'normal' ]]; then
|
||||||
mapfile -t COMPREPLY < <(compgen -W "${!opts[*]}" -P "$cur_word" '')
|
COMPREPLY+=( $(compgen -W "${!opts[*]}" -P "$cur_word" '') )
|
||||||
return 0
|
return 0
|
||||||
elif [[ "$optlen" = "${#cur_word}" && "$state" != "warning" ]]; then
|
elif [[ "$optlen" = "${#cur_word}" && "$state" != "warning" ]]; then
|
||||||
# This short option group only awaits its argument!
|
# This short option group only awaits its argument!
|
||||||
@@ -128,28 +127,15 @@ _rgblink_completions() {
|
|||||||
# so that the next completion request switches to the argument
|
# so that the next completion request switches to the argument
|
||||||
# An exception is made for warnings, since it's idiomatic to stick them to the
|
# An exception is made for warnings, since it's idiomatic to stick them to the
|
||||||
# `-W`, and it doesn't break anything.
|
# `-W`, and it doesn't break anything.
|
||||||
COMPREPLY=( "$cur_word" )
|
COMPREPLY+=( "$cur_word" )
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
COMPREPLY=()
|
|
||||||
case "$state" in
|
case "$state" in
|
||||||
unk) # Return with no replies: no idea what to complete!
|
unk) # Return with no replies: no idea what to complete!
|
||||||
;;
|
;;
|
||||||
warning)
|
|
||||||
mapfile -t COMPREPLY < <(compgen -W "
|
|
||||||
assert
|
|
||||||
div
|
|
||||||
obsolete
|
|
||||||
shift
|
|
||||||
shift-amount
|
|
||||||
truncation
|
|
||||||
all
|
|
||||||
everything
|
|
||||||
error" -P "${cur_word:0:$optlen}" -- "${cur_word:$optlen}")
|
|
||||||
;;
|
|
||||||
normal) # Acts like a glob...
|
normal) # Acts like a glob...
|
||||||
state="glob-*.o *.obj"
|
state="glob-*.o *.obj"
|
||||||
;&
|
;&
|
||||||
@@ -165,10 +151,6 @@ _rgblink_completions() {
|
|||||||
done < <(compgen -A directory -- "${cur_word:$optlen}")
|
done < <(compgen -A directory -- "${cur_word:$optlen}")
|
||||||
compopt -o filenames
|
compopt -o filenames
|
||||||
;;
|
;;
|
||||||
*)
|
|
||||||
echo >&2 "Internal completion error: invalid state \"$state\", please report this bug"
|
|
||||||
return 1
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,31 @@
|
|||||||
#!/usr/bin/env bash
|
#!/bin/bash
|
||||||
|
|
||||||
# SPDX-License-Identifier: MIT
|
# SPDX-License-Identifier: MIT
|
||||||
|
#
|
||||||
|
# Copyright (c) 2021 Rangi
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in all
|
||||||
|
# copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS 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.
|
||||||
|
|
||||||
declare -A FILES
|
declare -A FILES
|
||||||
while read -r -d '' file; do
|
while read -r -d '' file; do
|
||||||
FILES["$file"]="true"
|
FILES["$file"]="true"
|
||||||
done < <(git diff --name-only -z "$1" HEAD)
|
done < <(git diff --name-only -z $1 HEAD)
|
||||||
|
|
||||||
edited () {
|
edited () {
|
||||||
${FILES["$1"]:-"false"}
|
${FILES["$1"]:-"false"}
|
||||||
@@ -20,33 +40,18 @@ dependency () {
|
|||||||
# Pull requests that edit the first file without the second may be correct,
|
# Pull requests that edit the first file without the second may be correct,
|
||||||
# but are suspicious enough to require review.
|
# but are suspicious enough to require review.
|
||||||
|
|
||||||
dependency include/linkdefs.hpp man/rgbds.5 \
|
dependency include/linkdefs.h src/rgbds.5 \
|
||||||
"Was the object file format changed?"
|
"Was the object file format changed?"
|
||||||
|
|
||||||
dependency src/asm/parser.y man/rgbasm.5 \
|
dependency src/asm/parser.y src/asm/rgbasm.5 \
|
||||||
"Was the rgbasm grammar changed?"
|
"Was the rgbasm grammar changed?"
|
||||||
|
|
||||||
dependency src/asm/actions.cpp man/rgbasm.5 \
|
dependency include/asm/warning.h src/asm/rgbasm.1 \
|
||||||
"Was the rgbasm grammar changed?"
|
|
||||||
|
|
||||||
dependency src/link/script.y man/rgblink.5 \
|
|
||||||
"Was the linker script grammar changed?"
|
|
||||||
|
|
||||||
dependency src/link/layout.cpp man/rgblink.5 \
|
|
||||||
"Was the linker script grammar changed?"
|
|
||||||
|
|
||||||
dependency include/asm/warning.hpp man/rgbasm.1 \
|
|
||||||
"Were the rgbasm warnings changed?"
|
"Were the rgbasm warnings changed?"
|
||||||
dependency include/link/warning.hpp man/rgblink.1 \
|
|
||||||
"Were the rgblink warnings changed?"
|
|
||||||
dependency include/fix/warning.hpp man/rgbfix.1 \
|
|
||||||
"Were the rgbfix warnings changed?"
|
|
||||||
dependency include/gfx/warning.hpp man/rgbgfx.1 \
|
|
||||||
"Were the rgbgfx warnings changed?"
|
|
||||||
|
|
||||||
dependency src/asm/object.cpp include/linkdefs.hpp \
|
dependency src/asm/object.c include/linkdefs.h \
|
||||||
"Should the object file revision be bumped?"
|
"Should the object file revision be bumped?"
|
||||||
dependency src/link/object.cpp include/linkdefs.hpp \
|
dependency src/link/object.c include/linkdefs.h \
|
||||||
"Should the object file revision be bumped?"
|
"Should the object file revision be bumped?"
|
||||||
|
|
||||||
dependency Makefile CMakeLists.txt \
|
dependency Makefile CMakeLists.txt \
|
||||||
@@ -54,40 +59,27 @@ dependency Makefile CMakeLists.txt \
|
|||||||
dependency Makefile src/CMakeLists.txt \
|
dependency Makefile src/CMakeLists.txt \
|
||||||
"Did the build process change?"
|
"Did the build process change?"
|
||||||
|
|
||||||
dependency src/asm/main.cpp man/rgbasm.1 \
|
dependency src/asm/main.c src/asm/rgbasm.1 \
|
||||||
"Did the rgbasm CLI change?"
|
"Did the rgbasm CLI change?"
|
||||||
dependency src/asm/main.cpp contrib/zsh_compl/_rgbasm \
|
dependency src/asm/main.c contrib/zsh_compl/_rgbasm \
|
||||||
"Did the rgbasm CLI change?"
|
"Did the rgbasm CLI change?"
|
||||||
dependency src/asm/main.cpp contrib/bash_compl/_rgbasm.bash \
|
dependency src/asm/main.c contrib/bash_compl/_rgbasm.bash \
|
||||||
"Did the rgbasm CLI change?"
|
"Did the rgbasm CLI change?"
|
||||||
dependency src/link/main.cpp man/rgblink.1 \
|
dependency src/link/main.c src/link/rgblink.1 \
|
||||||
"Did the rgblink CLI change?"
|
"Did the rgblink CLI change?"
|
||||||
dependency src/link/main.cpp contrib/zsh_compl/_rgblink \
|
dependency src/link/main.c contrib/zsh_compl/_rgblink \
|
||||||
"Did the rgblink CLI change?"
|
"Did the rgblink CLI change?"
|
||||||
dependency src/link/main.cpp contrib/bash_compl/_rgblink.bash \
|
dependency src/link/main.c contrib/bash_compl/_rgblink.bash \
|
||||||
"Did the rgblink CLI change?"
|
"Did the rgblink CLI change?"
|
||||||
dependency src/fix/main.cpp man/rgbfix.1 \
|
dependency src/fix/main.c src/fix/rgbfix.1 \
|
||||||
"Did the rgbfix CLI change?"
|
"Did the rgbfix CLI change?"
|
||||||
dependency src/fix/main.cpp contrib/zsh_compl/_rgbfix \
|
dependency src/fix/main.c contrib/zsh_compl/_rgbfix \
|
||||||
"Did the rgbfix CLI change?"
|
"Did the rgbfix CLI change?"
|
||||||
dependency src/fix/main.cpp contrib/bash_compl/_rgbfix.bash \
|
dependency src/fix/main.c contrib/bash_compl/_rgbfix.bash \
|
||||||
"Did the rgbfix CLI change?"
|
"Did the rgbfix CLI change?"
|
||||||
dependency src/gfx/main.cpp man/rgbgfx.1 \
|
dependency src/gfx/main.c src/gfx/rgbgfx.1 \
|
||||||
"Did the rgbgfx CLI change?"
|
"Did the rgbgfx CLI change?"
|
||||||
dependency src/gfx/main.cpp contrib/zsh_compl/_rgbgfx \
|
dependency src/gfx/main.c contrib/zsh_compl/_rgbgfx \
|
||||||
"Did the rgbgfx CLI change?"
|
"Did the rgbgfx CLI change?"
|
||||||
dependency src/gfx/main.cpp contrib/bash_compl/_rgbgfx.bash \
|
dependency src/gfx/main.c contrib/bash_compl/_rgbgfx.bash \
|
||||||
"Did the rgbgfx CLI change?"
|
"Did the rgbgfx CLI change?"
|
||||||
|
|
||||||
dependency test/fetch-test-deps.sh CONTRIBUTING.md \
|
|
||||||
"Did the test protocol change?"
|
|
||||||
dependency test/run-tests.sh CONTRIBUTING.md \
|
|
||||||
"Did the test protocol change?"
|
|
||||||
dependency test/asm/test.sh CONTRIBUTING.md \
|
|
||||||
"Did the RGBASM test protocol change?"
|
|
||||||
dependency test/link/test.sh CONTRIBUTING.md \
|
|
||||||
"Did the RGBLINK test protocol change?"
|
|
||||||
dependency test/fix/test.sh CONTRIBUTING.md \
|
|
||||||
"Did the RGBFIX test protocol change?"
|
|
||||||
dependency test/gfx/test.sh CONTRIBUTING.md \
|
|
||||||
"Did the RGBGFX test protocol change?"
|
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
clang-format --version
|
|
||||||
|
|
||||||
find . -type f \( -iname '*.hpp' -o -iname '*.cpp' \) -exec clang-format -i {} +
|
|
||||||
|
|
||||||
if ! git diff-index --quiet HEAD --; then
|
|
||||||
echo 'Unformatted files:'
|
|
||||||
git diff-index --name-only HEAD --
|
|
||||||
echo
|
|
||||||
git diff HEAD --
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# Build RGBDS with gcov support
|
|
||||||
make coverage -j
|
|
||||||
|
|
||||||
# Run the tests
|
|
||||||
pushd test
|
|
||||||
./fetch-test-deps.sh
|
|
||||||
if [[ $# -eq 0 ]]; then
|
|
||||||
./run-tests.sh
|
|
||||||
else
|
|
||||||
./run-tests.sh --os "$1"
|
|
||||||
fi
|
|
||||||
popd
|
|
||||||
|
|
||||||
# Generate coverage logs
|
|
||||||
gcov src/**/*.cpp
|
|
||||||
mkdir -p coverage
|
|
||||||
|
|
||||||
# Generate coverage report, excluding Bison-generated files
|
|
||||||
COVERAGE_INFO=coverage/coverage.info
|
|
||||||
lcov -c --no-external -d . -o "$COVERAGE_INFO"
|
|
||||||
lcov -r "$COVERAGE_INFO" src/asm/parser.{hpp,cpp} src/link/script.{hpp,cpp} -o "$COVERAGE_INFO"
|
|
||||||
genhtml --dark-mode -f -s -o coverage/ "$COVERAGE_INFO"
|
|
||||||
|
|
||||||
# Check whether running from coverage.yml workflow
|
|
||||||
if [ "$1" != "ubuntu-ci" ]; then
|
|
||||||
# Open report in web browser
|
|
||||||
if [ "$(uname)" == "Darwin" ]; then
|
|
||||||
open coverage/index.html
|
|
||||||
else
|
|
||||||
xdg-open coverage/index.html
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
@@ -1,54 +1,73 @@
|
|||||||
#!/usr/bin/env bash
|
#!/bin/bash
|
||||||
|
|
||||||
# SPDX-License-Identifier: MIT
|
# SPDX-License-Identifier: MIT
|
||||||
|
#
|
||||||
|
# Copyright (c) 2020 Eldred Habert
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in all
|
||||||
|
# copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS 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.
|
||||||
|
|
||||||
STATE=0
|
STATE=0
|
||||||
diff <(xxd "$1") <(xxd "$2") | while read -r LINE; do
|
diff <(xxd $1) <(xxd $2) | while read -r LINE; do
|
||||||
if [[ $STATE -eq 0 ]]; then
|
if [ $STATE -eq 0 ]; then
|
||||||
# Discard first line (line info)
|
# Discard first line (line info)
|
||||||
STATE=1
|
STATE=1
|
||||||
elif [[ "$LINE" = '---' ]]; then
|
elif [ "$LINE" = '---' ]; then
|
||||||
# Separator between files switches states
|
# Separator between files switches states
|
||||||
echo "$LINE"
|
echo $LINE
|
||||||
STATE=3
|
STATE=3
|
||||||
elif grep -Eq '^[0-9]+(,[0-9]+)?[cd][0-9]+(,[0-9]+)?' <<< "$LINE"; then
|
elif grep -Eq '^[0-9]+(,[0-9]+)?[cd][0-9]+(,[0-9]+)?' <<< "$LINE"; then
|
||||||
# Line info resets the whole thing
|
# Line info resets the whole thing
|
||||||
STATE=1
|
STATE=1
|
||||||
elif [[ $STATE -eq 1 || $STATE -eq 3 ]]; then
|
elif [ $STATE -eq 1 -o $STATE -eq 3 ]; then
|
||||||
# Compute the GB address from the ROM offset
|
# Compute the GB address from the ROM offset
|
||||||
OFS=$(cut -d ' ' -f 2 <<< "$LINE" | tr -d ':')
|
OFS=$(cut -d ' ' -f 2 <<< "$LINE" | tr -d ':')
|
||||||
BANK=$((0x$OFS / 0x4000))
|
BANK=$((0x$OFS / 0x4000))
|
||||||
ADDR=$((0x$OFS % 0x4000 + (BANK != 0) * 0x4000))
|
ADDR=$((0x$OFS % 0x4000 + ($BANK != 0) * 0x4000))
|
||||||
# Try finding the preceding symbol closest to the diff
|
# Try finding the preceding symbol closest to the diff
|
||||||
if [[ $STATE -eq 1 ]]; then
|
if [ $STATE -eq 1 ]; then
|
||||||
STATE=2
|
STATE=2
|
||||||
SYMFILE=${1%.*}.sym
|
SYMFILE=${1%.*}.sym
|
||||||
else
|
else
|
||||||
STATE=4
|
STATE=4
|
||||||
SYMFILE=${2%.*}.sym
|
SYMFILE=${2%.*}.sym
|
||||||
fi
|
fi
|
||||||
EXTRA=$(if [[ -f "$SYMFILE" ]]; then
|
EXTRA=$(if [ -f "$SYMFILE" ]; then
|
||||||
# Read the sym file for such a symbol
|
# Read the sym file for such a symbol
|
||||||
# Ignore comment lines, only pick matching bank
|
# Ignore comment lines, only pick matching bank
|
||||||
# (The bank regex ignores comments already, make `cut` and `tr` process less lines)
|
# (The bank regex ignores comments already, make `cut` and `tr` process less lines)
|
||||||
grep -Ei "$(printf "^%02x:" $BANK)" "$SYMFILE" |
|
grep -Ei $(printf "^%02x:" $BANK) "$SYMFILE" |
|
||||||
sed "s/$(printf "^%02x:" $BANK)/0x/g" |
|
|
||||||
cut -d ';' -f 1 |
|
cut -d ';' -f 1 |
|
||||||
tr -d "\r" |
|
tr -d "\r" |
|
||||||
sort -g |
|
|
||||||
while read -r SYMADDR SYM; do
|
while read -r SYMADDR SYM; do
|
||||||
SYMADDR=$(($SYMADDR))
|
SYMADDR=$((0x${SYMADDR#*:}))
|
||||||
if [[ $SYMADDR -le $ADDR ]]; then
|
if [ $SYMADDR -le $ADDR ]; then
|
||||||
printf " (%s+0x%x)\n" "$SYM" $((ADDR - SYMADDR))
|
printf " (%s+%#x)\n" "$SYM" $(($ADDR - $SYMADDR))
|
||||||
fi
|
fi
|
||||||
|
# TODO: assumes sorted sym files
|
||||||
done | tail -n 1
|
done | tail -n 1
|
||||||
fi)
|
fi)
|
||||||
printf "%02x:%04x %s\n" $BANK $ADDR "$EXTRA"
|
printf "%02x:%04x %s\n" $BANK $ADDR $EXTRA
|
||||||
fi
|
fi
|
||||||
if [[ $STATE -eq 2 || $STATE -eq 4 ]]; then
|
if [ $STATE -eq 2 -o $STATE -eq 4 ]; then
|
||||||
OFS=$(cut -d ' ' -f 2 <<< "$LINE" | tr -d ':')
|
OFS=$(cut -d ' ' -f 2 <<< "$LINE" | tr -d ':')
|
||||||
BANK=$((0x$OFS / 0x4000))
|
BANK=$((0x$OFS / 0x4000))
|
||||||
ADDR=$((0x$OFS % 0x4000 + (BANK != 0) * 0x4000))
|
ADDR=$((0x$OFS % 0x4000 + ($BANK != 0) * 0x4000))
|
||||||
printf "%s %02x:%04x: %s\n" "${LINE:0:1}" $BANK $ADDR "${LINE#*: }"
|
printf "%s %02x:%04x: %s\n" "${LINE:0:1}" $BANK $ADDR "${LINE#*: }"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
if [[ $# -ne 2 ]]; then
|
|
||||||
cat <<EOF >&2
|
|
||||||
Usage: $0 <palettes.pal> <output.png>
|
|
||||||
EOF
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
TMP=$(mktemp -d)
|
|
||||||
readonly TMP
|
|
||||||
trap 'rm -rf "$TMP"' EXIT
|
|
||||||
|
|
||||||
tile() { for i in {0..7}; do printf "$1"; done }
|
|
||||||
{ tile '\x00\x00' && tile '\xFF\x00' && tile '\x00\xFF' && tile '\xFF\xFF'; } >"$TMP/tmp.2bpp"
|
|
||||||
|
|
||||||
NB_BYTES=$(wc -c <"$1")
|
|
||||||
(( NB_PALS = NB_BYTES / 8 ))
|
|
||||||
for (( i = 0; i < NB_PALS; i++ )); do
|
|
||||||
printf '\0\1\2\3' >>"$TMP/tmp.tilemap"
|
|
||||||
printf $(printf '\\x%x' $i{,,,}) >> "$TMP/tmp.palmap"
|
|
||||||
done
|
|
||||||
|
|
||||||
"${RGBGFX:-${RGBDS+$RGBDS/}rgbgfx}" -r 4 "$2" -o "$TMP/tmp.2bpp" -OTQ -p "$1" -n "$NB_PALS"
|
|
||||||
@@ -16,53 +16,45 @@ _rgbasm_warnings() {
|
|||||||
'empty-data-directive:Warn on arg-less d[bwl] in ROM'
|
'empty-data-directive:Warn on arg-less d[bwl] in ROM'
|
||||||
'empty-macro-arg:Warn on empty macro arg'
|
'empty-macro-arg:Warn on empty macro arg'
|
||||||
'empty-strrpl:Warn on calling STRRPL with empty pattern'
|
'empty-strrpl:Warn on calling STRRPL with empty pattern'
|
||||||
'export-undefined:Warn on EXPORT of an undefined symbol'
|
|
||||||
'large-constant:Warn on constants too large for a signed 32-bit int'
|
'large-constant:Warn on constants too large for a signed 32-bit int'
|
||||||
|
'long-string:Warn on strings too long'
|
||||||
'macro-shift:Warn when shifting macro args part their limits'
|
'macro-shift:Warn when shifting macro args part their limits'
|
||||||
'nested-comment:Warn on "/*" inside block comments'
|
'nested-comment:Warn on "/*" inside block comments'
|
||||||
'numeric-string:Warn when a multi-character string is treated as a number'
|
'numeric-string:Warn when a multi-character string is treated as a number'
|
||||||
'obsolete:Warn when using deprecated features'
|
'obsolete:Warn when using deprecated features'
|
||||||
'purge:Warn when purging exported symbols or labels'
|
|
||||||
'shift:Warn when shifting negative values'
|
'shift:Warn when shifting negative values'
|
||||||
'shift-amount:Warn when a shift'\''s operand is negative or \> 32'
|
'shift-amount:Warn when a shift'\''s operand it negative or \> 32'
|
||||||
'truncation:Warn when implicit truncation loses bits'
|
'truncation:Warn when implicit truncation loses bits'
|
||||||
'unmapped-char:Warn on unmapped character'
|
|
||||||
'unmatched-directive:Warn on unmatched directive pair'
|
|
||||||
'unterminated-load:Warn on LOAD without ENDL'
|
|
||||||
'user:Warn when executing the WARN built-in'
|
'user:Warn when executing the WARN built-in'
|
||||||
)
|
)
|
||||||
|
# TODO: handle `no-` and `error=` somehow?
|
||||||
|
# TODO: handle `=0|1|2` levels for `numeric-string` and `truncation`?
|
||||||
_describe warning warnings
|
_describe warning warnings
|
||||||
}
|
}
|
||||||
|
|
||||||
local args=(
|
local args=(
|
||||||
# Arguments are listed here in the same order as in the manual, except for the version and help
|
# Arguments are listed here in the same order as in the manual, except for the version
|
||||||
'(- : * options)'{-V,--version}'[Print version number and exit]'
|
'(- : * options)'{-V,--version}'[Print version number]'
|
||||||
'(- : * options)'{-h,--help}'[Print help text and exit]'
|
|
||||||
|
|
||||||
'(-E --export-all)'{-E,--export-all}'[Export all symbols]'
|
'(-E --export-all)'{-E,--export-all}'[Export all symbols]'
|
||||||
'(-v --verbose)'{-v,--verbose}'[Enable verbose output]'
|
'(-h --halt-without-nop)'{-h,--halt-without-nop}'[Avoid outputting a `nop` after `halt`]'
|
||||||
|
'(-L ---preserve-ld)'{-L,--preserve-ld}'[Prevent auto-optimizing `ld` into `ldh`]'
|
||||||
|
'(-v --verbose)'{-v,--verbose}'[Print additional messages regarding progression]'
|
||||||
-w'[Disable all warnings]'
|
-w'[Disable all warnings]'
|
||||||
|
|
||||||
'(-B --backtrace)'{-B,--backtrace}'+[Set backtrace depth or style]:param:'
|
|
||||||
'(-b --binary-digits)'{-b,--binary-digits}'+[Change chars for binary constants]:digit spec:'
|
'(-b --binary-digits)'{-b,--binary-digits}'+[Change chars for binary constants]:digit spec:'
|
||||||
--color'[Whether to use color in output]:color:(auto always never)'
|
|
||||||
'*'{-D,--define}'+[Define a string symbol]:name + value (default 1):'
|
'*'{-D,--define}'+[Define a string symbol]:name + value (default 1):'
|
||||||
'(-g --gfx-chars)'{-g,--gfx-chars}'+[Change chars for gfx constants]:chars spec:'
|
'(-g --gfx-chars)'{-g,--gfx-chars}'+[Change chars for gfx constants]:chars spec:'
|
||||||
'(-I --include)'{-I,--include}'+[Add an include directory]:include path:_files -/'
|
'(-i --include)'{-i,--include}'+[Add an include directory]:include path:_files -/'
|
||||||
'(-M --dependfile)'{-M,--dependfile}"+[Write dependencies in Makefile format]:output file:_files -g '*.{d,mk}'"
|
'(-M --dependfile)'{-M,--dependfile}"+[List deps in make format]:output file:_files -g '*.{d,mk}'"
|
||||||
-MC'[Continue after missing dependencies]'
|
-MG'[Assume missing files should be generated]'
|
||||||
-MG'[Assume missing dependencies should be generated]'
|
-MP'[Add phony targets to all deps]'
|
||||||
-MP'[Add phony targets to all dependencies]'
|
|
||||||
'*'-MT"+[Add a target to the rules]:target:_files -g '*.{d,mk,o}'"
|
'*'-MT"+[Add a target to the rules]:target:_files -g '*.{d,mk,o}'"
|
||||||
'*'-MQ"+[Add a target to the rules]:target:_files -g '*.{d,mk,o}'"
|
'*'-MQ"+[Add a target to the rules]:target:_files -g '*.{d,mk,o}'"
|
||||||
'(-o --output)'{-o,--output}'+[Output file]:output file:_files'
|
'(-o --output)'{-o,--output}'+[Output file]:output file:_files'
|
||||||
'(-P --preinclude)'{-P,--preinclude}"+[Pre-include a file]:include file:_files -g '*.{asm,inc}'"
|
|
||||||
'(-p --pad-value)'{-p,--pad-value}'+[Set padding byte]:padding byte:'
|
'(-p --pad-value)'{-p,--pad-value}'+[Set padding byte]:padding byte:'
|
||||||
'(-Q --q-precision)'{-Q,--q-precision}'+[Set fixed-point precision]:precision:'
|
|
||||||
'(-r --recursion-depth)'{-r,--recursion-depth}'+[Set maximum recursion depth]:depth:'
|
'(-r --recursion-depth)'{-r,--recursion-depth}'+[Set maximum recursion depth]:depth:'
|
||||||
'(-s --state)'{-s,--state}"+[Write features of final state]:state file:_files -g '*.dump.asm'"
|
|
||||||
'(-W --warning)'{-W,--warning}'+[Toggle warning flags]:warning flag:_rgbasm_warnings'
|
'(-W --warning)'{-W,--warning}'+[Toggle warning flags]:warning flag:_rgbasm_warnings'
|
||||||
'(-X --max-errors)'{-X,--max-errors}'+[Set maximum errors before aborting]:maximum errors:'
|
|
||||||
|
|
||||||
":assembly sources:_files -g '*.asm'"
|
":assembly sources:_files -g '*.asm'"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -34,26 +34,9 @@ _mbc_names() {
|
|||||||
_describe "MBC name" mbc_names
|
_describe "MBC name" mbc_names
|
||||||
}
|
}
|
||||||
|
|
||||||
_rgbfix_warnings() {
|
|
||||||
local warnings=(
|
|
||||||
'error:Turn all warnings into errors'
|
|
||||||
|
|
||||||
'all:Enable most warning messages'
|
|
||||||
'everything:Enable literally everything'
|
|
||||||
|
|
||||||
'mbc:Warn about issues with MBC specs'
|
|
||||||
'obsolete:Warn when using deprecated features'
|
|
||||||
'overwrite:Warn when overwriting non-zero bytes'
|
|
||||||
'sgb:Warn when SGB flag conflicts with old licensee code'
|
|
||||||
'truncation:Warn when values are truncated to fit'
|
|
||||||
)
|
|
||||||
_describe warning warnings
|
|
||||||
}
|
|
||||||
|
|
||||||
local args=(
|
local args=(
|
||||||
# Arguments are listed here in the same order as in the manual, except for the version and help
|
# Arguments are listed here in the same order as in the manual, except for the version
|
||||||
'(- : * options)'{-V,--version}'[Print version number and exit]'
|
'(- : * options)'{-V,--version}'[Print version number]'
|
||||||
'(- : * options)'{-h,--help}'[Print help text and exit]'
|
|
||||||
|
|
||||||
'(-C --color-only -c --color-compatible)'{-C,--color-only}'[Mark ROM as GBC-only]'
|
'(-C --color-only -c --color-compatible)'{-C,--color-only}'[Mark ROM as GBC-only]'
|
||||||
'(-C --color-only -c --color-compatible)'{-c,--color-compatible}'[Mark ROM as GBC-compatible]'
|
'(-C --color-only -c --color-compatible)'{-c,--color-compatible}'[Mark ROM as GBC-compatible]'
|
||||||
@@ -61,21 +44,16 @@ local args=(
|
|||||||
'(-O --overwrite)'{-O,--overwrite}'[Allow overwriting non-zero bytes]'
|
'(-O --overwrite)'{-O,--overwrite}'[Allow overwriting non-zero bytes]'
|
||||||
'(-s --sgb-compatible)'{-s,--sgb-compatible}'[Set the SGB flag]'
|
'(-s --sgb-compatible)'{-s,--sgb-compatible}'[Set the SGB flag]'
|
||||||
'(-f --fix-spec -v --validate)'{-v,--validate}'[Shorthand for -f lhg]'
|
'(-f --fix-spec -v --validate)'{-v,--validate}'[Shorthand for -f lhg]'
|
||||||
-w'[Disable all warnings]'
|
|
||||||
|
|
||||||
--color'[Whether to use color in output]:color:(auto always never)'
|
|
||||||
'(-f --fix-spec -v --validate)'{-f,--fix-spec}'+[Fix or trash some header values]:fix spec:'
|
'(-f --fix-spec -v --validate)'{-f,--fix-spec}'+[Fix or trash some header values]:fix spec:'
|
||||||
'(-i --game-id)'{-i,--game-id}'+[Set game ID string]:4-char game ID:'
|
'(-i --game-id)'{-i,--game-id}'+[Set game ID string]:4-char game ID:'
|
||||||
'(-k --new-licensee)'{-k,--new-licensee}'+[Set new licensee string]:2-char licensee ID:'
|
'(-k --new-licensee)'{-k,--new-licensee}'+[Set new licensee string]:2-char licensee ID:'
|
||||||
'(-l --old-licensee)'{-l,--old-licensee}'+[Set old licensee ID]:licensee number:'
|
'(-l --old-licensee)'{-l,--old-licensee}'+[Set old licensee ID]:licensee number:'
|
||||||
'(-L --logo)'{-L,--logo}'+[Set custom logo]:1bpp image:'
|
|
||||||
'(-m --mbc-type)'{-m,--mbc-type}"+[Set MBC flags]:mbc name:_mbc_names"
|
'(-m --mbc-type)'{-m,--mbc-type}"+[Set MBC flags]:mbc name:_mbc_names"
|
||||||
'(-n --rom-version)'{-n,--rom-version}'+[Set ROM version]:rom version byte:'
|
'(-n --rom-version)'{-n,--rom-version}'+[Set ROM version]:rom version byte:'
|
||||||
'(-o --output)'{-o,--output}"+[Output file]:output file:_files -g '*.{gb,sgb,gbc}'"
|
|
||||||
'(-p --pad-value)'{-p,--pad-value}'+[Pad to next valid size using this byte as padding]:padding byte:'
|
'(-p --pad-value)'{-p,--pad-value}'+[Pad to next valid size using this byte as padding]:padding byte:'
|
||||||
'(-r --ram-size)'{-r,--ram-size}'+[Set RAM size]:ram size byte:'
|
'(-r --ram-size)'{-r,--ram-size}'+[Set RAM size]:ram size byte:'
|
||||||
'(-t --title)'{-t,--title}'+[Set title string]:11-char title string:'
|
'(-t --title)'{-t,--title}'+[Set title string]:11-char title string:'
|
||||||
'(-W --warning)'{-W,--warning}'+[Toggle warning flags]:warning flag:_rgbfix_warnings'
|
|
||||||
|
|
||||||
'*'":ROM files:_files -g '*.{gb,sgb,gbc}'"
|
'*'":ROM files:_files -g '*.{gb,sgb,gbc}'"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -9,56 +9,27 @@ _depths() {
|
|||||||
_describe 'bit depth' depths
|
_describe 'bit depth' depths
|
||||||
}
|
}
|
||||||
|
|
||||||
_rgbgfx_warnings() {
|
|
||||||
local warnings=(
|
|
||||||
'error:Turn all warnings into errors'
|
|
||||||
|
|
||||||
'all:Enable most warning messages'
|
|
||||||
'everything:Enable literally everything'
|
|
||||||
|
|
||||||
'embedded:Warn when using embedded PLTE without "-c embedded"'
|
|
||||||
'obsolete:Warn when using deprecated features'
|
|
||||||
'trim-nonempty:Warn when "-x" trims nonempty tiles'
|
|
||||||
)
|
|
||||||
_describe warning warnings
|
|
||||||
}
|
|
||||||
|
|
||||||
local args=(
|
local args=(
|
||||||
# Arguments are listed here in the same order as in the manual, except for the version and help
|
# Arguments are listed here in the same order as in the manual, except for the version
|
||||||
'(- : * options)'{-V,--version}'[Print version number and exit]'
|
'(- : * options)'{-V,--version}'[Print version number]'
|
||||||
'(- : * options)'{-h,--help}'[Print help text and exit]'
|
|
||||||
|
|
||||||
'(-a --attr-map -A --auto-attr-map)'{-A,--auto-attr-map}'[Shortcut for -a <file>.attrmap]'
|
'(-a --attr-map -A --output-attr-map)'{-A,--output-attr-map}'[Shortcut for -a <file>.attrmap]'
|
||||||
'(-C --color-curve)'{-C,--color-curve}'[Generate palettes using GBC color curve]'
|
'(-C --color-curve)'{-C,--color-curve}'[Generate palettes using GBC color curve]'
|
||||||
|
'(-D --debug)'{-D,--debug}'[Enable debug features]'
|
||||||
|
'(-f --fix -F --fix-and-save)'{-f,--fix}'[Fix input PNG into an indexed image]'
|
||||||
|
'(-f --fix -F --fix-and-save)'{-F,--fix-and-save}'[Like -f but also save CLI params within the PNG]'
|
||||||
|
'(-h --horizontal)'{-h,--horizontal}'[Lay out tiles horizontally instead of vertically]'
|
||||||
'(-m --mirror-tiles)'{-m,--mirror-tiles}'[Eliminate mirrored tiles from output]'
|
'(-m --mirror-tiles)'{-m,--mirror-tiles}'[Eliminate mirrored tiles from output]'
|
||||||
'(-O --group-outputs)'{-O,--group-outputs}'[Base "shortcut" options on the output path, not input]'
|
'(-p --palette -P --output-palette)'{-P,--output-palette}'[Shortcut for -p <file>.pal]'
|
||||||
'(-p --palette -P --auto-palette)'{-P,--auto-palette}'[Shortcut for -p <file>.pal]'
|
'(-t --tilemap -T --output-tilemap)'{-T,--output-tilemap}'[Shortcut for -t <file>.tilemap]'
|
||||||
'(-q --palette-map -Q --auto-palette-map)'{-Q,--auto-palette-map}'[Shortcut for -p <file>.palmap]'
|
|
||||||
'(-t --tilemap -T --auto-tilemap)'{-T,--auto-tilemap}'[Shortcut for -t <file>.tilemap]'
|
|
||||||
'(-u --unique-tiles)'{-u,--unique-tiles}'[Eliminate redundant tiles]'
|
'(-u --unique-tiles)'{-u,--unique-tiles}'[Eliminate redundant tiles]'
|
||||||
'(-v --verbose)'{-v,--verbose}'[Enable verbose output]'
|
'(-v --verbose)'{-v,--verbose}'[Enable verbose output]'
|
||||||
-w'[Disable all warnings]'
|
|
||||||
'(-X --mirror-x)'{-X,--mirror-x}'[Eliminate horizontally mirrored tiles from output]'
|
|
||||||
'(-Y --mirror-y)'{-Y,--mirror-y}'[Eliminate vertically mirrored tiles from output]'
|
|
||||||
'(-Z --columns)'{-Z,--columns}'[Read the image in column-major order]'
|
|
||||||
|
|
||||||
'(-a --attr-map -A --auto-attr-map)'{-a,--attr-map}'+[Generate a map of tile attributes (mirroring)]:attrmap file:_files'
|
'(-a --attr-map -A --output-attr-map)'{-a,--attr-map}'+[Generate a map of tile attributes (mirroring)]:attrmap file:_files'
|
||||||
'(-B --background-color)'{-B,--background-color}'+[Ignore tiles containing only specified color]:color:'
|
|
||||||
'(-b --base-tiles)'{-b,--base-tiles}'+[Base tile IDs for tile map output]:base tile IDs:'
|
|
||||||
--color'[Whether to use color in output]:color:(auto always never)'
|
|
||||||
'(-c --colors)'{-c,--colors}'+[Specify color palettes]:palette spec:'
|
|
||||||
'(-d --depth)'{-d,--depth}'+[Set bit depth]:bit depth:_depths'
|
'(-d --depth)'{-d,--depth}'+[Set bit depth]:bit depth:_depths'
|
||||||
'(-i --input-tileset)'{-i,--input-tileset}'+[Use specific tiles]:tileset file:_files -g "*.2bpp"'
|
|
||||||
'(-L --slice)'{-L,--slice}'+[Only process a portion of the image]:input slice:'
|
|
||||||
'(-N --nb-tiles)'{-N,--nb-tiles}'+[Limit number of tiles]:tile count:'
|
|
||||||
'(-n --nb-palettes)'{-n,--nb-palettes}'+[Limit number of palettes]:palette count:'
|
|
||||||
'(-o --output)'{-o,--output}'+[Set output file]:output file:_files'
|
'(-o --output)'{-o,--output}'+[Set output file]:output file:_files'
|
||||||
'(-p --palette -P --auto-palette)'{-p,--palette}"+[Output the image's palette in little-endian native RGB555 format]:palette file:_files"
|
'(-p --palette -P --output-palette)'{-p,--palette}"+[Output the image's palette in little-endian native RGB555 format]:palette file:_files"
|
||||||
'(-q --palette-map -Q --auto-palette-map)'{-q,--palette-map}"+[Output the image's palette map]:palette map file:_files"
|
'(-t --tilemap -T --output-tilemap)'{-t,--tilemap}'+[Generate a map of tile indices]:tilemap file:_files'
|
||||||
'(-r --reverse)'{-r,--reverse}'+[Yield an image from binary data]:image width (in tiles):'
|
|
||||||
'(-s --palette-size)'{-s,--palette-size}'+[Limit palette size]:palette size:'
|
|
||||||
'(-t --tilemap -T --auto-tilemap)'{-t,--tilemap}'+[Generate a map of tile indices]:tilemap file:_files'
|
|
||||||
'(-W --warning)'{-W,--warning}'+[Toggle warning flags]:warning flag:_rgbgfx_warnings'
|
|
||||||
'(-x --trim-end)'{-x,--trim-end}'+[Trim end of output by this many tiles]:tile count:'
|
'(-x --trim-end)'{-x,--trim-end}'+[Trim end of output by this many tiles]:tile count:'
|
||||||
|
|
||||||
":input png file:_files -g '*.png'"
|
":input png file:_files -g '*.png'"
|
||||||
|
|||||||
@@ -1,26 +1,8 @@
|
|||||||
#compdef rgblink
|
#compdef rgblink
|
||||||
|
|
||||||
_rgblink_warnings() {
|
|
||||||
local warnings=(
|
|
||||||
'error:Turn all warnings into errors'
|
|
||||||
|
|
||||||
'all:Enable most warning messages'
|
|
||||||
'everything:Enable literally everything'
|
|
||||||
|
|
||||||
'assert:Warn when WARN-type asserts fail'
|
|
||||||
'div:Warn when dividing the smallest int by -1'
|
|
||||||
'obsolete:Warn when using deprecated features'
|
|
||||||
'shift:Warn when shifting negative values'
|
|
||||||
'shift-amount:Warn when a shift'\''s operand is negative or \> 32'
|
|
||||||
'truncation:Warn when implicit truncation loses bits'
|
|
||||||
)
|
|
||||||
_describe warning warnings
|
|
||||||
}
|
|
||||||
|
|
||||||
local args=(
|
local args=(
|
||||||
# Arguments are listed here in the same order as in the manual, except for the version and help
|
# Arguments are listed here in the same order as in the manual, except for the version
|
||||||
'(- : * options)'{-V,--version}'[Print version number and exit]'
|
'(- : * options)'{-V,--version}'[Print version number]'
|
||||||
'(- : * options)'{-h,--help}'[Print help text and exit]'
|
|
||||||
|
|
||||||
'(-d --dmg)'{-d,--dmg}'[Enable DMG mode (-w + no VRAM banking)]'
|
'(-d --dmg)'{-d,--dmg}'[Enable DMG mode (-w + no VRAM banking)]'
|
||||||
'(-t --tiny)'{-t,--tiny}'[Enable tiny mode, disabling ROM banking]'
|
'(-t --tiny)'{-t,--tiny}'[Enable tiny mode, disabling ROM banking]'
|
||||||
@@ -28,17 +10,14 @@ local args=(
|
|||||||
'(-w --wramx)'{-w,--wramx}'[Disable WRAM banking]'
|
'(-w --wramx)'{-w,--wramx}'[Disable WRAM banking]'
|
||||||
'(-x --nopad)'{-x,--nopad}'[Disable padding the end of the final file]'
|
'(-x --nopad)'{-x,--nopad}'[Disable padding the end of the final file]'
|
||||||
|
|
||||||
'(-B --backtrace)'{-B,--backtrace}'+[Set backtrace depth or style]:param:'
|
|
||||||
--color'[Whether to use color in output]:color:(auto always never)'
|
|
||||||
'(-l --linkerscript)'{-l,--linkerscript}"+[Use a linker script]:linker script:_files -g '*.link'"
|
'(-l --linkerscript)'{-l,--linkerscript}"+[Use a linker script]:linker script:_files -g '*.link'"
|
||||||
'(-M --no-sym-in-map)'{-M,--no-sym-in-map}'[Do not output symbol names in map file]'
|
|
||||||
'(-m --map)'{-m,--map}"+[Produce a map file]:map file:_files -g '*.map'"
|
'(-m --map)'{-m,--map}"+[Produce a map file]:map file:_files -g '*.map'"
|
||||||
'(-n --sym)'(-n,--sym)"+[Produce a symbol file]:sym file:_files -g '*.sym'"
|
'(-n --sym)'(-n,--sym)"+[Produce a symbol file]:sym file:_files -g '*.sym'"
|
||||||
'(-O --overlay)'{-O,--overlay}'+[Overlay sections over on top of bin file]:base overlay:_files'
|
'(-O --overlay)'{-O,--overlay}'+[Overlay sections over on top of bin file]:base overlay:_files'
|
||||||
'(-o --output)'{-o,--output}"+[Write ROM image to this file]:rom file:_files -g '*.{gb,sgb,gbc}'"
|
'(-o --output)'{-o,--output}"+[Write ROM image to this file]:rom file:_files -g '*.{gb,sgb,gbc}'"
|
||||||
'(-p --pad-value)'{-p,--pad-value}'+[Set padding byte]:padding byte:'
|
'(-p --pad-value)'{-p,--pad-value}'+[Set padding byte]:padding byte:'
|
||||||
'(-S --scramble)'{-s,--scramble}'+[Activate scrambling]:scramble spec'
|
'(-S --scramble)'{-s,--scramble}'+[Activate scrambling]:scramble spec'
|
||||||
'(-W --warning)'{-W,--warning}'+[Toggle warning flags]:warning flag:_rgblink_warnings'
|
'(-s --smart)'{-s,--smart}'+[!BROKEN! Perform smart linking from this symbol]:symbol name:'
|
||||||
|
|
||||||
'*'":object files:_files -g '*.o'"
|
'*'":object files:_files -g '*.o'"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,61 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#ifndef RGBDS_ASM_ACTIONS_HPP
|
|
||||||
#define RGBDS_ASM_ACTIONS_HPP
|
|
||||||
|
|
||||||
#include <optional>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string>
|
|
||||||
#include <string_view>
|
|
||||||
#include <variant>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "linkdefs.hpp" // AssertionType, RPNCommand
|
|
||||||
|
|
||||||
#include "asm/rpn.hpp" // Expression
|
|
||||||
|
|
||||||
struct AlignmentSpec {
|
|
||||||
uint8_t alignment;
|
|
||||||
uint16_t alignOfs;
|
|
||||||
};
|
|
||||||
|
|
||||||
void act_If(int32_t condition);
|
|
||||||
void act_Elif(int32_t condition);
|
|
||||||
void act_Else();
|
|
||||||
void act_Endc();
|
|
||||||
|
|
||||||
AlignmentSpec act_Alignment(int32_t alignment, int32_t alignOfs);
|
|
||||||
|
|
||||||
void act_Assert(AssertionType type, Expression const &expr, std::string const &message);
|
|
||||||
void act_StaticAssert(AssertionType type, int32_t condition, std::string const &message);
|
|
||||||
|
|
||||||
std::optional<std::string> act_ReadFile(std::string const &name, uint32_t maxLen);
|
|
||||||
|
|
||||||
uint32_t act_CharToNum(std::string const &str);
|
|
||||||
uint32_t act_StringToNum(std::string const &str);
|
|
||||||
|
|
||||||
int32_t act_CharVal(std::string const &str);
|
|
||||||
int32_t act_CharVal(std::string const &str, int32_t negIdx);
|
|
||||||
uint8_t act_StringByte(std::string const &str, int32_t negIdx);
|
|
||||||
|
|
||||||
size_t act_StringLen(std::string const &str, bool printErrors);
|
|
||||||
std::string
|
|
||||||
act_StringSlice(std::string const &str, int32_t negStart, std::optional<int32_t> negStop);
|
|
||||||
std::string act_StringSub(std::string const &str, int32_t negPos, std::optional<uint32_t> optLen);
|
|
||||||
|
|
||||||
size_t act_CharLen(std::string const &str);
|
|
||||||
std::string act_StringChar(std::string const &str, int32_t negIdx);
|
|
||||||
std::string act_CharSub(std::string const &str, int32_t negPos);
|
|
||||||
int32_t act_CharCmp(std::string_view str1, std::string_view str2);
|
|
||||||
|
|
||||||
std::string act_StringReplace(std::string_view str, std::string const &old, std::string const &rep);
|
|
||||||
std::string act_StringFormat(
|
|
||||||
std::string const &spec, std::vector<std::variant<uint32_t, std::string>> const &args
|
|
||||||
);
|
|
||||||
|
|
||||||
std::string act_SectionName(std::string const &symName);
|
|
||||||
|
|
||||||
void act_CompoundAssignment(std::string const &symName, RPNCommand op, int32_t constValue);
|
|
||||||
|
|
||||||
#endif // RGBDS_ASM_ACTIONS_HPP
|
|
||||||
23
include/asm/charmap.h
Normal file
23
include/asm/charmap.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of RGBDS.
|
||||||
|
*
|
||||||
|
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RGBDS_ASM_CHARMAP_H
|
||||||
|
#define RGBDS_ASM_CHARMAP_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
struct Charmap *charmap_New(char const *name, char const *baseName);
|
||||||
|
void charmap_Delete(struct Charmap *charmap);
|
||||||
|
void charmap_Set(char const *name);
|
||||||
|
void charmap_Push(void);
|
||||||
|
void charmap_Pop(void);
|
||||||
|
void charmap_Add(char *mapping, uint8_t value);
|
||||||
|
size_t charmap_Convert(char const *input, uint8_t *output);
|
||||||
|
size_t charmap_ConvertNext(char const **input, uint8_t **output);
|
||||||
|
|
||||||
|
#endif /* RGBDS_ASM_CHARMAP_H */
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#ifndef RGBDS_ASM_CHARMAP_HPP
|
|
||||||
#define RGBDS_ASM_CHARMAP_HPP
|
|
||||||
|
|
||||||
#include <optional>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string>
|
|
||||||
#include <string_view>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#define DEFAULT_CHARMAP_NAME "main"
|
|
||||||
|
|
||||||
bool charmap_ForEach(
|
|
||||||
void (*mapFunc)(std::string const &),
|
|
||||||
void (*charFunc)(std::string const &, std::vector<int32_t>)
|
|
||||||
);
|
|
||||||
void charmap_New(std::string const &name, std::string const *baseName);
|
|
||||||
void charmap_Set(std::string const &name);
|
|
||||||
void charmap_Push();
|
|
||||||
void charmap_Pop();
|
|
||||||
void charmap_CheckStack();
|
|
||||||
void charmap_Add(std::string const &mapping, std::vector<int32_t> &&value);
|
|
||||||
bool charmap_HasChar(std::string const &mapping);
|
|
||||||
size_t charmap_CharSize(std::string const &mapping);
|
|
||||||
std::optional<int32_t> charmap_CharValue(std::string const &mapping, size_t idx);
|
|
||||||
std::vector<int32_t> charmap_Convert(std::string const &input);
|
|
||||||
size_t charmap_ConvertNext(std::string_view &input, std::vector<int32_t> *output);
|
|
||||||
std::string charmap_Reverse(std::vector<int32_t> const &value, bool &unique);
|
|
||||||
|
|
||||||
#endif // RGBDS_ASM_CHARMAP_HPP
|
|
||||||
31
include/asm/fixpoint.h
Normal file
31
include/asm/fixpoint.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of RGBDS.
|
||||||
|
*
|
||||||
|
* Copyright (c) 1997-2021, Carsten Sorensen and RGBDS contributors.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RGBDS_ASM_FIXPOINT_H
|
||||||
|
#define RGBDS_ASM_FIXPOINT_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
int32_t fix_Callback_PI(void);
|
||||||
|
void fix_Print(int32_t i);
|
||||||
|
int32_t fix_Sin(int32_t i);
|
||||||
|
int32_t fix_Cos(int32_t i);
|
||||||
|
int32_t fix_Tan(int32_t i);
|
||||||
|
int32_t fix_ASin(int32_t i);
|
||||||
|
int32_t fix_ACos(int32_t i);
|
||||||
|
int32_t fix_ATan(int32_t i);
|
||||||
|
int32_t fix_ATan2(int32_t i, int32_t j);
|
||||||
|
int32_t fix_Mul(int32_t i, int32_t j);
|
||||||
|
int32_t fix_Div(int32_t i, int32_t j);
|
||||||
|
int32_t fix_Pow(int32_t i, int32_t j);
|
||||||
|
int32_t fix_Log(int32_t i, int32_t j);
|
||||||
|
int32_t fix_Round(int32_t i);
|
||||||
|
int32_t fix_Ceil(int32_t i);
|
||||||
|
int32_t fix_Floor(int32_t i);
|
||||||
|
|
||||||
|
#endif /* RGBDS_ASM_FIXPOINT_H */
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#ifndef RGBDS_ASM_FIXPOINT_HPP
|
|
||||||
#define RGBDS_ASM_FIXPOINT_HPP
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
int32_t fix_Sin(int32_t i, int32_t q);
|
|
||||||
int32_t fix_Cos(int32_t i, int32_t q);
|
|
||||||
int32_t fix_Tan(int32_t i, int32_t q);
|
|
||||||
int32_t fix_ASin(int32_t i, int32_t q);
|
|
||||||
int32_t fix_ACos(int32_t i, int32_t q);
|
|
||||||
int32_t fix_ATan(int32_t i, int32_t q);
|
|
||||||
int32_t fix_ATan2(int32_t i, int32_t j, int32_t q);
|
|
||||||
int32_t fix_Mul(int32_t i, int32_t j, int32_t q);
|
|
||||||
int32_t fix_Mod(int32_t i, int32_t j, int32_t q);
|
|
||||||
int32_t fix_Div(int32_t i, int32_t j, int32_t q);
|
|
||||||
int32_t fix_Pow(int32_t i, int32_t j, int32_t q);
|
|
||||||
int32_t fix_Log(int32_t i, int32_t j, int32_t q);
|
|
||||||
int32_t fix_Round(int32_t i, int32_t q);
|
|
||||||
int32_t fix_Ceil(int32_t i, int32_t q);
|
|
||||||
int32_t fix_Floor(int32_t i, int32_t q);
|
|
||||||
|
|
||||||
#endif // RGBDS_ASM_FIXPOINT_HPP
|
|
||||||
63
include/asm/format.h
Normal file
63
include/asm/format.h
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of RGBDS.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020, RGBDS contributors.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RGBDS_FORMAT_SPEC_H
|
||||||
|
#define RGBDS_FORMAT_SPEC_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
enum FormatState {
|
||||||
|
FORMAT_SIGN, // expects '+' or ' ' (optional)
|
||||||
|
FORMAT_PREFIX, // expects '#' (optional)
|
||||||
|
FORMAT_ALIGN, // expects '-' (optional)
|
||||||
|
FORMAT_WIDTH, // expects '0'-'9', max 255 (optional) (leading '0' indicates pad)
|
||||||
|
FORMAT_FRAC, // got '.', expects '0'-'9', max 255 (optional)
|
||||||
|
FORMAT_DONE, // got [duXxbofs] (required)
|
||||||
|
FORMAT_INVALID, // got unexpected character
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FormatSpec {
|
||||||
|
enum FormatState state;
|
||||||
|
int sign;
|
||||||
|
bool prefix;
|
||||||
|
bool alignLeft;
|
||||||
|
bool padZero;
|
||||||
|
size_t width;
|
||||||
|
bool hasFrac;
|
||||||
|
size_t fracWidth;
|
||||||
|
int type;
|
||||||
|
bool valid;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct StrFmtArg {
|
||||||
|
union {
|
||||||
|
uint32_t number;
|
||||||
|
char *string;
|
||||||
|
};
|
||||||
|
bool isNumeric;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define INITIAL_STRFMT_ARG_SIZE 4
|
||||||
|
struct StrFmtArgList {
|
||||||
|
char *format;
|
||||||
|
size_t nbArgs;
|
||||||
|
size_t capacity;
|
||||||
|
struct StrFmtArg *args;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FormatSpec fmt_NewSpec(void);
|
||||||
|
bool fmt_IsEmpty(struct FormatSpec const *fmt);
|
||||||
|
bool fmt_IsValid(struct FormatSpec const *fmt);
|
||||||
|
bool fmt_IsFinished(struct FormatSpec const *fmt);
|
||||||
|
void fmt_UseCharacter(struct FormatSpec *fmt, int c);
|
||||||
|
void fmt_FinishCharacters(struct FormatSpec *fmt);
|
||||||
|
void fmt_PrintString(char *buf, size_t bufLen, struct FormatSpec const *fmt, char const *value);
|
||||||
|
void fmt_PrintNumber(char *buf, size_t bufLen, struct FormatSpec const *fmt, uint32_t value);
|
||||||
|
|
||||||
|
#endif /* RGBDS_FORMAT_SPEC_H */
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#ifndef RGBDS_ASM_FORMAT_HPP
|
|
||||||
#define RGBDS_ASM_FORMAT_HPP
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
class FormatSpec {
|
|
||||||
int sign;
|
|
||||||
bool exact;
|
|
||||||
bool alignLeft;
|
|
||||||
bool padZero;
|
|
||||||
size_t width;
|
|
||||||
bool hasFrac;
|
|
||||||
size_t fracWidth;
|
|
||||||
bool hasPrec;
|
|
||||||
size_t precision;
|
|
||||||
int type;
|
|
||||||
bool parsed;
|
|
||||||
|
|
||||||
public:
|
|
||||||
bool isValid() const { return !!type; }
|
|
||||||
bool isParsed() const { return parsed; }
|
|
||||||
|
|
||||||
size_t parseSpec(char const *spec);
|
|
||||||
|
|
||||||
void appendString(std::string &str, std::string const &value) const;
|
|
||||||
void appendNumber(std::string &str, uint32_t value) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // RGBDS_ASM_FORMAT_HPP
|
|
||||||
83
include/asm/fstack.h
Normal file
83
include/asm/fstack.h
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of RGBDS.
|
||||||
|
*
|
||||||
|
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Contains some assembler-wide defines and externs
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RGBDS_ASM_FSTACK_H
|
||||||
|
#define RGBDS_ASM_FSTACK_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "asm/lexer.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct FileStackNode {
|
||||||
|
struct FileStackNode *parent; /* Pointer to parent node, for error reporting */
|
||||||
|
/* Line at which the parent context was exited; meaningless for the root level */
|
||||||
|
uint32_t lineNo;
|
||||||
|
|
||||||
|
struct FileStackNode *next; /* Next node in the output linked list */
|
||||||
|
bool referenced; /* If referenced, don't free! */
|
||||||
|
uint32_t ID; /* Set only if referenced: ID within the object file, -1 if not output yet */
|
||||||
|
|
||||||
|
enum {
|
||||||
|
NODE_REPT,
|
||||||
|
NODE_FILE,
|
||||||
|
NODE_MACRO,
|
||||||
|
} type;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FileStackReptNode { /* NODE_REPT */
|
||||||
|
struct FileStackNode node;
|
||||||
|
uint32_t reptDepth;
|
||||||
|
/* WARNING: if changing this type, change overflow check in `fstk_Init` */
|
||||||
|
uint32_t iters[]; /* REPT iteration counts since last named node, in reverse depth order */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FileStackNamedNode { /* NODE_FILE, NODE_MACRO */
|
||||||
|
struct FileStackNode node;
|
||||||
|
char name[]; /* File name for files, file::macro name for macros */
|
||||||
|
};
|
||||||
|
|
||||||
|
extern size_t maxRecursionDepth;
|
||||||
|
|
||||||
|
struct MacroArgs;
|
||||||
|
|
||||||
|
void fstk_Dump(struct FileStackNode const *node, uint32_t lineNo);
|
||||||
|
void fstk_DumpCurrent(void);
|
||||||
|
struct FileStackNode *fstk_GetFileStack(void);
|
||||||
|
/* The lifetime of the returned chars is until reaching the end of that file */
|
||||||
|
char const *fstk_GetFileName(void);
|
||||||
|
|
||||||
|
void fstk_AddIncludePath(char const *s);
|
||||||
|
/**
|
||||||
|
* @param path The user-provided file name
|
||||||
|
* @param fullPath The address of a pointer, which will be made to point at the full path
|
||||||
|
* The pointer's value must be a valid argument to `realloc`, including NULL
|
||||||
|
* @param size Current size of the buffer, or 0 if the pointer is NULL
|
||||||
|
* @return True if the file was found, false if no path worked
|
||||||
|
*/
|
||||||
|
bool fstk_FindFile(char const *path, char **fullPath, size_t *size);
|
||||||
|
|
||||||
|
bool yywrap(void);
|
||||||
|
void fstk_RunInclude(char const *path);
|
||||||
|
void fstk_RunMacro(char const *macroName, struct MacroArgs *args);
|
||||||
|
void fstk_RunRept(uint32_t count, int32_t reptLineNo, char *body, size_t size);
|
||||||
|
void fstk_RunFor(char const *symName, int32_t start, int32_t stop, int32_t step,
|
||||||
|
int32_t reptLineNo, char *body, size_t size);
|
||||||
|
void fstk_StopRept(void);
|
||||||
|
bool fstk_Break(void);
|
||||||
|
|
||||||
|
void fstk_NewRecursionDepth(size_t newDepth);
|
||||||
|
void fstk_Init(char const *mainPath, size_t maxDepth);
|
||||||
|
|
||||||
|
#endif /* RGBDS_ASM_FSTACK_H */
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
// Contains some assembler-wide defines and externs
|
|
||||||
|
|
||||||
#ifndef RGBDS_ASM_FSTACK_HPP
|
|
||||||
#define RGBDS_ASM_FSTACK_HPP
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <optional>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string>
|
|
||||||
#include <variant>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "linkdefs.hpp"
|
|
||||||
|
|
||||||
#include "asm/lexer.hpp"
|
|
||||||
|
|
||||||
struct FileStackNode {
|
|
||||||
FileStackNodeType type;
|
|
||||||
std::variant<
|
|
||||||
std::vector<uint32_t>, // NODE_REPT
|
|
||||||
std::string // NODE_FILE, NODE_MACRO
|
|
||||||
>
|
|
||||||
data;
|
|
||||||
bool isQuiet; // Whether to omit this node from error reporting
|
|
||||||
|
|
||||||
std::shared_ptr<FileStackNode> parent; // Pointer to parent node, for error reporting
|
|
||||||
// Line at which the parent context was exited
|
|
||||||
// Meaningless at the root level, but gets written to the object file anyway, so init it
|
|
||||||
uint32_t lineNo = 0;
|
|
||||||
|
|
||||||
// Set only if referenced: ID within the object file, `UINT32_MAX` if not output yet
|
|
||||||
uint32_t ID = UINT32_MAX;
|
|
||||||
|
|
||||||
// REPT iteration counts since last named node, in reverse depth order
|
|
||||||
std::vector<uint32_t> &iters() { return std::get<std::vector<uint32_t>>(data); }
|
|
||||||
std::vector<uint32_t> const &iters() const { return std::get<std::vector<uint32_t>>(data); }
|
|
||||||
// File name for files, file::macro name for macros
|
|
||||||
std::string &name() { return std::get<std::string>(data); }
|
|
||||||
std::string const &name() const { return std::get<std::string>(data); }
|
|
||||||
|
|
||||||
FileStackNode(
|
|
||||||
FileStackNodeType type_,
|
|
||||||
std::variant<std::vector<uint32_t>, std::string> data_,
|
|
||||||
bool isQuiet_
|
|
||||||
)
|
|
||||||
: type(type_), data(data_), isQuiet(isQuiet_) {}
|
|
||||||
|
|
||||||
void printBacktrace(uint32_t curLineNo) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MacroArgs;
|
|
||||||
|
|
||||||
void fstk_VerboseOutputConfig();
|
|
||||||
|
|
||||||
void fstk_TraceCurrent();
|
|
||||||
std::shared_ptr<FileStackNode> fstk_GetFileStack();
|
|
||||||
std::shared_ptr<std::string> fstk_GetUniqueIDStr();
|
|
||||||
MacroArgs *fstk_GetCurrentMacroArgs();
|
|
||||||
|
|
||||||
void fstk_AddIncludePath(std::string const &path);
|
|
||||||
void fstk_AddPreIncludeFile(std::string const &path);
|
|
||||||
std::optional<std::string> fstk_FindFile(std::string const &path);
|
|
||||||
bool fstk_FileError(std::string const &path, char const *functionName);
|
|
||||||
bool fstk_FailedOnMissingInclude();
|
|
||||||
|
|
||||||
bool yywrap();
|
|
||||||
bool fstk_RunInclude(std::string const &path, bool isQuiet);
|
|
||||||
void fstk_RunMacro(
|
|
||||||
std::string const ¯oName, std::shared_ptr<MacroArgs> macroArgs, bool isQuiet
|
|
||||||
);
|
|
||||||
void fstk_RunRept(uint32_t count, int32_t reptLineNo, ContentSpan const &span, bool isQuiet);
|
|
||||||
void fstk_RunFor(
|
|
||||||
std::string const &symName,
|
|
||||||
int32_t start,
|
|
||||||
int32_t stop,
|
|
||||||
int32_t step,
|
|
||||||
int32_t reptLineNo,
|
|
||||||
ContentSpan const &span,
|
|
||||||
bool isQuiet
|
|
||||||
);
|
|
||||||
bool fstk_Break();
|
|
||||||
|
|
||||||
void fstk_NewRecursionDepth(size_t newDepth);
|
|
||||||
void fstk_Init(std::string const &mainPath);
|
|
||||||
|
|
||||||
#endif // RGBDS_ASM_FSTACK_HPP
|
|
||||||
102
include/asm/lexer.h
Normal file
102
include/asm/lexer.h
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of RGBDS.
|
||||||
|
*
|
||||||
|
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RGBDS_ASM_LEXER_H
|
||||||
|
#define RGBDS_ASM_LEXER_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#define MAXSTRLEN 255
|
||||||
|
|
||||||
|
struct LexerState;
|
||||||
|
extern struct LexerState *lexerState;
|
||||||
|
extern struct LexerState *lexerStateEOL;
|
||||||
|
|
||||||
|
static inline struct LexerState *lexer_GetState(void)
|
||||||
|
{
|
||||||
|
return lexerState;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void lexer_SetState(struct LexerState *state)
|
||||||
|
{
|
||||||
|
lexerState = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void lexer_SetStateAtEOL(struct LexerState *state)
|
||||||
|
{
|
||||||
|
lexerStateEOL = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern char binDigits[2];
|
||||||
|
extern char gfxDigits[4];
|
||||||
|
|
||||||
|
static inline void lexer_SetBinDigits(char const digits[2])
|
||||||
|
{
|
||||||
|
binDigits[0] = digits[0];
|
||||||
|
binDigits[1] = digits[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void lexer_SetGfxDigits(char const digits[4])
|
||||||
|
{
|
||||||
|
gfxDigits[0] = digits[0];
|
||||||
|
gfxDigits[1] = digits[1];
|
||||||
|
gfxDigits[2] = digits[2];
|
||||||
|
gfxDigits[3] = digits[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* `path` is referenced, but not held onto..!
|
||||||
|
*/
|
||||||
|
struct LexerState *lexer_OpenFile(char const *path);
|
||||||
|
struct LexerState *lexer_OpenFileView(char const *path, char *buf, size_t size, uint32_t lineNo);
|
||||||
|
void lexer_RestartRept(uint32_t lineNo);
|
||||||
|
void lexer_DeleteState(struct LexerState *state);
|
||||||
|
void lexer_Init(void);
|
||||||
|
|
||||||
|
enum LexerMode {
|
||||||
|
LEXER_NORMAL,
|
||||||
|
LEXER_RAW,
|
||||||
|
LEXER_SKIP_TO_ELIF,
|
||||||
|
LEXER_SKIP_TO_ENDC,
|
||||||
|
LEXER_SKIP_TO_ENDR
|
||||||
|
};
|
||||||
|
|
||||||
|
void lexer_SetMode(enum LexerMode mode);
|
||||||
|
void lexer_ToggleStringExpansion(bool enable);
|
||||||
|
|
||||||
|
uint32_t lexer_GetIFDepth(void);
|
||||||
|
void lexer_IncIFDepth(void);
|
||||||
|
void lexer_DecIFDepth(void);
|
||||||
|
bool lexer_RanIFBlock(void);
|
||||||
|
bool lexer_ReachedELSEBlock(void);
|
||||||
|
void lexer_RunIFBlock(void);
|
||||||
|
void lexer_ReachELSEBlock(void);
|
||||||
|
|
||||||
|
struct CaptureBody {
|
||||||
|
uint32_t lineNo;
|
||||||
|
char *body;
|
||||||
|
size_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
void lexer_CheckRecursionDepth(void);
|
||||||
|
char const *lexer_GetFileName(void);
|
||||||
|
uint32_t lexer_GetLineNo(void);
|
||||||
|
uint32_t lexer_GetColNo(void);
|
||||||
|
void lexer_DumpStringExpansions(void);
|
||||||
|
int yylex(void);
|
||||||
|
bool lexer_CaptureRept(struct CaptureBody *capture);
|
||||||
|
bool lexer_CaptureMacroBody(struct CaptureBody *capture);
|
||||||
|
|
||||||
|
#define INITIAL_DS_ARG_SIZE 2
|
||||||
|
struct DsArgList {
|
||||||
|
size_t nbArgs;
|
||||||
|
size_t capacity;
|
||||||
|
struct Expression *args;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* RGBDS_ASM_LEXER_H */
|
||||||
@@ -1,147 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#ifndef RGBDS_ASM_LEXER_HPP
|
|
||||||
#define RGBDS_ASM_LEXER_HPP
|
|
||||||
|
|
||||||
#include <deque>
|
|
||||||
#include <memory>
|
|
||||||
#include <optional>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string>
|
|
||||||
#include <variant>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "platform.hpp" // SSIZE_MAX
|
|
||||||
|
|
||||||
// This value is a compromise between `LexerState` allocation performance when reading the entire
|
|
||||||
// file works, and buffering performance when it doesn't (e.g. when piping a file into RGBASM).
|
|
||||||
static constexpr size_t LEXER_BUF_SIZE = 64;
|
|
||||||
// The buffer needs to be large enough for the maximum `lexerState->peek()` lookahead distance
|
|
||||||
static_assert(LEXER_BUF_SIZE > 1, "Lexer buffer size is too small");
|
|
||||||
// This caps the size of buffer reads, and according to POSIX, passing more than SSIZE_MAX is UB
|
|
||||||
static_assert(LEXER_BUF_SIZE <= SSIZE_MAX, "Lexer buffer size is too large");
|
|
||||||
|
|
||||||
enum LexerMode {
|
|
||||||
LEXER_NORMAL,
|
|
||||||
LEXER_RAW,
|
|
||||||
LEXER_SKIP_TO_ELIF,
|
|
||||||
LEXER_SKIP_TO_ENDC,
|
|
||||||
LEXER_SKIP_TO_ENDR,
|
|
||||||
NB_LEXER_MODES
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Expansion {
|
|
||||||
std::optional<std::string> name;
|
|
||||||
std::shared_ptr<std::string> contents;
|
|
||||||
size_t offset; // Cursor into `contents`
|
|
||||||
|
|
||||||
size_t size() const { return contents->size(); }
|
|
||||||
bool advance(); // Increment `offset`; return whether it then exceeds `contents`
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ContentSpan {
|
|
||||||
std::shared_ptr<char[]> ptr;
|
|
||||||
size_t size;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ViewedContent {
|
|
||||||
ContentSpan span; // Span of chars
|
|
||||||
size_t offset = 0; // Cursor into `span.ptr`
|
|
||||||
|
|
||||||
ViewedContent(ContentSpan const &span_) : span(span_) {}
|
|
||||||
ViewedContent(std::shared_ptr<char[]> ptr, size_t size) : span({.ptr = ptr, .size = size}) {}
|
|
||||||
|
|
||||||
std::shared_ptr<char[]> makeSharedContentPtr() const {
|
|
||||||
return std::shared_ptr<char[]>(span.ptr, &span.ptr[offset]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct BufferedContent {
|
|
||||||
int fd; // File from which to read chars
|
|
||||||
char buf[LEXER_BUF_SIZE] = {}; // Circular buffer of chars
|
|
||||||
size_t offset = 0; // Cursor into `buf`
|
|
||||||
size_t size = 0; // Number of "fresh" chars in `buf`
|
|
||||||
|
|
||||||
BufferedContent(int fd_) : fd(fd_) {}
|
|
||||||
~BufferedContent();
|
|
||||||
|
|
||||||
void advance(); // Increment `offset` circularly, decrement `size`
|
|
||||||
void refill(); // Read from `fd` to fill `buf`
|
|
||||||
|
|
||||||
private:
|
|
||||||
size_t readMore(size_t startIndex, size_t nbChars);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct IfStackEntry {
|
|
||||||
bool ranIfBlock; // Whether an IF/ELIF/ELSE block ran already
|
|
||||||
bool reachedElseBlock; // Whether an ELSE block ran already
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LexerState {
|
|
||||||
std::string path;
|
|
||||||
|
|
||||||
LexerMode mode;
|
|
||||||
bool atLineStart;
|
|
||||||
uint32_t lineNo;
|
|
||||||
int lastToken;
|
|
||||||
int nextToken;
|
|
||||||
|
|
||||||
std::deque<IfStackEntry> ifStack;
|
|
||||||
|
|
||||||
bool capturing; // Whether the text being lexed should be captured
|
|
||||||
size_t captureSize; // Amount of text captured
|
|
||||||
std::shared_ptr<std::vector<char>> captureBuf; // Buffer to send the captured text to if set
|
|
||||||
|
|
||||||
bool disableExpansions;
|
|
||||||
size_t expansionScanDistance; // Max distance already scanned for expansions
|
|
||||||
bool expandStrings;
|
|
||||||
std::deque<Expansion> expansions; // Front is the innermost current expansion
|
|
||||||
|
|
||||||
std::variant<std::monostate, ViewedContent, BufferedContent> content;
|
|
||||||
|
|
||||||
~LexerState();
|
|
||||||
|
|
||||||
int peekChar();
|
|
||||||
int peekCharAhead();
|
|
||||||
|
|
||||||
std::shared_ptr<char[]> makeSharedCaptureBufPtr() const {
|
|
||||||
return std::shared_ptr<char[]>(captureBuf, captureBuf->data());
|
|
||||||
}
|
|
||||||
|
|
||||||
void setAsCurrentState();
|
|
||||||
void setFileAsNextState(std::string const &filePath, bool updateStateNow);
|
|
||||||
void setViewAsNextState(char const *name, ContentSpan const &span, uint32_t lineNo_);
|
|
||||||
|
|
||||||
void clear(uint32_t lineNo_);
|
|
||||||
};
|
|
||||||
|
|
||||||
void lexer_SetBinDigits(char const digits[2]);
|
|
||||||
void lexer_SetGfxDigits(char const digits[4]);
|
|
||||||
|
|
||||||
bool lexer_AtTopLevel();
|
|
||||||
void lexer_RestartRept(uint32_t lineNo);
|
|
||||||
void lexer_SetMode(LexerMode mode);
|
|
||||||
void lexer_ToggleStringExpansion(bool enable);
|
|
||||||
|
|
||||||
uint32_t lexer_GetIFDepth();
|
|
||||||
void lexer_IncIFDepth();
|
|
||||||
void lexer_DecIFDepth();
|
|
||||||
bool lexer_RanIFBlock();
|
|
||||||
bool lexer_ReachedELSEBlock();
|
|
||||||
void lexer_RunIFBlock();
|
|
||||||
void lexer_ReachELSEBlock();
|
|
||||||
|
|
||||||
void lexer_CheckRecursionDepth();
|
|
||||||
uint32_t lexer_GetLineNo();
|
|
||||||
void lexer_TraceStringExpansions();
|
|
||||||
|
|
||||||
struct Capture {
|
|
||||||
uint32_t lineNo;
|
|
||||||
ContentSpan span;
|
|
||||||
};
|
|
||||||
|
|
||||||
Capture lexer_CaptureRept();
|
|
||||||
Capture lexer_CaptureMacro();
|
|
||||||
|
|
||||||
#endif // RGBDS_ASM_LEXER_HPP
|
|
||||||
37
include/asm/macro.h
Normal file
37
include/asm/macro.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of RGBDS.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020, Carsten Sorensen and RGBDS contributors.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RGBDS_MACRO_H
|
||||||
|
#define RGBDS_MACRO_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "asm/warning.h"
|
||||||
|
|
||||||
|
#include "helpers.h"
|
||||||
|
|
||||||
|
struct MacroArgs;
|
||||||
|
|
||||||
|
struct MacroArgs *macro_GetCurrentArgs(void);
|
||||||
|
struct MacroArgs *macro_NewArgs(void);
|
||||||
|
void macro_AppendArg(struct MacroArgs **args, char *s);
|
||||||
|
void macro_UseNewArgs(struct MacroArgs *args);
|
||||||
|
void macro_FreeArgs(struct MacroArgs *args);
|
||||||
|
char const *macro_GetArg(uint32_t i);
|
||||||
|
char const *macro_GetAllArgs(void);
|
||||||
|
|
||||||
|
uint32_t macro_GetUniqueID(void);
|
||||||
|
char const *macro_GetUniqueIDStr(void);
|
||||||
|
void macro_SetUniqueID(uint32_t id);
|
||||||
|
uint32_t macro_UseNewUniqueID(void);
|
||||||
|
void macro_ShiftCurrentArgs(int32_t count);
|
||||||
|
uint32_t macro_NbArgs(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#ifndef RGBDS_ASM_MACRO_HPP
|
|
||||||
#define RGBDS_ASM_MACRO_HPP
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
struct MacroArgs {
|
|
||||||
uint32_t shift;
|
|
||||||
std::vector<std::shared_ptr<std::string>> args;
|
|
||||||
|
|
||||||
uint32_t nbArgs() const { return args.size() - shift; }
|
|
||||||
std::shared_ptr<std::string> getArg(int32_t i) const;
|
|
||||||
std::shared_ptr<std::string> getAllArgs() const;
|
|
||||||
|
|
||||||
void appendArg(std::shared_ptr<std::string> arg);
|
|
||||||
void shiftArgs(int32_t count);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // RGBDS_ASM_MACRO_HPP
|
|
||||||
29
include/asm/main.h
Normal file
29
include/asm/main.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of RGBDS.
|
||||||
|
*
|
||||||
|
* Copyright (c) 1997-2021, Carsten Sorensen and RGBDS contributors.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RGBDS_MAIN_H
|
||||||
|
#define RGBDS_MAIN_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "helpers.h"
|
||||||
|
|
||||||
|
extern bool haltnop;
|
||||||
|
extern bool optimizeLoads;
|
||||||
|
extern bool verbose;
|
||||||
|
extern bool warnings; /* True to enable warnings, false to disable them. */
|
||||||
|
|
||||||
|
extern FILE *dependfile;
|
||||||
|
extern char *targetFileName;
|
||||||
|
extern bool generatedMissingIncludes;
|
||||||
|
extern bool failedOnMissingInclude;
|
||||||
|
extern bool generatePhonyDeps;
|
||||||
|
|
||||||
|
#endif /* RGBDS_MAIN_H */
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#ifndef RGBDS_ASM_MAIN_HPP
|
|
||||||
#define RGBDS_ASM_MAIN_HPP
|
|
||||||
|
|
||||||
#include <optional>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
enum MissingInclude {
|
|
||||||
INC_ERROR, // A missing included file is an error that halts assembly
|
|
||||||
GEN_EXIT, // A missing included file is assumed to be generated; exit normally
|
|
||||||
GEN_CONTINUE, // A missing included file is assumed to be generated; continue assembling
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Options {
|
|
||||||
bool exportAll = false; // -E
|
|
||||||
uint8_t fixPrecision = 16; // -Q
|
|
||||||
size_t maxRecursionDepth = 64; // -r
|
|
||||||
char binDigits[2] = {'0', '1'}; // -b
|
|
||||||
char gfxDigits[4] = {'0', '1', '2', '3'}; // -g
|
|
||||||
FILE *dependFile = nullptr; // -M
|
|
||||||
std::optional<std::string> targetFileName{}; // -MQ, -MT
|
|
||||||
MissingInclude missingIncludeState = INC_ERROR; // -MC, -MG
|
|
||||||
bool generatePhonyDeps = false; // -MP
|
|
||||||
std::optional<std::string> objectFileName{}; // -o
|
|
||||||
uint8_t padByte = 0; // -p
|
|
||||||
uint64_t maxErrors = 0; // -X
|
|
||||||
|
|
||||||
~Options() {
|
|
||||||
if (dependFile) {
|
|
||||||
fclose(dependFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void printDep(std::string const &depName) {
|
|
||||||
if (dependFile) {
|
|
||||||
fprintf(dependFile, "%s: %s\n", targetFileName->c_str(), depName.c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
extern Options options;
|
|
||||||
|
|
||||||
#endif // RGBDS_ASM_MAIN_HPP
|
|
||||||
25
include/asm/opt.h
Normal file
25
include/asm/opt.h
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of RGBDS.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021, Eldred Habert and RGBDS contributors.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RGBDS_OPT_H
|
||||||
|
#define RGBDS_OPT_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void opt_B(char const chars[2]);
|
||||||
|
void opt_G(char const chars[4]);
|
||||||
|
void opt_P(uint8_t fill);
|
||||||
|
void opt_L(bool optimize);
|
||||||
|
void opt_W(char const *flag);
|
||||||
|
void opt_Parse(char const *option);
|
||||||
|
|
||||||
|
void opt_Push(void);
|
||||||
|
void opt_Pop(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#ifndef RGBDS_ASM_OPT_HPP
|
|
||||||
#define RGBDS_ASM_OPT_HPP
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
void opt_B(char const binDigits[2]);
|
|
||||||
void opt_G(char const gfxDigits[4]);
|
|
||||||
void opt_P(uint8_t padByte);
|
|
||||||
void opt_Q(uint8_t fixPrecision);
|
|
||||||
void opt_W(char const *flag);
|
|
||||||
void opt_Parse(char const *option);
|
|
||||||
|
|
||||||
void opt_Push();
|
|
||||||
void opt_Pop();
|
|
||||||
void opt_CheckStack();
|
|
||||||
|
|
||||||
#endif // RGBDS_ASM_OPT_HPP
|
|
||||||
30
include/asm/output.h
Normal file
30
include/asm/output.h
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of RGBDS.
|
||||||
|
*
|
||||||
|
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RGBDS_ASM_OUTPUT_H
|
||||||
|
#define RGBDS_ASM_OUTPUT_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "linkdefs.h"
|
||||||
|
|
||||||
|
struct Expression;
|
||||||
|
struct FileStackNode;
|
||||||
|
|
||||||
|
extern char *objectName;
|
||||||
|
extern struct Section *sectionList;
|
||||||
|
|
||||||
|
void out_RegisterNode(struct FileStackNode *node);
|
||||||
|
void out_ReplaceNode(struct FileStackNode *node);
|
||||||
|
void out_SetFileName(char *s);
|
||||||
|
void out_CreatePatch(uint32_t type, struct Expression const *expr, uint32_t ofs, uint32_t pcShift);
|
||||||
|
bool out_CreateAssert(enum AssertionType type, struct Expression const *expr,
|
||||||
|
char const *message, uint32_t ofs);
|
||||||
|
void out_WriteObject(void);
|
||||||
|
|
||||||
|
#endif /* RGBDS_ASM_OUTPUT_H */
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#ifndef RGBDS_ASM_OUTPUT_HPP
|
|
||||||
#define RGBDS_ASM_OUTPUT_HPP
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "linkdefs.hpp"
|
|
||||||
|
|
||||||
struct Expression;
|
|
||||||
struct FileStackNode;
|
|
||||||
struct Symbol;
|
|
||||||
|
|
||||||
enum StateFeature { STATE_EQU, STATE_VAR, STATE_EQUS, STATE_CHAR, STATE_MACRO, NB_STATE_FEATURES };
|
|
||||||
|
|
||||||
void out_RegisterNode(std::shared_ptr<FileStackNode> node);
|
|
||||||
void out_RegisterSymbol(Symbol &sym);
|
|
||||||
void out_CreatePatch(uint32_t type, Expression const &expr, uint32_t ofs, uint32_t pcShift);
|
|
||||||
void out_CreateAssert(
|
|
||||||
AssertionType type, Expression const &expr, std::string const &message, uint32_t ofs
|
|
||||||
);
|
|
||||||
void out_WriteObject();
|
|
||||||
void out_WriteState(std::string name, std::vector<StateFeature> const &features);
|
|
||||||
|
|
||||||
#endif // RGBDS_ASM_OUTPUT_HPP
|
|
||||||
70
include/asm/rpn.h
Normal file
70
include/asm/rpn.h
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of RGBDS.
|
||||||
|
*
|
||||||
|
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RGBDS_ASM_RPN_H
|
||||||
|
#define RGBDS_ASM_RPN_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "linkdefs.h"
|
||||||
|
|
||||||
|
#define MAXRPNLEN 1048576
|
||||||
|
|
||||||
|
struct Expression {
|
||||||
|
int32_t val; // If the expression's value is known, it's here
|
||||||
|
char *reason; // Why the expression is not known, if it isn't
|
||||||
|
bool isKnown; // Whether the expression's value is known
|
||||||
|
bool isSymbol; // Whether the expression represents a symbol
|
||||||
|
uint8_t *rpn; // Array of bytes serializing the RPN expression
|
||||||
|
uint32_t rpnCapacity; // Size of the `rpn` buffer
|
||||||
|
uint32_t rpnLength; // Used size of the `rpn` buffer
|
||||||
|
uint32_t rpnPatchSize; // Size the expression will take in the object file
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determines if an expression is known at assembly time
|
||||||
|
*/
|
||||||
|
static inline bool rpn_isKnown(struct Expression const *expr)
|
||||||
|
{
|
||||||
|
return expr->isKnown;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determines if an expression is a symbol suitable for const diffing
|
||||||
|
*/
|
||||||
|
static inline bool rpn_isSymbol(const struct Expression *expr)
|
||||||
|
{
|
||||||
|
return expr->isSymbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rpn_Symbol(struct Expression *expr, char const *symName);
|
||||||
|
void rpn_Number(struct Expression *expr, uint32_t i);
|
||||||
|
void rpn_LOGNOT(struct Expression *expr, const struct Expression *src);
|
||||||
|
struct Symbol const *rpn_SymbolOf(struct Expression const *expr);
|
||||||
|
bool rpn_IsDiffConstant(struct Expression const *src, struct Symbol const *symName);
|
||||||
|
void rpn_BinaryOp(enum RPNCommand op, struct Expression *expr,
|
||||||
|
const struct Expression *src1,
|
||||||
|
const struct Expression *src2);
|
||||||
|
void rpn_HIGH(struct Expression *expr, const struct Expression *src);
|
||||||
|
void rpn_LOW(struct Expression *expr, const struct Expression *src);
|
||||||
|
void rpn_ISCONST(struct Expression *expr, const struct Expression *src);
|
||||||
|
void rpn_UNNEG(struct Expression *expr, const struct Expression *src);
|
||||||
|
void rpn_UNNOT(struct Expression *expr, const struct Expression *src);
|
||||||
|
void rpn_BankSymbol(struct Expression *expr, char const *symName);
|
||||||
|
void rpn_BankSection(struct Expression *expr, char const *sectionName);
|
||||||
|
void rpn_BankSelf(struct Expression *expr);
|
||||||
|
void rpn_SizeOfSection(struct Expression *expr, char const *sectionName);
|
||||||
|
void rpn_StartOfSection(struct Expression *expr, char const *sectionName);
|
||||||
|
void rpn_Free(struct Expression *expr);
|
||||||
|
void rpn_CheckHRAM(struct Expression *expr, const struct Expression *src);
|
||||||
|
void rpn_CheckRST(struct Expression *expr, const struct Expression *src);
|
||||||
|
void rpn_CheckNBit(struct Expression const *expr, uint8_t n);
|
||||||
|
int32_t rpn_GetConstVal(struct Expression const *expr);
|
||||||
|
|
||||||
|
#endif /* RGBDS_ASM_RPN_H */
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#ifndef RGBDS_ASM_RPN_HPP
|
|
||||||
#define RGBDS_ASM_RPN_HPP
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string>
|
|
||||||
#include <variant>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "linkdefs.hpp"
|
|
||||||
|
|
||||||
struct Symbol;
|
|
||||||
|
|
||||||
struct RPNValue {
|
|
||||||
RPNCommand command; // The RPN_* command ID
|
|
||||||
std::variant<std::monostate, uint8_t, uint32_t, std::string> data; // Data after the ID, if any
|
|
||||||
|
|
||||||
RPNValue(RPNCommand cmd);
|
|
||||||
RPNValue(RPNCommand cmd, uint8_t val);
|
|
||||||
RPNValue(RPNCommand cmd, uint32_t val);
|
|
||||||
RPNValue(RPNCommand cmd, std::string const &name);
|
|
||||||
|
|
||||||
void appendEncoded(std::vector<uint8_t> &buffer) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Expression {
|
|
||||||
std::variant<
|
|
||||||
int32_t, // If the expression's value is known, it's here
|
|
||||||
std::string // Why the expression is not known, if it isn't
|
|
||||||
>
|
|
||||||
data = 0;
|
|
||||||
std::vector<RPNValue> rpn{}; // Values to be serialized into the RPN expression
|
|
||||||
|
|
||||||
bool isKnown() const { return std::holds_alternative<int32_t>(data); }
|
|
||||||
int32_t value() const { return std::get<int32_t>(data); }
|
|
||||||
|
|
||||||
int32_t getConstVal() const;
|
|
||||||
Symbol const *symbolOf() const;
|
|
||||||
bool isDiffConstant(Symbol const *symName) const;
|
|
||||||
|
|
||||||
void makeNumber(uint32_t value);
|
|
||||||
void makeSymbol(std::string const &symName);
|
|
||||||
void makeBankSymbol(std::string const &symName);
|
|
||||||
void makeBankSection(std::string const §Name);
|
|
||||||
void makeSizeOfSection(std::string const §Name);
|
|
||||||
void makeStartOfSection(std::string const §Name);
|
|
||||||
void makeSizeOfSectionType(SectionType type);
|
|
||||||
void makeStartOfSectionType(SectionType type);
|
|
||||||
void makeUnaryOp(RPNCommand op, Expression &&src);
|
|
||||||
void makeBinaryOp(RPNCommand op, Expression &&src1, Expression const &src2);
|
|
||||||
|
|
||||||
void addCheckHRAM();
|
|
||||||
void addCheckRST();
|
|
||||||
void addCheckBitIndex(uint8_t mask);
|
|
||||||
|
|
||||||
void checkNBit(uint8_t n) const;
|
|
||||||
|
|
||||||
void encode(std::vector<uint8_t> &buffer) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool checkNBit(int32_t v, uint8_t n, char const *name);
|
|
||||||
|
|
||||||
#endif // RGBDS_ASM_RPN_HPP
|
|
||||||
82
include/asm/section.h
Normal file
82
include/asm/section.h
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of RGBDS.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020, Carsten Sorensen and RGBDS contributors.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RGBDS_SECTION_H
|
||||||
|
#define RGBDS_SECTION_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "linkdefs.h"
|
||||||
|
#include "platform.h" // NONNULL
|
||||||
|
|
||||||
|
extern uint8_t fillByte;
|
||||||
|
|
||||||
|
struct Expression;
|
||||||
|
|
||||||
|
struct Section {
|
||||||
|
char *name;
|
||||||
|
enum SectionType type;
|
||||||
|
enum SectionModifier modifier;
|
||||||
|
struct FileStackNode *src; /* Where the section was defined */
|
||||||
|
uint32_t fileLine; /* Line where the section was defined */
|
||||||
|
uint32_t size;
|
||||||
|
uint32_t org;
|
||||||
|
uint32_t bank;
|
||||||
|
uint8_t align; // Exactly as specified in `ALIGN[]`
|
||||||
|
uint16_t alignOfs;
|
||||||
|
struct Section *next;
|
||||||
|
struct Patch *patches;
|
||||||
|
uint8_t *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SectionSpec {
|
||||||
|
uint32_t bank;
|
||||||
|
uint8_t alignment;
|
||||||
|
uint16_t alignOfs;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct Section *currentSection;
|
||||||
|
|
||||||
|
struct Section *sect_FindSectionByName(char const *name);
|
||||||
|
void sect_NewSection(char const *name, uint32_t secttype, uint32_t org,
|
||||||
|
struct SectionSpec const *attributes, enum SectionModifier mod);
|
||||||
|
void sect_SetLoadSection(char const *name, uint32_t secttype, uint32_t org,
|
||||||
|
struct SectionSpec const *attributes, enum SectionModifier mod);
|
||||||
|
void sect_EndLoadSection(void);
|
||||||
|
|
||||||
|
struct Section *sect_GetSymbolSection(void);
|
||||||
|
uint32_t sect_GetSymbolOffset(void);
|
||||||
|
uint32_t sect_GetOutputOffset(void);
|
||||||
|
void sect_AlignPC(uint8_t alignment, uint16_t offset);
|
||||||
|
|
||||||
|
void sect_StartUnion(void);
|
||||||
|
void sect_NextUnionMember(void);
|
||||||
|
void sect_EndUnion(void);
|
||||||
|
void sect_CheckUnionClosed(void);
|
||||||
|
|
||||||
|
void sect_AbsByte(uint8_t b);
|
||||||
|
void sect_AbsByteGroup(uint8_t const *s, size_t length);
|
||||||
|
void sect_AbsWordGroup(uint8_t const *s, size_t length);
|
||||||
|
void sect_AbsLongGroup(uint8_t const *s, size_t length);
|
||||||
|
void sect_Skip(uint32_t skip, bool ds);
|
||||||
|
void sect_String(char const *s);
|
||||||
|
void sect_RelByte(struct Expression *expr, uint32_t pcShift);
|
||||||
|
void sect_RelBytes(uint32_t n, struct Expression *exprs, size_t size);
|
||||||
|
void sect_RelWord(struct Expression *expr, uint32_t pcShift);
|
||||||
|
void sect_RelLong(struct Expression *expr, uint32_t pcShift);
|
||||||
|
void sect_PCRelByte(struct Expression *expr, uint32_t pcShift);
|
||||||
|
void sect_BinaryFile(char const *s, int32_t startPos);
|
||||||
|
void sect_BinaryFileSlice(char const *s, int32_t start_pos, int32_t length);
|
||||||
|
|
||||||
|
void sect_PushSection(void);
|
||||||
|
void sect_PopSection(void);
|
||||||
|
|
||||||
|
bool sect_IsSizeKnown(struct Section const NONNULL(name));
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#ifndef RGBDS_ASM_SECTION_HPP
|
|
||||||
#define RGBDS_ASM_SECTION_HPP
|
|
||||||
|
|
||||||
#include <deque>
|
|
||||||
#include <memory>
|
|
||||||
#include <optional>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "linkdefs.hpp"
|
|
||||||
|
|
||||||
struct Expression;
|
|
||||||
struct FileStackNode;
|
|
||||||
struct Section;
|
|
||||||
|
|
||||||
struct Patch {
|
|
||||||
std::shared_ptr<FileStackNode> src;
|
|
||||||
uint32_t lineNo;
|
|
||||||
uint32_t offset;
|
|
||||||
Section *pcSection;
|
|
||||||
uint32_t pcOffset;
|
|
||||||
uint8_t type;
|
|
||||||
std::vector<uint8_t> rpn;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Section {
|
|
||||||
std::string name;
|
|
||||||
SectionType type;
|
|
||||||
SectionModifier modifier;
|
|
||||||
std::shared_ptr<FileStackNode> src; // Where the section was defined
|
|
||||||
uint32_t fileLine; // Line where the section was defined
|
|
||||||
uint32_t size;
|
|
||||||
uint32_t org;
|
|
||||||
uint32_t bank;
|
|
||||||
uint8_t align; // Exactly as specified in `ALIGN[]`
|
|
||||||
uint16_t alignOfs;
|
|
||||||
std::deque<Patch> patches;
|
|
||||||
std::vector<uint8_t> data;
|
|
||||||
|
|
||||||
uint32_t getID() const; // ID of the section in the object file (`UINT32_MAX` if none)
|
|
||||||
bool isSizeKnown() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SectionSpec {
|
|
||||||
uint32_t bank;
|
|
||||||
uint8_t alignment;
|
|
||||||
uint16_t alignOfs;
|
|
||||||
};
|
|
||||||
|
|
||||||
size_t sect_CountSections();
|
|
||||||
void sect_ForEach(void (*callback)(Section &));
|
|
||||||
|
|
||||||
Section *sect_FindSectionByName(std::string const &name);
|
|
||||||
void sect_NewSection(
|
|
||||||
std::string const &name,
|
|
||||||
SectionType type,
|
|
||||||
uint32_t org,
|
|
||||||
SectionSpec const &attrs,
|
|
||||||
SectionModifier mod
|
|
||||||
);
|
|
||||||
void sect_SetLoadSection(
|
|
||||||
std::string const &name,
|
|
||||||
SectionType type,
|
|
||||||
uint32_t org,
|
|
||||||
SectionSpec const &attrs,
|
|
||||||
SectionModifier mod
|
|
||||||
);
|
|
||||||
void sect_EndLoadSection(char const *cause);
|
|
||||||
void sect_CheckLoadClosed();
|
|
||||||
|
|
||||||
Section *sect_GetSymbolSection();
|
|
||||||
uint32_t sect_GetSymbolOffset();
|
|
||||||
uint32_t sect_GetOutputOffset();
|
|
||||||
std::optional<uint32_t> sect_GetOutputBank();
|
|
||||||
|
|
||||||
Patch *sect_AddOutputPatch();
|
|
||||||
|
|
||||||
uint32_t sect_GetAlignBytes(uint8_t alignment, uint16_t offset);
|
|
||||||
void sect_AlignPC(uint8_t alignment, uint16_t offset);
|
|
||||||
|
|
||||||
void sect_CheckSizes();
|
|
||||||
|
|
||||||
void sect_StartUnion();
|
|
||||||
void sect_NextUnionMember();
|
|
||||||
void sect_EndUnion();
|
|
||||||
void sect_CheckUnionClosed();
|
|
||||||
|
|
||||||
void sect_ConstByte(uint8_t byte);
|
|
||||||
void sect_ByteString(std::vector<int32_t> const &str);
|
|
||||||
void sect_WordString(std::vector<int32_t> const &str);
|
|
||||||
void sect_LongString(std::vector<int32_t> const &str);
|
|
||||||
void sect_Skip(uint32_t skip, bool ds);
|
|
||||||
void sect_RelByte(Expression const &expr, uint32_t pcShift);
|
|
||||||
void sect_RelBytes(uint32_t n, std::vector<Expression> const &exprs);
|
|
||||||
void sect_RelWord(Expression const &expr, uint32_t pcShift);
|
|
||||||
void sect_RelLong(Expression const &expr, uint32_t pcShift);
|
|
||||||
void sect_PCRelByte(Expression const &expr, uint32_t pcShift);
|
|
||||||
bool sect_BinaryFile(std::string const &name, uint32_t startPos);
|
|
||||||
bool sect_BinaryFileSlice(std::string const &name, uint32_t startPos, uint32_t length);
|
|
||||||
|
|
||||||
void sect_EndSection();
|
|
||||||
void sect_PushSection();
|
|
||||||
void sect_PopSection();
|
|
||||||
void sect_CheckStack();
|
|
||||||
|
|
||||||
std::string sect_PushSectionFragmentLiteral();
|
|
||||||
|
|
||||||
#endif // RGBDS_ASM_SECTION_HPP
|
|
||||||
150
include/asm/symbol.h
Normal file
150
include/asm/symbol.h
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of RGBDS.
|
||||||
|
*
|
||||||
|
* Copyright (c) 1997-2020, Carsten Sorensen and RGBDS contributors.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RGBDS_SYMBOL_H
|
||||||
|
#define RGBDS_SYMBOL_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include "asm/section.h"
|
||||||
|
|
||||||
|
#include "platform.h" // MIN_NB_ELMS
|
||||||
|
|
||||||
|
#define MAXSYMLEN 255
|
||||||
|
|
||||||
|
enum SymbolType {
|
||||||
|
SYM_LABEL,
|
||||||
|
SYM_EQU,
|
||||||
|
SYM_VAR,
|
||||||
|
SYM_MACRO,
|
||||||
|
SYM_EQUS,
|
||||||
|
SYM_REF // Forward reference to a label
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Symbol {
|
||||||
|
char name[MAXSYMLEN + 1];
|
||||||
|
enum SymbolType type;
|
||||||
|
bool isExported; /* Whether the symbol is to be exported */
|
||||||
|
bool isBuiltin; /* Whether the symbol is a built-in */
|
||||||
|
struct Section *section;
|
||||||
|
struct FileStackNode *src; /* Where the symbol was defined */
|
||||||
|
uint32_t fileLine; /* Line where the symbol was defined */
|
||||||
|
|
||||||
|
bool hasCallback;
|
||||||
|
union {
|
||||||
|
/* If sym_IsNumeric */
|
||||||
|
int32_t value;
|
||||||
|
int32_t (*numCallback)(void);
|
||||||
|
/* For SYM_MACRO and SYM_EQUS; TODO: have separate fields */
|
||||||
|
struct {
|
||||||
|
size_t macroSize;
|
||||||
|
char *macro;
|
||||||
|
};
|
||||||
|
/* For SYM_EQUS */
|
||||||
|
char const *(*strCallback)(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32_t ID; /* ID of the symbol in the object file (-1 if none) */
|
||||||
|
struct Symbol *next; /* Next object to output in the object file */
|
||||||
|
};
|
||||||
|
|
||||||
|
bool sym_IsPC(struct Symbol const *sym);
|
||||||
|
|
||||||
|
static inline bool sym_IsDefined(struct Symbol const *sym)
|
||||||
|
{
|
||||||
|
return sym->type != SYM_REF;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct Section *sym_GetSection(struct Symbol const *sym)
|
||||||
|
{
|
||||||
|
return sym_IsPC(sym) ? sect_GetSymbolSection() : sym->section;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool sym_IsConstant(struct Symbol const *sym)
|
||||||
|
{
|
||||||
|
if (sym->type == SYM_LABEL) {
|
||||||
|
struct Section const *sect = sym_GetSection(sym);
|
||||||
|
|
||||||
|
return sect && sect->org != (uint32_t)-1;
|
||||||
|
}
|
||||||
|
return sym->type == SYM_EQU || sym->type == SYM_VAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool sym_IsNumeric(struct Symbol const *sym)
|
||||||
|
{
|
||||||
|
return sym->type == SYM_LABEL || sym->type == SYM_EQU || sym->type == SYM_VAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool sym_IsLabel(struct Symbol const *sym)
|
||||||
|
{
|
||||||
|
return sym->type == SYM_LABEL || sym->type == SYM_REF;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool sym_IsLocal(struct Symbol const *sym)
|
||||||
|
{
|
||||||
|
return sym_IsLabel(sym) && strchr(sym->name, '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool sym_IsExported(struct Symbol const *sym)
|
||||||
|
{
|
||||||
|
return sym->isExported;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get a string equate's value
|
||||||
|
*/
|
||||||
|
static inline char const *sym_GetStringValue(struct Symbol const *sym)
|
||||||
|
{
|
||||||
|
if (sym->hasCallback)
|
||||||
|
return sym->strCallback();
|
||||||
|
return sym->macro;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sym_ForEach(void (*func)(struct Symbol *, void *), void *arg);
|
||||||
|
|
||||||
|
int32_t sym_GetValue(struct Symbol const *sym);
|
||||||
|
void sym_SetExportAll(bool set);
|
||||||
|
struct Symbol *sym_AddLocalLabel(char const *symName);
|
||||||
|
struct Symbol *sym_AddLabel(char const *symName);
|
||||||
|
struct Symbol *sym_AddAnonLabel(void);
|
||||||
|
void sym_WriteAnonLabelName(char buf[MIN_NB_ELMS(MAXSYMLEN + 1)], uint32_t ofs, bool neg);
|
||||||
|
void sym_Export(char const *symName);
|
||||||
|
struct Symbol *sym_AddEqu(char const *symName, int32_t value);
|
||||||
|
struct Symbol *sym_RedefEqu(char const *symName, int32_t value);
|
||||||
|
struct Symbol *sym_AddVar(char const *symName, int32_t value);
|
||||||
|
uint32_t sym_GetPCValue(void);
|
||||||
|
uint32_t sym_GetConstantSymValue(struct Symbol const *sym);
|
||||||
|
uint32_t sym_GetConstantValue(char const *symName);
|
||||||
|
/*
|
||||||
|
* Find a symbol by exact name, bypassing expansion checks
|
||||||
|
*/
|
||||||
|
struct Symbol *sym_FindExactSymbol(char const *symName);
|
||||||
|
/*
|
||||||
|
* Find a symbol by exact name; may not be scoped, produces an error if it is
|
||||||
|
*/
|
||||||
|
struct Symbol *sym_FindUnscopedSymbol(char const *symName);
|
||||||
|
/*
|
||||||
|
* Find a symbol, possibly scoped, by name
|
||||||
|
*/
|
||||||
|
struct Symbol *sym_FindScopedSymbol(char const *symName);
|
||||||
|
struct Symbol const *sym_GetPC(void);
|
||||||
|
struct Symbol *sym_AddMacro(char const *symName, int32_t defLineNo, char *body, size_t size);
|
||||||
|
struct Symbol *sym_Ref(char const *symName);
|
||||||
|
struct Symbol *sym_AddString(char const *symName, char const *value);
|
||||||
|
struct Symbol *sym_RedefString(char const *symName, char const *value);
|
||||||
|
void sym_Purge(char const *symName);
|
||||||
|
void sym_Init(time_t now);
|
||||||
|
|
||||||
|
/* Functions to save and restore the current symbol scope. */
|
||||||
|
char const *sym_GetCurrentSymbolScope(void);
|
||||||
|
void sym_SetCurrentSymbolScope(char const *newScope);
|
||||||
|
|
||||||
|
#endif /* RGBDS_SYMBOL_H */
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#ifndef RGBDS_ASM_SYMBOL_HPP
|
|
||||||
#define RGBDS_ASM_SYMBOL_HPP
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string>
|
|
||||||
#include <time.h>
|
|
||||||
#include <utility>
|
|
||||||
#include <variant>
|
|
||||||
|
|
||||||
#include "asm/lexer.hpp"
|
|
||||||
#include "asm/section.hpp"
|
|
||||||
|
|
||||||
enum SymbolType {
|
|
||||||
SYM_LABEL,
|
|
||||||
SYM_EQU,
|
|
||||||
SYM_VAR,
|
|
||||||
SYM_MACRO,
|
|
||||||
SYM_EQUS,
|
|
||||||
SYM_REF // Forward reference to a label
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Symbol; // Forward declaration for `sym_IsPC`
|
|
||||||
bool sym_IsPC(Symbol const *sym); // Forward declaration for `getSection`
|
|
||||||
|
|
||||||
struct Symbol {
|
|
||||||
std::string name;
|
|
||||||
SymbolType type;
|
|
||||||
bool isBuiltin;
|
|
||||||
bool isExported; // Not relevant for SYM_MACRO or SYM_EQUS
|
|
||||||
bool isQuiet; // Only relevant for SYM_MACRO
|
|
||||||
Section *section;
|
|
||||||
std::shared_ptr<FileStackNode> src; // Where the symbol was defined
|
|
||||||
uint32_t fileLine; // Line where the symbol was defined
|
|
||||||
|
|
||||||
std::variant<
|
|
||||||
int32_t, // If isNumeric()
|
|
||||||
int32_t (*)(), // If isNumeric() via a callback
|
|
||||||
ContentSpan, // For SYM_MACRO
|
|
||||||
std::shared_ptr<std::string>, // For SYM_EQUS
|
|
||||||
std::shared_ptr<std::string> (*)() // For SYM_EQUS via a callback
|
|
||||||
>
|
|
||||||
data;
|
|
||||||
|
|
||||||
uint32_t ID; // ID of the symbol in the object file (`UINT32_MAX` if none)
|
|
||||||
uint32_t defIndex; // Ordering of the symbol in the state file
|
|
||||||
|
|
||||||
bool isDefined() const { return type != SYM_REF; }
|
|
||||||
bool isNumeric() const { return type == SYM_LABEL || type == SYM_EQU || type == SYM_VAR; }
|
|
||||||
bool isLabel() const { return type == SYM_LABEL || type == SYM_REF; }
|
|
||||||
|
|
||||||
bool isConstant() const {
|
|
||||||
if (type == SYM_LABEL) {
|
|
||||||
Section const *sect = getSection();
|
|
||||||
return sect && sect->org != UINT32_MAX;
|
|
||||||
}
|
|
||||||
return type == SYM_EQU || type == SYM_VAR;
|
|
||||||
}
|
|
||||||
|
|
||||||
Section *getSection() const { return sym_IsPC(this) ? sect_GetSymbolSection() : section; }
|
|
||||||
|
|
||||||
int32_t getValue() const;
|
|
||||||
int32_t getOutputValue() const;
|
|
||||||
ContentSpan const &getMacro() const;
|
|
||||||
std::shared_ptr<std::string> getEqus() const;
|
|
||||||
uint32_t getConstantValue() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
void sym_ForEach(void (*callback)(Symbol &));
|
|
||||||
|
|
||||||
Symbol *sym_AddLocalLabel(std::string const &symName);
|
|
||||||
Symbol *sym_AddLabel(std::string const &symName);
|
|
||||||
Symbol *sym_AddAnonLabel();
|
|
||||||
std::string sym_MakeAnonLabelName(uint32_t ofs, bool neg);
|
|
||||||
void sym_Export(std::string const &symName);
|
|
||||||
Symbol *sym_AddEqu(std::string const &symName, int32_t value);
|
|
||||||
Symbol *sym_RedefEqu(std::string const &symName, int32_t value);
|
|
||||||
Symbol *sym_AddVar(std::string const &symName, int32_t value);
|
|
||||||
int32_t sym_GetRSValue();
|
|
||||||
void sym_SetRSValue(int32_t value);
|
|
||||||
// Find a symbol by exact name, bypassing expansion checks
|
|
||||||
Symbol *sym_FindExactSymbol(std::string const &symName);
|
|
||||||
// Find a symbol, possibly scoped, by name
|
|
||||||
Symbol *sym_FindScopedSymbol(std::string const &symName);
|
|
||||||
// Find a scoped symbol by name; do not return `@` or `_NARG` when they have no value
|
|
||||||
Symbol *sym_FindScopedValidSymbol(std::string const &symName);
|
|
||||||
Symbol const *sym_GetPC();
|
|
||||||
Symbol *sym_AddMacro(
|
|
||||||
std::string const &symName, int32_t defLineNo, ContentSpan const &span, bool isQuiet
|
|
||||||
);
|
|
||||||
Symbol *sym_Ref(std::string const &symName);
|
|
||||||
Symbol *sym_AddString(std::string const &symName, std::shared_ptr<std::string> value);
|
|
||||||
Symbol *sym_RedefString(std::string const &symName, std::shared_ptr<std::string> value);
|
|
||||||
void sym_Purge(std::string const &symName);
|
|
||||||
bool sym_IsPurgedExact(std::string const &symName);
|
|
||||||
bool sym_IsPurgedScoped(std::string const &symName);
|
|
||||||
void sym_Init(time_t now);
|
|
||||||
|
|
||||||
// Functions to save and restore the current label scopes.
|
|
||||||
std::pair<Symbol const *, Symbol const *> sym_GetCurrentLabelScopes();
|
|
||||||
void sym_SetCurrentLabelScopes(std::pair<Symbol const *, Symbol const *> newScopes);
|
|
||||||
void sym_ResetCurrentLabelScopes();
|
|
||||||
|
|
||||||
#endif // RGBDS_ASM_SYMBOL_HPP
|
|
||||||
21
include/asm/util.h
Normal file
21
include/asm/util.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of RGBDS.
|
||||||
|
*
|
||||||
|
* Copyright (c) 1997-2019, Carsten Sorensen and RGBDS contributors.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RGBDS_UTIL_H
|
||||||
|
#define RGBDS_UTIL_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
char const *printChar(int c);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @return The number of bytes read, or 0 if invalid data was found
|
||||||
|
*/
|
||||||
|
size_t readUTF8Char(uint8_t *dest, char const *src);
|
||||||
|
|
||||||
|
#endif /* RGBDS_UTIL_H */
|
||||||
93
include/asm/warning.h
Normal file
93
include/asm/warning.h
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of RGBDS.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019, Eldred Habert and RGBDS contributors.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WARNING_H
|
||||||
|
#define WARNING_H
|
||||||
|
|
||||||
|
#include "helpers.h"
|
||||||
|
|
||||||
|
extern unsigned int nbErrors;
|
||||||
|
|
||||||
|
enum WarningState {
|
||||||
|
WARNING_DEFAULT,
|
||||||
|
WARNING_DISABLED,
|
||||||
|
WARNING_ENABLED,
|
||||||
|
WARNING_ERROR
|
||||||
|
};
|
||||||
|
|
||||||
|
enum WarningID {
|
||||||
|
WARNING_ASSERT, // Assertions
|
||||||
|
WARNING_BACKWARDS_FOR, // `for` loop with backwards range
|
||||||
|
WARNING_BUILTIN_ARG, // Invalid args to builtins
|
||||||
|
WARNING_CHARMAP_REDEF, // Charmap entry re-definition
|
||||||
|
WARNING_DIV, // Division undefined behavior
|
||||||
|
WARNING_EMPTY_DATA_DIRECTIVE, // `db`, `dw` or `dl` directive without data in ROM
|
||||||
|
WARNING_EMPTY_MACRO_ARG, // Empty macro argument
|
||||||
|
WARNING_EMPTY_STRRPL, // Empty second argument in `STRRPL`
|
||||||
|
WARNING_LARGE_CONSTANT, // Constants too large
|
||||||
|
WARNING_LONG_STR, // String too long for internal buffers
|
||||||
|
WARNING_MACRO_SHIFT, // Shift past available arguments in macro
|
||||||
|
WARNING_NESTED_COMMENT, // Comment-start delimiter in a block comment
|
||||||
|
WARNING_OBSOLETE, // Obsolete things
|
||||||
|
WARNING_SHIFT, // Shifting undefined behavior
|
||||||
|
WARNING_SHIFT_AMOUNT, // Strange shift amount
|
||||||
|
WARNING_USER, // User warnings
|
||||||
|
|
||||||
|
NB_PLAIN_WARNINGS,
|
||||||
|
|
||||||
|
// Warnings past this point are "parametric" warnings, only mapping to a single flag
|
||||||
|
#define PARAM_WARNINGS_START NB_PLAIN_WARNINGS
|
||||||
|
// Treating string as number may lose some bits
|
||||||
|
WARNING_NUMERIC_STRING_1 = PARAM_WARNINGS_START,
|
||||||
|
WARNING_NUMERIC_STRING_2,
|
||||||
|
// Implicit truncation loses some bits
|
||||||
|
WARNING_TRUNCATION_1,
|
||||||
|
WARNING_TRUNCATION_2,
|
||||||
|
|
||||||
|
NB_PLAIN_AND_PARAM_WARNINGS,
|
||||||
|
#define NB_PARAM_WARNINGS (NB_PLAIN_AND_PARAM_WARNINGS - PARAM_WARNINGS_START)
|
||||||
|
|
||||||
|
// Warnings past this point are "meta" warnings
|
||||||
|
#define META_WARNINGS_START NB_PLAIN_AND_PARAM_WARNINGS
|
||||||
|
WARNING_ALL = META_WARNINGS_START,
|
||||||
|
WARNING_EXTRA,
|
||||||
|
WARNING_EVERYTHING,
|
||||||
|
|
||||||
|
NB_WARNINGS,
|
||||||
|
#define NB_META_WARNINGS (NB_WARNINGS - META_WARNINGS_START)
|
||||||
|
};
|
||||||
|
|
||||||
|
extern enum WarningState warningStates[NB_PLAIN_AND_PARAM_WARNINGS];
|
||||||
|
extern bool warningsAreErrors;
|
||||||
|
|
||||||
|
void processWarningFlag(char *flag);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Used to warn the user about problems that don't prevent the generation of
|
||||||
|
* valid code.
|
||||||
|
*/
|
||||||
|
void warning(enum WarningID id, char const *fmt, ...) format_(printf, 2, 3);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Used for errors that compromise the whole assembly process by affecting the
|
||||||
|
* following code, potencially making the assembler generate errors caused by
|
||||||
|
* the first one and unrelated to the code that the assembler complains about.
|
||||||
|
* It is also used when the assembler goes into an invalid state (for example,
|
||||||
|
* when it fails to allocate memory).
|
||||||
|
*/
|
||||||
|
_Noreturn void fatalerror(char const *fmt, ...) format_(printf, 1, 2);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Used for errors that make it impossible to assemble correctly, but don't
|
||||||
|
* affect the following code. The code will fail to assemble but the user will
|
||||||
|
* get a list of all errors at the end, making it easier to fix all of them at
|
||||||
|
* once.
|
||||||
|
*/
|
||||||
|
void error(char const *fmt, ...) format_(printf, 1, 2);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#ifndef RGBDS_ASM_WARNING_HPP
|
|
||||||
#define RGBDS_ASM_WARNING_HPP
|
|
||||||
|
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
#include "diagnostics.hpp"
|
|
||||||
|
|
||||||
enum WarningLevel {
|
|
||||||
LEVEL_DEFAULT, // Warnings that are enabled by default
|
|
||||||
LEVEL_ALL, // Warnings that probably indicate an error
|
|
||||||
LEVEL_EXTRA, // Warnings that are less likely to indicate an error
|
|
||||||
LEVEL_EVERYTHING, // Literally every warning
|
|
||||||
};
|
|
||||||
|
|
||||||
enum WarningID {
|
|
||||||
WARNING_ASSERT, // Assertions
|
|
||||||
WARNING_BACKWARDS_FOR, // `FOR` loop with backwards range
|
|
||||||
WARNING_BUILTIN_ARG, // Invalid args to builtins
|
|
||||||
WARNING_CHARMAP_REDEF, // Charmap entry re-definition
|
|
||||||
WARNING_DIV, // Undefined division behavior
|
|
||||||
WARNING_EMPTY_DATA_DIRECTIVE, // `db`, `dw` or `dl` directive without data in ROM
|
|
||||||
WARNING_EMPTY_MACRO_ARG, // Empty macro argument
|
|
||||||
WARNING_EMPTY_STRRPL, // Empty second argument in `STRRPL`
|
|
||||||
WARNING_EXPORT_UNDEFINED, // `EXPORT` of an undefined symbol
|
|
||||||
WARNING_LARGE_CONSTANT, // Constants too large
|
|
||||||
WARNING_MACRO_SHIFT, // `SHIFT` past available arguments in macro
|
|
||||||
WARNING_NESTED_COMMENT, // Comment-start delimiter in a block comment
|
|
||||||
WARNING_OBSOLETE, // Obsolete/deprecated things
|
|
||||||
WARNING_SHIFT, // Undefined `SHIFT` behavior
|
|
||||||
WARNING_SHIFT_AMOUNT, // Strange `SHIFT` amount
|
|
||||||
WARNING_UNMATCHED_DIRECTIVE, // `PUSH[C|O|S]` without `POP[C|O|S]`
|
|
||||||
WARNING_UNTERMINATED_LOAD, // `LOAD` without `ENDL`
|
|
||||||
WARNING_USER, // User-defined `WARN`ings
|
|
||||||
|
|
||||||
NB_PLAIN_WARNINGS,
|
|
||||||
|
|
||||||
// Warnings past this point are "parametric" warnings, only mapping to a single flag
|
|
||||||
// Treating string as number may lose some bits
|
|
||||||
WARNING_NUMERIC_STRING_1 = NB_PLAIN_WARNINGS,
|
|
||||||
WARNING_NUMERIC_STRING_2,
|
|
||||||
// Purging an exported symbol or label
|
|
||||||
WARNING_PURGE_1,
|
|
||||||
WARNING_PURGE_2,
|
|
||||||
// Implicit truncation loses some bits
|
|
||||||
WARNING_TRUNCATION_1,
|
|
||||||
WARNING_TRUNCATION_2,
|
|
||||||
// Character without charmap entry
|
|
||||||
WARNING_UNMAPPED_CHAR_1,
|
|
||||||
WARNING_UNMAPPED_CHAR_2,
|
|
||||||
|
|
||||||
NB_WARNINGS,
|
|
||||||
};
|
|
||||||
|
|
||||||
extern Diagnostics<WarningLevel, WarningID> warnings;
|
|
||||||
|
|
||||||
// Used to warn the user about problems that don't prevent the generation of
|
|
||||||
// valid code.
|
|
||||||
[[gnu::format(printf, 2, 3)]]
|
|
||||||
void warning(WarningID id, char const *fmt, ...);
|
|
||||||
|
|
||||||
// Used for errors that compromise the whole assembly process by affecting the
|
|
||||||
// following code, potencially making the assembler generate errors caused by
|
|
||||||
// the first one and unrelated to the code that the assembler complains about.
|
|
||||||
// It is also used when the assembler goes into an invalid state (for example,
|
|
||||||
// when it fails to allocate memory).
|
|
||||||
[[gnu::format(printf, 1, 2), noreturn]]
|
|
||||||
void fatal(char const *fmt, ...);
|
|
||||||
|
|
||||||
// Used for errors that make it impossible to assemble correctly, but don't
|
|
||||||
// affect the following code. The code will fail to assemble but the user will
|
|
||||||
// get a list of all errors at the end, making it easier to fix all of them at
|
|
||||||
// once.
|
|
||||||
[[gnu::format(printf, 1, 2)]]
|
|
||||||
void error(char const *fmt, ...);
|
|
||||||
|
|
||||||
// Used for errors that handle their own backtrace output. The code will fail
|
|
||||||
// to assemble but the user will get a list of all errors at the end, making it
|
|
||||||
// easier to fix all of them at once.
|
|
||||||
void errorNoTrace(std::function<void()> callback);
|
|
||||||
|
|
||||||
void requireZeroErrors();
|
|
||||||
|
|
||||||
#endif // RGBDS_ASM_WARNING_HPP
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#ifndef RGBDS_BACKTRACE_HPP
|
|
||||||
#define RGBDS_BACKTRACE_HPP
|
|
||||||
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "style.hpp"
|
|
||||||
|
|
||||||
#define TRACE_SEPARATOR "<-"
|
|
||||||
#define NODE_SEPARATOR "::"
|
|
||||||
#define REPT_NODE_PREFIX "REPT~"
|
|
||||||
|
|
||||||
struct Tracing {
|
|
||||||
uint64_t depth = 0;
|
|
||||||
bool collapse = false;
|
|
||||||
bool loud = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern Tracing tracing;
|
|
||||||
|
|
||||||
bool trace_ParseTraceDepth(char const *arg);
|
|
||||||
|
|
||||||
template<typename NodeT, typename NameFnT, typename LineNoFnT>
|
|
||||||
void trace_PrintBacktrace(std::vector<NodeT> const &stack, NameFnT getName, LineNoFnT getLineNo) {
|
|
||||||
size_t n = stack.size();
|
|
||||||
if (n == 0) {
|
|
||||||
return; // LCOV_EXCL_LINE
|
|
||||||
}
|
|
||||||
|
|
||||||
auto printLocation = [&](size_t i) {
|
|
||||||
NodeT const &item = stack[n - i - 1];
|
|
||||||
style_Reset(stderr);
|
|
||||||
if (!tracing.collapse) {
|
|
||||||
fputs(" ", stderr); // Just three spaces; the fourth will be printed next
|
|
||||||
}
|
|
||||||
fprintf(stderr, " %s ", i == 0 ? "at" : TRACE_SEPARATOR);
|
|
||||||
style_Set(stderr, STYLE_CYAN, true);
|
|
||||||
fputs(getName(item), stderr);
|
|
||||||
style_Set(stderr, STYLE_CYAN, false);
|
|
||||||
fprintf(stderr, "(%" PRIu32 ")", getLineNo(item));
|
|
||||||
if (!tracing.collapse) {
|
|
||||||
putc('\n', stderr);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (tracing.collapse) {
|
|
||||||
fputs(" ", stderr); // Just three spaces; the fourth will be handled by the loop
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tracing.depth == 0 || static_cast<size_t>(tracing.depth) >= n) {
|
|
||||||
for (size_t i = 0; i < n; ++i) {
|
|
||||||
printLocation(i);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
size_t last = tracing.depth / 2;
|
|
||||||
size_t first = tracing.depth - last;
|
|
||||||
size_t skipped = n - tracing.depth;
|
|
||||||
for (size_t i = 0; i < first; ++i) {
|
|
||||||
printLocation(i);
|
|
||||||
}
|
|
||||||
style_Reset(stderr);
|
|
||||||
|
|
||||||
if (tracing.collapse) {
|
|
||||||
fputs(" " TRACE_SEPARATOR, stderr);
|
|
||||||
} else {
|
|
||||||
fputs(" ", stderr); // Just three spaces; the fourth will be printed next
|
|
||||||
}
|
|
||||||
fprintf(stderr, " ...%zu more%s", skipped, last ? "..." : "");
|
|
||||||
if (!tracing.collapse) {
|
|
||||||
putc('\n', stderr);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = n - last; i < n; ++i) {
|
|
||||||
printLocation(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tracing.collapse) {
|
|
||||||
putc('\n', stderr);
|
|
||||||
}
|
|
||||||
style_Reset(stderr);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // RGBDS_BACKTRACE_HPP
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#ifndef RGBDS_CLI_HPP
|
|
||||||
#define RGBDS_CLI_HPP
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "extern/getopt.hpp" // option
|
|
||||||
#include "usage.hpp"
|
|
||||||
|
|
||||||
void cli_ParseArgs(
|
|
||||||
int argc,
|
|
||||||
char *argv[],
|
|
||||||
char const *shortOpts,
|
|
||||||
option const *longOpts,
|
|
||||||
void (*parseArg)(int, char *),
|
|
||||||
Usage usage
|
|
||||||
);
|
|
||||||
|
|
||||||
#endif // RGBDS_CLI_HPP
|
|
||||||
@@ -1,211 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#ifndef RGBDS_DIAGNOSTICS_HPP
|
|
||||||
#define RGBDS_DIAGNOSTICS_HPP
|
|
||||||
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include <optional>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string>
|
|
||||||
#include <utility>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "helpers.hpp"
|
|
||||||
#include "itertools.hpp"
|
|
||||||
|
|
||||||
[[gnu::format(printf, 1, 2)]]
|
|
||||||
void warnx(char const *fmt, ...);
|
|
||||||
|
|
||||||
enum WarningAbled { WARNING_DEFAULT, WARNING_ENABLED, WARNING_DISABLED };
|
|
||||||
|
|
||||||
struct WarningState {
|
|
||||||
WarningAbled state;
|
|
||||||
WarningAbled error;
|
|
||||||
|
|
||||||
void update(WarningState other);
|
|
||||||
};
|
|
||||||
|
|
||||||
std::pair<WarningState, std::optional<uint32_t>> getInitialWarningState(std::string &flag);
|
|
||||||
|
|
||||||
template<typename LevelEnumT>
|
|
||||||
struct WarningFlag {
|
|
||||||
char const *name;
|
|
||||||
LevelEnumT level;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum WarningBehavior { DISABLED, ENABLED, ERROR };
|
|
||||||
|
|
||||||
template<typename WarningEnumT>
|
|
||||||
struct ParamWarning {
|
|
||||||
WarningEnumT firstID;
|
|
||||||
WarningEnumT lastID;
|
|
||||||
uint8_t defaultLevel;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename WarningEnumT>
|
|
||||||
struct DiagnosticsState {
|
|
||||||
WarningState flagStates[WarningEnumT::NB_WARNINGS];
|
|
||||||
WarningState metaStates[WarningEnumT::NB_WARNINGS];
|
|
||||||
bool warningsEnabled = true;
|
|
||||||
bool warningsAreErrors = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename LevelEnumT, typename WarningEnumT>
|
|
||||||
struct Diagnostics {
|
|
||||||
std::vector<WarningFlag<LevelEnumT>> metaWarnings;
|
|
||||||
std::vector<WarningFlag<LevelEnumT>> warningFlags;
|
|
||||||
std::vector<ParamWarning<WarningEnumT>> paramWarnings;
|
|
||||||
DiagnosticsState<WarningEnumT> state;
|
|
||||||
uint64_t nbErrors;
|
|
||||||
|
|
||||||
void incrementErrors() {
|
|
||||||
if (nbErrors != UINT64_MAX) {
|
|
||||||
++nbErrors;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
WarningBehavior getWarningBehavior(WarningEnumT id) const;
|
|
||||||
void processWarningFlag(char const *flag);
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename LevelEnumT, typename WarningEnumT>
|
|
||||||
WarningBehavior Diagnostics<LevelEnumT, WarningEnumT>::getWarningBehavior(WarningEnumT id) const {
|
|
||||||
// Check if warnings are globally disabled
|
|
||||||
if (!state.warningsEnabled) {
|
|
||||||
return WarningBehavior::DISABLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the state of this warning flag
|
|
||||||
WarningState const &flagState = state.flagStates[id];
|
|
||||||
WarningState const &metaState = state.metaStates[id];
|
|
||||||
|
|
||||||
// If subsequent checks determine that the warning flag is enabled, this checks whether it has
|
|
||||||
// -Werror without -Wno-error=<flag> or -Wno-error=<meta>, which makes it into an error
|
|
||||||
bool warningIsError = state.warningsAreErrors && flagState.error != WARNING_DISABLED
|
|
||||||
&& metaState.error != WARNING_DISABLED;
|
|
||||||
WarningBehavior enabledBehavior =
|
|
||||||
warningIsError ? WarningBehavior::ERROR : WarningBehavior::ENABLED;
|
|
||||||
|
|
||||||
// First, check the state of the specific warning flag
|
|
||||||
if (flagState.state == WARNING_DISABLED) { // -Wno-<flag>
|
|
||||||
return WarningBehavior::DISABLED;
|
|
||||||
}
|
|
||||||
if (flagState.error == WARNING_ENABLED) { // -Werror=<flag>
|
|
||||||
return WarningBehavior::ERROR;
|
|
||||||
}
|
|
||||||
if (flagState.state == WARNING_ENABLED) { // -W<flag>
|
|
||||||
return enabledBehavior;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If no flag is specified, check the state of the "meta" flags that affect this warning flag
|
|
||||||
if (metaState.state == WARNING_DISABLED) { // -Wno-<meta>
|
|
||||||
return WarningBehavior::DISABLED;
|
|
||||||
}
|
|
||||||
if (metaState.error == WARNING_ENABLED) { // -Werror=<meta>
|
|
||||||
return WarningBehavior::ERROR;
|
|
||||||
}
|
|
||||||
if (metaState.state == WARNING_ENABLED) { // -W<meta>
|
|
||||||
return enabledBehavior;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If no meta flag is specified, check the default state of this warning flag
|
|
||||||
if (warningFlags[id].level == LevelEnumT::LEVEL_DEFAULT) { // enabled by default
|
|
||||||
return enabledBehavior;
|
|
||||||
}
|
|
||||||
|
|
||||||
// No flag enables this warning, explicitly or implicitly
|
|
||||||
return WarningBehavior::DISABLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename LevelEnumT, typename WarningEnumT>
|
|
||||||
void Diagnostics<LevelEnumT, WarningEnumT>::processWarningFlag(char const *flag) {
|
|
||||||
std::string rootFlag = flag;
|
|
||||||
|
|
||||||
// Check for `-Werror` or `-Wno-error` to return early
|
|
||||||
if (rootFlag == "error") {
|
|
||||||
// `-Werror` promotes warnings to errors
|
|
||||||
state.warningsAreErrors = true;
|
|
||||||
return;
|
|
||||||
} else if (rootFlag == "no-error") {
|
|
||||||
// `-Wno-error` disables promotion of warnings to errors
|
|
||||||
state.warningsAreErrors = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto [flagState, param] = getInitialWarningState(rootFlag);
|
|
||||||
|
|
||||||
// Try to match the flag against a parametric warning
|
|
||||||
// If there was an equals sign, it will have set `param`; if not, `param` will be 0,
|
|
||||||
// which applies to all levels
|
|
||||||
for (ParamWarning<WarningEnumT> const ¶mWarning : paramWarnings) {
|
|
||||||
WarningEnumT baseID = paramWarning.firstID;
|
|
||||||
uint8_t maxParam = paramWarning.lastID - baseID + 1;
|
|
||||||
assume(paramWarning.defaultLevel <= maxParam);
|
|
||||||
|
|
||||||
if (rootFlag != warningFlags[baseID].name) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If making the warning an error but param is 0, set to the maximum
|
|
||||||
// This accommodates `-Werror=<flag>`, but also `-Werror=<flag>=0`, which is
|
|
||||||
// thus filtered out by the caller.
|
|
||||||
// A param of 0 makes sense for disabling everything, but neither for
|
|
||||||
// enabling nor "erroring". Use the default for those.
|
|
||||||
if (!param.has_value() || *param == 0) {
|
|
||||||
param = paramWarning.defaultLevel;
|
|
||||||
} else if (*param > maxParam) {
|
|
||||||
warnx(
|
|
||||||
"Invalid warning flag parameter \"%s=%" PRIu32 "\"; capping at maximum %" PRIu8,
|
|
||||||
rootFlag.c_str(),
|
|
||||||
*param,
|
|
||||||
maxParam
|
|
||||||
);
|
|
||||||
*param = maxParam;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the first <param> to enabled/error, and disable the rest
|
|
||||||
for (uint32_t ofs = 0; ofs < maxParam; ++ofs) {
|
|
||||||
if (WarningState &warning = state.flagStates[baseID + ofs]; ofs < *param) {
|
|
||||||
warning.update(flagState);
|
|
||||||
} else {
|
|
||||||
warning.state = WARNING_DISABLED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (param.has_value()) {
|
|
||||||
warnx("Unknown warning flag parameter \"%s=%" PRIu32 "\"", rootFlag.c_str(), *param);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to match against a "meta" warning
|
|
||||||
for (WarningFlag<LevelEnumT> const &metaWarning : metaWarnings) {
|
|
||||||
if (rootFlag != metaWarning.name) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set each of the warning flags that meets this level
|
|
||||||
for (WarningEnumT id : EnumSeq(WarningEnumT::NB_WARNINGS)) {
|
|
||||||
if (metaWarning.level >= warningFlags[id].level) {
|
|
||||||
state.metaStates[id].update(flagState);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to match against a "normal" flag
|
|
||||||
for (WarningEnumT id : EnumSeq(WarningEnumT::NB_PLAIN_WARNINGS)) {
|
|
||||||
if (rootFlag == warningFlags[id].name) {
|
|
||||||
state.flagStates[id].update(flagState);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
warnx("Unknown warning flag \"%s\"", rootFlag.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // RGBDS_DIAGNOSTICS_HPP
|
|
||||||
21
include/error.h
Normal file
21
include/error.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of RGBDS.
|
||||||
|
*
|
||||||
|
* Copyright (c) 1997-2021, RGBDS contributors.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RGBDS_ERROR_H
|
||||||
|
#define RGBDS_ERROR_H
|
||||||
|
|
||||||
|
#include "helpers.h"
|
||||||
|
#include "platform.h"
|
||||||
|
|
||||||
|
void warn(char const NONNULL(fmt), ...) format_(printf, 1, 2);
|
||||||
|
void warnx(char const NONNULL(fmt), ...) format_(printf, 1, 2);
|
||||||
|
|
||||||
|
_Noreturn void err(char const NONNULL(fmt), ...) format_(printf, 1, 2);
|
||||||
|
_Noreturn void errx(char const NONNULL(fmt), ...) format_(printf, 1, 2);
|
||||||
|
|
||||||
|
#endif /* RGBDS_ERROR_H */
|
||||||
46
include/extern/getopt.h
vendored
Normal file
46
include/extern/getopt.h
vendored
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2005-2020 Rich Felker, et al.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
* a copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This implementation was taken from musl and modified for RGBDS */
|
||||||
|
|
||||||
|
#ifndef RGBDS_EXTERN_GETOPT_H
|
||||||
|
#define RGBDS_EXTERN_GETOPT_H
|
||||||
|
|
||||||
|
extern char *musl_optarg;
|
||||||
|
extern int musl_optind, musl_opterr, musl_optopt, musl_optreset;
|
||||||
|
|
||||||
|
struct option {
|
||||||
|
char const *name;
|
||||||
|
int has_arg;
|
||||||
|
int *flag;
|
||||||
|
int val;
|
||||||
|
};
|
||||||
|
|
||||||
|
int musl_getopt_long_only(int argc, char **argv, char const *optstring,
|
||||||
|
const struct option *longopts, int *idx);
|
||||||
|
|
||||||
|
#define no_argument 0
|
||||||
|
#define required_argument 1
|
||||||
|
#define optional_argument 2
|
||||||
|
|
||||||
|
#endif
|
||||||
26
include/extern/getopt.hpp
vendored
26
include/extern/getopt.hpp
vendored
@@ -1,26 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
// This implementation was taken from musl and modified for RGBDS
|
|
||||||
|
|
||||||
#ifndef RGBDS_EXTERN_GETOPT_HPP
|
|
||||||
#define RGBDS_EXTERN_GETOPT_HPP
|
|
||||||
|
|
||||||
// clang-format off: vertically align values
|
|
||||||
static constexpr int no_argument = 0;
|
|
||||||
static constexpr int required_argument = 1;
|
|
||||||
static constexpr int optional_argument = 2;
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
extern char *musl_optarg;
|
|
||||||
extern int musl_optind, musl_optopt;
|
|
||||||
|
|
||||||
struct option {
|
|
||||||
char const *name;
|
|
||||||
int has_arg;
|
|
||||||
int *flag;
|
|
||||||
int val;
|
|
||||||
};
|
|
||||||
|
|
||||||
int musl_getopt_long_only(int argc, char **argv, char const *optstring, option const *longopts);
|
|
||||||
|
|
||||||
#endif // RGBDS_EXTERN_GETOPT_HPP
|
|
||||||
14
include/extern/utf8decoder.h
vendored
Normal file
14
include/extern/utf8decoder.h
vendored
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of RGBDS.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018, Antonio Nino Diaz and RGBDS contributors.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EXTERN_UTF8DECODER_H
|
||||||
|
#define EXTERN_UTF8DECODER_H
|
||||||
|
|
||||||
|
uint32_t decode(uint32_t *state, uint32_t *codep, uint8_t byte);
|
||||||
|
|
||||||
|
#endif /* EXTERN_UTF8DECODER_H */
|
||||||
13
include/extern/utf8decoder.hpp
vendored
13
include/extern/utf8decoder.hpp
vendored
@@ -1,13 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#ifndef RGBDS_EXTERN_UTF8DECODER_HPP
|
|
||||||
#define RGBDS_EXTERN_UTF8DECODER_HPP
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define UTF8_ACCEPT 0
|
|
||||||
#define UTF8_REJECT 12
|
|
||||||
|
|
||||||
uint32_t decode(uint32_t *state, uint32_t *codep, uint8_t byte);
|
|
||||||
|
|
||||||
#endif // RGBDS_EXTERN_UTF8DECODER_HPP
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#ifndef RGBDS_FILE_HPP
|
|
||||||
#define RGBDS_FILE_HPP
|
|
||||||
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <fstream>
|
|
||||||
#include <ios>
|
|
||||||
#include <iostream>
|
|
||||||
#include <streambuf>
|
|
||||||
#include <string>
|
|
||||||
#include <variant>
|
|
||||||
|
|
||||||
#include "helpers.hpp" // assume
|
|
||||||
#include "platform.hpp"
|
|
||||||
|
|
||||||
class File {
|
|
||||||
std::variant<std::streambuf *, std::filebuf> _file;
|
|
||||||
|
|
||||||
public:
|
|
||||||
File() : _file(nullptr) {}
|
|
||||||
|
|
||||||
// This should only be called once, and before doing any `->` operations.
|
|
||||||
// Returns `nullptr` on error, and a non-null pointer otherwise.
|
|
||||||
File *open(std::string const &path, std::ios_base::openmode mode) {
|
|
||||||
if (path != "-") {
|
|
||||||
return _file.emplace<std::filebuf>().open(path, mode) ? this : nullptr;
|
|
||||||
} else if (mode & std::ios_base::in) {
|
|
||||||
assume(!(mode & std::ios_base::out));
|
|
||||||
_file.emplace<std::streambuf *>(std::cin.rdbuf());
|
|
||||||
if (setmode(STDIN_FILENO, (mode & std::ios_base::binary) ? O_BINARY : O_TEXT) == -1) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
assume(mode & std::ios_base::out);
|
|
||||||
_file.emplace<std::streambuf *>(std::cout.rdbuf());
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
std::streambuf &operator*() {
|
|
||||||
return std::holds_alternative<std::filebuf>(_file) ? std::get<std::filebuf>(_file)
|
|
||||||
: *std::get<std::streambuf *>(_file);
|
|
||||||
}
|
|
||||||
std::streambuf const &operator*() const {
|
|
||||||
// The non-`const` version does not perform any modifications, so it's okay.
|
|
||||||
return **const_cast<File *>(this);
|
|
||||||
}
|
|
||||||
std::streambuf *operator->() { return &**this; }
|
|
||||||
std::streambuf const *operator->() const {
|
|
||||||
// See the `operator*` equivalent.
|
|
||||||
return const_cast<File *>(this)->operator->();
|
|
||||||
}
|
|
||||||
|
|
||||||
char const *c_str(std::string const &path) const {
|
|
||||||
return std::holds_alternative<std::filebuf>(_file) ? path.c_str()
|
|
||||||
: std::get<std::streambuf *>(_file) == std::cin.rdbuf() ? "<stdin>"
|
|
||||||
: "<stdout>";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // RGBDS_FILE_HPP
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#ifndef RGBDS_FIX_FIX_HPP
|
|
||||||
#define RGBDS_FIX_FIX_HPP
|
|
||||||
|
|
||||||
bool fix_ProcessFile(char const *name, char const *outputName);
|
|
||||||
|
|
||||||
#endif // RGBDS_FIX_FIX_HPP
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#ifndef RGBDS_FIX_MAIN_HPP
|
|
||||||
#define RGBDS_FIX_MAIN_HPP
|
|
||||||
|
|
||||||
#include <optional>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "fix/mbc.hpp" // UNSPECIFIED, MbcType
|
|
||||||
|
|
||||||
// clang-format off: vertically align values
|
|
||||||
static constexpr uint8_t FIX_LOGO = 1 << 7;
|
|
||||||
static constexpr uint8_t TRASH_LOGO = 1 << 6;
|
|
||||||
static constexpr uint8_t FIX_HEADER_SUM = 1 << 5;
|
|
||||||
static constexpr uint8_t TRASH_HEADER_SUM = 1 << 4;
|
|
||||||
static constexpr uint8_t FIX_GLOBAL_SUM = 1 << 3;
|
|
||||||
static constexpr uint8_t TRASH_GLOBAL_SUM = 1 << 2;
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
enum Model { DMG, BOTH, CGB };
|
|
||||||
|
|
||||||
struct Options {
|
|
||||||
uint8_t fixSpec = 0; // -f, -v
|
|
||||||
Model model = DMG; // -C, -c
|
|
||||||
bool japanese = true; // -j
|
|
||||||
uint16_t oldLicensee = UNSPECIFIED; // -l
|
|
||||||
uint16_t romVersion = UNSPECIFIED; // -n
|
|
||||||
uint16_t padValue = UNSPECIFIED; // -p
|
|
||||||
uint16_t ramSize = UNSPECIFIED; // -r
|
|
||||||
bool sgb = false; // -s
|
|
||||||
|
|
||||||
std::optional<std::string> gameID; // -i
|
|
||||||
uint8_t gameIDLen;
|
|
||||||
|
|
||||||
std::optional<std::string> newLicensee; // -k
|
|
||||||
uint8_t newLicenseeLen;
|
|
||||||
|
|
||||||
std::optional<std::string> logoFilename; // -L
|
|
||||||
uint8_t logo[48] = {};
|
|
||||||
|
|
||||||
MbcType cartridgeType = MBC_NONE; // -m
|
|
||||||
uint8_t tpp1Rev[2];
|
|
||||||
|
|
||||||
std::optional<std::string> title; // -t
|
|
||||||
uint8_t titleLen;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern Options options;
|
|
||||||
|
|
||||||
#endif // RGBDS_FIX_MAIN_HPP
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#ifndef RGBDS_FIX_MBC_HPP
|
|
||||||
#define RGBDS_FIX_MBC_HPP
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
constexpr uint16_t UNSPECIFIED = 0x200;
|
|
||||||
static_assert(UNSPECIFIED > 0xFF, "UNSPECIFIED should not be in byte range!");
|
|
||||||
|
|
||||||
enum MbcType {
|
|
||||||
ROM = 0x00,
|
|
||||||
ROM_RAM = 0x08,
|
|
||||||
ROM_RAM_BATTERY = 0x09,
|
|
||||||
|
|
||||||
MBC1 = 0x01,
|
|
||||||
MBC1_RAM = 0x02,
|
|
||||||
MBC1_RAM_BATTERY = 0x03,
|
|
||||||
|
|
||||||
MBC2 = 0x05,
|
|
||||||
MBC2_BATTERY = 0x06,
|
|
||||||
|
|
||||||
MMM01 = 0x0B,
|
|
||||||
MMM01_RAM = 0x0C,
|
|
||||||
MMM01_RAM_BATTERY = 0x0D,
|
|
||||||
|
|
||||||
MBC3 = 0x11,
|
|
||||||
MBC3_TIMER_BATTERY = 0x0F,
|
|
||||||
MBC3_TIMER_RAM_BATTERY = 0x10,
|
|
||||||
MBC3_RAM = 0x12,
|
|
||||||
MBC3_RAM_BATTERY = 0x13,
|
|
||||||
|
|
||||||
MBC5 = 0x19,
|
|
||||||
MBC5_RAM = 0x1A,
|
|
||||||
MBC5_RAM_BATTERY = 0x1B,
|
|
||||||
MBC5_RUMBLE = 0x1C,
|
|
||||||
MBC5_RUMBLE_RAM = 0x1D,
|
|
||||||
MBC5_RUMBLE_RAM_BATTERY = 0x1E,
|
|
||||||
|
|
||||||
MBC6 = 0x20,
|
|
||||||
|
|
||||||
MBC7_SENSOR_RUMBLE_RAM_BATTERY = 0x22,
|
|
||||||
|
|
||||||
POCKET_CAMERA = 0xFC,
|
|
||||||
|
|
||||||
BANDAI_TAMA5 = 0xFD,
|
|
||||||
|
|
||||||
HUC3 = 0xFE,
|
|
||||||
|
|
||||||
HUC1_RAM_BATTERY = 0xFF,
|
|
||||||
|
|
||||||
// "Extended" values (still valid, but not directly actionable)
|
|
||||||
|
|
||||||
// A high byte of 0x01 means TPP1, the low byte is the requested features
|
|
||||||
// This does not include SRAM, which is instead implied by a non-zero SRAM size
|
|
||||||
// Note: Multiple rumble speeds imply rumble
|
|
||||||
TPP1 = 0x100,
|
|
||||||
TPP1_RUMBLE = 0x101,
|
|
||||||
TPP1_MULTIRUMBLE_RUMBLE = 0x103,
|
|
||||||
TPP1_TIMER = 0x104,
|
|
||||||
TPP1_TIMER_RUMBLE = 0x105,
|
|
||||||
TPP1_TIMER_MULTIRUMBLE_RUMBLE = 0x107,
|
|
||||||
TPP1_BATTERY = 0x108,
|
|
||||||
TPP1_BATTERY_RUMBLE = 0x109,
|
|
||||||
TPP1_BATTERY_MULTIRUMBLE_RUMBLE = 0x10B,
|
|
||||||
TPP1_BATTERY_TIMER = 0x10C,
|
|
||||||
TPP1_BATTERY_TIMER_RUMBLE = 0x10D,
|
|
||||||
TPP1_BATTERY_TIMER_MULTIRUMBLE_RUMBLE = 0x10F,
|
|
||||||
|
|
||||||
// Error values
|
|
||||||
MBC_NONE = UNSPECIFIED, // No MBC specified, do not act on it
|
|
||||||
};
|
|
||||||
|
|
||||||
bool mbc_HasRAM(MbcType type);
|
|
||||||
char const *mbc_Name(MbcType type);
|
|
||||||
MbcType mbc_ParseName(char const *name, uint8_t &tpp1Major, uint8_t &tpp1Minor);
|
|
||||||
|
|
||||||
#endif // RGBDS_FIX_MBC_HPP
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#ifndef RGBDS_FIX_WARNING_HPP
|
|
||||||
#define RGBDS_FIX_WARNING_HPP
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "diagnostics.hpp"
|
|
||||||
|
|
||||||
enum WarningLevel {
|
|
||||||
LEVEL_DEFAULT, // Warnings that are enabled by default
|
|
||||||
LEVEL_ALL, // Warnings that probably indicate an error
|
|
||||||
LEVEL_EVERYTHING, // Literally every warning
|
|
||||||
};
|
|
||||||
|
|
||||||
enum WarningID {
|
|
||||||
WARNING_MBC, // Issues with MBC specs
|
|
||||||
WARNING_OBSOLETE, // Obsolete/deprecated things
|
|
||||||
WARNING_OVERWRITE, // Overwriting non-zero bytes
|
|
||||||
WARNING_SGB, // SGB flag conflicts with old licensee code
|
|
||||||
WARNING_TRUNCATION, // Truncating values to fit
|
|
||||||
|
|
||||||
NB_PLAIN_WARNINGS,
|
|
||||||
|
|
||||||
NB_WARNINGS = NB_PLAIN_WARNINGS,
|
|
||||||
};
|
|
||||||
|
|
||||||
extern Diagnostics<WarningLevel, WarningID> warnings;
|
|
||||||
|
|
||||||
// Warns the user about problems that don't prevent fixing the ROM header
|
|
||||||
[[gnu::format(printf, 2, 3)]]
|
|
||||||
void warning(WarningID id, char const *fmt, ...);
|
|
||||||
|
|
||||||
// Prints an error, and increments the error count
|
|
||||||
[[gnu::format(printf, 1, 2)]]
|
|
||||||
void error(char const *fmt, ...);
|
|
||||||
|
|
||||||
// Prints an error, and exits with failure
|
|
||||||
[[gnu::format(printf, 1, 2), noreturn]]
|
|
||||||
void fatal(char const *fmt, ...);
|
|
||||||
|
|
||||||
uint32_t checkErrors(char const *filename);
|
|
||||||
|
|
||||||
#endif // RGBDS_FIX_WARNING_HPP
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#ifndef RGBDS_GFX_COLOR_SET_HPP
|
|
||||||
#define RGBDS_GFX_COLOR_SET_HPP
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
class ColorSet {
|
|
||||||
public:
|
|
||||||
static constexpr size_t capacity = 4;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Up to 4 colors, sorted, and where SIZE_MAX means the slot is empty
|
|
||||||
// (OK because it's not a valid color index)
|
|
||||||
// Sorting is done on the raw numerical values to lessen `compare`'s complexity
|
|
||||||
std::array<uint16_t, capacity> _colorIndices{UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX};
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Adds the specified color to the set, or **silently drops it** if the set is full.
|
|
||||||
void add(uint16_t color);
|
|
||||||
|
|
||||||
enum ComparisonResult {
|
|
||||||
NEITHER,
|
|
||||||
WE_BIGGER,
|
|
||||||
THEY_BIGGER = -1,
|
|
||||||
};
|
|
||||||
ComparisonResult compare(ColorSet const &other) const;
|
|
||||||
|
|
||||||
size_t size() const;
|
|
||||||
bool empty() const;
|
|
||||||
|
|
||||||
decltype(_colorIndices)::const_iterator begin() const;
|
|
||||||
decltype(_colorIndices)::const_iterator end() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // RGBDS_GFX_COLOR_SET_HPP
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user