/*
 * Copyright (c) 2021-2025 Rupert Carmichael
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

/* I'm not selling it on performance, but on simplicity, which is an odd thing.
   The logic is that open source matters to some people because the source code
   is meant to be looked-at.
                                - Terry A. Davis
*/

#ifndef CEGA_H
#define CEGA_H

#define SIZE_1K     0x000400
#define SIZE_2K     0x000800
#define SIZE_8K     0x002000
#define SIZE_16K    0x004000
#define SIZE_32K    0x008000
#define SIZE_64K    0x010000

#define REGION_JP           1
#define REGION_US           2
#define REGION_EU           3
#define REGION_DOMESTIC     REGION_JP // Japan (NTSC, Domestic)
#define REGION_EXPORT       REGION_US // Americas (NTSC/PAL-M, Export)
#define REGION_EXPORTPAL    REGION_EU // UK, Europe, and Oceania (PAL, Export)

#define SYSTEM_SG       0x0001
#define SYSTEM_SMS      0x0002
#define SYSTEM_GG       0x0004
#define SYSTEM_MD       0x0008
#define SYSTEM_MCD      0x0010
#define SYSTEM_32X      0x0020
#define SYSTEM_SYS1     0x0100
#define SYSTEM_SYS2     0x0200
#define SYSTEM_SYS16    0x0400

#define NUMINPUTS_SMS   3
#define NUMINPUTS_MD    3

enum cega_loglevel {
    CEGA_LOG_DBG,
    CEGA_LOG_INF,
    CEGA_LOG_WRN,
    CEGA_LOG_ERR,
    CEGA_LOG_SCR
};

void cega_set_region(unsigned);
int cega_get_system(void);
void cega_set_system(int);
void cega_init(void);
void cega_deinit(void);
void cega_reset(int);

void cega_log_set_callback(void (*)(int, const char *, ...));

void cega_input_set_callback(int, uint8_t (*)(int));
void cega_md_input_set_callback(int, uint16_t (*)(int));

extern void (*cega_log)(int, const char *, ...);

extern void (*cega_exec)(void);

extern int (*cega_bios_load)(void*, size_t);
extern int (*cega_rom_load)(void*, size_t);

extern size_t (*cega_state_size)(void);
extern int (*cega_state_load_raw)(const void*, size_t);
extern int (*cega_state_load)(const char*);
extern const void* (*cega_state_save_raw)(void);
extern int (*cega_state_save)(const char*);

extern int (*cega_sram_load)(const char*);
extern int (*cega_sram_save)(const char*);

extern uint8_t (*cega_input_cb[NUMINPUTS_SMS])(int);
extern uint16_t (*cega_md_input_cb[NUMINPUTS_MD])(int);

#endif
