summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x.travis-deps.sh13
-rw-r--r--.travis.yml2
-rw-r--r--CMakeLists.txt29
-rw-r--r--CONTRIBUTING.md8
-rw-r--r--README.md10
-rw-r--r--appveyor.yml4
-rw-r--r--externals/cmake-modules/FindSDL2.cmake224
-rw-r--r--externals/cmake-modules/WindowsCopyFiles.cmake28
-rw-r--r--externals/glad/include/glad/glad.h923
-rw-r--r--externals/glad/src/glad.c52
-rw-r--r--externals/glfw-3.1.1.bin/COPYING.txt22
-rw-r--r--externals/glfw-3.1.1.bin/include/GLFW/glfw3.h3340
-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.dllbin196839 -> 0 bytes
-rw-r--r--externals/glfw-3.1.1.bin/lib-mingw-i686/glfw3dll.abin54834 -> 0 bytes
-rw-r--r--externals/glfw-3.1.1.bin/lib-mingw-i686/libglfw3.abin89732 -> 0 bytes
-rw-r--r--externals/glfw-3.1.1.bin/lib-mingw-x86_64/glfw3.dllbin235754 -> 0 bytes
-rw-r--r--externals/glfw-3.1.1.bin/lib-mingw-x86_64/glfw3dll.abin53500 -> 0 bytes
-rw-r--r--externals/glfw-3.1.1.bin/lib-mingw-x86_64/libglfw3.abin97354 -> 0 bytes
-rw-r--r--externals/glfw-3.1.1.bin/lib-msvc_v120-Win32/glfw3.dllbin47104 -> 0 bytes
-rw-r--r--externals/glfw-3.1.1.bin/lib-msvc_v120-Win32/glfw3.libbin150616 -> 0 bytes
-rw-r--r--externals/glfw-3.1.1.bin/lib-msvc_v120-Win32/glfw3dll.libbin19984 -> 0 bytes
-rw-r--r--externals/glfw-3.1.1.bin/lib-msvc_v120-x64/glfw3.dllbin53248 -> 0 bytes
-rw-r--r--externals/glfw-3.1.1.bin/lib-msvc_v120-x64/glfw3.libbin196774 -> 0 bytes
-rw-r--r--externals/glfw-3.1.1.bin/lib-msvc_v120-x64/glfw3dll.libbin19602 -> 0 bytes
-rw-r--r--src/CMakeLists.txt3
-rw-r--r--src/audio_core/CMakeLists.txt16
-rw-r--r--src/audio_core/audio_core.cpp53
-rw-r--r--src/audio_core/audio_core.h26
-rw-r--r--src/audio_core/hle/dsp.cpp42
-rw-r--r--src/audio_core/hle/dsp.h539
-rw-r--r--src/audio_core/hle/pipe.cpp159
-rw-r--r--src/audio_core/hle/pipe.h57
-rw-r--r--src/audio_core/sink.h34
-rw-r--r--src/citra/CMakeLists.txt21
-rw-r--r--src/citra/citra.cpp4
-rw-r--r--src/citra/config.cpp60
-rw-r--r--src/citra/config.h10
-rw-r--r--src/citra/default_ini.h2
-rw-r--r--src/citra/emu_window/emu_window_glfw.cpp168
-rw-r--r--src/citra/emu_window/emu_window_glfw.h54
-rw-r--r--src/citra/emu_window/emu_window_sdl2.cpp167
-rw-r--r--src/citra/emu_window/emu_window_sdl2.h64
-rw-r--r--src/citra_qt/CMakeLists.txt27
-rw-r--r--src/citra_qt/debugger/callstack.cpp12
-rw-r--r--src/citra_qt/debugger/graphics_cmdlists.cpp1
-rw-r--r--src/citra_qt/debugger/graphics_framebuffer.cpp1
-rw-r--r--src/citra_qt/debugger/graphics_tracing.cpp2
-rw-r--r--src/citra_qt/debugger/graphics_vertex_shader.cpp6
-rw-r--r--src/citra_qt/debugger/registers.cpp8
-rw-r--r--src/citra_qt/main.cpp89
-rw-r--r--src/citra_qt/main.h10
-rw-r--r--src/common/bit_field.h44
-rw-r--r--src/common/color.h16
-rw-r--r--src/common/common_funcs.h10
-rw-r--r--src/common/emu_window.cpp4
-rw-r--r--src/common/file_util.cpp20
-rw-r--r--src/common/key_map.h14
-rw-r--r--src/common/logging/backend.cpp4
-rw-r--r--src/common/logging/backend.h20
-rw-r--r--src/common/logging/log.h4
-rw-r--r--src/common/x64/emitter.cpp4
-rw-r--r--src/common/x64/emitter.h113
-rw-r--r--src/core/CMakeLists.txt1
-rw-r--r--src/core/arm/arm_interface.h11
-rw-r--r--src/core/arm/disassembler/arm_disasm.cpp18
-rw-r--r--src/core/arm/dyncom/arm_dyncom_dec.cpp8
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp549
-rw-r--r--src/core/arm/dyncom/arm_dyncom_run.h4
-rw-r--r--src/core/arm/dyncom/arm_dyncom_thumb.h2
-rw-r--r--src/core/arm/skyeye_common/vfp/vfp_helper.h32
-rw-r--r--src/core/core.cpp18
-rw-r--r--src/core/core.h7
-rw-r--r--src/core/file_sys/archive_backend.cpp8
-rw-r--r--src/core/file_sys/archive_backend.h8
-rw-r--r--src/core/file_sys/disk_archive.cpp6
-rw-r--r--src/core/hle/function_wrappers.h4
-rw-r--r--src/core/hle/kernel/address_arbiter.cpp25
-rw-r--r--src/core/hle/kernel/memory.cpp5
-rw-r--r--src/core/hle/kernel/process.cpp8
-rw-r--r--src/core/hle/kernel/process.h1
-rw-r--r--src/core/hle/kernel/shared_memory.cpp21
-rw-r--r--src/core/hle/kernel/shared_memory.h7
-rw-r--r--src/core/hle/kernel/thread.cpp2
-rw-r--r--src/core/hle/kernel/timer.cpp6
-rw-r--r--src/core/hle/kernel/vm_manager.cpp7
-rw-r--r--src/core/hle/kernel/vm_manager.h5
-rw-r--r--src/core/hle/result.h67
-rw-r--r--src/core/hle/service/ac_u.cpp20
-rw-r--r--src/core/hle/service/act_u.cpp8
-rw-r--r--src/core/hle/service/am/am.cpp4
-rw-r--r--src/core/hle/service/am/am.h6
-rw-r--r--src/core/hle/service/am/am_app.cpp1
-rw-r--r--src/core/hle/service/am/am_net.cpp31
-rw-r--r--src/core/hle/service/am/am_sys.cpp16
-rw-r--r--src/core/hle/service/am/am_u.cpp29
-rw-r--r--src/core/hle/service/apt/apt.cpp2
-rw-r--r--src/core/hle/service/apt/apt_a.cpp1
-rw-r--r--src/core/hle/service/apt/apt_s.cpp8
-rw-r--r--src/core/hle/service/apt/apt_u.cpp9
-rw-r--r--src/core/hle/service/boss/boss.cpp4
-rw-r--r--src/core/hle/service/boss/boss.h3
-rw-r--r--src/core/hle/service/boss/boss_p.cpp2
-rw-r--r--src/core/hle/service/boss/boss_u.cpp5
-rw-r--r--src/core/hle/service/cam/cam.cpp286
-rw-r--r--src/core/hle/service/cam/cam.h417
-rw-r--r--src/core/hle/service/cam/cam_c.cpp2
-rw-r--r--src/core/hle/service/cam/cam_q.cpp2
-rw-r--r--src/core/hle/service/cam/cam_s.cpp2
-rw-r--r--src/core/hle/service/cam/cam_u.cpp44
-rw-r--r--src/core/hle/service/cecd/cecd.cpp4
-rw-r--r--src/core/hle/service/cecd/cecd.h3
-rw-r--r--src/core/hle/service/cecd/cecd_s.cpp2
-rw-r--r--src/core/hle/service/cecd/cecd_u.cpp9
-rw-r--r--src/core/hle/service/cfg/cfg.cpp27
-rw-r--r--src/core/hle/service/cfg/cfg.h9
-rw-r--r--src/core/hle/service/cfg/cfg_i.cpp1
-rw-r--r--src/core/hle/service/cfg/cfg_s.cpp1
-rw-r--r--src/core/hle/service/cfg/cfg_u.cpp1
-rw-r--r--src/core/hle/service/csnd_snd.cpp7
-rw-r--r--src/core/hle/service/dsp_dsp.cpp311
-rw-r--r--src/core/hle/service/dsp_dsp.h12
-rw-r--r--src/core/hle/service/err_f.cpp3
-rw-r--r--src/core/hle/service/frd/frd.cpp4
-rw-r--r--src/core/hle/service/frd/frd.h3
-rw-r--r--src/core/hle/service/frd/frd_a.cpp2
-rw-r--r--src/core/hle/service/frd/frd_u.cpp45
-rw-r--r--src/core/hle/service/fs/fs_user.cpp196
-rw-r--r--src/core/hle/service/gsp_gpu.cpp16
-rw-r--r--src/core/hle/service/gsp_lcd.cpp13
-rw-r--r--src/core/hle/service/hid/hid.cpp3
-rw-r--r--src/core/hle/service/hid/hid_spvr.cpp1
-rw-r--r--src/core/hle/service/hid/hid_user.cpp3
-rw-r--r--src/core/hle/service/http_c.cpp13
-rw-r--r--src/core/hle/service/ir/ir.cpp73
-rw-r--r--src/core/hle/service/ir/ir.h53
-rw-r--r--src/core/hle/service/ir/ir_rst.cpp1
-rw-r--r--src/core/hle/service/ir/ir_u.cpp2
-rw-r--r--src/core/hle/service/ir/ir_user.cpp41
-rw-r--r--src/core/hle/service/ldr_ro.cpp2
-rw-r--r--src/core/hle/service/mic_u.cpp11
-rw-r--r--src/core/hle/service/ndm_u.cpp19
-rw-r--r--src/core/hle/service/news/news.cpp4
-rw-r--r--src/core/hle/service/news/news.h3
-rw-r--r--src/core/hle/service/news/news_s.cpp13
-rw-r--r--src/core/hle/service/news/news_u.cpp2
-rw-r--r--src/core/hle/service/nim/nim.cpp5
-rw-r--r--src/core/hle/service/nim/nim.h6
-rw-r--r--src/core/hle/service/nim/nim_aoc.cpp2
-rw-r--r--src/core/hle/service/nim/nim_s.cpp5
-rw-r--r--src/core/hle/service/nim/nim_u.cpp1
-rw-r--r--src/core/hle/service/ns_s.cpp16
-rw-r--r--src/core/hle/service/nwm_uds.cpp20
-rw-r--r--src/core/hle/service/pm_app.cpp5
-rw-r--r--src/core/hle/service/ptm/ptm.cpp4
-rw-r--r--src/core/hle/service/ptm/ptm.h7
-rw-r--r--src/core/hle/service/ptm/ptm_play.cpp1
-rw-r--r--src/core/hle/service/ptm/ptm_sysm.cpp4
-rw-r--r--src/core/hle/service/ptm/ptm_u.cpp3
-rw-r--r--src/core/hle/service/soc_u.cpp32
-rw-r--r--src/core/hle/service/srv.cpp2
-rw-r--r--src/core/hle/service/ssl_c.cpp16
-rw-r--r--src/core/hle/service/y2r_u.cpp27
-rw-r--r--src/core/hle/svc.cpp37
-rw-r--r--src/core/hw/gpu.cpp34
-rw-r--r--src/core/loader/elf.cpp6
-rw-r--r--src/core/loader/loader.cpp6
-rw-r--r--src/core/loader/ncch.cpp3
-rw-r--r--src/core/memory.cpp88
-rw-r--r--src/core/memory_setup.h7
-rw-r--r--src/core/mmio.h34
-rw-r--r--src/core/system.cpp15
-rw-r--r--src/core/system.h9
-rw-r--r--src/video_core/CMakeLists.txt7
-rw-r--r--src/video_core/clipper.cpp13
-rw-r--r--src/video_core/clipper.h2
-rw-r--r--src/video_core/command_processor.cpp136
-rw-r--r--src/video_core/debug_utils/debug_utils.cpp17
-rw-r--r--src/video_core/debug_utils/debug_utils.h3
-rw-r--r--src/video_core/pica.cpp523
-rw-r--r--src/video_core/pica.h429
-rw-r--r--src/video_core/pica_state.h60
-rw-r--r--src/video_core/pica_types.h146
-rw-r--r--src/video_core/primitive_assembly.cpp21
-rw-r--r--src/video_core/primitive_assembly.h10
-rw-r--r--src/video_core/rasterizer.cpp17
-rw-r--r--src/video_core/rasterizer_interface.h (renamed from src/video_core/hwrasterizer_base.h)19
-rw-r--r--src/video_core/renderer_base.cpp29
-rw-r--r--src/video_core/renderer_base.h24
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp456
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h181
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp7
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h8
-rw-r--r--src/video_core/renderer_opengl/gl_shader_gen.cpp225
-rw-r--r--src/video_core/renderer_opengl/gl_shader_util.h2
-rw-r--r--src/video_core/renderer_opengl/gl_state.cpp17
-rw-r--r--src/video_core/renderer_opengl/gl_state.h5
-rw-r--r--src/video_core/renderer_opengl/pica_to_gl.h12
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp82
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.h2
-rw-r--r--src/video_core/shader/shader.cpp9
-rw-r--r--src/video_core/shader/shader.h32
-rw-r--r--src/video_core/shader/shader_interpreter.cpp4
-rw-r--r--src/video_core/shader/shader_jit_x64.cpp16
-rw-r--r--src/video_core/shader/shader_jit_x64.h2
-rw-r--r--src/video_core/swrasterizer.cpp16
-rw-r--r--src/video_core/swrasterizer.h26
-rw-r--r--src/video_core/video_core.cpp23
-rw-r--r--src/video_core/video_core.h7
209 files changed, 6613 insertions, 5914 deletions
diff --git a/.travis-deps.sh b/.travis-deps.sh
index 4b907abb3..bab90d307 100755
--- a/.travis-deps.sh
+++ b/.travis-deps.sh
@@ -13,18 +13,13 @@ if [ "$TRAVIS_OS_NAME" = "linux" -o -z "$TRAVIS_OS_NAME" ]; then
13 | tar -xz -C $HOME/.local --strip-components=1 13 | tar -xz -C $HOME/.local --strip-components=1
14 14
15 ( 15 (
16 git clone https://github.com/glfw/glfw.git --branch 3.1.1 --depth 1 16 wget http://libsdl.org/release/SDL2-2.0.4.tar.gz -O - | tar xz
17 mkdir glfw/build && cd glfw/build 17 cd SDL2-2.0.4
18 cmake -DBUILD_SHARED_LIBS=ON \ 18 ./configure --prefix=$HOME/.local
19 -DGLFW_BUILD_EXAMPLES=OFF \
20 -DGLFW_BUILD_TESTS=OFF \
21 -DCMAKE_INSTALL_PREFIX=$HOME/.local \
22 ..
23 make -j4 && make install 19 make -j4 && make install
24 ) 20 )
25
26elif [ "$TRAVIS_OS_NAME" = "osx" ]; then 21elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
27 brew update > /dev/null # silence the very verbose output 22 brew update > /dev/null # silence the very verbose output
28 brew install qt5 glfw3 23 brew install qt5 sdl2
29 gem install xcpretty 24 gem install xcpretty
30fi 25fi
diff --git a/.travis.yml b/.travis.yml
index 4d21257bc..2e875cccf 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -18,8 +18,6 @@ addons:
18 - gcc-4.9 18 - gcc-4.9
19 - g++-4.9 19 - g++-4.9
20 - xorg-dev 20 - xorg-dev
21 - libglu1-mesa-dev
22 - libxcursor-dev
23 - lib32stdc++6 # For CMake 21 - lib32stdc++6 # For CMake
24 - lftp # To upload builds 22 - lftp # To upload builds
25 23
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b8a981711..d6a4a915a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -35,8 +35,8 @@ endfunction()
35 35
36project(citra) 36project(citra)
37 37
38option(ENABLE_GLFW "Enable the GLFW frontend" ON) 38option(ENABLE_SDL2 "Enable the SDL2 frontend" ON)
39option(CITRA_USE_BUNDLED_GLFW "Download bundled GLFW binaries" OFF) 39option(CITRA_USE_BUNDLED_SDL2 "Download bundled SDL2 binaries" OFF)
40 40
41option(ENABLE_QT "Enable the Qt frontend" ON) 41option(ENABLE_QT "Enable the Qt frontend" ON)
42option(CITRA_USE_BUNDLED_QT "Download bundled Qt binaries" OFF) 42option(CITRA_USE_BUNDLED_QT "Download bundled Qt binaries" OFF)
@@ -135,34 +135,29 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/externals/cmake-modules")
135find_package(OpenGL REQUIRED) 135find_package(OpenGL REQUIRED)
136include_directories(${OPENGL_INCLUDE_DIR}) 136include_directories(${OPENGL_INCLUDE_DIR})
137 137
138if (ENABLE_GLFW) 138if (ENABLE_SDL2)
139 if (CITRA_USE_BUNDLED_GLFW) 139 if (CITRA_USE_BUNDLED_SDL2)
140 # Detect toolchain and platform 140 # Detect toolchain and platform
141 if (MSVC14 AND ARCHITECTURE_x86_64) 141 if (MSVC14 AND ARCHITECTURE_x86_64)
142 set(GLFW_VER "glfw-3.1.1-msvc2015_64") 142 set(SDL2_VER "SDL2-2.0.4")
143 elseif (MSVC12 AND ARCHITECTURE_x86_64)
144 set(GLFW_VER "glfw-3.1.1-msvc2013_64")
145 else() 143 else()
146 message(FATAL_ERROR "No bundled GLFW binaries for your toolchain. Disable CITRA_USE_BUNDLED_GLFW and provide your own.") 144 message(FATAL_ERROR "No bundled SDL2 binaries for your toolchain. Disable CITRA_USE_BUNDLED_SDL2 and provide your own.")
147 endif() 145 endif()
148 146
149 if (DEFINED GLFW_VER) 147 if (DEFINED SDL2_VER)
150 download_bundled_external("glfw/" ${GLFW_VER} GLFW_PREFIX) 148 download_bundled_external("sdl2/" ${SDL2_VER} SDL2_PREFIX)
151 endif() 149 endif()
152 150
153 set(GLFW_INCLUDE_DIRS "${GLFW_PREFIX}/include" CACHE PATH "Path to GLFW3 headers") 151 set(SDL2_INCLUDE_DIR "${SDL2_PREFIX}/include" CACHE PATH "Path to SDL2 headers")
154 set(GLFW_LIBRARY_DIRS "${GLFW_PREFIX}/lib" CACHE PATH "Path to GLFW3 libraries") 152 set(SDL2_LIBRARY "${SDL2_PREFIX}/lib/x64/SDL2.lib" CACHE PATH "Path to SDL2 library")
155 set(GLFW_LIBRARIES glfw3) 153 set(SDL2_DLL_DIR "${SDL2_PREFIX}/lib/x64/" CACHE PATH "Path to SDL2.dll")
156 else() 154 else()
157 find_package(PkgConfig REQUIRED) 155 find_package(SDL2 REQUIRED)
158 pkg_search_module(GLFW REQUIRED glfw3)
159 endif() 156 endif()
160endif() 157endif()
161 158
162IF (APPLE) 159IF (APPLE)
163 FIND_LIBRARY(COCOA_LIBRARY Cocoa) # Umbrella framework for everything GUI-related 160 FIND_LIBRARY(COCOA_LIBRARY Cocoa) # Umbrella framework for everything GUI-related
164 FIND_LIBRARY(IOKIT_LIBRARY IOKit) # GLFW dependency
165 FIND_LIBRARY(COREVIDEO_LIBRARY CoreVideo) # GLFW dependency
166 set(PLATFORM_LIBRARIES iconv ${COCOA_LIBRARY} ${IOKIT_LIBRARY} ${COREVIDEO_LIBRARY}) 161 set(PLATFORM_LIBRARIES iconv ${COCOA_LIBRARY} ${IOKIT_LIBRARY} ${COREVIDEO_LIBRARY})
167 162
168 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") 163 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 28b8b4031..c2735f564 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,3 +1,11 @@
1# Reporting Issues
2
3**The issue tracker is not a support forum.** Unless you can provide precise *technical information* regarding an issue, you *should not post in it*. If you need support, first read the [FAQ](https://github.com/citra-emu/citra/wiki/FAQ) and then either visit our IRC channel or ask in a general emulation forum such as [/r/emulation](https://www.reddit.com/r/emulation/). If you post support questions, generic messages to the developers or vague reports without technical details, they will be closed and locked.
4
5If you believe you have a valid issue report, please post text or a screenshot from the log (the console window that opens alongside Citra) and build version (hex string visible in the titlebar and zip filename), as well as your hardware and software information if applicable.
6
7While issues about specific games not booting are valid bugs, we are currently not interested in them unless you have several games which fail with the same or similar messages. (In which case please file only a single issue about it.) There are too many non-working games right now to file individual issues for every one of them.
8
1# Contributing 9# Contributing
2Citra is a brand new project, so we have a great opportunity to keep things clean and well organized early on. As such, coding style is very important when making commits. They aren't very strict rules since we want to be flexible and we understand that under certain circumstances some of them can be counterproductive. Just try to follow as many of them as possible: 10Citra is a brand new project, so we have a great opportunity to keep things clean and well organized early on. As such, coding style is very important when making commits. They aren't very strict rules since we want to be flexible and we understand that under certain circumstances some of them can be counterproductive. Just try to follow as many of them as possible:
3 11
diff --git a/README.md b/README.md
index 0d9e52396..a27acbc15 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,5 @@
1**BEFORE FILING AN ISSUE, READ THE RELEVANT SECTION IN THE [CONTRIBUTING](https://github.com/citra-emu/citra/blob/master/CONTRIBUTING.md#reporting-issues) FILE!!!**
2
1Citra Emulator 3Citra Emulator
2============== 4==============
3[![Travis CI Build Status](https://travis-ci.org/citra-emu/citra.svg)](https://travis-ci.org/citra-emu/citra) 5[![Travis CI Build Status](https://travis-ci.org/citra-emu/citra.svg)](https://travis-ci.org/citra-emu/citra)
@@ -7,6 +9,8 @@ Citra is an experimental open-source Nintendo 3DS emulator/debugger written in C
7 9
8Citra is licensed under the GPLv2 (or any later version). Refer to the license.txt file included. Please read the [FAQ](https://github.com/citra-emu/citra/wiki/FAQ) before getting started with the project. 10Citra is licensed under the GPLv2 (or any later version). Refer to the license.txt file included. Please read the [FAQ](https://github.com/citra-emu/citra/wiki/FAQ) before getting started with the project.
9 11
12Check out our [website](https://citra-emu.org/)!
13
10For development discussion, please join us @ #citra on freenode. 14For development discussion, please join us @ #citra on freenode.
11 15
12### Development 16### Development
@@ -15,9 +19,9 @@ If you want to contribute please take a look at the [Contributor's Guide](CONTRI
15 19
16### Building 20### Building
17 21
18* __Windows__: [Windows Build](https://github.com/citra-emu/citra/wiki/Windows-Build) 22* __Windows__: [Windows Build](https://github.com/citra-emu/citra/wiki/Building-For-Windows)
19* __Linux__: [Linux Build](https://github.com/citra-emu/citra/wiki/Linux-Build) 23* __Linux__: [Linux Build](https://github.com/citra-emu/citra/wiki/Building-For-Linux)
20* __OSX__: [OS X Build](https://github.com/citra-emu/citra/wiki/OS-X-Build) 24* __OSX__: [OS X Build](https://github.com/citra-emu/citra/wiki/Building-For-OS-X)
21 25
22 26
23### Support 27### Support
diff --git a/appveyor.yml b/appveyor.yml
index d05cc2213..1edd7041f 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -5,6 +5,8 @@ environment:
5 BUILD_PASSWORD: 5 BUILD_PASSWORD:
6 secure: EXGNlWKJsCtbeImEJ5EP9qrxZ+EqUFfNy+CP61nDOMA= 6 secure: EXGNlWKJsCtbeImEJ5EP9qrxZ+EqUFfNy+CP61nDOMA=
7 7
8os: Visual Studio 2015
9
8platform: 10platform:
9 - x64 11 - x64
10 12
@@ -17,7 +19,7 @@ install:
17before_build: 19before_build:
18 - mkdir build 20 - mkdir build
19 - cd build 21 - cd build
20 - cmake -G "Visual Studio 14 Win64" -DCITRA_USE_BUNDLED_GLFW=1 -DCITRA_USE_BUNDLED_QT=1 .. 22 - cmake -G "Visual Studio 14 2015 Win64" -DCITRA_USE_BUNDLED_QT=1 -DCITRA_USE_BUNDLED_SDL2=1 ..
21 - cd .. 23 - cd ..
22 24
23after_build: 25after_build:
diff --git a/externals/cmake-modules/FindSDL2.cmake b/externals/cmake-modules/FindSDL2.cmake
new file mode 100644
index 000000000..0af86840a
--- /dev/null
+++ b/externals/cmake-modules/FindSDL2.cmake
@@ -0,0 +1,224 @@
1
2# This module defines
3# SDL2_LIBRARY, the name of the library to link against
4# SDL2_FOUND, if false, do not try to link to SDL2
5# SDL2_INCLUDE_DIR, where to find SDL.h
6#
7# This module responds to the the flag:
8# SDL2_BUILDING_LIBRARY
9# If this is defined, then no SDL2main will be linked in because
10# only applications need main().
11# Otherwise, it is assumed you are building an application and this
12# module will attempt to locate and set the the proper link flags
13# as part of the returned SDL2_LIBRARY variable.
14#
15# Don't forget to include SDLmain.h and SDLmain.m your project for the
16# OS X framework based version. (Other versions link to -lSDL2main which
17# this module will try to find on your behalf.) Also for OS X, this
18# module will automatically add the -framework Cocoa on your behalf.
19#
20#
21# Additional Note: If you see an empty SDL2_LIBRARY_TEMP in your configuration
22# and no SDL2_LIBRARY, it means CMake did not find your SDL2 library
23# (SDL2.dll, libsdl2.so, SDL2.framework, etc).
24# Set SDL2_LIBRARY_TEMP to point to your SDL2 library, and configure again.
25# Similarly, if you see an empty SDL2MAIN_LIBRARY, you should set this value
26# as appropriate. These values are used to generate the final SDL2_LIBRARY
27# variable, but when these values are unset, SDL2_LIBRARY does not get created.
28#
29#
30# $SDL2DIR is an environment variable that would
31# correspond to the ./configure --prefix=$SDL2DIR
32# used in building SDL2.
33# l.e.galup 9-20-02
34#
35# Modified by Eric Wing.
36# Added code to assist with automated building by using environmental variables
37# and providing a more controlled/consistent search behavior.
38# Added new modifications to recognize OS X frameworks and
39# additional Unix paths (FreeBSD, etc).
40# Also corrected the header search path to follow "proper" SDL guidelines.
41# Added a search for SDL2main which is needed by some platforms.
42# Added a search for threads which is needed by some platforms.
43# Added needed compile switches for MinGW.
44#
45# On OSX, this will prefer the Framework version (if found) over others.
46# People will have to manually change the cache values of
47# SDL2_LIBRARY to override this selection or set the CMake environment
48# CMAKE_INCLUDE_PATH to modify the search paths.
49#
50# Note that the header path has changed from SDL2/SDL.h to just SDL.h
51# This needed to change because "proper" SDL convention
52# is #include "SDL.h", not <SDL2/SDL.h>. This is done for portability
53# reasons because not all systems place things in SDL2/ (see FreeBSD).
54
55#=============================================================================
56# Copyright 2003-2009 Kitware, Inc.
57#
58# Distributed under the OSI-approved BSD License (the "License").
59#
60# This software is distributed WITHOUT ANY WARRANTY; without even the
61# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
62# See the License for more information.
63#=============================================================================
64# CMake - Cross Platform Makefile Generator
65# Copyright 2000-2016 Kitware, Inc.
66# Copyright 2000-2011 Insight Software Consortium
67# All rights reserved.
68#
69# Redistribution and use in source and binary forms, with or without
70# modification, are permitted provided that the following conditions
71# are met:
72#
73# * Redistributions of source code must retain the above copyright
74# notice, this list of conditions and the following disclaimer.
75#
76# * Redistributions in binary form must reproduce the above copyright
77# notice, this list of conditions and the following disclaimer in the
78# documentation and/or other materials provided with the distribution.
79#
80# * Neither the names of Kitware, Inc., the Insight Software Consortium,
81# nor the names of their contributors may be used to endorse or promote
82# products derived from this software without specific prior written
83# permission.
84#
85# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
86# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
87# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
88# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
89# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
90# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
91# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
92# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
93# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
94# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
95# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
96#
97# ------------------------------------------------------------------------------
98#
99# The above copyright and license notice applies to distributions of
100# CMake in source and binary form. Some source files contain additional
101# notices of original copyright by their contributors; see each source
102# for details. Third-party software packages supplied with CMake under
103# compatible licenses provide their own copyright notices documented in
104# corresponding subdirectories.
105#
106# ------------------------------------------------------------------------------
107#
108# CMake was initially developed by Kitware with the following sponsorship:
109#
110# * National Library of Medicine at the National Institutes of Health
111# as part of the Insight Segmentation and Registration Toolkit (ITK).
112#
113# * US National Labs (Los Alamos, Livermore, Sandia) ASC Parallel
114# Visualization Initiative.
115#
116# * National Alliance for Medical Image Computing (NAMIC) is funded by the
117# National Institutes of Health through the NIH Roadmap for Medical Research,
118# Grant U54 EB005149.
119#
120# * Kitware, Inc.
121#
122
123message("<FindSDL2.cmake>")
124
125SET(SDL2_SEARCH_PATHS
126 ~/Library/Frameworks
127 /Library/Frameworks
128 /usr/local
129 /usr
130 /sw # Fink
131 /opt/local # DarwinPorts
132 /opt/csw # Blastwave
133 /opt
134 ${SDL2_PATH}
135)
136
137FIND_LIBRARY(SDL2_LIBRARY_TEMP
138 NAMES SDL2
139 HINTS
140 $ENV{SDL2DIR}
141 PATH_SUFFIXES lib64 lib
142 PATHS ${SDL2_SEARCH_PATHS}
143)
144
145IF(SDL2_LIBRARY_TEMP)
146 FIND_PATH(SDL2_INCLUDE_DIR SDL.h
147 HINTS
148 $ENV{SDL2DIR}
149 PATH_SUFFIXES include/SDL2 include
150 PATHS ${SDL2_SEARCH_PATHS}
151 )
152
153 IF(NOT SDL2_BUILDING_LIBRARY)
154 IF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework")
155 # Non-OS X framework versions expect you to also dynamically link to
156 # SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms
157 # seem to provide SDL2main for compatibility even though they don't
158 # necessarily need it.
159 FIND_LIBRARY(SDL2MAIN_LIBRARY
160 NAMES SDL2main
161 HINTS
162 $ENV{SDL2DIR}
163 PATH_SUFFIXES lib64 lib
164 PATHS ${SDL2_SEARCH_PATHS}
165 )
166 ENDIF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework")
167 ENDIF(NOT SDL2_BUILDING_LIBRARY)
168
169 # SDL2 may require threads on your system.
170 # The Apple build may not need an explicit flag because one of the
171 # frameworks may already provide it.
172 # But for non-OSX systems, I will use the CMake Threads package.
173 IF(NOT APPLE)
174 FIND_PACKAGE(Threads)
175 ENDIF(NOT APPLE)
176
177 # MinGW needs an additional library, mwindows
178 # It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -lmwindows
179 # (Actually on second look, I think it only needs one of the m* libraries.)
180 IF(MINGW)
181 SET(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW")
182 ENDIF(MINGW)
183
184 # For SDL2main
185 IF(NOT SDL2_BUILDING_LIBRARY)
186 IF(SDL2MAIN_LIBRARY)
187 SET(SDL2_LIBRARY_TEMP ${SDL2MAIN_LIBRARY} ${SDL2_LIBRARY_TEMP})
188 ENDIF(SDL2MAIN_LIBRARY)
189 ENDIF(NOT SDL2_BUILDING_LIBRARY)
190
191 # For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa.
192 # CMake doesn't display the -framework Cocoa string in the UI even
193 # though it actually is there if I modify a pre-used variable.
194 # I think it has something to do with the CACHE STRING.
195 # So I use a temporary variable until the end so I can set the
196 # "real" variable in one-shot.
197 IF(APPLE)
198 SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} "-framework Cocoa")
199 ENDIF(APPLE)
200
201 # For threads, as mentioned Apple doesn't need this.
202 # In fact, there seems to be a problem if I used the Threads package
203 # and try using this line, so I'm just skipping it entirely for OS X.
204 IF(NOT APPLE)
205 SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} ${CMAKE_THREAD_LIBS_INIT})
206 ENDIF(NOT APPLE)
207
208 # For MinGW library
209 IF(MINGW)
210 SET(SDL2_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL2_LIBRARY_TEMP})
211 ENDIF(MINGW)
212
213 # Set the final string here so the GUI reflects the final state.
214 SET(SDL2_LIBRARY ${SDL2_LIBRARY_TEMP} CACHE STRING "Where the SDL2 Library can be found")
215
216 # Unset the temp variable to INTERNAL so it is not seen in the CMake GUI
217 UNSET(SDL2_LIBRARY_TEMP)
218ENDIF(SDL2_LIBRARY_TEMP)
219
220message("</FindSDL2.cmake>")
221
222INCLUDE(FindPackageHandleStandardArgs)
223
224FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR)
diff --git a/externals/cmake-modules/WindowsCopyFiles.cmake b/externals/cmake-modules/WindowsCopyFiles.cmake
new file mode 100644
index 000000000..cd0c2ce47
--- /dev/null
+++ b/externals/cmake-modules/WindowsCopyFiles.cmake
@@ -0,0 +1,28 @@
1# Copyright 2016 Citra Emulator Project
2# Licensed under GPLv2 or any later version
3# Refer to the license.txt file included.
4
5# This file provides the function windows_copy_files.
6# This is only valid on Windows.
7
8# Include guard
9if(__windows_copy_files)
10 return()
11endif()
12set(__windows_copy_files YES)
13
14# Any number of files to copy from SOURCE_DIR to DEST_DIR can be specified after DEST_DIR.
15# This copying happens post-build.
16function(windows_copy_files TARGET SOURCE_DIR DEST_DIR)
17 # windows commandline expects the / to be \ so switch them
18 string(REPLACE "/" "\\\\" SOURCE_DIR ${SOURCE_DIR})
19 string(REPLACE "/" "\\\\" DEST_DIR ${DEST_DIR})
20
21 # /NJH /NJS /NDL /NFL /NC /NS /NP - Silence any output
22 # cmake adds an extra check for command success which doesn't work too well with robocopy
23 # so trick it into thinking the command was successful with the || cmd /c "exit /b 0"
24 add_custom_command(TARGET ${TARGET} POST_BUILD
25 COMMAND if not exist ${DEST_DIR} mkdir ${DEST_DIR} 2> nul
26 COMMAND robocopy ${SOURCE_DIR} ${DEST_DIR} ${ARGN} /NJH /NJS /NDL /NFL /NC /NS /NP || cmd /c "exit /b 0"
27 )
28endfunction() \ No newline at end of file
diff --git a/externals/glad/include/glad/glad.h b/externals/glad/include/glad/glad.h
index 678a5287a..6bd025683 100644
--- a/externals/glad/include/glad/glad.h
+++ b/externals/glad/include/glad/glad.h
@@ -1024,73 +1024,73 @@ typedef GLintptr GLvdpauSurfaceNV;
1024#ifndef GL_VERSION_1_0 1024#ifndef GL_VERSION_1_0
1025#define GL_VERSION_1_0 1 1025#define GL_VERSION_1_0 1
1026GLAPI int GLAD_GL_VERSION_1_0; 1026GLAPI int GLAD_GL_VERSION_1_0;
1027typedef void (APIENTRYP PFNGLCULLFACEPROC)(GLenum); 1027typedef void (APIENTRYP PFNGLCULLFACEPROC)(GLenum mode);
1028GLAPI PFNGLCULLFACEPROC glad_glCullFace; 1028GLAPI PFNGLCULLFACEPROC glad_glCullFace;
1029#define glCullFace glad_glCullFace 1029#define glCullFace glad_glCullFace
1030typedef void (APIENTRYP PFNGLFRONTFACEPROC)(GLenum); 1030typedef void (APIENTRYP PFNGLFRONTFACEPROC)(GLenum mode);
1031GLAPI PFNGLFRONTFACEPROC glad_glFrontFace; 1031GLAPI PFNGLFRONTFACEPROC glad_glFrontFace;
1032#define glFrontFace glad_glFrontFace 1032#define glFrontFace glad_glFrontFace
1033typedef void (APIENTRYP PFNGLHINTPROC)(GLenum, GLenum); 1033typedef void (APIENTRYP PFNGLHINTPROC)(GLenum target, GLenum mode);
1034GLAPI PFNGLHINTPROC glad_glHint; 1034GLAPI PFNGLHINTPROC glad_glHint;
1035#define glHint glad_glHint 1035#define glHint glad_glHint
1036typedef void (APIENTRYP PFNGLLINEWIDTHPROC)(GLfloat); 1036typedef void (APIENTRYP PFNGLLINEWIDTHPROC)(GLfloat width);
1037GLAPI PFNGLLINEWIDTHPROC glad_glLineWidth; 1037GLAPI PFNGLLINEWIDTHPROC glad_glLineWidth;
1038#define glLineWidth glad_glLineWidth 1038#define glLineWidth glad_glLineWidth
1039typedef void (APIENTRYP PFNGLPOINTSIZEPROC)(GLfloat); 1039typedef void (APIENTRYP PFNGLPOINTSIZEPROC)(GLfloat size);
1040GLAPI PFNGLPOINTSIZEPROC glad_glPointSize; 1040GLAPI PFNGLPOINTSIZEPROC glad_glPointSize;
1041#define glPointSize glad_glPointSize 1041#define glPointSize glad_glPointSize
1042typedef void (APIENTRYP PFNGLPOLYGONMODEPROC)(GLenum, GLenum); 1042typedef void (APIENTRYP PFNGLPOLYGONMODEPROC)(GLenum face, GLenum mode);
1043GLAPI PFNGLPOLYGONMODEPROC glad_glPolygonMode; 1043GLAPI PFNGLPOLYGONMODEPROC glad_glPolygonMode;
1044#define glPolygonMode glad_glPolygonMode 1044#define glPolygonMode glad_glPolygonMode
1045typedef void (APIENTRYP PFNGLSCISSORPROC)(GLint, GLint, GLsizei, GLsizei); 1045typedef void (APIENTRYP PFNGLSCISSORPROC)(GLint x, GLint y, GLsizei width, GLsizei height);
1046GLAPI PFNGLSCISSORPROC glad_glScissor; 1046GLAPI PFNGLSCISSORPROC glad_glScissor;
1047#define glScissor glad_glScissor 1047#define glScissor glad_glScissor
1048typedef void (APIENTRYP PFNGLTEXPARAMETERFPROC)(GLenum, GLenum, GLfloat); 1048typedef void (APIENTRYP PFNGLTEXPARAMETERFPROC)(GLenum target, GLenum pname, GLfloat param);
1049GLAPI PFNGLTEXPARAMETERFPROC glad_glTexParameterf; 1049GLAPI PFNGLTEXPARAMETERFPROC glad_glTexParameterf;
1050#define glTexParameterf glad_glTexParameterf 1050#define glTexParameterf glad_glTexParameterf
1051typedef void (APIENTRYP PFNGLTEXPARAMETERFVPROC)(GLenum, GLenum, const GLfloat*); 1051typedef void (APIENTRYP PFNGLTEXPARAMETERFVPROC)(GLenum target, GLenum pname, const GLfloat* params);
1052GLAPI PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv; 1052GLAPI PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv;
1053#define glTexParameterfv glad_glTexParameterfv 1053#define glTexParameterfv glad_glTexParameterfv
1054typedef void (APIENTRYP PFNGLTEXPARAMETERIPROC)(GLenum, GLenum, GLint); 1054typedef void (APIENTRYP PFNGLTEXPARAMETERIPROC)(GLenum target, GLenum pname, GLint param);
1055GLAPI PFNGLTEXPARAMETERIPROC glad_glTexParameteri; 1055GLAPI PFNGLTEXPARAMETERIPROC glad_glTexParameteri;
1056#define glTexParameteri glad_glTexParameteri 1056#define glTexParameteri glad_glTexParameteri
1057typedef void (APIENTRYP PFNGLTEXPARAMETERIVPROC)(GLenum, GLenum, const GLint*); 1057typedef void (APIENTRYP PFNGLTEXPARAMETERIVPROC)(GLenum target, GLenum pname, const GLint* params);
1058GLAPI PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv; 1058GLAPI PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv;
1059#define glTexParameteriv glad_glTexParameteriv 1059#define glTexParameteriv glad_glTexParameteriv
1060typedef void (APIENTRYP PFNGLTEXIMAGE1DPROC)(GLenum, GLint, GLint, GLsizei, GLint, GLenum, GLenum, const void*); 1060typedef void (APIENTRYP PFNGLTEXIMAGE1DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void* pixels);
1061GLAPI PFNGLTEXIMAGE1DPROC glad_glTexImage1D; 1061GLAPI PFNGLTEXIMAGE1DPROC glad_glTexImage1D;
1062#define glTexImage1D glad_glTexImage1D 1062#define glTexImage1D glad_glTexImage1D
1063typedef void (APIENTRYP PFNGLTEXIMAGE2DPROC)(GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const void*); 1063typedef void (APIENTRYP PFNGLTEXIMAGE2DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels);
1064GLAPI PFNGLTEXIMAGE2DPROC glad_glTexImage2D; 1064GLAPI PFNGLTEXIMAGE2DPROC glad_glTexImage2D;
1065#define glTexImage2D glad_glTexImage2D 1065#define glTexImage2D glad_glTexImage2D
1066typedef void (APIENTRYP PFNGLDRAWBUFFERPROC)(GLenum); 1066typedef void (APIENTRYP PFNGLDRAWBUFFERPROC)(GLenum buf);
1067GLAPI PFNGLDRAWBUFFERPROC glad_glDrawBuffer; 1067GLAPI PFNGLDRAWBUFFERPROC glad_glDrawBuffer;
1068#define glDrawBuffer glad_glDrawBuffer 1068#define glDrawBuffer glad_glDrawBuffer
1069typedef void (APIENTRYP PFNGLCLEARPROC)(GLbitfield); 1069typedef void (APIENTRYP PFNGLCLEARPROC)(GLbitfield mask);
1070GLAPI PFNGLCLEARPROC glad_glClear; 1070GLAPI PFNGLCLEARPROC glad_glClear;
1071#define glClear glad_glClear 1071#define glClear glad_glClear
1072typedef void (APIENTRYP PFNGLCLEARCOLORPROC)(GLfloat, GLfloat, GLfloat, GLfloat); 1072typedef void (APIENTRYP PFNGLCLEARCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
1073GLAPI PFNGLCLEARCOLORPROC glad_glClearColor; 1073GLAPI PFNGLCLEARCOLORPROC glad_glClearColor;
1074#define glClearColor glad_glClearColor 1074#define glClearColor glad_glClearColor
1075typedef void (APIENTRYP PFNGLCLEARSTENCILPROC)(GLint); 1075typedef void (APIENTRYP PFNGLCLEARSTENCILPROC)(GLint s);
1076GLAPI PFNGLCLEARSTENCILPROC glad_glClearStencil; 1076GLAPI PFNGLCLEARSTENCILPROC glad_glClearStencil;
1077#define glClearStencil glad_glClearStencil 1077#define glClearStencil glad_glClearStencil
1078typedef void (APIENTRYP PFNGLCLEARDEPTHPROC)(GLdouble); 1078typedef void (APIENTRYP PFNGLCLEARDEPTHPROC)(GLdouble depth);
1079GLAPI PFNGLCLEARDEPTHPROC glad_glClearDepth; 1079GLAPI PFNGLCLEARDEPTHPROC glad_glClearDepth;
1080#define glClearDepth glad_glClearDepth 1080#define glClearDepth glad_glClearDepth
1081typedef void (APIENTRYP PFNGLSTENCILMASKPROC)(GLuint); 1081typedef void (APIENTRYP PFNGLSTENCILMASKPROC)(GLuint mask);
1082GLAPI PFNGLSTENCILMASKPROC glad_glStencilMask; 1082GLAPI PFNGLSTENCILMASKPROC glad_glStencilMask;
1083#define glStencilMask glad_glStencilMask 1083#define glStencilMask glad_glStencilMask
1084typedef void (APIENTRYP PFNGLCOLORMASKPROC)(GLboolean, GLboolean, GLboolean, GLboolean); 1084typedef void (APIENTRYP PFNGLCOLORMASKPROC)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
1085GLAPI PFNGLCOLORMASKPROC glad_glColorMask; 1085GLAPI PFNGLCOLORMASKPROC glad_glColorMask;
1086#define glColorMask glad_glColorMask 1086#define glColorMask glad_glColorMask
1087typedef void (APIENTRYP PFNGLDEPTHMASKPROC)(GLboolean); 1087typedef void (APIENTRYP PFNGLDEPTHMASKPROC)(GLboolean flag);
1088GLAPI PFNGLDEPTHMASKPROC glad_glDepthMask; 1088GLAPI PFNGLDEPTHMASKPROC glad_glDepthMask;
1089#define glDepthMask glad_glDepthMask 1089#define glDepthMask glad_glDepthMask
1090typedef void (APIENTRYP PFNGLDISABLEPROC)(GLenum); 1090typedef void (APIENTRYP PFNGLDISABLEPROC)(GLenum cap);
1091GLAPI PFNGLDISABLEPROC glad_glDisable; 1091GLAPI PFNGLDISABLEPROC glad_glDisable;
1092#define glDisable glad_glDisable 1092#define glDisable glad_glDisable
1093typedef void (APIENTRYP PFNGLENABLEPROC)(GLenum); 1093typedef void (APIENTRYP PFNGLENABLEPROC)(GLenum cap);
1094GLAPI PFNGLENABLEPROC glad_glEnable; 1094GLAPI PFNGLENABLEPROC glad_glEnable;
1095#define glEnable glad_glEnable 1095#define glEnable glad_glEnable
1096typedef void (APIENTRYP PFNGLFINISHPROC)(); 1096typedef void (APIENTRYP PFNGLFINISHPROC)();
@@ -1099,1130 +1099,1130 @@ GLAPI PFNGLFINISHPROC glad_glFinish;
1099typedef void (APIENTRYP PFNGLFLUSHPROC)(); 1099typedef void (APIENTRYP PFNGLFLUSHPROC)();
1100GLAPI PFNGLFLUSHPROC glad_glFlush; 1100GLAPI PFNGLFLUSHPROC glad_glFlush;
1101#define glFlush glad_glFlush 1101#define glFlush glad_glFlush
1102typedef void (APIENTRYP PFNGLBLENDFUNCPROC)(GLenum, GLenum); 1102typedef void (APIENTRYP PFNGLBLENDFUNCPROC)(GLenum sfactor, GLenum dfactor);
1103GLAPI PFNGLBLENDFUNCPROC glad_glBlendFunc; 1103GLAPI PFNGLBLENDFUNCPROC glad_glBlendFunc;
1104#define glBlendFunc glad_glBlendFunc 1104#define glBlendFunc glad_glBlendFunc
1105typedef void (APIENTRYP PFNGLLOGICOPPROC)(GLenum); 1105typedef void (APIENTRYP PFNGLLOGICOPPROC)(GLenum opcode);
1106GLAPI PFNGLLOGICOPPROC glad_glLogicOp; 1106GLAPI PFNGLLOGICOPPROC glad_glLogicOp;
1107#define glLogicOp glad_glLogicOp 1107#define glLogicOp glad_glLogicOp
1108typedef void (APIENTRYP PFNGLSTENCILFUNCPROC)(GLenum, GLint, GLuint); 1108typedef void (APIENTRYP PFNGLSTENCILFUNCPROC)(GLenum func, GLint ref, GLuint mask);
1109GLAPI PFNGLSTENCILFUNCPROC glad_glStencilFunc; 1109GLAPI PFNGLSTENCILFUNCPROC glad_glStencilFunc;
1110#define glStencilFunc glad_glStencilFunc 1110#define glStencilFunc glad_glStencilFunc
1111typedef void (APIENTRYP PFNGLSTENCILOPPROC)(GLenum, GLenum, GLenum); 1111typedef void (APIENTRYP PFNGLSTENCILOPPROC)(GLenum fail, GLenum zfail, GLenum zpass);
1112GLAPI PFNGLSTENCILOPPROC glad_glStencilOp; 1112GLAPI PFNGLSTENCILOPPROC glad_glStencilOp;
1113#define glStencilOp glad_glStencilOp 1113#define glStencilOp glad_glStencilOp
1114typedef void (APIENTRYP PFNGLDEPTHFUNCPROC)(GLenum); 1114typedef void (APIENTRYP PFNGLDEPTHFUNCPROC)(GLenum func);
1115GLAPI PFNGLDEPTHFUNCPROC glad_glDepthFunc; 1115GLAPI PFNGLDEPTHFUNCPROC glad_glDepthFunc;
1116#define glDepthFunc glad_glDepthFunc 1116#define glDepthFunc glad_glDepthFunc
1117typedef void (APIENTRYP PFNGLPIXELSTOREFPROC)(GLenum, GLfloat); 1117typedef void (APIENTRYP PFNGLPIXELSTOREFPROC)(GLenum pname, GLfloat param);
1118GLAPI PFNGLPIXELSTOREFPROC glad_glPixelStoref; 1118GLAPI PFNGLPIXELSTOREFPROC glad_glPixelStoref;
1119#define glPixelStoref glad_glPixelStoref 1119#define glPixelStoref glad_glPixelStoref
1120typedef void (APIENTRYP PFNGLPIXELSTOREIPROC)(GLenum, GLint); 1120typedef void (APIENTRYP PFNGLPIXELSTOREIPROC)(GLenum pname, GLint param);
1121GLAPI PFNGLPIXELSTOREIPROC glad_glPixelStorei; 1121GLAPI PFNGLPIXELSTOREIPROC glad_glPixelStorei;
1122#define glPixelStorei glad_glPixelStorei 1122#define glPixelStorei glad_glPixelStorei
1123typedef void (APIENTRYP PFNGLREADBUFFERPROC)(GLenum); 1123typedef void (APIENTRYP PFNGLREADBUFFERPROC)(GLenum src);
1124GLAPI PFNGLREADBUFFERPROC glad_glReadBuffer; 1124GLAPI PFNGLREADBUFFERPROC glad_glReadBuffer;
1125#define glReadBuffer glad_glReadBuffer 1125#define glReadBuffer glad_glReadBuffer
1126typedef void (APIENTRYP PFNGLREADPIXELSPROC)(GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, void*); 1126typedef void (APIENTRYP PFNGLREADPIXELSPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels);
1127GLAPI PFNGLREADPIXELSPROC glad_glReadPixels; 1127GLAPI PFNGLREADPIXELSPROC glad_glReadPixels;
1128#define glReadPixels glad_glReadPixels 1128#define glReadPixels glad_glReadPixels
1129typedef void (APIENTRYP PFNGLGETBOOLEANVPROC)(GLenum, GLboolean*); 1129typedef void (APIENTRYP PFNGLGETBOOLEANVPROC)(GLenum pname, GLboolean* data);
1130GLAPI PFNGLGETBOOLEANVPROC glad_glGetBooleanv; 1130GLAPI PFNGLGETBOOLEANVPROC glad_glGetBooleanv;
1131#define glGetBooleanv glad_glGetBooleanv 1131#define glGetBooleanv glad_glGetBooleanv
1132typedef void (APIENTRYP PFNGLGETDOUBLEVPROC)(GLenum, GLdouble*); 1132typedef void (APIENTRYP PFNGLGETDOUBLEVPROC)(GLenum pname, GLdouble* data);
1133GLAPI PFNGLGETDOUBLEVPROC glad_glGetDoublev; 1133GLAPI PFNGLGETDOUBLEVPROC glad_glGetDoublev;
1134#define glGetDoublev glad_glGetDoublev 1134#define glGetDoublev glad_glGetDoublev
1135typedef GLenum (APIENTRYP PFNGLGETERRORPROC)(); 1135typedef GLenum (APIENTRYP PFNGLGETERRORPROC)();
1136GLAPI PFNGLGETERRORPROC glad_glGetError; 1136GLAPI PFNGLGETERRORPROC glad_glGetError;
1137#define glGetError glad_glGetError 1137#define glGetError glad_glGetError
1138typedef void (APIENTRYP PFNGLGETFLOATVPROC)(GLenum, GLfloat*); 1138typedef void (APIENTRYP PFNGLGETFLOATVPROC)(GLenum pname, GLfloat* data);
1139GLAPI PFNGLGETFLOATVPROC glad_glGetFloatv; 1139GLAPI PFNGLGETFLOATVPROC glad_glGetFloatv;
1140#define glGetFloatv glad_glGetFloatv 1140#define glGetFloatv glad_glGetFloatv
1141typedef void (APIENTRYP PFNGLGETINTEGERVPROC)(GLenum, GLint*); 1141typedef void (APIENTRYP PFNGLGETINTEGERVPROC)(GLenum pname, GLint* data);
1142GLAPI PFNGLGETINTEGERVPROC glad_glGetIntegerv; 1142GLAPI PFNGLGETINTEGERVPROC glad_glGetIntegerv;
1143#define glGetIntegerv glad_glGetIntegerv 1143#define glGetIntegerv glad_glGetIntegerv
1144typedef const GLubyte* (APIENTRYP PFNGLGETSTRINGPROC)(GLenum); 1144typedef const GLubyte* (APIENTRYP PFNGLGETSTRINGPROC)(GLenum name);
1145GLAPI PFNGLGETSTRINGPROC glad_glGetString; 1145GLAPI PFNGLGETSTRINGPROC glad_glGetString;
1146#define glGetString glad_glGetString 1146#define glGetString glad_glGetString
1147typedef void (APIENTRYP PFNGLGETTEXIMAGEPROC)(GLenum, GLint, GLenum, GLenum, void*); 1147typedef void (APIENTRYP PFNGLGETTEXIMAGEPROC)(GLenum target, GLint level, GLenum format, GLenum type, void* pixels);
1148GLAPI PFNGLGETTEXIMAGEPROC glad_glGetTexImage; 1148GLAPI PFNGLGETTEXIMAGEPROC glad_glGetTexImage;
1149#define glGetTexImage glad_glGetTexImage 1149#define glGetTexImage glad_glGetTexImage
1150typedef void (APIENTRYP PFNGLGETTEXPARAMETERFVPROC)(GLenum, GLenum, GLfloat*); 1150typedef void (APIENTRYP PFNGLGETTEXPARAMETERFVPROC)(GLenum target, GLenum pname, GLfloat* params);
1151GLAPI PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv; 1151GLAPI PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv;
1152#define glGetTexParameterfv glad_glGetTexParameterfv 1152#define glGetTexParameterfv glad_glGetTexParameterfv
1153typedef void (APIENTRYP PFNGLGETTEXPARAMETERIVPROC)(GLenum, GLenum, GLint*); 1153typedef void (APIENTRYP PFNGLGETTEXPARAMETERIVPROC)(GLenum target, GLenum pname, GLint* params);
1154GLAPI PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv; 1154GLAPI PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv;
1155#define glGetTexParameteriv glad_glGetTexParameteriv 1155#define glGetTexParameteriv glad_glGetTexParameteriv
1156typedef void (APIENTRYP PFNGLGETTEXLEVELPARAMETERFVPROC)(GLenum, GLint, GLenum, GLfloat*); 1156typedef void (APIENTRYP PFNGLGETTEXLEVELPARAMETERFVPROC)(GLenum target, GLint level, GLenum pname, GLfloat* params);
1157GLAPI PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv; 1157GLAPI PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv;
1158#define glGetTexLevelParameterfv glad_glGetTexLevelParameterfv 1158#define glGetTexLevelParameterfv glad_glGetTexLevelParameterfv
1159typedef void (APIENTRYP PFNGLGETTEXLEVELPARAMETERIVPROC)(GLenum, GLint, GLenum, GLint*); 1159typedef void (APIENTRYP PFNGLGETTEXLEVELPARAMETERIVPROC)(GLenum target, GLint level, GLenum pname, GLint* params);
1160GLAPI PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv; 1160GLAPI PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv;
1161#define glGetTexLevelParameteriv glad_glGetTexLevelParameteriv 1161#define glGetTexLevelParameteriv glad_glGetTexLevelParameteriv
1162typedef GLboolean (APIENTRYP PFNGLISENABLEDPROC)(GLenum); 1162typedef GLboolean (APIENTRYP PFNGLISENABLEDPROC)(GLenum cap);
1163GLAPI PFNGLISENABLEDPROC glad_glIsEnabled; 1163GLAPI PFNGLISENABLEDPROC glad_glIsEnabled;
1164#define glIsEnabled glad_glIsEnabled 1164#define glIsEnabled glad_glIsEnabled
1165typedef void (APIENTRYP PFNGLDEPTHRANGEPROC)(GLdouble, GLdouble); 1165typedef void (APIENTRYP PFNGLDEPTHRANGEPROC)(GLdouble near, GLdouble far);
1166GLAPI PFNGLDEPTHRANGEPROC glad_glDepthRange; 1166GLAPI PFNGLDEPTHRANGEPROC glad_glDepthRange;
1167#define glDepthRange glad_glDepthRange 1167#define glDepthRange glad_glDepthRange
1168typedef void (APIENTRYP PFNGLVIEWPORTPROC)(GLint, GLint, GLsizei, GLsizei); 1168typedef void (APIENTRYP PFNGLVIEWPORTPROC)(GLint x, GLint y, GLsizei width, GLsizei height);
1169GLAPI PFNGLVIEWPORTPROC glad_glViewport; 1169GLAPI PFNGLVIEWPORTPROC glad_glViewport;
1170#define glViewport glad_glViewport 1170#define glViewport glad_glViewport
1171#endif 1171#endif
1172#ifndef GL_VERSION_1_1 1172#ifndef GL_VERSION_1_1
1173#define GL_VERSION_1_1 1 1173#define GL_VERSION_1_1 1
1174GLAPI int GLAD_GL_VERSION_1_1; 1174GLAPI int GLAD_GL_VERSION_1_1;
1175typedef void (APIENTRYP PFNGLDRAWARRAYSPROC)(GLenum, GLint, GLsizei); 1175typedef void (APIENTRYP PFNGLDRAWARRAYSPROC)(GLenum mode, GLint first, GLsizei count);
1176GLAPI PFNGLDRAWARRAYSPROC glad_glDrawArrays; 1176GLAPI PFNGLDRAWARRAYSPROC glad_glDrawArrays;
1177#define glDrawArrays glad_glDrawArrays 1177#define glDrawArrays glad_glDrawArrays
1178typedef void (APIENTRYP PFNGLDRAWELEMENTSPROC)(GLenum, GLsizei, GLenum, const void*); 1178typedef void (APIENTRYP PFNGLDRAWELEMENTSPROC)(GLenum mode, GLsizei count, GLenum type, const void* indices);
1179GLAPI PFNGLDRAWELEMENTSPROC glad_glDrawElements; 1179GLAPI PFNGLDRAWELEMENTSPROC glad_glDrawElements;
1180#define glDrawElements glad_glDrawElements 1180#define glDrawElements glad_glDrawElements
1181typedef void (APIENTRYP PFNGLPOLYGONOFFSETPROC)(GLfloat, GLfloat); 1181typedef void (APIENTRYP PFNGLPOLYGONOFFSETPROC)(GLfloat factor, GLfloat units);
1182GLAPI PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset; 1182GLAPI PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset;
1183#define glPolygonOffset glad_glPolygonOffset 1183#define glPolygonOffset glad_glPolygonOffset
1184typedef void (APIENTRYP PFNGLCOPYTEXIMAGE1DPROC)(GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint); 1184typedef void (APIENTRYP PFNGLCOPYTEXIMAGE1DPROC)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
1185GLAPI PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D; 1185GLAPI PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D;
1186#define glCopyTexImage1D glad_glCopyTexImage1D 1186#define glCopyTexImage1D glad_glCopyTexImage1D
1187typedef void (APIENTRYP PFNGLCOPYTEXIMAGE2DPROC)(GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint); 1187typedef void (APIENTRYP PFNGLCOPYTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
1188GLAPI PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D; 1188GLAPI PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D;
1189#define glCopyTexImage2D glad_glCopyTexImage2D 1189#define glCopyTexImage2D glad_glCopyTexImage2D
1190typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE1DPROC)(GLenum, GLint, GLint, GLint, GLint, GLsizei); 1190typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
1191GLAPI PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D; 1191GLAPI PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D;
1192#define glCopyTexSubImage1D glad_glCopyTexSubImage1D 1192#define glCopyTexSubImage1D glad_glCopyTexSubImage1D
1193typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE2DPROC)(GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); 1193typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
1194GLAPI PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D; 1194GLAPI PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D;
1195#define glCopyTexSubImage2D glad_glCopyTexSubImage2D 1195#define glCopyTexSubImage2D glad_glCopyTexSubImage2D
1196typedef void (APIENTRYP PFNGLTEXSUBIMAGE1DPROC)(GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const void*); 1196typedef void (APIENTRYP PFNGLTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void* pixels);
1197GLAPI PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D; 1197GLAPI PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D;
1198#define glTexSubImage1D glad_glTexSubImage1D 1198#define glTexSubImage1D glad_glTexSubImage1D
1199typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DPROC)(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const void*); 1199typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels);
1200GLAPI PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D; 1200GLAPI PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D;
1201#define glTexSubImage2D glad_glTexSubImage2D 1201#define glTexSubImage2D glad_glTexSubImage2D
1202typedef void (APIENTRYP PFNGLBINDTEXTUREPROC)(GLenum, GLuint); 1202typedef void (APIENTRYP PFNGLBINDTEXTUREPROC)(GLenum target, GLuint texture);
1203GLAPI PFNGLBINDTEXTUREPROC glad_glBindTexture; 1203GLAPI PFNGLBINDTEXTUREPROC glad_glBindTexture;
1204#define glBindTexture glad_glBindTexture 1204#define glBindTexture glad_glBindTexture
1205typedef void (APIENTRYP PFNGLDELETETEXTURESPROC)(GLsizei, const GLuint*); 1205typedef void (APIENTRYP PFNGLDELETETEXTURESPROC)(GLsizei n, const GLuint* textures);
1206GLAPI PFNGLDELETETEXTURESPROC glad_glDeleteTextures; 1206GLAPI PFNGLDELETETEXTURESPROC glad_glDeleteTextures;
1207#define glDeleteTextures glad_glDeleteTextures 1207#define glDeleteTextures glad_glDeleteTextures
1208typedef void (APIENTRYP PFNGLGENTEXTURESPROC)(GLsizei, GLuint*); 1208typedef void (APIENTRYP PFNGLGENTEXTURESPROC)(GLsizei n, GLuint* textures);
1209GLAPI PFNGLGENTEXTURESPROC glad_glGenTextures; 1209GLAPI PFNGLGENTEXTURESPROC glad_glGenTextures;
1210#define glGenTextures glad_glGenTextures 1210#define glGenTextures glad_glGenTextures
1211typedef GLboolean (APIENTRYP PFNGLISTEXTUREPROC)(GLuint); 1211typedef GLboolean (APIENTRYP PFNGLISTEXTUREPROC)(GLuint texture);
1212GLAPI PFNGLISTEXTUREPROC glad_glIsTexture; 1212GLAPI PFNGLISTEXTUREPROC glad_glIsTexture;
1213#define glIsTexture glad_glIsTexture 1213#define glIsTexture glad_glIsTexture
1214#endif 1214#endif
1215#ifndef GL_VERSION_1_2 1215#ifndef GL_VERSION_1_2
1216#define GL_VERSION_1_2 1 1216#define GL_VERSION_1_2 1
1217GLAPI int GLAD_GL_VERSION_1_2; 1217GLAPI int GLAD_GL_VERSION_1_2;
1218typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC)(GLenum, GLuint, GLuint, GLsizei, GLenum, const void*); 1218typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices);
1219GLAPI PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements; 1219GLAPI PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements;
1220#define glDrawRangeElements glad_glDrawRangeElements 1220#define glDrawRangeElements glad_glDrawRangeElements
1221typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC)(GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const void*); 1221typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels);
1222GLAPI PFNGLTEXIMAGE3DPROC glad_glTexImage3D; 1222GLAPI PFNGLTEXIMAGE3DPROC glad_glTexImage3D;
1223#define glTexImage3D glad_glTexImage3D 1223#define glTexImage3D glad_glTexImage3D
1224typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const void*); 1224typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels);
1225GLAPI PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D; 1225GLAPI PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D;
1226#define glTexSubImage3D glad_glTexSubImage3D 1226#define glTexSubImage3D glad_glTexSubImage3D
1227typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC)(GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); 1227typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
1228GLAPI PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D; 1228GLAPI PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D;
1229#define glCopyTexSubImage3D glad_glCopyTexSubImage3D 1229#define glCopyTexSubImage3D glad_glCopyTexSubImage3D
1230#endif 1230#endif
1231#ifndef GL_VERSION_1_3 1231#ifndef GL_VERSION_1_3
1232#define GL_VERSION_1_3 1 1232#define GL_VERSION_1_3 1
1233GLAPI int GLAD_GL_VERSION_1_3; 1233GLAPI int GLAD_GL_VERSION_1_3;
1234typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC)(GLenum); 1234typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC)(GLenum texture);
1235GLAPI PFNGLACTIVETEXTUREPROC glad_glActiveTexture; 1235GLAPI PFNGLACTIVETEXTUREPROC glad_glActiveTexture;
1236#define glActiveTexture glad_glActiveTexture 1236#define glActiveTexture glad_glActiveTexture
1237typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC)(GLfloat, GLboolean); 1237typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC)(GLfloat value, GLboolean invert);
1238GLAPI PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage; 1238GLAPI PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage;
1239#define glSampleCoverage glad_glSampleCoverage 1239#define glSampleCoverage glad_glSampleCoverage
1240typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const void*); 1240typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data);
1241GLAPI PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D; 1241GLAPI PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D;
1242#define glCompressedTexImage3D glad_glCompressedTexImage3D 1242#define glCompressedTexImage3D glad_glCompressedTexImage3D
1243typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const void*); 1243typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data);
1244GLAPI PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D; 1244GLAPI PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D;
1245#define glCompressedTexImage2D glad_glCompressedTexImage2D 1245#define glCompressedTexImage2D glad_glCompressedTexImage2D
1246typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC)(GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const void*); 1246typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void* data);
1247GLAPI PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D; 1247GLAPI PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D;
1248#define glCompressedTexImage1D glad_glCompressedTexImage1D 1248#define glCompressedTexImage1D glad_glCompressedTexImage1D
1249typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const void*); 1249typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data);
1250GLAPI PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D; 1250GLAPI PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D;
1251#define glCompressedTexSubImage3D glad_glCompressedTexSubImage3D 1251#define glCompressedTexSubImage3D glad_glCompressedTexSubImage3D
1252typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const void*); 1252typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data);
1253GLAPI PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D; 1253GLAPI PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D;
1254#define glCompressedTexSubImage2D glad_glCompressedTexSubImage2D 1254#define glCompressedTexSubImage2D glad_glCompressedTexSubImage2D
1255typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)(GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const void*); 1255typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void* data);
1256GLAPI PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D; 1256GLAPI PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D;
1257#define glCompressedTexSubImage1D glad_glCompressedTexSubImage1D 1257#define glCompressedTexSubImage1D glad_glCompressedTexSubImage1D
1258typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC)(GLenum, GLint, void*); 1258typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC)(GLenum target, GLint level, void* img);
1259GLAPI PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage; 1259GLAPI PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage;
1260#define glGetCompressedTexImage glad_glGetCompressedTexImage 1260#define glGetCompressedTexImage glad_glGetCompressedTexImage
1261#endif 1261#endif
1262#ifndef GL_VERSION_1_4 1262#ifndef GL_VERSION_1_4
1263#define GL_VERSION_1_4 1 1263#define GL_VERSION_1_4 1
1264GLAPI int GLAD_GL_VERSION_1_4; 1264GLAPI int GLAD_GL_VERSION_1_4;
1265typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC)(GLenum, GLenum, GLenum, GLenum); 1265typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
1266GLAPI PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate; 1266GLAPI PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate;
1267#define glBlendFuncSeparate glad_glBlendFuncSeparate 1267#define glBlendFuncSeparate glad_glBlendFuncSeparate
1268typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSPROC)(GLenum, const GLint*, const GLsizei*, GLsizei); 1268typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSPROC)(GLenum mode, const GLint* first, const GLsizei* count, GLsizei drawcount);
1269GLAPI PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays; 1269GLAPI PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays;
1270#define glMultiDrawArrays glad_glMultiDrawArrays 1270#define glMultiDrawArrays glad_glMultiDrawArrays
1271typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSPROC)(GLenum, const GLsizei*, GLenum, const void**, GLsizei); 1271typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSPROC)(GLenum mode, const GLsizei* count, GLenum type, const void** indices, GLsizei drawcount);
1272GLAPI PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements; 1272GLAPI PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements;
1273#define glMultiDrawElements glad_glMultiDrawElements 1273#define glMultiDrawElements glad_glMultiDrawElements
1274typedef void (APIENTRYP PFNGLPOINTPARAMETERFPROC)(GLenum, GLfloat); 1274typedef void (APIENTRYP PFNGLPOINTPARAMETERFPROC)(GLenum pname, GLfloat param);
1275GLAPI PFNGLPOINTPARAMETERFPROC glad_glPointParameterf; 1275GLAPI PFNGLPOINTPARAMETERFPROC glad_glPointParameterf;
1276#define glPointParameterf glad_glPointParameterf 1276#define glPointParameterf glad_glPointParameterf
1277typedef void (APIENTRYP PFNGLPOINTPARAMETERFVPROC)(GLenum, const GLfloat*); 1277typedef void (APIENTRYP PFNGLPOINTPARAMETERFVPROC)(GLenum pname, const GLfloat* params);
1278GLAPI PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv; 1278GLAPI PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv;
1279#define glPointParameterfv glad_glPointParameterfv 1279#define glPointParameterfv glad_glPointParameterfv
1280typedef void (APIENTRYP PFNGLPOINTPARAMETERIPROC)(GLenum, GLint); 1280typedef void (APIENTRYP PFNGLPOINTPARAMETERIPROC)(GLenum pname, GLint param);
1281GLAPI PFNGLPOINTPARAMETERIPROC glad_glPointParameteri; 1281GLAPI PFNGLPOINTPARAMETERIPROC glad_glPointParameteri;
1282#define glPointParameteri glad_glPointParameteri 1282#define glPointParameteri glad_glPointParameteri
1283typedef void (APIENTRYP PFNGLPOINTPARAMETERIVPROC)(GLenum, const GLint*); 1283typedef void (APIENTRYP PFNGLPOINTPARAMETERIVPROC)(GLenum pname, const GLint* params);
1284GLAPI PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv; 1284GLAPI PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv;
1285#define glPointParameteriv glad_glPointParameteriv 1285#define glPointParameteriv glad_glPointParameteriv
1286typedef void (APIENTRYP PFNGLBLENDCOLORPROC)(GLfloat, GLfloat, GLfloat, GLfloat); 1286typedef void (APIENTRYP PFNGLBLENDCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
1287GLAPI PFNGLBLENDCOLORPROC glad_glBlendColor; 1287GLAPI PFNGLBLENDCOLORPROC glad_glBlendColor;
1288#define glBlendColor glad_glBlendColor 1288#define glBlendColor glad_glBlendColor
1289typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC)(GLenum); 1289typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC)(GLenum mode);
1290GLAPI PFNGLBLENDEQUATIONPROC glad_glBlendEquation; 1290GLAPI PFNGLBLENDEQUATIONPROC glad_glBlendEquation;
1291#define glBlendEquation glad_glBlendEquation 1291#define glBlendEquation glad_glBlendEquation
1292#endif 1292#endif
1293#ifndef GL_VERSION_1_5 1293#ifndef GL_VERSION_1_5
1294#define GL_VERSION_1_5 1 1294#define GL_VERSION_1_5 1
1295GLAPI int GLAD_GL_VERSION_1_5; 1295GLAPI int GLAD_GL_VERSION_1_5;
1296typedef void (APIENTRYP PFNGLGENQUERIESPROC)(GLsizei, GLuint*); 1296typedef void (APIENTRYP PFNGLGENQUERIESPROC)(GLsizei n, GLuint* ids);
1297GLAPI PFNGLGENQUERIESPROC glad_glGenQueries; 1297GLAPI PFNGLGENQUERIESPROC glad_glGenQueries;
1298#define glGenQueries glad_glGenQueries 1298#define glGenQueries glad_glGenQueries
1299typedef void (APIENTRYP PFNGLDELETEQUERIESPROC)(GLsizei, const GLuint*); 1299typedef void (APIENTRYP PFNGLDELETEQUERIESPROC)(GLsizei n, const GLuint* ids);
1300GLAPI PFNGLDELETEQUERIESPROC glad_glDeleteQueries; 1300GLAPI PFNGLDELETEQUERIESPROC glad_glDeleteQueries;
1301#define glDeleteQueries glad_glDeleteQueries 1301#define glDeleteQueries glad_glDeleteQueries
1302typedef GLboolean (APIENTRYP PFNGLISQUERYPROC)(GLuint); 1302typedef GLboolean (APIENTRYP PFNGLISQUERYPROC)(GLuint id);
1303GLAPI PFNGLISQUERYPROC glad_glIsQuery; 1303GLAPI PFNGLISQUERYPROC glad_glIsQuery;
1304#define glIsQuery glad_glIsQuery 1304#define glIsQuery glad_glIsQuery
1305typedef void (APIENTRYP PFNGLBEGINQUERYPROC)(GLenum, GLuint); 1305typedef void (APIENTRYP PFNGLBEGINQUERYPROC)(GLenum target, GLuint id);
1306GLAPI PFNGLBEGINQUERYPROC glad_glBeginQuery; 1306GLAPI PFNGLBEGINQUERYPROC glad_glBeginQuery;
1307#define glBeginQuery glad_glBeginQuery 1307#define glBeginQuery glad_glBeginQuery
1308typedef void (APIENTRYP PFNGLENDQUERYPROC)(GLenum); 1308typedef void (APIENTRYP PFNGLENDQUERYPROC)(GLenum target);
1309GLAPI PFNGLENDQUERYPROC glad_glEndQuery; 1309GLAPI PFNGLENDQUERYPROC glad_glEndQuery;
1310#define glEndQuery glad_glEndQuery 1310#define glEndQuery glad_glEndQuery
1311typedef void (APIENTRYP PFNGLGETQUERYIVPROC)(GLenum, GLenum, GLint*); 1311typedef void (APIENTRYP PFNGLGETQUERYIVPROC)(GLenum target, GLenum pname, GLint* params);
1312GLAPI PFNGLGETQUERYIVPROC glad_glGetQueryiv; 1312GLAPI PFNGLGETQUERYIVPROC glad_glGetQueryiv;
1313#define glGetQueryiv glad_glGetQueryiv 1313#define glGetQueryiv glad_glGetQueryiv
1314typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVPROC)(GLuint, GLenum, GLint*); 1314typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVPROC)(GLuint id, GLenum pname, GLint* params);
1315GLAPI PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv; 1315GLAPI PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv;
1316#define glGetQueryObjectiv glad_glGetQueryObjectiv 1316#define glGetQueryObjectiv glad_glGetQueryObjectiv
1317typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVPROC)(GLuint, GLenum, GLuint*); 1317typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVPROC)(GLuint id, GLenum pname, GLuint* params);
1318GLAPI PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv; 1318GLAPI PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv;
1319#define glGetQueryObjectuiv glad_glGetQueryObjectuiv 1319#define glGetQueryObjectuiv glad_glGetQueryObjectuiv
1320typedef void (APIENTRYP PFNGLBINDBUFFERPROC)(GLenum, GLuint); 1320typedef void (APIENTRYP PFNGLBINDBUFFERPROC)(GLenum target, GLuint buffer);
1321GLAPI PFNGLBINDBUFFERPROC glad_glBindBuffer; 1321GLAPI PFNGLBINDBUFFERPROC glad_glBindBuffer;
1322#define glBindBuffer glad_glBindBuffer 1322#define glBindBuffer glad_glBindBuffer
1323typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC)(GLsizei, const GLuint*); 1323typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC)(GLsizei n, const GLuint* buffers);
1324GLAPI PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers; 1324GLAPI PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers;
1325#define glDeleteBuffers glad_glDeleteBuffers 1325#define glDeleteBuffers glad_glDeleteBuffers
1326typedef void (APIENTRYP PFNGLGENBUFFERSPROC)(GLsizei, GLuint*); 1326typedef void (APIENTRYP PFNGLGENBUFFERSPROC)(GLsizei n, GLuint* buffers);
1327GLAPI PFNGLGENBUFFERSPROC glad_glGenBuffers; 1327GLAPI PFNGLGENBUFFERSPROC glad_glGenBuffers;
1328#define glGenBuffers glad_glGenBuffers 1328#define glGenBuffers glad_glGenBuffers
1329typedef GLboolean (APIENTRYP PFNGLISBUFFERPROC)(GLuint); 1329typedef GLboolean (APIENTRYP PFNGLISBUFFERPROC)(GLuint buffer);
1330GLAPI PFNGLISBUFFERPROC glad_glIsBuffer; 1330GLAPI PFNGLISBUFFERPROC glad_glIsBuffer;
1331#define glIsBuffer glad_glIsBuffer 1331#define glIsBuffer glad_glIsBuffer
1332typedef void (APIENTRYP PFNGLBUFFERDATAPROC)(GLenum, GLsizeiptr, const void*, GLenum); 1332typedef void (APIENTRYP PFNGLBUFFERDATAPROC)(GLenum target, GLsizeiptr size, const void* data, GLenum usage);
1333GLAPI PFNGLBUFFERDATAPROC glad_glBufferData; 1333GLAPI PFNGLBUFFERDATAPROC glad_glBufferData;
1334#define glBufferData glad_glBufferData 1334#define glBufferData glad_glBufferData
1335typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC)(GLenum, GLintptr, GLsizeiptr, const void*); 1335typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC)(GLenum target, GLintptr offset, GLsizeiptr size, const void* data);
1336GLAPI PFNGLBUFFERSUBDATAPROC glad_glBufferSubData; 1336GLAPI PFNGLBUFFERSUBDATAPROC glad_glBufferSubData;
1337#define glBufferSubData glad_glBufferSubData 1337#define glBufferSubData glad_glBufferSubData
1338typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAPROC)(GLenum, GLintptr, GLsizeiptr, void*); 1338typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAPROC)(GLenum target, GLintptr offset, GLsizeiptr size, void* data);
1339GLAPI PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData; 1339GLAPI PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData;
1340#define glGetBufferSubData glad_glGetBufferSubData 1340#define glGetBufferSubData glad_glGetBufferSubData
1341typedef void* (APIENTRYP PFNGLMAPBUFFERPROC)(GLenum, GLenum); 1341typedef void* (APIENTRYP PFNGLMAPBUFFERPROC)(GLenum target, GLenum access);
1342GLAPI PFNGLMAPBUFFERPROC glad_glMapBuffer; 1342GLAPI PFNGLMAPBUFFERPROC glad_glMapBuffer;
1343#define glMapBuffer glad_glMapBuffer 1343#define glMapBuffer glad_glMapBuffer
1344typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC)(GLenum); 1344typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC)(GLenum target);
1345GLAPI PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer; 1345GLAPI PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer;
1346#define glUnmapBuffer glad_glUnmapBuffer 1346#define glUnmapBuffer glad_glUnmapBuffer
1347typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC)(GLenum, GLenum, GLint*); 1347typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint* params);
1348GLAPI PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv; 1348GLAPI PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv;
1349#define glGetBufferParameteriv glad_glGetBufferParameteriv 1349#define glGetBufferParameteriv glad_glGetBufferParameteriv
1350typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVPROC)(GLenum, GLenum, void**); 1350typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVPROC)(GLenum target, GLenum pname, void** params);
1351GLAPI PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv; 1351GLAPI PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv;
1352#define glGetBufferPointerv glad_glGetBufferPointerv 1352#define glGetBufferPointerv glad_glGetBufferPointerv
1353#endif 1353#endif
1354#ifndef GL_VERSION_2_0 1354#ifndef GL_VERSION_2_0
1355#define GL_VERSION_2_0 1 1355#define GL_VERSION_2_0 1
1356GLAPI int GLAD_GL_VERSION_2_0; 1356GLAPI int GLAD_GL_VERSION_2_0;
1357typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC)(GLenum, GLenum); 1357typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC)(GLenum modeRGB, GLenum modeAlpha);
1358GLAPI PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate; 1358GLAPI PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate;
1359#define glBlendEquationSeparate glad_glBlendEquationSeparate 1359#define glBlendEquationSeparate glad_glBlendEquationSeparate
1360typedef void (APIENTRYP PFNGLDRAWBUFFERSPROC)(GLsizei, const GLenum*); 1360typedef void (APIENTRYP PFNGLDRAWBUFFERSPROC)(GLsizei n, const GLenum* bufs);
1361GLAPI PFNGLDRAWBUFFERSPROC glad_glDrawBuffers; 1361GLAPI PFNGLDRAWBUFFERSPROC glad_glDrawBuffers;
1362#define glDrawBuffers glad_glDrawBuffers 1362#define glDrawBuffers glad_glDrawBuffers
1363typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEPROC)(GLenum, GLenum, GLenum, GLenum); 1363typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEPROC)(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
1364GLAPI PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate; 1364GLAPI PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate;
1365#define glStencilOpSeparate glad_glStencilOpSeparate 1365#define glStencilOpSeparate glad_glStencilOpSeparate
1366typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC)(GLenum, GLenum, GLint, GLuint); 1366typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC)(GLenum face, GLenum func, GLint ref, GLuint mask);
1367GLAPI PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate; 1367GLAPI PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate;
1368#define glStencilFuncSeparate glad_glStencilFuncSeparate 1368#define glStencilFuncSeparate glad_glStencilFuncSeparate
1369typedef void (APIENTRYP PFNGLSTENCILMASKSEPARATEPROC)(GLenum, GLuint); 1369typedef void (APIENTRYP PFNGLSTENCILMASKSEPARATEPROC)(GLenum face, GLuint mask);
1370GLAPI PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate; 1370GLAPI PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate;
1371#define glStencilMaskSeparate glad_glStencilMaskSeparate 1371#define glStencilMaskSeparate glad_glStencilMaskSeparate
1372typedef void (APIENTRYP PFNGLATTACHSHADERPROC)(GLuint, GLuint); 1372typedef void (APIENTRYP PFNGLATTACHSHADERPROC)(GLuint program, GLuint shader);
1373GLAPI PFNGLATTACHSHADERPROC glad_glAttachShader; 1373GLAPI PFNGLATTACHSHADERPROC glad_glAttachShader;
1374#define glAttachShader glad_glAttachShader 1374#define glAttachShader glad_glAttachShader
1375typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONPROC)(GLuint, GLuint, const GLchar*); 1375typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONPROC)(GLuint program, GLuint index, const GLchar* name);
1376GLAPI PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation; 1376GLAPI PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation;
1377#define glBindAttribLocation glad_glBindAttribLocation 1377#define glBindAttribLocation glad_glBindAttribLocation
1378typedef void (APIENTRYP PFNGLCOMPILESHADERPROC)(GLuint); 1378typedef void (APIENTRYP PFNGLCOMPILESHADERPROC)(GLuint shader);
1379GLAPI PFNGLCOMPILESHADERPROC glad_glCompileShader; 1379GLAPI PFNGLCOMPILESHADERPROC glad_glCompileShader;
1380#define glCompileShader glad_glCompileShader 1380#define glCompileShader glad_glCompileShader
1381typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC)(); 1381typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC)();
1382GLAPI PFNGLCREATEPROGRAMPROC glad_glCreateProgram; 1382GLAPI PFNGLCREATEPROGRAMPROC glad_glCreateProgram;
1383#define glCreateProgram glad_glCreateProgram 1383#define glCreateProgram glad_glCreateProgram
1384typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC)(GLenum); 1384typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC)(GLenum type);
1385GLAPI PFNGLCREATESHADERPROC glad_glCreateShader; 1385GLAPI PFNGLCREATESHADERPROC glad_glCreateShader;
1386#define glCreateShader glad_glCreateShader 1386#define glCreateShader glad_glCreateShader
1387typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC)(GLuint); 1387typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC)(GLuint program);
1388GLAPI PFNGLDELETEPROGRAMPROC glad_glDeleteProgram; 1388GLAPI PFNGLDELETEPROGRAMPROC glad_glDeleteProgram;
1389#define glDeleteProgram glad_glDeleteProgram 1389#define glDeleteProgram glad_glDeleteProgram
1390typedef void (APIENTRYP PFNGLDELETESHADERPROC)(GLuint); 1390typedef void (APIENTRYP PFNGLDELETESHADERPROC)(GLuint shader);
1391GLAPI PFNGLDELETESHADERPROC glad_glDeleteShader; 1391GLAPI PFNGLDELETESHADERPROC glad_glDeleteShader;
1392#define glDeleteShader glad_glDeleteShader 1392#define glDeleteShader glad_glDeleteShader
1393typedef void (APIENTRYP PFNGLDETACHSHADERPROC)(GLuint, GLuint); 1393typedef void (APIENTRYP PFNGLDETACHSHADERPROC)(GLuint program, GLuint shader);
1394GLAPI PFNGLDETACHSHADERPROC glad_glDetachShader; 1394GLAPI PFNGLDETACHSHADERPROC glad_glDetachShader;
1395#define glDetachShader glad_glDetachShader 1395#define glDetachShader glad_glDetachShader
1396typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC)(GLuint); 1396typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC)(GLuint index);
1397GLAPI PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray; 1397GLAPI PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray;
1398#define glDisableVertexAttribArray glad_glDisableVertexAttribArray 1398#define glDisableVertexAttribArray glad_glDisableVertexAttribArray
1399typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC)(GLuint); 1399typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC)(GLuint index);
1400GLAPI PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray; 1400GLAPI PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray;
1401#define glEnableVertexAttribArray glad_glEnableVertexAttribArray 1401#define glEnableVertexAttribArray glad_glEnableVertexAttribArray
1402typedef void (APIENTRYP PFNGLGETACTIVEATTRIBPROC)(GLuint, GLuint, GLsizei, GLsizei*, GLint*, GLenum*, GLchar*); 1402typedef void (APIENTRYP PFNGLGETACTIVEATTRIBPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
1403GLAPI PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib; 1403GLAPI PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib;
1404#define glGetActiveAttrib glad_glGetActiveAttrib 1404#define glGetActiveAttrib glad_glGetActiveAttrib
1405typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMPROC)(GLuint, GLuint, GLsizei, GLsizei*, GLint*, GLenum*, GLchar*); 1405typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
1406GLAPI PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform; 1406GLAPI PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform;
1407#define glGetActiveUniform glad_glGetActiveUniform 1407#define glGetActiveUniform glad_glGetActiveUniform
1408typedef void (APIENTRYP PFNGLGETATTACHEDSHADERSPROC)(GLuint, GLsizei, GLsizei*, GLuint*); 1408typedef void (APIENTRYP PFNGLGETATTACHEDSHADERSPROC)(GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders);
1409GLAPI PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders; 1409GLAPI PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders;
1410#define glGetAttachedShaders glad_glGetAttachedShaders 1410#define glGetAttachedShaders glad_glGetAttachedShaders
1411typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC)(GLuint, const GLchar*); 1411typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC)(GLuint program, const GLchar* name);
1412GLAPI PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation; 1412GLAPI PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation;
1413#define glGetAttribLocation glad_glGetAttribLocation 1413#define glGetAttribLocation glad_glGetAttribLocation
1414typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC)(GLuint, GLenum, GLint*); 1414typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC)(GLuint program, GLenum pname, GLint* params);
1415GLAPI PFNGLGETPROGRAMIVPROC glad_glGetProgramiv; 1415GLAPI PFNGLGETPROGRAMIVPROC glad_glGetProgramiv;
1416#define glGetProgramiv glad_glGetProgramiv 1416#define glGetProgramiv glad_glGetProgramiv
1417typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC)(GLuint, GLsizei, GLsizei*, GLchar*); 1417typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC)(GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog);
1418GLAPI PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog; 1418GLAPI PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog;
1419#define glGetProgramInfoLog glad_glGetProgramInfoLog 1419#define glGetProgramInfoLog glad_glGetProgramInfoLog
1420typedef void (APIENTRYP PFNGLGETSHADERIVPROC)(GLuint, GLenum, GLint*); 1420typedef void (APIENTRYP PFNGLGETSHADERIVPROC)(GLuint shader, GLenum pname, GLint* params);
1421GLAPI PFNGLGETSHADERIVPROC glad_glGetShaderiv; 1421GLAPI PFNGLGETSHADERIVPROC glad_glGetShaderiv;
1422#define glGetShaderiv glad_glGetShaderiv 1422#define glGetShaderiv glad_glGetShaderiv
1423typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC)(GLuint, GLsizei, GLsizei*, GLchar*); 1423typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC)(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog);
1424GLAPI PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog; 1424GLAPI PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog;
1425#define glGetShaderInfoLog glad_glGetShaderInfoLog 1425#define glGetShaderInfoLog glad_glGetShaderInfoLog
1426typedef void (APIENTRYP PFNGLGETSHADERSOURCEPROC)(GLuint, GLsizei, GLsizei*, GLchar*); 1426typedef void (APIENTRYP PFNGLGETSHADERSOURCEPROC)(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* source);
1427GLAPI PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource; 1427GLAPI PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource;
1428#define glGetShaderSource glad_glGetShaderSource 1428#define glGetShaderSource glad_glGetShaderSource
1429typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC)(GLuint, const GLchar*); 1429typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC)(GLuint program, const GLchar* name);
1430GLAPI PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation; 1430GLAPI PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation;
1431#define glGetUniformLocation glad_glGetUniformLocation 1431#define glGetUniformLocation glad_glGetUniformLocation
1432typedef void (APIENTRYP PFNGLGETUNIFORMFVPROC)(GLuint, GLint, GLfloat*); 1432typedef void (APIENTRYP PFNGLGETUNIFORMFVPROC)(GLuint program, GLint location, GLfloat* params);
1433GLAPI PFNGLGETUNIFORMFVPROC glad_glGetUniformfv; 1433GLAPI PFNGLGETUNIFORMFVPROC glad_glGetUniformfv;
1434#define glGetUniformfv glad_glGetUniformfv 1434#define glGetUniformfv glad_glGetUniformfv
1435typedef void (APIENTRYP PFNGLGETUNIFORMIVPROC)(GLuint, GLint, GLint*); 1435typedef void (APIENTRYP PFNGLGETUNIFORMIVPROC)(GLuint program, GLint location, GLint* params);
1436GLAPI PFNGLGETUNIFORMIVPROC glad_glGetUniformiv; 1436GLAPI PFNGLGETUNIFORMIVPROC glad_glGetUniformiv;
1437#define glGetUniformiv glad_glGetUniformiv 1437#define glGetUniformiv glad_glGetUniformiv
1438typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVPROC)(GLuint, GLenum, GLdouble*); 1438typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVPROC)(GLuint index, GLenum pname, GLdouble* params);
1439GLAPI PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv; 1439GLAPI PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv;
1440#define glGetVertexAttribdv glad_glGetVertexAttribdv 1440#define glGetVertexAttribdv glad_glGetVertexAttribdv
1441typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVPROC)(GLuint, GLenum, GLfloat*); 1441typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVPROC)(GLuint index, GLenum pname, GLfloat* params);
1442GLAPI PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv; 1442GLAPI PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv;
1443#define glGetVertexAttribfv glad_glGetVertexAttribfv 1443#define glGetVertexAttribfv glad_glGetVertexAttribfv
1444typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC)(GLuint, GLenum, GLint*); 1444typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC)(GLuint index, GLenum pname, GLint* params);
1445GLAPI PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv; 1445GLAPI PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv;
1446#define glGetVertexAttribiv glad_glGetVertexAttribiv 1446#define glGetVertexAttribiv glad_glGetVertexAttribiv
1447typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC)(GLuint, GLenum, void**); 1447typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC)(GLuint index, GLenum pname, void** pointer);
1448GLAPI PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv; 1448GLAPI PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv;
1449#define glGetVertexAttribPointerv glad_glGetVertexAttribPointerv 1449#define glGetVertexAttribPointerv glad_glGetVertexAttribPointerv
1450typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC)(GLuint); 1450typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC)(GLuint program);
1451GLAPI PFNGLISPROGRAMPROC glad_glIsProgram; 1451GLAPI PFNGLISPROGRAMPROC glad_glIsProgram;
1452#define glIsProgram glad_glIsProgram 1452#define glIsProgram glad_glIsProgram
1453typedef GLboolean (APIENTRYP PFNGLISSHADERPROC)(GLuint); 1453typedef GLboolean (APIENTRYP PFNGLISSHADERPROC)(GLuint shader);
1454GLAPI PFNGLISSHADERPROC glad_glIsShader; 1454GLAPI PFNGLISSHADERPROC glad_glIsShader;
1455#define glIsShader glad_glIsShader 1455#define glIsShader glad_glIsShader
1456typedef void (APIENTRYP PFNGLLINKPROGRAMPROC)(GLuint); 1456typedef void (APIENTRYP PFNGLLINKPROGRAMPROC)(GLuint program);
1457GLAPI PFNGLLINKPROGRAMPROC glad_glLinkProgram; 1457GLAPI PFNGLLINKPROGRAMPROC glad_glLinkProgram;
1458#define glLinkProgram glad_glLinkProgram 1458#define glLinkProgram glad_glLinkProgram
1459typedef void (APIENTRYP PFNGLSHADERSOURCEPROC)(GLuint, GLsizei, const GLchar**, const GLint*); 1459typedef void (APIENTRYP PFNGLSHADERSOURCEPROC)(GLuint shader, GLsizei count, const GLchar** string, const GLint* length);
1460GLAPI PFNGLSHADERSOURCEPROC glad_glShaderSource; 1460GLAPI PFNGLSHADERSOURCEPROC glad_glShaderSource;
1461#define glShaderSource glad_glShaderSource 1461#define glShaderSource glad_glShaderSource
1462typedef void (APIENTRYP PFNGLUSEPROGRAMPROC)(GLuint); 1462typedef void (APIENTRYP PFNGLUSEPROGRAMPROC)(GLuint program);
1463GLAPI PFNGLUSEPROGRAMPROC glad_glUseProgram; 1463GLAPI PFNGLUSEPROGRAMPROC glad_glUseProgram;
1464#define glUseProgram glad_glUseProgram 1464#define glUseProgram glad_glUseProgram
1465typedef void (APIENTRYP PFNGLUNIFORM1FPROC)(GLint, GLfloat); 1465typedef void (APIENTRYP PFNGLUNIFORM1FPROC)(GLint location, GLfloat v0);
1466GLAPI PFNGLUNIFORM1FPROC glad_glUniform1f; 1466GLAPI PFNGLUNIFORM1FPROC glad_glUniform1f;
1467#define glUniform1f glad_glUniform1f 1467#define glUniform1f glad_glUniform1f
1468typedef void (APIENTRYP PFNGLUNIFORM2FPROC)(GLint, GLfloat, GLfloat); 1468typedef void (APIENTRYP PFNGLUNIFORM2FPROC)(GLint location, GLfloat v0, GLfloat v1);
1469GLAPI PFNGLUNIFORM2FPROC glad_glUniform2f; 1469GLAPI PFNGLUNIFORM2FPROC glad_glUniform2f;
1470#define glUniform2f glad_glUniform2f 1470#define glUniform2f glad_glUniform2f
1471typedef void (APIENTRYP PFNGLUNIFORM3FPROC)(GLint, GLfloat, GLfloat, GLfloat); 1471typedef void (APIENTRYP PFNGLUNIFORM3FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
1472GLAPI PFNGLUNIFORM3FPROC glad_glUniform3f; 1472GLAPI PFNGLUNIFORM3FPROC glad_glUniform3f;
1473#define glUniform3f glad_glUniform3f 1473#define glUniform3f glad_glUniform3f
1474typedef void (APIENTRYP PFNGLUNIFORM4FPROC)(GLint, GLfloat, GLfloat, GLfloat, GLfloat); 1474typedef void (APIENTRYP PFNGLUNIFORM4FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
1475GLAPI PFNGLUNIFORM4FPROC glad_glUniform4f; 1475GLAPI PFNGLUNIFORM4FPROC glad_glUniform4f;
1476#define glUniform4f glad_glUniform4f 1476#define glUniform4f glad_glUniform4f
1477typedef void (APIENTRYP PFNGLUNIFORM1IPROC)(GLint, GLint); 1477typedef void (APIENTRYP PFNGLUNIFORM1IPROC)(GLint location, GLint v0);
1478GLAPI PFNGLUNIFORM1IPROC glad_glUniform1i; 1478GLAPI PFNGLUNIFORM1IPROC glad_glUniform1i;
1479#define glUniform1i glad_glUniform1i 1479#define glUniform1i glad_glUniform1i
1480typedef void (APIENTRYP PFNGLUNIFORM2IPROC)(GLint, GLint, GLint); 1480typedef void (APIENTRYP PFNGLUNIFORM2IPROC)(GLint location, GLint v0, GLint v1);
1481GLAPI PFNGLUNIFORM2IPROC glad_glUniform2i; 1481GLAPI PFNGLUNIFORM2IPROC glad_glUniform2i;
1482#define glUniform2i glad_glUniform2i 1482#define glUniform2i glad_glUniform2i
1483typedef void (APIENTRYP PFNGLUNIFORM3IPROC)(GLint, GLint, GLint, GLint); 1483typedef void (APIENTRYP PFNGLUNIFORM3IPROC)(GLint location, GLint v0, GLint v1, GLint v2);
1484GLAPI PFNGLUNIFORM3IPROC glad_glUniform3i; 1484GLAPI PFNGLUNIFORM3IPROC glad_glUniform3i;
1485#define glUniform3i glad_glUniform3i 1485#define glUniform3i glad_glUniform3i
1486typedef void (APIENTRYP PFNGLUNIFORM4IPROC)(GLint, GLint, GLint, GLint, GLint); 1486typedef void (APIENTRYP PFNGLUNIFORM4IPROC)(GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
1487GLAPI PFNGLUNIFORM4IPROC glad_glUniform4i; 1487GLAPI PFNGLUNIFORM4IPROC glad_glUniform4i;
1488#define glUniform4i glad_glUniform4i 1488#define glUniform4i glad_glUniform4i
1489typedef void (APIENTRYP PFNGLUNIFORM1FVPROC)(GLint, GLsizei, const GLfloat*); 1489typedef void (APIENTRYP PFNGLUNIFORM1FVPROC)(GLint location, GLsizei count, const GLfloat* value);
1490GLAPI PFNGLUNIFORM1FVPROC glad_glUniform1fv; 1490GLAPI PFNGLUNIFORM1FVPROC glad_glUniform1fv;
1491#define glUniform1fv glad_glUniform1fv 1491#define glUniform1fv glad_glUniform1fv
1492typedef void (APIENTRYP PFNGLUNIFORM2FVPROC)(GLint, GLsizei, const GLfloat*); 1492typedef void (APIENTRYP PFNGLUNIFORM2FVPROC)(GLint location, GLsizei count, const GLfloat* value);
1493GLAPI PFNGLUNIFORM2FVPROC glad_glUniform2fv; 1493GLAPI PFNGLUNIFORM2FVPROC glad_glUniform2fv;
1494#define glUniform2fv glad_glUniform2fv 1494#define glUniform2fv glad_glUniform2fv
1495typedef void (APIENTRYP PFNGLUNIFORM3FVPROC)(GLint, GLsizei, const GLfloat*); 1495typedef void (APIENTRYP PFNGLUNIFORM3FVPROC)(GLint location, GLsizei count, const GLfloat* value);
1496GLAPI PFNGLUNIFORM3FVPROC glad_glUniform3fv; 1496GLAPI PFNGLUNIFORM3FVPROC glad_glUniform3fv;
1497#define glUniform3fv glad_glUniform3fv 1497#define glUniform3fv glad_glUniform3fv
1498typedef void (APIENTRYP PFNGLUNIFORM4FVPROC)(GLint, GLsizei, const GLfloat*); 1498typedef void (APIENTRYP PFNGLUNIFORM4FVPROC)(GLint location, GLsizei count, const GLfloat* value);
1499GLAPI PFNGLUNIFORM4FVPROC glad_glUniform4fv; 1499GLAPI PFNGLUNIFORM4FVPROC glad_glUniform4fv;
1500#define glUniform4fv glad_glUniform4fv 1500#define glUniform4fv glad_glUniform4fv
1501typedef void (APIENTRYP PFNGLUNIFORM1IVPROC)(GLint, GLsizei, const GLint*); 1501typedef void (APIENTRYP PFNGLUNIFORM1IVPROC)(GLint location, GLsizei count, const GLint* value);
1502GLAPI PFNGLUNIFORM1IVPROC glad_glUniform1iv; 1502GLAPI PFNGLUNIFORM1IVPROC glad_glUniform1iv;
1503#define glUniform1iv glad_glUniform1iv 1503#define glUniform1iv glad_glUniform1iv
1504typedef void (APIENTRYP PFNGLUNIFORM2IVPROC)(GLint, GLsizei, const GLint*); 1504typedef void (APIENTRYP PFNGLUNIFORM2IVPROC)(GLint location, GLsizei count, const GLint* value);
1505GLAPI PFNGLUNIFORM2IVPROC glad_glUniform2iv; 1505GLAPI PFNGLUNIFORM2IVPROC glad_glUniform2iv;
1506#define glUniform2iv glad_glUniform2iv 1506#define glUniform2iv glad_glUniform2iv
1507typedef void (APIENTRYP PFNGLUNIFORM3IVPROC)(GLint, GLsizei, const GLint*); 1507typedef void (APIENTRYP PFNGLUNIFORM3IVPROC)(GLint location, GLsizei count, const GLint* value);
1508GLAPI PFNGLUNIFORM3IVPROC glad_glUniform3iv; 1508GLAPI PFNGLUNIFORM3IVPROC glad_glUniform3iv;
1509#define glUniform3iv glad_glUniform3iv 1509#define glUniform3iv glad_glUniform3iv
1510typedef void (APIENTRYP PFNGLUNIFORM4IVPROC)(GLint, GLsizei, const GLint*); 1510typedef void (APIENTRYP PFNGLUNIFORM4IVPROC)(GLint location, GLsizei count, const GLint* value);
1511GLAPI PFNGLUNIFORM4IVPROC glad_glUniform4iv; 1511GLAPI PFNGLUNIFORM4IVPROC glad_glUniform4iv;
1512#define glUniform4iv glad_glUniform4iv 1512#define glUniform4iv glad_glUniform4iv
1513typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVPROC)(GLint, GLsizei, GLboolean, const GLfloat*); 1513typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
1514GLAPI PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv; 1514GLAPI PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv;
1515#define glUniformMatrix2fv glad_glUniformMatrix2fv 1515#define glUniformMatrix2fv glad_glUniformMatrix2fv
1516typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC)(GLint, GLsizei, GLboolean, const GLfloat*); 1516typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
1517GLAPI PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv; 1517GLAPI PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv;
1518#define glUniformMatrix3fv glad_glUniformMatrix3fv 1518#define glUniformMatrix3fv glad_glUniformMatrix3fv
1519typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC)(GLint, GLsizei, GLboolean, const GLfloat*); 1519typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
1520GLAPI PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv; 1520GLAPI PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv;
1521#define glUniformMatrix4fv glad_glUniformMatrix4fv 1521#define glUniformMatrix4fv glad_glUniformMatrix4fv
1522typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC)(GLuint); 1522typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC)(GLuint program);
1523GLAPI PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram; 1523GLAPI PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram;
1524#define glValidateProgram glad_glValidateProgram 1524#define glValidateProgram glad_glValidateProgram
1525typedef void (APIENTRYP PFNGLVERTEXATTRIB1DPROC)(GLuint, GLdouble); 1525typedef void (APIENTRYP PFNGLVERTEXATTRIB1DPROC)(GLuint index, GLdouble x);
1526GLAPI PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d; 1526GLAPI PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d;
1527#define glVertexAttrib1d glad_glVertexAttrib1d 1527#define glVertexAttrib1d glad_glVertexAttrib1d
1528typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVPROC)(GLuint, const GLdouble*); 1528typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVPROC)(GLuint index, const GLdouble* v);
1529GLAPI PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv; 1529GLAPI PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv;
1530#define glVertexAttrib1dv glad_glVertexAttrib1dv 1530#define glVertexAttrib1dv glad_glVertexAttrib1dv
1531typedef void (APIENTRYP PFNGLVERTEXATTRIB1FPROC)(GLuint, GLfloat); 1531typedef void (APIENTRYP PFNGLVERTEXATTRIB1FPROC)(GLuint index, GLfloat x);
1532GLAPI PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f; 1532GLAPI PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f;
1533#define glVertexAttrib1f glad_glVertexAttrib1f 1533#define glVertexAttrib1f glad_glVertexAttrib1f
1534typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVPROC)(GLuint, const GLfloat*); 1534typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVPROC)(GLuint index, const GLfloat* v);
1535GLAPI PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv; 1535GLAPI PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv;
1536#define glVertexAttrib1fv glad_glVertexAttrib1fv 1536#define glVertexAttrib1fv glad_glVertexAttrib1fv
1537typedef void (APIENTRYP PFNGLVERTEXATTRIB1SPROC)(GLuint, GLshort); 1537typedef void (APIENTRYP PFNGLVERTEXATTRIB1SPROC)(GLuint index, GLshort x);
1538GLAPI PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s; 1538GLAPI PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s;
1539#define glVertexAttrib1s glad_glVertexAttrib1s 1539#define glVertexAttrib1s glad_glVertexAttrib1s
1540typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVPROC)(GLuint, const GLshort*); 1540typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVPROC)(GLuint index, const GLshort* v);
1541GLAPI PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv; 1541GLAPI PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv;
1542#define glVertexAttrib1sv glad_glVertexAttrib1sv 1542#define glVertexAttrib1sv glad_glVertexAttrib1sv
1543typedef void (APIENTRYP PFNGLVERTEXATTRIB2DPROC)(GLuint, GLdouble, GLdouble); 1543typedef void (APIENTRYP PFNGLVERTEXATTRIB2DPROC)(GLuint index, GLdouble x, GLdouble y);
1544GLAPI PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d; 1544GLAPI PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d;
1545#define glVertexAttrib2d glad_glVertexAttrib2d 1545#define glVertexAttrib2d glad_glVertexAttrib2d
1546typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVPROC)(GLuint, const GLdouble*); 1546typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVPROC)(GLuint index, const GLdouble* v);
1547GLAPI PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv; 1547GLAPI PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv;
1548#define glVertexAttrib2dv glad_glVertexAttrib2dv 1548#define glVertexAttrib2dv glad_glVertexAttrib2dv
1549typedef void (APIENTRYP PFNGLVERTEXATTRIB2FPROC)(GLuint, GLfloat, GLfloat); 1549typedef void (APIENTRYP PFNGLVERTEXATTRIB2FPROC)(GLuint index, GLfloat x, GLfloat y);
1550GLAPI PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f; 1550GLAPI PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f;
1551#define glVertexAttrib2f glad_glVertexAttrib2f 1551#define glVertexAttrib2f glad_glVertexAttrib2f
1552typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVPROC)(GLuint, const GLfloat*); 1552typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVPROC)(GLuint index, const GLfloat* v);
1553GLAPI PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv; 1553GLAPI PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv;
1554#define glVertexAttrib2fv glad_glVertexAttrib2fv 1554#define glVertexAttrib2fv glad_glVertexAttrib2fv
1555typedef void (APIENTRYP PFNGLVERTEXATTRIB2SPROC)(GLuint, GLshort, GLshort); 1555typedef void (APIENTRYP PFNGLVERTEXATTRIB2SPROC)(GLuint index, GLshort x, GLshort y);
1556GLAPI PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s; 1556GLAPI PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s;
1557#define glVertexAttrib2s glad_glVertexAttrib2s 1557#define glVertexAttrib2s glad_glVertexAttrib2s
1558typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVPROC)(GLuint, const GLshort*); 1558typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVPROC)(GLuint index, const GLshort* v);
1559GLAPI PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv; 1559GLAPI PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv;
1560#define glVertexAttrib2sv glad_glVertexAttrib2sv 1560#define glVertexAttrib2sv glad_glVertexAttrib2sv
1561typedef void (APIENTRYP PFNGLVERTEXATTRIB3DPROC)(GLuint, GLdouble, GLdouble, GLdouble); 1561typedef void (APIENTRYP PFNGLVERTEXATTRIB3DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z);
1562GLAPI PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d; 1562GLAPI PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d;
1563#define glVertexAttrib3d glad_glVertexAttrib3d 1563#define glVertexAttrib3d glad_glVertexAttrib3d
1564typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVPROC)(GLuint, const GLdouble*); 1564typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVPROC)(GLuint index, const GLdouble* v);
1565GLAPI PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv; 1565GLAPI PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv;
1566#define glVertexAttrib3dv glad_glVertexAttrib3dv 1566#define glVertexAttrib3dv glad_glVertexAttrib3dv
1567typedef void (APIENTRYP PFNGLVERTEXATTRIB3FPROC)(GLuint, GLfloat, GLfloat, GLfloat); 1567typedef void (APIENTRYP PFNGLVERTEXATTRIB3FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z);
1568GLAPI PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f; 1568GLAPI PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f;
1569#define glVertexAttrib3f glad_glVertexAttrib3f 1569#define glVertexAttrib3f glad_glVertexAttrib3f
1570typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVPROC)(GLuint, const GLfloat*); 1570typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVPROC)(GLuint index, const GLfloat* v);
1571GLAPI PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv; 1571GLAPI PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv;
1572#define glVertexAttrib3fv glad_glVertexAttrib3fv 1572#define glVertexAttrib3fv glad_glVertexAttrib3fv
1573typedef void (APIENTRYP PFNGLVERTEXATTRIB3SPROC)(GLuint, GLshort, GLshort, GLshort); 1573typedef void (APIENTRYP PFNGLVERTEXATTRIB3SPROC)(GLuint index, GLshort x, GLshort y, GLshort z);
1574GLAPI PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s; 1574GLAPI PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s;
1575#define glVertexAttrib3s glad_glVertexAttrib3s 1575#define glVertexAttrib3s glad_glVertexAttrib3s
1576typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVPROC)(GLuint, const GLshort*); 1576typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVPROC)(GLuint index, const GLshort* v);
1577GLAPI PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv; 1577GLAPI PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv;
1578#define glVertexAttrib3sv glad_glVertexAttrib3sv 1578#define glVertexAttrib3sv glad_glVertexAttrib3sv
1579typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVPROC)(GLuint, const GLbyte*); 1579typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVPROC)(GLuint index, const GLbyte* v);
1580GLAPI PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv; 1580GLAPI PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv;
1581#define glVertexAttrib4Nbv glad_glVertexAttrib4Nbv 1581#define glVertexAttrib4Nbv glad_glVertexAttrib4Nbv
1582typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVPROC)(GLuint, const GLint*); 1582typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVPROC)(GLuint index, const GLint* v);
1583GLAPI PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv; 1583GLAPI PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv;
1584#define glVertexAttrib4Niv glad_glVertexAttrib4Niv 1584#define glVertexAttrib4Niv glad_glVertexAttrib4Niv
1585typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVPROC)(GLuint, const GLshort*); 1585typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVPROC)(GLuint index, const GLshort* v);
1586GLAPI PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv; 1586GLAPI PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv;
1587#define glVertexAttrib4Nsv glad_glVertexAttrib4Nsv 1587#define glVertexAttrib4Nsv glad_glVertexAttrib4Nsv
1588typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBPROC)(GLuint, GLubyte, GLubyte, GLubyte, GLubyte); 1588typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBPROC)(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
1589GLAPI PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub; 1589GLAPI PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub;
1590#define glVertexAttrib4Nub glad_glVertexAttrib4Nub 1590#define glVertexAttrib4Nub glad_glVertexAttrib4Nub
1591typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVPROC)(GLuint, const GLubyte*); 1591typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVPROC)(GLuint index, const GLubyte* v);
1592GLAPI PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv; 1592GLAPI PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv;
1593#define glVertexAttrib4Nubv glad_glVertexAttrib4Nubv 1593#define glVertexAttrib4Nubv glad_glVertexAttrib4Nubv
1594typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVPROC)(GLuint, const GLuint*); 1594typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVPROC)(GLuint index, const GLuint* v);
1595GLAPI PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv; 1595GLAPI PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv;
1596#define glVertexAttrib4Nuiv glad_glVertexAttrib4Nuiv 1596#define glVertexAttrib4Nuiv glad_glVertexAttrib4Nuiv
1597typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVPROC)(GLuint, const GLushort*); 1597typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVPROC)(GLuint index, const GLushort* v);
1598GLAPI PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv; 1598GLAPI PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv;
1599#define glVertexAttrib4Nusv glad_glVertexAttrib4Nusv 1599#define glVertexAttrib4Nusv glad_glVertexAttrib4Nusv
1600typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVPROC)(GLuint, const GLbyte*); 1600typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVPROC)(GLuint index, const GLbyte* v);
1601GLAPI PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv; 1601GLAPI PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv;
1602#define glVertexAttrib4bv glad_glVertexAttrib4bv 1602#define glVertexAttrib4bv glad_glVertexAttrib4bv
1603typedef void (APIENTRYP PFNGLVERTEXATTRIB4DPROC)(GLuint, GLdouble, GLdouble, GLdouble, GLdouble); 1603typedef void (APIENTRYP PFNGLVERTEXATTRIB4DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
1604GLAPI PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d; 1604GLAPI PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d;
1605#define glVertexAttrib4d glad_glVertexAttrib4d 1605#define glVertexAttrib4d glad_glVertexAttrib4d
1606typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVPROC)(GLuint, const GLdouble*); 1606typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVPROC)(GLuint index, const GLdouble* v);
1607GLAPI PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv; 1607GLAPI PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv;
1608#define glVertexAttrib4dv glad_glVertexAttrib4dv 1608#define glVertexAttrib4dv glad_glVertexAttrib4dv
1609typedef void (APIENTRYP PFNGLVERTEXATTRIB4FPROC)(GLuint, GLfloat, GLfloat, GLfloat, GLfloat); 1609typedef void (APIENTRYP PFNGLVERTEXATTRIB4FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
1610GLAPI PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f; 1610GLAPI PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f;
1611#define glVertexAttrib4f glad_glVertexAttrib4f 1611#define glVertexAttrib4f glad_glVertexAttrib4f
1612typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVPROC)(GLuint, const GLfloat*); 1612typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVPROC)(GLuint index, const GLfloat* v);
1613GLAPI PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv; 1613GLAPI PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv;
1614#define glVertexAttrib4fv glad_glVertexAttrib4fv 1614#define glVertexAttrib4fv glad_glVertexAttrib4fv
1615typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVPROC)(GLuint, const GLint*); 1615typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVPROC)(GLuint index, const GLint* v);
1616GLAPI PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv; 1616GLAPI PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv;
1617#define glVertexAttrib4iv glad_glVertexAttrib4iv 1617#define glVertexAttrib4iv glad_glVertexAttrib4iv
1618typedef void (APIENTRYP PFNGLVERTEXATTRIB4SPROC)(GLuint, GLshort, GLshort, GLshort, GLshort); 1618typedef void (APIENTRYP PFNGLVERTEXATTRIB4SPROC)(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
1619GLAPI PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s; 1619GLAPI PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s;
1620#define glVertexAttrib4s glad_glVertexAttrib4s 1620#define glVertexAttrib4s glad_glVertexAttrib4s
1621typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVPROC)(GLuint, const GLshort*); 1621typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVPROC)(GLuint index, const GLshort* v);
1622GLAPI PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv; 1622GLAPI PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv;
1623#define glVertexAttrib4sv glad_glVertexAttrib4sv 1623#define glVertexAttrib4sv glad_glVertexAttrib4sv
1624typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVPROC)(GLuint, const GLubyte*); 1624typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVPROC)(GLuint index, const GLubyte* v);
1625GLAPI PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv; 1625GLAPI PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv;
1626#define glVertexAttrib4ubv glad_glVertexAttrib4ubv 1626#define glVertexAttrib4ubv glad_glVertexAttrib4ubv
1627typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVPROC)(GLuint, const GLuint*); 1627typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVPROC)(GLuint index, const GLuint* v);
1628GLAPI PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv; 1628GLAPI PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv;
1629#define glVertexAttrib4uiv glad_glVertexAttrib4uiv 1629#define glVertexAttrib4uiv glad_glVertexAttrib4uiv
1630typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVPROC)(GLuint, const GLushort*); 1630typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVPROC)(GLuint index, const GLushort* v);
1631GLAPI PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv; 1631GLAPI PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv;
1632#define glVertexAttrib4usv glad_glVertexAttrib4usv 1632#define glVertexAttrib4usv glad_glVertexAttrib4usv
1633typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC)(GLuint, GLint, GLenum, GLboolean, GLsizei, const void*); 1633typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC)(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* pointer);
1634GLAPI PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer; 1634GLAPI PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer;
1635#define glVertexAttribPointer glad_glVertexAttribPointer 1635#define glVertexAttribPointer glad_glVertexAttribPointer
1636#endif 1636#endif
1637#ifndef GL_VERSION_2_1 1637#ifndef GL_VERSION_2_1
1638#define GL_VERSION_2_1 1 1638#define GL_VERSION_2_1 1
1639GLAPI int GLAD_GL_VERSION_2_1; 1639GLAPI int GLAD_GL_VERSION_2_1;
1640typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC)(GLint, GLsizei, GLboolean, const GLfloat*); 1640typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
1641GLAPI PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv; 1641GLAPI PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv;
1642#define glUniformMatrix2x3fv glad_glUniformMatrix2x3fv 1642#define glUniformMatrix2x3fv glad_glUniformMatrix2x3fv
1643typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC)(GLint, GLsizei, GLboolean, const GLfloat*); 1643typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
1644GLAPI PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv; 1644GLAPI PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv;
1645#define glUniformMatrix3x2fv glad_glUniformMatrix3x2fv 1645#define glUniformMatrix3x2fv glad_glUniformMatrix3x2fv
1646typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC)(GLint, GLsizei, GLboolean, const GLfloat*); 1646typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
1647GLAPI PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv; 1647GLAPI PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv;
1648#define glUniformMatrix2x4fv glad_glUniformMatrix2x4fv 1648#define glUniformMatrix2x4fv glad_glUniformMatrix2x4fv
1649typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC)(GLint, GLsizei, GLboolean, const GLfloat*); 1649typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
1650GLAPI PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv; 1650GLAPI PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv;
1651#define glUniformMatrix4x2fv glad_glUniformMatrix4x2fv 1651#define glUniformMatrix4x2fv glad_glUniformMatrix4x2fv
1652typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC)(GLint, GLsizei, GLboolean, const GLfloat*); 1652typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
1653GLAPI PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv; 1653GLAPI PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv;
1654#define glUniformMatrix3x4fv glad_glUniformMatrix3x4fv 1654#define glUniformMatrix3x4fv glad_glUniformMatrix3x4fv
1655typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC)(GLint, GLsizei, GLboolean, const GLfloat*); 1655typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
1656GLAPI PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv; 1656GLAPI PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv;
1657#define glUniformMatrix4x3fv glad_glUniformMatrix4x3fv 1657#define glUniformMatrix4x3fv glad_glUniformMatrix4x3fv
1658#endif 1658#endif
1659#ifndef GL_VERSION_3_0 1659#ifndef GL_VERSION_3_0
1660#define GL_VERSION_3_0 1 1660#define GL_VERSION_3_0 1
1661GLAPI int GLAD_GL_VERSION_3_0; 1661GLAPI int GLAD_GL_VERSION_3_0;
1662typedef void (APIENTRYP PFNGLCOLORMASKIPROC)(GLuint, GLboolean, GLboolean, GLboolean, GLboolean); 1662typedef void (APIENTRYP PFNGLCOLORMASKIPROC)(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
1663GLAPI PFNGLCOLORMASKIPROC glad_glColorMaski; 1663GLAPI PFNGLCOLORMASKIPROC glad_glColorMaski;
1664#define glColorMaski glad_glColorMaski 1664#define glColorMaski glad_glColorMaski
1665typedef void (APIENTRYP PFNGLGETBOOLEANI_VPROC)(GLenum, GLuint, GLboolean*); 1665typedef void (APIENTRYP PFNGLGETBOOLEANI_VPROC)(GLenum target, GLuint index, GLboolean* data);
1666GLAPI PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v; 1666GLAPI PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v;
1667#define glGetBooleani_v glad_glGetBooleani_v 1667#define glGetBooleani_v glad_glGetBooleani_v
1668typedef void (APIENTRYP PFNGLGETINTEGERI_VPROC)(GLenum, GLuint, GLint*); 1668typedef void (APIENTRYP PFNGLGETINTEGERI_VPROC)(GLenum target, GLuint index, GLint* data);
1669GLAPI PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v; 1669GLAPI PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v;
1670#define glGetIntegeri_v glad_glGetIntegeri_v 1670#define glGetIntegeri_v glad_glGetIntegeri_v
1671typedef void (APIENTRYP PFNGLENABLEIPROC)(GLenum, GLuint); 1671typedef void (APIENTRYP PFNGLENABLEIPROC)(GLenum target, GLuint index);
1672GLAPI PFNGLENABLEIPROC glad_glEnablei; 1672GLAPI PFNGLENABLEIPROC glad_glEnablei;
1673#define glEnablei glad_glEnablei 1673#define glEnablei glad_glEnablei
1674typedef void (APIENTRYP PFNGLDISABLEIPROC)(GLenum, GLuint); 1674typedef void (APIENTRYP PFNGLDISABLEIPROC)(GLenum target, GLuint index);
1675GLAPI PFNGLDISABLEIPROC glad_glDisablei; 1675GLAPI PFNGLDISABLEIPROC glad_glDisablei;
1676#define glDisablei glad_glDisablei 1676#define glDisablei glad_glDisablei
1677typedef GLboolean (APIENTRYP PFNGLISENABLEDIPROC)(GLenum, GLuint); 1677typedef GLboolean (APIENTRYP PFNGLISENABLEDIPROC)(GLenum target, GLuint index);
1678GLAPI PFNGLISENABLEDIPROC glad_glIsEnabledi; 1678GLAPI PFNGLISENABLEDIPROC glad_glIsEnabledi;
1679#define glIsEnabledi glad_glIsEnabledi 1679#define glIsEnabledi glad_glIsEnabledi
1680typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKPROC)(GLenum); 1680typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKPROC)(GLenum primitiveMode);
1681GLAPI PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback; 1681GLAPI PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback;
1682#define glBeginTransformFeedback glad_glBeginTransformFeedback 1682#define glBeginTransformFeedback glad_glBeginTransformFeedback
1683typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKPROC)(); 1683typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKPROC)();
1684GLAPI PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback; 1684GLAPI PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback;
1685#define glEndTransformFeedback glad_glEndTransformFeedback 1685#define glEndTransformFeedback glad_glEndTransformFeedback
1686typedef void (APIENTRYP PFNGLBINDBUFFERRANGEPROC)(GLenum, GLuint, GLuint, GLintptr, GLsizeiptr); 1686typedef void (APIENTRYP PFNGLBINDBUFFERRANGEPROC)(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
1687GLAPI PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange; 1687GLAPI PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange;
1688#define glBindBufferRange glad_glBindBufferRange 1688#define glBindBufferRange glad_glBindBufferRange
1689typedef void (APIENTRYP PFNGLBINDBUFFERBASEPROC)(GLenum, GLuint, GLuint); 1689typedef void (APIENTRYP PFNGLBINDBUFFERBASEPROC)(GLenum target, GLuint index, GLuint buffer);
1690GLAPI PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase; 1690GLAPI PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase;
1691#define glBindBufferBase glad_glBindBufferBase 1691#define glBindBufferBase glad_glBindBufferBase
1692typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSPROC)(GLuint, GLsizei, const GLchar**, GLenum); 1692typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSPROC)(GLuint program, GLsizei count, const GLchar** varyings, GLenum bufferMode);
1693GLAPI PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings; 1693GLAPI PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings;
1694#define glTransformFeedbackVaryings glad_glTransformFeedbackVaryings 1694#define glTransformFeedbackVaryings glad_glTransformFeedbackVaryings
1695typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)(GLuint, GLuint, GLsizei, GLsizei*, GLsizei*, GLenum*, GLchar*); 1695typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name);
1696GLAPI PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying; 1696GLAPI PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying;
1697#define glGetTransformFeedbackVarying glad_glGetTransformFeedbackVarying 1697#define glGetTransformFeedbackVarying glad_glGetTransformFeedbackVarying
1698typedef void (APIENTRYP PFNGLCLAMPCOLORPROC)(GLenum, GLenum); 1698typedef void (APIENTRYP PFNGLCLAMPCOLORPROC)(GLenum target, GLenum clamp);
1699GLAPI PFNGLCLAMPCOLORPROC glad_glClampColor; 1699GLAPI PFNGLCLAMPCOLORPROC glad_glClampColor;
1700#define glClampColor glad_glClampColor 1700#define glClampColor glad_glClampColor
1701typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERPROC)(GLuint, GLenum); 1701typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERPROC)(GLuint id, GLenum mode);
1702GLAPI PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender; 1702GLAPI PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender;
1703#define glBeginConditionalRender glad_glBeginConditionalRender 1703#define glBeginConditionalRender glad_glBeginConditionalRender
1704typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERPROC)(); 1704typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERPROC)();
1705GLAPI PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender; 1705GLAPI PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender;
1706#define glEndConditionalRender glad_glEndConditionalRender 1706#define glEndConditionalRender glad_glEndConditionalRender
1707typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC)(GLuint, GLint, GLenum, GLsizei, const void*); 1707typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC)(GLuint index, GLint size, GLenum type, GLsizei stride, const void* pointer);
1708GLAPI PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer; 1708GLAPI PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer;
1709#define glVertexAttribIPointer glad_glVertexAttribIPointer 1709#define glVertexAttribIPointer glad_glVertexAttribIPointer
1710typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVPROC)(GLuint, GLenum, GLint*); 1710typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVPROC)(GLuint index, GLenum pname, GLint* params);
1711GLAPI PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv; 1711GLAPI PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv;
1712#define glGetVertexAttribIiv glad_glGetVertexAttribIiv 1712#define glGetVertexAttribIiv glad_glGetVertexAttribIiv
1713typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVPROC)(GLuint, GLenum, GLuint*); 1713typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVPROC)(GLuint index, GLenum pname, GLuint* params);
1714GLAPI PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv; 1714GLAPI PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv;
1715#define glGetVertexAttribIuiv glad_glGetVertexAttribIuiv 1715#define glGetVertexAttribIuiv glad_glGetVertexAttribIuiv
1716typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IPROC)(GLuint, GLint); 1716typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IPROC)(GLuint index, GLint x);
1717GLAPI PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i; 1717GLAPI PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i;
1718#define glVertexAttribI1i glad_glVertexAttribI1i 1718#define glVertexAttribI1i glad_glVertexAttribI1i
1719typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IPROC)(GLuint, GLint, GLint); 1719typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IPROC)(GLuint index, GLint x, GLint y);
1720GLAPI PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i; 1720GLAPI PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i;
1721#define glVertexAttribI2i glad_glVertexAttribI2i 1721#define glVertexAttribI2i glad_glVertexAttribI2i
1722typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IPROC)(GLuint, GLint, GLint, GLint); 1722typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IPROC)(GLuint index, GLint x, GLint y, GLint z);
1723GLAPI PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i; 1723GLAPI PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i;
1724#define glVertexAttribI3i glad_glVertexAttribI3i 1724#define glVertexAttribI3i glad_glVertexAttribI3i
1725typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IPROC)(GLuint, GLint, GLint, GLint, GLint); 1725typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IPROC)(GLuint index, GLint x, GLint y, GLint z, GLint w);
1726GLAPI PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i; 1726GLAPI PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i;
1727#define glVertexAttribI4i glad_glVertexAttribI4i 1727#define glVertexAttribI4i glad_glVertexAttribI4i
1728typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIPROC)(GLuint, GLuint); 1728typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIPROC)(GLuint index, GLuint x);
1729GLAPI PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui; 1729GLAPI PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui;
1730#define glVertexAttribI1ui glad_glVertexAttribI1ui 1730#define glVertexAttribI1ui glad_glVertexAttribI1ui
1731typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIPROC)(GLuint, GLuint, GLuint); 1731typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIPROC)(GLuint index, GLuint x, GLuint y);
1732GLAPI PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui; 1732GLAPI PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui;
1733#define glVertexAttribI2ui glad_glVertexAttribI2ui 1733#define glVertexAttribI2ui glad_glVertexAttribI2ui
1734typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIPROC)(GLuint, GLuint, GLuint, GLuint); 1734typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIPROC)(GLuint index, GLuint x, GLuint y, GLuint z);
1735GLAPI PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui; 1735GLAPI PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui;
1736#define glVertexAttribI3ui glad_glVertexAttribI3ui 1736#define glVertexAttribI3ui glad_glVertexAttribI3ui
1737typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIPROC)(GLuint, GLuint, GLuint, GLuint, GLuint); 1737typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIPROC)(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
1738GLAPI PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui; 1738GLAPI PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui;
1739#define glVertexAttribI4ui glad_glVertexAttribI4ui 1739#define glVertexAttribI4ui glad_glVertexAttribI4ui
1740typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVPROC)(GLuint, const GLint*); 1740typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVPROC)(GLuint index, const GLint* v);
1741GLAPI PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv; 1741GLAPI PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv;
1742#define glVertexAttribI1iv glad_glVertexAttribI1iv 1742#define glVertexAttribI1iv glad_glVertexAttribI1iv
1743typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVPROC)(GLuint, const GLint*); 1743typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVPROC)(GLuint index, const GLint* v);
1744GLAPI PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv; 1744GLAPI PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv;
1745#define glVertexAttribI2iv glad_glVertexAttribI2iv 1745#define glVertexAttribI2iv glad_glVertexAttribI2iv
1746typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVPROC)(GLuint, const GLint*); 1746typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVPROC)(GLuint index, const GLint* v);
1747GLAPI PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv; 1747GLAPI PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv;
1748#define glVertexAttribI3iv glad_glVertexAttribI3iv 1748#define glVertexAttribI3iv glad_glVertexAttribI3iv
1749typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVPROC)(GLuint, const GLint*); 1749typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVPROC)(GLuint index, const GLint* v);
1750GLAPI PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv; 1750GLAPI PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv;
1751#define glVertexAttribI4iv glad_glVertexAttribI4iv 1751#define glVertexAttribI4iv glad_glVertexAttribI4iv
1752typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVPROC)(GLuint, const GLuint*); 1752typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVPROC)(GLuint index, const GLuint* v);
1753GLAPI PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv; 1753GLAPI PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv;
1754#define glVertexAttribI1uiv glad_glVertexAttribI1uiv 1754#define glVertexAttribI1uiv glad_glVertexAttribI1uiv
1755typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVPROC)(GLuint, const GLuint*); 1755typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVPROC)(GLuint index, const GLuint* v);
1756GLAPI PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv; 1756GLAPI PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv;
1757#define glVertexAttribI2uiv glad_glVertexAttribI2uiv 1757#define glVertexAttribI2uiv glad_glVertexAttribI2uiv
1758typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVPROC)(GLuint, const GLuint*); 1758typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVPROC)(GLuint index, const GLuint* v);
1759GLAPI PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv; 1759GLAPI PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv;
1760#define glVertexAttribI3uiv glad_glVertexAttribI3uiv 1760#define glVertexAttribI3uiv glad_glVertexAttribI3uiv
1761typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVPROC)(GLuint, const GLuint*); 1761typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVPROC)(GLuint index, const GLuint* v);
1762GLAPI PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv; 1762GLAPI PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv;
1763#define glVertexAttribI4uiv glad_glVertexAttribI4uiv 1763#define glVertexAttribI4uiv glad_glVertexAttribI4uiv
1764typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVPROC)(GLuint, const GLbyte*); 1764typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVPROC)(GLuint index, const GLbyte* v);
1765GLAPI PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv; 1765GLAPI PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv;
1766#define glVertexAttribI4bv glad_glVertexAttribI4bv 1766#define glVertexAttribI4bv glad_glVertexAttribI4bv
1767typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVPROC)(GLuint, const GLshort*); 1767typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVPROC)(GLuint index, const GLshort* v);
1768GLAPI PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv; 1768GLAPI PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv;
1769#define glVertexAttribI4sv glad_glVertexAttribI4sv 1769#define glVertexAttribI4sv glad_glVertexAttribI4sv
1770typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVPROC)(GLuint, const GLubyte*); 1770typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVPROC)(GLuint index, const GLubyte* v);
1771GLAPI PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv; 1771GLAPI PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv;
1772#define glVertexAttribI4ubv glad_glVertexAttribI4ubv 1772#define glVertexAttribI4ubv glad_glVertexAttribI4ubv
1773typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVPROC)(GLuint, const GLushort*); 1773typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVPROC)(GLuint index, const GLushort* v);
1774GLAPI PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv; 1774GLAPI PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv;
1775#define glVertexAttribI4usv glad_glVertexAttribI4usv 1775#define glVertexAttribI4usv glad_glVertexAttribI4usv
1776typedef void (APIENTRYP PFNGLGETUNIFORMUIVPROC)(GLuint, GLint, GLuint*); 1776typedef void (APIENTRYP PFNGLGETUNIFORMUIVPROC)(GLuint program, GLint location, GLuint* params);
1777GLAPI PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv; 1777GLAPI PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv;
1778#define glGetUniformuiv glad_glGetUniformuiv 1778#define glGetUniformuiv glad_glGetUniformuiv
1779typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONPROC)(GLuint, GLuint, const GLchar*); 1779typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONPROC)(GLuint program, GLuint color, const GLchar* name);
1780GLAPI PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation; 1780GLAPI PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation;
1781#define glBindFragDataLocation glad_glBindFragDataLocation 1781#define glBindFragDataLocation glad_glBindFragDataLocation
1782typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONPROC)(GLuint, const GLchar*); 1782typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONPROC)(GLuint program, const GLchar* name);
1783GLAPI PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation; 1783GLAPI PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation;
1784#define glGetFragDataLocation glad_glGetFragDataLocation 1784#define glGetFragDataLocation glad_glGetFragDataLocation
1785typedef void (APIENTRYP PFNGLUNIFORM1UIPROC)(GLint, GLuint); 1785typedef void (APIENTRYP PFNGLUNIFORM1UIPROC)(GLint location, GLuint v0);
1786GLAPI PFNGLUNIFORM1UIPROC glad_glUniform1ui; 1786GLAPI PFNGLUNIFORM1UIPROC glad_glUniform1ui;
1787#define glUniform1ui glad_glUniform1ui 1787#define glUniform1ui glad_glUniform1ui
1788typedef void (APIENTRYP PFNGLUNIFORM2UIPROC)(GLint, GLuint, GLuint); 1788typedef void (APIENTRYP PFNGLUNIFORM2UIPROC)(GLint location, GLuint v0, GLuint v1);
1789GLAPI PFNGLUNIFORM2UIPROC glad_glUniform2ui; 1789GLAPI PFNGLUNIFORM2UIPROC glad_glUniform2ui;
1790#define glUniform2ui glad_glUniform2ui 1790#define glUniform2ui glad_glUniform2ui
1791typedef void (APIENTRYP PFNGLUNIFORM3UIPROC)(GLint, GLuint, GLuint, GLuint); 1791typedef void (APIENTRYP PFNGLUNIFORM3UIPROC)(GLint location, GLuint v0, GLuint v1, GLuint v2);
1792GLAPI PFNGLUNIFORM3UIPROC glad_glUniform3ui; 1792GLAPI PFNGLUNIFORM3UIPROC glad_glUniform3ui;
1793#define glUniform3ui glad_glUniform3ui 1793#define glUniform3ui glad_glUniform3ui
1794typedef void (APIENTRYP PFNGLUNIFORM4UIPROC)(GLint, GLuint, GLuint, GLuint, GLuint); 1794typedef void (APIENTRYP PFNGLUNIFORM4UIPROC)(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
1795GLAPI PFNGLUNIFORM4UIPROC glad_glUniform4ui; 1795GLAPI PFNGLUNIFORM4UIPROC glad_glUniform4ui;
1796#define glUniform4ui glad_glUniform4ui 1796#define glUniform4ui glad_glUniform4ui
1797typedef void (APIENTRYP PFNGLUNIFORM1UIVPROC)(GLint, GLsizei, const GLuint*); 1797typedef void (APIENTRYP PFNGLUNIFORM1UIVPROC)(GLint location, GLsizei count, const GLuint* value);
1798GLAPI PFNGLUNIFORM1UIVPROC glad_glUniform1uiv; 1798GLAPI PFNGLUNIFORM1UIVPROC glad_glUniform1uiv;
1799#define glUniform1uiv glad_glUniform1uiv 1799#define glUniform1uiv glad_glUniform1uiv
1800typedef void (APIENTRYP PFNGLUNIFORM2UIVPROC)(GLint, GLsizei, const GLuint*); 1800typedef void (APIENTRYP PFNGLUNIFORM2UIVPROC)(GLint location, GLsizei count, const GLuint* value);
1801GLAPI PFNGLUNIFORM2UIVPROC glad_glUniform2uiv; 1801GLAPI PFNGLUNIFORM2UIVPROC glad_glUniform2uiv;
1802#define glUniform2uiv glad_glUniform2uiv 1802#define glUniform2uiv glad_glUniform2uiv
1803typedef void (APIENTRYP PFNGLUNIFORM3UIVPROC)(GLint, GLsizei, const GLuint*); 1803typedef void (APIENTRYP PFNGLUNIFORM3UIVPROC)(GLint location, GLsizei count, const GLuint* value);
1804GLAPI PFNGLUNIFORM3UIVPROC glad_glUniform3uiv; 1804GLAPI PFNGLUNIFORM3UIVPROC glad_glUniform3uiv;
1805#define glUniform3uiv glad_glUniform3uiv 1805#define glUniform3uiv glad_glUniform3uiv
1806typedef void (APIENTRYP PFNGLUNIFORM4UIVPROC)(GLint, GLsizei, const GLuint*); 1806typedef void (APIENTRYP PFNGLUNIFORM4UIVPROC)(GLint location, GLsizei count, const GLuint* value);
1807GLAPI PFNGLUNIFORM4UIVPROC glad_glUniform4uiv; 1807GLAPI PFNGLUNIFORM4UIVPROC glad_glUniform4uiv;
1808#define glUniform4uiv glad_glUniform4uiv 1808#define glUniform4uiv glad_glUniform4uiv
1809typedef void (APIENTRYP PFNGLTEXPARAMETERIIVPROC)(GLenum, GLenum, const GLint*); 1809typedef void (APIENTRYP PFNGLTEXPARAMETERIIVPROC)(GLenum target, GLenum pname, const GLint* params);
1810GLAPI PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv; 1810GLAPI PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv;
1811#define glTexParameterIiv glad_glTexParameterIiv 1811#define glTexParameterIiv glad_glTexParameterIiv
1812typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVPROC)(GLenum, GLenum, const GLuint*); 1812typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVPROC)(GLenum target, GLenum pname, const GLuint* params);
1813GLAPI PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv; 1813GLAPI PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv;
1814#define glTexParameterIuiv glad_glTexParameterIuiv 1814#define glTexParameterIuiv glad_glTexParameterIuiv
1815typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVPROC)(GLenum, GLenum, GLint*); 1815typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVPROC)(GLenum target, GLenum pname, GLint* params);
1816GLAPI PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv; 1816GLAPI PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv;
1817#define glGetTexParameterIiv glad_glGetTexParameterIiv 1817#define glGetTexParameterIiv glad_glGetTexParameterIiv
1818typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVPROC)(GLenum, GLenum, GLuint*); 1818typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVPROC)(GLenum target, GLenum pname, GLuint* params);
1819GLAPI PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv; 1819GLAPI PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv;
1820#define glGetTexParameterIuiv glad_glGetTexParameterIuiv 1820#define glGetTexParameterIuiv glad_glGetTexParameterIuiv
1821typedef void (APIENTRYP PFNGLCLEARBUFFERIVPROC)(GLenum, GLint, const GLint*); 1821typedef void (APIENTRYP PFNGLCLEARBUFFERIVPROC)(GLenum buffer, GLint drawbuffer, const GLint* value);
1822GLAPI PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv; 1822GLAPI PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv;
1823#define glClearBufferiv glad_glClearBufferiv 1823#define glClearBufferiv glad_glClearBufferiv
1824typedef void (APIENTRYP PFNGLCLEARBUFFERUIVPROC)(GLenum, GLint, const GLuint*); 1824typedef void (APIENTRYP PFNGLCLEARBUFFERUIVPROC)(GLenum buffer, GLint drawbuffer, const GLuint* value);
1825GLAPI PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv; 1825GLAPI PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv;
1826#define glClearBufferuiv glad_glClearBufferuiv 1826#define glClearBufferuiv glad_glClearBufferuiv
1827typedef void (APIENTRYP PFNGLCLEARBUFFERFVPROC)(GLenum, GLint, const GLfloat*); 1827typedef void (APIENTRYP PFNGLCLEARBUFFERFVPROC)(GLenum buffer, GLint drawbuffer, const GLfloat* value);
1828GLAPI PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv; 1828GLAPI PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv;
1829#define glClearBufferfv glad_glClearBufferfv 1829#define glClearBufferfv glad_glClearBufferfv
1830typedef void (APIENTRYP PFNGLCLEARBUFFERFIPROC)(GLenum, GLint, GLfloat, GLint); 1830typedef void (APIENTRYP PFNGLCLEARBUFFERFIPROC)(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
1831GLAPI PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi; 1831GLAPI PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi;
1832#define glClearBufferfi glad_glClearBufferfi 1832#define glClearBufferfi glad_glClearBufferfi
1833typedef const GLubyte* (APIENTRYP PFNGLGETSTRINGIPROC)(GLenum, GLuint); 1833typedef const GLubyte* (APIENTRYP PFNGLGETSTRINGIPROC)(GLenum name, GLuint index);
1834GLAPI PFNGLGETSTRINGIPROC glad_glGetStringi; 1834GLAPI PFNGLGETSTRINGIPROC glad_glGetStringi;
1835#define glGetStringi glad_glGetStringi 1835#define glGetStringi glad_glGetStringi
1836typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFERPROC)(GLuint); 1836typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFERPROC)(GLuint renderbuffer);
1837GLAPI PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer; 1837GLAPI PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer;
1838#define glIsRenderbuffer glad_glIsRenderbuffer 1838#define glIsRenderbuffer glad_glIsRenderbuffer
1839typedef void (APIENTRYP PFNGLBINDRENDERBUFFERPROC)(GLenum, GLuint); 1839typedef void (APIENTRYP PFNGLBINDRENDERBUFFERPROC)(GLenum target, GLuint renderbuffer);
1840GLAPI PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer; 1840GLAPI PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer;
1841#define glBindRenderbuffer glad_glBindRenderbuffer 1841#define glBindRenderbuffer glad_glBindRenderbuffer
1842typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSPROC)(GLsizei, const GLuint*); 1842typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSPROC)(GLsizei n, const GLuint* renderbuffers);
1843GLAPI PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers; 1843GLAPI PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers;
1844#define glDeleteRenderbuffers glad_glDeleteRenderbuffers 1844#define glDeleteRenderbuffers glad_glDeleteRenderbuffers
1845typedef void (APIENTRYP PFNGLGENRENDERBUFFERSPROC)(GLsizei, GLuint*); 1845typedef void (APIENTRYP PFNGLGENRENDERBUFFERSPROC)(GLsizei n, GLuint* renderbuffers);
1846GLAPI PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers; 1846GLAPI PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers;
1847#define glGenRenderbuffers glad_glGenRenderbuffers 1847#define glGenRenderbuffers glad_glGenRenderbuffers
1848typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC)(GLenum, GLenum, GLsizei, GLsizei); 1848typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
1849GLAPI PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage; 1849GLAPI PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage;
1850#define glRenderbufferStorage glad_glRenderbufferStorage 1850#define glRenderbufferStorage glad_glRenderbufferStorage
1851typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC)(GLenum, GLenum, GLint*); 1851typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint* params);
1852GLAPI PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv; 1852GLAPI PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv;
1853#define glGetRenderbufferParameteriv glad_glGetRenderbufferParameteriv 1853#define glGetRenderbufferParameteriv glad_glGetRenderbufferParameteriv
1854typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFERPROC)(GLuint); 1854typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFERPROC)(GLuint framebuffer);
1855GLAPI PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer; 1855GLAPI PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer;
1856#define glIsFramebuffer glad_glIsFramebuffer 1856#define glIsFramebuffer glad_glIsFramebuffer
1857typedef void (APIENTRYP PFNGLBINDFRAMEBUFFERPROC)(GLenum, GLuint); 1857typedef void (APIENTRYP PFNGLBINDFRAMEBUFFERPROC)(GLenum target, GLuint framebuffer);
1858GLAPI PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer; 1858GLAPI PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer;
1859#define glBindFramebuffer glad_glBindFramebuffer 1859#define glBindFramebuffer glad_glBindFramebuffer
1860typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC)(GLsizei, const GLuint*); 1860typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC)(GLsizei n, const GLuint* framebuffers);
1861GLAPI PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers; 1861GLAPI PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers;
1862#define glDeleteFramebuffers glad_glDeleteFramebuffers 1862#define glDeleteFramebuffers glad_glDeleteFramebuffers
1863typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSPROC)(GLsizei, GLuint*); 1863typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSPROC)(GLsizei n, GLuint* framebuffers);
1864GLAPI PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers; 1864GLAPI PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers;
1865#define glGenFramebuffers glad_glGenFramebuffers 1865#define glGenFramebuffers glad_glGenFramebuffers
1866typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC)(GLenum); 1866typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC)(GLenum target);
1867GLAPI PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus; 1867GLAPI PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus;
1868#define glCheckFramebufferStatus glad_glCheckFramebufferStatus 1868#define glCheckFramebufferStatus glad_glCheckFramebufferStatus
1869typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DPROC)(GLenum, GLenum, GLenum, GLuint, GLint); 1869typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
1870GLAPI PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D; 1870GLAPI PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D;
1871#define glFramebufferTexture1D glad_glFramebufferTexture1D 1871#define glFramebufferTexture1D glad_glFramebufferTexture1D
1872typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC)(GLenum, GLenum, GLenum, GLuint, GLint); 1872typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
1873GLAPI PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D; 1873GLAPI PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D;
1874#define glFramebufferTexture2D glad_glFramebufferTexture2D 1874#define glFramebufferTexture2D glad_glFramebufferTexture2D
1875typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DPROC)(GLenum, GLenum, GLenum, GLuint, GLint, GLint); 1875typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
1876GLAPI PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D; 1876GLAPI PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D;
1877#define glFramebufferTexture3D glad_glFramebufferTexture3D 1877#define glFramebufferTexture3D glad_glFramebufferTexture3D
1878typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC)(GLenum, GLenum, GLenum, GLuint); 1878typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
1879GLAPI PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer; 1879GLAPI PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer;
1880#define glFramebufferRenderbuffer glad_glFramebufferRenderbuffer 1880#define glFramebufferRenderbuffer glad_glFramebufferRenderbuffer
1881typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)(GLenum, GLenum, GLenum, GLint*); 1881typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)(GLenum target, GLenum attachment, GLenum pname, GLint* params);
1882GLAPI PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv; 1882GLAPI PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv;
1883#define glGetFramebufferAttachmentParameteriv glad_glGetFramebufferAttachmentParameteriv 1883#define glGetFramebufferAttachmentParameteriv glad_glGetFramebufferAttachmentParameteriv
1884typedef void (APIENTRYP PFNGLGENERATEMIPMAPPROC)(GLenum); 1884typedef void (APIENTRYP PFNGLGENERATEMIPMAPPROC)(GLenum target);
1885GLAPI PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap; 1885GLAPI PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap;
1886#define glGenerateMipmap glad_glGenerateMipmap 1886#define glGenerateMipmap glad_glGenerateMipmap
1887typedef void (APIENTRYP PFNGLBLITFRAMEBUFFERPROC)(GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum); 1887typedef void (APIENTRYP PFNGLBLITFRAMEBUFFERPROC)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
1888GLAPI PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer; 1888GLAPI PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer;
1889#define glBlitFramebuffer glad_glBlitFramebuffer 1889#define glBlitFramebuffer glad_glBlitFramebuffer
1890typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)(GLenum, GLsizei, GLenum, GLsizei, GLsizei); 1890typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
1891GLAPI PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample; 1891GLAPI PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample;
1892#define glRenderbufferStorageMultisample glad_glRenderbufferStorageMultisample 1892#define glRenderbufferStorageMultisample glad_glRenderbufferStorageMultisample
1893typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERPROC)(GLenum, GLenum, GLuint, GLint, GLint); 1893typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
1894GLAPI PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer; 1894GLAPI PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer;
1895#define glFramebufferTextureLayer glad_glFramebufferTextureLayer 1895#define glFramebufferTextureLayer glad_glFramebufferTextureLayer
1896typedef void* (APIENTRYP PFNGLMAPBUFFERRANGEPROC)(GLenum, GLintptr, GLsizeiptr, GLbitfield); 1896typedef void* (APIENTRYP PFNGLMAPBUFFERRANGEPROC)(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
1897GLAPI PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange; 1897GLAPI PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange;
1898#define glMapBufferRange glad_glMapBufferRange 1898#define glMapBufferRange glad_glMapBufferRange
1899typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEPROC)(GLenum, GLintptr, GLsizeiptr); 1899typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEPROC)(GLenum target, GLintptr offset, GLsizeiptr length);
1900GLAPI PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange; 1900GLAPI PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange;
1901#define glFlushMappedBufferRange glad_glFlushMappedBufferRange 1901#define glFlushMappedBufferRange glad_glFlushMappedBufferRange
1902typedef void (APIENTRYP PFNGLBINDVERTEXARRAYPROC)(GLuint); 1902typedef void (APIENTRYP PFNGLBINDVERTEXARRAYPROC)(GLuint array);
1903GLAPI PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray; 1903GLAPI PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray;
1904#define glBindVertexArray glad_glBindVertexArray 1904#define glBindVertexArray glad_glBindVertexArray
1905typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSPROC)(GLsizei, const GLuint*); 1905typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSPROC)(GLsizei n, const GLuint* arrays);
1906GLAPI PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays; 1906GLAPI PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays;
1907#define glDeleteVertexArrays glad_glDeleteVertexArrays 1907#define glDeleteVertexArrays glad_glDeleteVertexArrays
1908typedef void (APIENTRYP PFNGLGENVERTEXARRAYSPROC)(GLsizei, GLuint*); 1908typedef void (APIENTRYP PFNGLGENVERTEXARRAYSPROC)(GLsizei n, GLuint* arrays);
1909GLAPI PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays; 1909GLAPI PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays;
1910#define glGenVertexArrays glad_glGenVertexArrays 1910#define glGenVertexArrays glad_glGenVertexArrays
1911typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYPROC)(GLuint); 1911typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYPROC)(GLuint array);
1912GLAPI PFNGLISVERTEXARRAYPROC glad_glIsVertexArray; 1912GLAPI PFNGLISVERTEXARRAYPROC glad_glIsVertexArray;
1913#define glIsVertexArray glad_glIsVertexArray 1913#define glIsVertexArray glad_glIsVertexArray
1914#endif 1914#endif
1915#ifndef GL_VERSION_3_1 1915#ifndef GL_VERSION_3_1
1916#define GL_VERSION_3_1 1 1916#define GL_VERSION_3_1 1
1917GLAPI int GLAD_GL_VERSION_3_1; 1917GLAPI int GLAD_GL_VERSION_3_1;
1918typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC)(GLenum, GLint, GLsizei, GLsizei); 1918typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount);
1919GLAPI PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced; 1919GLAPI PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced;
1920#define glDrawArraysInstanced glad_glDrawArraysInstanced 1920#define glDrawArraysInstanced glad_glDrawArraysInstanced
1921typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC)(GLenum, GLsizei, GLenum, const void*, GLsizei); 1921typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC)(GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei instancecount);
1922GLAPI PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced; 1922GLAPI PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced;
1923#define glDrawElementsInstanced glad_glDrawElementsInstanced 1923#define glDrawElementsInstanced glad_glDrawElementsInstanced
1924typedef void (APIENTRYP PFNGLTEXBUFFERPROC)(GLenum, GLenum, GLuint); 1924typedef void (APIENTRYP PFNGLTEXBUFFERPROC)(GLenum target, GLenum internalformat, GLuint buffer);
1925GLAPI PFNGLTEXBUFFERPROC glad_glTexBuffer; 1925GLAPI PFNGLTEXBUFFERPROC glad_glTexBuffer;
1926#define glTexBuffer glad_glTexBuffer 1926#define glTexBuffer glad_glTexBuffer
1927typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXPROC)(GLuint); 1927typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXPROC)(GLuint index);
1928GLAPI PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex; 1928GLAPI PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex;
1929#define glPrimitiveRestartIndex glad_glPrimitiveRestartIndex 1929#define glPrimitiveRestartIndex glad_glPrimitiveRestartIndex
1930typedef void (APIENTRYP PFNGLCOPYBUFFERSUBDATAPROC)(GLenum, GLenum, GLintptr, GLintptr, GLsizeiptr); 1930typedef void (APIENTRYP PFNGLCOPYBUFFERSUBDATAPROC)(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
1931GLAPI PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData; 1931GLAPI PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData;
1932#define glCopyBufferSubData glad_glCopyBufferSubData 1932#define glCopyBufferSubData glad_glCopyBufferSubData
1933typedef void (APIENTRYP PFNGLGETUNIFORMINDICESPROC)(GLuint, GLsizei, const GLchar**, GLuint*); 1933typedef void (APIENTRYP PFNGLGETUNIFORMINDICESPROC)(GLuint program, GLsizei uniformCount, const GLchar** uniformNames, GLuint* uniformIndices);
1934GLAPI PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices; 1934GLAPI PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices;
1935#define glGetUniformIndices glad_glGetUniformIndices 1935#define glGetUniformIndices glad_glGetUniformIndices
1936typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMSIVPROC)(GLuint, GLsizei, const GLuint*, GLenum, GLint*); 1936typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMSIVPROC)(GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params);
1937GLAPI PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv; 1937GLAPI PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv;
1938#define glGetActiveUniformsiv glad_glGetActiveUniformsiv 1938#define glGetActiveUniformsiv glad_glGetActiveUniformsiv
1939typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMNAMEPROC)(GLuint, GLuint, GLsizei, GLsizei*, GLchar*); 1939typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMNAMEPROC)(GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformName);
1940GLAPI PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName; 1940GLAPI PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName;
1941#define glGetActiveUniformName glad_glGetActiveUniformName 1941#define glGetActiveUniformName glad_glGetActiveUniformName
1942typedef GLuint (APIENTRYP PFNGLGETUNIFORMBLOCKINDEXPROC)(GLuint, const GLchar*); 1942typedef GLuint (APIENTRYP PFNGLGETUNIFORMBLOCKINDEXPROC)(GLuint program, const GLchar* uniformBlockName);
1943GLAPI PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex; 1943GLAPI PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex;
1944#define glGetUniformBlockIndex glad_glGetUniformBlockIndex 1944#define glGetUniformBlockIndex glad_glGetUniformBlockIndex
1945typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVPROC)(GLuint, GLuint, GLenum, GLint*); 1945typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVPROC)(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params);
1946GLAPI PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv; 1946GLAPI PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv;
1947#define glGetActiveUniformBlockiv glad_glGetActiveUniformBlockiv 1947#define glGetActiveUniformBlockiv glad_glGetActiveUniformBlockiv
1948typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)(GLuint, GLuint, GLsizei, GLsizei*, GLchar*); 1948typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName);
1949GLAPI PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName; 1949GLAPI PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName;
1950#define glGetActiveUniformBlockName glad_glGetActiveUniformBlockName 1950#define glGetActiveUniformBlockName glad_glGetActiveUniformBlockName
1951typedef void (APIENTRYP PFNGLUNIFORMBLOCKBINDINGPROC)(GLuint, GLuint, GLuint); 1951typedef void (APIENTRYP PFNGLUNIFORMBLOCKBINDINGPROC)(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
1952GLAPI PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding; 1952GLAPI PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding;
1953#define glUniformBlockBinding glad_glUniformBlockBinding 1953#define glUniformBlockBinding glad_glUniformBlockBinding
1954#endif 1954#endif
1955#ifndef GL_VERSION_3_2 1955#ifndef GL_VERSION_3_2
1956#define GL_VERSION_3_2 1 1956#define GL_VERSION_3_2 1
1957GLAPI int GLAD_GL_VERSION_3_2; 1957GLAPI int GLAD_GL_VERSION_3_2;
1958typedef void (APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC)(GLenum, GLsizei, GLenum, const void*, GLint); 1958typedef void (APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC)(GLenum mode, GLsizei count, GLenum type, const void* indices, GLint basevertex);
1959GLAPI PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex; 1959GLAPI PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex;
1960#define glDrawElementsBaseVertex glad_glDrawElementsBaseVertex 1960#define glDrawElementsBaseVertex glad_glDrawElementsBaseVertex
1961typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)(GLenum, GLuint, GLuint, GLsizei, GLenum, const void*, GLint); 1961typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices, GLint basevertex);
1962GLAPI PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex; 1962GLAPI PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex;
1963#define glDrawRangeElementsBaseVertex glad_glDrawRangeElementsBaseVertex 1963#define glDrawRangeElementsBaseVertex glad_glDrawRangeElementsBaseVertex
1964typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)(GLenum, GLsizei, GLenum, const void*, GLsizei, GLint); 1964typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)(GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei instancecount, GLint basevertex);
1965GLAPI PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex; 1965GLAPI PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex;
1966#define glDrawElementsInstancedBaseVertex glad_glDrawElementsInstancedBaseVertex 1966#define glDrawElementsInstancedBaseVertex glad_glDrawElementsInstancedBaseVertex
1967typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)(GLenum, const GLsizei*, GLenum, const void**, GLsizei, const GLint*); 1967typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)(GLenum mode, const GLsizei* count, GLenum type, const void** indices, GLsizei drawcount, const GLint* basevertex);
1968GLAPI PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex; 1968GLAPI PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex;
1969#define glMultiDrawElementsBaseVertex glad_glMultiDrawElementsBaseVertex 1969#define glMultiDrawElementsBaseVertex glad_glMultiDrawElementsBaseVertex
1970typedef void (APIENTRYP PFNGLPROVOKINGVERTEXPROC)(GLenum); 1970typedef void (APIENTRYP PFNGLPROVOKINGVERTEXPROC)(GLenum mode);
1971GLAPI PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex; 1971GLAPI PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex;
1972#define glProvokingVertex glad_glProvokingVertex 1972#define glProvokingVertex glad_glProvokingVertex
1973typedef GLsync (APIENTRYP PFNGLFENCESYNCPROC)(GLenum, GLbitfield); 1973typedef GLsync (APIENTRYP PFNGLFENCESYNCPROC)(GLenum condition, GLbitfield flags);
1974GLAPI PFNGLFENCESYNCPROC glad_glFenceSync; 1974GLAPI PFNGLFENCESYNCPROC glad_glFenceSync;
1975#define glFenceSync glad_glFenceSync 1975#define glFenceSync glad_glFenceSync
1976typedef GLboolean (APIENTRYP PFNGLISSYNCPROC)(GLsync); 1976typedef GLboolean (APIENTRYP PFNGLISSYNCPROC)(GLsync sync);
1977GLAPI PFNGLISSYNCPROC glad_glIsSync; 1977GLAPI PFNGLISSYNCPROC glad_glIsSync;
1978#define glIsSync glad_glIsSync 1978#define glIsSync glad_glIsSync
1979typedef void (APIENTRYP PFNGLDELETESYNCPROC)(GLsync); 1979typedef void (APIENTRYP PFNGLDELETESYNCPROC)(GLsync sync);
1980GLAPI PFNGLDELETESYNCPROC glad_glDeleteSync; 1980GLAPI PFNGLDELETESYNCPROC glad_glDeleteSync;
1981#define glDeleteSync glad_glDeleteSync 1981#define glDeleteSync glad_glDeleteSync
1982typedef GLenum (APIENTRYP PFNGLCLIENTWAITSYNCPROC)(GLsync, GLbitfield, GLuint64); 1982typedef GLenum (APIENTRYP PFNGLCLIENTWAITSYNCPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout);
1983GLAPI PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync; 1983GLAPI PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync;
1984#define glClientWaitSync glad_glClientWaitSync 1984#define glClientWaitSync glad_glClientWaitSync
1985typedef void (APIENTRYP PFNGLWAITSYNCPROC)(GLsync, GLbitfield, GLuint64); 1985typedef void (APIENTRYP PFNGLWAITSYNCPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout);
1986GLAPI PFNGLWAITSYNCPROC glad_glWaitSync; 1986GLAPI PFNGLWAITSYNCPROC glad_glWaitSync;
1987#define glWaitSync glad_glWaitSync 1987#define glWaitSync glad_glWaitSync
1988typedef void (APIENTRYP PFNGLGETINTEGER64VPROC)(GLenum, GLint64*); 1988typedef void (APIENTRYP PFNGLGETINTEGER64VPROC)(GLenum pname, GLint64* data);
1989GLAPI PFNGLGETINTEGER64VPROC glad_glGetInteger64v; 1989GLAPI PFNGLGETINTEGER64VPROC glad_glGetInteger64v;
1990#define glGetInteger64v glad_glGetInteger64v 1990#define glGetInteger64v glad_glGetInteger64v
1991typedef void (APIENTRYP PFNGLGETSYNCIVPROC)(GLsync, GLenum, GLsizei, GLsizei*, GLint*); 1991typedef void (APIENTRYP PFNGLGETSYNCIVPROC)(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values);
1992GLAPI PFNGLGETSYNCIVPROC glad_glGetSynciv; 1992GLAPI PFNGLGETSYNCIVPROC glad_glGetSynciv;
1993#define glGetSynciv glad_glGetSynciv 1993#define glGetSynciv glad_glGetSynciv
1994typedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC)(GLenum, GLuint, GLint64*); 1994typedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC)(GLenum target, GLuint index, GLint64* data);
1995GLAPI PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v; 1995GLAPI PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v;
1996#define glGetInteger64i_v glad_glGetInteger64i_v 1996#define glGetInteger64i_v glad_glGetInteger64i_v
1997typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC)(GLenum, GLenum, GLint64*); 1997typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC)(GLenum target, GLenum pname, GLint64* params);
1998GLAPI PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v; 1998GLAPI PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v;
1999#define glGetBufferParameteri64v glad_glGetBufferParameteri64v 1999#define glGetBufferParameteri64v glad_glGetBufferParameteri64v
2000typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREPROC)(GLenum, GLenum, GLuint, GLint); 2000typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level);
2001GLAPI PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture; 2001GLAPI PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture;
2002#define glFramebufferTexture glad_glFramebufferTexture 2002#define glFramebufferTexture glad_glFramebufferTexture
2003typedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLEPROC)(GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLboolean); 2003typedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
2004GLAPI PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample; 2004GLAPI PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample;
2005#define glTexImage2DMultisample glad_glTexImage2DMultisample 2005#define glTexImage2DMultisample glad_glTexImage2DMultisample
2006typedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLEPROC)(GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLsizei, GLboolean); 2006typedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
2007GLAPI PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample; 2007GLAPI PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample;
2008#define glTexImage3DMultisample glad_glTexImage3DMultisample 2008#define glTexImage3DMultisample glad_glTexImage3DMultisample
2009typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVPROC)(GLenum, GLuint, GLfloat*); 2009typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVPROC)(GLenum pname, GLuint index, GLfloat* val);
2010GLAPI PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv; 2010GLAPI PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv;
2011#define glGetMultisamplefv glad_glGetMultisamplefv 2011#define glGetMultisamplefv glad_glGetMultisamplefv
2012typedef void (APIENTRYP PFNGLSAMPLEMASKIPROC)(GLuint, GLbitfield); 2012typedef void (APIENTRYP PFNGLSAMPLEMASKIPROC)(GLuint maskNumber, GLbitfield mask);
2013GLAPI PFNGLSAMPLEMASKIPROC glad_glSampleMaski; 2013GLAPI PFNGLSAMPLEMASKIPROC glad_glSampleMaski;
2014#define glSampleMaski glad_glSampleMaski 2014#define glSampleMaski glad_glSampleMaski
2015#endif 2015#endif
2016#ifndef GL_VERSION_3_3 2016#ifndef GL_VERSION_3_3
2017#define GL_VERSION_3_3 1 2017#define GL_VERSION_3_3 1
2018GLAPI int GLAD_GL_VERSION_3_3; 2018GLAPI int GLAD_GL_VERSION_3_3;
2019typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONINDEXEDPROC)(GLuint, GLuint, GLuint, const GLchar*); 2019typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONINDEXEDPROC)(GLuint program, GLuint colorNumber, GLuint index, const GLchar* name);
2020GLAPI PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed; 2020GLAPI PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed;
2021#define glBindFragDataLocationIndexed glad_glBindFragDataLocationIndexed 2021#define glBindFragDataLocationIndexed glad_glBindFragDataLocationIndexed
2022typedef GLint (APIENTRYP PFNGLGETFRAGDATAINDEXPROC)(GLuint, const GLchar*); 2022typedef GLint (APIENTRYP PFNGLGETFRAGDATAINDEXPROC)(GLuint program, const GLchar* name);
2023GLAPI PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex; 2023GLAPI PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex;
2024#define glGetFragDataIndex glad_glGetFragDataIndex 2024#define glGetFragDataIndex glad_glGetFragDataIndex
2025typedef void (APIENTRYP PFNGLGENSAMPLERSPROC)(GLsizei, GLuint*); 2025typedef void (APIENTRYP PFNGLGENSAMPLERSPROC)(GLsizei count, GLuint* samplers);
2026GLAPI PFNGLGENSAMPLERSPROC glad_glGenSamplers; 2026GLAPI PFNGLGENSAMPLERSPROC glad_glGenSamplers;
2027#define glGenSamplers glad_glGenSamplers 2027#define glGenSamplers glad_glGenSamplers
2028typedef void (APIENTRYP PFNGLDELETESAMPLERSPROC)(GLsizei, const GLuint*); 2028typedef void (APIENTRYP PFNGLDELETESAMPLERSPROC)(GLsizei count, const GLuint* samplers);
2029GLAPI PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers; 2029GLAPI PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers;
2030#define glDeleteSamplers glad_glDeleteSamplers 2030#define glDeleteSamplers glad_glDeleteSamplers
2031typedef GLboolean (APIENTRYP PFNGLISSAMPLERPROC)(GLuint); 2031typedef GLboolean (APIENTRYP PFNGLISSAMPLERPROC)(GLuint sampler);
2032GLAPI PFNGLISSAMPLERPROC glad_glIsSampler; 2032GLAPI PFNGLISSAMPLERPROC glad_glIsSampler;
2033#define glIsSampler glad_glIsSampler 2033#define glIsSampler glad_glIsSampler
2034typedef void (APIENTRYP PFNGLBINDSAMPLERPROC)(GLuint, GLuint); 2034typedef void (APIENTRYP PFNGLBINDSAMPLERPROC)(GLuint unit, GLuint sampler);
2035GLAPI PFNGLBINDSAMPLERPROC glad_glBindSampler; 2035GLAPI PFNGLBINDSAMPLERPROC glad_glBindSampler;
2036#define glBindSampler glad_glBindSampler 2036#define glBindSampler glad_glBindSampler
2037typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIPROC)(GLuint, GLenum, GLint); 2037typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIPROC)(GLuint sampler, GLenum pname, GLint param);
2038GLAPI PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri; 2038GLAPI PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri;
2039#define glSamplerParameteri glad_glSamplerParameteri 2039#define glSamplerParameteri glad_glSamplerParameteri
2040typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIVPROC)(GLuint, GLenum, const GLint*); 2040typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIVPROC)(GLuint sampler, GLenum pname, const GLint* param);
2041GLAPI PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv; 2041GLAPI PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv;
2042#define glSamplerParameteriv glad_glSamplerParameteriv 2042#define glSamplerParameteriv glad_glSamplerParameteriv
2043typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFPROC)(GLuint, GLenum, GLfloat); 2043typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFPROC)(GLuint sampler, GLenum pname, GLfloat param);
2044GLAPI PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf; 2044GLAPI PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf;
2045#define glSamplerParameterf glad_glSamplerParameterf 2045#define glSamplerParameterf glad_glSamplerParameterf
2046typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFVPROC)(GLuint, GLenum, const GLfloat*); 2046typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFVPROC)(GLuint sampler, GLenum pname, const GLfloat* param);
2047GLAPI PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv; 2047GLAPI PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv;
2048#define glSamplerParameterfv glad_glSamplerParameterfv 2048#define glSamplerParameterfv glad_glSamplerParameterfv
2049typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIIVPROC)(GLuint, GLenum, const GLint*); 2049typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIIVPROC)(GLuint sampler, GLenum pname, const GLint* param);
2050GLAPI PFNGLSAMPLERPARAMETERIIVPROC glad_glSamplerParameterIiv; 2050GLAPI PFNGLSAMPLERPARAMETERIIVPROC glad_glSamplerParameterIiv;
2051#define glSamplerParameterIiv glad_glSamplerParameterIiv 2051#define glSamplerParameterIiv glad_glSamplerParameterIiv
2052typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIUIVPROC)(GLuint, GLenum, const GLuint*); 2052typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIUIVPROC)(GLuint sampler, GLenum pname, const GLuint* param);
2053GLAPI PFNGLSAMPLERPARAMETERIUIVPROC glad_glSamplerParameterIuiv; 2053GLAPI PFNGLSAMPLERPARAMETERIUIVPROC glad_glSamplerParameterIuiv;
2054#define glSamplerParameterIuiv glad_glSamplerParameterIuiv 2054#define glSamplerParameterIuiv glad_glSamplerParameterIuiv
2055typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIVPROC)(GLuint, GLenum, GLint*); 2055typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIVPROC)(GLuint sampler, GLenum pname, GLint* params);
2056GLAPI PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv; 2056GLAPI PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv;
2057#define glGetSamplerParameteriv glad_glGetSamplerParameteriv 2057#define glGetSamplerParameteriv glad_glGetSamplerParameteriv
2058typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIIVPROC)(GLuint, GLenum, GLint*); 2058typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIIVPROC)(GLuint sampler, GLenum pname, GLint* params);
2059GLAPI PFNGLGETSAMPLERPARAMETERIIVPROC glad_glGetSamplerParameterIiv; 2059GLAPI PFNGLGETSAMPLERPARAMETERIIVPROC glad_glGetSamplerParameterIiv;
2060#define glGetSamplerParameterIiv glad_glGetSamplerParameterIiv 2060#define glGetSamplerParameterIiv glad_glGetSamplerParameterIiv
2061typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERFVPROC)(GLuint, GLenum, GLfloat*); 2061typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERFVPROC)(GLuint sampler, GLenum pname, GLfloat* params);
2062GLAPI PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv; 2062GLAPI PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv;
2063#define glGetSamplerParameterfv glad_glGetSamplerParameterfv 2063#define glGetSamplerParameterfv glad_glGetSamplerParameterfv
2064typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVPROC)(GLuint, GLenum, GLuint*); 2064typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVPROC)(GLuint sampler, GLenum pname, GLuint* params);
2065GLAPI PFNGLGETSAMPLERPARAMETERIUIVPROC glad_glGetSamplerParameterIuiv; 2065GLAPI PFNGLGETSAMPLERPARAMETERIUIVPROC glad_glGetSamplerParameterIuiv;
2066#define glGetSamplerParameterIuiv glad_glGetSamplerParameterIuiv 2066#define glGetSamplerParameterIuiv glad_glGetSamplerParameterIuiv
2067typedef void (APIENTRYP PFNGLQUERYCOUNTERPROC)(GLuint, GLenum); 2067typedef void (APIENTRYP PFNGLQUERYCOUNTERPROC)(GLuint id, GLenum target);
2068GLAPI PFNGLQUERYCOUNTERPROC glad_glQueryCounter; 2068GLAPI PFNGLQUERYCOUNTERPROC glad_glQueryCounter;
2069#define glQueryCounter glad_glQueryCounter 2069#define glQueryCounter glad_glQueryCounter
2070typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VPROC)(GLuint, GLenum, GLint64*); 2070typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VPROC)(GLuint id, GLenum pname, GLint64* params);
2071GLAPI PFNGLGETQUERYOBJECTI64VPROC glad_glGetQueryObjecti64v; 2071GLAPI PFNGLGETQUERYOBJECTI64VPROC glad_glGetQueryObjecti64v;
2072#define glGetQueryObjecti64v glad_glGetQueryObjecti64v 2072#define glGetQueryObjecti64v glad_glGetQueryObjecti64v
2073typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VPROC)(GLuint, GLenum, GLuint64*); 2073typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VPROC)(GLuint id, GLenum pname, GLuint64* params);
2074GLAPI PFNGLGETQUERYOBJECTUI64VPROC glad_glGetQueryObjectui64v; 2074GLAPI PFNGLGETQUERYOBJECTUI64VPROC glad_glGetQueryObjectui64v;
2075#define glGetQueryObjectui64v glad_glGetQueryObjectui64v 2075#define glGetQueryObjectui64v glad_glGetQueryObjectui64v
2076typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORPROC)(GLuint, GLuint); 2076typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORPROC)(GLuint index, GLuint divisor);
2077GLAPI PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor; 2077GLAPI PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor;
2078#define glVertexAttribDivisor glad_glVertexAttribDivisor 2078#define glVertexAttribDivisor glad_glVertexAttribDivisor
2079typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIPROC)(GLuint, GLenum, GLboolean, GLuint); 2079typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value);
2080GLAPI PFNGLVERTEXATTRIBP1UIPROC glad_glVertexAttribP1ui; 2080GLAPI PFNGLVERTEXATTRIBP1UIPROC glad_glVertexAttribP1ui;
2081#define glVertexAttribP1ui glad_glVertexAttribP1ui 2081#define glVertexAttribP1ui glad_glVertexAttribP1ui
2082typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIVPROC)(GLuint, GLenum, GLboolean, const GLuint*); 2082typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint* value);
2083GLAPI PFNGLVERTEXATTRIBP1UIVPROC glad_glVertexAttribP1uiv; 2083GLAPI PFNGLVERTEXATTRIBP1UIVPROC glad_glVertexAttribP1uiv;
2084#define glVertexAttribP1uiv glad_glVertexAttribP1uiv 2084#define glVertexAttribP1uiv glad_glVertexAttribP1uiv
2085typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIPROC)(GLuint, GLenum, GLboolean, GLuint); 2085typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value);
2086GLAPI PFNGLVERTEXATTRIBP2UIPROC glad_glVertexAttribP2ui; 2086GLAPI PFNGLVERTEXATTRIBP2UIPROC glad_glVertexAttribP2ui;
2087#define glVertexAttribP2ui glad_glVertexAttribP2ui 2087#define glVertexAttribP2ui glad_glVertexAttribP2ui
2088typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIVPROC)(GLuint, GLenum, GLboolean, const GLuint*); 2088typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint* value);
2089GLAPI PFNGLVERTEXATTRIBP2UIVPROC glad_glVertexAttribP2uiv; 2089GLAPI PFNGLVERTEXATTRIBP2UIVPROC glad_glVertexAttribP2uiv;
2090#define glVertexAttribP2uiv glad_glVertexAttribP2uiv 2090#define glVertexAttribP2uiv glad_glVertexAttribP2uiv
2091typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIPROC)(GLuint, GLenum, GLboolean, GLuint); 2091typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value);
2092GLAPI PFNGLVERTEXATTRIBP3UIPROC glad_glVertexAttribP3ui; 2092GLAPI PFNGLVERTEXATTRIBP3UIPROC glad_glVertexAttribP3ui;
2093#define glVertexAttribP3ui glad_glVertexAttribP3ui 2093#define glVertexAttribP3ui glad_glVertexAttribP3ui
2094typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIVPROC)(GLuint, GLenum, GLboolean, const GLuint*); 2094typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint* value);
2095GLAPI PFNGLVERTEXATTRIBP3UIVPROC glad_glVertexAttribP3uiv; 2095GLAPI PFNGLVERTEXATTRIBP3UIVPROC glad_glVertexAttribP3uiv;
2096#define glVertexAttribP3uiv glad_glVertexAttribP3uiv 2096#define glVertexAttribP3uiv glad_glVertexAttribP3uiv
2097typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIPROC)(GLuint, GLenum, GLboolean, GLuint); 2097typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value);
2098GLAPI PFNGLVERTEXATTRIBP4UIPROC glad_glVertexAttribP4ui; 2098GLAPI PFNGLVERTEXATTRIBP4UIPROC glad_glVertexAttribP4ui;
2099#define glVertexAttribP4ui glad_glVertexAttribP4ui 2099#define glVertexAttribP4ui glad_glVertexAttribP4ui
2100typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIVPROC)(GLuint, GLenum, GLboolean, const GLuint*); 2100typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint* value);
2101GLAPI PFNGLVERTEXATTRIBP4UIVPROC glad_glVertexAttribP4uiv; 2101GLAPI PFNGLVERTEXATTRIBP4UIVPROC glad_glVertexAttribP4uiv;
2102#define glVertexAttribP4uiv glad_glVertexAttribP4uiv 2102#define glVertexAttribP4uiv glad_glVertexAttribP4uiv
2103typedef void (APIENTRYP PFNGLVERTEXP2UIPROC)(GLenum, GLuint); 2103typedef void (APIENTRYP PFNGLVERTEXP2UIPROC)(GLenum type, GLuint value);
2104GLAPI PFNGLVERTEXP2UIPROC glad_glVertexP2ui; 2104GLAPI PFNGLVERTEXP2UIPROC glad_glVertexP2ui;
2105#define glVertexP2ui glad_glVertexP2ui 2105#define glVertexP2ui glad_glVertexP2ui
2106typedef void (APIENTRYP PFNGLVERTEXP2UIVPROC)(GLenum, const GLuint*); 2106typedef void (APIENTRYP PFNGLVERTEXP2UIVPROC)(GLenum type, const GLuint* value);
2107GLAPI PFNGLVERTEXP2UIVPROC glad_glVertexP2uiv; 2107GLAPI PFNGLVERTEXP2UIVPROC glad_glVertexP2uiv;
2108#define glVertexP2uiv glad_glVertexP2uiv 2108#define glVertexP2uiv glad_glVertexP2uiv
2109typedef void (APIENTRYP PFNGLVERTEXP3UIPROC)(GLenum, GLuint); 2109typedef void (APIENTRYP PFNGLVERTEXP3UIPROC)(GLenum type, GLuint value);
2110GLAPI PFNGLVERTEXP3UIPROC glad_glVertexP3ui; 2110GLAPI PFNGLVERTEXP3UIPROC glad_glVertexP3ui;
2111#define glVertexP3ui glad_glVertexP3ui 2111#define glVertexP3ui glad_glVertexP3ui
2112typedef void (APIENTRYP PFNGLVERTEXP3UIVPROC)(GLenum, const GLuint*); 2112typedef void (APIENTRYP PFNGLVERTEXP3UIVPROC)(GLenum type, const GLuint* value);
2113GLAPI PFNGLVERTEXP3UIVPROC glad_glVertexP3uiv; 2113GLAPI PFNGLVERTEXP3UIVPROC glad_glVertexP3uiv;
2114#define glVertexP3uiv glad_glVertexP3uiv 2114#define glVertexP3uiv glad_glVertexP3uiv
2115typedef void (APIENTRYP PFNGLVERTEXP4UIPROC)(GLenum, GLuint); 2115typedef void (APIENTRYP PFNGLVERTEXP4UIPROC)(GLenum type, GLuint value);
2116GLAPI PFNGLVERTEXP4UIPROC glad_glVertexP4ui; 2116GLAPI PFNGLVERTEXP4UIPROC glad_glVertexP4ui;
2117#define glVertexP4ui glad_glVertexP4ui 2117#define glVertexP4ui glad_glVertexP4ui
2118typedef void (APIENTRYP PFNGLVERTEXP4UIVPROC)(GLenum, const GLuint*); 2118typedef void (APIENTRYP PFNGLVERTEXP4UIVPROC)(GLenum type, const GLuint* value);
2119GLAPI PFNGLVERTEXP4UIVPROC glad_glVertexP4uiv; 2119GLAPI PFNGLVERTEXP4UIVPROC glad_glVertexP4uiv;
2120#define glVertexP4uiv glad_glVertexP4uiv 2120#define glVertexP4uiv glad_glVertexP4uiv
2121typedef void (APIENTRYP PFNGLTEXCOORDP1UIPROC)(GLenum, GLuint); 2121typedef void (APIENTRYP PFNGLTEXCOORDP1UIPROC)(GLenum type, GLuint coords);
2122GLAPI PFNGLTEXCOORDP1UIPROC glad_glTexCoordP1ui; 2122GLAPI PFNGLTEXCOORDP1UIPROC glad_glTexCoordP1ui;
2123#define glTexCoordP1ui glad_glTexCoordP1ui 2123#define glTexCoordP1ui glad_glTexCoordP1ui
2124typedef void (APIENTRYP PFNGLTEXCOORDP1UIVPROC)(GLenum, const GLuint*); 2124typedef void (APIENTRYP PFNGLTEXCOORDP1UIVPROC)(GLenum type, const GLuint* coords);
2125GLAPI PFNGLTEXCOORDP1UIVPROC glad_glTexCoordP1uiv; 2125GLAPI PFNGLTEXCOORDP1UIVPROC glad_glTexCoordP1uiv;
2126#define glTexCoordP1uiv glad_glTexCoordP1uiv 2126#define glTexCoordP1uiv glad_glTexCoordP1uiv
2127typedef void (APIENTRYP PFNGLTEXCOORDP2UIPROC)(GLenum, GLuint); 2127typedef void (APIENTRYP PFNGLTEXCOORDP2UIPROC)(GLenum type, GLuint coords);
2128GLAPI PFNGLTEXCOORDP2UIPROC glad_glTexCoordP2ui; 2128GLAPI PFNGLTEXCOORDP2UIPROC glad_glTexCoordP2ui;
2129#define glTexCoordP2ui glad_glTexCoordP2ui 2129#define glTexCoordP2ui glad_glTexCoordP2ui
2130typedef void (APIENTRYP PFNGLTEXCOORDP2UIVPROC)(GLenum, const GLuint*); 2130typedef void (APIENTRYP PFNGLTEXCOORDP2UIVPROC)(GLenum type, const GLuint* coords);
2131GLAPI PFNGLTEXCOORDP2UIVPROC glad_glTexCoordP2uiv; 2131GLAPI PFNGLTEXCOORDP2UIVPROC glad_glTexCoordP2uiv;
2132#define glTexCoordP2uiv glad_glTexCoordP2uiv 2132#define glTexCoordP2uiv glad_glTexCoordP2uiv
2133typedef void (APIENTRYP PFNGLTEXCOORDP3UIPROC)(GLenum, GLuint); 2133typedef void (APIENTRYP PFNGLTEXCOORDP3UIPROC)(GLenum type, GLuint coords);
2134GLAPI PFNGLTEXCOORDP3UIPROC glad_glTexCoordP3ui; 2134GLAPI PFNGLTEXCOORDP3UIPROC glad_glTexCoordP3ui;
2135#define glTexCoordP3ui glad_glTexCoordP3ui 2135#define glTexCoordP3ui glad_glTexCoordP3ui
2136typedef void (APIENTRYP PFNGLTEXCOORDP3UIVPROC)(GLenum, const GLuint*); 2136typedef void (APIENTRYP PFNGLTEXCOORDP3UIVPROC)(GLenum type, const GLuint* coords);
2137GLAPI PFNGLTEXCOORDP3UIVPROC glad_glTexCoordP3uiv; 2137GLAPI PFNGLTEXCOORDP3UIVPROC glad_glTexCoordP3uiv;
2138#define glTexCoordP3uiv glad_glTexCoordP3uiv 2138#define glTexCoordP3uiv glad_glTexCoordP3uiv
2139typedef void (APIENTRYP PFNGLTEXCOORDP4UIPROC)(GLenum, GLuint); 2139typedef void (APIENTRYP PFNGLTEXCOORDP4UIPROC)(GLenum type, GLuint coords);
2140GLAPI PFNGLTEXCOORDP4UIPROC glad_glTexCoordP4ui; 2140GLAPI PFNGLTEXCOORDP4UIPROC glad_glTexCoordP4ui;
2141#define glTexCoordP4ui glad_glTexCoordP4ui 2141#define glTexCoordP4ui glad_glTexCoordP4ui
2142typedef void (APIENTRYP PFNGLTEXCOORDP4UIVPROC)(GLenum, const GLuint*); 2142typedef void (APIENTRYP PFNGLTEXCOORDP4UIVPROC)(GLenum type, const GLuint* coords);
2143GLAPI PFNGLTEXCOORDP4UIVPROC glad_glTexCoordP4uiv; 2143GLAPI PFNGLTEXCOORDP4UIVPROC glad_glTexCoordP4uiv;
2144#define glTexCoordP4uiv glad_glTexCoordP4uiv 2144#define glTexCoordP4uiv glad_glTexCoordP4uiv
2145typedef void (APIENTRYP PFNGLMULTITEXCOORDP1UIPROC)(GLenum, GLenum, GLuint); 2145typedef void (APIENTRYP PFNGLMULTITEXCOORDP1UIPROC)(GLenum texture, GLenum type, GLuint coords);
2146GLAPI PFNGLMULTITEXCOORDP1UIPROC glad_glMultiTexCoordP1ui; 2146GLAPI PFNGLMULTITEXCOORDP1UIPROC glad_glMultiTexCoordP1ui;
2147#define glMultiTexCoordP1ui glad_glMultiTexCoordP1ui 2147#define glMultiTexCoordP1ui glad_glMultiTexCoordP1ui
2148typedef void (APIENTRYP PFNGLMULTITEXCOORDP1UIVPROC)(GLenum, GLenum, const GLuint*); 2148typedef void (APIENTRYP PFNGLMULTITEXCOORDP1UIVPROC)(GLenum texture, GLenum type, const GLuint* coords);
2149GLAPI PFNGLMULTITEXCOORDP1UIVPROC glad_glMultiTexCoordP1uiv; 2149GLAPI PFNGLMULTITEXCOORDP1UIVPROC glad_glMultiTexCoordP1uiv;
2150#define glMultiTexCoordP1uiv glad_glMultiTexCoordP1uiv 2150#define glMultiTexCoordP1uiv glad_glMultiTexCoordP1uiv
2151typedef void (APIENTRYP PFNGLMULTITEXCOORDP2UIPROC)(GLenum, GLenum, GLuint); 2151typedef void (APIENTRYP PFNGLMULTITEXCOORDP2UIPROC)(GLenum texture, GLenum type, GLuint coords);
2152GLAPI PFNGLMULTITEXCOORDP2UIPROC glad_glMultiTexCoordP2ui; 2152GLAPI PFNGLMULTITEXCOORDP2UIPROC glad_glMultiTexCoordP2ui;
2153#define glMultiTexCoordP2ui glad_glMultiTexCoordP2ui 2153#define glMultiTexCoordP2ui glad_glMultiTexCoordP2ui
2154typedef void (APIENTRYP PFNGLMULTITEXCOORDP2UIVPROC)(GLenum, GLenum, const GLuint*); 2154typedef void (APIENTRYP PFNGLMULTITEXCOORDP2UIVPROC)(GLenum texture, GLenum type, const GLuint* coords);
2155GLAPI PFNGLMULTITEXCOORDP2UIVPROC glad_glMultiTexCoordP2uiv; 2155GLAPI PFNGLMULTITEXCOORDP2UIVPROC glad_glMultiTexCoordP2uiv;
2156#define glMultiTexCoordP2uiv glad_glMultiTexCoordP2uiv 2156#define glMultiTexCoordP2uiv glad_glMultiTexCoordP2uiv
2157typedef void (APIENTRYP PFNGLMULTITEXCOORDP3UIPROC)(GLenum, GLenum, GLuint); 2157typedef void (APIENTRYP PFNGLMULTITEXCOORDP3UIPROC)(GLenum texture, GLenum type, GLuint coords);
2158GLAPI PFNGLMULTITEXCOORDP3UIPROC glad_glMultiTexCoordP3ui; 2158GLAPI PFNGLMULTITEXCOORDP3UIPROC glad_glMultiTexCoordP3ui;
2159#define glMultiTexCoordP3ui glad_glMultiTexCoordP3ui 2159#define glMultiTexCoordP3ui glad_glMultiTexCoordP3ui
2160typedef void (APIENTRYP PFNGLMULTITEXCOORDP3UIVPROC)(GLenum, GLenum, const GLuint*); 2160typedef void (APIENTRYP PFNGLMULTITEXCOORDP3UIVPROC)(GLenum texture, GLenum type, const GLuint* coords);
2161GLAPI PFNGLMULTITEXCOORDP3UIVPROC glad_glMultiTexCoordP3uiv; 2161GLAPI PFNGLMULTITEXCOORDP3UIVPROC glad_glMultiTexCoordP3uiv;
2162#define glMultiTexCoordP3uiv glad_glMultiTexCoordP3uiv 2162#define glMultiTexCoordP3uiv glad_glMultiTexCoordP3uiv
2163typedef void (APIENTRYP PFNGLMULTITEXCOORDP4UIPROC)(GLenum, GLenum, GLuint); 2163typedef void (APIENTRYP PFNGLMULTITEXCOORDP4UIPROC)(GLenum texture, GLenum type, GLuint coords);
2164GLAPI PFNGLMULTITEXCOORDP4UIPROC glad_glMultiTexCoordP4ui; 2164GLAPI PFNGLMULTITEXCOORDP4UIPROC glad_glMultiTexCoordP4ui;
2165#define glMultiTexCoordP4ui glad_glMultiTexCoordP4ui 2165#define glMultiTexCoordP4ui glad_glMultiTexCoordP4ui
2166typedef void (APIENTRYP PFNGLMULTITEXCOORDP4UIVPROC)(GLenum, GLenum, const GLuint*); 2166typedef void (APIENTRYP PFNGLMULTITEXCOORDP4UIVPROC)(GLenum texture, GLenum type, const GLuint* coords);
2167GLAPI PFNGLMULTITEXCOORDP4UIVPROC glad_glMultiTexCoordP4uiv; 2167GLAPI PFNGLMULTITEXCOORDP4UIVPROC glad_glMultiTexCoordP4uiv;
2168#define glMultiTexCoordP4uiv glad_glMultiTexCoordP4uiv 2168#define glMultiTexCoordP4uiv glad_glMultiTexCoordP4uiv
2169typedef void (APIENTRYP PFNGLNORMALP3UIPROC)(GLenum, GLuint); 2169typedef void (APIENTRYP PFNGLNORMALP3UIPROC)(GLenum type, GLuint coords);
2170GLAPI PFNGLNORMALP3UIPROC glad_glNormalP3ui; 2170GLAPI PFNGLNORMALP3UIPROC glad_glNormalP3ui;
2171#define glNormalP3ui glad_glNormalP3ui 2171#define glNormalP3ui glad_glNormalP3ui
2172typedef void (APIENTRYP PFNGLNORMALP3UIVPROC)(GLenum, const GLuint*); 2172typedef void (APIENTRYP PFNGLNORMALP3UIVPROC)(GLenum type, const GLuint* coords);
2173GLAPI PFNGLNORMALP3UIVPROC glad_glNormalP3uiv; 2173GLAPI PFNGLNORMALP3UIVPROC glad_glNormalP3uiv;
2174#define glNormalP3uiv glad_glNormalP3uiv 2174#define glNormalP3uiv glad_glNormalP3uiv
2175typedef void (APIENTRYP PFNGLCOLORP3UIPROC)(GLenum, GLuint); 2175typedef void (APIENTRYP PFNGLCOLORP3UIPROC)(GLenum type, GLuint color);
2176GLAPI PFNGLCOLORP3UIPROC glad_glColorP3ui; 2176GLAPI PFNGLCOLORP3UIPROC glad_glColorP3ui;
2177#define glColorP3ui glad_glColorP3ui 2177#define glColorP3ui glad_glColorP3ui
2178typedef void (APIENTRYP PFNGLCOLORP3UIVPROC)(GLenum, const GLuint*); 2178typedef void (APIENTRYP PFNGLCOLORP3UIVPROC)(GLenum type, const GLuint* color);
2179GLAPI PFNGLCOLORP3UIVPROC glad_glColorP3uiv; 2179GLAPI PFNGLCOLORP3UIVPROC glad_glColorP3uiv;
2180#define glColorP3uiv glad_glColorP3uiv 2180#define glColorP3uiv glad_glColorP3uiv
2181typedef void (APIENTRYP PFNGLCOLORP4UIPROC)(GLenum, GLuint); 2181typedef void (APIENTRYP PFNGLCOLORP4UIPROC)(GLenum type, GLuint color);
2182GLAPI PFNGLCOLORP4UIPROC glad_glColorP4ui; 2182GLAPI PFNGLCOLORP4UIPROC glad_glColorP4ui;
2183#define glColorP4ui glad_glColorP4ui 2183#define glColorP4ui glad_glColorP4ui
2184typedef void (APIENTRYP PFNGLCOLORP4UIVPROC)(GLenum, const GLuint*); 2184typedef void (APIENTRYP PFNGLCOLORP4UIVPROC)(GLenum type, const GLuint* color);
2185GLAPI PFNGLCOLORP4UIVPROC glad_glColorP4uiv; 2185GLAPI PFNGLCOLORP4UIVPROC glad_glColorP4uiv;
2186#define glColorP4uiv glad_glColorP4uiv 2186#define glColorP4uiv glad_glColorP4uiv
2187typedef void (APIENTRYP PFNGLSECONDARYCOLORP3UIPROC)(GLenum, GLuint); 2187typedef void (APIENTRYP PFNGLSECONDARYCOLORP3UIPROC)(GLenum type, GLuint color);
2188GLAPI PFNGLSECONDARYCOLORP3UIPROC glad_glSecondaryColorP3ui; 2188GLAPI PFNGLSECONDARYCOLORP3UIPROC glad_glSecondaryColorP3ui;
2189#define glSecondaryColorP3ui glad_glSecondaryColorP3ui 2189#define glSecondaryColorP3ui glad_glSecondaryColorP3ui
2190typedef void (APIENTRYP PFNGLSECONDARYCOLORP3UIVPROC)(GLenum, const GLuint*); 2190typedef void (APIENTRYP PFNGLSECONDARYCOLORP3UIVPROC)(GLenum type, const GLuint* color);
2191GLAPI PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv; 2191GLAPI PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv;
2192#define glSecondaryColorP3uiv glad_glSecondaryColorP3uiv 2192#define glSecondaryColorP3uiv glad_glSecondaryColorP3uiv
2193#endif 2193#endif
2194#ifndef GL_ES_VERSION_2_0 2194#ifndef GL_ES_VERSION_2_0
2195#define GL_ES_VERSION_2_0 1 2195#define GL_ES_VERSION_2_0 1
2196GLAPI int GLAD_GL_ES_VERSION_2_0; 2196GLAPI int GLAD_GL_ES_VERSION_2_0;
2197typedef void (APIENTRYP PFNGLCLEARDEPTHFPROC)(GLfloat); 2197typedef void (APIENTRYP PFNGLCLEARDEPTHFPROC)(GLfloat d);
2198GLAPI PFNGLCLEARDEPTHFPROC glad_glClearDepthf; 2198GLAPI PFNGLCLEARDEPTHFPROC glad_glClearDepthf;
2199#define glClearDepthf glad_glClearDepthf 2199#define glClearDepthf glad_glClearDepthf
2200typedef void (APIENTRYP PFNGLDEPTHRANGEFPROC)(GLfloat, GLfloat); 2200typedef void (APIENTRYP PFNGLDEPTHRANGEFPROC)(GLfloat n, GLfloat f);
2201GLAPI PFNGLDEPTHRANGEFPROC glad_glDepthRangef; 2201GLAPI PFNGLDEPTHRANGEFPROC glad_glDepthRangef;
2202#define glDepthRangef glad_glDepthRangef 2202#define glDepthRangef glad_glDepthRangef
2203typedef void (APIENTRYP PFNGLGETSHADERPRECISIONFORMATPROC)(GLenum, GLenum, GLint*, GLint*); 2203typedef void (APIENTRYP PFNGLGETSHADERPRECISIONFORMATPROC)(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
2204GLAPI PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat; 2204GLAPI PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat;
2205#define glGetShaderPrecisionFormat glad_glGetShaderPrecisionFormat 2205#define glGetShaderPrecisionFormat glad_glGetShaderPrecisionFormat
2206typedef void (APIENTRYP PFNGLRELEASESHADERCOMPILERPROC)(); 2206typedef void (APIENTRYP PFNGLRELEASESHADERCOMPILERPROC)();
2207GLAPI PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler; 2207GLAPI PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler;
2208#define glReleaseShaderCompiler glad_glReleaseShaderCompiler 2208#define glReleaseShaderCompiler glad_glReleaseShaderCompiler
2209typedef void (APIENTRYP PFNGLSHADERBINARYPROC)(GLsizei, const GLuint*, GLenum, const void*, GLsizei); 2209typedef void (APIENTRYP PFNGLSHADERBINARYPROC)(GLsizei count, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length);
2210GLAPI PFNGLSHADERBINARYPROC glad_glShaderBinary; 2210GLAPI PFNGLSHADERBINARYPROC glad_glShaderBinary;
2211#define glShaderBinary glad_glShaderBinary 2211#define glShaderBinary glad_glShaderBinary
2212#endif 2212#endif
2213#ifndef GL_ES_VERSION_3_0 2213#ifndef GL_ES_VERSION_3_0
2214#define GL_ES_VERSION_3_0 1 2214#define GL_ES_VERSION_3_0 1
2215GLAPI int GLAD_GL_ES_VERSION_3_0; 2215GLAPI int GLAD_GL_ES_VERSION_3_0;
2216typedef void (APIENTRYP PFNGLBINDTRANSFORMFEEDBACKPROC)(GLenum, GLuint); 2216typedef void (APIENTRYP PFNGLBINDTRANSFORMFEEDBACKPROC)(GLenum target, GLuint id);
2217GLAPI PFNGLBINDTRANSFORMFEEDBACKPROC glad_glBindTransformFeedback; 2217GLAPI PFNGLBINDTRANSFORMFEEDBACKPROC glad_glBindTransformFeedback;
2218#define glBindTransformFeedback glad_glBindTransformFeedback 2218#define glBindTransformFeedback glad_glBindTransformFeedback
2219typedef void (APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSPROC)(GLsizei, const GLuint*); 2219typedef void (APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSPROC)(GLsizei n, const GLuint* ids);
2220GLAPI PFNGLDELETETRANSFORMFEEDBACKSPROC glad_glDeleteTransformFeedbacks; 2220GLAPI PFNGLDELETETRANSFORMFEEDBACKSPROC glad_glDeleteTransformFeedbacks;
2221#define glDeleteTransformFeedbacks glad_glDeleteTransformFeedbacks 2221#define glDeleteTransformFeedbacks glad_glDeleteTransformFeedbacks
2222typedef void (APIENTRYP PFNGLGENTRANSFORMFEEDBACKSPROC)(GLsizei, GLuint*); 2222typedef void (APIENTRYP PFNGLGENTRANSFORMFEEDBACKSPROC)(GLsizei n, GLuint* ids);
2223GLAPI PFNGLGENTRANSFORMFEEDBACKSPROC glad_glGenTransformFeedbacks; 2223GLAPI PFNGLGENTRANSFORMFEEDBACKSPROC glad_glGenTransformFeedbacks;
2224#define glGenTransformFeedbacks glad_glGenTransformFeedbacks 2224#define glGenTransformFeedbacks glad_glGenTransformFeedbacks
2225typedef GLboolean (APIENTRYP PFNGLISTRANSFORMFEEDBACKPROC)(GLuint); 2225typedef GLboolean (APIENTRYP PFNGLISTRANSFORMFEEDBACKPROC)(GLuint id);
2226GLAPI PFNGLISTRANSFORMFEEDBACKPROC glad_glIsTransformFeedback; 2226GLAPI PFNGLISTRANSFORMFEEDBACKPROC glad_glIsTransformFeedback;
2227#define glIsTransformFeedback glad_glIsTransformFeedback 2227#define glIsTransformFeedback glad_glIsTransformFeedback
2228typedef void (APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKPROC)(); 2228typedef void (APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKPROC)();
@@ -2231,31 +2231,186 @@ GLAPI PFNGLPAUSETRANSFORMFEEDBACKPROC glad_glPauseTransformFeedback;
2231typedef void (APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKPROC)(); 2231typedef void (APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKPROC)();
2232GLAPI PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback; 2232GLAPI PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback;
2233#define glResumeTransformFeedback glad_glResumeTransformFeedback 2233#define glResumeTransformFeedback glad_glResumeTransformFeedback
2234typedef void (APIENTRYP PFNGLGETPROGRAMBINARYPROC)(GLuint, GLsizei, GLsizei*, GLenum*, void*); 2234typedef void (APIENTRYP PFNGLGETPROGRAMBINARYPROC)(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, void* binary);
2235GLAPI PFNGLGETPROGRAMBINARYPROC glad_glGetProgramBinary; 2235GLAPI PFNGLGETPROGRAMBINARYPROC glad_glGetProgramBinary;
2236#define glGetProgramBinary glad_glGetProgramBinary 2236#define glGetProgramBinary glad_glGetProgramBinary
2237typedef void (APIENTRYP PFNGLPROGRAMBINARYPROC)(GLuint, GLenum, const void*, GLsizei); 2237typedef void (APIENTRYP PFNGLPROGRAMBINARYPROC)(GLuint program, GLenum binaryFormat, const void* binary, GLsizei length);
2238GLAPI PFNGLPROGRAMBINARYPROC glad_glProgramBinary; 2238GLAPI PFNGLPROGRAMBINARYPROC glad_glProgramBinary;
2239#define glProgramBinary glad_glProgramBinary 2239#define glProgramBinary glad_glProgramBinary
2240typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIPROC)(GLuint, GLenum, GLint); 2240typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIPROC)(GLuint program, GLenum pname, GLint value);
2241GLAPI PFNGLPROGRAMPARAMETERIPROC glad_glProgramParameteri; 2241GLAPI PFNGLPROGRAMPARAMETERIPROC glad_glProgramParameteri;
2242#define glProgramParameteri glad_glProgramParameteri 2242#define glProgramParameteri glad_glProgramParameteri
2243typedef void (APIENTRYP PFNGLINVALIDATEFRAMEBUFFERPROC)(GLenum, GLsizei, const GLenum*); 2243typedef void (APIENTRYP PFNGLINVALIDATEFRAMEBUFFERPROC)(GLenum target, GLsizei numAttachments, const GLenum* attachments);
2244GLAPI PFNGLINVALIDATEFRAMEBUFFERPROC glad_glInvalidateFramebuffer; 2244GLAPI PFNGLINVALIDATEFRAMEBUFFERPROC glad_glInvalidateFramebuffer;
2245#define glInvalidateFramebuffer glad_glInvalidateFramebuffer 2245#define glInvalidateFramebuffer glad_glInvalidateFramebuffer
2246typedef void (APIENTRYP PFNGLINVALIDATESUBFRAMEBUFFERPROC)(GLenum, GLsizei, const GLenum*, GLint, GLint, GLsizei, GLsizei); 2246typedef void (APIENTRYP PFNGLINVALIDATESUBFRAMEBUFFERPROC)(GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height);
2247GLAPI PFNGLINVALIDATESUBFRAMEBUFFERPROC glad_glInvalidateSubFramebuffer; 2247GLAPI PFNGLINVALIDATESUBFRAMEBUFFERPROC glad_glInvalidateSubFramebuffer;
2248#define glInvalidateSubFramebuffer glad_glInvalidateSubFramebuffer 2248#define glInvalidateSubFramebuffer glad_glInvalidateSubFramebuffer
2249typedef void (APIENTRYP PFNGLTEXSTORAGE2DPROC)(GLenum, GLsizei, GLenum, GLsizei, GLsizei); 2249typedef void (APIENTRYP PFNGLTEXSTORAGE2DPROC)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
2250GLAPI PFNGLTEXSTORAGE2DPROC glad_glTexStorage2D; 2250GLAPI PFNGLTEXSTORAGE2DPROC glad_glTexStorage2D;
2251#define glTexStorage2D glad_glTexStorage2D 2251#define glTexStorage2D glad_glTexStorage2D
2252typedef void (APIENTRYP PFNGLTEXSTORAGE3DPROC)(GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLsizei); 2252typedef void (APIENTRYP PFNGLTEXSTORAGE3DPROC)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
2253GLAPI PFNGLTEXSTORAGE3DPROC glad_glTexStorage3D; 2253GLAPI PFNGLTEXSTORAGE3DPROC glad_glTexStorage3D;
2254#define glTexStorage3D glad_glTexStorage3D 2254#define glTexStorage3D glad_glTexStorage3D
2255typedef void (APIENTRYP PFNGLGETINTERNALFORMATIVPROC)(GLenum, GLenum, GLenum, GLsizei, GLint*); 2255typedef void (APIENTRYP PFNGLGETINTERNALFORMATIVPROC)(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params);
2256GLAPI PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ; 2256GLAPI PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ;
2257#define glGetInternalformativ glad_glGetInternalformativ 2257#define glGetInternalformativ glad_glGetInternalformativ
2258#endif 2258#endif
2259#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242
2260#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243
2261#define GL_DEBUG_CALLBACK_FUNCTION 0x8244
2262#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245
2263#define GL_DEBUG_SOURCE_API 0x8246
2264#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247
2265#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248
2266#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249
2267#define GL_DEBUG_SOURCE_APPLICATION 0x824A
2268#define GL_DEBUG_SOURCE_OTHER 0x824B
2269#define GL_DEBUG_TYPE_ERROR 0x824C
2270#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D
2271#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E
2272#define GL_DEBUG_TYPE_PORTABILITY 0x824F
2273#define GL_DEBUG_TYPE_PERFORMANCE 0x8250
2274#define GL_DEBUG_TYPE_OTHER 0x8251
2275#define GL_DEBUG_TYPE_MARKER 0x8268
2276#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269
2277#define GL_DEBUG_TYPE_POP_GROUP 0x826A
2278#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B
2279#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C
2280#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D
2281#define GL_BUFFER 0x82E0
2282#define GL_SHADER 0x82E1
2283#define GL_PROGRAM 0x82E2
2284#define GL_VERTEX_ARRAY 0x8074
2285#define GL_QUERY 0x82E3
2286#define GL_PROGRAM_PIPELINE 0x82E4
2287#define GL_SAMPLER 0x82E6
2288#define GL_MAX_LABEL_LENGTH 0x82E8
2289#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143
2290#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144
2291#define GL_DEBUG_LOGGED_MESSAGES 0x9145
2292#define GL_DEBUG_SEVERITY_HIGH 0x9146
2293#define GL_DEBUG_SEVERITY_MEDIUM 0x9147
2294#define GL_DEBUG_SEVERITY_LOW 0x9148
2295#define GL_DEBUG_OUTPUT 0x92E0
2296#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002
2297#define GL_STACK_OVERFLOW 0x0503
2298#define GL_STACK_UNDERFLOW 0x0504
2299#define GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR 0x8242
2300#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_KHR 0x8243
2301#define GL_DEBUG_CALLBACK_FUNCTION_KHR 0x8244
2302#define GL_DEBUG_CALLBACK_USER_PARAM_KHR 0x8245
2303#define GL_DEBUG_SOURCE_API_KHR 0x8246
2304#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_KHR 0x8247
2305#define GL_DEBUG_SOURCE_SHADER_COMPILER_KHR 0x8248
2306#define GL_DEBUG_SOURCE_THIRD_PARTY_KHR 0x8249
2307#define GL_DEBUG_SOURCE_APPLICATION_KHR 0x824A
2308#define GL_DEBUG_SOURCE_OTHER_KHR 0x824B
2309#define GL_DEBUG_TYPE_ERROR_KHR 0x824C
2310#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR 0x824D
2311#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR 0x824E
2312#define GL_DEBUG_TYPE_PORTABILITY_KHR 0x824F
2313#define GL_DEBUG_TYPE_PERFORMANCE_KHR 0x8250
2314#define GL_DEBUG_TYPE_OTHER_KHR 0x8251
2315#define GL_DEBUG_TYPE_MARKER_KHR 0x8268
2316#define GL_DEBUG_TYPE_PUSH_GROUP_KHR 0x8269
2317#define GL_DEBUG_TYPE_POP_GROUP_KHR 0x826A
2318#define GL_DEBUG_SEVERITY_NOTIFICATION_KHR 0x826B
2319#define GL_MAX_DEBUG_GROUP_STACK_DEPTH_KHR 0x826C
2320#define GL_DEBUG_GROUP_STACK_DEPTH_KHR 0x826D
2321#define GL_BUFFER_KHR 0x82E0
2322#define GL_SHADER_KHR 0x82E1
2323#define GL_PROGRAM_KHR 0x82E2
2324#define GL_VERTEX_ARRAY_KHR 0x8074
2325#define GL_QUERY_KHR 0x82E3
2326#define GL_PROGRAM_PIPELINE_KHR 0x82E4
2327#define GL_SAMPLER_KHR 0x82E6
2328#define GL_MAX_LABEL_LENGTH_KHR 0x82E8
2329#define GL_MAX_DEBUG_MESSAGE_LENGTH_KHR 0x9143
2330#define GL_MAX_DEBUG_LOGGED_MESSAGES_KHR 0x9144
2331#define GL_DEBUG_LOGGED_MESSAGES_KHR 0x9145
2332#define GL_DEBUG_SEVERITY_HIGH_KHR 0x9146
2333#define GL_DEBUG_SEVERITY_MEDIUM_KHR 0x9147
2334#define GL_DEBUG_SEVERITY_LOW_KHR 0x9148
2335#define GL_DEBUG_OUTPUT_KHR 0x92E0
2336#define GL_CONTEXT_FLAG_DEBUG_BIT_KHR 0x00000002
2337#define GL_STACK_OVERFLOW_KHR 0x0503
2338#define GL_STACK_UNDERFLOW_KHR 0x0504
2339#define GL_DISPLAY_LIST 0x82E7
2340#ifndef GL_KHR_debug
2341#define GL_KHR_debug 1
2342GLAPI int GLAD_GL_KHR_debug;
2343typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLPROC)(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled);
2344GLAPI PFNGLDEBUGMESSAGECONTROLPROC glad_glDebugMessageControl;
2345#define glDebugMessageControl glad_glDebugMessageControl
2346typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* buf);
2347GLAPI PFNGLDEBUGMESSAGEINSERTPROC glad_glDebugMessageInsert;
2348#define glDebugMessageInsert glad_glDebugMessageInsert
2349typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKPROC)(GLDEBUGPROC callback, const void* userParam);
2350GLAPI PFNGLDEBUGMESSAGECALLBACKPROC glad_glDebugMessageCallback;
2351#define glDebugMessageCallback glad_glDebugMessageCallback
2352typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGPROC)(GLuint count, GLsizei bufSize, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, GLchar* messageLog);
2353GLAPI PFNGLGETDEBUGMESSAGELOGPROC glad_glGetDebugMessageLog;
2354#define glGetDebugMessageLog glad_glGetDebugMessageLog
2355typedef void (APIENTRYP PFNGLPUSHDEBUGGROUPPROC)(GLenum source, GLuint id, GLsizei length, const GLchar* message);
2356GLAPI PFNGLPUSHDEBUGGROUPPROC glad_glPushDebugGroup;
2357#define glPushDebugGroup glad_glPushDebugGroup
2358typedef void (APIENTRYP PFNGLPOPDEBUGGROUPPROC)();
2359GLAPI PFNGLPOPDEBUGGROUPPROC glad_glPopDebugGroup;
2360#define glPopDebugGroup glad_glPopDebugGroup
2361typedef void (APIENTRYP PFNGLOBJECTLABELPROC)(GLenum identifier, GLuint name, GLsizei length, const GLchar* label);
2362GLAPI PFNGLOBJECTLABELPROC glad_glObjectLabel;
2363#define glObjectLabel glad_glObjectLabel
2364typedef void (APIENTRYP PFNGLGETOBJECTLABELPROC)(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei* length, GLchar* label);
2365GLAPI PFNGLGETOBJECTLABELPROC glad_glGetObjectLabel;
2366#define glGetObjectLabel glad_glGetObjectLabel
2367typedef void (APIENTRYP PFNGLOBJECTPTRLABELPROC)(const void* ptr, GLsizei length, const GLchar* label);
2368GLAPI PFNGLOBJECTPTRLABELPROC glad_glObjectPtrLabel;
2369#define glObjectPtrLabel glad_glObjectPtrLabel
2370typedef void (APIENTRYP PFNGLGETOBJECTPTRLABELPROC)(const void* ptr, GLsizei bufSize, GLsizei* length, GLchar* label);
2371GLAPI PFNGLGETOBJECTPTRLABELPROC glad_glGetObjectPtrLabel;
2372#define glGetObjectPtrLabel glad_glGetObjectPtrLabel
2373typedef void (APIENTRYP PFNGLGETPOINTERVPROC)(GLenum pname, void** params);
2374GLAPI PFNGLGETPOINTERVPROC glad_glGetPointerv;
2375#define glGetPointerv glad_glGetPointerv
2376typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLKHRPROC)(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled);
2377GLAPI PFNGLDEBUGMESSAGECONTROLKHRPROC glad_glDebugMessageControlKHR;
2378#define glDebugMessageControlKHR glad_glDebugMessageControlKHR
2379typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTKHRPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* buf);
2380GLAPI PFNGLDEBUGMESSAGEINSERTKHRPROC glad_glDebugMessageInsertKHR;
2381#define glDebugMessageInsertKHR glad_glDebugMessageInsertKHR
2382typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKKHRPROC)(GLDEBUGPROCKHR callback, const void* userParam);
2383GLAPI PFNGLDEBUGMESSAGECALLBACKKHRPROC glad_glDebugMessageCallbackKHR;
2384#define glDebugMessageCallbackKHR glad_glDebugMessageCallbackKHR
2385typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGKHRPROC)(GLuint count, GLsizei bufSize, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, GLchar* messageLog);
2386GLAPI PFNGLGETDEBUGMESSAGELOGKHRPROC glad_glGetDebugMessageLogKHR;
2387#define glGetDebugMessageLogKHR glad_glGetDebugMessageLogKHR
2388typedef void (APIENTRYP PFNGLPUSHDEBUGGROUPKHRPROC)(GLenum source, GLuint id, GLsizei length, const GLchar* message);
2389GLAPI PFNGLPUSHDEBUGGROUPKHRPROC glad_glPushDebugGroupKHR;
2390#define glPushDebugGroupKHR glad_glPushDebugGroupKHR
2391typedef void (APIENTRYP PFNGLPOPDEBUGGROUPKHRPROC)();
2392GLAPI PFNGLPOPDEBUGGROUPKHRPROC glad_glPopDebugGroupKHR;
2393#define glPopDebugGroupKHR glad_glPopDebugGroupKHR
2394typedef void (APIENTRYP PFNGLOBJECTLABELKHRPROC)(GLenum identifier, GLuint name, GLsizei length, const GLchar* label);
2395GLAPI PFNGLOBJECTLABELKHRPROC glad_glObjectLabelKHR;
2396#define glObjectLabelKHR glad_glObjectLabelKHR
2397typedef void (APIENTRYP PFNGLGETOBJECTLABELKHRPROC)(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei* length, GLchar* label);
2398GLAPI PFNGLGETOBJECTLABELKHRPROC glad_glGetObjectLabelKHR;
2399#define glGetObjectLabelKHR glad_glGetObjectLabelKHR
2400typedef void (APIENTRYP PFNGLOBJECTPTRLABELKHRPROC)(const void* ptr, GLsizei length, const GLchar* label);
2401GLAPI PFNGLOBJECTPTRLABELKHRPROC glad_glObjectPtrLabelKHR;
2402#define glObjectPtrLabelKHR glad_glObjectPtrLabelKHR
2403typedef void (APIENTRYP PFNGLGETOBJECTPTRLABELKHRPROC)(const void* ptr, GLsizei bufSize, GLsizei* length, GLchar* label);
2404GLAPI PFNGLGETOBJECTPTRLABELKHRPROC glad_glGetObjectPtrLabelKHR;
2405#define glGetObjectPtrLabelKHR glad_glGetObjectPtrLabelKHR
2406typedef void (APIENTRYP PFNGLGETPOINTERVKHRPROC)(GLenum pname, void** params);
2407GLAPI PFNGLGETPOINTERVKHRPROC glad_glGetPointervKHR;
2408#define glGetPointervKHR glad_glGetPointervKHR
2409#endif
2410#ifndef GL_KHR_debug
2411#define GL_KHR_debug 1
2412GLAPI int GLAD_GL_KHR_debug;
2413#endif
2259 2414
2260#ifdef __cplusplus 2415#ifdef __cplusplus
2261} 2416}
diff --git a/externals/glad/src/glad.c b/externals/glad/src/glad.c
index 014b54383..6af737acc 100644
--- a/externals/glad/src/glad.c
+++ b/externals/glad/src/glad.c
@@ -595,6 +595,29 @@ PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex;
595PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample; 595PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample;
596PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform; 596PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform;
597PFNGLFRONTFACEPROC glad_glFrontFace; 597PFNGLFRONTFACEPROC glad_glFrontFace;
598int GLAD_GL_KHR_debug;
599PFNGLDEBUGMESSAGECONTROLPROC glad_glDebugMessageControl;
600PFNGLDEBUGMESSAGEINSERTPROC glad_glDebugMessageInsert;
601PFNGLDEBUGMESSAGECALLBACKPROC glad_glDebugMessageCallback;
602PFNGLGETDEBUGMESSAGELOGPROC glad_glGetDebugMessageLog;
603PFNGLPUSHDEBUGGROUPPROC glad_glPushDebugGroup;
604PFNGLPOPDEBUGGROUPPROC glad_glPopDebugGroup;
605PFNGLOBJECTLABELPROC glad_glObjectLabel;
606PFNGLGETOBJECTLABELPROC glad_glGetObjectLabel;
607PFNGLOBJECTPTRLABELPROC glad_glObjectPtrLabel;
608PFNGLGETOBJECTPTRLABELPROC glad_glGetObjectPtrLabel;
609PFNGLGETPOINTERVPROC glad_glGetPointerv;
610PFNGLDEBUGMESSAGECONTROLKHRPROC glad_glDebugMessageControlKHR;
611PFNGLDEBUGMESSAGEINSERTKHRPROC glad_glDebugMessageInsertKHR;
612PFNGLDEBUGMESSAGECALLBACKKHRPROC glad_glDebugMessageCallbackKHR;
613PFNGLGETDEBUGMESSAGELOGKHRPROC glad_glGetDebugMessageLogKHR;
614PFNGLPUSHDEBUGGROUPKHRPROC glad_glPushDebugGroupKHR;
615PFNGLPOPDEBUGGROUPKHRPROC glad_glPopDebugGroupKHR;
616PFNGLOBJECTLABELKHRPROC glad_glObjectLabelKHR;
617PFNGLGETOBJECTLABELKHRPROC glad_glGetObjectLabelKHR;
618PFNGLOBJECTPTRLABELKHRPROC glad_glObjectPtrLabelKHR;
619PFNGLGETOBJECTPTRLABELKHRPROC glad_glGetObjectPtrLabelKHR;
620PFNGLGETPOINTERVKHRPROC glad_glGetPointervKHR;
598static void load_GL_VERSION_1_0(GLADloadproc load) { 621static void load_GL_VERSION_1_0(GLADloadproc load) {
599 if(!GLAD_GL_VERSION_1_0) return; 622 if(!GLAD_GL_VERSION_1_0) return;
600 glad_glCullFace = (PFNGLCULLFACEPROC)load("glCullFace"); 623 glad_glCullFace = (PFNGLCULLFACEPROC)load("glCullFace");
@@ -1008,8 +1031,34 @@ static void load_GL_VERSION_3_3(GLADloadproc load) {
1008 glad_glSecondaryColorP3ui = (PFNGLSECONDARYCOLORP3UIPROC)load("glSecondaryColorP3ui"); 1031 glad_glSecondaryColorP3ui = (PFNGLSECONDARYCOLORP3UIPROC)load("glSecondaryColorP3ui");
1009 glad_glSecondaryColorP3uiv = (PFNGLSECONDARYCOLORP3UIVPROC)load("glSecondaryColorP3uiv"); 1032 glad_glSecondaryColorP3uiv = (PFNGLSECONDARYCOLORP3UIVPROC)load("glSecondaryColorP3uiv");
1010} 1033}
1034static void load_GL_KHR_debug(GLADloadproc load) {
1035 if(!GLAD_GL_KHR_debug) return;
1036 glad_glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC)load("glDebugMessageControl");
1037 glad_glDebugMessageInsert = (PFNGLDEBUGMESSAGEINSERTPROC)load("glDebugMessageInsert");
1038 glad_glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC)load("glDebugMessageCallback");
1039 glad_glGetDebugMessageLog = (PFNGLGETDEBUGMESSAGELOGPROC)load("glGetDebugMessageLog");
1040 glad_glPushDebugGroup = (PFNGLPUSHDEBUGGROUPPROC)load("glPushDebugGroup");
1041 glad_glPopDebugGroup = (PFNGLPOPDEBUGGROUPPROC)load("glPopDebugGroup");
1042 glad_glObjectLabel = (PFNGLOBJECTLABELPROC)load("glObjectLabel");
1043 glad_glGetObjectLabel = (PFNGLGETOBJECTLABELPROC)load("glGetObjectLabel");
1044 glad_glObjectPtrLabel = (PFNGLOBJECTPTRLABELPROC)load("glObjectPtrLabel");
1045 glad_glGetObjectPtrLabel = (PFNGLGETOBJECTPTRLABELPROC)load("glGetObjectPtrLabel");
1046 glad_glGetPointerv = (PFNGLGETPOINTERVPROC)load("glGetPointerv");
1047 glad_glDebugMessageControlKHR = (PFNGLDEBUGMESSAGECONTROLKHRPROC)load("glDebugMessageControlKHR");
1048 glad_glDebugMessageInsertKHR = (PFNGLDEBUGMESSAGEINSERTKHRPROC)load("glDebugMessageInsertKHR");
1049 glad_glDebugMessageCallbackKHR = (PFNGLDEBUGMESSAGECALLBACKKHRPROC)load("glDebugMessageCallbackKHR");
1050 glad_glGetDebugMessageLogKHR = (PFNGLGETDEBUGMESSAGELOGKHRPROC)load("glGetDebugMessageLogKHR");
1051 glad_glPushDebugGroupKHR = (PFNGLPUSHDEBUGGROUPKHRPROC)load("glPushDebugGroupKHR");
1052 glad_glPopDebugGroupKHR = (PFNGLPOPDEBUGGROUPKHRPROC)load("glPopDebugGroupKHR");
1053 glad_glObjectLabelKHR = (PFNGLOBJECTLABELKHRPROC)load("glObjectLabelKHR");
1054 glad_glGetObjectLabelKHR = (PFNGLGETOBJECTLABELKHRPROC)load("glGetObjectLabelKHR");
1055 glad_glObjectPtrLabelKHR = (PFNGLOBJECTPTRLABELKHRPROC)load("glObjectPtrLabelKHR");
1056 glad_glGetObjectPtrLabelKHR = (PFNGLGETOBJECTPTRLABELKHRPROC)load("glGetObjectPtrLabelKHR");
1057 glad_glGetPointervKHR = (PFNGLGETPOINTERVKHRPROC)load("glGetPointervKHR");
1058}
1011static void find_extensionsGL(void) { 1059static void find_extensionsGL(void) {
1012 get_exts(); 1060 get_exts();
1061 GLAD_GL_KHR_debug = has_ext("GL_KHR_debug");
1013} 1062}
1014 1063
1015static void find_coreGL(void) { 1064static void find_coreGL(void) {
@@ -1086,6 +1135,7 @@ int gladLoadGLLoader(GLADloadproc load) {
1086 load_GL_VERSION_3_3(load); 1135 load_GL_VERSION_3_3(load);
1087 1136
1088 find_extensionsGL(); 1137 find_extensionsGL();
1138 load_GL_KHR_debug(load);
1089 return GLVersion.major != 0 || GLVersion.minor != 0; 1139 return GLVersion.major != 0 || GLVersion.minor != 0;
1090} 1140}
1091 1141
@@ -1343,6 +1393,7 @@ static void load_GL_ES_VERSION_3_0(GLADloadproc load) {
1343} 1393}
1344static void find_extensionsGLES2(void) { 1394static void find_extensionsGLES2(void) {
1345 get_exts(); 1395 get_exts();
1396 GLAD_GL_KHR_debug = has_ext("GL_KHR_debug");
1346} 1397}
1347 1398
1348static void find_coreGLES2(void) { 1399static void find_coreGLES2(void) {
@@ -1399,6 +1450,7 @@ int gladLoadGLES2Loader(GLADloadproc load) {
1399 load_GL_ES_VERSION_3_0(load); 1450 load_GL_ES_VERSION_3_0(load);
1400 1451
1401 find_extensionsGLES2(); 1452 find_extensionsGLES2();
1453 load_GL_KHR_debug(load);
1402 return GLVersion.major != 0 || GLVersion.minor != 0; 1454 return GLVersion.major != 0 || GLVersion.minor != 0;
1403} 1455}
1404 1456
diff --git a/externals/glfw-3.1.1.bin/COPYING.txt b/externals/glfw-3.1.1.bin/COPYING.txt
deleted file mode 100644
index b30c70158..000000000
--- a/externals/glfw-3.1.1.bin/COPYING.txt
+++ /dev/null
@@ -1,22 +0,0 @@
1Copyright (c) 2002-2006 Marcus Geelnard
2Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
3
4This software is provided 'as-is', without any express or implied
5warranty. In no event will the authors be held liable for any damages
6arising from the use of this software.
7
8Permission is granted to anyone to use this software for any purpose,
9including commercial applications, and to alter it and redistribute it
10freely, subject to the following restrictions:
11
121. The origin of this software must not be misrepresented; you must not
13 claim that you wrote the original software. If you use this software
14 in a product, an acknowledgment in the product documentation would
15 be appreciated but is not required.
16
172. Altered source versions must be plainly marked as such, and must not
18 be misrepresented as being the original software.
19
203. This notice may not be removed or altered from any source
21 distribution.
22
diff --git a/externals/glfw-3.1.1.bin/include/GLFW/glfw3.h b/externals/glfw-3.1.1.bin/include/GLFW/glfw3.h
deleted file mode 100644
index 009fa755f..000000000
--- a/externals/glfw-3.1.1.bin/include/GLFW/glfw3.h
+++ /dev/null
@@ -1,3340 +0,0 @@
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_h_
30#define _glfw3_h_
31
32#ifdef __cplusplus
33extern "C" {
34#endif
35
36
37/*************************************************************************
38 * Doxygen documentation
39 *************************************************************************/
40
41/*! @defgroup context Context handling
42 *
43 * This is the reference documentation for context related functions. For more
44 * information, see the @ref context.
45 */
46/*! @defgroup init Initialization, version and errors
47 *
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.
51 */
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.
56 */
57/*! @defgroup monitor Monitor handling
58 *
59 * This is the reference documentation for monitor related functions and types.
60 * For more information, see the @ref monitor.
61 */
62/*! @defgroup window Window handling
63 *
64 * This is the reference documentation for window related functions and types,
65 * including creation, deletion and event polling. For more information, see
66 * the @ref window.
67 */
68
69
70/*************************************************************************
71 * Compiler- and platform-specific preprocessor work
72 *************************************************************************/
73
74/* If we are we on Windows, we want a single define for it.
75 */
76#if !defined(_WIN32) && (defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__))
77 #define _WIN32
78#endif /* _WIN32 */
79
80/* It is customary to use APIENTRY for OpenGL function pointer declarations on
81 * all platforms. Additionally, the Windows OpenGL header needs APIENTRY.
82 */
83#ifndef APIENTRY
84 #ifdef _WIN32
85 #define APIENTRY __stdcall
86 #else
87 #define APIENTRY
88 #endif
89#endif /* APIENTRY */
90
91/* Some Windows OpenGL headers need this.
92 */
93#if !defined(WINGDIAPI) && defined(_WIN32)
94 #define WINGDIAPI __declspec(dllimport)
95 #define GLFW_WINGDIAPI_DEFINED
96#endif /* WINGDIAPI */
97
98/* Some Windows GLU headers need this.
99 */
100#if !defined(CALLBACK) && defined(_WIN32)
101 #define CALLBACK __stdcall
102 #define GLFW_CALLBACK_DEFINED
103#endif /* CALLBACK */
104
105/* Most Windows GLU headers need wchar_t.
106 * The OS X OpenGL header blocks the definition of ptrdiff_t by glext.h.
107 */
108#if !defined(GLFW_INCLUDE_NONE)
109 #include <stddef.h>
110#endif
111
112/* Include the chosen client API headers.
113 */
114#if defined(__APPLE_CC__)
115 #if defined(GLFW_INCLUDE_GLCOREARB)
116 #include <OpenGL/gl3.h>
117 #if defined(GLFW_INCLUDE_GLEXT)
118 #include <OpenGL/gl3ext.h>
119 #endif
120 #elif !defined(GLFW_INCLUDE_NONE)
121 #if !defined(GLFW_INCLUDE_GLEXT)
122 #define GL_GLEXT_LEGACY
123 #endif
124 #include <OpenGL/gl.h>
125 #endif
126 #if defined(GLFW_INCLUDE_GLU)
127 #include <OpenGL/glu.h>
128 #endif
129#else
130 #if defined(GLFW_INCLUDE_GLCOREARB)
131 #include <GL/glcorearb.h>
132 #elif defined(GLFW_INCLUDE_ES1)
133 #include <GLES/gl.h>
134 #if defined(GLFW_INCLUDE_GLEXT)
135 #include <GLES/glext.h>
136 #endif
137 #elif defined(GLFW_INCLUDE_ES2)
138 #include <GLES2/gl2.h>
139 #if defined(GLFW_INCLUDE_GLEXT)
140 #include <GLES2/gl2ext.h>
141 #endif
142 #elif defined(GLFW_INCLUDE_ES3)
143 #include <GLES3/gl3.h>
144 #if defined(GLFW_INCLUDE_GLEXT)
145 #include <GLES3/gl2ext.h>
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
161#endif
162
163#if defined(GLFW_DLL) && defined(_GLFW_BUILD_DLL)
164 /* GLFW_DLL must be defined by applications that are linking against the DLL
165 * version of the GLFW library. _GLFW_BUILD_DLL is defined by the GLFW
166 * configuration header when compiling the DLL version of the library.
167 */
168 #error "You may not have both GLFW_DLL and _GLFW_BUILD_DLL defined"
169#endif
170
171/* GLFWAPI is used to declare public API functions for export
172 * from the DLL / shared library / dynamic library.
173 */
174#if defined(_WIN32) && defined(_GLFW_BUILD_DLL)
175 /* We are building GLFW as a Win32 DLL */
176 #define GLFWAPI __declspec(dllexport)
177#elif defined(_WIN32) && defined(GLFW_DLL)
178 /* We are calling GLFW as a Win32 DLL */
179 #define GLFWAPI __declspec(dllimport)
180#elif defined(__GNUC__) && defined(_GLFW_BUILD_DLL)
181 /* We are building GLFW as a shared / dynamic library */
182 #define GLFWAPI __attribute__((visibility("default")))
183#else
184 /* We are building or calling GLFW as a static library */
185 #define GLFWAPI
186#endif
187
188
189/*************************************************************************
190 * GLFW API tokens
191 *************************************************************************/
192
193/*! @name GLFW version macros
194 * @{ */
195/*! @brief The major version number of the GLFW library.
196 *
197 * This is incremented when the API is changed in non-compatible ways.
198 * @ingroup init
199 */
200#define GLFW_VERSION_MAJOR 3
201/*! @brief The minor version number of the GLFW library.
202 *
203 * This is incremented when features are added to the API but it remains
204 * backward-compatible.
205 * @ingroup init
206 */
207#define GLFW_VERSION_MINOR 1
208/*! @brief The revision number of the GLFW library.
209 *
210 * This is incremented when a bug fix release is made that does not contain any
211 * API changes.
212 * @ingroup init
213 */
214#define GLFW_VERSION_REVISION 1
215/*! @} */
216
217/*! @name Key and button actions
218 * @{ */
219/*! @brief The key or mouse button was released.
220 *
221 * The key or mouse button was released.
222 *
223 * @ingroup input
224 */
225#define GLFW_RELEASE 0
226/*! @brief The key or mouse button was pressed.
227 *
228 * The key or mouse button was pressed.
229 *
230 * @ingroup input
231 */
232#define GLFW_PRESS 1
233/*! @brief The key was held down until it repeated.
234 *
235 * The key was held down until it repeated.
236 *
237 * @ingroup input
238 */
239#define GLFW_REPEAT 2
240/*! @} */
241
242/*! @defgroup keys Keyboard keys
243 *
244 * See [key input](@ref input_key) for how these are used.
245 *
246 * These key codes are inspired by the _USB HID Usage Tables v1.12_ (p. 53-60),
247 * but re-arranged to map to 7-bit ASCII for printable keys (function keys are
248 * put in the 256+ range).
249 *
250 * The naming of the key codes follow these rules:
251 * - The US keyboard layout is used
252 * - Names of printable alpha-numeric characters are used (e.g. "A", "R",
253 * "3", etc.)
254 * - For non-alphanumeric characters, Unicode:ish names are used (e.g.
255 * "COMMA", "LEFT_SQUARE_BRACKET", etc.). Note that some names do not
256 * correspond to the Unicode standard (usually for brevity)
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.)
260 *
261 * @ingroup input
262 * @{
263 */
264
265/* The unknown key */
266#define GLFW_KEY_UNKNOWN -1
267
268/* Printable keys */
269#define GLFW_KEY_SPACE 32
270#define GLFW_KEY_APOSTROPHE 39 /* ' */
271#define GLFW_KEY_COMMA 44 /* , */
272#define GLFW_KEY_MINUS 45 /* - */
273#define GLFW_KEY_PERIOD 46 /* . */
274#define GLFW_KEY_SLASH 47 /* / */
275#define GLFW_KEY_0 48
276#define GLFW_KEY_1 49
277#define GLFW_KEY_2 50
278#define GLFW_KEY_3 51
279#define GLFW_KEY_4 52
280#define GLFW_KEY_5 53
281#define GLFW_KEY_6 54
282#define GLFW_KEY_7 55
283#define GLFW_KEY_8 56
284#define GLFW_KEY_9 57
285#define GLFW_KEY_SEMICOLON 59 /* ; */
286#define GLFW_KEY_EQUAL 61 /* = */
287#define GLFW_KEY_A 65
288#define GLFW_KEY_B 66
289#define GLFW_KEY_C 67
290#define GLFW_KEY_D 68
291#define GLFW_KEY_E 69
292#define GLFW_KEY_F 70
293#define GLFW_KEY_G 71
294#define GLFW_KEY_H 72
295#define GLFW_KEY_I 73
296#define GLFW_KEY_J 74
297#define GLFW_KEY_K 75
298#define GLFW_KEY_L 76
299#define GLFW_KEY_M 77
300#define GLFW_KEY_N 78
301#define GLFW_KEY_O 79
302#define GLFW_KEY_P 80
303#define GLFW_KEY_Q 81
304#define GLFW_KEY_R 82
305#define GLFW_KEY_S 83
306#define GLFW_KEY_T 84
307#define GLFW_KEY_U 85
308#define GLFW_KEY_V 86
309#define GLFW_KEY_W 87
310#define GLFW_KEY_X 88
311#define GLFW_KEY_Y 89
312#define GLFW_KEY_Z 90
313#define GLFW_KEY_LEFT_BRACKET 91 /* [ */
314#define GLFW_KEY_BACKSLASH 92 /* \ */
315#define GLFW_KEY_RIGHT_BRACKET 93 /* ] */
316#define GLFW_KEY_GRAVE_ACCENT 96 /* ` */
317#define GLFW_KEY_WORLD_1 161 /* non-US #1 */
318#define GLFW_KEY_WORLD_2 162 /* non-US #2 */
319
320/* Function keys */
321#define GLFW_KEY_ESCAPE 256
322#define GLFW_KEY_ENTER 257
323#define GLFW_KEY_TAB 258
324#define GLFW_KEY_BACKSPACE 259
325#define GLFW_KEY_INSERT 260
326#define GLFW_KEY_DELETE 261
327#define GLFW_KEY_RIGHT 262
328#define GLFW_KEY_LEFT 263
329#define GLFW_KEY_DOWN 264
330#define GLFW_KEY_UP 265
331#define GLFW_KEY_PAGE_UP 266
332#define GLFW_KEY_PAGE_DOWN 267
333#define GLFW_KEY_HOME 268
334#define GLFW_KEY_END 269
335#define GLFW_KEY_CAPS_LOCK 280
336#define GLFW_KEY_SCROLL_LOCK 281
337#define GLFW_KEY_NUM_LOCK 282
338#define GLFW_KEY_PRINT_SCREEN 283
339#define GLFW_KEY_PAUSE 284
340#define GLFW_KEY_F1 290
341#define GLFW_KEY_F2 291
342#define GLFW_KEY_F3 292
343#define GLFW_KEY_F4 293
344#define GLFW_KEY_F5 294
345#define GLFW_KEY_F6 295
346#define GLFW_KEY_F7 296
347#define GLFW_KEY_F8 297
348#define GLFW_KEY_F9 298
349#define GLFW_KEY_F10 299
350#define GLFW_KEY_F11 300
351#define GLFW_KEY_F12 301
352#define GLFW_KEY_F13 302
353#define GLFW_KEY_F14 303
354#define GLFW_KEY_F15 304
355#define GLFW_KEY_F16 305
356#define GLFW_KEY_F17 306
357#define GLFW_KEY_F18 307
358#define GLFW_KEY_F19 308
359#define GLFW_KEY_F20 309
360#define GLFW_KEY_F21 310
361#define GLFW_KEY_F22 311
362#define GLFW_KEY_F23 312
363#define GLFW_KEY_F24 313
364#define GLFW_KEY_F25 314
365#define GLFW_KEY_KP_0 320
366#define GLFW_KEY_KP_1 321
367#define GLFW_KEY_KP_2 322
368#define GLFW_KEY_KP_3 323
369#define GLFW_KEY_KP_4 324
370#define GLFW_KEY_KP_5 325
371#define GLFW_KEY_KP_6 326
372#define GLFW_KEY_KP_7 327
373#define GLFW_KEY_KP_8 328
374#define GLFW_KEY_KP_9 329
375#define GLFW_KEY_KP_DECIMAL 330
376#define GLFW_KEY_KP_DIVIDE 331
377#define GLFW_KEY_KP_MULTIPLY 332
378#define GLFW_KEY_KP_SUBTRACT 333
379#define GLFW_KEY_KP_ADD 334
380#define GLFW_KEY_KP_ENTER 335
381#define GLFW_KEY_KP_EQUAL 336
382#define GLFW_KEY_LEFT_SHIFT 340
383#define GLFW_KEY_LEFT_CONTROL 341
384#define GLFW_KEY_LEFT_ALT 342
385#define GLFW_KEY_LEFT_SUPER 343
386#define GLFW_KEY_RIGHT_SHIFT 344
387#define GLFW_KEY_RIGHT_CONTROL 345
388#define GLFW_KEY_RIGHT_ALT 346
389#define GLFW_KEY_RIGHT_SUPER 347
390#define GLFW_KEY_MENU 348
391#define GLFW_KEY_LAST GLFW_KEY_MENU
392
393/*! @} */
394
395/*! @defgroup mods Modifier key flags
396 *
397 * See [key input](@ref input_key) for how these are used.
398 *
399 * @ingroup input
400 * @{ */
401
402/*! @brief If this bit is set one or more Shift keys were held down.
403 */
404#define GLFW_MOD_SHIFT 0x0001
405/*! @brief If this bit is set one or more Control keys were held down.
406 */
407#define GLFW_MOD_CONTROL 0x0002
408/*! @brief If this bit is set one or more Alt keys were held down.
409 */
410#define GLFW_MOD_ALT 0x0004
411/*! @brief If this bit is set one or more Super keys were held down.
412 */
413#define GLFW_MOD_SUPER 0x0008
414
415/*! @} */
416
417/*! @defgroup buttons Mouse buttons
418 *
419 * See [mouse button input](@ref input_mouse_button) for how these are used.
420 *
421 * @ingroup input
422 * @{ */
423#define GLFW_MOUSE_BUTTON_1 0
424#define GLFW_MOUSE_BUTTON_2 1
425#define GLFW_MOUSE_BUTTON_3 2
426#define GLFW_MOUSE_BUTTON_4 3
427#define GLFW_MOUSE_BUTTON_5 4
428#define GLFW_MOUSE_BUTTON_6 5
429#define GLFW_MOUSE_BUTTON_7 6
430#define GLFW_MOUSE_BUTTON_8 7
431#define GLFW_MOUSE_BUTTON_LAST GLFW_MOUSE_BUTTON_8
432#define GLFW_MOUSE_BUTTON_LEFT GLFW_MOUSE_BUTTON_1
433#define GLFW_MOUSE_BUTTON_RIGHT GLFW_MOUSE_BUTTON_2
434#define GLFW_MOUSE_BUTTON_MIDDLE GLFW_MOUSE_BUTTON_3
435/*! @} */
436
437/*! @defgroup joysticks Joysticks
438 *
439 * See [joystick input](@ref joystick) for how these are used.
440 *
441 * @ingroup input
442 * @{ */
443#define GLFW_JOYSTICK_1 0
444#define GLFW_JOYSTICK_2 1
445#define GLFW_JOYSTICK_3 2
446#define GLFW_JOYSTICK_4 3
447#define GLFW_JOYSTICK_5 4
448#define GLFW_JOYSTICK_6 5
449#define GLFW_JOYSTICK_7 6
450#define GLFW_JOYSTICK_8 7
451#define GLFW_JOYSTICK_9 8
452#define GLFW_JOYSTICK_10 9
453#define GLFW_JOYSTICK_11 10
454#define GLFW_JOYSTICK_12 11
455#define GLFW_JOYSTICK_13 12
456#define GLFW_JOYSTICK_14 13
457#define GLFW_JOYSTICK_15 14
458#define GLFW_JOYSTICK_16 15
459#define GLFW_JOYSTICK_LAST GLFW_JOYSTICK_16
460/*! @} */
461
462/*! @defgroup errors Error codes
463 *
464 * See [error handling](@ref error_handling) for how these are used.
465 *
466 * @ingroup init
467 * @{ */
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.
476 */
477#define GLFW_NOT_INITIALIZED 0x00010001
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.
487 */
488#define GLFW_NO_CURRENT_CONTEXT 0x00010002
489/*! @brief One of the arguments to the function was an invalid enum value.
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.
497 */
498#define GLFW_INVALID_ENUM 0x00010003
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.
509 */
510#define GLFW_INVALID_VALUE 0x00010004
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).
518 */
519#define GLFW_OUT_OF_MEMORY 0x00010005
520/*! @brief GLFW could not find support for the requested client API on the
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.
538 */
539#define GLFW_API_UNAVAILABLE 0x00010006
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.
556 */
557#define GLFW_VERSION_UNAVAILABLE 0x00010007
558/*! @brief A platform-specific error occurred that does not match any of the
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).
568 */
569#define GLFW_PLATFORM_ERROR 0x00010008
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.
588 */
589#define GLFW_FORMAT_UNAVAILABLE 0x00010009
590/*! @} */
591
592#define GLFW_FOCUSED 0x00020001
593#define GLFW_ICONIFIED 0x00020002
594#define GLFW_RESIZABLE 0x00020003
595#define GLFW_VISIBLE 0x00020004
596#define GLFW_DECORATED 0x00020005
597#define GLFW_AUTO_ICONIFY 0x00020006
598#define GLFW_FLOATING 0x00020007
599
600#define GLFW_RED_BITS 0x00021001
601#define GLFW_GREEN_BITS 0x00021002
602#define GLFW_BLUE_BITS 0x00021003
603#define GLFW_ALPHA_BITS 0x00021004
604#define GLFW_DEPTH_BITS 0x00021005
605#define GLFW_STENCIL_BITS 0x00021006
606#define GLFW_ACCUM_RED_BITS 0x00021007
607#define GLFW_ACCUM_GREEN_BITS 0x00021008
608#define GLFW_ACCUM_BLUE_BITS 0x00021009
609#define GLFW_ACCUM_ALPHA_BITS 0x0002100A
610#define GLFW_AUX_BUFFERS 0x0002100B
611#define GLFW_STEREO 0x0002100C
612#define GLFW_SAMPLES 0x0002100D
613#define GLFW_SRGB_CAPABLE 0x0002100E
614#define GLFW_REFRESH_RATE 0x0002100F
615#define GLFW_DOUBLEBUFFER 0x00021010
616
617#define GLFW_CLIENT_API 0x00022001
618#define GLFW_CONTEXT_VERSION_MAJOR 0x00022002
619#define GLFW_CONTEXT_VERSION_MINOR 0x00022003
620#define GLFW_CONTEXT_REVISION 0x00022004
621#define GLFW_CONTEXT_ROBUSTNESS 0x00022005
622#define GLFW_OPENGL_FORWARD_COMPAT 0x00022006
623#define GLFW_OPENGL_DEBUG_CONTEXT 0x00022007
624#define GLFW_OPENGL_PROFILE 0x00022008
625#define GLFW_CONTEXT_RELEASE_BEHAVIOR 0x00022009
626
627#define GLFW_OPENGL_API 0x00030001
628#define GLFW_OPENGL_ES_API 0x00030002
629
630#define GLFW_NO_ROBUSTNESS 0
631#define GLFW_NO_RESET_NOTIFICATION 0x00031001
632#define GLFW_LOSE_CONTEXT_ON_RESET 0x00031002
633
634#define GLFW_OPENGL_ANY_PROFILE 0
635#define GLFW_OPENGL_CORE_PROFILE 0x00032001
636#define GLFW_OPENGL_COMPAT_PROFILE 0x00032002
637
638#define GLFW_CURSOR 0x00033001
639#define GLFW_STICKY_KEYS 0x00033002
640#define GLFW_STICKY_MOUSE_BUTTONS 0x00033003
641
642#define GLFW_CURSOR_NORMAL 0x00034001
643#define GLFW_CURSOR_HIDDEN 0x00034002
644#define GLFW_CURSOR_DISABLED 0x00034003
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
689#define GLFW_CONNECTED 0x00040001
690#define GLFW_DISCONNECTED 0x00040002
691
692#define GLFW_DONT_CARE -1
693
694
695/*************************************************************************
696 * GLFW API types
697 *************************************************************************/
698
699/*! @brief Client API function pointer type.
700 *
701 * Generic function pointer used for returning client API function pointers
702 * without forcing a cast from a regular pointer.
703 *
704 * @ingroup context
705 */
706typedef void (*GLFWglproc)(void);
707
708/*! @brief Opaque monitor object.
709 *
710 * Opaque monitor object.
711 *
712 * @ingroup monitor
713 */
714typedef struct GLFWmonitor GLFWmonitor;
715
716/*! @brief Opaque window object.
717 *
718 * Opaque window object.
719 *
720 * @ingroup window
721 */
722typedef struct GLFWwindow GLFWwindow;
723
724/*! @brief Opaque cursor object.
725 *
726 * Opaque cursor object.
727 *
728 * @ingroup cursor
729 */
730typedef struct GLFWcursor GLFWcursor;
731
732/*! @brief The function signature for error callbacks.
733 *
734 * This is the function signature for error callback functions.
735 *
736 * @param[in] error An [error code](@ref errors).
737 * @param[in] description A UTF-8 encoded string describing the error.
738 *
739 * @sa glfwSetErrorCallback
740 *
741 * @ingroup init
742 */
743typedef void (* GLFWerrorfun)(int,const char*);
744
745/*! @brief The function signature for window position callbacks.
746 *
747 * This is the function signature for window position callback functions.
748 *
749 * @param[in] window The window that was moved.
750 * @param[in] xpos The new x-coordinate, in screen coordinates, of the
751 * upper-left corner of the client area of the window.
752 * @param[in] ypos The new y-coordinate, in screen coordinates, of the
753 * upper-left corner of the client area of the window.
754 *
755 * @sa glfwSetWindowPosCallback
756 *
757 * @ingroup window
758 */
759typedef void (* GLFWwindowposfun)(GLFWwindow*,int,int);
760
761/*! @brief The function signature for window resize callbacks.
762 *
763 * This is the function signature for window size callback functions.
764 *
765 * @param[in] window The window that was resized.
766 * @param[in] width The new width, in screen coordinates, of the window.
767 * @param[in] height The new height, in screen coordinates, of the window.
768 *
769 * @sa glfwSetWindowSizeCallback
770 *
771 * @ingroup window
772 */
773typedef void (* GLFWwindowsizefun)(GLFWwindow*,int,int);
774
775/*! @brief The function signature for window close callbacks.
776 *
777 * This is the function signature for window close callback functions.
778 *
779 * @param[in] window The window that the user attempted to close.
780 *
781 * @sa glfwSetWindowCloseCallback
782 *
783 * @ingroup window
784 */
785typedef void (* GLFWwindowclosefun)(GLFWwindow*);
786
787/*! @brief The function signature for window content refresh callbacks.
788 *
789 * This is the function signature for window refresh callback functions.
790 *
791 * @param[in] window The window whose content needs to be refreshed.
792 *
793 * @sa glfwSetWindowRefreshCallback
794 *
795 * @ingroup window
796 */
797typedef void (* GLFWwindowrefreshfun)(GLFWwindow*);
798
799/*! @brief The function signature for window focus/defocus callbacks.
800 *
801 * This is the function signature for window focus callback functions.
802 *
803 * @param[in] window The window that gained or lost input focus.
804 * @param[in] focused `GL_TRUE` if the window was given input focus, or
805 * `GL_FALSE` if it lost it.
806 *
807 * @sa glfwSetWindowFocusCallback
808 *
809 * @ingroup window
810 */
811typedef void (* GLFWwindowfocusfun)(GLFWwindow*,int);
812
813/*! @brief The function signature for window iconify/restore callbacks.
814 *
815 * This is the function signature for window iconify/restore callback
816 * functions.
817 *
818 * @param[in] window The window that was iconified or restored.
819 * @param[in] iconified `GL_TRUE` if the window was iconified, or `GL_FALSE`
820 * if it was restored.
821 *
822 * @sa glfwSetWindowIconifyCallback
823 *
824 * @ingroup window
825 */
826typedef void (* GLFWwindowiconifyfun)(GLFWwindow*,int);
827
828/*! @brief The function signature for framebuffer resize callbacks.
829 *
830 * This is the function signature for framebuffer resize callback
831 * functions.
832 *
833 * @param[in] window The window whose framebuffer was resized.
834 * @param[in] width The new width, in pixels, of the framebuffer.
835 * @param[in] height The new height, in pixels, of the framebuffer.
836 *
837 * @sa glfwSetFramebufferSizeCallback
838 *
839 * @ingroup window
840 */
841typedef void (* GLFWframebuffersizefun)(GLFWwindow*,int,int);
842
843/*! @brief The function signature for mouse button callbacks.
844 *
845 * This is the function signature for mouse button callback functions.
846 *
847 * @param[in] window The window that received the event.
848 * @param[in] button The [mouse button](@ref buttons) that was pressed or
849 * released.
850 * @param[in] action One of `GLFW_PRESS` or `GLFW_RELEASE`.
851 * @param[in] mods Bit field describing which [modifier keys](@ref mods) were
852 * held down.
853 *
854 * @sa glfwSetMouseButtonCallback
855 *
856 * @ingroup input
857 */
858typedef void (* GLFWmousebuttonfun)(GLFWwindow*,int,int,int);
859
860/*! @brief The function signature for cursor position callbacks.
861 *
862 * This is the function signature for cursor position callback functions.
863 *
864 * @param[in] window The window that received the event.
865 * @param[in] xpos The new x-coordinate, in screen coordinates, of the cursor.
866 * @param[in] ypos The new y-coordinate, in screen coordinates, of the cursor.
867 *
868 * @sa glfwSetCursorPosCallback
869 *
870 * @ingroup input
871 */
872typedef void (* GLFWcursorposfun)(GLFWwindow*,double,double);
873
874/*! @brief The function signature for cursor enter/leave callbacks.
875 *
876 * This is the function signature for cursor enter/leave callback functions.
877 *
878 * @param[in] window The window that received the event.
879 * @param[in] entered `GL_TRUE` if the cursor entered the window's client
880 * area, or `GL_FALSE` if it left it.
881 *
882 * @sa glfwSetCursorEnterCallback
883 *
884 * @ingroup input
885 */
886typedef void (* GLFWcursorenterfun)(GLFWwindow*,int);
887
888/*! @brief The function signature for scroll callbacks.
889 *
890 * This is the function signature for scroll callback functions.
891 *
892 * @param[in] window The window that received the event.
893 * @param[in] xoffset The scroll offset along the x-axis.
894 * @param[in] yoffset The scroll offset along the y-axis.
895 *
896 * @sa glfwSetScrollCallback
897 *
898 * @ingroup input
899 */
900typedef void (* GLFWscrollfun)(GLFWwindow*,double,double);
901
902/*! @brief The function signature for keyboard key callbacks.
903 *
904 * This is the function signature for keyboard key callback functions.
905 *
906 * @param[in] window The window that received the event.
907 * @param[in] key The [keyboard key](@ref keys) that was pressed or released.
908 * @param[in] scancode The system-specific scancode of the key.
909 * @param[in] action `GLFW_PRESS`, `GLFW_RELEASE` or `GLFW_REPEAT`.
910 * @param[in] mods Bit field describing which [modifier keys](@ref mods) were
911 * held down.
912 *
913 * @sa glfwSetKeyCallback
914 *
915 * @ingroup input
916 */
917typedef void (* GLFWkeyfun)(GLFWwindow*,int,int,int,int);
918
919/*! @brief The function signature for Unicode character callbacks.
920 *
921 * This is the function signature for Unicode character callback functions.
922 *
923 * @param[in] window The window that received the event.
924 * @param[in] codepoint The Unicode code point of the character.
925 *
926 * @sa glfwSetCharCallback
927 *
928 * @ingroup input
929 */
930typedef void (* GLFWcharfun)(GLFWwindow*,unsigned int);
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
964/*! @brief The function signature for monitor configuration callbacks.
965 *
966 * This is the function signature for monitor configuration callback functions.
967 *
968 * @param[in] monitor The monitor that was connected or disconnected.
969 * @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`.
970 *
971 * @sa glfwSetMonitorCallback
972 *
973 * @ingroup monitor
974 */
975typedef void (* GLFWmonitorfun)(GLFWmonitor*,int);
976
977/*! @brief Video mode type.
978 *
979 * This describes a single video mode.
980 *
981 * @ingroup monitor
982 */
983typedef struct GLFWvidmode
984{
985 /*! The width, in screen coordinates, of the video mode.
986 */
987 int width;
988 /*! The height, in screen coordinates, of the video mode.
989 */
990 int height;
991 /*! The bit depth of the red channel of the video mode.
992 */
993 int redBits;
994 /*! The bit depth of the green channel of the video mode.
995 */
996 int greenBits;
997 /*! The bit depth of the blue channel of the video mode.
998 */
999 int blueBits;
1000 /*! The refresh rate, in Hz, of the video mode.
1001 */
1002 int refreshRate;
1003} GLFWvidmode;
1004
1005/*! @brief Gamma ramp.
1006 *
1007 * This describes the gamma ramp for a monitor.
1008 *
1009 * @sa glfwGetGammaRamp glfwSetGammaRamp
1010 *
1011 * @ingroup monitor
1012 */
1013typedef struct GLFWgammaramp
1014{
1015 /*! An array of value describing the response of the red channel.
1016 */
1017 unsigned short* red;
1018 /*! An array of value describing the response of the green channel.
1019 */
1020 unsigned short* green;
1021 /*! An array of value describing the response of the blue channel.
1022 */
1023 unsigned short* blue;
1024 /*! The number of elements in each array.
1025 */
1026 unsigned int size;
1027} GLFWgammaramp;
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
1044
1045/*************************************************************************
1046 * GLFW API functions
1047 *************************************************************************/
1048
1049/*! @brief Initializes the GLFW library.
1050 *
1051 * This function initializes the GLFW library. Before most GLFW functions can
1052 * be used, GLFW must be initialized, and before an application terminates GLFW
1053 * should be terminated in order to free any resources allocated during or
1054 * after initialization.
1055 *
1056 * If this function fails, it calls @ref glfwTerminate before returning. If it
1057 * succeeds, you should call @ref glfwTerminate before the application exits.
1058 *
1059 * Additional calls to this function after successful initialization but before
1060 * termination will return `GL_TRUE` immediately.
1061 *
1062 * @return `GL_TRUE` if successful, or `GL_FALSE` if an
1063 * [error](@ref error_handling) occurred.
1064 *
1065 * @remarks __OS X:__ This function will change the current directory of the
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).
1069 *
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.
1075 *
1076 * @par Thread Safety
1077 * This function may only be called from the main thread.
1078 *
1079 * @sa @ref intro_init
1080 * @sa glfwTerminate
1081 *
1082 * @since Added in GLFW 1.0.
1083 *
1084 * @ingroup init
1085 */
1086GLFWAPI int glfwInit(void);
1087
1088/*! @brief Terminates the GLFW library.
1089 *
1090 * This function destroys all remaining windows and cursors, restores any
1091 * modified gamma ramps and frees any other allocated resources. Once this
1092 * function is called, you must again call @ref glfwInit successfully before
1093 * you will be able to use most GLFW functions.
1094 *
1095 * If GLFW has been successfully initialized, this function should be called
1096 * before the application exits. If initialization fails, there is no need to
1097 * call this function, as it is called by @ref glfwInit before it returns
1098 * failure.
1099 *
1100 * @remarks This function may be called before @ref glfwInit.
1101 *
1102 * @warning No window's context may be current on another thread when this
1103 * function is called.
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
1112 * @sa glfwInit
1113 *
1114 * @since Added in GLFW 1.0.
1115 *
1116 * @ingroup init
1117 */
1118GLFWAPI void glfwTerminate(void);
1119
1120/*! @brief Retrieves the version of the GLFW library.
1121 *
1122 * This function retrieves the major, minor and revision numbers of the GLFW
1123 * library. It is intended for when you are using GLFW as a shared library and
1124 * want to ensure that you are using the minimum required version.
1125 *
1126 * Any or all of the version arguments may be `NULL`. This function always
1127 * succeeds.
1128 *
1129 * @param[out] major Where to store the major version number, or `NULL`.
1130 * @param[out] minor Where to store the minor version number, or `NULL`.
1131 * @param[out] rev Where to store the revision number, or `NULL`.
1132 *
1133 * @remarks This function may be called before @ref glfwInit.
1134 *
1135 * @par Thread Safety
1136 * This function may be called from any thread.
1137 *
1138 * @sa @ref intro_version
1139 * @sa glfwGetVersionString
1140 *
1141 * @since Added in GLFW 1.0.
1142 *
1143 * @ingroup init
1144 */
1145GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev);
1146
1147/*! @brief Returns a string describing the compile-time configuration.
1148 *
1149 * This function returns the compile-time generated
1150 * [version string](@ref intro_version_string) of the GLFW library binary. It
1151 * describes the version, platform, compiler and any platform-specific
1152 * compile-time options.
1153 *
1154 * __Do not use the version string__ to parse the GLFW library version. The
1155 * @ref glfwGetVersion function already provides the version of the running
1156 * library binary.
1157 *
1158 * This function always succeeds.
1159 *
1160 * @return The GLFW version string.
1161 *
1162 * @remarks This function may be called before @ref glfwInit.
1163 *
1164 * @par Pointer Lifetime
1165 * The returned string is static and compile-time generated.
1166 *
1167 * @par Thread Safety
1168 * This function may be called from any thread.
1169 *
1170 * @sa @ref intro_version
1171 * @sa glfwGetVersion
1172 *
1173 * @since Added in GLFW 3.0.
1174 *
1175 * @ingroup init
1176 */
1177GLFWAPI const char* glfwGetVersionString(void);
1178
1179/*! @brief Sets the error callback.
1180 *
1181 * This function sets the error callback, which is called with an error code
1182 * and a human-readable description each time a GLFW error occurs.
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 *
1195 * @param[in] cbfun The new callback, or `NULL` to remove the currently set
1196 * callback.
1197 * @return The previously set callback, or `NULL` if no callback was set.
1198 *
1199 * @remarks This function may be called before @ref glfwInit.
1200 *
1201 * @par Thread Safety
1202 * This function may only be called from the main thread.
1203 *
1204 * @sa @ref error_handling
1205 *
1206 * @since Added in GLFW 3.0.
1207 *
1208 * @ingroup init
1209 */
1210GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun);
1211
1212/*! @brief Returns the currently connected monitors.
1213 *
1214 * This function returns an array of handles for all currently connected
1215 * monitors.
1216 *
1217 * @param[out] count Where to store the number of monitors in the returned
1218 * array. This is set to zero if an error occurred.
1219 * @return An array of monitor handles, or `NULL` if an
1220 * [error](@ref error_handling) occurred.
1221 *
1222 * @par Pointer Lifetime
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.
1226 *
1227 * @par Thread Safety
1228 * This function may only be called from the main thread.
1229 *
1230 * @sa @ref monitor_monitors
1231 * @sa @ref monitor_event
1232 * @sa glfwGetPrimaryMonitor
1233 *
1234 * @since Added in GLFW 3.0.
1235 *
1236 * @ingroup monitor
1237 */
1238GLFWAPI GLFWmonitor** glfwGetMonitors(int* count);
1239
1240/*! @brief Returns the primary monitor.
1241 *
1242 * This function returns the primary monitor. This is usually the monitor
1243 * where elements like the Windows task bar or the OS X menu bar is located.
1244 *
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.
1250 *
1251 * @sa @ref monitor_monitors
1252 * @sa glfwGetMonitors
1253 *
1254 * @since Added in GLFW 3.0.
1255 *
1256 * @ingroup monitor
1257 */
1258GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void);
1259
1260/*! @brief Returns the position of the monitor's viewport on the virtual screen.
1261 *
1262 * This function returns the position, in screen coordinates, of the upper-left
1263 * corner of the specified monitor.
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 *
1268 * @param[in] monitor The monitor to query.
1269 * @param[out] xpos Where to store the monitor x-coordinate, or `NULL`.
1270 * @param[out] ypos Where to store the monitor y-coordinate, or `NULL`.
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 *
1279 * @ingroup monitor
1280 */
1281GLFWAPI void glfwGetMonitorPos(GLFWmonitor* monitor, int* xpos, int* ypos);
1282
1283/*! @brief Returns the physical size of the monitor.
1284 *
1285 * This function returns the size, in millimetres, of the display area of the
1286 * specified monitor.
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 *
1296 * @param[in] monitor The monitor to query.
1297 * @param[out] widthMM Where to store the width, in millimetres, of the
1298 * monitor's display area, or `NULL`.
1299 * @param[out] heightMM Where to store the height, in millimetres, of the
1300 * monitor's display area, or `NULL`.
1301 *
1302 * @remarks __Windows:__ The OS calculates the returned physical size from the
1303 * current resolution and system DPI instead of querying the monitor EDID data.
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.
1311 *
1312 * @ingroup monitor
1313 */
1314GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* monitor, int* widthMM, int* heightMM);
1315
1316/*! @brief Returns the name of the specified monitor.
1317 *
1318 * This function returns a human-readable name, encoded as UTF-8, of the
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.
1321 *
1322 * @param[in] monitor The monitor to query.
1323 * @return The UTF-8 encoded name of the monitor, or `NULL` if an
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
1335 *
1336 * @since Added in GLFW 3.0.
1337 *
1338 * @ingroup monitor
1339 */
1340GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* monitor);
1341
1342/*! @brief Sets the monitor configuration callback.
1343 *
1344 * This function sets the monitor configuration callback, or removes the
1345 * currently set callback. This is called when a monitor is connected to or
1346 * disconnected from the system.
1347 *
1348 * @param[in] cbfun The new callback, or `NULL` to remove the currently set
1349 * callback.
1350 * @return The previously set callback, or `NULL` if no callback was set or the
1351 * library had not been [initialized](@ref intro_init).
1352 *
1353 * @bug __X11:__ This callback is not yet called on monitor configuration
1354 * changes.
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 *
1363 * @ingroup monitor
1364 */
1365GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun);
1366
1367/*! @brief Returns the available video modes for the specified monitor.
1368 *
1369 * This function returns an array of all video modes supported by the specified
1370 * monitor. The returned array is sorted in ascending order, first by color
1371 * bit depth (the sum of all channel depths) and then by resolution area (the
1372 * product of width and height).
1373 *
1374 * @param[in] monitor The monitor to query.
1375 * @param[out] count Where to store the number of video modes in the returned
1376 * array. This is set to zero if an error occurred.
1377 * @return An array of video modes, or `NULL` if an
1378 * [error](@ref error_handling) occurred.
1379 *
1380 * @par Pointer Lifetime
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.
1384 *
1385 * @par Thread Safety
1386 * This function may only be called from the main thread.
1387 *
1388 * @sa @ref monitor_modes
1389 * @sa glfwGetVideoMode
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 *
1396 * @ingroup monitor
1397 */
1398GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* monitor, int* count);
1399
1400/*! @brief Returns the current mode of the specified monitor.
1401 *
1402 * This function returns the current video mode of the specified monitor. If
1403 * you have created a full screen window for that monitor, the return value
1404 * will depend on whether that window is iconified.
1405 *
1406 * @param[in] monitor The monitor to query.
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.
1414 *
1415 * @par Thread Safety
1416 * This function may only be called from the main thread.
1417 *
1418 * @sa @ref monitor_modes
1419 * @sa glfwGetVideoModes
1420 *
1421 * @since Added in GLFW 3.0. Replaces `glfwGetDesktopMode`.
1422 *
1423 * @ingroup monitor
1424 */
1425GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor);
1426
1427/*! @brief Generates a gamma ramp and sets it for the specified monitor.
1428 *
1429 * This function generates a 256-element gamma ramp from the specified exponent
1430 * and then calls @ref glfwSetGammaRamp with it. The value must be a finite
1431 * number greater than zero.
1432 *
1433 * @param[in] monitor The monitor whose gamma ramp to set.
1434 * @param[in] gamma The desired exponent.
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 *
1443 * @ingroup monitor
1444 */
1445GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma);
1446
1447/*! @brief Returns the current gamma ramp for the specified monitor.
1448 *
1449 * This function returns the current gamma ramp of the specified monitor.
1450 *
1451 * @param[in] monitor The monitor to query.
1452 * @return The current gamma ramp, or `NULL` if an
1453 * [error](@ref error_handling) occurred.
1454 *
1455 * @par Pointer Lifetime
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.
1467 *
1468 * @ingroup monitor
1469 */
1470GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor);
1471
1472/*! @brief Sets the current gamma ramp for the specified monitor.
1473 *
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.
1477 *
1478 * @param[in] monitor The monitor whose gamma ramp to set.
1479 * @param[in] ramp The gamma ramp to use.
1480 *
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.
1495 *
1496 * @ingroup monitor
1497 */
1498GLFWAPI void glfwSetGammaRamp(GLFWmonitor* monitor, const GLFWgammaramp* ramp);
1499
1500/*! @brief Resets all window hints to their default values.
1501 *
1502 * This function resets all window hints to their
1503 * [default values](@ref window_hints_values).
1504 *
1505 * @par Thread Safety
1506 * This function may only be called from the main thread.
1507 *
1508 * @sa @ref window_hints
1509 * @sa glfwWindowHint
1510 *
1511 * @since Added in GLFW 3.0.
1512 *
1513 * @ingroup window
1514 */
1515GLFWAPI void glfwDefaultWindowHints(void);
1516
1517/*! @brief Sets the specified window hint to the desired value.
1518 *
1519 * This function sets hints for the next call to @ref glfwCreateWindow. The
1520 * hints, once set, retain their values until changed by a call to @ref
1521 * glfwWindowHint or @ref glfwDefaultWindowHints, or until the library is
1522 * terminated.
1523 *
1524 * @param[in] target The [window hint](@ref window_hints) to set.
1525 * @param[in] hint The new value of the window hint.
1526 *
1527 * @par Thread Safety
1528 * This function may only be called from the main thread.
1529 *
1530 * @sa @ref window_hints
1531 * @sa glfwDefaultWindowHints
1532 *
1533 * @since Added in GLFW 3.0. Replaces `glfwOpenWindowHint`.
1534 *
1535 * @ingroup window
1536 */
1537GLFWAPI void glfwWindowHint(int target, int hint);
1538
1539/*! @brief Creates a window and its associated context.
1540 *
1541 * This function creates a window and its associated OpenGL or OpenGL ES
1542 * context. Most of the options controlling how the window and its context
1543 * should be created are specified with [window hints](@ref window_hints).
1544 *
1545 * Successful creation does not change which context is current. Before you
1546 * can use the newly created context, you need to
1547 * [make it current](@ref context_current). For information about the `share`
1548 * parameter, see @ref context_sharing.
1549 *
1550 * The created window, framebuffer and context may differ from what you
1551 * requested, as not all parameters and hints are
1552 * [hard constraints](@ref window_hints_hard). This includes the size of the
1553 * window, especially for full screen windows. To query the actual attributes
1554 * of the created window, framebuffer and context, use queries like @ref
1555 * glfwGetWindowAttrib and @ref glfwGetWindowSize.
1556 *
1557 * To create a full screen window, you need to specify the monitor the window
1558 * will cover. If no monitor is specified, windowed mode will be used. Unless
1559 * you have a way for the user to choose a specific monitor, it is recommended
1560 * that you pick the primary monitor. For more information on how to query
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.
1578 *
1579 * Window systems put limits on window sizes. Very large or very small window
1580 * dimensions may be overridden by the window system on creation. Check the
1581 * actual [size](@ref window_size) after creation.
1582 *
1583 * The [swap interval](@ref buffer_swap) is not set during window creation and
1584 * the initial value may vary depending on driver settings and defaults.
1585 *
1586 * @param[in] width The desired width, in screen coordinates, of the window.
1587 * This must be greater than zero.
1588 * @param[in] height The desired height, in screen coordinates, of the window.
1589 * This must be greater than zero.
1590 * @param[in] title The initial, UTF-8 encoded window title.
1591 * @param[in] monitor The monitor to use for full screen mode, or `NULL` to use
1592 * windowed mode.
1593 * @param[in] share The window whose context to share resources with, or `NULL`
1594 * to not share resources.
1595 * @return The handle of the created window, or `NULL` if an
1596 * [error](@ref error_handling) occurred.
1597 *
1598 * @remarks __Windows:__ Window creation will fail if the Microsoft GDI
1599 * software OpenGL implementation is the only one available.
1600 *
1601 * @remarks __Windows:__ If the executable has an icon resource named
1602 * `GLFW_ICON,` it will be set as the icon for the window. If no such icon is
1603 * present, the `IDI_WINLOGO` icon will be used instead.
1604 *
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
1609 * window, but the dock icon will be the same as the application bundle's icon.
1610 * For more information on bundles, see the
1611 * [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/)
1612 * in the Mac Developer Library.
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).
1619 *
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.
1626 *
1627 * @remarks __X11:__ There is no mechanism for setting the window icon yet.
1628 *
1629 * @remarks __X11:__ Some window managers will not respect the placement of
1630 * initially hidden windows.
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
1639 * @sa glfwDestroyWindow
1640 *
1641 * @since Added in GLFW 3.0. Replaces `glfwOpenWindow`.
1642 *
1643 * @ingroup window
1644 */
1645GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, GLFWmonitor* monitor, GLFWwindow* share);
1646
1647/*! @brief Destroys the specified window and its context.
1648 *
1649 * This function destroys the specified window and its context. On calling
1650 * this function, no further callbacks will be called for that window.
1651 *
1652 * If the context of the specified window is current on the main thread, it is
1653 * detached before being destroyed.
1654 *
1655 * @param[in] window The window to destroy.
1656 *
1657 * @note The context of the specified window must not be current on any other
1658 * thread when this function is called.
1659 *
1660 * @par Reentrancy
1661 * This function may not be called from a callback.
1662 *
1663 * @par Thread Safety
1664 * This function may only be called from the main thread.
1665 *
1666 * @sa @ref window_creation
1667 * @sa glfwCreateWindow
1668 *
1669 * @since Added in GLFW 3.0. Replaces `glfwCloseWindow`.
1670 *
1671 * @ingroup window
1672 */
1673GLFWAPI void glfwDestroyWindow(GLFWwindow* window);
1674
1675/*! @brief Checks the close flag of the specified window.
1676 *
1677 * This function returns the value of the close flag of the specified window.
1678 *
1679 * @param[in] window The window to query.
1680 * @return The value of the close flag.
1681 *
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.
1688 *
1689 * @ingroup window
1690 */
1691GLFWAPI int glfwWindowShouldClose(GLFWwindow* window);
1692
1693/*! @brief Sets the close flag of the specified window.
1694 *
1695 * This function sets the value of the close flag of the specified window.
1696 * This can be used to override the user's attempt to close the window, or
1697 * to signal that it should be closed.
1698 *
1699 * @param[in] window The window whose flag to change.
1700 * @param[in] value The new value.
1701 *
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.
1708 *
1709 * @ingroup window
1710 */
1711GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* window, int value);
1712
1713/*! @brief Sets the title of the specified window.
1714 *
1715 * This function sets the window title, encoded as UTF-8, of the specified
1716 * window.
1717 *
1718 * @param[in] window The window whose title to change.
1719 * @param[in] title The UTF-8 encoded window title.
1720 *
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.
1730 *
1731 * @ingroup window
1732 */
1733GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title);
1734
1735/*! @brief Retrieves the position of the client area of the specified window.
1736 *
1737 * This function retrieves the position, in screen coordinates, of the
1738 * upper-left corner of the client area of the specified window.
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 *
1743 * @param[in] window The window to query.
1744 * @param[out] xpos Where to store the x-coordinate of the upper-left corner of
1745 * the client area, or `NULL`.
1746 * @param[out] ypos Where to store the y-coordinate of the upper-left corner of
1747 * the client area, or `NULL`.
1748 *
1749 * @par Thread Safety
1750 * This function may only be called from the main thread.
1751 *
1752 * @sa @ref window_pos
1753 * @sa glfwSetWindowPos
1754 *
1755 * @since Added in GLFW 3.0.
1756 *
1757 * @ingroup window
1758 */
1759GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos);
1760
1761/*! @brief Sets the position of the client area of the specified window.
1762 *
1763 * This function sets the position, in screen coordinates, of the upper-left
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.
1766 *
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.
1769 *
1770 * The window manager may put limits on what positions are allowed. GLFW
1771 * cannot and should not override these limits.
1772 *
1773 * @param[in] window The window to query.
1774 * @param[in] xpos The x-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.
1776 *
1777 * @par Thread Safety
1778 * This function may only be called from the main thread.
1779 *
1780 * @sa @ref window_pos
1781 * @sa glfwGetWindowPos
1782 *
1783 * @since Added in GLFW 1.0.
1784 *
1785 * @par
1786 * __GLFW 3:__ Added window handle parameter.
1787 *
1788 * @ingroup window
1789 */
1790GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos);
1791
1792/*! @brief Retrieves the size of the client area of the specified window.
1793 *
1794 * This function retrieves the size, in screen coordinates, of the client area
1795 * of the specified window. If you wish to retrieve the size of the
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.
1800 *
1801 * @param[in] window The window whose size to retrieve.
1802 * @param[out] width Where to store the width, in screen coordinates, of the
1803 * client area, or `NULL`.
1804 * @param[out] height Where to store the height, in screen coordinates, of the
1805 * client area, or `NULL`.
1806 *
1807 * @par Thread Safety
1808 * This function may only be called from the main thread.
1809 *
1810 * @sa @ref window_size
1811 * @sa glfwSetWindowSize
1812 *
1813 * @since Added in GLFW 1.0.
1814 *
1815 * @par
1816 * __GLFW 3:__ Added window handle parameter.
1817 *
1818 * @ingroup window
1819 */
1820GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height);
1821
1822/*! @brief Sets the size of the client area of the specified window.
1823 *
1824 * This function sets the size, in screen coordinates, of the client area of
1825 * the specified window.
1826 *
1827 * For full screen windows, this function selects and switches to the resolution
1828 * closest to the specified size, without affecting the window's context. As
1829 * the context is unaffected, the bit depths of the framebuffer remain
1830 * unchanged.
1831 *
1832 * The window manager may put limits on what sizes are allowed. GLFW cannot
1833 * and should not override these limits.
1834 *
1835 * @param[in] window The window to resize.
1836 * @param[in] width The desired width of the specified window.
1837 * @param[in] height The desired height of the specified window.
1838 *
1839 * @par Thread Safety
1840 * This function may only be called from the main thread.
1841 *
1842 * @sa @ref window_size
1843 * @sa glfwGetWindowSize
1844 *
1845 * @since Added in GLFW 1.0.
1846 *
1847 * @par
1848 * __GLFW 3:__ Added window handle parameter.
1849 *
1850 * @ingroup window
1851 */
1852GLFWAPI void glfwSetWindowSize(GLFWwindow* window, int width, int height);
1853
1854/*! @brief Retrieves the size of the framebuffer of the specified window.
1855 *
1856 * This function retrieves the size, in pixels, of the framebuffer of the
1857 * specified window. If you wish to retrieve the size of the window in screen
1858 * coordinates, see @ref glfwGetWindowSize.
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 *
1863 * @param[in] window The window whose framebuffer to query.
1864 * @param[out] width Where to store the width, in pixels, of the framebuffer,
1865 * or `NULL`.
1866 * @param[out] height Where to store the height, in pixels, of the framebuffer,
1867 * or `NULL`.
1868 *
1869 * @par Thread Safety
1870 * This function may only be called from the main thread.
1871 *
1872 * @sa @ref window_fbsize
1873 * @sa glfwSetFramebufferSizeCallback
1874 *
1875 * @since Added in GLFW 3.0.
1876 *
1877 * @ingroup window
1878 */
1879GLFWAPI void glfwGetFramebufferSize(GLFWwindow* window, int* width, int* height);
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
1916/*! @brief Iconifies the specified window.
1917 *
1918 * This function iconifies (minimizes) the specified window if it was
1919 * previously restored. If the window is already iconified, this function does
1920 * nothing.
1921 *
1922 * If the specified window is a full screen window, the original monitor
1923 * resolution is restored until the window is restored.
1924 *
1925 * @param[in] window The window to iconify.
1926 *
1927 * @par Thread Safety
1928 * This function may only be called from the main thread.
1929 *
1930 * @sa @ref window_iconify
1931 * @sa glfwRestoreWindow
1932 *
1933 * @since Added in GLFW 2.1.
1934 *
1935 * @par
1936 * __GLFW 3:__ Added window handle parameter.
1937 *
1938 * @ingroup window
1939 */
1940GLFWAPI void glfwIconifyWindow(GLFWwindow* window);
1941
1942/*! @brief Restores the specified window.
1943 *
1944 * This function restores the specified window if it was previously iconified
1945 * (minimized). If the window is already restored, this function does nothing.
1946 *
1947 * If the specified window is a full screen window, the resolution chosen for
1948 * the window is restored on the selected monitor.
1949 *
1950 * @param[in] window The window to restore.
1951 *
1952 * @par Thread Safety
1953 * This function may only be called from the main thread.
1954 *
1955 * @sa @ref window_iconify
1956 * @sa glfwIconifyWindow
1957 *
1958 * @since Added in GLFW 2.1.
1959 *
1960 * @par
1961 * __GLFW 3:__ Added window handle parameter.
1962 *
1963 * @ingroup window
1964 */
1965GLFWAPI void glfwRestoreWindow(GLFWwindow* window);
1966
1967/*! @brief Makes the specified window visible.
1968 *
1969 * This function makes the specified window visible if it was previously
1970 * hidden. If the window is already visible or is in full screen mode, this
1971 * function does nothing.
1972 *
1973 * @param[in] window The window to make visible.
1974 *
1975 * @par Thread Safety
1976 * This function may only be called from the main thread.
1977 *
1978 * @sa @ref window_hide
1979 * @sa glfwHideWindow
1980 *
1981 * @since Added in GLFW 3.0.
1982 *
1983 * @ingroup window
1984 */
1985GLFWAPI void glfwShowWindow(GLFWwindow* window);
1986
1987/*! @brief Hides the specified window.
1988 *
1989 * This function hides the specified window if it was previously visible. If
1990 * the window is already hidden or is in full screen mode, this function does
1991 * nothing.
1992 *
1993 * @param[in] window The window to hide.
1994 *
1995 * @par Thread Safety
1996 * This function may only be called from the main thread.
1997 *
1998 * @sa @ref window_hide
1999 * @sa glfwShowWindow
2000 *
2001 * @since Added in GLFW 3.0.
2002 *
2003 * @ingroup window
2004 */
2005GLFWAPI void glfwHideWindow(GLFWwindow* window);
2006
2007/*! @brief Returns the monitor that the window uses for full screen mode.
2008 *
2009 * This function returns the handle of the monitor that the specified window is
2010 * in full screen on.
2011 *
2012 * @param[in] window The window to query.
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.
2022 *
2023 * @ingroup window
2024 */
2025GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window);
2026
2027/*! @brief Returns an attribute of the specified window.
2028 *
2029 * This function returns the value of an attribute of the specified window or
2030 * its OpenGL or OpenGL ES context.
2031 *
2032 * @param[in] window The window to query.
2033 * @param[in] attrib The [window attribute](@ref window_attribs) whose value to
2034 * return.
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`.
2045 *
2046 * @ingroup window
2047 */
2048GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib);
2049
2050/*! @brief Sets the user pointer of the specified window.
2051 *
2052 * This function sets the user-defined pointer of the specified window. The
2053 * current value is retained until the window is destroyed. The initial value
2054 * is `NULL`.
2055 *
2056 * @param[in] window The window whose pointer to set.
2057 * @param[in] pointer The new value.
2058 *
2059 * @par Thread Safety
2060 * This function may be called from any thread. Access is not synchronized.
2061 *
2062 * @sa @ref window_userptr
2063 * @sa glfwGetWindowUserPointer
2064 *
2065 * @since Added in GLFW 3.0.
2066 *
2067 * @ingroup window
2068 */
2069GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* window, void* pointer);
2070
2071/*! @brief Returns the user pointer of the specified window.
2072 *
2073 * This function returns the current value of the user-defined pointer of the
2074 * specified window. The initial value is `NULL`.
2075 *
2076 * @param[in] window The window whose pointer to return.
2077 *
2078 * @par Thread Safety
2079 * This function may be called from any thread. Access is not synchronized.
2080 *
2081 * @sa @ref window_userptr
2082 * @sa glfwSetWindowUserPointer
2083 *
2084 * @since Added in GLFW 3.0.
2085 *
2086 * @ingroup window
2087 */
2088GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window);
2089
2090/*! @brief Sets the position callback for the specified window.
2091 *
2092 * This function sets the position callback of the specified window, which is
2093 * called when the window is moved. The callback is provided with the screen
2094 * position of the upper-left corner of the client area of the window.
2095 *
2096 * @param[in] window The window whose callback to set.
2097 * @param[in] cbfun The new callback, or `NULL` to remove the currently set
2098 * callback.
2099 * @return The previously set callback, or `NULL` if no callback was set or the
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.
2108 *
2109 * @ingroup window
2110 */
2111GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* window, GLFWwindowposfun cbfun);
2112
2113/*! @brief Sets the size callback for the specified window.
2114 *
2115 * This function sets the size callback of the specified window, which is
2116 * called when the window is resized. The callback is provided with the size,
2117 * in screen coordinates, of the client area of the window.
2118 *
2119 * @param[in] window The window whose callback to set.
2120 * @param[in] cbfun The new callback, or `NULL` to remove the currently set
2121 * callback.
2122 * @return The previously set callback, or `NULL` if no callback was set or the
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.
2134 *
2135 * @ingroup window
2136 */
2137GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwindowsizefun cbfun);
2138
2139/*! @brief Sets the close callback for the specified window.
2140 *
2141 * This function sets the close callback of the specified window, which is
2142 * called when the user attempts to close the window, for example by clicking
2143 * the close widget in the title bar.
2144 *
2145 * The close flag is set before this callback is called, but you can modify it
2146 * at any time with @ref glfwSetWindowShouldClose.
2147 *
2148 * The close callback is not triggered by @ref glfwDestroyWindow.
2149 *
2150 * @param[in] window The window whose callback to set.
2151 * @param[in] cbfun The new callback, or `NULL` to remove the currently set
2152 * callback.
2153 * @return The previously set callback, or `NULL` if no callback was set or the
2154 * library had not been [initialized](@ref intro_init).
2155 *
2156 * @remarks __OS X:__ Selecting Quit from the application menu will
2157 * trigger the close callback for all windows.
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 *
2169 * @ingroup window
2170 */
2171GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwindowclosefun cbfun);
2172
2173/*! @brief Sets the refresh callback for the specified window.
2174 *
2175 * This function sets the refresh callback of the specified window, which is
2176 * called when the client area of the window needs to be redrawn, for example
2177 * if the window has been exposed after having been covered by another window.
2178 *
2179 * On compositing window systems such as Aero, Compiz or Aqua, where the window
2180 * contents are saved off-screen, this callback may be called only very
2181 * infrequently or never at all.
2182 *
2183 * @param[in] window The window whose callback to set.
2184 * @param[in] cbfun The new callback, or `NULL` to remove the currently set
2185 * callback.
2186 * @return The previously set callback, or `NULL` if no callback was set or the
2187 * library had not been [initialized](@ref intro_init).
2188 *
2189 * @par Thread Safety
2190 * This function may only be called from the main thread.
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.
2198 *
2199 * @ingroup window
2200 */
2201GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* window, GLFWwindowrefreshfun cbfun);
2202
2203/*! @brief Sets the focus callback for the specified window.
2204 *
2205 * This function sets the focus callback of the specified window, which is
2206 * called when the window gains or loses input focus.
2207 *
2208 * After the focus callback is called for a window that lost input focus,
2209 * synthetic key and mouse button release events will be generated for all such
2210 * that had been pressed. For more information, see @ref glfwSetKeyCallback
2211 * and @ref glfwSetMouseButtonCallback.
2212 *
2213 * @param[in] window The window whose callback to set.
2214 * @param[in] cbfun The new callback, or `NULL` to remove the currently set
2215 * callback.
2216 * @return The previously set callback, or `NULL` if no callback was set or the
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.
2225 *
2226 * @ingroup window
2227 */
2228GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwindowfocusfun cbfun);
2229
2230/*! @brief Sets the iconify callback for the specified window.
2231 *
2232 * This function sets the iconification callback of the specified window, which
2233 * is called when the window is iconified or restored.
2234 *
2235 * @param[in] window The window whose callback to set.
2236 * @param[in] cbfun The new callback, or `NULL` to remove the currently set
2237 * callback.
2238 * @return The previously set callback, or `NULL` if no callback was set or the
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.
2247 *
2248 * @ingroup window
2249 */
2250GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* window, GLFWwindowiconifyfun cbfun);
2251
2252/*! @brief Sets the framebuffer resize callback for the specified window.
2253 *
2254 * This function sets the framebuffer resize callback of the specified window,
2255 * which is called when the framebuffer of the specified window is resized.
2256 *
2257 * @param[in] window The window whose callback to set.
2258 * @param[in] cbfun The new callback, or `NULL` to remove the currently set
2259 * callback.
2260 * @return The previously set callback, or `NULL` if no callback was set or the
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.
2269 *
2270 * @ingroup window
2271 */
2272GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* window, GLFWframebuffersizefun cbfun);
2273
2274/*! @brief Processes all pending events.
2275 *
2276 * This function processes only those events that are already in the event
2277 * queue and then returns immediately. Processing events will cause the window
2278 * and input callbacks associated with those events to be called.
2279 *
2280 * On some platforms, a window move, resize or menu operation will cause event
2281 * processing to block. This is due to how event processing is designed on
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.
2285 *
2286 * On some platforms, certain events are sent directly to the application
2287 * without going through the event queue, causing callbacks to be called
2288 * outside of a call to one of the event processing functions.
2289 *
2290 * Event processing is not required for joystick input to work.
2291 *
2292 * @par Reentrancy
2293 * This function may not be called from a callback.
2294 *
2295 * @par Thread Safety
2296 * This function may only be called from the main thread.
2297 *
2298 * @sa @ref events
2299 * @sa glfwWaitEvents
2300 *
2301 * @since Added in GLFW 1.0.
2302 *
2303 * @ingroup window
2304 */
2305GLFWAPI void glfwPollEvents(void);
2306
2307/*! @brief Waits until events are queued and processes them.
2308 *
2309 * This function puts the calling thread to sleep until at least one event is
2310 * available in the event queue. Once one or more events are available,
2311 * it behaves exactly like @ref glfwPollEvents, i.e. the events in the queue
2312 * are processed and the function then returns immediately. Processing events
2313 * will cause the window and input callbacks associated with those events to be
2314 * called.
2315 *
2316 * Since not all events are associated with callbacks, this function may return
2317 * without a callback having been called even if you are monitoring all
2318 * callbacks.
2319 *
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.
2325 *
2326 * On some platforms, certain callbacks may be called outside of a call to one
2327 * of the event processing functions.
2328 *
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.
2332 *
2333 * Event processing is not required for joystick input to work.
2334 *
2335 * @par Reentrancy
2336 * This function may not be called from a callback.
2337 *
2338 * @par Thread Safety
2339 * This function may only be called from the main thread.
2340 *
2341 * @sa @ref events
2342 * @sa glfwPollEvents
2343 *
2344 * @since Added in GLFW 2.5.
2345 *
2346 * @ingroup window
2347 */
2348GLFWAPI void glfwWaitEvents(void);
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
2371/*! @brief Returns the value of an input option for the specified window.
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 *
2377 * @param[in] window The window to query.
2378 * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or
2379 * `GLFW_STICKY_MOUSE_BUTTONS`.
2380 *
2381 * @par Thread Safety
2382 * This function may only be called from the main thread.
2383 *
2384 * @sa glfwSetInputMode
2385 *
2386 * @since Added in GLFW 3.0.
2387 *
2388 * @ingroup input
2389 */
2390GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);
2391
2392/*! @brief Sets an input option for the specified window.
2393 *
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
2396 * `GLFW_STICKY_MOUSE_BUTTONS`.
2397 *
2398 * If the mode is `GLFW_CURSOR`, the value must be one of the following cursor
2399 * modes:
2400 * - `GLFW_CURSOR_NORMAL` makes the cursor visible and behaving normally.
2401 * - `GLFW_CURSOR_HIDDEN` makes the cursor invisible when it is over the client
2402 * area of the window but does not restrict the cursor from leaving.
2403 * - `GLFW_CURSOR_DISABLED` hides and grabs the cursor, providing virtual
2404 * and unlimited cursor movement. This is useful for implementing for
2405 * example 3D camera controls.
2406 *
2407 * If the mode is `GLFW_STICKY_KEYS`, the value must be either `GL_TRUE` to
2408 * enable sticky keys, or `GL_FALSE` to disable it. If sticky keys are
2409 * enabled, a key press will ensure that @ref glfwGetKey returns `GLFW_PRESS`
2410 * the next time it is called even if the key had been released before the
2411 * call. This is useful when you are only interested in whether keys have been
2412 * pressed but not when or in which order.
2413 *
2414 * If the mode is `GLFW_STICKY_MOUSE_BUTTONS`, the value must be either
2415 * `GL_TRUE` to enable sticky mouse buttons, or `GL_FALSE` to disable it. If
2416 * sticky mouse buttons are enabled, a mouse button press will ensure that @ref
2417 * glfwGetMouseButton returns `GLFW_PRESS` the next time it is called even if
2418 * the mouse button had been released before the call. This is useful when you
2419 * are only interested in whether mouse buttons have been pressed but not when
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.
2429 *
2430 * @sa glfwGetInputMode
2431 *
2432 * @since Added in GLFW 3.0. Replaces `glfwEnable` and `glfwDisable`.
2433 *
2434 * @ingroup input
2435 */
2436GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value);
2437
2438/*! @brief Returns the last reported state of a keyboard key for the specified
2439 * window.
2440 *
2441 * This function returns the last state reported for the specified key to the
2442 * specified window. The returned state is one of `GLFW_PRESS` or
2443 * `GLFW_RELEASE`. The higher-level action `GLFW_REPEAT` is only reported to
2444 * the key callback.
2445 *
2446 * If the `GLFW_STICKY_KEYS` input mode is enabled, this function returns
2447 * `GLFW_PRESS` the first time you call it for a key that was pressed, even if
2448 * that key has already been released.
2449 *
2450 * The key functions deal with physical keys, with [key tokens](@ref keys)
2451 * named after their use on the standard US keyboard layout. If you want to
2452 * input text, use the Unicode character callback instead.
2453 *
2454 * The [modifier key bit masks](@ref mods) are not key tokens and cannot be
2455 * used with this function.
2456 *
2457 * @param[in] window The desired window.
2458 * @param[in] key The desired [keyboard key](@ref keys). `GLFW_KEY_UNKNOWN` is
2459 * not a valid key for this function.
2460 * @return One of `GLFW_PRESS` or `GLFW_RELEASE`.
2461 *
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.
2471 *
2472 * @ingroup input
2473 */
2474GLFWAPI int glfwGetKey(GLFWwindow* window, int key);
2475
2476/*! @brief Returns the last reported state of a mouse button for the specified
2477 * window.
2478 *
2479 * This function returns the last state reported for the specified mouse button
2480 * to the specified window. The returned state is one of `GLFW_PRESS` or
2481 * `GLFW_RELEASE`.
2482 *
2483 * If the `GLFW_STICKY_MOUSE_BUTTONS` input mode is enabled, this function
2484 * `GLFW_PRESS` the first time you call it for a mouse button that was pressed,
2485 * even if that mouse button has already been released.
2486 *
2487 * @param[in] window The desired window.
2488 * @param[in] button The desired [mouse button](@ref buttons).
2489 * @return One of `GLFW_PRESS` or `GLFW_RELEASE`.
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 *
2501 * @ingroup input
2502 */
2503GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button);
2504
2505/*! @brief Retrieves the position of the cursor relative to the client area of
2506 * the window.
2507 *
2508 * This function returns the position of the cursor, in screen coordinates,
2509 * relative to the upper-left corner of the client area of the specified
2510 * window.
2511 *
2512 * If the cursor is disabled (with `GLFW_CURSOR_DISABLED`) then the cursor
2513 * position is unbounded and limited only by the minimum and maximum values of
2514 * a `double`.
2515 *
2516 * The coordinate can be converted to their integer equivalents with the
2517 * `floor` function. Casting directly to an integer type works for positive
2518 * coordinates, but fails for negative ones.
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 *
2523 * @param[in] window The desired window.
2524 * @param[out] xpos Where to store the cursor x-coordinate, relative to the
2525 * left edge of the client area, or `NULL`.
2526 * @param[out] ypos Where to store the cursor y-coordinate, relative to the to
2527 * top edge of the client area, or `NULL`.
2528 *
2529 * @par Thread Safety
2530 * This function may only be called from the main thread.
2531 *
2532 * @sa @ref cursor_pos
2533 * @sa glfwSetCursorPos
2534 *
2535 * @since Added in GLFW 3.0. Replaces `glfwGetMousePos`.
2536 *
2537 * @ingroup input
2538 */
2539GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos);
2540
2541/*! @brief Sets the position of the cursor, relative to the client area of the
2542 * window.
2543 *
2544 * This function sets the position, in screen coordinates, of the cursor
2545 * relative to the upper-left corner of the client area of the specified
2546 * window. The window must have input focus. If the window does not have
2547 * input focus when this function is called, it fails silently.
2548 *
2549 * __Do not use this function__ to implement things like camera controls. GLFW
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
2556 * a `double`.
2557 *
2558 * @param[in] window The desired window.
2559 * @param[in] xpos The desired x-coordinate, relative to the left edge of the
2560 * client area.
2561 * @param[in] ypos The desired y-coordinate, relative to the top edge of the
2562 * client area.
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
2572 * @sa glfwGetCursorPos
2573 *
2574 * @since Added in GLFW 3.0. Replaces `glfwSetMousePos`.
2575 *
2576 * @ingroup input
2577 */
2578GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos);
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
2693/*! @brief Sets the key callback.
2694 *
2695 * This function sets the key callback of the specified window, which is called
2696 * when a key is pressed, repeated or released.
2697 *
2698 * The key functions deal with physical keys, with layout independent
2699 * [key tokens](@ref keys) named after their values in the standard US keyboard
2700 * layout. If you want to input text, use the
2701 * [character callback](@ref glfwSetCharCallback) instead.
2702 *
2703 * When a window loses input focus, it will generate synthetic key release
2704 * events for all pressed keys. You can tell these events from user-generated
2705 * events by the fact that the synthetic ones are generated after the focus
2706 * loss event has been processed, i.e. after the
2707 * [window focus callback](@ref glfwSetWindowFocusCallback) has been called.
2708 *
2709 * The scancode of a key is specific to that platform or sometimes even to that
2710 * machine. Scancodes are intended to allow users to bind keys that don't have
2711 * a GLFW key token. Such keys have `key` set to `GLFW_KEY_UNKNOWN`, their
2712 * state is not saved and so it cannot be queried with @ref glfwGetKey.
2713 *
2714 * Sometimes GLFW needs to generate synthetic key events, in which case the
2715 * scancode may be zero.
2716 *
2717 * @param[in] window The window whose callback to set.
2718 * @param[in] cbfun The new key callback, or `NULL` to remove the currently
2719 * set callback.
2720 * @return The previously set callback, or `NULL` if no callback was set or the
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.
2732 *
2733 * @ingroup input
2734 */
2735GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun cbfun);
2736
2737/*! @brief Sets the Unicode character callback.
2738 *
2739 * This function sets the character callback of the specified window, which is
2740 * called when a Unicode character is input.
2741 *
2742 * The character callback is intended for Unicode text input. As it deals with
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
2789 * [key callback](@ref glfwSetKeyCallback) instead.
2790 *
2791 * @param[in] window The window whose callback to set.
2792 * @param[in] cbfun The new callback, or `NULL` to remove the currently set
2793 * callback.
2794 * @return The previously set callback, or `NULL` if no callback was set or an
2795 * error occurred.
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 *
2804 * @ingroup input
2805 */
2806GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmodsfun cbfun);
2807
2808/*! @brief Sets the mouse button callback.
2809 *
2810 * This function sets the mouse button callback of the specified window, which
2811 * is called when a mouse button is pressed or released.
2812 *
2813 * When a window loses input focus, it will generate synthetic mouse button
2814 * release events for all pressed mouse buttons. You can tell these events
2815 * from user-generated events by the fact that the synthetic ones are generated
2816 * after the focus loss event has been processed, i.e. after the
2817 * [window focus callback](@ref glfwSetWindowFocusCallback) has been called.
2818 *
2819 * @param[in] window The window whose callback to set.
2820 * @param[in] cbfun The new callback, or `NULL` to remove the currently set
2821 * callback.
2822 * @return The previously set callback, or `NULL` if no callback was set or the
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.
2834 *
2835 * @ingroup input
2836 */
2837GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* window, GLFWmousebuttonfun cbfun);
2838
2839/*! @brief Sets the cursor position callback.
2840 *
2841 * This function sets the cursor position callback of the specified window,
2842 * which is called when the cursor is moved. The callback is provided with the
2843 * position, in screen coordinates, relative to the upper-left corner of the
2844 * client area of the window.
2845 *
2846 * @param[in] window The window whose callback to set.
2847 * @param[in] cbfun The new callback, or `NULL` to remove the currently set
2848 * callback.
2849 * @return The previously set callback, or `NULL` if no callback was set or the
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`.
2858 *
2859 * @ingroup input
2860 */
2861GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* window, GLFWcursorposfun cbfun);
2862
2863/*! @brief Sets the cursor enter/exit callback.
2864 *
2865 * This function sets the cursor boundary crossing callback of the specified
2866 * window, which is called when the cursor enters or leaves the client area of
2867 * the window.
2868 *
2869 * @param[in] window The window whose callback to set.
2870 * @param[in] cbfun The new callback, or `NULL` to remove the currently set
2871 * callback.
2872 * @return The previously set callback, or `NULL` if no callback was set or the
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.
2881 *
2882 * @ingroup input
2883 */
2884GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* window, GLFWcursorenterfun cbfun);
2885
2886/*! @brief Sets the scroll callback.
2887 *
2888 * This function sets the scroll callback of the specified window, which is
2889 * called when a scrolling device is used, such as a mouse wheel or scrolling
2890 * area of a touchpad.
2891 *
2892 * The scroll callback receives all scrolling input, like that from a mouse
2893 * wheel or a touchpad scrolling area.
2894 *
2895 * @param[in] window The window whose callback to set.
2896 * @param[in] cbfun The new scroll callback, or `NULL` to remove the currently
2897 * set callback.
2898 * @return The previously set callback, or `NULL` if no callback was set or the
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`.
2907 *
2908 * @ingroup input
2909 */
2910GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun cbfun);
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
2939/*! @brief Returns whether the specified joystick is present.
2940 *
2941 * This function returns whether the specified joystick is present.
2942 *
2943 * @param[in] joy The [joystick](@ref joysticks) to query.
2944 * @return `GL_TRUE` if the joystick is present, or `GL_FALSE` otherwise.
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 *
2953 * @ingroup input
2954 */
2955GLFWAPI int glfwJoystickPresent(int joy);
2956
2957/*! @brief Returns the values of all axes of the specified joystick.
2958 *
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.
2961 *
2962 * @param[in] joy The [joystick](@ref joysticks) to query.
2963 * @param[out] count Where to store the number of axis values in the returned
2964 * array. This is set to zero if an error occurred.
2965 * @return An array of axis values, or `NULL` if the joystick is not present.
2966 *
2967 * @par Pointer Lifetime
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.
2974 *
2975 * @sa @ref joystick_axis
2976 *
2977 * @since Added in GLFW 3.0. Replaces `glfwGetJoystickPos`.
2978 *
2979 * @ingroup input
2980 */
2981GLFWAPI const float* glfwGetJoystickAxes(int joy, int* count);
2982
2983/*! @brief Returns the state of all buttons of the specified joystick.
2984 *
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`.
2987 *
2988 * @param[in] joy The [joystick](@ref joysticks) to query.
2989 * @param[out] count Where to store the number of button states in the returned
2990 * array. This is set to zero if an error occurred.
2991 * @return An array of button states, or `NULL` if the joystick is not present.
2992 *
2993 * @par Pointer Lifetime
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
3002 *
3003 * @since Added in GLFW 2.2.
3004 *
3005 * @par
3006 * __GLFW 3:__ Changed to return a dynamic array.
3007 *
3008 * @ingroup input
3009 */
3010GLFWAPI const unsigned char* glfwGetJoystickButtons(int joy, int* count);
3011
3012/*! @brief Returns the name of the specified joystick.
3013 *
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.
3017 *
3018 * @param[in] joy The [joystick](@ref joysticks) to query.
3019 * @return The UTF-8 encoded name of the joystick, or `NULL` if the joystick
3020 * is not present.
3021 *
3022 * @par Pointer Lifetime
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.
3029 *
3030 * @sa @ref joystick_name
3031 *
3032 * @since Added in GLFW 3.0.
3033 *
3034 * @ingroup input
3035 */
3036GLFWAPI const char* glfwGetJoystickName(int joy);
3037
3038/*! @brief Sets the clipboard to the specified string.
3039 *
3040 * This function sets the system clipboard to the specified, UTF-8 encoded
3041 * string.
3042 *
3043 * @param[in] window The window that will own the clipboard contents.
3044 * @param[in] string A UTF-8 encoded string.
3045 *
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.
3051 *
3052 * @sa @ref clipboard
3053 * @sa glfwGetClipboardString
3054 *
3055 * @since Added in GLFW 3.0.
3056 *
3057 * @ingroup input
3058 */
3059GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string);
3060
3061/*! @brief Returns the contents of the clipboard as a string.
3062 *
3063 * This function returns the contents of the system clipboard, if it contains
3064 * or is convertible to a UTF-8 encoded string.
3065 *
3066 * @param[in] window The window that will request the clipboard contents.
3067 * @return The contents of the clipboard as a UTF-8 encoded string, or `NULL`
3068 * if an [error](@ref error_handling) occurred.
3069 *
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.
3075 *
3076 * @par Thread Safety
3077 * This function may only be called from the main thread.
3078 *
3079 * @sa @ref clipboard
3080 * @sa glfwSetClipboardString
3081 *
3082 * @since Added in GLFW 3.0.
3083 *
3084 * @ingroup input
3085 */
3086GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window);
3087
3088/*! @brief Returns the value of the GLFW timer.
3089 *
3090 * This function returns the value of the GLFW timer. Unless the timer has
3091 * been set using @ref glfwSetTime, the timer measures time elapsed since GLFW
3092 * was initialized.
3093 *
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.
3103 *
3104 * @sa @ref time
3105 *
3106 * @since Added in GLFW 1.0.
3107 *
3108 * @ingroup input
3109 */
3110GLFWAPI double glfwGetTime(void);
3111
3112/*! @brief Sets the GLFW timer.
3113 *
3114 * This function sets the value of the GLFW timer. It then continues to count
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.
3117 *
3118 * @param[in] time The new value, in seconds.
3119 *
3120 * @remarks The upper limit of the timer is calculated as
3121 * floor((2<sup>64</sup> - 1) / 10<sup>9</sup>) and is due to implementations
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.
3130 *
3131 * @ingroup input
3132 */
3133GLFWAPI void glfwSetTime(double time);
3134
3135/*! @brief Makes the context of the specified window current for the calling
3136 * thread.
3137 *
3138 * This function makes the OpenGL or OpenGL ES context of the specified window
3139 * current on the calling thread. A context can only be made current on
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.
3147 *
3148 * @param[in] window The window whose context to make current, or `NULL` to
3149 * detach the current context.
3150 *
3151 * @par Thread Safety
3152 * This function may be called from any thread.
3153 *
3154 * @sa @ref context_current
3155 * @sa glfwGetCurrentContext
3156 *
3157 * @since Added in GLFW 3.0.
3158 *
3159 * @ingroup context
3160 */
3161GLFWAPI void glfwMakeContextCurrent(GLFWwindow* window);
3162
3163/*! @brief Returns the window whose context is current on the calling thread.
3164 *
3165 * This function returns the window whose OpenGL or OpenGL ES context is
3166 * current on the calling thread.
3167 *
3168 * @return The window whose context is current, or `NULL` if no window's
3169 * context is current.
3170 *
3171 * @par Thread Safety
3172 * This function may be called from any thread.
3173 *
3174 * @sa @ref context_current
3175 * @sa glfwMakeContextCurrent
3176 *
3177 * @since Added in GLFW 3.0.
3178 *
3179 * @ingroup context
3180 */
3181GLFWAPI GLFWwindow* glfwGetCurrentContext(void);
3182
3183/*! @brief Swaps the front and back buffers of the specified window.
3184 *
3185 * This function swaps the front and back buffers of the specified window. If
3186 * the swap interval is greater than zero, the GPU driver waits the specified
3187 * number of screen updates before swapping the buffers.
3188 *
3189 * @param[in] window The window whose buffers to swap.
3190 *
3191 * @par Thread Safety
3192 * This function may be called from any thread.
3193 *
3194 * @sa @ref buffer_swap
3195 * @sa glfwSwapInterval
3196 *
3197 * @since Added in GLFW 1.0.
3198 *
3199 * @par
3200 * __GLFW 3:__ Added window handle parameter.
3201 *
3202 * @ingroup window
3203 */
3204GLFWAPI void glfwSwapBuffers(GLFWwindow* window);
3205
3206/*! @brief Sets the swap interval for the current context.
3207 *
3208 * This function sets the swap interval for the current context, i.e. the
3209 * number of screen updates to wait from the time @ref glfwSwapBuffers was
3210 * called before swapping the buffers and returning. This is sometimes called
3211 * _vertical synchronization_, _vertical retrace synchronization_ or just
3212 * _vsync_.
3213 *
3214 * Contexts that support either of the `WGL_EXT_swap_control_tear` and
3215 * `GLX_EXT_swap_control_tear` extensions also accept negative swap intervals,
3216 * which allow the driver to swap even if a frame arrives a little bit late.
3217 * You can check for the presence of these extensions using @ref
3218 * glfwExtensionSupported. For more information about swap tearing, see the
3219 * extension specifications.
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 *
3224 * @param[in] interval The minimum number of screen updates to wait for
3225 * until the buffers are swapped by @ref glfwSwapBuffers.
3226 *
3227 * @remarks This function is not called during context creation, leaving the
3228 * swap interval set to whatever is the default on that platform. This is done
3229 * because some swap interval extensions used by GLFW do not allow the swap
3230 * interval to be reset to zero once it has been set to a non-zero value.
3231 *
3232 * @remarks Some GPU drivers do not honor the requested swap interval, either
3233 * because of a user setting that overrides the application's request or due to
3234 * bugs in the driver.
3235 *
3236 * @par Thread Safety
3237 * This function may be called from any thread.
3238 *
3239 * @sa @ref buffer_swap
3240 * @sa glfwSwapBuffers
3241 *
3242 * @since Added in GLFW 1.0.
3243 *
3244 * @ingroup context
3245 */
3246GLFWAPI void glfwSwapInterval(int interval);
3247
3248/*! @brief Returns whether the specified extension is available.
3249 *
3250 * This function returns whether the specified
3251 * [client API extension](@ref context_glext) is supported by the current
3252 * OpenGL or OpenGL ES context. It searches both for OpenGL and OpenGL ES
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.
3262 *
3263 * @param[in] extension The ASCII encoded name of the extension.
3264 * @return `GL_TRUE` if the extension is available, or `GL_FALSE` otherwise.
3265 *
3266 * @par Thread Safety
3267 * This function may be called from any thread.
3268 *
3269 * @sa @ref context_glext
3270 * @sa glfwGetProcAddress
3271 *
3272 * @since Added in GLFW 1.0.
3273 *
3274 * @ingroup context
3275 */
3276GLFWAPI int glfwExtensionSupported(const char* extension);
3277
3278/*! @brief Returns the address of the specified function for the current
3279 * context.
3280 *
3281 * This function returns the address of the specified
3282 * [core or extension function](@ref context_glext), if it is supported
3283 * by the current context.
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 *
3288 * @param[in] procname The ASCII encoded name of the function.
3289 * @return The address of the function, or `NULL` if the function is
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.
3305 *
3306 * @sa @ref context_glext
3307 * @sa glfwExtensionSupported
3308 *
3309 * @since Added in GLFW 1.0.
3310 *
3311 * @ingroup context
3312 */
3313GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname);
3314
3315
3316/*************************************************************************
3317 * Global definition cleanup
3318 *************************************************************************/
3319
3320/* ------------------- BEGIN SYSTEM/COMPILER SPECIFIC -------------------- */
3321
3322#ifdef GLFW_WINGDIAPI_DEFINED
3323 #undef WINGDIAPI
3324 #undef GLFW_WINGDIAPI_DEFINED
3325#endif
3326
3327#ifdef GLFW_CALLBACK_DEFINED
3328 #undef CALLBACK
3329 #undef GLFW_CALLBACK_DEFINED
3330#endif
3331
3332/* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */
3333
3334
3335#ifdef __cplusplus
3336}
3337#endif
3338
3339#endif /* _glfw3_h_ */
3340
diff --git a/externals/glfw-3.1.1.bin/include/GLFW/glfw3native.h b/externals/glfw-3.1.1.bin/include/GLFW/glfw3native.h
deleted file mode 100644
index b3ce7482d..000000000
--- a/externals/glfw-3.1.1.bin/include/GLFW/glfw3native.h
+++ /dev/null
@@ -1,356 +0,0 @@
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
deleted file mode 100644
index 84c2e1bc2..000000000
--- a/externals/glfw-3.1.1.bin/lib-mingw-i686/glfw3.dll
+++ /dev/null
Binary files differ
diff --git a/externals/glfw-3.1.1.bin/lib-mingw-i686/glfw3dll.a b/externals/glfw-3.1.1.bin/lib-mingw-i686/glfw3dll.a
deleted file mode 100644
index dc593d062..000000000
--- a/externals/glfw-3.1.1.bin/lib-mingw-i686/glfw3dll.a
+++ /dev/null
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
deleted file mode 100644
index 59eae0868..000000000
--- a/externals/glfw-3.1.1.bin/lib-mingw-i686/libglfw3.a
+++ /dev/null
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
deleted file mode 100644
index 437918eda..000000000
--- a/externals/glfw-3.1.1.bin/lib-mingw-x86_64/glfw3.dll
+++ /dev/null
Binary files differ
diff --git a/externals/glfw-3.1.1.bin/lib-mingw-x86_64/glfw3dll.a b/externals/glfw-3.1.1.bin/lib-mingw-x86_64/glfw3dll.a
deleted file mode 100644
index be08358ab..000000000
--- a/externals/glfw-3.1.1.bin/lib-mingw-x86_64/glfw3dll.a
+++ /dev/null
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
deleted file mode 100644
index e9e7be933..000000000
--- a/externals/glfw-3.1.1.bin/lib-mingw-x86_64/libglfw3.a
+++ /dev/null
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
deleted file mode 100644
index f15748d7a..000000000
--- a/externals/glfw-3.1.1.bin/lib-msvc_v120-Win32/glfw3.dll
+++ /dev/null
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
deleted file mode 100644
index 6a5a85a1d..000000000
--- a/externals/glfw-3.1.1.bin/lib-msvc_v120-Win32/glfw3.lib
+++ /dev/null
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
deleted file mode 100644
index 248a5cadf..000000000
--- a/externals/glfw-3.1.1.bin/lib-msvc_v120-Win32/glfw3dll.lib
+++ /dev/null
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
deleted file mode 100644
index cba172f64..000000000
--- a/externals/glfw-3.1.1.bin/lib-msvc_v120-x64/glfw3.dll
+++ /dev/null
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
deleted file mode 100644
index efdd64332..000000000
--- a/externals/glfw-3.1.1.bin/lib-msvc_v120-x64/glfw3.lib
+++ /dev/null
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
deleted file mode 100644
index 49ed2bb67..000000000
--- a/externals/glfw-3.1.1.bin/lib-msvc_v120-x64/glfw3dll.lib
+++ /dev/null
Binary files differ
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index cb09f3cd1..de4fe716a 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -4,7 +4,8 @@ include_directories(.)
4add_subdirectory(common) 4add_subdirectory(common)
5add_subdirectory(core) 5add_subdirectory(core)
6add_subdirectory(video_core) 6add_subdirectory(video_core)
7if (ENABLE_GLFW) 7add_subdirectory(audio_core)
8if (ENABLE_SDL2)
8 add_subdirectory(citra) 9 add_subdirectory(citra)
9endif() 10endif()
10if (ENABLE_QT) 11if (ENABLE_QT)
diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt
new file mode 100644
index 000000000..b0d1c7eb6
--- /dev/null
+++ b/src/audio_core/CMakeLists.txt
@@ -0,0 +1,16 @@
1set(SRCS
2 audio_core.cpp
3 hle/dsp.cpp
4 hle/pipe.cpp
5 )
6
7set(HEADERS
8 audio_core.h
9 hle/dsp.h
10 hle/pipe.h
11 sink.h
12 )
13
14create_directory_groups(${SRCS} ${HEADERS})
15
16add_library(audio_core STATIC ${SRCS} ${HEADERS}) \ No newline at end of file
diff --git a/src/audio_core/audio_core.cpp b/src/audio_core/audio_core.cpp
new file mode 100644
index 000000000..894f46990
--- /dev/null
+++ b/src/audio_core/audio_core.cpp
@@ -0,0 +1,53 @@
1// Copyright 2016 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "audio_core/audio_core.h"
6#include "audio_core/hle/dsp.h"
7
8#include "core/core_timing.h"
9#include "core/hle/kernel/vm_manager.h"
10#include "core/hle/service/dsp_dsp.h"
11
12namespace AudioCore {
13
14// Audio Ticks occur about every 5 miliseconds.
15static int tick_event; ///< CoreTiming event
16static constexpr u64 audio_frame_ticks = 1310252ull; ///< Units: ARM11 cycles
17
18static void AudioTickCallback(u64 /*userdata*/, int cycles_late) {
19 if (DSP::HLE::Tick()) {
20 // HACK: We're not signaling the interrups when they should be, but just firing them all off together.
21 // It should be only (interrupt_id = 2, channel_id = 2) that's signalled here.
22 // TODO(merry): Understand when the other interrupts are fired.
23 DSP_DSP::SignalAllInterrupts();
24 }
25
26 // Reschedule recurrent event
27 CoreTiming::ScheduleEvent(audio_frame_ticks - cycles_late, tick_event);
28}
29
30/// Initialise Audio
31void Init() {
32 DSP::HLE::Init();
33
34 tick_event = CoreTiming::RegisterEvent("AudioCore::tick_event", AudioTickCallback);
35 CoreTiming::ScheduleEvent(audio_frame_ticks, tick_event);
36}
37
38/// Add DSP address spaces to Process's address space.
39void AddAddressSpace(Kernel::VMManager& address_space) {
40 auto r0_vma = address_space.MapBackingMemory(DSP::HLE::region0_base, reinterpret_cast<u8*>(&DSP::HLE::g_region0), sizeof(DSP::HLE::SharedMemory), Kernel::MemoryState::IO).MoveFrom();
41 address_space.Reprotect(r0_vma, Kernel::VMAPermission::ReadWrite);
42
43 auto r1_vma = address_space.MapBackingMemory(DSP::HLE::region1_base, reinterpret_cast<u8*>(&DSP::HLE::g_region1), sizeof(DSP::HLE::SharedMemory), Kernel::MemoryState::IO).MoveFrom();
44 address_space.Reprotect(r1_vma, Kernel::VMAPermission::ReadWrite);
45}
46
47/// Shutdown Audio
48void Shutdown() {
49 CoreTiming::UnscheduleEvent(tick_event, 0);
50 DSP::HLE::Shutdown();
51}
52
53} //namespace
diff --git a/src/audio_core/audio_core.h b/src/audio_core/audio_core.h
new file mode 100644
index 000000000..64c330914
--- /dev/null
+++ b/src/audio_core/audio_core.h
@@ -0,0 +1,26 @@
1// Copyright 2016 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7namespace Kernel {
8class VMManager;
9}
10
11namespace AudioCore {
12
13constexpr int num_sources = 24;
14constexpr int samples_per_frame = 160; ///< Samples per audio frame at native sample rate
15constexpr int native_sample_rate = 32728; ///< 32kHz
16
17/// Initialise Audio Core
18void Init();
19
20/// Add DSP address spaces to a Process.
21void AddAddressSpace(Kernel::VMManager& vm_manager);
22
23/// Shutdown Audio Core
24void Shutdown();
25
26} // namespace
diff --git a/src/audio_core/hle/dsp.cpp b/src/audio_core/hle/dsp.cpp
new file mode 100644
index 000000000..c89356edc
--- /dev/null
+++ b/src/audio_core/hle/dsp.cpp
@@ -0,0 +1,42 @@
1// Copyright 2016 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "audio_core/hle/dsp.h"
6#include "audio_core/hle/pipe.h"
7
8namespace DSP {
9namespace HLE {
10
11SharedMemory g_region0;
12SharedMemory g_region1;
13
14void Init() {
15 DSP::HLE::ResetPipes();
16}
17
18void Shutdown() {
19}
20
21bool Tick() {
22 return true;
23}
24
25SharedMemory& CurrentRegion() {
26 // The region with the higher frame counter is chosen unless there is wraparound.
27
28 if (g_region0.frame_counter == 0xFFFFu && g_region1.frame_counter != 0xFFFEu) {
29 // Wraparound has occured.
30 return g_region1;
31 }
32
33 if (g_region1.frame_counter == 0xFFFFu && g_region0.frame_counter != 0xFFFEu) {
34 // Wraparound has occured.
35 return g_region0;
36 }
37
38 return (g_region0.frame_counter > g_region1.frame_counter) ? g_region0 : g_region1;
39}
40
41} // namespace HLE
42} // namespace DSP
diff --git a/src/audio_core/hle/dsp.h b/src/audio_core/hle/dsp.h
new file mode 100644
index 000000000..376436c29
--- /dev/null
+++ b/src/audio_core/hle/dsp.h
@@ -0,0 +1,539 @@
1// Copyright 2016 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 <cstddef>
8#include <type_traits>
9
10#include "audio_core/audio_core.h"
11
12#include "common/bit_field.h"
13#include "common/common_funcs.h"
14#include "common/common_types.h"
15#include "common/swap.h"
16
17namespace DSP {
18namespace HLE {
19
20// The application-accessible region of DSP memory consists of two parts.
21// Both are marked as IO and have Read/Write permissions.
22//
23// First Region: 0x1FF50000 (Size: 0x8000)
24// Second Region: 0x1FF70000 (Size: 0x8000)
25//
26// The DSP reads from each region alternately based on the frame counter for each region much like a
27// double-buffer. The frame counter is located as the very last u16 of each region and is incremented
28// each audio tick.
29
30struct SharedMemory;
31
32constexpr VAddr region0_base = 0x1FF50000;
33extern SharedMemory g_region0;
34
35constexpr VAddr region1_base = 0x1FF70000;
36extern SharedMemory g_region1;
37
38/**
39 * The DSP is native 16-bit. The DSP also appears to be big-endian. When reading 32-bit numbers from
40 * its memory regions, the higher and lower 16-bit halves are swapped compared to the little-endian
41 * layout of the ARM11. Hence from the ARM11's point of view the memory space appears to be
42 * middle-endian.
43 *
44 * Unusually this does not appear to be an issue for floating point numbers. The DSP makes the more
45 * sensible choice of keeping that little-endian. There are also some exceptions such as the
46 * IntermediateMixSamples structure, which is little-endian.
47 *
48 * This struct implements the conversion to and from this middle-endianness.
49 */
50struct u32_dsp {
51 u32_dsp() = default;
52 operator u32() const {
53 return Convert(storage);
54 }
55 void operator=(u32 new_value) {
56 storage = Convert(new_value);
57 }
58private:
59 static constexpr u32 Convert(u32 value) {
60 return (value << 16) | (value >> 16);
61 }
62 u32_le storage;
63};
64#if (__GNUC__ >= 5) || defined(__clang__) || defined(_MSC_VER)
65static_assert(std::is_trivially_copyable<u32_dsp>::value, "u32_dsp isn't trivially copyable");
66#endif
67
68// There are 15 structures in each memory region. A table of them in the order they appear in memory
69// is presented below:
70//
71// # First Region DSP Address Purpose Control
72// 5 0x8400 DSP Status DSP
73// 9 0x8410 DSP Debug Info DSP
74// 6 0x8540 Final Mix Samples DSP
75// 2 0x8680 Source Status [24] DSP
76// 8 0x8710 Compressor Table Application
77// 4 0x9430 DSP Configuration Application
78// 7 0x9492 Intermediate Mix Samples DSP + App
79// 1 0x9E92 Source Configuration [24] Application
80// 3 0xA792 Source ADPCM Coefficients [24] Application
81// 10 0xA912 Surround Sound Related
82// 11 0xAA12 Surround Sound Related
83// 12 0xAAD2 Surround Sound Related
84// 13 0xAC52 Surround Sound Related
85// 14 0xAC5C Surround Sound Related
86// 0 0xBFFF Frame Counter Application
87//
88// #: This refers to the order in which they appear in the DspPipe::Audio DSP pipe.
89// See also: DSP::HLE::PipeRead.
90//
91// Note that the above addresses do vary slightly between audio firmwares observed; the addresses are
92// not fixed in stone. The addresses above are only an examplar; they're what this implementation
93// does and provides to applications.
94//
95// Application requests the DSP service to convert DSP addresses into ARM11 virtual addresses using the
96// ConvertProcessAddressFromDspDram service call. Applications seem to derive the addresses for the
97// second region via:
98// second_region_dsp_addr = first_region_dsp_addr | 0x10000
99//
100// Applications maintain most of its own audio state, the memory region is used mainly for
101// communication and not storage of state.
102//
103// In the documentation below, filter and effect transfer functions are specified in the z domain.
104// (If you are more familiar with the Laplace transform, z = exp(sT). The z domain is the digital
105// frequency domain, just like how the s domain is the analog frequency domain.)
106
107#define INSERT_PADDING_DSPWORDS(num_words) INSERT_PADDING_BYTES(2 * (num_words))
108
109// GCC versions < 5.0 do not implement std::is_trivially_copyable.
110// Excluding MSVC because it has weird behaviour for std::is_trivially_copyable.
111#if (__GNUC__ >= 5) || defined(__clang__)
112 #define ASSERT_DSP_STRUCT(name, size) \
113 static_assert(std::is_standard_layout<name>::value, "DSP structure " #name " doesn't use standard layout"); \
114 static_assert(std::is_trivially_copyable<name>::value, "DSP structure " #name " isn't trivially copyable"); \
115 static_assert(sizeof(name) == (size), "Unexpected struct size for DSP structure " #name)
116#else
117 #define ASSERT_DSP_STRUCT(name, size) \
118 static_assert(std::is_standard_layout<name>::value, "DSP structure " #name " doesn't use standard layout"); \
119 static_assert(sizeof(name) == (size), "Unexpected struct size for DSP structure " #name)
120#endif
121
122struct SourceConfiguration {
123 struct Configuration {
124 /// These dirty flags are set by the application when it updates the fields in this struct.
125 /// The DSP clears these each audio frame.
126 union {
127 u32_le dirty_raw;
128
129 BitField<2, 1, u32_le> adpcm_coefficients_dirty;
130 BitField<3, 1, u32_le> partial_embedded_buffer_dirty; ///< Tends to be set when a looped buffer is queued.
131
132 BitField<16, 1, u32_le> enable_dirty;
133 BitField<17, 1, u32_le> interpolation_dirty;
134 BitField<18, 1, u32_le> rate_multiplier_dirty;
135 BitField<19, 1, u32_le> buffer_queue_dirty;
136 BitField<20, 1, u32_le> loop_related_dirty;
137 BitField<21, 1, u32_le> play_position_dirty; ///< Tends to also be set when embedded buffer is updated.
138 BitField<22, 1, u32_le> filters_enabled_dirty;
139 BitField<23, 1, u32_le> simple_filter_dirty;
140 BitField<24, 1, u32_le> biquad_filter_dirty;
141 BitField<25, 1, u32_le> gain_0_dirty;
142 BitField<26, 1, u32_le> gain_1_dirty;
143 BitField<27, 1, u32_le> gain_2_dirty;
144 BitField<28, 1, u32_le> sync_dirty;
145 BitField<29, 1, u32_le> reset_flag;
146
147 BitField<31, 1, u32_le> embedded_buffer_dirty;
148 };
149
150 // Gain control
151
152 /**
153 * Gain is between 0.0-1.0. This determines how much will this source appear on
154 * each of the 12 channels that feed into the intermediate mixers.
155 * Each of the three intermediate mixers is fed two left and two right channels.
156 */
157 float_le gain[3][4];
158
159 // Interpolation
160
161 /// Multiplier for sample rate. Resampling occurs with the selected interpolation method.
162 float_le rate_multiplier;
163
164 enum class InterpolationMode : u8 {
165 None = 0,
166 Linear = 1,
167 Polyphase = 2
168 };
169
170 InterpolationMode interpolation_mode;
171 INSERT_PADDING_BYTES(1); ///< Interpolation related
172
173 // Filters
174
175 /**
176 * This is the simplest normalized first-order digital recursive filter.
177 * The transfer function of this filter is:
178 * H(z) = b0 / (1 + a1 z^-1)
179 * Values are signed fixed point with 15 fractional bits.
180 */
181 struct SimpleFilter {
182 s16_le b0;
183 s16_le a1;
184 };
185
186 /**
187 * This is a normalised biquad filter (second-order).
188 * The transfer function of this filter is:
189 * H(z) = (b0 + b1 z^-1 + b2 z^-2) / (1 - a1 z^-1 - a2 z^-2)
190 * Nintendo chose to negate the feedbackward coefficients. This differs from standard notation
191 * as in: https://ccrma.stanford.edu/~jos/filters/Direct_Form_I.html
192 * Values are signed fixed point with 14 fractional bits.
193 */
194 struct BiquadFilter {
195 s16_le b0;
196 s16_le b1;
197 s16_le b2;
198 s16_le a1;
199 s16_le a2;
200 };
201
202 union {
203 u16_le filters_enabled;
204 BitField<0, 1, u16_le> simple_filter_enabled;
205 BitField<1, 1, u16_le> biquad_filter_enabled;
206 };
207
208 SimpleFilter simple_filter;
209 BiquadFilter biquad_filter;
210
211 // Buffer Queue
212
213 /// A buffer of audio data from the application, along with metadata about it.
214 struct Buffer {
215 /// Physical memory address of the start of the buffer
216 u32_dsp physical_address;
217
218 /// This is length in terms of samples.
219 /// Note that in different buffer formats a sample takes up different number of bytes.
220 u32_dsp length;
221
222 /// ADPCM Predictor (4 bits) and Scale (4 bits)
223 union {
224 u16_le adpcm_ps;
225 BitField<0, 4, u16_le> adpcm_scale;
226 BitField<4, 4, u16_le> adpcm_predictor;
227 };
228
229 /// ADPCM Historical Samples (y[n-1] and y[n-2])
230 u16_le adpcm_yn[2];
231
232 /// This is non-zero when the ADPCM values above are to be updated.
233 u8 adpcm_dirty;
234
235 /// Is a looping buffer.
236 u8 is_looping;
237
238 /// This value is shown in SourceStatus::previous_buffer_id when this buffer has finished.
239 /// This allows the emulated application to tell what buffer is currently playing
240 u16_le buffer_id;
241
242 INSERT_PADDING_DSPWORDS(1);
243 };
244
245 u16_le buffers_dirty; ///< Bitmap indicating which buffers are dirty (bit i -> buffers[i])
246 Buffer buffers[4]; ///< Queued Buffers
247
248 // Playback controls
249
250 u32_dsp loop_related;
251 u8 enable;
252 INSERT_PADDING_BYTES(1);
253 u16_le sync; ///< Application-side sync (See also: SourceStatus::sync)
254 u32_dsp play_position; ///< Position. (Units: number of samples)
255 INSERT_PADDING_DSPWORDS(2);
256
257 // Embedded Buffer
258 // This buffer is often the first buffer to be used when initiating audio playback,
259 // after which the buffer queue is used.
260
261 u32_dsp physical_address;
262
263 /// This is length in terms of samples.
264 /// Note a sample takes up different number of bytes in different buffer formats.
265 u32_dsp length;
266
267 enum class MonoOrStereo : u16_le {
268 Mono = 1,
269 Stereo = 2
270 };
271
272 enum class Format : u16_le {
273 PCM8 = 0,
274 PCM16 = 1,
275 ADPCM = 2
276 };
277
278 union {
279 u16_le flags1_raw;
280 BitField<0, 2, MonoOrStereo> mono_or_stereo;
281 BitField<2, 2, Format> format;
282 BitField<5, 1, u16_le> fade_in;
283 };
284
285 /// ADPCM Predictor (4 bit) and Scale (4 bit)
286 union {
287 u16_le adpcm_ps;
288 BitField<0, 4, u16_le> adpcm_scale;
289 BitField<4, 4, u16_le> adpcm_predictor;
290 };
291
292 /// ADPCM Historical Samples (y[n-1] and y[n-2])
293 u16_le adpcm_yn[2];
294
295 union {
296 u16_le flags2_raw;
297 BitField<0, 1, u16_le> adpcm_dirty; ///< Has the ADPCM info above been changed?
298 BitField<1, 1, u16_le> is_looping; ///< Is this a looping buffer?
299 };
300
301 /// Buffer id of embedded buffer (used as a buffer id in SourceStatus to reference this buffer).
302 u16_le buffer_id;
303 };
304
305 Configuration config[AudioCore::num_sources];
306};
307ASSERT_DSP_STRUCT(SourceConfiguration::Configuration, 192);
308ASSERT_DSP_STRUCT(SourceConfiguration::Configuration::Buffer, 20);
309
310struct SourceStatus {
311 struct Status {
312 u8 is_enabled; ///< Is this channel enabled? (Doesn't have to be playing anything.)
313 u8 previous_buffer_id_dirty; ///< Non-zero when previous_buffer_id changes
314 u16_le sync; ///< Is set by the DSP to the value of SourceConfiguration::sync
315 u32_dsp buffer_position; ///< Number of samples into the current buffer
316 u16_le previous_buffer_id; ///< Updated when a buffer finishes playing
317 INSERT_PADDING_DSPWORDS(1);
318 };
319
320 Status status[AudioCore::num_sources];
321};
322ASSERT_DSP_STRUCT(SourceStatus::Status, 12);
323
324struct DspConfiguration {
325 /// These dirty flags are set by the application when it updates the fields in this struct.
326 /// The DSP clears these each audio frame.
327 union {
328 u32_le dirty_raw;
329
330 BitField<8, 1, u32_le> mixer1_enabled_dirty;
331 BitField<9, 1, u32_le> mixer2_enabled_dirty;
332 BitField<10, 1, u32_le> delay_effect_0_dirty;
333 BitField<11, 1, u32_le> delay_effect_1_dirty;
334 BitField<12, 1, u32_le> reverb_effect_0_dirty;
335 BitField<13, 1, u32_le> reverb_effect_1_dirty;
336
337 BitField<16, 1, u32_le> volume_0_dirty;
338
339 BitField<24, 1, u32_le> volume_1_dirty;
340 BitField<25, 1, u32_le> volume_2_dirty;
341 BitField<26, 1, u32_le> output_format_dirty;
342 BitField<27, 1, u32_le> limiter_enabled_dirty;
343 BitField<28, 1, u32_le> headphones_connected_dirty;
344 };
345
346 /// The DSP has three intermediate audio mixers. This controls the volume level (0.0-1.0) for each at the final mixer
347 float_le volume[3];
348
349 INSERT_PADDING_DSPWORDS(3);
350
351 enum class OutputFormat : u16_le {
352 Mono = 0,
353 Stereo = 1,
354 Surround = 2
355 };
356
357 OutputFormat output_format;
358
359 u16_le limiter_enabled; ///< Not sure of the exact gain equation for the limiter.
360 u16_le headphones_connected; ///< Application updates the DSP on headphone status.
361 INSERT_PADDING_DSPWORDS(4); ///< TODO: Surround sound related
362 INSERT_PADDING_DSPWORDS(2); ///< TODO: Intermediate mixer 1/2 related
363 u16_le mixer1_enabled;
364 u16_le mixer2_enabled;
365
366 /**
367 * This is delay with feedback.
368 * Transfer function:
369 * H(z) = a z^-N / (1 - b z^-1 + a g z^-N)
370 * where
371 * N = frame_count * samples_per_frame
372 * g, a and b are fixed point with 7 fractional bits
373 */
374 struct DelayEffect {
375 /// These dirty flags are set by the application when it updates the fields in this struct.
376 /// The DSP clears these each audio frame.
377 union {
378 u16_le dirty_raw;
379 BitField<0, 1, u16_le> enable_dirty;
380 BitField<1, 1, u16_le> work_buffer_address_dirty;
381 BitField<2, 1, u16_le> other_dirty; ///< Set when anything else has been changed
382 };
383
384 u16_le enable;
385 INSERT_PADDING_DSPWORDS(1);
386 u16_le outputs;
387 u32_dsp work_buffer_address; ///< The application allocates a block of memory for the DSP to use as a work buffer.
388 u16_le frame_count; ///< Frames to delay by
389
390 // Coefficients
391 s16_le g; ///< Fixed point with 7 fractional bits
392 s16_le a; ///< Fixed point with 7 fractional bits
393 s16_le b; ///< Fixed point with 7 fractional bits
394 };
395
396 DelayEffect delay_effect[2];
397
398 struct ReverbEffect {
399 INSERT_PADDING_DSPWORDS(26); ///< TODO
400 };
401
402 ReverbEffect reverb_effect[2];
403
404 INSERT_PADDING_DSPWORDS(4);
405};
406ASSERT_DSP_STRUCT(DspConfiguration, 196);
407ASSERT_DSP_STRUCT(DspConfiguration::DelayEffect, 20);
408ASSERT_DSP_STRUCT(DspConfiguration::ReverbEffect, 52);
409
410struct AdpcmCoefficients {
411 /// Coefficients are signed fixed point with 11 fractional bits.
412 /// Each source has 16 coefficients associated with it.
413 s16_le coeff[AudioCore::num_sources][16];
414};
415ASSERT_DSP_STRUCT(AdpcmCoefficients, 768);
416
417struct DspStatus {
418 u16_le unknown;
419 u16_le dropped_frames;
420 INSERT_PADDING_DSPWORDS(0xE);
421};
422ASSERT_DSP_STRUCT(DspStatus, 32);
423
424/// Final mixed output in PCM16 stereo format, what you hear out of the speakers.
425/// When the application writes to this region it has no effect.
426struct FinalMixSamples {
427 s16_le pcm16[2 * AudioCore::samples_per_frame];
428};
429ASSERT_DSP_STRUCT(FinalMixSamples, 640);
430
431/// DSP writes output of intermediate mixers 1 and 2 here.
432/// Writes to this region by the application edits the output of the intermediate mixers.
433/// This seems to be intended to allow the application to do custom effects on the ARM11.
434/// Values that exceed s16 range will be clipped by the DSP after further processing.
435struct IntermediateMixSamples {
436 struct Samples {
437 s32_le pcm32[4][AudioCore::samples_per_frame]; ///< Little-endian as opposed to DSP middle-endian.
438 };
439
440 Samples mix1;
441 Samples mix2;
442};
443ASSERT_DSP_STRUCT(IntermediateMixSamples, 5120);
444
445/// Compressor table
446struct Compressor {
447 INSERT_PADDING_DSPWORDS(0xD20); ///< TODO
448};
449
450/// There is no easy way to implement this in a HLE implementation.
451struct DspDebug {
452 INSERT_PADDING_DSPWORDS(0x130);
453};
454ASSERT_DSP_STRUCT(DspDebug, 0x260);
455
456struct SharedMemory {
457 /// Padding
458 INSERT_PADDING_DSPWORDS(0x400);
459
460 DspStatus dsp_status;
461
462 DspDebug dsp_debug;
463
464 FinalMixSamples final_samples;
465
466 SourceStatus source_statuses;
467
468 Compressor compressor;
469
470 DspConfiguration dsp_configuration;
471
472 IntermediateMixSamples intermediate_mix_samples;
473
474 SourceConfiguration source_configurations;
475
476 AdpcmCoefficients adpcm_coefficients;
477
478 struct {
479 INSERT_PADDING_DSPWORDS(0x100);
480 } unknown10;
481
482 struct {
483 INSERT_PADDING_DSPWORDS(0xC0);
484 } unknown11;
485
486 struct {
487 INSERT_PADDING_DSPWORDS(0x180);
488 } unknown12;
489
490 struct {
491 INSERT_PADDING_DSPWORDS(0xA);
492 } unknown13;
493
494 struct {
495 INSERT_PADDING_DSPWORDS(0x13A3);
496 } unknown14;
497
498 u16_le frame_counter;
499};
500ASSERT_DSP_STRUCT(SharedMemory, 0x8000);
501
502// Structures must have an offset that is a multiple of two.
503static_assert(offsetof(SharedMemory, frame_counter) % 2 == 0, "Structures in DSP::HLE::SharedMemory must be 2-byte aligned");
504static_assert(offsetof(SharedMemory, source_configurations) % 2 == 0, "Structures in DSP::HLE::SharedMemory must be 2-byte aligned");
505static_assert(offsetof(SharedMemory, source_statuses) % 2 == 0, "Structures in DSP::HLE::SharedMemory must be 2-byte aligned");
506static_assert(offsetof(SharedMemory, adpcm_coefficients) % 2 == 0, "Structures in DSP::HLE::SharedMemory must be 2-byte aligned");
507static_assert(offsetof(SharedMemory, dsp_configuration) % 2 == 0, "Structures in DSP::HLE::SharedMemory must be 2-byte aligned");
508static_assert(offsetof(SharedMemory, dsp_status) % 2 == 0, "Structures in DSP::HLE::SharedMemory must be 2-byte aligned");
509static_assert(offsetof(SharedMemory, final_samples) % 2 == 0, "Structures in DSP::HLE::SharedMemory must be 2-byte aligned");
510static_assert(offsetof(SharedMemory, intermediate_mix_samples) % 2 == 0, "Structures in DSP::HLE::SharedMemory must be 2-byte aligned");
511static_assert(offsetof(SharedMemory, compressor) % 2 == 0, "Structures in DSP::HLE::SharedMemory must be 2-byte aligned");
512static_assert(offsetof(SharedMemory, dsp_debug) % 2 == 0, "Structures in DSP::HLE::SharedMemory must be 2-byte aligned");
513static_assert(offsetof(SharedMemory, unknown10) % 2 == 0, "Structures in DSP::HLE::SharedMemory must be 2-byte aligned");
514static_assert(offsetof(SharedMemory, unknown11) % 2 == 0, "Structures in DSP::HLE::SharedMemory must be 2-byte aligned");
515static_assert(offsetof(SharedMemory, unknown12) % 2 == 0, "Structures in DSP::HLE::SharedMemory must be 2-byte aligned");
516static_assert(offsetof(SharedMemory, unknown13) % 2 == 0, "Structures in DSP::HLE::SharedMemory must be 2-byte aligned");
517static_assert(offsetof(SharedMemory, unknown14) % 2 == 0, "Structures in DSP::HLE::SharedMemory must be 2-byte aligned");
518
519#undef INSERT_PADDING_DSPWORDS
520#undef ASSERT_DSP_STRUCT
521
522/// Initialize DSP hardware
523void Init();
524
525/// Shutdown DSP hardware
526void Shutdown();
527
528/**
529 * Perform processing and updates state of current shared memory buffer.
530 * This function is called every audio tick before triggering the audio interrupt.
531 * @return Whether an audio interrupt should be triggered this frame.
532 */
533bool Tick();
534
535/// Returns a mutable reference to the current region. Current region is selected based on the frame counter.
536SharedMemory& CurrentRegion();
537
538} // namespace HLE
539} // namespace DSP
diff --git a/src/audio_core/hle/pipe.cpp b/src/audio_core/hle/pipe.cpp
new file mode 100644
index 000000000..9381883b4
--- /dev/null
+++ b/src/audio_core/hle/pipe.cpp
@@ -0,0 +1,159 @@
1// Copyright 2016 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <array>
6#include <vector>
7
8#include "audio_core/hle/dsp.h"
9#include "audio_core/hle/pipe.h"
10
11#include "common/assert.h"
12#include "common/common_types.h"
13#include "common/logging/log.h"
14
15namespace DSP {
16namespace HLE {
17
18static DspState dsp_state = DspState::Off;
19
20static std::array<std::vector<u8>, static_cast<size_t>(DspPipe::DspPipe_MAX)> pipe_data;
21
22void ResetPipes() {
23 for (auto& data : pipe_data) {
24 data.clear();
25 }
26 dsp_state = DspState::Off;
27}
28
29std::vector<u8> PipeRead(DspPipe pipe_number, u32 length) {
30 if (pipe_number >= DspPipe::DspPipe_MAX) {
31 LOG_ERROR(Audio_DSP, "pipe_number = %u invalid", pipe_number);
32 return {};
33 }
34
35 std::vector<u8>& data = pipe_data[static_cast<size_t>(pipe_number)];
36
37 if (length > data.size()) {
38 LOG_WARNING(Audio_DSP, "pipe_number = %u is out of data, application requested read of %u but %zu remain",
39 pipe_number, length, data.size());
40 length = data.size();
41 }
42
43 if (length == 0)
44 return {};
45
46 std::vector<u8> ret(data.begin(), data.begin() + length);
47 data.erase(data.begin(), data.begin() + length);
48 return ret;
49}
50
51size_t GetPipeReadableSize(DspPipe pipe_number) {
52 if (pipe_number >= DspPipe::DspPipe_MAX) {
53 LOG_ERROR(Audio_DSP, "pipe_number = %u invalid", pipe_number);
54 return 0;
55 }
56
57 return pipe_data[static_cast<size_t>(pipe_number)].size();
58}
59
60static void WriteU16(DspPipe pipe_number, u16 value) {
61 std::vector<u8>& data = pipe_data[static_cast<size_t>(pipe_number)];
62 // Little endian
63 data.emplace_back(value & 0xFF);
64 data.emplace_back(value >> 8);
65}
66
67static void AudioPipeWriteStructAddresses() {
68 // These struct addresses are DSP dram addresses.
69 // See also: DSP_DSP::ConvertProcessAddressFromDspDram
70 static const std::array<u16, 15> struct_addresses = {
71 0x8000 + offsetof(SharedMemory, frame_counter) / 2,
72 0x8000 + offsetof(SharedMemory, source_configurations) / 2,
73 0x8000 + offsetof(SharedMemory, source_statuses) / 2,
74 0x8000 + offsetof(SharedMemory, adpcm_coefficients) / 2,
75 0x8000 + offsetof(SharedMemory, dsp_configuration) / 2,
76 0x8000 + offsetof(SharedMemory, dsp_status) / 2,
77 0x8000 + offsetof(SharedMemory, final_samples) / 2,
78 0x8000 + offsetof(SharedMemory, intermediate_mix_samples) / 2,
79 0x8000 + offsetof(SharedMemory, compressor) / 2,
80 0x8000 + offsetof(SharedMemory, dsp_debug) / 2,
81 0x8000 + offsetof(SharedMemory, unknown10) / 2,
82 0x8000 + offsetof(SharedMemory, unknown11) / 2,
83 0x8000 + offsetof(SharedMemory, unknown12) / 2,
84 0x8000 + offsetof(SharedMemory, unknown13) / 2,
85 0x8000 + offsetof(SharedMemory, unknown14) / 2
86 };
87
88 // Begin with a u16 denoting the number of structs.
89 WriteU16(DspPipe::Audio, struct_addresses.size());
90 // Then write the struct addresses.
91 for (u16 addr : struct_addresses) {
92 WriteU16(DspPipe::Audio, addr);
93 }
94}
95
96void PipeWrite(DspPipe pipe_number, const std::vector<u8>& buffer) {
97 switch (pipe_number) {
98 case DspPipe::Audio: {
99 if (buffer.size() != 4) {
100 LOG_ERROR(Audio_DSP, "DspPipe::Audio: Unexpected buffer length %zu was written", buffer.size());
101 return;
102 }
103
104 enum class StateChange {
105 Initalize = 0,
106 Shutdown = 1,
107 Wakeup = 2,
108 Sleep = 3
109 };
110
111 // The difference between Initialize and Wakeup is that Input state is maintained
112 // when sleeping but isn't when turning it off and on again. (TODO: Implement this.)
113 // Waking up from sleep garbles some of the structs in the memory region. (TODO:
114 // Implement this.) Applications store away the state of these structs before
115 // sleeping and reset it back after wakeup on behalf of the DSP.
116
117 switch (static_cast<StateChange>(buffer[0])) {
118 case StateChange::Initalize:
119 LOG_INFO(Audio_DSP, "Application has requested initialization of DSP hardware");
120 ResetPipes();
121 AudioPipeWriteStructAddresses();
122 dsp_state = DspState::On;
123 break;
124 case StateChange::Shutdown:
125 LOG_INFO(Audio_DSP, "Application has requested shutdown of DSP hardware");
126 dsp_state = DspState::Off;
127 break;
128 case StateChange::Wakeup:
129 LOG_INFO(Audio_DSP, "Application has requested wakeup of DSP hardware");
130 ResetPipes();
131 AudioPipeWriteStructAddresses();
132 dsp_state = DspState::On;
133 break;
134 case StateChange::Sleep:
135 LOG_INFO(Audio_DSP, "Application has requested sleep of DSP hardware");
136 UNIMPLEMENTED();
137 dsp_state = DspState::Sleeping;
138 break;
139 default:
140 LOG_ERROR(Audio_DSP, "Application has requested unknown state transition of DSP hardware %hhu", buffer[0]);
141 dsp_state = DspState::Off;
142 break;
143 }
144
145 return;
146 }
147 default:
148 LOG_CRITICAL(Audio_DSP, "pipe_number = %u unimplemented", pipe_number);
149 UNIMPLEMENTED();
150 return;
151 }
152}
153
154DspState GetDspState() {
155 return dsp_state;
156}
157
158} // namespace HLE
159} // namespace DSP
diff --git a/src/audio_core/hle/pipe.h b/src/audio_core/hle/pipe.h
new file mode 100644
index 000000000..382d35e87
--- /dev/null
+++ b/src/audio_core/hle/pipe.h
@@ -0,0 +1,57 @@
1// Copyright 2016 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 <cstddef>
8#include <vector>
9
10#include "common/common_types.h"
11
12namespace DSP {
13namespace HLE {
14
15/// Reset the pipes by setting pipe positions back to the beginning.
16void ResetPipes();
17
18enum class DspPipe {
19 Debug = 0,
20 Dma = 1,
21 Audio = 2,
22 Binary = 3,
23 DspPipe_MAX
24};
25
26/**
27 * Read a DSP pipe.
28 * @param pipe_number The Pipe ID
29 * @param length How much data to request.
30 * @return The data read from the pipe. The size of this vector can be less than the length requested.
31 */
32std::vector<u8> PipeRead(DspPipe pipe_number, u32 length);
33
34/**
35 * How much data is left in pipe
36 * @param pipe_number The Pipe ID
37 * @return The amount of data remaning in the pipe. This is the maximum length PipeRead will return.
38 */
39size_t GetPipeReadableSize(DspPipe pipe_number);
40
41/**
42 * Write to a DSP pipe.
43 * @param pipe_number The Pipe ID
44 * @param buffer The data to write to the pipe.
45 */
46void PipeWrite(DspPipe pipe_number, const std::vector<u8>& buffer);
47
48enum class DspState {
49 Off,
50 On,
51 Sleeping
52};
53/// Get the state of the DSP
54DspState GetDspState();
55
56} // namespace HLE
57} // namespace DSP
diff --git a/src/audio_core/sink.h b/src/audio_core/sink.h
new file mode 100644
index 000000000..cad21a85e
--- /dev/null
+++ b/src/audio_core/sink.h
@@ -0,0 +1,34 @@
1// Copyright 2016 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 <vector>
8
9#include "common/common_types.h"
10
11namespace AudioCore {
12
13/**
14 * This class is an interface for an audio sink. An audio sink accepts samples in stereo signed PCM16 format to be output.
15 * Sinks *do not* handle resampling and expect the correct sample rate. They are dumb outputs.
16 */
17class Sink {
18public:
19 virtual ~Sink() = default;
20
21 /// The native rate of this sink. The sink expects to be fed samples that respect this. (Units: samples/sec)
22 virtual unsigned GetNativeSampleRate() const = 0;
23
24 /**
25 * Feed stereo samples to sink.
26 * @param samples Samples in interleaved stereo PCM16 format. Size of vector must be multiple of two.
27 */
28 virtual void EnqueueSamples(const std::vector<s16>& samples) = 0;
29
30 /// Samples enqueued that have not been played yet.
31 virtual std::size_t SamplesInQueue() const = 0;
32};
33
34} // namespace
diff --git a/src/citra/CMakeLists.txt b/src/citra/CMakeLists.txt
index e7f8a17f9..fa615deb9 100644
--- a/src/citra/CMakeLists.txt
+++ b/src/citra/CMakeLists.txt
@@ -1,11 +1,11 @@
1set(SRCS 1set(SRCS
2 emu_window/emu_window_glfw.cpp 2 emu_window/emu_window_sdl2.cpp
3 citra.cpp 3 citra.cpp
4 config.cpp 4 config.cpp
5 citra.rc 5 citra.rc
6 ) 6 )
7set(HEADERS 7set(HEADERS
8 emu_window/emu_window_glfw.h 8 emu_window/emu_window_sdl2.h
9 config.h 9 config.h
10 default_ini.h 10 default_ini.h
11 resource.h 11 resource.h
@@ -13,12 +13,11 @@ set(HEADERS
13 13
14create_directory_groups(${SRCS} ${HEADERS}) 14create_directory_groups(${SRCS} ${HEADERS})
15 15
16include_directories(${GLFW_INCLUDE_DIRS}) 16include_directories(${SDL2_INCLUDE_DIR})
17link_directories(${GLFW_LIBRARY_DIRS})
18 17
19add_executable(citra ${SRCS} ${HEADERS}) 18add_executable(citra ${SRCS} ${HEADERS})
20target_link_libraries(citra core video_core common) 19target_link_libraries(citra core video_core audio_core common)
21target_link_libraries(citra ${GLFW_LIBRARIES} ${OPENGL_gl_LIBRARY} inih glad) 20target_link_libraries(citra ${SDL2_LIBRARY} ${OPENGL_gl_LIBRARY} inih glad)
22if (MSVC) 21if (MSVC)
23 target_link_libraries(citra getopt) 22 target_link_libraries(citra getopt)
24endif() 23endif()
@@ -27,3 +26,13 @@ target_link_libraries(citra ${PLATFORM_LIBRARIES})
27if(${CMAKE_SYSTEM_NAME} MATCHES "Linux|FreeBSD|OpenBSD|NetBSD") 26if(${CMAKE_SYSTEM_NAME} MATCHES "Linux|FreeBSD|OpenBSD|NetBSD")
28 install(TARGETS citra RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin") 27 install(TARGETS citra RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin")
29endif() 28endif()
29
30if (MSVC)
31 include(WindowsCopyFiles)
32
33 set(DLL_DEST "${CMAKE_BINARY_DIR}/bin/$<CONFIG>/")
34
35 windows_copy_files(citra ${SDL2_DLL_DIR} ${DLL_DEST} SDL2.dll)
36
37 unset(DLL_DEST)
38endif()
diff --git a/src/citra/citra.cpp b/src/citra/citra.cpp
index c96fc1374..415b98a05 100644
--- a/src/citra/citra.cpp
+++ b/src/citra/citra.cpp
@@ -27,7 +27,7 @@
27#include "core/loader/loader.h" 27#include "core/loader/loader.h"
28 28
29#include "citra/config.h" 29#include "citra/config.h"
30#include "citra/emu_window/emu_window_glfw.h" 30#include "citra/emu_window/emu_window_sdl2.h"
31 31
32#include "video_core/video_core.h" 32#include "video_core/video_core.h"
33 33
@@ -76,7 +76,7 @@ int main(int argc, char **argv) {
76 GDBStub::ToggleServer(Settings::values.use_gdbstub); 76 GDBStub::ToggleServer(Settings::values.use_gdbstub);
77 GDBStub::SetServerPort(static_cast<u32>(Settings::values.gdbstub_port)); 77 GDBStub::SetServerPort(static_cast<u32>(Settings::values.gdbstub_port));
78 78
79 EmuWindow_GLFW* emu_window = new EmuWindow_GLFW; 79 EmuWindow_SDL2* emu_window = new EmuWindow_SDL2;
80 80
81 VideoCore::g_hw_renderer_enabled = Settings::values.use_hw_renderer; 81 VideoCore::g_hw_renderer_enabled = Settings::values.use_hw_renderer;
82 VideoCore::g_shader_jit_enabled = Settings::values.use_shader_jit; 82 VideoCore::g_shader_jit_enabled = Settings::values.use_shader_jit;
diff --git a/src/citra/config.cpp b/src/citra/config.cpp
index 2f13c29a2..9034b188e 100644
--- a/src/citra/config.cpp
+++ b/src/citra/config.cpp
@@ -2,14 +2,15 @@
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#define GLFW_INCLUDE_NONE
6#include <GLFW/glfw3.h>
7#include <inih/cpp/INIReader.h> 5#include <inih/cpp/INIReader.h>
8 6
7#include <SDL.h>
8
9#include "citra/default_ini.h" 9#include "citra/default_ini.h"
10 10
11#include "common/file_util.h" 11#include "common/file_util.h"
12#include "common/logging/log.h" 12#include "common/logging/log.h"
13#include "common/make_unique.h"
13 14
14#include "core/settings.h" 15#include "core/settings.h"
15 16
@@ -17,21 +18,22 @@
17 18
18Config::Config() { 19Config::Config() {
19 // TODO: Don't hardcode the path; let the frontend decide where to put the config files. 20 // TODO: Don't hardcode the path; let the frontend decide where to put the config files.
20 glfw_config_loc = FileUtil::GetUserPath(D_CONFIG_IDX) + "glfw-config.ini"; 21 sdl2_config_loc = FileUtil::GetUserPath(D_CONFIG_IDX) + "sdl2-config.ini";
21 glfw_config = new INIReader(glfw_config_loc); 22 sdl2_config = Common::make_unique<INIReader>(sdl2_config_loc);
22 23
23 Reload(); 24 Reload();
24} 25}
25 26
26bool Config::LoadINI(INIReader* config, const char* location, const std::string& default_contents, bool retry) { 27bool Config::LoadINI(const std::string& default_contents, bool retry) {
27 if (config->ParseError() < 0) { 28 const char* location = this->sdl2_config_loc.c_str();
29 if (sdl2_config->ParseError() < 0) {
28 if (retry) { 30 if (retry) {
29 LOG_WARNING(Config, "Failed to load %s. Creating file from defaults...", location); 31 LOG_WARNING(Config, "Failed to load %s. Creating file from defaults...", location);
30 FileUtil::CreateFullPath(location); 32 FileUtil::CreateFullPath(location);
31 FileUtil::WriteStringToFile(true, default_contents, location); 33 FileUtil::WriteStringToFile(true, default_contents, location);
32 *config = INIReader(location); // Reopen file 34 sdl2_config = Common::make_unique<INIReader>(location); // Reopen file
33 35
34 return LoadINI(config, location, default_contents, false); 36 return LoadINI(default_contents, false);
35 } 37 }
36 LOG_ERROR(Config, "Failed."); 38 LOG_ERROR(Config, "Failed.");
37 return false; 39 return false;
@@ -41,51 +43,47 @@ bool Config::LoadINI(INIReader* config, const char* location, const std::string&
41} 43}
42 44
43static const std::array<int, Settings::NativeInput::NUM_INPUTS> defaults = { 45static const std::array<int, Settings::NativeInput::NUM_INPUTS> defaults = {
44 GLFW_KEY_A, GLFW_KEY_S, GLFW_KEY_Z, GLFW_KEY_X, 46 SDL_SCANCODE_A, SDL_SCANCODE_S, SDL_SCANCODE_Z, SDL_SCANCODE_X,
45 GLFW_KEY_Q, GLFW_KEY_W, GLFW_KEY_1, GLFW_KEY_2, 47 SDL_SCANCODE_Q, SDL_SCANCODE_W, SDL_SCANCODE_1, SDL_SCANCODE_2,
46 GLFW_KEY_M, GLFW_KEY_N, GLFW_KEY_B, 48 SDL_SCANCODE_M, SDL_SCANCODE_N, SDL_SCANCODE_B,
47 GLFW_KEY_T, GLFW_KEY_G, GLFW_KEY_F, GLFW_KEY_H, 49 SDL_SCANCODE_T, SDL_SCANCODE_G, SDL_SCANCODE_F, SDL_SCANCODE_H,
48 GLFW_KEY_UP, GLFW_KEY_DOWN, GLFW_KEY_LEFT, GLFW_KEY_RIGHT, 50 SDL_SCANCODE_UP, SDL_SCANCODE_DOWN, SDL_SCANCODE_LEFT, SDL_SCANCODE_RIGHT,
49 GLFW_KEY_I, GLFW_KEY_K, GLFW_KEY_J, GLFW_KEY_L 51 SDL_SCANCODE_I, SDL_SCANCODE_K, SDL_SCANCODE_J, SDL_SCANCODE_L
50}; 52};
51 53
52void Config::ReadValues() { 54void Config::ReadValues() {
53 // Controls 55 // Controls
54 for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) { 56 for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) {
55 Settings::values.input_mappings[Settings::NativeInput::All[i]] = 57 Settings::values.input_mappings[Settings::NativeInput::All[i]] =
56 glfw_config->GetInteger("Controls", Settings::NativeInput::Mapping[i], defaults[i]); 58 sdl2_config->GetInteger("Controls", Settings::NativeInput::Mapping[i], defaults[i]);
57 } 59 }
58 60
59 // Core 61 // Core
60 Settings::values.frame_skip = glfw_config->GetInteger("Core", "frame_skip", 0); 62 Settings::values.frame_skip = sdl2_config->GetInteger("Core", "frame_skip", 0);
61 63
62 // Renderer 64 // Renderer
63 Settings::values.use_hw_renderer = glfw_config->GetBoolean("Renderer", "use_hw_renderer", false); 65 Settings::values.use_hw_renderer = sdl2_config->GetBoolean("Renderer", "use_hw_renderer", false);
64 Settings::values.use_shader_jit = glfw_config->GetBoolean("Renderer", "use_shader_jit", true); 66 Settings::values.use_shader_jit = sdl2_config->GetBoolean("Renderer", "use_shader_jit", true);
65 67
66 Settings::values.bg_red = (float)glfw_config->GetReal("Renderer", "bg_red", 1.0); 68 Settings::values.bg_red = (float)sdl2_config->GetReal("Renderer", "bg_red", 1.0);
67 Settings::values.bg_green = (float)glfw_config->GetReal("Renderer", "bg_green", 1.0); 69 Settings::values.bg_green = (float)sdl2_config->GetReal("Renderer", "bg_green", 1.0);
68 Settings::values.bg_blue = (float)glfw_config->GetReal("Renderer", "bg_blue", 1.0); 70 Settings::values.bg_blue = (float)sdl2_config->GetReal("Renderer", "bg_blue", 1.0);
69 71
70 // Data Storage 72 // Data Storage
71 Settings::values.use_virtual_sd = glfw_config->GetBoolean("Data Storage", "use_virtual_sd", true); 73 Settings::values.use_virtual_sd = sdl2_config->GetBoolean("Data Storage", "use_virtual_sd", true);
72 74
73 // System Region 75 // System Region
74 Settings::values.region_value = glfw_config->GetInteger("System Region", "region_value", 1); 76 Settings::values.region_value = sdl2_config->GetInteger("System Region", "region_value", 1);
75 77
76 // Miscellaneous 78 // Miscellaneous
77 Settings::values.log_filter = glfw_config->Get("Miscellaneous", "log_filter", "*:Info"); 79 Settings::values.log_filter = sdl2_config->Get("Miscellaneous", "log_filter", "*:Info");
78 80
79 // Debugging 81 // Debugging
80 Settings::values.use_gdbstub = glfw_config->GetBoolean("Debugging", "use_gdbstub", false); 82 Settings::values.use_gdbstub = sdl2_config->GetBoolean("Debugging", "use_gdbstub", false);
81 Settings::values.gdbstub_port = glfw_config->GetInteger("Debugging", "gdbstub_port", 24689); 83 Settings::values.gdbstub_port = sdl2_config->GetInteger("Debugging", "gdbstub_port", 24689);
82} 84}
83 85
84void Config::Reload() { 86void Config::Reload() {
85 LoadINI(glfw_config, glfw_config_loc.c_str(), DefaultINI::glfw_config_file); 87 LoadINI(DefaultINI::sdl2_config_file);
86 ReadValues(); 88 ReadValues();
87} 89}
88
89Config::~Config() {
90 delete glfw_config;
91}
diff --git a/src/citra/config.h b/src/citra/config.h
index c326ec669..52a478146 100644
--- a/src/citra/config.h
+++ b/src/citra/config.h
@@ -4,19 +4,19 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <memory>
7#include <string> 8#include <string>
8 9
9class INIReader; 10#include <inih/cpp/INIReader.h>
10 11
11class Config { 12class Config {
12 INIReader* glfw_config; 13 std::unique_ptr<INIReader> sdl2_config;
13 std::string glfw_config_loc; 14 std::string sdl2_config_loc;
14 15
15 bool LoadINI(INIReader* config, const char* location, const std::string& default_contents="", bool retry=true); 16 bool LoadINI(const std::string& default_contents="", bool retry=true);
16 void ReadValues(); 17 void ReadValues();
17public: 18public:
18 Config(); 19 Config();
19 ~Config();
20 20
21 void Reload(); 21 void Reload();
22}; 22};
diff --git a/src/citra/default_ini.h b/src/citra/default_ini.h
index 5ba40a8ed..c9b490a00 100644
--- a/src/citra/default_ini.h
+++ b/src/citra/default_ini.h
@@ -6,7 +6,7 @@
6 6
7namespace DefaultINI { 7namespace DefaultINI {
8 8
9const char* glfw_config_file = R"( 9const char* sdl2_config_file = R"(
10[Controls] 10[Controls]
11pad_start = 11pad_start =
12pad_select = 12pad_select =
diff --git a/src/citra/emu_window/emu_window_glfw.cpp b/src/citra/emu_window/emu_window_glfw.cpp
deleted file mode 100644
index 9453b1f48..000000000
--- a/src/citra/emu_window/emu_window_glfw.cpp
+++ /dev/null
@@ -1,168 +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 <algorithm>
6#include <cstdlib>
7#include <string>
8
9// Let’s use our own GL header, instead of one from GLFW.
10#include <glad/glad.h>
11#define GLFW_INCLUDE_NONE
12#include <GLFW/glfw3.h>
13
14#include "common/assert.h"
15#include "common/key_map.h"
16#include "common/logging/log.h"
17#include "common/scm_rev.h"
18#include "common/string_util.h"
19
20#include "video_core/video_core.h"
21
22#include "core/settings.h"
23#include "core/hle/service/hid/hid.h"
24
25#include "citra/emu_window/emu_window_glfw.h"
26
27EmuWindow_GLFW* EmuWindow_GLFW::GetEmuWindow(GLFWwindow* win) {
28 return static_cast<EmuWindow_GLFW*>(glfwGetWindowUserPointer(win));
29}
30
31void EmuWindow_GLFW::OnMouseButtonEvent(GLFWwindow* win, int button, int action, int mods) {
32 if (button == GLFW_MOUSE_BUTTON_LEFT) {
33 auto emu_window = GetEmuWindow(win);
34 auto layout = emu_window->GetFramebufferLayout();
35 double x, y;
36 glfwGetCursorPos(win, &x, &y);
37
38 if (action == GLFW_PRESS)
39 emu_window->TouchPressed(static_cast<unsigned>(x), static_cast<unsigned>(y));
40 else if (action == GLFW_RELEASE)
41 emu_window->TouchReleased();
42 }
43}
44
45void EmuWindow_GLFW::OnCursorPosEvent(GLFWwindow* win, double x, double y) {
46 GetEmuWindow(win)->TouchMoved(static_cast<unsigned>(std::max(x, 0.0)), static_cast<unsigned>(std::max(y, 0.0)));
47}
48
49/// Called by GLFW when a key event occurs
50void EmuWindow_GLFW::OnKeyEvent(GLFWwindow* win, int key, int scancode, int action, int mods) {
51 auto emu_window = GetEmuWindow(win);
52 int keyboard_id = emu_window->keyboard_id;
53
54 if (action == GLFW_PRESS) {
55 emu_window->KeyPressed({key, keyboard_id});
56 } else if (action == GLFW_RELEASE) {
57 emu_window->KeyReleased({key, keyboard_id});
58 }
59}
60
61/// Whether the window is still open, and a close request hasn't yet been sent
62const bool EmuWindow_GLFW::IsOpen() {
63 return glfwWindowShouldClose(m_render_window) == 0;
64}
65
66void EmuWindow_GLFW::OnFramebufferResizeEvent(GLFWwindow* win, int width, int height) {
67 GetEmuWindow(win)->NotifyFramebufferLayoutChanged(EmuWindow::FramebufferLayout::DefaultScreenLayout(width, height));
68}
69
70void EmuWindow_GLFW::OnClientAreaResizeEvent(GLFWwindow* win, int width, int height) {
71 // NOTE: GLFW provides no proper way to set a minimal window size.
72 // Hence, we just ignore the corresponding EmuWindow hint.
73 OnFramebufferResizeEvent(win, width, height);
74}
75
76/// EmuWindow_GLFW constructor
77EmuWindow_GLFW::EmuWindow_GLFW() {
78 keyboard_id = KeyMap::NewDeviceId();
79
80 ReloadSetKeymaps();
81
82 glfwSetErrorCallback([](int error, const char *desc){
83 LOG_ERROR(Frontend, "GLFW 0x%08x: %s", error, desc);
84 });
85
86 // Initialize the window
87 if(glfwInit() != GL_TRUE) {
88 LOG_CRITICAL(Frontend, "Failed to initialize GLFW! Exiting...");
89 exit(1);
90 }
91 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
92 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
93 // GLFW on OSX requires these window hints to be set to create a 3.2+ GL context.
94 glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
95 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
96
97 std::string window_title = Common::StringFromFormat("Citra | %s-%s", Common::g_scm_branch, Common::g_scm_desc);
98 m_render_window = glfwCreateWindow(VideoCore::kScreenTopWidth,
99 (VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight),
100 window_title.c_str(), nullptr, nullptr);
101
102 if (m_render_window == nullptr) {
103 LOG_CRITICAL(Frontend, "Failed to create GLFW window! Exiting...");
104 exit(1);
105 }
106
107 glfwSetWindowUserPointer(m_render_window, this);
108
109 // Notify base interface about window state
110 int width, height;
111 glfwGetFramebufferSize(m_render_window, &width, &height);
112 OnFramebufferResizeEvent(m_render_window, width, height);
113
114 glfwGetWindowSize(m_render_window, &width, &height);
115 OnClientAreaResizeEvent(m_render_window, width, height);
116
117 // Setup callbacks
118 glfwSetKeyCallback(m_render_window, OnKeyEvent);
119 glfwSetMouseButtonCallback(m_render_window, OnMouseButtonEvent);
120 glfwSetCursorPosCallback(m_render_window, OnCursorPosEvent);
121 glfwSetFramebufferSizeCallback(m_render_window, OnFramebufferResizeEvent);
122 glfwSetWindowSizeCallback(m_render_window, OnClientAreaResizeEvent);
123
124 DoneCurrent();
125}
126
127/// EmuWindow_GLFW destructor
128EmuWindow_GLFW::~EmuWindow_GLFW() {
129 glfwTerminate();
130}
131
132/// Swap buffers to display the next frame
133void EmuWindow_GLFW::SwapBuffers() {
134 glfwSwapBuffers(m_render_window);
135}
136
137/// Polls window events
138void EmuWindow_GLFW::PollEvents() {
139 glfwPollEvents();
140}
141
142/// Makes the GLFW OpenGL context current for the caller thread
143void EmuWindow_GLFW::MakeCurrent() {
144 glfwMakeContextCurrent(m_render_window);
145}
146
147/// Releases (dunno if this is the "right" word) the GLFW context from the caller thread
148void EmuWindow_GLFW::DoneCurrent() {
149 glfwMakeContextCurrent(nullptr);
150}
151
152void EmuWindow_GLFW::ReloadSetKeymaps() {
153 for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) {
154 KeyMap::SetKeyMapping({Settings::values.input_mappings[Settings::NativeInput::All[i]], keyboard_id}, Service::HID::pad_mapping[i]);
155 }
156}
157
158void EmuWindow_GLFW::OnMinimalClientAreaChangeRequest(const std::pair<unsigned,unsigned>& minimal_size) {
159 std::pair<int,int> current_size;
160 glfwGetWindowSize(m_render_window, &current_size.first, &current_size.second);
161
162 DEBUG_ASSERT((int)minimal_size.first > 0 && (int)minimal_size.second > 0);
163 int new_width = std::max(current_size.first, (int)minimal_size.first);
164 int new_height = std::max(current_size.second, (int)minimal_size.second);
165
166 if (current_size != std::make_pair(new_width, new_height))
167 glfwSetWindowSize(m_render_window, new_width, new_height);
168}
diff --git a/src/citra/emu_window/emu_window_glfw.h b/src/citra/emu_window/emu_window_glfw.h
deleted file mode 100644
index 7ccd5e6aa..000000000
--- a/src/citra/emu_window/emu_window_glfw.h
+++ /dev/null
@@ -1,54 +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 <utility>
8
9#include "common/emu_window.h"
10
11struct GLFWwindow;
12
13class EmuWindow_GLFW : public EmuWindow {
14public:
15 EmuWindow_GLFW();
16 ~EmuWindow_GLFW();
17
18 /// Swap buffers to display the next frame
19 void SwapBuffers() override;
20
21 /// Polls window events
22 void PollEvents() override;
23
24 /// Makes the graphics context current for the caller thread
25 void MakeCurrent() override;
26
27 /// Releases (dunno if this is the "right" word) the GLFW context from the caller thread
28 void DoneCurrent() override;
29
30 static void OnKeyEvent(GLFWwindow* win, int key, int scancode, int action, int mods);
31
32 static void OnMouseButtonEvent(GLFWwindow* window, int button, int action, int mods);
33
34 static void OnCursorPosEvent(GLFWwindow* window, double x, double y);
35
36 /// Whether the window is still open, and a close request hasn't yet been sent
37 const bool IsOpen();
38
39 static void OnClientAreaResizeEvent(GLFWwindow* win, int width, int height);
40
41 static void OnFramebufferResizeEvent(GLFWwindow* win, int width, int height);
42
43 void ReloadSetKeymaps() override;
44
45private:
46 void OnMinimalClientAreaChangeRequest(const std::pair<unsigned,unsigned>& minimal_size) override;
47
48 static EmuWindow_GLFW* GetEmuWindow(GLFWwindow* win);
49
50 GLFWwindow* m_render_window; ///< Internal GLFW render window
51
52 /// Device id of keyboard for use with KeyMap
53 int keyboard_id;
54};
diff --git a/src/citra/emu_window/emu_window_sdl2.cpp b/src/citra/emu_window/emu_window_sdl2.cpp
new file mode 100644
index 000000000..1fed82e78
--- /dev/null
+++ b/src/citra/emu_window/emu_window_sdl2.cpp
@@ -0,0 +1,167 @@
1// Copyright 2016 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <algorithm>
6#include <cstdlib>
7#include <string>
8
9#define SDL_MAIN_HANDLED
10#include <SDL.h>
11
12#include "common/key_map.h"
13#include "common/logging/log.h"
14#include "common/scm_rev.h"
15#include "common/string_util.h"
16
17#include "core/settings.h"
18#include "core/hle/service/hid/hid.h"
19
20#include "citra/emu_window/emu_window_sdl2.h"
21
22#include "video_core/video_core.h"
23
24void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) {
25 TouchMoved((unsigned)std::max(x, 0), (unsigned)std::max(y, 0));
26}
27
28void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) {
29 if (button != SDL_BUTTON_LEFT)
30 return;
31
32 if (state == SDL_PRESSED) {
33 TouchPressed((unsigned)std::max(x, 0), (unsigned)std::max(y, 0));
34 } else {
35 TouchReleased();
36 }
37}
38
39void EmuWindow_SDL2::OnKeyEvent(int key, u8 state) {
40 if (state == SDL_PRESSED) {
41 KeyPressed({ key, keyboard_id });
42 } else if (state == SDL_RELEASED) {
43 KeyReleased({ key, keyboard_id });
44 }
45}
46
47bool EmuWindow_SDL2::IsOpen() const {
48 return is_open;
49}
50
51void EmuWindow_SDL2::OnResize() {
52 int width, height;
53
54 SDL_GetWindowSize(render_window, &width, &height);
55
56 NotifyFramebufferLayoutChanged(EmuWindow::FramebufferLayout::DefaultScreenLayout(width, height));
57}
58
59EmuWindow_SDL2::EmuWindow_SDL2() {
60 keyboard_id = KeyMap::NewDeviceId();
61
62 ReloadSetKeymaps();
63
64 SDL_SetMainReady();
65
66 // Initialize the window
67 if (SDL_Init(SDL_INIT_VIDEO) < 0) {
68 LOG_CRITICAL(Frontend, "Failed to initialize SDL2! Exiting...");
69 exit(1);
70 }
71
72 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
73 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
74 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
75 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
76
77 std::string window_title = Common::StringFromFormat("Citra | %s-%s", Common::g_scm_branch, Common::g_scm_desc);
78 render_window = SDL_CreateWindow(window_title.c_str(),
79 SDL_WINDOWPOS_UNDEFINED, // x position
80 SDL_WINDOWPOS_UNDEFINED, // y position
81 VideoCore::kScreenTopWidth,
82 VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight,
83 SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
84
85 if (render_window == nullptr) {
86 LOG_CRITICAL(Frontend, "Failed to create SDL2 window! Exiting...");
87 exit(1);
88 }
89
90 gl_context = SDL_GL_CreateContext(render_window);
91
92 if (gl_context == nullptr) {
93 LOG_CRITICAL(Frontend, "Failed to create SDL2 GL context! Exiting...");
94 exit(1);
95 }
96
97 OnResize();
98 OnMinimalClientAreaChangeRequest(GetActiveConfig().min_client_area_size);
99 SDL_PumpEvents();
100
101 DoneCurrent();
102}
103
104EmuWindow_SDL2::~EmuWindow_SDL2() {
105 SDL_GL_DeleteContext(gl_context);
106 SDL_Quit();
107}
108
109void EmuWindow_SDL2::SwapBuffers() {
110 SDL_GL_SwapWindow(render_window);
111}
112
113void EmuWindow_SDL2::PollEvents() {
114 SDL_Event event;
115
116 // SDL_PollEvent returns 0 when there are no more events in the event queue
117 while (SDL_PollEvent(&event)) {
118 switch (event.type) {
119 case SDL_WINDOWEVENT:
120 switch (event.window.event) {
121 case SDL_WINDOWEVENT_SIZE_CHANGED:
122 case SDL_WINDOWEVENT_RESIZED:
123 case SDL_WINDOWEVENT_MAXIMIZED:
124 case SDL_WINDOWEVENT_RESTORED:
125 case SDL_WINDOWEVENT_MINIMIZED:
126 OnResize();
127 break;
128 case SDL_WINDOWEVENT_CLOSE:
129 is_open = false;
130 break;
131 }
132 break;
133 case SDL_KEYDOWN:
134 case SDL_KEYUP:
135 OnKeyEvent(static_cast<int>(event.key.keysym.scancode), event.key.state);
136 break;
137 case SDL_MOUSEMOTION:
138 OnMouseMotion(event.motion.x, event.motion.y);
139 break;
140 case SDL_MOUSEBUTTONDOWN:
141 case SDL_MOUSEBUTTONUP:
142 OnMouseButton(event.button.button, event.button.state, event.button.x, event.button.y);
143 break;
144 case SDL_QUIT:
145 is_open = false;
146 break;
147 }
148 }
149}
150
151void EmuWindow_SDL2::MakeCurrent() {
152 SDL_GL_MakeCurrent(render_window, gl_context);
153}
154
155void EmuWindow_SDL2::DoneCurrent() {
156 SDL_GL_MakeCurrent(render_window, nullptr);
157}
158
159void EmuWindow_SDL2::ReloadSetKeymaps() {
160 for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) {
161 KeyMap::SetKeyMapping({ Settings::values.input_mappings[Settings::NativeInput::All[i]], keyboard_id }, Service::HID::pad_mapping[i]);
162 }
163}
164
165void EmuWindow_SDL2::OnMinimalClientAreaChangeRequest(const std::pair<unsigned, unsigned>& minimal_size) {
166 SDL_SetWindowMinimumSize(render_window, minimal_size.first, minimal_size.second);
167}
diff --git a/src/citra/emu_window/emu_window_sdl2.h b/src/citra/emu_window/emu_window_sdl2.h
new file mode 100644
index 000000000..77279f022
--- /dev/null
+++ b/src/citra/emu_window/emu_window_sdl2.h
@@ -0,0 +1,64 @@
1// Copyright 2016 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 <utility>
8
9#include "common/emu_window.h"
10
11struct SDL_Window;
12
13class EmuWindow_SDL2 : public EmuWindow {
14public:
15 EmuWindow_SDL2();
16 ~EmuWindow_SDL2();
17
18 /// Swap buffers to display the next frame
19 void SwapBuffers() override;
20
21 /// Polls window events
22 void PollEvents() override;
23
24 /// Makes the graphics context current for the caller thread
25 void MakeCurrent() override;
26
27 /// Releases the GL context from the caller thread
28 void DoneCurrent() override;
29
30 /// Whether the window is still open, and a close request hasn't yet been sent
31 bool IsOpen() const;
32
33 /// Load keymap from configuration
34 void ReloadSetKeymaps() override;
35
36private:
37 /// Called by PollEvents when a key is pressed or released.
38 void OnKeyEvent(int key, u8 state);
39
40 /// Called by PollEvents when the mouse moves.
41 void OnMouseMotion(s32 x, s32 y);
42
43 /// Called by PollEvents when a mouse button is pressed or released
44 void OnMouseButton(u32 button, u8 state, s32 x, s32 y);
45
46 /// Called by PollEvents when any event that may cause the window to be resized occurs
47 void OnResize();
48
49 /// Called when a configuration change affects the minimal size of the window
50 void OnMinimalClientAreaChangeRequest(const std::pair<unsigned, unsigned>& minimal_size) override;
51
52 /// Is the window still open?
53 bool is_open = true;
54
55 /// Internal SDL2 render window
56 SDL_Window* render_window;
57
58 using SDL_GLContext = void *;
59 /// The OpenGL context associated with the window
60 SDL_GLContext gl_context;
61
62 /// Device id of keyboard for use with KeyMap
63 int keyboard_id;
64};
diff --git a/src/citra_qt/CMakeLists.txt b/src/citra_qt/CMakeLists.txt
index bbf6ae001..9b3eb2cd6 100644
--- a/src/citra_qt/CMakeLists.txt
+++ b/src/citra_qt/CMakeLists.txt
@@ -79,7 +79,7 @@ if (APPLE)
79else() 79else()
80 add_executable(citra-qt ${SRCS} ${HEADERS} ${UI_HDRS}) 80 add_executable(citra-qt ${SRCS} ${HEADERS} ${UI_HDRS})
81endif() 81endif()
82target_link_libraries(citra-qt core video_core common qhexedit) 82target_link_libraries(citra-qt core video_core audio_core common qhexedit)
83target_link_libraries(citra-qt ${OPENGL_gl_LIBRARY} ${CITRA_QT_LIBS}) 83target_link_libraries(citra-qt ${OPENGL_gl_LIBRARY} ${CITRA_QT_LIBS})
84target_link_libraries(citra-qt ${PLATFORM_LIBRARIES}) 84target_link_libraries(citra-qt ${PLATFORM_LIBRARIES})
85 85
@@ -88,9 +88,14 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Linux|FreeBSD|OpenBSD|NetBSD")
88endif() 88endif()
89 89
90if (Qt5_FOUND AND MSVC) 90if (Qt5_FOUND AND MSVC)
91 include(WindowsCopyFiles)
92
91 set(Qt5_DLL_DIR "${Qt5_DIR}/../../../bin") 93 set(Qt5_DLL_DIR "${Qt5_DIR}/../../../bin")
92 set(Qt5_PLATFORMS_DIR "${Qt5_DIR}/../../../plugins/platforms/") 94 set(Qt5_PLATFORMS_DIR "${Qt5_DIR}/../../../plugins/platforms/")
93 set(Qt5_DLLS 95 set(DLL_DEST "${CMAKE_BINARY_DIR}/bin/$<CONFIG>/")
96 set(PLATFORMS ${DLL_DEST}platforms/)
97
98 windows_copy_files(citra-qt ${Qt5_DLL_DIR} ${DLL_DEST}
94 icudt*.dll 99 icudt*.dll
95 icuin*.dll 100 icuin*.dll
96 icuuc*.dll 101 icuuc*.dll
@@ -99,24 +104,8 @@ if (Qt5_FOUND AND MSVC)
99 Qt5OpenGL$<$<CONFIG:Debug>:d>.* 104 Qt5OpenGL$<$<CONFIG:Debug>:d>.*
100 Qt5Widgets$<$<CONFIG:Debug>:d>.* 105 Qt5Widgets$<$<CONFIG:Debug>:d>.*
101 ) 106 )
102 set(DLL_DEST "${CMAKE_BINARY_DIR}/bin/$<CONFIG>/") 107 windows_copy_files(citra-qt ${Qt5_PLATFORMS_DIR} ${PLATFORMS} qwindows$<$<CONFIG:Debug>:d>.*)
103 set(PLATFORMS ${DLL_DEST}platforms/)
104 108
105 # windows commandline expects the / to be \ so switch them
106 string(REPLACE "/" "\\\\" Qt5_DLL_DIR ${Qt5_DLL_DIR})
107 string(REPLACE "/" "\\\\" Qt5_PLATFORMS_DIR ${Qt5_PLATFORMS_DIR})
108 string(REPLACE "/" "\\\\" DLL_DEST ${DLL_DEST})
109 string(REPLACE "/" "\\\\" PLATFORMS ${PLATFORMS})
110
111 # /NJH /NJS /NDL /NFL /NC /NS /NP - Silence any output
112 # cmake adds an extra check for command success which doesn't work too well with robocopy
113 # so trick it into thinking the command was successful with the || cmd /c "exit /b 0"
114 add_custom_command(TARGET citra-qt POST_BUILD
115 COMMAND robocopy ${Qt5_DLL_DIR} ${DLL_DEST} ${Qt5_DLLS} /NJH /NJS /NDL /NFL /NC /NS /NP || cmd /c "exit /b 0"
116 COMMAND if not exist ${PLATFORMS} mkdir ${PLATFORMS} 2> nul
117 COMMAND robocopy ${Qt5_PLATFORMS_DIR} ${PLATFORMS} qwindows$<$<CONFIG:Debug>:d>.* /NJH /NJS /NDL /NFL /NC /NS /NP || cmd /c "exit /b 0"
118 )
119 unset(Qt5_DLLS)
120 unset(Qt5_DLL_DIR) 109 unset(Qt5_DLL_DIR)
121 unset(Qt5_PLATFORMS_DIR) 110 unset(Qt5_PLATFORMS_DIR)
122 unset(DLL_DEST) 111 unset(DLL_DEST)
diff --git a/src/citra_qt/debugger/callstack.cpp b/src/citra_qt/debugger/callstack.cpp
index d45eed179..793944639 100644
--- a/src/citra_qt/debugger/callstack.cpp
+++ b/src/citra_qt/debugger/callstack.cpp
@@ -29,18 +29,16 @@ CallstackWidget::CallstackWidget(QWidget* parent): QDockWidget(parent)
29 29
30void CallstackWidget::OnDebugModeEntered() 30void CallstackWidget::OnDebugModeEntered()
31{ 31{
32 ARM_Interface* app_core = Core::g_app_core; 32 // Stack pointer
33 33 const u32 sp = Core::g_app_core->GetReg(13);
34 u32 sp = app_core->GetReg(13); //stack pointer
35 u32 ret_addr, call_addr, func_addr;
36 34
37 Clear(); 35 Clear();
38 36
39 int counter = 0; 37 int counter = 0;
40 for (u32 addr = 0x10000000; addr >= sp; addr -= 4) 38 for (u32 addr = 0x10000000; addr >= sp; addr -= 4)
41 { 39 {
42 ret_addr = Memory::Read32(addr); 40 const u32 ret_addr = Memory::Read32(addr);
43 call_addr = ret_addr - 4; //get call address??? 41 const u32 call_addr = ret_addr - 4; //get call address???
44 42
45 if (Memory::GetPointer(call_addr) == nullptr) 43 if (Memory::GetPointer(call_addr) == nullptr)
46 break; 44 break;
@@ -60,7 +58,7 @@ void CallstackWidget::OnDebugModeEntered()
60 // Pre-compute the left-shift and the prefetch offset 58 // Pre-compute the left-shift and the prefetch offset
61 i_offset <<= 2; 59 i_offset <<= 2;
62 i_offset += 8; 60 i_offset += 8;
63 func_addr = call_addr + i_offset; 61 const u32 func_addr = call_addr + i_offset;
64 62
65 callstack_model->setItem(counter, 0, new QStandardItem(QString("0x%1").arg(addr, 8, 16, QLatin1Char('0')))); 63 callstack_model->setItem(counter, 0, new QStandardItem(QString("0x%1").arg(addr, 8, 16, QLatin1Char('0'))));
66 callstack_model->setItem(counter, 1, new QStandardItem(QString("0x%1").arg(ret_addr, 8, 16, QLatin1Char('0')))); 64 callstack_model->setItem(counter, 1, new QStandardItem(QString("0x%1").arg(ret_addr, 8, 16, QLatin1Char('0'))));
diff --git a/src/citra_qt/debugger/graphics_cmdlists.cpp b/src/citra_qt/debugger/graphics_cmdlists.cpp
index ab97c8d2d..5186d2b44 100644
--- a/src/citra_qt/debugger/graphics_cmdlists.cpp
+++ b/src/citra_qt/debugger/graphics_cmdlists.cpp
@@ -21,6 +21,7 @@
21#include "common/vector_math.h" 21#include "common/vector_math.h"
22 22
23#include "video_core/pica.h" 23#include "video_core/pica.h"
24#include "video_core/pica_state.h"
24#include "video_core/debug_utils/debug_utils.h" 25#include "video_core/debug_utils/debug_utils.h"
25 26
26QImage LoadTexture(u8* src, const Pica::DebugUtils::TextureInfo& info) { 27QImage LoadTexture(u8* src, const Pica::DebugUtils::TextureInfo& info) {
diff --git a/src/citra_qt/debugger/graphics_framebuffer.cpp b/src/citra_qt/debugger/graphics_framebuffer.cpp
index 80b32eaff..c30e75933 100644
--- a/src/citra_qt/debugger/graphics_framebuffer.cpp
+++ b/src/citra_qt/debugger/graphics_framebuffer.cpp
@@ -18,6 +18,7 @@
18#include "core/hw/gpu.h" 18#include "core/hw/gpu.h"
19 19
20#include "video_core/pica.h" 20#include "video_core/pica.h"
21#include "video_core/pica_state.h"
21#include "video_core/utils.h" 22#include "video_core/utils.h"
22 23
23GraphicsFramebufferWidget::GraphicsFramebufferWidget(std::shared_ptr<Pica::DebugContext> debug_context, 24GraphicsFramebufferWidget::GraphicsFramebufferWidget(std::shared_ptr<Pica::DebugContext> debug_context,
diff --git a/src/citra_qt/debugger/graphics_tracing.cpp b/src/citra_qt/debugger/graphics_tracing.cpp
index b0bc782df..e06498744 100644
--- a/src/citra_qt/debugger/graphics_tracing.cpp
+++ b/src/citra_qt/debugger/graphics_tracing.cpp
@@ -22,7 +22,7 @@
22#include "nihstro/float24.h" 22#include "nihstro/float24.h"
23 23
24#include "video_core/pica.h" 24#include "video_core/pica.h"
25 25#include "video_core/pica_state.h"
26 26
27GraphicsTracingWidget::GraphicsTracingWidget(std::shared_ptr<Pica::DebugContext> debug_context, 27GraphicsTracingWidget::GraphicsTracingWidget(std::shared_ptr<Pica::DebugContext> debug_context,
28 QWidget* parent) 28 QWidget* parent)
diff --git a/src/citra_qt/debugger/graphics_vertex_shader.cpp b/src/citra_qt/debugger/graphics_vertex_shader.cpp
index a5a5fe6b0..4b676f1b1 100644
--- a/src/citra_qt/debugger/graphics_vertex_shader.cpp
+++ b/src/citra_qt/debugger/graphics_vertex_shader.cpp
@@ -19,6 +19,8 @@
19#include "citra_qt/debugger/graphics_vertex_shader.h" 19#include "citra_qt/debugger/graphics_vertex_shader.h"
20#include "citra_qt/util/util.h" 20#include "citra_qt/util/util.h"
21 21
22#include "video_core/pica.h"
23#include "video_core/pica_state.h"
22#include "video_core/shader/shader.h" 24#include "video_core/shader/shader.h"
23 25
24using nihstro::OpCode; 26using nihstro::OpCode;
@@ -496,8 +498,8 @@ void GraphicsVertexShaderWidget::Reload(bool replace_vertex_data, void* vertex_d
496 // Reload widget state 498 // Reload widget state
497 for (int attr = 0; attr < num_attributes; ++attr) { 499 for (int attr = 0; attr < num_attributes; ++attr) {
498 unsigned source_attr = shader_config.input_register_map.GetRegisterForAttribute(attr); 500 unsigned source_attr = shader_config.input_register_map.GetRegisterForAttribute(attr);
499 input_data_mapping[source_attr]->setText(QString("-> v%1").arg(attr)); 501 input_data_mapping[attr]->setText(QString("-> v%1").arg(source_attr));
500 input_data_container[source_attr]->setVisible(true); 502 input_data_container[attr]->setVisible(true);
501 } 503 }
502 // Only show input attributes which are used as input to the shader 504 // Only show input attributes which are used as input to the shader
503 for (unsigned int attr = num_attributes; attr < 16; ++attr) { 505 for (unsigned int attr = num_attributes; attr < 16; ++attr) {
diff --git a/src/citra_qt/debugger/registers.cpp b/src/citra_qt/debugger/registers.cpp
index 6100d67c5..1bd0bfebc 100644
--- a/src/citra_qt/debugger/registers.cpp
+++ b/src/citra_qt/debugger/registers.cpp
@@ -59,16 +59,14 @@ RegistersWidget::RegistersWidget(QWidget* parent) : QDockWidget(parent) {
59} 59}
60 60
61void RegistersWidget::OnDebugModeEntered() { 61void RegistersWidget::OnDebugModeEntered() {
62 ARM_Interface* app_core = Core::g_app_core; 62 if (!Core::g_app_core)
63
64 if (app_core == nullptr)
65 return; 63 return;
66 64
67 for (int i = 0; i < core_registers->childCount(); ++i) 65 for (int i = 0; i < core_registers->childCount(); ++i)
68 core_registers->child(i)->setText(1, QString("0x%1").arg(app_core->GetReg(i), 8, 16, QLatin1Char('0'))); 66 core_registers->child(i)->setText(1, QString("0x%1").arg(Core::g_app_core->GetReg(i), 8, 16, QLatin1Char('0')));
69 67
70 for (int i = 0; i < vfp_registers->childCount(); ++i) 68 for (int i = 0; i < vfp_registers->childCount(); ++i)
71 vfp_registers->child(i)->setText(1, QString("0x%1").arg(app_core->GetVFPReg(i), 8, 16, QLatin1Char('0'))); 69 vfp_registers->child(i)->setText(1, QString("0x%1").arg(Core::g_app_core->GetVFPReg(i), 8, 16, QLatin1Char('0')));
72 70
73 UpdateCPSRValues(); 71 UpdateCPSRValues();
74 UpdateVFPSystemRegisterValues(); 72 UpdateVFPSystemRegisterValues();
diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp
index d6c27f0df..57adbc136 100644
--- a/src/citra_qt/main.cpp
+++ b/src/citra_qt/main.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 <clocale>
5#include <thread> 6#include <thread>
6 7
7#include <QDesktopWidget> 8#include <QDesktopWidget>
@@ -171,6 +172,8 @@ GMainWindow::GMainWindow() : emu_thread(nullptr)
171 } 172 }
172 UpdateRecentFiles(); 173 UpdateRecentFiles();
173 174
175 confirm_before_closing = settings.value("confirmClose", true).toBool();
176
174 // Setup connections 177 // Setup connections
175 connect(game_list, SIGNAL(GameChosen(QString)), this, SLOT(OnGameListLoadFile(QString))); 178 connect(game_list, SIGNAL(GameChosen(QString)), this, SLOT(OnGameListLoadFile(QString)));
176 connect(ui.action_Load_File, SIGNAL(triggered()), this, SLOT(OnMenuLoadFile())); 179 connect(ui.action_Load_File, SIGNAL(triggered()), this, SLOT(OnMenuLoadFile()));
@@ -208,7 +211,7 @@ GMainWindow::GMainWindow() : emu_thread(nullptr)
208 211
209 show(); 212 show();
210 213
211 game_list->PopulateAsync(settings.value("gameListRootDir").toString(), settings.value("gameListDeepScan").toBool()); 214 game_list->PopulateAsync(settings.value("gameListRootDir", ".").toString(), settings.value("gameListDeepScan", false).toBool());
212 215
213 QStringList args = QApplication::arguments(); 216 QStringList args = QApplication::arguments();
214 if (args.length() >= 2) { 217 if (args.length() >= 2) {
@@ -246,22 +249,73 @@ void GMainWindow::OnDisplayTitleBars(bool show)
246 } 249 }
247} 250}
248 251
249void GMainWindow::BootGame(const std::string& filename) { 252bool GMainWindow::InitializeSystem() {
250 LOG_INFO(Frontend, "Citra starting...");
251
252 // Shutdown previous session if the emu thread is still active... 253 // Shutdown previous session if the emu thread is still active...
253 if (emu_thread != nullptr) 254 if (emu_thread != nullptr)
254 ShutdownGame(); 255 ShutdownGame();
255 256
256 // Initialize the core emulation 257 // Initialize the core emulation
257 System::Init(render_window); 258 System::Result system_result = System::Init(render_window);
259 if (System::Result::Success != system_result) {
260 switch (system_result) {
261 case System::Result::ErrorInitVideoCore:
262 QMessageBox::critical(this, tr("Error while starting Citra!"),
263 tr("Failed to initialize the video core!\n\n"
264 "Please ensure that your GPU supports OpenGL 3.3 and that you have the latest graphics driver."));
265 break;
266
267 default:
268 QMessageBox::critical(this, tr("Error while starting Citra!"),
269 tr("Unknown error (please check the log)!"));
270 break;
271 }
272 return false;
273 }
274 return true;
275}
258 276
259 // Load the game 277bool GMainWindow::LoadROM(const std::string& filename) {
260 if (Loader::ResultStatus::Success != Loader::LoadFile(filename)) { 278 Loader::ResultStatus result = Loader::LoadFile(filename);
279 if (Loader::ResultStatus::Success != result) {
261 LOG_CRITICAL(Frontend, "Failed to load ROM!"); 280 LOG_CRITICAL(Frontend, "Failed to load ROM!");
262 System::Shutdown(); 281 System::Shutdown();
263 return; 282
283 switch (result) {
284 case Loader::ResultStatus::ErrorEncrypted: {
285 // Build the MessageBox ourselves to have clickable link
286 QMessageBox popup_error;
287 popup_error.setTextFormat(Qt::RichText);
288 popup_error.setWindowTitle(tr("Error while loading ROM!"));
289 popup_error.setText(tr("The game that you are trying to load must be decrypted before being used with Citra.<br/><br/>"
290 "For more information on dumping and decrypting games, please see: <a href='https://citra-emu.org/wiki/Dumping-Game-Cartridges'>https://citra-emu.org/wiki/Dumping-Game-Cartridges</a>"));
291 popup_error.setIcon(QMessageBox::Critical);
292 popup_error.exec();
293 break;
294 }
295 case Loader::ResultStatus::ErrorInvalidFormat:
296 QMessageBox::critical(this, tr("Error while loading ROM!"),
297 tr("The ROM format is not supported."));
298 break;
299 case Loader::ResultStatus::Error:
300
301 default:
302 QMessageBox::critical(this, tr("Error while loading ROM!"),
303 tr("Unknown error!"));
304 break;
305 }
306 return false;
264 } 307 }
308 return true;
309}
310
311void GMainWindow::BootGame(const std::string& filename) {
312 LOG_INFO(Frontend, "Citra starting...");
313
314 if (!InitializeSystem())
315 return;
316
317 if (!LoadROM(filename))
318 return;
265 319
266 // Create and start the emulation thread 320 // Create and start the emulation thread
267 emu_thread = Common::make_unique<EmuThread>(render_window); 321 emu_thread = Common::make_unique<EmuThread>(render_window);
@@ -497,7 +551,22 @@ void GMainWindow::OnConfigure() {
497 //GControllerConfigDialog* dialog = new GControllerConfigDialog(controller_ports, this); 551 //GControllerConfigDialog* dialog = new GControllerConfigDialog(controller_ports, this);
498} 552}
499 553
554bool GMainWindow::ConfirmClose() {
555 if (emu_thread == nullptr || !confirm_before_closing)
556 return true;
557
558 auto answer = QMessageBox::question(this, tr("Citra"),
559 tr("Are you sure you want to close Citra?"),
560 QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
561 return answer != QMessageBox::No;
562}
563
500void GMainWindow::closeEvent(QCloseEvent* event) { 564void GMainWindow::closeEvent(QCloseEvent* event) {
565 if (!ConfirmClose()) {
566 event->ignore();
567 return;
568 }
569
501 // Save window layout 570 // Save window layout
502 QSettings settings(QSettings::IniFormat, QSettings::UserScope, "Citra team", "Citra"); 571 QSettings settings(QSettings::IniFormat, QSettings::UserScope, "Citra team", "Citra");
503 572
@@ -512,6 +581,7 @@ void GMainWindow::closeEvent(QCloseEvent* event) {
512 settings.setValue("singleWindowMode", ui.action_Single_Window_Mode->isChecked()); 581 settings.setValue("singleWindowMode", ui.action_Single_Window_Mode->isChecked());
513 settings.setValue("displayTitleBars", ui.actionDisplay_widget_title_bars->isChecked()); 582 settings.setValue("displayTitleBars", ui.actionDisplay_widget_title_bars->isChecked());
514 settings.setValue("firstStart", false); 583 settings.setValue("firstStart", false);
584 settings.setValue("confirmClose", confirm_before_closing);
515 game_list->SaveInterfaceLayout(settings); 585 game_list->SaveInterfaceLayout(settings);
516 SaveHotkeys(settings); 586 SaveHotkeys(settings);
517 587
@@ -545,6 +615,9 @@ int main(int argc, char* argv[]) {
545 QApplication::setAttribute(Qt::AA_X11InitThreads); 615 QApplication::setAttribute(Qt::AA_X11InitThreads);
546 QApplication app(argc, argv); 616 QApplication app(argc, argv);
547 617
618 // Qt changes the locale and causes issues in float conversion using std::to_string() when generating shaders
619 setlocale(LC_ALL, "C");
620
548 GMainWindow main_window; 621 GMainWindow main_window;
549 // After settings have been loaded by GMainWindow, apply the filter 622 // After settings have been loaded by GMainWindow, apply the filter
550 log_filter.ParseFilterString(Settings::values.log_filter); 623 log_filter.ParseFilterString(Settings::values.log_filter);
diff --git a/src/citra_qt/main.h b/src/citra_qt/main.h
index f6d429cd9..945aea0cd 100644
--- a/src/citra_qt/main.h
+++ b/src/citra_qt/main.h
@@ -59,6 +59,8 @@ signals:
59 void EmulationStopping(); 59 void EmulationStopping();
60 60
61private: 61private:
62 bool InitializeSystem();
63 bool LoadROM(const std::string& filename);
62 void BootGame(const std::string& filename); 64 void BootGame(const std::string& filename);
63 void ShutdownGame(); 65 void ShutdownGame();
64 66
@@ -82,6 +84,13 @@ private:
82 */ 84 */
83 void UpdateRecentFiles(); 85 void UpdateRecentFiles();
84 86
87 /**
88 * If the emulation is running,
89 * asks the user if he really want to close the emulator
90 *
91 * @return true if the user confirmed
92 */
93 bool ConfirmClose();
85 void closeEvent(QCloseEvent* event) override; 94 void closeEvent(QCloseEvent* event) override;
86 95
87private slots: 96private slots:
@@ -122,6 +131,7 @@ private:
122 GPUCommandListWidget* graphicsCommandsWidget; 131 GPUCommandListWidget* graphicsCommandsWidget;
123 132
124 QAction* actions_recent_files[max_recent_files_item]; 133 QAction* actions_recent_files[max_recent_files_item];
134 bool confirm_before_closing;
125}; 135};
126 136
127#endif // _CITRA_QT_MAIN_HXX_ 137#endif // _CITRA_QT_MAIN_HXX_
diff --git a/src/common/bit_field.h b/src/common/bit_field.h
index 66689f398..371eb17a1 100644
--- a/src/common/bit_field.h
+++ b/src/common/bit_field.h
@@ -115,29 +115,24 @@ template<std::size_t position, std::size_t bits, typename T>
115struct BitField 115struct BitField
116{ 116{
117private: 117private:
118 // This constructor might be considered ambiguous: 118 // We hide the copy assigment operator here, because the default copy
119 // Would it initialize the storage or just the bitfield? 119 // assignment would copy the full storage value, rather than just the bits
120 // Hence, delete it. Use the assignment operator to set bitfield values! 120 // relevant to this particular bit field.
121 BitField(T val) = delete; 121 // We don't delete it because we want BitField to be trivially copyable.
122 BitField& operator=(const BitField&) = default;
122 123
123public: 124public:
125 // This constructor and assignment operator might be considered ambiguous:
126 // Would they initialize the storage or just the bitfield?
127 // Hence, delete them. Use the Assign method to set bitfield values!
128 BitField(T val) = delete;
129 BitField& operator=(T val) = delete;
130
124 // Force default constructor to be created 131 // Force default constructor to be created
125 // so that we can use this within unions 132 // so that we can use this within unions
126 BitField() = default; 133 BitField() = default;
127 134
128 // We explicitly delete the copy assigment operator here, because the 135 FORCE_INLINE operator T() const {
129 // default copy assignment would copy the full storage value, rather than
130 // just the bits relevant to this particular bit field.
131 BitField& operator=(const BitField&) = delete;
132
133 FORCE_INLINE BitField& operator=(T val)
134 {
135 Assign(val);
136 return *this;
137 }
138
139 FORCE_INLINE operator T() const
140 {
141 return Value(); 136 return Value();
142 } 137 }
143 138
@@ -145,8 +140,7 @@ public:
145 storage = (storage & ~GetMask()) | (((StorageType)value << position) & GetMask()); 140 storage = (storage & ~GetMask()) | (((StorageType)value << position) & GetMask());
146 } 141 }
147 142
148 FORCE_INLINE T Value() const 143 FORCE_INLINE T Value() const {
149 {
150 if (std::numeric_limits<T>::is_signed) 144 if (std::numeric_limits<T>::is_signed)
151 { 145 {
152 std::size_t shift = 8 * sizeof(T)-bits; 146 std::size_t shift = 8 * sizeof(T)-bits;
@@ -159,8 +153,7 @@ public:
159 } 153 }
160 154
161 // TODO: we may want to change this to explicit operator bool() if it's bug-free in VS2015 155 // TODO: we may want to change this to explicit operator bool() if it's bug-free in VS2015
162 FORCE_INLINE bool ToBool() const 156 FORCE_INLINE bool ToBool() const {
163 {
164 return Value() != 0; 157 return Value() != 0;
165 } 158 }
166 159
@@ -176,8 +169,7 @@ private:
176 // Unsigned version of StorageType 169 // Unsigned version of StorageType
177 typedef typename std::make_unsigned<StorageType>::type StorageTypeU; 170 typedef typename std::make_unsigned<StorageType>::type StorageTypeU;
178 171
179 FORCE_INLINE StorageType GetMask() const 172 FORCE_INLINE StorageType GetMask() const {
180 {
181 return (((StorageTypeU)~0) >> (8 * sizeof(T)-bits)) << position; 173 return (((StorageTypeU)~0) >> (8 * sizeof(T)-bits)) << position;
182 } 174 }
183 175
@@ -189,6 +181,10 @@ private:
189 static_assert(position < 8 * sizeof(T), "Invalid position"); 181 static_assert(position < 8 * sizeof(T), "Invalid position");
190 static_assert(bits <= 8 * sizeof(T), "Invalid number of bits"); 182 static_assert(bits <= 8 * sizeof(T), "Invalid number of bits");
191 static_assert(bits > 0, "Invalid number of bits"); 183 static_assert(bits > 0, "Invalid number of bits");
192 static_assert(std::is_standard_layout<T>::value, "Invalid base type"); 184 static_assert(std::is_pod<T>::value, "Invalid base type");
193}; 185};
194#pragma pack() 186#pragma pack()
187
188#if (__GNUC__ >= 5) || defined(__clang__) || defined(_MSC_VER)
189static_assert(std::is_trivially_copyable<BitField<0, 1, u32>>::value, "BitField must be trivially copyable");
190#endif
diff --git a/src/common/color.h b/src/common/color.h
index eb199e308..908879ea6 100644
--- a/src/common/color.h
+++ b/src/common/color.h
@@ -11,42 +11,42 @@
11namespace Color { 11namespace Color {
12 12
13/// Convert a 1-bit color component to 8 bit 13/// Convert a 1-bit color component to 8 bit
14inline u8 Convert1To8(u8 value) { 14constexpr u8 Convert1To8(u8 value) {
15 return value * 255; 15 return value * 255;
16} 16}
17 17
18/// Convert a 4-bit color component to 8 bit 18/// Convert a 4-bit color component to 8 bit
19inline u8 Convert4To8(u8 value) { 19constexpr u8 Convert4To8(u8 value) {
20 return (value << 4) | value; 20 return (value << 4) | value;
21} 21}
22 22
23/// Convert a 5-bit color component to 8 bit 23/// Convert a 5-bit color component to 8 bit
24inline u8 Convert5To8(u8 value) { 24constexpr u8 Convert5To8(u8 value) {
25 return (value << 3) | (value >> 2); 25 return (value << 3) | (value >> 2);
26} 26}
27 27
28/// Convert a 6-bit color component to 8 bit 28/// Convert a 6-bit color component to 8 bit
29inline u8 Convert6To8(u8 value) { 29constexpr u8 Convert6To8(u8 value) {
30 return (value << 2) | (value >> 4); 30 return (value << 2) | (value >> 4);
31} 31}
32 32
33/// Convert a 8-bit color component to 1 bit 33/// Convert a 8-bit color component to 1 bit
34inline u8 Convert8To1(u8 value) { 34constexpr u8 Convert8To1(u8 value) {
35 return value >> 7; 35 return value >> 7;
36} 36}
37 37
38/// Convert a 8-bit color component to 4 bit 38/// Convert a 8-bit color component to 4 bit
39inline u8 Convert8To4(u8 value) { 39constexpr u8 Convert8To4(u8 value) {
40 return value >> 4; 40 return value >> 4;
41} 41}
42 42
43/// Convert a 8-bit color component to 5 bit 43/// Convert a 8-bit color component to 5 bit
44inline u8 Convert8To5(u8 value) { 44constexpr u8 Convert8To5(u8 value) {
45 return value >> 3; 45 return value >> 3;
46} 46}
47 47
48/// Convert a 8-bit color component to 6 bit 48/// Convert a 8-bit color component to 6 bit
49inline u8 Convert8To6(u8 value) { 49constexpr u8 Convert8To6(u8 value) {
50 return value >> 2; 50 return value >> 2;
51} 51}
52 52
diff --git a/src/common/common_funcs.h b/src/common/common_funcs.h
index ed20c3629..aa6aff7b9 100644
--- a/src/common/common_funcs.h
+++ b/src/common/common_funcs.h
@@ -18,19 +18,11 @@
18#define INSERT_PADDING_BYTES(num_bytes) u8 CONCAT2(pad, __LINE__)[(num_bytes)] 18#define INSERT_PADDING_BYTES(num_bytes) u8 CONCAT2(pad, __LINE__)[(num_bytes)]
19#define INSERT_PADDING_WORDS(num_words) u32 CONCAT2(pad, __LINE__)[(num_words)] 19#define INSERT_PADDING_WORDS(num_words) u32 CONCAT2(pad, __LINE__)[(num_words)]
20 20
21// Inlining
21#ifdef _WIN32 22#ifdef _WIN32
22 // Alignment
23 #define FORCE_INLINE __forceinline 23 #define FORCE_INLINE __forceinline
24 #define MEMORY_ALIGNED16(x) __declspec(align(16)) x
25 #define MEMORY_ALIGNED32(x) __declspec(align(32)) x
26 #define MEMORY_ALIGNED64(x) __declspec(align(64)) x
27 #define MEMORY_ALIGNED128(x) __declspec(align(128)) x
28#else 24#else
29 #define FORCE_INLINE inline __attribute__((always_inline)) 25 #define FORCE_INLINE inline __attribute__((always_inline))
30 #define MEMORY_ALIGNED16(x) __attribute__((aligned(16))) x
31 #define MEMORY_ALIGNED32(x) __attribute__((aligned(32))) x
32 #define MEMORY_ALIGNED64(x) __attribute__((aligned(64))) x
33 #define MEMORY_ALIGNED128(x) __attribute__((aligned(128))) x
34#endif 26#endif
35 27
36#ifndef _MSC_VER 28#ifndef _MSC_VER
diff --git a/src/common/emu_window.cpp b/src/common/emu_window.cpp
index b69b05cb9..b2807354a 100644
--- a/src/common/emu_window.cpp
+++ b/src/common/emu_window.cpp
@@ -55,14 +55,14 @@ void EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y) {
55 (framebuffer_layout.bottom_screen.bottom - framebuffer_layout.bottom_screen.top); 55 (framebuffer_layout.bottom_screen.bottom - framebuffer_layout.bottom_screen.top);
56 56
57 touch_pressed = true; 57 touch_pressed = true;
58 pad_state.touch = 1; 58 pad_state.touch.Assign(1);
59} 59}
60 60
61void EmuWindow::TouchReleased() { 61void EmuWindow::TouchReleased() {
62 touch_pressed = false; 62 touch_pressed = false;
63 touch_x = 0; 63 touch_x = 0;
64 touch_y = 0; 64 touch_y = 0;
65 pad_state.touch = 0; 65 pad_state.touch.Assign(0);
66} 66}
67 67
68void EmuWindow::TouchMoved(unsigned framebuffer_x, unsigned framebuffer_y) { 68void EmuWindow::TouchMoved(unsigned framebuffer_x, unsigned framebuffer_y) {
diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp
index 4c7113390..c3061479a 100644
--- a/src/common/file_util.cpp
+++ b/src/common/file_util.cpp
@@ -427,6 +427,9 @@ bool ForeachDirectoryEntry(unsigned* num_entries_out, const std::string &directo
427 // How many files + directories we found 427 // How many files + directories we found
428 unsigned found_entries = 0; 428 unsigned found_entries = 0;
429 429
430 // Save the status of callback function
431 bool callback_error = false;
432
430#ifdef _WIN32 433#ifdef _WIN32
431 // Find the first file in the directory. 434 // Find the first file in the directory.
432 WIN32_FIND_DATA ffd; 435 WIN32_FIND_DATA ffd;
@@ -454,9 +457,11 @@ bool ForeachDirectoryEntry(unsigned* num_entries_out, const std::string &directo
454 if (virtual_name == "." || virtual_name == "..") 457 if (virtual_name == "." || virtual_name == "..")
455 continue; 458 continue;
456 459
457 unsigned ret_entries; 460 unsigned ret_entries = 0;
458 if (!callback(&ret_entries, directory, virtual_name)) 461 if (!callback(&ret_entries, directory, virtual_name)) {
462 callback_error = true;
459 break; 463 break;
464 }
460 found_entries += ret_entries; 465 found_entries += ret_entries;
461 466
462#ifdef _WIN32 467#ifdef _WIN32
@@ -467,9 +472,14 @@ bool ForeachDirectoryEntry(unsigned* num_entries_out, const std::string &directo
467 closedir(dirp); 472 closedir(dirp);
468#endif 473#endif
469 474
470 // num_entries_out is allowed to be specified nullptr, in which case we shouldn't try to set it 475 if (!callback_error) {
471 if (num_entries_out != nullptr) 476 // num_entries_out is allowed to be specified nullptr, in which case we shouldn't try to set it
472 *num_entries_out = found_entries; 477 if (num_entries_out != nullptr)
478 *num_entries_out = found_entries;
479 return true;
480 } else {
481 return false;
482 }
473} 483}
474 484
475unsigned ScanDirectoryTree(const std::string &directory, FSTEntry& parent_entry) 485unsigned ScanDirectoryTree(const std::string &directory, FSTEntry& parent_entry)
diff --git a/src/common/key_map.h b/src/common/key_map.h
index 0ecec714f..68f7e2f99 100644
--- a/src/common/key_map.h
+++ b/src/common/key_map.h
@@ -4,6 +4,7 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <tuple>
7#include "core/hle/service/hid/hid.h" 8#include "core/hle/service/hid/hid.h"
8 9
9namespace KeyMap { 10namespace KeyMap {
@@ -15,15 +16,14 @@ struct HostDeviceKey {
15 int key_code; 16 int key_code;
16 int device_id; ///< Uniquely identifies a host device 17 int device_id; ///< Uniquely identifies a host device
17 18
18 bool operator < (const HostDeviceKey &other) const { 19 bool operator<(const HostDeviceKey &other) const {
19 if (device_id == other.device_id) { 20 return std::tie(key_code, device_id) <
20 return key_code < other.key_code; 21 std::tie(other.key_code, other.device_id);
21 }
22 return device_id < other.device_id;
23 } 22 }
24 23
25 bool operator == (const HostDeviceKey &other) const { 24 bool operator==(const HostDeviceKey &other) const {
26 return device_id == other.device_id && key_code == other.key_code; 25 return std::tie(key_code, device_id) ==
26 std::tie(other.key_code, other.device_id);
27 } 27 }
28}; 28};
29 29
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp
index 21a9ae8d0..54291429a 100644
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -44,10 +44,12 @@ namespace Log {
44 SUB(Service, LDR) \ 44 SUB(Service, LDR) \
45 SUB(Service, NIM) \ 45 SUB(Service, NIM) \
46 SUB(Service, NWM) \ 46 SUB(Service, NWM) \
47 SUB(Service, CAM) \
47 SUB(Service, CFG) \ 48 SUB(Service, CFG) \
48 SUB(Service, DSP) \ 49 SUB(Service, DSP) \
49 SUB(Service, HID) \ 50 SUB(Service, HID) \
50 SUB(Service, SOC) \ 51 SUB(Service, SOC) \
52 SUB(Service, IR) \
51 SUB(Service, Y2R) \ 53 SUB(Service, Y2R) \
52 CLS(HW) \ 54 CLS(HW) \
53 SUB(HW, Memory) \ 55 SUB(HW, Memory) \
@@ -57,6 +59,8 @@ namespace Log {
57 CLS(Render) \ 59 CLS(Render) \
58 SUB(Render, Software) \ 60 SUB(Render, Software) \
59 SUB(Render, OpenGL) \ 61 SUB(Render, OpenGL) \
62 CLS(Audio) \
63 SUB(Audio, DSP) \
60 CLS(Loader) 64 CLS(Loader)
61 65
62// GetClassName is a macro defined by Windows.h, grrr... 66// GetClassName is a macro defined by Windows.h, grrr...
diff --git a/src/common/logging/backend.h b/src/common/logging/backend.h
index c1f4d08e4..795d42ebd 100644
--- a/src/common/logging/backend.h
+++ b/src/common/logging/backend.h
@@ -27,25 +27,9 @@ struct Entry {
27 std::string message; 27 std::string message;
28 28
29 Entry() = default; 29 Entry() = default;
30 Entry(Entry&& o) = default;
30 31
31 // TODO(yuriks) Use defaulted move constructors once MSVC supports them 32 Entry& operator=(Entry&& o) = default;
32#define MOVE(member) member(std::move(o.member))
33 Entry(Entry&& o)
34 : MOVE(timestamp), MOVE(log_class), MOVE(log_level),
35 MOVE(location), MOVE(message)
36 {}
37#undef MOVE
38
39 Entry& operator=(const Entry&& o) {
40#define MOVE(member) member = std::move(o.member)
41 MOVE(timestamp);
42 MOVE(log_class);
43 MOVE(log_level);
44 MOVE(location);
45 MOVE(message);
46#undef MOVE
47 return *this;
48 }
49}; 33};
50 34
51/** 35/**
diff --git a/src/common/logging/log.h b/src/common/logging/log.h
index 43f0c59e4..4b01805ae 100644
--- a/src/common/logging/log.h
+++ b/src/common/logging/log.h
@@ -59,10 +59,12 @@ enum class Class : ClassType {
59 Service_LDR, ///< The LDR (3ds dll loader) service 59 Service_LDR, ///< The LDR (3ds dll loader) service
60 Service_NIM, ///< The NIM (Network interface manager) service 60 Service_NIM, ///< The NIM (Network interface manager) service
61 Service_NWM, ///< The NWM (Network wlan manager) service 61 Service_NWM, ///< The NWM (Network wlan manager) service
62 Service_CAM, ///< The CAM (Camera) service
62 Service_CFG, ///< The CFG (Configuration) service 63 Service_CFG, ///< The CFG (Configuration) service
63 Service_DSP, ///< The DSP (DSP control) service 64 Service_DSP, ///< The DSP (DSP control) service
64 Service_HID, ///< The HID (Human interface device) service 65 Service_HID, ///< The HID (Human interface device) service
65 Service_SOC, ///< The SOC (Socket) service 66 Service_SOC, ///< The SOC (Socket) service
67 Service_IR, ///< The IR service
66 Service_Y2R, ///< The Y2R (YUV to RGB conversion) service 68 Service_Y2R, ///< The Y2R (YUV to RGB conversion) service
67 HW, ///< Low-level hardware emulation 69 HW, ///< Low-level hardware emulation
68 HW_Memory, ///< Memory-map and address translation 70 HW_Memory, ///< Memory-map and address translation
@@ -72,6 +74,8 @@ enum class Class : ClassType {
72 Render, ///< Emulator video output and hardware acceleration 74 Render, ///< Emulator video output and hardware acceleration
73 Render_Software, ///< Software renderer backend 75 Render_Software, ///< Software renderer backend
74 Render_OpenGL, ///< OpenGL backend 76 Render_OpenGL, ///< OpenGL backend
77 Audio, ///< Emulator audio output
78 Audio_DSP, ///< The HLE implementation of the DSP
75 Loader, ///< ROM loader 79 Loader, ///< ROM loader
76 80
77 Count ///< Total number of logging classes 81 Count ///< Total number of logging classes
diff --git a/src/common/x64/emitter.cpp b/src/common/x64/emitter.cpp
index 939df210e..1dcf2416c 100644
--- a/src/common/x64/emitter.cpp
+++ b/src/common/x64/emitter.cpp
@@ -225,14 +225,14 @@ void OpArg::WriteVex(XEmitter* emit, X64Reg regOp1, X64Reg regOp2, int L, int pp
225 // do we need any VEX fields that only appear in the three-byte form? 225 // do we need any VEX fields that only appear in the three-byte form?
226 if (X == 1 && B == 1 && W == 0 && mmmmm == 1) 226 if (X == 1 && B == 1 && W == 0 && mmmmm == 1)
227 { 227 {
228 u8 RvvvvLpp = (R << 7) | (vvvv << 3) | (L << 1) | pp; 228 u8 RvvvvLpp = (R << 7) | (vvvv << 3) | (L << 2) | pp;
229 emit->Write8(0xC5); 229 emit->Write8(0xC5);
230 emit->Write8(RvvvvLpp); 230 emit->Write8(RvvvvLpp);
231 } 231 }
232 else 232 else
233 { 233 {
234 u8 RXBmmmmm = (R << 7) | (X << 6) | (B << 5) | mmmmm; 234 u8 RXBmmmmm = (R << 7) | (X << 6) | (B << 5) | mmmmm;
235 u8 WvvvvLpp = (W << 7) | (vvvv << 3) | (L << 1) | pp; 235 u8 WvvvvLpp = (W << 7) | (vvvv << 3) | (L << 2) | pp;
236 emit->Write8(0xC4); 236 emit->Write8(0xC4);
237 emit->Write8(RXBmmmmm); 237 emit->Write8(RXBmmmmm);
238 emit->Write8(WvvvvLpp); 238 emit->Write8(WvvvvLpp);
diff --git a/src/common/x64/emitter.h b/src/common/x64/emitter.h
index 2dd0dc94e..7c6548fb5 100644
--- a/src/common/x64/emitter.h
+++ b/src/common/x64/emitter.h
@@ -157,45 +157,37 @@ class XEmitter;
157// RIP addressing does not benefit from micro op fusion on Core arch 157// RIP addressing does not benefit from micro op fusion on Core arch
158struct OpArg 158struct OpArg
159{ 159{
160 OpArg() {} // dummy op arg, used for storage 160 friend class XEmitter;
161 OpArg(u64 _offset, int _scale, X64Reg rmReg = RAX, X64Reg scaledReg = RAX) 161
162 constexpr OpArg() = default; // dummy op arg, used for storage
163 constexpr OpArg(u64 offset_, int scale_, X64Reg rmReg = RAX, X64Reg scaledReg = RAX)
164 : scale(static_cast<u8>(scale_))
165 , offsetOrBaseReg(static_cast<u16>(rmReg))
166 , indexReg(static_cast<u16>(scaledReg))
167 , offset(offset_)
162 { 168 {
163 operandReg = 0;
164 scale = (u8)_scale;
165 offsetOrBaseReg = (u16)rmReg;
166 indexReg = (u16)scaledReg;
167 //if scale == 0 never mind offsetting
168 offset = _offset;
169 } 169 }
170 bool operator==(const OpArg &b) const 170
171 constexpr bool operator==(const OpArg &b) const
171 { 172 {
172 return operandReg == b.operandReg && scale == b.scale && offsetOrBaseReg == b.offsetOrBaseReg && 173 return operandReg == b.operandReg &&
173 indexReg == b.indexReg && offset == b.offset; 174 scale == b.scale &&
175 offsetOrBaseReg == b.offsetOrBaseReg &&
176 indexReg == b.indexReg &&
177 offset == b.offset;
174 } 178 }
179
175 void WriteRex(XEmitter *emit, int opBits, int bits, int customOp = -1) const; 180 void WriteRex(XEmitter *emit, int opBits, int bits, int customOp = -1) const;
176 void WriteVex(XEmitter* emit, X64Reg regOp1, X64Reg regOp2, int L, int pp, int mmmmm, int W = 0) const; 181 void WriteVex(XEmitter* emit, X64Reg regOp1, X64Reg regOp2, int L, int pp, int mmmmm, int W = 0) const;
177 void WriteRest(XEmitter *emit, int extraBytes=0, X64Reg operandReg=INVALID_REG, bool warn_64bit_offset = true) const; 182 void WriteRest(XEmitter *emit, int extraBytes=0, X64Reg operandReg=INVALID_REG, bool warn_64bit_offset = true) const;
178 void WriteFloatModRM(XEmitter *emit, FloatOp op);
179 void WriteSingleByteOp(XEmitter *emit, u8 op, X64Reg operandReg, int bits); 183 void WriteSingleByteOp(XEmitter *emit, u8 op, X64Reg operandReg, int bits);
180 // This one is public - must be written to
181 u64 offset; // use RIP-relative as much as possible - 64-bit immediates are not available.
182 u16 operandReg;
183
184 void WriteNormalOp(XEmitter *emit, bool toRM, NormalOp op, const OpArg &operand, int bits) const; 184 void WriteNormalOp(XEmitter *emit, bool toRM, NormalOp op, const OpArg &operand, int bits) const;
185 bool IsImm() const {return scale == SCALE_IMM8 || scale == SCALE_IMM16 || scale == SCALE_IMM32 || scale == SCALE_IMM64;}
186 bool IsSimpleReg() const {return scale == SCALE_NONE;}
187 bool IsSimpleReg(X64Reg reg) const
188 {
189 if (!IsSimpleReg())
190 return false;
191 return GetSimpleReg() == reg;
192 }
193 185
194 bool CanDoOpWith(const OpArg &other) const 186 constexpr bool IsImm() const { return scale == SCALE_IMM8 || scale == SCALE_IMM16 || scale == SCALE_IMM32 || scale == SCALE_IMM64; }
187 constexpr bool IsSimpleReg() const { return scale == SCALE_NONE; }
188 constexpr bool IsSimpleReg(X64Reg reg) const
195 { 189 {
196 if (IsSimpleReg()) return true; 190 return IsSimpleReg() && GetSimpleReg() == reg;
197 if (!IsSimpleReg() && !other.IsSimpleReg() && !other.IsImm()) return false;
198 return true;
199 } 191 }
200 192
201 int GetImmBits() const 193 int GetImmBits() const
@@ -220,16 +212,15 @@ struct OpArg
220 } 212 }
221 } 213 }
222 214
223 X64Reg GetSimpleReg() const 215 constexpr X64Reg GetSimpleReg() const
224 { 216 {
225 if (scale == SCALE_NONE) 217 return scale == SCALE_NONE
226 return (X64Reg)offsetOrBaseReg; 218 ? static_cast<X64Reg>(offsetOrBaseReg)
227 else 219 : INVALID_REG;
228 return INVALID_REG;
229 } 220 }
230 221
231 u32 GetImmValue() const { 222 constexpr u32 GetImmValue() const {
232 return (u32)offset; 223 return static_cast<u32>(offset);
233 } 224 }
234 225
235 // For loops. 226 // For loops.
@@ -238,56 +229,60 @@ struct OpArg
238 } 229 }
239 230
240private: 231private:
241 u8 scale; 232 u8 scale = 0;
242 u16 offsetOrBaseReg; 233 u16 offsetOrBaseReg = 0;
243 u16 indexReg; 234 u16 indexReg = 0;
235 u64 offset = 0; // use RIP-relative as much as possible - 64-bit immediates are not available.
236 u16 operandReg = 0;
244}; 237};
245 238
246inline OpArg M(const void *ptr) {return OpArg((u64)ptr, (int)SCALE_RIP);}
247template <typename T> 239template <typename T>
248inline OpArg M(const T *ptr) {return OpArg((u64)(const void *)ptr, (int)SCALE_RIP);} 240inline OpArg M(const T *ptr) { return OpArg(reinterpret_cast<u64>(ptr), static_cast<int>(SCALE_RIP)); }
249inline OpArg R(X64Reg value) {return OpArg(0, SCALE_NONE, value);} 241constexpr OpArg R(X64Reg value) { return OpArg(0, SCALE_NONE, value); }
250inline OpArg MatR(X64Reg value) {return OpArg(0, SCALE_ATREG, value);} 242constexpr OpArg MatR(X64Reg value) { return OpArg(0, SCALE_ATREG, value); }
251 243
252inline OpArg MDisp(X64Reg value, int offset) 244constexpr OpArg MDisp(X64Reg value, int offset)
253{ 245{
254 return OpArg((u32)offset, SCALE_ATREG, value); 246 return OpArg(static_cast<u32>(offset), SCALE_ATREG, value);
255} 247}
256 248
257inline OpArg MComplex(X64Reg base, X64Reg scaled, int scale, int offset) 249constexpr OpArg MComplex(X64Reg base, X64Reg scaled, int scale, int offset)
258{ 250{
259 return OpArg(offset, scale, base, scaled); 251 return OpArg(offset, scale, base, scaled);
260} 252}
261 253
262inline OpArg MScaled(X64Reg scaled, int scale, int offset) 254constexpr OpArg MScaled(X64Reg scaled, int scale, int offset)
263{ 255{
264 if (scale == SCALE_1) 256 return scale == SCALE_1
265 return OpArg(offset, SCALE_ATREG, scaled); 257 ? OpArg(offset, SCALE_ATREG, scaled)
266 else 258 : OpArg(offset, scale | 0x20, RAX, scaled);
267 return OpArg(offset, scale | 0x20, RAX, scaled);
268} 259}
269 260
270inline OpArg MRegSum(X64Reg base, X64Reg offset) 261constexpr OpArg MRegSum(X64Reg base, X64Reg offset)
271{ 262{
272 return MComplex(base, offset, 1, 0); 263 return MComplex(base, offset, 1, 0);
273} 264}
274 265
275inline OpArg Imm8 (u8 imm) {return OpArg(imm, SCALE_IMM8);} 266constexpr OpArg Imm8 (u8 imm) { return OpArg(imm, SCALE_IMM8); }
276inline OpArg Imm16(u16 imm) {return OpArg(imm, SCALE_IMM16);} //rarely used 267constexpr OpArg Imm16(u16 imm) { return OpArg(imm, SCALE_IMM16); } //rarely used
277inline OpArg Imm32(u32 imm) {return OpArg(imm, SCALE_IMM32);} 268constexpr OpArg Imm32(u32 imm) { return OpArg(imm, SCALE_IMM32); }
278inline OpArg Imm64(u64 imm) {return OpArg(imm, SCALE_IMM64);} 269constexpr OpArg Imm64(u64 imm) { return OpArg(imm, SCALE_IMM64); }
279inline OpArg UImmAuto(u32 imm) { 270constexpr OpArg UImmAuto(u32 imm) {
280 return OpArg(imm, imm >= 128 ? SCALE_IMM32 : SCALE_IMM8); 271 return OpArg(imm, imm >= 128 ? SCALE_IMM32 : SCALE_IMM8);
281} 272}
282inline OpArg SImmAuto(s32 imm) { 273constexpr OpArg SImmAuto(s32 imm) {
283 return OpArg(imm, (imm >= 128 || imm < -128) ? SCALE_IMM32 : SCALE_IMM8); 274 return OpArg(imm, (imm >= 128 || imm < -128) ? SCALE_IMM32 : SCALE_IMM8);
284} 275}
285 276
277template <typename T>
278OpArg ImmPtr(const T* imm)
279{
286#ifdef _ARCH_64 280#ifdef _ARCH_64
287inline OpArg ImmPtr(const void* imm) {return Imm64((u64)imm);} 281 return Imm64(reinterpret_cast<u64>(imm));
288#else 282#else
289inline OpArg ImmPtr(const void* imm) {return Imm32((u32)imm);} 283 return Imm32(reinterpret_cast<u32>(imm));
290#endif 284#endif
285}
291 286
292inline u32 PtrOffset(const void* ptr, const void* base) 287inline u32 PtrOffset(const void* ptr, const void* base)
293{ 288{
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index d21f198e5..35b61dada 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -252,6 +252,7 @@ set(HEADERS
252 tracer/citrace.h 252 tracer/citrace.h
253 memory.h 253 memory.h
254 memory_setup.h 254 memory_setup.h
255 mmio.h
255 settings.h 256 settings.h
256 system.h 257 system.h
257 ) 258 )
diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h
index 5cffe513c..533067d4f 100644
--- a/src/core/arm/arm_interface.h
+++ b/src/core/arm/arm_interface.h
@@ -14,10 +14,6 @@ namespace Core {
14/// Generic ARM11 CPU interface 14/// Generic ARM11 CPU interface
15class ARM_Interface : NonCopyable { 15class ARM_Interface : NonCopyable {
16public: 16public:
17 ARM_Interface() {
18 num_instructions = 0;
19 }
20
21 virtual ~ARM_Interface() { 17 virtual ~ARM_Interface() {
22 } 18 }
23 19
@@ -146,11 +142,11 @@ public:
146 virtual void PrepareReschedule() = 0; 142 virtual void PrepareReschedule() = 0;
147 143
148 /// Getter for num_instructions 144 /// Getter for num_instructions
149 u64 GetNumInstructions() { 145 u64 GetNumInstructions() const {
150 return num_instructions; 146 return num_instructions;
151 } 147 }
152 148
153 s64 down_count; ///< A decreasing counter of remaining cycles before the next event, decreased by the cpu run loop 149 s64 down_count = 0; ///< A decreasing counter of remaining cycles before the next event, decreased by the cpu run loop
154 150
155protected: 151protected:
156 152
@@ -162,6 +158,5 @@ protected:
162 158
163private: 159private:
164 160
165 u64 num_instructions; ///< Number of instructions executed 161 u64 num_instructions = 0; ///< Number of instructions executed
166
167}; 162};
diff --git a/src/core/arm/disassembler/arm_disasm.cpp b/src/core/arm/disassembler/arm_disasm.cpp
index 76408e9fa..5ad1f1c29 100644
--- a/src/core/arm/disassembler/arm_disasm.cpp
+++ b/src/core/arm/disassembler/arm_disasm.cpp
@@ -738,23 +738,23 @@ std::string ARM_Disasm::DisassembleMemHalf(u32 insn)
738 if (is_immed) { 738 if (is_immed) {
739 if (is_pre) { 739 if (is_pre) {
740 if (offset == 0) { 740 if (offset == 0) {
741 return Common::StringFromFormat("%s%sh\tr%d, [r%d]", opname, cond_to_str(cond), rd, rn); 741 return Common::StringFromFormat("%s%s%s\tr%d, [r%d]", opname, cond_to_str(cond), width, rd, rn);
742 } else { 742 } else {
743 return Common::StringFromFormat("%s%sh\tr%d, [r%d, #%s%u]%s", 743 return Common::StringFromFormat("%s%s%s\tr%d, [r%d, #%s%u]%s",
744 opname, cond_to_str(cond), rd, rn, minus, offset, bang); 744 opname, cond_to_str(cond), width, rd, rn, minus, offset, bang);
745 } 745 }
746 } else { 746 } else {
747 return Common::StringFromFormat("%s%sh\tr%d, [r%d], #%s%u", 747 return Common::StringFromFormat("%s%s%s\tr%d, [r%d], #%s%u",
748 opname, cond_to_str(cond), rd, rn, minus, offset); 748 opname, cond_to_str(cond), width, rd, rn, minus, offset);
749 } 749 }
750 } 750 }
751 751
752 if (is_pre) { 752 if (is_pre) {
753 return Common::StringFromFormat("%s%sh\tr%d, [r%d, %sr%d]%s", 753 return Common::StringFromFormat("%s%s%s\tr%d, [r%d, %sr%d]%s",
754 opname, cond_to_str(cond), rd, rn, minus, rm, bang); 754 opname, cond_to_str(cond), width, rd, rn, minus, rm, bang);
755 } else { 755 } else {
756 return Common::StringFromFormat("%s%sh\tr%d, [r%d], %sr%d", 756 return Common::StringFromFormat("%s%s%s\tr%d, [r%d], %sr%d",
757 opname, cond_to_str(cond), rd, rn, minus, rm); 757 opname, cond_to_str(cond), width, rd, rn, minus, rm);
758 } 758 }
759} 759}
760 760
diff --git a/src/core/arm/dyncom/arm_dyncom_dec.cpp b/src/core/arm/dyncom/arm_dyncom_dec.cpp
index ee4288314..8cd6755cb 100644
--- a/src/core/arm/dyncom/arm_dyncom_dec.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_dec.cpp
@@ -6,10 +6,9 @@
6#include "core/arm/skyeye_common/armsupp.h" 6#include "core/arm/skyeye_common/armsupp.h"
7 7
8const InstructionSetEncodingItem arm_instruction[] = { 8const InstructionSetEncodingItem arm_instruction[] = {
9 { "vmla", 4, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x0, 9, 11, 0x5, 4, 4, 0 }}, 9 { "vmla", 5, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x0, 9, 11, 0x5, 6, 6, 0, 4, 4, 0 }},
10 { "vmls", 7, ARMVFP2, { 28, 31, 0xF, 25, 27, 0x1, 23, 23, 1, 11, 11, 0, 8, 9, 0x2, 6, 6, 1, 4, 4, 0 }}, 10 { "vmls", 5, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x0, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 }},
11 { "vnmla", 4, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x1, 9, 11, 0x5, 4, 4, 0 }}, 11 { "vnmla", 5, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x1, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 }},
12 { "vnmla", 5, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 }},
13 { "vnmls", 5, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x1, 9, 11, 0x5, 6, 6, 0, 4, 4, 0 }}, 12 { "vnmls", 5, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x1, 9, 11, 0x5, 6, 6, 0, 4, 4, 0 }},
14 { "vnmul", 5, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 }}, 13 { "vnmul", 5, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 }},
15 { "vmul", 5, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 0, 4, 4, 0 }}, 14 { "vmul", 5, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 0, 4, 4, 0 }},
@@ -211,7 +210,6 @@ const InstructionSetEncodingItem arm_exclusion_code[] = {
211 { "vmla", 0, ARMVFP2, { 0 }}, 210 { "vmla", 0, ARMVFP2, { 0 }},
212 { "vmls", 0, ARMVFP2, { 0 }}, 211 { "vmls", 0, ARMVFP2, { 0 }},
213 { "vnmla", 0, ARMVFP2, { 0 }}, 212 { "vnmla", 0, ARMVFP2, { 0 }},
214 { "vnmla", 0, ARMVFP2, { 0 }},
215 { "vnmls", 0, ARMVFP2, { 0 }}, 213 { "vnmls", 0, ARMVFP2, { 0 }},
216 { "vnmul", 0, ARMVFP2, { 0 }}, 214 { "vnmul", 0, ARMVFP2, { 0 }},
217 { "vmul", 0, ARMVFP2, { 0 }}, 215 { "vmul", 0, ARMVFP2, { 0 }},
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index 96c88c83a..5f8826034 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -51,7 +51,7 @@ enum {
51 51
52typedef unsigned int (*shtop_fp_t)(ARMul_State* cpu, unsigned int sht_oper); 52typedef unsigned int (*shtop_fp_t)(ARMul_State* cpu, unsigned int sht_oper);
53 53
54static bool CondPassed(ARMul_State* cpu, unsigned int cond) { 54static bool CondPassed(const ARMul_State* cpu, unsigned int cond) {
55 const bool n_flag = cpu->NFlag != 0; 55 const bool n_flag = cpu->NFlag != 0;
56 const bool z_flag = cpu->ZFlag != 0; 56 const bool z_flag = cpu->ZFlag != 0;
57 const bool c_flag = cpu->CFlag != 0; 57 const bool c_flag = cpu->CFlag != 0;
@@ -1623,9 +1623,6 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrb)(unsigned int inst, int index)
1623 inst_cream->inst = inst; 1623 inst_cream->inst = inst;
1624 inst_cream->get_addr = get_calc_addr_op(inst); 1624 inst_cream->get_addr = get_calc_addr_op(inst);
1625 1625
1626 if (BITS(inst, 12, 15) == 15) {
1627 inst_base->br = INDIRECT_BRANCH;
1628 }
1629 return inst_base; 1626 return inst_base;
1630} 1627}
1631static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrbt)(unsigned int inst, int index) 1628static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrbt)(unsigned int inst, int index)
@@ -1646,9 +1643,6 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrbt)(unsigned int inst, int index)
1646 DEBUG_MSG; 1643 DEBUG_MSG;
1647 } 1644 }
1648 1645
1649 if (BITS(inst, 12, 15) == 15) {
1650 inst_base->br = INDIRECT_BRANCH;
1651 }
1652 return inst_base; 1646 return inst_base;
1653} 1647}
1654static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrd)(unsigned int inst, int index) 1648static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrd)(unsigned int inst, int index)
@@ -1703,9 +1697,6 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrh)(unsigned int inst, int index)
1703 inst_cream->inst = inst; 1697 inst_cream->inst = inst;
1704 inst_cream->get_addr = get_calc_addr_op(inst); 1698 inst_cream->get_addr = get_calc_addr_op(inst);
1705 1699
1706 if (BITS(inst, 12, 15) == 15) {
1707 inst_base->br = INDIRECT_BRANCH;
1708 }
1709 return inst_base; 1700 return inst_base;
1710} 1701}
1711static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsb)(unsigned int inst, int index) 1702static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsb)(unsigned int inst, int index)
@@ -1720,9 +1711,6 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsb)(unsigned int inst, int index)
1720 inst_cream->inst = inst; 1711 inst_cream->inst = inst;
1721 inst_cream->get_addr = get_calc_addr_op(inst); 1712 inst_cream->get_addr = get_calc_addr_op(inst);
1722 1713
1723 if (BITS(inst, 12, 15) == 15) {
1724 inst_base->br = INDIRECT_BRANCH;
1725 }
1726 return inst_base; 1714 return inst_base;
1727} 1715}
1728static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsh)(unsigned int inst, int index) 1716static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsh)(unsigned int inst, int index)
@@ -1737,9 +1725,6 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsh)(unsigned int inst, int index)
1737 inst_cream->inst = inst; 1725 inst_cream->inst = inst;
1738 inst_cream->get_addr = get_calc_addr_op(inst); 1726 inst_cream->get_addr = get_calc_addr_op(inst);
1739 1727
1740 if (BITS(inst, 12, 15) == 15) {
1741 inst_base->br = INDIRECT_BRANCH;
1742 }
1743 return inst_base; 1728 return inst_base;
1744} 1729}
1745static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrt)(unsigned int inst, int index) 1730static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrt)(unsigned int inst, int index)
@@ -2597,9 +2582,6 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(str)(unsigned int inst, int index)
2597 inst_cream->inst = inst; 2582 inst_cream->inst = inst;
2598 inst_cream->get_addr = get_calc_addr_op(inst); 2583 inst_cream->get_addr = get_calc_addr_op(inst);
2599 2584
2600 if (BITS(inst, 12, 15) == 15) {
2601 inst_base->br = INDIRECT_BRANCH;
2602 }
2603 return inst_base; 2585 return inst_base;
2604} 2586}
2605static ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb)(unsigned int inst, int index) 2587static ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb)(unsigned int inst, int index)
@@ -2645,9 +2627,6 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(strb)(unsigned int inst, int index)
2645 inst_cream->inst = inst; 2627 inst_cream->inst = inst;
2646 inst_cream->get_addr = get_calc_addr_op(inst); 2628 inst_cream->get_addr = get_calc_addr_op(inst);
2647 2629
2648 if (BITS(inst, 12, 15) == 15) {
2649 inst_base->br = INDIRECT_BRANCH;
2650 }
2651 return inst_base; 2630 return inst_base;
2652} 2631}
2653static ARM_INST_PTR INTERPRETER_TRANSLATE(strbt)(unsigned int inst, int index) 2632static ARM_INST_PTR INTERPRETER_TRANSLATE(strbt)(unsigned int inst, int index)
@@ -2669,9 +2648,6 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(strbt)(unsigned int inst, int index)
2669 DEBUG_MSG; 2648 DEBUG_MSG;
2670 } 2649 }
2671 2650
2672 if (BITS(inst, 12, 15) == 15) {
2673 inst_base->br = INDIRECT_BRANCH;
2674 }
2675 return inst_base; 2651 return inst_base;
2676} 2652}
2677static ARM_INST_PTR INTERPRETER_TRANSLATE(strd)(unsigned int inst, int index){ 2653static ARM_INST_PTR INTERPRETER_TRANSLATE(strd)(unsigned int inst, int index){
@@ -2685,9 +2661,6 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(strd)(unsigned int inst, int index){
2685 inst_cream->inst = inst; 2661 inst_cream->inst = inst;
2686 inst_cream->get_addr = get_calc_addr_op(inst); 2662 inst_cream->get_addr = get_calc_addr_op(inst);
2687 2663
2688 if (BITS(inst, 12, 15) == 15) {
2689 inst_base->br = INDIRECT_BRANCH;
2690 }
2691 return inst_base; 2664 return inst_base;
2692} 2665}
2693static ARM_INST_PTR INTERPRETER_TRANSLATE(strex)(unsigned int inst, int index) 2666static ARM_INST_PTR INTERPRETER_TRANSLATE(strex)(unsigned int inst, int index)
@@ -2729,9 +2702,6 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(strh)(unsigned int inst, int index)
2729 inst_cream->inst = inst; 2702 inst_cream->inst = inst;
2730 inst_cream->get_addr = get_calc_addr_op(inst); 2703 inst_cream->get_addr = get_calc_addr_op(inst);
2731 2704
2732 if (BITS(inst, 12, 15) == 15) {
2733 inst_base->br = INDIRECT_BRANCH;
2734 }
2735 return inst_base; 2705 return inst_base;
2736} 2706}
2737static ARM_INST_PTR INTERPRETER_TRANSLATE(strt)(unsigned int inst, int index) 2707static ARM_INST_PTR INTERPRETER_TRANSLATE(strt)(unsigned int inst, int index)
@@ -2757,9 +2727,6 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(strt)(unsigned int inst, int index)
2757 DEBUG_MSG; 2727 DEBUG_MSG;
2758 } 2728 }
2759 2729
2760 if (BITS(inst, 12, 15) == 15) {
2761 inst_base->br = INDIRECT_BRANCH;
2762 }
2763 return inst_base; 2730 return inst_base;
2764} 2731}
2765static ARM_INST_PTR INTERPRETER_TRANSLATE(sub)(unsigned int inst, int index) 2732static ARM_INST_PTR INTERPRETER_TRANSLATE(sub)(unsigned int inst, int index)
@@ -2808,9 +2775,6 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(swp)(unsigned int inst, int index)
2808 inst_cream->Rd = BITS(inst, 12, 15); 2775 inst_cream->Rd = BITS(inst, 12, 15);
2809 inst_cream->Rm = BITS(inst, 0, 3); 2776 inst_cream->Rm = BITS(inst, 0, 3);
2810 2777
2811 if (inst_cream->Rd == 15) {
2812 inst_base->br = INDIRECT_BRANCH;
2813 }
2814 return inst_base; 2778 return inst_base;
2815} 2779}
2816static ARM_INST_PTR INTERPRETER_TRANSLATE(swpb)(unsigned int inst, int index){ 2780static ARM_INST_PTR INTERPRETER_TRANSLATE(swpb)(unsigned int inst, int index){
@@ -2825,9 +2789,6 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(swpb)(unsigned int inst, int index){
2825 inst_cream->Rd = BITS(inst, 12, 15); 2789 inst_cream->Rd = BITS(inst, 12, 15);
2826 inst_cream->Rm = BITS(inst, 0, 3); 2790 inst_cream->Rm = BITS(inst, 0, 3);
2827 2791
2828 if (inst_cream->Rd == 15) {
2829 inst_base->br = INDIRECT_BRANCH;
2830 }
2831 return inst_base; 2792 return inst_base;
2832} 2793}
2833static ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab)(unsigned int inst, int index){ 2794static ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab)(unsigned int inst, int index){
@@ -2915,9 +2876,6 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(tst)(unsigned int inst, int index)
2915 inst_cream->shifter_operand = BITS(inst, 0, 11); 2876 inst_cream->shifter_operand = BITS(inst, 0, 11);
2916 inst_cream->shtop_func = get_shtop(inst); 2877 inst_cream->shtop_func = get_shtop(inst);
2917 2878
2918 if (inst_cream->Rd == 15)
2919 inst_base->br = INDIRECT_BRANCH;
2920
2921 return inst_base; 2879 return inst_base;
2922} 2880}
2923 2881
@@ -3244,7 +3202,6 @@ const transop_fp_t arm_instruction_trans[] = {
3244 INTERPRETER_TRANSLATE(vmla), 3202 INTERPRETER_TRANSLATE(vmla),
3245 INTERPRETER_TRANSLATE(vmls), 3203 INTERPRETER_TRANSLATE(vmls),
3246 INTERPRETER_TRANSLATE(vnmla), 3204 INTERPRETER_TRANSLATE(vnmla),
3247 INTERPRETER_TRANSLATE(vnmla),
3248 INTERPRETER_TRANSLATE(vnmls), 3205 INTERPRETER_TRANSLATE(vnmls),
3249 INTERPRETER_TRANSLATE(vnmul), 3206 INTERPRETER_TRANSLATE(vnmul),
3250 INTERPRETER_TRANSLATE(vmul), 3207 INTERPRETER_TRANSLATE(vmul),
@@ -3636,209 +3593,208 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
3636 case 0: goto VMLA_INST; \ 3593 case 0: goto VMLA_INST; \
3637 case 1: goto VMLS_INST; \ 3594 case 1: goto VMLS_INST; \
3638 case 2: goto VNMLA_INST; \ 3595 case 2: goto VNMLA_INST; \
3639 case 3: goto VNMLA_INST; \ 3596 case 3: goto VNMLS_INST; \
3640 case 4: goto VNMLS_INST; \ 3597 case 4: goto VNMUL_INST; \
3641 case 5: goto VNMUL_INST; \ 3598 case 5: goto VMUL_INST; \
3642 case 6: goto VMUL_INST; \ 3599 case 6: goto VADD_INST; \
3643 case 7: goto VADD_INST; \ 3600 case 7: goto VSUB_INST; \
3644 case 8: goto VSUB_INST; \ 3601 case 8: goto VDIV_INST; \
3645 case 9: goto VDIV_INST; \ 3602 case 9: goto VMOVI_INST; \
3646 case 10: goto VMOVI_INST; \ 3603 case 10: goto VMOVR_INST; \
3647 case 11: goto VMOVR_INST; \ 3604 case 11: goto VABS_INST; \
3648 case 12: goto VABS_INST; \ 3605 case 12: goto VNEG_INST; \
3649 case 13: goto VNEG_INST; \ 3606 case 13: goto VSQRT_INST; \
3650 case 14: goto VSQRT_INST; \ 3607 case 14: goto VCMP_INST; \
3651 case 15: goto VCMP_INST; \ 3608 case 15: goto VCMP2_INST; \
3652 case 16: goto VCMP2_INST; \ 3609 case 16: goto VCVTBDS_INST; \
3653 case 17: goto VCVTBDS_INST; \ 3610 case 17: goto VCVTBFF_INST; \
3654 case 18: goto VCVTBFF_INST; \ 3611 case 18: goto VCVTBFI_INST; \
3655 case 19: goto VCVTBFI_INST; \ 3612 case 19: goto VMOVBRS_INST; \
3656 case 20: goto VMOVBRS_INST; \ 3613 case 20: goto VMSR_INST; \
3657 case 21: goto VMSR_INST; \ 3614 case 21: goto VMOVBRC_INST; \
3658 case 22: goto VMOVBRC_INST; \ 3615 case 22: goto VMRS_INST; \
3659 case 23: goto VMRS_INST; \ 3616 case 23: goto VMOVBCR_INST; \
3660 case 24: goto VMOVBCR_INST; \ 3617 case 24: goto VMOVBRRSS_INST; \
3661 case 25: goto VMOVBRRSS_INST; \ 3618 case 25: goto VMOVBRRD_INST; \
3662 case 26: goto VMOVBRRD_INST; \ 3619 case 26: goto VSTR_INST; \
3663 case 27: goto VSTR_INST; \ 3620 case 27: goto VPUSH_INST; \
3664 case 28: goto VPUSH_INST; \ 3621 case 28: goto VSTM_INST; \
3665 case 29: goto VSTM_INST; \ 3622 case 29: goto VPOP_INST; \
3666 case 30: goto VPOP_INST; \ 3623 case 30: goto VLDR_INST; \
3667 case 31: goto VLDR_INST; \ 3624 case 31: goto VLDM_INST ; \
3668 case 32: goto VLDM_INST ; \ 3625 case 32: goto SRS_INST; \
3669 case 33: goto SRS_INST; \ 3626 case 33: goto RFE_INST; \
3670 case 34: goto RFE_INST; \ 3627 case 34: goto BKPT_INST; \
3671 case 35: goto BKPT_INST; \ 3628 case 35: goto BLX_INST; \
3672 case 36: goto BLX_INST; \ 3629 case 36: goto CPS_INST; \
3673 case 37: goto CPS_INST; \ 3630 case 37: goto PLD_INST; \
3674 case 38: goto PLD_INST; \ 3631 case 38: goto SETEND_INST; \
3675 case 39: goto SETEND_INST; \ 3632 case 39: goto CLREX_INST; \
3676 case 40: goto CLREX_INST; \ 3633 case 40: goto REV16_INST; \
3677 case 41: goto REV16_INST; \ 3634 case 41: goto USAD8_INST; \
3678 case 42: goto USAD8_INST; \ 3635 case 42: goto SXTB_INST; \
3679 case 43: goto SXTB_INST; \ 3636 case 43: goto UXTB_INST; \
3680 case 44: goto UXTB_INST; \ 3637 case 44: goto SXTH_INST; \
3681 case 45: goto SXTH_INST; \ 3638 case 45: goto SXTB16_INST; \
3682 case 46: goto SXTB16_INST; \ 3639 case 46: goto UXTH_INST; \
3683 case 47: goto UXTH_INST; \ 3640 case 47: goto UXTB16_INST; \
3684 case 48: goto UXTB16_INST; \ 3641 case 48: goto CPY_INST; \
3685 case 49: goto CPY_INST; \ 3642 case 49: goto UXTAB_INST; \
3686 case 50: goto UXTAB_INST; \ 3643 case 50: goto SSUB8_INST; \
3687 case 51: goto SSUB8_INST; \ 3644 case 51: goto SHSUB8_INST; \
3688 case 52: goto SHSUB8_INST; \ 3645 case 52: goto SSUBADDX_INST; \
3689 case 53: goto SSUBADDX_INST; \ 3646 case 53: goto STREX_INST; \
3690 case 54: goto STREX_INST; \ 3647 case 54: goto STREXB_INST; \
3691 case 55: goto STREXB_INST; \ 3648 case 55: goto SWP_INST; \
3692 case 56: goto SWP_INST; \ 3649 case 56: goto SWPB_INST; \
3693 case 57: goto SWPB_INST; \ 3650 case 57: goto SSUB16_INST; \
3694 case 58: goto SSUB16_INST; \ 3651 case 58: goto SSAT16_INST; \
3695 case 59: goto SSAT16_INST; \ 3652 case 59: goto SHSUBADDX_INST; \
3696 case 60: goto SHSUBADDX_INST; \ 3653 case 60: goto QSUBADDX_INST; \
3697 case 61: goto QSUBADDX_INST; \ 3654 case 61: goto SHADDSUBX_INST; \
3698 case 62: goto SHADDSUBX_INST; \ 3655 case 62: goto SHADD8_INST; \
3699 case 63: goto SHADD8_INST; \ 3656 case 63: goto SHADD16_INST; \
3700 case 64: goto SHADD16_INST; \ 3657 case 64: goto SEL_INST; \
3701 case 65: goto SEL_INST; \ 3658 case 65: goto SADDSUBX_INST; \
3702 case 66: goto SADDSUBX_INST; \ 3659 case 66: goto SADD8_INST; \
3703 case 67: goto SADD8_INST; \ 3660 case 67: goto SADD16_INST; \
3704 case 68: goto SADD16_INST; \ 3661 case 68: goto SHSUB16_INST; \
3705 case 69: goto SHSUB16_INST; \ 3662 case 69: goto UMAAL_INST; \
3706 case 70: goto UMAAL_INST; \ 3663 case 70: goto UXTAB16_INST; \
3707 case 71: goto UXTAB16_INST; \ 3664 case 71: goto USUBADDX_INST; \
3708 case 72: goto USUBADDX_INST; \ 3665 case 72: goto USUB8_INST; \
3709 case 73: goto USUB8_INST; \ 3666 case 73: goto USUB16_INST; \
3710 case 74: goto USUB16_INST; \ 3667 case 74: goto USAT16_INST; \
3711 case 75: goto USAT16_INST; \ 3668 case 75: goto USADA8_INST; \
3712 case 76: goto USADA8_INST; \ 3669 case 76: goto UQSUBADDX_INST; \
3713 case 77: goto UQSUBADDX_INST; \ 3670 case 77: goto UQSUB8_INST; \
3714 case 78: goto UQSUB8_INST; \ 3671 case 78: goto UQSUB16_INST; \
3715 case 79: goto UQSUB16_INST; \ 3672 case 79: goto UQADDSUBX_INST; \
3716 case 80: goto UQADDSUBX_INST; \ 3673 case 80: goto UQADD8_INST; \
3717 case 81: goto UQADD8_INST; \ 3674 case 81: goto UQADD16_INST; \
3718 case 82: goto UQADD16_INST; \ 3675 case 82: goto SXTAB_INST; \
3719 case 83: goto SXTAB_INST; \ 3676 case 83: goto UHSUBADDX_INST; \
3720 case 84: goto UHSUBADDX_INST; \ 3677 case 84: goto UHSUB8_INST; \
3721 case 85: goto UHSUB8_INST; \ 3678 case 85: goto UHSUB16_INST; \
3722 case 86: goto UHSUB16_INST; \ 3679 case 86: goto UHADDSUBX_INST; \
3723 case 87: goto UHADDSUBX_INST; \ 3680 case 87: goto UHADD8_INST; \
3724 case 88: goto UHADD8_INST; \ 3681 case 88: goto UHADD16_INST; \
3725 case 89: goto UHADD16_INST; \ 3682 case 89: goto UADDSUBX_INST; \
3726 case 90: goto UADDSUBX_INST; \ 3683 case 90: goto UADD8_INST; \
3727 case 91: goto UADD8_INST; \ 3684 case 91: goto UADD16_INST; \
3728 case 92: goto UADD16_INST; \ 3685 case 92: goto SXTAH_INST; \
3729 case 93: goto SXTAH_INST; \ 3686 case 93: goto SXTAB16_INST; \
3730 case 94: goto SXTAB16_INST; \ 3687 case 94: goto QADD8_INST; \
3731 case 95: goto QADD8_INST; \ 3688 case 95: goto BXJ_INST; \
3732 case 96: goto BXJ_INST; \ 3689 case 96: goto CLZ_INST; \
3733 case 97: goto CLZ_INST; \ 3690 case 97: goto UXTAH_INST; \
3734 case 98: goto UXTAH_INST; \ 3691 case 98: goto BX_INST; \
3735 case 99: goto BX_INST; \ 3692 case 99: goto REV_INST; \
3736 case 100: goto REV_INST; \ 3693 case 100: goto BLX_INST; \
3737 case 101: goto BLX_INST; \ 3694 case 101: goto REVSH_INST; \
3738 case 102: goto REVSH_INST; \ 3695 case 102: goto QADD_INST; \
3739 case 103: goto QADD_INST; \ 3696 case 103: goto QADD16_INST; \
3740 case 104: goto QADD16_INST; \ 3697 case 104: goto QADDSUBX_INST; \
3741 case 105: goto QADDSUBX_INST; \ 3698 case 105: goto LDREX_INST; \
3742 case 106: goto LDREX_INST; \ 3699 case 106: goto QDADD_INST; \
3743 case 107: goto QDADD_INST; \ 3700 case 107: goto QDSUB_INST; \
3744 case 108: goto QDSUB_INST; \ 3701 case 108: goto QSUB_INST; \
3745 case 109: goto QSUB_INST; \ 3702 case 109: goto LDREXB_INST; \
3746 case 110: goto LDREXB_INST; \ 3703 case 110: goto QSUB8_INST; \
3747 case 111: goto QSUB8_INST; \ 3704 case 111: goto QSUB16_INST; \
3748 case 112: goto QSUB16_INST; \ 3705 case 112: goto SMUAD_INST; \
3749 case 113: goto SMUAD_INST; \ 3706 case 113: goto SMMUL_INST; \
3750 case 114: goto SMMUL_INST; \ 3707 case 114: goto SMUSD_INST; \
3751 case 115: goto SMUSD_INST; \ 3708 case 115: goto SMLSD_INST; \
3752 case 116: goto SMLSD_INST; \ 3709 case 116: goto SMLSLD_INST; \
3753 case 117: goto SMLSLD_INST; \ 3710 case 117: goto SMMLA_INST; \
3754 case 118: goto SMMLA_INST; \ 3711 case 118: goto SMMLS_INST; \
3755 case 119: goto SMMLS_INST; \ 3712 case 119: goto SMLALD_INST; \
3756 case 120: goto SMLALD_INST; \ 3713 case 120: goto SMLAD_INST; \
3757 case 121: goto SMLAD_INST; \ 3714 case 121: goto SMLAW_INST; \
3758 case 122: goto SMLAW_INST; \ 3715 case 122: goto SMULW_INST; \
3759 case 123: goto SMULW_INST; \ 3716 case 123: goto PKHTB_INST; \
3760 case 124: goto PKHTB_INST; \ 3717 case 124: goto PKHBT_INST; \
3761 case 125: goto PKHBT_INST; \ 3718 case 125: goto SMUL_INST; \
3762 case 126: goto SMUL_INST; \ 3719 case 126: goto SMLALXY_INST; \
3763 case 127: goto SMLALXY_INST; \ 3720 case 127: goto SMLA_INST; \
3764 case 128: goto SMLA_INST; \ 3721 case 128: goto MCRR_INST; \
3765 case 129: goto MCRR_INST; \ 3722 case 129: goto MRRC_INST; \
3766 case 130: goto MRRC_INST; \ 3723 case 130: goto CMP_INST; \
3767 case 131: goto CMP_INST; \ 3724 case 131: goto TST_INST; \
3768 case 132: goto TST_INST; \ 3725 case 132: goto TEQ_INST; \
3769 case 133: goto TEQ_INST; \ 3726 case 133: goto CMN_INST; \
3770 case 134: goto CMN_INST; \ 3727 case 134: goto SMULL_INST; \
3771 case 135: goto SMULL_INST; \ 3728 case 135: goto UMULL_INST; \
3772 case 136: goto UMULL_INST; \ 3729 case 136: goto UMLAL_INST; \
3773 case 137: goto UMLAL_INST; \ 3730 case 137: goto SMLAL_INST; \
3774 case 138: goto SMLAL_INST; \ 3731 case 138: goto MUL_INST; \
3775 case 139: goto MUL_INST; \ 3732 case 139: goto MLA_INST; \
3776 case 140: goto MLA_INST; \ 3733 case 140: goto SSAT_INST; \
3777 case 141: goto SSAT_INST; \ 3734 case 141: goto USAT_INST; \
3778 case 142: goto USAT_INST; \ 3735 case 142: goto MRS_INST; \
3779 case 143: goto MRS_INST; \ 3736 case 143: goto MSR_INST; \
3780 case 144: goto MSR_INST; \ 3737 case 144: goto AND_INST; \
3781 case 145: goto AND_INST; \ 3738 case 145: goto BIC_INST; \
3782 case 146: goto BIC_INST; \ 3739 case 146: goto LDM_INST; \
3783 case 147: goto LDM_INST; \ 3740 case 147: goto EOR_INST; \
3784 case 148: goto EOR_INST; \ 3741 case 148: goto ADD_INST; \
3785 case 149: goto ADD_INST; \ 3742 case 149: goto RSB_INST; \
3786 case 150: goto RSB_INST; \ 3743 case 150: goto RSC_INST; \
3787 case 151: goto RSC_INST; \ 3744 case 151: goto SBC_INST; \
3788 case 152: goto SBC_INST; \ 3745 case 152: goto ADC_INST; \
3789 case 153: goto ADC_INST; \ 3746 case 153: goto SUB_INST; \
3790 case 154: goto SUB_INST; \ 3747 case 154: goto ORR_INST; \
3791 case 155: goto ORR_INST; \ 3748 case 155: goto MVN_INST; \
3792 case 156: goto MVN_INST; \ 3749 case 156: goto MOV_INST; \
3793 case 157: goto MOV_INST; \ 3750 case 157: goto STM_INST; \
3794 case 158: goto STM_INST; \ 3751 case 158: goto LDM_INST; \
3795 case 159: goto LDM_INST; \ 3752 case 159: goto LDRSH_INST; \
3796 case 160: goto LDRSH_INST; \ 3753 case 160: goto STM_INST; \
3797 case 161: goto STM_INST; \ 3754 case 161: goto LDM_INST; \
3798 case 162: goto LDM_INST; \ 3755 case 162: goto LDRSB_INST; \
3799 case 163: goto LDRSB_INST; \ 3756 case 163: goto STRD_INST; \
3800 case 164: goto STRD_INST; \ 3757 case 164: goto LDRH_INST; \
3801 case 165: goto LDRH_INST; \ 3758 case 165: goto STRH_INST; \
3802 case 166: goto STRH_INST; \ 3759 case 166: goto LDRD_INST; \
3803 case 167: goto LDRD_INST; \ 3760 case 167: goto STRT_INST; \
3804 case 168: goto STRT_INST; \ 3761 case 168: goto STRBT_INST; \
3805 case 169: goto STRBT_INST; \ 3762 case 169: goto LDRBT_INST; \
3806 case 170: goto LDRBT_INST; \ 3763 case 170: goto LDRT_INST; \
3807 case 171: goto LDRT_INST; \ 3764 case 171: goto MRC_INST; \
3808 case 172: goto MRC_INST; \ 3765 case 172: goto MCR_INST; \
3809 case 173: goto MCR_INST; \ 3766 case 173: goto MSR_INST; \
3810 case 174: goto MSR_INST; \ 3767 case 174: goto MSR_INST; \
3811 case 175: goto MSR_INST; \ 3768 case 175: goto MSR_INST; \
3812 case 176: goto MSR_INST; \ 3769 case 176: goto MSR_INST; \
3813 case 177: goto MSR_INST; \ 3770 case 177: goto MSR_INST; \
3814 case 178: goto MSR_INST; \ 3771 case 178: goto LDRB_INST; \
3815 case 179: goto LDRB_INST; \ 3772 case 179: goto STRB_INST; \
3816 case 180: goto STRB_INST; \ 3773 case 180: goto LDR_INST; \
3817 case 181: goto LDR_INST; \ 3774 case 181: goto LDRCOND_INST ; \
3818 case 182: goto LDRCOND_INST ; \ 3775 case 182: goto STR_INST; \
3819 case 183: goto STR_INST; \ 3776 case 183: goto CDP_INST; \
3820 case 184: goto CDP_INST; \ 3777 case 184: goto STC_INST; \
3821 case 185: goto STC_INST; \ 3778 case 185: goto LDC_INST; \
3822 case 186: goto LDC_INST; \ 3779 case 186: goto LDREXD_INST; \
3823 case 187: goto LDREXD_INST; \ 3780 case 187: goto STREXD_INST; \
3824 case 188: goto STREXD_INST; \ 3781 case 188: goto LDREXH_INST; \
3825 case 189: goto LDREXH_INST; \ 3782 case 189: goto STREXH_INST; \
3826 case 190: goto STREXH_INST; \ 3783 case 190: goto NOP_INST; \
3827 case 191: goto NOP_INST; \ 3784 case 191: goto YIELD_INST; \
3828 case 192: goto YIELD_INST; \ 3785 case 192: goto WFE_INST; \
3829 case 193: goto WFE_INST; \ 3786 case 193: goto WFI_INST; \
3830 case 194: goto WFI_INST; \ 3787 case 194: goto SEV_INST; \
3831 case 195: goto SEV_INST; \ 3788 case 195: goto SWI_INST; \
3832 case 196: goto SWI_INST; \ 3789 case 196: goto BBL_INST; \
3833 case 197: goto BBL_INST; \ 3790 case 197: goto B_2_THUMB ; \
3834 case 198: goto B_2_THUMB ; \ 3791 case 198: goto B_COND_THUMB ; \
3835 case 199: goto B_COND_THUMB ; \ 3792 case 199: goto BL_1_THUMB ; \
3836 case 200: goto BL_1_THUMB ; \ 3793 case 200: goto BL_2_THUMB ; \
3837 case 201: goto BL_2_THUMB ; \ 3794 case 201: goto BLX_1_THUMB ; \
3838 case 202: goto BLX_1_THUMB ; \ 3795 case 202: goto DISPATCH; \
3839 case 203: goto DISPATCH; \ 3796 case 203: goto INIT_INST_LENGTH; \
3840 case 204: goto INIT_INST_LENGTH; \ 3797 case 204: goto END; \
3841 case 205: goto END; \
3842 } 3798 }
3843#endif 3799#endif
3844 3800
@@ -3865,7 +3821,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
3865 // to a clunky switch statement. 3821 // to a clunky switch statement.
3866#if defined __GNUC__ || defined __clang__ 3822#if defined __GNUC__ || defined __clang__
3867 void *InstLabel[] = { 3823 void *InstLabel[] = {
3868 &&VMLA_INST, &&VMLS_INST, &&VNMLA_INST, &&VNMLA_INST, &&VNMLS_INST, &&VNMUL_INST, &&VMUL_INST, &&VADD_INST, &&VSUB_INST, 3824 &&VMLA_INST, &&VMLS_INST, &&VNMLA_INST, &&VNMLS_INST, &&VNMUL_INST, &&VMUL_INST, &&VADD_INST, &&VSUB_INST,
3869 &&VDIV_INST, &&VMOVI_INST, &&VMOVR_INST, &&VABS_INST, &&VNEG_INST, &&VSQRT_INST, &&VCMP_INST, &&VCMP2_INST, &&VCVTBDS_INST, 3825 &&VDIV_INST, &&VMOVI_INST, &&VMOVR_INST, &&VABS_INST, &&VNEG_INST, &&VSQRT_INST, &&VCMP_INST, &&VCMP2_INST, &&VCVTBDS_INST,
3870 &&VCVTBFF_INST, &&VCVTBFI_INST, &&VMOVBRS_INST, &&VMSR_INST, &&VMOVBRC_INST, &&VMRS_INST, &&VMOVBCR_INST, &&VMOVBRRSS_INST, 3826 &&VCVTBFF_INST, &&VCVTBFI_INST, &&VMOVBRS_INST, &&VMSR_INST, &&VMOVBRC_INST, &&VMRS_INST, &&VMOVBCR_INST, &&VMOVBRRSS_INST,
3871 &&VMOVBRRD_INST, &&VSTR_INST, &&VPUSH_INST, &&VSTM_INST, &&VPOP_INST, &&VLDR_INST, &&VLDM_INST, 3827 &&VMOVBRRD_INST, &&VSTR_INST, &&VPUSH_INST, &&VSTM_INST, &&VPOP_INST, &&VLDR_INST, &&VLDM_INST,
@@ -4477,11 +4433,6 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4477 inst_cream->get_addr(cpu, inst_cream->inst, addr); 4433 inst_cream->get_addr(cpu, inst_cream->inst, addr);
4478 4434
4479 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = cpu->ReadMemory8(addr); 4435 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = cpu->ReadMemory8(addr);
4480
4481 if (BITS(inst_cream->inst, 12, 15) == 15) {
4482 INC_PC(sizeof(ldst_inst));
4483 goto DISPATCH;
4484 }
4485 } 4436 }
4486 cpu->Reg[15] += cpu->GetInstructionSize(); 4437 cpu->Reg[15] += cpu->GetInstructionSize();
4487 INC_PC(sizeof(ldst_inst)); 4438 INC_PC(sizeof(ldst_inst));
@@ -4494,12 +4445,14 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4494 ldst_inst* inst_cream = (ldst_inst*)inst_base->component; 4445 ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
4495 inst_cream->get_addr(cpu, inst_cream->inst, addr); 4446 inst_cream->get_addr(cpu, inst_cream->inst, addr);
4496 4447
4497 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = cpu->ReadMemory8(addr); 4448 const u32 dest_index = BITS(inst_cream->inst, 12, 15);
4449 const u32 previous_mode = cpu->Mode;
4498 4450
4499 if (BITS(inst_cream->inst, 12, 15) == 15) { 4451 cpu->ChangePrivilegeMode(USER32MODE);
4500 INC_PC(sizeof(ldst_inst)); 4452 const u8 value = cpu->ReadMemory8(addr);
4501 goto DISPATCH; 4453 cpu->ChangePrivilegeMode(previous_mode);
4502 } 4454
4455 cpu->Reg[dest_index] = value;
4503 } 4456 }
4504 cpu->Reg[15] += cpu->GetInstructionSize(); 4457 cpu->Reg[15] += cpu->GetInstructionSize();
4505 INC_PC(sizeof(ldst_inst)); 4458 INC_PC(sizeof(ldst_inst));
@@ -4535,10 +4488,6 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4535 cpu->SetExclusiveMemoryAddress(read_addr); 4488 cpu->SetExclusiveMemoryAddress(read_addr);
4536 4489
4537 RD = cpu->ReadMemory32(read_addr); 4490 RD = cpu->ReadMemory32(read_addr);
4538 if (inst_cream->Rd == 15) {
4539 INC_PC(sizeof(generic_arm_inst));
4540 goto DISPATCH;
4541 }
4542 } 4491 }
4543 cpu->Reg[15] += cpu->GetInstructionSize(); 4492 cpu->Reg[15] += cpu->GetInstructionSize();
4544 INC_PC(sizeof(generic_arm_inst)); 4493 INC_PC(sizeof(generic_arm_inst));
@@ -4554,10 +4503,6 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4554 cpu->SetExclusiveMemoryAddress(read_addr); 4503 cpu->SetExclusiveMemoryAddress(read_addr);
4555 4504
4556 RD = cpu->ReadMemory8(read_addr); 4505 RD = cpu->ReadMemory8(read_addr);
4557 if (inst_cream->Rd == 15) {
4558 INC_PC(sizeof(generic_arm_inst));
4559 goto DISPATCH;
4560 }
4561 } 4506 }
4562 cpu->Reg[15] += cpu->GetInstructionSize(); 4507 cpu->Reg[15] += cpu->GetInstructionSize();
4563 INC_PC(sizeof(generic_arm_inst)); 4508 INC_PC(sizeof(generic_arm_inst));
@@ -4573,10 +4518,6 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4573 cpu->SetExclusiveMemoryAddress(read_addr); 4518 cpu->SetExclusiveMemoryAddress(read_addr);
4574 4519
4575 RD = cpu->ReadMemory16(read_addr); 4520 RD = cpu->ReadMemory16(read_addr);
4576 if (inst_cream->Rd == 15) {
4577 INC_PC(sizeof(generic_arm_inst));
4578 goto DISPATCH;
4579 }
4580 } 4521 }
4581 cpu->Reg[15] += cpu->GetInstructionSize(); 4522 cpu->Reg[15] += cpu->GetInstructionSize();
4582 INC_PC(sizeof(generic_arm_inst)); 4523 INC_PC(sizeof(generic_arm_inst));
@@ -4593,11 +4534,6 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4593 4534
4594 RD = cpu->ReadMemory32(read_addr); 4535 RD = cpu->ReadMemory32(read_addr);
4595 RD2 = cpu->ReadMemory32(read_addr + 4); 4536 RD2 = cpu->ReadMemory32(read_addr + 4);
4596
4597 if (inst_cream->Rd == 15) {
4598 INC_PC(sizeof(generic_arm_inst));
4599 goto DISPATCH;
4600 }
4601 } 4537 }
4602 cpu->Reg[15] += cpu->GetInstructionSize(); 4538 cpu->Reg[15] += cpu->GetInstructionSize();
4603 INC_PC(sizeof(generic_arm_inst)); 4539 INC_PC(sizeof(generic_arm_inst));
@@ -4611,10 +4547,6 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4611 inst_cream->get_addr(cpu, inst_cream->inst, addr); 4547 inst_cream->get_addr(cpu, inst_cream->inst, addr);
4612 4548
4613 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = cpu->ReadMemory16(addr); 4549 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = cpu->ReadMemory16(addr);
4614 if (BITS(inst_cream->inst, 12, 15) == 15) {
4615 INC_PC(sizeof(ldst_inst));
4616 goto DISPATCH;
4617 }
4618 } 4550 }
4619 cpu->Reg[15] += cpu->GetInstructionSize(); 4551 cpu->Reg[15] += cpu->GetInstructionSize();
4620 INC_PC(sizeof(ldst_inst)); 4552 INC_PC(sizeof(ldst_inst));
@@ -4631,10 +4563,6 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4631 value |= 0xffffff00; 4563 value |= 0xffffff00;
4632 } 4564 }
4633 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; 4565 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4634 if (BITS(inst_cream->inst, 12, 15) == 15) {
4635 INC_PC(sizeof(ldst_inst));
4636 goto DISPATCH;
4637 }
4638 } 4566 }
4639 cpu->Reg[15] += cpu->GetInstructionSize(); 4567 cpu->Reg[15] += cpu->GetInstructionSize();
4640 INC_PC(sizeof(ldst_inst)); 4568 INC_PC(sizeof(ldst_inst));
@@ -4652,10 +4580,6 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4652 value |= 0xffff0000; 4580 value |= 0xffff0000;
4653 } 4581 }
4654 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; 4582 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4655 if (BITS(inst_cream->inst, 12, 15) == 15) {
4656 INC_PC(sizeof(ldst_inst));
4657 goto DISPATCH;
4658 }
4659 } 4583 }
4660 cpu->Reg[15] += cpu->GetInstructionSize(); 4584 cpu->Reg[15] += cpu->GetInstructionSize();
4661 INC_PC(sizeof(ldst_inst)); 4585 INC_PC(sizeof(ldst_inst));
@@ -4668,13 +4592,14 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4668 ldst_inst* inst_cream = (ldst_inst*)inst_base->component; 4592 ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
4669 inst_cream->get_addr(cpu, inst_cream->inst, addr); 4593 inst_cream->get_addr(cpu, inst_cream->inst, addr);
4670 4594
4671 unsigned int value = cpu->ReadMemory32(addr); 4595 const u32 dest_index = BITS(inst_cream->inst, 12, 15);
4672 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; 4596 const u32 previous_mode = cpu->Mode;
4673 4597
4674 if (BITS(inst_cream->inst, 12, 15) == 15) { 4598 cpu->ChangePrivilegeMode(USER32MODE);
4675 INC_PC(sizeof(ldst_inst)); 4599 const u32 value = cpu->ReadMemory32(addr);
4676 goto DISPATCH; 4600 cpu->ChangePrivilegeMode(previous_mode);
4677 } 4601
4602 cpu->Reg[dest_index] = value;
4678 } 4603 }
4679 cpu->Reg[15] += cpu->GetInstructionSize(); 4604 cpu->Reg[15] += cpu->GetInstructionSize();
4680 INC_PC(sizeof(ldst_inst)); 4605 INC_PC(sizeof(ldst_inst));
@@ -4731,10 +4656,6 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4731 UPDATE_NFLAG(RD); 4656 UPDATE_NFLAG(RD);
4732 UPDATE_ZFLAG(RD); 4657 UPDATE_ZFLAG(RD);
4733 } 4658 }
4734 if (inst_cream->Rd == 15) {
4735 INC_PC(sizeof(mla_inst));
4736 goto DISPATCH;
4737 }
4738 } 4659 }
4739 cpu->Reg[15] += cpu->GetInstructionSize(); 4660 cpu->Reg[15] += cpu->GetInstructionSize();
4740 INC_PC(sizeof(mla_inst)); 4661 INC_PC(sizeof(mla_inst));
@@ -4773,18 +4694,15 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4773 if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { 4694 if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
4774 mrc_inst* inst_cream = (mrc_inst*)inst_base->component; 4695 mrc_inst* inst_cream = (mrc_inst*)inst_base->component;
4775 4696
4776 unsigned int inst = inst_cream->inst; 4697 if (inst_cream->cp_num == 15) {
4777 if (inst_cream->Rd == 15) { 4698 const uint32_t value = cpu->ReadCP15Register(CRn, OPCODE_1, CRm, OPCODE_2);
4778 DEBUG_MSG; 4699
4779 } 4700 if (inst_cream->Rd == 15) {
4780 if (inst_cream->inst == 0xeef04a10) { 4701 cpu->Cpsr = (cpu->Cpsr & ~0xF0000000) | (value & 0xF0000000);
4781 // Undefined instruction fmrx 4702 LOAD_NZCVT;
4782 RD = 0x20000000; 4703 } else {
4783 CITRA_IGNORE_EXIT(-1); 4704 RD = value;
4784 goto END; 4705 }
4785 } else {
4786 if (inst_cream->cp_num == 15)
4787 RD = cpu->ReadCP15Register(CRn, OPCODE_1, CRm, OPCODE_2);
4788 } 4706 }
4789 } 4707 }
4790 cpu->Reg[15] += cpu->GetInstructionSize(); 4708 cpu->Reg[15] += cpu->GetInstructionSize();
@@ -4883,10 +4801,6 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4883 UPDATE_NFLAG(RD); 4801 UPDATE_NFLAG(RD);
4884 UPDATE_ZFLAG(RD); 4802 UPDATE_ZFLAG(RD);
4885 } 4803 }
4886 if (inst_cream->Rd == 15) {
4887 INC_PC(sizeof(mul_inst));
4888 goto DISPATCH;
4889 }
4890 } 4804 }
4891 cpu->Reg[15] += cpu->GetInstructionSize(); 4805 cpu->Reg[15] += cpu->GetInstructionSize();
4892 INC_PC(sizeof(mul_inst)); 4806 INC_PC(sizeof(mul_inst));
@@ -6061,8 +5975,13 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6061 if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { 5975 if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
6062 ldst_inst* inst_cream = (ldst_inst*)inst_base->component; 5976 ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
6063 inst_cream->get_addr(cpu, inst_cream->inst, addr); 5977 inst_cream->get_addr(cpu, inst_cream->inst, addr);
6064 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff; 5978
5979 const u32 previous_mode = cpu->Mode;
5980 const u32 value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff;
5981
5982 cpu->ChangePrivilegeMode(USER32MODE);
6065 cpu->WriteMemory8(addr, value); 5983 cpu->WriteMemory8(addr, value);
5984 cpu->ChangePrivilegeMode(previous_mode);
6066 } 5985 }
6067 cpu->Reg[15] += cpu->GetInstructionSize(); 5986 cpu->Reg[15] += cpu->GetInstructionSize();
6068 INC_PC(sizeof(ldst_inst)); 5987 INC_PC(sizeof(ldst_inst));
@@ -6196,8 +6115,16 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6196 ldst_inst* inst_cream = (ldst_inst*)inst_base->component; 6115 ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
6197 inst_cream->get_addr(cpu, inst_cream->inst, addr); 6116 inst_cream->get_addr(cpu, inst_cream->inst, addr);
6198 6117
6199 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; 6118 const u32 previous_mode = cpu->Mode;
6119 const u32 rt_index = BITS(inst_cream->inst, 12, 15);
6120
6121 u32 value = cpu->Reg[rt_index];
6122 if (rt_index == 15)
6123 value += 2 * cpu->GetInstructionSize();
6124
6125 cpu->ChangePrivilegeMode(USER32MODE);
6200 cpu->WriteMemory32(addr, value); 6126 cpu->WriteMemory32(addr, value);
6127 cpu->ChangePrivilegeMode(previous_mode);
6201 } 6128 }
6202 cpu->Reg[15] += cpu->GetInstructionSize(); 6129 cpu->Reg[15] += cpu->GetInstructionSize();
6203 INC_PC(sizeof(ldst_inst)); 6130 INC_PC(sizeof(ldst_inst));
diff --git a/src/core/arm/dyncom/arm_dyncom_run.h b/src/core/arm/dyncom/arm_dyncom_run.h
index 13bef17fc..8eb694fee 100644
--- a/src/core/arm/dyncom/arm_dyncom_run.h
+++ b/src/core/arm/dyncom/arm_dyncom_run.h
@@ -30,7 +30,7 @@
30 * @return If the PC is being read, then the word-aligned PC value is returned. 30 * @return If the PC is being read, then the word-aligned PC value is returned.
31 * If the PC is not being read, then the value stored in the register is returned. 31 * If the PC is not being read, then the value stored in the register is returned.
32 */ 32 */
33static inline u32 CHECK_READ_REG15_WA(ARMul_State* cpu, int Rn) { 33inline u32 CHECK_READ_REG15_WA(const ARMul_State* cpu, int Rn) {
34 return (Rn == 15) ? ((cpu->Reg[15] & ~0x3) + cpu->GetInstructionSize() * 2) : cpu->Reg[Rn]; 34 return (Rn == 15) ? ((cpu->Reg[15] & ~0x3) + cpu->GetInstructionSize() * 2) : cpu->Reg[Rn];
35} 35}
36 36
@@ -43,6 +43,6 @@ static inline u32 CHECK_READ_REG15_WA(ARMul_State* cpu, int Rn) {
43 * @return If the PC is being read, then the incremented PC value is returned. 43 * @return If the PC is being read, then the incremented PC value is returned.
44 * If the PC is not being read, then the values stored in the register is returned. 44 * If the PC is not being read, then the values stored in the register is returned.
45 */ 45 */
46static inline u32 CHECK_READ_REG15(ARMul_State* cpu, int Rn) { 46inline u32 CHECK_READ_REG15(const ARMul_State* cpu, int Rn) {
47 return (Rn == 15) ? ((cpu->Reg[15] & ~0x1) + cpu->GetInstructionSize() * 2) : cpu->Reg[Rn]; 47 return (Rn == 15) ? ((cpu->Reg[15] & ~0x1) + cpu->GetInstructionSize() * 2) : cpu->Reg[Rn];
48} 48}
diff --git a/src/core/arm/dyncom/arm_dyncom_thumb.h b/src/core/arm/dyncom/arm_dyncom_thumb.h
index 447974363..c1be3c735 100644
--- a/src/core/arm/dyncom/arm_dyncom_thumb.h
+++ b/src/core/arm/dyncom/arm_dyncom_thumb.h
@@ -38,7 +38,7 @@ enum class ThumbDecodeStatus {
38// Translates a Thumb mode instruction into its ARM equivalent. 38// Translates a Thumb mode instruction into its ARM equivalent.
39ThumbDecodeStatus TranslateThumbInstruction(u32 addr, u32 instr, u32* ainstr, u32* inst_size); 39ThumbDecodeStatus TranslateThumbInstruction(u32 addr, u32 instr, u32* ainstr, u32* inst_size);
40 40
41static inline u32 GetThumbInstruction(u32 instr, u32 address) { 41inline u32 GetThumbInstruction(u32 instr, u32 address) {
42 // Normally you would need to handle instruction endianness, 42 // Normally you would need to handle instruction endianness,
43 // however, it is fixed to little-endian on the MPCore, so 43 // however, it is fixed to little-endian on the MPCore, so
44 // there's no need to check for this beforehand. 44 // there's no need to check for this beforehand.
diff --git a/src/core/arm/skyeye_common/vfp/vfp_helper.h b/src/core/arm/skyeye_common/vfp/vfp_helper.h
index 91a8d4d57..210972917 100644
--- a/src/core/arm/skyeye_common/vfp/vfp_helper.h
+++ b/src/core/arm/skyeye_common/vfp/vfp_helper.h
@@ -85,7 +85,7 @@ enum : u32 {
85 85
86#define vfp_single(inst) (((inst) & 0x0000f00) == 0xa00) 86#define vfp_single(inst) (((inst) & 0x0000f00) == 0xa00)
87 87
88static inline u32 vfp_shiftright32jamming(u32 val, unsigned int shift) 88inline u32 vfp_shiftright32jamming(u32 val, unsigned int shift)
89{ 89{
90 if (shift) { 90 if (shift) {
91 if (shift < 32) 91 if (shift < 32)
@@ -96,7 +96,7 @@ static inline u32 vfp_shiftright32jamming(u32 val, unsigned int shift)
96 return val; 96 return val;
97} 97}
98 98
99static inline u64 vfp_shiftright64jamming(u64 val, unsigned int shift) 99inline u64 vfp_shiftright64jamming(u64 val, unsigned int shift)
100{ 100{
101 if (shift) { 101 if (shift) {
102 if (shift < 64) 102 if (shift < 64)
@@ -107,7 +107,7 @@ static inline u64 vfp_shiftright64jamming(u64 val, unsigned int shift)
107 return val; 107 return val;
108} 108}
109 109
110static inline u32 vfp_hi64to32jamming(u64 val) 110inline u32 vfp_hi64to32jamming(u64 val)
111{ 111{
112 u32 v; 112 u32 v;
113 u32 highval = val >> 32; 113 u32 highval = val >> 32;
@@ -121,7 +121,7 @@ static inline u32 vfp_hi64to32jamming(u64 val)
121 return v; 121 return v;
122} 122}
123 123
124static inline void add128(u64* resh, u64* resl, u64 nh, u64 nl, u64 mh, u64 ml) 124inline void add128(u64* resh, u64* resl, u64 nh, u64 nl, u64 mh, u64 ml)
125{ 125{
126 *resl = nl + ml; 126 *resl = nl + ml;
127 *resh = nh + mh; 127 *resh = nh + mh;
@@ -129,7 +129,7 @@ static inline void add128(u64* resh, u64* resl, u64 nh, u64 nl, u64 mh, u64 ml)
129 *resh += 1; 129 *resh += 1;
130} 130}
131 131
132static inline void sub128(u64* resh, u64* resl, u64 nh, u64 nl, u64 mh, u64 ml) 132inline void sub128(u64* resh, u64* resl, u64 nh, u64 nl, u64 mh, u64 ml)
133{ 133{
134 *resl = nl - ml; 134 *resl = nl - ml;
135 *resh = nh - mh; 135 *resh = nh - mh;
@@ -137,7 +137,7 @@ static inline void sub128(u64* resh, u64* resl, u64 nh, u64 nl, u64 mh, u64 ml)
137 *resh -= 1; 137 *resh -= 1;
138} 138}
139 139
140static inline void mul64to128(u64* resh, u64* resl, u64 n, u64 m) 140inline void mul64to128(u64* resh, u64* resl, u64 n, u64 m)
141{ 141{
142 u32 nh, nl, mh, ml; 142 u32 nh, nl, mh, ml;
143 u64 rh, rma, rmb, rl; 143 u64 rh, rma, rmb, rl;
@@ -164,20 +164,20 @@ static inline void mul64to128(u64* resh, u64* resl, u64 n, u64 m)
164 *resh = rh; 164 *resh = rh;
165} 165}
166 166
167static inline void shift64left(u64* resh, u64* resl, u64 n) 167inline void shift64left(u64* resh, u64* resl, u64 n)
168{ 168{
169 *resh = n >> 63; 169 *resh = n >> 63;
170 *resl = n << 1; 170 *resl = n << 1;
171} 171}
172 172
173static inline u64 vfp_hi64multiply64(u64 n, u64 m) 173inline u64 vfp_hi64multiply64(u64 n, u64 m)
174{ 174{
175 u64 rh, rl; 175 u64 rh, rl;
176 mul64to128(&rh, &rl, n, m); 176 mul64to128(&rh, &rl, n, m);
177 return rh | (rl != 0); 177 return rh | (rl != 0);
178} 178}
179 179
180static inline u64 vfp_estimate_div128to64(u64 nh, u64 nl, u64 m) 180inline u64 vfp_estimate_div128to64(u64 nh, u64 nl, u64 m)
181{ 181{
182 u64 mh, ml, remh, reml, termh, terml, z; 182 u64 mh, ml, remh, reml, termh, terml, z;
183 183
@@ -249,7 +249,7 @@ enum : u32 {
249 VFP_SNAN = (VFP_NAN|VFP_NAN_SIGNAL) 249 VFP_SNAN = (VFP_NAN|VFP_NAN_SIGNAL)
250}; 250};
251 251
252static inline int vfp_single_type(vfp_single* s) 252inline int vfp_single_type(const vfp_single* s)
253{ 253{
254 int type = VFP_NUMBER; 254 int type = VFP_NUMBER;
255 if (s->exponent == 255) { 255 if (s->exponent == 255) {
@@ -271,7 +271,7 @@ static inline int vfp_single_type(vfp_single* s)
271// Unpack a single-precision float. Note that this returns the magnitude 271// Unpack a single-precision float. Note that this returns the magnitude
272// of the single-precision float mantissa with the 1. if necessary, 272// of the single-precision float mantissa with the 1. if necessary,
273// aligned to bit 30. 273// aligned to bit 30.
274static inline void vfp_single_unpack(vfp_single* s, s32 val, u32* fpscr) 274inline void vfp_single_unpack(vfp_single* s, s32 val, u32* fpscr)
275{ 275{
276 s->sign = vfp_single_packed_sign(val) >> 16, 276 s->sign = vfp_single_packed_sign(val) >> 16,
277 s->exponent = vfp_single_packed_exponent(val); 277 s->exponent = vfp_single_packed_exponent(val);
@@ -293,7 +293,7 @@ static inline void vfp_single_unpack(vfp_single* s, s32 val, u32* fpscr)
293 293
294// Re-pack a single-precision float. This assumes that the float is 294// Re-pack a single-precision float. This assumes that the float is
295// already normalised such that the MSB is bit 30, _not_ bit 31. 295// already normalised such that the MSB is bit 30, _not_ bit 31.
296static inline s32 vfp_single_pack(vfp_single* s) 296inline s32 vfp_single_pack(const vfp_single* s)
297{ 297{
298 u32 val = (s->sign << 16) + 298 u32 val = (s->sign << 16) +
299 (s->exponent << VFP_SINGLE_MANTISSA_BITS) + 299 (s->exponent << VFP_SINGLE_MANTISSA_BITS) +
@@ -335,7 +335,7 @@ struct vfp_double {
335#define vfp_double_packed_exponent(v) (((v) >> VFP_DOUBLE_MANTISSA_BITS) & ((1 << VFP_DOUBLE_EXPONENT_BITS) - 1)) 335#define vfp_double_packed_exponent(v) (((v) >> VFP_DOUBLE_MANTISSA_BITS) & ((1 << VFP_DOUBLE_EXPONENT_BITS) - 1))
336#define vfp_double_packed_mantissa(v) ((v) & ((1ULL << VFP_DOUBLE_MANTISSA_BITS) - 1)) 336#define vfp_double_packed_mantissa(v) ((v) & ((1ULL << VFP_DOUBLE_MANTISSA_BITS) - 1))
337 337
338static inline int vfp_double_type(vfp_double* s) 338inline int vfp_double_type(const vfp_double* s)
339{ 339{
340 int type = VFP_NUMBER; 340 int type = VFP_NUMBER;
341 if (s->exponent == 2047) { 341 if (s->exponent == 2047) {
@@ -357,7 +357,7 @@ static inline int vfp_double_type(vfp_double* s)
357// Unpack a double-precision float. Note that this returns the magnitude 357// Unpack a double-precision float. Note that this returns the magnitude
358// of the double-precision float mantissa with the 1. if necessary, 358// of the double-precision float mantissa with the 1. if necessary,
359// aligned to bit 62. 359// aligned to bit 62.
360static inline void vfp_double_unpack(vfp_double* s, s64 val, u32* fpscr) 360inline void vfp_double_unpack(vfp_double* s, s64 val, u32* fpscr)
361{ 361{
362 s->sign = vfp_double_packed_sign(val) >> 48; 362 s->sign = vfp_double_packed_sign(val) >> 48;
363 s->exponent = vfp_double_packed_exponent(val); 363 s->exponent = vfp_double_packed_exponent(val);
@@ -379,7 +379,7 @@ static inline void vfp_double_unpack(vfp_double* s, s64 val, u32* fpscr)
379 379
380// Re-pack a double-precision float. This assumes that the float is 380// Re-pack a double-precision float. This assumes that the float is
381// already normalised such that the MSB is bit 30, _not_ bit 31. 381// already normalised such that the MSB is bit 30, _not_ bit 31.
382static inline s64 vfp_double_pack(vfp_double* s) 382inline s64 vfp_double_pack(const vfp_double* s)
383{ 383{
384 u64 val = ((u64)s->sign << 48) + 384 u64 val = ((u64)s->sign << 48) +
385 ((u64)s->exponent << VFP_DOUBLE_MANTISSA_BITS) + 385 ((u64)s->exponent << VFP_DOUBLE_MANTISSA_BITS) +
@@ -415,7 +415,7 @@ struct op {
415 u32 flags; 415 u32 flags;
416}; 416};
417 417
418static inline u32 fls(u32 x) 418inline u32 fls(u32 x)
419{ 419{
420 int r = 32; 420 int r = 32;
421 421
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 219b03af4..84d6c392e 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -2,6 +2,9 @@
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 <memory>
6
7#include "common/make_unique.h"
5#include "common/logging/log.h" 8#include "common/logging/log.h"
6 9
7#include "core/core.h" 10#include "core/core.h"
@@ -17,8 +20,8 @@
17 20
18namespace Core { 21namespace Core {
19 22
20ARM_Interface* g_app_core = nullptr; ///< ARM11 application core 23std::unique_ptr<ARM_Interface> g_app_core; ///< ARM11 application core
21ARM_Interface* g_sys_core = nullptr; ///< ARM11 system (OS) core 24std::unique_ptr<ARM_Interface> g_sys_core; ///< ARM11 system (OS) core
22 25
23/// Run the core CPU loop 26/// Run the core CPU loop
24void RunLoop(int tight_loop) { 27void RunLoop(int tight_loop) {
@@ -70,17 +73,16 @@ void Stop() {
70} 73}
71 74
72/// Initialize the core 75/// Initialize the core
73int Init() { 76void Init() {
74 g_sys_core = new ARM_DynCom(USER32MODE); 77 g_sys_core = Common::make_unique<ARM_DynCom>(USER32MODE);
75 g_app_core = new ARM_DynCom(USER32MODE); 78 g_app_core = Common::make_unique<ARM_DynCom>(USER32MODE);
76 79
77 LOG_DEBUG(Core, "Initialized OK"); 80 LOG_DEBUG(Core, "Initialized OK");
78 return 0;
79} 81}
80 82
81void Shutdown() { 83void Shutdown() {
82 delete g_app_core; 84 g_app_core.reset();
83 delete g_sys_core; 85 g_sys_core.reset();
84 86
85 LOG_DEBUG(Core, "Shutdown OK"); 87 LOG_DEBUG(Core, "Shutdown OK");
86} 88}
diff --git a/src/core/core.h b/src/core/core.h
index 491230a74..ad26dca3f 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -4,6 +4,7 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <memory>
7#include "common/common_types.h" 8#include "common/common_types.h"
8 9
9class ARM_Interface; 10class ARM_Interface;
@@ -23,8 +24,8 @@ struct ThreadContext {
23 u32 fpexc; 24 u32 fpexc;
24}; 25};
25 26
26extern ARM_Interface* g_app_core; ///< ARM11 application core 27extern std::unique_ptr<ARM_Interface> g_app_core; ///< ARM11 application core
27extern ARM_Interface* g_sys_core; ///< ARM11 system (OS) core 28extern std::unique_ptr<ARM_Interface> g_sys_core; ///< ARM11 system (OS) core
28 29
29//////////////////////////////////////////////////////////////////////////////////////////////////// 30////////////////////////////////////////////////////////////////////////////////////////////////////
30 31
@@ -51,7 +52,7 @@ void Halt(const char *msg);
51void Stop(); 52void Stop();
52 53
53/// Initialize the core 54/// Initialize the core
54int Init(); 55void Init();
55 56
56/// Shutdown the core 57/// Shutdown the core
57void Shutdown(); 58void Shutdown();
diff --git a/src/core/file_sys/archive_backend.cpp b/src/core/file_sys/archive_backend.cpp
index 3f81447df..97adf0e12 100644
--- a/src/core/file_sys/archive_backend.cpp
+++ b/src/core/file_sys/archive_backend.cpp
@@ -43,7 +43,7 @@ Path::Path(LowPathType type, u32 size, u32 pointer) : type(type) {
43 } 43 }
44} 44}
45 45
46const std::string Path::DebugStr() const { 46std::string Path::DebugStr() const {
47 switch (GetType()) { 47 switch (GetType()) {
48 case Invalid: 48 case Invalid:
49 default: 49 default:
@@ -66,7 +66,7 @@ const std::string Path::DebugStr() const {
66 } 66 }
67} 67}
68 68
69const std::string Path::AsString() const { 69std::string Path::AsString() const {
70 switch (GetType()) { 70 switch (GetType()) {
71 case Char: 71 case Char:
72 return string; 72 return string;
@@ -83,7 +83,7 @@ const std::string Path::AsString() const {
83 } 83 }
84} 84}
85 85
86const std::u16string Path::AsU16Str() const { 86std::u16string Path::AsU16Str() const {
87 switch (GetType()) { 87 switch (GetType()) {
88 case Char: 88 case Char:
89 return Common::UTF8ToUTF16(string); 89 return Common::UTF8ToUTF16(string);
@@ -99,7 +99,7 @@ const std::u16string Path::AsU16Str() const {
99 } 99 }
100} 100}
101 101
102const std::vector<u8> Path::AsBinary() const { 102std::vector<u8> Path::AsBinary() const {
103 switch (GetType()) { 103 switch (GetType()) {
104 case Binary: 104 case Binary:
105 return binary; 105 return binary;
diff --git a/src/core/file_sys/archive_backend.h b/src/core/file_sys/archive_backend.h
index e7a59a1ed..601e95d8c 100644
--- a/src/core/file_sys/archive_backend.h
+++ b/src/core/file_sys/archive_backend.h
@@ -49,11 +49,11 @@ public:
49 * Gets the string representation of the path for debugging 49 * Gets the string representation of the path for debugging
50 * @return String representation of the path for debugging 50 * @return String representation of the path for debugging
51 */ 51 */
52 const std::string DebugStr() const; 52 std::string DebugStr() const;
53 53
54 const std::string AsString() const; 54 std::string AsString() const;
55 const std::u16string AsU16Str() const; 55 std::u16string AsU16Str() const;
56 const std::vector<u8> AsBinary() const; 56 std::vector<u8> AsBinary() const;
57 57
58private: 58private:
59 LowPathType type; 59 LowPathType type;
diff --git a/src/core/file_sys/disk_archive.cpp b/src/core/file_sys/disk_archive.cpp
index 0ba502200..a51416774 100644
--- a/src/core/file_sys/disk_archive.cpp
+++ b/src/core/file_sys/disk_archive.cpp
@@ -139,7 +139,7 @@ bool DiskFile::Close() const {
139 139
140//////////////////////////////////////////////////////////////////////////////////////////////////// 140////////////////////////////////////////////////////////////////////////////////////////////////////
141 141
142DiskDirectory::DiskDirectory(const DiskArchive& archive, const Path& path) { 142DiskDirectory::DiskDirectory(const DiskArchive& archive, const Path& path) : directory() {
143 // TODO(Link Mauve): normalize path into an absolute path without "..", it can currently bypass 143 // TODO(Link Mauve): normalize path into an absolute path without "..", it can currently bypass
144 // the root directory we set while opening the archive. 144 // the root directory we set while opening the archive.
145 // For example, opening /../../usr/bin can give the emulated program your installed programs. 145 // For example, opening /../../usr/bin can give the emulated program your installed programs.
@@ -149,7 +149,9 @@ DiskDirectory::DiskDirectory(const DiskArchive& archive, const Path& path) {
149bool DiskDirectory::Open() { 149bool DiskDirectory::Open() {
150 if (!FileUtil::IsDirectory(path)) 150 if (!FileUtil::IsDirectory(path))
151 return false; 151 return false;
152 FileUtil::ScanDirectoryTree(path, directory); 152 unsigned size = FileUtil::ScanDirectoryTree(path, directory);
153 directory.size = size;
154 directory.isDirectory = true;
153 children_iterator = directory.children.begin(); 155 children_iterator = directory.children.begin();
154 return true; 156 return true;
155} 157}
diff --git a/src/core/hle/function_wrappers.h b/src/core/hle/function_wrappers.h
index 3501e45db..882a51df1 100644
--- a/src/core/hle/function_wrappers.h
+++ b/src/core/hle/function_wrappers.h
@@ -188,6 +188,10 @@ template<ResultCode func(s64*, Handle, u32)> void Wrap() {
188 FuncReturn(retval); 188 FuncReturn(retval);
189} 189}
190 190
191template<ResultCode func(Handle, u32)> void Wrap() {
192 FuncReturn(func(PARAM(0), PARAM(1)).raw);
193}
194
191//////////////////////////////////////////////////////////////////////////////////////////////////// 195////////////////////////////////////////////////////////////////////////////////////////////////////
192// Function wrappers that return type u32 196// Function wrappers that return type u32
193 197
diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp
index 195286422..5c3c47acf 100644
--- a/src/core/hle/kernel/address_arbiter.cpp
+++ b/src/core/hle/kernel/address_arbiter.cpp
@@ -45,30 +45,32 @@ ResultCode AddressArbiter::ArbitrateAddress(ArbitrationType type, VAddr address,
45 45
46 // Wait current thread (acquire the arbiter)... 46 // Wait current thread (acquire the arbiter)...
47 case ArbitrationType::WaitIfLessThan: 47 case ArbitrationType::WaitIfLessThan:
48 if ((s32)Memory::Read32(address) <= value) { 48 if ((s32)Memory::Read32(address) < value) {
49 Kernel::WaitCurrentThread_ArbitrateAddress(address); 49 Kernel::WaitCurrentThread_ArbitrateAddress(address);
50 } 50 }
51 break; 51 break;
52 case ArbitrationType::WaitIfLessThanWithTimeout: 52 case ArbitrationType::WaitIfLessThanWithTimeout:
53 if ((s32)Memory::Read32(address) <= value) { 53 if ((s32)Memory::Read32(address) < value) {
54 Kernel::WaitCurrentThread_ArbitrateAddress(address); 54 Kernel::WaitCurrentThread_ArbitrateAddress(address);
55 GetCurrentThread()->WakeAfterDelay(nanoseconds); 55 GetCurrentThread()->WakeAfterDelay(nanoseconds);
56 } 56 }
57 break; 57 break;
58 case ArbitrationType::DecrementAndWaitIfLessThan: 58 case ArbitrationType::DecrementAndWaitIfLessThan:
59 { 59 {
60 s32 memory_value = Memory::Read32(address) - 1; 60 s32 memory_value = Memory::Read32(address);
61 Memory::Write32(address, memory_value); 61 if (memory_value < value) {
62 if (memory_value <= value) { 62 // Only change the memory value if the thread should wait
63 Memory::Write32(address, (s32)memory_value - 1);
63 Kernel::WaitCurrentThread_ArbitrateAddress(address); 64 Kernel::WaitCurrentThread_ArbitrateAddress(address);
64 } 65 }
65 break; 66 break;
66 } 67 }
67 case ArbitrationType::DecrementAndWaitIfLessThanWithTimeout: 68 case ArbitrationType::DecrementAndWaitIfLessThanWithTimeout:
68 { 69 {
69 s32 memory_value = Memory::Read32(address) - 1; 70 s32 memory_value = Memory::Read32(address);
70 Memory::Write32(address, memory_value); 71 if (memory_value < value) {
71 if (memory_value <= value) { 72 // Only change the memory value if the thread should wait
73 Memory::Write32(address, (s32)memory_value - 1);
72 Kernel::WaitCurrentThread_ArbitrateAddress(address); 74 Kernel::WaitCurrentThread_ArbitrateAddress(address);
73 GetCurrentThread()->WakeAfterDelay(nanoseconds); 75 GetCurrentThread()->WakeAfterDelay(nanoseconds);
74 } 76 }
@@ -82,6 +84,13 @@ ResultCode AddressArbiter::ArbitrateAddress(ArbitrationType type, VAddr address,
82 84
83 HLE::Reschedule(__func__); 85 HLE::Reschedule(__func__);
84 86
87 // The calls that use a timeout seem to always return a Timeout error even if they did not put the thread to sleep
88 if (type == ArbitrationType::WaitIfLessThanWithTimeout ||
89 type == ArbitrationType::DecrementAndWaitIfLessThanWithTimeout) {
90
91 return ResultCode(ErrorDescription::Timeout, ErrorModule::OS,
92 ErrorSummary::StatusChanged, ErrorLevel::Info);
93 }
85 return RESULT_SUCCESS; 94 return RESULT_SUCCESS;
86} 95}
87 96
diff --git a/src/core/hle/kernel/memory.cpp b/src/core/hle/kernel/memory.cpp
index 0cfb43fc7..862643448 100644
--- a/src/core/hle/kernel/memory.cpp
+++ b/src/core/hle/kernel/memory.cpp
@@ -7,6 +7,8 @@
7#include <utility> 7#include <utility>
8#include <vector> 8#include <vector>
9 9
10#include "audio_core/audio_core.h"
11
10#include "common/common_types.h" 12#include "common/common_types.h"
11#include "common/logging/log.h" 13#include "common/logging/log.h"
12 14
@@ -107,7 +109,6 @@ struct MemoryArea {
107static MemoryArea memory_areas[] = { 109static MemoryArea memory_areas[] = {
108 {SHARED_MEMORY_VADDR, SHARED_MEMORY_SIZE, "Shared Memory"}, // Shared memory 110 {SHARED_MEMORY_VADDR, SHARED_MEMORY_SIZE, "Shared Memory"}, // Shared memory
109 {VRAM_VADDR, VRAM_SIZE, "VRAM"}, // Video memory (VRAM) 111 {VRAM_VADDR, VRAM_SIZE, "VRAM"}, // Video memory (VRAM)
110 {DSP_RAM_VADDR, DSP_RAM_SIZE, "DSP RAM"}, // DSP memory
111 {TLS_AREA_VADDR, TLS_AREA_SIZE, "TLS Area"}, // TLS memory 112 {TLS_AREA_VADDR, TLS_AREA_SIZE, "TLS Area"}, // TLS memory
112}; 113};
113 114
@@ -133,6 +134,8 @@ void InitLegacyAddressSpace(Kernel::VMManager& address_space) {
133 auto shared_page_vma = address_space.MapBackingMemory(SHARED_PAGE_VADDR, 134 auto shared_page_vma = address_space.MapBackingMemory(SHARED_PAGE_VADDR,
134 (u8*)&SharedPage::shared_page, SHARED_PAGE_SIZE, MemoryState::Shared).MoveFrom(); 135 (u8*)&SharedPage::shared_page, SHARED_PAGE_SIZE, MemoryState::Shared).MoveFrom();
135 address_space.Reprotect(shared_page_vma, VMAPermission::Read); 136 address_space.Reprotect(shared_page_vma, VMAPermission::Read);
137
138 AudioCore::AddAddressSpace(address_space);
136} 139}
137 140
138} // namespace 141} // namespace
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index d148efde2..24b266eae 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -35,7 +35,7 @@ SharedPtr<Process> Process::Create(SharedPtr<CodeSet> code_set) {
35 35
36 process->codeset = std::move(code_set); 36 process->codeset = std::move(code_set);
37 process->flags.raw = 0; 37 process->flags.raw = 0;
38 process->flags.memory_region = MemoryRegion::APPLICATION; 38 process->flags.memory_region.Assign(MemoryRegion::APPLICATION);
39 Memory::InitLegacyAddressSpace(process->vm_manager); 39 Memory::InitLegacyAddressSpace(process->vm_manager);
40 40
41 return process; 41 return process;
@@ -130,9 +130,11 @@ void Process::Run(s32 main_thread_priority, u32 stack_size) {
130 Kernel::SetupMainThread(codeset->entrypoint, main_thread_priority); 130 Kernel::SetupMainThread(codeset->entrypoint, main_thread_priority);
131} 131}
132 132
133VAddr Process::GetLinearHeapAreaAddress() const {
134 return kernel_version < 0x22C ? Memory::LINEAR_HEAP_VADDR : Memory::NEW_LINEAR_HEAP_VADDR;
135}
133VAddr Process::GetLinearHeapBase() const { 136VAddr Process::GetLinearHeapBase() const {
134 return (kernel_version < 0x22C ? Memory::LINEAR_HEAP_VADDR : Memory::NEW_LINEAR_HEAP_VADDR) 137 return GetLinearHeapAreaAddress() + memory_region->base;
135 + memory_region->base;
136} 138}
137 139
138VAddr Process::GetLinearHeapLimit() const { 140VAddr Process::GetLinearHeapLimit() const {
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h
index 60e17f251..6d2ca96a2 100644
--- a/src/core/hle/kernel/process.h
+++ b/src/core/hle/kernel/process.h
@@ -143,6 +143,7 @@ public:
143 /// Bitmask of the used TLS slots 143 /// Bitmask of the used TLS slots
144 std::bitset<300> used_tls_slots; 144 std::bitset<300> used_tls_slots;
145 145
146 VAddr GetLinearHeapAreaAddress() const;
146 VAddr GetLinearHeapBase() const; 147 VAddr GetLinearHeapBase() const;
147 VAddr GetLinearHeapLimit() const; 148 VAddr GetLinearHeapLimit() const;
148 149
diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp
index 1f477664b..d90f0f00f 100644
--- a/src/core/hle/kernel/shared_memory.cpp
+++ b/src/core/hle/kernel/shared_memory.cpp
@@ -39,6 +39,12 @@ ResultCode SharedMemory::Map(VAddr address, MemoryPermission permissions,
39 ErrorSummary::InvalidArgument, ErrorLevel::Permanent); 39 ErrorSummary::InvalidArgument, ErrorLevel::Permanent);
40 } 40 }
41 41
42 // TODO(Subv): Return E0E01BEE when permissions and other_permissions don't
43 // match what was specified when the memory block was created.
44
45 // TODO(Subv): Return E0E01BEE when address should be 0.
46 // Note: Find out when that's the case.
47
42 if (fixed_address != 0) { 48 if (fixed_address != 0) {
43 if (address != 0 && address != fixed_address) { 49 if (address != 0 && address != fixed_address) {
44 LOG_ERROR(Kernel, "cannot map id=%u, address=0x%08X name=%s: fixed_addres is 0x%08X!", 50 LOG_ERROR(Kernel, "cannot map id=%u, address=0x%08X name=%s: fixed_addres is 0x%08X!",
@@ -74,6 +80,21 @@ ResultCode SharedMemory::Map(VAddr address, MemoryPermission permissions,
74 return RESULT_SUCCESS; 80 return RESULT_SUCCESS;
75} 81}
76 82
83ResultCode SharedMemory::Unmap(VAddr address) {
84 if (base_address == 0) {
85 // TODO(Subv): Verify what actually happens when you want to unmap a memory block that
86 // was originally mapped with address = 0
87 return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::OS, ErrorSummary::InvalidArgument, ErrorLevel::Usage);
88 }
89
90 if (base_address != address)
91 return ResultCode(ErrorDescription::WrongAddress, ErrorModule::OS, ErrorSummary::InvalidState, ErrorLevel::Usage);
92
93 base_address = 0;
94
95 return RESULT_SUCCESS;
96}
97
77u8* SharedMemory::GetPointer(u32 offset) { 98u8* SharedMemory::GetPointer(u32 offset) {
78 if (base_address != 0) 99 if (base_address != 0)
79 return Memory::GetPointer(base_address + offset); 100 return Memory::GetPointer(base_address + offset);
diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h
index 35b550d12..b51049ad0 100644
--- a/src/core/hle/kernel/shared_memory.h
+++ b/src/core/hle/kernel/shared_memory.h
@@ -53,6 +53,13 @@ public:
53 ResultCode Map(VAddr address, MemoryPermission permissions, MemoryPermission other_permissions); 53 ResultCode Map(VAddr address, MemoryPermission permissions, MemoryPermission other_permissions);
54 54
55 /** 55 /**
56 * Unmaps a shared memory block from the specified address in system memory
57 * @param address Address in system memory where the shared memory block is mapped
58 * @return Result code of the unmap operation
59 */
60 ResultCode Unmap(VAddr address);
61
62 /**
56 * Gets a pointer to the shared memory block 63 * Gets a pointer to the shared memory block
57 * @param offset Offset from the start of the shared memory block to get pointer 64 * @param offset Offset from the start of the shared memory block to get pointer
58 * @return Pointer to the shared memory block from the specified offset 65 * @return Pointer to the shared memory block from the specified offset
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index c08fc1c7a..bf32f653d 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -300,7 +300,7 @@ static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) {
300 300
301 thread->waitsynch_waited = false; 301 thread->waitsynch_waited = false;
302 302
303 if (thread->status == THREADSTATUS_WAIT_SYNCH) { 303 if (thread->status == THREADSTATUS_WAIT_SYNCH || thread->status == THREADSTATUS_WAIT_ARB) {
304 thread->SetWaitSynchronizationResult(ResultCode(ErrorDescription::Timeout, ErrorModule::OS, 304 thread->SetWaitSynchronizationResult(ResultCode(ErrorDescription::Timeout, ErrorModule::OS,
305 ErrorSummary::StatusChanged, ErrorLevel::Info)); 305 ErrorSummary::StatusChanged, ErrorLevel::Info));
306 306
diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp
index 08b3ea8c0..ce6bbd719 100644
--- a/src/core/hle/kernel/timer.cpp
+++ b/src/core/hle/kernel/timer.cpp
@@ -42,6 +42,9 @@ bool Timer::ShouldWait() {
42 42
43void Timer::Acquire() { 43void Timer::Acquire() {
44 ASSERT_MSG( !ShouldWait(), "object unavailable!"); 44 ASSERT_MSG( !ShouldWait(), "object unavailable!");
45
46 if (reset_type == RESETTYPE_ONESHOT)
47 signaled = false;
45} 48}
46 49
47void Timer::Set(s64 initial, s64 interval) { 50void Timer::Set(s64 initial, s64 interval) {
@@ -84,9 +87,6 @@ static void TimerCallback(u64 timer_handle, int cycles_late) {
84 // Resume all waiting threads 87 // Resume all waiting threads
85 timer->WakeupAllWaitingThreads(); 88 timer->WakeupAllWaitingThreads();
86 89
87 if (timer->reset_type == RESETTYPE_ONESHOT)
88 timer->signaled = false;
89
90 if (timer->interval_delay != 0) { 90 if (timer->interval_delay != 0) {
91 // Reschedule the timer with the interval delay 91 // Reschedule the timer with the interval delay
92 u64 interval_microseconds = timer->interval_delay / 1000; 92 u64 interval_microseconds = timer->interval_delay / 1000;
diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp
index 2610acf76..1e289f38a 100644
--- a/src/core/hle/kernel/vm_manager.cpp
+++ b/src/core/hle/kernel/vm_manager.cpp
@@ -8,6 +8,7 @@
8 8
9#include "core/hle/kernel/vm_manager.h" 9#include "core/hle/kernel/vm_manager.h"
10#include "core/memory_setup.h" 10#include "core/memory_setup.h"
11#include "core/mmio.h"
11 12
12namespace Kernel { 13namespace Kernel {
13 14
@@ -104,7 +105,7 @@ ResultVal<VMManager::VMAHandle> VMManager::MapBackingMemory(VAddr target, u8 * m
104 return MakeResult<VMAHandle>(MergeAdjacent(vma_handle)); 105 return MakeResult<VMAHandle>(MergeAdjacent(vma_handle));
105} 106}
106 107
107ResultVal<VMManager::VMAHandle> VMManager::MapMMIO(VAddr target, PAddr paddr, u32 size, MemoryState state) { 108ResultVal<VMManager::VMAHandle> VMManager::MapMMIO(VAddr target, PAddr paddr, u32 size, MemoryState state, Memory::MMIORegionPointer mmio_handler) {
108 // This is the appropriately sized VMA that will turn into our allocation. 109 // This is the appropriately sized VMA that will turn into our allocation.
109 CASCADE_RESULT(VMAIter vma_handle, CarveVMA(target, size)); 110 CASCADE_RESULT(VMAIter vma_handle, CarveVMA(target, size));
110 VirtualMemoryArea& final_vma = vma_handle->second; 111 VirtualMemoryArea& final_vma = vma_handle->second;
@@ -114,6 +115,7 @@ ResultVal<VMManager::VMAHandle> VMManager::MapMMIO(VAddr target, PAddr paddr, u3
114 final_vma.permissions = VMAPermission::ReadWrite; 115 final_vma.permissions = VMAPermission::ReadWrite;
115 final_vma.meminfo_state = state; 116 final_vma.meminfo_state = state;
116 final_vma.paddr = paddr; 117 final_vma.paddr = paddr;
118 final_vma.mmio_handler = mmio_handler;
117 UpdatePageTableForVMA(final_vma); 119 UpdatePageTableForVMA(final_vma);
118 120
119 return MakeResult<VMAHandle>(MergeAdjacent(vma_handle)); 121 return MakeResult<VMAHandle>(MergeAdjacent(vma_handle));
@@ -330,8 +332,7 @@ void VMManager::UpdatePageTableForVMA(const VirtualMemoryArea& vma) {
330 Memory::MapMemoryRegion(vma.base, vma.size, vma.backing_memory); 332 Memory::MapMemoryRegion(vma.base, vma.size, vma.backing_memory);
331 break; 333 break;
332 case VMAType::MMIO: 334 case VMAType::MMIO:
333 // TODO(yuriks): Add support for MMIO handlers. 335 Memory::MapIoRegion(vma.base, vma.size, vma.mmio_handler);
334 Memory::MapIoRegion(vma.base, vma.size);
335 break; 336 break;
336 } 337 }
337} 338}
diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h
index 4e95f1f0c..91d40655b 100644
--- a/src/core/hle/kernel/vm_manager.h
+++ b/src/core/hle/kernel/vm_manager.h
@@ -11,6 +11,7 @@
11#include "common/common_types.h" 11#include "common/common_types.h"
12 12
13#include "core/hle/result.h" 13#include "core/hle/result.h"
14#include "core/mmio.h"
14 15
15namespace Kernel { 16namespace Kernel {
16 17
@@ -92,6 +93,7 @@ struct VirtualMemoryArea {
92 // Settings for type = MMIO 93 // Settings for type = MMIO
93 /// Physical address of the register area this VMA maps to. 94 /// Physical address of the register area this VMA maps to.
94 PAddr paddr = 0; 95 PAddr paddr = 0;
96 Memory::MMIORegionPointer mmio_handler = nullptr;
95 97
96 /// Tests if this area can be merged to the right with `next`. 98 /// Tests if this area can be merged to the right with `next`.
97 bool CanBeMergedWith(const VirtualMemoryArea& next) const; 99 bool CanBeMergedWith(const VirtualMemoryArea& next) const;
@@ -168,8 +170,9 @@ public:
168 * @param paddr The physical address where the registers are present. 170 * @param paddr The physical address where the registers are present.
169 * @param size Size of the mapping. 171 * @param size Size of the mapping.
170 * @param state MemoryState tag to attach to the VMA. 172 * @param state MemoryState tag to attach to the VMA.
173 * @param mmio_handler The handler that will implement read and write for this MMIO region.
171 */ 174 */
172 ResultVal<VMAHandle> MapMMIO(VAddr target, PAddr paddr, u32 size, MemoryState state); 175 ResultVal<VMAHandle> MapMMIO(VAddr target, PAddr paddr, u32 size, MemoryState state, Memory::MMIORegionPointer mmio_handler);
173 176
174 /// Unmaps a range of addresses, splitting VMAs as necessary. 177 /// Unmaps a range of addresses, splitting VMAs as necessary.
175 ResultCode UnmapRange(VAddr target, u32 size); 178 ResultCode UnmapRange(VAddr target, u32 size);
diff --git a/src/core/hle/result.h b/src/core/hle/result.h
index cb2d681e0..69613fbbb 100644
--- a/src/core/hle/result.h
+++ b/src/core/hle/result.h
@@ -18,6 +18,7 @@
18/// Detailed description of the error. This listing is likely incomplete. 18/// Detailed description of the error. This listing is likely incomplete.
19enum class ErrorDescription : u32 { 19enum class ErrorDescription : u32 {
20 Success = 0, 20 Success = 0,
21 WrongAddress = 53,
21 FS_NotFound = 100, 22 FS_NotFound = 100,
22 FS_NotFormatted = 340, ///< This is used by the FS service when creating a SaveData archive 23 FS_NotFormatted = 340, ///< This is used by the FS service when creating a SaveData archive
23 InvalidSection = 1000, 24 InvalidSection = 1000,
@@ -192,10 +193,10 @@ union ResultCode {
192 explicit ResultCode(u32 raw) : raw(raw) {} 193 explicit ResultCode(u32 raw) : raw(raw) {}
193 ResultCode(ErrorDescription description_, ErrorModule module_, 194 ResultCode(ErrorDescription description_, ErrorModule module_,
194 ErrorSummary summary_, ErrorLevel level_) : raw(0) { 195 ErrorSummary summary_, ErrorLevel level_) : raw(0) {
195 description = description_; 196 description.Assign(description_);
196 module = module_; 197 module.Assign(module_);
197 summary = summary_; 198 summary.Assign(summary_);
198 level = level_; 199 level.Assign(level_);
199 } 200 }
200 201
201 ResultCode& operator=(const ResultCode& o) { raw = o.raw; return *this; } 202 ResultCode& operator=(const ResultCode& o) { raw = o.raw; return *this; }
@@ -268,7 +269,6 @@ public:
268 : result_code(error_code) 269 : result_code(error_code)
269 { 270 {
270 ASSERT(error_code.IsError()); 271 ASSERT(error_code.IsError());
271 UpdateDebugPtr();
272 } 272 }
273 273
274 /** 274 /**
@@ -286,40 +286,37 @@ public:
286 : result_code(o.result_code) 286 : result_code(o.result_code)
287 { 287 {
288 if (!o.empty()) { 288 if (!o.empty()) {
289 new (&storage) T(*o.GetPointer()); 289 new (&object) T(o.object);
290 } 290 }
291 UpdateDebugPtr();
292 } 291 }
293 292
294 ResultVal(ResultVal&& o) 293 ResultVal(ResultVal&& o)
295 : result_code(o.result_code) 294 : result_code(o.result_code)
296 { 295 {
297 if (!o.empty()) { 296 if (!o.empty()) {
298 new (&storage) T(std::move(*o.GetPointer())); 297 new (&object) T(std::move(o.object));
299 } 298 }
300 UpdateDebugPtr();
301 } 299 }
302 300
303 ~ResultVal() { 301 ~ResultVal() {
304 if (!empty()) { 302 if (!empty()) {
305 GetPointer()->~T(); 303 object.~T();
306 } 304 }
307 } 305 }
308 306
309 ResultVal& operator=(const ResultVal& o) { 307 ResultVal& operator=(const ResultVal& o) {
310 if (!empty()) { 308 if (!empty()) {
311 if (!o.empty()) { 309 if (!o.empty()) {
312 *GetPointer() = *o.GetPointer(); 310 object = o.object;
313 } else { 311 } else {
314 GetPointer()->~T(); 312 object.~T();
315 } 313 }
316 } else { 314 } else {
317 if (!o.empty()) { 315 if (!o.empty()) {
318 new (&storage) T(*o.GetPointer()); 316 new (&object) T(o.object);
319 } 317 }
320 } 318 }
321 result_code = o.result_code; 319 result_code = o.result_code;
322 UpdateDebugPtr();
323 320
324 return *this; 321 return *this;
325 } 322 }
@@ -332,11 +329,10 @@ public:
332 void emplace(ResultCode success_code, Args&&... args) { 329 void emplace(ResultCode success_code, Args&&... args) {
333 ASSERT(success_code.IsSuccess()); 330 ASSERT(success_code.IsSuccess());
334 if (!empty()) { 331 if (!empty()) {
335 GetPointer()->~T(); 332 object.~T();
336 } 333 }
337 new (&storage) T(std::forward<Args>(args)...); 334 new (&object) T(std::forward<Args>(args)...);
338 result_code = success_code; 335 result_code = success_code;
339 UpdateDebugPtr();
340 } 336 }
341 337
342 /// Returns true if the `ResultVal` contains an error code and no value. 338 /// Returns true if the `ResultVal` contains an error code and no value.
@@ -349,15 +345,15 @@ public:
349 345
350 ResultCode Code() const { return result_code; } 346 ResultCode Code() const { return result_code; }
351 347
352 const T& operator* () const { return *GetPointer(); } 348 const T& operator* () const { return object; }
353 T& operator* () { return *GetPointer(); } 349 T& operator* () { return object; }
354 const T* operator->() const { return GetPointer(); } 350 const T* operator->() const { return &object; }
355 T* operator->() { return GetPointer(); } 351 T* operator->() { return &object; }
356 352
357 /// Returns the value contained in this `ResultVal`, or the supplied default if it is missing. 353 /// Returns the value contained in this `ResultVal`, or the supplied default if it is missing.
358 template <typename U> 354 template <typename U>
359 T ValueOr(U&& value) const { 355 T ValueOr(U&& value) const {
360 return !empty() ? *GetPointer() : std::move(value); 356 return !empty() ? object : std::move(value);
361 } 357 }
362 358
363 /// Asserts that the result succeeded and returns a reference to it. 359 /// Asserts that the result succeeded and returns a reference to it.
@@ -371,31 +367,10 @@ public:
371 } 367 }
372 368
373private: 369private:
374 typedef typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type StorageType; 370 // A union is used to allocate the storage for the value, while allowing us to construct and
375 371 // destruct it at will.
376 StorageType storage; 372 union { T object; };
377 ResultCode result_code; 373 ResultCode result_code;
378#ifdef _DEBUG
379 // The purpose of this pointer is to aid inspecting the type with a debugger, eliminating the
380 // need to cast `storage` to a pointer or pay attention to `result_code`.
381 const T* debug_ptr;
382#endif
383
384 void UpdateDebugPtr() {
385#ifdef _DEBUG
386 debug_ptr = empty() ? nullptr : static_cast<const T*>(static_cast<const void*>(&storage));
387#endif
388 }
389
390 const T* GetPointer() const {
391 ASSERT(!empty());
392 return static_cast<const T*>(static_cast<const void*>(&storage));
393 }
394
395 T* GetPointer() {
396 ASSERT(!empty());
397 return static_cast<T*>(static_cast<void*>(&storage));
398 }
399}; 374};
400 375
401/** 376/**
diff --git a/src/core/hle/service/ac_u.cpp b/src/core/hle/service/ac_u.cpp
index f8aab6bc7..d67325506 100644
--- a/src/core/hle/service/ac_u.cpp
+++ b/src/core/hle/service/ac_u.cpp
@@ -3,7 +3,6 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "common/logging/log.h" 5#include "common/logging/log.h"
6#include "core/hle/hle.h"
7#include "core/hle/service/ac_u.h" 6#include "core/hle/service/ac_u.h"
8 7
9//////////////////////////////////////////////////////////////////////////////////////////////////// 8////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -23,12 +22,27 @@ static void GetWifiStatus(Service::Interface* self) {
23 // TODO(purpasmart96): This function is only a stub, 22 // TODO(purpasmart96): This function is only a stub,
24 // it returns a valid result without implementing full functionality. 23 // it returns a valid result without implementing full functionality.
25 24
26 cmd_buff[1] = 0; // No error 25 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
27 cmd_buff[2] = 0; // Connection type set to none 26 cmd_buff[2] = 0; // Connection type set to none
28 27
29 LOG_WARNING(Service_AC, "(STUBBED) called"); 28 LOG_WARNING(Service_AC, "(STUBBED) called");
30} 29}
31 30
31/**
32 * AC_U::IsConnected service function
33 * Outputs:
34 * 1 : Result of function, 0 on success, otherwise error code
35 * 2 : bool, is connected
36 */
37static void IsConnected(Service::Interface* self) {
38 u32* cmd_buff = Kernel::GetCommandBuffer();
39
40 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
41 cmd_buff[2] = false; // Not connected to ac:u service
42
43 LOG_WARNING(Service_AC, "(STUBBED) called");
44}
45
32const Interface::FunctionInfo FunctionTable[] = { 46const Interface::FunctionInfo FunctionTable[] = {
33 {0x00010000, nullptr, "CreateDefaultConfig"}, 47 {0x00010000, nullptr, "CreateDefaultConfig"},
34 {0x00040006, nullptr, "ConnectAsync"}, 48 {0x00040006, nullptr, "ConnectAsync"},
@@ -45,7 +59,7 @@ const Interface::FunctionInfo FunctionTable[] = {
45 {0x002D0082, nullptr, "SetRequestEulaVersion"}, 59 {0x002D0082, nullptr, "SetRequestEulaVersion"},
46 {0x00300004, nullptr, "RegisterDisconnectEvent"}, 60 {0x00300004, nullptr, "RegisterDisconnectEvent"},
47 {0x003C0042, nullptr, "GetAPSSIDList"}, 61 {0x003C0042, nullptr, "GetAPSSIDList"},
48 {0x003E0042, nullptr, "IsConnected"}, 62 {0x003E0042, IsConnected, "IsConnected"},
49 {0x00400042, nullptr, "SetClientVersion"}, 63 {0x00400042, nullptr, "SetClientVersion"},
50}; 64};
51 65
diff --git a/src/core/hle/service/act_u.cpp b/src/core/hle/service/act_u.cpp
index 57f49c91f..b23d17fba 100644
--- a/src/core/hle/service/act_u.cpp
+++ b/src/core/hle/service/act_u.cpp
@@ -2,7 +2,6 @@
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 "core/hle/hle.h"
6#include "core/hle/service/act_u.h" 5#include "core/hle/service/act_u.h"
7 6
8//////////////////////////////////////////////////////////////////////////////////////////////////// 7////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -10,14 +9,15 @@
10 9
11namespace ACT_U { 10namespace ACT_U {
12 11
13// Empty arrays are illegal -- commented out until an entry is added. 12const Interface::FunctionInfo FunctionTable[] = {
14//const Interface::FunctionInfo FunctionTable[] = { }; 13 {0x000600C2, nullptr, "GetAccountDataBlock"},
14};
15 15
16//////////////////////////////////////////////////////////////////////////////////////////////////// 16////////////////////////////////////////////////////////////////////////////////////////////////////
17// Interface class 17// Interface class
18 18
19Interface::Interface() { 19Interface::Interface() {
20 //Register(FunctionTable); 20 Register(FunctionTable);
21} 21}
22 22
23} // namespace 23} // namespace
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 7ae4859a7..06be9940e 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -10,10 +10,6 @@
10#include "core/hle/service/am/am_net.h" 10#include "core/hle/service/am/am_net.h"
11#include "core/hle/service/am/am_sys.h" 11#include "core/hle/service/am/am_sys.h"
12 12
13#include "core/hle/hle.h"
14#include "core/hle/kernel/event.h"
15#include "core/hle/kernel/shared_memory.h"
16
17namespace Service { 13namespace Service {
18namespace AM { 14namespace AM {
19 15
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h
index 0b78f5393..15e63bc7b 100644
--- a/src/core/hle/service/am/am.h
+++ b/src/core/hle/service/am/am.h
@@ -4,10 +4,10 @@
4 4
5#pragma once 5#pragma once
6 6
7#include "core/hle/kernel/kernel.h"
8#include "core/hle/service/service.h"
9
10namespace Service { 7namespace Service {
8
9class Interface;
10
11namespace AM { 11namespace AM {
12 12
13/** 13/**
diff --git a/src/core/hle/service/am/am_app.cpp b/src/core/hle/service/am/am_app.cpp
index f40a87cb4..16c76a1eb 100644
--- a/src/core/hle/service/am/am_app.cpp
+++ b/src/core/hle/service/am/am_app.cpp
@@ -2,7 +2,6 @@
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 "core/hle/hle.h"
6#include "core/hle/service/am/am.h" 5#include "core/hle/service/am/am.h"
7#include "core/hle/service/am/am_app.h" 6#include "core/hle/service/am/am_app.h"
8 7
diff --git a/src/core/hle/service/am/am_net.cpp b/src/core/hle/service/am/am_net.cpp
index aa391f3b2..065e04118 100644
--- a/src/core/hle/service/am/am_net.cpp
+++ b/src/core/hle/service/am/am_net.cpp
@@ -2,7 +2,6 @@
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 "core/hle/hle.h"
6#include "core/hle/service/am/am.h" 5#include "core/hle/service/am/am.h"
7#include "core/hle/service/am/am_net.h" 6#include "core/hle/service/am/am_net.h"
8 7
@@ -10,6 +9,36 @@ namespace Service {
10namespace AM { 9namespace AM {
11 10
12const Interface::FunctionInfo FunctionTable[] = { 11const Interface::FunctionInfo FunctionTable[] = {
12 {0x00010040, TitleIDListGetTotal, "TitleIDListGetTotal"},
13 {0x00020082, GetTitleIDList, "GetTitleIDList"},
14 {0x00030084, nullptr, "ListTitles"},
15 {0x000400C0, nullptr, "DeleteApplicationTitle"},
16 {0x000500C0, nullptr, "GetTitleProductCode"},
17 {0x00080000, nullptr, "TitleIDListGetTotal3"},
18 {0x00090082, nullptr, "GetTitleIDList3"},
19 {0x000A0000, nullptr, "GetDeviceID"},
20 {0x000D0084, nullptr, "ListTitles2"},
21 {0x00140040, nullptr, "FinishInstallToMedia"},
22 {0x00180080, nullptr, "InitializeTitleDatabase"},
23 {0x00190040, nullptr, "ReloadDBS"},
24 {0x001A00C0, nullptr, "GetDSiWareExportSize"},
25 {0x001B0144, nullptr, "ExportDSiWare"},
26 {0x001C0084, nullptr, "ImportDSiWare"},
27 {0x00230080, nullptr, "TitleIDListGetTotal2"},
28 {0x002400C2, nullptr, "GetTitleIDList2"},
29 {0x04010080, nullptr, "InstallFIRM"},
30 {0x04020040, nullptr, "StartInstallCIADB0"},
31 {0x04030000, nullptr, "StartInstallCIADB1"},
32 {0x04040002, nullptr, "AbortCIAInstall"},
33 {0x04050002, nullptr, "CloseCIAFinalizeInstall"},
34 {0x04060002, nullptr, "CloseCIA"},
35 {0x040700C2, nullptr, "FinalizeTitlesInstall"},
36 {0x04080042, nullptr, "GetCiaFileInfo"},
37 {0x040E00C2, nullptr, "InstallTitlesFinish"},
38 {0x040F0000, nullptr, "InstallNATIVEFIRM"},
39 {0x041000C0, nullptr, "DeleteTitle"},
40 {0x04120000, nullptr, "Initialize"},
41 {0x041700C0, nullptr, "MigrateAGBtoSAV"},
13 {0x08010000, nullptr, "OpenTicket"}, 42 {0x08010000, nullptr, "OpenTicket"},
14 {0x08020002, nullptr, "TicketAbortInstall"}, 43 {0x08020002, nullptr, "TicketAbortInstall"},
15 {0x08030002, nullptr, "TicketFinalizeInstall"}, 44 {0x08030002, nullptr, "TicketFinalizeInstall"},
diff --git a/src/core/hle/service/am/am_sys.cpp b/src/core/hle/service/am/am_sys.cpp
index 864fc14df..e38812297 100644
--- a/src/core/hle/service/am/am_sys.cpp
+++ b/src/core/hle/service/am/am_sys.cpp
@@ -2,7 +2,6 @@
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 "core/hle/hle.h"
6#include "core/hle/service/am/am.h" 5#include "core/hle/service/am/am.h"
7#include "core/hle/service/am/am_sys.h" 6#include "core/hle/service/am/am_sys.h"
8 7
@@ -12,6 +11,21 @@ namespace AM {
12const Interface::FunctionInfo FunctionTable[] = { 11const Interface::FunctionInfo FunctionTable[] = {
13 {0x00010040, TitleIDListGetTotal, "TitleIDListGetTotal"}, 12 {0x00010040, TitleIDListGetTotal, "TitleIDListGetTotal"},
14 {0x00020082, GetTitleIDList, "GetTitleIDList"}, 13 {0x00020082, GetTitleIDList, "GetTitleIDList"},
14 {0x00030084, nullptr, "ListTitles"},
15 {0x000400C0, nullptr, "DeleteApplicationTitle"},
16 {0x000500C0, nullptr, "GetTitleProductCode"},
17 {0x00080000, nullptr, "TitleIDListGetTotal3"},
18 {0x00090082, nullptr, "GetTitleIDList3"},
19 {0x000A0000, nullptr, "GetDeviceID"},
20 {0x000D0084, nullptr, "ListTitles2"},
21 {0x00140040, nullptr, "FinishInstallToMedia"},
22 {0x00180080, nullptr, "InitializeTitleDatabase"},
23 {0x00190040, nullptr, "ReloadDBS"},
24 {0x001A00C0, nullptr, "GetDSiWareExportSize"},
25 {0x001B0144, nullptr, "ExportDSiWare"},
26 {0x001C0084, nullptr, "ImportDSiWare"},
27 {0x00230080, nullptr, "TitleIDListGetTotal2"},
28 {0x002400C2, nullptr, "GetTitleIDList2"}
15}; 29};
16 30
17AM_SYS_Interface::AM_SYS_Interface() { 31AM_SYS_Interface::AM_SYS_Interface() {
diff --git a/src/core/hle/service/am/am_u.cpp b/src/core/hle/service/am/am_u.cpp
index 6bf84b36b..c0392b754 100644
--- a/src/core/hle/service/am/am_u.cpp
+++ b/src/core/hle/service/am/am_u.cpp
@@ -2,7 +2,6 @@
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 "core/hle/hle.h"
6#include "core/hle/service/am/am.h" 5#include "core/hle/service/am/am.h"
7#include "core/hle/service/am/am_u.h" 6#include "core/hle/service/am/am_u.h"
8 7
@@ -12,6 +11,34 @@ namespace AM {
12const Interface::FunctionInfo FunctionTable[] = { 11const Interface::FunctionInfo FunctionTable[] = {
13 {0x00010040, TitleIDListGetTotal, "TitleIDListGetTotal"}, 12 {0x00010040, TitleIDListGetTotal, "TitleIDListGetTotal"},
14 {0x00020082, GetTitleIDList, "GetTitleIDList"}, 13 {0x00020082, GetTitleIDList, "GetTitleIDList"},
14 {0x00030084, nullptr, "ListTitles"},
15 {0x000400C0, nullptr, "DeleteApplicationTitle"},
16 {0x000500C0, nullptr, "GetTitleProductCode"},
17 {0x00080000, nullptr, "TitleIDListGetTotal3"},
18 {0x00090082, nullptr, "GetTitleIDList3"},
19 {0x000A0000, nullptr, "GetDeviceID"},
20 {0x000D0084, nullptr, "ListTitles2"},
21 {0x00140040, nullptr, "FinishInstallToMedia"},
22 {0x00180080, nullptr, "InitializeTitleDatabase"},
23 {0x00190040, nullptr, "ReloadDBS"},
24 {0x001A00C0, nullptr, "GetDSiWareExportSize"},
25 {0x001B0144, nullptr, "ExportDSiWare"},
26 {0x001C0084, nullptr, "ImportDSiWare"},
27 {0x00230080, nullptr, "TitleIDListGetTotal2"},
28 {0x002400C2, nullptr, "GetTitleIDList2"},
29 {0x04010080, nullptr, "InstallFIRM"},
30 {0x04020040, nullptr, "StartInstallCIADB0"},
31 {0x04030000, nullptr, "StartInstallCIADB1"},
32 {0x04040002, nullptr, "AbortCIAInstall"},
33 {0x04050002, nullptr, "CloseCIAFinalizeInstall"},
34 {0x04060002, nullptr, "CloseCIA"},
35 {0x040700C2, nullptr, "FinalizeTitlesInstall"},
36 {0x04080042, nullptr, "GetCiaFileInfo"},
37 {0x040E00C2, nullptr, "InstallTitlesFinish"},
38 {0x040F0000, nullptr, "InstallNATIVEFIRM"},
39 {0x041000C0, nullptr, "DeleteTitle"},
40 {0x04120000, nullptr, "Initialize"},
41 {0x041700C0, nullptr, "MigrateAGBtoSAV"}
15}; 42};
16 43
17AM_U_Interface::AM_U_Interface() { 44AM_U_Interface::AM_U_Interface() {
diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp
index feb579778..98c72fc32 100644
--- a/src/core/hle/service/apt/apt.cpp
+++ b/src/core/hle/service/apt/apt.cpp
@@ -14,12 +14,10 @@
14#include "core/hle/service/apt/apt_u.h" 14#include "core/hle/service/apt/apt_u.h"
15#include "core/hle/service/fs/archive.h" 15#include "core/hle/service/fs/archive.h"
16 16
17#include "core/hle/hle.h"
18#include "core/hle/kernel/event.h" 17#include "core/hle/kernel/event.h"
19#include "core/hle/kernel/mutex.h" 18#include "core/hle/kernel/mutex.h"
20#include "core/hle/kernel/process.h" 19#include "core/hle/kernel/process.h"
21#include "core/hle/kernel/shared_memory.h" 20#include "core/hle/kernel/shared_memory.h"
22#include "core/hle/kernel/thread.h"
23 21
24namespace Service { 22namespace Service {
25namespace APT { 23namespace APT {
diff --git a/src/core/hle/service/apt/apt_a.cpp b/src/core/hle/service/apt/apt_a.cpp
index 22800c56f..0c6a77305 100644
--- a/src/core/hle/service/apt/apt_a.cpp
+++ b/src/core/hle/service/apt/apt_a.cpp
@@ -2,7 +2,6 @@
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 "core/hle/hle.h"
6#include "core/hle/service/apt/apt.h" 5#include "core/hle/service/apt/apt.h"
7#include "core/hle/service/apt/apt_a.h" 6#include "core/hle/service/apt/apt_a.h"
8 7
diff --git a/src/core/hle/service/apt/apt_s.cpp b/src/core/hle/service/apt/apt_s.cpp
index 3ac6ff94f..7f6e81a63 100644
--- a/src/core/hle/service/apt/apt_s.cpp
+++ b/src/core/hle/service/apt/apt_s.cpp
@@ -2,8 +2,6 @@
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
6#include "core/hle/hle.h"
7#include "core/hle/service/apt/apt.h" 5#include "core/hle/service/apt/apt.h"
8#include "core/hle/service/apt/apt_s.h" 6#include "core/hle/service/apt/apt_s.h"
9 7
@@ -91,6 +89,12 @@ const Interface::FunctionInfo FunctionTable[] = {
91 {0x004E0000, nullptr, "HardwareResetAsync"}, 89 {0x004E0000, nullptr, "HardwareResetAsync"},
92 {0x004F0080, nullptr, "SetApplicationCpuTimeLimit"}, 90 {0x004F0080, nullptr, "SetApplicationCpuTimeLimit"},
93 {0x00500040, nullptr, "GetApplicationCpuTimeLimit"}, 91 {0x00500040, nullptr, "GetApplicationCpuTimeLimit"},
92 {0x00510080, nullptr, "GetStartupArgument"},
93 {0x00520104, nullptr, "Wrap1"},
94 {0x00530104, nullptr, "Unwrap1"},
95 {0x00580002, nullptr, "GetProgramID"},
96 {0x01010000, nullptr, "CheckNew3DSApp"},
97 {0x01020000, nullptr, "CheckNew3DS"}
94}; 98};
95 99
96APT_S_Interface::APT_S_Interface() { 100APT_S_Interface::APT_S_Interface() {
diff --git a/src/core/hle/service/apt/apt_u.cpp b/src/core/hle/service/apt/apt_u.cpp
index 2e9d1f4b4..b13b51549 100644
--- a/src/core/hle/service/apt/apt_u.cpp
+++ b/src/core/hle/service/apt/apt_u.cpp
@@ -2,9 +2,6 @@
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
6#include "common/file_util.h"
7
8#include "core/hle/service/apt/apt.h" 5#include "core/hle/service/apt/apt.h"
9#include "core/hle/service/apt/apt_u.h" 6#include "core/hle/service/apt/apt_u.h"
10 7
@@ -92,6 +89,12 @@ const Interface::FunctionInfo FunctionTable[] = {
92 {0x004E0000, nullptr, "HardwareResetAsync"}, 89 {0x004E0000, nullptr, "HardwareResetAsync"},
93 {0x004F0080, SetAppCpuTimeLimit, "SetAppCpuTimeLimit"}, 90 {0x004F0080, SetAppCpuTimeLimit, "SetAppCpuTimeLimit"},
94 {0x00500040, GetAppCpuTimeLimit, "GetAppCpuTimeLimit"}, 91 {0x00500040, GetAppCpuTimeLimit, "GetAppCpuTimeLimit"},
92 {0x00510080, nullptr, "GetStartupArgument"},
93 {0x00520104, nullptr, "Wrap1"},
94 {0x00530104, nullptr, "Unwrap1"},
95 {0x00580002, nullptr, "GetProgramID"},
96 {0x01010000, nullptr, "CheckNew3DSApp"},
97 {0x01020000, nullptr, "CheckNew3DS"}
95}; 98};
96 99
97APT_U_Interface::APT_U_Interface() { 100APT_U_Interface::APT_U_Interface() {
diff --git a/src/core/hle/service/boss/boss.cpp b/src/core/hle/service/boss/boss.cpp
index d38140f19..419ec976e 100644
--- a/src/core/hle/service/boss/boss.cpp
+++ b/src/core/hle/service/boss/boss.cpp
@@ -7,10 +7,6 @@
7#include "core/hle/service/boss/boss_p.h" 7#include "core/hle/service/boss/boss_p.h"
8#include "core/hle/service/boss/boss_u.h" 8#include "core/hle/service/boss/boss_u.h"
9 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 { 10namespace Service {
15namespace BOSS { 11namespace BOSS {
16 12
diff --git a/src/core/hle/service/boss/boss.h b/src/core/hle/service/boss/boss.h
index a6942ada6..d3b5d7101 100644
--- a/src/core/hle/service/boss/boss.h
+++ b/src/core/hle/service/boss/boss.h
@@ -4,9 +4,6 @@
4 4
5#pragma once 5#pragma once
6 6
7#include "core/hle/kernel/kernel.h"
8#include "core/hle/service/service.h"
9
10namespace Service { 7namespace Service {
11namespace BOSS { 8namespace BOSS {
12 9
diff --git a/src/core/hle/service/boss/boss_p.cpp b/src/core/hle/service/boss/boss_p.cpp
index 089f5f186..c498abe4e 100644
--- a/src/core/hle/service/boss/boss_p.cpp
+++ b/src/core/hle/service/boss/boss_p.cpp
@@ -2,8 +2,6 @@
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 "core/hle/hle.h"
6#include "core/hle/service/boss/boss.h"
7#include "core/hle/service/boss/boss_p.h" 5#include "core/hle/service/boss/boss_p.h"
8 6
9namespace Service { 7namespace Service {
diff --git a/src/core/hle/service/boss/boss_u.cpp b/src/core/hle/service/boss/boss_u.cpp
index ed978b963..d59babe71 100644
--- a/src/core/hle/service/boss/boss_u.cpp
+++ b/src/core/hle/service/boss/boss_u.cpp
@@ -2,8 +2,6 @@
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 "core/hle/hle.h"
6#include "core/hle/service/boss/boss.h"
7#include "core/hle/service/boss/boss_u.h" 5#include "core/hle/service/boss/boss_u.h"
8 6
9namespace Service { 7namespace Service {
@@ -11,6 +9,9 @@ namespace BOSS {
11 9
12const Interface::FunctionInfo FunctionTable[] = { 10const Interface::FunctionInfo FunctionTable[] = {
13 {0x00020100, nullptr, "GetStorageInfo"}, 11 {0x00020100, nullptr, "GetStorageInfo"},
12 {0x000C0082, nullptr, "UnregisterTask"},
13 {0x001E0042, nullptr, "CancelTask"},
14 {0x00330042, nullptr, "StartBgImmediate"},
14}; 15};
15 16
16BOSS_U_Interface::BOSS_U_Interface() { 17BOSS_U_Interface::BOSS_U_Interface() {
diff --git a/src/core/hle/service/cam/cam.cpp b/src/core/hle/service/cam/cam.cpp
index 4f34b699b..4d714037f 100644
--- a/src/core/hle/service/cam/cam.cpp
+++ b/src/core/hle/service/cam/cam.cpp
@@ -4,20 +4,287 @@
4 4
5#include "common/logging/log.h" 5#include "common/logging/log.h"
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/kernel/event.h"
8#include "core/hle/service/cam/cam.h" 8#include "core/hle/service/cam/cam.h"
9#include "core/hle/service/cam/cam_c.h" 9#include "core/hle/service/cam/cam_c.h"
10#include "core/hle/service/cam/cam_q.h" 10#include "core/hle/service/cam/cam_q.h"
11#include "core/hle/service/cam/cam_s.h" 11#include "core/hle/service/cam/cam_s.h"
12#include "core/hle/service/cam/cam_u.h" 12#include "core/hle/service/cam/cam_u.h"
13 13#include "core/hle/service/service.h"
14#include "core/hle/kernel/event.h"
15#include "core/hle/kernel/shared_memory.h"
16#include "core/hle/hle.h"
17 14
18namespace Service { 15namespace Service {
19namespace CAM { 16namespace CAM {
20 17
18static const u32 TRANSFER_BYTES = 5 * 1024;
19
20static Kernel::SharedPtr<Kernel::Event> completion_event_cam1;
21static Kernel::SharedPtr<Kernel::Event> completion_event_cam2;
22static Kernel::SharedPtr<Kernel::Event> interrupt_error_event;
23static Kernel::SharedPtr<Kernel::Event> vsync_interrupt_error_event;
24
25void StartCapture(Service::Interface* self) {
26 u32* cmd_buff = Kernel::GetCommandBuffer();
27
28 u8 port = cmd_buff[1] & 0xFF;
29
30 cmd_buff[0] = IPC::MakeHeader(0x1, 1, 0);
31 cmd_buff[1] = RESULT_SUCCESS.raw;
32
33 LOG_WARNING(Service_CAM, "(STUBBED) called, port=%d", port);
34}
35
36void StopCapture(Service::Interface* self) {
37 u32* cmd_buff = Kernel::GetCommandBuffer();
38
39 u8 port = cmd_buff[1] & 0xFF;
40
41 cmd_buff[0] = IPC::MakeHeader(0x2, 1, 0);
42 cmd_buff[1] = RESULT_SUCCESS.raw;
43
44 LOG_WARNING(Service_CAM, "(STUBBED) called, port=%d", port);
45}
46
47void GetVsyncInterruptEvent(Service::Interface* self) {
48 u32* cmd_buff = Kernel::GetCommandBuffer();
49
50 u8 port = cmd_buff[1] & 0xFF;
51
52 cmd_buff[0] = IPC::MakeHeader(0x5, 1, 2);
53 cmd_buff[1] = RESULT_SUCCESS.raw;
54 cmd_buff[2] = IPC::MoveHandleDesc();
55 cmd_buff[3] = Kernel::g_handle_table.Create(vsync_interrupt_error_event).MoveFrom();
56
57 LOG_WARNING(Service_CAM, "(STUBBED) called, port=%d", port);
58}
59
60void GetBufferErrorInterruptEvent(Service::Interface* self) {
61 u32* cmd_buff = Kernel::GetCommandBuffer();
62
63 u8 port = cmd_buff[1] & 0xFF;
64
65 cmd_buff[0] = IPC::MakeHeader(0x6, 1, 2);
66 cmd_buff[1] = RESULT_SUCCESS.raw;
67 cmd_buff[2] = IPC::MoveHandleDesc();
68 cmd_buff[3] = Kernel::g_handle_table.Create(interrupt_error_event).MoveFrom();
69
70 LOG_WARNING(Service_CAM, "(STUBBED) called, port=%d", port);
71}
72
73void SetReceiving(Service::Interface* self) {
74 u32* cmd_buff = Kernel::GetCommandBuffer();
75
76 VAddr dest = cmd_buff[1];
77 u8 port = cmd_buff[2] & 0xFF;
78 u32 image_size = cmd_buff[3];
79 u16 trans_unit = cmd_buff[4] & 0xFFFF;
80
81 Kernel::Event* completion_event = (Port)port == Port::Cam2 ?
82 completion_event_cam2.get() : completion_event_cam1.get();
83
84 completion_event->Signal();
85
86 cmd_buff[0] = IPC::MakeHeader(0x7, 1, 2);
87 cmd_buff[1] = RESULT_SUCCESS.raw;
88 cmd_buff[2] = IPC::MoveHandleDesc();
89 cmd_buff[3] = Kernel::g_handle_table.Create(completion_event).MoveFrom();
90
91 LOG_WARNING(Service_CAM, "(STUBBED) called, addr=0x%X, port=%d, image_size=%d, trans_unit=%d",
92 dest, port, image_size, trans_unit);
93}
94
95void SetTransferLines(Service::Interface* self) {
96 u32* cmd_buff = Kernel::GetCommandBuffer();
97
98 u8 port = cmd_buff[1] & 0xFF;
99 u16 transfer_lines = cmd_buff[2] & 0xFFFF;
100 u16 width = cmd_buff[3] & 0xFFFF;
101 u16 height = cmd_buff[4] & 0xFFFF;
102
103 cmd_buff[0] = IPC::MakeHeader(0x9, 1, 0);
104 cmd_buff[1] = RESULT_SUCCESS.raw;
105
106 LOG_WARNING(Service_CAM, "(STUBBED) called, port=%d, lines=%d, width=%d, height=%d",
107 port, transfer_lines, width, height);
108}
109
110void GetMaxLines(Service::Interface* self) {
111 u32* cmd_buff = Kernel::GetCommandBuffer();
112
113 u16 width = cmd_buff[1] & 0xFFFF;
114 u16 height = cmd_buff[2] & 0xFFFF;
115
116 cmd_buff[0] = IPC::MakeHeader(0xA, 2, 0);
117 cmd_buff[1] = RESULT_SUCCESS.raw;
118 cmd_buff[2] = TRANSFER_BYTES / (2 * width);
119
120 LOG_WARNING(Service_CAM, "(STUBBED) called, width=%d, height=%d, lines = %d",
121 width, height, cmd_buff[2]);
122}
123
124void GetTransferBytes(Service::Interface* self) {
125 u32* cmd_buff = Kernel::GetCommandBuffer();
126
127 u8 port = cmd_buff[1] & 0xFF;
128
129 cmd_buff[0] = IPC::MakeHeader(0xC, 2, 0);
130 cmd_buff[1] = RESULT_SUCCESS.raw;
131 cmd_buff[2] = TRANSFER_BYTES;
132
133 LOG_WARNING(Service_CAM, "(STUBBED) called, port=%d", port);
134}
135
136void SetTrimming(Service::Interface* self) {
137 u32* cmd_buff = Kernel::GetCommandBuffer();
138
139 u8 port = cmd_buff[1] & 0xFF;
140 bool trim = (cmd_buff[2] & 0xFF) != 0;
141
142 cmd_buff[0] = IPC::MakeHeader(0xE, 1, 0);
143 cmd_buff[1] = RESULT_SUCCESS.raw;
144
145 LOG_WARNING(Service_CAM, "(STUBBED) called, port=%d, trim=%d", port, trim);
146}
147
148void SetTrimmingParamsCenter(Service::Interface* self) {
149 u32* cmd_buff = Kernel::GetCommandBuffer();
150
151 u8 port = cmd_buff[1] & 0xFF;
152 s16 trimW = cmd_buff[2] & 0xFFFF;
153 s16 trimH = cmd_buff[3] & 0xFFFF;
154 s16 camW = cmd_buff[4] & 0xFFFF;
155 s16 camH = cmd_buff[5] & 0xFFFF;
156
157 cmd_buff[0] = IPC::MakeHeader(0x12, 1, 0);
158 cmd_buff[1] = RESULT_SUCCESS.raw;
159
160 LOG_WARNING(Service_CAM, "(STUBBED) called, port=%d, trimW=%d, trimH=%d, camW=%d, camH=%d",
161 port, trimW, trimH, camW, camH);
162}
163
164void Activate(Service::Interface* self) {
165 u32* cmd_buff = Kernel::GetCommandBuffer();
166
167 u8 cam_select = cmd_buff[1] & 0xFF;
168
169 cmd_buff[0] = IPC::MakeHeader(0x13, 1, 0);
170 cmd_buff[1] = RESULT_SUCCESS.raw;
171
172 LOG_WARNING(Service_CAM, "(STUBBED) called, cam_select=%d",
173 cam_select);
174}
175
176void FlipImage(Service::Interface* self) {
177 u32* cmd_buff = Kernel::GetCommandBuffer();
178
179 u8 cam_select = cmd_buff[1] & 0xFF;
180 u8 flip = cmd_buff[2] & 0xFF;
181 u8 context = cmd_buff[3] & 0xFF;
182
183 cmd_buff[0] = IPC::MakeHeader(0x1D, 1, 0);
184 cmd_buff[1] = RESULT_SUCCESS.raw;
185
186 LOG_WARNING(Service_CAM, "(STUBBED) called, cam_select=%d, flip=%d, context=%d",
187 cam_select, flip, context);
188}
189
190void SetSize(Service::Interface* self) {
191 u32* cmd_buff = Kernel::GetCommandBuffer();
192
193 u8 cam_select = cmd_buff[1] & 0xFF;
194 u8 size = cmd_buff[2] & 0xFF;
195 u8 context = cmd_buff[3] & 0xFF;
196
197 cmd_buff[0] = IPC::MakeHeader(0x1F, 1, 0);
198 cmd_buff[1] = RESULT_SUCCESS.raw;
199
200 LOG_WARNING(Service_CAM, "(STUBBED) called, cam_select=%d, size=%d, context=%d",
201 cam_select, size, context);
202}
203
204void SetFrameRate(Service::Interface* self) {
205 u32* cmd_buff = Kernel::GetCommandBuffer();
206
207 u8 cam_select = cmd_buff[1] & 0xFF;
208 u8 frame_rate = cmd_buff[2] & 0xFF;
209
210 cmd_buff[0] = IPC::MakeHeader(0x20, 1, 0);
211 cmd_buff[1] = RESULT_SUCCESS.raw;
212
213 LOG_WARNING(Service_CAM, "(STUBBED) called, cam_select=%d, frame_rate=%d",
214 cam_select, frame_rate);
215}
216
217void GetStereoCameraCalibrationData(Service::Interface* self) {
218 u32* cmd_buff = Kernel::GetCommandBuffer();
219
220 // Default values taken from yuriks' 3DS. Valid data is required here or games using the
221 // calibration get stuck in an infinite CPU loop.
222 StereoCameraCalibrationData data = {};
223 data.isValidRotationXY = 0;
224 data.scale = 1.001776f;
225 data.rotationZ = 0.008322907f;
226 data.translationX = -87.70484f;
227 data.translationY = -7.640977f;
228 data.rotationX = 0.0f;
229 data.rotationY = 0.0f;
230 data.angleOfViewRight = 64.66875f;
231 data.angleOfViewLeft = 64.76067f;
232 data.distanceToChart = 250.0f;
233 data.distanceCameras = 35.0f;
234 data.imageWidth = 640;
235 data.imageHeight = 480;
236
237 cmd_buff[0] = IPC::MakeHeader(0x2B, 17, 0);
238 cmd_buff[1] = RESULT_SUCCESS.raw;
239 memcpy(&cmd_buff[2], &data, sizeof(data));
240
241 LOG_TRACE(Service_CAM, "called");
242}
243
244void GetSuitableY2rStandardCoefficient(Service::Interface* self) {
245 u32* cmd_buff = Kernel::GetCommandBuffer();
246
247 cmd_buff[0] = IPC::MakeHeader(0x36, 2, 0);
248 cmd_buff[1] = RESULT_SUCCESS.raw;
249 cmd_buff[2] = 0;
250
251 LOG_WARNING(Service_CAM, "(STUBBED) called");
252}
253
254void PlayShutterSound(Service::Interface* self) {
255 u32* cmd_buff = Kernel::GetCommandBuffer();
256
257 u8 sound_id = cmd_buff[1] & 0xFF;
258
259 cmd_buff[0] = IPC::MakeHeader(0x38, 1, 0);
260 cmd_buff[1] = RESULT_SUCCESS.raw;
261
262 LOG_WARNING(Service_CAM, "(STUBBED) called, sound_id=%d", sound_id);
263}
264
265void DriverInitialize(Service::Interface* self) {
266 u32* cmd_buff = Kernel::GetCommandBuffer();
267
268 completion_event_cam1->Clear();
269 completion_event_cam2->Clear();
270 interrupt_error_event->Clear();
271 vsync_interrupt_error_event->Clear();
272
273 cmd_buff[0] = IPC::MakeHeader(0x39, 1, 0);
274 cmd_buff[1] = RESULT_SUCCESS.raw;
275
276 LOG_WARNING(Service_CAM, "(STUBBED) called");
277}
278
279void DriverFinalize(Service::Interface* self) {
280 u32* cmd_buff = Kernel::GetCommandBuffer();
281
282 cmd_buff[0] = IPC::MakeHeader(0x3A, 1, 0);
283 cmd_buff[1] = RESULT_SUCCESS.raw;
284
285 LOG_WARNING(Service_CAM, "(STUBBED) called");
286}
287
21void Init() { 288void Init() {
22 using namespace Kernel; 289 using namespace Kernel;
23 290
@@ -25,9 +292,18 @@ void Init() {
25 AddService(new CAM_Q_Interface); 292 AddService(new CAM_Q_Interface);
26 AddService(new CAM_S_Interface); 293 AddService(new CAM_S_Interface);
27 AddService(new CAM_U_Interface); 294 AddService(new CAM_U_Interface);
295
296 completion_event_cam1 = Kernel::Event::Create(RESETTYPE_ONESHOT, "CAM_U::completion_event_cam1");
297 completion_event_cam2 = Kernel::Event::Create(RESETTYPE_ONESHOT, "CAM_U::completion_event_cam2");
298 interrupt_error_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "CAM_U::interrupt_error_event");
299 vsync_interrupt_error_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "CAM_U::vsync_interrupt_error_event");
28} 300}
29 301
30void Shutdown() { 302void Shutdown() {
303 completion_event_cam1 = nullptr;
304 completion_event_cam2 = nullptr;
305 interrupt_error_event = nullptr;
306 vsync_interrupt_error_event = nullptr;
31} 307}
32 308
33} // namespace CAM 309} // namespace CAM
diff --git a/src/core/hle/service/cam/cam.h b/src/core/hle/service/cam/cam.h
index edd524841..2f4923728 100644
--- a/src/core/hle/service/cam/cam.h
+++ b/src/core/hle/service/cam/cam.h
@@ -4,12 +4,429 @@
4 4
5#pragma once 5#pragma once
6 6
7#include "common/common_funcs.h"
8#include "common/common_types.h"
9#include "common/swap.h"
10
7#include "core/hle/kernel/kernel.h" 11#include "core/hle/kernel/kernel.h"
8#include "core/hle/service/service.h" 12#include "core/hle/service/service.h"
9 13
10namespace Service { 14namespace Service {
11namespace CAM { 15namespace CAM {
12 16
17enum class Port : u8 {
18 None = 0,
19 Cam1 = 1,
20 Cam2 = 2,
21 Both = Cam1 | Cam2
22};
23
24enum class CameraSelect : u8 {
25 None = 0,
26 Out1 = 1,
27 In1 = 2,
28 Out2 = 4,
29 In1Out1 = Out1 | In1,
30 Out1Out2 = Out1 | Out2,
31 In1Out2 = In1 | Out2,
32 All = Out1 | In1 | Out2
33};
34
35enum class Effect : u8 {
36 None = 0,
37 Mono = 1,
38 Sepia = 2,
39 Negative = 3,
40 Negafilm = 4,
41 Sepia01 = 5
42};
43
44enum class Context : u8 {
45 None = 0,
46 A = 1,
47 B = 2,
48 Both = A | B
49};
50
51enum class Flip : u8 {
52 None = 0,
53 Horizontal = 1,
54 Vertical = 2,
55 Reverse = 3
56};
57
58enum class Size : u8 {
59 VGA = 0,
60 QVGA = 1,
61 QQVGA = 2,
62 CIF = 3,
63 QCIF = 4,
64 DS_LCD = 5,
65 DS_LCDx4 = 6,
66 CTR_TOP_LCD = 7,
67 CTR_BOTTOM_LCD = QVGA
68};
69
70enum class FrameRate : u8 {
71 Rate_15 = 0,
72 Rate_15_To_5 = 1,
73 Rate_15_To_2 = 2,
74 Rate_10 = 3,
75 Rate_8_5 = 4,
76 Rate_5 = 5,
77 Rate_20 = 6,
78 Rate_20_To_5 = 7,
79 Rate_30 = 8,
80 Rate_30_To_5 = 9,
81 Rate_15_To_10 = 10,
82 Rate_20_To_10 = 11,
83 Rate_30_To_10 = 12
84};
85
86enum class ShutterSoundType : u8 {
87 Normal = 0,
88 Movie = 1,
89 MovieEnd = 2
90};
91
92enum class WhiteBalance : u8 {
93 BalanceAuto = 0,
94 Balance3200K = 1,
95 Balance4150K = 2,
96 Balance5200K = 3,
97 Balance6000K = 4,
98 Balance7000K = 5,
99 BalanceMax = 6,
100 BalanceNormal = BalanceAuto,
101 BalanceTungsten = Balance3200K,
102 BalanceWhiteFluorescentLight = Balance4150K,
103 BalanceDaylight = Balance5200K,
104 BalanceCloudy = Balance6000K,
105 BalanceHorizon = Balance6000K,
106 BalanceShade = Balance7000K
107};
108
109enum class PhotoMode : u8 {
110 Normal = 0,
111 Portrait = 1,
112 Landscape = 2,
113 Nightview = 3,
114 Letter0 = 4
115};
116
117enum class LensCorrection : u8 {
118 Off = 0,
119 On70 = 1,
120 On90 = 2,
121 Dark = Off,
122 Normal = On70,
123 Bright = On90
124};
125
126enum class Contrast : u8 {
127 Pattern01 = 1,
128 Pattern02 = 2,
129 Pattern03 = 3,
130 Pattern04 = 4,
131 Pattern05 = 5,
132 Pattern06 = 6,
133 Pattern07 = 7,
134 Pattern08 = 8,
135 Pattern09 = 9,
136 Pattern10 = 10,
137 Pattern11 = 11,
138 Low = Pattern05,
139 Normal = Pattern06,
140 High = Pattern07
141};
142
143enum class OutputFormat : u8 {
144 YUV422 = 0,
145 RGB565 = 1
146};
147
148/// Stereo camera calibration data.
149struct StereoCameraCalibrationData {
150 u8 isValidRotationXY; ///< Bool indicating whether the X and Y rotation data is valid.
151 INSERT_PADDING_BYTES(3);
152 float_le scale; ///< Scale to match the left camera image with the right.
153 float_le rotationZ; ///< Z axis rotation to match the left camera image with the right.
154 float_le translationX; ///< X axis translation to match the left camera image with the right.
155 float_le translationY; ///< Y axis translation to match the left camera image with the right.
156 float_le rotationX; ///< X axis rotation to match the left camera image with the right.
157 float_le rotationY; ///< Y axis rotation to match the left camera image with the right.
158 float_le angleOfViewRight; ///< Right camera angle of view.
159 float_le angleOfViewLeft; ///< Left camera angle of view.
160 float_le distanceToChart; ///< Distance between cameras and measurement chart.
161 float_le distanceCameras; ///< Distance between left and right cameras.
162 s16_le imageWidth; ///< Image width.
163 s16_le imageHeight; ///< Image height.
164 INSERT_PADDING_BYTES(16);
165};
166static_assert(sizeof(StereoCameraCalibrationData) == 64, "StereoCameraCalibrationData structure size is wrong");
167
168struct PackageParameterCameraSelect {
169 CameraSelect camera;
170 s8 exposure;
171 WhiteBalance white_balance;
172 s8 sharpness;
173 bool auto_exposure;
174 bool auto_white_balance;
175 FrameRate frame_rate;
176 PhotoMode photo_mode;
177 Contrast contrast;
178 LensCorrection lens_correction;
179 bool noise_filter;
180 u8 padding;
181 s16 auto_exposure_window_x;
182 s16 auto_exposure_window_y;
183 s16 auto_exposure_window_width;
184 s16 auto_exposure_window_height;
185 s16 auto_white_balance_window_x;
186 s16 auto_white_balance_window_y;
187 s16 auto_white_balance_window_width;
188 s16 auto_white_balance_window_height;
189};
190
191static_assert(sizeof(PackageParameterCameraSelect) == 28, "PackageParameterCameraSelect structure size is wrong");
192
193/**
194 * Unknown
195 * Inputs:
196 * 0: 0x00010040
197 * 1: u8 Camera port (`Port` enum)
198 * Outputs:
199 * 0: 0x00010040
200 * 1: ResultCode
201 */
202void StartCapture(Service::Interface* self);
203
204/**
205 * Unknown
206 * Inputs:
207 * 0: 0x00020040
208 * 1: u8 Camera port (`Port` enum)
209 * Outputs:
210 * 0: 0x00020040
211 * 1: ResultCode
212 */
213void StopCapture(Service::Interface* self);
214
215/**
216 * Unknown
217 * Inputs:
218 * 0: 0x00050040
219 * 1: u8 Camera port (`Port` enum)
220 * Outputs:
221 * 0: 0x00050042
222 * 1: ResultCode
223 * 2: Descriptor: Handle
224 * 3: Event handle
225 */
226void GetVsyncInterruptEvent(Service::Interface* self);
227
228/**
229 * Unknown
230 * Inputs:
231 * 0: 0x00060040
232 * 1: u8 Camera port (`Port` enum)
233 * Outputs:
234 * 0: 0x00060042
235 * 1: ResultCode
236 * 2: Descriptor: Handle
237 * 3: Event handle
238 */
239void GetBufferErrorInterruptEvent(Service::Interface* self);
240
241/**
242 * Sets the target buffer to receive a frame of image data and starts the transfer. Each camera
243 * port has its own event to signal the end of the transfer.
244 *
245 * Inputs:
246 * 0: 0x00070102
247 * 1: Destination address in calling process
248 * 2: u8 Camera port (`Port` enum)
249 * 3: Image size (in bytes?)
250 * 4: u16 Transfer unit size (in bytes?)
251 * 5: Descriptor: Handle
252 * 6: Handle to destination process
253 * Outputs:
254 * 0: 0x00070042
255 * 1: ResultCode
256 * 2: Descriptor: Handle
257 * 3: Handle to event signalled when transfer finishes
258 */
259void SetReceiving(Service::Interface* self);
260
261/**
262 * Unknown
263 * Inputs:
264 * 0: 0x00090100
265 * 1: u8 Camera port (`Port` enum)
266 * 2: u16 Number of lines to transfer
267 * 3: u16 Width
268 * 4: u16 Height
269 * Outputs:
270 * 0: 0x00090040
271 * 1: ResultCode
272 */
273void SetTransferLines(Service::Interface* self);
274
275/**
276 * Unknown
277 * Inputs:
278 * 0: 0x000A0080
279 * 1: u16 Width
280 * 2: u16 Height
281 * Outputs:
282 * 0: 0x000A0080
283 * 1: ResultCode
284 * 2: Maximum number of lines that fit in the buffer(?)
285 */
286void GetMaxLines(Service::Interface* self);
287
288/**
289 * Unknown
290 * Inputs:
291 * 0: 0x000C0040
292 * 1: u8 Camera port (`Port` enum)
293 * Outputs:
294 * 0: 0x000C0080
295 * 1: ResultCode
296 * 2: Total number of bytes for each frame with current settings(?)
297 */
298void GetTransferBytes(Service::Interface* self);
299
300/**
301 * Unknown
302 * Inputs:
303 * 0: 0x000E0080
304 * 1: u8 Camera port (`Port` enum)
305 * 2: u8 bool Enable trimming if true
306 * Outputs:
307 * 0: 0x000E0040
308 * 1: ResultCode
309 */
310void SetTrimming(Service::Interface* self);
311
312/**
313 * Unknown
314 * Inputs:
315 * 0: 0x00120140
316 * 1: u8 Camera port (`Port` enum)
317 * 2: s16 Trim width(?)
318 * 3: s16 Trim height(?)
319 * 4: s16 Camera width(?)
320 * 5: s16 Camera height(?)
321 * Outputs:
322 * 0: 0x00120040
323 * 1: ResultCode
324 */
325void SetTrimmingParamsCenter(Service::Interface* self);
326
327/**
328 * Selects up to two physical cameras to enable.
329 * Inputs:
330 * 0: 0x00130040
331 * 1: u8 Cameras to activate (`CameraSelect` enum)
332 * Outputs:
333 * 0: 0x00130040
334 * 1: ResultCode
335 */
336void Activate(Service::Interface* self);
337
338/**
339 * Unknown
340 * Inputs:
341 * 0: 0x001D00C0
342 * 1: u8 Camera select (`CameraSelect` enum)
343 * 2: u8 Type of flipping to perform (`Flip` enum)
344 * 3: u8 Context (`Context` enum)
345 * Outputs:
346 * 0: 0x001D0040
347 * 1: ResultCode
348 */
349void FlipImage(Service::Interface* self);
350
351/**
352 * Unknown
353 * Inputs:
354 * 0: 0x001F00C0
355 * 1: u8 Camera select (`CameraSelect` enum)
356 * 2: u8 Camera frame resolution (`Size` enum)
357 * 3: u8 Context id (`Context` enum)
358 * Outputs:
359 * 0: 0x001F0040
360 * 1: ResultCode
361 */
362void SetSize(Service::Interface* self);
363
364/**
365 * Unknown
366 * Inputs:
367 * 0: 0x00200080
368 * 1: u8 Camera select (`CameraSelect` enum)
369 * 2: u8 Camera framerate (`FrameRate` enum)
370 * Outputs:
371 * 0: 0x00200040
372 * 1: ResultCode
373 */
374void SetFrameRate(Service::Interface* self);
375
376/**
377 * Returns calibration data relating the outside cameras to eachother, for use in AR applications.
378 *
379 * Inputs:
380 * 0: 0x002B0000
381 * Outputs:
382 * 0: 0x002B0440
383 * 1: ResultCode
384 * 2-17: `StereoCameraCalibrationData` structure with calibration values
385 */
386void GetStereoCameraCalibrationData(Service::Interface* self);
387
388/**
389 * Unknown
390 * Inputs:
391 * 0: 0x00360000
392 * Outputs:
393 * 0: 0x00360080
394 * 1: ResultCode
395 * 2: ?
396 */
397void GetSuitableY2rStandardCoefficient(Service::Interface* self);
398
399/**
400 * Unknown
401 * Inputs:
402 * 0: 0x00380040
403 * 1: u8 Sound ID
404 * Outputs:
405 * 0: 0x00380040
406 * 1: ResultCode
407 */
408void PlayShutterSound(Service::Interface* self);
409
410/**
411 * Initializes the camera driver. Must be called before using other functions.
412 * Inputs:
413 * 0: 0x00390000
414 * Outputs:
415 * 0: 0x00390040
416 * 1: ResultCode
417 */
418void DriverInitialize(Service::Interface* self);
419
420/**
421 * Shuts down the camera driver.
422 * Inputs:
423 * 0: 0x003A0000
424 * Outputs:
425 * 0: 0x003A0040
426 * 1: ResultCode
427 */
428void DriverFinalize(Service::Interface* self);
429
13/// Initialize CAM service(s) 430/// Initialize CAM service(s)
14void Init(); 431void Init();
15 432
diff --git a/src/core/hle/service/cam/cam_c.cpp b/src/core/hle/service/cam/cam_c.cpp
index d35adcb9f..8fa7abc85 100644
--- a/src/core/hle/service/cam/cam_c.cpp
+++ b/src/core/hle/service/cam/cam_c.cpp
@@ -2,8 +2,6 @@
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 "core/hle/hle.h"
6#include "core/hle/service/cam/cam.h"
7#include "core/hle/service/cam/cam_c.h" 5#include "core/hle/service/cam/cam_c.h"
8 6
9namespace Service { 7namespace Service {
diff --git a/src/core/hle/service/cam/cam_q.cpp b/src/core/hle/service/cam/cam_q.cpp
index c2760a102..d3ba91e9d 100644
--- a/src/core/hle/service/cam/cam_q.cpp
+++ b/src/core/hle/service/cam/cam_q.cpp
@@ -2,8 +2,6 @@
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 "core/hle/hle.h"
6#include "core/hle/service/cam/cam.h"
7#include "core/hle/service/cam/cam_q.h" 5#include "core/hle/service/cam/cam_q.h"
8 6
9namespace Service { 7namespace Service {
diff --git a/src/core/hle/service/cam/cam_s.cpp b/src/core/hle/service/cam/cam_s.cpp
index aefbf7df4..2a13984d8 100644
--- a/src/core/hle/service/cam/cam_s.cpp
+++ b/src/core/hle/service/cam/cam_s.cpp
@@ -2,8 +2,6 @@
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 "core/hle/hle.h"
6#include "core/hle/service/cam/cam.h"
7#include "core/hle/service/cam/cam_s.h" 5#include "core/hle/service/cam/cam_s.h"
8 6
9namespace Service { 7namespace Service {
diff --git a/src/core/hle/service/cam/cam_u.cpp b/src/core/hle/service/cam/cam_u.cpp
index 55083e0c7..a1070ebb2 100644
--- a/src/core/hle/service/cam/cam_u.cpp
+++ b/src/core/hle/service/cam/cam_u.cpp
@@ -2,7 +2,6 @@
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 "core/hle/hle.h"
6#include "core/hle/service/cam/cam.h" 5#include "core/hle/service/cam/cam.h"
7#include "core/hle/service/cam/cam_u.h" 6#include "core/hle/service/cam/cam_u.h"
8 7
@@ -10,25 +9,25 @@ namespace Service {
10namespace CAM { 9namespace CAM {
11 10
12const Interface::FunctionInfo FunctionTable[] = { 11const Interface::FunctionInfo FunctionTable[] = {
13 {0x00010040, nullptr, "StartCapture"}, 12 {0x00010040, StartCapture, "StartCapture"},
14 {0x00020040, nullptr, "StopCapture"}, 13 {0x00020040, StopCapture, "StopCapture"},
15 {0x00030040, nullptr, "IsBusy"}, 14 {0x00030040, nullptr, "IsBusy"},
16 {0x00040040, nullptr, "ClearBuffer"}, 15 {0x00040040, nullptr, "ClearBuffer"},
17 {0x00050040, nullptr, "GetVsyncInterruptEvent"}, 16 {0x00050040, GetVsyncInterruptEvent, "GetVsyncInterruptEvent"},
18 {0x00060040, nullptr, "GetBufferErrorInterruptEvent"}, 17 {0x00060040, GetBufferErrorInterruptEvent, "GetBufferErrorInterruptEvent"},
19 {0x00070102, nullptr, "SetReceiving"}, 18 {0x00070102, SetReceiving, "SetReceiving"},
20 {0x00080040, nullptr, "IsFinishedReceiving"}, 19 {0x00080040, nullptr, "IsFinishedReceiving"},
21 {0x00090100, nullptr, "SetTransferLines"}, 20 {0x00090100, SetTransferLines, "SetTransferLines"},
22 {0x000A0080, nullptr, "GetMaxLines"}, 21 {0x000A0080, GetMaxLines, "GetMaxLines"},
23 {0x000B0100, nullptr, "SetTransferBytes"}, 22 {0x000B0100, nullptr, "SetTransferBytes"},
24 {0x000C0040, nullptr, "GetTransferBytes"}, 23 {0x000C0040, GetTransferBytes, "GetTransferBytes"},
25 {0x000D0080, nullptr, "GetMaxBytes"}, 24 {0x000D0080, nullptr, "GetMaxBytes"},
26 {0x000E0080, nullptr, "SetTrimming"}, 25 {0x000E0080, SetTrimming, "SetTrimming"},
27 {0x000F0040, nullptr, "IsTrimming"}, 26 {0x000F0040, nullptr, "IsTrimming"},
28 {0x00100140, nullptr, "SetTrimmingParams"}, 27 {0x00100140, nullptr, "SetTrimmingParams"},
29 {0x00110040, nullptr, "GetTrimmingParams"}, 28 {0x00110040, nullptr, "GetTrimmingParams"},
30 {0x00120140, nullptr, "SetTrimmingParamsCenter"}, 29 {0x00120140, SetTrimmingParamsCenter, "SetTrimmingParamsCenter"},
31 {0x00130040, nullptr, "Activate"}, 30 {0x00130040, Activate, "Activate"},
32 {0x00140080, nullptr, "SwitchContext"}, 31 {0x00140080, nullptr, "SwitchContext"},
33 {0x00150080, nullptr, "SetExposure"}, 32 {0x00150080, nullptr, "SetExposure"},
34 {0x00160080, nullptr, "SetWhiteBalance"}, 33 {0x00160080, nullptr, "SetWhiteBalance"},
@@ -38,10 +37,10 @@ const Interface::FunctionInfo FunctionTable[] = {
38 {0x001A0040, nullptr, "IsAutoExposure"}, 37 {0x001A0040, nullptr, "IsAutoExposure"},
39 {0x001B0080, nullptr, "SetAutoWhiteBalance"}, 38 {0x001B0080, nullptr, "SetAutoWhiteBalance"},
40 {0x001C0040, nullptr, "IsAutoWhiteBalance"}, 39 {0x001C0040, nullptr, "IsAutoWhiteBalance"},
41 {0x001D00C0, nullptr, "FlipImage"}, 40 {0x001D00C0, FlipImage, "FlipImage"},
42 {0x001E0200, nullptr, "SetDetailSize"}, 41 {0x001E0200, nullptr, "SetDetailSize"},
43 {0x001F00C0, nullptr, "SetSize"}, 42 {0x001F00C0, SetSize, "SetSize"},
44 {0x00200080, nullptr, "SetFrameRate"}, 43 {0x00200080, SetFrameRate, "SetFrameRate"},
45 {0x00210080, nullptr, "SetPhotoMode"}, 44 {0x00210080, nullptr, "SetPhotoMode"},
46 {0x002200C0, nullptr, "SetEffect"}, 45 {0x002200C0, nullptr, "SetEffect"},
47 {0x00230080, nullptr, "SetContrast"}, 46 {0x00230080, nullptr, "SetContrast"},
@@ -52,17 +51,22 @@ const Interface::FunctionInfo FunctionTable[] = {
52 {0x00280080, nullptr, "SetNoiseFilter"}, 51 {0x00280080, nullptr, "SetNoiseFilter"},
53 {0x00290080, nullptr, "SynchronizeVsyncTiming"}, 52 {0x00290080, nullptr, "SynchronizeVsyncTiming"},
54 {0x002A0080, nullptr, "GetLatestVsyncTiming"}, 53 {0x002A0080, nullptr, "GetLatestVsyncTiming"},
55 {0x002B0000, nullptr, "GetStereoCameraCalibrationData"}, 54 {0x002B0000, GetStereoCameraCalibrationData, "GetStereoCameraCalibrationData"},
56 {0x002C0400, nullptr, "SetStereoCameraCalibrationData"}, 55 {0x002C0400, nullptr, "SetStereoCameraCalibrationData"},
56 {0x002D00C0, nullptr, "WriteRegisterI2c"},
57 {0x002E00C0, nullptr, "WriteMcuVariableI2c"},
58 {0x002F0080, nullptr, "ReadRegisterI2cExclusive"},
59 {0x00300080, nullptr, "ReadMcuVariableI2cExclusive"},
57 {0x00310180, nullptr, "SetImageQualityCalibrationData"}, 60 {0x00310180, nullptr, "SetImageQualityCalibrationData"},
58 {0x00320000, nullptr, "GetImageQualityCalibrationData"}, 61 {0x00320000, nullptr, "GetImageQualityCalibrationData"},
59 {0x003302C0, nullptr, "SetPackageParameterWithoutContext"}, 62 {0x003302C0, nullptr, "SetPackageParameterWithoutContext"},
60 {0x00340140, nullptr, "SetPackageParameterWithContext"}, 63 {0x00340140, nullptr, "SetPackageParameterWithContext"},
61 {0x003501C0, nullptr, "SetPackageParameterWithContextDetail"}, 64 {0x003501C0, nullptr, "SetPackageParameterWithContextDetail"},
62 {0x00360000, nullptr, "GetSuitableY2rStandardCoefficient"}, 65 {0x00360000, GetSuitableY2rStandardCoefficient, "GetSuitableY2rStandardCoefficient"},
63 {0x00380040, nullptr, "PlayShutterSound"}, 66 {0x00370202, nullptr, "PlayShutterSoundWithWave"},
64 {0x00390000, nullptr, "DriverInitialize"}, 67 {0x00380040, PlayShutterSound, "PlayShutterSound"},
65 {0x003A0000, nullptr, "DriverFinalize"}, 68 {0x00390000, DriverInitialize, "DriverInitialize"},
69 {0x003A0000, DriverFinalize, "DriverFinalize"},
66 {0x003B0000, nullptr, "GetActivatedCamera"}, 70 {0x003B0000, nullptr, "GetActivatedCamera"},
67 {0x003C0000, nullptr, "GetSleepCamera"}, 71 {0x003C0000, nullptr, "GetSleepCamera"},
68 {0x003D0040, nullptr, "SetSleepCamera"}, 72 {0x003D0040, nullptr, "SetSleepCamera"},
diff --git a/src/core/hle/service/cecd/cecd.cpp b/src/core/hle/service/cecd/cecd.cpp
index db0e52b79..6d79ce9b4 100644
--- a/src/core/hle/service/cecd/cecd.cpp
+++ b/src/core/hle/service/cecd/cecd.cpp
@@ -9,10 +9,6 @@
9#include "core/hle/service/cecd/cecd_s.h" 9#include "core/hle/service/cecd/cecd_s.h"
10#include "core/hle/service/cecd/cecd_u.h" 10#include "core/hle/service/cecd/cecd_u.h"
11 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 { 12namespace Service {
17namespace CECD { 13namespace CECD {
18 14
diff --git a/src/core/hle/service/cecd/cecd.h b/src/core/hle/service/cecd/cecd.h
index 32fd2045d..9e158521b 100644
--- a/src/core/hle/service/cecd/cecd.h
+++ b/src/core/hle/service/cecd/cecd.h
@@ -4,9 +4,6 @@
4 4
5#pragma once 5#pragma once
6 6
7#include "core/hle/kernel/kernel.h"
8#include "core/hle/service/service.h"
9
10namespace Service { 7namespace Service {
11namespace CECD { 8namespace CECD {
12 9
diff --git a/src/core/hle/service/cecd/cecd_s.cpp b/src/core/hle/service/cecd/cecd_s.cpp
index 72d7e8d44..bfd821c07 100644
--- a/src/core/hle/service/cecd/cecd_s.cpp
+++ b/src/core/hle/service/cecd/cecd_s.cpp
@@ -2,8 +2,6 @@
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 "core/hle/hle.h"
6#include "core/hle/service/cecd/cecd.h"
7#include "core/hle/service/cecd/cecd_s.h" 5#include "core/hle/service/cecd/cecd_s.h"
8 6
9namespace Service { 7namespace Service {
diff --git a/src/core/hle/service/cecd/cecd_u.cpp b/src/core/hle/service/cecd/cecd_u.cpp
index 0a23bafbc..9b720a738 100644
--- a/src/core/hle/service/cecd/cecd_u.cpp
+++ b/src/core/hle/service/cecd/cecd_u.cpp
@@ -2,18 +2,17 @@
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 "core/hle/hle.h"
6#include "core/hle/service/cecd/cecd.h"
7#include "core/hle/service/cecd/cecd_u.h" 5#include "core/hle/service/cecd/cecd_u.h"
8 6
9namespace Service { 7namespace Service {
10namespace CECD { 8namespace CECD {
11 9
12// Empty arrays are illegal -- commented out until an entry is added. 10static const Interface::FunctionInfo FunctionTable[] = {
13//const Interface::FunctionInfo FunctionTable[] = { }; 11 { 0x00120104, nullptr, "ReadSavedData" },
12};
14 13
15CECD_U_Interface::CECD_U_Interface() { 14CECD_U_Interface::CECD_U_Interface() {
16 //Register(FunctionTable); 15 Register(FunctionTable);
17} 16}
18 17
19} // namespace CECD 18} // namespace CECD
diff --git a/src/core/hle/service/cfg/cfg.cpp b/src/core/hle/service/cfg/cfg.cpp
index 56986a49e..4c82a58e4 100644
--- a/src/core/hle/service/cfg/cfg.cpp
+++ b/src/core/hle/service/cfg/cfg.cpp
@@ -4,13 +4,15 @@
4 4
5#include <algorithm> 5#include <algorithm>
6 6
7#include "common/file_util.h"
7#include "common/logging/log.h" 8#include "common/logging/log.h"
8#include "common/string_util.h" 9#include "common/string_util.h"
9#include "common/file_util.h" 10#include "common/swap.h"
10 11
11#include "core/file_sys/archive_systemsavedata.h" 12#include "core/file_sys/archive_systemsavedata.h"
12#include "core/file_sys/file_backend.h" 13#include "core/file_sys/file_backend.h"
13#include "core/settings.h" 14#include "core/settings.h"
15#include "core/hle/result.h"
14#include "core/hle/service/cfg/cfg.h" 16#include "core/hle/service/cfg/cfg.h"
15#include "core/hle/service/cfg/cfg_i.h" 17#include "core/hle/service/cfg/cfg_i.h"
16#include "core/hle/service/cfg/cfg_s.h" 18#include "core/hle/service/cfg/cfg_s.h"
@@ -292,8 +294,8 @@ ResultCode DeleteConfigNANDSaveFile() {
292 294
293ResultCode UpdateConfigNANDSavegame() { 295ResultCode UpdateConfigNANDSavegame() {
294 FileSys::Mode mode = {}; 296 FileSys::Mode mode = {};
295 mode.write_flag = 1; 297 mode.write_flag.Assign(1);
296 mode.create_flag = 1; 298 mode.create_flag.Assign(1);
297 299
298 FileSys::Path path("config"); 300 FileSys::Path path("config");
299 301
@@ -333,6 +335,18 @@ ResultCode FormatConfig() {
333 res = CreateConfigInfoBlk(0x000A0000, sizeof(CONSOLE_USERNAME_BLOCK), 0xE, &CONSOLE_USERNAME_BLOCK); 335 res = CreateConfigInfoBlk(0x000A0000, sizeof(CONSOLE_USERNAME_BLOCK), 0xE, &CONSOLE_USERNAME_BLOCK);
334 if (!res.IsSuccess()) return res; 336 if (!res.IsSuccess()) return res;
335 337
338 // 0x000A0000 - Profile username
339 struct {
340 u16_le username[10];
341 u8 unused[4];
342 u32_le wordfilter_version; // Unused by Citra
343 } profile_username = {};
344
345 std::u16string username_string = Common::UTF8ToUTF16("Citra");
346 std::copy(username_string.cbegin(), username_string.cend(), profile_username.username);
347 res = CreateConfigInfoBlk(0x000A0000, sizeof(profile_username), 0xE, &profile_username);
348 if (!res.IsSuccess()) return res;
349
336 // 0x000A0001 - Profile birthday 350 // 0x000A0001 - Profile birthday
337 const u8 profile_birthday[2] = {3, 25}; // March 25th, 2014 351 const u8 profile_birthday[2] = {3, 25}; // March 25th, 2014
338 res = CreateConfigInfoBlk(0x000A0001, sizeof(profile_birthday), 0xE, profile_birthday); 352 res = CreateConfigInfoBlk(0x000A0001, sizeof(profile_birthday), 0xE, profile_birthday);
@@ -343,9 +357,10 @@ ResultCode FormatConfig() {
343 res = CreateConfigInfoBlk(0x000B0000, sizeof(COUNTRY_INFO), 0xE, &COUNTRY_INFO); 357 res = CreateConfigInfoBlk(0x000B0000, sizeof(COUNTRY_INFO), 0xE, &COUNTRY_INFO);
344 if (!res.IsSuccess()) return res; 358 if (!res.IsSuccess()) return res;
345 359
346 char16_t country_name_buffer[16][0x40] = {}; 360 u16_le country_name_buffer[16][0x40] = {};
361 std::u16string region_name = Common::UTF8ToUTF16("Gensokyo");
347 for (size_t i = 0; i < 16; ++i) { 362 for (size_t i = 0; i < 16; ++i) {
348 Common::UTF8ToUTF16("Gensokyo").copy(country_name_buffer[i], 0x40); 363 std::copy(region_name.cbegin(), region_name.cend(), country_name_buffer[i]);
349 } 364 }
350 // 0x000B0001 - Localized names for the profile Country 365 // 0x000B0001 - Localized names for the profile Country
351 res = CreateConfigInfoBlk(0x000B0001, sizeof(country_name_buffer), 0xE, country_name_buffer); 366 res = CreateConfigInfoBlk(0x000B0001, sizeof(country_name_buffer), 0xE, country_name_buffer);
@@ -404,7 +419,7 @@ void Init() {
404 419
405 FileSys::Path config_path("config"); 420 FileSys::Path config_path("config");
406 FileSys::Mode open_mode = {}; 421 FileSys::Mode open_mode = {};
407 open_mode.read_flag = 1; 422 open_mode.read_flag.Assign(1);
408 423
409 auto config_result = Service::FS::OpenFileFromArchive(*archive_result, config_path, open_mode); 424 auto config_result = Service::FS::OpenFileFromArchive(*archive_result, config_path, open_mode);
410 425
diff --git a/src/core/hle/service/cfg/cfg.h b/src/core/hle/service/cfg/cfg.h
index fc2a16a04..606ab99cf 100644
--- a/src/core/hle/service/cfg/cfg.h
+++ b/src/core/hle/service/cfg/cfg.h
@@ -5,10 +5,15 @@
5#pragma once 5#pragma once
6 6
7#include <array> 7#include <array>
8#include "core/hle/result.h" 8
9#include "core/hle/service/service.h" 9#include "common/common_types.h"
10
11union ResultCode;
10 12
11namespace Service { 13namespace Service {
14
15class Interface;
16
12namespace CFG { 17namespace CFG {
13 18
14enum SystemModel { 19enum SystemModel {
diff --git a/src/core/hle/service/cfg/cfg_i.cpp b/src/core/hle/service/cfg/cfg_i.cpp
index 5aeadc084..0559a07b2 100644
--- a/src/core/hle/service/cfg/cfg_i.cpp
+++ b/src/core/hle/service/cfg/cfg_i.cpp
@@ -2,7 +2,6 @@
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 "core/hle/hle.h"
6#include "core/hle/service/cfg/cfg.h" 5#include "core/hle/service/cfg/cfg.h"
7#include "core/hle/service/cfg/cfg_i.h" 6#include "core/hle/service/cfg/cfg_i.h"
8 7
diff --git a/src/core/hle/service/cfg/cfg_s.cpp b/src/core/hle/service/cfg/cfg_s.cpp
index a329514a6..b03d290e5 100644
--- a/src/core/hle/service/cfg/cfg_s.cpp
+++ b/src/core/hle/service/cfg/cfg_s.cpp
@@ -2,7 +2,6 @@
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 "core/hle/hle.h"
6#include "core/hle/service/cfg/cfg.h" 5#include "core/hle/service/cfg/cfg.h"
7#include "core/hle/service/cfg/cfg_s.h" 6#include "core/hle/service/cfg/cfg_s.h"
8 7
diff --git a/src/core/hle/service/cfg/cfg_u.cpp b/src/core/hle/service/cfg/cfg_u.cpp
index 18939750b..89ae96c9e 100644
--- a/src/core/hle/service/cfg/cfg_u.cpp
+++ b/src/core/hle/service/cfg/cfg_u.cpp
@@ -2,7 +2,6 @@
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 "core/hle/hle.h"
6#include "core/hle/service/cfg/cfg.h" 5#include "core/hle/service/cfg/cfg.h"
7#include "core/hle/service/cfg/cfg_u.h" 6#include "core/hle/service/cfg/cfg_u.h"
8 7
diff --git a/src/core/hle/service/csnd_snd.cpp b/src/core/hle/service/csnd_snd.cpp
index 669659510..6318bf2a7 100644
--- a/src/core/hle/service/csnd_snd.cpp
+++ b/src/core/hle/service/csnd_snd.cpp
@@ -22,9 +22,10 @@ const Interface::FunctionInfo FunctionTable[] = {
22 {0x00060000, nullptr, "ReleaseSoundChannels"}, 22 {0x00060000, nullptr, "ReleaseSoundChannels"},
23 {0x00070000, nullptr, "AcquireCaptureDevice"}, 23 {0x00070000, nullptr, "AcquireCaptureDevice"},
24 {0x00080040, nullptr, "ReleaseCaptureDevice"}, 24 {0x00080040, nullptr, "ReleaseCaptureDevice"},
25 {0x00090082, nullptr, "FlushDCache"}, 25 {0x00090082, nullptr, "FlushDataCache"},
26 {0x000A0082, nullptr, "StoreDCache"}, 26 {0x000A0082, nullptr, "StoreDataCache"},
27 {0x000B0082, nullptr, "InvalidateDCache"}, 27 {0x000B0082, nullptr, "InvalidateDataCache"},
28 {0x000C0000, nullptr, "Reset"},
28}; 29};
29 30
30//////////////////////////////////////////////////////////////////////////////////////////////////// 31////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/service/dsp_dsp.cpp b/src/core/hle/service/dsp_dsp.cpp
index ce5619069..3ba24d466 100644
--- a/src/core/hle/service/dsp_dsp.cpp
+++ b/src/core/hle/service/dsp_dsp.cpp
@@ -2,9 +2,13 @@
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 <cinttypes>
6
7#include "audio_core/hle/pipe.h"
8
9#include "common/hash.h"
5#include "common/logging/log.h" 10#include "common/logging/log.h"
6 11
7#include "core/hle/hle.h"
8#include "core/hle/kernel/event.h" 12#include "core/hle/kernel/event.h"
9#include "core/hle/service/dsp_dsp.h" 13#include "core/hle/service/dsp_dsp.h"
10 14
@@ -15,17 +19,30 @@ namespace DSP_DSP {
15 19
16static u32 read_pipe_count; 20static u32 read_pipe_count;
17static Kernel::SharedPtr<Kernel::Event> semaphore_event; 21static Kernel::SharedPtr<Kernel::Event> semaphore_event;
18static Kernel::SharedPtr<Kernel::Event> interrupt_event;
19 22
20void SignalInterrupt() { 23struct PairHash {
21 // TODO(bunnei): This is just a stub, it does not do anything other than signal to the emulated 24 template <typename T, typename U>
22 // application that a DSP interrupt occurred, without specifying which one. Since we do not 25 std::size_t operator()(const std::pair<T, U> &x) const {
23 // emulate the DSP yet (and how it works is largely unknown), this is a work around to get games 26 // TODO(yuriks): Replace with better hash combining function.
24 // that check the DSP interrupt signal event to run. We should figure out the different types of 27 return std::hash<T>()(x.first) ^ std::hash<U>()(x.second);
25 // DSP interrupts, and trigger them at the appropriate times. 28 }
29};
30
31/// Map of (audio interrupt number, channel number) to Kernel::Events. See: RegisterInterruptEvents
32static std::unordered_map<std::pair<u32, u32>, Kernel::SharedPtr<Kernel::Event>, PairHash> interrupt_events;
33
34// DSP Interrupts:
35// Interrupt #2 occurs every frame tick. Userland programs normally have a thread that's waiting
36// for an interrupt event. Immediately after this interrupt event, userland normally updates the
37// state in the next region and increments the relevant frame counter by two.
38void SignalAllInterrupts() {
39 // HACK: The other interrupts have currently unknown purpose, we trigger them each tick in any case.
40 for (auto& interrupt_event : interrupt_events)
41 interrupt_event.second->Signal();
42}
26 43
27 if (interrupt_event != 0) 44void SignalInterrupt(u32 interrupt, u32 channel) {
28 interrupt_event->Signal(); 45 interrupt_events[std::make_pair(interrupt, channel)]->Signal();
29} 46}
30 47
31/** 48/**
@@ -41,18 +58,18 @@ static void ConvertProcessAddressFromDspDram(Service::Interface* self) {
41 58
42 u32 addr = cmd_buff[1]; 59 u32 addr = cmd_buff[1];
43 60
44 cmd_buff[1] = 0; // No error 61 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
45 cmd_buff[2] = (addr << 1) + (Memory::DSP_RAM_VADDR + 0x40000); 62 cmd_buff[2] = (addr << 1) + (Memory::DSP_RAM_VADDR + 0x40000);
46 63
47 LOG_WARNING(Service_DSP, "(STUBBED) called with address 0x%08X", addr); 64 LOG_DEBUG(Service_DSP, "addr=0x%08X", addr);
48} 65}
49 66
50/** 67/**
51 * DSP_DSP::LoadComponent service function 68 * DSP_DSP::LoadComponent service function
52 * Inputs: 69 * Inputs:
53 * 1 : Size 70 * 1 : Size
54 * 2 : Unknown (observed only half word used) 71 * 2 : Program mask (observed only half word used)
55 * 3 : Unknown (observed only half word used) 72 * 3 : Data mask (observed only half word used)
56 * 4 : (size << 4) | 0xA 73 * 4 : (size << 4) | 0xA
57 * 5 : Buffer address 74 * 5 : Buffer address
58 * Outputs: 75 * Outputs:
@@ -63,18 +80,28 @@ static void LoadComponent(Service::Interface* self) {
63 u32* cmd_buff = Kernel::GetCommandBuffer(); 80 u32* cmd_buff = Kernel::GetCommandBuffer();
64 81
65 u32 size = cmd_buff[1]; 82 u32 size = cmd_buff[1];
66 u32 unk1 = cmd_buff[2]; 83 u32 prog_mask = cmd_buff[2];
67 u32 unk2 = cmd_buff[3]; 84 u32 data_mask = cmd_buff[3];
68 u32 new_size = cmd_buff[4]; 85 u32 desc = cmd_buff[4];
69 u32 buffer = cmd_buff[5]; 86 u32 buffer = cmd_buff[5];
70 87
71 cmd_buff[1] = 0; // No error 88 cmd_buff[0] = IPC::MakeHeader(0x11, 2, 2);
89 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
72 cmd_buff[2] = 1; // Pretend that we actually loaded the DSP firmware 90 cmd_buff[2] = 1; // Pretend that we actually loaded the DSP firmware
91 cmd_buff[3] = desc;
92 cmd_buff[4] = buffer;
73 93
74 // TODO(bunnei): Implement real DSP firmware loading 94 // TODO(bunnei): Implement real DSP firmware loading
75 95
76 LOG_WARNING(Service_DSP, "(STUBBED) called size=0x%X, unk1=0x%08X, unk2=0x%08X, new_size=0x%X, buffer=0x%08X", 96 ASSERT(Memory::GetPointer(buffer) != nullptr);
77 size, unk1, unk2, new_size, buffer); 97 ASSERT(size > 0x37C);
98
99 LOG_INFO(Service_DSP, "Firmware hash: %#" PRIx64, Common::ComputeHash64(Memory::GetPointer(buffer), size));
100 // Some versions of the firmware have the location of DSP structures listed here.
101 LOG_INFO(Service_DSP, "Structures hash: %#" PRIx64, Common::ComputeHash64(Memory::GetPointer(buffer) + 0x340, 60));
102
103 LOG_WARNING(Service_DSP, "(STUBBED) called size=0x%X, prog_mask=0x%08X, data_mask=0x%08X, buffer=0x%08X",
104 size, prog_mask, data_mask, buffer);
78} 105}
79 106
80/** 107/**
@@ -115,15 +142,14 @@ static void FlushDataCache(Service::Interface* self) {
115 142
116 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 143 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
117 144
118 LOG_DEBUG(Service_DSP, "(STUBBED) called address=0x%08X, size=0x%X, process=0x%08X", 145 LOG_TRACE(Service_DSP, "called address=0x%08X, size=0x%X, process=0x%08X", address, size, process);
119 address, size, process);
120} 146}
121 147
122/** 148/**
123 * DSP_DSP::RegisterInterruptEvents service function 149 * DSP_DSP::RegisterInterruptEvents service function
124 * Inputs: 150 * Inputs:
125 * 1 : Parameter 0 (purpose unknown) 151 * 1 : Interrupt Number
126 * 2 : Parameter 1 (purpose unknown) 152 * 2 : Channel Number
127 * 4 : Interrupt event handle 153 * 4 : Interrupt event handle
128 * Outputs: 154 * Outputs:
129 * 1 : Result of function, 0 on success, otherwise error code 155 * 1 : Result of function, 0 on success, otherwise error code
@@ -131,37 +157,37 @@ static void FlushDataCache(Service::Interface* self) {
131static void RegisterInterruptEvents(Service::Interface* self) { 157static void RegisterInterruptEvents(Service::Interface* self) {
132 u32* cmd_buff = Kernel::GetCommandBuffer(); 158 u32* cmd_buff = Kernel::GetCommandBuffer();
133 159
134 u32 param0 = cmd_buff[1]; 160 u32 interrupt = cmd_buff[1];
135 u32 param1 = cmd_buff[2]; 161 u32 channel = cmd_buff[2];
136 u32 event_handle = cmd_buff[4]; 162 u32 event_handle = cmd_buff[4];
137 163
138 auto evt = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[4]); 164 if (event_handle) {
139 if (evt != nullptr) { 165 auto evt = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[4]);
140 interrupt_event = evt; 166 if (evt) {
141 cmd_buff[1] = 0; // No error 167 interrupt_events[std::make_pair(interrupt, channel)] = evt;
168 cmd_buff[1] = RESULT_SUCCESS.raw;
169 LOG_INFO(Service_DSP, "Registered interrupt=%u, channel=%u, event_handle=0x%08X", interrupt, channel, event_handle);
170 } else {
171 LOG_CRITICAL(Service_DSP, "Invalid event handle! interrupt=%u, channel=%u, event_handle=0x%08X", interrupt, channel, event_handle);
172 ASSERT(false); // This should really be handled at a IPC translation layer.
173 }
142 } else { 174 } else {
143 LOG_ERROR(Service_DSP, "called with invalid handle=%08X", cmd_buff[4]); 175 interrupt_events.erase(std::make_pair(interrupt, channel));
144 176 LOG_INFO(Service_DSP, "Unregistered interrupt=%u, channel=%u, event_handle=0x%08X", interrupt, channel, event_handle);
145 // TODO(yuriks): An error should be returned from SendSyncRequest, not in the cmdbuf
146 cmd_buff[1] = -1;
147 } 177 }
148
149 LOG_WARNING(Service_DSP, "(STUBBED) called param0=%u, param1=%u, event_handle=0x%08X", param0, param1, event_handle);
150} 178}
151 179
152/** 180/**
153 * DSP_DSP::WriteReg0x10 service function 181 * DSP_DSP::SetSemaphore service function
154 * Inputs: 182 * Inputs:
155 * 1 : Unknown (observed only half word used) 183 * 1 : Unknown (observed only half word used)
156 * Outputs: 184 * Outputs:
157 * 1 : Result of function, 0 on success, otherwise error code 185 * 1 : Result of function, 0 on success, otherwise error code
158 */ 186 */
159static void WriteReg0x10(Service::Interface* self) { 187static void SetSemaphore(Service::Interface* self) {
160 u32* cmd_buff = Kernel::GetCommandBuffer(); 188 u32* cmd_buff = Kernel::GetCommandBuffer();
161 189
162 SignalInterrupt(); 190 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
163
164 cmd_buff[1] = 0; // No error
165 191
166 LOG_WARNING(Service_DSP, "(STUBBED) called"); 192 LOG_WARNING(Service_DSP, "(STUBBED) called");
167} 193}
@@ -169,9 +195,9 @@ static void WriteReg0x10(Service::Interface* self) {
169/** 195/**
170 * DSP_DSP::WriteProcessPipe service function 196 * DSP_DSP::WriteProcessPipe service function
171 * Inputs: 197 * Inputs:
172 * 1 : Number 198 * 1 : Channel
173 * 2 : Size 199 * 2 : Size
174 * 3 : (size <<14) | 0x402 200 * 3 : (size << 14) | 0x402
175 * 4 : Buffer 201 * 4 : Buffer
176 * Outputs: 202 * Outputs:
177 * 0 : Return header 203 * 0 : Return header
@@ -180,24 +206,36 @@ static void WriteReg0x10(Service::Interface* self) {
180static void WriteProcessPipe(Service::Interface* self) { 206static void WriteProcessPipe(Service::Interface* self) {
181 u32* cmd_buff = Kernel::GetCommandBuffer(); 207 u32* cmd_buff = Kernel::GetCommandBuffer();
182 208
183 u32 number = cmd_buff[1]; 209 DSP::HLE::DspPipe pipe = static_cast<DSP::HLE::DspPipe>(cmd_buff[1]);
184 u32 size = cmd_buff[2]; 210 u32 size = cmd_buff[2];
185 u32 new_size = cmd_buff[3]; 211 u32 buffer = cmd_buff[4];
186 u32 buffer = cmd_buff[4]; 212
213 ASSERT_MSG(IPC::StaticBufferDesc(size, 1) == cmd_buff[3], "IPC static buffer descriptor failed validation (0x%X). pipe=%u, size=0x%X, buffer=0x%08X", cmd_buff[3], pipe, size, buffer);
214 ASSERT_MSG(Memory::GetPointer(buffer) != nullptr, "Invalid Buffer: pipe=%u, size=0x%X, buffer=0x%08X", pipe, size, buffer);
215
216 std::vector<u8> message(size);
217
218 for (size_t i = 0; i < size; i++) {
219 message[i] = Memory::Read8(buffer + i);
220 }
221
222 DSP::HLE::PipeWrite(pipe, message);
187 223
188 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 224 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
189 225
190 LOG_WARNING(Service_DSP, "(STUBBED) called number=%u, size=0x%X, new_size=0x%X, buffer=0x%08X", 226 LOG_DEBUG(Service_DSP, "pipe=%u, size=0x%X, buffer=0x%08X", pipe, size, buffer);
191 number, size, new_size, buffer);
192} 227}
193 228
194/** 229/**
195 * DSP_DSP::ReadPipeIfPossible service function 230 * DSP_DSP::ReadPipeIfPossible service function
231 * A pipe is a means of communication between the ARM11 and DSP that occurs on
232 * hardware by writing to/reading from the DSP registers at 0x10203000.
233 * Pipes are used for initialisation. See also DSP::HLE::PipeRead.
196 * Inputs: 234 * Inputs:
197 * 1 : Unknown 235 * 1 : Pipe Number
198 * 2 : Unknown 236 * 2 : Unknown
199 * 3 : Size in bytes of read (observed only lower half word used) 237 * 3 : Size in bytes of read (observed only lower half word used)
200 * 0x41 : Virtual address to read from DSP pipe to in memory 238 * 0x41 : Virtual address of memory buffer to write pipe contents to
201 * Outputs: 239 * Outputs:
202 * 1 : Result of function, 0 on success, otherwise error code 240 * 1 : Result of function, 0 on success, otherwise error code
203 * 2 : Number of bytes read from pipe 241 * 2 : Number of bytes read from pipe
@@ -205,35 +243,82 @@ static void WriteProcessPipe(Service::Interface* self) {
205static void ReadPipeIfPossible(Service::Interface* self) { 243static void ReadPipeIfPossible(Service::Interface* self) {
206 u32* cmd_buff = Kernel::GetCommandBuffer(); 244 u32* cmd_buff = Kernel::GetCommandBuffer();
207 245
208 u32 unk1 = cmd_buff[1]; 246 DSP::HLE::DspPipe pipe = static_cast<DSP::HLE::DspPipe>(cmd_buff[1]);
209 u32 unk2 = cmd_buff[2]; 247 u32 unknown = cmd_buff[2];
210 u32 size = cmd_buff[3] & 0xFFFF;// Lower 16 bits are size 248 u32 size = cmd_buff[3] & 0xFFFF; // Lower 16 bits are size
211 VAddr addr = cmd_buff[0x41]; 249 VAddr addr = cmd_buff[0x41];
212 250
213 // Canned DSP responses that games expect. These were taken from HW by 3dmoo team. 251 ASSERT_MSG(Memory::GetPointer(addr) != nullptr, "Invalid addr: pipe=0x%08X, unknown=0x%08X, size=0x%X, buffer=0x%08X", pipe, unknown, size, addr);
214 // TODO: Remove this hack :)
215 static const std::array<u16, 16> canned_read_pipe = {{
216 0x000F, 0xBFFF, 0x9E8E, 0x8680, 0xA78E, 0x9430, 0x8400, 0x8540,
217 0x948E, 0x8710, 0x8410, 0xA90E, 0xAA0E, 0xAACE, 0xAC4E, 0xAC58
218 }};
219 252
220 u32 initial_size = read_pipe_count; 253 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
254 if (DSP::HLE::GetPipeReadableSize(pipe) >= size) {
255 std::vector<u8> response = DSP::HLE::PipeRead(pipe, size);
221 256
222 for (unsigned offset = 0; offset < size; offset += sizeof(u16)) { 257 Memory::WriteBlock(addr, response.data(), response.size());
223 if (read_pipe_count < canned_read_pipe.size()) { 258
224 Memory::Write16(addr + offset, canned_read_pipe[read_pipe_count]); 259 cmd_buff[2] = static_cast<u32>(response.size());
225 read_pipe_count++; 260 } else {
226 } else { 261 cmd_buff[2] = 0; // Return no data
227 LOG_ERROR(Service_DSP, "canned read pipe log exceeded!");
228 break;
229 }
230 } 262 }
231 263
232 cmd_buff[1] = 0; // No error 264 LOG_DEBUG(Service_DSP, "pipe=0x%08X, unknown=0x%08X, size=0x%X, buffer=0x%08X, return cmd_buff[2]=0x%08X", pipe, unknown, size, addr, cmd_buff[2]);
233 cmd_buff[2] = (read_pipe_count - initial_size) * sizeof(u16); 265}
234 266
235 LOG_WARNING(Service_DSP, "(STUBBED) called unk1=0x%08X, unk2=0x%08X, size=0x%X, buffer=0x%08X", 267/**
236 unk1, unk2, size, addr); 268 * DSP_DSP::ReadPipe service function
269 * Inputs:
270 * 1 : Pipe Number
271 * 2 : Unknown
272 * 3 : Size in bytes of read (observed only lower half word used)
273 * 0x41 : Virtual address of memory buffer to write pipe contents to
274 * Outputs:
275 * 1 : Result of function, 0 on success, otherwise error code
276 * 2 : Number of bytes read from pipe
277 */
278static void ReadPipe(Service::Interface* self) {
279 u32* cmd_buff = Kernel::GetCommandBuffer();
280
281 DSP::HLE::DspPipe pipe = static_cast<DSP::HLE::DspPipe>(cmd_buff[1]);
282 u32 unknown = cmd_buff[2];
283 u32 size = cmd_buff[3] & 0xFFFF; // Lower 16 bits are size
284 VAddr addr = cmd_buff[0x41];
285
286 ASSERT_MSG(Memory::GetPointer(addr) != nullptr, "Invalid addr: pipe=0x%08X, unknown=0x%08X, size=0x%X, buffer=0x%08X", pipe, unknown, size, addr);
287
288 if (DSP::HLE::GetPipeReadableSize(pipe) >= size) {
289 std::vector<u8> response = DSP::HLE::PipeRead(pipe, size);
290
291 Memory::WriteBlock(addr, response.data(), response.size());
292
293 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
294 cmd_buff[2] = static_cast<u32>(response.size());
295 } else {
296 // No more data is in pipe. Hardware hangs in this case; this should never happen.
297 UNREACHABLE();
298 }
299
300 LOG_DEBUG(Service_DSP, "pipe=0x%08X, unknown=0x%08X, size=0x%X, buffer=0x%08X, return cmd_buff[2]=0x%08X", pipe, unknown, size, addr, cmd_buff[2]);
301}
302
303/**
304 * DSP_DSP::GetPipeReadableSize service function
305 * Inputs:
306 * 1 : Pipe Number
307 * 2 : Unknown
308 * Outputs:
309 * 1 : Result of function, 0 on success, otherwise error code
310 * 2 : Number of bytes readable from pipe
311 */
312static void GetPipeReadableSize(Service::Interface* self) {
313 u32* cmd_buff = Kernel::GetCommandBuffer();
314
315 DSP::HLE::DspPipe pipe = static_cast<DSP::HLE::DspPipe>(cmd_buff[1]);
316 u32 unknown = cmd_buff[2];
317
318 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
319 cmd_buff[2] = DSP::HLE::GetPipeReadableSize(pipe);
320
321 LOG_DEBUG(Service_DSP, "pipe=0x%08X, unknown=0x%08X, return cmd_buff[2]=0x%08X", pipe, unknown, cmd_buff[2]);
237} 322}
238 323
239/** 324/**
@@ -268,20 +353,86 @@ static void GetHeadphoneStatus(Service::Interface* self) {
268 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 353 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
269 cmd_buff[2] = 0; // Not using headphones? 354 cmd_buff[2] = 0; // Not using headphones?
270 355
271 LOG_DEBUG(Service_DSP, "(STUBBED) called"); 356 LOG_WARNING(Service_DSP, "(STUBBED) called");
357}
358
359/**
360 * DSP_DSP::RecvData service function
361 * This function reads a value out of a DSP register.
362 * Inputs:
363 * 1 : Register Number
364 * Outputs:
365 * 1 : Result of function, 0 on success, otherwise error code
366 * 2 : Value in the register
367 * Notes:
368 * This function has only been observed being called with a register number of 0.
369 */
370static void RecvData(Service::Interface* self) {
371 u32* cmd_buff = Kernel::GetCommandBuffer();
372
373 u32 register_number = cmd_buff[1];
374
375 ASSERT_MSG(register_number == 0, "Unknown register_number %u", register_number);
376
377 // Application reads this after requesting DSP shutdown, to verify the DSP has indeed shutdown or slept.
378
379 cmd_buff[1] = RESULT_SUCCESS.raw;
380 switch (DSP::HLE::GetDspState()) {
381 case DSP::HLE::DspState::On:
382 cmd_buff[2] = 0;
383 break;
384 case DSP::HLE::DspState::Off:
385 case DSP::HLE::DspState::Sleeping:
386 cmd_buff[2] = 1;
387 break;
388 default:
389 UNREACHABLE();
390 break;
391 }
392
393 LOG_DEBUG(Service_DSP, "register_number=%u", register_number);
394}
395
396/**
397 * DSP_DSP::RecvDataIsReady service function
398 * This function checks whether a DSP register is ready to be read.
399 * Inputs:
400 * 1 : Register Number
401 * Outputs:
402 * 1 : Result of function, 0 on success, otherwise error code
403 * 2 : non-zero == ready
404 * Note:
405 * This function has only been observed being called with a register number of 0.
406 */
407static void RecvDataIsReady(Service::Interface* self) {
408 u32* cmd_buff = Kernel::GetCommandBuffer();
409
410 u32 register_number = cmd_buff[1];
411
412 ASSERT_MSG(register_number == 0, "Unknown register_number %u", register_number);
413
414 cmd_buff[1] = RESULT_SUCCESS.raw;
415 cmd_buff[2] = 1; // Ready to read
416
417 LOG_DEBUG(Service_DSP, "register_number=%u", register_number);
272} 418}
273 419
274const Interface::FunctionInfo FunctionTable[] = { 420const Interface::FunctionInfo FunctionTable[] = {
275 {0x00010040, nullptr, "RecvData"}, 421 {0x00010040, RecvData, "RecvData"},
276 {0x00020040, nullptr, "RecvDataIsReady"}, 422 {0x00020040, RecvDataIsReady, "RecvDataIsReady"},
277 {0x00030080, nullptr, "SendData"}, 423 {0x00030080, nullptr, "SendData"},
278 {0x00040040, nullptr, "SendDataIsEmpty"}, 424 {0x00040040, nullptr, "SendDataIsEmpty"},
279 {0x00070040, WriteReg0x10, "WriteReg0x10"}, 425 {0x000500C2, nullptr, "SendFifoEx"},
426 {0x000600C0, nullptr, "RecvFifoEx"},
427 {0x00070040, SetSemaphore, "SetSemaphore"},
280 {0x00080000, nullptr, "GetSemaphore"}, 428 {0x00080000, nullptr, "GetSemaphore"},
281 {0x00090040, nullptr, "ClearSemaphore"}, 429 {0x00090040, nullptr, "ClearSemaphore"},
430 {0x000A0040, nullptr, "MaskSemaphore"},
282 {0x000B0000, nullptr, "CheckSemaphoreRequest"}, 431 {0x000B0000, nullptr, "CheckSemaphoreRequest"},
283 {0x000C0040, ConvertProcessAddressFromDspDram, "ConvertProcessAddressFromDspDram"}, 432 {0x000C0040, ConvertProcessAddressFromDspDram, "ConvertProcessAddressFromDspDram"},
284 {0x000D0082, WriteProcessPipe, "WriteProcessPipe"}, 433 {0x000D0082, WriteProcessPipe, "WriteProcessPipe"},
434 {0x000E00C0, ReadPipe, "ReadPipe"},
435 {0x000F0080, GetPipeReadableSize, "GetPipeReadableSize"},
285 {0x001000C0, ReadPipeIfPossible, "ReadPipeIfPossible"}, 436 {0x001000C0, ReadPipeIfPossible, "ReadPipeIfPossible"},
286 {0x001100C2, LoadComponent, "LoadComponent"}, 437 {0x001100C2, LoadComponent, "LoadComponent"},
287 {0x00120000, nullptr, "UnloadComponent"}, 438 {0x00120000, nullptr, "UnloadComponent"},
@@ -295,7 +446,10 @@ const Interface::FunctionInfo FunctionTable[] = {
295 {0x001A0042, nullptr, "SetIirFilterI2S1_cmd1"}, 446 {0x001A0042, nullptr, "SetIirFilterI2S1_cmd1"},
296 {0x001B0042, nullptr, "SetIirFilterI2S1_cmd2"}, 447 {0x001B0042, nullptr, "SetIirFilterI2S1_cmd2"},
297 {0x001C0082, nullptr, "SetIirFilterEQ"}, 448 {0x001C0082, nullptr, "SetIirFilterEQ"},
449 {0x001D00C0, nullptr, "ReadMultiEx_SPI2"},
450 {0x001E00C2, nullptr, "WriteMultiEx_SPI2"},
298 {0x001F0000, GetHeadphoneStatus, "GetHeadphoneStatus"}, 451 {0x001F0000, GetHeadphoneStatus, "GetHeadphoneStatus"},
452 {0x00200040, nullptr, "ForceHeadphoneOut"},
299 {0x00210000, nullptr, "GetIsDspOccupied"}, 453 {0x00210000, nullptr, "GetIsDspOccupied"},
300}; 454};
301 455
@@ -304,7 +458,6 @@ const Interface::FunctionInfo FunctionTable[] = {
304 458
305Interface::Interface() { 459Interface::Interface() {
306 semaphore_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "DSP_DSP::semaphore_event"); 460 semaphore_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "DSP_DSP::semaphore_event");
307 interrupt_event = nullptr;
308 read_pipe_count = 0; 461 read_pipe_count = 0;
309 462
310 Register(FunctionTable); 463 Register(FunctionTable);
@@ -312,7 +465,7 @@ Interface::Interface() {
312 465
313Interface::~Interface() { 466Interface::~Interface() {
314 semaphore_event = nullptr; 467 semaphore_event = nullptr;
315 interrupt_event = nullptr; 468 interrupt_events.clear();
316} 469}
317 470
318} // namespace 471} // namespace
diff --git a/src/core/hle/service/dsp_dsp.h b/src/core/hle/service/dsp_dsp.h
index b6f611db5..32b89e9bb 100644
--- a/src/core/hle/service/dsp_dsp.h
+++ b/src/core/hle/service/dsp_dsp.h
@@ -23,7 +23,15 @@ public:
23 } 23 }
24}; 24};
25 25
26/// Signals that a DSP interrupt has occurred to userland code 26/// Signal all audio related interrupts.
27void SignalInterrupt(); 27void SignalAllInterrupts();
28
29/**
30 * Signal a specific audio related interrupt based on interrupt id and channel id.
31 * @param interrupt_id The interrupt id
32 * @param channel_id The channel id
33 * The significance of various values of interrupt_id and channel_id is not yet known.
34 */
35void SignalInterrupt(u32 interrupt_id, u32 channel_id);
28 36
29} // namespace 37} // namespace
diff --git a/src/core/hle/service/err_f.cpp b/src/core/hle/service/err_f.cpp
index e8c06c1cf..5f9cf6e94 100644
--- a/src/core/hle/service/err_f.cpp
+++ b/src/core/hle/service/err_f.cpp
@@ -2,9 +2,10 @@
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/bit_field.h"
6#include "common/common_types.h"
5#include "common/logging/log.h" 7#include "common/logging/log.h"
6 8
7#include "core/hle/hle.h"
8#include "core/hle/service/err_f.h" 9#include "core/hle/service/err_f.h"
9 10
10//////////////////////////////////////////////////////////////////////////////////////////////////// 11////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/service/frd/frd.cpp b/src/core/hle/service/frd/frd.cpp
index 2911ab402..c13ffd9d2 100644
--- a/src/core/hle/service/frd/frd.cpp
+++ b/src/core/hle/service/frd/frd.cpp
@@ -7,10 +7,6 @@
7#include "core/hle/service/frd/frd_a.h" 7#include "core/hle/service/frd/frd_a.h"
8#include "core/hle/service/frd/frd_u.h" 8#include "core/hle/service/frd/frd_u.h"
9 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 { 10namespace Service {
15namespace FRD { 11namespace FRD {
16 12
diff --git a/src/core/hle/service/frd/frd.h b/src/core/hle/service/frd/frd.h
index 41f7a2f6b..f9f88b444 100644
--- a/src/core/hle/service/frd/frd.h
+++ b/src/core/hle/service/frd/frd.h
@@ -4,9 +4,6 @@
4 4
5#pragma once 5#pragma once
6 6
7#include "core/hle/kernel/kernel.h"
8#include "core/hle/service/service.h"
9
10namespace Service { 7namespace Service {
11namespace FRD { 8namespace FRD {
12 9
diff --git a/src/core/hle/service/frd/frd_a.cpp b/src/core/hle/service/frd/frd_a.cpp
index 1c438a337..818d610f3 100644
--- a/src/core/hle/service/frd/frd_a.cpp
+++ b/src/core/hle/service/frd/frd_a.cpp
@@ -2,8 +2,6 @@
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 "core/hle/hle.h"
6#include "core/hle/service/frd/frd.h"
7#include "core/hle/service/frd/frd_a.h" 5#include "core/hle/service/frd/frd_a.h"
8 6
9namespace Service { 7namespace Service {
diff --git a/src/core/hle/service/frd/frd_u.cpp b/src/core/hle/service/frd/frd_u.cpp
index 3a5897d06..2c6885377 100644
--- a/src/core/hle/service/frd/frd_u.cpp
+++ b/src/core/hle/service/frd/frd_u.cpp
@@ -2,8 +2,6 @@
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 "core/hle/hle.h"
6#include "core/hle/service/frd/frd.h"
7#include "core/hle/service/frd/frd_u.h" 5#include "core/hle/service/frd/frd_u.h"
8 6
9namespace Service { 7namespace Service {
@@ -11,25 +9,58 @@ namespace FRD {
11 9
12const Interface::FunctionInfo FunctionTable[] = { 10const Interface::FunctionInfo FunctionTable[] = {
13 {0x00010000, nullptr, "HasLoggedIn"}, 11 {0x00010000, nullptr, "HasLoggedIn"},
12 {0x00020000, nullptr, "IsOnline"},
14 {0x00030000, nullptr, "Login"}, 13 {0x00030000, nullptr, "Login"},
15 {0x00040000, nullptr, "Logout"}, 14 {0x00040000, nullptr, "Logout"},
16 {0x00050000, nullptr, "GetFriendKey"}, 15 {0x00050000, nullptr, "GetMyFriendKey"},
16 {0x00060000, nullptr, "GetMyPreference"},
17 {0x00070000, nullptr, "GetMyProfile"},
17 {0x00080000, nullptr, "GetMyPresence"}, 18 {0x00080000, nullptr, "GetMyPresence"},
18 {0x00090000, nullptr, "GetMyScreenName"}, 19 {0x00090000, nullptr, "GetMyScreenName"},
19 {0x00100040, nullptr, "GetPassword"}, 20 {0x000A0000, nullptr, "GetMyMii"},
21 {0x000B0000, nullptr, "GetMyLocalAccountId"},
22 {0x000C0000, nullptr, "GetMyPlayingGame"},
23 {0x000D0000, nullptr, "GetMyFavoriteGame"},
24 {0x000E0000, nullptr, "GetMyNcPrincipalId"},
25 {0x000F0000, nullptr, "GetMyComment"},
26 {0x00100040, nullptr, "GetMyPassword"},
20 {0x00110080, nullptr, "GetFriendKeyList"}, 27 {0x00110080, nullptr, "GetFriendKeyList"},
28 {0x00120042, nullptr, "GetFriendPresence"},
29 {0x00130142, nullptr, "GetFriendScreenName"},
30 {0x00140044, nullptr, "GetFriendMii"},
31 {0x00150042, nullptr, "GetFriendProfile"},
32 {0x00160042, nullptr, "GetFriendRelationship"},
33 {0x00170042, nullptr, "GetFriendAttributeFlags"},
34 {0x00180044, nullptr, "GetFriendPlayingGame"},
21 {0x00190042, nullptr, "GetFriendFavoriteGame"}, 35 {0x00190042, nullptr, "GetFriendFavoriteGame"},
22 {0x001A00C4, nullptr, "GetFriendInfo"}, 36 {0x001A00C4, nullptr, "GetFriendInfo"},
23 {0x001B0080, nullptr, "IsOnFriendList"}, 37 {0x001B0080, nullptr, "IsIncludedInFriendList"},
24 {0x001C0042, nullptr, "DecodeLocalFriendCode"}, 38 {0x001C0042, nullptr, "UnscrambleLocalFriendCode"},
25 {0x001D0002, nullptr, "SetCurrentlyPlayingText"}, 39 {0x001D0002, nullptr, "UpdateGameModeDescription"},
40 {0x001E02C2, nullptr, "UpdateGameMode"},
41 {0x001F0042, nullptr, "SendInvitation"},
42 {0x00200002, nullptr, "AttachToEventNotification"},
43 {0x00210040, nullptr, "SetNotificationMask"},
44 {0x00220040, nullptr, "GetEventNotification"},
26 {0x00230000, nullptr, "GetLastResponseResult"}, 45 {0x00230000, nullptr, "GetLastResponseResult"},
46 {0x00240040, nullptr, "PrincipalIdToFriendCode"},
47 {0x00250080, nullptr, "FriendCodeToPrincipalId"},
48 {0x00260080, nullptr, "IsValidFriendCode"},
27 {0x00270040, nullptr, "ResultToErrorCode"}, 49 {0x00270040, nullptr, "ResultToErrorCode"},
28 {0x00280244, nullptr, "RequestGameAuthentication"}, 50 {0x00280244, nullptr, "RequestGameAuthentication"},
29 {0x00290000, nullptr, "GetGameAuthenticationData"}, 51 {0x00290000, nullptr, "GetGameAuthenticationData"},
30 {0x002A0204, nullptr, "RequestServiceLocator"}, 52 {0x002A0204, nullptr, "RequestServiceLocator"},
31 {0x002B0000, nullptr, "GetServiceLocatorData"}, 53 {0x002B0000, nullptr, "GetServiceLocatorData"},
54 {0x002C0002, nullptr, "DetectNatProperties"},
55 {0x002D0000, nullptr, "GetNatProperties"},
56 {0x002E0000, nullptr, "GetServerTimeInterval"},
57 {0x002F0040, nullptr, "AllowHalfAwake"},
58 {0x00300000, nullptr, "GetServerTypes"},
59 {0x00310082, nullptr, "GetFriendComment"},
32 {0x00320042, nullptr, "SetClientSdkVersion"}, 60 {0x00320042, nullptr, "SetClientSdkVersion"},
61 {0x00330000, nullptr, "GetMyApproachContext"},
62 {0x00340046, nullptr, "AddFriendWithApproach"},
63 {0x00350082, nullptr, "DecryptApproachContext"},
33}; 64};
34 65
35FRD_U_Interface::FRD_U_Interface() { 66FRD_U_Interface::FRD_U_Interface() {
diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp
index b3fa89302..632620a56 100644
--- a/src/core/hle/service/fs/fs_user.cpp
+++ b/src/core/hle/service/fs/fs_user.cpp
@@ -708,96 +708,114 @@ static void GetPriority(Service::Interface* self) {
708} 708}
709 709
710const Interface::FunctionInfo FunctionTable[] = { 710const Interface::FunctionInfo FunctionTable[] = {
711 {0x000100C6, nullptr, "Dummy1"}, 711 {0x000100C6, nullptr, "Dummy1"},
712 {0x040100C4, nullptr, "Control"}, 712 {0x040100C4, nullptr, "Control"},
713 {0x08010002, Initialize, "Initialize"}, 713 {0x08010002, Initialize, "Initialize"},
714 {0x080201C2, OpenFile, "OpenFile"}, 714 {0x080201C2, OpenFile, "OpenFile"},
715 {0x08030204, OpenFileDirectly, "OpenFileDirectly"}, 715 {0x08030204, OpenFileDirectly, "OpenFileDirectly"},
716 {0x08040142, DeleteFile, "DeleteFile"}, 716 {0x08040142, DeleteFile, "DeleteFile"},
717 {0x08050244, RenameFile, "RenameFile"}, 717 {0x08050244, RenameFile, "RenameFile"},
718 {0x08060142, DeleteDirectory, "DeleteDirectory"}, 718 {0x08060142, DeleteDirectory, "DeleteDirectory"},
719 {0x08070142, nullptr, "DeleteDirectoryRecursively"}, 719 {0x08070142, nullptr, "DeleteDirectoryRecursively"},
720 {0x08080202, CreateFile, "CreateFile"}, 720 {0x08080202, CreateFile, "CreateFile"},
721 {0x08090182, CreateDirectory, "CreateDirectory"}, 721 {0x08090182, CreateDirectory, "CreateDirectory"},
722 {0x080A0244, RenameDirectory, "RenameDirectory"}, 722 {0x080A0244, RenameDirectory, "RenameDirectory"},
723 {0x080B0102, OpenDirectory, "OpenDirectory"}, 723 {0x080B0102, OpenDirectory, "OpenDirectory"},
724 {0x080C00C2, OpenArchive, "OpenArchive"}, 724 {0x080C00C2, OpenArchive, "OpenArchive"},
725 {0x080D0144, nullptr, "ControlArchive"}, 725 {0x080D0144, nullptr, "ControlArchive"},
726 {0x080E0080, CloseArchive, "CloseArchive"}, 726 {0x080E0080, CloseArchive, "CloseArchive"},
727 {0x080F0180, FormatThisUserSaveData,"FormatThisUserSaveData"}, 727 {0x080F0180, FormatThisUserSaveData, "FormatThisUserSaveData"},
728 {0x08100200, nullptr, "CreateSystemSaveData"}, 728 {0x08100200, nullptr, "CreateSystemSaveData"},
729 {0x08110040, nullptr, "DeleteSystemSaveData"}, 729 {0x08110040, nullptr, "DeleteSystemSaveData"},
730 {0x08120080, GetFreeBytes, "GetFreeBytes"}, 730 {0x08120080, GetFreeBytes, "GetFreeBytes"},
731 {0x08130000, nullptr, "GetCardType"}, 731 {0x08130000, nullptr, "GetCardType"},
732 {0x08140000, nullptr, "GetSdmcArchiveResource"}, 732 {0x08140000, nullptr, "GetSdmcArchiveResource"},
733 {0x08150000, nullptr, "GetNandArchiveResource"}, 733 {0x08150000, nullptr, "GetNandArchiveResource"},
734 {0x08160000, nullptr, "GetSdmcFatfsErro"}, 734 {0x08160000, nullptr, "GetSdmcFatfsError"},
735 {0x08170000, IsSdmcDetected, "IsSdmcDetected"}, 735 {0x08170000, IsSdmcDetected, "IsSdmcDetected"},
736 {0x08180000, IsSdmcWriteable, "IsSdmcWritable"}, 736 {0x08180000, IsSdmcWriteable, "IsSdmcWritable"},
737 {0x08190042, nullptr, "GetSdmcCid"}, 737 {0x08190042, nullptr, "GetSdmcCid"},
738 {0x081A0042, nullptr, "GetNandCid"}, 738 {0x081A0042, nullptr, "GetNandCid"},
739 {0x081B0000, nullptr, "GetSdmcSpeedInfo"}, 739 {0x081B0000, nullptr, "GetSdmcSpeedInfo"},
740 {0x081C0000, nullptr, "GetNandSpeedInfo"}, 740 {0x081C0000, nullptr, "GetNandSpeedInfo"},
741 {0x081D0042, nullptr, "GetSdmcLog"}, 741 {0x081D0042, nullptr, "GetSdmcLog"},
742 {0x081E0042, nullptr, "GetNandLog"}, 742 {0x081E0042, nullptr, "GetNandLog"},
743 {0x081F0000, nullptr, "ClearSdmcLog"}, 743 {0x081F0000, nullptr, "ClearSdmcLog"},
744 {0x08200000, nullptr, "ClearNandLog"}, 744 {0x08200000, nullptr, "ClearNandLog"},
745 {0x08210000, CardSlotIsInserted, "CardSlotIsInserted"}, 745 {0x08210000, CardSlotIsInserted, "CardSlotIsInserted"},
746 {0x08220000, nullptr, "CardSlotPowerOn"}, 746 {0x08220000, nullptr, "CardSlotPowerOn"},
747 {0x08230000, nullptr, "CardSlotPowerOff"}, 747 {0x08230000, nullptr, "CardSlotPowerOff"},
748 {0x08240000, nullptr, "CardSlotGetCardIFPowerStatus"}, 748 {0x08240000, nullptr, "CardSlotGetCardIFPowerStatus"},
749 {0x08250040, nullptr, "CardNorDirectCommand"}, 749 {0x08250040, nullptr, "CardNorDirectCommand"},
750 {0x08260080, nullptr, "CardNorDirectCommandWithAddress"}, 750 {0x08260080, nullptr, "CardNorDirectCommandWithAddress"},
751 {0x08270082, nullptr, "CardNorDirectRead"}, 751 {0x08270082, nullptr, "CardNorDirectRead"},
752 {0x082800C2, nullptr, "CardNorDirectReadWithAddress"}, 752 {0x082800C2, nullptr, "CardNorDirectReadWithAddress"},
753 {0x08290082, nullptr, "CardNorDirectWrite"}, 753 {0x08290082, nullptr, "CardNorDirectWrite"},
754 {0x082A00C2, nullptr, "CardNorDirectWriteWithAddress"}, 754 {0x082A00C2, nullptr, "CardNorDirectWriteWithAddress"},
755 {0x082B00C2, nullptr, "CardNorDirectRead_4xIO"}, 755 {0x082B00C2, nullptr, "CardNorDirectRead_4xIO"},
756 {0x082C0082, nullptr, "CardNorDirectCpuWriteWithoutVerify"}, 756 {0x082C0082, nullptr, "CardNorDirectCpuWriteWithoutVerify"},
757 {0x082D0040, nullptr, "CardNorDirectSectorEraseWithoutVerify"}, 757 {0x082D0040, nullptr, "CardNorDirectSectorEraseWithoutVerify"},
758 {0x082E0040, nullptr, "GetProductInfo"}, 758 {0x082E0040, nullptr, "GetProductInfo"},
759 {0x082F0040, nullptr, "GetProgramLaunchInfo"}, 759 {0x082F0040, nullptr, "GetProgramLaunchInfo"},
760 {0x08300182, nullptr, "CreateExtSaveData"}, 760 {0x08300182, nullptr, "CreateExtSaveData"},
761 {0x08310180, nullptr, "CreateSharedExtSaveData"}, 761 {0x08310180, nullptr, "CreateSharedExtSaveData"},
762 {0x08320102, nullptr, "ReadExtSaveDataIcon"}, 762 {0x08320102, nullptr, "ReadExtSaveDataIcon"},
763 {0x08330082, nullptr, "EnumerateExtSaveData"}, 763 {0x08330082, nullptr, "EnumerateExtSaveData"},
764 {0x08340082, nullptr, "EnumerateSharedExtSaveData"}, 764 {0x08340082, nullptr, "EnumerateSharedExtSaveData"},
765 {0x08350080, nullptr, "DeleteExtSaveData"}, 765 {0x08350080, nullptr, "DeleteExtSaveData"},
766 {0x08360080, nullptr, "DeleteSharedExtSaveData"}, 766 {0x08360080, nullptr, "DeleteSharedExtSaveData"},
767 {0x08370040, nullptr, "SetCardSpiBaudRate"}, 767 {0x08370040, nullptr, "SetCardSpiBaudRate"},
768 {0x08380040, nullptr, "SetCardSpiBusMode"}, 768 {0x08380040, nullptr, "SetCardSpiBusMode"},
769 {0x08390000, nullptr, "SendInitializeInfoTo9"}, 769 {0x08390000, nullptr, "SendInitializeInfoTo9"},
770 {0x083A0100, nullptr, "GetSpecialContentIndex"}, 770 {0x083A0100, nullptr, "GetSpecialContentIndex"},
771 {0x083B00C2, nullptr, "GetLegacyRomHeader"}, 771 {0x083B00C2, nullptr, "GetLegacyRomHeader"},
772 {0x083C00C2, nullptr, "GetLegacyBannerData"}, 772 {0x083C00C2, nullptr, "GetLegacyBannerData"},
773 {0x083D0100, nullptr, "CheckAuthorityToAccessExtSaveData"}, 773 {0x083D0100, nullptr, "CheckAuthorityToAccessExtSaveData"},
774 {0x083E00C2, nullptr, "QueryTotalQuotaSize"}, 774 {0x083E00C2, nullptr, "QueryTotalQuotaSize"},
775 {0x083F00C0, nullptr, "GetExtDataBlockSize"}, 775 {0x083F00C0, nullptr, "GetExtDataBlockSize"},
776 {0x08400040, nullptr, "AbnegateAccessRight"}, 776 {0x08400040, nullptr, "AbnegateAccessRight"},
777 {0x08410000, nullptr, "DeleteSdmcRoot"}, 777 {0x08410000, nullptr, "DeleteSdmcRoot"},
778 {0x08420040, nullptr, "DeleteAllExtSaveDataOnNand"}, 778 {0x08420040, nullptr, "DeleteAllExtSaveDataOnNand"},
779 {0x08430000, nullptr, "InitializeCtrFileSystem"}, 779 {0x08430000, nullptr, "InitializeCtrFileSystem"},
780 {0x08440000, nullptr, "CreateSeed"}, 780 {0x08440000, nullptr, "CreateSeed"},
781 {0x084500C2, nullptr, "GetFormatInfo"}, 781 {0x084500C2, nullptr, "GetFormatInfo"},
782 {0x08460102, nullptr, "GetLegacyRomHeader2"}, 782 {0x08460102, nullptr, "GetLegacyRomHeader2"},
783 {0x08470180, nullptr, "FormatCtrCardUserSaveData"}, 783 {0x08470180, nullptr, "FormatCtrCardUserSaveData"},
784 {0x08480042, nullptr, "GetSdmcCtrRootPath"}, 784 {0x08480042, nullptr, "GetSdmcCtrRootPath"},
785 {0x08490040, nullptr, "GetArchiveResource"}, 785 {0x08490040, nullptr, "GetArchiveResource"},
786 {0x084A0002, nullptr, "ExportIntegrityVerificationSeed"}, 786 {0x084A0002, nullptr, "ExportIntegrityVerificationSeed"},
787 {0x084B0002, nullptr, "ImportIntegrityVerificationSeed"}, 787 {0x084B0002, nullptr, "ImportIntegrityVerificationSeed"},
788 {0x084C0242, FormatSaveData, "FormatSaveData"}, 788 {0x084C0242, FormatSaveData, "FormatSaveData"},
789 {0x084D0102, nullptr, "GetLegacySubBannerData"}, 789 {0x084D0102, nullptr, "GetLegacySubBannerData"},
790 {0x084E0342, nullptr, "UpdateSha256Context"}, 790 {0x084E0342, nullptr, "UpdateSha256Context"},
791 {0x084F0102, nullptr, "ReadSpecialFile"}, 791 {0x084F0102, nullptr, "ReadSpecialFile"},
792 {0x08500040, nullptr, "GetSpecialFileSize"}, 792 {0x08500040, nullptr, "GetSpecialFileSize"},
793 {0x08510242, CreateExtSaveData, "CreateExtSaveData"}, 793 {0x08510242, CreateExtSaveData, "CreateExtSaveData"},
794 {0x08520100, DeleteExtSaveData, "DeleteExtSaveData"}, 794 {0x08520100, DeleteExtSaveData, "DeleteExtSaveData"},
795 {0x08560240, CreateSystemSaveData, "CreateSystemSaveData"}, 795 {0x08530142, nullptr, "ReadExtSaveDataIcon"},
796 {0x08570080, DeleteSystemSaveData, "DeleteSystemSaveData"}, 796 {0x085400C0, nullptr, "GetExtDataBlockSize"},
797 {0x08580000, nullptr, "GetMovableSedHashedKeyYRandomData"}, 797 {0x08550102, nullptr, "EnumerateExtSaveData"},
798 {0x08560240, CreateSystemSaveData, "CreateSystemSaveData"},
799 {0x08570080, DeleteSystemSaveData, "DeleteSystemSaveData"},
800 {0x08580000, nullptr, "StartDeviceMoveAsSource"},
801 {0x08590200, nullptr, "StartDeviceMoveAsDestination"},
802 {0x085A00C0, nullptr, "SetArchivePriority"},
803 {0x085B0080, nullptr, "GetArchivePriority"},
804 {0x085C00C0, nullptr, "SetCtrCardLatencyParameter"},
805 {0x085D01C0, nullptr, "SetFsCompatibilityInfo"},
806 {0x085E0040, nullptr, "ResetCardCompatibilityParameter"},
807 {0x085F0040, nullptr, "SwitchCleanupInvalidSaveData"},
808 {0x08600042, nullptr, "EnumerateSystemSaveData"},
798 {0x08610042, InitializeWithSdkVersion, "InitializeWithSdkVersion"}, 809 {0x08610042, InitializeWithSdkVersion, "InitializeWithSdkVersion"},
799 {0x08620040, SetPriority, "SetPriority"}, 810 {0x08620040, SetPriority, "SetPriority"},
800 {0x08630000, GetPriority, "GetPriority"}, 811 {0x08630000, GetPriority, "GetPriority"},
812 {0x08640000, nullptr, "GetNandInfo"},
813 {0x08650140, nullptr, "SetSaveDataSecureValue"},
814 {0x086600C0, nullptr, "GetSaveDataSecureValue"},
815 {0x086700C4, nullptr, "ControlSecureSave"},
816 {0x08680000, nullptr, "GetMediaType"},
817 {0x08690000, nullptr, "GetNandEraseCount"},
818 {0x086A0082, nullptr, "ReadNandReport"}
801}; 819};
802 820
803//////////////////////////////////////////////////////////////////////////////////////////////////// 821////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp
index 481da0c9f..2ace2cade 100644
--- a/src/core/hle/service/gsp_gpu.cpp
+++ b/src/core/hle/service/gsp_gpu.cpp
@@ -275,7 +275,7 @@ static void FlushDataCache(Service::Interface* self) {
275 u32 size = cmd_buff[2]; 275 u32 size = cmd_buff[2];
276 u32 process = cmd_buff[4]; 276 u32 process = cmd_buff[4];
277 277
278 VideoCore::g_renderer->hw_rasterizer->NotifyFlush(Memory::VirtualToPhysicalAddress(address), size); 278 VideoCore::g_renderer->Rasterizer()->InvalidateRegion(Memory::VirtualToPhysicalAddress(address), size);
279 279
280 // TODO(purpasmart96): Verify return header on HW 280 // TODO(purpasmart96): Verify return header on HW
281 281
@@ -320,7 +320,7 @@ static void RegisterInterruptRelayQueue(Service::Interface* self) {
320 * @todo This probably does not belong in the GSP module, instead move to video_core 320 * @todo This probably does not belong in the GSP module, instead move to video_core
321 */ 321 */
322void SignalInterrupt(InterruptId interrupt_id) { 322void SignalInterrupt(InterruptId interrupt_id) {
323 if (0 == g_interrupt_event) { 323 if (nullptr == g_interrupt_event) {
324 LOG_WARNING(Service_GSP, "cannot synchronize until GSP event has been created!"); 324 LOG_WARNING(Service_GSP, "cannot synchronize until GSP event has been created!");
325 return; 325 return;
326 } 326 }
@@ -347,7 +347,7 @@ void SignalInterrupt(InterruptId interrupt_id) {
347 FrameBufferUpdate* info = GetFrameBufferInfo(thread_id, screen_id); 347 FrameBufferUpdate* info = GetFrameBufferInfo(thread_id, screen_id);
348 if (info->is_dirty) { 348 if (info->is_dirty) {
349 SetBufferSwap(screen_id, info->framebuffer_info[info->index]); 349 SetBufferSwap(screen_id, info->framebuffer_info[info->index]);
350 info->is_dirty = false; 350 info->is_dirty.Assign(false);
351 } 351 }
352 } 352 }
353 } 353 }
@@ -365,7 +365,7 @@ static void ExecuteCommand(const Command& command, u32 thread_id) {
365 365
366 // GX request DMA - typically used for copying memory from GSP heap to VRAM 366 // GX request DMA - typically used for copying memory from GSP heap to VRAM
367 case CommandId::REQUEST_DMA: 367 case CommandId::REQUEST_DMA:
368 VideoCore::g_renderer->hw_rasterizer->NotifyPreRead(Memory::VirtualToPhysicalAddress(command.dma_request.source_address), 368 VideoCore::g_renderer->Rasterizer()->FlushRegion(Memory::VirtualToPhysicalAddress(command.dma_request.source_address),
369 command.dma_request.size); 369 command.dma_request.size);
370 370
371 memcpy(Memory::GetPointer(command.dma_request.dest_address), 371 memcpy(Memory::GetPointer(command.dma_request.dest_address),
@@ -373,7 +373,7 @@ static void ExecuteCommand(const Command& command, u32 thread_id) {
373 command.dma_request.size); 373 command.dma_request.size);
374 SignalInterrupt(InterruptId::DMA); 374 SignalInterrupt(InterruptId::DMA);
375 375
376 VideoCore::g_renderer->hw_rasterizer->NotifyFlush(Memory::VirtualToPhysicalAddress(command.dma_request.dest_address), 376 VideoCore::g_renderer->Rasterizer()->InvalidateRegion(Memory::VirtualToPhysicalAddress(command.dma_request.dest_address),
377 command.dma_request.size); 377 command.dma_request.size);
378 break; 378 break;
379 379
@@ -467,7 +467,7 @@ static void ExecuteCommand(const Command& command, u32 thread_id) {
467 if (region.size == 0) 467 if (region.size == 0)
468 break; 468 break;
469 469
470 VideoCore::g_renderer->hw_rasterizer->NotifyFlush( 470 VideoCore::g_renderer->Rasterizer()->InvalidateRegion(
471 Memory::VirtualToPhysicalAddress(region.address), region.size); 471 Memory::VirtualToPhysicalAddress(region.address), region.size);
472 } 472 }
473 break; 473 break;
@@ -499,7 +499,7 @@ static void SetLcdForceBlack(Service::Interface* self) {
499 499
500 // Since data is already zeroed, there is no need to explicitly set 500 // Since data is already zeroed, there is no need to explicitly set
501 // the color to black (all zero). 501 // the color to black (all zero).
502 data.is_enabled = enable_black; 502 data.is_enabled.Assign(enable_black);
503 503
504 LCD::Write(HW::VADDR_LCD + 4 * LCD_REG_INDEX(color_fill_top), data.raw); // Top LCD 504 LCD::Write(HW::VADDR_LCD + 4 * LCD_REG_INDEX(color_fill_top), data.raw); // Top LCD
505 LCD::Write(HW::VADDR_LCD + 4 * LCD_REG_INDEX(color_fill_bottom), data.raw); // Bottom LCD 505 LCD::Write(HW::VADDR_LCD + 4 * LCD_REG_INDEX(color_fill_bottom), data.raw); // Bottom LCD
@@ -521,7 +521,7 @@ static void TriggerCmdReqQueue(Service::Interface* self) {
521 ExecuteCommand(command_buffer->commands[i], thread_id); 521 ExecuteCommand(command_buffer->commands[i], thread_id);
522 522
523 // Indicates that command has completed 523 // Indicates that command has completed
524 command_buffer->number_commands = command_buffer->number_commands - 1; 524 command_buffer->number_commands.Assign(command_buffer->number_commands - 1);
525 } 525 }
526 } 526 }
527 527
diff --git a/src/core/hle/service/gsp_lcd.cpp b/src/core/hle/service/gsp_lcd.cpp
index 9e36732b4..c700c21c5 100644
--- a/src/core/hle/service/gsp_lcd.cpp
+++ b/src/core/hle/service/gsp_lcd.cpp
@@ -2,8 +2,6 @@
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/bit_field.h"
6
7#include "core/hle/service/gsp_lcd.h" 5#include "core/hle/service/gsp_lcd.h"
8 6
9//////////////////////////////////////////////////////////////////////////////////////////////////// 7////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -11,14 +9,19 @@
11 9
12namespace GSP_LCD { 10namespace GSP_LCD {
13 11
14/*const Interface::FunctionInfo FunctionTable[] = { 12const Interface::FunctionInfo FunctionTable[] = {
15};*/ 13 {0x000F0000, nullptr, "PowerOnAllBacklights"},
14 {0x00100000, nullptr, "PowerOffAllBacklights"},
15 {0x00110040, nullptr, "PowerOnBacklight"},
16 {0x00120040, nullptr, "PowerOffBacklight"},
17 {0x00130040, nullptr, "SetLedForceOff"}
18};
16 19
17//////////////////////////////////////////////////////////////////////////////////////////////////// 20////////////////////////////////////////////////////////////////////////////////////////////////////
18// Interface class 21// Interface class
19 22
20Interface::Interface() { 23Interface::Interface() {
21 //Register(FunctionTable); 24 Register(FunctionTable);
22} 25}
23 26
24} // namespace 27} // namespace
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 2e1e5c3e9..11d7e69a1 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -13,7 +13,6 @@
13#include "core/core_timing.h" 13#include "core/core_timing.h"
14#include "core/hle/kernel/event.h" 14#include "core/hle/kernel/event.h"
15#include "core/hle/kernel/shared_memory.h" 15#include "core/hle/kernel/shared_memory.h"
16#include "core/hle/hle.h"
17 16
18#include "video_core/video_core.h" 17#include "video_core/video_core.h"
19 18
@@ -106,7 +105,7 @@ void Update() {
106 bool pressed = false; 105 bool pressed = false;
107 106
108 std::tie(touch_entry->x, touch_entry->y, pressed) = VideoCore::g_emu_window->GetTouchState(); 107 std::tie(touch_entry->x, touch_entry->y, pressed) = VideoCore::g_emu_window->GetTouchState();
109 touch_entry->valid = pressed ? 1 : 0; 108 touch_entry->valid.Assign(pressed ? 1 : 0);
110 109
111 // TODO(bunnei): We're not doing anything with offset 0xA8 + 0x18 of HID SharedMemory, which 110 // TODO(bunnei): We're not doing anything with offset 0xA8 + 0x18 of HID SharedMemory, which
112 // supposedly is "Touch-screen entry, which contains the raw coordinate data prior to being 111 // supposedly is "Touch-screen entry, which contains the raw coordinate data prior to being
diff --git a/src/core/hle/service/hid/hid_spvr.cpp b/src/core/hle/service/hid/hid_spvr.cpp
index 532931ae0..c50f597eb 100644
--- a/src/core/hle/service/hid/hid_spvr.cpp
+++ b/src/core/hle/service/hid/hid_spvr.cpp
@@ -2,7 +2,6 @@
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 "core/hle/hle.h"
6#include "core/hle/service/hid/hid.h" 5#include "core/hle/service/hid/hid.h"
7#include "core/hle/service/hid/hid_spvr.h" 6#include "core/hle/service/hid/hid_spvr.h"
8 7
diff --git a/src/core/hle/service/hid/hid_user.cpp b/src/core/hle/service/hid/hid_user.cpp
index fbfb9e885..bbdde2abb 100644
--- a/src/core/hle/service/hid/hid_user.cpp
+++ b/src/core/hle/service/hid/hid_user.cpp
@@ -2,7 +2,6 @@
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 "core/hle/hle.h"
6#include "core/hle/service/hid/hid.h" 5#include "core/hle/service/hid/hid.h"
7#include "core/hle/service/hid/hid_user.h" 6#include "core/hle/service/hid/hid_user.h"
8 7
@@ -11,6 +10,8 @@ namespace HID {
11 10
12const Interface::FunctionInfo FunctionTable[] = { 11const Interface::FunctionInfo FunctionTable[] = {
13 {0x000A0000, GetIPCHandles, "GetIPCHandles"}, 12 {0x000A0000, GetIPCHandles, "GetIPCHandles"},
13 {0x000B0000, nullptr, "StartAnalogStickCalibration"},
14 {0x000E0000, nullptr, "GetAnalogStickCalibrateParam"},
14 {0x00110000, EnableAccelerometer, "EnableAccelerometer"}, 15 {0x00110000, EnableAccelerometer, "EnableAccelerometer"},
15 {0x00120000, DisableAccelerometer, "DisableAccelerometer"}, 16 {0x00120000, DisableAccelerometer, "DisableAccelerometer"},
16 {0x00130000, EnableGyroscopeLow, "EnableGyroscopeLow"}, 17 {0x00130000, EnableGyroscopeLow, "EnableGyroscopeLow"},
diff --git a/src/core/hle/service/http_c.cpp b/src/core/hle/service/http_c.cpp
index 0a3aba0a0..0855ab227 100644
--- a/src/core/hle/service/http_c.cpp
+++ b/src/core/hle/service/http_c.cpp
@@ -2,7 +2,6 @@
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 "core/hle/hle.h"
6#include "core/hle/service/http_c.h" 5#include "core/hle/service/http_c.h"
7 6
8//////////////////////////////////////////////////////////////////////////////////////////////////// 7////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -47,10 +46,20 @@ const Interface::FunctionInfo FunctionTable[] = {
47 {0x00220040, nullptr, "GetResponseStatusCode"}, 46 {0x00220040, nullptr, "GetResponseStatusCode"},
48 {0x002300C0, nullptr, "GetResponseStatusCodeTimeout"}, 47 {0x002300C0, nullptr, "GetResponseStatusCodeTimeout"},
49 {0x00240082, nullptr, "AddTrustedRootCA"}, 48 {0x00240082, nullptr, "AddTrustedRootCA"},
49 {0x00250080, nullptr, "AddDefaultCert"},
50 {0x00260080, nullptr, "SelectRootCertChain"},
51 {0x002700C4, nullptr, "SetClientCert"},
52 {0x002B0080, nullptr, "SetSSLOpt"},
53 {0x002C0080, nullptr, "SetSSLClearOpt"},
54 {0x002D0000, nullptr, "CreateRootCertChain"},
55 {0x002E0040, nullptr, "DestroyRootCertChain"},
56 {0x002F0082, nullptr, "RootCertChainAddCert"},
57 {0x00300080, nullptr, "RootCertChainAddDefaultCert"},
50 {0x00350186, nullptr, "SetDefaultProxy"}, 58 {0x00350186, nullptr, "SetDefaultProxy"},
51 {0x00360000, nullptr, "ClearDNSCache"}, 59 {0x00360000, nullptr, "ClearDNSCache"},
52 {0x00370080, nullptr, "SetKeepAlive"}, 60 {0x00370080, nullptr, "SetKeepAlive"},
53 {0x003800C0, nullptr, "Finalize"}, 61 {0x003800C0, nullptr, "SetPostDataTypeSize"},
62 {0x00390000, nullptr, "Finalize"},
54}; 63};
55 64
56//////////////////////////////////////////////////////////////////////////////////////////////////// 65////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/service/ir/ir.cpp b/src/core/hle/service/ir/ir.cpp
index adfbb258d..c2121cb2e 100644
--- a/src/core/hle/service/ir/ir.cpp
+++ b/src/core/hle/service/ir/ir.cpp
@@ -2,21 +2,22 @@
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 "core/hle/kernel/event.h"
6#include "core/hle/kernel/shared_memory.h"
7
5#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
6#include "core/hle/service/ir/ir.h" 9#include "core/hle/service/ir/ir.h"
7#include "core/hle/service/ir/ir_rst.h" 10#include "core/hle/service/ir/ir_rst.h"
8#include "core/hle/service/ir/ir_u.h" 11#include "core/hle/service/ir/ir_u.h"
9#include "core/hle/service/ir/ir_user.h" 12#include "core/hle/service/ir/ir_user.h"
10 13
11#include "core/hle/hle.h"
12#include "core/hle/kernel/event.h"
13#include "core/hle/kernel/shared_memory.h"
14
15namespace Service { 14namespace Service {
16namespace IR { 15namespace IR {
17 16
18static Kernel::SharedPtr<Kernel::Event> handle_event; 17static Kernel::SharedPtr<Kernel::Event> handle_event;
18static Kernel::SharedPtr<Kernel::Event> conn_status_event;
19static Kernel::SharedPtr<Kernel::SharedMemory> shared_memory; 19static Kernel::SharedPtr<Kernel::SharedMemory> shared_memory;
20static Kernel::SharedPtr<Kernel::SharedMemory> transfer_shared_memory;
20 21
21void GetHandles(Service::Interface* self) { 22void GetHandles(Service::Interface* self) {
22 u32* cmd_buff = Kernel::GetCommandBuffer(); 23 u32* cmd_buff = Kernel::GetCommandBuffer();
@@ -27,6 +28,64 @@ void GetHandles(Service::Interface* self) {
27 cmd_buff[4] = Kernel::g_handle_table.Create(Service::IR::handle_event).MoveFrom(); 28 cmd_buff[4] = Kernel::g_handle_table.Create(Service::IR::handle_event).MoveFrom();
28} 29}
29 30
31void InitializeIrNopShared(Interface* self) {
32 u32* cmd_buff = Kernel::GetCommandBuffer();
33
34 u32 transfer_buff_size = cmd_buff[1];
35 u32 recv_buff_size = cmd_buff[2];
36 u32 unk1 = cmd_buff[3];
37 u32 send_buff_size = cmd_buff[4];
38 u32 unk2 = cmd_buff[5];
39 u8 baud_rate = cmd_buff[6] & 0xFF;
40 Handle handle = cmd_buff[8];
41
42 if(Kernel::g_handle_table.IsValid(handle)) {
43 transfer_shared_memory = Kernel::g_handle_table.Get<Kernel::SharedMemory>(handle);
44 transfer_shared_memory->name = "IR:TransferSharedMemory";
45 }
46
47 cmd_buff[1] = RESULT_SUCCESS.raw;
48
49 LOG_WARNING(Service_IR, "(STUBBED) called, transfer_buff_size=%d, recv_buff_size=%d, "
50 "unk1=%d, send_buff_size=%d, unk2=%d, baud_rate=%u, handle=0x%08X",
51 transfer_buff_size, recv_buff_size, unk1, send_buff_size, unk2, baud_rate, handle);
52}
53
54void RequireConnection(Interface* self) {
55 u32* cmd_buff = Kernel::GetCommandBuffer();
56
57 conn_status_event->Signal();
58
59 cmd_buff[1] = RESULT_SUCCESS.raw;
60
61 LOG_WARNING(Service_IR, "(STUBBED) called");
62}
63
64void Disconnect(Interface* self) {
65 u32* cmd_buff = Kernel::GetCommandBuffer();
66
67 cmd_buff[1] = RESULT_SUCCESS.raw;
68
69 LOG_WARNING(Service_IR, "(STUBBED) called");
70}
71
72void GetConnectionStatusEvent(Interface* self) {
73 u32* cmd_buff = Kernel::GetCommandBuffer();
74
75 cmd_buff[1] = RESULT_SUCCESS.raw;
76 cmd_buff[3] = Kernel::g_handle_table.Create(Service::IR::conn_status_event).MoveFrom();
77
78 LOG_WARNING(Service_IR, "(STUBBED) called");
79}
80
81void FinalizeIrNop(Interface* self) {
82 u32* cmd_buff = Kernel::GetCommandBuffer();
83
84 cmd_buff[1] = RESULT_SUCCESS.raw;
85
86 LOG_WARNING(Service_IR, "(STUBBED) called");
87}
88
30void Init() { 89void Init() {
31 using namespace Kernel; 90 using namespace Kernel;
32 91
@@ -36,15 +95,19 @@ void Init() {
36 95
37 using Kernel::MemoryPermission; 96 using Kernel::MemoryPermission;
38 shared_memory = SharedMemory::Create(0x1000, Kernel::MemoryPermission::ReadWrite, 97 shared_memory = SharedMemory::Create(0x1000, Kernel::MemoryPermission::ReadWrite,
39 Kernel::MemoryPermission::ReadWrite, "IR:SharedMemory"); 98 Kernel::MemoryPermission::ReadWrite, "IR:SharedMemory");
99 transfer_shared_memory = nullptr;
40 100
41 // Create event handle(s) 101 // Create event handle(s)
42 handle_event = Event::Create(RESETTYPE_ONESHOT, "IR:HandleEvent"); 102 handle_event = Event::Create(RESETTYPE_ONESHOT, "IR:HandleEvent");
103 conn_status_event = Event::Create(RESETTYPE_ONESHOT, "IR:ConnectionStatusEvent");
43} 104}
44 105
45void Shutdown() { 106void Shutdown() {
107 transfer_shared_memory = nullptr;
46 shared_memory = nullptr; 108 shared_memory = nullptr;
47 handle_event = nullptr; 109 handle_event = nullptr;
110 conn_status_event = nullptr;
48} 111}
49 112
50} // namespace IR 113} // namespace IR
diff --git a/src/core/hle/service/ir/ir.h b/src/core/hle/service/ir/ir.h
index c16d963e7..72d44ce60 100644
--- a/src/core/hle/service/ir/ir.h
+++ b/src/core/hle/service/ir/ir.h
@@ -4,10 +4,10 @@
4 4
5#pragma once 5#pragma once
6 6
7#include "core/hle/kernel/kernel.h"
8#include "core/hle/service/service.h"
9
10namespace Service { 7namespace Service {
8
9class Interface;
10
11namespace IR { 11namespace IR {
12 12
13/** 13/**
@@ -20,6 +20,53 @@ namespace IR {
20 */ 20 */
21void GetHandles(Interface* self); 21void GetHandles(Interface* self);
22 22
23/**
24 * IR::InitializeIrNopShared service function
25 * Inputs:
26 * 1 : Size of transfer buffer
27 * 2 : Recv buffer size
28 * 3 : unknown
29 * 4 : Send buffer size
30 * 5 : unknown
31 * 6 : BaudRate (u8)
32 * 7 : 0
33 * 8 : Handle of transfer shared memory
34 * Outputs:
35 * 1 : Result of function, 0 on success, otherwise error code
36 */
37void InitializeIrNopShared(Interface* self);
38
39/**
40 * IR::FinalizeIrNop service function
41 * Outputs:
42 * 1 : Result of function, 0 on success, otherwise error code
43 */
44void FinalizeIrNop(Interface* self);
45
46/**
47 * IR::GetConnectionStatusEvent service function
48 * Outputs:
49 * 1 : Result of function, 0 on success, otherwise error code
50 * 2 : Connection Status Event handle
51 */
52void GetConnectionStatusEvent(Interface* self);
53
54/**
55 * IR::Disconnect service function
56 * Outputs:
57 * 1 : Result of function, 0 on success, otherwise error code
58 */
59void Disconnect(Interface* self);
60
61/**
62 * IR::RequireConnection service function
63 * Inputs:
64 * 1 : unknown (u8), looks like always 1
65 * Outputs:
66 * 1 : Result of function, 0 on success, otherwise error code
67 */
68void RequireConnection(Interface* self);
69
23/// Initialize IR service 70/// Initialize IR service
24void Init(); 71void Init();
25 72
diff --git a/src/core/hle/service/ir/ir_rst.cpp b/src/core/hle/service/ir/ir_rst.cpp
index 96ae63420..c0300f109 100644
--- a/src/core/hle/service/ir/ir_rst.cpp
+++ b/src/core/hle/service/ir/ir_rst.cpp
@@ -2,7 +2,6 @@
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 "core/hle/hle.h"
6#include "core/hle/service/ir/ir.h" 5#include "core/hle/service/ir/ir.h"
7#include "core/hle/service/ir/ir_rst.h" 6#include "core/hle/service/ir/ir_rst.h"
8 7
diff --git a/src/core/hle/service/ir/ir_u.cpp b/src/core/hle/service/ir/ir_u.cpp
index 1b1e3078b..96f76cb83 100644
--- a/src/core/hle/service/ir/ir_u.cpp
+++ b/src/core/hle/service/ir/ir_u.cpp
@@ -2,8 +2,6 @@
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 "core/hle/hle.h"
6#include "core/hle/service/ir/ir.h"
7#include "core/hle/service/ir/ir_u.h" 5#include "core/hle/service/ir/ir_u.h"
8 6
9namespace Service { 7namespace Service {
diff --git a/src/core/hle/service/ir/ir_user.cpp b/src/core/hle/service/ir/ir_user.cpp
index 8e3ff140f..06a601029 100644
--- a/src/core/hle/service/ir/ir_user.cpp
+++ b/src/core/hle/service/ir/ir_user.cpp
@@ -2,7 +2,6 @@
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 "core/hle/hle.h"
6#include "core/hle/service/ir/ir.h" 5#include "core/hle/service/ir/ir.h"
7#include "core/hle/service/ir/ir_user.h" 6#include "core/hle/service/ir/ir_user.h"
8 7
@@ -10,20 +9,32 @@ namespace Service {
10namespace IR { 9namespace IR {
11 10
12const Interface::FunctionInfo FunctionTable[] = { 11const Interface::FunctionInfo FunctionTable[] = {
13 {0x00010182, nullptr, "InitializeIrNop"}, 12 {0x00010182, nullptr, "InitializeIrNop"},
14 {0x00020000, nullptr, "FinalizeIrNop"}, 13 {0x00020000, FinalizeIrNop, "FinalizeIrNop"},
15 {0x00030000, nullptr, "ClearReceiveBuffer"}, 14 {0x00030000, nullptr, "ClearReceiveBuffer"},
16 {0x00040000, nullptr, "ClearSendBuffer"}, 15 {0x00040000, nullptr, "ClearSendBuffer"},
17 {0x00060040, nullptr, "RequireConnection"}, 16 {0x000500C0, nullptr, "WaitConnection"},
18 {0x00090000, nullptr, "Disconnect"}, 17 {0x00060040, RequireConnection, "RequireConnection"},
19 {0x000A0000, nullptr, "GetReceiveEvent"}, 18 {0x000702C0, nullptr, "AutoConnection"},
20 {0x000B0000, nullptr, "GetSendEvent"}, 19 {0x00080000, nullptr, "AnyConnection"},
21 {0x000C0000, nullptr, "GetConnectionStatusEvent"}, 20 {0x00090000, Disconnect, "Disconnect"},
22 {0x000D0042, nullptr, "SendIrNop"}, 21 {0x000A0000, nullptr, "GetReceiveEvent"},
23 {0x000E0042, nullptr, "SendIrNopLarge"}, 22 {0x000B0000, nullptr, "GetSendEvent"},
24 {0x00180182, nullptr, "InitializeIrNopShared"}, 23 {0x000C0000, GetConnectionStatusEvent, "GetConnectionStatusEvent"},
25 {0x00190040, nullptr, "ReleaseReceivedData"}, 24 {0x000D0042, nullptr, "SendIrNop"},
26 {0x001A0040, nullptr, "SetOwnMachineId"}, 25 {0x000E0042, nullptr, "SendIrNopLarge"},
26 {0x000F0040, nullptr, "ReceiveIrnop"},
27 {0x00100042, nullptr, "ReceiveIrnopLarge"},
28 {0x00110040, nullptr, "GetLatestReceiveErrorResult"},
29 {0x00120040, nullptr, "GetLatestSendErrorResult"},
30 {0x00130000, nullptr, "GetConnectionStatus"},
31 {0x00140000, nullptr, "GetTryingToConnectStatus"},
32 {0x00150000, nullptr, "GetReceiveSizeFreeAndUsed"},
33 {0x00160000, nullptr, "GetSendSizeFreeAndUsed"},
34 {0x00170000, nullptr, "GetConnectionRole"},
35 {0x00180182, InitializeIrNopShared, "InitializeIrNopShared"},
36 {0x00190040, nullptr, "ReleaseReceivedData"},
37 {0x001A0040, nullptr, "SetOwnMachineId"},
27}; 38};
28 39
29IR_User_Interface::IR_User_Interface() { 40IR_User_Interface::IR_User_Interface() {
diff --git a/src/core/hle/service/ldr_ro.cpp b/src/core/hle/service/ldr_ro.cpp
index f84ce4d72..ecec2ce32 100644
--- a/src/core/hle/service/ldr_ro.cpp
+++ b/src/core/hle/service/ldr_ro.cpp
@@ -2,9 +2,9 @@
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/common_types.h"
5#include "common/logging/log.h" 6#include "common/logging/log.h"
6 7
7#include "core/hle/hle.h"
8#include "core/hle/service/ldr_ro.h" 8#include "core/hle/service/ldr_ro.h"
9 9
10//////////////////////////////////////////////////////////////////////////////////////////////////// 10////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/service/mic_u.cpp b/src/core/hle/service/mic_u.cpp
index 25e70d321..f792bc9cd 100644
--- a/src/core/hle/service/mic_u.cpp
+++ b/src/core/hle/service/mic_u.cpp
@@ -2,7 +2,6 @@
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 "core/hle/hle.h"
6#include "core/hle/service/mic_u.h" 5#include "core/hle/service/mic_u.h"
7 6
8//////////////////////////////////////////////////////////////////////////////////////////////////// 7////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -18,14 +17,14 @@ const Interface::FunctionInfo FunctionTable[] = {
18 {0x00050000, nullptr, "StopSampling"}, 17 {0x00050000, nullptr, "StopSampling"},
19 {0x00060000, nullptr, "IsSampling"}, 18 {0x00060000, nullptr, "IsSampling"},
20 {0x00070000, nullptr, "GetEventHandle"}, 19 {0x00070000, nullptr, "GetEventHandle"},
21 {0x00080040, nullptr, "SetControl"}, 20 {0x00080040, nullptr, "SetGain"},
22 {0x00090000, nullptr, "GetControl"}, 21 {0x00090000, nullptr, "GetGain"},
23 {0x000A0040, nullptr, "SetBias"}, 22 {0x000A0040, nullptr, "SetPower"},
24 {0x000B0000, nullptr, "GetBias"}, 23 {0x000B0000, nullptr, "GetPower"},
25 {0x000C0042, nullptr, "size"}, 24 {0x000C0042, nullptr, "size"},
26 {0x000D0040, nullptr, "SetClamp"}, 25 {0x000D0040, nullptr, "SetClamp"},
27 {0x000E0000, nullptr, "GetClamp"}, 26 {0x000E0000, nullptr, "GetClamp"},
28 {0x000F0040, nullptr, "unknown_input1"}, 27 {0x000F0040, nullptr, "SetAllowShellClosed"},
29 {0x00100040, nullptr, "unknown_input2"}, 28 {0x00100040, nullptr, "unknown_input2"},
30}; 29};
31 30
diff --git a/src/core/hle/service/ndm_u.cpp b/src/core/hle/service/ndm_u.cpp
index df3c97193..8fdf1ef90 100644
--- a/src/core/hle/service/ndm_u.cpp
+++ b/src/core/hle/service/ndm_u.cpp
@@ -2,8 +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 "core/hle/hle.h" 5#include "core/hle/service/ndm_u.h"
6#include "ndm_u.h"
7 6
8//////////////////////////////////////////////////////////////////////////////////////////////////// 7////////////////////////////////////////////////////////////////////////////////////////////////////
9// Namespace NDM_U 8// Namespace NDM_U
@@ -14,10 +13,26 @@ const Interface::FunctionInfo FunctionTable[] = {
14 {0x00010042, nullptr, "EnterExclusiveState"}, 13 {0x00010042, nullptr, "EnterExclusiveState"},
15 {0x00020002, nullptr, "LeaveExclusiveState"}, 14 {0x00020002, nullptr, "LeaveExclusiveState"},
16 {0x00030000, nullptr, "QueryExclusiveMode"}, 15 {0x00030000, nullptr, "QueryExclusiveMode"},
16 {0x00040002, nullptr, "LockState"},
17 {0x00050002, nullptr, "UnlockState"},
17 {0x00060040, nullptr, "SuspendDaemons"}, 18 {0x00060040, nullptr, "SuspendDaemons"},
19 {0x00070040, nullptr, "ResumeDaemons"},
18 {0x00080040, nullptr, "DisableWifiUsage"}, 20 {0x00080040, nullptr, "DisableWifiUsage"},
19 {0x00090000, nullptr, "EnableWifiUsage"}, 21 {0x00090000, nullptr, "EnableWifiUsage"},
22 {0x000A0000, nullptr, "GetCurrentState"},
23 {0x000B0000, nullptr, "GetTargetState"},
24 {0x000C0000, nullptr, "<Stubbed>"},
25 {0x000D0040, nullptr, "QueryStatus"},
26 {0x000E0040, nullptr, "GetDaemonDisableCount"},
27 {0x000F0000, nullptr, "GetSchedulerDisableCount"},
28 {0x00100040, nullptr, "SetScanInterval"},
29 {0x00110000, nullptr, "GetScanInterval"},
30 {0x00120040, nullptr, "SetRetryInterval"},
31 {0x00130000, nullptr, "GetRetryInterval"},
20 {0x00140040, nullptr, "OverrideDefaultDaemons"}, 32 {0x00140040, nullptr, "OverrideDefaultDaemons"},
33 {0x00150000, nullptr, "ResetDefaultDaemons"},
34 {0x00160000, nullptr, "GetDefaultDaemons"},
35 {0x00170000, nullptr, "ClearHalfAwakeMacFilter"},
21}; 36};
22 37
23//////////////////////////////////////////////////////////////////////////////////////////////////// 38////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/service/news/news.cpp b/src/core/hle/service/news/news.cpp
index 63cbd3850..b3f500694 100644
--- a/src/core/hle/service/news/news.cpp
+++ b/src/core/hle/service/news/news.cpp
@@ -9,10 +9,6 @@
9#include "core/hle/service/news/news_s.h" 9#include "core/hle/service/news/news_s.h"
10#include "core/hle/service/news/news_u.h" 10#include "core/hle/service/news/news_u.h"
11 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 { 12namespace Service {
17namespace NEWS { 13namespace NEWS {
18 14
diff --git a/src/core/hle/service/news/news.h b/src/core/hle/service/news/news.h
index b31ade255..46a3ffcb5 100644
--- a/src/core/hle/service/news/news.h
+++ b/src/core/hle/service/news/news.h
@@ -4,9 +4,6 @@
4 4
5#pragma once 5#pragma once
6 6
7#include "core/hle/kernel/kernel.h"
8#include "core/hle/service/service.h"
9
10namespace Service { 7namespace Service {
11namespace NEWS { 8namespace NEWS {
12 9
diff --git a/src/core/hle/service/news/news_s.cpp b/src/core/hle/service/news/news_s.cpp
index 2f8c37d9e..39b5a50f8 100644
--- a/src/core/hle/service/news/news_s.cpp
+++ b/src/core/hle/service/news/news_s.cpp
@@ -2,7 +2,6 @@
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 "core/hle/hle.h"
6#include "core/hle/service/news/news.h" 5#include "core/hle/service/news/news.h"
7#include "core/hle/service/news/news_s.h" 6#include "core/hle/service/news/news_s.h"
8 7
@@ -11,6 +10,18 @@ namespace NEWS {
11 10
12const Interface::FunctionInfo FunctionTable[] = { 11const Interface::FunctionInfo FunctionTable[] = {
13 {0x000100C6, nullptr, "AddNotification"}, 12 {0x000100C6, nullptr, "AddNotification"},
13 {0x00050000, nullptr, "GetTotalNotifications"},
14 {0x00060042, nullptr, "SetNewsDBHeader"},
15 {0x00070082, nullptr, "SetNotificationHeader"},
16 {0x00080082, nullptr, "SetNotificationMessage"},
17 {0x00090082, nullptr, "SetNotificationImage"},
18 {0x000A0042, nullptr, "GetNewsDBHeader"},
19 {0x000B0082, nullptr, "GetNotificationHeader"},
20 {0x000C0082, nullptr, "GetNotificationMessage"},
21 {0x000D0082, nullptr, "GetNotificationImage"},
22 {0x000E0040, nullptr, "SetInfoLEDPattern"},
23 {0x00120082, nullptr, "GetNotificationHeaderOther"},
24 {0x00130000, nullptr, "WriteNewsDBSavedata"},
14}; 25};
15 26
16NEWS_S_Interface::NEWS_S_Interface() { 27NEWS_S_Interface::NEWS_S_Interface() {
diff --git a/src/core/hle/service/news/news_u.cpp b/src/core/hle/service/news/news_u.cpp
index 81f45a244..6b75cc24e 100644
--- a/src/core/hle/service/news/news_u.cpp
+++ b/src/core/hle/service/news/news_u.cpp
@@ -2,8 +2,6 @@
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 "core/hle/hle.h"
6#include "core/hle/service/news/news.h"
7#include "core/hle/service/news/news_u.h" 5#include "core/hle/service/news/news_u.h"
8 6
9namespace Service { 7namespace Service {
diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp
index 73b0ee52a..ed42464ce 100644
--- a/src/core/hle/service/nim/nim.cpp
+++ b/src/core/hle/service/nim/nim.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/common_types.h"
5#include "common/logging/log.h" 6#include "common/logging/log.h"
6 7
7#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
@@ -10,10 +11,6 @@
10#include "core/hle/service/nim/nim_s.h" 11#include "core/hle/service/nim/nim_s.h"
11#include "core/hle/service/nim/nim_u.h" 12#include "core/hle/service/nim/nim_u.h"
12 13
13#include "core/hle/kernel/event.h"
14#include "core/hle/kernel/shared_memory.h"
15#include "core/hle/hle.h"
16
17namespace Service { 14namespace Service {
18namespace NIM { 15namespace NIM {
19 16
diff --git a/src/core/hle/service/nim/nim.h b/src/core/hle/service/nim/nim.h
index f7635c747..c3106f18b 100644
--- a/src/core/hle/service/nim/nim.h
+++ b/src/core/hle/service/nim/nim.h
@@ -4,10 +4,10 @@
4 4
5#pragma once 5#pragma once
6 6
7#include "core/hle/kernel/kernel.h"
8#include "core/hle/service/service.h"
9
10namespace Service { 7namespace Service {
8
9class Interface;
10
11namespace NIM { 11namespace NIM {
12 12
13/** 13/**
diff --git a/src/core/hle/service/nim/nim_aoc.cpp b/src/core/hle/service/nim/nim_aoc.cpp
index e6b1b6145..4a4818d57 100644
--- a/src/core/hle/service/nim/nim_aoc.cpp
+++ b/src/core/hle/service/nim/nim_aoc.cpp
@@ -2,8 +2,6 @@
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 "core/hle/hle.h"
6#include "core/hle/service/nim/nim.h"
7#include "core/hle/service/nim/nim_aoc.h" 5#include "core/hle/service/nim/nim_aoc.h"
8 6
9namespace Service { 7namespace Service {
diff --git a/src/core/hle/service/nim/nim_s.cpp b/src/core/hle/service/nim/nim_s.cpp
index 5d8bc059f..dcaa0255a 100644
--- a/src/core/hle/service/nim/nim_s.cpp
+++ b/src/core/hle/service/nim/nim_s.cpp
@@ -2,8 +2,6 @@
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 "core/hle/hle.h"
6#include "core/hle/service/nim/nim.h"
7#include "core/hle/service/nim/nim_s.h" 5#include "core/hle/service/nim/nim_s.h"
8 6
9namespace Service { 7namespace Service {
@@ -11,6 +9,9 @@ namespace NIM {
11 9
12const Interface::FunctionInfo FunctionTable[] = { 10const Interface::FunctionInfo FunctionTable[] = {
13 {0x000A0000, nullptr, "CheckSysupdateAvailableSOAP"}, 11 {0x000A0000, nullptr, "CheckSysupdateAvailableSOAP"},
12 {0x0016020A, nullptr, "ListTitles"},
13 {0x002D0042, nullptr, "DownloadTickets"},
14 {0x00420240, nullptr, "StartDownload"},
14}; 15};
15 16
16NIM_S_Interface::NIM_S_Interface() { 17NIM_S_Interface::NIM_S_Interface() {
diff --git a/src/core/hle/service/nim/nim_u.cpp b/src/core/hle/service/nim/nim_u.cpp
index 066570a85..eae45ebc0 100644
--- a/src/core/hle/service/nim/nim_u.cpp
+++ b/src/core/hle/service/nim/nim_u.cpp
@@ -2,7 +2,6 @@
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 "core/hle/hle.h"
6#include "core/hle/service/nim/nim.h" 5#include "core/hle/service/nim/nim.h"
7#include "core/hle/service/nim/nim_u.h" 6#include "core/hle/service/nim/nim_u.h"
8 7
diff --git a/src/core/hle/service/ns_s.cpp b/src/core/hle/service/ns_s.cpp
index 6b3ef6ece..072918d62 100644
--- a/src/core/hle/service/ns_s.cpp
+++ b/src/core/hle/service/ns_s.cpp
@@ -2,8 +2,6 @@
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
6#include "core/hle/hle.h"
7#include "core/hle/service/ns_s.h" 5#include "core/hle/service/ns_s.h"
8 6
9//////////////////////////////////////////////////////////////////////////////////////////////////// 7////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -12,7 +10,21 @@
12namespace NS_S { 10namespace NS_S {
13 11
14const Interface::FunctionInfo FunctionTable[] = { 12const Interface::FunctionInfo FunctionTable[] = {
13 {0x000100C0, nullptr, "LaunchFIRM"},
15 {0x000200C0, nullptr, "LaunchTitle"}, 14 {0x000200C0, nullptr, "LaunchTitle"},
15 {0x00030000, nullptr, "TerminateApplication"},
16 {0x00040040, nullptr, "TerminateProcess"},
17 {0x000500C0, nullptr, "LaunchApplicationFIRM"},
18 {0x00060042, nullptr, "SetFIRMParams4A0"},
19 {0x00070042, nullptr, "CardUpdateInitialize"},
20 {0x00080000, nullptr, "CardUpdateShutdown"},
21 {0x000D0140, nullptr, "SetTWLBannerHMAC"},
22 {0x000E0000, nullptr, "ShutdownAsync"},
23 {0x00100180, nullptr, "RebootSystem"},
24 {0x00110100, nullptr, "TerminateTitle"},
25 {0x001200C0, nullptr, "SetApplicationCpuTimeLimit"},
26 {0x00150140, nullptr, "LaunchApplication"},
27 {0x00160000, nullptr, "RebootSystemClean"},
16}; 28};
17 29
18//////////////////////////////////////////////////////////////////////////////////////////////////// 30////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/service/nwm_uds.cpp b/src/core/hle/service/nwm_uds.cpp
index 18b22956f..dc80984b2 100644
--- a/src/core/hle/service/nwm_uds.cpp
+++ b/src/core/hle/service/nwm_uds.cpp
@@ -2,9 +2,9 @@
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/common_types.h"
5#include "common/logging/log.h" 6#include "common/logging/log.h"
6 7
7#include "core/hle/hle.h"
8#include "core/hle/kernel/event.h" 8#include "core/hle/kernel/event.h"
9#include "core/hle/service/nwm_uds.h" 9#include "core/hle/service/nwm_uds.h"
10 10
@@ -106,14 +106,32 @@ static void Initialize(Service::Interface* self) {
106} 106}
107 107
108const Interface::FunctionInfo FunctionTable[] = { 108const Interface::FunctionInfo FunctionTable[] = {
109 {0x00020000, nullptr, "Scrap"},
109 {0x00030000, Shutdown, "Shutdown"}, 110 {0x00030000, Shutdown, "Shutdown"},
111 {0x00040402, nullptr, "CreateNetwork"},
112 {0x00050040, nullptr, "EjectClient"},
113 {0x00060000, nullptr, "EjectSpectator"},
114 {0x00070080, nullptr, "UpdateNetworkAttribute"},
115 {0x00080000, nullptr, "DestroyNetwork"},
116 {0x000A0000, nullptr, "DisconnectNetwork"},
117 {0x000B0000, nullptr, "GetConnectionStatus"},
118 {0x000D0040, nullptr, "GetNodeInformation"},
110 {0x000F0404, RecvBeaconBroadcastData, "RecvBeaconBroadcastData"}, 119 {0x000F0404, RecvBeaconBroadcastData, "RecvBeaconBroadcastData"},
111 {0x00100042, nullptr, "SetBeaconAdditionalData"}, 120 {0x00100042, nullptr, "SetBeaconAdditionalData"},
121 {0x00110040, nullptr, "GetApplicationData"},
122 {0x00120100, nullptr, "Bind"},
123 {0x00130040, nullptr, "Unbind"},
112 {0x001400C0, nullptr, "RecvBroadcastDataFrame"}, 124 {0x001400C0, nullptr, "RecvBroadcastDataFrame"},
125 {0x00150080, nullptr, "SetMaxSendDelay"},
126 {0x00170182, nullptr, "SendTo"},
127 {0x001A0000, nullptr, "GetChannel"},
113 {0x001B0302, Initialize, "Initialize"}, 128 {0x001B0302, Initialize, "Initialize"},
114 {0x001D0044, nullptr, "BeginHostingNetwork"}, 129 {0x001D0044, nullptr, "BeginHostingNetwork"},
115 {0x001E0084, nullptr, "ConnectToNetwork"}, 130 {0x001E0084, nullptr, "ConnectToNetwork"},
116 {0x001F0006, nullptr, "DecryptBeaconData"}, 131 {0x001F0006, nullptr, "DecryptBeaconData"},
132 {0x00200040, nullptr, "Flush"},
133 {0x00210080, nullptr, "SetProbeResponseParam"},
134 {0x00220402, nullptr, "ScanOnConnection"},
117}; 135};
118 136
119//////////////////////////////////////////////////////////////////////////////////////////////////// 137////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/service/pm_app.cpp b/src/core/hle/service/pm_app.cpp
index 7420a62f4..05d01bc48 100644
--- a/src/core/hle/service/pm_app.cpp
+++ b/src/core/hle/service/pm_app.cpp
@@ -2,7 +2,6 @@
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 "core/hle/hle.h"
6#include "core/hle/service/pm_app.h" 5#include "core/hle/service/pm_app.h"
7 6
8//////////////////////////////////////////////////////////////////////////////////////////////////// 7////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -19,6 +18,10 @@ const Interface::FunctionInfo FunctionTable[] = {
19 {0x00070042, nullptr, "GetFIRMLaunchParams"}, 18 {0x00070042, nullptr, "GetFIRMLaunchParams"},
20 {0x00080100, nullptr, "GetTitleExheaderFlags"}, 19 {0x00080100, nullptr, "GetTitleExheaderFlags"},
21 {0x00090042, nullptr, "SetFIRMLaunchParams"}, 20 {0x00090042, nullptr, "SetFIRMLaunchParams"},
21 {0x000A0140, nullptr, "SetResourceLimit"},
22 {0x000B0140, nullptr, "GetResourceLimitMax"},
23 {0x000C0080, nullptr, "UnregisterProcess"},
24 {0x000D0240, nullptr, "LaunchTitleUpdate"},
22}; 25};
23 26
24//////////////////////////////////////////////////////////////////////////////////////////////////// 27////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/service/ptm/ptm.cpp b/src/core/hle/service/ptm/ptm.cpp
index 22c1093ff..6bdee4d9e 100644
--- a/src/core/hle/service/ptm/ptm.cpp
+++ b/src/core/hle/service/ptm/ptm.cpp
@@ -110,8 +110,8 @@ void Init() {
110 110
111 FileSys::Path gamecoin_path("gamecoin.dat"); 111 FileSys::Path gamecoin_path("gamecoin.dat");
112 FileSys::Mode open_mode = {}; 112 FileSys::Mode open_mode = {};
113 open_mode.write_flag = 1; 113 open_mode.write_flag.Assign(1);
114 open_mode.create_flag = 1; 114 open_mode.create_flag.Assign(1);
115 // Open the file and write the default gamecoin information 115 // Open the file and write the default gamecoin information
116 auto gamecoin_result = Service::FS::OpenFileFromArchive(*archive_result, gamecoin_path, open_mode); 116 auto gamecoin_result = Service::FS::OpenFileFromArchive(*archive_result, gamecoin_path, open_mode);
117 if (gamecoin_result.Succeeded()) { 117 if (gamecoin_result.Succeeded()) {
diff --git a/src/core/hle/service/ptm/ptm.h b/src/core/hle/service/ptm/ptm.h
index f2e76441f..4cf7383d1 100644
--- a/src/core/hle/service/ptm/ptm.h
+++ b/src/core/hle/service/ptm/ptm.h
@@ -4,11 +4,12 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <array> 7#include "common/common_types.h"
8#include "core/hle/service/service.h"
9#include "core/hle/result.h"
10 8
11namespace Service { 9namespace Service {
10
11class Interface;
12
12namespace PTM { 13namespace PTM {
13 14
14/// Charge levels used by PTM functions 15/// Charge levels used by PTM functions
diff --git a/src/core/hle/service/ptm/ptm_play.cpp b/src/core/hle/service/ptm/ptm_play.cpp
index 7bb990193..ca5dd0403 100644
--- a/src/core/hle/service/ptm/ptm_play.cpp
+++ b/src/core/hle/service/ptm/ptm_play.cpp
@@ -2,7 +2,6 @@
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 "core/hle/hle.h"
6#include "core/hle/service/ptm/ptm_play.h" 5#include "core/hle/service/ptm/ptm_play.h"
7 6
8namespace Service { 7namespace Service {
diff --git a/src/core/hle/service/ptm/ptm_sysm.cpp b/src/core/hle/service/ptm/ptm_sysm.cpp
index 655658f3b..fe76dd108 100644
--- a/src/core/hle/service/ptm/ptm_sysm.cpp
+++ b/src/core/hle/service/ptm/ptm_sysm.cpp
@@ -2,7 +2,6 @@
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 "core/hle/hle.h"
6#include "core/hle/service/ptm/ptm.h" 5#include "core/hle/service/ptm/ptm.h"
7#include "core/hle/service/ptm/ptm_sysm.h" 6#include "core/hle/service/ptm/ptm_sysm.h"
8 7
@@ -39,7 +38,8 @@ const Interface::FunctionInfo FunctionTable[] = {
39 {0x08110000, nullptr, "GetShellStatus"}, 38 {0x08110000, nullptr, "GetShellStatus"},
40 {0x08120000, nullptr, "IsShutdownByBatteryEmpty"}, 39 {0x08120000, nullptr, "IsShutdownByBatteryEmpty"},
41 {0x08130000, nullptr, "FormatSavedata"}, 40 {0x08130000, nullptr, "FormatSavedata"},
42 {0x08140000, nullptr, "GetLegacyJumpProhibitedFlag"} 41 {0x08140000, nullptr, "GetLegacyJumpProhibitedFlag"},
42 {0x08180040, nullptr, "ConfigureNew3DSCPU"},
43}; 43};
44 44
45PTM_Sysm_Interface::PTM_Sysm_Interface() { 45PTM_Sysm_Interface::PTM_Sysm_Interface() {
diff --git a/src/core/hle/service/ptm/ptm_u.cpp b/src/core/hle/service/ptm/ptm_u.cpp
index 09dc38c3e..17e764866 100644
--- a/src/core/hle/service/ptm/ptm_u.cpp
+++ b/src/core/hle/service/ptm/ptm_u.cpp
@@ -2,9 +2,6 @@
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/logging/log.h"
6
7#include "core/hle/hle.h"
8#include "core/hle/service/ptm/ptm.h" 5#include "core/hle/service/ptm/ptm.h"
9#include "core/hle/service/ptm/ptm_u.h" 6#include "core/hle/service/ptm/ptm_u.h"
10 7
diff --git a/src/core/hle/service/soc_u.cpp b/src/core/hle/service/soc_u.cpp
index 633b66fe2..b52e52d4a 100644
--- a/src/core/hle/service/soc_u.cpp
+++ b/src/core/hle/service/soc_u.cpp
@@ -178,17 +178,17 @@ struct CTRPollFD {
178 static Events TranslateTo3DS(u32 input_event) { 178 static Events TranslateTo3DS(u32 input_event) {
179 Events ev = {}; 179 Events ev = {};
180 if (input_event & POLLIN) 180 if (input_event & POLLIN)
181 ev.pollin = 1; 181 ev.pollin.Assign(1);
182 if (input_event & POLLPRI) 182 if (input_event & POLLPRI)
183 ev.pollpri = 1; 183 ev.pollpri.Assign(1);
184 if (input_event & POLLHUP) 184 if (input_event & POLLHUP)
185 ev.pollhup = 1; 185 ev.pollhup.Assign(1);
186 if (input_event & POLLERR) 186 if (input_event & POLLERR)
187 ev.pollerr = 1; 187 ev.pollerr.Assign(1);
188 if (input_event & POLLOUT) 188 if (input_event & POLLOUT)
189 ev.pollout = 1; 189 ev.pollout.Assign(1);
190 if (input_event & POLLNVAL) 190 if (input_event & POLLNVAL)
191 ev.pollnval = 1; 191 ev.pollnval.Assign(1);
192 return ev; 192 return ev;
193 } 193 }
194 194
@@ -552,13 +552,23 @@ static void RecvFrom(Service::Interface* self) {
552 u32 flags = cmd_buffer[3]; 552 u32 flags = cmd_buffer[3];
553 socklen_t addr_len = static_cast<socklen_t>(cmd_buffer[4]); 553 socklen_t addr_len = static_cast<socklen_t>(cmd_buffer[4]);
554 554
555 u8* output_buff = Memory::GetPointer(cmd_buffer[0x104 >> 2]); 555 struct
556 {
557 u32 output_buffer_descriptor;
558 u32 output_buffer_addr;
559 u32 address_buffer_descriptor;
560 u32 output_src_address_buffer;
561 } buffer_parameters;
562
563 std::memcpy(&buffer_parameters, &cmd_buffer[64], sizeof(buffer_parameters));
564
565 u8* output_buff = Memory::GetPointer(buffer_parameters.output_buffer_addr);
556 sockaddr src_addr; 566 sockaddr src_addr;
557 socklen_t src_addr_len = sizeof(src_addr); 567 socklen_t src_addr_len = sizeof(src_addr);
558 int ret = ::recvfrom(socket_handle, (char*)output_buff, len, flags, &src_addr, &src_addr_len); 568 int ret = ::recvfrom(socket_handle, (char*)output_buff, len, flags, &src_addr, &src_addr_len);
559 569
560 if (cmd_buffer[0x1A0 >> 2] != 0) { 570 if (buffer_parameters.output_src_address_buffer != 0) {
561 CTRSockAddr* ctr_src_addr = reinterpret_cast<CTRSockAddr*>(Memory::GetPointer(cmd_buffer[0x1A0 >> 2])); 571 CTRSockAddr* ctr_src_addr = reinterpret_cast<CTRSockAddr*>(Memory::GetPointer(buffer_parameters.output_src_address_buffer));
562 *ctr_src_addr = CTRSockAddr::FromPlatform(src_addr); 572 *ctr_src_addr = CTRSockAddr::FromPlatform(src_addr);
563 } 573 }
564 574
@@ -732,7 +742,8 @@ const Interface::FunctionInfo FunctionTable[] = {
732 {0x000C0082, Shutdown, "Shutdown"}, 742 {0x000C0082, Shutdown, "Shutdown"},
733 {0x000D0082, nullptr, "GetHostByName"}, 743 {0x000D0082, nullptr, "GetHostByName"},
734 {0x000E00C2, nullptr, "GetHostByAddr"}, 744 {0x000E00C2, nullptr, "GetHostByAddr"},
735 {0x000F0106, nullptr, "unknown_resolve_ip"}, 745 {0x000F0106, nullptr, "GetAddrInfo"},
746 {0x00100102, nullptr, "GetNameInfo"},
736 {0x00110102, nullptr, "GetSockOpt"}, 747 {0x00110102, nullptr, "GetSockOpt"},
737 {0x00120104, nullptr, "SetSockOpt"}, 748 {0x00120104, nullptr, "SetSockOpt"},
738 {0x001300C2, Fcntl, "Fcntl"}, 749 {0x001300C2, Fcntl, "Fcntl"},
@@ -749,6 +760,7 @@ const Interface::FunctionInfo FunctionTable[] = {
749 {0x001E0040, nullptr, "ICMPClose"}, 760 {0x001E0040, nullptr, "ICMPClose"},
750 {0x001F0040, nullptr, "GetResolverInfo"}, 761 {0x001F0040, nullptr, "GetResolverInfo"},
751 {0x00210002, nullptr, "CloseSockets"}, 762 {0x00210002, nullptr, "CloseSockets"},
763 {0x00230040, nullptr, "AddGlobalSocket"},
752}; 764};
753 765
754//////////////////////////////////////////////////////////////////////////////////////////////////// 766////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/service/srv.cpp b/src/core/hle/service/srv.cpp
index 3b8c7c0e4..41fc3437b 100644
--- a/src/core/hle/service/srv.cpp
+++ b/src/core/hle/service/srv.cpp
@@ -2,9 +2,9 @@
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/common_types.h"
5#include "common/logging/log.h" 6#include "common/logging/log.h"
6 7
7#include "core/hle/hle.h"
8#include "core/hle/service/srv.h" 8#include "core/hle/service/srv.h"
9#include "core/hle/kernel/event.h" 9#include "core/hle/kernel/event.h"
10 10
diff --git a/src/core/hle/service/ssl_c.cpp b/src/core/hle/service/ssl_c.cpp
index cabd18c80..14a4e98ec 100644
--- a/src/core/hle/service/ssl_c.cpp
+++ b/src/core/hle/service/ssl_c.cpp
@@ -4,7 +4,7 @@
4 4
5#include <random> 5#include <random>
6 6
7#include "core/hle/hle.h" 7#include "common/common_types.h"
8#include "core/hle/service/ssl_c.h" 8#include "core/hle/service/ssl_c.h"
9 9
10//////////////////////////////////////////////////////////////////////////////////////////////////// 10////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -62,10 +62,24 @@ static void GenerateRandomData(Service::Interface* self) {
62const Interface::FunctionInfo FunctionTable[] = { 62const Interface::FunctionInfo FunctionTable[] = {
63 {0x00010002, Initialize, "Initialize"}, 63 {0x00010002, Initialize, "Initialize"},
64 {0x000200C2, nullptr, "CreateContext"}, 64 {0x000200C2, nullptr, "CreateContext"},
65 {0x00030000, nullptr, "CreateRootCertChain"},
66 {0x00040040, nullptr, "DestroyRootCertChain"},
65 {0x00050082, nullptr, "AddTrustedRootCA"}, 67 {0x00050082, nullptr, "AddTrustedRootCA"},
68 {0x00060080, nullptr, "RootCertChainAddDefaultCert"},
69 {0x00070080, nullptr, "RootCertChainRemoveCert"},
70 {0x000E0040, nullptr, "OpenDefaultClientCertContext"},
71 {0x000F0040, nullptr, "CloseClientCertContext"},
66 {0x00110042, GenerateRandomData, "GenerateRandomData"}, 72 {0x00110042, GenerateRandomData, "GenerateRandomData"},
73 {0x00120042, nullptr, "InitializeConnectionSession"},
74 {0x00130040, nullptr, "StartConnection"},
75 {0x00140040, nullptr, "StartConnectionGetOut"},
67 {0x00150082, nullptr, "Read"}, 76 {0x00150082, nullptr, "Read"},
68 {0x00170082, nullptr, "Write"}, 77 {0x00170082, nullptr, "Write"},
78 {0x00180080, nullptr, "ContextSetRootCertChain"},
79 {0x00190080, nullptr, "ContextSetClientCert"},
80 {0x001B0080, nullptr, "ContextClearOpt"},
81 {0x001E0040, nullptr, "DestroyContext"},
82 {0x001F0082, nullptr, "ContextInitSharedmem"}
69}; 83};
70 84
71//////////////////////////////////////////////////////////////////////////////////////////////////// 85////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/service/y2r_u.cpp b/src/core/hle/service/y2r_u.cpp
index 6b1b71fe4..a495441a4 100644
--- a/src/core/hle/service/y2r_u.cpp
+++ b/src/core/hle/service/y2r_u.cpp
@@ -4,15 +4,15 @@
4 4
5#include <cstring> 5#include <cstring>
6 6
7#include "common/common_types.h"
7#include "common/logging/log.h" 8#include "common/logging/log.h"
8 9
9#include "core/hle/hle.h"
10#include "core/hle/kernel/event.h" 10#include "core/hle/kernel/event.h"
11#include "core/hle/kernel/kernel.h"
11#include "core/hle/service/y2r_u.h" 12#include "core/hle/service/y2r_u.h"
12#include "core/hw/y2r.h" 13#include "core/hw/y2r.h"
13 14
14#include "video_core/renderer_base.h" 15#include "video_core/renderer_base.h"
15#include "video_core/utils.h"
16#include "video_core/video_core.h" 16#include "video_core/video_core.h"
17 17
18//////////////////////////////////////////////////////////////////////////////////////////////////// 18////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -267,7 +267,7 @@ static void StartConversion(Service::Interface* self) {
267 // dst_image_size would seem to be perfect for this, but it doesn't include the gap :( 267 // dst_image_size would seem to be perfect for this, but it doesn't include the gap :(
268 u32 total_output_size = conversion.input_lines * 268 u32 total_output_size = conversion.input_lines *
269 (conversion.dst.transfer_unit + conversion.dst.gap); 269 (conversion.dst.transfer_unit + conversion.dst.gap);
270 VideoCore::g_renderer->hw_rasterizer->NotifyFlush( 270 VideoCore::g_renderer->Rasterizer()->InvalidateRegion(
271 Memory::VirtualToPhysicalAddress(conversion.dst.address), total_output_size); 271 Memory::VirtualToPhysicalAddress(conversion.dst.address), total_output_size);
272 272
273 LOG_DEBUG(Service_Y2R, "called"); 273 LOG_DEBUG(Service_Y2R, "called");
@@ -375,21 +375,41 @@ static void DriverFinalize(Service::Interface* self) {
375 375
376const Interface::FunctionInfo FunctionTable[] = { 376const Interface::FunctionInfo FunctionTable[] = {
377 {0x00010040, SetInputFormat, "SetInputFormat"}, 377 {0x00010040, SetInputFormat, "SetInputFormat"},
378 {0x00020000, nullptr, "GetInputFormat"},
378 {0x00030040, SetOutputFormat, "SetOutputFormat"}, 379 {0x00030040, SetOutputFormat, "SetOutputFormat"},
380 {0x00040000, nullptr, "GetOutputFormat"},
379 {0x00050040, SetRotation, "SetRotation"}, 381 {0x00050040, SetRotation, "SetRotation"},
382 {0x00060000, nullptr, "GetRotation"},
380 {0x00070040, SetBlockAlignment, "SetBlockAlignment"}, 383 {0x00070040, SetBlockAlignment, "SetBlockAlignment"},
384 {0x00080000, nullptr, "GetBlockAlignment"},
385 {0x00090040, nullptr, "SetSpacialDithering"},
386 {0x000A0000, nullptr, "GetSpacialDithering"},
387 {0x000B0040, nullptr, "SetTemporalDithering"},
388 {0x000C0000, nullptr, "GetTemporalDithering"},
381 {0x000D0040, SetTransferEndInterrupt, "SetTransferEndInterrupt"}, 389 {0x000D0040, SetTransferEndInterrupt, "SetTransferEndInterrupt"},
382 {0x000F0000, GetTransferEndEvent, "GetTransferEndEvent"}, 390 {0x000F0000, GetTransferEndEvent, "GetTransferEndEvent"},
383 {0x00100102, SetSendingY, "SetSendingY"}, 391 {0x00100102, SetSendingY, "SetSendingY"},
384 {0x00110102, SetSendingU, "SetSendingU"}, 392 {0x00110102, SetSendingU, "SetSendingU"},
385 {0x00120102, SetSendingV, "SetSendingV"}, 393 {0x00120102, SetSendingV, "SetSendingV"},
386 {0x00130102, SetSendingYUYV, "SetSendingYUYV"}, 394 {0x00130102, SetSendingYUYV, "SetSendingYUYV"},
395 {0x00140000, nullptr, "IsFinishedSendingYuv"},
396 {0x00150000, nullptr, "IsFinishedSendingY"},
397 {0x00160000, nullptr, "IsFinishedSendingU"},
398 {0x00170000, nullptr, "IsFinishedSendingV"},
387 {0x00180102, SetReceiving, "SetReceiving"}, 399 {0x00180102, SetReceiving, "SetReceiving"},
400 {0x00190000, nullptr, "IsFinishedReceiving"},
388 {0x001A0040, SetInputLineWidth, "SetInputLineWidth"}, 401 {0x001A0040, SetInputLineWidth, "SetInputLineWidth"},
402 {0x001B0000, nullptr, "GetInputLineWidth"},
389 {0x001C0040, SetInputLines, "SetInputLines"}, 403 {0x001C0040, SetInputLines, "SetInputLines"},
404 {0x001D0000, nullptr, "GetInputLines"},
390 {0x001E0100, SetCoefficient, "SetCoefficient"}, 405 {0x001E0100, SetCoefficient, "SetCoefficient"},
406 {0x001F0000, nullptr, "GetCoefficient"},
391 {0x00200040, SetStandardCoefficient, "SetStandardCoefficient"}, 407 {0x00200040, SetStandardCoefficient, "SetStandardCoefficient"},
408 {0x00210040, nullptr, "GetStandardCoefficientParams"},
392 {0x00220040, SetAlpha, "SetAlpha"}, 409 {0x00220040, SetAlpha, "SetAlpha"},
410 {0x00230000, nullptr, "GetAlpha"},
411 {0x00240200, nullptr, "SetDitheringWeightParams"},
412 {0x00250000, nullptr, "GetDitheringWeightParams"},
393 {0x00260000, StartConversion, "StartConversion"}, 413 {0x00260000, StartConversion, "StartConversion"},
394 {0x00270000, StopConversion, "StopConversion"}, 414 {0x00270000, StopConversion, "StopConversion"},
395 {0x00280000, IsBusyConversion, "IsBusyConversion"}, 415 {0x00280000, IsBusyConversion, "IsBusyConversion"},
@@ -397,6 +417,7 @@ const Interface::FunctionInfo FunctionTable[] = {
397 {0x002A0000, PingProcess, "PingProcess"}, 417 {0x002A0000, PingProcess, "PingProcess"},
398 {0x002B0000, DriverInitialize, "DriverInitialize"}, 418 {0x002B0000, DriverInitialize, "DriverInitialize"},
399 {0x002C0000, DriverFinalize, "DriverFinalize"}, 419 {0x002C0000, DriverFinalize, "DriverFinalize"},
420 {0x002D0000, nullptr, "GetPackageParameter"},
400}; 421};
401 422
402//////////////////////////////////////////////////////////////////////////////////////////////////// 423////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 7f63ff505..7a39b101d 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -161,6 +161,8 @@ static ResultCode MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 o
161 LOG_TRACE(Kernel_SVC, "called memblock=0x%08X, addr=0x%08X, mypermissions=0x%08X, otherpermission=%d", 161 LOG_TRACE(Kernel_SVC, "called memblock=0x%08X, addr=0x%08X, mypermissions=0x%08X, otherpermission=%d",
162 handle, addr, permissions, other_permissions); 162 handle, addr, permissions, other_permissions);
163 163
164 // TODO(Subv): The same process that created a SharedMemory object can not map it in its own address space
165
164 SharedPtr<SharedMemory> shared_memory = Kernel::g_handle_table.Get<SharedMemory>(handle); 166 SharedPtr<SharedMemory> shared_memory = Kernel::g_handle_table.Get<SharedMemory>(handle);
165 if (shared_memory == nullptr) 167 if (shared_memory == nullptr)
166 return ERR_INVALID_HANDLE; 168 return ERR_INVALID_HANDLE;
@@ -175,13 +177,27 @@ static ResultCode MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 o
175 case MemoryPermission::WriteExecute: 177 case MemoryPermission::WriteExecute:
176 case MemoryPermission::ReadWriteExecute: 178 case MemoryPermission::ReadWriteExecute:
177 case MemoryPermission::DontCare: 179 case MemoryPermission::DontCare:
178 shared_memory->Map(addr, permissions_type, 180 return shared_memory->Map(addr, permissions_type,
179 static_cast<MemoryPermission>(other_permissions)); 181 static_cast<MemoryPermission>(other_permissions));
180 break;
181 default: 182 default:
182 LOG_ERROR(Kernel_SVC, "unknown permissions=0x%08X", permissions); 183 LOG_ERROR(Kernel_SVC, "unknown permissions=0x%08X", permissions);
183 } 184 }
184 return RESULT_SUCCESS; 185
186 return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::OS, ErrorSummary::InvalidArgument, ErrorLevel::Usage);
187}
188
189static ResultCode UnmapMemoryBlock(Handle handle, u32 addr) {
190 using Kernel::SharedMemory;
191
192 LOG_TRACE(Kernel_SVC, "called memblock=0x%08X, addr=0x%08X", handle, addr);
193
194 // TODO(Subv): Return E0A01BF5 if the address is not in the application's heap
195
196 SharedPtr<SharedMemory> shared_memory = Kernel::g_handle_table.Get<SharedMemory>(handle);
197 if (shared_memory == nullptr)
198 return ERR_INVALID_HANDLE;
199
200 return shared_memory->Unmap(addr);
185} 201}
186 202
187/// Connect to an OS service given the port name, returns the handle to the port to out 203/// Connect to an OS service given the port name, returns the handle to the port to out
@@ -470,6 +486,7 @@ static ResultCode CreateThread(Handle* out_handle, s32 priority, u32 entry_point
470 } 486 }
471 487
472 switch (processor_id) { 488 switch (processor_id) {
489 case THREADPROCESSORID_ALL:
473 case THREADPROCESSORID_DEFAULT: 490 case THREADPROCESSORID_DEFAULT:
474 case THREADPROCESSORID_0: 491 case THREADPROCESSORID_0:
475 case THREADPROCESSORID_1: 492 case THREADPROCESSORID_1:
@@ -765,7 +782,13 @@ static s64 GetSystemTick() {
765static ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32 my_permission, 782static ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32 my_permission,
766 u32 other_permission) { 783 u32 other_permission) {
767 using Kernel::SharedMemory; 784 using Kernel::SharedMemory;
768 // TODO(Subv): Implement this function 785
786 if (size % Memory::PAGE_SIZE != 0)
787 return ResultCode(ErrorDescription::MisalignedSize, ErrorModule::OS, ErrorSummary::InvalidArgument, ErrorLevel::Usage);
788
789 // TODO(Subv): Return E0A01BF5 if the address is not in the application's heap
790
791 // TODO(Subv): Implement this function properly
769 792
770 using Kernel::MemoryPermission; 793 using Kernel::MemoryPermission;
771 SharedPtr<SharedMemory> shared_memory = SharedMemory::Create(size, 794 SharedPtr<SharedMemory> shared_memory = SharedMemory::Create(size,
@@ -781,7 +804,7 @@ static ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32
781static ResultCode GetSystemInfo(s64* out, u32 type, s32 param) { 804static ResultCode GetSystemInfo(s64* out, u32 type, s32 param) {
782 using Kernel::MemoryRegion; 805 using Kernel::MemoryRegion;
783 806
784 LOG_TRACE(Kernel_SVC, "called process=0x%08X type=%u param=%d", process_handle, type, param); 807 LOG_TRACE(Kernel_SVC, "called type=%u param=%d", type, param);
785 808
786 switch ((SystemInfoType)type) { 809 switch ((SystemInfoType)type) {
787 case SystemInfoType::REGION_MEMORY_USAGE: 810 case SystemInfoType::REGION_MEMORY_USAGE:
@@ -807,7 +830,7 @@ static ResultCode GetSystemInfo(s64* out, u32 type, s32 param) {
807 } 830 }
808 break; 831 break;
809 case SystemInfoType::KERNEL_ALLOCATED_PAGES: 832 case SystemInfoType::KERNEL_ALLOCATED_PAGES:
810 LOG_ERROR(Kernel_SVC, "unimplemented GetSystemInfo type=2 param=%d", type, param); 833 LOG_ERROR(Kernel_SVC, "unimplemented GetSystemInfo type=2 param=%d", param);
811 *out = 0; 834 *out = 0;
812 break; 835 break;
813 case SystemInfoType::KERNEL_SPAWNED_PIDS: 836 case SystemInfoType::KERNEL_SPAWNED_PIDS:
@@ -912,7 +935,7 @@ static const FunctionDef SVC_Table[] = {
912 {0x1D, HLE::Wrap<ClearTimer>, "ClearTimer"}, 935 {0x1D, HLE::Wrap<ClearTimer>, "ClearTimer"},
913 {0x1E, HLE::Wrap<CreateMemoryBlock>, "CreateMemoryBlock"}, 936 {0x1E, HLE::Wrap<CreateMemoryBlock>, "CreateMemoryBlock"},
914 {0x1F, HLE::Wrap<MapMemoryBlock>, "MapMemoryBlock"}, 937 {0x1F, HLE::Wrap<MapMemoryBlock>, "MapMemoryBlock"},
915 {0x20, nullptr, "UnmapMemoryBlock"}, 938 {0x20, HLE::Wrap<UnmapMemoryBlock>, "UnmapMemoryBlock"},
916 {0x21, HLE::Wrap<CreateAddressArbiter>, "CreateAddressArbiter"}, 939 {0x21, HLE::Wrap<CreateAddressArbiter>, "CreateAddressArbiter"},
917 {0x22, HLE::Wrap<ArbitrateAddress>, "ArbitrateAddress"}, 940 {0x22, HLE::Wrap<ArbitrateAddress>, "ArbitrateAddress"},
918 {0x23, HLE::Wrap<CloseHandle>, "CloseHandle"}, 941 {0x23, HLE::Wrap<CloseHandle>, "CloseHandle"},
diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp
index bc7bde903..7e2f9cdfa 100644
--- a/src/core/hw/gpu.cpp
+++ b/src/core/hw/gpu.cpp
@@ -17,7 +17,6 @@
17#include "core/core_timing.h" 17#include "core/core_timing.h"
18 18
19#include "core/hle/service/gsp_gpu.h" 19#include "core/hle/service/gsp_gpu.h"
20#include "core/hle/service/dsp_dsp.h"
21#include "core/hle/service/hid/hid.h" 20#include "core/hle/service/hid/hid.h"
22 21
23#include "core/hw/hw.h" 22#include "core/hw/hw.h"
@@ -26,7 +25,7 @@
26#include "core/tracer/recorder.h" 25#include "core/tracer/recorder.h"
27 26
28#include "video_core/command_processor.h" 27#include "video_core/command_processor.h"
29#include "video_core/hwrasterizer_base.h" 28#include "video_core/rasterizer_interface.h"
30#include "video_core/renderer_base.h" 29#include "video_core/renderer_base.h"
31#include "video_core/utils.h" 30#include "video_core/utils.h"
32#include "video_core/video_core.h" 31#include "video_core/video_core.h"
@@ -141,13 +140,13 @@ inline void Write(u32 addr, const T data) {
141 GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PSC1); 140 GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PSC1);
142 } 141 }
143 142
144 VideoCore::g_renderer->hw_rasterizer->NotifyFlush(config.GetStartAddress(), config.GetEndAddress() - config.GetStartAddress()); 143 VideoCore::g_renderer->Rasterizer()->InvalidateRegion(config.GetStartAddress(), config.GetEndAddress() - config.GetStartAddress());
145 } 144 }
146 145
147 // Reset "trigger" flag and set the "finish" flag 146 // Reset "trigger" flag and set the "finish" flag
148 // NOTE: This was confirmed to happen on hardware even if "address_start" is zero. 147 // NOTE: This was confirmed to happen on hardware even if "address_start" is zero.
149 config.trigger = 0; 148 config.trigger.Assign(0);
150 config.finished = 1; 149 config.finished.Assign(1);
151 } 150 }
152 break; 151 break;
153 } 152 }
@@ -172,7 +171,7 @@ inline void Write(u32 addr, const T data) {
172 u32 output_gap = config.texture_copy.output_gap * 16; 171 u32 output_gap = config.texture_copy.output_gap * 16;
173 172
174 size_t contiguous_input_size = config.texture_copy.size / input_width * (input_width + input_gap); 173 size_t contiguous_input_size = config.texture_copy.size / input_width * (input_width + input_gap);
175 VideoCore::g_renderer->hw_rasterizer->NotifyPreRead(config.GetPhysicalInputAddress(), contiguous_input_size); 174 VideoCore::g_renderer->Rasterizer()->FlushRegion(config.GetPhysicalInputAddress(), contiguous_input_size);
176 175
177 u32 remaining_size = config.texture_copy.size; 176 u32 remaining_size = config.texture_copy.size;
178 u32 remaining_input = input_width; 177 u32 remaining_input = input_width;
@@ -205,7 +204,7 @@ inline void Write(u32 addr, const T data) {
205 config.flags); 204 config.flags);
206 205
207 size_t contiguous_output_size = config.texture_copy.size / output_width * (output_width + output_gap); 206 size_t contiguous_output_size = config.texture_copy.size / output_width * (output_width + output_gap);
208 VideoCore::g_renderer->hw_rasterizer->NotifyFlush(config.GetPhysicalOutputAddress(), contiguous_output_size); 207 VideoCore::g_renderer->Rasterizer()->InvalidateRegion(config.GetPhysicalOutputAddress(), contiguous_output_size);
209 208
210 GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PPF); 209 GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PPF);
211 break; 210 break;
@@ -232,7 +231,7 @@ inline void Write(u32 addr, const T data) {
232 u32 input_size = config.input_width * config.input_height * GPU::Regs::BytesPerPixel(config.input_format); 231 u32 input_size = config.input_width * config.input_height * GPU::Regs::BytesPerPixel(config.input_format);
233 u32 output_size = output_width * output_height * GPU::Regs::BytesPerPixel(config.output_format); 232 u32 output_size = output_width * output_height * GPU::Regs::BytesPerPixel(config.output_format);
234 233
235 VideoCore::g_renderer->hw_rasterizer->NotifyPreRead(config.GetPhysicalInputAddress(), input_size); 234 VideoCore::g_renderer->Rasterizer()->FlushRegion(config.GetPhysicalInputAddress(), input_size);
236 235
237 for (u32 y = 0; y < output_height; ++y) { 236 for (u32 y = 0; y < output_height; ++y) {
238 for (u32 x = 0; x < output_width; ++x) { 237 for (u32 x = 0; x < output_width; ++x) {
@@ -339,7 +338,7 @@ inline void Write(u32 addr, const T data) {
339 g_regs.display_transfer_config.trigger = 0; 338 g_regs.display_transfer_config.trigger = 0;
340 GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PPF); 339 GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PPF);
341 340
342 VideoCore::g_renderer->hw_rasterizer->NotifyFlush(config.GetPhysicalOutputAddress(), output_size); 341 VideoCore::g_renderer->Rasterizer()->InvalidateRegion(config.GetPhysicalOutputAddress(), output_size);
343 } 342 }
344 break; 343 break;
345 } 344 }
@@ -414,11 +413,6 @@ static void VBlankCallback(u64 userdata, int cycles_late) {
414 GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PDC0); 413 GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PDC0);
415 GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PDC1); 414 GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PDC1);
416 415
417 // TODO(bunnei): Fake a DSP interrupt on each frame. This does not belong here, but
418 // until we can emulate DSP interrupts, this is probably the only reasonable place to do
419 // this. Certain games expect this to be periodically signaled.
420 DSP_DSP::SignalInterrupt();
421
422 // Check for user input updates 416 // Check for user input updates
423 Service::HID::Update(); 417 Service::HID::Update();
424 418
@@ -444,16 +438,16 @@ void Init() {
444 framebuffer_sub.address_left1 = 0x1848F000; 438 framebuffer_sub.address_left1 = 0x1848F000;
445 framebuffer_sub.address_left2 = 0x184C7800; 439 framebuffer_sub.address_left2 = 0x184C7800;
446 440
447 framebuffer_top.width = 240; 441 framebuffer_top.width.Assign(240);
448 framebuffer_top.height = 400; 442 framebuffer_top.height.Assign(400);
449 framebuffer_top.stride = 3 * 240; 443 framebuffer_top.stride = 3 * 240;
450 framebuffer_top.color_format = Regs::PixelFormat::RGB8; 444 framebuffer_top.color_format.Assign(Regs::PixelFormat::RGB8);
451 framebuffer_top.active_fb = 0; 445 framebuffer_top.active_fb = 0;
452 446
453 framebuffer_sub.width = 240; 447 framebuffer_sub.width.Assign(240);
454 framebuffer_sub.height = 320; 448 framebuffer_sub.height.Assign(320);
455 framebuffer_sub.stride = 3 * 240; 449 framebuffer_sub.stride = 3 * 240;
456 framebuffer_sub.color_format = Regs::PixelFormat::RGB8; 450 framebuffer_sub.color_format.Assign(Regs::PixelFormat::RGB8);
457 framebuffer_sub.active_fb = 0; 451 framebuffer_sub.active_fb = 0;
458 452
459 last_skip_frame = false; 453 last_skip_frame = false;
diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp
index 5d7264f12..69df94324 100644
--- a/src/core/loader/elf.cpp
+++ b/src/core/loader/elf.cpp
@@ -250,7 +250,7 @@ const char *ElfReader::GetSectionName(int section) const {
250 return nullptr; 250 return nullptr;
251 251
252 int name_offset = sections[section].sh_name; 252 int name_offset = sections[section].sh_name;
253 const char* ptr = (char*)GetSectionDataPtr(header->e_shstrndx); 253 const char* ptr = reinterpret_cast<const char*>(GetSectionDataPtr(header->e_shstrndx));
254 254
255 if (ptr) 255 if (ptr)
256 return ptr + name_offset; 256 return ptr + name_offset;
@@ -347,10 +347,10 @@ bool ElfReader::LoadSymbols() {
347 SectionID sec = GetSectionByName(".symtab"); 347 SectionID sec = GetSectionByName(".symtab");
348 if (sec != -1) { 348 if (sec != -1) {
349 int stringSection = sections[sec].sh_link; 349 int stringSection = sections[sec].sh_link;
350 const char *stringBase = (const char *)GetSectionDataPtr(stringSection); 350 const char *stringBase = reinterpret_cast<const char*>(GetSectionDataPtr(stringSection));
351 351
352 //We have a symbol table! 352 //We have a symbol table!
353 Elf32_Sym* symtab = (Elf32_Sym *)(GetSectionDataPtr(sec)); 353 const Elf32_Sym* symtab = reinterpret_cast<const Elf32_Sym*>(GetSectionDataPtr(sec));
354 unsigned int numSymbols = sections[sec].sh_size / sizeof(Elf32_Sym); 354 unsigned int numSymbols = sections[sec].sh_size / sizeof(Elf32_Sym);
355 for (unsigned sym = 0; sym < numSymbols; sym++) { 355 for (unsigned sym = 0; sym < numSymbols; sym++) {
356 int size = symtab[sym].st_size; 356 int size = symtab[sym].st_size;
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp
index 6b88169e1..b1907cd55 100644
--- a/src/core/loader/loader.cpp
+++ b/src/core/loader/loader.cpp
@@ -137,11 +137,11 @@ ResultStatus LoadFile(const std::string& filename) {
137 AppLoader_NCCH app_loader(std::move(file), filename); 137 AppLoader_NCCH app_loader(std::move(file), filename);
138 138
139 // Load application and RomFS 139 // Load application and RomFS
140 if (ResultStatus::Success == app_loader.Load()) { 140 ResultStatus result = app_loader.Load();
141 if (ResultStatus::Success == result) {
141 Service::FS::RegisterArchiveType(Common::make_unique<FileSys::ArchiveFactory_RomFS>(app_loader), Service::FS::ArchiveIdCode::RomFS); 142 Service::FS::RegisterArchiveType(Common::make_unique<FileSys::ArchiveFactory_RomFS>(app_loader), Service::FS::ArchiveIdCode::RomFS);
142 return ResultStatus::Success;
143 } 143 }
144 break; 144 return result;
145 } 145 }
146 146
147 // CIA file format... 147 // CIA file format...
diff --git a/src/core/loader/ncch.cpp b/src/core/loader/ncch.cpp
index 68b3f546e..93f21bec2 100644
--- a/src/core/loader/ncch.cpp
+++ b/src/core/loader/ncch.cpp
@@ -255,7 +255,8 @@ ResultStatus AppLoader_NCCH::Load() {
255 priority = exheader_header.arm11_system_local_caps.priority; 255 priority = exheader_header.arm11_system_local_caps.priority;
256 resource_limit_category = exheader_header.arm11_system_local_caps.resource_limit_category; 256 resource_limit_category = exheader_header.arm11_system_local_caps.resource_limit_category;
257 257
258 LOG_INFO(Loader, "Name: %s" , exheader_header.codeset_info.name); 258 LOG_INFO(Loader, "Name: %s" , exheader_header.codeset_info.name);
259 LOG_INFO(Loader, "Program ID: %016X" , ncch_header.program_id);
259 LOG_DEBUG(Loader, "Code compressed: %s" , is_compressed ? "yes" : "no"); 260 LOG_DEBUG(Loader, "Code compressed: %s" , is_compressed ? "yes" : "no");
260 LOG_DEBUG(Loader, "Entry point: 0x%08X", entry_point); 261 LOG_DEBUG(Loader, "Entry point: 0x%08X", entry_point);
261 LOG_DEBUG(Loader, "Code size: 0x%08X", code_size); 262 LOG_DEBUG(Loader, "Code size: 0x%08X", code_size);
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index fc79c3ee9..7de5bd15d 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -13,6 +13,7 @@
13#include "core/hle/kernel/process.h" 13#include "core/hle/kernel/process.h"
14#include "core/memory.h" 14#include "core/memory.h"
15#include "core/memory_setup.h" 15#include "core/memory_setup.h"
16#include "core/mmio.h"
16 17
17namespace Memory { 18namespace Memory {
18 19
@@ -25,6 +26,12 @@ enum class PageType {
25 Special, 26 Special,
26}; 27};
27 28
29struct SpecialRegion {
30 VAddr base;
31 u32 size;
32 MMIORegionPointer handler;
33};
34
28/** 35/**
29 * A (reasonably) fast way of allowing switchable and remappable process address spaces. It loosely 36 * A (reasonably) fast way of allowing switchable and remappable process address spaces. It loosely
30 * mimics the way a real CPU page table works, but instead is optimized for minimal decoding and 37 * mimics the way a real CPU page table works, but instead is optimized for minimal decoding and
@@ -41,8 +48,13 @@ struct PageTable {
41 std::array<u8*, NUM_ENTRIES> pointers; 48 std::array<u8*, NUM_ENTRIES> pointers;
42 49
43 /** 50 /**
51 * Contains MMIO handlers that back memory regions whose entries in the `attribute` array is of type `Special`.
52 */
53 std::vector<SpecialRegion> special_regions;
54
55 /**
44 * Array of fine grained page attributes. If it is set to any value other than `Memory`, then 56 * Array of fine grained page attributes. If it is set to any value other than `Memory`, then
45 * the corresponding entry in `pointer` MUST be set to null. 57 * the corresponding entry in `pointers` MUST be set to null.
46 */ 58 */
47 std::array<PageType, NUM_ENTRIES> attributes; 59 std::array<PageType, NUM_ENTRIES> attributes;
48}; 60};
@@ -80,10 +92,12 @@ void MapMemoryRegion(VAddr base, u32 size, u8* target) {
80 MapPages(base / PAGE_SIZE, size / PAGE_SIZE, target, PageType::Memory); 92 MapPages(base / PAGE_SIZE, size / PAGE_SIZE, target, PageType::Memory);
81} 93}
82 94
83void MapIoRegion(VAddr base, u32 size) { 95void MapIoRegion(VAddr base, u32 size, MMIORegionPointer mmio_handler) {
84 ASSERT_MSG((size & PAGE_MASK) == 0, "non-page aligned size: %08X", size); 96 ASSERT_MSG((size & PAGE_MASK) == 0, "non-page aligned size: %08X", size);
85 ASSERT_MSG((base & PAGE_MASK) == 0, "non-page aligned base: %08X", base); 97 ASSERT_MSG((base & PAGE_MASK) == 0, "non-page aligned base: %08X", base);
86 MapPages(base / PAGE_SIZE, size / PAGE_SIZE, nullptr, PageType::Special); 98 MapPages(base / PAGE_SIZE, size / PAGE_SIZE, nullptr, PageType::Special);
99
100 current_page_table->special_regions.emplace_back(SpecialRegion{base, size, mmio_handler});
87} 101}
88 102
89void UnmapRegion(VAddr base, u32 size) { 103void UnmapRegion(VAddr base, u32 size) {
@@ -92,6 +106,22 @@ void UnmapRegion(VAddr base, u32 size) {
92 MapPages(base / PAGE_SIZE, size / PAGE_SIZE, nullptr, PageType::Unmapped); 106 MapPages(base / PAGE_SIZE, size / PAGE_SIZE, nullptr, PageType::Unmapped);
93} 107}
94 108
109/**
110 * This function should only be called for virtual addreses with attribute `PageType::Special`.
111 */
112static MMIORegionPointer GetMMIOHandler(VAddr vaddr) {
113 for (const auto& region : current_page_table->special_regions) {
114 if (vaddr >= region.base && vaddr < (region.base + region.size)) {
115 return region.handler;
116 }
117 }
118 ASSERT_MSG(false, "Mapped IO page without a handler @ %08X", vaddr);
119 return nullptr; // Should never happen
120}
121
122template<typename T>
123T ReadMMIO(MMIORegionPointer mmio_handler, VAddr addr);
124
95template <typename T> 125template <typename T>
96T Read(const VAddr vaddr) { 126T Read(const VAddr vaddr) {
97 const u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; 127 const u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS];
@@ -108,14 +138,17 @@ T Read(const VAddr vaddr) {
108 return 0; 138 return 0;
109 case PageType::Memory: 139 case PageType::Memory:
110 ASSERT_MSG(false, "Mapped memory page without a pointer @ %08X", vaddr); 140 ASSERT_MSG(false, "Mapped memory page without a pointer @ %08X", vaddr);
141 break;
111 case PageType::Special: 142 case PageType::Special:
112 LOG_ERROR(HW_Memory, "I/O reads aren't implemented yet @ %08X", vaddr); 143 return ReadMMIO<T>(GetMMIOHandler(vaddr), vaddr);
113 return 0;
114 default: 144 default:
115 UNREACHABLE(); 145 UNREACHABLE();
116 } 146 }
117} 147}
118 148
149template<typename T>
150void WriteMMIO(MMIORegionPointer mmio_handler, VAddr addr, const T data);
151
119template <typename T> 152template <typename T>
120void Write(const VAddr vaddr, const T data) { 153void Write(const VAddr vaddr, const T data) {
121 u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; 154 u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS];
@@ -131,9 +164,10 @@ void Write(const VAddr vaddr, const T data) {
131 return; 164 return;
132 case PageType::Memory: 165 case PageType::Memory:
133 ASSERT_MSG(false, "Mapped memory page without a pointer @ %08X", vaddr); 166 ASSERT_MSG(false, "Mapped memory page without a pointer @ %08X", vaddr);
167 break;
134 case PageType::Special: 168 case PageType::Special:
135 LOG_ERROR(HW_Memory, "I/O writes aren't implemented yet @ %08X", vaddr); 169 WriteMMIO<T>(GetMMIOHandler(vaddr), vaddr, data);
136 return; 170 break;
137 default: 171 default:
138 UNREACHABLE(); 172 UNREACHABLE();
139 } 173 }
@@ -191,6 +225,46 @@ void WriteBlock(const VAddr addr, const u8* data, const size_t size) {
191 } 225 }
192} 226}
193 227
228template<>
229u8 ReadMMIO<u8>(MMIORegionPointer mmio_handler, VAddr addr) {
230 return mmio_handler->Read8(addr);
231}
232
233template<>
234u16 ReadMMIO<u16>(MMIORegionPointer mmio_handler, VAddr addr) {
235 return mmio_handler->Read16(addr);
236}
237
238template<>
239u32 ReadMMIO<u32>(MMIORegionPointer mmio_handler, VAddr addr) {
240 return mmio_handler->Read32(addr);
241}
242
243template<>
244u64 ReadMMIO<u64>(MMIORegionPointer mmio_handler, VAddr addr) {
245 return mmio_handler->Read64(addr);
246}
247
248template<>
249void WriteMMIO<u8>(MMIORegionPointer mmio_handler, VAddr addr, const u8 data) {
250 mmio_handler->Write8(addr, data);
251}
252
253template<>
254void WriteMMIO<u16>(MMIORegionPointer mmio_handler, VAddr addr, const u16 data) {
255 mmio_handler->Write16(addr, data);
256}
257
258template<>
259void WriteMMIO<u32>(MMIORegionPointer mmio_handler, VAddr addr, const u32 data) {
260 mmio_handler->Write32(addr, data);
261}
262
263template<>
264void WriteMMIO<u64>(MMIORegionPointer mmio_handler, VAddr addr, const u64 data) {
265 mmio_handler->Write64(addr, data);
266}
267
194PAddr VirtualToPhysicalAddress(const VAddr addr) { 268PAddr VirtualToPhysicalAddress(const VAddr addr) {
195 if (addr == 0) { 269 if (addr == 0) {
196 return 0; 270 return 0;
@@ -217,7 +291,7 @@ VAddr PhysicalToVirtualAddress(const PAddr addr) {
217 } else if (addr >= VRAM_PADDR && addr < VRAM_PADDR_END) { 291 } else if (addr >= VRAM_PADDR && addr < VRAM_PADDR_END) {
218 return addr - VRAM_PADDR + VRAM_VADDR; 292 return addr - VRAM_PADDR + VRAM_VADDR;
219 } else if (addr >= FCRAM_PADDR && addr < FCRAM_PADDR_END) { 293 } else if (addr >= FCRAM_PADDR && addr < FCRAM_PADDR_END) {
220 return addr - FCRAM_PADDR + Kernel::g_current_process->GetLinearHeapBase(); 294 return addr - FCRAM_PADDR + Kernel::g_current_process->GetLinearHeapAreaAddress();
221 } else if (addr >= DSP_RAM_PADDR && addr < DSP_RAM_PADDR_END) { 295 } else if (addr >= DSP_RAM_PADDR && addr < DSP_RAM_PADDR_END) {
222 return addr - DSP_RAM_PADDR + DSP_RAM_VADDR; 296 return addr - DSP_RAM_PADDR + DSP_RAM_VADDR;
223 } else if (addr >= IO_AREA_PADDR && addr < IO_AREA_PADDR_END) { 297 } else if (addr >= IO_AREA_PADDR && addr < IO_AREA_PADDR_END) {
diff --git a/src/core/memory_setup.h b/src/core/memory_setup.h
index 84ff30120..05f70a1fe 100644
--- a/src/core/memory_setup.h
+++ b/src/core/memory_setup.h
@@ -23,10 +23,11 @@ void MapMemoryRegion(VAddr base, u32 size, u8* target);
23 23
24/** 24/**
25 * Maps a region of the emulated process address space as a IO region. 25 * Maps a region of the emulated process address space as a IO region.
26 * @note Currently this can only be used to mark a region as being IO, since actual memory-mapped 26 * @param base The address to start mapping at. Must be page-aligned.
27 * IO isn't yet supported. 27 * @param size The amount of bytes to map. Must be page-aligned.
28 * @param mmio_handler The handler that backs the mapping.
28 */ 29 */
29void MapIoRegion(VAddr base, u32 size); 30void MapIoRegion(VAddr base, u32 size, MMIORegionPointer mmio_handler);
30 31
31void UnmapRegion(VAddr base, u32 size); 32void UnmapRegion(VAddr base, u32 size);
32 33
diff --git a/src/core/mmio.h b/src/core/mmio.h
new file mode 100644
index 000000000..06b555e98
--- /dev/null
+++ b/src/core/mmio.h
@@ -0,0 +1,34 @@
1// Copyright 2016 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 <memory>
8
9#include "common/common_types.h"
10
11namespace Memory {
12
13/**
14 * Represents a device with memory mapped IO.
15 * A device may be mapped to multiple regions of memory.
16 */
17class MMIORegion {
18public:
19 virtual ~MMIORegion() = default;
20
21 virtual u8 Read8(VAddr addr) = 0;
22 virtual u16 Read16(VAddr addr) = 0;
23 virtual u32 Read32(VAddr addr) = 0;
24 virtual u64 Read64(VAddr addr) = 0;
25
26 virtual void Write8(VAddr addr, u8 data) = 0;
27 virtual void Write16(VAddr addr, u16 data) = 0;
28 virtual void Write32(VAddr addr, u32 data) = 0;
29 virtual void Write64(VAddr addr, u64 data) = 0;
30};
31
32using MMIORegionPointer = std::shared_ptr<MMIORegion>;
33
34};
diff --git a/src/core/system.cpp b/src/core/system.cpp
index 7e9c56538..4a4757af3 100644
--- a/src/core/system.cpp
+++ b/src/core/system.cpp
@@ -2,9 +2,12 @@
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 "audio_core/audio_core.h"
6
5#include "core/core.h" 7#include "core/core.h"
6#include "core/core_timing.h" 8#include "core/core_timing.h"
7#include "core/system.h" 9#include "core/system.h"
10#include "core/gdbstub/gdbstub.h"
8#include "core/hw/hw.h" 11#include "core/hw/hw.h"
9#include "core/hle/hle.h" 12#include "core/hle/hle.h"
10#include "core/hle/kernel/kernel.h" 13#include "core/hle/kernel/kernel.h"
@@ -12,23 +15,27 @@
12 15
13#include "video_core/video_core.h" 16#include "video_core/video_core.h"
14 17
15#include "core/gdbstub/gdbstub.h"
16
17namespace System { 18namespace System {
18 19
19void Init(EmuWindow* emu_window) { 20Result Init(EmuWindow* emu_window) {
20 Core::Init(); 21 Core::Init();
21 CoreTiming::Init(); 22 CoreTiming::Init();
22 Memory::Init(); 23 Memory::Init();
23 HW::Init(); 24 HW::Init();
24 Kernel::Init(); 25 Kernel::Init();
25 HLE::Init(); 26 HLE::Init();
26 VideoCore::Init(emu_window); 27 if (!VideoCore::Init(emu_window)) {
28 return Result::ErrorInitVideoCore;
29 }
30 AudioCore::Init();
27 GDBStub::Init(); 31 GDBStub::Init();
32
33 return Result::Success;
28} 34}
29 35
30void Shutdown() { 36void Shutdown() {
31 GDBStub::Shutdown(); 37 GDBStub::Shutdown();
38 AudioCore::Shutdown();
32 VideoCore::Shutdown(); 39 VideoCore::Shutdown();
33 HLE::Shutdown(); 40 HLE::Shutdown();
34 Kernel::Shutdown(); 41 Kernel::Shutdown();
diff --git a/src/core/system.h b/src/core/system.h
index 59a75ca12..a4a627ea9 100644
--- a/src/core/system.h
+++ b/src/core/system.h
@@ -8,7 +8,14 @@ class EmuWindow;
8 8
9namespace System { 9namespace System {
10 10
11void Init(EmuWindow* emu_window); 11enum class Result {
12 Success, ///< Everything is fine
13 Error, ///< Something went wrong (no module specified)
14 ErrorInitCore, ///< Something went wrong during core init
15 ErrorInitVideoCore, ///< Something went wrong during video core init
16};
17
18Result Init(EmuWindow* emu_window);
12void Shutdown(); 19void Shutdown();
13 20
14} 21}
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index 2a924f4ad..76cfd4f7d 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -11,8 +11,10 @@ set(SRCS
11 pica.cpp 11 pica.cpp
12 primitive_assembly.cpp 12 primitive_assembly.cpp
13 rasterizer.cpp 13 rasterizer.cpp
14 renderer_base.cpp
14 shader/shader.cpp 15 shader/shader.cpp
15 shader/shader_interpreter.cpp 16 shader/shader_interpreter.cpp
17 swrasterizer.cpp
16 utils.cpp 18 utils.cpp
17 video_core.cpp 19 video_core.cpp
18 ) 20 )
@@ -30,13 +32,16 @@ set(HEADERS
30 clipper.h 32 clipper.h
31 command_processor.h 33 command_processor.h
32 gpu_debugger.h 34 gpu_debugger.h
33 hwrasterizer_base.h
34 pica.h 35 pica.h
36 pica_state.h
37 pica_types.h
35 primitive_assembly.h 38 primitive_assembly.h
36 rasterizer.h 39 rasterizer.h
40 rasterizer_interface.h
37 renderer_base.h 41 renderer_base.h
38 shader/shader.h 42 shader/shader.h
39 shader/shader_interpreter.h 43 shader/shader_interpreter.h
44 swrasterizer.h
40 utils.h 45 utils.h
41 video_core.h 46 video_core.h
42 ) 47 )
diff --git a/src/video_core/clipper.cpp b/src/video_core/clipper.cpp
index ed99c4f13..3d503486e 100644
--- a/src/video_core/clipper.cpp
+++ b/src/video_core/clipper.cpp
@@ -6,6 +6,7 @@
6 6
7#include "video_core/clipper.h" 7#include "video_core/clipper.h"
8#include "video_core/pica.h" 8#include "video_core/pica.h"
9#include "video_core/pica_state.h"
9#include "video_core/rasterizer.h" 10#include "video_core/rasterizer.h"
10#include "video_core/shader/shader_interpreter.h" 11#include "video_core/shader/shader_interpreter.h"
11 12
@@ -59,15 +60,17 @@ static void InitScreenCoordinates(OutputVertex& vtx)
59 } viewport; 60 } viewport;
60 61
61 const auto& regs = g_state.regs; 62 const auto& regs = g_state.regs;
62 viewport.halfsize_x = float24::FromRawFloat24(regs.viewport_size_x); 63 viewport.halfsize_x = float24::FromRaw(regs.viewport_size_x);
63 viewport.halfsize_y = float24::FromRawFloat24(regs.viewport_size_y); 64 viewport.halfsize_y = float24::FromRaw(regs.viewport_size_y);
64 viewport.offset_x = float24::FromFloat32(static_cast<float>(regs.viewport_corner.x)); 65 viewport.offset_x = float24::FromFloat32(static_cast<float>(regs.viewport_corner.x));
65 viewport.offset_y = float24::FromFloat32(static_cast<float>(regs.viewport_corner.y)); 66 viewport.offset_y = float24::FromFloat32(static_cast<float>(regs.viewport_corner.y));
66 viewport.zscale = float24::FromRawFloat24(regs.viewport_depth_range); 67 viewport.zscale = float24::FromRaw(regs.viewport_depth_range);
67 viewport.offset_z = float24::FromRawFloat24(regs.viewport_depth_far_plane); 68 viewport.offset_z = float24::FromRaw(regs.viewport_depth_far_plane);
68 69
69 float24 inv_w = float24::FromFloat32(1.f) / vtx.pos.w; 70 float24 inv_w = float24::FromFloat32(1.f) / vtx.pos.w;
70 vtx.color *= inv_w; 71 vtx.color *= inv_w;
72 vtx.view *= inv_w;
73 vtx.quat *= inv_w;
71 vtx.tc0 *= inv_w; 74 vtx.tc0 *= inv_w;
72 vtx.tc1 *= inv_w; 75 vtx.tc1 *= inv_w;
73 vtx.tc2 *= inv_w; 76 vtx.tc2 *= inv_w;
@@ -78,7 +81,7 @@ static void InitScreenCoordinates(OutputVertex& vtx)
78 vtx.screenpos[2] = viewport.offset_z + vtx.pos.z * inv_w * viewport.zscale; 81 vtx.screenpos[2] = viewport.offset_z + vtx.pos.z * inv_w * viewport.zscale;
79} 82}
80 83
81void ProcessTriangle(OutputVertex &v0, OutputVertex &v1, OutputVertex &v2) { 84void ProcessTriangle(const OutputVertex &v0, const OutputVertex &v1, const OutputVertex &v2) {
82 using boost::container::static_vector; 85 using boost::container::static_vector;
83 86
84 // Clipping a planar n-gon against a plane will remove at least 1 vertex and introduces 2 at 87 // Clipping a planar n-gon against a plane will remove at least 1 vertex and introduces 2 at
diff --git a/src/video_core/clipper.h b/src/video_core/clipper.h
index 6ed01e877..f85d8d4c9 100644
--- a/src/video_core/clipper.h
+++ b/src/video_core/clipper.h
@@ -14,7 +14,7 @@ namespace Clipper {
14 14
15using Shader::OutputVertex; 15using Shader::OutputVertex;
16 16
17void ProcessTriangle(OutputVertex& v0, OutputVertex& v1, OutputVertex& v2); 17void ProcessTriangle(const OutputVertex& v0, const OutputVertex& v1, const OutputVertex& v2);
18 18
19} // namespace 19} // namespace
20 20
diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp
index bd1b09a4b..2274dfa66 100644
--- a/src/video_core/command_processor.cpp
+++ b/src/video_core/command_processor.cpp
@@ -15,6 +15,7 @@
15#include "video_core/clipper.h" 15#include "video_core/clipper.h"
16#include "video_core/command_processor.h" 16#include "video_core/command_processor.h"
17#include "video_core/pica.h" 17#include "video_core/pica.h"
18#include "video_core/pica_state.h"
18#include "video_core/primitive_assembly.h" 19#include "video_core/primitive_assembly.h"
19#include "video_core/renderer_base.h" 20#include "video_core/renderer_base.h"
20#include "video_core/video_core.h" 21#include "video_core/video_core.h"
@@ -73,6 +74,14 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
73 GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::P3D); 74 GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::P3D);
74 break; 75 break;
75 76
77 case PICA_REG_INDEX_WORKAROUND(vs_default_attributes_setup.index, 0x232):
78 if (regs.vs_default_attributes_setup.index == 15) {
79 // Reset immediate primitive state
80 g_state.immediate.primitive_assembler.Reconfigure(regs.triangle_topology);
81 g_state.immediate.attribute_id = 0;
82 }
83 break;
84
76 // Load default vertex input attributes 85 // Load default vertex input attributes
77 case PICA_REG_INDEX_WORKAROUND(vs_default_attributes_setup.set_value[0], 0x233): 86 case PICA_REG_INDEX_WORKAROUND(vs_default_attributes_setup.set_value[0], 0x233):
78 case PICA_REG_INDEX_WORKAROUND(vs_default_attributes_setup.set_value[1], 0x234): 87 case PICA_REG_INDEX_WORKAROUND(vs_default_attributes_setup.set_value[1], 0x234):
@@ -98,21 +107,58 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
98 Math::Vec4<float24>& attribute = g_state.vs.default_attributes[setup.index]; 107 Math::Vec4<float24>& attribute = g_state.vs.default_attributes[setup.index];
99 108
100 // NOTE: The destination component order indeed is "backwards" 109 // NOTE: The destination component order indeed is "backwards"
101 attribute.w = float24::FromRawFloat24(default_attr_write_buffer[0] >> 8); 110 attribute.w = float24::FromRaw(default_attr_write_buffer[0] >> 8);
102 attribute.z = float24::FromRawFloat24(((default_attr_write_buffer[0] & 0xFF) << 16) | ((default_attr_write_buffer[1] >> 16) & 0xFFFF)); 111 attribute.z = float24::FromRaw(((default_attr_write_buffer[0] & 0xFF) << 16) | ((default_attr_write_buffer[1] >> 16) & 0xFFFF));
103 attribute.y = float24::FromRawFloat24(((default_attr_write_buffer[1] & 0xFFFF) << 8) | ((default_attr_write_buffer[2] >> 24) & 0xFF)); 112 attribute.y = float24::FromRaw(((default_attr_write_buffer[1] & 0xFFFF) << 8) | ((default_attr_write_buffer[2] >> 24) & 0xFF));
104 attribute.x = float24::FromRawFloat24(default_attr_write_buffer[2] & 0xFFFFFF); 113 attribute.x = float24::FromRaw(default_attr_write_buffer[2] & 0xFFFFFF);
105 114
106 LOG_TRACE(HW_GPU, "Set default VS attribute %x to (%f %f %f %f)", (int)setup.index, 115 LOG_TRACE(HW_GPU, "Set default VS attribute %x to (%f %f %f %f)", (int)setup.index,
107 attribute.x.ToFloat32(), attribute.y.ToFloat32(), attribute.z.ToFloat32(), 116 attribute.x.ToFloat32(), attribute.y.ToFloat32(), attribute.z.ToFloat32(),
108 attribute.w.ToFloat32()); 117 attribute.w.ToFloat32());
109 118
110 // TODO: Verify that this actually modifies the register! 119 // TODO: Verify that this actually modifies the register!
111 setup.index = setup.index + 1; 120 if (setup.index < 15) {
121 setup.index++;
122 } else {
123 // Put each attribute into an immediate input buffer.
124 // When all specified immediate attributes are present, the Vertex Shader is invoked and everything is
125 // sent to the primitive assembler.
126
127 auto& immediate_input = g_state.immediate.input;
128 auto& immediate_attribute_id = g_state.immediate.attribute_id;
129 const auto& attribute_config = regs.vertex_attributes;
130
131 immediate_input.attr[immediate_attribute_id++] = attribute;
132
133 if (immediate_attribute_id >= attribute_config.GetNumTotalAttributes()) {
134 immediate_attribute_id = 0;
135
136 Shader::UnitState<false> shader_unit;
137 Shader::Setup(shader_unit);
138
139 // Send to vertex shader
140 Shader::OutputVertex output = Shader::Run(shader_unit, immediate_input, attribute_config.GetNumTotalAttributes());
141
142 // Send to renderer
143 using Pica::Shader::OutputVertex;
144 auto AddTriangle = [](const OutputVertex& v0, const OutputVertex& v1, const OutputVertex& v2) {
145 VideoCore::g_renderer->Rasterizer()->AddTriangle(v0, v1, v2);
146 };
147
148 g_state.immediate.primitive_assembler.SubmitVertex(output, AddTriangle);
149 }
150 }
112 } 151 }
113 break; 152 break;
114 } 153 }
115 154
155 case PICA_REG_INDEX(gpu_mode):
156 if (regs.gpu_mode == Regs::GPUMode::Configuring && regs.vs_default_attributes_setup.index == 15) {
157 // Draw immediate mode triangles when GPU Mode is set to GPUMode::Configuring
158 VideoCore::g_renderer->Rasterizer()->DrawTriangles();
159 }
160 break;
161
116 case PICA_REG_INDEX_WORKAROUND(command_buffer.trigger[0], 0x23c): 162 case PICA_REG_INDEX_WORKAROUND(command_buffer.trigger[0], 0x23c):
117 case PICA_REG_INDEX_WORKAROUND(command_buffer.trigger[1], 0x23d): 163 case PICA_REG_INDEX_WORKAROUND(command_buffer.trigger[1], 0x23d):
118 { 164 {
@@ -157,15 +203,25 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
157 203
158 // TODO: What happens if a loader overwrites a previous one's data? 204 // TODO: What happens if a loader overwrites a previous one's data?
159 for (unsigned component = 0; component < loader_config.component_count; ++component) { 205 for (unsigned component = 0; component < loader_config.component_count; ++component) {
160 if (component >= 12) 206 if (component >= 12) {
161 LOG_ERROR(HW_GPU, "Overflow in the vertex attribute loader %u trying to load component %u", loader, component); 207 LOG_ERROR(HW_GPU, "Overflow in the vertex attribute loader %u trying to load component %u", loader, component);
208 continue;
209 }
210
162 u32 attribute_index = loader_config.GetComponent(component); 211 u32 attribute_index = loader_config.GetComponent(component);
163 vertex_attribute_sources[attribute_index] = load_address; 212 if (attribute_index < 12) {
164 vertex_attribute_strides[attribute_index] = static_cast<u32>(loader_config.byte_count); 213 vertex_attribute_sources[attribute_index] = load_address;
165 vertex_attribute_formats[attribute_index] = attribute_config.GetFormat(attribute_index); 214 vertex_attribute_strides[attribute_index] = static_cast<u32>(loader_config.byte_count);
166 vertex_attribute_elements[attribute_index] = attribute_config.GetNumElements(attribute_index); 215 vertex_attribute_formats[attribute_index] = attribute_config.GetFormat(attribute_index);
167 vertex_attribute_element_size[attribute_index] = attribute_config.GetElementSizeInBytes(attribute_index); 216 vertex_attribute_elements[attribute_index] = attribute_config.GetNumElements(attribute_index);
168 load_address += attribute_config.GetStride(attribute_index); 217 vertex_attribute_element_size[attribute_index] = attribute_config.GetElementSizeInBytes(attribute_index);
218 load_address += attribute_config.GetStride(attribute_index);
219 } else if (attribute_index < 16) {
220 // Attribute ids 12, 13, 14 and 15 signify 4, 8, 12 and 16-byte paddings, respectively
221 load_address += (attribute_index - 11) * 4;
222 } else {
223 UNREACHABLE(); // This is truly unreachable due to the number of bits for each component
224 }
169 } 225 }
170 } 226 }
171 227
@@ -336,19 +392,14 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
336 } 392 }
337 } 393 }
338 394
339 if (Settings::values.use_hw_renderer) { 395 // Send to renderer
340 // Send to hardware renderer 396 using Pica::Shader::OutputVertex;
341 static auto AddHWTriangle = [](const Pica::Shader::OutputVertex& v0, 397 auto AddTriangle = [](
342 const Pica::Shader::OutputVertex& v1, 398 const OutputVertex& v0, const OutputVertex& v1, const OutputVertex& v2) {
343 const Pica::Shader::OutputVertex& v2) { 399 VideoCore::g_renderer->Rasterizer()->AddTriangle(v0, v1, v2);
344 VideoCore::g_renderer->hw_rasterizer->AddTriangle(v0, v1, v2); 400 };
345 };
346 401
347 primitive_assembler.SubmitVertex(output, AddHWTriangle); 402 primitive_assembler.SubmitVertex(output, AddTriangle);
348 } else {
349 // Send to triangle clipper
350 primitive_assembler.SubmitVertex(output, Clipper::ProcessTriangle);
351 }
352 } 403 }
353 404
354 for (auto& range : memory_accesses.ranges) { 405 for (auto& range : memory_accesses.ranges) {
@@ -356,9 +407,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
356 range.second, range.first); 407 range.second, range.first);
357 } 408 }
358 409
359 if (Settings::values.use_hw_renderer) { 410 VideoCore::g_renderer->Rasterizer()->DrawTriangles();
360 VideoCore::g_renderer->hw_rasterizer->DrawTriangles();
361 }
362 411
363#if PICA_DUMP_GEOMETRY 412#if PICA_DUMP_GEOMETRY
364 geometry_dumper.Dump(); 413 geometry_dumper.Dump();
@@ -425,10 +474,10 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
425 uniform[3 - i] = float24::FromFloat32(*(float*)(&uniform_write_buffer[i])); 474 uniform[3 - i] = float24::FromFloat32(*(float*)(&uniform_write_buffer[i]));
426 } else { 475 } else {
427 // TODO: Untested 476 // TODO: Untested
428 uniform.w = float24::FromRawFloat24(uniform_write_buffer[0] >> 8); 477 uniform.w = float24::FromRaw(uniform_write_buffer[0] >> 8);
429 uniform.z = float24::FromRawFloat24(((uniform_write_buffer[0] & 0xFF)<<16) | ((uniform_write_buffer[1] >> 16) & 0xFFFF)); 478 uniform.z = float24::FromRaw(((uniform_write_buffer[0] & 0xFF) << 16) | ((uniform_write_buffer[1] >> 16) & 0xFFFF));
430 uniform.y = float24::FromRawFloat24(((uniform_write_buffer[1] & 0xFFFF)<<8) | ((uniform_write_buffer[2] >> 24) & 0xFF)); 479 uniform.y = float24::FromRaw(((uniform_write_buffer[1] & 0xFFFF) << 8) | ((uniform_write_buffer[2] >> 24) & 0xFF));
431 uniform.x = float24::FromRawFloat24(uniform_write_buffer[2] & 0xFFFFFF); 480 uniform.x = float24::FromRaw(uniform_write_buffer[2] & 0xFFFFFF);
432 } 481 }
433 482
434 LOG_TRACE(HW_GPU, "Set uniform %x to (%f %f %f %f)", (int)uniform_setup.index, 483 LOG_TRACE(HW_GPU, "Set uniform %x to (%f %f %f %f)", (int)uniform_setup.index,
@@ -436,7 +485,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
436 uniform.w.ToFloat32()); 485 uniform.w.ToFloat32());
437 486
438 // TODO: Verify that this actually modifies the register! 487 // TODO: Verify that this actually modifies the register!
439 uniform_setup.index = uniform_setup.index + 1; 488 uniform_setup.index.Assign(uniform_setup.index + 1);
440 } 489 }
441 break; 490 break;
442 } 491 }
@@ -471,11 +520,29 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
471 break; 520 break;
472 } 521 }
473 522
523 case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[0], 0x1c8):
524 case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[1], 0x1c9):
525 case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[2], 0x1ca):
526 case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[3], 0x1cb):
527 case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[4], 0x1cc):
528 case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[5], 0x1cd):
529 case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[6], 0x1ce):
530 case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[7], 0x1cf):
531 {
532 auto& lut_config = regs.lighting.lut_config;
533
534 ASSERT_MSG(lut_config.index < 256, "lut_config.index exceeded maximum value of 255!");
535
536 g_state.lighting.luts[lut_config.type][lut_config.index].raw = value;
537 lut_config.index.Assign(lut_config.index + 1);
538 break;
539 }
540
474 default: 541 default:
475 break; 542 break;
476 } 543 }
477 544
478 VideoCore::g_renderer->hw_rasterizer->NotifyPicaRegisterChanged(id); 545 VideoCore::g_renderer->Rasterizer()->NotifyPicaRegisterChanged(id);
479 546
480 if (g_debug_context) 547 if (g_debug_context)
481 g_debug_context->OnEvent(DebugContext::Event::PicaCommandProcessed, reinterpret_cast<void*>(&id)); 548 g_debug_context->OnEvent(DebugContext::Event::PicaCommandProcessed, reinterpret_cast<void*>(&id));
@@ -493,9 +560,8 @@ void ProcessCommandList(const u32* list, u32 size) {
493 560
494 u32 value = *g_state.cmd_list.current_ptr++; 561 u32 value = *g_state.cmd_list.current_ptr++;
495 const CommandHeader header = { *g_state.cmd_list.current_ptr++ }; 562 const CommandHeader header = { *g_state.cmd_list.current_ptr++ };
496 u32 cmd = header.cmd_id;
497 563
498 WritePicaReg(cmd, value, header.parameter_mask); 564 WritePicaReg(header.cmd_id, value, header.parameter_mask);
499 565
500 for (unsigned i = 0; i < header.extra_data_length; ++i) { 566 for (unsigned i = 0; i < header.extra_data_length; ++i) {
501 u32 cmd = header.cmd_id + (header.group_commands ? i + 1 : 0); 567 u32 cmd = header.cmd_id + (header.group_commands ? i + 1 : 0);
diff --git a/src/video_core/debug_utils/debug_utils.cpp b/src/video_core/debug_utils/debug_utils.cpp
index f1cfa9361..271e81ca1 100644
--- a/src/video_core/debug_utils/debug_utils.cpp
+++ b/src/video_core/debug_utils/debug_utils.cpp
@@ -28,6 +28,7 @@
28#include "core/settings.h" 28#include "core/settings.h"
29 29
30#include "video_core/pica.h" 30#include "video_core/pica.h"
31#include "video_core/pica_state.h"
31#include "video_core/renderer_base.h" 32#include "video_core/renderer_base.h"
32#include "video_core/utils.h" 33#include "video_core/utils.h"
33#include "video_core/video_core.h" 34#include "video_core/video_core.h"
@@ -46,10 +47,8 @@ void DebugContext::OnEvent(Event event, void* data) {
46 { 47 {
47 std::unique_lock<std::mutex> lock(breakpoint_mutex); 48 std::unique_lock<std::mutex> lock(breakpoint_mutex);
48 49
49 if (Settings::values.use_hw_renderer) { 50 // Commit the hardware renderer's framebuffer so it will show on debug widgets
50 // Commit the hardware renderer's framebuffer so it will show on debug widgets 51 VideoCore::g_renderer->Rasterizer()->FlushFramebuffer();
51 VideoCore::g_renderer->hw_rasterizer->CommitFramebuffer();
52 }
53 52
54 // TODO: Should stop the CPU thread here once we multithread emulation. 53 // TODO: Should stop the CPU thread here once we multithread emulation.
55 54
@@ -115,7 +114,7 @@ void GeometryDumper::Dump() {
115} 114}
116 115
117 116
118void DumpShader(const std::string& filename, const Regs::ShaderConfig& config, const State::ShaderSetup& setup, const Regs::VSOutputAttributes* output_attributes) 117void DumpShader(const std::string& filename, const Regs::ShaderConfig& config, const Shader::ShaderSetup& setup, const Regs::VSOutputAttributes* output_attributes)
119{ 118{
120 struct StuffToWrite { 119 struct StuffToWrite {
121 u8* pointer; 120 u8* pointer;
@@ -203,11 +202,11 @@ void DumpShader(const std::string& filename, const Regs::ShaderConfig& config, c
203 202
204 if (it == output_info_table.end()) { 203 if (it == output_info_table.end()) {
205 output_info_table.emplace_back(); 204 output_info_table.emplace_back();
206 output_info_table.back().type = type; 205 output_info_table.back().type.Assign(type);
207 output_info_table.back().component_mask = component_mask; 206 output_info_table.back().component_mask.Assign(component_mask);
208 output_info_table.back().id = i; 207 output_info_table.back().id.Assign(i);
209 } else { 208 } else {
210 it->component_mask = it->component_mask | component_mask; 209 it->component_mask.Assign(it->component_mask | component_mask);
211 } 210 }
212 } catch (const std::out_of_range& ) { 211 } catch (const std::out_of_range& ) {
213 DEBUG_ASSERT_MSG(false, "Unknown output attribute mapping"); 212 DEBUG_ASSERT_MSG(false, "Unknown output attribute mapping");
diff --git a/src/video_core/debug_utils/debug_utils.h b/src/video_core/debug_utils/debug_utils.h
index 85762f5b4..795160a32 100644
--- a/src/video_core/debug_utils/debug_utils.h
+++ b/src/video_core/debug_utils/debug_utils.h
@@ -17,6 +17,7 @@
17#include "core/tracer/recorder.h" 17#include "core/tracer/recorder.h"
18 18
19#include "video_core/pica.h" 19#include "video_core/pica.h"
20#include "video_core/shader/shader.h"
20 21
21namespace Pica { 22namespace Pica {
22 23
@@ -182,7 +183,7 @@ private:
182}; 183};
183 184
184void DumpShader(const std::string& filename, const Regs::ShaderConfig& config, 185void DumpShader(const std::string& filename, const Regs::ShaderConfig& config,
185 const State::ShaderSetup& setup, const Regs::VSOutputAttributes* output_attributes); 186 const Shader::ShaderSetup& setup, const Regs::VSOutputAttributes* output_attributes);
186 187
187 188
188// Utility class to log Pica commands. 189// Utility class to log Pica commands.
diff --git a/src/video_core/pica.cpp b/src/video_core/pica.cpp
index 8c528989e..32ad72674 100644
--- a/src/video_core/pica.cpp
+++ b/src/video_core/pica.cpp
@@ -6,72 +6,481 @@
6#include <unordered_map> 6#include <unordered_map>
7 7
8#include "video_core/pica.h" 8#include "video_core/pica.h"
9#include "video_core/pica_state.h"
9#include "video_core/shader/shader.h" 10#include "video_core/shader/shader.h"
10 11
11namespace Pica { 12namespace Pica {
12 13
13State g_state; 14State g_state;
14 15
16static const std::pair<u16, const char*> register_names[] = {
17 { 0x010, "GPUREG_FINALIZE" },
18
19 { 0x040, "GPUREG_FACECULLING_CONFIG" },
20 { 0x041, "GPUREG_VIEWPORT_WIDTH" },
21 { 0x042, "GPUREG_VIEWPORT_INVW" },
22 { 0x043, "GPUREG_VIEWPORT_HEIGHT" },
23 { 0x044, "GPUREG_VIEWPORT_INVH" },
24
25 { 0x047, "GPUREG_FRAGOP_CLIP" },
26 { 0x048, "GPUREG_FRAGOP_CLIP_DATA0" },
27 { 0x049, "GPUREG_FRAGOP_CLIP_DATA1" },
28 { 0x04A, "GPUREG_FRAGOP_CLIP_DATA2" },
29 { 0x04B, "GPUREG_FRAGOP_CLIP_DATA3" },
30
31 { 0x04D, "GPUREG_DEPTHMAP_SCALE" },
32 { 0x04E, "GPUREG_DEPTHMAP_OFFSET" },
33 { 0x04F, "GPUREG_SH_OUTMAP_TOTAL" },
34 { 0x050, "GPUREG_SH_OUTMAP_O0" },
35 { 0x051, "GPUREG_SH_OUTMAP_O1" },
36 { 0x052, "GPUREG_SH_OUTMAP_O2" },
37 { 0x053, "GPUREG_SH_OUTMAP_O3" },
38 { 0x054, "GPUREG_SH_OUTMAP_O4" },
39 { 0x055, "GPUREG_SH_OUTMAP_O5" },
40 { 0x056, "GPUREG_SH_OUTMAP_O6" },
41
42 { 0x061, "GPUREG_EARLYDEPTH_FUNC" },
43 { 0x062, "GPUREG_EARLYDEPTH_TEST1" },
44 { 0x063, "GPUREG_EARLYDEPTH_CLEAR" },
45 { 0x064, "GPUREG_SH_OUTATTR_MODE" },
46 { 0x065, "GPUREG_SCISSORTEST_MODE" },
47 { 0x066, "GPUREG_SCISSORTEST_POS" },
48 { 0x067, "GPUREG_SCISSORTEST_DIM" },
49 { 0x068, "GPUREG_VIEWPORT_XY" },
50
51 { 0x06A, "GPUREG_EARLYDEPTH_DATA" },
52
53 { 0x06D, "GPUREG_DEPTHMAP_ENABLE" },
54 { 0x06E, "GPUREG_RENDERBUF_DIM" },
55 { 0x06F, "GPUREG_SH_OUTATTR_CLOCK" },
56
57 { 0x080, "GPUREG_TEXUNIT_CONFIG" },
58 { 0x081, "GPUREG_TEXUNIT0_BORDER_COLOR" },
59 { 0x082, "GPUREG_TEXUNIT0_DIM" },
60 { 0x083, "GPUREG_TEXUNIT0_PARAM" },
61 { 0x084, "GPUREG_TEXUNIT0_LOD" },
62 { 0x085, "GPUREG_TEXUNIT0_ADDR1" },
63 { 0x086, "GPUREG_TEXUNIT0_ADDR2" },
64 { 0x087, "GPUREG_TEXUNIT0_ADDR3" },
65 { 0x088, "GPUREG_TEXUNIT0_ADDR4" },
66 { 0x089, "GPUREG_TEXUNIT0_ADDR5" },
67 { 0x08A, "GPUREG_TEXUNIT0_ADDR6" },
68 { 0x08B, "GPUREG_TEXUNIT0_SHADOW" },
69
70 { 0x08E, "GPUREG_TEXUNIT0_TYPE" },
71 { 0x08F, "GPUREG_LIGHTING_ENABLE0" },
72
73 { 0x091, "GPUREG_TEXUNIT1_BORDER_COLOR" },
74 { 0x092, "GPUREG_TEXUNIT1_DIM" },
75 { 0x093, "GPUREG_TEXUNIT1_PARAM" },
76 { 0x094, "GPUREG_TEXUNIT1_LOD" },
77 { 0x095, "GPUREG_TEXUNIT1_ADDR" },
78 { 0x096, "GPUREG_TEXUNIT1_TYPE" },
79
80 { 0x099, "GPUREG_TEXUNIT2_BORDER_COLOR" },
81 { 0x09A, "GPUREG_TEXUNIT2_DIM" },
82 { 0x09B, "GPUREG_TEXUNIT2_PARAM" },
83 { 0x09C, "GPUREG_TEXUNIT2_LOD" },
84 { 0x09D, "GPUREG_TEXUNIT2_ADDR" },
85 { 0x09E, "GPUREG_TEXUNIT2_TYPE" },
86
87 { 0x0A8, "GPUREG_TEXUNIT3_PROCTEX0" },
88 { 0x0A9, "GPUREG_TEXUNIT3_PROCTEX1" },
89 { 0x0AA, "GPUREG_TEXUNIT3_PROCTEX2" },
90 { 0x0AB, "GPUREG_TEXUNIT3_PROCTEX3" },
91 { 0x0AC, "GPUREG_TEXUNIT3_PROCTEX4" },
92 { 0x0AD, "GPUREG_TEXUNIT3_PROCTEX5" },
93
94 { 0x0AF, "GPUREG_PROCTEX_LUT" },
95 { 0x0B0, "GPUREG_PROCTEX_LUT_DATA0" },
96 { 0x0B1, "GPUREG_PROCTEX_LUT_DATA1" },
97 { 0x0B2, "GPUREG_PROCTEX_LUT_DATA2" },
98 { 0x0B3, "GPUREG_PROCTEX_LUT_DATA3" },
99 { 0x0B4, "GPUREG_PROCTEX_LUT_DATA4" },
100 { 0x0B5, "GPUREG_PROCTEX_LUT_DATA5" },
101 { 0x0B6, "GPUREG_PROCTEX_LUT_DATA6" },
102 { 0x0B7, "GPUREG_PROCTEX_LUT_DATA7" },
103
104 { 0x0C0, "GPUREG_TEXENV0_SOURCE" },
105 { 0x0C1, "GPUREG_TEXENV0_OPERAND" },
106 { 0x0C2, "GPUREG_TEXENV0_COMBINER" },
107 { 0x0C3, "GPUREG_TEXENV0_COLOR" },
108 { 0x0C4, "GPUREG_TEXENV0_SCALE" },
109
110 { 0x0C8, "GPUREG_TEXENV1_SOURCE" },
111 { 0x0C9, "GPUREG_TEXENV1_OPERAND" },
112 { 0x0CA, "GPUREG_TEXENV1_COMBINER" },
113 { 0x0CB, "GPUREG_TEXENV1_COLOR" },
114 { 0x0CC, "GPUREG_TEXENV1_SCALE" },
115
116 { 0x0D0, "GPUREG_TEXENV2_SOURCE" },
117 { 0x0D1, "GPUREG_TEXENV2_OPERAND" },
118 { 0x0D2, "GPUREG_TEXENV2_COMBINER" },
119 { 0x0D3, "GPUREG_TEXENV2_COLOR" },
120 { 0x0D4, "GPUREG_TEXENV2_SCALE" },
121
122 { 0x0D8, "GPUREG_TEXENV3_SOURCE" },
123 { 0x0D9, "GPUREG_TEXENV3_OPERAND" },
124 { 0x0DA, "GPUREG_TEXENV3_COMBINER" },
125 { 0x0DB, "GPUREG_TEXENV3_COLOR" },
126 { 0x0DC, "GPUREG_TEXENV3_SCALE" },
127
128 { 0x0E0, "GPUREG_TEXENV_UPDATE_BUFFER" },
129 { 0x0E1, "GPUREG_FOG_COLOR" },
130
131 { 0x0E4, "GPUREG_GAS_ATTENUATION" },
132 { 0x0E5, "GPUREG_GAS_ACCMAX" },
133 { 0x0E6, "GPUREG_FOG_LUT_INDEX" },
134
135 { 0x0E8, "GPUREG_FOG_LUT_DATA0" },
136 { 0x0E9, "GPUREG_FOG_LUT_DATA1" },
137 { 0x0EA, "GPUREG_FOG_LUT_DATA2" },
138 { 0x0EB, "GPUREG_FOG_LUT_DATA3" },
139 { 0x0EC, "GPUREG_FOG_LUT_DATA4" },
140 { 0x0ED, "GPUREG_FOG_LUT_DATA5" },
141 { 0x0EE, "GPUREG_FOG_LUT_DATA6" },
142 { 0x0EF, "GPUREG_FOG_LUT_DATA7" },
143 { 0x0F0, "GPUREG_TEXENV4_SOURCE" },
144 { 0x0F1, "GPUREG_TEXENV4_OPERAND" },
145 { 0x0F2, "GPUREG_TEXENV4_COMBINER" },
146 { 0x0F3, "GPUREG_TEXENV4_COLOR" },
147 { 0x0F4, "GPUREG_TEXENV4_SCALE" },
148
149 { 0x0F8, "GPUREG_TEXENV5_SOURCE" },
150 { 0x0F9, "GPUREG_TEXENV5_OPERAND" },
151 { 0x0FA, "GPUREG_TEXENV5_COMBINER" },
152 { 0x0FB, "GPUREG_TEXENV5_COLOR" },
153 { 0x0FC, "GPUREG_TEXENV5_SCALE" },
154 { 0x0FD, "GPUREG_TEXENV_BUFFER_COLOR" },
155
156 { 0x100, "GPUREG_COLOR_OPERATION" },
157 { 0x101, "GPUREG_BLEND_FUNC" },
158 { 0x102, "GPUREG_LOGIC_OP" },
159 { 0x103, "GPUREG_BLEND_COLOR" },
160 { 0x104, "GPUREG_FRAGOP_ALPHA_TEST" },
161 { 0x105, "GPUREG_STENCIL_TEST" },
162 { 0x106, "GPUREG_STENCIL_OP" },
163 { 0x107, "GPUREG_DEPTH_COLOR_MASK" },
164
165 { 0x110, "GPUREG_FRAMEBUFFER_INVALIDATE" },
166 { 0x111, "GPUREG_FRAMEBUFFER_FLUSH" },
167 { 0x112, "GPUREG_COLORBUFFER_READ" },
168 { 0x113, "GPUREG_COLORBUFFER_WRITE" },
169 { 0x114, "GPUREG_DEPTHBUFFER_READ" },
170 { 0x115, "GPUREG_DEPTHBUFFER_WRITE" },
171 { 0x116, "GPUREG_DEPTHBUFFER_FORMAT" },
172 { 0x117, "GPUREG_COLORBUFFER_FORMAT" },
173 { 0x118, "GPUREG_EARLYDEPTH_TEST2" },
174
175 { 0x11B, "GPUREG_FRAMEBUFFER_BLOCK32" },
176 { 0x11C, "GPUREG_DEPTHBUFFER_LOC" },
177 { 0x11D, "GPUREG_COLORBUFFER_LOC" },
178 { 0x11E, "GPUREG_FRAMEBUFFER_DIM" },
179
180 { 0x120, "GPUREG_GAS_LIGHT_XY" },
181 { 0x121, "GPUREG_GAS_LIGHT_Z" },
182 { 0x122, "GPUREG_GAS_LIGHT_Z_COLOR" },
183 { 0x123, "GPUREG_GAS_LUT_INDEX" },
184 { 0x124, "GPUREG_GAS_LUT_DATA" },
185
186 { 0x126, "GPUREG_GAS_DELTAZ_DEPTH" },
187
188 { 0x130, "GPUREG_FRAGOP_SHADOW" },
189
190 { 0x140, "GPUREG_LIGHT0_SPECULAR0" },
191 { 0x141, "GPUREG_LIGHT0_SPECULAR1" },
192 { 0x142, "GPUREG_LIGHT0_DIFFUSE" },
193 { 0x143, "GPUREG_LIGHT0_AMBIENT" },
194 { 0x144, "GPUREG_LIGHT0_XY" },
195 { 0x145, "GPUREG_LIGHT0_Z" },
196 { 0x146, "GPUREG_LIGHT0_SPOTDIR_XY" },
197 { 0x147, "GPUREG_LIGHT0_SPOTDIR_Z" },
198
199 { 0x149, "GPUREG_LIGHT0_CONFIG" },
200 { 0x14A, "GPUREG_LIGHT0_ATTENUATION_BIAS" },
201 { 0x14B, "GPUREG_LIGHT0_ATTENUATION_SCALE" },
202
203 { 0x150, "GPUREG_LIGHT1_SPECULAR0" },
204 { 0x151, "GPUREG_LIGHT1_SPECULAR1" },
205 { 0x152, "GPUREG_LIGHT1_DIFFUSE" },
206 { 0x153, "GPUREG_LIGHT1_AMBIENT" },
207 { 0x154, "GPUREG_LIGHT1_XY" },
208 { 0x155, "GPUREG_LIGHT1_Z" },
209 { 0x156, "GPUREG_LIGHT1_SPOTDIR_XY" },
210 { 0x157, "GPUREG_LIGHT1_SPOTDIR_Z" },
211
212 { 0x159, "GPUREG_LIGHT1_CONFIG" },
213 { 0x15A, "GPUREG_LIGHT1_ATTENUATION_BIAS" },
214 { 0x15B, "GPUREG_LIGHT1_ATTENUATION_SCALE" },
215
216 { 0x160, "GPUREG_LIGHT2_SPECULAR0" },
217 { 0x161, "GPUREG_LIGHT2_SPECULAR1" },
218 { 0x162, "GPUREG_LIGHT2_DIFFUSE" },
219 { 0x163, "GPUREG_LIGHT2_AMBIENT" },
220 { 0x164, "GPUREG_LIGHT2_XY" },
221 { 0x165, "GPUREG_LIGHT2_Z" },
222 { 0x166, "GPUREG_LIGHT2_SPOTDIR_XY" },
223 { 0x167, "GPUREG_LIGHT2_SPOTDIR_Z" },
224
225 { 0x169, "GPUREG_LIGHT2_CONFIG" },
226 { 0x16A, "GPUREG_LIGHT2_ATTENUATION_BIAS" },
227 { 0x16B, "GPUREG_LIGHT2_ATTENUATION_SCALE" },
228
229 { 0x170, "GPUREG_LIGHT3_SPECULAR0" },
230 { 0x171, "GPUREG_LIGHT3_SPECULAR1" },
231 { 0x172, "GPUREG_LIGHT3_DIFFUSE" },
232 { 0x173, "GPUREG_LIGHT3_AMBIENT" },
233 { 0x174, "GPUREG_LIGHT3_XY" },
234 { 0x175, "GPUREG_LIGHT3_Z" },
235 { 0x176, "GPUREG_LIGHT3_SPOTDIR_XY" },
236 { 0x177, "GPUREG_LIGHT3_SPOTDIR_Z" },
237
238 { 0x179, "GPUREG_LIGHT3_CONFIG" },
239 { 0x17A, "GPUREG_LIGHT3_ATTENUATION_BIAS" },
240 { 0x17B, "GPUREG_LIGHT3_ATTENUATION_SCALE" },
241
242 { 0x180, "GPUREG_LIGHT4_SPECULAR0" },
243 { 0x181, "GPUREG_LIGHT4_SPECULAR1" },
244 { 0x182, "GPUREG_LIGHT4_DIFFUSE" },
245 { 0x183, "GPUREG_LIGHT4_AMBIENT" },
246 { 0x184, "GPUREG_LIGHT4_XY" },
247 { 0x185, "GPUREG_LIGHT4_Z" },
248 { 0x186, "GPUREG_LIGHT4_SPOTDIR_XY" },
249 { 0x187, "GPUREG_LIGHT4_SPOTDIR_Z" },
250
251 { 0x189, "GPUREG_LIGHT4_CONFIG" },
252 { 0x18A, "GPUREG_LIGHT4_ATTENUATION_BIAS" },
253 { 0x18B, "GPUREG_LIGHT4_ATTENUATION_SCALE" },
254
255 { 0x190, "GPUREG_LIGHT5_SPECULAR0" },
256 { 0x191, "GPUREG_LIGHT5_SPECULAR1" },
257 { 0x192, "GPUREG_LIGHT5_DIFFUSE" },
258 { 0x193, "GPUREG_LIGHT5_AMBIENT" },
259 { 0x194, "GPUREG_LIGHT5_XY" },
260 { 0x195, "GPUREG_LIGHT5_Z" },
261 { 0x196, "GPUREG_LIGHT5_SPOTDIR_XY" },
262 { 0x197, "GPUREG_LIGHT5_SPOTDIR_Z" },
263
264 { 0x199, "GPUREG_LIGHT5_CONFIG" },
265 { 0x19A, "GPUREG_LIGHT5_ATTENUATION_BIAS" },
266 { 0x19B, "GPUREG_LIGHT5_ATTENUATION_SCALE" },
267
268 { 0x1A0, "GPUREG_LIGHT6_SPECULAR0" },
269 { 0x1A1, "GPUREG_LIGHT6_SPECULAR1" },
270 { 0x1A2, "GPUREG_LIGHT6_DIFFUSE" },
271 { 0x1A3, "GPUREG_LIGHT6_AMBIENT" },
272 { 0x1A4, "GPUREG_LIGHT6_XY" },
273 { 0x1A5, "GPUREG_LIGHT6_Z" },
274 { 0x1A6, "GPUREG_LIGHT6_SPOTDIR_XY" },
275 { 0x1A7, "GPUREG_LIGHT6_SPOTDIR_Z" },
276
277 { 0x1A9, "GPUREG_LIGHT6_CONFIG" },
278 { 0x1AA, "GPUREG_LIGHT6_ATTENUATION_BIAS" },
279 { 0x1AB, "GPUREG_LIGHT6_ATTENUATION_SCALE" },
280
281 { 0x1B0, "GPUREG_LIGHT7_SPECULAR0" },
282 { 0x1B1, "GPUREG_LIGHT7_SPECULAR1" },
283 { 0x1B2, "GPUREG_LIGHT7_DIFFUSE" },
284 { 0x1B3, "GPUREG_LIGHT7_AMBIENT" },
285 { 0x1B4, "GPUREG_LIGHT7_XY" },
286 { 0x1B5, "GPUREG_LIGHT7_Z" },
287 { 0x1B6, "GPUREG_LIGHT7_SPOTDIR_XY" },
288 { 0x1B7, "GPUREG_LIGHT7_SPOTDIR_Z" },
289
290 { 0x1B9, "GPUREG_LIGHT7_CONFIG" },
291 { 0x1BA, "GPUREG_LIGHT7_ATTENUATION_BIAS" },
292 { 0x1BB, "GPUREG_LIGHT7_ATTENUATION_SCALE" },
293
294 { 0x1C0, "GPUREG_LIGHTING_AMBIENT" },
295
296 { 0x1C2, "GPUREG_LIGHTING_NUM_LIGHTS" },
297 { 0x1C3, "GPUREG_LIGHTING_CONFIG0" },
298 { 0x1C4, "GPUREG_LIGHTING_CONFIG1" },
299 { 0x1C5, "GPUREG_LIGHTING_LUT_INDEX" },
300 { 0x1C6, "GPUREG_LIGHTING_ENABLE1" },
301
302 { 0x1C8, "GPUREG_LIGHTING_LUT_DATA0" },
303 { 0x1C9, "GPUREG_LIGHTING_LUT_DATA1" },
304 { 0x1CA, "GPUREG_LIGHTING_LUT_DATA2" },
305 { 0x1CB, "GPUREG_LIGHTING_LUT_DATA3" },
306 { 0x1CC, "GPUREG_LIGHTING_LUT_DATA4" },
307 { 0x1CD, "GPUREG_LIGHTING_LUT_DATA5" },
308 { 0x1CE, "GPUREG_LIGHTING_LUT_DATA6" },
309 { 0x1CF, "GPUREG_LIGHTING_LUT_DATA7" },
310 { 0x1D0, "GPUREG_LIGHTING_LUTINPUT_ABS" },
311 { 0x1D1, "GPUREG_LIGHTING_LUTINPUT_SELECT" },
312 { 0x1D2, "GPUREG_LIGHTING_LUTINPUT_SCALE" },
313
314 { 0x1D9, "GPUREG_LIGHTING_LIGHT_PERMUTATION" },
315
316 { 0x200, "GPUREG_ATTRIBBUFFERS_LOC" },
317 { 0x201, "GPUREG_ATTRIBBUFFERS_FORMAT_LOW" },
318 { 0x202, "GPUREG_ATTRIBBUFFERS_FORMAT_HIGH" },
319 { 0x203, "GPUREG_ATTRIBBUFFER0_OFFSET" },
320 { 0x204, "GPUREG_ATTRIBBUFFER0_CONFIG1" },
321 { 0x205, "GPUREG_ATTRIBBUFFER0_CONFIG2" },
322 { 0x206, "GPUREG_ATTRIBBUFFER1_OFFSET" },
323 { 0x207, "GPUREG_ATTRIBBUFFER1_CONFIG1" },
324 { 0x208, "GPUREG_ATTRIBBUFFER1_CONFIG2" },
325 { 0x209, "GPUREG_ATTRIBBUFFER2_OFFSET" },
326 { 0x20A, "GPUREG_ATTRIBBUFFER2_CONFIG1" },
327 { 0x20B, "GPUREG_ATTRIBBUFFER2_CONFIG2" },
328 { 0x20C, "GPUREG_ATTRIBBUFFER3_OFFSET" },
329 { 0x20D, "GPUREG_ATTRIBBUFFER3_CONFIG1" },
330 { 0x20E, "GPUREG_ATTRIBBUFFER3_CONFIG2" },
331 { 0x20F, "GPUREG_ATTRIBBUFFER4_OFFSET" },
332 { 0x210, "GPUREG_ATTRIBBUFFER4_CONFIG1" },
333 { 0x211, "GPUREG_ATTRIBBUFFER4_CONFIG2" },
334 { 0x212, "GPUREG_ATTRIBBUFFER5_OFFSET" },
335 { 0x213, "GPUREG_ATTRIBBUFFER5_CONFIG1" },
336 { 0x214, "GPUREG_ATTRIBBUFFER5_CONFIG2" },
337 { 0x215, "GPUREG_ATTRIBBUFFER6_OFFSET" },
338 { 0x216, "GPUREG_ATTRIBBUFFER6_CONFIG1" },
339 { 0x217, "GPUREG_ATTRIBBUFFER6_CONFIG2" },
340 { 0x218, "GPUREG_ATTRIBBUFFER7_OFFSET" },
341 { 0x219, "GPUREG_ATTRIBBUFFER7_CONFIG1" },
342 { 0x21A, "GPUREG_ATTRIBBUFFER7_CONFIG2" },
343 { 0x21B, "GPUREG_ATTRIBBUFFER8_OFFSET" },
344 { 0x21C, "GPUREG_ATTRIBBUFFER8_CONFIG1" },
345 { 0x21D, "GPUREG_ATTRIBBUFFER8_CONFIG2" },
346 { 0x21E, "GPUREG_ATTRIBBUFFER9_OFFSET" },
347 { 0x21F, "GPUREG_ATTRIBBUFFER9_CONFIG1" },
348 { 0x220, "GPUREG_ATTRIBBUFFER9_CONFIG2" },
349 { 0x221, "GPUREG_ATTRIBBUFFER10_OFFSET" },
350 { 0x222, "GPUREG_ATTRIBBUFFER10_CONFIG1" },
351 { 0x223, "GPUREG_ATTRIBBUFFER10_CONFIG2" },
352 { 0x224, "GPUREG_ATTRIBBUFFER11_OFFSET" },
353 { 0x225, "GPUREG_ATTRIBBUFFER11_CONFIG1" },
354 { 0x226, "GPUREG_ATTRIBBUFFER11_CONFIG2" },
355 { 0x227, "GPUREG_INDEXBUFFER_CONFIG" },
356 { 0x228, "GPUREG_NUMVERTICES" },
357 { 0x229, "GPUREG_GEOSTAGE_CONFIG" },
358 { 0x22A, "GPUREG_VERTEX_OFFSET" },
359
360 { 0x22D, "GPUREG_POST_VERTEX_CACHE_NUM" },
361 { 0x22E, "GPUREG_DRAWARRAYS" },
362 { 0x22F, "GPUREG_DRAWELEMENTS" },
363
364 { 0x231, "GPUREG_VTX_FUNC" },
365 { 0x232, "GPUREG_FIXEDATTRIB_INDEX" },
366 { 0x233, "GPUREG_FIXEDATTRIB_DATA0" },
367 { 0x234, "GPUREG_FIXEDATTRIB_DATA1" },
368 { 0x235, "GPUREG_FIXEDATTRIB_DATA2" },
369
370 { 0x238, "GPUREG_CMDBUF_SIZE0" },
371 { 0x239, "GPUREG_CMDBUF_SIZE1" },
372 { 0x23A, "GPUREG_CMDBUF_ADDR0" },
373 { 0x23B, "GPUREG_CMDBUF_ADDR1" },
374 { 0x23C, "GPUREG_CMDBUF_JUMP0" },
375 { 0x23D, "GPUREG_CMDBUF_JUMP1" },
376
377 { 0x242, "GPUREG_VSH_NUM_ATTR" },
378
379 { 0x244, "GPUREG_VSH_COM_MODE" },
380 { 0x245, "GPUREG_START_DRAW_FUNC0" },
381
382 { 0x24A, "GPUREG_VSH_OUTMAP_TOTAL1" },
383
384 { 0x251, "GPUREG_VSH_OUTMAP_TOTAL2" },
385 { 0x252, "GPUREG_GSH_MISC0" },
386 { 0x253, "GPUREG_GEOSTAGE_CONFIG2" },
387 { 0x254, "GPUREG_GSH_MISC1" },
388
389 { 0x25E, "GPUREG_PRIMITIVE_CONFIG" },
390 { 0x25F, "GPUREG_RESTART_PRIMITIVE" },
391
392 { 0x280, "GPUREG_GSH_BOOLUNIFORM" },
393 { 0x281, "GPUREG_GSH_INTUNIFORM_I0" },
394 { 0x282, "GPUREG_GSH_INTUNIFORM_I1" },
395 { 0x283, "GPUREG_GSH_INTUNIFORM_I2" },
396 { 0x284, "GPUREG_GSH_INTUNIFORM_I3" },
397
398 { 0x289, "GPUREG_GSH_INPUTBUFFER_CONFIG" },
399 { 0x28A, "GPUREG_GSH_ENTRYPOINT" },
400 { 0x28B, "GPUREG_GSH_ATTRIBUTES_PERMUTATION_LOW" },
401 { 0x28C, "GPUREG_GSH_ATTRIBUTES_PERMUTATION_HIGH" },
402 { 0x28D, "GPUREG_GSH_OUTMAP_MASK" },
403
404 { 0x28F, "GPUREG_GSH_CODETRANSFER_END" },
405 { 0x290, "GPUREG_GSH_FLOATUNIFORM_INDEX" },
406 { 0x291, "GPUREG_GSH_FLOATUNIFORM_DATA0" },
407 { 0x292, "GPUREG_GSH_FLOATUNIFORM_DATA1" },
408 { 0x293, "GPUREG_GSH_FLOATUNIFORM_DATA2" },
409 { 0x294, "GPUREG_GSH_FLOATUNIFORM_DATA3" },
410 { 0x295, "GPUREG_GSH_FLOATUNIFORM_DATA4" },
411 { 0x296, "GPUREG_GSH_FLOATUNIFORM_DATA5" },
412 { 0x297, "GPUREG_GSH_FLOATUNIFORM_DATA6" },
413 { 0x298, "GPUREG_GSH_FLOATUNIFORM_DATA7" },
414
415 { 0x29B, "GPUREG_GSH_CODETRANSFER_INDEX" },
416 { 0x29C, "GPUREG_GSH_CODETRANSFER_DATA0" },
417 { 0x29D, "GPUREG_GSH_CODETRANSFER_DATA1" },
418 { 0x29E, "GPUREG_GSH_CODETRANSFER_DATA2" },
419 { 0x29F, "GPUREG_GSH_CODETRANSFER_DATA3" },
420 { 0x2A0, "GPUREG_GSH_CODETRANSFER_DATA4" },
421 { 0x2A1, "GPUREG_GSH_CODETRANSFER_DATA5" },
422 { 0x2A2, "GPUREG_GSH_CODETRANSFER_DATA6" },
423 { 0x2A3, "GPUREG_GSH_CODETRANSFER_DATA7" },
424
425 { 0x2A5, "GPUREG_GSH_OPDESCS_INDEX" },
426 { 0x2A6, "GPUREG_GSH_OPDESCS_DATA0" },
427 { 0x2A7, "GPUREG_GSH_OPDESCS_DATA1" },
428 { 0x2A8, "GPUREG_GSH_OPDESCS_DATA2" },
429 { 0x2A9, "GPUREG_GSH_OPDESCS_DATA3" },
430 { 0x2AA, "GPUREG_GSH_OPDESCS_DATA4" },
431 { 0x2AB, "GPUREG_GSH_OPDESCS_DATA5" },
432 { 0x2AC, "GPUREG_GSH_OPDESCS_DATA6" },
433 { 0x2AD, "GPUREG_GSH_OPDESCS_DATA7" },
434
435 { 0x2B0, "GPUREG_VSH_BOOLUNIFORM" },
436 { 0x2B1, "GPUREG_VSH_INTUNIFORM_I0" },
437 { 0x2B2, "GPUREG_VSH_INTUNIFORM_I1" },
438 { 0x2B3, "GPUREG_VSH_INTUNIFORM_I2" },
439 { 0x2B4, "GPUREG_VSH_INTUNIFORM_I3" },
440
441 { 0x2B9, "GPUREG_VSH_INPUTBUFFER_CONFIG" },
442 { 0x2BA, "GPUREG_VSH_ENTRYPOINT" },
443 { 0x2BB, "GPUREG_VSH_ATTRIBUTES_PERMUTATION_LOW" },
444 { 0x2BC, "GPUREG_VSH_ATTRIBUTES_PERMUTATION_HIGH" },
445 { 0x2BD, "GPUREG_VSH_OUTMAP_MASK" },
446
447 { 0x2BF, "GPUREG_VSH_CODETRANSFER_END" },
448 { 0x2C0, "GPUREG_VSH_FLOATUNIFORM_INDEX" },
449 { 0x2C1, "GPUREG_VSH_FLOATUNIFORM_DATA0" },
450 { 0x2C2, "GPUREG_VSH_FLOATUNIFORM_DATA1" },
451 { 0x2C3, "GPUREG_VSH_FLOATUNIFORM_DATA2" },
452 { 0x2C4, "GPUREG_VSH_FLOATUNIFORM_DATA3" },
453 { 0x2C5, "GPUREG_VSH_FLOATUNIFORM_DATA4" },
454 { 0x2C6, "GPUREG_VSH_FLOATUNIFORM_DATA5" },
455 { 0x2C7, "GPUREG_VSH_FLOATUNIFORM_DATA6" },
456 { 0x2C8, "GPUREG_VSH_FLOATUNIFORM_DATA7" },
457
458 { 0x2CB, "GPUREG_VSH_CODETRANSFER_INDEX" },
459 { 0x2CC, "GPUREG_VSH_CODETRANSFER_DATA0" },
460 { 0x2CD, "GPUREG_VSH_CODETRANSFER_DATA1" },
461 { 0x2CE, "GPUREG_VSH_CODETRANSFER_DATA2" },
462 { 0x2CF, "GPUREG_VSH_CODETRANSFER_DATA3" },
463 { 0x2D0, "GPUREG_VSH_CODETRANSFER_DATA4" },
464 { 0x2D1, "GPUREG_VSH_CODETRANSFER_DATA5" },
465 { 0x2D2, "GPUREG_VSH_CODETRANSFER_DATA6" },
466 { 0x2D3, "GPUREG_VSH_CODETRANSFER_DATA7" },
467
468 { 0x2D5, "GPUREG_VSH_OPDESCS_INDEX" },
469 { 0x2D6, "GPUREG_VSH_OPDESCS_DATA0" },
470 { 0x2D7, "GPUREG_VSH_OPDESCS_DATA1" },
471 { 0x2D8, "GPUREG_VSH_OPDESCS_DATA2" },
472 { 0x2D9, "GPUREG_VSH_OPDESCS_DATA3" },
473 { 0x2DA, "GPUREG_VSH_OPDESCS_DATA4" },
474 { 0x2DB, "GPUREG_VSH_OPDESCS_DATA5" },
475 { 0x2DC, "GPUREG_VSH_OPDESCS_DATA6" },
476 { 0x2DD, "GPUREG_VSH_OPDESCS_DATA7" },
477};
478
15std::string Regs::GetCommandName(int index) { 479std::string Regs::GetCommandName(int index) {
16 static std::unordered_map<u32, std::string> map; 480 static std::unordered_map<u32, const char*> map;
17 481
18 if (map.empty()) { 482 if (map.empty()) {
19 #define ADD_FIELD(name) \ 483 map.insert(begin(register_names), end(register_names));
20 map.insert({static_cast<u32>(PICA_REG_INDEX(name)), #name}); \
21 /* TODO: change to Regs::name when VS2015 and other compilers support it */ \
22 for (u32 i = PICA_REG_INDEX(name) + 1; i < PICA_REG_INDEX(name) + sizeof(Regs().name) / 4; ++i) \
23 map.insert({i, #name + std::string("+") + std::to_string(i-PICA_REG_INDEX(name))}); \
24
25 ADD_FIELD(trigger_irq);
26 ADD_FIELD(cull_mode);
27 ADD_FIELD(viewport_size_x);
28 ADD_FIELD(viewport_size_y);
29 ADD_FIELD(viewport_depth_range);
30 ADD_FIELD(viewport_depth_far_plane);
31 ADD_FIELD(viewport_corner);
32 ADD_FIELD(texture0_enable);
33 ADD_FIELD(texture0);
34 ADD_FIELD(texture0_format);
35 ADD_FIELD(texture1);
36 ADD_FIELD(texture1_format);
37 ADD_FIELD(texture2);
38 ADD_FIELD(texture2_format);
39 ADD_FIELD(tev_stage0);
40 ADD_FIELD(tev_stage1);
41 ADD_FIELD(tev_stage2);
42 ADD_FIELD(tev_stage3);
43 ADD_FIELD(tev_combiner_buffer_input);
44 ADD_FIELD(tev_stage4);
45 ADD_FIELD(tev_stage5);
46 ADD_FIELD(tev_combiner_buffer_color);
47 ADD_FIELD(output_merger);
48 ADD_FIELD(framebuffer);
49 ADD_FIELD(vertex_attributes);
50 ADD_FIELD(index_array);
51 ADD_FIELD(num_vertices);
52 ADD_FIELD(vertex_offset);
53 ADD_FIELD(trigger_draw);
54 ADD_FIELD(trigger_draw_indexed);
55 ADD_FIELD(vs_default_attributes_setup);
56 ADD_FIELD(command_buffer);
57 ADD_FIELD(triangle_topology);
58 ADD_FIELD(restart_primitive);
59 ADD_FIELD(gs.bool_uniforms);
60 ADD_FIELD(gs.int_uniforms);
61 ADD_FIELD(gs.main_offset);
62 ADD_FIELD(gs.input_register_map);
63 ADD_FIELD(gs.uniform_setup);
64 ADD_FIELD(gs.program);
65 ADD_FIELD(gs.swizzle_patterns);
66 ADD_FIELD(vs.bool_uniforms);
67 ADD_FIELD(vs.int_uniforms);
68 ADD_FIELD(vs.main_offset);
69 ADD_FIELD(vs.input_register_map);
70 ADD_FIELD(vs.uniform_setup);
71 ADD_FIELD(vs.program);
72 ADD_FIELD(vs.swizzle_patterns);
73
74#undef ADD_FIELD
75 } 484 }
76 485
77 // Return empty string if no match is found 486 // Return empty string if no match is found
diff --git a/src/video_core/pica.h b/src/video_core/pica.h
index 2f1b2dec4..2e0c33201 100644
--- a/src/video_core/pica.h
+++ b/src/video_core/pica.h
@@ -16,6 +16,8 @@
16#include "common/vector_math.h" 16#include "common/vector_math.h"
17#include "common/logging/log.h" 17#include "common/logging/log.h"
18 18
19#include "pica_types.h"
20
19namespace Pica { 21namespace Pica {
20 22
21// Returns index corresponding to the Regs member labeled by field_name 23// Returns index corresponding to the Regs member labeled by field_name
@@ -239,7 +241,8 @@ struct Regs {
239 TextureConfig texture0; 241 TextureConfig texture0;
240 INSERT_PADDING_WORDS(0x8); 242 INSERT_PADDING_WORDS(0x8);
241 BitField<0, 4, TextureFormat> texture0_format; 243 BitField<0, 4, TextureFormat> texture0_format;
242 INSERT_PADDING_WORDS(0x2); 244 BitField<0, 1, u32> fragment_lighting_enable;
245 INSERT_PADDING_WORDS(0x1);
243 TextureConfig texture1; 246 TextureConfig texture1;
244 BitField<0, 4, TextureFormat> texture1_format; 247 BitField<0, 4, TextureFormat> texture1_format;
245 INSERT_PADDING_WORDS(0x2); 248 INSERT_PADDING_WORDS(0x2);
@@ -641,7 +644,268 @@ struct Regs {
641 } 644 }
642 } 645 }
643 646
644 INSERT_PADDING_WORDS(0xe0); 647 INSERT_PADDING_WORDS(0x20);
648
649 enum class LightingSampler {
650 Distribution0 = 0,
651 Distribution1 = 1,
652 Fresnel = 3,
653 ReflectBlue = 4,
654 ReflectGreen = 5,
655 ReflectRed = 6,
656 SpotlightAttenuation = 8,
657 DistanceAttenuation = 16,
658 };
659
660 /**
661 * Pica fragment lighting supports using different LUTs for each lighting component:
662 * Reflectance R, G, and B channels, distribution function for specular components 0 and 1,
663 * fresnel factor, and spotlight attenuation. Furthermore, which LUTs are used for each channel
664 * (or whether a channel is enabled at all) is specified by various pre-defined lighting
665 * configurations. With configurations that require more LUTs, more cycles are required on HW to
666 * perform lighting computations.
667 */
668 enum class LightingConfig {
669 Config0 = 0, ///< Reflect Red, Distribution 0, Spotlight
670 Config1 = 1, ///< Reflect Red, Fresnel, Spotlight
671 Config2 = 2, ///< Reflect Red, Distribution 0/1
672 Config3 = 3, ///< Distribution 0/1, Fresnel
673 Config4 = 4, ///< Reflect Red/Green/Blue, Distribution 0/1, Spotlight
674 Config5 = 5, ///< Reflect Red/Green/Blue, Distribution 0, Fresnel, Spotlight
675 Config6 = 6, ///< Reflect Red, Distribution 0/1, Fresnel, Spotlight
676 Config7 = 8, ///< Reflect Red/Green/Blue, Distribution 0/1, Fresnel, Spotlight
677 ///< NOTE: '8' is intentional, '7' does not appear to be a valid configuration
678 };
679
680 /// Selects which lighting components are affected by fresnel
681 enum class LightingFresnelSelector {
682 None = 0, ///< Fresnel is disabled
683 PrimaryAlpha = 1, ///< Primary (diffuse) lighting alpha is affected by fresnel
684 SecondaryAlpha = 2, ///< Secondary (specular) lighting alpha is affected by fresnel
685 Both = PrimaryAlpha | SecondaryAlpha, ///< Both primary and secondary lighting alphas are affected by fresnel
686 };
687
688 /// Factor used to scale the output of a lighting LUT
689 enum class LightingScale {
690 Scale1 = 0, ///< Scale is 1x
691 Scale2 = 1, ///< Scale is 2x
692 Scale4 = 2, ///< Scale is 4x
693 Scale8 = 3, ///< Scale is 8x
694 Scale1_4 = 6, ///< Scale is 0.25x
695 Scale1_2 = 7, ///< Scale is 0.5x
696 };
697
698 enum class LightingLutInput {
699 NH = 0, // Cosine of the angle between the normal and half-angle vectors
700 VH = 1, // Cosine of the angle between the view and half-angle vectors
701 NV = 2, // Cosine of the angle between the normal and the view vector
702 LN = 3, // Cosine of the angle between the light and the normal vectors
703 };
704
705 enum class LightingBumpMode : u32 {
706 None = 0,
707 NormalMap = 1,
708 TangentMap = 2,
709 };
710
711 union LightColor {
712 BitField< 0, 10, u32> b;
713 BitField<10, 10, u32> g;
714 BitField<20, 10, u32> r;
715
716 Math::Vec3f ToVec3f() const {
717 // These fields are 10 bits wide, however 255 corresponds to 1.0f for each color component
718 return Math::MakeVec((f32)r / 255.f, (f32)g / 255.f, (f32)b / 255.f);
719 }
720 };
721
722 /// Returns true if the specified lighting sampler is supported by the current Pica lighting configuration
723 static bool IsLightingSamplerSupported(LightingConfig config, LightingSampler sampler) {
724 switch (sampler) {
725 case LightingSampler::Distribution0:
726 return (config != LightingConfig::Config1);
727
728 case LightingSampler::Distribution1:
729 return (config != LightingConfig::Config0) && (config != LightingConfig::Config1) && (config != LightingConfig::Config5);
730
731 case LightingSampler::Fresnel:
732 return (config != LightingConfig::Config0) && (config != LightingConfig::Config2) && (config != LightingConfig::Config4);
733
734 case LightingSampler::ReflectRed:
735 return (config != LightingConfig::Config3);
736
737 case LightingSampler::ReflectGreen:
738 case LightingSampler::ReflectBlue:
739 return (config == LightingConfig::Config4) || (config == LightingConfig::Config5) || (config == LightingConfig::Config7);
740 }
741 return false;
742 }
743
744 struct {
745 struct LightSrc {
746 LightColor specular_0; // material.specular_0 * light.specular_0
747 LightColor specular_1; // material.specular_1 * light.specular_1
748 LightColor diffuse; // material.diffuse * light.diffuse
749 LightColor ambient; // material.ambient * light.ambient
750
751 struct {
752 // Encoded as 16-bit floating point
753 union {
754 BitField< 0, 16, u32> x;
755 BitField<16, 16, u32> y;
756 };
757 union {
758 BitField< 0, 16, u32> z;
759 };
760
761 INSERT_PADDING_WORDS(0x3);
762
763 union {
764 BitField<0, 1, u32> directional;
765 BitField<1, 1, u32> two_sided_diffuse; // When disabled, clamp dot-product to 0
766 };
767 };
768
769 BitField<0, 20, u32> dist_atten_bias;
770 BitField<0, 20, u32> dist_atten_scale;
771
772 INSERT_PADDING_WORDS(0x4);
773 };
774 static_assert(sizeof(LightSrc) == 0x10 * sizeof(u32), "LightSrc structure must be 0x10 words");
775
776 LightSrc light[8];
777 LightColor global_ambient; // Emission + (material.ambient * lighting.ambient)
778 INSERT_PADDING_WORDS(0x1);
779 BitField<0, 3, u32> num_lights; // Number of enabled lights - 1
780
781 union {
782 BitField< 2, 2, LightingFresnelSelector> fresnel_selector;
783 BitField< 4, 4, LightingConfig> config;
784 BitField<22, 2, u32> bump_selector; // 0: Texture 0, 1: Texture 1, 2: Texture 2
785 BitField<27, 1, u32> clamp_highlights;
786 BitField<28, 2, LightingBumpMode> bump_mode;
787 BitField<30, 1, u32> disable_bump_renorm;
788 };
789
790 union {
791 BitField<16, 1, u32> disable_lut_d0;
792 BitField<17, 1, u32> disable_lut_d1;
793 BitField<19, 1, u32> disable_lut_fr;
794 BitField<20, 1, u32> disable_lut_rr;
795 BitField<21, 1, u32> disable_lut_rg;
796 BitField<22, 1, u32> disable_lut_rb;
797
798 // Each bit specifies whether distance attenuation should be applied for the
799 // corresponding light
800
801 BitField<24, 1, u32> disable_dist_atten_light_0;
802 BitField<25, 1, u32> disable_dist_atten_light_1;
803 BitField<26, 1, u32> disable_dist_atten_light_2;
804 BitField<27, 1, u32> disable_dist_atten_light_3;
805 BitField<28, 1, u32> disable_dist_atten_light_4;
806 BitField<29, 1, u32> disable_dist_atten_light_5;
807 BitField<30, 1, u32> disable_dist_atten_light_6;
808 BitField<31, 1, u32> disable_dist_atten_light_7;
809 };
810
811 bool IsDistAttenDisabled(unsigned index) const {
812 const unsigned disable[] = { disable_dist_atten_light_0, disable_dist_atten_light_1,
813 disable_dist_atten_light_2, disable_dist_atten_light_3,
814 disable_dist_atten_light_4, disable_dist_atten_light_5,
815 disable_dist_atten_light_6, disable_dist_atten_light_7 };
816 return disable[index] != 0;
817 }
818
819 union {
820 BitField<0, 8, u32> index; ///< Index at which to set data in the LUT
821 BitField<8, 5, u32> type; ///< Type of LUT for which to set data
822 } lut_config;
823
824 BitField<0, 1, u32> disable;
825 INSERT_PADDING_WORDS(0x1);
826
827 // When data is written to any of these registers, it gets written to the lookup table of
828 // the selected type at the selected index, specified above in the `lut_config` register.
829 // With each write, `lut_config.index` is incremented. It does not matter which of these
830 // registers is written to, the behavior will be the same.
831 u32 lut_data[8];
832
833 // These are used to specify if absolute (abs) value should be used for each LUT index. When
834 // abs mode is disabled, LUT indexes are in the range of (-1.0, 1.0). Otherwise, they are in
835 // the range of (0.0, 1.0).
836 union {
837 BitField< 1, 1, u32> disable_d0;
838 BitField< 5, 1, u32> disable_d1;
839 BitField< 9, 1, u32> disable_sp;
840 BitField<13, 1, u32> disable_fr;
841 BitField<17, 1, u32> disable_rb;
842 BitField<21, 1, u32> disable_rg;
843 BitField<25, 1, u32> disable_rr;
844 } abs_lut_input;
845
846 union {
847 BitField< 0, 3, LightingLutInput> d0;
848 BitField< 4, 3, LightingLutInput> d1;
849 BitField< 8, 3, LightingLutInput> sp;
850 BitField<12, 3, LightingLutInput> fr;
851 BitField<16, 3, LightingLutInput> rb;
852 BitField<20, 3, LightingLutInput> rg;
853 BitField<24, 3, LightingLutInput> rr;
854 } lut_input;
855
856 union {
857 BitField< 0, 3, LightingScale> d0;
858 BitField< 4, 3, LightingScale> d1;
859 BitField< 8, 3, LightingScale> sp;
860 BitField<12, 3, LightingScale> fr;
861 BitField<16, 3, LightingScale> rb;
862 BitField<20, 3, LightingScale> rg;
863 BitField<24, 3, LightingScale> rr;
864
865 static float GetScale(LightingScale scale) {
866 switch (scale) {
867 case LightingScale::Scale1:
868 return 1.0f;
869 case LightingScale::Scale2:
870 return 2.0f;
871 case LightingScale::Scale4:
872 return 4.0f;
873 case LightingScale::Scale8:
874 return 8.0f;
875 case LightingScale::Scale1_4:
876 return 0.25f;
877 case LightingScale::Scale1_2:
878 return 0.5f;
879 }
880 return 0.0f;
881 }
882 } lut_scale;
883
884 INSERT_PADDING_WORDS(0x6);
885
886 union {
887 // There are 8 light enable "slots", corresponding to the total number of lights
888 // supported by Pica. For N enabled lights (specified by register 0x1c2, or 'src_num'
889 // above), the first N slots below will be set to integers within the range of 0-7,
890 // corresponding to the actual light that is enabled for each slot.
891
892 BitField< 0, 3, u32> slot_0;
893 BitField< 4, 3, u32> slot_1;
894 BitField< 8, 3, u32> slot_2;
895 BitField<12, 3, u32> slot_3;
896 BitField<16, 3, u32> slot_4;
897 BitField<20, 3, u32> slot_5;
898 BitField<24, 3, u32> slot_6;
899 BitField<28, 3, u32> slot_7;
900
901 unsigned GetNum(unsigned index) const {
902 const unsigned enable_slots[] = { slot_0, slot_1, slot_2, slot_3, slot_4, slot_5, slot_6, slot_7 };
903 return enable_slots[index];
904 }
905 } light_enable;
906 } lighting;
907
908 INSERT_PADDING_WORDS(0x26);
645 909
646 enum class VertexAttributeFormat : u64 { 910 enum class VertexAttributeFormat : u64 {
647 BYTE = 0, 911 BYTE = 0,
@@ -825,7 +1089,16 @@ struct Regs {
825 } 1089 }
826 } command_buffer; 1090 } command_buffer;
827 1091
828 INSERT_PADDING_WORDS(0x20); 1092 INSERT_PADDING_WORDS(0x07);
1093
1094 enum class GPUMode : u32 {
1095 Drawing = 0,
1096 Configuring = 1
1097 };
1098
1099 GPUMode gpu_mode;
1100
1101 INSERT_PADDING_WORDS(0x18);
829 1102
830 enum class TriangleTopology : u32 { 1103 enum class TriangleTopology : u32 {
831 List = 0, 1104 List = 0,
@@ -990,6 +1263,7 @@ ASSERT_REG_POSITION(viewport_corner, 0x68);
990ASSERT_REG_POSITION(texture0_enable, 0x80); 1263ASSERT_REG_POSITION(texture0_enable, 0x80);
991ASSERT_REG_POSITION(texture0, 0x81); 1264ASSERT_REG_POSITION(texture0, 0x81);
992ASSERT_REG_POSITION(texture0_format, 0x8e); 1265ASSERT_REG_POSITION(texture0_format, 0x8e);
1266ASSERT_REG_POSITION(fragment_lighting_enable, 0x8f);
993ASSERT_REG_POSITION(texture1, 0x91); 1267ASSERT_REG_POSITION(texture1, 0x91);
994ASSERT_REG_POSITION(texture1_format, 0x96); 1268ASSERT_REG_POSITION(texture1_format, 0x96);
995ASSERT_REG_POSITION(texture2, 0x99); 1269ASSERT_REG_POSITION(texture2, 0x99);
@@ -1004,6 +1278,7 @@ ASSERT_REG_POSITION(tev_stage5, 0xf8);
1004ASSERT_REG_POSITION(tev_combiner_buffer_color, 0xfd); 1278ASSERT_REG_POSITION(tev_combiner_buffer_color, 0xfd);
1005ASSERT_REG_POSITION(output_merger, 0x100); 1279ASSERT_REG_POSITION(output_merger, 0x100);
1006ASSERT_REG_POSITION(framebuffer, 0x110); 1280ASSERT_REG_POSITION(framebuffer, 0x110);
1281ASSERT_REG_POSITION(lighting, 0x140);
1007ASSERT_REG_POSITION(vertex_attributes, 0x200); 1282ASSERT_REG_POSITION(vertex_attributes, 0x200);
1008ASSERT_REG_POSITION(index_array, 0x227); 1283ASSERT_REG_POSITION(index_array, 0x227);
1009ASSERT_REG_POSITION(num_vertices, 0x228); 1284ASSERT_REG_POSITION(num_vertices, 0x228);
@@ -1012,6 +1287,7 @@ ASSERT_REG_POSITION(trigger_draw, 0x22e);
1012ASSERT_REG_POSITION(trigger_draw_indexed, 0x22f); 1287ASSERT_REG_POSITION(trigger_draw_indexed, 0x22f);
1013ASSERT_REG_POSITION(vs_default_attributes_setup, 0x232); 1288ASSERT_REG_POSITION(vs_default_attributes_setup, 0x232);
1014ASSERT_REG_POSITION(command_buffer, 0x238); 1289ASSERT_REG_POSITION(command_buffer, 0x238);
1290ASSERT_REG_POSITION(gpu_mode, 0x245);
1015ASSERT_REG_POSITION(triangle_topology, 0x25e); 1291ASSERT_REG_POSITION(triangle_topology, 0x25e);
1016ASSERT_REG_POSITION(restart_primitive, 0x25f); 1292ASSERT_REG_POSITION(restart_primitive, 0x25f);
1017ASSERT_REG_POSITION(gs, 0x280); 1293ASSERT_REG_POSITION(gs, 0x280);
@@ -1026,157 +1302,10 @@ static_assert(sizeof(Regs::ShaderConfig) == 0x30 * sizeof(u32), "ShaderConfig st
1026static_assert(sizeof(Regs) <= 0x300 * sizeof(u32), "Register set structure larger than it should be"); 1302static_assert(sizeof(Regs) <= 0x300 * sizeof(u32), "Register set structure larger than it should be");
1027static_assert(sizeof(Regs) >= 0x300 * sizeof(u32), "Register set structure smaller than it should be"); 1303static_assert(sizeof(Regs) >= 0x300 * sizeof(u32), "Register set structure smaller than it should be");
1028 1304
1029struct float24 {
1030 static float24 FromFloat32(float val) {
1031 float24 ret;
1032 ret.value = val;
1033 return ret;
1034 }
1035
1036 // 16 bit mantissa, 7 bit exponent, 1 bit sign
1037 // TODO: No idea if this works as intended
1038 static float24 FromRawFloat24(u32 hex) {
1039 float24 ret;
1040 if ((hex & 0xFFFFFF) == 0) {
1041 ret.value = 0;
1042 } else {
1043 u32 mantissa = hex & 0xFFFF;
1044 u32 exponent = (hex >> 16) & 0x7F;
1045 u32 sign = hex >> 23;
1046 ret.value = std::pow(2.0f, (float)exponent-63.0f) * (1.0f + mantissa * std::pow(2.0f, -16.f));
1047 if (sign)
1048 ret.value = -ret.value;
1049 }
1050 return ret;
1051 }
1052
1053 static float24 Zero() {
1054 return FromFloat32(0.f);
1055 }
1056
1057 // Not recommended for anything but logging
1058 float ToFloat32() const {
1059 return value;
1060 }
1061
1062 float24 operator * (const float24& flt) const {
1063 if ((this->value == 0.f && !std::isnan(flt.value)) ||
1064 (flt.value == 0.f && !std::isnan(this->value)))
1065 // PICA gives 0 instead of NaN when multiplying by inf
1066 return Zero();
1067 return float24::FromFloat32(ToFloat32() * flt.ToFloat32());
1068 }
1069
1070 float24 operator / (const float24& flt) const {
1071 return float24::FromFloat32(ToFloat32() / flt.ToFloat32());
1072 }
1073
1074 float24 operator + (const float24& flt) const {
1075 return float24::FromFloat32(ToFloat32() + flt.ToFloat32());
1076 }
1077
1078 float24 operator - (const float24& flt) const {
1079 return float24::FromFloat32(ToFloat32() - flt.ToFloat32());
1080 }
1081
1082 float24& operator *= (const float24& flt) {
1083 if ((this->value == 0.f && !std::isnan(flt.value)) ||
1084 (flt.value == 0.f && !std::isnan(this->value)))
1085 // PICA gives 0 instead of NaN when multiplying by inf
1086 *this = Zero();
1087 else value *= flt.ToFloat32();
1088 return *this;
1089 }
1090
1091 float24& operator /= (const float24& flt) {
1092 value /= flt.ToFloat32();
1093 return *this;
1094 }
1095
1096 float24& operator += (const float24& flt) {
1097 value += flt.ToFloat32();
1098 return *this;
1099 }
1100
1101 float24& operator -= (const float24& flt) {
1102 value -= flt.ToFloat32();
1103 return *this;
1104 }
1105
1106 float24 operator - () const {
1107 return float24::FromFloat32(-ToFloat32());
1108 }
1109
1110 bool operator < (const float24& flt) const {
1111 return ToFloat32() < flt.ToFloat32();
1112 }
1113
1114 bool operator > (const float24& flt) const {
1115 return ToFloat32() > flt.ToFloat32();
1116 }
1117
1118 bool operator >= (const float24& flt) const {
1119 return ToFloat32() >= flt.ToFloat32();
1120 }
1121
1122 bool operator <= (const float24& flt) const {
1123 return ToFloat32() <= flt.ToFloat32();
1124 }
1125
1126 bool operator == (const float24& flt) const {
1127 return ToFloat32() == flt.ToFloat32();
1128 }
1129
1130 bool operator != (const float24& flt) const {
1131 return ToFloat32() != flt.ToFloat32();
1132 }
1133
1134private:
1135 // Stored as a regular float, merely for convenience
1136 // TODO: Perform proper arithmetic on this!
1137 float value;
1138};
1139static_assert(sizeof(float24) == sizeof(float), "Shader JIT assumes float24 is implemented as a 32-bit float");
1140
1141/// Struct used to describe current Pica state
1142struct State {
1143 /// Pica registers
1144 Regs regs;
1145
1146 /// Vertex shader memory
1147 struct ShaderSetup {
1148 struct {
1149 // The float uniforms are accessed by the shader JIT using SSE instructions, and are
1150 // therefore required to be 16-byte aligned.
1151 Math::Vec4<float24> MEMORY_ALIGNED16(f[96]);
1152
1153 std::array<bool, 16> b;
1154 std::array<Math::Vec4<u8>, 4> i;
1155 } uniforms;
1156
1157 Math::Vec4<float24> default_attributes[16];
1158
1159 std::array<u32, 1024> program_code;
1160 std::array<u32, 1024> swizzle_data;
1161 };
1162
1163 ShaderSetup vs;
1164 ShaderSetup gs;
1165
1166 /// Current Pica command list
1167 struct {
1168 const u32* head_ptr;
1169 const u32* current_ptr;
1170 u32 length;
1171 } cmd_list;
1172};
1173
1174/// Initialize Pica state 1305/// Initialize Pica state
1175void Init(); 1306void Init();
1176 1307
1177/// Shutdown Pica state 1308/// Shutdown Pica state
1178void Shutdown(); 1309void Shutdown();
1179 1310
1180extern State g_state; ///< Current Pica state
1181
1182} // namespace 1311} // namespace
diff --git a/src/video_core/pica_state.h b/src/video_core/pica_state.h
new file mode 100644
index 000000000..c7616bc55
--- /dev/null
+++ b/src/video_core/pica_state.h
@@ -0,0 +1,60 @@
1// Copyright 2016 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 "video_core/pica.h"
8#include "video_core/primitive_assembly.h"
9#include "video_core/shader/shader.h"
10
11namespace Pica {
12
13/// Struct used to describe current Pica state
14struct State {
15 /// Pica registers
16 Regs regs;
17
18 Shader::ShaderSetup vs;
19 Shader::ShaderSetup gs;
20
21 struct {
22 union LutEntry {
23 // Used for raw access
24 u32 raw;
25
26 // LUT value, encoded as 12-bit fixed point, with 12 fraction bits
27 BitField< 0, 12, u32> value;
28
29 // Used by HW for efficient interpolation, Citra does not use these
30 BitField<12, 12, u32> difference;
31
32 float ToFloat() {
33 return static_cast<float>(value) / 4095.f;
34 }
35 };
36
37 std::array<std::array<LutEntry, 256>, 24> luts;
38 } lighting;
39
40 /// Current Pica command list
41 struct {
42 const u32* head_ptr;
43 const u32* current_ptr;
44 u32 length;
45 } cmd_list;
46
47 /// Struct used to describe immediate mode rendering state
48 struct ImmediateModeState {
49 Shader::InputVertex input;
50 // This is constructed with a dummy triangle topology
51 PrimitiveAssembler<Shader::OutputVertex> primitive_assembler;
52 int attribute_id = 0;
53
54 ImmediateModeState() : primitive_assembler(Regs::TriangleTopology::List) {}
55 } immediate;
56};
57
58extern State g_state; ///< Current Pica state
59
60} // namespace
diff --git a/src/video_core/pica_types.h b/src/video_core/pica_types.h
new file mode 100644
index 000000000..ecf45654b
--- /dev/null
+++ b/src/video_core/pica_types.h
@@ -0,0 +1,146 @@
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 <cstring>
8
9#include "common/common_types.h"
10
11namespace Pica {
12
13/**
14 * Template class for converting arbitrary Pica float types to IEEE 754 32-bit single-precision
15 * floating point.
16 *
17 * When decoding, format is as follows:
18 * - The first `M` bits are the mantissa
19 * - The next `E` bits are the exponent
20 * - The last bit is the sign bit
21 *
22 * @todo Verify on HW if this conversion is sufficiently accurate.
23 */
24template<unsigned M, unsigned E>
25struct Float {
26public:
27 static Float<M, E> FromFloat32(float val) {
28 Float<M, E> ret;
29 ret.value = val;
30 return ret;
31 }
32
33 static Float<M, E> FromRaw(u32 hex) {
34 Float<M, E> res;
35
36 const int width = M + E + 1;
37 const int bias = 128 - (1 << (E - 1));
38 const int exponent = (hex >> M) & ((1 << E) - 1);
39 const unsigned mantissa = hex & ((1 << M) - 1);
40
41 if (hex & ((1 << (width - 1)) - 1))
42 hex = ((hex >> (E + M)) << 31) | (mantissa << (23 - M)) | ((exponent + bias) << 23);
43 else
44 hex = ((hex >> (E + M)) << 31);
45
46 std::memcpy(&res.value, &hex, sizeof(float));
47
48 return res;
49 }
50
51 static Float<M, E> Zero() {
52 return FromFloat32(0.f);
53 }
54
55 // Not recommended for anything but logging
56 float ToFloat32() const {
57 return value;
58 }
59
60 Float<M, E> operator * (const Float<M, E>& flt) const {
61 if ((this->value == 0.f && !std::isnan(flt.value)) ||
62 (flt.value == 0.f && !std::isnan(this->value)))
63 // PICA gives 0 instead of NaN when multiplying by inf
64 return Zero();
65 return Float<M, E>::FromFloat32(ToFloat32() * flt.ToFloat32());
66 }
67
68 Float<M, E> operator / (const Float<M, E>& flt) const {
69 return Float<M, E>::FromFloat32(ToFloat32() / flt.ToFloat32());
70 }
71
72 Float<M, E> operator + (const Float<M, E>& flt) const {
73 return Float<M, E>::FromFloat32(ToFloat32() + flt.ToFloat32());
74 }
75
76 Float<M, E> operator - (const Float<M, E>& flt) const {
77 return Float<M, E>::FromFloat32(ToFloat32() - flt.ToFloat32());
78 }
79
80 Float<M, E>& operator *= (const Float<M, E>& flt) {
81 if ((this->value == 0.f && !std::isnan(flt.value)) ||
82 (flt.value == 0.f && !std::isnan(this->value)))
83 // PICA gives 0 instead of NaN when multiplying by inf
84 *this = Zero();
85 else value *= flt.ToFloat32();
86 return *this;
87 }
88
89 Float<M, E>& operator /= (const Float<M, E>& flt) {
90 value /= flt.ToFloat32();
91 return *this;
92 }
93
94 Float<M, E>& operator += (const Float<M, E>& flt) {
95 value += flt.ToFloat32();
96 return *this;
97 }
98
99 Float<M, E>& operator -= (const Float<M, E>& flt) {
100 value -= flt.ToFloat32();
101 return *this;
102 }
103
104 Float<M, E> operator - () const {
105 return Float<M, E>::FromFloat32(-ToFloat32());
106 }
107
108 bool operator < (const Float<M, E>& flt) const {
109 return ToFloat32() < flt.ToFloat32();
110 }
111
112 bool operator > (const Float<M, E>& flt) const {
113 return ToFloat32() > flt.ToFloat32();
114 }
115
116 bool operator >= (const Float<M, E>& flt) const {
117 return ToFloat32() >= flt.ToFloat32();
118 }
119
120 bool operator <= (const Float<M, E>& flt) const {
121 return ToFloat32() <= flt.ToFloat32();
122 }
123
124 bool operator == (const Float<M, E>& flt) const {
125 return ToFloat32() == flt.ToFloat32();
126 }
127
128 bool operator != (const Float<M, E>& flt) const {
129 return ToFloat32() != flt.ToFloat32();
130 }
131
132private:
133 static const unsigned MASK = (1 << (M + E + 1)) - 1;
134 static const unsigned MANTISSA_MASK = (1 << M) - 1;
135 static const unsigned EXPONENT_MASK = (1 << E) - 1;
136
137 // Stored as a regular float, merely for convenience
138 // TODO: Perform proper arithmetic on this!
139 float value;
140};
141
142using float24 = Float<16, 7>;
143using float20 = Float<12, 7>;
144using float16 = Float<10, 5>;
145
146} // namespace Pica
diff --git a/src/video_core/primitive_assembly.cpp b/src/video_core/primitive_assembly.cpp
index 44a8dbfe9..0061690f1 100644
--- a/src/video_core/primitive_assembly.cpp
+++ b/src/video_core/primitive_assembly.cpp
@@ -39,13 +39,12 @@ void PrimitiveAssembler<VertexType>::SubmitVertex(VertexType& vtx, TriangleHandl
39 39
40 buffer[buffer_index] = vtx; 40 buffer[buffer_index] = vtx;
41 41
42 if (topology == Regs::TriangleTopology::Strip) { 42 strip_ready |= (buffer_index == 1);
43 strip_ready |= (buffer_index == 1); 43
44 if (topology == Regs::TriangleTopology::Strip)
44 buffer_index = !buffer_index; 45 buffer_index = !buffer_index;
45 } else if (topology == Regs::TriangleTopology::Fan) { 46 else if (topology == Regs::TriangleTopology::Fan)
46 buffer_index = 1; 47 buffer_index = 1;
47 strip_ready = true;
48 }
49 break; 48 break;
50 49
51 default: 50 default:
@@ -54,6 +53,18 @@ void PrimitiveAssembler<VertexType>::SubmitVertex(VertexType& vtx, TriangleHandl
54 } 53 }
55} 54}
56 55
56template<typename VertexType>
57void PrimitiveAssembler<VertexType>::Reset() {
58 buffer_index = 0;
59 strip_ready = false;
60}
61
62template<typename VertexType>
63void PrimitiveAssembler<VertexType>::Reconfigure(Regs::TriangleTopology topology) {
64 Reset();
65 this->topology = topology;
66}
67
57// explicitly instantiate use cases 68// explicitly instantiate use cases
58template 69template
59struct PrimitiveAssembler<Shader::OutputVertex>; 70struct PrimitiveAssembler<Shader::OutputVertex>;
diff --git a/src/video_core/primitive_assembly.h b/src/video_core/primitive_assembly.h
index 52d0ec8ff..cc6e5fde5 100644
--- a/src/video_core/primitive_assembly.h
+++ b/src/video_core/primitive_assembly.h
@@ -30,6 +30,16 @@ struct PrimitiveAssembler {
30 */ 30 */
31 void SubmitVertex(VertexType& vtx, TriangleHandler triangle_handler); 31 void SubmitVertex(VertexType& vtx, TriangleHandler triangle_handler);
32 32
33 /**
34 * Resets the internal state of the PrimitiveAssembler.
35 */
36 void Reset();
37
38 /**
39 * Reconfigures the PrimitiveAssembler to use a different triangle topology.
40 */
41 void Reconfigure(Regs::TriangleTopology topology);
42
33private: 43private:
34 Regs::TriangleTopology topology; 44 Regs::TriangleTopology topology;
35 45
diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp
index ecfdbc9e8..fd02aa652 100644
--- a/src/video_core/rasterizer.cpp
+++ b/src/video_core/rasterizer.cpp
@@ -15,6 +15,7 @@
15#include "core/hw/gpu.h" 15#include "core/hw/gpu.h"
16 16
17#include "video_core/pica.h" 17#include "video_core/pica.h"
18#include "video_core/pica_state.h"
18#include "video_core/rasterizer.h" 19#include "video_core/rasterizer.h"
19#include "video_core/utils.h" 20#include "video_core/utils.h"
20#include "video_core/debug_utils/debug_utils.h" 21#include "video_core/debug_utils/debug_utils.h"
@@ -857,12 +858,12 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0,
857 } 858 }
858 } 859 }
859 860
860 // TODO: Does depth indeed only get written even if depth testing is enabled? 861 unsigned num_bits = Regs::DepthBitsPerPixel(regs.framebuffer.depth_format);
862 u32 z = (u32)((v0.screenpos[2].ToFloat32() * w0 +
863 v1.screenpos[2].ToFloat32() * w1 +
864 v2.screenpos[2].ToFloat32() * w2) * ((1 << num_bits) - 1) / wsum);
865
861 if (output_merger.depth_test_enable) { 866 if (output_merger.depth_test_enable) {
862 unsigned num_bits = Regs::DepthBitsPerPixel(regs.framebuffer.depth_format);
863 u32 z = (u32)((v0.screenpos[2].ToFloat32() * w0 +
864 v1.screenpos[2].ToFloat32() * w1 +
865 v2.screenpos[2].ToFloat32() * w2) * ((1 << num_bits) - 1) / wsum);
866 u32 ref_z = GetDepth(x >> 4, y >> 4); 867 u32 ref_z = GetDepth(x >> 4, y >> 4);
867 868
868 bool pass = false; 869 bool pass = false;
@@ -906,11 +907,11 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0,
906 UpdateStencil(stencil_test.action_depth_fail); 907 UpdateStencil(stencil_test.action_depth_fail);
907 continue; 908 continue;
908 } 909 }
909
910 if (output_merger.depth_write_enable)
911 SetDepth(x >> 4, y >> 4, z);
912 } 910 }
913 911
912 if (output_merger.depth_write_enable)
913 SetDepth(x >> 4, y >> 4, z);
914
914 // The stencil depth_pass action is executed even if depth testing is disabled 915 // The stencil depth_pass action is executed even if depth testing is disabled
915 if (stencil_action_enable) 916 if (stencil_action_enable)
916 UpdateStencil(stencil_test.action_depth_pass); 917 UpdateStencil(stencil_test.action_depth_pass);
diff --git a/src/video_core/hwrasterizer_base.h b/src/video_core/rasterizer_interface.h
index 54b8892fb..008c5827b 100644
--- a/src/video_core/hwrasterizer_base.h
+++ b/src/video_core/rasterizer_interface.h
@@ -12,10 +12,11 @@ struct OutputVertex;
12} 12}
13} 13}
14 14
15class HWRasterizer { 15namespace VideoCore {
16
17class RasterizerInterface {
16public: 18public:
17 virtual ~HWRasterizer() { 19 virtual ~RasterizerInterface() {}
18 }
19 20
20 /// Initialize API-specific GPU objects 21 /// Initialize API-specific GPU objects
21 virtual void InitObjects() = 0; 22 virtual void InitObjects() = 0;
@@ -32,14 +33,16 @@ public:
32 virtual void DrawTriangles() = 0; 33 virtual void DrawTriangles() = 0;
33 34
34 /// Commit the rasterizer's framebuffer contents immediately to the current 3DS memory framebuffer 35 /// Commit the rasterizer's framebuffer contents immediately to the current 3DS memory framebuffer
35 virtual void CommitFramebuffer() = 0; 36 virtual void FlushFramebuffer() = 0;
36 37
37 /// Notify rasterizer that the specified PICA register has been changed 38 /// Notify rasterizer that the specified PICA register has been changed
38 virtual void NotifyPicaRegisterChanged(u32 id) = 0; 39 virtual void NotifyPicaRegisterChanged(u32 id) = 0;
39 40
40 /// Notify rasterizer that the specified 3DS memory region will be read from after this notification 41 /// Notify rasterizer that any caches of the specified region should be flushed to 3DS memory.
41 virtual void NotifyPreRead(PAddr addr, u32 size) = 0; 42 virtual void FlushRegion(PAddr addr, u32 size) = 0;
42 43
43 /// Notify rasterizer that a 3DS memory region has been changed 44 /// Notify rasterizer that any caches of the specified region should be discraded and reloaded from 3DS memory.
44 virtual void NotifyFlush(PAddr addr, u32 size) = 0; 45 virtual void InvalidateRegion(PAddr addr, u32 size) = 0;
45}; 46};
47
48}
diff --git a/src/video_core/renderer_base.cpp b/src/video_core/renderer_base.cpp
new file mode 100644
index 000000000..6467ff723
--- /dev/null
+++ b/src/video_core/renderer_base.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 <memory>
6
7#include "common/make_unique.h"
8
9#include "core/settings.h"
10
11#include "video_core/renderer_base.h"
12#include "video_core/video_core.h"
13#include "video_core/swrasterizer.h"
14#include "video_core/renderer_opengl/gl_rasterizer.h"
15
16void RendererBase::RefreshRasterizerSetting() {
17 bool hw_renderer_enabled = VideoCore::g_hw_renderer_enabled;
18 if (rasterizer == nullptr || opengl_rasterizer_active != hw_renderer_enabled) {
19 opengl_rasterizer_active = hw_renderer_enabled;
20
21 if (hw_renderer_enabled) {
22 rasterizer = Common::make_unique<RasterizerOpenGL>();
23 } else {
24 rasterizer = Common::make_unique<VideoCore::SWRasterizer>();
25 }
26 rasterizer->InitObjects();
27 rasterizer->Reset();
28 }
29}
diff --git a/src/video_core/renderer_base.h b/src/video_core/renderer_base.h
index 6587bcf27..f68091cc8 100644
--- a/src/video_core/renderer_base.h
+++ b/src/video_core/renderer_base.h
@@ -8,7 +8,7 @@
8 8
9#include "common/common_types.h" 9#include "common/common_types.h"
10 10
11#include "video_core/hwrasterizer_base.h" 11#include "video_core/rasterizer_interface.h"
12 12
13class EmuWindow; 13class EmuWindow;
14 14
@@ -22,9 +22,6 @@ public:
22 kFramebuffer_Texture 22 kFramebuffer_Texture
23 }; 23 };
24 24
25 RendererBase() : m_current_fps(0), m_current_frame(0) {
26 }
27
28 virtual ~RendererBase() { 25 virtual ~RendererBase() {
29 } 26 }
30 27
@@ -38,7 +35,7 @@ public:
38 virtual void SetWindow(EmuWindow* window) = 0; 35 virtual void SetWindow(EmuWindow* window) = 0;
39 36
40 /// Initialize the renderer 37 /// Initialize the renderer
41 virtual void Init() = 0; 38 virtual bool Init() = 0;
42 39
43 /// Shutdown the renderer 40 /// Shutdown the renderer
44 virtual void ShutDown() = 0; 41 virtual void ShutDown() = 0;
@@ -46,18 +43,25 @@ public:
46 // Getter/setter functions: 43 // Getter/setter functions:
47 // ------------------------ 44 // ------------------------
48 45
49 f32 GetCurrentframe() const { 46 f32 GetCurrentFPS() const {
50 return m_current_fps; 47 return m_current_fps;
51 } 48 }
52 49
53 int current_frame() const { 50 int GetCurrentFrame() const {
54 return m_current_frame; 51 return m_current_frame;
55 } 52 }
56 53
57 std::unique_ptr<HWRasterizer> hw_rasterizer; 54 VideoCore::RasterizerInterface* Rasterizer() const {
55 return rasterizer.get();
56 }
57
58 void RefreshRasterizerSetting();
58 59
59protected: 60protected:
60 f32 m_current_fps; ///< Current framerate, should be set by the renderer 61 std::unique_ptr<VideoCore::RasterizerInterface> rasterizer;
61 int m_current_frame; ///< Current frame, should be set by the renderer 62 f32 m_current_fps = 0.0f; ///< Current framerate, should be set by the renderer
63 int m_current_frame = 0; ///< Current frame, should be set by the renderer
62 64
65private:
66 bool opengl_rasterizer_active = false;
63}; 67};
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 822739088..b3dc6aa19 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -19,6 +19,7 @@
19#include "core/hw/gpu.h" 19#include "core/hw/gpu.h"
20 20
21#include "video_core/pica.h" 21#include "video_core/pica.h"
22#include "video_core/pica_state.h"
22#include "video_core/utils.h" 23#include "video_core/utils.h"
23#include "video_core/renderer_opengl/gl_rasterizer.h" 24#include "video_core/renderer_opengl/gl_rasterizer.h"
24#include "video_core/renderer_opengl/gl_shader_gen.h" 25#include "video_core/renderer_opengl/gl_shader_gen.h"
@@ -36,7 +37,7 @@ static bool IsPassThroughTevStage(const Pica::Regs::TevStageConfig& stage) {
36 stage.GetAlphaMultiplier() == 1); 37 stage.GetAlphaMultiplier() == 1);
37} 38}
38 39
39RasterizerOpenGL::RasterizerOpenGL() : last_fb_color_addr(0), last_fb_depth_addr(0) { } 40RasterizerOpenGL::RasterizerOpenGL() : cached_fb_color_addr(0), cached_fb_depth_addr(0) { }
40RasterizerOpenGL::~RasterizerOpenGL() { } 41RasterizerOpenGL::~RasterizerOpenGL() { }
41 42
42void RasterizerOpenGL::InitObjects() { 43void RasterizerOpenGL::InitObjects() {
@@ -75,6 +76,12 @@ void RasterizerOpenGL::InitObjects() {
75 glEnableVertexAttribArray(GLShader::ATTRIBUTE_TEXCOORD1); 76 glEnableVertexAttribArray(GLShader::ATTRIBUTE_TEXCOORD1);
76 glEnableVertexAttribArray(GLShader::ATTRIBUTE_TEXCOORD2); 77 glEnableVertexAttribArray(GLShader::ATTRIBUTE_TEXCOORD2);
77 78
79 glVertexAttribPointer(GLShader::ATTRIBUTE_NORMQUAT, 4, GL_FLOAT, GL_FALSE, sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, normquat));
80 glEnableVertexAttribArray(GLShader::ATTRIBUTE_NORMQUAT);
81
82 glVertexAttribPointer(GLShader::ATTRIBUTE_VIEW, 3, GL_FLOAT, GL_FALSE, sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, view));
83 glEnableVertexAttribArray(GLShader::ATTRIBUTE_VIEW);
84
78 SetShader(); 85 SetShader();
79 86
80 // Create textures for OGL framebuffer that will be rendered to, initially 1x1 to succeed in framebuffer creation 87 // Create textures for OGL framebuffer that will be rendered to, initially 1x1 to succeed in framebuffer creation
@@ -120,12 +127,26 @@ void RasterizerOpenGL::InitObjects() {
120 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb_color_texture.texture.handle, 0); 127 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb_color_texture.texture.handle, 0);
121 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, fb_depth_texture.texture.handle, 0); 128 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, fb_depth_texture.texture.handle, 0);
122 129
130 for (size_t i = 0; i < lighting_lut.size(); ++i) {
131 lighting_lut[i].Create();
132 state.lighting_lut[i].texture_1d = lighting_lut[i].handle;
133
134 glActiveTexture(GL_TEXTURE3 + i);
135 glBindTexture(GL_TEXTURE_1D, state.lighting_lut[i].texture_1d);
136
137 glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA32F, 256, 0, GL_RGBA, GL_FLOAT, nullptr);
138 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
139 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
140 }
141 state.Apply();
142
123 ASSERT_MSG(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, 143 ASSERT_MSG(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE,
124 "OpenGL rasterizer framebuffer setup failed, status %X", glCheckFramebufferStatus(GL_FRAMEBUFFER)); 144 "OpenGL rasterizer framebuffer setup failed, status %X", glCheckFramebufferStatus(GL_FRAMEBUFFER));
125} 145}
126 146
127void RasterizerOpenGL::Reset() { 147void RasterizerOpenGL::Reset() {
128 SyncCullMode(); 148 SyncCullMode();
149 SyncDepthModifiers();
129 SyncBlendEnabled(); 150 SyncBlendEnabled();
130 SyncBlendFuncs(); 151 SyncBlendFuncs();
131 SyncBlendColor(); 152 SyncBlendColor();
@@ -135,15 +156,37 @@ void RasterizerOpenGL::Reset() {
135 156
136 SetShader(); 157 SetShader();
137 158
138 res_cache.FullFlush(); 159 res_cache.InvalidateAll();
160}
161
162/**
163 * This is a helper function to resolve an issue with opposite quaternions being interpolated by
164 * OpenGL. See below for a detailed description of this issue (yuriks):
165 *
166 * For any rotation, there are two quaternions Q, and -Q, that represent the same rotation. If you
167 * interpolate two quaternions that are opposite, instead of going from one rotation to another
168 * using the shortest path, you'll go around the longest path. You can test if two quaternions are
169 * opposite by checking if Dot(Q1, W2) < 0. In that case, you can flip either of them, therefore
170 * making Dot(-Q1, W2) positive.
171 *
172 * NOTE: This solution corrects this issue per-vertex before passing the quaternions to OpenGL. This
173 * should be correct for nearly all cases, however a more correct implementation (but less trivial
174 * and perhaps unnecessary) would be to handle this per-fragment, by interpolating the quaternions
175 * manually using two Lerps, and doing this correction before each Lerp.
176 */
177static bool AreQuaternionsOpposite(Math::Vec4<Pica::float24> qa, Math::Vec4<Pica::float24> qb) {
178 Math::Vec4f a{ qa.x.ToFloat32(), qa.y.ToFloat32(), qa.z.ToFloat32(), qa.w.ToFloat32() };
179 Math::Vec4f b{ qb.x.ToFloat32(), qb.y.ToFloat32(), qb.z.ToFloat32(), qb.w.ToFloat32() };
180
181 return (Math::Dot(a, b) < 0.f);
139} 182}
140 183
141void RasterizerOpenGL::AddTriangle(const Pica::Shader::OutputVertex& v0, 184void RasterizerOpenGL::AddTriangle(const Pica::Shader::OutputVertex& v0,
142 const Pica::Shader::OutputVertex& v1, 185 const Pica::Shader::OutputVertex& v1,
143 const Pica::Shader::OutputVertex& v2) { 186 const Pica::Shader::OutputVertex& v2) {
144 vertex_batch.emplace_back(v0); 187 vertex_batch.emplace_back(v0, false);
145 vertex_batch.emplace_back(v1); 188 vertex_batch.emplace_back(v1, AreQuaternionsOpposite(v0.quat, v1.quat));
146 vertex_batch.emplace_back(v2); 189 vertex_batch.emplace_back(v2, AreQuaternionsOpposite(v0.quat, v2.quat));
147} 190}
148 191
149void RasterizerOpenGL::DrawTriangles() { 192void RasterizerOpenGL::DrawTriangles() {
@@ -155,6 +198,13 @@ void RasterizerOpenGL::DrawTriangles() {
155 state.draw.shader_dirty = false; 198 state.draw.shader_dirty = false;
156 } 199 }
157 200
201 for (unsigned index = 0; index < lighting_lut.size(); index++) {
202 if (uniform_block_data.lut_dirty[index]) {
203 SyncLightingLUT(index);
204 uniform_block_data.lut_dirty[index] = false;
205 }
206 }
207
158 if (uniform_block_data.dirty) { 208 if (uniform_block_data.dirty) {
159 glBufferData(GL_UNIFORM_BUFFER, sizeof(UniformData), &uniform_block_data.data, GL_STATIC_DRAW); 209 glBufferData(GL_UNIFORM_BUFFER, sizeof(UniformData), &uniform_block_data.data, GL_STATIC_DRAW);
160 uniform_block_data.dirty = false; 210 uniform_block_data.dirty = false;
@@ -168,19 +218,17 @@ void RasterizerOpenGL::DrawTriangles() {
168 // Flush the resource cache at the current depth and color framebuffer addresses for render-to-texture 218 // Flush the resource cache at the current depth and color framebuffer addresses for render-to-texture
169 const auto& regs = Pica::g_state.regs; 219 const auto& regs = Pica::g_state.regs;
170 220
171 PAddr cur_fb_color_addr = regs.framebuffer.GetColorBufferPhysicalAddress(); 221 u32 cached_fb_color_size = Pica::Regs::BytesPerColorPixel(fb_color_texture.format)
172 u32 cur_fb_color_size = Pica::Regs::BytesPerColorPixel(regs.framebuffer.color_format) 222 * fb_color_texture.width * fb_color_texture.height;
173 * regs.framebuffer.GetWidth() * regs.framebuffer.GetHeight();
174 223
175 PAddr cur_fb_depth_addr = regs.framebuffer.GetDepthBufferPhysicalAddress(); 224 u32 cached_fb_depth_size = Pica::Regs::BytesPerDepthPixel(fb_depth_texture.format)
176 u32 cur_fb_depth_size = Pica::Regs::BytesPerDepthPixel(regs.framebuffer.depth_format) 225 * fb_depth_texture.width * fb_depth_texture.height;
177 * regs.framebuffer.GetWidth() * regs.framebuffer.GetHeight();
178 226
179 res_cache.NotifyFlush(cur_fb_color_addr, cur_fb_color_size, true); 227 res_cache.InvalidateInRange(cached_fb_color_addr, cached_fb_color_size, true);
180 res_cache.NotifyFlush(cur_fb_depth_addr, cur_fb_depth_size, true); 228 res_cache.InvalidateInRange(cached_fb_depth_addr, cached_fb_depth_size, true);
181} 229}
182 230
183void RasterizerOpenGL::CommitFramebuffer() { 231void RasterizerOpenGL::FlushFramebuffer() {
184 CommitColorBuffer(); 232 CommitColorBuffer();
185 CommitDepthBuffer(); 233 CommitDepthBuffer();
186} 234}
@@ -188,15 +236,18 @@ void RasterizerOpenGL::CommitFramebuffer() {
188void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) { 236void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) {
189 const auto& regs = Pica::g_state.regs; 237 const auto& regs = Pica::g_state.regs;
190 238
191 if (!Settings::values.use_hw_renderer)
192 return;
193
194 switch(id) { 239 switch(id) {
195 // Culling 240 // Culling
196 case PICA_REG_INDEX(cull_mode): 241 case PICA_REG_INDEX(cull_mode):
197 SyncCullMode(); 242 SyncCullMode();
198 break; 243 break;
199 244
245 // Depth modifiers
246 case PICA_REG_INDEX(viewport_depth_range):
247 case PICA_REG_INDEX(viewport_depth_far_plane):
248 SyncDepthModifiers();
249 break;
250
200 // Blending 251 // Blending
201 case PICA_REG_INDEX(output_merger.alphablend_enable): 252 case PICA_REG_INDEX(output_merger.alphablend_enable):
202 SyncBlendEnabled(); 253 SyncBlendEnabled();
@@ -281,54 +332,203 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) {
281 case PICA_REG_INDEX(tev_combiner_buffer_color): 332 case PICA_REG_INDEX(tev_combiner_buffer_color):
282 SyncCombinerColor(); 333 SyncCombinerColor();
283 break; 334 break;
335
336 // Fragment lighting specular 0 color
337 case PICA_REG_INDEX_WORKAROUND(lighting.light[0].specular_0, 0x140 + 0 * 0x10):
338 SyncLightSpecular0(0);
339 break;
340 case PICA_REG_INDEX_WORKAROUND(lighting.light[1].specular_0, 0x140 + 1 * 0x10):
341 SyncLightSpecular0(1);
342 break;
343 case PICA_REG_INDEX_WORKAROUND(lighting.light[2].specular_0, 0x140 + 2 * 0x10):
344 SyncLightSpecular0(2);
345 break;
346 case PICA_REG_INDEX_WORKAROUND(lighting.light[3].specular_0, 0x140 + 3 * 0x10):
347 SyncLightSpecular0(3);
348 break;
349 case PICA_REG_INDEX_WORKAROUND(lighting.light[4].specular_0, 0x140 + 4 * 0x10):
350 SyncLightSpecular0(4);
351 break;
352 case PICA_REG_INDEX_WORKAROUND(lighting.light[5].specular_0, 0x140 + 5 * 0x10):
353 SyncLightSpecular0(5);
354 break;
355 case PICA_REG_INDEX_WORKAROUND(lighting.light[6].specular_0, 0x140 + 6 * 0x10):
356 SyncLightSpecular0(6);
357 break;
358 case PICA_REG_INDEX_WORKAROUND(lighting.light[7].specular_0, 0x140 + 7 * 0x10):
359 SyncLightSpecular0(7);
360 break;
361
362 // Fragment lighting specular 1 color
363 case PICA_REG_INDEX_WORKAROUND(lighting.light[0].specular_1, 0x141 + 0 * 0x10):
364 SyncLightSpecular1(0);
365 break;
366 case PICA_REG_INDEX_WORKAROUND(lighting.light[1].specular_1, 0x141 + 1 * 0x10):
367 SyncLightSpecular1(1);
368 break;
369 case PICA_REG_INDEX_WORKAROUND(lighting.light[2].specular_1, 0x141 + 2 * 0x10):
370 SyncLightSpecular1(2);
371 break;
372 case PICA_REG_INDEX_WORKAROUND(lighting.light[3].specular_1, 0x141 + 3 * 0x10):
373 SyncLightSpecular1(3);
374 break;
375 case PICA_REG_INDEX_WORKAROUND(lighting.light[4].specular_1, 0x141 + 4 * 0x10):
376 SyncLightSpecular1(4);
377 break;
378 case PICA_REG_INDEX_WORKAROUND(lighting.light[5].specular_1, 0x141 + 5 * 0x10):
379 SyncLightSpecular1(5);
380 break;
381 case PICA_REG_INDEX_WORKAROUND(lighting.light[6].specular_1, 0x141 + 6 * 0x10):
382 SyncLightSpecular1(6);
383 break;
384 case PICA_REG_INDEX_WORKAROUND(lighting.light[7].specular_1, 0x141 + 7 * 0x10):
385 SyncLightSpecular1(7);
386 break;
387
388 // Fragment lighting diffuse color
389 case PICA_REG_INDEX_WORKAROUND(lighting.light[0].diffuse, 0x142 + 0 * 0x10):
390 SyncLightDiffuse(0);
391 break;
392 case PICA_REG_INDEX_WORKAROUND(lighting.light[1].diffuse, 0x142 + 1 * 0x10):
393 SyncLightDiffuse(1);
394 break;
395 case PICA_REG_INDEX_WORKAROUND(lighting.light[2].diffuse, 0x142 + 2 * 0x10):
396 SyncLightDiffuse(2);
397 break;
398 case PICA_REG_INDEX_WORKAROUND(lighting.light[3].diffuse, 0x142 + 3 * 0x10):
399 SyncLightDiffuse(3);
400 break;
401 case PICA_REG_INDEX_WORKAROUND(lighting.light[4].diffuse, 0x142 + 4 * 0x10):
402 SyncLightDiffuse(4);
403 break;
404 case PICA_REG_INDEX_WORKAROUND(lighting.light[5].diffuse, 0x142 + 5 * 0x10):
405 SyncLightDiffuse(5);
406 break;
407 case PICA_REG_INDEX_WORKAROUND(lighting.light[6].diffuse, 0x142 + 6 * 0x10):
408 SyncLightDiffuse(6);
409 break;
410 case PICA_REG_INDEX_WORKAROUND(lighting.light[7].diffuse, 0x142 + 7 * 0x10):
411 SyncLightDiffuse(7);
412 break;
413
414 // Fragment lighting ambient color
415 case PICA_REG_INDEX_WORKAROUND(lighting.light[0].ambient, 0x143 + 0 * 0x10):
416 SyncLightAmbient(0);
417 break;
418 case PICA_REG_INDEX_WORKAROUND(lighting.light[1].ambient, 0x143 + 1 * 0x10):
419 SyncLightAmbient(1);
420 break;
421 case PICA_REG_INDEX_WORKAROUND(lighting.light[2].ambient, 0x143 + 2 * 0x10):
422 SyncLightAmbient(2);
423 break;
424 case PICA_REG_INDEX_WORKAROUND(lighting.light[3].ambient, 0x143 + 3 * 0x10):
425 SyncLightAmbient(3);
426 break;
427 case PICA_REG_INDEX_WORKAROUND(lighting.light[4].ambient, 0x143 + 4 * 0x10):
428 SyncLightAmbient(4);
429 break;
430 case PICA_REG_INDEX_WORKAROUND(lighting.light[5].ambient, 0x143 + 5 * 0x10):
431 SyncLightAmbient(5);
432 break;
433 case PICA_REG_INDEX_WORKAROUND(lighting.light[6].ambient, 0x143 + 6 * 0x10):
434 SyncLightAmbient(6);
435 break;
436 case PICA_REG_INDEX_WORKAROUND(lighting.light[7].ambient, 0x143 + 7 * 0x10):
437 SyncLightAmbient(7);
438 break;
439
440 // Fragment lighting position
441 case PICA_REG_INDEX_WORKAROUND(lighting.light[0].x, 0x144 + 0 * 0x10):
442 case PICA_REG_INDEX_WORKAROUND(lighting.light[0].z, 0x145 + 0 * 0x10):
443 SyncLightPosition(0);
444 break;
445 case PICA_REG_INDEX_WORKAROUND(lighting.light[1].x, 0x144 + 1 * 0x10):
446 case PICA_REG_INDEX_WORKAROUND(lighting.light[1].z, 0x145 + 1 * 0x10):
447 SyncLightPosition(1);
448 break;
449 case PICA_REG_INDEX_WORKAROUND(lighting.light[2].x, 0x144 + 2 * 0x10):
450 case PICA_REG_INDEX_WORKAROUND(lighting.light[2].z, 0x145 + 2 * 0x10):
451 SyncLightPosition(2);
452 break;
453 case PICA_REG_INDEX_WORKAROUND(lighting.light[3].x, 0x144 + 3 * 0x10):
454 case PICA_REG_INDEX_WORKAROUND(lighting.light[3].z, 0x145 + 3 * 0x10):
455 SyncLightPosition(3);
456 break;
457 case PICA_REG_INDEX_WORKAROUND(lighting.light[4].x, 0x144 + 4 * 0x10):
458 case PICA_REG_INDEX_WORKAROUND(lighting.light[4].z, 0x145 + 4 * 0x10):
459 SyncLightPosition(4);
460 break;
461 case PICA_REG_INDEX_WORKAROUND(lighting.light[5].x, 0x144 + 5 * 0x10):
462 case PICA_REG_INDEX_WORKAROUND(lighting.light[5].z, 0x145 + 5 * 0x10):
463 SyncLightPosition(5);
464 break;
465 case PICA_REG_INDEX_WORKAROUND(lighting.light[6].x, 0x144 + 6 * 0x10):
466 case PICA_REG_INDEX_WORKAROUND(lighting.light[6].z, 0x145 + 6 * 0x10):
467 SyncLightPosition(6);
468 break;
469 case PICA_REG_INDEX_WORKAROUND(lighting.light[7].x, 0x144 + 7 * 0x10):
470 case PICA_REG_INDEX_WORKAROUND(lighting.light[7].z, 0x145 + 7 * 0x10):
471 SyncLightPosition(7);
472 break;
473
474 // Fragment lighting global ambient color (emission + ambient * ambient)
475 case PICA_REG_INDEX_WORKAROUND(lighting.global_ambient, 0x1c0):
476 SyncGlobalAmbient();
477 break;
478
479 // Fragment lighting lookup tables
480 case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[0], 0x1c8):
481 case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[1], 0x1c9):
482 case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[2], 0x1ca):
483 case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[3], 0x1cb):
484 case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[4], 0x1cc):
485 case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[5], 0x1cd):
486 case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[6], 0x1ce):
487 case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[7], 0x1cf):
488 {
489 auto& lut_config = regs.lighting.lut_config;
490 uniform_block_data.lut_dirty[lut_config.type / 4] = true;
491 break;
492 }
493
284 } 494 }
285} 495}
286 496
287void RasterizerOpenGL::NotifyPreRead(PAddr addr, u32 size) { 497void RasterizerOpenGL::FlushRegion(PAddr addr, u32 size) {
288 const auto& regs = Pica::g_state.regs; 498 const auto& regs = Pica::g_state.regs;
289 499
290 if (!Settings::values.use_hw_renderer) 500 u32 cached_fb_color_size = Pica::Regs::BytesPerColorPixel(fb_color_texture.format)
291 return; 501 * fb_color_texture.width * fb_color_texture.height;
292 502
293 PAddr cur_fb_color_addr = regs.framebuffer.GetColorBufferPhysicalAddress(); 503 u32 cached_fb_depth_size = Pica::Regs::BytesPerDepthPixel(fb_depth_texture.format)
294 u32 cur_fb_color_size = Pica::Regs::BytesPerColorPixel(regs.framebuffer.color_format) 504 * fb_depth_texture.width * fb_depth_texture.height;
295 * regs.framebuffer.GetWidth() * regs.framebuffer.GetHeight();
296
297 PAddr cur_fb_depth_addr = regs.framebuffer.GetDepthBufferPhysicalAddress();
298 u32 cur_fb_depth_size = Pica::Regs::BytesPerDepthPixel(regs.framebuffer.depth_format)
299 * regs.framebuffer.GetWidth() * regs.framebuffer.GetHeight();
300 505
301 // If source memory region overlaps 3DS framebuffers, commit them before the copy happens 506 // If source memory region overlaps 3DS framebuffers, commit them before the copy happens
302 if (MathUtil::IntervalsIntersect(addr, size, cur_fb_color_addr, cur_fb_color_size)) 507 if (MathUtil::IntervalsIntersect(addr, size, cached_fb_color_addr, cached_fb_color_size))
303 CommitColorBuffer(); 508 CommitColorBuffer();
304 509
305 if (MathUtil::IntervalsIntersect(addr, size, cur_fb_depth_addr, cur_fb_depth_size)) 510 if (MathUtil::IntervalsIntersect(addr, size, cached_fb_depth_addr, cached_fb_depth_size))
306 CommitDepthBuffer(); 511 CommitDepthBuffer();
307} 512}
308 513
309void RasterizerOpenGL::NotifyFlush(PAddr addr, u32 size) { 514void RasterizerOpenGL::InvalidateRegion(PAddr addr, u32 size) {
310 const auto& regs = Pica::g_state.regs; 515 const auto& regs = Pica::g_state.regs;
311 516
312 if (!Settings::values.use_hw_renderer) 517 u32 cached_fb_color_size = Pica::Regs::BytesPerColorPixel(fb_color_texture.format)
313 return; 518 * fb_color_texture.width * fb_color_texture.height;
314
315 PAddr cur_fb_color_addr = regs.framebuffer.GetColorBufferPhysicalAddress();
316 u32 cur_fb_color_size = Pica::Regs::BytesPerColorPixel(regs.framebuffer.color_format)
317 * regs.framebuffer.GetWidth() * regs.framebuffer.GetHeight();
318 519
319 PAddr cur_fb_depth_addr = regs.framebuffer.GetDepthBufferPhysicalAddress(); 520 u32 cached_fb_depth_size = Pica::Regs::BytesPerDepthPixel(fb_depth_texture.format)
320 u32 cur_fb_depth_size = Pica::Regs::BytesPerDepthPixel(regs.framebuffer.depth_format) 521 * fb_depth_texture.width * fb_depth_texture.height;
321 * regs.framebuffer.GetWidth() * regs.framebuffer.GetHeight();
322 522
323 // If modified memory region overlaps 3DS framebuffers, reload their contents into OpenGL 523 // If modified memory region overlaps 3DS framebuffers, reload their contents into OpenGL
324 if (MathUtil::IntervalsIntersect(addr, size, cur_fb_color_addr, cur_fb_color_size)) 524 if (MathUtil::IntervalsIntersect(addr, size, cached_fb_color_addr, cached_fb_color_size))
325 ReloadColorBuffer(); 525 ReloadColorBuffer();
326 526
327 if (MathUtil::IntervalsIntersect(addr, size, cur_fb_depth_addr, cur_fb_depth_size)) 527 if (MathUtil::IntervalsIntersect(addr, size, cached_fb_depth_addr, cached_fb_depth_size))
328 ReloadDepthBuffer(); 528 ReloadDepthBuffer();
329 529
330 // Notify cache of flush in case the region touches a cached resource 530 // Notify cache of flush in case the region touches a cached resource
331 res_cache.NotifyFlush(addr, size); 531 res_cache.InvalidateInRange(addr, size);
332} 532}
333 533
334void RasterizerOpenGL::SamplerInfo::Create() { 534void RasterizerOpenGL::SamplerInfo::Create() {
@@ -499,27 +699,48 @@ void RasterizerOpenGL::SetShader() {
499 uniform_tex = glGetUniformLocation(shader->shader.handle, "tex[2]"); 699 uniform_tex = glGetUniformLocation(shader->shader.handle, "tex[2]");
500 if (uniform_tex != -1) { glUniform1i(uniform_tex, 2); } 700 if (uniform_tex != -1) { glUniform1i(uniform_tex, 2); }
501 701
702 // Set the texture samplers to correspond to different lookup table texture units
703 GLuint uniform_lut = glGetUniformLocation(shader->shader.handle, "lut[0]");
704 if (uniform_lut != -1) { glUniform1i(uniform_lut, 3); }
705 uniform_lut = glGetUniformLocation(shader->shader.handle, "lut[1]");
706 if (uniform_lut != -1) { glUniform1i(uniform_lut, 4); }
707 uniform_lut = glGetUniformLocation(shader->shader.handle, "lut[2]");
708 if (uniform_lut != -1) { glUniform1i(uniform_lut, 5); }
709 uniform_lut = glGetUniformLocation(shader->shader.handle, "lut[3]");
710 if (uniform_lut != -1) { glUniform1i(uniform_lut, 6); }
711 uniform_lut = glGetUniformLocation(shader->shader.handle, "lut[4]");
712 if (uniform_lut != -1) { glUniform1i(uniform_lut, 7); }
713 uniform_lut = glGetUniformLocation(shader->shader.handle, "lut[5]");
714 if (uniform_lut != -1) { glUniform1i(uniform_lut, 8); }
715
502 current_shader = shader_cache.emplace(config, std::move(shader)).first->second.get(); 716 current_shader = shader_cache.emplace(config, std::move(shader)).first->second.get();
503 717
504 unsigned int block_index = glGetUniformBlockIndex(current_shader->shader.handle, "shader_data"); 718 unsigned int block_index = glGetUniformBlockIndex(current_shader->shader.handle, "shader_data");
505 glUniformBlockBinding(current_shader->shader.handle, block_index, 0); 719 glUniformBlockBinding(current_shader->shader.handle, block_index, 0);
506 }
507 720
508 // Update uniforms 721 // Update uniforms
509 SyncAlphaTest(); 722 SyncAlphaTest();
510 SyncCombinerColor(); 723 SyncCombinerColor();
511 auto& tev_stages = Pica::g_state.regs.GetTevStages(); 724 auto& tev_stages = Pica::g_state.regs.GetTevStages();
512 for (int index = 0; index < tev_stages.size(); ++index) 725 for (int index = 0; index < tev_stages.size(); ++index)
513 SyncTevConstColor(index, tev_stages[index]); 726 SyncTevConstColor(index, tev_stages[index]);
727
728 SyncGlobalAmbient();
729 for (int light_index = 0; light_index < 8; light_index++) {
730 SyncLightDiffuse(light_index);
731 SyncLightAmbient(light_index);
732 SyncLightPosition(light_index);
733 }
734 }
514} 735}
515 736
516void RasterizerOpenGL::SyncFramebuffer() { 737void RasterizerOpenGL::SyncFramebuffer() {
517 const auto& regs = Pica::g_state.regs; 738 const auto& regs = Pica::g_state.regs;
518 739
519 PAddr cur_fb_color_addr = regs.framebuffer.GetColorBufferPhysicalAddress(); 740 PAddr new_fb_color_addr = regs.framebuffer.GetColorBufferPhysicalAddress();
520 Pica::Regs::ColorFormat new_fb_color_format = regs.framebuffer.color_format; 741 Pica::Regs::ColorFormat new_fb_color_format = regs.framebuffer.color_format;
521 742
522 PAddr cur_fb_depth_addr = regs.framebuffer.GetDepthBufferPhysicalAddress(); 743 PAddr new_fb_depth_addr = regs.framebuffer.GetDepthBufferPhysicalAddress();
523 Pica::Regs::DepthFormat new_fb_depth_format = regs.framebuffer.depth_format; 744 Pica::Regs::DepthFormat new_fb_depth_format = regs.framebuffer.depth_format;
524 745
525 bool fb_size_changed = fb_color_texture.width != static_cast<GLsizei>(regs.framebuffer.GetWidth()) || 746 bool fb_size_changed = fb_color_texture.width != static_cast<GLsizei>(regs.framebuffer.GetWidth()) ||
@@ -531,10 +752,10 @@ void RasterizerOpenGL::SyncFramebuffer() {
531 bool depth_fb_prop_changed = fb_depth_texture.format != new_fb_depth_format || 752 bool depth_fb_prop_changed = fb_depth_texture.format != new_fb_depth_format ||
532 fb_size_changed; 753 fb_size_changed;
533 754
534 bool color_fb_modified = last_fb_color_addr != cur_fb_color_addr || 755 bool color_fb_modified = cached_fb_color_addr != new_fb_color_addr ||
535 color_fb_prop_changed; 756 color_fb_prop_changed;
536 757
537 bool depth_fb_modified = last_fb_depth_addr != cur_fb_depth_addr || 758 bool depth_fb_modified = cached_fb_depth_addr != new_fb_depth_addr ||
538 depth_fb_prop_changed; 759 depth_fb_prop_changed;
539 760
540 // Commit if framebuffer modified in any way 761 // Commit if framebuffer modified in any way
@@ -574,13 +795,13 @@ void RasterizerOpenGL::SyncFramebuffer() {
574 795
575 // Load buffer data again if fb modified in any way 796 // Load buffer data again if fb modified in any way
576 if (color_fb_modified) { 797 if (color_fb_modified) {
577 last_fb_color_addr = cur_fb_color_addr; 798 cached_fb_color_addr = new_fb_color_addr;
578 799
579 ReloadColorBuffer(); 800 ReloadColorBuffer();
580 } 801 }
581 802
582 if (depth_fb_modified) { 803 if (depth_fb_modified) {
583 last_fb_depth_addr = cur_fb_depth_addr; 804 cached_fb_depth_addr = new_fb_depth_addr;
584 805
585 ReloadDepthBuffer(); 806 ReloadDepthBuffer();
586 } 807 }
@@ -596,12 +817,12 @@ void RasterizerOpenGL::SyncCullMode() {
596 817
597 case Pica::Regs::CullMode::KeepClockWise: 818 case Pica::Regs::CullMode::KeepClockWise:
598 state.cull.enabled = true; 819 state.cull.enabled = true;
599 state.cull.mode = GL_BACK; 820 state.cull.front_face = GL_CW;
600 break; 821 break;
601 822
602 case Pica::Regs::CullMode::KeepCounterClockWise: 823 case Pica::Regs::CullMode::KeepCounterClockWise:
603 state.cull.enabled = true; 824 state.cull.enabled = true;
604 state.cull.mode = GL_FRONT; 825 state.cull.front_face = GL_CCW;
605 break; 826 break;
606 827
607 default: 828 default:
@@ -611,6 +832,15 @@ void RasterizerOpenGL::SyncCullMode() {
611 } 832 }
612} 833}
613 834
835void RasterizerOpenGL::SyncDepthModifiers() {
836 float depth_scale = -Pica::float24::FromRaw(Pica::g_state.regs.viewport_depth_range).ToFloat32();
837 float depth_offset = Pica::float24::FromRaw(Pica::g_state.regs.viewport_depth_far_plane).ToFloat32() / 2.0f;
838
839 // TODO: Implement scale modifier
840 uniform_block_data.data.depth_offset = depth_offset;
841 uniform_block_data.dirty = true;
842}
843
614void RasterizerOpenGL::SyncBlendEnabled() { 844void RasterizerOpenGL::SyncBlendEnabled() {
615 state.blend.enabled = (Pica::g_state.regs.output_merger.alphablend_enable == 1); 845 state.blend.enabled = (Pica::g_state.regs.output_merger.alphablend_enable == 1);
616} 846}
@@ -657,8 +887,10 @@ void RasterizerOpenGL::SyncStencilTest() {
657 887
658void RasterizerOpenGL::SyncDepthTest() { 888void RasterizerOpenGL::SyncDepthTest() {
659 const auto& regs = Pica::g_state.regs; 889 const auto& regs = Pica::g_state.regs;
660 state.depth.test_enabled = (regs.output_merger.depth_test_enable == 1); 890 state.depth.test_enabled = regs.output_merger.depth_test_enable == 1 ||
661 state.depth.test_func = PicaToGL::CompareFunc(regs.output_merger.depth_test_func); 891 regs.output_merger.depth_write_enable == 1;
892 state.depth.test_func = regs.output_merger.depth_test_enable == 1 ?
893 PicaToGL::CompareFunc(regs.output_merger.depth_test_func) : GL_ALWAYS;
662 state.color_mask.red_enabled = regs.output_merger.red_enable; 894 state.color_mask.red_enabled = regs.output_merger.red_enable;
663 state.color_mask.green_enabled = regs.output_merger.green_enable; 895 state.color_mask.green_enabled = regs.output_merger.green_enable;
664 state.color_mask.blue_enabled = regs.output_merger.blue_enable; 896 state.color_mask.blue_enabled = regs.output_merger.blue_enable;
@@ -682,19 +914,87 @@ void RasterizerOpenGL::SyncTevConstColor(int stage_index, const Pica::Regs::TevS
682 } 914 }
683} 915}
684 916
917void RasterizerOpenGL::SyncGlobalAmbient() {
918 auto color = PicaToGL::LightColor(Pica::g_state.regs.lighting.global_ambient);
919 if (color != uniform_block_data.data.lighting_global_ambient) {
920 uniform_block_data.data.lighting_global_ambient = color;
921 uniform_block_data.dirty = true;
922 }
923}
924
925void RasterizerOpenGL::SyncLightingLUT(unsigned lut_index) {
926 std::array<GLvec4, 256> new_data;
927
928 for (unsigned offset = 0; offset < new_data.size(); ++offset) {
929 new_data[offset][0] = Pica::g_state.lighting.luts[(lut_index * 4) + 0][offset].ToFloat();
930 new_data[offset][1] = Pica::g_state.lighting.luts[(lut_index * 4) + 1][offset].ToFloat();
931 new_data[offset][2] = Pica::g_state.lighting.luts[(lut_index * 4) + 2][offset].ToFloat();
932 new_data[offset][3] = Pica::g_state.lighting.luts[(lut_index * 4) + 3][offset].ToFloat();
933 }
934
935 if (new_data != lighting_lut_data[lut_index]) {
936 lighting_lut_data[lut_index] = new_data;
937 glActiveTexture(GL_TEXTURE3 + lut_index);
938 glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 256, GL_RGBA, GL_FLOAT, lighting_lut_data[lut_index].data());
939 }
940}
941
942void RasterizerOpenGL::SyncLightSpecular0(int light_index) {
943 auto color = PicaToGL::LightColor(Pica::g_state.regs.lighting.light[light_index].specular_0);
944 if (color != uniform_block_data.data.light_src[light_index].specular_0) {
945 uniform_block_data.data.light_src[light_index].specular_0 = color;
946 uniform_block_data.dirty = true;
947 }
948}
949
950void RasterizerOpenGL::SyncLightSpecular1(int light_index) {
951 auto color = PicaToGL::LightColor(Pica::g_state.regs.lighting.light[light_index].specular_1);
952 if (color != uniform_block_data.data.light_src[light_index].specular_1) {
953 uniform_block_data.data.light_src[light_index].specular_1 = color;
954 uniform_block_data.dirty = true;
955 }
956}
957
958void RasterizerOpenGL::SyncLightDiffuse(int light_index) {
959 auto color = PicaToGL::LightColor(Pica::g_state.regs.lighting.light[light_index].diffuse);
960 if (color != uniform_block_data.data.light_src[light_index].diffuse) {
961 uniform_block_data.data.light_src[light_index].diffuse = color;
962 uniform_block_data.dirty = true;
963 }
964}
965
966void RasterizerOpenGL::SyncLightAmbient(int light_index) {
967 auto color = PicaToGL::LightColor(Pica::g_state.regs.lighting.light[light_index].ambient);
968 if (color != uniform_block_data.data.light_src[light_index].ambient) {
969 uniform_block_data.data.light_src[light_index].ambient = color;
970 uniform_block_data.dirty = true;
971 }
972}
973
974void RasterizerOpenGL::SyncLightPosition(int light_index) {
975 GLvec3 position = {
976 Pica::float16::FromRaw(Pica::g_state.regs.lighting.light[light_index].x).ToFloat32(),
977 Pica::float16::FromRaw(Pica::g_state.regs.lighting.light[light_index].y).ToFloat32(),
978 Pica::float16::FromRaw(Pica::g_state.regs.lighting.light[light_index].z).ToFloat32() };
979
980 if (position != uniform_block_data.data.light_src[light_index].position) {
981 uniform_block_data.data.light_src[light_index].position = position;
982 uniform_block_data.dirty = true;
983 }
984}
985
685void RasterizerOpenGL::SyncDrawState() { 986void RasterizerOpenGL::SyncDrawState() {
686 const auto& regs = Pica::g_state.regs; 987 const auto& regs = Pica::g_state.regs;
687 988
688 // Sync the viewport 989 // Sync the viewport
689 GLsizei viewport_width = (GLsizei)Pica::float24::FromRawFloat24(regs.viewport_size_x).ToFloat32() * 2; 990 GLsizei viewport_width = (GLsizei)Pica::float24::FromRaw(regs.viewport_size_x).ToFloat32() * 2;
690 GLsizei viewport_height = (GLsizei)Pica::float24::FromRawFloat24(regs.viewport_size_y).ToFloat32() * 2; 991 GLsizei viewport_height = (GLsizei)Pica::float24::FromRaw(regs.viewport_size_y).ToFloat32() * 2;
691 992
692 // OpenGL uses different y coordinates, so negate corner offset and flip origin 993 // OpenGL uses different y coordinates, so negate corner offset and flip origin
693 // TODO: Ensure viewport_corner.x should not be negated or origin flipped 994 // TODO: Ensure viewport_corner.x should not be negated or origin flipped
694 // TODO: Use floating-point viewports for accuracy if supported 995 // TODO: Use floating-point viewports for accuracy if supported
695 glViewport((GLsizei)static_cast<float>(regs.viewport_corner.x), 996 glViewport((GLsizei)regs.viewport_corner.x,
696 -(GLsizei)static_cast<float>(regs.viewport_corner.y) 997 (GLsizei)regs.viewport_corner.y,
697 + regs.framebuffer.GetHeight() - viewport_height,
698 viewport_width, viewport_height); 998 viewport_width, viewport_height);
699 999
700 // Sync bound texture(s), upload if not cached 1000 // Sync bound texture(s), upload if not cached
@@ -717,7 +1017,7 @@ void RasterizerOpenGL::SyncDrawState() {
717MICROPROFILE_DEFINE(OpenGL_FramebufferReload, "OpenGL", "FB Reload", MP_RGB(70, 70, 200)); 1017MICROPROFILE_DEFINE(OpenGL_FramebufferReload, "OpenGL", "FB Reload", MP_RGB(70, 70, 200));
718 1018
719void RasterizerOpenGL::ReloadColorBuffer() { 1019void RasterizerOpenGL::ReloadColorBuffer() {
720 u8* color_buffer = Memory::GetPhysicalPointer(Pica::g_state.regs.framebuffer.GetColorBufferPhysicalAddress()); 1020 u8* color_buffer = Memory::GetPhysicalPointer(cached_fb_color_addr);
721 1021
722 if (color_buffer == nullptr) 1022 if (color_buffer == nullptr)
723 return; 1023 return;
@@ -733,7 +1033,7 @@ void RasterizerOpenGL::ReloadColorBuffer() {
733 for (int x = 0; x < fb_color_texture.width; ++x) { 1033 for (int x = 0; x < fb_color_texture.width; ++x) {
734 const u32 coarse_y = y & ~7; 1034 const u32 coarse_y = y & ~7;
735 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_color_texture.width * bytes_per_pixel; 1035 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_color_texture.width * bytes_per_pixel;
736 u32 gl_pixel_index = (x + y * fb_color_texture.width) * bytes_per_pixel; 1036 u32 gl_pixel_index = (x + (fb_color_texture.height - 1 - y) * fb_color_texture.width) * bytes_per_pixel;
737 1037
738 u8* pixel = color_buffer + dst_offset; 1038 u8* pixel = color_buffer + dst_offset;
739 memcpy(&temp_fb_color_buffer[gl_pixel_index], pixel, bytes_per_pixel); 1039 memcpy(&temp_fb_color_buffer[gl_pixel_index], pixel, bytes_per_pixel);
@@ -752,13 +1052,11 @@ void RasterizerOpenGL::ReloadColorBuffer() {
752} 1052}
753 1053
754void RasterizerOpenGL::ReloadDepthBuffer() { 1054void RasterizerOpenGL::ReloadDepthBuffer() {
755 PAddr depth_buffer_addr = Pica::g_state.regs.framebuffer.GetDepthBufferPhysicalAddress(); 1055 if (cached_fb_depth_addr == 0)
756
757 if (depth_buffer_addr == 0)
758 return; 1056 return;
759 1057
760 // TODO: Appears to work, but double-check endianness of depth values and order of depth-stencil 1058 // TODO: Appears to work, but double-check endianness of depth values and order of depth-stencil
761 u8* depth_buffer = Memory::GetPhysicalPointer(depth_buffer_addr); 1059 u8* depth_buffer = Memory::GetPhysicalPointer(cached_fb_depth_addr);
762 1060
763 if (depth_buffer == nullptr) 1061 if (depth_buffer == nullptr)
764 return; 1062 return;
@@ -779,7 +1077,7 @@ void RasterizerOpenGL::ReloadDepthBuffer() {
779 for (int x = 0; x < fb_depth_texture.width; ++x) { 1077 for (int x = 0; x < fb_depth_texture.width; ++x) {
780 const u32 coarse_y = y & ~7; 1078 const u32 coarse_y = y & ~7;
781 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_depth_texture.width * bytes_per_pixel; 1079 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_depth_texture.width * bytes_per_pixel;
782 u32 gl_pixel_index = (x + y * fb_depth_texture.width); 1080 u32 gl_pixel_index = (x + (fb_depth_texture.height - 1 - y) * fb_depth_texture.width);
783 1081
784 u8* pixel = depth_buffer + dst_offset; 1082 u8* pixel = depth_buffer + dst_offset;
785 u32 depth_stencil = *(u32*)pixel; 1083 u32 depth_stencil = *(u32*)pixel;
@@ -791,7 +1089,7 @@ void RasterizerOpenGL::ReloadDepthBuffer() {
791 for (int x = 0; x < fb_depth_texture.width; ++x) { 1089 for (int x = 0; x < fb_depth_texture.width; ++x) {
792 const u32 coarse_y = y & ~7; 1090 const u32 coarse_y = y & ~7;
793 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_depth_texture.width * bytes_per_pixel; 1091 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_depth_texture.width * bytes_per_pixel;
794 u32 gl_pixel_index = (x + y * fb_depth_texture.width) * gl_bpp; 1092 u32 gl_pixel_index = (x + (fb_depth_texture.height - 1 - y) * fb_depth_texture.width) * gl_bpp;
795 1093
796 u8* pixel = depth_buffer + dst_offset; 1094 u8* pixel = depth_buffer + dst_offset;
797 memcpy(&temp_fb_depth_data[gl_pixel_index], pixel, bytes_per_pixel); 1095 memcpy(&temp_fb_depth_data[gl_pixel_index], pixel, bytes_per_pixel);
@@ -821,8 +1119,8 @@ Common::Profiling::TimingCategory buffer_commit_category("Framebuffer Commit");
821MICROPROFILE_DEFINE(OpenGL_FramebufferCommit, "OpenGL", "FB Commit", MP_RGB(70, 70, 200)); 1119MICROPROFILE_DEFINE(OpenGL_FramebufferCommit, "OpenGL", "FB Commit", MP_RGB(70, 70, 200));
822 1120
823void RasterizerOpenGL::CommitColorBuffer() { 1121void RasterizerOpenGL::CommitColorBuffer() {
824 if (last_fb_color_addr != 0) { 1122 if (cached_fb_color_addr != 0) {
825 u8* color_buffer = Memory::GetPhysicalPointer(last_fb_color_addr); 1123 u8* color_buffer = Memory::GetPhysicalPointer(cached_fb_color_addr);
826 1124
827 if (color_buffer != nullptr) { 1125 if (color_buffer != nullptr) {
828 Common::Profiling::ScopeTimer timer(buffer_commit_category); 1126 Common::Profiling::ScopeTimer timer(buffer_commit_category);
@@ -846,7 +1144,7 @@ void RasterizerOpenGL::CommitColorBuffer() {
846 for (int x = 0; x < fb_color_texture.width; ++x) { 1144 for (int x = 0; x < fb_color_texture.width; ++x) {
847 const u32 coarse_y = y & ~7; 1145 const u32 coarse_y = y & ~7;
848 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_color_texture.width * bytes_per_pixel; 1146 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_color_texture.width * bytes_per_pixel;
849 u32 gl_pixel_index = x * bytes_per_pixel + y * fb_color_texture.width * bytes_per_pixel; 1147 u32 gl_pixel_index = x * bytes_per_pixel + (fb_color_texture.height - 1 - y) * fb_color_texture.width * bytes_per_pixel;
850 1148
851 u8* pixel = color_buffer + dst_offset; 1149 u8* pixel = color_buffer + dst_offset;
852 memcpy(pixel, &temp_gl_color_buffer[gl_pixel_index], bytes_per_pixel); 1150 memcpy(pixel, &temp_gl_color_buffer[gl_pixel_index], bytes_per_pixel);
@@ -857,9 +1155,9 @@ void RasterizerOpenGL::CommitColorBuffer() {
857} 1155}
858 1156
859void RasterizerOpenGL::CommitDepthBuffer() { 1157void RasterizerOpenGL::CommitDepthBuffer() {
860 if (last_fb_depth_addr != 0) { 1158 if (cached_fb_depth_addr != 0) {
861 // TODO: Output seems correct visually, but doesn't quite match sw renderer output. One of them is wrong. 1159 // TODO: Output seems correct visually, but doesn't quite match sw renderer output. One of them is wrong.
862 u8* depth_buffer = Memory::GetPhysicalPointer(last_fb_depth_addr); 1160 u8* depth_buffer = Memory::GetPhysicalPointer(cached_fb_depth_addr);
863 1161
864 if (depth_buffer != nullptr) { 1162 if (depth_buffer != nullptr) {
865 Common::Profiling::ScopeTimer timer(buffer_commit_category); 1163 Common::Profiling::ScopeTimer timer(buffer_commit_category);
@@ -888,7 +1186,7 @@ void RasterizerOpenGL::CommitDepthBuffer() {
888 for (int x = 0; x < fb_depth_texture.width; ++x) { 1186 for (int x = 0; x < fb_depth_texture.width; ++x) {
889 const u32 coarse_y = y & ~7; 1187 const u32 coarse_y = y & ~7;
890 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_depth_texture.width * bytes_per_pixel; 1188 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_depth_texture.width * bytes_per_pixel;
891 u32 gl_pixel_index = (x + y * fb_depth_texture.width); 1189 u32 gl_pixel_index = (x + (fb_depth_texture.height - 1 - y) * fb_depth_texture.width);
892 1190
893 u8* pixel = depth_buffer + dst_offset; 1191 u8* pixel = depth_buffer + dst_offset;
894 u32 depth_stencil = ((u32*)temp_gl_depth_data)[gl_pixel_index]; 1192 u32 depth_stencil = ((u32*)temp_gl_depth_data)[gl_pixel_index];
@@ -900,7 +1198,7 @@ void RasterizerOpenGL::CommitDepthBuffer() {
900 for (int x = 0; x < fb_depth_texture.width; ++x) { 1198 for (int x = 0; x < fb_depth_texture.width; ++x) {
901 const u32 coarse_y = y & ~7; 1199 const u32 coarse_y = y & ~7;
902 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_depth_texture.width * bytes_per_pixel; 1200 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_depth_texture.width * bytes_per_pixel;
903 u32 gl_pixel_index = (x + y * fb_depth_texture.width) * gl_bpp; 1201 u32 gl_pixel_index = (x + (fb_depth_texture.height - 1 - y) * fb_depth_texture.width) * gl_bpp;
904 1202
905 u8* pixel = depth_buffer + dst_offset; 1203 u8* pixel = depth_buffer + dst_offset;
906 memcpy(pixel, &temp_gl_depth_data[gl_pixel_index], bytes_per_pixel); 1204 memcpy(pixel, &temp_gl_depth_data[gl_pixel_index], bytes_per_pixel);
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 5ba898189..fc85aa3ff 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -14,9 +14,11 @@
14#include "common/hash.h" 14#include "common/hash.h"
15 15
16#include "video_core/pica.h" 16#include "video_core/pica.h"
17#include "video_core/hwrasterizer_base.h" 17#include "video_core/pica_state.h"
18#include "video_core/rasterizer_interface.h"
18#include "video_core/renderer_opengl/gl_rasterizer_cache.h" 19#include "video_core/renderer_opengl/gl_rasterizer_cache.h"
19#include "video_core/renderer_opengl/gl_state.h" 20#include "video_core/renderer_opengl/gl_state.h"
21#include "video_core/renderer_opengl/pica_to_gl.h"
20#include "video_core/shader/shader_interpreter.h" 22#include "video_core/shader/shader_interpreter.h"
21 23
22/** 24/**
@@ -71,6 +73,59 @@ struct PicaShaderConfig {
71 regs.tev_combiner_buffer_input.update_mask_rgb.Value() | 73 regs.tev_combiner_buffer_input.update_mask_rgb.Value() |
72 regs.tev_combiner_buffer_input.update_mask_a.Value() << 4; 74 regs.tev_combiner_buffer_input.update_mask_a.Value() << 4;
73 75
76 // Fragment lighting
77
78 res.lighting.enable = !regs.lighting.disable;
79 res.lighting.src_num = regs.lighting.num_lights + 1;
80
81 for (unsigned light_index = 0; light_index < res.lighting.src_num; ++light_index) {
82 unsigned num = regs.lighting.light_enable.GetNum(light_index);
83 const auto& light = regs.lighting.light[num];
84 res.lighting.light[light_index].num = num;
85 res.lighting.light[light_index].directional = light.directional != 0;
86 res.lighting.light[light_index].two_sided_diffuse = light.two_sided_diffuse != 0;
87 res.lighting.light[light_index].dist_atten_enable = !regs.lighting.IsDistAttenDisabled(num);
88 res.lighting.light[light_index].dist_atten_bias = Pica::float20::FromRaw(light.dist_atten_bias).ToFloat32();
89 res.lighting.light[light_index].dist_atten_scale = Pica::float20::FromRaw(light.dist_atten_scale).ToFloat32();
90 }
91
92 res.lighting.lut_d0.enable = regs.lighting.disable_lut_d0 == 0;
93 res.lighting.lut_d0.abs_input = regs.lighting.abs_lut_input.disable_d0 == 0;
94 res.lighting.lut_d0.type = regs.lighting.lut_input.d0.Value();
95 res.lighting.lut_d0.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.d0);
96
97 res.lighting.lut_d1.enable = regs.lighting.disable_lut_d1 == 0;
98 res.lighting.lut_d1.abs_input = regs.lighting.abs_lut_input.disable_d1 == 0;
99 res.lighting.lut_d1.type = regs.lighting.lut_input.d1.Value();
100 res.lighting.lut_d1.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.d1);
101
102 res.lighting.lut_fr.enable = regs.lighting.disable_lut_fr == 0;
103 res.lighting.lut_fr.abs_input = regs.lighting.abs_lut_input.disable_fr == 0;
104 res.lighting.lut_fr.type = regs.lighting.lut_input.fr.Value();
105 res.lighting.lut_fr.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.fr);
106
107 res.lighting.lut_rr.enable = regs.lighting.disable_lut_rr == 0;
108 res.lighting.lut_rr.abs_input = regs.lighting.abs_lut_input.disable_rr == 0;
109 res.lighting.lut_rr.type = regs.lighting.lut_input.rr.Value();
110 res.lighting.lut_rr.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.rr);
111
112 res.lighting.lut_rg.enable = regs.lighting.disable_lut_rg == 0;
113 res.lighting.lut_rg.abs_input = regs.lighting.abs_lut_input.disable_rg == 0;
114 res.lighting.lut_rg.type = regs.lighting.lut_input.rg.Value();
115 res.lighting.lut_rg.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.rg);
116
117 res.lighting.lut_rb.enable = regs.lighting.disable_lut_rb == 0;
118 res.lighting.lut_rb.abs_input = regs.lighting.abs_lut_input.disable_rb == 0;
119 res.lighting.lut_rb.type = regs.lighting.lut_input.rb.Value();
120 res.lighting.lut_rb.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.rb);
121
122 res.lighting.config = regs.lighting.config;
123 res.lighting.fresnel_selector = regs.lighting.fresnel_selector;
124 res.lighting.bump_mode = regs.lighting.bump_mode;
125 res.lighting.bump_selector = regs.lighting.bump_selector;
126 res.lighting.bump_renorm = regs.lighting.disable_bump_renorm == 0;
127 res.lighting.clamp_highlights = regs.lighting.clamp_highlights != 0;
128
74 return res; 129 return res;
75 } 130 }
76 131
@@ -86,9 +141,37 @@ struct PicaShaderConfig {
86 return std::memcmp(this, &o, sizeof(PicaShaderConfig)) == 0; 141 return std::memcmp(this, &o, sizeof(PicaShaderConfig)) == 0;
87 }; 142 };
88 143
89 Pica::Regs::CompareFunc alpha_test_func; 144 Pica::Regs::CompareFunc alpha_test_func = Pica::Regs::CompareFunc::Never;
90 std::array<Pica::Regs::TevStageConfig, 6> tev_stages = {}; 145 std::array<Pica::Regs::TevStageConfig, 6> tev_stages = {};
91 u8 combiner_buffer_input; 146 u8 combiner_buffer_input = 0;
147
148 struct {
149 struct {
150 unsigned num = 0;
151 bool directional = false;
152 bool two_sided_diffuse = false;
153 bool dist_atten_enable = false;
154 GLfloat dist_atten_scale = 0.0f;
155 GLfloat dist_atten_bias = 0.0f;
156 } light[8];
157
158 bool enable = false;
159 unsigned src_num = 0;
160 Pica::Regs::LightingBumpMode bump_mode = Pica::Regs::LightingBumpMode::None;
161 unsigned bump_selector = 0;
162 bool bump_renorm = false;
163 bool clamp_highlights = false;
164
165 Pica::Regs::LightingConfig config = Pica::Regs::LightingConfig::Config0;
166 Pica::Regs::LightingFresnelSelector fresnel_selector = Pica::Regs::LightingFresnelSelector::None;
167
168 struct {
169 bool enable = false;
170 bool abs_input = false;
171 Pica::Regs::LightingLutInput type = Pica::Regs::LightingLutInput::NH;
172 float scale = 1.0f;
173 } lut_d0, lut_d1, lut_fr, lut_rr, lut_rg, lut_rb;
174 } lighting;
92}; 175};
93 176
94namespace std { 177namespace std {
@@ -102,37 +185,22 @@ struct hash<PicaShaderConfig> {
102 185
103} // namespace std 186} // namespace std
104 187
105class RasterizerOpenGL : public HWRasterizer { 188class RasterizerOpenGL : public VideoCore::RasterizerInterface {
106public: 189public:
107 190
108 RasterizerOpenGL(); 191 RasterizerOpenGL();
109 ~RasterizerOpenGL() override; 192 ~RasterizerOpenGL() override;
110 193
111 /// Initialize API-specific GPU objects
112 void InitObjects() override; 194 void InitObjects() override;
113
114 /// Reset the rasterizer, such as flushing all caches and updating all state
115 void Reset() override; 195 void Reset() override;
116
117 /// Queues the primitive formed by the given vertices for rendering
118 void AddTriangle(const Pica::Shader::OutputVertex& v0, 196 void AddTriangle(const Pica::Shader::OutputVertex& v0,
119 const Pica::Shader::OutputVertex& v1, 197 const Pica::Shader::OutputVertex& v1,
120 const Pica::Shader::OutputVertex& v2) override; 198 const Pica::Shader::OutputVertex& v2) override;
121
122 /// Draw the current batch of triangles
123 void DrawTriangles() override; 199 void DrawTriangles() override;
124 200 void FlushFramebuffer() override;
125 /// Commit the rasterizer's framebuffer contents immediately to the current 3DS memory framebuffer
126 void CommitFramebuffer() override;
127
128 /// Notify rasterizer that the specified PICA register has been changed
129 void NotifyPicaRegisterChanged(u32 id) override; 201 void NotifyPicaRegisterChanged(u32 id) override;
130 202 void FlushRegion(PAddr addr, u32 size) override;
131 /// Notify rasterizer that the specified 3DS memory region will be read from after this notification 203 void InvalidateRegion(PAddr addr, u32 size) override;
132 void NotifyPreRead(PAddr addr, u32 size) override;
133
134 /// Notify rasterizer that a 3DS memory region has been changed
135 void NotifyFlush(PAddr addr, u32 size) override;
136 204
137 /// OpenGL shader generated for a given Pica register state 205 /// OpenGL shader generated for a given Pica register state
138 struct PicaShader { 206 struct PicaShader {
@@ -182,7 +250,7 @@ private:
182 250
183 /// Structure that the hardware rendered vertices are composed of 251 /// Structure that the hardware rendered vertices are composed of
184 struct HardwareVertex { 252 struct HardwareVertex {
185 HardwareVertex(const Pica::Shader::OutputVertex& v) { 253 HardwareVertex(const Pica::Shader::OutputVertex& v, bool flip_quaternion) {
186 position[0] = v.pos.x.ToFloat32(); 254 position[0] = v.pos.x.ToFloat32();
187 position[1] = v.pos.y.ToFloat32(); 255 position[1] = v.pos.y.ToFloat32();
188 position[2] = v.pos.z.ToFloat32(); 256 position[2] = v.pos.z.ToFloat32();
@@ -197,6 +265,19 @@ private:
197 tex_coord1[1] = v.tc1.y.ToFloat32(); 265 tex_coord1[1] = v.tc1.y.ToFloat32();
198 tex_coord2[0] = v.tc2.x.ToFloat32(); 266 tex_coord2[0] = v.tc2.x.ToFloat32();
199 tex_coord2[1] = v.tc2.y.ToFloat32(); 267 tex_coord2[1] = v.tc2.y.ToFloat32();
268 normquat[0] = v.quat.x.ToFloat32();
269 normquat[1] = v.quat.y.ToFloat32();
270 normquat[2] = v.quat.z.ToFloat32();
271 normquat[3] = v.quat.w.ToFloat32();
272 view[0] = v.view.x.ToFloat32();
273 view[1] = v.view.y.ToFloat32();
274 view[2] = v.view.z.ToFloat32();
275
276 if (flip_quaternion) {
277 for (float& x : normquat) {
278 x = -x;
279 }
280 }
200 } 281 }
201 282
202 GLfloat position[4]; 283 GLfloat position[4];
@@ -204,19 +285,31 @@ private:
204 GLfloat tex_coord0[2]; 285 GLfloat tex_coord0[2];
205 GLfloat tex_coord1[2]; 286 GLfloat tex_coord1[2];
206 GLfloat tex_coord2[2]; 287 GLfloat tex_coord2[2];
288 GLfloat normquat[4];
289 GLfloat view[3];
290 };
291
292 struct LightSrc {
293 alignas(16) GLvec3 specular_0;
294 alignas(16) GLvec3 specular_1;
295 alignas(16) GLvec3 diffuse;
296 alignas(16) GLvec3 ambient;
297 alignas(16) GLvec3 position;
207 }; 298 };
208 299
209 /// Uniform structure for the Uniform Buffer Object, all members must be 16-byte aligned 300 /// Uniform structure for the Uniform Buffer Object, all members must be 16-byte aligned
210 struct UniformData { 301 struct UniformData {
211 // A vec4 color for each of the six tev stages 302 // A vec4 color for each of the six tev stages
212 std::array<GLfloat, 4> const_color[6]; 303 GLvec4 const_color[6];
213 std::array<GLfloat, 4> tev_combiner_buffer_color; 304 GLvec4 tev_combiner_buffer_color;
214 GLint alphatest_ref; 305 GLint alphatest_ref;
215 INSERT_PADDING_BYTES(12); 306 GLfloat depth_offset;
307 alignas(16) GLvec3 lighting_global_ambient;
308 LightSrc light_src[8];
216 }; 309 };
217 310
218 static_assert(sizeof(UniformData) == 0x80, "The size of the UniformData structure has changed, update the structure in the shader"); 311 static_assert(sizeof(UniformData) == 0x310, "The size of the UniformData structure has changed, update the structure in the shader");
219 static_assert(sizeof(UniformData) < 16000, "UniformData structure must be less than 16kb as per the OpenGL spec"); 312 static_assert(sizeof(UniformData) < 16384, "UniformData structure must be less than 16kb as per the OpenGL spec");
220 313
221 /// Reconfigure the OpenGL color texture to use the given format and dimensions 314 /// Reconfigure the OpenGL color texture to use the given format and dimensions
222 void ReconfigureColorTexture(TextureInfo& texture, Pica::Regs::ColorFormat format, u32 width, u32 height); 315 void ReconfigureColorTexture(TextureInfo& texture, Pica::Regs::ColorFormat format, u32 width, u32 height);
@@ -233,6 +326,9 @@ private:
233 /// Syncs the cull mode to match the PICA register 326 /// Syncs the cull mode to match the PICA register
234 void SyncCullMode(); 327 void SyncCullMode();
235 328
329 /// Syncs the depth scale and offset to match the PICA registers
330 void SyncDepthModifiers();
331
236 /// Syncs the blend enabled status to match the PICA register 332 /// Syncs the blend enabled status to match the PICA register
237 void SyncBlendEnabled(); 333 void SyncBlendEnabled();
238 334
@@ -260,6 +356,27 @@ private:
260 /// Syncs the TEV combiner color buffer to match the PICA register 356 /// Syncs the TEV combiner color buffer to match the PICA register
261 void SyncCombinerColor(); 357 void SyncCombinerColor();
262 358
359 /// Syncs the lighting global ambient color to match the PICA register
360 void SyncGlobalAmbient();
361
362 /// Syncs the lighting lookup tables
363 void SyncLightingLUT(unsigned index);
364
365 /// Syncs the specified light's diffuse color to match the PICA register
366 void SyncLightDiffuse(int light_index);
367
368 /// Syncs the specified light's ambient color to match the PICA register
369 void SyncLightAmbient(int light_index);
370
371 /// Syncs the specified light's position to match the PICA register
372 void SyncLightPosition(int light_index);
373
374 /// Syncs the specified light's specular 0 color to match the PICA register
375 void SyncLightSpecular0(int light_index);
376
377 /// Syncs the specified light's specular 1 color to match the PICA register
378 void SyncLightSpecular1(int light_index);
379
263 /// Syncs the remaining OpenGL drawing state to match the current PICA state 380 /// Syncs the remaining OpenGL drawing state to match the current PICA state
264 void SyncDrawState(); 381 void SyncDrawState();
265 382
@@ -289,8 +406,8 @@ private:
289 406
290 OpenGLState state; 407 OpenGLState state;
291 408
292 PAddr last_fb_color_addr; 409 PAddr cached_fb_color_addr;
293 PAddr last_fb_depth_addr; 410 PAddr cached_fb_depth_addr;
294 411
295 // Hardware rasterizer 412 // Hardware rasterizer
296 std::array<SamplerInfo, 3> texture_samplers; 413 std::array<SamplerInfo, 3> texture_samplers;
@@ -302,6 +419,7 @@ private:
302 419
303 struct { 420 struct {
304 UniformData data; 421 UniformData data;
422 bool lut_dirty[6];
305 bool dirty; 423 bool dirty;
306 } uniform_block_data; 424 } uniform_block_data;
307 425
@@ -309,4 +427,7 @@ private:
309 OGLBuffer vertex_buffer; 427 OGLBuffer vertex_buffer;
310 OGLBuffer uniform_buffer; 428 OGLBuffer uniform_buffer;
311 OGLFramebuffer framebuffer; 429 OGLFramebuffer framebuffer;
430
431 std::array<OGLTexture, 6> lighting_lut;
432 std::array<std::array<GLvec4, 256>, 6> lighting_lut_data;
312}; 433};
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index 10d4ab0b6..a9ad46fe0 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -15,7 +15,7 @@
15#include "video_core/renderer_opengl/pica_to_gl.h" 15#include "video_core/renderer_opengl/pica_to_gl.h"
16 16
17RasterizerCacheOpenGL::~RasterizerCacheOpenGL() { 17RasterizerCacheOpenGL::~RasterizerCacheOpenGL() {
18 FullFlush(); 18 InvalidateAll();
19} 19}
20 20
21MICROPROFILE_DEFINE(OpenGL_TextureUpload, "OpenGL", "Texture Upload", MP_RGB(128, 64, 192)); 21MICROPROFILE_DEFINE(OpenGL_TextureUpload, "OpenGL", "Texture Upload", MP_RGB(128, 64, 192));
@@ -58,8 +58,7 @@ void RasterizerCacheOpenGL::LoadAndBindTexture(OpenGLState &state, unsigned text
58 } 58 }
59} 59}
60 60
61void RasterizerCacheOpenGL::NotifyFlush(PAddr addr, u32 size, bool ignore_hash) { 61void RasterizerCacheOpenGL::InvalidateInRange(PAddr addr, u32 size, bool ignore_hash) {
62 // Flush any texture that falls in the flushed region
63 // TODO: Optimize by also inserting upper bound (addr + size) of each texture into the same map and also narrow using lower_bound 62 // TODO: Optimize by also inserting upper bound (addr + size) of each texture into the same map and also narrow using lower_bound
64 auto cache_upper_bound = texture_cache.upper_bound(addr + size); 63 auto cache_upper_bound = texture_cache.upper_bound(addr + size);
65 64
@@ -77,6 +76,6 @@ void RasterizerCacheOpenGL::NotifyFlush(PAddr addr, u32 size, bool ignore_hash)
77 } 76 }
78} 77}
79 78
80void RasterizerCacheOpenGL::FullFlush() { 79void RasterizerCacheOpenGL::InvalidateAll() {
81 texture_cache.clear(); 80 texture_cache.clear();
82} 81}
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
index 98a48ffbe..b69651427 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
@@ -23,11 +23,11 @@ public:
23 LoadAndBindTexture(state, texture_unit, Pica::DebugUtils::TextureInfo::FromPicaRegister(config.config, config.format)); 23 LoadAndBindTexture(state, texture_unit, Pica::DebugUtils::TextureInfo::FromPicaRegister(config.config, config.format));
24 } 24 }
25 25
26 /// Flush any cached resource that touches the flushed region 26 /// Invalidate any cached resource intersecting the specified region.
27 void NotifyFlush(PAddr addr, u32 size, bool ignore_hash = false); 27 void InvalidateInRange(PAddr addr, u32 size, bool ignore_hash = false);
28 28
29 /// Flush all cached OpenGL resources tracked by this cache manager 29 /// Invalidate all cached OpenGL resources tracked by this cache manager
30 void FullFlush(); 30 void InvalidateAll();
31 31
32private: 32private:
33 struct CachedTexture { 33 struct CachedTexture {
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp
index 498c506e7..ee4b54ab9 100644
--- a/src/video_core/renderer_opengl/gl_shader_gen.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp
@@ -32,12 +32,10 @@ static void AppendSource(std::string& out, TevStageConfig::Source source,
32 out += "primary_color"; 32 out += "primary_color";
33 break; 33 break;
34 case Source::PrimaryFragmentColor: 34 case Source::PrimaryFragmentColor:
35 // HACK: Until we implement fragment lighting, use primary_color 35 out += "primary_fragment_color";
36 out += "primary_color";
37 break; 36 break;
38 case Source::SecondaryFragmentColor: 37 case Source::SecondaryFragmentColor:
39 // HACK: Until we implement fragment lighting, use zero 38 out += "secondary_fragment_color";
40 out += "vec4(0.0)";
41 break; 39 break;
42 case Source::Texture0: 40 case Source::Texture0:
43 out += "texture(tex[0], texcoord[0])"; 41 out += "texture(tex[0], texcoord[0])";
@@ -320,25 +318,229 @@ static void WriteTevStage(std::string& out, const PicaShaderConfig& config, unsi
320 out += "next_combiner_buffer.a = last_tex_env_out.a;\n"; 318 out += "next_combiner_buffer.a = last_tex_env_out.a;\n";
321} 319}
322 320
321/// Writes the code to emulate fragment lighting
322static void WriteLighting(std::string& out, const PicaShaderConfig& config) {
323 // Define lighting globals
324 out += "vec4 diffuse_sum = vec4(0.0, 0.0, 0.0, 1.0);\n"
325 "vec4 specular_sum = vec4(0.0, 0.0, 0.0, 1.0);\n"
326 "vec3 light_vector = vec3(0.0);\n"
327 "vec3 refl_value = vec3(0.0);\n";
328
329 // Compute fragment normals
330 if (config.lighting.bump_mode == Pica::Regs::LightingBumpMode::NormalMap) {
331 // Bump mapping is enabled using a normal map, read perturbation vector from the selected texture
332 std::string bump_selector = std::to_string(config.lighting.bump_selector);
333 out += "vec3 surface_normal = 2.0 * texture(tex[" + bump_selector + "], texcoord[" + bump_selector + "]).rgb - 1.0;\n";
334
335 // Recompute Z-component of perturbation if 'renorm' is enabled, this provides a higher precision result
336 if (config.lighting.bump_renorm) {
337 std::string val = "(1.0 - (surface_normal.x*surface_normal.x + surface_normal.y*surface_normal.y))";
338 out += "surface_normal.z = sqrt(max(" + val + ", 0.0));\n";
339 }
340 } else if (config.lighting.bump_mode == Pica::Regs::LightingBumpMode::TangentMap) {
341 // Bump mapping is enabled using a tangent map
342 LOG_CRITICAL(HW_GPU, "unimplemented bump mapping mode (tangent mapping)");
343 UNIMPLEMENTED();
344 } else {
345 // No bump mapping - surface local normal is just a unit normal
346 out += "vec3 surface_normal = vec3(0.0, 0.0, 1.0);\n";
347 }
348
349 // Rotate the surface-local normal by the interpolated normal quaternion to convert it to eyespace
350 out += "vec3 normal = normalize(quaternion_rotate(normquat, surface_normal));\n";
351
352 // Gets the index into the specified lookup table for specular lighting
353 auto GetLutIndex = [config](unsigned light_num, Regs::LightingLutInput input, bool abs) {
354 const std::string half_angle = "normalize(normalize(view) + light_vector)";
355 std::string index;
356 switch (input) {
357 case Regs::LightingLutInput::NH:
358 index = "dot(normal, " + half_angle + ")";
359 break;
360
361 case Regs::LightingLutInput::VH:
362 index = std::string("dot(normalize(view), " + half_angle + ")");
363 break;
364
365 case Regs::LightingLutInput::NV:
366 index = std::string("dot(normal, normalize(view))");
367 break;
368
369 case Regs::LightingLutInput::LN:
370 index = std::string("dot(light_vector, normal)");
371 break;
372
373 default:
374 LOG_CRITICAL(HW_GPU, "Unknown lighting LUT input %d\n", (int)input);
375 UNIMPLEMENTED();
376 break;
377 }
378
379 if (abs) {
380 // LUT index is in the range of (0.0, 1.0)
381 index = config.lighting.light[light_num].two_sided_diffuse ? "abs(" + index + ")" : "max(" + index + ", 0.f)";
382 return "(FLOAT_255 * clamp(" + index + ", 0.0, 1.0))";
383 } else {
384 // LUT index is in the range of (-1.0, 1.0)
385 index = "clamp(" + index + ", -1.0, 1.0)";
386 return "(FLOAT_255 * ((" + index + " < 0) ? " + index + " + 2.0 : " + index + ") / 2.0)";
387 }
388
389 return std::string();
390 };
391
392 // Gets the lighting lookup table value given the specified sampler and index
393 auto GetLutValue = [](Regs::LightingSampler sampler, std::string lut_index) {
394 return std::string("texture(lut[" + std::to_string((unsigned)sampler / 4) + "], " +
395 lut_index + ")[" + std::to_string((unsigned)sampler & 3) + "]");
396 };
397
398 // Write the code to emulate each enabled light
399 for (unsigned light_index = 0; light_index < config.lighting.src_num; ++light_index) {
400 const auto& light_config = config.lighting.light[light_index];
401 std::string light_src = "light_src[" + std::to_string(light_config.num) + "]";
402
403 // Compute light vector (directional or positional)
404 if (light_config.directional)
405 out += "light_vector = normalize(" + light_src + ".position);\n";
406 else
407 out += "light_vector = normalize(" + light_src + ".position + view);\n";
408
409 // Compute dot product of light_vector and normal, adjust if lighting is one-sided or two-sided
410 std::string dot_product = light_config.two_sided_diffuse ? "abs(dot(light_vector, normal))" : "max(dot(light_vector, normal), 0.0)";
411
412 // If enabled, compute distance attenuation value
413 std::string dist_atten = "1.0";
414 if (light_config.dist_atten_enable) {
415 std::string scale = std::to_string(light_config.dist_atten_scale);
416 std::string bias = std::to_string(light_config.dist_atten_bias);
417 std::string index = "(" + scale + " * length(-view - " + light_src + ".position) + " + bias + ")";
418 index = "((clamp(" + index + ", 0.0, FLOAT_255)))";
419 const unsigned lut_num = ((unsigned)Regs::LightingSampler::DistanceAttenuation + light_config.num);
420 dist_atten = GetLutValue((Regs::LightingSampler)lut_num, index);
421 }
422
423 // If enabled, clamp specular component if lighting result is negative
424 std::string clamp_highlights = config.lighting.clamp_highlights ? "(dot(light_vector, normal) <= 0.0 ? 0.0 : 1.0)" : "1.0";
425
426 // Specular 0 component
427 std::string d0_lut_value = "1.0";
428 if (config.lighting.lut_d0.enable && Pica::Regs::IsLightingSamplerSupported(config.lighting.config, Pica::Regs::LightingSampler::Distribution0)) {
429 // Lookup specular "distribution 0" LUT value
430 std::string index = GetLutIndex(light_config.num, config.lighting.lut_d0.type, config.lighting.lut_d0.abs_input);
431 d0_lut_value = "(" + std::to_string(config.lighting.lut_d0.scale) + " * " + GetLutValue(Regs::LightingSampler::Distribution0, index) + ")";
432 }
433 std::string specular_0 = "(" + d0_lut_value + " * " + light_src + ".specular_0)";
434
435 // If enabled, lookup ReflectRed value, otherwise, 1.0 is used
436 if (config.lighting.lut_rr.enable && Pica::Regs::IsLightingSamplerSupported(config.lighting.config, Pica::Regs::LightingSampler::ReflectRed)) {
437 std::string index = GetLutIndex(light_config.num, config.lighting.lut_rr.type, config.lighting.lut_rr.abs_input);
438 std::string value = "(" + std::to_string(config.lighting.lut_rr.scale) + " * " + GetLutValue(Regs::LightingSampler::ReflectRed, index) + ")";
439 out += "refl_value.r = " + value + ";\n";
440 } else {
441 out += "refl_value.r = 1.0;\n";
442 }
443
444 // If enabled, lookup ReflectGreen value, otherwise, ReflectRed value is used
445 if (config.lighting.lut_rg.enable && Pica::Regs::IsLightingSamplerSupported(config.lighting.config, Pica::Regs::LightingSampler::ReflectGreen)) {
446 std::string index = GetLutIndex(light_config.num, config.lighting.lut_rg.type, config.lighting.lut_rg.abs_input);
447 std::string value = "(" + std::to_string(config.lighting.lut_rg.scale) + " * " + GetLutValue(Regs::LightingSampler::ReflectGreen, index) + ")";
448 out += "refl_value.g = " + value + ";\n";
449 } else {
450 out += "refl_value.g = refl_value.r;\n";
451 }
452
453 // If enabled, lookup ReflectBlue value, otherwise, ReflectRed value is used
454 if (config.lighting.lut_rb.enable && Pica::Regs::IsLightingSamplerSupported(config.lighting.config, Pica::Regs::LightingSampler::ReflectBlue)) {
455 std::string index = GetLutIndex(light_config.num, config.lighting.lut_rb.type, config.lighting.lut_rb.abs_input);
456 std::string value = "(" + std::to_string(config.lighting.lut_rb.scale) + " * " + GetLutValue(Regs::LightingSampler::ReflectBlue, index) + ")";
457 out += "refl_value.b = " + value + ";\n";
458 } else {
459 out += "refl_value.b = refl_value.r;\n";
460 }
461
462 // Specular 1 component
463 std::string d1_lut_value = "1.0";
464 if (config.lighting.lut_d1.enable && Pica::Regs::IsLightingSamplerSupported(config.lighting.config, Pica::Regs::LightingSampler::Distribution1)) {
465 // Lookup specular "distribution 1" LUT value
466 std::string index = GetLutIndex(light_config.num, config.lighting.lut_d1.type, config.lighting.lut_d1.abs_input);
467 d1_lut_value = "(" + std::to_string(config.lighting.lut_d1.scale) + " * " + GetLutValue(Regs::LightingSampler::Distribution1, index) + ")";
468 }
469 std::string specular_1 = "(" + d1_lut_value + " * refl_value * " + light_src + ".specular_1)";
470
471 // Fresnel
472 if (config.lighting.lut_fr.enable && Pica::Regs::IsLightingSamplerSupported(config.lighting.config, Pica::Regs::LightingSampler::Fresnel)) {
473 // Lookup fresnel LUT value
474 std::string index = GetLutIndex(light_config.num, config.lighting.lut_fr.type, config.lighting.lut_fr.abs_input);
475 std::string value = "(" + std::to_string(config.lighting.lut_fr.scale) + " * " + GetLutValue(Regs::LightingSampler::Fresnel, index) + ")";
476
477 // Enabled for difffuse lighting alpha component
478 if (config.lighting.fresnel_selector == Pica::Regs::LightingFresnelSelector::PrimaryAlpha ||
479 config.lighting.fresnel_selector == Pica::Regs::LightingFresnelSelector::Both)
480 out += "diffuse_sum.a *= " + value + ";\n";
481
482 // Enabled for the specular lighting alpha component
483 if (config.lighting.fresnel_selector == Pica::Regs::LightingFresnelSelector::SecondaryAlpha ||
484 config.lighting.fresnel_selector == Pica::Regs::LightingFresnelSelector::Both)
485 out += "specular_sum.a *= " + value + ";\n";
486 }
487
488 // Compute primary fragment color (diffuse lighting) function
489 out += "diffuse_sum.rgb += ((" + light_src + ".diffuse * " + dot_product + ") + " + light_src + ".ambient) * " + dist_atten + ";\n";
490
491 // Compute secondary fragment color (specular lighting) function
492 out += "specular_sum.rgb += (" + specular_0 + " + " + specular_1 + ") * " + clamp_highlights + " * " + dist_atten + ";\n";
493 }
494
495 // Sum final lighting result
496 out += "diffuse_sum.rgb += lighting_global_ambient;\n";
497 out += "primary_fragment_color = clamp(diffuse_sum, vec4(0.0), vec4(1.0));\n";
498 out += "secondary_fragment_color = clamp(specular_sum, vec4(0.0), vec4(1.0));\n";
499}
500
323std::string GenerateFragmentShader(const PicaShaderConfig& config) { 501std::string GenerateFragmentShader(const PicaShaderConfig& config) {
324 std::string out = R"( 502 std::string out = R"(
325#version 330 core 503#version 330 core
326#define NUM_TEV_STAGES 6 504#define NUM_TEV_STAGES 6
505#define NUM_LIGHTS 8
506#define LIGHTING_LUT_SIZE 256
507#define FLOAT_255 (255.0 / 256.0)
327 508
328in vec4 primary_color; 509in vec4 primary_color;
329in vec2 texcoord[3]; 510in vec2 texcoord[3];
511in vec4 normquat;
512in vec3 view;
330 513
331out vec4 color; 514out vec4 color;
332 515
516struct LightSrc {
517 vec3 specular_0;
518 vec3 specular_1;
519 vec3 diffuse;
520 vec3 ambient;
521 vec3 position;
522};
523
333layout (std140) uniform shader_data { 524layout (std140) uniform shader_data {
334 vec4 const_color[NUM_TEV_STAGES]; 525 vec4 const_color[NUM_TEV_STAGES];
335 vec4 tev_combiner_buffer_color; 526 vec4 tev_combiner_buffer_color;
336 int alphatest_ref; 527 int alphatest_ref;
528 float depth_offset;
529 vec3 lighting_global_ambient;
530 LightSrc light_src[NUM_LIGHTS];
337}; 531};
338 532
339uniform sampler2D tex[3]; 533uniform sampler2D tex[3];
534uniform sampler1D lut[6];
535
536// Rotate the vector v by the quaternion q
537vec3 quaternion_rotate(vec4 q, vec3 v) {
538 return v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);
539}
340 540
341void main() { 541void main() {
542vec4 primary_fragment_color = vec4(0.0);
543vec4 secondary_fragment_color = vec4(0.0);
342)"; 544)";
343 545
344 // Do not do any sort of processing if it's obvious we're not going to pass the alpha test 546 // Do not do any sort of processing if it's obvious we're not going to pass the alpha test
@@ -347,6 +549,9 @@ void main() {
347 return out; 549 return out;
348 } 550 }
349 551
552 if (config.lighting.enable)
553 WriteLighting(out, config);
554
350 out += "vec4 combiner_buffer = vec4(0.0);\n"; 555 out += "vec4 combiner_buffer = vec4(0.0);\n";
351 out += "vec4 next_combiner_buffer = tev_combiner_buffer_color;\n"; 556 out += "vec4 next_combiner_buffer = tev_combiner_buffer_color;\n";
352 out += "vec4 last_tex_env_out = vec4(0.0);\n"; 557 out += "vec4 last_tex_env_out = vec4(0.0);\n";
@@ -360,29 +565,37 @@ void main() {
360 out += ") discard;\n"; 565 out += ") discard;\n";
361 } 566 }
362 567
363 out += "color = last_tex_env_out;\n}"; 568 out += "color = last_tex_env_out;\n";
569 out += "gl_FragDepth = gl_FragCoord.z + depth_offset;\n}";
364 570
365 return out; 571 return out;
366} 572}
367 573
368std::string GenerateVertexShader() { 574std::string GenerateVertexShader() {
369 std::string out = "#version 330 core\n"; 575 std::string out = "#version 330 core\n";
576
370 out += "layout(location = " + std::to_string((int)ATTRIBUTE_POSITION) + ") in vec4 vert_position;\n"; 577 out += "layout(location = " + std::to_string((int)ATTRIBUTE_POSITION) + ") in vec4 vert_position;\n";
371 out += "layout(location = " + std::to_string((int)ATTRIBUTE_COLOR) + ") in vec4 vert_color;\n"; 578 out += "layout(location = " + std::to_string((int)ATTRIBUTE_COLOR) + ") in vec4 vert_color;\n";
372 out += "layout(location = " + std::to_string((int)ATTRIBUTE_TEXCOORD0) + ") in vec2 vert_texcoord0;\n"; 579 out += "layout(location = " + std::to_string((int)ATTRIBUTE_TEXCOORD0) + ") in vec2 vert_texcoord0;\n";
373 out += "layout(location = " + std::to_string((int)ATTRIBUTE_TEXCOORD1) + ") in vec2 vert_texcoord1;\n"; 580 out += "layout(location = " + std::to_string((int)ATTRIBUTE_TEXCOORD1) + ") in vec2 vert_texcoord1;\n";
374 out += "layout(location = " + std::to_string((int)ATTRIBUTE_TEXCOORD2) + ") in vec2 vert_texcoord2;\n"; 581 out += "layout(location = " + std::to_string((int)ATTRIBUTE_TEXCOORD2) + ") in vec2 vert_texcoord2;\n";
582 out += "layout(location = " + std::to_string((int)ATTRIBUTE_NORMQUAT) + ") in vec4 vert_normquat;\n";
583 out += "layout(location = " + std::to_string((int)ATTRIBUTE_VIEW) + ") in vec3 vert_view;\n";
375 584
376 out += R"( 585 out += R"(
377out vec4 primary_color; 586out vec4 primary_color;
378out vec2 texcoord[3]; 587out vec2 texcoord[3];
588out vec4 normquat;
589out vec3 view;
379 590
380void main() { 591void main() {
381 primary_color = vert_color; 592 primary_color = vert_color;
382 texcoord[0] = vert_texcoord0; 593 texcoord[0] = vert_texcoord0;
383 texcoord[1] = vert_texcoord1; 594 texcoord[1] = vert_texcoord1;
384 texcoord[2] = vert_texcoord2; 595 texcoord[2] = vert_texcoord2;
385 gl_Position = vec4(vert_position.x, -vert_position.y, -vert_position.z, vert_position.w); 596 normquat = vert_normquat;
597 view = vert_view;
598 gl_Position = vec4(vert_position.x, vert_position.y, -vert_position.z, vert_position.w);
386} 599}
387)"; 600)";
388 601
diff --git a/src/video_core/renderer_opengl/gl_shader_util.h b/src/video_core/renderer_opengl/gl_shader_util.h
index 046aae14f..097242f6f 100644
--- a/src/video_core/renderer_opengl/gl_shader_util.h
+++ b/src/video_core/renderer_opengl/gl_shader_util.h
@@ -14,6 +14,8 @@ enum Attributes {
14 ATTRIBUTE_TEXCOORD0, 14 ATTRIBUTE_TEXCOORD0,
15 ATTRIBUTE_TEXCOORD1, 15 ATTRIBUTE_TEXCOORD1,
16 ATTRIBUTE_TEXCOORD2, 16 ATTRIBUTE_TEXCOORD2,
17 ATTRIBUTE_NORMQUAT,
18 ATTRIBUTE_VIEW,
17}; 19};
18 20
19/** 21/**
diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp
index c44497fc3..08e4d0b54 100644
--- a/src/video_core/renderer_opengl/gl_state.cpp
+++ b/src/video_core/renderer_opengl/gl_state.cpp
@@ -11,6 +11,7 @@ OpenGLState::OpenGLState() {
11 // These all match default OpenGL values 11 // These all match default OpenGL values
12 cull.enabled = false; 12 cull.enabled = false;
13 cull.mode = GL_BACK; 13 cull.mode = GL_BACK;
14 cull.front_face = GL_CCW;
14 15
15 depth.test_enabled = false; 16 depth.test_enabled = false;
16 depth.test_func = GL_LESS; 17 depth.test_func = GL_LESS;
@@ -47,6 +48,10 @@ OpenGLState::OpenGLState() {
47 texture_unit.sampler = 0; 48 texture_unit.sampler = 0;
48 } 49 }
49 50
51 for (auto& lut : lighting_lut) {
52 lut.texture_1d = 0;
53 }
54
50 draw.framebuffer = 0; 55 draw.framebuffer = 0;
51 draw.vertex_array = 0; 56 draw.vertex_array = 0;
52 draw.vertex_buffer = 0; 57 draw.vertex_buffer = 0;
@@ -67,6 +72,10 @@ void OpenGLState::Apply() {
67 glCullFace(cull.mode); 72 glCullFace(cull.mode);
68 } 73 }
69 74
75 if (cull.front_face != cur_state.cull.front_face) {
76 glFrontFace(cull.front_face);
77 }
78
70 // Depth test 79 // Depth test
71 if (depth.test_enabled != cur_state.depth.test_enabled) { 80 if (depth.test_enabled != cur_state.depth.test_enabled) {
72 if (depth.test_enabled) { 81 if (depth.test_enabled) {
@@ -165,6 +174,14 @@ void OpenGLState::Apply() {
165 } 174 }
166 } 175 }
167 176
177 // Lighting LUTs
178 for (unsigned i = 0; i < ARRAY_SIZE(lighting_lut); ++i) {
179 if (lighting_lut[i].texture_1d != cur_state.lighting_lut[i].texture_1d) {
180 glActiveTexture(GL_TEXTURE3 + i);
181 glBindTexture(GL_TEXTURE_1D, lighting_lut[i].texture_1d);
182 }
183 }
184
168 // Framebuffer 185 // Framebuffer
169 if (draw.framebuffer != cur_state.draw.framebuffer) { 186 if (draw.framebuffer != cur_state.draw.framebuffer) {
170 glBindFramebuffer(GL_FRAMEBUFFER, draw.framebuffer); 187 glBindFramebuffer(GL_FRAMEBUFFER, draw.framebuffer);
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h
index 84b3d49bc..e848058d7 100644
--- a/src/video_core/renderer_opengl/gl_state.h
+++ b/src/video_core/renderer_opengl/gl_state.h
@@ -11,6 +11,7 @@ public:
11 struct { 11 struct {
12 bool enabled; // GL_CULL_FACE 12 bool enabled; // GL_CULL_FACE
13 GLenum mode; // GL_CULL_FACE_MODE 13 GLenum mode; // GL_CULL_FACE_MODE
14 GLenum front_face; // GL_FRONT_FACE
14 } cull; 15 } cull;
15 16
16 struct { 17 struct {
@@ -61,6 +62,10 @@ public:
61 } texture_units[3]; 62 } texture_units[3];
62 63
63 struct { 64 struct {
65 GLuint texture_1d; // GL_TEXTURE_BINDING_1D
66 } lighting_lut[6];
67
68 struct {
64 GLuint framebuffer; // GL_DRAW_FRAMEBUFFER_BINDING 69 GLuint framebuffer; // GL_DRAW_FRAMEBUFFER_BINDING
65 GLuint vertex_array; // GL_VERTEX_ARRAY_BINDING 70 GLuint vertex_array; // GL_VERTEX_ARRAY_BINDING
66 GLuint vertex_buffer; // GL_ARRAY_BUFFER_BINDING 71 GLuint vertex_buffer; // GL_ARRAY_BUFFER_BINDING
diff --git a/src/video_core/renderer_opengl/pica_to_gl.h b/src/video_core/renderer_opengl/pica_to_gl.h
index 04c1d1a34..3d6c4e9e5 100644
--- a/src/video_core/renderer_opengl/pica_to_gl.h
+++ b/src/video_core/renderer_opengl/pica_to_gl.h
@@ -10,6 +10,9 @@
10 10
11#include "video_core/pica.h" 11#include "video_core/pica.h"
12 12
13using GLvec3 = std::array<GLfloat, 3>;
14using GLvec4 = std::array<GLfloat, 4>;
15
13namespace PicaToGL { 16namespace PicaToGL {
14 17
15inline GLenum TextureFilterMode(Pica::Regs::TextureConfig::TextureFilter mode) { 18inline GLenum TextureFilterMode(Pica::Regs::TextureConfig::TextureFilter mode) {
@@ -175,7 +178,7 @@ inline GLenum StencilOp(Pica::Regs::StencilAction action) {
175 return stencil_op_table[(unsigned)action]; 178 return stencil_op_table[(unsigned)action];
176} 179}
177 180
178inline std::array<GLfloat, 4> ColorRGBA8(const u32 color) { 181inline GLvec4 ColorRGBA8(const u32 color) {
179 return { { (color >> 0 & 0xFF) / 255.0f, 182 return { { (color >> 0 & 0xFF) / 255.0f,
180 (color >> 8 & 0xFF) / 255.0f, 183 (color >> 8 & 0xFF) / 255.0f,
181 (color >> 16 & 0xFF) / 255.0f, 184 (color >> 16 & 0xFF) / 255.0f,
@@ -183,4 +186,11 @@ inline std::array<GLfloat, 4> ColorRGBA8(const u32 color) {
183 } }; 186 } };
184} 187}
185 188
189inline std::array<GLfloat, 3> LightColor(const Pica::Regs::LightColor& color) {
190 return { { color.r / 255.0f,
191 color.g / 255.0f,
192 color.b / 255.0f
193 } };
194}
195
186} // namespace 196} // namespace
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 1420229cc..11c4d0daf 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -81,8 +81,8 @@ struct ScreenRectVertex {
81 * The projection part of the matrix is trivial, hence these operations are represented 81 * The projection part of the matrix is trivial, hence these operations are represented
82 * by a 3x2 matrix. 82 * by a 3x2 matrix.
83 */ 83 */
84static std::array<GLfloat, 3*2> MakeOrthographicMatrix(const float width, const float height) { 84static std::array<GLfloat, 3 * 2> MakeOrthographicMatrix(const float width, const float height) {
85 std::array<GLfloat, 3*2> matrix; 85 std::array<GLfloat, 3 * 2> matrix;
86 86
87 matrix[0] = 2.f / width; matrix[2] = 0.f; matrix[4] = -1.f; 87 matrix[0] = 2.f / width; matrix[2] = 0.f; matrix[4] = -1.f;
88 matrix[1] = 0.f; matrix[3] = -2.f / height; matrix[5] = 1.f; 88 matrix[1] = 0.f; matrix[3] = -2.f / height; matrix[5] = 1.f;
@@ -93,7 +93,6 @@ static std::array<GLfloat, 3*2> MakeOrthographicMatrix(const float width, const
93 93
94/// RendererOpenGL constructor 94/// RendererOpenGL constructor
95RendererOpenGL::RendererOpenGL() { 95RendererOpenGL::RendererOpenGL() {
96 hw_rasterizer.reset(new RasterizerOpenGL());
97 resolution_width = std::max(VideoCore::kScreenTopWidth, VideoCore::kScreenBottomWidth); 96 resolution_width = std::max(VideoCore::kScreenTopWidth, VideoCore::kScreenBottomWidth);
98 resolution_height = VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight; 97 resolution_height = VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight;
99} 98}
@@ -157,15 +156,7 @@ void RendererOpenGL::SwapBuffers() {
157 156
158 profiler.BeginFrame(); 157 profiler.BeginFrame();
159 158
160 bool hw_renderer_enabled = VideoCore::g_hw_renderer_enabled; 159 RefreshRasterizerSetting();
161 if (Settings::values.use_hw_renderer != hw_renderer_enabled) {
162 // TODO: Save new setting value to config file for next startup
163 Settings::values.use_hw_renderer = hw_renderer_enabled;
164
165 if (Settings::values.use_hw_renderer) {
166 hw_rasterizer->Reset();
167 }
168 }
169 160
170 if (Pica::g_debug_context && Pica::g_debug_context->recorder) { 161 if (Pica::g_debug_context && Pica::g_debug_context->recorder) {
171 Pica::g_debug_context->recorder->FrameFinished(); 162 Pica::g_debug_context->recorder->FrameFinished();
@@ -286,8 +277,6 @@ void RendererOpenGL::InitOpenGLObjects() {
286 277
287 state.texture_units[0].texture_2d = 0; 278 state.texture_units[0].texture_2d = 0;
288 state.Apply(); 279 state.Apply();
289
290 hw_rasterizer->InitObjects();
291} 280}
292 281
293void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture, 282void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture,
@@ -405,8 +394,58 @@ void RendererOpenGL::SetWindow(EmuWindow* window) {
405 render_window = window; 394 render_window = window;
406} 395}
407 396
397static const char* GetSource(GLenum source) {
398#define RET(s) case GL_DEBUG_SOURCE_##s: return #s
399 switch (source) {
400 RET(API);
401 RET(WINDOW_SYSTEM);
402 RET(SHADER_COMPILER);
403 RET(THIRD_PARTY);
404 RET(APPLICATION);
405 RET(OTHER);
406 default:
407 UNREACHABLE();
408 }
409#undef RET
410}
411
412static const char* GetType(GLenum type) {
413#define RET(t) case GL_DEBUG_TYPE_##t: return #t
414 switch (type) {
415 RET(ERROR);
416 RET(DEPRECATED_BEHAVIOR);
417 RET(UNDEFINED_BEHAVIOR);
418 RET(PORTABILITY);
419 RET(PERFORMANCE);
420 RET(OTHER);
421 RET(MARKER);
422 default:
423 UNREACHABLE();
424 }
425#undef RET
426}
427
428static void DebugHandler(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
429 const GLchar* message, const void* user_param) {
430 Log::Level level;
431 switch (severity) {
432 case GL_DEBUG_SEVERITY_HIGH:
433 level = Log::Level::Error;
434 break;
435 case GL_DEBUG_SEVERITY_MEDIUM:
436 level = Log::Level::Warning;
437 break;
438 case GL_DEBUG_SEVERITY_NOTIFICATION:
439 case GL_DEBUG_SEVERITY_LOW:
440 level = Log::Level::Debug;
441 break;
442 }
443 LOG_GENERIC(Log::Class::Render_OpenGL, level, "%s %s %d: %s",
444 GetSource(source), GetType(type), id, message);
445}
446
408/// Initialize the renderer 447/// Initialize the renderer
409void RendererOpenGL::Init() { 448bool RendererOpenGL::Init() {
410 render_window->MakeCurrent(); 449 render_window->MakeCurrent();
411 450
412 // TODO: Make frontends initialize this, so they can use gladLoadGLLoader with their own loaders 451 // TODO: Make frontends initialize this, so they can use gladLoadGLLoader with their own loaders
@@ -415,10 +454,23 @@ void RendererOpenGL::Init() {
415 exit(-1); 454 exit(-1);
416 } 455 }
417 456
457 if (GLAD_GL_KHR_debug) {
458 glEnable(GL_DEBUG_OUTPUT);
459 glDebugMessageCallback(DebugHandler, nullptr);
460 }
461
418 LOG_INFO(Render_OpenGL, "GL_VERSION: %s", glGetString(GL_VERSION)); 462 LOG_INFO(Render_OpenGL, "GL_VERSION: %s", glGetString(GL_VERSION));
419 LOG_INFO(Render_OpenGL, "GL_VENDOR: %s", glGetString(GL_VENDOR)); 463 LOG_INFO(Render_OpenGL, "GL_VENDOR: %s", glGetString(GL_VENDOR));
420 LOG_INFO(Render_OpenGL, "GL_RENDERER: %s", glGetString(GL_RENDERER)); 464 LOG_INFO(Render_OpenGL, "GL_RENDERER: %s", glGetString(GL_RENDERER));
465 if (!GLAD_GL_VERSION_3_3) {
466 return false;
467 }
468
421 InitOpenGLObjects(); 469 InitOpenGLObjects();
470
471 RefreshRasterizerSetting();
472
473 return true;
422} 474}
423 475
424/// Shutdown the renderer 476/// Shutdown the renderer
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h
index b42df7654..fe4d142a5 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.h
+++ b/src/video_core/renderer_opengl/renderer_opengl.h
@@ -31,7 +31,7 @@ public:
31 void SetWindow(EmuWindow* window) override; 31 void SetWindow(EmuWindow* window) override;
32 32
33 /// Initialize the renderer 33 /// Initialize the renderer
34 void Init() override; 34 bool Init() override;
35 35
36 /// Shutdown the renderer 36 /// Shutdown the renderer
37 void ShutDown() override; 37 void ShutDown() override;
diff --git a/src/video_core/shader/shader.cpp b/src/video_core/shader/shader.cpp
index 59f54236b..5e8930476 100644
--- a/src/video_core/shader/shader.cpp
+++ b/src/video_core/shader/shader.cpp
@@ -14,6 +14,7 @@
14 14
15#include "video_core/debug_utils/debug_utils.h" 15#include "video_core/debug_utils/debug_utils.h"
16#include "video_core/pica.h" 16#include "video_core/pica.h"
17#include "video_core/pica_state.h"
17#include "video_core/video_core.h" 18#include "video_core/video_core.h"
18 19
19#include "shader.h" 20#include "shader.h"
@@ -134,16 +135,18 @@ OutputVertex Run(UnitState<false>& state, const InputVertex& input, int num_attr
134 std::fmin(std::fabs(ret.color[i].ToFloat32()), 1.0f)); 135 std::fmin(std::fabs(ret.color[i].ToFloat32()), 1.0f));
135 } 136 }
136 137
137 LOG_TRACE(Render_Software, "Output vertex: pos (%.2f, %.2f, %.2f, %.2f), quat (%.2f, %.2f, %.2f, %.2f), col(%.2f, %.2f, %.2f, %.2f), tc0(%.2f, %.2f)", 138 LOG_TRACE(Render_Software, "Output vertex: pos(%.2f, %.2f, %.2f, %.2f), quat(%.2f, %.2f, %.2f, %.2f), "
139 "col(%.2f, %.2f, %.2f, %.2f), tc0(%.2f, %.2f), view(%.2f, %.2f, %.2f)",
138 ret.pos.x.ToFloat32(), ret.pos.y.ToFloat32(), ret.pos.z.ToFloat32(), ret.pos.w.ToFloat32(), 140 ret.pos.x.ToFloat32(), ret.pos.y.ToFloat32(), ret.pos.z.ToFloat32(), ret.pos.w.ToFloat32(),
139 ret.quat.x.ToFloat32(), ret.quat.y.ToFloat32(), ret.quat.z.ToFloat32(), ret.quat.w.ToFloat32(), 141 ret.quat.x.ToFloat32(), ret.quat.y.ToFloat32(), ret.quat.z.ToFloat32(), ret.quat.w.ToFloat32(),
140 ret.color.x.ToFloat32(), ret.color.y.ToFloat32(), ret.color.z.ToFloat32(), ret.color.w.ToFloat32(), 142 ret.color.x.ToFloat32(), ret.color.y.ToFloat32(), ret.color.z.ToFloat32(), ret.color.w.ToFloat32(),
141 ret.tc0.u().ToFloat32(), ret.tc0.v().ToFloat32()); 143 ret.tc0.u().ToFloat32(), ret.tc0.v().ToFloat32(),
144 ret.view.x.ToFloat32(), ret.view.y.ToFloat32(), ret.view.z.ToFloat32());
142 145
143 return ret; 146 return ret;
144} 147}
145 148
146DebugData<true> ProduceDebugInfo(const InputVertex& input, int num_attributes, const Regs::ShaderConfig& config, const State::ShaderSetup& setup) { 149DebugData<true> ProduceDebugInfo(const InputVertex& input, int num_attributes, const Regs::ShaderConfig& config, const ShaderSetup& setup) {
147 UnitState<true> state; 150 UnitState<true> state;
148 151
149 state.program_counter = config.main_offset; 152 state.program_counter = config.main_offset;
diff --git a/src/video_core/shader/shader.h b/src/video_core/shader/shader.h
index 1c6fa592c..7af8f1fa1 100644
--- a/src/video_core/shader/shader.h
+++ b/src/video_core/shader/shader.h
@@ -37,17 +37,19 @@ struct OutputVertex {
37 Math::Vec4<float24> color; 37 Math::Vec4<float24> color;
38 Math::Vec2<float24> tc0; 38 Math::Vec2<float24> tc0;
39 Math::Vec2<float24> tc1; 39 Math::Vec2<float24> tc1;
40 float24 pad[6]; 40 INSERT_PADDING_WORDS(2);
41 Math::Vec3<float24> view;
42 INSERT_PADDING_WORDS(1);
41 Math::Vec2<float24> tc2; 43 Math::Vec2<float24> tc2;
42 44
43 // Padding for optimal alignment 45 // Padding for optimal alignment
44 float24 pad2[4]; 46 INSERT_PADDING_WORDS(4);
45 47
46 // Attributes used to store intermediate results 48 // Attributes used to store intermediate results
47 49
48 // position after perspective divide 50 // position after perspective divide
49 Math::Vec3<float24> screenpos; 51 Math::Vec3<float24> screenpos;
50 float24 pad3; 52 INSERT_PADDING_WORDS(1);
51 53
52 // Linear interpolation 54 // Linear interpolation
53 // factor: 0=this, 1=vtx 55 // factor: 0=this, 1=vtx
@@ -75,6 +77,22 @@ struct OutputVertex {
75static_assert(std::is_pod<OutputVertex>::value, "Structure is not POD"); 77static_assert(std::is_pod<OutputVertex>::value, "Structure is not POD");
76static_assert(sizeof(OutputVertex) == 32 * sizeof(float), "OutputVertex has invalid size"); 78static_assert(sizeof(OutputVertex) == 32 * sizeof(float), "OutputVertex has invalid size");
77 79
80/// Vertex shader memory
81struct ShaderSetup {
82 struct {
83 // The float uniforms are accessed by the shader JIT using SSE instructions, and are
84 // therefore required to be 16-byte aligned.
85 alignas(16) Math::Vec4<float24> f[96];
86
87 std::array<bool, 16> b;
88 std::array<Math::Vec4<u8>, 4> i;
89 } uniforms;
90
91 Math::Vec4<float24> default_attributes[16];
92
93 std::array<u32, 1024> program_code;
94 std::array<u32, 1024> swizzle_data;
95};
78 96
79// Helper structure used to keep track of data useful for inspection of shader emulation 97// Helper structure used to keep track of data useful for inspection of shader emulation
80template<bool full_debugging> 98template<bool full_debugging>
@@ -258,9 +276,9 @@ struct UnitState {
258 struct Registers { 276 struct Registers {
259 // The registers are accessed by the shader JIT using SSE instructions, and are therefore 277 // The registers are accessed by the shader JIT using SSE instructions, and are therefore
260 // required to be 16-byte aligned. 278 // required to be 16-byte aligned.
261 Math::Vec4<float24> MEMORY_ALIGNED16(input[16]); 279 alignas(16) Math::Vec4<float24> input[16];
262 Math::Vec4<float24> MEMORY_ALIGNED16(output[16]); 280 alignas(16) Math::Vec4<float24> output[16];
263 Math::Vec4<float24> MEMORY_ALIGNED16(temporary[16]); 281 alignas(16) Math::Vec4<float24> temporary[16];
264 } registers; 282 } registers;
265 static_assert(std::is_pod<Registers>::value, "Structure is not POD"); 283 static_assert(std::is_pod<Registers>::value, "Structure is not POD");
266 284
@@ -345,7 +363,7 @@ OutputVertex Run(UnitState<false>& state, const InputVertex& input, int num_attr
345 * @param setup Setup object for the shader pipeline 363 * @param setup Setup object for the shader pipeline
346 * @return Debug information for this shader with regards to the given vertex 364 * @return Debug information for this shader with regards to the given vertex
347 */ 365 */
348DebugData<true> ProduceDebugInfo(const InputVertex& input, int num_attributes, const Regs::ShaderConfig& config, const State::ShaderSetup& setup); 366DebugData<true> ProduceDebugInfo(const InputVertex& input, int num_attributes, const Regs::ShaderConfig& config, const ShaderSetup& setup);
349 367
350} // namespace Shader 368} // namespace Shader
351 369
diff --git a/src/video_core/shader/shader_interpreter.cpp b/src/video_core/shader/shader_interpreter.cpp
index 7b0c20b74..79fcc56b9 100644
--- a/src/video_core/shader/shader_interpreter.cpp
+++ b/src/video_core/shader/shader_interpreter.cpp
@@ -7,6 +7,7 @@
7#include <nihstro/shader_bytecode.h> 7#include <nihstro/shader_bytecode.h>
8 8
9#include "video_core/pica.h" 9#include "video_core/pica.h"
10#include "video_core/pica_state.h"
10#include "video_core/shader/shader.h" 11#include "video_core/shader/shader.h"
11#include "video_core/shader/shader_interpreter.h" 12#include "video_core/shader/shader_interpreter.h"
12 13
@@ -515,7 +516,8 @@ void RunInterpreter(UnitState<Debug>& state) {
515 516
516 case OpCode::Id::JMPU: 517 case OpCode::Id::JMPU:
517 Record<DebugDataRecord::COND_BOOL_IN>(state.debug, iteration, uniforms.b[instr.flow_control.bool_uniform_id]); 518 Record<DebugDataRecord::COND_BOOL_IN>(state.debug, iteration, uniforms.b[instr.flow_control.bool_uniform_id]);
518 if (uniforms.b[instr.flow_control.bool_uniform_id]) { 519
520 if (uniforms.b[instr.flow_control.bool_uniform_id] == !(instr.flow_control.num_instructions & 1)) {
519 state.program_counter = instr.flow_control.dest_offset - 1; 521 state.program_counter = instr.flow_control.dest_offset - 1;
520 } 522 }
521 break; 523 break;
diff --git a/src/video_core/shader/shader_jit_x64.cpp b/src/video_core/shader/shader_jit_x64.cpp
index 00415e402..5083d7e54 100644
--- a/src/video_core/shader/shader_jit_x64.cpp
+++ b/src/video_core/shader/shader_jit_x64.cpp
@@ -11,6 +11,8 @@
11#include "shader.h" 11#include "shader.h"
12#include "shader_jit_x64.h" 12#include "shader_jit_x64.h"
13 13
14#include "video_core/pica_state.h"
15
14namespace Pica { 16namespace Pica {
15 17
16namespace Shader { 18namespace Shader {
@@ -653,7 +655,7 @@ void JitCompiler::Compile_IF(Instruction instr) {
653 FixupBranch b = J_CC(CC_Z, true); 655 FixupBranch b = J_CC(CC_Z, true);
654 656
655 // Compile the code that corresponds to the condition evaluating as true 657 // Compile the code that corresponds to the condition evaluating as true
656 Compile_Block(instr.flow_control.dest_offset - 1); 658 Compile_Block(instr.flow_control.dest_offset);
657 659
658 // If there isn't an "ELSE" condition, we are done here 660 // If there isn't an "ELSE" condition, we are done here
659 if (instr.flow_control.num_instructions == 0) { 661 if (instr.flow_control.num_instructions == 0) {
@@ -667,7 +669,7 @@ void JitCompiler::Compile_IF(Instruction instr) {
667 669
668 // This code corresponds to the "ELSE" condition 670 // This code corresponds to the "ELSE" condition
669 // Comple the code that corresponds to the condition evaluating as false 671 // Comple the code that corresponds to the condition evaluating as false
670 Compile_Block(instr.flow_control.dest_offset + instr.flow_control.num_instructions - 1); 672 Compile_Block(instr.flow_control.dest_offset + instr.flow_control.num_instructions);
671 673
672 SetJumpTarget(b2); 674 SetJumpTarget(b2);
673} 675}
@@ -691,7 +693,7 @@ void JitCompiler::Compile_LOOP(Instruction instr) {
691 693
692 auto loop_start = GetCodePtr(); 694 auto loop_start = GetCodePtr();
693 695
694 Compile_Block(instr.flow_control.dest_offset); 696 Compile_Block(instr.flow_control.dest_offset + 1);
695 697
696 ADD(32, R(LOOPCOUNT_REG), R(LOOPINC)); // Increment LOOPCOUNT_REG by Z-component 698 ADD(32, R(LOOPCOUNT_REG), R(LOOPINC)); // Increment LOOPCOUNT_REG by Z-component
697 SUB(32, R(LOOPCOUNT), Imm8(1)); // Increment loop count by 1 699 SUB(32, R(LOOPCOUNT), Imm8(1)); // Increment loop count by 1
@@ -710,19 +712,21 @@ void JitCompiler::Compile_JMP(Instruction instr) {
710 else 712 else
711 UNREACHABLE(); 713 UNREACHABLE();
712 714
713 FixupBranch b = J_CC(CC_NZ, true); 715 bool inverted_condition = (instr.opcode.Value() == OpCode::Id::JMPU) &&
716 (instr.flow_control.num_instructions & 1);
717 FixupBranch b = J_CC(inverted_condition ? CC_Z : CC_NZ, true);
714 718
715 Compile_Block(instr.flow_control.dest_offset); 719 Compile_Block(instr.flow_control.dest_offset);
716 720
717 SetJumpTarget(b); 721 SetJumpTarget(b);
718} 722}
719 723
720void JitCompiler::Compile_Block(unsigned stop) { 724void JitCompiler::Compile_Block(unsigned end) {
721 // Save current offset pointer 725 // Save current offset pointer
722 unsigned* prev_offset_ptr = offset_ptr; 726 unsigned* prev_offset_ptr = offset_ptr;
723 unsigned offset = *prev_offset_ptr; 727 unsigned offset = *prev_offset_ptr;
724 728
725 while (offset <= stop) 729 while (offset < end)
726 Compile_NextInstr(&offset); 730 Compile_NextInstr(&offset);
727 731
728 // Restore current offset pointer 732 // Restore current offset pointer
diff --git a/src/video_core/shader/shader_jit_x64.h b/src/video_core/shader/shader_jit_x64.h
index 3afbceccf..5ad2d9606 100644
--- a/src/video_core/shader/shader_jit_x64.h
+++ b/src/video_core/shader/shader_jit_x64.h
@@ -61,7 +61,7 @@ public:
61 void Compile_MAD(Instruction instr); 61 void Compile_MAD(Instruction instr);
62 62
63private: 63private:
64 void Compile_Block(unsigned stop); 64 void Compile_Block(unsigned end);
65 void Compile_NextInstr(unsigned* offset); 65 void Compile_NextInstr(unsigned* offset);
66 66
67 void Compile_SwizzleSrc(Instruction instr, unsigned src_num, SourceRegister src_reg, Gen::X64Reg dest); 67 void Compile_SwizzleSrc(Instruction instr, unsigned src_num, SourceRegister src_reg, Gen::X64Reg dest);
diff --git a/src/video_core/swrasterizer.cpp b/src/video_core/swrasterizer.cpp
new file mode 100644
index 000000000..03df15b01
--- /dev/null
+++ b/src/video_core/swrasterizer.cpp
@@ -0,0 +1,16 @@
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 "video_core/clipper.h"
6#include "video_core/swrasterizer.h"
7
8namespace VideoCore {
9
10void SWRasterizer::AddTriangle(const Pica::Shader::OutputVertex& v0,
11 const Pica::Shader::OutputVertex& v1,
12 const Pica::Shader::OutputVertex& v2) {
13 Pica::Clipper::ProcessTriangle(v0, v1, v2);
14}
15
16}
diff --git a/src/video_core/swrasterizer.h b/src/video_core/swrasterizer.h
new file mode 100644
index 000000000..9a9a76d7a
--- /dev/null
+++ b/src/video_core/swrasterizer.h
@@ -0,0 +1,26 @@
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 "common/common_types.h"
8
9#include "video_core/rasterizer_interface.h"
10
11namespace VideoCore {
12
13class SWRasterizer : public RasterizerInterface {
14 void InitObjects() override {}
15 void Reset() override {}
16 void AddTriangle(const Pica::Shader::OutputVertex& v0,
17 const Pica::Shader::OutputVertex& v1,
18 const Pica::Shader::OutputVertex& v2) override;
19 void DrawTriangles() override {}
20 void FlushFramebuffer() override {}
21 void NotifyPicaRegisterChanged(u32 id) override {}
22 void FlushRegion(PAddr addr, u32 size) override {}
23 void InvalidateRegion(PAddr addr, u32 size) override {}
24};
25
26}
diff --git a/src/video_core/video_core.cpp b/src/video_core/video_core.cpp
index eaddda668..ee5e50df1 100644
--- a/src/video_core/video_core.cpp
+++ b/src/video_core/video_core.cpp
@@ -2,7 +2,10 @@
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 <memory>
6
5#include "common/emu_window.h" 7#include "common/emu_window.h"
8#include "common/make_unique.h"
6#include "common/logging/log.h" 9#include "common/logging/log.h"
7 10
8#include "core/core.h" 11#include "core/core.h"
@@ -18,29 +21,33 @@
18 21
19namespace VideoCore { 22namespace VideoCore {
20 23
21EmuWindow* g_emu_window = nullptr; ///< Frontend emulator window 24EmuWindow* g_emu_window = nullptr; ///< Frontend emulator window
22RendererBase* g_renderer = nullptr; ///< Renderer plugin 25std::unique_ptr<RendererBase> g_renderer; ///< Renderer plugin
23 26
24std::atomic<bool> g_hw_renderer_enabled; 27std::atomic<bool> g_hw_renderer_enabled;
25std::atomic<bool> g_shader_jit_enabled; 28std::atomic<bool> g_shader_jit_enabled;
26 29
27/// Initialize the video core 30/// Initialize the video core
28void Init(EmuWindow* emu_window) { 31bool Init(EmuWindow* emu_window) {
29 Pica::Init(); 32 Pica::Init();
30 33
31 g_emu_window = emu_window; 34 g_emu_window = emu_window;
32 g_renderer = new RendererOpenGL(); 35 g_renderer = Common::make_unique<RendererOpenGL>();
33 g_renderer->SetWindow(g_emu_window); 36 g_renderer->SetWindow(g_emu_window);
34 g_renderer->Init(); 37 if (g_renderer->Init()) {
35 38 LOG_DEBUG(Render, "initialized OK");
36 LOG_DEBUG(Render, "initialized OK"); 39 } else {
40 LOG_ERROR(Render, "initialization failed !");
41 return false;
42 }
43 return true;
37} 44}
38 45
39/// Shutdown the video core 46/// Shutdown the video core
40void Shutdown() { 47void Shutdown() {
41 Pica::Shutdown(); 48 Pica::Shutdown();
42 49
43 delete g_renderer; 50 g_renderer.reset();
44 51
45 LOG_DEBUG(Render, "shutdown OK"); 52 LOG_DEBUG(Render, "shutdown OK");
46} 53}
diff --git a/src/video_core/video_core.h b/src/video_core/video_core.h
index 2867bf03e..bca67fb8c 100644
--- a/src/video_core/video_core.h
+++ b/src/video_core/video_core.h
@@ -5,6 +5,7 @@
5#pragma once 5#pragma once
6 6
7#include <atomic> 7#include <atomic>
8#include <memory>
8 9
9class EmuWindow; 10class EmuWindow;
10class RendererBase; 11class RendererBase;
@@ -29,8 +30,8 @@ static const int kScreenBottomHeight = 240; ///< 3DS bottom screen height
29// Video core renderer 30// Video core renderer
30// --------------------- 31// ---------------------
31 32
32extern RendererBase* g_renderer; ///< Renderer plugin 33extern std::unique_ptr<RendererBase> g_renderer; ///< Renderer plugin
33extern EmuWindow* g_emu_window; ///< Emu window 34extern EmuWindow* g_emu_window; ///< Emu window
34 35
35// TODO: Wrap these in a user settings struct along with any other graphics settings (often set from qt ui) 36// TODO: Wrap these in a user settings struct along with any other graphics settings (often set from qt ui)
36extern std::atomic<bool> g_hw_renderer_enabled; 37extern std::atomic<bool> g_hw_renderer_enabled;
@@ -40,7 +41,7 @@ extern std::atomic<bool> g_shader_jit_enabled;
40void Start(); 41void Start();
41 42
42/// Initialize the video core 43/// Initialize the video core
43void Init(EmuWindow* emu_window); 44bool Init(EmuWindow* emu_window);
44 45
45/// Shutdown the video core 46/// Shutdown the video core
46void Shutdown(); 47void Shutdown();