summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/emucore.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/emucore.h')
-rw-r--r--src/emu/emucore.h211
1 files changed, 106 insertions, 105 deletions
diff --git a/src/emu/emucore.h b/src/emu/emucore.h
index 4c8b9c96056..f6552461131 100644
--- a/src/emu/emucore.h
+++ b/src/emu/emucore.h
@@ -5,6 +5,7 @@
emucore.h
General core utilities and macros used throughout the emulator.
+
***************************************************************************/
#ifndef MAME_EMU_EMUCORE_H
@@ -12,33 +13,38 @@
#pragma once
-// standard C includes
-#include <assert.h>
-#include <math.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdarg.h>
-
// some cleanups for Solaris for things defined in stdlib.h
#if defined(__sun__) && defined(__svr4__)
#undef si_status
#undef WWORD
#endif
+// centralised forward declarations
+#include "emufwd.h"
+
+// common stuff from lib/util
+#include "corealloc.h"
+#include "coretmpl.h"
+#include "bitmap.h"
+#include "endianness.h"
+#include "strformat.h"
+#include "vecstream.h"
+
+// common stuff from osd
+#include "osdcomm.h"
+
// standard C++ includes
-#include <cassert>
#include <exception>
+#include <string>
#include <type_traits>
#include <typeinfo>
-// core system includes
-#include "osdcomm.h"
-#include "emualloc.h"
-#include "corestr.h"
-#include "bitmap.h"
-
-#include "emufwd.h"
+// standard C includes
+#include <cassert>
+#include <cmath>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
//**************************************************************************
@@ -70,20 +76,34 @@ using osd::s64;
// useful utility functions
using util::underlying_value;
using util::enum_value;
+using util::make_bitmask;
using util::BIT;
using util::bitswap;
using util::iabs;
+using util::string_format;
+
+using endianness_t = util::endianness;
+
+using util::BYTE_XOR_BE;
+using util::BYTE_XOR_LE;
+using util::BYTE4_XOR_BE;
+using util::BYTE4_XOR_LE;
+using util::WORD_XOR_BE;
+using util::WORD_XOR_LE;
+using util::BYTE8_XOR_BE;
+using util::BYTE8_XOR_LE;
+using util::WORD2_XOR_BE;
+using util::WORD2_XOR_LE;
+using util::DWORD_XOR_BE;
+using util::DWORD_XOR_LE;
-// genf is a generic function pointer; cast function pointers to this instead of void *
-typedef void genf(void);
+// input ports support up to 32 bits each
+typedef u32 ioport_value;
// pen_t is used to represent pixel values in bitmaps
typedef u32 pen_t;
-// stream_sample_t is used to represent a single sample in a sound stream
-typedef s32 stream_sample_t;
-
//**************************************************************************
@@ -152,21 +172,9 @@ union PAIR64
// COMMON CONSTANTS
//**************************************************************************
-// constants for expression endianness
-enum endianness_t
-{
- ENDIANNESS_LITTLE,
- ENDIANNESS_BIG
-};
-
-extern const char *const endianness_names[2];
-
-// declare native endianness to be one or the other
-#ifdef LSB_FIRST
-const endianness_t ENDIANNESS_NATIVE = ENDIANNESS_LITTLE;
-#else
-const endianness_t ENDIANNESS_NATIVE = ENDIANNESS_BIG;
-#endif
+constexpr endianness_t ENDIANNESS_LITTLE = util::endianness::little;
+constexpr endianness_t ENDIANNESS_BIG = util::endianness::big;
+constexpr endianness_t ENDIANNESS_NATIVE = util::endianness::native;
// M_PI is not part of the C/C++ standards and is not present on
@@ -176,15 +184,19 @@ const endianness_t ENDIANNESS_NATIVE = ENDIANNESS_BIG;
#endif
-// orientation of bitmaps
-constexpr int ORIENTATION_FLIP_X = 0x0001; // mirror everything in the X direction
-constexpr int ORIENTATION_FLIP_Y = 0x0002; // mirror everything in the Y direction
-constexpr int ORIENTATION_SWAP_XY = 0x0004; // mirror along the top-left/bottom-right diagonal
+/// \name Image orientation flags
+/// \{
+
+constexpr int ORIENTATION_FLIP_X = 0x0001; ///< Mirror horizontally (in the X direction)
+constexpr int ORIENTATION_FLIP_Y = 0x0002; ///< Mirror vertically (in the Y direction)
+constexpr int ORIENTATION_SWAP_XY = 0x0004; ///< Mirror along the top-left/bottom-right diagonal
constexpr int ROT0 = 0;
-constexpr int ROT90 = ORIENTATION_SWAP_XY | ORIENTATION_FLIP_X; // rotate clockwise 90 degrees
-constexpr int ROT180 = ORIENTATION_FLIP_X | ORIENTATION_FLIP_Y; // rotate 180 degrees
-constexpr int ROT270 = ORIENTATION_SWAP_XY | ORIENTATION_FLIP_Y; // rotate counter-clockwise 90 degrees
+constexpr int ROT90 = ORIENTATION_SWAP_XY | ORIENTATION_FLIP_X; ///< Rotate 90 degrees clockwise
+constexpr int ROT180 = ORIENTATION_FLIP_X | ORIENTATION_FLIP_Y; ///< Rotate 180 degrees
+constexpr int ROT270 = ORIENTATION_SWAP_XY | ORIENTATION_FLIP_Y; ///< Rotate 90 degrees anti-clockwise (270 degrees clockwise)
+
+/// \}
@@ -192,27 +204,6 @@ constexpr int ROT270 = ORIENTATION_SWAP_XY | ORIENTATION_FLIP_Y;
// COMMON MACROS
//**************************************************************************
-// macro for defining a copy constructor and assignment operator to prevent copying
-#define DISABLE_COPYING(TYPE) \
- TYPE(const TYPE &) = delete; \
- TYPE &operator=(const TYPE &) = delete
-
-// macro for declaring enumeration operators that increment/decrement like plain old C
-#define DECLARE_ENUM_INCDEC_OPERATORS(TYPE) \
-inline TYPE &operator++(TYPE &value) { return value = TYPE(std::underlying_type_t<TYPE>(value) + 1); } \
-inline TYPE &operator--(TYPE &value) { return value = TYPE(std::underlying_type_t<TYPE>(value) - 1); } \
-inline TYPE operator++(TYPE &value, int) { TYPE const old(value); ++value; return old; } \
-inline TYPE operator--(TYPE &value, int) { TYPE const old(value); --value; return old; }
-
-// macro for declaring bitwise operators for an enumerated type
-#define DECLARE_ENUM_BITWISE_OPERATORS(TYPE) \
-constexpr TYPE operator~(TYPE value) { return TYPE(~std::underlying_type_t<TYPE>(value)); } \
-constexpr TYPE operator&(TYPE a, TYPE b) { return TYPE(std::underlying_type_t<TYPE>(a) & std::underlying_type_t<TYPE>(b)); } \
-constexpr TYPE operator|(TYPE a, TYPE b) { return TYPE(std::underlying_type_t<TYPE>(a) | std::underlying_type_t<TYPE>(b)); } \
-inline TYPE &operator&=(TYPE &a, TYPE b) { return a = a & b; } \
-inline TYPE &operator|=(TYPE &a, TYPE b) { return a = a | b; }
-
-
// this macro passes an item followed by a string version of itself as two consecutive parameters
#define NAME(x) x, #x
@@ -225,16 +216,6 @@ template <typename T> constexpr auto RADIAN_TO_DEGREE(T const &x) { return (180.
template <typename T> constexpr auto DEGREE_TO_RADIAN(T const &x) { return (M_PI / 180.0) * x; }
-// endian-based value: first value is if 'endian' is little-endian, second is if 'endian' is big-endian
-#define ENDIAN_VALUE_LE_BE(endian,leval,beval) (((endian) == ENDIANNESS_LITTLE) ? (leval) : (beval))
-
-// endian-based value: first value is if native endianness is little-endian, second is if native is big-endian
-#define NATIVE_ENDIAN_VALUE_LE_BE(leval,beval) ENDIAN_VALUE_LE_BE(ENDIANNESS_NATIVE, leval, beval)
-
-// endian-based value: first value is if 'endian' matches native, second is if 'endian' doesn't match native
-#define ENDIAN_VALUE_NE_NNE(endian,neval,nneval) (((endian) == ENDIANNESS_NATIVE) ? (neval) : (nneval))
-
-
//**************************************************************************
// EXCEPTION CLASSES
//**************************************************************************
@@ -247,17 +228,28 @@ class emu_exception : public std::exception { };
class emu_fatalerror : public emu_exception
{
public:
- emu_fatalerror(const char *format, ...) ATTR_PRINTF(2,3);
- emu_fatalerror(const char *format, va_list ap);
- emu_fatalerror(int _exitcode, const char *format, ...) ATTR_PRINTF(3,4);
- emu_fatalerror(int _exitcode, const char *format, va_list ap);
-
- const char *string() const { return text; }
- int exitcode() const { return code; }
+ emu_fatalerror(emu_fatalerror const &) = default;
+ emu_fatalerror(emu_fatalerror &&) = default;
+ emu_fatalerror(util::format_argument_pack<char> const &args);
+ emu_fatalerror(int _exitcode, util::format_argument_pack<char> const &args);
+
+ template <typename Format, typename... Params, typename = std::enable_if_t<!std::is_base_of_v<emu_fatalerror, std::remove_reference_t<Format> > > >
+ emu_fatalerror(Format &&fmt, Params &&... args)
+ : emu_fatalerror(static_cast<util::format_argument_pack<char> const &>(util::make_format_argument_pack(std::forward<Format>(fmt), std::forward<Params>(args)...)))
+ {
+ }
+ template <typename Format, typename... Params>
+ emu_fatalerror(int _exitcode, Format &&fmt, Params &&... args)
+ : emu_fatalerror(_exitcode, static_cast<util::format_argument_pack<char> const &>(util::make_format_argument_pack(std::forward<Format>(fmt), std::forward<Params>(args)...)))
+ {
+ }
+
+ virtual char const *what() const noexcept override { return m_text.c_str(); }
+ int exitcode() const noexcept { return m_code; }
private:
- char text[1024];
- int code;
+ std::string m_text;
+ int m_code;
};
class tag_add_exception
@@ -269,26 +261,28 @@ private:
std::string m_tag;
};
+
//**************************************************************************
// CASTING TEMPLATES
//**************************************************************************
-void report_bad_cast(const std::type_info &src_type, const std::type_info &dst_type);
-void report_bad_device_cast(const device_t *dev, const std::type_info &src_type, const std::type_info &dst_type);
-
-template <typename Dest, typename Source>
-inline std::enable_if_t<std::is_base_of<device_t, Source>::value> report_bad_cast(Source *const src)
-{
- if (src) report_bad_device_cast(src, typeid(Source), typeid(Dest));
- else report_bad_cast(typeid(Source), typeid(Dest));
-}
+[[noreturn]] void report_bad_cast(const std::type_info &src_type, const std::type_info &dst_type);
+[[noreturn]] void report_bad_device_cast(const device_t *dev, const std::type_info &src_type, const std::type_info &dst_type);
template <typename Dest, typename Source>
-inline std::enable_if_t<!std::is_base_of<device_t, Source>::value> report_bad_cast(Source *const src)
+inline void report_bad_cast(Source *src)
{
- device_t const *dev(dynamic_cast<device_t const *>(src));
- if (dev) report_bad_device_cast(dev, typeid(Source), typeid(Dest));
- else report_bad_cast(typeid(Source), typeid(Dest));
+ if constexpr (std::is_base_of_v<device_t, Source>)
+ {
+ if (src) report_bad_device_cast(src, typeid(Source), typeid(Dest));
+ else report_bad_cast(typeid(Source), typeid(Dest));
+ }
+ else
+ {
+ device_t const *dev(dynamic_cast<device_t const *>(src));
+ if (dev) report_bad_device_cast(dev, typeid(Source), typeid(Dest));
+ else report_bad_cast(typeid(Source), typeid(Dest));
+ }
}
// template function for casting from a base class to a derived class that is checked
@@ -296,7 +290,7 @@ inline std::enable_if_t<!std::is_base_of<device_t, Source>::value> report_bad_ca
template <typename Dest, typename Source>
inline Dest downcast(Source *src)
{
-#if defined(MAME_DEBUG) && !defined(MAME_DEBUG_FAST)
+#if defined(MAME_DEBUG)
Dest const chk(dynamic_cast<Dest>(src));
if (chk != src) report_bad_cast<std::remove_pointer_t<Dest>, Source>(src);
#endif
@@ -306,7 +300,7 @@ inline Dest downcast(Source *src)
template<class Dest, class Source>
inline Dest downcast(Source &src)
{
-#if defined(MAME_DEBUG) && !defined(MAME_DEBUG_FAST)
+#if defined(MAME_DEBUG)
std::remove_reference_t<Dest> *const chk(dynamic_cast<std::remove_reference_t<Dest> *>(&src));
if (chk != &src) report_bad_cast<std::remove_reference_t<Dest>, Source>(&src);
#endif
@@ -316,15 +310,15 @@ inline Dest downcast(Source &src)
//**************************************************************************
-// FUNCTION PROTOTYPES
+// INLINE FUNCTIONS
//**************************************************************************
-[[noreturn]] void fatalerror(const char *format, ...) ATTR_PRINTF(1,2);
-[[noreturn]] void fatalerror_exitcode(running_machine &machine, int exitcode, const char *format, ...) ATTR_PRINTF(3,4);
+template <typename... T>
+[[noreturn]] inline void fatalerror(T &&... args)
+{
+ throw emu_fatalerror(std::forward<T>(args)...);
+}
-//**************************************************************************
-// INLINE FUNCTIONS
-//**************************************************************************
// convert a series of 32 bits into a float
inline float u2f(u32 v)
@@ -373,4 +367,11 @@ inline u64 d2u(double d)
return u.vv;
}
-#endif /* MAME_EMU_EMUCORE_H */
+
+//**************************************************************************
+// USEFUL UTILITIES
+//**************************************************************************
+
+using util::make_unique_clear;
+
+#endif // MAME_EMU_EMUCORE_H