MCUME/MCUME_pico2/picogb/emu.cpp

166 wiersze
4.1 KiB
C++
Czysty Zwykły widok Historia

2025-01-26 16:25:30 +00:00
#include <string.h>
#include "emuapi.h"
#include "iopins.h"
extern "C" {
#include "minigb_apu/minigb_apu.h"
#include "palettes/gbcolors.h"
#include "palettes/hedley.h"
#include "palettes/peanut_gb.h"
}
#include "flash_t.h"
static uint8_t ram[32768];
static gb_s gb;
static palette_t palette16; // Colour palette
#define RGB565_TO_RGB888(rgb565) ((((rgb565) & 0xF800) << 8) | (((rgb565) & 0x07E0) << 5) | (((rgb565) & 0x001F) << 3))
void gb_error(struct gb_s* gb, const enum gb_error_e gb_err, const uint16_t addr) {
const char* gb_err_str[4] = {
"UNKNOWN",
"INVALID OPCODE",
"INVALID READ",
"INVALID WRITE"
};
printf("Error %d occurred: %s at %04X\n.\n", gb_err, gb_err_str[gb_err], addr);
}
/**
* Returns a byte from the ROM file at the given address.
*/
uint8_t __not_in_flash_func(gb_rom_read)(struct gb_s* gb, const uint_fast32_t addr) {
return flash_start[addr];
}
/**
* Returns a byte from the cartridge RAM at the given address.
*/
uint8_t __not_in_flash_func(gb_cart_ram_read)(struct gb_s* gb, const uint_fast32_t addr) {
return ram[addr];
}
/**
* Writes a given byte to the cartridge RAM at the given address.
*/
void __not_in_flash_func(gb_cart_ram_write)(struct gb_s* gb, const uint_fast32_t addr, const uint8_t val) {
ram[addr] = val;
}
static uint8_t tmppixels[LCD_WIDTH];
/**
* Draws scanline into framebuffer.
*/
void __always_inline lcd_draw_line(struct gb_s* gb, const unsigned char *pixels, const uint_fast8_t y) {
if (gb->cgb.cgbMode) {
emu_DrawLinePal16((unsigned char *)&pixels[0], 160, 128, y);
}
else
{
for (unsigned int x = 0; x < LCD_WIDTH; x++)
tmppixels[x] = pixels[x] & 3; //(pixels[x] & LCD_PALETTE_ALL) >> 4;
emu_DrawLinePal16((unsigned char *)&tmppixels[0], 160, 128, y);
}
}
void gbc_Init(void)
{
emu_printf("gbc_Init");
emu_printf("gbc_Init done");
}
static int k = 0;
2025-03-30 13:36:21 +00:00
static int ihk = 0;
static int iusbhk; // USB keyboard key
void emu_KeyboardOnDown(int keymodifer, int key) {
if (key <= 0x7f) iusbhk = key;
//else if (key == KBD_KEY_UP) iusbhk = 0xD7;
//else if (key == KBD_KEY_LEFT) iusbhk = 0xD8;
//else if (key == KBD_KEY_RIGHT) iusbhk = 0xD9;
//else if (key == KBD_KEY_DOWN) iusbhk = 0xDA;
//else if (key == KBD_KEY_BS) iusbhk = 0x7F;
else
iusbhk = 0;
}
void emu_KeyboardOnUp(int keymodifer, int key) {
iusbhk = 0;
}
2025-01-26 16:25:30 +00:00
void gbc_Input(int click) {
2025-03-30 13:36:21 +00:00
ihk = emu_ReadI2CKeyboard();
2025-01-26 16:25:30 +00:00
k = emu_ReadKeys();
}
void gbc_Start(char * filename)
{
emu_printf("gbc_Start");
int size = flash_load(filename);
#ifdef SOUND_PRESENT
#ifdef HAS_SND
emu_sndInit();
#endif
#else
#endif
/* Initialise GB context. */
gb_init_error_e ret = gb_init(&gb, &gb_rom_read, &gb_cart_ram_read,
&gb_cart_ram_write, &gb_error, nullptr);
auto_assign_palette(palette16, gb_colour_hash(&gb), gb_get_rom_name(&gb, filename));
//manual_assign_palette(palette16, 0);
for (int i = 0; i < 3; i++)
for (int j = 0; j < 4; j++) {
uint32_t val = RGB565_TO_RGB888(palette16[i][j]);
emu_SetPaletteEntry(val>>16, (val>>8) & 0xff, val & 0xff, i * 4 + j);
}
gb_init_lcd(&gb, &lcd_draw_line);
emu_printf("gbc_Start done");
}
void gbc_Step(void) {
gb_run_frame(&gb);
2025-03-30 13:36:21 +00:00
int hk = ihk;
if (iusbhk) hk = iusbhk;
switch(hk) {
case '1':
k = MASK_KEY_USER1;
break;
case '2':
k = MASK_KEY_USER2;
break;
default:
break;
};
2025-01-26 16:25:30 +00:00
gb.direct.joypad_bits.up = !(( k & MASK_JOY1_UP) || ( k & MASK_JOY2_UP));
gb.direct.joypad_bits.down = !(( k & MASK_JOY1_DOWN) || ( k & MASK_JOY2_DOWN));
gb.direct.joypad_bits.right = !(( k & MASK_JOY1_LEFT) || ( k & MASK_JOY2_LEFT));
gb.direct.joypad_bits.left = !(( k & MASK_JOY1_RIGHT) || ( k & MASK_JOY2_RIGHT));
gb.direct.joypad_bits.a = !(k & MASK_KEY_USER3);
gb.direct.joypad_bits.b = !(k & MASK_JOY2_BTN);
gb.direct.joypad_bits.select = !(k & MASK_KEY_USER1);
gb.direct.joypad_bits.start = !(k & MASK_KEY_USER2);
2025-03-30 13:36:21 +00:00
2025-01-26 16:25:30 +00:00
emu_DrawVsync();
}
void SND_Process(void *stream, int len) {
// psg_update((int16*)stream, 0, len);
}