nestopia/source/fltkui/jg/jg.h
rdanbrook b22f8a0d93 FLTK: Begin full rewrite
- The FLTK frontend is now based on Nestopia JG, which has been imported
  into the codebase and largely replaces the functionality previously
  contained in "nstcommon", as well as the old input system. This has
  effectively become a "Jolly Good API" frontend specific to Nestopia.

- Many new input devices are now supported, and can take both a
  keyboard/mouse and a joystick definition. This includes user interface
  functionality, such as fast forward, state saving, disk swapping, and
  resetting.

- USB joysticks/gamepads are now hot-pluggable

- The window is now freely resizable and adapts to the change by making
  the emulator output fill as much as possible while maintaining the
  selected aspect ratio.

- Settings are now separated by interface settings, emulator settings,
  and input definitions.

- General UI improvements have been done. The code is significantly
  cleaner and more flexible, with some user-facing improvements to the
  theme and menu system.

- This revision is still WIP. Some features or settings are either
  temporarily or permanently removed:
  - All audio related settings are gone, pending a rewrite of the audio
    output code in the frontend. PAL (50Hz) support is flaky.
  - Video filters have been removed, with the tentative plan to replace
    them with modern shaders.
  - Some NTSC filter fine tuning settings are not yet exposed in
    Nestopia JG
  - Some video settings (such as Hue/Saturation) are removed
  - NSF Playback is removed pending a replacement using FLTK widgets
  - The rewinder is disabled, with a tentative plan to replace it with
    a solution that is implemented entirely in the frontend.
  - Cheats are temporarily non-functional
2024-05-17 08:14:19 -06:00

414 lines
13 KiB
C++

/*
zlib License
Copyright (c) 2020-2022 Rupert Carmichael
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef JG_H
#define JG_H
#ifdef __cplusplus
#include <cstddef>
#if __cplusplus >= 201103L
#include <cstdint>
#else
#include <stdint.h>
#endif
extern "C" {
#else
#include <stddef.h>
#include <stdint.h>
#endif
// Semantic Versioning
#define JG_VERSION_MAJOR 1
#define JG_VERSION_MINOR 0
#define JG_VERSION_PATCH 0
// Enums
enum jg_datatype {
JG_DATA_RAW, /**< Raw data */
JG_DATA_AUDIO, /**< Audio samples */
JG_DATA_VIDEO /**< Static or streaming visual data */
};
enum jg_hints {
JG_HINT_AUDIO_INTERNAL = 0x00000001, /**< Core internally allocates
audio buffer */
JG_HINT_VIDEO_INTERNAL = 0x00000002, /**< Core internally allocates
video buffer */
JG_HINT_VIDEO_FLIP_H = 0x00000004, /**< Screen flipped horizontally */
JG_HINT_VIDEO_FLIP_V = 0x00000008, /**< Screen flipped vertically */
JG_HINT_VIDEO_ROTATE_L = 0x00000010, /**< Screen rotated 90 degrees
left */
JG_HINT_VIDEO_ROTATE_R = 0x00000020, /**< Screen rotated 90 degrees
right */
JG_HINT_VIDEO_PRESCALED = 0x00000040, /**< Video internally scaled by
core */
JG_HINT_MEDIA_ARCHIVED = 0x00000080, /**< Core uses archived/compressed
content */
JG_HINT_INPUT_AUDIO = 0x00000100, /**< Core supports audio input
(microphone) */
JG_HINT_INPUT_VIDEO = 0x00000200 /**< Core supports visual input
(camera, scanner) */
};
enum jg_inputtype {
JG_INPUT_CONTROLLER, /**< Emulated Controller or Gamepad input type */
JG_INPUT_GUN, /**< Emulated Light Gun input type */
JG_INPUT_KEYBOARD, /**< Emulated Keyboard input type */
JG_INPUT_POINTER, /**< Emulated Pointer input type: mice, trackballs,
drawing tablets, light sensors */
JG_INPUT_SPINNER, /**< Emulated Spinner input type */
JG_INPUT_TOUCH, /**< Emulated Touchscreen or Touchpad input type */
JG_INPUT_EXTERNAL /**< Emulated External input type: Coin slots,
system/hardware buttons */
};
enum jg_loglevel {
JG_LOG_DBG, /**< Debug: verbose logging */
JG_LOG_INF, /**< Info: general purpose logging */
JG_LOG_WRN, /**< Warning: warnings about non-critical errors */
JG_LOG_ERR, /**< Error: critical errors requiring program exit */
JG_LOG_SCR /**< Screen: log to on-screen display */
};
enum jg_pixfmt {
JG_PIXFMT_XRGB8888, /**< 32-bit pixels with bits 24-31 unused, bits 16-23
for Red, bits 8-15 for Green, and bits 0-7 for
Blue */
JG_PIXFMT_XBGR8888, /**< 32-bit pixels with bits 24-31 unused, bits 16-23
for Blue, bits 8-15 for Green, and bits 0-7 for
Red */
JG_PIXFMT_RGBX5551, /**< 16-bit pixels with bits 11-15 for Red, bits 6-10
for Green, bits 1-5 for Blue, and bit 0 unused */
JG_PIXFMT_RGB565 /**< 16-bit pixels with bits 11-15 for Red, bits 5-10
for Green, and bits 0-4 for Blue */
};
enum jg_sampfmt {
JG_SAMPFMT_INT16, /**< 16-bit Signed Integer audio samples */
JG_SAMPFMT_FLT32 /**< 32-bit Floating Point audio samples */
};
enum jg_settingflag {
JG_SETTING_RESTART = 0x01, /**< Restart Required */
JG_SETTING_INPUT = 0x02 /**< Setting changes an input device */
};
// Typedefs
typedef struct _jg_coreinfo_t {
const char *name; /**< Short Name of the core e.g. "corename" */
const char *fname; /**< Full Name of the core e.g. "Core Name" */
const char *version; /**< Version e.g. "1.0 WIP" */
const char *sys; /**< System being emulated e.g. "sms" */
uint8_t numinputs; /**< Number of Ports/Inputs */
uint32_t hints; /**< Hints set for this core */
} jg_coreinfo_t;
typedef struct _jg_pathinfo_t {
const char *base; /**< Base user directory from which all other paths
begin */
const char *core; /**< Core asset path: for external support files
required for normal core operation, typically
distributed with the core */
const char *user; /**< User asset path: for external support files
not required for normal core operation,
typically optional audio/graphics/etc */
const char *bios; /**< BIOS directory: where BIOS or firmware files
are located */
const char *save; /**< Save directory: where SRAM, Memory Card, Real
Time Clock, or other non-volatile data is
saved */
} jg_pathinfo_t;
typedef struct _jg_fileinfo_t {
void *data; /**< Pointer to the file data */
size_t size; /**< Size of the file data in bytes */
uint32_t crc; /**< CRC32 Checksum */
const char *md5; /**< MD5 Checksum */
const char *path; /**< Filesystem full path */
const char *name; /**< Name of the file (without extension) */
const char *fname; /**< Full name of the file (with extension) */
} jg_fileinfo_t;
typedef struct _jg_videoinfo_t {
enum jg_pixfmt pixfmt; /**< Pixel Format */
unsigned wmax; /**< Maximum Width (X Resolution) */
unsigned hmax; /**< Maximum Height (Y Resolution) */
unsigned w; /**< Width: Current displayed video width */
unsigned h; /**< Height: Current displayed video height */
unsigned x; /**< X Offset: Start drawing x pixels into the
canvas from the left */
unsigned y; /**< Y Offset: Start drawing y pixels into the
canvas from the top */
unsigned p; /**< Pitch: Row Length, usually equal to Width */
double aspect; /**< Aspect Ratio e.g. 4.0/3.0 == 1.333333 */
void *buf; /**< Pointer to Video Buffer */
} jg_videoinfo_t;
typedef struct _jg_audioinfo_t {
enum jg_sampfmt sampfmt; /**< Sample Format */
unsigned rate; /**< Sample Rate in Hz e.g. 48000 */
unsigned channels; /**< Number of Channels */
unsigned spf; /**< Number of Audio Samples Per Frame */
void *buf; /**< Pointer to Audio Buffer */
} jg_audioinfo_t;
typedef struct _jg_inputinfo_t {
enum jg_inputtype type; /**< Type of emulated input device */
int index; /**< Index/port input device is plugged into */
const char *name; /**< Short name e.g. "gamepad" */
const char *fname; /**< Full name e.g. "Game Pad" */
const char **defs; /**< List of input definitions/button names */
int numaxes; /**< Number of axes on emulated device */
int numbuttons; /**< Number of buttons on emulated device */
} jg_inputinfo_t;
typedef struct _jg_inputstate_t {
int16_t *axis; /**< 16-bit signed axis values allocated by frontend */
uint8_t *button; /**< Digital button values allocated by frontend */
int32_t *coord; /**< 32-bit signed coordinate values allocated by
frontend */
int32_t *rel; /**< 32-bit signed relative motion values allocated by
frontend */
} jg_inputstate_t;
typedef struct _jg_setting_t {
const char *name; /**< Name of the setting */
const char *fname; /**< Full (Friendly) name of the setting */
const char *opts; /**< List of options: This string must be in one of two
formats.\n\n For numeric ranges:\n
N = Setting\n\n
For a list of settings with distinct names:\n
0 = Option, 1 = Other Option, 2 = Another Option */
const char *desc; /**< Description of the setting (verbose) */
int val; /**< Value of the setting */
int min; /**< Range minimum */
int max; /**< Range maximum */
uint32_t flags; /**< Flags to handle special behaviour */
} jg_setting_t;
// Jolly Good API Callbacks
/**
* Send log data to the frontend
* @param log level
* @param format string
*/
typedef void (*jg_cb_log_t)(int, const char *, ...);
void jg_set_cb_log(jg_cb_log_t);
/**
* Tell the frontend how many samples to read from the audio buffer
* @param number of samples to read
*/
typedef void (*jg_cb_audio_t)(size_t);
void jg_set_cb_audio(jg_cb_audio_t);
/**
* Send frame time interval to the frontend
* @param frame time interval
*/
typedef void (*jg_cb_frametime_t)(double);
void jg_set_cb_frametime(jg_cb_frametime_t);
/**
* Send Force Feedback data to the frontend
* @param port
* @param strength (0.0 to 1.0)
* @param length of time in frames
*/
typedef void (*jg_cb_rumble_t)(int, float, size_t);
void jg_set_cb_rumble(jg_cb_rumble_t);
// Jolly Good API Calls
/**
* Initialize the core
* @return success/fail
*/
int jg_init(void);
/**
* Deinitialize a core
*/
void jg_deinit(void);
/**
* Reset the system
* @param hard or soft reset
*/
void jg_reset(int);
/**
* Run a single frame of emulation
*/
void jg_exec_frame(void);
/**
* Load a game
* @return success/fail
*/
int jg_game_load(void);
/**
* Unload a game
* @return success/fail
*/
int jg_game_unload(void);
/**
* Load a state by path
* @param filename of the state to load
*/
int jg_state_load(const char *);
/**
* Load raw state data
* @param pointer to raw state data
*/
void jg_state_load_raw(const void*);
/**
* Save a state by path
* @param filename of the state to save
*/
int jg_state_save(const char *);
/**
* Save raw state data
* @return pointer to raw state data
*/
const void* jg_state_save_raw(void);
/**
* Retrieve the size of state data
* @return size of state data in bytes
*/
size_t jg_state_size(void);
/**
* Select next disc, floppy, or other type of media
*/
void jg_media_select(void);
/**
* Insert or remove media (disc, floppy, etc)
*/
void jg_media_insert(void);
/**
* Clear (disable) all cheat codes
*/
void jg_cheat_clear(void);
/**
* Set (enable) a cheat code
* @param cheat code
*/
void jg_cheat_set(const char *);
/**
* Rehash settings or other properties which may be modified while running
*/
void jg_rehash(void);
/**
* Push data into the core
* @param type of data being pushed
* @param port number of device, if applicable (default 0)
* @param pointer to a data buffer or struct containing a data buffer
* @param size of data or number of samples
*/
void jg_data_push(uint32_t, int, const void*, size_t);
/**
* Return core information
* @param system being emulated
* @return information about the core
*/
jg_coreinfo_t* jg_get_coreinfo(const char *);
/**
* Return video information
* @return information about video rendering
*/
jg_videoinfo_t* jg_get_videoinfo(void);
/**
* Return audio information
* @return information about audio
*/
jg_audioinfo_t* jg_get_audioinfo(void);
/**
* Return audio information
* @param port input device is plugged into
* @return information about an input device
*/
jg_inputinfo_t* jg_get_inputinfo(int);
/**
* Return number of emulator-specific settings, get pointer to settings array
* @param pointer to frontend's variable used to hold the number of settings
* @return pointer to core's settings array
*/
jg_setting_t* jg_get_settings(size_t*);
/**
* Set up video parameters after a game is loaded
*/
void jg_setup_video(void);
/**
* Set up audio parameters after a game is loaded
*/
void jg_setup_audio(void);
/**
* Pass a pointer to an input state into the emulator core
* @param pointer to input state
* @param index/port number
*/
void jg_set_inputstate(jg_inputstate_t*, int);
/**
* Tell the emulator information about the game
* @param jg_fileinfo_t
*/
void jg_set_gameinfo(jg_fileinfo_t);
/**
* Tell the emulator information about an auxiliary file
* @param jg_fileinfo_t
* @param index number
*/
void jg_set_auxinfo(jg_fileinfo_t, int);
/**
* Tell the emulator the paths for file operations
* @param jg_pathinfo_t
*/
void jg_set_paths(jg_pathinfo_t);
#ifdef __cplusplus
}
#endif
#endif