Adopt the sox resampler instead of RetroArch
Removing RetroArch code from my project. Signed-off-by: Christopher Snowhill <kode54@gmail.com>CQTexperiment
parent
78e960a9e4
commit
d4990de7f3
|
@ -487,8 +487,6 @@ void* kAppControllerContext = &kAppControllerContext;
|
|||
|
||||
[userDefaultsValuesDict setObject:@"cubic" forKey:@"resampling"];
|
||||
|
||||
[userDefaultsValuesDict setObject:@"normal" forKey:@"outputResampling"];
|
||||
|
||||
[userDefaultsValuesDict setObject:[NSNumber numberWithInteger:CogStatusStopped] forKey:@"lastPlaybackStatus"];
|
||||
[userDefaultsValuesDict setObject:[NSNumber numberWithInteger:-1] forKey:@"lastTrackPlaying"];
|
||||
[userDefaultsValuesDict setObject:[NSNumber numberWithDouble:0] forKey:@"lastTrackPosition"];
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#import <AudioToolbox/AudioToolbox.h>
|
||||
#import <AudioUnit/AudioUnit.h>
|
||||
|
||||
#import <audio/audio_resampler.h>
|
||||
#import <soxr.h>
|
||||
|
||||
#import "Node.h"
|
||||
#import "RefillNode.h"
|
||||
|
@ -22,8 +22,7 @@
|
|||
@interface ConverterNode : Node {
|
||||
NSDictionary * rgInfo;
|
||||
|
||||
void *resampler_data;
|
||||
const retro_resampler_t *resampler;
|
||||
soxr_t soxr;
|
||||
|
||||
void *inputBuffer;
|
||||
size_t inputBufferSize;
|
||||
|
@ -74,8 +73,6 @@
|
|||
RefillNode *refillNode;
|
||||
id __weak originalPreviousNode;
|
||||
|
||||
NSString *outputResampling;
|
||||
|
||||
void *hdcd_decoder;
|
||||
|
||||
HeadphoneFilter *hFilter;
|
||||
|
|
|
@ -13,9 +13,6 @@
|
|||
|
||||
#import "Logging.h"
|
||||
|
||||
#import <audio/conversion/s16_to_float.h>
|
||||
#import <audio/conversion/s32_to_float.h>
|
||||
|
||||
#import "lpc.h"
|
||||
#import "util.h"
|
||||
|
||||
|
@ -57,9 +54,8 @@ void PrintStreamDesc (AudioStreamBasicDescription *inDesc)
|
|||
if (self)
|
||||
{
|
||||
rgInfo = nil;
|
||||
|
||||
resampler = NULL;
|
||||
resampler_data = NULL;
|
||||
|
||||
soxr = 0;
|
||||
inputBuffer = NULL;
|
||||
inputBufferSize = 0;
|
||||
floatBuffer = NULL;
|
||||
|
@ -81,12 +77,9 @@ void PrintStreamDesc (AudioStreamBasicDescription *inDesc)
|
|||
dsd2pcm = NULL;
|
||||
dsd2pcmCount = 0;
|
||||
|
||||
outputResampling = @"";
|
||||
|
||||
hdcd_decoder = NULL;
|
||||
|
||||
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.volumeScaling" options:0 context:nil];
|
||||
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.outputResampling" options:0 context:nil];
|
||||
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.headphoneVirtualization" options:0 context:nil];
|
||||
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.hrirPath" options:0 context:nil];
|
||||
}
|
||||
|
@ -274,43 +267,7 @@ void scale_by_volume(float * buffer, size_t count, float volume)
|
|||
{
|
||||
if ( volume != 1.0 )
|
||||
{
|
||||
#if TARGET_CPU_X86 || TARGET_CPU_X86_64
|
||||
if ( count >= 8 )
|
||||
{
|
||||
__m128 vgf = _mm_set1_ps(volume);
|
||||
while ( count >= 8 )
|
||||
{
|
||||
__m128 input = _mm_loadu_ps(buffer);
|
||||
__m128 input2 = _mm_loadu_ps(buffer + 4);
|
||||
__m128 output = _mm_mul_ps(input, vgf);
|
||||
__m128 output2 = _mm_mul_ps(input2, vgf);
|
||||
|
||||
_mm_storeu_ps(buffer + 0, output);
|
||||
_mm_storeu_ps(buffer + 4, output2);
|
||||
|
||||
buffer += 8;
|
||||
count -= 8;
|
||||
}
|
||||
}
|
||||
#elif TARGET_CPU_ARM || TARGET_CPU_ARM64
|
||||
if ( count >= 8 )
|
||||
{
|
||||
float32x4_t vgf = vdupq_n_f32(volume);
|
||||
while ( count >= 8 )
|
||||
{
|
||||
float32x4x2_t oreg;
|
||||
float32x4x2_t inreg = vld1q_f32_x2(buffer);
|
||||
oreg.val[0] = vmulq_f32(inreg.val[0], vgf);
|
||||
oreg.val[1] = vmulq_f32(inreg.val[1], vgf);
|
||||
vst1q_f32_x2(buffer, oreg);
|
||||
buffer += 8;
|
||||
count -= 8;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
buffer[i] *= volume;
|
||||
vDSP_vsmul(buffer, 1, &volume, buffer, 1, count);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -514,7 +471,7 @@ static int dsd2pcm_latency(void * _state)
|
|||
else return 0;
|
||||
}
|
||||
|
||||
static void dsd2pcm_process(void * _state, uint8_t * src, size_t sofs, size_t sinc, float * dest, size_t dofs, size_t dinc, size_t len)
|
||||
static void dsd2pcm_process(void * _state, const uint8_t * src, size_t sofs, size_t sinc, float * dest, size_t dofs, size_t dinc, size_t len)
|
||||
{
|
||||
struct dsd2pcm_state * state = (struct dsd2pcm_state *) _state;
|
||||
int bite1, bite2, temp;
|
||||
|
@ -877,7 +834,8 @@ tryagain:
|
|||
samplesRead = bytesReadFromInput / 2;
|
||||
if (isUnsigned)
|
||||
convert_u16_to_s16(inputBuffer, samplesRead);
|
||||
convert_s16_to_float(inputBuffer + bytesReadFromInput, inputBuffer, samplesRead, 1.0);
|
||||
vDSP_vflt16((const short *)inputBuffer, 1, (float *)(inputBuffer + bytesReadFromInput), 1, samplesRead);
|
||||
scale_by_volume((float *)(inputBuffer + bytesReadFromInput), samplesRead, (float)(1.0 / (1ULL << 15)));
|
||||
memmove(inputBuffer, inputBuffer + bytesReadFromInput, samplesRead * sizeof(float));
|
||||
bitsPerSample = 32;
|
||||
bytesReadFromInput = samplesRead * sizeof(float);
|
||||
|
@ -899,7 +857,8 @@ tryagain:
|
|||
samplesRead = bytesReadFromInput / 4;
|
||||
if (isUnsigned)
|
||||
convert_u32_to_s32(inputBuffer, samplesRead);
|
||||
convert_s32_to_float(inputBuffer + bytesReadFromInput, inputBuffer, samplesRead, gain);
|
||||
vDSP_vflt32((const int *)inputBuffer, 1, (float *)(inputBuffer + bytesReadFromInput), 1, samplesRead);
|
||||
scale_by_volume((float *)(inputBuffer + bytesReadFromInput), samplesRead, gain * (1.0 / (1ULL << 31)));
|
||||
memmove(inputBuffer, inputBuffer + bytesReadFromInput, samplesRead * sizeof(float));
|
||||
bitsPerSample = 32;
|
||||
bytesReadFromInput = samplesRead * sizeof(float);
|
||||
|
@ -922,13 +881,9 @@ tryagain:
|
|||
|
||||
memmove(inputBuffer + N_samples_to_add_ * floatFormat.mBytesPerPacket, inputBuffer, bytesReadFromInput);
|
||||
|
||||
// Great padding! And we want to eat more, based on the resampler filter size
|
||||
int samplesLatency = (int)ceil(resampler->latency(resampler_data) * sampleRatio);
|
||||
|
||||
// Guess what? This extrapolates into the memory before its input pointer!
|
||||
lpc_extrapolate_bkwd(inputBuffer + N_samples_to_add_ * floatFormat.mBytesPerPacket, samples_in_buffer, prime, floatFormat.mChannelsPerFrame, LPC_ORDER, N_samples_to_add_, &extrapolateBuffer, &extrapolateBufferSize);
|
||||
bytesReadFromInput += N_samples_to_add_ * floatFormat.mBytesPerPacket;
|
||||
latencyEaten = N_samples_to_drop_ + samplesLatency;
|
||||
latencyEaten = N_samples_to_drop_;
|
||||
if (dsd2pcm) latencyEaten += dsdLatencyEaten;
|
||||
is_preextrapolated_ = 2;
|
||||
}
|
||||
|
@ -949,7 +904,7 @@ tryagain:
|
|||
}
|
||||
|
||||
// And now that we've reached the end, we eat slightly less, due to the filter size
|
||||
int samplesLatency = (int)resampler->latency(resampler_data);
|
||||
int samplesLatency = 0;
|
||||
if (dsd2pcm) samplesLatency += dsd2pcmLatency;
|
||||
samplesLatency = (int)ceil(samplesLatency * sampleRatio);
|
||||
|
||||
|
@ -975,8 +930,6 @@ tryagain:
|
|||
|
||||
if (inpOffset != inpSize && floatOffset == floatSize)
|
||||
{
|
||||
struct resampler_data src_data;
|
||||
|
||||
size_t inputSamples = (inpSize - inpOffset) / floatFormat.mBytesPerPacket;
|
||||
|
||||
ioNumberPackets = (UInt32)inputSamples;
|
||||
|
@ -996,54 +949,50 @@ tryagain:
|
|||
return 0;
|
||||
}
|
||||
|
||||
src_data.data_out = floatBuffer;
|
||||
src_data.output_frames = 0;
|
||||
|
||||
src_data.data_in = (float*)(((uint8_t*)inputBuffer) + inpOffset);
|
||||
src_data.input_frames = inputSamples;
|
||||
|
||||
src_data.ratio = sampleRatio;
|
||||
size_t inputDone = 0;
|
||||
size_t outputDone = 0;
|
||||
|
||||
if (!skipResampler)
|
||||
{
|
||||
resampler->process(resampler_data, &src_data);
|
||||
soxr_process(soxr, (float *)(((uint8_t*)inputBuffer) + inpOffset), inputSamples, &inputDone, floatBuffer, ioNumberPackets, &outputDone);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(src_data.data_out, src_data.data_in, inputSamples * floatFormat.mBytesPerPacket);
|
||||
src_data.output_frames = inputSamples;
|
||||
memcpy(floatBuffer, (((uint8_t*)inputBuffer) + inpOffset), inputSamples * floatFormat.mBytesPerPacket);
|
||||
inputDone = inputSamples;
|
||||
outputDone = inputSamples;
|
||||
}
|
||||
|
||||
inpOffset += inputSamples * floatFormat.mBytesPerPacket;
|
||||
inpOffset += inputDone * floatFormat.mBytesPerPacket;
|
||||
|
||||
if (latencyEaten)
|
||||
{
|
||||
if (src_data.output_frames > latencyEaten)
|
||||
if (outputDone > latencyEaten)
|
||||
{
|
||||
src_data.output_frames -= latencyEaten;
|
||||
memmove(src_data.data_out, src_data.data_out + latencyEaten * inputFormat.mChannelsPerFrame, src_data.output_frames * floatFormat.mBytesPerPacket);
|
||||
outputDone -= latencyEaten;
|
||||
memmove(floatBuffer, floatBuffer + latencyEaten * floatFormat.mBytesPerPacket, outputDone * floatFormat.mBytesPerPacket);
|
||||
latencyEaten = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
latencyEaten -= src_data.output_frames;
|
||||
src_data.output_frames = 0;
|
||||
latencyEaten -= outputDone;
|
||||
outputDone = 0;
|
||||
}
|
||||
}
|
||||
else if (latencyEatenPost)
|
||||
{
|
||||
if (src_data.output_frames > latencyEatenPost)
|
||||
if (outputDone > latencyEatenPost)
|
||||
{
|
||||
src_data.output_frames -= latencyEatenPost;
|
||||
outputDone -= latencyEatenPost;
|
||||
}
|
||||
else
|
||||
{
|
||||
src_data.output_frames = 0;
|
||||
outputDone = 0;
|
||||
}
|
||||
latencyEatenPost = 0;
|
||||
}
|
||||
|
||||
amountReadFromFC = (int)(src_data.output_frames * floatFormat.mBytesPerPacket);
|
||||
amountReadFromFC = (int)(outputDone * floatFormat.mBytesPerPacket);
|
||||
|
||||
scale_by_volume( (float*) floatBuffer, amountReadFromFC / sizeof(float), volumeScale);
|
||||
|
||||
|
@ -1102,14 +1051,6 @@ tryagain:
|
|||
//User reset the volume scaling option
|
||||
[self refreshVolumeScaling];
|
||||
}
|
||||
else if ([keyPath isEqualToString:@"values.outputResampling"]) {
|
||||
// Reset resampler
|
||||
if (resampler && resampler_data) {
|
||||
NSString *value = [[NSUserDefaults standardUserDefaults] stringForKey:@"outputResampling"];
|
||||
if (![value isEqualToString:outputResampling])
|
||||
[self inputFormatDidChange:inputFormat];
|
||||
}
|
||||
}
|
||||
else if ([keyPath isEqualToString:@"values.headphoneVirtualization"] ||
|
||||
[keyPath isEqualToString:@"values.hrirPath"]) {
|
||||
// Reset the converter, without rebuffering
|
||||
|
@ -1254,35 +1195,22 @@ static float db_to_scale(float db)
|
|||
}
|
||||
}
|
||||
|
||||
convert_s16_to_float_init_simd();
|
||||
convert_s32_to_float_init_simd();
|
||||
|
||||
skipResampler = outputFormat.mSampleRate == floatFormat.mSampleRate;
|
||||
|
||||
sampleRatio = (double)outputFormat.mSampleRate / (double)floatFormat.mSampleRate;
|
||||
|
||||
if (!skipResampler)
|
||||
{
|
||||
enum resampler_quality quality = RESAMPLER_QUALITY_DONTCARE;
|
||||
soxr_quality_spec_t q_spec = soxr_quality_spec(SOXR_HQ, 0);
|
||||
soxr_io_spec_t io_spec = soxr_io_spec(SOXR_FLOAT32_I, SOXR_FLOAT32_I);
|
||||
soxr_runtime_spec_t runtime_spec = soxr_runtime_spec(0);
|
||||
|
||||
NSString * resampling = [[NSUserDefaults standardUserDefaults] stringForKey:@"outputResampling"];
|
||||
if ([resampling isEqualToString:@"lowest"])
|
||||
quality = RESAMPLER_QUALITY_LOWEST;
|
||||
else if ([resampling isEqualToString:@"lower"])
|
||||
quality = RESAMPLER_QUALITY_LOWER;
|
||||
else if ([resampling isEqualToString:@"normal"])
|
||||
quality = RESAMPLER_QUALITY_NORMAL;
|
||||
else if ([resampling isEqualToString:@"higher"])
|
||||
quality = RESAMPLER_QUALITY_HIGHER;
|
||||
else if ([resampling isEqualToString:@"highest"])
|
||||
quality = RESAMPLER_QUALITY_HIGHEST;
|
||||
soxr_error_t error;
|
||||
|
||||
outputResampling = resampling;
|
||||
soxr = soxr_create(floatFormat.mSampleRate, outputFormat.mSampleRate, floatFormat.mChannelsPerFrame, &error, &io_spec, &q_spec, &runtime_spec);
|
||||
|
||||
if (!retro_resampler_realloc(&resampler_data, &resampler, "sinc", quality, inputFormat.mChannelsPerFrame, sampleRatio))
|
||||
{
|
||||
if (error)
|
||||
return NO;
|
||||
}
|
||||
|
||||
PRIME_LEN_ = max(floatFormat.mSampleRate/20, 1024u);
|
||||
PRIME_LEN_ = min(PRIME_LEN_, 16384u);
|
||||
|
@ -1319,7 +1247,6 @@ static float db_to_scale(float db)
|
|||
DLog(@"Decoder dealloc");
|
||||
|
||||
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.volumeScaling"];
|
||||
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.outputResampling"];
|
||||
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.headphoneVirtualization"];
|
||||
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.hrirPath"];
|
||||
|
||||
|
@ -1394,11 +1321,10 @@ static float db_to_scale(float db)
|
|||
free(hdcd_decoder);
|
||||
hdcd_decoder = NULL;
|
||||
}
|
||||
if (resampler && resampler_data)
|
||||
if (soxr)
|
||||
{
|
||||
resampler->free(resampler, resampler_data);
|
||||
resampler = NULL;
|
||||
resampler_data = NULL;
|
||||
soxr_delete(soxr);
|
||||
soxr = NULL;
|
||||
}
|
||||
if (dsd2pcm && dsd2pcmCount)
|
||||
{
|
||||
|
|
|
@ -9,8 +9,11 @@
|
|||
#import "AudioSource.h"
|
||||
#import "AudioDecoder.h"
|
||||
|
||||
#import <audio/audio_resampler.h>
|
||||
#import <memalign.h>
|
||||
#import <soxr.h>
|
||||
#import <mm_malloc.h>
|
||||
|
||||
#import "lpc.h"
|
||||
#import "util.h"
|
||||
|
||||
@implementation HeadphoneFilter
|
||||
|
||||
|
@ -169,16 +172,30 @@ static const int8_t speakers_to_hesuvi_14[8][2][8] = {
|
|||
double sampleRatio = sampleRate / sampleRateOfSource;
|
||||
int resampledCount = (int)ceil((double)sampleCount * sampleRatio);
|
||||
|
||||
void *resampler_data = NULL;
|
||||
const retro_resampler_t *resampler = NULL;
|
||||
|
||||
if (!retro_resampler_realloc(&resampler_data, &resampler, "sinc", RESAMPLER_QUALITY_NORMAL, impulseChannels, sampleRatio)) {
|
||||
soxr_quality_spec_t q_spec = soxr_quality_spec(SOXR_HQ, 0);
|
||||
soxr_io_spec_t io_spec = soxr_io_spec(SOXR_FLOAT32_I, SOXR_FLOAT32_I);
|
||||
soxr_runtime_spec_t runtime_spec = soxr_runtime_spec(0);
|
||||
|
||||
soxr_error_t error;
|
||||
|
||||
soxr_t soxr = soxr_create(sampleRateOfSource, sampleRate, impulseChannels, &error, &io_spec, &q_spec, &runtime_spec);
|
||||
|
||||
if (error) {
|
||||
free(impulseBuffer);
|
||||
return nil;
|
||||
}
|
||||
|
||||
int resamplerLatencyIn = (int) resampler->latency(resampler_data);
|
||||
int resamplerLatencyOut = (int)ceil(resamplerLatencyIn * sampleRatio);
|
||||
unsigned long PRIME_LEN_ = MAX(sampleRateOfSource/20, 1024u);
|
||||
PRIME_LEN_ = MIN(PRIME_LEN_, 16384u);
|
||||
PRIME_LEN_ = MAX(PRIME_LEN_, 2*LPC_ORDER + 1);
|
||||
|
||||
unsigned int N_samples_to_add_ = sampleRateOfSource;
|
||||
unsigned int N_samples_to_drop_ = sampleRate;
|
||||
|
||||
samples_len(&N_samples_to_add_, &N_samples_to_drop_, 20, 8192u);
|
||||
|
||||
int resamplerLatencyIn = (int) N_samples_to_add_;
|
||||
int resamplerLatencyOut = (int) N_samples_to_drop_;
|
||||
|
||||
float * tempImpulse = (float *) realloc(impulseBuffer, (sampleCount + resamplerLatencyIn * 2 + 1024) * sizeof(float) * impulseChannels);
|
||||
if (!tempImpulse) {
|
||||
|
@ -195,29 +212,31 @@ static const int8_t speakers_to_hesuvi_14[8][2][8] = {
|
|||
free(impulseBuffer);
|
||||
return nil;
|
||||
}
|
||||
|
||||
size_t prime = MIN(sampleCount, PRIME_LEN_);
|
||||
|
||||
void * extrapolate_buffer = NULL;
|
||||
size_t extrapolate_buffer_size = 0;
|
||||
|
||||
memmove(impulseBuffer + resamplerLatencyIn * impulseChannels, impulseBuffer, sampleCount * sizeof(float) * impulseChannels);
|
||||
memset(impulseBuffer, 0, resamplerLatencyIn * sizeof(float) * impulseChannels);
|
||||
memset(impulseBuffer + (resamplerLatencyIn + sampleCount) * impulseChannels, 0, resamplerLatencyIn * sizeof(float) * impulseChannels);
|
||||
lpc_extrapolate_bkwd(impulseBuffer + N_samples_to_add_ * impulseChannels, sampleCount, prime, impulseChannels, LPC_ORDER, N_samples_to_add_, &extrapolate_buffer, &extrapolate_buffer_size);
|
||||
lpc_extrapolate_fwd(impulseBuffer + N_samples_to_add_ * impulseChannels, sampleCount, prime, impulseChannels, LPC_ORDER, N_samples_to_add_, &extrapolate_buffer, &extrapolate_buffer_size);
|
||||
free(extrapolate_buffer);
|
||||
|
||||
struct resampler_data src_data;
|
||||
src_data.data_in = impulseBuffer;
|
||||
src_data.input_frames = sampleCount + resamplerLatencyIn * 2;
|
||||
src_data.data_out = resampledImpulse;
|
||||
src_data.output_frames = 0;
|
||||
src_data.ratio = sampleRatio;
|
||||
size_t inputDone = 0;
|
||||
size_t outputDone = 0;
|
||||
|
||||
soxr_process(soxr, impulseBuffer, sampleCount + N_samples_to_add_ * 2, &inputDone, resampledImpulse, resampledCount, &outputDone);
|
||||
|
||||
resampler->process(resampler_data, &src_data);
|
||||
soxr_delete(soxr);
|
||||
|
||||
resampler->free(resampler, resampler_data);
|
||||
outputDone -= N_samples_to_drop_ * 2;
|
||||
|
||||
src_data.output_frames -= resamplerLatencyOut * 2;
|
||||
|
||||
memmove(resampledImpulse, resampledImpulse + resamplerLatencyOut * impulseChannels, src_data.output_frames * sizeof(float) * impulseChannels);
|
||||
memmove(resampledImpulse, resampledImpulse + N_samples_to_drop_ * impulseChannels, outputDone * sizeof(float) * impulseChannels);
|
||||
|
||||
free(impulseBuffer);
|
||||
impulseBuffer = resampledImpulse;
|
||||
sampleCount = (int) src_data.output_frames;
|
||||
sampleCount = (int) outputDone;
|
||||
}
|
||||
|
||||
channelCount = channels;
|
||||
|
@ -229,7 +248,7 @@ static const int8_t speakers_to_hesuvi_14[8][2][8] = {
|
|||
while (fftSize > 2) { pow++; fftSize /= 2; }
|
||||
fftSize = 2 << pow;
|
||||
|
||||
float * deinterleavedImpulseBuffer = (float *) memalign_alloc(16, fftSize * sizeof(float) * impulseChannels);
|
||||
float * deinterleavedImpulseBuffer = (float *) _mm_malloc(fftSize * sizeof(float) * impulseChannels, 16);
|
||||
if (!deinterleavedImpulseBuffer) {
|
||||
free(impulseBuffer);
|
||||
return nil;
|
||||
|
@ -249,54 +268,54 @@ static const int8_t speakers_to_hesuvi_14[8][2][8] = {
|
|||
|
||||
fftSetup = vDSP_create_fftsetup(log2n, FFT_RADIX2);
|
||||
if (!fftSetup) {
|
||||
memalign_free(deinterleavedImpulseBuffer);
|
||||
_mm_free(deinterleavedImpulseBuffer);
|
||||
return nil;
|
||||
}
|
||||
|
||||
paddedSignal = (float *) memalign_alloc(16, sizeof(float) * paddedBufferSize);
|
||||
paddedSignal = (float *) _mm_malloc(sizeof(float) * paddedBufferSize, 16);
|
||||
if (!paddedSignal) {
|
||||
memalign_free(deinterleavedImpulseBuffer);
|
||||
_mm_free(deinterleavedImpulseBuffer);
|
||||
return nil;
|
||||
}
|
||||
|
||||
signal_fft.realp = (float *) memalign_alloc(16, sizeof(float) * fftSizeOver2);
|
||||
signal_fft.imagp = (float *) memalign_alloc(16, sizeof(float) * fftSizeOver2);
|
||||
signal_fft.realp = (float *) _mm_malloc(sizeof(float) * fftSizeOver2, 16);
|
||||
signal_fft.imagp = (float *) _mm_malloc(sizeof(float) * fftSizeOver2, 16);
|
||||
if (!signal_fft.realp || !signal_fft.imagp) {
|
||||
memalign_free(deinterleavedImpulseBuffer);
|
||||
_mm_free(deinterleavedImpulseBuffer);
|
||||
return nil;
|
||||
}
|
||||
|
||||
input_filtered_signal_per_channel[0].realp = (float *) memalign_alloc(16, sizeof(float) * fftSizeOver2);
|
||||
input_filtered_signal_per_channel[0].imagp = (float *) memalign_alloc(16, sizeof(float) * fftSizeOver2);
|
||||
input_filtered_signal_per_channel[0].realp = (float *) _mm_malloc(sizeof(float) * fftSizeOver2, 16);
|
||||
input_filtered_signal_per_channel[0].imagp = (float *) _mm_malloc(sizeof(float) * fftSizeOver2, 16);
|
||||
if (!input_filtered_signal_per_channel[0].realp ||
|
||||
!input_filtered_signal_per_channel[0].imagp) {
|
||||
memalign_free(deinterleavedImpulseBuffer);
|
||||
_mm_free(deinterleavedImpulseBuffer);
|
||||
return nil;
|
||||
}
|
||||
|
||||
input_filtered_signal_per_channel[1].realp = (float *) memalign_alloc(16, sizeof(float) * fftSizeOver2);
|
||||
input_filtered_signal_per_channel[1].imagp = (float *) memalign_alloc(16, sizeof(float) * fftSizeOver2);
|
||||
input_filtered_signal_per_channel[1].realp = (float *) _mm_malloc(sizeof(float) * fftSizeOver2, 16);
|
||||
input_filtered_signal_per_channel[1].imagp = (float *) _mm_malloc(sizeof(float) * fftSizeOver2, 16);
|
||||
if (!input_filtered_signal_per_channel[1].realp ||
|
||||
!input_filtered_signal_per_channel[1].imagp) {
|
||||
memalign_free(deinterleavedImpulseBuffer);
|
||||
_mm_free(deinterleavedImpulseBuffer);
|
||||
return nil;
|
||||
}
|
||||
|
||||
impulse_responses = (COMPLEX_SPLIT *) calloc(sizeof(COMPLEX_SPLIT), channels * 2);
|
||||
if (!impulse_responses) {
|
||||
memalign_free(deinterleavedImpulseBuffer);
|
||||
_mm_free(deinterleavedImpulseBuffer);
|
||||
return nil;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < channels; ++i) {
|
||||
impulse_responses[i * 2 + 0].realp = (float *) memalign_alloc(16, sizeof(float) * fftSizeOver2);
|
||||
impulse_responses[i * 2 + 0].imagp = (float *) memalign_alloc(16, sizeof(float) * fftSizeOver2);
|
||||
impulse_responses[i * 2 + 1].realp = (float *) memalign_alloc(16, sizeof(float) * fftSizeOver2);
|
||||
impulse_responses[i * 2 + 1].imagp = (float *) memalign_alloc(16, sizeof(float) * fftSizeOver2);
|
||||
impulse_responses[i * 2 + 0].realp = (float *) _mm_malloc(sizeof(float) * fftSizeOver2, 16);
|
||||
impulse_responses[i * 2 + 0].imagp = (float *) _mm_malloc(sizeof(float) * fftSizeOver2, 16);
|
||||
impulse_responses[i * 2 + 1].realp = (float *) _mm_malloc(sizeof(float) * fftSizeOver2, 16);
|
||||
impulse_responses[i * 2 + 1].imagp = (float *) _mm_malloc(sizeof(float) * fftSizeOver2, 16);
|
||||
|
||||
if (!impulse_responses[i * 2 + 0].realp || !impulse_responses[i * 2 + 0].imagp ||
|
||||
!impulse_responses[i * 2 + 1].realp || !impulse_responses[i * 2 + 1].imagp) {
|
||||
memalign_free(deinterleavedImpulseBuffer);
|
||||
_mm_free(deinterleavedImpulseBuffer);
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
@ -317,7 +336,7 @@ static const int8_t speakers_to_hesuvi_14[8][2][8] = {
|
|||
if (impulseChannels == 7) {
|
||||
temp = (float *) malloc(sizeof(float) * fftSize);
|
||||
if (!temp) {
|
||||
memalign_free(deinterleavedImpulseBuffer);
|
||||
_mm_free(deinterleavedImpulseBuffer);
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
@ -330,7 +349,7 @@ static const int8_t speakers_to_hesuvi_14[8][2][8] = {
|
|||
else {
|
||||
temp = (float *) malloc(sizeof(float) * fftSize * 2);
|
||||
if (!temp) {
|
||||
memalign_free(deinterleavedImpulseBuffer);
|
||||
_mm_free(deinterleavedImpulseBuffer);
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
@ -355,20 +374,20 @@ static const int8_t speakers_to_hesuvi_14[8][2][8] = {
|
|||
vDSP_fft_zrip(fftSetup, &impulse_responses[i * 2 + 1], 1, log2n, FFT_FORWARD);
|
||||
}
|
||||
|
||||
memalign_free(deinterleavedImpulseBuffer);
|
||||
_mm_free(deinterleavedImpulseBuffer);
|
||||
|
||||
left_result = (float *) memalign_alloc(16, sizeof(float) * fftSize);
|
||||
right_result = (float *) memalign_alloc(16, sizeof(float) * fftSize);
|
||||
left_result = (float *) _mm_malloc(sizeof(float) * fftSize, 16);
|
||||
right_result = (float *) _mm_malloc(sizeof(float) * fftSize, 16);
|
||||
if (!left_result || !right_result)
|
||||
return nil;
|
||||
|
||||
prevOverlapLeft = (float *) memalign_alloc(16, sizeof(float) * fftSize);
|
||||
prevOverlapRight = (float *) memalign_alloc(16, sizeof(float) * fftSize);
|
||||
prevOverlapLeft = (float *) _mm_malloc(sizeof(float) * fftSize, 16);
|
||||
prevOverlapRight = (float *) _mm_malloc(sizeof(float) * fftSize, 16);
|
||||
if (!prevOverlapLeft || !prevOverlapRight)
|
||||
return nil;
|
||||
|
||||
left_mix_result = (float *) memalign_alloc(16, sizeof(float) * fftSize);
|
||||
right_mix_result = (float *) memalign_alloc(16, sizeof(float) * fftSize);
|
||||
left_mix_result = (float *) _mm_malloc(sizeof(float) * fftSize, 16);
|
||||
right_mix_result = (float *) _mm_malloc(sizeof(float) * fftSize, 16);
|
||||
if (!left_mix_result || !right_mix_result)
|
||||
return nil;
|
||||
|
||||
|
@ -381,32 +400,32 @@ static const int8_t speakers_to_hesuvi_14[8][2][8] = {
|
|||
- (void)dealloc {
|
||||
if (fftSetup) vDSP_destroy_fftsetup(fftSetup);
|
||||
|
||||
memalign_free(paddedSignal);
|
||||
_mm_free(paddedSignal);
|
||||
|
||||
memalign_free(signal_fft.realp);
|
||||
memalign_free(signal_fft.imagp);
|
||||
_mm_free(signal_fft.realp);
|
||||
_mm_free(signal_fft.imagp);
|
||||
|
||||
memalign_free(input_filtered_signal_per_channel[0].realp);
|
||||
memalign_free(input_filtered_signal_per_channel[0].imagp);
|
||||
memalign_free(input_filtered_signal_per_channel[1].realp);
|
||||
memalign_free(input_filtered_signal_per_channel[1].imagp);
|
||||
_mm_free(input_filtered_signal_per_channel[0].realp);
|
||||
_mm_free(input_filtered_signal_per_channel[0].imagp);
|
||||
_mm_free(input_filtered_signal_per_channel[1].realp);
|
||||
_mm_free(input_filtered_signal_per_channel[1].imagp);
|
||||
|
||||
if (impulse_responses) {
|
||||
for (size_t i = 0; i < channelCount * 2; ++i) {
|
||||
memalign_free(impulse_responses[i].realp);
|
||||
memalign_free(impulse_responses[i].imagp);
|
||||
_mm_free(impulse_responses[i].realp);
|
||||
_mm_free(impulse_responses[i].imagp);
|
||||
}
|
||||
free(impulse_responses);
|
||||
}
|
||||
|
||||
memalign_free(left_result);
|
||||
memalign_free(right_result);
|
||||
_mm_free(left_result);
|
||||
_mm_free(right_result);
|
||||
|
||||
memalign_free(prevOverlapLeft);
|
||||
memalign_free(prevOverlapRight);
|
||||
_mm_free(prevOverlapLeft);
|
||||
_mm_free(prevOverlapRight);
|
||||
|
||||
memalign_free(left_mix_result);
|
||||
memalign_free(right_mix_result);
|
||||
_mm_free(left_mix_result);
|
||||
_mm_free(right_mix_result);
|
||||
}
|
||||
|
||||
- (void)process:(const float*)inBuffer sampleCount:(size_t)count toBuffer:(float *)outBuffer {
|
||||
|
|
|
@ -43,7 +43,6 @@
|
|||
17F94DD50B8D0F7000A34E87 /* PluginController.h in Headers */ = {isa = PBXBuildFile; fileRef = 17F94DD30B8D0F7000A34E87 /* PluginController.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
17F94DD60B8D0F7000A34E87 /* PluginController.m in Sources */ = {isa = PBXBuildFile; fileRef = 17F94DD40B8D0F7000A34E87 /* PluginController.m */; };
|
||||
17F94DDD0B8D101100A34E87 /* Plugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 17F94DDC0B8D101100A34E87 /* Plugin.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
832BEF04278DD06D005E1BC4 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 832BEF03278DD06D005E1BC4 /* AVFoundation.framework */; };
|
||||
8347C7412796C58800FA8A7D /* NSFileHandle+CreateFile.h in Headers */ = {isa = PBXBuildFile; fileRef = 8347C73F2796C58800FA8A7D /* NSFileHandle+CreateFile.h */; };
|
||||
8347C7422796C58800FA8A7D /* NSFileHandle+CreateFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 8347C7402796C58800FA8A7D /* NSFileHandle+CreateFile.m */; };
|
||||
835C88A82797D4D400E28EAE /* LICENSE.LGPL in Resources */ = {isa = PBXBuildFile; fileRef = 835C88A42797D4D400E28EAE /* LICENSE.LGPL */; };
|
||||
|
@ -55,46 +54,12 @@
|
|||
835C88B2279811A500E28EAE /* hdcd_decode2.c in Sources */ = {isa = PBXBuildFile; fileRef = 835C88B0279811A500E28EAE /* hdcd_decode2.c */; };
|
||||
835EDD7B279FE23A001EDCCE /* HeadphoneFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 835EDD7A279FE23A001EDCCE /* HeadphoneFilter.m */; };
|
||||
835EDD7D279FE307001EDCCE /* HeadphoneFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 835EDD7C279FE307001EDCCE /* HeadphoneFilter.h */; };
|
||||
835EDD7F27A00089001EDCCE /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 835EDD7E27A00089001EDCCE /* Accelerate.framework */; };
|
||||
83725A8B27AA0DBF0003F694 /* soxr.h in Headers */ = {isa = PBXBuildFile; fileRef = 83725A8827AA0DBF0003F694 /* soxr.h */; };
|
||||
83725A8C27AA0DBF0003F694 /* libsoxr.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 83725A8A27AA0DBF0003F694 /* libsoxr.0.dylib */; };
|
||||
83725A8E27AA0DE60003F694 /* libsoxr.0.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83725A8A27AA0DBF0003F694 /* libsoxr.0.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
83725A9027AA16C90003F694 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83725A7B27AA0D8A0003F694 /* Accelerate.framework */; };
|
||||
83725A9127AA16D50003F694 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83725A7C27AA0D8E0003F694 /* AVFoundation.framework */; };
|
||||
8384912718080FF100E7332D /* Logging.h in Headers */ = {isa = PBXBuildFile; fileRef = 8384912618080FF100E7332D /* Logging.h */; };
|
||||
8389F270278E64590074164C /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = 8389F225278E64590074164C /* config.h */; };
|
||||
8389F279278E64590074164C /* utf.h in Headers */ = {isa = PBXBuildFile; fileRef = 8389F236278E64590074164C /* utf.h */; };
|
||||
8389F27A278E64590074164C /* memalign.h in Headers */ = {isa = PBXBuildFile; fileRef = 8389F237278E64590074164C /* memalign.h */; };
|
||||
8389F27B278E64590074164C /* vfs.h in Headers */ = {isa = PBXBuildFile; fileRef = 8389F239278E64590074164C /* vfs.h */; };
|
||||
8389F27C278E64590074164C /* vfs_implementation.h in Headers */ = {isa = PBXBuildFile; fileRef = 8389F23A278E64590074164C /* vfs_implementation.h */; };
|
||||
8389F27D278E64590074164C /* strl.h in Headers */ = {isa = PBXBuildFile; fileRef = 8389F23C278E64590074164C /* strl.h */; };
|
||||
8389F27E278E64590074164C /* strcasestr.h in Headers */ = {isa = PBXBuildFile; fileRef = 8389F23D278E64590074164C /* strcasestr.h */; };
|
||||
8389F27F278E64590074164C /* fopen_utf8.h in Headers */ = {isa = PBXBuildFile; fileRef = 8389F23E278E64590074164C /* fopen_utf8.h */; };
|
||||
8389F280278E64590074164C /* posix_string.h in Headers */ = {isa = PBXBuildFile; fileRef = 8389F23F278E64590074164C /* posix_string.h */; };
|
||||
8389F281278E64590074164C /* msvc.h in Headers */ = {isa = PBXBuildFile; fileRef = 8389F240278E64590074164C /* msvc.h */; };
|
||||
8389F282278E64590074164C /* retro_common_api.h in Headers */ = {isa = PBXBuildFile; fileRef = 8389F241278E64590074164C /* retro_common_api.h */; };
|
||||
8389F283278E64590074164C /* retro_timers.h in Headers */ = {isa = PBXBuildFile; fileRef = 8389F242278E64590074164C /* retro_timers.h */; };
|
||||
8389F284278E64590074164C /* string_list.h in Headers */ = {isa = PBXBuildFile; fileRef = 8389F244278E64590074164C /* string_list.h */; };
|
||||
8389F285278E64590074164C /* config_file.h in Headers */ = {isa = PBXBuildFile; fileRef = 8389F246278E64590074164C /* config_file.h */; };
|
||||
8389F286278E64590074164C /* config_file_userdata.h in Headers */ = {isa = PBXBuildFile; fileRef = 8389F247278E64590074164C /* config_file_userdata.h */; };
|
||||
8389F287278E64590074164C /* file_path.h in Headers */ = {isa = PBXBuildFile; fileRef = 8389F248278E64590074164C /* file_path.h */; };
|
||||
8389F288278E64590074164C /* retro_environment.h in Headers */ = {isa = PBXBuildFile; fileRef = 8389F249278E64590074164C /* retro_environment.h */; };
|
||||
8389F289278E64590074164C /* rhmap.h in Headers */ = {isa = PBXBuildFile; fileRef = 8389F24B278E64590074164C /* rhmap.h */; };
|
||||
8389F28A278E64590074164C /* retro_inline.h in Headers */ = {isa = PBXBuildFile; fileRef = 8389F24C278E64590074164C /* retro_inline.h */; };
|
||||
8389F28B278E64590074164C /* retro_math.h in Headers */ = {isa = PBXBuildFile; fileRef = 8389F24D278E64590074164C /* retro_math.h */; };
|
||||
8389F28C278E64590074164C /* file_stream.h in Headers */ = {isa = PBXBuildFile; fileRef = 8389F24F278E64590074164C /* file_stream.h */; };
|
||||
8389F28D278E64590074164C /* features_cpu.h in Headers */ = {isa = PBXBuildFile; fileRef = 8389F251278E64590074164C /* features_cpu.h */; };
|
||||
8389F28E278E64590074164C /* retro_miscellaneous.h in Headers */ = {isa = PBXBuildFile; fileRef = 8389F252278E64590074164C /* retro_miscellaneous.h */; };
|
||||
8389F28F278E64590074164C /* rtime.h in Headers */ = {isa = PBXBuildFile; fileRef = 8389F254278E64590074164C /* rtime.h */; };
|
||||
8389F290278E64590074164C /* boolean.h in Headers */ = {isa = PBXBuildFile; fileRef = 8389F255278E64590074164C /* boolean.h */; };
|
||||
8389F291278E64590074164C /* audio_resampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 8389F257278E64590074164C /* audio_resampler.h */; };
|
||||
8389F292278E64590074164C /* s16_to_float.h in Headers */ = {isa = PBXBuildFile; fileRef = 8389F259278E64590074164C /* s16_to_float.h */; };
|
||||
8389F293278E64590074164C /* s32_to_float.h in Headers */ = {isa = PBXBuildFile; fileRef = 8389F25A278E64590074164C /* s32_to_float.h */; };
|
||||
8389F294278E64590074164C /* libretro.h in Headers */ = {isa = PBXBuildFile; fileRef = 8389F25B278E64590074164C /* libretro.h */; };
|
||||
8389F295278E64590074164C /* retro_assert.h in Headers */ = {isa = PBXBuildFile; fileRef = 8389F25C278E64590074164C /* retro_assert.h */; };
|
||||
8389F296278E64590074164C /* stdstring.h in Headers */ = {isa = PBXBuildFile; fileRef = 8389F25E278E64590074164C /* stdstring.h */; };
|
||||
8389F297278E64590074164C /* filters.h in Headers */ = {isa = PBXBuildFile; fileRef = 8389F25F278E64590074164C /* filters.h */; };
|
||||
8389F298278E64590074164C /* features_cpu.c in Sources */ = {isa = PBXBuildFile; fileRef = 8389F261278E64590074164C /* features_cpu.c */; };
|
||||
8389F299278E64590074164C /* memalign.c in Sources */ = {isa = PBXBuildFile; fileRef = 8389F263278E64590074164C /* memalign.c */; };
|
||||
8389F29B278E64590074164C /* sinc_resampler.c in Sources */ = {isa = PBXBuildFile; fileRef = 8389F269278E64590074164C /* sinc_resampler.c */; };
|
||||
8389F29C278E64590074164C /* audio_resampler.c in Sources */ = {isa = PBXBuildFile; fileRef = 8389F26A278E64590074164C /* audio_resampler.c */; };
|
||||
8389F29D278E64590074164C /* s16_to_float.c in Sources */ = {isa = PBXBuildFile; fileRef = 8389F26C278E64590074164C /* s16_to_float.c */; };
|
||||
8389F29E278E64590074164C /* s32_to_float.c in Sources */ = {isa = PBXBuildFile; fileRef = 8389F26D278E64590074164C /* s32_to_float.c */; };
|
||||
839366671815923C006DD712 /* CogPluginMulti.h in Headers */ = {isa = PBXBuildFile; fileRef = 839366651815923C006DD712 /* CogPluginMulti.h */; };
|
||||
839366681815923C006DD712 /* CogPluginMulti.m in Sources */ = {isa = PBXBuildFile; fileRef = 839366661815923C006DD712 /* CogPluginMulti.m */; };
|
||||
83A44A01279119B50049B6E2 /* RefillNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A449FF279119B50049B6E2 /* RefillNode.m */; };
|
||||
|
@ -118,6 +83,16 @@
|
|||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
83725A8D27AA0DDB0003F694 /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 10;
|
||||
files = (
|
||||
83725A8E27AA0DE60003F694 /* libsoxr.0.dylib in CopyFiles */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
|
@ -161,7 +136,6 @@
|
|||
17F94DD40B8D0F7000A34E87 /* PluginController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = PluginController.m; sourceTree = "<group>"; };
|
||||
17F94DDC0B8D101100A34E87 /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Plugin.h; sourceTree = "<group>"; };
|
||||
32DBCF5E0370ADEE00C91783 /* CogAudio_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CogAudio_Prefix.pch; sourceTree = "<group>"; };
|
||||
832BEF03278DD06D005E1BC4 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
|
||||
8347C73F2796C58800FA8A7D /* NSFileHandle+CreateFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSFileHandle+CreateFile.h"; path = "../../Utils/NSFileHandle+CreateFile.h"; sourceTree = "<group>"; };
|
||||
8347C7402796C58800FA8A7D /* NSFileHandle+CreateFile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSFileHandle+CreateFile.m"; path = "../../Utils/NSFileHandle+CreateFile.m"; sourceTree = "<group>"; };
|
||||
835C88A42797D4D400E28EAE /* LICENSE.LGPL */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE.LGPL; sourceTree = "<group>"; };
|
||||
|
@ -173,56 +147,11 @@
|
|||
835C88B0279811A500E28EAE /* hdcd_decode2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = hdcd_decode2.c; sourceTree = "<group>"; };
|
||||
835EDD7A279FE23A001EDCCE /* HeadphoneFilter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HeadphoneFilter.m; sourceTree = "<group>"; };
|
||||
835EDD7C279FE307001EDCCE /* HeadphoneFilter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HeadphoneFilter.h; sourceTree = "<group>"; };
|
||||
835EDD7E27A00089001EDCCE /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
|
||||
83725A7B27AA0D8A0003F694 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
|
||||
83725A7C27AA0D8E0003F694 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
|
||||
83725A8827AA0DBF0003F694 /* soxr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = soxr.h; sourceTree = "<group>"; };
|
||||
83725A8A27AA0DBF0003F694 /* libsoxr.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libsoxr.0.dylib; sourceTree = "<group>"; };
|
||||
8384912618080FF100E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = "<group>"; };
|
||||
8389F225278E64590074164C /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = "<group>"; };
|
||||
8389F228278E64590074164C /* encoding_utf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = encoding_utf.c; sourceTree = "<group>"; };
|
||||
8389F22A278E64590074164C /* vfs_implementation.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vfs_implementation.c; sourceTree = "<group>"; };
|
||||
8389F22C278E64590074164C /* string_list.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = string_list.c; sourceTree = "<group>"; };
|
||||
8389F22E278E64590074164C /* file_path_io.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = file_path_io.c; sourceTree = "<group>"; };
|
||||
8389F22F278E64590074164C /* file_path.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = file_path.c; sourceTree = "<group>"; };
|
||||
8389F230278E64590074164C /* config_file_userdata.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = config_file_userdata.c; sourceTree = "<group>"; };
|
||||
8389F231278E64590074164C /* config_file.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = config_file.c; sourceTree = "<group>"; };
|
||||
8389F233278E64590074164C /* file_stream.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = file_stream.c; sourceTree = "<group>"; };
|
||||
8389F236278E64590074164C /* utf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utf.h; sourceTree = "<group>"; };
|
||||
8389F237278E64590074164C /* memalign.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = memalign.h; sourceTree = "<group>"; };
|
||||
8389F239278E64590074164C /* vfs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vfs.h; sourceTree = "<group>"; };
|
||||
8389F23A278E64590074164C /* vfs_implementation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vfs_implementation.h; sourceTree = "<group>"; };
|
||||
8389F23C278E64590074164C /* strl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = strl.h; sourceTree = "<group>"; };
|
||||
8389F23D278E64590074164C /* strcasestr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = strcasestr.h; sourceTree = "<group>"; };
|
||||
8389F23E278E64590074164C /* fopen_utf8.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fopen_utf8.h; sourceTree = "<group>"; };
|
||||
8389F23F278E64590074164C /* posix_string.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = posix_string.h; sourceTree = "<group>"; };
|
||||
8389F240278E64590074164C /* msvc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = msvc.h; sourceTree = "<group>"; };
|
||||
8389F241278E64590074164C /* retro_common_api.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = retro_common_api.h; sourceTree = "<group>"; };
|
||||
8389F242278E64590074164C /* retro_timers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = retro_timers.h; sourceTree = "<group>"; };
|
||||
8389F244278E64590074164C /* string_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = string_list.h; sourceTree = "<group>"; };
|
||||
8389F246278E64590074164C /* config_file.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config_file.h; sourceTree = "<group>"; };
|
||||
8389F247278E64590074164C /* config_file_userdata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config_file_userdata.h; sourceTree = "<group>"; };
|
||||
8389F248278E64590074164C /* file_path.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = file_path.h; sourceTree = "<group>"; };
|
||||
8389F249278E64590074164C /* retro_environment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = retro_environment.h; sourceTree = "<group>"; };
|
||||
8389F24B278E64590074164C /* rhmap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rhmap.h; sourceTree = "<group>"; };
|
||||
8389F24C278E64590074164C /* retro_inline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = retro_inline.h; sourceTree = "<group>"; };
|
||||
8389F24D278E64590074164C /* retro_math.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = retro_math.h; sourceTree = "<group>"; };
|
||||
8389F24F278E64590074164C /* file_stream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = file_stream.h; sourceTree = "<group>"; };
|
||||
8389F251278E64590074164C /* features_cpu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = features_cpu.h; sourceTree = "<group>"; };
|
||||
8389F252278E64590074164C /* retro_miscellaneous.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = retro_miscellaneous.h; sourceTree = "<group>"; };
|
||||
8389F254278E64590074164C /* rtime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rtime.h; sourceTree = "<group>"; };
|
||||
8389F255278E64590074164C /* boolean.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = boolean.h; sourceTree = "<group>"; };
|
||||
8389F257278E64590074164C /* audio_resampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = audio_resampler.h; sourceTree = "<group>"; };
|
||||
8389F259278E64590074164C /* s16_to_float.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = s16_to_float.h; sourceTree = "<group>"; };
|
||||
8389F25A278E64590074164C /* s32_to_float.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = s32_to_float.h; sourceTree = "<group>"; };
|
||||
8389F25B278E64590074164C /* libretro.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = libretro.h; sourceTree = "<group>"; };
|
||||
8389F25C278E64590074164C /* retro_assert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = retro_assert.h; sourceTree = "<group>"; };
|
||||
8389F25E278E64590074164C /* stdstring.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stdstring.h; sourceTree = "<group>"; };
|
||||
8389F25F278E64590074164C /* filters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = filters.h; sourceTree = "<group>"; };
|
||||
8389F261278E64590074164C /* features_cpu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = features_cpu.c; sourceTree = "<group>"; };
|
||||
8389F263278E64590074164C /* memalign.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = memalign.c; sourceTree = "<group>"; };
|
||||
8389F265278E64590074164C /* rtime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rtime.c; sourceTree = "<group>"; };
|
||||
8389F269278E64590074164C /* sinc_resampler.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sinc_resampler.c; sourceTree = "<group>"; };
|
||||
8389F26A278E64590074164C /* audio_resampler.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = audio_resampler.c; sourceTree = "<group>"; };
|
||||
8389F26C278E64590074164C /* s16_to_float.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = s16_to_float.c; sourceTree = "<group>"; };
|
||||
8389F26D278E64590074164C /* s32_to_float.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = s32_to_float.c; sourceTree = "<group>"; };
|
||||
8389F26F278E64590074164C /* stdstring.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = stdstring.c; sourceTree = "<group>"; };
|
||||
839366651815923C006DD712 /* CogPluginMulti.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CogPluginMulti.h; sourceTree = "<group>"; };
|
||||
839366661815923C006DD712 /* CogPluginMulti.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CogPluginMulti.m; sourceTree = "<group>"; };
|
||||
83A449FF279119B50049B6E2 /* RefillNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RefillNode.m; sourceTree = "<group>"; };
|
||||
|
@ -243,10 +172,11 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
835EDD7F27A00089001EDCCE /* Accelerate.framework in Frameworks */,
|
||||
832BEF04278DD06D005E1BC4 /* AVFoundation.framework in Frameworks */,
|
||||
83725A9127AA16D50003F694 /* AVFoundation.framework in Frameworks */,
|
||||
8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */,
|
||||
83725A9027AA16C90003F694 /* Accelerate.framework in Frameworks */,
|
||||
17D21DAD0B8BE76800D1EBDE /* AudioToolbox.framework in Frameworks */,
|
||||
83725A8C27AA0DBF0003F694 /* libsoxr.0.dylib in Frameworks */,
|
||||
17D21DAE0B8BE76800D1EBDE /* AudioUnit.framework in Frameworks */,
|
||||
17D21DAF0B8BE76800D1EBDE /* CoreAudio.framework in Frameworks */,
|
||||
17D21DB00B8BE76800D1EBDE /* CoreAudioKit.framework in Frameworks */,
|
||||
|
@ -272,7 +202,7 @@
|
|||
089C1665FE841158C02AAC07 /* Resources */,
|
||||
0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */,
|
||||
034768DFFF38A50411DB9C8B /* Products */,
|
||||
832BEF02278DD06D005E1BC4 /* Frameworks */,
|
||||
83725A8F27AA16C90003F694 /* Frameworks */,
|
||||
);
|
||||
name = CogAudio;
|
||||
sourceTree = "<group>";
|
||||
|
@ -338,8 +268,10 @@
|
|||
1058C7B2FEA5585E11CA2CBB /* Other Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
83725A7B27AA0D8A0003F694 /* Accelerate.framework */,
|
||||
17D21DAA0B8BE76800D1EBDE /* AudioUnit.framework */,
|
||||
17D21DA90B8BE76800D1EBDE /* AudioToolbox.framework */,
|
||||
83725A7C27AA0D8E0003F694 /* AVFoundation.framework */,
|
||||
17D21DAB0B8BE76800D1EBDE /* CoreAudio.framework */,
|
||||
17D21DAC0B8BE76800D1EBDE /* CoreAudioKit.framework */,
|
||||
0867D6A5FE840307C02AAC07 /* AppKit.framework */,
|
||||
|
@ -382,9 +314,9 @@
|
|||
17D21CD80B8BE5B400D1EBDE /* ThirdParty */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
83725A8627AA0DBF0003F694 /* libsoxr */,
|
||||
835C88AE279811A500E28EAE /* hdcd */,
|
||||
835C88A22797D4D400E28EAE /* lvqcl */,
|
||||
8389F224278E64590074164C /* RetroArch */,
|
||||
17D21DC40B8BE79700D1EBDE /* CoreAudioUtils */,
|
||||
17D21CD90B8BE5B400D1EBDE /* VirtualRingBuffer */,
|
||||
);
|
||||
|
@ -429,15 +361,6 @@
|
|||
name = "Other Sources";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
832BEF02278DD06D005E1BC4 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
835EDD7E27A00089001EDCCE /* Accelerate.framework */,
|
||||
832BEF03278DD06D005E1BC4 /* AVFoundation.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
835C88A22797D4D400E28EAE /* lvqcl */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -467,275 +390,36 @@
|
|||
path = hdcd;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8389F224278E64590074164C /* RetroArch */ = {
|
||||
83725A8627AA0DBF0003F694 /* libsoxr */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8389F225278E64590074164C /* config.h */,
|
||||
8389F226278E64590074164C /* libretro-common */,
|
||||
83725A8727AA0DBF0003F694 /* include */,
|
||||
83725A8927AA0DBF0003F694 /* lib */,
|
||||
);
|
||||
path = RetroArch;
|
||||
path = libsoxr;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8389F226278E64590074164C /* libretro-common */ = {
|
||||
83725A8727AA0DBF0003F694 /* include */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8389F266278E64590074164C /* audio */,
|
||||
8389F227278E64590074164C /* encodings */,
|
||||
8389F260278E64590074164C /* features */,
|
||||
8389F22D278E64590074164C /* file */,
|
||||
8389F234278E64590074164C /* include */,
|
||||
8389F22B278E64590074164C /* lists */,
|
||||
8389F262278E64590074164C /* memmap */,
|
||||
8389F232278E64590074164C /* streams */,
|
||||
8389F26E278E64590074164C /* string */,
|
||||
8389F264278E64590074164C /* time */,
|
||||
8389F229278E64590074164C /* vfs */,
|
||||
);
|
||||
path = "libretro-common";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8389F227278E64590074164C /* encodings */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8389F228278E64590074164C /* encoding_utf.c */,
|
||||
);
|
||||
path = encodings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8389F229278E64590074164C /* vfs */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8389F22A278E64590074164C /* vfs_implementation.c */,
|
||||
);
|
||||
path = vfs;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8389F22B278E64590074164C /* lists */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8389F22C278E64590074164C /* string_list.c */,
|
||||
);
|
||||
path = lists;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8389F22D278E64590074164C /* file */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8389F230278E64590074164C /* config_file_userdata.c */,
|
||||
8389F231278E64590074164C /* config_file.c */,
|
||||
8389F22E278E64590074164C /* file_path_io.c */,
|
||||
8389F22F278E64590074164C /* file_path.c */,
|
||||
);
|
||||
path = file;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8389F232278E64590074164C /* streams */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8389F233278E64590074164C /* file_stream.c */,
|
||||
);
|
||||
path = streams;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8389F234278E64590074164C /* include */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8389F24A278E64590074164C /* array */,
|
||||
8389F256278E64590074164C /* audio */,
|
||||
8389F255278E64590074164C /* boolean.h */,
|
||||
8389F23B278E64590074164C /* compat */,
|
||||
8389F235278E64590074164C /* encodings */,
|
||||
8389F250278E64590074164C /* features */,
|
||||
8389F245278E64590074164C /* file */,
|
||||
8389F25F278E64590074164C /* filters.h */,
|
||||
8389F25B278E64590074164C /* libretro.h */,
|
||||
8389F243278E64590074164C /* lists */,
|
||||
8389F237278E64590074164C /* memalign.h */,
|
||||
8389F25C278E64590074164C /* retro_assert.h */,
|
||||
8389F241278E64590074164C /* retro_common_api.h */,
|
||||
8389F249278E64590074164C /* retro_environment.h */,
|
||||
8389F24C278E64590074164C /* retro_inline.h */,
|
||||
8389F24D278E64590074164C /* retro_math.h */,
|
||||
8389F252278E64590074164C /* retro_miscellaneous.h */,
|
||||
8389F242278E64590074164C /* retro_timers.h */,
|
||||
8389F24E278E64590074164C /* streams */,
|
||||
8389F25D278E64590074164C /* string */,
|
||||
8389F253278E64590074164C /* time */,
|
||||
8389F238278E64590074164C /* vfs */,
|
||||
83725A8827AA0DBF0003F694 /* soxr.h */,
|
||||
);
|
||||
path = include;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8389F235278E64590074164C /* encodings */ = {
|
||||
83725A8927AA0DBF0003F694 /* lib */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8389F236278E64590074164C /* utf.h */,
|
||||
83725A8A27AA0DBF0003F694 /* libsoxr.0.dylib */,
|
||||
);
|
||||
path = encodings;
|
||||
path = lib;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8389F238278E64590074164C /* vfs */ = {
|
||||
83725A8F27AA16C90003F694 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8389F23A278E64590074164C /* vfs_implementation.h */,
|
||||
8389F239278E64590074164C /* vfs.h */,
|
||||
);
|
||||
path = vfs;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8389F23B278E64590074164C /* compat */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8389F23E278E64590074164C /* fopen_utf8.h */,
|
||||
8389F240278E64590074164C /* msvc.h */,
|
||||
8389F23F278E64590074164C /* posix_string.h */,
|
||||
8389F23D278E64590074164C /* strcasestr.h */,
|
||||
8389F23C278E64590074164C /* strl.h */,
|
||||
);
|
||||
path = compat;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8389F243278E64590074164C /* lists */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8389F244278E64590074164C /* string_list.h */,
|
||||
);
|
||||
path = lists;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8389F245278E64590074164C /* file */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8389F247278E64590074164C /* config_file_userdata.h */,
|
||||
8389F246278E64590074164C /* config_file.h */,
|
||||
8389F248278E64590074164C /* file_path.h */,
|
||||
);
|
||||
path = file;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8389F24A278E64590074164C /* array */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8389F24B278E64590074164C /* rhmap.h */,
|
||||
);
|
||||
path = array;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8389F24E278E64590074164C /* streams */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8389F24F278E64590074164C /* file_stream.h */,
|
||||
);
|
||||
path = streams;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8389F250278E64590074164C /* features */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8389F251278E64590074164C /* features_cpu.h */,
|
||||
);
|
||||
path = features;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8389F253278E64590074164C /* time */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8389F254278E64590074164C /* rtime.h */,
|
||||
);
|
||||
path = time;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8389F256278E64590074164C /* audio */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8389F257278E64590074164C /* audio_resampler.h */,
|
||||
8389F258278E64590074164C /* conversion */,
|
||||
);
|
||||
path = audio;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8389F258278E64590074164C /* conversion */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8389F259278E64590074164C /* s16_to_float.h */,
|
||||
8389F25A278E64590074164C /* s32_to_float.h */,
|
||||
);
|
||||
path = conversion;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8389F25D278E64590074164C /* string */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8389F25E278E64590074164C /* stdstring.h */,
|
||||
);
|
||||
path = string;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8389F260278E64590074164C /* features */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8389F261278E64590074164C /* features_cpu.c */,
|
||||
);
|
||||
path = features;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8389F262278E64590074164C /* memmap */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8389F263278E64590074164C /* memalign.c */,
|
||||
);
|
||||
path = memmap;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8389F264278E64590074164C /* time */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8389F265278E64590074164C /* rtime.c */,
|
||||
);
|
||||
path = time;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8389F266278E64590074164C /* audio */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8389F26B278E64590074164C /* conversion */,
|
||||
8389F267278E64590074164C /* resampler */,
|
||||
);
|
||||
path = audio;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8389F267278E64590074164C /* resampler */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8389F268278E64590074164C /* drivers */,
|
||||
8389F26A278E64590074164C /* audio_resampler.c */,
|
||||
);
|
||||
path = resampler;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8389F268278E64590074164C /* drivers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8389F269278E64590074164C /* sinc_resampler.c */,
|
||||
);
|
||||
path = drivers;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8389F26B278E64590074164C /* conversion */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8389F26C278E64590074164C /* s16_to_float.c */,
|
||||
8389F26D278E64590074164C /* s32_to_float.c */,
|
||||
);
|
||||
path = conversion;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8389F26E278E64590074164C /* string */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8389F26F278E64590074164C /* stdstring.c */,
|
||||
);
|
||||
path = string;
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
@ -746,62 +430,31 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
17D21CA10B8BE4BA00D1EBDE /* BufferChain.h in Headers */,
|
||||
8389F27C278E64590074164C /* vfs_implementation.h in Headers */,
|
||||
17D21CA50B8BE4BA00D1EBDE /* InputNode.h in Headers */,
|
||||
8389F291278E64590074164C /* audio_resampler.h in Headers */,
|
||||
8389F27B278E64590074164C /* vfs.h in Headers */,
|
||||
8389F293278E64590074164C /* s32_to_float.h in Headers */,
|
||||
17D21CA70B8BE4BA00D1EBDE /* Node.h in Headers */,
|
||||
8389F283278E64590074164C /* retro_timers.h in Headers */,
|
||||
17D21CA90B8BE4BA00D1EBDE /* OutputNode.h in Headers */,
|
||||
8389F296278E64590074164C /* stdstring.h in Headers */,
|
||||
8389F27F278E64590074164C /* fopen_utf8.h in Headers */,
|
||||
8389F27E278E64590074164C /* strcasestr.h in Headers */,
|
||||
8389F287278E64590074164C /* file_path.h in Headers */,
|
||||
8389F270278E64590074164C /* config.h in Headers */,
|
||||
17D21CC50B8BE4BA00D1EBDE /* OutputCoreAudio.h in Headers */,
|
||||
17D21CC70B8BE4BA00D1EBDE /* Status.h in Headers */,
|
||||
8389F28E278E64590074164C /* retro_miscellaneous.h in Headers */,
|
||||
8389F280278E64590074164C /* posix_string.h in Headers */,
|
||||
8389F28D278E64590074164C /* features_cpu.h in Headers */,
|
||||
17D21CDF0B8BE5B400D1EBDE /* VirtualRingBuffer.h in Headers */,
|
||||
8389F282278E64590074164C /* retro_common_api.h in Headers */,
|
||||
835C88AB2797D4D400E28EAE /* lpc.h in Headers */,
|
||||
8389F28F278E64590074164C /* rtime.h in Headers */,
|
||||
17D21CF30B8BE5EF00D1EBDE /* Semaphore.h in Headers */,
|
||||
8389F285278E64590074164C /* config_file.h in Headers */,
|
||||
17D21DC70B8BE79700D1EBDE /* CoreAudioUtils.h in Headers */,
|
||||
8389F284278E64590074164C /* string_list.h in Headers */,
|
||||
8389F27A278E64590074164C /* memalign.h in Headers */,
|
||||
17D21EBD0B8BF44000D1EBDE /* AudioPlayer.h in Headers */,
|
||||
17F94DD50B8D0F7000A34E87 /* PluginController.h in Headers */,
|
||||
17F94DDD0B8D101100A34E87 /* Plugin.h in Headers */,
|
||||
17A2D3C50B8D1D37000778C4 /* AudioDecoder.h in Headers */,
|
||||
8389F27D278E64590074164C /* strl.h in Headers */,
|
||||
8389F281278E64590074164C /* msvc.h in Headers */,
|
||||
8347C7412796C58800FA8A7D /* NSFileHandle+CreateFile.h in Headers */,
|
||||
8389F290278E64590074164C /* boolean.h in Headers */,
|
||||
8389F295278E64590074164C /* retro_assert.h in Headers */,
|
||||
8389F28A278E64590074164C /* retro_inline.h in Headers */,
|
||||
17C940230B900909008627D6 /* AudioMetadataReader.h in Headers */,
|
||||
8389F294278E64590074164C /* libretro.h in Headers */,
|
||||
83725A8B27AA0DBF0003F694 /* soxr.h in Headers */,
|
||||
17B619300B909BC300BC003F /* AudioPropertiesReader.h in Headers */,
|
||||
835EDD7D279FE307001EDCCE /* HeadphoneFilter.h in Headers */,
|
||||
8389F286278E64590074164C /* config_file_userdata.h in Headers */,
|
||||
839366671815923C006DD712 /* CogPluginMulti.h in Headers */,
|
||||
17ADB13C0B97926D00257CA2 /* AudioSource.h in Headers */,
|
||||
8389F292278E64590074164C /* s16_to_float.h in Headers */,
|
||||
835C88B1279811A500E28EAE /* hdcd_decode2.h in Headers */,
|
||||
8389F279278E64590074164C /* utf.h in Headers */,
|
||||
8389F288278E64590074164C /* retro_environment.h in Headers */,
|
||||
83A44A02279119B50049B6E2 /* RefillNode.h in Headers */,
|
||||
8EC1225F0B993BD500C5B3AD /* ConverterNode.h in Headers */,
|
||||
8389F28C278E64590074164C /* file_stream.h in Headers */,
|
||||
8384912718080FF100E7332D /* Logging.h in Headers */,
|
||||
8389F297278E64590074164C /* filters.h in Headers */,
|
||||
8E8D3D2F0CBAEE6E00135C1B /* AudioContainer.h in Headers */,
|
||||
8389F289278E64590074164C /* rhmap.h in Headers */,
|
||||
8389F28B278E64590074164C /* retro_math.h in Headers */,
|
||||
B0575F2D0D687A0800411D77 /* Helper.h in Headers */,
|
||||
835C88AD2797DA5800E28EAE /* util.h in Headers */,
|
||||
07DB5F3E0ED353A900C2E3EF /* AudioMetadataWriter.h in Headers */,
|
||||
|
@ -820,6 +473,7 @@
|
|||
8DC2EF540486A6940098B216 /* Sources */,
|
||||
8DC2EF560486A6940098B216 /* Frameworks */,
|
||||
8DC2EF520486A6940098B216 /* Resources */,
|
||||
83725A8D27AA0DDB0003F694 /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
|
@ -885,14 +539,9 @@
|
|||
17D21CA60B8BE4BA00D1EBDE /* InputNode.m in Sources */,
|
||||
17D21CA80B8BE4BA00D1EBDE /* Node.m in Sources */,
|
||||
17D21CAA0B8BE4BA00D1EBDE /* OutputNode.m in Sources */,
|
||||
8389F298278E64590074164C /* features_cpu.c in Sources */,
|
||||
8389F29E278E64590074164C /* s32_to_float.c in Sources */,
|
||||
17D21CC60B8BE4BA00D1EBDE /* OutputCoreAudio.m in Sources */,
|
||||
17D21CE00B8BE5B400D1EBDE /* VirtualRingBuffer.m in Sources */,
|
||||
8389F29D278E64590074164C /* s16_to_float.c in Sources */,
|
||||
8389F29B278E64590074164C /* sinc_resampler.c in Sources */,
|
||||
835C88B2279811A500E28EAE /* hdcd_decode2.c in Sources */,
|
||||
8389F299278E64590074164C /* memalign.c in Sources */,
|
||||
17D21CF40B8BE5EF00D1EBDE /* Semaphore.m in Sources */,
|
||||
8347C7422796C58800FA8A7D /* NSFileHandle+CreateFile.m in Sources */,
|
||||
17D21DC80B8BE79700D1EBDE /* CoreAudioUtils.m in Sources */,
|
||||
|
@ -908,7 +557,6 @@
|
|||
8EC122600B993BD500C5B3AD /* ConverterNode.m in Sources */,
|
||||
8E8D3D300CBAEE6E00135C1B /* AudioContainer.m in Sources */,
|
||||
B0575F300D687A4000411D77 /* Helper.m in Sources */,
|
||||
8389F29C278E64590074164C /* audio_resampler.c in Sources */,
|
||||
07DB5F3F0ED353A900C2E3EF /* AudioMetadataWriter.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -934,12 +582,14 @@
|
|||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = CogAudio_Prefix.pch;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"ThirdParty/RetroArch/libretro-common/include",
|
||||
ThirdParty/RetroArch,
|
||||
);
|
||||
HEADER_SEARCH_PATHS = ThirdParty/libsoxr/include;
|
||||
INFOPLIST_FILE = Info.plist;
|
||||
INSTALL_PATH = "@executable_path/../Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks";
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
ThirdParty/libsoxr/lib,
|
||||
"$(PROJECT_DIR)/ThirdParty/libsoxr/lib",
|
||||
);
|
||||
OTHER_LDFLAGS = "";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.cogx.cogaudio;
|
||||
PRODUCT_NAME = CogAudio;
|
||||
|
@ -967,12 +617,14 @@
|
|||
GCC_MODEL_TUNING = G5;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = CogAudio_Prefix.pch;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"ThirdParty/RetroArch/libretro-common/include",
|
||||
ThirdParty/RetroArch,
|
||||
);
|
||||
HEADER_SEARCH_PATHS = ThirdParty/libsoxr/include;
|
||||
INFOPLIST_FILE = Info.plist;
|
||||
INSTALL_PATH = "@executable_path/../Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks";
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
ThirdParty/libsoxr/lib,
|
||||
"$(PROJECT_DIR)/ThirdParty/libsoxr/lib",
|
||||
);
|
||||
OTHER_LDFLAGS = "";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.cogx.cogaudio;
|
||||
PRODUCT_NAME = CogAudio;
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
#ifndef _RARCH_CONFIG_H
|
||||
#define _RARCH_CONFIG_H
|
||||
|
||||
#include <TargetConditionals.h>
|
||||
|
||||
#define HAVE_SSIZE_T 1
|
||||
#define HAVE_STRL 1
|
||||
|
||||
#if TARGET_CPU_X86 || TARGET_CPU_X86_64
|
||||
#define HAVE_SSE 1
|
||||
#define __SSE__ 1
|
||||
#define __SSE2__ 1
|
||||
#define __AVX__ 1
|
||||
#endif
|
||||
|
||||
#if TARGET_CPU_ARM || TARGET_CPU_ARM64
|
||||
#define HAVE_NEON 1
|
||||
#define __ARM_NEON__ 1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -1,110 +0,0 @@
|
|||
/* Copyright (C) 2010-2021 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (s16_to_float.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#if defined(__SSE2__)
|
||||
#include <emmintrin.h>
|
||||
#endif
|
||||
|
||||
#include <boolean.h>
|
||||
#include <features/features_cpu.h>
|
||||
#include <audio/conversion/s16_to_float.h>
|
||||
|
||||
#if (defined(__ARM_NEON__) || defined(HAVE_NEON))
|
||||
static bool s16_to_float_neon_enabled = false;
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
void convert_s16_to_float(float *out,
|
||||
const int16_t *in, size_t samples, float gain)
|
||||
{
|
||||
unsigned i = 0;
|
||||
|
||||
if (s16_to_float_neon_enabled)
|
||||
{
|
||||
float gf = gain / (1 << 15);
|
||||
float32x4_t vgf = {gf, gf, gf, gf};
|
||||
while (samples >= 8)
|
||||
{
|
||||
float32x4x2_t oreg;
|
||||
int16x4x2_t inreg = vld1_s16_x2(in); // why were these interleaved before?
|
||||
int32x4_t p1 = vmovl_s16(inreg.val[0]);
|
||||
int32x4_t p2 = vmovl_s16(inreg.val[1]);
|
||||
oreg.val[0] = vmulq_f32(vcvtq_f32_s32(p1), vgf);
|
||||
oreg.val[1] = vmulq_f32(vcvtq_f32_s32(p2), vgf);
|
||||
vst1q_f32_x2(out, oreg);
|
||||
in += 8;
|
||||
out += 8;
|
||||
samples -= 8;
|
||||
}
|
||||
}
|
||||
|
||||
gain /= 0x8000;
|
||||
|
||||
for (; i < samples; i++)
|
||||
out[i] = (float)in[i] * gain;
|
||||
}
|
||||
|
||||
void convert_s16_to_float_init_simd(void)
|
||||
{
|
||||
uint64_t cpu = cpu_features_get();
|
||||
|
||||
if (cpu & RETRO_SIMD_NEON)
|
||||
s16_to_float_neon_enabled = true;
|
||||
}
|
||||
#else
|
||||
void convert_s16_to_float(float *out,
|
||||
const int16_t *in, size_t samples, float gain)
|
||||
{
|
||||
unsigned i = 0;
|
||||
|
||||
#if defined(__SSE2__)
|
||||
float fgain = gain / UINT32_C(0x80000000);
|
||||
__m128 factor = _mm_set1_ps(fgain);
|
||||
|
||||
for (i = 0; i + 8 <= samples; i += 8, in += 8, out += 8)
|
||||
{
|
||||
__m128i input = _mm_loadu_si128((const __m128i *)in);
|
||||
__m128i regs_l = _mm_unpacklo_epi16(_mm_setzero_si128(), input);
|
||||
__m128i regs_r = _mm_unpackhi_epi16(_mm_setzero_si128(), input);
|
||||
__m128 output_l = _mm_mul_ps(_mm_cvtepi32_ps(regs_l), factor);
|
||||
__m128 output_r = _mm_mul_ps(_mm_cvtepi32_ps(regs_r), factor);
|
||||
|
||||
_mm_storeu_ps(out + 0, output_l);
|
||||
_mm_storeu_ps(out + 4, output_r);
|
||||
}
|
||||
|
||||
samples = samples - i;
|
||||
i = 0;
|
||||
#endif
|
||||
|
||||
gain /= 0x8000;
|
||||
|
||||
for (; i < samples; i++)
|
||||
out[i] = (float)in[i] * gain;
|
||||
}
|
||||
|
||||
void convert_s16_to_float_init_simd(void) { }
|
||||
#endif
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
/* Copyright (C) 2010-2021 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (s32_to_float.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#if defined(__SSE2__)
|
||||
#include <emmintrin.h>
|
||||
#endif
|
||||
|
||||
#include <boolean.h>
|
||||
#include <features/features_cpu.h>
|
||||
#include <audio/conversion/s32_to_float.h>
|
||||
|
||||
#if (defined(__ARM_NEON__) || defined(HAVE_NEON))
|
||||
static bool s32_to_float_neon_enabled = false;
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
void convert_s32_to_float(float *out,
|
||||
const int32_t *in, size_t samples, float gain)
|
||||
{
|
||||
unsigned i = 0;
|
||||
|
||||
if (s32_to_float_neon_enabled)
|
||||
{
|
||||
float gf = gain / UINT32_C(1U << 31);
|
||||
float32x4_t vgf = {gf, gf, gf, gf};
|
||||
while (samples >= 8)
|
||||
{
|
||||
float32x4x2_t oreg;
|
||||
int32x4x2_t inreg = vld1q_s32_x2(in); // why were these interleaved before?
|
||||
oreg.val[0] = vmulq_f32(vcvtq_f32_s32(inreg.val[0]), vgf);
|
||||
oreg.val[1] = vmulq_f32(vcvtq_f32_s32(inreg.val[1]), vgf);
|
||||
vst1q_f32_x2(out, oreg);
|
||||
in += 8;
|
||||
out += 8;
|
||||
samples -= 8;
|
||||
}
|
||||
}
|
||||
|
||||
gain /= UINT32_C(0x80000000);
|
||||
|
||||
for (; i < samples; i++)
|
||||
out[i] = (float)in[i] * gain;
|
||||
}
|
||||
|
||||
void convert_s32_to_float_init_simd(void)
|
||||
{
|
||||
uint64_t cpu = cpu_features_get();
|
||||
|
||||
if (cpu & RETRO_SIMD_NEON)
|
||||
s32_to_float_neon_enabled = true;
|
||||
}
|
||||
#else
|
||||
void convert_s32_to_float(float *out,
|
||||
const int32_t *in, size_t samples, float gain)
|
||||
{
|
||||
unsigned i = 0;
|
||||
|
||||
#if defined(__SSE2__)
|
||||
float fgain = gain / UINT32_C(0x80000000);
|
||||
__m128 factor = _mm_set1_ps(fgain);
|
||||
|
||||
for (i = 0; i + 8 <= samples; i += 8, in += 8, out += 8)
|
||||
{
|
||||
__m128i input = _mm_loadu_si128((const __m128i *)in);
|
||||
__m128i input2 = _mm_loadu_si128((const __m128i *)(in + 4));
|
||||
__m128 output_l = _mm_mul_ps(_mm_cvtepi32_ps(input), factor);
|
||||
__m128 output_r = _mm_mul_ps(_mm_cvtepi32_ps(input2), factor);
|
||||
|
||||
_mm_storeu_ps(out + 0, output_l);
|
||||
_mm_storeu_ps(out + 4, output_r);
|
||||
}
|
||||
|
||||
samples = samples - i;
|
||||
i = 0;
|
||||
#endif
|
||||
|
||||
gain /= 0x80000000L;
|
||||
|
||||
for (; i < samples; i++)
|
||||
out[i] = (float)in[i] * gain;
|
||||
}
|
||||
|
||||
void convert_s32_to_float_init_simd(void) { }
|
||||
#endif
|
||||
|
|
@ -1,260 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (audio_resampler.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <string/stdstring.h>
|
||||
#include <features/features_cpu.h>
|
||||
#include <file/config_file_userdata.h>
|
||||
|
||||
#include <audio/audio_resampler.h>
|
||||
|
||||
static void resampler_null_process(void *a, struct resampler_data *b) { }
|
||||
static size_t resampler_null_latency(void *a) { return 0; }
|
||||
static void resampler_null_free(const retro_resampler_t *a, void *b) { }
|
||||
static void *resampler_null_init(const struct resampler_config *a, const retro_resampler_t **b,
|
||||
double c, enum resampler_quality d, size_t e, resampler_simd_mask_t f) { return (void*)0; }
|
||||
|
||||
retro_resampler_t null_resampler = {
|
||||
resampler_null_init,
|
||||
resampler_null_process,
|
||||
resampler_null_free,
|
||||
resampler_null_latency,
|
||||
RESAMPLER_API_VERSION,
|
||||
"null",
|
||||
"null"
|
||||
};
|
||||
|
||||
static const retro_resampler_t *resampler_drivers[] = {
|
||||
&sinc_resampler,
|
||||
#ifdef HAVE_CC_RESAMPLER
|
||||
&CC_resampler,
|
||||
#endif
|
||||
#ifdef HAVE_NEAREST_RESAMPLER
|
||||
&nearest_resampler,
|
||||
#endif
|
||||
&null_resampler,
|
||||
NULL,
|
||||
};
|
||||
|
||||
#if 0
|
||||
static const struct resampler_config resampler_config = {
|
||||
config_userdata_get_float,
|
||||
config_userdata_get_int,
|
||||
config_userdata_get_float_array,
|
||||
config_userdata_get_int_array,
|
||||
config_userdata_get_string,
|
||||
config_userdata_free,
|
||||
};
|
||||
#else
|
||||
// sinc doesn't use this anyway
|
||||
static int stub_get_float(void *userdata,
|
||||
const char *key, float *value, float default_value)
|
||||
{
|
||||
*value = default_value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stub_get_int(void *userdata,
|
||||
const char *key, int *value, int default_value)
|
||||
{
|
||||
*value = default_value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stub_get_float_array(void *userdata,
|
||||
const char *key, float **values, unsigned *out_num_values,
|
||||
const float *default_values, unsigned num_default_values)
|
||||
{
|
||||
*values = malloc(sizeof(float) * num_default_values);
|
||||
if (*values)
|
||||
memcpy(*values, default_values, sizeof(float) * num_default_values);
|
||||
*out_num_values = num_default_values;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stub_get_int_array(void *userdata,
|
||||
const char *key, int **values, unsigned *out_num_values,
|
||||
const int *default_values, unsigned num_default_values)
|
||||
{
|
||||
*values = malloc(sizeof(int) * num_default_values);
|
||||
if (*values)
|
||||
memcpy(*values, default_values, sizeof(int) * num_default_values);
|
||||
*out_num_values = num_default_values;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stub_get_string(void *userdata,
|
||||
const char *key, char **output, const char *default_output)
|
||||
{
|
||||
size_t len = strlen(default_output) + 1;
|
||||
*output = malloc(len);
|
||||
if (*output)
|
||||
memcpy(*output, default_output, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void stub_free(void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
static const struct resampler_config resampler_config = {
|
||||
stub_get_float,
|
||||
stub_get_int,
|
||||
stub_get_float_array,
|
||||
stub_get_int_array,
|
||||
stub_get_string,
|
||||
stub_free,
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* find_resampler_driver_index:
|
||||
* @ident : Identifier of resampler driver to find.
|
||||
*
|
||||
* Finds resampler driver index by @ident name.
|
||||
*
|
||||
* Returns: resampler driver index if resampler driver was found, otherwise
|
||||
* -1.
|
||||
**/
|
||||
static int find_resampler_driver_index(const char *ident)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; resampler_drivers[i]; i++)
|
||||
if (string_is_equal_noncase(ident, resampler_drivers[i]->ident))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* find_resampler_driver:
|
||||
* @ident : Identifier of resampler driver to find.
|
||||
*
|
||||
* Finds resampler by @ident name.
|
||||
*
|
||||
* Returns: resampler driver if resampler driver was found, otherwise
|
||||
* NULL.
|
||||
**/
|
||||
static const retro_resampler_t *find_resampler_driver(const char *ident)
|
||||
{
|
||||
int i = find_resampler_driver_index(ident);
|
||||
|
||||
if (i >= 0)
|
||||
return resampler_drivers[i];
|
||||
|
||||
return resampler_drivers[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* resampler_append_plugs:
|
||||
* @re : Resampler handle
|
||||
* @backend : Resampler backend that is about to be set.
|
||||
* @bw_ratio : Bandwidth ratio.
|
||||
*
|
||||
* Initializes resampler driver based on queried CPU features.
|
||||
*
|
||||
* Returns: true (1) if successfully initialized, otherwise false (0).
|
||||
**/
|
||||
static bool resampler_append_plugs(void **re,
|
||||
const retro_resampler_t **backend,
|
||||
enum resampler_quality quality,
|
||||
size_t channels,
|
||||
double bw_ratio)
|
||||
{
|
||||
resampler_simd_mask_t mask = (resampler_simd_mask_t)cpu_features_get();
|
||||
|
||||
if (*backend)
|
||||
*re = (*backend)->init(&resampler_config, backend, bw_ratio, quality, channels, mask);
|
||||
|
||||
if (!*re)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* audio_resampler_driver_find_handle:
|
||||
* @idx : index of driver to get handle to.
|
||||
*
|
||||
* Returns: handle to audio resampler driver at index. Can be NULL
|
||||
* if nothing found.
|
||||
**/
|
||||
const void *audio_resampler_driver_find_handle(int idx)
|
||||
{
|
||||
const void *drv = resampler_drivers[idx];
|
||||
if (!drv)
|
||||
return NULL;
|
||||
return drv;
|
||||
}
|
||||
|
||||
/**
|
||||
* audio_resampler_driver_find_ident:
|
||||
* @idx : index of driver to get handle to.
|
||||
*
|
||||
* Returns: Human-readable identifier of audio resampler driver at index.
|
||||
* Can be NULL if nothing found.
|
||||
**/
|
||||
const char *audio_resampler_driver_find_ident(int idx)
|
||||
{
|
||||
const retro_resampler_t *drv = resampler_drivers[idx];
|
||||
if (!drv)
|
||||
return NULL;
|
||||
return drv->ident;
|
||||
}
|
||||
|
||||
/**
|
||||
* retro_resampler_realloc:
|
||||
* @re : Resampler handle
|
||||
* @backend : Resampler backend that is about to be set.
|
||||
* @ident : Identifier name for resampler we want.
|
||||
* @bw_ratio : Bandwidth ratio.
|
||||
*
|
||||
* Reallocates resampler. Will free previous handle before
|
||||
* allocating a new one. If ident is NULL, first resampler will be used.
|
||||
*
|
||||
* Returns: true (1) if successful, otherwise false (0).
|
||||
**/
|
||||
bool retro_resampler_realloc(void **re, const retro_resampler_t **backend,
|
||||
const char *ident, enum resampler_quality quality, size_t channels,
|
||||
double bw_ratio)
|
||||
{
|
||||
if (*re && *backend)
|
||||
(*backend)->free(*backend, *re);
|
||||
|
||||
*re = NULL;
|
||||
*backend = find_resampler_driver(ident);
|
||||
|
||||
if (!resampler_append_plugs(re, backend, quality, channels, bw_ratio))
|
||||
{
|
||||
if (!*re)
|
||||
*backend = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,512 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (encoding_utf.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <boolean.h>
|
||||
#include <compat/strl.h>
|
||||
#include <retro_inline.h>
|
||||
|
||||
#include <encodings/utf.h>
|
||||
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
#include <windows.h>
|
||||
#elif defined(_XBOX)
|
||||
#include <xtl.h>
|
||||
#endif
|
||||
|
||||
#define UTF8_WALKBYTE(string) (*((*(string))++))
|
||||
|
||||
static unsigned leading_ones(uint8_t c)
|
||||
{
|
||||
unsigned ones = 0;
|
||||
while (c & 0x80)
|
||||
{
|
||||
ones++;
|
||||
c <<= 1;
|
||||
}
|
||||
|
||||
return ones;
|
||||
}
|
||||
|
||||
/* Simple implementation. Assumes the sequence is
|
||||
* properly synchronized and terminated. */
|
||||
|
||||
size_t utf8_conv_utf32(uint32_t *out, size_t out_chars,
|
||||
const char *in, size_t in_size)
|
||||
{
|
||||
unsigned i;
|
||||
size_t ret = 0;
|
||||
while (in_size && out_chars)
|
||||
{
|
||||
unsigned extra, shift;
|
||||
uint32_t c;
|
||||
uint8_t first = *in++;
|
||||
unsigned ones = leading_ones(first);
|
||||
|
||||
if (ones > 6 || ones == 1) /* Invalid or desync. */
|
||||
break;
|
||||
|
||||
extra = ones ? ones - 1 : ones;
|
||||
if (1 + extra > in_size) /* Overflow. */
|
||||
break;
|
||||
|
||||
shift = (extra - 1) * 6;
|
||||
c = (first & ((1 << (7 - ones)) - 1)) << (6 * extra);
|
||||
|
||||
for (i = 0; i < extra; i++, in++, shift -= 6)
|
||||
c |= (*in & 0x3f) << shift;
|
||||
|
||||
*out++ = c;
|
||||
in_size -= 1 + extra;
|
||||
out_chars--;
|
||||
ret++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool utf16_conv_utf8(uint8_t *out, size_t *out_chars,
|
||||
const uint16_t *in, size_t in_size)
|
||||
{
|
||||
size_t out_pos = 0;
|
||||
size_t in_pos = 0;
|
||||
static const
|
||||
uint8_t utf8_limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
|
||||
|
||||
for (;;)
|
||||
{
|
||||
unsigned num_adds;
|
||||
uint32_t value;
|
||||
|
||||
if (in_pos == in_size)
|
||||
{
|
||||
*out_chars = out_pos;
|
||||
return true;
|
||||
}
|
||||
value = in[in_pos++];
|
||||
if (value < 0x80)
|
||||
{
|
||||
if (out)
|
||||
out[out_pos] = (char)value;
|
||||
out_pos++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (value >= 0xD800 && value < 0xE000)
|
||||
{
|
||||
uint32_t c2;
|
||||
|
||||
if (value >= 0xDC00 || in_pos == in_size)
|
||||
break;
|
||||
c2 = in[in_pos++];
|
||||
if (c2 < 0xDC00 || c2 >= 0xE000)
|
||||
break;
|
||||
value = (((value - 0xD800) << 10) | (c2 - 0xDC00)) + 0x10000;
|
||||
}
|
||||
|
||||
for (num_adds = 1; num_adds < 5; num_adds++)
|
||||
if (value < (((uint32_t)1) << (num_adds * 5 + 6)))
|
||||
break;
|
||||
if (out)
|
||||
out[out_pos] = (char)(utf8_limits[num_adds - 1]
|
||||
+ (value >> (6 * num_adds)));
|
||||
out_pos++;
|
||||
do
|
||||
{
|
||||
num_adds--;
|
||||
if (out)
|
||||
out[out_pos] = (char)(0x80
|
||||
+ ((value >> (6 * num_adds)) & 0x3F));
|
||||
out_pos++;
|
||||
}while (num_adds != 0);
|
||||
}
|
||||
|
||||
*out_chars = out_pos;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Acts mostly like strlcpy.
|
||||
*
|
||||
* Copies the given number of UTF-8 characters,
|
||||
* but at most d_len bytes.
|
||||
*
|
||||
* Always NULL terminates.
|
||||
* Does not copy half a character.
|
||||
*
|
||||
* Returns number of bytes. 's' is assumed valid UTF-8.
|
||||
* Use only if 'chars' is considerably less than 'd_len'. */
|
||||
size_t utf8cpy(char *d, size_t d_len, const char *s, size_t chars)
|
||||
{
|
||||
const uint8_t *sb = (const uint8_t*)s;
|
||||
const uint8_t *sb_org = sb;
|
||||
|
||||
if (!s)
|
||||
return 0;
|
||||
|
||||
while (*sb && chars-- > 0)
|
||||
{
|
||||
sb++;
|
||||
while ((*sb & 0xC0) == 0x80)
|
||||
sb++;
|
||||
}
|
||||
|
||||
if ((size_t)(sb - sb_org) > d_len-1 /* NUL */)
|
||||
{
|
||||
sb = sb_org + d_len-1;
|
||||
while ((*sb & 0xC0) == 0x80)
|
||||
sb--;
|
||||
}
|
||||
|
||||
memcpy(d, sb_org, sb-sb_org);
|
||||
d[sb-sb_org] = '\0';
|
||||
|
||||
return sb-sb_org;
|
||||
}
|
||||
|
||||
const char *utf8skip(const char *str, size_t chars)
|
||||
{
|
||||
const uint8_t *strb = (const uint8_t*)str;
|
||||
|
||||
if (!chars)
|
||||
return str;
|
||||
|
||||
do
|
||||
{
|
||||
strb++;
|
||||
while ((*strb & 0xC0)==0x80)
|
||||
strb++;
|
||||
chars--;
|
||||
}while (chars);
|
||||
|
||||
return (const char*)strb;
|
||||
}
|
||||
|
||||
size_t utf8len(const char *string)
|
||||
{
|
||||
size_t ret = 0;
|
||||
|
||||
if (!string)
|
||||
return 0;
|
||||
|
||||
while (*string)
|
||||
{
|
||||
if ((*string & 0xC0) != 0x80)
|
||||
ret++;
|
||||
string++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Does not validate the input, returns garbage if it's not UTF-8. */
|
||||
uint32_t utf8_walk(const char **string)
|
||||
{
|
||||
uint8_t first = UTF8_WALKBYTE(string);
|
||||
uint32_t ret = 0;
|
||||
|
||||
if (first < 128)
|
||||
return first;
|
||||
|
||||
ret = (ret << 6) | (UTF8_WALKBYTE(string) & 0x3F);
|
||||
if (first >= 0xE0)
|
||||
{
|
||||
ret = (ret << 6) | (UTF8_WALKBYTE(string) & 0x3F);
|
||||
if (first >= 0xF0)
|
||||
{
|
||||
ret = (ret << 6) | (UTF8_WALKBYTE(string) & 0x3F);
|
||||
return ret | (first & 7) << 18;
|
||||
}
|
||||
return ret | (first & 15) << 12;
|
||||
}
|
||||
|
||||
return ret | (first & 31) << 6;
|
||||
}
|
||||
|
||||
static bool utf16_to_char(uint8_t **utf_data,
|
||||
size_t *dest_len, const uint16_t *in)
|
||||
{
|
||||
unsigned len = 0;
|
||||
|
||||
while (in[len] != '\0')
|
||||
len++;
|
||||
|
||||
utf16_conv_utf8(NULL, dest_len, in, len);
|
||||
*dest_len += 1;
|
||||
*utf_data = (uint8_t*)malloc(*dest_len);
|
||||
if (*utf_data == 0)
|
||||
return false;
|
||||
|
||||
return utf16_conv_utf8(*utf_data, dest_len, in, len);
|
||||
}
|
||||
|
||||
bool utf16_to_char_string(const uint16_t *in, char *s, size_t len)
|
||||
{
|
||||
size_t dest_len = 0;
|
||||
uint8_t *utf16_data = NULL;
|
||||
bool ret = utf16_to_char(&utf16_data, &dest_len, in);
|
||||
|
||||
if (ret)
|
||||
{
|
||||
utf16_data[dest_len] = 0;
|
||||
strlcpy(s, (const char*)utf16_data, len);
|
||||
}
|
||||
|
||||
free(utf16_data);
|
||||
utf16_data = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(_WIN32) && !defined(_XBOX) && !defined(UNICODE)
|
||||
/* Returned pointer MUST be freed by the caller if non-NULL. */
|
||||
static char *mb_to_mb_string_alloc(const char *str,
|
||||
enum CodePage cp_in, enum CodePage cp_out)
|
||||
{
|
||||
wchar_t *path_buf_wide = NULL;
|
||||
int path_buf_wide_len = MultiByteToWideChar(cp_in, 0, str, -1, NULL, 0);
|
||||
|
||||
/* Windows 95 will return 0 from these functions with
|
||||
* a UTF8 codepage set without MSLU.
|
||||
*
|
||||
* From an unknown MSDN version (others omit this info):
|
||||
* - CP_UTF8 Windows 98/Me, Windows NT 4.0 and later:
|
||||
* Translate using UTF-8. When this is set, dwFlags must be zero.
|
||||
* - Windows 95: Under the Microsoft Layer for Unicode,
|
||||
* MultiByteToWideChar also supports CP_UTF7 and CP_UTF8.
|
||||
*/
|
||||
|
||||
if (!path_buf_wide_len)
|
||||
return strdup(str);
|
||||
|
||||
path_buf_wide = (wchar_t*)
|
||||
calloc(path_buf_wide_len + sizeof(wchar_t), sizeof(wchar_t));
|
||||
|
||||
if (path_buf_wide)
|
||||
{
|
||||
MultiByteToWideChar(cp_in, 0,
|
||||
str, -1, path_buf_wide, path_buf_wide_len);
|
||||
|
||||
if (*path_buf_wide)
|
||||
{
|
||||
int path_buf_len = WideCharToMultiByte(cp_out, 0,
|
||||
path_buf_wide, -1, NULL, 0, NULL, NULL);
|
||||
|
||||
if (path_buf_len)
|
||||
{
|
||||
char *path_buf = (char*)
|
||||
calloc(path_buf_len + sizeof(char), sizeof(char));
|
||||
|
||||
if (path_buf)
|
||||
{
|
||||
WideCharToMultiByte(cp_out, 0,
|
||||
path_buf_wide, -1, path_buf,
|
||||
path_buf_len, NULL, NULL);
|
||||
|
||||
free(path_buf_wide);
|
||||
|
||||
if (*path_buf)
|
||||
return path_buf;
|
||||
|
||||
free(path_buf);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
free(path_buf_wide);
|
||||
return strdup(str);
|
||||
}
|
||||
}
|
||||
|
||||
free(path_buf_wide);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Returned pointer MUST be freed by the caller if non-NULL. */
|
||||
char* utf8_to_local_string_alloc(const char *str)
|
||||
{
|
||||
if (str && *str)
|
||||
{
|
||||
#if defined(_WIN32) && !defined(_XBOX) && !defined(UNICODE)
|
||||
return mb_to_mb_string_alloc(str, CODEPAGE_UTF8, CODEPAGE_LOCAL);
|
||||
#else
|
||||
/* assume string needs no modification if not on Windows */
|
||||
return strdup(str);
|
||||
#endif
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Returned pointer MUST be freed by the caller if non-NULL. */
|
||||
char* local_to_utf8_string_alloc(const char *str)
|
||||
{
|
||||
if (str && *str)
|
||||
{
|
||||
#if defined(_WIN32) && !defined(_XBOX) && !defined(UNICODE)
|
||||
return mb_to_mb_string_alloc(str, CODEPAGE_LOCAL, CODEPAGE_UTF8);
|
||||
#else
|
||||
/* assume string needs no modification if not on Windows */
|
||||
return strdup(str);
|
||||
#endif
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Returned pointer MUST be freed by the caller if non-NULL. */
|
||||
wchar_t* utf8_to_utf16_string_alloc(const char *str)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
int len = 0;
|
||||
int out_len = 0;
|
||||
#else
|
||||
size_t len = 0;
|
||||
size_t out_len = 0;
|
||||
#endif
|
||||
wchar_t *buf = NULL;
|
||||
|
||||
if (!str || !*str)
|
||||
return NULL;
|
||||
|
||||
#ifdef _WIN32
|
||||
len = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
|
||||
|
||||
if (len)
|
||||
{
|
||||
buf = (wchar_t*)calloc(len, sizeof(wchar_t));
|
||||
|
||||
if (!buf)
|
||||
return NULL;
|
||||
|
||||
out_len = MultiByteToWideChar(CP_UTF8, 0, str, -1, buf, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* fallback to ANSI codepage instead */
|
||||
len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
|
||||
|
||||
if (len)
|
||||
{
|
||||
buf = (wchar_t*)calloc(len, sizeof(wchar_t));
|
||||
|
||||
if (!buf)
|
||||
return NULL;
|
||||
|
||||
out_len = MultiByteToWideChar(CP_ACP, 0, str, -1, buf, len);
|
||||
}
|
||||
}
|
||||
|
||||
if (out_len < 0)
|
||||
{
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
/* NOTE: For now, assume non-Windows platforms' locale is already UTF-8. */
|
||||
len = mbstowcs(NULL, str, 0) + 1;
|
||||
|
||||
if (len)
|
||||
{
|
||||
buf = (wchar_t*)calloc(len, sizeof(wchar_t));
|
||||
|
||||
if (!buf)
|
||||
return NULL;
|
||||
|
||||
out_len = mbstowcs(buf, str, len);
|
||||
}
|
||||
|
||||
if (out_len == (size_t)-1)
|
||||
{
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* Returned pointer MUST be freed by the caller if non-NULL. */
|
||||
char* utf16_to_utf8_string_alloc(const wchar_t *str)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
int len = 0;
|
||||
#else
|
||||
size_t len = 0;
|
||||
#endif
|
||||
char *buf = NULL;
|
||||
|
||||
if (!str || !*str)
|
||||
return NULL;
|
||||
|
||||
#ifdef _WIN32
|
||||
{
|
||||
UINT code_page = CP_UTF8;
|
||||
len = WideCharToMultiByte(code_page,
|
||||
0, str, -1, NULL, 0, NULL, NULL);
|
||||
|
||||
/* fallback to ANSI codepage instead */
|
||||
if (!len)
|
||||
{
|
||||
code_page = CP_ACP;
|
||||
len = WideCharToMultiByte(code_page,
|
||||
0, str, -1, NULL, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
buf = (char*)calloc(len, sizeof(char));
|
||||
|
||||
if (!buf)
|
||||
return NULL;
|
||||
|
||||
if (WideCharToMultiByte(code_page,
|
||||
0, str, -1, buf, len, NULL, NULL) < 0)
|
||||
{
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* NOTE: For now, assume non-Windows platforms'
|
||||
* locale is already UTF-8. */
|
||||
len = wcstombs(NULL, str, 0) + 1;
|
||||
|
||||
if (len)
|
||||
{
|
||||
buf = (char*)calloc(len, sizeof(char));
|
||||
|
||||
if (!buf)
|
||||
return NULL;
|
||||
|
||||
if (wcstombs(buf, str, len) == (size_t)-1)
|
||||
{
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return buf;
|
||||
}
|
|
@ -1,877 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (features_cpu.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <direct.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <compat/strl.h>
|
||||
#include <streams/file_stream.h>
|
||||
#include <libretro.h>
|
||||
#include <features/features_cpu.h>
|
||||
#include <retro_timers.h>
|
||||
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef __PSL1GHT__
|
||||
#include <lv2/systime.h>
|
||||
#endif
|
||||
|
||||
#if defined(_XBOX360)
|
||||
#include <PPCIntrinsics.h>
|
||||
#elif !defined(__MACH__) && (defined(__POWERPC__) || defined(__powerpc__) || defined(__ppc__) || defined(__PPC64__) || defined(__powerpc64__))
|
||||
#ifndef _PPU_INTRINSICS_H
|
||||
#include <ppu_intrinsics.h>
|
||||
#endif
|
||||
#elif defined(_POSIX_MONOTONIC_CLOCK) || defined(ANDROID) || defined(__QNX__) || defined(DJGPP)
|
||||
/* POSIX_MONOTONIC_CLOCK is not being defined in Android headers despite support being present. */
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#if defined(__QNX__) && !defined(CLOCK_MONOTONIC)
|
||||
#define CLOCK_MONOTONIC 2
|
||||
#endif
|
||||
|
||||
#if defined(PSP)
|
||||
#include <pspkernel.h>
|
||||
#endif
|
||||
|
||||
#if defined(PSP) || defined(__PSL1GHT__)
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#if defined(PSP)
|
||||
#include <psprtc.h>
|
||||
#endif
|
||||
|
||||
#if defined(VITA)
|
||||
#include <psp2/kernel/processmgr.h>
|
||||
#include <psp2/rtc.h>
|
||||
#endif
|
||||
|
||||
#if defined(PS2)
|
||||
#include <ps2sdkapi.h>
|
||||
#endif
|
||||
|
||||
#if !defined(__PSL1GHT__) && defined(__PS3__)
|
||||
#include <sys/sys_time.h>
|
||||
#endif
|
||||
|
||||
#ifdef GEKKO
|
||||
#include <ogc/lwp_watchdog.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIIU
|
||||
#include <wiiu/os/time.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_LIBNX)
|
||||
#include <switch.h>
|
||||
#elif defined(SWITCH)
|
||||
#include <libtransistor/types.h>
|
||||
#include <libtransistor/svc.h>
|
||||
#endif
|
||||
|
||||
#if defined(_3DS)
|
||||
#include <3ds/svc.h>
|
||||
#include <3ds/os.h>
|
||||
#include <3ds/services/cfgu.h>
|
||||
#endif
|
||||
|
||||
/* iOS/OSX specific. Lacks clock_gettime(), so implement it. */
|
||||
#ifdef __MACH__
|
||||
#include <sys/time.h>
|
||||
|
||||
#ifndef CLOCK_MONOTONIC
|
||||
#define CLOCK_MONOTONIC 0
|
||||
#endif
|
||||
|
||||
#ifndef CLOCK_REALTIME
|
||||
#define CLOCK_REALTIME 0
|
||||
#endif
|
||||
|
||||
/* this function is part of iOS 10 now */
|
||||
static int ra_clock_gettime(int clk_ik, struct timespec *t)
|
||||
{
|
||||
struct timeval now;
|
||||
int rv = gettimeofday(&now, NULL);
|
||||
if (rv)
|
||||
return rv;
|
||||
t->tv_sec = now.tv_sec;
|
||||
t->tv_nsec = now.tv_usec * 1000;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__MACH__) && __IPHONE_OS_VERSION_MIN_REQUIRED < 100000
|
||||
#else
|
||||
#define ra_clock_gettime clock_gettime
|
||||
#endif
|
||||
|
||||
#ifdef EMSCRIPTEN
|
||||
#include <emscripten.h>
|
||||
#endif
|
||||
|
||||
#if defined(BSD) || defined(__APPLE__)
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* cpu_features_get_perf_counter:
|
||||
*
|
||||
* Gets performance counter.
|
||||
*
|
||||
* Returns: performance counter.
|
||||
**/
|
||||
retro_perf_tick_t cpu_features_get_perf_counter(void)
|
||||
{
|
||||
retro_perf_tick_t time_ticks = 0;
|
||||
#if defined(_WIN32)
|
||||
long tv_sec, tv_usec;
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1200
|
||||
static const unsigned __int64 epoch = 11644473600000000;
|
||||
#else
|
||||
static const unsigned __int64 epoch = 11644473600000000ULL;
|
||||
#endif
|
||||
FILETIME file_time;
|
||||
SYSTEMTIME system_time;
|
||||
ULARGE_INTEGER ularge;
|
||||
|
||||
GetSystemTime(&system_time);
|
||||
SystemTimeToFileTime(&system_time, &file_time);
|
||||
ularge.LowPart = file_time.dwLowDateTime;
|
||||
ularge.HighPart = file_time.dwHighDateTime;
|
||||
|
||||
tv_sec = (long)((ularge.QuadPart - epoch) / 10000000L);
|
||||
tv_usec = (long)(system_time.wMilliseconds * 1000);
|
||||
time_ticks = (1000000 * tv_sec + tv_usec);
|
||||
#elif defined(GEKKO)
|
||||
time_ticks = gettime();
|
||||
#elif !defined(__MACH__) && (defined(_XBOX360) || defined(__powerpc__) || defined(__ppc__) || defined(__POWERPC__) || defined(__PSL1GHT__) || defined(__PPC64__) || defined(__powerpc64__))
|
||||
time_ticks = __mftb();
|
||||
#elif (defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK > 0) || defined(__QNX__) || defined(ANDROID)
|
||||
struct timespec tv = {0};
|
||||
if (ra_clock_gettime(CLOCK_MONOTONIC, &tv) == 0)
|
||||
time_ticks = (retro_perf_tick_t)tv.tv_sec * 1000000000 +
|
||||
(retro_perf_tick_t)tv.tv_nsec;
|
||||
|
||||
#elif defined(__GNUC__) && defined(__i386__) || defined(__i486__) || defined(__i686__) || defined(_M_X64) || defined(_M_AMD64)
|
||||
__asm__ volatile ("rdtsc" : "=A" (time_ticks));
|
||||
#elif defined(__GNUC__) && defined(__x86_64__) || defined(_M_IX86)
|
||||
unsigned a, d;
|
||||
__asm__ volatile ("rdtsc" : "=a" (a), "=d" (d));
|
||||
time_ticks = (retro_perf_tick_t)a | ((retro_perf_tick_t)d << 32);
|
||||
#elif defined(__ARM_ARCH_6__)
|
||||
__asm__ volatile( "mrc p15, 0, %0, c9, c13, 0" : "=r"(time_ticks) );
|
||||
#elif defined(__aarch64__)
|
||||
__asm__ volatile( "mrs %0, cntvct_el0" : "=r"(time_ticks) );
|
||||
#elif defined(PSP) || defined(VITA)
|
||||
time_ticks = sceKernelGetSystemTimeWide();
|
||||
#elif defined(PS2)
|
||||
time_ticks = ps2_clock();
|
||||
#elif defined(_3DS)
|
||||
time_ticks = svcGetSystemTick();
|
||||
#elif defined(WIIU)
|
||||
time_ticks = OSGetSystemTime();
|
||||
#elif defined(HAVE_LIBNX)
|
||||
time_ticks = armGetSystemTick();
|
||||
#elif defined(EMSCRIPTEN)
|
||||
time_ticks = emscripten_get_now() * 1000;
|
||||
#endif
|
||||
|
||||
return time_ticks;
|
||||
}
|
||||
|
||||
/**
|
||||
* cpu_features_get_time_usec:
|
||||
*
|
||||
* Gets time in microseconds.
|
||||
*
|
||||
* Returns: time in microseconds.
|
||||
**/
|
||||
retro_time_t cpu_features_get_time_usec(void)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
static LARGE_INTEGER freq;
|
||||
LARGE_INTEGER count;
|
||||
|
||||
/* Frequency is guaranteed to not change. */
|
||||
if (!freq.QuadPart && !QueryPerformanceFrequency(&freq))
|
||||
return 0;
|
||||
|
||||
if (!QueryPerformanceCounter(&count))
|
||||
return 0;
|
||||
return (count.QuadPart / freq.QuadPart * 1000000) + (count.QuadPart % freq.QuadPart * 1000000 / freq.QuadPart);
|
||||
#elif defined(__PSL1GHT__)
|
||||
return sysGetSystemTime();
|
||||
#elif !defined(__PSL1GHT__) && defined(__PS3__)
|
||||
return sys_time_get_system_time();
|
||||
#elif defined(GEKKO)
|
||||
return ticks_to_microsecs(gettime());
|
||||
#elif defined(WIIU)
|
||||
return ticks_to_us(OSGetSystemTime());
|
||||
#elif defined(SWITCH) || defined(HAVE_LIBNX)
|
||||
return (svcGetSystemTick() * 10) / 192;
|
||||
#elif defined(_3DS)
|
||||
return osGetTime() * 1000;
|
||||
#elif defined(_POSIX_MONOTONIC_CLOCK) || defined(__QNX__) || defined(ANDROID) || defined(__MACH__) || defined(DJGPP)
|
||||
struct timespec tv = {0};
|
||||
if (ra_clock_gettime(CLOCK_MONOTONIC, &tv) < 0)
|
||||
return 0;
|
||||
return tv.tv_sec * INT64_C(1000000) + (tv.tv_nsec + 500) / 1000;
|
||||
#elif defined(EMSCRIPTEN)
|
||||
return emscripten_get_now() * 1000;
|
||||
#elif defined(PS2)
|
||||
return ps2_clock() / PS2_CLOCKS_PER_MSEC * 1000;
|
||||
#elif defined(VITA) || defined(PSP)
|
||||
return sceKernelGetSystemTimeWide();
|
||||
#else
|
||||
#error "Your platform does not have a timer function implemented in cpu_features_get_time_usec(). Cannot continue."
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(__x86_64__) || defined(__i386__) || defined(__i486__) || defined(__i686__) || (defined(_M_X64) && _MSC_VER > 1310) || (defined(_M_IX86) && _MSC_VER > 1310)
|
||||
#define CPU_X86
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_XBOX)
|
||||
#if (_MSC_VER > 1310)
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(CPU_X86) && !defined(__MACH__)
|
||||
void x86_cpuid(int func, int flags[4])
|
||||
{
|
||||
/* On Android, we compile RetroArch with PIC, and we
|
||||
* are not allowed to clobber the ebx register. */
|
||||
#ifdef __x86_64__
|
||||
#define REG_b "rbx"
|
||||
#define REG_S "rsi"
|
||||
#else
|
||||
#define REG_b "ebx"
|
||||
#define REG_S "esi"
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
__asm__ volatile (
|
||||
"mov %%" REG_b ", %%" REG_S "\n"
|
||||
"cpuid\n"
|
||||
"xchg %%" REG_b ", %%" REG_S "\n"
|
||||
: "=a"(flags[0]), "=S"(flags[1]), "=c"(flags[2]), "=d"(flags[3])
|
||||
: "a"(func));
|
||||
#elif defined(_MSC_VER)
|
||||
__cpuid(flags, func);
|
||||
#else
|
||||
#ifndef NDEBUG
|
||||
printf("Unknown compiler. Cannot check CPUID with inline assembly.\n");
|
||||
#endif
|
||||
memset(flags, 0, 4 * sizeof(int));
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Only runs on i686 and above. Needs to be conditionally run. */
|
||||
static uint64_t xgetbv_x86(uint32_t idx)
|
||||
{
|
||||
#if defined(__GNUC__)
|
||||
uint32_t eax, edx;
|
||||
__asm__ volatile (
|
||||
/* Older GCC versions (Apple's GCC for example) do
|
||||
* not understand xgetbv instruction.
|
||||
* Stamp out the machine code directly.
|
||||
*/
|
||||
".byte 0x0f, 0x01, 0xd0\n"
|
||||
: "=a"(eax), "=d"(edx) : "c"(idx));
|
||||
return ((uint64_t)edx << 32) | eax;
|
||||
#elif _MSC_FULL_VER >= 160040219
|
||||
/* Intrinsic only works on 2010 SP1 and above. */
|
||||
return _xgetbv(idx);
|
||||
#else
|
||||
#ifndef NDEBUG
|
||||
printf("Unknown compiler. Cannot check xgetbv bits.\n");
|
||||
#endif
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__ARM_NEON__)
|
||||
#if defined(__arm__)
|
||||
static void arm_enable_runfast_mode(void)
|
||||
{
|
||||
/* RunFast mode. Enables flush-to-zero and some
|
||||
* floating point optimizations. */
|
||||
static const unsigned x = 0x04086060;
|
||||
static const unsigned y = 0x03000000;
|
||||
int r;
|
||||
__asm__ volatile(
|
||||
"fmrx %0, fpscr \n\t" /* r0 = FPSCR */
|
||||
"and %0, %0, %1 \n\t" /* r0 = r0 & 0x04086060 */
|
||||
"orr %0, %0, %2 \n\t" /* r0 = r0 | 0x03000000 */
|
||||
"fmxr fpscr, %0 \n\t" /* FPSCR = r0 */
|
||||
: "=r"(r)
|
||||
: "r"(x), "r"(y)
|
||||
);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) && !defined(CPU_X86)
|
||||
static unsigned char check_arm_cpu_feature(const char* feature)
|
||||
{
|
||||
char line[1024];
|
||||
unsigned char status = 0;
|
||||
RFILE *fp = filestream_open("/proc/cpuinfo",
|
||||
RETRO_VFS_FILE_ACCESS_READ,
|
||||
RETRO_VFS_FILE_ACCESS_HINT_NONE);
|
||||
|
||||
if (!fp)
|
||||
return 0;
|
||||
|
||||
while (filestream_gets(fp, line, sizeof(line)))
|
||||
{
|
||||
if (strncmp(line, "Features\t: ", 11))
|
||||
continue;
|
||||
|
||||
if (strstr(line + 11, feature))
|
||||
status = 1;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
filestream_close(fp);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#if !defined(_SC_NPROCESSORS_ONLN)
|
||||
/* Parse an decimal integer starting from 'input', but not going further
|
||||
* than 'limit'. Return the value into '*result'.
|
||||
*
|
||||
* NOTE: Does not skip over leading spaces, or deal with sign characters.
|
||||
* NOTE: Ignores overflows.
|
||||
*
|
||||
* The function returns NULL in case of error (bad format), or the new
|
||||
* position after the decimal number in case of success (which will always
|
||||
* be <= 'limit').
|
||||
*/
|
||||
static const char *parse_decimal(const char* input,
|
||||
const char* limit, int* result)
|
||||
{
|
||||
const char* p = input;
|
||||
int val = 0;
|
||||
|
||||
while (p < limit)
|
||||
{
|
||||
int d = (*p - '0');
|
||||
if ((unsigned)d >= 10U)
|
||||
break;
|
||||
val = val*10 + d;
|
||||
p++;
|
||||
}
|
||||
if (p == input)
|
||||
return NULL;
|
||||
|
||||
*result = val;
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Parse a textual list of cpus and store the result inside a CpuList object.
|
||||
* Input format is the following:
|
||||
* - comma-separated list of items (no spaces)
|
||||
* - each item is either a single decimal number (cpu index), or a range made
|
||||
* of two numbers separated by a single dash (-). Ranges are inclusive.
|
||||
*
|
||||
* Examples: 0
|
||||
* 2,4-127,128-143
|
||||
* 0-1
|
||||
*/
|
||||
static void cpulist_parse(CpuList* list, char **buf, ssize_t length)
|
||||
{
|
||||
const char* p = (const char*)buf;
|
||||
const char* end = p + length;
|
||||
|
||||
/* NOTE: the input line coming from sysfs typically contains a
|
||||
* trailing newline, so take care of it in the code below
|
||||
*/
|
||||
while (p < end && *p != '\n')
|
||||
{
|
||||
int val, start_value, end_value;
|
||||
/* Find the end of current item, and put it into 'q' */
|
||||
const char *q = (const char*)memchr(p, ',', end-p);
|
||||
|
||||
if (!q)
|
||||
q = end;
|
||||
|
||||
/* Get first value */
|
||||
if (!(p = parse_decimal(p, q, &start_value)))
|
||||
return;
|
||||
|
||||
end_value = start_value;
|
||||
|
||||
/* If we're not at the end of the item, expect a dash and
|
||||
* and integer; extract end value.
|
||||
*/
|
||||
if (p < q && *p == '-')
|
||||
{
|
||||
if (!(p = parse_decimal(p+1, q, &end_value)))
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set bits CPU list bits */
|
||||
for (val = start_value; val <= end_value; val++)
|
||||
{
|
||||
if ((unsigned)val < 32)
|
||||
list->mask |= (uint32_t)(UINT32_C(1) << val);
|
||||
}
|
||||
|
||||
/* Jump to next item */
|
||||
p = q;
|
||||
if (p < end)
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read a CPU list from one sysfs file */
|
||||
static void cpulist_read_from(CpuList* list, const char* filename)
|
||||
{
|
||||
ssize_t length;
|
||||
char *buf = NULL;
|
||||
|
||||
list->mask = 0;
|
||||
|
||||
if (filestream_read_file(filename, (void**)&buf, &length) != 1)
|
||||
return;
|
||||
|
||||
cpulist_parse(list, &buf, length);
|
||||
if (buf)
|
||||
free(buf);
|
||||
buf = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* cpu_features_get_core_amount:
|
||||
*
|
||||
* Gets the amount of available CPU cores.
|
||||
*
|
||||
* Returns: amount of CPU cores available.
|
||||
**/
|
||||
unsigned cpu_features_get_core_amount(void)
|
||||
{
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
/* Win32 */
|
||||
SYSTEM_INFO sysinfo;
|
||||
#if defined(__WINRT__) || defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
|
||||
GetNativeSystemInfo(&sysinfo);
|
||||
#else
|
||||
GetSystemInfo(&sysinfo);
|
||||
#endif
|
||||
return sysinfo.dwNumberOfProcessors;
|
||||
#elif defined(GEKKO)
|
||||
return 1;
|
||||
#elif defined(PSP) || defined(PS2)
|
||||
return 1;
|
||||
#elif defined(__PSL1GHT__) || !defined(__PSL1GHT__) && defined(__PS3__)
|
||||
return 1; /* Only one PPU, SPUs don't really count */
|
||||
#elif defined(VITA)
|
||||
return 4;
|
||||
#elif defined(HAVE_LIBNX) || defined(SWITCH)
|
||||
return 4;
|
||||
#elif defined(_3DS)
|
||||
u8 device_model = 0xFF;
|
||||
CFGU_GetSystemModel(&device_model);/*(0 = O3DS, 1 = O3DSXL, 2 = N3DS, 3 = 2DS, 4 = N3DSXL, 5 = N2DSXL)*/
|
||||
switch (device_model)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 3:
|
||||
/*Old 3/2DS*/
|
||||
return 2;
|
||||
|
||||
case 2:
|
||||
case 4:
|
||||
case 5:
|
||||
/*New 3/2DS*/
|
||||
return 4;
|
||||
|
||||
default:
|
||||
/*Unknown Device Or Check Failed*/
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
#elif defined(WIIU)
|
||||
return 3;
|
||||
#elif defined(_SC_NPROCESSORS_ONLN)
|
||||
/* Linux, most UNIX-likes. */
|
||||
long ret = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
if (ret <= 0)
|
||||
return (unsigned)1;
|
||||
return (unsigned)ret;
|
||||
#elif defined(BSD) || defined(__APPLE__)
|
||||
/* BSD */
|
||||
/* Copypasta from stackoverflow, dunno if it works. */
|
||||
int num_cpu = 0;
|
||||
int mib[4];
|
||||
size_t len = sizeof(num_cpu);
|
||||
|
||||
mib[0] = CTL_HW;
|
||||
mib[1] = HW_AVAILCPU;
|
||||
sysctl(mib, 2, &num_cpu, &len, NULL, 0);
|
||||
if (num_cpu < 1)
|
||||
{
|
||||
mib[1] = HW_NCPU;
|
||||
sysctl(mib, 2, &num_cpu, &len, NULL, 0);
|
||||
if (num_cpu < 1)
|
||||
num_cpu = 1;
|
||||
}
|
||||
return num_cpu;
|
||||
#elif defined(__linux__)
|
||||
CpuList cpus_present[1];
|
||||
CpuList cpus_possible[1];
|
||||
int amount = 0;
|
||||
|
||||
cpulist_read_from(cpus_present, "/sys/devices/system/cpu/present");
|
||||
cpulist_read_from(cpus_possible, "/sys/devices/system/cpu/possible");
|
||||
|
||||
/* Compute the intersection of both sets to get the actual number of
|
||||
* CPU cores that can be used on this device by the kernel.
|
||||
*/
|
||||
cpus_present->mask &= cpus_possible->mask;
|
||||
amount = __builtin_popcount(cpus_present->mask);
|
||||
|
||||
if (amount == 0)
|
||||
return 1;
|
||||
return amount;
|
||||
#elif defined(_XBOX360)
|
||||
return 3;
|
||||
#else
|
||||
/* No idea, assume single core. */
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* According to http://en.wikipedia.org/wiki/CPUID */
|
||||
#define VENDOR_INTEL_b 0x756e6547
|
||||
#define VENDOR_INTEL_c 0x6c65746e
|
||||
#define VENDOR_INTEL_d 0x49656e69
|
||||
|
||||
/**
|
||||
* cpu_features_get:
|
||||
*
|
||||
* Gets CPU features..
|
||||
*
|
||||
* Returns: bitmask of all CPU features available.
|
||||
**/
|
||||
uint64_t cpu_features_get(void)
|
||||
{
|
||||
uint64_t cpu = 0;
|
||||
#if defined(CPU_X86) && !defined(__MACH__)
|
||||
int vendor_is_intel = 0;
|
||||
const int avx_flags = (1 << 27) | (1 << 28);
|
||||
#endif
|
||||
#if defined(__MACH__)
|
||||
size_t len = sizeof(size_t);
|
||||
|
||||
if (sysctlbyname("hw.optional.floatingpoint", NULL, &len, NULL, 0) == 0)
|
||||
{
|
||||
cpu |= RETRO_SIMD_CMOV;
|
||||
}
|
||||
|
||||
#if defined(CPU_X86)
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.mmx", NULL, &len, NULL, 0) == 0)
|
||||
{
|
||||
cpu |= RETRO_SIMD_MMX;
|
||||
cpu |= RETRO_SIMD_MMXEXT;
|
||||
}
|
||||
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.sse", NULL, &len, NULL, 0) == 0)
|
||||
cpu |= RETRO_SIMD_SSE;
|
||||
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.sse2", NULL, &len, NULL, 0) == 0)
|
||||
cpu |= RETRO_SIMD_SSE2;
|
||||
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.sse3", NULL, &len, NULL, 0) == 0)
|
||||
cpu |= RETRO_SIMD_SSE3;
|
||||
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.supplementalsse3", NULL, &len, NULL, 0) == 0)
|
||||
cpu |= RETRO_SIMD_SSSE3;
|
||||
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.sse4_1", NULL, &len, NULL, 0) == 0)
|
||||
cpu |= RETRO_SIMD_SSE4;
|
||||
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.sse4_2", NULL, &len, NULL, 0) == 0)
|
||||
cpu |= RETRO_SIMD_SSE42;
|
||||
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.aes", NULL, &len, NULL, 0) == 0)
|
||||
cpu |= RETRO_SIMD_AES;
|
||||
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.avx1_0", NULL, &len, NULL, 0) == 0)
|
||||
cpu |= RETRO_SIMD_AVX;
|
||||
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.avx2_0", NULL, &len, NULL, 0) == 0)
|
||||
cpu |= RETRO_SIMD_AVX2;
|
||||
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.altivec", NULL, &len, NULL, 0) == 0)
|
||||
cpu |= RETRO_SIMD_VMX;
|
||||
|
||||
#else
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.neon", NULL, &len, NULL, 0) == 0)
|
||||
cpu |= RETRO_SIMD_NEON;
|
||||
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.neon_fp16", NULL, &len, NULL, 0) == 0)
|
||||
cpu |= RETRO_SIMD_VFPV3;
|
||||
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.neon_hpfp", NULL, &len, NULL, 0) == 0)
|
||||
cpu |= RETRO_SIMD_VFPV4;
|
||||
#endif
|
||||
#elif defined(_XBOX1)
|
||||
cpu |= RETRO_SIMD_MMX;
|
||||
cpu |= RETRO_SIMD_SSE;
|
||||
cpu |= RETRO_SIMD_MMXEXT;
|
||||
#elif defined(CPU_X86)
|
||||
unsigned max_flag = 0;
|
||||
int flags[4];
|
||||
int vendor_shuffle[3];
|
||||
char vendor[13];
|
||||
uint64_t cpu_flags = 0;
|
||||
x86_cpuid(0, flags);
|
||||
vendor_shuffle[0] = flags[1];
|
||||
vendor_shuffle[1] = flags[3];
|
||||
vendor_shuffle[2] = flags[2];
|
||||
|
||||
vendor[0] = '\0';
|
||||
memcpy(vendor, vendor_shuffle, sizeof(vendor_shuffle));
|
||||
|
||||
/* printf("[CPUID]: Vendor: %s\n", vendor); */
|
||||
|
||||
vendor_is_intel = (
|
||||
flags[1] == VENDOR_INTEL_b &&
|
||||
flags[2] == VENDOR_INTEL_c &&
|
||||
flags[3] == VENDOR_INTEL_d);
|
||||
|
||||
max_flag = flags[0];
|
||||
if (max_flag < 1) /* Does CPUID not support func = 1? (unlikely ...) */
|
||||
return 0;
|
||||
|
||||
x86_cpuid(1, flags);
|
||||
|
||||
if (flags[3] & (1 << 15))
|
||||
cpu |= RETRO_SIMD_CMOV;
|
||||
|
||||
if (flags[3] & (1 << 23))
|
||||
cpu |= RETRO_SIMD_MMX;
|
||||
|
||||
if (flags[3] & (1 << 25))
|
||||
{
|
||||
/* SSE also implies MMXEXT (according to FFmpeg source). */
|
||||
cpu |= RETRO_SIMD_SSE;
|
||||
cpu |= RETRO_SIMD_MMXEXT;
|
||||
}
|
||||
|
||||
if (flags[3] & (1 << 26))
|
||||
cpu |= RETRO_SIMD_SSE2;
|
||||
|
||||
if (flags[2] & (1 << 0))
|
||||
cpu |= RETRO_SIMD_SSE3;
|
||||
|
||||
if (flags[2] & (1 << 9))
|
||||
cpu |= RETRO_SIMD_SSSE3;
|
||||
|
||||
if (flags[2] & (1 << 19))
|
||||
cpu |= RETRO_SIMD_SSE4;
|
||||
|
||||
if (flags[2] & (1 << 20))
|
||||
cpu |= RETRO_SIMD_SSE42;
|
||||
|
||||
if ((flags[2] & (1 << 23)))
|
||||
cpu |= RETRO_SIMD_POPCNT;
|
||||
|
||||
if (vendor_is_intel && (flags[2] & (1 << 22)))
|
||||
cpu |= RETRO_SIMD_MOVBE;
|
||||
|
||||
if (flags[2] & (1 << 25))
|
||||
cpu |= RETRO_SIMD_AES;
|
||||
|
||||
/* Must only perform xgetbv check if we have
|
||||
* AVX CPU support (guaranteed to have at least i686). */
|
||||
if (((flags[2] & avx_flags) == avx_flags)
|
||||
&& ((xgetbv_x86(0) & 0x6) == 0x6))
|
||||
cpu |= RETRO_SIMD_AVX;
|
||||
|
||||
if (max_flag >= 7)
|
||||
{
|
||||
x86_cpuid(7, flags);
|
||||
if (flags[1] & (1 << 5))
|
||||
cpu |= RETRO_SIMD_AVX2;
|
||||
}
|
||||
|
||||
x86_cpuid(0x80000000, flags);
|
||||
max_flag = flags[0];
|
||||
if (max_flag >= 0x80000001u)
|
||||
{
|
||||
x86_cpuid(0x80000001, flags);
|
||||
if (flags[3] & (1 << 23))
|
||||
cpu |= RETRO_SIMD_MMX;
|
||||
if (flags[3] & (1 << 22))
|
||||
cpu |= RETRO_SIMD_MMXEXT;
|
||||
}
|
||||
#elif defined(__linux__)
|
||||
if (check_arm_cpu_feature("neon"))
|
||||
{
|
||||
cpu |= RETRO_SIMD_NEON;
|
||||
#if defined(__ARM_NEON__) && defined(__arm__)
|
||||
arm_enable_runfast_mode();
|
||||
#endif
|
||||
}
|
||||
|
||||
if (check_arm_cpu_feature("vfpv3"))
|
||||
cpu |= RETRO_SIMD_VFPV3;
|
||||
|
||||
if (check_arm_cpu_feature("vfpv4"))
|
||||
cpu |= RETRO_SIMD_VFPV4;
|
||||
|
||||
if (check_arm_cpu_feature("asimd"))
|
||||
{
|
||||
cpu |= RETRO_SIMD_ASIMD;
|
||||
#ifdef __ARM_NEON__
|
||||
cpu |= RETRO_SIMD_NEON;
|
||||
#if defined(__arm__)
|
||||
arm_enable_runfast_mode();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
check_arm_cpu_feature("swp");
|
||||
check_arm_cpu_feature("half");
|
||||
check_arm_cpu_feature("thumb");
|
||||
check_arm_cpu_feature("fastmult");
|
||||
check_arm_cpu_feature("vfp");
|
||||
check_arm_cpu_feature("edsp");
|
||||
check_arm_cpu_feature("thumbee");
|
||||
check_arm_cpu_feature("tls");
|
||||
check_arm_cpu_feature("idiva");
|
||||
check_arm_cpu_feature("idivt");
|
||||
#endif
|
||||
|
||||
#elif defined(__ARM_NEON__)
|
||||
cpu |= RETRO_SIMD_NEON;
|
||||
#if defined(__arm__)
|
||||
arm_enable_runfast_mode();
|
||||
#endif
|
||||
#elif defined(__ALTIVEC__)
|
||||
cpu |= RETRO_SIMD_VMX;
|
||||
#elif defined(XBOX360)
|
||||
cpu |= RETRO_SIMD_VMX128;
|
||||
#elif defined(PSP) || defined(PS2)
|
||||
cpu |= RETRO_SIMD_VFPU;
|
||||
#elif defined(GEKKO)
|
||||
cpu |= RETRO_SIMD_PS;
|
||||
#endif
|
||||
|
||||
return cpu;
|
||||
}
|
||||
|
||||
void cpu_features_get_model_name(char *name, int len)
|
||||
{
|
||||
#if defined(CPU_X86) && !defined(__MACH__)
|
||||
union {
|
||||
int i[4];
|
||||
unsigned char s[16];
|
||||
} flags;
|
||||
int i, j;
|
||||
size_t pos = 0;
|
||||
bool start = false;
|
||||
|
||||
if (!name)
|
||||
return;
|
||||
|
||||
x86_cpuid(0x80000000, flags.i);
|
||||
|
||||
if (flags.i[0] < 0x80000004)
|
||||
return;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
memset(flags.i, 0, sizeof(flags.i));
|
||||
x86_cpuid(0x80000002 + i, flags.i);
|
||||
|
||||
for (j = 0; j < sizeof(flags.s); j++)
|
||||
{
|
||||
if (!start && flags.s[j] == ' ')
|
||||
continue;
|
||||
else
|
||||
start = true;
|
||||
|
||||
if (pos == len - 1)
|
||||
{
|
||||
/* truncate if we ran out of room */
|
||||
name[pos] = '\0';
|
||||
goto end;
|
||||
}
|
||||
|
||||
name[pos++] = flags.s[j];
|
||||
}
|
||||
}
|
||||
end:
|
||||
/* terminate our string */
|
||||
if (pos < (size_t)len)
|
||||
name[pos] = '\0';
|
||||
#elif defined(__MACH__)
|
||||
if (!name)
|
||||
return;
|
||||
{
|
||||
size_t len_size = len;
|
||||
sysctlbyname("machdep.cpu.brand_string", name, &len_size, NULL, 0);
|
||||
}
|
||||
#else
|
||||
if (!name)
|
||||
return;
|
||||
return;
|
||||
#endif
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,171 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (config_file_userdata.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <file/file_path.h>
|
||||
#include <lists/string_list.h>
|
||||
|
||||
#include <file/config_file_userdata.h>
|
||||
|
||||
int config_userdata_get_float(void *userdata, const char *key_str,
|
||||
float *value, float default_value)
|
||||
{
|
||||
bool got;
|
||||
char key[2][256];
|
||||
struct config_file_userdata *usr = (struct config_file_userdata*)userdata;
|
||||
|
||||
fill_pathname_join_delim(key[0], usr->prefix[0], key_str, '_', sizeof(key[0]));
|
||||
fill_pathname_join_delim(key[1], usr->prefix[1], key_str, '_', sizeof(key[1]));
|
||||
|
||||
got = config_get_float (usr->conf, key[0], value);
|
||||
got = got || config_get_float(usr->conf, key[1], value);
|
||||
|
||||
if (!got)
|
||||
*value = default_value;
|
||||
return got;
|
||||
}
|
||||
|
||||
int config_userdata_get_int(void *userdata, const char *key_str,
|
||||
int *value, int default_value)
|
||||
{
|
||||
bool got;
|
||||
char key[2][256];
|
||||
struct config_file_userdata *usr = (struct config_file_userdata*)userdata;
|
||||
|
||||
fill_pathname_join_delim(key[0], usr->prefix[0], key_str, '_', sizeof(key[0]));
|
||||
fill_pathname_join_delim(key[1], usr->prefix[1], key_str, '_', sizeof(key[1]));
|
||||
|
||||
got = config_get_int (usr->conf, key[0], value);
|
||||
got = got || config_get_int(usr->conf, key[1], value);
|
||||
|
||||
if (!got)
|
||||
*value = default_value;
|
||||
return got;
|
||||
}
|
||||
|
||||
int config_userdata_get_hex(void *userdata, const char *key_str,
|
||||
unsigned *value, unsigned default_value)
|
||||
{
|
||||
bool got;
|
||||
char key[2][256];
|
||||
struct config_file_userdata *usr = (struct config_file_userdata*)userdata;
|
||||
|
||||
fill_pathname_join_delim(key[0], usr->prefix[0], key_str, '_', sizeof(key[0]));
|
||||
fill_pathname_join_delim(key[1], usr->prefix[1], key_str, '_', sizeof(key[1]));
|
||||
|
||||
got = config_get_hex(usr->conf, key[0], value);
|
||||
got = got || config_get_hex(usr->conf, key[1], value);
|
||||
|
||||
if (!got)
|
||||
*value = default_value;
|
||||
return got;
|
||||
}
|
||||
|
||||
int config_userdata_get_float_array(void *userdata, const char *key_str,
|
||||
float **values, unsigned *out_num_values,
|
||||
const float *default_values, unsigned num_default_values)
|
||||
{
|
||||
char key[2][256];
|
||||
struct config_file_userdata *usr = (struct config_file_userdata*)userdata;
|
||||
char *str = NULL;
|
||||
|
||||
fill_pathname_join_delim(key[0], usr->prefix[0], key_str, '_', sizeof(key[0]));
|
||||
fill_pathname_join_delim(key[1], usr->prefix[1], key_str, '_', sizeof(key[1]));
|
||||
|
||||
if ( config_get_string(usr->conf, key[0], &str) ||
|
||||
config_get_string(usr->conf, key[1], &str))
|
||||
{
|
||||
unsigned i;
|
||||
struct string_list list = {0};
|
||||
string_list_initialize(&list);
|
||||
string_split_noalloc(&list, str, " ");
|
||||
*values = (float*)calloc(list.size, sizeof(float));
|
||||
for (i = 0; i < list.size; i++)
|
||||
(*values)[i] = (float)strtod(list.elems[i].data, NULL);
|
||||
*out_num_values = (unsigned)list.size;
|
||||
string_list_deinitialize(&list);
|
||||
free(str);
|
||||
return true;
|
||||
}
|
||||
|
||||
*values = (float*)calloc(num_default_values, sizeof(float));
|
||||
memcpy(*values, default_values, sizeof(float) * num_default_values);
|
||||
*out_num_values = num_default_values;
|
||||
return false;
|
||||
}
|
||||
|
||||
int config_userdata_get_int_array(void *userdata, const char *key_str,
|
||||
int **values, unsigned *out_num_values,
|
||||
const int *default_values, unsigned num_default_values)
|
||||
{
|
||||
char key[2][256];
|
||||
struct config_file_userdata *usr = (struct config_file_userdata*)userdata;
|
||||
char *str = NULL;
|
||||
fill_pathname_join_delim(key[0], usr->prefix[0], key_str, '_', sizeof(key[0]));
|
||||
fill_pathname_join_delim(key[1], usr->prefix[1], key_str, '_', sizeof(key[1]));
|
||||
|
||||
if ( config_get_string(usr->conf, key[0], &str) ||
|
||||
config_get_string(usr->conf, key[1], &str))
|
||||
{
|
||||
unsigned i;
|
||||
struct string_list list = {0};
|
||||
string_list_initialize(&list);
|
||||
string_split_noalloc(&list, str, " ");
|
||||
*values = (int*)calloc(list.size, sizeof(int));
|
||||
for (i = 0; i < list.size; i++)
|
||||
(*values)[i] = (int)strtod(list.elems[i].data, NULL);
|
||||
*out_num_values = (unsigned)list.size;
|
||||
string_list_deinitialize(&list);
|
||||
free(str);
|
||||
return true;
|
||||
}
|
||||
|
||||
*values = (int*)calloc(num_default_values, sizeof(int));
|
||||
memcpy(*values, default_values, sizeof(int) * num_default_values);
|
||||
*out_num_values = num_default_values;
|
||||
return false;
|
||||
}
|
||||
|
||||
int config_userdata_get_string(void *userdata, const char *key_str,
|
||||
char **output, const char *default_output)
|
||||
{
|
||||
char key[2][256];
|
||||
struct config_file_userdata *usr = (struct config_file_userdata*)userdata;
|
||||
char *str = NULL;
|
||||
fill_pathname_join_delim(key[0], usr->prefix[0], key_str, '_', sizeof(key[0]));
|
||||
fill_pathname_join_delim(key[1], usr->prefix[1], key_str, '_', sizeof(key[1]));
|
||||
|
||||
if ( config_get_string(usr->conf, key[0], &str) ||
|
||||
config_get_string(usr->conf, key[1], &str))
|
||||
{
|
||||
*output = str;
|
||||
return true;
|
||||
}
|
||||
|
||||
*output = strdup(default_output);
|
||||
return false;
|
||||
}
|
||||
|
||||
void config_userdata_free(void *ptr)
|
||||
{
|
||||
if (ptr)
|
||||
free(ptr);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,151 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (file_path_io.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <boolean.h>
|
||||
#include <file/file_path.h>
|
||||
#include <retro_assert.h>
|
||||
#include <compat/strl.h>
|
||||
#include <compat/posix_string.h>
|
||||
#include <retro_miscellaneous.h>
|
||||
#include <string/stdstring.h>
|
||||
#define VFS_FRONTEND
|
||||
#include <vfs/vfs_implementation.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
#else
|
||||
#include <unistd.h> /* stat() is defined here */
|
||||
#endif
|
||||
|
||||
/* TODO/FIXME - globals */
|
||||
static retro_vfs_stat_t path_stat_cb = retro_vfs_stat_impl;
|
||||
static retro_vfs_mkdir_t path_mkdir_cb = retro_vfs_mkdir_impl;
|
||||
|
||||
void path_vfs_init(const struct retro_vfs_interface_info* vfs_info)
|
||||
{
|
||||
const struct retro_vfs_interface*
|
||||
vfs_iface = vfs_info->iface;
|
||||
|
||||
path_stat_cb = retro_vfs_stat_impl;
|
||||
path_mkdir_cb = retro_vfs_mkdir_impl;
|
||||
|
||||
if (vfs_info->required_interface_version < PATH_REQUIRED_VFS_VERSION || !vfs_iface)
|
||||
return;
|
||||
|
||||
path_stat_cb = vfs_iface->stat;
|
||||
path_mkdir_cb = vfs_iface->mkdir;
|
||||
}
|
||||
|
||||
int path_stat(const char *path)
|
||||
{
|
||||
return path_stat_cb(path, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* path_is_directory:
|
||||
* @path : path
|
||||
*
|
||||
* Checks if path is a directory.
|
||||
*
|
||||
* Returns: true (1) if path is a directory, otherwise false (0).
|
||||
*/
|
||||
bool path_is_directory(const char *path)
|
||||
{
|
||||
return (path_stat_cb(path, NULL) & RETRO_VFS_STAT_IS_DIRECTORY) != 0;
|
||||
}
|
||||
|
||||
bool path_is_character_special(const char *path)
|
||||
{
|
||||
return (path_stat_cb(path, NULL) & RETRO_VFS_STAT_IS_CHARACTER_SPECIAL) != 0;
|
||||
}
|
||||
|
||||
bool path_is_valid(const char *path)
|
||||
{
|
||||
return (path_stat_cb(path, NULL) & RETRO_VFS_STAT_IS_VALID) != 0;
|
||||
}
|
||||
|
||||
int32_t path_get_size(const char *path)
|
||||
{
|
||||
int32_t filesize = 0;
|
||||
if (path_stat_cb(path, &filesize) != 0)
|
||||
return filesize;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* path_mkdir:
|
||||
* @dir : directory
|
||||
*
|
||||
* Create directory on filesystem.
|
||||
*
|
||||
* Returns: true (1) if directory could be created, otherwise false (0).
|
||||
**/
|
||||
bool path_mkdir(const char *dir)
|
||||
{
|
||||
bool norecurse = false;
|
||||
char *basedir = NULL;
|
||||
|
||||
if (!(dir && *dir))
|
||||
return false;
|
||||
|
||||
/* Use heap. Real chance of stack
|
||||
* overflow if we recurse too hard. */
|
||||
basedir = strdup(dir);
|
||||
|
||||
if (!basedir)
|
||||
return false;
|
||||
|
||||
path_parent_dir(basedir);
|
||||
|
||||
if (!*basedir || !strcmp(basedir, dir))
|
||||
{
|
||||
free(basedir);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( path_is_directory(basedir)
|
||||
|| path_mkdir(basedir))
|
||||
norecurse = true;
|
||||
|
||||
free(basedir);
|
||||
|
||||
if (norecurse)
|
||||
{
|
||||
int ret = path_mkdir_cb(dir);
|
||||
|
||||
/* Don't treat this as an error. */
|
||||
if (ret == -2 && path_is_directory(dir))
|
||||
return true;
|
||||
else if (ret == 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
|
@ -1,284 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (rhmap.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __LIBRETRO_SDK_ARRAY_RHMAP_H__
|
||||
#define __LIBRETRO_SDK_ARRAY_RHMAP_H__
|
||||
|
||||
/*
|
||||
* This file implements a hash map with 32-bit keys.
|
||||
* Based on the implementation from the public domain Bitwise project
|
||||
* by Per Vognsen - https://github.com/pervognsen/bitwise
|
||||
*
|
||||
* It's a super simple type safe hash map for C with no need
|
||||
* to predeclare any type or anything.
|
||||
* Will always allocate memory for twice the amount of max elements
|
||||
* so larger structs should be stored as pointers or indices to an array.
|
||||
* Can be used in C++ with POD types (without any constructor/destructor).
|
||||
*
|
||||
* Be careful not to supply modifying statements to the macro arguments.
|
||||
* Something like RHMAP_FIT(map, i++); would have unintended results.
|
||||
*
|
||||
* Sample usage:
|
||||
*
|
||||
* -- Set 2 elements with string keys and mytype_t values:
|
||||
* mytype_t* map = NULL;
|
||||
* RHMAP_SET_STR(map, "foo", foo_element);
|
||||
* RHMAP_SET_STR(map, "bar", bar_element);
|
||||
* -- now RHMAP_LEN(map) == 2, RHMAP_GET_STR(map, "foo") == foo_element
|
||||
*
|
||||
* -- Check if keys exist:
|
||||
* bool has_foo = RHMAP_HAS_STR(map, "foo");
|
||||
* bool has_baz = RHMAP_HAS_STR(map, "baz");
|
||||
* -- now has_foo == true, has_baz == false
|
||||
*
|
||||
* -- Removing a key:
|
||||
* bool removed = RHMAP_DEL_STR(map, "bar");
|
||||
* bool removed_again = RHMAP_DEL_STR(map, "bar");
|
||||
* -- now RHMAP_LEN(map) == 1, removed == true, removed_again == false
|
||||
*
|
||||
* -- Add/modify via pointer:
|
||||
* mytype_t* p_elem = RHMAP_PTR_STR(map, "qux");
|
||||
* p_elem->a = 123;
|
||||
* -- New keys initially have memory uninitialized
|
||||
* -- Pointers can get invalidated when a key is added/removed
|
||||
*
|
||||
* -- Looking up the index for a given key:
|
||||
* ptrdiff_t idx_foo = RHMAP_IDX_STR(map, "foo");
|
||||
* ptrdiff_t idx_invalid = RHMAP_IDX_STR(map, "invalid");
|
||||
* -- now idx_foo >= 0, idx_invalid == -1, map[idx_foo] == foo_element
|
||||
* -- Indices can change when a key is added/removed
|
||||
*
|
||||
* -- Clear all elements (keep memory allocated):
|
||||
* RHMAP_CLEAR(map);
|
||||
* -- now RHMAP_LEN(map) == 0, RHMAP_CAP(map) == 16
|
||||
*
|
||||
* -- Reserve memory for at least N elements:
|
||||
* RHMAP_FIT(map, 30);
|
||||
* -- now RHMAP_LEN(map) == 0, RHMAP_CAP(map) == 64
|
||||
*
|
||||
* -- Add elements with custom hash keys:
|
||||
* RHMAP_SET(map, my_uint32_hash(key1), some_element);
|
||||
* RHMAP_SET(map, my_uint32_hash(key2), other_element);
|
||||
* -- now RHMAP_LEN(map) == 2, _GET/_HAS/_DEL/_PTR/_IDX also exist
|
||||
*
|
||||
* -- Iterate elements (random order, order can change on insert):
|
||||
* for (size_t i = 0, cap = RHMAP_CAP(map); i != cap, i++)
|
||||
* if (RHMAP_KEY(map, i))
|
||||
* ------ here map[i] is the value of key RHMAP_KEY(map, i)
|
||||
*
|
||||
* -- Set a custom null value (is zeroed by default):
|
||||
* RHMAP_SETNULLVAL(map, map_null);
|
||||
* -- now RHMAP_GET_STR(map, "invalid") == map_null
|
||||
*
|
||||
* -- Free allocated memory:
|
||||
* RHMAP_FREE(map);
|
||||
* -- now map == NULL, RHMAP_LEN(map) == 0, RHMAP_CAP(map) == 0
|
||||
*
|
||||
* -- To handle running out of memory:
|
||||
* bool ran_out_of_memory = !RHMAP_TRYFIT(map, 1000);
|
||||
* -- before setting an element (with SET, PTR or NULLVAL).
|
||||
* -- When out of memory, map will stay unmodified.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h> /* for malloc, realloc */
|
||||
#include <string.h> /* for memcpy, memset */
|
||||
#include <stddef.h> /* for ptrdiff_t, size_t */
|
||||
#include <stdint.h> /* for uint32_t */
|
||||
|
||||
#define RHMAP_LEN(b) ((b) ? RHMAP__HDR(b)->len : 0)
|
||||
#define RHMAP_MAX(b) ((b) ? RHMAP__HDR(b)->maxlen : 0)
|
||||
#define RHMAP_CAP(b) ((b) ? RHMAP__HDR(b)->maxlen + 1 : 0)
|
||||
#define RHMAP_KEY(b, idx) (RHMAP__HDR(b)->keys[idx])
|
||||
#define RHMAP_KEY_STR(b, idx) (RHMAP__HDR(b)->key_strs[idx])
|
||||
#define RHMAP_SETNULLVAL(b, val) (RHMAP__FIT1(b), b[-1] = (val))
|
||||
#define RHMAP_CLEAR(b) ((b) ? (memset(RHMAP__HDR(b)->keys, 0, RHMAP_CAP(b) * sizeof(uint32_t)), RHMAP__HDR(b)->len = 0) : 0)
|
||||
#define RHMAP_FREE(b) ((b) ? (rhmap__free(RHMAP__HDR(b)), (b) = NULL) : 0)
|
||||
#define RHMAP_FIT(b, n) ((!(n) || ((b) && (size_t)(n) * 2 <= RHMAP_MAX(b))) ? 0 : RHMAP__GROW(b, n))
|
||||
#define RHMAP_TRYFIT(b, n) (RHMAP_FIT((b), (n)), (!(n) || ((b) && (size_t)(n) * 2 <= RHMAP_MAX(b))))
|
||||
|
||||
#define RHMAP_SET(b, key, val) RHMAP_SET_FULL(b, key, NULL, val)
|
||||
#define RHMAP_GET(b, key) RHMAP_GET_FULL(b, key, NULL)
|
||||
#define RHMAP_HAS(b, key) RHMAP_HAS_FULL(b, key, NULL)
|
||||
#define RHMAP_DEL(b, key) RHMAP_DEL_FULL(b, key, NULL)
|
||||
#define RHMAP_PTR(b, key) RHMAP_PTR_FULL(b, key, NULL)
|
||||
#define RHMAP_IDX(b, key) RHMAP_IDX_FULL(b, key, NULL)
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define RHMAP__UNUSED __attribute__((__unused__))
|
||||
#else
|
||||
#define RHMAP__UNUSED
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4505) //unreferenced local function has been removed
|
||||
#endif
|
||||
|
||||
#define RHMAP_SET_FULL(b, key, str, val) (RHMAP__FIT1(b), b[rhmap__idx(RHMAP__HDR(b), (key), (str), 1, 0)] = (val))
|
||||
#define RHMAP_GET_FULL(b, key, str) (RHMAP__FIT1(b), b[rhmap__idx(RHMAP__HDR(b), (key), (str), 0, 0)])
|
||||
#define RHMAP_HAS_FULL(b, key, str) ((b) ? rhmap__idx(RHMAP__HDR(b), (key), (str), 0, 0) != -1 : 0)
|
||||
#define RHMAP_DEL_FULL(b, key, str) ((b) ? rhmap__idx(RHMAP__HDR(b), (key), (str), 0, sizeof(*(b))) != -1 : 0)
|
||||
#define RHMAP_PTR_FULL(b, key, str) (RHMAP__FIT1(b), &b[rhmap__idx(RHMAP__HDR(b), (key), (str), 1, 0)])
|
||||
#define RHMAP_IDX_FULL(b, key, str) ((b) ? rhmap__idx(RHMAP__HDR(b), (key), (str), 0, 0) : -1)
|
||||
|
||||
#define RHMAP_SET_STR(b, string_key, val) RHMAP_SET_FULL(b, rhmap_hash_string(string_key), string_key, val)
|
||||
#define RHMAP_GET_STR(b, string_key) RHMAP_GET_FULL(b, rhmap_hash_string(string_key), string_key)
|
||||
#define RHMAP_HAS_STR(b, string_key) RHMAP_HAS_FULL(b, rhmap_hash_string(string_key), string_key)
|
||||
#define RHMAP_DEL_STR(b, string_key) RHMAP_DEL_FULL(b, rhmap_hash_string(string_key), string_key)
|
||||
#define RHMAP_PTR_STR(b, string_key) RHMAP_PTR_FULL(b, rhmap_hash_string(string_key), string_key)
|
||||
#define RHMAP_IDX_STR(b, string_key) RHMAP_IDX_FULL(b, rhmap_hash_string(string_key), string_key)
|
||||
|
||||
RHMAP__UNUSED static uint32_t rhmap_hash_string(const char* str)
|
||||
{
|
||||
unsigned char c;
|
||||
uint32_t hash = (uint32_t)0x811c9dc5;
|
||||
while ((c = (unsigned char)*(str++)) != '\0')
|
||||
hash = ((hash * (uint32_t)0x01000193) ^ (uint32_t)c);
|
||||
return (hash ? hash : 1);
|
||||
}
|
||||
|
||||
struct rhmap__hdr { size_t len, maxlen; uint32_t *keys; char** key_strs; };
|
||||
#define RHMAP__HDR(b) (((struct rhmap__hdr *)&(b)[-1])-1)
|
||||
#define RHMAP__GROW(b, n) (*(void**)(&(b)) = rhmap__grow(RHMAP__HDR(b), (void*)(b), sizeof(*(b)), (size_t)(n)))
|
||||
#define RHMAP__FIT1(b) ((b) && RHMAP_LEN(b) * 2 <= RHMAP_MAX(b) ? 0 : RHMAP__GROW(b, 0))
|
||||
|
||||
RHMAP__UNUSED static void* rhmap__grow(struct rhmap__hdr *old_hdr, void* old_ptr, size_t elem_size, size_t reserve)
|
||||
{
|
||||
struct rhmap__hdr *new_hdr;
|
||||
char *new_vals;
|
||||
size_t new_max = (old_ptr ? old_hdr->maxlen * 2 + 1 : 15);
|
||||
while (new_max && new_max / 2 <= reserve)
|
||||
if (!(new_max = new_max * 2 + 1))
|
||||
return old_ptr; /* overflow */
|
||||
|
||||
new_hdr = (struct rhmap__hdr *)malloc(sizeof(struct rhmap__hdr) + (new_max + 2) * elem_size);
|
||||
if (!new_hdr)
|
||||
return old_ptr; /* out of memory */
|
||||
|
||||
new_hdr->maxlen = new_max;
|
||||
new_hdr->keys = (uint32_t *)calloc(new_max + 1, sizeof(uint32_t));
|
||||
if (!new_hdr->keys)
|
||||
{
|
||||
/* out of memory */
|
||||
free(new_hdr);
|
||||
return old_ptr;
|
||||
}
|
||||
new_hdr->key_strs = (char**)calloc(new_max + 1, sizeof(char*));
|
||||
if (!new_hdr->key_strs)
|
||||
{
|
||||
/* out of memory */
|
||||
free(new_hdr->keys);
|
||||
free(new_hdr);
|
||||
return old_ptr;
|
||||
}
|
||||
|
||||
new_vals = ((char*)(new_hdr + 1)) + elem_size;
|
||||
if (old_ptr)
|
||||
{
|
||||
size_t i;
|
||||
char* old_vals = ((char*)(old_hdr + 1)) + elem_size;
|
||||
for (i = 0; i <= old_hdr->maxlen; i++)
|
||||
{
|
||||
uint32_t key, j;
|
||||
if (!old_hdr->keys[i])
|
||||
continue;
|
||||
for (key = old_hdr->keys[i], j = key;; j++)
|
||||
{
|
||||
if (!new_hdr->keys[j &= new_hdr->maxlen])
|
||||
{
|
||||
new_hdr->keys[j] = key;
|
||||
new_hdr->key_strs[j] = old_hdr->key_strs[i];
|
||||
memcpy(new_vals + j * elem_size, old_vals + i * elem_size, elem_size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
memcpy(new_vals - elem_size, old_vals - elem_size, elem_size);
|
||||
new_hdr->len = old_hdr->len;
|
||||
free(old_hdr->keys);
|
||||
free(old_hdr->key_strs);
|
||||
free(old_hdr);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(new_vals - elem_size, 0, elem_size);
|
||||
new_hdr->len = 0;
|
||||
}
|
||||
return new_vals;
|
||||
}
|
||||
|
||||
RHMAP__UNUSED static ptrdiff_t rhmap__idx(struct rhmap__hdr* hdr, uint32_t key, const char * str, int add, size_t del)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
if (!key)
|
||||
return (ptrdiff_t)-1;
|
||||
|
||||
for (i = key;; i++)
|
||||
{
|
||||
if (hdr->keys[i &= hdr->maxlen] == key && (!hdr->key_strs[i] || !str || !strcmp(hdr->key_strs[i], str)))
|
||||
{
|
||||
if (del)
|
||||
{
|
||||
hdr->len--;
|
||||
hdr->keys[i] = 0;
|
||||
free(hdr->key_strs[i]);
|
||||
hdr->key_strs[i] = NULL;
|
||||
while ((key = hdr->keys[i = (i + 1) & hdr->maxlen]) != 0)
|
||||
{
|
||||
if ((key = (uint32_t)rhmap__idx(hdr, key, str, 1, 0)) == i) continue;
|
||||
hdr->len--;
|
||||
hdr->keys[i] = 0;
|
||||
free(hdr->key_strs[i]);
|
||||
hdr->key_strs[i] = NULL;
|
||||
memcpy(((char*)(hdr + 1)) + (key + 1) * del,
|
||||
((char*)(hdr + 1)) + (i + 1) * del, del);
|
||||
}
|
||||
}
|
||||
return (ptrdiff_t)i;
|
||||
}
|
||||
if (!hdr->keys[i])
|
||||
{
|
||||
if (add) { hdr->len++; hdr->keys[i] = key; if (str) hdr->key_strs[i] = strdup(str); return (ptrdiff_t)i; }
|
||||
return (ptrdiff_t)-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RHMAP__UNUSED static void rhmap__free(struct rhmap__hdr* hdr)
|
||||
{
|
||||
size_t i;
|
||||
for (i=0;i<hdr->maxlen+1;i++)
|
||||
{
|
||||
free(hdr->key_strs[i]);
|
||||
}
|
||||
free(hdr->key_strs);
|
||||
free(hdr->keys);
|
||||
free(hdr);
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,208 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (audio_resampler.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __LIBRETRO_SDK_AUDIO_RESAMPLER_DRIVER_H
|
||||
#define __LIBRETRO_SDK_AUDIO_RESAMPLER_DRIVER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <boolean.h>
|
||||
#include <retro_common_api.h>
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
#define RESAMPLER_SIMD_SSE (1 << 0)
|
||||
#define RESAMPLER_SIMD_SSE2 (1 << 1)
|
||||
#define RESAMPLER_SIMD_VMX (1 << 2)
|
||||
#define RESAMPLER_SIMD_VMX128 (1 << 3)
|
||||
#define RESAMPLER_SIMD_AVX (1 << 4)
|
||||
#define RESAMPLER_SIMD_NEON (1 << 5)
|
||||
#define RESAMPLER_SIMD_SSE3 (1 << 6)
|
||||
#define RESAMPLER_SIMD_SSSE3 (1 << 7)
|
||||
#define RESAMPLER_SIMD_MMX (1 << 8)
|
||||
#define RESAMPLER_SIMD_MMXEXT (1 << 9)
|
||||
#define RESAMPLER_SIMD_SSE4 (1 << 10)
|
||||
#define RESAMPLER_SIMD_SSE42 (1 << 11)
|
||||
#define RESAMPLER_SIMD_AVX2 (1 << 12)
|
||||
#define RESAMPLER_SIMD_VFPU (1 << 13)
|
||||
#define RESAMPLER_SIMD_PS (1 << 14)
|
||||
|
||||
enum resampler_quality
|
||||
{
|
||||
RESAMPLER_QUALITY_DONTCARE = 0,
|
||||
RESAMPLER_QUALITY_LOWEST,
|
||||
RESAMPLER_QUALITY_LOWER,
|
||||
RESAMPLER_QUALITY_NORMAL,
|
||||
RESAMPLER_QUALITY_HIGHER,
|
||||
RESAMPLER_QUALITY_HIGHEST
|
||||
};
|
||||
|
||||
/* A bit-mask of all supported SIMD instruction sets.
|
||||
* Allows an implementation to pick different
|
||||
* resampler_implementation structs.
|
||||
*/
|
||||
typedef unsigned resampler_simd_mask_t;
|
||||
|
||||
#define RESAMPLER_API_VERSION 1
|
||||
|
||||
struct resampler_data
|
||||
{
|
||||
const float *data_in;
|
||||
float *data_out;
|
||||
|
||||
size_t input_frames;
|
||||
size_t output_frames;
|
||||
|
||||
double ratio;
|
||||
};
|
||||
|
||||
/* Returns true if config key was found. Otherwise,
|
||||
* returns false, and sets value to default value.
|
||||
*/
|
||||
typedef int (*resampler_config_get_float_t)(void *userdata,
|
||||
const char *key, float *value, float default_value);
|
||||
|
||||
typedef int (*resampler_config_get_int_t)(void *userdata,
|
||||
const char *key, int *value, int default_value);
|
||||
|
||||
/* Allocates an array with values. free() with resampler_config_free_t. */
|
||||
typedef int (*resampler_config_get_float_array_t)(void *userdata,
|
||||
const char *key, float **values, unsigned *out_num_values,
|
||||
const float *default_values, unsigned num_default_values);
|
||||
|
||||
typedef int (*resampler_config_get_int_array_t)(void *userdata,
|
||||
const char *key, int **values, unsigned *out_num_values,
|
||||
const int *default_values, unsigned num_default_values);
|
||||
|
||||
typedef int (*resampler_config_get_string_t)(void *userdata,
|
||||
const char *key, char **output, const char *default_output);
|
||||
|
||||
/* Calls free() in host runtime. Sometimes needed on Windows.
|
||||
* free() on NULL is fine. */
|
||||
typedef void (*resampler_config_free_t)(void *ptr);
|
||||
|
||||
struct resampler_config
|
||||
{
|
||||
resampler_config_get_float_t get_float;
|
||||
resampler_config_get_int_t get_int;
|
||||
|
||||
resampler_config_get_float_array_t get_float_array;
|
||||
resampler_config_get_int_array_t get_int_array;
|
||||
|
||||
resampler_config_get_string_t get_string;
|
||||
/* Avoid problems where resampler plug and host are
|
||||
* linked against different C runtimes. */
|
||||
resampler_config_free_t free;
|
||||
};
|
||||
|
||||
/* NEW: Init takes a pointer to a pointer to a retro_resampler struct, and
|
||||
* fills it out with an altered version of the static structure. This is so
|
||||
* other threads don't clobber the process pointer in each other's instances
|
||||
* when selecting different resampler modes.
|
||||
*
|
||||
* Only the init function needs it on input, and the free function cleans up
|
||||
* after it. The process and latency functions shouldn't need it. */
|
||||
|
||||
typedef struct retro_resampler retro_resampler_t;
|
||||
|
||||
/* Bandwidth factor. Will be < 1.0 for downsampling, > 1.0 for upsampling.
|
||||
* Corresponds to expected resampling ratio. */
|
||||
typedef void *(*resampler_init_t)(const struct resampler_config *config,
|
||||
const retro_resampler_t **resampler, double bandwidth_mod,
|
||||
enum resampler_quality quality, size_t channels, resampler_simd_mask_t mask);
|
||||
|
||||
/* Frees the handle, and if duped by above, the resampler */
|
||||
typedef void (*resampler_free_t)(const retro_resampler_t *resampler, void *data);
|
||||
|
||||
/* Processes input data. */
|
||||
typedef void (*resampler_process_t)(void *_data, struct resampler_data *data);
|
||||
|
||||
typedef size_t (*resampler_latency_t)(void *_data);
|
||||
|
||||
struct retro_resampler
|
||||
{
|
||||
resampler_init_t init;
|
||||
resampler_process_t process;
|
||||
resampler_free_t free;
|
||||
resampler_latency_t latency;
|
||||
|
||||
/* Must be RESAMPLER_API_VERSION */
|
||||
unsigned api_version;
|
||||
|
||||
/* Human readable identifier of implementation. */
|
||||
const char *ident;
|
||||
|
||||
/* Computer-friendly short version of ident.
|
||||
* Lower case, no spaces and special characters, etc. */
|
||||
const char *short_ident;
|
||||
};
|
||||
|
||||
typedef struct audio_frame_float
|
||||
{
|
||||
float l;
|
||||
float r;
|
||||
} audio_frame_float_t;
|
||||
|
||||
extern retro_resampler_t sinc_resampler;
|
||||
#ifdef HAVE_CC_RESAMPLER
|
||||
extern retro_resampler_t CC_resampler;
|
||||
#endif
|
||||
extern retro_resampler_t nearest_resampler;
|
||||
|
||||
/**
|
||||
* audio_resampler_driver_find_handle:
|
||||
* @index : index of driver to get handle to.
|
||||
*
|
||||
* Returns: handle to audio resampler driver at index. Can be NULL
|
||||
* if nothing found.
|
||||
**/
|
||||
const void *audio_resampler_driver_find_handle(int index);
|
||||
|
||||
/**
|
||||
* audio_resampler_driver_find_ident:
|
||||
* @index : index of driver to get handle to.
|
||||
*
|
||||
* Returns: Human-readable identifier of audio resampler driver at index.
|
||||
* Can be NULL if nothing found.
|
||||
**/
|
||||
const char *audio_resampler_driver_find_ident(int index);
|
||||
|
||||
/**
|
||||
* retro_resampler_realloc:
|
||||
* @re : Resampler handle
|
||||
* @backend : Resampler backend that is about to be set.
|
||||
* @ident : Identifier name for resampler we want.
|
||||
* @bw_ratio : Bandwidth ratio.
|
||||
*
|
||||
* Reallocates resampler. Will free previous handle before
|
||||
* allocating a new one. If ident is NULL, first resampler will be used.
|
||||
*
|
||||
* Returns: true (1) if successful, otherwise false (0).
|
||||
**/
|
||||
bool retro_resampler_realloc(void **re, const retro_resampler_t **backend,
|
||||
const char *ident, enum resampler_quality quality, size_t channels,
|
||||
double bw_ratio);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
|
@ -1,55 +0,0 @@
|
|||
/* Copyright (C) 2010-2021 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (s16_to_float.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef __LIBRETRO_SDK_CONVERSION_S16_TO_FLOAT_H__
|
||||
#define __LIBRETRO_SDK_CONVERSION_S16_TO_FLOAT_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <retro_common_api.h>
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* convert_s16_to_float:
|
||||
* @out : output buffer
|
||||
* @in : input buffer
|
||||
* @samples : size of samples to be converted
|
||||
* @gain : gain applied (.e.g. audio volume)
|
||||
*
|
||||
* Converts from signed integer 16-bit
|
||||
* to floating point.
|
||||
**/
|
||||
void convert_s16_to_float(float *out,
|
||||
const int16_t *in, size_t samples, float gain);
|
||||
|
||||
/**
|
||||
* convert_s16_to_float_init_simd:
|
||||
*
|
||||
* Sets up function pointers for conversion
|
||||
* functions based on CPU features.
|
||||
**/
|
||||
void convert_s16_to_float_init_simd(void);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
|
@ -1,55 +0,0 @@
|
|||
/* Copyright (C) 2010-2021 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (s32_to_float.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef __LIBRETRO_SDK_CONVERSION_S32_TO_FLOAT_H__
|
||||
#define __LIBRETRO_SDK_CONVERSION_S32_TO_FLOAT_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <retro_common_api.h>
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* convert_s32_to_float:
|
||||
* @out : output buffer
|
||||
* @in : input buffer
|
||||
* @samples : size of samples to be converted
|
||||
* @gain : gain applied (.e.g. audio volume)
|
||||
*
|
||||
* Converts from signed integer 16-bit
|
||||
* to floating point.
|
||||
**/
|
||||
void convert_s32_to_float(float *out,
|
||||
const int32_t *in, size_t samples, float gain);
|
||||
|
||||
/**
|
||||
* convert_s32_to_float_init_simd:
|
||||
*
|
||||
* Sets up function pointers for conversion
|
||||
* functions based on CPU features.
|
||||
**/
|
||||
void convert_s32_to_float_init_simd(void);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
|
@ -1,39 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (boolean.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __LIBRETRO_SDK_BOOLEAN_H
|
||||
#define __LIBRETRO_SDK_BOOLEAN_H
|
||||
|
||||
#ifndef __cplusplus
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1800 && !defined(SN_TARGET_PS3)
|
||||
/* Hack applied for MSVC when compiling in C89 mode as it isn't C99 compliant. */
|
||||
#define bool unsigned char
|
||||
#define true 1
|
||||
#define false 0
|
||||
#else
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,34 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (fopen_utf8.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __LIBRETRO_SDK_COMPAT_FOPEN_UTF8_H
|
||||
#define __LIBRETRO_SDK_COMPAT_FOPEN_UTF8_H
|
||||
|
||||
#ifdef _WIN32
|
||||
/* Defined to error rather than fopen_utf8, to make it clear to everyone reading the code that not worrying about utf16 is fine */
|
||||
/* TODO: enable */
|
||||
/* #define fopen (use fopen_utf8 instead) */
|
||||
void *fopen_utf8(const char * filename, const char * mode);
|
||||
#else
|
||||
#define fopen_utf8 fopen
|
||||
#endif
|
||||
#endif
|
|
@ -1,126 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (msvc.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __LIBRETRO_SDK_COMPAT_MSVC_H
|
||||
#define __LIBRETRO_SDK_COMPAT_MSVC_H
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Pre-MSVC 2015 compilers don't implement snprintf, vsnprintf in a cross-platform manner. */
|
||||
#if _MSC_VER < 1900
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef snprintf
|
||||
#define snprintf c99_snprintf_retro__
|
||||
#endif
|
||||
int c99_snprintf_retro__(char *outBuf, size_t size, const char *format, ...);
|
||||
|
||||
#ifndef vsnprintf
|
||||
#define vsnprintf c99_vsnprintf_retro__
|
||||
#endif
|
||||
int c99_vsnprintf_retro__(char *outBuf, size_t size, const char *format, va_list ap);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef UNICODE /* Do not bother with UNICODE at this time. */
|
||||
#include <direct.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
|
||||
/* Python headers defines ssize_t and sets HAVE_SSIZE_T.
|
||||
* Cannot duplicate these efforts.
|
||||
*/
|
||||
#ifndef HAVE_SSIZE_T
|
||||
#if defined(_WIN64)
|
||||
typedef __int64 ssize_t;
|
||||
#elif defined(_WIN32)
|
||||
typedef int ssize_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define mkdir(dirname, unused) _mkdir(dirname)
|
||||
#define strtoull _strtoui64
|
||||
#undef strcasecmp
|
||||
#define strcasecmp _stricmp
|
||||
#undef strncasecmp
|
||||
#define strncasecmp _strnicmp
|
||||
|
||||
/* Disable some of the annoying warnings. */
|
||||
#pragma warning(disable : 4800)
|
||||
#pragma warning(disable : 4805)
|
||||
#pragma warning(disable : 4244)
|
||||
#pragma warning(disable : 4305)
|
||||
#pragma warning(disable : 4146)
|
||||
#pragma warning(disable : 4267)
|
||||
#pragma warning(disable : 4723)
|
||||
#pragma warning(disable : 4996)
|
||||
|
||||
/* roundf and va_copy is available since MSVC 2013 */
|
||||
#if _MSC_VER < 1800
|
||||
#define roundf(in) (in >= 0.0f ? floorf(in + 0.5f) : ceilf(in - 0.5f))
|
||||
#define va_copy(x, y) ((x) = (y))
|
||||
#endif
|
||||
|
||||
#if _MSC_VER <= 1310
|
||||
#ifndef __cplusplus
|
||||
/* VC6 math.h doesn't define some functions when in C mode.
|
||||
* Trying to define a prototype gives "undefined reference".
|
||||
* But providing an implementation then gives "function already has body".
|
||||
* So the equivalent of the implementations from math.h are used as
|
||||
* defines here instead, and it seems to work.
|
||||
*/
|
||||
#define cosf(x) ((float)cos((double)x))
|
||||
#define powf(x, y) ((float)pow((double)x, (double)y))
|
||||
#define sinf(x) ((float)sin((double)x))
|
||||
#define ceilf(x) ((float)ceil((double)x))
|
||||
#define floorf(x) ((float)floor((double)x))
|
||||
#define sqrtf(x) ((float)sqrt((double)x))
|
||||
#define fabsf(x) ((float)fabs((double)(x)))
|
||||
#endif
|
||||
|
||||
#ifndef _strtoui64
|
||||
#define _strtoui64(x, y, z) (_atoi64(x))
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX _MAX_PATH
|
||||
#endif
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
#define SIZE_MAX _UI32_MAX
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -1,60 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (posix_string.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __LIBRETRO_SDK_COMPAT_POSIX_STRING_H
|
||||
#define __LIBRETRO_SDK_COMPAT_POSIX_STRING_H
|
||||
|
||||
#include <retro_common_api.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <compat/msvc.h>
|
||||
#endif
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
#ifdef _WIN32
|
||||
#undef strtok_r
|
||||
#define strtok_r(str, delim, saveptr) retro_strtok_r__(str, delim, saveptr)
|
||||
|
||||
char *strtok_r(char *str, const char *delim, char **saveptr);
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#undef strcasecmp
|
||||
#undef strdup
|
||||
#define strcasecmp(a, b) retro_strcasecmp__(a, b)
|
||||
#define strdup(orig) retro_strdup__(orig)
|
||||
int strcasecmp(const char *a, const char *b);
|
||||
char *strdup(const char *orig);
|
||||
|
||||
/* isblank is available since MSVC 2013 */
|
||||
#if _MSC_VER < 1800
|
||||
#undef isblank
|
||||
#define isblank(c) retro_isblank__(c)
|
||||
int isblank(int c);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
|
@ -1,48 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (strcasestr.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __LIBRETRO_SDK_COMPAT_STRCASESTR_H
|
||||
#define __LIBRETRO_SDK_COMPAT_STRCASESTR_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(RARCH_INTERNAL) && defined(HAVE_CONFIG_H)
|
||||
#include "../../../config.h"
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRCASESTR
|
||||
|
||||
#include <retro_common_api.h>
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
/* Avoid possible naming collisions during link
|
||||
* since we prefer to use the actual name. */
|
||||
#define strcasestr(haystack, needle) strcasestr_retro__(haystack, needle)
|
||||
|
||||
char *strcasestr(const char *haystack, const char *needle);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,59 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (strl.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __LIBRETRO_SDK_COMPAT_STRL_H
|
||||
#define __LIBRETRO_SDK_COMPAT_STRL_H
|
||||
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#if defined(RARCH_INTERNAL) && defined(HAVE_CONFIG_H)
|
||||
#include "../../../config.h"
|
||||
#endif
|
||||
|
||||
#include <retro_common_api.h>
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
#ifdef __MACH__
|
||||
#ifndef HAVE_STRL
|
||||
#define HAVE_STRL
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRL
|
||||
/* Avoid possible naming collisions during link since
|
||||
* we prefer to use the actual name. */
|
||||
#define strlcpy(dst, src, size) strlcpy_retro__(dst, src, size)
|
||||
|
||||
#define strlcat(dst, src, size) strlcat_retro__(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);
|
||||
|
||||
#endif
|
||||
|
||||
char *strldup(const char *s, size_t n);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
|
@ -1,67 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (utf.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _LIBRETRO_ENCODINGS_UTF_H
|
||||
#define _LIBRETRO_ENCODINGS_UTF_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <boolean.h>
|
||||
|
||||
#include <retro_common_api.h>
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
enum CodePage
|
||||
{
|
||||
CODEPAGE_LOCAL = 0, /* CP_ACP */
|
||||
CODEPAGE_UTF8 = 65001 /* CP_UTF8 */
|
||||
};
|
||||
|
||||
size_t utf8_conv_utf32(uint32_t *out, size_t out_chars,
|
||||
const char *in, size_t in_size);
|
||||
|
||||
bool utf16_conv_utf8(uint8_t *out, size_t *out_chars,
|
||||
const uint16_t *in, size_t in_size);
|
||||
|
||||
size_t utf8len(const char *string);
|
||||
|
||||
size_t utf8cpy(char *d, size_t d_len, const char *s, size_t chars);
|
||||
|
||||
const char *utf8skip(const char *str, size_t chars);
|
||||
|
||||
uint32_t utf8_walk(const char **string);
|
||||
|
||||
bool utf16_to_char_string(const uint16_t *in, char *s, size_t len);
|
||||
|
||||
char* utf8_to_local_string_alloc(const char *str);
|
||||
|
||||
char* local_to_utf8_string_alloc(const char *str);
|
||||
|
||||
wchar_t* utf8_to_utf16_string_alloc(const char *str);
|
||||
|
||||
char* utf16_to_utf8_string_alloc(const wchar_t *str);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
|
@ -1,75 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (features_cpu.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _LIBRETRO_SDK_CPU_INFO_H
|
||||
#define _LIBRETRO_SDK_CPU_INFO_H
|
||||
|
||||
#include <retro_common_api.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <libretro.h>
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* cpu_features_get_perf_counter:
|
||||
*
|
||||
* Gets performance counter.
|
||||
*
|
||||
* Returns: performance counter.
|
||||
**/
|
||||
retro_perf_tick_t cpu_features_get_perf_counter(void);
|
||||
|
||||
/**
|
||||
* cpu_features_get_time_usec:
|
||||
*
|
||||
* Gets time in microseconds, from an undefined epoch.
|
||||
* The epoch may change between computers or across reboots.
|
||||
*
|
||||
* Returns: time in microseconds
|
||||
**/
|
||||
retro_time_t cpu_features_get_time_usec(void);
|
||||
|
||||
/**
|
||||
* cpu_features_get:
|
||||
*
|
||||
* Gets CPU features.
|
||||
*
|
||||
* Returns: bitmask of all CPU features available.
|
||||
**/
|
||||
uint64_t cpu_features_get(void);
|
||||
|
||||
/**
|
||||
* cpu_features_get_core_amount:
|
||||
*
|
||||
* Gets the amount of available CPU cores.
|
||||
*
|
||||
* Returns: amount of CPU cores available.
|
||||
**/
|
||||
unsigned cpu_features_get_core_amount(void);
|
||||
|
||||
void cpu_features_get_model_name(char *name, int len);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
|
@ -1,225 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (config_file.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __LIBRETRO_SDK_CONFIG_FILE_H
|
||||
#define __LIBRETRO_SDK_CONFIG_FILE_H
|
||||
|
||||
#include <retro_common_api.h>
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <boolean.h>
|
||||
|
||||
#define CONFIG_GET_BOOL_BASE(conf, base, var, key) do { \
|
||||
bool tmp = false; \
|
||||
if (config_get_bool(conf, key, &tmp)) \
|
||||
base->var = tmp; \
|
||||
} while(0)
|
||||
|
||||
#define CONFIG_GET_INT_BASE(conf, base, var, key) do { \
|
||||
int tmp = 0; \
|
||||
if (config_get_int(conf, key, &tmp)) \
|
||||
base->var = tmp; \
|
||||
} while(0)
|
||||
|
||||
#define CONFIG_GET_FLOAT_BASE(conf, base, var, key) do { \
|
||||
float tmp = 0.0f; \
|
||||
if (config_get_float(conf, key, &tmp)) \
|
||||
base->var = tmp; \
|
||||
} while(0)
|
||||
|
||||
struct config_file
|
||||
{
|
||||
char *path;
|
||||
char *reference;
|
||||
struct config_entry_list **entries_map;
|
||||
struct config_entry_list *entries;
|
||||
struct config_entry_list *tail;
|
||||
struct config_entry_list *last;
|
||||
struct config_include_list *includes;
|
||||
unsigned include_depth;
|
||||
bool guaranteed_no_duplicates;
|
||||
bool modified;
|
||||
};
|
||||
|
||||
typedef struct config_file config_file_t;
|
||||
|
||||
struct config_file_cb
|
||||
{
|
||||
void (*config_file_new_entry_cb)(char*, char*);
|
||||
};
|
||||
|
||||
typedef struct config_file_cb config_file_cb_t ;
|
||||
|
||||
/* Config file format
|
||||
* - # are treated as comments. Rest of the line is ignored.
|
||||
* - Format is: key = value. There can be as many spaces as you like in-between.
|
||||
* - Value can be wrapped inside "" for multiword strings. (foo = "hai u")
|
||||
* - #include includes a config file in-place.
|
||||
*
|
||||
* Path is relative to where config file was loaded unless an absolute path is chosen.
|
||||
* Key/value pairs from an #include are read-only, and cannot be modified.
|
||||
*/
|
||||
|
||||
/* Loads a config file. Returns NULL if file doesn't exist.
|
||||
* NULL path will create an empty config file. */
|
||||
config_file_t *config_file_new(const char *path);
|
||||
|
||||
config_file_t *config_file_new_alloc(void);
|
||||
|
||||
void config_file_initialize(struct config_file *conf);
|
||||
|
||||
/* Loads a config file. Returns NULL if file doesn't exist.
|
||||
* NULL path will create an empty config file.
|
||||
* Includes cb callbacks to run custom code during config file processing.*/
|
||||
config_file_t *config_file_new_with_callback(const char *path, config_file_cb_t *cb);
|
||||
|
||||
/* Load a config file from a string.
|
||||
* > WARNING: This will modify 'from_string'.
|
||||
* Pass a copy of source string if original
|
||||
* contents must be preserved */
|
||||
config_file_t *config_file_new_from_string(char *from_string,
|
||||
const char *path);
|
||||
|
||||
config_file_t *config_file_new_from_path_to_string(const char *path);
|
||||
|
||||
/* Frees config file. */
|
||||
void config_file_free(config_file_t *conf);
|
||||
|
||||
void config_file_set_reference_path(config_file_t *conf, char *path);
|
||||
|
||||
bool config_file_deinitialize(config_file_t *conf);
|
||||
|
||||
/* Loads a new config, and appends its data to conf.
|
||||
* The key-value pairs of the new config file takes priority over the old. */
|
||||
bool config_append_file(config_file_t *conf, const char *path);
|
||||
|
||||
/* All extract functions return true when value is valid and exists.
|
||||
* Returns false otherwise. */
|
||||
|
||||
bool config_entry_exists(config_file_t *conf, const char *entry);
|
||||
|
||||
struct config_entry_list
|
||||
{
|
||||
char *key;
|
||||
char *value;
|
||||
struct config_entry_list *next;
|
||||
/* If we got this from an #include,
|
||||
* do not allow overwrite. */
|
||||
bool readonly;
|
||||
};
|
||||
|
||||
|
||||
struct config_file_entry
|
||||
{
|
||||
const char *key;
|
||||
const char *value;
|
||||
/* Used intentionally. Opaque here. */
|
||||
const struct config_entry_list *next;
|
||||
};
|
||||
|
||||
struct config_entry_list *config_get_entry(
|
||||
const config_file_t *conf, const char *key);
|
||||
|
||||
bool config_get_entry_list_head(config_file_t *conf, struct config_file_entry *entry);
|
||||
bool config_get_entry_list_next(struct config_file_entry *entry);
|
||||
|
||||
/* Extracts a double from config file. */
|
||||
bool config_get_double(config_file_t *conf, const char *entry, double *in);
|
||||
|
||||
/* Extracts a float from config file. */
|
||||
bool config_get_float(config_file_t *conf, const char *entry, float *in);
|
||||
|
||||
/* Extracts an int from config file. */
|
||||
bool config_get_int(config_file_t *conf, const char *entry, int *in);
|
||||
|
||||
/* Extracts an uint from config file. */
|
||||
bool config_get_uint(config_file_t *conf, const char *entry, unsigned *in);
|
||||
|
||||
/* Extracts an size_t from config file. */
|
||||
bool config_get_size_t(config_file_t *conf, const char *key, size_t *in);
|
||||
|
||||
#if defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L
|
||||
/* Extracts an uint64 from config file. */
|
||||
bool config_get_uint64(config_file_t *conf, const char *entry, uint64_t *in);
|
||||
#endif
|
||||
|
||||
/* Extracts an unsigned int from config file treating input as hex. */
|
||||
bool config_get_hex(config_file_t *conf, const char *entry, unsigned *in);
|
||||
|
||||
/* Extracts a single char. If value consists of several chars,
|
||||
* this is an error. */
|
||||
bool config_get_char(config_file_t *conf, const char *entry, char *in);
|
||||
|
||||
/* Extracts an allocated string in *in. This must be free()-d if
|
||||
* this function succeeds. */
|
||||
bool config_get_string(config_file_t *conf, const char *entry, char **in);
|
||||
|
||||
/* Extracts a string to a preallocated buffer. Avoid memory allocation. */
|
||||
bool config_get_array(config_file_t *conf, const char *entry, char *s, size_t len);
|
||||
|
||||
/* Extracts a string to a preallocated buffer. Avoid memory allocation.
|
||||
* Recognized magic like ~/. Similar to config_get_array() otherwise. */
|
||||
bool config_get_path(config_file_t *conf, const char *entry, char *s, size_t len);
|
||||
|
||||
/* Extracts a string to a preallocated buffer. Avoid memory allocation. */
|
||||
bool config_get_config_path(config_file_t *conf, char *s, size_t len);
|
||||
|
||||
/* Extracts a boolean from config.
|
||||
* Valid boolean true are "true" and "1". Valid false are "false" and "0".
|
||||
* Other values will be treated as an error. */
|
||||
bool config_get_bool(config_file_t *conf, const char *entry, bool *in);
|
||||
|
||||
/* Setters. Similar to the getters.
|
||||
* Will not write to entry if the entry was obtained from an #include. */
|
||||
void config_set_double(config_file_t *conf, const char *entry, double value);
|
||||
void config_set_float(config_file_t *conf, const char *entry, float value);
|
||||
void config_set_int(config_file_t *conf, const char *entry, int val);
|
||||
void config_set_hex(config_file_t *conf, const char *entry, unsigned val);
|
||||
void config_set_uint64(config_file_t *conf, const char *entry, uint64_t val);
|
||||
void config_set_char(config_file_t *conf, const char *entry, char val);
|
||||
void config_set_string(config_file_t *conf, const char *entry, const char *val);
|
||||
void config_unset(config_file_t *conf, const char *key);
|
||||
void config_set_path(config_file_t *conf, const char *entry, const char *val);
|
||||
void config_set_bool(config_file_t *conf, const char *entry, bool val);
|
||||
void config_set_uint(config_file_t *conf, const char *key, unsigned int val);
|
||||
|
||||
/* Write the current config to a file. */
|
||||
bool config_file_write(config_file_t *conf, const char *path, bool val);
|
||||
|
||||
/* Dump the current config to an already opened file.
|
||||
* Does not close the file. */
|
||||
void config_file_dump(config_file_t *conf, FILE *file, bool val);
|
||||
|
||||
#ifdef ORBIS
|
||||
void config_file_dump_orbis(config_file_t *conf, int fd);
|
||||
#endif
|
||||
|
||||
bool config_file_exists(const char *path);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
|
@ -1,64 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (config_file_userdata.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _LIBRETRO_SDK_CONFIG_FILE_USERDATA_H
|
||||
#define _LIBRETRO_SDK_CONFIG_FILE_USERDATA_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <file/config_file.h>
|
||||
|
||||
#include <retro_common_api.h>
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
struct config_file_userdata
|
||||
{
|
||||
config_file_t *conf;
|
||||
const char *prefix[2];
|
||||
};
|
||||
|
||||
int config_userdata_get_float(void *userdata, const char *key_str,
|
||||
float *value, float default_value);
|
||||
|
||||
int config_userdata_get_int(void *userdata, const char *key_str,
|
||||
int *value, int default_value);
|
||||
|
||||
int config_userdata_get_hex(void *userdata, const char *key_str,
|
||||
unsigned *value, unsigned default_value);
|
||||
|
||||
int config_userdata_get_float_array(void *userdata, const char *key_str,
|
||||
float **values, unsigned *out_num_values,
|
||||
const float *default_values, unsigned num_default_values);
|
||||
|
||||
int config_userdata_get_int_array(void *userdata, const char *key_str,
|
||||
int **values, unsigned *out_num_values,
|
||||
const int *default_values, unsigned num_default_values);
|
||||
|
||||
int config_userdata_get_string(void *userdata, const char *key_str,
|
||||
char **output, const char *default_output);
|
||||
|
||||
void config_userdata_free(void *ptr);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
|
@ -1,538 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (file_path.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __LIBRETRO_SDK_FILE_PATH_H
|
||||
#define __LIBRETRO_SDK_FILE_PATH_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <libretro.h>
|
||||
#include <retro_common_api.h>
|
||||
|
||||
#include <boolean.h>
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
#define PATH_REQUIRED_VFS_VERSION 3
|
||||
|
||||
void path_vfs_init(const struct retro_vfs_interface_info* vfs_info);
|
||||
|
||||
/* Order in this enum is equivalent to negative sort order in filelist
|
||||
* (i.e. DIRECTORY is on top of PLAIN_FILE) */
|
||||
enum
|
||||
{
|
||||
RARCH_FILETYPE_UNSET,
|
||||
RARCH_PLAIN_FILE,
|
||||
RARCH_COMPRESSED_FILE_IN_ARCHIVE,
|
||||
RARCH_COMPRESSED_ARCHIVE,
|
||||
RARCH_DIRECTORY,
|
||||
RARCH_FILE_UNSUPPORTED
|
||||
};
|
||||
|
||||
/**
|
||||
* path_is_compressed_file:
|
||||
* @path : path
|
||||
*
|
||||
* Checks if path is a compressed file.
|
||||
*
|
||||
* Returns: true (1) if path is a compressed file, otherwise false (0).
|
||||
**/
|
||||
bool path_is_compressed_file(const char *path);
|
||||
|
||||
/**
|
||||
* path_contains_compressed_file:
|
||||
* @path : path
|
||||
*
|
||||
* Checks if path contains a compressed file.
|
||||
*
|
||||
* Currently we only check for hash symbol (#) inside the pathname.
|
||||
* If path is ever expanded to a general URI, we should check for that here.
|
||||
*
|
||||
* Example: Somewhere in the path there might be a compressed file
|
||||
* E.g.: /path/to/file.7z#mygame.img
|
||||
*
|
||||
* Returns: true (1) if path contains compressed file, otherwise false (0).
|
||||
**/
|
||||
#define path_contains_compressed_file(path) (path_get_archive_delim((path)) != NULL)
|
||||
|
||||
/**
|
||||
* path_get_archive_delim:
|
||||
* @path : path
|
||||
*
|
||||
* Gets delimiter of an archive file. Only the first '#'
|
||||
* after a compression extension is considered.
|
||||
*
|
||||
* Returns: pointer to the delimiter in the path if it contains
|
||||
* a compressed file, otherwise NULL.
|
||||
*/
|
||||
const char *path_get_archive_delim(const char *path);
|
||||
|
||||
/**
|
||||
* path_get_extension:
|
||||
* @path : path
|
||||
*
|
||||
* Gets extension of file. Only '.'s
|
||||
* after the last slash are considered.
|
||||
*
|
||||
* Returns: extension part from the path.
|
||||
*/
|
||||
const char *path_get_extension(const char *path);
|
||||
|
||||
/**
|
||||
* path_remove_extension:
|
||||
* @path : path
|
||||
*
|
||||
* Mutates path by removing its extension. Removes all
|
||||
* text after and including the last '.'.
|
||||
* Only '.'s after the last slash are considered.
|
||||
*
|
||||
* Returns:
|
||||
* 1) If path has an extension, returns path with the
|
||||
* extension removed.
|
||||
* 2) If there is no extension, returns NULL.
|
||||
* 3) If path is empty or NULL, returns NULL
|
||||
*/
|
||||
char *path_remove_extension(char *path);
|
||||
|
||||
/**
|
||||
* path_basename:
|
||||
* @path : path
|
||||
*
|
||||
* Get basename from @path.
|
||||
*
|
||||
* Returns: basename from path.
|
||||
**/
|
||||
const char *path_basename(const char *path);
|
||||
const char *path_basename_nocompression(const char *path);
|
||||
|
||||
/**
|
||||
* path_basedir:
|
||||
* @path : path
|
||||
*
|
||||
* Extracts base directory by mutating path.
|
||||
* Keeps trailing '/'.
|
||||
**/
|
||||
void path_basedir(char *path);
|
||||
|
||||
/**
|
||||
* path_parent_dir:
|
||||
* @path : path
|
||||
*
|
||||
* Extracts parent directory by mutating path.
|
||||
* Assumes that path is a directory. Keeps trailing '/'.
|
||||
* If the path was already at the root directory, returns empty string
|
||||
**/
|
||||
void path_parent_dir(char *path);
|
||||
|
||||
/**
|
||||
* path_resolve_realpath:
|
||||
* @buf : input and output buffer for path
|
||||
* @size : size of buffer
|
||||
* @resolve_symlinks : whether to resolve symlinks or not
|
||||
*
|
||||
* Resolves use of ".", "..", multiple slashes etc in absolute paths.
|
||||
*
|
||||
* Relative paths are rebased on the current working dir.
|
||||
*
|
||||
* Returns: @buf if successful, NULL otherwise.
|
||||
* Note: Not implemented on consoles
|
||||
* Note: Symlinks are only resolved on Unix-likes
|
||||
* Note: The current working dir might not be what you expect,
|
||||
* e.g. on Android it is "/"
|
||||
* Use of fill_pathname_resolve_relative() should be prefered
|
||||
**/
|
||||
char *path_resolve_realpath(char *buf, size_t size, bool resolve_symlinks);
|
||||
|
||||
/**
|
||||
* path_relative_to:
|
||||
* @out : buffer to write the relative path to
|
||||
* @path : path to be expressed relatively
|
||||
* @base : relative to this
|
||||
* @size : size of output buffer
|
||||
*
|
||||
* Turns @path into a path relative to @base and writes it to @out.
|
||||
*
|
||||
* @base is assumed to be a base directory, i.e. a path ending with '/' or '\'.
|
||||
* Both @path and @base are assumed to be absolute paths without "." or "..".
|
||||
*
|
||||
* E.g. path /a/b/e/f.cgp with base /a/b/c/d/ turns into ../../e/f.cgp
|
||||
**/
|
||||
size_t path_relative_to(char *out, const char *path, const char *base, size_t size);
|
||||
|
||||
/**
|
||||
* path_is_absolute:
|
||||
* @path : path
|
||||
*
|
||||
* Checks if @path is an absolute path or a relative path.
|
||||
*
|
||||
* Returns: true if path is absolute, false if path is relative.
|
||||
**/
|
||||
bool path_is_absolute(const char *path);
|
||||
|
||||
/**
|
||||
* fill_pathname:
|
||||
* @out_path : output path
|
||||
* @in_path : input path
|
||||
* @replace : what to replace
|
||||
* @size : buffer size of output path
|
||||
*
|
||||
* FIXME: Verify
|
||||
*
|
||||
* Replaces filename extension with 'replace' and outputs result to out_path.
|
||||
* The extension here is considered to be the string from the last '.'
|
||||
* to the end.
|
||||
*
|
||||
* Only '.'s after the last slash are considered as extensions.
|
||||
* If no '.' is present, in_path and replace will simply be concatenated.
|
||||
* 'size' is buffer size of 'out_path'.
|
||||
* E.g.: in_path = "/foo/bar/baz/boo.c", replace = ".asm" =>
|
||||
* out_path = "/foo/bar/baz/boo.asm"
|
||||
* E.g.: in_path = "/foo/bar/baz/boo.c", replace = "" =>
|
||||
* out_path = "/foo/bar/baz/boo"
|
||||
*/
|
||||
void fill_pathname(char *out_path, const char *in_path,
|
||||
const char *replace, size_t size);
|
||||
|
||||
/**
|
||||
* fill_dated_filename:
|
||||
* @out_filename : output filename
|
||||
* @ext : extension of output filename
|
||||
* @size : buffer size of output filename
|
||||
*
|
||||
* Creates a 'dated' filename prefixed by 'RetroArch', and
|
||||
* concatenates extension (@ext) to it.
|
||||
*
|
||||
* E.g.:
|
||||
* out_filename = "RetroArch-{month}{day}-{Hours}{Minutes}.{@ext}"
|
||||
**/
|
||||
size_t fill_dated_filename(char *out_filename,
|
||||
const char *ext, size_t size);
|
||||
|
||||
/**
|
||||
* fill_str_dated_filename:
|
||||
* @out_filename : output filename
|
||||
* @in_str : input string
|
||||
* @ext : extension of output filename
|
||||
* @size : buffer size of output filename
|
||||
*
|
||||
* Creates a 'dated' filename prefixed by the string @in_str, and
|
||||
* concatenates extension (@ext) to it.
|
||||
*
|
||||
* E.g.:
|
||||
* out_filename = "RetroArch-{year}{month}{day}-{Hour}{Minute}{Second}.{@ext}"
|
||||
**/
|
||||
void fill_str_dated_filename(char *out_filename,
|
||||
const char *in_str, const char *ext, size_t size);
|
||||
|
||||
/**
|
||||
* fill_pathname_noext:
|
||||
* @out_path : output path
|
||||
* @in_path : input path
|
||||
* @replace : what to replace
|
||||
* @size : buffer size of output path
|
||||
*
|
||||
* Appends a filename extension 'replace' to 'in_path', and outputs
|
||||
* result in 'out_path'.
|
||||
*
|
||||
* Assumes in_path has no extension. If an extension is still
|
||||
* present in 'in_path', it will be ignored.
|
||||
*
|
||||
*/
|
||||
size_t fill_pathname_noext(char *out_path, const char *in_path,
|
||||
const char *replace, size_t size);
|
||||
|
||||
/**
|
||||
* find_last_slash:
|
||||
* @str : input path
|
||||
*
|
||||
* Gets a pointer to the last slash in the input path.
|
||||
*
|
||||
* Returns: a pointer to the last slash in the input path.
|
||||
**/
|
||||
char *find_last_slash(const char *str);
|
||||
|
||||
/**
|
||||
* fill_pathname_dir:
|
||||
* @in_dir : input directory path
|
||||
* @in_basename : input basename to be appended to @in_dir
|
||||
* @replace : replacement to be appended to @in_basename
|
||||
* @size : size of buffer
|
||||
*
|
||||
* Appends basename of 'in_basename', to 'in_dir', along with 'replace'.
|
||||
* Basename of in_basename is the string after the last '/' or '\\',
|
||||
* i.e the filename without directories.
|
||||
*
|
||||
* If in_basename has no '/' or '\\', the whole 'in_basename' will be used.
|
||||
* 'size' is buffer size of 'in_dir'.
|
||||
*
|
||||
* E.g..: in_dir = "/tmp/some_dir", in_basename = "/some_content/foo.c",
|
||||
* replace = ".asm" => in_dir = "/tmp/some_dir/foo.c.asm"
|
||||
**/
|
||||
size_t fill_pathname_dir(char *in_dir, const char *in_basename,
|
||||
const char *replace, size_t size);
|
||||
|
||||
/**
|
||||
* fill_pathname_base:
|
||||
* @out : output path
|
||||
* @in_path : input path
|
||||
* @size : size of output path
|
||||
*
|
||||
* Copies basename of @in_path into @out_path.
|
||||
**/
|
||||
size_t fill_pathname_base(char *out_path, const char *in_path, size_t size);
|
||||
|
||||
void fill_pathname_base_noext(char *out_dir,
|
||||
const char *in_path, size_t size);
|
||||
|
||||
size_t fill_pathname_base_ext(char *out,
|
||||
const char *in_path, const char *ext,
|
||||
size_t size);
|
||||
|
||||
/**
|
||||
* fill_pathname_basedir:
|
||||
* @out_dir : output directory
|
||||
* @in_path : input path
|
||||
* @size : size of output directory
|
||||
*
|
||||
* Copies base directory of @in_path into @out_path.
|
||||
* If in_path is a path without any slashes (relative current directory),
|
||||
* @out_path will get path "./".
|
||||
**/
|
||||
void fill_pathname_basedir(char *out_path, const char *in_path, size_t size);
|
||||
|
||||
void fill_pathname_basedir_noext(char *out_dir,
|
||||
const char *in_path, size_t size);
|
||||
|
||||
/**
|
||||
* fill_pathname_parent_dir_name:
|
||||
* @out_dir : output directory
|
||||
* @in_dir : input directory
|
||||
* @size : size of output directory
|
||||
*
|
||||
* Copies only the parent directory name of @in_dir into @out_dir.
|
||||
* The two buffers must not overlap. Removes trailing '/'.
|
||||
* Returns true on success, false if a slash was not found in the path.
|
||||
**/
|
||||
bool fill_pathname_parent_dir_name(char *out_dir,
|
||||
const char *in_dir, size_t size);
|
||||
|
||||
/**
|
||||
* fill_pathname_parent_dir:
|
||||
* @out_dir : output directory
|
||||
* @in_dir : input directory
|
||||
* @size : size of output directory
|
||||
*
|
||||
* Copies parent directory of @in_dir into @out_dir.
|
||||
* Assumes @in_dir is a directory. Keeps trailing '/'.
|
||||
* If the path was already at the root directory, @out_dir will be an empty string.
|
||||
**/
|
||||
void fill_pathname_parent_dir(char *out_dir,
|
||||
const char *in_dir, size_t size);
|
||||
|
||||
/**
|
||||
* fill_pathname_resolve_relative:
|
||||
* @out_path : output path
|
||||
* @in_refpath : input reference path
|
||||
* @in_path : input path
|
||||
* @size : size of @out_path
|
||||
*
|
||||
* Joins basedir of @in_refpath together with @in_path.
|
||||
* If @in_path is an absolute path, out_path = in_path.
|
||||
* E.g.: in_refpath = "/foo/bar/baz.a", in_path = "foobar.cg",
|
||||
* out_path = "/foo/bar/foobar.cg".
|
||||
**/
|
||||
void fill_pathname_resolve_relative(char *out_path, const char *in_refpath,
|
||||
const char *in_path, size_t size);
|
||||
|
||||
/**
|
||||
* fill_pathname_join:
|
||||
* @out_path : output path
|
||||
* @dir : directory
|
||||
* @path : path
|
||||
* @size : size of output path
|
||||
*
|
||||
* Joins a directory (@dir) and path (@path) together.
|
||||
* Makes sure not to get two consecutive slashes
|
||||
* between directory and path.
|
||||
**/
|
||||
size_t fill_pathname_join(char *out_path, const char *dir,
|
||||
const char *path, size_t size);
|
||||
|
||||
size_t fill_pathname_join_special_ext(char *out_path,
|
||||
const char *dir, const char *path,
|
||||
const char *last, const char *ext,
|
||||
size_t size);
|
||||
|
||||
size_t fill_pathname_join_concat_noext(char *out_path,
|
||||
const char *dir, const char *path,
|
||||
const char *concat,
|
||||
size_t size);
|
||||
|
||||
size_t fill_pathname_join_concat(char *out_path,
|
||||
const char *dir, const char *path,
|
||||
const char *concat,
|
||||
size_t size);
|
||||
|
||||
void fill_pathname_join_noext(char *out_path,
|
||||
const char *dir, const char *path, size_t size);
|
||||
|
||||
/**
|
||||
* fill_pathname_join_delim:
|
||||
* @out_path : output path
|
||||
* @dir : directory
|
||||
* @path : path
|
||||
* @delim : delimiter
|
||||
* @size : size of output path
|
||||
*
|
||||
* Joins a directory (@dir) and path (@path) together
|
||||
* using the given delimiter (@delim).
|
||||
**/
|
||||
size_t fill_pathname_join_delim(char *out_path, const char *dir,
|
||||
const char *path, const char delim, size_t size);
|
||||
|
||||
size_t fill_pathname_join_delim_concat(char *out_path, const char *dir,
|
||||
const char *path, const char delim, const char *concat,
|
||||
size_t size);
|
||||
|
||||
/**
|
||||
* fill_short_pathname_representation:
|
||||
* @out_rep : output representation
|
||||
* @in_path : input path
|
||||
* @size : size of output representation
|
||||
*
|
||||
* Generates a short representation of path. It should only
|
||||
* be used for displaying the result; the output representation is not
|
||||
* binding in any meaningful way (for a normal path, this is the same as basename)
|
||||
* In case of more complex URLs, this should cut everything except for
|
||||
* the main image file.
|
||||
*
|
||||
* E.g.: "/path/to/game.img" -> game.img
|
||||
* "/path/to/myarchive.7z#folder/to/game.img" -> game.img
|
||||
*/
|
||||
size_t fill_short_pathname_representation(char* out_rep,
|
||||
const char *in_path, size_t size);
|
||||
|
||||
void fill_short_pathname_representation_noext(char* out_rep,
|
||||
const char *in_path, size_t size);
|
||||
|
||||
void fill_pathname_expand_special(char *out_path,
|
||||
const char *in_path, size_t size);
|
||||
|
||||
void fill_pathname_abbreviate_special(char *out_path,
|
||||
const char *in_path, size_t size);
|
||||
|
||||
void fill_pathname_abbreviated_or_relative(char *out_path, const char *in_refpath, const char *in_path, size_t size);
|
||||
|
||||
void pathname_conform_slashes_to_os(char *path);
|
||||
|
||||
void pathname_make_slashes_portable(char *path);
|
||||
|
||||
/**
|
||||
* path_basedir:
|
||||
* @path : path
|
||||
*
|
||||
* Extracts base directory by mutating path.
|
||||
* Keeps trailing '/'.
|
||||
**/
|
||||
void path_basedir_wrapper(char *path);
|
||||
|
||||
/**
|
||||
* path_char_is_slash:
|
||||
* @c : character
|
||||
*
|
||||
* Checks if character (@c) is a slash.
|
||||
*
|
||||
* Returns: true (1) if character is a slash, otherwise false (0).
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
#define PATH_CHAR_IS_SLASH(c) (((c) == '/') || ((c) == '\\'))
|
||||
#else
|
||||
#define PATH_CHAR_IS_SLASH(c) ((c) == '/')
|
||||
#endif
|
||||
|
||||
/**
|
||||
* path_default_slash and path_default_slash_c:
|
||||
*
|
||||
* Gets the default slash separator.
|
||||
*
|
||||
* Returns: default slash separator.
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
#define PATH_DEFAULT_SLASH() "\\"
|
||||
#define PATH_DEFAULT_SLASH_C() '\\'
|
||||
#else
|
||||
#define PATH_DEFAULT_SLASH() "/"
|
||||
#define PATH_DEFAULT_SLASH_C() '/'
|
||||
#endif
|
||||
|
||||
/**
|
||||
* fill_pathname_slash:
|
||||
* @path : path
|
||||
* @size : size of path
|
||||
*
|
||||
* Assumes path is a directory. Appends a slash
|
||||
* if not already there.
|
||||
**/
|
||||
void fill_pathname_slash(char *path, size_t size);
|
||||
|
||||
#if !defined(RARCH_CONSOLE) && defined(RARCH_INTERNAL)
|
||||
void fill_pathname_application_path(char *buf, size_t size);
|
||||
void fill_pathname_application_dir(char *buf, size_t size);
|
||||
void fill_pathname_home_dir(char *buf, size_t size);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* path_mkdir:
|
||||
* @dir : directory
|
||||
*
|
||||
* Create directory on filesystem.
|
||||
*
|
||||
* Returns: true (1) if directory could be created, otherwise false (0).
|
||||
**/
|
||||
bool path_mkdir(const char *dir);
|
||||
|
||||
/**
|
||||
* path_is_directory:
|
||||
* @path : path
|
||||
*
|
||||
* Checks if path is a directory.
|
||||
*
|
||||
* Returns: true (1) if path is a directory, otherwise false (0).
|
||||
*/
|
||||
bool path_is_directory(const char *path);
|
||||
|
||||
bool path_is_character_special(const char *path);
|
||||
|
||||
int path_stat(const char *path);
|
||||
|
||||
bool path_is_valid(const char *path);
|
||||
|
||||
int32_t path_get_size(const char *path);
|
||||
|
||||
bool is_path_accessible_using_standard_io(const char *path);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
|
@ -1,93 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (filters.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _LIBRETRO_SDK_FILTERS_H
|
||||
#define _LIBRETRO_SDK_FILTERS_H
|
||||
|
||||
/* for MSVC; should be benign under any circumstances */
|
||||
#define _USE_MATH_DEFINES
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <retro_inline.h>
|
||||
#include <retro_math.h>
|
||||
|
||||
static INLINE double sinc(double val)
|
||||
{
|
||||
if (fabs(val) < 0.00001)
|
||||
return 1.0;
|
||||
return sin(val) / val;
|
||||
}
|
||||
|
||||
/* Paeth prediction filter. */
|
||||
static INLINE int paeth(int a, int b, int c)
|
||||
{
|
||||
int p = a + b - c;
|
||||
int pa = abs(p - a);
|
||||
int pb = abs(p - b);
|
||||
int pc = abs(p - c);
|
||||
|
||||
if (pa <= pb && pa <= pc)
|
||||
return a;
|
||||
else if (pb <= pc)
|
||||
return b;
|
||||
return c;
|
||||
}
|
||||
|
||||
/* Modified Bessel function of first order.
|
||||
* Check Wiki for mathematical definition ... */
|
||||
static INLINE double besseli0(double x)
|
||||
{
|
||||
unsigned i;
|
||||
double sum = 0.0;
|
||||
double factorial = 1.0;
|
||||
double factorial_mult = 0.0;
|
||||
double x_pow = 1.0;
|
||||
double two_div_pow = 1.0;
|
||||
double x_sqr = x * x;
|
||||
|
||||
/* Approximate. This is an infinite sum.
|
||||
* Luckily, it converges rather fast. */
|
||||
for (i = 0; i < 18; i++)
|
||||
{
|
||||
sum += x_pow * two_div_pow / (factorial * factorial);
|
||||
|
||||
factorial_mult += 1.0;
|
||||
x_pow *= x_sqr;
|
||||
two_div_pow *= 0.25;
|
||||
factorial *= factorial_mult;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
static INLINE double kaiser_window_function(double index, double beta)
|
||||
{
|
||||
return besseli0(beta * sqrtf(1 - index * index));
|
||||
}
|
||||
|
||||
static INLINE double lanzcos_window_function(double index)
|
||||
{
|
||||
return sinc(M_PI * index);
|
||||
}
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -1,186 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (string_list.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __LIBRETRO_SDK_STRING_LIST_H
|
||||
#define __LIBRETRO_SDK_STRING_LIST_H
|
||||
|
||||
#include <retro_common_api.h>
|
||||
|
||||
#include <boolean.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
union string_list_elem_attr
|
||||
{
|
||||
bool b;
|
||||
int i;
|
||||
void *p;
|
||||
};
|
||||
|
||||
struct string_list_elem
|
||||
{
|
||||
char *data;
|
||||
void *userdata;
|
||||
union string_list_elem_attr attr;
|
||||
};
|
||||
|
||||
struct string_list
|
||||
{
|
||||
struct string_list_elem *elems;
|
||||
size_t size;
|
||||
size_t cap;
|
||||
};
|
||||
|
||||
/**
|
||||
* string_list_find_elem:
|
||||
* @list : pointer to string list
|
||||
* @elem : element to find inside the string list.
|
||||
*
|
||||
* Searches for an element (@elem) inside the string list.
|
||||
*
|
||||
* Returns: true (1) if element could be found, otherwise false (0).
|
||||
*/
|
||||
int string_list_find_elem(const struct string_list *list, const char *elem);
|
||||
|
||||
/**
|
||||
* string_list_find_elem_prefix:
|
||||
* @list : pointer to string list
|
||||
* @prefix : prefix to append to @elem
|
||||
* @elem : element to find inside the string list.
|
||||
*
|
||||
* Searches for an element (@elem) inside the string list. Will
|
||||
* also search for the same element prefixed by @prefix.
|
||||
*
|
||||
* Returns: true (1) if element could be found, otherwise false (0).
|
||||
*/
|
||||
bool string_list_find_elem_prefix(const struct string_list *list,
|
||||
const char *prefix, const char *elem);
|
||||
|
||||
/**
|
||||
* string_split:
|
||||
* @str : string to turn into a string list
|
||||
* @delim : delimiter character to use for splitting the string.
|
||||
*
|
||||
* Creates a new string list based on string @str, delimited by @delim.
|
||||
*
|
||||
* Returns: new string list if successful, otherwise NULL.
|
||||
*/
|
||||
struct string_list *string_split(const char *str, const char *delim);
|
||||
|
||||
bool string_split_noalloc(struct string_list *list,
|
||||
const char *str, const char *delim);
|
||||
|
||||
/**
|
||||
* string_separate:
|
||||
* @str : string to turn into a string list
|
||||
* @delim : delimiter character to use for separating the string.
|
||||
*
|
||||
* Creates a new string list based on string @str, delimited by @delim.
|
||||
* Includes empty strings - i.e. two adjacent delimiters will resolve
|
||||
* to a string list element of "".
|
||||
*
|
||||
* Returns: new string list if successful, otherwise NULL.
|
||||
*/
|
||||
struct string_list *string_separate(char *str, const char *delim);
|
||||
|
||||
bool string_separate_noalloc(struct string_list *list,
|
||||
char *str, const char *delim);
|
||||
|
||||
bool string_list_deinitialize(struct string_list *list);
|
||||
|
||||
bool string_list_initialize(struct string_list *list);
|
||||
|
||||
/**
|
||||
* string_list_new:
|
||||
*
|
||||
* Creates a new string list. Has to be freed manually.
|
||||
*
|
||||
* Returns: new string list if successful, otherwise NULL.
|
||||
*/
|
||||
struct string_list *string_list_new(void);
|
||||
|
||||
/**
|
||||
* string_list_append:
|
||||
* @list : pointer to string list
|
||||
* @elem : element to add to the string list
|
||||
* @attr : attributes of new element.
|
||||
*
|
||||
* Appends a new element to the string list.
|
||||
*
|
||||
* Returns: true (1) if successful, otherwise false (0).
|
||||
**/
|
||||
bool string_list_append(struct string_list *list, const char *elem,
|
||||
union string_list_elem_attr attr);
|
||||
|
||||
/**
|
||||
* string_list_append_n:
|
||||
* @list : pointer to string list
|
||||
* @elem : element to add to the string list
|
||||
* @length : read at most this many bytes from elem
|
||||
* @attr : attributes of new element.
|
||||
*
|
||||
* Appends a new element to the string list.
|
||||
*
|
||||
* Returns: true (1) if successful, otherwise false (0).
|
||||
**/
|
||||
bool string_list_append_n(struct string_list *list, const char *elem,
|
||||
unsigned length, union string_list_elem_attr attr);
|
||||
|
||||
/**
|
||||
* string_list_free
|
||||
* @list : pointer to string list object
|
||||
*
|
||||
* Frees a string list.
|
||||
*/
|
||||
void string_list_free(struct string_list *list);
|
||||
|
||||
/**
|
||||
* string_list_join_concat:
|
||||
* @buffer : buffer that @list will be joined to.
|
||||
* @size : length of @buffer.
|
||||
* @list : pointer to string list.
|
||||
* @delim : delimiter character for @list.
|
||||
*
|
||||
* A string list will be joined/concatenated as a
|
||||
* string to @buffer, delimited by @delim.
|
||||
*/
|
||||
void string_list_join_concat(char *buffer, size_t size,
|
||||
const struct string_list *list, const char *sep);
|
||||
|
||||
/**
|
||||
* string_list_set:
|
||||
* @list : pointer to string list
|
||||
* @idx : index of element in string list
|
||||
* @str : value for the element.
|
||||
*
|
||||
* Set value of element inside string list.
|
||||
**/
|
||||
void string_list_set(struct string_list *list, unsigned idx,
|
||||
const char *str);
|
||||
|
||||
struct string_list *string_list_clone(const struct string_list *src);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
|
@ -1,42 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (memalign.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _LIBRETRO_MEMALIGN_H
|
||||
#define _LIBRETRO_MEMALIGN_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <retro_common_api.h>
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
void *memalign_alloc(size_t boundary, size_t size);
|
||||
|
||||
void *memalign_calloc(size_t boundary, size_t unit, size_t size);
|
||||
|
||||
void *memalign_alloc_aligned(size_t size);
|
||||
|
||||
void memalign_free(void *ptr);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
|
@ -1,35 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (retro_assert.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __RETRO_ASSERT_H
|
||||
#define __RETRO_ASSERT_H
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef RARCH_INTERNAL
|
||||
#include <stdio.h>
|
||||
#define retro_assert(cond) ((void)( (cond) || (printf("Assertion failed at %s:%d.\n", __FILE__, __LINE__), abort(), 0) ))
|
||||
#else
|
||||
#define retro_assert(cond) assert(cond)
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,119 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (retro_common_api.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _LIBRETRO_COMMON_RETRO_COMMON_API_H
|
||||
#define _LIBRETRO_COMMON_RETRO_COMMON_API_H
|
||||
|
||||
/*
|
||||
This file is designed to normalize the libretro-common compiling environment
|
||||
for public API headers. This should be leaner than a normal compiling environment,
|
||||
since it gets #included into other project's sources.
|
||||
*/
|
||||
|
||||
/* ------------------------------------ */
|
||||
|
||||
/*
|
||||
Ordinarily we want to put #ifdef __cplusplus extern "C" in C library
|
||||
headers to enable them to get used by c++ sources.
|
||||
However, we want to support building this library as C++ as well, so a
|
||||
special technique is called for.
|
||||
*/
|
||||
|
||||
#define RETRO_BEGIN_DECLS
|
||||
#define RETRO_END_DECLS
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#ifdef CXX_BUILD
|
||||
/* build wants everything to be built as c++, so no extern "C" */
|
||||
#else
|
||||
#undef RETRO_BEGIN_DECLS
|
||||
#undef RETRO_END_DECLS
|
||||
#define RETRO_BEGIN_DECLS extern "C" {
|
||||
#define RETRO_END_DECLS }
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
/* header is included by a C source file, so no extern "C" */
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
IMO, this non-standard ssize_t should not be used.
|
||||
However, it's a good example of how to handle something like this.
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
#ifndef HAVE_SSIZE_T
|
||||
#define HAVE_SSIZE_T
|
||||
#if defined(_WIN64)
|
||||
typedef __int64 ssize_t;
|
||||
#elif defined(_WIN32)
|
||||
typedef int ssize_t;
|
||||
#endif
|
||||
#endif
|
||||
#elif defined(__MACH__)
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if _MSC_VER >= 1800
|
||||
#include <inttypes.h>
|
||||
#else
|
||||
#ifndef PRId64
|
||||
#define PRId64 "I64d"
|
||||
#define PRIu64 "I64u"
|
||||
#define PRIuPTR "Iu"
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
/* C++11 says this one isn't needed, but apparently (some versions of) mingw require it anyways */
|
||||
/* https://stackoverflow.com/questions/8132399/how-to-printf-uint64-t-fails-with-spurious-trailing-in-format */
|
||||
/* https://github.com/libretro/RetroArch/issues/6009 */
|
||||
#ifndef __STDC_FORMAT_MACROS
|
||||
#define __STDC_FORMAT_MACROS 1
|
||||
#endif
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
#ifndef PRId64
|
||||
#error "inttypes.h is being screwy"
|
||||
#endif
|
||||
#define STRING_REP_INT64 "%" PRId64
|
||||
#define STRING_REP_UINT64 "%" PRIu64
|
||||
#define STRING_REP_USIZE "%" PRIuPTR
|
||||
|
||||
/*
|
||||
I would like to see retro_inline.h moved in here; possibly boolean too.
|
||||
|
||||
rationale: these are used in public APIs, and it is easier to find problems
|
||||
and write code that works the first time portably when theyre included uniformly
|
||||
than to do the analysis from scratch each time you think you need it, for each feature.
|
||||
|
||||
Moreover it helps force you to make hard decisions: if you EVER bring in boolean.h,
|
||||
then you should pay the price everywhere, so you can see how much grief it will cause.
|
||||
|
||||
Of course, another school of thought is that you should do as little damage as possible
|
||||
in as few places as possible...
|
||||
*/
|
||||
|
||||
/* _LIBRETRO_COMMON_RETRO_COMMON_API_H */
|
||||
#endif
|
|
@ -1,114 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (retro_environment.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __LIBRETRO_SDK_ENVIRONMENT_H
|
||||
#define __LIBRETRO_SDK_ENVIRONMENT_H
|
||||
|
||||
/*
|
||||
This file is designed to create a normalized environment for compiling
|
||||
libretro-common's private implementations, or any other sources which might
|
||||
enjoy use of it's environment (RetroArch for instance).
|
||||
This should be an elaborately crafted environment so that sources don't
|
||||
need to be full of platform-specific workarounds.
|
||||
*/
|
||||
|
||||
#if defined (__cplusplus)
|
||||
#if 0
|
||||
printf("This is C++, version %d.\n", __cplusplus);
|
||||
#endif
|
||||
/* The expected values would be
|
||||
* 199711L, for ISO/IEC 14882:1998 or 14882:2003
|
||||
*/
|
||||
|
||||
#elif defined(__STDC__)
|
||||
/* This is standard C. */
|
||||
|
||||
#if (__STDC__ == 1)
|
||||
/* The implementation is ISO-conforming. */
|
||||
#define __STDC_ISO__
|
||||
#else
|
||||
/* The implementation is not ISO-conforming. */
|
||||
#endif
|
||||
|
||||
#if defined(__STDC_VERSION__)
|
||||
#if (__STDC_VERSION__ >= 201112L)
|
||||
/* This is C11. */
|
||||
#define __STDC_C11__
|
||||
#elif (__STDC_VERSION__ >= 199901L)
|
||||
/* This is C99. */
|
||||
#define __STDC_C99__
|
||||
#elif (__STDC_VERSION__ >= 199409L)
|
||||
/* This is C89 with amendment 1. */
|
||||
#define __STDC_C89__
|
||||
#define __STDC_C89_AMENDMENT_1__
|
||||
#else
|
||||
/* This is C89 without amendment 1. */
|
||||
#define __STDC_C89__
|
||||
#endif
|
||||
#else /* !defined(__STDC_VERSION__) */
|
||||
/* This is C89. __STDC_VERSION__ is not defined. */
|
||||
#define __STDC_C89__
|
||||
#endif
|
||||
|
||||
#else /* !defined(__STDC__) */
|
||||
/* This is not standard C. __STDC__ is not defined. */
|
||||
#endif
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__)
|
||||
/* Try to find out if we're compiling for WinRT or non-WinRT */
|
||||
#if defined(_MSC_VER) && defined(__has_include)
|
||||
#if __has_include(<winapifamily.h>)
|
||||
#define HAVE_WINAPIFAMILY_H 1
|
||||
#else
|
||||
#define HAVE_WINAPIFAMILY_H 0
|
||||
#endif
|
||||
|
||||
/* If _USING_V110_SDK71_ is defined it means we are using the Windows XP toolset. */
|
||||
#elif defined(_MSC_VER) && (_MSC_VER >= 1700 && !_USING_V110_SDK71_) /* _MSC_VER == 1700 for Visual Studio 2012 */
|
||||
#define HAVE_WINAPIFAMILY_H 1
|
||||
#else
|
||||
#define HAVE_WINAPIFAMILY_H 0
|
||||
#endif
|
||||
|
||||
#if HAVE_WINAPIFAMILY_H
|
||||
#include <winapifamily.h>
|
||||
#define WINAPI_FAMILY_WINRT (!WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP))
|
||||
#else
|
||||
#define WINAPI_FAMILY_WINRT 0
|
||||
#endif /* HAVE_WINAPIFAMILY_H */
|
||||
|
||||
#if WINAPI_FAMILY_WINRT
|
||||
#undef __WINRT__
|
||||
#define __WINRT__ 1
|
||||
#endif
|
||||
|
||||
/* MSVC obviously has to have some non-standard constants... */
|
||||
#if _M_IX86_FP == 1
|
||||
#define __SSE__ 1
|
||||
#elif _M_IX86_FP == 2 || (defined(_M_AMD64) || defined(_M_X64))
|
||||
#define __SSE__ 1
|
||||
#define __SSE2__ 1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,39 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (retro_inline.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __LIBRETRO_SDK_INLINE_H
|
||||
#define __LIBRETRO_SDK_INLINE_H
|
||||
|
||||
#ifndef INLINE
|
||||
|
||||
#if defined(_WIN32) || defined(__INTEL_COMPILER)
|
||||
#define INLINE __inline
|
||||
#elif defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L
|
||||
#define INLINE inline
|
||||
#elif defined(__GNUC__)
|
||||
#define INLINE __inline__
|
||||
#else
|
||||
#define INLINE
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -1,190 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (retro_math.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _LIBRETRO_COMMON_MATH_H
|
||||
#define _LIBRETRO_COMMON_MATH_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#elif defined(_WIN32) && defined(_XBOX)
|
||||
#include <Xtl.h>
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <compat/msvc.h>
|
||||
#endif
|
||||
#include <retro_inline.h>
|
||||
|
||||
#ifndef M_PI
|
||||
#if !defined(USE_MATH_DEFINES)
|
||||
#define M_PI 3.14159265358979323846264338327
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* next_pow2:
|
||||
* @v : initial value
|
||||
*
|
||||
* Get next power of 2 value based on initial value.
|
||||
*
|
||||
* Returns: next power of 2 value (derived from @v).
|
||||
**/
|
||||
static INLINE uint32_t next_pow2(uint32_t v)
|
||||
{
|
||||
v--;
|
||||
v |= v >> 1;
|
||||
v |= v >> 2;
|
||||
v |= v >> 4;
|
||||
v |= v >> 8;
|
||||
v |= v >> 16;
|
||||
v++;
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* prev_pow2:
|
||||
* @v : initial value
|
||||
*
|
||||
* Get previous power of 2 value based on initial value.
|
||||
*
|
||||
* Returns: previous power of 2 value (derived from @v).
|
||||
**/
|
||||
static INLINE uint32_t prev_pow2(uint32_t v)
|
||||
{
|
||||
v |= v >> 1;
|
||||
v |= v >> 2;
|
||||
v |= v >> 4;
|
||||
v |= v >> 8;
|
||||
v |= v >> 16;
|
||||
return v - (v >> 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* clamp:
|
||||
* @v : initial value
|
||||
*
|
||||
* Get the clamped value based on initial value.
|
||||
*
|
||||
* Returns: clamped value (derived from @v).
|
||||
**/
|
||||
static INLINE float clamp_value(float v, float min, float max)
|
||||
{
|
||||
return v <= min ? min : v >= max ? max : v;
|
||||
}
|
||||
|
||||
/**
|
||||
* saturate_value:
|
||||
* @v : initial value
|
||||
*
|
||||
* Get the clamped 0.0-1.0 value based on initial value.
|
||||
*
|
||||
* Returns: clamped 0.0-1.0 value (derived from @v).
|
||||
**/
|
||||
static INLINE float saturate_value(float v)
|
||||
{
|
||||
return clamp_value(v, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* dot_product:
|
||||
* @a : left hand vector value
|
||||
* @b : right hand vector value
|
||||
*
|
||||
* Get the dot product of the two passed in vectors.
|
||||
*
|
||||
* Returns: dot product value (derived from @a and @b).
|
||||
**/
|
||||
static INLINE float dot_product(const float* a, const float* b)
|
||||
{
|
||||
return (a[0] * b[0]) + (a[1] * b[1]) + (a[2] * b[2]);
|
||||
}
|
||||
|
||||
/**
|
||||
* convert_rgb_to_yxy:
|
||||
* @rgb : in RGB colour space value
|
||||
* @Yxy : out Yxy colour space value
|
||||
*
|
||||
* Convert from RGB colour space to Yxy colour space.
|
||||
*
|
||||
* Returns: Yxy colour space value (derived from @rgb).
|
||||
**/
|
||||
static INLINE void convert_rgb_to_yxy(const float* rgb, float* Yxy)
|
||||
{
|
||||
float inv;
|
||||
float xyz[3];
|
||||
float one[3] = {1.0, 1.0, 1.0};
|
||||
float rgb_xyz[3][3] = {
|
||||
{0.4124564, 0.3575761, 0.1804375},
|
||||
{0.2126729, 0.7151522, 0.0721750},
|
||||
{0.0193339, 0.1191920, 0.9503041}
|
||||
};
|
||||
|
||||
xyz[0] = dot_product(rgb_xyz[0], rgb);
|
||||
xyz[1] = dot_product(rgb_xyz[1], rgb);
|
||||
xyz[2] = dot_product(rgb_xyz[2], rgb);
|
||||
|
||||
inv = 1.0f / dot_product(xyz, one);
|
||||
Yxy[0] = xyz[1];
|
||||
Yxy[1] = xyz[0] * inv;
|
||||
Yxy[2] = xyz[1] * inv;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert_yxy_to_rgb:
|
||||
* @rgb : in Yxy colour space value
|
||||
* @Yxy : out rgb colour space value
|
||||
*
|
||||
* Convert from Yxy colour space to rgb colour space.
|
||||
*
|
||||
* Returns: rgb colour space value (derived from @Yxy).
|
||||
**/
|
||||
static INLINE void convert_yxy_to_rgb(const float* Yxy, float* rgb)
|
||||
{
|
||||
float xyz[3];
|
||||
float xyz_rgb[3][3] = {
|
||||
{3.2404542, -1.5371385, -0.4985314},
|
||||
{-0.9692660, 1.8760108, 0.0415560},
|
||||
{0.0556434, -0.2040259, 1.0572252}
|
||||
};
|
||||
xyz[0] = Yxy[0] * Yxy[1] / Yxy[2];
|
||||
xyz[1] = Yxy[0];
|
||||
xyz[2] = Yxy[0] * (1.0 - Yxy[1] - Yxy[2]) / Yxy[2];
|
||||
|
||||
rgb[0] = dot_product(xyz_rgb[0], xyz);
|
||||
rgb[1] = dot_product(xyz_rgb[1], xyz);
|
||||
rgb[2] = dot_product(xyz_rgb[2], xyz);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,207 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (retro_miscellaneous.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __RARCH_MISCELLANEOUS_H
|
||||
#define __RARCH_MISCELLANEOUS_H
|
||||
|
||||
#define RARCH_MAX_SUBSYSTEMS 10
|
||||
#define RARCH_MAX_SUBSYSTEM_ROMS 10
|
||||
|
||||
#include <stdint.h>
|
||||
#include <boolean.h>
|
||||
#include <retro_inline.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
#if defined(_XBOX)
|
||||
#include <Xtl.h>
|
||||
#else
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <compat/msvc.h>
|
||||
#endif
|
||||
|
||||
static INLINE void bits_or_bits(uint32_t *a, uint32_t *b, uint32_t count)
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = 0; i < count;i++)
|
||||
a[i] |= b[i];
|
||||
}
|
||||
|
||||
static INLINE void bits_clear_bits(uint32_t *a, uint32_t *b, uint32_t count)
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = 0; i < count;i++)
|
||||
a[i] &= ~b[i];
|
||||
}
|
||||
|
||||
static INLINE bool bits_any_set(uint32_t* ptr, uint32_t count)
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (ptr[i] != 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifndef PATH_MAX_LENGTH
|
||||
#if defined(_XBOX1) || defined(_3DS) || defined(PSP) || defined(PS2) || defined(GEKKO)|| defined(WIIU) || defined(ORBIS) || defined(__PSL1GHT__) || defined(__PS3__)
|
||||
#define PATH_MAX_LENGTH 512
|
||||
#else
|
||||
#define PATH_MAX_LENGTH 4096
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef NAME_MAX_LENGTH
|
||||
#define NAME_MAX_LENGTH 256
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||
|
||||
#define BITS_GET_ELEM(a, i) ((a).data[i])
|
||||
#define BITS_GET_ELEM_PTR(a, i) ((a)->data[i])
|
||||
|
||||
#define BIT_SET(a, bit) ((a)[(bit) >> 3] |= (1 << ((bit) & 7)))
|
||||
#define BIT_CLEAR(a, bit) ((a)[(bit) >> 3] &= ~(1 << ((bit) & 7)))
|
||||
#define BIT_GET(a, bit) (((a)[(bit) >> 3] >> ((bit) & 7)) & 1)
|
||||
|
||||
#define BIT16_SET(a, bit) ((a) |= (1 << ((bit) & 15)))
|
||||
#define BIT16_CLEAR(a, bit) ((a) &= ~(1 << ((bit) & 15)))
|
||||
#define BIT16_GET(a, bit) (((a) >> ((bit) & 15)) & 1)
|
||||
#define BIT16_CLEAR_ALL(a) ((a) = 0)
|
||||
|
||||
#define BIT32_SET(a, bit) ((a) |= (UINT32_C(1) << ((bit) & 31)))
|
||||
#define BIT32_CLEAR(a, bit) ((a) &= ~(UINT32_C(1) << ((bit) & 31)))
|
||||
#define BIT32_GET(a, bit) (((a) >> ((bit) & 31)) & 1)
|
||||
#define BIT32_CLEAR_ALL(a) ((a) = 0)
|
||||
|
||||
#define BIT64_SET(a, bit) ((a) |= (UINT64_C(1) << ((bit) & 63)))
|
||||
#define BIT64_CLEAR(a, bit) ((a) &= ~(UINT64_C(1) << ((bit) & 63)))
|
||||
#define BIT64_GET(a, bit) (((a) >> ((bit) & 63)) & 1)
|
||||
#define BIT64_CLEAR_ALL(a) ((a) = 0)
|
||||
|
||||
#define BIT128_SET(a, bit) ((a).data[(bit) >> 5] |= (UINT32_C(1) << ((bit) & 31)))
|
||||
#define BIT128_CLEAR(a, bit) ((a).data[(bit) >> 5] &= ~(UINT32_C(1) << ((bit) & 31)))
|
||||
#define BIT128_GET(a, bit) (((a).data[(bit) >> 5] >> ((bit) & 31)) & 1)
|
||||
#define BIT128_CLEAR_ALL(a) memset(&(a), 0, sizeof(a))
|
||||
|
||||
#define BIT128_SET_PTR(a, bit) BIT128_SET(*a, bit)
|
||||
#define BIT128_CLEAR_PTR(a, bit) BIT128_CLEAR(*a, bit)
|
||||
#define BIT128_GET_PTR(a, bit) BIT128_GET(*a, bit)
|
||||
#define BIT128_CLEAR_ALL_PTR(a) BIT128_CLEAR_ALL(*a)
|
||||
|
||||
#define BIT256_SET(a, bit) BIT128_SET(a, bit)
|
||||
#define BIT256_CLEAR(a, bit) BIT128_CLEAR(a, bit)
|
||||
#define BIT256_GET(a, bit) BIT128_GET(a, bit)
|
||||
#define BIT256_CLEAR_ALL(a) BIT128_CLEAR_ALL(a)
|
||||
|
||||
#define BIT256_SET_PTR(a, bit) BIT256_SET(*a, bit)
|
||||
#define BIT256_CLEAR_PTR(a, bit) BIT256_CLEAR(*a, bit)
|
||||
#define BIT256_GET_PTR(a, bit) BIT256_GET(*a, bit)
|
||||
#define BIT256_CLEAR_ALL_PTR(a) BIT256_CLEAR_ALL(*a)
|
||||
|
||||
#define BIT512_SET(a, bit) BIT256_SET(a, bit)
|
||||
#define BIT512_CLEAR(a, bit) BIT256_CLEAR(a, bit)
|
||||
#define BIT512_GET(a, bit) BIT256_GET(a, bit)
|
||||
#define BIT512_CLEAR_ALL(a) BIT256_CLEAR_ALL(a)
|
||||
|
||||
#define BIT512_SET_PTR(a, bit) BIT512_SET(*a, bit)
|
||||
#define BIT512_CLEAR_PTR(a, bit) BIT512_CLEAR(*a, bit)
|
||||
#define BIT512_GET_PTR(a, bit) BIT512_GET(*a, bit)
|
||||
#define BIT512_CLEAR_ALL_PTR(a) BIT512_CLEAR_ALL(*a)
|
||||
|
||||
#define BITS_COPY16_PTR(a,bits) \
|
||||
{ \
|
||||
BIT128_CLEAR_ALL_PTR(a); \
|
||||
BITS_GET_ELEM_PTR(a, 0) = (bits) & 0xffff; \
|
||||
}
|
||||
|
||||
#define BITS_COPY32_PTR(a,bits) \
|
||||
{ \
|
||||
BIT128_CLEAR_ALL_PTR(a); \
|
||||
BITS_GET_ELEM_PTR(a, 0) = (bits); \
|
||||
}
|
||||
|
||||
#define BITS_COPY64_PTR(a,bits) \
|
||||
{ \
|
||||
BIT128_CLEAR_ALL_PTR(a); \
|
||||
BITS_GET_ELEM_PTR(a, 0) = (bits); \
|
||||
BITS_GET_ELEM_PTR(a, 1) = (bits >> 32); \
|
||||
}
|
||||
|
||||
/* Helper macros and struct to keep track of many booleans. */
|
||||
/* This struct has 256 bits. */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t data[8];
|
||||
} retro_bits_t;
|
||||
|
||||
/* This struct has 512 bits. */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t data[16];
|
||||
} retro_bits_512_t;
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifdef _WIN64
|
||||
# define PRI_SIZET PRIu64
|
||||
# else
|
||||
# if _MSC_VER == 1800
|
||||
# define PRI_SIZET PRIu32
|
||||
# else
|
||||
# define PRI_SIZET "u"
|
||||
# endif
|
||||
# endif
|
||||
#elif defined(PS2)
|
||||
# define PRI_SIZET "u"
|
||||
#else
|
||||
# if (SIZE_MAX == 0xFFFF)
|
||||
# define PRI_SIZET "hu"
|
||||
# elif (SIZE_MAX == 0xFFFFFFFF)
|
||||
# define PRI_SIZET "u"
|
||||
# elif (SIZE_MAX == 0xFFFFFFFFFFFFFFFF)
|
||||
# define PRI_SIZET "lu"
|
||||
# else
|
||||
# error PRI_SIZET: unknown SIZE_MAX
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,112 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (retro_timers.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __LIBRETRO_COMMON_TIMERS_H
|
||||
#define __LIBRETRO_COMMON_TIMERS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(XENON)
|
||||
#include <time/time.h>
|
||||
#elif !defined(__PSL1GHT__) && defined(__PS3__)
|
||||
#include <sys/timer.h>
|
||||
#elif defined(GEKKO) || defined(__PSL1GHT__) || defined(__QNX__)
|
||||
#include <unistd.h>
|
||||
#elif defined(WIIU)
|
||||
#include <wiiu/os/thread.h>
|
||||
#elif defined(PSP)
|
||||
#include <pspthreadman.h>
|
||||
#elif defined(VITA)
|
||||
#include <psp2/kernel/threadmgr.h>
|
||||
#elif defined(_3DS)
|
||||
#include <3ds.h>
|
||||
#else
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#elif defined(_WIN32) && defined(_XBOX)
|
||||
#include <Xtl.h>
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <compat/msvc.h>
|
||||
#endif
|
||||
#include <retro_inline.h>
|
||||
|
||||
#ifdef DJGPP
|
||||
#define timespec timeval
|
||||
#define tv_nsec tv_usec
|
||||
#include <unistd.h>
|
||||
|
||||
extern int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
|
||||
|
||||
static int nanosleepDOS(const struct timespec *rqtp, struct timespec *rmtp)
|
||||
{
|
||||
usleep(1000000L * rqtp->tv_sec + rqtp->tv_nsec / 1000);
|
||||
|
||||
if (rmtp)
|
||||
rmtp->tv_sec = rmtp->tv_nsec=0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define nanosleep nanosleepDOS
|
||||
#endif
|
||||
|
||||
/**
|
||||
* retro_sleep:
|
||||
* @msec : amount in milliseconds to sleep
|
||||
*
|
||||
* Sleeps for a specified amount of milliseconds (@msec).
|
||||
**/
|
||||
#if defined(PSP) || defined(VITA)
|
||||
#define retro_sleep(msec) (sceKernelDelayThread(1000 * (msec)))
|
||||
#elif defined(_3DS)
|
||||
#define retro_sleep(msec) (svcSleepThread(1000000 * (s64)(msec)))
|
||||
#elif defined(__WINRT__) || defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
|
||||
#define retro_sleep(msec) (SleepEx((msec), FALSE))
|
||||
#elif defined(_WIN32)
|
||||
#define retro_sleep(msec) (Sleep((msec)))
|
||||
#elif defined(XENON)
|
||||
#define retro_sleep(msec) (udelay(1000 * (msec)))
|
||||
#elif !defined(__PSL1GHT__) && defined(__PS3__)
|
||||
#define retro_sleep(msec) (sys_timer_usleep(1000 * (msec)))
|
||||
#elif defined(GEKKO) || defined(__PSL1GHT__) || defined(__QNX__)
|
||||
#define retro_sleep(msec) (usleep(1000 * (msec)))
|
||||
#elif defined(WIIU)
|
||||
#define retro_sleep(msec) (OSSleepTicks(ms_to_ticks((msec))))
|
||||
#else
|
||||
#define retro_sleep(msec) \
|
||||
{ \
|
||||
struct timespec tv = {0}; \
|
||||
tv.tv_sec = msec / 1000; \
|
||||
tv.tv_nsec = (msec % 1000) * 1000000; \
|
||||
nanosleep(&tv, NULL); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,117 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (file_stream.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __LIBRETRO_SDK_FILE_STREAM_H
|
||||
#define __LIBRETRO_SDK_FILE_STREAM_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <libretro.h>
|
||||
#include <retro_common_api.h>
|
||||
#include <retro_inline.h>
|
||||
#include <boolean.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <vfs/vfs_implementation.h>
|
||||
|
||||
#define FILESTREAM_REQUIRED_VFS_VERSION 2
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
typedef struct RFILE RFILE;
|
||||
|
||||
#define FILESTREAM_REQUIRED_VFS_VERSION 2
|
||||
|
||||
void filestream_vfs_init(const struct retro_vfs_interface_info* vfs_info);
|
||||
|
||||
int64_t filestream_get_size(RFILE *stream);
|
||||
|
||||
int64_t filestream_truncate(RFILE *stream, int64_t length);
|
||||
|
||||
/**
|
||||
* filestream_open:
|
||||
* @path : path to file
|
||||
* @mode : file mode to use when opening (read/write)
|
||||
* @bufsize : optional buffer size (-1 or 0 to use default)
|
||||
*
|
||||
* Opens a file for reading or writing, depending on the requested mode.
|
||||
* Returns a pointer to an RFILE if opened successfully, otherwise NULL.
|
||||
**/
|
||||
RFILE* filestream_open(const char *path, unsigned mode, unsigned hints);
|
||||
|
||||
int64_t filestream_seek(RFILE *stream, int64_t offset, int seek_position);
|
||||
|
||||
int64_t filestream_read(RFILE *stream, void *data, int64_t len);
|
||||
|
||||
int64_t filestream_write(RFILE *stream, const void *data, int64_t len);
|
||||
|
||||
int64_t filestream_tell(RFILE *stream);
|
||||
|
||||
void filestream_rewind(RFILE *stream);
|
||||
|
||||
int filestream_close(RFILE *stream);
|
||||
|
||||
int64_t filestream_read_file(const char *path, void **buf, int64_t *len);
|
||||
|
||||
char* filestream_gets(RFILE *stream, char *s, size_t len);
|
||||
|
||||
int filestream_getc(RFILE *stream);
|
||||
|
||||
int filestream_vscanf(RFILE *stream, const char* format, va_list *args);
|
||||
|
||||
int filestream_scanf(RFILE *stream, const char* format, ...);
|
||||
|
||||
int filestream_eof(RFILE *stream);
|
||||
|
||||
bool filestream_write_file(const char *path, const void *data, int64_t size);
|
||||
|
||||
int filestream_putc(RFILE *stream, int c);
|
||||
|
||||
int filestream_vprintf(RFILE *stream, const char* format, va_list args);
|
||||
|
||||
int filestream_printf(RFILE *stream, const char* format, ...);
|
||||
|
||||
int filestream_error(RFILE *stream);
|
||||
|
||||
int filestream_flush(RFILE *stream);
|
||||
|
||||
int filestream_delete(const char *path);
|
||||
|
||||
int filestream_rename(const char *old_path, const char *new_path);
|
||||
|
||||
const char* filestream_get_path(RFILE *stream);
|
||||
|
||||
bool filestream_exists(const char *path);
|
||||
|
||||
/* Returned pointer must be freed by the caller. */
|
||||
char* filestream_getline(RFILE *stream);
|
||||
|
||||
libretro_vfs_implementation_file* filestream_get_vfs_handle(RFILE *stream);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
|
@ -1,269 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (stdstring.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __LIBRETRO_SDK_STDSTRING_H
|
||||
#define __LIBRETRO_SDK_STDSTRING_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <boolean.h>
|
||||
|
||||
#include <retro_common_api.h>
|
||||
#include <retro_inline.h>
|
||||
#include <compat/strl.h>
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
#define STRLEN_CONST(x) ((sizeof((x))-1))
|
||||
|
||||
#define strcpy_literal(a, b) strcpy(a, b)
|
||||
|
||||
#define string_is_not_equal(a, b) !string_is_equal((a), (b))
|
||||
|
||||
#define string_is_not_equal_fast(a, b, size) (memcmp(a, b, size) != 0)
|
||||
#define string_is_equal_fast(a, b, size) (memcmp(a, b, size) == 0)
|
||||
|
||||
#define TOLOWER(c) ((c) | (lr_char_props[(unsigned char)(c)] & 0x20))
|
||||
#define TOUPPER(c) ((c) & ~(lr_char_props[(unsigned char)(c)] & 0x20))
|
||||
|
||||
/* C standard says \f \v are space, but this one disagrees */
|
||||
#define ISSPACE(c) (lr_char_props[(unsigned char)(c)] & 0x80)
|
||||
|
||||
#define ISDIGIT(c) (lr_char_props[(unsigned char)(c)] & 0x40)
|
||||
#define ISALPHA(c) (lr_char_props[(unsigned char)(c)] & 0x20)
|
||||
#define ISLOWER(c) (lr_char_props[(unsigned char)(c)] & 0x04)
|
||||
#define ISUPPER(c) (lr_char_props[(unsigned char)(c)] & 0x02)
|
||||
#define ISALNUM(c) (lr_char_props[(unsigned char)(c)] & 0x60)
|
||||
#define ISUALPHA(c) (lr_char_props[(unsigned char)(c)] & 0x28)
|
||||
#define ISUALNUM(c) (lr_char_props[(unsigned char)(c)] & 0x68)
|
||||
#define IS_XDIGIT(c) (lr_char_props[(unsigned char)(c)] & 0x01)
|
||||
|
||||
/* Deprecated alias, all callers should use string_is_equal_case_insensitive instead */
|
||||
#define string_is_equal_noncase string_is_equal_case_insensitive
|
||||
|
||||
static INLINE bool string_is_empty(const char *data)
|
||||
{
|
||||
return !data || (*data == '\0');
|
||||
}
|
||||
|
||||
static INLINE bool string_is_equal(const char *a, const char *b)
|
||||
{
|
||||
return (a && b) ? !strcmp(a, b) : false;
|
||||
}
|
||||
|
||||
static INLINE bool string_starts_with_size(const char *str, const char *prefix,
|
||||
size_t size)
|
||||
{
|
||||
return (str && prefix) ? !strncmp(prefix, str, size) : false;
|
||||
}
|
||||
|
||||
static INLINE bool string_starts_with(const char *str, const char *prefix)
|
||||
{
|
||||
return (str && prefix) ? !strncmp(prefix, str, strlen(prefix)) : false;
|
||||
}
|
||||
|
||||
static INLINE bool string_ends_with_size(const char *str, const char *suffix,
|
||||
size_t str_len, size_t suffix_len)
|
||||
{
|
||||
return (str_len < suffix_len) ? false :
|
||||
!memcmp(suffix, str + (str_len - suffix_len), suffix_len);
|
||||
}
|
||||
|
||||
static INLINE bool string_ends_with(const char *str, const char *suffix)
|
||||
{
|
||||
if (!str || !suffix)
|
||||
return false;
|
||||
return string_ends_with_size(str, suffix, strlen(str), strlen(suffix));
|
||||
}
|
||||
|
||||
/* Returns the length of 'str' (c.f. strlen()), but only
|
||||
* checks the first 'size' characters
|
||||
* - If 'str' is NULL, returns 0
|
||||
* - If 'str' is not NULL and no '\0' character is found
|
||||
* in the first 'size' characters, returns 'size' */
|
||||
static INLINE size_t strlen_size(const char *str, size_t size)
|
||||
{
|
||||
size_t i = 0;
|
||||
if (str)
|
||||
while (i < size && str[i]) i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
static INLINE bool string_is_equal_case_insensitive(const char *a,
|
||||
const char *b)
|
||||
{
|
||||
int result = 0;
|
||||
const unsigned char *p1 = (const unsigned char*)a;
|
||||
const unsigned char *p2 = (const unsigned char*)b;
|
||||
|
||||
if (!a || !b)
|
||||
return false;
|
||||
if (p1 == p2)
|
||||
return true;
|
||||
|
||||
while ((result = tolower (*p1) - tolower (*p2++)) == 0)
|
||||
if (*p1++ == '\0')
|
||||
break;
|
||||
|
||||
return (result == 0);
|
||||
}
|
||||
|
||||
static INLINE bool string_starts_with_case_insensitive(const char *str,
|
||||
const char *prefix)
|
||||
{
|
||||
int result = 0;
|
||||
const unsigned char *p1 = (const unsigned char*)str;
|
||||
const unsigned char *p2 = (const unsigned char*)prefix;
|
||||
|
||||
if (!str || !prefix)
|
||||
return false;
|
||||
if (p1 == p2)
|
||||
return true;
|
||||
|
||||
while ((result = tolower (*p1++) - tolower (*p2)) == 0)
|
||||
if (*p2++ == '\0')
|
||||
break;
|
||||
|
||||
return (result == 0 || *p2 == '\0');
|
||||
}
|
||||
|
||||
char *string_to_upper(char *s);
|
||||
|
||||
char *string_to_lower(char *s);
|
||||
|
||||
char *string_ucwords(char *s);
|
||||
|
||||
char *string_replace_substring(const char *in, const char *pattern,
|
||||
const char *by);
|
||||
|
||||
/* Remove leading whitespaces */
|
||||
char *string_trim_whitespace_left(char *const s);
|
||||
|
||||
/* Remove trailing whitespaces */
|
||||
char *string_trim_whitespace_right(char *const s);
|
||||
|
||||
/* Remove leading and trailing whitespaces */
|
||||
char *string_trim_whitespace(char *const s);
|
||||
|
||||
/*
|
||||
* Wraps string specified by 'src' to destination buffer
|
||||
* specified by 'dst' and 'dst_size'.
|
||||
* This function assumes that all glyphs in the string
|
||||
* have an on-screen pixel width similar to that of
|
||||
* regular Latin characters - i.e. it will not wrap
|
||||
* correctly any text containing so-called 'wide' Unicode
|
||||
* characters (e.g. CJK languages, emojis, etc.).
|
||||
*
|
||||
* @param dst pointer to destination buffer.
|
||||
* @param dst_size size of destination buffer.
|
||||
* @param src pointer to input string.
|
||||
* @param line_width max number of characters per line.
|
||||
* @param wideglyph_width not used, but is necessary to keep
|
||||
* compatibility with word_wrap_wideglyph().
|
||||
* @param max_lines max lines of destination string.
|
||||
* 0 means no limit.
|
||||
*/
|
||||
void word_wrap(char *dst, size_t dst_size, const char *src,
|
||||
int line_width, int wideglyph_width, unsigned max_lines);
|
||||
|
||||
/*
|
||||
* Wraps string specified by 'src' to destination buffer
|
||||
* specified by 'dst' and 'dst_size'.
|
||||
* This function assumes that all glyphs in the string
|
||||
* are:
|
||||
* - EITHER 'non-wide' Unicode glyphs, with an on-screen
|
||||
* pixel width similar to that of regular Latin characters
|
||||
* - OR 'wide' Unicode glyphs (e.g. CJK languages, emojis, etc.)
|
||||
* with an on-screen pixel width defined by 'wideglyph_width'
|
||||
* Note that wrapping may occur in inappropriate locations
|
||||
* if 'src' string contains 'wide' Unicode characters whose
|
||||
* on-screen pixel width deviates greatly from the set
|
||||
* 'wideglyph_width' value.
|
||||
*
|
||||
* @param dst pointer to destination buffer.
|
||||
* @param dst_size size of destination buffer.
|
||||
* @param src pointer to input string.
|
||||
* @param line_width max number of characters per line.
|
||||
* @param wideglyph_width effective width of 'wide' Unicode glyphs.
|
||||
* the value here is normalised relative to the
|
||||
* typical on-screen pixel width of a regular
|
||||
* Latin character:
|
||||
* - a regular Latin character is defined to
|
||||
* have an effective width of 100
|
||||
* - wideglyph_width = 100 * (wide_character_pixel_width / latin_character_pixel_width)
|
||||
* - e.g. if 'wide' Unicode characters in 'src'
|
||||
* have an on-screen pixel width twice that of
|
||||
* regular Latin characters, wideglyph_width
|
||||
* would be 200
|
||||
* @param max_lines max lines of destination string.
|
||||
* 0 means no limit.
|
||||
*/
|
||||
void word_wrap_wideglyph(char *dst, size_t dst_size, const char *src,
|
||||
int line_width, int wideglyph_width, unsigned max_lines);
|
||||
|
||||
/* Splits string into tokens seperated by 'delim'
|
||||
* > Returned token string must be free()'d
|
||||
* > Returns NULL if token is not found
|
||||
* > After each call, 'str' is set to the position after the
|
||||
* last found token
|
||||
* > Tokens *include* empty strings
|
||||
* Usage example:
|
||||
* char *str = "1,2,3,4,5,6,7,,,10,";
|
||||
* char **str_ptr = &str;
|
||||
* char *token = NULL;
|
||||
* while ((token = string_tokenize(str_ptr, ",")))
|
||||
* {
|
||||
* printf("%s\n", token);
|
||||
* free(token);
|
||||
* token = NULL;
|
||||
* }
|
||||
*/
|
||||
char* string_tokenize(char **str, const char *delim);
|
||||
|
||||
/* Removes every instance of character 'c' from 'str' */
|
||||
void string_remove_all_chars(char *str, char c);
|
||||
|
||||
/* Replaces every instance of character 'find' in 'str'
|
||||
* with character 'replace' */
|
||||
void string_replace_all_chars(char *str, char find, char replace);
|
||||
|
||||
/* Converts string to unsigned integer.
|
||||
* Returns 0 if string is invalid */
|
||||
unsigned string_to_unsigned(const char *str);
|
||||
|
||||
/* Converts hexadecimal string to unsigned integer.
|
||||
* Handles optional leading '0x'.
|
||||
* Returns 0 if string is invalid */
|
||||
unsigned string_hex_to_unsigned(const char *str);
|
||||
|
||||
char *string_init(const char *src);
|
||||
|
||||
void string_set(char **string, const char *src);
|
||||
|
||||
extern const unsigned char lr_char_props[256];
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
|
@ -1,48 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (rtime.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __LIBRETRO_SDK_RTIME_H__
|
||||
#define __LIBRETRO_SDK_RTIME_H__
|
||||
|
||||
#include <retro_common_api.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <time.h>
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
/* TODO/FIXME: Move all generic time handling functions
|
||||
* to this file */
|
||||
|
||||
/* Must be called before using rtime_localtime() */
|
||||
void rtime_init(void);
|
||||
|
||||
/* Must be called upon program termination */
|
||||
void rtime_deinit(void);
|
||||
|
||||
/* Thread-safe wrapper for localtime() */
|
||||
struct tm *rtime_localtime(const time_t *timep, struct tm *result);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
|
@ -1,111 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (vfs_implementation.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __LIBRETRO_SDK_VFS_H
|
||||
#define __LIBRETRO_SDK_VFS_H
|
||||
|
||||
#include <retro_common_api.h>
|
||||
#include <boolean.h>
|
||||
|
||||
#ifdef RARCH_INTERNAL
|
||||
#ifndef VFS_FRONTEND
|
||||
#define VFS_FRONTEND
|
||||
#endif
|
||||
#endif
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
#ifdef _WIN32
|
||||
typedef void* HANDLE;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CDROM
|
||||
typedef struct
|
||||
{
|
||||
int64_t byte_pos;
|
||||
char *cue_buf;
|
||||
size_t cue_len;
|
||||
unsigned cur_lba;
|
||||
unsigned last_frame_lba;
|
||||
unsigned char cur_min;
|
||||
unsigned char cur_sec;
|
||||
unsigned char cur_frame;
|
||||
unsigned char cur_track;
|
||||
unsigned char last_frame[2352];
|
||||
char drive;
|
||||
bool last_frame_valid;
|
||||
} vfs_cdrom_t;
|
||||
#endif
|
||||
|
||||
enum vfs_scheme
|
||||
{
|
||||
VFS_SCHEME_NONE = 0,
|
||||
VFS_SCHEME_CDROM
|
||||
};
|
||||
|
||||
#if !(defined(__WINRT__) && defined(__cplusplus_winrt))
|
||||
#ifdef VFS_FRONTEND
|
||||
struct retro_vfs_file_handle
|
||||
#else
|
||||
struct libretro_vfs_implementation_file
|
||||
#endif
|
||||
{
|
||||
#ifdef HAVE_CDROM
|
||||
vfs_cdrom_t cdrom; /* int64_t alignment */
|
||||
#endif
|
||||
int64_t size;
|
||||
uint64_t mappos;
|
||||
uint64_t mapsize;
|
||||
FILE *fp;
|
||||
#ifdef _WIN32
|
||||
HANDLE fh;
|
||||
#endif
|
||||
char *buf;
|
||||
char* orig_path;
|
||||
uint8_t *mapped;
|
||||
int fd;
|
||||
unsigned hints;
|
||||
enum vfs_scheme scheme;
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Replace the following symbol with something appropriate
|
||||
* to signify the file is being compiled for a front end instead of a core.
|
||||
* This allows the same code to act as reference implementation
|
||||
* for VFS and as fallbacks for when the front end does not provide VFS functionality.
|
||||
*/
|
||||
|
||||
#ifdef VFS_FRONTEND
|
||||
typedef struct retro_vfs_file_handle libretro_vfs_implementation_file;
|
||||
#else
|
||||
typedef struct libretro_vfs_implementation_file libretro_vfs_implementation_file;
|
||||
#endif
|
||||
|
||||
#ifdef VFS_FRONTEND
|
||||
typedef struct retro_vfs_dir_handle libretro_vfs_implementation_dir;
|
||||
#else
|
||||
typedef struct libretro_vfs_implementation_dir libretro_vfs_implementation_dir;
|
||||
#endif
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
|
@ -1,82 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (vfs_implementation.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __LIBRETRO_SDK_VFS_IMPLEMENTATION_H
|
||||
#define __LIBRETRO_SDK_VFS_IMPLEMENTATION_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <libretro.h>
|
||||
#include <retro_environment.h>
|
||||
#include <vfs/vfs.h>
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
libretro_vfs_implementation_file *retro_vfs_file_open_impl(const char *path, unsigned mode, unsigned hints);
|
||||
|
||||
int retro_vfs_file_close_impl(libretro_vfs_implementation_file *stream);
|
||||
|
||||
int retro_vfs_file_error_impl(libretro_vfs_implementation_file *stream);
|
||||
|
||||
int64_t retro_vfs_file_size_impl(libretro_vfs_implementation_file *stream);
|
||||
|
||||
int64_t retro_vfs_file_truncate_impl(libretro_vfs_implementation_file *stream, int64_t length);
|
||||
|
||||
int64_t retro_vfs_file_tell_impl(libretro_vfs_implementation_file *stream);
|
||||
|
||||
int64_t retro_vfs_file_seek_impl(libretro_vfs_implementation_file *stream, int64_t offset, int seek_position);
|
||||
|
||||
int64_t retro_vfs_file_read_impl(libretro_vfs_implementation_file *stream, void *s, uint64_t len);
|
||||
|
||||
int64_t retro_vfs_file_write_impl(libretro_vfs_implementation_file *stream, const void *s, uint64_t len);
|
||||
|
||||
int retro_vfs_file_flush_impl(libretro_vfs_implementation_file *stream);
|
||||
|
||||
int retro_vfs_file_remove_impl(const char *path);
|
||||
|
||||
int retro_vfs_file_rename_impl(const char *old_path, const char *new_path);
|
||||
|
||||
const char *retro_vfs_file_get_path_impl(libretro_vfs_implementation_file *stream);
|
||||
|
||||
int retro_vfs_stat_impl(const char *path, int32_t *size);
|
||||
|
||||
int retro_vfs_mkdir_impl(const char *dir);
|
||||
|
||||
libretro_vfs_implementation_dir *retro_vfs_opendir_impl(const char *dir, bool include_hidden);
|
||||
|
||||
bool retro_vfs_readdir_impl(libretro_vfs_implementation_dir *dirstream);
|
||||
|
||||
const char *retro_vfs_dirent_get_name_impl(libretro_vfs_implementation_dir *dirstream);
|
||||
|
||||
bool retro_vfs_dirent_is_dir_impl(libretro_vfs_implementation_dir *dirstream);
|
||||
|
||||
int retro_vfs_closedir_impl(libretro_vfs_implementation_dir *dirstream);
|
||||
|
||||
#ifdef __WINRT__
|
||||
|
||||
void uwp_set_acl(const wchar_t* path, const wchar_t* AccessString);
|
||||
|
||||
#endif
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
|
@ -1,554 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (string_list.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <lists/string_list.h>
|
||||
#include <compat/strl.h>
|
||||
#include <compat/posix_string.h>
|
||||
#include <string/stdstring.h>
|
||||
|
||||
static bool string_list_deinitialize_internal(struct string_list *list)
|
||||
{
|
||||
if (!list)
|
||||
return false;
|
||||
|
||||
if (list->elems)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < list->size; i++)
|
||||
{
|
||||
if (list->elems[i].data)
|
||||
free(list->elems[i].data);
|
||||
if (list->elems[i].userdata)
|
||||
free(list->elems[i].userdata);
|
||||
list->elems[i].data = NULL;
|
||||
list->elems[i].userdata = NULL;
|
||||
}
|
||||
|
||||
free(list->elems);
|
||||
}
|
||||
|
||||
list->elems = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* string_list_capacity:
|
||||
* @list : pointer to string list
|
||||
* @cap : new capacity for string list.
|
||||
*
|
||||
* Change maximum capacity of string list's size.
|
||||
*
|
||||
* Returns: true (1) if successful, otherwise false (0).
|
||||
**/
|
||||
static bool string_list_capacity(struct string_list *list, size_t cap)
|
||||
{
|
||||
struct string_list_elem *new_data = (struct string_list_elem*)
|
||||
realloc(list->elems, cap * sizeof(*new_data));
|
||||
|
||||
if (!new_data)
|
||||
return false;
|
||||
|
||||
if (cap > list->cap)
|
||||
memset(&new_data[list->cap], 0, sizeof(*new_data) * (cap - list->cap));
|
||||
|
||||
list->elems = new_data;
|
||||
list->cap = cap;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* string_list_free
|
||||
* @list : pointer to string list object
|
||||
*
|
||||
* Frees a string list.
|
||||
*/
|
||||
void string_list_free(struct string_list *list)
|
||||
{
|
||||
if (!list)
|
||||
return;
|
||||
|
||||
string_list_deinitialize_internal(list);
|
||||
|
||||
free(list);
|
||||
}
|
||||
|
||||
bool string_list_deinitialize(struct string_list *list)
|
||||
{
|
||||
if (!list)
|
||||
return false;
|
||||
if (!string_list_deinitialize_internal(list))
|
||||
return false;
|
||||
list->elems = NULL;
|
||||
list->size = 0;
|
||||
list->cap = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* string_list_new:
|
||||
*
|
||||
* Creates a new string list. Has to be freed manually.
|
||||
*
|
||||
* Returns: new string list if successful, otherwise NULL.
|
||||
*/
|
||||
struct string_list *string_list_new(void)
|
||||
{
|
||||
struct string_list_elem *
|
||||
elems = NULL;
|
||||
struct string_list *list = (struct string_list*)
|
||||
malloc(sizeof(*list));
|
||||
if (!list)
|
||||
return NULL;
|
||||
|
||||
if (!(elems = (struct string_list_elem*)
|
||||
calloc(32, sizeof(*elems))))
|
||||
{
|
||||
string_list_free(list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list->elems = elems;
|
||||
list->size = 0;
|
||||
list->cap = 32;
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
bool string_list_initialize(struct string_list *list)
|
||||
{
|
||||
struct string_list_elem *
|
||||
elems = NULL;
|
||||
if (!list)
|
||||
return false;
|
||||
if (!(elems = (struct string_list_elem*)
|
||||
calloc(32, sizeof(*elems))))
|
||||
{
|
||||
string_list_deinitialize(list);
|
||||
return false;
|
||||
}
|
||||
list->elems = elems;
|
||||
list->size = 0;
|
||||
list->cap = 32;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* string_list_append:
|
||||
* @list : pointer to string list
|
||||
* @elem : element to add to the string list
|
||||
* @attr : attributes of new element.
|
||||
*
|
||||
* Appends a new element to the string list.
|
||||
*
|
||||
* Returns: true (1) if successful, otherwise false (0).
|
||||
**/
|
||||
bool string_list_append(struct string_list *list, const char *elem,
|
||||
union string_list_elem_attr attr)
|
||||
{
|
||||
char *data_dup = NULL;
|
||||
|
||||
/* Note: If 'list' is incorrectly initialised
|
||||
* (i.e. if struct is zero initialised and
|
||||
* string_list_initialize() is not called on
|
||||
* it) capacity will be zero. This will cause
|
||||
* a segfault. Handle this case by forcing the new
|
||||
* capacity to a fixed size of 32 */
|
||||
if (list->size >= list->cap &&
|
||||
!string_list_capacity(list,
|
||||
(list->cap > 0) ? (list->cap * 2) : 32))
|
||||
return false;
|
||||
|
||||
data_dup = strdup(elem);
|
||||
if (!data_dup)
|
||||
return false;
|
||||
|
||||
list->elems[list->size].data = data_dup;
|
||||
list->elems[list->size].attr = attr;
|
||||
|
||||
list->size++;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* string_list_append_n:
|
||||
* @list : pointer to string list
|
||||
* @elem : element to add to the string list
|
||||
* @length : read at most this many bytes from elem
|
||||
* @attr : attributes of new element.
|
||||
*
|
||||
* Appends a new element to the string list.
|
||||
*
|
||||
* Returns: true (1) if successful, otherwise false (0).
|
||||
**/
|
||||
bool string_list_append_n(struct string_list *list, const char *elem,
|
||||
unsigned length, union string_list_elem_attr attr)
|
||||
{
|
||||
char *data_dup = NULL;
|
||||
|
||||
if (list->size >= list->cap &&
|
||||
!string_list_capacity(list, list->cap * 2))
|
||||
return false;
|
||||
|
||||
data_dup = (char*)malloc(length + 1);
|
||||
|
||||
if (!data_dup)
|
||||
return false;
|
||||
|
||||
strlcpy(data_dup, elem, length + 1);
|
||||
|
||||
list->elems[list->size].data = data_dup;
|
||||
list->elems[list->size].attr = attr;
|
||||
|
||||
list->size++;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* string_list_set:
|
||||
* @list : pointer to string list
|
||||
* @idx : index of element in string list
|
||||
* @str : value for the element.
|
||||
*
|
||||
* Set value of element inside string list.
|
||||
**/
|
||||
void string_list_set(struct string_list *list,
|
||||
unsigned idx, const char *str)
|
||||
{
|
||||
free(list->elems[idx].data);
|
||||
list->elems[idx].data = strdup(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* string_list_join_concat:
|
||||
* @buffer : buffer that @list will be joined to.
|
||||
* @size : length of @buffer.
|
||||
* @list : pointer to string list.
|
||||
* @delim : delimiter character for @list.
|
||||
*
|
||||
* A string list will be joined/concatenated as a
|
||||
* string to @buffer, delimited by @delim.
|
||||
*/
|
||||
void string_list_join_concat(char *buffer, size_t size,
|
||||
const struct string_list *list, const char *delim)
|
||||
{
|
||||
size_t i;
|
||||
size_t len = strlen_size(buffer, size);
|
||||
|
||||
/* If buffer is already 'full', nothing
|
||||
* further can be added
|
||||
* > This condition will also be triggered
|
||||
* if buffer is not NUL-terminated,
|
||||
* in which case any attempt to increment
|
||||
* buffer or decrement size would lead to
|
||||
* undefined behaviour */
|
||||
if (len >= size)
|
||||
return;
|
||||
|
||||
buffer += len;
|
||||
size -= len;
|
||||
|
||||
for (i = 0; i < list->size; i++)
|
||||
{
|
||||
strlcat(buffer, list->elems[i].data, size);
|
||||
if ((i + 1) < list->size)
|
||||
strlcat(buffer, delim, size);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* string_split:
|
||||
* @str : string to turn into a string list
|
||||
* @delim : delimiter character to use for splitting the string.
|
||||
*
|
||||
* Creates a new string list based on string @str, delimited by @delim.
|
||||
*
|
||||
* Returns: new string list if successful, otherwise NULL.
|
||||
*/
|
||||
struct string_list *string_split(const char *str, const char *delim)
|
||||
{
|
||||
char *save = NULL;
|
||||
char *copy = NULL;
|
||||
const char *tmp = NULL;
|
||||
struct string_list *list = string_list_new();
|
||||
|
||||
if (!list)
|
||||
return NULL;
|
||||
|
||||
copy = strdup(str);
|
||||
if (!copy)
|
||||
goto error;
|
||||
|
||||
tmp = strtok_r(copy, delim, &save);
|
||||
while (tmp)
|
||||
{
|
||||
union string_list_elem_attr attr;
|
||||
|
||||
attr.i = 0;
|
||||
|
||||
if (!string_list_append(list, tmp, attr))
|
||||
goto error;
|
||||
|
||||
tmp = strtok_r(NULL, delim, &save);
|
||||
}
|
||||
|
||||
free(copy);
|
||||
return list;
|
||||
|
||||
error:
|
||||
string_list_free(list);
|
||||
free(copy);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool string_split_noalloc(struct string_list *list,
|
||||
const char *str, const char *delim)
|
||||
{
|
||||
char *save = NULL;
|
||||
char *copy = NULL;
|
||||
const char *tmp = NULL;
|
||||
|
||||
if (!list)
|
||||
return false;
|
||||
|
||||
copy = strdup(str);
|
||||
if (!copy)
|
||||
return false;
|
||||
|
||||
tmp = strtok_r(copy, delim, &save);
|
||||
while (tmp)
|
||||
{
|
||||
union string_list_elem_attr attr;
|
||||
|
||||
attr.i = 0;
|
||||
|
||||
if (!string_list_append(list, tmp, attr))
|
||||
{
|
||||
free(copy);
|
||||
return false;
|
||||
}
|
||||
|
||||
tmp = strtok_r(NULL, delim, &save);
|
||||
}
|
||||
|
||||
free(copy);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* string_separate:
|
||||
* @str : string to turn into a string list
|
||||
* @delim : delimiter character to use for separating the string.
|
||||
*
|
||||
* Creates a new string list based on string @str, delimited by @delim.
|
||||
* Includes empty strings - i.e. two adjacent delimiters will resolve
|
||||
* to a string list element of "".
|
||||
*
|
||||
* Returns: new string list if successful, otherwise NULL.
|
||||
*/
|
||||
struct string_list *string_separate(char *str, const char *delim)
|
||||
{
|
||||
char *token = NULL;
|
||||
char **str_ptr = NULL;
|
||||
struct string_list *list = NULL;
|
||||
|
||||
/* Sanity check */
|
||||
if (!str || string_is_empty(delim))
|
||||
goto error;
|
||||
|
||||
str_ptr = &str;
|
||||
list = string_list_new();
|
||||
|
||||
if (!list)
|
||||
goto error;
|
||||
|
||||
token = string_tokenize(str_ptr, delim);
|
||||
while (token)
|
||||
{
|
||||
union string_list_elem_attr attr;
|
||||
|
||||
attr.i = 0;
|
||||
|
||||
if (!string_list_append(list, token, attr))
|
||||
goto error;
|
||||
|
||||
free(token);
|
||||
token = NULL;
|
||||
|
||||
token = string_tokenize(str_ptr, delim);
|
||||
}
|
||||
|
||||
return list;
|
||||
|
||||
error:
|
||||
if (token)
|
||||
free(token);
|
||||
if (list)
|
||||
string_list_free(list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool string_separate_noalloc(
|
||||
struct string_list *list,
|
||||
char *str, const char *delim)
|
||||
{
|
||||
char *token = NULL;
|
||||
char **str_ptr = NULL;
|
||||
|
||||
/* Sanity check */
|
||||
if (!str || string_is_empty(delim) || !list)
|
||||
return false;
|
||||
|
||||
str_ptr = &str;
|
||||
token = string_tokenize(str_ptr, delim);
|
||||
|
||||
while (token)
|
||||
{
|
||||
union string_list_elem_attr attr;
|
||||
|
||||
attr.i = 0;
|
||||
|
||||
if (!string_list_append(list, token, attr))
|
||||
{
|
||||
free(token);
|
||||
return false;
|
||||
}
|
||||
|
||||
free(token);
|
||||
token = string_tokenize(str_ptr, delim);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* string_list_find_elem:
|
||||
* @list : pointer to string list
|
||||
* @elem : element to find inside the string list.
|
||||
*
|
||||
* Searches for an element (@elem) inside the string list.
|
||||
*
|
||||
* Returns: true (1) if element could be found, otherwise false (0).
|
||||
*/
|
||||
int string_list_find_elem(const struct string_list *list, const char *elem)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (!list)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < list->size; i++)
|
||||
{
|
||||
if (string_is_equal_noncase(list->elems[i].data, elem))
|
||||
return (int)(i + 1);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* string_list_find_elem_prefix:
|
||||
* @list : pointer to string list
|
||||
* @prefix : prefix to append to @elem
|
||||
* @elem : element to find inside the string list.
|
||||
*
|
||||
* Searches for an element (@elem) inside the string list. Will
|
||||
* also search for the same element prefixed by @prefix.
|
||||
*
|
||||
* Returns: true (1) if element could be found, otherwise false (0).
|
||||
*/
|
||||
bool string_list_find_elem_prefix(const struct string_list *list,
|
||||
const char *prefix, const char *elem)
|
||||
{
|
||||
size_t i;
|
||||
char prefixed[255];
|
||||
|
||||
if (!list)
|
||||
return false;
|
||||
|
||||
prefixed[0] = '\0';
|
||||
|
||||
strlcpy(prefixed, prefix, sizeof(prefixed));
|
||||
strlcat(prefixed, elem, sizeof(prefixed));
|
||||
|
||||
for (i = 0; i < list->size; i++)
|
||||
{
|
||||
if (string_is_equal_noncase(list->elems[i].data, elem) ||
|
||||
string_is_equal_noncase(list->elems[i].data, prefixed))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
struct string_list *string_list_clone(
|
||||
const struct string_list *src)
|
||||
{
|
||||
unsigned i;
|
||||
struct string_list_elem
|
||||
*elems = NULL;
|
||||
struct string_list
|
||||
*dest = (struct string_list*)
|
||||
malloc(sizeof(struct string_list));
|
||||
|
||||
if (!dest)
|
||||
return NULL;
|
||||
|
||||
dest->elems = NULL;
|
||||
dest->size = src->size;
|
||||
dest->cap = src->cap;
|
||||
if (dest->cap < dest->size)
|
||||
dest->cap = dest->size;
|
||||
|
||||
elems = (struct string_list_elem*)
|
||||
calloc(dest->cap, sizeof(struct string_list_elem));
|
||||
|
||||
if (!elems)
|
||||
{
|
||||
free(dest);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dest->elems = elems;
|
||||
|
||||
for (i = 0; i < src->size; i++)
|
||||
{
|
||||
const char *_src = src->elems[i].data;
|
||||
size_t len = _src ? strlen(_src) : 0;
|
||||
|
||||
dest->elems[i].data = NULL;
|
||||
dest->elems[i].attr = src->elems[i].attr;
|
||||
|
||||
if (len != 0)
|
||||
{
|
||||
char *result = (char*)malloc(len + 1);
|
||||
strcpy(result, _src);
|
||||
dest->elems[i].data = result;
|
||||
}
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (memalign.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <memalign.h>
|
||||
|
||||
void *memalign_alloc(size_t boundary, size_t size)
|
||||
{
|
||||
void **place = NULL;
|
||||
uintptr_t addr = 0;
|
||||
void *ptr = (void*)malloc(boundary + size + sizeof(uintptr_t));
|
||||
if (!ptr)
|
||||
return NULL;
|
||||
|
||||
addr = ((uintptr_t)ptr + sizeof(uintptr_t) + boundary)
|
||||
& ~(boundary - 1);
|
||||
place = (void**)addr;
|
||||
place[-1] = ptr;
|
||||
|
||||
return (void*)addr;
|
||||
}
|
||||
|
||||
void *memalign_calloc(size_t boundary, size_t unit, size_t size)
|
||||
{
|
||||
size *= unit;
|
||||
|
||||
void **place = NULL;
|
||||
uintptr_t addr = 0;
|
||||
void *ptr = (void*)calloc(1, boundary + size + sizeof(uintptr_t));
|
||||
if (!ptr)
|
||||
return NULL;
|
||||
|
||||
addr = ((uintptr_t)ptr + sizeof(uintptr_t) + boundary)
|
||||
& ~(boundary - 1);
|
||||
place = (void**)addr;
|
||||
place[-1] = ptr;
|
||||
|
||||
return (void*)addr;
|
||||
}
|
||||
void memalign_free(void *ptr)
|
||||
{
|
||||
void **p = NULL;
|
||||
if (!ptr)
|
||||
return;
|
||||
|
||||
p = (void**)ptr;
|
||||
free(p[-1]);
|
||||
}
|
||||
|
||||
void *memalign_alloc_aligned(size_t size)
|
||||
{
|
||||
#if defined(__x86_64__) || defined(__LP64) || defined(__IA64__) || defined(_M_X64) || defined(_M_X64) || defined(_WIN64)
|
||||
return memalign_alloc(64, size);
|
||||
#elif defined(__i386__) || defined(__i486__) || defined(__i686__) || defined(GEKKO) || defined(_M_IX86)
|
||||
return memalign_alloc(32, size);
|
||||
#else
|
||||
return memalign_alloc(32, size);
|
||||
#endif
|
||||
}
|
|
@ -1,682 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (file_stream.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <compat/msvc.h>
|
||||
#endif
|
||||
|
||||
#include <string/stdstring.h>
|
||||
#include <streams/file_stream.h>
|
||||
#define VFS_FRONTEND
|
||||
#include <vfs/vfs_implementation.h>
|
||||
|
||||
#define VFS_ERROR_RETURN_VALUE -1
|
||||
|
||||
struct RFILE
|
||||
{
|
||||
struct retro_vfs_file_handle *hfile;
|
||||
bool error_flag;
|
||||
bool eof_flag;
|
||||
};
|
||||
|
||||
static retro_vfs_get_path_t filestream_get_path_cb = NULL;
|
||||
static retro_vfs_open_t filestream_open_cb = NULL;
|
||||
static retro_vfs_close_t filestream_close_cb = NULL;
|
||||
static retro_vfs_size_t filestream_size_cb = NULL;
|
||||
static retro_vfs_truncate_t filestream_truncate_cb = NULL;
|
||||
static retro_vfs_tell_t filestream_tell_cb = NULL;
|
||||
static retro_vfs_seek_t filestream_seek_cb = NULL;
|
||||
static retro_vfs_read_t filestream_read_cb = NULL;
|
||||
static retro_vfs_write_t filestream_write_cb = NULL;
|
||||
static retro_vfs_flush_t filestream_flush_cb = NULL;
|
||||
static retro_vfs_remove_t filestream_remove_cb = NULL;
|
||||
static retro_vfs_rename_t filestream_rename_cb = NULL;
|
||||
|
||||
/* VFS Initialization */
|
||||
|
||||
void filestream_vfs_init(const struct retro_vfs_interface_info* vfs_info)
|
||||
{
|
||||
const struct retro_vfs_interface *
|
||||
vfs_iface = vfs_info->iface;
|
||||
|
||||
filestream_get_path_cb = NULL;
|
||||
filestream_open_cb = NULL;
|
||||
filestream_close_cb = NULL;
|
||||
filestream_tell_cb = NULL;
|
||||
filestream_size_cb = NULL;
|
||||
filestream_truncate_cb = NULL;
|
||||
filestream_seek_cb = NULL;
|
||||
filestream_read_cb = NULL;
|
||||
filestream_write_cb = NULL;
|
||||
filestream_flush_cb = NULL;
|
||||
filestream_remove_cb = NULL;
|
||||
filestream_rename_cb = NULL;
|
||||
|
||||
if (
|
||||
(vfs_info->required_interface_version <
|
||||
FILESTREAM_REQUIRED_VFS_VERSION)
|
||||
|| !vfs_iface)
|
||||
return;
|
||||
|
||||
filestream_get_path_cb = vfs_iface->get_path;
|
||||
filestream_open_cb = vfs_iface->open;
|
||||
filestream_close_cb = vfs_iface->close;
|
||||
filestream_size_cb = vfs_iface->size;
|
||||
filestream_truncate_cb = vfs_iface->truncate;
|
||||
filestream_tell_cb = vfs_iface->tell;
|
||||
filestream_seek_cb = vfs_iface->seek;
|
||||
filestream_read_cb = vfs_iface->read;
|
||||
filestream_write_cb = vfs_iface->write;
|
||||
filestream_flush_cb = vfs_iface->flush;
|
||||
filestream_remove_cb = vfs_iface->remove;
|
||||
filestream_rename_cb = vfs_iface->rename;
|
||||
}
|
||||
|
||||
/* Callback wrappers */
|
||||
bool filestream_exists(const char *path)
|
||||
{
|
||||
RFILE *dummy = NULL;
|
||||
|
||||
if (!path || !*path)
|
||||
return false;
|
||||
|
||||
dummy = filestream_open(
|
||||
path,
|
||||
RETRO_VFS_FILE_ACCESS_READ,
|
||||
RETRO_VFS_FILE_ACCESS_HINT_NONE);
|
||||
|
||||
if (!dummy)
|
||||
return false;
|
||||
|
||||
if (filestream_close(dummy) != 0)
|
||||
if (dummy)
|
||||
free(dummy);
|
||||
|
||||
dummy = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
int64_t filestream_get_size(RFILE *stream)
|
||||
{
|
||||
int64_t output;
|
||||
|
||||
if (filestream_size_cb)
|
||||
output = filestream_size_cb(stream->hfile);
|
||||
else
|
||||
output = retro_vfs_file_size_impl(
|
||||
(libretro_vfs_implementation_file*)stream->hfile);
|
||||
|
||||
if (output == VFS_ERROR_RETURN_VALUE)
|
||||
stream->error_flag = true;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
int64_t filestream_truncate(RFILE *stream, int64_t length)
|
||||
{
|
||||
int64_t output;
|
||||
|
||||
if (filestream_truncate_cb)
|
||||
output = filestream_truncate_cb(stream->hfile, length);
|
||||
else
|
||||
output = retro_vfs_file_truncate_impl(
|
||||
(libretro_vfs_implementation_file*)stream->hfile, length);
|
||||
|
||||
if (output == VFS_ERROR_RETURN_VALUE)
|
||||
stream->error_flag = true;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* filestream_open:
|
||||
* @path : path to file
|
||||
* @mode : file mode to use when opening (read/write)
|
||||
* @hints :
|
||||
*
|
||||
* Opens a file for reading or writing, depending on the requested mode.
|
||||
* Returns a pointer to an RFILE if opened successfully, otherwise NULL.
|
||||
**/
|
||||
RFILE* filestream_open(const char *path, unsigned mode, unsigned hints)
|
||||
{
|
||||
struct retro_vfs_file_handle *fp = NULL;
|
||||
RFILE* output = NULL;
|
||||
|
||||
if (filestream_open_cb)
|
||||
fp = (struct retro_vfs_file_handle*)
|
||||
filestream_open_cb(path, mode, hints);
|
||||
else
|
||||
fp = (struct retro_vfs_file_handle*)
|
||||
retro_vfs_file_open_impl(path, mode, hints);
|
||||
|
||||
if (!fp)
|
||||
return NULL;
|
||||
|
||||
output = (RFILE*)malloc(sizeof(RFILE));
|
||||
output->error_flag = false;
|
||||
output->eof_flag = false;
|
||||
output->hfile = fp;
|
||||
return output;
|
||||
}
|
||||
|
||||
char* filestream_gets(RFILE *stream, char *s, size_t len)
|
||||
{
|
||||
int c = 0;
|
||||
char *p = s;
|
||||
if (!stream)
|
||||
return NULL;
|
||||
|
||||
/* get max bytes or up to a newline */
|
||||
|
||||
for (len--; len > 0; len--)
|
||||
{
|
||||
if ((c = filestream_getc(stream)) == EOF)
|
||||
break;
|
||||
*p++ = c;
|
||||
if (c == '\n')
|
||||
break;
|
||||
}
|
||||
*p = 0;
|
||||
|
||||
if (p == s && c == EOF)
|
||||
return NULL;
|
||||
return (s);
|
||||
}
|
||||
|
||||
int filestream_getc(RFILE *stream)
|
||||
{
|
||||
char c = 0;
|
||||
if (stream && filestream_read(stream, &c, 1) == 1)
|
||||
return (int)(unsigned char)c;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
int filestream_vscanf(RFILE *stream, const char* format, va_list *args)
|
||||
{
|
||||
char buf[4096];
|
||||
char subfmt[64];
|
||||
va_list args_copy;
|
||||
const char * bufiter = buf;
|
||||
int ret = 0;
|
||||
int64_t startpos = filestream_tell(stream);
|
||||
int64_t maxlen = filestream_read(stream, buf, sizeof(buf)-1);
|
||||
|
||||
if (maxlen <= 0)
|
||||
return EOF;
|
||||
|
||||
buf[maxlen] = '\0';
|
||||
|
||||
/* Have to copy the input va_list here
|
||||
* > Calling va_arg() on 'args' directly would
|
||||
* cause the va_list to have an indeterminate value
|
||||
* in the function calling filestream_vscanf(),
|
||||
* leading to unexpected behaviour */
|
||||
#ifdef __va_copy
|
||||
__va_copy(args_copy, *args);
|
||||
#else
|
||||
va_copy(args_copy, *args);
|
||||
#endif
|
||||
|
||||
while (*format)
|
||||
{
|
||||
if (*format == '%')
|
||||
{
|
||||
int sublen;
|
||||
char* subfmtiter = subfmt;
|
||||
bool asterisk = false;
|
||||
|
||||
*subfmtiter++ = *format++; /* '%' */
|
||||
|
||||
/* %[*][width][length]specifier */
|
||||
|
||||
if (*format == '*')
|
||||
{
|
||||
asterisk = true;
|
||||
*subfmtiter++ = *format++;
|
||||
}
|
||||
|
||||
while (ISDIGIT((unsigned char)*format))
|
||||
*subfmtiter++ = *format++; /* width */
|
||||
|
||||
/* length */
|
||||
if (*format == 'h' || *format == 'l')
|
||||
{
|
||||
if (format[1] == format[0])
|
||||
*subfmtiter++ = *format++;
|
||||
*subfmtiter++ = *format++;
|
||||
}
|
||||
else if (
|
||||
*format == 'j' ||
|
||||
*format == 'z' ||
|
||||
*format == 't' ||
|
||||
*format == 'L')
|
||||
{
|
||||
*subfmtiter++ = *format++;
|
||||
}
|
||||
|
||||
/* specifier - always a single character (except ]) */
|
||||
if (*format == '[')
|
||||
{
|
||||
while (*format != ']')
|
||||
*subfmtiter++ = *format++;
|
||||
*subfmtiter++ = *format++;
|
||||
}
|
||||
else
|
||||
*subfmtiter++ = *format++;
|
||||
|
||||
*subfmtiter++ = '%';
|
||||
*subfmtiter++ = 'n';
|
||||
*subfmtiter++ = '\0';
|
||||
|
||||
if (sizeof(void*) != sizeof(long*))
|
||||
abort(); /* all pointers must have the same size */
|
||||
|
||||
if (asterisk)
|
||||
{
|
||||
int v = sscanf(bufiter, subfmt, &sublen);
|
||||
if (v == EOF)
|
||||
return EOF;
|
||||
if (v != 0)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
int v = sscanf(bufiter, subfmt, va_arg(args_copy, void*), &sublen);
|
||||
if (v == EOF)
|
||||
return EOF;
|
||||
if (v != 1)
|
||||
break;
|
||||
}
|
||||
|
||||
ret++;
|
||||
bufiter += sublen;
|
||||
}
|
||||
else if (isspace((unsigned char)*format))
|
||||
{
|
||||
while (isspace((unsigned char)*bufiter))
|
||||
bufiter++;
|
||||
format++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*bufiter != *format)
|
||||
break;
|
||||
bufiter++;
|
||||
format++;
|
||||
}
|
||||
}
|
||||
|
||||
va_end(args_copy);
|
||||
filestream_seek(stream, startpos+(bufiter-buf),
|
||||
RETRO_VFS_SEEK_POSITION_START);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int filestream_scanf(RFILE *stream, const char* format, ...)
|
||||
{
|
||||
int result;
|
||||
va_list vl;
|
||||
va_start(vl, format);
|
||||
result = filestream_vscanf(stream, format, &vl);
|
||||
va_end(vl);
|
||||
return result;
|
||||
}
|
||||
|
||||
int64_t filestream_seek(RFILE *stream, int64_t offset, int seek_position)
|
||||
{
|
||||
int64_t output;
|
||||
|
||||
if (filestream_seek_cb)
|
||||
output = filestream_seek_cb(stream->hfile, offset, seek_position);
|
||||
else
|
||||
output = retro_vfs_file_seek_impl(
|
||||
(libretro_vfs_implementation_file*)stream->hfile,
|
||||
offset, seek_position);
|
||||
|
||||
if (output == VFS_ERROR_RETURN_VALUE)
|
||||
stream->error_flag = true;
|
||||
|
||||
stream->eof_flag = false;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
int filestream_eof(RFILE *stream)
|
||||
{
|
||||
return stream->eof_flag;
|
||||
}
|
||||
|
||||
int64_t filestream_tell(RFILE *stream)
|
||||
{
|
||||
int64_t output;
|
||||
|
||||
if (filestream_size_cb)
|
||||
output = filestream_tell_cb(stream->hfile);
|
||||
else
|
||||
output = retro_vfs_file_tell_impl(
|
||||
(libretro_vfs_implementation_file*)stream->hfile);
|
||||
|
||||
if (output == VFS_ERROR_RETURN_VALUE)
|
||||
stream->error_flag = true;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
void filestream_rewind(RFILE *stream)
|
||||
{
|
||||
if (!stream)
|
||||
return;
|
||||
filestream_seek(stream, 0L, RETRO_VFS_SEEK_POSITION_START);
|
||||
stream->error_flag = false;
|
||||
stream->eof_flag = false;
|
||||
}
|
||||
|
||||
int64_t filestream_read(RFILE *stream, void *s, int64_t len)
|
||||
{
|
||||
int64_t output;
|
||||
|
||||
if (filestream_read_cb)
|
||||
output = filestream_read_cb(stream->hfile, s, len);
|
||||
else
|
||||
output = retro_vfs_file_read_impl(
|
||||
(libretro_vfs_implementation_file*)stream->hfile, s, len);
|
||||
|
||||
if (output == VFS_ERROR_RETURN_VALUE)
|
||||
stream->error_flag = true;
|
||||
if (output < len)
|
||||
stream->eof_flag = true;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
int filestream_flush(RFILE *stream)
|
||||
{
|
||||
int output;
|
||||
|
||||
if (filestream_flush_cb)
|
||||
output = filestream_flush_cb(stream->hfile);
|
||||
else
|
||||
output = retro_vfs_file_flush_impl(
|
||||
(libretro_vfs_implementation_file*)stream->hfile);
|
||||
|
||||
if (output == VFS_ERROR_RETURN_VALUE)
|
||||
stream->error_flag = true;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
int filestream_delete(const char *path)
|
||||
{
|
||||
if (filestream_remove_cb)
|
||||
return filestream_remove_cb(path);
|
||||
|
||||
return retro_vfs_file_remove_impl(path);
|
||||
}
|
||||
|
||||
int filestream_rename(const char *old_path, const char *new_path)
|
||||
{
|
||||
if (filestream_rename_cb)
|
||||
return filestream_rename_cb(old_path, new_path);
|
||||
|
||||
return retro_vfs_file_rename_impl(old_path, new_path);
|
||||
}
|
||||
|
||||
const char* filestream_get_path(RFILE *stream)
|
||||
{
|
||||
if (filestream_get_path_cb)
|
||||
return filestream_get_path_cb(stream->hfile);
|
||||
|
||||
return retro_vfs_file_get_path_impl(
|
||||
(libretro_vfs_implementation_file*)stream->hfile);
|
||||
}
|
||||
|
||||
int64_t filestream_write(RFILE *stream, const void *s, int64_t len)
|
||||
{
|
||||
int64_t output;
|
||||
|
||||
if (filestream_write_cb)
|
||||
output = filestream_write_cb(stream->hfile, s, len);
|
||||
else
|
||||
output = retro_vfs_file_write_impl(
|
||||
(libretro_vfs_implementation_file*)stream->hfile, s, len);
|
||||
|
||||
if (output == VFS_ERROR_RETURN_VALUE)
|
||||
stream->error_flag = true;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
int filestream_putc(RFILE *stream, int c)
|
||||
{
|
||||
char c_char = (char)c;
|
||||
if (!stream)
|
||||
return EOF;
|
||||
return filestream_write(stream, &c_char, 1) == 1
|
||||
? (int)(unsigned char)c
|
||||
: EOF;
|
||||
}
|
||||
|
||||
int filestream_vprintf(RFILE *stream, const char* format, va_list args)
|
||||
{
|
||||
static char buffer[8 * 1024];
|
||||
int64_t num_chars = vsnprintf(buffer, sizeof(buffer),
|
||||
format, args);
|
||||
|
||||
if (num_chars < 0)
|
||||
return -1;
|
||||
else if (num_chars == 0)
|
||||
return 0;
|
||||
|
||||
return (int)filestream_write(stream, buffer, num_chars);
|
||||
}
|
||||
|
||||
int filestream_printf(RFILE *stream, const char* format, ...)
|
||||
{
|
||||
va_list vl;
|
||||
int result;
|
||||
va_start(vl, format);
|
||||
result = filestream_vprintf(stream, format, vl);
|
||||
va_end(vl);
|
||||
return result;
|
||||
}
|
||||
|
||||
int filestream_error(RFILE *stream)
|
||||
{
|
||||
if (stream && stream->error_flag)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int filestream_close(RFILE *stream)
|
||||
{
|
||||
int output;
|
||||
struct retro_vfs_file_handle* fp = stream->hfile;
|
||||
|
||||
if (filestream_close_cb)
|
||||
output = filestream_close_cb(fp);
|
||||
else
|
||||
output = retro_vfs_file_close_impl(
|
||||
(libretro_vfs_implementation_file*)fp);
|
||||
|
||||
if (output == 0)
|
||||
free(stream);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* filestream_read_file:
|
||||
* @path : path to file.
|
||||
* @buf : buffer to allocate and read the contents of the
|
||||
* file into. Needs to be freed manually.
|
||||
* @len : optional output integer containing bytes read.
|
||||
*
|
||||
* Read the contents of a file into @buf.
|
||||
*
|
||||
* Returns: non zero on success.
|
||||
*/
|
||||
int64_t filestream_read_file(const char *path, void **buf, int64_t *len)
|
||||
{
|
||||
int64_t ret = 0;
|
||||
int64_t content_buf_size = 0;
|
||||
void *content_buf = NULL;
|
||||
RFILE *file = filestream_open(path,
|
||||
RETRO_VFS_FILE_ACCESS_READ,
|
||||
RETRO_VFS_FILE_ACCESS_HINT_NONE);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
*buf = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
content_buf_size = filestream_get_size(file);
|
||||
|
||||
if (content_buf_size < 0)
|
||||
goto error;
|
||||
|
||||
content_buf = malloc((size_t)(content_buf_size + 1));
|
||||
|
||||
if (!content_buf)
|
||||
goto error;
|
||||
if ((int64_t)(uint64_t)(content_buf_size + 1) != (content_buf_size + 1))
|
||||
goto error;
|
||||
|
||||
ret = filestream_read(file, content_buf, (int64_t)content_buf_size);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
|
||||
if (filestream_close(file) != 0)
|
||||
if (file)
|
||||
free(file);
|
||||
|
||||
*buf = content_buf;
|
||||
|
||||
/* Allow for easy reading of strings to be safe.
|
||||
* Will only work with sane character formatting (Unix). */
|
||||
((char*)content_buf)[ret] = '\0';
|
||||
|
||||
if (len)
|
||||
*len = ret;
|
||||
|
||||
return 1;
|
||||
|
||||
error:
|
||||
if (file)
|
||||
if (filestream_close(file) != 0)
|
||||
free(file);
|
||||
if (content_buf)
|
||||
free(content_buf);
|
||||
if (len)
|
||||
*len = -1;
|
||||
*buf = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* filestream_write_file:
|
||||
* @path : path to file.
|
||||
* @data : contents to write to the file.
|
||||
* @size : size of the contents.
|
||||
*
|
||||
* Writes data to a file.
|
||||
*
|
||||
* Returns: true (1) on success, false (0) otherwise.
|
||||
*/
|
||||
bool filestream_write_file(const char *path, const void *data, int64_t size)
|
||||
{
|
||||
int64_t ret = 0;
|
||||
RFILE *file = filestream_open(path,
|
||||
RETRO_VFS_FILE_ACCESS_WRITE,
|
||||
RETRO_VFS_FILE_ACCESS_HINT_NONE);
|
||||
if (!file)
|
||||
return false;
|
||||
|
||||
ret = filestream_write(file, data, size);
|
||||
if (filestream_close(file) != 0)
|
||||
if (file)
|
||||
free(file);
|
||||
|
||||
if (ret != size)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Returned pointer must be freed by the caller. */
|
||||
char* filestream_getline(RFILE *stream)
|
||||
{
|
||||
char *newline_tmp = NULL;
|
||||
size_t cur_size = 8;
|
||||
size_t idx = 0;
|
||||
int in = 0;
|
||||
char *newline = (char*)malloc(9);
|
||||
|
||||
if (!stream || !newline)
|
||||
{
|
||||
if (newline)
|
||||
free(newline);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
in = filestream_getc(stream);
|
||||
|
||||
while (in != EOF && in != '\n')
|
||||
{
|
||||
if (idx == cur_size)
|
||||
{
|
||||
cur_size *= 2;
|
||||
newline_tmp = (char*)realloc(newline, cur_size + 1);
|
||||
|
||||
if (!newline_tmp)
|
||||
{
|
||||
free(newline);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
newline = newline_tmp;
|
||||
}
|
||||
|
||||
newline[idx++] = in;
|
||||
in = filestream_getc(stream);
|
||||
}
|
||||
|
||||
newline[idx] = '\0';
|
||||
return newline;
|
||||
}
|
||||
|
||||
libretro_vfs_implementation_file* filestream_get_vfs_handle(RFILE *stream)
|
||||
{
|
||||
return (libretro_vfs_implementation_file*)stream->hfile;
|
||||
}
|
|
@ -1,536 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (stdstring.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <string/stdstring.h>
|
||||
#include <encodings/utf.h>
|
||||
|
||||
const uint8_t lr_char_props[256] = {
|
||||
/*x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x80,0x00,0x00, /* 0x */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 1x */
|
||||
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 2x !"#$%&'()*+,-./ */
|
||||
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x00,0x00,0x00,0x00,0x00,0x00, /* 3x 0123456789:;<=>? */
|
||||
0x00,0x23,0x23,0x23,0x23,0x23,0x23,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, /* 4x @ABCDEFGHIJKLMNO */
|
||||
0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x00,0x00,0x00,0x00,0x08, /* 5x PQRSTUVWXYZ[\]^_ */
|
||||
0x00,0x25,0x25,0x25,0x25,0x25,0x25,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24, /* 6x `abcdefghijklmno */
|
||||
0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x00,0x00,0x00,0x00,0x00, /* 7x pqrstuvwxyz{|}~ */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 8x */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 9x */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* Ax */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* Bx */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* Cx */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* Dx */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* Ex */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* Fx */
|
||||
};
|
||||
|
||||
char *string_init(const char *src)
|
||||
{
|
||||
return src ? strdup(src) : NULL;
|
||||
}
|
||||
|
||||
void string_set(char **string, const char *src)
|
||||
{
|
||||
free(*string);
|
||||
*string = string_init(src);
|
||||
}
|
||||
|
||||
|
||||
char *string_to_upper(char *s)
|
||||
{
|
||||
char *cs = (char *)s;
|
||||
for ( ; *cs != '\0'; cs++)
|
||||
*cs = toupper((unsigned char)*cs);
|
||||
return s;
|
||||
}
|
||||
|
||||
char *string_to_lower(char *s)
|
||||
{
|
||||
char *cs = (char *)s;
|
||||
for ( ; *cs != '\0'; cs++)
|
||||
*cs = tolower((unsigned char)*cs);
|
||||
return s;
|
||||
}
|
||||
|
||||
char *string_ucwords(char *s)
|
||||
{
|
||||
char *cs = (char *)s;
|
||||
for ( ; *cs != '\0'; cs++)
|
||||
{
|
||||
if (*cs == ' ')
|
||||
*(cs+1) = toupper((unsigned char)*(cs+1));
|
||||
}
|
||||
|
||||
s[0] = toupper((unsigned char)s[0]);
|
||||
return s;
|
||||
}
|
||||
|
||||
char *string_replace_substring(const char *in,
|
||||
const char *pattern, const char *replacement)
|
||||
{
|
||||
size_t numhits, pattern_len, replacement_len, outlen;
|
||||
const char *inat = NULL;
|
||||
const char *inprev = NULL;
|
||||
char *out = NULL;
|
||||
char *outat = NULL;
|
||||
|
||||
/* if either pattern or replacement is NULL,
|
||||
* duplicate in and let caller handle it. */
|
||||
if (!pattern || !replacement)
|
||||
return strdup(in);
|
||||
|
||||
pattern_len = strlen(pattern);
|
||||
replacement_len = strlen(replacement);
|
||||
numhits = 0;
|
||||
inat = in;
|
||||
|
||||
while ((inat = strstr(inat, pattern)))
|
||||
{
|
||||
inat += pattern_len;
|
||||
numhits++;
|
||||
}
|
||||
|
||||
outlen = strlen(in) - pattern_len*numhits + replacement_len*numhits;
|
||||
out = (char *)malloc(outlen+1);
|
||||
|
||||
if (!out)
|
||||
return NULL;
|
||||
|
||||
outat = out;
|
||||
inat = in;
|
||||
inprev = in;
|
||||
|
||||
while ((inat = strstr(inat, pattern)))
|
||||
{
|
||||
memcpy(outat, inprev, inat-inprev);
|
||||
outat += inat-inprev;
|
||||
memcpy(outat, replacement, replacement_len);
|
||||
outat += replacement_len;
|
||||
inat += pattern_len;
|
||||
inprev = inat;
|
||||
}
|
||||
strcpy(outat, inprev);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/* Remove leading whitespaces */
|
||||
char *string_trim_whitespace_left(char *const s)
|
||||
{
|
||||
if (s && *s)
|
||||
{
|
||||
size_t len = strlen(s);
|
||||
char *current = s;
|
||||
|
||||
while (*current && ISSPACE((unsigned char)*current))
|
||||
{
|
||||
++current;
|
||||
--len;
|
||||
}
|
||||
|
||||
if (s != current)
|
||||
memmove(s, current, len + 1);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Remove trailing whitespaces */
|
||||
char *string_trim_whitespace_right(char *const s)
|
||||
{
|
||||
if (s && *s)
|
||||
{
|
||||
size_t len = strlen(s);
|
||||
char *current = s + len - 1;
|
||||
|
||||
while (current != s && ISSPACE((unsigned char)*current))
|
||||
{
|
||||
--current;
|
||||
--len;
|
||||
}
|
||||
|
||||
current[ISSPACE((unsigned char)*current) ? 0 : 1] = '\0';
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Remove leading and trailing whitespaces */
|
||||
char *string_trim_whitespace(char *const s)
|
||||
{
|
||||
string_trim_whitespace_right(s); /* order matters */
|
||||
string_trim_whitespace_left(s);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void word_wrap(char *dst, size_t dst_size, const char *src, int line_width, int wideglyph_width, unsigned max_lines)
|
||||
{
|
||||
char *lastspace = NULL;
|
||||
unsigned counter = 0;
|
||||
unsigned lines = 1;
|
||||
size_t src_len = strlen(src);
|
||||
const char *src_end = src + src_len;
|
||||
|
||||
/* Prevent buffer overflow */
|
||||
if (dst_size < src_len + 1)
|
||||
return;
|
||||
|
||||
/* Early return if src string length is less
|
||||
* than line width */
|
||||
if (src_len < line_width)
|
||||
{
|
||||
strcpy(dst, src);
|
||||
return;
|
||||
}
|
||||
|
||||
while (*src != '\0')
|
||||
{
|
||||
unsigned char_len;
|
||||
|
||||
char_len = (unsigned)(utf8skip(src, 1) - src);
|
||||
counter++;
|
||||
|
||||
if (*src == ' ')
|
||||
lastspace = dst; /* Remember the location of the whitespace */
|
||||
else if (*src == '\n')
|
||||
{
|
||||
/* If newlines embedded in the input,
|
||||
* reset the index */
|
||||
lines++;
|
||||
counter = 0;
|
||||
|
||||
/* Early return if remaining src string
|
||||
* length is less than line width */
|
||||
if (src_end - src <= line_width)
|
||||
{
|
||||
strcpy(dst, src);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
while (char_len--)
|
||||
*dst++ = *src++;
|
||||
|
||||
if (counter >= (unsigned)line_width)
|
||||
{
|
||||
counter = 0;
|
||||
|
||||
if (lastspace && (max_lines == 0 || lines < max_lines))
|
||||
{
|
||||
/* Replace nearest (previous) whitespace
|
||||
* with newline character */
|
||||
*lastspace = '\n';
|
||||
lines++;
|
||||
|
||||
src -= dst - lastspace - 1;
|
||||
dst = lastspace + 1;
|
||||
lastspace = NULL;
|
||||
|
||||
/* Early return if remaining src string
|
||||
* length is less than line width */
|
||||
if (src_end - src < line_width)
|
||||
{
|
||||
strcpy(dst, src);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*dst = '\0';
|
||||
}
|
||||
|
||||
void word_wrap_wideglyph(char *dst, size_t dst_size, const char *src, int line_width, int wideglyph_width, unsigned max_lines)
|
||||
{
|
||||
char *lastspace = NULL;
|
||||
char *lastwideglyph = NULL;
|
||||
const char *src_end = src + strlen(src);
|
||||
unsigned lines = 1;
|
||||
/* 'line_width' means max numbers of characters per line,
|
||||
* but this metric is only meaningful when dealing with
|
||||
* 'regular' glyphs that have an on-screen pixel width
|
||||
* similar to that of regular Latin characters.
|
||||
* When handing so-called 'wide' Unicode glyphs, it is
|
||||
* necessary to consider the actual on-screen pixel width
|
||||
* of each character.
|
||||
* In order to do this, we create a distinction between
|
||||
* regular Latin 'non-wide' glyphs and 'wide' glyphs, and
|
||||
* normalise all values relative to the on-screen pixel
|
||||
* width of regular Latin characters:
|
||||
* - Regular 'non-wide' glyphs have a normalised width of 100
|
||||
* - 'line_width' is therefore normalised to 100 * (width_in_characters)
|
||||
* - 'wide' glyphs have a normalised width of
|
||||
* 100 * (wide_character_pixel_width / latin_character_pixel_width)
|
||||
* - When a character is detected, the position in the current
|
||||
* line is incremented by the regular normalised width of 100
|
||||
* - If that character is then determined to be a 'wide'
|
||||
* glyph, the position in the current line is further incremented
|
||||
* by the difference between the normalised 'wide' and 'non-wide'
|
||||
* width values */
|
||||
unsigned counter_normalized = 0;
|
||||
int line_width_normalized = line_width * 100;
|
||||
int additional_counter_normalized = wideglyph_width - 100;
|
||||
|
||||
/* Early return if src string length is less
|
||||
* than line width */
|
||||
if (src_end - src < line_width)
|
||||
{
|
||||
strlcpy(dst, src, dst_size);
|
||||
return;
|
||||
}
|
||||
|
||||
while (*src != '\0')
|
||||
{
|
||||
unsigned char_len;
|
||||
|
||||
char_len = (unsigned)(utf8skip(src, 1) - src);
|
||||
counter_normalized += 100;
|
||||
|
||||
/* Prevent buffer overflow */
|
||||
if (char_len >= dst_size)
|
||||
break;
|
||||
|
||||
if (*src == ' ')
|
||||
lastspace = dst; /* Remember the location of the whitespace */
|
||||
else if (*src == '\n')
|
||||
{
|
||||
/* If newlines embedded in the input,
|
||||
* reset the index */
|
||||
lines++;
|
||||
counter_normalized = 0;
|
||||
|
||||
/* Early return if remaining src string
|
||||
* length is less than line width */
|
||||
if (src_end - src <= line_width)
|
||||
{
|
||||
strlcpy(dst, src, dst_size);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (char_len >= 3)
|
||||
{
|
||||
/* Remember the location of the first byte
|
||||
* whose length as UTF-8 >= 3*/
|
||||
lastwideglyph = dst;
|
||||
counter_normalized += additional_counter_normalized;
|
||||
}
|
||||
|
||||
dst_size -= char_len;
|
||||
while (char_len--)
|
||||
*dst++ = *src++;
|
||||
|
||||
if (counter_normalized >= (unsigned)line_width_normalized)
|
||||
{
|
||||
counter_normalized = 0;
|
||||
|
||||
if (max_lines != 0 && lines >= max_lines)
|
||||
continue;
|
||||
else if (lastwideglyph && (!lastspace || lastwideglyph > lastspace))
|
||||
{
|
||||
/* Insert newline character */
|
||||
*lastwideglyph = '\n';
|
||||
lines++;
|
||||
src -= dst - lastwideglyph;
|
||||
dst = lastwideglyph + 1;
|
||||
lastwideglyph = NULL;
|
||||
|
||||
/* Early return if remaining src string
|
||||
* length is less than line width */
|
||||
if (src_end - src <= line_width)
|
||||
{
|
||||
strlcpy(dst, src, dst_size);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (lastspace)
|
||||
{
|
||||
/* Replace nearest (previous) whitespace
|
||||
* with newline character */
|
||||
*lastspace = '\n';
|
||||
lines++;
|
||||
src -= dst - lastspace - 1;
|
||||
dst = lastspace + 1;
|
||||
lastspace = NULL;
|
||||
|
||||
/* Early return if remaining src string
|
||||
* length is less than line width */
|
||||
if (src_end - src < line_width)
|
||||
{
|
||||
strlcpy(dst, src, dst_size);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*dst = '\0';
|
||||
}
|
||||
|
||||
/* Splits string into tokens seperated by 'delim'
|
||||
* > Returned token string must be free()'d
|
||||
* > Returns NULL if token is not found
|
||||
* > After each call, 'str' is set to the position after the
|
||||
* last found token
|
||||
* > Tokens *include* empty strings
|
||||
* Usage example:
|
||||
* char *str = "1,2,3,4,5,6,7,,,10,";
|
||||
* char **str_ptr = &str;
|
||||
* char *token = NULL;
|
||||
* while ((token = string_tokenize(str_ptr, ",")))
|
||||
* {
|
||||
* printf("%s\n", token);
|
||||
* free(token);
|
||||
* token = NULL;
|
||||
* }
|
||||
*/
|
||||
char* string_tokenize(char **str, const char *delim)
|
||||
{
|
||||
/* Taken from https://codereview.stackexchange.com/questions/216956/strtok-function-thread-safe-supports-empty-tokens-doesnt-change-string# */
|
||||
char *str_ptr = NULL;
|
||||
char *delim_ptr = NULL;
|
||||
char *token = NULL;
|
||||
size_t token_len = 0;
|
||||
|
||||
/* Sanity checks */
|
||||
if (!str || string_is_empty(delim))
|
||||
return NULL;
|
||||
|
||||
str_ptr = *str;
|
||||
|
||||
/* Note: we don't check string_is_empty() here,
|
||||
* empty strings are valid */
|
||||
if (!str_ptr)
|
||||
return NULL;
|
||||
|
||||
/* Search for delimiter */
|
||||
delim_ptr = strstr(str_ptr, delim);
|
||||
|
||||
if (delim_ptr)
|
||||
token_len = delim_ptr - str_ptr;
|
||||
else
|
||||
token_len = strlen(str_ptr);
|
||||
|
||||
/* Allocate token string */
|
||||
token = (char *)malloc((token_len + 1) * sizeof(char));
|
||||
|
||||
if (!token)
|
||||
return NULL;
|
||||
|
||||
/* Copy token */
|
||||
strlcpy(token, str_ptr, (token_len + 1) * sizeof(char));
|
||||
token[token_len] = '\0';
|
||||
|
||||
/* Update input string pointer */
|
||||
*str = delim_ptr ? delim_ptr + strlen(delim) : NULL;
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
/* Removes every instance of character 'c' from 'str' */
|
||||
void string_remove_all_chars(char *str, char c)
|
||||
{
|
||||
char *read_ptr = NULL;
|
||||
char *write_ptr = NULL;
|
||||
|
||||
if (string_is_empty(str))
|
||||
return;
|
||||
|
||||
read_ptr = str;
|
||||
write_ptr = str;
|
||||
|
||||
while (*read_ptr != '\0')
|
||||
{
|
||||
*write_ptr = *read_ptr++;
|
||||
write_ptr += (*write_ptr != c) ? 1 : 0;
|
||||
}
|
||||
|
||||
*write_ptr = '\0';
|
||||
}
|
||||
|
||||
/* Replaces every instance of character 'find' in 'str'
|
||||
* with character 'replace' */
|
||||
void string_replace_all_chars(char *str, char find, char replace)
|
||||
{
|
||||
char *str_ptr = str;
|
||||
|
||||
if (string_is_empty(str))
|
||||
return;
|
||||
|
||||
while ((str_ptr = strchr(str_ptr, find)))
|
||||
*str_ptr++ = replace;
|
||||
}
|
||||
|
||||
/* Converts string to unsigned integer.
|
||||
* Returns 0 if string is invalid */
|
||||
unsigned string_to_unsigned(const char *str)
|
||||
{
|
||||
const char *ptr = NULL;
|
||||
|
||||
if (string_is_empty(str))
|
||||
return 0;
|
||||
|
||||
for (ptr = str; *ptr != '\0'; ptr++)
|
||||
{
|
||||
if (!ISDIGIT((unsigned char)*ptr))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (unsigned)strtoul(str, NULL, 10);
|
||||
}
|
||||
|
||||
/* Converts hexadecimal string to unsigned integer.
|
||||
* Handles optional leading '0x'.
|
||||
* Returns 0 if string is invalid */
|
||||
unsigned string_hex_to_unsigned(const char *str)
|
||||
{
|
||||
const char *hex_str = str;
|
||||
const char *ptr = NULL;
|
||||
size_t len;
|
||||
|
||||
if (string_is_empty(str))
|
||||
return 0;
|
||||
|
||||
/* Remove leading '0x', if required */
|
||||
len = strlen(str);
|
||||
|
||||
if (len >= 2)
|
||||
if ((str[0] == '0') &&
|
||||
((str[1] == 'x') || (str[1] == 'X')))
|
||||
hex_str = str + 2;
|
||||
|
||||
if (string_is_empty(hex_str))
|
||||
return 0;
|
||||
|
||||
/* Check for valid characters */
|
||||
for (ptr = hex_str; *ptr != '\0'; ptr++)
|
||||
{
|
||||
if (!isxdigit((unsigned char)*ptr))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (unsigned)strtoul(hex_str, NULL, 16);
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (rtime.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
#include <rthreads/rthreads.h>
|
||||
#include <retro_assert.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <time/rtime.h>
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
/* TODO/FIXME - global */
|
||||
slock_t *rtime_localtime_lock = NULL;
|
||||
#endif
|
||||
|
||||
/* Must be called before using rtime_localtime() */
|
||||
void rtime_init(void)
|
||||
{
|
||||
rtime_deinit();
|
||||
#ifdef HAVE_THREADS
|
||||
if (!rtime_localtime_lock)
|
||||
rtime_localtime_lock = slock_new();
|
||||
|
||||
retro_assert(rtime_localtime_lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Must be called upon program termination */
|
||||
void rtime_deinit(void)
|
||||
{
|
||||
#ifdef HAVE_THREADS
|
||||
if (rtime_localtime_lock)
|
||||
{
|
||||
slock_free(rtime_localtime_lock);
|
||||
rtime_localtime_lock = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Thread-safe wrapper for localtime() */
|
||||
struct tm *rtime_localtime(const time_t *timep, struct tm *result)
|
||||
{
|
||||
struct tm *time_info = NULL;
|
||||
|
||||
/* Lock mutex */
|
||||
#ifdef HAVE_THREADS
|
||||
slock_lock(rtime_localtime_lock);
|
||||
#endif
|
||||
|
||||
time_info = localtime(timep);
|
||||
if (time_info)
|
||||
memcpy(result, time_info, sizeof(struct tm));
|
||||
|
||||
/* Unlock mutex */
|
||||
#ifdef HAVE_THREADS
|
||||
slock_unlock(rtime_localtime_lock);
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,12 @@
|
|||
These were compiled with default settings from:
|
||||
|
||||
https://github.com/nanake/libsoxr
|
||||
|
||||
Using CMake:
|
||||
|
||||
```
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" -DCMAKE_OSX_DEPLOYMENT_TARGET="10.12"
|
||||
make -j8
|
||||
```
|
|
@ -0,0 +1,344 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-18 robs@users.sourceforge.net
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This library 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 Lesser
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* -------------------------------- Gubbins --------------------------------- */
|
||||
|
||||
#if !defined soxr_included
|
||||
#define soxr_included
|
||||
|
||||
|
||||
#if defined __cplusplus
|
||||
#include <cstddef>
|
||||
extern "C" {
|
||||
#else
|
||||
#include <stddef.h>
|
||||
#endif
|
||||
|
||||
#if defined SOXR_DLL
|
||||
#if defined soxr_EXPORTS
|
||||
#define SOXR __declspec(dllexport)
|
||||
#else
|
||||
#define SOXR __declspec(dllimport)
|
||||
#endif
|
||||
#elif defined SOXR_VISIBILITY && defined __GNUC__ && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 1)
|
||||
#define SOXR __attribute__ ((visibility("default")))
|
||||
#else
|
||||
#define SOXR
|
||||
#endif
|
||||
|
||||
typedef struct soxr_io_spec soxr_io_spec_t;
|
||||
typedef struct soxr_quality_spec soxr_quality_spec_t;
|
||||
typedef struct soxr_runtime_spec soxr_runtime_spec_t;
|
||||
|
||||
|
||||
|
||||
/* ---------------------------- API conventions --------------------------------
|
||||
|
||||
Buffer lengths (and occupancies) are expressed as the number of contained
|
||||
samples per channel.
|
||||
|
||||
Parameter names for buffer lengths have the suffix `len'.
|
||||
|
||||
A single-character `i' or 'o' is often used in names to give context as
|
||||
input or output (e.g. ilen, olen). */
|
||||
|
||||
|
||||
|
||||
/* --------------------------- Version management --------------------------- */
|
||||
|
||||
/* E.g. #if SOXR_THIS_VERSION >= SOXR_VERSION(0,1,1) ... */
|
||||
|
||||
#define SOXR_VERSION(x,y,z) (((x)<<16)|((y)<<8)|(z))
|
||||
#define SOXR_THIS_VERSION SOXR_VERSION(0,1,3)
|
||||
#define SOXR_THIS_VERSION_STR "0.1.3"
|
||||
|
||||
|
||||
|
||||
/* --------------------------- Type declarations ---------------------------- */
|
||||
|
||||
typedef struct soxr * soxr_t; /* A resampler for 1 or more channels. */
|
||||
typedef char const * soxr_error_t; /* 0:no-error; non-0:error. */
|
||||
|
||||
typedef void * soxr_buf_t; /* 1 buffer of channel-interleaved samples. */
|
||||
typedef void const * soxr_cbuf_t; /* Ditto; read-only. */
|
||||
|
||||
typedef soxr_buf_t const * soxr_bufs_t;/* Or, a separate buffer for each ch. */
|
||||
typedef soxr_cbuf_t const * soxr_cbufs_t; /* Ditto; read-only. */
|
||||
|
||||
typedef void const * soxr_in_t; /* Either a soxr_cbuf_t or soxr_cbufs_t,
|
||||
depending on itype in soxr_io_spec_t. */
|
||||
typedef void * soxr_out_t; /* Either a soxr_buf_t or soxr_bufs_t,
|
||||
depending on otype in soxr_io_spec_t. */
|
||||
|
||||
|
||||
|
||||
/* --------------------------- API main functions --------------------------- */
|
||||
|
||||
SOXR char const * soxr_version(void); /* Query library version: "libsoxr-x.y.z" */
|
||||
|
||||
#define soxr_strerror(e) /* Soxr counterpart to strerror. */ \
|
||||
((e)?(e):"no error")
|
||||
|
||||
|
||||
/* Create a stream resampler: */
|
||||
|
||||
SOXR soxr_t soxr_create(
|
||||
double input_rate, /* Input sample-rate. */
|
||||
double output_rate, /* Output sample-rate. */
|
||||
unsigned num_channels, /* Number of channels to be used. */
|
||||
/* All following arguments are optional (may be set to NULL). */
|
||||
soxr_error_t *, /* To report any error during creation. */
|
||||
soxr_io_spec_t const *, /* To specify non-default I/O formats. */
|
||||
soxr_quality_spec_t const *, /* To specify non-default resampling quality.*/
|
||||
soxr_runtime_spec_t const *);/* To specify non-default runtime resources.
|
||||
|
||||
Default io_spec is per soxr_io_spec(SOXR_FLOAT32_I, SOXR_FLOAT32_I)
|
||||
Default quality_spec is per soxr_quality_spec(SOXR_HQ, 0)
|
||||
Default runtime_spec is per soxr_runtime_spec(1) */
|
||||
|
||||
|
||||
|
||||
/* If not using an app-supplied input function, after creating a stream
|
||||
* resampler, repeatedly call: */
|
||||
|
||||
SOXR soxr_error_t soxr_process(
|
||||
soxr_t resampler, /* As returned by soxr_create. */
|
||||
/* Input (to be resampled): */
|
||||
soxr_in_t in, /* Input buffer(s); may be NULL (see below). */
|
||||
size_t ilen, /* Input buf. length (samples per channel). */
|
||||
size_t * idone, /* To return actual # samples used (<= ilen). */
|
||||
/* Output (resampled): */
|
||||
soxr_out_t out, /* Output buffer(s).*/
|
||||
size_t olen, /* Output buf. length (samples per channel). */
|
||||
size_t * odone); /* To return actual # samples out (<= olen).
|
||||
|
||||
Note that no special meaning is associated with ilen or olen equal to
|
||||
zero. End-of-input (i.e. no data is available nor shall be available)
|
||||
may be indicated by seting `in' to NULL. */
|
||||
|
||||
|
||||
|
||||
/* If using an app-supplied input function, it must look and behave like this:*/
|
||||
|
||||
typedef size_t /* data_len */
|
||||
(* soxr_input_fn_t)( /* Supply data to be resampled. */
|
||||
void * input_fn_state, /* As given to soxr_set_input_fn (below). */
|
||||
soxr_in_t * data, /* Returned data; see below. N.B. ptr to ptr(s)*/
|
||||
size_t requested_len); /* Samples per channel, >= returned data_len.
|
||||
|
||||
data_len *data Indicates Meaning
|
||||
------- ------- ------------ -------------------------
|
||||
!=0 !=0 Success *data contains data to be
|
||||
input to the resampler.
|
||||
0 !=0 (or End-of-input No data is available nor
|
||||
not set) shall be available.
|
||||
0 0 Failure An error occurred whilst trying to
|
||||
source data to be input to the resampler. */
|
||||
|
||||
/* and be registered with a previously created stream resampler using: */
|
||||
|
||||
SOXR soxr_error_t soxr_set_input_fn(/* Set (or reset) an input function.*/
|
||||
soxr_t resampler, /* As returned by soxr_create. */
|
||||
soxr_input_fn_t, /* Function to supply data to be resampled.*/
|
||||
void * input_fn_state, /* If needed by the input function. */
|
||||
size_t max_ilen); /* Maximum value for input fn. requested_len.*/
|
||||
|
||||
/* then repeatedly call: */
|
||||
|
||||
SOXR size_t /*odone*/ soxr_output(/* Resample and output a block of data.*/
|
||||
soxr_t resampler, /* As returned by soxr_create. */
|
||||
soxr_out_t data, /* App-supplied buffer(s) for resampled data.*/
|
||||
size_t olen); /* Amount of data to output; >= odone. */
|
||||
|
||||
|
||||
|
||||
/* Common stream resampler operations: */
|
||||
|
||||
SOXR soxr_error_t soxr_error(soxr_t); /* Query error status. */
|
||||
SOXR size_t * soxr_num_clips(soxr_t); /* Query int. clip counter (for R/W). */
|
||||
SOXR double soxr_delay(soxr_t); /* Query current delay in output samples.*/
|
||||
SOXR char const * soxr_engine(soxr_t); /* Query resampling engine name. */
|
||||
|
||||
SOXR soxr_error_t soxr_clear(soxr_t); /* Ready for fresh signal, same config. */
|
||||
SOXR void soxr_delete(soxr_t); /* Free resources. */
|
||||
|
||||
|
||||
|
||||
/* `Short-cut', single call to resample a (probably short) signal held entirely
|
||||
* in memory. See soxr_create and soxr_process above for parameter details.
|
||||
* Note that unlike soxr_create however, the default quality spec. for
|
||||
* soxr_oneshot is per soxr_quality_spec(SOXR_LQ, 0). */
|
||||
|
||||
SOXR soxr_error_t soxr_oneshot(
|
||||
double input_rate,
|
||||
double output_rate,
|
||||
unsigned num_channels,
|
||||
soxr_in_t in , size_t ilen, size_t * idone,
|
||||
soxr_out_t out, size_t olen, size_t * odone,
|
||||
soxr_io_spec_t const *,
|
||||
soxr_quality_spec_t const *,
|
||||
soxr_runtime_spec_t const *);
|
||||
|
||||
|
||||
|
||||
/* For variable-rate resampling. See example # 5 for how to create a
|
||||
* variable-rate resampler and how to use this function. */
|
||||
|
||||
SOXR soxr_error_t soxr_set_io_ratio(soxr_t, double io_ratio, size_t slew_len);
|
||||
|
||||
|
||||
|
||||
/* -------------------------- API type definitions -------------------------- */
|
||||
|
||||
typedef enum { /* Datatypes supported for I/O to/from the resampler: */
|
||||
/* Internal; do not use: */
|
||||
SOXR_FLOAT32, SOXR_FLOAT64, SOXR_INT32, SOXR_INT16, SOXR_SPLIT = 4,
|
||||
|
||||
/* Use for interleaved channels: */
|
||||
SOXR_FLOAT32_I = SOXR_FLOAT32, SOXR_FLOAT64_I, SOXR_INT32_I, SOXR_INT16_I,
|
||||
|
||||
/* Use for split channels: */
|
||||
SOXR_FLOAT32_S = SOXR_SPLIT , SOXR_FLOAT64_S, SOXR_INT32_S, SOXR_INT16_S
|
||||
|
||||
} soxr_datatype_t;
|
||||
|
||||
#define soxr_datatype_size(x) /* Returns `sizeof' a soxr_datatype_t sample. */\
|
||||
((unsigned char *)"\4\10\4\2")[(x)&3]
|
||||
|
||||
|
||||
|
||||
struct soxr_io_spec { /* Typically */
|
||||
soxr_datatype_t itype; /* Input datatype. SOXR_FLOAT32_I */
|
||||
soxr_datatype_t otype; /* Output datatype. SOXR_FLOAT32_I */
|
||||
double scale; /* Linear gain to apply during resampling. 1 */
|
||||
void * e; /* Reserved for internal use 0 */
|
||||
unsigned long flags; /* Per the following #defines. 0 */
|
||||
};
|
||||
|
||||
#define SOXR_TPDF 0 /* Applicable only if otype is INT16. */
|
||||
#define SOXR_NO_DITHER 8u /* Disable the above. */
|
||||
|
||||
|
||||
|
||||
struct soxr_quality_spec { /* Typically */
|
||||
double precision; /* Conversion precision (in bits). 20 */
|
||||
double phase_response; /* 0=minimum, ... 50=linear, ... 100=maximum 50 */
|
||||
double passband_end; /* 0dB pt. bandwidth to preserve; nyquist=1 0.913*/
|
||||
double stopband_begin; /* Aliasing/imaging control; > passband_end 1 */
|
||||
void * e; /* Reserved for internal use. 0 */
|
||||
unsigned long flags; /* Per the following #defines. 0 */
|
||||
};
|
||||
|
||||
#define SOXR_ROLLOFF_SMALL 0u /* <= 0.01 dB */
|
||||
#define SOXR_ROLLOFF_MEDIUM 1u /* <= 0.35 dB */
|
||||
#define SOXR_ROLLOFF_NONE 2u /* For Chebyshev bandwidth. */
|
||||
|
||||
#define SOXR_HI_PREC_CLOCK 8u /* Increase `irrational' ratio accuracy. */
|
||||
#define SOXR_DOUBLE_PRECISION 16u /* Use D.P. calcs even if precision <= 20. */
|
||||
#define SOXR_VR 32u /* Variable-rate resampling. */
|
||||
|
||||
|
||||
|
||||
struct soxr_runtime_spec { /* Typically */
|
||||
unsigned log2_min_dft_size; /* For DFT efficiency. [8,15] 10 */
|
||||
unsigned log2_large_dft_size; /* For DFT efficiency. [8,20] 17 */
|
||||
unsigned coef_size_kbytes; /* For SOXR_COEF_INTERP_AUTO (below). 400 */
|
||||
unsigned num_threads; /* 0: per OMP_NUM_THREADS; 1: 1 thread. 1 */
|
||||
void * e; /* Reserved for internal use. 0 */
|
||||
unsigned long flags; /* Per the following #defines. 0 */
|
||||
};
|
||||
/* For `irrational' ratios only: */
|
||||
#define SOXR_COEF_INTERP_AUTO 0u /* Auto select coef. interpolation. */
|
||||
#define SOXR_COEF_INTERP_LOW 2u /* Man. select: less CPU, more memory. */
|
||||
#define SOXR_COEF_INTERP_HIGH 3u /* Man. select: more CPU, less memory. */
|
||||
|
||||
|
||||
|
||||
/* -------------------------- API type constructors ------------------------- */
|
||||
|
||||
/* These functions allow setting of the most commonly-used structure
|
||||
* parameters, with other parameters being given default values. The default
|
||||
* values may then be overridden, directly in the structure, if needed. */
|
||||
|
||||
SOXR soxr_quality_spec_t soxr_quality_spec(
|
||||
unsigned long recipe, /* Per the #defines immediately below. */
|
||||
unsigned long flags); /* As soxr_quality_spec_t.flags. */
|
||||
|
||||
/* The 5 standard qualities found in SoX: */
|
||||
#define SOXR_QQ 0 /* 'Quick' cubic interpolation. */
|
||||
#define SOXR_LQ 1 /* 'Low' 16-bit with larger rolloff. */
|
||||
#define SOXR_MQ 2 /* 'Medium' 16-bit with medium rolloff. */
|
||||
#define SOXR_HQ SOXR_20_BITQ /* 'High quality'. */
|
||||
#define SOXR_VHQ SOXR_28_BITQ /* 'Very high quality'. */
|
||||
|
||||
#define SOXR_16_BITQ 3
|
||||
#define SOXR_20_BITQ 4
|
||||
#define SOXR_24_BITQ 5
|
||||
#define SOXR_28_BITQ 6
|
||||
#define SOXR_32_BITQ 7
|
||||
/* Reserved for internal use (to be removed): */
|
||||
#define SOXR_LSR0Q 8 /* 'Best sinc'. */
|
||||
#define SOXR_LSR1Q 9 /* 'Medium sinc'. */
|
||||
#define SOXR_LSR2Q 10 /* 'Fast sinc'. */
|
||||
|
||||
#define SOXR_LINEAR_PHASE 0x00
|
||||
#define SOXR_INTERMEDIATE_PHASE 0x10
|
||||
#define SOXR_MINIMUM_PHASE 0x30
|
||||
|
||||
#define SOXR_STEEP_FILTER 0x40
|
||||
|
||||
|
||||
|
||||
SOXR soxr_runtime_spec_t soxr_runtime_spec(
|
||||
unsigned num_threads);
|
||||
|
||||
|
||||
|
||||
SOXR soxr_io_spec_t soxr_io_spec(
|
||||
soxr_datatype_t itype,
|
||||
soxr_datatype_t otype);
|
||||
|
||||
|
||||
|
||||
/* --------------------------- Advanced use only ---------------------------- */
|
||||
|
||||
/* For new designs, the following functions/usage will probably not be needed.
|
||||
* They might be useful when adding soxr into an existing design where values
|
||||
* for the resampling-rate and/or number-of-channels parameters to soxr_create
|
||||
* are not available when that function will be called. In such cases, the
|
||||
* relevant soxr_create parameter(s) can be given as 0, then one or both of the
|
||||
* following (as appropriate) later invoked (but prior to calling soxr_process
|
||||
* or soxr_output):
|
||||
*
|
||||
* soxr_set_error(soxr, soxr_set_io_ratio(soxr, io_ratio, 0));
|
||||
* soxr_set_error(soxr, soxr_set_num_channels(soxr, num_channels));
|
||||
*/
|
||||
|
||||
SOXR soxr_error_t soxr_set_error(soxr_t, soxr_error_t);
|
||||
SOXR soxr_error_t soxr_set_num_channels(soxr_t, unsigned);
|
||||
|
||||
|
||||
|
||||
#undef SOXR
|
||||
|
||||
#if defined __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
Binary file not shown.
|
@ -177,7 +177,6 @@
|
|||
8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; };
|
||||
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
|
||||
8E07AB790AAC930B00A4B32F /* PreferencesController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E07AB770AAC930B00A4B32F /* PreferencesController.m */; };
|
||||
8E6889240AAA403C00AD3950 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8E6889230AAA403C00AD3950 /* Carbon.framework */; };
|
||||
8E75757109F31D5A0080F1EE /* DNDArrayController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E75752C09F31D5A0080F1EE /* DNDArrayController.m */; };
|
||||
8E75757209F31D5A0080F1EE /* PlaylistController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E75752E09F31D5A0080F1EE /* PlaylistController.m */; };
|
||||
8E75757309F31D5A0080F1EE /* PlaylistEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E75753009F31D5A0080F1EE /* PlaylistEntry.m */; };
|
||||
|
@ -1012,7 +1011,6 @@
|
|||
8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
|
||||
8E07AB760AAC930B00A4B32F /* PreferencesController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PreferencesController.h; path = Preferences/PreferencesController.h; sourceTree = "<group>"; };
|
||||
8E07AB770AAC930B00A4B32F /* PreferencesController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = PreferencesController.m; path = Preferences/PreferencesController.m; sourceTree = "<group>"; };
|
||||
8E6889230AAA403C00AD3950 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
|
||||
8E75752B09F31D5A0080F1EE /* DNDArrayController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DNDArrayController.h; sourceTree = "<group>"; };
|
||||
8E75752C09F31D5A0080F1EE /* DNDArrayController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = DNDArrayController.m; sourceTree = "<group>"; };
|
||||
8E75752D09F31D5A0080F1EE /* PlaylistController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PlaylistController.h; sourceTree = "<group>"; };
|
||||
|
@ -1044,7 +1042,6 @@
|
|||
ED69CBC725BE32C00090B90D /* MASShortcut.framework in Frameworks */,
|
||||
8355D6B8180613FB00D05687 /* Security.framework in Frameworks */,
|
||||
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */,
|
||||
8E6889240AAA403C00AD3950 /* Carbon.framework in Frameworks */,
|
||||
17BB5CED0B8A86010009ACB1 /* AudioToolbox.framework in Frameworks */,
|
||||
17BB5CF90B8A86350009ACB1 /* AudioUnit.framework in Frameworks */,
|
||||
17BB5CFA0B8A86350009ACB1 /* CoreAudio.framework in Frameworks */,
|
||||
|
@ -1092,7 +1089,6 @@
|
|||
ED69CBB825BE328C0090B90D /* MASShortcut.xcodeproj */,
|
||||
838F851D256B4E5E00C3E614 /* Sparkle.framework */,
|
||||
17F5612A0C3BD4DC0019975C /* CogAudio.xcodeproj */,
|
||||
8E6889230AAA403C00AD3950 /* Carbon.framework */,
|
||||
1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */,
|
||||
);
|
||||
name = "Linked Frameworks";
|
||||
|
|
|
@ -245,20 +245,11 @@
|
|||
</connections>
|
||||
</customObject>
|
||||
<customView id="58" userLabel="OutputView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="530" height="185"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="530" height="156"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8GG-SU-ZrX">
|
||||
<rect key="frame" x="5" y="16" width="135" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="right" title="Resampling Quality: " id="tgE-40-uus">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="60">
|
||||
<rect key="frame" x="144" y="80" width="251" height="26"/>
|
||||
<rect key="frame" x="144" y="49" width="251" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Item1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" inset="2" arrowPosition="arrowAtCenter" preferredEdge="maxY" selectedItem="62" id="210">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
|
@ -279,7 +270,7 @@
|
|||
</connections>
|
||||
</popUpButton>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="zkP-2E-1Kc">
|
||||
<rect key="frame" x="17" y="51" width="123" height="17"/>
|
||||
<rect key="frame" x="17" y="22" width="123" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Volume Level:" id="wK4-EF-8Wa">
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -288,7 +279,7 @@
|
|||
</textFieldCell>
|
||||
</textField>
|
||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2v7-Ef-ekr">
|
||||
<rect key="frame" x="144" y="45" width="251" height="26"/>
|
||||
<rect key="frame" x="144" y="16" width="251" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="vmS-eb-zen">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
|
@ -308,29 +299,8 @@
|
|||
<binding destination="52" name="selectedObject" keyPath="values.volumeScaling" previousBinding="6uG-yb-1C2" id="mQV-hu-vZC"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="tW9-9e-FZx">
|
||||
<rect key="frame" x="144" y="10" width="251" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="Ara-An-Gkf" id="zFu-hG-VFE">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" title="OtherViews" id="Fqi-au-3Rx">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" id="Ara-An-Gkf"/>
|
||||
<menuItem title="Item 2" id="Yet-s2-7o3"/>
|
||||
<menuItem title="Item 3" id="MOu-Oy-HWV"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<binding destination="Yrc-8b-9dF" name="content" keyPath="arrangedObjects" id="AUP-bM-LUj"/>
|
||||
<binding destination="Yrc-8b-9dF" name="contentValues" keyPath="arrangedObjects.name" previousBinding="JGE-12-MXt" id="lIz-gH-9kJ"/>
|
||||
<binding destination="Yrc-8b-9dF" name="contentObjects" keyPath="arrangedObjects.preference" previousBinding="AUP-bM-LUj" id="JGE-12-MXt"/>
|
||||
<binding destination="52" name="selectedObject" keyPath="values.outputResampling" previousBinding="lIz-gH-9kJ" id="wcT-TT-yKh"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="65">
|
||||
<rect key="frame" x="17" y="86" width="123" height="17"/>
|
||||
<rect key="frame" x="17" y="55" width="123" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="right" title="Output Device: " id="211">
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -339,7 +309,7 @@
|
|||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="DhK-tx-xFv">
|
||||
<rect key="frame" x="18" y="156" width="227" height="18"/>
|
||||
<rect key="frame" x="18" y="127" width="227" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Limit volume control to 100%" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="ds2-aw-ebU">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
|
@ -350,7 +320,7 @@
|
|||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1aX-Fo-arv">
|
||||
<rect key="frame" x="18" y="119" width="20" height="18"/>
|
||||
<rect key="frame" x="18" y="90" width="20" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="EJb-yF-qRd">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
|
@ -361,7 +331,7 @@
|
|||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="4qt-T1-7jG" userLabel="Push Button - Select a SoundFont">
|
||||
<rect key="frame" x="36" y="111" width="73" height="32"/>
|
||||
<rect key="frame" x="36" y="82" width="73" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Select" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Otm-xP-EEU" userLabel="Button Cell - Select a SoundFont">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
|
@ -372,7 +342,7 @@
|
|||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="kOF-Po-oeH" userLabel="Push Button - Select a SoundFont">
|
||||
<rect key="frame" x="102" y="111" width="43" height="32"/>
|
||||
<rect key="frame" x="102" y="82" width="43" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="X" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="eOk-lh-q1L" userLabel="Button Cell - Select a SoundFont">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
|
@ -383,7 +353,7 @@
|
|||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="iZm-aN-M1J" userLabel="Text Field - Selected:">
|
||||
<rect key="frame" x="145" y="120" width="45" height="17"/>
|
||||
<rect key="frame" x="145" y="91" width="45" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="HRIR:" id="1Bl-uL-Xda" userLabel="Text Field Cell - Selected">
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -392,7 +362,7 @@
|
|||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="bsA-1J-aVt">
|
||||
<rect key="frame" x="187" y="120" width="275" height="17"/>
|
||||
<rect key="frame" x="187" y="91" width="275" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Label" id="5vB-dF-Jvk">
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -409,7 +379,7 @@
|
|||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<point key="canvasLocation" x="-151" y="317.5"/>
|
||||
<point key="canvasLocation" x="-151" y="303"/>
|
||||
</customView>
|
||||
<customObject id="i5B-ga-Atm" userLabel="MIDIPane" customClass="MIDIPane">
|
||||
<connections>
|
||||
|
@ -712,13 +682,5 @@
|
|||
</declaredKeys>
|
||||
<classReference key="objectClass" className="NSDictionary"/>
|
||||
</arrayController>
|
||||
<arrayController objectClassName="NSDictionary" editable="NO" id="Yrc-8b-9dF" customClass="OutputResamplerBehaviorArrayController">
|
||||
<declaredKeys>
|
||||
<string>name</string>
|
||||
<string>slug</string>
|
||||
<string>preference</string>
|
||||
</declaredKeys>
|
||||
<classReference key="objectClass" className="NSDictionary"/>
|
||||
</arrayController>
|
||||
</objects>
|
||||
</document>
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
//
|
||||
// OutputResamplerBehaviorArrayController.h
|
||||
// General
|
||||
//
|
||||
// Created by Christopher Snowhill on 01/11/22.
|
||||
//
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface OutputResamplerBehaviorArrayController : NSArrayController
|
||||
|
||||
@end
|
|
@ -1,42 +0,0 @@
|
|||
//
|
||||
// OutputResamplerBehaviorArrayController.m
|
||||
// General
|
||||
//
|
||||
// Created by Christopher Snowhill on 01/11/22.
|
||||
//
|
||||
//
|
||||
|
||||
#import "OutputResamplerBehaviorArrayController.h"
|
||||
|
||||
@implementation OutputResamplerBehaviorArrayController
|
||||
- (void)awakeFromNib
|
||||
{
|
||||
[self removeObjects:[self arrangedObjects]];
|
||||
|
||||
[self addObject:
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
NSLocalizedStringFromTableInBundle(@"Lowest", nil, [NSBundle bundleForClass:[self class]], @"") , @"name",
|
||||
@"lowest", @"preference",nil]];
|
||||
|
||||
[self addObject:
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
NSLocalizedStringFromTableInBundle(@"Lower", nil, [NSBundle bundleForClass:[self class]], @"") , @"name",
|
||||
@"lower", @"preference",nil]];
|
||||
|
||||
[self addObject:
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
NSLocalizedStringFromTableInBundle(@"Normal", nil, [NSBundle bundleForClass:[self class]], @"") , @"name",
|
||||
@"normal", @"preference",nil]];
|
||||
|
||||
[self addObject:
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
NSLocalizedStringFromTableInBundle(@"Higher", nil, [NSBundle bundleForClass:[self class]], @"") , @"name",
|
||||
@"higher", @"preference",nil]];
|
||||
|
||||
[self addObject:
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
NSLocalizedStringFromTableInBundle(@"Highest", nil, [NSBundle bundleForClass:[self class]], @"") , @"name",
|
||||
@"highest", @"preference",nil]];
|
||||
}
|
||||
|
||||
@end
|
|
@ -18,7 +18,6 @@
|
|||
17E41DB80C130AA500AC744D /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 17E41DB70C130AA500AC744D /* Localizable.strings */; };
|
||||
17E78A7E0D68BE3C005C5A59 /* file_tree.png in Resources */ = {isa = PBXBuildFile; fileRef = 17E78A7D0D68BE3C005C5A59 /* file_tree.png */; };
|
||||
17E78B6A0D68C1E3005C5A59 /* Preferences.xib in Resources */ = {isa = PBXBuildFile; fileRef = 17E78B680D68C1E3005C5A59 /* Preferences.xib */; };
|
||||
832BEF00278D989E005E1BC4 /* OutputResamplerBehaviorArrayController.m in Sources */ = {isa = PBXBuildFile; fileRef = 832BEEFC278D989E005E1BC4 /* OutputResamplerBehaviorArrayController.m */; };
|
||||
83651DA527322C8700A2C097 /* MIDIFlavorBehaviorArrayController.m in Sources */ = {isa = PBXBuildFile; fileRef = 83651DA327322C8700A2C097 /* MIDIFlavorBehaviorArrayController.m */; };
|
||||
8372053718E3DEAF007EFAD4 /* ResamplerBehaviorArrayController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8372053618E3DEAF007EFAD4 /* ResamplerBehaviorArrayController.m */; };
|
||||
837C0D401C50954000CAE18F /* MIDIPluginBehaviorArrayController.m in Sources */ = {isa = PBXBuildFile; fileRef = 837C0D3F1C50954000CAE18F /* MIDIPluginBehaviorArrayController.m */; };
|
||||
|
@ -94,8 +93,6 @@
|
|||
32DBCF630370AF2F00C91783 /* Preferences_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Preferences_Prefix.pch; sourceTree = "<group>"; };
|
||||
3DFAC48E235B6B8100A29416 /* DEVELOPMENT_TEAM.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = DEVELOPMENT_TEAM.xcconfig; sourceTree = "<group>"; };
|
||||
3DFAC48F235B6B8100A29416 /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; };
|
||||
832BEEFC278D989E005E1BC4 /* OutputResamplerBehaviorArrayController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OutputResamplerBehaviorArrayController.m; sourceTree = "<group>"; };
|
||||
832BEEFF278D989E005E1BC4 /* OutputResamplerBehaviorArrayController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OutputResamplerBehaviorArrayController.h; sourceTree = "<group>"; };
|
||||
833F681B1CDBCAA700AFB9F0 /* es */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
833F681C1CDBCAA700AFB9F0 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
8347435D20E6D58800063D45 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Preferences.strings; sourceTree = "<group>"; };
|
||||
|
@ -250,8 +247,6 @@
|
|||
83651DA327322C8700A2C097 /* MIDIFlavorBehaviorArrayController.m */,
|
||||
837C0D3E1C50954000CAE18F /* MIDIPluginBehaviorArrayController.h */,
|
||||
837C0D3F1C50954000CAE18F /* MIDIPluginBehaviorArrayController.m */,
|
||||
832BEEFF278D989E005E1BC4 /* OutputResamplerBehaviorArrayController.h */,
|
||||
832BEEFC278D989E005E1BC4 /* OutputResamplerBehaviorArrayController.m */,
|
||||
17C643370B8A77CC00C53518 /* OutputsArrayController.h */,
|
||||
17C643360B8A77CC00C53518 /* OutputsArrayController.m */,
|
||||
99F1813D0DE01D7A00FD5FFB /* PlaylistBehaviorArrayController.h */,
|
||||
|
@ -464,7 +459,6 @@
|
|||
8E07AA8A0AAC8EA200A4B32F /* GeneralPreferencesPlugin.m in Sources */,
|
||||
83EF495F17FBC96A00642E3C /* VolumeBehaviorArrayController.m in Sources */,
|
||||
17C643380B8A77CC00C53518 /* OutputsArrayController.m in Sources */,
|
||||
832BEF00278D989E005E1BC4 /* OutputResamplerBehaviorArrayController.m in Sources */,
|
||||
837C0D401C50954000CAE18F /* MIDIPluginBehaviorArrayController.m in Sources */,
|
||||
17C6433F0B8A783F00C53518 /* OutputPane.m in Sources */,
|
||||
170744AD0BFF3938002475C9 /* AppcastArrayController.m in Sources */,
|
||||
|
|
12
README.md
12
README.md
|
@ -47,14 +47,6 @@ Setup your `DEVELOPMENT_TEAM` like described in [Xcode-config/Shared.xcconfig](h
|
|||
![Mini window](https://github.com/losnoco/Cog/blob/main/.github/images/MiniWindow.png)
|
||||
|
||||
|
||||
ADDENDUM - 2022-01-12
|
||||
|
||||
For some basic eye candy comparisons on the newly included RetroArch sinc
|
||||
resampler, please see this test project:
|
||||
|
||||
https://github.com/kode54/retroarch_resampler_test
|
||||
|
||||
|
||||
ADDENDUM - 2022-01-25
|
||||
|
||||
I've added an HRIR convolver, based on the HeSuVi HRIR format. A preset is
|
||||
|
@ -82,3 +74,7 @@ used for both left and right outputs.
|
|||
[Here are some preset HRIR files](https://cogcdn.cog.losno.co/HeSuVi-hrir-basic.7z).
|
||||
|
||||
The original HeSuVi project is located [here](https://sourceforge.net/projects/hesuvi/).
|
||||
|
||||
ADDENDUM - 2022-02-01
|
||||
|
||||
I've replaced the resampler with libsoxr, with no quality control settings exposed.
|
Loading…
Reference in New Issue