2017-06-13 22:02:52 +00:00
|
|
|
/*
|
|
|
|
|
|
|
|
This file is part of Emu-Pizza
|
|
|
|
|
|
|
|
Emu-Pizza is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
Emu-Pizza is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with Emu-Pizza. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <sys/types.h>
|
2017-06-18 20:05:33 +00:00
|
|
|
#include "../emulibc/emulibc.h"
|
|
|
|
#include "../emulibc/waterboxcore.h"
|
2017-06-15 23:00:41 +00:00
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#define EXPORT ECL_EXPORT
|
2017-06-13 22:02:52 +00:00
|
|
|
|
|
|
|
#include "cartridge.h"
|
|
|
|
#include "cycles.h"
|
|
|
|
#include "gameboy.h"
|
|
|
|
#include "global.h"
|
|
|
|
#include "gpu.h"
|
|
|
|
#include "input.h"
|
|
|
|
#include "sound.h"
|
|
|
|
#include "serial.h"
|
2017-06-15 23:00:41 +00:00
|
|
|
#include "utils.h"
|
|
|
|
#include "mmu.h"
|
2017-06-16 12:19:03 +00:00
|
|
|
#include "sound_output.h"
|
2017-06-19 00:35:55 +00:00
|
|
|
#include "sgb.h"
|
2017-06-13 22:02:52 +00:00
|
|
|
|
|
|
|
/* proto */
|
2017-06-16 13:20:35 +00:00
|
|
|
void frame_cb();
|
2017-06-13 22:02:52 +00:00
|
|
|
void connected_cb();
|
|
|
|
void disconnected_cb();
|
|
|
|
void rumble_cb(uint8_t rumble);
|
|
|
|
void network_send_data(uint8_t v);
|
|
|
|
void *start_thread(void *args);
|
|
|
|
void *start_thread_network(void *args);
|
|
|
|
|
|
|
|
/* cartridge name */
|
|
|
|
char cart_name[64];
|
|
|
|
|
2017-06-15 23:00:41 +00:00
|
|
|
int main(void)
|
2017-06-13 22:02:52 +00:00
|
|
|
{
|
2017-06-15 23:00:41 +00:00
|
|
|
}
|
2017-06-13 22:02:52 +00:00
|
|
|
|
2017-06-24 00:51:19 +00:00
|
|
|
EXPORT int Init(const void *rom, int romlen, int sgb, const void *spc, int spclen)
|
2017-06-15 23:00:41 +00:00
|
|
|
{
|
|
|
|
/* init global variables */
|
|
|
|
global_init();
|
2017-06-13 22:02:52 +00:00
|
|
|
|
2017-06-15 23:00:41 +00:00
|
|
|
/* first, load cartridge */
|
|
|
|
char ret = cartridge_load(rom, romlen);
|
2017-06-13 22:02:52 +00:00
|
|
|
|
2017-06-15 23:00:41 +00:00
|
|
|
if (ret != 0)
|
|
|
|
return 0; // failure
|
2017-06-19 00:35:55 +00:00
|
|
|
global_sgb = !!sgb;
|
|
|
|
if (global_sgb && global_cgb)
|
2017-07-02 01:02:52 +00:00
|
|
|
utils_log("Warn: CGB game in SGB mode\n");
|
2017-06-24 00:51:19 +00:00
|
|
|
if (sgb && !sgb_init((const uint8_t*)spc, spclen))
|
|
|
|
return 0;
|
2017-06-13 22:02:52 +00:00
|
|
|
|
2017-06-15 23:00:41 +00:00
|
|
|
gameboy_init();
|
2017-06-13 22:02:52 +00:00
|
|
|
|
2017-06-15 23:00:41 +00:00
|
|
|
/* init GPU */
|
2017-06-16 13:20:35 +00:00
|
|
|
gpu_init(frame_cb);
|
2017-06-13 22:02:52 +00:00
|
|
|
|
2017-06-15 23:00:41 +00:00
|
|
|
/* set rumble cb */
|
|
|
|
mmu_set_rumble_cb(&rumble_cb);
|
2017-06-13 22:02:52 +00:00
|
|
|
|
2017-06-19 00:35:55 +00:00
|
|
|
sound_output_init(global_sgb ? 2147727 : 2097152, 44100);
|
2017-06-16 12:19:03 +00:00
|
|
|
|
2017-06-15 23:00:41 +00:00
|
|
|
return 1;
|
|
|
|
}
|
2017-06-13 22:02:52 +00:00
|
|
|
|
2017-06-15 23:00:41 +00:00
|
|
|
typedef struct
|
2017-06-13 22:02:52 +00:00
|
|
|
{
|
2017-06-19 23:52:27 +00:00
|
|
|
uint32_t *VideoBuffer;
|
|
|
|
int16_t *SoundBuffer;
|
2017-06-18 20:05:33 +00:00
|
|
|
int64_t Cycles;
|
|
|
|
int32_t Width;
|
|
|
|
int32_t Height;
|
|
|
|
int32_t Samples;
|
|
|
|
int32_t Lagged;
|
2017-06-25 13:19:32 +00:00
|
|
|
int64_t Time;
|
2017-06-18 20:05:33 +00:00
|
|
|
uint32_t Keys;
|
|
|
|
} MyFrameInfo;
|
2017-06-13 22:02:52 +00:00
|
|
|
|
2017-06-19 23:52:27 +00:00
|
|
|
static uint32_t *current_vbuff;
|
2017-06-18 20:05:33 +00:00
|
|
|
static uint64_t overflow;
|
2017-06-15 23:00:41 +00:00
|
|
|
|
2017-06-19 23:52:27 +00:00
|
|
|
EXPORT void FrameAdvance(MyFrameInfo *frame)
|
2017-06-15 23:00:41 +00:00
|
|
|
{
|
2017-06-19 00:35:55 +00:00
|
|
|
if (global_sgb)
|
2017-06-19 23:52:27 +00:00
|
|
|
sgb_set_controller_data((uint8_t *)&frame->Keys);
|
2017-06-19 00:35:55 +00:00
|
|
|
else
|
|
|
|
input_set_keys(frame->Keys);
|
2017-06-18 20:05:33 +00:00
|
|
|
current_vbuff = frame->VideoBuffer;
|
2017-06-24 13:38:03 +00:00
|
|
|
global_lagged = 1;
|
2017-06-25 13:19:32 +00:00
|
|
|
global_currenttime = frame->Time;
|
2017-06-18 20:05:33 +00:00
|
|
|
|
2017-06-15 23:00:41 +00:00
|
|
|
uint64_t current = cycles.sampleclock;
|
2017-06-18 20:05:33 +00:00
|
|
|
uint64_t target = current + 35112 - overflow;
|
|
|
|
gameboy_run(target);
|
|
|
|
uint64_t elapsed = cycles.sampleclock - current;
|
|
|
|
frame->Cycles = elapsed;
|
|
|
|
overflow = cycles.sampleclock - target;
|
|
|
|
|
|
|
|
frame->Samples = sound_output_read(frame->SoundBuffer);
|
2017-06-19 23:52:27 +00:00
|
|
|
if (global_sgb)
|
|
|
|
{
|
|
|
|
frame->Width = 256;
|
|
|
|
frame->Height = 224;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
frame->Width = 160;
|
|
|
|
frame->Height = 144;
|
|
|
|
}
|
2017-06-24 13:38:03 +00:00
|
|
|
frame->Lagged = global_lagged;
|
2017-06-16 13:20:35 +00:00
|
|
|
current_vbuff = NULL;
|
2017-06-13 22:02:52 +00:00
|
|
|
}
|
|
|
|
|
2017-06-16 01:38:52 +00:00
|
|
|
EXPORT int IsCGB(void)
|
|
|
|
{
|
|
|
|
return global_cgb;
|
|
|
|
}
|
|
|
|
|
2017-06-18 20:05:33 +00:00
|
|
|
EXPORT void SetInputCallback(void (*callback)(void))
|
|
|
|
{
|
2017-06-24 13:38:03 +00:00
|
|
|
global_input_callback = callback;
|
2017-06-18 20:05:33 +00:00
|
|
|
}
|
|
|
|
|
2017-06-19 23:52:27 +00:00
|
|
|
EXPORT void GetMemoryAreas(MemoryArea *m)
|
2017-06-18 20:05:33 +00:00
|
|
|
{
|
|
|
|
m[0].Data = mmu.memory;
|
|
|
|
m[0].Name = "Fake System Bus";
|
|
|
|
m[0].Size = 0x10000;
|
|
|
|
m[0].Flags = MEMORYAREA_FLAGS_PRIMARY | MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_WORDSIZE1;
|
|
|
|
}
|
|
|
|
|
2017-06-25 01:46:11 +00:00
|
|
|
EXPORT int GetSaveramSize(void)
|
|
|
|
{
|
|
|
|
return mmu_saveram_size();
|
|
|
|
}
|
|
|
|
|
|
|
|
EXPORT void PutSaveram(const uint8_t* data, int size)
|
|
|
|
{
|
|
|
|
mmu_restore_saveram(data, size);
|
|
|
|
}
|
|
|
|
|
|
|
|
EXPORT void GetSaveram(uint8_t* data, int size)
|
|
|
|
{
|
|
|
|
mmu_save_saveram(data, size);
|
|
|
|
}
|
|
|
|
|
2017-06-16 13:20:35 +00:00
|
|
|
void frame_cb()
|
2017-06-13 22:02:52 +00:00
|
|
|
{
|
2017-06-19 23:52:27 +00:00
|
|
|
if (global_sgb)
|
|
|
|
{
|
|
|
|
sgb_render_frame(current_vbuff);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
memcpy(current_vbuff, gpu.frame_buffer, sizeof(gpu.frame_buffer));
|
|
|
|
}
|
2017-06-13 22:02:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void connected_cb()
|
|
|
|
{
|
2017-06-15 23:00:41 +00:00
|
|
|
utils_log("Connected\n");
|
2017-06-13 22:02:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void disconnected_cb()
|
|
|
|
{
|
2017-06-15 23:00:41 +00:00
|
|
|
utils_log("Disconnected\n");
|
2017-06-13 22:02:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void rumble_cb(uint8_t rumble)
|
|
|
|
{
|
2017-06-15 23:00:41 +00:00
|
|
|
if (rumble)
|
|
|
|
printf("RUMBLE\n");
|
2017-06-13 22:02:52 +00:00
|
|
|
}
|