1 #ifdef CORETYPE_GAMBATTE
8 #include "core/audioapi.hpp"
9 #include "core/misc.hpp"
10 #include "core/emucore.hpp"
11 #include "core/command.hpp"
12 #include "core/controllerframe.hpp"
13 #include "core/dispatch.hpp"
14 #include "core/framebuffer.hpp"
15 #include "core/window.hpp"
16 #include "library/pixfmt-rgb32.hpp"
17 #include "library/string.hpp"
18 #include "library/serialization.hpp"
19 #include "library/minmax.hpp"
20 #include "library/framebuffer.hpp"
22 #include "libgambatte/include/gambatte.h"
24 #define SAMPLES_PER_FRAME 35112
26 #define LOGICAL_BUTTON_LEFT 0
27 #define LOGICAL_BUTTON_RIGHT 1
28 #define LOGICAL_BUTTON_UP 2
29 #define LOGICAL_BUTTON_DOWN 3
30 #define LOGICAL_BUTTON_A 4
31 #define LOGICAL_BUTTON_B 5
32 #define LOGICAL_BUTTON_SELECT 6
33 #define LOGICAL_BUTTON_START 7
35 const char* button_symbols
= "ABsSrlud";
39 int regions_compatible(unsigned rom
, unsigned run
)
44 unsigned header_fn(size_t r
)
50 core_type
* internal_rom
= NULL
;
51 extern core_type type_dmg
;
52 extern core_type type_gbc
;
53 extern core_type type_gbc_gba
;
56 gambatte::GB
* instance
;
57 unsigned frame_overflow
= 0;
58 std::vector
<unsigned char> romdata
;
59 uint32_t primary_framebuffer
[160*144];
60 uint32_t norom_framebuffer
[160*144];
61 uint32_t accumulator_l
= 0;
62 uint32_t accumulator_r
= 0;
63 unsigned accumulator_s
= 0;
65 void init_norom_framebuffer()
67 static bool done
= false;
71 for(size_t i
= 0; i
< 160 * 144; i
++)
72 norom_framebuffer
[i
] = 0xFF8080;
80 return ecore_callbacks
->get_time();
85 class myinput
: public gambatte::InputGetter
91 for(unsigned i
= 0; i
< 8; i
++) {
92 int_pflag
= int_pflag
? int_pflag
: 1;
93 if(ecore_callbacks
->get_input(0, 0, i
))
100 int load_rom_common(core_romimage
* img
, unsigned flags
, uint64_t rtc_sec
, uint64_t rtc_subsec
,
103 const char* markup
= img
[0].markup
;
106 flags2
= atoi(markup
);
110 const unsigned char* data
= img
[0].data
;
111 size_t size
= img
[0].size
;
115 memset(instance
, 0, sizeof(gambatte::GB
));
116 new(instance
) gambatte::GB
;
117 instance
->setInputGetter(&getinput
);
118 instance
->set_walltime_fn(walltime_fn
);
119 memset(primary_framebuffer
, 0, sizeof(primary_framebuffer
));
123 rtc_fixed_val
= rtc_sec
;
124 instance
->load(data
, size
, flags
);
126 romdata
.resize(size
);
127 memcpy(&romdata
[0], data
, size
);
128 internal_rom
= inttype
;
132 int load_rom_dmg(core_romimage
* img
, uint64_t rtc_sec
, uint64_t rtc_subsec
)
134 return load_rom_common(img
, gambatte::GB::FORCE_DMG
, rtc_sec
, rtc_subsec
, &type_dmg
);
137 int load_rom_gbc(core_romimage
* img
, uint64_t rtc_sec
, uint64_t rtc_subsec
)
139 return load_rom_common(img
, 0, rtc_sec
, rtc_subsec
, &type_gbc
);
142 int load_rom_gbc_gba(core_romimage
* img
, uint64_t rtc_sec
, uint64_t rtc_subsec
)
144 return load_rom_common(img
, gambatte::GB::GBA_CGB
, rtc_sec
, rtc_subsec
, &type_gbc_gba
);
147 uint64_t magic
[4] = {35112, 2097152, 16742706, 626688};
149 core_region
region_world("world", "World", 0, 0, false, magic
, regions_compatible
);
150 core_romimage_info
image_rom_dmg("rom", "Cartridge ROM", 1, header_fn
);
151 core_romimage_info
image_rom_gbc("rom", "Cartridge ROM", 1, header_fn
);
152 core_romimage_info
image_rom_gbca("rom", "Cartridge ROM", 1, header_fn
);
153 core_type
type_dmg("dmg", "Game Boy", 1, load_rom_dmg
, "gb;dmg");
154 core_type
type_gbc("gbc", "Game Boy Color", 0, load_rom_gbc
, "gbc;cgb");
155 core_type
type_gbc_gba("gbc_gba", "Game Boy Color (GBA)", 2, load_rom_gbc_gba
, "");
156 core_type_region_bind
bind_A(type_dmg
, region_world
);
157 core_type_region_bind
bind_B(type_gbc
, region_world
);
158 core_type_region_bind
bind_C(type_gbc_gba
, region_world
);
159 core_type_image_bind
bind_D(type_dmg
, image_rom_dmg
, 0);
160 core_type_image_bind
bind_E(type_gbc
, image_rom_gbc
, 0);
161 core_type_image_bind
bind_F(type_gbc_gba
, image_rom_gbca
, 0);
162 core_sysregion
sr1("gdmg", type_dmg
, region_world
);
163 core_sysregion
sr2("ggbc", type_gbc
, region_world
);
164 core_sysregion
sr3("ggbca", type_gbc_gba
, region_world
);
166 const char* buttonnames
[] = {"left", "right", "up", "down", "A", "B", "select", "start"};
168 void _set_core_controller(unsigned port
) throw() {}
170 int get_button_id_gamepad(unsigned controller
, unsigned lbid
) throw()
174 if(lbid
== LOGICAL_BUTTON_A
) return 0;
175 if(lbid
== LOGICAL_BUTTON_B
) return 1;
176 if(lbid
== LOGICAL_BUTTON_SELECT
) return 2;
177 if(lbid
== LOGICAL_BUTTON_START
) return 3;
178 if(lbid
== LOGICAL_BUTTON_RIGHT
) return 4;
179 if(lbid
== LOGICAL_BUTTON_LEFT
) return 5;
180 if(lbid
== LOGICAL_BUTTON_UP
) return 6;
181 if(lbid
== LOGICAL_BUTTON_DOWN
) return 7;
186 int get_button_id_none(unsigned controller
, unsigned lbid
) throw()
191 struct porttype_gamepad
: public porttype_info
193 porttype_gamepad() : porttype_info("gamepad", "Gamepad", 1, generic_port_size
<1, 0, 8>())
195 write
= generic_port_write
<1, 0, 8>;
196 read
= generic_port_read
<1, 0, 8>;
197 display
= generic_port_display
<1, 0, 8, 0>;
198 serialize
= generic_port_serialize
<1, 0, 8, 0>;
199 deserialize
= generic_port_deserialize
<1, 0, 8>;
200 legal
= generic_port_legal
<1>;
201 deviceflags
= generic_port_deviceflags
<1, 1>;
202 button_id
= get_button_id_gamepad
;
203 ctrlname
= "gamepad";
205 set_core_controller
= _set_core_controller
;
210 struct porttype_none
: public porttype_info
212 porttype_none() : porttype_info("none", "None", 0, generic_port_size
<0, 0, 0>())
214 write
= generic_port_write
<0, 0, 0>;
215 read
= generic_port_read
<0, 0, 0>;
216 display
= generic_port_display
<0, 0, 0, 0>;
217 serialize
= generic_port_serialize
<0, 0, 0, 0>;
218 deserialize
= generic_port_deserialize
<0, 0, 0>;
219 legal
= generic_port_legal
<2>;
220 deviceflags
= generic_port_deviceflags
<0, 0>;
221 button_id
= get_button_id_none
;
224 set_core_controller
= _set_core_controller
;
230 std::string
get_logical_button_name(unsigned lbid
) throw(std::bad_alloc
)
232 if(lbid
>= sizeof(buttonnames
) / sizeof(buttonnames
[0]))
234 return buttonnames
[lbid
];
237 uint32_t get_snes_cpu_rate() { return 0; }
238 uint32_t get_snes_apu_rate() { return 0; }
239 std::string
get_core_identifier()
241 return "libgambatte "+gambatte::GB::version();
244 std::pair
<unsigned, unsigned> get_core_logical_controller_limits()
246 return std::make_pair(1, 8);
249 bool get_core_need_analog()
254 std::string
get_core_default_port(unsigned port
)
256 return (port
== 0) ? "gamepad" : "none";
259 core_region
& core_get_region()
264 std::pair
<uint32_t, uint32_t> get_video_rate()
266 return std::make_pair(262144, 4389);
269 std::pair
<uint32_t, uint32_t> get_audio_rate()
271 return std::make_pair(32768, 1);
274 bool core_set_region(core_region
& region
)
276 return (®ion
== ®ion_world
);
279 std::pair
<bool, uint32_t> core_emulate_cycles(uint32_t cycles
)
281 messages
<< "Delayed resets are not supported";
282 return std::make_pair(false, 0);
285 void core_runtosave()
296 void do_basic_core_init()
298 instance
= new gambatte::GB
;
299 instance
->setInputGetter(&getinput
);
300 instance
->set_walltime_fn(walltime_fn
);
307 void core_unload_cartridge()
311 void set_preload_settings()
315 void core_install_handler()
319 void core_uninstall_handler()
323 void core_emulate_frame_nocore()
325 init_norom_framebuffer();
327 int16_t soundbuf
[(SAMPLES_PER_FRAME
+ 63) / 32];
329 unsigned samples_emitted
= SAMPLES_PER_FRAME
- frame_overflow
;
330 for(unsigned i
= 0; i
< samples_emitted
; i
++) {
331 accumulator_l
+= 32768;
332 accumulator_r
+= 32768;
334 if((accumulator_s
& 63) == 0) {
335 int16_t l2
= (accumulator_l
>> 6) - 32768;
336 int16_t r2
= (accumulator_r
>> 6) - 32768;
337 soundbuf
[emitted
++] = l2
;
338 soundbuf
[emitted
++] = r2
;
339 information_dispatch::do_sample(l2
, r2
);
340 accumulator_l
= accumulator_r
= 0;
344 audioapi_submit_buffer(soundbuf
, emitted
/ 2, true, 32768);
345 ecore_callbacks
->timer_tick(samples_emitted
, 2097152);
349 framebuffer_info inf
;
350 inf
.type
= &_pixel_format_rgb32
;
351 inf
.mem
= const_cast<char*>(reinterpret_cast<const char*>(norom_framebuffer
));
353 inf
.physheight
= 144;
354 inf
.physstride
= 640;
361 framebuffer_raw
ls(inf
);
362 ecore_callbacks
->output_frame(ls
, 262144, 4389);
364 void core_emulate_frame()
367 core_emulate_frame_nocore();
370 uint32_t samplebuffer
[SAMPLES_PER_FRAME
+ 2064];
372 int16_t soundbuf
[(SAMPLES_PER_FRAME
+ 63) / 32 + 66];
374 unsigned samples_emitted
= SAMPLES_PER_FRAME
- frame_overflow
;
375 long ret
= instance
->runFor(primary_framebuffer
, 160, samplebuffer
, samples_emitted
);
376 for(unsigned i
= 0; i
< samples_emitted
; i
++) {
377 uint32_t l
= (int32_t)(int16_t)(samplebuffer
[i
]) + 32768;
378 uint32_t r
= (int32_t)(int16_t)(samplebuffer
[i
] >> 16) + 32768;
382 if((accumulator_s
& 63) == 0) {
383 int16_t l2
= (accumulator_l
>> 6) - 32768;
384 int16_t r2
= (accumulator_r
>> 6) - 32768;
385 soundbuf
[emitted
++] = l2
;
386 soundbuf
[emitted
++] = r2
;
387 information_dispatch::do_sample(l2
, r2
);
388 accumulator_l
= accumulator_r
= 0;
392 audioapi_submit_buffer(soundbuf
, emitted
/ 2, true, 32768);
393 ecore_callbacks
->timer_tick(samples_emitted
, 2097152);
394 frame_overflow
+= samples_emitted
;
395 if(frame_overflow
>= SAMPLES_PER_FRAME
) {
396 frame_overflow
-= SAMPLES_PER_FRAME
;
400 framebuffer_info inf
;
401 inf
.type
= &_pixel_format_rgb32
;
402 inf
.mem
= const_cast<char*>(reinterpret_cast<const char*>(primary_framebuffer
));
404 inf
.physheight
= 144;
405 inf
.physstride
= 640;
412 framebuffer_raw
ls(inf
);
413 ecore_callbacks
->output_frame(ls
, 262144, 4389);
416 std::list
<vma_info
> get_vma_list()
418 std::list
<vma_info
> vmas
;
427 auto g
= instance
->getSaveRam();
430 sram
.size
= g
.second
;
431 sram
.backing_ram
= g
.first
;
432 sram
.native_endian
= false;
433 sram
.readonly
= false;
434 sram
.iospace_rw
= NULL
;
436 auto g2
= instance
->getWorkRam();
439 wram
.size
= g2
.second
;
440 wram
.backing_ram
= g2
.first
;
441 wram
.native_endian
= false;
442 wram
.readonly
= false;
443 wram
.iospace_rw
= NULL
;
445 auto g3
= instance
->getVideoRam();
448 vram
.size
= g3
.second
;
449 vram
.backing_ram
= g3
.first
;
450 vram
.native_endian
= false;
451 vram
.readonly
= false;
452 vram
.iospace_rw
= NULL
;
454 auto g4
= instance
->getIoRam();
455 ioamhram
.name
= "IOAMHRAM";
456 ioamhram
.base
= 0x18000;
457 ioamhram
.size
= g4
.second
;
458 ioamhram
.backing_ram
= g4
.first
;
459 ioamhram
.native_endian
= false;
460 ioamhram
.readonly
= false;
461 ioamhram
.iospace_rw
= NULL
;
464 rom
.base
= 0x80000000;
465 rom
.size
= romdata
.size();
466 rom
.backing_ram
= (void*)&romdata
[0];
467 rom
.native_endian
= false;
469 rom
.iospace_rw
= NULL
;
472 vmas
.push_back(sram
);
473 vmas
.push_back(wram
);
475 vmas
.push_back(vram
);
476 vmas
.push_back(ioamhram
);
480 std::set
<std::string
> get_sram_set()
482 std::set
<std::string
> s
;
485 auto g
= instance
->getSaveRam();
492 std::map
<std::string
, std::vector
<char>> save_sram() throw(std::bad_alloc
)
494 std::map
<std::string
, std::vector
<char>> s
;
497 auto g
= instance
->getSaveRam();
498 s
["main"].resize(g
.second
);
499 memcpy(&s
["main"][0], g
.first
, g
.second
);
501 time_t timebase
= instance
->getRtcBase();
502 for(size_t i
= 0; i
< 8; i
++)
503 s
["rtc"][i
] = ((unsigned long long)timebase
>> (8 * i
));
507 void load_sram(std::map
<std::string
, std::vector
<char>>& sram
) throw(std::bad_alloc
)
511 std::vector
<char> x
= sram
.count("main") ? sram
["main"] : std::vector
<char>();
512 std::vector
<char> x2
= sram
.count("rtc") ? sram
["rtc"] : std::vector
<char>();
513 auto g
= instance
->getSaveRam();
515 if(x
.size() != g
.second
)
516 messages
<< "WARNING: SRAM 'main': Loaded " << x
.size()
517 << " bytes, but the SRAM is " << g
.second
<< "." << std::endl
;
518 memcpy(g
.first
, &x
[0], min(x
.size(), g
.second
));
522 for(size_t i
= 0; i
< 8 && i
< x2
.size(); i
++)
523 timebase
|= (unsigned long long)(unsigned char)x2
[i
] << (8 * i
);
524 instance
->setRtcBase(timebase
);
528 unsigned core_get_poll_flag()
533 void core_set_poll_flag(unsigned pflag
)
539 std::vector
<char> cmp_save
;
541 function_ptr_command
<> cmp_save1("set-cmp-save", "", "\n", []() throw(std::bad_alloc
, std::runtime_error
) {
544 instance
->saveState(cmp_save
);
547 function_ptr_command
<> cmp_save2("do-cmp-save", "", "\n", []() throw(std::bad_alloc
, std::runtime_error
) {
551 instance
->saveState(x
, cmp_save
);
554 void core_serialize(std::vector
<char>& out
)
557 throw std::runtime_error("Can't save without ROM");
558 instance
->saveState(out
);
559 size_t osize
= out
.size();
560 out
.resize(osize
+ 4 * sizeof(primary_framebuffer
) / sizeof(primary_framebuffer
[0]));
561 for(size_t i
= 0; i
< sizeof(primary_framebuffer
) / sizeof(primary_framebuffer
[0]); i
++)
562 write32ube(&out
[osize
+ 4 * i
], primary_framebuffer
[i
]);
563 out
.push_back(frame_overflow
>> 8);
564 out
.push_back(frame_overflow
);
567 void core_unserialize(const char* in
, size_t insize
)
570 throw std::runtime_error("Can't load without ROM");
571 size_t foffset
= insize
- 2 - 4 * sizeof(primary_framebuffer
) / sizeof(primary_framebuffer
[0]);
572 std::vector
<char> tmp
;
574 memcpy(&tmp
[0], in
, foffset
);
575 instance
->loadState(tmp
);
576 for(size_t i
= 0; i
< sizeof(primary_framebuffer
) / sizeof(primary_framebuffer
[0]); i
++)
577 primary_framebuffer
[i
] = read32ube(&in
[foffset
+ 4 * i
]);
579 unsigned x1
= (unsigned char)in
[insize
- 2];
580 unsigned x2
= (unsigned char)in
[insize
- 1];
581 frame_overflow
= x1
* 256 + x2
;
584 std::pair
<uint32_t, uint32_t> get_scale_factors(uint32_t width
, uint32_t height
)
586 return std::make_pair(max(512 / width
, (uint32_t)1), max(448 / height
, (uint32_t)1));
589 std::pair
<uint64_t, uint64_t> core_get_bus_map()
591 return std::make_pair(0, 0);
594 emucore_callbacks::~emucore_callbacks() throw() {}
596 struct emucore_callbacks
* ecore_callbacks
;