mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
76c1995559 | ||
|
|
ae84570f04 | ||
|
|
094a31ef8c | ||
|
|
291dcf3b6c | ||
|
|
a890bd072b | ||
|
|
2f6c808ccb | ||
|
|
e80907abd0 | ||
|
|
25d39155d3 | ||
|
|
77021d229b | ||
|
|
1b250b90b2 | ||
|
|
e2b4723489 | ||
|
|
2507413162 | ||
|
|
e023a84d04 | ||
|
|
34c127d9c3 | ||
|
|
9a930988c2 | ||
|
|
8c4204c542 | ||
|
|
663c1930ec | ||
|
|
30ccf43f44 | ||
|
|
fdc17adbcb | ||
|
|
cc196954f3 | ||
|
|
55b6cfff84 | ||
|
|
1fc73b04eb |
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
|
||||||
105
.clang-format
105
.clang-format
@@ -1,105 +0,0 @@
|
|||||||
AccessModifierOffset: -4
|
|
||||||
AlignAfterOpenBracket: BlockIndent
|
|
||||||
AlignArrayOfStructures: Left
|
|
||||||
AlignConsecutiveAssignments: None
|
|
||||||
AlignConsecutiveBitFields: Consecutive
|
|
||||||
AlignConsecutiveDeclarations: None
|
|
||||||
AlignConsecutiveMacros: Consecutive
|
|
||||||
AlignEscapedNewlines: DontAlign
|
|
||||||
AlignOperands: Align
|
|
||||||
AlignTrailingComments: true
|
|
||||||
AllowShortBlocksOnASingleLine: Empty
|
|
||||||
AllowShortCaseLabelsOnASingleLine: false
|
|
||||||
AllowShortEnumsOnASingleLine: true
|
|
||||||
AllowShortFunctionsOnASingleLine: InlineOnly
|
|
||||||
AllowShortIfStatementsOnASingleLine: Never
|
|
||||||
AllowShortLambdasOnASingleLine: All
|
|
||||||
AllowShortLoopsOnASingleLine: false
|
|
||||||
AlwaysBreakAfterReturnType: None
|
|
||||||
AlwaysBreakBeforeMultilineStrings: false
|
|
||||||
AlwaysBreakTemplateDeclarations: Yes
|
|
||||||
AttributeMacros:
|
|
||||||
- format_
|
|
||||||
- attr_
|
|
||||||
BinPackArguments: false
|
|
||||||
BinPackParameters: false
|
|
||||||
BitFieldColonSpacing: Both
|
|
||||||
BreakAfterAttributes: Always
|
|
||||||
BreakBeforeBinaryOperators: NonAssignment
|
|
||||||
BreakBeforeBraces: Attach
|
|
||||||
BreakBeforeConceptDeclarations: true
|
|
||||||
BreakBeforeTernaryOperators: true
|
|
||||||
BreakConstructorInitializers: BeforeColon
|
|
||||||
BreakInheritanceList: AfterComma
|
|
||||||
BreakStringLiterals: true
|
|
||||||
ColumnLimit: 100
|
|
||||||
CompactNamespaces: false
|
|
||||||
ContinuationIndentWidth: 4
|
|
||||||
Cpp11BracedListStyle: true
|
|
||||||
DeriveLineEnding: true
|
|
||||||
DerivePointerAlignment: false
|
|
||||||
EmptyLineBeforeAccessModifier: Leave
|
|
||||||
FixNamespaceComments: false
|
|
||||||
IncludeBlocks: Regroup
|
|
||||||
IncludeCategories:
|
|
||||||
- Regex: '^<sys/'
|
|
||||||
Priority: 0
|
|
||||||
- Regex: '^<'
|
|
||||||
Priority: 1
|
|
||||||
- Regex: '^"extern/'
|
|
||||||
Priority: 2
|
|
||||||
- Regex: '^"(asm|link|fix|gfx)/'
|
|
||||||
Priority: 3
|
|
||||||
- Regex: '^"'
|
|
||||||
Priority: 2
|
|
||||||
IndentAccessModifiers: false
|
|
||||||
IndentCaseBlocks: false
|
|
||||||
IndentCaseLabels: false
|
|
||||||
IndentExternBlock: Indent
|
|
||||||
IndentGotoLabels: false
|
|
||||||
IndentPPDirectives: BeforeHash
|
|
||||||
IndentRequires: true
|
|
||||||
IndentWidth: 4
|
|
||||||
IndentWrappedFunctionNames: true
|
|
||||||
InsertBraces: true
|
|
||||||
InsertNewlineAtEOF: true
|
|
||||||
# Only support for Javascript as of clang-format 14...
|
|
||||||
# InsertTrailingCommas: Wrapped
|
|
||||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
|
||||||
LambdaBodyIndentation: Signature
|
|
||||||
Language: Cpp
|
|
||||||
MaxEmptyLinesToKeep: 1
|
|
||||||
NamespaceIndentation: None
|
|
||||||
PPIndentWidth: -1
|
|
||||||
PointerAlignment: Right
|
|
||||||
QualifierAlignment: Right
|
|
||||||
ReflowComments: true
|
|
||||||
RemoveParentheses: ReturnStatement
|
|
||||||
RemoveSemicolon: true
|
|
||||||
SortIncludes: CaseSensitive
|
|
||||||
SortUsingDeclarations: true
|
|
||||||
SpaceAfterCStyleCast: false
|
|
||||||
SpaceAfterLogicalNot: false
|
|
||||||
SpaceAfterTemplateKeyword: false
|
|
||||||
SpaceAroundPointerQualifiers: Both
|
|
||||||
SpaceBeforeAssignmentOperators: true
|
|
||||||
SpaceBeforeCaseColon: false
|
|
||||||
SpaceBeforeCpp11BracedList: false
|
|
||||||
SpaceBeforeCtorInitializerColon: true
|
|
||||||
SpaceBeforeInheritanceColon: true
|
|
||||||
SpaceBeforeParens: ControlStatements
|
|
||||||
SpaceBeforeRangeBasedForLoopColon: true
|
|
||||||
SpaceBeforeSquareBrackets: false
|
|
||||||
SpaceInEmptyBlock: false
|
|
||||||
SpaceInEmptyParentheses: false
|
|
||||||
SpacesBeforeTrailingComments: 1
|
|
||||||
SpacesInAngles: false
|
|
||||||
SpacesInCStyleCastParentheses: false
|
|
||||||
SpacesInConditionalStatement: false
|
|
||||||
SpacesInContainerLiterals: false
|
|
||||||
SpacesInParentheses: false
|
|
||||||
SpacesInSquareBrackets: false
|
|
||||||
Standard: c++20
|
|
||||||
TabWidth: 4
|
|
||||||
UseCRLF: false
|
|
||||||
UseTab: ForIndentation
|
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
[*]
|
|
||||||
root = true
|
|
||||||
indent_style = tab
|
|
||||||
indent_size = tab
|
|
||||||
tab_width = 8
|
|
||||||
charset = utf-8
|
|
||||||
insert_final_newline = true
|
|
||||||
trim_trailing_whitespace = true
|
|
||||||
end_of_line = lf
|
|
||||||
18
.gitattributes
vendored
18
.gitattributes
vendored
@@ -1,18 +0,0 @@
|
|||||||
# Shell scripts need Unix line endings (see https://github.com/gbdev/rgbds/issues/841)
|
|
||||||
*.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.bak/FUNDING.yml
Normal file
3
.github.bak/FUNDING.yml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
github: avivace
|
||||||
|
patreon: gbdev01
|
||||||
|
open_collective: gbdev
|
||||||
56
.github.bak/actions/doc_postproc.awk
Executable file
56
.github.bak/actions/doc_postproc.awk
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.bak/actions/get-pages.sh
Executable file
113
.github.bak/actions/get-pages.sh
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[@]##*/}"
|
||||||
18
.github.bak/actions/install_deps.sh
Executable file
18
.github.bak/actions/install_deps.sh
Executable file
@@ -0,0 +1,18 @@
|
|||||||
|
case `echo $1 | cut -d '-' -f 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.bak/actions/mingw-configure.sh
Normal file
17
.github.bak/actions/mingw-configure.sh
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.bak/actions/mingw-env.sh
Normal file
16
.github.bak/actions/mingw-env.sh
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.bak/actions/mingw-w64-libpng-dev.sh
Executable file
44
.github.bak/actions/mingw-w64-libpng-dev.sh
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.bak/actions/mingw-w64-libpng-dev.sha256sums
Normal file
2
.github.bak/actions/mingw-w64-libpng-dev.sha256sums
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
10d9e0cb60e2b387a79b355eb7527c0bee2ed8cbd12cf04417cabc4d6976683c libpng-1.6.37-apng.patch.gz
|
||||||
|
505e70834d35383537b6491e7ae8641f1a4bed1876dbfe361201fc80868d88ca libpng-1.6.37.tar.xz
|
||||||
25
.github.bak/workflows/checkpatch.yml
Normal file
25
.github.bak/workflows/checkpatch.yml
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
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
name: Create release docs
|
name: "Create release docs"
|
||||||
on:
|
on:
|
||||||
release:
|
release:
|
||||||
types:
|
types:
|
||||||
@@ -6,27 +6,32 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
if: github.repository_owner == 'gbdev'
|
runs-on: ubuntu-18.04
|
||||||
runs-on: ubuntu-latest
|
|
||||||
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: |
|
||||||
200
.github.bak/workflows/testing.yml
Normal file
200
.github.bak/workflows/testing.yml
Normal file
@@ -0,0 +1,200 @@
|
|||||||
|
name: "Regression testing"
|
||||||
|
on:
|
||||||
|
- push
|
||||||
|
- pull_request
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
unix-testing:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-20.04, ubuntu-18.04, ubuntu-16.04, macos-10.15]
|
||||||
|
cc: [gcc, clang]
|
||||||
|
buildsys: [make, cmake]
|
||||||
|
include:
|
||||||
|
- os: ubuntu-18.04
|
||||||
|
cc: gcc
|
||||||
|
target: develop
|
||||||
|
cmakevars: -DSANITIZERS=ON -DMORE_WARNINGS=ON -DCMAKE_BUILD_TYPE=Debug
|
||||||
|
- os: ubuntu-20.04
|
||||||
|
cc: gcc
|
||||||
|
target: develop
|
||||||
|
cmakevars: -DSANITIZERS=ON -DMORE_WARNINGS=ON -DCMAKE_BUILD_TYPE=Debug
|
||||||
|
fail-fast: false
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Install deps
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
./.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
|
||||||
|
run: |
|
||||||
|
export PATH="/usr/local/opt/bison/bin:$PATH"
|
||||||
|
make ${{ matrix.target }} -j Q= CC=${{ matrix.cc }}
|
||||||
|
sudo make install -j Q=
|
||||||
|
if: matrix.buildsys == 'make'
|
||||||
|
- 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=Release -DCMAKE_C_COMPILER=${{ matrix.cc }} ${{ matrix.cmakevars }}
|
||||||
|
cmake --build build
|
||||||
|
cp build/src/rgb{asm,link,fix,gfx} .
|
||||||
|
sudo cmake --install build
|
||||||
|
if: matrix.buildsys == 'cmake'
|
||||||
|
- name: Package binaries
|
||||||
|
run: |
|
||||||
|
mkdir bins
|
||||||
|
cp rgb{asm,link,fix,gfx} bins
|
||||||
|
- name: Upload binaries
|
||||||
|
uses: actions/upload-artifact@v1
|
||||||
|
with:
|
||||||
|
name: rgbds-canary-${{ matrix.os }}-${{ matrix.cc }}-${{ matrix.buildsys }}
|
||||||
|
path: bins
|
||||||
|
- name: Test
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
test/run-tests.sh
|
||||||
|
|
||||||
|
windows-testing:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
bits: [32, 64]
|
||||||
|
include:
|
||||||
|
- bits: 32
|
||||||
|
arch: x86
|
||||||
|
platform: Win32
|
||||||
|
- bits: 64
|
||||||
|
arch: x86_x64
|
||||||
|
platform: x64
|
||||||
|
fail-fast: false
|
||||||
|
runs-on: windows-2019
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Get zlib, libpng and bison
|
||||||
|
run: | # TODO: use an array
|
||||||
|
$wc = New-Object System.Net.WebClient
|
||||||
|
$wc.DownloadFile('https://www.zlib.net/zlib1211.zip', 'zlib.zip')
|
||||||
|
$hash = (Get-FileHash "zlib.zip" -Algorithm SHA256).Hash
|
||||||
|
if ($hash -ne 'd7510a8ee1918b7d0cad197a089c0a2cd4d6df05fee22389f67f115e738b178d') {
|
||||||
|
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.23/win_flex_bison-2.5.23.zip', 'winflexbison.zip')
|
||||||
|
$hash = (Get-FileHash "winflexbison.zip" -Algorithm SHA256).Hash
|
||||||
|
if ($hash -ne '6AA5C8EA662DA1550020A5804C28BE63FFAA53486DA9F6842E24C379EC422DFC') {
|
||||||
|
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.11 zlib
|
||||||
|
Move-Item lpng1637 libpng
|
||||||
|
- name: Build zlib
|
||||||
|
run: | # BUILD_SHARED_LIBS causes the output DLL to be correctly called `zlib1.dll`
|
||||||
|
cmake -S zlib -B zbuild -A ${{ matrix.platform }} -DCMAKE_INSTALL_PREFIX=install_dir -DBUILD_SHARED_LIBS=ON
|
||||||
|
cmake --build zbuild --config Release
|
||||||
|
cmake --install zbuild
|
||||||
|
- name: Build libpng
|
||||||
|
run: |
|
||||||
|
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
|
||||||
|
cmake --install pngbuild
|
||||||
|
- name: Build Windows binaries
|
||||||
|
run: |
|
||||||
|
cmake -S . -B build -A ${{ matrix.platform }} -DCMAKE_INSTALL_PREFIX=install_dir -DCMAKE_BUILD_TYPE=Release
|
||||||
|
cmake --build build --config Release
|
||||||
|
cmake --install build
|
||||||
|
- name: Package binaries
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
mkdir bins
|
||||||
|
cp install_dir/bin/{rgbasm.exe,rgblink.exe,rgbfix.exe,rgbgfx.exe,zlib1.dll,libpng16.dll} bins
|
||||||
|
- name: Upload Windows binaries
|
||||||
|
uses: actions/upload-artifact@v1
|
||||||
|
with:
|
||||||
|
name: rgbds-canary-win${{ matrix.bits }}
|
||||||
|
path: bins
|
||||||
|
- name: Test
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
cp bins/* .
|
||||||
|
test/run-tests.sh
|
||||||
|
|
||||||
|
windows-xbuild:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
bits: [32, 64]
|
||||||
|
os: [ubuntu-18.04]
|
||||||
|
include:
|
||||||
|
- bits: 32
|
||||||
|
arch: i686
|
||||||
|
triplet: i686-w64-mingw32
|
||||||
|
- bits: 64
|
||||||
|
arch: x86-64
|
||||||
|
triplet: x86_64-w64-mingw32
|
||||||
|
fail-fast: false
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
env:
|
||||||
|
DIST_DIR: win${{ matrix.bits }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Install deps
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
./.github/actions/install_deps.sh ${{ matrix.os }}
|
||||||
|
- name: Install MinGW
|
||||||
|
run: |
|
||||||
|
sudo apt-get install gcc-mingw-w64-${{ matrix.arch }} mingw-w64-tools libz-mingw-w64-dev
|
||||||
|
- name: Install libpng dev headers for MinGW
|
||||||
|
run: |
|
||||||
|
sudo ./.github/actions/mingw-w64-libpng-dev.sh ${{ matrix.triplet }}
|
||||||
|
- name: Cross-build Windows binaries
|
||||||
|
run: |
|
||||||
|
make mingw${{ matrix.bits }} -j Q=
|
||||||
|
- name: Package binaries
|
||||||
|
run: |
|
||||||
|
mkdir bins
|
||||||
|
mv rgbasm bins/rgbasm.exe
|
||||||
|
mv rgblink bins/rgblink.exe
|
||||||
|
mv rgbfix bins/rgbfix.exe
|
||||||
|
mv rgbgfx bins/rgbgfx.exe
|
||||||
|
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
|
||||||
|
uses: actions/upload-artifact@v1
|
||||||
|
with:
|
||||||
|
name: rgbds-canary-mingw-win${{ matrix.bits }}
|
||||||
|
path: bins
|
||||||
|
|
||||||
|
windows-xtesting:
|
||||||
|
needs: windows-xbuild
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
bits: [32, 64]
|
||||||
|
fail-fast: false
|
||||||
|
runs-on: windows-2019
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Retrieve binaries
|
||||||
|
uses: actions/download-artifact@v1
|
||||||
|
with:
|
||||||
|
name: rgbds-canary-mingw-win${{ matrix.bits }}
|
||||||
|
path: bins
|
||||||
|
- name: Extract binaries
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
cp bins/* .
|
||||||
|
- name: Run tests
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
test/run-tests.sh
|
||||||
@@ -1,45 +1,50 @@
|
|||||||
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'
|
runs-on: ubuntu-18.04
|
||||||
runs-on: ubuntu-latest
|
|
||||||
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 +55,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
|
||||||
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
@@ -1,2 +0,0 @@
|
|||||||
open_collective: gbdev
|
|
||||||
github: gbdev
|
|
||||||
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'
|
|
||||||
17
.github/workflows/checkdiff.yml
vendored
17
.github/workflows/checkdiff.yml
vendored
@@ -1,17 +0,0 @@
|
|||||||
name: Diff completeness check
|
|
||||||
on: pull_request
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
checkdiff:
|
|
||||||
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: Check diff
|
|
||||||
working-directory: rgbds
|
|
||||||
run: |
|
|
||||||
make checkdiff "BASE_REF=${{ github.event.pull_request.base.sha }}" Q= | tee log
|
|
||||||
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
|
|
||||||
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/zlib1211.zip', 'zlib.zip')
|
||||||
|
$hash = (Get-FileHash "zlib.zip" -Algorithm SHA256).Hash
|
||||||
|
if ($hash -ne 'd7510a8ee1918b7d0cad197a089c0a2cd4d6df05fee22389f67f115e738b178d') {
|
||||||
|
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.23/win_flex_bison-2.5.23.zip', 'winflexbison.zip')
|
||||||
|
$hash = (Get-FileHash "winflexbison.zip" -Algorithm SHA256).Hash
|
||||||
|
if ($hash -ne '6AA5C8EA662DA1550020A5804C28BE63FFAA53486DA9F6842E24C379EC422DFC') {
|
||||||
|
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.11 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 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: |
|
|
||||||
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 }}
|
|
||||||
389
.github/workflows/testing.yml
vendored
389
.github/workflows/testing.yml
vendored
@@ -1,389 +0,0 @@
|
|||||||
name: Regression testing
|
|
||||||
on:
|
|
||||||
- push
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
unix:
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
os: [ubuntu-22.04, macos-14]
|
|
||||||
cxx: [g++, clang++]
|
|
||||||
buildsys: [make, cmake]
|
|
||||||
exclude:
|
|
||||||
# Don't use `g++` on macOS; it's just an alias to `clang++`.
|
|
||||||
- os: macos-14
|
|
||||||
cxx: g++
|
|
||||||
fail-fast: false
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
steps:
|
|
||||||
- name: Checkout repo
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Install deps
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
./.github/scripts/install_deps.sh ${{ matrix.os }}
|
|
||||||
- name: Build & install using Make
|
|
||||||
if: matrix.buildsys == 'make'
|
|
||||||
run: |
|
|
||||||
make develop -kj Q= CXX=${{ matrix.cxx }}
|
|
||||||
sudo make install -j Q=
|
|
||||||
- name: Build & install using 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
|
|
||||||
run: |
|
|
||||||
mkdir bins
|
|
||||||
cp rgb{asm,link,fix,gfx} bins
|
|
||||||
- name: Upload binaries
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: rgbds-canary-${{ matrix.os }}-${{ matrix.cxx }}-${{ matrix.buildsys }}
|
|
||||||
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 ${{ matrix.os }}
|
|
||||||
- name: Run tests
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
CXX=${{ matrix.cxx }} test/run-tests.sh --os ${{ matrix.os }}
|
|
||||||
|
|
||||||
macos-static:
|
|
||||||
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:
|
|
||||||
matrix:
|
|
||||||
bits: [32, 64]
|
|
||||||
os: [windows-2022, windows-2025]
|
|
||||||
include:
|
|
||||||
- bits: 32
|
|
||||||
arch: x86
|
|
||||||
platform: Win32
|
|
||||||
- bits: 64
|
|
||||||
arch: x86_x64
|
|
||||||
platform: x64
|
|
||||||
fail-fast: false
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
steps:
|
|
||||||
- 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.os }}-${{ matrix.arch }}-${{ hashFiles('zlib/**', 'libpng/**') }}
|
|
||||||
- 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`
|
|
||||||
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
|
|
||||||
- name: Package binaries
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
mkdir bins
|
|
||||||
cp install_dir/bin/{rgbasm.exe,rgblink.exe,rgbfix.exe,rgbgfx.exe,zlib1.dll,libpng16.dll} bins
|
|
||||||
- name: Upload Windows binaries
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: rgbds-canary-w${{ matrix.bits }}-${{ matrix.os }}
|
|
||||||
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 }}-${{ 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
|
|
||||||
run: |
|
|
||||||
cp bins/* .
|
|
||||||
cp bins/*.dll test/gfx
|
|
||||||
test/run-tests.sh --os ${{ matrix.os }}
|
|
||||||
|
|
||||||
windows-mingw-build:
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
bits: [32, 64]
|
|
||||||
include:
|
|
||||||
- bits: 32
|
|
||||||
arch: i686
|
|
||||||
triplet: i686-w64-mingw32
|
|
||||||
- bits: 64
|
|
||||||
arch: x86-64
|
|
||||||
triplet: x86_64-w64-mingw32
|
|
||||||
fail-fast: false
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
env:
|
|
||||||
DIST_DIR: win${{ matrix.bits }}
|
|
||||||
steps:
|
|
||||||
- name: Checkout repo
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Install deps
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
./.github/scripts/install_deps.sh ubuntu
|
|
||||||
- name: Install MinGW
|
|
||||||
run: | # dpkg-dev is apparently required for pkg-config for cross-building
|
|
||||||
sudo apt-get install g++-mingw-w64-${{ matrix.arch }}-win32 mingw-w64-tools libz-mingw-w64-dev dpkg-dev
|
|
||||||
- name: Install libpng dev headers for MinGW
|
|
||||||
run: |
|
|
||||||
./.github/scripts/mingw-w64-libpng-dev.sh ${{ matrix.triplet }}
|
|
||||||
- name: Cross-build Windows binaries
|
|
||||||
run: |
|
|
||||||
make mingw${{ matrix.bits }} -kj Q=
|
|
||||||
- name: Package binaries
|
|
||||||
run: | # DLL dependencies can be figured out using e.g. Dependency Walker or objdump -p
|
|
||||||
mkdir bins
|
|
||||||
mv -v rgb{asm,link,fix,gfx}.exe bins/
|
|
||||||
cp -v /usr/${{ matrix.triplet }}/lib/zlib1.dll bins
|
|
||||||
cp -v /usr/${{ matrix.triplet }}/bin/libpng16-16.dll bins
|
|
||||||
cp -v /usr/lib/gcc/${{ matrix.triplet }}/10-win32/lib{ssp-0,stdc++-6}.dll bins
|
|
||||||
[ "${{ matrix.bits }}" -ne 32 ] || cp -v /usr/lib/gcc/${{ matrix.triplet }}/10-win32/libgcc_s_dw2-1.dll bins
|
|
||||||
- name: Upload Windows binaries
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: rgbds-canary-mingw-win${{ matrix.bits }}
|
|
||||||
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:
|
|
||||||
needs: windows-mingw-build
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
os: [windows-2022, windows-2025]
|
|
||||||
bits: [32, 64]
|
|
||||||
fail-fast: false
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
steps:
|
|
||||||
- name: Checkout repo
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Retrieve binaries
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: rgbds-canary-mingw-win${{ matrix.bits }}
|
|
||||||
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
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
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
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
test/run-tests.sh --os ${{ matrix.os }}
|
|
||||||
|
|
||||||
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: "15.0"
|
|
||||||
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
|
|
||||||
24
.gitignore
vendored
24
.gitignore
vendored
@@ -1,18 +1,16 @@
|
|||||||
/rgbasm
|
rgbasm
|
||||||
/rgblink
|
rgblink
|
||||||
/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/
|
test/pokecrystal
|
||||||
callgrind.out.*
|
test/pokered
|
||||||
|
test/ucity
|
||||||
|
|||||||
117
CMakeLists.txt
117
CMakeLists.txt
@@ -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)
|
||||||
@@ -22,85 +25,54 @@ endif()
|
|||||||
|
|
||||||
option(SANITIZERS "Build with sanitizers enabled" OFF) # Ignored on MSVC
|
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
|
||||||
|
option(TRACE_PARSER "Trace parser execution" OFF)
|
||||||
|
option(TRACE_LEXER "Trace lexer execution" OFF)
|
||||||
|
|
||||||
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")
|
|
||||||
# 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)
|
||||||
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
|
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "-g -Og -fno-omit-frame-pointer -fno-optimize-sibling-calls ${CMAKE_CXX_FLAGS_DEBUG}"
|
|
||||||
CACHE STRING "" FORCE)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(MORE_WARNINGS)
|
if(MORE_WARNINGS)
|
||||||
add_compile_options(-Werror -Wextra
|
add_compile_options(-Werror -Wextra -Wno-type-limits
|
||||||
-Walloc-zero -Wcast-align -Wcast-qual -Wduplicated-branches -Wduplicated-cond
|
-Wno-sign-compare -Wvla -Wformat -Wformat-security -Wformat-overflow=2
|
||||||
-Wfloat-equal -Wlogical-op -Wnull-dereference -Wold-style-cast -Wshift-overflow=2
|
-Wformat-truncation=1 -Wformat-y2k -Wswitch-enum -Wunused
|
||||||
-Wstringop-overflow=4 -Wtrampolines -Wundef -Wuninitialized -Wunused -Wshadow
|
-Wuninitialized -Wunknown-pragmas -Wstrict-overflow=5
|
||||||
-Wformat=2 -Wformat-overflow=2 -Wformat-truncation=1
|
-Wstringop-overflow=4 -Walloc-zero -Wduplicated-cond
|
||||||
-Wno-format-nonliteral -Wno-strict-overflow
|
-Wfloat-equal -Wshadow -Wcast-qual -Wcast-align -Wlogical-op
|
||||||
-Wno-unused-but-set-variable # bison's `yynerrs_` is incremented but unused
|
-Wnested-externs -Wno-aggressive-loop-optimizations -Winline
|
||||||
-Wno-type-limits -Wno-tautological-constant-out-of-range-compare
|
-Wundef -Wstrict-prototypes -Wold-style-definition)
|
||||||
-Wvla # MSVC does not support VLAs
|
|
||||||
-Wno-unknown-warning-option) # Clang shouldn't diagnose unknown warnings
|
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Use versioning consistent with Makefile
|
# Use versioning consistent with Makefile
|
||||||
# the git revision is used but uses the fallback in an archive
|
# the git revision is used but uses the fallback in an archive
|
||||||
|
|
||||||
find_program(GIT git)
|
execute_process(COMMAND git describe --tags --dirty --always
|
||||||
if(GIT)
|
OUTPUT_VARIABLE GIT_REV
|
||||||
execute_process(COMMAND ${GIT} --git-dir=.git -c safe.directory='*' describe --tags --dirty --always
|
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
|
||||||
OUTPUT_VARIABLE GIT_REV OUTPUT_STRIP_TRAILING_WHITESPACE
|
|
||||||
ERROR_QUIET)
|
ERROR_QUIET)
|
||||||
message(STATUS "RGBDS version: ${GIT_REV}")
|
string(STRIP "${GIT_REV}" GIT_REV)
|
||||||
else(GIT)
|
|
||||||
message(STATUS "Cannot determine RGBDS version (Git not installed), falling back")
|
|
||||||
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)
|
add_definitions(-DBUILD_VERSION_STRING="${GIT_REV}")
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
|
||||||
|
set(CMAKE_C_STANDARD 11)
|
||||||
|
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)
|
||||||
@@ -116,19 +88,10 @@ if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(MANDIR "share/man")
|
if(TRACE_PARSER)
|
||||||
set(man1 "man/rgbasm.1"
|
target_compile_definitions(rgbasm PRIVATE -DYYDEBUG)
|
||||||
"man/rgbfix.1"
|
endif()
|
||||||
"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")
|
if(TRACE_LEXER)
|
||||||
set(DEST "${MANDIR}/${SECTION}")
|
target_compile_definitions(rgbasm PRIVATE -DLEXER_DEBUG)
|
||||||
install(FILES ${${SECTION}} DESTINATION ${DEST})
|
endif()
|
||||||
endforeach()
|
|
||||||
|
|||||||
193
CONTRIBUTING.md
193
CONTRIBUTING.md
@@ -1,193 +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. 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
|
|
||||||
|
|
||||||
Each `.asm` file corresponds to one test.
|
|
||||||
RGBASM will be invoked on the `.asm` file with all warnings enabled.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
### 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
|
|
||||||
```
|
|
||||||
96
CONTRIBUTING.rst
Normal file
96
CONTRIBUTING.rst
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
Contributing
|
||||||
|
============
|
||||||
|
|
||||||
|
RGBDS was created in the late 90's and has received contributions from several
|
||||||
|
developers since then. It wouldn't have been possible to get to this point
|
||||||
|
without their work and, for that reason, 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,34 +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>
|
|
||||||
53
CONTRIBUTORS.rst
Normal file
53
CONTRIBUTORS.rst
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
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>
|
||||||
|
|
||||||
|
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>
|
||||||
|
|
||||||
|
- Eldred Habert <eldredhabert0@gmail.com>
|
||||||
|
|
||||||
|
- 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>
|
||||||
|
|
||||||
|
- Rangi <http://github.com/Rangi42>
|
||||||
|
|
||||||
|
- 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=0.9.4
|
# 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
|
||||||
|
|||||||
280
Makefile
280
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 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,40 +27,32 @@ 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
|
||||||
|
|
||||||
# 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
|
REALCFLAGS := ${CFLAGS} ${WARNFLAGS} -std=gnu11 -D_POSIX_C_SOURCE=200809L \
|
||||||
|
-Iinclude
|
||||||
# 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
|
|
||||||
BASE_REF := origin/master
|
|
||||||
|
|
||||||
# Rules to build the RGBDS binaries
|
# Rules to build the RGBDS binaries
|
||||||
|
|
||||||
all: rgbasm rgblink rgbfix rgbgfx
|
all: rgbasm rgblink rgbfix rgbgfx
|
||||||
|
|
||||||
common_obj := \
|
|
||||||
src/extern/getopt.o \
|
|
||||||
src/diagnostics.o \
|
|
||||||
src/usage.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 \
|
||||||
@@ -64,204 +60,178 @@ rgbasm_obj := \
|
|||||||
src/asm/lexer.o \
|
src/asm/lexer.o \
|
||||||
src/asm/macro.o \
|
src/asm/macro.o \
|
||||||
src/asm/main.o \
|
src/asm/main.o \
|
||||||
|
src/asm/parser.o \
|
||||||
src/asm/opt.o \
|
src/asm/opt.o \
|
||||||
src/asm/output.o \
|
src/asm/output.o \
|
||||||
src/asm/parser.o \
|
|
||||||
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/err.o \
|
||||||
|
src/extern/getopt.o \
|
||||||
src/extern/utf8decoder.o \
|
src/extern/utf8decoder.o \
|
||||||
|
src/hashmap.o \
|
||||||
src/linkdefs.o \
|
src/linkdefs.o \
|
||||||
src/opmath.o \
|
src/opmath.o
|
||||||
src/util.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/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/err.o \
|
||||||
src/extern/utf8decoder.o \
|
src/extern/getopt.o \
|
||||||
|
src/hashmap.o \
|
||||||
src/linkdefs.o \
|
src/linkdefs.o \
|
||||||
src/opmath.o \
|
src/opmath.o
|
||||||
src/util.o
|
|
||||||
|
|
||||||
src/link/lexer.o src/link/main.o: src/link/script.hpp
|
|
||||||
|
|
||||||
rgbfix_obj := \
|
rgbfix_obj := \
|
||||||
${common_obj} \
|
|
||||||
src/fix/main.o \
|
src/fix/main.o \
|
||||||
src/fix/mbc.o \
|
src/extern/err.o \
|
||||||
src/fix/warning.o
|
src/extern/getopt.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/err.o \
|
||||||
src/gfx/pal_spec.o \
|
src/extern/getopt.o
|
||||||
src/gfx/png.o \
|
|
||||||
src/gfx/process.o \
|
|
||||||
src/gfx/reverse.o \
|
|
||||||
src/gfx/rgba.o \
|
|
||||||
src/gfx/warning.o \
|
|
||||||
src/util.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 for suspiciously missing changed files.
|
# Target used to check the coding style of the whole codebase.
|
||||||
checkdiff:
|
# `extern/` is excluded, as it contains external code that should not be patched
|
||||||
$Qcontrib/checkdiff.bash `git merge-base HEAD ${BASE_REF}`
|
# 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...
|
||||||
|
|
||||||
|
BASE_REF:= origin/master
|
||||||
|
checkpatch:
|
||||||
|
$Qeval COMMON_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
|
||||||
|
|
||||||
|
# This target is used during development in order to prevent adding new issues
|
||||||
|
# to the source code. All warnings are treated as errors in order to block the
|
||||||
|
# compilation and make the continous integration infrastructure return failure.
|
||||||
|
|
||||||
# Target used in development to prevent adding new issues to the source code.
|
|
||||||
# All warnings are treated as errors to block the compilation and make the
|
|
||||||
# continous integration infrastructure return failure.
|
|
||||||
# The rationale for some of the flags is documented in the CMakeLists.
|
|
||||||
develop:
|
develop:
|
||||||
$Q${MAKE} WARNFLAGS="${WARNFLAGS} -Werror -Wextra \
|
$Qenv $(MAKE) -j WARNFLAGS="-Werror -Wall -Wextra -Wpedantic -Wno-type-limits \
|
||||||
-Walloc-zero -Wcast-align -Wcast-qual -Wduplicated-branches -Wduplicated-cond \
|
-Wno-sign-compare -Wvla -Wformat -Wformat-security -Wformat-overflow=2 \
|
||||||
-Wfloat-equal -Wlogical-op -Wnull-dereference -Wold-style-cast -Wshift-overflow=2 \
|
-Wformat-truncation=1 -Wformat-y2k -Wswitch-enum -Wunused \
|
||||||
-Wstringop-overflow=4 -Wtrampolines -Wundef -Wuninitialized -Wunused -Wshadow \
|
-Wuninitialized -Wunknown-pragmas -Wstrict-overflow=4 \
|
||||||
-Wformat=2 -Wformat-overflow=2 -Wformat-truncation=1 \
|
-Wstringop-overflow=4 -Walloc-zero -Wduplicated-cond \
|
||||||
-Wno-format-nonliteral -Wno-strict-overflow -Wno-unused-but-set-variable \
|
-Wfloat-equal -Wshadow -Wcast-qual -Wcast-align -Wlogical-op \
|
||||||
-Wno-type-limits -Wno-tautological-constant-out-of-range-compare -Wvla \
|
-Wnested-externs -Wno-aggressive-loop-optimizations -Winline \
|
||||||
-D_GLIBCXX_ASSERTIONS -fsanitize=address -fsanitize=undefined \
|
-Wundef -Wstrict-prototypes -Wold-style-definition \
|
||||||
-fsanitize=float-divide-by-zero" \
|
-fsanitize=shift -fsanitize=integer-divide-by-zero \
|
||||||
CXXFLAGS="-ggdb3 -Og -fno-omit-frame-pointer -fno-optimize-sibling-calls"
|
-fsanitize=unreachable -fsanitize=vla-bound \
|
||||||
|
-fsanitize=signed-integer-overflow -fsanitize=bounds \
|
||||||
# Target used in development to debug with gdb.
|
-fsanitize=object-size -fsanitize=bool -fsanitize=enum \
|
||||||
debug:
|
-fsanitize=alignment -fsanitize=null" CFLAGS="-ggdb3 -O0"
|
||||||
$Qenv ${MAKE} \
|
|
||||||
CXXFLAGS="-ggdb3 -O0 -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 check code with clang-tidy.
|
|
||||||
# Requires Bison-generated header files to exist.
|
|
||||||
tidy: src/asm/parser.hpp src/link/script.hpp
|
|
||||||
$Qclang-tidy -p . $$(find src -name '*.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 \
|
$Qmake 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 \
|
$Qmake 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
|
||||||
@@ -274,4 +244,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 -
|
||||||
|
|||||||
167
README.md
167
README.md
@@ -1,167 +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/).
|
|
||||||
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, or 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`.
|
|
||||||
|
|
||||||
## 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.
|
|
||||||
|
|
||||||
```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.)
|
|
||||||
|
|
||||||
## 2. RGBDS Folder Organization
|
|
||||||
|
|
||||||
The RGBDS source code file structure is as follows:
|
|
||||||
|
|
||||||
```
|
|
||||||
.
|
|
||||||
├── .github/
|
|
||||||
│ ├── scripts/
|
|
||||||
│ │ └── ...
|
|
||||||
│ └── workflows/
|
|
||||||
│ └── ...
|
|
||||||
├── contrib/
|
|
||||||
│ ├── zsh_compl/
|
|
||||||
│ │ └── ...
|
|
||||||
│ └── ...
|
|
||||||
├── include/
|
|
||||||
│ └── ...
|
|
||||||
├── man/
|
|
||||||
│ └── ...
|
|
||||||
├── src/
|
|
||||||
│ ├── asm/
|
|
||||||
│ │ └── ...
|
|
||||||
│ ├── extern/
|
|
||||||
│ │ └── ...
|
|
||||||
│ ├── fix/
|
|
||||||
│ │ └── ...
|
|
||||||
│ ├── gfx/
|
|
||||||
│ │ └── ...
|
|
||||||
│ ├── link/
|
|
||||||
│ │ └── ...
|
|
||||||
│ ├── CMakeLists.txt
|
|
||||||
│ └── ...
|
|
||||||
├── test/
|
|
||||||
│ ├── ...
|
|
||||||
│ └── run-tests.sh
|
|
||||||
├── .clang-format
|
|
||||||
├── CMakeLists.txt
|
|
||||||
├── compile_flags.txt
|
|
||||||
├── Dockerfile
|
|
||||||
├── Makefile
|
|
||||||
└── README.md
|
|
||||||
```
|
|
||||||
|
|
||||||
- `.github/` - files and scripts related to the integration of the RGBDS codebase with
|
|
||||||
GitHub.
|
|
||||||
* `scripts/` - 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 the respective source files in `src`.
|
|
||||||
- `man/` - manual pages.
|
|
||||||
- `src/` - source code of RGBDS.
|
|
||||||
* Note that the code unique to each RGBDS tool is stored in its respective subdirectory
|
|
||||||
(RGBASM's code is in `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 C++ formatting with
|
|
||||||
[`clang-format`](https://clang.llvm.org/docs/ClangFormat.html).
|
|
||||||
- `compile_flags.txt` - compiler flags for C++ static analysis with
|
|
||||||
[`clang-tidy`](https://clang.llvm.org/extra/clang-tidy/).
|
|
||||||
- `Dockerfile` - defines how to build RGBDS with Docker.
|
|
||||||
|
|
||||||
## 3. History
|
|
||||||
|
|
||||||
- 1996-10-01: Carsten Sørensen (a.k.a. SurfSmurf) releases
|
|
||||||
[xAsm](http://otakunozoku.com/RGBDSdocs/asm.htm),
|
|
||||||
[xLink](http://otakunozoku.com/RGBDSdocs/link.htm), and
|
|
||||||
[RGBFix](http://otakunozoku.com/RGBDSdocs/fix.htm),
|
|
||||||
a Game Boy SM83 (GBZ80) assembler/linker system for DOS/Win32.
|
|
||||||
- 1997-07-03: Sørensen releases [ASMotor](http://otakunozoku.com/RGBDSdocs/geninfo.htm),
|
|
||||||
packaging the three programs together and moving towards making them a
|
|
||||||
general-purpose target-independent system.
|
|
||||||
- 1999-08-01: Justin Lloyd (a.k.a. Otaku no Zoku) adapts ASMotor to re-focus
|
|
||||||
on SM83 assembly/machine code, and releases this version as
|
|
||||||
[RGBDS](http://otakunozoku.com/rednex-gameboy-development-system/).
|
|
||||||
- 2009-06-11: Vegard Nossum adapts the code to be more UNIX-like and releases
|
|
||||||
this version as [rgbds-linux](https://github.com/vegard/rgbds-linux).
|
|
||||||
- 2010-01-12: Anthony J. Bentley [forks](https://github.com/bentley) Nossum's
|
|
||||||
repository. The fork becomes the reference implementation of RGBDS.
|
|
||||||
- 2010-09-25: Sørensen continues development of
|
|
||||||
[ASMotor](https://github.com/asmotor/asmotor) to this day.
|
|
||||||
- 2015-01-18: stag019 begins implementing [RGBGFX](https://github.com/stag019/rgbgfx),
|
|
||||||
a PNG-to-Game Boy graphics converter, for eventual integration into RGBDS.
|
|
||||||
- 2016-09-05: RGBGFX is
|
|
||||||
[integrated](https://github.com/gbdev/rgbds/commit/c3c31138ddbd8680d4e67957e387f2816798a71b)
|
|
||||||
into Bentley's repository.
|
|
||||||
- 2017-02-23: Bentley's repository is moved to the [rednex](https://github.com/rednex)
|
|
||||||
organization.
|
|
||||||
- 2018-01-26: The codebase is [relicensed](https://github.com/gbdev/rgbds/issues/128)
|
|
||||||
under the MIT license.
|
|
||||||
- 2020-09-15: The repository is [moved](https://github.com/gbdev/rgbds/issues/567)
|
|
||||||
to the [gbdev](https://github.com/gbdev) organization.
|
|
||||||
- 2022-05-17: The [rgbds.gbdev.io](https://rgbds.gbdev.io) website for RGBDS
|
|
||||||
documentation and downloads is published.
|
|
||||||
|
|
||||||
## 4. 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).
|
|
||||||
115
README.rst
Normal file
115
README.rst
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
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.
|
||||||
|
|
||||||
|
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
|
||||||
|
├── CMakeLists.txt
|
||||||
|
├── Makefile
|
||||||
|
└── README.rst
|
||||||
|
|
||||||
|
- ``.github/`` - files and scripts related to the integration of the RGBDS codebase with
|
||||||
|
GitHub.
|
||||||
|
|
||||||
|
- ``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.
|
||||||
|
|
||||||
|
- ``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.
|
||||||
|
|
||||||
|
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.
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
-std=c++2a
|
|
||||||
-I
|
|
||||||
include
|
|
||||||
-fno-exceptions
|
|
||||||
-fno-rtti
|
|
||||||
-fno-caret-diagnostics
|
|
||||||
@@ -1,226 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Known bugs:
|
|
||||||
# - Newlines in file/directory names break this script
|
|
||||||
# This is because we rely on `compgen -A`, which is broken like this.
|
|
||||||
# A fix would require implementing it ourselves, and no thanks!
|
|
||||||
# - `rgbasm --binary-digits=a` is treated the same as `rgbasm --binary-digits=` (for example)
|
|
||||||
# This is not our fault, Bash passes both of these identically.
|
|
||||||
# Maybe it could be worked around, but such a fix would likely be involved.
|
|
||||||
# The user can work around it by typing `--binary-digits ''` instead, 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 -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
|
|
||||||
# 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.)
|
|
||||||
|
|
||||||
# Something to note:
|
|
||||||
# `rgbasm --binary-digits=a` gets passed to us as ('rgbasm' '--binary-digits' '=' 'a')
|
|
||||||
# Thus, we don't need to do much to handle that form of argument passing: skip '=' after long opts.
|
|
||||||
|
|
||||||
_rgbasm_completions() {
|
|
||||||
# Format: "long_opt:state_after"
|
|
||||||
# Empty long opt = it doesn't exit
|
|
||||||
# See the `state` variable below for info about `state_after`
|
|
||||||
declare -A opts=(
|
|
||||||
[h]="help:normal"
|
|
||||||
[V]="version:normal"
|
|
||||||
[W]="warning:warning"
|
|
||||||
[w]=":normal"
|
|
||||||
[b]="binary-digits:unk"
|
|
||||||
[D]="define:unk"
|
|
||||||
[E]="export-all:normal"
|
|
||||||
[g]="gfx-chars:unk"
|
|
||||||
[I]="include:dir"
|
|
||||||
[M]="dependfile:glob-*.mk *.d"
|
|
||||||
[o]="output:glob-*.o"
|
|
||||||
[P]="preinclude:glob-*.asm *.inc"
|
|
||||||
[p]="pad-value:unk"
|
|
||||||
[Q]="q-precision:unk"
|
|
||||||
[r]="recursion-depth:unk"
|
|
||||||
[s]="state:unk"
|
|
||||||
[v]="verbose:normal"
|
|
||||||
[X]="max-errors:unk"
|
|
||||||
)
|
|
||||||
# Parse command-line up to current word
|
|
||||||
local opt_ena=true
|
|
||||||
# Possible states:
|
|
||||||
# - normal = Well, normal. Options are parsed normally.
|
|
||||||
# - unk = An argument that can't be completed, and should just be skipped.
|
|
||||||
# - warning = A warning flag.
|
|
||||||
# - dir = A directory path
|
|
||||||
# - glob-* = A glob, after the dash is a whitespace-separated list of file globs to use
|
|
||||||
local state=normal
|
|
||||||
# The length of the option, used as a return value by the function below
|
|
||||||
local optlen=0
|
|
||||||
# $1: a short option word
|
|
||||||
# `state` will be set to the parsing state after the last option character in the word. If
|
|
||||||
# "normal" is not returned, `optlen` will be set to the length (dash included) of the "option"
|
|
||||||
# part of the argument.
|
|
||||||
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"[GP] ]]; 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
|
|
||||||
# If the option is not known, assume it doesn't take an argument
|
|
||||||
local opt="${opts["${1:$i:1}"]:-":normal"}"
|
|
||||||
state="${opt#*:}"
|
|
||||||
# If the option takes an argument, record the length and exit
|
|
||||||
if [[ "$state" != 'normal' ]]; then
|
|
||||||
let optlen="$i + 1"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
optlen=0
|
|
||||||
}
|
|
||||||
|
|
||||||
for (( i = 1; i < COMP_CWORD; i++ )); do
|
|
||||||
local word="${COMP_WORDS[$i]}"
|
|
||||||
|
|
||||||
# If currently processing an argument, skip this word
|
|
||||||
if [[ "$state" != 'normal' ]]; then
|
|
||||||
state=normal
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$word" = '--' ]]; then
|
|
||||||
# Options stop being parsed after this
|
|
||||||
opt_ena=false
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if it's a long option
|
|
||||||
if [[ "$word" = '--'* ]]; then
|
|
||||||
# If the option is unknown, assume it takes no arguments: keep the state at "normal"
|
|
||||||
for long_opt in "${opts[@]}"; do
|
|
||||||
if [[ "$word" = "--${long_opt%%:*}" ]]; then
|
|
||||||
state="${long_opt#*:}"
|
|
||||||
# Check if the next word is just '='; if so, skip it, the argument must follow
|
|
||||||
# (See "known bugs" at the top of this script)
|
|
||||||
let i++
|
|
||||||
if [[ "${COMP_WORDS[$i]}" != '=' ]]; then
|
|
||||||
let i--
|
|
||||||
fi
|
|
||||||
optlen=0
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
# Check if it's a short option
|
|
||||||
elif [[ "$word" = '-'* ]]; then
|
|
||||||
parse_short_opt "$word"
|
|
||||||
# The last option takes an argument...
|
|
||||||
if [[ "$state" != 'normal' ]]; then
|
|
||||||
if [[ "$optlen" -ne "${#word}" ]]; then
|
|
||||||
# If it's contained within the word, we won't complete it, revert to "normal"
|
|
||||||
state=normal
|
|
||||||
else
|
|
||||||
# Otherwise, complete it, but start at the beginning of *that* word
|
|
||||||
optlen=0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Parse current word
|
|
||||||
# Careful that it might look like an option, so use `--` aggressively!
|
|
||||||
local cur_word="${COMP_WORDS[$i]}"
|
|
||||||
|
|
||||||
# Process options, as short ones may change the state
|
|
||||||
if $opt_ena && [[ "$state" = 'normal' && "$cur_word" = '-'* ]]; then
|
|
||||||
# We might want to complete to an option or an arg to that option
|
|
||||||
# Parse the option word to check
|
|
||||||
# There's no whitespace in the option names, so we can ride a little dirty...
|
|
||||||
|
|
||||||
# Is this a long option?
|
|
||||||
if [[ "$cur_word" = '--'* ]]; then
|
|
||||||
# It is, try to complete one
|
|
||||||
mapfile -t COMPREPLY < <(compgen -W "${opts[*]%%:*}" -P '--' -- "${cur_word#--}")
|
|
||||||
return 0
|
|
||||||
elif [[ "$cur_word" = '-M'[GPQT] ]]; then
|
|
||||||
# These options act like long opts with no arguments, so return them and exactly them
|
|
||||||
COMPREPLY=( "$cur_word" )
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
# Short options may be grouped, parse them to determine what to complete
|
|
||||||
parse_short_opt "$cur_word"
|
|
||||||
|
|
||||||
if [[ "$state" = 'normal' ]]; then
|
|
||||||
mapfile -t COMPREPLY < <(compgen -W "${!opts[*]}" -P "$cur_word" ''; compgen -W '-MC -MG -MP -MQ -MT' "$cur_word")
|
|
||||||
return 0
|
|
||||||
elif [[ "$optlen" = "${#cur_word}" && "$state" != "warning" ]]; then
|
|
||||||
# This short option group only awaits its argument!
|
|
||||||
# Post the option group as-is as a reply so that Readline inserts a space,
|
|
||||||
# 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
|
|
||||||
# `-W`, and it doesn't break anything.
|
|
||||||
COMPREPLY=( "$cur_word" )
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
COMPREPLY=()
|
|
||||||
case "$state" in
|
|
||||||
unk) # Return with no replies: no idea what to complete!
|
|
||||||
;;
|
|
||||||
warning)
|
|
||||||
mapfile -t COMPREPLY < <(compgen -W "
|
|
||||||
assert
|
|
||||||
backwards-for
|
|
||||||
builtin-args
|
|
||||||
charmap-redef
|
|
||||||
div
|
|
||||||
empty-data-directive
|
|
||||||
empty-macro-arg
|
|
||||||
empty-strrpl
|
|
||||||
large-constant
|
|
||||||
macro-shift
|
|
||||||
nested-comment
|
|
||||||
numeric-string
|
|
||||||
obsolete
|
|
||||||
purge
|
|
||||||
shift
|
|
||||||
shift-amount
|
|
||||||
truncation
|
|
||||||
unmapped-char
|
|
||||||
unmatched-directive
|
|
||||||
unterminated-load
|
|
||||||
user
|
|
||||||
all
|
|
||||||
extra
|
|
||||||
everything
|
|
||||||
error" -P "${cur_word:0:$optlen}" -- "${cur_word:$optlen}")
|
|
||||||
;;
|
|
||||||
normal) # Acts like a glob...
|
|
||||||
state="glob-*.asm *.inc *.sm83"
|
|
||||||
;&
|
|
||||||
glob-*)
|
|
||||||
while read -r word; do
|
|
||||||
COMPREPLY+=("${cur_word:0:$optlen}$word")
|
|
||||||
done < <(for glob in ${state#glob-}; do compgen -A file -X \!"$glob" -- "${cur_word:$optlen}"; done)
|
|
||||||
# Also complete directories
|
|
||||||
;&
|
|
||||||
dir)
|
|
||||||
while read -r word; do
|
|
||||||
COMPREPLY+=("${cur_word:0:$optlen}$word")
|
|
||||||
done < <(compgen -A directory -- "${cur_word:$optlen}")
|
|
||||||
compopt -o filenames
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo >&2 "Internal completion error: invalid state \"$state\", please report this bug"
|
|
||||||
return 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
complete -F _rgbasm_completions rgbasm
|
|
||||||
@@ -1,200 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Same notes as RGBASM
|
|
||||||
|
|
||||||
_rgbfix_completions() {
|
|
||||||
# Format: "long_opt:state_after"
|
|
||||||
# Empty long opt = it doesn't exit
|
|
||||||
# See the `state` variable below for info about `state_after`
|
|
||||||
declare -A opts=(
|
|
||||||
[h]="help:normal"
|
|
||||||
[V]="version:normal"
|
|
||||||
[W]="warning:warning"
|
|
||||||
[w]=":normal"
|
|
||||||
[C]="color-only:normal"
|
|
||||||
[c]="color-compatible:normal"
|
|
||||||
[f]="fix-spec:fix-spec"
|
|
||||||
[i]="game-id:unk"
|
|
||||||
[j]="non-japanese:normal"
|
|
||||||
[k]="new-licensee:unk"
|
|
||||||
[L]="custom-logo:glob-*.1bpp"
|
|
||||||
[l]="old-licensee:unk"
|
|
||||||
[m]="mbc-type:mbc"
|
|
||||||
[n]="rom-version:unk"
|
|
||||||
[o]="output:glob-*.gb *.gbc *.sgb"
|
|
||||||
[p]="pad-value:unk"
|
|
||||||
[r]="ram-size:unk"
|
|
||||||
[s]="sgb-compatible:normal"
|
|
||||||
[t]="title:unk"
|
|
||||||
[v]="validate:normal"
|
|
||||||
)
|
|
||||||
# Parse command-line up to current word
|
|
||||||
local opt_ena=true
|
|
||||||
# Possible states:
|
|
||||||
# - normal = Well, normal. Options are parsed normally.
|
|
||||||
# - unk = An argument that can't be completed, and should just be skipped.
|
|
||||||
# - warning = A warning flag.
|
|
||||||
# - dir = A directory path
|
|
||||||
# - glob-* = A glob, after the dash is a whitespace-separated list of file globs to use
|
|
||||||
local state=normal
|
|
||||||
# The length of the option, used as a return value by the function below
|
|
||||||
local optlen=0
|
|
||||||
# $1: a short option word
|
|
||||||
# `state` will be set to the parsing state after the last option character in the word. If
|
|
||||||
# "normal" is not returned, `optlen` will be set to the length (dash included) of the "option"
|
|
||||||
# part of the argument.
|
|
||||||
parse_short_opt() {
|
|
||||||
for (( i = 1; i < "${#1}"; i++ )); do
|
|
||||||
# If the option is not known, assume it doesn't take an argument
|
|
||||||
local opt="${opts["${1:$i:1}"]:-":normal"}"
|
|
||||||
state="${opt#*:}"
|
|
||||||
# If the option takes an argument, record the length and exit
|
|
||||||
if [[ "$state" != 'normal' ]]; then
|
|
||||||
let optlen="$i + 1"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
optlen=0
|
|
||||||
}
|
|
||||||
|
|
||||||
for (( i = 1; i < COMP_CWORD; i++ )); do
|
|
||||||
local word="${COMP_WORDS[$i]}"
|
|
||||||
|
|
||||||
# If currently processing an argument, skip this word
|
|
||||||
if [[ "$state" != 'normal' ]]; then
|
|
||||||
state=normal
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$word" = '--' ]]; then
|
|
||||||
# Options stop being parsed after this
|
|
||||||
opt_ena=false
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if it's a long option
|
|
||||||
if [[ "$word" = '--'* ]]; then
|
|
||||||
# If the option is unknown, assume it takes no arguments: keep the state at "normal"
|
|
||||||
for long_opt in "${opts[@]}"; do
|
|
||||||
if [[ "$word" = "--${long_opt%%:*}" ]]; then
|
|
||||||
state="${long_opt#*:}"
|
|
||||||
# Check if the next word is just '='; if so, skip it, the argument must follow
|
|
||||||
# (See "known bugs" at the top of this script)
|
|
||||||
let i++
|
|
||||||
if [[ "${COMP_WORDS[$i]}" != '=' ]]; then
|
|
||||||
let i--
|
|
||||||
fi
|
|
||||||
optlen=0
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
# Check if it's a short option
|
|
||||||
elif [[ "$word" = '-'* ]]; then
|
|
||||||
parse_short_opt "$word"
|
|
||||||
# The last option takes an argument...
|
|
||||||
if [[ "$state" != 'normal' ]]; then
|
|
||||||
if [[ "$optlen" -ne "${#word}" ]]; then
|
|
||||||
# If it's contained within the word, we won't complete it, revert to "normal"
|
|
||||||
state=normal
|
|
||||||
else
|
|
||||||
# Otherwise, complete it, but start at the beginning of *that* word
|
|
||||||
optlen=0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Parse current word
|
|
||||||
# Careful that it might look like an option, so use `--` aggressively!
|
|
||||||
local cur_word="${COMP_WORDS[$i]}"
|
|
||||||
|
|
||||||
# Process options, as short ones may change the state
|
|
||||||
if $opt_ena && [[ "$state" = 'normal' && "$cur_word" = '-'* ]]; then
|
|
||||||
# We might want to complete to an option or an arg to that option
|
|
||||||
# Parse the option word to check
|
|
||||||
# There's no whitespace in the option names, so we can ride a little dirty...
|
|
||||||
|
|
||||||
# Is this a long option?
|
|
||||||
if [[ "$cur_word" = '--'* ]]; then
|
|
||||||
# It is, try to complete one
|
|
||||||
mapfile -t COMPREPLY < <(compgen -W "${opts[*]%%:*}" -P '--' -- "${cur_word#--}")
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
# Short options may be grouped, parse them to determine what to complete
|
|
||||||
parse_short_opt "$cur_word"
|
|
||||||
|
|
||||||
if [[ "$state" = 'normal' ]]; then
|
|
||||||
mapfile -t COMPREPLY < <(compgen -W "${!opts[*]}" -P "$cur_word" '')
|
|
||||||
return 0
|
|
||||||
elif [[ "$optlen" = "${#cur_word}" && "$state" != "warning" ]]; then
|
|
||||||
# This short option group only awaits its argument!
|
|
||||||
# Post the option group as-is as a reply so that Readline inserts a space,
|
|
||||||
# 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
|
|
||||||
# `-W`, and it doesn't break anything.
|
|
||||||
COMPREPLY=( "$cur_word" )
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
COMPREPLY=()
|
|
||||||
case "$state" in
|
|
||||||
unk) # Return with no replies: no idea what to complete!
|
|
||||||
;;
|
|
||||||
warning)
|
|
||||||
mapfile -t COMPREPLY < <(compgen -W "
|
|
||||||
mbc
|
|
||||||
overwrite
|
|
||||||
sgb
|
|
||||||
truncation
|
|
||||||
all
|
|
||||||
everything
|
|
||||||
error" -P "${cur_word:0:$optlen}" -- "${cur_word:$optlen}")
|
|
||||||
;;
|
|
||||||
fix-spec)
|
|
||||||
COMPREPLY=( "${cur_word}"{l,h,g,L,H,G} )
|
|
||||||
;;
|
|
||||||
mbc)
|
|
||||||
local cur_arg="${cur_word:$optlen}"
|
|
||||||
cur_arg="${cur_arg@U}"
|
|
||||||
compopt -o nosort # Keep `help` first in the list, mainly
|
|
||||||
mapfile -t COMPREPLY < <(compgen -W "help" -P "${cur_word:0:$optlen}" -- "${cur_word:$optlen}")
|
|
||||||
mapfile -t COMPREPLY -O ${#COMPREPLY} < <(compgen -W "
|
|
||||||
ROM_ONLY
|
|
||||||
MBC1{,+RAM,+RAM+BATTERY}
|
|
||||||
MBC2{,+BATTERY}
|
|
||||||
MMM01{,+RAM}
|
|
||||||
MBC3{+TIMER+BATTERY,+TIMER+RAM+BATTERY,,+RAM,+RAM+BATTERY}
|
|
||||||
MBC5{,+RAM,+RAM+BATTERY,+RUMBLE,+RUMBLE+RAM,+RUMBLE+RAM+BATTERY}
|
|
||||||
MBC6
|
|
||||||
MBC7+SENSOR+RUMBLE+RAM+BATTERY
|
|
||||||
POCKET_CAMERA
|
|
||||||
BANDAI_TAMA5
|
|
||||||
HUC3
|
|
||||||
HUC1+RAM+BATTERY
|
|
||||||
TPP1_1.0{,+BATTERY}{,+RTC}{,+RUMBLE,+MULTIRUMBLE}" -P "${cur_word:0:$optlen}" -- "${cur_word/ /_}")
|
|
||||||
;;
|
|
||||||
normal) # Acts like a glob...
|
|
||||||
state="glob-*.gb *.gbc *.sgb"
|
|
||||||
;&
|
|
||||||
glob-*)
|
|
||||||
while read -r word; do
|
|
||||||
COMPREPLY+=("${cur_word:0:$optlen}$word")
|
|
||||||
done < <(for glob in ${state#glob-}; do compgen -A file -X \!"$glob" -- "${cur_word:$optlen}"; done)
|
|
||||||
# Also complete directories
|
|
||||||
;&
|
|
||||||
dir)
|
|
||||||
while read -r word; do
|
|
||||||
COMPREPLY+=("${cur_word:0:$optlen}$word")
|
|
||||||
done < <(compgen -A directory -- "${cur_word:$optlen}")
|
|
||||||
compopt -o filenames
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo >&2 "Internal completion error: invalid state \"$state\", please report this bug"
|
|
||||||
return 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
complete -F _rgbfix_completions rgbfix
|
|
||||||
@@ -1,187 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Same notes as RGBASM
|
|
||||||
|
|
||||||
_rgbgfx_completions() {
|
|
||||||
# Format: "long_opt:state_after"
|
|
||||||
# Empty long opt = it doesn't exit
|
|
||||||
# See the `state` variable below for info about `state_after`
|
|
||||||
declare -A opts=(
|
|
||||||
[h]="help: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]="colors:unk"
|
|
||||||
[d]="depth:unk"
|
|
||||||
[i]="input-tileset:glob-*.2bpp"
|
|
||||||
[L]="slice:unk"
|
|
||||||
[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"
|
|
||||||
[v]="verbose:normal"
|
|
||||||
[X]="mirror-x:normal"
|
|
||||||
[x]="trim-end:unk"
|
|
||||||
[Y]="mirror-y:normal"
|
|
||||||
[Z]="columns:normal"
|
|
||||||
)
|
|
||||||
# Parse command-line up to current word
|
|
||||||
local opt_ena=true
|
|
||||||
# Possible states:
|
|
||||||
# - normal = Well, normal. Options are parsed normally.
|
|
||||||
# - unk = An argument that can't be completed, and should just be skipped.
|
|
||||||
# - warning = A warning flag.
|
|
||||||
# - dir = A directory path
|
|
||||||
# - glob-* = A glob, after the dash is a whitespace-separated list of file globs to use
|
|
||||||
local state=normal
|
|
||||||
# The length of the option, used as a return value by the function below
|
|
||||||
local optlen=0
|
|
||||||
# $1: a short option word
|
|
||||||
# `state` will be set to the parsing state after the last option character in the word. If
|
|
||||||
# "normal" is not returned, `optlen` will be set to the length (dash included) of the "option"
|
|
||||||
# part of the argument.
|
|
||||||
parse_short_opt() {
|
|
||||||
for (( i = 1; i < "${#1}"; i++ )); do
|
|
||||||
# If the option is not known, assume it doesn't take an argument
|
|
||||||
local opt="${opts["${1:$i:1}"]:-":normal"}"
|
|
||||||
state="${opt#*:}"
|
|
||||||
# If the option takes an argument, record the length and exit
|
|
||||||
if [[ "$state" != 'normal' ]]; then
|
|
||||||
let optlen="$i + 1"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
optlen=0
|
|
||||||
}
|
|
||||||
|
|
||||||
for (( i = 1; i < COMP_CWORD; i++ )); do
|
|
||||||
local word="${COMP_WORDS[$i]}"
|
|
||||||
|
|
||||||
# If currently processing an argument, skip this word
|
|
||||||
if [[ "$state" != 'normal' ]]; then
|
|
||||||
state=normal
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$word" = '--' ]]; then
|
|
||||||
# Options stop being parsed after this
|
|
||||||
opt_ena=false
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if it's a long option
|
|
||||||
if [[ "$word" = '--'* ]]; then
|
|
||||||
# If the option is unknown, assume it takes no arguments: keep the state at "normal"
|
|
||||||
for long_opt in "${opts[@]}"; do
|
|
||||||
if [[ "$word" = "--${long_opt%%:*}" ]]; then
|
|
||||||
state="${long_opt#*:}"
|
|
||||||
# Check if the next word is just '='; if so, skip it, the argument must follow
|
|
||||||
# (See "known bugs" at the top of this script)
|
|
||||||
let i++
|
|
||||||
if [[ "${COMP_WORDS[$i]}" != '=' ]]; then
|
|
||||||
let i--
|
|
||||||
fi
|
|
||||||
optlen=0
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
# Check if it's a short option
|
|
||||||
elif [[ "$word" = '-'* ]]; then
|
|
||||||
parse_short_opt "$word"
|
|
||||||
# The last option takes an argument...
|
|
||||||
if [[ "$state" != 'normal' ]]; then
|
|
||||||
if [[ "$optlen" -ne "${#word}" ]]; then
|
|
||||||
# If it's contained within the word, we won't complete it, revert to "normal"
|
|
||||||
state=normal
|
|
||||||
else
|
|
||||||
# Otherwise, complete it, but start at the beginning of *that* word
|
|
||||||
optlen=0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Parse current word
|
|
||||||
# Careful that it might look like an option, so use `--` aggressively!
|
|
||||||
local cur_word="${COMP_WORDS[$i]}"
|
|
||||||
|
|
||||||
# Process options, as short ones may change the state
|
|
||||||
if $opt_ena && [[ "$state" = 'normal' && "$cur_word" = '-'* ]]; then
|
|
||||||
# We might want to complete to an option or an arg to that option
|
|
||||||
# Parse the option word to check
|
|
||||||
# There's no whitespace in the option names, so we can ride a little dirty...
|
|
||||||
|
|
||||||
# Is this a long option?
|
|
||||||
if [[ "$cur_word" = '--'* ]]; then
|
|
||||||
# It is, try to complete one
|
|
||||||
mapfile -t COMPREPLY < <(compgen -W "${opts[*]%%:*}" -P '--' -- "${cur_word#--}")
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
# Short options may be grouped, parse them to determine what to complete
|
|
||||||
parse_short_opt "$cur_word"
|
|
||||||
|
|
||||||
if [[ "$state" = 'normal' ]]; then
|
|
||||||
mapfile -t COMPREPLY < <(compgen -W "${!opts[*]}" -P "$cur_word" '')
|
|
||||||
return 0
|
|
||||||
elif [[ "$optlen" = "${#cur_word}" && "$state" != "warning" ]]; then
|
|
||||||
# This short option group only awaits its argument!
|
|
||||||
# Post the option group as-is as a reply so that Readline inserts a space,
|
|
||||||
# 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
|
|
||||||
# `-W`, and it doesn't break anything.
|
|
||||||
COMPREPLY=( "$cur_word" )
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
COMPREPLY=()
|
|
||||||
case "$state" in
|
|
||||||
unk) # Return with no replies: no idea what to complete!
|
|
||||||
;;
|
|
||||||
warning)
|
|
||||||
mapfile -t COMPREPLY < <(compgen -W "
|
|
||||||
embedded
|
|
||||||
trim-nonempty
|
|
||||||
all
|
|
||||||
everything
|
|
||||||
error" -P "${cur_word:0:$optlen}" -- "${cur_word:$optlen}")
|
|
||||||
;;
|
|
||||||
normal) # Acts like a glob...
|
|
||||||
state="glob-*.png"
|
|
||||||
;&
|
|
||||||
glob-*)
|
|
||||||
while read -r word; do
|
|
||||||
COMPREPLY+=("${cur_word:0:$optlen}$word")
|
|
||||||
done < <(for glob in ${state#glob-}; do compgen -A file -X \!"$glob" -- "${cur_word:$optlen}"; done)
|
|
||||||
# Also complete directories
|
|
||||||
;&
|
|
||||||
dir)
|
|
||||||
while read -r word; do
|
|
||||||
COMPREPLY+=("${cur_word:0:$optlen}$word")
|
|
||||||
done < <(compgen -A directory -- "${cur_word:$optlen}")
|
|
||||||
compopt -o filenames
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo >&2 "Internal completion error: invalid state \"$state\", please report this bug"
|
|
||||||
return 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
complete -F _rgbgfx_completions rgbgfx
|
|
||||||
@@ -1,174 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Same notes as RGBASM
|
|
||||||
|
|
||||||
_rgblink_completions() {
|
|
||||||
# Format: "long_opt:state_after"
|
|
||||||
# Empty long opt = it doesn't exit
|
|
||||||
# See the `state` variable below for info about `state_after`
|
|
||||||
declare -A opts=(
|
|
||||||
[h]="help:normal"
|
|
||||||
[V]="version:normal"
|
|
||||||
[W]="warning:warning"
|
|
||||||
[M]="no-sym-in-map:normal"
|
|
||||||
[d]="dmg:normal"
|
|
||||||
[l]="linkerscript:glob-*"
|
|
||||||
[m]="map:glob-*.map"
|
|
||||||
[n]="sym:glob-*.sym"
|
|
||||||
[O]="overlay:glob-*.gb *.gbc *.sgb"
|
|
||||||
[o]="output:glob-*.gb *.gbc *.sgb"
|
|
||||||
[p]="pad:unk"
|
|
||||||
[t]="tiny:normal"
|
|
||||||
[v]="verbose:normal"
|
|
||||||
[w]="wramx:normal"
|
|
||||||
[x]="nopad:normal"
|
|
||||||
)
|
|
||||||
# Parse command-line up to current word
|
|
||||||
local opt_ena=true
|
|
||||||
# Possible states:
|
|
||||||
# - normal = Well, normal. Options are parsed normally.
|
|
||||||
# - unk = An argument that can't be completed, and should just be skipped.
|
|
||||||
# - warning = A warning flag.
|
|
||||||
# - dir = A directory path
|
|
||||||
# - glob-* = A glob, after the dash is a whitespace-separated list of file globs to use
|
|
||||||
local state=normal
|
|
||||||
# The length of the option, used as a return value by the function below
|
|
||||||
local optlen=0
|
|
||||||
# $1: a short option word
|
|
||||||
# `state` will be set to the parsing state after the last option character in the word. If
|
|
||||||
# "normal" is not returned, `optlen` will be set to the length (dash included) of the "option"
|
|
||||||
# part of the argument.
|
|
||||||
parse_short_opt() {
|
|
||||||
for (( i = 1; i < "${#1}"; i++ )); do
|
|
||||||
# If the option is not known, assume it doesn't take an argument
|
|
||||||
local opt="${opts["${1:$i:1}"]:-":normal"}"
|
|
||||||
state="${opt#*:}"
|
|
||||||
# If the option takes an argument, record the length and exit
|
|
||||||
if [[ "$state" != 'normal' ]]; then
|
|
||||||
let optlen="$i + 1"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
optlen=0
|
|
||||||
}
|
|
||||||
|
|
||||||
for (( i = 1; i < COMP_CWORD; i++ )); do
|
|
||||||
local word="${COMP_WORDS[$i]}"
|
|
||||||
|
|
||||||
# If currently processing an argument, skip this word
|
|
||||||
if [[ "$state" != 'normal' ]]; then
|
|
||||||
state=normal
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$word" = '--' ]]; then
|
|
||||||
# Options stop being parsed after this
|
|
||||||
opt_ena=false
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if it's a long option
|
|
||||||
if [[ "$word" = '--'* ]]; then
|
|
||||||
# If the option is unknown, assume it takes no arguments: keep the state at "normal"
|
|
||||||
for long_opt in "${opts[@]}"; do
|
|
||||||
if [[ "$word" = "--${long_opt%%:*}" ]]; then
|
|
||||||
state="${long_opt#*:}"
|
|
||||||
# Check if the next word is just '='; if so, skip it, the argument must follow
|
|
||||||
# (See "known bugs" at the top of this script)
|
|
||||||
let i++
|
|
||||||
if [[ "${COMP_WORDS[$i]}" != '=' ]]; then
|
|
||||||
let i--
|
|
||||||
fi
|
|
||||||
optlen=0
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
# Check if it's a short option
|
|
||||||
elif [[ "$word" = '-'* ]]; then
|
|
||||||
parse_short_opt "$word"
|
|
||||||
# The last option takes an argument...
|
|
||||||
if [[ "$state" != 'normal' ]]; then
|
|
||||||
if [[ "$optlen" -ne "${#word}" ]]; then
|
|
||||||
# If it's contained within the word, we won't complete it, revert to "normal"
|
|
||||||
state=normal
|
|
||||||
else
|
|
||||||
# Otherwise, complete it, but start at the beginning of *that* word
|
|
||||||
optlen=0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Parse current word
|
|
||||||
# Careful that it might look like an option, so use `--` aggressively!
|
|
||||||
local cur_word="${COMP_WORDS[$i]}"
|
|
||||||
|
|
||||||
# Process options, as short ones may change the state
|
|
||||||
if $opt_ena && [[ "$state" = 'normal' && "$cur_word" = '-'* ]]; then
|
|
||||||
# We might want to complete to an option or an arg to that option
|
|
||||||
# Parse the option word to check
|
|
||||||
# There's no whitespace in the option names, so we can ride a little dirty...
|
|
||||||
|
|
||||||
# Is this a long option?
|
|
||||||
if [[ "$cur_word" = '--'* ]]; then
|
|
||||||
# It is, try to complete one
|
|
||||||
mapfile -t COMPREPLY < <(compgen -W "${opts[*]%%:*}" -P '--' -- "${cur_word#--}")
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
# Short options may be grouped, parse them to determine what to complete
|
|
||||||
parse_short_opt "$cur_word"
|
|
||||||
|
|
||||||
if [[ "$state" = 'normal' ]]; then
|
|
||||||
mapfile -t COMPREPLY < <(compgen -W "${!opts[*]}" -P "$cur_word" '')
|
|
||||||
return 0
|
|
||||||
elif [[ "$optlen" = "${#cur_word}" && "$state" != "warning" ]]; then
|
|
||||||
# This short option group only awaits its argument!
|
|
||||||
# Post the option group as-is as a reply so that Readline inserts a space,
|
|
||||||
# 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
|
|
||||||
# `-W`, and it doesn't break anything.
|
|
||||||
COMPREPLY=( "$cur_word" )
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
COMPREPLY=()
|
|
||||||
case "$state" in
|
|
||||||
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...
|
|
||||||
state="glob-*.o *.obj"
|
|
||||||
;&
|
|
||||||
glob-*)
|
|
||||||
while read -r word; do
|
|
||||||
COMPREPLY+=("${cur_word:0:$optlen}$word")
|
|
||||||
done < <(for glob in ${state#glob-}; do compgen -A file -X \!"$glob" -- "${cur_word:$optlen}"; done)
|
|
||||||
# Also complete directories
|
|
||||||
;&
|
|
||||||
dir)
|
|
||||||
while read -r word; do
|
|
||||||
COMPREPLY+=("${cur_word:0:$optlen}$word")
|
|
||||||
done < <(compgen -A directory -- "${cur_word:$optlen}")
|
|
||||||
compopt -o filenames
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo >&2 "Internal completion error: invalid state \"$state\", please report this bug"
|
|
||||||
return 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
complete -F _rgblink_completions rgblink
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
declare -A FILES
|
|
||||||
while read -r -d '' file; do
|
|
||||||
FILES["$file"]="true"
|
|
||||||
done < <(git diff --name-only -z "$1" HEAD)
|
|
||||||
|
|
||||||
edited () {
|
|
||||||
${FILES["$1"]:-"false"}
|
|
||||||
}
|
|
||||||
|
|
||||||
dependency () {
|
|
||||||
if edited "$1" && ! edited "$2"; then
|
|
||||||
echo "'$1' was modified, but not '$2'! $3" | xargs
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Pull requests that edit the first file without the second may be correct,
|
|
||||||
# but are suspicious enough to require review.
|
|
||||||
|
|
||||||
dependency include/linkdefs.hpp man/rgbds.5 \
|
|
||||||
"Was the object file format changed?"
|
|
||||||
|
|
||||||
dependency src/asm/parser.y man/rgbasm.5 \
|
|
||||||
"Was the rgbasm grammar changed?"
|
|
||||||
|
|
||||||
dependency src/asm/actions.cpp man/rgbasm.5 \
|
|
||||||
"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?"
|
|
||||||
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 \
|
|
||||||
"Should the object file revision be bumped?"
|
|
||||||
dependency src/link/object.cpp include/linkdefs.hpp \
|
|
||||||
"Should the object file revision be bumped?"
|
|
||||||
|
|
||||||
dependency Makefile CMakeLists.txt \
|
|
||||||
"Did the build process change?"
|
|
||||||
dependency Makefile src/CMakeLists.txt \
|
|
||||||
"Did the build process change?"
|
|
||||||
|
|
||||||
dependency src/asm/main.cpp man/rgbasm.1 \
|
|
||||||
"Did the rgbasm CLI change?"
|
|
||||||
dependency src/asm/main.cpp contrib/zsh_compl/_rgbasm \
|
|
||||||
"Did the rgbasm CLI change?"
|
|
||||||
dependency src/asm/main.cpp contrib/bash_compl/_rgbasm.bash \
|
|
||||||
"Did the rgbasm CLI change?"
|
|
||||||
dependency src/link/main.cpp man/rgblink.1 \
|
|
||||||
"Did the rgblink CLI change?"
|
|
||||||
dependency src/link/main.cpp contrib/zsh_compl/_rgblink \
|
|
||||||
"Did the rgblink CLI change?"
|
|
||||||
dependency src/link/main.cpp contrib/bash_compl/_rgblink.bash \
|
|
||||||
"Did the rgblink CLI change?"
|
|
||||||
dependency src/fix/main.cpp man/rgbfix.1 \
|
|
||||||
"Did the rgbfix CLI change?"
|
|
||||||
dependency src/fix/main.cpp contrib/zsh_compl/_rgbfix \
|
|
||||||
"Did the rgbfix CLI change?"
|
|
||||||
dependency src/fix/main.cpp contrib/bash_compl/_rgbfix.bash \
|
|
||||||
"Did the rgbfix CLI change?"
|
|
||||||
dependency src/gfx/main.cpp man/rgbgfx.1 \
|
|
||||||
"Did the rgbgfx CLI change?"
|
|
||||||
dependency src/gfx/main.cpp contrib/zsh_compl/_rgbgfx \
|
|
||||||
"Did the rgbgfx CLI change?"
|
|
||||||
dependency src/gfx/main.cpp contrib/bash_compl/_rgbgfx.bash \
|
|
||||||
"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"
|
|
||||||
@@ -9,58 +9,41 @@ _rgbasm_warnings() {
|
|||||||
'everything:Enable literally everything'
|
'everything:Enable literally everything'
|
||||||
|
|
||||||
'assert:Warn when WARN-type asserts fail'
|
'assert:Warn when WARN-type asserts fail'
|
||||||
'backwards-for:Warn when start and stop are backwards relative to step'
|
|
||||||
'builtin-args:Report incorrect args to built-in funcs'
|
'builtin-args:Report incorrect args to built-in funcs'
|
||||||
'charmap-redef:Warn when redefining a charmap mapping'
|
|
||||||
'div:Warn when dividing the smallest int by -1'
|
'div:Warn when dividing the smallest int by -1'
|
||||||
'empty-data-directive:Warn on arg-less d[bwl] in ROM'
|
'empty-entry:Warn on empty entries in db, dw, dl args'
|
||||||
'empty-macro-arg:Warn on empty macro arg'
|
|
||||||
'empty-strrpl:Warn on calling STRRPL with empty pattern'
|
|
||||||
'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'
|
||||||
'macro-shift:Warn when shifting macro args part their limits'
|
'long-string:Warn on strings too long'
|
||||||
'nested-comment:Warn on "/*" inside block comments'
|
|
||||||
'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 truncations lose 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?
|
||||||
_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]'
|
||||||
|
'(-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]'
|
'(-v --verbose)'{-v,--verbose}'[Print additional messages regarding progression]'
|
||||||
-w'[Disable all warnings]'
|
-w'[Disable all warnings]'
|
||||||
|
|
||||||
'(-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:'
|
||||||
'*'{-D,--define}'+[Define a string symbol]:name + value (default 1):'
|
'(-D --define)'{-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 dependencies should be generated]'
|
|
||||||
-MP'[Add phony targets to all dependencies]'
|
|
||||||
'*'-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}'"
|
|
||||||
'(-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'"
|
||||||
)
|
)
|
||||||
_arguments -s -S : $args
|
_arguments -s -S : $args
|
||||||
|
|||||||
@@ -1,79 +1,24 @@
|
|||||||
#compdef rgbfix
|
#compdef rgbfix
|
||||||
|
|
||||||
_mbc_names() {
|
|
||||||
local mbc_names=(
|
|
||||||
'ROM:$00'
|
|
||||||
'MBC1:$01'
|
|
||||||
'MBC1+RAM:$02'
|
|
||||||
'MBC1+RAM+BATTERY:$03'
|
|
||||||
'MBC2:$05'
|
|
||||||
'MBC2+BATTERY:$06'
|
|
||||||
'ROM+RAM:$08'
|
|
||||||
'ROM+RAM+BATTERY:$09'
|
|
||||||
'MMM01:$0B'
|
|
||||||
'MMM01+RAM:$0C'
|
|
||||||
'MMM01+RAM+BATTERY:$0D'
|
|
||||||
'MBC3+TIMER+BATTERY:$0F'
|
|
||||||
'MBC3+TIMER+RAM+BATTERY:$10'
|
|
||||||
'MBC3:$11'
|
|
||||||
'MBC3+RAM:$12'
|
|
||||||
'MBC3+RAM+BATTERY:$13'
|
|
||||||
'MBC5:$19'
|
|
||||||
'MBC5+RAM:$1A'
|
|
||||||
'MBC5+RAM+BATTERY:$1B'
|
|
||||||
'MBC5+RUMBLE:$1C'
|
|
||||||
'MBC5+RUMBLE+RAM:$1D'
|
|
||||||
'MBC5+RUMBLE+RAM+BATTERY:$1E'
|
|
||||||
'MBC6:$20'
|
|
||||||
'MBC7+SENSOR+RUMBLE+RAM+BATTERY:$22'
|
|
||||||
'POCKET_CAMERA:$FC'
|
|
||||||
'BANDAI_TAMA5:$FD'
|
|
||||||
'HUC3:$FE'
|
|
||||||
'HUC1+RAM+BATTERY:$FF'
|
|
||||||
)
|
|
||||||
_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'
|
|
||||||
'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-only}'[Mark ROM as GBC-only]'
|
||||||
'(-C --color-only -c --color-compatible)'{-c,--color-compatible}'[Mark ROM as GBC-compatible]'
|
'(-c --color-compatible)'{-c,--color-compatible}'[Mark ROM as GBC-compatible]'
|
||||||
'(-j --non-japanese)'{-j,--non-japanese}'[Set the non-Japanese region flag]'
|
'(-j --non-japanese)'{-j,--non-japanese}'[Set the non-Japanese region flag]'
|
||||||
'(-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]'
|
|
||||||
|
|
||||||
'(-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 flags byte:'
|
||||||
'(-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,29 @@ _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"'
|
|
||||||
'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:'
|
|
||||||
'(-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 files:_files -g '*.png'"
|
||||||
)
|
)
|
||||||
_arguments -s -S : $args
|
_arguments -s -S : $args
|
||||||
|
|||||||
@@ -1,42 +1,21 @@
|
|||||||
#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]'
|
||||||
'(-v --verbose)'{-v,--verbose}'[Enable verbose output]'
|
'(-v --verbose)'{-v,--verbose}'[Enable verbose output]'
|
||||||
'(-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]'
|
|
||||||
|
|
||||||
'(-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 --smart)'{-s,--smart}'+[!BROKEN! Perform smart linking from this symbol]:symbol name:'
|
||||||
'(-W --warning)'{-W,--warning}'+[Toggle warning flags]:warning flag:_rgblink_warnings'
|
|
||||||
|
|
||||||
'*'":object files:_files -g '*.o'"
|
'*'":object files:_files -g '*.o'"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#ifndef RGBDS_ASM_ACTIONS_HPP
|
|
||||||
#define RGBDS_ASM_ACTIONS_HPP
|
|
||||||
|
|
||||||
#include <optional>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string>
|
|
||||||
#include <string_view>
|
|
||||||
#include <variant>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "asm/output.hpp" // AssertionType
|
|
||||||
#include "asm/rpn.hpp" // RPNCommand
|
|
||||||
|
|
||||||
std::optional<std::string> act_ReadFile(std::string const &name, uint32_t maxLen);
|
|
||||||
|
|
||||||
uint32_t act_StringToNum(std::vector<int32_t> const &str);
|
|
||||||
|
|
||||||
size_t act_StringLen(std::string const &str, bool printErrors);
|
|
||||||
std::string act_StringSlice(std::string const &str, uint32_t start, uint32_t stop);
|
|
||||||
std::string act_StringSub(std::string const &str, uint32_t pos, uint32_t len);
|
|
||||||
|
|
||||||
size_t act_CharLen(std::string const &str);
|
|
||||||
std::string act_StringChar(std::string const &str, uint32_t idx);
|
|
||||||
std::string act_CharSub(std::string const &str, uint32_t pos);
|
|
||||||
int32_t act_CharCmp(std::string_view str1, std::string_view str2);
|
|
||||||
|
|
||||||
uint32_t act_AdjustNegativeIndex(int32_t idx, size_t len, char const *functionName);
|
|
||||||
uint32_t act_AdjustNegativePos(int32_t pos, size_t len, char const *functionName);
|
|
||||||
|
|
||||||
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
|
|
||||||
);
|
|
||||||
|
|
||||||
void act_CompoundAssignment(std::string const &symName, RPNCommand op, int32_t constValue);
|
|
||||||
|
|
||||||
void act_FailAssert(AssertionType type);
|
|
||||||
void act_FailAssertMsg(AssertionType type, std::string const &message);
|
|
||||||
|
|
||||||
#endif // RGBDS_ASM_ACTIONS_HPP
|
|
||||||
22
include/asm/charmap.h
Normal file
22
include/asm/charmap.h
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* 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(const char *name, const char *baseName);
|
||||||
|
void charmap_Delete(struct Charmap *charmap);
|
||||||
|
void charmap_Set(const char *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);
|
||||||
|
|
||||||
|
#endif /* RGBDS_ASM_CHARMAP_H */
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#ifndef RGBDS_ASM_CHARMAP_HPP
|
|
||||||
#define RGBDS_ASM_CHARMAP_HPP
|
|
||||||
|
|
||||||
#include <optional>
|
|
||||||
#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 <stdint.h>
|
||||||
|
#include <stdbool.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;
|
||||||
|
uint8_t width;
|
||||||
|
bool hasFrac;
|
||||||
|
uint8_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,47 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#ifndef RGBDS_ASM_FORMAT_HPP
|
|
||||||
#define RGBDS_ASM_FORMAT_HPP
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
enum FormatState {
|
|
||||||
FORMAT_SIGN, // expects '+' or ' ' (optional)
|
|
||||||
FORMAT_EXACT, // 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_PREC, // got 'q', expects '0'-'9', range 1-31 (optional)
|
|
||||||
FORMAT_DONE, // got [duXxbofs] (required)
|
|
||||||
FORMAT_INVALID, // got unexpected character
|
|
||||||
};
|
|
||||||
|
|
||||||
class FormatSpec {
|
|
||||||
FormatState state;
|
|
||||||
int sign;
|
|
||||||
bool exact;
|
|
||||||
bool alignLeft;
|
|
||||||
bool padZero;
|
|
||||||
size_t width;
|
|
||||||
bool hasFrac;
|
|
||||||
size_t fracWidth;
|
|
||||||
bool hasPrec;
|
|
||||||
size_t precision;
|
|
||||||
int type;
|
|
||||||
bool valid;
|
|
||||||
|
|
||||||
public:
|
|
||||||
bool isEmpty() const { return !state; }
|
|
||||||
bool isValid() const { return valid || state == FORMAT_DONE; }
|
|
||||||
bool isFinished() const { return state >= FORMAT_DONE; }
|
|
||||||
|
|
||||||
void useCharacter(int c);
|
|
||||||
void finishCharacters();
|
|
||||||
|
|
||||||
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"
|
||||||
|
|
||||||
|
#include "types.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 nMaxRecursionDepth;
|
||||||
|
|
||||||
|
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 nReptLineNo, 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_Init(char const *mainPath, size_t maxRecursionDepth);
|
||||||
|
|
||||||
|
#endif /* RGBDS_ASM_FSTACK_H */
|
||||||
@@ -1,80 +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;
|
|
||||||
|
|
||||||
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_)
|
|
||||||
: type(type_), data(data_) {}
|
|
||||||
|
|
||||||
std::string const &dump(uint32_t curLineNo) const;
|
|
||||||
std::string reptChain() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MacroArgs;
|
|
||||||
|
|
||||||
bool fstk_DumpCurrent();
|
|
||||||
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);
|
|
||||||
void fstk_RunMacro(std::string const ¯oName, std::shared_ptr<MacroArgs> macroArgs);
|
|
||||||
void fstk_RunRept(uint32_t count, int32_t reptLineNo, ContentSpan const &span);
|
|
||||||
void fstk_RunFor(
|
|
||||||
std::string const &symName,
|
|
||||||
int32_t start,
|
|
||||||
int32_t stop,
|
|
||||||
int32_t step,
|
|
||||||
int32_t reptLineNo,
|
|
||||||
ContentSpan const &span
|
|
||||||
);
|
|
||||||
bool fstk_Break();
|
|
||||||
|
|
||||||
void fstk_NewRecursionDepth(size_t newDepth);
|
|
||||||
void fstk_Init(std::string const &mainPath);
|
|
||||||
|
|
||||||
#endif // RGBDS_ASM_FSTACK_HPP
|
|
||||||
101
include/asm/lexer.h
Normal file
101
include/asm/lexer.h
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
* 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 *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;
|
||||||
|
};
|
||||||
|
|
||||||
|
char const *lexer_GetFileName(void);
|
||||||
|
uint32_t lexer_GetLineNo(void);
|
||||||
|
uint32_t lexer_GetColNo(void);
|
||||||
|
void lexer_DumpStringExpansions(void);
|
||||||
|
int yylex(void);
|
||||||
|
void lexer_CaptureRept(struct CaptureBody *capture);
|
||||||
|
void 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,146 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#ifndef RGBDS_ASM_LEXER_HPP
|
|
||||||
#define RGBDS_ASM_LEXER_HPP
|
|
||||||
|
|
||||||
#include <deque>
|
|
||||||
#include <memory>
|
|
||||||
#include <optional>
|
|
||||||
#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_DumpStringExpansions();
|
|
||||||
|
|
||||||
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 *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
|
|
||||||
37
include/asm/main.h
Normal file
37
include/asm/main.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* 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 *tzTargetFileName;
|
||||||
|
extern bool oGeneratedMissingIncludes;
|
||||||
|
extern bool oFailedOnMissingInclude;
|
||||||
|
extern bool oGeneratePhonyDeps;
|
||||||
|
|
||||||
|
/* TODO: are these really needed? */
|
||||||
|
#define YY_FATAL_ERROR fatalerror
|
||||||
|
|
||||||
|
#ifdef YYLMAX
|
||||||
|
#undef YYLMAX
|
||||||
|
#endif
|
||||||
|
#define YYLMAX 65536
|
||||||
|
|
||||||
|
#endif /* RGBDS_MAIN_H */
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#ifndef RGBDS_ASM_MAIN_HPP
|
|
||||||
#define RGBDS_ASM_MAIN_HPP
|
|
||||||
|
|
||||||
#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 {
|
|
||||||
uint8_t fixPrecision = 16; // -Q
|
|
||||||
size_t maxRecursionDepth = 64; // -r
|
|
||||||
char binDigits[2] = {'0', '1'}; // -b
|
|
||||||
char gfxDigits[4] = {'0', '1', '2', '3'}; // -g
|
|
||||||
bool verbose = false; // -v
|
|
||||||
FILE *dependFile = nullptr; // -M
|
|
||||||
std::string targetFileName; // -MQ, -MT
|
|
||||||
MissingInclude missingIncludeState = INC_ERROR; // -MC, -MG
|
|
||||||
bool generatePhonyDeps = false; // -MP
|
|
||||||
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;
|
|
||||||
|
|
||||||
#define verbosePrint(...) \
|
|
||||||
do { \
|
|
||||||
if (options.verbose) { \
|
|
||||||
fprintf(stderr, __VA_ARGS__); \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#endif // RGBDS_ASM_MAIN_HPP
|
|
||||||
22
include/asm/opt.h
Normal file
22
include/asm/opt.h
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
|
||||||
|
void opt_B(char chars[2]);
|
||||||
|
void opt_G(char chars[4]);
|
||||||
|
void opt_P(uint8_t fill);
|
||||||
|
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 *tzObjectname;
|
||||||
|
extern struct Section *pSectionList, *pCurrentSection;
|
||||||
|
|
||||||
|
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,27 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#ifndef RGBDS_ASM_OUTPUT_HPP
|
|
||||||
#define RGBDS_ASM_OUTPUT_HPP
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "linkdefs.hpp"
|
|
||||||
|
|
||||||
struct Expression;
|
|
||||||
struct FileStackNode;
|
|
||||||
|
|
||||||
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_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
|
|
||||||
66
include/asm/rpn.h
Normal file
66
include/asm/rpn.h
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* 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 nVal; // 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 *tRPN; // Array of bytes serializing the RPN expression
|
||||||
|
uint32_t nRPNCapacity; // Size of the `tRPN` buffer
|
||||||
|
uint32_t nRPNLength; // Used size of the `tRPN` buffer
|
||||||
|
uint32_t nRPNPatchSize; // Size the expression will take in the obj file
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determines if an expression is known at assembly time
|
||||||
|
*/
|
||||||
|
static inline bool rpn_isKnown(const struct Expression *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 *tzSym);
|
||||||
|
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 *sym);
|
||||||
|
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 *tzSym);
|
||||||
|
void rpn_BankSection(struct Expression *expr, char const *tzSectionName);
|
||||||
|
void rpn_BankSelf(struct Expression *expr);
|
||||||
|
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);
|
||||||
|
|
||||||
|
#endif /* RGBDS_ASM_RPN_H */
|
||||||
@@ -1,57 +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 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;
|
|
||||||
bool isSymbol = false; // Whether the expression represents a symbol suitable for const diffing
|
|
||||||
std::vector<uint8_t> rpn{}; // Bytes serializing the RPN expression
|
|
||||||
uint32_t rpnPatchSize = 0; // Size the expression will take in the object file
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
bool makeCheckHRAM();
|
|
||||||
void makeCheckRST();
|
|
||||||
void makeCheckBitIndex(uint8_t mask);
|
|
||||||
|
|
||||||
void checkNBit(uint8_t n) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void clear();
|
|
||||||
uint8_t *reserveSpace(uint32_t size);
|
|
||||||
uint8_t *reserveSpace(uint32_t size, uint32_t patchSize);
|
|
||||||
};
|
|
||||||
|
|
||||||
bool checkNBit(int32_t v, uint8_t n, char const *name);
|
|
||||||
|
|
||||||
#endif // RGBDS_ASM_RPN_HPP
|
|
||||||
79
include/asm/section.h
Normal file
79
include/asm/section.h
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* 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"
|
||||||
|
|
||||||
|
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;
|
||||||
|
uint16_t alignOfs;
|
||||||
|
struct Section *next;
|
||||||
|
struct Patch *patches;
|
||||||
|
uint8_t *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SectionSpec {
|
||||||
|
uint32_t bank;
|
||||||
|
uint8_t alignment;
|
||||||
|
uint16_t alignOfs;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Section *out_FindSectionByName(const char *name);
|
||||||
|
void out_NewSection(char const *name, uint32_t secttype, uint32_t org,
|
||||||
|
struct SectionSpec const *attributes,
|
||||||
|
enum SectionModifier mod);
|
||||||
|
void out_SetLoadSection(char const *name, uint32_t secttype, uint32_t org,
|
||||||
|
struct SectionSpec const *attributes,
|
||||||
|
enum SectionModifier mod);
|
||||||
|
void out_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 out_AbsByte(uint8_t b);
|
||||||
|
void out_AbsByteGroup(uint8_t const *s, int32_t length);
|
||||||
|
void out_AbsWordGroup(uint8_t const *s, int32_t length);
|
||||||
|
void out_AbsLongGroup(uint8_t const *s, int32_t length);
|
||||||
|
void out_Skip(int32_t skip, bool ds);
|
||||||
|
void out_String(char const *s);
|
||||||
|
void out_RelByte(struct Expression *expr, uint32_t pcShift);
|
||||||
|
void out_RelBytes(uint32_t n, struct Expression *exprs, size_t size);
|
||||||
|
void out_RelWord(struct Expression *expr, uint32_t pcShift);
|
||||||
|
void out_RelLong(struct Expression *expr, uint32_t pcShift);
|
||||||
|
void out_PCRelByte(struct Expression *expr, uint32_t pcShift);
|
||||||
|
void out_BinaryFile(char const *s, int32_t startPos);
|
||||||
|
void out_BinaryFileSlice(char const *s, int32_t start_pos, int32_t length);
|
||||||
|
|
||||||
|
void out_PushSection(void);
|
||||||
|
void out_PopSection(void);
|
||||||
|
|
||||||
|
#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 <stdint.h>
|
|
||||||
#include <string>
|
|
||||||
#include <unordered_map>
|
|
||||||
#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
|
|
||||||
152
include/asm/symbol.h
Normal file
152
include/asm/symbol.h
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
#define HASHSIZE (1 << 16)
|
||||||
|
#define MAXSYMLEN 256
|
||||||
|
|
||||||
|
enum SymbolType {
|
||||||
|
SYM_LABEL,
|
||||||
|
SYM_EQU,
|
||||||
|
SYM_SET,
|
||||||
|
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 */
|
||||||
|
struct {
|
||||||
|
size_t macroSize;
|
||||||
|
char *macro;
|
||||||
|
};
|
||||||
|
/* For SYM_EQUS, TODO: separate "base" fields from SYM_MACRO */
|
||||||
|
char const *(*strCallback)(void); /* For SYM_EQUS */
|
||||||
|
};
|
||||||
|
|
||||||
|
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_SET;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool sym_IsNumeric(struct Symbol const *sym)
|
||||||
|
{
|
||||||
|
return sym->type == SYM_LABEL || sym->type == SYM_EQU
|
||||||
|
|| sym->type == SYM_SET;
|
||||||
|
}
|
||||||
|
|
||||||
|
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_AddSet(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 *s);
|
||||||
|
/*
|
||||||
|
* Find a symbol by exact name, bypassing expansion checks
|
||||||
|
*/
|
||||||
|
struct Symbol *sym_FindExactSymbol(char const *name);
|
||||||
|
/*
|
||||||
|
* Find a symbol by exact name; may not be scoped, produces an error if it is
|
||||||
|
*/
|
||||||
|
struct Symbol *sym_FindUnscopedSymbol(char const *name);
|
||||||
|
/*
|
||||||
|
* Find a symbol, possibly scoped, by name
|
||||||
|
*/
|
||||||
|
struct Symbol *sym_FindScopedSymbol(char const *name);
|
||||||
|
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.h>
|
|
||||||
#include <string>
|
|
||||||
#include <string_view>
|
|
||||||
#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 isExported; // Whether the symbol is to be exported
|
|
||||||
bool isBuiltin; // Whether the symbol is a built-in
|
|
||||||
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 &));
|
|
||||||
|
|
||||||
void sym_SetExportAll(bool set);
|
|
||||||
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);
|
|
||||||
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>
|
||||||
|
|
||||||
|
uint32_t calchash(const char *s);
|
||||||
|
char const *print(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 */
|
||||||
70
include/asm/warning.h
Normal file
70
include/asm/warning.h
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* 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 WarningID {
|
||||||
|
WARNING_ASSERT, /* Assertions */
|
||||||
|
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_TRUNCATION, /* Implicit truncation loses some bits */
|
||||||
|
WARNING_USER, /* User warnings */
|
||||||
|
|
||||||
|
NB_WARNINGS,
|
||||||
|
|
||||||
|
/* Warnings past this point are "meta" warnings */
|
||||||
|
WARNING_ALL = NB_WARNINGS,
|
||||||
|
WARNING_EXTRA,
|
||||||
|
WARNING_EVERYTHING,
|
||||||
|
|
||||||
|
NB_WARNINGS_ALL
|
||||||
|
#define NB_META_WARNINGS (NB_WARNINGS_ALL - NB_WARNINGS)
|
||||||
|
};
|
||||||
|
|
||||||
|
void processWarningFlag(char const *flag);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Used to warn the user about problems that don't prevent the generation of
|
||||||
|
* valid code.
|
||||||
|
*/
|
||||||
|
void warning(enum WarningID id, const char *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(const char *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(const char *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_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 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(std::function<void()> callback);
|
|
||||||
|
|
||||||
void requireZeroErrors();
|
|
||||||
|
|
||||||
#endif // RGBDS_ASM_WARNING_HPP
|
|
||||||
@@ -1,212 +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.h>
|
|
||||||
#include <string>
|
|
||||||
#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 L>
|
|
||||||
struct WarningFlag {
|
|
||||||
char const *name;
|
|
||||||
L level;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum WarningBehavior { DISABLED, ENABLED, ERROR };
|
|
||||||
|
|
||||||
template<typename W>
|
|
||||||
struct ParamWarning {
|
|
||||||
W firstID;
|
|
||||||
W lastID;
|
|
||||||
uint8_t defaultLevel;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename W>
|
|
||||||
struct DiagnosticsState {
|
|
||||||
WarningState flagStates[W::NB_WARNINGS];
|
|
||||||
WarningState metaStates[W::NB_WARNINGS];
|
|
||||||
bool warningsEnabled = true;
|
|
||||||
bool warningsAreErrors = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename L, typename W>
|
|
||||||
struct Diagnostics {
|
|
||||||
std::vector<WarningFlag<L>> metaWarnings;
|
|
||||||
std::vector<WarningFlag<L>> warningFlags;
|
|
||||||
std::vector<ParamWarning<W>> paramWarnings;
|
|
||||||
DiagnosticsState<W> state;
|
|
||||||
uint64_t nbErrors;
|
|
||||||
|
|
||||||
void incrementErrors() {
|
|
||||||
if (nbErrors != UINT64_MAX) {
|
|
||||||
++nbErrors;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
WarningBehavior getWarningBehavior(W id) const;
|
|
||||||
std::string processWarningFlag(char const *flag);
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename L, typename W>
|
|
||||||
WarningBehavior Diagnostics<L, W>::getWarningBehavior(W 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 == L::LEVEL_DEFAULT) { // enabled by default
|
|
||||||
return enabledBehavior;
|
|
||||||
}
|
|
||||||
|
|
||||||
// No flag enables this warning, explicitly or implicitly
|
|
||||||
return WarningBehavior::DISABLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename L, typename W>
|
|
||||||
std::string Diagnostics<L, W>::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 rootFlag;
|
|
||||||
} else if (rootFlag == "no-error") {
|
|
||||||
// `-Wno-error` disables promotion of warnings to errors
|
|
||||||
state.warningsAreErrors = false;
|
|
||||||
return rootFlag;
|
|
||||||
}
|
|
||||||
|
|
||||||
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<W> const ¶mWarning : paramWarnings) {
|
|
||||||
W 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 rootFlag;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (param.has_value()) {
|
|
||||||
warnx("Unknown warning flag parameter \"%s=%" PRIu32 "\"", rootFlag.c_str(), *param);
|
|
||||||
return rootFlag;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to match against a "meta" warning
|
|
||||||
for (WarningFlag<L> const &metaWarning : metaWarnings) {
|
|
||||||
if (rootFlag != metaWarning.name) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set each of the warning flags that meets this level
|
|
||||||
for (W id : EnumSeq(W::NB_WARNINGS)) {
|
|
||||||
if (metaWarning.level >= warningFlags[id].level) {
|
|
||||||
state.metaStates[id].update(flagState);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return rootFlag;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to match against a "normal" flag
|
|
||||||
for (W id : EnumSeq(W::NB_PLAIN_WARNINGS)) {
|
|
||||||
if (rootFlag == warningFlags[id].name) {
|
|
||||||
state.flagStates[id].update(flagState);
|
|
||||||
return rootFlag;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
warnx("Unknown warning flag \"%s\"", rootFlag.c_str());
|
|
||||||
return rootFlag;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // RGBDS_DIAGNOSTICS_HPP
|
|
||||||
44
include/extern/err.h
vendored
Normal file
44
include/extern/err.h
vendored
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of RGBDS.
|
||||||
|
*
|
||||||
|
* Copyright (c) 1997-2018, RGBDS contributors.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EXTERN_ERR_H
|
||||||
|
#define EXTERN_ERR_H
|
||||||
|
|
||||||
|
#ifdef ERR_IN_LIBC
|
||||||
|
|
||||||
|
#include <err.h>
|
||||||
|
|
||||||
|
#else /* ERR_IN_LIBC */
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include "helpers.h"
|
||||||
|
|
||||||
|
#define warn rgbds_warn
|
||||||
|
#define vwarn rgbds_vwarn
|
||||||
|
#define warnx rgbds_warnx
|
||||||
|
#define vwarnx rgbds_vwarnx
|
||||||
|
|
||||||
|
#define err rgbds_err
|
||||||
|
#define verr rgbds_verr
|
||||||
|
#define errx rgbds_errx
|
||||||
|
#define verrx rgbds_verrx
|
||||||
|
|
||||||
|
void warn(const char *fmt, ...) format_(printf, 1, 2);
|
||||||
|
void vwarn(const char *fmt, va_list ap) format_(printf, 1, 0);
|
||||||
|
void warnx(const char *fmt, ...) format_(printf, 1, 2);
|
||||||
|
void vwarnx(const char *fmt, va_list ap) format_(printf, 1, 0);
|
||||||
|
|
||||||
|
_Noreturn void err(int status, const char *fmt, ...) format_(printf, 2, 3);
|
||||||
|
_Noreturn void verr(int status, const char *fmt, va_list ap) format_(printf, 2, 0);
|
||||||
|
_Noreturn void errx(int status, const char *fmt, ...) format_(printf, 2, 3);
|
||||||
|
_Noreturn void verrx(int status, const char *fmt, va_list ap) format_(printf, 2, 0);
|
||||||
|
|
||||||
|
#endif /* ERR_IN_LIBC */
|
||||||
|
|
||||||
|
#endif /* EXTERN_ERR_H */
|
||||||
45
include/extern/getopt.h
vendored
Normal file
45
include/extern/getopt.h
vendored
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* 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 {
|
||||||
|
const char *name;
|
||||||
|
int has_arg;
|
||||||
|
int *flag;
|
||||||
|
int val;
|
||||||
|
};
|
||||||
|
|
||||||
|
int musl_getopt_long_only(int, char **, const char *, const struct option *, int *);
|
||||||
|
|
||||||
|
#define no_argument 0
|
||||||
|
#define required_argument 1
|
||||||
|
#define optional_argument 2
|
||||||
|
|
||||||
|
#endif
|
||||||
28
include/extern/getopt.hpp
vendored
28
include/extern/getopt.hpp
vendored
@@ -1,28 +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_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, option const *longopts, int *idx
|
|
||||||
);
|
|
||||||
|
|
||||||
#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,62 +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.h>
|
|
||||||
#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,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,41 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#ifndef RGBDS_FIX_WARNING_HPP
|
|
||||||
#define RGBDS_FIX_WARNING_HPP
|
|
||||||
|
|
||||||
#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_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
|
|
||||||
36
include/gfx/gb.h
Normal file
36
include/gfx/gb.h
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of RGBDS.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013-2018, stag019 and RGBDS contributors.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RGBDS_GFX_GB_H
|
||||||
|
#define RGBDS_GFX_GB_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "gfx/main.h"
|
||||||
|
|
||||||
|
#define XFLIP 0x40
|
||||||
|
#define YFLIP 0x20
|
||||||
|
|
||||||
|
void raw_to_gb(const struct RawIndexedImage *raw_image, struct GBImage *gb);
|
||||||
|
void output_file(const struct Options *opts, const struct GBImage *gb);
|
||||||
|
int get_tile_index(uint8_t *tile, uint8_t **tiles, int num_tiles,
|
||||||
|
int tile_size);
|
||||||
|
uint8_t reverse_bits(uint8_t b);
|
||||||
|
void xflip(uint8_t *tile, uint8_t *tile_xflip, int tile_size);
|
||||||
|
void yflip(uint8_t *tile, uint8_t *tile_yflip, int tile_size);
|
||||||
|
int get_mirrored_tile_index(uint8_t *tile, uint8_t **tiles, int num_tiles,
|
||||||
|
int tile_size, int *flags);
|
||||||
|
void create_mapfiles(const struct Options *opts, struct GBImage *gb,
|
||||||
|
struct Mapfile *tilemap, struct Mapfile *attrmap);
|
||||||
|
void output_tilemap_file(const struct Options *opts,
|
||||||
|
const struct Mapfile *tilemap);
|
||||||
|
void output_attrmap_file(const struct Options *opts,
|
||||||
|
const struct Mapfile *attrmap);
|
||||||
|
void output_palette_file(const struct Options *opts,
|
||||||
|
const struct RawIndexedImage *raw_image);
|
||||||
|
|
||||||
|
#endif
|
||||||
91
include/gfx/main.h
Normal file
91
include/gfx/main.h
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of RGBDS.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013-2018, stag019 and RGBDS contributors.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RGBDS_GFX_MAIN_H
|
||||||
|
#define RGBDS_GFX_MAIN_H
|
||||||
|
|
||||||
|
#include <png.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "extern/err.h"
|
||||||
|
|
||||||
|
struct Options {
|
||||||
|
bool debug;
|
||||||
|
bool verbose;
|
||||||
|
bool hardfix;
|
||||||
|
bool fix;
|
||||||
|
bool horizontal;
|
||||||
|
bool mirror;
|
||||||
|
bool unique;
|
||||||
|
bool colorcurve;
|
||||||
|
int trim;
|
||||||
|
char *tilemapfile;
|
||||||
|
bool tilemapout;
|
||||||
|
char *attrmapfile;
|
||||||
|
bool attrmapout;
|
||||||
|
char *palfile;
|
||||||
|
bool palout;
|
||||||
|
char *outfile;
|
||||||
|
char *infile;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RGBColor {
|
||||||
|
uint8_t red;
|
||||||
|
uint8_t green;
|
||||||
|
uint8_t blue;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ImageOptions {
|
||||||
|
bool horizontal;
|
||||||
|
int trim;
|
||||||
|
char *tilemapfile;
|
||||||
|
bool tilemapout;
|
||||||
|
char *attrmapfile;
|
||||||
|
bool attrmapout;
|
||||||
|
char *palfile;
|
||||||
|
bool palout;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PNGImage {
|
||||||
|
png_struct *png;
|
||||||
|
png_info *info;
|
||||||
|
|
||||||
|
png_byte **data;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
png_byte depth;
|
||||||
|
png_byte type;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RawIndexedImage {
|
||||||
|
uint8_t **data;
|
||||||
|
struct RGBColor *palette;
|
||||||
|
int num_colors;
|
||||||
|
unsigned int width;
|
||||||
|
unsigned int height;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GBImage {
|
||||||
|
uint8_t *data;
|
||||||
|
int size;
|
||||||
|
bool horizontal;
|
||||||
|
int trim;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Mapfile {
|
||||||
|
uint8_t *data;
|
||||||
|
int size;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern int depth, colors;
|
||||||
|
|
||||||
|
#include "gfx/makepng.h"
|
||||||
|
#include "gfx/gb.h"
|
||||||
|
|
||||||
|
#endif /* RGBDS_GFX_MAIN_H */
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#ifndef RGBDS_GFX_MAIN_HPP
|
|
||||||
#define RGBDS_GFX_MAIN_HPP
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <optional>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string>
|
|
||||||
#include <utility>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "helpers.hpp"
|
|
||||||
|
|
||||||
#include "gfx/rgba.hpp"
|
|
||||||
|
|
||||||
struct Options {
|
|
||||||
bool useColorCurve = false; // -C
|
|
||||||
bool allowDedup = false; // -u
|
|
||||||
bool allowMirroringX = false; // -X, -m
|
|
||||||
bool allowMirroringY = false; // -Y, -m
|
|
||||||
bool columnMajor = false; // -Z
|
|
||||||
uint8_t verbosity = 0; // -v
|
|
||||||
|
|
||||||
std::string attrmap{}; // -a, -A
|
|
||||||
std::optional<Rgba> bgColor{}; // -B
|
|
||||||
std::array<uint8_t, 2> baseTileIDs{0, 0}; // -b
|
|
||||||
enum {
|
|
||||||
NO_SPEC,
|
|
||||||
EXPLICIT,
|
|
||||||
EMBEDDED,
|
|
||||||
DMG,
|
|
||||||
} palSpecType = NO_SPEC; // -c
|
|
||||||
std::vector<std::array<std::optional<Rgba>, 4>> palSpec{};
|
|
||||||
uint8_t palSpecDmg = 0;
|
|
||||||
uint8_t bitDepth = 2; // -d
|
|
||||||
std::string inputTileset{}; // -i
|
|
||||||
struct {
|
|
||||||
uint16_t left;
|
|
||||||
uint16_t top;
|
|
||||||
uint16_t width;
|
|
||||||
uint16_t height;
|
|
||||||
uint32_t right() const { return left + width * 8; }
|
|
||||||
uint32_t bottom() const { return top + height * 8; }
|
|
||||||
} inputSlice{0, 0, 0, 0}; // -L (margins in clockwise order, like CSS)
|
|
||||||
uint8_t basePalID = 0; // -l
|
|
||||||
std::array<uint16_t, 2> maxNbTiles{UINT16_MAX, 0}; // -N
|
|
||||||
uint16_t nbPalettes = 8; // -n
|
|
||||||
std::string output{}; // -o
|
|
||||||
std::string palettes{}; // -p, -P
|
|
||||||
std::string palmap{}; // -q, -Q
|
|
||||||
uint16_t reversedWidth = 0; // -r, in tiles
|
|
||||||
uint8_t nbColorsPerPal = 0; // -s; 0 means "auto" = 1 << bitDepth;
|
|
||||||
std::string tilemap{}; // -t, -T
|
|
||||||
uint64_t trim = 0; // -x
|
|
||||||
|
|
||||||
std::string input{}; // positional arg
|
|
||||||
|
|
||||||
// clang-format off: vertically align values
|
|
||||||
static constexpr uint8_t VERB_NONE = 0; // Normal, no extra output
|
|
||||||
static constexpr uint8_t VERB_CFG = 1; // Print configuration after parsing options
|
|
||||||
static constexpr uint8_t VERB_LOG_ACT = 2; // Log actions before doing them
|
|
||||||
static constexpr uint8_t VERB_INTERM = 3; // Print some intermediate results
|
|
||||||
static constexpr uint8_t VERB_DEBUG = 4; // Internals are logged
|
|
||||||
static constexpr uint8_t VERB_TRACE = 5; // Step-by-step algorithm details
|
|
||||||
static constexpr uint8_t VERB_VVVVVV = 6; // What, can't I have a little fun?
|
|
||||||
// clang-format on
|
|
||||||
[[gnu::format(printf, 3, 4)]]
|
|
||||||
void verbosePrint(uint8_t level, char const *fmt, ...) const;
|
|
||||||
|
|
||||||
mutable bool hasTransparentPixels = false;
|
|
||||||
uint8_t maxOpaqueColors() const { return nbColorsPerPal - hasTransparentPixels; }
|
|
||||||
|
|
||||||
uint16_t maxNbColors() const { return nbColorsPerPal * nbPalettes; }
|
|
||||||
|
|
||||||
uint8_t dmgColors[4] = {};
|
|
||||||
uint8_t dmgValue(uint8_t i) const {
|
|
||||||
assume(i < 4);
|
|
||||||
return (palSpecDmg >> (2 * i)) & 0b11;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
extern Options options;
|
|
||||||
|
|
||||||
struct Palette {
|
|
||||||
// An array of 4 GBC-native (RGB555) colors
|
|
||||||
std::array<uint16_t, 4> colors{UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX};
|
|
||||||
|
|
||||||
void addColor(uint16_t color);
|
|
||||||
uint8_t indexOf(uint16_t color) const;
|
|
||||||
uint16_t &operator[](size_t index) { return colors[index]; }
|
|
||||||
uint16_t const &operator[](size_t index) const { return colors[index]; }
|
|
||||||
|
|
||||||
decltype(colors)::iterator begin();
|
|
||||||
decltype(colors)::iterator end();
|
|
||||||
decltype(colors)::const_iterator begin() const;
|
|
||||||
decltype(colors)::const_iterator end() const;
|
|
||||||
|
|
||||||
uint8_t size() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Flipping tends to happen fairly often, so take a bite out of dcache to speed it up
|
|
||||||
static std::array<uint16_t, 256> flipTable = ([]() constexpr {
|
|
||||||
std::array<uint16_t, 256> table{};
|
|
||||||
for (uint16_t i = 0; i < table.size(); ++i) {
|
|
||||||
// To flip all the bits, we'll flip both nibbles, then each nibble half, etc.
|
|
||||||
uint16_t byte = i;
|
|
||||||
byte = (byte & 0b0000'1111) << 4 | (byte & 0b1111'0000) >> 4;
|
|
||||||
byte = (byte & 0b0011'0011) << 2 | (byte & 0b1100'1100) >> 2;
|
|
||||||
byte = (byte & 0b0101'0101) << 1 | (byte & 0b1010'1010) >> 1;
|
|
||||||
table[i] = byte;
|
|
||||||
}
|
|
||||||
return table;
|
|
||||||
})();
|
|
||||||
|
|
||||||
#endif // RGBDS_GFX_MAIN_HPP
|
|
||||||
21
include/gfx/makepng.h
Normal file
21
include/gfx/makepng.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of RGBDS.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013-2018, stag019 and RGBDS contributors.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RGBDS_GFX_PNG_H
|
||||||
|
#define RGBDS_GFX_PNG_H
|
||||||
|
|
||||||
|
#include "gfx/main.h"
|
||||||
|
|
||||||
|
struct RawIndexedImage *input_png_file(const struct Options *opts,
|
||||||
|
struct ImageOptions *png_options);
|
||||||
|
void output_png_file(const struct Options *opts,
|
||||||
|
const struct ImageOptions *png_options,
|
||||||
|
const struct RawIndexedImage *raw_image);
|
||||||
|
void destroy_raw_image(struct RawIndexedImage **raw_image_ptr_ptr);
|
||||||
|
|
||||||
|
#endif /* RGBDS_GFX_PNG_H */
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user