mirror of
https://github.com/libretro/RetroArch
synced 2025-02-26 15:39:55 +00:00
Merge pull request #2986 from leiradel/master
implemented the RETRO_ENVIRONMENT_SET_MEMORY_MAPS callback
This commit is contained in:
commit
d9393d5872
168
dynamic.c
168
dynamic.c
@ -623,6 +623,106 @@ static void rarch_log_libretro(enum retro_log_level level,
|
||||
va_end(vp);
|
||||
}
|
||||
|
||||
static size_t add_bits_down(size_t n)
|
||||
{
|
||||
n |= n >> 1;
|
||||
n |= n >> 2;
|
||||
n |= n >> 4;
|
||||
n |= n >> 8;
|
||||
n |= n >> 16;
|
||||
|
||||
/* double shift to avoid warnings on 32bit (it's dead code, but compilers suck) */
|
||||
if (sizeof(size_t) > 4)
|
||||
n |= n >> 16 >> 16;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static size_t inflate(size_t addr, size_t mask)
|
||||
{
|
||||
while (mask)
|
||||
{
|
||||
size_t tmp = (mask - 1) & ~mask;
|
||||
/* to put in an 1 bit instead, OR in tmp+1 */
|
||||
addr = ((addr & ~tmp) << 1) | (addr & tmp);
|
||||
mask = mask & (mask - 1);
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
static size_t reduce(size_t addr, size_t mask)
|
||||
{
|
||||
while (mask)
|
||||
{
|
||||
size_t tmp = (mask - 1) & ~mask;
|
||||
addr = (addr & tmp) | ((addr >> 1) & ~tmp);
|
||||
mask = (mask & (mask - 1)) >> 1;
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
static size_t highest_bit(size_t n)
|
||||
{
|
||||
n = add_bits_down(n);
|
||||
return n ^ (n >> 1);
|
||||
}
|
||||
|
||||
static bool preprocess_descriptors(struct retro_memory_descriptor *first, unsigned count)
|
||||
{
|
||||
struct retro_memory_descriptor *desc;
|
||||
const struct retro_memory_descriptor *end;
|
||||
size_t top_addr, disconnect_mask;
|
||||
|
||||
end = first + count;
|
||||
top_addr = 1;
|
||||
|
||||
for (desc = first; desc < end; desc++)
|
||||
{
|
||||
if (desc->select != 0)
|
||||
top_addr |= desc->select;
|
||||
else
|
||||
top_addr |= desc->start + desc->len - 1;
|
||||
}
|
||||
|
||||
top_addr = add_bits_down(top_addr);
|
||||
|
||||
for (desc = first; desc < end; desc++)
|
||||
{
|
||||
if (desc->select == 0)
|
||||
{
|
||||
if (desc->len == 0)
|
||||
return false;
|
||||
|
||||
if ((desc->len & (desc->len - 1)) != 0)
|
||||
return false;
|
||||
|
||||
desc->select = top_addr & ~inflate(add_bits_down(desc->len - 1), desc->disconnect);
|
||||
}
|
||||
|
||||
if (desc->len == 0)
|
||||
desc->len = add_bits_down(reduce(top_addr & ~desc->select, desc->disconnect)) + 1;
|
||||
|
||||
if (desc->start & ~desc->select)
|
||||
return false;
|
||||
|
||||
while (reduce(top_addr & ~desc->select, desc->disconnect) >> 1 > desc->len - 1)
|
||||
desc->disconnect |= highest_bit(top_addr & ~desc->select & ~desc->disconnect);
|
||||
|
||||
disconnect_mask = add_bits_down(desc->len - 1);
|
||||
desc->disconnect &= disconnect_mask;
|
||||
|
||||
while ((~disconnect_mask) >> 1 & desc->disconnect)
|
||||
{
|
||||
disconnect_mask >>= 1;
|
||||
desc->disconnect &= disconnect_mask;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* rarch_environment_cb:
|
||||
* @cmd : Identifier of command.
|
||||
@ -1214,6 +1314,74 @@ bool rarch_environment_cb(unsigned cmd, void *data)
|
||||
system->ports.size = i;
|
||||
break;
|
||||
}
|
||||
|
||||
case RETRO_ENVIRONMENT_SET_MEMORY_MAPS:
|
||||
{
|
||||
unsigned i;
|
||||
struct retro_memory_descriptor *descriptors;
|
||||
const struct retro_memory_map *mmaps =
|
||||
(const struct retro_memory_map*)data;
|
||||
|
||||
free((void*)system->mmaps.descriptors);
|
||||
system->mmaps.num_descriptors = 0;
|
||||
|
||||
descriptors = (struct retro_memory_descriptor*)
|
||||
calloc(mmaps->num_descriptors, sizeof(*system->mmaps.descriptors));
|
||||
|
||||
if (!descriptors)
|
||||
return false;
|
||||
|
||||
system->mmaps.descriptors = descriptors;
|
||||
memcpy((void*)system->mmaps.descriptors, mmaps->descriptors,
|
||||
mmaps->num_descriptors * sizeof(*system->mmaps.descriptors));
|
||||
system->mmaps.num_descriptors = mmaps->num_descriptors;
|
||||
preprocess_descriptors(descriptors, mmaps->num_descriptors);
|
||||
|
||||
RARCH_LOG("Environ SET_MEMORY_MAPS.\n");
|
||||
|
||||
if (sizeof(void *) == 8)
|
||||
RARCH_LOG(" ndx flags ptr offset start select disconn len addrspace\n");
|
||||
else
|
||||
RARCH_LOG(" ndx flags ptr offset start select disconn len addrspace\n");
|
||||
|
||||
for (i = 0; i < system->mmaps.num_descriptors; i++)
|
||||
{
|
||||
const struct retro_memory_descriptor *desc =
|
||||
&system->mmaps.descriptors[i];
|
||||
char flags[7];
|
||||
|
||||
flags[0] = 'M';
|
||||
if ((desc->flags & RETRO_MEMDESC_MINSIZE_8) == RETRO_MEMDESC_MINSIZE_8)
|
||||
flags[1] = '8';
|
||||
else if ((desc->flags & RETRO_MEMDESC_MINSIZE_4) == RETRO_MEMDESC_MINSIZE_4)
|
||||
flags[1] = '4';
|
||||
else if ((desc->flags & RETRO_MEMDESC_MINSIZE_2) == RETRO_MEMDESC_MINSIZE_2)
|
||||
flags[1] = '2';
|
||||
else
|
||||
flags[1] = '1';
|
||||
|
||||
flags[2] = 'A';
|
||||
if ((desc->flags & RETRO_MEMDESC_ALIGN_8) == RETRO_MEMDESC_ALIGN_8)
|
||||
flags[3] = '8';
|
||||
else if ((desc->flags & RETRO_MEMDESC_ALIGN_4) == RETRO_MEMDESC_ALIGN_4)
|
||||
flags[3] = '4';
|
||||
else if ((desc->flags & RETRO_MEMDESC_ALIGN_2) == RETRO_MEMDESC_ALIGN_2)
|
||||
flags[3] = '2';
|
||||
else
|
||||
flags[3] = '1';
|
||||
|
||||
flags[4] = (desc->flags & RETRO_MEMDESC_BIGENDIAN) ? 'B' : 'b';
|
||||
flags[5] = (desc->flags & RETRO_MEMDESC_CONST) ? 'C' : 'c';
|
||||
flags[6] = 0;
|
||||
|
||||
RARCH_LOG(" %03u %s %p %08X %08X %08X %08X %08X %s\n",
|
||||
i + 1, flags, desc->ptr, desc->offset, desc->start,
|
||||
desc->select, desc->disconnect, desc->len,
|
||||
desc->addrspace ? desc->addrspace : "");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case RETRO_ENVIRONMENT_SET_GEOMETRY:
|
||||
{
|
||||
|
17
runloop.c
17
runloop.c
@ -717,13 +717,20 @@ bool runloop_ctl(enum runloop_ctl_state state, void *data)
|
||||
if (runloop_system.subsystem.data)
|
||||
free(runloop_system.subsystem.data);
|
||||
runloop_system.subsystem.data = NULL;
|
||||
runloop_system.subsystem.size = 0;
|
||||
|
||||
if (runloop_system.ports.data)
|
||||
free(runloop_system.ports.data);
|
||||
runloop_system.subsystem.size = 0;
|
||||
runloop_system.ports.data = NULL;
|
||||
runloop_system.ports.size = 0;
|
||||
runloop_key_event = NULL;
|
||||
runloop_frontend_key_event = NULL;
|
||||
runloop_system.ports.data = NULL;
|
||||
runloop_system.ports.size = 0;
|
||||
|
||||
if (runloop_system.mmaps.descriptors)
|
||||
free((void *)runloop_system.mmaps.descriptors);
|
||||
runloop_system.mmaps.descriptors = NULL;
|
||||
runloop_system.mmaps.num_descriptors = 0;
|
||||
|
||||
runloop_key_event = NULL;
|
||||
runloop_frontend_key_event = NULL;
|
||||
|
||||
audio_driver_unset_callback();
|
||||
memset(&runloop_system, 0, sizeof(rarch_system_info_t));
|
||||
|
Loading…
x
Reference in New Issue
Block a user