mirror of
https://github.com/mamedev/mame.git
synced 2024-11-16 07:48:32 +01:00
docs: Added preliminary guide for would-be contributors. (#10717) [Ryan Holtz, Vas Crabb, O. Galibert]
This commit is contained in:
parent
0619912fb0
commit
e85a2899c5
10 changed files with 862 additions and 76 deletions
4
CONTRIBUTING.md
Normal file
4
CONTRIBUTING.md
Normal file
|
@ -0,0 +1,4 @@
|
|||
Contributing to MAME
|
||||
====================
|
||||
|
||||
Please see the guidelines for [Contributing to MAME](https://docs.mamedev.org/contributing/) on our documentation web site.
|
|
@ -69,9 +69,9 @@ make vs2019 MSBUILD=1
|
|||
Where can I find out more?
|
||||
=============
|
||||
|
||||
* [Official MAME Development Team Site](http://mamedev.org/) (includes binary downloads, wiki, forums, and more)
|
||||
* [Official MAME Development Team Site](https://mamedev.org/) (includes binary downloads, wiki, forums, and more)
|
||||
* [Official MESS Wiki](http://mess.redump.net/)
|
||||
* [MAME Testers](http://mametesters.org/) (official bug tracker for MAME and MESS)
|
||||
* [MAME Testers](https://mametesters.org/) (official bug tracker for MAME and MESS)
|
||||
|
||||
|
||||
Contributing
|
||||
|
@ -85,8 +85,12 @@ Some parts of the code follow [Allman style](https://en.wikipedia.org/wiki/Inden
|
|||
|
||||
All contributors need to either add a standard header for license info (on new files) or inform us of their wishes regarding which of the following licenses they would like their code to be made available under: the [BSD-3-Clause](http://opensource.org/licenses/BSD-3-Clause) license, the [LGPL-2.1](http://opensource.org/licenses/LGPL-2.1), or the [GPL-2.0](http://opensource.org/licenses/GPL-2.0).
|
||||
|
||||
See more specific [C++ Coding Guidelines](https://docs.mamedev.org/contributing/cxx.html) on our documentation web site.
|
||||
|
||||
|
||||
License
|
||||
=======
|
||||
|
||||
The MAME project as a whole is made available under the terms of the
|
||||
[GNU General Public License, version 2](http://opensource.org/licenses/GPL-2.0)
|
||||
or later (GPL-2.0+), since it contains code made available under multiple
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
|
510
docs/source/contributing/cxx.rst
Normal file
510
docs/source/contributing/cxx.rst
Normal file
|
@ -0,0 +1,510 @@
|
|||
.. _contributing-cxx:
|
||||
|
||||
C++ Coding Guidelines
|
||||
=====================
|
||||
|
||||
.. contents:: :local:
|
||||
|
||||
|
||||
.. _contributing-cxx-intro:
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
**In terms of coding conventions, the style present within an existing
|
||||
source file should be favoured over the standards found below.**
|
||||
|
||||
When a new source file is being created, the following coding
|
||||
conventions should be observed if creating a new file within the MAME
|
||||
core (``src/emu`` and ``src/lib``). If the source file is outside the
|
||||
core, deference can be given to a contributor’s preferred style,
|
||||
although it is strongly encouraged to code with the understanding that
|
||||
the file may need to be comprehensible by more than one person as time
|
||||
marches forward.
|
||||
|
||||
|
||||
.. _contributing-cxx-definitions:
|
||||
|
||||
Definitions
|
||||
-----------
|
||||
|
||||
Snake case
|
||||
All lowercase letters with words separated by underscores:
|
||||
``this_is_snake_case``
|
||||
Screaming snake case
|
||||
All uppercase letters with words separated by underscores:
|
||||
``SCREAMING_SNAKE_CASE``
|
||||
Camel case:
|
||||
Lowercase initial letter, first letter of each subsequent word
|
||||
capitalised, with no separators between words: ``exampleCamelCase``
|
||||
Llama case:
|
||||
Uppercase initial letter, first letter of each subsequent word
|
||||
capitalised, with no separators between words: ``LlamaCaseSample``
|
||||
|
||||
|
||||
.. _contributing-cxx-naming:
|
||||
|
||||
Naming conventions
|
||||
------------------
|
||||
|
||||
Preprocessor macros
|
||||
Macro names should use screaming snake case. Macros are always
|
||||
global and name conflicts can cause confusing errors – think
|
||||
carefully about what macros really need to be in headers and name
|
||||
them carefully.
|
||||
Include guards
|
||||
Include guard macros should begin with ``MAME_``, and end with a
|
||||
capitalised version of the file name, with separators replaced by
|
||||
underscores.
|
||||
Constants
|
||||
Constants should use screaming snake case, whether they are constant
|
||||
globals, constant data members, enumerators or preprocessor
|
||||
constants.
|
||||
Functions
|
||||
Free functions names should use snake case. (There are some utility
|
||||
function that were previously implemented as preprocessor macros
|
||||
that still use screaming snake case.)
|
||||
Classes
|
||||
Class names should use snake case. Abstract class names should end
|
||||
in ``_base``. Public member functions (including static member
|
||||
functions) should use snake case.
|
||||
Device classes
|
||||
Concrete driver ``driver_device`` implementation names
|
||||
conventionally end in ``_state``, while other concrete device class
|
||||
names end in ``_device``. Concrete ``device_interface`` names
|
||||
conventionally begin with ``device_`` and end with ``_interface``.
|
||||
Device types
|
||||
Device types should use screaming snake case. Remember that device
|
||||
types are names in the global namespace, so choose explicit,
|
||||
unambiguous names.
|
||||
Enumerations
|
||||
The enumeration name should use snake case. The enumerators should
|
||||
use screaming snake case.
|
||||
Template parameters
|
||||
Template parameters should use llama case (both type and value
|
||||
parameters).
|
||||
|
||||
|
||||
.. _contributing-cxx-literals:
|
||||
|
||||
Variables and literals
|
||||
----------------------
|
||||
|
||||
Octal literals are discouraged from use outside of specific cases. They
|
||||
lack the obvious letter-based prefixes found in hexadecimal and binary
|
||||
literals, and therefore can be difficult to distinguish at a glance from
|
||||
a decimal literal to coders who are unfamiliar with octal notation.
|
||||
|
||||
Lower-case hexadecimal literals are preferred, e.g. ``0xbadc0de`` rather
|
||||
than ``0xBADC0DE``. For clarity, try not to exceed the bit width of the
|
||||
variable which will be used to store it.
|
||||
|
||||
Binary literals have rarely been used in the MAME source code due to the
|
||||
``0b`` prefix not being standardised until C++14, but there is no policy
|
||||
to avoid their use.
|
||||
|
||||
Integer suffix notation should be used when specifying 64-bit literals,
|
||||
but is not strictly required in other cases. It can, however, clarify
|
||||
the intended use of a given literal at a glance. Uppercase long integer
|
||||
literal suffixes should be used to avoid confusion with the digit 1,
|
||||
e.g. ``7LL`` rather than ``7ll``.
|
||||
|
||||
Types that do not have a specifically defined size should be avoided if
|
||||
they are to be registered with MAME’s save-state system, as it harms
|
||||
portability. In general, this means avoiding the use of ``int`` for
|
||||
these members.
|
||||
|
||||
It's encouraged, but not required, for class data members to be prefixed
|
||||
with ``m_`` for non-static instance members and ``s_`` for static
|
||||
members. This does not apply to nested classes or structs.
|
||||
|
||||
|
||||
.. _contributing-cxx-braceindent:
|
||||
|
||||
Bracing and indentation
|
||||
-----------------------
|
||||
|
||||
Tabs are used for initial indentation of lines, with one tab used per
|
||||
nested scope level. Statements split across multiple lines should be
|
||||
indented by two tabs. Spaces are used for alignment at other places
|
||||
within a line.
|
||||
|
||||
Either K&R or Allman-style bracing is preferred. There is no specific
|
||||
preference for bracing on single-line statements, although bracing
|
||||
should be consistent for a given ``if/else`` block, as shown:
|
||||
|
||||
.. code-block:: C++
|
||||
|
||||
if (x == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
call_some_function();
|
||||
x--;
|
||||
}
|
||||
|
||||
When using a series of ``if``/``else`` or ``if``/``else if``/``else``
|
||||
blocks with comments at the top indentation level, avoid extraneous
|
||||
newlines. The use of additional newlines may lead to ``else if`` or
|
||||
``else`` blocks being missed due to the newlines pushing the blocks
|
||||
outside the visible editor height:
|
||||
|
||||
.. code-block:: C++
|
||||
|
||||
// Early-out if our hypothetical counter has run out.
|
||||
if (x == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// We should do something if the counter is running.
|
||||
else
|
||||
{
|
||||
call_some_function();
|
||||
x--;
|
||||
}
|
||||
|
||||
Indentation for ``case`` statements inside a ``switch`` body can either
|
||||
be on the same level as the ``switch`` statement or inward by one level.
|
||||
There is no specific style which is used across all core files, although
|
||||
indenting by one level appears to be used most often.
|
||||
|
||||
|
||||
.. _contributing-cxx-spacing:
|
||||
|
||||
Spacing
|
||||
-------
|
||||
|
||||
Consistent single-spacing between binary operators, variables, and
|
||||
literals is strongly preferred. The following examples exhibit
|
||||
reasonably consistent spacing:
|
||||
|
||||
.. code-block:: C++
|
||||
|
||||
uint8_t foo = (((bar + baz) + 3) & 7) << 1;
|
||||
uint8_t foo = ((bar << 1) + baz) & 0x0e;
|
||||
uint8_t foo = bar ? baz : 5;
|
||||
|
||||
The following examples exhibit extremes in either direction, although
|
||||
having extra spaces is less difficult to read than having too few:
|
||||
|
||||
.. code-block:: C++
|
||||
|
||||
uint8_t foo = ( ( ( bar + baz ) + 3 ) & 7 ) << 1;
|
||||
uint8_t foo = ((bar<<1)+baz)&0x0e;
|
||||
uint8_t foo = (bar?baz:5);
|
||||
|
||||
A space should be used between a fundamental C++ statement and its
|
||||
opening parenthesis, e.g.:
|
||||
|
||||
.. code-block:: C++
|
||||
|
||||
switch (value) ...
|
||||
if (a != b) ...
|
||||
for (int i = 0; i < foo; i++) ...
|
||||
|
||||
|
||||
.. _contributing-cxx-scoping:
|
||||
|
||||
Scoping
|
||||
-------
|
||||
|
||||
Variables should be scoped as narrowly as is reasonably possible. There
|
||||
are many instances of C89-style local variable declaration in the MAME
|
||||
codebase, but this is largely a hold-over from MAME’s early days, which
|
||||
pre-date the C99 specification.
|
||||
|
||||
The following two snippets exhibit the legacy style of local variable
|
||||
declaration, followed by the more modern and preferred style:
|
||||
|
||||
.. code-block:: C++
|
||||
|
||||
void example_device::some_function()
|
||||
{
|
||||
int i;
|
||||
uint8_t data;
|
||||
|
||||
for (i = 0; i < std::size(m_buffer); i++)
|
||||
{
|
||||
data = m_buffer[i];
|
||||
if (data)
|
||||
{
|
||||
some_other_function(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.. code-block:: C++
|
||||
|
||||
void example_device::some_function()
|
||||
{
|
||||
for (int i = 0; i < std::size(m_buffer); i++)
|
||||
{
|
||||
const uint8_t data = m_buffer[i];
|
||||
if (data)
|
||||
{
|
||||
some_other_function(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Enumerated values, structs, and classes used only by one specific device
|
||||
should be declared within the device's class itself. This avoids
|
||||
pollution of the global namespace and makes the device-specific use of
|
||||
them more obvious at a glance.
|
||||
|
||||
|
||||
.. _contributing-cxx-const:
|
||||
|
||||
Const Correctness
|
||||
-----------------
|
||||
|
||||
Const-correctness has not historically been a strict requirement of code
|
||||
that goes into MAME, but there’s increasing value in it as the amount of
|
||||
code refactoring increases and technical debt decreases.
|
||||
|
||||
When writing new code, it’s worth taking the time to determine if a
|
||||
local variable can be declared ``const``. Similarly, it's encouraged to
|
||||
consider which member functions of a new class can be ``const``
|
||||
qualified.
|
||||
|
||||
In a similar vein, arrays of constants should be declared ``constexpr``
|
||||
and should use screaming snake case, as outlined towards the top of this
|
||||
document. Lastly, arrays of C-style strings should be declared as both
|
||||
a const array of const strings, as so:
|
||||
|
||||
.. code-block:: C++
|
||||
|
||||
static const char *const EXAMPLE_NAMES[4] =
|
||||
{
|
||||
"1-bit",
|
||||
"2-bit",
|
||||
"4-bit",
|
||||
"Invalid"
|
||||
};
|
||||
|
||||
|
||||
.. _contributing-cxx-comments:
|
||||
|
||||
Comments
|
||||
--------
|
||||
|
||||
While ``/* ANSI C comments */`` are often found in the codebase, there
|
||||
has been a gradual shift towards ``// C++-style comments`` for
|
||||
single-line comments. This is very much a guideline, and coders are
|
||||
encouraged to use whichever style is most comfortable.
|
||||
|
||||
Unless specifically quoting content from a machine or ancillary
|
||||
materials, comments should be in English so as to match the predominant
|
||||
language that the MAME team shares worldwide.
|
||||
|
||||
Commented-out code should typically be removed prior to authoring a pull
|
||||
request, as it has a tendency to rot due to the fast-moving nature of
|
||||
MAME’s core API. If there is a desire known beforehand for the code to
|
||||
eventually be included, it should be bookended in ``if (0)`` or
|
||||
``if (false)``, as code removed through a preprocessor macro will rot at
|
||||
the same rate.
|
||||
|
||||
|
||||
.. _contributing-cxx-helpers:
|
||||
|
||||
MAME-Specific Helpers
|
||||
---------------------
|
||||
|
||||
When at all possible, use helper functions and macros for bit
|
||||
manipulation operations.
|
||||
|
||||
The ``BIT(value, bit)`` helper can be used to extract the state of a bit
|
||||
at a given position from an integer value. The resulting value will be
|
||||
aligned to the least significant bit position, i.e. will be either 0 or
|
||||
1.
|
||||
|
||||
An overload of the same function, ``BIT(value, bit, width)`` can be used
|
||||
to extract a bit field of a specified width from an integer value,
|
||||
starting at the specified bit position. The result will also be
|
||||
right-justified and will be of the same type as the incoming value.
|
||||
|
||||
There are, additionally, a number of helpers for functionality such as
|
||||
counting leading zeroes/ones, population count, and signed/unsigned
|
||||
integer multiplication and division for both 32-bit and 64-bit results.
|
||||
Not all of these helpers have wide use in the MAME codebase, but using
|
||||
them in new code is strongly preferred when that code is performance-
|
||||
critical, as they utilise inline assembly or compiler intrinsics per-
|
||||
platform when available.
|
||||
|
||||
``count_leading_zeros_32/64(T value)``
|
||||
Accepts an unsigned 32/64-bit value and returns an unsigned 8-bit
|
||||
value containing the number of consecutive zeros starting from the
|
||||
most significant bit.
|
||||
``count_leading_ones_32/64(T value)``
|
||||
Same functionality as above, but examining consecutive one-bits.
|
||||
``population_count_32/64(T value)``
|
||||
Accepts an unsigned 32/64-bit value and returns the number of
|
||||
one-bits found, i.e. the Hamming weight of the value.
|
||||
``rotl_32/64(T value, int shift)``
|
||||
Performs a circular/barrel left shift of an unsigned 32/64-bit value
|
||||
with the specified shift value. The shift value will be masked to
|
||||
the valid bit range for a 32-bit or 64-bit value.
|
||||
``rotr_32/64(T value, int shift)``
|
||||
Same functionality as above, but with a right shift.
|
||||
|
||||
For documentation on helpers related to multiplication and division,
|
||||
refer to ``src/osd/eminline.h``.
|
||||
|
||||
|
||||
.. _contributing-cxx-logging:
|
||||
|
||||
Logging
|
||||
-------
|
||||
|
||||
MAME has multiple logging function for different purposes. Two of the
|
||||
most frequently used logging functions are ``logerror`` and
|
||||
``osd_printf_verbose``:
|
||||
|
||||
* Devices inherit a ``logerror`` member function. This automatically
|
||||
includes the fully-qualified tag of the invoking device in log
|
||||
messages. Output is sent to MAME’s debugger’s rotating log buffer if
|
||||
the debugger is enabled. If the
|
||||
:ref:`-log option <mame-commandline-log>` is enabled, it’s also
|
||||
written to the file ``error.log`` in the working directory. If the
|
||||
:ref:`-oslog option <mame-commandline-oslog>` is enabled, it’s
|
||||
additionally sent to the OS diagnostic output (the host debugger
|
||||
diagnostic log on Windows if a host debugger is attached, or standard
|
||||
error otherwise).
|
||||
* The output of the ``osd_printf_verbose`` function is sent to standard
|
||||
error if the :ref:`-verbose option <mame-commandline-verbose>` is
|
||||
enabled.
|
||||
|
||||
The ``osd_printf_verbose`` function should be used for logging that is
|
||||
useful for diagnosing user issues, while ``logerror`` should be used for
|
||||
messages more relevant to developers (either developing MAME itself, or
|
||||
developing software for emulated systems using MAME’s debugger).
|
||||
|
||||
For debug logging, a channel-based logging system exists via the header
|
||||
``logmacro.h``. It can be used as a generic logging system as follows,
|
||||
without needing to make use of its ability to mask out specific
|
||||
channels:
|
||||
|
||||
.. code-block:: C++
|
||||
|
||||
// All other headers in the .cpp file should be above this line.
|
||||
#define VERBOSE (1)
|
||||
#include "logmacro.h"
|
||||
...
|
||||
void some_device::some_reg_write(u8 data)
|
||||
{
|
||||
LOG("%s: some_reg_write: %02x\n", machine().describe_context(), data);
|
||||
}
|
||||
|
||||
The above example also makes use of a helper function which is available
|
||||
in all derivatives of ``device_t``: ``machine().describe_context()``.
|
||||
This function will return a string that describe the emulation context
|
||||
in which the function is being run. This includes the full-qualified
|
||||
tag of the currently executing device (if any). If the relevant device
|
||||
implements ``device_state_interface``, it will also include the current
|
||||
program-counter value reported by the device.
|
||||
|
||||
For more fine-grained control, specific bit masks can be defined and
|
||||
used via the ``LOGMASKED`` macro:
|
||||
|
||||
.. code-block:: C++
|
||||
|
||||
// All other headers in the .cpp file should be above this line.
|
||||
#define LOG_FOO (1 << 1U)
|
||||
#define LOG_BAR (1 << 2U)
|
||||
|
||||
#define VERBOSE (LOG_FOO | LOG_BAR)
|
||||
#include "logmacro.h"
|
||||
...
|
||||
void some_device::some_reg_write(u8 data)
|
||||
{
|
||||
LOGMASKED(LOG_FOO, "some_reg_write: %02x\n", data);
|
||||
}
|
||||
|
||||
void some_device::another_reg_write(u8 data)
|
||||
{
|
||||
LOGMASKED(LOG_BAR, "another_reg_write: %02x\n", data);
|
||||
}
|
||||
|
||||
Note that the least significant bit position for user-supplied masks is
|
||||
1, as bit position 0 is reserved for ``LOG_GENERAL``.
|
||||
|
||||
By default, ``LOG`` and ``LOGMASKED`` will use the device-supplied
|
||||
``logerror`` function. However, this can be redirected as desired. The
|
||||
most common use case would be to direct output to the standard output
|
||||
instead, which can be accomplished by explicitly defining
|
||||
``LOG_OUTPUT_FUNC`` as so:
|
||||
|
||||
.. code-block:: C++
|
||||
|
||||
#define LOG_OUTPUT_FUNC osd_printf_info
|
||||
|
||||
A developer should always ensure that ``VERBOSE`` is set to 0 and that
|
||||
any definition of ``LOG_OUTPUT_FUNC`` is commented out prior to opening
|
||||
a pull request.
|
||||
|
||||
|
||||
.. _contributing-cxx-structure:
|
||||
|
||||
Structural organization
|
||||
-----------------------
|
||||
|
||||
Header includes should generally be grouped from most-dependent to
|
||||
least-dependent, and sorted alphabetically within said groups:
|
||||
|
||||
* The project prefix header, ``emu.h``, must be the first thing in a
|
||||
translation unit
|
||||
* Local project headers (i.e. headers found in the same source
|
||||
directory)
|
||||
* Headers in ``src/devices``
|
||||
* Headers in ``src/emu``
|
||||
* Headers in ``src/lib/formats``
|
||||
* Headers in ``src/lib/util``
|
||||
* Headers from the OSD layer
|
||||
* C++ standard library headers
|
||||
* C standard library headers
|
||||
* OS-specific headers
|
||||
* Layout headers
|
||||
|
||||
Finally, task-specific headers such as ``logmacro.h`` - described in the
|
||||
previous section - should be included last. A practical example
|
||||
follows:
|
||||
|
||||
.. code-block:: C++
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "cpu/m68000/m68000.h"
|
||||
#include "machine/mc68328.h"
|
||||
#include "machine/ram.h"
|
||||
#include "sound/dac.h"
|
||||
#include "video/mc68328lcd.h"
|
||||
#include "video/sed1375.h"
|
||||
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
#include "speaker.h"
|
||||
|
||||
#include "pilot1k.lh"
|
||||
|
||||
#define VERBOSE (0)
|
||||
#include "logmacro.h"
|
||||
|
||||
The class declaration for a machine driver should be within the
|
||||
corresponding source file. In such cases, the class declaration and all
|
||||
contents of the source file, excluding the ``GAME``, ``COMP``, or
|
||||
``CONS`` macro, should be enclosed in an anonymous namespace.
|
||||
|
||||
Constants which are used by a device or machine driver should be in the
|
||||
form of explicitly-sized enumerated values within the class declaration,
|
||||
or be relegated to ``#define`` macros within the source file. This
|
||||
helps avoid polluting the preprocessor.
|
||||
|
||||
Type names and other identifiers with a leading underscore should be
|
||||
avoided within the global namespace, as they are explicitly reserved
|
||||
according to the C++ standard. Additionally, identifiers suffixed with
|
||||
``_t`` should be avoided within the global namespace, as they are also
|
||||
reserved according to POSIX standards. While MAME violates this policy
|
||||
occasionally – most notably with ``device_t`` – it’s considered to be an
|
||||
unfortunate legacy decision that should be avoided in any new code.
|
144
docs/source/contributing/index.rst
Normal file
144
docs/source/contributing/index.rst
Normal file
|
@ -0,0 +1,144 @@
|
|||
.. _contributing:
|
||||
|
||||
Contributing to MAME
|
||||
====================
|
||||
|
||||
So you want to contribute to MAME but aren’t sure where to start? Well
|
||||
the great news is that there’s always plenty to do for people with a
|
||||
variety of skill sets.
|
||||
|
||||
|
||||
.. _contributing-testing:
|
||||
|
||||
Testing and reporting bugs
|
||||
--------------------------
|
||||
|
||||
One thing MAME can always do with is more testing and bug reports. If
|
||||
you’re familiar with a system that MAME emulates and notice something
|
||||
wrong, or if you find a bug in MAME’s user interface, you can head over
|
||||
to `MAME Testers <https://mametesters.org/>`_ and, assuming it isn’t
|
||||
already reported, register an account and open an issue. Be sure to
|
||||
read the `FAQ <https://mametesters.org/faq.html>`_ and
|
||||
`rules <https://mametesters.org/rules.html>`_ first to ensure you start
|
||||
out on the right foot. Please note that MAME Testers only accepts
|
||||
user-facing bugs in tagged release versions.
|
||||
|
||||
For other kinds of issues, we have
|
||||
`GitHub Issues <https://github.com/mamedev/mame/issues/>`_. There’s a
|
||||
bit more leeway here. For example we accept developer-facing issues
|
||||
(e.g. bugs in internal APIs, or build system inadequacies), feature
|
||||
requests, and major regressions before they make it into a released
|
||||
version. Please respect the fact that the issue tracker is *not* a
|
||||
discussion or support forum, it’s only for reporting reproducible
|
||||
issues. Don’t open issues to ask questions or request support. Also,
|
||||
keep in mind that the ``master`` branch is unstable. If the current
|
||||
revision doesn’t compile at all or is completely broken, we’re probably
|
||||
already aware of it and don’t need issues opened for that. Wait a while
|
||||
and see if there’s an update. You might want to comment on the commit
|
||||
in question with the compiler error message, particularly if you’re
|
||||
compiling in an unorthodox but supported configuration.
|
||||
|
||||
When opening an issue, remember to provide as much information as
|
||||
possible to help others understand, reproduce, and diagnose the issue.
|
||||
Things that are helpful to include:
|
||||
|
||||
* The incorrect behaviour, and expected or correct behaviour. Be
|
||||
specific: just saying it “doesn’t work” usually isn’t enough detail.
|
||||
* Environment details, including your operating system, CPU
|
||||
architecture, system locale, and display language, if applicable. For
|
||||
video output bugs, note your video hardware (GPU), driver version, and
|
||||
the MAME video output module you’re using. For input handling bugs,
|
||||
include the input peripherals and MAME input modules you’re using.
|
||||
* The exact version of MAME you’re using, including a git commit digest
|
||||
if it isn’t a tagged release version, and any non-standard build
|
||||
options.
|
||||
* The exact system and software being emulated (may not be applicable
|
||||
for issues with parts of MAME’s UI, like the system selection menu).
|
||||
Include things like the selected BIOS version, and emulated peripheral
|
||||
(slot device) configuration.
|
||||
* Steps to reproduce the issue. Assume the person reading is familiar
|
||||
with MAME itself, but not necessarily familiar with the emulated
|
||||
system and software in question. For emulation issues, input
|
||||
recordings and/or saved state files for reproducing the issue can be
|
||||
invaluable.
|
||||
* An original reference for the correct behaviour. If you have access
|
||||
to the original hardware for the emulated system, it helps to make a
|
||||
recording of the correct behaviour for comparison.
|
||||
|
||||
|
||||
.. _contributing-code:
|
||||
|
||||
Contributing to MAME’s source code
|
||||
----------------------------------
|
||||
|
||||
MAME itself is written in C++, but that isn’t the sum total of the
|
||||
source code. The source code also includes:
|
||||
|
||||
* The documentation hosted on this site (and also included in releases
|
||||
as a PDF), written in
|
||||
`reStructuredText <https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html>`_
|
||||
markup.
|
||||
* The supplied :ref:`plugins <plugins>`, written in
|
||||
`Lua 5.3 <https://www.lua.org/manual/5.3/>`_.
|
||||
* Internal layouts for emulated machines that need to display more than
|
||||
a simple video screen. These are an XML application
|
||||
:ref:`described here <layfile>`.
|
||||
* The software lists, describing known software media for systems that
|
||||
MAME emulates. MAME software lists are an XML application.
|
||||
* The user interface translations, in GNU gettext PO format. They can
|
||||
be edited with a good text editor, or a dedicated tool like
|
||||
`Poedit <https://poedit.net/>`_.
|
||||
|
||||
Our primary source code repository is
|
||||
`hosted on GitHub <https://github.com/mamedev/mame/>`_. We prefer to
|
||||
receive source code contributions in the form of
|
||||
`pull requests <https://github.com/mamedev/mame/pulls>`_. You’ll need
|
||||
to learn the basics of git distributed version control and familiarise
|
||||
yourself with the git tools. The basic process for creating a pull
|
||||
request is as follows:
|
||||
|
||||
* Sign up for an account on GitHub.
|
||||
* Create a fork of the mamedev/mame repository.
|
||||
* Create a new branch off the ``master`` branch in your forked
|
||||
repository.
|
||||
* Clone your forked repository, and check out your new branch.
|
||||
* Make your changes, and build and test them locally.
|
||||
* Commit your changes, and push your branch to GitHub.
|
||||
* Optionally enable GitHub Actions for your forked repository, allowing
|
||||
your changes to be built on Windows, macOS and Linux.
|
||||
* Open a pull request to merge your changes into the ``master`` branch
|
||||
in the mamedev/mame repository.
|
||||
|
||||
Please keep the following in mind (note that not all points are relevant
|
||||
to all kinds of changes):
|
||||
|
||||
* Make your commit messages descriptive. Please include what the change
|
||||
affects, and what it’s supposed to achieve. A person reading the
|
||||
commit log shouldn’t need to resort to examining the diff to get a
|
||||
basic idea of what a commit is supposed to do. The default commit
|
||||
messages provided by GitHub are completely useless, as they don’t give
|
||||
any indication of what a change is supposed to do.
|
||||
* Test your changes. Ensure that a full build of MAME completes, and
|
||||
that the code you changed works. It’s a good idea to build with
|
||||
``DEBUG=1`` to check that assertions compile and don’t trigger.
|
||||
* Use an enlightening pull request title and description. The title
|
||||
should give a one-line summary of what the overall change affects and
|
||||
what it’s supposed to do. The description should contain more detail.
|
||||
Don’t leave the description empty and describe the change in comments,
|
||||
as this makes searching and filtering more difficult.
|
||||
* Be aware that GitHub Actions has opaque resource limits. It isn’t
|
||||
clear when you’re close to the limits, and we’ve had contributors
|
||||
banned from GitHub Actions for violating the limits. Even if you
|
||||
appeal the ban, they still won’t tell you what the actual limits are,
|
||||
justifying this by saying that if you know the limits, you can take
|
||||
steps to evade them. If you enable GitHub Actions, consider not
|
||||
pushing individual commits if you don’t need them to be automatically
|
||||
built, or cancelling workflow runs when you don’t need the results.
|
||||
|
||||
We have guidelines for specific parts of the source:
|
||||
|
||||
.. toctree::
|
||||
:titlesonly:
|
||||
|
||||
cxx
|
||||
softlist
|
175
docs/source/contributing/softlist.rst
Normal file
175
docs/source/contributing/softlist.rst
Normal file
|
@ -0,0 +1,175 @@
|
|||
.. _contributing-softlist:
|
||||
|
||||
Guidelines for Software Lists
|
||||
=============================
|
||||
|
||||
.. contents:: :local:
|
||||
|
||||
|
||||
.. _contributing-softlist-intro:
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
MAME’s software lists describe known software media for emulated
|
||||
systems in a form that can be used to identify media image files for
|
||||
known software, verify media image file integrity, and load media
|
||||
image files for emulation. Software lists are implemented as XML
|
||||
files in the ``hash`` folder. The XML structure is described in the
|
||||
file ``hash/softwarelist.dtd``.
|
||||
|
||||
Philosophically, software list items should represent the original
|
||||
media, rather than a specific dump of the media. Ideally, it should be
|
||||
possible for anyone with the media to dump it and produce the same image
|
||||
file. Of course, this isn’t always possible in practice – in particular
|
||||
it’s problematic for inherently analog media, like home computer
|
||||
software stored on audio tape cassettes.
|
||||
|
||||
MAME strives to document the best available media images. It is not our
|
||||
intention to propagate corrupted, truncated, defaced, watermarked, or
|
||||
otherwise bad media images. Where possible, file structures matching
|
||||
the original media structure are preferred. For example we prefer
|
||||
individual files for separate ROM chips in cartridge media, and we use
|
||||
disk images rather than archives of files extracted from the original
|
||||
disks.
|
||||
|
||||
|
||||
.. _contributing-softlist-itempart:
|
||||
|
||||
Items and parts
|
||||
---------------
|
||||
|
||||
A software list is a collection of *items* and each item may have
|
||||
multiple *parts*. An item represents a piece of software, as
|
||||
distributed as a complete package. A part represents a single piece of
|
||||
media within the package. Parts can be mounted individually in
|
||||
emulated media devices. For example a piece of software distributed on
|
||||
three floppy disks will be a single item, while each floppy disk will be
|
||||
one part within that item.
|
||||
|
||||
Sometimes, logically separate parts of a single physical piece of media
|
||||
are represented as separate parts within a software item. For example
|
||||
each side of an audio tape cassette is represented as a separate part.
|
||||
However individual ROM chips within a cartridge may be separate files,
|
||||
but they are *not* separate parts, as the cartridge is mounted as a
|
||||
whole.
|
||||
|
||||
Each item is a ``software`` element. The ``software`` element may have
|
||||
the following attributes:
|
||||
|
||||
name (required)
|
||||
The short name identifying the item. This is used for file names,
|
||||
command line arguments, database keys, URL fragments, and many other
|
||||
purposes. It should be terse but still recognisable. It must be
|
||||
unique within the software list. Valid characters are lowercase
|
||||
English letters, decimal digits and underscores. The maximum
|
||||
allowed length is sixteen characters.
|
||||
cloneof (optional)
|
||||
The short name of the parent item if the item is a clone. The
|
||||
parent must be within the same software list – parent/clone
|
||||
relationships spanning multiple software lists are not supported.
|
||||
supported (optional)
|
||||
One of the values ``yes`` (fully usable in emulation), ``no`` (not
|
||||
usable in emulation), or ``partial`` (usable in emulation with
|
||||
limitations). If the attribute is not present, it is equivalent to
|
||||
``yes``. Examples of partially supported software include games
|
||||
that are playable with graphical glitches, and office software where
|
||||
some but not all functionality works.
|
||||
|
||||
Each part is a ``part`` element within the ``software`` element. The
|
||||
``part`` element must have the following attributes:
|
||||
|
||||
name (required)
|
||||
The short name identifying the part. This is used for command line
|
||||
arguments, database keys, URL fragments, and many other purposes.
|
||||
It must be unique within the item. It is also used as the display
|
||||
name if a separate display name is not provided. Valid characters
|
||||
are lowercase English letters, decimal digits and underscores. The
|
||||
maximum allowed length is sixteen characters.
|
||||
interface (required)
|
||||
This attribute is used to identify suitable emulated media devices
|
||||
for mounting the software part. Applicable values depend on the
|
||||
emulated system.
|
||||
|
||||
|
||||
.. _contributing-softlist-metadata:
|
||||
|
||||
Metadata
|
||||
--------
|
||||
|
||||
Software lists support various kinds of metadata. All software list
|
||||
items require the following metadata elements to be present:
|
||||
|
||||
description
|
||||
This is the primary display name for the software item. It should
|
||||
be the original name of the software, transliterated into English
|
||||
Latin script if necessary. It must be unique within the software
|
||||
list. If extra text besides the title itself is required for
|
||||
disambiguation, use lowercase outside of proper nouns, initialisms
|
||||
and verbatim quotes.
|
||||
year
|
||||
The year of release or copyright year for the software. If unknown,
|
||||
use an estimate with a question mark. Items can be filtered by year
|
||||
in the software selection menu.
|
||||
publisher
|
||||
The publisher of the software. This may be the same as the
|
||||
developer if the software was self-published. Items can be filtered
|
||||
by published in the software selection menu.
|
||||
|
||||
Most user-visible software item metadata is provided using ``info``
|
||||
elements. Each ``info`` element must have a ``name`` attribute and a
|
||||
``value`` attribute. The ``name`` attribute identifies the type of
|
||||
metadata, and the ``value`` attribute is the metadata value itself.
|
||||
Note that ``name`` attributes do not need to be unique within an item.
|
||||
Multiple ``info`` elements with the same ``name`` may be present if
|
||||
appropriate. This is frequently seen for software sold using different
|
||||
titles in different regions.
|
||||
|
||||
MAME displays metadata from ``info`` elements in the software selection
|
||||
menu. The following ``name`` attributes are recognised specifically,
|
||||
and can show localised names:
|
||||
|
||||
alt_title
|
||||
Used for alternate titles. Examples are different tiles used in
|
||||
different languages, scripts or regions, or different titles used
|
||||
on the title screen and packaging. MAME searches alternate titles
|
||||
as well as the description.
|
||||
author
|
||||
Author of the software. Items can be filtered by author in the
|
||||
software selection menu.
|
||||
barcode
|
||||
Barcode number identifying the software package (typically an EAN).
|
||||
developer
|
||||
Developer responsible for implementing the software. Items can be
|
||||
filtered by developer in the software selection menu.
|
||||
distributor
|
||||
Party responsible for distributing the software to retailers (or
|
||||
customers in the case of direct sales). Items can be filtered by
|
||||
distributor in the software selection menu.
|
||||
install
|
||||
Installation instructions.
|
||||
isbn
|
||||
ISBN for software included with a commercial book.
|
||||
oem
|
||||
Original equipment manufacturer, typically used with customised
|
||||
versions of software distributed by a hardware vendor.
|
||||
original_publisher
|
||||
The original publisher, for items representing software re-released
|
||||
by a different publisher.
|
||||
partno
|
||||
Distributor’s part number for the software.
|
||||
pcb
|
||||
Printed circuit board identifier, typically for cartridge media.
|
||||
programmer
|
||||
Programmer who wrote the code for the software.
|
||||
release
|
||||
Fine-grained release date for the software, if known. Use
|
||||
YYYYMMDD format with no punctuation. If only the month is know,
|
||||
use “xx” for the day digits. For example ``199103xx`` or
|
||||
``19940729``.
|
||||
serial
|
||||
Number identifying the software within a series of releases.
|
||||
usage
|
||||
Usage instructions.
|
||||
version
|
||||
Version number of the software.
|
|
@ -28,6 +28,7 @@ MAME Documentation
|
|||
debugger/index
|
||||
tools/index
|
||||
|
||||
contributing/index
|
||||
techspecs/index
|
||||
|
||||
security
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
.. _naming:
|
||||
|
||||
MAME Naming Conventions
|
||||
=======================
|
||||
|
||||
|
@ -13,25 +15,6 @@ To promote consistency and readability in MAME source code, we have some
|
|||
naming conventions for various elements.
|
||||
|
||||
|
||||
.. _naming-definitions:
|
||||
|
||||
Definitions
|
||||
-----------
|
||||
|
||||
Snake case
|
||||
All lowercase letters with words separated by underscores:
|
||||
``this_is_snake_case``
|
||||
Screaming snake case
|
||||
All uppercase letters with words separated by underscores:
|
||||
``SCREAMING_SNAKE_CASE``
|
||||
Camel case:
|
||||
Lowercase initial letter, first letter of each subsequent word
|
||||
capitalised, with no separators between words: ``exampleCamelCase``
|
||||
Llama case:
|
||||
Uppercase initial letter, first letter of each subsequent word
|
||||
capitalised, with no separators between words: ``LlamaCaseSample``
|
||||
|
||||
|
||||
.. _naming-transliteration:
|
||||
|
||||
Transliteration
|
||||
|
@ -108,39 +91,5 @@ use lowercase for anything else besides proper nouns and initialisms.
|
|||
C++ naming conventions
|
||||
----------------------
|
||||
|
||||
Preprocessor macros
|
||||
Macro names should use screaming snake case. Macros are always
|
||||
global and name conflicts can cause confusing errors – think
|
||||
carefully about what macros really need to be in headers and name
|
||||
them carefully.
|
||||
Include guards
|
||||
Include guard macros should begin with ``MAME_``, and end with a
|
||||
capitalised version of the file name, withe separators replaced by
|
||||
underscores.
|
||||
Constants
|
||||
Constants should use screaming snake case, whether they are constant
|
||||
globals, constant data members, enumerators or preprocessor
|
||||
constants.
|
||||
Functions
|
||||
Free functions names should use snake case. (There are some utility
|
||||
function that were previously implemented as preprocessor macros
|
||||
that still use screaming snake case.)
|
||||
Classes
|
||||
Class names should use snake case. Abstract class names should end
|
||||
in ``_base``. Public member functions (including static member
|
||||
functions) should use snake case.
|
||||
Device classes
|
||||
Concrete driver ``driver_device`` implementation names
|
||||
conventionally end in ``_state``, while other concrete device class
|
||||
names end in ``_device``. Concrete ``device_interface`` names
|
||||
conventionally begin with ``device_`` and end with ``_interface``.
|
||||
Device types
|
||||
Device types should use screaming snake case. Remember that device
|
||||
types are names in the global namespace, so choose explicit,
|
||||
unambiguous names.
|
||||
Enumerations
|
||||
The enumeration name should use snake case. The enumerators should
|
||||
use screaming snake case.
|
||||
Template parameters
|
||||
Template parameters should use llama case (both type and value
|
||||
parameters).
|
||||
For C++ naming conventions, see the relevant section in the C++
|
||||
Coding Guidelines: :ref:`contributing-cxx-naming`
|
||||
|
|
Loading…
Reference in a new issue