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
Citra2018
Commits
a0c222c0
Commit
a0c222c0
authored
Oct 01, 2018
by
James
Browse files
Update for latest upstream
parent
aea54fb1
Changes
13
Hide whitespace changes
Inline
Side-by-side
CMakeLists.txt
View file @
a0c222c0
...
...
@@ -24,7 +24,7 @@ option(ENABLE_CUBEB "Enables the cubeb audio backend" OFF)
option
(
USE_DISCORD_PRESENCE
"Enables Discord Rich Presence"
OFF
)
option
(
ENABLE_SCRIPTING
"Enables scripting support"
O
N
)
option
(
ENABLE_SCRIPTING
"Enables scripting support"
O
FF
)
option
(
DISABLE_CLANG_TARGET
"Disables the Clang format check"
ON
)
...
...
src/audio_core/dsp_interface.cpp
View file @
a0c222c0
...
...
@@ -42,6 +42,8 @@ void DspInterface::OutputFrame(StereoFrame16& frame) {
return
;
fifo
.
Push
(
frame
.
data
(),
frame
.
size
());
GetSink
().
OnAudioSubmission
(
frame
.
size
());
}
void
DspInterface
::
OutputCallback
(
s16
*
buffer
,
std
::
size_t
num_frames
)
{
...
...
src/audio_core/libretro_sink.cpp
View file @
a0c222c0
...
...
@@ -11,7 +11,11 @@
namespace
AudioCore
{
LibRetroSink
::
LibRetroSink
(
std
::
string
target_device_name
)
{}
struct
LibRetroSink
::
Impl
{
std
::
function
<
void
(
s16
*
,
std
::
size_t
)
>
cb
;
};
LibRetroSink
::
LibRetroSink
(
std
::
string
target_device_name
)
:
impl
(
std
::
make_unique
<
Impl
>
())
{}
LibRetroSink
::~
LibRetroSink
()
{}
...
...
@@ -19,12 +23,16 @@ unsigned int LibRetroSink::GetNativeSampleRate() const {
return
native_sample_rate
;
// We specify this.
}
void
LibRetroSink
::
EnqueueSamples
(
const
s16
*
samples
,
size_t
sample_count
)
{
LibRetro
::
SubmitAudio
(
samples
,
sample_count
)
;
void
LibRetroSink
::
SetCallback
(
std
::
function
<
void
(
s16
*
,
std
::
size_t
)
>
cb
)
{
this
->
impl
->
cb
=
cb
;
}
size_t
LibRetroSink
::
SamplesInQueue
()
const
{
return
0
;
void
LibRetroSink
::
OnAudioSubmission
(
std
::
size_t
frames
)
{
std
::
vector
<
s16
>
buffer
(
frames
*
2
);
this
->
impl
->
cb
(
buffer
.
data
(),
buffer
.
size
()
/
2
);
LibRetro
::
SubmitAudio
(
buffer
.
data
(),
buffer
.
size
()
/
2
);
}
std
::
vector
<
std
::
string
>
ListLibretroSinkDevices
()
{
...
...
src/audio_core/libretro_sink.h
View file @
a0c222c0
...
...
@@ -26,9 +26,14 @@ public:
unsigned
int
GetNativeSampleRate
()
const
override
;
void
EnqueueSamples
(
const
s16
*
samples
,
size_t
sample_count
)
override
;
void
SetCallback
(
std
::
function
<
void
(
s16
*
,
std
::
size_t
)
>
cb
)
override
;
size_t
SamplesInQueue
()
const
override
;
void
OnAudioSubmission
(
std
::
size_t
frames
)
override
;
struct
Impl
;
private:
std
::
unique_ptr
<
Impl
>
impl
;
};
void
audio_callback
();
...
...
src/audio_core/sink.h
View file @
a0c222c0
...
...
@@ -30,6 +30,9 @@ public:
* @param sample_count Number of samples.
*/
virtual
void
SetCallback
(
std
::
function
<
void
(
s16
*
,
std
::
size_t
)
>
cb
)
=
0
;
/// Optional callback to signify that a buffer has been written.
virtual
void
OnAudioSubmission
(
std
::
size_t
frames
)
{}
};
}
// namespace AudioCore
src/audio_core/sink_details.cpp
View file @
a0c222c0
...
...
@@ -24,16 +24,16 @@ namespace AudioCore {
// g_sink_details is ordered in terms of desirability, with the best choice at the top.
const
std
::
vector
<
SinkDetails
>
g_sink_details
=
{
#ifdef HAVE_LIBRETRO
SinkDetails
{
"libretro"
,
&
std
::
make_unique
<
LibRetroSink
,
std
::
string
>
,
&
ListLibretroSinkDevices
},
SinkDetails
{
"libretro"
,
&
std
::
make_unique
<
LibRetroSink
,
std
::
string
>
,
&
ListLibretroSinkDevices
,
true
},
#endif
#ifdef HAVE_CUBEB
SinkDetails
{
"cubeb"
,
&
std
::
make_unique
<
CubebSink
,
std
::
string
>
,
&
ListCubebSinkDevices
},
SinkDetails
{
"cubeb"
,
&
std
::
make_unique
<
CubebSink
,
std
::
string
>
,
&
ListCubebSinkDevices
,
false
},
#endif
#ifdef HAVE_SDL2
SinkDetails
{
"sdl2"
,
&
std
::
make_unique
<
SDL2Sink
,
std
::
string
>
,
&
ListSDL2SinkDevices
},
SinkDetails
{
"sdl2"
,
&
std
::
make_unique
<
SDL2Sink
,
std
::
string
>
,
&
ListSDL2SinkDevices
,
false
},
#endif
SinkDetails
{
"null"
,
&
std
::
make_unique
<
NullSink
,
std
::
string
>
,
[]
{
return
std
::
vector
<
std
::
string
>
{
"null"
};
}},
[]
{
return
std
::
vector
<
std
::
string
>
{
"null"
};
}
,
false
},
};
const
SinkDetails
&
GetSinkDetails
(
std
::
string_view
sink_id
)
{
...
...
src/audio_core/sink_details.h
View file @
a0c222c0
...
...
@@ -19,8 +19,8 @@ struct SinkDetails {
using
FactoryFn
=
std
::
function
<
std
::
unique_ptr
<
Sink
>
(
std
::
string
)
>
;
using
ListDevicesFn
=
std
::
function
<
std
::
vector
<
std
::
string
>
()
>
;
SinkDetails
(
const
char
*
id_
,
FactoryFn
factory_
,
ListDevicesFn
list_devices_
)
:
id
(
id_
),
factory
(
std
::
move
(
factory_
)),
list_devices
(
std
::
move
(
list_devices_
))
{}
SinkDetails
(
const
char
*
id_
,
FactoryFn
factory_
,
ListDevicesFn
list_devices_
,
bool
is_sync_
)
:
id
(
id_
),
factory
(
std
::
move
(
factory_
)),
list_devices
(
std
::
move
(
list_devices_
))
,
is_sync
(
is_sync_
)
{}
/// Name for this sink.
const
char
*
id
;
...
...
@@ -28,6 +28,8 @@ struct SinkDetails {
FactoryFn
factory
;
/// A method to call to list available devices.
ListDevicesFn
list_devices
;
/// If this sink should be handled synchronously.
bool
is_sync
;
};
extern
const
std
::
vector
<
SinkDetails
>
g_sink_details
;
...
...
src/citra_libretro/citra_libretro.cpp
View file @
a0c222c0
...
...
@@ -8,6 +8,7 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <common/file_util.h>
#include "glad/glad.h"
#include "libretro.h"
...
...
@@ -308,8 +309,8 @@ void UpdateSettings() {
if
(
!
FileUtil
::
CreateDir
(
target_dir
))
{
LOG_ERROR
(
Frontend
,
"Failed to create
\"
{}
\"
. Using Citra's default paths."
,
target_dir
);
}
else
{
FileUtil
::
GetUserPath
(
D_ROOT_IDX
,
target_dir
);
const
auto
&
target_dir_result
=
FileUtil
::
GetUserPath
(
D_USER_IDX
,
target_dir
);
FileUtil
::
GetUserPath
(
FileUtil
::
UserPath
::
RootDir
,
target_dir
);
const
auto
&
target_dir_result
=
FileUtil
::
GetUserPath
(
FileUtil
::
UserPath
::
UserDir
,
target_dir
);
LOG_INFO
(
Frontend
,
"User dir set to
\"
{}
\"
."
,
target_dir_result
);
}
}
...
...
@@ -346,9 +347,6 @@ void retro_run() {
case
Core
::
System
::
ResultStatus
::
ErrorSystemFiles
:
msg
=
"Citra was unable to locate a 3DS system archive: "
+
errorContent
;
break
;
case
Core
::
System
::
ResultStatus
::
ErrorSharedFont
:
msg
=
"Citra was unable to locate the 3DS shared fonts."
;
break
;
default:
msg
=
"Fatal Error encountered: "
+
errorContent
;
break
;
...
...
@@ -389,9 +387,8 @@ void context_reset() {
"Likely memory leak: context_destroy() was not called before context_reset()!"
);
}
VideoCore
::
g_renderer
=
std
::
make_unique
<
RendererOpenGL
>
();
VideoCore
::
g_renderer
->
SetWindow
(
emu_instance
->
emu_window
.
get
());
if
(
VideoCore
::
g_renderer
->
Init
())
{
VideoCore
::
g_renderer
=
std
::
make_unique
<
RendererOpenGL
>
(
*
emu_instance
->
emu_window
);
if
(
VideoCore
::
g_renderer
->
Init
()
!=
Core
::
System
::
ResultStatus
::
Success
)
{
LOG_DEBUG
(
Render
,
"initialized OK"
);
}
else
{
LOG_ERROR
(
Render
,
"initialization failed!"
);
...
...
@@ -412,7 +409,7 @@ void context_destroy() {
void
retro_reset
()
{
Core
::
System
::
GetInstance
().
Shutdown
();
Core
::
System
::
GetInstance
().
Load
(
emu_instance
->
emu_window
.
get
()
,
LibRetro
::
settings
.
file_path
);
Core
::
System
::
GetInstance
().
Load
(
*
emu_instance
->
emu_window
,
LibRetro
::
settings
.
file_path
);
context_reset
();
// Force the renderer to appear
}
...
...
@@ -449,7 +446,7 @@ bool retro_load_game(const struct retro_game_info* info) {
UpdateSettings
();
const
Core
::
System
::
ResultStatus
load_result
{
Core
::
System
::
GetInstance
().
Load
(
emu_instance
->
emu_window
.
get
()
,
LibRetro
::
settings
.
file_path
)};
*
emu_instance
->
emu_window
,
LibRetro
::
settings
.
file_path
)};
switch
(
load_result
)
{
case
Core
::
System
::
ResultStatus
::
ErrorGetLoader
:
...
...
src/citra_libretro/environment.cpp
View file @
a0c222c0
...
...
@@ -52,6 +52,10 @@ bool SetAudioCallback(retro_audio_callback* cb) {
return
environ_cb
(
RETRO_ENVIRONMENT_SET_AUDIO_CALLBACK
,
cb
);
}
bool
SetFrameTimeCallback
(
retro_frame_time_callback
*
cb
)
{
return
environ_cb
(
RETRO_ENVIRONMENT_SET_FRAME_TIME_CALLBACK
,
cb
);
}
bool
SetGeometry
(
retro_system_av_info
*
cb
)
{
return
environ_cb
(
RETRO_ENVIRONMENT_SET_GEOMETRY
,
cb
);
}
...
...
src/citra_libretro/environment.h
View file @
a0c222c0
...
...
@@ -51,6 +51,9 @@ bool SetHWRenderer(retro_hw_render_callback* cb);
/// Sets the async audio callback.
bool
SetAudioCallback
(
retro_audio_callback
*
cb
);
/// Sets the frame time callback.
bool
SetFrameTimeCallback
(
retro_frame_time_callback
*
cb
);
/// Set the size of the new screen buffer.
bool
SetGeometry
(
retro_system_av_info
*
cb
);
...
...
src/common/logging/backend.cpp
View file @
a0c222c0
...
...
@@ -29,6 +29,38 @@ namespace Log {
*/
class
Impl
{
public:
Impl
()
{
backend_thread
=
std
::
thread
([
&
]
{
Entry
entry
;
auto
write_logs
=
[
&
](
Entry
&
e
)
{
std
::
lock_guard
<
std
::
mutex
>
lock
(
writing_mutex
);
for
(
const
auto
&
backend
:
backends
)
{
backend
->
Write
(
e
);
}
};
while
(
true
)
{
std
::
unique_lock
<
std
::
mutex
>
lock
(
message_mutex
);
message_cv
.
wait
(
lock
,
[
&
]
{
return
!
running
||
message_queue
.
Pop
(
entry
);
});
if
(
!
running
)
{
break
;
}
write_logs
(
entry
);
}
// Drain the logging queue. Only writes out up to MAX_LOGS_TO_WRITE to prevent a case
// where a system is repeatedly spamming logs even on close.
constexpr
int
MAX_LOGS_TO_WRITE
=
100
;
int
logs_written
=
0
;
while
(
logs_written
++
<
MAX_LOGS_TO_WRITE
&&
message_queue
.
Pop
(
entry
))
{
write_logs
(
entry
);
}
});
}
~
Impl
()
{
running
=
false
;
message_cv
.
notify_one
();
backend_thread
.
join
();
}
Impl
(
Impl
const
&
)
=
delete
;
const
Impl
&
operator
=
(
Impl
const
&
)
=
delete
;
...
...
@@ -70,39 +102,6 @@ public:
}
private:
Impl
()
{
backend_thread
=
std
::
thread
([
&
]
{
Entry
entry
;
auto
write_logs
=
[
&
](
Entry
&
e
)
{
std
::
lock_guard
<
std
::
mutex
>
lock
(
writing_mutex
);
for
(
const
auto
&
backend
:
backends
)
{
backend
->
Write
(
e
);
}
};
while
(
true
)
{
std
::
unique_lock
<
std
::
mutex
>
lock
(
message_mutex
);
message_cv
.
wait
(
lock
,
[
&
]
{
return
!
running
||
message_queue
.
Pop
(
entry
);
});
if
(
!
running
)
{
break
;
}
write_logs
(
entry
);
}
// Drain the logging queue. Only writes out up to MAX_LOGS_TO_WRITE to prevent a case
// where a system is repeatedly spamming logs even on close.
constexpr
int
MAX_LOGS_TO_WRITE
=
100
;
int
logs_written
=
0
;
while
(
logs_written
++
<
MAX_LOGS_TO_WRITE
&&
message_queue
.
Pop
(
entry
))
{
write_logs
(
entry
);
}
});
}
~
Impl
()
{
running
=
false
;
message_cv
.
notify_one
();
backend_thread
.
join
();
}
std
::
atomic_bool
running
{
true
};
std
::
mutex
message_mutex
,
writing_mutex
;
std
::
condition_variable
message_cv
;
...
...
src/video_core/renderer_opengl/renderer_opengl.cpp
View file @
a0c222c0
...
...
@@ -103,7 +103,7 @@ void RendererOpenGL::SwapBuffers() {
OpenGLState
prev_state
=
OpenGLState
::
GetCurState
();
state
.
Apply
();
render_window
->
SetupFramebuffer
();
render_window
.
SetupFramebuffer
();
for
(
int
i
:
{
0
,
1
,
2
})
{
int
fb_id
=
i
==
2
?
1
:
0
;
...
...
@@ -398,7 +398,7 @@ void RendererOpenGL::DrawScreens() {
glViewport
(
0
,
0
,
layout
.
width
,
layout
.
height
);
if
(
render_window
->
NeedsClearing
())
{
if
(
render_window
.
NeedsClearing
())
{
glClear
(
GL_COLOR_BUFFER_BIT
);
}
...
...
src/video_core/video_core.cpp
View file @
a0c222c0
...
...
@@ -4,6 +4,7 @@
#include <memory>
#include "common/logging/log.h"
#include "core/frontend/emu_window.h"
#include "video_core/pica.h"
#include "video_core/renderer_base.h"
#include "video_core/renderer_opengl/renderer_opengl.h"
...
...
@@ -27,16 +28,21 @@ std::atomic<bool> g_renderer_bg_color_update_requested;
Core
::
System
::
ResultStatus
Init
(
EmuWindow
&
emu_window
)
{
Pica
::
Init
();
g_renderer
=
std
::
make_unique
<
RendererOpenGL
>
(
emu_window
);
Core
::
System
::
ResultStatus
result
=
g_renderer
->
Init
();
if
(
!
emu_window
.
ShouldDeferRendererInit
())
{
g_renderer
=
std
::
make_unique
<
RendererOpenGL
>
(
emu_window
);
Core
::
System
::
ResultStatus
result
=
g_renderer
->
Init
();
if
(
result
!=
Core
::
System
::
ResultStatus
::
Success
)
{
LOG_ERROR
(
Render
,
"initialization failed !"
);
if
(
result
!=
Core
::
System
::
ResultStatus
::
Success
)
{
LOG_ERROR
(
Render
,
"initialization failed !"
);
}
else
{
LOG_DEBUG
(
Render
,
"initialized OK"
);
}
return
result
;
}
else
{
LOG_DEBUG
(
Render
,
"initialized OK"
);
// We will come back to it later
return
Core
::
System
::
ResultStatus
::
Success
;
}
return
result
;
}
/// Shutdown the video core
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment