Fix randomish crash with quicknes
This commit is contained in:
parent
1da8cb9bc1
commit
db88753772
Binary file not shown.
|
@ -5,12 +5,10 @@
|
||||||
#include <jaffarCommon/serializers/contiguous.hpp>
|
#include <jaffarCommon/serializers/contiguous.hpp>
|
||||||
#include <jaffarCommon/deserializers/contiguous.hpp>
|
#include <jaffarCommon/deserializers/contiguous.hpp>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _WIN32
|
||||||
#define EXPORT extern "C" __declspec(dllexport)
|
#define QN_EXPORT extern "C" __declspec(dllexport)
|
||||||
#elif __MINGW32__
|
|
||||||
#define EXPORT extern "C" __declspec(dllexport) __attribute__((force_align_arg_pointer))
|
|
||||||
#else
|
#else
|
||||||
#define EXPORT extern "C" __attribute__((force_align_arg_pointer))
|
#define QN_EXPORT extern "C" __attribute__((visibility("default")))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Relevant defines for video output
|
// Relevant defines for video output
|
||||||
|
@ -19,44 +17,45 @@
|
||||||
#define DEFAULT_HEIGHT 240
|
#define DEFAULT_HEIGHT 240
|
||||||
|
|
||||||
|
|
||||||
EXPORT quickerNES::Emu *qn_new()
|
QN_EXPORT quickerNES::Emu *qn_new()
|
||||||
{
|
{
|
||||||
// Zero intialized emulator to make super sure no side effects from previous data remains
|
// Zero intialized emulator to make super sure no side effects from previous data remains
|
||||||
auto ptr = calloc(1, sizeof(quickerNES::Emu));
|
auto ptr = calloc(1, sizeof(quickerNES::Emu));
|
||||||
auto e = new (ptr) quickerNES::Emu();
|
auto e = new (ptr) quickerNES::Emu();
|
||||||
|
|
||||||
// Creating video buffer
|
// Creating video buffer
|
||||||
auto videoBuffer = (uint8_t *) malloc(VIDEO_BUFFER_SIZE);
|
auto videoBuffer = (uint8_t *) malloc(VIDEO_BUFFER_SIZE);
|
||||||
e->set_pixels(videoBuffer, DEFAULT_WIDTH + 8);
|
e->set_pixels(videoBuffer, DEFAULT_WIDTH + 8);
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void qn_delete(quickerNES::Emu *e)
|
QN_EXPORT void qn_delete(quickerNES::Emu *e)
|
||||||
{
|
{
|
||||||
free(e->get_pixels_base_ptr());
|
free(e->get_pixels_base_ptr());
|
||||||
free(e);
|
e->~Emu(); // make sure to explicitly call the dtor
|
||||||
|
free(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT const char *qn_loadines(quickerNES::Emu *e, const void *data, int length)
|
QN_EXPORT const char *qn_loadines(quickerNES::Emu *e, const void *data, int length)
|
||||||
{
|
{
|
||||||
e->load_ines((const uint8_t*)data);
|
e->load_ines((const uint8_t*)data);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT const char *qn_set_sample_rate(quickerNES::Emu *e, int rate)
|
QN_EXPORT const char *qn_set_sample_rate(quickerNES::Emu *e, int rate)
|
||||||
{
|
{
|
||||||
const char *ret = e->set_sample_rate(rate);
|
const char *ret = e->set_sample_rate(rate);
|
||||||
if (!ret) e->set_equalizer(quickerNES::Emu::nes_eq);
|
if (!ret) e->set_equalizer(quickerNES::Emu::nes_eq);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT const char *qn_emulate_frame(quickerNES::Emu *e, int pad1, int pad2)
|
QN_EXPORT const char *qn_emulate_frame(quickerNES::Emu *e, int pad1, int pad2)
|
||||||
{
|
{
|
||||||
return e->emulate_frame((uint32_t)pad1, (uint32_t)pad2);
|
return e->emulate_frame((uint32_t)pad1, (uint32_t)pad2);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void qn_blit(quickerNES::Emu *e, int32_t *dest, const int32_t *colors, int cropleft, int croptop, int cropright, int cropbottom)
|
QN_EXPORT void qn_blit(quickerNES::Emu *e, int32_t *dest, const int32_t *colors, int cropleft, int croptop, int cropright, int cropbottom)
|
||||||
{
|
{
|
||||||
// what is the point of the 256 color bitmap and the dynamic color allocation to it?
|
// what is the point of the 256 color bitmap and the dynamic color allocation to it?
|
||||||
// why not just render directly to a 512 color bitmap with static palette positions?
|
// why not just render directly to a 512 color bitmap with static palette positions?
|
||||||
|
@ -81,17 +80,17 @@ EXPORT void qn_blit(quickerNES::Emu *e, int32_t *dest, const int32_t *colors, in
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT const quickerNES::Emu::rgb_t *qn_get_default_colors()
|
QN_EXPORT const quickerNES::Emu::rgb_t *qn_get_default_colors()
|
||||||
{
|
{
|
||||||
return quickerNES::Emu::nes_colors;
|
return quickerNES::Emu::nes_colors;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT int qn_get_joypad_read_count(quickerNES::Emu *e)
|
QN_EXPORT int qn_get_joypad_read_count(quickerNES::Emu *e)
|
||||||
{
|
{
|
||||||
return e->get_joypad_read_count();
|
return e->get_joypad_read_count();
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void qn_get_audio_info(quickerNES::Emu *e, int *sample_count, int *chan_count)
|
QN_EXPORT void qn_get_audio_info(quickerNES::Emu *e, int *sample_count, int *chan_count)
|
||||||
{
|
{
|
||||||
if (sample_count)
|
if (sample_count)
|
||||||
*sample_count = e->frame().sample_count;
|
*sample_count = e->frame().sample_count;
|
||||||
|
@ -99,17 +98,17 @@ EXPORT void qn_get_audio_info(quickerNES::Emu *e, int *sample_count, int *chan_c
|
||||||
*chan_count = e->frame().chan_count;
|
*chan_count = e->frame().chan_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT int qn_read_audio(quickerNES::Emu *e, short *dest, int max_samples)
|
QN_EXPORT int qn_read_audio(quickerNES::Emu *e, short *dest, int max_samples)
|
||||||
{
|
{
|
||||||
return e->read_samples(dest, max_samples);
|
return e->read_samples(dest, max_samples);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void qn_reset(quickerNES::Emu *e, int hard)
|
QN_EXPORT void qn_reset(quickerNES::Emu *e, int hard)
|
||||||
{
|
{
|
||||||
e->reset(hard);
|
e->reset(hard);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT const char *qn_state_size(quickerNES::Emu *e, int *size)
|
QN_EXPORT const char *qn_state_size(quickerNES::Emu *e, int *size)
|
||||||
{
|
{
|
||||||
jaffarCommon::serializer::Contiguous s;
|
jaffarCommon::serializer::Contiguous s;
|
||||||
e->serializeState(s);
|
e->serializeState(s);
|
||||||
|
@ -117,44 +116,44 @@ EXPORT const char *qn_state_size(quickerNES::Emu *e, int *size)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT const char *qn_state_save(quickerNES::Emu *e, void *dest, int size)
|
QN_EXPORT const char *qn_state_save(quickerNES::Emu *e, void *dest, int size)
|
||||||
{
|
{
|
||||||
jaffarCommon::serializer::Contiguous s(dest, size);
|
jaffarCommon::serializer::Contiguous s(dest, size);
|
||||||
e->serializeState(s);
|
e->serializeState(s);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT const char *qn_state_load(quickerNES::Emu *e, const void *src, int size)
|
QN_EXPORT const char *qn_state_load(quickerNES::Emu *e, const void *src, int size)
|
||||||
{
|
{
|
||||||
jaffarCommon::deserializer::Contiguous d(src, size);
|
jaffarCommon::deserializer::Contiguous d(src, size);
|
||||||
e->deserializeState(d);
|
e->deserializeState(d);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT int qn_has_battery_ram(quickerNES::Emu *e)
|
QN_EXPORT int qn_has_battery_ram(quickerNES::Emu *e)
|
||||||
{
|
{
|
||||||
return e->has_battery_ram();
|
return e->has_battery_ram();
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT const char *qn_battery_ram_size(quickerNES::Emu *e, int *size)
|
QN_EXPORT const char *qn_battery_ram_size(quickerNES::Emu *e, int *size)
|
||||||
{
|
{
|
||||||
*size = e->get_high_mem_size();
|
*size = e->get_high_mem_size();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT const char *qn_battery_ram_save(quickerNES::Emu *e, void *dest, int size)
|
QN_EXPORT const char *qn_battery_ram_save(quickerNES::Emu *e, void *dest, int size)
|
||||||
{
|
{
|
||||||
memcpy(dest, e->high_mem(), size);
|
memcpy(dest, e->high_mem(), size);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT const char *qn_battery_ram_load(quickerNES::Emu *e, const void *src, int size)
|
QN_EXPORT const char *qn_battery_ram_load(quickerNES::Emu *e, const void *src, int size)
|
||||||
{
|
{
|
||||||
memcpy(e->high_mem(), src, size);
|
memcpy(e->high_mem(), src, size);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT const char *qn_battery_ram_clear(quickerNES::Emu *e)
|
QN_EXPORT const char *qn_battery_ram_clear(quickerNES::Emu *e)
|
||||||
{
|
{
|
||||||
int size = 0;
|
int size = 0;
|
||||||
qn_battery_ram_size(e, &size);
|
qn_battery_ram_size(e, &size);
|
||||||
|
@ -162,12 +161,12 @@ EXPORT const char *qn_battery_ram_clear(quickerNES::Emu *e)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void qn_set_sprite_limit(quickerNES::Emu *e, int n)
|
QN_EXPORT void qn_set_sprite_limit(quickerNES::Emu *e, int n)
|
||||||
{
|
{
|
||||||
e->set_sprite_mode((quickerNES::Emu::sprite_mode_t)n);
|
e->set_sprite_mode((quickerNES::Emu::sprite_mode_t)n);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT int qn_get_memory_area(quickerNES::Emu *e, int which, const void **data, int *size, int *writable, const char **name)
|
QN_EXPORT int qn_get_memory_area(quickerNES::Emu *e, int which, const void **data, int *size, int *writable, const char **name)
|
||||||
{
|
{
|
||||||
if (!data || !size || !writable || !name)
|
if (!data || !size || !writable || !name)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -226,22 +225,22 @@ EXPORT int qn_get_memory_area(quickerNES::Emu *e, int which, const void **data,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT unsigned char qn_peek_prgbus(quickerNES::Emu *e, int addr)
|
QN_EXPORT unsigned char qn_peek_prgbus(quickerNES::Emu *e, int addr)
|
||||||
{
|
{
|
||||||
return e->peek_prg(addr & 0xffff);
|
return e->peek_prg(addr & 0xffff);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void qn_poke_prgbus(quickerNES::Emu *e, int addr, unsigned char val)
|
QN_EXPORT void qn_poke_prgbus(quickerNES::Emu *e, int addr, unsigned char val)
|
||||||
{
|
{
|
||||||
e->poke_prg(addr & 0xffff, val);
|
e->poke_prg(addr & 0xffff, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void qn_get_cpuregs(quickerNES::Emu *e, unsigned int *dest)
|
QN_EXPORT void qn_get_cpuregs(quickerNES::Emu *e, unsigned int *dest)
|
||||||
{
|
{
|
||||||
e->get_regs(dest);
|
e->get_regs(dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT const char *qn_get_mapper(quickerNES::Emu *e, int *number)
|
QN_EXPORT const char *qn_get_mapper(quickerNES::Emu *e, int *number)
|
||||||
{
|
{
|
||||||
int m = e->cart()->mapper_code();
|
int m = e->cart()->mapper_code();
|
||||||
if (number)
|
if (number)
|
||||||
|
@ -306,33 +305,33 @@ EXPORT const char *qn_get_mapper(quickerNES::Emu *e, int *number)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT uint8_t qn_get_reg2000(quickerNES::Emu *e)
|
QN_EXPORT uint8_t qn_get_reg2000(quickerNES::Emu *e)
|
||||||
{
|
{
|
||||||
return e->get_ppu2000();
|
return e->get_ppu2000();
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT uint8_t *qn_get_palmem(quickerNES::Emu *e)
|
QN_EXPORT uint8_t *qn_get_palmem(quickerNES::Emu *e)
|
||||||
{
|
{
|
||||||
return e->pal_mem();
|
return e->pal_mem();
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT uint8_t *qn_get_oammem(quickerNES::Emu *e)
|
QN_EXPORT uint8_t *qn_get_oammem(quickerNES::Emu *e)
|
||||||
{
|
{
|
||||||
return e->pal_mem();
|
return e->pal_mem();
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT uint8_t qn_peek_ppu(quickerNES::Emu *e, int addr)
|
QN_EXPORT uint8_t qn_peek_ppu(quickerNES::Emu *e, int addr)
|
||||||
{
|
{
|
||||||
return e->peek_ppu(addr);
|
return e->peek_ppu(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void qn_peek_ppubus(quickerNES::Emu *e, uint8_t *dest)
|
QN_EXPORT void qn_peek_ppubus(quickerNES::Emu *e, uint8_t *dest)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 0x3000; i++)
|
for (int i = 0; i < 0x3000; i++)
|
||||||
dest[i] = e->peek_ppu(i);
|
dest[i] = e->peek_ppu(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void qn_set_tracecb(quickerNES::Emu *e, void (*cb)(unsigned int *dest))
|
QN_EXPORT void qn_set_tracecb(quickerNES::Emu *e, void (*cb)(unsigned int *dest))
|
||||||
{
|
{
|
||||||
e->set_tracecb(cb);
|
e->set_tracecb(cb);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 74c1a73fe8baf08ed02b66248b9bf12b4a77076c
|
Subproject commit befc3c90a190b3657ffb244a7926c5f641ac82be
|
|
@ -2,18 +2,9 @@ CXX = g++
|
||||||
RM = rm
|
RM = rm
|
||||||
CP = cp
|
CP = cp
|
||||||
|
|
||||||
MACHINE = $(shell $(CXX) -dumpmachine)
|
CXXFLAGS = -I../core/source/quickerNES/core/ -I../core/extern/jaffarCommon/include -Wall -Wfatal-errors -Werror \
|
||||||
ifneq (,$(findstring i686,$(MACHINE)))
|
-std=c++20 -O3 -fomit-frame-pointer -flto -fvisibility=internal -fvisibility-inlines-hidden \
|
||||||
$(error 32 bit build no longer supported)
|
-D_GNU_SOURCE -D__INLINE__=inline -D_QUICKERNES_DETECT_JOYPAD_READS -D_QUICKERNES_ENABLE_TRACEBACK_SUPPORT
|
||||||
else ifneq (,$(findstring x86_64,$(MACHINE)))
|
|
||||||
ARCH = 64
|
|
||||||
else
|
|
||||||
$(error Unknown arch)
|
|
||||||
endif
|
|
||||||
|
|
||||||
CXXFLAGS_32 = -march=pentium4 -mtune=core2
|
|
||||||
CXXFLAGS_64 =
|
|
||||||
CXXFLAGS = -Wall -I../core/source/quickerNES/core/ -I../core/extern/jaffarCommon/include -D__INLINE__=inline -O3 -Wfatal-errors -Werror -fomit-frame-pointer -flto -D_GNU_SOURCE -D_QUICKERNES_DETECT_JOYPAD_READS -D_QUICKERNES_ENABLE_TRACEBACK_SUPPORT $(CXXFLAGS_$(ARCH))
|
|
||||||
|
|
||||||
# TODO: include these as options in the Makefile
|
# TODO: include these as options in the Makefile
|
||||||
# -fprofile-generate
|
# -fprofile-generate
|
||||||
|
@ -26,12 +17,10 @@ else
|
||||||
TARGET = libquicknes.dll
|
TARGET = libquicknes.dll
|
||||||
endif
|
endif
|
||||||
|
|
||||||
LDFLAGS_32 = -static -static-libgcc -static-libstdc++
|
LDFLAGS = -shared -s $(CXXFLAGS)
|
||||||
LDFLAGS_64 =
|
|
||||||
LDFLAGS = -shared $(LDFLAGS_$(ARCH)) $(CXXFLAGS)
|
|
||||||
|
|
||||||
DEST_64 = ../../Assets/dll
|
DEST = ../../Assets/dll
|
||||||
DESTCOPY_64 = ../../output/dll
|
DESTCOPY = ../../output/dll
|
||||||
|
|
||||||
SRCS = \
|
SRCS = \
|
||||||
../core/source/quickerNES/core/apu/vrc7/emu2413_state.cpp \
|
../core/source/quickerNES/core/apu/vrc7/emu2413_state.cpp \
|
||||||
|
@ -70,7 +59,7 @@ clean:
|
||||||
$(RM) -f $(TARGET)
|
$(RM) -f $(TARGET)
|
||||||
|
|
||||||
install:
|
install:
|
||||||
$(CP) $(TARGET) $(DEST_$(ARCH))
|
$(CP) $(TARGET) $(DEST)
|
||||||
ifneq ("$(wildcard $(DESTCOPY_$(ARCH)))", "")
|
ifneq ("$(wildcard $(DESTCOPY))", "")
|
||||||
$(CP) $(TARGET) $(DESTCOPY_$(ARCH))
|
$(CP) $(TARGET) $(DESTCOPY)
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -161,6 +161,7 @@
|
||||||
<AdditionalIncludeDirectories>$(ProjectDir)\..</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>$(ProjectDir)\..</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>_WINDLL;%(PreprocessorDefinitions);_QUICKERNES_DETECT_JOYPAD_READS;_QUICKERNES_ENABLE_TRACEBACK_SUPPORT;</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_WINDLL;%(PreprocessorDefinitions);_QUICKERNES_DETECT_JOYPAD_READS;_QUICKERNES_ENABLE_TRACEBACK_SUPPORT;</PreprocessorDefinitions>
|
||||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
|
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
@ -180,6 +181,7 @@
|
||||||
<AdditionalIncludeDirectories>$(ProjectDir)\..</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>$(ProjectDir)\..</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>_WINDLL;%(PreprocessorDefinitions);_QUICKERNES_DETECT_JOYPAD_READS;_QUICKERNES_ENABLE_TRACEBACK_SUPPORT;</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_WINDLL;%(PreprocessorDefinitions);_QUICKERNES_DETECT_JOYPAD_READS;_QUICKERNES_ENABLE_TRACEBACK_SUPPORT;</PreprocessorDefinitions>
|
||||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
|
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
@ -200,4 +202,4 @@
|
||||||
<Target Name="CopyToHawkOutput" AfterTargets="PostBuildEvent" Condition=" Exists('$(ProjectDir)../../output/dll') ">
|
<Target Name="CopyToHawkOutput" AfterTargets="PostBuildEvent" Condition=" Exists('$(ProjectDir)../../output/dll') ">
|
||||||
<Copy SourceFiles="$(OutDir)libquicknes.dll" DestinationFolder="$(ProjectDir)../../output/dll" SkipUnchangedFiles="true" />
|
<Copy SourceFiles="$(OutDir)libquicknes.dll" DestinationFolder="$(ProjectDir)../../output/dll" SkipUnchangedFiles="true" />
|
||||||
</Target>
|
</Target>
|
||||||
</Project>
|
</Project>
|
Loading…
Reference in New Issue