Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Libretro
Lutro
Commits
bc0dae44
Unverified
Commit
bc0dae44
authored
Apr 10, 2021
by
RobLoach
Committed by
GitHub
Apr 10, 2021
Browse files
Merge pull request #186 from libretro/update-libretro
Update libretro-common
parents
b5469ad2
c4c4686c
Changes
68
Hide whitespace changes
Inline
Side-by-side
Makefile.common
View file @
bc0dae44
...
...
@@ -64,16 +64,25 @@ endif
ifneq
($(STATIC_LINKING), 1)
SOURCES_C
+=
\
$(CORE_DIR)
/libretro-common/file/file_path.c
\
$(CORE_DIR)
/libretro-common/file/file_path_io.c
\
$(CORE_DIR)
/libretro-common/features/features_cpu.c
\
$(CORE_DIR)
/libretro-common/audio/conversion/float_to_s16.c
\
$(CORE_DIR)
/libretro-common/audio/conversion/s16_to_float.c
\
$(CORE_DIR)
/libretro-common/audio/audio_mix.c
\
$(CORE_DIR)
/libretro-common/compat/compat_posix_string.c
\
$(CORE_DIR)
/libretro-common/memmap/memalign.c
\
$(CORE_DIR)
/libretro-common/memmap/memmap.c
\
$(CORE_DIR)
/libretro-common/compat/compat_strcasestr.c
\
$(CORE_DIR)
/libretro-common/compat/compat_strl.c
\
$(CORE_DIR)
/libretro-common/encodings/encoding_crc32.c
\
$(CORE_DIR)
/libretro-common/encodings/encoding_utf.c
\
$(CORE_DIR)
/libretro-common/time/rtime.c
\
$(CORE_DIR)
/libretro-common/streams/file_stream.c
\
$(CORE_DIR)
/libretro-common/streams/trans_stream.c
\
$(CORE_DIR)
/libretro-common/streams/trans_stream_pipe.c
\
$(CORE_DIR)
/libretro-common/streams/interface_stream.c
\
$(CORE_DIR)
/libretro-common/streams/memory_stream.c
\
$(CORE_DIR)
/libretro-common/string/stdstring.c
\
$(CORE_DIR)
/libretro-common/vfs/vfs_implementation.c
\
$(CORE_DIR)
/libretro-common/compat/fopen_utf8.c
ifeq
($(HAVE_NEON),1)
...
...
libretro-common/audio/audio_mix.c
View file @
bc0dae44
/* Copyright (C) 2010-20
17
The RetroArch team
/* Copyright (C) 2010-20
20
The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (audio_mix.c).
...
...
@@ -20,7 +20,12 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <audio/audio_mix.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memalign.h>
#include <retro_environment.h>
#if defined(__SSE2__)
#include <emmintrin.h>
...
...
@@ -28,6 +33,12 @@
#include <altivec.h>
#endif
#include <retro_miscellaneous.h>
#include <audio/audio_mix.h>
#include <streams/file_stream.h>
#include <audio/conversion/float_to_s16.h>
#include <audio/conversion/s16_to_float.h>
void
audio_mix_volume_C
(
float
*
out
,
const
float
*
in
,
float
vol
,
size_t
samples
)
{
size_t
i
;
...
...
@@ -38,7 +49,7 @@ void audio_mix_volume_C(float *out, const float *in, float vol, size_t samples)
#ifdef __SSE2__
void
audio_mix_volume_SSE2
(
float
*
out
,
const
float
*
in
,
float
vol
,
size_t
samples
)
{
size_t
i
;
size_t
i
,
remaining_samples
;
__m128
volume
=
_mm_set1_ps
(
vol
);
for
(
i
=
0
;
i
+
16
<=
samples
;
i
+=
16
,
out
+=
16
,
in
+=
16
)
...
...
@@ -46,7 +57,7 @@ void audio_mix_volume_SSE2(float *out, const float *in, float vol, size_t sample
unsigned
j
;
__m128
input
[
4
];
__m128
additive
[
4
];
input
[
0
]
=
_mm_loadu_ps
(
out
+
0
);
input
[
1
]
=
_mm_loadu_ps
(
out
+
4
);
input
[
2
]
=
_mm_loadu_ps
(
out
+
8
);
...
...
@@ -61,7 +72,310 @@ void audio_mix_volume_SSE2(float *out, const float *in, float vol, size_t sample
_mm_storeu_ps
(
out
+
4
*
j
,
_mm_add_ps
(
input
[
j
],
additive
[
j
]));
}
audio_mix_volume_C
(
out
,
in
,
vol
,
samples
-
i
);
remaining_samples
=
samples
-
i
;
for
(
i
=
0
;
i
<
remaining_samples
;
i
++
)
out
[
i
]
+=
in
[
i
]
*
vol
;
}
#endif
void
audio_mix_free_chunk
(
audio_chunk_t
*
chunk
)
{
if
(
!
chunk
)
return
;
#ifdef HAVE_RWAV
if
(
chunk
->
rwav
&&
chunk
->
rwav
->
samples
)
{
/* rwav_free only frees the samples */
rwav_free
(
chunk
->
rwav
);
free
(
chunk
->
rwav
);
}
#endif
if
(
chunk
->
buf
)
free
(
chunk
->
buf
);
if
(
chunk
->
upsample_buf
)
memalign_free
(
chunk
->
upsample_buf
);
if
(
chunk
->
float_buf
)
memalign_free
(
chunk
->
float_buf
);
if
(
chunk
->
float_resample_buf
)
memalign_free
(
chunk
->
float_resample_buf
);
if
(
chunk
->
resample_buf
)
memalign_free
(
chunk
->
resample_buf
);
if
(
chunk
->
resampler
&&
chunk
->
resampler_data
)
chunk
->
resampler
->
free
(
chunk
->
resampler_data
);
free
(
chunk
);
}
audio_chunk_t
*
audio_mix_load_wav_file
(
const
char
*
path
,
int
sample_rate
)
{
#ifdef HAVE_RWAV
int
sample_size
;
int64_t
len
=
0
;
void
*
buf
=
NULL
;
audio_chunk_t
*
chunk
=
(
audio_chunk_t
*
)
malloc
(
sizeof
(
*
chunk
));
if
(
!
chunk
)
return
NULL
;
chunk
->
buf
=
NULL
;
chunk
->
upsample_buf
=
NULL
;
chunk
->
float_buf
=
NULL
;
chunk
->
float_resample_buf
=
NULL
;
chunk
->
resample_buf
=
NULL
;
chunk
->
len
=
0
;
chunk
->
resample_len
=
0
;
chunk
->
rwav
=
(
rwav_t
*
)
malloc
(
sizeof
(
rwav_t
));
chunk
->
sample_rate
=
sample_rate
;
chunk
->
resample
=
false
;
chunk
->
resampler
=
NULL
;
chunk
->
resampler_data
=
NULL
;
chunk
->
ratio
=
0
.
00
f
;
chunk
->
rwav
->
bitspersample
=
0
;
chunk
->
rwav
->
numchannels
=
0
;
chunk
->
rwav
->
samplerate
=
0
;
chunk
->
rwav
->
numsamples
=
0
;
chunk
->
rwav
->
subchunk2size
=
0
;
chunk
->
rwav
->
samples
=
NULL
;
if
(
!
filestream_read_file
(
path
,
&
buf
,
&
len
))
{
printf
(
"Could not open WAV file for reading.
\n
"
);
goto
error
;
}
chunk
->
buf
=
buf
;
chunk
->
len
=
len
;
if
(
rwav_load
(
chunk
->
rwav
,
chunk
->
buf
,
chunk
->
len
)
==
RWAV_ITERATE_ERROR
)
{
printf
(
"error: could not load WAV file
\n
"
);
goto
error
;
}
/* numsamples does not know or care about
* multiple channels, but we need space for 2 */
chunk
->
upsample_buf
=
(
int16_t
*
)
memalign_alloc
(
128
,
chunk
->
rwav
->
numsamples
*
2
*
sizeof
(
int16_t
));
sample_size
=
chunk
->
rwav
->
bitspersample
/
8
;
if
(
sample_size
==
1
)
{
unsigned
i
;
if
(
chunk
->
rwav
->
numchannels
==
1
)
{
for
(
i
=
0
;
i
<
chunk
->
rwav
->
numsamples
;
i
++
)
{
uint8_t
*
sample
=
(
(
uint8_t
*
)
chunk
->
rwav
->
samples
)
+
i
;
chunk
->
upsample_buf
[
i
*
2
]
=
(
int16_t
)((
sample
[
0
]
-
128
)
<<
8
);
chunk
->
upsample_buf
[(
i
*
2
)
+
1
]
=
(
int16_t
)((
sample
[
0
]
-
128
)
<<
8
);
}
}
else
if
(
chunk
->
rwav
->
numchannels
==
2
)
{
for
(
i
=
0
;
i
<
chunk
->
rwav
->
numsamples
;
i
++
)
{
uint8_t
*
sample
=
(
(
uint8_t
*
)
chunk
->
rwav
->
samples
)
+
(
i
*
2
);
chunk
->
upsample_buf
[
i
*
2
]
=
(
int16_t
)((
sample
[
0
]
-
128
)
<<
8
);
chunk
->
upsample_buf
[(
i
*
2
)
+
1
]
=
(
int16_t
)((
sample
[
1
]
-
128
)
<<
8
);
}
}
}
else
if
(
sample_size
==
2
)
{
if
(
chunk
->
rwav
->
numchannels
==
1
)
{
unsigned
i
;
for
(
i
=
0
;
i
<
chunk
->
rwav
->
numsamples
;
i
++
)
{
int16_t
sample
=
((
int16_t
*
)
chunk
->
rwav
->
samples
)[
i
];
chunk
->
upsample_buf
[
i
*
2
]
=
sample
;
chunk
->
upsample_buf
[(
i
*
2
)
+
1
]
=
sample
;
}
}
else
if
(
chunk
->
rwav
->
numchannels
==
2
)
memcpy
(
chunk
->
upsample_buf
,
chunk
->
rwav
->
samples
,
chunk
->
rwav
->
subchunk2size
);
}
else
if
(
sample_size
!=
2
)
{
/* we don't support any other sample size besides 8 and 16-bit yet */
printf
(
"error: we don't support a sample size of %d
\n
"
,
sample_size
);
goto
error
;
}
if
(
sample_rate
!=
(
int
)
chunk
->
rwav
->
samplerate
)
{
chunk
->
resample
=
true
;
chunk
->
ratio
=
(
double
)
sample_rate
/
chunk
->
rwav
->
samplerate
;
retro_resampler_realloc
(
&
chunk
->
resampler_data
,
&
chunk
->
resampler
,
NULL
,
RESAMPLER_QUALITY_DONTCARE
,
chunk
->
ratio
);
if
(
chunk
->
resampler
&&
chunk
->
resampler_data
)
{
struct
resampler_data
info
;
chunk
->
float_buf
=
(
float
*
)
memalign_alloc
(
128
,
chunk
->
rwav
->
numsamples
*
2
*
chunk
->
ratio
*
sizeof
(
float
));
/* why is *3 needed instead of just *2? Does the
* sinc driver require more space than we know about? */
chunk
->
float_resample_buf
=
(
float
*
)
memalign_alloc
(
128
,
chunk
->
rwav
->
numsamples
*
3
*
chunk
->
ratio
*
sizeof
(
float
));
convert_s16_to_float
(
chunk
->
float_buf
,
chunk
->
upsample_buf
,
chunk
->
rwav
->
numsamples
*
2
,
1
.
0
);
info
.
data_in
=
(
const
float
*
)
chunk
->
float_buf
;
info
.
data_out
=
chunk
->
float_resample_buf
;
/* a 'frame' consists of two channels, so we set this
* to the number of samples irrespective of channel count */
info
.
input_frames
=
chunk
->
rwav
->
numsamples
;
info
.
output_frames
=
0
;
info
.
ratio
=
chunk
->
ratio
;
chunk
->
resampler
->
process
(
chunk
->
resampler_data
,
&
info
);
/* number of output_frames does not increase with
* multiple channels, but assume we need space for 2 */
chunk
->
resample_buf
=
(
int16_t
*
)
memalign_alloc
(
128
,
info
.
output_frames
*
2
*
sizeof
(
int16_t
));
chunk
->
resample_len
=
info
.
output_frames
;
convert_float_to_s16
(
chunk
->
resample_buf
,
chunk
->
float_resample_buf
,
info
.
output_frames
*
2
);
}
}
return
chunk
;
error:
audio_mix_free_chunk
(
chunk
);
#endif
return
NULL
;
}
size_t
audio_mix_get_chunk_num_samples
(
audio_chunk_t
*
chunk
)
{
if
(
!
chunk
)
return
0
;
#ifdef HAVE_RWAV
if
(
chunk
->
rwav
)
{
if
(
chunk
->
resample
)
return
chunk
->
resample_len
;
return
chunk
->
rwav
->
numsamples
;
}
#endif
/* no other filetypes supported yet */
return
0
;
}
/**
* audio_mix_get_chunk_sample:
* @chunk : audio chunk instance
* @channel : channel of the sample (0=left, 1=right)
* @index : index of the sample
*
* Get a sample from an audio chunk.
*
* Returns: A signed 16-bit audio sample.
**/
int16_t
audio_mix_get_chunk_sample
(
audio_chunk_t
*
chunk
,
unsigned
channel
,
size_t
index
)
{
if
(
!
chunk
)
return
0
;
#ifdef HAVE_RWAV
if
(
chunk
->
rwav
)
{
int
sample_size
=
chunk
->
rwav
->
bitspersample
/
8
;
int16_t
sample_out
=
0
;
/* 0 is the first/left channel */
uint8_t
*
sample
=
NULL
;
if
(
chunk
->
resample
)
sample
=
(
uint8_t
*
)
chunk
->
resample_buf
+
(
sample_size
*
index
*
chunk
->
rwav
->
numchannels
)
+
(
channel
*
sample_size
);
else
sample
=
(
uint8_t
*
)
chunk
->
upsample_buf
+
(
sample_size
*
index
*
chunk
->
rwav
->
numchannels
)
+
(
channel
*
sample_size
);
sample_out
=
(
int16_t
)
*
sample
;
return
sample_out
;
}
#endif
/* no other filetypes supported yet */
return
0
;
}
int16_t
*
audio_mix_get_chunk_samples
(
audio_chunk_t
*
chunk
)
{
if
(
!
chunk
)
return
0
;
#ifdef HAVE_RWAV
if
(
chunk
->
rwav
)
{
int16_t
*
sample
;
if
(
chunk
->
resample
)
sample
=
chunk
->
resample_buf
;
else
sample
=
chunk
->
upsample_buf
;
return
sample
;
}
#endif
return
NULL
;
}
int
audio_mix_get_chunk_num_channels
(
audio_chunk_t
*
chunk
)
{
if
(
!
chunk
)
return
0
;
#ifdef HAVE_RWAV
if
(
chunk
->
rwav
)
return
chunk
->
rwav
->
numchannels
;
#endif
/* don't support other formats yet */
return
0
;
}
libretro-common/audio/conversion/float_to_s16.c
View file @
bc0dae44
/* Copyright (C) 2010-20
17
The RetroArch team
/* Copyright (C) 2010-20
20
The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (float_to_s16.c).
...
...
@@ -28,15 +28,15 @@
#include <altivec.h>
#endif
#include <features/features_cpu.h>
#include <audio/conversion/float_to_s16.h>
#if defined(__ARM_NEON__) && !defined(DONT_WANT_ARM_OPTIMIZATIONS) || defined(HAVE_NEON)
#if (defined(__ARM_NEON__) && !defined(DONT_WANT_ARM_OPTIMIZATIONS)) || defined(HAVE_NEON)
#ifndef HAVE_ARM_NEON_OPTIMIZATIONS
#define HAVE_ARM_NEON_OPTIMIZATIONS
#endif
#endif
#include <features/features_cpu.h>
#include <audio/conversion/float_to_s16.h>
#if defined(HAVE_ARM_NEON_OPTIMIZATIONS)
static
bool
float_to_s16_neon_enabled
=
false
;
void
convert_float_s16_asm
(
int16_t
*
out
,
const
float
*
in
,
size_t
samples
);
...
...
@@ -48,7 +48,7 @@ void convert_float_s16_asm(int16_t *out, const float *in, size_t samples);
* @in : input buffer
* @samples : size of samples to be converted
*
* Converts floating point
* Converts floating point
* to signed integer 16-bit.
*
* C implementation callback function.
...
...
@@ -78,7 +78,7 @@ void convert_float_to_s16(int16_t *out,
#elif defined(__ALTIVEC__)
int
samples_in
=
samples
;
/* Unaligned loads/store is a bit expensive,
/* Unaligned loads/store is a bit expensive,
* so we optimize for the good path (very likely). */
if
(((
uintptr_t
)
out
&
15
)
+
((
uintptr_t
)
in
&
15
)
==
0
)
{
...
...
@@ -112,7 +112,7 @@ void convert_float_to_s16(int16_t *out,
#elif defined(_MIPS_ARCH_ALLEGREX)
#ifdef DEBUG
/* Make sure the buffers are 16 byte aligned, this should be
/* Make sure the buffers are 16 byte aligned, this should be
* the default behaviour of malloc in the PSPSDK.
* Assume alignment. */
retro_assert
(((
uintptr_t
)
in
&
0xf
)
==
0
);
...
...
libretro-common/audio/conversion/float_to_s16_neon.S
View file @
bc0dae44
/*
Copyright
(
C
)
2010
-
20
17
The
RetroArch
team
/*
Copyright
(
C
)
2010
-
20
20
The
RetroArch
team
*
*
---------------------------------------------------------------------------------------
*
The
following
license
statement
only
applies
to
this
file
(
float_to_s16_neon
.
S
)
.
...
...
libretro-common/audio/conversion/float_to_s16_neon.c
View file @
bc0dae44
/* Copyright (C) 2010-20
17
The RetroArch team
/* Copyright (C) 2010-20
20
The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (float_to_s16_neon.S).
...
...
libretro-common/audio/conversion/s16_to_float.c
View file @
bc0dae44
/* Copyright (C) 2010-20
17
The RetroArch team
/* Copyright (C) 2010-20
20
The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (s16_to_float.c).
...
...
@@ -29,7 +29,7 @@
#include <features/features_cpu.h>
#include <audio/conversion/s16_to_float.h>
#if defined(__ARM_NEON__) && !defined(DONT_WANT_ARM_OPTIMIZATIONS) || defined(HAVE_NEON)
#if
(
defined(__ARM_NEON__) && !defined(DONT_WANT_ARM_OPTIMIZATIONS)
)
|| defined(HAVE_NEON)
#ifndef HAVE_ARM_NEON_OPTIMIZATIONS
#define HAVE_ARM_NEON_OPTIMIZATIONS
#endif
...
...
@@ -56,7 +56,7 @@ void convert_s16_float_asm(float *out, const int16_t *in,
void
convert_s16_to_float
(
float
*
out
,
const
int16_t
*
in
,
size_t
samples
,
float
gain
)
{
size_t
i
=
0
;
unsigned
i
=
0
;
#if defined(__SSE2__)
float
fgain
=
gain
/
UINT32_C
(
0x80000000
);
...
...
@@ -79,11 +79,10 @@ void convert_s16_to_float(float *out,
#elif defined(__ALTIVEC__)
size_t
samples_in
=
samples
;
/* Unaligned loads/store is a bit expensive, so we
/* Unaligned loads/store is a bit expensive, so we
* optimize for the good path (very likely). */
if
(((
uintptr_t
)
out
&
15
)
+
((
uintptr_t
)
in
&
15
)
==
0
)
{
size_t
i
;
const
vector
float
gain_vec
=
{
gain
,
gain
,
gain
,
gain
};
const
vector
float
zero_vec
=
{
0
.
0
f
,
0
.
0
f
,
0
.
0
f
,
0
.
0
f
};
...
...
@@ -119,15 +118,18 @@ void convert_s16_to_float(float *out,
i
=
0
;
}
#elif defined(_MIPS_ARCH_ALLEGREX)
#endif
gain
=
gain
/
0x8000
;
#if defined(_MIPS_ARCH_ALLEGREX)
#ifdef DEBUG
/* Make sure the buffer is 16 byte aligned, this should be the
/* Make sure the buffer is 16 byte aligned, this should be the
* default behaviour of malloc in the PSPSDK.
* Only the output buffer can be assumed to be 16-byte aligned. */
retro_assert
(((
uintptr_t
)
out
&
0xf
)
==
0
);
#endif
gain
=
gain
/
0x8000
;
__asm__
(
".set push
\n
"
".set noreorder
\n
"
...
...
@@ -172,10 +174,9 @@ void convert_s16_to_float(float *out,
}
#endif
gain
=
gain
/
0x8000
;
for
(;
i
<
samples
;
i
++
)
out
[
i
]
=
(
float
)
in
[
i
]
*
gain
;
out
[
i
]
=
(
float
)
in
[
i
]
*
gain
;
}
/**
...
...
libretro-common/audio/conversion/s16_to_float_neon.S
View file @
bc0dae44
/*
Copyright
(
C
)
2010
-
20
17
The
RetroArch
team
/*
Copyright
(
C
)
2010
-
20
20
The
RetroArch
team
*
*
---------------------------------------------------------------------------------------
*
The
following
license
statement
only
applies
to
this
file
(
s16_to_float_neon
.
S
)
.
...
...
libretro-common/audio/conversion/s16_to_float_neon.c
View file @
bc0dae44
/* Copyright (C) 2010-20
17
The RetroArch team
/* Copyright (C) 2010-20
20
The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (s16_to_float_neon.S).
...
...
libretro-common/compat/compat_posix_string.c
View file @
bc0dae44
/* Copyright (C) 2010-20
17
The RetroArch team
/* Copyright (C) 2010-20
20
The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (compat_posix_string.c).
...
...
libretro-common/compat/compat_strcasestr.c
View file @
bc0dae44
/* Copyright (C) 2010-20
17
The RetroArch team
/* Copyright (C) 2010-20
20
The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (compat_strcasestr.c).
...
...
libretro-common/compat/compat_strl.c
View file @
bc0dae44
/* Copyright (C) 2010-20
17
The RetroArch team
/* Copyright (C) 2010-20
20
The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (compat_strl.c).
...
...
libretro-common/compat/fopen_utf8.c
View file @
bc0dae44
/* Copyright (C) 2010-2020 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (fopen_utf8.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 <compat/fopen_utf8.h>
#include <encodings/utf.h>
#include <stdio.h>
#include <stdlib.h>
#if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0500 || defined(_XBOX)
...
...
@@ -11,21 +34,29 @@
#ifdef _WIN32
#undef fopen
FILE
*
fopen_utf8
(
const
char
*
filename
,
const
char
*
mode
)
void
*
fopen_utf8
(
const
char
*
filename
,
const
char
*
mode
)
{
#if defined(_XBOX)
return
fopen
(
filename
,
mode
);
#elif defined(LEGACY_WIN32)
#if defined(LEGACY_WIN32)
FILE
*
ret
=
NULL
;
char
*
filename_local
=
utf8_to_local_string_alloc
(
filename
);
FILE
*
ret
=
fopen
(
filename_local
,
mode
);
free
(
filename_local
);
if
(
!
filename_local
)
return
NULL
;
ret
=
fopen
(
filename_local
,
mode
);
if
(
filename_local
)
free
(
filename_local
);
return
ret
;
#else
wchar_t
*
filename_w
=
utf8_to_utf16_string_alloc
(
filename
);
wchar_t
*
mode_w
=
utf8_to_utf16_string_alloc
(
mode
);
FILE
*
ret
=
_wfopen
(
filename_w
,
mode_w
);
free
(
filename_w
);
free
(
mode_w
);
FILE
*
ret
=
NULL
;
if
(
filename_w
&&
mode_w
)
ret
=
_wfopen
(
filename_w
,
mode_w
);