mirror of
https://github.com/libretro/ppsspp.git
synced 2025-02-24 19:00:54 +00:00
Merge pull request #7946 from unknownbrackets/native-merge
Merge native directly into PPSSPP
This commit is contained in:
commit
cf0697ec09
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -1,6 +1,3 @@
|
||||
[submodule "native"]
|
||||
path = native
|
||||
url = https://github.com/hrydgard/native.git
|
||||
[submodule "pspautotests"]
|
||||
path = pspautotests
|
||||
url = https://github.com/hrydgard/pspautotests.git
|
||||
|
540
CMakeLists.txt
540
CMakeLists.txt
@ -126,7 +126,7 @@ else()
|
||||
set(CoreLinkType STATIC)
|
||||
endif()
|
||||
|
||||
include_directories(native)
|
||||
include_directories(ext/native)
|
||||
|
||||
if(RPI)
|
||||
include_directories(/opt/vc/include /opt/vc/include/interface/vcos/pthreads)
|
||||
@ -389,12 +389,12 @@ if(NOT USING_GLES2)
|
||||
|
||||
add_definitions(-DGLEW_STATIC)
|
||||
add_library(glew STATIC
|
||||
native/ext/glew/GL/glew.h
|
||||
native/ext/glew/GL/glxew.h
|
||||
native/ext/glew/GL/wglew.h
|
||||
native/ext/glew/glew.c)
|
||||
ext/native/ext/glew/GL/glew.h
|
||||
ext/native/ext/glew/GL/glxew.h
|
||||
ext/native/ext/glew/GL/wglew.h
|
||||
ext/native/ext/glew/glew.c)
|
||||
target_link_libraries(glew ${OPENGL_LIBRARIES})
|
||||
include_directories(native/ext/glew)
|
||||
include_directories(ext/native/ext/glew)
|
||||
set(GLEW_LIBRARIES glew)
|
||||
endif()
|
||||
|
||||
@ -402,21 +402,21 @@ add_subdirectory(ext/snappy)
|
||||
add_subdirectory(ext/udis86)
|
||||
|
||||
add_library(vjson STATIC
|
||||
native/ext/vjson/json.cpp
|
||||
native/ext/vjson/json.h
|
||||
native/ext/vjson/block_allocator.cpp
|
||||
native/ext/vjson/block_allocator.h
|
||||
ext/native/ext/vjson/json.cpp
|
||||
ext/native/ext/vjson/json.h
|
||||
ext/native/ext/vjson/block_allocator.cpp
|
||||
ext/native/ext/vjson/block_allocator.h
|
||||
)
|
||||
|
||||
add_library(rg_etc1 STATIC
|
||||
native/ext/rg_etc1/rg_etc1.cpp
|
||||
native/ext/rg_etc1/rg_etc1.h)
|
||||
include_directories(native/ext/rg_etc1)
|
||||
ext/native/ext/rg_etc1/rg_etc1.cpp
|
||||
ext/native/ext/rg_etc1/rg_etc1.h)
|
||||
include_directories(ext/native/ext/rg_etc1)
|
||||
|
||||
add_library(stb_vorbis STATIC
|
||||
native/ext/stb_vorbis/stb_vorbis.c
|
||||
native/ext/stb_vorbis/stb_vorbis.h)
|
||||
include_directories(native/ext/stb_vorbis)
|
||||
ext/native/ext/stb_vorbis/stb_vorbis.c
|
||||
ext/native/ext/stb_vorbis/stb_vorbis.h)
|
||||
include_directories(ext/native/ext/stb_vorbis)
|
||||
|
||||
if(USE_FFMPEG)
|
||||
if(USE_SYSTEM_FFMPEG)
|
||||
@ -610,9 +610,9 @@ else()
|
||||
endif()
|
||||
|
||||
add_library(cityhash STATIC
|
||||
native/ext/cityhash/city.cpp
|
||||
native/ext/cityhash/city.h
|
||||
native/ext/cityhash/citycrc.h
|
||||
ext/native/ext/cityhash/city.cpp
|
||||
ext/native/ext/cityhash/city.h
|
||||
ext/native/ext/cityhash/citycrc.h
|
||||
)
|
||||
include_directories(ext/cityhash)
|
||||
|
||||
@ -628,63 +628,63 @@ endif()
|
||||
|
||||
|
||||
add_library(libzip STATIC
|
||||
native/ext/libzip/zip.h
|
||||
native/ext/libzip/mkstemp.c
|
||||
native/ext/libzip/zip_add.c
|
||||
native/ext/libzip/zip_add_dir.c
|
||||
native/ext/libzip/zip_close.c
|
||||
native/ext/libzip/zip_delete.c
|
||||
native/ext/libzip/zip_dirent.c
|
||||
native/ext/libzip/zip_entry_free.c
|
||||
native/ext/libzip/zip_entry_new.c
|
||||
native/ext/libzip/zip_err_str.c
|
||||
native/ext/libzip/zip_error.c
|
||||
native/ext/libzip/zip_error_clear.c
|
||||
native/ext/libzip/zip_error_get.c
|
||||
native/ext/libzip/zip_error_get_sys_type.c
|
||||
native/ext/libzip/zip_error_strerror.c
|
||||
native/ext/libzip/zip_error_to_str.c
|
||||
native/ext/libzip/zip_fclose.c
|
||||
native/ext/libzip/zip_file_error_clear.c
|
||||
native/ext/libzip/zip_file_error_get.c
|
||||
native/ext/libzip/zip_file_get_offset.c
|
||||
native/ext/libzip/zip_file_strerror.c
|
||||
native/ext/libzip/zip_filerange_crc.c
|
||||
native/ext/libzip/zip_fopen.c
|
||||
native/ext/libzip/zip_fopen_index.c
|
||||
native/ext/libzip/zip_fread.c
|
||||
native/ext/libzip/zip_free.c
|
||||
native/ext/libzip/zip_get_archive_comment.c
|
||||
native/ext/libzip/zip_get_archive_flag.c
|
||||
native/ext/libzip/zip_get_file_comment.c
|
||||
native/ext/libzip/zip_get_name.c
|
||||
native/ext/libzip/zip_get_num_files.c
|
||||
native/ext/libzip/zip_memdup.c
|
||||
native/ext/libzip/zip_name_locate.c
|
||||
native/ext/libzip/zip_new.c
|
||||
native/ext/libzip/zip_open.c
|
||||
native/ext/libzip/zip_rename.c
|
||||
native/ext/libzip/zip_replace.c
|
||||
native/ext/libzip/zip_set_archive_comment.c
|
||||
native/ext/libzip/zip_set_archive_flag.c
|
||||
native/ext/libzip/zip_set_file_comment.c
|
||||
native/ext/libzip/zip_set_name.c
|
||||
native/ext/libzip/zip_source_buffer.c
|
||||
native/ext/libzip/zip_source_file.c
|
||||
native/ext/libzip/zip_source_filep.c
|
||||
native/ext/libzip/zip_source_free.c
|
||||
native/ext/libzip/zip_source_function.c
|
||||
native/ext/libzip/zip_source_zip.c
|
||||
native/ext/libzip/zip_stat.c
|
||||
native/ext/libzip/zip_stat_index.c
|
||||
native/ext/libzip/zip_stat_init.c
|
||||
native/ext/libzip/zip_strerror.c
|
||||
native/ext/libzip/zip_unchange.c
|
||||
native/ext/libzip/zip_unchange_all.c
|
||||
native/ext/libzip/zip_unchange_archive.c
|
||||
native/ext/libzip/zip_unchange_data.c)
|
||||
ext/native/ext/libzip/zip.h
|
||||
ext/native/ext/libzip/mkstemp.c
|
||||
ext/native/ext/libzip/zip_add.c
|
||||
ext/native/ext/libzip/zip_add_dir.c
|
||||
ext/native/ext/libzip/zip_close.c
|
||||
ext/native/ext/libzip/zip_delete.c
|
||||
ext/native/ext/libzip/zip_dirent.c
|
||||
ext/native/ext/libzip/zip_entry_free.c
|
||||
ext/native/ext/libzip/zip_entry_new.c
|
||||
ext/native/ext/libzip/zip_err_str.c
|
||||
ext/native/ext/libzip/zip_error.c
|
||||
ext/native/ext/libzip/zip_error_clear.c
|
||||
ext/native/ext/libzip/zip_error_get.c
|
||||
ext/native/ext/libzip/zip_error_get_sys_type.c
|
||||
ext/native/ext/libzip/zip_error_strerror.c
|
||||
ext/native/ext/libzip/zip_error_to_str.c
|
||||
ext/native/ext/libzip/zip_fclose.c
|
||||
ext/native/ext/libzip/zip_file_error_clear.c
|
||||
ext/native/ext/libzip/zip_file_error_get.c
|
||||
ext/native/ext/libzip/zip_file_get_offset.c
|
||||
ext/native/ext/libzip/zip_file_strerror.c
|
||||
ext/native/ext/libzip/zip_filerange_crc.c
|
||||
ext/native/ext/libzip/zip_fopen.c
|
||||
ext/native/ext/libzip/zip_fopen_index.c
|
||||
ext/native/ext/libzip/zip_fread.c
|
||||
ext/native/ext/libzip/zip_free.c
|
||||
ext/native/ext/libzip/zip_get_archive_comment.c
|
||||
ext/native/ext/libzip/zip_get_archive_flag.c
|
||||
ext/native/ext/libzip/zip_get_file_comment.c
|
||||
ext/native/ext/libzip/zip_get_name.c
|
||||
ext/native/ext/libzip/zip_get_num_files.c
|
||||
ext/native/ext/libzip/zip_memdup.c
|
||||
ext/native/ext/libzip/zip_name_locate.c
|
||||
ext/native/ext/libzip/zip_new.c
|
||||
ext/native/ext/libzip/zip_open.c
|
||||
ext/native/ext/libzip/zip_rename.c
|
||||
ext/native/ext/libzip/zip_replace.c
|
||||
ext/native/ext/libzip/zip_set_archive_comment.c
|
||||
ext/native/ext/libzip/zip_set_archive_flag.c
|
||||
ext/native/ext/libzip/zip_set_file_comment.c
|
||||
ext/native/ext/libzip/zip_set_name.c
|
||||
ext/native/ext/libzip/zip_source_buffer.c
|
||||
ext/native/ext/libzip/zip_source_file.c
|
||||
ext/native/ext/libzip/zip_source_filep.c
|
||||
ext/native/ext/libzip/zip_source_free.c
|
||||
ext/native/ext/libzip/zip_source_function.c
|
||||
ext/native/ext/libzip/zip_source_zip.c
|
||||
ext/native/ext/libzip/zip_stat.c
|
||||
ext/native/ext/libzip/zip_stat_index.c
|
||||
ext/native/ext/libzip/zip_stat_init.c
|
||||
ext/native/ext/libzip/zip_strerror.c
|
||||
ext/native/ext/libzip/zip_unchange.c
|
||||
ext/native/ext/libzip/zip_unchange_all.c
|
||||
ext/native/ext/libzip/zip_unchange_archive.c
|
||||
ext/native/ext/libzip/zip_unchange_data.c)
|
||||
target_link_libraries(libzip ${ZLIB_LIBRARY})
|
||||
include_directories(native/ext/libzip)
|
||||
include_directories(ext/native/ext/libzip)
|
||||
set(LIBZIP_LIBRARY libzip)
|
||||
|
||||
# FindPNG does a few things we don't want. So do it ourselves. Fixed to libpng17
|
||||
@ -696,35 +696,35 @@ if (PNG_FOUND)
|
||||
include_directories(${PNG_PNG_INCLUDE_DIR})
|
||||
else()
|
||||
if(ARM)
|
||||
file(GLOB PNG_ARM_INCLUDES native/ext/libpng17/arm/*)
|
||||
file(GLOB PNG_ARM_INCLUDES ext/native/ext/libpng17/arm/*)
|
||||
endif()
|
||||
add_library(png17 STATIC
|
||||
native/ext/libpng17/pngconf.h
|
||||
native/ext/libpng17/pngdebug.h
|
||||
native/ext/libpng17/png.c
|
||||
native/ext/libpng17/png.h
|
||||
native/ext/libpng17/pngerror.c
|
||||
native/ext/libpng17/pngget.c
|
||||
native/ext/libpng17/pnginfo.h
|
||||
native/ext/libpng17/pnglibconf.h
|
||||
native/ext/libpng17/pngmem.c
|
||||
native/ext/libpng17/pngpread.c
|
||||
native/ext/libpng17/pngpriv.h
|
||||
native/ext/libpng17/pngread.c
|
||||
native/ext/libpng17/pngrio.c
|
||||
native/ext/libpng17/pngrtran.c
|
||||
native/ext/libpng17/pngrutil.c
|
||||
native/ext/libpng17/pngset.c
|
||||
native/ext/libpng17/pngstruct.h
|
||||
native/ext/libpng17/pngtest.c
|
||||
native/ext/libpng17/pngtrans.c
|
||||
native/ext/libpng17/pngwio.c
|
||||
native/ext/libpng17/pngwrite.c
|
||||
native/ext/libpng17/pngwtran.c
|
||||
native/ext/libpng17/pngwutil.c
|
||||
ext/native/ext/libpng17/pngconf.h
|
||||
ext/native/ext/libpng17/pngdebug.h
|
||||
ext/native/ext/libpng17/png.c
|
||||
ext/native/ext/libpng17/png.h
|
||||
ext/native/ext/libpng17/pngerror.c
|
||||
ext/native/ext/libpng17/pngget.c
|
||||
ext/native/ext/libpng17/pnginfo.h
|
||||
ext/native/ext/libpng17/pnglibconf.h
|
||||
ext/native/ext/libpng17/pngmem.c
|
||||
ext/native/ext/libpng17/pngpread.c
|
||||
ext/native/ext/libpng17/pngpriv.h
|
||||
ext/native/ext/libpng17/pngread.c
|
||||
ext/native/ext/libpng17/pngrio.c
|
||||
ext/native/ext/libpng17/pngrtran.c
|
||||
ext/native/ext/libpng17/pngrutil.c
|
||||
ext/native/ext/libpng17/pngset.c
|
||||
ext/native/ext/libpng17/pngstruct.h
|
||||
ext/native/ext/libpng17/pngtest.c
|
||||
ext/native/ext/libpng17/pngtrans.c
|
||||
ext/native/ext/libpng17/pngwio.c
|
||||
ext/native/ext/libpng17/pngwrite.c
|
||||
ext/native/ext/libpng17/pngwtran.c
|
||||
ext/native/ext/libpng17/pngwutil.c
|
||||
${PNG_ARM_INCLUDES} )
|
||||
set(PNG_LIBRARY png17)
|
||||
include_directories(native/ext)
|
||||
include_directories(ext/native/ext)
|
||||
endif()
|
||||
|
||||
set(nativeExtra)
|
||||
@ -739,24 +739,24 @@ if(ARMV7)
|
||||
set (CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -march=armv7-a -mfpu=neon -mcpu=cortex-a9")
|
||||
endif()
|
||||
set(nativeExtra ${nativeExtra}
|
||||
native/math/fast/fast_matrix_neon.S)
|
||||
ext/native/math/fast/fast_matrix_neon.S)
|
||||
endif()
|
||||
if(X86 AND NOT MIPS)
|
||||
set(nativeExtra ${nativeExtra}
|
||||
native/math/fast/fast_matrix_sse.c)
|
||||
ext/native/math/fast/fast_matrix_sse.c)
|
||||
endif()
|
||||
|
||||
|
||||
if(ANDROID)
|
||||
set(nativeExtra ${nativeExtra}
|
||||
native/base/NativeApp.h
|
||||
native/android/app-android.cpp
|
||||
native/android/native_audio.cpp
|
||||
native/android/native_audio.h)
|
||||
ext/native/base/NativeApp.h
|
||||
ext/native/android/app-android.cpp
|
||||
ext/native/android/native_audio.cpp
|
||||
ext/native/android/native_audio.h)
|
||||
|
||||
add_library(native_audio SHARED
|
||||
native/android/native-audio-so.cpp
|
||||
native/android/native-audio-so.h)
|
||||
ext/native/android/native-audio-so.cpp
|
||||
ext/native/android/native-audio-so.h)
|
||||
target_link_libraries(native_audio OpenSLES log)
|
||||
# No target
|
||||
elseif(IOS)
|
||||
@ -785,8 +785,8 @@ elseif(USING_QT_UI)
|
||||
message(FATAL_ERROR "Cmake does not yet support Qt. Please use qmake instead.")
|
||||
find_package(Qt4 COMPONENTS QtMultimedia QtOpenGL QtGui QtCore)
|
||||
include(${QT_USE_FILE})
|
||||
qt4_wrap_cpp(nativeQtHeader native/base/QtMain.h)
|
||||
set(nativeExtra ${nativeExtra} native/base/QtMain.cpp ${nativeQtHeader})
|
||||
qt4_wrap_cpp(nativeQtHeader ext/native/base/QtMain.h)
|
||||
set(nativeExtra ${nativeExtra} ext/native/base/QtMain.cpp ${nativeQtHeader})
|
||||
if(NOT MOBILE_DEVICE)
|
||||
qt4_wrap_cpp(nativeQtHeader Qt/mainwindow.h)
|
||||
set(nativeExtra ${nativeExtra} Qt/mainwindow.cpp)
|
||||
@ -798,7 +798,7 @@ elseif(USING_QT_UI)
|
||||
endif()
|
||||
elseif(BLACKBERRY)
|
||||
unset(CMAKE_DL_LIBS)
|
||||
set(nativeExtra ${nativeExtra} native/base/BlackberryMain.cpp native/base/BlackberryDisplay.cpp)
|
||||
set(nativeExtra ${nativeExtra} ext/native/base/BlackberryMain.cpp ext/native/base/BlackberryDisplay.cpp)
|
||||
set(nativeExtraLibs ${nativeExtraLibs} OpenAL bps screen socket EGL)
|
||||
set(TargetBin PPSSPPBlackberry)
|
||||
elseif(SDL2_FOUND)
|
||||
@ -809,7 +809,7 @@ elseif(SDL2_FOUND)
|
||||
set(nativeExtra ${nativeExtra}
|
||||
SDL/SDLJoystick.h
|
||||
SDL/SDLJoystick.cpp
|
||||
native/base/PCMain.cpp)
|
||||
ext/native/base/PCMain.cpp)
|
||||
set(nativeExtraLibs ${nativeExtraLibs} ${SDL2_LIBRARY})
|
||||
if(APPLE)
|
||||
set(nativeExtra ${nativeExtra} SDL/SDLMain.h SDL/SDLMain.mm)
|
||||
@ -856,164 +856,164 @@ endif()
|
||||
|
||||
add_library(native STATIC
|
||||
${nativeExtra}
|
||||
native/base/backtrace.cpp
|
||||
native/base/backtrace.h
|
||||
native/audio/mixer.cpp
|
||||
native/audio/mixer.h
|
||||
native/audio/wav_read.cpp
|
||||
native/audio/wav_read.h
|
||||
native/base/basictypes.h
|
||||
native/base/buffer.cpp
|
||||
native/base/buffer.h
|
||||
native/base/color.h
|
||||
native/base/colorutil.cpp
|
||||
native/base/colorutil.h
|
||||
native/base/display.cpp
|
||||
native/base/display.h
|
||||
native/base/error_context.cpp
|
||||
native/base/error_context.h
|
||||
native/base/fastlist.h
|
||||
native/base/fastlist_test.cpp
|
||||
native/base/functional.h
|
||||
native/base/linked_ptr.h
|
||||
native/base/logging.h
|
||||
native/base/mutex.h
|
||||
native/base/scoped_ptr.h
|
||||
native/base/stats.h
|
||||
native/base/stringutil.cpp
|
||||
native/base/stringutil.h
|
||||
native/base/timeutil.cpp
|
||||
native/base/timeutil.h
|
||||
native/data/compression.cpp
|
||||
native/data/compression.h
|
||||
native/ext/vjson/json.cpp
|
||||
native/ext/vjson/json.h
|
||||
native/ext/vjson/block_allocator.cpp
|
||||
native/ext/vjson/block_allocator.h
|
||||
native/file/chunk_file.cpp
|
||||
native/file/chunk_file.h
|
||||
native/file/dialog.cpp
|
||||
native/file/dialog.h
|
||||
native/file/easy_file.cpp
|
||||
native/file/easy_file.h
|
||||
native/file/fd_util.cpp
|
||||
native/file/fd_util.h
|
||||
native/file/file_util.cpp
|
||||
native/file/file_util.h
|
||||
native/file/ini_file.cpp
|
||||
native/file/ini_file.h
|
||||
native/file/path.cpp
|
||||
native/file/path.h
|
||||
native/file/vfs.h
|
||||
native/file/zip_read.cpp
|
||||
native/file/zip_read.h
|
||||
native/gfx/gl_common.h
|
||||
native/gfx/gl_debug_log.cpp
|
||||
native/gfx/gl_debug_log.h
|
||||
native/gfx/gl_lost_manager.cpp
|
||||
native/gfx/gl_lost_manager.h
|
||||
native/gfx/texture.cpp
|
||||
native/gfx/texture.h
|
||||
native/gfx/texture_atlas.cpp
|
||||
native/gfx/texture_atlas.h
|
||||
# native/gfx/texture_dx11.cpp
|
||||
native/gfx/texture_gen.cpp
|
||||
native/gfx/texture_gen.h
|
||||
native/gfx_es2/draw_buffer.cpp
|
||||
native/gfx_es2/draw_buffer.h
|
||||
native/gfx_es2/draw_text.cpp
|
||||
native/gfx_es2/draw_text.h
|
||||
native/gfx_es2/gpu_features.cpp
|
||||
native/gfx_es2/gpu_features.h
|
||||
native/gfx_es2/glsl_program.cpp
|
||||
native/gfx_es2/glsl_program.h
|
||||
native/gfx_es2/vertex_format.cpp
|
||||
native/gfx_es2/vertex_format.h
|
||||
native/gfx_es2/gl3stub.c
|
||||
native/gfx_es2/gl3stub.h
|
||||
native/i18n/i18n.cpp
|
||||
native/i18n/i18n.h
|
||||
native/image/png_load.cpp
|
||||
native/image/png_load.h
|
||||
native/image/zim_load.cpp
|
||||
native/image/zim_load.h
|
||||
native/image/zim_save.cpp
|
||||
native/image/zim_save.h
|
||||
native/input/gesture_detector.cpp
|
||||
native/input/gesture_detector.h
|
||||
native/input/keycodes.h
|
||||
native/input/input_state.h
|
||||
native/input/input_state.cpp
|
||||
native/math/fast/fast_math.c
|
||||
native/math/fast/fast_matrix.c
|
||||
native/math/curves.cpp
|
||||
native/math/curves.h
|
||||
native/math/expression_parser.cpp
|
||||
native/math/expression_parser.h
|
||||
native/math/lin/aabb.cpp
|
||||
native/math/lin/aabb.h
|
||||
native/math/lin/matrix4x4.cpp
|
||||
native/math/lin/matrix4x4.h
|
||||
native/math/lin/plane.cpp
|
||||
native/math/lin/plane.h
|
||||
native/math/lin/quat.cpp
|
||||
native/math/lin/quat.h
|
||||
native/math/lin/ray.h
|
||||
native/math/lin/vec3.cpp
|
||||
native/math/lin/vec3.h
|
||||
native/math/math_util.cpp
|
||||
native/math/math_util.h
|
||||
native/net/http_client.cpp
|
||||
native/net/http_client.h
|
||||
native/net/resolve.cpp
|
||||
native/net/resolve.h
|
||||
native/net/url.cpp
|
||||
native/net/url.h
|
||||
native/profiler/profiler.cpp
|
||||
native/profiler/profiler.h
|
||||
native/thin3d/thin3d.cpp
|
||||
native/thin3d/thin3d.h
|
||||
native/thin3d/thin3d_gl.cpp
|
||||
native/thread/prioritizedworkqueue.cpp
|
||||
native/thread/prioritizedworkqueue.h
|
||||
native/thread/threadutil.cpp
|
||||
native/thread/threadutil.h
|
||||
native/thread/threadpool.cpp
|
||||
native/thread/threadpool.h
|
||||
native/ui/screen.cpp
|
||||
native/ui/screen.h
|
||||
native/ui/ui.cpp
|
||||
native/ui/ui.h
|
||||
native/ui/ui_context.cpp
|
||||
native/ui/ui_context.h
|
||||
native/ui/ui_screen.cpp
|
||||
native/ui/ui_screen.h
|
||||
native/ui/view.cpp
|
||||
native/ui/view.h
|
||||
native/ui/viewgroup.cpp
|
||||
native/ui/viewgroup.h
|
||||
native/ui/virtual_input.cpp
|
||||
native/ui/virtual_input.h
|
||||
native/util/bits/bits.cpp
|
||||
native/util/bits/bits.h
|
||||
native/util/bits/hamming.h
|
||||
native/util/bits/varint.cpp
|
||||
native/util/bits/varint.h
|
||||
native/util/hash/hash.cpp
|
||||
native/util/hash/hash.h
|
||||
native/util/random/perlin.cpp
|
||||
native/util/random/perlin.h
|
||||
native/util/random/rng.h
|
||||
native/util/text/utf8.h
|
||||
native/util/text/utf8.cpp
|
||||
native/util/text/parsers.h
|
||||
native/util/text/parsers.cpp
|
||||
native/util/const_map.h
|
||||
native/ext/jpge/jpgd.cpp
|
||||
native/ext/jpge/jpgd.h
|
||||
native/ext/jpge/jpge.cpp
|
||||
native/ext/jpge/jpge.h)
|
||||
include_directories(native)
|
||||
ext/native/base/backtrace.cpp
|
||||
ext/native/base/backtrace.h
|
||||
ext/native/audio/mixer.cpp
|
||||
ext/native/audio/mixer.h
|
||||
ext/native/audio/wav_read.cpp
|
||||
ext/native/audio/wav_read.h
|
||||
ext/native/base/basictypes.h
|
||||
ext/native/base/buffer.cpp
|
||||
ext/native/base/buffer.h
|
||||
ext/native/base/color.h
|
||||
ext/native/base/colorutil.cpp
|
||||
ext/native/base/colorutil.h
|
||||
ext/native/base/display.cpp
|
||||
ext/native/base/display.h
|
||||
ext/native/base/error_context.cpp
|
||||
ext/native/base/error_context.h
|
||||
ext/native/base/fastlist.h
|
||||
ext/native/base/fastlist_test.cpp
|
||||
ext/native/base/functional.h
|
||||
ext/native/base/linked_ptr.h
|
||||
ext/native/base/logging.h
|
||||
ext/native/base/mutex.h
|
||||
ext/native/base/scoped_ptr.h
|
||||
ext/native/base/stats.h
|
||||
ext/native/base/stringutil.cpp
|
||||
ext/native/base/stringutil.h
|
||||
ext/native/base/timeutil.cpp
|
||||
ext/native/base/timeutil.h
|
||||
ext/native/data/compression.cpp
|
||||
ext/native/data/compression.h
|
||||
ext/native/ext/vjson/json.cpp
|
||||
ext/native/ext/vjson/json.h
|
||||
ext/native/ext/vjson/block_allocator.cpp
|
||||
ext/native/ext/vjson/block_allocator.h
|
||||
ext/native/file/chunk_file.cpp
|
||||
ext/native/file/chunk_file.h
|
||||
ext/native/file/dialog.cpp
|
||||
ext/native/file/dialog.h
|
||||
ext/native/file/easy_file.cpp
|
||||
ext/native/file/easy_file.h
|
||||
ext/native/file/fd_util.cpp
|
||||
ext/native/file/fd_util.h
|
||||
ext/native/file/file_util.cpp
|
||||
ext/native/file/file_util.h
|
||||
ext/native/file/ini_file.cpp
|
||||
ext/native/file/ini_file.h
|
||||
ext/native/file/path.cpp
|
||||
ext/native/file/path.h
|
||||
ext/native/file/vfs.h
|
||||
ext/native/file/zip_read.cpp
|
||||
ext/native/file/zip_read.h
|
||||
ext/native/gfx/gl_common.h
|
||||
ext/native/gfx/gl_debug_log.cpp
|
||||
ext/native/gfx/gl_debug_log.h
|
||||
ext/native/gfx/gl_lost_manager.cpp
|
||||
ext/native/gfx/gl_lost_manager.h
|
||||
ext/native/gfx/texture.cpp
|
||||
ext/native/gfx/texture.h
|
||||
ext/native/gfx/texture_atlas.cpp
|
||||
ext/native/gfx/texture_atlas.h
|
||||
# ext/native/gfx/texture_dx11.cpp
|
||||
ext/native/gfx/texture_gen.cpp
|
||||
ext/native/gfx/texture_gen.h
|
||||
ext/native/gfx_es2/draw_buffer.cpp
|
||||
ext/native/gfx_es2/draw_buffer.h
|
||||
ext/native/gfx_es2/draw_text.cpp
|
||||
ext/native/gfx_es2/draw_text.h
|
||||
ext/native/gfx_es2/gpu_features.cpp
|
||||
ext/native/gfx_es2/gpu_features.h
|
||||
ext/native/gfx_es2/glsl_program.cpp
|
||||
ext/native/gfx_es2/glsl_program.h
|
||||
ext/native/gfx_es2/vertex_format.cpp
|
||||
ext/native/gfx_es2/vertex_format.h
|
||||
ext/native/gfx_es2/gl3stub.c
|
||||
ext/native/gfx_es2/gl3stub.h
|
||||
ext/native/i18n/i18n.cpp
|
||||
ext/native/i18n/i18n.h
|
||||
ext/native/image/png_load.cpp
|
||||
ext/native/image/png_load.h
|
||||
ext/native/image/zim_load.cpp
|
||||
ext/native/image/zim_load.h
|
||||
ext/native/image/zim_save.cpp
|
||||
ext/native/image/zim_save.h
|
||||
ext/native/input/gesture_detector.cpp
|
||||
ext/native/input/gesture_detector.h
|
||||
ext/native/input/keycodes.h
|
||||
ext/native/input/input_state.h
|
||||
ext/native/input/input_state.cpp
|
||||
ext/native/math/fast/fast_math.c
|
||||
ext/native/math/fast/fast_matrix.c
|
||||
ext/native/math/curves.cpp
|
||||
ext/native/math/curves.h
|
||||
ext/native/math/expression_parser.cpp
|
||||
ext/native/math/expression_parser.h
|
||||
ext/native/math/lin/aabb.cpp
|
||||
ext/native/math/lin/aabb.h
|
||||
ext/native/math/lin/matrix4x4.cpp
|
||||
ext/native/math/lin/matrix4x4.h
|
||||
ext/native/math/lin/plane.cpp
|
||||
ext/native/math/lin/plane.h
|
||||
ext/native/math/lin/quat.cpp
|
||||
ext/native/math/lin/quat.h
|
||||
ext/native/math/lin/ray.h
|
||||
ext/native/math/lin/vec3.cpp
|
||||
ext/native/math/lin/vec3.h
|
||||
ext/native/math/math_util.cpp
|
||||
ext/native/math/math_util.h
|
||||
ext/native/net/http_client.cpp
|
||||
ext/native/net/http_client.h
|
||||
ext/native/net/resolve.cpp
|
||||
ext/native/net/resolve.h
|
||||
ext/native/net/url.cpp
|
||||
ext/native/net/url.h
|
||||
ext/native/profiler/profiler.cpp
|
||||
ext/native/profiler/profiler.h
|
||||
ext/native/thin3d/thin3d.cpp
|
||||
ext/native/thin3d/thin3d.h
|
||||
ext/native/thin3d/thin3d_gl.cpp
|
||||
ext/native/thread/prioritizedworkqueue.cpp
|
||||
ext/native/thread/prioritizedworkqueue.h
|
||||
ext/native/thread/threadutil.cpp
|
||||
ext/native/thread/threadutil.h
|
||||
ext/native/thread/threadpool.cpp
|
||||
ext/native/thread/threadpool.h
|
||||
ext/native/ui/screen.cpp
|
||||
ext/native/ui/screen.h
|
||||
ext/native/ui/ui.cpp
|
||||
ext/native/ui/ui.h
|
||||
ext/native/ui/ui_context.cpp
|
||||
ext/native/ui/ui_context.h
|
||||
ext/native/ui/ui_screen.cpp
|
||||
ext/native/ui/ui_screen.h
|
||||
ext/native/ui/view.cpp
|
||||
ext/native/ui/view.h
|
||||
ext/native/ui/viewgroup.cpp
|
||||
ext/native/ui/viewgroup.h
|
||||
ext/native/ui/virtual_input.cpp
|
||||
ext/native/ui/virtual_input.h
|
||||
ext/native/util/bits/bits.cpp
|
||||
ext/native/util/bits/bits.h
|
||||
ext/native/util/bits/hamming.h
|
||||
ext/native/util/bits/varint.cpp
|
||||
ext/native/util/bits/varint.h
|
||||
ext/native/util/hash/hash.cpp
|
||||
ext/native/util/hash/hash.h
|
||||
ext/native/util/random/perlin.cpp
|
||||
ext/native/util/random/perlin.h
|
||||
ext/native/util/random/rng.h
|
||||
ext/native/util/text/utf8.h
|
||||
ext/native/util/text/utf8.cpp
|
||||
ext/native/util/text/parsers.h
|
||||
ext/native/util/text/parsers.cpp
|
||||
ext/native/util/const_map.h
|
||||
ext/native/ext/jpge/jpgd.cpp
|
||||
ext/native/ext/jpge/jpgd.h
|
||||
ext/native/ext/jpge/jpge.cpp
|
||||
ext/native/ext/jpge/jpge.h)
|
||||
include_directories(ext/native)
|
||||
|
||||
if (LINUX AND NOT ANDROID)
|
||||
SET(RT_LIB rt)
|
||||
|
@ -73,7 +73,7 @@
|
||||
<PreprocessorDefinitions>USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_32=1;_M_IX86=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>../native</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../ext/native</AdditionalIncludeDirectories>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
@ -100,7 +100,7 @@
|
||||
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PreprocessorDefinitions>USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_64=1;_M_X64=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>../native</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../ext/native</AdditionalIncludeDirectories>
|
||||
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<OmitFramePointers>false</OmitFramePointers>
|
||||
@ -132,7 +132,7 @@
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<AdditionalIncludeDirectories>../native</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../ext/native</AdditionalIncludeDirectories>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
@ -161,7 +161,7 @@
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_64=1;_M_X64=1;NDEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
|
||||
<AdditionalIncludeDirectories>../native</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../ext/native</AdditionalIncludeDirectories>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
@ -282,7 +282,7 @@
|
||||
<None Include="CMakeLists.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\native\native.vcxproj">
|
||||
<ProjectReference Include="..\ext\native\native.vcxproj">
|
||||
<Project>{c4df647e-80ea-4111-a0a8-218b1b711e18}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
|
@ -70,7 +70,7 @@
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86\include;../common;..;../native;../native/ext/glew;../ext/zlib;../native/ext</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86\include;../common;..;../ext/native;../ext/native/ext/glew;../ext/zlib;../ext/native/ext</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WIN32;_ARCH_32=1;_M_IX86=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
@ -91,7 +91,7 @@
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\include;../common;..;../native;../native/ext/glew;../ext/zlib;../native/ext</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\include;../common;..;../ext/native;../ext/native/ext/glew;../ext/zlib;../ext/native/ext</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WIN32;_ARCH_64=1;_M_X64=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
@ -115,7 +115,7 @@
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86\include;../common;..;../native;../native/ext/glew;../ext/zlib;../native/ext</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86\include;../common;..;../ext/native;../ext/native/ext/glew;../ext/zlib;../ext/native/ext</AdditionalIncludeDirectories>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
@ -145,7 +145,7 @@
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\include;../common;..;../native;../native/ext/glew;../ext/zlib;../native/ext</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\include;../common;..;../ext/native;../ext/native/ext/glew;../ext/zlib;../ext/native/ext</AdditionalIncludeDirectories>
|
||||
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
@ -731,7 +731,7 @@
|
||||
<ProjectReference Include="..\GPU\GPU.vcxproj">
|
||||
<Project>{457f45d2-556f-47bc-a31d-aff0d15beaed}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\native\native.vcxproj">
|
||||
<ProjectReference Include="..\ext\native\native.vcxproj">
|
||||
<Project>{C4DF647E-80EA-4111-A0A8-218B1B711E18}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\ext\zlib\zlib.vcxproj">
|
||||
|
@ -19,7 +19,7 @@
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "native/math/expression_parser.h"
|
||||
#include "math/expression_parser.h"
|
||||
|
||||
struct MemMap;
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "native/base/mutex.h"
|
||||
#include "base/mutex.h"
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
|
||||
|
@ -16,8 +16,8 @@
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#include "i18n/i18n.h"
|
||||
#include "native/thread/thread.h"
|
||||
#include "native/thread/threadutil.h"
|
||||
#include "thread/thread.h"
|
||||
#include "thread/threadutil.h"
|
||||
|
||||
#include "Common/ChunkFile.h"
|
||||
|
||||
|
@ -17,8 +17,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "native/thread/thread.h"
|
||||
#include "native/base/mutex.h"
|
||||
#include "thread/thread.h"
|
||||
#include "base/mutex.h"
|
||||
#include "Core/Dialog/PSPDialog.h"
|
||||
#include "Core/Dialog/SavedataParam.h"
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "native/base/mutex.h"
|
||||
#include "base/mutex.h"
|
||||
#include "Core/FileSystems/FileSystem.h"
|
||||
|
||||
class MetaFileSystem : public IHandleAllocator, public IFileSystem
|
||||
|
@ -18,8 +18,8 @@
|
||||
#include <cstdlib>
|
||||
#include <set>
|
||||
|
||||
#include "native/thread/thread.h"
|
||||
#include "native/thread/threadutil.h"
|
||||
#include "thread/thread.h"
|
||||
#include "thread/threadutil.h"
|
||||
#include "profiler/profiler.h"
|
||||
|
||||
#include "Core/Core.h"
|
||||
|
@ -15,7 +15,7 @@
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#include "native/ext/jpge/jpgd.h"
|
||||
#include "ext/jpge/jpgd.h"
|
||||
|
||||
#include "Common/Common.h"
|
||||
#include "Common/ChunkFile.h"
|
||||
|
@ -19,7 +19,7 @@
|
||||
#include <algorithm>
|
||||
#include <set>
|
||||
|
||||
#include "native/base/stringutil.h"
|
||||
#include "base/stringutil.h"
|
||||
#include "Common/ChunkFile.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Core/Config.h"
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include "native/base/mutex.h"
|
||||
#include "base/mutex.h"
|
||||
#include "Core/ThreadEventQueue.h"
|
||||
|
||||
class NoBase {
|
||||
|
@ -23,9 +23,9 @@
|
||||
#endif
|
||||
|
||||
#include "math/math_util.h"
|
||||
#include "native/thread/thread.h"
|
||||
#include "native/thread/threadutil.h"
|
||||
#include "native/base/mutex.h"
|
||||
#include "thread/thread.h"
|
||||
#include "thread/threadutil.h"
|
||||
#include "base/mutex.h"
|
||||
#include "util/text/utf8.h"
|
||||
|
||||
#include "Core/MemMap.h"
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "native/base/mutex.h"
|
||||
#include "base/mutex.h"
|
||||
#include "Core/System.h"
|
||||
#include "Core/CoreTiming.h"
|
||||
#include <deque>
|
||||
|
@ -43,7 +43,7 @@
|
||||
//#define SCALING_MEASURE_TIME
|
||||
|
||||
#ifdef SCALING_MEASURE_TIME
|
||||
#include "native/base/timeutil.h"
|
||||
#include "base/timeutil.h"
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////// Helper Functions (mostly math for parallelization)
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
#include "helper/global.h"
|
||||
#include "helper/dx_state.h"
|
||||
//#include "../native/gfx/gl_common.h"
|
||||
|
||||
|
@ -68,26 +68,26 @@
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<IncludePath>..\dx9sdk\Include;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);</IncludePath>
|
||||
<LibraryPath>..\dx9sdk\Lib\x86;$(VC_LibraryPath_x86);$(WindowsSdk_71A_LibraryPath_x86);</LibraryPath>
|
||||
<IncludePath>dx9sdk\Include;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);</IncludePath>
|
||||
<LibraryPath>dx9sdk\Lib\x86;$(VC_LibraryPath_x86);$(WindowsSdk_71A_LibraryPath_x86);</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<IncludePath>..\dx9sdk\Include;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);</IncludePath>
|
||||
<LibraryPath>..\dx9sdk\Lib\x64;$(VC_LibraryPath_x64);$(WindowsSdk_71A_LibraryPath_x64);</LibraryPath>
|
||||
<IncludePath>dx9sdk\Include;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);</IncludePath>
|
||||
<LibraryPath>dx9sdk\Lib\x64;$(VC_LibraryPath_x64);$(WindowsSdk_71A_LibraryPath_x64);</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<IncludePath>..\dx9sdk\Include;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);</IncludePath>
|
||||
<LibraryPath>..\dx9sdk\Lib\x64;$(VC_LibraryPath_x64);$(WindowsSdk_71A_LibraryPath_x64);</LibraryPath>
|
||||
<IncludePath>dx9sdk\Include;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);</IncludePath>
|
||||
<LibraryPath>dx9sdk\Lib\x64;$(VC_LibraryPath_x64);$(WindowsSdk_71A_LibraryPath_x64);</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<IncludePath>..\dx9sdk\Include;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);</IncludePath>
|
||||
<LibraryPath>..\dx9sdk\Lib\x86;$(VC_LibraryPath_x86);$(WindowsSdk_71A_LibraryPath_x86);</LibraryPath>
|
||||
<IncludePath>dx9sdk\Include;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);</IncludePath>
|
||||
<LibraryPath>dx9sdk\Lib\x86;$(VC_LibraryPath_x86);$(WindowsSdk_71A_LibraryPath_x86);</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>../common;..;../native;../native/ext/glew;</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../common;..;../ext/native;../ext/native/ext/glew;</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_32=1;_M_IX86=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
@ -108,7 +108,7 @@
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>../common;..;../native;../native/ext/glew;</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../common;..;../ext/native;../ext/native/ext/glew;</AdditionalIncludeDirectories>
|
||||
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<OmitFramePointers>false</OmitFramePointers>
|
||||
@ -132,7 +132,7 @@
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>../common;..;../native;../native/ext/glew;</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../common;..;../ext/native;../ext/native/ext/glew;</AdditionalIncludeDirectories>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
@ -158,7 +158,7 @@
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>../common;..;../native;../native/ext/glew;</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../common;..;../ext/native;../ext/native/ext/glew;</AdditionalIncludeDirectories>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include <algorithm>
|
||||
#include "native/base/mutex.h"
|
||||
#include "native/base/timeutil.h"
|
||||
#include "base/mutex.h"
|
||||
#include "base/timeutil.h"
|
||||
#include "Common/ColorConv.h"
|
||||
#include "GPU/GeDisasm.h"
|
||||
#include "GPU/GPU.h"
|
||||
|
@ -71,5 +71,5 @@ HEADERS += $$P/Common/ChunkFile.h \
|
||||
$$P/Common/Timer.h \
|
||||
$$P/Common/Crypto/*.h
|
||||
|
||||
INCLUDEPATH += $$P/native
|
||||
INCLUDEPATH += $$P/ext/native
|
||||
|
||||
|
@ -5,8 +5,8 @@ CONFIG += staticlib
|
||||
|
||||
include(Settings.pri)
|
||||
|
||||
INCLUDEPATH += $$P/ $$P/native $$P/Core/MIPS $$P/ext/xbrz
|
||||
!contains(DEFINES, USING_GLES2): INCLUDEPATH += $$P/native/ext/glew
|
||||
INCLUDEPATH += $$P/ $$P/ext/native $$P/Core/MIPS $$P/ext/xbrz
|
||||
!contains(DEFINES, USING_GLES2): INCLUDEPATH += $$P/ext/native/ext/glew
|
||||
|
||||
arm {
|
||||
SOURCES += $$P/Core/MIPS/ARM/*.cpp #CoreARM
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include "Core/CoreTiming.h"
|
||||
#include "mainwindow.h"
|
||||
#include "ctrlregisterlist.h"
|
||||
#include "native/base/stringutil.h"
|
||||
#include "base/stringutil.h"
|
||||
#include "Core/Debugger/SymbolMap.h"
|
||||
#include "GPU/GPUState.h"
|
||||
#include "GPU/GPUInterface.h"
|
||||
|
@ -6,8 +6,8 @@ CONFIG += staticlib
|
||||
|
||||
include(Settings.pri)
|
||||
|
||||
INCLUDEPATH += $$P/ $$P/native
|
||||
!contains(DEFINES, USING_GLES2): INCLUDEPATH += $$P/native/ext/glew
|
||||
INCLUDEPATH += $$P/ $$P/ext/native
|
||||
!contains(DEFINES, USING_GLES2): INCLUDEPATH += $$P/ext/native/ext/glew
|
||||
|
||||
win32 {
|
||||
SOURCES += $$P/Windows/OpenGLBase.cpp
|
||||
|
194
Qt/Native.pro
194
Qt/Native.pro
@ -9,36 +9,36 @@ include(Settings.pri)
|
||||
# To support Sailfish which is stuck on GCC 4.6
|
||||
linux-g++:system($$QMAKE_CXX --version | grep "4.6."): DEFINES+=override
|
||||
|
||||
INCLUDEPATH += $$P/native
|
||||
INCLUDEPATH += $$P/ext/native
|
||||
|
||||
!contains(DEFINES,USING_GLES2) {
|
||||
SOURCES += $$P/native/ext/glew/glew.c
|
||||
HEADERS += $$P/native/ext/glew/GL/*.h
|
||||
INCLUDEPATH += $$P/native/ext/glew
|
||||
SOURCES += $$P/ext/native/ext/glew/glew.c
|
||||
HEADERS += $$P/ext/native/ext/glew/GL/*.h
|
||||
INCLUDEPATH += $$P/ext/native/ext/glew
|
||||
}
|
||||
|
||||
# RG_ETC1
|
||||
|
||||
SOURCES += $$P/native/ext/rg_etc1/rg_etc1.cpp
|
||||
HEADERS += $$P/native/ext/rg_etc1/rg_etc1.h
|
||||
INCLUDEPATH += $$P/native/ext/rg_etc1
|
||||
SOURCES += $$P/ext/native/ext/rg_etc1/rg_etc1.cpp
|
||||
HEADERS += $$P/ext/native/ext/rg_etc1/rg_etc1.h
|
||||
INCLUDEPATH += $$P/ext/native/ext/rg_etc1
|
||||
|
||||
# Cityhash
|
||||
|
||||
SOURCES += ../native/ext/cityhash/city.cpp
|
||||
HEADERS += ../native/ext/cityhash/*.h
|
||||
INCLUDEPATH += ../native/ext/cityhash
|
||||
SOURCES += ../ext/native/ext/cityhash/city.cpp
|
||||
HEADERS += ../ext/native/ext/cityhash/*.h
|
||||
INCLUDEPATH += ../ext/native/ext/cityhash
|
||||
|
||||
# JPGE
|
||||
SOURCES += $$P/native/ext/jpge/*.cpp
|
||||
HEADERS += $$P/native/ext/jpge/*.h
|
||||
INCLUDEPATH += $$P/native/ext/jpge
|
||||
SOURCES += $$P/ext/native/ext/jpge/*.cpp
|
||||
HEADERS += $$P/ext/native/ext/jpge/*.h
|
||||
INCLUDEPATH += $$P/ext/native/ext/jpge
|
||||
|
||||
# Stb_vorbis
|
||||
|
||||
SOURCES += $$P/native/ext/stb_vorbis/stb_vorbis.c
|
||||
HEADERS += $$P/native/ext/stb_vorbis/stb_vorbis.h
|
||||
INCLUDEPATH += $$P/native/ext/stb_vorbis
|
||||
SOURCES += $$P/ext/native/ext/stb_vorbis/stb_vorbis.c
|
||||
HEADERS += $$P/ext/native/ext/stb_vorbis/stb_vorbis.h
|
||||
INCLUDEPATH += $$P/ext/native/ext/stb_vorbis
|
||||
|
||||
# Snappy
|
||||
|
||||
@ -54,11 +54,11 @@ INCLUDEPATH += $$P/ext/udis86
|
||||
|
||||
# VJSON
|
||||
|
||||
SOURCES += $$P/native/ext/vjson/json.cpp \
|
||||
$$P/native/ext/vjson/block_allocator.cpp
|
||||
HEADERS += $$P/native/ext/vjson/json.h \
|
||||
$$P/native/ext/vjson/block_allocator.h
|
||||
INCLUDEPATH += $$P/native/ext/vjson
|
||||
SOURCES += $$P/ext/native/ext/vjson/json.cpp \
|
||||
$$P/ext/native/ext/vjson/block_allocator.cpp
|
||||
HEADERS += $$P/ext/native/ext/vjson/json.h \
|
||||
$$P/ext/native/ext/vjson/block_allocator.h
|
||||
INCLUDEPATH += $$P/ext/native/ext/vjson
|
||||
|
||||
# Zlib
|
||||
win32|contains(QT_CONFIG, no-zlib) {
|
||||
@ -67,85 +67,85 @@ win32|contains(QT_CONFIG, no-zlib) {
|
||||
}
|
||||
|
||||
# Libzip
|
||||
SOURCES += $$P/native/ext/libzip/*.c
|
||||
HEADERS += $$P/native/ext/libzip/*.h
|
||||
SOURCES += $$P/ext/native/ext/libzip/*.c
|
||||
HEADERS += $$P/ext/native/ext/libzip/*.h
|
||||
|
||||
# Native
|
||||
|
||||
SOURCES += $$P/native/audio/*.cpp \
|
||||
$$P/native/base/backtrace.cpp \
|
||||
$$P/native/base/buffer.cpp \
|
||||
$$P/native/base/colorutil.cpp \
|
||||
$$P/native/base/compat.cpp \
|
||||
$$P/native/base/display.cpp \
|
||||
$$P/native/base/error_context.cpp \
|
||||
$$P/native/base/fastlist_test.cpp \
|
||||
$$P/native/base/stringutil.cpp \
|
||||
$$P/native/base/timeutil.cpp \
|
||||
$$P/native/data/compression.cpp \
|
||||
$$P/native/file/*.cpp \
|
||||
$$P/native/gfx/gl_debug_log.cpp \
|
||||
$$P/native/gfx/gl_lost_manager.cpp \
|
||||
$$P/native/gfx/texture.cpp \
|
||||
$$P/native/gfx/texture_atlas.cpp \
|
||||
$$P/native/gfx/texture_gen.cpp \
|
||||
$$P/native/gfx_es2/*.cpp \
|
||||
$$P/native/gfx_es2/*.c \
|
||||
$$P/native/i18n/*.cpp \
|
||||
$$P/native/image/*.cpp \
|
||||
$$P/native/input/*.cpp \
|
||||
$$P/native/math/curves.cpp \
|
||||
$$P/native/math/expression_parser.cpp \
|
||||
$$P/native/math/math_util.cpp \
|
||||
$$P/native/math/lin/*.cpp \
|
||||
$$P/native/math/fast/*.c \
|
||||
$$P/native/net/*.cpp \
|
||||
$$P/native/profiler/profiler.cpp \
|
||||
$$P/native/thin3d/thin3d.cpp \
|
||||
$$P/native/thin3d/thin3d_gl.cpp \
|
||||
$$P/native/thread/*.cpp \
|
||||
$$P/native/ui/*.cpp \
|
||||
$$P/native/util/bits/*.cpp \
|
||||
$$P/native/util/hash/hash.cpp \
|
||||
$$P/native/util/random/perlin.cpp \
|
||||
$$P/native/util/text/utf8.cpp \
|
||||
$$P/native/util/text/parsers.cpp
|
||||
SOURCES += $$P/ext/native/audio/*.cpp \
|
||||
$$P/ext/native/base/backtrace.cpp \
|
||||
$$P/ext/native/base/buffer.cpp \
|
||||
$$P/ext/native/base/colorutil.cpp \
|
||||
$$P/ext/native/base/compat.cpp \
|
||||
$$P/ext/native/base/display.cpp \
|
||||
$$P/ext/native/base/error_context.cpp \
|
||||
$$P/ext/native/base/fastlist_test.cpp \
|
||||
$$P/ext/native/base/stringutil.cpp \
|
||||
$$P/ext/native/base/timeutil.cpp \
|
||||
$$P/ext/native/data/compression.cpp \
|
||||
$$P/ext/native/file/*.cpp \
|
||||
$$P/ext/native/gfx/gl_debug_log.cpp \
|
||||
$$P/ext/native/gfx/gl_lost_manager.cpp \
|
||||
$$P/ext/native/gfx/texture.cpp \
|
||||
$$P/ext/native/gfx/texture_atlas.cpp \
|
||||
$$P/ext/native/gfx/texture_gen.cpp \
|
||||
$$P/ext/native/gfx_es2/*.cpp \
|
||||
$$P/ext/native/gfx_es2/*.c \
|
||||
$$P/ext/native/i18n/*.cpp \
|
||||
$$P/ext/native/image/*.cpp \
|
||||
$$P/ext/native/input/*.cpp \
|
||||
$$P/ext/native/math/curves.cpp \
|
||||
$$P/ext/native/math/expression_parser.cpp \
|
||||
$$P/ext/native/math/math_util.cpp \
|
||||
$$P/ext/native/math/lin/*.cpp \
|
||||
$$P/ext/native/math/fast/*.c \
|
||||
$$P/ext/native/net/*.cpp \
|
||||
$$P/ext/native/profiler/profiler.cpp \
|
||||
$$P/ext/native/thin3d/thin3d.cpp \
|
||||
$$P/ext/native/thin3d/thin3d_gl.cpp \
|
||||
$$P/ext/native/thread/*.cpp \
|
||||
$$P/ext/native/ui/*.cpp \
|
||||
$$P/ext/native/util/bits/*.cpp \
|
||||
$$P/ext/native/util/hash/hash.cpp \
|
||||
$$P/ext/native/util/random/perlin.cpp \
|
||||
$$P/ext/native/util/text/utf8.cpp \
|
||||
$$P/ext/native/util/text/parsers.cpp
|
||||
|
||||
armv7: SOURCES += $$files($$P/native/math/fast/fast_matrix_neon.S)
|
||||
armv7: SOURCES += $$files($$P/ext/native/math/fast/fast_matrix_neon.S)
|
||||
|
||||
|
||||
HEADERS += $$P/native/audio/*.h \
|
||||
$$P/native/base/backtrace.h \
|
||||
$$P/native/base/basictypes.h \
|
||||
$$P/native/base/buffer.h \
|
||||
$$P/native/base/color.h \
|
||||
$$P/native/base/colorutil.h \
|
||||
$$P/native/base/display.h \
|
||||
$$P/native/base/error_context.h \
|
||||
$$P/native/base/fastlist.h \
|
||||
$$P/native/base/linked_ptr.h \
|
||||
$$P/native/base/logging.h \
|
||||
$$P/native/base/mutex.h \
|
||||
$$P/native/base/scoped_ptr.h \
|
||||
$$P/native/base/stats.h \
|
||||
$$P/native/base/stringutil.h \
|
||||
$$P/native/base/timeutil.h \
|
||||
$$P/native/data/compression.h \
|
||||
$$P/native/file/*.h \
|
||||
$$P/native/gfx/*.h \
|
||||
$$P/native/gfx_es2/*.h \
|
||||
$$P/native/i18n/*.h \
|
||||
$$P/native/image/*.h \
|
||||
$$P/native/input/*.h \
|
||||
$$P/native/math/*.h \
|
||||
$$P/native/math/lin/*.h \
|
||||
$$P/native/math/fast/*.h \
|
||||
$$P/native/net/*.h \
|
||||
$$P/native/profiler/profiler.h \
|
||||
$$P/native/thread/*.h \
|
||||
$$P/native/ui/*.h \
|
||||
$$P/native/util/bits/*.h \
|
||||
$$P/native/util/hash/hash.h \
|
||||
$$P/native/util/random/*.h \
|
||||
$$P/native/util/text/utf8.h \
|
||||
$$P/native/util/text/parsers.h
|
||||
HEADERS += $$P/ext/native/audio/*.h \
|
||||
$$P/ext/native/base/backtrace.h \
|
||||
$$P/ext/native/base/basictypes.h \
|
||||
$$P/ext/native/base/buffer.h \
|
||||
$$P/ext/native/base/color.h \
|
||||
$$P/ext/native/base/colorutil.h \
|
||||
$$P/ext/native/base/display.h \
|
||||
$$P/ext/native/base/error_context.h \
|
||||
$$P/ext/native/base/fastlist.h \
|
||||
$$P/ext/native/base/linked_ptr.h \
|
||||
$$P/ext/native/base/logging.h \
|
||||
$$P/ext/native/base/mutex.h \
|
||||
$$P/ext/native/base/scoped_ptr.h \
|
||||
$$P/ext/native/base/stats.h \
|
||||
$$P/ext/native/base/stringutil.h \
|
||||
$$P/ext/native/base/timeutil.h \
|
||||
$$P/ext/native/data/compression.h \
|
||||
$$P/ext/native/file/*.h \
|
||||
$$P/ext/native/gfx/*.h \
|
||||
$$P/ext/native/gfx_es2/*.h \
|
||||
$$P/ext/native/i18n/*.h \
|
||||
$$P/ext/native/image/*.h \
|
||||
$$P/ext/native/input/*.h \
|
||||
$$P/ext/native/math/*.h \
|
||||
$$P/ext/native/math/lin/*.h \
|
||||
$$P/ext/native/math/fast/*.h \
|
||||
$$P/ext/native/net/*.h \
|
||||
$$P/ext/native/profiler/profiler.h \
|
||||
$$P/ext/native/thread/*.h \
|
||||
$$P/ext/native/ui/*.h \
|
||||
$$P/ext/native/util/bits/*.h \
|
||||
$$P/ext/native/util/hash/hash.h \
|
||||
$$P/ext/native/util/random/*.h \
|
||||
$$P/ext/native/util/text/utf8.h \
|
||||
$$P/ext/native/util/text/parsers.h
|
||||
|
@ -64,11 +64,11 @@ unix:contains(QT_CONFIG, system-zlib) {
|
||||
}
|
||||
|
||||
# Main
|
||||
SOURCES += $$P/native/base/QtMain.cpp
|
||||
HEADERS += $$P/native/base/QtMain.h
|
||||
SOURCES += $$P/ext/native/base/QtMain.cpp
|
||||
HEADERS += $$P/ext/native/base/QtMain.h
|
||||
symbian {
|
||||
SOURCES += $$P/native/base/SymbianMediaKeys.cpp
|
||||
HEADERS += $$P/native/base/SymbianMediaKeys.h
|
||||
SOURCES += $$P/ext/native/base/SymbianMediaKeys.cpp
|
||||
HEADERS += $$P/ext/native/base/SymbianMediaKeys.h
|
||||
}
|
||||
|
||||
# UI
|
||||
@ -77,7 +77,7 @@ SOURCES += $$P/UI/*.cpp \
|
||||
arm:android: SOURCES += $$P/android/jni/ArmEmitterTest.cpp
|
||||
HEADERS += $$P/UI/*.h
|
||||
|
||||
INCLUDEPATH += $$P $$P/Common $$P/native $$P/native/ext $$P/native/ext/glew
|
||||
INCLUDEPATH += $$P $$P/Common $$P/ext/native $$P/ext/native/ext $$P/ext/native/ext/glew
|
||||
|
||||
mobile_platform {
|
||||
!no_assets: RESOURCES += $$P/Qt/assets.qrc
|
||||
|
@ -1,5 +1,5 @@
|
||||
DEFINES += ANDROID
|
||||
INCLUDEPATH += $$P/native/ext/libzip
|
||||
INCLUDEPATH += $$P/ext/native/ext/libzip
|
||||
|
||||
!contains(CONFIG, staticlib) {
|
||||
# Packaging
|
||||
|
@ -2,7 +2,7 @@
|
||||
#include "base/logging.h"
|
||||
#include "base/timeutil.h"
|
||||
#include "base/mutex.h"
|
||||
#include "native/file/chunk_file.h"
|
||||
#include "file/chunk_file.h"
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Core/HW/SimpleAudioDec.h"
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include "TiltEventProcessor.h"
|
||||
#include "Core/HLE/sceCtrl.h"
|
||||
#include "math.h"
|
||||
#include "native/base/logging.h"
|
||||
#include "base/logging.h"
|
||||
|
||||
|
||||
using namespace TiltEventProcessor;
|
||||
|
@ -123,7 +123,7 @@
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>../common;..;../native;../native/ext/glew;../ext/zlib;../native/ext</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../common;..;../ext/native;../ext/native/ext/glew;../ext/zlib;../ext/native/ext</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
@ -145,7 +145,7 @@
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>../common;..;../native;../native/ext/glew;../ext/zlib;../native/ext</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../common;..;../ext/native;../ext/native/ext/glew;../ext/zlib;../ext/native/ext</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
@ -169,7 +169,7 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>../common;..;../native;../native/ext/glew;../ext/zlib;../native/ext</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../common;..;../ext/native;../ext/native/ext/glew;../ext/zlib;../ext/native/ext</AdditionalIncludeDirectories>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
@ -196,7 +196,7 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>../common;..;../native;../native/ext/glew;../ext/zlib;../native/ext</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../common;..;../ext/native;../ext/native/ext/glew;../ext/zlib;../ext/native/ext</AdditionalIncludeDirectories>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "Common/CommonWindows.h"
|
||||
#include <dsound.h>
|
||||
|
||||
#include "native/thread/threadutil.h"
|
||||
#include "thread/threadutil.h"
|
||||
#include "Core/Reporting.h"
|
||||
#include "Core/Util/AudioFormat.h"
|
||||
#include "Windows/W32Util/Misc.h"
|
||||
|
@ -19,8 +19,8 @@
|
||||
|
||||
#include "Common/Log.h"
|
||||
#include "Common/CommonWindows.h"
|
||||
#include "native/gfx/gl_common.h"
|
||||
#include "native/gfx_es2/gpu_features.h"
|
||||
#include "gfx/gl_common.h"
|
||||
#include "gfx_es2/gpu_features.h"
|
||||
#include "GL/gl.h"
|
||||
#include "GL/wglew.h"
|
||||
#include "Core/Config.h"
|
||||
|
@ -1,6 +1,6 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
VisualStudioVersion = 12.0.30723.0
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.23107.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PPSSPPWindows", "PPSSPP.vcxproj", "{567AF8DB-42C1-4D08-96CD-D70A2DFEFC6B}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
@ -35,7 +35,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Core", "..\Core\Core.vcxpro
|
||||
{3FCDBAE2-5103-4350-9A8E-848CE9C73195} = {3FCDBAE2-5103-4350-9A8E-848CE9C73195}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "native", "..\native\native.vcxproj", "{C4DF647E-80EA-4111-A0A8-218B1B711E18}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "native", "..\ext\native\native.vcxproj", "{C4DF647E-80EA-4111-A0A8-218B1B711E18}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{F761046E-6C38-4428-A5F1-38391A37BB34} = {F761046E-6C38-4428-A5F1-38391A37BB34}
|
||||
EndProjectSection
|
||||
|
@ -97,25 +97,25 @@
|
||||
<OutDir>..\</OutDir>
|
||||
<TargetName>PPSSPPDebug</TargetName>
|
||||
<EmbedManifest>false</EmbedManifest>
|
||||
<IncludePath>..\dx9sdk\Include;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);</IncludePath>
|
||||
<LibraryPath>..\dx9sdk\Lib\x86;$(VC_LibraryPath_x86);$(WindowsSdk_71A_LibraryPath_x86);</LibraryPath>
|
||||
<IncludePath>dx9sdk\Include;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);</IncludePath>
|
||||
<LibraryPath>dx9sdk\Lib\x86;$(VC_LibraryPath_x86);$(WindowsSdk_71A_LibraryPath_x86);</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<TargetName>PPSSPPDebug64</TargetName>
|
||||
<EmbedManifest>false</EmbedManifest>
|
||||
<IncludePath>..\dx9sdk\Include;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);</IncludePath>
|
||||
<LibraryPath>..\dx9sdk\Lib\x64;$(VC_LibraryPath_x64);$(WindowsSdk_71A_LibraryPath_x64);</LibraryPath>
|
||||
<IncludePath>dx9sdk\Include;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);</IncludePath>
|
||||
<LibraryPath>dx9sdk\Lib\x64;$(VC_LibraryPath_x64);$(WindowsSdk_71A_LibraryPath_x64);</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<TargetName>PPSSPPWindows64</TargetName>
|
||||
<EmbedManifest>false</EmbedManifest>
|
||||
<IncludePath>..\dx9sdk\Include;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);</IncludePath>
|
||||
<LibraryPath>..\dx9sdk\Lib\x64;$(VC_LibraryPath_x64);$(WindowsSdk_71A_LibraryPath_x64);</LibraryPath>
|
||||
<IncludePath>dx9sdk\Include;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);</IncludePath>
|
||||
<LibraryPath>dx9sdk\Lib\x64;$(VC_LibraryPath_x64);$(WindowsSdk_71A_LibraryPath_x64);</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<EmbedManifest>false</EmbedManifest>
|
||||
<IncludePath>..\dx9sdk\Include;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);</IncludePath>
|
||||
<LibraryPath>..\dx9sdk\Lib\x86;$(VC_LibraryPath_x86);$(WindowsSdk_71A_LibraryPath_x86);</LibraryPath>
|
||||
<IncludePath>dx9sdk\Include;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);</IncludePath>
|
||||
<LibraryPath>dx9sdk\Lib\x86;$(VC_LibraryPath_x86);$(WindowsSdk_71A_LibraryPath_x86);</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
@ -126,7 +126,7 @@
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
<AdditionalIncludeDirectories>../common;..;../native;../native/ext/glew;../ext/zlib</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../common;..;../ext/native;../ext/native/ext/glew;../ext/zlib</AdditionalIncludeDirectories>
|
||||
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
|
||||
@ -163,7 +163,7 @@
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<AdditionalIncludeDirectories>../common;..;../native;../native/ext/glew;../ext/zlib</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../common;..;../ext/native;../ext/native/ext/glew;../ext/zlib</AdditionalIncludeDirectories>
|
||||
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<OmitFramePointers>false</OmitFramePointers>
|
||||
@ -203,7 +203,7 @@
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<AdditionalIncludeDirectories>../common;..;../native;../native/ext/glew;../ext/zlib</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../common;..;../ext/native;../ext/native/ext/glew;../ext/zlib</AdditionalIncludeDirectories>
|
||||
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
|
||||
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
@ -248,7 +248,7 @@
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<AdditionalIncludeDirectories>../common;..;../native;../native/ext/glew;../ext/zlib</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../common;..;../ext/native;../ext/native/ext/glew;../ext/zlib</AdditionalIncludeDirectories>
|
||||
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
@ -282,7 +282,7 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\android\jni\TestRunner.cpp" />
|
||||
<ClCompile Include="..\native\ext\glew\glew.c">
|
||||
<ClCompile Include="..\ext\native\ext\glew\glew.c">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
|
||||
<ForcedIncludeFiles Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</ForcedIncludeFiles>
|
||||
@ -427,7 +427,7 @@
|
||||
<ProjectReference Include="..\GPU\GPU.vcxproj">
|
||||
<Project>{457f45d2-556f-47bc-a31d-aff0d15beaed}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\native\native.vcxproj">
|
||||
<ProjectReference Include="..\ext\native\native.vcxproj">
|
||||
<Project>{C4DF647E-80EA-4111-A0A8-218B1B711E18}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\ext\zlib\zlib.vcxproj">
|
||||
|
@ -1,16 +1,16 @@
|
||||
eclipse.preferences.version=1
|
||||
environment/project/com.android.toolchain.gcc.2140973729.1677696028.85809333/NDK_MODULE_PATH/delimiter=;
|
||||
environment/project/com.android.toolchain.gcc.2140973729.1677696028.85809333/NDK_MODULE_PATH/operation=append
|
||||
environment/project/com.android.toolchain.gcc.2140973729.1677696028.85809333/NDK_MODULE_PATH/value=.;..;..\\native\\ext
|
||||
environment/project/com.android.toolchain.gcc.2140973729.1677696028.85809333/NDK_MODULE_PATH/value=.;..;..\\ext\\native\\ext
|
||||
environment/project/com.android.toolchain.gcc.2140973729.1677696028.85809333/append=true
|
||||
environment/project/com.android.toolchain.gcc.2140973729.1677696028.85809333/appendContributed=true
|
||||
environment/project/com.android.toolchain.gcc.2140973729.1677696028/NDK_MODULE_PATH/delimiter=;
|
||||
environment/project/com.android.toolchain.gcc.2140973729.1677696028/NDK_MODULE_PATH/operation=append
|
||||
environment/project/com.android.toolchain.gcc.2140973729.1677696028/NDK_MODULE_PATH/value=.;..;..\\native\\ext
|
||||
environment/project/com.android.toolchain.gcc.2140973729.1677696028/NDK_MODULE_PATH/value=.;..;..\\ext\\native\\ext
|
||||
environment/project/com.android.toolchain.gcc.2140973729.1677696028/append=true
|
||||
environment/project/com.android.toolchain.gcc.2140973729.1677696028/appendContributed=true
|
||||
environment/project/com.android.toolchain.gcc.2140973729/NDK_MODULE_PATH/delimiter=;
|
||||
environment/project/com.android.toolchain.gcc.2140973729/NDK_MODULE_PATH/operation=append
|
||||
environment/project/com.android.toolchain.gcc.2140973729/NDK_MODULE_PATH/value=.;..;..\\native\\ext
|
||||
environment/project/com.android.toolchain.gcc.2140973729/NDK_MODULE_PATH/value=.;..;..\\ext\\native\\ext
|
||||
environment/project/com.android.toolchain.gcc.2140973729/append=true
|
||||
environment/project/com.android.toolchain.gcc.2140973729/appendContributed=true
|
||||
|
@ -4,5 +4,5 @@ xcopy ..\assets\shaders assets\shaders /s /y <d.txt
|
||||
copy ..\assets\langregion.ini assets\langregion.ini
|
||||
copy ..\assets\*.png assets
|
||||
SET NDK=C:\AndroidNDK
|
||||
SET NDK_MODULE_PATH=..;..\native\ext
|
||||
SET NDK_MODULE_PATH=..\ext;..\ext\native\ext
|
||||
%NDK%/ndk-build -j9 %*
|
||||
|
@ -3,4 +3,4 @@ cp -r ../lang assets
|
||||
cp -r ../assets/shaders assets
|
||||
cp ../assets/langregion.ini assets/langregion.ini
|
||||
cp ../assets/*.png assets
|
||||
NDK_MODULE_PATH=..:../native/ext $NDK/ndk-build -j3 $*
|
||||
NDK_MODULE_PATH=../ext:../ext/native/ext $NDK/ndk-build -j3 $*
|
||||
|
@ -4,7 +4,7 @@ include $(CLEAR_VARS)
|
||||
|
||||
#TARGET_PLATFORM := android-8
|
||||
|
||||
NATIVE := ../../native
|
||||
NATIVE := ../../ext/native
|
||||
SRC := ../..
|
||||
|
||||
include $(LOCAL_PATH)/Locals.mk
|
||||
@ -325,7 +325,7 @@ LOCAL_STATIC_LIBRARIES += ppsspp_core
|
||||
# These are the files just for ppsspp_jni
|
||||
LOCAL_MODULE := ppsspp_jni
|
||||
LOCAL_SRC_FILES := \
|
||||
$(SRC)/native/android/app-android.cpp \
|
||||
$(NATIVE)/android/app-android.cpp \
|
||||
$(SRC)/UI/BackgroundAudio.cpp \
|
||||
$(SRC)/UI/DevScreens.cpp \
|
||||
$(SRC)/UI/EmuScreen.cpp \
|
||||
|
@ -12,4 +12,4 @@
|
||||
|
||||
# Project target.
|
||||
target=android-22
|
||||
android.library.reference.1=../native/android
|
||||
android.library.reference.1=../ext/native/android
|
||||
|
@ -1,4 +1,4 @@
|
||||
./native/tools/build/atlastool atlasscript.txt ui 8888 && cp ui_atlas.zim assets && cp ui_atlas.zim android/assets && cp ui_atlas.zim.png ui_atlas_high.zim.png && mv ui_atlas.cpp ui_atlas_highmem.cpp && mv ui_atlas.h UI
|
||||
./native/tools/build/atlastool atlasscript_lowmem.txt ui 8888 && mv ui_atlas.zim assets/ui_atlas_lowmem.zim && mv ui_atlas.cpp ui_atlas_lowmem.cpp
|
||||
./ext/native/tools/build/atlastool atlasscript.txt ui 8888 && cp ui_atlas.zim assets && cp ui_atlas.zim android/assets && cp ui_atlas.zim.png ui_atlas_high.zim.png && mv ui_atlas.cpp ui_atlas_highmem.cpp && mv ui_atlas.h UI
|
||||
./ext/native/tools/build/atlastool atlasscript_lowmem.txt ui 8888 && mv ui_atlas.zim assets/ui_atlas_lowmem.zim && mv ui_atlas.cpp ui_atlas_lowmem.cpp
|
||||
diff -I'^//.*' -D USING_QT_UI ui_atlas_highmem.cpp ui_atlas_lowmem.cpp > UI/ui_atlas.cpp
|
||||
rm ui_atlas_highmem.cpp ui_atlas_lowmem.cpp ui_atlas.h
|
||||
|
6
ext/native/.gitignore
vendored
Normal file
6
ext/native/.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
Release
|
||||
Debug
|
||||
*.vcxproj.user
|
||||
android/.settings
|
||||
local.properties
|
||||
.DS_Store
|
133
ext/native/Android.mk
Normal file
133
ext/native/Android.mk
Normal file
@ -0,0 +1,133 @@
|
||||
# Basic Android.mk for libnative
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE := libnative
|
||||
LOCAL_ARM_MODE := arm
|
||||
LOCAL_SRC_FILES :=\
|
||||
android/native_audio.cpp \
|
||||
android/native-audio-so.cpp \
|
||||
audio/wav_read.cpp \
|
||||
audio/mixer.cpp.arm \
|
||||
base/backtrace.cpp \
|
||||
base/buffer.cpp \
|
||||
base/compat.cpp \
|
||||
base/display.cpp \
|
||||
base/timeutil.cpp \
|
||||
base/colorutil.cpp \
|
||||
base/error_context.cpp \
|
||||
base/stringutil.cpp \
|
||||
data/compression.cpp \
|
||||
ext/rg_etc1/rg_etc1.cpp \
|
||||
ext/cityhash/city.cpp \
|
||||
ext/libpng17/png.c \
|
||||
ext/libpng17/pngerror.c \
|
||||
ext/libpng17/pngget.c \
|
||||
ext/libpng17/pngmem.c \
|
||||
ext/libpng17/pngpread.c \
|
||||
ext/libpng17/pngread.c \
|
||||
ext/libpng17/pngrio.c \
|
||||
ext/libpng17/pngrtran.c \
|
||||
ext/libpng17/pngrutil.c \
|
||||
ext/libpng17/pngset.c \
|
||||
ext/libpng17/pngtest.c \
|
||||
ext/libpng17/pngtrans.c \
|
||||
ext/libpng17/pngwio.c \
|
||||
ext/libpng17/pngwrite.c \
|
||||
ext/libpng17/pngwtran.c \
|
||||
ext/libpng17/pngwutil.c \
|
||||
ext/jpge/jpgd.cpp \
|
||||
ext/jpge/jpge.cpp \
|
||||
ext/sha1/sha1.cpp \
|
||||
ext/stb_vorbis/stb_vorbis.c.arm \
|
||||
ext/vjson/json.cpp \
|
||||
ext/vjson/block_allocator.cpp \
|
||||
file/dialog.cpp \
|
||||
file/fd_util.cpp \
|
||||
file/easy_file.cpp \
|
||||
file/chunk_file.cpp \
|
||||
file/file_util.cpp \
|
||||
file/path.cpp \
|
||||
file/ini_file.cpp \
|
||||
file/zip_read.cpp \
|
||||
json/json_writer.cpp \
|
||||
i18n/i18n.cpp \
|
||||
input/gesture_detector.cpp \
|
||||
input/input_state.cpp \
|
||||
math/fast/fast_math.c \
|
||||
math/fast/fast_matrix.c \
|
||||
math/math_util.cpp \
|
||||
math/curves.cpp \
|
||||
math/expression_parser.cpp \
|
||||
math/lin/aabb.cpp.arm \
|
||||
math/lin/plane.cpp.arm \
|
||||
math/lin/quat.cpp.arm \
|
||||
math/lin/vec3.cpp.arm \
|
||||
math/lin/matrix4x4.cpp.arm \
|
||||
midi/midi_input.cpp \
|
||||
net/http_client.cpp \
|
||||
net/http_server.cpp \
|
||||
net/http_headers.cpp \
|
||||
net/resolve.cpp \
|
||||
net/url.cpp \
|
||||
profiler/profiler.cpp \
|
||||
thread/executor.cpp \
|
||||
thread/threadutil.cpp \
|
||||
thread/prioritizedworkqueue.cpp \
|
||||
thread/threadpool.cpp \
|
||||
gfx_es2/glsl_program.cpp \
|
||||
gfx_es2/gpu_features.cpp \
|
||||
gfx_es2/gl3stub.c \
|
||||
gfx_es2/draw_buffer.cpp.arm \
|
||||
gfx_es2/draw_text.cpp.arm \
|
||||
gfx_es2/vertex_format.cpp \
|
||||
gfx/gl_debug_log.cpp \
|
||||
gfx/gl_lost_manager.cpp \
|
||||
gfx/texture.cpp \
|
||||
gfx/texture_atlas.cpp \
|
||||
gfx/texture_gen.cpp \
|
||||
image/zim_load.cpp \
|
||||
image/zim_save.cpp \
|
||||
image/png_load.cpp \
|
||||
thin3d/thin3d.cpp \
|
||||
thin3d/thin3d_gl.cpp \
|
||||
ui/view.cpp \
|
||||
ui/viewgroup.cpp \
|
||||
ui/ui.cpp \
|
||||
ui/ui_screen.cpp \
|
||||
ui/ui_context.cpp \
|
||||
ui/screen.cpp \
|
||||
ui/virtual_input.cpp \
|
||||
util/random/perlin.cpp \
|
||||
util/text/utf8.cpp \
|
||||
util/text/parsers.cpp \
|
||||
util/hash/hash.cpp
|
||||
|
||||
LOCAL_CFLAGS := -O3 -DUSING_GLES2 -fsigned-char -fno-strict-aliasing -Wall -Wno-multichar -D__STDC_CONSTANT_MACROS
|
||||
LOCAL_CPPFLAGS := -fno-exceptions -std=gnu++11 -fno-rtti -Wno-reorder
|
||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/ext $(LOCAL_PATH)/ext/libzip
|
||||
|
||||
#Portable native and separate code on android in future is easy you needs add files
|
||||
#by ($(target_arch_ABI),arquitecture (armeabi-v7a , armeabi , x86 , MIPS)
|
||||
# ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
|
||||
ifeq ($(findstring armeabi-v7a,$(TARGET_ARCH_ABI)),armeabi-v7a)
|
||||
LOCAL_CFLAGS := $(LOCAL_CFLAGS) -DARM -DARMEABI_V7A
|
||||
LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
|
||||
math/fast/fast_matrix_neon.S.neon \
|
||||
ext/libpng17/arm/arm_init.c \
|
||||
ext/libpng17/arm/filter_neon_intrinsics.c \
|
||||
ext/libpng17/arm/filter_neon.S.neon
|
||||
|
||||
else ifeq ($(TARGET_ARCH_ABI),armeabi)
|
||||
LOCAL_CFLAGS := $(LOCAL_CFLAGS) -DARM -DARMEABI -march=armv6
|
||||
else ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
|
||||
LOCAL_CFLAGS := $(LOCAL_CFLAGS) -D_ARCH_64 -DARM64
|
||||
else ifeq ($(TARGET_ARCH_ABI),x86)
|
||||
LOCAL_CFLAGS := $(LOCAL_CFLAGS) -D_M_IX86
|
||||
LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
|
||||
math/fast/fast_matrix_sse.c
|
||||
endif
|
||||
|
||||
include $(BUILD_STATIC_LIBRARY)
|
9
ext/native/LICENSE.TXT
Normal file
9
ext/native/LICENSE.TXT
Normal file
@ -0,0 +1,9 @@
|
||||
Copyright (C) 2012 Henrik Rydgard
|
||||
|
||||
This applies to all the code here not covered under other licenses, see README.md.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
50
ext/native/README.md
Normal file
50
ext/native/README.md
Normal file
@ -0,0 +1,50 @@
|
||||
native
|
||||
======
|
||||
|
||||
This is my library of stuff that I use when writing C++ programs, mostly for Android but it's all written to enable easy portability between Android, Linux, Windows and MacOSX. The code is part ugly, part inconsistent but quite useful.
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
* JSON read/write (two libraries that should be made more similar)
|
||||
* basic OpenGL utility code, like compressed texture loading
|
||||
* 2D texture atlases and drawing code
|
||||
* ETC1 texture save/load support
|
||||
* basic logging
|
||||
* Really simple audio mixer with OGG sample support
|
||||
* RIFF file read/write
|
||||
* MIDI Input (only on Windows)
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
* The associated tools to create ZIM texture files and atlases do not yet live here but I might move them here eventually.
|
||||
* This library is not really meant to be a public library but I see no reason not to set it free.
|
||||
* Note that the included VS project is probably not very useful for you and you're likely better off making your own.
|
||||
* Don't complain about inconsistent naming etc - this consists of code that has been cobbled together from a variety of my projects through the years. Fashions come and go.
|
||||
|
||||
Licenses
|
||||
--------
|
||||
|
||||
This library, for my convenience, incorporates code from a variety of public domain or similarly-licensed code. This is the list:
|
||||
|
||||
* glew (GL extension wrangler), MIT license. TODO: should just use a submodule.
|
||||
* rg_etc1. ZLIB license.
|
||||
* sha1, public domain implementation by Dominik Reichl
|
||||
* vjson in a heavily modified form, originally by Ivan Vashchaev (TODO: break out into its own repo?)
|
||||
* libzip with attribution "Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner"
|
||||
* stb_vorbis, public domain by Sean Barrett of RAD Tools
|
||||
|
||||
If you're not okay with the licenses above, don't use this code.
|
||||
|
||||
I hereby release all code here not under the licenses above under the MIT license.
|
||||
|
||||
Contact
|
||||
-------
|
||||
|
||||
If you find this useful for your own projects, drop me a line at hrydgard@gmail.com .
|
||||
|
||||
Henrik Rydgård
|
||||
|
||||
|
||||
|
9
ext/native/android/.classpath
Normal file
9
ext/native/android/.classpath
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="gen"/>
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
||||
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
|
||||
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
|
||||
<classpathentry kind="output" path="bin/classes"/>
|
||||
</classpath>
|
2
ext/native/android/.gitignore
vendored
Normal file
2
ext/native/android/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
gen
|
||||
bin
|
33
ext/native/android/.project
Normal file
33
ext/native/android/.project
Normal file
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>libnative</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
13
ext/native/android/AndroidManifest.xml
Normal file
13
ext/native/android/AndroidManifest.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.turboviking.libnative"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0" >
|
||||
|
||||
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="19" />
|
||||
|
||||
<application
|
||||
android:icon="@drawable/ic_launcher" >
|
||||
</application>
|
||||
|
||||
</manifest>
|
8
ext/native/android/README.md
Normal file
8
ext/native/android/README.md
Normal file
@ -0,0 +1,8 @@
|
||||
Here's an Android library project. Add this to your eclipse workspace
|
||||
and add a dependency to it, then just inherit from NativeActivity,
|
||||
write your C++ code, and Bob's your uncle.
|
||||
|
||||
|
||||
Contact: hrydgard@gmail.com
|
||||
|
||||
|
536
ext/native/android/app-android.cpp
Normal file
536
ext/native/android/app-android.cpp
Normal file
@ -0,0 +1,536 @@
|
||||
// This is generic code that is included in all Android apps that use the
|
||||
// Native framework by Henrik Rydgård (https://github.com/hrydgard/native).
|
||||
|
||||
// It calls a set of methods defined in NativeApp.h. These should be implemented
|
||||
// by your game or app.
|
||||
|
||||
#include <jni.h>
|
||||
#include <android/log.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
#include <queue>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/display.h"
|
||||
#include "base/mutex.h"
|
||||
#include "base/NativeApp.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/timeutil.h"
|
||||
#include "thread/threadutil.h"
|
||||
#include "file/zip_read.h"
|
||||
#include "input/input_state.h"
|
||||
#include "profiler/profiler.h"
|
||||
#include "audio/mixer.h"
|
||||
#include "math/math_util.h"
|
||||
#include "net/resolve.h"
|
||||
#include "android/native_audio.h"
|
||||
#include "gfx/gl_common.h"
|
||||
|
||||
#include "app-android.h"
|
||||
|
||||
static JNIEnv *jniEnvUI;
|
||||
|
||||
struct FrameCommand {
|
||||
FrameCommand() {}
|
||||
FrameCommand(std::string cmd, std::string prm) : command(cmd), params(prm) {}
|
||||
|
||||
std::string command;
|
||||
std::string params;
|
||||
};
|
||||
|
||||
static recursive_mutex frameCommandLock;
|
||||
static std::queue<FrameCommand> frameCommands;
|
||||
|
||||
std::string systemName;
|
||||
std::string langRegion;
|
||||
std::string mogaVersion;
|
||||
|
||||
static float left_joystick_x_async;
|
||||
static float left_joystick_y_async;
|
||||
static float right_joystick_x_async;
|
||||
static float right_joystick_y_async;
|
||||
static float hat_joystick_x_async;
|
||||
static float hat_joystick_y_async;
|
||||
|
||||
static int optimalFramesPerBuffer = 0;
|
||||
static int optimalSampleRate = 0;
|
||||
static int sampleRate = 0;
|
||||
static int framesPerBuffer = 0;
|
||||
static int androidVersion;
|
||||
static int deviceType;
|
||||
|
||||
// Should only be used for display detection during startup (for config defaults etc)
|
||||
static int display_xres;
|
||||
static int display_yres;
|
||||
|
||||
// Android implementation of callbacks to the Java part of the app
|
||||
void SystemToast(const char *text) {
|
||||
lock_guard guard(frameCommandLock);
|
||||
frameCommands.push(FrameCommand("toast", text));
|
||||
}
|
||||
|
||||
void ShowKeyboard() {
|
||||
lock_guard guard(frameCommandLock);
|
||||
frameCommands.push(FrameCommand("showKeyboard", ""));
|
||||
}
|
||||
|
||||
void Vibrate(int length_ms) {
|
||||
lock_guard guard(frameCommandLock);
|
||||
char temp[32];
|
||||
sprintf(temp, "%i", length_ms);
|
||||
frameCommands.push(FrameCommand("vibrate", temp));
|
||||
}
|
||||
|
||||
void LaunchBrowser(const char *url) {
|
||||
lock_guard guard(frameCommandLock);
|
||||
frameCommands.push(FrameCommand("launchBrowser", url));
|
||||
}
|
||||
|
||||
void LaunchMarket(const char *url) {
|
||||
lock_guard guard(frameCommandLock);
|
||||
frameCommands.push(FrameCommand("launchMarket", url));
|
||||
}
|
||||
|
||||
void LaunchEmail(const char *email_address) {
|
||||
lock_guard guard(frameCommandLock);
|
||||
frameCommands.push(FrameCommand("launchEmail", email_address));
|
||||
}
|
||||
|
||||
void System_SendMessage(const char *command, const char *parameter) {
|
||||
lock_guard guard(frameCommandLock);
|
||||
frameCommands.push(FrameCommand(command, parameter));
|
||||
}
|
||||
|
||||
std::string System_GetProperty(SystemProperty prop) {
|
||||
switch (prop) {
|
||||
case SYSPROP_NAME:
|
||||
return systemName;
|
||||
case SYSPROP_LANGREGION: // "en_US"
|
||||
return langRegion;
|
||||
case SYSPROP_MOGA_VERSION:
|
||||
return mogaVersion;
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
int System_GetPropertyInt(SystemProperty prop) {
|
||||
switch (prop) {
|
||||
case SYSPROP_SYSTEMVERSION:
|
||||
return androidVersion;
|
||||
case SYSPROP_DEVICE_TYPE:
|
||||
return deviceType;
|
||||
case SYSPROP_DISPLAY_XRES:
|
||||
return display_xres;
|
||||
case SYSPROP_DISPLAY_YRES:
|
||||
return display_yres;
|
||||
case SYSPROP_AUDIO_SAMPLE_RATE:
|
||||
return sampleRate;
|
||||
case SYSPROP_AUDIO_FRAMES_PER_BUFFER:
|
||||
return framesPerBuffer;
|
||||
case SYSPROP_AUDIO_OPTIMAL_SAMPLE_RATE:
|
||||
return optimalSampleRate;
|
||||
case SYSPROP_AUDIO_OPTIMAL_FRAMES_PER_BUFFER:
|
||||
return optimalFramesPerBuffer;
|
||||
case SYSPROP_DISPLAY_REFRESH_RATE:
|
||||
return (int)(display_hz * 1000.0);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Remember that all of these need initialization on init! The process
|
||||
// may be reused when restarting the game. Globals are DANGEROUS.
|
||||
|
||||
float dp_xscale = 1.0f;
|
||||
float dp_yscale = 1.0f;
|
||||
|
||||
InputState input_state;
|
||||
|
||||
static bool renderer_inited = false;
|
||||
static bool first_lost = true;
|
||||
static std::string library_path;
|
||||
|
||||
std::string GetJavaString(JNIEnv *env, jstring jstr) {
|
||||
const char *str = env->GetStringUTFChars(jstr, 0);
|
||||
std::string cpp_string = std::string(str);
|
||||
env->ReleaseStringUTFChars(jstr, str);
|
||||
return cpp_string;
|
||||
}
|
||||
|
||||
// This is now only used as a trigger for GetAppInfo as a function to all before Init.
|
||||
// On Android we don't use any of the values it returns.
|
||||
extern "C" jboolean Java_com_henrikrydgard_libnative_NativeApp_isLandscape(JNIEnv *env, jclass) {
|
||||
std::string app_name, app_nice_name, version;
|
||||
bool landscape;
|
||||
NativeGetAppInfo(&app_name, &app_nice_name, &landscape, &version);
|
||||
return landscape;
|
||||
}
|
||||
|
||||
// Allow the app to intercept the back button.
|
||||
extern "C" jboolean Java_com_henrikrydgard_libnative_NativeApp_isAtTopLevel(JNIEnv *env, jclass) {
|
||||
return NativeIsAtTopLevel();
|
||||
}
|
||||
|
||||
extern "C" void Java_com_henrikrydgard_libnative_NativeApp_audioConfig
|
||||
(JNIEnv *env, jclass, jint optimalFPB, jint optimalSR) {
|
||||
optimalFramesPerBuffer = optimalFPB;
|
||||
optimalSampleRate = optimalSR;
|
||||
}
|
||||
|
||||
extern "C" jstring Java_com_henrikrydgard_libnative_NativeApp_queryConfig
|
||||
(JNIEnv *env, jclass, jstring jquery) {
|
||||
std::string query = GetJavaString(env, jquery);
|
||||
std::string result = NativeQueryConfig(query);
|
||||
jstring jresult = env->NewStringUTF(result.c_str());
|
||||
return jresult;
|
||||
}
|
||||
|
||||
extern "C" void Java_com_henrikrydgard_libnative_NativeApp_init
|
||||
(JNIEnv *env, jclass, jstring jmodel, jint jdeviceType, jint jxres, jint jyres, jstring jlangRegion, jstring japkpath,
|
||||
jstring jdataDir, jstring jexternalDir, jstring jlibraryDir, jstring jshortcutParam,
|
||||
jstring jinstallID, jint jAndroidVersion) {
|
||||
jniEnvUI = env;
|
||||
|
||||
setCurrentThreadName("androidInit");
|
||||
|
||||
ILOG("NativeApp.init() -- begin");
|
||||
PROFILE_INIT();
|
||||
|
||||
memset(&input_state, 0, sizeof(input_state));
|
||||
renderer_inited = false;
|
||||
first_lost = true;
|
||||
androidVersion = jAndroidVersion;
|
||||
deviceType = jdeviceType;
|
||||
|
||||
g_buttonTracker.Reset();
|
||||
|
||||
left_joystick_x_async = 0;
|
||||
left_joystick_y_async = 0;
|
||||
right_joystick_x_async = 0;
|
||||
right_joystick_y_async = 0;
|
||||
hat_joystick_x_async = 0;
|
||||
hat_joystick_y_async = 0;
|
||||
display_xres = jxres;
|
||||
display_yres = jyres;
|
||||
|
||||
std::string apkPath = GetJavaString(env, japkpath);
|
||||
VFSRegister("", new ZipAssetReader(apkPath.c_str(), "assets/"));
|
||||
|
||||
systemName = GetJavaString(env, jmodel);
|
||||
langRegion = GetJavaString(env, jlangRegion);
|
||||
|
||||
std::string externalDir = GetJavaString(env, jexternalDir);
|
||||
std::string user_data_path = GetJavaString(env, jdataDir) + "/";
|
||||
library_path = GetJavaString(env, jlibraryDir) + "/";
|
||||
std::string shortcut_param = GetJavaString(env, jshortcutParam);
|
||||
std::string installID = GetJavaString(env, jinstallID);
|
||||
|
||||
ILOG("NativeApp.init(): External storage path: %s", externalDir.c_str());
|
||||
ILOG("NativeApp.init(): Launch shortcut parameter: %s", shortcut_param.c_str());
|
||||
|
||||
std::string app_name;
|
||||
std::string app_nice_name;
|
||||
std::string version;
|
||||
bool landscape;
|
||||
|
||||
net::Init();
|
||||
|
||||
NativeGetAppInfo(&app_name, &app_nice_name, &landscape, &version);
|
||||
|
||||
// If shortcut_param is not empty, pass it as additional varargs argument to NativeInit() method.
|
||||
// NativeInit() is expected to treat extra argument as boot_filename, which in turn will start game immediately.
|
||||
// NOTE: Will only work if ppsspp started from Activity.onCreate(). Won't work if ppsspp app start from onResume().
|
||||
|
||||
if (shortcut_param.empty()) {
|
||||
const char *argv[2] = {app_name.c_str(), 0};
|
||||
NativeInit(1, argv, user_data_path.c_str(), externalDir.c_str(), installID.c_str());
|
||||
}
|
||||
else {
|
||||
const char *argv[3] = {app_name.c_str(), shortcut_param.c_str(), 0};
|
||||
NativeInit(2, argv, user_data_path.c_str(), externalDir.c_str(), installID.c_str());
|
||||
}
|
||||
|
||||
ILOG("NativeApp.init() -- end");
|
||||
}
|
||||
|
||||
extern "C" void Java_com_henrikrydgard_libnative_NativeApp_audioInit(JNIEnv *, jclass) {
|
||||
sampleRate = optimalSampleRate;
|
||||
if (NativeQueryConfig("force44khz") != "0" || optimalSampleRate == 0) {
|
||||
sampleRate = 44100;
|
||||
}
|
||||
if (optimalFramesPerBuffer > 0) {
|
||||
framesPerBuffer = optimalFramesPerBuffer;
|
||||
} else {
|
||||
framesPerBuffer = 512;
|
||||
}
|
||||
|
||||
// Some devices have totally bonkers buffer sizes like 8192. They will have terrible latency anyway, so to avoid having to
|
||||
// create extra smart buffering code, we'll just let their regular mixer deal with it, missing the fast path (as if they had one...)
|
||||
if (framesPerBuffer > 512) {
|
||||
framesPerBuffer = 512;
|
||||
sampleRate = 44100;
|
||||
}
|
||||
|
||||
ILOG("NativeApp.audioInit() -- Using OpenSL audio! frames/buffer: %i optimal sr: %i actual sr: %i", optimalFramesPerBuffer, optimalSampleRate, sampleRate);
|
||||
AndroidAudio_Init(&NativeMix, library_path, framesPerBuffer, sampleRate);
|
||||
}
|
||||
|
||||
extern "C" void Java_com_henrikrydgard_libnative_NativeApp_audioShutdown(JNIEnv *, jclass) {
|
||||
AndroidAudio_Shutdown();
|
||||
}
|
||||
|
||||
extern "C" void Java_com_henrikrydgard_libnative_NativeApp_resume(JNIEnv *, jclass) {
|
||||
ILOG("NativeApp.resume() - resuming audio");
|
||||
AndroidAudio_Resume();
|
||||
}
|
||||
|
||||
extern "C" void Java_com_henrikrydgard_libnative_NativeApp_pause(JNIEnv *, jclass) {
|
||||
ILOG("NativeApp.pause() - pausing audio");
|
||||
AndroidAudio_Pause();
|
||||
}
|
||||
|
||||
extern "C" void Java_com_henrikrydgard_libnative_NativeApp_shutdown(JNIEnv *, jclass) {
|
||||
ILOG("NativeApp.shutdown() -- begin");
|
||||
NativeShutdown();
|
||||
VFSShutdown();
|
||||
net::Shutdown();
|
||||
ILOG("NativeApp.shutdown() -- end");
|
||||
}
|
||||
|
||||
static jmethodID postCommand;
|
||||
|
||||
extern "C" void Java_com_henrikrydgard_libnative_NativeRenderer_displayInit(JNIEnv * env, jobject obj) {
|
||||
ILOG("NativeApp.displayInit()");
|
||||
if (!renderer_inited) {
|
||||
NativeInitGraphics();
|
||||
renderer_inited = true;
|
||||
} else {
|
||||
NativeDeviceLost(); // ???
|
||||
ILOG("displayInit: NativeDeviceLost completed.");
|
||||
}
|
||||
|
||||
DLOG("(Re)-fetching method ID to postCommand...");
|
||||
postCommand = env->GetMethodID(env->GetObjectClass(obj), "postCommand", "(Ljava/lang/String;Ljava/lang/String;)V");
|
||||
}
|
||||
|
||||
extern "C" void Java_com_henrikrydgard_libnative_NativeRenderer_displayResize(JNIEnv *, jobject clazz, jint w, jint h, jint dpi, jfloat refreshRate) {
|
||||
ILOG("NativeApp.displayResize(%i x %i, dpi=%i, refresh=%0.2f)", w, h, dpi, refreshRate);
|
||||
|
||||
g_dpi = dpi;
|
||||
g_dpi_scale = 240.0f / (float)g_dpi;
|
||||
|
||||
pixel_xres = w;
|
||||
pixel_yres = h;
|
||||
dp_xres = pixel_xres * g_dpi_scale;
|
||||
dp_yres = pixel_yres * g_dpi_scale;
|
||||
dp_xscale = (float)dp_xres / pixel_xres;
|
||||
dp_yscale = (float)dp_yres / pixel_yres;
|
||||
display_hz = refreshRate;
|
||||
|
||||
NativeResized();
|
||||
}
|
||||
|
||||
extern "C" void Java_com_henrikrydgard_libnative_NativeRenderer_displayRender(JNIEnv *env, jobject obj) {
|
||||
static bool hasSetThreadName = false;
|
||||
if (!hasSetThreadName) {
|
||||
hasSetThreadName = true;
|
||||
setCurrentThreadName("AndroidRender");
|
||||
}
|
||||
|
||||
if (renderer_inited) {
|
||||
// TODO: Look into if these locks are a perf loss
|
||||
{
|
||||
lock_guard guard(input_state.lock);
|
||||
|
||||
input_state.pad_lstick_x = left_joystick_x_async;
|
||||
input_state.pad_lstick_y = left_joystick_y_async;
|
||||
input_state.pad_rstick_x = right_joystick_x_async;
|
||||
input_state.pad_rstick_y = right_joystick_y_async;
|
||||
|
||||
UpdateInputState(&input_state);
|
||||
}
|
||||
NativeUpdate(input_state);
|
||||
|
||||
{
|
||||
lock_guard guard(input_state.lock);
|
||||
EndInputState(&input_state);
|
||||
}
|
||||
|
||||
NativeRender();
|
||||
time_update();
|
||||
} else {
|
||||
ELOG("BAD: Ended up in nativeRender even though app has quit.%s", "");
|
||||
// Shouldn't really get here. Let's draw magenta.
|
||||
glDepthMask(GL_TRUE);
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
glClearColor(1.0, 0.0, 1.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
}
|
||||
|
||||
lock_guard guard(frameCommandLock);
|
||||
while (!frameCommands.empty()) {
|
||||
FrameCommand frameCmd;
|
||||
frameCmd = frameCommands.front();
|
||||
frameCommands.pop();
|
||||
|
||||
DLOG("frameCommand %s %s", frameCmd.command.c_str(), frameCmd.params.c_str());
|
||||
|
||||
jstring cmd = env->NewStringUTF(frameCmd.command.c_str());
|
||||
jstring param = env->NewStringUTF(frameCmd.params.c_str());
|
||||
env->CallVoidMethod(obj, postCommand, cmd, param);
|
||||
env->DeleteLocalRef(cmd);
|
||||
env->DeleteLocalRef(param);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void Java_com_henrikrydgard_libnative_NativeRenderer_displayShutdown(JNIEnv *env, jobject obj) {
|
||||
if (renderer_inited) {
|
||||
NativeDeviceLost();
|
||||
ILOG("NativeDeviceLost completed.");
|
||||
NativeShutdownGraphics();
|
||||
renderer_inited = false;
|
||||
NativeMessageReceived("recreateviews", "");
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" jboolean JNICALL Java_com_henrikrydgard_libnative_NativeApp_touch
|
||||
(JNIEnv *, jclass, float x, float y, int code, int pointerId) {
|
||||
float scaledX = x * dp_xscale;
|
||||
float scaledY = y * dp_yscale;
|
||||
|
||||
TouchInput touch;
|
||||
touch.id = pointerId;
|
||||
touch.x = scaledX;
|
||||
touch.y = scaledY;
|
||||
touch.flags = code;
|
||||
if (code & 2) {
|
||||
input_state.pointer_down[pointerId] = true;
|
||||
} else if (code & 4) {
|
||||
input_state.pointer_down[pointerId] = false;
|
||||
}
|
||||
|
||||
bool retval = NativeTouch(touch);
|
||||
{
|
||||
lock_guard guard(input_state.lock);
|
||||
if (pointerId >= MAX_POINTERS) {
|
||||
ELOG("Too many pointers: %i", pointerId);
|
||||
return false; // We ignore 8+ pointers entirely.
|
||||
}
|
||||
input_state.pointer_x[pointerId] = scaledX;
|
||||
input_state.pointer_y[pointerId] = scaledY;
|
||||
input_state.mouse_valid = true;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
extern "C" jboolean Java_com_henrikrydgard_libnative_NativeApp_keyDown(JNIEnv *, jclass, jint deviceId, jint key, jboolean isRepeat) {
|
||||
KeyInput keyInput;
|
||||
keyInput.deviceId = deviceId;
|
||||
keyInput.keyCode = key;
|
||||
keyInput.flags = KEY_DOWN;
|
||||
if (isRepeat) {
|
||||
keyInput.flags |= KEY_IS_REPEAT;
|
||||
}
|
||||
return NativeKey(keyInput);
|
||||
}
|
||||
|
||||
extern "C" jboolean Java_com_henrikrydgard_libnative_NativeApp_keyUp(JNIEnv *, jclass, jint deviceId, jint key) {
|
||||
KeyInput keyInput;
|
||||
keyInput.deviceId = deviceId;
|
||||
keyInput.keyCode = key;
|
||||
keyInput.flags = KEY_UP;
|
||||
return NativeKey(keyInput);
|
||||
}
|
||||
|
||||
extern "C" void Java_com_henrikrydgard_libnative_NativeApp_beginJoystickEvent(
|
||||
JNIEnv *env, jclass) {
|
||||
// mutex lock?
|
||||
}
|
||||
|
||||
extern "C" jboolean Java_com_henrikrydgard_libnative_NativeApp_joystickAxis(
|
||||
JNIEnv *env, jclass, jint deviceId, jint axisId, jfloat value) {
|
||||
if (!renderer_inited)
|
||||
return false;
|
||||
switch (axisId) {
|
||||
case JOYSTICK_AXIS_X:
|
||||
left_joystick_x_async = value;
|
||||
break;
|
||||
case JOYSTICK_AXIS_Y:
|
||||
left_joystick_y_async = -value;
|
||||
break;
|
||||
case JOYSTICK_AXIS_Z:
|
||||
right_joystick_x_async = value;
|
||||
break;
|
||||
case JOYSTICK_AXIS_RZ:
|
||||
right_joystick_y_async = -value;
|
||||
break;
|
||||
case JOYSTICK_AXIS_HAT_X:
|
||||
hat_joystick_x_async = value;
|
||||
break;
|
||||
case JOYSTICK_AXIS_HAT_Y:
|
||||
hat_joystick_y_async = -value;
|
||||
break;
|
||||
}
|
||||
|
||||
AxisInput axis;
|
||||
axis.axisId = axisId;
|
||||
axis.deviceId = deviceId;
|
||||
axis.value = value;
|
||||
return NativeAxis(axis);
|
||||
}
|
||||
|
||||
extern "C" void Java_com_henrikrydgard_libnative_NativeApp_endJoystickEvent(
|
||||
JNIEnv *env, jclass) {
|
||||
// mutex unlock?
|
||||
}
|
||||
|
||||
|
||||
extern "C" jboolean Java_com_henrikrydgard_libnative_NativeApp_mouseWheelEvent(
|
||||
JNIEnv *env, jclass, jint stick, jfloat x, jfloat y) {
|
||||
// TODO: Support mousewheel for android
|
||||
return true;
|
||||
}
|
||||
|
||||
extern "C" jboolean JNICALL Java_com_henrikrydgard_libnative_NativeApp_accelerometer(JNIEnv *, jclass, float x, float y, float z) {
|
||||
if (!renderer_inited)
|
||||
return false;
|
||||
|
||||
// Theoretically this needs locking but I doubt it matters. Worst case, the X
|
||||
// from one "sensor frame" will be used together with Y from the next.
|
||||
// Should look into quantization though, for compressed movement storage.
|
||||
input_state.accelerometer_valid = true;
|
||||
input_state.acc.x = x;
|
||||
input_state.acc.y = y;
|
||||
input_state.acc.z = z;
|
||||
|
||||
AxisInput axis;
|
||||
axis.deviceId = DEVICE_ID_ACCELEROMETER;
|
||||
axis.flags = 0;
|
||||
|
||||
axis.axisId = JOYSTICK_AXIS_ACCELEROMETER_X;
|
||||
axis.value = x;
|
||||
bool retvalX = NativeAxis(axis);
|
||||
|
||||
axis.axisId = JOYSTICK_AXIS_ACCELEROMETER_Y;
|
||||
axis.value = y;
|
||||
bool retvalY = NativeAxis(axis);
|
||||
|
||||
axis.axisId = JOYSTICK_AXIS_ACCELEROMETER_Z;
|
||||
axis.value = z;
|
||||
bool retvalZ = NativeAxis(axis);
|
||||
|
||||
return retvalX || retvalY || retvalZ;
|
||||
}
|
||||
|
||||
extern "C" void Java_com_henrikrydgard_libnative_NativeApp_sendMessage(JNIEnv *env, jclass, jstring message, jstring param) {
|
||||
std::string msg = GetJavaString(env, message);
|
||||
std::string prm = GetJavaString(env, param);
|
||||
|
||||
if (msg == "moga") {
|
||||
mogaVersion = prm;
|
||||
}
|
||||
NativeMessageReceived(msg.c_str(), prm.c_str());
|
||||
}
|
8
ext/native/android/app-android.h
Normal file
8
ext/native/android/app-android.h
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "input/keycodes.h"
|
||||
|
||||
// Compatability we alias the keycodes
|
||||
// since native's keycodes are based on
|
||||
// android keycodes.
|
||||
typedef enum _keycode_t AndroidKeyCodes;
|
92
ext/native/android/build.xml
Normal file
92
ext/native/android/build.xml
Normal file
@ -0,0 +1,92 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="android" default="help">
|
||||
|
||||
<!-- The local.properties file is created and updated by the 'android' tool.
|
||||
It contains the path to the SDK. It should *NOT* be checked into
|
||||
Version Control Systems. -->
|
||||
<property file="local.properties" />
|
||||
|
||||
<!-- The ant.properties file can be created by you. It is only edited by the
|
||||
'android' tool to add properties to it.
|
||||
This is the place to change some Ant specific build properties.
|
||||
Here are some properties you may want to change/update:
|
||||
|
||||
source.dir
|
||||
The name of the source directory. Default is 'src'.
|
||||
out.dir
|
||||
The name of the output directory. Default is 'bin'.
|
||||
|
||||
For other overridable properties, look at the beginning of the rules
|
||||
files in the SDK, at tools/ant/build.xml
|
||||
|
||||
Properties related to the SDK location or the project target should
|
||||
be updated using the 'android' tool with the 'update' action.
|
||||
|
||||
This file is an integral part of the build system for your
|
||||
application and should be checked into Version Control Systems.
|
||||
|
||||
-->
|
||||
<property file="ant.properties" />
|
||||
|
||||
<!-- if sdk.dir was not set from one of the property file, then
|
||||
get it from the ANDROID_HOME env var.
|
||||
This must be done before we load project.properties since
|
||||
the proguard config can use sdk.dir -->
|
||||
<property environment="env" />
|
||||
<condition property="sdk.dir" value="${env.ANDROID_HOME}">
|
||||
<isset property="env.ANDROID_HOME" />
|
||||
</condition>
|
||||
|
||||
<!-- The project.properties file is created and updated by the 'android'
|
||||
tool, as well as ADT.
|
||||
|
||||
This contains project specific properties such as project target, and library
|
||||
dependencies. Lower level build properties are stored in ant.properties
|
||||
(or in .classpath for Eclipse projects).
|
||||
|
||||
This file is an integral part of the build system for your
|
||||
application and should be checked into Version Control Systems. -->
|
||||
<loadproperties srcFile="project.properties" />
|
||||
|
||||
<!-- quick check on sdk.dir -->
|
||||
<fail
|
||||
message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
|
||||
unless="sdk.dir"
|
||||
/>
|
||||
|
||||
<!--
|
||||
Import per project custom build rules if present at the root of the project.
|
||||
This is the place to put custom intermediary targets such as:
|
||||
-pre-build
|
||||
-pre-compile
|
||||
-post-compile (This is typically used for code obfuscation.
|
||||
Compiled code location: ${out.classes.absolute.dir}
|
||||
If this is not done in place, override ${out.dex.input.absolute.dir})
|
||||
-post-package
|
||||
-post-build
|
||||
-pre-clean
|
||||
-->
|
||||
<import file="custom_rules.xml" optional="true" />
|
||||
|
||||
<!-- Import the actual build file.
|
||||
|
||||
To customize existing targets, there are two options:
|
||||
- Customize only one target:
|
||||
- copy/paste the target into this file, *before* the
|
||||
<import> task.
|
||||
- customize it to your needs.
|
||||
- Customize the whole content of build.xml
|
||||
- copy/paste the content of the rules files (minus the top node)
|
||||
into this file, replacing the <import> task.
|
||||
- customize to your needs.
|
||||
|
||||
***********************
|
||||
****** IMPORTANT ******
|
||||
***********************
|
||||
In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
|
||||
in order to avoid having your file be overridden by tools such as "android update project"
|
||||
-->
|
||||
<!-- version-tag: 1 -->
|
||||
<import file="${sdk.dir}/tools/ant/build.xml" />
|
||||
|
||||
</project>
|
BIN
ext/native/android/libs/com.bda.controller.jar
Normal file
BIN
ext/native/android/libs/com.bda.controller.jar
Normal file
Binary file not shown.
190
ext/native/android/native-audio-so.cpp
Normal file
190
ext/native/android/native-audio-so.cpp
Normal file
@ -0,0 +1,190 @@
|
||||
// Minimal audio streaming using OpenSL.
|
||||
//
|
||||
// Loosely based on the Android NDK sample code.
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// for native audio
|
||||
#include <SLES/OpenSLES.h>
|
||||
#include <SLES/OpenSLES_Android.h>
|
||||
|
||||
#include "../base/logging.h"
|
||||
#include "native-audio-so.h"
|
||||
|
||||
// This is kinda ugly, but for simplicity I've left these as globals just like in the sample,
|
||||
// as there's not really any use case for this where we have multiple audio devices yet.
|
||||
|
||||
// engine interfaces
|
||||
static SLObjectItf engineObject;
|
||||
static SLEngineItf engineEngine;
|
||||
static SLObjectItf outputMixObject;
|
||||
|
||||
// buffer queue player interfaces
|
||||
static SLObjectItf bqPlayerObject = NULL;
|
||||
static SLPlayItf bqPlayerPlay;
|
||||
static SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue;
|
||||
static SLMuteSoloItf bqPlayerMuteSolo;
|
||||
static SLVolumeItf bqPlayerVolume;
|
||||
|
||||
// Double buffering.
|
||||
static short *buffer[2];
|
||||
static int curBuffer = 0;
|
||||
static int framesPerBuffer;
|
||||
int sampleRate;
|
||||
|
||||
static AndroidAudioCallback audioCallback;
|
||||
|
||||
// This callback handler is called every time a buffer finishes playing.
|
||||
// The documentation available is very unclear about how to best manage buffers.
|
||||
// I've chosen to this approach: Instantly enqueue a buffer that was rendered to the last time,
|
||||
// and then render the next. Hopefully it's okay to spend time in this callback after having enqueued.
|
||||
static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context) {
|
||||
if (bq != bqPlayerBufferQueue) {
|
||||
ELOG("Wrong bq!");
|
||||
return;
|
||||
}
|
||||
|
||||
int renderedFrames = audioCallback(buffer[curBuffer], framesPerBuffer);
|
||||
|
||||
int sizeInBytes = framesPerBuffer * 2 * sizeof(short);
|
||||
int byteCount = (framesPerBuffer - renderedFrames) * 4;
|
||||
if (byteCount > 0) {
|
||||
memset(buffer[curBuffer] + renderedFrames * 2, 0, byteCount);
|
||||
}
|
||||
SLresult result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, buffer[curBuffer], sizeInBytes);
|
||||
|
||||
// Comment from sample code:
|
||||
// the most likely other result is SL_RESULT_BUFFER_INSUFFICIENT,
|
||||
// which for this code example would indicate a programming error
|
||||
if (result != SL_RESULT_SUCCESS) {
|
||||
ELOG("OpenSL ES: Failed to enqueue! %i %i", renderedFrames, sizeInBytes);
|
||||
}
|
||||
|
||||
curBuffer ^= 1; // Switch buffer
|
||||
}
|
||||
|
||||
// create the engine and output mix objects
|
||||
bool OpenSLWrap_Init(AndroidAudioCallback cb, int _FramesPerBuffer, int _SampleRate) {
|
||||
audioCallback = cb;
|
||||
framesPerBuffer = _FramesPerBuffer;
|
||||
if (framesPerBuffer == 0)
|
||||
framesPerBuffer = 256;
|
||||
if (framesPerBuffer < 32)
|
||||
framesPerBuffer = 32;
|
||||
sampleRate = _SampleRate;
|
||||
if (sampleRate != 44100 && sampleRate != 48000) {
|
||||
ELOG("Invalid sample rate %i - choosing 44100", sampleRate);
|
||||
sampleRate = 44100;
|
||||
}
|
||||
|
||||
buffer[0] = new short[framesPerBuffer * 2];
|
||||
buffer[1] = new short[framesPerBuffer * 2];
|
||||
|
||||
SLresult result;
|
||||
// create engine
|
||||
result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
|
||||
assert(SL_RESULT_SUCCESS == result);
|
||||
result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
|
||||
assert(SL_RESULT_SUCCESS == result);
|
||||
result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
|
||||
assert(SL_RESULT_SUCCESS == result);
|
||||
result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, 0, 0);
|
||||
assert(SL_RESULT_SUCCESS == result);
|
||||
result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
|
||||
assert(SL_RESULT_SUCCESS == result);
|
||||
|
||||
SLuint32 sr = SL_SAMPLINGRATE_44_1;
|
||||
if (sampleRate == 48000) {
|
||||
sr = SL_SAMPLINGRATE_48;
|
||||
}
|
||||
|
||||
SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};
|
||||
SLDataFormat_PCM format_pcm = {
|
||||
SL_DATAFORMAT_PCM,
|
||||
2,
|
||||
sr,
|
||||
SL_PCMSAMPLEFORMAT_FIXED_16,
|
||||
SL_PCMSAMPLEFORMAT_FIXED_16,
|
||||
SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT,
|
||||
SL_BYTEORDER_LITTLEENDIAN
|
||||
};
|
||||
|
||||
SLDataSource audioSrc = {&loc_bufq, &format_pcm};
|
||||
|
||||
// configure audio sink
|
||||
SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObject};
|
||||
SLDataSink audioSnk = {&loc_outmix, NULL};
|
||||
|
||||
// create audio player
|
||||
const SLInterfaceID ids[2] = {SL_IID_BUFFERQUEUE, SL_IID_VOLUME};
|
||||
const SLboolean req[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
|
||||
result = (*engineEngine)->CreateAudioPlayer(engineEngine, &bqPlayerObject, &audioSrc, &audioSnk, 2, ids, req);
|
||||
assert(SL_RESULT_SUCCESS == result);
|
||||
|
||||
result = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE);
|
||||
assert(SL_RESULT_SUCCESS == result);
|
||||
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_PLAY, &bqPlayerPlay);
|
||||
assert(SL_RESULT_SUCCESS == result);
|
||||
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_BUFFERQUEUE,
|
||||
&bqPlayerBufferQueue);
|
||||
assert(SL_RESULT_SUCCESS == result);
|
||||
result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, NULL);
|
||||
assert(SL_RESULT_SUCCESS == result);
|
||||
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_VOLUME, &bqPlayerVolume);
|
||||
assert(SL_RESULT_SUCCESS == result);
|
||||
result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING);
|
||||
assert(SL_RESULT_SUCCESS == result);
|
||||
|
||||
// Render and enqueue a first buffer. (or should we just play the buffer empty?)
|
||||
curBuffer = 0;
|
||||
audioCallback(buffer[curBuffer], framesPerBuffer);
|
||||
|
||||
result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, buffer[curBuffer], sizeof(buffer[curBuffer]));
|
||||
if (SL_RESULT_SUCCESS != result) {
|
||||
return false;
|
||||
}
|
||||
curBuffer ^= 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
// shut down the native audio system
|
||||
void OpenSLWrap_Shutdown() {
|
||||
SLresult result;
|
||||
ILOG("OpenSLWrap_Shutdown - stopping playback");
|
||||
result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_STOPPED);
|
||||
if (SL_RESULT_SUCCESS != result) {
|
||||
ELOG("SetPlayState failed");
|
||||
}
|
||||
|
||||
ILOG("OpenSLWrap_Shutdown - deleting player object");
|
||||
|
||||
if (bqPlayerObject != NULL) {
|
||||
(*bqPlayerObject)->Destroy(bqPlayerObject);
|
||||
bqPlayerObject = NULL;
|
||||
bqPlayerPlay = NULL;
|
||||
bqPlayerBufferQueue = NULL;
|
||||
bqPlayerMuteSolo = NULL;
|
||||
bqPlayerVolume = NULL;
|
||||
}
|
||||
|
||||
ILOG("OpenSLWrap_Shutdown - deleting mix object");
|
||||
|
||||
if (outputMixObject != NULL) {
|
||||
(*outputMixObject)->Destroy(outputMixObject);
|
||||
outputMixObject = NULL;
|
||||
}
|
||||
|
||||
ILOG("OpenSLWrap_Shutdown - deleting engine object");
|
||||
|
||||
if (engineObject != NULL) {
|
||||
(*engineObject)->Destroy(engineObject);
|
||||
engineObject = NULL;
|
||||
engineEngine = NULL;
|
||||
}
|
||||
delete [] buffer[0];
|
||||
delete [] buffer[1];
|
||||
ILOG("OpenSLWrap_Shutdown - finished");
|
||||
}
|
||||
|
6
ext/native/android/native-audio-so.h
Normal file
6
ext/native/android/native-audio-so.h
Normal file
@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
typedef int (*AndroidAudioCallback)(short *buffer, int num_samples);
|
||||
|
||||
bool OpenSLWrap_Init(AndroidAudioCallback cb, int _FramesPerBuffer, int _SampleRate);
|
||||
void OpenSLWrap_Shutdown();
|
71
ext/native/android/native_audio.cpp
Normal file
71
ext/native/android/native_audio.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
#include "base/logging.h"
|
||||
#include "android/native_audio.h"
|
||||
#include "android/native-audio-so.h"
|
||||
|
||||
struct AudioState {
|
||||
void *so;
|
||||
AndroidAudioCallback callback;
|
||||
bool playing;
|
||||
int frames_per_buffer;
|
||||
int sample_rate;
|
||||
};
|
||||
|
||||
static AudioState *state = 0;
|
||||
|
||||
bool AndroidAudio_Init(AndroidAudioCallback callback, std::string libraryDir, int optimalFramesPerBuffer, int optimalSampleRate) {
|
||||
if (state != 0) {
|
||||
ELOG("Audio state already exists");
|
||||
return false;
|
||||
}
|
||||
|
||||
state = new AudioState();
|
||||
state->callback = callback;
|
||||
state->playing = false;
|
||||
state->frames_per_buffer = optimalFramesPerBuffer ? optimalFramesPerBuffer : 256;
|
||||
state->sample_rate = optimalSampleRate ? optimalSampleRate : 44100;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AndroidAudio_Resume() {
|
||||
if (!state) {
|
||||
ELOG("Audio was shutdown, cannot resume!");
|
||||
return false;
|
||||
}
|
||||
if (!state->playing) {
|
||||
ILOG("Calling OpenSLWrap_Init_T...");
|
||||
bool init_retval = OpenSLWrap_Init(state->callback, state->frames_per_buffer, state->sample_rate);
|
||||
ILOG("Returned from OpenSLWrap_Init_T");
|
||||
state->playing = true;
|
||||
return init_retval;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AndroidAudio_Pause() {
|
||||
if (!state) {
|
||||
ELOG("Audio was shutdown, cannot pause!");
|
||||
return false;
|
||||
}
|
||||
if (state->playing) {
|
||||
ILOG("Calling OpenSLWrap_Shutdown_T...");
|
||||
OpenSLWrap_Shutdown();
|
||||
ILOG("Returned from OpenSLWrap_Shutdown_T ...");
|
||||
state->playing = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void AndroidAudio_Shutdown() {
|
||||
if (!state) {
|
||||
ELOG("Audio already shutdown!");
|
||||
return;
|
||||
}
|
||||
if (state->playing) {
|
||||
ELOG("Should not shut down when playing! Something is wrong!");
|
||||
}
|
||||
delete state;
|
||||
state = 0;
|
||||
ILOG("OpenSLWrap completely unloaded.");
|
||||
}
|
16
ext/native/android/native_audio.h
Normal file
16
ext/native/android/native_audio.h
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "native-audio-so.h"
|
||||
#include <string>
|
||||
|
||||
// This is the file you should include from your program. It dynamically loads
|
||||
// the native_audio.so shared object and sets up the function pointers.
|
||||
|
||||
// Do not call this if you have detected that the android version is below
|
||||
// 2.2, as it will fail miserably.
|
||||
|
||||
// It's okay for optimalFramesPerBuffer and optimalSampleRate to be 0. Defaults will be used.
|
||||
bool AndroidAudio_Init(AndroidAudioCallback cb, std::string libraryDir, int optimalFramesPerBuffer, int optimalSampleRate);
|
||||
bool AndroidAudio_Pause();
|
||||
bool AndroidAudio_Resume();
|
||||
void AndroidAudio_Shutdown();
|
20
ext/native/android/proguard-project.txt
Normal file
20
ext/native/android/proguard-project.txt
Normal file
@ -0,0 +1,20 @@
|
||||
# To enable ProGuard in your project, edit project.properties
|
||||
# to define the proguard.config property as described in that file.
|
||||
#
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in ${sdk.dir}/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the ProGuard
|
||||
# include property in project.properties.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
15
ext/native/android/project.properties
Normal file
15
ext/native/android/project.properties
Normal file
@ -0,0 +1,15 @@
|
||||
# This file is automatically generated by Android Tools.
|
||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||
#
|
||||
# This file must be checked in Version Control Systems.
|
||||
#
|
||||
# To customize properties used by the Ant build system edit
|
||||
# "ant.properties", and override values to adapt the script to your
|
||||
# project structure.
|
||||
#
|
||||
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
|
||||
#proguard.config=${sdk.dir}\tools\proguard\proguard-android.txt:proguard-project.txt
|
||||
|
||||
# Project target.
|
||||
target=android-22
|
||||
android.library=true
|
BIN
ext/native/android/res/drawable-hdpi/ic_launcher.png
Normal file
BIN
ext/native/android/res/drawable-hdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.2 KiB |
BIN
ext/native/android/res/drawable-ldpi/ic_launcher.png
Normal file
BIN
ext/native/android/res/drawable-ldpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
BIN
ext/native/android/res/drawable-mdpi/ic_launcher.png
Normal file
BIN
ext/native/android/res/drawable-mdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.1 KiB |
BIN
ext/native/android/res/drawable-xhdpi/ic_launcher.png
Normal file
BIN
ext/native/android/res/drawable-xhdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
@ -0,0 +1,26 @@
|
||||
package com.henrikrydgard.libnative;
|
||||
import android.media.AudioManager;
|
||||
import android.media.AudioManager.OnAudioFocusChangeListener;
|
||||
|
||||
public class AudioFocusChangeListener implements OnAudioFocusChangeListener{
|
||||
// not used right now, but we may need to use it sometime. So just store it
|
||||
// for now.
|
||||
private boolean hasAudioFocus = false;
|
||||
|
||||
@Override
|
||||
public void onAudioFocusChange(int focusChange) {
|
||||
switch (focusChange){
|
||||
case AudioManager.AUDIOFOCUS_GAIN:
|
||||
hasAudioFocus = true;
|
||||
break;
|
||||
|
||||
case AudioManager.AUDIOFOCUS_LOSS:
|
||||
hasAudioFocus = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasAudioFocus() {
|
||||
return hasAudioFocus;
|
||||
}
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
package com.henrikrydgard.libnative;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.view.InputDevice;
|
||||
import android.view.InputDevice.MotionRange;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
|
||||
public class InputDeviceState {
|
||||
private static final String TAG = "InputDeviceState";
|
||||
|
||||
private static final int deviceId = NativeApp.DEVICE_ID_PAD_0;
|
||||
|
||||
private InputDevice mDevice;
|
||||
private int[] mAxes;
|
||||
|
||||
InputDevice getDevice() { return mDevice; }
|
||||
|
||||
@TargetApi(19)
|
||||
void logAdvanced(InputDevice device) {
|
||||
Log.i(TAG, "Vendor ID:" + device.getVendorId() + " productId: " + device.getProductId());
|
||||
}
|
||||
|
||||
public InputDeviceState(InputDevice device) {
|
||||
mDevice = device;
|
||||
int numAxes = 0;
|
||||
for (MotionRange range : device.getMotionRanges()) {
|
||||
if ((range.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
|
||||
numAxes += 1;
|
||||
}
|
||||
}
|
||||
|
||||
mAxes = new int[numAxes];
|
||||
|
||||
int i = 0;
|
||||
for (MotionRange range : device.getMotionRanges()) {
|
||||
if ((range.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
|
||||
mAxes[i++] = range.getAxis();
|
||||
}
|
||||
}
|
||||
|
||||
Log.i(TAG, "Registering input device with " + numAxes + " axes: " + device.getName());
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
logAdvanced(device);
|
||||
}
|
||||
NativeApp.sendMessage("inputDeviceConnected", device.getName());
|
||||
}
|
||||
|
||||
public static float ProcessAxis(InputDevice.MotionRange range, float axisvalue) {
|
||||
float absaxisvalue = Math.abs(axisvalue);
|
||||
float deadzone = range.getFlat();
|
||||
if (absaxisvalue <= deadzone) {
|
||||
return 0.0f;
|
||||
}
|
||||
float normalizedvalue;
|
||||
if (axisvalue < 0.0f) {
|
||||
normalizedvalue = absaxisvalue / range.getMin();
|
||||
} else {
|
||||
normalizedvalue = absaxisvalue / range.getMax();
|
||||
}
|
||||
|
||||
return normalizedvalue;
|
||||
}
|
||||
|
||||
public boolean onKeyDown(KeyEvent event) {
|
||||
int keyCode = event.getKeyCode();
|
||||
boolean repeat = event.getRepeatCount() > 0;
|
||||
return NativeApp.keyDown(deviceId, keyCode, repeat);
|
||||
}
|
||||
|
||||
public boolean onKeyUp(KeyEvent event) {
|
||||
int keyCode = event.getKeyCode();
|
||||
return NativeApp.keyUp(deviceId, keyCode);
|
||||
}
|
||||
|
||||
public boolean onJoystickMotion(MotionEvent event) {
|
||||
if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) == 0) {
|
||||
return false;
|
||||
}
|
||||
NativeApp.beginJoystickEvent();
|
||||
for (int i = 0; i < mAxes.length; i++) {
|
||||
int axisId = mAxes[i];
|
||||
float value = event.getAxisValue(axisId);
|
||||
// TODO: Use processAxis or move that to the C++ code
|
||||
NativeApp.joystickAxis(deviceId, axisId, value);
|
||||
}
|
||||
NativeApp.endJoystickEvent();
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package com.henrikrydgard.libnative;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.util.UUID;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
|
||||
public class Installation {
|
||||
private static String sID = null;
|
||||
private static final String INSTALLATION = "INSTALLATION";
|
||||
|
||||
public synchronized static String id(Context context) {
|
||||
if (sID == null) {
|
||||
File installation = new File(context.getFilesDir(), INSTALLATION);
|
||||
try {
|
||||
if (!installation.exists())
|
||||
writeInstallationFile(installation);
|
||||
sID = readInstallationFile(installation);
|
||||
} catch (Exception e) {
|
||||
// We can't even open a file for writing? Then we can't get a unique-ish installation id.
|
||||
return "BROKENAPPUSERFILESYSTEM";
|
||||
}
|
||||
}
|
||||
return sID;
|
||||
}
|
||||
|
||||
private static String readInstallationFile(File installation) throws IOException {
|
||||
RandomAccessFile f = new RandomAccessFile(installation, "r");
|
||||
byte[] bytes = new byte[(int) f.length()];
|
||||
f.readFully(bytes);
|
||||
f.close();
|
||||
return new String(bytes);
|
||||
}
|
||||
|
||||
private static void writeInstallationFile(File installation) throws IOException {
|
||||
FileOutputStream out = new FileOutputStream(installation);
|
||||
String id = UUID.randomUUID().toString();
|
||||
out.write(id.getBytes());
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
|
118
ext/native/android/src/com/henrikrydgard/libnative/MogaHack.java
Normal file
118
ext/native/android/src/com/henrikrydgard/libnative/MogaHack.java
Normal file
@ -0,0 +1,118 @@
|
||||
/**
|
||||
* Mupen64PlusAE, an N64 emulator for the Android platform
|
||||
*
|
||||
* Copyright (C) 2013 Paul Lamb
|
||||
*
|
||||
* This file is part of Mupen64PlusAE.
|
||||
*
|
||||
* Mupen64PlusAE is free software: you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Mupen64PlusAE is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Mupen64PlusAE. If
|
||||
* not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Paul Lamb
|
||||
*/
|
||||
package com.henrikrydgard.libnative;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
|
||||
import com.bda.controller.Controller;
|
||||
import com.bda.controller.IControllerService;
|
||||
|
||||
/**
|
||||
* Temporary hack for crash in MOGA library on Lollipop. This hack can be removed once MOGA fixes
|
||||
* their library. The actual issue is caused by the use of implicit service intents, which are
|
||||
* illegal in Lollipop, as seen in the logcat message below.
|
||||
*
|
||||
* <pre>
|
||||
* {@code Service Intent must be explicit: Intent { act=com.bda.controller.IControllerService } }
|
||||
* </pre>
|
||||
*
|
||||
* @see <a href="http://www.mogaanywhere.com/developers/">MOGA developer site</a>
|
||||
* @see <a href="http://commonsware.com/blog/2014/06/29/dealing-deprecations-bindservice.html">
|
||||
* Discussion on explicit intents</a>
|
||||
*/
|
||||
public class MogaHack
|
||||
{
|
||||
public static void init(Controller controller, Context context )
|
||||
{
|
||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT)
|
||||
{
|
||||
boolean mIsBound = false;
|
||||
java.lang.reflect.Field fIsBound = null;
|
||||
android.content.ServiceConnection mServiceConnection = null;
|
||||
java.lang.reflect.Field fServiceConnection = null;
|
||||
try
|
||||
{
|
||||
Class<?> cMogaController = controller.getClass();
|
||||
fIsBound = cMogaController.getDeclaredField( "mIsBound" );
|
||||
fIsBound.setAccessible( true );
|
||||
mIsBound = fIsBound.getBoolean( controller );
|
||||
fServiceConnection = cMogaController.getDeclaredField( "mServiceConnection" );
|
||||
fServiceConnection.setAccessible( true );
|
||||
mServiceConnection = ( android.content.ServiceConnection ) fServiceConnection.get( controller );
|
||||
}
|
||||
catch( NoSuchFieldException e )
|
||||
{
|
||||
Log.e( "MogaHack", "MOGA Lollipop Hack NoSuchFieldException (get)", e );
|
||||
}
|
||||
catch( IllegalAccessException e )
|
||||
{
|
||||
Log.e( "MogaHack", "MOGA Lollipop Hack IllegalAccessException (get)", e );
|
||||
}
|
||||
catch( IllegalArgumentException e )
|
||||
{
|
||||
Log.e( "MogaHack", "MOGA Lollipop Hack IllegalArgumentException (get)", e );
|
||||
}
|
||||
if( ( !mIsBound ) && ( mServiceConnection != null ) )
|
||||
{
|
||||
// Convert implicit intent to explicit intent, see http://stackoverflow.com/a/26318757
|
||||
Intent intent = new Intent( IControllerService.class.getName() );
|
||||
List<ResolveInfo> resolveInfos = context.getPackageManager().queryIntentServices( intent, 0 );
|
||||
if( resolveInfos == null || resolveInfos.size() != 1 )
|
||||
{
|
||||
// What? this doesn't do anything.
|
||||
// Log.e( "MogaHack", "Somebody is trying to intercept our intent. Disabling MOGA controller for security." );
|
||||
}
|
||||
ServiceInfo serviceInfo = resolveInfos.get( 0 ).serviceInfo;
|
||||
String packageName = serviceInfo.packageName;
|
||||
String className = serviceInfo.name;
|
||||
intent.setComponent( new ComponentName( packageName, className ) );
|
||||
|
||||
// Start the service explicitly
|
||||
context.startService( intent );
|
||||
context.bindService( intent, mServiceConnection, 1 );
|
||||
try
|
||||
{
|
||||
fIsBound.setBoolean( controller, true );
|
||||
}
|
||||
catch( IllegalAccessException e )
|
||||
{
|
||||
Log.e( "MogaHack", "MOGA Lollipop Hack IllegalAccessException (set)", e );
|
||||
}
|
||||
catch( IllegalArgumentException e )
|
||||
{
|
||||
Log.e( "MogaHack", "MOGA Lollipop Hack IllegalArgumentException (set)", e );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
controller.init();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,875 @@
|
||||
package com.henrikrydgard.libnative;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.UiModeManager;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.ConfigurationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Point;
|
||||
import android.media.AudioManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.Vibrator;
|
||||
import android.text.InputType;
|
||||
import android.util.Log;
|
||||
import android.view.Display;
|
||||
import android.view.Gravity;
|
||||
import android.view.InputDevice;
|
||||
import android.view.InputEvent;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnSystemUiVisibilityChangeListener;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.EditText;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.Toast;
|
||||
|
||||
public class NativeActivity extends Activity {
|
||||
// Remember to loadLibrary your JNI .so in a static {} block
|
||||
|
||||
// Adjust these as necessary
|
||||
private static String TAG = "NativeActivity";
|
||||
|
||||
// Allows us to skip a lot of initialization on secondary calls to onCreate.
|
||||
private static boolean initialized = false;
|
||||
|
||||
// Graphics and audio interfaces
|
||||
private NativeGLView mGLSurfaceView;
|
||||
protected NativeRenderer nativeRenderer;
|
||||
|
||||
private String shortcutParam = "";
|
||||
|
||||
public static String runCommand;
|
||||
public static String commandParameter;
|
||||
public static String installID;
|
||||
|
||||
// Remember settings for best audio latency
|
||||
private int optimalFramesPerBuffer;
|
||||
private int optimalSampleRate;
|
||||
|
||||
// audioFocusChangeListener to listen to changes in audio state
|
||||
private AudioFocusChangeListener audioFocusChangeListener;
|
||||
private AudioManager audioManager;
|
||||
|
||||
private Vibrator vibrator;
|
||||
|
||||
private boolean isXperiaPlay;
|
||||
|
||||
// Allow for multiple connected gamepads but just consider them the same for now.
|
||||
// Actually this is not entirely true, see the code.
|
||||
InputDeviceState inputPlayerA;
|
||||
InputDeviceState inputPlayerB;
|
||||
InputDeviceState inputPlayerC;
|
||||
String inputPlayerADesc;
|
||||
|
||||
// Functions for the app activity to override to change behaviour.
|
||||
|
||||
public boolean useLowProfileButtons() {
|
||||
return true;
|
||||
}
|
||||
|
||||
NativeRenderer getRenderer() {
|
||||
return nativeRenderer;
|
||||
}
|
||||
|
||||
@TargetApi(17)
|
||||
private void detectOptimalAudioSettings() {
|
||||
try {
|
||||
optimalFramesPerBuffer = Integer.parseInt(this.audioManager.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER));
|
||||
} catch (NumberFormatException e) {
|
||||
// Ignore, if we can't parse it it's bogus and zero is a fine value (means we couldn't detect it).
|
||||
}
|
||||
try {
|
||||
optimalSampleRate = Integer.parseInt(this.audioManager.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE));
|
||||
} catch (NumberFormatException e) {
|
||||
// Ignore, if we can't parse it it's bogus and zero is a fine value (means we couldn't detect it).
|
||||
}
|
||||
}
|
||||
|
||||
String getApplicationLibraryDir(ApplicationInfo application) {
|
||||
String libdir = null;
|
||||
try {
|
||||
// Starting from Android 2.3, nativeLibraryDir is available:
|
||||
Field field = ApplicationInfo.class.getField("nativeLibraryDir");
|
||||
libdir = (String) field.get(application);
|
||||
} catch (SecurityException e1) {
|
||||
} catch (NoSuchFieldException e1) {
|
||||
} catch (IllegalArgumentException e) {
|
||||
} catch (IllegalAccessException e) {
|
||||
}
|
||||
if (libdir == null) {
|
||||
// Fallback for Android < 2.3:
|
||||
libdir = application.dataDir + "/lib";
|
||||
}
|
||||
return libdir;
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
|
||||
void GetScreenSizeJB(Point size, boolean real) {
|
||||
WindowManager w = getWindowManager();
|
||||
if (real) {
|
||||
w.getDefaultDisplay().getRealSize(size);
|
||||
}
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
|
||||
void GetScreenSizeHC(Point size, boolean real) {
|
||||
WindowManager w = getWindowManager();
|
||||
if (real && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||
GetScreenSizeJB(size, real);
|
||||
} else {
|
||||
w.getDefaultDisplay().getSize(size);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void GetScreenSize(Point size) {
|
||||
boolean real = useImmersive();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
|
||||
GetScreenSizeHC(size, real);
|
||||
} else {
|
||||
WindowManager w = getWindowManager();
|
||||
Display d = w.getDefaultDisplay();
|
||||
size.x = d.getWidth();
|
||||
size.y = d.getHeight();
|
||||
}
|
||||
}
|
||||
|
||||
public void setShortcutParam(String shortcutParam) {
|
||||
this.shortcutParam = ((shortcutParam == null) ? "" : shortcutParam);
|
||||
}
|
||||
|
||||
public void Initialize() {
|
||||
// Initialize audio classes. Do this here since detectOptimalAudioSettings()
|
||||
// needs audioManager
|
||||
this.audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
|
||||
this.audioFocusChangeListener = new AudioFocusChangeListener();
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 17) {
|
||||
// Get the optimal buffer sz
|
||||
detectOptimalAudioSettings();
|
||||
}
|
||||
|
||||
// isLandscape is used to trigger GetAppInfo currently, we
|
||||
boolean landscape = NativeApp.isLandscape();
|
||||
Log.d(TAG, "Landscape: " + landscape);
|
||||
|
||||
// Get system information
|
||||
ApplicationInfo appInfo = null;
|
||||
PackageManager packMgmr = getPackageManager();
|
||||
String packageName = getPackageName();
|
||||
try {
|
||||
appInfo = packMgmr.getApplicationInfo(packageName, 0);
|
||||
} catch (NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Unable to locate assets, aborting...");
|
||||
}
|
||||
|
||||
int deviceType = NativeApp.DEVICE_TYPE_MOBILE;
|
||||
UiModeManager uiModeManager = (UiModeManager) getSystemService(UI_MODE_SERVICE);
|
||||
switch (uiModeManager.getCurrentModeType()) {
|
||||
case Configuration.UI_MODE_TYPE_TELEVISION:
|
||||
deviceType = NativeApp.DEVICE_TYPE_TV;
|
||||
Log.i(TAG, "Running on an Android TV Device");
|
||||
break;
|
||||
case Configuration.UI_MODE_TYPE_DESK:
|
||||
deviceType = NativeApp.DEVICE_TYPE_DESKTOP;
|
||||
Log.i(TAG, "Running on an Android desktop computer (!)");
|
||||
break;
|
||||
// All other device types are treated the same.
|
||||
}
|
||||
|
||||
isXperiaPlay = IsXperiaPlay();
|
||||
|
||||
String libraryDir = getApplicationLibraryDir(appInfo);
|
||||
File sdcard = Environment.getExternalStorageDirectory();
|
||||
|
||||
String externalStorageDir = sdcard.getAbsolutePath();
|
||||
String dataDir = this.getFilesDir().getAbsolutePath();
|
||||
String apkFilePath = appInfo.sourceDir;
|
||||
|
||||
String model = Build.MANUFACTURER + ":" + Build.MODEL;
|
||||
String languageRegion = Locale.getDefault().getLanguage() + "_" + Locale.getDefault().getCountry();
|
||||
|
||||
Point displaySize = new Point();
|
||||
GetScreenSize(displaySize);
|
||||
NativeApp.audioConfig(optimalFramesPerBuffer, optimalSampleRate);
|
||||
NativeApp.init(model, deviceType, displaySize.x, displaySize.y, languageRegion, apkFilePath, dataDir, externalStorageDir, libraryDir, shortcutParam, installID, Build.VERSION.SDK_INT);
|
||||
|
||||
NativeApp.sendMessage("cacheDir", getCacheDir().getAbsolutePath());
|
||||
|
||||
// OK, config should be initialized, we can query for screen rotation.
|
||||
if (Build.VERSION.SDK_INT >= 9) {
|
||||
updateScreenRotation();
|
||||
}
|
||||
|
||||
// Detect OpenGL support.
|
||||
// We don't currently use this detection for anything but good to have in the log.
|
||||
if (!detectOpenGLES20()) {
|
||||
Log.i(TAG, "OpenGL ES 2.0 NOT detected. Things will likely go badly.");
|
||||
} else {
|
||||
if (detectOpenGLES30()) {
|
||||
Log.i(TAG, "OpenGL ES 3.0 detected.");
|
||||
}
|
||||
else {
|
||||
Log.i(TAG, "OpenGL ES 2.0 detected.");
|
||||
}
|
||||
}
|
||||
|
||||
vibrator = (Vibrator)getSystemService(VIBRATOR_SERVICE);
|
||||
if (Build.VERSION.SDK_INT >= 11) {
|
||||
checkForVibrator();
|
||||
}
|
||||
}
|
||||
|
||||
@TargetApi(9)
|
||||
private void updateScreenRotation() {
|
||||
// Query the native application on the desired rotation.
|
||||
int rot = 0;
|
||||
String rotString = NativeApp.queryConfig("screenRotation");
|
||||
try {
|
||||
rot = Integer.parseInt(rotString);
|
||||
} catch (NumberFormatException e) {
|
||||
Log.e(TAG, "Invalid rotation: " + rotString);
|
||||
return;
|
||||
}
|
||||
switch (rot) {
|
||||
case 0:
|
||||
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
|
||||
break;
|
||||
case 1:
|
||||
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
|
||||
break;
|
||||
case 2:
|
||||
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
|
||||
break;
|
||||
case 3:
|
||||
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
|
||||
break;
|
||||
case 4:
|
||||
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean useImmersive() {
|
||||
String immersive = NativeApp.queryConfig("immersiveMode");
|
||||
return immersive.equals("1") && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
|
||||
}
|
||||
|
||||
@SuppressLint("InlinedApi")
|
||||
@TargetApi(14)
|
||||
private void updateSystemUiVisibility() {
|
||||
int flags = 0;
|
||||
if (useLowProfileButtons()) {
|
||||
flags |= View.SYSTEM_UI_FLAG_LOW_PROFILE;
|
||||
}
|
||||
if (useImmersive()) {
|
||||
flags |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
|
||||
}
|
||||
if (getWindow().getDecorView() != null) {
|
||||
getWindow().getDecorView().setSystemUiVisibility(flags);
|
||||
} else {
|
||||
Log.e(TAG, "updateSystemUiVisibility: decor view not yet created, ignoring");
|
||||
}
|
||||
}
|
||||
|
||||
// Need API 11 to check for existence of a vibrator? Zany.
|
||||
@TargetApi(11)
|
||||
public void checkForVibrator() {
|
||||
if (Build.VERSION.SDK_INT >= 11) {
|
||||
if (!vibrator.hasVibrator()) {
|
||||
vibrator = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Override this to scale the backbuffer (use the Android hardware scaler)
|
||||
public void getDesiredBackbufferSize(Point sz) {
|
||||
sz.x = 0;
|
||||
sz.y = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
installID = Installation.id(this);
|
||||
|
||||
if (!initialized) {
|
||||
Initialize();
|
||||
initialized = true;
|
||||
}
|
||||
// Keep the screen bright - very annoying if it goes dark when tilting away
|
||||
Window window = this.getWindow();
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
setVolumeControlStream(AudioManager.STREAM_MUSIC);
|
||||
|
||||
gainAudioFocus(this.audioManager, this.audioFocusChangeListener);
|
||||
NativeApp.audioInit();
|
||||
|
||||
mGLSurfaceView = new NativeGLView(this);
|
||||
nativeRenderer = new NativeRenderer(this);
|
||||
|
||||
Point sz = new Point();
|
||||
getDesiredBackbufferSize(sz);
|
||||
if (sz.x > 0) {
|
||||
Log.i(TAG, "Requesting fixed size buffer: " + sz.x + "x" + sz.y);
|
||||
// Auto-calculates new DPI and forwards to the correct call on mGLSurfaceView.getHolder()
|
||||
nativeRenderer.setFixedSize(sz.x, sz.y, mGLSurfaceView);
|
||||
}
|
||||
mGLSurfaceView.setEGLContextClientVersion(2);
|
||||
|
||||
// Setup the GLSurface and ask android for the correct
|
||||
// Number of bits for r, g, b, a, depth and stencil components
|
||||
// The PSP only has 16-bit Z so that should be enough.
|
||||
// Might want to change this for other apps (24-bit might be useful).
|
||||
// Actually, we might be able to do without both stencil and depth in
|
||||
// the back buffer, but that would kill non-buffered rendering.
|
||||
|
||||
// It appears some gingerbread devices blow up if you use a config chooser at all ???? (Xperia Play)
|
||||
//if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
|
||||
// On some (especially older devices), things blow up later (EGL_BAD_MATCH) if we don't set the format here,
|
||||
// if we specify that we want destination alpha in the config chooser, which we do.
|
||||
// http://grokbase.com/t/gg/android-developers/11bj40jm4w/fall-back
|
||||
|
||||
|
||||
// Needed to avoid banding on Ouya?
|
||||
if (Build.MANUFACTURER == "OUYA") {
|
||||
mGLSurfaceView.getHolder().setFormat(PixelFormat.RGBX_8888);
|
||||
mGLSurfaceView.setEGLConfigChooser(new NativeEGLConfigChooser());
|
||||
}
|
||||
|
||||
mGLSurfaceView.setRenderer(nativeRenderer);
|
||||
setContentView(mGLSurfaceView);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
|
||||
updateSystemUiVisibility();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
setupSystemUiCallback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TargetApi(19)
|
||||
void setupSystemUiCallback() {
|
||||
getWindow().getDecorView().setOnSystemUiVisibilityChangeListener(new OnSystemUiVisibilityChangeListener() {
|
||||
@Override
|
||||
public void onSystemUiVisibilityChange(int visibility) {
|
||||
if (visibility == 0) {
|
||||
updateSystemUiVisibility();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
Log.i(TAG, "onStop - do nothing special");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
Log.i(TAG, "onDestroy");
|
||||
mGLSurfaceView.onDestroy();
|
||||
nativeRenderer.onDestroyed();
|
||||
NativeApp.audioShutdown();
|
||||
// Probably vain attempt to help the garbage collector...
|
||||
mGLSurfaceView = null;
|
||||
audioFocusChangeListener = null;
|
||||
audioManager = null;
|
||||
}
|
||||
|
||||
private boolean detectOpenGLES20() {
|
||||
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
|
||||
ConfigurationInfo info = am.getDeviceConfigurationInfo();
|
||||
return info.reqGlEsVersion >= 0x20000;
|
||||
}
|
||||
|
||||
private boolean detectOpenGLES30() {
|
||||
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
|
||||
ConfigurationInfo info = am.getDeviceConfigurationInfo();
|
||||
return info.reqGlEsVersion >= 0x30000;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
Log.i(TAG, "onPause");
|
||||
loseAudioFocus(this.audioManager, this.audioFocusChangeListener);
|
||||
NativeApp.pause();
|
||||
mGLSurfaceView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
|
||||
updateSystemUiVisibility();
|
||||
}
|
||||
// OK, config should be initialized, we can query for screen rotation.
|
||||
if (Build.VERSION.SDK_INT >= 9) {
|
||||
updateScreenRotation();
|
||||
}
|
||||
|
||||
Log.i(TAG, "onResume");
|
||||
if (mGLSurfaceView != null) {
|
||||
mGLSurfaceView.onResume();
|
||||
} else {
|
||||
Log.e(TAG, "mGLSurfaceView really shouldn't be null in onResume");
|
||||
}
|
||||
|
||||
gainAudioFocus(this.audioManager, this.audioFocusChangeListener);
|
||||
NativeApp.resume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
|
||||
updateSystemUiVisibility();
|
||||
}
|
||||
|
||||
Point sz = new Point();
|
||||
getDesiredBackbufferSize(sz);
|
||||
if (sz.x > 0) {
|
||||
mGLSurfaceView.getHolder().setFixedSize(sz.x/2, sz.y/2);
|
||||
}
|
||||
}
|
||||
|
||||
//keep this static so we can call this even if we don't
|
||||
//instantiate NativeAudioPlayer
|
||||
public static void gainAudioFocus(AudioManager audioManager, AudioFocusChangeListener focusChangeListener) {
|
||||
if (audioManager != null) {
|
||||
audioManager.requestAudioFocus(focusChangeListener,
|
||||
AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
|
||||
}
|
||||
}
|
||||
|
||||
//keep this static so we can call this even if we don't
|
||||
//instantiate NativeAudioPlayer
|
||||
public static void loseAudioFocus(AudioManager audioManager,AudioFocusChangeListener focusChangeListener){
|
||||
if (audioManager != null) {
|
||||
audioManager.abandonAudioFocus(focusChangeListener);
|
||||
}
|
||||
}
|
||||
|
||||
// We simply grab the first input device to produce an event and ignore all others that are connected.
|
||||
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
|
||||
private InputDeviceState getInputDeviceState(InputEvent event) {
|
||||
InputDevice device = event.getDevice();
|
||||
if (device == null) {
|
||||
return null;
|
||||
}
|
||||
if (inputPlayerA == null) {
|
||||
inputPlayerADesc = getInputDesc(device);
|
||||
Log.i(TAG, "Input player A registered: desc = " + inputPlayerADesc);
|
||||
inputPlayerA = new InputDeviceState(device);
|
||||
}
|
||||
|
||||
if (inputPlayerA.getDevice() == device) {
|
||||
return inputPlayerA;
|
||||
}
|
||||
|
||||
if (inputPlayerB == null) {
|
||||
Log.i(TAG, "Input player B registered: desc = " + getInputDesc(device));
|
||||
inputPlayerB = new InputDeviceState(device);
|
||||
}
|
||||
|
||||
if (inputPlayerB.getDevice() == device) {
|
||||
return inputPlayerB;
|
||||
}
|
||||
|
||||
if (inputPlayerC == null) {
|
||||
Log.i(TAG, "Input player C registered");
|
||||
inputPlayerC = new InputDeviceState(device);
|
||||
}
|
||||
|
||||
if (inputPlayerC.getDevice() == device) {
|
||||
return inputPlayerC;
|
||||
}
|
||||
|
||||
return inputPlayerA;
|
||||
}
|
||||
|
||||
public boolean IsXperiaPlay() {
|
||||
return android.os.Build.MODEL.equals("R800a") || android.os.Build.MODEL.equals("R800i") || android.os.Build.MODEL.equals("R800x") || android.os.Build.MODEL.equals("R800at") || android.os.Build.MODEL.equals("SO-01D") || android.os.Build.MODEL.equals("zeus");
|
||||
}
|
||||
|
||||
// We grab the keys before onKeyDown/... even see them. This is also better because it lets us
|
||||
// distinguish devices.
|
||||
@Override
|
||||
public boolean dispatchKeyEvent(KeyEvent event) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1 && !isXperiaPlay) {
|
||||
InputDeviceState state = getInputDeviceState(event);
|
||||
if (state == null) {
|
||||
return super.dispatchKeyEvent(event);
|
||||
}
|
||||
|
||||
// Let's let back and menu through to dispatchKeyEvent.
|
||||
boolean passThrough = false;
|
||||
|
||||
switch (event.getKeyCode()) {
|
||||
case KeyEvent.KEYCODE_BACK:
|
||||
case KeyEvent.KEYCODE_MENU:
|
||||
passThrough = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Don't passthrough back button if gamepad.
|
||||
int sources = event.getSource();
|
||||
switch (sources) {
|
||||
case InputDevice.SOURCE_GAMEPAD:
|
||||
case InputDevice.SOURCE_JOYSTICK:
|
||||
case InputDevice.SOURCE_DPAD:
|
||||
passThrough = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!passThrough) {
|
||||
switch (event.getAction()) {
|
||||
case KeyEvent.ACTION_DOWN:
|
||||
if (state.onKeyDown(event)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case KeyEvent.ACTION_UP:
|
||||
if (state.onKeyUp(event)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Let's go through the old path (onKeyUp, onKeyDown).
|
||||
return super.dispatchKeyEvent(event);
|
||||
}
|
||||
|
||||
@TargetApi(16)
|
||||
static public String getInputDesc(InputDevice input) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||
return input.getDescriptor();
|
||||
} else {
|
||||
List<InputDevice.MotionRange> motions = input.getMotionRanges();
|
||||
String fakeid = "";
|
||||
for (InputDevice.MotionRange range : motions)
|
||||
fakeid += range.getAxis();
|
||||
return fakeid;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@TargetApi(12)
|
||||
public boolean onGenericMotionEvent(MotionEvent event) {
|
||||
// Log.d(TAG, "onGenericMotionEvent: " + event);
|
||||
if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) != 0) {
|
||||
if (Build.VERSION.SDK_INT >= 12) {
|
||||
InputDeviceState state = getInputDeviceState(event);
|
||||
if (state == null) {
|
||||
Log.w(TAG, "Joystick event but failed to get input device state.");
|
||||
return super.onGenericMotionEvent(event);
|
||||
}
|
||||
state.onJoystickMotion(event);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_HOVER_MOVE:
|
||||
// process the mouse hover movement...
|
||||
return true;
|
||||
case MotionEvent.ACTION_SCROLL:
|
||||
NativeApp.mouseWheelEvent(event.getX(), event.getY());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return super.onGenericMotionEvent(event);
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
// Eat these keys, to avoid accidental exits / other screwups.
|
||||
// Maybe there's even more we need to eat on tablets?
|
||||
boolean repeat = event.getRepeatCount() > 0;
|
||||
switch (keyCode) {
|
||||
case KeyEvent.KEYCODE_BACK:
|
||||
if (event.isAltPressed()) {
|
||||
NativeApp.keyDown(0, 1004, repeat); // special custom keycode for the O button on Xperia Play
|
||||
} else if (NativeApp.isAtTopLevel()) {
|
||||
Log.i(TAG, "IsAtTopLevel returned true.");
|
||||
// Pass through the back event.
|
||||
return super.onKeyDown(keyCode, event);
|
||||
} else {
|
||||
NativeApp.keyDown(0, keyCode, repeat);
|
||||
}
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_MENU:
|
||||
case KeyEvent.KEYCODE_SEARCH:
|
||||
NativeApp.keyDown(0, keyCode, repeat);
|
||||
return true;
|
||||
|
||||
case KeyEvent.KEYCODE_DPAD_UP:
|
||||
case KeyEvent.KEYCODE_DPAD_DOWN:
|
||||
case KeyEvent.KEYCODE_DPAD_LEFT:
|
||||
case KeyEvent.KEYCODE_DPAD_RIGHT:
|
||||
// Joysticks are supported in Honeycomb MR1 and later via the onGenericMotionEvent method.
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1 && event.getSource() == InputDevice.SOURCE_JOYSTICK) {
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
// Fall through
|
||||
default:
|
||||
// send the rest of the keys through.
|
||||
// TODO: get rid of the three special cases above by adjusting the native side of the code.
|
||||
// Log.d(TAG, "Key down: " + keyCode + ", KeyEvent: " + event);
|
||||
return NativeApp.keyDown(0, keyCode, repeat);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
@Override
|
||||
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
||||
switch (keyCode) {
|
||||
case KeyEvent.KEYCODE_BACK:
|
||||
if (event.isAltPressed()) {
|
||||
NativeApp.keyUp(0, 1004); // special custom keycode
|
||||
} else if (NativeApp.isAtTopLevel()) {
|
||||
Log.i(TAG, "IsAtTopLevel returned true.");
|
||||
return super.onKeyUp(keyCode, event);
|
||||
} else {
|
||||
NativeApp.keyUp(0, keyCode);
|
||||
}
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_MENU:
|
||||
case KeyEvent.KEYCODE_SEARCH:
|
||||
// Search probably should also be ignored. We send it to the app.
|
||||
NativeApp.keyUp(0, keyCode);
|
||||
return true;
|
||||
|
||||
case KeyEvent.KEYCODE_DPAD_UP:
|
||||
case KeyEvent.KEYCODE_DPAD_DOWN:
|
||||
case KeyEvent.KEYCODE_DPAD_LEFT:
|
||||
case KeyEvent.KEYCODE_DPAD_RIGHT:
|
||||
// Joysticks are supported in Honeycomb MR1 and later via the onGenericMotionEvent method.
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1 && event.getSource() == InputDevice.SOURCE_JOYSTICK) {
|
||||
return super.onKeyUp(keyCode, event);
|
||||
}
|
||||
// Fall through
|
||||
default:
|
||||
// send the rest of the keys through.
|
||||
// TODO: get rid of the three special cases above by adjusting the native side of the code.
|
||||
// Log.d(TAG, "Key down: " + keyCode + ", KeyEvent: " + event);
|
||||
return NativeApp.keyUp(0, keyCode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@TargetApi(11)
|
||||
private AlertDialog.Builder createDialogBuilderWithTheme() {
|
||||
return new AlertDialog.Builder(this, AlertDialog.THEME_HOLO_DARK);
|
||||
}
|
||||
|
||||
// The return value is sent elsewhere. TODO in java, in SendMessage in C++.
|
||||
public void inputBox(String title, String defaultText, String defaultAction) {
|
||||
final FrameLayout fl = new FrameLayout(this);
|
||||
final EditText input = new EditText(this);
|
||||
input.setGravity(Gravity.CENTER);
|
||||
|
||||
FrameLayout.LayoutParams editBoxLayout = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT);
|
||||
editBoxLayout.setMargins(2, 20, 2, 20);
|
||||
fl.addView(input, editBoxLayout);
|
||||
|
||||
input.setInputType(InputType.TYPE_CLASS_TEXT);
|
||||
input.setText(defaultText);
|
||||
input.selectAll();
|
||||
|
||||
AlertDialog.Builder bld = null;
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB)
|
||||
bld = new AlertDialog.Builder(this);
|
||||
else
|
||||
bld = createDialogBuilderWithTheme();
|
||||
|
||||
AlertDialog dlg = bld
|
||||
.setView(fl)
|
||||
.setTitle(title)
|
||||
.setPositiveButton(defaultAction, new DialogInterface.OnClickListener(){
|
||||
public void onClick(DialogInterface d, int which) {
|
||||
NativeApp.sendMessage("inputbox_completed", input.getText().toString());
|
||||
d.dismiss();
|
||||
}
|
||||
})
|
||||
.setNegativeButton("Cancel", new DialogInterface.OnClickListener(){
|
||||
public void onClick(DialogInterface d, int which) {
|
||||
NativeApp.sendMessage("inputbox_failed", "");
|
||||
d.cancel();
|
||||
}
|
||||
}).create();
|
||||
|
||||
dlg.setCancelable(true);
|
||||
dlg.show();
|
||||
}
|
||||
|
||||
public boolean processCommand(String command, String params) {
|
||||
if (command.equals("launchBrowser")) {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(params));
|
||||
startActivity(i);
|
||||
return true;
|
||||
} else if (command.equals("launchEmail")) {
|
||||
Intent send = new Intent(Intent.ACTION_SENDTO);
|
||||
String uriText;
|
||||
uriText = "mailto:email@gmail.com" + "?subject=Your app is..."
|
||||
+ "&body=great! Or?";
|
||||
uriText = uriText.replace(" ", "%20");
|
||||
Uri uri = Uri.parse(uriText);
|
||||
send.setData(uri);
|
||||
startActivity(Intent.createChooser(send, "E-mail the app author!"));
|
||||
return true;
|
||||
} else if (command.equals("sharejpeg")) {
|
||||
Intent share = new Intent(Intent.ACTION_SEND);
|
||||
share.setType("image/jpeg");
|
||||
share.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + params));
|
||||
startActivity(Intent.createChooser(share, "Share Picture"));
|
||||
} else if (command.equals("sharetext")) {
|
||||
Intent sendIntent = new Intent();
|
||||
sendIntent.setType("text/plain");
|
||||
sendIntent.putExtra(Intent.EXTRA_TEXT, params);
|
||||
sendIntent.setAction(Intent.ACTION_SEND);
|
||||
startActivity(sendIntent);
|
||||
} else if (command.equals("showTwitter")) {
|
||||
String twitter_user_name = params;
|
||||
try {
|
||||
startActivity(new Intent(Intent.ACTION_VIEW,
|
||||
Uri.parse("twitter://user?screen_name="
|
||||
+ twitter_user_name)));
|
||||
} catch (Exception e) {
|
||||
startActivity(new Intent(
|
||||
Intent.ACTION_VIEW,
|
||||
Uri.parse("https://twitter.com/#!/" + twitter_user_name)));
|
||||
}
|
||||
} else if (command.equals("launchMarket")) {
|
||||
// Don't need this, can just use launchBrowser with a market:
|
||||
// http://stackoverflow.com/questions/3442366/android-link-to-market-from-inside-another-app
|
||||
// http://developer.android.com/guide/publishing/publishing.html#marketintent
|
||||
return false;
|
||||
} else if (command.equals("toast")) {
|
||||
Toast toast = Toast.makeText(this, params, Toast.LENGTH_SHORT);
|
||||
toast.show();
|
||||
Log.i(TAG, params);
|
||||
return true;
|
||||
} else if (command.equals("showKeyboard")) {
|
||||
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
// No idea what the point of the ApplicationWindowToken is or if it
|
||||
// matters where we get it from...
|
||||
inputMethodManager.toggleSoftInputFromWindow(
|
||||
mGLSurfaceView.getApplicationWindowToken(),
|
||||
InputMethodManager.SHOW_FORCED, 0);
|
||||
return true;
|
||||
} else if (command.equals("hideKeyboard")) {
|
||||
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
inputMethodManager.toggleSoftInputFromWindow(
|
||||
mGLSurfaceView.getApplicationWindowToken(),
|
||||
InputMethodManager.SHOW_FORCED, 0);
|
||||
return true;
|
||||
} else if (command.equals("inputbox")) {
|
||||
String title = "Input";
|
||||
String defString = "";
|
||||
String[] param = params.split(":");
|
||||
if (param[0].length() > 0)
|
||||
title = param[0];
|
||||
if (param.length > 1)
|
||||
defString = param[1];
|
||||
Log.i(TAG, "Launching inputbox: " + title + " " + defString);
|
||||
inputBox(title, defString, "OK");
|
||||
return true;
|
||||
} else if (command.equals("vibrate")) {
|
||||
int milliseconds = -1;
|
||||
if (params != "") {
|
||||
try {
|
||||
milliseconds = Integer.parseInt(params);
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
// Special parameters to perform standard haptic feedback
|
||||
// operations
|
||||
// -1 = Standard keyboard press feedback
|
||||
// -2 = Virtual key press
|
||||
// -3 = Long press feedback
|
||||
// Note that these three do not require the VIBRATE Android
|
||||
// permission.
|
||||
switch (milliseconds) {
|
||||
case -1:
|
||||
mGLSurfaceView.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP);
|
||||
break;
|
||||
case -2:
|
||||
mGLSurfaceView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
|
||||
break;
|
||||
case -3:
|
||||
mGLSurfaceView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
|
||||
break;
|
||||
default:
|
||||
if (vibrator != null) {
|
||||
vibrator.vibrate(milliseconds);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
} else if (command.equals("finish")) {
|
||||
finish();
|
||||
} else if (command.equals("rotate")) {
|
||||
if (Build.VERSION.SDK_INT >= 9) {
|
||||
updateScreenRotation();
|
||||
}
|
||||
} else if (command.equals("immersive")) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
updateSystemUiVisibility();
|
||||
}
|
||||
} else if (command.equals("recreate")) {
|
||||
recreate();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
@Override
|
||||
public void recreate()
|
||||
{
|
||||
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
|
||||
{
|
||||
super.recreate();
|
||||
}
|
||||
else
|
||||
{
|
||||
startActivity(getIntent());
|
||||
finish();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package com.henrikrydgard.libnative;
|
||||
|
||||
|
||||
// Note that the display* methods are in NativeRenderer.java
|
||||
|
||||
public class NativeApp {
|
||||
public final static int DEVICE_ID_DEFAULT = 0;
|
||||
public final static int DEVICE_ID_KEYBOARD = 1;
|
||||
public final static int DEVICE_ID_MOUSE = 2;
|
||||
public final static int DEVICE_ID_PAD_0 = 10;
|
||||
|
||||
public final static int DEVICE_TYPE_MOBILE = 0;
|
||||
public final static int DEVICE_TYPE_TV = 1;
|
||||
public final static int DEVICE_TYPE_DESKTOP = 2;
|
||||
|
||||
public static native void init(String model, int deviceType, int xres, int yres, String languageRegion, String apkPath, String dataDir, String externalDir, String libraryDir, String shortcutParam, String installID, int androidVersion);
|
||||
|
||||
public static native void audioInit();
|
||||
public static native void audioShutdown();
|
||||
public static native void audioConfig(int optimalFramesPerBuffer, int optimalSampleRate);
|
||||
|
||||
public static native boolean isLandscape();
|
||||
public static native boolean isAtTopLevel();
|
||||
|
||||
// These have Android semantics: Resume is always called on bootup, after init
|
||||
public static native void pause();
|
||||
public static native void resume();
|
||||
|
||||
// There's not really any reason to ever call shutdown as we can recover from a killed activity.
|
||||
public static native void shutdown();
|
||||
|
||||
public static native boolean keyDown(int deviceId, int key, boolean isRepeat);
|
||||
public static native boolean keyUp(int deviceId, int key);
|
||||
|
||||
public static native void beginJoystickEvent();
|
||||
public static native void joystickAxis(int deviceId, int axis, float value);
|
||||
public static native void endJoystickEvent();
|
||||
|
||||
public static native boolean mouseWheelEvent(float x, float y);
|
||||
|
||||
// will only be called between init() and shutdown()
|
||||
public static native int audioRender(short[] buffer);
|
||||
|
||||
// Sensor/input data. These are asynchronous, beware!
|
||||
public static native boolean touch(float x, float y, int data, int pointerId);
|
||||
|
||||
public static native boolean accelerometer(float x, float y, float z);
|
||||
|
||||
public static native void sendMessage(String msg, String arg);
|
||||
|
||||
public static native String queryConfig(String queryName);
|
||||
}
|
||||
|
@ -0,0 +1,206 @@
|
||||
package com.henrikrydgard.libnative;
|
||||
|
||||
import javax.microedition.khronos.egl.EGL10;
|
||||
import javax.microedition.khronos.egl.EGLConfig;
|
||||
import javax.microedition.khronos.egl.EGLDisplay;
|
||||
|
||||
import android.opengl.GLSurfaceView.EGLConfigChooser;
|
||||
import android.util.Log;
|
||||
|
||||
public class NativeEGLConfigChooser implements EGLConfigChooser {
|
||||
private static final String TAG = "NativeEGLConfigChooser";
|
||||
|
||||
private static final int EGL_OPENGL_ES2_BIT = 4;
|
||||
|
||||
private class ConfigAttribs {
|
||||
EGLConfig config;
|
||||
public int red;
|
||||
public int green;
|
||||
public int blue;
|
||||
public int alpha;
|
||||
public int stencil;
|
||||
public int depth;
|
||||
public int samples;
|
||||
public void Log() {
|
||||
Log.i(TAG, "EGLConfig: red=" + red + " green=" + green + " blue=" + blue + " alpha=" + alpha + " depth=" + depth + " stencil=" + stencil + " samples=" + samples);
|
||||
}
|
||||
}
|
||||
|
||||
int getEglConfigAttrib(EGL10 egl, EGLDisplay display, EGLConfig config, int attr) {
|
||||
int[] value = new int[1];
|
||||
try {
|
||||
if (egl.eglGetConfigAttrib(display, config, attr, value))
|
||||
return value[0];
|
||||
else
|
||||
return -1;
|
||||
} catch (IllegalArgumentException e) {
|
||||
if (config == null) {
|
||||
Log.e(TAG, "Called getEglConfigAttrib with null config. Bad developer.");
|
||||
} else {
|
||||
Log.e(TAG, "Illegal argument to getEglConfigAttrib: attr=" + attr);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
ConfigAttribs[] getConfigAttribs(EGL10 egl, EGLDisplay display, EGLConfig[] configs) {
|
||||
ConfigAttribs[] attr = new ConfigAttribs[configs.length];
|
||||
for (int i = 0; i < configs.length; i++) {
|
||||
ConfigAttribs cfg = new ConfigAttribs();
|
||||
cfg.config = configs[i];
|
||||
cfg.red = getEglConfigAttrib(egl, display, configs[i], EGL10.EGL_RED_SIZE);
|
||||
cfg.green = getEglConfigAttrib(egl, display, configs[i], EGL10.EGL_GREEN_SIZE);
|
||||
cfg.blue = getEglConfigAttrib(egl, display, configs[i], EGL10.EGL_BLUE_SIZE);
|
||||
cfg.alpha = getEglConfigAttrib(egl, display, configs[i], EGL10.EGL_ALPHA_SIZE);
|
||||
cfg.depth = getEglConfigAttrib(egl, display, configs[i], EGL10.EGL_DEPTH_SIZE);
|
||||
cfg.stencil = getEglConfigAttrib(egl, display, configs[i], EGL10.EGL_STENCIL_SIZE);
|
||||
cfg.samples = getEglConfigAttrib(egl, display, configs[i], EGL10.EGL_SAMPLES);
|
||||
attr[i] = cfg;
|
||||
}
|
||||
return attr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
|
||||
// The absolute minimum. We will do our best to choose a better config though.
|
||||
int[] configSpec = {
|
||||
EGL10.EGL_RED_SIZE, 5,
|
||||
EGL10.EGL_GREEN_SIZE, 6,
|
||||
EGL10.EGL_BLUE_SIZE, 5,
|
||||
EGL10.EGL_DEPTH_SIZE, 16,
|
||||
EGL10.EGL_STENCIL_SIZE, 0,
|
||||
EGL10.EGL_SURFACE_TYPE, EGL10.EGL_WINDOW_BIT,
|
||||
EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
||||
EGL10.EGL_NONE
|
||||
};
|
||||
|
||||
int[] num_config = new int[1];
|
||||
if (!egl.eglChooseConfig(display, configSpec, null, 0, num_config)) {
|
||||
throw new IllegalArgumentException("eglChooseConfig failed when counting");
|
||||
}
|
||||
|
||||
int numConfigs = num_config[0];
|
||||
Log.i(TAG, "There are " + numConfigs + " egl configs");
|
||||
if (numConfigs <= 0) {
|
||||
throw new IllegalArgumentException("No configs match configSpec");
|
||||
}
|
||||
|
||||
EGLConfig[] eglConfigs = new EGLConfig[numConfigs];
|
||||
if (!egl.eglChooseConfig(display, configSpec, eglConfigs, numConfigs, num_config)) {
|
||||
throw new IllegalArgumentException("eglChooseConfig failed when retrieving");
|
||||
}
|
||||
|
||||
ConfigAttribs [] configs = getConfigAttribs(egl, display, eglConfigs);
|
||||
|
||||
ConfigAttribs chosen = null;
|
||||
|
||||
// Log them all.
|
||||
for (int i = 0; i < configs.length; i++) {
|
||||
configs[i].Log();
|
||||
}
|
||||
|
||||
// We now ignore destination alpha as a workaround for the Mali issue
|
||||
// where we get badly composited if we use it.
|
||||
|
||||
// First, find our ideal configuration. Prefer depth.
|
||||
for (int i = 0; i < configs.length; i++) {
|
||||
ConfigAttribs c = configs[i];
|
||||
if (c.red == 8 && c.green == 8 && c.blue == 8 && c.alpha == 0 && c.stencil >= 8 && c.depth >= 24) {
|
||||
chosen = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (chosen == null) {
|
||||
// Then, prefer one with 20-bit depth (Tegra 3)
|
||||
for (int i = 0; i < configs.length; i++) {
|
||||
ConfigAttribs c = configs[i];
|
||||
if (c.red == 8 && c.green == 8 && c.blue == 8 && c.alpha == 0 && c.stencil >= 8 && c.depth >= 20) {
|
||||
chosen = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (chosen == null) {
|
||||
// Second, accept one with 16-bit depth.
|
||||
for (int i = 0; i < configs.length; i++) {
|
||||
ConfigAttribs c = configs[i];
|
||||
if (c.red == 8 && c.green == 8 && c.blue == 8 && c.alpha == 0 && c.stencil >= 8 && c.depth >= 16) {
|
||||
chosen = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (chosen == null) {
|
||||
// Third, accept one with no stencil.
|
||||
for (int i = 0; i < configs.length; i++) {
|
||||
ConfigAttribs c = configs[i];
|
||||
if (c.red == 8 && c.green == 8 && c.blue == 8 && c.alpha == 0 && c.depth >= 16) {
|
||||
chosen = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (chosen == null) {
|
||||
// Third, accept one with alpha but with stencil.
|
||||
for (int i = 0; i < configs.length; i++) {
|
||||
ConfigAttribs c = configs[i];
|
||||
if (c.red == 8 && c.green == 8 && c.blue == 8 && c.alpha == 8 && c.stencil >= 8 && c.depth >= 24) {
|
||||
chosen = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (chosen == null) {
|
||||
// Third, accept one with alpha but with stencil.
|
||||
for (int i = 0; i < configs.length; i++) {
|
||||
ConfigAttribs c = configs[i];
|
||||
if (c.red == 8 && c.green == 8 && c.blue == 8 && c.alpha == 8 && c.stencil >= 8 && c.depth >= 16) {
|
||||
chosen = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (chosen == null) {
|
||||
// Fourth, accept one with 16-bit color but depth and stencil required.
|
||||
for (int i = 0; i < configs.length; i++) {
|
||||
ConfigAttribs c = configs[i];
|
||||
if (c.red >= 5 && c.green >= 6 && c.blue >= 5 && c.depth >= 16 && c.stencil >= 8) {
|
||||
chosen = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (chosen == null) {
|
||||
// Fifth, accept one with 16-bit color but depth required.
|
||||
for (int i = 0; i < configs.length; i++) {
|
||||
ConfigAttribs c = configs[i];
|
||||
if (c.red >= 5 && c.green >= 6 && c.blue >= 5 && c.depth >= 16) {
|
||||
chosen = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (chosen == null) {
|
||||
// Final, accept the first one in the list.
|
||||
if (configs.length > 0)
|
||||
chosen = configs[0];
|
||||
}
|
||||
|
||||
if (chosen == null) {
|
||||
throw new IllegalArgumentException("Failed to find a valid EGL config");
|
||||
}
|
||||
|
||||
Log.i(TAG, "Final chosen config: ");
|
||||
chosen.Log();
|
||||
return chosen.config;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,235 @@
|
||||
package com.henrikrydgard.libnative;
|
||||
|
||||
// Touch- and sensor-enabled GLSurfaceView.
|
||||
// Supports simple multitouch and pressure.
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.opengl.GLSurfaceView;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
// import android.os.Build;
|
||||
// import android.util.Log;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import com.bda.controller.*;
|
||||
|
||||
public class NativeGLView extends GLSurfaceView implements SensorEventListener, ControllerListener {
|
||||
private static String TAG = "NativeGLView";
|
||||
private SensorManager mSensorManager;
|
||||
private Sensor mAccelerometer;
|
||||
private NativeActivity mActivity;
|
||||
|
||||
// Moga controller
|
||||
private Controller mController = null;
|
||||
private boolean isMogaPro = false;
|
||||
|
||||
public NativeGLView(NativeActivity activity) {
|
||||
super(activity);
|
||||
mActivity = activity;
|
||||
|
||||
/*// TODO: This would be nice.
|
||||
if (Build.VERSION.SDK_INT >= 11) {
|
||||
try {
|
||||
Method method_setPreserveEGLContextOnPause = GLSurfaceView.class.getMethod(
|
||||
"setPreserveEGLContextOnPause", new Class[] { Boolean.class });
|
||||
Log.i(TAG, "Invoking setPreserveEGLContextOnPause");
|
||||
method_setPreserveEGLContextOnPause.invoke(this, true);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}*/
|
||||
|
||||
mSensorManager = (SensorManager)activity.getSystemService(Activity.SENSOR_SERVICE);
|
||||
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
|
||||
|
||||
mController = Controller.getInstance(activity);
|
||||
try {
|
||||
MogaHack.init(mController, activity);
|
||||
Log.i(TAG, "MOGA initialized");
|
||||
mController.setListener(this, new Handler());
|
||||
} catch (Exception e) {
|
||||
Log.i(TAG, "Moga failed to initialize");
|
||||
}
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
|
||||
private int getToolType(final MotionEvent ev, int pointer) {
|
||||
return ev.getToolType(pointer);
|
||||
}
|
||||
|
||||
public boolean onTouchEvent(final MotionEvent ev) {
|
||||
boolean canReadToolType = Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH;
|
||||
|
||||
int numTouchesHandled = 0;
|
||||
float scaleX = (float)mActivity.getRenderer().getDpiScaleX();
|
||||
float scaleY = (float)mActivity.getRenderer().getDpiScaleY();
|
||||
for (int i = 0; i < ev.getPointerCount(); i++) {
|
||||
int pid = ev.getPointerId(i);
|
||||
int code = 0;
|
||||
|
||||
final int action = ev.getActionMasked();
|
||||
|
||||
// These code bits are now the same as the constants in input_state.h.
|
||||
switch (action) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
case MotionEvent.ACTION_POINTER_DOWN:
|
||||
if (ev.getActionIndex() == i)
|
||||
code = 2;
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_POINTER_UP:
|
||||
if (ev.getActionIndex() == i)
|
||||
code = 4;
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
code = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (code != 0) {
|
||||
if (canReadToolType) {
|
||||
int tool = getToolType(ev, i);
|
||||
code |= tool << 10; // We use the Android tool type codes
|
||||
}
|
||||
// Can't use || due to short circuit evaluation
|
||||
numTouchesHandled += NativeApp.touch(scaleX * ev.getX(i), scaleY * ev.getY(i), code, pid) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
return numTouchesHandled > 0;
|
||||
}
|
||||
|
||||
// Sensor management
|
||||
public void onAccuracyChanged(Sensor sensor, int arg1) {
|
||||
}
|
||||
|
||||
public void onSensorChanged(SensorEvent event) {
|
||||
if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER) {
|
||||
return;
|
||||
}
|
||||
// Can also look at event.timestamp for accuracy magic
|
||||
NativeApp.accelerometer(event.values[0], event.values[1], event.values[2]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
mSensorManager.unregisterListener(this);
|
||||
if (mController != null) {
|
||||
mController.onPause();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME);
|
||||
if (mController != null) {
|
||||
mController.onResume();
|
||||
|
||||
// According to the docs, the Moga's state can be inconsistent here.
|
||||
// We should do a one time poll. TODO
|
||||
}
|
||||
}
|
||||
|
||||
public void onDestroy() {
|
||||
if (mController != null) {
|
||||
mController.exit();
|
||||
}
|
||||
}
|
||||
|
||||
// MOGA Controller - from ControllerListener
|
||||
@Override
|
||||
public void onKeyEvent(KeyEvent event) {
|
||||
// The Moga left stick doubles as a D-pad. This creates mapping conflicts so let's turn it off.
|
||||
// Unfortunately this breaks menu navigation in PPSSPP currently but meh.
|
||||
// This is different on Moga Pro though.
|
||||
|
||||
if (!isMogaPro) {
|
||||
switch (event.getKeyCode()) {
|
||||
case KeyEvent.KEYCODE_DPAD_DOWN:
|
||||
case KeyEvent.KEYCODE_DPAD_UP:
|
||||
case KeyEvent.KEYCODE_DPAD_LEFT:
|
||||
case KeyEvent.KEYCODE_DPAD_RIGHT:
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
boolean repeat = false; // Moga has no repeats?
|
||||
switch (event.getAction()) {
|
||||
case KeyEvent.ACTION_DOWN:
|
||||
NativeApp.keyDown(NativeApp.DEVICE_ID_PAD_0, event.getKeyCode(), repeat);
|
||||
break;
|
||||
case KeyEvent.ACTION_UP:
|
||||
NativeApp.keyUp(NativeApp.DEVICE_ID_PAD_0, event.getKeyCode());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// MOGA Controller - from ControllerListener
|
||||
@Override
|
||||
public void onMotionEvent(com.bda.controller.MotionEvent event) {
|
||||
NativeApp.joystickAxis(NativeApp.DEVICE_ID_PAD_0, com.bda.controller.MotionEvent.AXIS_X, event.getAxisValue(com.bda.controller.MotionEvent.AXIS_X));
|
||||
NativeApp.joystickAxis(NativeApp.DEVICE_ID_PAD_0, com.bda.controller.MotionEvent.AXIS_Y, event.getAxisValue(com.bda.controller.MotionEvent.AXIS_Y));
|
||||
NativeApp.joystickAxis(NativeApp.DEVICE_ID_PAD_0, com.bda.controller.MotionEvent.AXIS_Z, event.getAxisValue(com.bda.controller.MotionEvent.AXIS_Z));
|
||||
NativeApp.joystickAxis(NativeApp.DEVICE_ID_PAD_0, com.bda.controller.MotionEvent.AXIS_RZ, event.getAxisValue(com.bda.controller.MotionEvent.AXIS_RZ));
|
||||
NativeApp.joystickAxis(NativeApp.DEVICE_ID_PAD_0, com.bda.controller.MotionEvent.AXIS_LTRIGGER, event.getAxisValue(com.bda.controller.MotionEvent.AXIS_LTRIGGER));
|
||||
NativeApp.joystickAxis(NativeApp.DEVICE_ID_PAD_0, com.bda.controller.MotionEvent.AXIS_RTRIGGER, event.getAxisValue(com.bda.controller.MotionEvent.AXIS_RTRIGGER));
|
||||
}
|
||||
|
||||
// MOGA Controller - from ControllerListener
|
||||
@Override
|
||||
public void onStateEvent(StateEvent state) {
|
||||
switch (state.getState()) {
|
||||
case StateEvent.STATE_CONNECTION:
|
||||
switch (state.getAction()) {
|
||||
case StateEvent.ACTION_CONNECTED:
|
||||
Log.i(TAG, "Moga Connected");
|
||||
if (mController.getState(Controller.STATE_CURRENT_PRODUCT_VERSION) == Controller.ACTION_VERSION_MOGA) {
|
||||
NativeApp.sendMessage("moga", "Moga");
|
||||
} else {
|
||||
Log.i(TAG, "MOGA Pro detected");
|
||||
isMogaPro = true;
|
||||
NativeApp.sendMessage("moga", "MogaPro");
|
||||
}
|
||||
break;
|
||||
case StateEvent.ACTION_CONNECTING:
|
||||
Log.i(TAG, "Moga Connecting...");
|
||||
break;
|
||||
case StateEvent.ACTION_DISCONNECTED:
|
||||
Log.i(TAG, "Moga Disconnected (or simply Not connected)");
|
||||
NativeApp.sendMessage("moga", "");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case StateEvent.STATE_POWER_LOW:
|
||||
switch (state.getAction()) {
|
||||
case StateEvent.ACTION_TRUE:
|
||||
Log.i(TAG, "Moga Power Low");
|
||||
break;
|
||||
case StateEvent.ACTION_FALSE:
|
||||
Log.i(TAG, "Moga Power OK");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
package com.henrikrydgard.libnative;
|
||||
|
||||
import javax.microedition.khronos.egl.EGLConfig;
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
import android.graphics.Point;
|
||||
import android.opengl.GLES20;
|
||||
import android.opengl.GLSurfaceView;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.Display;
|
||||
|
||||
public class NativeRenderer implements GLSurfaceView.Renderer {
|
||||
private static String TAG = "NativeRenderer";
|
||||
private NativeActivity mActivity;
|
||||
private boolean isDark = false;
|
||||
private int dpi;
|
||||
private float refreshRate;
|
||||
|
||||
private double dpi_scale_x;
|
||||
private double dpi_scale_y;
|
||||
|
||||
int last_width, last_height;
|
||||
|
||||
NativeRenderer(NativeActivity act) {
|
||||
mActivity = act;
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
Display display = act.getWindowManager().getDefaultDisplay();
|
||||
display.getMetrics(metrics);
|
||||
dpi = metrics.densityDpi;
|
||||
|
||||
refreshRate = display.getRefreshRate();
|
||||
}
|
||||
|
||||
double getDpiScaleX() {
|
||||
return dpi_scale_x;
|
||||
}
|
||||
double getDpiScaleY() {
|
||||
return dpi_scale_y;
|
||||
}
|
||||
|
||||
public void setDark(boolean d) {
|
||||
isDark = d;
|
||||
}
|
||||
|
||||
public void setFixedSize(int xres, int yres, GLSurfaceView surfaceView) {
|
||||
Log.i(TAG, "Setting surface to fixed size " + xres + "x" + yres);
|
||||
surfaceView.getHolder().setFixedSize(xres, yres);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDrawFrame(GL10 unused /*use GLES20*/) {
|
||||
if (isDark) {
|
||||
GLES20.glDisable(GLES20.GL_SCISSOR_TEST);
|
||||
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_STENCIL_BUFFER_BIT);
|
||||
} else {
|
||||
displayRender();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceCreated(GL10 unused, EGLConfig config) {
|
||||
// Log.i(TAG, "onSurfaceCreated - EGL context is new or was lost");
|
||||
// Actually, it seems that it is here we should recreate lost GL objects.
|
||||
displayInit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceChanged(GL10 unused, int width, int height) {
|
||||
Point sz = new Point();
|
||||
mActivity.GetScreenSize(sz);
|
||||
double actualW = sz.x;
|
||||
double actualH = sz.y;
|
||||
dpi_scale_x = ((double)width / (double)actualW);
|
||||
dpi_scale_y = ((double)height / (double)actualH);
|
||||
Log.i(TAG, "onSurfaceChanged: " + dpi_scale_x + "x" + dpi_scale_y + " (width=" + width + ", actualW=" + actualW);
|
||||
int scaled_dpi = (int)((double)dpi * dpi_scale_x);
|
||||
displayResize(width, height, scaled_dpi, refreshRate);
|
||||
last_width = width;
|
||||
last_height = height;
|
||||
}
|
||||
|
||||
// Not override, it's custom.
|
||||
public void onDestroyed() {
|
||||
displayShutdown();
|
||||
}
|
||||
|
||||
// NATIVE METHODS
|
||||
|
||||
// Note: This also means "device lost" and you should reload
|
||||
// all buffered objects.
|
||||
public native void displayInit();
|
||||
public native void displayResize(int w, int h, int dpi, float refreshRate);
|
||||
public native void displayRender();
|
||||
public native void displayShutdown();
|
||||
|
||||
// called by the C++ code through JNI. Dispatch anything we can't directly handle
|
||||
// on the gfx thread to the UI thread.
|
||||
public void postCommand(String command, String parameter) {
|
||||
final String cmd = command;
|
||||
final String param = parameter;
|
||||
mActivity.runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
NativeRenderer.this.mActivity.processCommand(cmd, param);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
11
ext/native/audio/CMakeLists.txt
Normal file
11
ext/native/audio/CMakeLists.txt
Normal file
@ -0,0 +1,11 @@
|
||||
set(SRCS
|
||||
mixer.cpp
|
||||
wav_read.cpp)
|
||||
|
||||
set(SRCS ${SRCS})
|
||||
|
||||
add_library(mixer STATIC ${SRCS})
|
||||
|
||||
if(UNIX)
|
||||
add_definitions(-fPIC)
|
||||
endif(UNIX)
|
201
ext/native/audio/mixer.cpp
Normal file
201
ext/native/audio/mixer.cpp
Normal file
@ -0,0 +1,201 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "audio/mixer.h"
|
||||
#include "audio/wav_read.h"
|
||||
#include "base/logging.h"
|
||||
#include "ext/stb_vorbis/stb_vorbis.h"
|
||||
#include "file/vfs.h"
|
||||
|
||||
// TODO:
|
||||
// * Vorbis streaming playback
|
||||
|
||||
struct ChannelEffectState {
|
||||
// Filter state
|
||||
};
|
||||
|
||||
enum CLIP_TYPE {
|
||||
CT_PCM16,
|
||||
CT_SYNTHFX,
|
||||
CT_VORBIS,
|
||||
// CT_PHOENIX?
|
||||
};
|
||||
|
||||
struct Clip {
|
||||
int type;
|
||||
|
||||
short *data;
|
||||
int length;
|
||||
int num_channels; // this is NOT stereo vs mono
|
||||
int sample_rate;
|
||||
int loop_start;
|
||||
int loop_end;
|
||||
};
|
||||
|
||||
// If current_clip == 0, the channel is free.
|
||||
|
||||
enum ClipPlaybackState {
|
||||
PB_STOPPED = 0,
|
||||
PB_PLAYING = 1,
|
||||
};
|
||||
|
||||
|
||||
struct Channel {
|
||||
const Clip *current_clip;
|
||||
// Playback state
|
||||
ClipPlaybackState state;
|
||||
int pos;
|
||||
PlayParams params;
|
||||
// Effect state
|
||||
ChannelEffectState effect_state;
|
||||
};
|
||||
|
||||
struct Mixer {
|
||||
Channel *channels;
|
||||
int sample_rate;
|
||||
int num_channels;
|
||||
int num_fixed_channels;
|
||||
};
|
||||
|
||||
Mixer *mixer_create(int sample_rate, int channels, int fixed_channels) {
|
||||
Mixer *mixer = new Mixer();
|
||||
memset(mixer, 0, sizeof(Mixer));
|
||||
mixer->channels = new Channel[channels];
|
||||
memset(mixer->channels, 0, sizeof(Channel) * channels);
|
||||
mixer->sample_rate = sample_rate;
|
||||
mixer->num_channels = channels;
|
||||
mixer->num_fixed_channels = fixed_channels;
|
||||
return mixer;
|
||||
}
|
||||
|
||||
void mixer_destroy(Mixer *mixer) {
|
||||
delete [] mixer->channels;
|
||||
delete mixer;
|
||||
}
|
||||
|
||||
static int get_free_channel(Mixer *mixer) {
|
||||
int chan_with_biggest_pos = -1;
|
||||
int biggest_pos = -1;
|
||||
for (int i = mixer->num_fixed_channels; i < mixer->num_channels; i++) {
|
||||
Channel *chan = &mixer->channels[i];
|
||||
if (!chan->current_clip) {
|
||||
return i;
|
||||
}
|
||||
if (chan->pos > biggest_pos) {
|
||||
biggest_pos = chan->pos;
|
||||
chan_with_biggest_pos = i;
|
||||
}
|
||||
}
|
||||
return chan_with_biggest_pos;
|
||||
}
|
||||
|
||||
Clip *clip_load(const char *filename) {
|
||||
short *data;
|
||||
int num_samples;
|
||||
int sample_rate, num_channels;
|
||||
|
||||
if (!strcmp(filename + strlen(filename) - 4, ".ogg")) {
|
||||
// Ogg file. For now, directly decompress, no streaming support.
|
||||
uint8_t *filedata;
|
||||
size_t size;
|
||||
filedata = VFSReadFile(filename, &size);
|
||||
num_samples = (int)stb_vorbis_decode_memory(filedata, (int)size, &num_channels, &data);
|
||||
if (num_samples <= 0)
|
||||
return NULL;
|
||||
sample_rate = 44100;
|
||||
ILOG("read ogg %s, length %i, rate %i", filename, num_samples, sample_rate);
|
||||
} else {
|
||||
// Wav file. Easy peasy.
|
||||
data = wav_read(filename, &num_samples, &sample_rate, &num_channels);
|
||||
if (!data) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
Clip *clip = new Clip();
|
||||
clip->type = CT_PCM16;
|
||||
clip->data = data;
|
||||
clip->length = num_samples;
|
||||
clip->num_channels = num_channels;
|
||||
clip->sample_rate = sample_rate;
|
||||
clip->loop_start = 0;
|
||||
clip->loop_end = 0;
|
||||
return clip;
|
||||
}
|
||||
|
||||
void clip_destroy(Clip *clip) {
|
||||
if (clip) {
|
||||
free(clip->data);
|
||||
delete clip;
|
||||
} else {
|
||||
ELOG("Can't destroy zero clip");
|
||||
}
|
||||
}
|
||||
|
||||
const short *clip_data(const Clip *clip)
|
||||
{
|
||||
return clip->data;
|
||||
}
|
||||
|
||||
size_t clip_length(const Clip *clip) {
|
||||
return clip->length;
|
||||
}
|
||||
|
||||
void clip_set_loop(Clip *clip, int start, int end) {
|
||||
clip->loop_start = start;
|
||||
clip->loop_end = end;
|
||||
}
|
||||
|
||||
PlayParams *mixer_play_clip(Mixer *mixer, const Clip *clip, int channel) {
|
||||
if (channel == -1) {
|
||||
channel = get_free_channel(mixer);
|
||||
}
|
||||
|
||||
Channel *chan = &mixer->channels[channel];
|
||||
// Think about this order and make sure it's thread"safe" (not perfect but should not cause crashes).
|
||||
chan->pos = 0;
|
||||
chan->current_clip = clip;
|
||||
chan->state = PB_PLAYING;
|
||||
PlayParams *params = &chan->params;
|
||||
params->volume = 128;
|
||||
params->pan = 128;
|
||||
return params;
|
||||
}
|
||||
|
||||
void mixer_mix(Mixer *mixer, short *buffer, int num_samples) {
|
||||
// Clear the buffer.
|
||||
memset(buffer, 0, num_samples * sizeof(short) * 2);
|
||||
for (int i = 0; i < mixer->num_channels; i++) {
|
||||
Channel *chan = &mixer->channels[i];
|
||||
if (chan->state == PB_PLAYING) {
|
||||
const Clip *clip = chan->current_clip;
|
||||
if (clip->type == CT_PCM16) {
|
||||
// For now, only allow mono PCM
|
||||
CHECK(clip->num_channels == 1);
|
||||
if (true || chan->params.delta == 0) {
|
||||
// Fast playback of non pitched clips
|
||||
int cnt = num_samples;
|
||||
if (clip->length - chan->pos < cnt) {
|
||||
cnt = clip->length - chan->pos;
|
||||
}
|
||||
// TODO: Take pan into account.
|
||||
int left_volume = chan->params.volume;
|
||||
int right_volume = chan->params.volume;
|
||||
// TODO: NEONize. Can also make special loops for left_volume == right_volume etc.
|
||||
for (int s = 0; s < cnt; s++) {
|
||||
int cdata = clip->data[chan->pos];
|
||||
buffer[s * 2 + 0] += cdata * left_volume >> 8;
|
||||
buffer[s * 2 + 1] += cdata * right_volume >> 8;
|
||||
chan->pos++;
|
||||
}
|
||||
if (chan->pos >= clip->length) {
|
||||
chan->state = PB_STOPPED;
|
||||
chan->current_clip = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (clip->type == CT_VORBIS) {
|
||||
// For music
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
43
ext/native/audio/mixer.h
Normal file
43
ext/native/audio/mixer.h
Normal file
@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include "base/basictypes.h"
|
||||
|
||||
// Simple mixer intended for sound effects for games.
|
||||
// The clip loading code supports ogg SFX.
|
||||
|
||||
struct Mixer;
|
||||
struct Clip;
|
||||
struct Channel;
|
||||
|
||||
// This struct is public for easy manipulation of running channels.
|
||||
struct PlayParams {
|
||||
uint8_t volume; // 0-255
|
||||
uint8_t pan; // 0-255, 127 is dead center.
|
||||
int32_t delta;
|
||||
};
|
||||
|
||||
// Mixer
|
||||
// ==========================
|
||||
// For now, channels is required to be 2 (it specifies L/R, not mixing channels)
|
||||
Mixer *mixer_create(int sample_rate, int channels, int fixed_channels);
|
||||
void mixer_destroy(Mixer *mixer);
|
||||
|
||||
// Buffer must be r/w.
|
||||
void mixer_mix(Mixer *mixer, short *buffer, int num_samples);
|
||||
|
||||
|
||||
// Clip
|
||||
// ==========================
|
||||
Clip *clip_load(const char *filename);
|
||||
void clip_destroy(Clip *clip);
|
||||
|
||||
const short *clip_data(const Clip *clip);
|
||||
size_t clip_length(const Clip *clip);
|
||||
void clip_set_loop(int start, int end);
|
||||
|
||||
|
||||
// The returned PlayState pointer can be used to set the playback parameters,
|
||||
// but must not be kept around unless you are using a fixed channel.
|
||||
// Channel must be either -1 for auto assignment to a free channel, or less
|
||||
// than the number of fixed channels that the mixer was created with.
|
||||
PlayParams *mixer_play_clip(Mixer *mixer, const Clip *clip, int channel);
|
70
ext/native/audio/wav_read.cpp
Normal file
70
ext/native/audio/wav_read.cpp
Normal file
@ -0,0 +1,70 @@
|
||||
#include "base/basictypes.h"
|
||||
#include "base/logging.h"
|
||||
#include "audio/wav_read.h"
|
||||
#include "file/chunk_file.h"
|
||||
|
||||
short *wav_read(const char *filename,
|
||||
int *num_samples, int *sample_rate,
|
||||
int *num_channels)
|
||||
{
|
||||
ChunkFile cf(filename, true);
|
||||
if (cf.failed()) {
|
||||
WLOG("ERROR: Wave file %s could not be opened", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
short *data = 0;
|
||||
int samplesPerSec, avgBytesPerSec,wBlockAlign,wBytesPerSample;
|
||||
if (cf.descend('RIFF')) {
|
||||
cf.readInt(); //get past 'WAVE'
|
||||
if (cf.descend('fmt ')) { //enter the format chunk
|
||||
int temp = cf.readInt();
|
||||
int format = temp & 0xFFFF;
|
||||
if (format != 1) {
|
||||
cf.ascend();
|
||||
cf.ascend();
|
||||
ELOG("Error - bad format");
|
||||
return NULL;
|
||||
}
|
||||
*num_channels = temp >> 16;
|
||||
samplesPerSec = cf.readInt();
|
||||
avgBytesPerSec = cf.readInt();
|
||||
|
||||
temp = cf.readInt();
|
||||
wBlockAlign = temp & 0xFFFF;
|
||||
wBytesPerSample = temp >> 16;
|
||||
cf.ascend();
|
||||
// ILOG("got fmt data: %i", samplesPerSec);
|
||||
} else {
|
||||
ELOG("Error - no format chunk in wav");
|
||||
cf.ascend();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (cf.descend('data')) { //enter the data chunk
|
||||
int numBytes = cf.getCurrentChunkSize();
|
||||
int numSamples = numBytes / wBlockAlign;
|
||||
data = (short *)malloc(sizeof(short) * numSamples * *num_channels);
|
||||
*num_samples = numSamples;
|
||||
if (wBlockAlign == 2 && *num_channels == 1) {
|
||||
cf.readData((uint8_t *)data,numBytes);
|
||||
} else {
|
||||
ELOG("Error - bad blockalign or channels");
|
||||
free(data);
|
||||
return NULL;
|
||||
}
|
||||
cf.ascend();
|
||||
} else {
|
||||
ELOG("Error - no data chunk in wav");
|
||||
cf.ascend();
|
||||
return NULL;
|
||||
}
|
||||
cf.ascend();
|
||||
} else {
|
||||
ELOG("Could not descend into RIFF file");
|
||||
return NULL;
|
||||
}
|
||||
*sample_rate = samplesPerSec;
|
||||
ILOG("read wav %s, length %i, rate %i", filename, *num_samples, *sample_rate);
|
||||
return data;
|
||||
}
|
7
ext/native/audio/wav_read.h
Normal file
7
ext/native/audio/wav_read.h
Normal file
@ -0,0 +1,7 @@
|
||||
#include "base/basictypes.h"
|
||||
|
||||
// Allocates a buffer that should be freed using free().
|
||||
short *wav_read(const char *filename,
|
||||
int *num_samples, int *sample_rate,
|
||||
int *num_channels);
|
||||
// TODO: Non-allocating version.
|
86
ext/native/base/BlackberryAudio.h
Normal file
86
ext/native/base/BlackberryAudio.h
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Sacha Refshauge
|
||||
*
|
||||
*/
|
||||
// Blackberry implementation of the framework.
|
||||
#ifndef BLACKBERRYAUDIO_H
|
||||
#define BLACKBERRYAUDIO_H
|
||||
|
||||
#include <AL/al.h>
|
||||
#include <AL/alc.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "base/NativeApp.h"
|
||||
|
||||
#define AUDIO_FREQ 44100
|
||||
#define SAMPLE_SIZE 2048
|
||||
class BlackberryAudio
|
||||
{
|
||||
public:
|
||||
BlackberryAudio()
|
||||
{
|
||||
alcDevice = alcOpenDevice(NULL);
|
||||
if (alContext = alcCreateContext(alcDevice, NULL))
|
||||
alcMakeContextCurrent(alContext);
|
||||
alGenSources(1, &source);
|
||||
alGenBuffers(1, &buffer);
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||
pthread_create(&thread_handle, &attr, &BlackberryAudio::staticThreadProc, this);
|
||||
}
|
||||
~BlackberryAudio()
|
||||
{
|
||||
pthread_cancel(thread_handle);
|
||||
alcMakeContextCurrent(NULL);
|
||||
if (alContext)
|
||||
{
|
||||
alcDestroyContext(alContext);
|
||||
alContext = NULL;
|
||||
}
|
||||
if (alcDevice)
|
||||
{
|
||||
alcCloseDevice(alcDevice);
|
||||
alcDevice = NULL;
|
||||
}
|
||||
}
|
||||
static void* staticThreadProc(void* arg)
|
||||
{
|
||||
return reinterpret_cast<BlackberryAudio*>(arg)->RunAudio();
|
||||
}
|
||||
private:
|
||||
void* RunAudio()
|
||||
{
|
||||
while(true)
|
||||
{
|
||||
size_t frames_ready;
|
||||
alGetSourcei(source, AL_SOURCE_STATE, &state);
|
||||
if (state != AL_PLAYING) {
|
||||
frames_ready = NativeMix((short*)stream, 5*SAMPLE_SIZE);
|
||||
}
|
||||
else
|
||||
frames_ready = 0;
|
||||
if (frames_ready > 0)
|
||||
{
|
||||
const size_t bytes_ready = frames_ready * sizeof(short) * 2;
|
||||
alSourcei(source, AL_BUFFER, 0);
|
||||
alBufferData(buffer, AL_FORMAT_STEREO16, stream, bytes_ready, AUDIO_FREQ);
|
||||
alSourcei(source, AL_BUFFER, buffer);
|
||||
alSourcePlay(source);
|
||||
// TODO: Maybe this could get behind?
|
||||
usleep((1000000 * SAMPLE_SIZE) / AUDIO_FREQ);
|
||||
}
|
||||
else
|
||||
usleep(10000);
|
||||
}
|
||||
}
|
||||
ALCdevice *alcDevice;
|
||||
ALCcontext *alContext;
|
||||
ALenum state;
|
||||
ALuint buffer;
|
||||
ALuint source;
|
||||
char stream[20*SAMPLE_SIZE];
|
||||
pthread_t thread_handle;
|
||||
};
|
||||
#endif
|
||||
|
175
ext/native/base/BlackberryDisplay.cpp
Normal file
175
ext/native/base/BlackberryDisplay.cpp
Normal file
@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Sacha Refshauge
|
||||
*
|
||||
*/
|
||||
// Blackberry implementation of the framework.
|
||||
#include "BlackberryMain.h"
|
||||
|
||||
const char* BlackberryMain::displayTypeString(int type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case SCREEN_DISPLAY_TYPE_INTERNAL:
|
||||
return "Internal"; break;
|
||||
case SCREEN_DISPLAY_TYPE_COMPOSITE:
|
||||
return "Composite"; break;
|
||||
case SCREEN_DISPLAY_TYPE_DVI:
|
||||
return "DVI"; break;
|
||||
case SCREEN_DISPLAY_TYPE_HDMI:
|
||||
return "HDMI"; break;
|
||||
case SCREEN_DISPLAY_TYPE_DISPLAYPORT:
|
||||
return "DisplayPort"; break;
|
||||
case SCREEN_DISPLAY_TYPE_OTHER:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "Unknown Port";
|
||||
}
|
||||
|
||||
void BlackberryMain::startDisplays() {
|
||||
int num_configs;
|
||||
EGLint attrib_list[]= {
|
||||
EGL_RED_SIZE, 8,
|
||||
EGL_GREEN_SIZE, 8,
|
||||
EGL_BLUE_SIZE, 8,
|
||||
EGL_DEPTH_SIZE, 24,
|
||||
EGL_STENCIL_SIZE, 8,
|
||||
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
||||
EGL_NONE};
|
||||
|
||||
const EGLint attributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
|
||||
|
||||
screen_get_context_property_iv(screen_cxt, SCREEN_PROPERTY_DISPLAY_COUNT, &ndisplays);
|
||||
egl_disp = (EGLDisplay*)calloc(ndisplays, sizeof(EGLDisplay));
|
||||
egl_surf = (EGLSurface*)calloc(ndisplays, sizeof(EGLSurface));
|
||||
displays = (dispdata_t*)calloc(ndisplays, sizeof(dispdata_t));
|
||||
screen_win = (screen_window_t *)calloc(ndisplays, sizeof(screen_window_t ));
|
||||
screen_dpy = (screen_display_t*)calloc(ndisplays, sizeof(screen_display_t));
|
||||
screen_get_context_property_pv(screen_cxt, SCREEN_PROPERTY_DISPLAYS, (void **)screen_dpy);
|
||||
|
||||
// Common data
|
||||
int usage = SCREEN_USAGE_ROTATION | SCREEN_USAGE_OPENGL_ES2;
|
||||
int format = SCREEN_FORMAT_RGBX8888;
|
||||
int sensitivity = SCREEN_SENSITIVITY_ALWAYS;
|
||||
|
||||
// Initialise every display
|
||||
for (int i = 0; i < ndisplays; i++) {
|
||||
screen_get_display_property_iv(screen_dpy[i], SCREEN_PROPERTY_TYPE, &(displays[i].type));
|
||||
screen_get_display_property_iv(screen_dpy[i], SCREEN_PROPERTY_ATTACHED, &(displays[i].attached));
|
||||
|
||||
screen_create_window(&screen_win[i], screen_cxt);
|
||||
screen_set_window_property_iv(screen_win[i], SCREEN_PROPERTY_FORMAT, &format);
|
||||
screen_set_window_property_iv(screen_win[i], SCREEN_PROPERTY_USAGE, &usage);
|
||||
screen_set_window_property_iv(screen_win[i], SCREEN_PROPERTY_SENSITIVITY, &sensitivity);
|
||||
screen_set_window_property_pv(screen_win[i], SCREEN_PROPERTY_DISPLAY, (void **)&screen_dpy[i]);
|
||||
|
||||
egl_disp[i] = eglGetDisplay((EGLNativeDisplayType)i);
|
||||
eglInitialize(egl_disp[i], NULL, NULL);
|
||||
if (egl_cont == EGL_NO_CONTEXT) {
|
||||
eglChooseConfig(egl_disp[0], attrib_list, &egl_conf, 1, &num_configs);
|
||||
egl_cont = eglCreateContext(egl_disp[0], egl_conf, EGL_NO_CONTEXT, attributes);
|
||||
}
|
||||
|
||||
fprintf(stderr, "Display %i: %s, %s\n", i, displayTypeString(displays[i].type), displays[i].attached ? "Attached" : "Detached");
|
||||
if (displays[i].attached)
|
||||
realiseDisplay(i);
|
||||
}
|
||||
#ifdef ARM
|
||||
screen_get_display_property_iv(screen_dpy[0], SCREEN_PROPERTY_DPI, &dpi); // Only internal display has DPI
|
||||
// We only use dpi to calculate the width. Smaller aspect ratios have giant text despite high DPI.
|
||||
dpi = dpi * (((float)displays[0].width/(float)displays[0].height) / (16.0/9.0)); // Adjust to 16:9
|
||||
#else
|
||||
dpi = 340.0f;
|
||||
#endif
|
||||
g_dpi_scale = 210.0f / dpi;
|
||||
switchDisplay(screen_ui);
|
||||
}
|
||||
|
||||
void BlackberryMain::realiseDisplay(int idx) {
|
||||
const EGLint egl_surfaceAttr[] = { EGL_RENDER_BUFFER, EGL_BACK_BUFFER, EGL_NONE };
|
||||
int size[2] = { atoi(getenv("WIDTH")), atoi(getenv("HEIGHT")) };
|
||||
if (idx != 0)
|
||||
screen_get_display_property_iv(screen_dpy[idx], SCREEN_PROPERTY_SIZE, size);
|
||||
|
||||
displays[idx].width = size[0];
|
||||
displays[idx].height = size[1];
|
||||
screen_set_window_property_iv(screen_win[idx], SCREEN_PROPERTY_BUFFER_SIZE, size);
|
||||
screen_create_window_buffers(screen_win[idx], 2); // Double buffered
|
||||
fprintf(stderr, "Display %i realised with %ix%i\n", idx, size[0], size[1]);
|
||||
|
||||
egl_surf[idx] = eglCreateWindowSurface(egl_disp[idx], egl_conf, screen_win[idx], egl_surfaceAttr);
|
||||
|
||||
// Only enable for devices with hardware QWERTY, 1:1 aspect ratio
|
||||
if ((pixel_xres == pixel_yres) && displays[idx].type != SCREEN_DISPLAY_TYPE_INTERNAL)
|
||||
{
|
||||
screen_emu = idx;
|
||||
if (emulating)
|
||||
switchDisplay(idx);
|
||||
}
|
||||
|
||||
displays[idx].realised = true;
|
||||
}
|
||||
|
||||
void BlackberryMain::unrealiseDisplay(int idx) {
|
||||
if (displays[idx].type != SCREEN_DISPLAY_TYPE_INTERNAL) // Always true, only external can unrealise
|
||||
{
|
||||
screen_emu = screen_ui;
|
||||
if (emulating)
|
||||
switchDisplay(screen_ui);
|
||||
}
|
||||
killDisplay(idx, false);
|
||||
displays[idx].realised = false;
|
||||
}
|
||||
|
||||
void BlackberryMain::switchDisplay(int idx) {
|
||||
static int screen_curr = -1;
|
||||
if (idx != screen_curr) {
|
||||
pixel_xres = displays[idx].width;
|
||||
pixel_yres = displays[idx].height;
|
||||
dp_xres = (int)(pixel_xres * g_dpi_scale);
|
||||
dp_yres = (int)(pixel_yres * g_dpi_scale);
|
||||
screen_curr = idx;
|
||||
eglMakeCurrent(egl_disp[idx], egl_surf[idx], egl_surf[idx], egl_cont);
|
||||
}
|
||||
if (emulating) {
|
||||
PSP_CoreParameter().pixelWidth = pixel_xres;
|
||||
PSP_CoreParameter().pixelHeight = pixel_yres;
|
||||
}
|
||||
}
|
||||
|
||||
void BlackberryMain::killDisplays() {
|
||||
for (int i = 0; i < ndisplays; i++) {
|
||||
killDisplay(i, true);
|
||||
}
|
||||
if (egl_cont != EGL_NO_CONTEXT) {
|
||||
eglDestroyContext(egl_disp[0], egl_cont);
|
||||
egl_cont = EGL_NO_CONTEXT;
|
||||
}
|
||||
free(egl_disp);
|
||||
free(egl_surf);
|
||||
eglReleaseThread();
|
||||
free(screen_dpy);
|
||||
}
|
||||
|
||||
void BlackberryMain::killDisplay(int idx, bool killContext) {
|
||||
if (egl_disp[idx] != EGL_NO_DISPLAY) {
|
||||
if (killContext)
|
||||
eglMakeCurrent(egl_disp[idx], EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
if (egl_surf[idx] != EGL_NO_SURFACE) {
|
||||
eglDestroySurface(egl_disp[idx], egl_surf[idx]);
|
||||
egl_surf[idx] = EGL_NO_SURFACE;
|
||||
}
|
||||
if (killContext)
|
||||
{
|
||||
eglTerminate(egl_disp[idx]);
|
||||
egl_disp[idx] = EGL_NO_DISPLAY;
|
||||
}
|
||||
}
|
||||
if (killContext && screen_win[idx] != NULL) {
|
||||
screen_destroy_window(screen_win[idx]);
|
||||
screen_win[idx] = NULL;
|
||||
}
|
||||
screen_destroy_window_buffers(screen_win[idx]);
|
||||
}
|
||||
|
359
ext/native/base/BlackberryMain.cpp
Normal file
359
ext/native/base/BlackberryMain.cpp
Normal file
@ -0,0 +1,359 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Sacha Refshauge
|
||||
*
|
||||
*/
|
||||
// Blackberry implementation of the framework.
|
||||
|
||||
#include <pwd.h>
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
|
||||
#include <bps/locale.h> // Get locale
|
||||
#include <bps/navigator_invoke.h> // Receive invocation messages
|
||||
#include "BlackberryMain.h"
|
||||
#include "base/NKCodeFromBlackberry.h"
|
||||
|
||||
// Bad: PPSSPP includes from native
|
||||
#include "Core/System.h"
|
||||
#include "Core/Config.h"
|
||||
#include "Core/Core.h"
|
||||
#include "UI/MiscScreens.h"
|
||||
|
||||
static bool g_quitRequested = false;
|
||||
|
||||
// Simple implementations of System functions
|
||||
|
||||
std::string System_GetProperty(SystemProperty prop) {
|
||||
switch (prop) {
|
||||
case SYSPROP_NAME: {
|
||||
std::string name = "Blackberry:";
|
||||
#ifdef ARM
|
||||
return name + ((pixel_xres != pixel_yres) ? "Touch" : "QWERTY");
|
||||
#else
|
||||
return name + "Simulator";
|
||||
#endif
|
||||
}
|
||||
case SYSPROP_LANGREGION: {
|
||||
char *locale = 0;
|
||||
locale_get_locale(&locale);
|
||||
return std::string(locale);
|
||||
}
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
int System_GetPropertyInt(SystemProperty prop) {
|
||||
switch (prop) {
|
||||
case SYSPROP_AUDIO_SAMPLE_RATE:
|
||||
return 44100;
|
||||
case SYSPROP_DISPLAY_REFRESH_RATE:
|
||||
return 60000;
|
||||
case SYSPROP_DEVICE_TYPE:
|
||||
return DEVICE_TYPE_MOBILE;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void System_SendMessage(const char *command, const char *parameter) {
|
||||
if (!strcmp(command, "finish")) {
|
||||
g_quitRequested = true;
|
||||
}
|
||||
}
|
||||
|
||||
void SystemToast(const char *text) {
|
||||
dialog_instance_t dialog = 0;
|
||||
dialog_create_toast(&dialog);
|
||||
dialog_set_toast_message_text(dialog, text);
|
||||
dialog_set_toast_position(dialog, DIALOG_POSITION_TOP_CENTER);
|
||||
dialog_show(dialog);
|
||||
}
|
||||
|
||||
void ShowAd(int x, int y, bool center_x) {
|
||||
}
|
||||
|
||||
void ShowKeyboard() {
|
||||
virtualkeyboard_show();
|
||||
}
|
||||
|
||||
void Vibrate(int length_ms) {
|
||||
// Vibration: intensity strength(1-100), duration ms(0-5000)
|
||||
// Intensity: LOW = 1, MEDIUM = 10, HIGH = 100
|
||||
switch (length_ms) {
|
||||
case -1: // Keyboard Tap
|
||||
vibration_request(VIBRATION_INTENSITY_LOW, 50);
|
||||
break;
|
||||
case -2: // Virtual Key
|
||||
vibration_request(VIBRATION_INTENSITY_LOW, 25);
|
||||
break;
|
||||
case -3: // Long Press
|
||||
vibration_request(VIBRATION_INTENSITY_LOW, 50);
|
||||
break;
|
||||
default:
|
||||
vibration_request(VIBRATION_INTENSITY_LOW, length_ms);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void LaunchBrowser(const char *url)
|
||||
{
|
||||
char* error;
|
||||
navigator_invoke(url, &error);
|
||||
}
|
||||
|
||||
void LaunchMarket(const char *url)
|
||||
{
|
||||
char* error;
|
||||
navigator_invoke(url, &error);
|
||||
}
|
||||
|
||||
void LaunchEmail(const char *email_address)
|
||||
{
|
||||
char* error;
|
||||
navigator_invoke((std::string("mailto:") + email_address).c_str(), &error);
|
||||
}
|
||||
|
||||
InputState input_state;
|
||||
|
||||
void BlackberryMain::handleInput(screen_event_t screen_event)
|
||||
{
|
||||
TouchInput input;
|
||||
KeyInput key;
|
||||
int val, buttons, pointerId;
|
||||
int pair[2];
|
||||
screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TYPE, &val);
|
||||
screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_SOURCE_POSITION, pair);
|
||||
|
||||
input_state.mouse_valid = true;
|
||||
switch(val)
|
||||
{
|
||||
// Touchscreen
|
||||
case SCREEN_EVENT_MTOUCH_TOUCH:
|
||||
case SCREEN_EVENT_MTOUCH_RELEASE: // Up, down
|
||||
screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TOUCH_ID, &pointerId);
|
||||
input_state.pointer_down[pointerId] = (val == SCREEN_EVENT_MTOUCH_TOUCH);
|
||||
input_state.pointer_x[pointerId] = pair[0] * g_dpi_scale;
|
||||
input_state.pointer_y[pointerId] = pair[1] * g_dpi_scale;
|
||||
|
||||
input.x = pair[0] * g_dpi_scale;
|
||||
input.y = pair[1] * g_dpi_scale;
|
||||
input.flags = (val == SCREEN_EVENT_MTOUCH_TOUCH) ? TOUCH_DOWN : TOUCH_UP;
|
||||
input.id = pointerId;
|
||||
NativeTouch(input);
|
||||
break;
|
||||
case SCREEN_EVENT_MTOUCH_MOVE:
|
||||
screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TOUCH_ID, &pointerId);
|
||||
input_state.pointer_x[pointerId] = pair[0] * g_dpi_scale;
|
||||
input_state.pointer_y[pointerId] = pair[1] * g_dpi_scale;
|
||||
|
||||
input.x = pair[0] * g_dpi_scale;
|
||||
input.y = pair[1] * g_dpi_scale;
|
||||
input.flags = TOUCH_MOVE;
|
||||
input.id = pointerId;
|
||||
NativeTouch(input);
|
||||
break;
|
||||
// Mouse, Simulator
|
||||
case SCREEN_EVENT_POINTER:
|
||||
screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_BUTTONS, &buttons);
|
||||
if (buttons == SCREEN_LEFT_MOUSE_BUTTON) { // Down
|
||||
input_state.pointer_x[0] = pair[0] * g_dpi_scale;
|
||||
input_state.pointer_y[0] = pair[1] * g_dpi_scale;
|
||||
input_state.pointer_down[0] = true;
|
||||
|
||||
input.x = pair[0] * g_dpi_scale;
|
||||
input.y = pair[1] * g_dpi_scale;
|
||||
input.flags = TOUCH_DOWN;
|
||||
input.id = 0;
|
||||
NativeTouch(input);
|
||||
} else if (input_state.pointer_down[0]) { // Up
|
||||
input_state.pointer_x[0] = pair[0] * g_dpi_scale;
|
||||
input_state.pointer_y[0] = pair[1] * g_dpi_scale;
|
||||
input_state.pointer_down[0] = false;
|
||||
|
||||
input.x = pair[0] * g_dpi_scale;
|
||||
input.y = pair[1] * g_dpi_scale;
|
||||
input.flags = TOUCH_UP;
|
||||
input.id = 0;
|
||||
NativeTouch(input);
|
||||
}
|
||||
break;
|
||||
// Keyboard
|
||||
case SCREEN_EVENT_KEYBOARD:
|
||||
int flags, value;
|
||||
screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_KEY_FLAGS, &flags);
|
||||
screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_KEY_SYM, &value);
|
||||
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, KeyMapRawBlackberrytoNative.find(value)->second, (flags & KEY_DOWN) ? KEY_DOWN : KEY_UP));
|
||||
break;
|
||||
// Gamepad
|
||||
case SCREEN_EVENT_GAMEPAD:
|
||||
case SCREEN_EVENT_JOYSTICK:
|
||||
int analog0[3];
|
||||
screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_BUTTONS, &buttons);
|
||||
for (int i = 0; i < 32; i++) {
|
||||
int mask = 1 << i;
|
||||
if ((old_buttons & mask) != (buttons & mask))
|
||||
NativeKey(KeyInput(DEVICE_ID_PAD_0, KeyMapPadBlackberrytoNative.find(mask)->second, (buttons & mask) ? KEY_DOWN : KEY_UP));
|
||||
}
|
||||
if (!screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_ANALOG0, analog0)) {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
AxisInput axis;
|
||||
axis.axisId = JOYSTICK_AXIS_X + i;
|
||||
// 1.2 to try to approximate the PSP's clamped rectangular range.
|
||||
axis.value = 1.2 * analog0[i] / 128.0f;
|
||||
if (axis.value > 1.0f) axis.value = 1.0f;
|
||||
if (axis.value < -1.0f) axis.value = -1.0f;
|
||||
axis.deviceId = DEVICE_ID_PAD_0;
|
||||
axis.flags = 0;
|
||||
NativeAxis(axis);
|
||||
}
|
||||
}
|
||||
old_buttons = buttons;
|
||||
break;
|
||||
case SCREEN_EVENT_DISPLAY:
|
||||
screen_display_t new_dpy = NULL;
|
||||
screen_get_event_property_pv(screen_event, SCREEN_PROPERTY_DISPLAY, (void **)&new_dpy);
|
||||
for (int i = 0; i < ndisplays; i++) {
|
||||
if (new_dpy != screen_dpy[i])
|
||||
continue;
|
||||
int active = 0;
|
||||
screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_ATTACHED, &active);
|
||||
if (active) {
|
||||
int size[2];
|
||||
screen_get_display_property_iv(screen_dpy[i], SCREEN_PROPERTY_SIZE, size);
|
||||
if (size[0] == 0 || size[1] == 0)
|
||||
active = 0;
|
||||
}
|
||||
if (active && !displays[i].attached)
|
||||
realiseDisplay(i);
|
||||
else if (!active && displays[i].attached && displays[i].realised)
|
||||
unrealiseDisplay(i);
|
||||
displays[i].attached = active;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void BlackberryMain::startMain(int argc, char *argv[]) {
|
||||
g_quitRequested = false;
|
||||
// Receive events from window manager
|
||||
screen_create_context(&screen_cxt, 0);
|
||||
// Initialise Blackberry Platform Services
|
||||
bps_initialize();
|
||||
// TODO: Enable/disable based on setting
|
||||
sensor_set_rate(SENSOR_TYPE_ACCELEROMETER, 25000);
|
||||
sensor_request_events(SENSOR_TYPE_ACCELEROMETER);
|
||||
|
||||
net::Init();
|
||||
startDisplays();
|
||||
screen_request_events(screen_cxt);
|
||||
navigator_request_events(0);
|
||||
dialog_request_events(0);
|
||||
vibration_request_events(0);
|
||||
NativeInit(argc, (const char **)argv, "/accounts/1000/shared/misc/", "app/native/assets/", "BADCOFFEE");
|
||||
NativeInitGraphics();
|
||||
audio = new BlackberryAudio();
|
||||
runMain();
|
||||
}
|
||||
|
||||
void BlackberryMain::runMain() {
|
||||
bool running = true;
|
||||
while (running && !g_quitRequested) {
|
||||
input_state.mouse_valid = false;
|
||||
input_state.accelerometer_valid = false;
|
||||
while (true) {
|
||||
// Handle Blackberry events
|
||||
bps_event_t *event = NULL;
|
||||
bps_get_event(&event, 0);
|
||||
if (event == NULL)
|
||||
break; // Ran out of events
|
||||
int domain = bps_event_get_domain(event);
|
||||
if (domain == screen_get_domain()) {
|
||||
handleInput(screen_event_get_event(event));
|
||||
} else if (domain == navigator_get_domain()) {
|
||||
switch(bps_event_get_code(event))
|
||||
{
|
||||
case NAVIGATOR_INVOKE_TARGET:
|
||||
{
|
||||
const navigator_invoke_invocation_t *invoke = navigator_invoke_event_get_invocation(event);
|
||||
if(invoke) {
|
||||
boot_filename = navigator_invoke_invocation_get_uri(invoke)+7; // Remove file://
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NAVIGATOR_ORIENTATION:
|
||||
sensor_remap_coordinates(navigator_event_get_orientation_angle(event));
|
||||
break;
|
||||
case NAVIGATOR_WINDOW_STATE:
|
||||
Core_NotifyWindowHidden(navigator_event_get_window_state(event) != NAVIGATOR_WINDOW_FULLSCREEN);
|
||||
break;
|
||||
case NAVIGATOR_BACK:
|
||||
case NAVIGATOR_SWIPE_DOWN:
|
||||
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_BACK, KEY_DOWN));
|
||||
break;
|
||||
case NAVIGATOR_EXIT:
|
||||
return;
|
||||
}
|
||||
} else if (domain == sensor_get_domain()) {
|
||||
if (SENSOR_ACCELEROMETER_READING == bps_event_get_code(event)) {
|
||||
sensor_event_get_xyz(event, &(input_state.acc.y), &(input_state.acc.x), &(input_state.acc.z));
|
||||
AxisInput axis;
|
||||
axis.deviceId = DEVICE_ID_ACCELEROMETER;
|
||||
axis.flags = 0;
|
||||
|
||||
axis.axisId = JOYSTICK_AXIS_ACCELEROMETER_X;
|
||||
axis.value = input_state.acc.x;
|
||||
NativeAxis(axis);
|
||||
|
||||
axis.axisId = JOYSTICK_AXIS_ACCELEROMETER_Y;
|
||||
axis.value = input_state.acc.y;
|
||||
NativeAxis(axis);
|
||||
|
||||
axis.axisId = JOYSTICK_AXIS_ACCELEROMETER_Z;
|
||||
axis.value = input_state.acc.z;
|
||||
NativeAxis(axis);
|
||||
}
|
||||
}
|
||||
}
|
||||
UpdateInputState(&input_state);
|
||||
// Work in Progress
|
||||
// Currently: Render to HDMI port (eg. 1080p) when in game. Render to device when in menu.
|
||||
// Idea: Render to all displays. Controls go to internal, game goes to external(s).
|
||||
if (GetUIState() == UISTATE_INGAME && !emulating) {
|
||||
emulating = true;
|
||||
switchDisplay(screen_emu);
|
||||
if (g_Config.iShowFPSCounter == 4) {
|
||||
int options = SCREEN_DEBUG_STATISTICS;
|
||||
screen_set_window_property_iv(screen_win[0], SCREEN_PROPERTY_DEBUG, &options);
|
||||
}
|
||||
} else if (GetUIState() != UISTATE_INGAME && emulating) {
|
||||
emulating = false;
|
||||
switchDisplay(screen_ui);
|
||||
}
|
||||
time_update();
|
||||
UpdateRunLoop();
|
||||
// This handles VSync
|
||||
if (emulating)
|
||||
eglSwapBuffers(egl_disp[screen_emu], egl_surf[screen_emu]);
|
||||
else
|
||||
eglSwapBuffers(egl_disp[screen_ui], egl_surf[screen_ui]);
|
||||
}
|
||||
}
|
||||
|
||||
void BlackberryMain::endMain() {
|
||||
screen_stop_events(screen_cxt);
|
||||
bps_shutdown();
|
||||
NativeShutdownGraphics();
|
||||
delete audio;
|
||||
NativeShutdown();
|
||||
killDisplays();
|
||||
net::Shutdown();
|
||||
screen_destroy_context(screen_cxt);
|
||||
}
|
||||
|
||||
// Entry Point
|
||||
int main(int argc, char *argv[]) {
|
||||
delete new BlackberryMain(argc, argv);
|
||||
return 0;
|
||||
}
|
93
ext/native/base/BlackberryMain.h
Normal file
93
ext/native/base/BlackberryMain.h
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Sacha Refshauge
|
||||
*
|
||||
*/
|
||||
// Blackberry implementation of the framework.
|
||||
#ifndef BLACKBERRYMAIN_H
|
||||
#define BLACKBERRYMAIN_H
|
||||
|
||||
// Blackberry specific
|
||||
#include <bps/bps.h> // Blackberry Platform Services
|
||||
#include <bps/screen.h> // Blackberry Window Manager
|
||||
#include <bps/navigator.h> // Invoke Service
|
||||
#include <bps/virtualkeyboard.h>// Keyboard Service
|
||||
#include <bps/sensor.h> // Accelerometer
|
||||
#include <bps/dialog.h> // Dialog Service (Toast=BB10)
|
||||
#include <bps/vibration.h> // Vibrate Service (BB10)
|
||||
#include "sys/keycodes.h"
|
||||
#include "input/keycodes.h"
|
||||
|
||||
// Display
|
||||
#include <EGL/egl.h>
|
||||
#include <screen/screen.h>
|
||||
#include <sys/platform.h>
|
||||
#include <GLES2/gl2.h>
|
||||
#include "Core/System.h"
|
||||
|
||||
// Native
|
||||
#include "base/timeutil.h"
|
||||
#include "gfx_es2/glsl_program.h"
|
||||
#include "file/zip_read.h"
|
||||
#include "base/NativeApp.h"
|
||||
#include "input/input_state.h"
|
||||
#include "net/resolve.h"
|
||||
#include "base/display.h"
|
||||
|
||||
#include "BlackberryAudio.h"
|
||||
|
||||
struct dispdata_t {
|
||||
int attached;
|
||||
int type;
|
||||
bool realised;
|
||||
int width, height;
|
||||
};
|
||||
|
||||
class BlackberryMain
|
||||
{
|
||||
public:
|
||||
BlackberryMain(int argc, char *argv[]) :
|
||||
emulating(false),
|
||||
screen_ui(0), screen_emu(0),
|
||||
old_buttons(0),
|
||||
egl_cont(EGL_NO_CONTEXT)
|
||||
{
|
||||
startMain(argc, argv);
|
||||
}
|
||||
~BlackberryMain() {
|
||||
endMain();
|
||||
}
|
||||
void startMain(int argc, char *argv[]);
|
||||
|
||||
private:
|
||||
void runMain();
|
||||
void endMain();
|
||||
|
||||
void handleInput(screen_event_t screen_event);
|
||||
|
||||
const char* displayTypeString(int type);
|
||||
void startDisplays();
|
||||
void* startDisplay(int idx);
|
||||
void realiseDisplay(int idx);
|
||||
void unrealiseDisplay(int idx);
|
||||
void switchDisplay(int idx);
|
||||
void killDisplays();
|
||||
void killDisplay(int idx, bool killContext);
|
||||
|
||||
BlackberryAudio* audio;
|
||||
dispdata_t *displays;
|
||||
int dpi;
|
||||
int ndisplays;
|
||||
int screen_ui, screen_emu;
|
||||
bool emulating;
|
||||
int old_buttons;
|
||||
EGLDisplay* egl_disp;
|
||||
EGLSurface* egl_surf;
|
||||
EGLContext egl_cont;
|
||||
EGLConfig egl_conf;
|
||||
screen_context_t screen_cxt;
|
||||
screen_display_t *screen_dpy;
|
||||
screen_window_t *screen_win;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
20
ext/native/base/CMakeLists.txt
Normal file
20
ext/native/base/CMakeLists.txt
Normal file
@ -0,0 +1,20 @@
|
||||
set(SRCS
|
||||
colorutil.cpp
|
||||
timeutil.cpp
|
||||
../thread/threadutil.cpp
|
||||
error_context.cpp
|
||||
display.cpp
|
||||
buffer.cpp
|
||||
backtrace.cpp)
|
||||
|
||||
add_library(base STATIC ${SRCS})
|
||||
|
||||
if(UNIX)
|
||||
add_definitions(-fPIC)
|
||||
endif(UNIX)
|
||||
|
||||
add_library(timeutil STATIC timeutil.cpp)
|
||||
|
||||
if(UNIX)
|
||||
add_definitions(-fPIC)
|
||||
endif(UNIX)
|
100
ext/native/base/NKCodeFromBlackberry.h
Normal file
100
ext/native/base/NKCodeFromBlackberry.h
Normal file
@ -0,0 +1,100 @@
|
||||
#include <map>
|
||||
#include "util/const_map.h"
|
||||
|
||||
static const std::map<int, int> KeyMapPadBlackberrytoNative = InitConstMap<int, int>
|
||||
(SCREEN_A_GAME_BUTTON, NKCODE_BUTTON_A)
|
||||
(SCREEN_B_GAME_BUTTON, NKCODE_BUTTON_B)
|
||||
(SCREEN_C_GAME_BUTTON, NKCODE_BUTTON_C)
|
||||
(SCREEN_X_GAME_BUTTON, NKCODE_BUTTON_X)
|
||||
(SCREEN_Y_GAME_BUTTON, NKCODE_BUTTON_Y)
|
||||
(SCREEN_Z_GAME_BUTTON, NKCODE_BUTTON_Z)
|
||||
(SCREEN_MENU1_GAME_BUTTON, NKCODE_BUTTON_START)
|
||||
(SCREEN_MENU2_GAME_BUTTON, NKCODE_BUTTON_SELECT)
|
||||
(SCREEN_MENU3_GAME_BUTTON, NKCODE_MENU)
|
||||
(SCREEN_MENU4_GAME_BUTTON, NKCODE_BACK)
|
||||
(SCREEN_L1_GAME_BUTTON, NKCODE_BUTTON_L1)
|
||||
(SCREEN_L2_GAME_BUTTON, NKCODE_BUTTON_L2)
|
||||
(SCREEN_L3_GAME_BUTTON, NKCODE_OUYA_BUTTON_L3)
|
||||
(SCREEN_R1_GAME_BUTTON, NKCODE_BUTTON_R1)
|
||||
(SCREEN_R2_GAME_BUTTON, NKCODE_BUTTON_R2)
|
||||
(SCREEN_R3_GAME_BUTTON, NKCODE_OUYA_BUTTON_R3)
|
||||
(SCREEN_DPAD_UP_GAME_BUTTON, NKCODE_DPAD_UP)
|
||||
(SCREEN_DPAD_DOWN_GAME_BUTTON, NKCODE_DPAD_DOWN)
|
||||
(SCREEN_DPAD_LEFT_GAME_BUTTON, NKCODE_DPAD_LEFT)
|
||||
(SCREEN_DPAD_RIGHT_GAME_BUTTON, NKCODE_DPAD_RIGHT);
|
||||
|
||||
// TODO: Add any missing keys
|
||||
static const std::map<int, int> KeyMapRawBlackberrytoNative = InitConstMap<int, int>
|
||||
(KEYCODE_P, NKCODE_P)
|
||||
(KEYCODE_O, NKCODE_O)
|
||||
(KEYCODE_I, NKCODE_I)
|
||||
(KEYCODE_U, NKCODE_U)
|
||||
(KEYCODE_Y, NKCODE_Y)
|
||||
(KEYCODE_T, NKCODE_T)
|
||||
(KEYCODE_R, NKCODE_R)
|
||||
(KEYCODE_E, NKCODE_E)
|
||||
(KEYCODE_W, NKCODE_W)
|
||||
(KEYCODE_Q, NKCODE_Q)
|
||||
(KEYCODE_L, NKCODE_L)
|
||||
(KEYCODE_K, NKCODE_K)
|
||||
(KEYCODE_J, NKCODE_J)
|
||||
(KEYCODE_H, NKCODE_H)
|
||||
(KEYCODE_G, NKCODE_G)
|
||||
(KEYCODE_F, NKCODE_F)
|
||||
(KEYCODE_D, NKCODE_D)
|
||||
(KEYCODE_S, NKCODE_S)
|
||||
(KEYCODE_A, NKCODE_A)
|
||||
(KEYCODE_M, NKCODE_M)
|
||||
(KEYCODE_N, NKCODE_N)
|
||||
(KEYCODE_B, NKCODE_B)
|
||||
(KEYCODE_V, NKCODE_V)
|
||||
(KEYCODE_C, NKCODE_C)
|
||||
(KEYCODE_X, NKCODE_X)
|
||||
(KEYCODE_Z, NKCODE_Z)
|
||||
(KEYCODE_COMMA, NKCODE_COMMA)
|
||||
(KEYCODE_PERIOD, NKCODE_PERIOD)
|
||||
(KEYCODE_LEFT_ALT, NKCODE_ALT_LEFT)
|
||||
(KEYCODE_RIGHT_ALT, NKCODE_ALT_RIGHT)
|
||||
(KEYCODE_LEFT_SHIFT, NKCODE_SHIFT_LEFT)
|
||||
(KEYCODE_RIGHT_SHIFT, NKCODE_SHIFT_RIGHT)
|
||||
(KEYCODE_TAB, NKCODE_TAB)
|
||||
(KEYCODE_SPACE, NKCODE_SPACE)
|
||||
(KEYCODE_RETURN, NKCODE_ENTER)
|
||||
(KEYCODE_MINUS, NKCODE_MINUS)
|
||||
(KEYCODE_EQUAL, NKCODE_EQUALS)
|
||||
(KEYCODE_LEFT_BRACKET, NKCODE_LEFT_BRACKET)
|
||||
(KEYCODE_RIGHT_BRACKET, NKCODE_RIGHT_BRACKET)
|
||||
(KEYCODE_BACK_SLASH, NKCODE_BACKSLASH)
|
||||
(KEYCODE_SEMICOLON, NKCODE_SEMICOLON)
|
||||
(KEYCODE_APOSTROPHE, NKCODE_APOSTROPHE)
|
||||
(KEYCODE_SLASH, NKCODE_SLASH)
|
||||
(KEYCODE_AT, NKCODE_AT)
|
||||
(KEYCODE_PLUS, NKCODE_PLUS)
|
||||
(KEYCODE_ESCAPE, NKCODE_ESCAPE)
|
||||
(KEYCODE_DELETE, NKCODE_FORWARD_DEL)
|
||||
(KEYCODE_LEFT_CTRL, NKCODE_CTRL_LEFT)
|
||||
(KEYCODE_RIGHT_CTRL, NKCODE_CTRL_RIGHT)
|
||||
(KEYCODE_CAPS_LOCK, NKCODE_CAPS_LOCK)
|
||||
(KEYCODE_HOME, NKCODE_MOVE_HOME)
|
||||
(KEYCODE_END, NKCODE_MOVE_END)
|
||||
(KEYCODE_INSERT, NKCODE_INSERT)
|
||||
(KEYCODE_ZERO, NKCODE_0)
|
||||
(KEYCODE_ONE, NKCODE_1)
|
||||
(KEYCODE_TWO, NKCODE_2)
|
||||
(KEYCODE_THREE, NKCODE_3)
|
||||
(KEYCODE_FOUR, NKCODE_4)
|
||||
(KEYCODE_FIVE, NKCODE_5)
|
||||
(KEYCODE_SIX, NKCODE_6)
|
||||
(KEYCODE_SEVEN, NKCODE_7)
|
||||
(KEYCODE_EIGHT, NKCODE_8)
|
||||
(KEYCODE_NINE, NKCODE_9)
|
||||
(KEYCODE_KP_DIVIDE, NKCODE_NUMPAD_DIVIDE)
|
||||
(KEYCODE_KP_MULTIPLY, NKCODE_NUMPAD_MULTIPLY)
|
||||
(KEYCODE_KP_MINUS, NKCODE_NUMPAD_SUBTRACT)
|
||||
(KEYCODE_KP_PLUS, NKCODE_NUMPAD_ADD)
|
||||
(KEYCODE_KP_ENTER, NKCODE_NUMPAD_ENTER)
|
||||
(KEYCODE_LEFT, NKCODE_DPAD_LEFT)
|
||||
(KEYCODE_UP, NKCODE_DPAD_UP)
|
||||
(KEYCODE_RIGHT, NKCODE_DPAD_RIGHT)
|
||||
(KEYCODE_DOWN, NKCODE_DPAD_DOWN);
|
||||
|
101
ext/native/base/NKCodeFromQt.h
Normal file
101
ext/native/base/NKCodeFromQt.h
Normal file
@ -0,0 +1,101 @@
|
||||
#include "util/const_map.h"
|
||||
#include <map>
|
||||
|
||||
// TODO: Add any missing keys
|
||||
static const std::map<int, int> KeyMapRawQttoNative = InitConstMap<int, int>
|
||||
(Qt::Key_P, NKCODE_P)
|
||||
(Qt::Key_O, NKCODE_O)
|
||||
(Qt::Key_I, NKCODE_I)
|
||||
(Qt::Key_U, NKCODE_U)
|
||||
(Qt::Key_Y, NKCODE_Y)
|
||||
(Qt::Key_T, NKCODE_T)
|
||||
(Qt::Key_R, NKCODE_R)
|
||||
(Qt::Key_E, NKCODE_E)
|
||||
(Qt::Key_W, NKCODE_W)
|
||||
(Qt::Key_Q, NKCODE_Q)
|
||||
(Qt::Key_L, NKCODE_L)
|
||||
(Qt::Key_K, NKCODE_K)
|
||||
(Qt::Key_J, NKCODE_J)
|
||||
(Qt::Key_H, NKCODE_H)
|
||||
(Qt::Key_G, NKCODE_G)
|
||||
(Qt::Key_F, NKCODE_F)
|
||||
(Qt::Key_D, NKCODE_D)
|
||||
(Qt::Key_S, NKCODE_S)
|
||||
(Qt::Key_A, NKCODE_A)
|
||||
(Qt::Key_M, NKCODE_M)
|
||||
(Qt::Key_N, NKCODE_N)
|
||||
(Qt::Key_B, NKCODE_B)
|
||||
(Qt::Key_V, NKCODE_V)
|
||||
(Qt::Key_C, NKCODE_C)
|
||||
(Qt::Key_X, NKCODE_X)
|
||||
(Qt::Key_Z, NKCODE_Z)
|
||||
(Qt::Key_P + 0x20, NKCODE_P)
|
||||
(Qt::Key_O + 0x20, NKCODE_O)
|
||||
(Qt::Key_I + 0x20, NKCODE_I)
|
||||
(Qt::Key_U + 0x20, NKCODE_U)
|
||||
(Qt::Key_Y + 0x20, NKCODE_Y)
|
||||
(Qt::Key_T + 0x20, NKCODE_T)
|
||||
(Qt::Key_R + 0x20, NKCODE_R)
|
||||
(Qt::Key_E + 0x20, NKCODE_E)
|
||||
(Qt::Key_W + 0x20, NKCODE_W)
|
||||
(Qt::Key_Q + 0x20, NKCODE_Q)
|
||||
(Qt::Key_L + 0x20, NKCODE_L)
|
||||
(Qt::Key_K + 0x20, NKCODE_K)
|
||||
(Qt::Key_J + 0x20, NKCODE_J)
|
||||
(Qt::Key_H + 0x20, NKCODE_H)
|
||||
(Qt::Key_G + 0x20, NKCODE_G)
|
||||
(Qt::Key_F + 0x20, NKCODE_F)
|
||||
(Qt::Key_D + 0x20, NKCODE_D)
|
||||
(Qt::Key_S + 0x20, NKCODE_S)
|
||||
(Qt::Key_A + 0x20, NKCODE_A)
|
||||
(Qt::Key_M + 0x20, NKCODE_M)
|
||||
(Qt::Key_N + 0x20, NKCODE_N)
|
||||
(Qt::Key_B + 0x20, NKCODE_B)
|
||||
(Qt::Key_V + 0x20, NKCODE_V)
|
||||
(Qt::Key_C + 0x20, NKCODE_C)
|
||||
(Qt::Key_X + 0x20, NKCODE_X)
|
||||
(Qt::Key_Z + 0x20, NKCODE_Z)
|
||||
(Qt::Key_Comma, NKCODE_COMMA)
|
||||
(Qt::Key_Period, NKCODE_PERIOD)
|
||||
(Qt::Key_Alt, NKCODE_ALT_LEFT)
|
||||
(Qt::Key_Shift, NKCODE_SHIFT_LEFT)
|
||||
(Qt::Key_Tab, NKCODE_TAB)
|
||||
(Qt::Key_Space, NKCODE_SPACE)
|
||||
(Qt::Key_Return, NKCODE_ENTER)
|
||||
(Qt::Key_Minus, NKCODE_MINUS)
|
||||
(Qt::Key_Minus, NKCODE_PLUS)
|
||||
(Qt::Key_Equal, NKCODE_EQUALS)
|
||||
(Qt::Key_BracketLeft, NKCODE_LEFT_BRACKET)
|
||||
(Qt::Key_BracketRight, NKCODE_RIGHT_BRACKET)
|
||||
(Qt::Key_Backslash, NKCODE_BACKSLASH)
|
||||
(Qt::Key_Semicolon, NKCODE_SEMICOLON)
|
||||
(Qt::Key_Apostrophe, NKCODE_APOSTROPHE)
|
||||
(Qt::Key_Slash, NKCODE_SLASH)
|
||||
(Qt::Key_At, NKCODE_AT)
|
||||
(Qt::Key_PageUp, NKCODE_PAGE_UP)
|
||||
(Qt::Key_PageDown, NKCODE_PAGE_DOWN)
|
||||
(Qt::Key_Escape, NKCODE_ESCAPE)
|
||||
(Qt::Key_Delete, NKCODE_FORWARD_DEL)
|
||||
(Qt::Key_Control, NKCODE_CTRL_LEFT)
|
||||
(Qt::Key_CapsLock, NKCODE_CAPS_LOCK)
|
||||
(Qt::Key_Home, NKCODE_MOVE_HOME)
|
||||
(Qt::Key_End, NKCODE_MOVE_END)
|
||||
(Qt::Key_Insert, NKCODE_INSERT)
|
||||
(Qt::Key_Period, NKCODE_NUMPAD_DOT)
|
||||
(Qt::Key_Enter, NKCODE_NUMPAD_ENTER)
|
||||
(Qt::Key_1, NKCODE_1)
|
||||
(Qt::Key_2, NKCODE_2)
|
||||
(Qt::Key_3, NKCODE_3)
|
||||
(Qt::Key_4, NKCODE_4)
|
||||
(Qt::Key_5, NKCODE_5)
|
||||
(Qt::Key_6, NKCODE_6)
|
||||
(Qt::Key_7, NKCODE_7)
|
||||
(Qt::Key_8, NKCODE_8)
|
||||
(Qt::Key_9, NKCODE_9)
|
||||
(Qt::Key_0, NKCODE_0)
|
||||
(Qt::Key_Left, NKCODE_DPAD_LEFT)
|
||||
(Qt::Key_Up, NKCODE_DPAD_UP)
|
||||
(Qt::Key_Right, NKCODE_DPAD_RIGHT)
|
||||
(Qt::Key_Down, NKCODE_DPAD_DOWN)
|
||||
(Qt::Key_Back, NKCODE_BACK);
|
||||
|
111
ext/native/base/NKCodeFromSDL.h
Normal file
111
ext/native/base/NKCodeFromSDL.h
Normal file
@ -0,0 +1,111 @@
|
||||
#pragma once
|
||||
|
||||
#include "util/const_map.h"
|
||||
#include <map>
|
||||
|
||||
// TODO: Add any missing keys
|
||||
static const std::map<int, int> KeyMapRawSDLtoNative = InitConstMap<int, int>
|
||||
(SDLK_p, NKCODE_P)
|
||||
(SDLK_o, NKCODE_O)
|
||||
(SDLK_i, NKCODE_I)
|
||||
(SDLK_u, NKCODE_U)
|
||||
(SDLK_y, NKCODE_Y)
|
||||
(SDLK_t, NKCODE_T)
|
||||
(SDLK_r, NKCODE_R)
|
||||
(SDLK_e, NKCODE_E)
|
||||
(SDLK_w, NKCODE_W)
|
||||
(SDLK_q, NKCODE_Q)
|
||||
(SDLK_l, NKCODE_L)
|
||||
(SDLK_k, NKCODE_K)
|
||||
(SDLK_j, NKCODE_J)
|
||||
(SDLK_h, NKCODE_H)
|
||||
(SDLK_g, NKCODE_G)
|
||||
(SDLK_f, NKCODE_F)
|
||||
(SDLK_d, NKCODE_D)
|
||||
(SDLK_s, NKCODE_S)
|
||||
(SDLK_a, NKCODE_A)
|
||||
(SDLK_m, NKCODE_M)
|
||||
(SDLK_n, NKCODE_N)
|
||||
(SDLK_b, NKCODE_B)
|
||||
(SDLK_v, NKCODE_V)
|
||||
(SDLK_c, NKCODE_C)
|
||||
(SDLK_x, NKCODE_X)
|
||||
(SDLK_z, NKCODE_Z)
|
||||
(SDLK_COMMA, NKCODE_COMMA)
|
||||
(SDLK_PERIOD, NKCODE_PERIOD)
|
||||
(SDLK_LALT, NKCODE_ALT_LEFT)
|
||||
(SDLK_RALT, NKCODE_ALT_RIGHT)
|
||||
(SDLK_LSHIFT, NKCODE_SHIFT_LEFT)
|
||||
(SDLK_RSHIFT, NKCODE_SHIFT_RIGHT)
|
||||
(SDLK_TAB, NKCODE_TAB)
|
||||
(SDLK_SPACE, NKCODE_SPACE)
|
||||
(SDLK_RETURN, NKCODE_ENTER)
|
||||
(SDLK_MINUS, NKCODE_MINUS)
|
||||
(SDLK_EQUALS, NKCODE_EQUALS)
|
||||
(SDLK_LEFTBRACKET, NKCODE_LEFT_BRACKET)
|
||||
(SDLK_RIGHTBRACKET, NKCODE_RIGHT_BRACKET)
|
||||
(SDLK_BACKSLASH, NKCODE_BACKSLASH)
|
||||
(SDLK_SEMICOLON, NKCODE_SEMICOLON)
|
||||
// (SDLK_, NKCODE_APOSTROPHE) // I cannot find the SDL equiv
|
||||
(SDLK_SLASH, NKCODE_SLASH)
|
||||
(SDLK_AT, NKCODE_AT)
|
||||
(SDLK_PLUS, NKCODE_PLUS)
|
||||
(SDLK_PAGEUP, NKCODE_PAGE_UP)
|
||||
(SDLK_PAGEDOWN, NKCODE_PAGE_DOWN)
|
||||
#ifdef MAEMO
|
||||
(SDLK_BACKSPACE, NKCODE_ESCAPE)
|
||||
#else
|
||||
(SDLK_ESCAPE, NKCODE_ESCAPE)
|
||||
(SDLK_BACKSPACE, NKCODE_DEL)
|
||||
#endif
|
||||
(SDLK_DELETE, NKCODE_FORWARD_DEL)
|
||||
(SDLK_LCTRL, NKCODE_CTRL_LEFT)
|
||||
(SDLK_RCTRL, NKCODE_CTRL_RIGHT)
|
||||
(SDLK_CAPSLOCK, NKCODE_CAPS_LOCK)
|
||||
(SDLK_HOME, NKCODE_MOVE_HOME)
|
||||
(SDLK_END, NKCODE_MOVE_END)
|
||||
(SDLK_INSERT, NKCODE_INSERT)
|
||||
(SDLK_KP_0, NKCODE_NUMPAD_0)
|
||||
(SDLK_KP_1, NKCODE_NUMPAD_1)
|
||||
(SDLK_KP_2, NKCODE_NUMPAD_2)
|
||||
(SDLK_KP_3, NKCODE_NUMPAD_3)
|
||||
(SDLK_KP_4, NKCODE_NUMPAD_4)
|
||||
(SDLK_KP_5, NKCODE_NUMPAD_5)
|
||||
(SDLK_KP_6, NKCODE_NUMPAD_6)
|
||||
(SDLK_KP_7, NKCODE_NUMPAD_7)
|
||||
(SDLK_KP_8, NKCODE_NUMPAD_8)
|
||||
(SDLK_KP_9, NKCODE_NUMPAD_9)
|
||||
(SDLK_KP_DIVIDE, NKCODE_NUMPAD_DIVIDE)
|
||||
(SDLK_KP_MULTIPLY, NKCODE_NUMPAD_MULTIPLY)
|
||||
(SDLK_KP_MINUS, NKCODE_NUMPAD_SUBTRACT)
|
||||
(SDLK_KP_PLUS, NKCODE_NUMPAD_ADD)
|
||||
(SDLK_KP_PERIOD, NKCODE_NUMPAD_DOT)
|
||||
(SDLK_KP_ENTER, NKCODE_NUMPAD_ENTER)
|
||||
(SDLK_KP_EQUALS, NKCODE_NUMPAD_EQUALS)
|
||||
(SDLK_1, NKCODE_1)
|
||||
(SDLK_2, NKCODE_2)
|
||||
(SDLK_3, NKCODE_3)
|
||||
(SDLK_4, NKCODE_4)
|
||||
(SDLK_5, NKCODE_5)
|
||||
(SDLK_6, NKCODE_6)
|
||||
(SDLK_7, NKCODE_7)
|
||||
(SDLK_8, NKCODE_8)
|
||||
(SDLK_9, NKCODE_9)
|
||||
(SDLK_0, NKCODE_0)
|
||||
(SDLK_F1, NKCODE_F1)
|
||||
(SDLK_F2, NKCODE_F2)
|
||||
(SDLK_F3, NKCODE_F3)
|
||||
(SDLK_F4, NKCODE_F4)
|
||||
(SDLK_F5, NKCODE_F5)
|
||||
(SDLK_F6, NKCODE_F6)
|
||||
(SDLK_F7, NKCODE_F7)
|
||||
(SDLK_F8, NKCODE_F8)
|
||||
(SDLK_F9, NKCODE_F9)
|
||||
(SDLK_F10, NKCODE_F10)
|
||||
(SDLK_F11, NKCODE_F11)
|
||||
(SDLK_F12, NKCODE_F12)
|
||||
(SDLK_LEFT, NKCODE_DPAD_LEFT)
|
||||
(SDLK_UP, NKCODE_DPAD_UP)
|
||||
(SDLK_RIGHT, NKCODE_DPAD_RIGHT)
|
||||
(SDLK_DOWN, NKCODE_DPAD_DOWN);
|
||||
|
155
ext/native/base/NativeApp.h
Normal file
155
ext/native/base/NativeApp.h
Normal file
@ -0,0 +1,155 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
// The Native App API.
|
||||
//
|
||||
// Implement these functions and you've got a native app. These are called
|
||||
// from the framework, which exposes the native JNI api which is a bit
|
||||
// more complicated.
|
||||
|
||||
// This is defined in input/input_state.h.
|
||||
struct InputState;
|
||||
struct TouchInput;
|
||||
struct KeyInput;
|
||||
struct AxisInput;
|
||||
|
||||
// The first function to get called, just write strings to the two pointers.
|
||||
// This might get called multiple times in some implementations, you must be able to handle that.
|
||||
void NativeGetAppInfo(std::string *app_dir_name, std::string *app_nice_name, bool *landscape, std::string *version);
|
||||
|
||||
// Generic host->C++ messaging, used for functionality like system-native popup input boxes.
|
||||
void NativeMessageReceived(const char *message, const char *value);
|
||||
|
||||
// Easy way for the Java side to ask the C++ side for configuration options, such as
|
||||
// the rotation lock which must be controlled from Java on Android.
|
||||
// It is currently not called on non-Android platforms.
|
||||
std::string NativeQueryConfig(std::string query);
|
||||
|
||||
// For the back button to work right, this should return true on your main or title screen.
|
||||
// Otherwise, just return false.
|
||||
bool NativeIsAtTopLevel();
|
||||
|
||||
// The very first function to be called after NativeGetAppInfo. Even NativeMix is not called
|
||||
// before this, although it may be called at any point in time afterwards (on any thread!)
|
||||
// This functions must NOT call OpenGL. Main thread.
|
||||
void NativeInit(int argc, const char *argv[], const char *savegame_directory, const char *external_directory, const char *installID, bool fs=false);
|
||||
|
||||
// Runs after NativeInit() at some point. May (and probably should) call OpenGL.
|
||||
// Should not initialize anything screen-size-dependent - do that in NativeResized.
|
||||
void NativeInitGraphics();
|
||||
|
||||
// Signals that you need to destroy and recreate all buffered OpenGL resources,
|
||||
// like textures, vbo etc.
|
||||
void NativeDeviceLost();
|
||||
|
||||
// If you want to change DPI stuff (such as modifying dp_xres and dp_yres), this is the
|
||||
// place to do it. You should only read g_dpi_scale and pixel_xres and pixel_yres in this,
|
||||
// and only write dp_xres and dp_yres.
|
||||
void NativeResized();
|
||||
|
||||
// Called ~sixty times a second, delivers the current input state.
|
||||
// Main thread.
|
||||
void NativeUpdate(InputState &input);
|
||||
|
||||
// Delivers touch events "instantly", without waiting for the next frame so that NativeUpdate can deliver.
|
||||
// Useful for triggering audio events, saving a few ms.
|
||||
// If you don't care about touch latency, just do a no-op implementation of this.
|
||||
// time is not yet implemented. finger can be from 0 to 7, inclusive.
|
||||
bool NativeTouch(const TouchInput &touch);
|
||||
bool NativeKey(const KeyInput &key);
|
||||
bool NativeAxis(const AxisInput &axis);
|
||||
|
||||
// Called when it's time to render. If the device can keep up, this
|
||||
// will also be called sixty times per second. Main thread.
|
||||
void NativeRender();
|
||||
|
||||
// This should render num_samples 44khz stereo samples.
|
||||
// Try not to make too many assumptions on the granularity
|
||||
// of num_samples.
|
||||
// This function may be called from a totally separate thread from
|
||||
// the rest of the game, so be careful with synchronization.
|
||||
// Returns the number of samples actually output. The app should do everything it can
|
||||
// to fill the buffer completely.
|
||||
int NativeMix(short *audio, int num_samples);
|
||||
void NativeSetMixer(void* mixer);
|
||||
|
||||
// Called when it's time to shutdown. After this has been called,
|
||||
// no more calls to any other function will be made from the framework
|
||||
// before process exit.
|
||||
// The graphics context should still be active when calling this, as freeing
|
||||
// of graphics resources happens here.
|
||||
// Main thread.
|
||||
void NativeShutdownGraphics();
|
||||
void NativeShutdown();
|
||||
|
||||
// Called on app.onCreate and app.onDestroy (?). Tells the app to save/restore
|
||||
// light state. If app was fully rebooted between these calls, it's okay if some minor
|
||||
// state is lost (position in level) but the level currently playihg, or the song
|
||||
// currently being edited, or whatever, should be restored properly. In this case,
|
||||
// firstTime will be set so that appropriate action can be taken (or not taken when
|
||||
// it's not set).
|
||||
//
|
||||
// Note that NativeRestore is always called on bootup.
|
||||
void NativeRestoreState(bool firstTime); // onCreate
|
||||
void NativeSaveState(); // onDestroy
|
||||
|
||||
// Calls back into Java / SDL
|
||||
// These APIs must be implemented by every port (for example app-android.cpp, PCMain.cpp).
|
||||
// You are free to call these.
|
||||
void SystemToast(const char *text);
|
||||
void ShowKeyboard();
|
||||
void ShowAd(int x, int y, bool center_x);
|
||||
|
||||
// Vibrate either takes a number of milliseconds to vibrate unconditionally,
|
||||
// or you can specify these constants for "standard" feedback. On Android,
|
||||
// these will only be performed if haptic feedback is enabled globally.
|
||||
// Also, on Android, these will work even if you don't have the VIBRATE permission,
|
||||
// while generic vibration will not if you don't have it.
|
||||
enum {
|
||||
HAPTIC_SOFT_KEYBOARD = -1,
|
||||
HAPTIC_VIRTUAL_KEY = -2,
|
||||
HAPTIC_LONG_PRESS_ACTIVATED = -3,
|
||||
};
|
||||
void Vibrate(int length_ms);
|
||||
void LaunchBrowser(const char *url);
|
||||
void LaunchMarket(const char *url);
|
||||
void LaunchEmail(const char *email_address);
|
||||
bool System_InputBoxGetString(const char *title, const char *defaultValue, char *outValue, size_t outlength);
|
||||
bool System_InputBoxGetWString(const wchar_t *title, const std::wstring &defaultValue, std::wstring &outValue);
|
||||
void System_SendMessage(const char *command, const char *parameter);
|
||||
|
||||
// This will get muddy with multi-screen support :/ But this will always be the type of the main device.
|
||||
enum SystemDeviceType {
|
||||
DEVICE_TYPE_MOBILE = 0, // phones and pads
|
||||
DEVICE_TYPE_TV = 1, // Android TV and similar
|
||||
DEVICE_TYPE_DESKTOP = 2, // Desktop computer
|
||||
};
|
||||
|
||||
enum SystemProperty {
|
||||
SYSPROP_NAME,
|
||||
SYSPROP_LANGREGION,
|
||||
SYSPROP_CPUINFO,
|
||||
SYSPROP_CLIPBOARD_TEXT,
|
||||
SYSPROP_GPUDRIVER_VERSION,
|
||||
|
||||
// Available as Int:
|
||||
SYSPROP_SYSTEMVERSION,
|
||||
SYSPROP_DISPLAY_XRES,
|
||||
SYSPROP_DISPLAY_YRES,
|
||||
SYSPROP_DISPLAY_REFRESH_RATE, // returns 1000*the refresh rate in Hz as it can be non-integer
|
||||
SYSPROP_MOGA_VERSION,
|
||||
|
||||
SYSPROP_DEVICE_TYPE,
|
||||
|
||||
// Exposed on Android. Choosing the optimal sample rate for audio
|
||||
// will result in lower latencies. Buffer size is automatically matched
|
||||
// by the OpenSL audio backend, only exposed here for debugging/info.
|
||||
SYSPROP_AUDIO_SAMPLE_RATE,
|
||||
SYSPROP_AUDIO_FRAMES_PER_BUFFER,
|
||||
SYSPROP_AUDIO_OPTIMAL_SAMPLE_RATE,
|
||||
SYSPROP_AUDIO_OPTIMAL_FRAMES_PER_BUFFER,
|
||||
};
|
||||
|
||||
std::string System_GetProperty(SystemProperty prop);
|
||||
int System_GetPropertyInt(SystemProperty prop);
|
898
ext/native/base/PCMain.cpp
Normal file
898
ext/native/base/PCMain.cpp
Normal file
@ -0,0 +1,898 @@
|
||||
// SDL/EGL implementation of the framework.
|
||||
// This is quite messy due to platform-specific implementations and #ifdef's.
|
||||
// Note: SDL1.2 implementation is deprecated and will soon be replaced by SDL2.0.
|
||||
// If your platform is not supported, it is suggested to use Qt instead.
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
#include <shlobj.h>
|
||||
#include <shlwapi.h>
|
||||
#include <ShellAPI.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
|
||||
#include "SDL.h"
|
||||
#ifndef _WIN32
|
||||
#include "SDL/SDLJoystick.h"
|
||||
SDLJoystick *joystick = NULL;
|
||||
#endif
|
||||
|
||||
#ifdef RPI
|
||||
#include <bcm_host.h>
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "base/display.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/timeutil.h"
|
||||
#include "gfx/gl_common.h"
|
||||
#include "gfx_es2/gpu_features.h"
|
||||
#include "input/input_state.h"
|
||||
#include "input/keycodes.h"
|
||||
#include "net/resolve.h"
|
||||
#include "base/NKCodeFromSDL.h"
|
||||
#include "util/const_map.h"
|
||||
#include "util/text/utf8.h"
|
||||
#include "math/math_util.h"
|
||||
|
||||
#ifdef PPSSPP
|
||||
// Bad: PPSSPP includes from native
|
||||
#include "Core/System.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/Config.h"
|
||||
|
||||
GlobalUIState lastUIState = UISTATE_MENU;
|
||||
GlobalUIState GetUIState();
|
||||
#endif
|
||||
|
||||
static SDL_Window* g_Screen = NULL;
|
||||
static bool g_ToggleFullScreenNextFrame = false;
|
||||
static int g_QuitRequested = 0;
|
||||
|
||||
static int g_DesktopWidth = 0;
|
||||
static int g_DesktopHeight = 0;
|
||||
|
||||
#if defined(USING_EGL)
|
||||
#include "EGL/egl.h"
|
||||
|
||||
#if !defined(USING_FBDEV)
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#endif
|
||||
|
||||
#include "SDL_syswm.h"
|
||||
#include "math.h"
|
||||
|
||||
static EGLDisplay g_eglDisplay = NULL;
|
||||
static EGLContext g_eglContext = NULL;
|
||||
static EGLSurface g_eglSurface = NULL;
|
||||
#ifdef USING_FBDEV
|
||||
static EGLNativeDisplayType g_Display = NULL;
|
||||
#else
|
||||
static Display* g_Display = NULL;
|
||||
#endif
|
||||
static NativeWindowType g_Window = (NativeWindowType)NULL;
|
||||
|
||||
int8_t CheckEGLErrors(const std::string& file, uint16_t line) {
|
||||
EGLenum error;
|
||||
std::string errortext;
|
||||
|
||||
error = eglGetError();
|
||||
switch (error)
|
||||
{
|
||||
case EGL_SUCCESS: case 0: return 0;
|
||||
case EGL_NOT_INITIALIZED: errortext = "EGL_NOT_INITIALIZED"; break;
|
||||
case EGL_BAD_ACCESS: errortext = "EGL_BAD_ACCESS"; break;
|
||||
case EGL_BAD_ALLOC: errortext = "EGL_BAD_ALLOC"; break;
|
||||
case EGL_BAD_ATTRIBUTE: errortext = "EGL_BAD_ATTRIBUTE"; break;
|
||||
case EGL_BAD_CONTEXT: errortext = "EGL_BAD_CONTEXT"; break;
|
||||
case EGL_BAD_CONFIG: errortext = "EGL_BAD_CONFIG"; break;
|
||||
case EGL_BAD_CURRENT_SURFACE: errortext = "EGL_BAD_CURRENT_SURFACE"; break;
|
||||
case EGL_BAD_DISPLAY: errortext = "EGL_BAD_DISPLAY"; break;
|
||||
case EGL_BAD_SURFACE: errortext = "EGL_BAD_SURFACE"; break;
|
||||
case EGL_BAD_MATCH: errortext = "EGL_BAD_MATCH"; break;
|
||||
case EGL_BAD_PARAMETER: errortext = "EGL_BAD_PARAMETER"; break;
|
||||
case EGL_BAD_NATIVE_PIXMAP: errortext = "EGL_BAD_NATIVE_PIXMAP"; break;
|
||||
case EGL_BAD_NATIVE_WINDOW: errortext = "EGL_BAD_NATIVE_WINDOW"; break;
|
||||
default: errortext = "unknown"; break;
|
||||
}
|
||||
printf( "ERROR: EGL Error detected in file %s at line %d: %s (0x%X)\n", file.c_str(), line, errortext.c_str(), error );
|
||||
return 1;
|
||||
}
|
||||
#define EGL_ERROR(str, check) { \
|
||||
if (check) CheckEGLErrors( __FILE__, __LINE__ ); \
|
||||
printf("EGL ERROR: " str "\n"); \
|
||||
return 1; \
|
||||
}
|
||||
|
||||
int8_t EGL_Open() {
|
||||
#ifdef USING_FBDEV
|
||||
g_Display = ((EGLNativeDisplayType)0);
|
||||
#else
|
||||
if ((g_Display = XOpenDisplay(NULL)) == NULL)
|
||||
EGL_ERROR("Unable to get display!", false);
|
||||
#endif
|
||||
if ((g_eglDisplay = eglGetDisplay((NativeDisplayType)g_Display)) == EGL_NO_DISPLAY)
|
||||
EGL_ERROR("Unable to create EGL display.", true);
|
||||
if (eglInitialize(g_eglDisplay, NULL, NULL) != EGL_TRUE)
|
||||
EGL_ERROR("Unable to initialize EGL display.", true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t EGL_Init() {
|
||||
EGLConfig g_eglConfig;
|
||||
EGLint g_numConfigs = 0;
|
||||
EGLint attrib_list[]= {
|
||||
// TODO: Should cycle through fallbacks, like on Android
|
||||
#ifdef USING_FBDEV
|
||||
EGL_RED_SIZE, 5,
|
||||
EGL_GREEN_SIZE, 6,
|
||||
EGL_BLUE_SIZE, 5,
|
||||
#endif
|
||||
EGL_DEPTH_SIZE, 16,
|
||||
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||
#ifdef USING_GLES2
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
||||
#else
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
|
||||
#endif
|
||||
EGL_SAMPLE_BUFFERS, 0,
|
||||
EGL_SAMPLES, 0,
|
||||
#ifdef MAEMO
|
||||
EGL_BUFFER_SIZE, 16,
|
||||
#endif
|
||||
EGL_NONE};
|
||||
|
||||
const EGLint attributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
|
||||
|
||||
EGLBoolean result = eglChooseConfig(g_eglDisplay, attrib_list, &g_eglConfig, 1, &g_numConfigs);
|
||||
if (result != EGL_TRUE || g_numConfigs == 0) EGL_ERROR("Unable to query for available configs.", true);
|
||||
|
||||
g_eglContext = eglCreateContext(g_eglDisplay, g_eglConfig, NULL, attributes );
|
||||
if (g_eglContext == EGL_NO_CONTEXT) EGL_ERROR("Unable to create GLES context!", true);
|
||||
|
||||
#if !defined(USING_FBDEV)
|
||||
//Get the SDL window handle
|
||||
SDL_SysWMinfo sysInfo; //Will hold our Window information
|
||||
SDL_VERSION(&sysInfo.version); //Set SDL version
|
||||
#endif
|
||||
|
||||
#ifdef USING_FBDEV
|
||||
g_Window = (NativeWindowType)NULL;
|
||||
#else
|
||||
g_Window = (NativeWindowType)sysInfo.info.x11.window;
|
||||
#endif
|
||||
g_eglSurface = eglCreateWindowSurface(g_eglDisplay, g_eglConfig, g_Window, 0);
|
||||
if (g_eglSurface == EGL_NO_SURFACE)
|
||||
EGL_ERROR("Unable to create EGL surface!", true);
|
||||
|
||||
if (eglMakeCurrent(g_eglDisplay, g_eglSurface, g_eglSurface, g_eglContext) != EGL_TRUE)
|
||||
EGL_ERROR("Unable to make GLES context current.", true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void EGL_Close() {
|
||||
if (g_eglDisplay != NULL) {
|
||||
eglMakeCurrent(g_eglDisplay, NULL, NULL, EGL_NO_CONTEXT);
|
||||
if (g_eglContext != NULL) {
|
||||
eglDestroyContext(g_eglDisplay, g_eglContext);
|
||||
}
|
||||
if (g_eglSurface != NULL) {
|
||||
eglDestroySurface(g_eglDisplay, g_eglSurface);
|
||||
}
|
||||
eglTerminate(g_eglDisplay);
|
||||
g_eglDisplay = NULL;
|
||||
}
|
||||
if (g_Display != NULL) {
|
||||
#if !defined(USING_FBDEV)
|
||||
XCloseDisplay(g_Display);
|
||||
#endif
|
||||
g_Display = NULL;
|
||||
}
|
||||
g_eglSurface = NULL;
|
||||
g_eglContext = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
int getDisplayNumber(void)
|
||||
{
|
||||
int displayNumber = 0;
|
||||
char * displayNumberStr;
|
||||
|
||||
//get environment
|
||||
displayNumberStr=getenv("SDL_VIDEO_FULLSCREEN_HEAD");
|
||||
|
||||
if (displayNumberStr)
|
||||
{
|
||||
displayNumber = atoi(displayNumberStr);
|
||||
}
|
||||
|
||||
return displayNumber;
|
||||
}
|
||||
|
||||
// Simple implementations of System functions
|
||||
|
||||
|
||||
void SystemToast(const char *text) {
|
||||
#ifdef _WIN32
|
||||
MessageBox(0, text, "Toast!", MB_ICONINFORMATION);
|
||||
#else
|
||||
puts(text);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ShowKeyboard() {
|
||||
// Irrelevant on PC
|
||||
}
|
||||
|
||||
void Vibrate(int length_ms) {
|
||||
// Ignore on PC
|
||||
}
|
||||
|
||||
void System_SendMessage(const char *command, const char *parameter) {
|
||||
if (!strcmp(command, "toggle_fullscreen")) {
|
||||
g_ToggleFullScreenNextFrame = true;
|
||||
} else if (!strcmp(command, "finish")) {
|
||||
// Do a clean exit
|
||||
g_QuitRequested = true;
|
||||
}
|
||||
}
|
||||
|
||||
void LaunchBrowser(const char *url) {
|
||||
#if defined(MOBILE_DEVICE)
|
||||
ILOG("Would have gone to %s but LaunchBrowser is not implemented on this platform", url);
|
||||
#elif defined(_WIN32)
|
||||
ShellExecute(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL);
|
||||
#elif defined(__APPLE__)
|
||||
std::string command = std::string("open ") + url;
|
||||
system(command.c_str());
|
||||
#else
|
||||
std::string command = std::string("xdg-open ") + url;
|
||||
int err = system(command.c_str());
|
||||
if (err) {
|
||||
ILOG("Would have gone to %s but xdg-utils seems not to be installed", url)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void LaunchMarket(const char *url) {
|
||||
#if defined(MOBILE_DEVICE)
|
||||
ILOG("Would have gone to %s but LaunchMarket is not implemented on this platform", url);
|
||||
#elif defined(_WIN32)
|
||||
ShellExecute(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL);
|
||||
#elif defined(__APPLE__)
|
||||
std::string command = std::string("open ") + url;
|
||||
system(command.c_str());
|
||||
#else
|
||||
std::string command = std::string("xdg-open ") + url;
|
||||
int err = system(command.c_str());
|
||||
if (err) {
|
||||
ILOG("Would have gone to %s but xdg-utils seems not to be installed", url)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void LaunchEmail(const char *email_address) {
|
||||
#if defined(MOBILE_DEVICE)
|
||||
ILOG("Would have opened your email client for %s but LaunchEmail is not implemented on this platform", email_address);
|
||||
#elif defined(_WIN32)
|
||||
ShellExecute(NULL, "open", (std::string("mailto:") + email_address).c_str(), NULL, NULL, SW_SHOWNORMAL);
|
||||
#elif defined(__APPLE__)
|
||||
std::string command = std::string("open mailto:") + email_address;
|
||||
system(command.c_str());
|
||||
#else
|
||||
std::string command = std::string("xdg-email ") + email_address;
|
||||
int err = system(command.c_str());
|
||||
if (err) {
|
||||
ILOG("Would have gone to %s but xdg-utils seems not to be installed", email_address)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string System_GetProperty(SystemProperty prop) {
|
||||
switch (prop) {
|
||||
case SYSPROP_NAME:
|
||||
#ifdef _WIN32
|
||||
return "SDL:Windows";
|
||||
#elif __linux__
|
||||
return "SDL:Linux";
|
||||
#elif __APPLE__
|
||||
return "SDL:OSX";
|
||||
#else
|
||||
return "SDL:";
|
||||
#endif
|
||||
case SYSPROP_LANGREGION:
|
||||
return "en_US";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
int System_GetPropertyInt(SystemProperty prop) {
|
||||
switch (prop) {
|
||||
case SYSPROP_AUDIO_SAMPLE_RATE:
|
||||
return 44100;
|
||||
case SYSPROP_DISPLAY_REFRESH_RATE:
|
||||
return 60000;
|
||||
case SYSPROP_DEVICE_TYPE:
|
||||
#if defined(MOBILE_DEVICE)
|
||||
return DEVICE_TYPE_MOBILE;
|
||||
#else
|
||||
return DEVICE_TYPE_DESKTOP;
|
||||
#endif
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
InputState input_state;
|
||||
|
||||
static const int legacyKeyMap[] {
|
||||
NKCODE_X, //A
|
||||
NKCODE_S, //B
|
||||
NKCODE_Z, //X
|
||||
NKCODE_A, //Y
|
||||
NKCODE_W, //LBUMPER
|
||||
NKCODE_Q, //RBUMPER
|
||||
NKCODE_1, //START
|
||||
NKCODE_2, //SELECT
|
||||
NKCODE_DPAD_UP, //UP
|
||||
NKCODE_DPAD_DOWN, //DOWN
|
||||
NKCODE_DPAD_LEFT, //LEFT
|
||||
NKCODE_DPAD_RIGHT, //RIGHT
|
||||
0, //MENU (SwipeDown)
|
||||
NKCODE_ESCAPE, //BACK
|
||||
NKCODE_I, //JOY UP
|
||||
NKCODE_K, //JOY DOWN
|
||||
NKCODE_J, //JOY LEFT
|
||||
NKCODE_L, //JOY RIGHT
|
||||
};
|
||||
|
||||
void SimulateGamepad(const uint8_t *keys, InputState *input) {
|
||||
// Legacy key mapping.
|
||||
input->pad_buttons = 0;
|
||||
input->pad_lstick_x = 0;
|
||||
input->pad_lstick_y = 0;
|
||||
input->pad_rstick_x = 0;
|
||||
input->pad_rstick_y = 0;
|
||||
}
|
||||
|
||||
extern void mixaudio(void *userdata, Uint8 *stream, int len) {
|
||||
NativeMix((short *)stream, len / 4);
|
||||
}
|
||||
|
||||
// returns -1 on failure
|
||||
static int parseInt(const char *str) {
|
||||
int val;
|
||||
int retval = sscanf(str, "%d", &val);
|
||||
printf("%i = scanf %s\n", retval, str);
|
||||
if (retval != 1) {
|
||||
return -1;
|
||||
} else {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
static float parseFloat(const char *str) {
|
||||
float val;
|
||||
int retval = sscanf(str, "%f", &val);
|
||||
printf("%i = sscanf %s\n", retval, str);
|
||||
if (retval != 1) {
|
||||
return -1.0f;
|
||||
} else {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
void ToggleFullScreenIfFlagSet() {
|
||||
if (g_ToggleFullScreenNextFrame) {
|
||||
g_ToggleFullScreenNextFrame = false;
|
||||
|
||||
Uint32 window_flags = SDL_GetWindowFlags(g_Screen);
|
||||
SDL_SetWindowFullscreen(g_Screen, window_flags ^ SDL_WINDOW_FULLSCREEN_DESKTOP);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#undef main
|
||||
#endif
|
||||
int main(int argc, char *argv[]) {
|
||||
#ifdef RPI
|
||||
bcm_host_init();
|
||||
#endif
|
||||
putenv((char*)"SDL_VIDEO_CENTERED=1");
|
||||
|
||||
std::string app_name;
|
||||
std::string app_name_nice;
|
||||
std::string version;
|
||||
bool landscape;
|
||||
NativeGetAppInfo(&app_name, &app_name_nice, &landscape, &version);
|
||||
|
||||
net::Init();
|
||||
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO) < 0) {
|
||||
fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
// Make sure to request a somewhat modern GL context at least - the
|
||||
// latest supported by MacOSX (really, really sad...)
|
||||
// Requires SDL 2.0
|
||||
// We really should upgrade to SDL 2.0 soon.
|
||||
//SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
//SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||
//SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
|
||||
#endif
|
||||
|
||||
#ifdef USING_EGL
|
||||
if (EGL_Open())
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
// Get the video info before doing anything else, so we don't get skewed resolution results.
|
||||
// TODO: support multiple displays correctly
|
||||
SDL_DisplayMode displayMode;
|
||||
int should_be_zero = SDL_GetCurrentDisplayMode(0, &displayMode);
|
||||
if (should_be_zero != 0) {
|
||||
fprintf(stderr, "Could not get display mode: %s\n", SDL_GetError());
|
||||
return 1;
|
||||
}
|
||||
g_DesktopWidth = displayMode.w;
|
||||
g_DesktopHeight = displayMode.h;
|
||||
|
||||
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
||||
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||
SDL_GL_SetSwapInterval(1);
|
||||
|
||||
Uint32 mode;
|
||||
#ifdef USING_GLES2
|
||||
mode = SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN;
|
||||
#else
|
||||
mode = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE;
|
||||
#endif
|
||||
int set_xres = -1;
|
||||
int set_yres = -1;
|
||||
bool portrait = false;
|
||||
bool set_ipad = false;
|
||||
float set_dpi = 1.0f;
|
||||
float set_scale = 1.0f;
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (!strcmp(argv[i],"--fullscreen"))
|
||||
mode |= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
if (set_xres == -2) {
|
||||
set_xres = parseInt(argv[i]);
|
||||
} else if (set_yres == -2) {
|
||||
set_yres = parseInt(argv[i]);
|
||||
}
|
||||
if (set_dpi == -2)
|
||||
set_dpi = parseFloat(argv[i]);
|
||||
if (set_scale == -2)
|
||||
set_scale = parseFloat(argv[i]);
|
||||
|
||||
if (!strcmp(argv[i],"--xres"))
|
||||
set_xres = -2;
|
||||
if (!strcmp(argv[i],"--yres"))
|
||||
set_yres = -2;
|
||||
if (!strcmp(argv[i],"--dpi"))
|
||||
set_dpi = -2;
|
||||
if (!strcmp(argv[i],"--scale"))
|
||||
set_scale = -2;
|
||||
|
||||
if (!strcmp(argv[i],"--ipad"))
|
||||
set_ipad = true;
|
||||
if (!strcmp(argv[i],"--portrait"))
|
||||
portrait = true;
|
||||
}
|
||||
|
||||
// Is resolution is too low to run windowed
|
||||
if (g_DesktopWidth < 480 * 2 && g_DesktopHeight < 272 * 2) {
|
||||
mode |= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
}
|
||||
|
||||
if (mode & SDL_WINDOW_FULLSCREEN_DESKTOP) {
|
||||
pixel_xres = g_DesktopWidth;
|
||||
pixel_yres = g_DesktopHeight;
|
||||
#ifdef PPSSPP
|
||||
g_Config.bFullScreen = true;
|
||||
#endif
|
||||
} else {
|
||||
// set a sensible default resolution (2x)
|
||||
pixel_xres = 480 * 2 * set_scale;
|
||||
pixel_yres = 272 * 2 * set_scale;
|
||||
if (portrait) {
|
||||
std::swap(pixel_xres, pixel_yres);
|
||||
}
|
||||
#ifdef PPSSPP
|
||||
g_Config.bFullScreen = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
set_dpi = 1.0f / set_dpi;
|
||||
|
||||
if (set_ipad) {
|
||||
pixel_xres = 1024;
|
||||
pixel_yres = 768;
|
||||
}
|
||||
if (!landscape) {
|
||||
std::swap(pixel_xres, pixel_yres);
|
||||
}
|
||||
|
||||
if (set_xres > 0) {
|
||||
pixel_xres = set_xres;
|
||||
}
|
||||
if (set_yres > 0) {
|
||||
pixel_yres = set_yres;
|
||||
}
|
||||
float dpi_scale = 1.0f;
|
||||
if (set_dpi > 0) {
|
||||
dpi_scale = set_dpi;
|
||||
}
|
||||
|
||||
dp_xres = (float)pixel_xres * dpi_scale;
|
||||
dp_yres = (float)pixel_yres * dpi_scale;
|
||||
|
||||
g_Screen = SDL_CreateWindow(app_name_nice.c_str(), SDL_WINDOWPOS_UNDEFINED_DISPLAY(getDisplayNumber()),\
|
||||
SDL_WINDOWPOS_UNDEFINED, pixel_xres, pixel_yres, mode);
|
||||
|
||||
if (g_Screen == NULL) {
|
||||
fprintf(stderr, "SDL_CreateWindow failed: %s\n", SDL_GetError());
|
||||
SDL_Quit();
|
||||
return 2;
|
||||
}
|
||||
|
||||
SDL_GLContext glContext = SDL_GL_CreateContext(g_Screen);
|
||||
if (glContext == NULL) {
|
||||
fprintf(stderr, "SDL_GL_CreateContext failed: %s\n", SDL_GetError());
|
||||
SDL_Quit();
|
||||
return 2;
|
||||
}
|
||||
|
||||
#ifdef USING_EGL
|
||||
EGL_Init();
|
||||
#endif
|
||||
|
||||
#ifdef PPSSPP
|
||||
SDL_SetWindowTitle(g_Screen, (app_name_nice + " " + PPSSPP_GIT_VERSION).c_str());
|
||||
#endif
|
||||
|
||||
#ifdef MOBILE_DEVICE
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef USING_GLES2
|
||||
if (GLEW_OK != glewInit()) {
|
||||
printf("Failed to initialize glew!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (GLEW_VERSION_2_0) {
|
||||
printf("OpenGL 2.0 or higher.\n");
|
||||
} else {
|
||||
printf("Sorry, this program requires OpenGL 2.0.\n");
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// VFSRegister("temp/", new DirectoryAssetReader("E:\\Temp\\"));
|
||||
TCHAR path[MAX_PATH];
|
||||
SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, path);
|
||||
PathAppend(path, (app_name + "\\").c_str());
|
||||
#else
|
||||
// Mac / Linux
|
||||
char path[2048];
|
||||
const char *the_path = getenv("HOME");
|
||||
if (!the_path) {
|
||||
struct passwd* pwd = getpwuid(getuid());
|
||||
if (pwd)
|
||||
the_path = pwd->pw_dir;
|
||||
}
|
||||
strcpy(path, the_path);
|
||||
if (path[strlen(path)-1] != '/')
|
||||
strcat(path, "/");
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
NativeInit(argc, (const char **)argv, path, "D:\\", "BADCOFFEE");
|
||||
#else
|
||||
NativeInit(argc, (const char **)argv, path, "/tmp", "BADCOFFEE");
|
||||
#endif
|
||||
|
||||
pixel_in_dps = (float)pixel_xres / dp_xres;
|
||||
g_dpi_scale = dp_xres / (float)pixel_xres;
|
||||
|
||||
printf("Pixels: %i x %i\n", pixel_xres, pixel_yres);
|
||||
printf("Virtual pixels: %i x %i\n", dp_xres, dp_yres);
|
||||
|
||||
NativeInitGraphics();
|
||||
NativeResized();
|
||||
|
||||
SDL_AudioSpec fmt, ret_fmt;
|
||||
memset(&fmt, 0, sizeof(fmt));
|
||||
fmt.freq = 44100;
|
||||
fmt.format = AUDIO_S16;
|
||||
fmt.channels = 2;
|
||||
fmt.samples = 2048;
|
||||
fmt.callback = &mixaudio;
|
||||
fmt.userdata = (void *)0;
|
||||
|
||||
if (SDL_OpenAudio(&fmt, &ret_fmt) < 0) {
|
||||
ELOG("Failed to open audio: %s", SDL_GetError());
|
||||
} else {
|
||||
if (ret_fmt.samples != fmt.samples) // Notify, but still use it
|
||||
ELOG("Output audio samples: %d (requested: %d)", ret_fmt.samples, fmt.samples);
|
||||
if (ret_fmt.freq != fmt.freq || ret_fmt.format != fmt.format || ret_fmt.channels != fmt.channels) {
|
||||
ELOG("Sound buffer format does not match requested format.");
|
||||
ELOG("Output audio freq: %d (requested: %d)", ret_fmt.freq, fmt.freq);
|
||||
ELOG("Output audio format: %d (requested: %d)", ret_fmt.format, fmt.format);
|
||||
ELOG("Output audio channels: %d (requested: %d)", ret_fmt.channels, fmt.channels);
|
||||
ELOG("Provided output format does not match requirement, turning audio off");
|
||||
SDL_CloseAudio();
|
||||
}
|
||||
}
|
||||
|
||||
// Audio must be unpaused _after_ NativeInit()
|
||||
SDL_PauseAudio(0);
|
||||
#ifndef _WIN32
|
||||
joystick = new SDLJoystick();
|
||||
#endif
|
||||
EnableFZ();
|
||||
|
||||
int framecount = 0;
|
||||
float t = 0;
|
||||
float lastT = 0;
|
||||
uint32_t pad_buttons = 0; // legacy pad buttons
|
||||
while (true) {
|
||||
input_state.accelerometer_valid = false;
|
||||
input_state.mouse_valid = true;
|
||||
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event)) {
|
||||
float mx = event.motion.x * g_dpi_scale;
|
||||
float my = event.motion.y * g_dpi_scale;
|
||||
|
||||
switch (event.type) {
|
||||
case SDL_QUIT:
|
||||
g_QuitRequested = 1;
|
||||
break;
|
||||
#if !defined(MOBILE_DEVICE)
|
||||
case SDL_WINDOWEVENT:
|
||||
switch (event.window.event) {
|
||||
case SDL_WINDOWEVENT_RESIZED:
|
||||
{
|
||||
Uint32 window_flags = SDL_GetWindowFlags(g_Screen);
|
||||
bool fullscreen = (window_flags & SDL_WINDOW_FULLSCREEN);
|
||||
|
||||
pixel_xres = event.window.data1;
|
||||
pixel_yres = event.window.data2;
|
||||
dp_xres = (float)pixel_xres * dpi_scale;
|
||||
dp_yres = (float)pixel_yres * dpi_scale;
|
||||
NativeResized();
|
||||
|
||||
#if defined(PPSSPP)
|
||||
// Set variable here in case fullscreen was toggled by hotkey
|
||||
g_Config.bFullScreen = fullscreen;
|
||||
|
||||
// Hide/Show cursor correctly toggling fullscreen
|
||||
if (lastUIState == UISTATE_INGAME && fullscreen && !g_Config.bShowTouchControls) {
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
} else if (lastUIState != UISTATE_INGAME || !fullscreen) {
|
||||
SDL_ShowCursor(SDL_ENABLE);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case SDL_KEYDOWN:
|
||||
{
|
||||
int k = event.key.keysym.sym;
|
||||
KeyInput key;
|
||||
key.flags = KEY_DOWN;
|
||||
key.keyCode = KeyMapRawSDLtoNative.find(k)->second;
|
||||
key.deviceId = DEVICE_ID_KEYBOARD;
|
||||
NativeKey(key);
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(legacyKeyMap); i++) {
|
||||
if (legacyKeyMap[i] == key.keyCode)
|
||||
pad_buttons |= 1 << i;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_KEYUP:
|
||||
{
|
||||
int k = event.key.keysym.sym;
|
||||
KeyInput key;
|
||||
key.flags = KEY_UP;
|
||||
key.keyCode = KeyMapRawSDLtoNative.find(k)->second;
|
||||
key.deviceId = DEVICE_ID_KEYBOARD;
|
||||
NativeKey(key);
|
||||
for (int i = 0; i < ARRAY_SIZE(legacyKeyMap); i++) {
|
||||
if (legacyKeyMap[i] == key.keyCode)
|
||||
pad_buttons &= ~(1 << i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_TEXTINPUT:
|
||||
{
|
||||
int pos = 0;
|
||||
int c = u8_nextchar(event.text.text, &pos);
|
||||
KeyInput key;
|
||||
key.flags = KEY_CHAR;
|
||||
key.keyCode = c;
|
||||
key.deviceId = DEVICE_ID_KEYBOARD;
|
||||
NativeKey(key);
|
||||
break;
|
||||
}
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
switch (event.button.button) {
|
||||
case SDL_BUTTON_LEFT:
|
||||
{
|
||||
input_state.pointer_x[0] = mx;
|
||||
input_state.pointer_y[0] = my;
|
||||
input_state.pointer_down[0] = true;
|
||||
input_state.mouse_valid = true;
|
||||
TouchInput input;
|
||||
input.x = mx;
|
||||
input.y = my;
|
||||
input.flags = TOUCH_DOWN | TOUCH_MOUSE;
|
||||
input.id = 0;
|
||||
NativeTouch(input);
|
||||
KeyInput key(DEVICE_ID_MOUSE, NKCODE_EXT_MOUSEBUTTON_1, KEY_DOWN);
|
||||
NativeKey(key);
|
||||
}
|
||||
break;
|
||||
case SDL_BUTTON_RIGHT:
|
||||
{
|
||||
KeyInput key(DEVICE_ID_MOUSE, NKCODE_EXT_MOUSEBUTTON_2, KEY_DOWN);
|
||||
NativeKey(key);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SDL_MOUSEWHEEL:
|
||||
{
|
||||
KeyInput key;
|
||||
key.deviceId = DEVICE_ID_MOUSE;
|
||||
if (event.wheel.y > 0) {
|
||||
key.keyCode = NKCODE_EXT_MOUSEWHEEL_UP;
|
||||
} else {
|
||||
key.keyCode = NKCODE_EXT_MOUSEWHEEL_DOWN;
|
||||
}
|
||||
key.flags = KEY_DOWN;
|
||||
NativeKey(key);
|
||||
|
||||
// SDL2 doesn't consider the mousewheel a button anymore
|
||||
// so let's send the KEY_UP right away.
|
||||
// Maybe KEY_UP alone will suffice?
|
||||
key.flags = KEY_UP;
|
||||
NativeKey(key);
|
||||
}
|
||||
case SDL_MOUSEMOTION:
|
||||
if (input_state.pointer_down[0]) {
|
||||
input_state.pointer_x[0] = mx;
|
||||
input_state.pointer_y[0] = my;
|
||||
input_state.mouse_valid = true;
|
||||
TouchInput input;
|
||||
input.x = mx;
|
||||
input.y = my;
|
||||
input.flags = TOUCH_MOVE | TOUCH_MOUSE;
|
||||
input.id = 0;
|
||||
NativeTouch(input);
|
||||
}
|
||||
break;
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
switch (event.button.button) {
|
||||
case SDL_BUTTON_LEFT:
|
||||
{
|
||||
input_state.pointer_x[0] = mx;
|
||||
input_state.pointer_y[0] = my;
|
||||
input_state.pointer_down[0] = false;
|
||||
input_state.mouse_valid = true;
|
||||
//input_state.mouse_buttons_up = 1;
|
||||
TouchInput input;
|
||||
input.x = mx;
|
||||
input.y = my;
|
||||
input.flags = TOUCH_UP | TOUCH_MOUSE;
|
||||
input.id = 0;
|
||||
NativeTouch(input);
|
||||
KeyInput key(DEVICE_ID_MOUSE, NKCODE_EXT_MOUSEBUTTON_1, KEY_UP);
|
||||
NativeKey(key);
|
||||
}
|
||||
break;
|
||||
case SDL_BUTTON_RIGHT:
|
||||
{
|
||||
KeyInput key(DEVICE_ID_MOUSE, NKCODE_EXT_MOUSEBUTTON_2, KEY_UP);
|
||||
NativeKey(key);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
#ifndef _WIN32
|
||||
joystick->ProcessInput(event);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (g_QuitRequested)
|
||||
break;
|
||||
const uint8_t *keys = SDL_GetKeyboardState(NULL);
|
||||
SimulateGamepad(keys, &input_state);
|
||||
input_state.pad_buttons = pad_buttons;
|
||||
UpdateInputState(&input_state, true);
|
||||
#ifdef PPSSPP
|
||||
UpdateRunLoop();
|
||||
#else
|
||||
NativeUpdate(input_state);
|
||||
NativeRender();
|
||||
#endif
|
||||
if (g_QuitRequested)
|
||||
break;
|
||||
#if defined(PPSSPP) && !defined(MOBILE_DEVICE)
|
||||
if (lastUIState != GetUIState()) {
|
||||
lastUIState = GetUIState();
|
||||
if (lastUIState == UISTATE_INGAME && g_Config.bFullScreen && !g_Config.bShowTouchControls)
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
if (lastUIState != UISTATE_INGAME && g_Config.bFullScreen)
|
||||
SDL_ShowCursor(SDL_ENABLE);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (framecount % 60 == 0) {
|
||||
// glsl_refresh(); // auto-reloads modified GLSL shaders once per second.
|
||||
}
|
||||
|
||||
#ifdef USING_EGL
|
||||
eglSwapBuffers(g_eglDisplay, g_eglSurface);
|
||||
#else
|
||||
if (!keys[SDLK_TAB] || t - lastT >= 1.0/60.0)
|
||||
{
|
||||
SDL_GL_SwapWindow(g_Screen);
|
||||
lastT = t;
|
||||
}
|
||||
#endif
|
||||
|
||||
ToggleFullScreenIfFlagSet();
|
||||
time_update();
|
||||
t = time_now();
|
||||
framecount++;
|
||||
}
|
||||
#ifndef _WIN32
|
||||
delete joystick;
|
||||
#endif
|
||||
// Faster exit, thanks to the OS. Remove this if you want to debug shutdown
|
||||
// The speed difference is only really noticable on Linux. On Windows you do notice it though
|
||||
#ifndef MOBILE_DEVICE
|
||||
exit(0);
|
||||
#endif
|
||||
NativeShutdownGraphics();
|
||||
SDL_PauseAudio(1);
|
||||
SDL_CloseAudio();
|
||||
NativeShutdown();
|
||||
#ifdef USING_EGL
|
||||
EGL_Close();
|
||||
#endif
|
||||
SDL_GL_DeleteContext(glContext);
|
||||
SDL_Quit();
|
||||
net::Shutdown();
|
||||
#ifdef RPI
|
||||
bcm_host_deinit();
|
||||
#endif
|
||||
|
||||
exit(0);
|
||||
return 0;
|
||||
}
|
257
ext/native/base/QtMain.cpp
Normal file
257
ext/native/base/QtMain.cpp
Normal file
@ -0,0 +1,257 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Sacha Refshauge
|
||||
*
|
||||
*/
|
||||
// Qt 4.7+ / 5.0+ implementation of the framework.
|
||||
// Currently supports: Android, Symbian, Blackberry, Maemo/Meego, Linux, Windows, Mac OSX
|
||||
|
||||
#include <QApplication>
|
||||
#include <QUrl>
|
||||
#include <QDir>
|
||||
#include <QDesktopWidget>
|
||||
#include <QDesktopServices>
|
||||
#include <QLocale>
|
||||
#include <QThread>
|
||||
|
||||
#if QT_VERSION > QT_VERSION_CHECK(5, 0, 0)
|
||||
#include <QStandardPaths>
|
||||
#ifdef QT_HAS_SYSTEMINFO
|
||||
#include <QScreenSaver>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __SYMBIAN32__
|
||||
#include <QSystemScreenSaver>
|
||||
#include <QFeedbackHapticsEffect>
|
||||
#include "SymbianMediaKeys.h"
|
||||
#endif
|
||||
#ifdef SDL
|
||||
#include "SDL/SDLJoystick.h"
|
||||
#include "SDL_audio.h"
|
||||
#endif
|
||||
#include "QtMain.h"
|
||||
#include "math/math_util.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
InputState* input_state;
|
||||
|
||||
#ifdef SDL
|
||||
extern void mixaudio(void *userdata, Uint8 *stream, int len) {
|
||||
NativeMix((short *)stream, len / 4);
|
||||
}
|
||||
#endif
|
||||
|
||||
std::string System_GetProperty(SystemProperty prop) {
|
||||
switch (prop) {
|
||||
case SYSPROP_NAME:
|
||||
#ifdef __SYMBIAN32__
|
||||
return "Qt:Symbian";
|
||||
#elif defined(BLACKBERRY)
|
||||
return "Qt:Blackberry";
|
||||
#elif defined(MAEMO)
|
||||
return "Qt:Maemo";
|
||||
#elif defined(ANDROID)
|
||||
return "Qt:Android";
|
||||
#elif defined(Q_OS_LINUX)
|
||||
return "Qt:Linux";
|
||||
#elif defined(_WIN32)
|
||||
return "Qt:Windows";
|
||||
#elif defined(Q_OS_MAC)
|
||||
return "Qt:Mac";
|
||||
#else
|
||||
return "Qt";
|
||||
#endif
|
||||
case SYSPROP_LANGREGION:
|
||||
return QLocale::system().name().toStdString();
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
int System_GetPropertyInt(SystemProperty prop) {
|
||||
switch (prop) {
|
||||
case SYSPROP_AUDIO_SAMPLE_RATE:
|
||||
return 44100;
|
||||
case SYSPROP_DISPLAY_REFRESH_RATE:
|
||||
return 60000;
|
||||
case SYSPROP_DEVICE_TYPE:
|
||||
#ifdef __SYMBIAN32__
|
||||
return DEVICE_TYPE_MOBILE;
|
||||
#elif defined(BLACKBERRY)
|
||||
return DEVICE_TYPE_MOBILE;
|
||||
#elif defined(MAEMO)
|
||||
return DEVICE_TYPE_MOBILE;
|
||||
#elif defined(ANDROID)
|
||||
return DEVICE_TYPE_MOBILE;
|
||||
#elif defined(Q_OS_LINUX)
|
||||
return DEVICE_TYPE_DESKTOP;
|
||||
#elif defined(_WIN32)
|
||||
return DEVICE_TYPE_DESKTOP;
|
||||
#elif defined(Q_OS_MAC)
|
||||
return DEVICE_TYPE_DESKTOP;
|
||||
#else
|
||||
return DEVICE_TYPE_DESKTOP;
|
||||
#endif
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void System_SendMessage(const char *command, const char *parameter) {
|
||||
if (!strcmp(command, "finish")) {
|
||||
qApp->exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
bool System_InputBoxGetString(const char *title, const char *defaultValue, char *outValue, size_t outLength)
|
||||
{
|
||||
QString text = emugl->InputBoxGetQString(QString(title), QString(defaultValue));
|
||||
if (text.isEmpty())
|
||||
return false;
|
||||
strcpy(outValue, text.toStdString().c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
void Vibrate(int length_ms) {
|
||||
if (length_ms == -1 || length_ms == -3)
|
||||
length_ms = 50;
|
||||
else if (length_ms == -2)
|
||||
length_ms = 25;
|
||||
// Symbian only for now
|
||||
#if defined(__SYMBIAN32__)
|
||||
QFeedbackHapticsEffect effect;
|
||||
effect.setIntensity(0.8);
|
||||
effect.setDuration(length_ms);
|
||||
effect.start();
|
||||
#endif
|
||||
}
|
||||
|
||||
void LaunchBrowser(const char *url)
|
||||
{
|
||||
QDesktopServices::openUrl(QUrl(url));
|
||||
}
|
||||
|
||||
float CalculateDPIScale()
|
||||
{
|
||||
// Sane default rather than check DPI
|
||||
#ifdef __SYMBIAN32__
|
||||
return 1.4f;
|
||||
#elif defined(USING_GLES2)
|
||||
return 1.2f;
|
||||
#else
|
||||
return 1.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int mainInternal(QApplication &a)
|
||||
{
|
||||
#ifdef MOBILE_DEVICE
|
||||
emugl = new MainUI();
|
||||
emugl->resize(pixel_xres, pixel_yres);
|
||||
emugl->showFullScreen();
|
||||
#endif
|
||||
EnableFZ();
|
||||
// Disable screensaver
|
||||
#ifdef __SYMBIAN32__
|
||||
QSystemScreenSaver ssObject(emugl);
|
||||
ssObject.setScreenSaverInhibit();
|
||||
QScopedPointer<SymbianMediaKeys> mediakeys(new SymbianMediaKeys());
|
||||
#elif defined(QT_HAS_SYSTEMINFO)
|
||||
QScreenSaver ssObject(emugl);
|
||||
ssObject.setScreenSaverEnabled(false);
|
||||
#endif
|
||||
|
||||
#ifdef SDL
|
||||
SDLJoystick joy(true);
|
||||
joy.startEventLoop();
|
||||
SDL_Init(SDL_INIT_AUDIO);
|
||||
SDL_AudioSpec fmt, ret_fmt;
|
||||
memset(&fmt, 0, sizeof(fmt));
|
||||
fmt.freq = 44100;
|
||||
fmt.format = AUDIO_S16;
|
||||
fmt.channels = 2;
|
||||
fmt.samples = 2048;
|
||||
fmt.callback = &mixaudio;
|
||||
fmt.userdata = (void *)0;
|
||||
|
||||
if (SDL_OpenAudio(&fmt, &ret_fmt) < 0) {
|
||||
ELOG("Failed to open audio: %s", SDL_GetError());
|
||||
} else {
|
||||
if (ret_fmt.samples != fmt.samples) // Notify, but still use it
|
||||
ELOG("Output audio samples: %d (requested: %d)", ret_fmt.samples, fmt.samples);
|
||||
if (ret_fmt.freq != fmt.freq || ret_fmt.format != fmt.format || ret_fmt.channels != fmt.channels) {
|
||||
ELOG("Sound buffer format does not match requested format.");
|
||||
ELOG("Output audio freq: %d (requested: %d)", ret_fmt.freq, fmt.freq);
|
||||
ELOG("Output audio format: %d (requested: %d)", ret_fmt.format, fmt.format);
|
||||
ELOG("Output audio channels: %d (requested: %d)", ret_fmt.channels, fmt.channels);
|
||||
ELOG("Provided output format does not match requirement, turning audio off");
|
||||
SDL_CloseAudio();
|
||||
}
|
||||
}
|
||||
SDL_PauseAudio(0);
|
||||
#else
|
||||
QScopedPointer<MainAudio> audio(new MainAudio());
|
||||
audio->run();
|
||||
#endif
|
||||
return a.exec();
|
||||
}
|
||||
|
||||
#ifndef SDL
|
||||
Q_DECL_EXPORT
|
||||
#endif
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#if defined(Q_OS_LINUX) && !defined(MAEMO)
|
||||
QApplication::setAttribute(Qt::AA_X11InitThreads, true);
|
||||
#endif
|
||||
QApplication a(argc, argv);
|
||||
QSize res = QApplication::desktop()->screenGeometry().size();
|
||||
if (res.width() < res.height())
|
||||
res.transpose();
|
||||
pixel_xres = res.width();
|
||||
pixel_yres = res.height();
|
||||
g_dpi_scale = CalculateDPIScale();
|
||||
dp_xres = (int)(pixel_xres * g_dpi_scale); dp_yres = (int)(pixel_yres * g_dpi_scale);
|
||||
net::Init();
|
||||
std::string savegame_dir = ".";
|
||||
std::string assets_dir = ".";
|
||||
#if QT_VERSION > QT_VERSION_CHECK(5, 0, 0)
|
||||
savegame_dir = QStandardPaths::writableLocation(QStandardPaths::HomeLocation).toStdString();
|
||||
assets_dir = QStandardPaths::writableLocation(QStandardPaths::DataLocation).toStdString();
|
||||
#elif defined(__SYMBIAN32__)
|
||||
savegame_dir = "E:/PPSSPP";
|
||||
assets_dir = "E:/PPSSPP";
|
||||
#elif defined(BLACKBERRY)
|
||||
savegame_dir = "/accounts/1000/shared/misc";
|
||||
assets_dir = "app/native/assets";
|
||||
#elif defined(MAEMO)
|
||||
savegame_dir = "/home/user/MyDocs/PPSSPP";
|
||||
assets_dir = "/opt/PPSSPP";
|
||||
#endif
|
||||
savegame_dir += "/";
|
||||
assets_dir += "/";
|
||||
|
||||
bool fullscreenCLI=false;
|
||||
for (int i = 1; i < argc; i++)
|
||||
{
|
||||
if (!strcmp(argv[i],"--fullscreen"))
|
||||
fullscreenCLI=true;
|
||||
}
|
||||
NativeInit(argc, (const char **)argv, savegame_dir.c_str(), assets_dir.c_str(), "BADCOFFEE",fullscreenCLI);
|
||||
|
||||
int ret = mainInternal(a);
|
||||
|
||||
#ifndef MOBILE_DEVICE
|
||||
exit(0);
|
||||
#endif
|
||||
NativeShutdownGraphics();
|
||||
#ifdef SDL
|
||||
SDL_PauseAudio(1);
|
||||
SDL_CloseAudio();
|
||||
#endif
|
||||
NativeShutdown();
|
||||
net::Shutdown();
|
||||
return ret;
|
||||
}
|
||||
|
296
ext/native/base/QtMain.h
Normal file
296
ext/native/base/QtMain.h
Normal file
@ -0,0 +1,296 @@
|
||||
#ifndef QTMAIN_H
|
||||
#define QTMAIN_H
|
||||
|
||||
#include <QTouchEvent>
|
||||
#include <QMouseEvent>
|
||||
#include <QInputDialog>
|
||||
#include "gfx_es2/glsl_program.h"
|
||||
#include <QGLWidget>
|
||||
|
||||
#ifndef SDL
|
||||
#include <QAudioOutput>
|
||||
#include <QAudioFormat>
|
||||
#endif
|
||||
#if defined(MOBILE_DEVICE) && !defined(MAEMO)
|
||||
#include <QAccelerometer>
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
|
||||
QTM_USE_NAMESPACE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "base/display.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/timeutil.h"
|
||||
#include "file/zip_read.h"
|
||||
#include "gfx/gl_common.h"
|
||||
#include "input/input_state.h"
|
||||
#include "input/keycodes.h"
|
||||
#include "base/NativeApp.h"
|
||||
#include "net/resolve.h"
|
||||
#include "base/NKCodeFromQt.h"
|
||||
|
||||
// Bad: PPSSPP includes from native
|
||||
#include "Core/System.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/Config.h"
|
||||
|
||||
// Input
|
||||
void SimulateGamepad(InputState *input);
|
||||
|
||||
//GUI
|
||||
class MainUI : public QGLWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MainUI(QWidget *parent = 0):
|
||||
QGLWidget(parent)
|
||||
{
|
||||
setAttribute(Qt::WA_AcceptTouchEvents);
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
|
||||
setAttribute(Qt::WA_LockLandscapeOrientation);
|
||||
#endif
|
||||
#if defined(MOBILE_DEVICE) && !defined(MAEMO)
|
||||
acc = new QAccelerometer(this);
|
||||
acc->start();
|
||||
#endif
|
||||
setFocus();
|
||||
setFocusPolicy(Qt::StrongFocus);
|
||||
startTimer(16);
|
||||
}
|
||||
~MainUI() {
|
||||
#if defined(MOBILE_DEVICE) && !defined(MAEMO)
|
||||
delete acc;
|
||||
#endif
|
||||
NativeShutdownGraphics();
|
||||
}
|
||||
|
||||
public slots:
|
||||
QString InputBoxGetQString(QString title, QString defaultValue) {
|
||||
bool ok;
|
||||
QString text = QInputDialog::getText(this, title, title, QLineEdit::Normal, defaultValue, &ok);
|
||||
if (!ok)
|
||||
text = QString();
|
||||
return text;
|
||||
}
|
||||
|
||||
signals:
|
||||
void doubleClick();
|
||||
void newFrame();
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent * e)
|
||||
{
|
||||
UpdateScreenScale(e->size().width(), e->size().height(), false);
|
||||
PSP_CoreParameter().pixelWidth = pixel_xres;
|
||||
PSP_CoreParameter().pixelHeight = pixel_yres;
|
||||
}
|
||||
|
||||
void timerEvent(QTimerEvent *) {
|
||||
updateGL();
|
||||
emit newFrame();
|
||||
}
|
||||
void changeEvent(QEvent *e)
|
||||
{
|
||||
QGLWidget::changeEvent(e);
|
||||
if(e->type() == QEvent::WindowStateChange)
|
||||
Core_NotifyWindowHidden(isMinimized());
|
||||
}
|
||||
bool event(QEvent *e)
|
||||
{
|
||||
TouchInput input;
|
||||
QList<QTouchEvent::TouchPoint> touchPoints;
|
||||
switch(e->type())
|
||||
{
|
||||
case QEvent::TouchBegin:
|
||||
case QEvent::TouchUpdate:
|
||||
case QEvent::TouchEnd:
|
||||
touchPoints = static_cast<QTouchEvent *>(e)->touchPoints();
|
||||
foreach (const QTouchEvent::TouchPoint &touchPoint, touchPoints) {
|
||||
switch (touchPoint.state()) {
|
||||
case Qt::TouchPointStationary:
|
||||
break;
|
||||
case Qt::TouchPointPressed:
|
||||
case Qt::TouchPointReleased:
|
||||
input_state.pointer_down[touchPoint.id()] = (touchPoint.state() == Qt::TouchPointPressed);
|
||||
input_state.pointer_x[touchPoint.id()] = touchPoint.pos().x() * g_dpi_scale;
|
||||
input_state.pointer_y[touchPoint.id()] = touchPoint.pos().y() * g_dpi_scale;
|
||||
|
||||
input.x = touchPoint.pos().x() * g_dpi_scale;
|
||||
input.y = touchPoint.pos().y() * g_dpi_scale;
|
||||
input.flags = (touchPoint.state() == Qt::TouchPointPressed) ? TOUCH_DOWN : TOUCH_UP;
|
||||
input.id = touchPoint.id();
|
||||
NativeTouch(input);
|
||||
break;
|
||||
case Qt::TouchPointMoved:
|
||||
input_state.pointer_x[touchPoint.id()] = touchPoint.pos().x() * g_dpi_scale;
|
||||
input_state.pointer_y[touchPoint.id()] = touchPoint.pos().y() * g_dpi_scale;
|
||||
|
||||
input.x = touchPoint.pos().x() * g_dpi_scale;
|
||||
input.y = touchPoint.pos().y() * g_dpi_scale;
|
||||
input.flags = TOUCH_MOVE;
|
||||
input.id = touchPoint.id();
|
||||
NativeTouch(input);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case QEvent::MouseButtonDblClick:
|
||||
if (!g_Config.bShowTouchControls || GetUIState() != UISTATE_INGAME)
|
||||
emit doubleClick();
|
||||
break;
|
||||
case QEvent::MouseButtonPress:
|
||||
case QEvent::MouseButtonRelease:
|
||||
input_state.pointer_down[0] = (e->type() == QEvent::MouseButtonPress);
|
||||
input_state.pointer_x[0] = ((QMouseEvent*)e)->pos().x() * g_dpi_scale;
|
||||
input_state.pointer_y[0] = ((QMouseEvent*)e)->pos().y() * g_dpi_scale;
|
||||
|
||||
input.x = ((QMouseEvent*)e)->pos().x() * g_dpi_scale;
|
||||
input.y = ((QMouseEvent*)e)->pos().y() * g_dpi_scale;
|
||||
input.flags = (e->type() == QEvent::MouseButtonPress) ? TOUCH_DOWN : TOUCH_UP;
|
||||
input.id = 0;
|
||||
NativeTouch(input);
|
||||
break;
|
||||
case QEvent::MouseMove:
|
||||
input_state.pointer_x[0] = ((QMouseEvent*)e)->pos().x() * g_dpi_scale;
|
||||
input_state.pointer_y[0] = ((QMouseEvent*)e)->pos().y() * g_dpi_scale;
|
||||
|
||||
input.x = ((QMouseEvent*)e)->pos().x() * g_dpi_scale;
|
||||
input.y = ((QMouseEvent*)e)->pos().y() * g_dpi_scale;
|
||||
input.flags = TOUCH_MOVE;
|
||||
input.id = 0;
|
||||
NativeTouch(input);
|
||||
break;
|
||||
case QEvent::Wheel:
|
||||
NativeKey(KeyInput(DEVICE_ID_MOUSE, ((QWheelEvent*)e)->delta()<0 ? NKCODE_EXT_MOUSEWHEEL_DOWN : NKCODE_EXT_MOUSEWHEEL_UP, KEY_DOWN));
|
||||
break;
|
||||
case QEvent::KeyPress:
|
||||
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, KeyMapRawQttoNative.find(((QKeyEvent*)e)->key())->second, KEY_DOWN));
|
||||
break;
|
||||
case QEvent::KeyRelease:
|
||||
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, KeyMapRawQttoNative.find(((QKeyEvent*)e)->key())->second, KEY_UP));
|
||||
break;
|
||||
default:
|
||||
return QWidget::event(e);
|
||||
}
|
||||
e->accept();
|
||||
return true;
|
||||
}
|
||||
|
||||
void initializeGL()
|
||||
{
|
||||
#ifndef USING_GLES2
|
||||
glewInit();
|
||||
#endif
|
||||
NativeInitGraphics();
|
||||
}
|
||||
|
||||
void paintGL()
|
||||
{
|
||||
updateAccelerometer();
|
||||
UpdateInputState(&input_state);
|
||||
time_update();
|
||||
UpdateRunLoop();
|
||||
}
|
||||
|
||||
void updateAccelerometer()
|
||||
{
|
||||
#if defined(MOBILE_DEVICE) && !defined(MAEMO)
|
||||
// TODO: Toggle it depending on whether it is enabled
|
||||
QAccelerometerReading *reading = acc->reading();
|
||||
if (reading) {
|
||||
input_state.acc.x = reading->x();
|
||||
input_state.acc.y = reading->y();
|
||||
input_state.acc.z = reading->z();
|
||||
AxisInput axis;
|
||||
axis.deviceId = DEVICE_ID_ACCELEROMETER;
|
||||
axis.flags = 0;
|
||||
|
||||
axis.axisId = JOYSTICK_AXIS_ACCELEROMETER_X;
|
||||
axis.value = input_state.acc.x;
|
||||
NativeAxis(axis);
|
||||
|
||||
axis.axisId = JOYSTICK_AXIS_ACCELEROMETER_Y;
|
||||
axis.value = input_state.acc.y;
|
||||
NativeAxis(axis);
|
||||
|
||||
axis.axisId = JOYSTICK_AXIS_ACCELEROMETER_Z;
|
||||
axis.value = input_state.acc.z;
|
||||
NativeAxis(axis);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
InputState input_state;
|
||||
#if defined(MOBILE_DEVICE) && !defined(MAEMO)
|
||||
QAccelerometer* acc;
|
||||
#endif
|
||||
};
|
||||
|
||||
static MainUI* emugl = NULL;
|
||||
|
||||
#ifndef SDL
|
||||
|
||||
// Audio
|
||||
#define AUDIO_FREQ 44100
|
||||
#define AUDIO_CHANNELS 2
|
||||
#define AUDIO_SAMPLES 2048
|
||||
#define AUDIO_SAMPLESIZE 16
|
||||
#define AUDIO_BUFFERS 5
|
||||
class MainAudio: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MainAudio() {
|
||||
}
|
||||
~MainAudio() {
|
||||
if (feed != NULL) {
|
||||
killTimer(timer);
|
||||
feed->close();
|
||||
}
|
||||
if (output) {
|
||||
output->stop();
|
||||
delete output;
|
||||
}
|
||||
if (mixbuf)
|
||||
free(mixbuf);
|
||||
}
|
||||
public slots:
|
||||
void run() {
|
||||
QAudioFormat fmt;
|
||||
fmt.setSampleRate(AUDIO_FREQ);
|
||||
fmt.setCodec("audio/pcm");
|
||||
fmt.setChannelCount(AUDIO_CHANNELS);
|
||||
fmt.setSampleSize(AUDIO_SAMPLESIZE);
|
||||
fmt.setByteOrder(QAudioFormat::LittleEndian);
|
||||
fmt.setSampleType(QAudioFormat::SignedInt);
|
||||
mixlen = sizeof(short)*AUDIO_BUFFERS*AUDIO_CHANNELS*AUDIO_SAMPLES;
|
||||
mixbuf = (char*)malloc(mixlen);
|
||||
output = new QAudioOutput(fmt);
|
||||
output->setBufferSize(mixlen);
|
||||
feed = output->start();
|
||||
if (feed != NULL)
|
||||
timer = startTimer((1000*AUDIO_SAMPLES) / AUDIO_FREQ);
|
||||
}
|
||||
|
||||
protected:
|
||||
void timerEvent(QTimerEvent *) {
|
||||
memset(mixbuf, 0, mixlen);
|
||||
size_t frames = NativeMix((short *)mixbuf, AUDIO_BUFFERS*AUDIO_SAMPLES);
|
||||
if (frames > 0)
|
||||
feed->write(mixbuf, sizeof(short) * AUDIO_CHANNELS * frames);
|
||||
}
|
||||
private:
|
||||
QIODevice* feed;
|
||||
QAudioOutput* output;
|
||||
int mixlen;
|
||||
char* mixbuf;
|
||||
int timer;
|
||||
};
|
||||
|
||||
#endif //SDL
|
||||
|
||||
#endif
|
||||
|
333
ext/native/base/SymbianMediaKeys.cpp
Normal file
333
ext/native/base/SymbianMediaKeys.cpp
Normal file
@ -0,0 +1,333 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Antti Pohjola
|
||||
*
|
||||
*/
|
||||
//Adds mediakey support for Symbian (volume up/down)
|
||||
|
||||
#include <QApplication>
|
||||
#include "SymbianMediaKeys.h"
|
||||
#include "input/keycodes.h"
|
||||
#include "input/input_state.h"
|
||||
#include "base/NativeApp.h"
|
||||
|
||||
#define KTimeOut 80
|
||||
|
||||
SymbianMediaKeys::SymbianMediaKeys()
|
||||
: CActive ( EPriorityNormal ){
|
||||
CActiveScheduler::Add( this );
|
||||
iInterfaceSelector = CRemConInterfaceSelector::NewL();
|
||||
iRemConCore = CRemConCoreApiTarget::NewL(*iInterfaceSelector, *this);
|
||||
iInterfaceSelector->OpenTargetL();
|
||||
|
||||
playtimer = new QTimer(this);
|
||||
connect(playtimer, SIGNAL(timeout()), this, SLOT(playtimerexpired()));
|
||||
stoptimer = new QTimer(this);
|
||||
connect(stoptimer, SIGNAL(timeout()), this, SLOT(stoptimerexpired()));
|
||||
forwardtimer = new QTimer(this);
|
||||
connect(forwardtimer, SIGNAL(timeout()), this, SLOT(forwardtimerexpired()));
|
||||
backwardtimer = new QTimer(this);
|
||||
connect(backwardtimer, SIGNAL(timeout()), this, SLOT(backwardtimerexpired()));
|
||||
voluptimer = new QTimer(this);
|
||||
connect(voluptimer, SIGNAL(timeout()), this, SLOT(voluptimerexpired()));
|
||||
voldowntimer = new QTimer(this);
|
||||
connect(voldowntimer, SIGNAL(timeout()), this, SLOT(voldowntimerexpired()));
|
||||
}
|
||||
|
||||
SymbianMediaKeys::~SymbianMediaKeys(){
|
||||
delete iInterfaceSelector;
|
||||
iRemConCore = NULL; //owned by interfaceselector
|
||||
Cancel();
|
||||
iResponseQ.Reset();
|
||||
iResponseQ.Close();
|
||||
}
|
||||
|
||||
void SymbianMediaKeys::subscribeKeyEvent(QObject* aObject ){
|
||||
receiver = aObject;
|
||||
}
|
||||
|
||||
/*
|
||||
* it seems that it takes about 600ms to get an update after buttonpress
|
||||
* */
|
||||
void SymbianMediaKeys::MrccatoCommand(TRemConCoreApiOperationId aOperationId,TRemConCoreApiButtonAction aButtonAct){
|
||||
TRequestStatus status;
|
||||
switch( aOperationId ){
|
||||
case ERemConCoreApiPausePlayFunction:
|
||||
{
|
||||
switch (aButtonAct){
|
||||
case ERemConCoreApiButtonPress:
|
||||
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_PLAY_PAUSE, KEY_DOWN));
|
||||
break;
|
||||
case ERemConCoreApiButtonRelease:
|
||||
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_PLAY_PAUSE, KEY_UP));
|
||||
break;
|
||||
case ERemConCoreApiButtonClick:
|
||||
playtimer->start(KTimeOut);
|
||||
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_PLAY_PAUSE, KEY_DOWN));
|
||||
break;
|
||||
default:
|
||||
// Play/Pause unknown action
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ERemConCoreApiStop:
|
||||
{
|
||||
switch (aButtonAct){
|
||||
case ERemConCoreApiButtonPress:
|
||||
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_STOP, KEY_DOWN));
|
||||
break;
|
||||
case ERemConCoreApiButtonRelease:
|
||||
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_STOP, KEY_UP));
|
||||
break;
|
||||
case ERemConCoreApiButtonClick:
|
||||
stoptimer->start(KTimeOut);
|
||||
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_STOP, KEY_DOWN));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ERemConCoreApiRewind:
|
||||
{
|
||||
switch (aButtonAct){
|
||||
case ERemConCoreApiButtonPress:
|
||||
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_PREVIOUS, KEY_DOWN));
|
||||
break;
|
||||
case ERemConCoreApiButtonRelease:
|
||||
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_PREVIOUS, KEY_UP));
|
||||
break;
|
||||
case ERemConCoreApiButtonClick:
|
||||
backwardtimer->start(KTimeOut);
|
||||
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_PREVIOUS, KEY_DOWN));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ERemConCoreApiFastForward:
|
||||
{
|
||||
switch (aButtonAct){
|
||||
case ERemConCoreApiButtonPress:
|
||||
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_NEXT, KEY_DOWN));
|
||||
break;
|
||||
case ERemConCoreApiButtonRelease:
|
||||
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_NEXT, KEY_UP));
|
||||
break;
|
||||
case ERemConCoreApiButtonClick:
|
||||
forwardtimer->start(KTimeOut);
|
||||
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_NEXT, KEY_DOWN));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ERemConCoreApiVolumeUp:
|
||||
{
|
||||
switch (aButtonAct){
|
||||
case ERemConCoreApiButtonPress:
|
||||
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_VOLUME_UP, KEY_DOWN));
|
||||
break;
|
||||
case ERemConCoreApiButtonRelease:
|
||||
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_VOLUME_UP, KEY_UP));
|
||||
break;
|
||||
case ERemConCoreApiButtonClick:
|
||||
voluptimer->start(KTimeOut);
|
||||
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_VOLUME_UP, KEY_DOWN));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ERemConCoreApiVolumeDown:
|
||||
{
|
||||
switch (aButtonAct){
|
||||
case ERemConCoreApiButtonPress:
|
||||
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_VOLUME_DOWN, KEY_DOWN));
|
||||
break;
|
||||
case ERemConCoreApiButtonRelease:
|
||||
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_VOLUME_DOWN, KEY_UP));
|
||||
break;
|
||||
case ERemConCoreApiButtonClick:
|
||||
voldowntimer->start(KTimeOut);
|
||||
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_VOLUME_DOWN, KEY_DOWN));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ERemConCoreApiBackward:
|
||||
{
|
||||
switch (aButtonAct)
|
||||
{
|
||||
case ERemConCoreApiButtonPress:
|
||||
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_PREVIOUS, KEY_DOWN));
|
||||
break;
|
||||
case ERemConCoreApiButtonRelease:
|
||||
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_PREVIOUS, KEY_UP));
|
||||
break;
|
||||
case ERemConCoreApiButtonClick:
|
||||
backwardtimer->start(KTimeOut);
|
||||
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_PREVIOUS, KEY_DOWN));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ERemConCoreApiForward:
|
||||
{
|
||||
switch (aButtonAct)
|
||||
{
|
||||
case ERemConCoreApiButtonPress:
|
||||
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_NEXT, KEY_DOWN));
|
||||
break;
|
||||
case ERemConCoreApiButtonRelease:
|
||||
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_NEXT, KEY_UP));
|
||||
break;
|
||||
case ERemConCoreApiButtonClick:
|
||||
forwardtimer->start(KTimeOut);
|
||||
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_NEXT, KEY_DOWN));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
//complete key event
|
||||
CompleteMediaKeyEvent( aOperationId );
|
||||
}
|
||||
|
||||
void SymbianMediaKeys::MrccatoPlay(TRemConCoreApiPlaybackSpeed aSpeed,TRemConCoreApiButtonAction aButtonAct){
|
||||
|
||||
}
|
||||
|
||||
void SymbianMediaKeys::MrccatoTuneFunction(TBool aTwoPart, TUint aMajorChannel,TUint aMinorChannel,TRemConCoreApiButtonAction aButtonAct){
|
||||
|
||||
}
|
||||
|
||||
void SymbianMediaKeys::MrccatoSelectDiskFunction(TUint aDisk, TRemConCoreApiButtonAction aButtonAct){
|
||||
|
||||
}
|
||||
|
||||
void SymbianMediaKeys::MrccatoSelectAvInputFunction(TUint8 aAvInputSignalNumber,TRemConCoreApiButtonAction aButtonAct){
|
||||
|
||||
}
|
||||
|
||||
void SymbianMediaKeys::MrccatoSelectAudioInputFunction(TUint8 aAudioInputSignalNumber,TRemConCoreApiButtonAction aButtonAct){
|
||||
|
||||
}
|
||||
|
||||
void SymbianMediaKeys::CompleteMediaKeyEvent( TRemConCoreApiOperationId aOperationId ){
|
||||
if( !IsActive() ){
|
||||
switch ( aOperationId )
|
||||
{
|
||||
case ERemConCoreApiVolumeUp:
|
||||
{
|
||||
iRemConCore->VolumeUpResponse( iStatus, KErrNone );
|
||||
SetActive();
|
||||
break;
|
||||
}
|
||||
|
||||
case ERemConCoreApiVolumeDown:
|
||||
{
|
||||
iRemConCore->VolumeDownResponse( iStatus, KErrNone );
|
||||
SetActive();
|
||||
break;
|
||||
}
|
||||
case ERemConCoreApiPlay:
|
||||
{
|
||||
iRemConCore-> PlayResponse(iStatus, KErrNone);
|
||||
SetActive();
|
||||
break;
|
||||
}
|
||||
case ERemConCoreApiStop:
|
||||
{
|
||||
iRemConCore->StopResponse(iStatus, KErrNone);
|
||||
SetActive();
|
||||
break;
|
||||
}
|
||||
case ERemConCoreApiPause:
|
||||
{
|
||||
iRemConCore->PauseResponse(iStatus, KErrNone);
|
||||
SetActive();
|
||||
break;
|
||||
}
|
||||
case ERemConCoreApiRewind:
|
||||
{
|
||||
iRemConCore->RewindResponse(iStatus, KErrNone);
|
||||
SetActive();
|
||||
break;
|
||||
}
|
||||
case ERemConCoreApiFastForward:
|
||||
{
|
||||
iRemConCore->FastForwardResponse(iStatus, KErrNone);
|
||||
SetActive();
|
||||
break;
|
||||
}
|
||||
case ERemConCoreApiForward:
|
||||
{
|
||||
iRemConCore->ForwardResponse( iStatus, KErrNone );
|
||||
SetActive();
|
||||
break;
|
||||
}
|
||||
case ERemConCoreApiBackward:
|
||||
{
|
||||
iRemConCore->BackwardResponse(iStatus, KErrNone );
|
||||
SetActive();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else{
|
||||
//active, append to queue
|
||||
iResponseQ.Append( aOperationId );
|
||||
}
|
||||
}
|
||||
|
||||
void SymbianMediaKeys::RunL(){
|
||||
if ( iResponseQ.Count() ){
|
||||
CompleteMediaKeyEvent( iResponseQ[0] );
|
||||
//remove old response from que
|
||||
iResponseQ.Remove(0);
|
||||
iResponseQ.Compress();
|
||||
}
|
||||
}
|
||||
|
||||
void SymbianMediaKeys::DoCancel(){
|
||||
}
|
||||
|
||||
void SymbianMediaKeys::playtimerexpired(){
|
||||
playtimer->stop();
|
||||
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_PLAY_PAUSE, KEY_UP));
|
||||
}
|
||||
|
||||
void SymbianMediaKeys::stoptimerexpired(){
|
||||
stoptimer->stop();
|
||||
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_STOP, KEY_UP));
|
||||
}
|
||||
|
||||
void SymbianMediaKeys::forwardtimerexpired(){
|
||||
forwardtimer->stop();
|
||||
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_NEXT, KEY_UP));
|
||||
}
|
||||
|
||||
void SymbianMediaKeys::backwardtimerexpired(){
|
||||
backwardtimer->stop();
|
||||
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_MEDIA_PREVIOUS, KEY_UP));
|
||||
}
|
||||
|
||||
void SymbianMediaKeys::voluptimerexpired(){
|
||||
voluptimer->stop();
|
||||
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_VOLUME_UP, KEY_UP));
|
||||
}
|
||||
|
||||
void SymbianMediaKeys::voldowntimerexpired(){
|
||||
voldowntimer->stop();
|
||||
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_VOLUME_DOWN, KEY_UP));
|
||||
}
|
70
ext/native/base/SymbianMediaKeys.h
Normal file
70
ext/native/base/SymbianMediaKeys.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Antti Pohjola
|
||||
*
|
||||
*/
|
||||
//Adds mediakey support for Symbian (volume up/down)
|
||||
|
||||
#ifndef SYMBIANMEDIAKEYS_H_
|
||||
#define SYMBIANMEDIAKEYS_H_
|
||||
|
||||
#include <QObject>
|
||||
#include <QTimer>
|
||||
#include <e32base.h>
|
||||
|
||||
#include <remconcoreapitargetobserver.h> // link against RemConCoreApi.lib
|
||||
#include <remconcoreapitarget.h> // and
|
||||
#include <remconinterfaceselector.h> // RemConInterfaceBase.lib
|
||||
|
||||
class SymbianMediaKeys: public QObject, public CActive, public MRemConCoreApiTargetObserver
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SymbianMediaKeys();
|
||||
virtual ~SymbianMediaKeys();
|
||||
|
||||
public:
|
||||
void subscribeKeyEvent(QObject* aObject );
|
||||
|
||||
public: //From MRemConCoreApiTargetObserver
|
||||
void MrccatoCommand(TRemConCoreApiOperationId aOperationId,TRemConCoreApiButtonAction aButtonAct);
|
||||
|
||||
void MrccatoPlay(TRemConCoreApiPlaybackSpeed aSpeed,TRemConCoreApiButtonAction aButtonAct);
|
||||
|
||||
void MrccatoTuneFunction(TBool aTwoPart,TUint aMajorChannel,TUint aMinorChannel,TRemConCoreApiButtonAction aButtonAct);
|
||||
|
||||
void MrccatoSelectDiskFunction(TUint aDisk,TRemConCoreApiButtonAction aButtonAct);
|
||||
|
||||
void MrccatoSelectAvInputFunction(TUint8 aAvInputSignalNumber,TRemConCoreApiButtonAction aButtonAct);
|
||||
|
||||
void MrccatoSelectAudioInputFunction(TUint8 aAudioInputSignalNumber,TRemConCoreApiButtonAction aButtonAct);
|
||||
|
||||
private:
|
||||
void CompleteMediaKeyEvent( TRemConCoreApiOperationId aOperationId );
|
||||
void RunL();
|
||||
void DoCancel();
|
||||
|
||||
public slots:
|
||||
void playtimerexpired();
|
||||
void stoptimerexpired();
|
||||
void forwardtimerexpired();
|
||||
void backwardtimerexpired();
|
||||
void voluptimerexpired();
|
||||
void voldowntimerexpired();
|
||||
private:
|
||||
|
||||
RArray<TRemConCoreApiOperationId> iResponseQ; //response queue
|
||||
|
||||
CRemConCoreApiTarget* iRemConCore; //the controller
|
||||
CRemConInterfaceSelector* iInterfaceSelector;
|
||||
|
||||
QObject* receiver;
|
||||
|
||||
QTimer* playtimer;
|
||||
QTimer* stoptimer;
|
||||
QTimer* forwardtimer;
|
||||
QTimer* backwardtimer;
|
||||
QTimer* voluptimer;
|
||||
QTimer* voldowntimer;
|
||||
};
|
||||
|
||||
#endif /* SYMBIANMEDIAKEYS_H_ */
|
17
ext/native/base/arch.h
Normal file
17
ext/native/base/arch.h
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
// This provides MSVC's arch-detection defines on other platforms as well.
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
#if defined(__x86_64__) && !defined(_M_X64)
|
||||
#define _M_X64 1
|
||||
#endif
|
||||
|
||||
#if defined(__x86__) && !defined(_M_IX86)
|
||||
#define _M_IX86 1
|
||||
#endif
|
||||
|
||||
// TODO: ARM, ARM64
|
||||
|
||||
#endif
|
22
ext/native/base/backtrace.cpp
Normal file
22
ext/native/base/backtrace.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
#include "base/backtrace.h"
|
||||
|
||||
#if defined(__GLIBC__) && !defined(__UCLIBC__)
|
||||
#include <execinfo.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static void *backtrace_buffer[128];
|
||||
|
||||
void PrintBacktraceToStderr() {
|
||||
int num_addrs = backtrace(backtrace_buffer, 128);
|
||||
backtrace_symbols_fd(backtrace_buffer, num_addrs, STDERR_FILENO);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void PrintBacktraceToStderr() {
|
||||
fprintf(stderr, "No backtrace available to print on this platform\n");
|
||||
}
|
||||
|
||||
#endif
|
3
ext/native/base/backtrace.h
Normal file
3
ext/native/base/backtrace.h
Normal file
@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void PrintBacktraceToStderr();
|
95
ext/native/base/basictypes.h
Normal file
95
ext/native/base/basictypes.h
Normal file
@ -0,0 +1,95 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h> // for byte swapping
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma warning(disable:4244)
|
||||
#pragma warning(disable:4996)
|
||||
#pragma warning(disable:4305) // truncation from double to float
|
||||
#endif
|
||||
|
||||
#define DISALLOW_COPY_AND_ASSIGN(t) \
|
||||
private: \
|
||||
t(const t &other); \
|
||||
void operator =(const t &other);
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
typedef intptr_t ssize_t;
|
||||
|
||||
#include <tchar.h>
|
||||
|
||||
#define ALIGNED16(x) __declspec(align(16)) x
|
||||
#define ALIGNED32(x) __declspec(align(32)) x
|
||||
#define ALIGNED64(x) __declspec(align(64)) x
|
||||
#define ALIGNED16_DECL(x) __declspec(align(16)) x
|
||||
#define ALIGNED64_DECL(x) __declspec(align(64)) x
|
||||
|
||||
#else
|
||||
|
||||
#define ALIGNED16(x) __attribute__((aligned(16))) x
|
||||
#define ALIGNED32(x) __attribute__((aligned(32))) x
|
||||
#define ALIGNED64(x) __attribute__((aligned(64))) x
|
||||
#define ALIGNED16_DECL(x) __attribute__((aligned(16))) x
|
||||
#define ALIGNED64_DECL(x) __attribute__((aligned(64))) x
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
// Byteswapping
|
||||
#ifndef ARRAY_SIZE
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
|
||||
#endif
|
||||
|
||||
inline uint8_t swap8(uint8_t _data) {return _data;}
|
||||
|
||||
// Just in case this has been defined by platform
|
||||
#undef swap16
|
||||
#undef swap32
|
||||
#undef swap64
|
||||
|
||||
#ifdef _WIN32
|
||||
inline uint16_t swap16(uint16_t _data) {return _byteswap_ushort(_data);}
|
||||
inline uint32_t swap32(uint32_t _data) {return _byteswap_ulong (_data);}
|
||||
inline uint64_t swap64(uint64_t _data) {return _byteswap_uint64(_data);}
|
||||
#elif defined(ARM)
|
||||
inline uint16_t swap16 (uint16_t _data) { uint32_t data = _data; __asm__ ("rev16 %0, %1\n" : "=l" (data) : "l" (data)); return (uint16_t)data;}
|
||||
inline uint32_t swap32 (uint32_t _data) {__asm__ ("rev %0, %1\n" : "=l" (_data) : "l" (_data)); return _data;}
|
||||
inline uint64_t swap64(uint64_t _data) {return ((uint64_t)swap32(_data) << 32) | swap32(_data >> 32);}
|
||||
#elif __linux__ && !defined(ANDROID)
|
||||
#include <byteswap.h>
|
||||
inline uint16_t swap16(uint16_t _data) {return bswap_16(_data);}
|
||||
inline uint32_t swap32(uint32_t _data) {return bswap_32(_data);}
|
||||
inline uint64_t swap64(uint64_t _data) {return bswap_64(_data);}
|
||||
#elif defined(__DragonFly__) || defined(__FreeBSD__)
|
||||
#include <sys/endian.h>
|
||||
inline uint16_t swap16(uint16_t _data) {return bswap16(_data);}
|
||||
inline uint32_t swap32(uint32_t _data) {return bswap32(_data);}
|
||||
inline uint64_t swap64(uint64_t _data) {return bswap64(_data);}
|
||||
#elif defined(__GNUC__)
|
||||
inline uint16_t swap16(uint16_t _data) {return (_data >> 8) | (_data << 8);}
|
||||
inline uint32_t swap32(uint32_t _data) {return __builtin_bswap32(_data);}
|
||||
inline uint64_t swap64(uint64_t _data) {return __builtin_bswap64(_data);}
|
||||
#else
|
||||
// Slow generic implementation. Hopefully this never hits
|
||||
inline uint16_t swap16(uint16_t data) {return (data >> 8) | (data << 8);}
|
||||
inline uint32_t swap32(uint32_t data) {return (swap16(data) << 16) | swap16(data >> 16);}
|
||||
inline uint64_t swap64(uint64_t data) {return ((uint64_t)swap32(data) << 32) | swap32(data >> 32);}
|
||||
#endif
|
||||
|
||||
inline uint16_t swap16(const uint8_t* _pData) {return swap16(*(const uint16_t*)_pData);}
|
||||
inline uint32_t swap32(const uint8_t* _pData) {return swap32(*(const uint32_t*)_pData);}
|
||||
inline uint64_t swap64(const uint8_t* _pData) {return swap64(*(const uint64_t*)_pData);}
|
||||
|
||||
// Thread local storage
|
||||
#ifdef _WIN32
|
||||
#define __THREAD __declspec( thread )
|
||||
#else
|
||||
#define __THREAD __thread
|
||||
#endif
|
||||
|
||||
// For really basic windows code compat
|
||||
#ifndef _TCHAR_DEFINED
|
||||
typedef char TCHAR;
|
||||
#endif
|
||||
|
234
ext/native/base/buffer.cpp
Normal file
234
ext/native/base/buffer.cpp
Normal file
@ -0,0 +1,234 @@
|
||||
#include "base/buffer.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#undef min
|
||||
#undef max
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/timeutil.h"
|
||||
#include "file/fd_util.h"
|
||||
|
||||
Buffer::Buffer() { }
|
||||
Buffer::~Buffer() { }
|
||||
|
||||
char *Buffer::Append(ssize_t length) {
|
||||
size_t old_size = data_.size();
|
||||
data_.resize(old_size + length);
|
||||
return &data_[0] + old_size;
|
||||
}
|
||||
|
||||
void Buffer::Append(const std::string &str) {
|
||||
char *ptr = Append(str.size());
|
||||
memcpy(ptr, str.data(), str.size());
|
||||
}
|
||||
|
||||
void Buffer::Append(const char *str) {
|
||||
size_t len = strlen(str);
|
||||
char *dest = Append(len);
|
||||
memcpy(dest, str, len);
|
||||
}
|
||||
|
||||
void Buffer::Append(const Buffer &other) {
|
||||
size_t len = other.size();
|
||||
char *dest = Append(len);
|
||||
memcpy(dest, &other.data_[0], len);
|
||||
}
|
||||
|
||||
void Buffer::AppendValue(int value) {
|
||||
char buf[16];
|
||||
// This is slow.
|
||||
sprintf(buf, "%i", value);
|
||||
Append(buf);
|
||||
}
|
||||
|
||||
void Buffer::Take(size_t length, std::string *dest) {
|
||||
if (length > data_.size()) {
|
||||
ELOG("Truncating length in Buffer::Take()");
|
||||
length = data_.size();
|
||||
}
|
||||
dest->resize(length);
|
||||
if (length > 0) {
|
||||
Take(length, &(*dest)[0]);
|
||||
}
|
||||
}
|
||||
|
||||
void Buffer::Take(size_t length, char *dest) {
|
||||
memcpy(dest, &data_[0], length);
|
||||
data_.erase(data_.begin(), data_.begin() + length);
|
||||
}
|
||||
|
||||
int Buffer::TakeLineCRLF(std::string *dest) {
|
||||
int after_next_line = OffsetToAfterNextCRLF();
|
||||
if (after_next_line < 0)
|
||||
return after_next_line;
|
||||
else {
|
||||
Take(after_next_line - 2, dest);
|
||||
Skip(2); // Skip the CRLF
|
||||
return after_next_line - 2;
|
||||
}
|
||||
}
|
||||
|
||||
void Buffer::Skip(size_t length) {
|
||||
if (length > data_.size()) {
|
||||
ELOG("Truncating length in Buffer::Skip()");
|
||||
length = data_.size();
|
||||
}
|
||||
data_.erase(data_.begin(), data_.begin() + length);
|
||||
}
|
||||
|
||||
int Buffer::SkipLineCRLF() {
|
||||
int after_next_line = OffsetToAfterNextCRLF();
|
||||
if (after_next_line < 0)
|
||||
return after_next_line;
|
||||
else {
|
||||
Skip(after_next_line);
|
||||
return after_next_line - 2;
|
||||
}
|
||||
}
|
||||
|
||||
int Buffer::OffsetToAfterNextCRLF() {
|
||||
for (int i = 0; i < (int)data_.size() - 1; i++) {
|
||||
if (data_[i] == '\r' && data_[i + 1] == '\n') {
|
||||
return i + 2;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Buffer::Printf(const char *fmt, ...) {
|
||||
char buffer[2048];
|
||||
va_list vl;
|
||||
va_start(vl, fmt);
|
||||
ssize_t retval = vsnprintf(buffer, sizeof(buffer), fmt, vl);
|
||||
if (retval >= (ssize_t)sizeof(buffer)) {
|
||||
// Output was truncated. TODO: Do something.
|
||||
ELOG("Buffer::Printf truncated output");
|
||||
}
|
||||
if (retval < 0) {
|
||||
ELOG("Buffer::Printf failed");
|
||||
}
|
||||
va_end(vl);
|
||||
char *ptr = Append(retval);
|
||||
memcpy(ptr, buffer, retval);
|
||||
}
|
||||
|
||||
bool Buffer::Flush(int fd) {
|
||||
// Look into using send() directly.
|
||||
bool success = (ssize_t)data_.size() == fd_util::WriteLine(fd, &data_[0], data_.size());
|
||||
if (success) {
|
||||
data_.resize(0);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
bool Buffer::FlushToFile(const char *filename) {
|
||||
FILE *f = fopen(filename, "wb");
|
||||
if (!f)
|
||||
return false;
|
||||
if (data_.size()) {
|
||||
fwrite(&data_[0], 1, data_.size(), f);
|
||||
}
|
||||
fclose(f);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Buffer::FlushSocket(uintptr_t sock) {
|
||||
for (size_t pos = 0, end = data_.size(); pos < end; ) {
|
||||
int sent = send(sock, &data_[pos], (int)(end - pos), 0);
|
||||
if (sent < 0) {
|
||||
ELOG("FlushSocket failed");
|
||||
return false;
|
||||
}
|
||||
pos += sent;
|
||||
|
||||
// Buffer full, don't spin.
|
||||
if (sent == 0) {
|
||||
sleep_ms(1);
|
||||
}
|
||||
}
|
||||
data_.resize(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Buffer::ReadAll(int fd, int hintSize) {
|
||||
std::vector<char> buf;
|
||||
if (hintSize >= 65536 * 16) {
|
||||
buf.resize(65536);
|
||||
} else if (hintSize >= 1024 * 16) {
|
||||
buf.resize(hintSize / 16);
|
||||
} else {
|
||||
buf.resize(1024);
|
||||
}
|
||||
|
||||
while (true) {
|
||||
int retval = recv(fd, &buf[0], (int)buf.size(), 0);
|
||||
if (retval == 0) {
|
||||
break;
|
||||
} else if (retval < 0) {
|
||||
ELOG("Error reading from buffer: %i", retval);
|
||||
return false;
|
||||
}
|
||||
char *p = Append((size_t)retval);
|
||||
memcpy(p, &buf[0], retval);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Buffer::ReadAllWithProgress(int fd, int knownSize, float *progress) {
|
||||
std::vector<char> buf;
|
||||
if (knownSize >= 65536 * 16) {
|
||||
buf.resize(65536);
|
||||
} else if (knownSize >= 1024 * 16) {
|
||||
buf.resize(knownSize / 16);
|
||||
} else {
|
||||
buf.resize(1024);
|
||||
}
|
||||
|
||||
int total = 0;
|
||||
while (true) {
|
||||
int retval = recv(fd, &buf[0], (int)buf.size(), 0);
|
||||
if (retval == 0) {
|
||||
return true;
|
||||
} else if (retval < 0) {
|
||||
ELOG("Error reading from buffer: %i", retval);
|
||||
return false;
|
||||
}
|
||||
char *p = Append((size_t)retval);
|
||||
memcpy(p, &buf[0], retval);
|
||||
total += retval;
|
||||
*progress = (float)total / (float)knownSize;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int Buffer::Read(int fd, size_t sz) {
|
||||
char buf[1024];
|
||||
int retval;
|
||||
size_t received = 0;
|
||||
while ((retval = recv(fd, buf, (int)std::min(sz, sizeof(buf)), 0)) > 0) {
|
||||
if (retval < 0) {
|
||||
return retval;
|
||||
}
|
||||
char *p = Append((size_t)retval);
|
||||
memcpy(p, buf, retval);
|
||||
sz -= retval;
|
||||
received += retval;
|
||||
if (sz == 0)
|
||||
return 0;
|
||||
}
|
||||
return (int)received;
|
||||
}
|
||||
|
||||
void Buffer::PeekAll(std::string *dest) {
|
||||
dest->resize(data_.size());
|
||||
memcpy(&(*dest)[0], &data_[0], data_.size());
|
||||
}
|
88
ext/native/base/buffer.h
Normal file
88
ext/native/base/buffer.h
Normal file
@ -0,0 +1,88 @@
|
||||
#ifndef _IO_BUFFER_H
|
||||
#define _IO_BUFFER_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/logging.h"
|
||||
|
||||
// Acts as a queue. Intended to be as fast as possible for most uses.
|
||||
// Does not do synchronization, must use external mutexes.
|
||||
class Buffer {
|
||||
public:
|
||||
Buffer();
|
||||
~Buffer();
|
||||
|
||||
// Write max [length] bytes to the returned pointer.
|
||||
// Any other operation on this Buffer invalidates the pointer.
|
||||
char *Append(ssize_t length);
|
||||
char *Append(size_t length) { return Append((ssize_t)length); }
|
||||
|
||||
// These work pretty much like you'd expect.
|
||||
void Append(const char *str); // str null-terminated. The null is not copied.
|
||||
void Append(const std::string &str);
|
||||
void Append(const Buffer &other);
|
||||
|
||||
// Various types. Useful for varz etc. Appends a string representation of the
|
||||
// value, rather than a binary representation.
|
||||
void AppendValue(int value);
|
||||
|
||||
// Parsing Helpers
|
||||
|
||||
// Use for easy line skipping. If no CRLF within the buffer, returns -1.
|
||||
// If parsing HTML headers, this indicates that you should probably buffer up
|
||||
// more data.
|
||||
int OffsetToAfterNextCRLF();
|
||||
|
||||
// Takers
|
||||
|
||||
void Take(size_t length, std::string *dest);
|
||||
void Take(size_t length, char *dest);
|
||||
void TakeAll(std::string *dest) { Take(size(), dest); }
|
||||
// On failure, return value < 0 and *dest is unchanged.
|
||||
// Strips off the actual CRLF from the result.
|
||||
int TakeLineCRLF(std::string *dest);
|
||||
|
||||
// Skippers
|
||||
void Skip(size_t length);
|
||||
// Returns -1 on failure (no CRLF within sight).
|
||||
// Otherwise returns the length of the line skipped, not including CRLF. Can be 0.
|
||||
int SkipLineCRLF();
|
||||
|
||||
// Utility functions.
|
||||
void Printf(const char *fmt, ...);
|
||||
|
||||
// Dumps the entire buffer to the string, but keeps it around.
|
||||
// Only to be used for debugging, since it might not be fast at all.
|
||||
void PeekAll(std::string *dest);
|
||||
|
||||
// Simple I/O.
|
||||
|
||||
// Writes the entire buffer to the file descriptor. Also resets the
|
||||
// size to zero. On failure, data remains in buffer and nothing is
|
||||
// written.
|
||||
bool Flush(int fd);
|
||||
bool FlushToFile(const char *filename);
|
||||
bool FlushSocket(uintptr_t sock); // Windows portability
|
||||
|
||||
bool ReadAll(int fd, int hintSize = 0);
|
||||
bool ReadAllWithProgress(int fd, int knownSize, float *progress);
|
||||
|
||||
// < 0: error
|
||||
// >= 0: number of bytes read
|
||||
int Read(int fd, size_t sz);
|
||||
|
||||
// Utilities. Try to avoid checking for size.
|
||||
size_t size() const { return data_.size(); }
|
||||
bool empty() const { return size() == 0; }
|
||||
void clear() { data_.resize(0); }
|
||||
|
||||
private:
|
||||
// TODO: Find a better internal representation, like a cord.
|
||||
std::vector<char> data_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Buffer);
|
||||
};
|
||||
|
||||
#endif // _IO_BUFFER_H
|
16
ext/native/base/color.h
Normal file
16
ext/native/base/color.h
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
typedef unsigned int Color;
|
||||
|
||||
//have to use a define to ensure constant folding.. with an inline I don't get that, sucks
|
||||
#define COLOR(i) (((i&0xFF) << 16) | (i & 0xFF00) | ((i & 0xFF0000) >> 16) | 0xFF000000)
|
||||
inline Color darkenColor(Color color) {
|
||||
return (color & 0xFF000000) | ((color >> 1)&0x7F7F7F);
|
||||
}
|
||||
inline Color whitenColor(Color color) {
|
||||
return ((color & 0xFF000000) | ((color >> 1)&0x7F7F7F)) + 0x7F7F7F;
|
||||
}
|
||||
inline Color colorInterpol(Color x, Color y, int n) {
|
||||
// TODO
|
||||
return x;
|
||||
}
|
101
ext/native/base/colorutil.cpp
Normal file
101
ext/native/base/colorutil.cpp
Normal file
@ -0,0 +1,101 @@
|
||||
#include "base/colorutil.h"
|
||||
|
||||
uint32_t whiteAlpha(float alpha) {
|
||||
if (alpha < 0.0f) alpha = 0.0f;
|
||||
if (alpha > 1.0f) alpha = 1.0f;
|
||||
uint32_t color = (int)(alpha*255) << 24;
|
||||
color |= 0xFFFFFF;
|
||||
return color;
|
||||
}
|
||||
|
||||
uint32_t blackAlpha(float alpha) {
|
||||
if (alpha < 0.0f) alpha = 0.0f;
|
||||
if (alpha > 1.0f) alpha = 1.0f;
|
||||
return (int)(alpha*255)<<24;
|
||||
}
|
||||
|
||||
uint32_t colorAlpha(uint32_t rgb, float alpha) {
|
||||
if (alpha < 0.0f) alpha = 0.0f;
|
||||
if (alpha > 1.0f) alpha = 1.0f;
|
||||
return ((int)(alpha*255)<<24) | (rgb & 0xFFFFFF);
|
||||
}
|
||||
|
||||
uint32_t alphaMul(uint32_t color, float alphaMul) {
|
||||
uint32_t rgb = color & 0xFFFFFF;
|
||||
uint32_t alpha = color >> 24;
|
||||
alpha *= alphaMul;
|
||||
if (alpha < 0.0f) alpha = 0.0f;
|
||||
if (alpha > 255.0f) alpha = 255.0f;
|
||||
return ((int)(alpha)<<24) | (rgb & 0xFFFFFF);
|
||||
}
|
||||
|
||||
uint32_t rgba(float r, float g, float b, float alpha) {
|
||||
uint32_t color = (int)(alpha*255)<<24;
|
||||
color |= (int)(b*255)<<16;
|
||||
color |= (int)(g*255)<<8;
|
||||
color |= (int)(r*255);
|
||||
return color;
|
||||
}
|
||||
|
||||
uint32_t rgba_clamp(float r, float g, float b, float a) {
|
||||
if (r > 1.0f) r = 1.0f;
|
||||
if (g > 1.0f) g = 1.0f;
|
||||
if (b > 1.0f) b = 1.0f;
|
||||
if (a > 1.0f) a = 1.0f;
|
||||
|
||||
if (r < 0.0f) r = 0.0f;
|
||||
if (g < 0.0f) g = 0.0f;
|
||||
if (b < 0.0f) b = 0.0f;
|
||||
if (a < 0.0f) a = 0.0f;
|
||||
|
||||
return rgba(r,g,b,a);
|
||||
}
|
||||
|
||||
/* hsv2rgb.c
|
||||
* Convert Hue Saturation Value to Red Green Blue
|
||||
*
|
||||
* P.J. 08-Aug-98
|
||||
*
|
||||
* Reference:
|
||||
* D. F. Rogers
|
||||
* Procedural Elements for Computer Graphics
|
||||
* McGraw Hill 1985
|
||||
*/
|
||||
uint32_t hsva(float H, float S, float V, float alpha) {
|
||||
/*
|
||||
* Purpose:
|
||||
* Convert HSV values to RGB values
|
||||
* All values are in the range [0.0 .. 1.0]
|
||||
*/
|
||||
float F, M, N, K;
|
||||
int I;
|
||||
if ( S == 0.0 ) {
|
||||
// Achromatic case, set level of grey
|
||||
return rgba(V, V, V, alpha);
|
||||
} else {
|
||||
/*
|
||||
* Determine levels of primary colours.
|
||||
*/
|
||||
if (H >= 1.0) {
|
||||
H = 0.0;
|
||||
} else {
|
||||
H = H * 6;
|
||||
}
|
||||
I = (int) H; /* should be in the range 0..5 */
|
||||
F = H - I; /* fractional part */
|
||||
|
||||
M = V * (1 - S);
|
||||
N = V * (1 - S * F);
|
||||
K = V * (1 - S * (1 - F));
|
||||
|
||||
float r, g, b;
|
||||
if (I == 0) { r = V; g = K; b = M; }
|
||||
else if (I == 1) { r = N; g = V; b = M; }
|
||||
else if (I == 2) { r = M; g = V; b = K; }
|
||||
else if (I == 3) { r = M; g = N; b = V; }
|
||||
else if (I == 4) { r = K; g = M; b = V; }
|
||||
else if (I == 5) { r = V; g = M; b = N; }
|
||||
else return 0;
|
||||
return rgba(r, g, b, alpha);
|
||||
}
|
||||
}
|
12
ext/native/base/colorutil.h
Normal file
12
ext/native/base/colorutil.h
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "base/basictypes.h"
|
||||
|
||||
uint32_t whiteAlpha(float alpha);
|
||||
uint32_t blackAlpha(float alpha);
|
||||
uint32_t colorAlpha(uint32_t color, float alpha);
|
||||
uint32_t colorBlend(uint32_t color, uint32_t color2, float alpha);
|
||||
uint32_t alphaMul(uint32_t color, float alphaMul);
|
||||
uint32_t rgba(float r, float g, float b, float alpha);
|
||||
uint32_t rgba_clamp(float r, float g, float b, float alpha);
|
||||
uint32_t hsva(float h, float s, float v, float alpha);
|
28
ext/native/base/compat.cpp
Normal file
28
ext/native/base/compat.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "base/compat.h"
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
|
||||
static int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap) {
|
||||
int count = -1;
|
||||
if (size != 0)
|
||||
count = _vsnprintf_s(str, size, _TRUNCATE, format, ap);
|
||||
if (count == -1)
|
||||
count = _vscprintf(format, ap);
|
||||
return count;
|
||||
}
|
||||
|
||||
int c99_snprintf(char* str, size_t size, const char* format, ...) {
|
||||
int count;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
count = c99_vsnprintf(str, size, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user