Unverified Commit 7118601a authored by Kurtis Dinelle's avatar Kurtis Dinelle Committed by GitHub
Browse files

Merge pull request #4 from phcoder/lr3-rebase

LIBRETRO: Add files for CI/CD with libretro pipelines and various improvements
parents 9ea1d28f 77d7e926
Pipeline #80313 failed with stages
in 6 minutes and 7 seconds
# DESCRIPTION: GitLab CI/CD for libRetro (NOT FOR GitLab-proper)
##############################################################################
################################# BOILERPLATE ################################
##############################################################################
# Core definitions
.core-defs:
variables:
JNI_PATH: .
CORENAME: jaxe
MAKEFILE: Makefile.libretro
GIT_SUBMODULE_STRATEGY: recursive
# Inclusion templates, required for the build to work
include:
################################## DESKTOPS ################################
# Windows 64-bit
- project: 'libretro-infrastructure/ci-templates'
file: '/windows-x64-mingw.yml'
# Windows 32-bit
- project: 'libretro-infrastructure/ci-templates'
file: '/windows-i686-mingw.yml'
# Linux 64-bit
- project: 'libretro-infrastructure/ci-templates'
file: '/linux-x64.yml'
# Linux 32-bit
- project: 'libretro-infrastructure/ci-templates'
file: '/linux-i686.yml'
# MacOS 64-bit
- project: 'libretro-infrastructure/ci-templates'
file: '/osx-x64.yml'
# MacOS ARM 64-bit
- project: 'libretro-infrastructure/ci-templates'
file: '/osx-arm64.yml'
# MacOS PPC
- project: 'libretro-infrastructure/ci-templates'
file: '/osx-ppc.yml'
################################## CELLULAR ################################
# Android
- project: 'libretro-infrastructure/ci-templates'
file: '/android-jni.yml'
# iOS
- project: 'libretro-infrastructure/ci-templates'
file: '/ios-arm64.yml'
# iOS (armv7)
- project: 'libretro-infrastructure/ci-templates'
file: '/ios9.yml'
################################## CONSOLES ################################
# PlayStation Portable
- project: 'libretro-infrastructure/ci-templates'
file: '/psp-static.yml'
# PlayStation Vita
- project: 'libretro-infrastructure/ci-templates'
file: '/vita-static.yml'
# PlayStation2
- project: 'libretro-infrastructure/ci-templates'
file: '/ps2-static.yml'
# Nintendo 3DS
- project: 'libretro-infrastructure/ci-templates'
file: '/ctr-static.yml'
# Nintendo GameCube
- project: 'libretro-infrastructure/ci-templates'
file: '/ngc-static.yml'
# Nintendo Wii
- project: 'libretro-infrastructure/ci-templates'
file: '/wii-static.yml'
# Nintendo WiiU
- project: 'libretro-infrastructure/ci-templates'
file: '/wiiu-static.yml'
# Nintendo Switch
- project: 'libretro-infrastructure/ci-templates'
file: '/libnx-static.yml'
# OpenDingux
- project: 'libretro-infrastructure/ci-templates'
file: '/dingux-mips32.yml'
# OpenDingux
- project: 'libretro-infrastructure/ci-templates'
file: '/dingux-arm32.yml'
# tvOS (AppleTV)
- project: 'libretro-infrastructure/ci-templates'
file: '/tvos-arm64.yml'
#################################### MISC ##################################
# Emscripten
- project: 'libretro-infrastructure/ci-templates'
file: '/emscripten-static.yml'
# Stages for building
stages:
- build-prepare
- build-shared
- build-static
##############################################################################
#################################### STAGES ##################################
##############################################################################
#
################################### DESKTOPS #################################
# Windows 64-bit
libretro-build-windows-x64:
extends:
- .libretro-windows-x64-mingw-make-default
- .core-defs
# Windows 32-bit
libretro-build-windows-i686:
extends:
- .libretro-windows-i686-mingw-make-default
- .core-defs
# Linux 64-bit
libretro-build-linux-x64:
extends:
- .libretro-linux-x64-make-default
- .core-defs
# Linux 32-bit
libretro-build-linux-i686:
extends:
- .libretro-linux-i686-make-default
- .core-defs
# MacOS 64-bit
libretro-build-osx-x64:
extends:
- .libretro-osx-x64-make-default
- .core-defs
# MacOS ARM 64-bit
libretro-build-osx-arm64:
extends:
- .libretro-osx-arm64-make-default
- .core-defs
# MacOS PPC
libretro-build-osx-ppc:
extends:
- .libretro-osx-ppc-make-default
- .core-defs
################################### CELLULAR #################################
# Android ARMv7a
android-armeabi-v7a:
extends:
- .libretro-android-jni-armeabi-v7a
- .core-defs
# Android ARMv8a
android-arm64-v8a:
extends:
- .libretro-android-jni-arm64-v8a
- .core-defs
# Android 64-bit x86
android-x86_64:
extends:
- .libretro-android-jni-x86_64
- .core-defs
# Android 32-bit x86
android-x86:
extends:
- .libretro-android-jni-x86
- .core-defs
# iOS
libretro-build-ios-arm64:
extends:
- .libretro-ios-arm64-make-default
- .core-defs
# iOS (armv7) [iOS 9 and up]
libretro-build-ios9:
extends:
- .libretro-ios9-make-default
- .core-defs
# tvOS
libretro-build-tvos-arm64:
extends:
- .libretro-tvos-arm64-make-default
- .core-defs
################################### CONSOLES #################################
# PlayStation Portable
libretro-build-psp:
extends:
- .libretro-psp-static-retroarch-master
- .core-defs
# PlayStation Vita
libretro-build-vita:
extends:
- .libretro-vita-static-retroarch-master
- .core-defs
# PlayStation2
libretro-build-ps2:
extends:
- .libretro-ps2-static-retroarch-master
- .core-defs
# Nintendo 3DS
libretro-build-ctr:
extends:
- .libretro-ctr-static-retroarch-master
- .core-defs
# Nintendo GameCube
libretro-build-ngc:
extends:
- .libretro-ngc-static-retroarch-master
- .core-defs
# Nintendo Wii
libretro-build-wii:
extends:
- .libretro-wii-static-retroarch-master
- .core-defs
# Nintendo WiiU
libretro-build-wiiu:
extends:
- .libretro-wiiu-static-retroarch-master
- .core-defs
# Nintendo Switch
libretro-build-libnx-aarch64:
extends:
- .libretro-libnx-static-retroarch-master
- .core-defs
# OpenDingux
libretro-build-dingux-mips32:
extends:
- .libretro-dingux-mips32-make-default
- .core-defs
# OpenDingux Beta
libretro-build-dingux-odbeta-mips32:
extends:
- .libretro-dingux-odbeta-mips32-make-default
- .core-defs
# OpenDingux
libretro-build-dingux-arm32:
extends:
- .libretro-miyoo-arm32-make-default
- .core-defs
# RetroFW
libretro-build-retrofw-mips32:
extends:
- .libretro-retrofw-mips32-make-default
- .core-defs
#################################### MISC ##################################
# Emscripten
libretro-build-emscripten:
extends:
- .libretro-emscripten-static-retroarch-master
- .core-defs
......@@ -37,6 +37,7 @@ GIT_VERSION := " $(shell git rev-parse --short HEAD || echo unknown)"
ifneq ($(GIT_VERSION)," unknown")
CFLAGS += -DGIT_VERSION=\"$(GIT_VERSION)\"
endif
CFLAGS += -std=c99
ifeq ($(ARCHFLAGS),)
ifeq ($(archs),ppc)
......@@ -68,6 +69,15 @@ else ifeq ($(platform), linux-portable)
fpic := -fPIC -nostdlib
SHARED := -shared -Wl,--version-script=$(CORE_DIR)/link.T
LIBS = -lm
# tvOS
else ifeq ($(platform), tvos-arm64)
TARGET := $(TARGET_NAME)_libretro_tvos.dylib
fpic := -fPIC
SHARED := -dynamiclib
CFLAGS += -DIOS
ifeq ($(IOSSDK),)
IOSSDK := $(shell xcodebuild -version -sdk appletvos Path)
endif
else ifneq (,$(findstring osx,$(platform)))
TARGET := $(TARGET_NAME)_libretro.dylib
fpic := -fPIC
......@@ -240,6 +250,7 @@ else ifeq ($(platform), retrofw)
fpic := -fPIC
SHARED := -shared -Wl,--version-script=$(CORE_DIR)/link.T -Wl,--no-undefined
CFLAGS += -ffast-math -march=mips32 -mtune=mips32 -mhard-float
LIBS = -lm
# Emscripten
else ifeq ($(platform), emscripten)
......@@ -284,6 +295,7 @@ else ifeq ($(platform), gcw0)
DISABLE_ERROR_LOGGING := 1
CFLAGS += -march=mips32 -mtune=mips32r2 -mhard-float
LIBS = -lm
# Windows MSVC 2017 all architectures
else ifneq (,$(findstring windows_msvc2017,$(platform)))
......@@ -468,7 +480,16 @@ else ifeq ($(platform), xbox360_msvc2010)
CFLAGS += -D_XBOX -D_XBOX360
CXXFLAGS += -D_XBOX -D_XBOX360
STATIC_LINKING=1
# MIYOO
else ifeq ($(platform), miyoo)
TARGET := $(TARGET_NAME)_libretro.so
fpic := -fPIC
SHARED := -shared -Wl,-version-script=link.T
CC = /opt/miyoo/usr/bin/arm-linux-gcc
AR = /opt/miyoo/usr/bin/arm-linux-ar
PLATFORM_DEFINES += -D_GNU_SOURCE
CFLAGS += -fomit-frame-pointer -ffast-math -march=armv5te -mtune=arm926ej-s
CFLAGS += -fno-common -ftree-vectorize -funswitch-loops
# Current Windows builds via mingw/gcc
else
TARGET := $(TARGET_NAME)_libretro.dll
......
......@@ -229,12 +229,15 @@ Differences and notes compared to standalone version:
TODOs:
* Add more color themes (same as standalone)
* Investigate if better key mapping is possible
* Allow frontend to peek into "VRAM"
* Uncapped CPU frequency
* Option for PC start address
* Option for timer frequency
* Option for refresh frequency
* Choose resampled audio frequency based on available outputs or make it configurable
* retro_reset function
* Maybe have retroachievements support?
## Contributing
......
#ifndef CHIP8_H
#define CHIP8_H
#ifndef __LIBRETRO__
#ifdef WIN32
#include <windows.h>
#else
#include <sys/time.h>
#endif
#endif
#include <stdbool.h>
#include <stdint.h>
......
display_name = "CHIP-8/SuperChip8/XO-CHIP"
authors = "Kurtis Dinelle"
supported_extensions = "ch8"
supported_extensions = "ch8|sc8|xo8|hc8"
corename = "JAXE"
manufacturer = "RCA"
categories = "Emulator"
......
......@@ -6,6 +6,8 @@
#include "libretro.h"
#include "chip8.h"
#define VALID_EXTENSIONS "ch8|sc8|xo8|hc8"
#ifdef USE_RGB565
typedef unsigned short pixel_t;
#if defined(ABGR1555)
......@@ -145,8 +147,57 @@ static struct retro_variable variables[] =
{ NULL, NULL },
};
// TODO: find a better mapping
static int hexorder[] = {
RETRO_DEVICE_ID_JOYPAD_B,
RETRO_DEVICE_ID_JOYPAD_START,
RETRO_DEVICE_ID_JOYPAD_Y,
RETRO_DEVICE_ID_JOYPAD_SELECT,
RETRO_DEVICE_ID_JOYPAD_L,
RETRO_DEVICE_ID_JOYPAD_UP,
RETRO_DEVICE_ID_JOYPAD_A,
RETRO_DEVICE_ID_JOYPAD_LEFT,
RETRO_DEVICE_ID_JOYPAD_DOWN,
RETRO_DEVICE_ID_JOYPAD_RIGHT,
RETRO_DEVICE_ID_JOYPAD_R,
RETRO_DEVICE_ID_JOYPAD_L2,
RETRO_DEVICE_ID_JOYPAD_X,
RETRO_DEVICE_ID_JOYPAD_R2,
RETRO_DEVICE_ID_JOYPAD_L3,
RETRO_DEVICE_ID_JOYPAD_R3
};
static struct retro_input_descriptor input_desc[] = {
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "7" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "2" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "8" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "9" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "0" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT,"3" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "C" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "5" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "6" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "1" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "5" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "A" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "B" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "D" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3, "E" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3, "F" },
{ 0 },
};
void retro_set_environment(retro_environment_t fn)
{
static const struct retro_system_content_info_override content_overrides[] = {
{
VALID_EXTENSIONS, /* extensions */
false, /* need_fullpath */
true /* persistent_data */
},
{ NULL, false, false }
};
environ_cb = fn;
fn(RETRO_ENVIRONMENT_SET_VARIABLES, variables);
......@@ -157,6 +208,12 @@ void retro_set_environment(retro_environment_t fn)
log_cb = log.log;
else
log_cb = fallback_log;
/* Request a persistent content data buffer */
environ_cb(RETRO_ENVIRONMENT_SET_CONTENT_INFO_OVERRIDE,
(void*)content_overrides);
environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, input_desc);
}
static void load_theme(void)
......@@ -237,7 +294,7 @@ void draw_display(void)
{
color = p2_color;
}
else if (chip8.display[y][x] && chip8.display2[y][x])
else
{
color = overlap_color;
}
......@@ -253,53 +310,15 @@ void retro_set_audio_sample_batch(retro_audio_sample_batch_t fn) { audio_batch_c
void retro_set_input_poll(retro_input_poll_t fn) { input_poll_cb = fn; }
void retro_set_input_state(retro_input_state_t fn) { input_state_cb = fn; }
// TODO: find a better mapping
static int hexorder[] = {
RETRO_DEVICE_ID_JOYPAD_B,
RETRO_DEVICE_ID_JOYPAD_START,
RETRO_DEVICE_ID_JOYPAD_Y,
RETRO_DEVICE_ID_JOYPAD_SELECT,
RETRO_DEVICE_ID_JOYPAD_L,
RETRO_DEVICE_ID_JOYPAD_UP,
RETRO_DEVICE_ID_JOYPAD_A,
RETRO_DEVICE_ID_JOYPAD_LEFT,
RETRO_DEVICE_ID_JOYPAD_DOWN,
RETRO_DEVICE_ID_JOYPAD_RIGHT,
RETRO_DEVICE_ID_JOYPAD_R,
RETRO_DEVICE_ID_JOYPAD_L2,
RETRO_DEVICE_ID_JOYPAD_X,
RETRO_DEVICE_ID_JOYPAD_R2,
RETRO_DEVICE_ID_JOYPAD_L3,
RETRO_DEVICE_ID_JOYPAD_R3
};
struct retro_input_descriptor desc[] = {
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "7" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "2" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "8" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "9" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "0" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT,"3" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "C" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "5" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "6" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "1" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "5" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "A" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "B" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "D" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3, "E" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3, "F" },
{ 0 },
};
void retro_init(void)
{
}
bool retro_load_game(const struct retro_game_info *info)
{
static void *rom_buf = NULL;
static const void *rom_data = NULL;
static size_t rom_size = 0;
static void load_rom(void) {
cpu_debt = 0;
audio_counter_chip8 = 0;
audio_counter_resample = 0;
......@@ -309,16 +328,55 @@ bool retro_load_game(const struct retro_game_info *info)
chip8_init_with_vars();
chip8_load_font(&chip8);
chip8_load_rom_buffer(&chip8, info->data, info->size);
chip8_load_rom_buffer(&chip8, rom_data, rom_size);
}
bool retro_load_game(const struct retro_game_info *info)
{
const struct retro_game_info_ext *info_ext = NULL;
/* We need persistent ROM buffer for resets. */
rom_buf = NULL;
rom_data = NULL;
rom_size = 0;
if (environ_cb(RETRO_ENVIRONMENT_GET_GAME_INFO_EXT, &info_ext) &&
info_ext && info_ext->persistent_data) {
rom_data = (const uint8_t*)info_ext->data;
rom_size = info_ext->size;
}
/* If frontend does not support persistent
* content data, must create a copy */
if (!rom_data) {
if (!info)
return false;
environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, desc);
rom_size = info->size;
rom_buf = malloc(rom_size);
if (!rom_buf) {
log_cb(RETRO_LOG_INFO, "Failed to allocate ROM buffer.\n");
return false;
}
memcpy(rom_buf, info->data, rom_size);
rom_data = (const uint8_t*)rom_buf;
}
load_rom();
return true;
}
void retro_unload_game(void)
{
if (rom_buf)
free(rom_buf);
rom_buf = NULL;
rom_data = NULL;
rom_size = 0;
}
int get_audio_sample(void)
......@@ -344,12 +402,23 @@ int get_audio_sample(void)
return x;
}
static void audio_sample(int16_t sample) {
// TODO: Use audio_batch_cb
static void audio_sample(int16_t sample) {
int16_t buf[200]; // Should be enough to call batch_cb only once
// in most cases
int16_t *bufptr = buf;
while (audio_counter_resample >= ONE_SEC / AUDIO_RESAMPLE_RATE) {
audio_cb(sample, sample);
*bufptr++ = sample;
*bufptr++ = sample;
if (bufptr >= buf + sizeof(buf) / sizeof(buf[0])) {
audio_batch_cb(buf, (bufptr - buf) / 2);
bufptr = buf;
}
audio_counter_resample -= ONE_SEC / AUDIO_RESAMPLE_RATE;
}
if (bufptr != buf) {
audio_batch_cb(buf, (bufptr - buf) / 2);
}
}
void retro_run(void)
......@@ -419,7 +488,7 @@ void retro_get_system_info(struct retro_system_info *info)
#define GIT_VERSION ""
#endif
info->library_version = "1.0" GIT_VERSION;
info->valid_extensions = "ch8";
info->valid_extensions = VALID_EXTENSIONS;
info->need_fullpath = false;
}
......@@ -449,7 +518,7 @@ void retro_deinit(void) { }
void retro_reset(void)
{
// TODO
load_rom();
}
struct serialized_state
......@@ -533,6 +602,6 @@ void *retro_get_memory_data(unsigned id)
/* Stubs */
unsigned int retro_api_version(void) { return RETRO_API_VERSION; }
void retro_cheat_reset(void) { }
void retro_cheat_set(unsigned index, bool enabled, const char *code) { }
void retro_cheat_set(unsigned idx, bool enabled, const char *code) { }
bool retro_load_game_special(unsigned game_type, const struct retro_game_info *info, size_t num_info) { return false; }
void retro_set_controller_port_device(unsigned port, unsigned device) { }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment