environment.cpp 4.39 KB
Newer Older
James's avatar
James committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Copyright 2017 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.

#include <cstring>
#include <core/settings.h>

#include "audio_core/libretro_sink.h"
#include "common/scm_rev.h"
#include "environment.h"

using namespace LibRetro;

namespace LibRetro {

static retro_video_refresh_t video_cb;
static retro_audio_sample_t audio_cb;
static retro_environment_t environ_cb;
static retro_input_poll_t input_poll_cb;
James's avatar
James committed
20
static retro_input_state_t input_state_cb;
James's avatar
James committed
21

22
void UploadVideoFrame(const void* data, unsigned width, unsigned height, size_t pitch) {
James's avatar
James committed
23
24
25
    return video_cb(data, width, height, pitch);
}

Libretro-Admin's avatar
Libretro-Admin committed
26
27
28
29
bool SetHWSharedContext() {
    return environ_cb(RETRO_ENVIRONMENT_SET_HW_SHARED_CONTEXT, NULL);
}

James's avatar
James committed
30
31
32
33
34
void PollInput() {
    return input_poll_cb();
}

bool SetVariables(const retro_variable vars[]) {
35
    return environ_cb(RETRO_ENVIRONMENT_SET_VARIABLES, (void*)vars);
James's avatar
James committed
36
37
38
}

bool SetControllerInfo(const retro_controller_info info[]) {
39
    return environ_cb(RETRO_ENVIRONMENT_SET_CONTROLLER_INFO, (void*)info);
James's avatar
James committed
40
41
42
}

bool SetPixelFormat(const retro_pixel_format fmt) {
43
    return environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, (void*)&fmt);
James's avatar
James committed
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
}

bool SetHWRenderer(retro_hw_render_callback* cb) {
    return environ_cb(RETRO_ENVIRONMENT_SET_HW_RENDER, cb);
}

bool SetAudioCallback(retro_audio_callback* cb) {
    return environ_cb(RETRO_ENVIRONMENT_SET_AUDIO_CALLBACK, cb);
}

bool SetGeometry(retro_system_av_info* cb) {
    return environ_cb(RETRO_ENVIRONMENT_SET_GEOMETRY, cb);
}

bool SetInputDescriptors(const retro_input_descriptor desc[]) {
59
    return environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, (void*)desc);
James's avatar
James committed
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
}

bool HasUpdatedConfig() {
    bool updated = false;
    return environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated;
}

bool Shutdown() {
    return environ_cb(RETRO_ENVIRONMENT_SHUTDOWN, NULL);
}

/// Displays the specified message to the screen.
bool DisplayMessage(const char* sg) {
    retro_message msg;
    msg.msg = sg;
75
    msg.frames = 60 * 10;
James's avatar
James committed
76
77
78
79
    return environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, &msg);
}

std::string FetchVariable(std::string key, std::string def) {
80
    struct retro_variable var = {nullptr};
James's avatar
James committed
81
    var.key = key.c_str();
82
    if (!environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value == nullptr) {
James's avatar
James committed
83
        // Fetching variable failed.
Libretro-Admin's avatar
Libretro-Admin committed
84
        LOG_ERROR(Frontend, "Fetching variable %s failed.", key.c_str());
James's avatar
James committed
85
86
87
88
89
        return def;
    }
    return std::string(var.value);
}

90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
std::string GetSaveDir() {
    char* var = nullptr;
    if (!environ_cb(RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY, &var) || var == nullptr) {
        // Fetching variable failed.
        LOG_ERROR(Frontend, "No save directory provided by LibRetro.");
        return std::string();
    }
    return std::string(var);
}

std::string GetSystemDir() {
    char* var = nullptr;
    if (!environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &var) || var == nullptr) {
        // Fetching variable failed.
        LOG_ERROR(Frontend, "No system directory provided by LibRetro.");
        return std::string();
    }
    return std::string(var);
}

110
int16_t CheckInput(unsigned port, unsigned device, unsigned index, unsigned id) {
James's avatar
James committed
111
112
    return input_state_cb(port, device, index, id);
}
James's avatar
James committed
113
114
};

115
void retro_get_system_info(struct retro_system_info* info) {
James's avatar
James committed
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
    memset(info, 0, sizeof(*info));
    info->library_name = "Citra";
    info->library_version = Common::g_scm_desc;
    info->need_fullpath = true;
    info->valid_extensions = "3ds|3dsx|cia|elf";
}

void retro_set_audio_sample(retro_audio_sample_t cb) {
    // We don't need single audio sample callbacks.
}

void retro_set_input_poll(retro_input_poll_t cb) {
    LibRetro::input_poll_cb = cb;
}

void retro_set_video_refresh(retro_video_refresh_t cb) {
    LibRetro::video_cb = cb;
}
void retro_set_environment(retro_environment_t cb) {
    LibRetro::environ_cb = cb;
    LibRetro::OnConfigureEnvironment();
}

void retro_set_controller_port_device(unsigned port, unsigned device) {}

James's avatar
James committed
141
142
143
144
void retro_set_input_state(retro_input_state_t cb) {
    input_state_cb = cb;
}

James's avatar
James committed
145
void retro_get_system_av_info(struct retro_system_av_info* info) {
James's avatar
James committed
146
147
    // These are placeholders until we get control.
    info->timing.fps = 60.0;
148
    info->timing.sample_rate = 32728;
James's avatar
James committed
149
150
151
152
153
    info->geometry.base_width = 400;
    info->geometry.base_height = 480;
    info->geometry.max_width = 400 * 10;
    info->geometry.max_height = 480 * 10;
    info->geometry.aspect_ratio = 0;
Libretro-Admin's avatar
Libretro-Admin committed
154
}