Merge branch 'master' of https://github.com/bunnei/citra
This commit is contained in:
commit
1de7e8cbe4
|
@ -2,21 +2,37 @@ cmake_minimum_required(VERSION 2.6)
|
||||||
|
|
||||||
project(citra)
|
project(citra)
|
||||||
|
|
||||||
SET(GCC_COMPILE_FLAGS "-std=c++11 -fpermissive")
|
SET(CXX_COMPILE_FLAGS "-std=c++11 -fpermissive")
|
||||||
|
|
||||||
# silence some spam
|
# silence some spam
|
||||||
add_definitions(-Wno-attributes)
|
add_definitions(-Wno-attributes)
|
||||||
add_definitions(-DSINGLETHREADED)
|
add_definitions(-DSINGLETHREADED)
|
||||||
add_definitions(${GCC_COMPILE_FLAGS})
|
add_definitions(${CXX_COMPILE_FLAGS})
|
||||||
|
|
||||||
# dependency checking
|
# dependency checking
|
||||||
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/externals/cmake-modules/")
|
||||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/CMakeTests)
|
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/CMakeTests)
|
||||||
include(FindOpenGL REQUIRED)
|
|
||||||
include(FindX11 REQUIRED)
|
include(FindX11 REQUIRED)
|
||||||
find_package(PkgConfig REQUIRED)
|
find_package(PkgConfig REQUIRED)
|
||||||
|
find_package(GLEW REQUIRED)
|
||||||
|
find_package(OpenGL REQUIRED)
|
||||||
pkg_search_module(GLFW REQUIRED glfw3)
|
pkg_search_module(GLFW REQUIRED glfw3)
|
||||||
|
|
||||||
|
# corefoundation is required only on OSX
|
||||||
|
IF (APPLE)
|
||||||
|
FIND_LIBRARY(COREFOUNDATION_LIBRARY CoreFoundation)
|
||||||
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
|
||||||
|
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++")
|
||||||
|
ENDIF (APPLE)
|
||||||
|
|
||||||
|
#external includes
|
||||||
include_directories(${GLFW_INCLUDE_DIRS})
|
include_directories(${GLFW_INCLUDE_DIRS})
|
||||||
|
include_directories(${OPENGL_INCLUDE_DIR})
|
||||||
|
include_directories(${GLEW_INCLUDE_PATH})
|
||||||
|
|
||||||
|
# workaround for GLFW linking on OSX
|
||||||
|
link_directories(${GLFW_LIBRARY_DIRS})
|
||||||
|
|
||||||
option(DISABLE_QT4 "Disable Qt4 GUI" OFF)
|
option(DISABLE_QT4 "Disable Qt4 GUI" OFF)
|
||||||
if(NOT DISABLE_QT4)
|
if(NOT DISABLE_QT4)
|
||||||
include(FindQt4)
|
include(FindQt4)
|
||||||
|
@ -32,15 +48,11 @@ if(NOT DISABLE_QT4)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# generate git revision information
|
# generate git revision information
|
||||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/externals/cmake-modules/")
|
|
||||||
include(GetGitRevisionDescription)
|
include(GetGitRevisionDescription)
|
||||||
get_git_head_revision(GIT_REF_SPEC GIT_REV)
|
get_git_head_revision(GIT_REF_SPEC GIT_REV)
|
||||||
git_describe(GIT_DESC --always --long --dirty)
|
git_describe(GIT_DESC --always --long --dirty)
|
||||||
git_branch_name(GIT_BRANCH)
|
git_branch_name(GIT_BRANCH)
|
||||||
|
|
||||||
# external includes
|
|
||||||
include_directories(${OPENGL_INCLUDE_DIR})
|
|
||||||
|
|
||||||
# internal includes
|
# internal includes
|
||||||
include_directories(src)
|
include_directories(src)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
citra emulator
|
citra emulator
|
||||||
==============
|
==============
|
||||||
[![Travis CI Build Status](https://travis-ci.org/bunnei/citra.svg)](https://travis-ci.org/bunnei/citra)
|
[![Travis CI Build Status](https://travis-ci.org/citra-emu/citra.svg)](https://travis-ci.org/citra-emu/citra)
|
||||||
|
|
||||||
An experimental open-source Nintendo 3DS emulator/debugger written in C++. At this time, it only emulates a very small subset of 3DS hardware, and therefore is only useful for booting/debugging very simple homebrew demos. Citra is licensed under the GPLv2. Refer to the license.txt file included. Please read the [FAQ](https://github.com/bunnei/citra/wiki/FAQ) before getting started with the project.
|
An experimental open-source Nintendo 3DS emulator/debugger written in C++. At this time, it only emulates a very small subset of 3DS hardware, and therefore is only useful for booting/debugging very simple homebrew demos. Citra is licensed under the GPLv2. Refer to the license.txt file included. Please read the [FAQ](https://github.com/bunnei/citra/wiki/FAQ) before getting started with the project.
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
#
|
||||||
|
# Try to find GLEW library and include path.
|
||||||
|
# Once done this will define
|
||||||
|
#
|
||||||
|
# GLEW_FOUND
|
||||||
|
# GLEW_INCLUDE_PATH
|
||||||
|
# GLEW_LIBRARY
|
||||||
|
#
|
||||||
|
|
||||||
|
IF (WIN32)
|
||||||
|
FIND_PATH( GLEW_INCLUDE_PATH GL/glew.h
|
||||||
|
$ENV{PROGRAMFILES}/GLEW/include
|
||||||
|
${PROJECT_SOURCE_DIR}/src/nvgl/glew/include
|
||||||
|
DOC "The directory where GL/glew.h resides")
|
||||||
|
FIND_LIBRARY( GLEW_LIBRARY
|
||||||
|
NAMES glew GLEW glew32 glew32s
|
||||||
|
PATHS
|
||||||
|
$ENV{PROGRAMFILES}/GLEW/lib
|
||||||
|
${PROJECT_SOURCE_DIR}/src/nvgl/glew/bin
|
||||||
|
${PROJECT_SOURCE_DIR}/src/nvgl/glew/lib
|
||||||
|
DOC "The GLEW library")
|
||||||
|
ELSE (WIN32)
|
||||||
|
FIND_PATH( GLEW_INCLUDE_PATH GL/glew.h
|
||||||
|
/usr/include
|
||||||
|
/usr/local/include
|
||||||
|
/sw/include
|
||||||
|
/opt/local/include
|
||||||
|
DOC "The directory where GL/glew.h resides")
|
||||||
|
FIND_LIBRARY( GLEW_LIBRARY
|
||||||
|
NAMES GLEW glew
|
||||||
|
PATHS
|
||||||
|
/usr/lib64
|
||||||
|
/usr/lib
|
||||||
|
/usr/local/lib64
|
||||||
|
/usr/local/lib
|
||||||
|
/sw/lib
|
||||||
|
/opt/local/lib
|
||||||
|
DOC "The GLEW library")
|
||||||
|
ENDIF (WIN32)
|
||||||
|
|
||||||
|
IF (GLEW_INCLUDE_PATH)
|
||||||
|
SET( GLEW_FOUND 1 CACHE STRING "Set to 1 if GLEW is found, 0 otherwise")
|
||||||
|
ELSE (GLEW_INCLUDE_PATH)
|
||||||
|
SET( GLEW_FOUND 0 CACHE STRING "Set to 1 if GLEW is found, 0 otherwise")
|
||||||
|
ENDIF (GLEW_INCLUDE_PATH)
|
||||||
|
|
||||||
|
MARK_AS_ADVANCED( GLEW_FOUND )
|
|
@ -1,12 +1,19 @@
|
||||||
set(SRCS citra.cpp
|
set(SRCS citra.cpp
|
||||||
emu_window/emu_window_glfw.cpp)
|
emu_window/emu_window_glfw.cpp)
|
||||||
|
set(HEADERS citra.h
|
||||||
|
resource.h)
|
||||||
|
|
||||||
# NOTE: This is a workaround for CMake bug 0006976 (missing X11_xf86vmode_LIB variable)
|
# NOTE: This is a workaround for CMake bug 0006976 (missing X11_xf86vmode_LIB variable)
|
||||||
if (NOT X11_xf86vmode_LIB)
|
if (NOT X11_xf86vmode_LIB)
|
||||||
set(X11_xv86vmode_LIB Xxf86vm)
|
set(X11_xv86vmode_LIB Xxf86vm)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_executable(citra ${SRCS})
|
add_executable(citra ${SRCS} ${HEADERS})
|
||||||
target_link_libraries(citra core common video_core GLEW pthread X11 Xxf86vm Xi Xcursor ${OPENGL_LIBRARIES} ${GLFW_LIBRARIES} rt ${X11_Xrandr_LIB} ${X11_xv86vmode_LIB})
|
|
||||||
|
if (APPLE)
|
||||||
|
target_link_libraries(citra core common video_core iconv pthread ${COREFOUNDATION_LIBRARY} ${OPENGL_LIBRARIES} ${GLEW_LIBRARY} ${GLFW_LIBRARIES})
|
||||||
|
else()
|
||||||
|
target_link_libraries(citra core common video_core GLEW pthread X11 Xxf86vm Xi Xcursor ${OPENGL_LIBRARIES} ${GLFW_LIBRARIES} rt ${X11_Xrandr_LIB} ${X11_xv86vmode_LIB})
|
||||||
|
endif()
|
||||||
|
|
||||||
#install(TARGETS citra RUNTIME DESTINATION ${bindir})
|
#install(TARGETS citra RUNTIME DESTINATION ${bindir})
|
||||||
|
|
|
@ -27,11 +27,18 @@ EmuWindow_GLFW::EmuWindow_GLFW() {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
|
||||||
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
||||||
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
m_render_window = glfwCreateWindow(VideoCore::kScreenTopWidth,
|
m_render_window = glfwCreateWindow(VideoCore::kScreenTopWidth,
|
||||||
(VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight),
|
(VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight),
|
||||||
m_window_title.c_str(), NULL, NULL);
|
m_window_title.c_str(), NULL, NULL);
|
||||||
|
|
||||||
|
if (m_render_window == NULL) {
|
||||||
|
printf("Failed to create GLFW window! Exiting...");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
// Setup callbacks
|
// Setup callbacks
|
||||||
glfwSetWindowUserPointer(m_render_window, this);
|
glfwSetWindowUserPointer(m_render_window, this);
|
||||||
//glfwSetKeyCallback(m_render_window, OnKeyEvent);
|
//glfwSetKeyCallback(m_render_window, OnKeyEvent);
|
||||||
|
|
|
@ -8,6 +8,23 @@ set(SRCS
|
||||||
main.cpp
|
main.cpp
|
||||||
config/controller_config.cpp
|
config/controller_config.cpp
|
||||||
config/controller_config_util.cpp)
|
config/controller_config_util.cpp)
|
||||||
|
set (HEADERS
|
||||||
|
bootmanager.hxx
|
||||||
|
debugger/callstack.hxx
|
||||||
|
debugger/disassembler.hxx
|
||||||
|
debugger/ramview.hxx
|
||||||
|
debugger/registers.hxx
|
||||||
|
hotkeys.hxx
|
||||||
|
main.hxx
|
||||||
|
ui_callstack.h
|
||||||
|
ui_controller_config.h
|
||||||
|
ui_disassembler.h
|
||||||
|
ui_hotkeys.h
|
||||||
|
ui_main.h
|
||||||
|
ui_registers.h
|
||||||
|
version.h
|
||||||
|
config/controller_config.hxx
|
||||||
|
config/controller_config_util.hxx)
|
||||||
|
|
||||||
qt4_wrap_ui(UI_HDRS
|
qt4_wrap_ui(UI_HDRS
|
||||||
debugger/callstack.ui
|
debugger/callstack.ui
|
||||||
|
@ -32,7 +49,11 @@ qt4_wrap_cpp(MOC_SRCS
|
||||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||||
include_directories(./)
|
include_directories(./)
|
||||||
|
|
||||||
add_executable(citra-qt ${SRCS} ${MOC_SRCS} ${UI_HDRS})
|
add_executable(citra-qt ${SRCS} ${HEADERS} ${MOC_SRCS} ${UI_HDRS})
|
||||||
target_link_libraries(citra-qt core common video_core qhexedit ${QT_LIBRARIES} ${OPENGL_LIBRARIES} ${SDL2_LIBRARY} rt GLEW ${GLFW_LIBRARIES})
|
if (APPLE)
|
||||||
|
target_link_libraries(citra-qt core common video_core qhexedit iconv ${COREFOUNDATION_LIBRARY} ${QT_LIBRARIES} ${GLEW_LIBRARY} ${OPENGL_LIBRARIES})
|
||||||
|
else()
|
||||||
|
target_link_libraries(citra-qt core common video_core qhexedit ${QT_LIBRARIES} ${OPENGL_LIBRARIES} ${SDL2_LIBRARY} rt GLEW ${GLFW_LIBRARIES})
|
||||||
|
endif()
|
||||||
|
|
||||||
#install(TARGETS citra-qt RUNTIME DESTINATION ${bindir})
|
#install(TARGETS citra-qt RUNTIME DESTINATION ${bindir})
|
||||||
|
|
|
@ -50,7 +50,7 @@ void EmuThread::run()
|
||||||
|
|
||||||
void EmuThread::Stop()
|
void EmuThread::Stop()
|
||||||
{
|
{
|
||||||
if (!isRunning())
|
if (!isRunning())
|
||||||
{
|
{
|
||||||
INFO_LOG(MASTER_LOG, "EmuThread::Stop called while emu thread wasn't running, returning...");
|
INFO_LOG(MASTER_LOG, "EmuThread::Stop called while emu thread wasn't running, returning...");
|
||||||
return;
|
return;
|
||||||
|
@ -65,7 +65,7 @@ void EmuThread::Stop()
|
||||||
terminate();
|
terminate();
|
||||||
wait(1000);
|
wait(1000);
|
||||||
if (isRunning())
|
if (isRunning())
|
||||||
WARN_LOG(MASTER_LOG, "EmuThread STILL running, something is wrong here...");
|
WARN_LOG(MASTER_LOG, "EmuThread STILL running, something is wrong here...");
|
||||||
}
|
}
|
||||||
INFO_LOG(MASTER_LOG, "EmuThread stopped");
|
INFO_LOG(MASTER_LOG, "EmuThread stopped");
|
||||||
}
|
}
|
||||||
|
@ -76,9 +76,8 @@ void EmuThread::Stop()
|
||||||
class GGLWidgetInternal : public QGLWidget
|
class GGLWidgetInternal : public QGLWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GGLWidgetInternal(GRenderWindow* parent) : QGLWidget(parent)
|
GGLWidgetInternal(QGLFormat fmt, GRenderWindow* parent) : QGLWidget(parent)
|
||||||
{
|
{
|
||||||
setAutoBufferSwap(false);
|
|
||||||
doneCurrent();
|
doneCurrent();
|
||||||
parent_ = parent;
|
parent_ = parent;
|
||||||
}
|
}
|
||||||
|
@ -106,8 +105,13 @@ EmuThread& GRenderWindow::GetEmuThread()
|
||||||
GRenderWindow::GRenderWindow(QWidget* parent) : QWidget(parent), emu_thread(this)
|
GRenderWindow::GRenderWindow(QWidget* parent) : QWidget(parent), emu_thread(this)
|
||||||
{
|
{
|
||||||
// TODO: One of these flags might be interesting: WA_OpaquePaintEvent, WA_NoBackground, WA_DontShowOnScreen, WA_DeleteOnClose
|
// TODO: One of these flags might be interesting: WA_OpaquePaintEvent, WA_NoBackground, WA_DontShowOnScreen, WA_DeleteOnClose
|
||||||
|
QGLFormat fmt;
|
||||||
|
fmt.setProfile(QGLFormat::CoreProfile);
|
||||||
|
fmt.setVersion(3,2);
|
||||||
|
fmt.setSampleBuffers(true);
|
||||||
|
fmt.setSamples(4);
|
||||||
|
|
||||||
child = new GGLWidgetInternal(this);
|
child = new GGLWidgetInternal(fmt, this);
|
||||||
QBoxLayout* layout = new QHBoxLayout(this);
|
QBoxLayout* layout = new QHBoxLayout(this);
|
||||||
resize(VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight);
|
resize(VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight);
|
||||||
layout->addWidget(child);
|
layout->addWidget(child);
|
||||||
|
@ -147,12 +151,12 @@ void GRenderWindow::DoneCurrent()
|
||||||
void GRenderWindow::PollEvents() {
|
void GRenderWindow::PollEvents() {
|
||||||
// TODO(ShizZy): Does this belong here? This is a reasonable place to update the window title
|
// TODO(ShizZy): Does this belong here? This is a reasonable place to update the window title
|
||||||
// from the main thread, but this should probably be in an event handler...
|
// from the main thread, but this should probably be in an event handler...
|
||||||
/*
|
/*
|
||||||
static char title[128];
|
static char title[128];
|
||||||
sprintf(title, "%s (FPS: %02.02f)", window_title_.c_str(),
|
sprintf(title, "%s (FPS: %02.02f)", window_title_.c_str(),
|
||||||
video_core::g_renderer->current_fps());
|
video_core::g_renderer->current_fps());
|
||||||
setWindowTitle(title);
|
setWindowTitle(title);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void GRenderWindow::BackupGeometry()
|
void GRenderWindow::BackupGeometry()
|
||||||
|
@ -185,26 +189,26 @@ QByteArray GRenderWindow::saveGeometry()
|
||||||
|
|
||||||
void GRenderWindow::keyPressEvent(QKeyEvent* event)
|
void GRenderWindow::keyPressEvent(QKeyEvent* event)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
bool key_processed = false;
|
bool key_processed = false;
|
||||||
for (unsigned int channel = 0; channel < 4 && controller_interface(); ++channel)
|
for (unsigned int channel = 0; channel < 4 && controller_interface(); ++channel)
|
||||||
if (controller_interface()->SetControllerStatus(channel, event->key(), input_common::GCController::PRESSED))
|
if (controller_interface()->SetControllerStatus(channel, event->key(), input_common::GCController::PRESSED))
|
||||||
key_processed = true;
|
key_processed = true;
|
||||||
|
|
||||||
if (!key_processed)
|
if (!key_processed)
|
||||||
QWidget::keyPressEvent(event);
|
QWidget::keyPressEvent(event);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void GRenderWindow::keyReleaseEvent(QKeyEvent* event)
|
void GRenderWindow::keyReleaseEvent(QKeyEvent* event)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
bool key_processed = false;
|
bool key_processed = false;
|
||||||
for (unsigned int channel = 0; channel < 4 && controller_interface(); ++channel)
|
for (unsigned int channel = 0; channel < 4 && controller_interface(); ++channel)
|
||||||
if (controller_interface()->SetControllerStatus(channel, event->key(), input_common::GCController::RELEASED))
|
if (controller_interface()->SetControllerStatus(channel, event->key(), input_common::GCController::RELEASED))
|
||||||
key_processed = true;
|
key_processed = true;
|
||||||
|
|
||||||
if (!key_processed)
|
if (!key_processed)
|
||||||
QWidget::keyPressEvent(event);
|
QWidget::keyPressEvent(event);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
|
@ -19,4 +19,43 @@ set(SRCS break_points.cpp
|
||||||
timer.cpp
|
timer.cpp
|
||||||
utf8.cpp)
|
utf8.cpp)
|
||||||
|
|
||||||
add_library(common STATIC ${SRCS})
|
set(HEADERS atomic.h
|
||||||
|
atomic_gcc.h
|
||||||
|
atomic_win32.h
|
||||||
|
bit_field.h
|
||||||
|
break_points.h
|
||||||
|
chunk_file.h
|
||||||
|
common_funcs.h
|
||||||
|
common_paths.h
|
||||||
|
common_types.h
|
||||||
|
common.h
|
||||||
|
console_listener.h
|
||||||
|
cpu_detect.h
|
||||||
|
debug_interface.h
|
||||||
|
emu_window.h
|
||||||
|
extended_trace.h
|
||||||
|
fifo_queue.h
|
||||||
|
file_search.h
|
||||||
|
file_util.h
|
||||||
|
hash.h
|
||||||
|
linear_disk_cache.h
|
||||||
|
log_manager.h
|
||||||
|
log.h
|
||||||
|
math_util.h
|
||||||
|
mem_arena.h
|
||||||
|
memory_util.h
|
||||||
|
msg_handler.h
|
||||||
|
platform.h
|
||||||
|
scm_rev.h
|
||||||
|
std_condition_variable.h
|
||||||
|
std_mutex.h
|
||||||
|
std_thread.h
|
||||||
|
string_util.h
|
||||||
|
swap.h
|
||||||
|
symbols.h
|
||||||
|
thread.h
|
||||||
|
thunk.h
|
||||||
|
timer.h
|
||||||
|
utf8.h)
|
||||||
|
|
||||||
|
add_library(common STATIC ${SRCS} ${HEADERS})
|
||||||
|
|
|
@ -654,7 +654,8 @@ inline PointerWrapSection::~PointerWrapSection() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class CChunkFileReader
|
// Commented out because it is currently unused, and breaks builds on OSX
|
||||||
|
/*class CChunkFileReader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum Error {
|
enum Error {
|
||||||
|
@ -869,6 +870,6 @@ private:
|
||||||
int UncompressedSize;
|
int UncompressedSize;
|
||||||
char GitVersion[32];
|
char GitVersion[32];
|
||||||
};
|
};
|
||||||
};
|
}; */
|
||||||
|
|
||||||
#endif // _POINTERWRAP_H_
|
#endif // _POINTERWRAP_H_
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
#define STACKALIGN
|
#define STACKALIGN
|
||||||
|
|
||||||
#if __cplusplus >= 201103 || defined(_MSC_VER) || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
#if __cplusplus >= 201103L || defined(_MSC_VER) || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||||
#define HAVE_CXX11_SYNTAX 1
|
#define HAVE_CXX11_SYNTAX 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -159,4 +159,48 @@ enum EMUSTATE_CHANGE
|
||||||
EMUSTATE_CHANGE_STOP
|
EMUSTATE_CHANGE_STOP
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#ifndef _XBOX
|
||||||
|
inline unsigned long long bswap64(unsigned long long x) { return _byteswap_uint64(x); }
|
||||||
|
inline unsigned int bswap32(unsigned int x) { return _byteswap_ulong(x); }
|
||||||
|
inline unsigned short bswap16(unsigned short x) { return _byteswap_ushort(x); }
|
||||||
|
#else
|
||||||
|
inline unsigned long long bswap64(unsigned long long x) { return __loaddoublewordbytereverse(0, &x); }
|
||||||
|
inline unsigned int bswap32(unsigned int x) { return __loadwordbytereverse(0, &x); }
|
||||||
|
inline unsigned short bswap16(unsigned short x) { return __loadshortbytereverse(0, &x); }
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
// TODO: speedup
|
||||||
|
inline unsigned short bswap16(unsigned short x) { return (x << 8) | (x >> 8); }
|
||||||
|
inline unsigned int bswap32(unsigned int x) { return (x >> 24) | ((x & 0xFF0000) >> 8) | ((x & 0xFF00) << 8) | (x << 24);}
|
||||||
|
inline unsigned long long bswap64(unsigned long long x) {return ((unsigned long long)bswap32(x) << 32) | bswap32(x >> 32); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inline float bswapf(float f) {
|
||||||
|
union {
|
||||||
|
float f;
|
||||||
|
unsigned int u32;
|
||||||
|
} dat1, dat2;
|
||||||
|
|
||||||
|
dat1.f = f;
|
||||||
|
dat2.u32 = bswap32(dat1.u32);
|
||||||
|
|
||||||
|
return dat2.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double bswapd(double f) {
|
||||||
|
union {
|
||||||
|
double f;
|
||||||
|
unsigned long long u64;
|
||||||
|
} dat1, dat2;
|
||||||
|
|
||||||
|
dat1.f = f;
|
||||||
|
dat2.u64 = bswap64(dat1.u64);
|
||||||
|
|
||||||
|
return dat2.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "swap.h"
|
||||||
|
|
||||||
#endif // _COMMON_H_
|
#endif // _COMMON_H_
|
||||||
|
|
|
@ -62,7 +62,7 @@ typedef signed long long s64; ///< 64-bit signed int
|
||||||
typedef float f32; ///< 32-bit floating point
|
typedef float f32; ///< 32-bit floating point
|
||||||
typedef double f64; ///< 64-bit floating point
|
typedef double f64; ///< 64-bit floating point
|
||||||
|
|
||||||
#include "common/swap.h"
|
#include "common/common.h"
|
||||||
|
|
||||||
/// Union for fast 16-bit type casting
|
/// Union for fast 16-bit type casting
|
||||||
union t16 {
|
union t16 {
|
||||||
|
@ -100,6 +100,7 @@ union t128 {
|
||||||
__m128 a; ///< 128-bit floating point (__m128 maps to the XMM[0-7] registers)
|
__m128 a; ///< 128-bit floating point (__m128 maps to the XMM[0-7] registers)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace common {
|
||||||
/// Rectangle data structure
|
/// Rectangle data structure
|
||||||
class Rect {
|
class Rect {
|
||||||
public:
|
public:
|
||||||
|
@ -123,3 +124,4 @@ public:
|
||||||
return (x0_ == val.x0_ && y0_ == val.y0_ && x1_ == val.x1_ && y1_ == val.y1_);
|
return (x0_ == val.x0_ && y0_ == val.y0_ && x1_ == val.x1_ && y1_ == val.y1_);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -43,4 +43,47 @@ set(SRCS core.cpp
|
||||||
hw/lcd.cpp
|
hw/lcd.cpp
|
||||||
hw/ndma.cpp)
|
hw/ndma.cpp)
|
||||||
|
|
||||||
add_library(core STATIC ${SRCS})
|
set(HEADERS core.h
|
||||||
|
core_timing.h
|
||||||
|
loader.h
|
||||||
|
mem_map.h
|
||||||
|
system.h
|
||||||
|
arm/disassembler/arm_disasm.h
|
||||||
|
arm/disassembler/load_symbol_map.h
|
||||||
|
arm/interpreter/arm_interpreter.h
|
||||||
|
arm/interpreter/arm_regformat.h
|
||||||
|
arm/interpreter/armcpu.h
|
||||||
|
arm/interpreter/armdefs.h
|
||||||
|
arm/interpreter/armemu.h
|
||||||
|
arm/interpreter/armmmu.h
|
||||||
|
arm/interpreter/armos.h
|
||||||
|
arm/interpreter/skyeye_defs.h
|
||||||
|
arm/interpreter/mmu/arm1176jzf_s_mmu.h
|
||||||
|
arm/interpreter/mmu/cache.h
|
||||||
|
arm/interpreter/mmu/rb.h
|
||||||
|
arm/interpreter/mmu/sa_mmu.h
|
||||||
|
arm/interpreter/mmu/tlb.h
|
||||||
|
arm/interpreter/mmu/wb.h
|
||||||
|
arm/interpreter/vfp/asm_vfp.h
|
||||||
|
arm/interpreter/vfp/vfp.h
|
||||||
|
arm/interpreter/vfp/vfp_helper.h
|
||||||
|
elf/elf_reader.h
|
||||||
|
elf/elf_types.h
|
||||||
|
file_sys/directory_file_system.h
|
||||||
|
file_sys/file_sys.h
|
||||||
|
file_sys/meta_file_system.h
|
||||||
|
hle/config_mem.h
|
||||||
|
hle/coprocessor.h
|
||||||
|
hle/hle.h
|
||||||
|
hle/syscall.h
|
||||||
|
hle/function_wrappers.h
|
||||||
|
hle/service/apt.h
|
||||||
|
hle/service/gsp.h
|
||||||
|
hle/service/hid.h
|
||||||
|
hle/service/service.h
|
||||||
|
hle/service/srv.h
|
||||||
|
hw/hw.h
|
||||||
|
hw/lcd.h
|
||||||
|
hw/ndma.h)
|
||||||
|
|
||||||
|
add_library(core STATIC ${SRCS} ${HEADERS})
|
||||||
|
|
|
@ -86,12 +86,12 @@ static union
|
||||||
} reg_conv;
|
} reg_conv;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
printf_nothing (void *foo, ...)
|
printf_nothing (const char *foo, ...)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cirrus_not_implemented (char *insn)
|
cirrus_not_implemented (const char *insn)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "Cirrus instruction '%s' not implemented.\n", insn);
|
fprintf (stderr, "Cirrus instruction '%s' not implemented.\n", insn);
|
||||||
fprintf (stderr, "aborting!\n");
|
fprintf (stderr, "aborting!\n");
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
#define pr_info //printf
|
#define pr_info //printf
|
||||||
#define pr_debug //printf
|
#define pr_debug //printf
|
||||||
|
|
||||||
static u32 fls(int x);
|
static u32 vfp_fls(int x);
|
||||||
#define do_div(n, base) {n/=base;}
|
#define do_div(n, base) {n/=base;}
|
||||||
|
|
||||||
/* From vfpinstr.h */
|
/* From vfpinstr.h */
|
||||||
|
@ -508,7 +508,7 @@ struct op {
|
||||||
u32 flags;
|
u32 flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline u32 fls(int x)
|
static u32 vfp_fls(int x)
|
||||||
{
|
{
|
||||||
int r = 32;
|
int r = 32;
|
||||||
|
|
||||||
|
|
|
@ -69,9 +69,9 @@ static void vfp_double_dump(const char *str, struct vfp_double *d)
|
||||||
|
|
||||||
static void vfp_double_normalise_denormal(struct vfp_double *vd)
|
static void vfp_double_normalise_denormal(struct vfp_double *vd)
|
||||||
{
|
{
|
||||||
int bits = 31 - fls(vd->significand >> 32);
|
int bits = 31 - vfp_fls(vd->significand >> 32);
|
||||||
if (bits == 31)
|
if (bits == 31)
|
||||||
bits = 63 - fls(vd->significand);
|
bits = 63 - vfp_fls(vd->significand);
|
||||||
|
|
||||||
vfp_double_dump("normalise_denormal: in", vd);
|
vfp_double_dump("normalise_denormal: in", vd);
|
||||||
|
|
||||||
|
@ -108,9 +108,9 @@ u32 vfp_double_normaliseround(ARMul_State* state, int dd, struct vfp_double *vd,
|
||||||
exponent = vd->exponent;
|
exponent = vd->exponent;
|
||||||
significand = vd->significand;
|
significand = vd->significand;
|
||||||
|
|
||||||
shift = 32 - fls(significand >> 32);
|
shift = 32 - vfp_fls(significand >> 32);
|
||||||
if (shift == 32)
|
if (shift == 32)
|
||||||
shift = 64 - fls(significand);
|
shift = 64 - vfp_fls(significand);
|
||||||
if (shift) {
|
if (shift) {
|
||||||
exponent -= shift;
|
exponent -= shift;
|
||||||
significand <<= shift;
|
significand <<= shift;
|
||||||
|
|
|
@ -69,7 +69,7 @@ static void vfp_single_dump(const char *str, struct vfp_single *s)
|
||||||
|
|
||||||
static void vfp_single_normalise_denormal(struct vfp_single *vs)
|
static void vfp_single_normalise_denormal(struct vfp_single *vs)
|
||||||
{
|
{
|
||||||
int bits = 31 - fls(vs->significand);
|
int bits = 31 - vfp_fls(vs->significand);
|
||||||
|
|
||||||
vfp_single_dump("normalise_denormal: in", vs);
|
vfp_single_dump("normalise_denormal: in", vs);
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ u32 vfp_single_normaliseround(ARMul_State* state, int sd, struct vfp_single *vs,
|
||||||
* bit 31, so we have VFP_SINGLE_LOW_BITS + 1 below the least
|
* bit 31, so we have VFP_SINGLE_LOW_BITS + 1 below the least
|
||||||
* significant bit.
|
* significant bit.
|
||||||
*/
|
*/
|
||||||
shift = 32 - fls(significand);
|
shift = 32 - vfp_fls(significand);
|
||||||
if (shift < 32 && shift) {
|
if (shift < 32 && shift) {
|
||||||
exponent -= shift;
|
exponent -= shift;
|
||||||
significand <<= shift;
|
significand <<= shift;
|
||||||
|
|
|
@ -83,15 +83,6 @@ template<u32 func(int, void *)> void WrapU_IV() {
|
||||||
RETURN(retval);
|
RETURN(retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<float func()> void WrapF_V() {
|
|
||||||
RETURNF(func());
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Not sure about the floating point parameter passing
|
|
||||||
template<float func(int, float, u32)> void WrapF_IFU() {
|
|
||||||
RETURNF(func(PARAM(0), PARAMF(0), PARAM(1)));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<u32 func(u32)> void WrapU_U() {
|
template<u32 func(u32)> void WrapU_U() {
|
||||||
u32 retval = func(PARAM(0));
|
u32 retval = func(PARAM(0));
|
||||||
RETURN(retval);
|
RETURN(retval);
|
||||||
|
@ -127,12 +118,6 @@ template<int func(u32, u32)> void WrapI_UU() {
|
||||||
RETURN(retval);
|
RETURN(retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int func(u32, float, float)> void WrapI_UFF() {
|
|
||||||
// Not sure about the float arguments.
|
|
||||||
int retval = func(PARAM(0), PARAMF(0), PARAMF(1));
|
|
||||||
RETURN(retval);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int func(u32, u32, u32)> void WrapI_UUU() {
|
template<int func(u32, u32, u32)> void WrapI_UUU() {
|
||||||
int retval = func(PARAM(0), PARAM(1), PARAM(2));
|
int retval = func(PARAM(0), PARAM(1), PARAM(2));
|
||||||
RETURN(retval);
|
RETURN(retval);
|
||||||
|
|
|
@ -2,4 +2,9 @@ set(SRCS video_core.cpp
|
||||||
utils.cpp
|
utils.cpp
|
||||||
renderer_opengl/renderer_opengl.cpp)
|
renderer_opengl/renderer_opengl.cpp)
|
||||||
|
|
||||||
add_library(video_core STATIC ${SRCS})
|
set(HEADERS video_core.h
|
||||||
|
utils.h
|
||||||
|
renderer_base.h
|
||||||
|
renderer_opengl/renderer_opengl.h)
|
||||||
|
|
||||||
|
add_library(video_core STATIC ${SRCS} ${HEADERS})
|
||||||
|
|
|
@ -37,7 +37,7 @@ void RendererOpenGL::SwapBuffers() {
|
||||||
// EFB->XFB copy
|
// EFB->XFB copy
|
||||||
// TODO(bunnei): This is a hack and does not belong here. The copy should be triggered by some
|
// TODO(bunnei): This is a hack and does not belong here. The copy should be triggered by some
|
||||||
// register write We're also treating both framebuffers as a single one in OpenGL.
|
// register write We're also treating both framebuffers as a single one in OpenGL.
|
||||||
Rect framebuffer_size(0, 0, m_resolution_width, m_resolution_height);
|
common::Rect framebuffer_size(0, 0, m_resolution_width, m_resolution_height);
|
||||||
RenderXFB(framebuffer_size, framebuffer_size);
|
RenderXFB(framebuffer_size, framebuffer_size);
|
||||||
|
|
||||||
// XFB->Window copy
|
// XFB->Window copy
|
||||||
|
@ -75,7 +75,7 @@ void RendererOpenGL::FlipFramebuffer(const u8* in, u8* out) {
|
||||||
* @param src_rect Source rectangle in XFB to copy
|
* @param src_rect Source rectangle in XFB to copy
|
||||||
* @param dst_rect Destination rectangle in output framebuffer to copy to
|
* @param dst_rect Destination rectangle in output framebuffer to copy to
|
||||||
*/
|
*/
|
||||||
void RendererOpenGL::RenderXFB(const Rect& src_rect, const Rect& dst_rect) {
|
void RendererOpenGL::RenderXFB(const common::Rect& src_rect, const common::Rect& dst_rect) {
|
||||||
|
|
||||||
FlipFramebuffer(LCD::GetFramebufferPointer(LCD::g_regs.framebuffer_top_left_1), m_xfb_top_flipped);
|
FlipFramebuffer(LCD::GetFramebufferPointer(LCD::g_regs.framebuffer_top_left_1), m_xfb_top_flipped);
|
||||||
FlipFramebuffer(LCD::GetFramebufferPointer(LCD::g_regs.framebuffer_sub_left_1), m_xfb_bottom_flipped);
|
FlipFramebuffer(LCD::GetFramebufferPointer(LCD::g_regs.framebuffer_sub_left_1), m_xfb_bottom_flipped);
|
||||||
|
|
|
@ -28,7 +28,7 @@ public:
|
||||||
* @param src_rect Source rectangle in XFB to copy
|
* @param src_rect Source rectangle in XFB to copy
|
||||||
* @param dst_rect Destination rectangle in output framebuffer to copy to
|
* @param dst_rect Destination rectangle in output framebuffer to copy to
|
||||||
*/
|
*/
|
||||||
void RenderXFB(const Rect& src_rect, const Rect& dst_rect);
|
void RenderXFB(const common::Rect& src_rect, const common::Rect& dst_rect);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the emulator window to use for renderer
|
* Set the emulator window to use for renderer
|
||||||
|
@ -59,7 +59,7 @@ private:
|
||||||
* @param out Pointer to output buffer with flipped framebuffer
|
* @param out Pointer to output buffer with flipped framebuffer
|
||||||
* @todo Early on hack... I'd like to find a more efficient way of doing this /bunnei
|
* @todo Early on hack... I'd like to find a more efficient way of doing this /bunnei
|
||||||
*/
|
*/
|
||||||
void RendererOpenGL::FlipFramebuffer(const u8* in, u8* out);
|
void FlipFramebuffer(const u8* in, u8* out);
|
||||||
|
|
||||||
|
|
||||||
EmuWindow* m_render_window; ///< Handle to render window
|
EmuWindow* m_render_window; ///< Handle to render window
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
#include "video_core/utils.h"
|
#include "video_core/utils.h"
|
||||||
|
|
||||||
namespace VideoCore {
|
namespace VideoCore {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dumps a texture to TGA
|
* Dumps a texture to TGA
|
||||||
* @param filename String filename to dump texture to
|
* @param filename String filename to dump texture to
|
||||||
|
@ -32,9 +31,9 @@ void DumpTGA(std::string filename, int width, int height, u8* raw_data) {
|
||||||
fwrite(&hdr, sizeof(TGAHeader), 1, fout);
|
fwrite(&hdr, sizeof(TGAHeader), 1, fout);
|
||||||
for (int i = 0; i < height; i++) {
|
for (int i = 0; i < height; i++) {
|
||||||
for (int j = 0; j < width; j++) {
|
for (int j = 0; j < width; j++) {
|
||||||
r = raw_data[(4 * (i * width)) + (4 * j) + 0];
|
b = raw_data[(3 * (i * width)) + (3 * j) + 0];
|
||||||
g = raw_data[(4 * (i * width)) + (4 * j) + 1];
|
g = raw_data[(3 * (i * width)) + (3 * j) + 1];
|
||||||
b = raw_data[(4 * (i * width)) + (4 * j) + 2];
|
r = raw_data[(3 * (i * width)) + (3 * j) + 2];
|
||||||
putc(b, fout);
|
putc(b, fout);
|
||||||
putc(g, fout);
|
putc(g, fout);
|
||||||
putc(r, fout);
|
putc(r, fout);
|
||||||
|
@ -42,5 +41,4 @@ void DumpTGA(std::string filename, int width, int height, u8* raw_data) {
|
||||||
}
|
}
|
||||||
fclose(fout);
|
fclose(fout);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -30,6 +30,9 @@ void Start() {
|
||||||
|
|
||||||
/// Initialize the video core
|
/// Initialize the video core
|
||||||
void Init(EmuWindow* emu_window) {
|
void Init(EmuWindow* emu_window) {
|
||||||
|
// Known problem with GLEW prevents contexts above 2.x on OSX unless glewExperimental is enabled.
|
||||||
|
glewExperimental = GL_TRUE;
|
||||||
|
|
||||||
g_emu_window = emu_window;
|
g_emu_window = emu_window;
|
||||||
g_emu_window->MakeCurrent();
|
g_emu_window->MakeCurrent();
|
||||||
g_renderer = new RendererOpenGL();
|
g_renderer = new RendererOpenGL();
|
||||||
|
|
Reference in New Issue