-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy pathhoja_frontend.c
More file actions
291 lines (246 loc) · 7.36 KB
/
Copy pathhoja_frontend.c
File metadata and controls
291 lines (246 loc) · 7.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
#include "hoja_frontend.h"
// Private variables
TaskHandle_t hoja_button_taskhandle = NULL;
hoja_core_t hoja_current_core = HOJA_CORE_NULL;
hoja_status_t hoja_current_status = HOJA_STATUS_IDLE;
bool _hoja_force_wired = false;
/**
* @brief Initialize HOJA library. Register any callbacks before calling this function.
*/
hoja_err_t hoja_init()
{
const char* TAG = "hoja_init";
esp_err_t ret;
if (hoja_current_status == HOJA_STATUS_INITIALIZED)
{
ESP_LOGE(TAG, "API is already initialized.");
return HOJA_FAIL;
}
if (hoja_current_status == HOJA_STATUS_RUNNING)
{
ESP_LOGE(TAG, "API is running a core already.");
return HOJA_FAIL;
}
bool fail = false;
if (hoja_button_cb == NULL)
{
fail = true;
ESP_LOGE(TAG, "hoja_button_cb is not registered!");
}
if (hoja_analog_cb == NULL)
{
fail = true;
ESP_LOGE(TAG, "hoja_analog_cb is not registered!");
}
if (hoja_event_cb == NULL)
{
fail = true;
ESP_LOGE(TAG, "hoja_event_cb is not registered!");
}
if (fail)
{
return HOJA_FAIL;
}
// Initialize NVS
ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK( ret );
if (hoja_settings_init() != HOJA_OK)
{
ESP_LOGE(TAG, "Settings failed to load.");
return HOJA_FAIL;
}
if (hoja_button_taskhandle != NULL)
{
vTaskDelete(hoja_button_taskhandle);
}
// We need to start the button scan task.
xTaskCreatePinnedToCore(hoja_button_task, "HOJA Button Task", 2048, NULL, 0, &hoja_button_taskhandle, HOJA_INPUT_CPU);
hoja_current_status = HOJA_STATUS_INITIALIZED;
ESP_LOGI(TAG, "HOJA initialized.");
hoja_event_cb(HOJA_EVT_SYSTEM, HEVT_API_INIT_OK, 0x00);
return HOJA_OK;
}
/**
* @brief Set the core used by HOJA.
* @param core Type of hoja_core_t
*/
hoja_err_t hoja_set_core(hoja_core_t core)
{
const char* TAG = "hoja_set_core";
if (core >= HOJA_CORE_MAX)
{
ESP_LOGE(TAG, "Core type is invalid!");
return HOJA_FAIL;
}
if (!core)
{
ESP_LOGE(TAG, "Core type is null!");
return HOJA_FAIL;
}
if (hoja_current_status == HOJA_STATUS_RUNNING)
{
ESP_LOGE(TAG, "Cannot set core while another core is running!");
return HOJA_FAIL;
}
hoja_current_core = core;
ESP_LOGI(TAG, "HOJA Core set.");
return HOJA_OK;
}
/**
* @brief Attempt to start the core specified by hoja_set_core
*/
hoja_err_t hoja_start_core(void)
{
char* TAG = "hoja_start_core";
hoja_err_t err = HOJA_FAIL;
switch(hoja_current_core)
{
case HOJA_CORE_NS:
ESP_LOGI(TAG, "Attempting Nintendo Switch Core start...");
err = core_ns_start();
break;
case HOJA_CORE_SNES:
ESP_LOGI(TAG, "Attempting SNES/NES Core start...");
err = core_snes_start();
break;
case HOJA_CORE_GC:
ESP_LOGI(TAG, "Attempting GameCube Core start...");
err = core_gamecube_start();
break;
case HOJA_CORE_USB:
ESP_LOGI(TAG, "Attempting USB Core start...");
err = core_usb_start();
break;
case HOJA_CORE_BT_DINPUT:
ESP_LOGI(TAG, "Attempting BT DInput Core start...");
err = core_bt_dinput_start();
break;
case HOJA_CORE_BT_XINPUT:
ESP_LOGI(TAG, "Attempting BT XInput Core start...");
err = core_bt_xinput_start();
break;
default:
// No core matches!
ESP_LOGE(TAG, "Specified core does not exist or isn't implemented yet.");
return HOJA_FAIL;
break;
}
if (err == HOJA_OK)
{
hoja_current_status = HOJA_STATUS_RUNNING;
}
return err;
}
/**
* @brief Attempt to stop the core that is currently running.
*/
void hoja_stop_core(void)
{
const char* TAG = "hoja_stop_core";
if (hoja_current_status != HOJA_STATUS_RUNNING)
{
ESP_LOGE(TAG, "Core needs to be running before you can stop it!");
return;
}
switch(hoja_current_core)
{
case HOJA_CORE_NS:
ESP_LOGI(TAG, "Attempting Nintendo Switch Core stop...");
core_ns_stop();
break;
case HOJA_CORE_SNES:
ESP_LOGI(TAG, "Attempting SNES/NES Core stop...");
core_snes_stop();
break;
case HOJA_CORE_GC:
ESP_LOGI(TAG, "Attempting GameCube Core stop...");
core_gamecube_stop();
break;
case HOJA_CORE_BT_DINPUT:
ESP_LOGI(TAG, "Attempting BT Dinput Core stop...");
core_bt_dinput_stop();
break;
case HOJA_CORE_BT_XINPUT:
ESP_LOGI(TAG, "Attempting BT Xinput Core stop...");
core_bt_xinput_stop();
break;
case HOJA_CORE_USB:
ESP_LOGI(TAG, "Attempting USB Core stop...");
core_usb_stop();
break;
default:
// No core matches!
ESP_LOGE(TAG, "Specified core does not exist or isn't implemented yet.");
return;
break;
}
hoja_current_status = HOJA_STATUS_INITIALIZED;
}
/**
* @brief Is called when button task is initiated by the API.
*
* @param *button_data Pointer to global button_data variable. Gets passed to callback function
* for modification of button inputs. Recommended to perform OR EQUALS on button_data members. Type of hoja_button_data_s
*/
hoja_button_callback_t hoja_button_cb = NULL;
/**
* @brief Is called when analog reading is initiated by the API.
*
* @param *analog_data Pointer to global analog_data variable. Gets passed to callback function
* for modification of analog inputs. Recommended to perform EQUALS on analog_data members. Type of hoja_analog_data_s
*/
hoja_analog_callback_t hoja_analog_cb = NULL;
/**
* @brief Is called when HOJA event is triggered by the API.
*
* @param type Type of hoja_event_type_t
* @param evt Event that occurred. See hoja_types.h for details on types for each category.
* @param param uint8_t type of data related to the event that occurred.
*/
hoja_event_callback_t hoja_event_cb = NULL;
/**
* @brief This will force the HOJA api to override the boot event for unplugged.
* This allows you to boot into wired modes even when you are in a wireless mode.
*/
void hoja_set_force_wired(bool enable)
{
_hoja_force_wired = enable;
}
/**
* @brief return the force wired status.
*/
bool hoja_get_force_wired(void)
{
return _hoja_force_wired;
}
/**
* @brief Register HOJA callback function for button input.
*/
hoja_err_t hoja_register_button_callback(hoja_button_callback_t func)
{
if (func == NULL) return HOJA_FAIL;
hoja_button_cb = func;
return HOJA_OK;
}
/**
* @brief Register HOJA callback function for analog input.
*/
hoja_err_t hoja_register_analog_callback(hoja_analog_callback_t func)
{
if (func == NULL) return HOJA_FAIL;
hoja_analog_cb = func;
return HOJA_OK;
}
/**
* @brief Register HOJA callback function for system, core, and utility events.
*/
hoja_err_t hoja_register_event_callback(hoja_event_callback_t func)
{
if (func == NULL) return HOJA_FAIL;
hoja_event_cb = func;
return HOJA_OK;
}