mirror of
https://github.com/gbdev/rgbds.git
synced 2026-05-08 10:59:36 +00:00
Move documentation outside of the root directory (#1936)
This commit is contained in:
@@ -0,0 +1,294 @@
|
||||
# RGBDS Architecture
|
||||
|
||||
The RGBDS package consists of four programs: RGBASM, RGBLINK, RGBFIX, and RGBGFX.
|
||||
|
||||
- RGBASM is the assembler. It takes assembly code as input, and produces an RGB object file as output (and optionally a state file, logging the final state of variables and constants).
|
||||
- RGBLINK is the linker. It takes object files as input, and produces a ROM file as output (and optionally a symbol and/or map file, logging where the assembly declarations got placed in the ROM).
|
||||
- RGBFIX is the checksum/header fixer. It takes a ROM file as input, and outputs the same ROM file (or modifies it in-place) with the cartridge header's checksum and other metadata fixed for consistency.
|
||||
- RGBGFX is the graphics converter. It takes a PNG image file as input, and outputs the tile data, palettes, tilemap, attribute map, and/or palette map in formats that the Game Boy can use.
|
||||
|
||||
In the simplest case, a single pipeline can turn an assembly file into a ROM:
|
||||
|
||||
```console
|
||||
(rgbasm -o - - | rgblink -o - - | rgbfix -v -p 0) < game.asm > game.gb
|
||||
```
|
||||
|
||||
This document describes how these four programs are structured. It goes over each source code file, noting which data is *global* (and thus scoped in all files), *owned* by that file (i.e. that is where the data's memory is managed, via [RAII](https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization)) or *referenced* by that file (i.e. there are non-owning pointers to some data, and care must be taken to not dereference those pointers after the data's owner has moved or deleted the data).
|
||||
|
||||
We assume that the programs are single-threaded; data structures and operations may not be thread-safe.
|
||||
|
||||
## Folder Organization
|
||||
|
||||
The RGBDS source code file structure is as follows:
|
||||
|
||||
```
|
||||
rgbds/
|
||||
├── .github/
|
||||
│ ├── scripts/
|
||||
│ │ └── ...
|
||||
│ └── workflows/
|
||||
│ └── ...
|
||||
├── cmake/
|
||||
│ └── ...
|
||||
├── contrib/
|
||||
│ ├── bash_compl/
|
||||
│ ├── zsh_compl/
|
||||
│ │ └── ...
|
||||
│ └── ...
|
||||
├── docs/
|
||||
│ └── ...
|
||||
├── include/
|
||||
│ └── ...
|
||||
├── man/
|
||||
│ └── ...
|
||||
├── src/
|
||||
│ ├── asm/
|
||||
│ │ └── ...
|
||||
│ ├── extern/
|
||||
│ │ └── ...
|
||||
│ ├── fix/
|
||||
│ │ └── ...
|
||||
│ ├── gfx/
|
||||
│ │ └── ...
|
||||
│ ├── link/
|
||||
│ │ └── ...
|
||||
│ ├── CMakeLists.txt
|
||||
│ ├── bison.sh
|
||||
│ └── ...
|
||||
├── test/
|
||||
│ ├── fetch-test-deps.sh
|
||||
│ ├── run-tests.sh
|
||||
│ └── ...
|
||||
├── .clang-format
|
||||
├── .clang-tidy
|
||||
├── CMakeLists.txt
|
||||
├── CMakePresets.json
|
||||
├── compile_flags.txt
|
||||
├── Dockerfile
|
||||
└── Makefile
|
||||
```
|
||||
|
||||
- **`.github/`:**
|
||||
Files related to the integration of the RGBDS codebase with GitHub features.
|
||||
* **`scripts/`:**
|
||||
Scripts used by GitHub Actions workflow files.
|
||||
* **`workflows/`:**
|
||||
GitHub Actions CI workflow description files. Used for automated testing, deployment, etc.
|
||||
- **`cmake/`**:
|
||||
Files relevant to our CMake build system that are not required to be somewhere else (e.g. `CMakePresets.json` *has* to be at the root).
|
||||
- **`contrib/`:**
|
||||
Scripts and other resources which may be useful to RGBDS users and developers.
|
||||
* **`bash_compl/`:**
|
||||
Tab completion scripts for use with `bash`. Run them with `source` somewhere in your `.bashrc`, and they should auto-load when you open a shell.
|
||||
* **`zsh_compl/`:**
|
||||
Tab completion scripts for use with `zsh`. Put them somewhere in your `fpath`, and they should auto-load when you open a shell.
|
||||
- **`docs/`:**
|
||||
Documentation related to the development and maintenance of RGBDS itself.
|
||||
(The directory's name, as well as some of its file's names, are
|
||||
[recognized by GitHub](https://docs.github.com/en/communities/setting-up-your-project-for-healthy-contributions/setting-guidelines-for-repository-contributors)
|
||||
and linked to in parts of its UI.)
|
||||
Documentation for RGBDS itself exists as manual pages in `man/`.
|
||||
- **`include/`:**
|
||||
Header files for the respective source files in `src`.
|
||||
- **`man/`:**
|
||||
Manual pages to be read with `man`, written in the [`mandoc`](https://mandoc.bsd.lv) dialect.
|
||||
- **`src/`:**
|
||||
Source code of RGBDS.
|
||||
* **`asm/`:**
|
||||
Source code of RGBASM.
|
||||
* **`extern/`:**
|
||||
Source code copied from external sources.
|
||||
* **`fix/`:**
|
||||
Source code of RGBFIX.
|
||||
* **`gfx/`:**
|
||||
Source code of RGBGFX.
|
||||
* **`link/`:**
|
||||
Source code of RGBLINK.
|
||||
* **`CMakeLists.txt`:**
|
||||
Defines how to build individual RGBDS programs with CMake, including the source files that each program depends on.
|
||||
* **`bison.sh`:**
|
||||
Script used to run the Bison parser generator with the latest flags that the user's version supports.
|
||||
- **`test/`:**
|
||||
Testing framework used to verify that changes to the code don't break or modify the behavior of RGBDS.
|
||||
* **`fetch-test-deps.sh`:**
|
||||
Script used to fetch dependencies for building external repositories. `fetch-test-deps.sh --help` describes its options.
|
||||
* **`run-tests.sh`:**
|
||||
Script used to run tests, including internal test cases and external repositories. `run-tests.sh --help` describes its options.
|
||||
- **`.clang-format`:**
|
||||
Code style for automated C++ formatting with [`clang-format`](https://clang.llvm.org/docs/ClangFormat.html) (for which we define the shortcut `make format`).
|
||||
- **`.clang-tidy`:**
|
||||
Configuration for C++ static analysis with [`clang-tidy`](https://clang.llvm.org/extra/clang-tidy/) (for which we define the shortcut `make tidy`).
|
||||
- **`CMakeLists.txt`:**
|
||||
Defines how to build RGBDS with CMake.
|
||||
- **`CMakePresets.json`:**
|
||||
Defines some [presets](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html) useful for working with our CMake.
|
||||
- **`compile_flags.txt`:**
|
||||
Compiler flags for `clang-tidy`.
|
||||
- **`Dockerfile`:**
|
||||
Defines how to build RGBDS with Docker (which we do in CI to provide a [container image](https://github.com/gbdev/rgbds/pkgs/container/rgbds)).
|
||||
- **`Makefile`:**
|
||||
Defines how to build RGBDS with `make`, including the source files that each program depends on.
|
||||
|
||||
## RGBDS
|
||||
|
||||
These files in the `src/` directory are shared across multiple programs: often all four (RGBASM, RGBLINK, RGBFIX, and RGBGFX), sometimes only RGBASM and RGBLINK.
|
||||
|
||||
- **`backtrace.cpp`:**
|
||||
Generic printing of location backtraces for RGBASM and RGBLINK. Allows configuring backtrace styles with a command-line flag (conventionally `-B/--backtrace`). Renders warnings in yellow, errors in red, and locations in cyan.
|
||||
- **`cli.cpp`:**
|
||||
A function for parsing command-line options, including RGBDS-specific "at-files" (a filename containing more options, prepended with an "`@`").
|
||||
This is the only file to use the extern/getopt.cpp variables and functions.
|
||||
- **`diagnostics.cpp`:**
|
||||
Generic warning/error diagnostic support for all programs. Allows command-line flags (conventionally `-W`) to have `no-`, `error=`, or `no-error=` prefixes, and `=` level suffixes; allows "meta" flags to affect groups of individual flags; and counts how many total errors there have been. Every program has its own `warning.cpp` file that uses this.
|
||||
- **`linkdefs.cpp`:**
|
||||
Constants, data, and functions related to RGBDS object files, which are used for RGBASM output and RGBLINK input.
|
||||
This file defines two *global* variables, `sectionTypeInfo` (metadata about each section type) and `sectionModNames` (names of section modifiers, for error reporting). RGBLINK may change some values in `sectionTypeInfo` depending on its command-line options (this only affects RGBLINK; `sectionTypeInfo` is immutable in RGBASM).
|
||||
- **`opmath.cpp`:**
|
||||
Functions for mathematical operations in RGBASM and RGBLINK that aren't trivially equivalent to built-in C++ ones, such as division and modulo with well-defined results for negative values.
|
||||
- **`style.cpp`:**
|
||||
Generic printing of cross-platform colored or bold text. Obeys the [`FORCE_COLOR`](https://force-color.org/) and [`NO_COLOR`](https://no-color.org/) environment variables, and allows configuring with a command-line flag (conventionally `--color`).
|
||||
- **`usage.cpp`:**
|
||||
Generic printing of usage information. Renders headings in green, flags in cyan, and URLs in blue. Every program has its own `main.cpp` file that uses this.
|
||||
- **`util.cpp`:**
|
||||
Utility functions applicable to most programs, mostly dealing with text strings, such as locale-independent character checks.
|
||||
- **`verbosity.cpp`:**
|
||||
Generic printing of messages conditionally at different verbosity levels. Allows configuring with a command-line flag (conventionally `-v/--verbose`).
|
||||
- **`version.cpp`:**
|
||||
RGBDS version number and string for all the programs.
|
||||
|
||||
## External
|
||||
|
||||
These files have been copied ("vendored") from external authors and adapted for use with RGBDS. Both of our vendored dependencies use the same MIT license as RGBDS.
|
||||
|
||||
- **`getopt.cpp`:**
|
||||
Functions for parsing command-line options, including conventional single-dash and double-dash options.
|
||||
This file defines some *global* `musl_opt*` variables, including `musl_optarg` (the argument given after an option flag) and `musl_optind` (the index of the next option in `argv`). Copied from [musl libc](https://musl.libc.org/).
|
||||
- **`utf8decoder.cpp`:**
|
||||
Function for decoding UTF-8 bytes into Unicode code points. Copied from [Björn Höhrmann](https://bjoern.hoehrmann.de/utf-8/decoder/dfa/).
|
||||
|
||||
## RGBASM
|
||||
|
||||
- **`actions.cpp`:**
|
||||
Actions taken by the assembly language parser, to avoid large amounts of code going in the parser.y file.
|
||||
- **`charmap.cpp`:**
|
||||
Functions and data related to charmaps.
|
||||
This file *owns* the `Charmap`s in its `charmaps` collection. It also maintains a static `currentCharmap` pointer, and a `charmapStack` stack of pointers to `Charmap`s within `charmaps` (which is affected by `PUSHC` and `POPC` directives).
|
||||
- **`fixpoint.cpp`:**
|
||||
Functions for fixed-point math, with configurable [Q*m*.*n*](https://en.wikipedia.org/wiki/Q_(number_format)) precision.
|
||||
- **`format.cpp`:**
|
||||
`FormatSpec` methods for parsing and applying format specs, as used by `{interpolations}` and `STRFMT`.
|
||||
- **`fstack.cpp`:**
|
||||
Functions and data related to "fstack" nodes (the contents of top-level or `INCLUDE`d files, macro expansions, or `REPT`/`FOR` loop iterations) and their "contexts" (metadata that is only relevant while a node's content is being lexed and parsed).
|
||||
This file *owns* the `Context`s in its `contextStack` collection. Each of those `Context`s *owns* its `LexerState`, and *refers* to its `FileStackNode`, `uniqueIDStr`, and `macroArgs`. Each `FileStackNode` also *references* its `parent`.
|
||||
- **`lexer.cpp`:**
|
||||
Functions and data related to [lexing](https://en.wikipedia.org/wiki/Lexical_analysis) assembly source code into tokens, which can then be parsed.
|
||||
This file maintains static `lexerState` and `lexerStateEOL` pointers to `LexerState`s from the `Context`s in `fstack.cpp`.
|
||||
Each `LexerState` *owns* its `content` and its `expansions`' content. Each `Expansion` (the contents of an `{interpolation}` or macro argument) in turn *owns* its `contents`.
|
||||
The lexer and parser are interdependent: when the parser reaches certain tokens, it changes the lexer's mode, which affects how characters get lexed into tokens. For example, when the parser reaches a macro name, it changes the lexer to "raw" mode, which lexes the rest of the line as a sequence of string arguments to the macro.
|
||||
- **`macro.cpp`:**
|
||||
`MacroArgs` methods related to macro arguments. Each `MacroArgs` *references* its arguments' contents.
|
||||
- **`main.cpp`:**
|
||||
The `main` function for running RGBASM, including the initial handling of command-line options.
|
||||
This file defines a *global* `options` variable with the parsed CLI options.
|
||||
- **`opt.cpp`:**
|
||||
Functions for parsing options specified by `OPT` or by certain command-line options.
|
||||
This file *owns* the `OptStackEntry`s in its `stack` collection (which is affected by `PUSHO` and `POPO` directives).
|
||||
- **`output.cpp`:**
|
||||
Functions and data related to outputting object files (with `-o/--output`) and state files (with `-s/--state`).
|
||||
This file *owns* its `assertions` (created by `ASSERT` and `STATIC_ASSERT` directives). Every assertion gets output in the object file.
|
||||
This file also *references* some `fileStackNodes`, and maintains static pointers to `Symbol`s in `objectSymbols`. Only the "registered" symbols and fstack nodes get output in the object file. The `fileStackNodes` and `objectSymbols` collections keep track of which nodes and symbols have been registered for output.
|
||||
- **`parser.y`:**
|
||||
Grammar for the RGBASM assembly language, which Bison preprocesses into a [LALR(1) parser](https://en.wikipedia.org/wiki/LALR_parser).
|
||||
The Bison-generated parser calls `yylex` (defined in `lexer.cpp`) to get the next token, and calls `yywrap` (defined in `fstack.cpp`) when the current context is out of tokens and returns `EOF`.
|
||||
- **`rpn.cpp`:**
|
||||
`Expression` methods and data related to "[RPN](https://en.wikipedia.org/wiki/Reverse_Polish_notation)" expressions. When a numeric expression is parsed, if its value cannot be calculated at assembly time, it is built up into a buffer of RPN-encoded operations to do so at link time by RGBLINK. The valid RPN operations are defined in [man/rgbds.5](man/rgbds.5).
|
||||
- **`section.cpp`:**
|
||||
Functions and data related to `SECTION`s.
|
||||
This file *owns* the `Section`s in its `sections` collection. It also maintains various static pointers to those sections, including the `currentSection`, `currentLoadSection`, and `sectionStack` (which is affected by `PUSHS` and `POPS` directives). (Note that sections cannot be deleted.)
|
||||
- **`symbol.cpp`:**
|
||||
Functions and data related to symbols (labels, constants, variables, string constants, macros, etc).
|
||||
This file *owns* the `Symbol`s in its `symbols` collection, and the various built-in ones outside that collection (`PCSymbol` for "`@`", `NARGSymbol` for "`_NARG`", etc). It also maintains a static `purgedSymbols` collection to remember which symbol names have been `PURGE`d from `symbols`, for error reporting purposes.
|
||||
- **`warning.cpp`:**
|
||||
Functions and data for warning and error output.
|
||||
This file defines a *global* `warnings` variable using the `diagnostics.cpp` code for RGBASM-specific warning flags.
|
||||
|
||||
## RGBFIX
|
||||
|
||||
- **`fix.cpp`:**
|
||||
Functions for fixing the ROM header.
|
||||
- **`main.cpp`:**
|
||||
The `main` function for running RGBFIX, including the initial handling of command-line options.
|
||||
This file defines a *global* `options` variable with the parsed CLI options.
|
||||
- **`mbc.cpp`:**
|
||||
Functions and data related to [MBCs](https://gbdev.io/pandocs/MBCs.html), including the names of known MBC values.
|
||||
- **`warning.cpp`:**
|
||||
Functions and data for warning and error output.
|
||||
This file defines a *global* `warnings` variable using the `diagnostics.cpp` code for RGBFIX-specific warning flags.
|
||||
|
||||
## RGBGFX
|
||||
|
||||
- **`color_set.cpp`:**
|
||||
`ColorSet` methods for creating and comparing sets of colors. A color set includes the unique colors used by a single tile, and these sets are then packed into palettes.
|
||||
- **`main.cpp`:**
|
||||
The `main` function for running RGBGFX, including the initial handling of command-line options.
|
||||
This file defines a *global* `options` variable with the parsed CLI options.
|
||||
- **`pal_packing.cpp`:**
|
||||
Functions for packing color sets into palettes. This is done with an ["overload-and-remove" heuristic](https://arxiv.org/abs/1605.00558) for a pagination algorithm.
|
||||
- **`pal_sorting.cpp`:**
|
||||
Functions for sorting colors within palettes, which works differently for grayscale, RGB, or indexed-color palettes.
|
||||
- **`pal_spec.cpp`:**
|
||||
Functions for parsing various formats of palette specifications (from `-c/--colors`).
|
||||
- **`palette.cpp`:**
|
||||
`Palette` methods for working with up to four GBC-native (RGB555) colors.
|
||||
- **`png.cpp`:**
|
||||
`Png` methods for reading PNG image files, standardizing them to 8-bit RGBA pixels while also reading their indexed palette if there is one.
|
||||
- **`process.cpp`:**
|
||||
Functions related to generating and outputting files (tile data, palettes, tilemap, attribute map, and/or palette map).
|
||||
- **`reverse.cpp`:**
|
||||
Functions related to reverse-generating RGBGFX outputs into a PNG file (for `-r/--reverse`).
|
||||
- **`rgba.cpp`:**
|
||||
`Rgba` methods related to RGBA colors and their 8-bit or 5-bit representations.
|
||||
- **`warning.cpp`:**
|
||||
Functions and data for warning and error output.
|
||||
This file defines a *global* `warnings` variable using the `diagnostics.cpp` code for RGBGFX-specific warning flags.
|
||||
|
||||
## RGBLINK
|
||||
|
||||
- **`assign.cpp`:**
|
||||
Functions and data for assigning `SECTION`s to specific banks and addresses.
|
||||
This file *owns* the `memory` table of free space: each section type is associated with a list of each bank's free address ranges, which are allocated to sections using a [first-fit decreasing](https://en.wikipedia.org/wiki/Bin_packing_problem#First-fit_algorithm) bin-packing algorithm.
|
||||
- **`fstack.cpp`:**
|
||||
Functions related to "fstack" nodes (the contents of top-level or `INCLUDE`d files, macro expansions, or `REPT`/`FOR` loop iterations) read from the object files. At link time, these nodes are only needed for printing of location backtraces.
|
||||
- **`layout.cpp`:**
|
||||
Actions taken by the linker script parser, to avoid large amounts of code going in the script.y file.
|
||||
This file maintains some static data about the current bank and address layout, which get checked and updated for consistency as the linker script is parsed.
|
||||
- **`lexer.cpp`:**
|
||||
Functions and data related to [lexing](https://en.wikipedia.org/wiki/Lexical_analysis) linker script files into tokens, which can then be parsed.
|
||||
This file *owns* the `LexerStackEntry`s in its `lexerStack` collection. Each of those `LexerStackEntry`s *owns* its `file`. The stack is updated as linker scripts can `INCLUDE` other linker script pieces.
|
||||
The linker script lexer is simpler than the RGBASM one, and does not have modes.
|
||||
- **`main.cpp`:**
|
||||
The `main` function for running RGBLINK, including the initial handling of command-line options.
|
||||
This file defines a *global* `options` variable with the parsed CLI options.
|
||||
- **`object.cpp`:**
|
||||
Functions and data for reading object files generated by RGBASM.
|
||||
This file *owns* the `Symbol`s in its `symbolLists` collection, and the `FileStackNode`s in its `nodes` collection.
|
||||
- **`output.cpp`:**
|
||||
Functions and data related to outputting ROM files (with `-o/--output`), symbol files (with `-n/--sym`), and map files (with `-m/--map`).
|
||||
This file *references* some `Symbol`s and `Section`s, in collections that keep them sorted by address and name, which allows the symbol and map output to be in order.
|
||||
- **`patch.cpp`:**
|
||||
Functions and data related to "[RPN](https://en.wikipedia.org/wiki/Reverse_Polish_notation)" expression patches read from the object files, including the ones for `ASSERT` conditions. After sections have been assigned specific locations, the RPN patches can have their values calculated and applied to the ROM. The valid RPN operations are defined in [man/rgbds.5](man/rgbds.5).
|
||||
This file *owns* the `Assertion`s in its `assertions` collection, and the `RPNStackEntry`s in its `rpnStack` collection.
|
||||
- **`script.y`:**
|
||||
Grammar for the linker script language, which Bison preprocesses into a [LALR(1) parser](https://en.wikipedia.org/wiki/LALR_parser).
|
||||
The Bison-generated parser calls `yylex` (defined in `lexer.cpp`) to get the next token, and calls `yywrap` (also defined in `lexer.cpp`) when the current context is out of tokens and returns `EOF`.
|
||||
- **`sdas_obj.cpp`:**
|
||||
Functions and data for reading object files generated by [GBDK with SDCC](https://gbdk.org/). RGBLINK support for these object files is incomplete.
|
||||
- **`section.cpp`:**
|
||||
Functions and data related to `SECTION`s read from the object files.
|
||||
This file *owns* the `Section`s in its `sections` collection.
|
||||
- **`symbol.cpp`:**
|
||||
Functions and data related to symbols read from the object files.
|
||||
This file *references* the `Symbol`s in its `symbols` and `localSymbols` collections, which allow accessing symbols by name.
|
||||
- **`warning.cpp`:**
|
||||
Functions and data for warning and error output.
|
||||
This file defines a *global* `warnings` variable using the `diagnostics.cpp` code for RGBLINK-specific warning flags.
|
||||
@@ -0,0 +1,263 @@
|
||||
# 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
|
||||
|
||||
Thank you! Code contributions are the most appreciated.
|
||||
You can find a description of the project's layout in [`ARCHITECTURE.md`](ARCHITECTURE.md).
|
||||
|
||||
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). You can also use `cmake --preset develop` if you prefer.
|
||||
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.)
|
||||
6. Format your changes according to `clang-format`, which will reformat the
|
||||
coding style according to our standards defined in `.clang-format`.
|
||||
7. Create a pull request against the branch `master`.
|
||||
8. Check the results of the GitHub Actions CI jobs for your pull request. The
|
||||
"Code format checking" and "Regression testing" jobs should all succeed.
|
||||
The "Diff completeness check" and "Static analysis" jobs should be manually
|
||||
checked, as they may output warnings which do not count as failure errors.
|
||||
The "Code coverage report" provides an
|
||||
[LCOV](https://github.com/linux-test-project/lcov)-generated report which
|
||||
can be downloaded and checked to see if your new code has full test coverage.
|
||||
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.
|
||||
|
||||
## Adding a test
|
||||
|
||||
The test suite is a little ad-hoc, so the way tests work is different for each
|
||||
program being tested.
|
||||
|
||||
Feel free to modify how the test scripts work, if the thing you want to test
|
||||
doesn't fit the existing scheme(s).
|
||||
|
||||
### RGBASM
|
||||
|
||||
There are two kinds of test.
|
||||
|
||||
#### Simple tests
|
||||
|
||||
Each `.asm` file corresponds to one test.
|
||||
RGBASM will be invoked on the `.asm` file with all warnings enabled.
|
||||
|
||||
If a `.flags` file exists, its first line contains flags to pass to RGBASM.
|
||||
(There may be more lines, which will be ignored; they can serve as comments to
|
||||
explain what the test is about.)
|
||||
|
||||
If a `.out` file exists, RGBASM's output (`print`, `println`, etc.) must match
|
||||
its contents.
|
||||
If a `.err` file exists, RGBASM's error output (`warn`, errors, etc.) must match
|
||||
its contents.
|
||||
|
||||
If a `.out.bin` file exists, the object file will be linked, and the generated
|
||||
ROM truncated to the length of the `.out.bin` file.
|
||||
After that, the ROM must match the `.out.bin` file.
|
||||
|
||||
#### CLI tests
|
||||
|
||||
Each `.flags` file in `cli/` corresponds to one test.
|
||||
RGBASM will be invoked, passing it the first line of the `.flags` file.
|
||||
(There may be more lines, which will be ignored; they can serve as comments to
|
||||
explain what the test is about.)
|
||||
|
||||
If a `.out` file exists, RGBASM's output (`print`, `println`, etc.) must match
|
||||
its contents.
|
||||
If a `.err` file exists, RGBASM's error output (`warn`, errors, etc.) must match
|
||||
its contents.
|
||||
|
||||
### RGBLINK
|
||||
|
||||
Each `.asm` file corresponds to one test, or one *set* of tests.
|
||||
|
||||
All tests begin by assembling the `.asm` file into an object file, which will be
|
||||
linked in various ways depending on the test.
|
||||
|
||||
#### Simple tests
|
||||
|
||||
These simply check that RGBLINK's output matches some expected output.
|
||||
|
||||
A `.out` file **must** exist, and RGBLINK's total output must match that file's
|
||||
contents.
|
||||
|
||||
Additionally, if a `.out.bin` file exists, the `.gb` file generated by RGBLINK
|
||||
must match it.
|
||||
|
||||
#### Linker script tests
|
||||
|
||||
These allow applying various linker scripts to the same object file.
|
||||
If one or more `.link` files exist, whose names start the same as the `.asm`
|
||||
file, then each of those files correspond to one test.
|
||||
|
||||
Each `.link` linker script **must** be accompanied by a `.out` file, and
|
||||
RGBLINK's total output must match that file's contents when passed the
|
||||
corresponding linker script.
|
||||
|
||||
#### Variant tests
|
||||
|
||||
These allow testing RGBLINK's `-d`, `-t`, and `-w` flags.
|
||||
If one or more
|
||||
<code>-<var><flag></var>.out</code> or <code>-no-<var><flag></var>.out</code>
|
||||
files exist, then each of them corresponds to one test.
|
||||
|
||||
The object file will be linked with and without said flag, respectively; and in
|
||||
each case, RGBLINK's total output must match the `.out` file's contents.
|
||||
|
||||
### RGBFIX
|
||||
|
||||
Each `.flags` file corresponds to one test.
|
||||
Each one is a text file whose first line contains flags to pass to RGBFIX.
|
||||
(There may be more lines, which will be ignored; they can serve as comments to
|
||||
explain what the test is about.)
|
||||
|
||||
RGBFIX will be invoked on the `.bin` file if it exists, or else on
|
||||
default-input.bin.
|
||||
|
||||
If no `.out` file exist, RGBFIX is not expected to output anything.
|
||||
If one *does* exist, RGBFIX's output **must** match the `.out` file's contents.
|
||||
|
||||
If no `.err` file exists, RGBFIX is simply expected to be able to process the
|
||||
file normally.
|
||||
If one *does* exist, RGBFIX's return status is ignored, but its error output
|
||||
**must** match the `.err` file's contents.
|
||||
|
||||
Additionally, if a `.gb` file exists, the output of RGBFIX must match the `.gb`.
|
||||
|
||||
### RGBGFX
|
||||
|
||||
There are three kinds of test.
|
||||
|
||||
#### Simple tests
|
||||
|
||||
Each `.png` file corresponds to one test.
|
||||
RGBGFX will be invoked on the file.
|
||||
If a `.flags` file exists, it will be used as part of the RGBGFX invocation
|
||||
(<code>@<var><file></var>.flags</code>).
|
||||
|
||||
If `.out.1bpp`, `.out.2bpp`, `.out.pal`, `.out.tilemap`, `.out.attrmap`, or
|
||||
`.out.palmap` files exist, RGBGFX will create the corresponding kind of output,
|
||||
which must match the file's contents.
|
||||
Multiple kinds of output may be tested for the same input.
|
||||
|
||||
If no `.err` file exists, RGBGFX is simply expected to be able to process the
|
||||
file normally.
|
||||
If one *does* exist, RGBGFX's return status is ignored, but its output **must**
|
||||
match the `.err` file's contents.
|
||||
|
||||
#### Reverse tests
|
||||
|
||||
Each `.1bpp` or `.2bpp` file corresponds to one test.
|
||||
RGBGFX will be invoked on the file with `-r 1` for reverse mode, then invoked on
|
||||
the output without `-r 1`.
|
||||
The round-trip output must match the input file's contents.
|
||||
If a `.flags` file exists, it will be used as part of the RGBGFX invocation
|
||||
(<code>@<var><file></var>.flags</code>).
|
||||
|
||||
#### Random seed tests
|
||||
|
||||
Each `seed*.bin` file corresponds to one test.
|
||||
Each one is a binary RNG file which is passed to the `rgbgfx_test` program.
|
||||
|
||||
### Downstream projects
|
||||
|
||||
1. Make sure the downstream project supports
|
||||
<code>make <var><target></var> RGBDS=<var><path/to/RGBDS/></var></code>.
|
||||
While the test suite supports any Make target name, only
|
||||
[Make](//gnu.org/software/make) is currently supported, and the Makefile must
|
||||
support a `RGBDS` variable to use a non-system RGBDS directory.
|
||||
2. Add the project to `test/fetch-test-deps.sh`: add a new `action` line at the
|
||||
bottom, following the existing pattern:
|
||||
|
||||
```sh
|
||||
action <domain> <owner> <repo> <hash of last commit>
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
## Publishing a new release
|
||||
|
||||
Please refer to [`RELEASE.md`](RELEASE.md).
|
||||
|
||||
## Closing remarks
|
||||
|
||||
Feel free to add yourself to `CREDITS.md`!
|
||||
@@ -0,0 +1,48 @@
|
||||
# Contributors to RGBDS
|
||||
|
||||
## Original author
|
||||
|
||||
- Carsten Elton Sørensen <csoren@gmail.com>
|
||||
|
||||
## Main contributors
|
||||
|
||||
- Justin Lloyd <jlloyd@imf.la>
|
||||
- Vegard Nossum <vegard.nossum@gmail.com>
|
||||
- Anthony J. Bentley <anthony@anjbe.name>
|
||||
- stag019 <stag019@gmail.com>
|
||||
- Antonio Niño Díaz <antonio_nd@outlook.com>
|
||||
- Eldred "ISSOtm" Habert <me@eldred.fr>
|
||||
- Sylvie "Rangi" Oukaour <https://github.com/Rangi42>
|
||||
|
||||
## Other contributors
|
||||
|
||||
- Ben Hetherington <dev@ben-h.uk>
|
||||
- Björn Höhrmann <bjoern@hoehrmann.de>
|
||||
- Christophe Staïesse <chastai@skynet.be>
|
||||
- David Brotz <dbrotz007@gmail.com>
|
||||
- Evie <https://evie.gbdev.io>
|
||||
- James "JL2210" Larrowe <https://github.com/JL2210>
|
||||
- Maja Kądziołka <github@compilercrim.es>
|
||||
- The Musl C library <https://musl.libc.org/>
|
||||
- obskyr <powpowd@gmail.com>
|
||||
- The OpenBSD Project <http://www.openbsd.org>
|
||||
- Quint Guvernator <quint@guvernator.net>
|
||||
- Sanqui <gsanky@gmail.com>
|
||||
- YamaArashi <shadow962@live.com>
|
||||
- yenatch <yenatch@gmail.com>
|
||||
- phs <phil@philhsmith.com>
|
||||
- jidoc01 <jidoc01@naver.com>
|
||||
|
||||
[<img src="https://contrib.rocks/image?repo=gbdev/rgbds">](https://github.com/gbdev/rgbds/graphs/contributors)
|
||||
|
||||
Contributor image made with [contrib.rocks](https://contrib.rocks).
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
RGBGFX generates palettes using algorithms found in the paper
|
||||
["Algorithms for the Pagination Problem, a Bin Packing with Overlapping Items"](https://arxiv.org/abs/1605.00558)
|
||||
([GitHub](https://github.com/pagination-problem/pagination), MIT license),
|
||||
by Aristide Grange, Imed Kacem, and Sébastien Martin.
|
||||
|
||||
RGBGFX's color palette was taken from [SameBoy](https://sameboy.github.io), with
|
||||
permission and help by [LIJI](https://github.com/LIJI32).
|
||||
@@ -0,0 +1,83 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user