Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libmeteor/cinterface.cpp
2 views
1
#include "ameteor.hpp"
2
#include "ameteor/cartmem.hpp"
3
#include "source/debug.hpp"
4
#include <sstream>
5
6
#define EXPORT extern "C" __declspec(dllexport)
7
8
void (*messagecallback)(const char *msg, int abort) = NULL;
9
10
EXPORT void libmeteor_setmessagecallback(void (*callback)(const char *msg, int abort))
11
{
12
messagecallback = callback;
13
print_bizhawk("libmeteor message stream operational.");
14
}
15
16
void print_bizhawk(const char *msg)
17
{
18
if (messagecallback)
19
messagecallback(msg, 0);
20
}
21
void print_bizhawk(std::string &msg)
22
{
23
if (messagecallback)
24
messagecallback(msg.c_str(), 0);
25
}
26
void abort_bizhawk(const char *msg)
27
{
28
if (messagecallback)
29
messagecallback(msg, 1);
30
AMeteor::Stop(); // makes it easy to pick apart what happened
31
}
32
33
uint16_t (*keycallback)() = NULL;
34
35
void keyupdate_bizhawk()
36
{
37
if (keycallback)
38
AMeteor::_keypad.SetPadState(keycallback() ^ 0x3FF);
39
}
40
41
EXPORT void libmeteor_setkeycallback(uint16_t (*callback)())
42
{
43
keycallback = callback;
44
}
45
46
bool traceenabled = false;
47
void (*tracecallback)(const char *msg) = NULL;
48
49
EXPORT void libmeteor_settracecallback(void (*callback)(const char*msg))
50
{
51
tracecallback = callback;
52
traceenabled = tracecallback != NULL;
53
}
54
55
void trace_bizhawk(std::string msg)
56
{
57
if (tracecallback)
58
tracecallback(msg.c_str());
59
}
60
61
EXPORT void libmeteor_hardreset()
62
{
63
AMeteor::Reset(AMeteor::UNIT_ALL ^ (AMeteor::UNIT_MEMORY_BIOS | AMeteor::UNIT_MEMORY_ROM));
64
}
65
66
uint32_t *videobuff;
67
68
void videocb(const uint16_t *frame)
69
{
70
uint32_t *dest = videobuff;
71
const uint16_t *src = frame;
72
for (int i = 0; i < 240 * 160; i++, src++, dest++)
73
{
74
uint16_t c = *src;
75
uint16_t b = c >> 10 & 31;
76
uint16_t g = c >> 5 & 31;
77
uint16_t r = c & 31;
78
b = b << 3 | b >> 2;
79
g = g << 3 | g >> 2;
80
r = r << 3 | r >> 2;
81
*dest = b | g << 8 | r << 16 | 0xff000000;
82
}
83
AMeteor::Stop(); // to the end of frame only
84
}
85
86
int16_t *soundbuff;
87
int16_t *soundbuffcur;
88
int16_t *soundbuffend;
89
90
void soundcb(const int16_t *samples)
91
{
92
if (soundbuffcur < soundbuffend)
93
{
94
*soundbuffcur++ = *samples++;
95
*soundbuffcur++ = *samples++;
96
}
97
}
98
99
EXPORT unsigned libmeteor_emptysound()
100
{
101
unsigned ret = (soundbuffcur - soundbuff) * sizeof(int16_t);
102
soundbuffcur = soundbuff;
103
return ret;
104
}
105
106
EXPORT int libmeteor_setbuffers(uint32_t *vid, unsigned vidlen, int16_t *aud, unsigned audlen)
107
{
108
if (vidlen < 240 * 160 * sizeof(uint32_t))
109
return 0;
110
if (audlen < 4 || audlen % 4 != 0)
111
return 0;
112
videobuff = vid;
113
soundbuff = aud;
114
soundbuffend = soundbuff + audlen / sizeof(int16_t);
115
libmeteor_emptysound();
116
return 1;
117
}
118
119
EXPORT void libmeteor_init()
120
{
121
static bool first = true;
122
if (first)
123
{
124
AMeteor::_lcd.GetScreen().GetRenderer().SetFrameSlot(syg::ptr_fun(videocb));
125
AMeteor::_sound.GetSpeaker().SetFrameSlot(syg::ptr_fun(soundcb));
126
first = false;
127
}
128
}
129
130
EXPORT void libmeteor_frameadvance()
131
{
132
AMeteor::Run(10000000);
133
}
134
135
EXPORT void libmeteor_loadrom(const void *data, unsigned size)
136
{
137
AMeteor::_memory.LoadRom((const uint8_t*)data, size);
138
}
139
140
EXPORT void libmeteor_loadbios(const void *data, unsigned size)
141
{
142
AMeteor::_memory.LoadBios((const uint8_t*)data, size);
143
}
144
145
EXPORT uint8_t *libmeteor_getmemoryarea(int which)
146
{
147
if (which < 7)
148
return AMeteor::_memory.GetMemoryArea(which);
149
else if (which == 7)
150
return AMeteor::_io.GetIoPointer();
151
else
152
return NULL;
153
}
154
155
EXPORT int libmeteor_loadsaveram(const void *data, unsigned size)
156
{
157
return AMeteor::_memory.LoadCart((const uint8_t*)data, size);
158
}
159
160
EXPORT int libmeteor_savesaveram(void **data, unsigned *size)
161
{
162
return AMeteor::_memory.SaveCart((uint8_t **)data, size);
163
}
164
165
EXPORT void libmeteor_savesaveram_destroy(void *data)
166
{
167
AMeteor::_memory.SaveCartDestroy((uint8_t *)data);
168
}
169
170
EXPORT int libmeteor_hassaveram()
171
{
172
return AMeteor::_memory.HasCart();
173
}
174
175
EXPORT void libmeteor_clearsaveram()
176
{
177
AMeteor::_memory.DeleteCart();
178
}
179
180
EXPORT int libmeteor_savestate(void **data, unsigned *size)
181
{
182
if (!data || !size)
183
return 0;
184
185
std::ostringstream ss = std::ostringstream(std::ios_base::binary);
186
AMeteor::SaveState(ss);
187
188
std::string s = ss.str();
189
190
void *ret = std::malloc(s.size());
191
if (!ret)
192
return 0;
193
std::memcpy(ret, s.data(), s.size());
194
*data = ret;
195
*size = s.size();
196
return 1;
197
}
198
199
EXPORT void libmeteor_savestate_destroy(void *data)
200
{
201
std::free(data);
202
}
203
204
EXPORT int libmeteor_loadstate(const void *data, unsigned size)
205
{
206
std::istringstream ss = std::istringstream(std::string((const char*)data, size), std::ios_base::binary);
207
return AMeteor::LoadState(ss);
208
}
209
210
// TODO: cartram memory domain, cartram in system bus memory domain
211
EXPORT uint8_t libmeteor_peekbus(uint32_t addr)
212
{
213
return AMeteor::_memory.Peek8(addr);
214
}
215
216
EXPORT void libmeteor_writebus(uint32_t addr, uint8_t val)
217
{
218
AMeteor::_memory.Write8(addr, val);
219
}
220
221
int slcallbackline = 400;
222
void (*slcallback)() = NULL;
223
224
EXPORT void libmeteor_setscanlinecallback(void (*callback)(), int scanline)
225
{
226
if (!callback)
227
slcallbackline = 400;
228
else
229
slcallbackline = scanline;
230
slcallback = callback;
231
}
232
233
void scanlinecallback_bizhawk()
234
{
235
if (slcallback)
236
slcallback();
237
}
238
239
EXPORT void libmeteor_getregs(int *dest)
240
{
241
AMeteor::_cpu.UpdateCpsr();
242
for (int i = 0; i < 16; i++)
243
dest[i] = AMeteor::_cpu.Reg(i);
244
dest[16] = AMeteor::_cpu.Cpsr().dw;
245
dest[17] = AMeteor::_cpu.Spsr().dw;
246
}
247
248