mirror of
https://github.com/libretro/RetroArch
synced 2025-01-26 18:35:22 +00:00
Can build for C++.
This commit is contained in:
parent
4ca72bd7e6
commit
d5fca50a2f
8
Makefile
8
Makefile
@ -176,11 +176,15 @@ ifeq ($(DEBUG), 1)
|
||||
endif
|
||||
|
||||
CFLAGS += -Wall $(OPTIMIZE_FLAG) -g -I. -pedantic
|
||||
ifeq ($(CXX_BUILD), 1)
|
||||
CFLAGS += -std=c++0x -xc++
|
||||
else
|
||||
ifneq ($(findstring icc,$(CC)),)
|
||||
CFLAGS += -std=c99 -D_GNU_SOURCE
|
||||
else
|
||||
CFLAGS += -std=gnu99
|
||||
endif
|
||||
endif
|
||||
|
||||
all: $(TARGET) config.mk
|
||||
|
||||
@ -193,7 +197,11 @@ ssnes: $(OBJ)
|
||||
@$(if $(Q), $(shell echo echo LD $@),)
|
||||
|
||||
tools/ssnes-joyconfig: $(JOYCONFIG_OBJ)
|
||||
ifeq ($(CXX_BUILD), 1)
|
||||
$(Q)$(CXX) -o $@ $(JOYCONFIG_OBJ) $(SDL_LIBS) $(LDFLAGS) $(LIBRARY_DIRS)
|
||||
else
|
||||
$(Q)$(CC) -o $@ $(JOYCONFIG_OBJ) $(SDL_LIBS) $(LDFLAGS) $(LIBRARY_DIRS)
|
||||
endif
|
||||
@$(if $(Q), $(shell echo echo LD $@),)
|
||||
|
||||
%.o: %.c config.h config.mk $(HEADERS)
|
||||
|
23
Makefile.win
23
Makefile.win
@ -1,7 +1,7 @@
|
||||
TARGET = ssnes.exe
|
||||
JTARGET = ssnes-joyconfig.exe
|
||||
OBJ = ssnes.o file.o driver.o conf/config_file.o settings.o dynamic.o message.o rewind.o movie.o gfx/gfx_common.o bps.o ups.o strl.o screenshot.o audio/hermite.o getopt.o audio/utils.o
|
||||
JOBJ = conf/config_file.o tools/main-stub.o tools/ssnes-joyconfig.o strl.o
|
||||
OBJ = ssnes.o file.o driver.o conf/config_file.o settings.o dynamic.o message.o rewind.o movie.o gfx/gfx_common.o bps.o ups.o strl.o screenshot.o audio/hermite.o getopt.o audio/utils.o posix_string.o
|
||||
JOBJ = conf/config_file.o tools/main-stub.o tools/ssnes-joyconfig.o strl.o posix_string.o
|
||||
|
||||
CC = gcc
|
||||
CXX = g++
|
||||
@ -139,12 +139,16 @@ ifeq ($(HAVE_FFMPEG), 1)
|
||||
OBJ += record/ffemu.o
|
||||
endif
|
||||
|
||||
ifneq ($(V),1)
|
||||
ifneq ($(V), 1)
|
||||
Q := @
|
||||
endif
|
||||
|
||||
CFLAGS += -Wall -O3 -std=gnu99 -I.
|
||||
CXXFLAGS += -Wall -O3 -pedantic -I.
|
||||
CFLAGS += -Wall -O3 -I.
|
||||
ifeq ($(CXX_BUILD), 1)
|
||||
CFLAGS += -std=c++0x -xc++
|
||||
else
|
||||
CFLAGS += -std=gnu99
|
||||
endif
|
||||
|
||||
all: $(TARGET) $(JTARGET)
|
||||
|
||||
@ -156,13 +160,12 @@ $(TARGET): $(OBJ)
|
||||
$(Q)$(CC) $(CFLAGS) $(DEFINES) -c -o $@ $<
|
||||
@$(if $(Q), $(shell echo echo CC $<),)
|
||||
|
||||
%.o: %.cpp
|
||||
$(Q)$(CXX) $(CXXFLAGS) $(DEFINES) -c -o $@ $<
|
||||
@$(if $(Q), $(shell echo echo CXX $<),)
|
||||
|
||||
|
||||
$(JTARGET): $(JOBJ)
|
||||
ifeq ($(CXX_BUILD), 1)
|
||||
$(Q)$(CXX) -o $@ $(JOBJ) -lSDL $(LDFLAGS)
|
||||
else
|
||||
$(Q)$(CC) -o $@ $(JOBJ) -lSDL $(LDFLAGS)
|
||||
endif
|
||||
@$(if $(Q), $(shell echo echo LD $@),)
|
||||
|
||||
clean:
|
||||
|
41
audio/alsa.c
41
audio/alsa.c
@ -34,7 +34,7 @@ typedef struct alsa
|
||||
|
||||
static bool alsa_use_float(void *data)
|
||||
{
|
||||
alsa_t *alsa = data;
|
||||
alsa_t *alsa = (alsa_t*)data;
|
||||
return alsa->has_float;
|
||||
}
|
||||
|
||||
@ -51,7 +51,7 @@ static bool find_float_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
|
||||
|
||||
static void *alsa_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
alsa_t *alsa = calloc(1, sizeof(alsa_t));
|
||||
alsa_t *alsa = (alsa_t*)calloc(1, sizeof(alsa_t));
|
||||
if (!alsa)
|
||||
return NULL;
|
||||
|
||||
@ -62,14 +62,17 @@ static void *alsa_init(const char *device, unsigned rate, unsigned latency)
|
||||
if (device)
|
||||
alsa_dev = device;
|
||||
|
||||
TRY_ALSA(snd_pcm_open(&alsa->pcm, alsa_dev, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK));
|
||||
|
||||
unsigned int latency_usec = latency * 1000;
|
||||
unsigned int channels = 2;
|
||||
unsigned periods = 4;
|
||||
snd_pcm_uframes_t buffer_size;
|
||||
snd_pcm_format_t format;
|
||||
|
||||
TRY_ALSA(snd_pcm_open(&alsa->pcm, alsa_dev, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK));
|
||||
|
||||
TRY_ALSA(snd_pcm_hw_params_malloc(¶ms));
|
||||
alsa->has_float = find_float_format(alsa->pcm, params);
|
||||
snd_pcm_format_t format = alsa->has_float ? SND_PCM_FORMAT_FLOAT : SND_PCM_FORMAT_S16;
|
||||
unsigned int channels = 2;
|
||||
format = alsa->has_float ? SND_PCM_FORMAT_FLOAT : SND_PCM_FORMAT_S16;
|
||||
|
||||
TRY_ALSA(snd_pcm_hw_params_any(alsa->pcm, params));
|
||||
TRY_ALSA(snd_pcm_hw_params_set_access(alsa->pcm, params, SND_PCM_ACCESS_RW_INTERLEAVED));
|
||||
@ -78,12 +81,10 @@ static void *alsa_init(const char *device, unsigned rate, unsigned latency)
|
||||
TRY_ALSA(snd_pcm_hw_params_set_rate(alsa->pcm, params, rate, 0));
|
||||
|
||||
TRY_ALSA(snd_pcm_hw_params_set_buffer_time_near(alsa->pcm, params, &latency_usec, NULL));
|
||||
unsigned periods = 4;
|
||||
TRY_ALSA(snd_pcm_hw_params_set_periods_near(alsa->pcm, params, &periods, NULL));
|
||||
|
||||
TRY_ALSA(snd_pcm_hw_params(alsa->pcm, params));
|
||||
|
||||
snd_pcm_uframes_t buffer_size;
|
||||
snd_pcm_hw_params_get_period_size(params, &buffer_size, NULL);
|
||||
SSNES_LOG("ALSA: Period size: %d frames\n", (int)buffer_size);
|
||||
snd_pcm_hw_params_get_buffer_size(params, &buffer_size);
|
||||
@ -119,14 +120,14 @@ error:
|
||||
|
||||
static ssize_t alsa_write(void *data, const void *buf, size_t size)
|
||||
{
|
||||
alsa_t *alsa = data;
|
||||
alsa_t *alsa = (alsa_t*)data;
|
||||
|
||||
snd_pcm_sframes_t frames;
|
||||
snd_pcm_sframes_t written = 0;
|
||||
int rc;
|
||||
size = snd_pcm_bytes_to_frames(alsa->pcm, size); // Frames to write
|
||||
|
||||
while (written < size)
|
||||
while (written < (snd_pcm_sframes_t)size)
|
||||
{
|
||||
if (!alsa->nonblock)
|
||||
{
|
||||
@ -166,7 +167,7 @@ static bool alsa_stop(void *data)
|
||||
|
||||
static void alsa_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
alsa_t *alsa = data;
|
||||
alsa_t *alsa = (alsa_t*)data;
|
||||
alsa->nonblock = state;
|
||||
}
|
||||
|
||||
@ -177,7 +178,7 @@ static bool alsa_start(void *data)
|
||||
|
||||
static void alsa_free(void *data)
|
||||
{
|
||||
alsa_t *alsa = data;
|
||||
alsa_t *alsa = (alsa_t*)data;
|
||||
if (alsa)
|
||||
{
|
||||
if (alsa->pcm)
|
||||
@ -190,13 +191,13 @@ static void alsa_free(void *data)
|
||||
}
|
||||
|
||||
const audio_driver_t audio_alsa = {
|
||||
.init = alsa_init,
|
||||
.write = alsa_write,
|
||||
.stop = alsa_stop,
|
||||
.start = alsa_start,
|
||||
.use_float = alsa_use_float,
|
||||
.set_nonblock_state = alsa_set_nonblock_state,
|
||||
.free = alsa_free,
|
||||
.ident = "alsa"
|
||||
alsa_init,
|
||||
alsa_write,
|
||||
alsa_stop,
|
||||
alsa_start,
|
||||
alsa_set_nonblock_state,
|
||||
alsa_free,
|
||||
alsa_use_float,
|
||||
"alsa"
|
||||
};
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include "general.h"
|
||||
#include "fifo_buffer.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include "../boolean.h"
|
||||
#include <pthread.h>
|
||||
|
||||
#include <CoreAudio/CoreAudio.h>
|
||||
@ -43,7 +43,7 @@ typedef struct coreaudio
|
||||
|
||||
static void coreaudio_free(void *data)
|
||||
{
|
||||
coreaudio_t *dev = data;
|
||||
coreaudio_t *dev = (coreaudio_t*)data;
|
||||
if (!dev)
|
||||
return;
|
||||
|
||||
@ -66,7 +66,7 @@ static OSStatus audio_cb(void *userdata, AudioUnitRenderActionFlags *action_flag
|
||||
const AudioTimeStamp *time_stamp, UInt32 bus_number,
|
||||
UInt32 number_frames, AudioBufferList *io_data)
|
||||
{
|
||||
coreaudio_t *dev = userdata;
|
||||
coreaudio_t *dev = (coreaudio_t*)userdata;
|
||||
(void)time_stamp;
|
||||
(void)bus_number;
|
||||
(void)number_frames;
|
||||
@ -99,7 +99,7 @@ static void *coreaudio_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
(void)device;
|
||||
|
||||
coreaudio_t *dev = calloc(1, sizeof(*dev));
|
||||
coreaudio_t *dev = (coreaudio_t*)calloc(1, sizeof(*dev));
|
||||
if (!dev)
|
||||
return NULL;
|
||||
|
||||
@ -115,40 +115,46 @@ static void *coreaudio_init(const char *device, unsigned rate, unsigned latency)
|
||||
AudioObjectSetPropertyData(kAudioObjectSystemObject, &addr, 0, NULL,
|
||||
sizeof(CFRunLoopRef), &run_loop);
|
||||
|
||||
ComponentDescription desc = {
|
||||
.componentType = kAudioUnitType_Output,
|
||||
.componentSubType = kAudioUnitSubType_HALOutput,
|
||||
.componentManufacturer = kAudioUnitManufacturer_Apple,
|
||||
};
|
||||
ComponentDescription desc = {0};
|
||||
desc.componentType = kAudioUnitType_Output;
|
||||
desc.componentSubType = kAudioUnitSubType_HALOutput;
|
||||
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
|
||||
|
||||
Component comp = FindNextComponent(NULL, &desc);
|
||||
AudioStreamBasicDescription stream_desc = {0};
|
||||
AudioStreamBasicDescription real_desc;
|
||||
AudioChannelLayout layout = {0};
|
||||
AURenderCallbackStruct cb = {0};
|
||||
|
||||
Component comp = NULL;
|
||||
OSStatus res = noErr;
|
||||
UInt32 i_size = 0;
|
||||
size_t fifo_size;
|
||||
|
||||
comp = FindNextComponent(NULL, &desc);
|
||||
if (comp == NULL)
|
||||
goto error;
|
||||
|
||||
OSStatus res = OpenAComponent(comp, &dev->dev);
|
||||
res = OpenAComponent(comp, &dev->dev);
|
||||
if (res != noErr)
|
||||
goto error;
|
||||
|
||||
dev->dev_alive = true;
|
||||
|
||||
AudioStreamBasicDescription stream_desc = {
|
||||
.mSampleRate = rate,
|
||||
.mBitsPerChannel = sizeof(float) * CHAR_BIT,
|
||||
.mChannelsPerFrame = 2,
|
||||
.mBytesPerPacket = 2 * sizeof(float),
|
||||
.mBytesPerFrame = 2 * sizeof(float),
|
||||
.mFramesPerPacket = 1,
|
||||
.mFormatID = kAudioFormatLinearPCM,
|
||||
.mFormatFlags = kAudioFormatFlagIsFloat | kAudioFormatFlagIsPacked | (is_little_endian() ? 0 : kAudioFormatFlagIsBigEndian),
|
||||
};
|
||||
stream_desc.mSampleRate = rate;
|
||||
stream_desc.mBitsPerChannel = sizeof(float) * CHAR_BIT;
|
||||
stream_desc.mChannelsPerFrame = 2;
|
||||
stream_desc.mBytesPerPacket = 2 * sizeof(float);
|
||||
stream_desc.mBytesPerFrame = 2 * sizeof(float);
|
||||
stream_desc.mFramesPerPacket = 1;
|
||||
stream_desc.mFormatID = kAudioFormatLinearPCM;
|
||||
stream_desc.mFormatFlags = kAudioFormatFlagIsFloat | kAudioFormatFlagIsPacked | (is_little_endian() ? 0 : kAudioFormatFlagIsBigEndian);
|
||||
|
||||
res = AudioUnitSetProperty(dev->dev, kAudioUnitProperty_StreamFormat,
|
||||
kAudioUnitScope_Input, 0, &stream_desc, sizeof(stream_desc));
|
||||
if (res != noErr)
|
||||
goto error;
|
||||
|
||||
AudioStreamBasicDescription real_desc;
|
||||
UInt32 i_size = sizeof(real_desc);
|
||||
i_size = sizeof(real_desc);
|
||||
res = AudioUnitGetProperty(dev->dev, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &real_desc, &i_size);
|
||||
if (res != noErr)
|
||||
goto error;
|
||||
@ -165,20 +171,16 @@ static void *coreaudio_init(const char *device, unsigned rate, unsigned latency)
|
||||
if (real_desc.mFormatID != stream_desc.mFormatID)
|
||||
goto error;
|
||||
|
||||
AudioChannelLayout layout = {
|
||||
.mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelBitmap,
|
||||
.mChannelBitmap = (1 << 2) - 1,
|
||||
};
|
||||
layout.mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelBitmap;
|
||||
layout.mChannelBitmap = 0x03;
|
||||
|
||||
res = AudioUnitSetProperty(dev->dev, kAudioUnitProperty_AudioChannelLayout,
|
||||
kAudioUnitScope_Input, 0, &layout, sizeof(layout));
|
||||
if (res != noErr)
|
||||
goto error;
|
||||
|
||||
AURenderCallbackStruct cb = {
|
||||
.inputProc = audio_cb,
|
||||
.inputProcRefCon = dev,
|
||||
};
|
||||
cb.inputProc = audio_cb;
|
||||
cb.inputProcRefCon = dev;
|
||||
|
||||
res = AudioUnitSetProperty(dev->dev, kAudioUnitProperty_SetRenderCallback,
|
||||
kAudioUnitScope_Input, 0, &cb, sizeof(cb));
|
||||
@ -189,7 +191,7 @@ static void *coreaudio_init(const char *device, unsigned rate, unsigned latency)
|
||||
if (res != noErr)
|
||||
goto error;
|
||||
|
||||
size_t fifo_size = (latency * g_settings.audio.out_rate) / 1000;
|
||||
fifo_size = (latency * g_settings.audio.out_rate) / 1000;
|
||||
fifo_size *= 2 * sizeof(float);
|
||||
|
||||
dev->buffer = fifo_new(fifo_size);
|
||||
@ -212,9 +214,9 @@ error:
|
||||
|
||||
static ssize_t coreaudio_write(void *data, const void *buf_, size_t size)
|
||||
{
|
||||
coreaudio_t *dev = data;
|
||||
coreaudio_t *dev = (coreaudio_t*)data;
|
||||
|
||||
const uint8_t *buf = buf_;
|
||||
const uint8_t *buf = (const uint8_t*)buf_;
|
||||
size_t written = 0;
|
||||
|
||||
while (size > 0)
|
||||
@ -246,19 +248,19 @@ static ssize_t coreaudio_write(void *data, const void *buf_, size_t size)
|
||||
|
||||
static bool coreaudio_stop(void *data)
|
||||
{
|
||||
coreaudio_t *dev = data;
|
||||
coreaudio_t *dev = (coreaudio_t*)data;
|
||||
return AudioOutputUnitStop(dev->dev) == noErr;
|
||||
}
|
||||
|
||||
static void coreaudio_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
coreaudio_t *dev = data;
|
||||
coreaudio_t *dev = (coreaudio_t*)data;
|
||||
dev->nonblock = state;
|
||||
}
|
||||
|
||||
static bool coreaudio_start(void *data)
|
||||
{
|
||||
coreaudio_t *dev = data;
|
||||
coreaudio_t *dev = (coreaudio_t*)data;
|
||||
return AudioOutputUnitStart(dev->dev) == noErr;
|
||||
}
|
||||
|
||||
@ -269,13 +271,13 @@ static bool coreaudio_use_float(void *data)
|
||||
}
|
||||
|
||||
const audio_driver_t audio_coreaudio = {
|
||||
.init = coreaudio_init,
|
||||
.write = coreaudio_write,
|
||||
.stop = coreaudio_stop,
|
||||
.start = coreaudio_start,
|
||||
.set_nonblock_state = coreaudio_set_nonblock_state,
|
||||
.free = coreaudio_free,
|
||||
.use_float = coreaudio_use_float,
|
||||
.ident = "coreaudio"
|
||||
coreaudio_init,
|
||||
coreaudio_write,
|
||||
coreaudio_stop,
|
||||
coreaudio_start,
|
||||
coreaudio_set_nonblock_state,
|
||||
coreaudio_free,
|
||||
coreaudio_use_float,
|
||||
"coreaudio"
|
||||
};
|
||||
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
#include "driver.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include "../boolean.h"
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
@ -111,7 +111,7 @@ static inline void release_region(dsound_t *ds, const struct audio_lock *region)
|
||||
|
||||
static DWORD CALLBACK dsound_thread(PVOID data)
|
||||
{
|
||||
dsound_t *ds = data;
|
||||
dsound_t *ds = (dsound_t*)data;
|
||||
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
|
||||
|
||||
DWORD write_ptr;
|
||||
@ -218,7 +218,7 @@ static void dsound_clear_buffer(dsound_t *ds)
|
||||
|
||||
static void dsound_free(void *data)
|
||||
{
|
||||
dsound_t *ds = data;
|
||||
dsound_t *ds = (dsound_t*)data;
|
||||
if (ds)
|
||||
{
|
||||
if (ds->thread)
|
||||
@ -251,7 +251,10 @@ static void dsound_free(void *data)
|
||||
|
||||
static void *dsound_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
dsound_t *ds = calloc(1, sizeof(*ds));
|
||||
WAVEFORMATEX wfx = {0};
|
||||
DSBUFFERDESC bufdesc = {0};
|
||||
|
||||
dsound_t *ds = (dsound_t*)calloc(1, sizeof(*ds));
|
||||
if (!ds)
|
||||
goto error;
|
||||
|
||||
@ -263,14 +266,12 @@ static void *dsound_init(const char *device, unsigned rate, unsigned latency)
|
||||
if (IDirectSound_SetCooperativeLevel(ds->ds, GetDesktopWindow(), DSSCL_PRIORITY) != DS_OK)
|
||||
goto error;
|
||||
|
||||
WAVEFORMATEX wfx = {
|
||||
.wFormatTag = WAVE_FORMAT_PCM,
|
||||
.nChannels = 2,
|
||||
.nSamplesPerSec = rate,
|
||||
.wBitsPerSample = 16,
|
||||
.nBlockAlign = 2 * sizeof(int16_t),
|
||||
.nAvgBytesPerSec = rate * 2 * sizeof(int16_t),
|
||||
};
|
||||
wfx.wFormatTag = WAVE_FORMAT_PCM;
|
||||
wfx.nChannels = 2;
|
||||
wfx.nSamplesPerSec = rate;
|
||||
wfx.wBitsPerSample = 16;
|
||||
wfx.nBlockAlign = 2 * sizeof(int16_t);
|
||||
wfx.nAvgBytesPerSec = rate * 2 * sizeof(int16_t);
|
||||
|
||||
ds->buffer_size = (latency * wfx.nAvgBytesPerSec) / 1000;
|
||||
ds->buffer_size /= CHUNK_SIZE;
|
||||
@ -281,12 +282,10 @@ static void *dsound_init(const char *device, unsigned rate, unsigned latency)
|
||||
SSNES_LOG("[DirectSound]: Setting buffer size of %u bytes\n", ds->buffer_size);
|
||||
SSNES_LOG("[DirectSound]: Latency = %u ms\n", (unsigned)((1000 * ds->buffer_size) / wfx.nAvgBytesPerSec));
|
||||
|
||||
DSBUFFERDESC bufdesc = {
|
||||
.dwSize = sizeof(DSBUFFERDESC),
|
||||
.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS,
|
||||
.dwBufferBytes = ds->buffer_size,
|
||||
.lpwfxFormat = &wfx,
|
||||
};
|
||||
bufdesc.dwSize = sizeof(DSBUFFERDESC);
|
||||
bufdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS;
|
||||
bufdesc.dwBufferBytes = ds->buffer_size;
|
||||
bufdesc.lpwfxFormat = &wfx;
|
||||
|
||||
ds->event = CreateEvent(NULL, false, false, NULL);
|
||||
if (!ds->event)
|
||||
@ -319,14 +318,14 @@ error:
|
||||
|
||||
static bool dsound_stop(void *data)
|
||||
{
|
||||
dsound_t *ds = data;
|
||||
dsound_t *ds = (dsound_t*)data;
|
||||
dsound_stop_thread(ds);
|
||||
return IDirectSoundBuffer_Stop(ds->dsb) == DS_OK;
|
||||
}
|
||||
|
||||
static bool dsound_start(void *data)
|
||||
{
|
||||
dsound_t *ds = data;
|
||||
dsound_t *ds = (dsound_t*)data;
|
||||
dsound_clear_buffer(ds);
|
||||
|
||||
if (!dsound_start_thread(ds))
|
||||
@ -337,14 +336,14 @@ static bool dsound_start(void *data)
|
||||
|
||||
static void dsound_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
dsound_t *ds = data;
|
||||
dsound_t *ds = (dsound_t*)data;
|
||||
ds->nonblock = state;
|
||||
}
|
||||
|
||||
static ssize_t dsound_write(void *data, const void *buf_, size_t size)
|
||||
{
|
||||
dsound_t *ds = data;
|
||||
const uint8_t *buf = buf_;
|
||||
dsound_t *ds = (dsound_t*)data;
|
||||
const uint8_t *buf = (const uint8_t*)buf_;
|
||||
|
||||
if (!ds->thread_alive)
|
||||
return -1;
|
||||
@ -374,14 +373,14 @@ static ssize_t dsound_write(void *data, const void *buf_, size_t size)
|
||||
return written;
|
||||
}
|
||||
|
||||
|
||||
const audio_driver_t audio_dsound = {
|
||||
.init = dsound_init,
|
||||
.write = dsound_write,
|
||||
.stop = dsound_stop,
|
||||
.start = dsound_start,
|
||||
.set_nonblock_state = dsound_set_nonblock_state,
|
||||
.free = dsound_free,
|
||||
.ident = "dsound"
|
||||
dsound_init,
|
||||
dsound_write,
|
||||
dsound_stop,
|
||||
dsound_start,
|
||||
dsound_set_nonblock_state,
|
||||
dsound_free,
|
||||
NULL,
|
||||
"dsound"
|
||||
};
|
||||
|
||||
|
47
audio/ext.c
47
audio/ext.c
@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
#include "ext/ssnes_audio.h"
|
||||
#include <stdbool.h>
|
||||
#include "../boolean.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "driver.h"
|
||||
@ -34,7 +34,7 @@ typedef struct audio_ext
|
||||
|
||||
static void audio_ext_free(void *data)
|
||||
{
|
||||
audio_ext_t *ext = data;
|
||||
audio_ext_t *ext = (audio_ext_t*)data;
|
||||
if (ext)
|
||||
{
|
||||
if (ext->driver && ext->handle)
|
||||
@ -53,10 +53,13 @@ static void *audio_ext_init(const char *device, unsigned rate, unsigned latency)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
audio_ext_t *ext = calloc(1, sizeof(*ext));
|
||||
audio_ext_t *ext = (audio_ext_t*)calloc(1, sizeof(*ext));
|
||||
if (!ext)
|
||||
return NULL;
|
||||
|
||||
ssnes_audio_driver_info_t info = {0};
|
||||
const ssnes_audio_driver_t *(*plugin_load)(void) = NULL;
|
||||
|
||||
ext->lib = dylib_load(g_settings.audio.external_driver);
|
||||
if (!ext->lib)
|
||||
{
|
||||
@ -64,7 +67,7 @@ static void *audio_ext_init(const char *device, unsigned rate, unsigned latency)
|
||||
goto error;
|
||||
}
|
||||
|
||||
const ssnes_audio_driver_t* (*plugin_load)(void) = (const ssnes_audio_driver_t* (*)(void))dylib_proc(ext->lib, "ssnes_audio_driver_init");
|
||||
plugin_load = (const ssnes_audio_driver_t *(*)(void))dylib_proc(ext->lib, "ssnes_audio_driver_init");
|
||||
|
||||
if (!plugin_load)
|
||||
{
|
||||
@ -87,11 +90,9 @@ static void *audio_ext_init(const char *device, unsigned rate, unsigned latency)
|
||||
goto error;
|
||||
}
|
||||
|
||||
ssnes_audio_driver_info_t info = {
|
||||
.device = device,
|
||||
.sample_rate = rate,
|
||||
.latency = latency
|
||||
};
|
||||
info.device = device;
|
||||
info.sample_rate = rate;
|
||||
info.latency = latency;
|
||||
|
||||
ext->handle = ext->driver->init(&info);
|
||||
if (!ext->handle)
|
||||
@ -115,7 +116,7 @@ error:
|
||||
|
||||
static ssize_t audio_ext_write(void *data, const void *buf, size_t size)
|
||||
{
|
||||
audio_ext_t *ext = data;
|
||||
audio_ext_t *ext = (audio_ext_t*)data;
|
||||
unsigned frame_size = ext->is_float ? (2 * sizeof(float)) : (2 * sizeof(int16_t));
|
||||
size /= frame_size;
|
||||
|
||||
@ -127,37 +128,37 @@ static ssize_t audio_ext_write(void *data, const void *buf, size_t size)
|
||||
|
||||
static bool audio_ext_start(void *data)
|
||||
{
|
||||
audio_ext_t *ext = data;
|
||||
audio_ext_t *ext = (audio_ext_t*)data;
|
||||
return ext->driver->start(ext->handle);
|
||||
}
|
||||
|
||||
static bool audio_ext_stop(void *data)
|
||||
{
|
||||
audio_ext_t *ext = data;
|
||||
audio_ext_t *ext = (audio_ext_t*)data;
|
||||
return ext->driver->stop(ext->handle);
|
||||
}
|
||||
|
||||
static void audio_ext_set_nonblock_state(void *data, bool toggle)
|
||||
{
|
||||
audio_ext_t *ext = data;
|
||||
audio_ext_t *ext = (audio_ext_t*)data;
|
||||
ext->driver->set_nonblock_state(ext->handle, toggle);
|
||||
}
|
||||
|
||||
static bool audio_ext_use_float(void *data)
|
||||
{
|
||||
audio_ext_t *ext = data;
|
||||
audio_ext_t *ext = (audio_ext_t*)data;
|
||||
ext->is_float = ext->driver->use_float(ext->handle);
|
||||
return ext->is_float;
|
||||
}
|
||||
|
||||
|
||||
const audio_driver_t audio_ext = {
|
||||
.init = audio_ext_init,
|
||||
.write = audio_ext_write,
|
||||
.stop = audio_ext_stop,
|
||||
.start = audio_ext_start,
|
||||
.set_nonblock_state = audio_ext_set_nonblock_state,
|
||||
.use_float = audio_ext_use_float,
|
||||
.free = audio_ext_free,
|
||||
.ident = "ext"
|
||||
audio_ext_init,
|
||||
audio_ext_write,
|
||||
audio_ext_stop,
|
||||
audio_ext_start,
|
||||
audio_ext_set_nonblock_state,
|
||||
audio_ext_free,
|
||||
audio_ext_use_float,
|
||||
"ext"
|
||||
};
|
||||
|
||||
|
@ -48,7 +48,7 @@ static inline float hermite_kernel(float mu1, float a, float b, float c, float d
|
||||
|
||||
hermite_resampler_t *hermite_new(void)
|
||||
{
|
||||
hermite_resampler_t *re = calloc(1, sizeof(*re));
|
||||
hermite_resampler_t *re = (hermite_resampler_t*)calloc(1, sizeof(*re));
|
||||
if (!re)
|
||||
return NULL;
|
||||
return re;
|
||||
|
@ -22,7 +22,7 @@
|
||||
#define __SSNES_HERMITE_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include "../boolean.h"
|
||||
|
||||
typedef struct hermite_resampler hermite_resampler_t;
|
||||
|
||||
|
65
audio/jack.c
65
audio/jack.c
@ -25,7 +25,7 @@
|
||||
#include <jack/ringbuffer.h>
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "../boolean.h"
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
@ -45,7 +45,7 @@ typedef struct jack
|
||||
|
||||
static int process_cb(jack_nframes_t nframes, void *data)
|
||||
{
|
||||
jack_t *jd = data;
|
||||
jack_t *jd = (jack_t*)data;
|
||||
if (nframes <= 0)
|
||||
{
|
||||
pthread_cond_signal(&jd->cond);
|
||||
@ -62,7 +62,7 @@ static int process_cb(jack_nframes_t nframes, void *data)
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
jack_default_audio_sample_t *out = jack_port_get_buffer(jd->ports[i], nframes);
|
||||
jack_default_audio_sample_t *out = (jack_default_audio_sample_t*)jack_port_get_buffer(jd->ports[i], nframes);
|
||||
assert(out);
|
||||
jack_ringbuffer_read(jd->buffer[i], (char*)out, min_avail * sizeof(jack_default_audio_sample_t));
|
||||
|
||||
@ -77,7 +77,7 @@ static int process_cb(jack_nframes_t nframes, void *data)
|
||||
|
||||
static void shutdown_cb(void *data)
|
||||
{
|
||||
jack_t *jd = data;
|
||||
jack_t *jd = (jack_t*)data;
|
||||
jd->shutdown = true;
|
||||
pthread_cond_signal(&jd->cond);
|
||||
}
|
||||
@ -108,7 +108,7 @@ static size_t find_buffersize(jack_t *jd, int latency)
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
jack_port_get_latency_range(jd->ports[i], JackPlaybackLatency, &range);
|
||||
if (range.max > jack_latency)
|
||||
if ((int)range.max > jack_latency)
|
||||
jack_latency = range.max;
|
||||
}
|
||||
|
||||
@ -126,7 +126,7 @@ static size_t find_buffersize(jack_t *jd, int latency)
|
||||
|
||||
static void *ja_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
jack_t *jd = calloc(1, sizeof(jack_t));
|
||||
jack_t *jd = (jack_t*)calloc(1, sizeof(jack_t));
|
||||
if (!jd)
|
||||
return NULL;
|
||||
|
||||
@ -134,6 +134,9 @@ static void *ja_init(const char *device, unsigned rate, unsigned latency)
|
||||
pthread_mutex_init(&jd->cond_lock, NULL);
|
||||
|
||||
const char **jports = NULL;
|
||||
char *dest_ports[2];
|
||||
size_t bufsize = 0;
|
||||
int parsed = 0;
|
||||
|
||||
jd->client = jack_client_open("SSNES", JackNullOption, NULL);
|
||||
if (jd->client == NULL)
|
||||
@ -152,7 +155,6 @@ static void *ja_init(const char *device, unsigned rate, unsigned latency)
|
||||
goto error;
|
||||
}
|
||||
|
||||
char *dest_ports[2];
|
||||
jports = jack_get_ports(jd->client, NULL, NULL, JackPortIsPhysical | JackPortIsInput);
|
||||
if (jports == NULL)
|
||||
{
|
||||
@ -160,7 +162,7 @@ static void *ja_init(const char *device, unsigned rate, unsigned latency)
|
||||
goto error;
|
||||
}
|
||||
|
||||
size_t bufsize = find_buffersize(jd, latency);
|
||||
bufsize = find_buffersize(jd, latency);
|
||||
SSNES_LOG("JACK: Internal buffer size: %d frames.\n", (int)(bufsize / sizeof(jack_default_audio_sample_t)));
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
@ -172,7 +174,7 @@ static void *ja_init(const char *device, unsigned rate, unsigned latency)
|
||||
}
|
||||
}
|
||||
|
||||
int parsed = parse_ports(dest_ports, jports);
|
||||
parsed = parse_ports(dest_ports, jports);
|
||||
|
||||
if (jack_activate(jd->client) < 0)
|
||||
{
|
||||
@ -191,7 +193,6 @@ static void *ja_init(const char *device, unsigned rate, unsigned latency)
|
||||
|
||||
for (int i = 0; i < parsed; i++)
|
||||
free(dest_ports[i]);
|
||||
|
||||
|
||||
jack_free(jports);
|
||||
return jd;
|
||||
@ -204,7 +205,7 @@ error:
|
||||
|
||||
static size_t write_buffer(jack_t *jd, const float *buf, size_t size)
|
||||
{
|
||||
jack_default_audio_sample_t out_deinterleaved_buffer[2][FRAMES(size)];
|
||||
jack_default_audio_sample_t out_deinterleaved_buffer[2][AUDIO_CHUNK_SIZE_NONBLOCKING];
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
for (size_t j = 0; j < FRAMES(size); j++)
|
||||
@ -218,9 +219,11 @@ static size_t write_buffer(jack_t *jd, const float *buf, size_t size)
|
||||
if (jd->shutdown)
|
||||
return 0;
|
||||
|
||||
size_t avail[2];
|
||||
avail[0] = jack_ringbuffer_write_space(jd->buffer[0]);
|
||||
avail[1] = jack_ringbuffer_write_space(jd->buffer[1]);
|
||||
size_t avail[2] = {
|
||||
jack_ringbuffer_write_space(jd->buffer[0]),
|
||||
jack_ringbuffer_write_space(jd->buffer[1]),
|
||||
};
|
||||
|
||||
size_t min_avail = avail[0] < avail[1] ? avail[0] : avail[1];
|
||||
min_avail /= sizeof(float);
|
||||
|
||||
@ -229,7 +232,10 @@ static size_t write_buffer(jack_t *jd, const float *buf, size_t size)
|
||||
if (write_frames > 0)
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
jack_ringbuffer_write(jd->buffer[i], (const char*)&out_deinterleaved_buffer[i][written], write_frames * sizeof(jack_default_audio_sample_t));
|
||||
{
|
||||
jack_ringbuffer_write(jd->buffer[i], (const char*)&out_deinterleaved_buffer[i][written],
|
||||
write_frames * sizeof(jack_default_audio_sample_t));
|
||||
}
|
||||
written += write_frames;
|
||||
}
|
||||
else
|
||||
@ -248,9 +254,9 @@ static size_t write_buffer(jack_t *jd, const float *buf, size_t size)
|
||||
|
||||
static ssize_t ja_write(void *data, const void *buf, size_t size)
|
||||
{
|
||||
jack_t *jd = data;
|
||||
jack_t *jd = (jack_t*)data;
|
||||
|
||||
return write_buffer(jd, buf, size);
|
||||
return write_buffer(jd, (const float*)buf, size);
|
||||
}
|
||||
|
||||
static bool ja_stop(void *data)
|
||||
@ -261,7 +267,7 @@ static bool ja_stop(void *data)
|
||||
|
||||
static void ja_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
jack_t *jd = data;
|
||||
jack_t *jd = (jack_t*)data;
|
||||
jd->nonblock = state;
|
||||
}
|
||||
|
||||
@ -273,7 +279,7 @@ static bool ja_start(void *data)
|
||||
|
||||
static void ja_free(void *data)
|
||||
{
|
||||
jack_t *jd = data;
|
||||
jack_t *jd = (jack_t*)data;
|
||||
|
||||
jd->shutdown = true;
|
||||
|
||||
@ -299,18 +305,13 @@ static bool ja_use_float(void *data)
|
||||
}
|
||||
|
||||
const audio_driver_t audio_jack = {
|
||||
.init = ja_init,
|
||||
.write = ja_write,
|
||||
.stop = ja_stop,
|
||||
.start = ja_start,
|
||||
.set_nonblock_state = ja_set_nonblock_state,
|
||||
.free = ja_free,
|
||||
.use_float = ja_use_float,
|
||||
.ident = "jack"
|
||||
ja_init,
|
||||
ja_write,
|
||||
ja_stop,
|
||||
ja_start,
|
||||
ja_set_nonblock_state,
|
||||
ja_free,
|
||||
ja_use_float,
|
||||
"jack"
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -59,7 +59,7 @@ typedef struct al
|
||||
static void *al_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
(void)device;
|
||||
al_t *al = calloc(1, sizeof(al_t));
|
||||
al_t *al = (al_t*)calloc(1, sizeof(al_t));
|
||||
if (!al)
|
||||
return NULL;
|
||||
|
||||
@ -76,8 +76,8 @@ static void *al_init(const char *device, unsigned rate, unsigned latency)
|
||||
al->rate = rate;
|
||||
|
||||
al->num_buffers = (latency * rate * 2 * 2) / (1000 * BUFSIZE);
|
||||
al->buffers = calloc(al->num_buffers, sizeof(ALuint));
|
||||
al->res_buf = calloc(al->num_buffers, sizeof(ALuint));
|
||||
al->buffers = (ALuint*)calloc(al->num_buffers, sizeof(ALuint));
|
||||
al->res_buf = (ALuint*)calloc(al->num_buffers, sizeof(ALuint));
|
||||
if (al->buffers == NULL || al->res_buf == NULL)
|
||||
goto error;
|
||||
|
||||
@ -127,10 +127,9 @@ static bool al_get_buffer(al_t *al, ALuint *buffer)
|
||||
if (al->res_ptr == 0)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
struct timespec tv = {
|
||||
.tv_sec = 0,
|
||||
.tv_nsec = 1000000
|
||||
};
|
||||
struct timespec tv = {0};
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_nsec = 1000000;
|
||||
#endif
|
||||
|
||||
for (;;)
|
||||
@ -155,7 +154,7 @@ static bool al_get_buffer(al_t *al, ALuint *buffer)
|
||||
|
||||
static size_t al_fill_internal_buf(al_t *al, const void *buf, size_t size)
|
||||
{
|
||||
size_t read_size = (BUFSIZE - al->tmpbuf_ptr > size) ? size : (BUFSIZE - al->tmpbuf_ptr);
|
||||
size_t read_size = (BUFSIZE - al->tmpbuf_ptr > (ssize_t)size) ? size : (BUFSIZE - al->tmpbuf_ptr);
|
||||
memcpy(al->tmpbuf + al->tmpbuf_ptr, buf, read_size);
|
||||
al->tmpbuf_ptr += read_size;
|
||||
return read_size;
|
||||
@ -163,7 +162,7 @@ static size_t al_fill_internal_buf(al_t *al, const void *buf, size_t size)
|
||||
|
||||
static ssize_t al_write(void *data, const void *buf, size_t size)
|
||||
{
|
||||
al_t *al = data;
|
||||
al_t *al = (al_t*)data;
|
||||
|
||||
size_t written = 0;
|
||||
while (written < size)
|
||||
@ -204,7 +203,7 @@ static bool al_stop(void *data)
|
||||
|
||||
static void al_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
al_t *al = data;
|
||||
al_t *al = (al_t*)data;
|
||||
al->nonblock = state;
|
||||
}
|
||||
|
||||
@ -216,7 +215,7 @@ static bool al_start(void *data)
|
||||
|
||||
static void al_free(void *data)
|
||||
{
|
||||
al_t *al= data;
|
||||
al_t *al = (al_t*)data;
|
||||
if (al)
|
||||
{
|
||||
alSourceStop(al->source);
|
||||
@ -235,12 +234,13 @@ static void al_free(void *data)
|
||||
}
|
||||
|
||||
const audio_driver_t audio_openal = {
|
||||
.init = al_init,
|
||||
.write = al_write,
|
||||
.stop = al_stop,
|
||||
.start = al_start,
|
||||
.set_nonblock_state = al_set_nonblock_state,
|
||||
.free = al_free,
|
||||
.ident = "openal"
|
||||
al_init,
|
||||
al_write,
|
||||
al_stop,
|
||||
al_start,
|
||||
al_set_nonblock_state,
|
||||
al_free,
|
||||
NULL,
|
||||
"openal"
|
||||
};
|
||||
|
||||
|
27
audio/oss.c
27
audio/oss.c
@ -43,7 +43,7 @@
|
||||
|
||||
static void *oss_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
int *fd = calloc(1, sizeof(int));
|
||||
int *fd = (int*)calloc(1, sizeof(int));
|
||||
if (fd == NULL)
|
||||
return NULL;
|
||||
|
||||
@ -98,7 +98,7 @@ static void *oss_init(const char *device, unsigned rate, unsigned latency)
|
||||
|
||||
static ssize_t oss_write(void *data, const void *buf, size_t size)
|
||||
{
|
||||
int *fd = data;
|
||||
int *fd = (int*)data;
|
||||
|
||||
if (size == 0)
|
||||
return 0;
|
||||
@ -116,7 +116,7 @@ static ssize_t oss_write(void *data, const void *buf, size_t size)
|
||||
|
||||
static bool oss_stop(void *data)
|
||||
{
|
||||
int *fd = data;
|
||||
int *fd = (int*)data;
|
||||
ioctl(*fd, SNDCTL_DSP_RESET, 0);
|
||||
return true;
|
||||
}
|
||||
@ -128,7 +128,7 @@ static bool oss_start(void *data)
|
||||
|
||||
static void oss_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
int *fd = data;
|
||||
int *fd = (int*)data;
|
||||
int rc;
|
||||
if (state)
|
||||
rc = fcntl(*fd, F_SETFL, fcntl(*fd, F_GETFL) | O_NONBLOCK);
|
||||
@ -140,7 +140,7 @@ static void oss_set_nonblock_state(void *data, bool state)
|
||||
|
||||
static void oss_free(void *data)
|
||||
{
|
||||
int *fd = data;
|
||||
int *fd = (int*)data;
|
||||
|
||||
ioctl(*fd, SNDCTL_DSP_RESET, 0);
|
||||
close(*fd);
|
||||
@ -148,12 +148,13 @@ static void oss_free(void *data)
|
||||
}
|
||||
|
||||
const audio_driver_t audio_oss = {
|
||||
.init = oss_init,
|
||||
.write = oss_write,
|
||||
.stop = oss_stop,
|
||||
.start = oss_start,
|
||||
.set_nonblock_state = oss_set_nonblock_state,
|
||||
.free = oss_free,
|
||||
.ident = "oss"
|
||||
oss_init,
|
||||
oss_write,
|
||||
oss_stop,
|
||||
oss_start,
|
||||
oss_set_nonblock_state,
|
||||
oss_free,
|
||||
NULL,
|
||||
"oss"
|
||||
};
|
||||
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
#include "driver.h"
|
||||
#include "general.h"
|
||||
#include <pulse/pulseaudio.h>
|
||||
#include <stdbool.h>
|
||||
#include "../boolean.h"
|
||||
#include <string.h>
|
||||
|
||||
#include <stdio.h>
|
||||
@ -34,7 +34,7 @@ typedef struct
|
||||
|
||||
static void pulse_free(void *data)
|
||||
{
|
||||
pa_t *pa = data;
|
||||
pa_t *pa = (pa_t*)data;
|
||||
if (pa)
|
||||
{
|
||||
if (pa->mainloop)
|
||||
@ -61,7 +61,7 @@ static void pulse_free(void *data)
|
||||
|
||||
static void context_state_cb(pa_context *c, void *data)
|
||||
{
|
||||
pa_t *pa = data;
|
||||
pa_t *pa = (pa_t*)data;
|
||||
switch (pa_context_get_state(c))
|
||||
{
|
||||
case PA_CONTEXT_READY:
|
||||
@ -76,7 +76,7 @@ static void context_state_cb(pa_context *c, void *data)
|
||||
|
||||
static void stream_state_cb(pa_stream *s, void *data)
|
||||
{
|
||||
pa_t *pa = data;
|
||||
pa_t *pa = (pa_t*)data;
|
||||
switch (pa_stream_get_state(s)) {
|
||||
case PA_STREAM_READY:
|
||||
case PA_STREAM_FAILED:
|
||||
@ -92,20 +92,24 @@ static void stream_request_cb(pa_stream *s, size_t length, void *data)
|
||||
{
|
||||
(void)length;
|
||||
(void)s;
|
||||
pa_t *pa = data;
|
||||
pa_t *pa = (pa_t*)data;
|
||||
pa_threaded_mainloop_signal(pa->mainloop, 0);
|
||||
}
|
||||
|
||||
static void stream_latency_update_cb(pa_stream *s, void *data)
|
||||
{
|
||||
(void)s;
|
||||
pa_t *pa = data;
|
||||
pa_t *pa = (pa_t*)data;
|
||||
pa_threaded_mainloop_signal(pa->mainloop, 0);
|
||||
}
|
||||
|
||||
static void *pulse_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
pa_t *pa = calloc(1, sizeof(*pa));
|
||||
pa_sample_spec spec;
|
||||
memset(&spec, 0, sizeof(spec));
|
||||
pa_buffer_attr buffer_attr = {0};
|
||||
|
||||
pa_t *pa = (pa_t*)calloc(1, sizeof(*pa));
|
||||
if (!pa)
|
||||
goto error;
|
||||
|
||||
@ -131,11 +135,9 @@ static void *pulse_init(const char *device, unsigned rate, unsigned latency)
|
||||
if (pa_context_get_state(pa->context) != PA_CONTEXT_READY)
|
||||
goto unlock_error;
|
||||
|
||||
pa_sample_spec spec = {
|
||||
.format = is_little_endian() ? PA_SAMPLE_FLOAT32LE : PA_SAMPLE_FLOAT32BE,
|
||||
.channels = 2,
|
||||
.rate = rate
|
||||
};
|
||||
spec.format = is_little_endian() ? PA_SAMPLE_FLOAT32LE : PA_SAMPLE_FLOAT32BE;
|
||||
spec.channels = 2;
|
||||
spec.rate = rate;
|
||||
|
||||
pa->stream = pa_stream_new(pa->context, "audio", &spec, NULL);
|
||||
if (!pa->stream)
|
||||
@ -145,13 +147,11 @@ static void *pulse_init(const char *device, unsigned rate, unsigned latency)
|
||||
pa_stream_set_write_callback(pa->stream, stream_request_cb, pa);
|
||||
pa_stream_set_latency_update_callback(pa->stream, stream_latency_update_cb, pa);
|
||||
|
||||
pa_buffer_attr buffer_attr = {
|
||||
.maxlength = -1,
|
||||
.tlength = pa_usec_to_bytes(latency * PA_USEC_PER_MSEC, &spec),
|
||||
.prebuf = -1,
|
||||
.minreq = -1,
|
||||
.fragsize = -1
|
||||
};
|
||||
buffer_attr.maxlength = -1;
|
||||
buffer_attr.tlength = pa_usec_to_bytes(latency * PA_USEC_PER_MSEC, &spec);
|
||||
buffer_attr.prebuf = -1;
|
||||
buffer_attr.minreq = -1;
|
||||
buffer_attr.fragsize = -1;
|
||||
|
||||
if (pa_stream_connect_playback(pa->stream, NULL, &buffer_attr, PA_STREAM_ADJUST_LATENCY, NULL, NULL) < 0)
|
||||
goto error;
|
||||
@ -174,7 +174,7 @@ error:
|
||||
|
||||
static ssize_t pulse_write(void *data, const void *buf, size_t size)
|
||||
{
|
||||
pa_t *pa = data;
|
||||
pa_t *pa = (pa_t*)data;
|
||||
|
||||
pa_threaded_mainloop_lock(pa->mainloop);
|
||||
unsigned length = pa_stream_writable_size(pa->stream);
|
||||
@ -212,7 +212,7 @@ static bool pulse_start(void *data)
|
||||
|
||||
static void pulse_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
pa_t *pa = data;
|
||||
pa_t *pa = (pa_t*)data;
|
||||
pa->nonblock = state;
|
||||
}
|
||||
|
||||
@ -223,18 +223,13 @@ static bool pulse_use_float(void *data)
|
||||
}
|
||||
|
||||
const audio_driver_t audio_pulse = {
|
||||
.init = pulse_init,
|
||||
.write = pulse_write,
|
||||
.stop = pulse_stop,
|
||||
.start = pulse_start,
|
||||
.set_nonblock_state = pulse_set_nonblock_state,
|
||||
.use_float = pulse_use_float,
|
||||
.free = pulse_free,
|
||||
.ident = "pulse"
|
||||
pulse_init,
|
||||
pulse_write,
|
||||
pulse_stop,
|
||||
pulse_start,
|
||||
pulse_set_nonblock_state,
|
||||
pulse_free,
|
||||
pulse_use_float,
|
||||
"pulse"
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
30
audio/roar.c
30
audio/roar.c
@ -21,7 +21,7 @@
|
||||
#include <roaraudio.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include "../boolean.h"
|
||||
#include "general.h"
|
||||
|
||||
typedef struct
|
||||
@ -34,7 +34,7 @@ static void *ra_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
(void)latency;
|
||||
int err;
|
||||
roar_t *roar = calloc(1, sizeof(roar_t));
|
||||
roar_t *roar = (roar_t*)calloc(1, sizeof(roar_t));
|
||||
if (roar == NULL)
|
||||
return NULL;
|
||||
|
||||
@ -54,7 +54,7 @@ static void *ra_init(const char *device, unsigned rate, unsigned latency)
|
||||
|
||||
static ssize_t ra_write(void *data, const void *buf, size_t size)
|
||||
{
|
||||
roar_t *roar = data;
|
||||
roar_t *roar = (roar_t*)data;
|
||||
ssize_t rc;
|
||||
|
||||
if (size == 0)
|
||||
@ -86,7 +86,7 @@ static bool ra_stop(void *data)
|
||||
|
||||
static void ra_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
roar_t *roar = data;
|
||||
roar_t *roar = (roar_t*)data;
|
||||
if (roar_vs_blocking(roar->vss, (state) ? ROAR_VS_FALSE : ROAR_VS_TRUE, NULL) < 0)
|
||||
fprintf(stderr, "SSNES [ERROR]: Can't set nonblocking. Will not be able to fast-forward.\n");
|
||||
roar->nonblocking = state;
|
||||
@ -100,23 +100,19 @@ static bool ra_start(void *data)
|
||||
|
||||
static void ra_free(void *data)
|
||||
{
|
||||
roar_t *roar = data;
|
||||
roar_t *roar = (roar_t*)data;
|
||||
roar_vs_close(roar->vss, ROAR_VS_TRUE, NULL);
|
||||
free(data);
|
||||
}
|
||||
|
||||
const audio_driver_t audio_roar = {
|
||||
.init = ra_init,
|
||||
.write = ra_write,
|
||||
.stop = ra_stop,
|
||||
.start = ra_start,
|
||||
.set_nonblock_state = ra_set_nonblock_state,
|
||||
.free = ra_free,
|
||||
.ident = "roar"
|
||||
ra_init,
|
||||
ra_write,
|
||||
ra_stop,
|
||||
ra_start,
|
||||
ra_set_nonblock_state,
|
||||
ra_free,
|
||||
NULL,
|
||||
"roar"
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <rsound.h>
|
||||
#include "fifo_buffer.h"
|
||||
#include <stdbool.h>
|
||||
#include "../boolean.h"
|
||||
#include "SDL.h"
|
||||
|
||||
typedef struct rsd
|
||||
@ -37,7 +37,7 @@ typedef struct rsd
|
||||
|
||||
static ssize_t audio_cb(void *data, size_t bytes, void *userdata)
|
||||
{
|
||||
rsd_t *rsd = userdata;
|
||||
rsd_t *rsd = (rsd_t*)userdata;
|
||||
|
||||
size_t avail = fifo_read_avail(rsd->buffer);
|
||||
size_t write_size = bytes > avail ? avail : bytes;
|
||||
@ -49,14 +49,14 @@ static ssize_t audio_cb(void *data, size_t bytes, void *userdata)
|
||||
|
||||
static void err_cb(void *userdata)
|
||||
{
|
||||
rsd_t *rsd = userdata;
|
||||
rsd_t *rsd = (rsd_t*)userdata;
|
||||
rsd->has_error = true;
|
||||
SDL_CondSignal(rsd->cond);
|
||||
}
|
||||
|
||||
static void *rs_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
rsd_t *rsd = calloc(1, sizeof(rsd_t));
|
||||
rsd_t *rsd = (rsd_t*)calloc(1, sizeof(rsd_t));
|
||||
if (!rsd)
|
||||
return NULL;
|
||||
|
||||
@ -100,7 +100,7 @@ static void *rs_init(const char *device, unsigned rate, unsigned latency)
|
||||
|
||||
static ssize_t rs_write(void *data, const void *buf, size_t size)
|
||||
{
|
||||
rsd_t *rsd = data;
|
||||
rsd_t *rsd = (rsd_t*)data;
|
||||
|
||||
if (rsd->has_error)
|
||||
return -1;
|
||||
@ -146,7 +146,7 @@ static ssize_t rs_write(void *data, const void *buf, size_t size)
|
||||
|
||||
static bool rs_stop(void *data)
|
||||
{
|
||||
rsd_t *rsd = data;
|
||||
rsd_t *rsd = (rsd_t*)data;
|
||||
rsd_stop(rsd->rd);
|
||||
|
||||
return true;
|
||||
@ -154,13 +154,13 @@ static bool rs_stop(void *data)
|
||||
|
||||
static void rs_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
rsd_t *rsd = data;
|
||||
rsd_t *rsd = (rsd_t*)data;
|
||||
rsd->nonblock = state;
|
||||
}
|
||||
|
||||
static bool rs_start(void *data)
|
||||
{
|
||||
rsd_t *rsd = data;
|
||||
rsd_t *rsd = (rsd_t*)data;
|
||||
if (rsd_start(rsd->rd) < 0)
|
||||
return false;
|
||||
|
||||
@ -169,7 +169,7 @@ static bool rs_start(void *data)
|
||||
|
||||
static void rs_free(void *data)
|
||||
{
|
||||
rsd_t *rsd = data;
|
||||
rsd_t *rsd = (rsd_t*)data;
|
||||
|
||||
rsd_stop(rsd->rd);
|
||||
rsd_free(rsd->rd);
|
||||
@ -182,12 +182,13 @@ static void rs_free(void *data)
|
||||
}
|
||||
|
||||
const audio_driver_t audio_rsound = {
|
||||
.init = rs_init,
|
||||
.write = rs_write,
|
||||
.stop = rs_stop,
|
||||
.start = rs_start,
|
||||
.set_nonblock_state = rs_set_nonblock_state,
|
||||
.free = rs_free,
|
||||
.ident = "rsound"
|
||||
rs_init,
|
||||
rs_write,
|
||||
rs_stop,
|
||||
rs_start,
|
||||
rs_set_nonblock_state,
|
||||
rs_free,
|
||||
NULL,
|
||||
"rsound"
|
||||
};
|
||||
|
||||
|
44
audio/sdl.c
44
audio/sdl.c
@ -18,7 +18,7 @@
|
||||
|
||||
#include "driver.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include "../boolean.h"
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
@ -40,10 +40,10 @@ typedef struct sdl_audio
|
||||
|
||||
static void sdl_audio_cb(void *data, Uint8 *stream, int len)
|
||||
{
|
||||
sdl_audio_t *sdl = data;
|
||||
sdl_audio_t *sdl = (sdl_audio_t*)data;
|
||||
|
||||
size_t avail = fifo_read_avail(sdl->buffer);
|
||||
size_t write_size = len > avail ? avail : len;
|
||||
size_t write_size = len > (int)avail ? avail : len;
|
||||
fifo_read(sdl->buffer, stream, write_size);
|
||||
SDL_CondSignal(sdl->cond);
|
||||
|
||||
@ -64,21 +64,20 @@ static void *sdl_audio_init(const char *device, unsigned rate, unsigned latency)
|
||||
if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0)
|
||||
return NULL;
|
||||
|
||||
sdl_audio_t *sdl = calloc(1, sizeof(*sdl));
|
||||
sdl_audio_t *sdl = (sdl_audio_t*)calloc(1, sizeof(*sdl));
|
||||
if (!sdl)
|
||||
return NULL;
|
||||
|
||||
// We have to buffer up some data ourselves, so we let SDL carry approx half of the latency. SDL double buffers audio and we do as well.
|
||||
int frames = find_num_frames(rate, latency / 4);
|
||||
|
||||
SDL_AudioSpec spec = {
|
||||
.freq = rate,
|
||||
.format = AUDIO_S16SYS,
|
||||
.channels = 2,
|
||||
.samples = frames, // This is in audio frames, not samples ... :(
|
||||
.callback = sdl_audio_cb,
|
||||
.userdata = sdl
|
||||
};
|
||||
SDL_AudioSpec spec = {0};
|
||||
spec.freq = rate;
|
||||
spec.format = AUDIO_S16SYS;
|
||||
spec.channels = 2;
|
||||
spec.samples = frames; // This is in audio frames, not samples ... :(
|
||||
spec.callback = sdl_audio_cb;
|
||||
spec.userdata = sdl;
|
||||
|
||||
SDL_AudioSpec out;
|
||||
|
||||
@ -111,7 +110,7 @@ static void *sdl_audio_init(const char *device, unsigned rate, unsigned latency)
|
||||
|
||||
static ssize_t sdl_audio_write(void *data, const void *buf, size_t size)
|
||||
{
|
||||
sdl_audio_t *sdl = data;
|
||||
sdl_audio_t *sdl = (sdl_audio_t*)data;
|
||||
|
||||
ssize_t ret = 0;
|
||||
if (sdl->nonblock)
|
||||
@ -168,7 +167,7 @@ static bool sdl_audio_start(void *data)
|
||||
|
||||
static void sdl_audio_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
sdl_audio_t *sdl = data;
|
||||
sdl_audio_t *sdl = (sdl_audio_t*)data;
|
||||
sdl->nonblock = state;
|
||||
}
|
||||
|
||||
@ -177,7 +176,7 @@ static void sdl_audio_free(void *data)
|
||||
SDL_CloseAudio();
|
||||
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
||||
|
||||
sdl_audio_t *sdl = data;
|
||||
sdl_audio_t *sdl = (sdl_audio_t*)data;
|
||||
if (sdl)
|
||||
{
|
||||
fifo_free(sdl->buffer);
|
||||
@ -188,12 +187,13 @@ static void sdl_audio_free(void *data)
|
||||
}
|
||||
|
||||
const audio_driver_t audio_sdl = {
|
||||
.init = sdl_audio_init,
|
||||
.write = sdl_audio_write,
|
||||
.stop = sdl_audio_stop,
|
||||
.start = sdl_audio_start,
|
||||
.set_nonblock_state = sdl_audio_set_nonblock_state,
|
||||
.free = sdl_audio_free,
|
||||
.ident = "sdl"
|
||||
sdl_audio_init,
|
||||
sdl_audio_write,
|
||||
sdl_audio_stop,
|
||||
sdl_audio_start,
|
||||
sdl_audio_set_nonblock_state,
|
||||
sdl_audio_free,
|
||||
NULL,
|
||||
"sdl"
|
||||
};
|
||||
|
||||
|
@ -30,7 +30,7 @@ struct xaudio2
|
||||
static void WINAPI voice_on_buffer_end(void *handle_, void *data)
|
||||
{
|
||||
(void)data;
|
||||
xaudio2_t *handle = handle_;
|
||||
xaudio2_t *handle = (xaudio2_t*)handle_;
|
||||
InterlockedDecrement(&handle->buffers);
|
||||
SetEvent(handle->hEvent);
|
||||
}
|
||||
@ -41,30 +41,32 @@ static void WINAPI dummy_uint32(void *handle, UINT32 dummy) { (void)handle; (voi
|
||||
static void WINAPI dummy_voidp_hresult(void *handle, void *data, HRESULT dummy) { (void)handle; (void)data; (void)dummy; }
|
||||
|
||||
const struct IXAudio2VoiceCallbackVtbl voice_vtable = {
|
||||
.OnBufferStart = dummy_voidp,
|
||||
.OnBufferEnd = voice_on_buffer_end,
|
||||
.OnLoopEnd = dummy_voidp,
|
||||
.OnVoiceProcessingPassEnd = dummy_nil,
|
||||
.OnVoiceProcessingPassStart = dummy_uint32,
|
||||
.OnVoiceError = dummy_voidp_hresult,
|
||||
.OnStreamEnd = dummy_nil,
|
||||
dummy_uint32,
|
||||
dummy_nil,
|
||||
dummy_nil,
|
||||
dummy_voidp,
|
||||
voice_on_buffer_end,
|
||||
dummy_voidp,
|
||||
dummy_voidp_hresult,
|
||||
};
|
||||
|
||||
xaudio2_t *xaudio2_new(unsigned samplerate, unsigned channels, size_t size)
|
||||
{
|
||||
xaudio2_t *handle = calloc(1, sizeof(*handle));
|
||||
xaudio2_t *handle = (xaudio2_t*)calloc(1, sizeof(*handle));
|
||||
if (!handle)
|
||||
return NULL;
|
||||
|
||||
handle->lpVtbl = &voice_vtable;
|
||||
CoInitializeEx(0, COINIT_MULTITHREADED);
|
||||
WAVEFORMATEX wfx = {0};
|
||||
|
||||
if (FAILED(XAudio2Create(&handle->pXAudio2)))
|
||||
goto error;
|
||||
|
||||
if (FAILED(IXAudio2_CreateMasteringVoice(handle->pXAudio2,
|
||||
&handle->pMasterVoice, channels, samplerate, 0, 0, 0)))
|
||||
goto error;
|
||||
|
||||
WAVEFORMATEX wfx;
|
||||
wfx.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
|
||||
wfx.nChannels = channels;
|
||||
wfx.nSamplesPerSec = samplerate;
|
||||
@ -72,6 +74,7 @@ xaudio2_t *xaudio2_new(unsigned samplerate, unsigned channels, size_t size)
|
||||
wfx.wBitsPerSample = sizeof(float) * 8;
|
||||
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
|
||||
wfx.cbSize = 0;
|
||||
|
||||
if (FAILED(IXAudio2_CreateSourceVoice(handle->pXAudio2,
|
||||
&handle->pSourceVoice, &wfx,
|
||||
XAUDIO2_VOICE_NOSRC, XAUDIO2_DEFAULT_FREQ_RATIO,
|
||||
@ -85,7 +88,7 @@ xaudio2_t *xaudio2_new(unsigned samplerate, unsigned channels, size_t size)
|
||||
IXAudio2SourceVoice_Start(handle->pSourceVoice, 0, XAUDIO2_COMMIT_NOW);
|
||||
|
||||
handle->bufsize = size / MAX_BUFFERS;
|
||||
handle->buf = calloc(1, handle->bufsize * MAX_BUFFERS);
|
||||
handle->buf = (uint8_t*)calloc(1, handle->bufsize * MAX_BUFFERS);
|
||||
if (!handle->buf)
|
||||
goto error;
|
||||
|
||||
@ -104,7 +107,7 @@ size_t xaudio2_write_avail(xaudio2_t *handle)
|
||||
size_t xaudio2_write(xaudio2_t *handle, const void *buf, size_t bytes_)
|
||||
{
|
||||
unsigned bytes = bytes_;
|
||||
const uint8_t *buffer = buf;
|
||||
const uint8_t *buffer = (const uint8_t*)buf;
|
||||
while (bytes)
|
||||
{
|
||||
unsigned need = min(bytes, handle->bufsize - handle->bufptr);
|
||||
@ -120,10 +123,10 @@ size_t xaudio2_write(xaudio2_t *handle, const void *buf, size_t bytes_)
|
||||
while (handle->buffers == MAX_BUFFERS - 1)
|
||||
WaitForSingleObject(handle->hEvent, INFINITE);
|
||||
|
||||
XAUDIO2_BUFFER xa2buffer = {
|
||||
.AudioBytes = handle->bufsize,
|
||||
.pAudioData = handle->buf + handle->write_buffer * handle->bufsize,
|
||||
};
|
||||
XAUDIO2_BUFFER xa2buffer = {0};
|
||||
xa2buffer.AudioBytes = handle->bufsize;
|
||||
xa2buffer.pAudioData = handle->buf + handle->write_buffer * handle->bufsize;
|
||||
|
||||
if (FAILED(IXAudio2SourceVoice_SubmitSourceBuffer(handle->pSourceVoice, &xa2buffer, NULL)))
|
||||
return 0;
|
||||
|
||||
|
@ -8,6 +8,10 @@
|
||||
#ifndef XAUDIO2_MINGW_H
|
||||
#define XAUDIO2_MINGW_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define CINTERFACE
|
||||
#endif
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <basetyps.h>
|
||||
@ -205,6 +209,7 @@ DECLARE_INTERFACE_(IXAudio2, IUnknown)
|
||||
static inline HRESULT XAudio2Create(IXAudio2 **ppXAudio2)
|
||||
{
|
||||
IXAudio2 *pXAudio2;
|
||||
|
||||
HRESULT hr = CoCreateInstance(&CLSID_XAudio2, NULL, CLSCTX_INPROC_SERVER, &IID_IXAudio2, (void**)&pXAudio2);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
|
@ -31,7 +31,7 @@ static void *xa_init(const char *device, unsigned rate, unsigned latency)
|
||||
if (latency < 8)
|
||||
latency = 8; // Do not allow shenanigans.
|
||||
|
||||
xa_t *xa = calloc(1, sizeof(xa_t));
|
||||
xa_t *xa = (xa_t*)calloc(1, sizeof(xa_t));
|
||||
if (xa == NULL)
|
||||
return NULL;
|
||||
|
||||
@ -51,7 +51,7 @@ static void *xa_init(const char *device, unsigned rate, unsigned latency)
|
||||
|
||||
static ssize_t xa_write(void *data, const void *buf, size_t size)
|
||||
{
|
||||
xa_t *xa = data;
|
||||
xa_t *xa = (xa_t*)data;
|
||||
if (xa->nonblock)
|
||||
{
|
||||
size_t avail = xaudio2_write_avail(xa->xa);
|
||||
@ -74,7 +74,7 @@ static bool xa_stop(void *data)
|
||||
|
||||
static void xa_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
xa_t *xa = data;
|
||||
xa_t *xa = (xa_t*)data;
|
||||
xa->nonblock = state;
|
||||
}
|
||||
|
||||
@ -92,7 +92,7 @@ static bool xa_use_float(void *data)
|
||||
|
||||
static void xa_free(void *data)
|
||||
{
|
||||
xa_t *xa = data;
|
||||
xa_t *xa = (xa_t*)data;
|
||||
if (xa)
|
||||
{
|
||||
if (xa->xa)
|
||||
@ -102,13 +102,13 @@ static void xa_free(void *data)
|
||||
}
|
||||
|
||||
const audio_driver_t audio_xa = {
|
||||
.init = xa_init,
|
||||
.write = xa_write,
|
||||
.stop = xa_stop,
|
||||
.start = xa_start,
|
||||
.set_nonblock_state = xa_set_nonblock_state,
|
||||
.use_float = xa_use_float,
|
||||
.free = xa_free,
|
||||
.ident = "xaudio"
|
||||
xa_init,
|
||||
xa_write,
|
||||
xa_stop,
|
||||
xa_start,
|
||||
xa_set_nonblock_state,
|
||||
xa_free,
|
||||
xa_use_float,
|
||||
"xaudio"
|
||||
};
|
||||
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include "autosave.h"
|
||||
#include "thread.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include "boolean.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "general.h"
|
||||
@ -41,7 +41,7 @@ struct autosave
|
||||
|
||||
static void autosave_thread(void *data)
|
||||
{
|
||||
autosave_t *save = data;
|
||||
autosave_t *save = (autosave_t*)data;
|
||||
|
||||
bool first_log = true;
|
||||
|
||||
@ -86,7 +86,7 @@ static void autosave_thread(void *data)
|
||||
|
||||
autosave_t *autosave_new(const char *path, const void *data, size_t size, unsigned interval)
|
||||
{
|
||||
autosave_t *handle = calloc(1, sizeof(*handle));
|
||||
autosave_t *handle = (autosave_t*)calloc(1, sizeof(*handle));
|
||||
if (!handle)
|
||||
return NULL;
|
||||
|
||||
|
26
boolean.h
Normal file
26
boolean.h
Normal file
@ -0,0 +1,26 @@
|
||||
/* SSNES - A Super Nintendo Entertainment System (SNES) Emulator frontend for libsnes.
|
||||
* Copyright (C) 2010-2011 - Hans-Kristian Arntzen
|
||||
*
|
||||
* Some code herein may be based on code found in BSNES.
|
||||
*
|
||||
* SSNES 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 Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* SSNES 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 SSNES.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __SSNES_BOOLEAN_H
|
||||
#define __SSNES_BOOLEAN_H
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
22
bps.c
22
bps.c
@ -18,7 +18,7 @@
|
||||
#include "bps.h"
|
||||
#include "movie.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "boolean.h"
|
||||
|
||||
enum bps_mode
|
||||
{
|
||||
@ -77,17 +77,15 @@ bps_error_t bps_apply_patch(
|
||||
if (modify_length < 19)
|
||||
return BPS_PATCH_TOO_SMALL;
|
||||
|
||||
struct bps_data bps = {
|
||||
.modify_data = modify_data,
|
||||
.modify_length = modify_length,
|
||||
.target_data = target_data,
|
||||
.target_length = *target_length,
|
||||
.source_data = source_data,
|
||||
.source_length = source_length,
|
||||
|
||||
.modify_checksum = ~0,
|
||||
.target_checksum = ~0,
|
||||
};
|
||||
struct bps_data bps = {0};
|
||||
bps.modify_data = modify_data;
|
||||
bps.modify_length = modify_length;
|
||||
bps.target_data = target_data;
|
||||
bps.target_length = *target_length;
|
||||
bps.source_data = source_data;
|
||||
bps.source_length = source_length;
|
||||
bps.modify_checksum = ~0;
|
||||
bps.target_checksum = ~0;
|
||||
|
||||
if ((bps_read(&bps) != 'B') || (bps_read(&bps) != 'P') || (bps_read(&bps) != 'S') || (bps_read(&bps) != '1'))
|
||||
return BPS_PATCH_INVALID_HEADER;
|
||||
|
14
cheats.c
14
cheats.c
@ -57,7 +57,7 @@ static char *strcat_alloc(char *dest, const char *input)
|
||||
size_t input_len = strlen(input);
|
||||
size_t required_len = dest_len + input_len + 1;
|
||||
|
||||
char *output = realloc(dest, required_len);
|
||||
char *output = (char*)realloc(dest, required_len);
|
||||
if (!output)
|
||||
return NULL;
|
||||
|
||||
@ -126,7 +126,7 @@ static bool xml_grab_cheats(cheat_manager_t *handle, xmlNodePtr ptr)
|
||||
if (handle->size == handle->buf_size)
|
||||
{
|
||||
handle->buf_size *= 2;
|
||||
handle->cheats = realloc(handle->cheats, handle->buf_size * sizeof(struct cheat));
|
||||
handle->cheats = (struct cheat*)realloc(handle->cheats, handle->buf_size * sizeof(struct cheat));
|
||||
if (!handle->cheats)
|
||||
return false;
|
||||
}
|
||||
@ -242,12 +242,15 @@ cheat_manager_t* cheat_manager_new(const char *path)
|
||||
|
||||
xmlParserCtxtPtr ctx = NULL;
|
||||
xmlDocPtr doc = NULL;
|
||||
cheat_manager_t *handle = calloc(1, sizeof(struct cheat_manager));
|
||||
cheat_manager_t *handle = (cheat_manager_t*)calloc(1, sizeof(struct cheat_manager));
|
||||
if (!handle)
|
||||
return NULL;
|
||||
|
||||
xmlNodePtr head = NULL;
|
||||
xmlNodePtr cur = NULL;
|
||||
|
||||
handle->buf_size = 1;
|
||||
handle->cheats = calloc(handle->buf_size, sizeof(struct cheat));
|
||||
handle->cheats = (struct cheat*)calloc(handle->buf_size, sizeof(struct cheat));
|
||||
if (!handle->cheats)
|
||||
{
|
||||
handle->buf_size = 0;
|
||||
@ -271,8 +274,7 @@ cheat_manager_t* cheat_manager_new(const char *path)
|
||||
goto error;
|
||||
}
|
||||
|
||||
xmlNodePtr head = xmlDocGetRootElement(doc);
|
||||
xmlNodePtr cur = NULL;
|
||||
head = xmlDocGetRootElement(doc);
|
||||
for (cur = head; cur; cur = cur->next)
|
||||
{
|
||||
if (cur->type == XML_ELEMENT_NODE && strcmp((const char*)cur->name, "database") == 0)
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include "../strl.h"
|
||||
#include "../posix_string.h"
|
||||
|
||||
#if !defined(_WIN32) && !defined(__CELLOS_LV2__)
|
||||
#include <sys/param.h> // MAXPATHLEN
|
||||
@ -69,7 +70,7 @@ static config_file_t *config_file_new_internal(const char *path, unsigned depth)
|
||||
|
||||
static char *getaline(FILE *file)
|
||||
{
|
||||
char *newline = malloc(9);
|
||||
char *newline = (char*)malloc(9);
|
||||
size_t cur_size = 8;
|
||||
size_t index = 0;
|
||||
|
||||
@ -79,7 +80,7 @@ static char *getaline(FILE *file)
|
||||
if (index == cur_size)
|
||||
{
|
||||
cur_size *= 2;
|
||||
newline = realloc(newline, cur_size + 1);
|
||||
newline = (char*)realloc(newline, cur_size + 1);
|
||||
}
|
||||
|
||||
newline[index++] = in;
|
||||
@ -98,7 +99,7 @@ static char *extract_value(char *line, bool is_value)
|
||||
|
||||
// If we don't have an equal sign here, we've got an invalid string...
|
||||
if (*line != '=')
|
||||
return false;
|
||||
return NULL;
|
||||
|
||||
line++;
|
||||
}
|
||||
@ -112,7 +113,7 @@ static char *extract_value(char *line, bool is_value)
|
||||
line++;
|
||||
char *tok = strtok(line, "\"");
|
||||
if (!tok)
|
||||
return false;
|
||||
return NULL;
|
||||
return strdup(tok);
|
||||
}
|
||||
else if (*line == '\0') // Nothing :(
|
||||
@ -171,7 +172,7 @@ static void add_child_list(config_file_t *parent, config_file_t *child)
|
||||
static void add_include_list(config_file_t *conf, const char *path)
|
||||
{
|
||||
struct include_list *head = conf->includes;
|
||||
struct include_list *node = calloc(1, sizeof(*node));
|
||||
struct include_list *node = (struct include_list*)calloc(1, sizeof(*node));
|
||||
node->path = strdup(path);
|
||||
|
||||
if (head)
|
||||
@ -278,7 +279,7 @@ static bool parse_line(config_file_t *conf, struct entry_list *list, char *line)
|
||||
while (isspace(*line))
|
||||
line++;
|
||||
|
||||
char *key = malloc(9);
|
||||
char *key = (char*)malloc(9);
|
||||
size_t cur_size = 8;
|
||||
size_t index = 0;
|
||||
|
||||
@ -287,7 +288,7 @@ static bool parse_line(config_file_t *conf, struct entry_list *list, char *line)
|
||||
if (index == cur_size)
|
||||
{
|
||||
cur_size *= 2;
|
||||
key = realloc(key, cur_size + 1);
|
||||
key = (char*)realloc(key, cur_size + 1);
|
||||
}
|
||||
|
||||
key[index++] = *line++;
|
||||
@ -308,7 +309,7 @@ static bool parse_line(config_file_t *conf, struct entry_list *list, char *line)
|
||||
|
||||
static config_file_t *config_file_new_internal(const char *path, unsigned depth)
|
||||
{
|
||||
struct config_file *conf = calloc(1, sizeof(*conf));
|
||||
struct config_file *conf = (struct config_file*)calloc(1, sizeof(*conf));
|
||||
if (!conf)
|
||||
return NULL;
|
||||
|
||||
@ -334,7 +335,7 @@ static config_file_t *config_file_new_internal(const char *path, unsigned depth)
|
||||
|
||||
while (!feof(file))
|
||||
{
|
||||
struct entry_list *list = calloc(1, sizeof(*list));
|
||||
struct entry_list *list = (struct entry_list*)calloc(1, sizeof(*list));
|
||||
char *line = getaline(file);
|
||||
|
||||
if (line)
|
||||
@ -552,7 +553,7 @@ void config_set_string(config_file_t *conf, const char *key, const char *val)
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
struct entry_list *elem = calloc(1, sizeof(*elem));
|
||||
struct entry_list *elem = (struct entry_list*)calloc(1, sizeof(*elem));
|
||||
elem->key = strdup(key);
|
||||
elem->value = strdup(val);
|
||||
|
||||
@ -565,7 +566,11 @@ void config_set_string(config_file_t *conf, const char *key, const char *val)
|
||||
void config_set_double(config_file_t *conf, const char *key, double val)
|
||||
{
|
||||
char buf[128];
|
||||
#ifdef __cplusplus
|
||||
snprintf(buf, sizeof(buf), "%f", (float)val);
|
||||
#else
|
||||
snprintf(buf, sizeof(buf), "%lf", val);
|
||||
#endif
|
||||
config_set_string(conf, key, buf);
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
#define __CONFIG_FILE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "../boolean.h"
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
#ifndef __CONFIG_DEF_H
|
||||
#define __CONFIG_DEF_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "boolean.h"
|
||||
#include "libsnes.hpp"
|
||||
#include "driver.h"
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
#define __SSNES_FEATURES_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include "boolean.h"
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
|
52
driver.c
52
driver.c
@ -23,6 +23,7 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include "posix_string.h"
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
@ -127,7 +128,7 @@ static void find_audio_driver(void)
|
||||
}
|
||||
SSNES_ERR("Couldn't find any audio driver named \"%s\"\n", g_settings.audio.driver);
|
||||
fprintf(stderr, "Available audio drivers are:\n");
|
||||
for (unsigned i = 0; i < sizeof(audio_drivers) / sizeof(audio_driver_t*); i++)
|
||||
for (size_t i = 0; i < sizeof(audio_drivers) / sizeof(audio_driver_t*); i++)
|
||||
fprintf(stderr, "\t%s\n", audio_drivers[i]->ident);
|
||||
|
||||
exit(1);
|
||||
@ -145,7 +146,7 @@ static void find_video_driver(void)
|
||||
}
|
||||
SSNES_ERR("Couldn't find any video driver named \"%s\"\n", g_settings.video.driver);
|
||||
fprintf(stderr, "Available video drivers are:\n");
|
||||
for (int i = 0; i < sizeof(video_drivers) / sizeof(video_driver_t*); i++)
|
||||
for (size_t i = 0; i < sizeof(video_drivers) / sizeof(video_driver_t*); i++)
|
||||
fprintf(stderr, "\t%s\n", video_drivers[i]->ident);
|
||||
|
||||
exit(1);
|
||||
@ -163,7 +164,7 @@ static void find_input_driver(void)
|
||||
}
|
||||
SSNES_ERR("Couldn't find any input driver named \"%s\"\n", g_settings.input.driver);
|
||||
fprintf(stderr, "Available input drivers are:\n");
|
||||
for (int i = 0; i < sizeof(input_drivers) / sizeof(input_driver_t*); i++)
|
||||
for (size_t i = 0; i < sizeof(input_drivers) / sizeof(input_driver_t*); i++)
|
||||
fprintf(stderr, "\t%s\n", input_drivers[i]->ident);
|
||||
|
||||
exit(1);
|
||||
@ -186,6 +187,7 @@ static void init_dsp_plugin(void)
|
||||
{
|
||||
if (!(*g_settings.audio.dsp_plugin))
|
||||
return;
|
||||
ssnes_dsp_info_t info = {0};
|
||||
|
||||
g_extern.audio_data.dsp_lib = dylib_load(g_settings.audio.dsp_plugin);
|
||||
if (!g_extern.audio_data.dsp_lib)
|
||||
@ -217,10 +219,8 @@ static void init_dsp_plugin(void)
|
||||
|
||||
SSNES_LOG("Loaded DSP plugin: \"%s\"\n", g_extern.audio_data.dsp_plugin->ident ? g_extern.audio_data.dsp_plugin->ident : "Unknown");
|
||||
|
||||
const ssnes_dsp_info_t info = {
|
||||
.input_rate = g_settings.audio.in_rate,
|
||||
.output_rate = g_settings.audio.out_rate
|
||||
};
|
||||
info.input_rate = g_settings.audio.in_rate;
|
||||
info.output_rate = g_settings.audio.out_rate;
|
||||
|
||||
g_extern.audio_data.dsp_handle = g_extern.audio_data.dsp_plugin->init(&info);
|
||||
if (!g_extern.audio_data.dsp_handle)
|
||||
@ -259,9 +259,9 @@ static void adjust_audio_input_rate(void)
|
||||
float timing_skew = fabs(1.0f - g_extern.system.timing.fps / g_settings.video.refresh_rate);
|
||||
if (timing_skew > 0.05f) // We don't want to adjust pitch too much. If we have extreme cases, just don't readjust at all.
|
||||
{
|
||||
SSNES_LOG("Timings deviate too much. Will not adjust. (Display = %.2f Hz, Game = %.2lf Hz)\n",
|
||||
SSNES_LOG("Timings deviate too much. Will not adjust. (Display = %.2f Hz, Game = %.2f Hz)\n",
|
||||
g_settings.video.refresh_rate,
|
||||
g_extern.system.timing.fps);
|
||||
(float)g_extern.system.timing.fps);
|
||||
|
||||
g_settings.video.refresh_rate = g_extern.system.timing.fps;
|
||||
}
|
||||
@ -282,20 +282,17 @@ static void adjust_audio_input_rate(void)
|
||||
first = false;
|
||||
}
|
||||
|
||||
#define AUDIO_CHUNK_SIZE_BLOCKING 64
|
||||
#define AUDIO_CHUNK_SIZE_NONBLOCKING 2048 // So we don't get complete line-noise when fast-forwarding audio.
|
||||
#define AUDIO_MAX_RATIO 16
|
||||
void init_audio(void)
|
||||
{
|
||||
// Accomodate rewind since at some point we might have two full buffers.
|
||||
size_t max_bufsamples = AUDIO_CHUNK_SIZE_NONBLOCKING * 2;
|
||||
|
||||
// Used for recording even if audio isn't enabled.
|
||||
assert((g_extern.audio_data.conv_outsamples = malloc(max_bufsamples * sizeof(int16_t) * AUDIO_MAX_RATIO)));
|
||||
assert((g_extern.audio_data.conv_outsamples = (int16_t*)malloc(max_bufsamples * sizeof(int16_t) * AUDIO_MAX_RATIO)));
|
||||
g_extern.audio_data.chunk_size = g_extern.audio_data.block_chunk_size;
|
||||
|
||||
// Needs to be able to hold full content of a full max_bufsamples in addition to its own.
|
||||
assert((g_extern.audio_data.rewind_buf = malloc(max_bufsamples * sizeof(int16_t))));
|
||||
assert((g_extern.audio_data.rewind_buf = (int16_t*)malloc(max_bufsamples * sizeof(int16_t))));
|
||||
g_extern.audio_data.rewind_size = max_bufsamples;
|
||||
|
||||
if (!g_settings.audio.enable)
|
||||
@ -329,10 +326,10 @@ void init_audio(void)
|
||||
if (!g_extern.audio_data.source)
|
||||
g_extern.audio_active = false;
|
||||
|
||||
assert((g_extern.audio_data.data = malloc(max_bufsamples * sizeof(float))));
|
||||
assert((g_extern.audio_data.data = (float*)malloc(max_bufsamples * sizeof(float))));
|
||||
g_extern.audio_data.data_ptr = 0;
|
||||
assert(g_settings.audio.out_rate < g_settings.audio.in_rate * AUDIO_MAX_RATIO);
|
||||
assert((g_extern.audio_data.outsamples = malloc(max_bufsamples * sizeof(float) * AUDIO_MAX_RATIO)));
|
||||
assert((g_extern.audio_data.outsamples = (float*)malloc(max_bufsamples * sizeof(float) * AUDIO_MAX_RATIO)));
|
||||
|
||||
g_extern.audio_data.src_ratio =
|
||||
(double)g_settings.audio.out_rate / g_settings.audio.in_rate;
|
||||
@ -412,11 +409,11 @@ static void init_filter(void)
|
||||
unsigned maxsize = pow2_x > pow2_y ? pow2_x : pow2_y;
|
||||
g_extern.filter.scale = maxsize / SSNES_SCALE_BASE;
|
||||
|
||||
g_extern.filter.buffer = malloc(SSNES_SCALE_BASE * SSNES_SCALE_BASE * g_extern.filter.scale * g_extern.filter.scale * sizeof(uint32_t));
|
||||
g_extern.filter.buffer = (uint32_t*)malloc(SSNES_SCALE_BASE * SSNES_SCALE_BASE * g_extern.filter.scale * g_extern.filter.scale * sizeof(uint32_t));
|
||||
g_extern.filter.pitch = SSNES_SCALE_BASE * g_extern.filter.scale * sizeof(uint32_t);
|
||||
assert(g_extern.filter.buffer);
|
||||
|
||||
g_extern.filter.colormap = malloc(32768 * sizeof(uint32_t));
|
||||
g_extern.filter.colormap = (uint32_t*)malloc(32768 * sizeof(uint32_t));
|
||||
assert(g_extern.filter.colormap);
|
||||
|
||||
// Set up conversion map from 16-bit XRGB1555 to 32-bit ARGB.
|
||||
@ -524,16 +521,15 @@ void init_video_input(void)
|
||||
|
||||
SSNES_LOG("Video @ %ux%u\n", width, height);
|
||||
|
||||
video_info_t video = {
|
||||
.width = width,
|
||||
.height = height,
|
||||
.fullscreen = g_settings.video.fullscreen,
|
||||
.vsync = g_settings.video.vsync,
|
||||
.force_aspect = g_settings.video.force_aspect,
|
||||
.smooth = g_settings.video.smooth,
|
||||
.input_scale = scale,
|
||||
.rgb32 = g_extern.filter.active
|
||||
};
|
||||
video_info_t video = {0};
|
||||
video.width = width;
|
||||
video.height = height;
|
||||
video.fullscreen = g_settings.video.fullscreen;
|
||||
video.vsync = g_settings.video.vsync;
|
||||
video.force_aspect = g_settings.video.force_aspect;
|
||||
video.smooth = g_settings.video.smooth;
|
||||
video.input_scale = scale;
|
||||
video.rgb32 = g_extern.filter.active;
|
||||
|
||||
const input_driver_t *tmp = driver.input;
|
||||
driver.video_data = driver.video->init(&video, &driver.input, &driver.input_data);
|
||||
|
8
driver.h
8
driver.h
@ -20,12 +20,16 @@
|
||||
#define __DRIVER__H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
#include "boolean.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include "input/keysym.h"
|
||||
|
||||
#define AUDIO_CHUNK_SIZE_BLOCKING 64
|
||||
#define AUDIO_CHUNK_SIZE_NONBLOCKING 2048 // So we don't get complete line-noise when fast-forwarding audio.
|
||||
#define AUDIO_MAX_RATIO 16
|
||||
|
||||
// SNES has 12 buttons from 0-11 (libsnes.hpp)
|
||||
#define SSNES_FIRST_META_KEY 12
|
||||
enum
|
||||
@ -57,7 +61,6 @@ enum
|
||||
SSNES_BIND_LIST_END
|
||||
};
|
||||
|
||||
|
||||
struct snes_keybind
|
||||
{
|
||||
int id;
|
||||
@ -133,7 +136,6 @@ typedef struct video_driver
|
||||
const char *ident;
|
||||
} video_driver_t;
|
||||
|
||||
|
||||
typedef struct driver
|
||||
{
|
||||
const audio_driver_t *audio;
|
||||
|
19
dynamic.c
19
dynamic.c
@ -25,7 +25,7 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "boolean.h"
|
||||
#include "libsnes.hpp"
|
||||
|
||||
#ifdef NEED_DYNAMIC
|
||||
@ -250,7 +250,7 @@ dylib_t dylib_load(const char *path)
|
||||
function_t dylib_proc(dylib_t lib, const char *proc)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
function_t sym = (function_t)GetProcAddress(lib ? lib : GetModuleHandle(NULL), proc);
|
||||
function_t sym = (function_t)GetProcAddress(lib ? (HMODULE)lib : GetModuleHandle(NULL), proc);
|
||||
#else
|
||||
void *ptr_sym = NULL;
|
||||
if (lib)
|
||||
@ -276,7 +276,7 @@ function_t dylib_proc(dylib_t lib, const char *proc)
|
||||
void dylib_close(dylib_t lib)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
FreeLibrary(lib);
|
||||
FreeLibrary((HMODULE)lib);
|
||||
#else
|
||||
dlclose(lib);
|
||||
#endif
|
||||
@ -315,7 +315,8 @@ static bool environment_cb(unsigned cmd, void *data)
|
||||
case SNES_ENVIRONMENT_SET_TIMING:
|
||||
g_extern.system.timing = *(const struct snes_system_timing*)data;
|
||||
g_extern.system.timing_set = true;
|
||||
SSNES_LOG("Environ SET_TIMING: %.3lf Hz/ %.3lf Hz\n", g_extern.system.timing.fps, g_extern.system.timing.sample_rate);
|
||||
SSNES_LOG("Environ SET_TIMING: %.3f Hz/ %.3f Hz\n",
|
||||
(float)g_extern.system.timing.fps, (float)g_extern.system.timing.sample_rate);
|
||||
break;
|
||||
|
||||
case SNES_ENVIRONMENT_GET_CAN_DUPE:
|
||||
@ -363,11 +364,9 @@ static void set_environment_defaults(void)
|
||||
{
|
||||
SSNES_LOG("Setting environment defaults (SNES)\n");
|
||||
g_extern.system.pitch = 0; // 0 is classic libsnes semantics.
|
||||
g_extern.system.geom = (struct snes_geometry) {
|
||||
.base_width = 256,
|
||||
.base_height = 224,
|
||||
.max_width = 512,
|
||||
.max_height = 512,
|
||||
};
|
||||
g_extern.system.geom.base_width = 256;
|
||||
g_extern.system.geom.base_height = 224;
|
||||
g_extern.system.geom.max_width = 512;
|
||||
g_extern.system.geom.max_height = 512;
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
#ifndef __DYNAMIC_H
|
||||
#define __DYNAMIC_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "boolean.h"
|
||||
#include "libsnes.hpp"
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
|
@ -26,11 +26,11 @@ struct fifo_buffer
|
||||
|
||||
fifo_buffer_t *fifo_new(size_t size)
|
||||
{
|
||||
fifo_buffer_t *buf = calloc(1, sizeof(*buf));
|
||||
fifo_buffer_t *buf = (fifo_buffer_t*)calloc(1, sizeof(*buf));
|
||||
if (buf == NULL)
|
||||
return NULL;
|
||||
|
||||
buf->buffer = calloc(1, size + 1);
|
||||
buf->buffer = (uint8_t*)calloc(1, size + 1);
|
||||
if (buf->buffer == NULL)
|
||||
{
|
||||
free(buf);
|
||||
|
81
file.c
81
file.c
@ -18,7 +18,7 @@
|
||||
#include "file.h"
|
||||
#include "general.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include "boolean.h"
|
||||
#include "libsnes.hpp"
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
@ -49,12 +49,13 @@ ssize_t read_file(const char *path, void **buf)
|
||||
{
|
||||
void *rom_buf = NULL;
|
||||
FILE *file = fopen(path, "rb");
|
||||
ssize_t rc = 0;
|
||||
size_t len = 0;
|
||||
if (!file)
|
||||
goto error;
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
long len = ftell(file);
|
||||
ssize_t rc = 0;
|
||||
len = ftell(file);
|
||||
rewind(file);
|
||||
rom_buf = malloc(len + 1);
|
||||
if (!rom_buf)
|
||||
@ -63,7 +64,7 @@ ssize_t read_file(const char *path, void **buf)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((rc = fread(rom_buf, 1, len, file)) < len)
|
||||
if ((rc = fread(rom_buf, 1, len, file)) < (ssize_t)len)
|
||||
SSNES_WARN("Didn't read whole file.\n");
|
||||
|
||||
*buf = rom_buf;
|
||||
@ -86,18 +87,21 @@ bool read_file_string(const char *path, char **buf)
|
||||
{
|
||||
*buf = NULL;
|
||||
FILE *file = fopen(path, "r");
|
||||
size_t len = 0;
|
||||
char *ptr = NULL;
|
||||
|
||||
if (!file)
|
||||
goto error;
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
long len = ftell(file) + 2; // Takes account of being able to read in EOF and '\0' at end.
|
||||
len = ftell(file) + 2; // Takes account of being able to read in EOF and '\0' at end.
|
||||
rewind(file);
|
||||
|
||||
*buf = calloc(len, sizeof(char));
|
||||
*buf = (char*)calloc(len, sizeof(char));
|
||||
if (!*buf)
|
||||
goto error;
|
||||
|
||||
char *ptr = *buf;
|
||||
ptr = *buf;
|
||||
|
||||
while (ptr && !feof(file))
|
||||
{
|
||||
@ -136,6 +140,7 @@ static void patch_rom(uint8_t **buf, ssize_t *size)
|
||||
ssize_t patch_size = 0;
|
||||
void *patch_data = NULL;
|
||||
enum patch_type type = PATCH_NONE;
|
||||
bool success = false;
|
||||
|
||||
if (g_extern.ups_pref && g_extern.bps_pref)
|
||||
{
|
||||
@ -168,19 +173,18 @@ static void patch_rom(uint8_t **buf, ssize_t *size)
|
||||
}
|
||||
|
||||
size_t target_size = ret_size * 4; // Just to be sure ...
|
||||
uint8_t *patched_rom = malloc(target_size);
|
||||
uint8_t *patched_rom = (uint8_t*)malloc(target_size);
|
||||
if (!patched_rom)
|
||||
{
|
||||
SSNES_ERR("Failed to allocate memory for patched ROM ...\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
switch (type)
|
||||
{
|
||||
case PATCH_UPS:
|
||||
{
|
||||
ups_error_t err = ups_apply_patch(patch_data, patch_size, ret_buf, ret_size, patched_rom, &target_size);
|
||||
ups_error_t err = ups_apply_patch((const uint8_t*)patch_data, patch_size, ret_buf, ret_size, patched_rom, &target_size);
|
||||
if (err == UPS_SUCCESS)
|
||||
{
|
||||
SSNES_LOG("ROM patched successfully (UPS)!\n");
|
||||
@ -194,7 +198,7 @@ static void patch_rom(uint8_t **buf, ssize_t *size)
|
||||
|
||||
case PATCH_BPS:
|
||||
{
|
||||
bps_error_t err = bps_apply_patch(patch_data, patch_size, ret_buf, ret_size, patched_rom, &target_size);
|
||||
bps_error_t err = bps_apply_patch((const uint8_t*)patch_data, patch_size, ret_buf, ret_size, patched_rom, &target_size);
|
||||
if (err == BPS_SUCCESS)
|
||||
{
|
||||
SSNES_LOG("ROM patched successfully (BPS)!\n");
|
||||
@ -244,7 +248,7 @@ static ssize_t read_rom_file(FILE* file, void** buf)
|
||||
SSNES_LOG("Reading ROM from stdin ...\n");
|
||||
size_t buf_size = 0xFFFFF; // Some initial guesstimate.
|
||||
size_t buf_ptr = 0;
|
||||
uint8_t *rom_buf = malloc(buf_size);
|
||||
uint8_t *rom_buf = (uint8_t*)malloc(buf_size);
|
||||
if (rom_buf == NULL)
|
||||
{
|
||||
SSNES_ERR("Couldn't allocate memory!\n");
|
||||
@ -260,7 +264,7 @@ static ssize_t read_rom_file(FILE* file, void** buf)
|
||||
if (buf_ptr < buf_size)
|
||||
break;
|
||||
|
||||
rom_buf = realloc(rom_buf, buf_size * 2);
|
||||
rom_buf = (uint8_t*)realloc(rom_buf, buf_size * 2);
|
||||
if (rom_buf == NULL)
|
||||
{
|
||||
SSNES_ERR("Couldn't allocate memory!\n");
|
||||
@ -286,14 +290,14 @@ static ssize_t read_rom_file(FILE* file, void** buf)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fread(rom_buf, 1, ret, file) < ret)
|
||||
if (fread(rom_buf, 1, ret, file) < (size_t)ret)
|
||||
{
|
||||
SSNES_ERR("Didn't read whole file.\n");
|
||||
free(rom_buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret_buf = rom_buf;
|
||||
ret_buf = (uint8_t*)rom_buf;
|
||||
}
|
||||
|
||||
// Remove copier header if present (512 first bytes).
|
||||
@ -406,7 +410,7 @@ bool save_state(const char *path)
|
||||
}
|
||||
|
||||
SSNES_LOG("State size: %d bytes.\n", (int)size);
|
||||
psnes_serialize(data, size);
|
||||
psnes_serialize((uint8_t*)data, size);
|
||||
bool ret = dump_to_file(path, data, size);
|
||||
free(data);
|
||||
if (!ret)
|
||||
@ -466,7 +470,7 @@ bool load_state(const char *path)
|
||||
|
||||
for (unsigned i = 0; i < 2; i++)
|
||||
if (block_size[i])
|
||||
block_buf[i] = malloc(block_size[i]);
|
||||
block_buf[i] = (uint8_t*)malloc(block_size[i]);
|
||||
|
||||
// Backup current SRAM which is overwritten by unserialize.
|
||||
for (unsigned i = 0; i < 2; i++)
|
||||
@ -479,7 +483,7 @@ bool load_state(const char *path)
|
||||
}
|
||||
}
|
||||
|
||||
psnes_unserialize(buf, size);
|
||||
psnes_unserialize((uint8_t*)buf, size);
|
||||
|
||||
// Flush back :D
|
||||
for (unsigned i = 0; i < 2; i++)
|
||||
@ -511,7 +515,7 @@ void load_ram_file(const char *path, int type)
|
||||
|
||||
void *buf = NULL;
|
||||
ssize_t rc = read_file(path, &buf);
|
||||
if (rc <= size)
|
||||
if (rc <= (ssize_t)size)
|
||||
memcpy(data, buf, rc);
|
||||
|
||||
free(buf);
|
||||
@ -555,6 +559,7 @@ static bool load_sgb_rom(void)
|
||||
FILE *extra_rom = NULL;
|
||||
void *extra_rom_buf = NULL;
|
||||
ssize_t extra_rom_len = 0;
|
||||
char *xml_buf = 0;
|
||||
|
||||
if ((rom_len = read_rom_file(g_extern.rom_file, &rom_buf)) == -1)
|
||||
{
|
||||
@ -568,11 +573,11 @@ static bool load_sgb_rom(void)
|
||||
goto error;
|
||||
}
|
||||
|
||||
char *xml_buf = load_xml_map(g_extern.xml_name);
|
||||
xml_buf = load_xml_map(g_extern.xml_name);
|
||||
|
||||
if (!psnes_load_cartridge_super_game_boy(
|
||||
xml_buf, rom_buf, rom_len,
|
||||
NULL, extra_rom_buf, extra_rom_len))
|
||||
xml_buf, (const uint8_t*)rom_buf, rom_len,
|
||||
NULL, (const uint8_t*)extra_rom_buf, extra_rom_len))
|
||||
{
|
||||
SSNES_ERR("Cannot load SGB/GameBoy rom.\n");
|
||||
goto error;
|
||||
@ -607,6 +612,7 @@ static bool load_bsx_rom(bool slotted)
|
||||
FILE *extra_rom = NULL;
|
||||
void *extra_rom_buf = NULL;
|
||||
ssize_t extra_rom_len = 0;
|
||||
char *xml_buf = 0;
|
||||
|
||||
if ((rom_len = read_rom_file(g_extern.rom_file, &rom_buf)) == -1)
|
||||
{
|
||||
@ -620,13 +626,13 @@ static bool load_bsx_rom(bool slotted)
|
||||
goto error;
|
||||
}
|
||||
|
||||
char *xml_buf = load_xml_map(g_extern.xml_name);
|
||||
xml_buf = load_xml_map(g_extern.xml_name);
|
||||
|
||||
if (slotted)
|
||||
{
|
||||
if (!psnes_load_cartridge_bsx_slotted(
|
||||
xml_buf, rom_buf, rom_len,
|
||||
NULL, extra_rom_buf, extra_rom_len))
|
||||
xml_buf, (const uint8_t*)rom_buf, rom_len,
|
||||
NULL, (const uint8_t*)extra_rom_buf, extra_rom_len))
|
||||
{
|
||||
SSNES_ERR("Cannot load BSX slotted rom.\n");
|
||||
goto error;
|
||||
@ -636,8 +642,8 @@ static bool load_bsx_rom(bool slotted)
|
||||
else
|
||||
{
|
||||
if (!psnes_load_cartridge_bsx(
|
||||
NULL, rom_buf, rom_len,
|
||||
NULL, extra_rom_buf, extra_rom_len))
|
||||
NULL, (const uint8_t*)rom_buf, rom_len,
|
||||
NULL, (const uint8_t*)extra_rom_buf, extra_rom_len))
|
||||
{
|
||||
SSNES_ERR("Cannot load BSX rom.\n");
|
||||
goto error;
|
||||
@ -673,6 +679,8 @@ static bool load_sufami_rom(void)
|
||||
FILE *extra_rom[2] = {NULL};
|
||||
void *extra_rom_buf[2] = {NULL};
|
||||
ssize_t extra_rom_len[2] = {0};
|
||||
char *xml_buf = 0;
|
||||
const char *roms[2] = {0};
|
||||
|
||||
if ((rom_len = read_rom_file(g_extern.rom_file, &rom_buf)) == -1)
|
||||
{
|
||||
@ -680,7 +688,8 @@ static bool load_sufami_rom(void)
|
||||
goto error;
|
||||
}
|
||||
|
||||
const char *roms[2] = { g_extern.sufami_rom_path[0], g_extern.sufami_rom_path[1] };
|
||||
roms[0] = g_extern.sufami_rom_path[0];
|
||||
roms[1] = g_extern.sufami_rom_path[1];
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
@ -694,12 +703,12 @@ static bool load_sufami_rom(void)
|
||||
}
|
||||
}
|
||||
|
||||
char *xml_buf = load_xml_map(g_extern.xml_name);
|
||||
xml_buf = load_xml_map(g_extern.xml_name);
|
||||
|
||||
if (!psnes_load_cartridge_sufami_turbo(
|
||||
xml_buf, rom_buf, rom_len,
|
||||
NULL, extra_rom_buf[0], extra_rom_len[0],
|
||||
NULL, extra_rom_buf[1], extra_rom_len[1]))
|
||||
xml_buf, (const uint8_t*)rom_buf, rom_len,
|
||||
NULL, (const uint8_t*)extra_rom_buf[0], extra_rom_len[0],
|
||||
NULL, (const uint8_t*)extra_rom_buf[1], extra_rom_len[1]))
|
||||
{
|
||||
SSNES_ERR("Cannot load Sufami Turbo rom.\n");
|
||||
goto error;
|
||||
@ -765,7 +774,7 @@ static bool load_normal_rom(void)
|
||||
|
||||
char *xml_buf = load_xml_map(g_extern.xml_name);
|
||||
|
||||
if (!psnes_load_cartridge_normal(xml_buf, rom_buf, rom_len))
|
||||
if (!psnes_load_cartridge_normal(xml_buf, (const uint8_t*)rom_buf, rom_len))
|
||||
{
|
||||
SSNES_ERR("ROM file is not valid!\n");
|
||||
free(rom_buf);
|
||||
@ -856,7 +865,7 @@ char **dir_list_new(const char *dir, const char *ext)
|
||||
goto error;
|
||||
#endif
|
||||
|
||||
dir_list = calloc(cur_size, sizeof(char*));
|
||||
dir_list = (char**)calloc(cur_size, sizeof(char*));
|
||||
if (!dir_list)
|
||||
goto error;
|
||||
|
||||
@ -879,7 +888,7 @@ char **dir_list_new(const char *dir, const char *ext)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
dir_list[cur_ptr] = malloc(MAXPATHLEN);
|
||||
dir_list[cur_ptr] = (char*)malloc(MAXPATHLEN);
|
||||
if (!dir_list[cur_ptr])
|
||||
goto error;
|
||||
|
||||
@ -895,7 +904,7 @@ char **dir_list_new(const char *dir, const char *ext)
|
||||
if (cur_ptr + 1 == cur_size) // Need to reserve for NULL.
|
||||
{
|
||||
cur_size *= 2;
|
||||
dir_list = realloc(dir_list, cur_size * sizeof(char*));
|
||||
dir_list = (char**)realloc(dir_list, cur_size * sizeof(char*));
|
||||
if (!dir_list)
|
||||
goto error;
|
||||
|
||||
|
2
file.h
2
file.h
@ -19,7 +19,7 @@
|
||||
#ifndef __SSNES_FILE_H
|
||||
#define __SSNES_FILE_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "boolean.h"
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
11
general.h
11
general.h
@ -19,7 +19,7 @@
|
||||
#ifndef __SSNES_GENERAL_H
|
||||
#define __SSNES_GENERAL_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "boolean.h"
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include "driver.h"
|
||||
@ -171,7 +171,7 @@ enum ssnes_game_type
|
||||
SSNES_CART_SGB,
|
||||
SSNES_CART_BSX,
|
||||
SSNES_CART_BSX_SLOTTED,
|
||||
SSNES_CART_SUFAMI,
|
||||
SSNES_CART_SUFAMI
|
||||
};
|
||||
|
||||
|
||||
@ -410,10 +410,9 @@ static inline void ssnes_sleep(unsigned msec)
|
||||
#elif defined(GEKKO)
|
||||
usleep(1000 * msec);
|
||||
#else
|
||||
struct timespec tv = {
|
||||
.tv_sec = msec / 1000,
|
||||
.tv_nsec = (msec % 1000) * 1000000,
|
||||
};
|
||||
struct timespec tv = {0};
|
||||
tv.tv_sec = msec / 1000;
|
||||
tv.tv_nsec = (msec % 1000) * 1000000;
|
||||
nanosleep(&tv, NULL);
|
||||
#endif
|
||||
}
|
||||
|
2
getopt.c
2
getopt.c
@ -20,7 +20,7 @@
|
||||
#ifndef HAVE_GETOPT_LONG
|
||||
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include "boolean.h"
|
||||
#include <stddef.h>
|
||||
#include <assert.h>
|
||||
|
||||
|
116
gfx/ext.c
116
gfx/ext.c
@ -19,7 +19,7 @@
|
||||
|
||||
#define SSNES_DLL_IMPORT
|
||||
#include "ext/ssnes_video.h"
|
||||
#include <stdbool.h>
|
||||
#include "../boolean.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "dynamic.h"
|
||||
@ -56,13 +56,13 @@ static void *input_ext_init(void)
|
||||
|
||||
static void input_ext_poll(void *data)
|
||||
{
|
||||
input_ext_t *ext = data;
|
||||
input_ext_t *ext = (input_ext_t*)data;
|
||||
ext->driver->poll(ext->handle);
|
||||
}
|
||||
|
||||
static int16_t input_ext_input_state(void *data, const struct snes_keybind **snes_keybinds, bool port, unsigned device, unsigned index, unsigned id)
|
||||
{
|
||||
input_ext_t *ext = data;
|
||||
input_ext_t *ext = (input_ext_t*)data;
|
||||
|
||||
unsigned player = 0;
|
||||
if (device == SNES_DEVICE_MULTITAP)
|
||||
@ -74,7 +74,7 @@ static int16_t input_ext_input_state(void *data, const struct snes_keybind **sne
|
||||
|
||||
for (unsigned i = 0; g_settings.input.binds[player - 1][i].id != -1; i++)
|
||||
{
|
||||
if (g_settings.input.binds[player - 1][i].id == id)
|
||||
if (g_settings.input.binds[player - 1][i].id == (int)id)
|
||||
{
|
||||
ssnes_bind = &g_settings.input.binds[player - 1][i];
|
||||
break;
|
||||
@ -83,11 +83,10 @@ static int16_t input_ext_input_state(void *data, const struct snes_keybind **sne
|
||||
|
||||
if (ssnes_bind)
|
||||
{
|
||||
struct ssnes_keybind bind = {
|
||||
.key = ssnes_bind->key,
|
||||
.joykey = ssnes_bind->joykey,
|
||||
.joyaxis = ssnes_bind->joyaxis
|
||||
};
|
||||
struct ssnes_keybind bind = {0};
|
||||
bind.key = ssnes_bind->key;
|
||||
bind.joykey = ssnes_bind->joykey;
|
||||
bind.joyaxis = ssnes_bind->joyaxis;
|
||||
|
||||
return ext->driver->input_state(ext->handle, &bind, player);
|
||||
}
|
||||
@ -97,7 +96,7 @@ static int16_t input_ext_input_state(void *data, const struct snes_keybind **sne
|
||||
|
||||
static bool input_ext_key_pressed(void *data, int key)
|
||||
{
|
||||
input_ext_t *ext = data;
|
||||
input_ext_t *ext = (input_ext_t*)data;
|
||||
|
||||
const struct snes_keybind *ssnes_bind = NULL;
|
||||
for (unsigned i = 0; g_settings.input.binds[0][i].id != -1; i++)
|
||||
@ -111,11 +110,10 @@ static bool input_ext_key_pressed(void *data, int key)
|
||||
|
||||
if (ssnes_bind)
|
||||
{
|
||||
struct ssnes_keybind bind = {
|
||||
.key = ssnes_bind->key,
|
||||
.joykey = ssnes_bind->joykey,
|
||||
.joyaxis = ssnes_bind->joyaxis
|
||||
};
|
||||
struct ssnes_keybind bind = {0};
|
||||
bind.key = ssnes_bind->key;
|
||||
bind.joykey = ssnes_bind->joykey;
|
||||
bind.joyaxis = ssnes_bind->joyaxis;
|
||||
|
||||
return ext->driver->input_state(ext->handle, &bind, 1);
|
||||
}
|
||||
@ -125,7 +123,7 @@ static bool input_ext_key_pressed(void *data, int key)
|
||||
|
||||
static void input_ext_free(void *data)
|
||||
{
|
||||
input_ext_t *ext = data;
|
||||
input_ext_t *ext = (input_ext_t*)data;
|
||||
if (ext)
|
||||
{
|
||||
if (ext->driver && ext->handle)
|
||||
@ -144,15 +142,14 @@ static void input_ext_free(void *data)
|
||||
}
|
||||
|
||||
static const input_driver_t input_ext = {
|
||||
.init = input_ext_init,
|
||||
.poll = input_ext_poll,
|
||||
.input_state = input_ext_input_state,
|
||||
.key_pressed = input_ext_key_pressed,
|
||||
.free = input_ext_free,
|
||||
.ident = "ext"
|
||||
input_ext_init,
|
||||
input_ext_poll,
|
||||
input_ext_input_state,
|
||||
input_ext_key_pressed,
|
||||
input_ext_free,
|
||||
"ext"
|
||||
};
|
||||
|
||||
|
||||
//////////// Video hook
|
||||
typedef struct
|
||||
{
|
||||
@ -162,7 +159,7 @@ typedef struct
|
||||
|
||||
static void video_ext_free(void *data)
|
||||
{
|
||||
ext_t *ext = data;
|
||||
ext_t *ext = (ext_t*)data;
|
||||
if (ext)
|
||||
{
|
||||
if (ext->driver && ext->handle)
|
||||
@ -182,25 +179,25 @@ static void video_ext_free(void *data)
|
||||
|
||||
static bool video_ext_focus(void *data)
|
||||
{
|
||||
ext_t *ext = data;
|
||||
ext_t *ext = (ext_t*)data;
|
||||
return ext->driver->focus(ext->handle);
|
||||
}
|
||||
|
||||
static bool video_ext_alive(void *data)
|
||||
{
|
||||
ext_t *ext = data;
|
||||
ext_t *ext = (ext_t*)data;
|
||||
return ext->driver->alive(ext->handle);
|
||||
}
|
||||
|
||||
static void video_ext_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
ext_t *ext = data;
|
||||
ext_t *ext = (ext_t*)data;
|
||||
ext->driver->set_nonblock_state(ext->handle, state);
|
||||
}
|
||||
|
||||
static bool video_ext_frame(void *data, const void *frame, unsigned width, unsigned height, unsigned pitch, const char *msg)
|
||||
{
|
||||
ext_t *ext = data;
|
||||
ext_t *ext = (ext_t*)data;
|
||||
return ext->driver->frame(ext->handle, frame, width, height, pitch, msg);
|
||||
}
|
||||
|
||||
@ -214,7 +211,7 @@ static void *setup_input(ext_t *ext, const ssnes_input_driver_t *driver)
|
||||
if (!handle)
|
||||
return NULL;
|
||||
|
||||
input_ext_t *wrap_handle = input_ext.init();
|
||||
input_ext_t *wrap_handle = (input_ext_t*)input_ext.init();
|
||||
if (!wrap_handle)
|
||||
return NULL;
|
||||
|
||||
@ -268,29 +265,28 @@ static bool setup_video(ext_t *ext, const video_info_t *video, const input_drive
|
||||
gfx_window_title_reset();
|
||||
gfx_window_title(title_buf, sizeof(title_buf));
|
||||
|
||||
ssnes_video_info_t info = {
|
||||
.width = video->width,
|
||||
.height = video->height,
|
||||
.fullscreen = video->fullscreen,
|
||||
.vsync = video->vsync,
|
||||
.force_aspect = video->force_aspect,
|
||||
.aspect_ratio = g_settings.video.aspect_ratio,
|
||||
.smooth = video->smooth,
|
||||
.input_scale = video->input_scale,
|
||||
.color_format = video->rgb32 ? SSNES_COLOR_FORMAT_ARGB8888 : SSNES_COLOR_FORMAT_XRGB1555,
|
||||
.xml_shader = xml_shader,
|
||||
.cg_shader = cg_shader,
|
||||
.ttf_font = font,
|
||||
.ttf_font_size = g_settings.video.font_size,
|
||||
.ttf_font_color = (font_color_r << 16) | (font_color_g << 8) | (font_color_b << 0),
|
||||
.title_hint = title_buf,
|
||||
ssnes_video_info_t info = {0};
|
||||
info.width = video->width;
|
||||
info.height = video->height;
|
||||
info.fullscreen = video->fullscreen;
|
||||
info.vsync = video->vsync;
|
||||
info.force_aspect = video->force_aspect;
|
||||
info.aspect_ratio = g_settings.video.aspect_ratio;
|
||||
info.smooth = video->smooth;
|
||||
info.input_scale = video->input_scale;
|
||||
info.color_format = video->rgb32 ? SSNES_COLOR_FORMAT_ARGB8888 : SSNES_COLOR_FORMAT_XRGB1555;
|
||||
info.xml_shader = xml_shader;
|
||||
info.cg_shader = cg_shader;
|
||||
info.ttf_font = font;
|
||||
info.ttf_font_size = g_settings.video.font_size;
|
||||
info.ttf_font_color = (font_color_r << 16) | (font_color_g << 8) | (font_color_b << 0);
|
||||
info.title_hint = title_buf;
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
.python_state_new = py_state_new,
|
||||
.python_state_get = py_state_get,
|
||||
.python_state_free = py_state_free,
|
||||
info.python_state_new = py_state_new;
|
||||
info.python_state_get = py_state_get;
|
||||
info.python_state_free = py_state_free;
|
||||
#endif
|
||||
};
|
||||
|
||||
const ssnes_input_driver_t *input_driver = NULL;
|
||||
ext->handle = ext->driver->init(&info, &input_driver);
|
||||
@ -308,10 +304,12 @@ static bool setup_video(ext_t *ext, const video_info_t *video, const input_drive
|
||||
|
||||
static void *video_ext_init(const video_info_t *video, const input_driver_t **input, void **input_data)
|
||||
{
|
||||
ext_t *ext = calloc(1, sizeof(*ext));
|
||||
ext_t *ext = (ext_t*)calloc(1, sizeof(*ext));
|
||||
if (!ext)
|
||||
return NULL;
|
||||
|
||||
const ssnes_video_driver_t *(*video_init)(void) = NULL;
|
||||
|
||||
if (!(*g_settings.video.external_driver))
|
||||
{
|
||||
SSNES_ERR("External driver needs video_external_driver path to be set!\n");
|
||||
@ -325,8 +323,7 @@ static void *video_ext_init(const video_info_t *video, const input_driver_t **in
|
||||
goto error;
|
||||
}
|
||||
|
||||
const ssnes_video_driver_t* (*video_init)(void) =
|
||||
(const ssnes_video_driver_t *(*)(void))dylib_proc(g_lib, "ssnes_video_init");
|
||||
video_init = (const ssnes_video_driver_t *(*)(void))dylib_proc(g_lib, "ssnes_video_init");
|
||||
if (!video_init)
|
||||
{
|
||||
SSNES_ERR("Couldn't find function ssnes_video_init in library ...\n");
|
||||
@ -355,12 +352,13 @@ error:
|
||||
}
|
||||
|
||||
const video_driver_t video_ext = {
|
||||
.init = video_ext_init,
|
||||
.frame = video_ext_frame,
|
||||
.alive = video_ext_alive,
|
||||
.set_nonblock_state = video_ext_set_nonblock_state,
|
||||
.focus = video_ext_focus,
|
||||
.free = video_ext_free,
|
||||
.ident = "ext"
|
||||
video_ext_init,
|
||||
video_ext_frame,
|
||||
video_ext_set_nonblock_state,
|
||||
video_ext_alive,
|
||||
video_ext_focus,
|
||||
NULL,
|
||||
video_ext_free,
|
||||
"ext"
|
||||
};
|
||||
|
||||
|
@ -33,11 +33,12 @@ struct font_renderer
|
||||
font_renderer_t *font_renderer_new(const char *font_path, unsigned font_size)
|
||||
{
|
||||
(void)font_size;
|
||||
font_renderer_t *handle = calloc(1, sizeof(*handle));
|
||||
FT_Error err;
|
||||
font_renderer_t *handle = (font_renderer_t*)calloc(1, sizeof(*handle));
|
||||
if (!handle)
|
||||
goto error;
|
||||
|
||||
FT_Error err = FT_Init_FreeType(&handle->lib);
|
||||
err = FT_Init_FreeType(&handle->lib);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
@ -78,11 +79,11 @@ void font_renderer_msg(font_renderer_t *handle, const char *msg, struct font_out
|
||||
|
||||
if (!err)
|
||||
{
|
||||
struct font_output *tmp = calloc(1, sizeof(*tmp));
|
||||
struct font_output *tmp = (struct font_output*)calloc(1, sizeof(*tmp));
|
||||
if (!tmp)
|
||||
break;
|
||||
|
||||
tmp->output = malloc(slot->bitmap.pitch * slot->bitmap.rows);
|
||||
tmp->output = (uint8_t*)malloc(slot->bitmap.pitch * slot->bitmap.rows);
|
||||
if (!tmp->output)
|
||||
{
|
||||
free(tmp);
|
||||
|
@ -19,7 +19,7 @@
|
||||
#define __GFX_COMMON_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include "../boolean.h"
|
||||
|
||||
bool gfx_window_title(char *buf, size_t size);
|
||||
void gfx_window_title_reset(void);
|
||||
|
46
gfx/gl.c
46
gfx/gl.c
@ -895,7 +895,7 @@ static void check_window(gl_t *gl)
|
||||
|
||||
static bool gl_frame(void *data, const void *frame, unsigned width, unsigned height, unsigned pitch, const char *msg)
|
||||
{
|
||||
gl_t *gl = data;
|
||||
gl_t *gl = (gl_t*)data;
|
||||
|
||||
gl_shader_use(1);
|
||||
gl->frame_count++;
|
||||
@ -1054,11 +1054,13 @@ static bool gl_frame(void *data, const void *frame, unsigned width, unsigned hei
|
||||
0, 0, 0, width, height, gl->texture_type,
|
||||
gl->texture_fmt, frame);
|
||||
|
||||
struct gl_tex_info tex_info = {
|
||||
.tex = gl->texture[gl->tex_index],
|
||||
.input_size = {width, height},
|
||||
.tex_size = {gl->tex_w, gl->tex_h}
|
||||
};
|
||||
struct gl_tex_info tex_info = {0};
|
||||
tex_info.tex = gl->texture[gl->tex_index];
|
||||
tex_info.input_size[0] = width;
|
||||
tex_info.input_size[1] = height;
|
||||
tex_info.tex_size[0] = gl->tex_w;
|
||||
tex_info.tex_size[1] = gl->tex_h;
|
||||
|
||||
struct gl_tex_info fbo_tex_info[MAX_SHADERS];
|
||||
unsigned fbo_tex_info_cnt = 0;
|
||||
memcpy(tex_info.coord, gl->tex_coords, sizeof(gl->tex_coords));
|
||||
@ -1165,7 +1167,7 @@ static bool gl_frame(void *data, const void *frame, unsigned width, unsigned hei
|
||||
|
||||
static void gl_free(void *data)
|
||||
{
|
||||
gl_t *gl = data;
|
||||
gl_t *gl = (gl_t*)data;
|
||||
|
||||
gl_deinit_font(gl);
|
||||
gl_shader_deinit();
|
||||
@ -1191,7 +1193,7 @@ static void gl_free(void *data)
|
||||
|
||||
static void gl_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
gl_t *gl = data;
|
||||
gl_t *gl = (gl_t*)data;
|
||||
if (gl->vsync)
|
||||
{
|
||||
SSNES_LOG("GL VSync => %s\n", state ? "off" : "on");
|
||||
@ -1247,7 +1249,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
|
||||
}
|
||||
#endif
|
||||
|
||||
gl_t *gl = calloc(1, sizeof(gl_t));
|
||||
gl_t *gl = (gl_t*)calloc(1, sizeof(gl_t));
|
||||
if (!gl)
|
||||
{
|
||||
sdlwrap_destroy();
|
||||
@ -1362,7 +1364,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
|
||||
}
|
||||
|
||||
// Hook up SDL input driver to get SDL_QUIT events and RESIZE.
|
||||
sdl_input_t *sdl_input = input_sdl.init();
|
||||
sdl_input_t *sdl_input = (sdl_input_t*)input_sdl.init();
|
||||
if (sdl_input)
|
||||
{
|
||||
*input = &input_sdl;
|
||||
@ -1385,7 +1387,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
|
||||
|
||||
static bool gl_alive(void *data)
|
||||
{
|
||||
gl_t *gl = data;
|
||||
gl_t *gl = (gl_t*)data;
|
||||
check_window(gl);
|
||||
return !gl->quitting;
|
||||
}
|
||||
@ -1399,7 +1401,7 @@ static bool gl_focus(void *data)
|
||||
#ifdef HAVE_XML
|
||||
static bool gl_xml_shader(void *data, const char *path)
|
||||
{
|
||||
gl_t *gl = data;
|
||||
gl_t *gl = (gl_t*)data;
|
||||
|
||||
//if (!gl_check_error())
|
||||
// SSNES_WARN("Error happened before deinit!\n");
|
||||
@ -1445,17 +1447,17 @@ static bool gl_xml_shader(void *data, const char *path)
|
||||
#endif
|
||||
|
||||
const video_driver_t video_gl = {
|
||||
.init = gl_init,
|
||||
.frame = gl_frame,
|
||||
.alive = gl_alive,
|
||||
.set_nonblock_state = gl_set_nonblock_state,
|
||||
.focus = gl_focus,
|
||||
.free = gl_free,
|
||||
gl_init,
|
||||
gl_frame,
|
||||
gl_set_nonblock_state,
|
||||
gl_alive,
|
||||
gl_focus,
|
||||
#ifdef HAVE_XML
|
||||
.xml_shader = gl_xml_shader,
|
||||
gl_xml_shader,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
.ident = "gl"
|
||||
gl_free,
|
||||
"gl"
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
14
gfx/image.c
14
gfx/image.c
@ -40,7 +40,7 @@ bool texture_image_load(const char *path, struct texture_image *out_img)
|
||||
out_img->height = img->h;
|
||||
|
||||
size_t size = out_img->width * out_img->height * sizeof(uint32_t);
|
||||
out_img->pixels = malloc(size);
|
||||
out_img->pixels = (uint32_t*)malloc(size);
|
||||
if (!out_img->pixels)
|
||||
{
|
||||
SDL_FreeSurface(img);
|
||||
@ -52,12 +52,12 @@ bool texture_image_load(const char *path, struct texture_image *out_img)
|
||||
SSNES_LOG("SDL_image: %dx%d @ %d bpp\n", img->w, img->h, img->format->BitsPerPixel);
|
||||
if (img->format->BitsPerPixel == 32)
|
||||
{
|
||||
for (unsigned y = 0; y < img->h; y++)
|
||||
for (int y = 0; y < img->h; y++)
|
||||
{
|
||||
uint32_t *dst = out_img->pixels + y * img->w;
|
||||
const uint32_t *src = (const uint32_t*)img->pixels + y * img->pitch / sizeof(uint32_t);
|
||||
|
||||
for (unsigned x = 0; x < img->w; x++)
|
||||
for (int x = 0; x < img->w; x++)
|
||||
{
|
||||
uint32_t r = (src[x] & fmt->Rmask) >> fmt->Rshift;
|
||||
uint32_t g = (src[x] & fmt->Gmask) >> fmt->Gshift;
|
||||
@ -69,12 +69,12 @@ bool texture_image_load(const char *path, struct texture_image *out_img)
|
||||
}
|
||||
else if (img->format->BitsPerPixel == 24)
|
||||
{
|
||||
for (unsigned y = 0; y < img->h; y++)
|
||||
for (int y = 0; y < img->h; y++)
|
||||
{
|
||||
uint32_t *dst = out_img->pixels + y * img->w;
|
||||
const uint8_t *src = (const uint8_t*)img->pixels + y * img->pitch;
|
||||
|
||||
for (unsigned x = 0; x < img->w; x++)
|
||||
for (int x = 0; x < img->w; x++)
|
||||
{
|
||||
// Correct?
|
||||
uint32_t color = 0;
|
||||
@ -113,7 +113,7 @@ bool texture_image_load(const char *path, struct texture_image *out_img)
|
||||
if (len < 0)
|
||||
return false;
|
||||
|
||||
uint8_t *buf = raw_buf;
|
||||
uint8_t *buf = (uint8_t*)raw_buf;
|
||||
|
||||
if (buf[2] != 2) // Uncompressed RGB
|
||||
{
|
||||
@ -134,7 +134,7 @@ bool texture_image_load(const char *path, struct texture_image *out_img)
|
||||
SSNES_LOG("Loaded TGA: (%ux%u @ %u bpp)\n", width, height, bits);
|
||||
|
||||
unsigned size = width * height * sizeof(uint32_t);
|
||||
out_img->pixels = malloc(size);
|
||||
out_img->pixels = (uint32_t*)malloc(size);
|
||||
out_img->width = width;
|
||||
out_img->height = height;
|
||||
if (!out_img->pixels)
|
||||
|
@ -19,7 +19,7 @@
|
||||
#define __SSNES_IMAGE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "../boolean.h"
|
||||
|
||||
struct texture_image
|
||||
{
|
||||
|
@ -16,17 +16,18 @@
|
||||
*/
|
||||
|
||||
#include <Python.h>
|
||||
#include <stdbool.h>
|
||||
#include "../../boolean.h"
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "dynamic.h"
|
||||
#include "libsnes.hpp"
|
||||
#include "../../dynamic.h"
|
||||
#include "../../libsnes.hpp"
|
||||
#include "py_state.h"
|
||||
#include "general.h"
|
||||
#include "strl.h"
|
||||
#include "file.h"
|
||||
#include "../../general.h"
|
||||
#include "../../strl.h"
|
||||
#include "../../posix_string.h"
|
||||
#include "../../file.h"
|
||||
|
||||
#define PY_READ_FUNC_DECL(RAMTYPE) py_read_##RAMTYPE
|
||||
#define PY_READ_FUNC(RAMTYPE) \
|
||||
@ -195,7 +196,7 @@ static char *dupe_newline(const char *str)
|
||||
return NULL;
|
||||
|
||||
unsigned size = strlen(str) + 2;
|
||||
char *ret = malloc(size);
|
||||
char *ret = (char*)malloc(size);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
@ -213,7 +214,7 @@ static char *align_program(const char *program)
|
||||
return NULL;
|
||||
|
||||
size_t prog_size = strlen(program) + 1;
|
||||
char *new_prog = calloc(1, prog_size);
|
||||
char *new_prog = (char*)calloc(1, prog_size);
|
||||
if (!new_prog)
|
||||
return NULL;
|
||||
|
||||
@ -250,7 +251,8 @@ py_state_t *py_state_new(const char *script, unsigned is_file, const char *pycla
|
||||
Py_Initialize();
|
||||
SSNES_LOG("Initialized Python runtime!\n");
|
||||
|
||||
py_state_t *handle = calloc(1, sizeof(*handle));
|
||||
py_state_t *handle = (py_state_t*)calloc(1, sizeof(*handle));
|
||||
PyObject *hook = NULL;
|
||||
|
||||
handle->main = PyImport_AddModule("__main__");
|
||||
if (!handle->main)
|
||||
@ -292,7 +294,7 @@ py_state_t *py_state_new(const char *script, unsigned is_file, const char *pycla
|
||||
}
|
||||
Py_INCREF(handle->dict);
|
||||
|
||||
PyObject *hook = PyDict_GetItemString(handle->dict, pyclass);
|
||||
hook = PyDict_GetItemString(handle->dict, pyclass);
|
||||
if (!hook)
|
||||
{
|
||||
SSNES_ERR("Python: PyDict_GetItemString() failed.\n");
|
||||
|
@ -19,7 +19,7 @@
|
||||
#define __SSNES_PY_STATE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "../../boolean.h"
|
||||
|
||||
#ifndef PY_STATE_OMIT_DECLARATION
|
||||
typedef struct py_state py_state_t;
|
||||
|
85
gfx/sdl.c
85
gfx/sdl.c
@ -37,8 +37,7 @@ static void convert_32bit_32bit_direct(uint32_t *out, unsigned outpitch, const u
|
||||
static void convert_15bit_15bit_shift(uint16_t *out, unsigned outpitch, const uint16_t *input, unsigned width, unsigned height, unsigned pitch, const SDL_PixelFormat *fmt);
|
||||
static void convert_32bit_32bit_shift(uint32_t *out, unsigned outpitch, const uint32_t *input, unsigned width, unsigned height, unsigned pitch, const SDL_PixelFormat *fmt);
|
||||
|
||||
typedef struct sdl_video sdl_video_t;
|
||||
struct sdl_video
|
||||
typedef struct sdl_video
|
||||
{
|
||||
SDL_Surface *screen, *buffer;
|
||||
bool quitting;
|
||||
@ -56,11 +55,11 @@ struct sdl_video
|
||||
uint8_t font_g;
|
||||
uint8_t font_b;
|
||||
#endif
|
||||
};
|
||||
} sdl_video_t;
|
||||
|
||||
static void sdl_gfx_free(void *data)
|
||||
{
|
||||
sdl_video_t *vid = data;
|
||||
sdl_video_t *vid = (sdl_video_t*)data;
|
||||
if (!vid)
|
||||
return;
|
||||
|
||||
@ -148,7 +147,7 @@ static void sdl_render_msg_15(sdl_video_t *vid, SDL_Surface *buffer, const char
|
||||
int rbase_y = base_y - head->off_y;
|
||||
if (rbase_y >= 0)
|
||||
{
|
||||
for (int y = 0; y < head->height && (y + rbase_y) < height; y++)
|
||||
for (int y = 0; y < (int)head->height && (y + rbase_y) < (int)height; y++)
|
||||
{
|
||||
if (rbase_x < 0)
|
||||
continue;
|
||||
@ -156,7 +155,7 @@ static void sdl_render_msg_15(sdl_video_t *vid, SDL_Surface *buffer, const char
|
||||
const uint8_t *a = head->output + head->pitch * y;
|
||||
uint16_t *out = (uint16_t*)buffer->pixels + (rbase_y - head->height + y) * (buffer->pitch >> 1) + rbase_x;
|
||||
|
||||
for (int x = 0; x < head->width && (x + rbase_x) < width; x++)
|
||||
for (int x = 0; x < (int)head->width && (x + rbase_x) < (int)width; x++)
|
||||
{
|
||||
unsigned blend = a[x];
|
||||
unsigned out_pix = out[x];
|
||||
@ -209,7 +208,7 @@ static void sdl_render_msg_32(sdl_video_t *vid, SDL_Surface *buffer, const char
|
||||
int rbase_y = base_y - head->off_y;
|
||||
if (rbase_y >= 0)
|
||||
{
|
||||
for (int y = 0; y < head->height && (y + rbase_y) < height; y++)
|
||||
for (int y = 0; y < (int)head->height && (y + rbase_y) < (int)height; y++)
|
||||
{
|
||||
if (rbase_x < 0)
|
||||
continue;
|
||||
@ -217,7 +216,7 @@ static void sdl_render_msg_32(sdl_video_t *vid, SDL_Surface *buffer, const char
|
||||
const uint8_t *a = head->output + head->pitch * y;
|
||||
uint32_t *out = (uint32_t*)buffer->pixels + (rbase_y - head->height + y) * (buffer->pitch >> 2) + rbase_x;
|
||||
|
||||
for (int x = 0; x < head->width && (x + rbase_x) < width; x++)
|
||||
for (int x = 0; x < (int)head->width && (x + rbase_x) < (int)width; x++)
|
||||
{
|
||||
unsigned blend = a[x];
|
||||
unsigned out_pix = out[x];
|
||||
@ -255,7 +254,7 @@ static void *sdl_gfx_init(const video_info_t *video, const input_driver_t **inpu
|
||||
|
||||
SDL_InitSubSystem(SDL_INIT_VIDEO);
|
||||
|
||||
sdl_video_t *vid = calloc(1, sizeof(*vid));
|
||||
sdl_video_t *vid = (sdl_video_t*)calloc(1, sizeof(*vid));
|
||||
if (!vid)
|
||||
return NULL;
|
||||
|
||||
@ -265,6 +264,11 @@ static void *sdl_gfx_init(const video_info_t *video, const input_driver_t **inpu
|
||||
unsigned full_y = video_info->current_h;
|
||||
SSNES_LOG("Detecting desktop resolution %ux%u.\n", full_x, full_y);
|
||||
|
||||
#ifndef XENON
|
||||
sdl_input_t *sdl_input = NULL;
|
||||
#endif
|
||||
const SDL_PixelFormat *fmt = NULL;
|
||||
|
||||
if (!video->fullscreen)
|
||||
SSNES_LOG("Creating window @ %ux%u\n", video->width, video->height);
|
||||
|
||||
@ -287,7 +291,7 @@ static void *sdl_gfx_init(const video_info_t *video, const input_driver_t **inpu
|
||||
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
|
||||
const SDL_PixelFormat *fmt = vid->screen->format;
|
||||
fmt = vid->screen->format;
|
||||
if (vid->render32)
|
||||
{
|
||||
SSNES_LOG("SDL: Creating 32-bit buffer.\n");
|
||||
@ -312,7 +316,7 @@ static void *sdl_gfx_init(const video_info_t *video, const input_driver_t **inpu
|
||||
}
|
||||
|
||||
#ifndef XENON
|
||||
sdl_input_t *sdl_input = input_sdl.init();
|
||||
sdl_input = (sdl_input_t*)input_sdl.init();
|
||||
if (sdl_input)
|
||||
{
|
||||
*input = &input_sdl;
|
||||
@ -330,7 +334,6 @@ static void *sdl_gfx_init(const video_info_t *video, const input_driver_t **inpu
|
||||
|
||||
sdl_init_font(vid, g_settings.video.font_path, g_settings.video.font_size);
|
||||
|
||||
|
||||
if (fmt->Rshift == 10 && fmt->Gshift == 5 && fmt->Bshift == 0) // XRGB1555
|
||||
{
|
||||
SSNES_LOG("SDL: 15-bit format matches. Fast blit.\n");
|
||||
@ -475,7 +478,7 @@ static void check_window(sdl_video_t *vid)
|
||||
|
||||
static bool sdl_gfx_frame(void *data, const void *frame, unsigned width, unsigned height, unsigned pitch, const char *msg)
|
||||
{
|
||||
sdl_video_t *vid = data;
|
||||
sdl_video_t *vid = (sdl_video_t*)data;
|
||||
|
||||
if (SDL_MUSTLOCK(vid->buffer))
|
||||
SDL_LockSurface(vid->buffer);
|
||||
@ -483,41 +486,31 @@ static bool sdl_gfx_frame(void *data, const void *frame, unsigned width, unsigne
|
||||
// :(
|
||||
// 15-bit -> 32-bit (Sometimes 15-bit won't work on "modern" OSes :\)
|
||||
if (vid->upsample)
|
||||
{
|
||||
convert_15bit_32bit(vid->buffer->pixels, vid->buffer->pitch, frame, width, height, pitch, vid->screen->format);
|
||||
}
|
||||
convert_15bit_32bit((uint32_t*)vid->buffer->pixels, vid->buffer->pitch, (const uint16_t*)frame, width, height, pitch, vid->screen->format);
|
||||
// 15-bit -> 15-bit
|
||||
else if (!vid->rgb32)
|
||||
{
|
||||
vid->convert_15_func(vid->buffer->pixels, vid->buffer->pitch, frame, width, height, pitch, vid->screen->format);
|
||||
}
|
||||
vid->convert_15_func((uint16_t*)vid->buffer->pixels, vid->buffer->pitch, (const uint16_t*)frame, width, height, pitch, vid->screen->format);
|
||||
// 32-bit -> 15-bit
|
||||
else if (vid->rgb32 && g_settings.video.force_16bit)
|
||||
{
|
||||
convert_32bit_15bit(vid->buffer->pixels, vid->buffer->pitch, frame, width, height, pitch, vid->screen->format);
|
||||
}
|
||||
convert_32bit_15bit((uint16_t*)vid->buffer->pixels, vid->buffer->pitch, (const uint32_t*)frame, width, height, pitch, vid->screen->format);
|
||||
// 32-bit -> 32-bit
|
||||
else
|
||||
{
|
||||
vid->convert_32_func(vid->buffer->pixels, vid->buffer->pitch, frame, width, height, pitch, vid->screen->format);
|
||||
}
|
||||
vid->convert_32_func((uint32_t*)vid->buffer->pixels, vid->buffer->pitch, (const uint32_t*)frame, width, height, pitch, vid->screen->format);
|
||||
|
||||
if (SDL_MUSTLOCK(vid->buffer))
|
||||
SDL_UnlockSurface(vid->buffer);
|
||||
|
||||
SDL_Rect src = {
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.w = width,
|
||||
.h = height
|
||||
};
|
||||
SDL_Rect src = {0};
|
||||
src.x = 0;
|
||||
src.y = 0;
|
||||
src.w = width;
|
||||
src.h = height;
|
||||
|
||||
SDL_Rect dest = {
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.w = vid->screen->w,
|
||||
.h = vid->screen->h
|
||||
};
|
||||
SDL_Rect dest = {0};
|
||||
dest.x = 0;
|
||||
dest.y = 0;
|
||||
dest.w = vid->screen->w;
|
||||
dest.h = vid->screen->h;
|
||||
|
||||
SDL_SoftStretch(vid->buffer, &src, vid->screen, &dest);
|
||||
|
||||
@ -546,7 +539,7 @@ static void sdl_gfx_set_nonblock_state(void *data, bool state)
|
||||
|
||||
static bool sdl_gfx_alive(void *data)
|
||||
{
|
||||
sdl_video_t *vid = data;
|
||||
sdl_video_t *vid = (sdl_video_t*)data;
|
||||
check_window(vid);
|
||||
return !vid->quitting;
|
||||
}
|
||||
@ -557,14 +550,14 @@ static bool sdl_gfx_focus(void *data)
|
||||
return (SDL_GetAppState() & (SDL_APPINPUTFOCUS | SDL_APPACTIVE)) == (SDL_APPINPUTFOCUS | SDL_APPACTIVE);
|
||||
}
|
||||
|
||||
|
||||
const video_driver_t video_sdl = {
|
||||
.init = sdl_gfx_init,
|
||||
.frame = sdl_gfx_frame,
|
||||
.alive = sdl_gfx_alive,
|
||||
.set_nonblock_state = sdl_gfx_set_nonblock_state,
|
||||
.focus = sdl_gfx_focus,
|
||||
.free = sdl_gfx_free,
|
||||
.ident = "sdl"
|
||||
sdl_gfx_init,
|
||||
sdl_gfx_frame,
|
||||
sdl_gfx_set_nonblock_state,
|
||||
sdl_gfx_alive,
|
||||
sdl_gfx_focus,
|
||||
NULL,
|
||||
sdl_gfx_free,
|
||||
"sdl"
|
||||
};
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
#ifndef __SDLWRAP_H
|
||||
#define __SDLWRAP_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "../boolean.h"
|
||||
|
||||
#include "SDL.h"
|
||||
#include "SDL_version.h"
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "../conf/config_file.h"
|
||||
#include "image.h"
|
||||
#include "../dynamic.h"
|
||||
#include "../posix_string.h"
|
||||
|
||||
#ifdef HAVE_CONFIGFILE
|
||||
#include "snes_state.h"
|
||||
@ -483,6 +484,13 @@ static bool load_imports(const char *dir_path, config_file_t *conf)
|
||||
|
||||
struct snes_tracker_uniform_info info[MAX_VARIABLES];
|
||||
unsigned info_cnt = 0;
|
||||
struct snes_tracker_info tracker_info = {0};
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
char script_path[128];
|
||||
char *script = NULL;
|
||||
char *script_class = NULL;
|
||||
#endif
|
||||
|
||||
const char *id = strtok(imports, ";");
|
||||
while (id && info_cnt < MAX_VARIABLES)
|
||||
@ -516,7 +524,7 @@ static bool load_imports(const char *dir_path, config_file_t *conf)
|
||||
}
|
||||
|
||||
enum snes_tracker_type tracker_type;
|
||||
enum snes_ram_type ram_type = SNES_MEMORY_WRAM;
|
||||
enum snes_ram_type ram_type = SSNES_STATE_NONE;
|
||||
|
||||
if (strcmp(semantic, "capture") == 0)
|
||||
tracker_type = SSNES_STATE_CAPTURE;
|
||||
@ -623,20 +631,15 @@ static bool load_imports(const char *dir_path, config_file_t *conf)
|
||||
id = strtok(NULL, ";");
|
||||
}
|
||||
|
||||
struct snes_tracker_info tracker_info = {
|
||||
.wram = psnes_get_memory_data(SNES_MEMORY_WRAM),
|
||||
.vram = psnes_get_memory_data(SNES_MEMORY_VRAM),
|
||||
.cgram = psnes_get_memory_data(SNES_MEMORY_CGRAM),
|
||||
.oam = psnes_get_memory_data(SNES_MEMORY_OAM),
|
||||
.apuram = psnes_get_memory_data(SNES_MEMORY_APURAM),
|
||||
.info = info,
|
||||
.info_elem = info_cnt,
|
||||
};
|
||||
tracker_info.wram = psnes_get_memory_data(SNES_MEMORY_WRAM);
|
||||
tracker_info.vram = psnes_get_memory_data(SNES_MEMORY_VRAM);
|
||||
tracker_info.cgram = psnes_get_memory_data(SNES_MEMORY_CGRAM);
|
||||
tracker_info.oam = psnes_get_memory_data(SNES_MEMORY_OAM);
|
||||
tracker_info.apuram = psnes_get_memory_data(SNES_MEMORY_APURAM);
|
||||
tracker_info.info = info;
|
||||
tracker_info.info_elem = info_cnt;
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
char script_path[128];
|
||||
char *script = NULL;
|
||||
char *script_class = NULL;
|
||||
if (config_get_string(conf, "import_script", &script))
|
||||
{
|
||||
strlcpy(script_path, dir_path, sizeof(script_path));
|
||||
@ -685,6 +688,11 @@ static bool load_preset(const char *path)
|
||||
cgGLLoadProgram(prg[0].fprg);
|
||||
cgGLLoadProgram(prg[0].vprg);
|
||||
|
||||
int shaders;
|
||||
// Basedir.
|
||||
char dir_path[MAXPATHLEN];
|
||||
char *ptr = NULL;
|
||||
|
||||
SSNES_LOG("Loading Cg meta-shader: %s\n", path);
|
||||
config_file_t *conf = config_file_new(path);
|
||||
if (!conf)
|
||||
@ -693,7 +701,6 @@ static bool load_preset(const char *path)
|
||||
goto error;
|
||||
}
|
||||
|
||||
int shaders;
|
||||
if (!config_get_int(conf, "shaders", &shaders))
|
||||
{
|
||||
SSNES_ERR("Cannot find \"shaders\" param.\n");
|
||||
@ -719,7 +726,7 @@ static bool load_preset(const char *path)
|
||||
prg[shaders + 1] = prg[0];
|
||||
|
||||
// Check filter params.
|
||||
for (unsigned i = 0; i < shaders; i++)
|
||||
for (int i = 0; i < shaders; i++)
|
||||
{
|
||||
bool smooth;
|
||||
char filter_name_buf[64];
|
||||
@ -729,7 +736,7 @@ static bool load_preset(const char *path)
|
||||
}
|
||||
|
||||
// Bigass for-loop ftw. Check scaling params.
|
||||
for (unsigned i = 0; i < shaders; i++)
|
||||
for (int i = 0; i < shaders; i++)
|
||||
{
|
||||
char *scale_type = NULL;
|
||||
char *scale_type_x = NULL;
|
||||
@ -854,10 +861,8 @@ static bool load_preset(const char *path)
|
||||
free(scale_type_y);
|
||||
}
|
||||
|
||||
// Basedir.
|
||||
char dir_path[MAXPATHLEN];
|
||||
strlcpy(dir_path, path, sizeof(dir_path));
|
||||
char *ptr = strrchr(dir_path, '/');
|
||||
ptr = strrchr(dir_path, '/');
|
||||
if (!ptr) ptr = strrchr(dir_path, '\\');
|
||||
if (ptr)
|
||||
ptr[1] = '\0';
|
||||
@ -865,7 +870,7 @@ static bool load_preset(const char *path)
|
||||
dir_path[0] = '\0';
|
||||
|
||||
// Finally load shaders :)
|
||||
for (unsigned i = 0; i < shaders; i++)
|
||||
for (int i = 0; i < shaders; i++)
|
||||
{
|
||||
char *shader_path;
|
||||
char attr_buf[64];
|
||||
|
@ -19,7 +19,7 @@
|
||||
#ifndef __SSNES_CG_H
|
||||
#define __SSNES_CG_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "../boolean.h"
|
||||
#include "gl_common.h"
|
||||
|
||||
bool gl_cg_init(const char *path);
|
||||
|
@ -15,11 +15,12 @@
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "../boolean.h"
|
||||
#include <string.h>
|
||||
#include "../general.h"
|
||||
#include "shader_glsl.h"
|
||||
#include "../strl.h"
|
||||
#include "../posix_string.h"
|
||||
#include "snes_state.h"
|
||||
#include "../dynamic.h"
|
||||
|
||||
@ -333,6 +334,8 @@ static bool get_texture_image(const char *shader_path, xmlNodePtr ptr)
|
||||
xmlChar *filename = xmlGetProp(ptr, (const xmlChar*)"file");
|
||||
xmlChar *filter = xmlGetProp(ptr, (const xmlChar*)"filter");
|
||||
xmlChar *id = xmlGetProp(ptr, (const xmlChar*)"id");
|
||||
char *last = NULL;
|
||||
struct texture_image img;
|
||||
|
||||
if (!id)
|
||||
{
|
||||
@ -352,13 +355,12 @@ static bool get_texture_image(const char *shader_path, xmlNodePtr ptr)
|
||||
char tex_path[MAXPATHLEN];
|
||||
strlcpy(tex_path, shader_path, sizeof(tex_path));
|
||||
|
||||
char *last = strrchr(tex_path, '/');
|
||||
last = strrchr(tex_path, '/');
|
||||
if (!last) last = strrchr(tex_path, '\\');
|
||||
if (last) last[1] = '\0';
|
||||
|
||||
strlcat(tex_path, (const char*)filename, sizeof(tex_path));
|
||||
|
||||
struct texture_image img;
|
||||
SSNES_LOG("Loading texture image from: \"%s\" ...\n", tex_path);
|
||||
if (!texture_image_load(tex_path, &img))
|
||||
{
|
||||
@ -477,13 +479,18 @@ static bool get_import_value(xmlNodePtr ptr)
|
||||
xmlChar *cgram = xmlGetProp(ptr, (const xmlChar*)"cgram");
|
||||
xmlChar *bitmask = xmlGetProp(ptr, (const xmlChar*)"mask");
|
||||
|
||||
unsigned memtype;
|
||||
enum snes_tracker_type tracker_type;
|
||||
enum snes_ram_type ram_type = SSNES_STATE_NONE;
|
||||
uint32_t addr = 0;
|
||||
unsigned mask_value = 0;
|
||||
|
||||
if (!semantic || !id)
|
||||
{
|
||||
SSNES_ERR("No semantic or ID for import value!\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
enum snes_tracker_type tracker_type;
|
||||
|
||||
if (strcmp((const char*)semantic, "capture") == 0)
|
||||
tracker_type = SSNES_STATE_CAPTURE;
|
||||
@ -505,9 +512,6 @@ static bool get_import_value(xmlNodePtr ptr)
|
||||
goto error;
|
||||
}
|
||||
|
||||
enum snes_ram_type ram_type = SSNES_STATE_NONE;
|
||||
uint32_t addr = 0;
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
if (tracker_type != SSNES_STATE_PYTHON)
|
||||
#endif
|
||||
@ -541,7 +545,6 @@ static bool get_import_value(xmlNodePtr ptr)
|
||||
}
|
||||
}
|
||||
|
||||
unsigned memtype;
|
||||
switch (ram_type)
|
||||
{
|
||||
case SSNES_STATE_WRAM:
|
||||
@ -570,7 +573,6 @@ static bool get_import_value(xmlNodePtr ptr)
|
||||
goto error;
|
||||
}
|
||||
|
||||
unsigned mask_value = 0;
|
||||
if (bitmask)
|
||||
mask_value = strtoul((const char*)bitmask, NULL, 16);
|
||||
|
||||
@ -618,6 +620,10 @@ static unsigned get_xml_shaders(const char *path, struct shader_program *prog, s
|
||||
|
||||
SSNES_LOG("Loading XML shader: %s\n", path);
|
||||
xmlDocPtr doc = xmlCtxtReadFile(ctx, path, NULL, 0);
|
||||
xmlNodePtr head = NULL;
|
||||
xmlNodePtr cur = NULL;
|
||||
unsigned num = 0;
|
||||
|
||||
if (!doc)
|
||||
{
|
||||
SSNES_ERR("Failed to parse XML file: %s\n", path);
|
||||
@ -630,8 +636,8 @@ static unsigned get_xml_shaders(const char *path, struct shader_program *prog, s
|
||||
goto error;
|
||||
}
|
||||
|
||||
xmlNodePtr head = xmlDocGetRootElement(doc);
|
||||
xmlNodePtr cur = NULL;
|
||||
head = xmlDocGetRootElement(doc);
|
||||
|
||||
for (cur = head; cur; cur = cur->next)
|
||||
{
|
||||
if (cur->type == XML_ELEMENT_NODE && strcmp((const char*)cur->name, "shader") == 0)
|
||||
@ -652,7 +658,6 @@ static unsigned get_xml_shaders(const char *path, struct shader_program *prog, s
|
||||
if (!cur) // We couldn't find any GLSL shader :(
|
||||
goto error;
|
||||
|
||||
unsigned num = 0;
|
||||
memset(prog, 0, sizeof(struct shader_program) * size);
|
||||
|
||||
// Iterate to check if we find fragment and/or vertex shaders.
|
||||
@ -739,11 +744,19 @@ static void print_shader_log(GLuint obj)
|
||||
|
||||
pglGetShaderiv(obj, GL_INFO_LOG_LENGTH, &max_len);
|
||||
|
||||
char info_log[max_len];
|
||||
if (max_len == 0)
|
||||
return;
|
||||
|
||||
char *info_log = (char*)malloc(max_len);
|
||||
if (!info_log)
|
||||
return;
|
||||
|
||||
pglGetShaderInfoLog(obj, max_len, &info_len, info_log);
|
||||
|
||||
if (info_len > 0)
|
||||
SSNES_LOG("Shader log: %s\n", info_log);
|
||||
|
||||
free(info_log);
|
||||
}
|
||||
|
||||
static void print_linker_log(GLuint obj)
|
||||
@ -753,11 +766,19 @@ static void print_linker_log(GLuint obj)
|
||||
|
||||
pglGetProgramiv(obj, GL_INFO_LOG_LENGTH, &max_len);
|
||||
|
||||
char info_log[max_len];
|
||||
if (max_len == 0)
|
||||
return;
|
||||
|
||||
char *info_log = (char*)malloc(max_len);
|
||||
if (!info_log)
|
||||
return;
|
||||
|
||||
pglGetProgramInfoLog(obj, max_len, &info_len, info_log);
|
||||
|
||||
if (info_len > 0)
|
||||
SSNES_LOG("Linker log: %s\n", info_log);
|
||||
|
||||
free(info_log);
|
||||
}
|
||||
|
||||
static bool compile_shader(GLuint shader, const char *program)
|
||||
@ -906,10 +927,10 @@ bool gl_glsl_init(const char *path)
|
||||
return false;
|
||||
}
|
||||
|
||||
struct shader_program stock_prog = {
|
||||
.vertex = strdup(stock_vertex),
|
||||
.fragment = strdup(stock_fragment),
|
||||
};
|
||||
struct shader_program stock_prog = {0};
|
||||
stock_prog.vertex = strdup(stock_vertex);
|
||||
stock_prog.fragment = strdup(stock_fragment);
|
||||
|
||||
if (!compile_programs(&gl_program[0], &stock_prog, 1))
|
||||
return false;
|
||||
|
||||
@ -958,15 +979,14 @@ bool gl_glsl_init(const char *path)
|
||||
|
||||
if (gl_tracker_info_cnt > 0)
|
||||
{
|
||||
struct snes_tracker_info info = {
|
||||
.wram = psnes_get_memory_data(SNES_MEMORY_WRAM),
|
||||
.vram = psnes_get_memory_data(SNES_MEMORY_VRAM),
|
||||
.cgram = psnes_get_memory_data(SNES_MEMORY_CGRAM),
|
||||
.apuram = psnes_get_memory_data(SNES_MEMORY_APURAM),
|
||||
.oam = psnes_get_memory_data(SNES_MEMORY_OAM),
|
||||
.info = gl_tracker_info,
|
||||
.info_elem = gl_tracker_info_cnt,
|
||||
};
|
||||
struct snes_tracker_info info = {0};
|
||||
info.wram = psnes_get_memory_data(SNES_MEMORY_WRAM);
|
||||
info.vram = psnes_get_memory_data(SNES_MEMORY_VRAM);
|
||||
info.cgram = psnes_get_memory_data(SNES_MEMORY_CGRAM);
|
||||
info.apuram = psnes_get_memory_data(SNES_MEMORY_APURAM);
|
||||
info.oam = psnes_get_memory_data(SNES_MEMORY_OAM);
|
||||
info.info = gl_tracker_info;
|
||||
info.info_elem = gl_tracker_info_cnt;
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
if (*gl_tracker_script)
|
||||
@ -999,7 +1019,7 @@ void gl_glsl_deinit(void)
|
||||
if (glsl_enable)
|
||||
{
|
||||
pglUseProgram(0);
|
||||
for (int i = 0; i <= gl_num_programs; i++)
|
||||
for (unsigned i = 0; i <= gl_num_programs; i++)
|
||||
{
|
||||
if (gl_program[i] == 0)
|
||||
continue;
|
||||
@ -1064,15 +1084,15 @@ void gl_glsl_set_params(unsigned width, unsigned height,
|
||||
|
||||
GLint location;
|
||||
|
||||
float inputSize[2] = {width, height};
|
||||
float inputSize[2] = {(float)width, (float)height};
|
||||
location = pglGetUniformLocation(gl_program[active_index], "rubyInputSize");
|
||||
pglUniform2fv(location, 1, inputSize);
|
||||
|
||||
float outputSize[2] = {out_width, out_height};
|
||||
float outputSize[2] = {(float)out_width, (float)out_height};
|
||||
location = pglGetUniformLocation(gl_program[active_index], "rubyOutputSize");
|
||||
pglUniform2fv(location, 1, outputSize);
|
||||
|
||||
float textureSize[2] = {tex_width, tex_height};
|
||||
float textureSize[2] = {(float)tex_width, (float)tex_height};
|
||||
location = pglGetUniformLocation(gl_program[active_index], "rubyTextureSize");
|
||||
pglUniform2fv(location, 1, textureSize);
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
#ifndef __SSNES_GLSL_H
|
||||
#define __SSNES_GLSL_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "../boolean.h"
|
||||
#include "gl_common.h"
|
||||
|
||||
bool gl_glsl_init(const char *path);
|
||||
|
@ -63,7 +63,7 @@ struct snes_tracker
|
||||
|
||||
snes_tracker_t* snes_tracker_init(const struct snes_tracker_info *info)
|
||||
{
|
||||
snes_tracker_t *tracker = calloc(1, sizeof(*tracker));
|
||||
snes_tracker_t *tracker = (snes_tracker_t*)calloc(1, sizeof(*tracker));
|
||||
if (!tracker)
|
||||
return NULL;
|
||||
|
||||
@ -80,7 +80,7 @@ snes_tracker_t* snes_tracker_init(const struct snes_tracker_info *info)
|
||||
}
|
||||
#endif
|
||||
|
||||
tracker->info = calloc(info->info_elem, sizeof(struct snes_tracker_internal));
|
||||
tracker->info = (struct snes_tracker_internal*)calloc(info->info_elem, sizeof(struct snes_tracker_internal));
|
||||
tracker->info_elem = info->info_elem;
|
||||
|
||||
for (unsigned i = 0; i < info->info_elem; i++)
|
||||
|
@ -19,7 +19,7 @@
|
||||
#define __SSNES_SNES_STATE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "../boolean.h"
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
|
110
gfx/xvideo.c
110
gfx/xvideo.c
@ -37,8 +37,7 @@
|
||||
|
||||
// Adapted from bSNES and MPlayer source.
|
||||
|
||||
typedef struct xv xv_t;
|
||||
struct xv
|
||||
typedef struct xv
|
||||
{
|
||||
Display *display;
|
||||
GC gc;
|
||||
@ -76,12 +75,12 @@ struct xv
|
||||
uint8_t font_v;
|
||||
#endif
|
||||
|
||||
void (*render_func)(xv_t*, const void *frame, unsigned width, unsigned height, unsigned pitch);
|
||||
};
|
||||
void (*render_func)(struct xv*, const void *frame, unsigned width, unsigned height, unsigned pitch);
|
||||
} xv_t;
|
||||
|
||||
static void xv_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
xv_t *xv = data;
|
||||
xv_t *xv = (xv_t*)data;
|
||||
Atom atom = XInternAtom(xv->display, "XV_SYNC_TO_VBLANK", true);
|
||||
if (atom != None && xv->port)
|
||||
XvSetPortAttribute(xv->display, xv->port, atom, !state);
|
||||
@ -108,9 +107,9 @@ static inline void calculate_yuv(uint8_t *y, uint8_t *u, uint8_t *v, unsigned r,
|
||||
|
||||
static void init_yuv_tables(xv_t *xv)
|
||||
{
|
||||
xv->ytable = malloc(0x8000);
|
||||
xv->utable = malloc(0x8000);
|
||||
xv->vtable = malloc(0x8000);
|
||||
xv->ytable = (uint8_t*)malloc(0x8000);
|
||||
xv->utable = (uint8_t*)malloc(0x8000);
|
||||
xv->vtable = (uint8_t*)malloc(0x8000);
|
||||
|
||||
for (unsigned i = 0; i < 0x8000; i++)
|
||||
{
|
||||
@ -217,7 +216,7 @@ static void xv_init_font(xv_t *xv, const char *font_path, unsigned font_size)
|
||||
// We render @ 2x scale to combat chroma downsampling. Also makes fonts more bearable :)
|
||||
static void render16_yuy2(xv_t *xv, const void *input_, unsigned width, unsigned height, unsigned pitch)
|
||||
{
|
||||
const uint16_t *input = input_;
|
||||
const uint16_t *input = (const uint16_t*)input_;
|
||||
uint8_t *output = (uint8_t*)xv->image->data;
|
||||
|
||||
for (unsigned y = 0; y < height; y++)
|
||||
@ -245,7 +244,7 @@ static void render16_yuy2(xv_t *xv, const void *input_, unsigned width, unsigned
|
||||
|
||||
static void render16_uyvy(xv_t *xv, const void *input_, unsigned width, unsigned height, unsigned pitch)
|
||||
{
|
||||
const uint16_t *input = input_;
|
||||
const uint16_t *input = (const uint16_t*)input_;
|
||||
uint8_t *output = (uint8_t*)xv->image->data;
|
||||
|
||||
for (unsigned y = 0; y < height; y++)
|
||||
@ -273,7 +272,7 @@ static void render16_uyvy(xv_t *xv, const void *input_, unsigned width, unsigned
|
||||
|
||||
static void render32_yuy2(xv_t *xv, const void *input_, unsigned width, unsigned height, unsigned pitch)
|
||||
{
|
||||
const uint32_t *input = input_;
|
||||
const uint32_t *input = (const uint32_t*)input_;
|
||||
uint8_t *output = (uint8_t*)xv->image->data;
|
||||
|
||||
for (unsigned y = 0; y < height; y++)
|
||||
@ -302,7 +301,7 @@ static void render32_yuy2(xv_t *xv, const void *input_, unsigned width, unsigned
|
||||
|
||||
static void render32_uyvy(xv_t *xv, const void *input_, unsigned width, unsigned height, unsigned pitch)
|
||||
{
|
||||
const uint32_t *input = input_;
|
||||
const uint32_t *input = (const uint32_t*)input_;
|
||||
uint16_t *output = (uint16_t*)xv->image->data;
|
||||
|
||||
for (unsigned y = 0; y < height; y++)
|
||||
@ -343,20 +342,20 @@ struct format_desc
|
||||
|
||||
static const struct format_desc formats[] = {
|
||||
{
|
||||
.render_16 = render16_yuy2,
|
||||
.render_32 = render32_yuy2,
|
||||
.components = { 'Y', 'U', 'Y', 'V' },
|
||||
.luma_index = { 0, 2 },
|
||||
.u_index = 1,
|
||||
.v_index = 3,
|
||||
render16_yuy2,
|
||||
render32_yuy2,
|
||||
{ 'Y', 'U', 'Y', 'V' },
|
||||
{ 0, 2 },
|
||||
1,
|
||||
3,
|
||||
},
|
||||
{
|
||||
.render_16 = render16_uyvy,
|
||||
.render_32 = render32_uyvy,
|
||||
.components = { 'U', 'Y', 'V', 'Y' },
|
||||
.luma_index = { 1, 3 },
|
||||
.u_index = 0,
|
||||
.v_index = 2,
|
||||
render16_uyvy,
|
||||
render32_uyvy,
|
||||
{ 'U', 'Y', 'V', 'Y' },
|
||||
{ 1, 3 },
|
||||
0,
|
||||
2,
|
||||
},
|
||||
};
|
||||
|
||||
@ -400,11 +399,21 @@ static bool adaptor_set_format(xv_t *xv, Display *dpy, XvPortID port, const vide
|
||||
|
||||
static void *xv_init(const video_info_t *video, const input_driver_t **input, void **input_data)
|
||||
{
|
||||
xv_t *xv = calloc(1, sizeof(*xv));
|
||||
xv_t *xv = (xv_t*)calloc(1, sizeof(*xv));
|
||||
if (!xv)
|
||||
return NULL;
|
||||
|
||||
xv->display = XOpenDisplay(NULL);
|
||||
struct sigaction sa;
|
||||
unsigned adaptor_count = 0;
|
||||
int visualmatches = 0;
|
||||
XSetWindowAttributes attributes = {0};
|
||||
unsigned width = 0, height = 0;
|
||||
char buf[128];
|
||||
Atom atom = 0;
|
||||
void *xinput = NULL;
|
||||
XVisualInfo *visualinfo = NULL;
|
||||
XVisualInfo visualtemplate = {0};
|
||||
|
||||
if (!XShmQueryExtension(xv->display))
|
||||
{
|
||||
@ -417,7 +426,6 @@ static void *xv_init(const video_info_t *video, const input_driver_t **input, vo
|
||||
// Find an appropriate Xv port.
|
||||
xv->port = 0;
|
||||
XvAdaptorInfo *adaptor_info;
|
||||
unsigned adaptor_count = 0;
|
||||
XvQueryAdaptors(xv->display, DefaultRootWindow(xv->display), &adaptor_count, &adaptor_info);
|
||||
for (unsigned i = 0; i < adaptor_count; i++)
|
||||
{
|
||||
@ -442,13 +450,11 @@ static void *xv_init(const video_info_t *video, const input_driver_t **input, vo
|
||||
goto error;
|
||||
}
|
||||
|
||||
XVisualInfo visualtemplate;
|
||||
visualtemplate.visualid = xv->visualid;
|
||||
visualtemplate.screen = DefaultScreen(xv->display);
|
||||
visualtemplate.depth = xv->depth;
|
||||
visualtemplate.visual = 0;
|
||||
int visualmatches = 0;
|
||||
XVisualInfo *visualinfo = XGetVisualInfo(xv->display, VisualIDMask | VisualScreenMask | VisualDepthMask, &visualtemplate, &visualmatches);
|
||||
visualinfo = XGetVisualInfo(xv->display, VisualIDMask | VisualScreenMask | VisualDepthMask, &visualtemplate, &visualmatches);
|
||||
if (visualmatches < 1 || !visualinfo->visual)
|
||||
{
|
||||
if (visualinfo) XFree(visualinfo);
|
||||
@ -457,13 +463,12 @@ static void *xv_init(const video_info_t *video, const input_driver_t **input, vo
|
||||
}
|
||||
|
||||
xv->colormap = XCreateColormap(xv->display, DefaultRootWindow(xv->display), visualinfo->visual, AllocNone);
|
||||
XSetWindowAttributes attributes;
|
||||
attributes.colormap = xv->colormap;
|
||||
attributes.border_pixel = 0;
|
||||
attributes.event_mask = StructureNotifyMask | DestroyNotify | ClientMessage;
|
||||
|
||||
unsigned width = video->fullscreen ? ((video->width == 0) ? g_extern.system.geom.base_width : video->width) : video->width;
|
||||
unsigned height = video->fullscreen ? ((video->height == 0) ? g_extern.system.geom.base_height : video->height) : video->height;
|
||||
width = video->fullscreen ? ((video->width == 0) ? g_extern.system.geom.base_width : video->width) : video->width;
|
||||
height = video->fullscreen ? ((video->height == 0) ? g_extern.system.geom.base_height : video->height) : video->height;
|
||||
xv->window = XCreateWindow(xv->display, DefaultRootWindow(xv->display),
|
||||
0, 0, width, height,
|
||||
0, xv->depth, InputOutput, visualinfo->visual,
|
||||
@ -474,7 +479,6 @@ static void *xv_init(const video_info_t *video, const input_driver_t **input, vo
|
||||
|
||||
XMapWindow(xv->display, xv->window);
|
||||
|
||||
char buf[128];
|
||||
if (gfx_window_title(buf, sizeof(buf)))
|
||||
XStoreName(xv->display, xv->window, buf);
|
||||
|
||||
@ -485,7 +489,7 @@ static void *xv_init(const video_info_t *video, const input_driver_t **input, vo
|
||||
xv->gc = XCreateGC(xv->display, xv->window, 0, 0);
|
||||
|
||||
// Set colorkey to auto paint, so that Xv video output is always visible
|
||||
Atom atom = XInternAtom(xv->display, "XV_AUTOPAINT_COLORKEY", true);
|
||||
atom = XInternAtom(xv->display, "XV_AUTOPAINT_COLORKEY", true);
|
||||
if (atom != None) XvSetPortAttribute(xv->display, xv->port, atom, 1);
|
||||
|
||||
xv->width = g_extern.system.geom.max_width;
|
||||
@ -501,7 +505,7 @@ static void *xv_init(const video_info_t *video, const input_driver_t **input, vo
|
||||
xv->height = xv->image->height;
|
||||
|
||||
xv->shminfo.shmid = shmget(IPC_PRIVATE, xv->image->data_size, IPC_CREAT | 0777);
|
||||
xv->shminfo.shmaddr = xv->image->data = shmat(xv->shminfo.shmid, NULL, 0);
|
||||
xv->shminfo.shmaddr = xv->image->data = (char*)shmat(xv->shminfo.shmid, NULL, 0);
|
||||
xv->shminfo.readOnly = false;
|
||||
if (!XShmAttach(xv->display, &xv->shminfo))
|
||||
{
|
||||
@ -515,7 +519,6 @@ static void *xv_init(const video_info_t *video, const input_driver_t **input, vo
|
||||
if (xv->quit_atom)
|
||||
XSetWMProtocols(xv->display, xv->window, &xv->quit_atom, 1);
|
||||
|
||||
struct sigaction sa;
|
||||
sa.sa_handler = sighandler;
|
||||
sa.sa_flags = SA_RESTART;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
@ -525,7 +528,7 @@ static void *xv_init(const video_info_t *video, const input_driver_t **input, vo
|
||||
xv_set_nonblock_state(xv, !video->vsync);
|
||||
xv->focus = true;
|
||||
|
||||
void *xinput = input_x.init();
|
||||
xinput = input_x.init();
|
||||
if (xinput)
|
||||
{
|
||||
*input = &input_x;
|
||||
@ -575,7 +578,7 @@ static bool check_resize(xv_t *xv, unsigned width, unsigned height)
|
||||
return false;
|
||||
}
|
||||
|
||||
xv->shminfo.shmaddr = xv->image->data = shmat(xv->shminfo.shmid, NULL, 0);
|
||||
xv->shminfo.shmaddr = xv->image->data = (char*)shmat(xv->shminfo.shmid, NULL, 0);
|
||||
xv->shminfo.readOnly = false;
|
||||
|
||||
if (!XShmAttach(xv->display, &xv->shminfo))
|
||||
@ -648,13 +651,13 @@ static void xv_render_msg(xv_t *xv, const char *msg, unsigned width, unsigned he
|
||||
int base_y = _base_y - head->off_y;
|
||||
if (base_y >= 0)
|
||||
{
|
||||
for (int y = 0; y < head->height && (base_y + y) < height; y++)
|
||||
for (int y = 0; y < (int)head->height && (base_y + y) < height; y++)
|
||||
{
|
||||
if (base_x < 0)
|
||||
continue;
|
||||
|
||||
const uint8_t * restrict a = head->output + head->pitch * y;
|
||||
uint8_t * restrict out = (uint8_t*)xv->image->data + (base_y - head->height + y) * pitch + base_x;
|
||||
const uint8_t *a = head->output + head->pitch * y;
|
||||
uint8_t *out = (uint8_t*)xv->image->data + (base_y - head->height + y) * pitch + base_x;
|
||||
|
||||
for (int x = 0; x < (head->width << 1) && (base_x + x) < pitch; x += 4)
|
||||
{
|
||||
@ -698,7 +701,7 @@ static void xv_render_msg(xv_t *xv, const char *msg, unsigned width, unsigned he
|
||||
|
||||
static bool xv_frame(void *data, const void *frame, unsigned width, unsigned height, unsigned pitch, const char *msg)
|
||||
{
|
||||
xv_t *xv = data;
|
||||
xv_t *xv = (xv_t*)data;
|
||||
|
||||
if (!check_resize(xv, width, height))
|
||||
return false;
|
||||
@ -728,7 +731,7 @@ static bool xv_frame(void *data, const void *frame, unsigned width, unsigned hei
|
||||
|
||||
static bool xv_alive(void *data)
|
||||
{
|
||||
xv_t *xv = data;
|
||||
xv_t *xv = (xv_t*)data;
|
||||
|
||||
XEvent event;
|
||||
while (XPending(xv->display))
|
||||
@ -737,7 +740,7 @@ static bool xv_alive(void *data)
|
||||
switch (event.type)
|
||||
{
|
||||
case ClientMessage:
|
||||
if (event.xclient.data.l[0] == xv->quit_atom)
|
||||
if ((Atom)event.xclient.data.l[0] == xv->quit_atom)
|
||||
return false;
|
||||
break;
|
||||
case DestroyNotify:
|
||||
@ -758,14 +761,14 @@ static bool xv_alive(void *data)
|
||||
|
||||
static bool xv_focus(void *data)
|
||||
{
|
||||
xv_t *xv = data;
|
||||
xv_t *xv = (xv_t*)data;
|
||||
return xv->focus;
|
||||
}
|
||||
|
||||
|
||||
static void xv_free(void *data)
|
||||
{
|
||||
xv_t *xv = data;
|
||||
xv_t *xv = (xv_t*)data;
|
||||
XShmDetach(xv->display, &xv->shminfo);
|
||||
shmdt(xv->shminfo.shmaddr);
|
||||
shmctl(xv->shminfo.shmid, IPC_RMID, NULL);
|
||||
@ -791,12 +794,13 @@ static void xv_free(void *data)
|
||||
}
|
||||
|
||||
const video_driver_t video_xvideo = {
|
||||
.init = xv_init,
|
||||
.frame = xv_frame,
|
||||
.alive = xv_alive,
|
||||
.set_nonblock_state = xv_set_nonblock_state,
|
||||
.focus = xv_focus,
|
||||
.free = xv_free,
|
||||
.ident = "xvideo"
|
||||
xv_init,
|
||||
xv_frame,
|
||||
xv_set_nonblock_state,
|
||||
xv_alive,
|
||||
xv_focus,
|
||||
NULL,
|
||||
xv_free,
|
||||
"xvideo"
|
||||
};
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include "ssnes_dinput.h"
|
||||
#include "SDL.h"
|
||||
#include "SDL_syswm.h"
|
||||
#include <stdbool.h>
|
||||
#include "../boolean.h"
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
@ -46,7 +46,7 @@ void sdl_dinput_free(sdl_dinput_t *di)
|
||||
|
||||
static BOOL CALLBACK enum_axes_cb(const DIDEVICEOBJECTINSTANCE *inst, void *p)
|
||||
{
|
||||
LPDIRECTINPUTDEVICE8 joypad = p;
|
||||
LPDIRECTINPUTDEVICE8 joypad = (LPDIRECTINPUTDEVICE8)p;
|
||||
|
||||
DIPROPRANGE range;
|
||||
memset(&range, 0, sizeof(range));
|
||||
@ -63,7 +63,7 @@ static BOOL CALLBACK enum_axes_cb(const DIDEVICEOBJECTINSTANCE *inst, void *p)
|
||||
|
||||
static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p)
|
||||
{
|
||||
sdl_dinput_t *di = p;
|
||||
sdl_dinput_t *di = (sdl_dinput_t*)p;
|
||||
|
||||
unsigned active = 0;
|
||||
unsigned n;
|
||||
@ -82,7 +82,11 @@ static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p)
|
||||
if (n == MAX_PLAYERS)
|
||||
return DIENUM_CONTINUE;
|
||||
|
||||
#ifdef __cplusplus
|
||||
if (FAILED(IDirectInput8_CreateDevice(di->ctx, inst->guidInstance, &di->joypad[n], NULL)))
|
||||
#else
|
||||
if (FAILED(IDirectInput8_CreateDevice(di->ctx, &inst->guidInstance, &di->joypad[n], NULL)))
|
||||
#endif
|
||||
return DIENUM_CONTINUE;
|
||||
|
||||
IDirectInputDevice8_SetDataFormat(di->joypad[n], &c_dfDIJoystick2);
|
||||
@ -97,7 +101,7 @@ static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p)
|
||||
|
||||
sdl_dinput_t* sdl_dinput_init(void)
|
||||
{
|
||||
sdl_dinput_t *di = calloc(1, sizeof(*di));
|
||||
sdl_dinput_t *di = (sdl_dinput_t*)calloc(1, sizeof(*di));
|
||||
if (!di)
|
||||
return NULL;
|
||||
|
||||
@ -118,9 +122,15 @@ sdl_dinput_t* sdl_dinput_init(void)
|
||||
di->hWnd = info.window;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
if (FAILED(DirectInput8Create(
|
||||
GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8,
|
||||
(void**)&di->ctx, NULL)))
|
||||
#else
|
||||
if (FAILED(DirectInput8Create(
|
||||
GetModuleHandle(NULL), DIRECTINPUT_VERSION, &IID_IDirectInput8,
|
||||
(void**)&di->ctx, NULL)))
|
||||
#endif
|
||||
{
|
||||
SSNES_ERR("Failed to init DirectInput.\n");
|
||||
goto error;
|
||||
|
27
input/sdl.c
27
input/sdl.c
@ -18,7 +18,7 @@
|
||||
#include "driver.h"
|
||||
|
||||
#include "../gfx/sdlwrap.h"
|
||||
#include <stdbool.h>
|
||||
#include "../boolean.h"
|
||||
#include "general.h"
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
@ -126,7 +126,7 @@ static void init_lut(void)
|
||||
static void *sdl_input_init(void)
|
||||
{
|
||||
init_lut();
|
||||
sdl_input_t *sdl = calloc(1, sizeof(*sdl));
|
||||
sdl_input_t *sdl = (sdl_input_t*)calloc(1, sizeof(*sdl));
|
||||
if (!sdl)
|
||||
return NULL;
|
||||
|
||||
@ -189,7 +189,7 @@ static bool sdl_joykey_pressed(sdl_input_t *sdl, int port_num, uint16_t joykey)
|
||||
if (GET_HAT_DIR(joykey))
|
||||
{
|
||||
int hat = GET_HAT(joykey);
|
||||
if (hat < sdl->num_hats[port_num])
|
||||
if (hat < (int)sdl->num_hats[port_num])
|
||||
{
|
||||
Uint8 dir = SDL_JoystickGetHat(sdl->joysticks[port_num], hat);
|
||||
switch (GET_HAT_DIR(joykey))
|
||||
@ -273,7 +273,7 @@ static bool sdl_bind_button_pressed(void *data, int key)
|
||||
for (unsigned i = 0; binds[i].id != -1; i++)
|
||||
{
|
||||
if (binds[i].id == key)
|
||||
return sdl_is_pressed(data, 0, &binds[i]);
|
||||
return sdl_is_pressed((sdl_input_t*)data, 0, &binds[i]);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -352,8 +352,9 @@ static int16_t sdl_justifier_device_state(sdl_input_t *sdl, unsigned index, unsi
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int16_t sdl_input_state(void *data, const struct snes_keybind **binds, bool port, unsigned device, unsigned index, unsigned id)
|
||||
static int16_t sdl_input_state(void *data_, const struct snes_keybind **binds, bool port, unsigned device, unsigned index, unsigned id)
|
||||
{
|
||||
sdl_input_t *data = (sdl_input_t*)data_;
|
||||
switch (device)
|
||||
{
|
||||
case SNES_DEVICE_JOYPAD:
|
||||
@ -381,7 +382,7 @@ static void sdl_input_free(void *data)
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event));
|
||||
|
||||
sdl_input_t *sdl = data;
|
||||
sdl_input_t *sdl = (sdl_input_t*)data;
|
||||
|
||||
#ifdef HAVE_DINPUT
|
||||
sdl_dinput_free(sdl->di);
|
||||
@ -412,7 +413,7 @@ static void sdl_poll_mouse(sdl_input_t *sdl)
|
||||
static void sdl_input_poll(void *data)
|
||||
{
|
||||
SDL_PumpEvents();
|
||||
sdl_input_t *sdl = data;
|
||||
sdl_input_t *sdl = (sdl_input_t*)data;
|
||||
|
||||
#ifdef HAVE_DINPUT
|
||||
sdl_dinput_poll(sdl->di);
|
||||
@ -424,11 +425,11 @@ static void sdl_input_poll(void *data)
|
||||
}
|
||||
|
||||
const input_driver_t input_sdl = {
|
||||
.init = sdl_input_init,
|
||||
.poll = sdl_input_poll,
|
||||
.input_state = sdl_input_state,
|
||||
.key_pressed = sdl_bind_button_pressed,
|
||||
.free = sdl_input_free,
|
||||
.ident = "sdl"
|
||||
sdl_input_init,
|
||||
sdl_input_poll,
|
||||
sdl_input_state,
|
||||
sdl_bind_button_pressed,
|
||||
sdl_input_free,
|
||||
"sdl"
|
||||
};
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
#define DIRECTINPUT_VERSION 0x0800
|
||||
|
||||
#include <dinput.h>
|
||||
#include <stdbool.h>
|
||||
#include "../boolean.h"
|
||||
#include "general.h"
|
||||
|
||||
// Piggyback joypad driver for SDL.
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include "driver.h"
|
||||
|
||||
#include "SDL.h"
|
||||
#include <stdbool.h>
|
||||
#include "../boolean.h"
|
||||
#include "general.h"
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
@ -135,7 +135,7 @@ static void init_lut(void)
|
||||
|
||||
static void *x_input_init(void)
|
||||
{
|
||||
x11_input_t *x11 = calloc(1, sizeof(*x11));
|
||||
x11_input_t *x11 = (x11_input_t*)calloc(1, sizeof(*x11));
|
||||
if (!x11)
|
||||
return NULL;
|
||||
|
||||
@ -146,7 +146,7 @@ static void *x_input_init(void)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
x11->sdl = input_sdl.init();
|
||||
x11->sdl = (sdl_input_t*)input_sdl.init();
|
||||
if (!x11->sdl)
|
||||
{
|
||||
free(x11);
|
||||
@ -171,7 +171,7 @@ static bool x_is_pressed(x11_input_t *x11, const struct snes_keybind *binds, uns
|
||||
{
|
||||
for (int i = 0; binds[i].id != -1; i++)
|
||||
{
|
||||
if (binds[i].id == id)
|
||||
if (binds[i].id == (int)id)
|
||||
return x_key_pressed(x11, binds[i].key);
|
||||
}
|
||||
|
||||
@ -180,7 +180,7 @@ static bool x_is_pressed(x11_input_t *x11, const struct snes_keybind *binds, uns
|
||||
|
||||
static bool x_bind_button_pressed(void *data, int key)
|
||||
{
|
||||
x11_input_t *x11 = data;
|
||||
x11_input_t *x11 = (x11_input_t*)data;
|
||||
bool pressed = x_is_pressed(x11, g_settings.input.binds[0], key);
|
||||
if (!pressed)
|
||||
return input_sdl.key_pressed(x11->sdl, key);
|
||||
@ -189,7 +189,7 @@ static bool x_bind_button_pressed(void *data, int key)
|
||||
|
||||
static int16_t x_input_state(void *data, const struct snes_keybind **binds, bool port, unsigned device, unsigned index, unsigned id)
|
||||
{
|
||||
x11_input_t *x11 = data;
|
||||
x11_input_t *x11 = (x11_input_t*)data;
|
||||
bool pressed = false;
|
||||
|
||||
switch (device)
|
||||
@ -213,7 +213,7 @@ static int16_t x_input_state(void *data, const struct snes_keybind **binds, bool
|
||||
|
||||
static void x_input_free(void *data)
|
||||
{
|
||||
x11_input_t *x11 = data;
|
||||
x11_input_t *x11 = (x11_input_t*)data;
|
||||
input_sdl.free(x11->sdl);
|
||||
XCloseDisplay(x11->display);
|
||||
free(data);
|
||||
@ -221,17 +221,17 @@ static void x_input_free(void *data)
|
||||
|
||||
static void x_input_poll(void *data)
|
||||
{
|
||||
x11_input_t *x11 = data;
|
||||
x11_input_t *x11 = (x11_input_t*)data;
|
||||
XQueryKeymap(x11->display, x11->state);
|
||||
input_sdl.poll(x11->sdl);
|
||||
}
|
||||
|
||||
const input_driver_t input_x = {
|
||||
.init = x_input_init,
|
||||
.poll = x_input_poll,
|
||||
.input_state = x_input_state,
|
||||
.key_pressed = x_bind_button_pressed,
|
||||
.free = x_input_free,
|
||||
.ident = "x"
|
||||
x_input_init,
|
||||
x_input_poll,
|
||||
x_input_state,
|
||||
x_bind_button_pressed,
|
||||
x_input_free,
|
||||
"x"
|
||||
};
|
||||
|
||||
|
@ -18,7 +18,8 @@
|
||||
#include "message.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include "boolean.h"
|
||||
#include "posix_string.h"
|
||||
|
||||
struct queue_elem
|
||||
{
|
||||
@ -37,12 +38,12 @@ struct msg_queue
|
||||
|
||||
msg_queue_t *msg_queue_new(size_t size)
|
||||
{
|
||||
msg_queue_t *queue = calloc(1, sizeof(*queue));
|
||||
msg_queue_t *queue = (msg_queue_t*)calloc(1, sizeof(*queue));
|
||||
if (!queue)
|
||||
return NULL;
|
||||
|
||||
queue->size = size + 1;
|
||||
queue->elems = calloc(queue->size, sizeof(struct queue_elem*));
|
||||
queue->elems = (struct queue_elem**)calloc(queue->size, sizeof(struct queue_elem*));
|
||||
|
||||
if (!queue->elems)
|
||||
{
|
||||
@ -65,7 +66,7 @@ void msg_queue_push(msg_queue_t *queue, const char *msg, unsigned prio, unsigned
|
||||
if (queue->ptr >= queue->size)
|
||||
return;
|
||||
|
||||
struct queue_elem *new_elem = calloc(1, sizeof(struct queue_elem));
|
||||
struct queue_elem *new_elem = (struct queue_elem*)calloc(1, sizeof(struct queue_elem));
|
||||
new_elem->prio = prio;
|
||||
new_elem->duration = duration;
|
||||
new_elem->msg = msg ? strdup(msg) : NULL;
|
||||
|
8
movie.c
8
movie.c
@ -166,7 +166,7 @@ static bool init_playback(bsv_movie_t *handle, const char *path)
|
||||
// If we're playing back from the start, state_size is 0.
|
||||
if (state_size)
|
||||
{
|
||||
handle->state = malloc(state_size);
|
||||
handle->state = (uint8_t*)malloc(state_size);
|
||||
if (!handle->state)
|
||||
return false;
|
||||
|
||||
@ -212,7 +212,7 @@ static bool init_record(bsv_movie_t *handle, const char *path)
|
||||
header[STATE_SIZE_INDEX] = swap_if_big32(state_size);
|
||||
fwrite(header, 4, sizeof(uint32_t), handle->file);
|
||||
|
||||
handle->state = malloc(state_size);
|
||||
handle->state = (uint8_t*)malloc(state_size);
|
||||
if (!handle->state)
|
||||
return false;
|
||||
|
||||
@ -255,7 +255,7 @@ void bsv_movie_set_input(bsv_movie_t *handle, int16_t input)
|
||||
|
||||
bsv_movie_t *bsv_movie_init(const char *path, enum ssnes_movie_type type)
|
||||
{
|
||||
bsv_movie_t *handle = calloc(1, sizeof(*handle));
|
||||
bsv_movie_t *handle = (bsv_movie_t*)calloc(1, sizeof(*handle));
|
||||
if (!handle)
|
||||
return NULL;
|
||||
|
||||
@ -268,7 +268,7 @@ bsv_movie_t *bsv_movie_init(const char *path, enum ssnes_movie_type type)
|
||||
goto error;
|
||||
|
||||
// Just pick something really large :D ~1 million frames rewind should do the trick.
|
||||
if (!(handle->frame_pos = calloc((1 << 20), sizeof(size_t))))
|
||||
if (!(handle->frame_pos = (size_t*)calloc((1 << 20), sizeof(size_t))))
|
||||
goto error;
|
||||
|
||||
handle->frame_pos[0] = handle->min_file_pos;
|
||||
|
4
movie.h
4
movie.h
@ -19,14 +19,14 @@
|
||||
#define __SSNES_MOVIE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "boolean.h"
|
||||
|
||||
typedef struct bsv_movie bsv_movie_t;
|
||||
|
||||
enum ssnes_movie_type
|
||||
{
|
||||
SSNES_MOVIE_PLAYBACK,
|
||||
SSNES_MOVIE_RECORD,
|
||||
SSNES_MOVIE_RECORD
|
||||
};
|
||||
|
||||
bsv_movie_t *bsv_movie_init(const char *path, enum ssnes_movie_type type);
|
||||
|
15
netplay.c
15
netplay.c
@ -364,11 +364,11 @@ static bool get_info(netplay_t *handle)
|
||||
|
||||
static void init_buffers(netplay_t *handle)
|
||||
{
|
||||
handle->buffer = calloc(handle->buffer_size, sizeof(*handle->buffer));
|
||||
handle->buffer = (struct delta_frame*)calloc(handle->buffer_size, sizeof(*handle->buffer));
|
||||
handle->state_size = psnes_serialize_size();
|
||||
for (unsigned i = 0; i < handle->buffer_size; i++)
|
||||
{
|
||||
handle->buffer[i].state = malloc(handle->state_size);
|
||||
handle->buffer[i].state = (uint8_t*)malloc(handle->state_size);
|
||||
handle->buffer[i].is_simulated = true;
|
||||
}
|
||||
}
|
||||
@ -378,7 +378,7 @@ netplay_t *netplay_new(const char *server, uint16_t port, unsigned frames, const
|
||||
if (frames > UDP_FRAME_PACKETS)
|
||||
frames = UDP_FRAME_PACKETS;
|
||||
|
||||
netplay_t *handle = calloc(1, sizeof(*handle));
|
||||
netplay_t *handle = (netplay_t*)calloc(1, sizeof(*handle));
|
||||
if (!handle)
|
||||
return NULL;
|
||||
|
||||
@ -451,10 +451,9 @@ static int poll_input(netplay_t *handle, bool block)
|
||||
{
|
||||
int max_fd = (handle->fd > handle->udp_fd ? handle->fd : handle->udp_fd) + 1;
|
||||
|
||||
const struct timeval tv = {
|
||||
.tv_sec = 0,
|
||||
.tv_usec = block ? (RETRY_MS * 1000) : 0
|
||||
};
|
||||
struct timeval tv = {0};
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = block ? (RETRY_MS * 1000) : 0;
|
||||
|
||||
do
|
||||
{
|
||||
@ -566,7 +565,7 @@ static void parse_packet(netplay_t *handle, uint32_t *buffer, unsigned size)
|
||||
static bool receive_data(netplay_t *handle, uint32_t *buffer, size_t size)
|
||||
{
|
||||
socklen_t addrlen = sizeof(handle->their_addr);
|
||||
if (recvfrom(handle->udp_fd, NONCONST_CAST buffer, size, 0, (struct sockaddr*)&handle->their_addr, &addrlen) != size)
|
||||
if (recvfrom(handle->udp_fd, NONCONST_CAST buffer, size, 0, (struct sockaddr*)&handle->their_addr, &addrlen) != (ssize_t)size)
|
||||
return false;
|
||||
handle->has_client_addr = true;
|
||||
return true;
|
||||
|
@ -20,7 +20,7 @@
|
||||
#define __SSNES_NETPLAY_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "boolean.h"
|
||||
#include "libsnes.hpp"
|
||||
|
||||
void input_poll_net(void);
|
||||
|
56
posix_string.c
Normal file
56
posix_string.c
Normal file
@ -0,0 +1,56 @@
|
||||
/* SSNES - A Super Nintendo Entertainment System (SNES) Emulator frontend for libsnes.
|
||||
* Copyright (C) 2010-2011 - Hans-Kristian Arntzen
|
||||
*
|
||||
* Some code herein may be based on code found in BSNES.
|
||||
*
|
||||
* SSNES 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 Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* SSNES 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 SSNES.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "posix_string.h"
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include "strl.h"
|
||||
|
||||
int strcasecmp(const char *a, const char *b)
|
||||
{
|
||||
while (*a && *b)
|
||||
{
|
||||
int a_ = tolower(*a);
|
||||
int b_ = tolower(*b);
|
||||
if (a_ != b_)
|
||||
return a_ - b_;
|
||||
|
||||
a++;
|
||||
b++;
|
||||
}
|
||||
|
||||
return tolower(*a) - tolower(*b);
|
||||
}
|
||||
|
||||
char *strdup(const char *orig)
|
||||
{
|
||||
size_t len = strlen(orig) + 1;
|
||||
char *ret = (char*)malloc(len);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
strlcpy(ret, orig, len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int isblank(int c)
|
||||
{
|
||||
return (c == ' ') || (c == '\t');
|
||||
}
|
||||
|
32
posix_string.h
Normal file
32
posix_string.h
Normal file
@ -0,0 +1,32 @@
|
||||
/* SSNES - A Super Nintendo Entertainment System (SNES) Emulator frontend for libsnes.
|
||||
* Copyright (C) 2010-2011 - Hans-Kristian Arntzen
|
||||
*
|
||||
* Some code herein may be based on code found in BSNES.
|
||||
*
|
||||
* SSNES 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 Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* SSNES 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 SSNES.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __SSNES_POSIX_STRING_H
|
||||
#define __SSNES_POSIX_STRING_H
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#define strcasecmp(a, b) strcasecmp_ssnes__(a, b)
|
||||
#define strdup(orig) strdup_ssnes__(orig)
|
||||
#define isblank(c) isblank_ssnes__(c)
|
||||
int strcasecmp(const char *a, const char *b);
|
||||
char *strdup(const char *orig);
|
||||
int isblank(int c);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -1,3 +1,27 @@
|
||||
/* SSNES - A Super Nintendo Entertainment System (SNES) Emulator frontend for libsnes.
|
||||
* Copyright (C) 2010-2011 - Hans-Kristian Arntzen
|
||||
*
|
||||
* Some code herein may be based on code found in BSNES.
|
||||
*
|
||||
* SSNES 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 Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* SSNES 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 SSNES.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __STDC_CONSTANT_MACROS
|
||||
#define __STDC_CONSTANT_MACROS
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavutil/mathematics.h>
|
||||
#include <libavutil/avutil.h>
|
||||
@ -6,11 +30,15 @@
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libswscale/swscale.h>
|
||||
#include <libavutil/avconfig.h>
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include "../boolean.h"
|
||||
#include "ffemu.h"
|
||||
#include "fifo_buffer.h"
|
||||
#include "thread.h"
|
||||
@ -31,8 +59,8 @@ struct video_info
|
||||
uint8_t *outbuf;
|
||||
size_t outbuf_size;
|
||||
|
||||
int fmt;
|
||||
int pix_fmt;
|
||||
enum PixelFormat fmt;
|
||||
enum PixelFormat pix_fmt;
|
||||
size_t pix_size;
|
||||
|
||||
AVFormatContext *format;
|
||||
@ -111,12 +139,12 @@ static bool init_audio(struct audio_info *audio, struct ffemu_params *param)
|
||||
return false;
|
||||
}
|
||||
|
||||
audio->buffer = av_malloc(audio->codec->frame_size * param->channels * sizeof(int16_t));
|
||||
audio->buffer = (int16_t*)av_malloc(audio->codec->frame_size * param->channels * sizeof(int16_t));
|
||||
if (!audio->buffer)
|
||||
return false;
|
||||
|
||||
audio->outbuf_size = 2000000;
|
||||
audio->outbuf = av_malloc(audio->outbuf_size);
|
||||
audio->outbuf = (int16_t*)av_malloc(audio->outbuf_size);
|
||||
if (!audio->outbuf)
|
||||
return false;
|
||||
|
||||
@ -193,10 +221,10 @@ static bool init_video(struct video_info *video, const struct ffemu_params *para
|
||||
|
||||
// Allocate a big buffer :p ffmpeg API doesn't seem to give us some clues how big this buffer should be.
|
||||
video->outbuf_size = 1 << 23;
|
||||
video->outbuf = av_malloc(video->outbuf_size);
|
||||
video->outbuf = (uint8_t*)av_malloc(video->outbuf_size);
|
||||
|
||||
size_t size = avpicture_get_size(video->pix_fmt, param->out_width, param->out_height);
|
||||
video->conv_frame_buf = av_malloc(size);
|
||||
video->conv_frame_buf = (uint8_t*)av_malloc(size);
|
||||
video->conv_frame = avcodec_alloc_frame();
|
||||
avpicture_fill((AVPicture*)video->conv_frame, video->conv_frame_buf, video->pix_fmt, param->out_width, param->out_height);
|
||||
|
||||
@ -339,7 +367,7 @@ ffemu_t *ffemu_new(const struct ffemu_params *params)
|
||||
{
|
||||
av_register_all();
|
||||
|
||||
ffemu_t *handle = calloc(1, sizeof(*handle));
|
||||
ffemu_t *handle = (ffemu_t*)calloc(1, sizeof(*handle));
|
||||
if (!handle)
|
||||
goto error;
|
||||
|
||||
@ -547,11 +575,11 @@ static bool ffemu_push_audio_thread(ffemu_t *handle, const struct ffemu_audio_da
|
||||
{
|
||||
AVPacket pkt;
|
||||
av_init_packet(&pkt);
|
||||
pkt.data = handle->audio.outbuf;
|
||||
pkt.data = (uint8_t*)handle->audio.outbuf;
|
||||
pkt.stream_index = handle->muxer.astream->index;
|
||||
|
||||
int out_size = avcodec_encode_audio(handle->audio.codec,
|
||||
handle->audio.outbuf, handle->audio.outbuf_size, handle->audio.buffer);
|
||||
(uint8_t*)handle->audio.outbuf, handle->audio.outbuf_size, (const int16_t*)handle->audio.buffer);
|
||||
if (out_size < 0)
|
||||
return false;
|
||||
|
||||
@ -579,7 +607,7 @@ bool ffemu_finalize(ffemu_t *handle)
|
||||
deinit_thread(handle);
|
||||
|
||||
size_t audio_buf_size = 512 * handle->params.channels * sizeof(int16_t);
|
||||
int16_t *audio_buf = av_malloc(audio_buf_size);
|
||||
int16_t *audio_buf = (int16_t*)av_malloc(audio_buf_size);
|
||||
void *video_buf = av_malloc(2 * handle->params.fb_width * handle->params.fb_height * handle->video.pix_size);
|
||||
|
||||
// Try pushing data in an interleaving pattern to ease the work of the muxer a bit.
|
||||
@ -592,10 +620,9 @@ bool ffemu_finalize(ffemu_t *handle)
|
||||
{
|
||||
fifo_read(handle->audio_fifo, audio_buf, audio_buf_size);
|
||||
|
||||
struct ffemu_audio_data aud = {
|
||||
.frames = 512,
|
||||
.data = audio_buf
|
||||
};
|
||||
struct ffemu_audio_data aud = {0};
|
||||
aud.frames = 512;
|
||||
aud.data = audio_buf;
|
||||
|
||||
ffemu_push_audio_thread(handle, &aud);
|
||||
did_work = true;
|
||||
@ -616,10 +643,9 @@ bool ffemu_finalize(ffemu_t *handle)
|
||||
// Flush out last audio.
|
||||
size_t avail = fifo_read_avail(handle->audio_fifo);
|
||||
fifo_read(handle->audio_fifo, audio_buf, avail);
|
||||
struct ffemu_audio_data aud = {
|
||||
.frames = avail / (sizeof(int16_t) * handle->params.channels),
|
||||
.data = audio_buf
|
||||
};
|
||||
struct ffemu_audio_data aud = {0};
|
||||
aud.frames = avail / (sizeof(int16_t) * handle->params.channels);
|
||||
aud.data = audio_buf;
|
||||
ffemu_push_audio_thread(handle, &aud);
|
||||
|
||||
deinit_thread_buf(handle);
|
||||
@ -658,14 +684,14 @@ bool ffemu_finalize(ffemu_t *handle)
|
||||
|
||||
static void ffemu_thread(void *data)
|
||||
{
|
||||
ffemu_t *ff = data;
|
||||
ffemu_t *ff = (ffemu_t*)data;
|
||||
|
||||
// For some reason, FFmpeg has a tendency to crash if we don't overallocate a bit. :s
|
||||
void *video_buf = av_malloc(2 * ff->params.fb_width * ff->params.fb_height * ff->video.pix_size);
|
||||
assert(video_buf);
|
||||
|
||||
size_t audio_buf_size = 512 * ff->params.channels * sizeof(int16_t);
|
||||
int16_t *audio_buf = av_malloc(audio_buf_size);
|
||||
int16_t *audio_buf = (int16_t*)av_malloc(audio_buf_size);
|
||||
assert(audio_buf);
|
||||
|
||||
while (ff->alive)
|
||||
@ -717,10 +743,9 @@ static void ffemu_thread(void *data)
|
||||
slock_unlock(ff->lock);
|
||||
scond_signal(ff->cond);
|
||||
|
||||
struct ffemu_audio_data aud = {
|
||||
.frames = 512,
|
||||
.data = audio_buf
|
||||
};
|
||||
struct ffemu_audio_data aud = {0};
|
||||
aud.frames = 512;
|
||||
aud.data = audio_buf;
|
||||
|
||||
ffemu_push_audio_thread(ff, &aud);
|
||||
}
|
||||
|
@ -1,3 +1,20 @@
|
||||
/* SSNES - A Super Nintendo Entertainment System (SNES) Emulator frontend for libsnes.
|
||||
* Copyright (C) 2010-2011 - Hans-Kristian Arntzen
|
||||
*
|
||||
* Some code herein may be based on code found in BSNES.
|
||||
*
|
||||
* SSNES 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 Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* SSNES 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 SSNES.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FFEMU_H
|
||||
#define __FFEMU_H
|
||||
|
||||
|
20
rewind.c
20
rewind.c
@ -18,7 +18,7 @@
|
||||
#include "rewind.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "boolean.h"
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
@ -68,7 +68,7 @@ state_manager_t *state_manager_new(size_t state_size, size_t buffer_size, void *
|
||||
if (buffer_size <= state_size * 4) // Need a sufficient buffer size.
|
||||
return NULL;
|
||||
|
||||
state_manager_t *state = calloc(1, sizeof(*state));
|
||||
state_manager_t *state = (state_manager_t*)calloc(1, sizeof(*state));
|
||||
if (!state)
|
||||
return NULL;
|
||||
|
||||
@ -81,9 +81,9 @@ state_manager_t *state_manager_new(size_t state_size, size_t buffer_size, void *
|
||||
state->buf_size_mask = state->buf_size - 1;
|
||||
SSNES_LOG("Readjusted rewind buffer size to %u MiB\n", (unsigned)(sizeof(uint64_t) * (state->buf_size >> 20)));
|
||||
|
||||
if (!(state->buffer = calloc(1, state->buf_size * sizeof(uint64_t))))
|
||||
if (!(state->buffer = (uint64_t*)calloc(1, state->buf_size * sizeof(uint64_t))))
|
||||
goto error;
|
||||
if (!(state->tmp_state = calloc(1, state->state_size * sizeof(uint32_t))))
|
||||
if (!(state->tmp_state = (uint32_t*)calloc(1, state->state_size * sizeof(uint32_t))))
|
||||
goto error;
|
||||
|
||||
memcpy(state->tmp_state, init_buffer, state_size);
|
||||
@ -128,8 +128,8 @@ bool state_manager_pop(state_manager_t *state, void **data)
|
||||
{
|
||||
// Apply the xor patch.
|
||||
uint32_t addr = state->buffer[state->top_ptr] >> 32;
|
||||
uint32_t xor = state->buffer[state->top_ptr] & 0xFFFFFFFFU;
|
||||
state->tmp_state[addr] ^= xor;
|
||||
uint32_t xor_ = state->buffer[state->top_ptr] & 0xFFFFFFFFU;
|
||||
state->tmp_state[addr] ^= xor_;
|
||||
|
||||
state->top_ptr = (state->top_ptr - 1) & state->buf_size_mask;
|
||||
}
|
||||
@ -154,7 +154,7 @@ static void generate_delta(state_manager_t *state, const void *data)
|
||||
{
|
||||
bool crossed = false;
|
||||
const uint32_t *old_state = state->tmp_state;
|
||||
const uint32_t *new_state = data;
|
||||
const uint32_t *new_state = (const uint32_t*)data;
|
||||
|
||||
state->buffer[state->top_ptr++] = 0; // For each separate delta, we have a 0 value sentinel in between.
|
||||
state->top_ptr &= state->buf_size_mask;
|
||||
@ -165,15 +165,15 @@ static void generate_delta(state_manager_t *state, const void *data)
|
||||
|
||||
for (uint64_t i = 0; i < state->state_size; i++)
|
||||
{
|
||||
uint64_t xor = old_state[i] ^ new_state[i];
|
||||
uint64_t xor_ = old_state[i] ^ new_state[i];
|
||||
|
||||
// If the data differs (xor != 0), we push that xor on the stack with index and xor.
|
||||
// This can be reversed by reapplying the xor.
|
||||
// This, if states don't really differ much, we'll save lots of space :)
|
||||
// Hopefully this will work really well with save states.
|
||||
if (xor)
|
||||
if (xor_)
|
||||
{
|
||||
state->buffer[state->top_ptr] = (i << 32) | xor;
|
||||
state->buffer[state->top_ptr] = (i << 32) | xor_;
|
||||
state->top_ptr = (state->top_ptr + 1) & state->buf_size_mask;
|
||||
|
||||
if (state->top_ptr == state->bottom_ptr)
|
||||
|
2
rewind.h
2
rewind.h
@ -19,7 +19,7 @@
|
||||
#define __SSNES_REWIND_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include "boolean.h"
|
||||
|
||||
typedef struct state_manager state_manager_t;
|
||||
|
||||
|
17
screenshot.c
17
screenshot.c
@ -19,7 +19,7 @@
|
||||
#include "strl.h"
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <stdbool.h>
|
||||
#include "boolean.h"
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "general.h"
|
||||
@ -35,16 +35,16 @@ static void write_header(FILE *file, unsigned width, unsigned height)
|
||||
// Generic BMP stuff.
|
||||
const uint8_t header[] = {
|
||||
'B', 'M',
|
||||
(size >> 0) & 0xff, (size >> 8) & 0xff, (size >> 16) & 0xff, (size >> 24) & 0xff,
|
||||
(uint8_t)(size >> 0), (uint8_t)(size >> 8), (uint8_t)(size >> 16), (uint8_t)(size >> 24),
|
||||
0, 0, 0, 0,
|
||||
54, 0, 0, 0,
|
||||
40, 0, 0, 0,
|
||||
(width >> 0) & 0xff, (width >> 8) & 0xff, (width >> 16) & 0xff, (width >> 24) & 0xff,
|
||||
(height >> 0) & 0xff, (height >> 8) & 0xff, (height >> 16) & 0xff, (height >> 24) & 0xff,
|
||||
(uint8_t)(width >> 0), (uint8_t)(width >> 8), (uint8_t)(width >> 16), (uint8_t)(width >> 24),
|
||||
(uint8_t)(height >> 0), (uint8_t)(height >> 8), (uint8_t)(height >> 16), (uint8_t)(height >> 24),
|
||||
1, 0,
|
||||
24, 0,
|
||||
0, 0, 0, 0,
|
||||
(size_array >> 0) & 0xff, (size_array >> 8) & 0xff, (size_array >> 16) & 0xff, (size_array >> 24) & 0xff,
|
||||
(uint8_t)(size_array >> 0), (uint8_t)(size_array >> 8), (uint8_t)(size_array >> 16), (uint8_t)(size_array >> 24),
|
||||
19, 11, 0, 0,
|
||||
19, 11, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
@ -58,8 +58,9 @@ static void dump_content(FILE *file, const uint16_t *frame, unsigned width, unsi
|
||||
{
|
||||
pitch >>= 1;
|
||||
unsigned line_size = (width * 3 + 3) & ~3;
|
||||
uint8_t line[line_size];
|
||||
memset(line, 0, sizeof(line));
|
||||
uint8_t *line = (uint8_t*)calloc(1, line_size);
|
||||
if (!line)
|
||||
return;
|
||||
|
||||
// BMP likes reverse ordering for some reason :v
|
||||
for (int j = height - 1; j >= 0; j--)
|
||||
@ -79,6 +80,8 @@ static void dump_content(FILE *file, const uint16_t *frame, unsigned width, unsi
|
||||
|
||||
fwrite(line, 1, sizeof(line), file);
|
||||
}
|
||||
|
||||
free(line);
|
||||
}
|
||||
|
||||
bool screenshot_dump(const char *folder, const uint16_t *frame,
|
||||
|
@ -19,7 +19,7 @@
|
||||
#define __SSNES_SCREENSHOT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "boolean.h"
|
||||
|
||||
bool screenshot_dump(const char *folder, const uint16_t *frame,
|
||||
unsigned width, unsigned height, unsigned pitch);
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "strl.h"
|
||||
#include "config.def.h"
|
||||
#include "file.h"
|
||||
#include "posix_string.h"
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
@ -635,7 +636,7 @@ static struct snes_keybind *find_snes_bind(unsigned port, int id)
|
||||
|
||||
static int find_sk_bind(const char *str)
|
||||
{
|
||||
for (int i = 0; i < sizeof(sk_map) / sizeof(struct key_map); i++)
|
||||
for (size_t i = 0; i < sizeof(sk_map) / sizeof(struct key_map); i++)
|
||||
{
|
||||
if (strcasecmp(sk_map[i].str, str) == 0)
|
||||
return sk_map[i].key;
|
||||
@ -673,7 +674,7 @@ static void read_keybinds(config_file_t *conf)
|
||||
int key = find_sk_key(tmp_key);
|
||||
|
||||
if (key >= 0)
|
||||
bind->key = key;
|
||||
bind->key = (enum ssnes_key)key;
|
||||
|
||||
free(tmp_key);
|
||||
tmp_key = NULL;
|
||||
|
104
ssnes.c
104
ssnes.c
@ -15,7 +15,7 @@
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "boolean.h"
|
||||
#include "libsnes.hpp"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -168,13 +168,12 @@ static void video_frame(const uint16_t *data, unsigned width, unsigned height)
|
||||
#ifdef HAVE_FFMPEG
|
||||
if (g_extern.recording && (!g_extern.filter.active || !g_settings.video.post_filter_record || is_dupe))
|
||||
{
|
||||
struct ffemu_video_data ffemu_data = {
|
||||
.data = data,
|
||||
.pitch = lines_to_pitch(height),
|
||||
.width = width,
|
||||
.height = height,
|
||||
.is_dupe = is_dupe
|
||||
};
|
||||
struct ffemu_video_data ffemu_data = {0};
|
||||
ffemu_data.data = data;
|
||||
ffemu_data.pitch = lines_to_pitch(height);
|
||||
ffemu_data.width = width;
|
||||
ffemu_data.height = height;
|
||||
ffemu_data.is_dupe = is_dupe;
|
||||
ffemu_push_video(g_extern.rec, &ffemu_data);
|
||||
}
|
||||
#endif
|
||||
@ -196,12 +195,11 @@ static void video_frame(const uint16_t *data, unsigned width, unsigned height)
|
||||
#ifdef HAVE_FFMPEG
|
||||
if (g_extern.recording && g_settings.video.post_filter_record)
|
||||
{
|
||||
struct ffemu_video_data ffemu_data = {
|
||||
.data = g_extern.filter.buffer,
|
||||
.pitch = g_extern.filter.pitch,
|
||||
.width = owidth,
|
||||
.height = oheight,
|
||||
};
|
||||
struct ffemu_video_data ffemu_data = {0};
|
||||
ffemu_data.data = g_extern.filter.buffer;
|
||||
ffemu_data.pitch = g_extern.filter.pitch;
|
||||
ffemu_data.width = owidth;
|
||||
ffemu_data.height = oheight;
|
||||
ffemu_push_video(g_extern.rec, &ffemu_data);
|
||||
}
|
||||
#endif
|
||||
@ -251,10 +249,9 @@ static bool audio_flush(const int16_t *data, size_t samples)
|
||||
#ifdef HAVE_FFMPEG
|
||||
if (g_extern.recording)
|
||||
{
|
||||
struct ffemu_audio_data ffemu_data = {
|
||||
.data = data,
|
||||
.frames = samples / 2
|
||||
};
|
||||
struct ffemu_audio_data ffemu_data = {0};
|
||||
ffemu_data.data = data;
|
||||
ffemu_data.frames = samples / 2;
|
||||
ffemu_push_audio(g_extern.rec, &ffemu_data);
|
||||
}
|
||||
#endif
|
||||
@ -269,26 +266,23 @@ static bool audio_flush(const int16_t *data, size_t samples)
|
||||
|
||||
audio_convert_s16_to_float(g_extern.audio_data.data, data, samples);
|
||||
|
||||
ssnes_dsp_input_t dsp_input = {
|
||||
.samples = g_extern.audio_data.data,
|
||||
.frames = samples / 2
|
||||
};
|
||||
ssnes_dsp_input_t dsp_input = {0};
|
||||
dsp_input.samples = g_extern.audio_data.data;
|
||||
dsp_input.frames = samples / 2;
|
||||
|
||||
ssnes_dsp_output_t dsp_output = {
|
||||
.should_resample = SSNES_TRUE
|
||||
};
|
||||
ssnes_dsp_output_t dsp_output = {0};
|
||||
dsp_output.should_resample = SSNES_TRUE;
|
||||
|
||||
if (g_extern.audio_data.dsp_plugin)
|
||||
g_extern.audio_data.dsp_plugin->process(g_extern.audio_data.dsp_handle, &dsp_output, &dsp_input);
|
||||
|
||||
if (dsp_output.should_resample)
|
||||
{
|
||||
struct hermite_data src_data = {
|
||||
.data_in = dsp_output.samples ? dsp_output.samples : g_extern.audio_data.data,
|
||||
.data_out = g_extern.audio_data.outsamples,
|
||||
.input_frames = dsp_output.samples ? dsp_output.frames : (samples / 2),
|
||||
.ratio = g_extern.audio_data.src_ratio,
|
||||
};
|
||||
struct hermite_data src_data = {0};
|
||||
src_data.data_in = dsp_output.samples ? dsp_output.samples : g_extern.audio_data.data;
|
||||
src_data.data_out = g_extern.audio_data.outsamples;
|
||||
src_data.input_frames = dsp_output.samples ? dsp_output.frames : (samples / 2);
|
||||
src_data.ratio = g_extern.audio_data.src_ratio;
|
||||
|
||||
hermite_process(g_extern.audio_data.source, &src_data);
|
||||
|
||||
@ -305,7 +299,7 @@ static bool audio_flush(const int16_t *data, size_t samples)
|
||||
{
|
||||
float f[0x10000];
|
||||
int16_t i[0x10000 * sizeof(float) / sizeof(int16_t)];
|
||||
} static const empty_buf;
|
||||
} static const empty_buf = {{0}};
|
||||
|
||||
if (g_extern.audio_data.use_float)
|
||||
{
|
||||
@ -1009,22 +1003,19 @@ static void init_recording(void)
|
||||
{
|
||||
fps = g_extern.system.timing.fps;
|
||||
samplerate = g_extern.system.timing.sample_rate;
|
||||
SSNES_LOG("Custom timing given: FPS: %.4lf, Sample rate: %.4lf\n", fps, samplerate);
|
||||
SSNES_LOG("Custom timing given: FPS: %.4f, Sample rate: %.4f\n", (float)fps, (float)samplerate);
|
||||
}
|
||||
|
||||
struct ffemu_params params = {
|
||||
.out_width = g_extern.system.geom.base_width,
|
||||
.out_height = g_extern.system.geom.base_height,
|
||||
.fb_width = g_extern.system.geom.max_width,
|
||||
.fb_height = g_extern.system.geom.max_height,
|
||||
.channels = 2,
|
||||
.filename = g_extern.record_path,
|
||||
|
||||
.fps = fps,
|
||||
.samplerate = samplerate,
|
||||
|
||||
.rgb32 = false,
|
||||
};
|
||||
struct ffemu_params params = {0};
|
||||
params.out_width = g_extern.system.geom.base_width;
|
||||
params.out_height = g_extern.system.geom.base_height;
|
||||
params.fb_width = g_extern.system.geom.max_width;
|
||||
params.fb_height = g_extern.system.geom.max_height;
|
||||
params.channels = 2;
|
||||
params.filename = g_extern.record_path;
|
||||
params.fps = fps;
|
||||
params.samplerate = samplerate;
|
||||
params.rgb32 = false;
|
||||
|
||||
if (g_extern.record_width || g_extern.record_height)
|
||||
{
|
||||
@ -1105,7 +1096,7 @@ static void init_rewind(void)
|
||||
{
|
||||
size_t serial_size = psnes_serialize_size();
|
||||
g_extern.state_buf = calloc(1, (serial_size + 3) & ~3); // Make sure we allocate at least 4-byte multiple.
|
||||
psnes_serialize(g_extern.state_buf, serial_size);
|
||||
psnes_serialize((uint8_t*)g_extern.state_buf, serial_size);
|
||||
SSNES_LOG("Initing rewind buffer with size: %u MB\n", (unsigned)(g_settings.rewind_buffer_size / 1000000));
|
||||
g_extern.state_manager = state_manager_new((serial_size + 3) & ~3, g_settings.rewind_buffer_size, g_extern.state_buf);
|
||||
if (!g_extern.state_manager)
|
||||
@ -1172,11 +1163,10 @@ static void init_netplay(void)
|
||||
if (!g_extern.netplay_enable)
|
||||
return;
|
||||
|
||||
struct snes_callbacks cbs = {
|
||||
.frame_cb = video_frame,
|
||||
.sample_cb = audio_sample,
|
||||
.state_cb = input_state
|
||||
};
|
||||
struct snes_callbacks cbs = {0};
|
||||
cbs.frame_cb = video_frame;
|
||||
cbs.sample_cb = audio_sample;
|
||||
cbs.state_cb = input_state;
|
||||
|
||||
if (*g_extern.netplay_server)
|
||||
{
|
||||
@ -1574,7 +1564,7 @@ static void check_rewind(void)
|
||||
setup_rewind_audio();
|
||||
|
||||
msg_queue_push(g_extern.msg_queue, "Rewinding!", 0, g_extern.is_paused ? 1 : 30);
|
||||
psnes_unserialize(buf, psnes_serialize_size());
|
||||
psnes_unserialize((uint8_t*)buf, psnes_serialize_size());
|
||||
|
||||
if (g_extern.bsv.movie)
|
||||
bsv_movie_frame_rewind(g_extern.bsv.movie);
|
||||
@ -1588,7 +1578,7 @@ static void check_rewind(void)
|
||||
cnt = (cnt + 1) % (g_settings.rewind_granularity ? g_settings.rewind_granularity : 1); // Avoid possible SIGFPE.
|
||||
if (cnt == 0 || g_extern.bsv.movie)
|
||||
{
|
||||
psnes_serialize(g_extern.state_buf, psnes_serialize_size());
|
||||
psnes_serialize((uint8_t*)g_extern.state_buf, psnes_serialize_size());
|
||||
state_manager_push(g_extern.state_manager, g_extern.state_buf);
|
||||
}
|
||||
}
|
||||
@ -1958,6 +1948,8 @@ int main(int argc, char *argv[])
|
||||
fill_pathnames();
|
||||
set_savestate_auto_index();
|
||||
|
||||
bool use_sram = true;
|
||||
|
||||
if (!init_rom_file(g_extern.game_type))
|
||||
goto error;
|
||||
|
||||
@ -2001,9 +1993,9 @@ int main(int argc, char *argv[])
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETPLAY
|
||||
bool use_sram = !g_extern.sram_save_disable && !g_extern.netplay_is_client;
|
||||
use_sram = !g_extern.sram_save_disable && !g_extern.netplay_is_client;
|
||||
#else
|
||||
bool use_sram = !g_extern.sram_save_disable;
|
||||
use_sram = !g_extern.sram_save_disable;
|
||||
#endif
|
||||
|
||||
if (!use_sram)
|
||||
|
4
strl.h
4
strl.h
@ -27,8 +27,8 @@
|
||||
|
||||
#ifndef HAVE_STRL
|
||||
// Avoid possible naming collitions during link since we prefer to use the actual name.
|
||||
#define strlcpy(dst, src, size) __strlcpy_ssnes(dst, src, size)
|
||||
#define strlcat(dst, src, size) __strlcat_ssnes(dst, src, size)
|
||||
#define strlcpy(dst, src, size) strlcpy_ssnes__(dst, src, size)
|
||||
#define strlcat(dst, src, size) strlcat_ssnes__(dst, src, size)
|
||||
|
||||
size_t strlcpy(char *dest, const char *source, size_t size);
|
||||
size_t strlcat(char *dest, const char *source, size_t size);
|
||||
|
20
thread.c
20
thread.c
@ -46,7 +46,7 @@ struct sthread
|
||||
|
||||
static DWORD CALLBACK thread_wrap(void *data_)
|
||||
{
|
||||
struct thread_data *data = data_;
|
||||
struct thread_data *data = (struct thread_data*)data_;
|
||||
data->func(data->userdata);
|
||||
free(data);
|
||||
return 0;
|
||||
@ -54,11 +54,11 @@ static DWORD CALLBACK thread_wrap(void *data_)
|
||||
|
||||
sthread_t *sthread_create(void (*thread_func)(void*), void *userdata)
|
||||
{
|
||||
sthread_t *thread = calloc(1, sizeof(*thread));
|
||||
sthread_t *thread = (sthread_t*)calloc(1, sizeof(*thread));
|
||||
if (!thread)
|
||||
return NULL;
|
||||
|
||||
struct thread_data *data = calloc(1, sizeof(*data));
|
||||
struct thread_data *data = (struct thread_data*)calloc(1, sizeof(*data));
|
||||
if (!data)
|
||||
{
|
||||
free(thread);
|
||||
@ -93,7 +93,7 @@ struct slock
|
||||
|
||||
slock_t *slock_new(void)
|
||||
{
|
||||
slock_t *lock = calloc(1, sizeof(*lock));
|
||||
slock_t *lock = (slock_t*)calloc(1, sizeof(*lock));
|
||||
if (!lock)
|
||||
return NULL;
|
||||
|
||||
@ -124,7 +124,7 @@ struct scond
|
||||
|
||||
scond_t *scond_new(void)
|
||||
{
|
||||
scond_t *cond = calloc(1, sizeof(*cond));
|
||||
scond_t *cond = (scond_t*)calloc(1, sizeof(*cond));
|
||||
if (!cond)
|
||||
return NULL;
|
||||
|
||||
@ -179,7 +179,7 @@ struct sthread
|
||||
|
||||
static void *thread_wrap(void *data_)
|
||||
{
|
||||
struct thread_data *data = data_;
|
||||
struct thread_data *data = (struct thread_data*)data_;
|
||||
data->func(data->userdata);
|
||||
free(data);
|
||||
pthread_exit(NULL);
|
||||
@ -187,11 +187,11 @@ static void *thread_wrap(void *data_)
|
||||
|
||||
sthread_t *sthread_create(void (*thread_func)(void*), void *userdata)
|
||||
{
|
||||
sthread_t *thr = calloc(1, sizeof(*thr));
|
||||
sthread_t *thr = (sthread_t*)calloc(1, sizeof(*thr));
|
||||
if (!thr)
|
||||
return NULL;
|
||||
|
||||
struct thread_data *data = calloc(1, sizeof(*data));
|
||||
struct thread_data *data = (struct thread_data*)calloc(1, sizeof(*data));
|
||||
if (!data)
|
||||
{
|
||||
free(thr);
|
||||
@ -224,7 +224,7 @@ struct slock
|
||||
|
||||
slock_t *slock_new(void)
|
||||
{
|
||||
slock_t *lock = calloc(1, sizeof(*lock));
|
||||
slock_t *lock = (slock_t*)calloc(1, sizeof(*lock));
|
||||
if (!lock)
|
||||
return NULL;
|
||||
|
||||
@ -260,7 +260,7 @@ struct scond
|
||||
|
||||
scond_t *scond_new(void)
|
||||
{
|
||||
scond_t *cond = calloc(1, sizeof(*cond));
|
||||
scond_t *cond = (scond_t*)calloc(1, sizeof(*cond));
|
||||
if (!cond)
|
||||
return NULL;
|
||||
|
||||
|
2
thread.h
2
thread.h
@ -18,7 +18,7 @@
|
||||
#ifndef THREAD_H__
|
||||
#define THREAD_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "boolean.h"
|
||||
|
||||
// Implements the bare minimum needed for SSNES. :)
|
||||
|
||||
|
@ -27,9 +27,10 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
#include <stdbool.h>
|
||||
#include "../boolean.h"
|
||||
#include "general.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include "../posix_string.h"
|
||||
|
||||
static int g_player = 1;
|
||||
static int g_joypad = 0;
|
||||
@ -55,9 +56,9 @@ static void print_help(void)
|
||||
|
||||
struct bind
|
||||
{
|
||||
char *keystr;
|
||||
char *confbtn[MAX_PLAYERS];
|
||||
char *confaxis[MAX_PLAYERS];
|
||||
const char *keystr;
|
||||
const char *confbtn[MAX_PLAYERS];
|
||||
const char *confaxis[MAX_PLAYERS];
|
||||
bool is_misc;
|
||||
};
|
||||
|
||||
@ -129,7 +130,8 @@ static void get_binds(config_file_t *conf, int player, int joypad)
|
||||
int last_axis = 0xFF;
|
||||
int last_pos = 0;
|
||||
int num_axes = SDL_JoystickNumAxes(joystick);
|
||||
int initial_axes[num_axes];
|
||||
int *initial_axes = (int*)calloc(num_axes, sizeof(int));
|
||||
assert(initial_axes);
|
||||
|
||||
SDL_PumpEvents();
|
||||
SDL_JoystickUpdate();
|
||||
@ -218,6 +220,8 @@ static void get_binds(config_file_t *conf, int player, int joypad)
|
||||
}
|
||||
}
|
||||
|
||||
free(initial_axes);
|
||||
|
||||
end:
|
||||
SDL_JoystickClose(joystick);
|
||||
SDL_Quit();
|
||||
|
21
ups.c
21
ups.c
@ -80,17 +80,16 @@ ups_error_t ups_apply_patch(
|
||||
const uint8_t *sourcedata, size_t sourcelength,
|
||||
uint8_t *targetdata, size_t *targetlength)
|
||||
{
|
||||
struct ups_data data = {
|
||||
.patch_data = patchdata,
|
||||
.source_data = sourcedata,
|
||||
.target_data = targetdata,
|
||||
.patch_length = patchlength,
|
||||
.source_length = sourcelength,
|
||||
.target_length = *targetlength,
|
||||
.patch_checksum = ~0,
|
||||
.source_checksum = ~0,
|
||||
.target_checksum = ~0
|
||||
};
|
||||
struct ups_data data = {0};
|
||||
data.patch_data = patchdata;
|
||||
data.source_data = sourcedata;
|
||||
data.target_data = targetdata;
|
||||
data.patch_length = patchlength;
|
||||
data.source_length = sourcelength;
|
||||
data.target_length = *targetlength;
|
||||
data.patch_checksum = ~0;
|
||||
data.source_checksum = ~0;
|
||||
data.target_checksum = ~0;
|
||||
|
||||
if (data.patch_length < 18)
|
||||
return UPS_PATCH_INVALID;
|
||||
|
Loading…
x
Reference in New Issue
Block a user