summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x.travis-build.sh10
-rwxr-xr-x.travis-deps.sh1
-rw-r--r--.travis-upload.sh6
-rw-r--r--.travis.yml2
-rw-r--r--CMakeLists.txt6
-rw-r--r--CONTRIBUTING.md6
-rw-r--r--Doxyfile126
-rw-r--r--README.md2
-rw-r--r--appveyor.yml12
-rw-r--r--dist/citra.ico (renamed from src/assets/citra.ico)bin509287 -> 509287 bytes
-rw-r--r--dist/doc-icon.png (renamed from doc-icon.png)bin8791 -> 8791 bytes
-rw-r--r--externals/glfw-3.0.4.bin/include/GLFW/glfw3native.h180
-rw-r--r--externals/glfw-3.0.4.bin/lib-mingw-i686/glfw3.dllbin172569 -> 0 bytes
-rw-r--r--externals/glfw-3.0.4.bin/lib-mingw-i686/libglfw3.abin83006 -> 0 bytes
-rw-r--r--externals/glfw-3.0.4.bin/lib-mingw-x86_64/glfw3.dllbin199843 -> 0 bytes
-rw-r--r--externals/glfw-3.0.4.bin/lib-mingw-x86_64/libglfw3.abin89300 -> 0 bytes
-rw-r--r--externals/glfw-3.0.4.bin/lib-msvc_v110-Win32/glfw3.dllbin43520 -> 0 bytes
-rw-r--r--externals/glfw-3.0.4.bin/lib-msvc_v110-Win32/glfw3.libbin123024 -> 0 bytes
-rw-r--r--externals/glfw-3.0.4.bin/lib-msvc_v110-Win32/glfw3dll.libbin17748 -> 0 bytes
-rw-r--r--externals/glfw-3.0.4.bin/lib-msvc_v110-x64/glfw3.dllbin48640 -> 0 bytes
-rw-r--r--externals/glfw-3.0.4.bin/lib-msvc_v110-x64/glfw3.libbin180886 -> 0 bytes
-rw-r--r--externals/glfw-3.0.4.bin/lib-msvc_v110-x64/glfw3dll.libbin17418 -> 0 bytes
-rw-r--r--externals/glfw-3.0.4.bin/lib-msvc_v120-Win32/glfw3.dllbin43520 -> 0 bytes
-rw-r--r--externals/glfw-3.0.4.bin/lib-msvc_v120-Win32/glfw3.libbin123566 -> 0 bytes
-rw-r--r--externals/glfw-3.0.4.bin/lib-msvc_v120-Win32/glfw3dll.libbin17748 -> 0 bytes
-rw-r--r--externals/glfw-3.0.4.bin/lib-msvc_v120-x64/glfw3.dllbin48640 -> 0 bytes
-rw-r--r--externals/glfw-3.0.4.bin/lib-msvc_v120-x64/glfw3.libbin180408 -> 0 bytes
-rw-r--r--externals/glfw-3.0.4.bin/lib-msvc_v120-x64/glfw3dll.libbin17418 -> 0 bytes
-rw-r--r--externals/glfw-3.1.1.bin/COPYING.txt (renamed from externals/glfw-3.0.4.bin/COPYING.txt)0
-rw-r--r--externals/glfw-3.1.1.bin/include/GLFW/glfw3.h (renamed from externals/glfw-3.0.4.bin/include/GLFW/glfw3.h)2014
-rw-r--r--externals/glfw-3.1.1.bin/include/GLFW/glfw3native.h356
-rw-r--r--externals/glfw-3.1.1.bin/lib-mingw-i686/glfw3.dllbin0 -> 196839 bytes
-rw-r--r--externals/glfw-3.1.1.bin/lib-mingw-i686/glfw3dll.a (renamed from externals/glfw-3.0.4.bin/lib-mingw-i686/glfw3dll.a)bin48318 -> 54834 bytes
-rw-r--r--externals/glfw-3.1.1.bin/lib-mingw-i686/libglfw3.abin0 -> 89732 bytes
-rw-r--r--externals/glfw-3.1.1.bin/lib-mingw-x86_64/glfw3.dllbin0 -> 235754 bytes
-rw-r--r--externals/glfw-3.1.1.bin/lib-mingw-x86_64/glfw3dll.a (renamed from externals/glfw-3.0.4.bin/lib-mingw-x86_64/glfw3dll.a)bin47144 -> 53500 bytes
-rw-r--r--externals/glfw-3.1.1.bin/lib-mingw-x86_64/libglfw3.abin0 -> 97354 bytes
-rw-r--r--externals/glfw-3.1.1.bin/lib-msvc_v120-Win32/glfw3.dllbin0 -> 47104 bytes
-rw-r--r--externals/glfw-3.1.1.bin/lib-msvc_v120-Win32/glfw3.libbin0 -> 150616 bytes
-rw-r--r--externals/glfw-3.1.1.bin/lib-msvc_v120-Win32/glfw3dll.libbin0 -> 19984 bytes
-rw-r--r--externals/glfw-3.1.1.bin/lib-msvc_v120-x64/glfw3.dllbin0 -> 53248 bytes
-rw-r--r--externals/glfw-3.1.1.bin/lib-msvc_v120-x64/glfw3.libbin0 -> 196774 bytes
-rw-r--r--externals/glfw-3.1.1.bin/lib-msvc_v120-x64/glfw3dll.libbin0 -> 19602 bytes
-rw-r--r--src/citra/citra.rc18
-rw-r--r--src/citra/config.cpp1
-rw-r--r--src/citra/resource.hbin898 -> 431 bytes
-rw-r--r--src/citra_qt/CMakeLists.txt14
-rw-r--r--src/citra_qt/bootmanager.cpp2
-rw-r--r--src/citra_qt/bootmanager.h2
-rw-r--r--src/citra_qt/citra-qt.rcbin566 -> 275 bytes
-rw-r--r--src/citra_qt/config.cpp2
-rw-r--r--src/citra_qt/debugger/callstack.cpp2
-rw-r--r--src/citra_qt/debugger/callstack.ui3
-rw-r--r--src/citra_qt/debugger/graphics_cmdlists.cpp4
-rw-r--r--src/citra_qt/debugger/graphics_framebuffer.cpp3
-rw-r--r--src/citra_qt/main.cpp2
-rw-r--r--src/citra_qt/main.ui17
-rw-r--r--src/common/CMakeLists.txt2
-rw-r--r--src/common/color.h (renamed from src/video_core/color.h)3
-rw-r--r--src/common/emu_window.cpp2
-rw-r--r--src/common/file_util.cpp2
-rw-r--r--src/common/logging/backend.cpp1
-rw-r--r--src/common/logging/log.h5
-rw-r--r--src/common/math_util.h2
-rw-r--r--src/common/swap.h2
-rw-r--r--src/common/vector_math.h (renamed from src/video_core/math.h)2
-rw-r--r--src/core/CMakeLists.txt83
-rw-r--r--src/core/arm/disassembler/arm_disasm.cpp2
-rw-r--r--src/core/arm/dyncom/arm_dyncom.cpp2
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp39
-rw-r--r--src/core/arm/dyncom/arm_dyncom_thumb.cpp102
-rw-r--r--src/core/arm/interpreter/arminit.cpp1
-rw-r--r--src/core/arm/interpreter/armsupp.cpp2
-rw-r--r--src/core/arm/skyeye_common/arm_regformat.h2
-rw-r--r--src/core/arm/skyeye_common/armdefs.h34
-rw-r--r--src/core/arm/skyeye_common/armemu.h47
-rw-r--r--src/core/arm/skyeye_common/vfp/vfp.cpp4
-rw-r--r--src/core/arm/skyeye_common/vfp/vfp.h1
-rw-r--r--src/core/arm/skyeye_common/vfp/vfp_helper.h4
-rw-r--r--src/core/arm/skyeye_common/vfp/vfpinstr.cpp18
-rw-r--r--src/core/core_timing.cpp2
-rw-r--r--src/core/core_timing.h2
-rw-r--r--src/core/file_sys/archive_extsavedata.cpp13
-rw-r--r--src/core/file_sys/archive_extsavedata.h4
-rw-r--r--src/core/file_sys/archive_savedata.cpp2
-rw-r--r--src/core/hle/function_wrappers.h17
-rw-r--r--src/core/hle/kernel/event.cpp3
-rw-r--r--src/core/hle/kernel/kernel.cpp22
-rw-r--r--src/core/hle/kernel/kernel.h6
-rw-r--r--src/core/hle/kernel/mutex.cpp9
-rw-r--r--src/core/hle/kernel/resource_limit.h8
-rw-r--r--src/core/hle/kernel/semaphore.cpp10
-rw-r--r--src/core/hle/kernel/thread.cpp84
-rw-r--r--src/core/hle/kernel/thread.h14
-rw-r--r--src/core/hle/kernel/timer.cpp2
-rw-r--r--src/core/hle/kernel/vm_manager.cpp245
-rw-r--r--src/core/hle/kernel/vm_manager.h200
-rw-r--r--src/core/hle/service/am/am.cpp55
-rw-r--r--src/core/hle/service/am/am.h47
-rw-r--r--src/core/hle/service/am/am_app.cpp20
-rw-r--r--src/core/hle/service/am/am_app.h22
-rw-r--r--src/core/hle/service/am/am_net.cpp (renamed from src/core/hle/service/am_net.cpp)17
-rw-r--r--src/core/hle/service/am/am_net.h22
-rw-r--r--src/core/hle/service/am/am_sys.cpp22
-rw-r--r--src/core/hle/service/am/am_sys.h22
-rw-r--r--src/core/hle/service/am/am_u.cpp22
-rw-r--r--src/core/hle/service/am/am_u.h22
-rw-r--r--src/core/hle/service/am_app.cpp23
-rw-r--r--src/core/hle/service/am_app.h23
-rw-r--r--src/core/hle/service/am_net.h23
-rw-r--r--src/core/hle/service/am_sys.cpp62
-rw-r--r--src/core/hle/service/am_sys.h23
-rw-r--r--src/core/hle/service/apt/apt.cpp4
-rw-r--r--src/core/hle/service/apt/apt.h8
-rw-r--r--src/core/hle/service/boss/boss.cpp29
-rw-r--r--src/core/hle/service/boss/boss.h20
-rw-r--r--src/core/hle/service/boss/boss_p.cpp20
-rw-r--r--src/core/hle/service/boss/boss_p.h22
-rw-r--r--src/core/hle/service/boss/boss_u.cpp21
-rw-r--r--src/core/hle/service/boss/boss_u.h22
-rw-r--r--src/core/hle/service/boss_p.cpp23
-rw-r--r--src/core/hle/service/boss_p.h23
-rw-r--r--src/core/hle/service/boss_u.cpp24
-rw-r--r--src/core/hle/service/boss_u.h23
-rw-r--r--src/core/hle/service/cam/cam.cpp35
-rw-r--r--src/core/hle/service/cam/cam.h20
-rw-r--r--src/core/hle/service/cam/cam_c.cpp20
-rw-r--r--src/core/hle/service/cam/cam_c.h22
-rw-r--r--src/core/hle/service/cam/cam_q.cpp20
-rw-r--r--src/core/hle/service/cam/cam_q.h22
-rw-r--r--src/core/hle/service/cam/cam_s.cpp20
-rw-r--r--src/core/hle/service/cam/cam_s.h22
-rw-r--r--src/core/hle/service/cam/cam_u.cpp20
-rw-r--r--src/core/hle/service/cam/cam_u.h22
-rw-r--r--src/core/hle/service/cam_u.cpp23
-rw-r--r--src/core/hle/service/cam_u.h23
-rw-r--r--src/core/hle/service/cecd/cecd.cpp31
-rw-r--r--src/core/hle/service/cecd/cecd.h20
-rw-r--r--src/core/hle/service/cecd/cecd_s.cpp20
-rw-r--r--src/core/hle/service/cecd/cecd_s.h (renamed from src/core/hle/service/cecd_s.h)13
-rw-r--r--src/core/hle/service/cecd/cecd_u.cpp20
-rw-r--r--src/core/hle/service/cecd/cecd_u.h (renamed from src/core/hle/service/cecd_u.h)13
-rw-r--r--src/core/hle/service/cecd_s.cpp23
-rw-r--r--src/core/hle/service/cecd_u.cpp23
-rw-r--r--src/core/hle/service/cfg/cfg.cpp4
-rw-r--r--src/core/hle/service/frd/frd.cpp29
-rw-r--r--src/core/hle/service/frd/frd.h20
-rw-r--r--src/core/hle/service/frd/frd_a.cpp20
-rw-r--r--src/core/hle/service/frd/frd_a.h (renamed from src/core/hle/service/frd_a.h)13
-rw-r--r--src/core/hle/service/frd/frd_u.cpp (renamed from src/core/hle/service/frd_u.cpp)17
-rw-r--r--src/core/hle/service/frd/frd_u.h (renamed from src/core/hle/service/frd_u.h)13
-rw-r--r--src/core/hle/service/frd_a.cpp23
-rw-r--r--src/core/hle/service/fs/archive.cpp29
-rw-r--r--src/core/hle/service/fs/archive.h4
-rw-r--r--src/core/hle/service/fs/fs_user.cpp20
-rw-r--r--src/core/hle/service/gsp_gpu.cpp68
-rw-r--r--src/core/hle/service/hid/hid.cpp6
-rw-r--r--src/core/hle/service/hid/hid_spvr.cpp2
-rw-r--r--src/core/hle/service/hid/hid_user.h2
-rw-r--r--src/core/hle/service/news/news.cpp31
-rw-r--r--src/core/hle/service/news/news.h20
-rw-r--r--src/core/hle/service/news/news_s.cpp21
-rw-r--r--src/core/hle/service/news/news_s.h (renamed from src/core/hle/service/news_s.h)13
-rw-r--r--src/core/hle/service/news/news_u.cpp21
-rw-r--r--src/core/hle/service/news/news_u.h (renamed from src/core/hle/service/news_u.h)13
-rw-r--r--src/core/hle/service/news_s.cpp24
-rw-r--r--src/core/hle/service/news_u.cpp24
-rw-r--r--src/core/hle/service/nim/nim.cpp42
-rw-r--r--src/core/hle/service/nim/nim.h30
-rw-r--r--src/core/hle/service/nim/nim_aoc.cpp (renamed from src/core/hle/service/nim_aoc.cpp)16
-rw-r--r--src/core/hle/service/nim/nim_aoc.h22
-rw-r--r--src/core/hle/service/nim/nim_s.cpp22
-rw-r--r--src/core/hle/service/nim/nim_s.h22
-rw-r--r--src/core/hle/service/nim/nim_u.cpp27
-rw-r--r--src/core/hle/service/nim/nim_u.h22
-rw-r--r--src/core/hle/service/nim_aoc.h23
-rw-r--r--src/core/hle/service/nim_u.cpp48
-rw-r--r--src/core/hle/service/nim_u.h23
-rw-r--r--src/core/hle/service/ptm/ptm.h6
-rw-r--r--src/core/hle/service/ptm/ptm_play.cpp2
-rw-r--r--src/core/hle/service/service.cpp60
-rw-r--r--src/core/hle/service/soc_u.cpp30
-rw-r--r--src/core/hle/svc.cpp32
-rw-r--r--src/core/hw/gpu.cpp17
-rw-r--r--src/core/hw/hw.cpp2
-rw-r--r--src/core/hw/lcd.cpp2
-rw-r--r--src/core/hw/lcd.h2
-rw-r--r--src/core/loader/3dsx.cpp2
-rw-r--r--src/core/mem_map.cpp55
-rw-r--r--src/core/mem_map.h8
-rw-r--r--src/core/memory.cpp12
-rw-r--r--src/core/memory.h2
-rw-r--r--src/core/memory_setup.h7
-rw-r--r--src/core/settings.h1
-rw-r--r--src/video_core/CMakeLists.txt2
-rw-r--r--src/video_core/command_processor.cpp78
-rw-r--r--src/video_core/debug_utils/debug_utils.cpp6
-rw-r--r--src/video_core/debug_utils/debug_utils.h3
-rw-r--r--src/video_core/pica.h93
-rw-r--r--src/video_core/rasterizer.cpp80
-rw-r--r--src/video_core/renderer_opengl/generated/gl_3_2_core.c16
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp169
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h3
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_shaders.h24
-rw-r--r--src/video_core/renderer_opengl/gl_state.cpp49
-rw-r--r--src/video_core/renderer_opengl/gl_state.h11
-rw-r--r--src/video_core/renderer_opengl/pica_to_gl.h31
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp10
-rw-r--r--src/video_core/vertex_shader.cpp33
210 files changed, 4512 insertions, 1964 deletions
diff --git a/.travis-build.sh b/.travis-build.sh
index 21582c689..422e13220 100755
--- a/.travis-build.sh
+++ b/.travis-build.sh
@@ -3,14 +3,20 @@
3set -e 3set -e
4set -x 4set -x
5 5
6if grep -r '\s$' src *.yml *.txt *.md Doxyfile .gitignore .gitmodules .travis* dist/*.desktop \
7 dist/*.svg dist/*.xml; then
8 echo Trailing whitespace found, aborting
9 exit 1
10fi
11
6#if OS is linux or is not set 12#if OS is linux or is not set
7if [ "$TRAVIS_OS_NAME" = "linux" -o -z "$TRAVIS_OS_NAME" ]; then 13if [ "$TRAVIS_OS_NAME" = "linux" -o -z "$TRAVIS_OS_NAME" ]; then
8 mkdir build && cd build 14 mkdir build && cd build
9 cmake -DUSE_QT5=OFF .. 15 cmake -DUSE_QT5=OFF ..
10 make -j4 16 make -j4
11elif [ "$TRAVIS_OS_NAME" = "osx" ]; then 17elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
12 export Qt5_DIR=$(brew --prefix)/opt/qt5 18 export Qt5_DIR=$(brew --prefix)/opt/qt5
13 mkdir build && cd build 19 mkdir build && cd build
14 cmake .. -GXcode 20 cmake .. -GXcode
15 xcodebuild -configuration Release 21 xcodebuild -configuration Release | xcpretty -c && exit ${PIPESTATUS[0]}
16fi 22fi
diff --git a/.travis-deps.sh b/.travis-deps.sh
index f8074fb91..b9561bb66 100755
--- a/.travis-deps.sh
+++ b/.travis-deps.sh
@@ -26,4 +26,5 @@ if [ "$TRAVIS_OS_NAME" = "linux" -o -z "$TRAVIS_OS_NAME" ]; then
26elif [ "$TRAVIS_OS_NAME" = "osx" ]; then 26elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
27 brew tap homebrew/versions 27 brew tap homebrew/versions
28 brew install qt5 glfw3 pkgconfig 28 brew install qt5 glfw3 pkgconfig
29 gem install xcpretty
29fi 30fi
diff --git a/.travis-upload.sh b/.travis-upload.sh
index 4b9446a96..0904b646a 100644
--- a/.travis-upload.sh
+++ b/.travis-upload.sh
@@ -6,7 +6,7 @@ if [ "$TRAVIS_BRANCH" = "master" ]; then
6 REV_NAME="citra-${GITDATE}-${GITREV}-linux-amd64" 6 REV_NAME="citra-${GITDATE}-${GITREV}-linux-amd64"
7 UPLOAD_DIR="/citra/nightly/linux-amd64" 7 UPLOAD_DIR="/citra/nightly/linux-amd64"
8 mkdir "$REV_NAME" 8 mkdir "$REV_NAME"
9 9
10 sudo apt-get -qq install lftp 10 sudo apt-get -qq install lftp
11 cp build/src/citra/citra "$REV_NAME" 11 cp build/src/citra/citra "$REV_NAME"
12 cp build/src/citra_qt/citra-qt "$REV_NAME" 12 cp build/src/citra_qt/citra-qt "$REV_NAME"
@@ -14,7 +14,7 @@ if [ "$TRAVIS_BRANCH" = "master" ]; then
14 REV_NAME="citra-${GITDATE}-${GITREV}-osx-amd64" 14 REV_NAME="citra-${GITDATE}-${GITREV}-osx-amd64"
15 UPLOAD_DIR="/citra/nightly/osx-amd64" 15 UPLOAD_DIR="/citra/nightly/osx-amd64"
16 mkdir "$REV_NAME" 16 mkdir "$REV_NAME"
17 17
18 brew install lftp 18 brew install lftp
19 cp build/src/citra/Release/citra "$REV_NAME" 19 cp build/src/citra/Release/citra "$REV_NAME"
20 cp -r build/src/citra_qt/Release/citra-qt.app "$REV_NAME" 20 cp -r build/src/citra_qt/Release/citra-qt.app "$REV_NAME"
@@ -22,7 +22,7 @@ if [ "$TRAVIS_BRANCH" = "master" ]; then
22 # move qt libs into app bundle for deployment 22 # move qt libs into app bundle for deployment
23 $(brew --prefix)/opt/qt5/bin/macdeployqt "${REV_NAME}/citra-qt.app" 23 $(brew --prefix)/opt/qt5/bin/macdeployqt "${REV_NAME}/citra-qt.app"
24 fi 24 fi
25 25
26 ARCHIVE_NAME="${REV_NAME}.tar.xz" 26 ARCHIVE_NAME="${REV_NAME}.tar.xz"
27 tar -cJvf "$ARCHIVE_NAME" "$REV_NAME" 27 tar -cJvf "$ARCHIVE_NAME" "$REV_NAME"
28 lftp -c "open -u citra-builds,$BUILD_PASSWORD sftp://builds.citra-emu.org; put -O '$UPLOAD_DIR' '$ARCHIVE_NAME'" 28 lftp -c "open -u citra-builds,$BUILD_PASSWORD sftp://builds.citra-emu.org; put -O '$UPLOAD_DIR' '$ARCHIVE_NAME'"
diff --git a/.travis.yml b/.travis.yml
index b878cc160..5c882a574 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -6,7 +6,7 @@ language: cpp
6 6
7env: 7env:
8 global: 8 global:
9 - secure: "AXHFIafTmbGDsHD3mUVj5a4I397DQjti/WoqAJGUp2PglxTcc04BwxZ9Z+xLuf5N2Hs5r9ojAJLT8OGxJCLBDXzneQTNSqXbFuYSLbqrEAiIRlA9eRIotWCg+wYcO+5e8MKX+cHVKwiIWasUB21AtCdq6msh6Y3pUshZp212VPg=" 9 - secure: "AXHFIafTmbGDsHD3mUVj5a4I397DQjti/WoqAJGUp2PglxTcc04BwxZ9Z+xLuf5N2Hs5r9ojAJLT8OGxJCLBDXzneQTNSqXbFuYSLbqrEAiIRlA9eRIotWCg+wYcO+5e8MKX+cHVKwiIWasUB21AtCdq6msh6Y3pUshZp212VPg="
10 10
11before_install: 11before_install:
12 - sh .travis-deps.sh 12 - sh .travis-deps.sh
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d958dfc35..6805ebed8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -45,7 +45,7 @@ else()
45 set(CMAKE_CXX_FLAGS_RELEASE "${optimization_flags} /MP /MD" CACHE STRING "" FORCE) 45 set(CMAKE_CXX_FLAGS_RELEASE "${optimization_flags} /MP /MD" CACHE STRING "" FORCE)
46 set(CMAKE_C_FLAGS_RELWITHDEBINFO "${optimization_flags} /MP /MD /Zi /Zo" CACHE STRING "" FORCE) 46 set(CMAKE_C_FLAGS_RELWITHDEBINFO "${optimization_flags} /MP /MD /Zi /Zo" CACHE STRING "" FORCE)
47 set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${optimization_flags} /MP /MD /Zi /Zo" CACHE STRING "" FORCE) 47 set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${optimization_flags} /MP /MD /Zi /Zo" CACHE STRING "" FORCE)
48 48
49 set(CMAKE_EXE_LINKER_FLAGS_DEBUG "/DEBUG" CACHE STRING "" FORCE) 49 set(CMAKE_EXE_LINKER_FLAGS_DEBUG "/DEBUG" CACHE STRING "" FORCE)
50 set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "/DEBUG" CACHE STRING "" FORCE) 50 set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "/DEBUG" CACHE STRING "" FORCE)
51endif() 51endif()
@@ -114,7 +114,7 @@ if (ENABLE_GLFW)
114 set(TMP_TOOLSET "mingw-${TMP_ARCH}") 114 set(TMP_TOOLSET "mingw-${TMP_ARCH}")
115 endif() 115 endif()
116 116
117 set(GLFW_PREFIX "${CMAKE_CURRENT_SOURCE_DIR}/externals/glfw-3.0.4.bin") 117 set(GLFW_PREFIX "${CMAKE_CURRENT_SOURCE_DIR}/externals/glfw-3.1.1.bin")
118 set(GLFW_INCLUDE_DIRS "${GLFW_PREFIX}/include" CACHE PATH "Path to GLFW3 headers") 118 set(GLFW_INCLUDE_DIRS "${GLFW_PREFIX}/include" CACHE PATH "Path to GLFW3 headers")
119 set(GLFW_LIBRARY_DIRS "${GLFW_PREFIX}/lib-${TMP_TOOLSET}" CACHE PATH "Path to GLFW3 libraries") 119 set(GLFW_LIBRARY_DIRS "${GLFW_PREFIX}/lib-${TMP_TOOLSET}" CACHE PATH "Path to GLFW3 libraries")
120 120
@@ -137,7 +137,7 @@ IF (APPLE)
137 FIND_LIBRARY(IOKIT_LIBRARY IOKit) # GLFW dependency 137 FIND_LIBRARY(IOKIT_LIBRARY IOKit) # GLFW dependency
138 FIND_LIBRARY(COREVIDEO_LIBRARY CoreVideo) # GLFW dependency 138 FIND_LIBRARY(COREVIDEO_LIBRARY CoreVideo) # GLFW dependency
139 set(PLATFORM_LIBRARIES iconv ${COCOA_LIBRARY} ${IOKIT_LIBRARY} ${COREVIDEO_LIBRARY}) 139 set(PLATFORM_LIBRARIES iconv ${COCOA_LIBRARY} ${IOKIT_LIBRARY} ${COREVIDEO_LIBRARY})
140 140
141 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") 141 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
142 set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++") 142 set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++")
143ELSEIF(MINGW) 143ELSEIF(MINGW)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index c8c8e3884..906a4bc7d 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -10,16 +10,16 @@ Citra is a brand new project, so we have a great opportunity to keep things clea
10 10
11### Naming Rules 11### Naming Rules
12* Functions 12* Functions
13 * CamelCase, "_" may also be used for clarity (e.g. ARM_InitCore) 13 * PascalCase, "_" may also be used for clarity (e.g. ARM_InitCore)
14* Variables 14* Variables
15 * lower_case_underscored 15 * lower_case_underscored
16 * Prefix "g_" if global 16 * Prefix "g_" if global
17* Classes 17* Classes
18 * CamelCase, "_" may also be used for clarity (e.g. OGL_VideoInterface) 18 * PascalCase, "_" may also be used for clarity (e.g. OGL_VideoInterface)
19* Files/Folders 19* Files/Folders
20 * lower_case_underscored 20 * lower_case_underscored
21* Namespaces 21* Namespaces
22 * CamelCase, "_" may also be used for clarity (e.g. ARM_InitCore) 22 * PascalCase, "_" may also be used for clarity (e.g. ARM_InitCore)
23 23
24### Indentation/Whitespace Style 24### Indentation/Whitespace Style
25Follow the indentation/whitespace style shown below. Do not use tabs, use 4-spaces instead. 25Follow the indentation/whitespace style shown below. Do not use tabs, use 4-spaces instead.
diff --git a/Doxyfile b/Doxyfile
index 5c2e09246..6ddf2cf21 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -38,7 +38,7 @@ PROJECT_NAME = Citra
38# could be handy for archiving the generated documentation or if some version 38# could be handy for archiving the generated documentation or if some version
39# control system is used. 39# control system is used.
40 40
41PROJECT_NUMBER = 41PROJECT_NUMBER =
42 42
43# Using the PROJECT_BRIEF tag one can provide an optional one line description 43# Using the PROJECT_BRIEF tag one can provide an optional one line description
44# for a project that appears at the top of each page and should give viewer a 44# for a project that appears at the top of each page and should give viewer a
@@ -51,7 +51,7 @@ PROJECT_BRIEF = "Nintendo 3DS emulator/debugger"
51# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo 51# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo
52# to the output directory. 52# to the output directory.
53 53
54PROJECT_LOGO = doc-icon.png 54PROJECT_LOGO = dist/doc-icon.png
55 55
56# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path 56# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
57# into which the generated documentation will be written. If a relative path is 57# into which the generated documentation will be written. If a relative path is
@@ -162,7 +162,7 @@ FULL_PATH_NAMES = YES
162# will be relative from the directory where doxygen is started. 162# will be relative from the directory where doxygen is started.
163# This tag requires that the tag FULL_PATH_NAMES is set to YES. 163# This tag requires that the tag FULL_PATH_NAMES is set to YES.
164 164
165STRIP_FROM_PATH = 165STRIP_FROM_PATH =
166 166
167# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the 167# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
168# path mentioned in the documentation of a class, which tells the reader which 168# path mentioned in the documentation of a class, which tells the reader which
@@ -171,7 +171,7 @@ STRIP_FROM_PATH =
171# specify the list of include paths that are normally passed to the compiler 171# specify the list of include paths that are normally passed to the compiler
172# using the -I flag. 172# using the -I flag.
173 173
174STRIP_FROM_INC_PATH = 174STRIP_FROM_INC_PATH =
175 175
176# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but 176# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
177# less readable) file names. This can be useful is your file systems doesn't 177# less readable) file names. This can be useful is your file systems doesn't
@@ -238,13 +238,13 @@ TAB_SIZE = 4
238# "Side Effects:". You can put \n's in the value part of an alias to insert 238# "Side Effects:". You can put \n's in the value part of an alias to insert
239# newlines. 239# newlines.
240 240
241ALIASES = 241ALIASES =
242 242
243# This tag can be used to specify a number of word-keyword mappings (TCL only). 243# This tag can be used to specify a number of word-keyword mappings (TCL only).
244# A mapping has the form "name=value". For example adding "class=itcl::class" 244# A mapping has the form "name=value". For example adding "class=itcl::class"
245# will allow you to use the command class in the itcl::class meaning. 245# will allow you to use the command class in the itcl::class meaning.
246 246
247TCL_SUBST = 247TCL_SUBST =
248 248
249# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources 249# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
250# only. Doxygen will then generate output that is more tailored for C. For 250# only. Doxygen will then generate output that is more tailored for C. For
@@ -291,7 +291,7 @@ OPTIMIZE_OUTPUT_VHDL = NO
291# Note that for custom extensions you also need to set FILE_PATTERNS otherwise 291# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
292# the files are not read by doxygen. 292# the files are not read by doxygen.
293 293
294EXTENSION_MAPPING = 294EXTENSION_MAPPING =
295 295
296# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments 296# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
297# according to the Markdown format, which allows for more readable 297# according to the Markdown format, which allows for more readable
@@ -627,7 +627,7 @@ GENERATE_DEPRECATEDLIST= YES
627# sections, marked by \if <section_label> ... \endif and \cond <section_label> 627# sections, marked by \if <section_label> ... \endif and \cond <section_label>
628# ... \endcond blocks. 628# ... \endcond blocks.
629 629
630ENABLED_SECTIONS = 630ENABLED_SECTIONS =
631 631
632# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the 632# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
633# initial value of a variable or macro / define can have for it to appear in the 633# initial value of a variable or macro / define can have for it to appear in the
@@ -669,7 +669,7 @@ SHOW_NAMESPACES = YES
669# by doxygen. Whatever the program writes to standard output is used as the file 669# by doxygen. Whatever the program writes to standard output is used as the file
670# version. For an example see the documentation. 670# version. For an example see the documentation.
671 671
672FILE_VERSION_FILTER = 672FILE_VERSION_FILTER =
673 673
674# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed 674# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
675# by doxygen. The layout file controls the global structure of the generated 675# by doxygen. The layout file controls the global structure of the generated
@@ -682,7 +682,7 @@ FILE_VERSION_FILTER =
682# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE 682# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
683# tag is left empty. 683# tag is left empty.
684 684
685LAYOUT_FILE = 685LAYOUT_FILE =
686 686
687# The CITE_BIB_FILES tag can be used to specify one or more bib files containing 687# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
688# the reference definitions. This must be a list of .bib files. The .bib 688# the reference definitions. This must be a list of .bib files. The .bib
@@ -692,7 +692,7 @@ LAYOUT_FILE =
692# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the 692# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
693# search path. See also \cite for info how to create references. 693# search path. See also \cite for info how to create references.
694 694
695CITE_BIB_FILES = 695CITE_BIB_FILES =
696 696
697#--------------------------------------------------------------------------- 697#---------------------------------------------------------------------------
698# Configuration options related to warning and progress messages 698# Configuration options related to warning and progress messages
@@ -751,7 +751,7 @@ WARN_FORMAT = "$file:$line: $text"
751# messages should be written. If left blank the output is written to standard 751# messages should be written. If left blank the output is written to standard
752# error (stderr). 752# error (stderr).
753 753
754WARN_LOGFILE = 754WARN_LOGFILE =
755 755
756#--------------------------------------------------------------------------- 756#---------------------------------------------------------------------------
757# Configuration options related to the input files 757# Configuration options related to the input files
@@ -807,7 +807,7 @@ RECURSIVE = YES
807# Note that relative paths are relative to the directory from which doxygen is 807# Note that relative paths are relative to the directory from which doxygen is
808# run. 808# run.
809 809
810EXCLUDE = 810EXCLUDE =
811 811
812# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or 812# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
813# directories that are symbolic links (a Unix file system feature) are excluded 813# directories that are symbolic links (a Unix file system feature) are excluded
@@ -823,7 +823,7 @@ EXCLUDE_SYMLINKS = NO
823# Note that the wildcards are matched against the file with absolute path, so to 823# Note that the wildcards are matched against the file with absolute path, so to
824# exclude all test directories for example use the pattern */test/* 824# exclude all test directories for example use the pattern */test/*
825 825
826EXCLUDE_PATTERNS = 826EXCLUDE_PATTERNS =
827 827
828# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 828# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
829# (namespaces, classes, functions, etc.) that should be excluded from the 829# (namespaces, classes, functions, etc.) that should be excluded from the
@@ -834,13 +834,13 @@ EXCLUDE_PATTERNS =
834# Note that the wildcards are matched against the file with absolute path, so to 834# Note that the wildcards are matched against the file with absolute path, so to
835# exclude all test directories use the pattern */test/* 835# exclude all test directories use the pattern */test/*
836 836
837EXCLUDE_SYMBOLS = 837EXCLUDE_SYMBOLS =
838 838
839# The EXAMPLE_PATH tag can be used to specify one or more files or directories 839# The EXAMPLE_PATH tag can be used to specify one or more files or directories
840# that contain example code fragments that are included (see the \include 840# that contain example code fragments that are included (see the \include
841# command). 841# command).
842 842
843EXAMPLE_PATH = 843EXAMPLE_PATH =
844 844
845# If the value of the EXAMPLE_PATH tag contains directories, you can use the 845# If the value of the EXAMPLE_PATH tag contains directories, you can use the
846# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and 846# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
@@ -860,7 +860,7 @@ EXAMPLE_RECURSIVE = NO
860# that contain images that are to be included in the documentation (see the 860# that contain images that are to be included in the documentation (see the
861# \image command). 861# \image command).
862 862
863IMAGE_PATH = 863IMAGE_PATH =
864 864
865# The INPUT_FILTER tag can be used to specify a program that doxygen should 865# The INPUT_FILTER tag can be used to specify a program that doxygen should
866# invoke to filter for each input file. Doxygen will invoke the filter program 866# invoke to filter for each input file. Doxygen will invoke the filter program
@@ -877,7 +877,7 @@ IMAGE_PATH =
877# code is scanned, but not when the output code is generated. If lines are added 877# code is scanned, but not when the output code is generated. If lines are added
878# or removed, the anchors will not be placed correctly. 878# or removed, the anchors will not be placed correctly.
879 879
880INPUT_FILTER = 880INPUT_FILTER =
881 881
882# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 882# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
883# basis. Doxygen will compare the file name with each pattern and apply the 883# basis. Doxygen will compare the file name with each pattern and apply the
@@ -886,7 +886,7 @@ INPUT_FILTER =
886# filters are used. If the FILTER_PATTERNS tag is empty or if none of the 886# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
887# patterns match the file name, INPUT_FILTER is applied. 887# patterns match the file name, INPUT_FILTER is applied.
888 888
889FILTER_PATTERNS = 889FILTER_PATTERNS =
890 890
891# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 891# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
892# INPUT_FILTER ) will also be used to filter the input files that are used for 892# INPUT_FILTER ) will also be used to filter the input files that are used for
@@ -901,14 +901,14 @@ FILTER_SOURCE_FILES = NO
901# *.ext= (so without naming a filter). 901# *.ext= (so without naming a filter).
902# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. 902# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
903 903
904FILTER_SOURCE_PATTERNS = 904FILTER_SOURCE_PATTERNS =
905 905
906# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that 906# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
907# is part of the input, its contents will be placed on the main page 907# is part of the input, its contents will be placed on the main page
908# (index.html). This can be useful if you have a project on for instance GitHub 908# (index.html). This can be useful if you have a project on for instance GitHub
909# and want to reuse the introduction page also for the doxygen output. 909# and want to reuse the introduction page also for the doxygen output.
910 910
911USE_MDFILE_AS_MAINPAGE = 911USE_MDFILE_AS_MAINPAGE =
912 912
913#--------------------------------------------------------------------------- 913#---------------------------------------------------------------------------
914# Configuration options related to source browsing 914# Configuration options related to source browsing
@@ -1013,7 +1013,7 @@ CLANG_ASSISTED_PARSING = NO
1013# specified with INPUT and INCLUDE_PATH. 1013# specified with INPUT and INCLUDE_PATH.
1014# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. 1014# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
1015 1015
1016CLANG_OPTIONS = 1016CLANG_OPTIONS =
1017 1017
1018#--------------------------------------------------------------------------- 1018#---------------------------------------------------------------------------
1019# Configuration options related to the alphabetical class index 1019# Configuration options related to the alphabetical class index
@@ -1039,7 +1039,7 @@ COLS_IN_ALPHA_INDEX = 5
1039# while generating the index headers. 1039# while generating the index headers.
1040# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. 1040# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
1041 1041
1042IGNORE_PREFIX = 1042IGNORE_PREFIX =
1043 1043
1044#--------------------------------------------------------------------------- 1044#---------------------------------------------------------------------------
1045# Configuration options related to the HTML output 1045# Configuration options related to the HTML output
@@ -1083,7 +1083,7 @@ HTML_FILE_EXTENSION = .html
1083# of the possible markers and block names see the documentation. 1083# of the possible markers and block names see the documentation.
1084# This tag requires that the tag GENERATE_HTML is set to YES. 1084# This tag requires that the tag GENERATE_HTML is set to YES.
1085 1085
1086HTML_HEADER = 1086HTML_HEADER =
1087 1087
1088# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each 1088# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
1089# generated HTML page. If the tag is left blank doxygen will generate a standard 1089# generated HTML page. If the tag is left blank doxygen will generate a standard
@@ -1093,7 +1093,7 @@ HTML_HEADER =
1093# that doxygen normally uses. 1093# that doxygen normally uses.
1094# This tag requires that the tag GENERATE_HTML is set to YES. 1094# This tag requires that the tag GENERATE_HTML is set to YES.
1095 1095
1096HTML_FOOTER = 1096HTML_FOOTER =
1097 1097
1098# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style 1098# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
1099# sheet that is used by each HTML page. It can be used to fine-tune the look of 1099# sheet that is used by each HTML page. It can be used to fine-tune the look of
@@ -1105,7 +1105,7 @@ HTML_FOOTER =
1105# obsolete. 1105# obsolete.
1106# This tag requires that the tag GENERATE_HTML is set to YES. 1106# This tag requires that the tag GENERATE_HTML is set to YES.
1107 1107
1108HTML_STYLESHEET = 1108HTML_STYLESHEET =
1109 1109
1110# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined 1110# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
1111# cascading style sheets that are included after the standard style sheets 1111# cascading style sheets that are included after the standard style sheets
@@ -1118,7 +1118,7 @@ HTML_STYLESHEET =
1118# list). For an example see the documentation. 1118# list). For an example see the documentation.
1119# This tag requires that the tag GENERATE_HTML is set to YES. 1119# This tag requires that the tag GENERATE_HTML is set to YES.
1120 1120
1121HTML_EXTRA_STYLESHEET = 1121HTML_EXTRA_STYLESHEET =
1122 1122
1123# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or 1123# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
1124# other source files which should be copied to the HTML output directory. Note 1124# other source files which should be copied to the HTML output directory. Note
@@ -1128,7 +1128,7 @@ HTML_EXTRA_STYLESHEET =
1128# files will be copied as-is; there are no commands or markers available. 1128# files will be copied as-is; there are no commands or markers available.
1129# This tag requires that the tag GENERATE_HTML is set to YES. 1129# This tag requires that the tag GENERATE_HTML is set to YES.
1130 1130
1131HTML_EXTRA_FILES = 1131HTML_EXTRA_FILES =
1132 1132
1133# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen 1133# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
1134# will adjust the colors in the stylesheet and background images according to 1134# will adjust the colors in the stylesheet and background images according to
@@ -1256,7 +1256,7 @@ GENERATE_HTMLHELP = NO
1256# written to the html output directory. 1256# written to the html output directory.
1257# This tag requires that the tag GENERATE_HTMLHELP is set to YES. 1257# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
1258 1258
1259CHM_FILE = 1259CHM_FILE =
1260 1260
1261# The HHC_LOCATION tag can be used to specify the location (absolute path 1261# The HHC_LOCATION tag can be used to specify the location (absolute path
1262# including file name) of the HTML help compiler ( hhc.exe). If non-empty 1262# including file name) of the HTML help compiler ( hhc.exe). If non-empty
@@ -1264,7 +1264,7 @@ CHM_FILE =
1264# The file has to be specified with full path. 1264# The file has to be specified with full path.
1265# This tag requires that the tag GENERATE_HTMLHELP is set to YES. 1265# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
1266 1266
1267HHC_LOCATION = 1267HHC_LOCATION =
1268 1268
1269# The GENERATE_CHI flag controls if a separate .chi index file is generated ( 1269# The GENERATE_CHI flag controls if a separate .chi index file is generated (
1270# YES) or that it should be included in the master .chm file ( NO). 1270# YES) or that it should be included in the master .chm file ( NO).
@@ -1277,7 +1277,7 @@ GENERATE_CHI = NO
1277# and project file content. 1277# and project file content.
1278# This tag requires that the tag GENERATE_HTMLHELP is set to YES. 1278# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
1279 1279
1280CHM_INDEX_ENCODING = 1280CHM_INDEX_ENCODING =
1281 1281
1282# The BINARY_TOC flag controls whether a binary table of contents is generated ( 1282# The BINARY_TOC flag controls whether a binary table of contents is generated (
1283# YES) or a normal table of contents ( NO) in the .chm file. Furthermore it 1283# YES) or a normal table of contents ( NO) in the .chm file. Furthermore it
@@ -1308,7 +1308,7 @@ GENERATE_QHP = NO
1308# the HTML output folder. 1308# the HTML output folder.
1309# This tag requires that the tag GENERATE_QHP is set to YES. 1309# This tag requires that the tag GENERATE_QHP is set to YES.
1310 1310
1311QCH_FILE = 1311QCH_FILE =
1312 1312
1313# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help 1313# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
1314# Project output. For more information please see Qt Help Project / Namespace 1314# Project output. For more information please see Qt Help Project / Namespace
@@ -1333,7 +1333,7 @@ QHP_VIRTUAL_FOLDER = doc
1333# filters). 1333# filters).
1334# This tag requires that the tag GENERATE_QHP is set to YES. 1334# This tag requires that the tag GENERATE_QHP is set to YES.
1335 1335
1336QHP_CUST_FILTER_NAME = 1336QHP_CUST_FILTER_NAME =
1337 1337
1338# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the 1338# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
1339# custom filter to add. For more information please see Qt Help Project / Custom 1339# custom filter to add. For more information please see Qt Help Project / Custom
@@ -1341,21 +1341,21 @@ QHP_CUST_FILTER_NAME =
1341# filters). 1341# filters).
1342# This tag requires that the tag GENERATE_QHP is set to YES. 1342# This tag requires that the tag GENERATE_QHP is set to YES.
1343 1343
1344QHP_CUST_FILTER_ATTRS = 1344QHP_CUST_FILTER_ATTRS =
1345 1345
1346# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this 1346# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
1347# project's filter section matches. Qt Help Project / Filter Attributes (see: 1347# project's filter section matches. Qt Help Project / Filter Attributes (see:
1348# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). 1348# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
1349# This tag requires that the tag GENERATE_QHP is set to YES. 1349# This tag requires that the tag GENERATE_QHP is set to YES.
1350 1350
1351QHP_SECT_FILTER_ATTRS = 1351QHP_SECT_FILTER_ATTRS =
1352 1352
1353# The QHG_LOCATION tag can be used to specify the location of Qt's 1353# The QHG_LOCATION tag can be used to specify the location of Qt's
1354# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the 1354# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
1355# generated .qhp file. 1355# generated .qhp file.
1356# This tag requires that the tag GENERATE_QHP is set to YES. 1356# This tag requires that the tag GENERATE_QHP is set to YES.
1357 1357
1358QHG_LOCATION = 1358QHG_LOCATION =
1359 1359
1360# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be 1360# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
1361# generated, together with the HTML files, they form an Eclipse help plugin. To 1361# generated, together with the HTML files, they form an Eclipse help plugin. To
@@ -1488,7 +1488,7 @@ MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
1488# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols 1488# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
1489# This tag requires that the tag USE_MATHJAX is set to YES. 1489# This tag requires that the tag USE_MATHJAX is set to YES.
1490 1490
1491MATHJAX_EXTENSIONS = 1491MATHJAX_EXTENSIONS =
1492 1492
1493# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces 1493# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
1494# of code that will be used on startup of the MathJax code. See the MathJax site 1494# of code that will be used on startup of the MathJax code. See the MathJax site
@@ -1496,7 +1496,7 @@ MATHJAX_EXTENSIONS =
1496# example see the documentation. 1496# example see the documentation.
1497# This tag requires that the tag USE_MATHJAX is set to YES. 1497# This tag requires that the tag USE_MATHJAX is set to YES.
1498 1498
1499MATHJAX_CODEFILE = 1499MATHJAX_CODEFILE =
1500 1500
1501# When the SEARCHENGINE tag is enabled doxygen will generate a search box for 1501# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
1502# the HTML output. The underlying search engine uses javascript and DHTML and 1502# the HTML output. The underlying search engine uses javascript and DHTML and
@@ -1556,7 +1556,7 @@ EXTERNAL_SEARCH = NO
1556# Searching" for details. 1556# Searching" for details.
1557# This tag requires that the tag SEARCHENGINE is set to YES. 1557# This tag requires that the tag SEARCHENGINE is set to YES.
1558 1558
1559SEARCHENGINE_URL = 1559SEARCHENGINE_URL =
1560 1560
1561# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed 1561# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
1562# search data is written to a file for indexing by an external tool. With the 1562# search data is written to a file for indexing by an external tool. With the
@@ -1572,7 +1572,7 @@ SEARCHDATA_FILE = searchdata.xml
1572# projects and redirect the results back to the right project. 1572# projects and redirect the results back to the right project.
1573# This tag requires that the tag SEARCHENGINE is set to YES. 1573# This tag requires that the tag SEARCHENGINE is set to YES.
1574 1574
1575EXTERNAL_SEARCH_ID = 1575EXTERNAL_SEARCH_ID =
1576 1576
1577# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen 1577# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
1578# projects other than the one defined by this configuration file, but that are 1578# projects other than the one defined by this configuration file, but that are
@@ -1582,7 +1582,7 @@ EXTERNAL_SEARCH_ID =
1582# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... 1582# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
1583# This tag requires that the tag SEARCHENGINE is set to YES. 1583# This tag requires that the tag SEARCHENGINE is set to YES.
1584 1584
1585EXTRA_SEARCH_MAPPINGS = 1585EXTRA_SEARCH_MAPPINGS =
1586 1586
1587#--------------------------------------------------------------------------- 1587#---------------------------------------------------------------------------
1588# Configuration options related to the LaTeX output 1588# Configuration options related to the LaTeX output
@@ -1643,7 +1643,7 @@ PAPER_TYPE = a4
1643# If left blank no extra packages will be included. 1643# If left blank no extra packages will be included.
1644# This tag requires that the tag GENERATE_LATEX is set to YES. 1644# This tag requires that the tag GENERATE_LATEX is set to YES.
1645 1645
1646EXTRA_PACKAGES = 1646EXTRA_PACKAGES =
1647 1647
1648# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the 1648# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
1649# generated LaTeX document. The header should contain everything until the first 1649# generated LaTeX document. The header should contain everything until the first
@@ -1659,7 +1659,7 @@ EXTRA_PACKAGES =
1659# HTML_HEADER. 1659# HTML_HEADER.
1660# This tag requires that the tag GENERATE_LATEX is set to YES. 1660# This tag requires that the tag GENERATE_LATEX is set to YES.
1661 1661
1662LATEX_HEADER = 1662LATEX_HEADER =
1663 1663
1664# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the 1664# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
1665# generated LaTeX document. The footer should contain everything after the last 1665# generated LaTeX document. The footer should contain everything after the last
@@ -1670,7 +1670,7 @@ LATEX_HEADER =
1670# Note: Only use a user-defined footer if you know what you are doing! 1670# Note: Only use a user-defined footer if you know what you are doing!
1671# This tag requires that the tag GENERATE_LATEX is set to YES. 1671# This tag requires that the tag GENERATE_LATEX is set to YES.
1672 1672
1673LATEX_FOOTER = 1673LATEX_FOOTER =
1674 1674
1675# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or 1675# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
1676# other source files which should be copied to the LATEX_OUTPUT output 1676# other source files which should be copied to the LATEX_OUTPUT output
@@ -1678,7 +1678,7 @@ LATEX_FOOTER =
1678# markers available. 1678# markers available.
1679# This tag requires that the tag GENERATE_LATEX is set to YES. 1679# This tag requires that the tag GENERATE_LATEX is set to YES.
1680 1680
1681LATEX_EXTRA_FILES = 1681LATEX_EXTRA_FILES =
1682 1682
1683# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is 1683# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
1684# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will 1684# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
@@ -1778,14 +1778,14 @@ RTF_HYPERLINKS = NO
1778# default style sheet that doxygen normally uses. 1778# default style sheet that doxygen normally uses.
1779# This tag requires that the tag GENERATE_RTF is set to YES. 1779# This tag requires that the tag GENERATE_RTF is set to YES.
1780 1780
1781RTF_STYLESHEET_FILE = 1781RTF_STYLESHEET_FILE =
1782 1782
1783# Set optional variables used in the generation of an RTF document. Syntax is 1783# Set optional variables used in the generation of an RTF document. Syntax is
1784# similar to doxygen's config file. A template extensions file can be generated 1784# similar to doxygen's config file. A template extensions file can be generated
1785# using doxygen -e rtf extensionFile. 1785# using doxygen -e rtf extensionFile.
1786# This tag requires that the tag GENERATE_RTF is set to YES. 1786# This tag requires that the tag GENERATE_RTF is set to YES.
1787 1787
1788RTF_EXTENSIONS_FILE = 1788RTF_EXTENSIONS_FILE =
1789 1789
1790#--------------------------------------------------------------------------- 1790#---------------------------------------------------------------------------
1791# Configuration options related to the man page output 1791# Configuration options related to the man page output
@@ -1820,7 +1820,7 @@ MAN_EXTENSION = .3
1820# MAN_EXTENSION with the initial . removed. 1820# MAN_EXTENSION with the initial . removed.
1821# This tag requires that the tag GENERATE_MAN is set to YES. 1821# This tag requires that the tag GENERATE_MAN is set to YES.
1822 1822
1823MAN_SUBDIR = 1823MAN_SUBDIR =
1824 1824
1825# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it 1825# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
1826# will generate one additional man file for each entity documented in the real 1826# will generate one additional man file for each entity documented in the real
@@ -1933,7 +1933,7 @@ PERLMOD_PRETTY = YES
1933# overwrite each other's variables. 1933# overwrite each other's variables.
1934# This tag requires that the tag GENERATE_PERLMOD is set to YES. 1934# This tag requires that the tag GENERATE_PERLMOD is set to YES.
1935 1935
1936PERLMOD_MAKEVAR_PREFIX = 1936PERLMOD_MAKEVAR_PREFIX =
1937 1937
1938#--------------------------------------------------------------------------- 1938#---------------------------------------------------------------------------
1939# Configuration options related to the preprocessor 1939# Configuration options related to the preprocessor
@@ -1974,7 +1974,7 @@ SEARCH_INCLUDES = YES
1974# preprocessor. 1974# preprocessor.
1975# This tag requires that the tag SEARCH_INCLUDES is set to YES. 1975# This tag requires that the tag SEARCH_INCLUDES is set to YES.
1976 1976
1977INCLUDE_PATH = 1977INCLUDE_PATH =
1978 1978
1979# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 1979# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
1980# patterns (like *.h and *.hpp) to filter out the header-files in the 1980# patterns (like *.h and *.hpp) to filter out the header-files in the
@@ -1982,7 +1982,7 @@ INCLUDE_PATH =
1982# used. 1982# used.
1983# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. 1983# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
1984 1984
1985INCLUDE_FILE_PATTERNS = 1985INCLUDE_FILE_PATTERNS =
1986 1986
1987# The PREDEFINED tag can be used to specify one or more macro names that are 1987# The PREDEFINED tag can be used to specify one or more macro names that are
1988# defined before the preprocessor is started (similar to the -D option of e.g. 1988# defined before the preprocessor is started (similar to the -D option of e.g.
@@ -1992,7 +1992,7 @@ INCLUDE_FILE_PATTERNS =
1992# recursively expanded use the := operator instead of the = operator. 1992# recursively expanded use the := operator instead of the = operator.
1993# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. 1993# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
1994 1994
1995PREDEFINED = 1995PREDEFINED =
1996 1996
1997# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this 1997# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
1998# tag can be used to specify a list of macro names that should be expanded. The 1998# tag can be used to specify a list of macro names that should be expanded. The
@@ -2001,7 +2001,7 @@ PREDEFINED =
2001# definition found in the source code. 2001# definition found in the source code.
2002# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. 2002# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
2003 2003
2004EXPAND_AS_DEFINED = 2004EXPAND_AS_DEFINED =
2005 2005
2006# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will 2006# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
2007# remove all references to function-like macros that are alone on a line, have 2007# remove all references to function-like macros that are alone on a line, have
@@ -2030,13 +2030,13 @@ SKIP_FUNCTION_MACROS = YES
2030# the path). If a tag file is not located in the directory in which doxygen is 2030# the path). If a tag file is not located in the directory in which doxygen is
2031# run, you must also specify the path to the tagfile here. 2031# run, you must also specify the path to the tagfile here.
2032 2032
2033TAGFILES = 2033TAGFILES =
2034 2034
2035# When a file name is specified after GENERATE_TAGFILE, doxygen will create a 2035# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
2036# tag file that is based on the input files it reads. See section "Linking to 2036# tag file that is based on the input files it reads. See section "Linking to
2037# external documentation" for more information about the usage of tag files. 2037# external documentation" for more information about the usage of tag files.
2038 2038
2039GENERATE_TAGFILE = 2039GENERATE_TAGFILE =
2040 2040
2041# If the ALLEXTERNALS tag is set to YES all external class will be listed in the 2041# If the ALLEXTERNALS tag is set to YES all external class will be listed in the
2042# class index. If set to NO only the inherited external classes will be listed. 2042# class index. If set to NO only the inherited external classes will be listed.
@@ -2084,14 +2084,14 @@ CLASS_DIAGRAMS = YES
2084# the mscgen tool resides. If left empty the tool is assumed to be found in the 2084# the mscgen tool resides. If left empty the tool is assumed to be found in the
2085# default search path. 2085# default search path.
2086 2086
2087MSCGEN_PATH = 2087MSCGEN_PATH =
2088 2088
2089# You can include diagrams made with dia in doxygen documentation. Doxygen will 2089# You can include diagrams made with dia in doxygen documentation. Doxygen will
2090# then run dia to produce the diagram and insert it in the documentation. The 2090# then run dia to produce the diagram and insert it in the documentation. The
2091# DIA_PATH tag allows you to specify the directory where the dia binary resides. 2091# DIA_PATH tag allows you to specify the directory where the dia binary resides.
2092# If left empty dia is assumed to be found in the default search path. 2092# If left empty dia is assumed to be found in the default search path.
2093 2093
2094DIA_PATH = 2094DIA_PATH =
2095 2095
2096# If set to YES, the inheritance and collaboration graphs will hide inheritance 2096# If set to YES, the inheritance and collaboration graphs will hide inheritance
2097# and usage relations if the target is undocumented or is not a class. 2097# and usage relations if the target is undocumented or is not a class.
@@ -2140,7 +2140,7 @@ DOT_FONTSIZE = 10
2140# the path where dot can find it using this tag. 2140# the path where dot can find it using this tag.
2141# This tag requires that the tag HAVE_DOT is set to YES. 2141# This tag requires that the tag HAVE_DOT is set to YES.
2142 2142
2143DOT_FONTPATH = 2143DOT_FONTPATH =
2144 2144
2145# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for 2145# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
2146# each documented class showing the direct and indirect inheritance relations. 2146# each documented class showing the direct and indirect inheritance relations.
@@ -2278,26 +2278,26 @@ INTERACTIVE_SVG = NO
2278# found. If left blank, it is assumed the dot tool can be found in the path. 2278# found. If left blank, it is assumed the dot tool can be found in the path.
2279# This tag requires that the tag HAVE_DOT is set to YES. 2279# This tag requires that the tag HAVE_DOT is set to YES.
2280 2280
2281DOT_PATH = 2281DOT_PATH =
2282 2282
2283# The DOTFILE_DIRS tag can be used to specify one or more directories that 2283# The DOTFILE_DIRS tag can be used to specify one or more directories that
2284# contain dot files that are included in the documentation (see the \dotfile 2284# contain dot files that are included in the documentation (see the \dotfile
2285# command). 2285# command).
2286# This tag requires that the tag HAVE_DOT is set to YES. 2286# This tag requires that the tag HAVE_DOT is set to YES.
2287 2287
2288DOTFILE_DIRS = 2288DOTFILE_DIRS =
2289 2289
2290# The MSCFILE_DIRS tag can be used to specify one or more directories that 2290# The MSCFILE_DIRS tag can be used to specify one or more directories that
2291# contain msc files that are included in the documentation (see the \mscfile 2291# contain msc files that are included in the documentation (see the \mscfile
2292# command). 2292# command).
2293 2293
2294MSCFILE_DIRS = 2294MSCFILE_DIRS =
2295 2295
2296# The DIAFILE_DIRS tag can be used to specify one or more directories that 2296# The DIAFILE_DIRS tag can be used to specify one or more directories that
2297# contain dia files that are included in the documentation (see the \diafile 2297# contain dia files that are included in the documentation (see the \diafile
2298# command). 2298# command).
2299 2299
2300DIAFILE_DIRS = 2300DIAFILE_DIRS =
2301 2301
2302# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the 2302# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
2303# path where java can find the plantuml.jar file. If left blank, it is assumed 2303# path where java can find the plantuml.jar file. If left blank, it is assumed
@@ -2306,7 +2306,7 @@ DIAFILE_DIRS =
2306# will not generate output for the diagram. 2306# will not generate output for the diagram.
2307# This tag requires that the tag HAVE_DOT is set to YES. 2307# This tag requires that the tag HAVE_DOT is set to YES.
2308 2308
2309PLANTUML_JAR_PATH = 2309PLANTUML_JAR_PATH =
2310 2310
2311# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes 2311# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
2312# that will be shown in the graph. If the number of nodes in a graph becomes 2312# that will be shown in the graph. If the number of nodes in a graph becomes
diff --git a/README.md b/README.md
index f420beb09..71d19784e 100644
--- a/README.md
+++ b/README.md
@@ -28,5 +28,5 @@ If you like, you can [donate by PayPal](https://www.paypal.com/cgi-bin/webscr?cm
28* Infrastructure setup 28* Infrastructure setup
29* Eventually 3D displays to get proper 3D output working 29* Eventually 3D displays to get proper 3D output working
30* ... etc ... 30* ... etc ...
31 31
32We also more than gladly accept used 3DS consoles, preferrably ones with firmware 4.5 or lower! If you would like to give yours away, don't hesitate to join our IRC channel #citra on [Freenode](http://webchat.freenode.net/?channels=citra) and talk to neobrain or bunnei. Mind you, IRC is slow-paced, so it might be a while until people reply. If you're in a hurry you can just leave contact details in the channel or via private message and we'll get back to you. 32We also more than gladly accept used 3DS consoles, preferrably ones with firmware 4.5 or lower! If you would like to give yours away, don't hesitate to join our IRC channel #citra on [Freenode](http://webchat.freenode.net/?channels=citra) and talk to neobrain or bunnei. Mind you, IRC is slow-paced, so it might be a while until people reply. If you're in a hurry you can just leave contact details in the channel or via private message and we'll get back to you.
diff --git a/appveyor.yml b/appveyor.yml
index f2b656729..aef2d6f73 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -33,18 +33,22 @@ after_build:
33 $GITREV = $(git show -s --format='%h') 33 $GITREV = $(git show -s --format='%h')
34 # Where are these spaces coming from? Regardless, let's remove them 34 # Where are these spaces coming from? Regardless, let's remove them
35 $BUILD_NAME = "citra-${GITDATE}-${GITREV}-windows-amd64.7z" -replace " ","" 35 $BUILD_NAME = "citra-${GITDATE}-${GITREV}-windows-amd64.7z" -replace " ",""
36 $BUILD_NAME_NOQT = "citra-noqt-${GITDATE}-${GITREV}-windows-amd64.7z" -replace " ",""
36 # Zip up the build folder 37 # Zip up the build folder
37 7z a $BUILD_NAME .\build\bin\release\* 38 7z a $BUILD_NAME .\build\bin\release\*
38 39 # Do a second archive with only the binaries
40 7z a $BUILD_NAME_NOQT .\build\bin\release\*.exe
41
39 # Download winscp 42 # Download winscp
40 Invoke-WebRequest "http://hivelocity.dl.sourceforge.net/project/winscp/WinSCP/5.7/winscp570.zip" -OutFile "winscp570.zip" 43 Invoke-WebRequest "http://iweb.dl.sourceforge.net/project/winscp/WinSCP/5.7.3/winscp573.zip" -OutFile "winscp573.zip"
41 7z e -y winscp570.zip 44 7z e -y winscp573.zip
42 45
43 # Upload to server 46 # Upload to server
44 .\WinSCP.com /command ` 47 .\WinSCP.com /command `
45 "option batch abort" ` 48 "option batch abort" `
46 "option confirm off" ` 49 "option confirm off" `
47 "open sftp://citra-builds:${env:BUILD_PASSWORD}@builds.citra-emu.org -hostkey=*" ` 50 "open sftp://citra-builds:${env:BUILD_PASSWORD}@builds.citra-emu.org -hostkey=*" `
48 "put $BUILD_NAME /citra/nightly/windows-amd64/" ` 51 "put $BUILD_NAME /citra/nightly/windows-amd64/" `
52 "put $BUILD_NAME_NOQT /citra/nightly/windows-noqt-amd64/" `
49 "exit" 53 "exit"
50 } 54 }
diff --git a/src/assets/citra.ico b/dist/citra.ico
index 4fef651e2..4fef651e2 100644
--- a/src/assets/citra.ico
+++ b/dist/citra.ico
Binary files differ
diff --git a/doc-icon.png b/dist/doc-icon.png
index 420b1546f..420b1546f 100644
--- a/doc-icon.png
+++ b/dist/doc-icon.png
Binary files differ
diff --git a/externals/glfw-3.0.4.bin/include/GLFW/glfw3native.h b/externals/glfw-3.0.4.bin/include/GLFW/glfw3native.h
deleted file mode 100644
index d570f5876..000000000
--- a/externals/glfw-3.0.4.bin/include/GLFW/glfw3native.h
+++ /dev/null
@@ -1,180 +0,0 @@
1/*************************************************************************
2 * GLFW 3.0 - www.glfw.org
3 * A library for OpenGL, window and input
4 *------------------------------------------------------------------------
5 * Copyright (c) 2002-2006 Marcus Geelnard
6 * Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
7 *
8 * This software is provided 'as-is', without any express or implied
9 * warranty. In no event will the authors be held liable for any damages
10 * arising from the use of this software.
11 *
12 * Permission is granted to anyone to use this software for any purpose,
13 * including commercial applications, and to alter it and redistribute it
14 * freely, subject to the following restrictions:
15 *
16 * 1. The origin of this software must not be misrepresented; you must not
17 * claim that you wrote the original software. If you use this software
18 * in a product, an acknowledgment in the product documentation would
19 * be appreciated but is not required.
20 *
21 * 2. Altered source versions must be plainly marked as such, and must not
22 * be misrepresented as being the original software.
23 *
24 * 3. This notice may not be removed or altered from any source
25 * distribution.
26 *
27 *************************************************************************/
28
29#ifndef _glfw3_native_h_
30#define _glfw3_native_h_
31
32#ifdef __cplusplus
33extern "C" {
34#endif
35
36
37/*************************************************************************
38 * Doxygen documentation
39 *************************************************************************/
40
41/*! @defgroup native Native access
42 *
43 * **By using the native API, you assert that you know what you're doing and
44 * how to fix problems caused by using it. If you don't, you shouldn't be
45 * using it.**
46 *
47 * Before the inclusion of @ref glfw3native.h, you must define exactly one
48 * window API macro and exactly one context API macro. Failure to do this
49 * will cause a compile-time error.
50 *
51 * The available window API macros are:
52 * * `GLFW_EXPOSE_NATIVE_WIN32`
53 * * `GLFW_EXPOSE_NATIVE_COCOA`
54 * * `GLFW_EXPOSE_NATIVE_X11`
55 *
56 * The available context API macros are:
57 * * `GLFW_EXPOSE_NATIVE_WGL`
58 * * `GLFW_EXPOSE_NATIVE_NSGL`
59 * * `GLFW_EXPOSE_NATIVE_GLX`
60 * * `GLFW_EXPOSE_NATIVE_EGL`
61 *
62 * These macros select which of the native access functions that are declared
63 * and which platform-specific headers to include. It is then up your (by
64 * definition platform-specific) code to handle which of these should be
65 * defined.
66 */
67
68
69/*************************************************************************
70 * System headers and types
71 *************************************************************************/
72
73#if defined(GLFW_EXPOSE_NATIVE_WIN32)
74 #include <windows.h>
75#elif defined(GLFW_EXPOSE_NATIVE_COCOA)
76 #if defined(__OBJC__)
77 #import <Cocoa/Cocoa.h>
78 #else
79 typedef void* id;
80 #endif
81#elif defined(GLFW_EXPOSE_NATIVE_X11)
82 #include <X11/Xlib.h>
83#else
84 #error "No window API specified"
85#endif
86
87#if defined(GLFW_EXPOSE_NATIVE_WGL)
88 /* WGL is declared by windows.h */
89#elif defined(GLFW_EXPOSE_NATIVE_NSGL)
90 /* NSGL is declared by Cocoa.h */
91#elif defined(GLFW_EXPOSE_NATIVE_GLX)
92 #include <GL/glx.h>
93#elif defined(GLFW_EXPOSE_NATIVE_EGL)
94 #include <EGL/egl.h>
95#else
96 #error "No context API specified"
97#endif
98
99
100/*************************************************************************
101 * Functions
102 *************************************************************************/
103
104#if defined(GLFW_EXPOSE_NATIVE_WIN32)
105/*! @brief Returns the `HWND` of the specified window.
106 * @return The `HWND` of the specified window.
107 * @ingroup native
108 */
109GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window);
110#endif
111
112#if defined(GLFW_EXPOSE_NATIVE_WGL)
113/*! @brief Returns the `HGLRC` of the specified window.
114 * @return The `HGLRC` of the specified window.
115 * @ingroup native
116 */
117GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window);
118#endif
119
120#if defined(GLFW_EXPOSE_NATIVE_COCOA)
121/*! @brief Returns the `NSWindow` of the specified window.
122 * @return The `NSWindow` of the specified window.
123 * @ingroup native
124 */
125GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window);
126#endif
127
128#if defined(GLFW_EXPOSE_NATIVE_NSGL)
129/*! @brief Returns the `NSOpenGLContext` of the specified window.
130 * @return The `NSOpenGLContext` of the specified window.
131 * @ingroup native
132 */
133GLFWAPI id glfwGetNSGLContext(GLFWwindow* window);
134#endif
135
136#if defined(GLFW_EXPOSE_NATIVE_X11)
137/*! @brief Returns the `Display` used by GLFW.
138 * @return The `Display` used by GLFW.
139 * @ingroup native
140 */
141GLFWAPI Display* glfwGetX11Display(void);
142/*! @brief Returns the `Window` of the specified window.
143 * @return The `Window` of the specified window.
144 * @ingroup native
145 */
146GLFWAPI Window glfwGetX11Window(GLFWwindow* window);
147#endif
148
149#if defined(GLFW_EXPOSE_NATIVE_GLX)
150/*! @brief Returns the `GLXContext` of the specified window.
151 * @return The `GLXContext` of the specified window.
152 * @ingroup native
153 */
154GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window);
155#endif
156
157#if defined(GLFW_EXPOSE_NATIVE_EGL)
158/*! @brief Returns the `EGLDisplay` used by GLFW.
159 * @return The `EGLDisplay` used by GLFW.
160 * @ingroup native
161 */
162GLFWAPI EGLDisplay glfwGetEGLDisplay(void);
163/*! @brief Returns the `EGLContext` of the specified window.
164 * @return The `EGLContext` of the specified window.
165 * @ingroup native
166 */
167GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window);
168/*! @brief Returns the `EGLSurface` of the specified window.
169 * @return The `EGLSurface` of the specified window.
170 * @ingroup native
171 */
172GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window);
173#endif
174
175#ifdef __cplusplus
176}
177#endif
178
179#endif /* _glfw3_native_h_ */
180
diff --git a/externals/glfw-3.0.4.bin/lib-mingw-i686/glfw3.dll b/externals/glfw-3.0.4.bin/lib-mingw-i686/glfw3.dll
deleted file mode 100644
index 5941d1a0a..000000000
--- a/externals/glfw-3.0.4.bin/lib-mingw-i686/glfw3.dll
+++ /dev/null
Binary files differ
diff --git a/externals/glfw-3.0.4.bin/lib-mingw-i686/libglfw3.a b/externals/glfw-3.0.4.bin/lib-mingw-i686/libglfw3.a
deleted file mode 100644
index 7138ee9b5..000000000
--- a/externals/glfw-3.0.4.bin/lib-mingw-i686/libglfw3.a
+++ /dev/null
Binary files differ
diff --git a/externals/glfw-3.0.4.bin/lib-mingw-x86_64/glfw3.dll b/externals/glfw-3.0.4.bin/lib-mingw-x86_64/glfw3.dll
deleted file mode 100644
index 49cf94a80..000000000
--- a/externals/glfw-3.0.4.bin/lib-mingw-x86_64/glfw3.dll
+++ /dev/null
Binary files differ
diff --git a/externals/glfw-3.0.4.bin/lib-mingw-x86_64/libglfw3.a b/externals/glfw-3.0.4.bin/lib-mingw-x86_64/libglfw3.a
deleted file mode 100644
index d1ca9a42a..000000000
--- a/externals/glfw-3.0.4.bin/lib-mingw-x86_64/libglfw3.a
+++ /dev/null
Binary files differ
diff --git a/externals/glfw-3.0.4.bin/lib-msvc_v110-Win32/glfw3.dll b/externals/glfw-3.0.4.bin/lib-msvc_v110-Win32/glfw3.dll
deleted file mode 100644
index d66c5dd89..000000000
--- a/externals/glfw-3.0.4.bin/lib-msvc_v110-Win32/glfw3.dll
+++ /dev/null
Binary files differ
diff --git a/externals/glfw-3.0.4.bin/lib-msvc_v110-Win32/glfw3.lib b/externals/glfw-3.0.4.bin/lib-msvc_v110-Win32/glfw3.lib
deleted file mode 100644
index 2f972ab1a..000000000
--- a/externals/glfw-3.0.4.bin/lib-msvc_v110-Win32/glfw3.lib
+++ /dev/null
Binary files differ
diff --git a/externals/glfw-3.0.4.bin/lib-msvc_v110-Win32/glfw3dll.lib b/externals/glfw-3.0.4.bin/lib-msvc_v110-Win32/glfw3dll.lib
deleted file mode 100644
index 365cdbafb..000000000
--- a/externals/glfw-3.0.4.bin/lib-msvc_v110-Win32/glfw3dll.lib
+++ /dev/null
Binary files differ
diff --git a/externals/glfw-3.0.4.bin/lib-msvc_v110-x64/glfw3.dll b/externals/glfw-3.0.4.bin/lib-msvc_v110-x64/glfw3.dll
deleted file mode 100644
index 44e6d49e4..000000000
--- a/externals/glfw-3.0.4.bin/lib-msvc_v110-x64/glfw3.dll
+++ /dev/null
Binary files differ
diff --git a/externals/glfw-3.0.4.bin/lib-msvc_v110-x64/glfw3.lib b/externals/glfw-3.0.4.bin/lib-msvc_v110-x64/glfw3.lib
deleted file mode 100644
index 77757999e..000000000
--- a/externals/glfw-3.0.4.bin/lib-msvc_v110-x64/glfw3.lib
+++ /dev/null
Binary files differ
diff --git a/externals/glfw-3.0.4.bin/lib-msvc_v110-x64/glfw3dll.lib b/externals/glfw-3.0.4.bin/lib-msvc_v110-x64/glfw3dll.lib
deleted file mode 100644
index 20b548406..000000000
--- a/externals/glfw-3.0.4.bin/lib-msvc_v110-x64/glfw3dll.lib
+++ /dev/null
Binary files differ
diff --git a/externals/glfw-3.0.4.bin/lib-msvc_v120-Win32/glfw3.dll b/externals/glfw-3.0.4.bin/lib-msvc_v120-Win32/glfw3.dll
deleted file mode 100644
index e15fc43b4..000000000
--- a/externals/glfw-3.0.4.bin/lib-msvc_v120-Win32/glfw3.dll
+++ /dev/null
Binary files differ
diff --git a/externals/glfw-3.0.4.bin/lib-msvc_v120-Win32/glfw3.lib b/externals/glfw-3.0.4.bin/lib-msvc_v120-Win32/glfw3.lib
deleted file mode 100644
index 071a0ab84..000000000
--- a/externals/glfw-3.0.4.bin/lib-msvc_v120-Win32/glfw3.lib
+++ /dev/null
Binary files differ
diff --git a/externals/glfw-3.0.4.bin/lib-msvc_v120-Win32/glfw3dll.lib b/externals/glfw-3.0.4.bin/lib-msvc_v120-Win32/glfw3dll.lib
deleted file mode 100644
index d0c5ff5e1..000000000
--- a/externals/glfw-3.0.4.bin/lib-msvc_v120-Win32/glfw3dll.lib
+++ /dev/null
Binary files differ
diff --git a/externals/glfw-3.0.4.bin/lib-msvc_v120-x64/glfw3.dll b/externals/glfw-3.0.4.bin/lib-msvc_v120-x64/glfw3.dll
deleted file mode 100644
index 9da042a6b..000000000
--- a/externals/glfw-3.0.4.bin/lib-msvc_v120-x64/glfw3.dll
+++ /dev/null
Binary files differ
diff --git a/externals/glfw-3.0.4.bin/lib-msvc_v120-x64/glfw3.lib b/externals/glfw-3.0.4.bin/lib-msvc_v120-x64/glfw3.lib
deleted file mode 100644
index e2b495ff5..000000000
--- a/externals/glfw-3.0.4.bin/lib-msvc_v120-x64/glfw3.lib
+++ /dev/null
Binary files differ
diff --git a/externals/glfw-3.0.4.bin/lib-msvc_v120-x64/glfw3dll.lib b/externals/glfw-3.0.4.bin/lib-msvc_v120-x64/glfw3dll.lib
deleted file mode 100644
index 3d6e86418..000000000
--- a/externals/glfw-3.0.4.bin/lib-msvc_v120-x64/glfw3dll.lib
+++ /dev/null
Binary files differ
diff --git a/externals/glfw-3.0.4.bin/COPYING.txt b/externals/glfw-3.1.1.bin/COPYING.txt
index b30c70158..b30c70158 100644
--- a/externals/glfw-3.0.4.bin/COPYING.txt
+++ b/externals/glfw-3.1.1.bin/COPYING.txt
diff --git a/externals/glfw-3.0.4.bin/include/GLFW/glfw3.h b/externals/glfw-3.1.1.bin/include/GLFW/glfw3.h
index 0f97738c7..009fa755f 100644
--- a/externals/glfw-3.0.4.bin/include/GLFW/glfw3.h
+++ b/externals/glfw-3.1.1.bin/include/GLFW/glfw3.h
@@ -1,5 +1,5 @@
1/************************************************************************* 1/*************************************************************************
2 * GLFW 3.0 - www.glfw.org 2 * GLFW 3.1 - www.glfw.org
3 * A library for OpenGL, window and input 3 * A library for OpenGL, window and input
4 *------------------------------------------------------------------------ 4 *------------------------------------------------------------------------
5 * Copyright (c) 2002-2006 Marcus Geelnard 5 * Copyright (c) 2002-2006 Marcus Geelnard
@@ -38,23 +38,27 @@ extern "C" {
38 * Doxygen documentation 38 * Doxygen documentation
39 *************************************************************************/ 39 *************************************************************************/
40 40
41/*! @defgroup clipboard Clipboard support
42 */
43/*! @defgroup context Context handling 41/*! @defgroup context Context handling
42 *
43 * This is the reference documentation for context related functions. For more
44 * information, see the @ref context.
44 */ 45 */
45/*! @defgroup error Error handling 46/*! @defgroup init Initialization, version and errors
46 */ 47 *
47/*! @defgroup init Initialization and version information 48 * This is the reference documentation for initialization and termination of
49 * the library, version management and error handling. For more information,
50 * see the @ref intro.
48 */ 51 */
49/*! @defgroup input Input handling 52/*! @defgroup input Input handling
53 *
54 * This is the reference documentation for input related functions and types.
55 * For more information, see the @ref input.
50 */ 56 */
51/*! @defgroup monitor Monitor handling 57/*! @defgroup monitor Monitor handling
52 * 58 *
53 * This is the reference documentation for monitor related functions and types. 59 * This is the reference documentation for monitor related functions and types.
54 * For more information, see the @ref monitor. 60 * For more information, see the @ref monitor.
55 */ 61 */
56/*! @defgroup time Time input
57 */
58/*! @defgroup window Window handling 62/*! @defgroup window Window handling
59 * 63 *
60 * This is the reference documentation for window related functions and types, 64 * This is the reference documentation for window related functions and types,
@@ -64,28 +68,17 @@ extern "C" {
64 68
65 69
66/************************************************************************* 70/*************************************************************************
67 * Global definitions 71 * Compiler- and platform-specific preprocessor work
68 *************************************************************************/ 72 *************************************************************************/
69 73
70/* ------------------- BEGIN SYSTEM/COMPILER SPECIFIC -------------------- */ 74/* If we are we on Windows, we want a single define for it.
71
72/* Please report any problems that you find with your compiler, which may
73 * be solved in this section! There are several compilers that I have not
74 * been able to test this file with yet.
75 *
76 * First: If we are we on Windows, we want a single define for it (_WIN32)
77 * (Note: For Cygwin the compiler flag -mwin32 should be used, but to
78 * make sure that things run smoothly for Cygwin users, we add __CYGWIN__
79 * to the list of "valid Win32 identifiers", which removes the need for
80 * -mwin32)
81 */ 75 */
82#if !defined(_WIN32) && (defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__)) 76#if !defined(_WIN32) && (defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__))
83 #define _WIN32 77 #define _WIN32
84#endif /* _WIN32 */ 78#endif /* _WIN32 */
85 79
86/* In order for extension support to be portable, we need to define an 80/* It is customary to use APIENTRY for OpenGL function pointer declarations on
87 * OpenGL function call method. We use the keyword APIENTRY, which is 81 * all platforms. Additionally, the Windows OpenGL header needs APIENTRY.
88 * defined for Win32. (Note: Windows also needs this for <GL/gl.h>)
89 */ 82 */
90#ifndef APIENTRY 83#ifndef APIENTRY
91 #ifdef _WIN32 84 #ifdef _WIN32
@@ -95,44 +88,23 @@ extern "C" {
95 #endif 88 #endif
96#endif /* APIENTRY */ 89#endif /* APIENTRY */
97 90
98/* The following three defines are here solely to make some Windows-based 91/* Some Windows OpenGL headers need this.
99 * <GL/gl.h> files happy. Theoretically we could include <windows.h>, but
100 * it has the major drawback of severely polluting our namespace.
101 */ 92 */
102
103/* Under Windows, we need WINGDIAPI defined */
104#if !defined(WINGDIAPI) && defined(_WIN32) 93#if !defined(WINGDIAPI) && defined(_WIN32)
105 #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__POCC__) 94 #define WINGDIAPI __declspec(dllimport)
106 /* Microsoft Visual C++, Borland C++ Builder and Pelles C */
107 #define WINGDIAPI __declspec(dllimport)
108 #elif defined(__LCC__)
109 /* LCC-Win32 */
110 #define WINGDIAPI __stdcall
111 #else
112 /* Others (e.g. MinGW, Cygwin) */
113 #define WINGDIAPI extern
114 #endif
115 #define GLFW_WINGDIAPI_DEFINED 95 #define GLFW_WINGDIAPI_DEFINED
116#endif /* WINGDIAPI */ 96#endif /* WINGDIAPI */
117 97
118/* Some <GL/glu.h> files also need CALLBACK defined */ 98/* Some Windows GLU headers need this.
99 */
119#if !defined(CALLBACK) && defined(_WIN32) 100#if !defined(CALLBACK) && defined(_WIN32)
120 #if defined(_MSC_VER) 101 #define CALLBACK __stdcall
121 /* Microsoft Visual C++ */
122 #if (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS)
123 #define CALLBACK __stdcall
124 #else
125 #define CALLBACK
126 #endif
127 #else
128 /* Other Windows compilers */
129 #define CALLBACK __stdcall
130 #endif
131 #define GLFW_CALLBACK_DEFINED 102 #define GLFW_CALLBACK_DEFINED
132#endif /* CALLBACK */ 103#endif /* CALLBACK */
133 104
134/* Most GL/glu.h variants on Windows need wchar_t 105/* Most Windows GLU headers need wchar_t.
135 * OpenGL/gl.h blocks the definition of ptrdiff_t by glext.h on OS X */ 106 * The OS X OpenGL header blocks the definition of ptrdiff_t by glext.h.
107 */
136#if !defined(GLFW_INCLUDE_NONE) 108#if !defined(GLFW_INCLUDE_NONE)
137 #include <stddef.h> 109 #include <stddef.h>
138#endif 110#endif
@@ -140,67 +112,79 @@ extern "C" {
140/* Include the chosen client API headers. 112/* Include the chosen client API headers.
141 */ 113 */
142#if defined(__APPLE_CC__) 114#if defined(__APPLE_CC__)
143 #if defined(GLFW_INCLUDE_GLCOREARB) 115 #if defined(GLFW_INCLUDE_GLCOREARB)
144 #include <OpenGL/gl3.h> 116 #include <OpenGL/gl3.h>
145 #elif !defined(GLFW_INCLUDE_NONE) 117 #if defined(GLFW_INCLUDE_GLEXT)
146 #define GL_GLEXT_LEGACY 118 #include <OpenGL/gl3ext.h>
147 #include <OpenGL/gl.h>
148 #endif 119 #endif
149 #if defined(GLFW_INCLUDE_GLU) 120 #elif !defined(GLFW_INCLUDE_NONE)
150 #include <OpenGL/glu.h> 121 #if !defined(GLFW_INCLUDE_GLEXT)
122 #define GL_GLEXT_LEGACY
151 #endif 123 #endif
124 #include <OpenGL/gl.h>
125 #endif
126 #if defined(GLFW_INCLUDE_GLU)
127 #include <OpenGL/glu.h>
128 #endif
152#else 129#else
153 #if defined(GLFW_INCLUDE_GLCOREARB) 130 #if defined(GLFW_INCLUDE_GLCOREARB)
154 #include <GL/glcorearb.h> 131 #include <GL/glcorearb.h>
155 #elif defined(GLFW_INCLUDE_ES1) 132 #elif defined(GLFW_INCLUDE_ES1)
156 #include <GLES/gl.h> 133 #include <GLES/gl.h>
157 #elif defined(GLFW_INCLUDE_ES2) 134 #if defined(GLFW_INCLUDE_GLEXT)
158 #include <GLES2/gl2.h> 135 #include <GLES/glext.h>
159 #elif defined(GLFW_INCLUDE_ES3) 136 #endif
160 #include <GLES3/gl3.h> 137 #elif defined(GLFW_INCLUDE_ES2)
161 #elif !defined(GLFW_INCLUDE_NONE) 138 #include <GLES2/gl2.h>
162 #include <GL/gl.h> 139 #if defined(GLFW_INCLUDE_GLEXT)
140 #include <GLES2/gl2ext.h>
163 #endif 141 #endif
164 #if defined(GLFW_INCLUDE_GLU) 142 #elif defined(GLFW_INCLUDE_ES3)
165 #include <GL/glu.h> 143 #include <GLES3/gl3.h>
144 #if defined(GLFW_INCLUDE_GLEXT)
145 #include <GLES3/gl2ext.h>
166 #endif 146 #endif
147 #elif defined(GLFW_INCLUDE_ES31)
148 #include <GLES3/gl31.h>
149 #if defined(GLFW_INCLUDE_GLEXT)
150 #include <GLES3/gl2ext.h>
151 #endif
152 #elif !defined(GLFW_INCLUDE_NONE)
153 #include <GL/gl.h>
154 #if defined(GLFW_INCLUDE_GLEXT)
155 #include <GL/glext.h>
156 #endif
157 #endif
158 #if defined(GLFW_INCLUDE_GLU)
159 #include <GL/glu.h>
160 #endif
167#endif 161#endif
168 162
169#if defined(GLFW_DLL) && defined(_GLFW_BUILD_DLL) 163#if defined(GLFW_DLL) && defined(_GLFW_BUILD_DLL)
170 /* GLFW_DLL is defined by users of GLFW when compiling programs that will link 164 /* GLFW_DLL must be defined by applications that are linking against the DLL
171 * to the DLL version of the GLFW library. _GLFW_BUILD_DLL is defined by the 165 * version of the GLFW library. _GLFW_BUILD_DLL is defined by the GLFW
172 * GLFW configuration header when compiling the DLL version of the library. 166 * configuration header when compiling the DLL version of the library.
173 */ 167 */
174 #error "You must not have both GLFW_DLL and _GLFW_BUILD_DLL defined" 168 #error "You may not have both GLFW_DLL and _GLFW_BUILD_DLL defined"
175#endif 169#endif
176 170
171/* GLFWAPI is used to declare public API functions for export
172 * from the DLL / shared library / dynamic library.
173 */
177#if defined(_WIN32) && defined(_GLFW_BUILD_DLL) 174#if defined(_WIN32) && defined(_GLFW_BUILD_DLL)
178 175 /* We are building GLFW as a Win32 DLL */
179 /* We are building a Win32 DLL */
180 #define GLFWAPI __declspec(dllexport) 176 #define GLFWAPI __declspec(dllexport)
181
182#elif defined(_WIN32) && defined(GLFW_DLL) 177#elif defined(_WIN32) && defined(GLFW_DLL)
183 178 /* We are calling GLFW as a Win32 DLL */
184 /* We are calling a Win32 DLL */ 179 #define GLFWAPI __declspec(dllimport)
185 #if defined(__LCC__)
186 #define GLFWAPI extern
187 #else
188 #define GLFWAPI __declspec(dllimport)
189 #endif
190
191#elif defined(__GNUC__) && defined(_GLFW_BUILD_DLL) 180#elif defined(__GNUC__) && defined(_GLFW_BUILD_DLL)
192 181 /* We are building GLFW as a shared / dynamic library */
193 #define GLFWAPI __attribute__((visibility("default"))) 182 #define GLFWAPI __attribute__((visibility("default")))
194
195#else 183#else
196 184 /* We are building or calling GLFW as a static library */
197 /* We are either building/calling a static lib or we are non-win32 */
198 #define GLFWAPI 185 #define GLFWAPI
199
200#endif 186#endif
201 187
202/* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */
203
204 188
205/************************************************************************* 189/*************************************************************************
206 * GLFW API tokens 190 * GLFW API tokens
@@ -220,27 +204,36 @@ extern "C" {
220 * backward-compatible. 204 * backward-compatible.
221 * @ingroup init 205 * @ingroup init
222 */ 206 */
223#define GLFW_VERSION_MINOR 0 207#define GLFW_VERSION_MINOR 1
224/*! @brief The revision number of the GLFW library. 208/*! @brief The revision number of the GLFW library.
225 * 209 *
226 * This is incremented when a bug fix release is made that does not contain any 210 * This is incremented when a bug fix release is made that does not contain any
227 * API changes. 211 * API changes.
228 * @ingroup init 212 * @ingroup init
229 */ 213 */
230#define GLFW_VERSION_REVISION 4 214#define GLFW_VERSION_REVISION 1
231/*! @} */ 215/*! @} */
232 216
233/*! @name Key and button actions 217/*! @name Key and button actions
234 * @{ */ 218 * @{ */
235/*! @brief The key or button was released. 219/*! @brief The key or mouse button was released.
220 *
221 * The key or mouse button was released.
222 *
236 * @ingroup input 223 * @ingroup input
237 */ 224 */
238#define GLFW_RELEASE 0 225#define GLFW_RELEASE 0
239/*! @brief The key or button was pressed. 226/*! @brief The key or mouse button was pressed.
227 *
228 * The key or mouse button was pressed.
229 *
240 * @ingroup input 230 * @ingroup input
241 */ 231 */
242#define GLFW_PRESS 1 232#define GLFW_PRESS 1
243/*! @brief The key was held down until it repeated. 233/*! @brief The key was held down until it repeated.
234 *
235 * The key was held down until it repeated.
236 *
244 * @ingroup input 237 * @ingroup input
245 */ 238 */
246#define GLFW_REPEAT 2 239#define GLFW_REPEAT 2
@@ -248,20 +241,22 @@ extern "C" {
248 241
249/*! @defgroup keys Keyboard keys 242/*! @defgroup keys Keyboard keys
250 * 243 *
251 * These key codes are inspired by the *USB HID Usage Tables v1.12* (p. 53-60), 244 * See [key input](@ref input_key) for how these are used.
252 * but re-arranged to map to 7-bit ASCII for printable keys (function keys are 245 *
253 * put in the 256+ range). 246 * These key codes are inspired by the _USB HID Usage Tables v1.12_ (p. 53-60),
254 * 247 * but re-arranged to map to 7-bit ASCII for printable keys (function keys are
255 * The naming of the key codes follow these rules: 248 * put in the 256+ range).
256 * - The US keyboard layout is used 249 *
257 * - Names of printable alpha-numeric characters are used (e.g. "A", "R", 250 * The naming of the key codes follow these rules:
258 * "3", etc.) 251 * - The US keyboard layout is used
259 * - For non-alphanumeric characters, Unicode:ish names are used (e.g. 252 * - Names of printable alpha-numeric characters are used (e.g. "A", "R",
260 * "COMMA", "LEFT_SQUARE_BRACKET", etc.). Note that some names do not 253 * "3", etc.)
261 * correspond to the Unicode standard (usually for brevity) 254 * - For non-alphanumeric characters, Unicode:ish names are used (e.g.
262 * - Keys that lack a clear US mapping are named "WORLD_x" 255 * "COMMA", "LEFT_SQUARE_BRACKET", etc.). Note that some names do not
263 * - For non-printable keys, custom names are used (e.g. "F4", 256 * correspond to the Unicode standard (usually for brevity)
264 * "BACKSPACE", etc.) 257 * - Keys that lack a clear US mapping are named "WORLD_x"
258 * - For non-printable keys, custom names are used (e.g. "F4",
259 * "BACKSPACE", etc.)
265 * 260 *
266 * @ingroup input 261 * @ingroup input
267 * @{ 262 * @{
@@ -398,6 +393,9 @@ extern "C" {
398/*! @} */ 393/*! @} */
399 394
400/*! @defgroup mods Modifier key flags 395/*! @defgroup mods Modifier key flags
396 *
397 * See [key input](@ref input_key) for how these are used.
398 *
401 * @ingroup input 399 * @ingroup input
402 * @{ */ 400 * @{ */
403 401
@@ -417,6 +415,9 @@ extern "C" {
417/*! @} */ 415/*! @} */
418 416
419/*! @defgroup buttons Mouse buttons 417/*! @defgroup buttons Mouse buttons
418 *
419 * See [mouse button input](@ref input_mouse_button) for how these are used.
420 *
420 * @ingroup input 421 * @ingroup input
421 * @{ */ 422 * @{ */
422#define GLFW_MOUSE_BUTTON_1 0 423#define GLFW_MOUSE_BUTTON_1 0
@@ -434,6 +435,9 @@ extern "C" {
434/*! @} */ 435/*! @} */
435 436
436/*! @defgroup joysticks Joysticks 437/*! @defgroup joysticks Joysticks
438 *
439 * See [joystick input](@ref joystick) for how these are used.
440 *
437 * @ingroup input 441 * @ingroup input
438 * @{ */ 442 * @{ */
439#define GLFW_JOYSTICK_1 0 443#define GLFW_JOYSTICK_1 0
@@ -456,36 +460,131 @@ extern "C" {
456/*! @} */ 460/*! @} */
457 461
458/*! @defgroup errors Error codes 462/*! @defgroup errors Error codes
459 * @ingroup error 463 *
464 * See [error handling](@ref error_handling) for how these are used.
465 *
466 * @ingroup init
460 * @{ */ 467 * @{ */
461/*! @brief GLFW has not been initialized. 468/*! @brief GLFW has not been initialized.
469 *
470 * This occurs if a GLFW function was called that may not be called unless the
471 * library is [initialized](@ref intro_init).
472 *
473 * @par Analysis
474 * Application programmer error. Initialize GLFW before calling any function
475 * that requires initialization.
462 */ 476 */
463#define GLFW_NOT_INITIALIZED 0x00010001 477#define GLFW_NOT_INITIALIZED 0x00010001
464/*! @brief No context is current for this thread. 478/*! @brief No context is current for this thread.
479 *
480 * This occurs if a GLFW function was called that needs and operates on the
481 * current OpenGL or OpenGL ES context but no context is current on the calling
482 * thread. One such function is @ref glfwSwapInterval.
483 *
484 * @par Analysis
485 * Application programmer error. Ensure a context is current before calling
486 * functions that require a current context.
465 */ 487 */
466#define GLFW_NO_CURRENT_CONTEXT 0x00010002 488#define GLFW_NO_CURRENT_CONTEXT 0x00010002
467/*! @brief One of the enum parameters for the function was given an invalid 489/*! @brief One of the arguments to the function was an invalid enum value.
468 * enum. 490 *
491 * One of the arguments to the function was an invalid enum value, for example
492 * requesting [GLFW_RED_BITS](@ref window_hints_fb) with @ref
493 * glfwGetWindowAttrib.
494 *
495 * @par Analysis
496 * Application programmer error. Fix the offending call.
469 */ 497 */
470#define GLFW_INVALID_ENUM 0x00010003 498#define GLFW_INVALID_ENUM 0x00010003
471/*! @brief One of the parameters for the function was given an invalid value. 499/*! @brief One of the arguments to the function was an invalid value.
500 *
501 * One of the arguments to the function was an invalid value, for example
502 * requesting a non-existent OpenGL or OpenGL ES version like 2.7.
503 *
504 * Requesting a valid but unavailable OpenGL or OpenGL ES version will instead
505 * result in a @ref GLFW_VERSION_UNAVAILABLE error.
506 *
507 * @par Analysis
508 * Application programmer error. Fix the offending call.
472 */ 509 */
473#define GLFW_INVALID_VALUE 0x00010004 510#define GLFW_INVALID_VALUE 0x00010004
474/*! @brief A memory allocation failed. 511/*! @brief A memory allocation failed.
512 *
513 * A memory allocation failed.
514 *
515 * @par Analysis
516 * A bug in GLFW or the underlying operating system. Report the bug to our
517 * [issue tracker](https://github.com/glfw/glfw/issues).
475 */ 518 */
476#define GLFW_OUT_OF_MEMORY 0x00010005 519#define GLFW_OUT_OF_MEMORY 0x00010005
477/*! @brief GLFW could not find support for the requested client API on the 520/*! @brief GLFW could not find support for the requested client API on the
478 * system. 521 * system.
522 *
523 * GLFW could not find support for the requested client API on the system. If
524 * emitted by functions other than @ref glfwCreateWindow, no supported client
525 * API was found.
526 *
527 * @par Analysis
528 * The installed graphics driver does not support the requested client API, or
529 * does not support it via the chosen context creation backend. Below are
530 * a few examples.
531 *
532 * @par
533 * Some pre-installed Windows graphics drivers do not support OpenGL. AMD only
534 * supports OpenGL ES via EGL, while Nvidia and Intel only supports it via
535 * a WGL or GLX extension. OS X does not provide OpenGL ES at all. The Mesa
536 * EGL, OpenGL and OpenGL ES libraries do not interface with the Nvidia binary
537 * driver.
479 */ 538 */
480#define GLFW_API_UNAVAILABLE 0x00010006 539#define GLFW_API_UNAVAILABLE 0x00010006
481/*! @brief The requested client API version is not available. 540/*! @brief The requested OpenGL or OpenGL ES version is not available.
541 *
542 * The requested OpenGL or OpenGL ES version (including any requested context
543 * or framebuffer hints) is not available on this machine.
544 *
545 * @par Analysis
546 * The machine does not support your requirements. If your application is
547 * sufficiently flexible, downgrade your requirements and try again.
548 * Otherwise, inform the user that their machine does not match your
549 * requirements.
550 *
551 * @par
552 * Future invalid OpenGL and OpenGL ES versions, for example OpenGL 4.8 if 5.0
553 * comes out before the 4.x series gets that far, also fail with this error and
554 * not @ref GLFW_INVALID_VALUE, because GLFW cannot know what future versions
555 * will exist.
482 */ 556 */
483#define GLFW_VERSION_UNAVAILABLE 0x00010007 557#define GLFW_VERSION_UNAVAILABLE 0x00010007
484/*! @brief A platform-specific error occurred that does not match any of the 558/*! @brief A platform-specific error occurred that does not match any of the
485 * more specific categories. 559 * more specific categories.
560 *
561 * A platform-specific error occurred that does not match any of the more
562 * specific categories.
563 *
564 * @par Analysis
565 * A bug or configuration error in GLFW, the underlying operating system or
566 * its drivers, or a lack of required resources. Report the issue to our
567 * [issue tracker](https://github.com/glfw/glfw/issues).
486 */ 568 */
487#define GLFW_PLATFORM_ERROR 0x00010008 569#define GLFW_PLATFORM_ERROR 0x00010008
488/*! @brief The clipboard did not contain data in the requested format. 570/*! @brief The requested format is not supported or available.
571 *
572 * If emitted during window creation, the requested pixel format is not
573 * supported.
574 *
575 * If emitted when querying the clipboard, the contents of the clipboard could
576 * not be converted to the requested format.
577 *
578 * @par Analysis
579 * If emitted during window creation, one or more
580 * [hard constraints](@ref window_hints_hard) did not match any of the
581 * available pixel formats. If your application is sufficiently flexible,
582 * downgrade your requirements and try again. Otherwise, inform the user that
583 * their machine does not match your requirements.
584 *
585 * @par
586 * If emitted when querying the clipboard, ignore the error or report it to
587 * the user, as appropriate.
489 */ 588 */
490#define GLFW_FORMAT_UNAVAILABLE 0x00010009 589#define GLFW_FORMAT_UNAVAILABLE 0x00010009
491/*! @} */ 590/*! @} */
@@ -495,6 +594,8 @@ extern "C" {
495#define GLFW_RESIZABLE 0x00020003 594#define GLFW_RESIZABLE 0x00020003
496#define GLFW_VISIBLE 0x00020004 595#define GLFW_VISIBLE 0x00020004
497#define GLFW_DECORATED 0x00020005 596#define GLFW_DECORATED 0x00020005
597#define GLFW_AUTO_ICONIFY 0x00020006
598#define GLFW_FLOATING 0x00020007
498 599
499#define GLFW_RED_BITS 0x00021001 600#define GLFW_RED_BITS 0x00021001
500#define GLFW_GREEN_BITS 0x00021002 601#define GLFW_GREEN_BITS 0x00021002
@@ -511,6 +612,7 @@ extern "C" {
511#define GLFW_SAMPLES 0x0002100D 612#define GLFW_SAMPLES 0x0002100D
512#define GLFW_SRGB_CAPABLE 0x0002100E 613#define GLFW_SRGB_CAPABLE 0x0002100E
513#define GLFW_REFRESH_RATE 0x0002100F 614#define GLFW_REFRESH_RATE 0x0002100F
615#define GLFW_DOUBLEBUFFER 0x00021010
514 616
515#define GLFW_CLIENT_API 0x00022001 617#define GLFW_CLIENT_API 0x00022001
516#define GLFW_CONTEXT_VERSION_MAJOR 0x00022002 618#define GLFW_CONTEXT_VERSION_MAJOR 0x00022002
@@ -520,6 +622,7 @@ extern "C" {
520#define GLFW_OPENGL_FORWARD_COMPAT 0x00022006 622#define GLFW_OPENGL_FORWARD_COMPAT 0x00022006
521#define GLFW_OPENGL_DEBUG_CONTEXT 0x00022007 623#define GLFW_OPENGL_DEBUG_CONTEXT 0x00022007
522#define GLFW_OPENGL_PROFILE 0x00022008 624#define GLFW_OPENGL_PROFILE 0x00022008
625#define GLFW_CONTEXT_RELEASE_BEHAVIOR 0x00022009
523 626
524#define GLFW_OPENGL_API 0x00030001 627#define GLFW_OPENGL_API 0x00030001
525#define GLFW_OPENGL_ES_API 0x00030002 628#define GLFW_OPENGL_ES_API 0x00030002
@@ -540,9 +643,54 @@ extern "C" {
540#define GLFW_CURSOR_HIDDEN 0x00034002 643#define GLFW_CURSOR_HIDDEN 0x00034002
541#define GLFW_CURSOR_DISABLED 0x00034003 644#define GLFW_CURSOR_DISABLED 0x00034003
542 645
646#define GLFW_ANY_RELEASE_BEHAVIOR 0
647#define GLFW_RELEASE_BEHAVIOR_FLUSH 0x00035001
648#define GLFW_RELEASE_BEHAVIOR_NONE 0x00035002
649
650/*! @defgroup shapes Standard cursor shapes
651 *
652 * See [standard cursor creation](@ref cursor_standard) for how these are used.
653 *
654 * @ingroup input
655 * @{ */
656
657/*! @brief The regular arrow cursor shape.
658 *
659 * The regular arrow cursor.
660 */
661#define GLFW_ARROW_CURSOR 0x00036001
662/*! @brief The text input I-beam cursor shape.
663 *
664 * The text input I-beam cursor shape.
665 */
666#define GLFW_IBEAM_CURSOR 0x00036002
667/*! @brief The crosshair shape.
668 *
669 * The crosshair shape.
670 */
671#define GLFW_CROSSHAIR_CURSOR 0x00036003
672/*! @brief The hand shape.
673 *
674 * The hand shape.
675 */
676#define GLFW_HAND_CURSOR 0x00036004
677/*! @brief The horizontal resize arrow shape.
678 *
679 * The horizontal resize arrow shape.
680 */
681#define GLFW_HRESIZE_CURSOR 0x00036005
682/*! @brief The vertical resize arrow shape.
683 *
684 * The vertical resize arrow shape.
685 */
686#define GLFW_VRESIZE_CURSOR 0x00036006
687/*! @} */
688
543#define GLFW_CONNECTED 0x00040001 689#define GLFW_CONNECTED 0x00040001
544#define GLFW_DISCONNECTED 0x00040002 690#define GLFW_DISCONNECTED 0x00040002
545 691
692#define GLFW_DONT_CARE -1
693
546 694
547/************************************************************************* 695/*************************************************************************
548 * GLFW API types 696 * GLFW API types
@@ -573,6 +721,14 @@ typedef struct GLFWmonitor GLFWmonitor;
573 */ 721 */
574typedef struct GLFWwindow GLFWwindow; 722typedef struct GLFWwindow GLFWwindow;
575 723
724/*! @brief Opaque cursor object.
725 *
726 * Opaque cursor object.
727 *
728 * @ingroup cursor
729 */
730typedef struct GLFWcursor GLFWcursor;
731
576/*! @brief The function signature for error callbacks. 732/*! @brief The function signature for error callbacks.
577 * 733 *
578 * This is the function signature for error callback functions. 734 * This is the function signature for error callback functions.
@@ -582,7 +738,7 @@ typedef struct GLFWwindow GLFWwindow;
582 * 738 *
583 * @sa glfwSetErrorCallback 739 * @sa glfwSetErrorCallback
584 * 740 *
585 * @ingroup error 741 * @ingroup init
586 */ 742 */
587typedef void (* GLFWerrorfun)(int,const char*); 743typedef void (* GLFWerrorfun)(int,const char*);
588 744
@@ -590,7 +746,7 @@ typedef void (* GLFWerrorfun)(int,const char*);
590 * 746 *
591 * This is the function signature for window position callback functions. 747 * This is the function signature for window position callback functions.
592 * 748 *
593 * @param[in] window The window that the user moved. 749 * @param[in] window The window that was moved.
594 * @param[in] xpos The new x-coordinate, in screen coordinates, of the 750 * @param[in] xpos The new x-coordinate, in screen coordinates, of the
595 * upper-left corner of the client area of the window. 751 * upper-left corner of the client area of the window.
596 * @param[in] ypos The new y-coordinate, in screen coordinates, of the 752 * @param[in] ypos The new y-coordinate, in screen coordinates, of the
@@ -606,7 +762,7 @@ typedef void (* GLFWwindowposfun)(GLFWwindow*,int,int);
606 * 762 *
607 * This is the function signature for window size callback functions. 763 * This is the function signature for window size callback functions.
608 * 764 *
609 * @param[in] window The window that the user resized. 765 * @param[in] window The window that was resized.
610 * @param[in] width The new width, in screen coordinates, of the window. 766 * @param[in] width The new width, in screen coordinates, of the window.
611 * @param[in] height The new height, in screen coordinates, of the window. 767 * @param[in] height The new height, in screen coordinates, of the window.
612 * 768 *
@@ -644,9 +800,9 @@ typedef void (* GLFWwindowrefreshfun)(GLFWwindow*);
644 * 800 *
645 * This is the function signature for window focus callback functions. 801 * This is the function signature for window focus callback functions.
646 * 802 *
647 * @param[in] window The window that was focused or defocused. 803 * @param[in] window The window that gained or lost input focus.
648 * @param[in] focused `GL_TRUE` if the window was focused, or `GL_FALSE` if 804 * @param[in] focused `GL_TRUE` if the window was given input focus, or
649 * it was defocused. 805 * `GL_FALSE` if it lost it.
650 * 806 *
651 * @sa glfwSetWindowFocusCallback 807 * @sa glfwSetWindowFocusCallback
652 * 808 *
@@ -750,7 +906,7 @@ typedef void (* GLFWscrollfun)(GLFWwindow*,double,double);
750 * @param[in] window The window that received the event. 906 * @param[in] window The window that received the event.
751 * @param[in] key The [keyboard key](@ref keys) that was pressed or released. 907 * @param[in] key The [keyboard key](@ref keys) that was pressed or released.
752 * @param[in] scancode The system-specific scancode of the key. 908 * @param[in] scancode The system-specific scancode of the key.
753 * @param[in] action @ref GLFW_PRESS, @ref GLFW_RELEASE or @ref GLFW_REPEAT. 909 * @param[in] action `GLFW_PRESS`, `GLFW_RELEASE` or `GLFW_REPEAT`.
754 * @param[in] mods Bit field describing which [modifier keys](@ref mods) were 910 * @param[in] mods Bit field describing which [modifier keys](@ref mods) were
755 * held down. 911 * held down.
756 * 912 *
@@ -773,6 +929,38 @@ typedef void (* GLFWkeyfun)(GLFWwindow*,int,int,int,int);
773 */ 929 */
774typedef void (* GLFWcharfun)(GLFWwindow*,unsigned int); 930typedef void (* GLFWcharfun)(GLFWwindow*,unsigned int);
775 931
932/*! @brief The function signature for Unicode character with modifiers
933 * callbacks.
934 *
935 * This is the function signature for Unicode character with modifiers callback
936 * functions. It is called for each input character, regardless of what
937 * modifier keys are held down.
938 *
939 * @param[in] window The window that received the event.
940 * @param[in] codepoint The Unicode code point of the character.
941 * @param[in] mods Bit field describing which [modifier keys](@ref mods) were
942 * held down.
943 *
944 * @sa glfwSetCharModsCallback
945 *
946 * @ingroup input
947 */
948typedef void (* GLFWcharmodsfun)(GLFWwindow*,unsigned int,int);
949
950/*! @brief The function signature for file drop callbacks.
951 *
952 * This is the function signature for file drop callbacks.
953 *
954 * @param[in] window The window that received the event.
955 * @param[in] count The number of dropped files.
956 * @param[in] paths The UTF-8 encoded file and/or directory path names.
957 *
958 * @sa glfwSetDropCallback
959 *
960 * @ingroup input
961 */
962typedef void (* GLFWdropfun)(GLFWwindow*,int,const char**);
963
776/*! @brief The function signature for monitor configuration callbacks. 964/*! @brief The function signature for monitor configuration callbacks.
777 * 965 *
778 * This is the function signature for monitor configuration callback functions. 966 * This is the function signature for monitor configuration callback functions.
@@ -838,6 +1026,21 @@ typedef struct GLFWgammaramp
838 unsigned int size; 1026 unsigned int size;
839} GLFWgammaramp; 1027} GLFWgammaramp;
840 1028
1029/*! @brief Image data.
1030 */
1031typedef struct GLFWimage
1032{
1033 /*! The width, in pixels, of this image.
1034 */
1035 int width;
1036 /*! The height, in pixels, of this image.
1037 */
1038 int height;
1039 /*! The pixel data of this image, arranged left-to-right, top-to-bottom.
1040 */
1041 unsigned char* pixels;
1042} GLFWimage;
1043
841 1044
842/************************************************************************* 1045/*************************************************************************
843 * GLFW API functions 1046 * GLFW API functions
@@ -846,53 +1049,70 @@ typedef struct GLFWgammaramp
846/*! @brief Initializes the GLFW library. 1049/*! @brief Initializes the GLFW library.
847 * 1050 *
848 * This function initializes the GLFW library. Before most GLFW functions can 1051 * This function initializes the GLFW library. Before most GLFW functions can
849 * be used, GLFW must be initialized, and before a program terminates GLFW 1052 * be used, GLFW must be initialized, and before an application terminates GLFW
850 * should be terminated in order to free any resources allocated during or 1053 * should be terminated in order to free any resources allocated during or
851 * after initialization. 1054 * after initialization.
852 * 1055 *
853 * If this function fails, it calls @ref glfwTerminate before returning. If it 1056 * If this function fails, it calls @ref glfwTerminate before returning. If it
854 * succeeds, you should call @ref glfwTerminate before the program exits. 1057 * succeeds, you should call @ref glfwTerminate before the application exits.
855 * 1058 *
856 * Additional calls to this function after successful initialization but before 1059 * Additional calls to this function after successful initialization but before
857 * termination will succeed but will do nothing. 1060 * termination will return `GL_TRUE` immediately.
858 * 1061 *
859 * @return `GL_TRUE` if successful, or `GL_FALSE` if an error occurred. 1062 * @return `GL_TRUE` if successful, or `GL_FALSE` if an
1063 * [error](@ref error_handling) occurred.
860 * 1064 *
861 * @par New in GLFW 3 1065 * @remarks __OS X:__ This function will change the current directory of the
862 * This function no longer registers @ref glfwTerminate with `atexit`. 1066 * application to the `Contents/Resources` subdirectory of the application's
1067 * bundle, if present. This can be disabled with a
1068 * [compile-time option](@ref compile_options_osx).
863 * 1069 *
864 * @note This function may only be called from the main thread. 1070 * @remarks __X11:__ If the `LC_CTYPE` category of the current locale is set to
1071 * `"C"` then the environment's locale will be applied to that category. This
1072 * is done because character input will not function when `LC_CTYPE` is set to
1073 * `"C"`. If another locale was set before this function was called, it will
1074 * be left untouched.
865 * 1075 *
866 * @note **OS X:** This function will change the current directory of the 1076 * @par Thread Safety
867 * application to the `Contents/Resources` subdirectory of the application's 1077 * This function may only be called from the main thread.
868 * bundle, if present.
869 * 1078 *
1079 * @sa @ref intro_init
870 * @sa glfwTerminate 1080 * @sa glfwTerminate
871 * 1081 *
1082 * @since Added in GLFW 1.0.
1083 *
872 * @ingroup init 1084 * @ingroup init
873 */ 1085 */
874GLFWAPI int glfwInit(void); 1086GLFWAPI int glfwInit(void);
875 1087
876/*! @brief Terminates the GLFW library. 1088/*! @brief Terminates the GLFW library.
877 * 1089 *
878 * This function destroys all remaining windows, frees any allocated resources 1090 * This function destroys all remaining windows and cursors, restores any
879 * and sets the library to an uninitialized state. Once this is called, you 1091 * modified gamma ramps and frees any other allocated resources. Once this
880 * must again call @ref glfwInit successfully before you will be able to use 1092 * function is called, you must again call @ref glfwInit successfully before
881 * most GLFW functions. 1093 * you will be able to use most GLFW functions.
882 * 1094 *
883 * If GLFW has been successfully initialized, this function should be called 1095 * If GLFW has been successfully initialized, this function should be called
884 * before the program exits. If initialization fails, there is no need to call 1096 * before the application exits. If initialization fails, there is no need to
885 * this function, as it is called by @ref glfwInit before it returns failure. 1097 * call this function, as it is called by @ref glfwInit before it returns
1098 * failure.
886 * 1099 *
887 * @remarks This function may be called before @ref glfwInit. 1100 * @remarks This function may be called before @ref glfwInit.
888 * 1101 *
889 * @note This function may only be called from the main thread.
890 *
891 * @warning No window's context may be current on another thread when this 1102 * @warning No window's context may be current on another thread when this
892 * function is called. 1103 * function is called.
893 * 1104 *
1105 * @par Reentrancy
1106 * This function may not be called from a callback.
1107 *
1108 * @par Thread Safety
1109 * This function may only be called from the main thread.
1110 *
1111 * @sa @ref intro_init
894 * @sa glfwInit 1112 * @sa glfwInit
895 * 1113 *
1114 * @since Added in GLFW 1.0.
1115 *
896 * @ingroup init 1116 * @ingroup init
897 */ 1117 */
898GLFWAPI void glfwTerminate(void); 1118GLFWAPI void glfwTerminate(void);
@@ -903,46 +1123,55 @@ GLFWAPI void glfwTerminate(void);
903 * library. It is intended for when you are using GLFW as a shared library and 1123 * library. It is intended for when you are using GLFW as a shared library and
904 * want to ensure that you are using the minimum required version. 1124 * want to ensure that you are using the minimum required version.
905 * 1125 *
1126 * Any or all of the version arguments may be `NULL`. This function always
1127 * succeeds.
1128 *
906 * @param[out] major Where to store the major version number, or `NULL`. 1129 * @param[out] major Where to store the major version number, or `NULL`.
907 * @param[out] minor Where to store the minor version number, or `NULL`. 1130 * @param[out] minor Where to store the minor version number, or `NULL`.
908 * @param[out] rev Where to store the revision number, or `NULL`. 1131 * @param[out] rev Where to store the revision number, or `NULL`.
909 * 1132 *
910 * @remarks This function may be called before @ref glfwInit. 1133 * @remarks This function may be called before @ref glfwInit.
911 * 1134 *
912 * @remarks This function may be called from any thread. 1135 * @par Thread Safety
1136 * This function may be called from any thread.
913 * 1137 *
1138 * @sa @ref intro_version
914 * @sa glfwGetVersionString 1139 * @sa glfwGetVersionString
915 * 1140 *
1141 * @since Added in GLFW 1.0.
1142 *
916 * @ingroup init 1143 * @ingroup init
917 */ 1144 */
918GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev); 1145GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev);
919 1146
920/*! @brief Returns a string describing the compile-time configuration. 1147/*! @brief Returns a string describing the compile-time configuration.
921 * 1148 *
922 * This function returns a static string generated at compile-time according to 1149 * This function returns the compile-time generated
923 * which configuration macros were defined. This is intended for use when 1150 * [version string](@ref intro_version_string) of the GLFW library binary. It
924 * submitting bug reports, to allow developers to see which code paths are 1151 * describes the version, platform, compiler and any platform-specific
925 * enabled in a binary. 1152 * compile-time options.
926 *
927 * The format of the string is as follows:
928 * - The version of GLFW
929 * - The name of the window system API
930 * - The name of the context creation API
931 * - Any additional options or APIs
932 * 1153 *
933 * For example, when compiling GLFW 3.0 with MinGW using the Win32 and WGL 1154 * __Do not use the version string__ to parse the GLFW library version. The
934 * back ends, the version string may look something like this: 1155 * @ref glfwGetVersion function already provides the version of the running
1156 * library binary.
935 * 1157 *
936 * 3.0.0 Win32 WGL MinGW 1158 * This function always succeeds.
937 * 1159 *
938 * @return The GLFW version string. 1160 * @return The GLFW version string.
939 * 1161 *
940 * @remarks This function may be called before @ref glfwInit. 1162 * @remarks This function may be called before @ref glfwInit.
941 * 1163 *
942 * @remarks This function may be called from any thread. 1164 * @par Pointer Lifetime
1165 * The returned string is static and compile-time generated.
943 * 1166 *
1167 * @par Thread Safety
1168 * This function may be called from any thread.
1169 *
1170 * @sa @ref intro_version
944 * @sa glfwGetVersion 1171 * @sa glfwGetVersion
945 * 1172 *
1173 * @since Added in GLFW 3.0.
1174 *
946 * @ingroup init 1175 * @ingroup init
947 */ 1176 */
948GLFWAPI const char* glfwGetVersionString(void); 1177GLFWAPI const char* glfwGetVersionString(void);
@@ -952,23 +1181,31 @@ GLFWAPI const char* glfwGetVersionString(void);
952 * This function sets the error callback, which is called with an error code 1181 * This function sets the error callback, which is called with an error code
953 * and a human-readable description each time a GLFW error occurs. 1182 * and a human-readable description each time a GLFW error occurs.
954 * 1183 *
1184 * The error callback is called on the thread where the error occurred. If you
1185 * are using GLFW from multiple threads, your error callback needs to be
1186 * written accordingly.
1187 *
1188 * Because the description string may have been generated specifically for that
1189 * error, it is not guaranteed to be valid after the callback has returned. If
1190 * you wish to use it after the callback returns, you need to make a copy.
1191 *
1192 * Once set, the error callback remains set even after the library has been
1193 * terminated.
1194 *
955 * @param[in] cbfun The new callback, or `NULL` to remove the currently set 1195 * @param[in] cbfun The new callback, or `NULL` to remove the currently set
956 * callback. 1196 * callback.
957 * @return The previously set callback, or `NULL` if no callback was set or an 1197 * @return The previously set callback, or `NULL` if no callback was set.
958 * error occurred.
959 * 1198 *
960 * @remarks This function may be called before @ref glfwInit. 1199 * @remarks This function may be called before @ref glfwInit.
961 * 1200 *
962 * @note The error callback is called by the thread where the error was 1201 * @par Thread Safety
963 * generated. If you are using GLFW from multiple threads, your error callback 1202 * This function may only be called from the main thread.
964 * needs to be written accordingly. 1203 *
1204 * @sa @ref error_handling
965 * 1205 *
966 * @note Because the description string provided to the callback may have been 1206 * @since Added in GLFW 3.0.
967 * generated specifically for that error, it is not guaranteed to be valid
968 * after the callback has returned. If you wish to use it after that, you need
969 * to make your own copy of it before returning.
970 * 1207 *
971 * @ingroup error 1208 * @ingroup init
972 */ 1209 */
973GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun); 1210GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun);
974 1211
@@ -977,19 +1214,25 @@ GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun);
977 * This function returns an array of handles for all currently connected 1214 * This function returns an array of handles for all currently connected
978 * monitors. 1215 * monitors.
979 * 1216 *
980 * @param[out] count Where to store the size of the returned array. This is 1217 * @param[out] count Where to store the number of monitors in the returned
981 * set to zero if an error occurred. 1218 * array. This is set to zero if an error occurred.
982 * @return An array of monitor handles, or `NULL` if an error occurred. 1219 * @return An array of monitor handles, or `NULL` if an
1220 * [error](@ref error_handling) occurred.
983 * 1221 *
984 * @note The returned array is allocated and freed by GLFW. You should not 1222 * @par Pointer Lifetime
985 * free it yourself. 1223 * The returned array is allocated and freed by GLFW. You should not free it
1224 * yourself. It is guaranteed to be valid only until the monitor configuration
1225 * changes or the library is terminated.
986 * 1226 *
987 * @note The returned array is valid only until the monitor configuration 1227 * @par Thread Safety
988 * changes. See @ref glfwSetMonitorCallback to receive notifications of 1228 * This function may only be called from the main thread.
989 * configuration changes.
990 * 1229 *
1230 * @sa @ref monitor_monitors
1231 * @sa @ref monitor_event
991 * @sa glfwGetPrimaryMonitor 1232 * @sa glfwGetPrimaryMonitor
992 * 1233 *
1234 * @since Added in GLFW 3.0.
1235 *
993 * @ingroup monitor 1236 * @ingroup monitor
994 */ 1237 */
995GLFWAPI GLFWmonitor** glfwGetMonitors(int* count); 1238GLFWAPI GLFWmonitor** glfwGetMonitors(int* count);
@@ -999,10 +1242,17 @@ GLFWAPI GLFWmonitor** glfwGetMonitors(int* count);
999 * This function returns the primary monitor. This is usually the monitor 1242 * This function returns the primary monitor. This is usually the monitor
1000 * where elements like the Windows task bar or the OS X menu bar is located. 1243 * where elements like the Windows task bar or the OS X menu bar is located.
1001 * 1244 *
1002 * @return The primary monitor, or `NULL` if an error occurred. 1245 * @return The primary monitor, or `NULL` if an [error](@ref error_handling)
1246 * occurred.
1247 *
1248 * @par Thread Safety
1249 * This function may only be called from the main thread.
1003 * 1250 *
1251 * @sa @ref monitor_monitors
1004 * @sa glfwGetMonitors 1252 * @sa glfwGetMonitors
1005 * 1253 *
1254 * @since Added in GLFW 3.0.
1255 *
1006 * @ingroup monitor 1256 * @ingroup monitor
1007 */ 1257 */
1008GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void); 1258GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void);
@@ -1012,10 +1262,20 @@ GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void);
1012 * This function returns the position, in screen coordinates, of the upper-left 1262 * This function returns the position, in screen coordinates, of the upper-left
1013 * corner of the specified monitor. 1263 * corner of the specified monitor.
1014 * 1264 *
1265 * Any or all of the position arguments may be `NULL`. If an error occurs, all
1266 * non-`NULL` position arguments will be set to zero.
1267 *
1015 * @param[in] monitor The monitor to query. 1268 * @param[in] monitor The monitor to query.
1016 * @param[out] xpos Where to store the monitor x-coordinate, or `NULL`. 1269 * @param[out] xpos Where to store the monitor x-coordinate, or `NULL`.
1017 * @param[out] ypos Where to store the monitor y-coordinate, or `NULL`. 1270 * @param[out] ypos Where to store the monitor y-coordinate, or `NULL`.
1018 * 1271 *
1272 * @par Thread Safety
1273 * This function may only be called from the main thread.
1274 *
1275 * @sa @ref monitor_properties
1276 *
1277 * @since Added in GLFW 3.0.
1278 *
1019 * @ingroup monitor 1279 * @ingroup monitor
1020 */ 1280 */
1021GLFWAPI void glfwGetMonitorPos(GLFWmonitor* monitor, int* xpos, int* ypos); 1281GLFWAPI void glfwGetMonitorPos(GLFWmonitor* monitor, int* xpos, int* ypos);
@@ -1025,31 +1285,55 @@ GLFWAPI void glfwGetMonitorPos(GLFWmonitor* monitor, int* xpos, int* ypos);
1025 * This function returns the size, in millimetres, of the display area of the 1285 * This function returns the size, in millimetres, of the display area of the
1026 * specified monitor. 1286 * specified monitor.
1027 * 1287 *
1288 * Some systems do not provide accurate monitor size information, either
1289 * because the monitor
1290 * [EDID](https://en.wikipedia.org/wiki/Extended_display_identification_data)
1291 * data is incorrect or because the driver does not report it accurately.
1292 *
1293 * Any or all of the size arguments may be `NULL`. If an error occurs, all
1294 * non-`NULL` size arguments will be set to zero.
1295 *
1028 * @param[in] monitor The monitor to query. 1296 * @param[in] monitor The monitor to query.
1029 * @param[out] width Where to store the width, in mm, of the monitor's display 1297 * @param[out] widthMM Where to store the width, in millimetres, of the
1030 * area, or `NULL`. 1298 * monitor's display area, or `NULL`.
1031 * @param[out] height Where to store the height, in mm, of the monitor's 1299 * @param[out] heightMM Where to store the height, in millimetres, of the
1032 * display area, or `NULL`. 1300 * monitor's display area, or `NULL`.
1033 * 1301 *
1034 * @note Some operating systems do not provide accurate information, either 1302 * @remarks __Windows:__ The OS calculates the returned physical size from the
1035 * because the monitor's EDID data is incorrect, or because the driver does not 1303 * current resolution and system DPI instead of querying the monitor EDID data.
1036 * report it accurately. 1304 *
1305 * @par Thread Safety
1306 * This function may only be called from the main thread.
1307 *
1308 * @sa @ref monitor_properties
1309 *
1310 * @since Added in GLFW 3.0.
1037 * 1311 *
1038 * @ingroup monitor 1312 * @ingroup monitor
1039 */ 1313 */
1040GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* monitor, int* width, int* height); 1314GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* monitor, int* widthMM, int* heightMM);
1041 1315
1042/*! @brief Returns the name of the specified monitor. 1316/*! @brief Returns the name of the specified monitor.
1043 * 1317 *
1044 * This function returns a human-readable name, encoded as UTF-8, of the 1318 * This function returns a human-readable name, encoded as UTF-8, of the
1045 * specified monitor. 1319 * specified monitor. The name typically reflects the make and model of the
1320 * monitor and is not guaranteed to be unique among the connected monitors.
1046 * 1321 *
1047 * @param[in] monitor The monitor to query. 1322 * @param[in] monitor The monitor to query.
1048 * @return The UTF-8 encoded name of the monitor, or `NULL` if an error 1323 * @return The UTF-8 encoded name of the monitor, or `NULL` if an
1049 * occurred. 1324 * [error](@ref error_handling) occurred.
1325 *
1326 * @par Pointer Lifetime
1327 * The returned string is allocated and freed by GLFW. You should not free it
1328 * yourself. It is valid until the specified monitor is disconnected or the
1329 * library is terminated.
1330 *
1331 * @par Thread Safety
1332 * This function may only be called from the main thread.
1333 *
1334 * @sa @ref monitor_properties
1050 * 1335 *
1051 * @note The returned string is allocated and freed by GLFW. You should not 1336 * @since Added in GLFW 3.0.
1052 * free it yourself.
1053 * 1337 *
1054 * @ingroup monitor 1338 * @ingroup monitor
1055 */ 1339 */
@@ -1063,12 +1347,19 @@ GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* monitor);
1063 * 1347 *
1064 * @param[in] cbfun The new callback, or `NULL` to remove the currently set 1348 * @param[in] cbfun The new callback, or `NULL` to remove the currently set
1065 * callback. 1349 * callback.
1066 * @return The previously set callback, or `NULL` if no callback was set or an 1350 * @return The previously set callback, or `NULL` if no callback was set or the
1067 * error occurred. 1351 * library had not been [initialized](@ref intro_init).
1068 * 1352 *
1069 * @bug **X11:** This callback is not yet called on monitor configuration 1353 * @bug __X11:__ This callback is not yet called on monitor configuration
1070 * changes. 1354 * changes.
1071 * 1355 *
1356 * @par Thread Safety
1357 * This function may only be called from the main thread.
1358 *
1359 * @sa @ref monitor_event
1360 *
1361 * @since Added in GLFW 3.0.
1362 *
1072 * @ingroup monitor 1363 * @ingroup monitor
1073 */ 1364 */
1074GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun); 1365GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun);
@@ -1083,16 +1374,25 @@ GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun);
1083 * @param[in] monitor The monitor to query. 1374 * @param[in] monitor The monitor to query.
1084 * @param[out] count Where to store the number of video modes in the returned 1375 * @param[out] count Where to store the number of video modes in the returned
1085 * array. This is set to zero if an error occurred. 1376 * array. This is set to zero if an error occurred.
1086 * @return An array of video modes, or `NULL` if an error occurred. 1377 * @return An array of video modes, or `NULL` if an
1378 * [error](@ref error_handling) occurred.
1087 * 1379 *
1088 * @note The returned array is allocated and freed by GLFW. You should not 1380 * @par Pointer Lifetime
1089 * free it yourself. 1381 * The returned array is allocated and freed by GLFW. You should not free it
1382 * yourself. It is valid until the specified monitor is disconnected, this
1383 * function is called again for that monitor or the library is terminated.
1090 * 1384 *
1091 * @note The returned array is valid only until this function is called again 1385 * @par Thread Safety
1092 * for the specified monitor. 1386 * This function may only be called from the main thread.
1093 * 1387 *
1388 * @sa @ref monitor_modes
1094 * @sa glfwGetVideoMode 1389 * @sa glfwGetVideoMode
1095 * 1390 *
1391 * @since Added in GLFW 1.0.
1392 *
1393 * @par
1394 * __GLFW 3:__ Changed to return an array of modes for a specific monitor.
1395 *
1096 * @ingroup monitor 1396 * @ingroup monitor
1097 */ 1397 */
1098GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* monitor, int* count); 1398GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* monitor, int* count);
@@ -1100,17 +1400,26 @@ GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* monitor, int* count);
1100/*! @brief Returns the current mode of the specified monitor. 1400/*! @brief Returns the current mode of the specified monitor.
1101 * 1401 *
1102 * This function returns the current video mode of the specified monitor. If 1402 * This function returns the current video mode of the specified monitor. If
1103 * you are using a full screen window, the return value will therefore depend 1403 * you have created a full screen window for that monitor, the return value
1104 * on whether it is focused. 1404 * will depend on whether that window is iconified.
1105 * 1405 *
1106 * @param[in] monitor The monitor to query. 1406 * @param[in] monitor The monitor to query.
1107 * @return The current mode of the monitor, or `NULL` if an error occurred. 1407 * @return The current mode of the monitor, or `NULL` if an
1408 * [error](@ref error_handling) occurred.
1409 *
1410 * @par Pointer Lifetime
1411 * The returned array is allocated and freed by GLFW. You should not free it
1412 * yourself. It is valid until the specified monitor is disconnected or the
1413 * library is terminated.
1108 * 1414 *
1109 * @note The returned struct is allocated and freed by GLFW. You should not 1415 * @par Thread Safety
1110 * free it yourself. 1416 * This function may only be called from the main thread.
1111 * 1417 *
1418 * @sa @ref monitor_modes
1112 * @sa glfwGetVideoModes 1419 * @sa glfwGetVideoModes
1113 * 1420 *
1421 * @since Added in GLFW 3.0. Replaces `glfwGetDesktopMode`.
1422 *
1114 * @ingroup monitor 1423 * @ingroup monitor
1115 */ 1424 */
1116GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor); 1425GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor);
@@ -1118,24 +1427,43 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor);
1118/*! @brief Generates a gamma ramp and sets it for the specified monitor. 1427/*! @brief Generates a gamma ramp and sets it for the specified monitor.
1119 * 1428 *
1120 * This function generates a 256-element gamma ramp from the specified exponent 1429 * This function generates a 256-element gamma ramp from the specified exponent
1121 * and then calls @ref glfwSetGammaRamp with it. 1430 * and then calls @ref glfwSetGammaRamp with it. The value must be a finite
1431 * number greater than zero.
1122 * 1432 *
1123 * @param[in] monitor The monitor whose gamma ramp to set. 1433 * @param[in] monitor The monitor whose gamma ramp to set.
1124 * @param[in] gamma The desired exponent. 1434 * @param[in] gamma The desired exponent.
1125 * 1435 *
1436 * @par Thread Safety
1437 * This function may only be called from the main thread.
1438 *
1439 * @sa @ref monitor_gamma
1440 *
1441 * @since Added in GLFW 3.0.
1442 *
1126 * @ingroup monitor 1443 * @ingroup monitor
1127 */ 1444 */
1128GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma); 1445GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma);
1129 1446
1130/*! @brief Retrieves the current gamma ramp for the specified monitor. 1447/*! @brief Returns the current gamma ramp for the specified monitor.
1131 * 1448 *
1132 * This function retrieves the current gamma ramp of the specified monitor. 1449 * This function returns the current gamma ramp of the specified monitor.
1133 * 1450 *
1134 * @param[in] monitor The monitor to query. 1451 * @param[in] monitor The monitor to query.
1135 * @return The current gamma ramp, or `NULL` if an error occurred. 1452 * @return The current gamma ramp, or `NULL` if an
1453 * [error](@ref error_handling) occurred.
1136 * 1454 *
1137 * @note The value arrays of the returned ramp are allocated and freed by GLFW. 1455 * @par Pointer Lifetime
1138 * You should not free them yourself. 1456 * The returned structure and its arrays are allocated and freed by GLFW. You
1457 * should not free them yourself. They are valid until the specified monitor
1458 * is disconnected, this function is called again for that monitor or the
1459 * library is terminated.
1460 *
1461 * @par Thread Safety
1462 * This function may only be called from the main thread.
1463 *
1464 * @sa @ref monitor_gamma
1465 *
1466 * @since Added in GLFW 3.0.
1139 * 1467 *
1140 * @ingroup monitor 1468 * @ingroup monitor
1141 */ 1469 */
@@ -1143,12 +1471,27 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor);
1143 1471
1144/*! @brief Sets the current gamma ramp for the specified monitor. 1472/*! @brief Sets the current gamma ramp for the specified monitor.
1145 * 1473 *
1146 * This function sets the current gamma ramp for the specified monitor. 1474 * This function sets the current gamma ramp for the specified monitor. The
1475 * original gamma ramp for that monitor is saved by GLFW the first time this
1476 * function is called and is restored by @ref glfwTerminate.
1147 * 1477 *
1148 * @param[in] monitor The monitor whose gamma ramp to set. 1478 * @param[in] monitor The monitor whose gamma ramp to set.
1149 * @param[in] ramp The gamma ramp to use. 1479 * @param[in] ramp The gamma ramp to use.
1150 * 1480 *
1151 * @note Gamma ramp sizes other than 256 are not supported by all hardware. 1481 * @remarks Gamma ramp sizes other than 256 are not supported by all platforms
1482 * or graphics hardware.
1483 *
1484 * @remarks __Windows:__ The gamma ramp size must be 256.
1485 *
1486 * @par Pointer Lifetime
1487 * The specified gamma ramp is copied before this function returns.
1488 *
1489 * @par Thread Safety
1490 * This function may only be called from the main thread.
1491 *
1492 * @sa @ref monitor_gamma
1493 *
1494 * @since Added in GLFW 3.0.
1152 * 1495 *
1153 * @ingroup monitor 1496 * @ingroup monitor
1154 */ 1497 */
@@ -1159,10 +1502,14 @@ GLFWAPI void glfwSetGammaRamp(GLFWmonitor* monitor, const GLFWgammaramp* ramp);
1159 * This function resets all window hints to their 1502 * This function resets all window hints to their
1160 * [default values](@ref window_hints_values). 1503 * [default values](@ref window_hints_values).
1161 * 1504 *
1162 * @note This function may only be called from the main thread. 1505 * @par Thread Safety
1506 * This function may only be called from the main thread.
1163 * 1507 *
1508 * @sa @ref window_hints
1164 * @sa glfwWindowHint 1509 * @sa glfwWindowHint
1165 * 1510 *
1511 * @since Added in GLFW 3.0.
1512 *
1166 * @ingroup window 1513 * @ingroup window
1167 */ 1514 */
1168GLFWAPI void glfwDefaultWindowHints(void); 1515GLFWAPI void glfwDefaultWindowHints(void);
@@ -1172,51 +1519,69 @@ GLFWAPI void glfwDefaultWindowHints(void);
1172 * This function sets hints for the next call to @ref glfwCreateWindow. The 1519 * This function sets hints for the next call to @ref glfwCreateWindow. The
1173 * hints, once set, retain their values until changed by a call to @ref 1520 * hints, once set, retain their values until changed by a call to @ref
1174 * glfwWindowHint or @ref glfwDefaultWindowHints, or until the library is 1521 * glfwWindowHint or @ref glfwDefaultWindowHints, or until the library is
1175 * terminated with @ref glfwTerminate. 1522 * terminated.
1176 * 1523 *
1177 * @param[in] target The [window hint](@ref window_hints) to set. 1524 * @param[in] target The [window hint](@ref window_hints) to set.
1178 * @param[in] hint The new value of the window hint. 1525 * @param[in] hint The new value of the window hint.
1179 * 1526 *
1180 * @par New in GLFW 3 1527 * @par Thread Safety
1181 * Hints are no longer reset to their default values on window creation. To 1528 * This function may only be called from the main thread.
1182 * set default hint values, use @ref glfwDefaultWindowHints.
1183 *
1184 * @note This function may only be called from the main thread.
1185 * 1529 *
1530 * @sa @ref window_hints
1186 * @sa glfwDefaultWindowHints 1531 * @sa glfwDefaultWindowHints
1187 * 1532 *
1533 * @since Added in GLFW 3.0. Replaces `glfwOpenWindowHint`.
1534 *
1188 * @ingroup window 1535 * @ingroup window
1189 */ 1536 */
1190GLFWAPI void glfwWindowHint(int target, int hint); 1537GLFWAPI void glfwWindowHint(int target, int hint);
1191 1538
1192/*! @brief Creates a window and its associated context. 1539/*! @brief Creates a window and its associated context.
1193 * 1540 *
1194 * This function creates a window and its associated context. Most of the 1541 * This function creates a window and its associated OpenGL or OpenGL ES
1195 * options controlling how the window and its context should be created are 1542 * context. Most of the options controlling how the window and its context
1196 * specified through @ref glfwWindowHint. 1543 * should be created are specified with [window hints](@ref window_hints).
1197 * 1544 *
1198 * Successful creation does not change which context is current. Before you 1545 * Successful creation does not change which context is current. Before you
1199 * can use the newly created context, you need to make it current using @ref 1546 * can use the newly created context, you need to
1200 * glfwMakeContextCurrent. 1547 * [make it current](@ref context_current). For information about the `share`
1548 * parameter, see @ref context_sharing.
1201 * 1549 *
1202 * Note that the created window and context may differ from what you requested, 1550 * The created window, framebuffer and context may differ from what you
1203 * as not all parameters and hints are 1551 * requested, as not all parameters and hints are
1204 * [hard constraints](@ref window_hints_hard). This includes the size of the 1552 * [hard constraints](@ref window_hints_hard). This includes the size of the
1205 * window, especially for full screen windows. To retrieve the actual 1553 * window, especially for full screen windows. To query the actual attributes
1206 * attributes of the created window and context, use queries like @ref 1554 * of the created window, framebuffer and context, use queries like @ref
1207 * glfwGetWindowAttrib and @ref glfwGetWindowSize. 1555 * glfwGetWindowAttrib and @ref glfwGetWindowSize.
1208 * 1556 *
1209 * To create a full screen window, you need to specify the monitor to use. If 1557 * To create a full screen window, you need to specify the monitor the window
1210 * no monitor is specified, windowed mode will be used. Unless you have a way 1558 * will cover. If no monitor is specified, windowed mode will be used. Unless
1211 * for the user to choose a specific monitor, it is recommended that you pick 1559 * you have a way for the user to choose a specific monitor, it is recommended
1212 * the primary monitor. For more information on how to retrieve monitors, see 1560 * that you pick the primary monitor. For more information on how to query
1213 * @ref monitor_monitors. 1561 * connected monitors, see @ref monitor_monitors.
1562 *
1563 * For full screen windows, the specified size becomes the resolution of the
1564 * window's _desired video mode_. As long as a full screen window has input
1565 * focus, the supported video mode most closely matching the desired video mode
1566 * is set for the specified monitor. For more information about full screen
1567 * windows, including the creation of so called _windowed full screen_ or
1568 * _borderless full screen_ windows, see @ref window_windowed_full_screen.
1569 *
1570 * By default, newly created windows use the placement recommended by the
1571 * window system. To create the window at a specific position, make it
1572 * initially invisible using the [GLFW_VISIBLE](@ref window_hints_wnd) window
1573 * hint, set its [position](@ref window_pos) and then [show](@ref window_hide)
1574 * it.
1575 *
1576 * If a full screen window has input focus, the screensaver is prohibited from
1577 * starting.
1214 * 1578 *
1215 * To create the window at a specific position, make it initially invisible 1579 * Window systems put limits on window sizes. Very large or very small window
1216 * using the `GLFW_VISIBLE` window hint, set its position and then show it. 1580 * dimensions may be overridden by the window system on creation. Check the
1581 * actual [size](@ref window_size) after creation.
1217 * 1582 *
1218 * If a full screen window is active, the screensaver is prohibited from 1583 * The [swap interval](@ref buffer_swap) is not set during window creation and
1219 * starting. 1584 * the initial value may vary depending on driver settings and defaults.
1220 * 1585 *
1221 * @param[in] width The desired width, in screen coordinates, of the window. 1586 * @param[in] width The desired width, in screen coordinates, of the window.
1222 * This must be greater than zero. 1587 * This must be greater than zero.
@@ -1227,32 +1592,54 @@ GLFWAPI void glfwWindowHint(int target, int hint);
1227 * windowed mode. 1592 * windowed mode.
1228 * @param[in] share The window whose context to share resources with, or `NULL` 1593 * @param[in] share The window whose context to share resources with, or `NULL`
1229 * to not share resources. 1594 * to not share resources.
1230 * @return The handle of the created window, or `NULL` if an error occurred. 1595 * @return The handle of the created window, or `NULL` if an
1596 * [error](@ref error_handling) occurred.
1231 * 1597 *
1232 * @remarks **Windows:** Window creation will fail if the Microsoft GDI 1598 * @remarks __Windows:__ Window creation will fail if the Microsoft GDI
1233 * software OpenGL implementation is the only one available. 1599 * software OpenGL implementation is the only one available.
1234 * 1600 *
1235 * @remarks **Windows:** If the executable has an icon resource named 1601 * @remarks __Windows:__ If the executable has an icon resource named
1236 * `GLFW_ICON,` it will be set as the icon for the window. If no such icon is 1602 * `GLFW_ICON,` it will be set as the icon for the window. If no such icon is
1237 * present, the `IDI_WINLOGO` icon will be used instead. 1603 * present, the `IDI_WINLOGO` icon will be used instead.
1238 * 1604 *
1239 * @remarks **OS X:** The GLFW window has no icon, as it is not a document 1605 * @remarks __Windows:__ The context to share resources with may not be current
1606 * on any other thread.
1607 *
1608 * @remarks __OS X:__ The GLFW window has no icon, as it is not a document
1240 * window, but the dock icon will be the same as the application bundle's icon. 1609 * window, but the dock icon will be the same as the application bundle's icon.
1241 * Also, the first time a window is opened the menu bar is populated with 1610 * For more information on bundles, see the
1242 * common commands like Hide, Quit and About. The (minimal) about dialog uses 1611 * [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/)
1243 * information from the application's bundle. For more information on bundles, 1612 * in the Mac Developer Library.
1244 * see the Bundle Programming Guide provided by Apple. 1613 *
1614 * @remarks __OS X:__ The first time a window is created the menu bar is
1615 * populated with common commands like Hide, Quit and About. The About entry
1616 * opens a minimal about dialog with information from the application's bundle.
1617 * The menu bar can be disabled with a
1618 * [compile-time option](@ref compile_options_osx).
1245 * 1619 *
1246 * @remarks **X11:** There is no mechanism for setting the window icon yet. 1620 * @remarks __OS X:__ On OS X 10.10 and later the window frame will not be
1621 * rendered at full resolution on Retina displays unless the
1622 * `NSHighResolutionCapable` key is enabled in the application bundle's
1623 * `Info.plist`. For more information, see
1624 * [High Resolution Guidelines for OS X](https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html)
1625 * in the Mac Developer Library.
1247 * 1626 *
1248 * @remarks The swap interval is not set during window creation, but is left at 1627 * @remarks __X11:__ There is no mechanism for setting the window icon yet.
1249 * the default value for that platform. For more information, see @ref
1250 * glfwSwapInterval.
1251 * 1628 *
1252 * @note This function may only be called from the main thread. 1629 * @remarks __X11:__ Some window managers will not respect the placement of
1630 * initially hidden windows.
1253 * 1631 *
1632 * @par Reentrancy
1633 * This function may not be called from a callback.
1634 *
1635 * @par Thread Safety
1636 * This function may only be called from the main thread.
1637 *
1638 * @sa @ref window_creation
1254 * @sa glfwDestroyWindow 1639 * @sa glfwDestroyWindow
1255 * 1640 *
1641 * @since Added in GLFW 3.0. Replaces `glfwOpenWindow`.
1642 *
1256 * @ingroup window 1643 * @ingroup window
1257 */ 1644 */
1258GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, GLFWmonitor* monitor, GLFWwindow* share); 1645GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, GLFWmonitor* monitor, GLFWwindow* share);
@@ -1262,19 +1649,25 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, G
1262 * This function destroys the specified window and its context. On calling 1649 * This function destroys the specified window and its context. On calling
1263 * this function, no further callbacks will be called for that window. 1650 * this function, no further callbacks will be called for that window.
1264 * 1651 *
1265 * @param[in] window The window to destroy. 1652 * If the context of the specified window is current on the main thread, it is
1653 * detached before being destroyed.
1266 * 1654 *
1267 * @note This function may only be called from the main thread. 1655 * @param[in] window The window to destroy.
1268 * 1656 *
1269 * @note This function may not be called from a callback. 1657 * @note The context of the specified window must not be current on any other
1658 * thread when this function is called.
1270 * 1659 *
1271 * @note If the window's context is current on the main thread, it is 1660 * @par Reentrancy
1272 * detached before being destroyed. 1661 * This function may not be called from a callback.
1273 * 1662 *
1274 * @warning The window's context must not be current on any other thread. 1663 * @par Thread Safety
1664 * This function may only be called from the main thread.
1275 * 1665 *
1666 * @sa @ref window_creation
1276 * @sa glfwCreateWindow 1667 * @sa glfwCreateWindow
1277 * 1668 *
1669 * @since Added in GLFW 3.0. Replaces `glfwCloseWindow`.
1670 *
1278 * @ingroup window 1671 * @ingroup window
1279 */ 1672 */
1280GLFWAPI void glfwDestroyWindow(GLFWwindow* window); 1673GLFWAPI void glfwDestroyWindow(GLFWwindow* window);
@@ -1286,7 +1679,12 @@ GLFWAPI void glfwDestroyWindow(GLFWwindow* window);
1286 * @param[in] window The window to query. 1679 * @param[in] window The window to query.
1287 * @return The value of the close flag. 1680 * @return The value of the close flag.
1288 * 1681 *
1289 * @remarks This function may be called from secondary threads. 1682 * @par Thread Safety
1683 * This function may be called from any thread. Access is not synchronized.
1684 *
1685 * @sa @ref window_close
1686 *
1687 * @since Added in GLFW 3.0.
1290 * 1688 *
1291 * @ingroup window 1689 * @ingroup window
1292 */ 1690 */
@@ -1301,7 +1699,12 @@ GLFWAPI int glfwWindowShouldClose(GLFWwindow* window);
1301 * @param[in] window The window whose flag to change. 1699 * @param[in] window The window whose flag to change.
1302 * @param[in] value The new value. 1700 * @param[in] value The new value.
1303 * 1701 *
1304 * @remarks This function may be called from secondary threads. 1702 * @par Thread Safety
1703 * This function may be called from any thread. Access is not synchronized.
1704 *
1705 * @sa @ref window_close
1706 *
1707 * @since Added in GLFW 3.0.
1305 * 1708 *
1306 * @ingroup window 1709 * @ingroup window
1307 */ 1710 */
@@ -1315,7 +1718,15 @@ GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* window, int value);
1315 * @param[in] window The window whose title to change. 1718 * @param[in] window The window whose title to change.
1316 * @param[in] title The UTF-8 encoded window title. 1719 * @param[in] title The UTF-8 encoded window title.
1317 * 1720 *
1318 * @note This function may only be called from the main thread. 1721 * @par Thread Safety
1722 * This function may only be called from the main thread.
1723 *
1724 * @sa @ref window_title
1725 *
1726 * @since Added in GLFW 1.0.
1727 *
1728 * @par
1729 * __GLFW 3:__ Added window handle parameter.
1319 * 1730 *
1320 * @ingroup window 1731 * @ingroup window
1321 */ 1732 */
@@ -1326,14 +1737,23 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title);
1326 * This function retrieves the position, in screen coordinates, of the 1737 * This function retrieves the position, in screen coordinates, of the
1327 * upper-left corner of the client area of the specified window. 1738 * upper-left corner of the client area of the specified window.
1328 * 1739 *
1740 * Any or all of the position arguments may be `NULL`. If an error occurs, all
1741 * non-`NULL` position arguments will be set to zero.
1742 *
1329 * @param[in] window The window to query. 1743 * @param[in] window The window to query.
1330 * @param[out] xpos Where to store the x-coordinate of the upper-left corner of 1744 * @param[out] xpos Where to store the x-coordinate of the upper-left corner of
1331 * the client area, or `NULL`. 1745 * the client area, or `NULL`.
1332 * @param[out] ypos Where to store the y-coordinate of the upper-left corner of 1746 * @param[out] ypos Where to store the y-coordinate of the upper-left corner of
1333 * the client area, or `NULL`. 1747 * the client area, or `NULL`.
1334 * 1748 *
1749 * @par Thread Safety
1750 * This function may only be called from the main thread.
1751 *
1752 * @sa @ref window_pos
1335 * @sa glfwSetWindowPos 1753 * @sa glfwSetWindowPos
1336 * 1754 *
1755 * @since Added in GLFW 3.0.
1756 *
1337 * @ingroup window 1757 * @ingroup window
1338 */ 1758 */
1339GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos); 1759GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos);
@@ -1341,26 +1761,29 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos);
1341/*! @brief Sets the position of the client area of the specified window. 1761/*! @brief Sets the position of the client area of the specified window.
1342 * 1762 *
1343 * This function sets the position, in screen coordinates, of the upper-left 1763 * This function sets the position, in screen coordinates, of the upper-left
1344 * corner of the client area of the window. 1764 * corner of the client area of the specified windowed mode window. If the
1765 * window is a full screen window, this function does nothing.
1345 * 1766 *
1346 * If the specified window is a full screen window, this function does nothing. 1767 * __Do not use this function__ to move an already visible window unless you
1768 * have very good reasons for doing so, as it will confuse and annoy the user.
1347 * 1769 *
1348 * If you wish to set an initial window position you should create a hidden 1770 * The window manager may put limits on what positions are allowed. GLFW
1349 * window (using @ref glfwWindowHint and `GLFW_VISIBLE`), set its position and 1771 * cannot and should not override these limits.
1350 * then show it.
1351 * 1772 *
1352 * @param[in] window The window to query. 1773 * @param[in] window The window to query.
1353 * @param[in] xpos The x-coordinate of the upper-left corner of the client area. 1774 * @param[in] xpos The x-coordinate of the upper-left corner of the client area.
1354 * @param[in] ypos The y-coordinate of the upper-left corner of the client area. 1775 * @param[in] ypos The y-coordinate of the upper-left corner of the client area.
1355 * 1776 *
1356 * @note It is very rarely a good idea to move an already visible window, as it 1777 * @par Thread Safety
1357 * will confuse and annoy the user. 1778 * This function may only be called from the main thread.
1358 * 1779 *
1359 * @note This function may only be called from the main thread. 1780 * @sa @ref window_pos
1781 * @sa glfwGetWindowPos
1360 * 1782 *
1361 * @note The window manager may put limits on what positions are allowed. 1783 * @since Added in GLFW 1.0.
1362 * 1784 *
1363 * @sa glfwGetWindowPos 1785 * @par
1786 * __GLFW 3:__ Added window handle parameter.
1364 * 1787 *
1365 * @ingroup window 1788 * @ingroup window
1366 */ 1789 */
@@ -1370,7 +1793,10 @@ GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos);
1370 * 1793 *
1371 * This function retrieves the size, in screen coordinates, of the client area 1794 * This function retrieves the size, in screen coordinates, of the client area
1372 * of the specified window. If you wish to retrieve the size of the 1795 * of the specified window. If you wish to retrieve the size of the
1373 * framebuffer in pixels, see @ref glfwGetFramebufferSize. 1796 * framebuffer of the window in pixels, see @ref glfwGetFramebufferSize.
1797 *
1798 * Any or all of the size arguments may be `NULL`. If an error occurs, all
1799 * non-`NULL` size arguments will be set to zero.
1374 * 1800 *
1375 * @param[in] window The window whose size to retrieve. 1801 * @param[in] window The window whose size to retrieve.
1376 * @param[out] width Where to store the width, in screen coordinates, of the 1802 * @param[out] width Where to store the width, in screen coordinates, of the
@@ -1378,8 +1804,17 @@ GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos);
1378 * @param[out] height Where to store the height, in screen coordinates, of the 1804 * @param[out] height Where to store the height, in screen coordinates, of the
1379 * client area, or `NULL`. 1805 * client area, or `NULL`.
1380 * 1806 *
1807 * @par Thread Safety
1808 * This function may only be called from the main thread.
1809 *
1810 * @sa @ref window_size
1381 * @sa glfwSetWindowSize 1811 * @sa glfwSetWindowSize
1382 * 1812 *
1813 * @since Added in GLFW 1.0.
1814 *
1815 * @par
1816 * __GLFW 3:__ Added window handle parameter.
1817 *
1383 * @ingroup window 1818 * @ingroup window
1384 */ 1819 */
1385GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height); 1820GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height);
@@ -1394,16 +1829,24 @@ GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height);
1394 * the context is unaffected, the bit depths of the framebuffer remain 1829 * the context is unaffected, the bit depths of the framebuffer remain
1395 * unchanged. 1830 * unchanged.
1396 * 1831 *
1832 * The window manager may put limits on what sizes are allowed. GLFW cannot
1833 * and should not override these limits.
1834 *
1397 * @param[in] window The window to resize. 1835 * @param[in] window The window to resize.
1398 * @param[in] width The desired width of the specified window. 1836 * @param[in] width The desired width of the specified window.
1399 * @param[in] height The desired height of the specified window. 1837 * @param[in] height The desired height of the specified window.
1400 * 1838 *
1401 * @note This function may only be called from the main thread. 1839 * @par Thread Safety
1402 * 1840 * This function may only be called from the main thread.
1403 * @note The window manager may put limits on what window sizes are allowed.
1404 * 1841 *
1842 * @sa @ref window_size
1405 * @sa glfwGetWindowSize 1843 * @sa glfwGetWindowSize
1406 * 1844 *
1845 * @since Added in GLFW 1.0.
1846 *
1847 * @par
1848 * __GLFW 3:__ Added window handle parameter.
1849 *
1407 * @ingroup window 1850 * @ingroup window
1408 */ 1851 */
1409GLFWAPI void glfwSetWindowSize(GLFWwindow* window, int width, int height); 1852GLFWAPI void glfwSetWindowSize(GLFWwindow* window, int width, int height);
@@ -1414,80 +1857,149 @@ GLFWAPI void glfwSetWindowSize(GLFWwindow* window, int width, int height);
1414 * specified window. If you wish to retrieve the size of the window in screen 1857 * specified window. If you wish to retrieve the size of the window in screen
1415 * coordinates, see @ref glfwGetWindowSize. 1858 * coordinates, see @ref glfwGetWindowSize.
1416 * 1859 *
1860 * Any or all of the size arguments may be `NULL`. If an error occurs, all
1861 * non-`NULL` size arguments will be set to zero.
1862 *
1417 * @param[in] window The window whose framebuffer to query. 1863 * @param[in] window The window whose framebuffer to query.
1418 * @param[out] width Where to store the width, in pixels, of the framebuffer, 1864 * @param[out] width Where to store the width, in pixels, of the framebuffer,
1419 * or `NULL`. 1865 * or `NULL`.
1420 * @param[out] height Where to store the height, in pixels, of the framebuffer, 1866 * @param[out] height Where to store the height, in pixels, of the framebuffer,
1421 * or `NULL`. 1867 * or `NULL`.
1422 * 1868 *
1869 * @par Thread Safety
1870 * This function may only be called from the main thread.
1871 *
1872 * @sa @ref window_fbsize
1423 * @sa glfwSetFramebufferSizeCallback 1873 * @sa glfwSetFramebufferSizeCallback
1424 * 1874 *
1875 * @since Added in GLFW 3.0.
1876 *
1425 * @ingroup window 1877 * @ingroup window
1426 */ 1878 */
1427GLFWAPI void glfwGetFramebufferSize(GLFWwindow* window, int* width, int* height); 1879GLFWAPI void glfwGetFramebufferSize(GLFWwindow* window, int* width, int* height);
1428 1880
1881/*! @brief Retrieves the size of the frame of the window.
1882 *
1883 * This function retrieves the size, in screen coordinates, of each edge of the
1884 * frame of the specified window. This size includes the title bar, if the
1885 * window has one. The size of the frame may vary depending on the
1886 * [window-related hints](@ref window_hints_wnd) used to create it.
1887 *
1888 * Because this function retrieves the size of each window frame edge and not
1889 * the offset along a particular coordinate axis, the retrieved values will
1890 * always be zero or positive.
1891 *
1892 * Any or all of the size arguments may be `NULL`. If an error occurs, all
1893 * non-`NULL` size arguments will be set to zero.
1894 *
1895 * @param[in] window The window whose frame size to query.
1896 * @param[out] left Where to store the size, in screen coordinates, of the left
1897 * edge of the window frame, or `NULL`.
1898 * @param[out] top Where to store the size, in screen coordinates, of the top
1899 * edge of the window frame, or `NULL`.
1900 * @param[out] right Where to store the size, in screen coordinates, of the
1901 * right edge of the window frame, or `NULL`.
1902 * @param[out] bottom Where to store the size, in screen coordinates, of the
1903 * bottom edge of the window frame, or `NULL`.
1904 *
1905 * @par Thread Safety
1906 * This function may only be called from the main thread.
1907 *
1908 * @sa @ref window_size
1909 *
1910 * @since Added in GLFW 3.1.
1911 *
1912 * @ingroup window
1913 */
1914GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* window, int* left, int* top, int* right, int* bottom);
1915
1429/*! @brief Iconifies the specified window. 1916/*! @brief Iconifies the specified window.
1430 * 1917 *
1431 * This function iconifies/minimizes the specified window, if it was previously 1918 * This function iconifies (minimizes) the specified window if it was
1432 * restored. If it is a full screen window, the original monitor resolution is 1919 * previously restored. If the window is already iconified, this function does
1433 * restored until the window is restored. If the window is already iconified, 1920 * nothing.
1434 * this function does nothing. 1921 *
1922 * If the specified window is a full screen window, the original monitor
1923 * resolution is restored until the window is restored.
1435 * 1924 *
1436 * @param[in] window The window to iconify. 1925 * @param[in] window The window to iconify.
1437 * 1926 *
1438 * @note This function may only be called from the main thread. 1927 * @par Thread Safety
1928 * This function may only be called from the main thread.
1439 * 1929 *
1930 * @sa @ref window_iconify
1440 * @sa glfwRestoreWindow 1931 * @sa glfwRestoreWindow
1441 * 1932 *
1933 * @since Added in GLFW 2.1.
1934 *
1935 * @par
1936 * __GLFW 3:__ Added window handle parameter.
1937 *
1442 * @ingroup window 1938 * @ingroup window
1443 */ 1939 */
1444GLFWAPI void glfwIconifyWindow(GLFWwindow* window); 1940GLFWAPI void glfwIconifyWindow(GLFWwindow* window);
1445 1941
1446/*! @brief Restores the specified window. 1942/*! @brief Restores the specified window.
1447 * 1943 *
1448 * This function restores the specified window, if it was previously 1944 * This function restores the specified window if it was previously iconified
1449 * iconified/minimized. If it is a full screen window, the resolution chosen 1945 * (minimized). If the window is already restored, this function does nothing.
1450 * for the window is restored on the selected monitor. If the window is 1946 *
1451 * already restored, this function does nothing. 1947 * If the specified window is a full screen window, the resolution chosen for
1948 * the window is restored on the selected monitor.
1452 * 1949 *
1453 * @param[in] window The window to restore. 1950 * @param[in] window The window to restore.
1454 * 1951 *
1455 * @note This function may only be called from the main thread. 1952 * @par Thread Safety
1953 * This function may only be called from the main thread.
1456 * 1954 *
1955 * @sa @ref window_iconify
1457 * @sa glfwIconifyWindow 1956 * @sa glfwIconifyWindow
1458 * 1957 *
1958 * @since Added in GLFW 2.1.
1959 *
1960 * @par
1961 * __GLFW 3:__ Added window handle parameter.
1962 *
1459 * @ingroup window 1963 * @ingroup window
1460 */ 1964 */
1461GLFWAPI void glfwRestoreWindow(GLFWwindow* window); 1965GLFWAPI void glfwRestoreWindow(GLFWwindow* window);
1462 1966
1463/*! @brief Makes the specified window visible. 1967/*! @brief Makes the specified window visible.
1464 * 1968 *
1465 * This function makes the specified window visible, if it was previously 1969 * This function makes the specified window visible if it was previously
1466 * hidden. If the window is already visible or is in full screen mode, this 1970 * hidden. If the window is already visible or is in full screen mode, this
1467 * function does nothing. 1971 * function does nothing.
1468 * 1972 *
1469 * @param[in] window The window to make visible. 1973 * @param[in] window The window to make visible.
1470 * 1974 *
1471 * @note This function may only be called from the main thread. 1975 * @par Thread Safety
1976 * This function may only be called from the main thread.
1472 * 1977 *
1978 * @sa @ref window_hide
1473 * @sa glfwHideWindow 1979 * @sa glfwHideWindow
1474 * 1980 *
1981 * @since Added in GLFW 3.0.
1982 *
1475 * @ingroup window 1983 * @ingroup window
1476 */ 1984 */
1477GLFWAPI void glfwShowWindow(GLFWwindow* window); 1985GLFWAPI void glfwShowWindow(GLFWwindow* window);
1478 1986
1479/*! @brief Hides the specified window. 1987/*! @brief Hides the specified window.
1480 * 1988 *
1481 * This function hides the specified window, if it was previously visible. If 1989 * This function hides the specified window if it was previously visible. If
1482 * the window is already hidden or is in full screen mode, this function does 1990 * the window is already hidden or is in full screen mode, this function does
1483 * nothing. 1991 * nothing.
1484 * 1992 *
1485 * @param[in] window The window to hide. 1993 * @param[in] window The window to hide.
1486 * 1994 *
1487 * @note This function may only be called from the main thread. 1995 * @par Thread Safety
1996 * This function may only be called from the main thread.
1488 * 1997 *
1998 * @sa @ref window_hide
1489 * @sa glfwShowWindow 1999 * @sa glfwShowWindow
1490 * 2000 *
2001 * @since Added in GLFW 3.0.
2002 *
1491 * @ingroup window 2003 * @ingroup window
1492 */ 2004 */
1493GLFWAPI void glfwHideWindow(GLFWwindow* window); 2005GLFWAPI void glfwHideWindow(GLFWwindow* window);
@@ -1498,7 +2010,15 @@ GLFWAPI void glfwHideWindow(GLFWwindow* window);
1498 * in full screen on. 2010 * in full screen on.
1499 * 2011 *
1500 * @param[in] window The window to query. 2012 * @param[in] window The window to query.
1501 * @return The monitor, or `NULL` if the window is in windowed mode. 2013 * @return The monitor, or `NULL` if the window is in windowed mode or an error
2014 * occurred.
2015 *
2016 * @par Thread Safety
2017 * This function may only be called from the main thread.
2018 *
2019 * @sa @ref window_monitor
2020 *
2021 * @since Added in GLFW 3.0.
1502 * 2022 *
1503 * @ingroup window 2023 * @ingroup window
1504 */ 2024 */
@@ -1506,13 +2026,22 @@ GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window);
1506 2026
1507/*! @brief Returns an attribute of the specified window. 2027/*! @brief Returns an attribute of the specified window.
1508 * 2028 *
1509 * This function returns an attribute of the specified window. There are many 2029 * This function returns the value of an attribute of the specified window or
1510 * attributes, some related to the window and others to its context. 2030 * its OpenGL or OpenGL ES context.
1511 * 2031 *
1512 * @param[in] window The window to query. 2032 * @param[in] window The window to query.
1513 * @param[in] attrib The [window attribute](@ref window_attribs) whose value to 2033 * @param[in] attrib The [window attribute](@ref window_attribs) whose value to
1514 * return. 2034 * return.
1515 * @return The value of the attribute, or zero if an error occurred. 2035 * @return The value of the attribute, or zero if an
2036 * [error](@ref error_handling) occurred.
2037 *
2038 * @par Thread Safety
2039 * This function may only be called from the main thread.
2040 *
2041 * @sa @ref window_attribs
2042 *
2043 * @since Added in GLFW 3.0. Replaces `glfwGetWindowParam` and
2044 * `glfwGetGLVersion`.
1516 * 2045 *
1517 * @ingroup window 2046 * @ingroup window
1518 */ 2047 */
@@ -1527,8 +2056,14 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib);
1527 * @param[in] window The window whose pointer to set. 2056 * @param[in] window The window whose pointer to set.
1528 * @param[in] pointer The new value. 2057 * @param[in] pointer The new value.
1529 * 2058 *
2059 * @par Thread Safety
2060 * This function may be called from any thread. Access is not synchronized.
2061 *
2062 * @sa @ref window_userptr
1530 * @sa glfwGetWindowUserPointer 2063 * @sa glfwGetWindowUserPointer
1531 * 2064 *
2065 * @since Added in GLFW 3.0.
2066 *
1532 * @ingroup window 2067 * @ingroup window
1533 */ 2068 */
1534GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* window, void* pointer); 2069GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* window, void* pointer);
@@ -1540,8 +2075,14 @@ GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* window, void* pointer);
1540 * 2075 *
1541 * @param[in] window The window whose pointer to return. 2076 * @param[in] window The window whose pointer to return.
1542 * 2077 *
2078 * @par Thread Safety
2079 * This function may be called from any thread. Access is not synchronized.
2080 *
2081 * @sa @ref window_userptr
1543 * @sa glfwSetWindowUserPointer 2082 * @sa glfwSetWindowUserPointer
1544 * 2083 *
2084 * @since Added in GLFW 3.0.
2085 *
1545 * @ingroup window 2086 * @ingroup window
1546 */ 2087 */
1547GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window); 2088GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window);
@@ -1555,8 +2096,15 @@ GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window);
1555 * @param[in] window The window whose callback to set. 2096 * @param[in] window The window whose callback to set.
1556 * @param[in] cbfun The new callback, or `NULL` to remove the currently set 2097 * @param[in] cbfun The new callback, or `NULL` to remove the currently set
1557 * callback. 2098 * callback.
1558 * @return The previously set callback, or `NULL` if no callback was set or an 2099 * @return The previously set callback, or `NULL` if no callback was set or the
1559 * error occurred. 2100 * library had not been [initialized](@ref intro_init).
2101 *
2102 * @par Thread Safety
2103 * This function may only be called from the main thread.
2104 *
2105 * @sa @ref window_pos
2106 *
2107 * @since Added in GLFW 3.0.
1560 * 2108 *
1561 * @ingroup window 2109 * @ingroup window
1562 */ 2110 */
@@ -1571,8 +2119,18 @@ GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* window, GLFWwindow
1571 * @param[in] window The window whose callback to set. 2119 * @param[in] window The window whose callback to set.
1572 * @param[in] cbfun The new callback, or `NULL` to remove the currently set 2120 * @param[in] cbfun The new callback, or `NULL` to remove the currently set
1573 * callback. 2121 * callback.
1574 * @return The previously set callback, or `NULL` if no callback was set or an 2122 * @return The previously set callback, or `NULL` if no callback was set or the
1575 * error occurred. 2123 * library had not been [initialized](@ref intro_init).
2124 *
2125 * @par Thread Safety
2126 * This function may only be called from the main thread.
2127 *
2128 * @sa @ref window_size
2129 *
2130 * @since Added in GLFW 1.0.
2131 *
2132 * @par
2133 * __GLFW 3:__ Added window handle parameter. Updated callback signature.
1576 * 2134 *
1577 * @ingroup window 2135 * @ingroup window
1578 */ 2136 */
@@ -1592,15 +2150,22 @@ GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwind
1592 * @param[in] window The window whose callback to set. 2150 * @param[in] window The window whose callback to set.
1593 * @param[in] cbfun The new callback, or `NULL` to remove the currently set 2151 * @param[in] cbfun The new callback, or `NULL` to remove the currently set
1594 * callback. 2152 * callback.
1595 * @return The previously set callback, or `NULL` if no callback was set or an 2153 * @return The previously set callback, or `NULL` if no callback was set or the
1596 * error occurred. 2154 * library had not been [initialized](@ref intro_init).
1597 * 2155 *
1598 * @par New in GLFW 3 2156 * @remarks __OS X:__ Selecting Quit from the application menu will
1599 * The close callback no longer returns a value.
1600 *
1601 * @remarks **OS X:** Selecting Quit from the application menu will
1602 * trigger the close callback for all windows. 2157 * trigger the close callback for all windows.
1603 * 2158 *
2159 * @par Thread Safety
2160 * This function may only be called from the main thread.
2161 *
2162 * @sa @ref window_close
2163 *
2164 * @since Added in GLFW 2.5.
2165 *
2166 * @par
2167 * __GLFW 3:__ Added window handle parameter. Updated callback signature.
2168 *
1604 * @ingroup window 2169 * @ingroup window
1605 */ 2170 */
1606GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwindowclosefun cbfun); 2171GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwindowclosefun cbfun);
@@ -1618,12 +2183,18 @@ GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwi
1618 * @param[in] window The window whose callback to set. 2183 * @param[in] window The window whose callback to set.
1619 * @param[in] cbfun The new callback, or `NULL` to remove the currently set 2184 * @param[in] cbfun The new callback, or `NULL` to remove the currently set
1620 * callback. 2185 * callback.
1621 * @return The previously set callback, or `NULL` if no callback was set or an 2186 * @return The previously set callback, or `NULL` if no callback was set or the
1622 * error occurred. 2187 * library had not been [initialized](@ref intro_init).
1623 * 2188 *
1624 * @note On compositing window systems such as Aero, Compiz or Aqua, where the 2189 * @par Thread Safety
1625 * window contents are saved off-screen, this callback may be called only very 2190 * This function may only be called from the main thread.
1626 * infrequently or never at all. 2191 *
2192 * @sa @ref window_refresh
2193 *
2194 * @since Added in GLFW 2.5.
2195 *
2196 * @par
2197 * __GLFW 3:__ Added window handle parameter. Updated callback signature.
1627 * 2198 *
1628 * @ingroup window 2199 * @ingroup window
1629 */ 2200 */
@@ -1632,18 +2203,25 @@ GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* window, GL
1632/*! @brief Sets the focus callback for the specified window. 2203/*! @brief Sets the focus callback for the specified window.
1633 * 2204 *
1634 * This function sets the focus callback of the specified window, which is 2205 * This function sets the focus callback of the specified window, which is
1635 * called when the window gains or loses focus. 2206 * called when the window gains or loses input focus.
1636 * 2207 *
1637 * After the focus callback is called for a window that lost focus, synthetic 2208 * After the focus callback is called for a window that lost input focus,
1638 * key and mouse button release events will be generated for all such that had 2209 * synthetic key and mouse button release events will be generated for all such
1639 * been pressed. For more information, see @ref glfwSetKeyCallback and @ref 2210 * that had been pressed. For more information, see @ref glfwSetKeyCallback
1640 * glfwSetMouseButtonCallback. 2211 * and @ref glfwSetMouseButtonCallback.
1641 * 2212 *
1642 * @param[in] window The window whose callback to set. 2213 * @param[in] window The window whose callback to set.
1643 * @param[in] cbfun The new callback, or `NULL` to remove the currently set 2214 * @param[in] cbfun The new callback, or `NULL` to remove the currently set
1644 * callback. 2215 * callback.
1645 * @return The previously set callback, or `NULL` if no callback was set or an 2216 * @return The previously set callback, or `NULL` if no callback was set or the
1646 * error occurred. 2217 * library had not been [initialized](@ref intro_init).
2218 *
2219 * @par Thread Safety
2220 * This function may only be called from the main thread.
2221 *
2222 * @sa @ref window_focus
2223 *
2224 * @since Added in GLFW 3.0.
1647 * 2225 *
1648 * @ingroup window 2226 * @ingroup window
1649 */ 2227 */
@@ -1657,8 +2235,15 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwi
1657 * @param[in] window The window whose callback to set. 2235 * @param[in] window The window whose callback to set.
1658 * @param[in] cbfun The new callback, or `NULL` to remove the currently set 2236 * @param[in] cbfun The new callback, or `NULL` to remove the currently set
1659 * callback. 2237 * callback.
1660 * @return The previously set callback, or `NULL` if no callback was set or an 2238 * @return The previously set callback, or `NULL` if no callback was set or the
1661 * error occurred. 2239 * library had not been [initialized](@ref intro_init).
2240 *
2241 * @par Thread Safety
2242 * This function may only be called from the main thread.
2243 *
2244 * @sa @ref window_iconify
2245 *
2246 * @since Added in GLFW 3.0.
1662 * 2247 *
1663 * @ingroup window 2248 * @ingroup window
1664 */ 2249 */
@@ -1672,8 +2257,15 @@ GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* window, GL
1672 * @param[in] window The window whose callback to set. 2257 * @param[in] window The window whose callback to set.
1673 * @param[in] cbfun The new callback, or `NULL` to remove the currently set 2258 * @param[in] cbfun The new callback, or `NULL` to remove the currently set
1674 * callback. 2259 * callback.
1675 * @return The previously set callback, or `NULL` if no callback was set or an 2260 * @return The previously set callback, or `NULL` if no callback was set or the
1676 * error occurred. 2261 * library had not been [initialized](@ref intro_init).
2262 *
2263 * @par Thread Safety
2264 * This function may only be called from the main thread.
2265 *
2266 * @sa @ref window_fbsize
2267 *
2268 * @since Added in GLFW 3.0.
1677 * 2269 *
1678 * @ingroup window 2270 * @ingroup window
1679 */ 2271 */
@@ -1681,114 +2273,164 @@ GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* window
1681 2273
1682/*! @brief Processes all pending events. 2274/*! @brief Processes all pending events.
1683 * 2275 *
1684 * This function processes only those events that have already been received 2276 * This function processes only those events that are already in the event
1685 * and then returns immediately. Processing events will cause the window and 2277 * queue and then returns immediately. Processing events will cause the window
1686 * input callbacks associated with those events to be called. 2278 * and input callbacks associated with those events to be called.
1687 *
1688 * This function is not required for joystick input to work.
1689 * 2279 *
1690 * @par New in GLFW 3 2280 * On some platforms, a window move, resize or menu operation will cause event
1691 * This function is no longer called by @ref glfwSwapBuffers. You need to call 2281 * processing to block. This is due to how event processing is designed on
1692 * it or @ref glfwWaitEvents yourself. 2282 * those platforms. You can use the
2283 * [window refresh callback](@ref window_refresh) to redraw the contents of
2284 * your window when necessary during such operations.
1693 * 2285 *
1694 * @remarks On some platforms, a window move, resize or menu operation will 2286 * On some platforms, certain events are sent directly to the application
1695 * cause event processing to block. This is due to how event processing is 2287 * without going through the event queue, causing callbacks to be called
1696 * designed on those platforms. You can use the 2288 * outside of a call to one of the event processing functions.
1697 * [window refresh callback](@ref GLFWwindowrefreshfun) to redraw the contents
1698 * of your window when necessary during the operation.
1699 * 2289 *
1700 * @note This function may only be called from the main thread. 2290 * Event processing is not required for joystick input to work.
1701 * 2291 *
1702 * @note This function may not be called from a callback. 2292 * @par Reentrancy
2293 * This function may not be called from a callback.
1703 * 2294 *
1704 * @note On some platforms, certain callbacks may be called outside of a call 2295 * @par Thread Safety
1705 * to one of the event processing functions. 2296 * This function may only be called from the main thread.
1706 * 2297 *
2298 * @sa @ref events
1707 * @sa glfwWaitEvents 2299 * @sa glfwWaitEvents
1708 * 2300 *
2301 * @since Added in GLFW 1.0.
2302 *
1709 * @ingroup window 2303 * @ingroup window
1710 */ 2304 */
1711GLFWAPI void glfwPollEvents(void); 2305GLFWAPI void glfwPollEvents(void);
1712 2306
1713/*! @brief Waits until events are pending and processes them. 2307/*! @brief Waits until events are queued and processes them.
1714 * 2308 *
1715 * This function puts the calling thread to sleep until at least one event has 2309 * This function puts the calling thread to sleep until at least one event is
1716 * been received. Once one or more events have been received, it behaves as if 2310 * available in the event queue. Once one or more events are available,
1717 * @ref glfwPollEvents was called, i.e. the events are processed and the 2311 * it behaves exactly like @ref glfwPollEvents, i.e. the events in the queue
1718 * function then returns immediately. Processing events will cause the window 2312 * are processed and the function then returns immediately. Processing events
1719 * and input callbacks associated with those events to be called. 2313 * will cause the window and input callbacks associated with those events to be
2314 * called.
1720 * 2315 *
1721 * Since not all events are associated with callbacks, this function may return 2316 * Since not all events are associated with callbacks, this function may return
1722 * without a callback having been called even if you are monitoring all 2317 * without a callback having been called even if you are monitoring all
1723 * callbacks. 2318 * callbacks.
1724 * 2319 *
1725 * This function is not required for joystick input to work. 2320 * On some platforms, a window move, resize or menu operation will cause event
2321 * processing to block. This is due to how event processing is designed on
2322 * those platforms. You can use the
2323 * [window refresh callback](@ref window_refresh) to redraw the contents of
2324 * your window when necessary during such operations.
1726 * 2325 *
1727 * @remarks On some platforms, a window move, resize or menu operation will 2326 * On some platforms, certain callbacks may be called outside of a call to one
1728 * cause event processing to block. This is due to how event processing is 2327 * of the event processing functions.
1729 * designed on those platforms. You can use the
1730 * [window refresh callback](@ref GLFWwindowrefreshfun) to redraw the contents
1731 * of your window when necessary during the operation.
1732 * 2328 *
1733 * @note This function may only be called from the main thread. 2329 * If no windows exist, this function returns immediately. For synchronization
2330 * of threads in applications that do not create windows, use your threading
2331 * library of choice.
1734 * 2332 *
1735 * @note This function may not be called from a callback. 2333 * Event processing is not required for joystick input to work.
1736 * 2334 *
1737 * @note On some platforms, certain callbacks may be called outside of a call 2335 * @par Reentrancy
1738 * to one of the event processing functions. 2336 * This function may not be called from a callback.
1739 * 2337 *
2338 * @par Thread Safety
2339 * This function may only be called from the main thread.
2340 *
2341 * @sa @ref events
1740 * @sa glfwPollEvents 2342 * @sa glfwPollEvents
1741 * 2343 *
2344 * @since Added in GLFW 2.5.
2345 *
1742 * @ingroup window 2346 * @ingroup window
1743 */ 2347 */
1744GLFWAPI void glfwWaitEvents(void); 2348GLFWAPI void glfwWaitEvents(void);
1745 2349
2350/*! @brief Posts an empty event to the event queue.
2351 *
2352 * This function posts an empty event from the current thread to the event
2353 * queue, causing @ref glfwWaitEvents to return.
2354 *
2355 * If no windows exist, this function returns immediately. For synchronization
2356 * of threads in applications that do not create windows, use your threading
2357 * library of choice.
2358 *
2359 * @par Thread Safety
2360 * This function may be called from any thread.
2361 *
2362 * @sa @ref events
2363 * @sa glfwWaitEvents
2364 *
2365 * @since Added in GLFW 3.1.
2366 *
2367 * @ingroup window
2368 */
2369GLFWAPI void glfwPostEmptyEvent(void);
2370
1746/*! @brief Returns the value of an input option for the specified window. 2371/*! @brief Returns the value of an input option for the specified window.
1747 * 2372 *
2373 * This function returns the value of an input option for the specified window.
2374 * The mode must be one of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or
2375 * `GLFW_STICKY_MOUSE_BUTTONS`.
2376 *
1748 * @param[in] window The window to query. 2377 * @param[in] window The window to query.
1749 * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or 2378 * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or
1750 * `GLFW_STICKY_MOUSE_BUTTONS`. 2379 * `GLFW_STICKY_MOUSE_BUTTONS`.
1751 * 2380 *
2381 * @par Thread Safety
2382 * This function may only be called from the main thread.
2383 *
1752 * @sa glfwSetInputMode 2384 * @sa glfwSetInputMode
1753 * 2385 *
2386 * @since Added in GLFW 3.0.
2387 *
1754 * @ingroup input 2388 * @ingroup input
1755 */ 2389 */
1756GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode); 2390GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);
1757 2391
1758/*! @brief Sets an input option for the specified window. 2392/*! @brief Sets an input option for the specified window.
1759 * @param[in] window The window whose input mode to set. 2393 *
1760 * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or 2394 * This function sets an input mode option for the specified window. The mode
2395 * must be one of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or
1761 * `GLFW_STICKY_MOUSE_BUTTONS`. 2396 * `GLFW_STICKY_MOUSE_BUTTONS`.
1762 * @param[in] value The new value of the specified input mode.
1763 * 2397 *
1764 * If `mode` is `GLFW_CURSOR`, the value must be one of the supported input 2398 * If the mode is `GLFW_CURSOR`, the value must be one of the following cursor
1765 * modes: 2399 * modes:
1766 * - `GLFW_CURSOR_NORMAL` makes the cursor visible and behaving normally. 2400 * - `GLFW_CURSOR_NORMAL` makes the cursor visible and behaving normally.
1767 * - `GLFW_CURSOR_HIDDEN` makes the cursor invisible when it is over the client 2401 * - `GLFW_CURSOR_HIDDEN` makes the cursor invisible when it is over the client
1768 * area of the window but does not restrict the cursor from leaving. This is 2402 * area of the window but does not restrict the cursor from leaving.
1769 * useful if you wish to render your own cursor or have no visible cursor at
1770 * all.
1771 * - `GLFW_CURSOR_DISABLED` hides and grabs the cursor, providing virtual 2403 * - `GLFW_CURSOR_DISABLED` hides and grabs the cursor, providing virtual
1772 * and unlimited cursor movement. This is useful for implementing for 2404 * and unlimited cursor movement. This is useful for implementing for
1773 * example 3D camera controls. 2405 * example 3D camera controls.
1774 * 2406 *
1775 * If `mode` is `GLFW_STICKY_KEYS`, the value must be either `GL_TRUE` to 2407 * If the mode is `GLFW_STICKY_KEYS`, the value must be either `GL_TRUE` to
1776 * enable sticky keys, or `GL_FALSE` to disable it. If sticky keys are 2408 * enable sticky keys, or `GL_FALSE` to disable it. If sticky keys are
1777 * enabled, a key press will ensure that @ref glfwGetKey returns @ref 2409 * enabled, a key press will ensure that @ref glfwGetKey returns `GLFW_PRESS`
1778 * GLFW_PRESS the next time it is called even if the key had been released 2410 * the next time it is called even if the key had been released before the
1779 * before the call. This is useful when you are only interested in whether 2411 * call. This is useful when you are only interested in whether keys have been
1780 * keys have been pressed but not when or in which order. 2412 * pressed but not when or in which order.
1781 * 2413 *
1782 * If `mode` is `GLFW_STICKY_MOUSE_BUTTONS`, the value must be either `GL_TRUE` 2414 * If the mode is `GLFW_STICKY_MOUSE_BUTTONS`, the value must be either
1783 * to enable sticky mouse buttons, or `GL_FALSE` to disable it. If sticky 2415 * `GL_TRUE` to enable sticky mouse buttons, or `GL_FALSE` to disable it. If
1784 * mouse buttons are enabled, a mouse button press will ensure that @ref 2416 * sticky mouse buttons are enabled, a mouse button press will ensure that @ref
1785 * glfwGetMouseButton returns @ref GLFW_PRESS the next time it is called even 2417 * glfwGetMouseButton returns `GLFW_PRESS` the next time it is called even if
1786 * if the mouse button had been released before the call. This is useful when 2418 * the mouse button had been released before the call. This is useful when you
1787 * you are only interested in whether mouse buttons have been pressed but not 2419 * are only interested in whether mouse buttons have been pressed but not when
1788 * when or in which order. 2420 * or in which order.
2421 *
2422 * @param[in] window The window whose input mode to set.
2423 * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or
2424 * `GLFW_STICKY_MOUSE_BUTTONS`.
2425 * @param[in] value The new value of the specified input mode.
2426 *
2427 * @par Thread Safety
2428 * This function may only be called from the main thread.
1789 * 2429 *
1790 * @sa glfwGetInputMode 2430 * @sa glfwGetInputMode
1791 * 2431 *
2432 * @since Added in GLFW 3.0. Replaces `glfwEnable` and `glfwDisable`.
2433 *
1792 * @ingroup input 2434 * @ingroup input
1793 */ 2435 */
1794GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value); 2436GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value);
@@ -1798,22 +2440,34 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value);
1798 * 2440 *
1799 * This function returns the last state reported for the specified key to the 2441 * This function returns the last state reported for the specified key to the
1800 * specified window. The returned state is one of `GLFW_PRESS` or 2442 * specified window. The returned state is one of `GLFW_PRESS` or
1801 * `GLFW_RELEASE`. The higher-level state `GLFW_REPEAT` is only reported to 2443 * `GLFW_RELEASE`. The higher-level action `GLFW_REPEAT` is only reported to
1802 * the key callback. 2444 * the key callback.
1803 * 2445 *
1804 * If the `GLFW_STICKY_KEYS` input mode is enabled, this function returns 2446 * If the `GLFW_STICKY_KEYS` input mode is enabled, this function returns
1805 * `GLFW_PRESS` the first time you call this function after a key has been 2447 * `GLFW_PRESS` the first time you call it for a key that was pressed, even if
1806 * pressed, even if the key has already been released. 2448 * that key has already been released.
1807 * 2449 *
1808 * The key functions deal with physical keys, with [key tokens](@ref keys) 2450 * The key functions deal with physical keys, with [key tokens](@ref keys)
1809 * named after their use on the standard US keyboard layout. If you want to 2451 * named after their use on the standard US keyboard layout. If you want to
1810 * input text, use the Unicode character callback instead. 2452 * input text, use the Unicode character callback instead.
1811 * 2453 *
2454 * The [modifier key bit masks](@ref mods) are not key tokens and cannot be
2455 * used with this function.
2456 *
1812 * @param[in] window The desired window. 2457 * @param[in] window The desired window.
1813 * @param[in] key The desired [keyboard key](@ref keys). 2458 * @param[in] key The desired [keyboard key](@ref keys). `GLFW_KEY_UNKNOWN` is
2459 * not a valid key for this function.
1814 * @return One of `GLFW_PRESS` or `GLFW_RELEASE`. 2460 * @return One of `GLFW_PRESS` or `GLFW_RELEASE`.
1815 * 2461 *
1816 * @note `GLFW_KEY_UNKNOWN` is not a valid key for this function. 2462 * @par Thread Safety
2463 * This function may only be called from the main thread.
2464 *
2465 * @sa @ref input_key
2466 *
2467 * @since Added in GLFW 1.0.
2468 *
2469 * @par
2470 * __GLFW 3:__ Added window handle parameter.
1817 * 2471 *
1818 * @ingroup input 2472 * @ingroup input
1819 */ 2473 */
@@ -1823,26 +2477,37 @@ GLFWAPI int glfwGetKey(GLFWwindow* window, int key);
1823 * window. 2477 * window.
1824 * 2478 *
1825 * This function returns the last state reported for the specified mouse button 2479 * This function returns the last state reported for the specified mouse button
1826 * to the specified window. 2480 * to the specified window. The returned state is one of `GLFW_PRESS` or
2481 * `GLFW_RELEASE`.
1827 * 2482 *
1828 * If the `GLFW_STICKY_MOUSE_BUTTONS` input mode is enabled, this function 2483 * If the `GLFW_STICKY_MOUSE_BUTTONS` input mode is enabled, this function
1829 * returns `GLFW_PRESS` the first time you call this function after a mouse 2484 * `GLFW_PRESS` the first time you call it for a mouse button that was pressed,
1830 * button has been pressed, even if the mouse button has already been released. 2485 * even if that mouse button has already been released.
1831 * 2486 *
1832 * @param[in] window The desired window. 2487 * @param[in] window The desired window.
1833 * @param[in] button The desired [mouse button](@ref buttons). 2488 * @param[in] button The desired [mouse button](@ref buttons).
1834 * @return One of `GLFW_PRESS` or `GLFW_RELEASE`. 2489 * @return One of `GLFW_PRESS` or `GLFW_RELEASE`.
1835 * 2490 *
2491 * @par Thread Safety
2492 * This function may only be called from the main thread.
2493 *
2494 * @sa @ref input_mouse_button
2495 *
2496 * @since Added in GLFW 1.0.
2497 *
2498 * @par
2499 * __GLFW 3:__ Added window handle parameter.
2500 *
1836 * @ingroup input 2501 * @ingroup input
1837 */ 2502 */
1838GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button); 2503GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button);
1839 2504
1840/*! @brief Retrieves the last reported cursor position, relative to the client 2505/*! @brief Retrieves the position of the cursor relative to the client area of
1841 * area of the window. 2506 * the window.
1842 * 2507 *
1843 * This function returns the last reported position of the cursor, in screen 2508 * This function returns the position of the cursor, in screen coordinates,
1844 * coordinates, relative to the upper-left corner of the client area of the 2509 * relative to the upper-left corner of the client area of the specified
1845 * specified window. 2510 * window.
1846 * 2511 *
1847 * If the cursor is disabled (with `GLFW_CURSOR_DISABLED`) then the cursor 2512 * If the cursor is disabled (with `GLFW_CURSOR_DISABLED`) then the cursor
1848 * position is unbounded and limited only by the minimum and maximum values of 2513 * position is unbounded and limited only by the minimum and maximum values of
@@ -1852,14 +2517,23 @@ GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button);
1852 * `floor` function. Casting directly to an integer type works for positive 2517 * `floor` function. Casting directly to an integer type works for positive
1853 * coordinates, but fails for negative ones. 2518 * coordinates, but fails for negative ones.
1854 * 2519 *
2520 * Any or all of the position arguments may be `NULL`. If an error occurs, all
2521 * non-`NULL` position arguments will be set to zero.
2522 *
1855 * @param[in] window The desired window. 2523 * @param[in] window The desired window.
1856 * @param[out] xpos Where to store the cursor x-coordinate, relative to the 2524 * @param[out] xpos Where to store the cursor x-coordinate, relative to the
1857 * left edge of the client area, or `NULL`. 2525 * left edge of the client area, or `NULL`.
1858 * @param[out] ypos Where to store the cursor y-coordinate, relative to the to 2526 * @param[out] ypos Where to store the cursor y-coordinate, relative to the to
1859 * top edge of the client area, or `NULL`. 2527 * top edge of the client area, or `NULL`.
1860 * 2528 *
2529 * @par Thread Safety
2530 * This function may only be called from the main thread.
2531 *
2532 * @sa @ref cursor_pos
1861 * @sa glfwSetCursorPos 2533 * @sa glfwSetCursorPos
1862 * 2534 *
2535 * @since Added in GLFW 3.0. Replaces `glfwGetMousePos`.
2536 *
1863 * @ingroup input 2537 * @ingroup input
1864 */ 2538 */
1865GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos); 2539GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos);
@@ -1869,11 +2543,16 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos);
1869 * 2543 *
1870 * This function sets the position, in screen coordinates, of the cursor 2544 * This function sets the position, in screen coordinates, of the cursor
1871 * relative to the upper-left corner of the client area of the specified 2545 * relative to the upper-left corner of the client area of the specified
1872 * window. The window must be focused. If the window does not have focus when 2546 * window. The window must have input focus. If the window does not have
1873 * this function is called, it fails silently. 2547 * input focus when this function is called, it fails silently.
1874 * 2548 *
1875 * If the cursor is disabled (with `GLFW_CURSOR_DISABLED`) then the cursor 2549 * __Do not use this function__ to implement things like camera controls. GLFW
1876 * position is unbounded and limited only by the minimum and maximum values of 2550 * already provides the `GLFW_CURSOR_DISABLED` cursor mode that hides the
2551 * cursor, transparently re-centers it and provides unconstrained cursor
2552 * motion. See @ref glfwSetInputMode for more information.
2553 *
2554 * If the cursor mode is `GLFW_CURSOR_DISABLED` then the cursor position is
2555 * unconstrained and limited only by the minimum and maximum values of
1877 * a `double`. 2556 * a `double`.
1878 * 2557 *
1879 * @param[in] window The desired window. 2558 * @param[in] window The desired window.
@@ -1882,15 +2561,138 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos);
1882 * @param[in] ypos The desired y-coordinate, relative to the top edge of the 2561 * @param[in] ypos The desired y-coordinate, relative to the top edge of the
1883 * client area. 2562 * client area.
1884 * 2563 *
2564 * @remarks __X11:__ Due to the asynchronous nature of a modern X desktop, it
2565 * may take a moment for the window focus event to arrive. This means you will
2566 * not be able to set the cursor position directly after window creation.
2567 *
2568 * @par Thread Safety
2569 * This function may only be called from the main thread.
2570 *
2571 * @sa @ref cursor_pos
1885 * @sa glfwGetCursorPos 2572 * @sa glfwGetCursorPos
1886 * 2573 *
2574 * @since Added in GLFW 3.0. Replaces `glfwSetMousePos`.
2575 *
1887 * @ingroup input 2576 * @ingroup input
1888 */ 2577 */
1889GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos); 2578GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos);
1890 2579
2580/*! @brief Creates a custom cursor.
2581 *
2582 * Creates a new custom cursor image that can be set for a window with @ref
2583 * glfwSetCursor. The cursor can be destroyed with @ref glfwDestroyCursor.
2584 * Any remaining cursors are destroyed by @ref glfwTerminate.
2585 *
2586 * The pixels are 32-bit little-endian RGBA, i.e. eight bits per channel. They
2587 * are arranged canonically as packed sequential rows, starting from the
2588 * top-left corner.
2589 *
2590 * The cursor hotspot is specified in pixels, relative to the upper-left corner
2591 * of the cursor image. Like all other coordinate systems in GLFW, the X-axis
2592 * points to the right and the Y-axis points down.
2593 *
2594 * @param[in] image The desired cursor image.
2595 * @param[in] xhot The desired x-coordinate, in pixels, of the cursor hotspot.
2596 * @param[in] yhot The desired y-coordinate, in pixels, of the cursor hotspot.
2597 *
2598 * @return The handle of the created cursor, or `NULL` if an
2599 * [error](@ref error_handling) occurred.
2600 *
2601 * @par Pointer Lifetime
2602 * The specified image data is copied before this function returns.
2603 *
2604 * @par Reentrancy
2605 * This function may not be called from a callback.
2606 *
2607 * @par Thread Safety
2608 * This function may only be called from the main thread.
2609 *
2610 * @sa @ref cursor_object
2611 * @sa glfwDestroyCursor
2612 * @sa glfwCreateStandardCursor
2613 *
2614 * @since Added in GLFW 3.1.
2615 *
2616 * @ingroup input
2617 */
2618GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot);
2619
2620/*! @brief Creates a cursor with a standard shape.
2621 *
2622 * Returns a cursor with a [standard shape](@ref shapes), that can be set for
2623 * a window with @ref glfwSetCursor.
2624 *
2625 * @param[in] shape One of the [standard shapes](@ref shapes).
2626 *
2627 * @return A new cursor ready to use or `NULL` if an
2628 * [error](@ref error_handling) occurred.
2629 *
2630 * @par Reentrancy
2631 * This function may not be called from a callback.
2632 *
2633 * @par Thread Safety
2634 * This function may only be called from the main thread.
2635 *
2636 * @sa @ref cursor_object
2637 * @sa glfwCreateCursor
2638 *
2639 * @since Added in GLFW 3.1.
2640 *
2641 * @ingroup input
2642 */
2643GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape);
2644
2645/*! @brief Destroys a cursor.
2646 *
2647 * This function destroys a cursor previously created with @ref
2648 * glfwCreateCursor. Any remaining cursors will be destroyed by @ref
2649 * glfwTerminate.
2650 *
2651 * @param[in] cursor The cursor object to destroy.
2652 *
2653 * @par Reentrancy
2654 * This function may not be called from a callback.
2655 *
2656 * @par Thread Safety
2657 * This function may only be called from the main thread.
2658 *
2659 * @sa @ref cursor_object
2660 * @sa glfwCreateCursor
2661 *
2662 * @since Added in GLFW 3.1.
2663 *
2664 * @ingroup input
2665 */
2666GLFWAPI void glfwDestroyCursor(GLFWcursor* cursor);
2667
2668/*! @brief Sets the cursor for the window.
2669 *
2670 * This function sets the cursor image to be used when the cursor is over the
2671 * client area of the specified window. The set cursor will only be visible
2672 * when the [cursor mode](@ref cursor_mode) of the window is
2673 * `GLFW_CURSOR_NORMAL`.
2674 *
2675 * On some platforms, the set cursor may not be visible unless the window also
2676 * has input focus.
2677 *
2678 * @param[in] window The window to set the cursor for.
2679 * @param[in] cursor The cursor to set, or `NULL` to switch back to the default
2680 * arrow cursor.
2681 *
2682 * @par Thread Safety
2683 * This function may only be called from the main thread.
2684 *
2685 * @sa @ref cursor_object
2686 *
2687 * @since Added in GLFW 3.1.
2688 *
2689 * @ingroup input
2690 */
2691GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor);
2692
1891/*! @brief Sets the key callback. 2693/*! @brief Sets the key callback.
1892 * 2694 *
1893 * This function sets the key callback of the specific window, which is called 2695 * This function sets the key callback of the specified window, which is called
1894 * when a key is pressed, repeated or released. 2696 * when a key is pressed, repeated or released.
1895 * 2697 *
1896 * The key functions deal with physical keys, with layout independent 2698 * The key functions deal with physical keys, with layout independent
@@ -1898,16 +2700,16 @@ GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos);
1898 * layout. If you want to input text, use the 2700 * layout. If you want to input text, use the
1899 * [character callback](@ref glfwSetCharCallback) instead. 2701 * [character callback](@ref glfwSetCharCallback) instead.
1900 * 2702 *
1901 * When a window loses focus, it will generate synthetic key release events 2703 * When a window loses input focus, it will generate synthetic key release
1902 * for all pressed keys. You can tell these events from user-generated events 2704 * events for all pressed keys. You can tell these events from user-generated
1903 * by the fact that the synthetic ones are generated after the window has lost 2705 * events by the fact that the synthetic ones are generated after the focus
1904 * focus, i.e. `GLFW_FOCUSED` will be false and the focus callback will have 2706 * loss event has been processed, i.e. after the
1905 * already been called. 2707 * [window focus callback](@ref glfwSetWindowFocusCallback) has been called.
1906 * 2708 *
1907 * The scancode of a key is specific to that platform or sometimes even to that 2709 * The scancode of a key is specific to that platform or sometimes even to that
1908 * machine. Scancodes are intended to allow users to bind keys that don't have 2710 * machine. Scancodes are intended to allow users to bind keys that don't have
1909 * a GLFW key token. Such keys have `key` set to `GLFW_KEY_UNKNOWN`, their 2711 * a GLFW key token. Such keys have `key` set to `GLFW_KEY_UNKNOWN`, their
1910 * state is not saved and so it cannot be retrieved with @ref glfwGetKey. 2712 * state is not saved and so it cannot be queried with @ref glfwGetKey.
1911 * 2713 *
1912 * Sometimes GLFW needs to generate synthetic key events, in which case the 2714 * Sometimes GLFW needs to generate synthetic key events, in which case the
1913 * scancode may be zero. 2715 * scancode may be zero.
@@ -1915,8 +2717,18 @@ GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos);
1915 * @param[in] window The window whose callback to set. 2717 * @param[in] window The window whose callback to set.
1916 * @param[in] cbfun The new key callback, or `NULL` to remove the currently 2718 * @param[in] cbfun The new key callback, or `NULL` to remove the currently
1917 * set callback. 2719 * set callback.
1918 * @return The previously set callback, or `NULL` if no callback was set or an 2720 * @return The previously set callback, or `NULL` if no callback was set or the
1919 * error occurred. 2721 * library had not been [initialized](@ref intro_init).
2722 *
2723 * @par Thread Safety
2724 * This function may only be called from the main thread.
2725 *
2726 * @sa @ref input_key
2727 *
2728 * @since Added in GLFW 1.0.
2729 *
2730 * @par
2731 * __GLFW 3:__ Added window handle parameter. Updated callback signature.
1920 * 2732 *
1921 * @ingroup input 2733 * @ingroup input
1922 */ 2734 */
@@ -1924,11 +2736,56 @@ GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun cbfun);
1924 2736
1925/*! @brief Sets the Unicode character callback. 2737/*! @brief Sets the Unicode character callback.
1926 * 2738 *
1927 * This function sets the character callback of the specific window, which is 2739 * This function sets the character callback of the specified window, which is
1928 * called when a Unicode character is input. 2740 * called when a Unicode character is input.
1929 * 2741 *
1930 * The character callback is intended for text input. If you want to know 2742 * The character callback is intended for Unicode text input. As it deals with
1931 * whether a specific key was pressed or released, use the 2743 * characters, it is keyboard layout dependent, whereas the
2744 * [key callback](@ref glfwSetKeyCallback) is not. Characters do not map 1:1
2745 * to physical keys, as a key may produce zero, one or more characters. If you
2746 * want to know whether a specific physical key was pressed or released, see
2747 * the key callback instead.
2748 *
2749 * The character callback behaves as system text input normally does and will
2750 * not be called if modifier keys are held down that would prevent normal text
2751 * input on that platform, for example a Super (Command) key on OS X or Alt key
2752 * on Windows. There is a
2753 * [character with modifiers callback](@ref glfwSetCharModsCallback) that
2754 * receives these events.
2755 *
2756 * @param[in] window The window whose callback to set.
2757 * @param[in] cbfun The new callback, or `NULL` to remove the currently set
2758 * callback.
2759 * @return The previously set callback, or `NULL` if no callback was set or the
2760 * library had not been [initialized](@ref intro_init).
2761 *
2762 * @par Thread Safety
2763 * This function may only be called from the main thread.
2764 *
2765 * @sa @ref input_char
2766 *
2767 * @since Added in GLFW 2.4.
2768 *
2769 * @par
2770 * __GLFW 3:__ Added window handle parameter. Updated callback signature.
2771 *
2772 * @ingroup input
2773 */
2774GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* window, GLFWcharfun cbfun);
2775
2776/*! @brief Sets the Unicode character with modifiers callback.
2777 *
2778 * This function sets the character with modifiers callback of the specified
2779 * window, which is called when a Unicode character is input regardless of what
2780 * modifier keys are used.
2781 *
2782 * The character with modifiers callback is intended for implementing custom
2783 * Unicode character input. For regular Unicode text input, see the
2784 * [character callback](@ref glfwSetCharCallback). Like the character
2785 * callback, the character with modifiers callback deals with characters and is
2786 * keyboard layout dependent. Characters do not map 1:1 to physical keys, as
2787 * a key may produce zero, one or more characters. If you want to know whether
2788 * a specific physical key was pressed or released, see the
1932 * [key callback](@ref glfwSetKeyCallback) instead. 2789 * [key callback](@ref glfwSetKeyCallback) instead.
1933 * 2790 *
1934 * @param[in] window The window whose callback to set. 2791 * @param[in] window The window whose callback to set.
@@ -1937,26 +2794,43 @@ GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun cbfun);
1937 * @return The previously set callback, or `NULL` if no callback was set or an 2794 * @return The previously set callback, or `NULL` if no callback was set or an
1938 * error occurred. 2795 * error occurred.
1939 * 2796 *
2797 * @par Thread Safety
2798 * This function may only be called from the main thread.
2799 *
2800 * @sa @ref input_char
2801 *
2802 * @since Added in GLFW 3.1.
2803 *
1940 * @ingroup input 2804 * @ingroup input
1941 */ 2805 */
1942GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* window, GLFWcharfun cbfun); 2806GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmodsfun cbfun);
1943 2807
1944/*! @brief Sets the mouse button callback. 2808/*! @brief Sets the mouse button callback.
1945 * 2809 *
1946 * This function sets the mouse button callback of the specified window, which 2810 * This function sets the mouse button callback of the specified window, which
1947 * is called when a mouse button is pressed or released. 2811 * is called when a mouse button is pressed or released.
1948 * 2812 *
1949 * When a window loses focus, it will generate synthetic mouse button release 2813 * When a window loses input focus, it will generate synthetic mouse button
1950 * events for all pressed mouse buttons. You can tell these events from 2814 * release events for all pressed mouse buttons. You can tell these events
1951 * user-generated events by the fact that the synthetic ones are generated 2815 * from user-generated events by the fact that the synthetic ones are generated
1952 * after the window has lost focus, i.e. `GLFW_FOCUSED` will be false and the 2816 * after the focus loss event has been processed, i.e. after the
1953 * focus callback will have already been called. 2817 * [window focus callback](@ref glfwSetWindowFocusCallback) has been called.
1954 * 2818 *
1955 * @param[in] window The window whose callback to set. 2819 * @param[in] window The window whose callback to set.
1956 * @param[in] cbfun The new callback, or `NULL` to remove the currently set 2820 * @param[in] cbfun The new callback, or `NULL` to remove the currently set
1957 * callback. 2821 * callback.
1958 * @return The previously set callback, or `NULL` if no callback was set or an 2822 * @return The previously set callback, or `NULL` if no callback was set or the
1959 * error occurred. 2823 * library had not been [initialized](@ref intro_init).
2824 *
2825 * @par Thread Safety
2826 * This function may only be called from the main thread.
2827 *
2828 * @sa @ref input_mouse_button
2829 *
2830 * @since Added in GLFW 1.0.
2831 *
2832 * @par
2833 * __GLFW 3:__ Added window handle parameter. Updated callback signature.
1960 * 2834 *
1961 * @ingroup input 2835 * @ingroup input
1962 */ 2836 */
@@ -1972,8 +2846,15 @@ GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* window, GLFWmo
1972 * @param[in] window The window whose callback to set. 2846 * @param[in] window The window whose callback to set.
1973 * @param[in] cbfun The new callback, or `NULL` to remove the currently set 2847 * @param[in] cbfun The new callback, or `NULL` to remove the currently set
1974 * callback. 2848 * callback.
1975 * @return The previously set callback, or `NULL` if no callback was set or an 2849 * @return The previously set callback, or `NULL` if no callback was set or the
1976 * error occurred. 2850 * library had not been [initialized](@ref intro_init).
2851 *
2852 * @par Thread Safety
2853 * This function may only be called from the main thread.
2854 *
2855 * @sa @ref cursor_pos
2856 *
2857 * @since Added in GLFW 3.0. Replaces `glfwSetMousePosCallback`.
1977 * 2858 *
1978 * @ingroup input 2859 * @ingroup input
1979 */ 2860 */
@@ -1988,8 +2869,15 @@ GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* window, GLFWcursor
1988 * @param[in] window The window whose callback to set. 2869 * @param[in] window The window whose callback to set.
1989 * @param[in] cbfun The new callback, or `NULL` to remove the currently set 2870 * @param[in] cbfun The new callback, or `NULL` to remove the currently set
1990 * callback. 2871 * callback.
1991 * @return The previously set callback, or `NULL` if no callback was set or an 2872 * @return The previously set callback, or `NULL` if no callback was set or the
1992 * error occurred. 2873 * library had not been [initialized](@ref intro_init).
2874 *
2875 * @par Thread Safety
2876 * This function may only be called from the main thread.
2877 *
2878 * @sa @ref cursor_enter
2879 *
2880 * @since Added in GLFW 3.0.
1993 * 2881 *
1994 * @ingroup input 2882 * @ingroup input
1995 */ 2883 */
@@ -2007,20 +2895,61 @@ GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* window, GLFWcu
2007 * @param[in] window The window whose callback to set. 2895 * @param[in] window The window whose callback to set.
2008 * @param[in] cbfun The new scroll callback, or `NULL` to remove the currently 2896 * @param[in] cbfun The new scroll callback, or `NULL` to remove the currently
2009 * set callback. 2897 * set callback.
2010 * @return The previously set callback, or `NULL` if no callback was set or an 2898 * @return The previously set callback, or `NULL` if no callback was set or the
2011 * error occurred. 2899 * library had not been [initialized](@ref intro_init).
2900 *
2901 * @par Thread Safety
2902 * This function may only be called from the main thread.
2903 *
2904 * @sa @ref scrolling
2905 *
2906 * @since Added in GLFW 3.0. Replaces `glfwSetMouseWheelCallback`.
2012 * 2907 *
2013 * @ingroup input 2908 * @ingroup input
2014 */ 2909 */
2015GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun cbfun); 2910GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun cbfun);
2016 2911
2912/*! @brief Sets the file drop callback.
2913 *
2914 * This function sets the file drop callback of the specified window, which is
2915 * called when one or more dragged files are dropped on the window.
2916 *
2917 * Because the path array and its strings may have been generated specifically
2918 * for that event, they are not guaranteed to be valid after the callback has
2919 * returned. If you wish to use them after the callback returns, you need to
2920 * make a deep copy.
2921 *
2922 * @param[in] window The window whose callback to set.
2923 * @param[in] cbfun The new file drop callback, or `NULL` to remove the
2924 * currently set callback.
2925 * @return The previously set callback, or `NULL` if no callback was set or the
2926 * library had not been [initialized](@ref intro_init).
2927 *
2928 * @par Thread Safety
2929 * This function may only be called from the main thread.
2930 *
2931 * @sa @ref path_drop
2932 *
2933 * @since Added in GLFW 3.1.
2934 *
2935 * @ingroup input
2936 */
2937GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* window, GLFWdropfun cbfun);
2938
2017/*! @brief Returns whether the specified joystick is present. 2939/*! @brief Returns whether the specified joystick is present.
2018 * 2940 *
2019 * This function returns whether the specified joystick is present. 2941 * This function returns whether the specified joystick is present.
2020 * 2942 *
2021 * @param[in] joy The joystick to query. 2943 * @param[in] joy The [joystick](@ref joysticks) to query.
2022 * @return `GL_TRUE` if the joystick is present, or `GL_FALSE` otherwise. 2944 * @return `GL_TRUE` if the joystick is present, or `GL_FALSE` otherwise.
2023 * 2945 *
2946 * @par Thread Safety
2947 * This function may only be called from the main thread.
2948 *
2949 * @sa @ref joystick
2950 *
2951 * @since Added in GLFW 3.0. Replaces `glfwGetJoystickParam`.
2952 *
2024 * @ingroup input 2953 * @ingroup input
2025 */ 2954 */
2026GLFWAPI int glfwJoystickPresent(int joy); 2955GLFWAPI int glfwJoystickPresent(int joy);
@@ -2028,17 +2957,24 @@ GLFWAPI int glfwJoystickPresent(int joy);
2028/*! @brief Returns the values of all axes of the specified joystick. 2957/*! @brief Returns the values of all axes of the specified joystick.
2029 * 2958 *
2030 * This function returns the values of all axes of the specified joystick. 2959 * This function returns the values of all axes of the specified joystick.
2960 * Each element in the array is a value between -1.0 and 1.0.
2031 * 2961 *
2032 * @param[in] joy The joystick to query. 2962 * @param[in] joy The [joystick](@ref joysticks) to query.
2033 * @param[out] count Where to store the size of the returned array. This is 2963 * @param[out] count Where to store the number of axis values in the returned
2034 * set to zero if an error occurred. 2964 * array. This is set to zero if an error occurred.
2035 * @return An array of axis values, or `NULL` if the joystick is not present. 2965 * @return An array of axis values, or `NULL` if the joystick is not present.
2036 * 2966 *
2037 * @note The returned array is allocated and freed by GLFW. You should not 2967 * @par Pointer Lifetime
2038 * free it yourself. 2968 * The returned array is allocated and freed by GLFW. You should not free it
2969 * yourself. It is valid until the specified joystick is disconnected, this
2970 * function is called again for that joystick or the library is terminated.
2971 *
2972 * @par Thread Safety
2973 * This function may only be called from the main thread.
2039 * 2974 *
2040 * @note The returned array is valid only until the next call to @ref 2975 * @sa @ref joystick_axis
2041 * glfwGetJoystickAxes for that joystick. 2976 *
2977 * @since Added in GLFW 3.0. Replaces `glfwGetJoystickPos`.
2042 * 2978 *
2043 * @ingroup input 2979 * @ingroup input
2044 */ 2980 */
@@ -2047,17 +2983,27 @@ GLFWAPI const float* glfwGetJoystickAxes(int joy, int* count);
2047/*! @brief Returns the state of all buttons of the specified joystick. 2983/*! @brief Returns the state of all buttons of the specified joystick.
2048 * 2984 *
2049 * This function returns the state of all buttons of the specified joystick. 2985 * This function returns the state of all buttons of the specified joystick.
2986 * Each element in the array is either `GLFW_PRESS` or `GLFW_RELEASE`.
2050 * 2987 *
2051 * @param[in] joy The joystick to query. 2988 * @param[in] joy The [joystick](@ref joysticks) to query.
2052 * @param[out] count Where to store the size of the returned array. This is 2989 * @param[out] count Where to store the number of button states in the returned
2053 * set to zero if an error occurred. 2990 * array. This is set to zero if an error occurred.
2054 * @return An array of button states, or `NULL` if the joystick is not present. 2991 * @return An array of button states, or `NULL` if the joystick is not present.
2055 * 2992 *
2056 * @note The returned array is allocated and freed by GLFW. You should not 2993 * @par Pointer Lifetime
2057 * free it yourself. 2994 * The returned array is allocated and freed by GLFW. You should not free it
2995 * yourself. It is valid until the specified joystick is disconnected, this
2996 * function is called again for that joystick or the library is terminated.
2997 *
2998 * @par Thread Safety
2999 * This function may only be called from the main thread.
3000 *
3001 * @sa @ref joystick_button
2058 * 3002 *
2059 * @note The returned array is valid only until the next call to @ref 3003 * @since Added in GLFW 2.2.
2060 * glfwGetJoystickButtons for that joystick. 3004 *
3005 * @par
3006 * __GLFW 3:__ Changed to return a dynamic array.
2061 * 3007 *
2062 * @ingroup input 3008 * @ingroup input
2063 */ 3009 */
@@ -2066,16 +3012,24 @@ GLFWAPI const unsigned char* glfwGetJoystickButtons(int joy, int* count);
2066/*! @brief Returns the name of the specified joystick. 3012/*! @brief Returns the name of the specified joystick.
2067 * 3013 *
2068 * This function returns the name, encoded as UTF-8, of the specified joystick. 3014 * This function returns the name, encoded as UTF-8, of the specified joystick.
3015 * The returned string is allocated and freed by GLFW. You should not free it
3016 * yourself.
2069 * 3017 *
2070 * @param[in] joy The joystick to query. 3018 * @param[in] joy The [joystick](@ref joysticks) to query.
2071 * @return The UTF-8 encoded name of the joystick, or `NULL` if the joystick 3019 * @return The UTF-8 encoded name of the joystick, or `NULL` if the joystick
2072 * is not present. 3020 * is not present.
2073 * 3021 *
2074 * @note The returned string is allocated and freed by GLFW. You should not 3022 * @par Pointer Lifetime
2075 * free it yourself. 3023 * The returned string is allocated and freed by GLFW. You should not free it
3024 * yourself. It is valid until the specified joystick is disconnected, this
3025 * function is called again for that joystick or the library is terminated.
3026 *
3027 * @par Thread Safety
3028 * This function may only be called from the main thread.
2076 * 3029 *
2077 * @note The returned string is valid only until the next call to @ref 3030 * @sa @ref joystick_name
2078 * glfwGetJoystickName for that joystick. 3031 *
3032 * @since Added in GLFW 3.0.
2079 * 3033 *
2080 * @ingroup input 3034 * @ingroup input
2081 */ 3035 */
@@ -2084,40 +3038,50 @@ GLFWAPI const char* glfwGetJoystickName(int joy);
2084/*! @brief Sets the clipboard to the specified string. 3038/*! @brief Sets the clipboard to the specified string.
2085 * 3039 *
2086 * This function sets the system clipboard to the specified, UTF-8 encoded 3040 * This function sets the system clipboard to the specified, UTF-8 encoded
2087 * string. The string is copied before returning, so you don't have to retain 3041 * string.
2088 * it afterwards.
2089 * 3042 *
2090 * @param[in] window The window that will own the clipboard contents. 3043 * @param[in] window The window that will own the clipboard contents.
2091 * @param[in] string A UTF-8 encoded string. 3044 * @param[in] string A UTF-8 encoded string.
2092 * 3045 *
2093 * @note This function may only be called from the main thread. 3046 * @par Pointer Lifetime
3047 * The specified string is copied before this function returns.
3048 *
3049 * @par Thread Safety
3050 * This function may only be called from the main thread.
2094 * 3051 *
3052 * @sa @ref clipboard
2095 * @sa glfwGetClipboardString 3053 * @sa glfwGetClipboardString
2096 * 3054 *
2097 * @ingroup clipboard 3055 * @since Added in GLFW 3.0.
3056 *
3057 * @ingroup input
2098 */ 3058 */
2099GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string); 3059GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string);
2100 3060
2101/*! @brief Retrieves the contents of the clipboard as a string. 3061/*! @brief Returns the contents of the clipboard as a string.
2102 * 3062 *
2103 * This function returns the contents of the system clipboard, if it contains 3063 * This function returns the contents of the system clipboard, if it contains
2104 * or is convertible to a UTF-8 encoded string. 3064 * or is convertible to a UTF-8 encoded string.
2105 * 3065 *
2106 * @param[in] window The window that will request the clipboard contents. 3066 * @param[in] window The window that will request the clipboard contents.
2107 * @return The contents of the clipboard as a UTF-8 encoded string, or `NULL` 3067 * @return The contents of the clipboard as a UTF-8 encoded string, or `NULL`
2108 * if an error occurred. 3068 * if an [error](@ref error_handling) occurred.
2109 * 3069 *
2110 * @note This function may only be called from the main thread. 3070 * @par Pointer Lifetime
3071 * The returned string is allocated and freed by GLFW. You should not free it
3072 * yourself. It is valid until the next call to @ref
3073 * glfwGetClipboardString or @ref glfwSetClipboardString, or until the library
3074 * is terminated.
2111 * 3075 *
2112 * @note The returned string is allocated and freed by GLFW. You should not 3076 * @par Thread Safety
2113 * free it yourself. 3077 * This function may only be called from the main thread.
2114 *
2115 * @note The returned string is valid only until the next call to @ref
2116 * glfwGetClipboardString or @ref glfwSetClipboardString.
2117 * 3078 *
3079 * @sa @ref clipboard
2118 * @sa glfwSetClipboardString 3080 * @sa glfwSetClipboardString
2119 * 3081 *
2120 * @ingroup clipboard 3082 * @since Added in GLFW 3.0.
3083 *
3084 * @ingroup input
2121 */ 3085 */
2122GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window); 3086GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window);
2123 3087
@@ -2127,63 +3091,91 @@ GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window);
2127 * been set using @ref glfwSetTime, the timer measures time elapsed since GLFW 3091 * been set using @ref glfwSetTime, the timer measures time elapsed since GLFW
2128 * was initialized. 3092 * was initialized.
2129 * 3093 *
2130 * @return The current value, in seconds, or zero if an error occurred. 3094 * The resolution of the timer is system dependent, but is usually on the order
3095 * of a few micro- or nanoseconds. It uses the highest-resolution monotonic
3096 * time source on each supported platform.
3097 *
3098 * @return The current value, in seconds, or zero if an
3099 * [error](@ref error_handling) occurred.
3100 *
3101 * @par Thread Safety
3102 * This function may be called from any thread. Access is not synchronized.
2131 * 3103 *
2132 * @remarks This function may be called from secondary threads. 3104 * @sa @ref time
2133 * 3105 *
2134 * @note The resolution of the timer is system dependent, but is usually on the 3106 * @since Added in GLFW 1.0.
2135 * order of a few micro- or nanoseconds. It uses the highest-resolution
2136 * monotonic time source on each supported platform.
2137 * 3107 *
2138 * @ingroup time 3108 * @ingroup input
2139 */ 3109 */
2140GLFWAPI double glfwGetTime(void); 3110GLFWAPI double glfwGetTime(void);
2141 3111
2142/*! @brief Sets the GLFW timer. 3112/*! @brief Sets the GLFW timer.
2143 * 3113 *
2144 * This function sets the value of the GLFW timer. It then continues to count 3114 * This function sets the value of the GLFW timer. It then continues to count
2145 * up from that value. 3115 * up from that value. The value must be a positive finite number less than
3116 * or equal to 18446744073.0, which is approximately 584.5 years.
2146 * 3117 *
2147 * @param[in] time The new value, in seconds. 3118 * @param[in] time The new value, in seconds.
2148 * 3119 *
2149 * @note The resolution of the timer is system dependent, but is usually on the 3120 * @remarks The upper limit of the timer is calculated as
2150 * order of a few micro- or nanoseconds. It uses the highest-resolution 3121 * floor((2<sup>64</sup> - 1) / 10<sup>9</sup>) and is due to implementations
2151 * monotonic time source on each supported platform. 3122 * storing nanoseconds in 64 bits. The limit may be increased in the future.
3123 *
3124 * @par Thread Safety
3125 * This function may only be called from the main thread.
3126 *
3127 * @sa @ref time
3128 *
3129 * @since Added in GLFW 2.2.
2152 * 3130 *
2153 * @ingroup time 3131 * @ingroup input
2154 */ 3132 */
2155GLFWAPI void glfwSetTime(double time); 3133GLFWAPI void glfwSetTime(double time);
2156 3134
2157/*! @brief Makes the context of the specified window current for the calling 3135/*! @brief Makes the context of the specified window current for the calling
2158 * thread. 3136 * thread.
2159 * 3137 *
2160 * This function makes the context of the specified window current on the 3138 * This function makes the OpenGL or OpenGL ES context of the specified window
2161 * calling thread. A context can only be made current on a single thread at 3139 * current on the calling thread. A context can only be made current on
2162 * a time and each thread can have only a single current context at a time. 3140 * a single thread at a time and each thread can have only a single current
3141 * context at a time.
3142 *
3143 * By default, making a context non-current implicitly forces a pipeline flush.
3144 * On machines that support `GL_KHR_context_flush_control`, you can control
3145 * whether a context performs this flush by setting the
3146 * [GLFW_CONTEXT_RELEASE_BEHAVIOR](@ref window_hints_ctx) window hint.
2163 * 3147 *
2164 * @param[in] window The window whose context to make current, or `NULL` to 3148 * @param[in] window The window whose context to make current, or `NULL` to
2165 * detach the current context. 3149 * detach the current context.
2166 * 3150 *
2167 * @remarks This function may be called from secondary threads. 3151 * @par Thread Safety
3152 * This function may be called from any thread.
2168 * 3153 *
3154 * @sa @ref context_current
2169 * @sa glfwGetCurrentContext 3155 * @sa glfwGetCurrentContext
2170 * 3156 *
3157 * @since Added in GLFW 3.0.
3158 *
2171 * @ingroup context 3159 * @ingroup context
2172 */ 3160 */
2173GLFWAPI void glfwMakeContextCurrent(GLFWwindow* window); 3161GLFWAPI void glfwMakeContextCurrent(GLFWwindow* window);
2174 3162
2175/*! @brief Returns the window whose context is current on the calling thread. 3163/*! @brief Returns the window whose context is current on the calling thread.
2176 * 3164 *
2177 * This function returns the window whose context is current on the calling 3165 * This function returns the window whose OpenGL or OpenGL ES context is
2178 * thread. 3166 * current on the calling thread.
2179 * 3167 *
2180 * @return The window whose context is current, or `NULL` if no window's 3168 * @return The window whose context is current, or `NULL` if no window's
2181 * context is current. 3169 * context is current.
2182 * 3170 *
2183 * @remarks This function may be called from secondary threads. 3171 * @par Thread Safety
3172 * This function may be called from any thread.
2184 * 3173 *
3174 * @sa @ref context_current
2185 * @sa glfwMakeContextCurrent 3175 * @sa glfwMakeContextCurrent
2186 * 3176 *
3177 * @since Added in GLFW 3.0.
3178 *
2187 * @ingroup context 3179 * @ingroup context
2188 */ 3180 */
2189GLFWAPI GLFWwindow* glfwGetCurrentContext(void); 3181GLFWAPI GLFWwindow* glfwGetCurrentContext(void);
@@ -2196,24 +3188,28 @@ GLFWAPI GLFWwindow* glfwGetCurrentContext(void);
2196 * 3188 *
2197 * @param[in] window The window whose buffers to swap. 3189 * @param[in] window The window whose buffers to swap.
2198 * 3190 *
2199 * @remarks This function may be called from secondary threads. 3191 * @par Thread Safety
2200 * 3192 * This function may be called from any thread.
2201 * @par New in GLFW 3
2202 * This function no longer calls @ref glfwPollEvents. You need to call it or
2203 * @ref glfwWaitEvents yourself.
2204 * 3193 *
3194 * @sa @ref buffer_swap
2205 * @sa glfwSwapInterval 3195 * @sa glfwSwapInterval
2206 * 3196 *
2207 * @ingroup context 3197 * @since Added in GLFW 1.0.
3198 *
3199 * @par
3200 * __GLFW 3:__ Added window handle parameter.
3201 *
3202 * @ingroup window
2208 */ 3203 */
2209GLFWAPI void glfwSwapBuffers(GLFWwindow* window); 3204GLFWAPI void glfwSwapBuffers(GLFWwindow* window);
2210 3205
2211/*! @brief Sets the swap interval for the current context. 3206/*! @brief Sets the swap interval for the current context.
2212 * 3207 *
2213 * This function sets the swap interval for the current context, i.e. the 3208 * This function sets the swap interval for the current context, i.e. the
2214 * number of screen updates to wait before swapping the buffers of a window and 3209 * number of screen updates to wait from the time @ref glfwSwapBuffers was
2215 * returning from @ref glfwSwapBuffers. This is sometimes called 'vertical 3210 * called before swapping the buffers and returning. This is sometimes called
2216 * synchronization', 'vertical retrace synchronization' or 'vsync'. 3211 * _vertical synchronization_, _vertical retrace synchronization_ or just
3212 * _vsync_.
2217 * 3213 *
2218 * Contexts that support either of the `WGL_EXT_swap_control_tear` and 3214 * Contexts that support either of the `WGL_EXT_swap_control_tear` and
2219 * `GLX_EXT_swap_control_tear` extensions also accept negative swap intervals, 3215 * `GLX_EXT_swap_control_tear` extensions also accept negative swap intervals,
@@ -2222,22 +3218,29 @@ GLFWAPI void glfwSwapBuffers(GLFWwindow* window);
2222 * glfwExtensionSupported. For more information about swap tearing, see the 3218 * glfwExtensionSupported. For more information about swap tearing, see the
2223 * extension specifications. 3219 * extension specifications.
2224 * 3220 *
3221 * A context must be current on the calling thread. Calling this function
3222 * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error.
3223 *
2225 * @param[in] interval The minimum number of screen updates to wait for 3224 * @param[in] interval The minimum number of screen updates to wait for
2226 * until the buffers are swapped by @ref glfwSwapBuffers. 3225 * until the buffers are swapped by @ref glfwSwapBuffers.
2227 * 3226 *
2228 * @remarks This function may be called from secondary threads. 3227 * @remarks This function is not called during context creation, leaving the
2229 * 3228 * swap interval set to whatever is the default on that platform. This is done
2230 * @note This function is not called during window creation, leaving the swap
2231 * interval set to whatever is the default on that platform. This is done
2232 * because some swap interval extensions used by GLFW do not allow the swap 3229 * because some swap interval extensions used by GLFW do not allow the swap
2233 * interval to be reset to zero once it has been set to a non-zero value. 3230 * interval to be reset to zero once it has been set to a non-zero value.
2234 * 3231 *
2235 * @note Some GPU drivers do not honor the requested swap interval, either 3232 * @remarks Some GPU drivers do not honor the requested swap interval, either
2236 * because of user settings that override the request or due to bugs in the 3233 * because of a user setting that overrides the application's request or due to
2237 * driver. 3234 * bugs in the driver.
3235 *
3236 * @par Thread Safety
3237 * This function may be called from any thread.
2238 * 3238 *
3239 * @sa @ref buffer_swap
2239 * @sa glfwSwapBuffers 3240 * @sa glfwSwapBuffers
2240 * 3241 *
3242 * @since Added in GLFW 1.0.
3243 *
2241 * @ingroup context 3244 * @ingroup context
2242 */ 3245 */
2243GLFWAPI void glfwSwapInterval(int interval); 3246GLFWAPI void glfwSwapInterval(int interval);
@@ -2245,19 +3248,28 @@ GLFWAPI void glfwSwapInterval(int interval);
2245/*! @brief Returns whether the specified extension is available. 3248/*! @brief Returns whether the specified extension is available.
2246 * 3249 *
2247 * This function returns whether the specified 3250 * This function returns whether the specified
2248 * [OpenGL or context creation API extension](@ref context_glext) is supported 3251 * [client API extension](@ref context_glext) is supported by the current
2249 * by the current context. For example, on Windows both the OpenGL and WGL 3252 * OpenGL or OpenGL ES context. It searches both for OpenGL and OpenGL ES
2250 * extension strings are checked. 3253 * extension and platform-specific context creation API extensions.
3254 *
3255 * A context must be current on the calling thread. Calling this function
3256 * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error.
3257 *
3258 * As this functions retrieves and searches one or more extension strings each
3259 * call, it is recommended that you cache its results if it is going to be used
3260 * frequently. The extension strings will not change during the lifetime of
3261 * a context, so there is no danger in doing this.
2251 * 3262 *
2252 * @param[in] extension The ASCII encoded name of the extension. 3263 * @param[in] extension The ASCII encoded name of the extension.
2253 * @return `GL_TRUE` if the extension is available, or `GL_FALSE` otherwise. 3264 * @return `GL_TRUE` if the extension is available, or `GL_FALSE` otherwise.
2254 * 3265 *
2255 * @remarks This function may be called from secondary threads. 3266 * @par Thread Safety
3267 * This function may be called from any thread.
2256 * 3268 *
2257 * @note As this functions searches one or more extension strings on each call, 3269 * @sa @ref context_glext
2258 * it is recommended that you cache its results if it's going to be used 3270 * @sa glfwGetProcAddress
2259 * frequently. The extension strings will not change during the lifetime of 3271 *
2260 * a context, so there is no danger in doing this. 3272 * @since Added in GLFW 1.0.
2261 * 3273 *
2262 * @ingroup context 3274 * @ingroup context
2263 */ 3275 */
@@ -2267,18 +3279,34 @@ GLFWAPI int glfwExtensionSupported(const char* extension);
2267 * context. 3279 * context.
2268 * 3280 *
2269 * This function returns the address of the specified 3281 * This function returns the address of the specified
2270 * [client API or extension function](@ref context_glext), if it is supported 3282 * [core or extension function](@ref context_glext), if it is supported
2271 * by the current context. 3283 * by the current context.
2272 * 3284 *
3285 * A context must be current on the calling thread. Calling this function
3286 * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error.
3287 *
2273 * @param[in] procname The ASCII encoded name of the function. 3288 * @param[in] procname The ASCII encoded name of the function.
2274 * @return The address of the function, or `NULL` if the function is 3289 * @return The address of the function, or `NULL` if the function is
2275 * unavailable. 3290 * unavailable or an [error](@ref error_handling) occurred.
3291 *
3292 * @remarks The addresses of a given function is not guaranteed to be the same
3293 * between contexts.
3294 *
3295 * @remarks This function may return a non-`NULL` address despite the
3296 * associated version or extension not being available. Always check the
3297 * context version or extension string presence first.
3298 *
3299 * @par Pointer Lifetime
3300 * The returned function pointer is valid until the context is destroyed or the
3301 * library is terminated.
3302 *
3303 * @par Thread Safety
3304 * This function may be called from any thread.
2276 * 3305 *
2277 * @remarks This function may be called from secondary threads. 3306 * @sa @ref context_glext
3307 * @sa glfwExtensionSupported
2278 * 3308 *
2279 * @note The addresses of these functions are not guaranteed to be the same for 3309 * @since Added in GLFW 1.0.
2280 * all contexts, especially if they use different client APIs or even different
2281 * context creation hints.
2282 * 3310 *
2283 * @ingroup context 3311 * @ingroup context
2284 */ 3312 */
diff --git a/externals/glfw-3.1.1.bin/include/GLFW/glfw3native.h b/externals/glfw-3.1.1.bin/include/GLFW/glfw3native.h
new file mode 100644
index 000000000..b3ce7482d
--- /dev/null
+++ b/externals/glfw-3.1.1.bin/include/GLFW/glfw3native.h
@@ -0,0 +1,356 @@
1/*************************************************************************
2 * GLFW 3.1 - www.glfw.org
3 * A library for OpenGL, window and input
4 *------------------------------------------------------------------------
5 * Copyright (c) 2002-2006 Marcus Geelnard
6 * Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
7 *
8 * This software is provided 'as-is', without any express or implied
9 * warranty. In no event will the authors be held liable for any damages
10 * arising from the use of this software.
11 *
12 * Permission is granted to anyone to use this software for any purpose,
13 * including commercial applications, and to alter it and redistribute it
14 * freely, subject to the following restrictions:
15 *
16 * 1. The origin of this software must not be misrepresented; you must not
17 * claim that you wrote the original software. If you use this software
18 * in a product, an acknowledgment in the product documentation would
19 * be appreciated but is not required.
20 *
21 * 2. Altered source versions must be plainly marked as such, and must not
22 * be misrepresented as being the original software.
23 *
24 * 3. This notice may not be removed or altered from any source
25 * distribution.
26 *
27 *************************************************************************/
28
29#ifndef _glfw3_native_h_
30#define _glfw3_native_h_
31
32#ifdef __cplusplus
33extern "C" {
34#endif
35
36
37/*************************************************************************
38 * Doxygen documentation
39 *************************************************************************/
40
41/*! @defgroup native Native access
42 *
43 * **By using the native access functions you assert that you know what you're
44 * doing and how to fix problems caused by using them. If you don't, you
45 * shouldn't be using them.**
46 *
47 * Before the inclusion of @ref glfw3native.h, you must define exactly one
48 * window system API macro and exactly one context creation API macro. Failure
49 * to do this will cause a compile-time error.
50 *
51 * The available window API macros are:
52 * * `GLFW_EXPOSE_NATIVE_WIN32`
53 * * `GLFW_EXPOSE_NATIVE_COCOA`
54 * * `GLFW_EXPOSE_NATIVE_X11`
55 *
56 * The available context API macros are:
57 * * `GLFW_EXPOSE_NATIVE_WGL`
58 * * `GLFW_EXPOSE_NATIVE_NSGL`
59 * * `GLFW_EXPOSE_NATIVE_GLX`
60 * * `GLFW_EXPOSE_NATIVE_EGL`
61 *
62 * These macros select which of the native access functions that are declared
63 * and which platform-specific headers to include. It is then up your (by
64 * definition platform-specific) code to handle which of these should be
65 * defined.
66 */
67
68
69/*************************************************************************
70 * System headers and types
71 *************************************************************************/
72
73#if defined(GLFW_EXPOSE_NATIVE_WIN32)
74 // This is a workaround for the fact that glfw3.h needs to export APIENTRY (for
75 // example to allow applications to correctly declare a GL_ARB_debug_output
76 // callback) but windows.h assumes no one will define APIENTRY before it does
77 #undef APIENTRY
78 #include <windows.h>
79#elif defined(GLFW_EXPOSE_NATIVE_COCOA)
80 #include <ApplicationServices/ApplicationServices.h>
81 #if defined(__OBJC__)
82 #import <Cocoa/Cocoa.h>
83 #else
84 typedef void* id;
85 #endif
86#elif defined(GLFW_EXPOSE_NATIVE_X11)
87 #include <X11/Xlib.h>
88 #include <X11/extensions/Xrandr.h>
89#else
90 #error "No window API selected"
91#endif
92
93#if defined(GLFW_EXPOSE_NATIVE_WGL)
94 /* WGL is declared by windows.h */
95#elif defined(GLFW_EXPOSE_NATIVE_NSGL)
96 /* NSGL is declared by Cocoa.h */
97#elif defined(GLFW_EXPOSE_NATIVE_GLX)
98 #include <GL/glx.h>
99#elif defined(GLFW_EXPOSE_NATIVE_EGL)
100 #include <EGL/egl.h>
101#else
102 #error "No context API selected"
103#endif
104
105
106/*************************************************************************
107 * Functions
108 *************************************************************************/
109
110#if defined(GLFW_EXPOSE_NATIVE_WIN32)
111/*! @brief Returns the adapter device name of the specified monitor.
112 *
113 * @return The UTF-8 encoded adapter device name (for example `\\.\DISPLAY1`)
114 * of the specified monitor, or `NULL` if an [error](@ref error_handling)
115 * occurred.
116 *
117 * @par Thread Safety
118 * This function may be called from any thread. Access is not synchronized.
119 *
120 * @par History
121 * Added in GLFW 3.1.
122 *
123 * @ingroup native
124 */
125GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor);
126
127/*! @brief Returns the display device name of the specified monitor.
128 *
129 * @return The UTF-8 encoded display device name (for example
130 * `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an
131 * [error](@ref error_handling) occurred.
132 *
133 * @par Thread Safety
134 * This function may be called from any thread. Access is not synchronized.
135 *
136 * @par History
137 * Added in GLFW 3.1.
138 *
139 * @ingroup native
140 */
141GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor);
142
143/*! @brief Returns the `HWND` of the specified window.
144 *
145 * @return The `HWND` of the specified window, or `NULL` if an
146 * [error](@ref error_handling) occurred.
147 *
148 * @par Thread Safety
149 * This function may be called from any thread. Access is not synchronized.
150 *
151 * @par History
152 * Added in GLFW 3.0.
153 *
154 * @ingroup native
155 */
156GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window);
157#endif
158
159#if defined(GLFW_EXPOSE_NATIVE_WGL)
160/*! @brief Returns the `HGLRC` of the specified window.
161 *
162 * @return The `HGLRC` of the specified window, or `NULL` if an
163 * [error](@ref error_handling) occurred.
164 *
165 * @par Thread Safety
166 * This function may be called from any thread. Access is not synchronized.
167 *
168 * @par History
169 * Added in GLFW 3.0.
170 *
171 * @ingroup native
172 */
173GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window);
174#endif
175
176#if defined(GLFW_EXPOSE_NATIVE_COCOA)
177/*! @brief Returns the `CGDirectDisplayID` of the specified monitor.
178 *
179 * @return The `CGDirectDisplayID` of the specified monitor, or
180 * `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred.
181 *
182 * @par Thread Safety
183 * This function may be called from any thread. Access is not synchronized.
184 *
185 * @par History
186 * Added in GLFW 3.1.
187 *
188 * @ingroup native
189 */
190GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor);
191
192/*! @brief Returns the `NSWindow` of the specified window.
193 *
194 * @return The `NSWindow` of the specified window, or `nil` if an
195 * [error](@ref error_handling) occurred.
196 *
197 * @par Thread Safety
198 * This function may be called from any thread. Access is not synchronized.
199 *
200 * @par History
201 * Added in GLFW 3.0.
202 *
203 * @ingroup native
204 */
205GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window);
206#endif
207
208#if defined(GLFW_EXPOSE_NATIVE_NSGL)
209/*! @brief Returns the `NSOpenGLContext` of the specified window.
210 *
211 * @return The `NSOpenGLContext` of the specified window, or `nil` if an
212 * [error](@ref error_handling) occurred.
213 *
214 * @par Thread Safety
215 * This function may be called from any thread. Access is not synchronized.
216 *
217 * @par History
218 * Added in GLFW 3.0.
219 *
220 * @ingroup native
221 */
222GLFWAPI id glfwGetNSGLContext(GLFWwindow* window);
223#endif
224
225#if defined(GLFW_EXPOSE_NATIVE_X11)
226/*! @brief Returns the `Display` used by GLFW.
227 *
228 * @return The `Display` used by GLFW, or `NULL` if an
229 * [error](@ref error_handling) occurred.
230 *
231 * @par Thread Safety
232 * This function may be called from any thread. Access is not synchronized.
233 *
234 * @par History
235 * Added in GLFW 3.0.
236 *
237 * @ingroup native
238 */
239GLFWAPI Display* glfwGetX11Display(void);
240
241/*! @brief Returns the `RRCrtc` of the specified monitor.
242 *
243 * @return The `RRCrtc` of the specified monitor, or `None` if an
244 * [error](@ref error_handling) occurred.
245 *
246 * @par Thread Safety
247 * This function may be called from any thread. Access is not synchronized.
248 *
249 * @par History
250 * Added in GLFW 3.1.
251 *
252 * @ingroup native
253 */
254GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor);
255
256/*! @brief Returns the `RROutput` of the specified monitor.
257 *
258 * @return The `RROutput` of the specified monitor, or `None` if an
259 * [error](@ref error_handling) occurred.
260 *
261 * @par Thread Safety
262 * This function may be called from any thread. Access is not synchronized.
263 *
264 * @par History
265 * Added in GLFW 3.1.
266 *
267 * @ingroup native
268 */
269GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor);
270
271/*! @brief Returns the `Window` of the specified window.
272 *
273 * @return The `Window` of the specified window, or `None` if an
274 * [error](@ref error_handling) occurred.
275 *
276 * @par Thread Safety
277 * This function may be called from any thread. Access is not synchronized.
278 *
279 * @par History
280 * Added in GLFW 3.0.
281 *
282 * @ingroup native
283 */
284GLFWAPI Window glfwGetX11Window(GLFWwindow* window);
285#endif
286
287#if defined(GLFW_EXPOSE_NATIVE_GLX)
288/*! @brief Returns the `GLXContext` of the specified window.
289 *
290 * @return The `GLXContext` of the specified window, or `NULL` if an
291 * [error](@ref error_handling) occurred.
292 *
293 * @par Thread Safety
294 * This function may be called from any thread. Access is not synchronized.
295 *
296 * @par History
297 * Added in GLFW 3.0.
298 *
299 * @ingroup native
300 */
301GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window);
302#endif
303
304#if defined(GLFW_EXPOSE_NATIVE_EGL)
305/*! @brief Returns the `EGLDisplay` used by GLFW.
306 *
307 * @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an
308 * [error](@ref error_handling) occurred.
309 *
310 * @par Thread Safety
311 * This function may be called from any thread. Access is not synchronized.
312 *
313 * @par History
314 * Added in GLFW 3.0.
315 *
316 * @ingroup native
317 */
318GLFWAPI EGLDisplay glfwGetEGLDisplay(void);
319
320/*! @brief Returns the `EGLContext` of the specified window.
321 *
322 * @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an
323 * [error](@ref error_handling) occurred.
324 *
325 * @par Thread Safety
326 * This function may be called from any thread. Access is not synchronized.
327 *
328 * @par History
329 * Added in GLFW 3.0.
330 *
331 * @ingroup native
332 */
333GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window);
334
335/*! @brief Returns the `EGLSurface` of the specified window.
336 *
337 * @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an
338 * [error](@ref error_handling) occurred.
339 *
340 * @par Thread Safety
341 * This function may be called from any thread. Access is not synchronized.
342 *
343 * @par History
344 * Added in GLFW 3.0.
345 *
346 * @ingroup native
347 */
348GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window);
349#endif
350
351#ifdef __cplusplus
352}
353#endif
354
355#endif /* _glfw3_native_h_ */
356
diff --git a/externals/glfw-3.1.1.bin/lib-mingw-i686/glfw3.dll b/externals/glfw-3.1.1.bin/lib-mingw-i686/glfw3.dll
new file mode 100644
index 000000000..84c2e1bc2
--- /dev/null
+++ b/externals/glfw-3.1.1.bin/lib-mingw-i686/glfw3.dll
Binary files differ
diff --git a/externals/glfw-3.0.4.bin/lib-mingw-i686/glfw3dll.a b/externals/glfw-3.1.1.bin/lib-mingw-i686/glfw3dll.a
index 415d85630..dc593d062 100644
--- a/externals/glfw-3.0.4.bin/lib-mingw-i686/glfw3dll.a
+++ b/externals/glfw-3.1.1.bin/lib-mingw-i686/glfw3dll.a
Binary files differ
diff --git a/externals/glfw-3.1.1.bin/lib-mingw-i686/libglfw3.a b/externals/glfw-3.1.1.bin/lib-mingw-i686/libglfw3.a
new file mode 100644
index 000000000..59eae0868
--- /dev/null
+++ b/externals/glfw-3.1.1.bin/lib-mingw-i686/libglfw3.a
Binary files differ
diff --git a/externals/glfw-3.1.1.bin/lib-mingw-x86_64/glfw3.dll b/externals/glfw-3.1.1.bin/lib-mingw-x86_64/glfw3.dll
new file mode 100644
index 000000000..437918eda
--- /dev/null
+++ b/externals/glfw-3.1.1.bin/lib-mingw-x86_64/glfw3.dll
Binary files differ
diff --git a/externals/glfw-3.0.4.bin/lib-mingw-x86_64/glfw3dll.a b/externals/glfw-3.1.1.bin/lib-mingw-x86_64/glfw3dll.a
index d71c65377..be08358ab 100644
--- a/externals/glfw-3.0.4.bin/lib-mingw-x86_64/glfw3dll.a
+++ b/externals/glfw-3.1.1.bin/lib-mingw-x86_64/glfw3dll.a
Binary files differ
diff --git a/externals/glfw-3.1.1.bin/lib-mingw-x86_64/libglfw3.a b/externals/glfw-3.1.1.bin/lib-mingw-x86_64/libglfw3.a
new file mode 100644
index 000000000..e9e7be933
--- /dev/null
+++ b/externals/glfw-3.1.1.bin/lib-mingw-x86_64/libglfw3.a
Binary files differ
diff --git a/externals/glfw-3.1.1.bin/lib-msvc_v120-Win32/glfw3.dll b/externals/glfw-3.1.1.bin/lib-msvc_v120-Win32/glfw3.dll
new file mode 100644
index 000000000..f15748d7a
--- /dev/null
+++ b/externals/glfw-3.1.1.bin/lib-msvc_v120-Win32/glfw3.dll
Binary files differ
diff --git a/externals/glfw-3.1.1.bin/lib-msvc_v120-Win32/glfw3.lib b/externals/glfw-3.1.1.bin/lib-msvc_v120-Win32/glfw3.lib
new file mode 100644
index 000000000..6a5a85a1d
--- /dev/null
+++ b/externals/glfw-3.1.1.bin/lib-msvc_v120-Win32/glfw3.lib
Binary files differ
diff --git a/externals/glfw-3.1.1.bin/lib-msvc_v120-Win32/glfw3dll.lib b/externals/glfw-3.1.1.bin/lib-msvc_v120-Win32/glfw3dll.lib
new file mode 100644
index 000000000..248a5cadf
--- /dev/null
+++ b/externals/glfw-3.1.1.bin/lib-msvc_v120-Win32/glfw3dll.lib
Binary files differ
diff --git a/externals/glfw-3.1.1.bin/lib-msvc_v120-x64/glfw3.dll b/externals/glfw-3.1.1.bin/lib-msvc_v120-x64/glfw3.dll
new file mode 100644
index 000000000..cba172f64
--- /dev/null
+++ b/externals/glfw-3.1.1.bin/lib-msvc_v120-x64/glfw3.dll
Binary files differ
diff --git a/externals/glfw-3.1.1.bin/lib-msvc_v120-x64/glfw3.lib b/externals/glfw-3.1.1.bin/lib-msvc_v120-x64/glfw3.lib
new file mode 100644
index 000000000..efdd64332
--- /dev/null
+++ b/externals/glfw-3.1.1.bin/lib-msvc_v120-x64/glfw3.lib
Binary files differ
diff --git a/externals/glfw-3.1.1.bin/lib-msvc_v120-x64/glfw3dll.lib b/externals/glfw-3.1.1.bin/lib-msvc_v120-x64/glfw3dll.lib
new file mode 100644
index 000000000..49ed2bb67
--- /dev/null
+++ b/externals/glfw-3.1.1.bin/lib-msvc_v120-x64/glfw3dll.lib
Binary files differ
diff --git a/src/citra/citra.rc b/src/citra/citra.rc
index 0165e93da..b0edb2e6b 100644
--- a/src/citra/citra.rc
+++ b/src/citra/citra.rc
@@ -1,9 +1,9 @@
1///////////////////////////////////////////////////////////////////////////// 1/////////////////////////////////////////////////////////////////////////////
2// 2//
3// Icon 3// Icon
4// 4//
5 5
6// Icon with lowest ID value placed first to ensure application icon 6// Icon with lowest ID value placed first to ensure application icon
7// remains consistent on all systems. 7// remains consistent on all systems.
8GLFW_ICON ICON "..\\assets\\citra.ico" 8GLFW_ICON ICON "..\\..\\dist\\citra.ico"
9 9
diff --git a/src/citra/config.cpp b/src/citra/config.cpp
index 846479fd7..1378567c1 100644
--- a/src/citra/config.cpp
+++ b/src/citra/config.cpp
@@ -66,7 +66,6 @@ void Config::ReadValues() {
66 Settings::values.pad_cright_key = glfw_config->GetInteger("Controls", "pad_cright", GLFW_KEY_L); 66 Settings::values.pad_cright_key = glfw_config->GetInteger("Controls", "pad_cright", GLFW_KEY_L);
67 67
68 // Core 68 // Core
69 Settings::values.gpu_refresh_rate = glfw_config->GetInteger("Core", "gpu_refresh_rate", 30);
70 Settings::values.frame_skip = glfw_config->GetInteger("Core", "frame_skip", 0); 69 Settings::values.frame_skip = glfw_config->GetInteger("Core", "frame_skip", 0);
71 70
72 // Renderer 71 // Renderer
diff --git a/src/citra/resource.h b/src/citra/resource.h
index 0d42c8a8a..127896424 100644
--- a/src/citra/resource.h
+++ b/src/citra/resource.h
Binary files differ
diff --git a/src/citra_qt/CMakeLists.txt b/src/citra_qt/CMakeLists.txt
index efccdbec6..c2d1ad240 100644
--- a/src/citra_qt/CMakeLists.txt
+++ b/src/citra_qt/CMakeLists.txt
@@ -89,15 +89,15 @@ if (Qt5_FOUND AND MSVC)
89 ) 89 )
90 set(DLL_DEST "${CMAKE_BINARY_DIR}/bin/$<CONFIG>/") 90 set(DLL_DEST "${CMAKE_BINARY_DIR}/bin/$<CONFIG>/")
91 set(PLATFORMS ${DLL_DEST}platforms/) 91 set(PLATFORMS ${DLL_DEST}platforms/)
92 92
93 # windows commandline expects the / to be \ so switch them 93 # windows commandline expects the / to be \ so switch them
94 string(REPLACE "/" "\\" Qt5_DLL_DIR ${Qt5_DLL_DIR}) 94 string(REPLACE "/" "\\\\" Qt5_DLL_DIR ${Qt5_DLL_DIR})
95 string(REPLACE "/" "\\" Qt5_PLATFORMS_DIR ${Qt5_PLATFORMS_DIR}) 95 string(REPLACE "/" "\\\\" Qt5_PLATFORMS_DIR ${Qt5_PLATFORMS_DIR})
96 string(REPLACE "/" "\\" DLL_DEST ${DLL_DEST}) 96 string(REPLACE "/" "\\\\" DLL_DEST ${DLL_DEST})
97 string(REPLACE "/" "\\" PLATFORMS ${PLATFORMS}) 97 string(REPLACE "/" "\\\\" PLATFORMS ${PLATFORMS})
98 98
99 # /NJH /NJS /NDL /NFL /NC /NS /NP - Silence any output 99 # /NJH /NJS /NDL /NFL /NC /NS /NP - Silence any output
100 # cmake adds an extra check for command success which doesn't work too well with robocopy 100 # cmake adds an extra check for command success which doesn't work too well with robocopy
101 # so trick it into thinking the command was successful with the || cmd /c "exit /b 0" 101 # so trick it into thinking the command was successful with the || cmd /c "exit /b 0"
102 add_custom_command(TARGET citra-qt POST_BUILD 102 add_custom_command(TARGET citra-qt POST_BUILD
103 COMMAND robocopy ${Qt5_DLL_DIR} ${DLL_DEST} ${Qt5_DLLS} /NJH /NJS /NDL /NFL /NC /NS /NP || cmd /c "exit /b 0" 103 COMMAND robocopy ${Qt5_DLL_DIR} ${DLL_DEST} ${Qt5_DLLS} /NJH /NJS /NDL /NFL /NC /NS /NP || cmd /c "exit /b 0"
diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp
index 72b55e94d..3db09c65b 100644
--- a/src/citra_qt/bootmanager.cpp
+++ b/src/citra_qt/bootmanager.cpp
@@ -57,7 +57,7 @@ void EmuThread::run() {
57 Core::SingleStep(); 57 Core::SingleStep();
58 emit DebugModeEntered(); 58 emit DebugModeEntered();
59 yieldCurrentThread(); 59 yieldCurrentThread();
60 60
61 was_active = false; 61 was_active = false;
62 } else { 62 } else {
63 std::unique_lock<std::mutex> lock(running_mutex); 63 std::unique_lock<std::mutex> lock(running_mutex);
diff --git a/src/citra_qt/bootmanager.h b/src/citra_qt/bootmanager.h
index 16809eaae..475124319 100644
--- a/src/citra_qt/bootmanager.h
+++ b/src/citra_qt/bootmanager.h
@@ -80,7 +80,7 @@ signals:
80 * @warning When connecting to this signal from other threads, make sure to specify either Qt::QueuedConnection (invoke slot within the destination object's message thread) or even Qt::BlockingQueuedConnection (additionally block source thread until slot returns) 80 * @warning When connecting to this signal from other threads, make sure to specify either Qt::QueuedConnection (invoke slot within the destination object's message thread) or even Qt::BlockingQueuedConnection (additionally block source thread until slot returns)
81 */ 81 */
82 void DebugModeEntered(); 82 void DebugModeEntered();
83 83
84 /** 84 /**
85 * Emitted right before the CPU continues execution 85 * Emitted right before the CPU continues execution
86 * 86 *
diff --git a/src/citra_qt/citra-qt.rc b/src/citra_qt/citra-qt.rc
index dd6f834f5..3c7239853 100644
--- a/src/citra_qt/citra-qt.rc
+++ b/src/citra_qt/citra-qt.rc
Binary files differ
diff --git a/src/citra_qt/config.cpp b/src/citra_qt/config.cpp
index 460f4ec07..2a9af1f38 100644
--- a/src/citra_qt/config.cpp
+++ b/src/citra_qt/config.cpp
@@ -49,7 +49,6 @@ void Config::ReadValues() {
49 qt_config->endGroup(); 49 qt_config->endGroup();
50 50
51 qt_config->beginGroup("Core"); 51 qt_config->beginGroup("Core");
52 Settings::values.gpu_refresh_rate = qt_config->value("gpu_refresh_rate", 30).toInt();
53 Settings::values.frame_skip = qt_config->value("frame_skip", 0).toInt(); 52 Settings::values.frame_skip = qt_config->value("frame_skip", 0).toInt();
54 qt_config->endGroup(); 53 qt_config->endGroup();
55 54
@@ -102,7 +101,6 @@ void Config::SaveValues() {
102 qt_config->endGroup(); 101 qt_config->endGroup();
103 102
104 qt_config->beginGroup("Core"); 103 qt_config->beginGroup("Core");
105 qt_config->setValue("gpu_refresh_rate", Settings::values.gpu_refresh_rate);
106 qt_config->setValue("frame_skip", Settings::values.frame_skip); 104 qt_config->setValue("frame_skip", Settings::values.frame_skip);
107 qt_config->endGroup(); 105 qt_config->endGroup();
108 106
diff --git a/src/citra_qt/debugger/callstack.cpp b/src/citra_qt/debugger/callstack.cpp
index 94e204717..6799ce844 100644
--- a/src/citra_qt/debugger/callstack.cpp
+++ b/src/citra_qt/debugger/callstack.cpp
@@ -39,7 +39,7 @@ void CallstackWidget::OnDebugModeEntered()
39 { 39 {
40 ret_addr = Memory::Read32(addr); 40 ret_addr = Memory::Read32(addr);
41 call_addr = ret_addr - 4; //get call address??? 41 call_addr = ret_addr - 4; //get call address???
42 42
43 if (Memory::GetPointer(call_addr) == nullptr) 43 if (Memory::GetPointer(call_addr) == nullptr)
44 break; 44 break;
45 45
diff --git a/src/citra_qt/debugger/callstack.ui b/src/citra_qt/debugger/callstack.ui
index b0e31120f..248ea3dd7 100644
--- a/src/citra_qt/debugger/callstack.ui
+++ b/src/citra_qt/debugger/callstack.ui
@@ -17,6 +17,9 @@
17 <layout class="QVBoxLayout" name="verticalLayout"> 17 <layout class="QVBoxLayout" name="verticalLayout">
18 <item> 18 <item>
19 <widget class="QTreeView" name="treeView"> 19 <widget class="QTreeView" name="treeView">
20 <property name="editTriggers">
21 <set>QAbstractItemView::NoEditTriggers</set>
22 </property>
20 <property name="alternatingRowColors"> 23 <property name="alternatingRowColors">
21 <bool>true</bool> 24 <bool>true</bool>
22 </property> 25 </property>
diff --git a/src/citra_qt/debugger/graphics_cmdlists.cpp b/src/citra_qt/debugger/graphics_cmdlists.cpp
index 804c735a3..cabf5fe07 100644
--- a/src/citra_qt/debugger/graphics_cmdlists.cpp
+++ b/src/citra_qt/debugger/graphics_cmdlists.cpp
@@ -11,10 +11,10 @@
11#include <QSpinBox> 11#include <QSpinBox>
12#include <QComboBox> 12#include <QComboBox>
13 13
14#include "video_core/pica.h" 14#include "common/vector_math.h"
15#include "video_core/math.h"
16 15
17#include "video_core/debug_utils/debug_utils.h" 16#include "video_core/debug_utils/debug_utils.h"
17#include "video_core/pica.h"
18 18
19#include "graphics_cmdlists.h" 19#include "graphics_cmdlists.h"
20 20
diff --git a/src/citra_qt/debugger/graphics_framebuffer.cpp b/src/citra_qt/debugger/graphics_framebuffer.cpp
index e07344591..6bbe7572c 100644
--- a/src/citra_qt/debugger/graphics_framebuffer.cpp
+++ b/src/citra_qt/debugger/graphics_framebuffer.cpp
@@ -9,10 +9,11 @@
9#include <QPushButton> 9#include <QPushButton>
10#include <QSpinBox> 10#include <QSpinBox>
11 11
12#include "common/color.h"
13
12#include "core/hw/gpu.h" 14#include "core/hw/gpu.h"
13#include "core/memory.h" 15#include "core/memory.h"
14 16
15#include "video_core/color.h"
16#include "video_core/pica.h" 17#include "video_core/pica.h"
17#include "video_core/utils.h" 18#include "video_core/utils.h"
18 19
diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp
index f6010459a..8041816a0 100644
--- a/src/citra_qt/main.cpp
+++ b/src/citra_qt/main.cpp
@@ -127,7 +127,7 @@ GMainWindow::GMainWindow() : emu_thread(nullptr)
127 127
128 ui.action_Use_Hardware_Renderer->setChecked(Settings::values.use_hw_renderer); 128 ui.action_Use_Hardware_Renderer->setChecked(Settings::values.use_hw_renderer);
129 SetHardwareRendererEnabled(ui.action_Use_Hardware_Renderer->isChecked()); 129 SetHardwareRendererEnabled(ui.action_Use_Hardware_Renderer->isChecked());
130 130
131 ui.action_Single_Window_Mode->setChecked(settings.value("singleWindowMode", true).toBool()); 131 ui.action_Single_Window_Mode->setChecked(settings.value("singleWindowMode", true).toBool());
132 ToggleWindowMode(); 132 ToggleWindowMode();
133 133
diff --git a/src/citra_qt/main.ui b/src/citra_qt/main.ui
index 0942c28c8..9a809ee6c 100644
--- a/src/citra_qt/main.ui
+++ b/src/citra_qt/main.ui
@@ -24,7 +24,20 @@
24 <bool>true</bool> 24 <bool>true</bool>
25 </property> 25 </property>
26 <widget class="QWidget" name="centralwidget"> 26 <widget class="QWidget" name="centralwidget">
27 <layout class="QHBoxLayout" name="horizontalLayout"/> 27 <layout class="QHBoxLayout" name="horizontalLayout">
28 <property name="leftMargin">
29 <number>0</number>
30 </property>
31 <property name="topMargin">
32 <number>0</number>
33 </property>
34 <property name="rightMargin">
35 <number>0</number>
36 </property>
37 <property name="bottomMargin">
38 <number>0</number>
39 </property>
40 </layout>
28 </widget> 41 </widget>
29 <widget class="QMenuBar" name="menubar"> 42 <widget class="QMenuBar" name="menubar">
30 <property name="geometry"> 43 <property name="geometry">
@@ -92,7 +105,7 @@
92 </action> 105 </action>
93 <action name="action_Start"> 106 <action name="action_Start">
94 <property name="enabled"> 107 <property name="enabled">
95 <bool>false</bool> 108 <bool>false</bool>
96 </property> 109 </property>
97 <property name="text"> 110 <property name="text">
98 <string>&amp;Start</string> 111 <string>&amp;Start</string>
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index dbaaac77b..e78f4f144 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -24,6 +24,7 @@ set(HEADERS
24 bit_field.h 24 bit_field.h
25 break_points.h 25 break_points.h
26 chunk_file.h 26 chunk_file.h
27 color.h
27 common_funcs.h 28 common_funcs.h
28 common_paths.h 29 common_paths.h
29 common_types.h 30 common_types.h
@@ -54,6 +55,7 @@ set(HEADERS
54 thread_queue_list.h 55 thread_queue_list.h
55 thunk.h 56 thunk.h
56 timer.h 57 timer.h
58 vector_math.h
57 ) 59 )
58 60
59create_directory_groups(${SRCS} ${HEADERS}) 61create_directory_groups(${SRCS} ${HEADERS})
diff --git a/src/video_core/color.h b/src/common/color.h
index 4d2026eb0..422fdc8af 100644
--- a/src/video_core/color.h
+++ b/src/common/color.h
@@ -6,8 +6,7 @@
6 6
7#include "common/common_types.h" 7#include "common/common_types.h"
8#include "common/swap.h" 8#include "common/swap.h"
9 9#include "common/vector_math.h"
10#include "video_core/math.h"
11 10
12namespace Color { 11namespace Color {
13 12
diff --git a/src/common/emu_window.cpp b/src/common/emu_window.cpp
index f5b6c7301..43facb85c 100644
--- a/src/common/emu_window.cpp
+++ b/src/common/emu_window.cpp
@@ -32,7 +32,7 @@ std::tuple<unsigned,unsigned> EmuWindow::ClipToTouchScreen(unsigned new_x, unsig
32 32
33 new_x = std::max(new_x, framebuffer_layout.bottom_screen.left); 33 new_x = std::max(new_x, framebuffer_layout.bottom_screen.left);
34 new_x = std::min(new_x, framebuffer_layout.bottom_screen.right-1); 34 new_x = std::min(new_x, framebuffer_layout.bottom_screen.right-1);
35 35
36 new_y = std::max(new_y, framebuffer_layout.bottom_screen.top); 36 new_y = std::max(new_y, framebuffer_layout.bottom_screen.top);
37 new_y = std::min(new_y, framebuffer_layout.bottom_screen.bottom-1); 37 new_y = std::min(new_y, framebuffer_layout.bottom_screen.bottom-1);
38 38
diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp
index 7cdd1484f..24648ea33 100644
--- a/src/common/file_util.cpp
+++ b/src/common/file_util.cpp
@@ -16,7 +16,7 @@
16 #include <io.h> 16 #include <io.h>
17 #include <direct.h> // getcwd 17 #include <direct.h> // getcwd
18 #include <tchar.h> 18 #include <tchar.h>
19 19
20 // 64 bit offsets for windows 20 // 64 bit offsets for windows
21 #define fseeko _fseeki64 21 #define fseeko _fseeki64
22 #define ftello _ftelli64 22 #define ftello _ftelli64
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp
index 6ca8cb78d..d85e58373 100644
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -37,6 +37,7 @@ namespace Log {
37 SUB(Service, APT) \ 37 SUB(Service, APT) \
38 SUB(Service, GSP) \ 38 SUB(Service, GSP) \
39 SUB(Service, AC) \ 39 SUB(Service, AC) \
40 SUB(Service, AM) \
40 SUB(Service, PTM) \ 41 SUB(Service, PTM) \
41 SUB(Service, LDR) \ 42 SUB(Service, LDR) \
42 SUB(Service, NIM) \ 43 SUB(Service, NIM) \
diff --git a/src/common/logging/log.h b/src/common/logging/log.h
index d720d7fe0..5b3a731e9 100644
--- a/src/common/logging/log.h
+++ b/src/common/logging/log.h
@@ -57,13 +57,14 @@ enum class Class : ClassType {
57 Service_APT, ///< The APT (Applets) service 57 Service_APT, ///< The APT (Applets) service
58 Service_GSP, ///< The GSP (GPU control) service 58 Service_GSP, ///< The GSP (GPU control) service
59 Service_AC, ///< The AC (WiFi status) service 59 Service_AC, ///< The AC (WiFi status) service
60 Service_AM, ///< The AM (Application manager) service
60 Service_PTM, ///< The PTM (Power status & misc.) service 61 Service_PTM, ///< The PTM (Power status & misc.) service
61 Service_LDR, ///< The LDR (3ds dll loader) service 62 Service_LDR, ///< The LDR (3ds dll loader) service
62 Service_NIM, ///< The NIM (Network interface manager) service 63 Service_NIM, ///< The NIM (Network interface manager) service
63 Service_NWM, ///< The NWM (Network manager) service 64 Service_NWM, ///< The NWM (Network wlan manager) service
64 Service_CFG, ///< The CFG (Configuration) service 65 Service_CFG, ///< The CFG (Configuration) service
65 Service_DSP, ///< The DSP (DSP control) service 66 Service_DSP, ///< The DSP (DSP control) service
66 Service_HID, ///< The HID (User input) service 67 Service_HID, ///< The HID (Human interface device) service
67 Service_SOC, ///< The SOC (Socket) service 68 Service_SOC, ///< The SOC (Socket) service
68 Service_Y2R, ///< The Y2R (YUV to RGB conversion) service 69 Service_Y2R, ///< The Y2R (YUV to RGB conversion) service
69 HW, ///< Low-level hardware emulation 70 HW, ///< Low-level hardware emulation
diff --git a/src/common/math_util.h b/src/common/math_util.h
index 4b0910741..d44b06e74 100644
--- a/src/common/math_util.h
+++ b/src/common/math_util.h
@@ -12,7 +12,7 @@ namespace MathUtil
12{ 12{
13 13
14inline bool IntervalsIntersect(unsigned start0, unsigned length0, unsigned start1, unsigned length1) { 14inline bool IntervalsIntersect(unsigned start0, unsigned length0, unsigned start1, unsigned length1) {
15 return (std::max(start0, start1) <= std::min(start0 + length0, start1 + length1)); 15 return (std::max(start0, start1) < std::min(start0 + length0, start1 + length1));
16} 16}
17 17
18template<typename T> 18template<typename T>
diff --git a/src/common/swap.h b/src/common/swap.h
index 7e37655bf..588cebc70 100644
--- a/src/common/swap.h
+++ b/src/common/swap.h
@@ -135,7 +135,7 @@ template <>
135inline void swap<8>(u8* data) { 135inline void swap<8>(u8* data) {
136 *reinterpret_cast<u64*>(data) = swap64(data); 136 *reinterpret_cast<u64*>(data) = swap64(data);
137} 137}
138 138
139} // Namespace Common 139} // Namespace Common
140 140
141 141
diff --git a/src/video_core/math.h b/src/common/vector_math.h
index f9a822658..4928c9bf2 100644
--- a/src/video_core/math.h
+++ b/src/common/vector_math.h
@@ -461,7 +461,7 @@ public:
461 // e.g. Vec2 uv() { return Vec2(x,y); } 461 // e.g. Vec2 uv() { return Vec2(x,y); }
462 462
463 // _DEFINE_SWIZZLER2 defines a single such function 463 // _DEFINE_SWIZZLER2 defines a single such function
464 // DEFINE_SWIZZLER2_COMP1 defines one-component functions for all component names (x<->r) 464 // DEFINE_SWIZZLER2_COMP1 defines one-component functions for all component names (x<->r)
465 // DEFINE_SWIZZLER2_COMP2 defines two component functions for all component names (x<->r) and permutations (xy<->yx) 465 // DEFINE_SWIZZLER2_COMP2 defines two component functions for all component names (x<->r) and permutations (xy<->yx)
466#define _DEFINE_SWIZZLER2(a, b, name) const Vec2<T> name() const { return Vec2<T>(a, b); } 466#define _DEFINE_SWIZZLER2(a, b, name) const Vec2<T> name() const { return Vec2<T>(a, b); }
467#define DEFINE_SWIZZLER2_COMP1(a, a2) \ 467#define DEFINE_SWIZZLER2_COMP1(a, a2) \
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 5caaee474..057b8ca0c 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -36,20 +36,29 @@ set(SRCS
36 hle/kernel/shared_memory.cpp 36 hle/kernel/shared_memory.cpp
37 hle/kernel/thread.cpp 37 hle/kernel/thread.cpp
38 hle/kernel/timer.cpp 38 hle/kernel/timer.cpp
39 hle/kernel/vm_manager.cpp
39 hle/service/ac_u.cpp 40 hle/service/ac_u.cpp
40 hle/service/act_u.cpp 41 hle/service/act_u.cpp
41 hle/service/am_app.cpp 42 hle/service/am/am.cpp
42 hle/service/am_net.cpp 43 hle/service/am/am_app.cpp
43 hle/service/am_sys.cpp 44 hle/service/am/am_net.cpp
45 hle/service/am/am_sys.cpp
46 hle/service/am/am_u.cpp
44 hle/service/apt/apt.cpp 47 hle/service/apt/apt.cpp
45 hle/service/apt/apt_a.cpp 48 hle/service/apt/apt_a.cpp
46 hle/service/apt/apt_s.cpp 49 hle/service/apt/apt_s.cpp
47 hle/service/apt/apt_u.cpp 50 hle/service/apt/apt_u.cpp
48 hle/service/boss_p.cpp 51 hle/service/boss/boss.cpp
49 hle/service/boss_u.cpp 52 hle/service/boss/boss_p.cpp
50 hle/service/cam_u.cpp 53 hle/service/boss/boss_u.cpp
51 hle/service/cecd_s.cpp 54 hle/service/cam/cam.cpp
52 hle/service/cecd_u.cpp 55 hle/service/cam/cam_c.cpp
56 hle/service/cam/cam_q.cpp
57 hle/service/cam/cam_s.cpp
58 hle/service/cam/cam_u.cpp
59 hle/service/cecd/cecd.cpp
60 hle/service/cecd/cecd_s.cpp
61 hle/service/cecd/cecd_u.cpp
53 hle/service/cfg/cfg.cpp 62 hle/service/cfg/cfg.cpp
54 hle/service/cfg/cfg_i.cpp 63 hle/service/cfg/cfg_i.cpp
55 hle/service/cfg/cfg_s.cpp 64 hle/service/cfg/cfg_s.cpp
@@ -57,8 +66,9 @@ set(SRCS
57 hle/service/csnd_snd.cpp 66 hle/service/csnd_snd.cpp
58 hle/service/dsp_dsp.cpp 67 hle/service/dsp_dsp.cpp
59 hle/service/err_f.cpp 68 hle/service/err_f.cpp
60 hle/service/frd_a.cpp 69 hle/service/frd/frd.cpp
61 hle/service/frd_u.cpp 70 hle/service/frd/frd_a.cpp
71 hle/service/frd/frd_u.cpp
62 hle/service/fs/archive.cpp 72 hle/service/fs/archive.cpp
63 hle/service/fs/fs_user.cpp 73 hle/service/fs/fs_user.cpp
64 hle/service/gsp_gpu.cpp 74 hle/service/gsp_gpu.cpp
@@ -74,10 +84,13 @@ set(SRCS
74 hle/service/ldr_ro.cpp 84 hle/service/ldr_ro.cpp
75 hle/service/mic_u.cpp 85 hle/service/mic_u.cpp
76 hle/service/ndm_u.cpp 86 hle/service/ndm_u.cpp
77 hle/service/news_s.cpp 87 hle/service/news/news.cpp
78 hle/service/news_u.cpp 88 hle/service/news/news_s.cpp
79 hle/service/nim_aoc.cpp 89 hle/service/news/news_u.cpp
80 hle/service/nim_u.cpp 90 hle/service/nim/nim.cpp
91 hle/service/nim/nim_aoc.cpp
92 hle/service/nim/nim_s.cpp
93 hle/service/nim/nim_u.cpp
81 hle/service/ns_s.cpp 94 hle/service/ns_s.cpp
82 hle/service/nwm_uds.cpp 95 hle/service/nwm_uds.cpp
83 hle/service/pm_app.cpp 96 hle/service/pm_app.cpp
@@ -116,7 +129,6 @@ set(HEADERS
116 arm/dyncom/arm_dyncom_thumb.h 129 arm/dyncom/arm_dyncom_thumb.h
117 arm/skyeye_common/arm_regformat.h 130 arm/skyeye_common/arm_regformat.h
118 arm/skyeye_common/armdefs.h 131 arm/skyeye_common/armdefs.h
119 arm/skyeye_common/armemu.h
120 arm/skyeye_common/armmmu.h 132 arm/skyeye_common/armmmu.h
121 arm/skyeye_common/vfp/asm_vfp.h 133 arm/skyeye_common/vfp/asm_vfp.h
122 arm/skyeye_common/vfp/vfp.h 134 arm/skyeye_common/vfp/vfp.h
@@ -148,21 +160,30 @@ set(HEADERS
148 hle/kernel/shared_memory.h 160 hle/kernel/shared_memory.h
149 hle/kernel/thread.h 161 hle/kernel/thread.h
150 hle/kernel/timer.h 162 hle/kernel/timer.h
163 hle/kernel/vm_manager.h
151 hle/result.h 164 hle/result.h
152 hle/service/ac_u.h 165 hle/service/ac_u.h
153 hle/service/act_u.h 166 hle/service/act_u.h
154 hle/service/am_app.h 167 hle/service/am/am.h
155 hle/service/am_net.h 168 hle/service/am/am_app.h
156 hle/service/am_sys.h 169 hle/service/am/am_net.h
170 hle/service/am/am_sys.h
171 hle/service/am/am_u.h
157 hle/service/apt/apt.h 172 hle/service/apt/apt.h
158 hle/service/apt/apt_a.h 173 hle/service/apt/apt_a.h
159 hle/service/apt/apt_s.h 174 hle/service/apt/apt_s.h
160 hle/service/apt/apt_u.h 175 hle/service/apt/apt_u.h
161 hle/service/boss_p.h 176 hle/service/boss/boss.h
162 hle/service/boss_u.h 177 hle/service/boss/boss_p.h
163 hle/service/cam_u.h 178 hle/service/boss/boss_u.h
164 hle/service/cecd_s.h 179 hle/service/cam/cam.h
165 hle/service/cecd_u.h 180 hle/service/cam/cam_c.h
181 hle/service/cam/cam_q.h
182 hle/service/cam/cam_s.h
183 hle/service/cam/cam_u.h
184 hle/service/cecd/cecd.h
185 hle/service/cecd/cecd_s.h
186 hle/service/cecd/cecd_u.h
166 hle/service/cfg/cfg.h 187 hle/service/cfg/cfg.h
167 hle/service/cfg/cfg_i.h 188 hle/service/cfg/cfg_i.h
168 hle/service/cfg/cfg_s.h 189 hle/service/cfg/cfg_s.h
@@ -170,8 +191,9 @@ set(HEADERS
170 hle/service/csnd_snd.h 191 hle/service/csnd_snd.h
171 hle/service/dsp_dsp.h 192 hle/service/dsp_dsp.h
172 hle/service/err_f.h 193 hle/service/err_f.h
173 hle/service/frd_a.h 194 hle/service/frd/frd.h
174 hle/service/frd_u.h 195 hle/service/frd/frd_a.h
196 hle/service/frd/frd_u.h
175 hle/service/fs/archive.h 197 hle/service/fs/archive.h
176 hle/service/fs/fs_user.h 198 hle/service/fs/fs_user.h
177 hle/service/gsp_gpu.h 199 hle/service/gsp_gpu.h
@@ -187,10 +209,13 @@ set(HEADERS
187 hle/service/ldr_ro.h 209 hle/service/ldr_ro.h
188 hle/service/mic_u.h 210 hle/service/mic_u.h
189 hle/service/ndm_u.h 211 hle/service/ndm_u.h
190 hle/service/news_s.h 212 hle/service/news/news.h
191 hle/service/news_u.h 213 hle/service/news/news_s.h
192 hle/service/nim_aoc.h 214 hle/service/news/news_u.h
193 hle/service/nim_u.h 215 hle/service/nim/nim.h
216 hle/service/nim/nim_aoc.h
217 hle/service/nim/nim_s.h
218 hle/service/nim/nim_u.h
194 hle/service/ns_s.h 219 hle/service/ns_s.h
195 hle/service/nwm_uds.h 220 hle/service/nwm_uds.h
196 hle/service/pm_app.h 221 hle/service/pm_app.h
diff --git a/src/core/arm/disassembler/arm_disasm.cpp b/src/core/arm/disassembler/arm_disasm.cpp
index 913dc1454..f6d44d85a 100644
--- a/src/core/arm/disassembler/arm_disasm.cpp
+++ b/src/core/arm/disassembler/arm_disasm.cpp
@@ -813,7 +813,7 @@ Opcode ARM_Disasm::Decode11(uint32_t insn) {
813 // SWI 813 // SWI
814 return OP_SWI; 814 return OP_SWI;
815 } 815 }
816 816
817 uint8_t bit4 = (insn >> 4) & 0x1; 817 uint8_t bit4 = (insn >> 4) & 0x1;
818 uint8_t cpnum = (insn >> 8) & 0xf; 818 uint8_t cpnum = (insn >> 8) & 0xf;
819 819
diff --git a/src/core/arm/dyncom/arm_dyncom.cpp b/src/core/arm/dyncom/arm_dyncom.cpp
index 0072ae533..529c4ac70 100644
--- a/src/core/arm/dyncom/arm_dyncom.cpp
+++ b/src/core/arm/dyncom/arm_dyncom.cpp
@@ -6,7 +6,7 @@
6 6
7#include "common/make_unique.h" 7#include "common/make_unique.h"
8 8
9#include "core/arm/skyeye_common/armemu.h" 9#include "core/arm/skyeye_common/armdefs.h"
10#include "core/arm/skyeye_common/vfp/vfp.h" 10#include "core/arm/skyeye_common/vfp/vfp.h"
11 11
12#include "core/arm/dyncom/arm_dyncom.h" 12#include "core/arm/dyncom/arm_dyncom.h"
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index e4b5486e0..b00eb49a9 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -134,7 +134,7 @@ static unsigned int DPO(Immediate)(ARMul_State* cpu, unsigned int sht_oper) {
134 unsigned int immed_8 = BITS(sht_oper, 0, 7); 134 unsigned int immed_8 = BITS(sht_oper, 0, 7);
135 unsigned int rotate_imm = BITS(sht_oper, 8, 11); 135 unsigned int rotate_imm = BITS(sht_oper, 8, 11);
136 unsigned int shifter_operand = ROTATE_RIGHT_32(immed_8, rotate_imm * 2); 136 unsigned int shifter_operand = ROTATE_RIGHT_32(immed_8, rotate_imm * 2);
137 if (rotate_imm == 0) 137 if (rotate_imm == 0)
138 cpu->shifter_carry_out = cpu->CFlag; 138 cpu->shifter_carry_out = cpu->CFlag;
139 else 139 else
140 cpu->shifter_carry_out = BIT(shifter_operand, 31); 140 cpu->shifter_carry_out = BIT(shifter_operand, 31);
@@ -521,7 +521,7 @@ static void MLnS(ImmediateOffset)(ARMul_State* cpu, unsigned int inst, unsigned
521 addr = CHECK_READ_REG15_WA(cpu, Rn) + offset_8; 521 addr = CHECK_READ_REG15_WA(cpu, Rn) + offset_8;
522 else 522 else
523 addr = CHECK_READ_REG15_WA(cpu, Rn) - offset_8; 523 addr = CHECK_READ_REG15_WA(cpu, Rn) - offset_8;
524 524
525 virt_addr = addr; 525 virt_addr = addr;
526} 526}
527 527
@@ -550,7 +550,7 @@ static void MLnS(ImmediatePreIndexed)(ARMul_State* cpu, unsigned int inst, unsig
550 550
551 if (U_BIT) 551 if (U_BIT)
552 addr = rn + offset_8; 552 addr = rn + offset_8;
553 else 553 else
554 addr = rn - offset_8; 554 addr = rn - offset_8;
555 555
556 virt_addr = addr; 556 virt_addr = addr;
@@ -1306,8 +1306,8 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(and)(unsigned int inst, int index)
1306 inst_cream->Rd = BITS(inst, 12, 15); 1306 inst_cream->Rd = BITS(inst, 12, 15);
1307 inst_cream->shifter_operand = BITS(inst, 0, 11); 1307 inst_cream->shifter_operand = BITS(inst, 0, 11);
1308 inst_cream->shtop_func = get_shtop(inst); 1308 inst_cream->shtop_func = get_shtop(inst);
1309 1309
1310 if (inst_cream->Rd == 15) 1310 if (inst_cream->Rd == 15)
1311 inst_base->br = INDIRECT_BRANCH; 1311 inst_base->br = INDIRECT_BRANCH;
1312 1312
1313 return inst_base; 1313 return inst_base;
@@ -1350,7 +1350,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(bic)(unsigned int inst, int index)
1350 inst_cream->shifter_operand = BITS(inst, 0, 11); 1350 inst_cream->shifter_operand = BITS(inst, 0, 11);
1351 inst_cream->shtop_func = get_shtop(inst); 1351 inst_cream->shtop_func = get_shtop(inst);
1352 1352
1353 if (inst_cream->Rd == 15) 1353 if (inst_cream->Rd == 15)
1354 inst_base->br = INDIRECT_BRANCH; 1354 inst_base->br = INDIRECT_BRANCH;
1355 return inst_base; 1355 return inst_base;
1356} 1356}
@@ -3269,7 +3269,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(yield)(unsigned int inst, int index)
3269#define VFP_INTERPRETER_STRUCT 3269#define VFP_INTERPRETER_STRUCT
3270#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" 3270#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
3271#undef VFP_INTERPRETER_STRUCT 3271#undef VFP_INTERPRETER_STRUCT
3272 3272
3273#define VFP_INTERPRETER_TRANS 3273#define VFP_INTERPRETER_TRANS
3274#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" 3274#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
3275#undef VFP_INTERPRETER_TRANS 3275#undef VFP_INTERPRETER_TRANS
@@ -3478,9 +3478,9 @@ const transop_fp_t arm_instruction_trans[] = {
3478 INTERPRETER_TRANSLATE(bbl), 3478 INTERPRETER_TRANSLATE(bbl),
3479 3479
3480 // All the thumb instructions should be placed the end of table 3480 // All the thumb instructions should be placed the end of table
3481 INTERPRETER_TRANSLATE(b_2_thumb), 3481 INTERPRETER_TRANSLATE(b_2_thumb),
3482 INTERPRETER_TRANSLATE(b_cond_thumb), 3482 INTERPRETER_TRANSLATE(b_cond_thumb),
3483 INTERPRETER_TRANSLATE(bl_1_thumb), 3483 INTERPRETER_TRANSLATE(bl_1_thumb),
3484 INTERPRETER_TRANSLATE(bl_2_thumb), 3484 INTERPRETER_TRANSLATE(bl_2_thumb),
3485 INTERPRETER_TRANSLATE(blx_1_thumb) 3485 INTERPRETER_TRANSLATE(blx_1_thumb)
3486}; 3486};
@@ -3564,17 +3564,13 @@ static int InterpreterTranslate(ARMul_State* cpu, int& bb_start, u32 addr) {
3564 unsigned int inst, inst_size = 4; 3564 unsigned int inst, inst_size = 4;
3565 int idx; 3565 int idx;
3566 int ret = NON_BRANCH; 3566 int ret = NON_BRANCH;
3567 int thumb = 0;
3568 int size = 0; // instruction size of basic block 3567 int size = 0; // instruction size of basic block
3569 bb_start = top; 3568 bb_start = top;
3570 3569
3571 if (cpu->TFlag)
3572 thumb = THUMB;
3573
3574 u32 phys_addr = addr; 3570 u32 phys_addr = addr;
3575 u32 pc_start = cpu->Reg[15]; 3571 u32 pc_start = cpu->Reg[15];
3576 3572
3577 while(ret == NON_BRANCH) { 3573 while (ret == NON_BRANCH) {
3578 inst = Memory::Read32(phys_addr & 0xFFFFFFFC); 3574 inst = Memory::Read32(phys_addr & 0xFFFFFFFC);
3579 3575
3580 size++; 3576 size++;
@@ -3890,7 +3886,6 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
3890 3886
3891 #define CurrentModeHasSPSR (cpu->Mode != SYSTEM32MODE) && (cpu->Mode != USER32MODE) 3887 #define CurrentModeHasSPSR (cpu->Mode != SYSTEM32MODE) && (cpu->Mode != USER32MODE)
3892 #define PC (cpu->Reg[15]) 3888 #define PC (cpu->Reg[15])
3893 #define CHECK_EXT_INT if (!cpu->NirqSig && !(cpu->Cpsr & 0x80)) goto END;
3894 3889
3895 // GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback 3890 // GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback
3896 // to a clunky switch statement. 3891 // to a clunky switch statement.
@@ -4343,7 +4338,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4343 } 4338 }
4344 } 4339 }
4345 if (BIT(inst, 13)) { 4340 if (BIT(inst, 13)) {
4346 if (cpu->Mode == USER32MODE) 4341 if (cpu->Mode == USER32MODE)
4347 cpu->Reg[13] = ReadMemory32(cpu, addr); 4342 cpu->Reg[13] = ReadMemory32(cpu, addr);
4348 else 4343 else
4349 cpu->Reg_usr[0] = ReadMemory32(cpu, addr); 4344 cpu->Reg_usr[0] = ReadMemory32(cpu, addr);
@@ -4351,7 +4346,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4351 addr += 4; 4346 addr += 4;
4352 } 4347 }
4353 if (BIT(inst, 14)) { 4348 if (BIT(inst, 14)) {
4354 if (cpu->Mode == USER32MODE) 4349 if (cpu->Mode == USER32MODE)
4355 cpu->Reg[14] = ReadMemory32(cpu, addr); 4350 cpu->Reg[14] = ReadMemory32(cpu, addr);
4356 else 4351 else
4357 cpu->Reg_usr[1] = ReadMemory32(cpu, addr); 4352 cpu->Reg_usr[1] = ReadMemory32(cpu, addr);
@@ -5153,7 +5148,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5153 REV16_INST: 5148 REV16_INST:
5154 REVSH_INST: 5149 REVSH_INST:
5155 { 5150 {
5156 5151
5157 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { 5152 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
5158 rev_inst* const inst_cream = (rev_inst*)inst_base->component; 5153 rev_inst* const inst_cream = (rev_inst*)inst_base->component;
5159 5154
@@ -5726,7 +5721,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5726 5721
5727 if (do_swap) 5722 if (do_swap)
5728 rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16)); 5723 rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16));
5729 5724
5730 const s32 product1 = (s16)(rn_val & 0xFFFF) * (s16)(rm_val & 0xFFFF); 5725 const s32 product1 = (s16)(rn_val & 0xFFFF) * (s16)(rm_val & 0xFFFF);
5731 const s32 product2 = (s16)((rn_val >> 16) & 0xFFFF) * (s16)((rm_val >> 16) & 0xFFFF); 5726 const s32 product2 = (s16)((rn_val >> 16) & 0xFFFF) * (s16)((rm_val >> 16) & 0xFFFF);
5732 s64 result; 5727 s64 result;
@@ -6588,7 +6583,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6588 { 6583 {
6589 u32 lo_val = 0; 6584 u32 lo_val = 0;
6590 u32 hi_val = 0; 6585 u32 hi_val = 0;
6591 6586
6592 // UHADD16 6587 // UHADD16
6593 if (op2 == 0x00) { 6588 if (op2 == 0x00) {
6594 lo_val = (rn_val & 0xFFFF) + (rm_val & 0xFFFF); 6589 lo_val = (rn_val & 0xFFFF) + (rm_val & 0xFFFF);
@@ -6777,7 +6772,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6777 6772
6778 u16 lo_val = 0; 6773 u16 lo_val = 0;
6779 u16 hi_val = 0; 6774 u16 hi_val = 0;
6780 6775
6781 // UQADD16 6776 // UQADD16
6782 if (op2 == 0x00) { 6777 if (op2 == 0x00) {
6783 lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, rm_val & 0xFFFF); 6778 lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, rm_val & 0xFFFF);
diff --git a/src/core/arm/dyncom/arm_dyncom_thumb.cpp b/src/core/arm/dyncom/arm_dyncom_thumb.cpp
index 08b5c0b77..3e79c44c0 100644
--- a/src/core/arm/dyncom/arm_dyncom_thumb.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_thumb.cpp
@@ -184,38 +184,27 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
184 case 9: // LDR Rd,[PC,#imm8] 184 case 9: // LDR Rd,[PC,#imm8]
185 *ainstr = 0xE59F0000 // base 185 *ainstr = 0xE59F0000 // base
186 | ((tinstr & 0x0700) << (12 - 8)) // Rd 186 | ((tinstr & 0x0700) << (12 - 8)) // Rd
187 |((tinstr & 0x00FF) << (2 - 0)); // off8 187 |((tinstr & 0x00FF) << (2 - 0)); // off8
188 break; 188 break;
189 189
190 case 10: 190 case 10:
191 case 11: 191 case 11:
192 // TODO: Format 7 and Format 8 perform the same ARM encoding, so the following could be 192 {
193 // merged into a single subset, saving on the following boolean: 193 static const ARMword subset[8] = {
194 194 0xE7800000, // STR Rd,[Rb,Ro]
195 if ((tinstr & (1 << 9)) == 0) {
196 static const ARMword subset[4] = {
197 0xE7800000, // STR Rd,[Rb,Ro]
198 0xE7C00000, // STRB Rd,[Rb,Ro]
199 0xE7900000, // LDR Rd,[Rb,Ro]
200 0xE7D00000 // LDRB Rd,[Rb,Ro]
201 };
202
203 *ainstr = subset[(tinstr & 0x0C00) >> 10] // base
204 |((tinstr & 0x0007) << (12 - 0)) // Rd
205 |((tinstr & 0x0038) << (16 - 3)) // Rb
206 |((tinstr & 0x01C0) >> 6); // Ro
207
208 } else {
209 static const ARMword subset[4] = {
210 0xE18000B0, // STRH Rd,[Rb,Ro] 195 0xE18000B0, // STRH Rd,[Rb,Ro]
196 0xE7C00000, // STRB Rd,[Rb,Ro]
211 0xE19000D0, // LDRSB Rd,[Rb,Ro] 197 0xE19000D0, // LDRSB Rd,[Rb,Ro]
198 0xE7900000, // LDR Rd,[Rb,Ro]
212 0xE19000B0, // LDRH Rd,[Rb,Ro] 199 0xE19000B0, // LDRH Rd,[Rb,Ro]
200 0xE7D00000, // LDRB Rd,[Rb,Ro]
213 0xE19000F0 // LDRSH Rd,[Rb,Ro] 201 0xE19000F0 // LDRSH Rd,[Rb,Ro]
214 }; 202 };
215 *ainstr = subset[(tinstr & 0x0C00) >> 10] // base 203
216 |((tinstr & 0x0007) << (12 - 0)) // Rd 204 *ainstr = subset[(tinstr & 0xE00) >> 9] // base
217 |((tinstr & 0x0038) << (16 - 3)) // Rb 205 |((tinstr & 0x0007) << (12 - 0)) // Rd
218 |((tinstr & 0x01C0) >> 6); // Ro 206 |((tinstr & 0x0038) << (16 - 3)) // Rb
207 |((tinstr & 0x01C0) >> 6); // Ro
219 } 208 }
220 break; 209 break;
221 210
@@ -285,9 +274,46 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
285 ? 0xE24DDF00 // SUB 274 ? 0xE24DDF00 // SUB
286 : 0xE28DDF00) // ADD 275 : 0xE28DDF00) // ADD
287 |(tinstr & 0x007F); // off7 276 |(tinstr & 0x007F); // off7
288 } else if ((tinstr & 0x0F00) == 0x0e00) 277 } else if ((tinstr & 0x0F00) == 0x0e00) {
289 *ainstr = 0xEF000000 | 0x180000; // base | BKPT mask 278 // BKPT
290 else { 279 *ainstr = 0xEF000000 // base
280 | BITS(tinstr, 0, 3) // imm4 field;
281 | (BITS(tinstr, 4, 7) << 8); // beginning 4 bits of imm12
282 } else if ((tinstr & 0x0F00) == 0x0200) {
283 static const ARMword subset[4] = {
284 0xE6BF0070, // SXTH
285 0xE6AF0070, // SXTB
286 0xE6FF0070, // UXTH
287 0xE6EF0070, // UXTB
288 };
289
290 *ainstr = subset[BITS(tinstr, 6, 7)] // base
291 | (BITS(tinstr, 0, 2) << 12) // Rd
292 | BITS(tinstr, 3, 5); // Rm
293 } else if ((tinstr & 0x0F00) == 0x600) {
294 if (BIT(tinstr, 5) == 0) {
295 // SETEND
296 *ainstr = 0xF1010000 // base
297 | (BIT(tinstr, 3) << 9); // endian specifier
298 } else {
299 // CPS
300 *ainstr = 0xF1080000 // base
301 | (BIT(tinstr, 0) << 6) // fiq bit
302 | (BIT(tinstr, 1) << 7) // irq bit
303 | (BIT(tinstr, 2) << 8) // abort bit
304 | (BIT(tinstr, 4) << 18); // enable bit
305 }
306 } else if ((tinstr & 0x0F00) == 0x0a00) {
307 static const ARMword subset[3] = {
308 0xE6BF0F30, // REV
309 0xE6BF0FB0, // REV16
310 0xE6FF0FB0, // REVSH
311 };
312
313 *ainstr = subset[BITS(tinstr, 6, 7)] // base
314 | (BITS(tinstr, 0, 2) << 12) // Rd
315 | BITS(tinstr, 3, 5); // Rm
316 } else {
291 static const ARMword subset[4] = { 317 static const ARMword subset[4] = {
292 0xE92D0000, // STMDB sp!,{rlist} 318 0xE92D0000, // STMDB sp!,{rlist}
293 0xE92D4000, // STMDB sp!,{rlist,lr} 319 0xE92D4000, // STMDB sp!,{rlist,lr}
@@ -301,11 +327,25 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
301 327
302 case 24: // STMIA 328 case 24: // STMIA
303 case 25: // LDMIA 329 case 25: // LDMIA
304 *ainstr = ((tinstr & (1 << 11)) // base 330 if (tinstr & (1 << 11))
305 ? 0xE8B00000 // LDMIA 331 {
306 : 0xE8A00000) // STMIA 332 unsigned int base = 0xE8900000;
307 |((tinstr & 0x0700) << (16 - 8)) // Rb 333 unsigned int rn = BITS(tinstr, 8, 10);
308 |(tinstr & 0x00FF); // mask8 334
335 // Writeback
336 if ((tinstr & (1 << rn)) == 0)
337 base |= (1 << 21);
338
339 *ainstr = base // base (LDMIA)
340 | (rn << 16) // Rn
341 | (tinstr & 0x00FF); // Register list
342 }
343 else
344 {
345 *ainstr = 0xE8A00000 // base (STMIA)
346 | (BITS(tinstr, 8, 10) << 16) // Rn
347 | (tinstr & 0x00FF); // Register list
348 }
309 break; 349 break;
310 350
311 case 26: // Bcc 351 case 26: // Bcc
diff --git a/src/core/arm/interpreter/arminit.cpp b/src/core/arm/interpreter/arminit.cpp
index 680a94a39..4f7a48fab 100644
--- a/src/core/arm/interpreter/arminit.cpp
+++ b/src/core/arm/interpreter/arminit.cpp
@@ -17,7 +17,6 @@
17 17
18#include <cstring> 18#include <cstring>
19#include "core/arm/skyeye_common/armdefs.h" 19#include "core/arm/skyeye_common/armdefs.h"
20#include "core/arm/skyeye_common/armemu.h"
21#include "core/arm/skyeye_common/vfp/vfp.h" 20#include "core/arm/skyeye_common/vfp/vfp.h"
22 21
23/***************************************************************************\ 22/***************************************************************************\
diff --git a/src/core/arm/interpreter/armsupp.cpp b/src/core/arm/interpreter/armsupp.cpp
index 1b078dc71..83f7f3e2c 100644
--- a/src/core/arm/interpreter/armsupp.cpp
+++ b/src/core/arm/interpreter/armsupp.cpp
@@ -628,7 +628,7 @@ void WriteCP15Register(ARMul_State* cpu, u32 value, u32 crn, u32 opcode_1, u32 c
628 cpu->CP15[CP15_DATA_SYNC_BARRIER] = value; 628 cpu->CP15[CP15_DATA_SYNC_BARRIER] = value;
629 else if (opcode_2 == 5) 629 else if (opcode_2 == 5)
630 cpu->CP15[CP15_DATA_MEMORY_BARRIER] = value; 630 cpu->CP15[CP15_DATA_MEMORY_BARRIER] = value;
631 631
632 } 632 }
633 else if (crn == 13 && opcode_1 == 0 && crm == 0 && opcode_2 == 2) 633 else if (crn == 13 && opcode_1 == 0 && crm == 0 && opcode_2 == 2)
634 { 634 {
diff --git a/src/core/arm/skyeye_common/arm_regformat.h b/src/core/arm/skyeye_common/arm_regformat.h
index 6c89774eb..a92effbb4 100644
--- a/src/core/arm/skyeye_common/arm_regformat.h
+++ b/src/core/arm/skyeye_common/arm_regformat.h
@@ -59,6 +59,8 @@ enum {
59 VFP_FPSID, 59 VFP_FPSID,
60 VFP_FPSCR, 60 VFP_FPSCR,
61 VFP_FPEXC, 61 VFP_FPEXC,
62 VFP_MVFR0,
63 VFP_MVFR1,
62 64
63 // Not an actual register. 65 // Not an actual register.
64 // All VFP system registers should be defined above this. 66 // All VFP system registers should be defined above this.
diff --git a/src/core/arm/skyeye_common/armdefs.h b/src/core/arm/skyeye_common/armdefs.h
index 470f9508d..d2c901100 100644
--- a/src/core/arm/skyeye_common/armdefs.h
+++ b/src/core/arm/skyeye_common/armdefs.h
@@ -1,16 +1,16 @@
1/* armdefs.h -- ARMulator common definitions: ARM6 Instruction Emulator. 1/* armdefs.h -- ARMulator common definitions: ARM6 Instruction Emulator.
2 Copyright (C) 1994 Advanced RISC Machines Ltd. 2 Copyright (C) 1994 Advanced RISC Machines Ltd.
3 3
4 This program is free software; you can redistribute it and/or modify 4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by 5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or 6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version. 7 (at your option) any later version.
8 8
9 This program is distributed in the hope that it will be useful, 9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of 10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details. 12 GNU General Public License for more details.
13 13
14 You should have received a copy of the GNU General Public License 14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software 15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
@@ -262,6 +262,34 @@ enum ConditionCode {
262 NV = 15, 262 NV = 15,
263}; 263};
264 264
265// Flags for use with the APSR.
266enum : u32 {
267 NBIT = (1U << 31U),
268 ZBIT = (1 << 30),
269 CBIT = (1 << 29),
270 VBIT = (1 << 28),
271 QBIT = (1 << 27),
272 JBIT = (1 << 24),
273 EBIT = (1 << 9),
274 ABIT = (1 << 8),
275 IBIT = (1 << 7),
276 FBIT = (1 << 6),
277 TBIT = (1 << 5),
278
279 // Masks for groups of bits in the APSR.
280 MODEBITS = 0x1F,
281 INTBITS = 0x1C0,
282};
283
284// Values for Emulate.
285enum {
286 STOP = 0, // Stop
287 CHANGEMODE = 1, // Change mode
288 ONCE = 2, // Execute just one iteration
289 RUN = 3 // Continuous execution
290};
291
292
265extern bool AddOverflow(ARMword, ARMword, ARMword); 293extern bool AddOverflow(ARMword, ARMword, ARMword);
266extern bool SubOverflow(ARMword, ARMword, ARMword); 294extern bool SubOverflow(ARMword, ARMword, ARMword);
267 295
diff --git a/src/core/arm/skyeye_common/armemu.h b/src/core/arm/skyeye_common/armemu.h
deleted file mode 100644
index 7e0965052..000000000
--- a/src/core/arm/skyeye_common/armemu.h
+++ /dev/null
@@ -1,47 +0,0 @@
1/* armemu.h -- ARMulator emulation macros: ARM6 Instruction Emulator.
2 Copyright (C) 1994 Advanced RISC Machines Ltd.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18#pragma once
19
20#include "core/arm/skyeye_common/armdefs.h"
21
22// Flags for use with the APSR.
23enum : u32 {
24 NBIT = (1U << 31U),
25 ZBIT = (1 << 30),
26 CBIT = (1 << 29),
27 VBIT = (1 << 28),
28 QBIT = (1 << 27),
29 JBIT = (1 << 24),
30 EBIT = (1 << 9),
31 ABIT = (1 << 8),
32 IBIT = (1 << 7),
33 FBIT = (1 << 6),
34 TBIT = (1 << 5),
35
36 // Masks for groups of bits in the APSR.
37 MODEBITS = 0x1F,
38 INTBITS = 0x1C0,
39};
40
41// Values for Emulate.
42enum {
43 STOP = 0, // Stop
44 CHANGEMODE = 1, // Change mode
45 ONCE = 2, // Execute just one interation
46 RUN = 3 // Continuous execution
47};
diff --git a/src/core/arm/skyeye_common/vfp/vfp.cpp b/src/core/arm/skyeye_common/vfp/vfp.cpp
index b88d47750..571d6c2f2 100644
--- a/src/core/arm/skyeye_common/vfp/vfp.cpp
+++ b/src/core/arm/skyeye_common/vfp/vfp.cpp
@@ -33,6 +33,10 @@ unsigned VFPInit(ARMul_State* state)
33 state->VFP[VFP_FPEXC] = 0; 33 state->VFP[VFP_FPEXC] = 0;
34 state->VFP[VFP_FPSCR] = 0; 34 state->VFP[VFP_FPSCR] = 0;
35 35
36 // ARM11 MPCore feature register values.
37 state->VFP[VFP_MVFR0] = 0x11111111;
38 state->VFP[VFP_MVFR1] = 0;
39
36 return 0; 40 return 0;
37} 41}
38 42
diff --git a/src/core/arm/skyeye_common/vfp/vfp.h b/src/core/arm/skyeye_common/vfp/vfp.h
index 727350f14..acefae9bb 100644
--- a/src/core/arm/skyeye_common/vfp/vfp.h
+++ b/src/core/arm/skyeye_common/vfp/vfp.h
@@ -22,7 +22,6 @@
22 22
23#include "core/arm/skyeye_common/vfp/vfp_helper.h" /* for references to cdp SoftFloat functions */ 23#include "core/arm/skyeye_common/vfp/vfp_helper.h" /* for references to cdp SoftFloat functions */
24 24
25#define VFP_DEBUG_UNIMPLEMENTED(x) LOG_ERROR(Core_ARM11, "in func %s, " #x " unimplemented\n", __FUNCTION__); exit(-1);
26#define VFP_DEBUG_UNTESTED(x) LOG_TRACE(Core_ARM11, "in func %s, " #x " untested\n", __FUNCTION__); 25#define VFP_DEBUG_UNTESTED(x) LOG_TRACE(Core_ARM11, "in func %s, " #x " untested\n", __FUNCTION__);
27#define CHECK_VFP_ENABLED 26#define CHECK_VFP_ENABLED
28#define CHECK_VFP_CDP_RET vfp_raise_exceptions(cpu, ret, inst_cream->instr, cpu->VFP[VFP_FPSCR]); 27#define CHECK_VFP_CDP_RET vfp_raise_exceptions(cpu, ret, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
diff --git a/src/core/arm/skyeye_common/vfp/vfp_helper.h b/src/core/arm/skyeye_common/vfp/vfp_helper.h
index ccc0212ab..2007d6dc4 100644
--- a/src/core/arm/skyeye_common/vfp/vfp_helper.h
+++ b/src/core/arm/skyeye_common/vfp/vfp_helper.h
@@ -18,10 +18,10 @@
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19*/ 19*/
20 20
21/* 21/*
22 * The following code is derivative from Linux Android kernel vfp 22 * The following code is derivative from Linux Android kernel vfp
23 * floating point support. 23 * floating point support.
24 * 24 *
25 * Copyright (C) 2004 ARM Limited. 25 * Copyright (C) 2004 ARM Limited.
26 * Written by Deep Blue Solutions Limited. 26 * Written by Deep Blue Solutions Limited.
27 * 27 *
diff --git a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
index 3ed918a93..67fe63aa4 100644
--- a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
+++ b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
@@ -1068,10 +1068,12 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrc)(unsigned int inst, int index)
1068#ifdef VFP_INTERPRETER_IMPL 1068#ifdef VFP_INTERPRETER_IMPL
1069VMOVBRC_INST: 1069VMOVBRC_INST:
1070{ 1070{
1071 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 1071 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
1072 CHECK_VFP_ENABLED; 1072 CHECK_VFP_ENABLED;
1073 1073
1074 VFP_DEBUG_UNIMPLEMENTED(VMOVBRC); 1074 vmovbrc_inst* const inst_cream = (vmovbrc_inst*)inst_base->component;
1075
1076 cpu->ExtReg[(2 * inst_cream->d) + inst_cream->index] = cpu->Reg[inst_cream->t];
1075 } 1077 }
1076 cpu->Reg[15] += GET_INST_SIZE(cpu); 1078 cpu->Reg[15] += GET_INST_SIZE(cpu);
1077 INC_PC(sizeof(vmovbrc_inst)); 1079 INC_PC(sizeof(vmovbrc_inst));
@@ -1139,12 +1141,10 @@ VMRS_INST:
1139 cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_FPSID]; 1141 cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_FPSID];
1140 break; 1142 break;
1141 case 6: 1143 case 6:
1142 /* MVFR1, VFPv3 only ? */ 1144 cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_MVFR1];
1143 LOG_TRACE(Core_ARM11, "\tr%d <= MVFR1 unimplemented\n", inst_cream->Rt);
1144 break; 1145 break;
1145 case 7: 1146 case 7:
1146 /* MVFR0, VFPv3 only? */ 1147 cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_MVFR0];
1147 LOG_TRACE(Core_ARM11, "\tr%d <= MVFR0 unimplemented\n", inst_cream->Rt);
1148 break; 1148 break;
1149 case 8: 1149 case 8:
1150 cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_FPEXC]; 1150 cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_FPEXC];
@@ -1195,10 +1195,12 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbcr)(unsigned int inst, int index)
1195#ifdef VFP_INTERPRETER_IMPL 1195#ifdef VFP_INTERPRETER_IMPL
1196VMOVBCR_INST: 1196VMOVBCR_INST:
1197{ 1197{
1198 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 1198 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
1199 CHECK_VFP_ENABLED; 1199 CHECK_VFP_ENABLED;
1200 1200
1201 VFP_DEBUG_UNIMPLEMENTED(VMOVBCR); 1201 vmovbcr_inst* const inst_cream = (vmovbcr_inst*) inst_base->component;
1202
1203 cpu->Reg[inst_cream->t] = cpu->ExtReg[(2 * inst_cream->d) + inst_cream->index];
1202 } 1204 }
1203 cpu->Reg[15] += GET_INST_SIZE(cpu); 1205 cpu->Reg[15] += GET_INST_SIZE(cpu);
1204 INC_PC(sizeof(vmovbcr_inst)); 1206 INC_PC(sizeof(vmovbcr_inst));
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp
index f70c84c3d..e53c2e606 100644
--- a/src/core/core_timing.cpp
+++ b/src/core/core_timing.cpp
@@ -549,7 +549,7 @@ std::string GetScheduledEventsSummary() {
549 const char* name = event_types[event->type].name; 549 const char* name = event_types[event->type].name;
550 if (!name) 550 if (!name)
551 name = "[unknown]"; 551 name = "[unknown]";
552 text += Common::StringFromFormat("%s : %i %08x%08x\n", name, (int)event->time, 552 text += Common::StringFromFormat("%s : %i %08x%08x\n", name, (int)event->time,
553 (u32)(event->userdata >> 32), (u32)(event->userdata)); 553 (u32)(event->userdata >> 32), (u32)(event->userdata));
554 event = event->next; 554 event = event->next;
555 } 555 }
diff --git a/src/core/core_timing.h b/src/core/core_timing.h
index 01519608d..64f5b06d9 100644
--- a/src/core/core_timing.h
+++ b/src/core/core_timing.h
@@ -87,7 +87,7 @@ void UnregisterAllEvents();
87/// userdata MAY NOT CONTAIN POINTERS. userdata might get written and reloaded from disk, 87/// userdata MAY NOT CONTAIN POINTERS. userdata might get written and reloaded from disk,
88/// when we implement state saves. 88/// when we implement state saves.
89/** 89/**
90 * Schedules an event to run after the specified number of cycles, 90 * Schedules an event to run after the specified number of cycles,
91 * with an optional parameter to be passed to the callback handler. 91 * with an optional parameter to be passed to the callback handler.
92 * This must be run ONLY from within the cpu thread. 92 * This must be run ONLY from within the cpu thread.
93 * @param cycles_into_future The number of cycles after which this event will be fired 93 * @param cycles_into_future The number of cycles after which this event will be fired
diff --git a/src/core/file_sys/archive_extsavedata.cpp b/src/core/file_sys/archive_extsavedata.cpp
index 38d498d0e..e50c58a52 100644
--- a/src/core/file_sys/archive_extsavedata.cpp
+++ b/src/core/file_sys/archive_extsavedata.cpp
@@ -30,8 +30,8 @@ std::string GetExtSaveDataPath(const std::string& mount_point, const Path& path)
30std::string GetExtDataContainerPath(const std::string& mount_point, bool shared) { 30std::string GetExtDataContainerPath(const std::string& mount_point, bool shared) {
31 if (shared) 31 if (shared)
32 return Common::StringFromFormat("%sdata/%s/extdata/", mount_point.c_str(), SYSTEM_ID.c_str()); 32 return Common::StringFromFormat("%sdata/%s/extdata/", mount_point.c_str(), SYSTEM_ID.c_str());
33 33
34 return Common::StringFromFormat("%sNintendo 3DS/%s/%s/extdata/", mount_point.c_str(), 34 return Common::StringFromFormat("%sNintendo 3DS/%s/%s/extdata/", mount_point.c_str(),
35 SYSTEM_ID.c_str(), SDCARD_ID.c_str()); 35 SYSTEM_ID.c_str(), SDCARD_ID.c_str());
36} 36}
37 37
@@ -71,7 +71,7 @@ bool ArchiveFactory_ExtSaveData::Initialize() {
71} 71}
72 72
73ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_ExtSaveData::Open(const Path& path) { 73ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_ExtSaveData::Open(const Path& path) {
74 std::string fullpath = GetExtSaveDataPath(mount_point, path); 74 std::string fullpath = GetExtSaveDataPath(mount_point, path) + "user/";
75 if (!FileUtil::Exists(fullpath)) { 75 if (!FileUtil::Exists(fullpath)) {
76 // TODO(Subv): Check error code, this one is probably wrong 76 // TODO(Subv): Check error code, this one is probably wrong
77 return ResultCode(ErrorDescription::FS_NotFormatted, ErrorModule::FS, 77 return ResultCode(ErrorDescription::FS_NotFormatted, ErrorModule::FS,
@@ -82,8 +82,11 @@ ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_ExtSaveData::Open(cons
82} 82}
83 83
84ResultCode ArchiveFactory_ExtSaveData::Format(const Path& path) { 84ResultCode ArchiveFactory_ExtSaveData::Format(const Path& path) {
85 std::string fullpath = GetExtSaveDataPath(mount_point, path); 85 // These folders are always created with the ExtSaveData
86 FileUtil::CreateFullPath(fullpath); 86 std::string user_path = GetExtSaveDataPath(mount_point, path) + "user/";
87 std::string boss_path = GetExtSaveDataPath(mount_point, path) + "boss/";
88 FileUtil::CreateFullPath(user_path);
89 FileUtil::CreateFullPath(boss_path);
87 return RESULT_SUCCESS; 90 return RESULT_SUCCESS;
88} 91}
89 92
diff --git a/src/core/file_sys/archive_extsavedata.h b/src/core/file_sys/archive_extsavedata.h
index c77c04e44..ef0b27bde 100644
--- a/src/core/file_sys/archive_extsavedata.h
+++ b/src/core/file_sys/archive_extsavedata.h
@@ -35,14 +35,14 @@ public:
35private: 35private:
36 /** 36 /**
37 * This holds the full directory path for this archive, it is only set after a successful call 37 * This holds the full directory path for this archive, it is only set after a successful call
38 * to Open, this is formed as <base extsavedatapath>/<type>/<high>/<low>. 38 * to Open, this is formed as <base extsavedatapath>/<type>/<high>/<low>.
39 * See GetExtSaveDataPath for the code that extracts this data from an archive path. 39 * See GetExtSaveDataPath for the code that extracts this data from an archive path.
40 */ 40 */
41 std::string mount_point; 41 std::string mount_point;
42}; 42};
43 43
44/** 44/**
45 * Constructs a path to the concrete ExtData archive in the host filesystem based on the 45 * Constructs a path to the concrete ExtData archive in the host filesystem based on the
46 * input Path and base mount point. 46 * input Path and base mount point.
47 * @param mount_point The base mount point of the ExtSaveData archives. 47 * @param mount_point The base mount point of the ExtSaveData archives.
48 * @param path The path that identifies the requested concrete ExtSaveData archive. 48 * @param path The path that identifies the requested concrete ExtSaveData archive.
diff --git a/src/core/file_sys/archive_savedata.cpp b/src/core/file_sys/archive_savedata.cpp
index 8dff51966..a92309377 100644
--- a/src/core/file_sys/archive_savedata.cpp
+++ b/src/core/file_sys/archive_savedata.cpp
@@ -21,7 +21,7 @@
21namespace FileSys { 21namespace FileSys {
22 22
23static std::string GetSaveDataContainerPath(const std::string& sdmc_directory) { 23static std::string GetSaveDataContainerPath(const std::string& sdmc_directory) {
24 return Common::StringFromFormat("%sNintendo 3DS/%s/%s/title/", sdmc_directory.c_str(), 24 return Common::StringFromFormat("%sNintendo 3DS/%s/%s/title/", sdmc_directory.c_str(),
25 SYSTEM_ID.c_str(), SDCARD_ID.c_str()); 25 SYSTEM_ID.c_str(), SDCARD_ID.c_str());
26} 26}
27 27
diff --git a/src/core/hle/function_wrappers.h b/src/core/hle/function_wrappers.h
index 23c86a72d..5949cb470 100644
--- a/src/core/hle/function_wrappers.h
+++ b/src/core/hle/function_wrappers.h
@@ -9,11 +9,15 @@
9#include "core/arm/arm_interface.h" 9#include "core/arm/arm_interface.h"
10#include "core/memory.h" 10#include "core/memory.h"
11#include "core/hle/hle.h" 11#include "core/hle/hle.h"
12#include "core/hle/result.h"
12 13
13namespace HLE { 14namespace HLE {
14 15
15#define PARAM(n) Core::g_app_core->GetReg(n) 16#define PARAM(n) Core::g_app_core->GetReg(n)
16 17
18/// An invalid result code that is meant to be overwritten when a thread resumes from waiting
19static const ResultCode RESULT_INVALID(0xDEADC0DE);
20
17/** 21/**
18 * HLE a function return from the current ARM11 userland process 22 * HLE a function return from the current ARM11 userland process
19 * @param res Result to return 23 * @param res Result to return
@@ -57,8 +61,11 @@ template<ResultCode func(s32*, u32*, s32, bool, s64)> void Wrap() {
57 s32 param_1 = 0; 61 s32 param_1 = 0;
58 s32 retval = func(&param_1, (Handle*)Memory::GetPointer(PARAM(1)), (s32)PARAM(2), 62 s32 retval = func(&param_1, (Handle*)Memory::GetPointer(PARAM(1)), (s32)PARAM(2),
59 (PARAM(3) != 0), (((s64)PARAM(4) << 32) | PARAM(0))).raw; 63 (PARAM(3) != 0), (((s64)PARAM(4) << 32) | PARAM(0))).raw;
60 Core::g_app_core->SetReg(1, (u32)param_1); 64
61 FuncReturn(retval); 65 if (retval != RESULT_INVALID.raw) {
66 Core::g_app_core->SetReg(1, (u32)param_1);
67 FuncReturn(retval);
68 }
62} 69}
63 70
64template<ResultCode func(u32, u32, u32, u32, s64)> void Wrap() { 71template<ResultCode func(u32, u32, u32, u32, s64)> void Wrap() {
@@ -73,7 +80,11 @@ template<ResultCode func(u32*)> void Wrap(){
73} 80}
74 81
75template<ResultCode func(u32, s64)> void Wrap() { 82template<ResultCode func(u32, s64)> void Wrap() {
76 FuncReturn(func(PARAM(0), (((s64)PARAM(3) << 32) | PARAM(2))).raw); 83 s32 retval = func(PARAM(0), (((s64)PARAM(3) << 32) | PARAM(2))).raw;
84
85 if (retval != RESULT_INVALID.raw) {
86 FuncReturn(retval);
87 }
77} 88}
78 89
79template<ResultCode func(void*, void*, u32)> void Wrap(){ 90template<ResultCode func(void*, void*, u32)> void Wrap(){
diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp
index e45deb1c6..f338f3266 100644
--- a/src/core/hle/kernel/event.cpp
+++ b/src/core/hle/kernel/event.cpp
@@ -41,10 +41,7 @@ void Event::Acquire() {
41 41
42void Event::Signal() { 42void Event::Signal() {
43 signaled = true; 43 signaled = true;
44
45 WakeupAllWaitingThreads(); 44 WakeupAllWaitingThreads();
46
47 HLE::Reschedule(__func__);
48} 45}
49 46
50void Event::Clear() { 47void Event::Clear() {
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 726e4d2ff..20e11da16 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -32,27 +32,13 @@ void WaitObject::RemoveWaitingThread(Thread* thread) {
32 waiting_threads.erase(itr); 32 waiting_threads.erase(itr);
33} 33}
34 34
35SharedPtr<Thread> WaitObject::WakeupNextThread() {
36 if (waiting_threads.empty())
37 return nullptr;
38
39 auto next_thread = std::move(waiting_threads.front());
40 waiting_threads.erase(waiting_threads.begin());
41
42 next_thread->ReleaseWaitObject(this);
43
44 return next_thread;
45}
46
47void WaitObject::WakeupAllWaitingThreads() { 35void WaitObject::WakeupAllWaitingThreads() {
48 auto waiting_threads_copy = waiting_threads; 36 for (auto thread : waiting_threads)
37 thread->ResumeFromWait();
49 38
50 // We use a copy because ReleaseWaitObject will remove the thread from this object's 39 waiting_threads.clear();
51 // waiting_threads list
52 for (auto thread : waiting_threads_copy)
53 thread->ReleaseWaitObject(this);
54 40
55 ASSERT_MSG(waiting_threads.empty(), "failed to awaken all waiting threads!"); 41 HLE::Reschedule(__func__);
56} 42}
57 43
58HandleTable::HandleTable() { 44HandleTable::HandleTable() {
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index a5a0f4800..64595f758 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -140,12 +140,6 @@ public:
140 */ 140 */
141 void RemoveWaitingThread(Thread* thread); 141 void RemoveWaitingThread(Thread* thread);
142 142
143 /**
144 * Wake up the next thread waiting on this object
145 * @return Pointer to the thread that was resumed, nullptr if no threads are waiting
146 */
147 SharedPtr<Thread> WakeupNextThread();
148
149 /// Wake up all threads waiting on this object 143 /// Wake up all threads waiting on this object
150 void WakeupAllWaitingThreads(); 144 void WakeupAllWaitingThreads();
151 145
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp
index 6aa73df86..edb97d324 100644
--- a/src/core/hle/kernel/mutex.cpp
+++ b/src/core/hle/kernel/mutex.cpp
@@ -23,12 +23,7 @@ static void ResumeWaitingThread(Mutex* mutex) {
23 // Reset mutex lock thread handle, nothing is waiting 23 // Reset mutex lock thread handle, nothing is waiting
24 mutex->lock_count = 0; 24 mutex->lock_count = 0;
25 mutex->holding_thread = nullptr; 25 mutex->holding_thread = nullptr;
26 26 mutex->WakeupAllWaitingThreads();
27 // Find the next waiting thread for the mutex...
28 auto next_thread = mutex->WakeupNextThread();
29 if (next_thread != nullptr) {
30 mutex->Acquire(next_thread);
31 }
32} 27}
33 28
34void ReleaseThreadMutexes(Thread* thread) { 29void ReleaseThreadMutexes(Thread* thread) {
@@ -94,8 +89,6 @@ void Mutex::Release() {
94 ResumeWaitingThread(this); 89 ResumeWaitingThread(this);
95 } 90 }
96 } 91 }
97
98 HLE::Reschedule(__func__);
99} 92}
100 93
101} // namespace 94} // namespace
diff --git a/src/core/hle/kernel/resource_limit.h b/src/core/hle/kernel/resource_limit.h
index 201ec0db9..1b8249c74 100644
--- a/src/core/hle/kernel/resource_limit.h
+++ b/src/core/hle/kernel/resource_limit.h
@@ -81,13 +81,13 @@ public:
81 s32 max_timers = 0; 81 s32 max_timers = 0;
82 s32 max_shared_mems = 0; 82 s32 max_shared_mems = 0;
83 s32 max_address_arbiters = 0; 83 s32 max_address_arbiters = 0;
84 84
85 /// Max CPU time that the processes in this category can utilize 85 /// Max CPU time that the processes in this category can utilize
86 s32 max_cpu_time = 0; 86 s32 max_cpu_time = 0;
87 87
88 // TODO(Subv): Increment these in their respective Kernel::T::Create functions, keeping in mind that 88 // TODO(Subv): Increment these in their respective Kernel::T::Create functions, keeping in mind that
89 // APPLICATION resource limits should not be affected by the objects created by service modules. 89 // APPLICATION resource limits should not be affected by the objects created by service modules.
90 // Currently we have no way of distinguishing if a Create was called by the running application, 90 // Currently we have no way of distinguishing if a Create was called by the running application,
91 // or by a service module. Approach this once we have separated the service modules into their own processes 91 // or by a service module. Approach this once we have separated the service modules into their own processes
92 92
93 /// Current memory that the processes in this category are using 93 /// Current memory that the processes in this category are using
diff --git a/src/core/hle/kernel/semaphore.cpp b/src/core/hle/kernel/semaphore.cpp
index dbb4c9b7f..4b359ed07 100644
--- a/src/core/hle/kernel/semaphore.cpp
+++ b/src/core/hle/kernel/semaphore.cpp
@@ -42,19 +42,13 @@ void Semaphore::Acquire() {
42 42
43ResultVal<s32> Semaphore::Release(s32 release_count) { 43ResultVal<s32> Semaphore::Release(s32 release_count) {
44 if (max_count - available_count < release_count) 44 if (max_count - available_count < release_count)
45 return ResultCode(ErrorDescription::OutOfRange, ErrorModule::Kernel, 45 return ResultCode(ErrorDescription::OutOfRange, ErrorModule::Kernel,
46 ErrorSummary::InvalidArgument, ErrorLevel::Permanent); 46 ErrorSummary::InvalidArgument, ErrorLevel::Permanent);
47 47
48 s32 previous_count = available_count; 48 s32 previous_count = available_count;
49 available_count += release_count; 49 available_count += release_count;
50 50
51 // Notify some of the threads that the semaphore has been released 51 WakeupAllWaitingThreads();
52 // stop once the semaphore is full again or there are no more waiting threads
53 while (!ShouldWait() && WakeupNextThread() != nullptr) {
54 Acquire();
55 }
56
57 HLE::Reschedule(__func__);
58 52
59 return MakeResult<s32>(previous_count); 53 return MakeResult<s32>(previous_count);
60} 54}
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 690d33b55..4729a7fe0 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -13,6 +13,7 @@
13#include "common/thread_queue_list.h" 13#include "common/thread_queue_list.h"
14 14
15#include "core/arm/arm_interface.h" 15#include "core/arm/arm_interface.h"
16#include "core/arm/skyeye_common/armdefs.h"
16#include "core/core.h" 17#include "core/core.h"
17#include "core/core_timing.h" 18#include "core/core_timing.h"
18#include "core/hle/hle.h" 19#include "core/hle/hle.h"
@@ -100,7 +101,7 @@ void Thread::Stop() {
100 } 101 }
101 102
102 status = THREADSTATUS_DEAD; 103 status = THREADSTATUS_DEAD;
103 104
104 WakeupAllWaitingThreads(); 105 WakeupAllWaitingThreads();
105 106
106 // Clean up any dangling references in objects that this thread was waiting for 107 // Clean up any dangling references in objects that this thread was waiting for
@@ -169,7 +170,7 @@ static void PriorityBoostStarvedThreads() {
169 } 170 }
170} 171}
171 172
172/** 173/**
173 * Switches the CPU's active thread context to that of the specified thread 174 * Switches the CPU's active thread context to that of the specified thread
174 * @param new_thread The thread to switch to 175 * @param new_thread The thread to switch to
175 */ 176 */
@@ -193,8 +194,22 @@ static void SwitchContext(Thread* new_thread) {
193 if (new_thread) { 194 if (new_thread) {
194 DEBUG_ASSERT_MSG(new_thread->status == THREADSTATUS_READY, "Thread must be ready to become running."); 195 DEBUG_ASSERT_MSG(new_thread->status == THREADSTATUS_READY, "Thread must be ready to become running.");
195 196
197 // Cancel any outstanding wakeup events for this thread
198 CoreTiming::UnscheduleEvent(ThreadWakeupEventType, new_thread->callback_handle);
199
196 current_thread = new_thread; 200 current_thread = new_thread;
197 201
202 // If the thread was waited by a svcWaitSynch call, step back PC by one instruction to rerun
203 // the SVC when the thread wakes up. This is necessary to ensure that the thread can acquire
204 // the requested wait object(s) before continuing.
205 if (new_thread->waitsynch_waited) {
206 // CPSR flag indicates CPU mode
207 bool thumb_mode = (new_thread->context.cpsr & TBIT) != 0;
208
209 // SVC instruction is 2 bytes for THUMB, 4 bytes for ARM
210 new_thread->context.pc -= thumb_mode ? 2 : 4;
211 }
212
198 ready_queue.remove(new_thread->current_priority, new_thread); 213 ready_queue.remove(new_thread->current_priority, new_thread);
199 new_thread->status = THREADSTATUS_RUNNING; 214 new_thread->status = THREADSTATUS_RUNNING;
200 215
@@ -243,6 +258,7 @@ void WaitCurrentThread_WaitSynchronization(std::vector<SharedPtr<WaitObject>> wa
243 thread->wait_set_output = wait_set_output; 258 thread->wait_set_output = wait_set_output;
244 thread->wait_all = wait_all; 259 thread->wait_all = wait_all;
245 thread->wait_objects = std::move(wait_objects); 260 thread->wait_objects = std::move(wait_objects);
261 thread->waitsynch_waited = true;
246 thread->status = THREADSTATUS_WAIT_SYNCH; 262 thread->status = THREADSTATUS_WAIT_SYNCH;
247} 263}
248 264
@@ -268,6 +284,8 @@ static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) {
268 return; 284 return;
269 } 285 }
270 286
287 thread->waitsynch_waited = false;
288
271 if (thread->status == THREADSTATUS_WAIT_SYNCH) { 289 if (thread->status == THREADSTATUS_WAIT_SYNCH) {
272 thread->SetWaitSynchronizationResult(ResultCode(ErrorDescription::Timeout, ErrorModule::OS, 290 thread->SetWaitSynchronizationResult(ResultCode(ErrorDescription::Timeout, ErrorModule::OS,
273 ErrorSummary::StatusChanged, ErrorLevel::Info)); 291 ErrorSummary::StatusChanged, ErrorLevel::Info));
@@ -288,63 +306,20 @@ void Thread::WakeAfterDelay(s64 nanoseconds) {
288 CoreTiming::ScheduleEvent(usToCycles(microseconds), ThreadWakeupEventType, callback_handle); 306 CoreTiming::ScheduleEvent(usToCycles(microseconds), ThreadWakeupEventType, callback_handle);
289} 307}
290 308
291void Thread::ReleaseWaitObject(WaitObject* wait_object) {
292 if (status != THREADSTATUS_WAIT_SYNCH || wait_objects.empty()) {
293 LOG_CRITICAL(Kernel, "thread is not waiting on any objects!");
294 return;
295 }
296
297 // Remove this thread from the waiting object's thread list
298 wait_object->RemoveWaitingThread(this);
299
300 unsigned index = 0;
301 bool wait_all_failed = false; // Will be set to true if any object is unavailable
302
303 // Iterate through all waiting objects to check availability...
304 for (auto itr = wait_objects.begin(); itr != wait_objects.end(); ++itr) {
305 if ((*itr)->ShouldWait())
306 wait_all_failed = true;
307
308 // The output should be the last index of wait_object
309 if (*itr == wait_object)
310 index = itr - wait_objects.begin();
311 }
312
313 // If we are waiting on all objects...
314 if (wait_all) {
315 // Resume the thread only if all are available...
316 if (!wait_all_failed) {
317 SetWaitSynchronizationResult(RESULT_SUCCESS);
318 SetWaitSynchronizationOutput(-1);
319
320 ResumeFromWait();
321 }
322 } else {
323 // Otherwise, resume
324 SetWaitSynchronizationResult(RESULT_SUCCESS);
325
326 if (wait_set_output)
327 SetWaitSynchronizationOutput(index);
328
329 ResumeFromWait();
330 }
331}
332
333void Thread::ResumeFromWait() { 309void Thread::ResumeFromWait() {
334 // Cancel any outstanding wakeup events for this thread
335 CoreTiming::UnscheduleEvent(ThreadWakeupEventType, callback_handle);
336
337 switch (status) { 310 switch (status) {
338 case THREADSTATUS_WAIT_SYNCH: 311 case THREADSTATUS_WAIT_SYNCH:
339 // Remove this thread from all other WaitObjects
340 for (auto wait_object : wait_objects)
341 wait_object->RemoveWaitingThread(this);
342 break;
343 case THREADSTATUS_WAIT_ARB: 312 case THREADSTATUS_WAIT_ARB:
344 case THREADSTATUS_WAIT_SLEEP: 313 case THREADSTATUS_WAIT_SLEEP:
345 break; 314 break;
346 case THREADSTATUS_RUNNING: 315
347 case THREADSTATUS_READY: 316 case THREADSTATUS_READY:
317 // If the thread is waiting on multiple wait objects, it might be awoken more than once
318 // before actually resuming. We can ignore subsequent wakeups if the thread status has
319 // already been set to THREADSTATUS_READY.
320 return;
321
322 case THREADSTATUS_RUNNING:
348 DEBUG_ASSERT_MSG(false, "Thread with object id %u has already resumed.", GetObjectId()); 323 DEBUG_ASSERT_MSG(false, "Thread with object id %u has already resumed.", GetObjectId());
349 return; 324 return;
350 case THREADSTATUS_DEAD: 325 case THREADSTATUS_DEAD:
@@ -353,7 +328,7 @@ void Thread::ResumeFromWait() {
353 GetObjectId()); 328 GetObjectId());
354 return; 329 return;
355 } 330 }
356 331
357 ready_queue.push_back(current_priority, this); 332 ready_queue.push_back(current_priority, this);
358 status = THREADSTATUS_READY; 333 status = THREADSTATUS_READY;
359} 334}
@@ -415,6 +390,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
415 thread->callback_handle = wakeup_callback_handle_table.Create(thread).MoveFrom(); 390 thread->callback_handle = wakeup_callback_handle_table.Create(thread).MoveFrom();
416 thread->owner_process = g_current_process; 391 thread->owner_process = g_current_process;
417 thread->tls_index = -1; 392 thread->tls_index = -1;
393 thread->waitsynch_waited = false;
418 394
419 // Find the next available TLS index, and mark it as used 395 // Find the next available TLS index, and mark it as used
420 auto& used_tls_slots = Kernel::g_current_process->used_tls_slots; 396 auto& used_tls_slots = Kernel::g_current_process->used_tls_slots;
@@ -504,7 +480,7 @@ void Reschedule() {
504 } else if (next) { 480 } else if (next) {
505 LOG_TRACE(Kernel, "context switch idle -> %u", next->GetObjectId()); 481 LOG_TRACE(Kernel, "context switch idle -> %u", next->GetObjectId());
506 } 482 }
507 483
508 SwitchContext(next); 484 SwitchContext(next);
509} 485}
510 486
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 389928178..b8160bb2c 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -94,12 +94,6 @@ public:
94 * @return The thread's ID 94 * @return The thread's ID
95 */ 95 */
96 u32 GetThreadId() const { return thread_id; } 96 u32 GetThreadId() const { return thread_id; }
97
98 /**
99 * Release an acquired wait object
100 * @param wait_object WaitObject to release
101 */
102 void ReleaseWaitObject(WaitObject* wait_object);
103 97
104 /** 98 /**
105 * Resumes a thread from waiting 99 * Resumes a thread from waiting
@@ -152,6 +146,8 @@ public:
152 146
153 s32 tls_index; ///< Index of the Thread Local Storage of the thread 147 s32 tls_index; ///< Index of the Thread Local Storage of the thread
154 148
149 bool waitsynch_waited; ///< Set to true if the last svcWaitSynch call caused the thread to wait
150
155 /// Mutexes currently held by this thread, which will be released when it exits. 151 /// Mutexes currently held by this thread, which will be released when it exits.
156 boost::container::flat_set<SharedPtr<Mutex>> held_mutexes; 152 boost::container::flat_set<SharedPtr<Mutex>> held_mutexes;
157 153
@@ -163,12 +159,12 @@ public:
163 159
164 std::string name; 160 std::string name;
165 161
162 /// Handle used as userdata to reference this object when inserting into the CoreTiming queue.
163 Handle callback_handle;
164
166private: 165private:
167 Thread(); 166 Thread();
168 ~Thread() override; 167 ~Thread() override;
169
170 /// Handle used as userdata to reference this object when inserting into the CoreTiming queue.
171 Handle callback_handle;
172}; 168};
173 169
174/** 170/**
diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp
index 25d066bf1..8aa4110a6 100644
--- a/src/core/hle/kernel/timer.cpp
+++ b/src/core/hle/kernel/timer.cpp
@@ -88,7 +88,7 @@ static void TimerCallback(u64 timer_handle, int cycles_late) {
88 if (timer->interval_delay != 0) { 88 if (timer->interval_delay != 0) {
89 // Reschedule the timer with the interval delay 89 // Reschedule the timer with the interval delay
90 u64 interval_microseconds = timer->interval_delay / 1000; 90 u64 interval_microseconds = timer->interval_delay / 1000;
91 CoreTiming::ScheduleEvent(usToCycles(interval_microseconds) - cycles_late, 91 CoreTiming::ScheduleEvent(usToCycles(interval_microseconds) - cycles_late,
92 timer_callback_event_type, timer_handle); 92 timer_callback_event_type, timer_handle);
93 } 93 }
94} 94}
diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp
new file mode 100644
index 000000000..b2dd21542
--- /dev/null
+++ b/src/core/hle/kernel/vm_manager.cpp
@@ -0,0 +1,245 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/assert.h"
6
7#include "core/hle/kernel/vm_manager.h"
8#include "core/memory_setup.h"
9
10namespace Kernel {
11
12bool VirtualMemoryArea::CanBeMergedWith(const VirtualMemoryArea& next) const {
13 ASSERT(base + size == next.base);
14 if (permissions != next.permissions ||
15 meminfo_state != next.meminfo_state ||
16 type != next.type) {
17 return false;
18 }
19 if (type == VMAType::AllocatedMemoryBlock &&
20 (backing_block != next.backing_block || offset + size != next.offset)) {
21 return false;
22 }
23 if (type == VMAType::BackingMemory && backing_memory + size != next.backing_memory) {
24 return false;
25 }
26 if (type == VMAType::MMIO && paddr + size != next.paddr) {
27 return false;
28 }
29 return true;
30}
31
32VMManager::VMManager() {
33 Reset();
34}
35
36void VMManager::Reset() {
37 vma_map.clear();
38
39 // Initialize the map with a single free region covering the entire managed space.
40 VirtualMemoryArea initial_vma;
41 initial_vma.size = MAX_ADDRESS;
42 vma_map.emplace(initial_vma.base, initial_vma);
43
44 UpdatePageTableForVMA(initial_vma);
45}
46
47VMManager::VMAHandle VMManager::FindVMA(VAddr target) const {
48 return std::prev(vma_map.upper_bound(target));
49}
50
51ResultVal<VMManager::VMAHandle> VMManager::MapMemoryBlock(VAddr target,
52 std::shared_ptr<std::vector<u8>> block, u32 offset, u32 size, MemoryState state) {
53 ASSERT(block != nullptr);
54 ASSERT(offset + size <= block->size());
55
56 // This is the appropriately sized VMA that will turn into our allocation.
57 CASCADE_RESULT(VMAIter vma_handle, CarveVMA(target, size));
58 VirtualMemoryArea& final_vma = vma_handle->second;
59 ASSERT(final_vma.size == size);
60
61 final_vma.type = VMAType::AllocatedMemoryBlock;
62 final_vma.permissions = VMAPermission::ReadWrite;
63 final_vma.meminfo_state = state;
64 final_vma.backing_block = block;
65 final_vma.offset = offset;
66 UpdatePageTableForVMA(final_vma);
67
68 return MakeResult<VMAHandle>(MergeAdjacent(vma_handle));
69}
70
71ResultVal<VMManager::VMAHandle> VMManager::MapBackingMemory(VAddr target, u8 * memory, u32 size, MemoryState state) {
72 ASSERT(memory != nullptr);
73
74 // This is the appropriately sized VMA that will turn into our allocation.
75 CASCADE_RESULT(VMAIter vma_handle, CarveVMA(target, size));
76 VirtualMemoryArea& final_vma = vma_handle->second;
77 ASSERT(final_vma.size == size);
78
79 final_vma.type = VMAType::BackingMemory;
80 final_vma.permissions = VMAPermission::ReadWrite;
81 final_vma.meminfo_state = state;
82 final_vma.backing_memory = memory;
83 UpdatePageTableForVMA(final_vma);
84
85 return MakeResult<VMAHandle>(MergeAdjacent(vma_handle));
86}
87
88ResultVal<VMManager::VMAHandle> VMManager::MapMMIO(VAddr target, PAddr paddr, u32 size, MemoryState state) {
89 // This is the appropriately sized VMA that will turn into our allocation.
90 CASCADE_RESULT(VMAIter vma_handle, CarveVMA(target, size));
91 VirtualMemoryArea& final_vma = vma_handle->second;
92 ASSERT(final_vma.size == size);
93
94 final_vma.type = VMAType::MMIO;
95 final_vma.permissions = VMAPermission::ReadWrite;
96 final_vma.meminfo_state = state;
97 final_vma.paddr = paddr;
98 UpdatePageTableForVMA(final_vma);
99
100 return MakeResult<VMAHandle>(MergeAdjacent(vma_handle));
101}
102
103void VMManager::Unmap(VMAHandle vma_handle) {
104 VMAIter iter = StripIterConstness(vma_handle);
105
106 VirtualMemoryArea& vma = iter->second;
107 vma.type = VMAType::Free;
108 vma.permissions = VMAPermission::None;
109 vma.meminfo_state = MemoryState::Free;
110
111 vma.backing_block = nullptr;
112 vma.offset = 0;
113 vma.backing_memory = nullptr;
114 vma.paddr = 0;
115
116 UpdatePageTableForVMA(vma);
117
118 MergeAdjacent(iter);
119}
120
121void VMManager::Reprotect(VMAHandle vma_handle, VMAPermission new_perms) {
122 VMAIter iter = StripIterConstness(vma_handle);
123
124 VirtualMemoryArea& vma = iter->second;
125 vma.permissions = new_perms;
126 UpdatePageTableForVMA(vma);
127
128 MergeAdjacent(iter);
129}
130
131VMManager::VMAIter VMManager::StripIterConstness(const VMAHandle & iter) {
132 // This uses a neat C++ trick to convert a const_iterator to a regular iterator, given
133 // non-const access to its container.
134 return vma_map.erase(iter, iter); // Erases an empty range of elements
135}
136
137ResultVal<VMManager::VMAIter> VMManager::CarveVMA(VAddr base, u32 size) {
138 ASSERT_MSG((size & Memory::PAGE_MASK) == 0, "non-page aligned size: %8X", size);
139 ASSERT_MSG((base & Memory::PAGE_MASK) == 0, "non-page aligned base: %08X", base);
140
141 VMAIter vma_handle = StripIterConstness(FindVMA(base));
142 if (vma_handle == vma_map.end()) {
143 // Target address is outside the range managed by the kernel
144 return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::OS,
145 ErrorSummary::InvalidArgument, ErrorLevel::Usage); // 0xE0E01BF5
146 }
147
148 VirtualMemoryArea& vma = vma_handle->second;
149 if (vma.type != VMAType::Free) {
150 // Region is already allocated
151 return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::OS,
152 ErrorSummary::InvalidState, ErrorLevel::Usage); // 0xE0A01BF5
153 }
154
155 u32 start_in_vma = base - vma.base;
156 u32 end_in_vma = start_in_vma + size;
157
158 if (end_in_vma > vma.size) {
159 // Requested allocation doesn't fit inside VMA
160 return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::OS,
161 ErrorSummary::InvalidState, ErrorLevel::Usage); // 0xE0A01BF5
162 }
163
164 if (end_in_vma != vma.size) {
165 // Split VMA at the end of the allocated region
166 SplitVMA(vma_handle, end_in_vma);
167 }
168 if (start_in_vma != 0) {
169 // Split VMA at the start of the allocated region
170 vma_handle = SplitVMA(vma_handle, start_in_vma);
171 }
172
173 return MakeResult<VMAIter>(vma_handle);
174}
175
176VMManager::VMAIter VMManager::SplitVMA(VMAIter vma_handle, u32 offset_in_vma) {
177 VirtualMemoryArea& old_vma = vma_handle->second;
178 VirtualMemoryArea new_vma = old_vma; // Make a copy of the VMA
179
180 // For now, don't allow no-op VMA splits (trying to split at a boundary) because it's probably
181 // a bug. This restriction might be removed later.
182 ASSERT(offset_in_vma < old_vma.size);
183 ASSERT(offset_in_vma > 0);
184
185 old_vma.size = offset_in_vma;
186 new_vma.base += offset_in_vma;
187 new_vma.size -= offset_in_vma;
188
189 switch (new_vma.type) {
190 case VMAType::Free:
191 break;
192 case VMAType::AllocatedMemoryBlock:
193 new_vma.offset += offset_in_vma;
194 break;
195 case VMAType::BackingMemory:
196 new_vma.backing_memory += offset_in_vma;
197 break;
198 case VMAType::MMIO:
199 new_vma.paddr += offset_in_vma;
200 break;
201 }
202
203 ASSERT(old_vma.CanBeMergedWith(new_vma));
204
205 return vma_map.emplace_hint(std::next(vma_handle), new_vma.base, new_vma);
206}
207
208VMManager::VMAIter VMManager::MergeAdjacent(VMAIter iter) {
209 VMAIter next_vma = std::next(iter);
210 if (next_vma != vma_map.end() && iter->second.CanBeMergedWith(next_vma->second)) {
211 iter->second.size += next_vma->second.size;
212 vma_map.erase(next_vma);
213 }
214
215 if (iter != vma_map.begin()) {
216 VMAIter prev_vma = std::prev(iter);
217 if (prev_vma->second.CanBeMergedWith(iter->second)) {
218 prev_vma->second.size += iter->second.size;
219 vma_map.erase(iter);
220 iter = prev_vma;
221 }
222 }
223
224 return iter;
225}
226
227void VMManager::UpdatePageTableForVMA(const VirtualMemoryArea& vma) {
228 switch (vma.type) {
229 case VMAType::Free:
230 Memory::UnmapRegion(vma.base, vma.size);
231 break;
232 case VMAType::AllocatedMemoryBlock:
233 Memory::MapMemoryRegion(vma.base, vma.size, vma.backing_block->data() + vma.offset);
234 break;
235 case VMAType::BackingMemory:
236 Memory::MapMemoryRegion(vma.base, vma.size, vma.backing_memory);
237 break;
238 case VMAType::MMIO:
239 // TODO(yuriks): Add support for MMIO handlers.
240 Memory::MapIoRegion(vma.base, vma.size);
241 break;
242 }
243}
244
245}
diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h
new file mode 100644
index 000000000..22b724603
--- /dev/null
+++ b/src/core/hle/kernel/vm_manager.h
@@ -0,0 +1,200 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <map>
8#include <memory>
9#include <string>
10#include <vector>
11
12#include "common/common_types.h"
13
14#include "core/hle/result.h"
15
16namespace Kernel {
17
18enum class VMAType : u8 {
19 /// VMA represents an unmapped region of the address space.
20 Free,
21 /// VMA is backed by a ref-counted allocate memory block.
22 AllocatedMemoryBlock,
23 /// VMA is backed by a raw, unmanaged pointer.
24 BackingMemory,
25 /// VMA is mapped to MMIO registers at a fixed PAddr.
26 MMIO,
27 // TODO(yuriks): Implement MemoryAlias to support MAP/UNMAP
28};
29
30/// Permissions for mapped memory blocks
31enum class VMAPermission : u8 {
32 None = 0,
33 Read = 1,
34 Write = 2,
35 Execute = 4,
36
37 ReadWrite = Read | Write,
38 ReadExecute = Read | Execute,
39 WriteExecute = Write | Execute,
40 ReadWriteExecute = Read | Write | Execute,
41};
42
43/// Set of values returned in MemoryInfo.state by svcQueryMemory.
44enum class MemoryState : u8 {
45 Free = 0,
46 Reserved = 1,
47 IO = 2,
48 Static = 3,
49 Code = 4,
50 Private = 5,
51 Shared = 6,
52 Continuous = 7,
53 Aliased = 8,
54 Alias = 9,
55 AliasCode = 10,
56 Locked = 11,
57};
58
59/**
60 * Represents a VMA in an address space. A VMA is a contiguous region of virtual addressing space
61 * with homogeneous attributes across its extents. In this particular implementation each VMA is
62 * also backed by a single host memory allocation.
63 */
64struct VirtualMemoryArea {
65 /// Virtual base address of the region.
66 VAddr base = 0;
67 /// Size of the region.
68 u32 size = 0;
69
70 VMAType type = VMAType::Free;
71 VMAPermission permissions = VMAPermission::None;
72 /// Tag returned by svcQueryMemory. Not otherwise used.
73 MemoryState meminfo_state = MemoryState::Free;
74
75 // Settings for type = AllocatedMemoryBlock
76 /// Memory block backing this VMA.
77 std::shared_ptr<std::vector<u8>> backing_block = nullptr;
78 /// Offset into the backing_memory the mapping starts from.
79 u32 offset = 0;
80
81 // Settings for type = BackingMemory
82 /// Pointer backing this VMA. It will not be destroyed or freed when the VMA is removed.
83 u8* backing_memory = nullptr;
84
85 // Settings for type = MMIO
86 /// Physical address of the register area this VMA maps to.
87 PAddr paddr = 0;
88
89 /// Tests if this area can be merged to the right with `next`.
90 bool CanBeMergedWith(const VirtualMemoryArea& next) const;
91};
92
93/**
94 * Manages a process' virtual addressing space. This class maintains a list of allocated and free
95 * regions in the address space, along with their attributes, and allows kernel clients to
96 * manipulate it, adjusting the page table to match.
97 *
98 * This is similar in idea and purpose to the VM manager present in operating system kernels, with
99 * the main difference being that it doesn't have to support swapping or memory mapping of files.
100 * The implementation is also simplified by not having to allocate page frames. See these articles
101 * about the Linux kernel for an explantion of the concept and implementation:
102 * - http://duartes.org/gustavo/blog/post/how-the-kernel-manages-your-memory/
103 * - http://duartes.org/gustavo/blog/post/page-cache-the-affair-between-memory-and-files/
104 */
105class VMManager {
106 // TODO(yuriks): Make page tables switchable to support multiple VMManagers
107public:
108 /**
109 * The maximum amount of address space managed by the kernel. Addresses above this are never used.
110 * @note This is the limit used by the New 3DS kernel. Old 3DS used 0x20000000.
111 */
112 static const u32 MAX_ADDRESS = 0x40000000;
113
114 /**
115 * A map covering the entirety of the managed address space, keyed by the `base` field of each
116 * VMA. It must always be modified by splitting or merging VMAs, so that the invariant
117 * `elem.base + elem.size == next.base` is preserved, and mergeable regions must always be
118 * merged when possible so that no two similar and adjacent regions exist that have not been
119 * merged.
120 */
121 std::map<VAddr, VirtualMemoryArea> vma_map;
122 using VMAHandle = decltype(vma_map)::const_iterator;
123
124 VMManager();
125
126 /// Clears the address space map, re-initializing with a single free area.
127 void Reset();
128
129 /// Finds the VMA in which the given address is included in, or `vma_map.end()`.
130 VMAHandle FindVMA(VAddr target) const;
131
132 // TODO(yuriks): Should these functions actually return the handle?
133
134 /**
135 * Maps part of a ref-counted block of memory at a given address.
136 *
137 * @param target The guest address to start the mapping at.
138 * @param block The block to be mapped.
139 * @param offset Offset into `block` to map from.
140 * @param size Size of the mapping.
141 * @param state MemoryState tag to attach to the VMA.
142 */
143 ResultVal<VMAHandle> MapMemoryBlock(VAddr target, std::shared_ptr<std::vector<u8>> block,
144 u32 offset, u32 size, MemoryState state);
145
146 /**
147 * Maps an unmanaged host memory pointer at a given address.
148 *
149 * @param target The guest address to start the mapping at.
150 * @param memory The memory to be mapped.
151 * @param size Size of the mapping.
152 * @param state MemoryState tag to attach to the VMA.
153 */
154 ResultVal<VMAHandle> MapBackingMemory(VAddr target, u8* memory, u32 size, MemoryState state);
155
156 /**
157 * Maps a memory-mapped IO region at a given address.
158 *
159 * @param target The guest address to start the mapping at.
160 * @param paddr The physical address where the registers are present.
161 * @param size Size of the mapping.
162 * @param state MemoryState tag to attach to the VMA.
163 */
164 ResultVal<VMAHandle> MapMMIO(VAddr target, PAddr paddr, u32 size, MemoryState state);
165
166 /// Unmaps the given VMA.
167 void Unmap(VMAHandle vma);
168
169 /// Changes the permissions of the given VMA.
170 void Reprotect(VMAHandle vma, VMAPermission new_perms);
171
172private:
173 using VMAIter = decltype(vma_map)::iterator;
174
175 /// Converts a VMAHandle to a mutable VMAIter.
176 VMAIter StripIterConstness(const VMAHandle& iter);
177
178 /**
179 * Carves a VMA of a specific size at the specified address by splitting Free VMAs while doing
180 * the appropriate error checking.
181 */
182 ResultVal<VMAIter> CarveVMA(VAddr base, u32 size);
183
184 /**
185 * Splits a VMA in two, at the specified offset.
186 * @returns the right side of the split, with the original iterator becoming the left side.
187 */
188 VMAIter SplitVMA(VMAIter vma, u32 offset_in_vma);
189
190 /**
191 * Checks for and merges the specified VMA with adjacent ones if possible.
192 * @returns the merged VMA or the original if no merging was possible.
193 */
194 VMAIter MergeAdjacent(VMAIter vma);
195
196 /// Updates the pages corresponding to this VMA so they match the VMA's attributes.
197 void UpdatePageTableForVMA(const VirtualMemoryArea& vma);
198};
199
200}
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
new file mode 100644
index 000000000..57dc1ece7
--- /dev/null
+++ b/src/core/hle/service/am/am.cpp
@@ -0,0 +1,55 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/logging/log.h"
6
7#include "core/hle/service/service.h"
8#include "core/hle/service/am/am_app.h"
9#include "core/hle/service/am/am_net.h"
10#include "core/hle/service/am/am_sys.h"
11
12#include "core/hle/hle.h"
13#include "core/hle/kernel/event.h"
14#include "core/hle/kernel/shared_memory.h"
15
16namespace Service {
17namespace AM {
18
19void TitleIDListGetTotal(Service::Interface* self) {
20 u32* cmd_buff = Kernel::GetCommandBuffer();
21 u32 media_type = cmd_buff[1] & 0xFF;
22
23 cmd_buff[1] = RESULT_SUCCESS.raw;
24 cmd_buff[2] = 0;
25
26 LOG_WARNING(Service_AM, "(STUBBED) media_type %u", media_type);
27}
28
29void GetTitleIDList(Service::Interface* self) {
30 u32* cmd_buff = Kernel::GetCommandBuffer();
31 u32 num_titles = cmd_buff[1];
32 u32 media_type = cmd_buff[2] & 0xFF;
33 u32 addr = cmd_buff[4];
34
35 cmd_buff[1] = RESULT_SUCCESS.raw;
36 cmd_buff[2] = 0;
37
38 LOG_WARNING(Service_AM, "(STUBBED) Requested %u titles from media type %u", num_titles, media_type);
39}
40
41void Init() {
42 using namespace Kernel;
43
44 AddService(new AM_APP_Interface);
45 AddService(new AM_NET_Interface);
46 AddService(new AM_SYS_Interface);
47}
48
49void Shutdown() {
50
51}
52
53} // namespace AM
54
55} // namespace Service
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h
new file mode 100644
index 000000000..063b8bd09
--- /dev/null
+++ b/src/core/hle/service/am/am.h
@@ -0,0 +1,47 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/hle/kernel/kernel.h"
8#include "core/hle/service/service.h"
9
10namespace Service {
11namespace AM {
12
13/**
14 * AM::TitleIDListGetTotal service function
15 * Gets the number of installed titles in the requested media type
16 * Inputs:
17 * 0 : Command header (0x00010040)
18 * 1 : Media type to load the titles from
19 * Outputs:
20 * 1 : Result, 0 on success, otherwise error code
21 * 2 : The number of titles in the requested media type
22 */
23void TitleIDListGetTotal(Service::Interface* self);
24
25/**
26 * AM::GetTitleIDList service function
27 * Loads information about the desired number of titles from the desired media type into an array
28 * Inputs:
29 * 0 : Command header (0x00020082)
30 * 1 : The maximum number of titles to load
31 * 2 : Media type to load the titles from
32 * 3 : Descriptor of the output buffer pointer
33 * 4 : Address of the output buffer
34 * Outputs:
35 * 1 : Result, 0 on success, otherwise error code
36 * 2 : The number of titles loaded from the requested media type
37 */
38void GetTitleIDList(Service::Interface* self);
39
40/// Initialize AM service
41void Init();
42
43/// Shutdown AM service
44void Shutdown();
45
46} // namespace AM
47} // namespace Service
diff --git a/src/core/hle/service/am/am_app.cpp b/src/core/hle/service/am/am_app.cpp
new file mode 100644
index 000000000..c6fc81bc3
--- /dev/null
+++ b/src/core/hle/service/am/am_app.cpp
@@ -0,0 +1,20 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/hle.h"
6#include "core/hle/service/am/am.h"
7#include "core/hle/service/am/am_app.h"
8
9namespace Service {
10namespace AM {
11
12// Empty arrays are illegal -- commented out until an entry is added.
13//const Interface::FunctionInfo FunctionTable[] = { };
14
15AM_APP_Interface::AM_APP_Interface() {
16 //Register(FunctionTable);
17}
18
19} // namespace AM
20} // namespace Service
diff --git a/src/core/hle/service/am/am_app.h b/src/core/hle/service/am/am_app.h
new file mode 100644
index 000000000..fd6017d14
--- /dev/null
+++ b/src/core/hle/service/am/am_app.h
@@ -0,0 +1,22 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included..
4
5#pragma once
6
7#include "core/hle/service/service.h"
8
9namespace Service {
10namespace AM {
11
12class AM_APP_Interface : public Service::Interface {
13public:
14 AM_APP_Interface();
15
16 std::string GetPortName() const override {
17 return "am:app";
18 }
19};
20
21} // namespace AM
22} // namespace Service
diff --git a/src/core/hle/service/am_net.cpp b/src/core/hle/service/am/am_net.cpp
index ba2a499f1..b1af0e9d8 100644
--- a/src/core/hle/service/am_net.cpp
+++ b/src/core/hle/service/am/am_net.cpp
@@ -3,12 +3,11 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "core/hle/hle.h" 5#include "core/hle/hle.h"
6#include "core/hle/service/am_net.h" 6#include "core/hle/service/am/am.h"
7#include "core/hle/service/am/am_net.h"
7 8
8//////////////////////////////////////////////////////////////////////////////////////////////////// 9namespace Service {
9// Namespace AM_NET 10namespace AM {
10
11namespace AM_NET {
12 11
13const Interface::FunctionInfo FunctionTable[] = { 12const Interface::FunctionInfo FunctionTable[] = {
14 {0x08010000, nullptr, "OpenTicket"}, 13 {0x08010000, nullptr, "OpenTicket"},
@@ -33,11 +32,9 @@ const Interface::FunctionInfo FunctionTable[] = {
33 {0x081B00C2, nullptr, "InstallTitlesFinish"}, 32 {0x081B00C2, nullptr, "InstallTitlesFinish"},
34}; 33};
35 34
36//////////////////////////////////////////////////////////////////////////////////////////////////// 35AM_NET_Interface::AM_NET_Interface() {
37// Interface class
38
39Interface::Interface() {
40 Register(FunctionTable); 36 Register(FunctionTable);
41} 37}
42 38
43} // namespace 39} // namespace AM
40} // namespace Service
diff --git a/src/core/hle/service/am/am_net.h b/src/core/hle/service/am/am_net.h
new file mode 100644
index 000000000..25d2c3f23
--- /dev/null
+++ b/src/core/hle/service/am/am_net.h
@@ -0,0 +1,22 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included..
4
5#pragma once
6
7#include "core/hle/service/service.h"
8
9namespace Service {
10namespace AM {
11
12class AM_NET_Interface : public Service::Interface {
13public:
14 AM_NET_Interface();
15
16 std::string GetPortName() const override {
17 return "am:net";
18 }
19};
20
21} // namespace AM
22} // namespace Service
diff --git a/src/core/hle/service/am/am_sys.cpp b/src/core/hle/service/am/am_sys.cpp
new file mode 100644
index 000000000..864fc14df
--- /dev/null
+++ b/src/core/hle/service/am/am_sys.cpp
@@ -0,0 +1,22 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/hle.h"
6#include "core/hle/service/am/am.h"
7#include "core/hle/service/am/am_sys.h"
8
9namespace Service {
10namespace AM {
11
12const Interface::FunctionInfo FunctionTable[] = {
13 {0x00010040, TitleIDListGetTotal, "TitleIDListGetTotal"},
14 {0x00020082, GetTitleIDList, "GetTitleIDList"},
15};
16
17AM_SYS_Interface::AM_SYS_Interface() {
18 Register(FunctionTable);
19}
20
21} // namespace AM
22} // namespace Service
diff --git a/src/core/hle/service/am/am_sys.h b/src/core/hle/service/am/am_sys.h
new file mode 100644
index 000000000..b114f1d35
--- /dev/null
+++ b/src/core/hle/service/am/am_sys.h
@@ -0,0 +1,22 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included..
4
5#pragma once
6
7#include "core/hle/service/service.h"
8
9namespace Service {
10namespace AM {
11
12class AM_SYS_Interface : public Service::Interface {
13public:
14 AM_SYS_Interface();
15
16 std::string GetPortName() const override {
17 return "am:sys";
18 }
19};
20
21} // namespace AM
22} // namespace Service
diff --git a/src/core/hle/service/am/am_u.cpp b/src/core/hle/service/am/am_u.cpp
new file mode 100644
index 000000000..6bf84b36b
--- /dev/null
+++ b/src/core/hle/service/am/am_u.cpp
@@ -0,0 +1,22 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/hle.h"
6#include "core/hle/service/am/am.h"
7#include "core/hle/service/am/am_u.h"
8
9namespace Service {
10namespace AM {
11
12const Interface::FunctionInfo FunctionTable[] = {
13 {0x00010040, TitleIDListGetTotal, "TitleIDListGetTotal"},
14 {0x00020082, GetTitleIDList, "GetTitleIDList"},
15};
16
17AM_U_Interface::AM_U_Interface() {
18 Register(FunctionTable);
19}
20
21} // namespace AM
22} // namespace Service
diff --git a/src/core/hle/service/am/am_u.h b/src/core/hle/service/am/am_u.h
new file mode 100644
index 000000000..3b2454b6c
--- /dev/null
+++ b/src/core/hle/service/am/am_u.h
@@ -0,0 +1,22 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included..
4
5#pragma once
6
7#include "core/hle/service/service.h"
8
9namespace Service {
10namespace AM {
11
12class AM_U_Interface : public Service::Interface {
13public:
14 AM_U_Interface();
15
16 std::string GetPortName() const override {
17 return "am:u";
18 }
19};
20
21} // namespace AM
22} // namespace Service
diff --git a/src/core/hle/service/am_app.cpp b/src/core/hle/service/am_app.cpp
deleted file mode 100644
index 684b753f0..000000000
--- a/src/core/hle/service/am_app.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/hle.h"
6#include "core/hle/service/am_app.h"
7
8////////////////////////////////////////////////////////////////////////////////////////////////////
9// Namespace AM_APP
10
11namespace AM_APP {
12
13// Empty arrays are illegal -- commented out until an entry is added.
14//const Interface::FunctionInfo FunctionTable[] = { };
15
16////////////////////////////////////////////////////////////////////////////////////////////////////
17// Interface class
18
19Interface::Interface() {
20 //Register(FunctionTable);
21}
22
23} // namespace
diff --git a/src/core/hle/service/am_app.h b/src/core/hle/service/am_app.h
deleted file mode 100644
index 50dc2f5a2..000000000
--- a/src/core/hle/service/am_app.h
+++ /dev/null
@@ -1,23 +0,0 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/hle/service/service.h"
8
9////////////////////////////////////////////////////////////////////////////////////////////////////
10// Namespace AM_APP
11
12namespace AM_APP {
13
14class Interface : public Service::Interface {
15public:
16 Interface();
17
18 std::string GetPortName() const override {
19 return "am:app";
20 }
21};
22
23} // namespace
diff --git a/src/core/hle/service/am_net.h b/src/core/hle/service/am_net.h
deleted file mode 100644
index 616c33ee8..000000000
--- a/src/core/hle/service/am_net.h
+++ /dev/null
@@ -1,23 +0,0 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/hle/service/service.h"
8
9////////////////////////////////////////////////////////////////////////////////////////////////////
10// Namespace AM_NET
11
12namespace AM_NET {
13
14class Interface : public Service::Interface {
15public:
16 Interface();
17
18 std::string GetPortName() const override {
19 return "am:net";
20 }
21};
22
23} // namespace
diff --git a/src/core/hle/service/am_sys.cpp b/src/core/hle/service/am_sys.cpp
deleted file mode 100644
index f9e3fe4b7..000000000
--- a/src/core/hle/service/am_sys.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/logging/log.h"
6
7#include "core/hle/hle.h"
8#include "core/hle/service/am_sys.h"
9
10namespace AM_SYS {
11
12/**
13 * Gets the number of installed titles in the requested media type
14 * Inputs:
15 * 0: Command header (0x00010040)
16 * 1: Media type to load the titles from
17 * Outputs:
18 * 1: Result, 0 on success, otherwise error code
19 * 2: The number of titles in the requested media type
20 */
21static void TitleIDListGetTotal(Service::Interface* self) {
22 u32* cmd_buff = Kernel::GetCommandBuffer();
23 u32 media_type = cmd_buff[1] & 0xFF;
24
25 cmd_buff[1] = RESULT_SUCCESS.raw;
26 cmd_buff[2] = 0;
27 LOG_WARNING(Service_CFG, "(STUBBED) media_type %u", media_type);
28}
29
30/**
31 * Loads information about the desired number of titles from the desired media type into an array
32 * Inputs:
33 * 0: Command header (0x00020082)
34 * 1: The maximum number of titles to load
35 * 2: Media type to load the titles from
36 * 3: Descriptor of the output buffer pointer
37 * 4: Address of the output buffer
38 * Outputs:
39 * 1: Result, 0 on success, otherwise error code
40 * 2: The number of titles loaded from the requested media type
41 */
42static void GetTitleIDList(Service::Interface* self) {
43 u32* cmd_buff = Kernel::GetCommandBuffer();
44 u32 num_titles = cmd_buff[1];
45 u32 media_type = cmd_buff[2] & 0xFF;
46 u32 addr = cmd_buff[4];
47
48 cmd_buff[1] = RESULT_SUCCESS.raw;
49 cmd_buff[2] = 0;
50 LOG_WARNING(Service_CFG, "(STUBBED) Requested %u titles from media type %u", num_titles, media_type);
51}
52
53const Interface::FunctionInfo FunctionTable[] = {
54 {0x00010040, TitleIDListGetTotal, "TitleIDListGetTotal"},
55 {0x00020082, GetTitleIDList, "GetTitleIDList"},
56};
57
58Interface::Interface() {
59 Register(FunctionTable);
60}
61
62} // namespace
diff --git a/src/core/hle/service/am_sys.h b/src/core/hle/service/am_sys.h
deleted file mode 100644
index bb6178a43..000000000
--- a/src/core/hle/service/am_sys.h
+++ /dev/null
@@ -1,23 +0,0 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/hle/service/service.h"
8
9////////////////////////////////////////////////////////////////////////////////////////////////////
10// Namespace AM_SYS
11
12namespace AM_SYS {
13
14class Interface : public Service::Interface {
15public:
16 Interface();
17
18 std::string GetPortName() const override {
19 return "am:sys";
20 }
21};
22
23} // namespace
diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp
index 3fd4cfb08..5d14f393d 100644
--- a/src/core/hle/service/apt/apt.cpp
+++ b/src/core/hle/service/apt/apt.cpp
@@ -151,7 +151,7 @@ void SendParameter(Service::Interface* self) {
151 u32 handle = cmd_buff[6]; 151 u32 handle = cmd_buff[6];
152 u32 size = cmd_buff[7]; 152 u32 size = cmd_buff[7];
153 u32 in_param_buffer_ptr = cmd_buff[8]; 153 u32 in_param_buffer_ptr = cmd_buff[8];
154 154
155 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 155 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
156 156
157 LOG_WARNING(Service_APT, "(STUBBED) called src_app_id=0x%08X, dst_app_id=0x%08X, signal_type=0x%08X," 157 LOG_WARNING(Service_APT, "(STUBBED) called src_app_id=0x%08X, dst_app_id=0x%08X, signal_type=0x%08X,"
@@ -283,7 +283,7 @@ void Init() {
283 AddService(new APT_A_Interface); 283 AddService(new APT_A_Interface);
284 AddService(new APT_S_Interface); 284 AddService(new APT_S_Interface);
285 AddService(new APT_U_Interface); 285 AddService(new APT_U_Interface);
286 286
287 // Load the shared system font (if available). 287 // Load the shared system font (if available).
288 // The expected format is a decrypted, uncompressed BCFNT file with the 0x80 byte header 288 // The expected format is a decrypted, uncompressed BCFNT file with the 0x80 byte header
289 // generated by the APT:U service. The best way to get is by dumping it from RAM. We've provided 289 // generated by the APT:U service. The best way to get is by dumping it from RAM. We've provided
diff --git a/src/core/hle/service/apt/apt.h b/src/core/hle/service/apt/apt.h
index e7fa39325..a03e1712a 100644
--- a/src/core/hle/service/apt/apt.h
+++ b/src/core/hle/service/apt/apt.h
@@ -63,7 +63,7 @@ void Initialize(Service::Interface* self);
63 * 4 : Handle to shared font memory 63 * 4 : Handle to shared font memory
64 */ 64 */
65void GetSharedFont(Service::Interface* self); 65void GetSharedFont(Service::Interface* self);
66 66
67/** 67/**
68 * APT::NotifyToWait service function 68 * APT::NotifyToWait service function
69 * Inputs: 69 * Inputs:
@@ -88,7 +88,7 @@ void Enable(Service::Interface* self);
88 * 4 : Home Menu AppId 88 * 4 : Home Menu AppId
89 * 5 : AppID of currently active app 89 * 5 : AppID of currently active app
90 */ 90 */
91void GetAppletManInfo(Service::Interface* self); 91void GetAppletManInfo(Service::Interface* self);
92 92
93/** 93/**
94 * APT::IsRegistered service function. This returns whether the specified AppID is registered with NS yet. 94 * APT::IsRegistered service function. This returns whether the specified AppID is registered with NS yet.
@@ -100,14 +100,14 @@ void GetAppletManInfo(Service::Interface* self);
100 * Outputs: 100 * Outputs:
101 * 0 : Return header 101 * 0 : Return header
102 * 1 : Result of function, 0 on success, otherwise error code 102 * 1 : Result of function, 0 on success, otherwise error code
103 * 2 : Output, 0 = not registered, 1 = registered. 103 * 2 : Output, 0 = not registered, 1 = registered.
104 */ 104 */
105void IsRegistered(Service::Interface* self); 105void IsRegistered(Service::Interface* self);
106 106
107void InquireNotification(Service::Interface* self); 107void InquireNotification(Service::Interface* self);
108 108
109/** 109/**
110 * APT::SendParameter service function. This sets the parameter data state. 110 * APT::SendParameter service function. This sets the parameter data state.
111 * Inputs: 111 * Inputs:
112 * 1 : Source AppID 112 * 1 : Source AppID
113 * 2 : Destination AppID 113 * 2 : Destination AppID
diff --git a/src/core/hle/service/boss/boss.cpp b/src/core/hle/service/boss/boss.cpp
new file mode 100644
index 000000000..d38140f19
--- /dev/null
+++ b/src/core/hle/service/boss/boss.cpp
@@ -0,0 +1,29 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/service/service.h"
6#include "core/hle/service/boss/boss.h"
7#include "core/hle/service/boss/boss_p.h"
8#include "core/hle/service/boss/boss_u.h"
9
10#include "core/hle/kernel/event.h"
11#include "core/hle/kernel/shared_memory.h"
12#include "core/hle/hle.h"
13
14namespace Service {
15namespace BOSS {
16
17void Init() {
18 using namespace Kernel;
19
20 AddService(new BOSS_P_Interface);
21 AddService(new BOSS_U_Interface);
22}
23
24void Shutdown() {
25}
26
27} // namespace BOSS
28
29} // namespace Service
diff --git a/src/core/hle/service/boss/boss.h b/src/core/hle/service/boss/boss.h
new file mode 100644
index 000000000..a6942ada6
--- /dev/null
+++ b/src/core/hle/service/boss/boss.h
@@ -0,0 +1,20 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/hle/kernel/kernel.h"
8#include "core/hle/service/service.h"
9
10namespace Service {
11namespace BOSS {
12
13/// Initialize BOSS service(s)
14void Init();
15
16/// Shutdown BOSS service(s)
17void Shutdown();
18
19} // namespace BOSS
20} // namespace Service
diff --git a/src/core/hle/service/boss/boss_p.cpp b/src/core/hle/service/boss/boss_p.cpp
new file mode 100644
index 000000000..089f5f186
--- /dev/null
+++ b/src/core/hle/service/boss/boss_p.cpp
@@ -0,0 +1,20 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/hle.h"
6#include "core/hle/service/boss/boss.h"
7#include "core/hle/service/boss/boss_p.h"
8
9namespace Service {
10namespace BOSS {
11
12// Empty arrays are illegal -- commented out until an entry is added.
13// const Interface::FunctionInfo FunctionTable[] = { };
14
15BOSS_P_Interface::BOSS_P_Interface() {
16 //Register(FunctionTable);
17}
18
19} // namespace BOSS
20} // namespace Service
diff --git a/src/core/hle/service/boss/boss_p.h b/src/core/hle/service/boss/boss_p.h
new file mode 100644
index 000000000..32112c251
--- /dev/null
+++ b/src/core/hle/service/boss/boss_p.h
@@ -0,0 +1,22 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included..
4
5#pragma once
6
7#include "core/hle/service/service.h"
8
9namespace Service {
10namespace BOSS {
11
12class BOSS_P_Interface : public Service::Interface {
13public:
14 BOSS_P_Interface();
15
16 std::string GetPortName() const override {
17 return "boss:P";
18 }
19};
20
21} // namespace BOSS
22} // namespace Service
diff --git a/src/core/hle/service/boss/boss_u.cpp b/src/core/hle/service/boss/boss_u.cpp
new file mode 100644
index 000000000..ed978b963
--- /dev/null
+++ b/src/core/hle/service/boss/boss_u.cpp
@@ -0,0 +1,21 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/hle.h"
6#include "core/hle/service/boss/boss.h"
7#include "core/hle/service/boss/boss_u.h"
8
9namespace Service {
10namespace BOSS {
11
12const Interface::FunctionInfo FunctionTable[] = {
13 {0x00020100, nullptr, "GetStorageInfo"},
14};
15
16BOSS_U_Interface::BOSS_U_Interface() {
17 Register(FunctionTable);
18}
19
20} // namespace BOSS
21} // namespace Service
diff --git a/src/core/hle/service/boss/boss_u.h b/src/core/hle/service/boss/boss_u.h
new file mode 100644
index 000000000..d047d8cf2
--- /dev/null
+++ b/src/core/hle/service/boss/boss_u.h
@@ -0,0 +1,22 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included..
4
5#pragma once
6
7#include "core/hle/service/service.h"
8
9namespace Service {
10namespace BOSS {
11
12class BOSS_U_Interface : public Service::Interface {
13public:
14 BOSS_U_Interface();
15
16 std::string GetPortName() const override {
17 return "boss:U";
18 }
19};
20
21} // namespace BOSS
22} // namespace Service
diff --git a/src/core/hle/service/boss_p.cpp b/src/core/hle/service/boss_p.cpp
deleted file mode 100644
index 8280830e5..000000000
--- a/src/core/hle/service/boss_p.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/hle.h"
6#include "core/hle/service/boss_p.h"
7
8////////////////////////////////////////////////////////////////////////////////////////////////////
9// Namespace BOSS_P
10
11namespace BOSS_P {
12
13// Empty arrays are illegal -- commented out until an entry is added.
14// const Interface::FunctionInfo FunctionTable[] = { };
15
16////////////////////////////////////////////////////////////////////////////////////////////////////
17// Interface class
18
19Interface::Interface() {
20 //Register(FunctionTable);
21}
22
23} // namespace
diff --git a/src/core/hle/service/boss_p.h b/src/core/hle/service/boss_p.h
deleted file mode 100644
index 71f1e7464..000000000
--- a/src/core/hle/service/boss_p.h
+++ /dev/null
@@ -1,23 +0,0 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/hle/service/service.h"
8
9////////////////////////////////////////////////////////////////////////////////////////////////////
10// Namespace BOSS_P
11
12namespace BOSS_P {
13
14class Interface : public Service::Interface {
15public:
16 Interface();
17
18 std::string GetPortName() const override {
19 return "boss:P";
20 }
21};
22
23} // namespace
diff --git a/src/core/hle/service/boss_u.cpp b/src/core/hle/service/boss_u.cpp
deleted file mode 100644
index 2c322bdfd..000000000
--- a/src/core/hle/service/boss_u.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/hle.h"
6#include "core/hle/service/boss_u.h"
7
8////////////////////////////////////////////////////////////////////////////////////////////////////
9// Namespace BOSS_U
10
11namespace BOSS_U {
12
13const Interface::FunctionInfo FunctionTable[] = {
14 {0x00020100, nullptr, "GetStorageInfo"},
15};
16
17////////////////////////////////////////////////////////////////////////////////////////////////////
18// Interface class
19
20Interface::Interface() {
21 Register(FunctionTable);
22}
23
24} // namespace
diff --git a/src/core/hle/service/boss_u.h b/src/core/hle/service/boss_u.h
deleted file mode 100644
index 2668f2dfd..000000000
--- a/src/core/hle/service/boss_u.h
+++ /dev/null
@@ -1,23 +0,0 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/hle/service/service.h"
8
9////////////////////////////////////////////////////////////////////////////////////////////////////
10// Namespace BOSS_U
11
12namespace BOSS_U {
13
14class Interface : public Service::Interface {
15public:
16 Interface();
17
18 std::string GetPortName() const override {
19 return "boss:U";
20 }
21};
22
23} // namespace
diff --git a/src/core/hle/service/cam/cam.cpp b/src/core/hle/service/cam/cam.cpp
new file mode 100644
index 000000000..4f34b699b
--- /dev/null
+++ b/src/core/hle/service/cam/cam.cpp
@@ -0,0 +1,35 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/logging/log.h"
6
7#include "core/hle/service/service.h"
8#include "core/hle/service/cam/cam.h"
9#include "core/hle/service/cam/cam_c.h"
10#include "core/hle/service/cam/cam_q.h"
11#include "core/hle/service/cam/cam_s.h"
12#include "core/hle/service/cam/cam_u.h"
13
14#include "core/hle/kernel/event.h"
15#include "core/hle/kernel/shared_memory.h"
16#include "core/hle/hle.h"
17
18namespace Service {
19namespace CAM {
20
21void Init() {
22 using namespace Kernel;
23
24 AddService(new CAM_C_Interface);
25 AddService(new CAM_Q_Interface);
26 AddService(new CAM_S_Interface);
27 AddService(new CAM_U_Interface);
28}
29
30void Shutdown() {
31}
32
33} // namespace CAM
34
35} // namespace Service
diff --git a/src/core/hle/service/cam/cam.h b/src/core/hle/service/cam/cam.h
new file mode 100644
index 000000000..edd524841
--- /dev/null
+++ b/src/core/hle/service/cam/cam.h
@@ -0,0 +1,20 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/hle/kernel/kernel.h"
8#include "core/hle/service/service.h"
9
10namespace Service {
11namespace CAM {
12
13/// Initialize CAM service(s)
14void Init();
15
16/// Shutdown CAM service(s)
17void Shutdown();
18
19} // namespace CAM
20} // namespace Service
diff --git a/src/core/hle/service/cam/cam_c.cpp b/src/core/hle/service/cam/cam_c.cpp
new file mode 100644
index 000000000..d35adcb9f
--- /dev/null
+++ b/src/core/hle/service/cam/cam_c.cpp
@@ -0,0 +1,20 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/hle.h"
6#include "core/hle/service/cam/cam.h"
7#include "core/hle/service/cam/cam_c.h"
8
9namespace Service {
10namespace CAM {
11
12// Empty arrays are illegal -- commented out until an entry is added.
13//const Interface::FunctionInfo FunctionTable[] = { };
14
15CAM_C_Interface::CAM_C_Interface() {
16 //Register(FunctionTable);
17}
18
19} // namespace CAM
20} // namespace Service
diff --git a/src/core/hle/service/cam/cam_c.h b/src/core/hle/service/cam/cam_c.h
new file mode 100644
index 000000000..6b296c00d
--- /dev/null
+++ b/src/core/hle/service/cam/cam_c.h
@@ -0,0 +1,22 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included..
4
5#pragma once
6
7#include "core/hle/service/service.h"
8
9namespace Service {
10namespace CAM {
11
12class CAM_C_Interface : public Service::Interface {
13public:
14 CAM_C_Interface();
15
16 std::string GetPortName() const override {
17 return "cam:c";
18 }
19};
20
21} // namespace CAM
22} // namespace Service
diff --git a/src/core/hle/service/cam/cam_q.cpp b/src/core/hle/service/cam/cam_q.cpp
new file mode 100644
index 000000000..c2760a102
--- /dev/null
+++ b/src/core/hle/service/cam/cam_q.cpp
@@ -0,0 +1,20 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/hle.h"
6#include "core/hle/service/cam/cam.h"
7#include "core/hle/service/cam/cam_q.h"
8
9namespace Service {
10namespace CAM {
11
12// Empty arrays are illegal -- commented out until an entry is added.
13//const Interface::FunctionInfo FunctionTable[] = { };
14
15CAM_Q_Interface::CAM_Q_Interface() {
16 //Register(FunctionTable);
17}
18
19} // namespace CAM
20} // namespace Service
diff --git a/src/core/hle/service/cam/cam_q.h b/src/core/hle/service/cam/cam_q.h
new file mode 100644
index 000000000..07cc12534
--- /dev/null
+++ b/src/core/hle/service/cam/cam_q.h
@@ -0,0 +1,22 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included..
4
5#pragma once
6
7#include "core/hle/service/service.h"
8
9namespace Service {
10namespace CAM {
11
12class CAM_Q_Interface : public Service::Interface {
13public:
14 CAM_Q_Interface();
15
16 std::string GetPortName() const override {
17 return "cam:q";
18 }
19};
20
21} // namespace CAM
22} // namespace Service
diff --git a/src/core/hle/service/cam/cam_s.cpp b/src/core/hle/service/cam/cam_s.cpp
new file mode 100644
index 000000000..aefbf7df4
--- /dev/null
+++ b/src/core/hle/service/cam/cam_s.cpp
@@ -0,0 +1,20 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/hle.h"
6#include "core/hle/service/cam/cam.h"
7#include "core/hle/service/cam/cam_s.h"
8
9namespace Service {
10namespace CAM {
11
12// Empty arrays are illegal -- commented out until an entry is added.
13//const Interface::FunctionInfo FunctionTable[] = { };
14
15CAM_S_Interface::CAM_S_Interface() {
16 //Register(FunctionTable);
17}
18
19} // namespace CAM
20} // namespace Service
diff --git a/src/core/hle/service/cam/cam_s.h b/src/core/hle/service/cam/cam_s.h
new file mode 100644
index 000000000..0a5d6fca2
--- /dev/null
+++ b/src/core/hle/service/cam/cam_s.h
@@ -0,0 +1,22 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included..
4
5#pragma once
6
7#include "core/hle/service/service.h"
8
9namespace Service {
10namespace CAM {
11
12class CAM_S_Interface : public Service::Interface {
13public:
14 CAM_S_Interface();
15
16 std::string GetPortName() const override {
17 return "cam:s";
18 }
19};
20
21} // namespace CAM
22} // namespace Service
diff --git a/src/core/hle/service/cam/cam_u.cpp b/src/core/hle/service/cam/cam_u.cpp
new file mode 100644
index 000000000..1c6aca955
--- /dev/null
+++ b/src/core/hle/service/cam/cam_u.cpp
@@ -0,0 +1,20 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/hle.h"
6#include "core/hle/service/cam/cam.h"
7#include "core/hle/service/cam/cam_u.h"
8
9namespace Service {
10namespace CAM {
11
12// Empty arrays are illegal -- commented out until an entry is added.
13//const Interface::FunctionInfo FunctionTable[] = { };
14
15CAM_U_Interface::CAM_U_Interface() {
16 //Register(FunctionTable);
17}
18
19} // namespace CAM
20} // namespace Service
diff --git a/src/core/hle/service/cam/cam_u.h b/src/core/hle/service/cam/cam_u.h
new file mode 100644
index 000000000..369264037
--- /dev/null
+++ b/src/core/hle/service/cam/cam_u.h
@@ -0,0 +1,22 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included..
4
5#pragma once
6
7#include "core/hle/service/service.h"
8
9namespace Service {
10namespace CAM {
11
12class CAM_U_Interface : public Service::Interface {
13public:
14 CAM_U_Interface();
15
16 std::string GetPortName() const override {
17 return "cam:u";
18 }
19};
20
21} // namespace CAM
22} // namespace Service
diff --git a/src/core/hle/service/cam_u.cpp b/src/core/hle/service/cam_u.cpp
deleted file mode 100644
index fcfd87715..000000000
--- a/src/core/hle/service/cam_u.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/hle.h"
6#include "core/hle/service/cam_u.h"
7
8////////////////////////////////////////////////////////////////////////////////////////////////////
9// Namespace CAM_U
10
11namespace CAM_U {
12
13// Empty arrays are illegal -- commented out until an entry is added.
14//const Interface::FunctionInfo FunctionTable[] = { };
15
16////////////////////////////////////////////////////////////////////////////////////////////////////
17// Interface class
18
19Interface::Interface() {
20 //Register(FunctionTable);
21}
22
23} // namespace
diff --git a/src/core/hle/service/cam_u.h b/src/core/hle/service/cam_u.h
deleted file mode 100644
index 878c20a84..000000000
--- a/src/core/hle/service/cam_u.h
+++ /dev/null
@@ -1,23 +0,0 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/hle/service/service.h"
8
9////////////////////////////////////////////////////////////////////////////////////////////////////
10// Namespace CAM_U
11
12namespace CAM_U {
13
14class Interface : public Service::Interface {
15public:
16 Interface();
17
18 std::string GetPortName() const override {
19 return "cam:u";
20 }
21};
22
23} // namespace
diff --git a/src/core/hle/service/cecd/cecd.cpp b/src/core/hle/service/cecd/cecd.cpp
new file mode 100644
index 000000000..db0e52b79
--- /dev/null
+++ b/src/core/hle/service/cecd/cecd.cpp
@@ -0,0 +1,31 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/logging/log.h"
6
7#include "core/hle/service/service.h"
8#include "core/hle/service/cecd/cecd.h"
9#include "core/hle/service/cecd/cecd_s.h"
10#include "core/hle/service/cecd/cecd_u.h"
11
12#include "core/hle/kernel/event.h"
13#include "core/hle/kernel/shared_memory.h"
14#include "core/hle/hle.h"
15
16namespace Service {
17namespace CECD {
18
19void Init() {
20 using namespace Kernel;
21
22 AddService(new CECD_S_Interface);
23 AddService(new CECD_U_Interface);
24}
25
26void Shutdown() {
27}
28
29} // namespace CECD
30
31} // namespace Service
diff --git a/src/core/hle/service/cecd/cecd.h b/src/core/hle/service/cecd/cecd.h
new file mode 100644
index 000000000..32fd2045d
--- /dev/null
+++ b/src/core/hle/service/cecd/cecd.h
@@ -0,0 +1,20 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/hle/kernel/kernel.h"
8#include "core/hle/service/service.h"
9
10namespace Service {
11namespace CECD {
12
13/// Initialize CECD service(s)
14void Init();
15
16/// Shutdown CECD service(s)
17void Shutdown();
18
19} // namespace CECD
20} // namespace Service
diff --git a/src/core/hle/service/cecd/cecd_s.cpp b/src/core/hle/service/cecd/cecd_s.cpp
new file mode 100644
index 000000000..72d7e8d44
--- /dev/null
+++ b/src/core/hle/service/cecd/cecd_s.cpp
@@ -0,0 +1,20 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/hle.h"
6#include "core/hle/service/cecd/cecd.h"
7#include "core/hle/service/cecd/cecd_s.h"
8
9namespace Service {
10namespace CECD {
11
12// Empty arrays are illegal -- commented out until an entry is added.
13//const Interface::FunctionInfo FunctionTable[] = { };
14
15CECD_S_Interface::CECD_S_Interface() {
16 //Register(FunctionTable);
17}
18
19} // namespace CECD
20} // namespace Service
diff --git a/src/core/hle/service/cecd_s.h b/src/core/hle/service/cecd/cecd_s.h
index d880d0391..df5c01849 100644
--- a/src/core/hle/service/cecd_s.h
+++ b/src/core/hle/service/cecd/cecd_s.h
@@ -6,18 +6,17 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9//////////////////////////////////////////////////////////////////////////////////////////////////// 9namespace Service {
10// Namespace CECD_S 10namespace CECD {
11 11
12namespace CECD_S { 12class CECD_S_Interface : public Interface {
13
14class Interface : public Service::Interface {
15public: 13public:
16 Interface(); 14 CECD_S_Interface();
17 15
18 std::string GetPortName() const override { 16 std::string GetPortName() const override {
19 return "cecd:s"; 17 return "cecd:s";
20 } 18 }
21}; 19};
22 20
23} // namespace 21} // namespace CECD
22} // namespace Service
diff --git a/src/core/hle/service/cecd/cecd_u.cpp b/src/core/hle/service/cecd/cecd_u.cpp
new file mode 100644
index 000000000..0a23bafbc
--- /dev/null
+++ b/src/core/hle/service/cecd/cecd_u.cpp
@@ -0,0 +1,20 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/hle.h"
6#include "core/hle/service/cecd/cecd.h"
7#include "core/hle/service/cecd/cecd_u.h"
8
9namespace Service {
10namespace CECD {
11
12// Empty arrays are illegal -- commented out until an entry is added.
13//const Interface::FunctionInfo FunctionTable[] = { };
14
15CECD_U_Interface::CECD_U_Interface() {
16 //Register(FunctionTable);
17}
18
19} // namespace CECD
20} // namespace Service
diff --git a/src/core/hle/service/cecd_u.h b/src/core/hle/service/cecd/cecd_u.h
index e67564135..394030ffc 100644
--- a/src/core/hle/service/cecd_u.h
+++ b/src/core/hle/service/cecd/cecd_u.h
@@ -6,18 +6,17 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9//////////////////////////////////////////////////////////////////////////////////////////////////// 9namespace Service {
10// Namespace CECD_U 10namespace CECD {
11 11
12namespace CECD_U { 12class CECD_U_Interface : public Interface {
13
14class Interface : public Service::Interface {
15public: 13public:
16 Interface(); 14 CECD_U_Interface();
17 15
18 std::string GetPortName() const override { 16 std::string GetPortName() const override {
19 return "cecd:u"; 17 return "cecd:u";
20 } 18 }
21}; 19};
22 20
23} // namespace 21} // namespace CECD
22} // namespace Service
diff --git a/src/core/hle/service/cecd_s.cpp b/src/core/hle/service/cecd_s.cpp
deleted file mode 100644
index b298f151d..000000000
--- a/src/core/hle/service/cecd_s.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/hle.h"
6#include "core/hle/service/cecd_s.h"
7
8////////////////////////////////////////////////////////////////////////////////////////////////////
9// Namespace CECD_S
10
11namespace CECD_S {
12
13// Empty arrays are illegal -- commented out until an entry is added.
14//const Interface::FunctionInfo FunctionTable[] = { };
15
16////////////////////////////////////////////////////////////////////////////////////////////////////
17// Interface class
18
19Interface::Interface() {
20 //Register(FunctionTable);
21}
22
23} // namespace
diff --git a/src/core/hle/service/cecd_u.cpp b/src/core/hle/service/cecd_u.cpp
deleted file mode 100644
index 9125364bc..000000000
--- a/src/core/hle/service/cecd_u.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/hle.h"
6#include "core/hle/service/cecd_u.h"
7
8////////////////////////////////////////////////////////////////////////////////////////////////////
9// Namespace CECD_U
10
11namespace CECD_U {
12
13// Empty arrays are illegal -- commented out until an entry is added.
14//const Interface::FunctionInfo FunctionTable[] = { };
15
16////////////////////////////////////////////////////////////////////////////////////////////////////
17// Interface class
18
19Interface::Interface() {
20 //Register(FunctionTable);
21}
22
23} // namespace
diff --git a/src/core/hle/service/cfg/cfg.cpp b/src/core/hle/service/cfg/cfg.cpp
index d42682883..62ad90fdc 100644
--- a/src/core/hle/service/cfg/cfg.cpp
+++ b/src/core/hle/service/cfg/cfg.cpp
@@ -315,11 +315,11 @@ void Init() {
315 AddService(new CFG_I_Interface); 315 AddService(new CFG_I_Interface);
316 AddService(new CFG_S_Interface); 316 AddService(new CFG_S_Interface);
317 AddService(new CFG_U_Interface); 317 AddService(new CFG_U_Interface);
318 318
319 // Open the SystemSaveData archive 0x00010017 319 // Open the SystemSaveData archive 0x00010017
320 FileSys::Path archive_path(cfg_system_savedata_id); 320 FileSys::Path archive_path(cfg_system_savedata_id);
321 auto archive_result = Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SystemSaveData, archive_path); 321 auto archive_result = Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SystemSaveData, archive_path);
322 322
323 // If the archive didn't exist, create the files inside 323 // If the archive didn't exist, create the files inside
324 if (archive_result.Code().description == ErrorDescription::FS_NotFormatted) { 324 if (archive_result.Code().description == ErrorDescription::FS_NotFormatted) {
325 // Format the archive to create the directories 325 // Format the archive to create the directories
diff --git a/src/core/hle/service/frd/frd.cpp b/src/core/hle/service/frd/frd.cpp
new file mode 100644
index 000000000..2911ab402
--- /dev/null
+++ b/src/core/hle/service/frd/frd.cpp
@@ -0,0 +1,29 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/service/service.h"
6#include "core/hle/service/frd/frd.h"
7#include "core/hle/service/frd/frd_a.h"
8#include "core/hle/service/frd/frd_u.h"
9
10#include "core/hle/kernel/event.h"
11#include "core/hle/kernel/shared_memory.h"
12#include "core/hle/hle.h"
13
14namespace Service {
15namespace FRD {
16
17void Init() {
18 using namespace Kernel;
19
20 AddService(new FRD_A_Interface);
21 AddService(new FRD_U_Interface);
22}
23
24void Shutdown() {
25}
26
27} // namespace FRD
28
29} // namespace Service
diff --git a/src/core/hle/service/frd/frd.h b/src/core/hle/service/frd/frd.h
new file mode 100644
index 000000000..41f7a2f6b
--- /dev/null
+++ b/src/core/hle/service/frd/frd.h
@@ -0,0 +1,20 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/hle/kernel/kernel.h"
8#include "core/hle/service/service.h"
9
10namespace Service {
11namespace FRD {
12
13/// Initialize FRD service(s)
14void Init();
15
16/// Shutdown FRD service(s)
17void Shutdown();
18
19} // namespace FRD
20} // namespace Service
diff --git a/src/core/hle/service/frd/frd_a.cpp b/src/core/hle/service/frd/frd_a.cpp
new file mode 100644
index 000000000..1c438a337
--- /dev/null
+++ b/src/core/hle/service/frd/frd_a.cpp
@@ -0,0 +1,20 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/hle.h"
6#include "core/hle/service/frd/frd.h"
7#include "core/hle/service/frd/frd_a.h"
8
9namespace Service {
10namespace FRD {
11
12// Empty arrays are illegal -- commented out until an entry is added.
13// const Interface::FunctionInfo FunctionTable[] = { };
14
15FRD_A_Interface::FRD_A_Interface() {
16 //Register(FunctionTable);
17}
18
19} // namespace FRD
20} // namespace Service
diff --git a/src/core/hle/service/frd_a.h b/src/core/hle/service/frd/frd_a.h
index f068c6108..006d1cadd 100644
--- a/src/core/hle/service/frd_a.h
+++ b/src/core/hle/service/frd/frd_a.h
@@ -6,18 +6,17 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9//////////////////////////////////////////////////////////////////////////////////////////////////// 9namespace Service {
10// Namespace FRD_A 10namespace FRD {
11 11
12namespace FRD_A { 12class FRD_A_Interface : public Service::Interface {
13
14class Interface : public Service::Interface {
15public: 13public:
16 Interface(); 14 FRD_A_Interface();
17 15
18 std::string GetPortName() const override { 16 std::string GetPortName() const override {
19 return "frd:a"; 17 return "frd:a";
20 } 18 }
21}; 19};
22 20
23} // namespace 21} // namespace FRD
22} // namespace Service
diff --git a/src/core/hle/service/frd_u.cpp b/src/core/hle/service/frd/frd_u.cpp
index 6d2ff1e21..439c7282e 100644
--- a/src/core/hle/service/frd_u.cpp
+++ b/src/core/hle/service/frd/frd_u.cpp
@@ -3,12 +3,11 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "core/hle/hle.h" 5#include "core/hle/hle.h"
6#include "core/hle/service/frd_u.h" 6#include "core/hle/service/frd/frd.h"
7#include "core/hle/service/frd/frd_u.h"
7 8
8//////////////////////////////////////////////////////////////////////////////////////////////////// 9namespace Service {
9// Namespace FRD_U 10namespace FRD {
10
11namespace FRD_U {
12 11
13const Interface::FunctionInfo FunctionTable[] = { 12const Interface::FunctionInfo FunctionTable[] = {
14 {0x00050000, nullptr, "GetFriendKey"}, 13 {0x00050000, nullptr, "GetFriendKey"},
@@ -22,11 +21,9 @@ const Interface::FunctionInfo FunctionTable[] = {
22 {0x00320042, nullptr, "SetClientSdkVersion"} 21 {0x00320042, nullptr, "SetClientSdkVersion"}
23}; 22};
24 23
25//////////////////////////////////////////////////////////////////////////////////////////////////// 24FRD_U_Interface::FRD_U_Interface() {
26// Interface class
27
28Interface::Interface() {
29 Register(FunctionTable); 25 Register(FunctionTable);
30} 26}
31 27
32} // namespace 28} // namespace FRD
29} // namespace Service
diff --git a/src/core/hle/service/frd_u.h b/src/core/hle/service/frd/frd_u.h
index ab8897d5b..07e43f155 100644
--- a/src/core/hle/service/frd_u.h
+++ b/src/core/hle/service/frd/frd_u.h
@@ -6,18 +6,17 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9//////////////////////////////////////////////////////////////////////////////////////////////////// 9namespace Service {
10// Namespace FRD_U 10namespace FRD {
11 11
12namespace FRD_U { 12class FRD_U_Interface : public Service::Interface {
13
14class Interface : public Service::Interface {
15public: 13public:
16 Interface(); 14 FRD_U_Interface();
17 15
18 std::string GetPortName() const override { 16 std::string GetPortName() const override {
19 return "frd:u"; 17 return "frd:u";
20 } 18 }
21}; 19};
22 20
23} // namespace 21} // namespace FRD
22} // namespace Service
diff --git a/src/core/hle/service/frd_a.cpp b/src/core/hle/service/frd_a.cpp
deleted file mode 100644
index 569979319..000000000
--- a/src/core/hle/service/frd_a.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/hle.h"
6#include "core/hle/service/frd_a.h"
7
8////////////////////////////////////////////////////////////////////////////////////////////////////
9// Namespace FRD_A
10
11namespace FRD_A {
12
13// Empty arrays are illegal -- commented out until an entry is added.
14// const Interface::FunctionInfo FunctionTable[] = { };
15
16////////////////////////////////////////////////////////////////////////////////////////////////////
17// Interface class
18
19Interface::Interface() {
20 //Register(FunctionTable);
21}
22
23} // namespace
diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp
index 6d4a9c7c9..4e275cb13 100644
--- a/src/core/hle/service/fs/archive.cpp
+++ b/src/core/hle/service/fs/archive.cpp
@@ -254,7 +254,7 @@ ResultVal<ArchiveHandle> OpenArchive(ArchiveIdCode id_code, FileSys::Path& archi
254 254
255 CASCADE_RESULT(std::unique_ptr<ArchiveBackend> res, itr->second->Open(archive_path)); 255 CASCADE_RESULT(std::unique_ptr<ArchiveBackend> res, itr->second->Open(archive_path));
256 256
257 // This should never even happen in the first place with 64-bit handles, 257 // This should never even happen in the first place with 64-bit handles,
258 while (handle_map.count(next_handle) != 0) { 258 while (handle_map.count(next_handle) != 0) {
259 ++next_handle; 259 ++next_handle;
260 } 260 }
@@ -406,7 +406,7 @@ ResultCode FormatArchive(ArchiveIdCode id_code, const FileSys::Path& path) {
406 return archive_itr->second->Format(path); 406 return archive_itr->second->Format(path);
407} 407}
408 408
409ResultCode CreateExtSaveData(MediaType media_type, u32 high, u32 low) { 409ResultCode CreateExtSaveData(MediaType media_type, u32 high, u32 low, VAddr icon_buffer, u32 icon_size) {
410 // Construct the binary path to the archive first 410 // Construct the binary path to the archive first
411 FileSys::Path path = FileSys::ConstructExtDataBinaryPath(static_cast<u32>(media_type), high, low); 411 FileSys::Path path = FileSys::ConstructExtDataBinaryPath(static_cast<u32>(media_type), high, low);
412 412
@@ -421,9 +421,25 @@ ResultCode CreateExtSaveData(MediaType media_type, u32 high, u32 low) {
421 } 421 }
422 422
423 std::string base_path = FileSys::GetExtDataContainerPath(media_type_directory, media_type == MediaType::NAND); 423 std::string base_path = FileSys::GetExtDataContainerPath(media_type_directory, media_type == MediaType::NAND);
424 std::string extsavedata_path = FileSys::GetExtSaveDataPath(base_path, path); 424 std::string game_path = FileSys::GetExtSaveDataPath(base_path, path);
425 if (!FileUtil::CreateFullPath(extsavedata_path)) 425 // These two folders are always created with the ExtSaveData
426 std::string user_path = game_path + "user/";
427 std::string boss_path = game_path + "boss/";
428 if (!FileUtil::CreateFullPath(user_path))
429 return ResultCode(-1); // TODO(Subv): Find the right error code
430 if (!FileUtil::CreateFullPath(boss_path))
431 return ResultCode(-1); // TODO(Subv): Find the right error code
432
433 u8* smdh_icon = Memory::GetPointer(icon_buffer);
434 if (!smdh_icon)
426 return ResultCode(-1); // TODO(Subv): Find the right error code 435 return ResultCode(-1); // TODO(Subv): Find the right error code
436
437 // Create the icon
438 FileUtil::IOFile icon_file(game_path + "icon", "wb+");
439 if (!icon_file.IsGood())
440 return ResultCode(-1); // TODO(Subv): Find the right error code
441
442 icon_file.WriteBytes(smdh_icon, icon_size);
427 return RESULT_SUCCESS; 443 return RESULT_SUCCESS;
428} 444}
429 445
@@ -441,6 +457,7 @@ ResultCode DeleteExtSaveData(MediaType media_type, u32 high, u32 low) {
441 return ResultCode(-1); // TODO(Subv): Find the right error code 457 return ResultCode(-1); // TODO(Subv): Find the right error code
442 } 458 }
443 459
460 // Delete all directories (/user, /boss) and the icon file.
444 std::string base_path = FileSys::GetExtDataContainerPath(media_type_directory, media_type == MediaType::NAND); 461 std::string base_path = FileSys::GetExtDataContainerPath(media_type_directory, media_type == MediaType::NAND);
445 std::string extsavedata_path = FileSys::GetExtSaveDataPath(base_path, path); 462 std::string extsavedata_path = FileSys::GetExtSaveDataPath(base_path, path);
446 if (!FileUtil::DeleteDirRecursively(extsavedata_path)) 463 if (!FileUtil::DeleteDirRecursively(extsavedata_path))
@@ -488,7 +505,7 @@ void ArchiveInit() {
488 RegisterArchiveType(std::move(sdmc_factory), ArchiveIdCode::SDMC); 505 RegisterArchiveType(std::move(sdmc_factory), ArchiveIdCode::SDMC);
489 else 506 else
490 LOG_ERROR(Service_FS, "Can't instantiate SDMC archive with path %s", sdmc_directory.c_str()); 507 LOG_ERROR(Service_FS, "Can't instantiate SDMC archive with path %s", sdmc_directory.c_str());
491 508
492 // Create the SaveData archive 509 // Create the SaveData archive
493 auto savedata_factory = Common::make_unique<FileSys::ArchiveFactory_SaveData>(sdmc_directory); 510 auto savedata_factory = Common::make_unique<FileSys::ArchiveFactory_SaveData>(sdmc_directory);
494 RegisterArchiveType(std::move(savedata_factory), ArchiveIdCode::SaveData); 511 RegisterArchiveType(std::move(savedata_factory), ArchiveIdCode::SaveData);
@@ -503,7 +520,7 @@ void ArchiveInit() {
503 if (sharedextsavedata_factory->Initialize()) 520 if (sharedextsavedata_factory->Initialize())
504 RegisterArchiveType(std::move(sharedextsavedata_factory), ArchiveIdCode::SharedExtSaveData); 521 RegisterArchiveType(std::move(sharedextsavedata_factory), ArchiveIdCode::SharedExtSaveData);
505 else 522 else
506 LOG_ERROR(Service_FS, "Can't instantiate SharedExtSaveData archive with path %s", 523 LOG_ERROR(Service_FS, "Can't instantiate SharedExtSaveData archive with path %s",
507 sharedextsavedata_factory->GetMountPoint().c_str()); 524 sharedextsavedata_factory->GetMountPoint().c_str());
508 525
509 // Create the SaveDataCheck archive, basically a small variation of the RomFS archive 526 // Create the SaveDataCheck archive, basically a small variation of the RomFS archive
diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h
index faab0cb79..357b6b096 100644
--- a/src/core/hle/service/fs/archive.h
+++ b/src/core/hle/service/fs/archive.h
@@ -177,9 +177,11 @@ ResultCode FormatArchive(ArchiveIdCode id_code, const FileSys::Path& path = File
177 * @param media_type The media type of the archive to create (NAND / SDMC) 177 * @param media_type The media type of the archive to create (NAND / SDMC)
178 * @param high The high word of the extdata id to create 178 * @param high The high word of the extdata id to create
179 * @param low The low word of the extdata id to create 179 * @param low The low word of the extdata id to create
180 * @param icon_buffer VAddr of the SMDH icon for this ExtSaveData
181 * @param icon_size Size of the SMDH icon
180 * @return ResultCode 0 on success or the corresponding code on error 182 * @return ResultCode 0 on success or the corresponding code on error
181 */ 183 */
182ResultCode CreateExtSaveData(MediaType media_type, u32 high, u32 low); 184ResultCode CreateExtSaveData(MediaType media_type, u32 high, u32 low, VAddr icon_buffer, u32 icon_size);
183 185
184/** 186/**
185 * Deletes the SharedExtSaveData archive for the specified extdata ID 187 * Deletes the SharedExtSaveData archive for the specified extdata ID
diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp
index b25c8941d..0ad44e55e 100644
--- a/src/core/hle/service/fs/fs_user.cpp
+++ b/src/core/hle/service/fs/fs_user.cpp
@@ -434,7 +434,7 @@ static void IsSdmcWriteable(Service::Interface* self) {
434} 434}
435 435
436/** 436/**
437 * FS_User::FormatSaveData service function, 437 * FS_User::FormatSaveData service function,
438 * formats the SaveData specified by the input path. 438 * formats the SaveData specified by the input path.
439 * Inputs: 439 * Inputs:
440 * 0 : 0x084C0242 440 * 0 : 0x084C0242
@@ -504,9 +504,9 @@ static void FormatThisUserSaveData(Service::Interface* self) {
504 * 6 : Unknown 504 * 6 : Unknown
505 * 7 : Unknown 505 * 7 : Unknown
506 * 8 : Unknown 506 * 8 : Unknown
507 * 9 : Unknown 507 * 9 : Size of the SMDH icon
508 * 10: Unknown 508 * 10: (SMDH Size << 4) | 0x0000000A
509 * 11: Unknown 509 * 11: Pointer to the SMDH icon for the new ExtSaveData
510 * Outputs: 510 * Outputs:
511 * 1 : Result of function, 0 on success, otherwise error code 511 * 1 : Result of function, 0 on success, otherwise error code
512 */ 512 */
@@ -516,14 +516,16 @@ static void CreateExtSaveData(Service::Interface* self) {
516 MediaType media_type = static_cast<MediaType>(cmd_buff[1] & 0xFF); 516 MediaType media_type = static_cast<MediaType>(cmd_buff[1] & 0xFF);
517 u32 save_low = cmd_buff[2]; 517 u32 save_low = cmd_buff[2];
518 u32 save_high = cmd_buff[3]; 518 u32 save_high = cmd_buff[3];
519 u32 icon_size = cmd_buff[9];
520 VAddr icon_buffer = cmd_buff[11];
519 521
520 LOG_WARNING(Service_FS, "(STUBBED) savedata_high=%08X savedata_low=%08X cmd_buff[3]=%08X " 522 LOG_WARNING(Service_FS, "(STUBBED) savedata_high=%08X savedata_low=%08X cmd_buff[3]=%08X "
521 "cmd_buff[4]=%08X cmd_buff[5]=%08X cmd_buff[6]=%08X cmd_buff[7]=%08X cmd_buff[8]=%08X " 523 "cmd_buff[4]=%08X cmd_buff[5]=%08X cmd_buff[6]=%08X cmd_buff[7]=%08X cmd_buff[8]=%08X "
522 "cmd_buff[9]=%08X cmd_buff[10]=%08X cmd_buff[11]=%08X", save_high, save_low, 524 "icon_size=%08X icon_descriptor=%08X icon_buffer=%08X", save_high, save_low,
523 cmd_buff[3], cmd_buff[4], cmd_buff[5], cmd_buff[6], cmd_buff[7], cmd_buff[8], cmd_buff[9], 525 cmd_buff[3], cmd_buff[4], cmd_buff[5], cmd_buff[6], cmd_buff[7], cmd_buff[8], icon_size,
524 cmd_buff[10], cmd_buff[11]); 526 cmd_buff[10], icon_buffer);
525 527
526 cmd_buff[1] = CreateExtSaveData(media_type, save_high, save_low).raw; 528 cmd_buff[1] = CreateExtSaveData(media_type, save_high, save_low, icon_buffer, icon_size).raw;
527} 529}
528 530
529/** 531/**
@@ -544,7 +546,7 @@ static void DeleteExtSaveData(Service::Interface* self) {
544 u32 save_high = cmd_buff[3]; 546 u32 save_high = cmd_buff[3];
545 u32 unknown = cmd_buff[4]; // TODO(Subv): Figure out what this is 547 u32 unknown = cmd_buff[4]; // TODO(Subv): Figure out what this is
546 548
547 LOG_WARNING(Service_FS, "(STUBBED) save_low=%08X save_high=%08X media_type=%08X unknown=%08X", 549 LOG_WARNING(Service_FS, "(STUBBED) save_low=%08X save_high=%08X media_type=%08X unknown=%08X",
548 save_low, save_high, cmd_buff[1] & 0xFF, unknown); 550 save_low, save_high, cmd_buff[1] & 0xFF, unknown);
549 551
550 cmd_buff[1] = DeleteExtSaveData(media_type, save_high, save_low).raw; 552 cmd_buff[1] = DeleteExtSaveData(media_type, save_high, save_low).raw;
diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp
index c56475ae4..4b0b4229d 100644
--- a/src/core/hle/service/gsp_gpu.cpp
+++ b/src/core/hle/service/gsp_gpu.cpp
@@ -167,7 +167,7 @@ static void WriteHWRegsWithMask(Service::Interface* self) {
167 u32* cmd_buff = Kernel::GetCommandBuffer(); 167 u32* cmd_buff = Kernel::GetCommandBuffer();
168 u32 reg_addr = cmd_buff[1]; 168 u32 reg_addr = cmd_buff[1];
169 u32 size = cmd_buff[2]; 169 u32 size = cmd_buff[2];
170 170
171 u32* src_data = (u32*)Memory::GetPointer(cmd_buff[4]); 171 u32* src_data = (u32*)Memory::GetPointer(cmd_buff[4]);
172 u32* mask_data = (u32*)Memory::GetPointer(cmd_buff[6]); 172 u32* mask_data = (u32*)Memory::GetPointer(cmd_buff[6]);
173 173
@@ -208,21 +208,21 @@ static void SetBufferSwap(u32 screen_id, const FrameBufferInfo& info) {
208 PAddr phys_address_left = Memory::VirtualToPhysicalAddress(info.address_left); 208 PAddr phys_address_left = Memory::VirtualToPhysicalAddress(info.address_left);
209 PAddr phys_address_right = Memory::VirtualToPhysicalAddress(info.address_right); 209 PAddr phys_address_right = Memory::VirtualToPhysicalAddress(info.address_right);
210 if (info.active_fb == 0) { 210 if (info.active_fb == 0) {
211 WriteHWRegs(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_left1)), 4, 211 WriteHWRegs(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_left1)), 4,
212 &phys_address_left); 212 &phys_address_left);
213 WriteHWRegs(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_right1)), 4, 213 WriteHWRegs(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_right1)), 4,
214 &phys_address_right); 214 &phys_address_right);
215 } else { 215 } else {
216 WriteHWRegs(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_left2)), 4, 216 WriteHWRegs(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_left2)), 4,
217 &phys_address_left); 217 &phys_address_left);
218 WriteHWRegs(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_right2)), 4, 218 WriteHWRegs(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_right2)), 4,
219 &phys_address_right); 219 &phys_address_right);
220 } 220 }
221 WriteHWRegs(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].stride)), 4, 221 WriteHWRegs(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].stride)), 4,
222 &info.stride); 222 &info.stride);
223 WriteHWRegs(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].color_format)), 4, 223 WriteHWRegs(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].color_format)), 4,
224 &info.format); 224 &info.format);
225 WriteHWRegs(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].active_fb)), 4, 225 WriteHWRegs(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].active_fb)), 4,
226 &info.shown_fb); 226 &info.shown_fb);
227} 227}
228 228
@@ -374,7 +374,7 @@ static void ExecuteCommand(const Command& command, u32 thread_id) {
374 { 374 {
375 auto& params = command.set_command_list_last; 375 auto& params = command.set_command_list_last;
376 376
377 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(command_processor_config.address)), 377 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(command_processor_config.address)),
378 Memory::VirtualToPhysicalAddress(params.address) >> 3); 378 Memory::VirtualToPhysicalAddress(params.address) >> 3);
379 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(command_processor_config.size)), params.size); 379 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(command_processor_config.size)), params.size);
380 380
@@ -470,7 +470,7 @@ static void SetLcdForceBlack(Service::Interface* self) {
470 470
471 LCD::Write(HW::VADDR_LCD + 4 * LCD_REG_INDEX(color_fill_top), data.raw); // Top LCD 471 LCD::Write(HW::VADDR_LCD + 4 * LCD_REG_INDEX(color_fill_top), data.raw); // Top LCD
472 LCD::Write(HW::VADDR_LCD + 4 * LCD_REG_INDEX(color_fill_bottom), data.raw); // Bottom LCD 472 LCD::Write(HW::VADDR_LCD + 4 * LCD_REG_INDEX(color_fill_bottom), data.raw); // Bottom LCD
473 473
474 cmd_buff[1] = RESULT_SUCCESS.raw; 474 cmd_buff[1] = RESULT_SUCCESS.raw;
475} 475}
476 476
@@ -496,6 +496,52 @@ static void TriggerCmdReqQueue(Service::Interface* self) {
496 cmd_buff[1] = 0; // No error 496 cmd_buff[1] = 0; // No error
497} 497}
498 498
499/**
500 * GSP_GPU::ImportDisplayCaptureInfo service function
501 *
502 * Returns information about the current framebuffer state
503 *
504 * Inputs:
505 * 0: Header 0x00180000
506 * Outputs:
507 * 1: Result code
508 * 2: Left framebuffer virtual address for the main screen
509 * 3: Right framebuffer virtual address for the main screen
510 * 4: Main screen framebuffer format
511 * 5: Main screen framebuffer width
512 * 6: Left framebuffer virtual address for the bottom screen
513 * 7: Right framebuffer virtual address for the bottom screen
514 * 8: Bottom screen framebuffer format
515 * 9: Bottom screen framebuffer width
516 */
517static void ImportDisplayCaptureInfo(Service::Interface* self) {
518 u32* cmd_buff = Kernel::GetCommandBuffer();
519
520 // TODO(Subv): We're always returning the framebuffer structures for thread_id = 0,
521 // because we only support a single running application at a time.
522 // This should always return the framebuffer data that is currently displayed on the screen.
523
524 u32 thread_id = 0;
525
526 FrameBufferUpdate* top_screen = GetFrameBufferInfo(thread_id, 0);
527 FrameBufferUpdate* bottom_screen = GetFrameBufferInfo(thread_id, 1);
528
529 cmd_buff[2] = top_screen->framebuffer_info[top_screen->index].address_left;
530 cmd_buff[3] = top_screen->framebuffer_info[top_screen->index].address_right;
531 cmd_buff[4] = top_screen->framebuffer_info[top_screen->index].format;
532 cmd_buff[5] = top_screen->framebuffer_info[top_screen->index].stride;
533
534 cmd_buff[6] = bottom_screen->framebuffer_info[bottom_screen->index].address_left;
535 cmd_buff[7] = bottom_screen->framebuffer_info[bottom_screen->index].address_right;
536 cmd_buff[8] = bottom_screen->framebuffer_info[bottom_screen->index].format;
537 cmd_buff[9] = bottom_screen->framebuffer_info[bottom_screen->index].stride;
538
539 cmd_buff[1] = RESULT_SUCCESS.raw;
540
541 LOG_WARNING(Service_GSP, "called");
542}
543
544
499const Interface::FunctionInfo FunctionTable[] = { 545const Interface::FunctionInfo FunctionTable[] = {
500 {0x00010082, WriteHWRegs, "WriteHWRegs"}, 546 {0x00010082, WriteHWRegs, "WriteHWRegs"},
501 {0x00020084, WriteHWRegsWithMask, "WriteHWRegsWithMask"}, 547 {0x00020084, WriteHWRegsWithMask, "WriteHWRegsWithMask"},
@@ -520,7 +566,7 @@ const Interface::FunctionInfo FunctionTable[] = {
520 {0x00150002, nullptr, "TryAcquireRight"}, 566 {0x00150002, nullptr, "TryAcquireRight"},
521 {0x00160042, nullptr, "AcquireRight"}, 567 {0x00160042, nullptr, "AcquireRight"},
522 {0x00170000, nullptr, "ReleaseRight"}, 568 {0x00170000, nullptr, "ReleaseRight"},
523 {0x00180000, nullptr, "ImportDisplayCaptureInfo"}, 569 {0x00180000, ImportDisplayCaptureInfo, "ImportDisplayCaptureInfo"},
524 {0x00190000, nullptr, "SaveVramSysArea"}, 570 {0x00190000, nullptr, "SaveVramSysArea"},
525 {0x001A0000, nullptr, "RestoreVramSysArea"}, 571 {0x001A0000, nullptr, "RestoreVramSysArea"},
526 {0x001B0000, nullptr, "ResetGpuCore"}, 572 {0x001B0000, nullptr, "ResetGpuCore"},
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 2d2133b2e..c7c1bb5ab 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -58,7 +58,7 @@ void Update() {
58 58
59 mem->pad.current_state.hex = state.hex; 59 mem->pad.current_state.hex = state.hex;
60 mem->pad.index = next_pad_index; 60 mem->pad.index = next_pad_index;
61 ++next_touch_index %= mem->pad.entries.size(); 61 next_touch_index = (next_touch_index + 1) % mem->pad.entries.size();
62 62
63 // Get the previous Pad state 63 // Get the previous Pad state
64 u32 last_entry_index = (mem->pad.index - 1) % mem->pad.entries.size(); 64 u32 last_entry_index = (mem->pad.index - 1) % mem->pad.entries.size();
@@ -88,7 +88,7 @@ void Update() {
88 } 88 }
89 89
90 mem->touch.index = next_touch_index; 90 mem->touch.index = next_touch_index;
91 ++next_touch_index %= mem->touch.entries.size(); 91 next_touch_index = (next_touch_index + 1) % mem->touch.entries.size();
92 92
93 // Get the current touch entry 93 // Get the current touch entry
94 TouchDataEntry* touch_entry = &mem->touch.entries[mem->touch.index]; 94 TouchDataEntry* touch_entry = &mem->touch.entries[mem->touch.index];
@@ -106,7 +106,7 @@ void Update() {
106 mem->touch.index_reset_ticks_previous = mem->touch.index_reset_ticks; 106 mem->touch.index_reset_ticks_previous = mem->touch.index_reset_ticks;
107 mem->touch.index_reset_ticks = (s64)CoreTiming::GetTicks(); 107 mem->touch.index_reset_ticks = (s64)CoreTiming::GetTicks();
108 } 108 }
109 109
110 // Signal both handles when there's an update to Pad or touch 110 // Signal both handles when there's an update to Pad or touch
111 event_pad_or_touch_1->Signal(); 111 event_pad_or_touch_1->Signal();
112 event_pad_or_touch_2->Signal(); 112 event_pad_or_touch_2->Signal();
diff --git a/src/core/hle/service/hid/hid_spvr.cpp b/src/core/hle/service/hid/hid_spvr.cpp
index 02db12efd..532931ae0 100644
--- a/src/core/hle/service/hid/hid_spvr.cpp
+++ b/src/core/hle/service/hid/hid_spvr.cpp
@@ -25,6 +25,6 @@ const Interface::FunctionInfo FunctionTable[] = {
25HID_SPVR_Interface::HID_SPVR_Interface() { 25HID_SPVR_Interface::HID_SPVR_Interface() {
26 Register(FunctionTable); 26 Register(FunctionTable);
27} 27}
28 28
29} // namespace HID 29} // namespace HID
30} // namespace Service 30} // namespace Service
diff --git a/src/core/hle/service/hid/hid_user.h b/src/core/hle/service/hid/hid_user.h
index 0eeec2c25..baf7fed79 100644
--- a/src/core/hle/service/hid/hid_user.h
+++ b/src/core/hle/service/hid/hid_user.h
@@ -11,7 +11,7 @@
11 11
12namespace Service { 12namespace Service {
13namespace HID { 13namespace HID {
14 14
15/** 15/**
16 * HID service interface. 16 * HID service interface.
17 */ 17 */
diff --git a/src/core/hle/service/news/news.cpp b/src/core/hle/service/news/news.cpp
new file mode 100644
index 000000000..63cbd3850
--- /dev/null
+++ b/src/core/hle/service/news/news.cpp
@@ -0,0 +1,31 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/logging/log.h"
6
7#include "core/hle/service/service.h"
8#include "core/hle/service/news/news.h"
9#include "core/hle/service/news/news_s.h"
10#include "core/hle/service/news/news_u.h"
11
12#include "core/hle/hle.h"
13#include "core/hle/kernel/event.h"
14#include "core/hle/kernel/shared_memory.h"
15
16namespace Service {
17namespace NEWS {
18
19void Init() {
20 using namespace Kernel;
21
22 AddService(new NEWS_S_Interface);
23 AddService(new NEWS_U_Interface);
24}
25
26void Shutdown() {
27}
28
29} // namespace NEWS
30
31} // namespace Service
diff --git a/src/core/hle/service/news/news.h b/src/core/hle/service/news/news.h
new file mode 100644
index 000000000..b31ade255
--- /dev/null
+++ b/src/core/hle/service/news/news.h
@@ -0,0 +1,20 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/hle/kernel/kernel.h"
8#include "core/hle/service/service.h"
9
10namespace Service {
11namespace NEWS {
12
13/// Initialize NEWS service(s)
14void Init();
15
16/// Shutdown NEWS service(s)
17void Shutdown();
18
19} // namespace NEWS
20} // namespace Service
diff --git a/src/core/hle/service/news/news_s.cpp b/src/core/hle/service/news/news_s.cpp
new file mode 100644
index 000000000..2f8c37d9e
--- /dev/null
+++ b/src/core/hle/service/news/news_s.cpp
@@ -0,0 +1,21 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/hle.h"
6#include "core/hle/service/news/news.h"
7#include "core/hle/service/news/news_s.h"
8
9namespace Service {
10namespace NEWS {
11
12const Interface::FunctionInfo FunctionTable[] = {
13 {0x000100C6, nullptr, "AddNotification"},
14};
15
16NEWS_S_Interface::NEWS_S_Interface() {
17 Register(FunctionTable);
18}
19
20} // namespace NEWS
21} // namespace Service
diff --git a/src/core/hle/service/news_s.h b/src/core/hle/service/news/news_s.h
index f8b4636d5..f58b969a8 100644
--- a/src/core/hle/service/news_s.h
+++ b/src/core/hle/service/news/news_s.h
@@ -6,18 +6,17 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9//////////////////////////////////////////////////////////////////////////////////////////////////// 9namespace Service {
10// Namespace NEWS_S 10namespace NEWS {
11 11
12namespace NEWS_S { 12class NEWS_S_Interface : public Service::Interface {
13
14class Interface : public Service::Interface {
15public: 13public:
16 Interface(); 14 NEWS_S_Interface();
17 15
18 std::string GetPortName() const override { 16 std::string GetPortName() const override {
19 return "news:s"; 17 return "news:s";
20 } 18 }
21}; 19};
22 20
23} // namespace 21} // namespace NEWS
22} // namespace Service
diff --git a/src/core/hle/service/news/news_u.cpp b/src/core/hle/service/news/news_u.cpp
new file mode 100644
index 000000000..81f45a244
--- /dev/null
+++ b/src/core/hle/service/news/news_u.cpp
@@ -0,0 +1,21 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/hle.h"
6#include "core/hle/service/news/news.h"
7#include "core/hle/service/news/news_u.h"
8
9namespace Service {
10namespace NEWS {
11
12const Interface::FunctionInfo FunctionTable[] = {
13 {0x000100C6, nullptr, "AddNotification"},
14};
15
16NEWS_U_Interface::NEWS_U_Interface() {
17 Register(FunctionTable);
18}
19
20} // namespace NEWS
21} // namespace Service
diff --git a/src/core/hle/service/news_u.h b/src/core/hle/service/news/news_u.h
index 0473cd19c..2720053d0 100644
--- a/src/core/hle/service/news_u.h
+++ b/src/core/hle/service/news/news_u.h
@@ -6,18 +6,17 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9//////////////////////////////////////////////////////////////////////////////////////////////////// 9namespace Service {
10// Namespace NEWS_U 10namespace NEWS {
11 11
12namespace NEWS_U { 12class NEWS_U_Interface : public Service::Interface {
13
14class Interface : public Service::Interface {
15public: 13public:
16 Interface(); 14 NEWS_U_Interface();
17 15
18 std::string GetPortName() const override { 16 std::string GetPortName() const override {
19 return "news:u"; 17 return "news:u";
20 } 18 }
21}; 19};
22 20
23} // namespace 21} // namespace NEWS
22} // namespace Service
diff --git a/src/core/hle/service/news_s.cpp b/src/core/hle/service/news_s.cpp
deleted file mode 100644
index 302d588c7..000000000
--- a/src/core/hle/service/news_s.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/hle.h"
6#include "core/hle/service/news_s.h"
7
8////////////////////////////////////////////////////////////////////////////////////////////////////
9// Namespace NEWS_S
10
11namespace NEWS_S {
12
13const Interface::FunctionInfo FunctionTable[] = {
14 {0x000100C6, nullptr, "AddNotification"},
15};
16
17////////////////////////////////////////////////////////////////////////////////////////////////////
18// Interface class
19
20Interface::Interface() {
21 Register(FunctionTable);
22}
23
24} // namespace
diff --git a/src/core/hle/service/news_u.cpp b/src/core/hle/service/news_u.cpp
deleted file mode 100644
index 7d835aa30..000000000
--- a/src/core/hle/service/news_u.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/hle.h"
6#include "core/hle/service/news_u.h"
7
8////////////////////////////////////////////////////////////////////////////////////////////////////
9// Namespace NEWS_U
10
11namespace NEWS_U {
12
13const Interface::FunctionInfo FunctionTable[] = {
14 {0x000100C8, nullptr, "AddNotification"},
15};
16
17////////////////////////////////////////////////////////////////////////////////////////////////////
18// Interface class
19
20Interface::Interface() {
21 Register(FunctionTable);
22}
23
24} // namespace
diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp
new file mode 100644
index 000000000..73b0ee52a
--- /dev/null
+++ b/src/core/hle/service/nim/nim.cpp
@@ -0,0 +1,42 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/logging/log.h"
6
7#include "core/hle/service/service.h"
8#include "core/hle/service/nim/nim.h"
9#include "core/hle/service/nim/nim_aoc.h"
10#include "core/hle/service/nim/nim_s.h"
11#include "core/hle/service/nim/nim_u.h"
12
13#include "core/hle/kernel/event.h"
14#include "core/hle/kernel/shared_memory.h"
15#include "core/hle/hle.h"
16
17namespace Service {
18namespace NIM {
19
20void CheckSysUpdateAvailable(Service::Interface* self) {
21 u32* cmd_buff = Kernel::GetCommandBuffer();
22
23 cmd_buff[1] = RESULT_SUCCESS.raw;
24 cmd_buff[2] = 0; // No update available
25
26 LOG_WARNING(Service_NWM, "(STUBBED) called");
27}
28
29void Init() {
30 using namespace Kernel;
31
32 AddService(new NIM_AOC_Interface);
33 AddService(new NIM_S_Interface);
34 AddService(new NIM_U_Interface);
35}
36
37void Shutdown() {
38}
39
40} // namespace NIM
41
42} // namespace Service
diff --git a/src/core/hle/service/nim/nim.h b/src/core/hle/service/nim/nim.h
new file mode 100644
index 000000000..f7635c747
--- /dev/null
+++ b/src/core/hle/service/nim/nim.h
@@ -0,0 +1,30 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/hle/kernel/kernel.h"
8#include "core/hle/service/service.h"
9
10namespace Service {
11namespace NIM {
12
13/**
14 * NIM::CheckSysUpdateAvailable service function
15 * Inputs:
16 * 1 : None
17 * Outputs:
18 * 1 : Result of function, 0 on success, otherwise error code
19 * 2 : flag, 0 = no system update available, 1 = system update available.
20 */
21void CheckSysUpdateAvailable(Service::Interface* self);
22
23/// Initialize NIM service(s)
24void Init();
25
26/// Shutdown NIM service(s)
27void Shutdown();
28
29} // namespace NIM
30} // namespace Service
diff --git a/src/core/hle/service/nim_aoc.cpp b/src/core/hle/service/nim/nim_aoc.cpp
index 7a6aea91a..e6b1b6145 100644
--- a/src/core/hle/service/nim_aoc.cpp
+++ b/src/core/hle/service/nim/nim_aoc.cpp
@@ -3,12 +3,11 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "core/hle/hle.h" 5#include "core/hle/hle.h"
6#include "core/hle/service/nim_aoc.h" 6#include "core/hle/service/nim/nim.h"
7#include "core/hle/service/nim/nim_aoc.h"
7 8
8//////////////////////////////////////////////////////////////////////////////////////////////////// 9namespace Service {
9// Namespace NIM_AOC 10namespace NIM {
10
11namespace NIM_AOC {
12 11
13const Interface::FunctionInfo FunctionTable[] = { 12const Interface::FunctionInfo FunctionTable[] = {
14 {0x00030042, nullptr, "SetApplicationId"}, 13 {0x00030042, nullptr, "SetApplicationId"},
@@ -20,11 +19,10 @@ const Interface::FunctionInfo FunctionTable[] = {
20 {0x00240282, nullptr, "CalculateContentsRequiredSize"}, 19 {0x00240282, nullptr, "CalculateContentsRequiredSize"},
21 {0x00250000, nullptr, "RefreshServerTime"}, 20 {0x00250000, nullptr, "RefreshServerTime"},
22}; 21};
23////////////////////////////////////////////////////////////////////////////////////////////////////
24// Interface class
25 22
26Interface::Interface() { 23NIM_AOC_Interface::NIM_AOC_Interface() {
27 Register(FunctionTable); 24 Register(FunctionTable);
28} 25}
29 26
30} // namespace 27} // namespace NIM
28} // namespace Service
diff --git a/src/core/hle/service/nim/nim_aoc.h b/src/core/hle/service/nim/nim_aoc.h
new file mode 100644
index 000000000..aace45b5a
--- /dev/null
+++ b/src/core/hle/service/nim/nim_aoc.h
@@ -0,0 +1,22 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included..
4
5#pragma once
6
7#include "core/hle/service/service.h"
8
9namespace Service {
10namespace NIM {
11
12class NIM_AOC_Interface : public Service::Interface {
13public:
14 NIM_AOC_Interface();
15
16 std::string GetPortName() const override {
17 return "nim:aoc";
18 }
19};
20
21} // namespace NIM
22} // namespace Service
diff --git a/src/core/hle/service/nim/nim_s.cpp b/src/core/hle/service/nim/nim_s.cpp
new file mode 100644
index 000000000..5d8bc059f
--- /dev/null
+++ b/src/core/hle/service/nim/nim_s.cpp
@@ -0,0 +1,22 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/hle.h"
6#include "core/hle/service/nim/nim.h"
7#include "core/hle/service/nim/nim_s.h"
8
9namespace Service {
10namespace NIM {
11
12const Interface::FunctionInfo FunctionTable[] = {
13 {0x000A0000, nullptr, "CheckSysupdateAvailableSOAP"},
14};
15
16NIM_S_Interface::NIM_S_Interface() {
17 Register(FunctionTable);
18}
19
20} // namespace NIM
21} // namespace Service
22
diff --git a/src/core/hle/service/nim/nim_s.h b/src/core/hle/service/nim/nim_s.h
new file mode 100644
index 000000000..f4bf73d26
--- /dev/null
+++ b/src/core/hle/service/nim/nim_s.h
@@ -0,0 +1,22 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included..
4
5#pragma once
6
7#include "core/hle/service/service.h"
8
9namespace Service {
10namespace NIM {
11
12class NIM_S_Interface : public Service::Interface {
13public:
14 NIM_S_Interface();
15
16 std::string GetPortName() const override {
17 return "nim:s";
18 }
19};
20
21} // namespace NIM
22} // namespace Service
diff --git a/src/core/hle/service/nim/nim_u.cpp b/src/core/hle/service/nim/nim_u.cpp
new file mode 100644
index 000000000..066570a85
--- /dev/null
+++ b/src/core/hle/service/nim/nim_u.cpp
@@ -0,0 +1,27 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/hle.h"
6#include "core/hle/service/nim/nim.h"
7#include "core/hle/service/nim/nim_u.h"
8
9namespace Service {
10namespace NIM {
11
12const Interface::FunctionInfo FunctionTable[] = {
13 {0x00010000, nullptr, "StartSysUpdate"},
14 {0x00020000, nullptr, "GetUpdateDownloadProgress"},
15 {0x00040000, nullptr, "FinishTitlesInstall"},
16 {0x00050000, nullptr, "CheckForSysUpdateEvent"},
17 {0x00090000, CheckSysUpdateAvailable, "CheckSysUpdateAvailable"},
18 {0x000A0000, nullptr, "GetState"},
19};
20
21NIM_U_Interface::NIM_U_Interface() {
22 Register(FunctionTable);
23}
24
25} // namespace NIM
26} // namespace Service
27
diff --git a/src/core/hle/service/nim/nim_u.h b/src/core/hle/service/nim/nim_u.h
new file mode 100644
index 000000000..bc89dc0f3
--- /dev/null
+++ b/src/core/hle/service/nim/nim_u.h
@@ -0,0 +1,22 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included..
4
5#pragma once
6
7#include "core/hle/service/service.h"
8
9namespace Service {
10namespace NIM {
11
12class NIM_U_Interface : public Service::Interface {
13public:
14 NIM_U_Interface();
15
16 std::string GetPortName() const override {
17 return "nim:u";
18 }
19};
20
21} // namespace NIM
22} // namespace Service
diff --git a/src/core/hle/service/nim_aoc.h b/src/core/hle/service/nim_aoc.h
deleted file mode 100644
index aeb71eed2..000000000
--- a/src/core/hle/service/nim_aoc.h
+++ /dev/null
@@ -1,23 +0,0 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/hle/service/service.h"
8
9////////////////////////////////////////////////////////////////////////////////////////////////////
10// Namespace NIM_AOC
11
12namespace NIM_AOC {
13
14class Interface : public Service::Interface {
15public:
16 Interface();
17
18 std::string GetPortName() const override {
19 return "nim:aoc";
20 }
21};
22
23} // namespace
diff --git a/src/core/hle/service/nim_u.cpp b/src/core/hle/service/nim_u.cpp
deleted file mode 100644
index 5f13bd98e..000000000
--- a/src/core/hle/service/nim_u.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/logging/log.h"
6
7#include "core/hle/hle.h"
8#include "core/hle/service/nim_u.h"
9
10////////////////////////////////////////////////////////////////////////////////////////////////////
11// Namespace NIM_U
12
13namespace NIM_U {
14
15/**
16 * NIM_U::CheckSysUpdateAvailable service function
17 * Inputs:
18 * 1 : None
19 * Outputs:
20 * 1 : Result of function, 0 on success, otherwise error code
21 * 2 : flag, 0 = no system update available, 1 = system update available.
22 */
23static void CheckSysUpdateAvailable(Service::Interface* self) {
24 u32* cmd_buff = Kernel::GetCommandBuffer();
25
26 cmd_buff[1] = RESULT_SUCCESS.raw;
27 cmd_buff[2] = 0; // No update available
28
29 LOG_WARNING(Service_NWM, "(STUBBED) called");
30}
31
32const Interface::FunctionInfo FunctionTable[] = {
33 {0x00010000, nullptr, "StartSysUpdate"},
34 {0x00020000, nullptr, "GetUpdateDownloadProgress"},
35 {0x00040000, nullptr, "FinishTitlesInstall"},
36 {0x00050000, nullptr, "CheckForSysUpdateEvent"},
37 {0x00090000, CheckSysUpdateAvailable, "CheckSysUpdateAvailable"},
38 {0x000A0000, nullptr, "GetState"},
39};
40
41////////////////////////////////////////////////////////////////////////////////////////////////////
42// Interface class
43
44Interface::Interface() {
45 Register(FunctionTable);
46}
47
48} // namespace
diff --git a/src/core/hle/service/nim_u.h b/src/core/hle/service/nim_u.h
deleted file mode 100644
index 57a1f6acf..000000000
--- a/src/core/hle/service/nim_u.h
+++ /dev/null
@@ -1,23 +0,0 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/hle/service/service.h"
8
9////////////////////////////////////////////////////////////////////////////////////////////////////
10// Namespace NIM_U
11
12namespace NIM_U {
13
14class Interface : public Service::Interface {
15public:
16 Interface();
17
18 std::string GetPortName() const override {
19 return "nim:u";
20 }
21};
22
23} // namespace
diff --git a/src/core/hle/service/ptm/ptm.h b/src/core/hle/service/ptm/ptm.h
index 493e6a11f..b690003cb 100644
--- a/src/core/hle/service/ptm/ptm.h
+++ b/src/core/hle/service/ptm/ptm.h
@@ -20,15 +20,15 @@ enum class ChargeLevels : u32 {
20 CompletelyFull = 5, 20 CompletelyFull = 5,
21}; 21};
22 22
23/** 23/**
24 * Represents the gamecoin file structure in the SharedExtData archive 24 * Represents the gamecoin file structure in the SharedExtData archive
25 * More information in 3dbrew (http://www.3dbrew.org/wiki/Extdata#Shared_Extdata_0xf000000b_gamecoin.dat) 25 * More information in 3dbrew (http://www.3dbrew.org/wiki/Extdata#Shared_Extdata_0xf000000b_gamecoin.dat)
26 */ 26 */
27struct GameCoin { 27struct GameCoin {
28 u32 magic; ///< Magic number: 0x4F00 28 u32 magic; ///< Magic number: 0x4F00
29 u16 total_coins; ///< Total Play Coins 29 u16 total_coins; ///< Total Play Coins
30 u16 total_coins_on_date; ///< Total Play Coins obtained on the date stored below. 30 u16 total_coins_on_date; ///< Total Play Coins obtained on the date stored below.
31 u32 step_count; ///< Total step count at the time a new Play Coin was obtained. 31 u32 step_count; ///< Total step count at the time a new Play Coin was obtained.
32 u32 last_step_count; ///< Step count for the day the last Play Coin was obtained 32 u32 last_step_count; ///< Step count for the day the last Play Coin was obtained
33 u16 year; 33 u16 year;
34 u8 month; 34 u8 month;
diff --git a/src/core/hle/service/ptm/ptm_play.cpp b/src/core/hle/service/ptm/ptm_play.cpp
index 48e68a3d8..7bb990193 100644
--- a/src/core/hle/service/ptm/ptm_play.cpp
+++ b/src/core/hle/service/ptm/ptm_play.cpp
@@ -18,6 +18,6 @@ const Interface::FunctionInfo FunctionTable[] = {
18PTM_Play_Interface::PTM_Play_Interface() { 18PTM_Play_Interface::PTM_Play_Interface() {
19 Register(FunctionTable); 19 Register(FunctionTable);
20} 20}
21 21
22} // namespace PTM 22} // namespace PTM
23} // namespace Service \ No newline at end of file 23} // namespace Service \ No newline at end of file
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 64185c62e..d681cc3dc 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -8,29 +8,15 @@
8#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
9#include "core/hle/service/ac_u.h" 9#include "core/hle/service/ac_u.h"
10#include "core/hle/service/act_u.h" 10#include "core/hle/service/act_u.h"
11#include "core/hle/service/am_app.h"
12#include "core/hle/service/am_net.h"
13#include "core/hle/service/am_sys.h"
14#include "core/hle/service/boss_p.h"
15#include "core/hle/service/boss_u.h"
16#include "core/hle/service/cam_u.h"
17#include "core/hle/service/cecd_u.h"
18#include "core/hle/service/cecd_s.h"
19#include "core/hle/service/csnd_snd.h" 11#include "core/hle/service/csnd_snd.h"
20#include "core/hle/service/dsp_dsp.h" 12#include "core/hle/service/dsp_dsp.h"
21#include "core/hle/service/err_f.h" 13#include "core/hle/service/err_f.h"
22#include "core/hle/service/frd_a.h"
23#include "core/hle/service/frd_u.h"
24#include "core/hle/service/gsp_gpu.h" 14#include "core/hle/service/gsp_gpu.h"
25#include "core/hle/service/gsp_lcd.h" 15#include "core/hle/service/gsp_lcd.h"
26#include "core/hle/service/http_c.h" 16#include "core/hle/service/http_c.h"
27#include "core/hle/service/ldr_ro.h" 17#include "core/hle/service/ldr_ro.h"
28#include "core/hle/service/mic_u.h" 18#include "core/hle/service/mic_u.h"
29#include "core/hle/service/ndm_u.h" 19#include "core/hle/service/ndm_u.h"
30#include "core/hle/service/news_s.h"
31#include "core/hle/service/news_u.h"
32#include "core/hle/service/nim_aoc.h"
33#include "core/hle/service/nim_u.h"
34#include "core/hle/service/ns_s.h" 20#include "core/hle/service/ns_s.h"
35#include "core/hle/service/nwm_uds.h" 21#include "core/hle/service/nwm_uds.h"
36#include "core/hle/service/pm_app.h" 22#include "core/hle/service/pm_app.h"
@@ -39,11 +25,18 @@
39#include "core/hle/service/ssl_c.h" 25#include "core/hle/service/ssl_c.h"
40#include "core/hle/service/y2r_u.h" 26#include "core/hle/service/y2r_u.h"
41 27
28#include "core/hle/service/am/am.h"
42#include "core/hle/service/apt/apt.h" 29#include "core/hle/service/apt/apt.h"
30#include "core/hle/service/boss/boss.h"
31#include "core/hle/service/cam/cam.h"
32#include "core/hle/service/cecd/cecd.h"
33#include "core/hle/service/frd/frd.h"
43#include "core/hle/service/fs/archive.h" 34#include "core/hle/service/fs/archive.h"
44#include "core/hle/service/cfg/cfg.h" 35#include "core/hle/service/cfg/cfg.h"
45#include "core/hle/service/hid/hid.h" 36#include "core/hle/service/hid/hid.h"
46#include "core/hle/service/ir/ir.h" 37#include "core/hle/service/ir/ir.h"
38#include "core/hle/service/news/news.h"
39#include "core/hle/service/nim/nim.h"
47#include "core/hle/service/ptm/ptm.h" 40#include "core/hle/service/ptm/ptm.h"
48 41
49namespace Service { 42namespace Service {
@@ -52,7 +45,7 @@ std::unordered_map<std::string, Kernel::SharedPtr<Interface>> g_kernel_named_por
52std::unordered_map<std::string, Kernel::SharedPtr<Interface>> g_srv_services; 45std::unordered_map<std::string, Kernel::SharedPtr<Interface>> g_srv_services;
53 46
54/** 47/**
55 * Creates a function string for logging, complete with the name (or header code, depending 48 * Creates a function string for logging, complete with the name (or header code, depending
56 * on what's passed in) the port name, and all the cmd_buff arguments. 49 * on what's passed in) the port name, and all the cmd_buff arguments.
57 */ 50 */
58static std::string MakeFunctionString(const char* name, const char* port_name, const u32* cmd_buff) { 51static std::string MakeFunctionString(const char* name, const char* port_name, const u32* cmd_buff) {
@@ -111,36 +104,29 @@ void Init() {
111 AddNamedPort(new ERR_F::Interface); 104 AddNamedPort(new ERR_F::Interface);
112 105
113 Service::FS::ArchiveInit(); 106 Service::FS::ArchiveInit();
114 Service::CFG::Init(); 107 Service::AM::Init();
115 Service::APT::Init(); 108 Service::APT::Init();
116 Service::PTM::Init(); 109 Service::BOSS::Init();
110 Service::CAM::Init();
111 Service::CECD::Init();
112 Service::CFG::Init();
113 Service::FRD::Init();
117 Service::HID::Init(); 114 Service::HID::Init();
118 Service::IR::Init(); 115 Service::IR::Init();
116 Service::NEWS::Init();
117 Service::NIM::Init();
118 Service::PTM::Init();
119 119
120 AddService(new AC_U::Interface); 120 AddService(new AC_U::Interface);
121 AddService(new ACT_U::Interface); 121 AddService(new ACT_U::Interface);
122 AddService(new AM_APP::Interface);
123 AddService(new AM_NET::Interface);
124 AddService(new AM_SYS::Interface);
125 AddService(new BOSS_P::Interface);
126 AddService(new BOSS_U::Interface);
127 AddService(new CAM_U::Interface);
128 AddService(new CECD_S::Interface);
129 AddService(new CECD_U::Interface);
130 AddService(new CSND_SND::Interface); 122 AddService(new CSND_SND::Interface);
131 AddService(new DSP_DSP::Interface); 123 AddService(new DSP_DSP::Interface);
132 AddService(new FRD_A::Interface);
133 AddService(new FRD_U::Interface);
134 AddService(new GSP_GPU::Interface); 124 AddService(new GSP_GPU::Interface);
135 AddService(new GSP_LCD::Interface); 125 AddService(new GSP_LCD::Interface);
136 AddService(new HTTP_C::Interface); 126 AddService(new HTTP_C::Interface);
137 AddService(new LDR_RO::Interface); 127 AddService(new LDR_RO::Interface);
138 AddService(new MIC_U::Interface); 128 AddService(new MIC_U::Interface);
139 AddService(new NDM_U::Interface); 129 AddService(new NDM_U::Interface);
140 AddService(new NEWS_S::Interface);
141 AddService(new NEWS_U::Interface);
142 AddService(new NIM_AOC::Interface);
143 AddService(new NIM_U::Interface);
144 AddService(new NS_S::Interface); 130 AddService(new NS_S::Interface);
145 AddService(new NWM_UDS::Interface); 131 AddService(new NWM_UDS::Interface);
146 AddService(new PM_APP::Interface); 132 AddService(new PM_APP::Interface);
@@ -153,11 +139,19 @@ void Init() {
153 139
154/// Shutdown ServiceManager 140/// Shutdown ServiceManager
155void Shutdown() { 141void Shutdown() {
142
143 Service::PTM::Shutdown();
144 Service::NIM::Shutdown();
145 Service::NEWS::Shutdown();
156 Service::IR::Shutdown(); 146 Service::IR::Shutdown();
157 Service::HID::Shutdown(); 147 Service::HID::Shutdown();
158 Service::PTM::Shutdown(); 148 Service::FRD::Shutdown();
159 Service::APT::Shutdown();
160 Service::CFG::Shutdown(); 149 Service::CFG::Shutdown();
150 Service::CECD::Shutdown();
151 Service::CAM::Shutdown();
152 Service::BOSS::Shutdown();
153 Service::APT::Shutdown();
154 Service::AM::Shutdown();
161 Service::FS::ArchiveShutdown(); 155 Service::FS::ArchiveShutdown();
162 156
163 g_srv_services.clear(); 157 g_srv_services.clear();
diff --git a/src/core/hle/service/soc_u.cpp b/src/core/hle/service/soc_u.cpp
index 39b8d65fd..1e0f5df9b 100644
--- a/src/core/hle/service/soc_u.cpp
+++ b/src/core/hle/service/soc_u.cpp
@@ -139,7 +139,7 @@ static int TranslateError(int error) {
139 auto found = error_map.find(error); 139 auto found = error_map.find(error);
140 if (found != error_map.end()) 140 if (found != error_map.end())
141 return -found->second; 141 return -found->second;
142 142
143 return error; 143 return error;
144} 144}
145 145
@@ -346,7 +346,7 @@ static void Bind(Service::Interface* self) {
346 sockaddr sock_addr = CTRSockAddr::ToPlatform(*ctr_sock_addr); 346 sockaddr sock_addr = CTRSockAddr::ToPlatform(*ctr_sock_addr);
347 347
348 int res = ::bind(socket_handle, &sock_addr, std::max<u32>(sizeof(sock_addr), len)); 348 int res = ::bind(socket_handle, &sock_addr, std::max<u32>(sizeof(sock_addr), len));
349 349
350 int result = 0; 350 int result = 0;
351 if (res != 0) 351 if (res != 0)
352 result = TranslateError(GET_ERRNO); 352 result = TranslateError(GET_ERRNO);
@@ -360,14 +360,14 @@ static void Fcntl(Service::Interface* self) {
360 u32 socket_handle = cmd_buffer[1]; 360 u32 socket_handle = cmd_buffer[1];
361 u32 ctr_cmd = cmd_buffer[2]; 361 u32 ctr_cmd = cmd_buffer[2];
362 u32 ctr_arg = cmd_buffer[3]; 362 u32 ctr_arg = cmd_buffer[3];
363 363
364 int result = 0; 364 int result = 0;
365 u32 posix_ret = 0; // TODO: Check what hardware returns for F_SETFL (unspecified by POSIX) 365 u32 posix_ret = 0; // TODO: Check what hardware returns for F_SETFL (unspecified by POSIX)
366 SCOPE_EXIT({ 366 SCOPE_EXIT({
367 cmd_buffer[1] = result; 367 cmd_buffer[1] = result;
368 cmd_buffer[2] = posix_ret; 368 cmd_buffer[2] = posix_ret;
369 }); 369 });
370 370
371 if (ctr_cmd == 3) { // F_GETFL 371 if (ctr_cmd == 3) { // F_GETFL
372#if EMU_PLATFORM == PLATFORM_WINDOWS 372#if EMU_PLATFORM == PLATFORM_WINDOWS
373 posix_ret = 0; 373 posix_ret = 0;
@@ -404,11 +404,11 @@ static void Fcntl(Service::Interface* self) {
404 posix_ret = -1; 404 posix_ret = -1;
405 return; 405 return;
406 } 406 }
407 407
408 flags &= ~O_NONBLOCK; 408 flags &= ~O_NONBLOCK;
409 if (ctr_arg & 4) // O_NONBLOCK 409 if (ctr_arg & 4) // O_NONBLOCK
410 flags |= O_NONBLOCK; 410 flags |= O_NONBLOCK;
411 411
412 int ret = ::fcntl(socket_handle, F_SETFL, flags); 412 int ret = ::fcntl(socket_handle, F_SETFL, flags);
413 if (ret == SOCKET_ERROR_VALUE) { 413 if (ret == SOCKET_ERROR_VALUE) {
414 result = TranslateError(GET_ERRNO); 414 result = TranslateError(GET_ERRNO);
@@ -439,8 +439,8 @@ static void Listen(Service::Interface* self) {
439} 439}
440 440
441static void Accept(Service::Interface* self) { 441static void Accept(Service::Interface* self) {
442 // TODO(Subv): Calling this function on a blocking socket will block the emu thread, 442 // TODO(Subv): Calling this function on a blocking socket will block the emu thread,
443 // preventing graceful shutdown when closing the emulator, this can be fixed by always 443 // preventing graceful shutdown when closing the emulator, this can be fixed by always
444 // performing nonblocking operations and spinlock until the data is available 444 // performing nonblocking operations and spinlock until the data is available
445 u32* cmd_buffer = Kernel::GetCommandBuffer(); 445 u32* cmd_buffer = Kernel::GetCommandBuffer();
446 u32 socket_handle = cmd_buffer[1]; 446 u32 socket_handle = cmd_buffer[1];
@@ -448,7 +448,7 @@ static void Accept(Service::Interface* self) {
448 sockaddr addr; 448 sockaddr addr;
449 socklen_t addr_len = sizeof(addr); 449 socklen_t addr_len = sizeof(addr);
450 u32 ret = static_cast<u32>(::accept(socket_handle, &addr, &addr_len)); 450 u32 ret = static_cast<u32>(::accept(socket_handle, &addr, &addr_len));
451 451
452 if ((s32)ret != SOCKET_ERROR_VALUE) 452 if ((s32)ret != SOCKET_ERROR_VALUE)
453 open_sockets[ret] = { ret, true }; 453 open_sockets[ret] = { ret, true };
454 454
@@ -525,8 +525,8 @@ static void SendTo(Service::Interface* self) {
525} 525}
526 526
527static void RecvFrom(Service::Interface* self) { 527static void RecvFrom(Service::Interface* self) {
528 // TODO(Subv): Calling this function on a blocking socket will block the emu thread, 528 // TODO(Subv): Calling this function on a blocking socket will block the emu thread,
529 // preventing graceful shutdown when closing the emulator, this can be fixed by always 529 // preventing graceful shutdown when closing the emulator, this can be fixed by always
530 // performing nonblocking operations and spinlock until the data is available 530 // performing nonblocking operations and spinlock until the data is available
531 u32* cmd_buffer = Kernel::GetCommandBuffer(); 531 u32* cmd_buffer = Kernel::GetCommandBuffer();
532 u32 socket_handle = cmd_buffer[1]; 532 u32 socket_handle = cmd_buffer[1];
@@ -568,7 +568,7 @@ static void Poll(Service::Interface* self) {
568 pollfd* platform_pollfd = new pollfd[nfds]; 568 pollfd* platform_pollfd = new pollfd[nfds];
569 for (unsigned current_fds = 0; current_fds < nfds; ++current_fds) 569 for (unsigned current_fds = 0; current_fds < nfds; ++current_fds)
570 platform_pollfd[current_fds] = CTRPollFD::ToPlatform(input_fds[current_fds]); 570 platform_pollfd[current_fds] = CTRPollFD::ToPlatform(input_fds[current_fds]);
571 571
572 int ret = ::poll(platform_pollfd, nfds, timeout); 572 int ret = ::poll(platform_pollfd, nfds, timeout);
573 573
574 // Now update the output pollfd structure 574 // Now update the output pollfd structure
@@ -630,7 +630,7 @@ static void GetPeerName(Service::Interface* self) {
630 socklen_t len = cmd_buffer[2]; 630 socklen_t len = cmd_buffer[2];
631 631
632 CTRSockAddr* ctr_dest_addr = reinterpret_cast<CTRSockAddr*>(Memory::GetPointer(cmd_buffer[0x104 >> 2])); 632 CTRSockAddr* ctr_dest_addr = reinterpret_cast<CTRSockAddr*>(Memory::GetPointer(cmd_buffer[0x104 >> 2]));
633 633
634 sockaddr dest_addr; 634 sockaddr dest_addr;
635 socklen_t dest_addr_len = sizeof(dest_addr); 635 socklen_t dest_addr_len = sizeof(dest_addr);
636 int ret = ::getpeername(socket_handle, &dest_addr, &dest_addr_len); 636 int ret = ::getpeername(socket_handle, &dest_addr, &dest_addr_len);
@@ -651,8 +651,8 @@ static void GetPeerName(Service::Interface* self) {
651} 651}
652 652
653static void Connect(Service::Interface* self) { 653static void Connect(Service::Interface* self) {
654 // TODO(Subv): Calling this function on a blocking socket will block the emu thread, 654 // TODO(Subv): Calling this function on a blocking socket will block the emu thread,
655 // preventing graceful shutdown when closing the emulator, this can be fixed by always 655 // preventing graceful shutdown when closing the emulator, this can be fixed by always
656 // performing nonblocking operations and spinlock until the data is available 656 // performing nonblocking operations and spinlock until the data is available
657 u32* cmd_buffer = Kernel::GetCommandBuffer(); 657 u32* cmd_buffer = Kernel::GetCommandBuffer();
658 u32 socket_handle = cmd_buffer[1]; 658 u32 socket_handle = cmd_buffer[1];
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 347d241f9..6cde4fc87 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -40,9 +40,6 @@ const ResultCode ERR_NOT_FOUND(ErrorDescription::NotFound, ErrorModule::Kernel,
40const ResultCode ERR_PORT_NAME_TOO_LONG(ErrorDescription(30), ErrorModule::OS, 40const ResultCode ERR_PORT_NAME_TOO_LONG(ErrorDescription(30), ErrorModule::OS,
41 ErrorSummary::InvalidArgument, ErrorLevel::Usage); // 0xE0E0181E 41 ErrorSummary::InvalidArgument, ErrorLevel::Usage); // 0xE0E0181E
42 42
43/// An invalid result code that is meant to be overwritten when a thread resumes from waiting
44const ResultCode RESULT_INVALID(0xDEADC0DE);
45
46enum ControlMemoryOperation { 43enum ControlMemoryOperation {
47 MEMORY_OPERATION_HEAP = 0x00000003, 44 MEMORY_OPERATION_HEAP = 0x00000003,
48 MEMORY_OPERATION_GSP_HEAP = 0x00010003, 45 MEMORY_OPERATION_GSP_HEAP = 0x00010003,
@@ -143,6 +140,10 @@ static ResultCode CloseHandle(Handle handle) {
143/// Wait for a handle to synchronize, timeout after the specified nanoseconds 140/// Wait for a handle to synchronize, timeout after the specified nanoseconds
144static ResultCode WaitSynchronization1(Handle handle, s64 nano_seconds) { 141static ResultCode WaitSynchronization1(Handle handle, s64 nano_seconds) {
145 auto object = Kernel::g_handle_table.GetWaitObject(handle); 142 auto object = Kernel::g_handle_table.GetWaitObject(handle);
143 Kernel::Thread* thread = Kernel::GetCurrentThread();
144
145 thread->waitsynch_waited = false;
146
146 if (object == nullptr) 147 if (object == nullptr)
147 return ERR_INVALID_HANDLE; 148 return ERR_INVALID_HANDLE;
148 149
@@ -154,14 +155,14 @@ static ResultCode WaitSynchronization1(Handle handle, s64 nano_seconds) {
154 // Check for next thread to schedule 155 // Check for next thread to schedule
155 if (object->ShouldWait()) { 156 if (object->ShouldWait()) {
156 157
157 object->AddWaitingThread(Kernel::GetCurrentThread()); 158 object->AddWaitingThread(thread);
158 Kernel::WaitCurrentThread_WaitSynchronization({ object }, false, false); 159 Kernel::WaitCurrentThread_WaitSynchronization({ object }, false, false);
159 160
160 // Create an event to wake the thread up after the specified nanosecond delay has passed 161 // Create an event to wake the thread up after the specified nanosecond delay has passed
161 Kernel::GetCurrentThread()->WakeAfterDelay(nano_seconds); 162 thread->WakeAfterDelay(nano_seconds);
162 163
163 // NOTE: output of this SVC will be set later depending on how the thread resumes 164 // NOTE: output of this SVC will be set later depending on how the thread resumes
164 return RESULT_INVALID; 165 return HLE::RESULT_INVALID;
165 } 166 }
166 167
167 object->Acquire(); 168 object->Acquire();
@@ -173,6 +174,9 @@ static ResultCode WaitSynchronization1(Handle handle, s64 nano_seconds) {
173static ResultCode WaitSynchronizationN(s32* out, Handle* handles, s32 handle_count, bool wait_all, s64 nano_seconds) { 174static ResultCode WaitSynchronizationN(s32* out, Handle* handles, s32 handle_count, bool wait_all, s64 nano_seconds) {
174 bool wait_thread = !wait_all; 175 bool wait_thread = !wait_all;
175 int handle_index = 0; 176 int handle_index = 0;
177 Kernel::Thread* thread = Kernel::GetCurrentThread();
178 bool was_waiting = thread->waitsynch_waited;
179 thread->waitsynch_waited = false;
176 180
177 // Check if 'handles' is invalid 181 // Check if 'handles' is invalid
178 if (handles == nullptr) 182 if (handles == nullptr)
@@ -190,6 +194,9 @@ static ResultCode WaitSynchronizationN(s32* out, Handle* handles, s32 handle_cou
190 // necessary 194 // necessary
191 if (handle_count != 0) { 195 if (handle_count != 0) {
192 bool selected = false; // True once an object has been selected 196 bool selected = false; // True once an object has been selected
197
198 Kernel::SharedPtr<Kernel::WaitObject> wait_object;
199
193 for (int i = 0; i < handle_count; ++i) { 200 for (int i = 0; i < handle_count; ++i) {
194 auto object = Kernel::g_handle_table.GetWaitObject(handles[i]); 201 auto object = Kernel::g_handle_table.GetWaitObject(handles[i]);
195 if (object == nullptr) 202 if (object == nullptr)
@@ -204,10 +211,11 @@ static ResultCode WaitSynchronizationN(s32* out, Handle* handles, s32 handle_cou
204 wait_thread = true; 211 wait_thread = true;
205 } else { 212 } else {
206 // Do not wait on this object, check if this object should be selected... 213 // Do not wait on this object, check if this object should be selected...
207 if (!wait_all && !selected) { 214 if (!wait_all && (!selected || (wait_object == object && was_waiting))) {
208 // Do not wait the thread 215 // Do not wait the thread
209 wait_thread = false; 216 wait_thread = false;
210 handle_index = i; 217 handle_index = i;
218 wait_object = object;
211 selected = true; 219 selected = true;
212 } 220 }
213 } 221 }
@@ -228,7 +236,7 @@ static ResultCode WaitSynchronizationN(s32* out, Handle* handles, s32 handle_cou
228 // Actually wait the current thread on each object if we decided to wait... 236 // Actually wait the current thread on each object if we decided to wait...
229 std::vector<SharedPtr<Kernel::WaitObject>> wait_objects; 237 std::vector<SharedPtr<Kernel::WaitObject>> wait_objects;
230 wait_objects.reserve(handle_count); 238 wait_objects.reserve(handle_count);
231 239
232 for (int i = 0; i < handle_count; ++i) { 240 for (int i = 0; i < handle_count; ++i) {
233 auto object = Kernel::g_handle_table.GetWaitObject(handles[i]); 241 auto object = Kernel::g_handle_table.GetWaitObject(handles[i]);
234 object->AddWaitingThread(Kernel::GetCurrentThread()); 242 object->AddWaitingThread(Kernel::GetCurrentThread());
@@ -241,7 +249,7 @@ static ResultCode WaitSynchronizationN(s32* out, Handle* handles, s32 handle_cou
241 Kernel::GetCurrentThread()->WakeAfterDelay(nano_seconds); 249 Kernel::GetCurrentThread()->WakeAfterDelay(nano_seconds);
242 250
243 // NOTE: output of this SVC will be set later depending on how the thread resumes 251 // NOTE: output of this SVC will be set later depending on how the thread resumes
244 return RESULT_INVALID; 252 return HLE::RESULT_INVALID;
245 } 253 }
246 254
247 // Acquire objects if we did not wait... 255 // Acquire objects if we did not wait...
@@ -261,7 +269,7 @@ static ResultCode WaitSynchronizationN(s32* out, Handle* handles, s32 handle_cou
261 269
262 // TODO(bunnei): If 'wait_all' is true, this is probably wrong. However, real hardware does 270 // TODO(bunnei): If 'wait_all' is true, this is probably wrong. However, real hardware does
263 // not seem to set it to any meaningful value. 271 // not seem to set it to any meaningful value.
264 *out = wait_all ? 0 : handle_index; 272 *out = handle_count != 0 ? (wait_all ? -1 : handle_index) : 0;
265 273
266 return RESULT_SUCCESS; 274 return RESULT_SUCCESS;
267} 275}
@@ -475,7 +483,7 @@ static ResultCode GetProcessIdOfThread(u32* process_id, Handle thread_handle) {
475 return ERR_INVALID_HANDLE; 483 return ERR_INVALID_HANDLE;
476 484
477 const SharedPtr<Kernel::Process> process = thread->owner_process; 485 const SharedPtr<Kernel::Process> process = thread->owner_process;
478 486
479 ASSERT_MSG(process != nullptr, "Invalid parent process for thread=0x%08X", thread_handle); 487 ASSERT_MSG(process != nullptr, "Invalid parent process for thread=0x%08X", thread_handle);
480 488
481 *process_id = process->process_id; 489 *process_id = process->process_id;
@@ -654,6 +662,8 @@ static ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32
654 using Kernel::MemoryPermission; 662 using Kernel::MemoryPermission;
655 SharedPtr<SharedMemory> shared_memory = SharedMemory::Create(size, 663 SharedPtr<SharedMemory> shared_memory = SharedMemory::Create(size,
656 (MemoryPermission)my_permission, (MemoryPermission)other_permission); 664 (MemoryPermission)my_permission, (MemoryPermission)other_permission);
665 // Map the SharedMemory to the specified address
666 shared_memory->base_address = addr;
657 CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(shared_memory))); 667 CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(shared_memory)));
658 668
659 LOG_WARNING(Kernel_SVC, "(STUBBED) called addr=0x%08X", addr); 669 LOG_WARNING(Kernel_SVC, "(STUBBED) called addr=0x%08X", addr);
diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp
index ddc5d647e..7471def57 100644
--- a/src/core/hw/gpu.cpp
+++ b/src/core/hw/gpu.cpp
@@ -2,6 +2,7 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "common/color.h"
5#include "common/common_types.h" 6#include "common/common_types.h"
6 7
7#include "core/arm/arm_interface.h" 8#include "core/arm/arm_interface.h"
@@ -22,7 +23,6 @@
22#include "video_core/command_processor.h" 23#include "video_core/command_processor.h"
23#include "video_core/utils.h" 24#include "video_core/utils.h"
24#include "video_core/video_core.h" 25#include "video_core/video_core.h"
25#include "video_core/color.h"
26 26
27namespace GPU { 27namespace GPU {
28 28
@@ -30,8 +30,8 @@ Regs g_regs;
30 30
31/// True if the current frame was skipped 31/// True if the current frame was skipped
32bool g_skip_frame; 32bool g_skip_frame;
33/// 268MHz / gpu_refresh_rate frames per second 33/// 268MHz CPU clocks / 60Hz frames per second
34static u64 frame_ticks; 34const u64 frame_ticks = 268123480ull / 60;
35/// Event id for CoreTiming 35/// Event id for CoreTiming
36static int vblank_event; 36static int vblank_event;
37/// Total number of frames drawn 37/// Total number of frames drawn
@@ -140,7 +140,7 @@ inline void Write(u32 addr, const T data) {
140 // Raw copies do not perform color conversion nor tiled->linear / linear->tiled conversions 140 // Raw copies do not perform color conversion nor tiled->linear / linear->tiled conversions
141 // TODO(Subv): Verify if raw copies perform scaling 141 // TODO(Subv): Verify if raw copies perform scaling
142 memcpy(dst_pointer, src_pointer, output_size); 142 memcpy(dst_pointer, src_pointer, output_size);
143 143
144 LOG_TRACE(HW_GPU, "DisplayTriggerTransfer: 0x%08x bytes from 0x%08x(%ux%u)-> 0x%08x(%ux%u), output format: %x, flags 0x%08X, Raw copy", 144 LOG_TRACE(HW_GPU, "DisplayTriggerTransfer: 0x%08x bytes from 0x%08x(%ux%u)-> 0x%08x(%ux%u), output format: %x, flags 0x%08X, Raw copy",
145 output_size, 145 output_size,
146 config.GetPhysicalInputAddress(), config.input_width.Value(), config.input_height.Value(), 146 config.GetPhysicalInputAddress(), config.input_width.Value(), config.input_height.Value(),
@@ -159,14 +159,14 @@ inline void Write(u32 addr, const T data) {
159 for (u32 x = 0; x < output_width; ++x) { 159 for (u32 x = 0; x < output_width; ++x) {
160 Math::Vec4<u8> src_color = { 0, 0, 0, 0 }; 160 Math::Vec4<u8> src_color = { 0, 0, 0, 0 };
161 161
162 // Calculate the [x,y] position of the input image 162 // Calculate the [x,y] position of the input image
163 // based on the current output position and the scale 163 // based on the current output position and the scale
164 u32 input_x = x * horizontal_scale; 164 u32 input_x = x * horizontal_scale;
165 u32 input_y = y * vertical_scale; 165 u32 input_y = y * vertical_scale;
166 166
167 if (config.flip_vertically) { 167 if (config.flip_vertically) {
168 // Flip the y value of the output data, 168 // Flip the y value of the output data,
169 // we do this after calculating the [x,y] position of the input image 169 // we do this after calculating the [x,y] position of the input image
170 // to account for the scaling options. 170 // to account for the scaling options.
171 y = output_height - y - 1; 171 y = output_height - y - 1;
172 } 172 }
@@ -302,7 +302,7 @@ static void VBlankCallback(u64 userdata, int cycles_late) {
302 // - If frameskip == 0 (disabled), always swap buffers 302 // - If frameskip == 0 (disabled), always swap buffers
303 // - If frameskip == 1, swap buffers every other frame (starting from the first frame) 303 // - If frameskip == 1, swap buffers every other frame (starting from the first frame)
304 // - If frameskip > 1, swap buffers every frameskip^n frames (starting from the second frame) 304 // - If frameskip > 1, swap buffers every frameskip^n frames (starting from the second frame)
305 if ((((Settings::values.frame_skip != 1) ^ last_skip_frame) && last_skip_frame != g_skip_frame) || 305 if ((((Settings::values.frame_skip != 1) ^ last_skip_frame) && last_skip_frame != g_skip_frame) ||
306 Settings::values.frame_skip == 0) { 306 Settings::values.frame_skip == 0) {
307 VideoCore::g_renderer->SwapBuffers(); 307 VideoCore::g_renderer->SwapBuffers();
308 } 308 }
@@ -357,7 +357,6 @@ void Init() {
357 framebuffer_sub.color_format = Regs::PixelFormat::RGB8; 357 framebuffer_sub.color_format = Regs::PixelFormat::RGB8;
358 framebuffer_sub.active_fb = 0; 358 framebuffer_sub.active_fb = 0;
359 359
360 frame_ticks = 268123480 / Settings::values.gpu_refresh_rate;
361 last_skip_frame = false; 360 last_skip_frame = false;
362 g_skip_frame = false; 361 g_skip_frame = false;
363 frame_count = 0; 362 frame_count = 0;
diff --git a/src/core/hw/hw.cpp b/src/core/hw/hw.cpp
index f4906cc7e..c7006a498 100644
--- a/src/core/hw/hw.cpp
+++ b/src/core/hw/hw.cpp
@@ -18,7 +18,7 @@ inline void Read(T &var, const u32 addr) {
18 GPU::Read(var, addr); 18 GPU::Read(var, addr);
19 break; 19 break;
20 case VADDR_LCD: 20 case VADDR_LCD:
21 LCD::Write(var, addr); 21 LCD::Read(var, addr);
22 break; 22 break;
23 default: 23 default:
24 LOG_ERROR(HW_Memory, "unknown Read%lu @ 0x%08X", sizeof(var) * 8, addr); 24 LOG_ERROR(HW_Memory, "unknown Read%lu @ 0x%08X", sizeof(var) * 8, addr);
diff --git a/src/core/hw/lcd.cpp b/src/core/hw/lcd.cpp
index 09134c95b..963c8d981 100644
--- a/src/core/hw/lcd.cpp
+++ b/src/core/hw/lcd.cpp
@@ -66,5 +66,5 @@ void Init() {
66void Shutdown() { 66void Shutdown() {
67 LOG_DEBUG(HW_LCD, "shutdown OK"); 67 LOG_DEBUG(HW_LCD, "shutdown OK");
68} 68}
69 69
70} // namespace 70} // namespace
diff --git a/src/core/hw/lcd.h b/src/core/hw/lcd.h
index fb14c3b21..8631eb201 100644
--- a/src/core/hw/lcd.h
+++ b/src/core/hw/lcd.h
@@ -85,5 +85,5 @@ void Init();
85 85
86/// Shutdown hardware 86/// Shutdown hardware
87void Shutdown(); 87void Shutdown();
88 88
89} // namespace 89} // namespace
diff --git a/src/core/loader/3dsx.cpp b/src/core/loader/3dsx.cpp
index ad5e929ce..14aeebebb 100644
--- a/src/core/loader/3dsx.cpp
+++ b/src/core/loader/3dsx.cpp
@@ -234,7 +234,7 @@ ResultStatus AppLoader_THREEDSX::Load() {
234 Kernel::g_current_process = Kernel::Process::Create(filename, 0); 234 Kernel::g_current_process = Kernel::Process::Create(filename, 0);
235 Kernel::g_current_process->svc_access_mask.set(); 235 Kernel::g_current_process->svc_access_mask.set();
236 Kernel::g_current_process->address_mappings = default_address_mappings; 236 Kernel::g_current_process->address_mappings = default_address_mappings;
237 237
238 // Attach the default resource limit (APPLICATION) to the process 238 // Attach the default resource limit (APPLICATION) to the process
239 Kernel::g_current_process->resource_limit = Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); 239 Kernel::g_current_process->resource_limit = Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
240 240
diff --git a/src/core/mem_map.cpp b/src/core/mem_map.cpp
index 5ecec9566..bf814b945 100644
--- a/src/core/mem_map.cpp
+++ b/src/core/mem_map.cpp
@@ -8,6 +8,10 @@
8#include "common/logging/log.h" 8#include "common/logging/log.h"
9 9
10#include "core/hle/config_mem.h" 10#include "core/hle/config_mem.h"
11#include "core/hle/kernel/kernel.h"
12#include "core/hle/kernel/shared_memory.h"
13#include "core/hle/kernel/vm_manager.h"
14#include "core/hle/result.h"
11#include "core/hle/shared_page.h" 15#include "core/hle/shared_page.h"
12#include "core/mem_map.h" 16#include "core/mem_map.h"
13#include "core/memory.h" 17#include "core/memory.h"
@@ -17,31 +21,23 @@
17 21
18namespace Memory { 22namespace Memory {
19 23
20u8* g_exefs_code; ///< ExeFS:/.code is loaded here
21u8* g_heap; ///< Application heap (main memory)
22u8* g_shared_mem; ///< Shared memory
23u8* g_heap_linear; ///< Linear heap
24u8* g_vram; ///< Video memory (VRAM) pointer
25u8* g_dsp_mem; ///< DSP memory
26u8* g_tls_mem; ///< TLS memory
27
28namespace { 24namespace {
29 25
30struct MemoryArea { 26struct MemoryArea {
31 u8** ptr;
32 u32 base; 27 u32 base;
33 u32 size; 28 u32 size;
29 const char* name;
34}; 30};
35 31
36// We don't declare the IO regions in here since its handled by other means. 32// We don't declare the IO regions in here since its handled by other means.
37static MemoryArea memory_areas[] = { 33static MemoryArea memory_areas[] = {
38 {&g_exefs_code, PROCESS_IMAGE_VADDR, PROCESS_IMAGE_MAX_SIZE}, 34 {PROCESS_IMAGE_VADDR, PROCESS_IMAGE_MAX_SIZE, "Process Image"}, // ExeFS:/.code is loaded here
39 {&g_heap, HEAP_VADDR, HEAP_SIZE }, 35 {HEAP_VADDR, HEAP_SIZE, "Heap"}, // Application heap (main memory)
40 {&g_shared_mem, SHARED_MEMORY_VADDR, SHARED_MEMORY_SIZE }, 36 {SHARED_MEMORY_VADDR, SHARED_MEMORY_SIZE, "Shared Memory"}, // Shared memory
41 {&g_heap_linear, LINEAR_HEAP_VADDR, LINEAR_HEAP_SIZE }, 37 {LINEAR_HEAP_VADDR, LINEAR_HEAP_SIZE, "Linear Heap"}, // Linear heap (main memory)
42 {&g_vram, VRAM_VADDR, VRAM_SIZE }, 38 {VRAM_VADDR, VRAM_SIZE, "VRAM"}, // Video memory (VRAM)
43 {&g_dsp_mem, DSP_RAM_VADDR, DSP_RAM_SIZE }, 39 {DSP_RAM_VADDR, DSP_RAM_SIZE, "DSP RAM"}, // DSP memory
44 {&g_tls_mem, TLS_AREA_VADDR, TLS_AREA_SIZE }, 40 {TLS_AREA_VADDR, TLS_AREA_SIZE, "TLS Area"}, // TLS memory
45}; 41};
46 42
47/// Represents a block of memory mapped by ControlMemory/MapMemoryBlock 43/// Represents a block of memory mapped by ControlMemory/MapMemoryBlock
@@ -135,27 +131,34 @@ VAddr PhysicalToVirtualAddress(const PAddr addr) {
135 return addr | 0x80000000; 131 return addr | 0x80000000;
136} 132}
137 133
134// TODO(yuriks): Move this into Process
135static Kernel::VMManager address_space;
136
138void Init() { 137void Init() {
138 using namespace Kernel;
139
139 InitMemoryMap(); 140 InitMemoryMap();
140 141
141 for (MemoryArea& area : memory_areas) { 142 for (MemoryArea& area : memory_areas) {
142 *area.ptr = new u8[area.size]; 143 auto block = std::make_shared<std::vector<u8>>(area.size);
143 MapMemoryRegion(area.base, area.size, *area.ptr); 144 address_space.MapMemoryBlock(area.base, std::move(block), 0, area.size, MemoryState::Private).Unwrap();
144 } 145 }
145 MapMemoryRegion(CONFIG_MEMORY_VADDR, CONFIG_MEMORY_SIZE, (u8*)&ConfigMem::config_mem);
146 MapMemoryRegion(SHARED_PAGE_VADDR, SHARED_PAGE_SIZE, (u8*)&SharedPage::shared_page);
147 146
148 LOG_DEBUG(HW_Memory, "initialized OK, RAM at %p", g_heap); 147 auto cfg_mem_vma = address_space.MapBackingMemory(CONFIG_MEMORY_VADDR,
148 (u8*)&ConfigMem::config_mem, CONFIG_MEMORY_SIZE, MemoryState::Shared).MoveFrom();
149 address_space.Reprotect(cfg_mem_vma, VMAPermission::Read);
150
151 auto shared_page_vma = address_space.MapBackingMemory(SHARED_PAGE_VADDR,
152 (u8*)&SharedPage::shared_page, SHARED_PAGE_SIZE, MemoryState::Shared).MoveFrom();
153 address_space.Reprotect(shared_page_vma, VMAPermission::Read);
154
155 LOG_DEBUG(HW_Memory, "initialized OK");
149} 156}
150 157
151void Shutdown() { 158void Shutdown() {
152 heap_map.clear(); 159 heap_map.clear();
153 heap_linear_map.clear(); 160 heap_linear_map.clear();
154 161 address_space.Reset();
155 for (MemoryArea& area : memory_areas) {
156 delete[] *area.ptr;
157 *area.ptr = nullptr;
158 }
159 162
160 LOG_DEBUG(HW_Memory, "shutdown OK"); 163 LOG_DEBUG(HW_Memory, "shutdown OK");
161} 164}
diff --git a/src/core/mem_map.h b/src/core/mem_map.h
index 945815cd6..ba50914a8 100644
--- a/src/core/mem_map.h
+++ b/src/core/mem_map.h
@@ -8,14 +8,6 @@
8 8
9namespace Memory { 9namespace Memory {
10 10
11extern u8* g_exefs_code; ///< ExeFS:/.code is loaded here
12extern u8* g_heap; ///< Application heap (main memory)
13extern u8* g_shared_mem; ///< Shared memory
14extern u8* g_heap_linear; ///< Linear heap (main memory)
15extern u8* g_vram; ///< Video memory (VRAM)
16extern u8* g_dsp_mem; ///< DSP memory
17extern u8* g_tls_mem; ///< TLS memory
18
19void Init(); 11void Init();
20void Shutdown(); 12void Shutdown();
21 13
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index 5d8069acd..28844a915 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -14,12 +14,10 @@
14#include "core/hw/hw.h" 14#include "core/hw/hw.h"
15#include "core/mem_map.h" 15#include "core/mem_map.h"
16#include "core/memory.h" 16#include "core/memory.h"
17#include "core/memory_setup.h"
17 18
18namespace Memory { 19namespace Memory {
19 20
20const u32 PAGE_MASK = PAGE_SIZE - 1;
21const int PAGE_BITS = 12;
22
23enum class PageType { 21enum class PageType {
24 /// Page is unmapped and should cause an access error. 22 /// Page is unmapped and should cause an access error.
25 Unmapped, 23 Unmapped,
@@ -64,7 +62,7 @@ static void MapPages(u32 base, u32 size, u8* memory, PageType type) {
64 while (base != end) { 62 while (base != end) {
65 ASSERT_MSG(base < PageTable::NUM_ENTRIES, "out of range mapping at %08X", base); 63 ASSERT_MSG(base < PageTable::NUM_ENTRIES, "out of range mapping at %08X", base);
66 64
67 if (current_page_table->attributes[base] != PageType::Unmapped) { 65 if (current_page_table->attributes[base] != PageType::Unmapped && type != PageType::Unmapped) {
68 LOG_ERROR(HW_Memory, "overlapping memory ranges at %08X", base * PAGE_SIZE); 66 LOG_ERROR(HW_Memory, "overlapping memory ranges at %08X", base * PAGE_SIZE);
69 } 67 }
70 current_page_table->attributes[base] = type; 68 current_page_table->attributes[base] = type;
@@ -92,6 +90,12 @@ void MapIoRegion(VAddr base, u32 size) {
92 MapPages(base / PAGE_SIZE, size / PAGE_SIZE, nullptr, PageType::Special); 90 MapPages(base / PAGE_SIZE, size / PAGE_SIZE, nullptr, PageType::Special);
93} 91}
94 92
93void UnmapRegion(VAddr base, u32 size) {
94 ASSERT_MSG((size & PAGE_MASK) == 0, "non-page aligned size: %08X", size);
95 ASSERT_MSG((base & PAGE_MASK) == 0, "non-page aligned base: %08X", base);
96 MapPages(base / PAGE_SIZE, size / PAGE_SIZE, nullptr, PageType::Unmapped);
97}
98
95template <typename T> 99template <typename T>
96T Read(const VAddr vaddr) { 100T Read(const VAddr vaddr) {
97 const u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; 101 const u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS];
diff --git a/src/core/memory.h b/src/core/memory.h
index 2d225801b..0b8ff9ec4 100644
--- a/src/core/memory.h
+++ b/src/core/memory.h
@@ -97,7 +97,7 @@ enum : VAddr {
97 SHARED_PAGE_VADDR_END = SHARED_PAGE_VADDR + SHARED_PAGE_SIZE, 97 SHARED_PAGE_VADDR_END = SHARED_PAGE_VADDR + SHARED_PAGE_SIZE,
98 98
99 // TODO(yuriks): The size of this area is dynamic, the kernel grows 99 // TODO(yuriks): The size of this area is dynamic, the kernel grows
100 // it as more and more threads are created. For now we'll just use a 100 // it as more and more threads are created. For now we'll just use a
101 // hardcoded value. 101 // hardcoded value.
102 /// Area where TLS (Thread-Local Storage) buffers are allocated. 102 /// Area where TLS (Thread-Local Storage) buffers are allocated.
103 TLS_AREA_VADDR = 0x1FF82000, 103 TLS_AREA_VADDR = 0x1FF82000,
diff --git a/src/core/memory_setup.h b/src/core/memory_setup.h
index 46263495f..361bfc816 100644
--- a/src/core/memory_setup.h
+++ b/src/core/memory_setup.h
@@ -6,8 +6,13 @@
6 6
7#include "common/common_types.h" 7#include "common/common_types.h"
8 8
9#include "core/memory.h"
10
9namespace Memory { 11namespace Memory {
10 12
13const u32 PAGE_MASK = PAGE_SIZE - 1;
14const int PAGE_BITS = 12;
15
11void InitMemoryMap(); 16void InitMemoryMap();
12 17
13/** 18/**
@@ -26,4 +31,6 @@ void MapMemoryRegion(VAddr base, u32 size, u8* target);
26 */ 31 */
27void MapIoRegion(VAddr base, u32 size); 32void MapIoRegion(VAddr base, u32 size);
28 33
34void UnmapRegion(VAddr base, u32 size);
35
29} 36}
diff --git a/src/core/settings.h b/src/core/settings.h
index 54c1023b8..5a70d157a 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -35,7 +35,6 @@ struct Values {
35 int pad_cright_key; 35 int pad_cright_key;
36 36
37 // Core 37 // Core
38 int gpu_refresh_rate;
39 int frame_skip; 38 int frame_skip;
40 39
41 // Data Storage 40 // Data Storage
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index 0258a3255..5c7f4ae18 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -29,11 +29,9 @@ set(HEADERS
29 renderer_opengl/pica_to_gl.h 29 renderer_opengl/pica_to_gl.h
30 renderer_opengl/renderer_opengl.h 30 renderer_opengl/renderer_opengl.h
31 clipper.h 31 clipper.h
32 color.h
33 command_processor.h 32 command_processor.h
34 gpu_debugger.h 33 gpu_debugger.h
35 hwrasterizer_base.h 34 hwrasterizer_base.h
36 math.h
37 pica.h 35 pica.h
38 primitive_assembly.h 36 primitive_assembly.h
39 rasterizer.h 37 rasterizer.h
diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp
index 100d8c7c1..b46fadd9f 100644
--- a/src/video_core/command_processor.cpp
+++ b/src/video_core/command_processor.cpp
@@ -56,7 +56,17 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) {
56 // Trigger IRQ 56 // Trigger IRQ
57 case PICA_REG_INDEX(trigger_irq): 57 case PICA_REG_INDEX(trigger_irq):
58 GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::P3D); 58 GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::P3D);
59 return; 59 break;
60
61 case PICA_REG_INDEX_WORKAROUND(command_buffer.trigger[0], 0x23c):
62 case PICA_REG_INDEX_WORKAROUND(command_buffer.trigger[1], 0x23d):
63 {
64 unsigned index = id - PICA_REG_INDEX(command_buffer.trigger[0]);
65 u32* head_ptr = (u32*)Memory::GetPhysicalPointer(regs.command_buffer.GetPhysicalAddress(index));
66 g_state.cmd_list.head_ptr = g_state.cmd_list.current_ptr = head_ptr;
67 g_state.cmd_list.length = regs.command_buffer.GetSize(index) / sizeof(u32);
68 break;
69 }
60 70
61 // It seems like these trigger vertex rendering 71 // It seems like these trigger vertex rendering
62 case PICA_REG_INDEX(trigger_draw): 72 case PICA_REG_INDEX(trigger_draw):
@@ -136,7 +146,7 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) {
136 input.attr[i][0].ToFloat32(), input.attr[i][1].ToFloat32(), 146 input.attr[i][0].ToFloat32(), input.attr[i][1].ToFloat32(),
137 input.attr[i][2].ToFloat32(), input.attr[i][3].ToFloat32()); 147 input.attr[i][2].ToFloat32(), input.attr[i][3].ToFloat32());
138 } 148 }
139 149
140 // Load per-vertex data from the loader arrays 150 // Load per-vertex data from the loader arrays
141 for (unsigned int comp = 0; comp < vertex_attribute_elements[i]; ++comp) { 151 for (unsigned int comp = 0; comp < vertex_attribute_elements[i]; ++comp) {
142 const u8* srcdata = Memory::GetPhysicalPointer(vertex_attribute_sources[i] + vertex_attribute_strides[i] * vertex + comp * vertex_attribute_element_size[i]); 152 const u8* srcdata = Memory::GetPhysicalPointer(vertex_attribute_sources[i] + vertex_attribute_strides[i] * vertex + comp * vertex_attribute_element_size[i]);
@@ -193,7 +203,7 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) {
193 const Pica::VertexShader::OutputVertex& v2) { 203 const Pica::VertexShader::OutputVertex& v2) {
194 VideoCore::g_renderer->hw_rasterizer->AddTriangle(v0, v1, v2); 204 VideoCore::g_renderer->hw_rasterizer->AddTriangle(v0, v1, v2);
195 }; 205 };
196 206
197 primitive_assembler.SubmitVertex(output, AddHWTriangle); 207 primitive_assembler.SubmitVertex(output, AddHWTriangle);
198 } else { 208 } else {
199 // Send to triangle clipper 209 // Send to triangle clipper
@@ -282,7 +292,7 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) {
282 } 292 }
283 break; 293 break;
284 } 294 }
285 295
286 // Load default vertex input attributes 296 // Load default vertex input attributes
287 case PICA_REG_INDEX_WORKAROUND(vs_default_attributes_setup.set_value[0], 0x233): 297 case PICA_REG_INDEX_WORKAROUND(vs_default_attributes_setup.set_value[0], 0x233):
288 case PICA_REG_INDEX_WORKAROUND(vs_default_attributes_setup.set_value[1], 0x234): 298 case PICA_REG_INDEX_WORKAROUND(vs_default_attributes_setup.set_value[1], 0x234):
@@ -306,7 +316,7 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) {
306 } 316 }
307 317
308 Math::Vec4<float24>& attribute = g_state.vs.default_attributes[setup.index]; 318 Math::Vec4<float24>& attribute = g_state.vs.default_attributes[setup.index];
309 319
310 // NOTE: The destination component order indeed is "backwards" 320 // NOTE: The destination component order indeed is "backwards"
311 attribute.w = float24::FromRawFloat24(default_attr_write_buffer[0] >> 8); 321 attribute.w = float24::FromRawFloat24(default_attr_write_buffer[0] >> 8);
312 attribute.z = float24::FromRawFloat24(((default_attr_write_buffer[0] & 0xFF) << 16) | ((default_attr_write_buffer[1] >> 16) & 0xFFFF)); 322 attribute.z = float24::FromRawFloat24(((default_attr_write_buffer[0] & 0xFF) << 16) | ((default_attr_write_buffer[1] >> 16) & 0xFFFF));
@@ -363,38 +373,34 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) {
363 g_debug_context->OnEvent(DebugContext::Event::CommandProcessed, reinterpret_cast<void*>(&id)); 373 g_debug_context->OnEvent(DebugContext::Event::CommandProcessed, reinterpret_cast<void*>(&id));
364} 374}
365 375
366static std::ptrdiff_t ExecuteCommandBlock(const u32* first_command_word) {
367 const CommandHeader& header = *(const CommandHeader*)(&first_command_word[1]);
368
369 u32* read_pointer = (u32*)first_command_word;
370
371 const u32 write_mask = ((header.parameter_mask & 0x1) ? (0xFFu << 0) : 0u) |
372 ((header.parameter_mask & 0x2) ? (0xFFu << 8) : 0u) |
373 ((header.parameter_mask & 0x4) ? (0xFFu << 16) : 0u) |
374 ((header.parameter_mask & 0x8) ? (0xFFu << 24) : 0u);
375
376 WritePicaReg(header.cmd_id, *read_pointer, write_mask);
377 read_pointer += 2;
378
379 for (unsigned int i = 1; i < 1+header.extra_data_length; ++i) {
380 u32 cmd = header.cmd_id + ((header.group_commands) ? i : 0);
381 WritePicaReg(cmd, *read_pointer, write_mask);
382 ++read_pointer;
383 }
384
385 // align read pointer to 8 bytes
386 if ((first_command_word - read_pointer) % 2)
387 ++read_pointer;
388
389 return read_pointer - first_command_word;
390}
391
392void ProcessCommandList(const u32* list, u32 size) { 376void ProcessCommandList(const u32* list, u32 size) {
393 u32* read_pointer = (u32*)list; 377 g_state.cmd_list.head_ptr = g_state.cmd_list.current_ptr = list;
394 u32 list_length = size / sizeof(u32); 378 g_state.cmd_list.length = size / sizeof(u32);
395 379
396 while (read_pointer < list + list_length) { 380 while (g_state.cmd_list.current_ptr < g_state.cmd_list.head_ptr + g_state.cmd_list.length) {
397 read_pointer += ExecuteCommandBlock(read_pointer); 381 // Expand a 4-bit mask to 4-byte mask, e.g. 0b0101 -> 0x00FF00FF
382 static const u32 expand_bits_to_bytes[] = {
383 0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff,
384 0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff,
385 0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff,
386 0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff
387 };
388
389 // Align read pointer to 8 bytes
390 if ((g_state.cmd_list.head_ptr - g_state.cmd_list.current_ptr) % 2 != 0)
391 ++g_state.cmd_list.current_ptr;
392
393 u32 value = *g_state.cmd_list.current_ptr++;
394 const CommandHeader header = { *g_state.cmd_list.current_ptr++ };
395 const u32 write_mask = expand_bits_to_bytes[header.parameter_mask];
396 u32 cmd = header.cmd_id;
397
398 WritePicaReg(cmd, value, write_mask);
399
400 for (unsigned i = 0; i < header.extra_data_length; ++i) {
401 u32 cmd = header.cmd_id + (header.group_commands ? i + 1 : 0);
402 WritePicaReg(cmd, *g_state.cmd_list.current_ptr++, write_mask);
403 }
398 } 404 }
399} 405}
400 406
diff --git a/src/video_core/debug_utils/debug_utils.cpp b/src/video_core/debug_utils/debug_utils.cpp
index 7987b922c..7b8ab72b6 100644
--- a/src/video_core/debug_utils/debug_utils.cpp
+++ b/src/video_core/debug_utils/debug_utils.cpp
@@ -17,11 +17,11 @@
17#include <nihstro/shader_binary.h> 17#include <nihstro/shader_binary.h>
18 18
19#include "common/assert.h" 19#include "common/assert.h"
20#include "common/color.h"
20#include "common/file_util.h" 21#include "common/file_util.h"
21#include "common/math_util.h" 22#include "common/math_util.h"
23#include "common/vector_math.h"
22 24
23#include "video_core/color.h"
24#include "video_core/math.h"
25#include "video_core/pica.h" 25#include "video_core/pica.h"
26#include "video_core/utils.h" 26#include "video_core/utils.h"
27#include "video_core/video_core.h" 27#include "video_core/video_core.h"
@@ -319,7 +319,7 @@ const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const Texture
319 // TODO(neobrain): Fix code design to unify vertical block offsets! 319 // TODO(neobrain): Fix code design to unify vertical block offsets!
320 source += coarse_y * info.stride; 320 source += coarse_y * info.stride;
321 } 321 }
322 322
323 // TODO: Assert that width/height are multiples of block dimensions 323 // TODO: Assert that width/height are multiples of block dimensions
324 324
325 switch (info.format) { 325 switch (info.format) {
diff --git a/src/video_core/debug_utils/debug_utils.h b/src/video_core/debug_utils/debug_utils.h
index f361a5385..7926d64ec 100644
--- a/src/video_core/debug_utils/debug_utils.h
+++ b/src/video_core/debug_utils/debug_utils.h
@@ -12,7 +12,8 @@
12#include <mutex> 12#include <mutex>
13#include <vector> 13#include <vector>
14 14
15#include "video_core/math.h" 15#include "common/vector_math.h"
16
16#include "video_core/pica.h" 17#include "video_core/pica.h"
17 18
18namespace Pica { 19namespace Pica {
diff --git a/src/video_core/pica.h b/src/video_core/pica.h
index b67dce1a9..9628a7589 100644
--- a/src/video_core/pica.h
+++ b/src/video_core/pica.h
@@ -15,8 +15,7 @@
15#include "common/common_funcs.h" 15#include "common/common_funcs.h"
16#include "common/common_types.h" 16#include "common/common_types.h"
17#include "common/logging/log.h" 17#include "common/logging/log.h"
18 18#include "common/vector_math.h"
19#include "math.h"
20 19
21namespace Pica { 20namespace Pica {
22 21
@@ -162,6 +161,25 @@ struct Regs {
162 ETC1A4 = 13, // compressed 161 ETC1A4 = 13, // compressed
163 }; 162 };
164 163
164 enum class LogicOp : u32 {
165 Clear = 0,
166 And = 1,
167 AndReverse = 2,
168 Copy = 3,
169 Set = 4,
170 CopyInverted = 5,
171 NoOp = 6,
172 Invert = 7,
173 Nand = 8,
174 Or = 9,
175 Nor = 10,
176 Xor = 11,
177 Equiv = 12,
178 AndInverted = 13,
179 OrReverse = 14,
180 OrInverted = 15,
181 };
182
165 static unsigned NibblesPerPixel(TextureFormat format) { 183 static unsigned NibblesPerPixel(TextureFormat format) {
166 switch (format) { 184 switch (format) {
167 case TextureFormat::RGBA8: 185 case TextureFormat::RGBA8:
@@ -221,6 +239,7 @@ struct Regs {
221 enum class Source : u32 { 239 enum class Source : u32 {
222 PrimaryColor = 0x0, 240 PrimaryColor = 0x0,
223 PrimaryFragmentColor = 0x1, 241 PrimaryFragmentColor = 0x1,
242 SecondaryFragmentColor = 0x2,
224 243
225 Texture0 = 0x3, 244 Texture0 = 0x3,
226 Texture1 = 0x4, 245 Texture1 = 0x4,
@@ -337,7 +356,7 @@ struct Regs {
337 return (stage_index < 4) && (update_mask_a & (1 << stage_index)); 356 return (stage_index < 4) && (update_mask_a & (1 << stage_index));
338 } 357 }
339 } tev_combiner_buffer_input; 358 } tev_combiner_buffer_input;
340 359
341 INSERT_PADDING_WORDS(0xf); 360 INSERT_PADDING_WORDS(0xf);
342 TevStageConfig tev_stage4; 361 TevStageConfig tev_stage4;
343 INSERT_PADDING_WORDS(0x3); 362 INSERT_PADDING_WORDS(0x3);
@@ -353,9 +372,9 @@ struct Regs {
353 INSERT_PADDING_WORDS(0x2); 372 INSERT_PADDING_WORDS(0x2);
354 373
355 const std::array<Regs::TevStageConfig,6> GetTevStages() const { 374 const std::array<Regs::TevStageConfig,6> GetTevStages() const {
356 return { tev_stage0, tev_stage1, 375 return {{ tev_stage0, tev_stage1,
357 tev_stage2, tev_stage3, 376 tev_stage2, tev_stage3,
358 tev_stage4, tev_stage5 }; 377 tev_stage4, tev_stage5 }};
359 }; 378 };
360 379
361 enum class BlendEquation : u32 { 380 enum class BlendEquation : u32 {
@@ -413,12 +432,8 @@ struct Regs {
413 } alpha_blending; 432 } alpha_blending;
414 433
415 union { 434 union {
416 enum Op { 435 BitField<0, 4, LogicOp> logic_op;
417 Set = 4, 436 };
418 };
419
420 BitField<0, 4, Op> op;
421 } logic_op;
422 437
423 union { 438 union {
424 BitField< 0, 8, u32> r; 439 BitField< 0, 8, u32> r;
@@ -703,12 +718,38 @@ struct Regs {
703 struct { 718 struct {
704 // Index of the current default attribute 719 // Index of the current default attribute
705 u32 index; 720 u32 index;
706 721
707 // Writing to these registers sets the "current" default attribute. 722 // Writing to these registers sets the "current" default attribute.
708 u32 set_value[3]; 723 u32 set_value[3];
709 } vs_default_attributes_setup; 724 } vs_default_attributes_setup;
710 725
711 INSERT_PADDING_WORDS(0x28); 726 INSERT_PADDING_WORDS(0x2);
727
728 struct {
729 // There are two channels that can be used to configure the next command buffer, which
730 // can be then executed by writing to the "trigger" registers. There are two reasons why a
731 // game might use this feature:
732 // 1) With this, an arbitrary number of additional command buffers may be executed in
733 // sequence without requiring any intervention of the CPU after the initial one is
734 // kicked off.
735 // 2) Games can configure these registers to provide a command list subroutine mechanism.
736
737 BitField< 0, 20, u32> size[2]; ///< Size (in bytes / 8) of each channel's command buffer
738 BitField< 0, 28, u32> addr[2]; ///< Physical address / 8 of each channel's command buffer
739 u32 trigger[2]; ///< Triggers execution of the channel's command buffer when written to
740
741 unsigned GetSize(unsigned index) const {
742 ASSERT(index < 2);
743 return 8 * size[index];
744 }
745
746 PAddr GetPhysicalAddress(unsigned index) const {
747 ASSERT(index < 2);
748 return (PAddr)(8 * addr[index]);
749 }
750 } command_buffer;
751
752 INSERT_PADDING_WORDS(0x20);
712 753
713 enum class TriangleTopology : u32 { 754 enum class TriangleTopology : u32 {
714 List = 0, 755 List = 0,
@@ -861,6 +902,7 @@ struct Regs {
861 ADD_FIELD(trigger_draw); 902 ADD_FIELD(trigger_draw);
862 ADD_FIELD(trigger_draw_indexed); 903 ADD_FIELD(trigger_draw_indexed);
863 ADD_FIELD(vs_default_attributes_setup); 904 ADD_FIELD(vs_default_attributes_setup);
905 ADD_FIELD(command_buffer);
864 ADD_FIELD(triangle_topology); 906 ADD_FIELD(triangle_topology);
865 ADD_FIELD(vs_bool_uniforms); 907 ADD_FIELD(vs_bool_uniforms);
866 ADD_FIELD(vs_int_uniforms); 908 ADD_FIELD(vs_int_uniforms);
@@ -938,6 +980,7 @@ ASSERT_REG_POSITION(num_vertices, 0x228);
938ASSERT_REG_POSITION(trigger_draw, 0x22e); 980ASSERT_REG_POSITION(trigger_draw, 0x22e);
939ASSERT_REG_POSITION(trigger_draw_indexed, 0x22f); 981ASSERT_REG_POSITION(trigger_draw_indexed, 0x22f);
940ASSERT_REG_POSITION(vs_default_attributes_setup, 0x232); 982ASSERT_REG_POSITION(vs_default_attributes_setup, 0x232);
983ASSERT_REG_POSITION(command_buffer, 0x238);
941ASSERT_REG_POSITION(triangle_topology, 0x25e); 984ASSERT_REG_POSITION(triangle_topology, 0x25e);
942ASSERT_REG_POSITION(vs_bool_uniforms, 0x2b0); 985ASSERT_REG_POSITION(vs_bool_uniforms, 0x2b0);
943ASSERT_REG_POSITION(vs_int_uniforms, 0x2b1); 986ASSERT_REG_POSITION(vs_int_uniforms, 0x2b1);
@@ -1053,21 +1096,12 @@ private:
1053 float value; 1096 float value;
1054}; 1097};
1055 1098
1056union CommandHeader {
1057 CommandHeader(u32 h) : hex(h) {}
1058
1059 u32 hex;
1060
1061 BitField< 0, 16, u32> cmd_id;
1062 BitField<16, 4, u32> parameter_mask;
1063 BitField<20, 11, u32> extra_data_length;
1064 BitField<31, 1, u32> group_commands;
1065};
1066
1067/// Struct used to describe current Pica state 1099/// Struct used to describe current Pica state
1068struct State { 1100struct State {
1101 /// Pica registers
1069 Regs regs; 1102 Regs regs;
1070 1103
1104 /// Vertex shader memory
1071 struct { 1105 struct {
1072 struct { 1106 struct {
1073 Math::Vec4<float24> f[96]; 1107 Math::Vec4<float24> f[96];
@@ -1080,6 +1114,13 @@ struct State {
1080 std::array<u32, 1024> program_code; 1114 std::array<u32, 1024> program_code;
1081 std::array<u32, 1024> swizzle_data; 1115 std::array<u32, 1024> swizzle_data;
1082 } vs; 1116 } vs;
1117
1118 /// Current Pica command list
1119 struct {
1120 const u32* head_ptr;
1121 const u32* current_ptr;
1122 u32 length;
1123 } cmd_list;
1083}; 1124};
1084 1125
1085/// Initialize Pica state 1126/// Initialize Pica state
diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp
index 767ff4205..59d156ee7 100644
--- a/src/video_core/rasterizer.cpp
+++ b/src/video_core/rasterizer.cpp
@@ -4,6 +4,7 @@
4 4
5#include <algorithm> 5#include <algorithm>
6 6
7#include "common/color.h"
7#include "common/common_types.h" 8#include "common/common_types.h"
8#include "common/math_util.h" 9#include "common/math_util.h"
9#include "common/profiler.h" 10#include "common/profiler.h"
@@ -13,7 +14,6 @@
13 14
14#include "debug_utils/debug_utils.h" 15#include "debug_utils/debug_utils.h"
15#include "math.h" 16#include "math.h"
16#include "color.h"
17#include "pica.h" 17#include "pica.h"
18#include "rasterizer.h" 18#include "rasterizer.h"
19#include "vertex_shader.h" 19#include "vertex_shader.h"
@@ -104,7 +104,7 @@ static u32 GetDepth(int x, int y) {
104 u8* depth_buffer = Memory::GetPhysicalPointer(addr); 104 u8* depth_buffer = Memory::GetPhysicalPointer(addr);
105 105
106 y = framebuffer.height - y; 106 y = framebuffer.height - y;
107 107
108 const u32 coarse_y = y & ~7; 108 const u32 coarse_y = y & ~7;
109 u32 bytes_per_pixel = Regs::BytesPerDepthPixel(framebuffer.depth_format); 109 u32 bytes_per_pixel = Regs::BytesPerDepthPixel(framebuffer.depth_format);
110 u32 stride = framebuffer.width * bytes_per_pixel; 110 u32 stride = framebuffer.width * bytes_per_pixel;
@@ -402,11 +402,16 @@ static void ProcessTriangleInternal(const VertexShader::OutputVertex& v0,
402 402
403 auto GetSource = [&](Source source) -> Math::Vec4<u8> { 403 auto GetSource = [&](Source source) -> Math::Vec4<u8> {
404 switch (source) { 404 switch (source) {
405 // TODO: What's the difference between these two?
406 case Source::PrimaryColor: 405 case Source::PrimaryColor:
406
407 // HACK: Until we implement fragment lighting, use primary_color
407 case Source::PrimaryFragmentColor: 408 case Source::PrimaryFragmentColor:
408 return primary_color; 409 return primary_color;
409 410
411 // HACK: Until we implement fragment lighting, use zero
412 case Source::SecondaryFragmentColor:
413 return {0, 0, 0, 0};
414
410 case Source::Texture0: 415 case Source::Texture0:
411 return texture_color[0]; 416 return texture_color[0];
412 417
@@ -570,6 +575,13 @@ static void ProcessTriangleInternal(const VertexShader::OutputVertex& v0,
570 case Operation::Add: 575 case Operation::Add:
571 return std::min(255, input[0] + input[1]); 576 return std::min(255, input[0] + input[1]);
572 577
578 case Operation::AddSigned:
579 {
580 // TODO(bunnei): Verify that the color conversion from (float) 0.5f to (byte) 128 is correct
581 auto result = static_cast<int>(input[0]) + static_cast<int>(input[1]) - 128;
582 return static_cast<u8>(MathUtil::Clamp<int>(result, 0, 255));
583 }
584
573 case Operation::Lerp: 585 case Operation::Lerp:
574 return (input[0] * input[2] + input[1] * (255 - input[2])) / 255; 586 return (input[0] * input[2] + input[1] * (255 - input[2])) / 255;
575 587
@@ -808,10 +820,9 @@ static void ProcessTriangleInternal(const VertexShader::OutputVertex& v0,
808 } 820 }
809 }; 821 };
810 822
811 using BlendEquation = Regs::BlendEquation;
812 static auto EvaluateBlendEquation = [](const Math::Vec4<u8>& src, const Math::Vec4<u8>& srcfactor, 823 static auto EvaluateBlendEquation = [](const Math::Vec4<u8>& src, const Math::Vec4<u8>& srcfactor,
813 const Math::Vec4<u8>& dest, const Math::Vec4<u8>& destfactor, 824 const Math::Vec4<u8>& dest, const Math::Vec4<u8>& destfactor,
814 BlendEquation equation) { 825 Regs::BlendEquation equation) {
815 Math::Vec4<int> result; 826 Math::Vec4<int> result;
816 827
817 auto src_result = (src * srcfactor).Cast<int>(); 828 auto src_result = (src * srcfactor).Cast<int>();
@@ -866,8 +877,63 @@ static void ProcessTriangleInternal(const VertexShader::OutputVertex& v0,
866 blend_output = EvaluateBlendEquation(combiner_output, srcfactor, dest, dstfactor, params.blend_equation_rgb); 877 blend_output = EvaluateBlendEquation(combiner_output, srcfactor, dest, dstfactor, params.blend_equation_rgb);
867 blend_output.a() = EvaluateBlendEquation(combiner_output, srcfactor, dest, dstfactor, params.blend_equation_a).a(); 878 blend_output.a() = EvaluateBlendEquation(combiner_output, srcfactor, dest, dstfactor, params.blend_equation_a).a();
868 } else { 879 } else {
869 LOG_CRITICAL(HW_GPU, "logic op: %x", output_merger.logic_op); 880 static auto LogicOp = [](u8 src, u8 dest, Regs::LogicOp op) -> u8 {
870 UNIMPLEMENTED(); 881 switch (op) {
882 case Regs::LogicOp::Clear:
883 return 0;
884
885 case Regs::LogicOp::And:
886 return src & dest;
887
888 case Regs::LogicOp::AndReverse:
889 return src & ~dest;
890
891 case Regs::LogicOp::Copy:
892 return src;
893
894 case Regs::LogicOp::Set:
895 return 255;
896
897 case Regs::LogicOp::CopyInverted:
898 return ~src;
899
900 case Regs::LogicOp::NoOp:
901 return dest;
902
903 case Regs::LogicOp::Invert:
904 return ~dest;
905
906 case Regs::LogicOp::Nand:
907 return ~(src & dest);
908
909 case Regs::LogicOp::Or:
910 return src | dest;
911
912 case Regs::LogicOp::Nor:
913 return ~(src | dest);
914
915 case Regs::LogicOp::Xor:
916 return src ^ dest;
917
918 case Regs::LogicOp::Equiv:
919 return ~(src ^ dest);
920
921 case Regs::LogicOp::AndInverted:
922 return ~src & dest;
923
924 case Regs::LogicOp::OrReverse:
925 return src | ~dest;
926
927 case Regs::LogicOp::OrInverted:
928 return ~src | dest;
929 }
930 };
931
932 blend_output = Math::MakeVec(
933 LogicOp(combiner_output.r(), dest.r(), output_merger.logic_op),
934 LogicOp(combiner_output.g(), dest.g(), output_merger.logic_op),
935 LogicOp(combiner_output.b(), dest.b(), output_merger.logic_op),
936 LogicOp(combiner_output.a(), dest.a(), output_merger.logic_op));
871 } 937 }
872 938
873 const Math::Vec4<u8> result = { 939 const Math::Vec4<u8> result = {
diff --git a/src/video_core/renderer_opengl/generated/gl_3_2_core.c b/src/video_core/renderer_opengl/generated/gl_3_2_core.c
index ef29972d7..95fd29c0a 100644
--- a/src/video_core/renderer_opengl/generated/gl_3_2_core.c
+++ b/src/video_core/renderer_opengl/generated/gl_3_2_core.c
@@ -62,9 +62,9 @@ static int TestPointer(const PROC pTest)
62 ptrdiff_t iTest; 62 ptrdiff_t iTest;
63 if(!pTest) return 0; 63 if(!pTest) return 0;
64 iTest = (ptrdiff_t)pTest; 64 iTest = (ptrdiff_t)pTest;
65 65
66 if(iTest == 1 || iTest == 2 || iTest == 3 || iTest == -1) return 0; 66 if(iTest == 1 || iTest == 2 || iTest == 3 || iTest == -1) return 0;
67 67
68 return 1; 68 return 1;
69} 69}
70 70
@@ -79,7 +79,7 @@ static PROC WinGetProcAddress(const char *name)
79 glMod = GetModuleHandleA("OpenGL32.dll"); 79 glMod = GetModuleHandleA("OpenGL32.dll");
80 return (PROC)GetProcAddress(glMod, (LPCSTR)name); 80 return (PROC)GetProcAddress(glMod, (LPCSTR)name);
81} 81}
82 82
83#define IntGetProcAddress(name) WinGetProcAddress(name) 83#define IntGetProcAddress(name) WinGetProcAddress(name)
84#else 84#else
85 #if defined(__APPLE__) 85 #if defined(__APPLE__)
@@ -1083,7 +1083,7 @@ static ogl_StrToExtMap *FindExtEntry(const char *extensionName)
1083 if(strcmp(extensionName, currLoc->extensionName) == 0) 1083 if(strcmp(extensionName, currLoc->extensionName) == 0)
1084 return currLoc; 1084 return currLoc;
1085 } 1085 }
1086 1086
1087 return NULL; 1087 return NULL;
1088} 1088}
1089 1089
@@ -1135,15 +1135,15 @@ int ogl_LoadFunctions()
1135{ 1135{
1136 int numFailed = 0; 1136 int numFailed = 0;
1137 ClearExtensionVars(); 1137 ClearExtensionVars();
1138 1138
1139 _ptrc_glGetIntegerv = (void (CODEGEN_FUNCPTR *)(GLenum, GLint *))IntGetProcAddress("glGetIntegerv"); 1139 _ptrc_glGetIntegerv = (void (CODEGEN_FUNCPTR *)(GLenum, GLint *))IntGetProcAddress("glGetIntegerv");
1140 if(!_ptrc_glGetIntegerv) return ogl_LOAD_FAILED; 1140 if(!_ptrc_glGetIntegerv) return ogl_LOAD_FAILED;
1141 _ptrc_glGetStringi = (const GLubyte * (CODEGEN_FUNCPTR *)(GLenum, GLuint))IntGetProcAddress("glGetStringi"); 1141 _ptrc_glGetStringi = (const GLubyte * (CODEGEN_FUNCPTR *)(GLenum, GLuint))IntGetProcAddress("glGetStringi");
1142 if(!_ptrc_glGetStringi) return ogl_LOAD_FAILED; 1142 if(!_ptrc_glGetStringi) return ogl_LOAD_FAILED;
1143 1143
1144 ProcExtsFromExtList(); 1144 ProcExtsFromExtList();
1145 numFailed = Load_Version_3_2(); 1145 numFailed = Load_Version_3_2();
1146 1146
1147 if(numFailed == 0) 1147 if(numFailed == 0)
1148 return ogl_LOAD_SUCCEEDED; 1148 return ogl_LOAD_SUCCEEDED;
1149 else 1149 else
@@ -1177,7 +1177,7 @@ int ogl_IsVersionGEQ(int majorVersion, int minorVersion)
1177{ 1177{
1178 if(g_major_version == 0) 1178 if(g_major_version == 0)
1179 GetGLVersion(); 1179 GetGLVersion();
1180 1180
1181 if(majorVersion > g_major_version) return 1; 1181 if(majorVersion > g_major_version) return 1;
1182 if(majorVersion < g_major_version) return 0; 1182 if(majorVersion < g_major_version) return 0;
1183 if(minorVersion >= g_minor_version) return 1; 1183 if(minorVersion >= g_minor_version) return 1;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 4b7d099a5..518f79331 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -2,10 +2,11 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "common/color.h"
6
5#include "core/settings.h" 7#include "core/settings.h"
6#include "core/hw/gpu.h" 8#include "core/hw/gpu.h"
7 9
8#include "video_core/color.h"
9#include "video_core/pica.h" 10#include "video_core/pica.h"
10#include "video_core/utils.h" 11#include "video_core/utils.h"
11#include "video_core/renderer_opengl/gl_rasterizer.h" 12#include "video_core/renderer_opengl/gl_rasterizer.h"
@@ -93,14 +94,27 @@ void RasterizerOpenGL::InitObjects() {
93 // Create textures for OGL framebuffer that will be rendered to, initially 1x1 to succeed in framebuffer creation 94 // Create textures for OGL framebuffer that will be rendered to, initially 1x1 to succeed in framebuffer creation
94 fb_color_texture.texture.Create(); 95 fb_color_texture.texture.Create();
95 ReconfigureColorTexture(fb_color_texture, Pica::Regs::ColorFormat::RGBA8, 1, 1); 96 ReconfigureColorTexture(fb_color_texture, Pica::Regs::ColorFormat::RGBA8, 1, 1);
97
98 state.texture_units[0].enabled_2d = true;
99 state.texture_units[0].texture_2d = fb_color_texture.texture.handle;
100 state.Apply();
101
96 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); 102 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
97 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 103 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
98 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 104 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
99 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 105 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
100 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 106 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
101 107
108 state.texture_units[0].texture_2d = 0;
109 state.Apply();
110
102 fb_depth_texture.texture.Create(); 111 fb_depth_texture.texture.Create();
103 ReconfigureDepthTexture(fb_depth_texture, Pica::Regs::DepthFormat::D16, 1, 1); 112 ReconfigureDepthTexture(fb_depth_texture, Pica::Regs::DepthFormat::D16, 1, 1);
113
114 state.texture_units[0].enabled_2d = true;
115 state.texture_units[0].texture_2d = fb_depth_texture.texture.handle;
116 state.Apply();
117
104 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); 118 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
105 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 119 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
106 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 120 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
@@ -109,14 +123,13 @@ void RasterizerOpenGL::InitObjects() {
109 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); 123 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
110 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE); 124 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
111 125
126 state.texture_units[0].texture_2d = 0;
127 state.Apply();
128
112 // Configure OpenGL framebuffer 129 // Configure OpenGL framebuffer
113 framebuffer.Create(); 130 framebuffer.Create();
114 131
115 state.draw.framebuffer = framebuffer.handle; 132 state.draw.framebuffer = framebuffer.handle;
116
117 // Unbind texture to allow binding to framebuffer
118 state.texture_units[0].enabled_2d = true;
119 state.texture_units[0].texture_2d = 0;
120 state.Apply(); 133 state.Apply();
121 134
122 glActiveTexture(GL_TEXTURE0); 135 glActiveTexture(GL_TEXTURE0);
@@ -135,6 +148,7 @@ void RasterizerOpenGL::Reset() {
135 SyncBlendFuncs(); 148 SyncBlendFuncs();
136 SyncBlendColor(); 149 SyncBlendColor();
137 SyncAlphaTest(); 150 SyncAlphaTest();
151 SyncLogicOp();
138 SyncStencilTest(); 152 SyncStencilTest();
139 SyncDepthTest(); 153 SyncDepthTest();
140 154
@@ -203,7 +217,19 @@ void RasterizerOpenGL::DrawTriangles() {
203 217
204 vertex_batch.clear(); 218 vertex_batch.clear();
205 219
206 // TODO: Flush the resource cache at the current depth and color framebuffer addresses for render-to-texture 220 // Flush the resource cache at the current depth and color framebuffer addresses for render-to-texture
221 const auto& regs = Pica::g_state.regs;
222
223 PAddr cur_fb_color_addr = regs.framebuffer.GetColorBufferPhysicalAddress();
224 u32 cur_fb_color_size = Pica::Regs::BytesPerColorPixel(regs.framebuffer.color_format)
225 * regs.framebuffer.GetWidth() * regs.framebuffer.GetHeight();
226
227 PAddr cur_fb_depth_addr = regs.framebuffer.GetDepthBufferPhysicalAddress();
228 u32 cur_fb_depth_size = Pica::Regs::BytesPerDepthPixel(regs.framebuffer.depth_format)
229 * regs.framebuffer.GetWidth() * regs.framebuffer.GetHeight();
230
231 res_cache.NotifyFlush(cur_fb_color_addr, cur_fb_color_size);
232 res_cache.NotifyFlush(cur_fb_depth_addr, cur_fb_depth_size);
207} 233}
208 234
209void RasterizerOpenGL::CommitFramebuffer() { 235void RasterizerOpenGL::CommitFramebuffer() {
@@ -249,6 +275,11 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) {
249 SyncDepthTest(); 275 SyncDepthTest();
250 break; 276 break;
251 277
278 // Logic op
279 case PICA_REG_INDEX(output_merger.logic_op):
280 SyncLogicOp();
281 break;
282
252 // TEV stage 0 283 // TEV stage 0
253 case PICA_REG_INDEX(tev_stage0.color_source1): 284 case PICA_REG_INDEX(tev_stage0.color_source1):
254 SyncTevSources(0, regs.tev_stage0); 285 SyncTevSources(0, regs.tev_stage0);
@@ -350,7 +381,7 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) {
350 case PICA_REG_INDEX(tev_stage5.color_scale): 381 case PICA_REG_INDEX(tev_stage5.color_scale):
351 SyncTevMultipliers(5, regs.tev_stage5); 382 SyncTevMultipliers(5, regs.tev_stage5);
352 break; 383 break;
353 384
354 // TEV combiner buffer color 385 // TEV combiner buffer color
355 case PICA_REG_INDEX(tev_combiner_buffer_color): 386 case PICA_REG_INDEX(tev_combiner_buffer_color):
356 SyncCombinerColor(); 387 SyncCombinerColor();
@@ -465,6 +496,9 @@ void RasterizerOpenGL::ReconfigureColorTexture(TextureInfo& texture, Pica::Regs:
465 glActiveTexture(GL_TEXTURE0); 496 glActiveTexture(GL_TEXTURE0);
466 glTexImage2D(GL_TEXTURE_2D, 0, internal_format, texture.width, texture.height, 0, 497 glTexImage2D(GL_TEXTURE_2D, 0, internal_format, texture.width, texture.height, 0,
467 texture.gl_format, texture.gl_type, nullptr); 498 texture.gl_format, texture.gl_type, nullptr);
499
500 state.texture_units[0].texture_2d = 0;
501 state.Apply();
468} 502}
469 503
470void RasterizerOpenGL::ReconfigureDepthTexture(DepthTextureInfo& texture, Pica::Regs::DepthFormat format, u32 width, u32 height) { 504void RasterizerOpenGL::ReconfigureDepthTexture(DepthTextureInfo& texture, Pica::Regs::DepthFormat format, u32 width, u32 height) {
@@ -484,7 +518,7 @@ void RasterizerOpenGL::ReconfigureDepthTexture(DepthTextureInfo& texture, Pica::
484 case Pica::Regs::DepthFormat::D24: 518 case Pica::Regs::DepthFormat::D24:
485 internal_format = GL_DEPTH_COMPONENT24; 519 internal_format = GL_DEPTH_COMPONENT24;
486 texture.gl_format = GL_DEPTH_COMPONENT; 520 texture.gl_format = GL_DEPTH_COMPONENT;
487 texture.gl_type = GL_UNSIGNED_INT_24_8; 521 texture.gl_type = GL_UNSIGNED_INT;
488 break; 522 break;
489 523
490 case Pica::Regs::DepthFormat::D24S8: 524 case Pica::Regs::DepthFormat::D24S8:
@@ -506,6 +540,9 @@ void RasterizerOpenGL::ReconfigureDepthTexture(DepthTextureInfo& texture, Pica::
506 glActiveTexture(GL_TEXTURE0); 540 glActiveTexture(GL_TEXTURE0);
507 glTexImage2D(GL_TEXTURE_2D, 0, internal_format, texture.width, texture.height, 0, 541 glTexImage2D(GL_TEXTURE_2D, 0, internal_format, texture.width, texture.height, 0,
508 texture.gl_format, texture.gl_type, nullptr); 542 texture.gl_format, texture.gl_type, nullptr);
543
544 state.texture_units[0].texture_2d = 0;
545 state.Apply();
509} 546}
510 547
511void RasterizerOpenGL::SyncFramebuffer() { 548void RasterizerOpenGL::SyncFramebuffer() {
@@ -633,6 +670,10 @@ void RasterizerOpenGL::SyncAlphaTest() {
633 glUniform1f(uniform_alphatest_ref, regs.output_merger.alpha_test.ref / 255.0f); 670 glUniform1f(uniform_alphatest_ref, regs.output_merger.alpha_test.ref / 255.0f);
634} 671}
635 672
673void RasterizerOpenGL::SyncLogicOp() {
674 state.logic_op = PicaToGL::LogicOp(Pica::g_state.regs.output_merger.logic_op);
675}
676
636void RasterizerOpenGL::SyncStencilTest() { 677void RasterizerOpenGL::SyncStencilTest() {
637 // TODO: Implement stencil test, mask, and op 678 // TODO: Implement stencil test, mask, and op
638} 679}
@@ -641,6 +682,10 @@ void RasterizerOpenGL::SyncDepthTest() {
641 const auto& regs = Pica::g_state.regs; 682 const auto& regs = Pica::g_state.regs;
642 state.depth.test_enabled = (regs.output_merger.depth_test_enable == 1); 683 state.depth.test_enabled = (regs.output_merger.depth_test_enable == 1);
643 state.depth.test_func = PicaToGL::CompareFunc(regs.output_merger.depth_test_func); 684 state.depth.test_func = PicaToGL::CompareFunc(regs.output_merger.depth_test_func);
685 state.color_mask.red_enabled = regs.output_merger.red_enable;
686 state.color_mask.green_enabled = regs.output_merger.green_enable;
687 state.color_mask.blue_enabled = regs.output_merger.blue_enable;
688 state.color_mask.alpha_enabled = regs.output_merger.alpha_enable;
644 state.depth.write_mask = regs.output_merger.depth_write_enable ? GL_TRUE : GL_FALSE; 689 state.depth.write_mask = regs.output_merger.depth_write_enable ? GL_TRUE : GL_FALSE;
645} 690}
646 691
@@ -748,10 +793,10 @@ void RasterizerOpenGL::ReloadColorBuffer() {
748 for (int x = 0; x < fb_color_texture.width; ++x) { 793 for (int x = 0; x < fb_color_texture.width; ++x) {
749 const u32 coarse_y = y & ~7; 794 const u32 coarse_y = y & ~7;
750 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_color_texture.width * bytes_per_pixel; 795 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_color_texture.width * bytes_per_pixel;
751 u32 gl_px_idx = x * bytes_per_pixel + y * fb_color_texture.width * bytes_per_pixel; 796 u32 gl_pixel_index = (x + y * fb_color_texture.width) * bytes_per_pixel;
752 797
753 u8* pixel = color_buffer + dst_offset; 798 u8* pixel = color_buffer + dst_offset;
754 memcpy(&temp_fb_color_buffer[gl_px_idx], pixel, bytes_per_pixel); 799 memcpy(&temp_fb_color_buffer[gl_pixel_index], pixel, bytes_per_pixel);
755 } 800 }
756 } 801 }
757 802
@@ -762,6 +807,9 @@ void RasterizerOpenGL::ReloadColorBuffer() {
762 glActiveTexture(GL_TEXTURE0); 807 glActiveTexture(GL_TEXTURE0);
763 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, fb_color_texture.width, fb_color_texture.height, 808 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, fb_color_texture.width, fb_color_texture.height,
764 fb_color_texture.gl_format, fb_color_texture.gl_type, temp_fb_color_buffer.get()); 809 fb_color_texture.gl_format, fb_color_texture.gl_type, temp_fb_color_buffer.get());
810
811 state.texture_units[0].texture_2d = 0;
812 state.Apply();
765} 813}
766 814
767void RasterizerOpenGL::ReloadDepthBuffer() { 815void RasterizerOpenGL::ReloadDepthBuffer() {
@@ -779,29 +827,29 @@ void RasterizerOpenGL::ReloadDepthBuffer() {
779 827
780 std::unique_ptr<u8[]> temp_fb_depth_buffer(new u8[fb_depth_texture.width * fb_depth_texture.height * gl_bpp]); 828 std::unique_ptr<u8[]> temp_fb_depth_buffer(new u8[fb_depth_texture.width * fb_depth_texture.height * gl_bpp]);
781 829
782 for (int y = 0; y < fb_depth_texture.height; ++y) { 830 u8* temp_fb_depth_data = bytes_per_pixel == 3 ? (temp_fb_depth_buffer.get() + 1) : temp_fb_depth_buffer.get();
783 for (int x = 0; x < fb_depth_texture.width; ++x) { 831
784 const u32 coarse_y = y & ~7; 832 if (fb_depth_texture.format == Pica::Regs::DepthFormat::D24S8) {
785 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_depth_texture.width * bytes_per_pixel; 833 for (int y = 0; y < fb_depth_texture.height; ++y) {
786 u32 gl_px_idx = x + y * fb_depth_texture.width; 834 for (int x = 0; x < fb_depth_texture.width; ++x) {
787 835 const u32 coarse_y = y & ~7;
788 switch (fb_depth_texture.format) { 836 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_depth_texture.width * bytes_per_pixel;
789 case Pica::Regs::DepthFormat::D16: 837 u32 gl_pixel_index = (x + y * fb_depth_texture.width);
790 ((u16*)temp_fb_depth_buffer.get())[gl_px_idx] = Color::DecodeD16(depth_buffer + dst_offset); 838
791 break; 839 u8* pixel = depth_buffer + dst_offset;
792 case Pica::Regs::DepthFormat::D24: 840 u32 depth_stencil = *(u32*)pixel;
793 ((u32*)temp_fb_depth_buffer.get())[gl_px_idx] = Color::DecodeD24(depth_buffer + dst_offset); 841 ((u32*)temp_fb_depth_data)[gl_pixel_index] = (depth_stencil << 8) | (depth_stencil >> 24);
794 break;
795 case Pica::Regs::DepthFormat::D24S8:
796 {
797 Math::Vec2<u32> depth_stencil = Color::DecodeD24S8(depth_buffer + dst_offset);
798 ((u32*)temp_fb_depth_buffer.get())[gl_px_idx] = (depth_stencil.x << 8) | depth_stencil.y;
799 break;
800 } 842 }
801 default: 843 }
802 LOG_CRITICAL(Render_OpenGL, "Unknown memory framebuffer depth format %x", fb_depth_texture.format); 844 } else {
803 UNIMPLEMENTED(); 845 for (int y = 0; y < fb_depth_texture.height; ++y) {
804 break; 846 for (int x = 0; x < fb_depth_texture.width; ++x) {
847 const u32 coarse_y = y & ~7;
848 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_depth_texture.width * bytes_per_pixel;
849 u32 gl_pixel_index = (x + y * fb_depth_texture.width) * gl_bpp;
850
851 u8* pixel = depth_buffer + dst_offset;
852 memcpy(&temp_fb_depth_data[gl_pixel_index], pixel, bytes_per_pixel);
805 } 853 }
806 } 854 }
807 } 855 }
@@ -813,6 +861,9 @@ void RasterizerOpenGL::ReloadDepthBuffer() {
813 glActiveTexture(GL_TEXTURE0); 861 glActiveTexture(GL_TEXTURE0);
814 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, fb_depth_texture.width, fb_depth_texture.height, 862 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, fb_depth_texture.width, fb_depth_texture.height,
815 fb_depth_texture.gl_format, fb_depth_texture.gl_type, temp_fb_depth_buffer.get()); 863 fb_depth_texture.gl_format, fb_depth_texture.gl_type, temp_fb_depth_buffer.get());
864
865 state.texture_units[0].texture_2d = 0;
866 state.Apply();
816} 867}
817 868
818void RasterizerOpenGL::CommitColorBuffer() { 869void RasterizerOpenGL::CommitColorBuffer() {
@@ -831,15 +882,18 @@ void RasterizerOpenGL::CommitColorBuffer() {
831 glActiveTexture(GL_TEXTURE0); 882 glActiveTexture(GL_TEXTURE0);
832 glGetTexImage(GL_TEXTURE_2D, 0, fb_color_texture.gl_format, fb_color_texture.gl_type, temp_gl_color_buffer.get()); 883 glGetTexImage(GL_TEXTURE_2D, 0, fb_color_texture.gl_format, fb_color_texture.gl_type, temp_gl_color_buffer.get());
833 884
885 state.texture_units[0].texture_2d = 0;
886 state.Apply();
887
834 // Directly copy pixels. Internal OpenGL color formats are consistent so no conversion is necessary. 888 // Directly copy pixels. Internal OpenGL color formats are consistent so no conversion is necessary.
835 for (int y = 0; y < fb_color_texture.height; ++y) { 889 for (int y = 0; y < fb_color_texture.height; ++y) {
836 for (int x = 0; x < fb_color_texture.width; ++x) { 890 for (int x = 0; x < fb_color_texture.width; ++x) {
837 const u32 coarse_y = y & ~7; 891 const u32 coarse_y = y & ~7;
838 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_color_texture.width * bytes_per_pixel; 892 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_color_texture.width * bytes_per_pixel;
839 u32 gl_px_idx = x * bytes_per_pixel + y * fb_color_texture.width * bytes_per_pixel; 893 u32 gl_pixel_index = x * bytes_per_pixel + y * fb_color_texture.width * bytes_per_pixel;
840 894
841 u8* pixel = color_buffer + dst_offset; 895 u8* pixel = color_buffer + dst_offset;
842 memcpy(pixel, &temp_gl_color_buffer[gl_px_idx], bytes_per_pixel); 896 memcpy(pixel, &temp_gl_color_buffer[gl_pixel_index], bytes_per_pixel);
843 } 897 }
844 } 898 }
845 } 899 }
@@ -866,29 +920,32 @@ void RasterizerOpenGL::CommitDepthBuffer() {
866 glActiveTexture(GL_TEXTURE0); 920 glActiveTexture(GL_TEXTURE0);
867 glGetTexImage(GL_TEXTURE_2D, 0, fb_depth_texture.gl_format, fb_depth_texture.gl_type, temp_gl_depth_buffer.get()); 921 glGetTexImage(GL_TEXTURE_2D, 0, fb_depth_texture.gl_format, fb_depth_texture.gl_type, temp_gl_depth_buffer.get());
868 922
869 for (int y = 0; y < fb_depth_texture.height; ++y) { 923 state.texture_units[0].texture_2d = 0;
870 for (int x = 0; x < fb_depth_texture.width; ++x) { 924 state.Apply();
871 const u32 coarse_y = y & ~7; 925
872 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_depth_texture.width * bytes_per_pixel; 926 u8* temp_gl_depth_data = bytes_per_pixel == 3 ? (temp_gl_depth_buffer.get() + 1) : temp_gl_depth_buffer.get();
873 u32 gl_px_idx = x + y * fb_depth_texture.width; 927
874 928 if (fb_depth_texture.format == Pica::Regs::DepthFormat::D24S8) {
875 switch (fb_depth_texture.format) { 929 for (int y = 0; y < fb_depth_texture.height; ++y) {
876 case Pica::Regs::DepthFormat::D16: 930 for (int x = 0; x < fb_depth_texture.width; ++x) {
877 Color::EncodeD16(((u16*)temp_gl_depth_buffer.get())[gl_px_idx], depth_buffer + dst_offset); 931 const u32 coarse_y = y & ~7;
878 break; 932 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_depth_texture.width * bytes_per_pixel;
879 case Pica::Regs::DepthFormat::D24: 933 u32 gl_pixel_index = (x + y * fb_depth_texture.width);
880 Color::EncodeD24(((u32*)temp_gl_depth_buffer.get())[gl_px_idx], depth_buffer + dst_offset); 934
881 break; 935 u8* pixel = depth_buffer + dst_offset;
882 case Pica::Regs::DepthFormat::D24S8: 936 u32 depth_stencil = ((u32*)temp_gl_depth_data)[gl_pixel_index];
883 { 937 *(u32*)pixel = (depth_stencil >> 8) | (depth_stencil << 24);
884 u32 depth_stencil = ((u32*)temp_gl_depth_buffer.get())[gl_px_idx];
885 Color::EncodeD24S8((depth_stencil >> 8), depth_stencil & 0xFF, depth_buffer + dst_offset);
886 break;
887 } 938 }
888 default: 939 }
889 LOG_CRITICAL(Render_OpenGL, "Unknown framebuffer depth format %x", fb_depth_texture.format); 940 } else {
890 UNIMPLEMENTED(); 941 for (int y = 0; y < fb_depth_texture.height; ++y) {
891 break; 942 for (int x = 0; x < fb_depth_texture.width; ++x) {
943 const u32 coarse_y = y & ~7;
944 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_depth_texture.width * bytes_per_pixel;
945 u32 gl_pixel_index = (x + y * fb_depth_texture.width) * gl_bpp;
946
947 u8* pixel = depth_buffer + dst_offset;
948 memcpy(pixel, &temp_gl_depth_data[gl_pixel_index], bytes_per_pixel);
892 } 949 }
893 } 950 }
894 } 951 }
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 9896f8d04..d7d422b1f 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -125,6 +125,9 @@ private:
125 /// Syncs the alpha test states to match the PICA register 125 /// Syncs the alpha test states to match the PICA register
126 void SyncAlphaTest(); 126 void SyncAlphaTest();
127 127
128 /// Syncs the logic op states to match the PICA register
129 void SyncLogicOp();
130
128 /// Syncs the stencil test states to match the PICA register 131 /// Syncs the stencil test states to match the PICA register
129 void SyncStencilTest(); 132 void SyncStencilTest();
130 133
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index 6f88a8b21..2e4110a88 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -4,13 +4,13 @@
4 4
5#include "common/make_unique.h" 5#include "common/make_unique.h"
6#include "common/math_util.h" 6#include "common/math_util.h"
7#include "common/vector_math.h"
7 8
8#include "core/memory.h" 9#include "core/memory.h"
9 10
10#include "video_core/renderer_opengl/gl_rasterizer_cache.h" 11#include "video_core/renderer_opengl/gl_rasterizer_cache.h"
11#include "video_core/renderer_opengl/pica_to_gl.h" 12#include "video_core/renderer_opengl/pica_to_gl.h"
12#include "video_core/debug_utils/debug_utils.h" 13#include "video_core/debug_utils/debug_utils.h"
13#include "video_core/math.h"
14 14
15RasterizerCacheOpenGL::~RasterizerCacheOpenGL() { 15RasterizerCacheOpenGL::~RasterizerCacheOpenGL() {
16 FullFlush(); 16 FullFlush();
diff --git a/src/video_core/renderer_opengl/gl_shaders.h b/src/video_core/renderer_opengl/gl_shaders.h
index 8f0941230..a8cb2f595 100644
--- a/src/video_core/renderer_opengl/gl_shaders.h
+++ b/src/video_core/renderer_opengl/gl_shaders.h
@@ -69,15 +69,16 @@ const char g_fragment_shader_hw[] = R"(
69#define NUM_VTX_ATTR 7 69#define NUM_VTX_ATTR 7
70#define NUM_TEV_STAGES 6 70#define NUM_TEV_STAGES 6
71 71
72#define SOURCE_PRIMARYCOLOR 0x0 72#define SOURCE_PRIMARYCOLOR 0x0
73#define SOURCE_PRIMARYFRAGMENTCOLOR 0x1 73#define SOURCE_PRIMARYFRAGMENTCOLOR 0x1
74#define SOURCE_TEXTURE0 0x3 74#define SOURCE_SECONDARYFRAGMENTCOLOR 0x2
75#define SOURCE_TEXTURE1 0x4 75#define SOURCE_TEXTURE0 0x3
76#define SOURCE_TEXTURE2 0x5 76#define SOURCE_TEXTURE1 0x4
77#define SOURCE_TEXTURE3 0x6 77#define SOURCE_TEXTURE2 0x5
78#define SOURCE_PREVIOUSBUFFER 0xd 78#define SOURCE_TEXTURE3 0x6
79#define SOURCE_CONSTANT 0xe 79#define SOURCE_PREVIOUSBUFFER 0xd
80#define SOURCE_PREVIOUS 0xf 80#define SOURCE_CONSTANT 0xe
81#define SOURCE_PREVIOUS 0xf
81 82
82#define COLORMODIFIER_SOURCECOLOR 0x0 83#define COLORMODIFIER_SOURCECOLOR 0x0
83#define COLORMODIFIER_ONEMINUSSOURCECOLOR 0x1 84#define COLORMODIFIER_ONEMINUSSOURCECOLOR 0x1
@@ -151,8 +152,11 @@ vec4 GetSource(int source) {
151 if (source == SOURCE_PRIMARYCOLOR) { 152 if (source == SOURCE_PRIMARYCOLOR) {
152 return o[2]; 153 return o[2];
153 } else if (source == SOURCE_PRIMARYFRAGMENTCOLOR) { 154 } else if (source == SOURCE_PRIMARYFRAGMENTCOLOR) {
154 // HACK: Uses color value, but should really use fragment lighting output 155 // HACK: Until we implement fragment lighting, use primary_color
155 return o[2]; 156 return o[2];
157 } else if (source == SOURCE_SECONDARYFRAGMENTCOLOR) {
158 // HACK: Until we implement fragment lighting, use zero
159 return vec4(0.0, 0.0, 0.0, 0.0);
156 } else if (source == SOURCE_TEXTURE0) { 160 } else if (source == SOURCE_TEXTURE0) {
157 return texture(tex[0], o[3].xy); 161 return texture(tex[0], o[3].xy);
158 } else if (source == SOURCE_TEXTURE1) { 162 } else if (source == SOURCE_TEXTURE1) {
diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp
index 1afa58c99..3526e16d5 100644
--- a/src/video_core/renderer_opengl/gl_state.cpp
+++ b/src/video_core/renderer_opengl/gl_state.cpp
@@ -16,6 +16,11 @@ OpenGLState::OpenGLState() {
16 depth.test_func = GL_LESS; 16 depth.test_func = GL_LESS;
17 depth.write_mask = GL_TRUE; 17 depth.write_mask = GL_TRUE;
18 18
19 color_mask.red_enabled = GL_TRUE;
20 color_mask.green_enabled = GL_TRUE;
21 color_mask.blue_enabled = GL_TRUE;
22 color_mask.alpha_enabled = GL_TRUE;
23
19 stencil.test_enabled = false; 24 stencil.test_enabled = false;
20 stencil.test_func = GL_ALWAYS; 25 stencil.test_func = GL_ALWAYS;
21 stencil.test_ref = 0; 26 stencil.test_ref = 0;
@@ -32,6 +37,8 @@ OpenGLState::OpenGLState() {
32 blend.color.blue = 0.0f; 37 blend.color.blue = 0.0f;
33 blend.color.alpha = 0.0f; 38 blend.color.alpha = 0.0f;
34 39
40 logic_op = GL_COPY;
41
35 for (auto& texture_unit : texture_units) { 42 for (auto& texture_unit : texture_units) {
36 texture_unit.enabled_2d = false; 43 texture_unit.enabled_2d = false;
37 texture_unit.texture_2d = 0; 44 texture_unit.texture_2d = 0;
@@ -75,6 +82,15 @@ void OpenGLState::Apply() {
75 glDepthMask(depth.write_mask); 82 glDepthMask(depth.write_mask);
76 } 83 }
77 84
85 // Color mask
86 if (color_mask.red_enabled != cur_state.color_mask.red_enabled ||
87 color_mask.green_enabled != cur_state.color_mask.green_enabled ||
88 color_mask.blue_enabled != cur_state.color_mask.blue_enabled ||
89 color_mask.alpha_enabled != cur_state.color_mask.alpha_enabled) {
90 glColorMask(color_mask.red_enabled, color_mask.green_enabled,
91 color_mask.blue_enabled, color_mask.alpha_enabled);
92 }
93
78 // Stencil test 94 // Stencil test
79 if (stencil.test_enabled != cur_state.stencil.test_enabled) { 95 if (stencil.test_enabled != cur_state.stencil.test_enabled) {
80 if (stencil.test_enabled) { 96 if (stencil.test_enabled) {
@@ -82,11 +98,11 @@ void OpenGLState::Apply() {
82 } else { 98 } else {
83 glDisable(GL_STENCIL_TEST); 99 glDisable(GL_STENCIL_TEST);
84 } 100 }
85 } 101 }
86 102
87 if (stencil.test_func != cur_state.stencil.test_func || 103 if (stencil.test_func != cur_state.stencil.test_func ||
88 stencil.test_ref != cur_state.stencil.test_ref || 104 stencil.test_ref != cur_state.stencil.test_ref ||
89 stencil.test_mask != cur_state.stencil.test_mask) { 105 stencil.test_mask != cur_state.stencil.test_mask) {
90 glStencilFunc(stencil.test_func, stencil.test_ref, stencil.test_mask); 106 glStencilFunc(stencil.test_func, stencil.test_ref, stencil.test_mask);
91 } 107 }
92 108
@@ -99,23 +115,34 @@ void OpenGLState::Apply() {
99 if (blend.enabled != cur_state.blend.enabled) { 115 if (blend.enabled != cur_state.blend.enabled) {
100 if (blend.enabled) { 116 if (blend.enabled) {
101 glEnable(GL_BLEND); 117 glEnable(GL_BLEND);
118
119 cur_state.logic_op = GL_COPY;
120 glLogicOp(cur_state.logic_op);
121 glDisable(GL_COLOR_LOGIC_OP);
102 } else { 122 } else {
103 glDisable(GL_BLEND); 123 glDisable(GL_BLEND);
124 glEnable(GL_COLOR_LOGIC_OP);
104 } 125 }
105 } 126 }
106 127
107 if (blend.color.red != cur_state.blend.color.red || 128 if (blend.color.red != cur_state.blend.color.red ||
108 blend.color.green != cur_state.blend.color.green || 129 blend.color.green != cur_state.blend.color.green ||
109 blend.color.blue != cur_state.blend.color.blue || 130 blend.color.blue != cur_state.blend.color.blue ||
110 blend.color.alpha != cur_state.blend.color.alpha) { 131 blend.color.alpha != cur_state.blend.color.alpha) {
111 glBlendColor(blend.color.red, blend.color.green, blend.color.blue, blend.color.alpha); 132 glBlendColor(blend.color.red, blend.color.green,
133 blend.color.blue, blend.color.alpha);
112 } 134 }
113 135
114 if (blend.src_rgb_func != cur_state.blend.src_rgb_func || 136 if (blend.src_rgb_func != cur_state.blend.src_rgb_func ||
115 blend.dst_rgb_func != cur_state.blend.dst_rgb_func || 137 blend.dst_rgb_func != cur_state.blend.dst_rgb_func ||
116 blend.src_a_func != cur_state.blend.src_a_func || 138 blend.src_a_func != cur_state.blend.src_a_func ||
117 blend.dst_a_func != cur_state.blend.dst_a_func) { 139 blend.dst_a_func != cur_state.blend.dst_a_func) {
118 glBlendFuncSeparate(blend.src_rgb_func, blend.dst_rgb_func, blend.src_a_func, blend.dst_a_func); 140 glBlendFuncSeparate(blend.src_rgb_func, blend.dst_rgb_func,
141 blend.src_a_func, blend.dst_a_func);
142 }
143
144 if (logic_op != cur_state.logic_op) {
145 glLogicOp(logic_op);
119 } 146 }
120 147
121 // Textures 148 // Textures
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h
index 281b7cad5..26b916360 100644
--- a/src/video_core/renderer_opengl/gl_state.h
+++ b/src/video_core/renderer_opengl/gl_state.h
@@ -20,6 +20,13 @@ public:
20 } depth; 20 } depth;
21 21
22 struct { 22 struct {
23 GLboolean red_enabled;
24 GLboolean green_enabled;
25 GLboolean blue_enabled;
26 GLboolean alpha_enabled;
27 } color_mask; // GL_COLOR_WRITEMASK
28
29 struct {
23 bool test_enabled; // GL_STENCIL_TEST 30 bool test_enabled; // GL_STENCIL_TEST
24 GLenum test_func; // GL_STENCIL_FUNC 31 GLenum test_func; // GL_STENCIL_FUNC
25 GLint test_ref; // GL_STENCIL_REF 32 GLint test_ref; // GL_STENCIL_REF
@@ -42,6 +49,8 @@ public:
42 } color; // GL_BLEND_COLOR 49 } color; // GL_BLEND_COLOR
43 } blend; 50 } blend;
44 51
52 GLenum logic_op; // GL_LOGIC_OP_MODE
53
45 // 3 texture units - one for each that is used in PICA fragment shader emulation 54 // 3 texture units - one for each that is used in PICA fragment shader emulation
46 struct { 55 struct {
47 bool enabled_2d; // GL_TEXTURE_2D 56 bool enabled_2d; // GL_TEXTURE_2D
@@ -61,7 +70,7 @@ public:
61 static const OpenGLState& GetCurState() { 70 static const OpenGLState& GetCurState() {
62 return cur_state; 71 return cur_state;
63 } 72 }
64 73
65 /// Apply this state as the current OpenGL state 74 /// Apply this state as the current OpenGL state
66 void Apply(); 75 void Apply();
67 76
diff --git a/src/video_core/renderer_opengl/pica_to_gl.h b/src/video_core/renderer_opengl/pica_to_gl.h
index f8763e71b..e566f9f7a 100644
--- a/src/video_core/renderer_opengl/pica_to_gl.h
+++ b/src/video_core/renderer_opengl/pica_to_gl.h
@@ -71,6 +71,37 @@ inline GLenum BlendFunc(Pica::Regs::BlendFactor factor) {
71 return blend_func_table[(unsigned)factor]; 71 return blend_func_table[(unsigned)factor];
72} 72}
73 73
74inline GLenum LogicOp(Pica::Regs::LogicOp op) {
75 static const GLenum logic_op_table[] = {
76 GL_CLEAR, // Clear
77 GL_AND, // And
78 GL_AND_REVERSE, // AndReverse
79 GL_COPY, // Copy
80 GL_SET, // Set
81 GL_COPY_INVERTED, // CopyInverted
82 GL_NOOP, // NoOp
83 GL_INVERT, // Invert
84 GL_NAND, // Nand
85 GL_OR, // Or
86 GL_NOR, // Nor
87 GL_XOR, // Xor
88 GL_EQUIV, // Equiv
89 GL_AND_INVERTED, // AndInverted
90 GL_OR_REVERSE, // OrReverse
91 GL_OR_INVERTED, // OrInverted
92 };
93
94 // Range check table for input
95 if ((unsigned)op >= ARRAY_SIZE(logic_op_table)) {
96 LOG_CRITICAL(Render_OpenGL, "Unknown logic op %d", op);
97 UNREACHABLE();
98
99 return GL_COPY;
100 }
101
102 return logic_op_table[(unsigned)op];
103}
104
74inline GLenum CompareFunc(Pica::Regs::CompareFunc func) { 105inline GLenum CompareFunc(Pica::Regs::CompareFunc func) {
75 static const GLenum compare_func_table[] = { 106 static const GLenum compare_func_table[] = {
76 GL_NEVER, // CompareFunc::Never 107 GL_NEVER, // CompareFunc::Never
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 16cf92e20..3399ca123 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -157,7 +157,7 @@ void RendererOpenGL::LoadFBToActiveGLTexture(const GPU::Regs::FramebufferConfig&
157 state.texture_units[0].enabled_2d = true; 157 state.texture_units[0].enabled_2d = true;
158 state.texture_units[0].texture_2d = texture.handle; 158 state.texture_units[0].texture_2d = texture.handle;
159 state.Apply(); 159 state.Apply();
160 160
161 glActiveTexture(GL_TEXTURE0); 161 glActiveTexture(GL_TEXTURE0);
162 glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)pixel_stride); 162 glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)pixel_stride);
163 163
@@ -170,6 +170,9 @@ void RendererOpenGL::LoadFBToActiveGLTexture(const GPU::Regs::FramebufferConfig&
170 texture.gl_format, texture.gl_type, framebuffer_data); 170 texture.gl_format, texture.gl_type, framebuffer_data);
171 171
172 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); 172 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
173
174 state.texture_units[0].texture_2d = 0;
175 state.Apply();
173} 176}
174 177
175/** 178/**
@@ -239,6 +242,9 @@ void RendererOpenGL::InitOpenGLObjects() {
239 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 242 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
240 } 243 }
241 244
245 state.texture_units[0].texture_2d = 0;
246 state.Apply();
247
242 hw_rasterizer->InitObjects(); 248 hw_rasterizer->InitObjects();
243} 249}
244 250
@@ -370,6 +376,8 @@ void RendererOpenGL::Init() {
370 } 376 }
371 377
372 LOG_INFO(Render_OpenGL, "GL_VERSION: %s", glGetString(GL_VERSION)); 378 LOG_INFO(Render_OpenGL, "GL_VERSION: %s", glGetString(GL_VERSION));
379 LOG_INFO(Render_OpenGL, "GL_VENDOR: %s", glGetString(GL_VENDOR));
380 LOG_INFO(Render_OpenGL, "GL_RENDERER: %s", glGetString(GL_RENDERER));
373 InitOpenGLObjects(); 381 InitOpenGLObjects();
374} 382}
375 383
diff --git a/src/video_core/vertex_shader.cpp b/src/video_core/vertex_shader.cpp
index 7d68998f1..87006a832 100644
--- a/src/video_core/vertex_shader.cpp
+++ b/src/video_core/vertex_shader.cpp
@@ -119,17 +119,13 @@ static void ProcessShaderCode(VertexShaderState& state) {
119 switch (instr.opcode.Value().GetInfo().type) { 119 switch (instr.opcode.Value().GetInfo().type) {
120 case OpCode::Type::Arithmetic: 120 case OpCode::Type::Arithmetic:
121 { 121 {
122 bool is_inverted = 0 != (instr.opcode.Value().GetInfo().subtype & OpCode::Info::SrcInversed); 122 const bool is_inverted = (0 != (instr.opcode.Value().GetInfo().subtype & OpCode::Info::SrcInversed));
123 // TODO: We don't really support this properly: For instance, the address register
124 // offset needs to be applied to SRC2 instead, etc.
125 // For now, we just abort in this situation.
126 ASSERT_MSG(!is_inverted, "Bad condition...");
127 123
128 const int address_offset = (instr.common.address_register_index == 0) 124 const int address_offset = (instr.common.address_register_index == 0)
129 ? 0 : state.address_registers[instr.common.address_register_index - 1]; 125 ? 0 : state.address_registers[instr.common.address_register_index - 1];
130 126
131 const float24* src1_ = LookupSourceRegister(instr.common.GetSrc1(is_inverted) + address_offset); 127 const float24* src1_ = LookupSourceRegister(instr.common.GetSrc1(is_inverted) + (!is_inverted * address_offset));
132 const float24* src2_ = LookupSourceRegister(instr.common.GetSrc2(is_inverted)); 128 const float24* src2_ = LookupSourceRegister(instr.common.GetSrc2(is_inverted) + ( is_inverted * address_offset));
133 129
134 const bool negate_src1 = ((bool)swizzle.negate_src1 != false); 130 const bool negate_src1 = ((bool)swizzle.negate_src1 != false);
135 const bool negate_src2 = ((bool)swizzle.negate_src2 != false); 131 const bool negate_src2 = ((bool)swizzle.negate_src2 != false);
@@ -208,6 +204,15 @@ static void ProcessShaderCode(VertexShaderState& state) {
208 } 204 }
209 break; 205 break;
210 206
207 case OpCode::Id::MIN:
208 for (int i = 0; i < 4; ++i) {
209 if (!swizzle.DestComponentEnabled(i))
210 continue;
211
212 dest[i] = std::min(src1[i], src2[i]);
213 }
214 break;
215
211 case OpCode::Id::DP3: 216 case OpCode::Id::DP3:
212 case OpCode::Id::DP4: 217 case OpCode::Id::DP4:
213 { 218 {
@@ -279,6 +284,16 @@ static void ProcessShaderCode(VertexShaderState& state) {
279 break; 284 break;
280 } 285 }
281 286
287 case OpCode::Id::SLT:
288 case OpCode::Id::SLTI:
289 for (int i = 0; i < 4; ++i) {
290 if (!swizzle.DestComponentEnabled(i))
291 continue;
292
293 dest[i] = (src1[i] < src2[i]) ? float24::FromFloat32(1.0f) : float24::FromFloat32(0.0f);
294 }
295 break;
296
282 case OpCode::Id::CMP: 297 case OpCode::Id::CMP:
283 for (int i = 0; i < 2; ++i) { 298 for (int i = 0; i < 2; ++i) {
284 // TODO: Can you restrict to one compare via dest masking? 299 // TODO: Can you restrict to one compare via dest masking?
@@ -330,7 +345,7 @@ static void ProcessShaderCode(VertexShaderState& state) {
330 345
331 case OpCode::Type::MultiplyAdd: 346 case OpCode::Type::MultiplyAdd:
332 { 347 {
333 if ((instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MAD) || 348 if ((instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MAD) ||
334 (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MADI)) { 349 (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MADI)) {
335 const SwizzlePattern& swizzle = *(SwizzlePattern*)&swizzle_data[instr.mad.operand_desc_id]; 350 const SwizzlePattern& swizzle = *(SwizzlePattern*)&swizzle_data[instr.mad.operand_desc_id];
336 351
@@ -547,7 +562,7 @@ OutputVertex RunShader(const InputVertex& input, int num_attributes) {
547 const auto& attribute_register_map = regs.vs_input_register_map; 562 const auto& attribute_register_map = regs.vs_input_register_map;
548 float24 dummy_register; 563 float24 dummy_register;
549 boost::fill(state.input_register_table, &dummy_register); 564 boost::fill(state.input_register_table, &dummy_register);
550 565
551 if (num_attributes > 0) state.input_register_table[attribute_register_map.attribute0_register] = &input.attr[0].x; 566 if (num_attributes > 0) state.input_register_table[attribute_register_map.attribute0_register] = &input.attr[0].x;
552 if (num_attributes > 1) state.input_register_table[attribute_register_map.attribute1_register] = &input.attr[1].x; 567 if (num_attributes > 1) state.input_register_table[attribute_register_map.attribute1_register] = &input.attr[1].x;
553 if (num_attributes > 2) state.input_register_table[attribute_register_map.attribute2_register] = &input.attr[2].x; 568 if (num_attributes > 2) state.input_register_table[attribute_register_map.attribute2_register] = &input.attr[2].x;