Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/quicknes/bizinterface.cpp
2 views
1
#include <cstdlib>
2
#include <cstring>
3
#include "nes_emu/Nes_Emu.h"
4
5
// simulate the write so we'll know how long the buffer needs to be
6
class Sim_Writer : public Data_Writer
7
{
8
long size_;
9
public:
10
Sim_Writer():size_(0) { }
11
error_t write(const void *, long size)
12
{
13
size_ += size;
14
return 0;
15
}
16
long size() const { return size_; }
17
};
18
19
// 0 filled new just for kicks
20
void *operator new(std::size_t n)
21
{
22
if (!n)
23
n = 1;
24
void *p = std::malloc(n);
25
std::memset(p, 0, n);
26
return p;
27
}
28
29
void operator delete(void *p)
30
{
31
std::free(p);
32
}
33
34
#ifdef _MSC_VER
35
#define EXPORT extern "C" __declspec(dllexport)
36
#else
37
#define EXPORT extern "C" __declspec(dllexport) __attribute__((force_align_arg_pointer))
38
#endif
39
40
EXPORT void qn_setup_mappers()
41
{
42
register_optional_mappers();
43
}
44
45
EXPORT Nes_Emu *qn_new()
46
{
47
return new Nes_Emu();
48
}
49
50
EXPORT void qn_delete(Nes_Emu *e)
51
{
52
delete e;
53
}
54
55
EXPORT const char *qn_loadines(Nes_Emu *e, const void *data, int length)
56
{
57
Mem_File_Reader r(data, length);
58
Auto_File_Reader a(r);
59
return e->load_ines(a);
60
}
61
62
EXPORT const char *qn_set_sample_rate(Nes_Emu *e, int rate)
63
{
64
const char *ret = e->set_sample_rate(rate);
65
if (!ret)
66
e->set_equalizer(Nes_Emu::nes_eq);
67
return ret;
68
}
69
70
EXPORT const char *qn_emulate_frame(Nes_Emu *e, int pad1, int pad2)
71
{
72
return e->emulate_frame(pad1, pad2);
73
}
74
75
EXPORT void qn_blit(Nes_Emu *e, int32_t *dest, const int32_t *colors, int cropleft, int croptop, int cropright, int cropbottom)
76
{
77
// what is the point of the 256 color bitmap and the dynamic color allocation to it?
78
// why not just render directly to a 512 color bitmap with static palette positions?
79
80
const int srcpitch = e->frame().pitch;
81
const unsigned char *src = e->frame().pixels;
82
const unsigned char *const srcend = src + (e->image_height - cropbottom) * srcpitch;
83
84
const short *lut = e->frame().palette;
85
86
const int rowlen = 256 - cropleft - cropright;
87
88
src += cropleft;
89
src += croptop * srcpitch;
90
91
for (; src < srcend; src += srcpitch)
92
{
93
for (int i = 0; i < rowlen; i++)
94
{
95
*dest++ = colors[lut[src[i]]];
96
}
97
}
98
}
99
100
EXPORT const Nes_Emu::rgb_t *qn_get_default_colors()
101
{
102
return Nes_Emu::nes_colors;
103
}
104
105
EXPORT int qn_get_joypad_read_count(Nes_Emu *e)
106
{
107
return e->frame().joypad_read_count;
108
}
109
110
EXPORT void qn_get_audio_info(Nes_Emu *e, int *sample_count, int *chan_count)
111
{
112
if (sample_count)
113
*sample_count = e->frame().sample_count;
114
if (chan_count)
115
*chan_count = e->frame().chan_count;
116
}
117
118
EXPORT int qn_read_audio(Nes_Emu *e, short *dest, int max_samples)
119
{
120
return e->read_samples(dest, max_samples);
121
}
122
123
EXPORT void qn_reset(Nes_Emu *e, int hard)
124
{
125
e->reset(hard);
126
}
127
128
EXPORT const char *qn_state_size(Nes_Emu *e, int *size)
129
{
130
Sim_Writer w;
131
Auto_File_Writer a(w);
132
const char *ret = e->save_state(a);
133
if (size)
134
*size = w.size();
135
return ret;
136
}
137
138
EXPORT const char *qn_state_save(Nes_Emu *e, void *dest, int size)
139
{
140
Mem_Writer w(dest, size, 0);
141
Auto_File_Writer a(w);
142
const char *ret = e->save_state(a);
143
if (!ret && w.size() != size)
144
return "Buffer Underrun!";
145
return ret;
146
}
147
148
EXPORT const char *qn_state_load(Nes_Emu *e, const void *src, int size)
149
{
150
Mem_File_Reader r(src, size);
151
Auto_File_Reader a(r);
152
return e->load_state(a);
153
}
154
155
EXPORT int qn_has_battery_ram(Nes_Emu *e)
156
{
157
return e->has_battery_ram();
158
}
159
160
EXPORT const char *qn_battery_ram_size(Nes_Emu *e, int *size)
161
{
162
Sim_Writer w;
163
Auto_File_Writer a(w);
164
const char *ret = e->save_battery_ram(a);
165
if (size)
166
*size = w.size();
167
return ret;
168
}
169
170
EXPORT const char *qn_battery_ram_save(Nes_Emu *e, void *dest, int size)
171
{
172
Mem_Writer w(dest, size, 0);
173
Auto_File_Writer a(w);
174
const char *ret = e->save_battery_ram(a);
175
if (!ret && w.size() != size)
176
return "Buffer Underrun!";
177
return ret;
178
}
179
180
EXPORT const char *qn_battery_ram_load(Nes_Emu *e, const void *src, int size)
181
{
182
Mem_File_Reader r(src, size);
183
Auto_File_Reader a(r);
184
return e->load_battery_ram(a);
185
}
186
187
EXPORT const char *qn_battery_ram_clear(Nes_Emu *e)
188
{
189
int size = 0;
190
const char *ret = qn_battery_ram_size(e, &size);
191
if (ret)
192
return ret;
193
void *data = std::malloc(size);
194
if (!data)
195
return "Out of Memory!";
196
std::memset(data, 0xff, size);
197
ret = qn_battery_ram_load(e, data, size);
198
std::free(data);
199
return ret;
200
}
201
202
EXPORT void qn_set_sprite_limit(Nes_Emu *e, int n)
203
{
204
e->set_sprite_mode((Nes_Emu::sprite_mode_t)n);
205
}
206
207
EXPORT int qn_get_memory_area(Nes_Emu *e, int which, const void **data, int *size, int *writable, const char **name)
208
{
209
if (!data || !size || !writable || !name)
210
return 0;
211
switch (which)
212
{
213
default:
214
return 0;
215
case 0:
216
*data = e->low_mem();
217
*size = e->low_mem_size;
218
*writable = 1;
219
*name = "RAM";
220
return 1;
221
case 1:
222
*data = e->high_mem();
223
*size = e->high_mem_size;
224
*writable = 1;
225
*name = "WRAM";
226
return 1;
227
case 2:
228
*data = e->chr_mem();
229
*size = e->chr_size();
230
*writable = 0;
231
*name = "CHR";
232
return 1;
233
case 3:
234
*data = e->nametable_mem();
235
*size = e->nametable_size();
236
*writable = 0;
237
*name = "CIRAM (nametables)";
238
return 1;
239
case 4:
240
*data = e->cart()->prg();
241
*size = e->cart()->prg_size();
242
*writable = 0;
243
*name = "PRG ROM";
244
return 1;
245
case 5:
246
*data = e->cart()->chr();
247
*size = e->cart()->chr_size();
248
*writable = 0;
249
*name = "CHR VROM";
250
return 1;
251
case 6:
252
*data = e->pal_mem();
253
*size = 32;
254
*writable = 1;
255
*name = "PALRAM";
256
return 1;
257
case 7:
258
*data = e->oam_mem();
259
*size = 256;
260
*writable = 1;
261
*name = "OAM";
262
return 1;
263
}
264
}
265
266
EXPORT unsigned char qn_peek_prgbus(Nes_Emu *e, int addr)
267
{
268
return e->peek_prg(addr & 0xffff);
269
}
270
271
EXPORT void qn_poke_prgbus(Nes_Emu *e, int addr, unsigned char val)
272
{
273
e->poke_prg(addr & 0xffff, val);
274
}
275
276
EXPORT void qn_get_cpuregs(Nes_Emu *e, unsigned int *dest)
277
{
278
e->get_regs(dest);
279
}
280
281
EXPORT const char *qn_get_mapper(Nes_Emu *e, int *number)
282
{
283
int m = e->cart()->mapper_code();
284
if (number)
285
*number = m;
286
switch (m)
287
{
288
default: return "unknown";
289
case 0: return "nrom";
290
case 1: return "mmc1";
291
case 2: return "unrom";
292
case 3: return "cnrom";
293
case 4: return "mmc3";
294
case 7: return "aorom";
295
case 69: return "fme7";
296
case 5: return "mmc5";
297
case 19: return "namco106";
298
case 24: return "vrc6a";
299
case 26: return "vrc6b";
300
case 11: return "color_dreams";
301
case 34: return "nina1";
302
case 66: return "gnrom";
303
case 87: return "mapper_87";
304
case 232: return "quattro";
305
case 9: return "mmc2";
306
case 10: return "mmc4";
307
}
308
}
309
310
EXPORT byte qn_get_reg2000(Nes_Emu *e)
311
{
312
return e->get_ppu2000();
313
}
314
315
EXPORT byte *qn_get_palmem(Nes_Emu *e)
316
{
317
return e->pal_mem();
318
}
319
320
EXPORT byte *qn_get_oammem(Nes_Emu *e)
321
{
322
return e->oam_mem();
323
}
324
325
EXPORT byte qn_peek_ppu(Nes_Emu *e, int addr)
326
{
327
return e->peek_ppu(addr);
328
}
329
330
EXPORT void qn_peek_ppubus(Nes_Emu *e, byte *dest)
331
{
332
for (int i = 0; i < 0x3000; i++)
333
dest[i] = e->peek_ppu(i);
334
}
335
336
EXPORT void qn_set_tracecb(Nes_Emu *e, void (*cb)(unsigned int *dest))
337
{
338
e->set_tracecb(cb);
339
}
340
341